const TWEAK_DEFAULTS = { heroImageSide: 'Left', scrollAnimations: true, }; function App() { const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS); const { TweaksPanel, TweakSection, TweakRadio, TweakToggle } = window; const [active, setActive] = React.useState('about'); React.useEffect(() => { const ids = window.SITE_DATA.nav.map((n) => n.id); const sections = ids.map((id) => document.getElementById(id)).filter(Boolean); if (!sections.length) return; const obs = new IntersectionObserver( (entries) => { const vis = entries.filter((e) => e.isIntersecting).sort((a, b) => b.intersectionRatio - a.intersectionRatio); if (vis[0]) setActive(vis[0].target.id); }, { rootMargin: '-45% 0px -50% 0px', threshold: [0, 0.25, 0.5, 1] } ); sections.forEach((s) => obs.observe(s)); return () => obs.disconnect(); }, []); const navigate = (id) => { if (id === 'top') { window.scrollTo({ top: 0, behavior: 'smooth' }); return; } const el = document.getElementById(id); if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }; React.useEffect(() => { document.documentElement.style.setProperty('--motion-enabled', tweaks.scrollAnimations ? '1' : '0'); if (!tweaks.scrollAnimations) { document.querySelectorAll('.reveal').forEach((el) => el.classList.add('in-view')); } }, [tweaks.scrollAnimations]); return (
setTweak('heroImageSide', v)} /> setTweak('scrollAnimations', v)} />
); } const root = ReactDOM.createRoot(document.getElementById('root')); root.render();