{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "header",
  "title": "Header",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/header/header-01.component.ts",
      "content": "// Sticky marketing top nav. Brand + 5 links + sign-in/CTA on desktop, hamburger +\n// right-side Sheet on mobile. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core'\nimport { Boxes, LucideAngularModule, Menu, X } from 'lucide-angular'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiSheetCloseComponent, UiSheetComponent, UiSheetContentComponent } from '@/ui/sheet/sheet.component'\n\nconst links = [\n  { label: 'Features', href: '#features' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Customers', href: '#customers' },\n  { label: 'Docs', href: '#docs' },\n  { label: 'Blog', href: '#blog' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-header-01, [ui-header-01]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [LucideAngularModule, UiButtonComponent, UiSheetCloseComponent, UiSheetComponent, UiSheetContentComponent],\n  template: `\n    <header\n      data-slot=\"header-01\"\n      class=\"bg-background/80 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-40 border-b backdrop-blur\"\n    >\n      <div class=\"mx-auto flex h-16 max-w-6xl items-center justify-between px-6\">\n        <a href=\"#\" class=\"flex items-center gap-2\">\n          <div class=\"bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-md\">\n            <lucide-icon [img]=\"Boxes\" class=\"size-4\" />\n          </div>\n          <span class=\"text-base font-semibold\">Acme</span>\n        </a>\n        <nav class=\"hidden items-center gap-6 md:flex\" aria-label=\"Primary\">\n          @for (link of links; track link.href) {\n            <a [href]=\"link.href\" class=\"text-muted-foreground hover:text-foreground text-sm transition-colors\">{{\n              link.label\n            }}</a>\n          }\n        </nav>\n        <div class=\"hidden items-center gap-2 md:flex\">\n          <button ui-button variant=\"ghost\" size=\"sm\">Sign in</button>\n          <button ui-button size=\"sm\">Start free trial</button>\n        </div>\n        <div ui-sheet [open]=\"mobileOpen()\" (openChange)=\"mobileOpen.set($event)\">\n          <button\n            ui-button\n            variant=\"ghost\"\n            size=\"icon\"\n            class=\"md:hidden\"\n            aria-label=\"Open menu\"\n            (click)=\"mobileOpen.set(true)\"\n          >\n            <lucide-icon [img]=\"Menu\" class=\"size-5\" />\n          </button>\n          <div ui-sheet-content side=\"right\" class=\"w-72\">\n            <div class=\"flex h-full flex-col\">\n              <div class=\"flex items-center justify-between border-b px-4 py-3\">\n                <div class=\"flex items-center gap-2\">\n                  <div class=\"bg-primary text-primary-foreground flex size-7 items-center justify-center rounded-md\">\n                    <lucide-icon [img]=\"Boxes\" class=\"size-3.5\" />\n                  </div>\n                  <span class=\"text-sm font-semibold\">Acme</span>\n                </div>\n                <button\n                  ui-button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  class=\"size-8\"\n                  aria-label=\"Close menu\"\n                  (click)=\"mobileOpen.set(false)\"\n                >\n                  <lucide-icon [img]=\"X\" class=\"size-4\" />\n                </button>\n              </div>\n              <nav class=\"flex flex-1 flex-col gap-1 p-4\" aria-label=\"Mobile\">\n                @for (link of links; track link.href) {\n                  <a\n                    [href]=\"link.href\"\n                    class=\"hover:bg-muted rounded-md px-3 py-2 text-sm transition-colors\"\n                    (click)=\"mobileOpen.set(false)\"\n                    >{{ link.label }}</a\n                  >\n                }\n              </nav>\n              <div class=\"flex flex-col gap-2 border-t p-4\">\n                <button ui-button variant=\"outline\" class=\"w-full\">Sign in</button>\n                <button ui-button class=\"w-full\">Start free trial</button>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </header>\n  `,\n})\nexport class UiHeader01Component {\n  protected readonly Boxes = Boxes\n  protected readonly Menu = Menu\n  protected readonly X = X\n  protected readonly links = links\n  readonly mobileOpen = signal(false)\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/header/header-01.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/header/header-announcement-stack.component.ts",
      "content": "// Two-tier header. A dismissible announcement strip sits above a sticky navbar;\n// dismissing it collapses the strip and the navbar settles flush to the top without a jump.\n// Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, OnInit, signal } from '@angular/core'\nimport { ArrowRight, Layers, LucideAngularModule, Menu, X } from 'lucide-angular'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport {\n  UiSheetComponent,\n  UiSheetContentComponent,\n  UiSheetHeaderComponent,\n  UiSheetTitleComponent,\n} from '@/ui/sheet/sheet.component'\n\nconst STORAGE_KEY = 'uipkge:announcement-dismissed'\n\nconst links = [\n  { label: 'Platform', href: '#platform' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Customers', href: '#customers' },\n  { label: 'Docs', href: '#docs' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-header-announcement-stack, [ui-header-announcement-stack]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiSeparatorComponent,\n    UiSheetComponent,\n    UiSheetContentComponent,\n    UiSheetHeaderComponent,\n    UiSheetTitleComponent,\n  ],\n  template: `\n    <div data-slot=\"header-announcement-stack\" class=\"sticky top-0 z-40\">\n      @if (!dismissed()) {\n        <div class=\"border-border bg-muted/60 border-b backdrop-blur\">\n          <div class=\"mx-auto flex h-10 max-w-6xl items-center gap-3 px-6 text-sm\">\n            <span ui-badge variant=\"secondary\" class=\"shrink-0\">New</span>\n            <p class=\"min-w-0 truncate\">\n              Row-level scoping now evaluates against SCIM groups.\n              <a href=\"#changelog\" class=\"hover:text-foreground underline underline-offset-4\"> Read the changelog</a>\n            </p>\n            <lucide-icon [img]=\"ArrowRight\" class=\"text-muted-foreground hidden size-3.5 shrink-0 sm:block\" />\n            <button\n              ui-button\n              variant=\"ghost\"\n              size=\"icon\"\n              class=\"ml-auto size-7 shrink-0\"\n              aria-label=\"Dismiss announcement\"\n              (click)=\"dismiss()\"\n            >\n              <lucide-icon [img]=\"X\" class=\"size-3.5\" />\n            </button>\n          </div>\n        </div>\n      }\n      <header class=\"border-border bg-background/90 border-b backdrop-blur\">\n        <div class=\"mx-auto flex h-16 max-w-6xl items-center gap-6 px-6\">\n          <a href=\"#top\" class=\"flex shrink-0 items-center gap-2 font-semibold tracking-tight\">\n            <lucide-icon [img]=\"Layers\" class=\"text-primary size-5\" />\n            Northwind\n          </a>\n          <nav class=\"hidden items-center gap-1 md:flex\" aria-label=\"Primary\">\n            @for (link of links; track link.href) {\n              <a\n                [href]=\"link.href\"\n                class=\"text-muted-foreground hover:text-foreground hover:bg-muted focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n                >{{ link.label }}</a\n              >\n            }\n          </nav>\n          <div class=\"ml-auto hidden items-center gap-2 md:flex\">\n            <button ui-button variant=\"ghost\" size=\"sm\">Sign in</button>\n            <button ui-button size=\"sm\">Book a demo</button>\n          </div>\n          <div ui-sheet [open]=\"open()\" (openChange)=\"open.set($event)\">\n            <button\n              ui-button\n              variant=\"ghost\"\n              size=\"icon\"\n              class=\"ml-auto md:hidden\"\n              aria-label=\"Open navigation menu\"\n              (click)=\"open.set(true)\"\n            >\n              <lucide-icon [img]=\"Menu\" class=\"size-5\" />\n            </button>\n            <div ui-sheet-content side=\"right\" class=\"w-72\">\n              <div ui-sheet-header>\n                <h2 ui-sheet-title>Menu</h2>\n              </div>\n              <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n                @for (link of links; track link.href) {\n                  <a\n                    [href]=\"link.href\"\n                    class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                    (click)=\"open.set(false)\"\n                    >{{ link.label }}</a\n                  >\n                }\n              </nav>\n              <ui-separator class=\"my-5\" />\n              <div class=\"grid gap-2\">\n                <button ui-button variant=\"outline\">Sign in</button>\n                <button ui-button>Book a demo</button>\n              </div>\n            </div>\n          </div>\n        </div>\n      </header>\n    </div>\n  `,\n})\nexport class UiHeaderAnnouncementStackComponent implements OnInit {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Layers = Layers\n  protected readonly Menu = Menu\n  protected readonly X = X\n  protected readonly links = links\n\n  readonly dismissed = signal(false)\n  readonly open = signal(false)\n\n  ngOnInit(): void {\n    try {\n      this.dismissed.set(window.sessionStorage.getItem(STORAGE_KEY) === '1')\n    } catch {\n      this.dismissed.set(false)\n    }\n  }\n\n  dismiss(): void {\n    this.dismissed.set(true)\n    try {\n      window.sessionStorage.setItem(STORAGE_KEY, '1')\n    } catch {\n      // Blocked storage: the dismissal still holds for this page view.\n    }\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/header/header-announcement-stack.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/header/header-centered-logo.component.ts",
      "content": "// Symmetrical navbar: wordmark centred between two nav halves with a utility cluster on\n// the right. Below the breakpoint the split collapses into one sheet trigger.\n// Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core'\nimport { Compass, LucideAngularModule, Menu, ShoppingBag, User } from 'lucide-angular'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport {\n  UiSheetComponent,\n  UiSheetContentComponent,\n  UiSheetHeaderComponent,\n  UiSheetTitleComponent,\n} from '@/ui/sheet/sheet.component'\n\nconst leftLinks = [\n  { label: 'Collections', href: '#collections' },\n  { label: 'New in', href: '#new' },\n  { label: 'Studio', href: '#studio' },\n]\nconst rightLinks = [\n  { label: 'Journal', href: '#journal' },\n  { label: 'Stockists', href: '#stockists' },\n  { label: 'Contact', href: '#contact' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-header-centered-logo, [ui-header-centered-logo]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiButtonComponent,\n    UiSeparatorComponent,\n    UiSheetComponent,\n    UiSheetContentComponent,\n    UiSheetHeaderComponent,\n    UiSheetTitleComponent,\n  ],\n  template: `\n    <header data-slot=\"header-centered-logo\" class=\"border-border bg-background border-b\">\n      <div class=\"mx-auto flex h-16 max-w-6xl items-center px-6\">\n        <nav class=\"hidden flex-1 basis-0 items-center gap-1 lg:flex\" aria-label=\"Primary left\">\n          @for (link of leftLinks; track link.href) {\n            <a [href]=\"link.href\" [class]=\"linkClass\">{{ link.label }}</a>\n          }\n        </nav>\n        <div ui-sheet [open]=\"open()\" (openChange)=\"open.set($event)\">\n          <button\n            ui-button\n            variant=\"ghost\"\n            size=\"icon\"\n            class=\"lg:hidden\"\n            aria-label=\"Open navigation menu\"\n            (click)=\"open.set(true)\"\n          >\n            <lucide-icon [img]=\"Menu\" class=\"size-5\" />\n          </button>\n          <div ui-sheet-content side=\"left\" class=\"w-72\">\n            <div ui-sheet-header>\n              <h2 ui-sheet-title>Menu</h2>\n            </div>\n            <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n              @for (link of allLinks; track link.href) {\n                <a\n                  [href]=\"link.href\"\n                  class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                  (click)=\"open.set(false)\"\n                  >{{ link.label }}</a\n                >\n              }\n            </nav>\n            <ui-separator class=\"my-5\" />\n            <button ui-button class=\"w-full\">Account</button>\n          </div>\n        </div>\n        <a\n          href=\"#top\"\n          class=\"mx-auto flex items-center gap-2 text-base font-semibold tracking-[0.18em] uppercase lg:mx-6\"\n        >\n          <lucide-icon [img]=\"Compass\" class=\"text-primary size-4\" />\n          Halden\n        </a>\n        <nav class=\"hidden flex-1 basis-0 items-center justify-end gap-1 lg:flex\" aria-label=\"Primary right\">\n          @for (link of rightLinks; track link.href) {\n            <a [href]=\"link.href\" [class]=\"linkClass\">{{ link.label }}</a>\n          }\n        </nav>\n        <div class=\"flex items-center gap-1 lg:ml-4\">\n          <button ui-button variant=\"ghost\" size=\"icon\" aria-label=\"Account\">\n            <lucide-icon [img]=\"User\" class=\"size-4\" />\n          </button>\n          <button ui-button variant=\"ghost\" size=\"icon\" aria-label=\"Bag\">\n            <lucide-icon [img]=\"ShoppingBag\" class=\"size-4\" />\n          </button>\n        </div>\n      </div>\n    </header>\n  `,\n})\nexport class UiHeaderCenteredLogoComponent {\n  protected readonly Compass = Compass\n  protected readonly Menu = Menu\n  protected readonly ShoppingBag = ShoppingBag\n  protected readonly User = User\n  protected readonly leftLinks = leftLinks\n  protected readonly rightLinks = rightLinks\n  protected readonly allLinks = [...leftLinks, ...rightLinks]\n  protected readonly linkClass =\n    'text-muted-foreground hover:text-foreground focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none'\n  readonly open = signal(false)\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/header/header-centered-logo.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/header/header-floating-pill.component.ts",
      "content": "// Detached pill navbar floating above the page. A sliding indicator tracks the active link\n// on hover and selection; the CTA stays pinned on the right. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, computed, signal } from '@angular/core'\nimport { CircleDot, LucideAngularModule, Menu } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiSheetComponent,\n  UiSheetContentComponent,\n  UiSheetHeaderComponent,\n  UiSheetTitleComponent,\n} from '@/ui/sheet/sheet.component'\n\nconst links = [\n  { label: 'Product', href: '#product' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Customers', href: '#customers' },\n  { label: 'Docs', href: '#docs' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-header-floating-pill, [ui-header-floating-pill]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiButtonComponent,\n    UiSheetComponent,\n    UiSheetContentComponent,\n    UiSheetHeaderComponent,\n    UiSheetTitleComponent,\n  ],\n  template: `\n    <div data-slot=\"header-floating-pill\" class=\"pointer-events-none sticky top-0 z-40 px-4 pt-4\">\n      <header\n        class=\"border-border bg-card/85 pointer-events-auto mx-auto flex h-14 max-w-4xl items-center gap-3 rounded-full border px-3 shadow-sm backdrop-blur\"\n      >\n        <a href=\"#top\" class=\"flex shrink-0 items-center gap-2 pl-2 font-semibold tracking-tight\">\n          <lucide-icon [img]=\"CircleDot\" class=\"text-primary size-4\" />\n          Verity\n        </a>\n        <nav class=\"relative hidden items-center md:flex\" aria-label=\"Primary\">\n          <span\n            class=\"bg-muted absolute inset-y-1 rounded-full transition-colors duration-200 ease-out\"\n            [style.left]=\"indicatorLeft()\"\n            [style.width]=\"indicatorWidth()\"\n            aria-hidden=\"true\"\n          ></span>\n          @for (link of links; track link.href; let i = $index) {\n            <a\n              [href]=\"link.href\"\n              data-pill-link\n              [class]=\"pillLinkClass(i)\"\n              [attr.aria-current]=\"i === active() ? 'page' : null\"\n              (mouseenter)=\"hovered.set(i)\"\n              (mouseleave)=\"hovered.set(null)\"\n              (focus)=\"hovered.set(i)\"\n              (blur)=\"hovered.set(null)\"\n              (click)=\"active.set(i)\"\n              >{{ link.label }}</a\n            >\n          }\n        </nav>\n        <button ui-button size=\"sm\" class=\"ml-auto rounded-full\">Start free</button>\n        <div ui-sheet [open]=\"open()\" (openChange)=\"open.set($event)\">\n          <button\n            ui-button\n            variant=\"ghost\"\n            size=\"icon\"\n            class=\"rounded-full md:hidden\"\n            aria-label=\"Open navigation menu\"\n            (click)=\"open.set(true)\"\n          >\n            <lucide-icon [img]=\"Menu\" class=\"size-5\" />\n          </button>\n          <div ui-sheet-content side=\"top\">\n            <div ui-sheet-header>\n              <h2 ui-sheet-title>Menu</h2>\n            </div>\n            <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n              @for (link of links; track link.href) {\n                <a\n                  [href]=\"link.href\"\n                  class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                  (click)=\"open.set(false)\"\n                  >{{ link.label }}</a\n                >\n              }\n            </nav>\n          </div>\n        </div>\n      </header>\n    </div>\n  `,\n})\nexport class UiHeaderFloatingPillComponent {\n  protected readonly CircleDot = CircleDot\n  protected readonly Menu = Menu\n  protected readonly links = links\n\n  readonly active = signal(0)\n  readonly hovered = signal<number | null>(null)\n  readonly open = signal(false)\n\n  /** Indicator follows hover, falling back to the selected link (measured slots are even widths). */\n  readonly indicatorLeft = computed(() => `${(this.hovered() ?? this.active()) * 88}px`)\n  readonly indicatorWidth = computed(() => '76px')\n\n  pillLinkClass(i: number): string {\n    return cn(\n      'focus-visible:ring-ring relative rounded-full px-3.5 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n      i === (this.hovered() ?? this.active()) || (this.hovered() === null && i === this.active())\n        ? 'text-foreground'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/header/header-floating-pill.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/header/header-mega-menu.component.ts",
      "content": "// Navbar with full-width mega panels. Product and Resources open grouped link lists with\n// descriptions and a highlighted card. Port of the React block 1:1 (desktop hover panels\n// driven by local state; mobile falls back to a sheet).\nimport { ChangeDetectionStrategy, Component, signal } from '@angular/core'\nimport {\n  ArrowRight,\n  BarChart3,\n  BookOpen,\n  Boxes,\n  Layers,\n  LifeBuoy,\n  Lock,\n  LucideAngularModule,\n  Menu,\n  Workflow,\n  type LucideIconData,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport {\n  UiSheetComponent,\n  UiSheetContentComponent,\n  UiSheetHeaderComponent,\n  UiSheetTitleComponent,\n} from '@/ui/sheet/sheet.component'\n\ninterface MegaItem {\n  icon: LucideIconData\n  title: string\n  body: string\n}\ninterface MegaGroup {\n  heading: string\n  items: MegaItem[]\n}\ninterface MegaMenu {\n  label: string\n  groups: MegaGroup[]\n  highlight: { title: string; body: string; cta: string }\n}\n\nconst menus: MegaMenu[] = [\n  {\n    label: 'Product',\n    groups: [\n      {\n        heading: 'Core',\n        items: [\n          { icon: Boxes, title: 'Metric layer', body: 'Versioned definitions your whole org shares.' },\n          { icon: BarChart3, title: 'Dashboards', body: 'Composed from certified metrics, not raw SQL.' },\n          { icon: Workflow, title: 'Pipelines', body: 'Scheduled materialisation with cost ceilings.' },\n        ],\n      },\n      {\n        heading: 'Governance',\n        items: [\n          { icon: Lock, title: 'Row-level access', body: 'Scope evaluated per query, per identity.' },\n          { icon: BookOpen, title: 'Change history', body: 'Every definition edit reviewed and revertible.' },\n          { icon: LifeBuoy, title: 'Audit exports', body: 'Generated from the same history, not by hand.' },\n        ],\n      },\n    ],\n    highlight: {\n      title: 'Ship your first dashboard today',\n      body: 'Connect a warehouse, publish one certified metric, and invite the team. No migration required.',\n      cta: 'Start the walkthrough',\n    },\n  },\n  {\n    label: 'Resources',\n    groups: [\n      {\n        heading: 'Learn',\n        items: [\n          { icon: BookOpen, title: 'Documentation', body: 'Setup, modelling, and the access model.' },\n          { icon: Layers, title: 'Guides', body: 'Reconciliation and first-close checklists.' },\n          { icon: BarChart3, title: 'Benchmarks', body: 'Close speed across 240 finance teams.' },\n        ],\n      },\n      {\n        heading: 'Support',\n        items: [\n          { icon: LifeBuoy, title: 'Help centre', body: 'Answers to the questions support gets most.' },\n          { icon: Workflow, title: 'Status', body: 'Live uptime and incident history.' },\n          { icon: Lock, title: 'Trust centre', body: 'SOC 2, subprocessors, and data residency.' },\n        ],\n      },\n    ],\n    highlight: {\n      title: 'Read the rollout plan',\n      body: 'The five-week implementation we run for every customer, written down so you can run it yourself.',\n      cta: 'Open the plan',\n    },\n  },\n]\n\nconst plainLinks = [\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Customers', href: '#customers' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-header-mega-menu, [ui-header-mega-menu]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiButtonComponent,\n    UiSeparatorComponent,\n    UiSheetComponent,\n    UiSheetContentComponent,\n    UiSheetHeaderComponent,\n    UiSheetTitleComponent,\n  ],\n  template: `\n    <header data-slot=\"header-mega-menu\" class=\"border-border bg-background/90 border-b backdrop-blur\">\n      <div class=\"mx-auto flex h-16 max-w-6xl items-center gap-6 px-6\">\n        <a href=\"#top\" class=\"flex shrink-0 items-center gap-2 font-semibold tracking-tight\">\n          <lucide-icon [img]=\"Layers\" class=\"text-primary size-5\" />\n          Northwind\n        </a>\n        <nav class=\"hidden lg:flex\" aria-label=\"Primary\">\n          <ul class=\"flex items-center gap-1\">\n            @for (menu of menus; track menu.label) {\n              <li class=\"relative\" (mouseenter)=\"openMenu.set(menu.label)\" (mouseleave)=\"openMenu.set(null)\">\n                <button\n                  type=\"button\"\n                  [class]=\"triggerClass(menu.label)\"\n                  [attr.aria-expanded]=\"openMenu() === menu.label\"\n                  (click)=\"toggleMenu(menu.label)\"\n                  (keydown.escape)=\"openMenu.set(null)\"\n                >\n                  {{ menu.label }}\n                </button>\n                @if (openMenu() === menu.label) {\n                  <div class=\"absolute top-full left-0 z-50 pt-2\">\n                    <div\n                      class=\"border-border bg-popover grid w-[46rem] grid-cols-[1fr_1fr_16rem] gap-6 rounded-lg border p-6 shadow-md\"\n                    >\n                      @for (group of menu.groups; track group.heading) {\n                        <div>\n                          <p class=\"text-muted-foreground font-mono text-xs tracking-[0.14em] uppercase\">\n                            {{ group.heading }}\n                          </p>\n                          <ul class=\"mt-3 space-y-1\">\n                            @for (item of group.items; track item.title) {\n                              <li>\n                                <a\n                                  href=\"#\"\n                                  class=\"hover:bg-muted focus-visible:ring-ring flex gap-3 rounded-md p-2 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n                                >\n                                  <lucide-icon [img]=\"item.icon\" class=\"text-muted-foreground mt-0.5 size-4 shrink-0\" />\n                                  <span class=\"min-w-0\">\n                                    <span class=\"block text-sm font-medium\">{{ item.title }}</span>\n                                    <span class=\"text-muted-foreground block text-xs leading-snug\">{{\n                                      item.body\n                                    }}</span>\n                                  </span>\n                                </a>\n                              </li>\n                            }\n                          </ul>\n                        </div>\n                      }\n                      <div class=\"bg-muted/50 flex flex-col rounded-lg p-4\">\n                        <p class=\"text-sm font-semibold\">{{ menu.highlight.title }}</p>\n                        <p class=\"text-muted-foreground mt-2 text-xs leading-relaxed\">{{ menu.highlight.body }}</p>\n                        <button ui-button variant=\"link\" class=\"mt-auto h-auto justify-start p-0 pt-4 text-xs\">\n                          {{ menu.highlight.cta }}\n                          <lucide-icon [img]=\"ArrowRight\" class=\"ml-1 size-3\" />\n                        </button>\n                      </div>\n                    </div>\n                  </div>\n                }\n              </li>\n            }\n            @for (link of plainLinks; track link.href) {\n              <li>\n                <a\n                  [href]=\"link.href\"\n                  class=\"hover:bg-muted hover:text-foreground focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n                  >{{ link.label }}</a\n                >\n              </li>\n            }\n          </ul>\n        </nav>\n        <div class=\"ml-auto flex items-center gap-2\">\n          <button ui-button variant=\"ghost\" size=\"sm\" class=\"hidden sm:inline-flex\">Sign in</button>\n          <ui-separator orientation=\"vertical\" class=\"hidden h-5 sm:block\" />\n          <button ui-button size=\"sm\">Book a demo</button>\n        </div>\n        <div ui-sheet [open]=\"open()\" (openChange)=\"open.set($event)\">\n          <button\n            ui-button\n            variant=\"ghost\"\n            size=\"icon\"\n            class=\"ml-auto lg:hidden\"\n            aria-label=\"Open navigation menu\"\n            (click)=\"open.set(true)\"\n          >\n            <lucide-icon [img]=\"Menu\" class=\"size-5\" />\n          </button>\n          <div ui-sheet-content side=\"right\" class=\"w-72 overflow-y-auto\">\n            <div ui-sheet-header>\n              <h2 ui-sheet-title>Menu</h2>\n            </div>\n            <nav class=\"mt-6 grid gap-5\" aria-label=\"Mobile\">\n              @for (menu of menus; track menu.label) {\n                <div>\n                  <p class=\"text-muted-foreground/70 text-xs font-medium tracking-wide uppercase\">{{ menu.label }}</p>\n                  <ul class=\"mt-2 grid gap-1\">\n                    @for (group of menu.groups; track group.heading) {\n                      @for (item of group.items; track item.title) {\n                        <li>\n                          <a\n                            href=\"#\"\n                            class=\"hover:bg-muted block rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                            (click)=\"open.set(false)\"\n                            >{{ item.title }}</a\n                          >\n                        </li>\n                      }\n                    }\n                  </ul>\n                </div>\n              }\n              <ui-separator />\n              @for (link of plainLinks; track link.href) {\n                <a\n                  [href]=\"link.href\"\n                  class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                  (click)=\"open.set(false)\"\n                  >{{ link.label }}</a\n                >\n              }\n              <ui-separator />\n              <div class=\"grid gap-2\">\n                <button ui-button variant=\"outline\">Sign in</button>\n                <button ui-button>Book a demo</button>\n              </div>\n            </nav>\n          </div>\n        </div>\n      </div>\n    </header>\n  `,\n})\nexport class UiHeaderMegaMenuComponent {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Layers = Layers\n  protected readonly Menu = Menu\n  protected readonly menus = menus\n  protected readonly plainLinks = plainLinks\n\n  readonly open = signal(false)\n  readonly openMenu = signal<string | null>(null)\n\n  toggleMenu(label: string): void {\n    this.openMenu.set(this.openMenu() === label ? null : label)\n  }\n\n  triggerClass(label: string): string {\n    return cn(\n      'hover:bg-muted hover:text-foreground focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n      this.openMenu() === label && 'bg-muted text-foreground',\n    )\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/header/header-mega-menu.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/header/header-search-command.component.ts",
      "content": "// Navbar with inline search. Click the field or press ⌘K to open a command palette of\n// grouped results; Escape closes and the shortcut hint stays visible in the trigger.\n// Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, HostListener, signal } from '@angular/core'\nimport {\n  BarChart3,\n  BookOpen,\n  Compass,\n  FileText,\n  History,\n  LucideAngularModule,\n  Menu,\n  Search,\n  Users,\n  type LucideIconData,\n} from 'lucide-angular'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCommandDialogComponent,\n  UiCommandEmptyComponent,\n  UiCommandGroupComponent,\n  UiCommandInputComponent,\n  UiCommandItemComponent,\n  UiCommandListComponent,\n} from '@/ui/command/command.component'\nimport { UiKbdComponent } from '@/ui/kbd/kbd.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport {\n  UiSheetComponent,\n  UiSheetContentComponent,\n  UiSheetHeaderComponent,\n  UiSheetTitleComponent,\n} from '@/ui/sheet/sheet.component'\n\nconst links = [\n  { label: 'Product', href: '#product' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Docs', href: '#docs' },\n]\n\ninterface SearchGroup {\n  heading: string\n  items: { icon: LucideIconData; label: string }[]\n}\n\nconst groups: SearchGroup[] = [\n  {\n    heading: 'Documentation',\n    items: [\n      { icon: BookOpen, label: 'Connect a warehouse' },\n      { icon: FileText, label: 'Define your first metric' },\n      { icon: BarChart3, label: 'Publish a dashboard' },\n    ],\n  },\n  {\n    heading: 'Company',\n    items: [\n      { icon: Users, label: 'Customer stories' },\n      { icon: History, label: 'Changelog' },\n    ],\n  },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-header-search-command, [ui-header-search-command]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiButtonComponent,\n    UiCommandDialogComponent,\n    UiCommandEmptyComponent,\n    UiCommandGroupComponent,\n    UiCommandInputComponent,\n    UiCommandItemComponent,\n    UiCommandListComponent,\n    UiKbdComponent,\n    UiSeparatorComponent,\n    UiSheetComponent,\n    UiSheetContentComponent,\n    UiSheetHeaderComponent,\n    UiSheetTitleComponent,\n  ],\n  template: `\n    <header data-slot=\"header-search-command\" class=\"border-border bg-background/90 border-b backdrop-blur\">\n      <div class=\"mx-auto flex h-16 max-w-6xl items-center gap-4 px-6\">\n        <a href=\"#top\" class=\"flex shrink-0 items-center gap-2 font-semibold tracking-tight\">\n          <lucide-icon [img]=\"Compass\" class=\"text-primary size-5\" />\n          Halden\n        </a>\n        <nav class=\"hidden items-center gap-1 md:flex\" aria-label=\"Primary\">\n          @for (link of links; track link.href) {\n            <a\n              [href]=\"link.href\"\n              class=\"text-muted-foreground hover:text-foreground hover:bg-muted focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n              >{{ link.label }}</a\n            >\n          }\n        </nav>\n        <button\n          type=\"button\"\n          class=\"border-border bg-muted/40 text-muted-foreground hover:bg-muted focus-visible:ring-ring ml-auto flex h-9 w-full max-w-64 items-center gap-2 rounded-md border px-3 text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n          (click)=\"open.set(true)\"\n        >\n          <lucide-icon [img]=\"Search\" class=\"size-4 shrink-0\" />\n          <span class=\"truncate\">Search docs…</span>\n          <span ui-kbd class=\"ml-auto hidden sm:inline-flex\">⌘K</span>\n        </button>\n        <ui-separator orientation=\"vertical\" class=\"hidden h-5 md:block\" />\n        <button ui-button size=\"sm\" class=\"hidden shrink-0 sm:inline-flex\">Start free</button>\n        <div ui-sheet [open]=\"menuOpen()\" (openChange)=\"menuOpen.set($event)\">\n          <button\n            ui-button\n            variant=\"ghost\"\n            size=\"icon\"\n            class=\"shrink-0 md:hidden\"\n            aria-label=\"Open navigation menu\"\n            (click)=\"menuOpen.set(true)\"\n          >\n            <lucide-icon [img]=\"Menu\" class=\"size-5\" />\n          </button>\n          <div ui-sheet-content side=\"right\" class=\"w-72\">\n            <div ui-sheet-header>\n              <h2 ui-sheet-title>Menu</h2>\n            </div>\n            <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n              @for (link of links; track link.href) {\n                <a\n                  [href]=\"link.href\"\n                  class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                  (click)=\"menuOpen.set(false)\"\n                  >{{ link.label }}</a\n                >\n              }\n            </nav>\n            <ui-separator class=\"my-5\" />\n            <div class=\"grid gap-2\">\n              <button ui-button variant=\"outline\">Sign in</button>\n              <button ui-button>Start free</button>\n            </div>\n          </div>\n        </div>\n      </div>\n      <ui-command-dialog\n        [open]=\"open()\"\n        (openChange)=\"open.set($event)\"\n        title=\"Search documentation\"\n        description=\"Search documentation, guides, and stories\"\n      >\n        <ui-command-input placeholder=\"Search documentation, guides, and stories…\" />\n        <ui-command-list>\n          <ui-command-empty>No results.</ui-command-empty>\n          @for (group of groups; track group.heading) {\n            <ui-command-group [heading]=\"group.heading\">\n              @for (item of group.items; track item.label) {\n                <ui-command-item [value]=\"item.label\" (select)=\"open.set(false)\">\n                  <lucide-icon [img]=\"item.icon\" class=\"text-muted-foreground mr-2 size-4\" />\n                  {{ item.label }}\n                </ui-command-item>\n              }\n            </ui-command-group>\n          }\n        </ui-command-list>\n      </ui-command-dialog>\n    </header>\n  `,\n})\nexport class UiHeaderSearchCommandComponent {\n  protected readonly Compass = Compass\n  protected readonly Menu = Menu\n  protected readonly Search = Search\n  protected readonly links = links\n  protected readonly groups = groups\n\n  readonly open = signal(false)\n  readonly menuOpen = signal(false)\n\n  @HostListener('window:keydown', ['$event'])\n  onKeydown(event: KeyboardEvent): void {\n    if (event.key.toLowerCase() !== 'k' || !(event.metaKey || event.ctrlKey)) return\n    event.preventDefault()\n    this.open.set(!this.open())\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/header/header-search-command.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/header/header-transparent-scroll.component.ts",
      "content": "// Navbar that starts transparent over the hero and fades in a blurred, bordered surface\n// past the first scroll. Port of the React block 1:1 (starts unscrolled so server and first\n// client paint agree; the scroll listener is the only thing that swaps the surface).\nimport { ChangeDetectionStrategy, Component, HostListener, signal } from '@angular/core'\nimport { Layers, LucideAngularModule, Menu } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport {\n  UiSheetComponent,\n  UiSheetContentComponent,\n  UiSheetHeaderComponent,\n  UiSheetTitleComponent,\n} from '@/ui/sheet/sheet.component'\n\nconst links = [\n  { label: 'Product', href: '#product' },\n  { label: 'Solutions', href: '#solutions' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Docs', href: '#docs' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-header-transparent-scroll, [ui-header-transparent-scroll]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiButtonComponent,\n    UiSeparatorComponent,\n    UiSheetComponent,\n    UiSheetContentComponent,\n    UiSheetHeaderComponent,\n    UiSheetTitleComponent,\n  ],\n  template: `\n    <header data-slot=\"header-transparent-scroll\" [class]=\"headerClass\">\n      <div class=\"mx-auto flex h-16 max-w-6xl items-center gap-6 px-6\">\n        <a href=\"#top\" class=\"flex items-center gap-2 font-semibold tracking-tight\">\n          <lucide-icon [img]=\"Layers\" class=\"text-primary size-5\" />\n          Northwind\n        </a>\n        <nav class=\"hidden items-center gap-1 md:flex\" aria-label=\"Primary\">\n          @for (link of links; track link.href) {\n            <a\n              [href]=\"link.href\"\n              class=\"text-muted-foreground hover:text-foreground hover:bg-muted focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n              >{{ link.label }}</a\n            >\n          }\n        </nav>\n        <div class=\"ml-auto hidden items-center gap-2 md:flex\">\n          <button ui-button variant=\"ghost\" size=\"sm\">Sign in</button>\n          <button ui-button size=\"sm\">Start free</button>\n        </div>\n        <div ui-sheet [open]=\"open()\" (openChange)=\"open.set($event)\">\n          <button\n            ui-button\n            variant=\"ghost\"\n            size=\"icon\"\n            class=\"ml-auto md:hidden\"\n            aria-label=\"Open navigation menu\"\n            (click)=\"open.set(true)\"\n          >\n            <lucide-icon [img]=\"Menu\" class=\"size-5\" />\n          </button>\n          <div ui-sheet-content side=\"right\" class=\"w-72\">\n            <div ui-sheet-header>\n              <h2 ui-sheet-title>Menu</h2>\n            </div>\n            <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n              @for (link of links; track link.href) {\n                <a\n                  [href]=\"link.href\"\n                  class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                  (click)=\"open.set(false)\"\n                  >{{ link.label }}</a\n                >\n              }\n            </nav>\n            <ui-separator class=\"my-5\" />\n            <div class=\"grid gap-2\">\n              <button ui-button variant=\"outline\">Sign in</button>\n              <button ui-button>Start free</button>\n            </div>\n          </div>\n        </div>\n      </div>\n    </header>\n  `,\n})\nexport class UiHeaderTransparentScrollComponent {\n  protected readonly Layers = Layers\n  protected readonly Menu = Menu\n  protected readonly links = links\n\n  readonly scrolled = signal(false)\n  readonly open = signal(false)\n\n  @HostListener('window:scroll')\n  onScroll(): void {\n    this.scrolled.set(window.scrollY > 24)\n  }\n\n  get headerClass(): string {\n    return cn(\n      'fixed inset-x-0 top-0 z-40 transition-colors duration-200',\n      this.scrolled() ? 'border-border bg-background/85 border-b backdrop-blur' : 'border-b border-transparent',\n    )\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/header/header-transparent-scroll.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/header/index.ts",
      "content": "export { UiHeader01Component } from './header-01.component'\nexport { UiHeaderAnnouncementStackComponent } from './header-announcement-stack.component'\nexport { UiHeaderCenteredLogoComponent } from './header-centered-logo.component'\nexport { UiHeaderFloatingPillComponent } from './header-floating-pill.component'\nexport { UiHeaderMegaMenuComponent } from './header-mega-menu.component'\nexport { UiHeaderSearchCommandComponent } from './header-search-command.component'\nexport { UiHeaderTransparentScrollComponent } from './header-transparent-scroll.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/header/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/command.json",
    "https://uipkge.dev/r/angular/kbd.json",
    "https://uipkge.dev/r/angular/navigation-menu.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/sheet.json"
  ],
  "description": "Site header collection: sticky top bar, dismissible announcement stack, centered-logo split, floating pill, full-width mega menu, inline search with command palette, and a transparent-over-hero scroll variant — each with a mobile sheet fallback.",
  "categories": [
    "marketing"
  ]
}