/** * Trouve-KA — navigation mobile (hamburger + panneau plein écran) * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * * Standard KA Nav v2 (2026-08-25) : * · bouton 44×44 (var(--touch)), visible uniquement < 768 px (md:hidden) ; * · panneau `fixed inset-0` (plein écran, z-modal) avec sa PROPRE barre de * fermeture ✕ — le burger du header ne sert qu'à ouvrir : si le header * n'est pas épinglé (bas de page), le ✕ interne reste visible ; * · le header n'a PAS de backdrop-filter, le fixed n'est pas re-parenté ; * · verrou de scroll via la classe ka-scroll-lock sur ; * · fermeture : ✕ interne, Escape (focus rendu au bouton), navigation ; * · liens géants numérotés (gk-display), safe-area iPhone en bas ; * · z-index : échelle --z-* des tokens (900 = --z-modal). */ "use client"; import { useEffect, useRef, useState } from "react"; import Link from "next/link"; import { usePathname } from "next/navigation"; interface MobileNavProps { links: ReadonlyArray<{ href: string; label: string }>; } export function MobileNav({ links }: MobileNavProps) { const [open, setOpen] = useState(false); const rootRef = useRef(null); const buttonRef = useRef(null); const pathname = usePathname(); // Fermeture à la navigation (le lien tapé a déjà déclenché le routage). useEffect(() => { setOpen(false); }, [pathname]); // Panneau ouvert : verrou de scroll + Escape + tap extérieur. useEffect(() => { if (!open) return; document.documentElement.classList.add("ka-scroll-lock"); const onKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { setOpen(false); buttonRef.current?.focus(); } }; const onPointerDown = (event: PointerEvent) => { if (rootRef.current && !rootRef.current.contains(event.target as Node)) { setOpen(false); } }; document.addEventListener("keydown", onKeyDown); document.addEventListener("pointerdown", onPointerDown); return () => { document.documentElement.classList.remove("ka-scroll-lock"); document.removeEventListener("keydown", onKeyDown); document.removeEventListener("pointerdown", onPointerDown); }; }, [open]); return (
{open && ( )}
); }