"use client"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { type ReactNode, useEffect, useRef, useState } from "react"; import { IconArrow, IconClose, IconMenu } from "./Icons"; /** Client shell for the header: scroll shadow, current-page marking and the accessible mobile drawer. */ export function HeaderChrome({ links, children, }: { links: Array<{ href: string; label: string }>; children: ReactNode; }) { const [scrolled, setScrolled] = useState(false); const [open, setOpen] = useState(false); const pathname = usePathname(); const panel = useRef(null); const opener = useRef(null); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 4); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); // biome-ignore lint/correctness/useExhaustiveDependencies: close the drawer on navigation useEffect(() => { setOpen(false); }, [pathname]); useEffect(() => { if (!open) return; const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; const first = panel.current?.querySelector("a,button"); first?.focus(); const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") setOpen(false); if (e.key === "Tab" && panel.current) { const f = [ ...panel.current.querySelectorAll("a,button,input,[tabindex]:not([tabindex='-1'])"), ]; if (f.length === 0) return; const a = f[0]!; const b = f[f.length - 1]!; if (e.shiftKey && document.activeElement === a) { e.preventDefault(); b.focus(); } else if (!e.shiftKey && document.activeElement === b) { e.preventDefault(); a.focus(); } } }; document.addEventListener("keydown", onKey); return () => { document.body.style.overflow = prev; document.removeEventListener("keydown", onKey); opener.current?.focus(); }; }, [open]); return (
{children}
{open && ( <>

AI-generated working papers; not formally peer reviewed. Research computed on MacLustr.

)}
); }