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();