// App entry: routing + tweaks + theme const { useState: useStateApp, useEffect: useEffectApp } = React; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "theme": "crimson", "lang": "en", "featuredProperty": "redfestdxb", "headlineStyle": "split" }/*EDITMODE-END*/; function App() { const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); const [route, setRoute] = useStateApp(() => { const h = (window.location.hash || '').replace('#', ''); return ['home','work','services','events','about','partner','contact'].includes(h) ? h : 'home'; }); const go = (r) => { setRoute(r); window.location.hash = r; window.scrollTo({ top: 0, behavior: 'instant' }); }; useEffectApp(() => { const onHash = () => { const h = (window.location.hash || '').replace('#', ''); if (['home','work','services','events','about','partner','contact'].includes(h)) { setRoute(h); } }; window.addEventListener('hashchange', onHash); return () => window.removeEventListener('hashchange', onHash); }, []); // Apply theme + lang to root const themeAttr = t.theme === 'crimson' ? null : t.theme; useEffectApp(() => { if (themeAttr) document.documentElement.setAttribute('data-theme', themeAttr); else document.documentElement.removeAttribute('data-theme'); }, [themeAttr]); const lang = t.lang || 'en'; const i18n = I18N[lang] || I18N.en; useEffectApp(() => { document.documentElement.setAttribute('lang', lang); document.documentElement.setAttribute('dir', i18n.dir); }, [lang, i18n.dir]); const sharedProps = { t: i18n, lang, setLang: (l) => setTweak('lang', l), go, route, featured: t.featuredProperty, setFeatured: (id) => setTweak('featuredProperty', id), headlineStyle: t.headlineStyle, }; return ( <>