'use client';
import { useState } from 'react';
import { usePathname } from 'next/navigation';
import { useAuth } from '@/contexts/AuthContext';
import { Wordmark, Ticker } from '@/components/vyndr';
import { HeartbeatBar } from '@/components/vyndr/LiveLayer';
import NotificationBell from '@/components/NotificationBell';
// Nav labels are English literals for now; nav-string i18n lands in Phase G
// (Session 38) once the locale dictionaries carry slate/terminal/etc. keys.
// VYNDR 2.0 nav (§6, Session 34). Primary links are SLATE / SCAN / LEDGER;
// everything else lives under a More dropdown. All nav chrome is
// JetBrains Mono, uppercase, 11px — system language, not SaaS sans. Active
// route is grade-green (--g-a); a Ticker runs under the bar.
// Session 57 (Phase 0) — TERMINAL removed: the surface was fabricated sample
// data (audit verdict REBUILD). Its layouts live on as §12 content-engine
// templates in components/intel/TerminalTemplates.tsx; "The Terminal" survives
// as brand language only. Don't re-add the link until it's fed real data.
const PRIMARY = [
{ id: 'slate', label: 'Slate', href: '/dashboard' },
{ id: 'scan', label: 'Scan', href: '/scan' },
{ id: 'ledger', label: 'Ledger', href: '/ledger' },
];
const MORE = [
{ label: 'Explore', href: '/explore' },
// Session 60 (4.4) — discoverable Parlay Lab entry (opens the drawer).
{ label: 'Parlay Lab', href: '#parlay', action: 'parlay' as const },
{ label: 'Compare', href: '/compare' },
{ label: 'Tracker', href: '/tracker' },
{ label: 'The Report', href: '/blog' },
{ label: 'Invite', href: '/invite' },
{ label: 'Pricing', href: '/pricing' },
{ label: 'Settings', href: '/settings' },
];
// Session 57 (Phase 0) — the hardcoded fallback ticker items (fake Wembanyama
// signal, "NYK vs SA Q3", invented Tatum move) are DELETED. The ticker renders
// only real /api/ticker snapshot exhaust, and hides itself entirely below 4
// real items (spec §3). Never seed it with fabricated content again.
function isActive(pathname: string, href: string) {
return pathname === href || pathname.startsWith(href + '/');
}
const linkStyle = (active: boolean) => ({
fontFamily: 'var(--mono)',
fontSize: 11,
fontWeight: 700,
letterSpacing: '0.08em',
textTransform: 'uppercase' as const,
color: active ? 'var(--g-a)' : 'var(--text-1)',
textDecoration: 'none',
whiteSpace: 'nowrap' as const,
transition: 'color .15s',
background: 'transparent',
border: 'none',
cursor: 'pointer',
padding: '6px 4px',
});
export default function Nav() {
const { user, tier, scansRemaining, signOut } = useAuth();
const pathname = usePathname() || '';
const [menuOpen, setMenuOpen] = useState(false);
const [moreOpen, setMoreOpen] = useState(false);
const [mobileOpen, setMobileOpen] = useState(false);
const showReadCounter =
pathname.startsWith('/scan') || pathname.startsWith('/dashboard');
const moreActive = MORE.some((l) => isActive(pathname, l.href));
return (
{/* Ticker + heartbeat under the bar (§8 living layer). No fallback
items — real snapshot exhaust or nothing. */}
);
}
const menuItem: React.CSSProperties = {
display: 'block',
padding: '10px 12px',
fontSize: 13,
color: 'var(--text-1)',
textDecoration: 'none',
fontFamily: 'var(--sans)',
};