function App() {
useReveal();
// After React mounts, scroll to the hash target if one is present in the URL.
// The native browser scroll-to-hash happens before React renders the sections,
// so we redo it once everything is on the page.
React.useEffect(() => {
const scrollToHash = () => {
const hash = window.location.hash;
if (!hash || hash.length < 2) return;
const el = document.getElementById(hash.slice(1));
if (el) {
// Defer one frame so layout settles
requestAnimationFrame(() => {
const top = el.getBoundingClientRect().top + window.pageYOffset - 70;
window.scrollTo({ top, behavior: 'auto' });
});
}
};
// Initial mount — small delay to let fonts/images influence layout
const t = setTimeout(scrollToHash, 80);
// Also handle hashchange (e.g. clicking another anchor on the same page)
window.addEventListener('hashchange', scrollToHash);
return () => {
clearTimeout(t);
window.removeEventListener('hashchange', scrollToHash);
};
}, []);
return (
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render();