"use client"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { Activity, Bell, Bookmark, Compass, Eye, Globe2, LayoutGrid, Radar, Search, Siren, X, Zap } from "lucide-react"; import { useState } from "react"; import { Mark } from "./brand"; import { DensityToggle } from "./prefs"; import { ThemeToggle } from "./theme"; import { Kbd } from "./ui"; const NAV = [ ["/live", "Live"], ["/breaking", "Breaking"], ["/pulse", "Pulse"], ["/radar", "Radar"], ["/silent", "Silent"], ["/explore", "Explore"], ["/entities", "Entities"], ["/sources", "Sources"], ["/coverage", "Coverage"], ["/watchlists", "Watchlists"], ["/alerts", "Alerts"], ] as const; export function Wordmark() { return ( WebSensor ); } export function TopNav() { const path = usePathname(); const openPalette = (): void => { window.dispatchEvent(new Event("ws:palette")); }; return ( {NAV.map(([href, label]) => { const active = href === "/live" ? path === "/" || path.startsWith("/live") : path.startsWith(href); return ( {label} ); })} Search entities, events, URLs… ⌘K ); } /** Mobile bottom navigation (spec §95): Live · Breaking · Explore · Watchlists · More (bottom sheet). */ export function MobileNav() { const path = usePathname(); const [moreFor, setMoreFor] = useState(null); const more = moreFor === path; const setMore = (v: boolean): void => setMoreFor(v ? path : null); const items = [ ["/live", "Live", Activity, path === "/" || path.startsWith("/live")], ["/breaking", "Breaking", Siren, path.startsWith("/breaking")], ["/explore", "Explore", Compass, path.startsWith("/explore")], ["/watchlists", "Watch", Eye, path.startsWith("/watchlists")], ] as const; const moreItems: [string, string, typeof Activity][] = [ ["/pulse", "Pulse", Zap], ["/radar", "Radar", Radar], ["/silent", "Silent changes", LayoutGrid], ["/entities", "Entities", Globe2], ["/sources", "Sources", Globe2], ["/coverage", "Coverage", Globe2], ["/country", "Countries", Globe2], ["/alerts", "Alerts", Bell], ["/bookmarks", "Bookmarks", Bookmark], ["/health", "Health", Activity], ["/api", "API", Zap], ]; return ( <> {items.map(([href, label, Icon, active]) => ( {label} ))} setMore(true)} aria-expanded={more} className={`flex flex-col items-center gap-0.5 py-2 text-[10.5px] ${more ? "text-signal" : "text-fg-muted"}`}> More {more && ( setMore(false)} className="scrim absolute inset-0 cursor-default" /> More setMore(false)} aria-label="Close" className="inline-flex size-7 items-center justify-center rounded-md border border-line"> {moreItems.map(([href, label, Icon]) => ( {label} ))} )} > ); }