// Main App composer. Loaded as Babel script. // Globals expected: React, ReactDOM, COPY, all components from components.jsx/sections.jsx, // and the Tweaks helpers from tweaks-panel.jsx. const { useState: useStateApp, useEffect: useEffectApp, useMemo: useMemoApp } = React; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "palette": "navy-heavy", "type": "serif", "density": "slow-luxe", "showFigures": true, "ribbon": true }/*EDITMODE-END*/; function App() { const [locale, setLocale] = useStateApp('en'); const [modal, setModal] = useStateApp(null); // 'viewing' | 'brochure' | 'broker' | null const [toast, setToast] = useStateApp(null); const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); const dir = (COPY[locale] && COPY[locale].dir) || 'ltr'; useEffectApp(() => { document.documentElement.dir = dir; document.documentElement.lang = locale; }, [dir, locale]); // Apply tweak data-attributes to so CSS can switch on them useEffectApp(() => { const html = document.documentElement; html.dataset.palette = t.palette; html.dataset.type = t.type; html.dataset.density = t.density; html.dataset.ribbon = t.ribbon ? 'on' : 'off'; }, [t.palette, t.type, t.density, t.ribbon]); const onRegister = () => { const el = document.getElementById('convert'); if (el) window.scrollTo({ top: el.offsetTop - 64, behavior: 'smooth' }); }; const onSent = () => { setToast({ msg: 'Enquiry received · we’ll be in touch within one business day.' }); setTimeout(() => setToast(null), 4500); }; return (