"use client" import { useEffect, useRef, useState } from "react" import Image from "next/image" import { play } from "@/lib/sound" import { cn } from "@/lib/utils" import { mainNav, site } from "@/modules/shared/config/site" import { LiveClock } from "./live-clock" import { ScrambleLink } from "./scramble-link" import { SoundToggle } from "./sound-toggle" /** * Fixed header in `mix-blend-mode: difference`, so it stays readable on black * and on white sections. Hides while scrolling down, returns when scrolling up. */ export function SiteHeader() { const [hidden, setHidden] = useState(false) const [menuOpen, setMenuOpen] = useState(false) const firstLinkRef = useRef(null) const toggleRef = useRef(null) useEffect(() => { let lastY = window.scrollY const onScroll = () => { const y = window.scrollY if (Math.abs(y - lastY) < 6) return setHidden(y > lastY && y > 160) lastY = y } window.addEventListener("scroll", onScroll, { passive: true }) return () => window.removeEventListener("scroll", onScroll) }, []) useEffect(() => { if (!menuOpen) return firstLinkRef.current?.focus() const onKey = (event: KeyboardEvent) => { // Focus would otherwise fall through to once #mobile-menu goes inert if (event.key === "Escape") { setMenuOpen(false) toggleRef.current?.focus() } } document.documentElement.style.overflow = "hidden" window.addEventListener("keydown", onKey) return () => { document.documentElement.style.overflow = "" window.removeEventListener("keydown", onKey) } }, [menuOpen]) const close = () => setMenuOpen(false) return ( <>
{/* Outside the header so it does not get blended */}
) }