/* Header — artistic nav with prominent wordmark + underline trail */ function Header({ accentVar }) { const [scrolled, setScrolled] = React.useState(false); const [active, setActive] = React.useState(''); const [hover, setHover] = React.useState(null); const [mobileOpen, setMobileOpen] = React.useState(false); const navRef = React.useRef(null); const linkRefs = React.useRef({}); const [indicator, setIndicator] = React.useState({ left: 0, width: 0, visible: false }); const nav = window.LB_DATA.nav; // Lock scroll when mobile menu is open React.useEffect(() => { if (mobileOpen) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = ''; } return () => { document.body.style.overflow = ''; }; }, [mobileOpen]); React.useEffect(() => { const onScroll = () => { setScrolled(window.scrollY > 40); let cur = ''; for (const n of nav) { const el = document.getElementById(n.id); if (el && el.getBoundingClientRect().top < 160) cur = n.id; } setActive(cur); }; onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); // Animated underline indicator React.useEffect(() => { const id = hover || active; const el = linkRefs.current[id]; const wrap = navRef.current; if (el && wrap) { const a = el.getBoundingClientRect(); const b = wrap.getBoundingClientRect(); setIndicator({ left: a.left - b.left, width: a.width, visible: true }); } else { setIndicator(s => ({ ...s, visible: false })); } }, [hover, active, scrolled]); const go = (e, id) => { e.preventDefault(); const el = document.getElementById(id); if (el) window.scrollTo({ top: el.offsetTop - 72, behavior: 'smooth' }); }; const onDark = !scrolled; return (
{/* Wordmark — prominent, single line */} go(e,'top')} style={{ display:'flex', alignItems:'center', gap:12, textDecoration:'none', color:'inherit', flexShrink: 0 }}> LatentBio {/* Nav */} {/* Mobile hamburger — inline display:none so it can never leak to desktop. CSS media query re-enables it on mobile with !important. */}
{/* Mobile overlay — only rendered when open. Since the hamburger is display:none on desktop, mobileOpen can only become true on mobile. Bulletproof against missing CSS. */} {mobileOpen && (
{nav.map(n => ( { go(e, n.id); setMobileOpen(false); }}> {n.label} ))} { go(e,'contact'); setMobileOpen(false); }}> Request Partnership
)}
); } window.Header = Header;