/* ============================================ H-Arch — App shell, routing, tweaks ============================================ */ const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "brand": "#682E92", "hero": "copper", "display": "fraunces" }/*EDITMODE-END*/; function App() { const [route, setRoute] = useState('home'); const [openFinish, setOpenFinish] = useState(null); const [toast, setToast] = useState(''); const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); // Apply tweak side-effects (palette / display family) useEffect(() => { document.documentElement.style.setProperty('--brand', t.brand); document.documentElement.style.setProperty('--brand-deep', darken(t.brand, 0.18)); document.documentElement.style.setProperty('--brand-tint', mix(t.brand, '#FFFFFF', 0.92)); const display = { fraunces: "'Fraunces', 'Cormorant Garamond', Georgia, serif", cormorant: "'Cormorant Garamond', 'Fraunces', Georgia, serif", tight: "'Inter Tight', 'Inter', sans-serif", }[t.display] || "'Fraunces', Georgia, serif"; document.documentElement.style.setProperty('--display', display); }, [t.brand, t.display]); // Route → top of page useEffect(() => { window.scrollTo({ top: 0, behavior: 'instant' }); }, [route]); useReveal(); const handleSample = useCallback(() => { // Pick a hero finish as a default sample request const f = window.HARCH_DATA.FINISHES.find((x) => x.slug === 'hairline-ss'); setOpenFinish(f); }, []); const handleOpen = useCallback((f) => setOpenFinish(f), []); const handleClose = useCallback(() => setOpenFinish(null), []); // Pages render let page; if (route === 'home') page = ; else if (route === 'finishes') page = ; else if (route === 'projects') page = ; else if (route === 'capabilities') page = ; else if (route === 'showroom') page = ; else if (route === 'contact') page = ; else page = ; const isHomeHero = route === 'home'; return (
); } /* ---------- Small colour helpers ---------- */ function hexToRgb(hex) { const m = hex.replace('#', ''); const n = parseInt(m.length === 3 ? m.split('').map((c) => c + c).join('') : m, 16); return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 }; } function rgbToHex({ r, g, b }) { return '#' + [r, g, b].map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join(''); } function darken(hex, amt) { const { r, g, b } = hexToRgb(hex); return rgbToHex({ r: r * (1 - amt), g: g * (1 - amt), b: b * (1 - amt) }); } function mix(a, b, t) { const ca = hexToRgb(a), cb = hexToRgb(b); return rgbToHex({ r: ca.r * (1 - t) + cb.r * t, g: ca.g * (1 - t) + cb.g * t, b: ca.b * (1 - t) + cb.b * t, }); } ReactDOM.createRoot(document.getElementById('root')).render();