// App shell — router, tweaks integration, mount const TWEAK_DEFAULTS = window.__TWEAK_DEFAULTS; function App() { // Route is one of: // 'home', 'projects', 'sectors', 'services', 'capability', 'about', 'awards', 'contact', 'sitemap' // 'project:', 'sector:' const [route, setRoute] = useState('home'); const [prefill, setPrefill] = useState(null); const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); // Apply tweak vars to root useEffect(() => { const r = document.documentElement.style; r.setProperty('--accent', t.accent); r.setProperty('--bronze', t.accent); r.setProperty('--bronze-soft', shade(t.accent, 0.45)); r.setProperty('--bronze-deep', shade(t.accent, -0.2)); r.setProperty('--density', String(t.density)); r.setProperty('--display-weight', String(t.displayWeight)); document.documentElement.setAttribute('dir', t.locale === 'ar' ? 'rtl' : 'ltr'); document.documentElement.setAttribute('lang', t.locale); }, [t.accent, t.density, t.displayWeight, t.locale]); const go = (r, payload) => { setRoute(r); if (r === 'contact' && payload) setPrefill(payload); else if (r !== 'contact') setPrefill(null); window.scrollTo({ top: 0, behavior: 'instant' }); window.history.replaceState(null, '', '#' + r); }; // Read initial hash route useEffect(() => { const h = (window.location.hash || '').replace(/^#/, ''); if (h) setRoute(h); }, []); const renderPage = () => { if (route.startsWith('project:')) return ; if (route.startsWith('sector:')) return ; switch (route) { case 'home': return ; case 'projects': return ; case 'sectors': return ; case 'services': return ; case 'capability': return ; case 'about': return ; case 'awards': return ; case 'contact': return ; case 'sitemap': return ; default: return ; } }; return (
); } function navTopId(route) { if (route.startsWith('project:')) return 'projects'; if (route.startsWith('sector:')) return 'sectors'; return route; } // Mix a hex toward white (amt > 0) or black (amt < 0) function shade(hex, amt) { const h = hex.replace('#', ''); const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16); let r = (n >> 16) & 255, g = (n >> 8) & 255, b = n & 255; if (amt >= 0) { r = Math.round(r + (255 - r) * amt); g = Math.round(g + (255 - g) * amt); b = Math.round(b + (255 - b) * amt); } else { r = Math.round(r * (1 + amt)); g = Math.round(g * (1 + amt)); b = Math.round(b * (1 + amt)); } return '#' + [r, g, b].map(v => v.toString(16).padStart(2, '0')).join(''); } ReactDOM.createRoot(document.getElementById('root')).render();