// Main App — route + tweak state coordinator function App() { const [route, _setRoute] = React.useState(() => { const h = window.location.hash.replace('#', ''); return ['home', 'products', 'about', 'contact'].includes(h) ? h : 'home'; }); const setRoute = (r) => { _setRoute(r); window.location.hash = r; window.scrollTo({ top: 0, behavior: 'instant' }); }; React.useEffect(() => { const onHash = () => { const h = window.location.hash.replace('#', ''); if (['home', 'products', 'about', 'contact'].includes(h)) { _setRoute(h); } }; window.addEventListener('hashchange', onHash); return () => window.removeEventListener('hashchange', onHash); }, []); // Subscribe to tweaks from the tweaks panel (or fallback to defaults) const [tweaks, setTweaks] = React.useState(() => window.__myfabTweaks || window.__myfabDefaults); React.useEffect(() => { const handler = (e) => setTweaks(e.detail); window.addEventListener('myfab-tweaks', handler); return () => window.removeEventListener('myfab-tweaks', handler); }, []); // Apply palette on initial mount React.useEffect(() => { document.documentElement.setAttribute('data-palette', tweaks.palette || 'light'); }, [tweaks.palette]); return (
); } function startApp() { ReactDOM.createRoot(document.getElementById('root')).render(); } if (window.__contentReady) { startApp(); } else { window.addEventListener('myfab-content-ready', startApp, { once: true }); // Safety net: render anyway after 3s if content never loads setTimeout(() => { if (!window.__contentReady) { window.__C = window.__CONTENT_DEFAULTS || {}; startApp(); } }, 3000); }