/** * App — hash-based router + toast state. Top-level mount. */ const { useState: useStateApp, useEffect } = React; const ROUTES = ['home', 'about', 'why', 'clients', 'contact']; function readRoute() { const h = (window.location.hash || '').replace(/^#\//, '').replace(/^#/, ''); return ROUTES.includes(h) ? h : 'home'; } function App() { const [route, setRoute] = useStateApp(readRoute()); const [toast, setToast] = useStateApp({ msg: '', t: 0 }); // sync hash → state useEffect(() => { const onHash = () => { setRoute(readRoute()); window.scrollTo({ top: 0, behavior: 'instant' }); }; window.addEventListener('hashchange', onHash); return () => window.removeEventListener('hashchange', onHash); }, []); // toast lifetime useEffect(() => { if (!toast.t) return; const id = setTimeout(() => setToast(s => ({ ...s, msg: '' })), 2400); return () => clearTimeout(id); }, [toast.t]); const showToast = (msg) => setToast({ msg, t: Date.now() }); const onNav = (id) => { if (!ROUTES.includes(id)) id = 'home'; if (id === route) { window.scrollTo({ top: 0, behavior: 'smooth' }); return; } window.location.hash = '#/' + id; }; let Page; switch (route) { case 'about': Page = AboutPage; break; case 'why': Page = WhyPage; break; case 'clients': Page = ClientsPage; break; case 'contact': Page = ContactPage; break; default: Page = HomePage; } return (