{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "site-header-narrow",
  "title": "Site Header Narrow",
  "description": "Sticky 640px personal header with mono nav and theme icon.",
  "dependencies": [
    "lucide-react",
    "next",
    "next-themes"
  ],
  "registryDependencies": [
    "@atroui/utils",
    "@atroui/brand",
    "@atroui/theme-toggle-icon"
  ],
  "files": [
    {
      "path": "registry/default/blocks/site-header-narrow.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport Link from \"next/link\"\nimport { usePathname } from \"next/navigation\"\nimport { Menu, Moon, Sun } from \"lucide-react\"\nimport { useTheme } from \"next-themes\"\n\nimport { getBrand } from \"@/lib/brand\"\nimport { cn } from \"@/lib/utils\"\n\nconst CONTENT = {\n  siteName: \"\",\n  primaryNav: [\n    { href: \"/projects\", label: \"projects\" },\n    { href: \"/writing\", label: \"writing\" },\n    { href: \"/resume\", label: \"resume\" },\n  ] as Array<{ href: string; label: string; external?: boolean }>,\n  moreNav: [\n    { href: \"/log\", label: \"log\" },\n    { href: \"/stack\", label: \"stack\" },\n    { href: \"/contact\", label: \"contact\" },\n  ] as Array<{ href: string; label: string }>,\n}\n\n/** Inlined icon toggle so this block stays installable alone. */\nfunction ThemeToggleIcon({ className }: { className?: string }) {\n  const { resolvedTheme, setTheme } = useTheme()\n  const [mounted, setMounted] = React.useState(false)\n  React.useEffect(() => setMounted(true), [])\n\n  const isDark = mounted && resolvedTheme === \"dark\"\n  const next = isDark ? \"light\" : \"dark\"\n  const label = `Switch to ${next} mode`\n\n  return (\n    <button\n      type=\"button\"\n      aria-label={label}\n      title={label}\n      onClick={() => setTheme(next)}\n      className={cn(\n        \"inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground\",\n        className\n      )}\n    >\n      {!mounted ? (\n        <Sun className=\"h-[13px] w-[13px] opacity-0\" aria-hidden />\n      ) : isDark ? (\n        <Sun className=\"h-[13px] w-[13px]\" aria-hidden />\n      ) : (\n        <Moon className=\"h-[13px] w-[13px]\" aria-hidden />\n      )}\n    </button>\n  )\n}\n\nexport function SiteHeaderNarrow({\n  siteName,\n  primaryNav = CONTENT.primaryNav,\n  moreNav = CONTENT.moreNav,\n  onOpenCommand,\n  className,\n}: {\n  siteName?: string\n  primaryNav?: Array<{ href: string; label: string; external?: boolean }>\n  moreNav?: Array<{ href: string; label: string }>\n  onOpenCommand?: () => void\n  className?: string\n} = {}) {\n  const pathname = usePathname()\n  const [scrolled, setScrolled] = React.useState(false)\n  const wordmark = siteName || CONTENT.siteName || getBrand().name\n\n  React.useEffect(() => {\n    const onScroll = () => setScrolled(window.scrollY > 4)\n    onScroll()\n    window.addEventListener(\"scroll\", onScroll, { passive: true })\n    return () => window.removeEventListener(\"scroll\", onScroll)\n  }, [])\n\n  return (\n    <header\n      className={cn(\n        \"sticky top-0 z-50 border-b pt-[env(safe-area-inset-top)] transition-colors\",\n        scrolled\n          ? \"border-border-subtle bg-background/85 backdrop-blur-xl\"\n          : \"border-border-subtle/60 bg-background/50 backdrop-blur-md\",\n        className\n      )}\n    >\n      <div className=\"mx-auto flex h-[52px] max-w-[640px] items-center justify-between px-5\">\n        <Link\n          href=\"/\"\n          aria-label=\"Home\"\n          className=\"inline-flex items-center gap-2 hover:opacity-80\"\n        >\n          <span className=\"font-mono text-[12px] tracking-[-0.01em] text-muted-foreground\">\n            {wordmark}\n          </span>\n        </Link>\n\n        <nav className=\"flex items-center gap-0.5 text-[13px]\">\n          {primaryNav.map((item) => {\n            const active =\n              !item.external &&\n              (pathname === item.href ||\n                pathname.startsWith(`${item.href}/`))\n            const itemClass = cn(\n              \"rounded-md px-2 py-1 font-mono text-[12px] transition-colors\",\n              active\n                ? \"text-foreground\"\n                : \"text-muted-foreground hover:text-foreground\"\n            )\n\n            if (item.external) {\n              return (\n                <a\n                  key={item.href}\n                  href={item.href}\n                  target=\"_blank\"\n                  rel=\"noopener noreferrer\"\n                  className={itemClass}\n                >\n                  {item.label}\n                </a>\n              )\n            }\n\n            return (\n              <Link key={item.href} href={item.href} className={itemClass}>\n                {item.label}\n              </Link>\n            )\n          })}\n\n          {moreNav.length > 0 ? (\n            <MoreMenu pathname={pathname} items={moreNav} />\n          ) : null}\n\n          <span className=\"mx-1 h-3.5 w-px bg-border-subtle\" aria-hidden />\n          {onOpenCommand ? (\n            <button\n              type=\"button\"\n              onClick={onOpenCommand}\n              aria-label=\"Open command menu\"\n              title=\"Open command menu (⌘K)\"\n              className=\"ml-0.5 hidden items-center gap-1 rounded-md border border-border-subtle bg-muted px-1.5 py-[3px] font-mono text-[10.5px] text-muted-foreground hover:text-foreground sm:inline-flex\"\n            >\n              <kbd className=\"font-mono\">⌘</kbd>\n              <kbd className=\"font-mono\">K</kbd>\n            </button>\n          ) : null}\n          <ThemeToggleIcon />\n        </nav>\n      </div>\n    </header>\n  )\n}\n\nfunction MoreMenu({\n  pathname,\n  items,\n}: {\n  pathname: string\n  items: Array<{ href: string; label: string }>\n}) {\n  const [open, setOpen] = React.useState(false)\n  const rootRef = React.useRef<HTMLDivElement>(null)\n\n  const moreActive = items.some(\n    (item) =>\n      pathname === item.href || pathname.startsWith(`${item.href}/`)\n  )\n\n  React.useEffect(() => {\n    if (!open) return\n    const onPointer = (e: MouseEvent) => {\n      if (!rootRef.current?.contains(e.target as Node)) setOpen(false)\n    }\n    const onKey = (e: KeyboardEvent) => {\n      if (e.key === \"Escape\") setOpen(false)\n    }\n    document.addEventListener(\"mousedown\", onPointer)\n    document.addEventListener(\"keydown\", onKey)\n    return () => {\n      document.removeEventListener(\"mousedown\", onPointer)\n      document.removeEventListener(\"keydown\", onKey)\n    }\n  }, [open])\n\n  React.useEffect(() => {\n    setOpen(false)\n  }, [pathname])\n\n  return (\n    <div ref={rootRef} className=\"relative\">\n      <button\n        type=\"button\"\n        aria-label=\"More pages\"\n        aria-expanded={open}\n        aria-haspopup=\"menu\"\n        title=\"More\"\n        onClick={() => setOpen((v) => !v)}\n        className={cn(\n          \"inline-flex items-center justify-center rounded-md px-2 py-1 transition-colors\",\n          open || moreActive\n            ? \"text-foreground\"\n            : \"text-muted-foreground hover:text-foreground\"\n        )}\n      >\n        <Menu size={15} strokeWidth={1.75} aria-hidden />\n      </button>\n\n      {open ? (\n        <div\n          role=\"menu\"\n          className=\"absolute top-[calc(100%+6px)] right-0 z-50 min-w-[132px] rounded-md border border-border-subtle bg-background py-1 shadow-[0_8px_24px_rgba(0,0,0,0.08)] dark:shadow-[0_8px_24px_rgba(0,0,0,0.4)]\"\n        >\n          {items.map((item) => {\n            const active =\n              pathname === item.href || pathname.startsWith(`${item.href}/`)\n            return (\n              <Link\n                key={item.href}\n                href={item.href}\n                role=\"menuitem\"\n                className={cn(\n                  \"block px-3 py-1.5 font-mono text-[12px] transition-colors\",\n                  active\n                    ? \"bg-muted text-foreground\"\n                    : \"text-muted-foreground hover:bg-muted hover:text-foreground\"\n                )}\n              >\n                {item.label}\n              </Link>\n            )\n          })}\n        </div>\n      ) : null}\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/site-header-narrow.tsx"
    }
  ],
  "type": "registry:block"
}