{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "header",
  "title": "Header",
  "type": "registry:block",
  "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"
  ],
  "files": [
    {
      "path": "packages/elements-lit/src/blocks/header/header.ts",
      "content": "import { LitElement, css, html, isServer, nothing } from 'lit'\nimport {\n  ArrowRight,\n  BarChart3,\n  BookOpen,\n  Boxes,\n  CircleDot,\n  Compass,\n  FileText,\n  History,\n  Layers,\n  LifeBuoy,\n  Lock,\n  Menu,\n  Search,\n  ShoppingBag,\n  User,\n  Users,\n  Workflow,\n  X,\n  type IconNode,\n} from 'lucide'\nimport { cn } from '../../lib/utils'\nimport { tailwind } from '../../lib/styles'\nimport { ThemeController } from '../../lib/theme'\nimport { icon } from '../../lib/icon'\n// Side-effect imports: register the composed elements for standalone use\n// (consumers who install only this block still get working primitives).\nimport '../../components/badge/badge'\nimport '../../components/button/button'\nimport '../../components/command/command'\nimport '../../components/kbd/kbd'\nimport '../../components/navigation-menu/navigation-menu'\nimport '../../components/separator/separator'\nimport '../../components/sheet/sheet'\n\nexport type HeaderVariant =\n  | 'default'\n  | 'announcement'\n  | 'centered'\n  | 'pill'\n  | 'mega'\n  | 'search'\n  | 'transparent'\n\nconst STORAGE_KEY = 'uipkge:announcement-dismissed'\n\nconst defaultLinks = [\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\nconst stackLinks = [\n  { label: 'Platform', href: '#platform' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Customers', href: '#customers' },\n  { label: 'Docs', href: '#docs' },\n]\n\nconst centeredLeft = [\n  { label: 'Collections', href: '#collections' },\n  { label: 'New in', href: '#new' },\n  { label: 'Studio', href: '#studio' },\n]\nconst centeredRight = [\n  { label: 'Journal', href: '#journal' },\n  { label: 'Stockists', href: '#stockists' },\n  { label: 'Contact', href: '#contact' },\n]\nconst centeredLinkClass =\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\nconst pillLinks = [\n  { label: 'Product', href: '#product' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Customers', href: '#customers' },\n  { label: 'Docs', href: '#docs' },\n]\n\ninterface MegaItem {\n  icon: IconNode\n  iconName: string\n  title: string\n  body: string\n}\n\ninterface MegaMenu {\n  label: string\n  groups: { heading: string; items: MegaItem[] }[]\n  highlight: { title: string; body: string; cta: string }\n}\n\n// `iconName` beside each icon node: lucide nodes don't carry their kebab-case\n// name, which icon() needs for the lucide-<name> class.\nconst megaMenus: MegaMenu[] = [\n  {\n    label: 'Product',\n    groups: [\n      {\n        heading: 'Core',\n        items: [\n          { icon: Boxes, iconName: 'boxes', title: 'Metric layer', body: 'Versioned definitions your whole org shares.' },\n          {\n            icon: BarChart3,\n            iconName: 'chart-column',\n            title: 'Dashboards',\n            body: 'Composed from certified metrics, not raw SQL.',\n          },\n          { icon: Workflow, iconName: 'workflow', title: 'Pipelines', body: 'Scheduled materialisation with cost ceilings.' },\n        ],\n      },\n      {\n        heading: 'Governance',\n        items: [\n          { icon: Lock, iconName: 'lock', title: 'Row-level access', body: 'Scope evaluated per query, per identity.' },\n          {\n            icon: BookOpen,\n            iconName: 'book-open',\n            title: 'Change history',\n            body: 'Every definition edit reviewed and revertible.',\n          },\n          {\n            icon: LifeBuoy,\n            iconName: 'life-buoy',\n            title: 'Audit exports',\n            body: 'Generated from the same history, not by hand.',\n          },\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          {\n            icon: BookOpen,\n            iconName: 'book-open',\n            title: 'Documentation',\n            body: 'Setup, modelling, and the access model.',\n          },\n          { icon: Layers, iconName: 'layers', title: 'Guides', body: 'Reconciliation and first-close checklists.' },\n          {\n            icon: BarChart3,\n            iconName: 'chart-column',\n            title: 'Benchmarks',\n            body: 'Close speed across 240 finance teams.',\n          },\n        ],\n      },\n      {\n        heading: 'Support',\n        items: [\n          {\n            icon: LifeBuoy,\n            iconName: 'life-buoy',\n            title: 'Help centre',\n            body: 'Answers to the questions support gets most.',\n          },\n          { icon: Workflow, iconName: 'workflow', title: 'Status', body: 'Live uptime and incident history.' },\n          { icon: Lock, iconName: '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 megaPlainLinks = [\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Customers', href: '#customers' },\n]\n\nconst searchLinks = [\n  { label: 'Product', href: '#product' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Docs', href: '#docs' },\n]\n\nconst searchGroups: { heading: string; items: { icon: IconNode; iconName: string; label: string }[] }[] = [\n  {\n    heading: 'Documentation',\n    items: [\n      { icon: BookOpen, iconName: 'book-open', label: 'Connect a warehouse' },\n      { icon: FileText, iconName: 'file-text', label: 'Define your first metric' },\n      { icon: BarChart3, iconName: 'chart-column', label: 'Publish a dashboard' },\n    ],\n  },\n  {\n    heading: 'Company',\n    items: [\n      { icon: Users, iconName: 'users', label: 'Customer stories' },\n      { icon: History, iconName: 'history', label: 'Changelog' },\n    ],\n  },\n]\n\nconst transparentLinks = [\n  { label: 'Product', href: '#product' },\n  { label: 'Solutions', href: '#solutions' },\n  { label: 'Pricing', href: '#pricing' },\n  { label: 'Docs', href: '#docs' },\n]\n\n/**\n * <uip-header> — the registry Header block collection as a web component.\n *\n * One block, one install unit: `variant` selects the section\n * ('default' | 'announcement' | 'centered' | 'pill' | 'mega' | 'search' |\n * 'transparent'). Class strings are React's verbatim per variant. React state\n * (useState) becomes @state fields; mobile Sheets become <uip-sheet> (open +\n * open-change), the mega dropdowns become <uip-navigation-menu>, and the\n * search palette becomes <uip-command-dialog>. Timers, scroll / keydown\n * listeners and the pill ResizeObserver are all torn down in\n * disconnectedCallback.\n */\nexport class UipHeader extends LitElement {\n  static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true }\n  // :host display can't be a utility class (the host has no template of its own).\n  static styles = [tailwind, css`:host { display: block; }`]\n\n  static properties = {\n    variant: { reflect: true },\n    sheetOpen: { state: true },\n    dismissed: { state: true },\n    pillActive: { state: true },\n    indicator: { state: true },\n    searchOpen: { state: true },\n    scrolled: { state: true },\n  }\n\n  variant: HeaderVariant = 'default'\n  private sheetOpen = false\n  private dismissed = false\n  private pillActive = 0\n  private indicator = { left: 0, width: 0 }\n  private searchOpen = false\n  private scrolled = false\n  private observer?: ResizeObserver\n\n  constructor() {\n    super()\n    new ThemeController(this)\n  }\n\n  connectedCallback() {\n    super.connectedCallback()\n    this.setAttribute('data-uipkge', '')\n    this.setAttribute('data-slot', 'header')\n    if (isServer) return\n    try {\n      if (window.sessionStorage.getItem(STORAGE_KEY) === '1') this.dismissed = true\n    } catch {\n      // Blocked storage: the strip stays visible, like React's first paint.\n    }\n    window.addEventListener('scroll', this.onScroll, { passive: true })\n    this.onScroll()\n    window.addEventListener('keydown', this.onKeydown)\n  }\n\n  disconnectedCallback() {\n    super.disconnectedCallback()\n    window.removeEventListener('scroll', this.onScroll)\n    window.removeEventListener('keydown', this.onKeydown)\n    this.observer?.disconnect()\n    this.observer = undefined\n  }\n\n  firstUpdated() {\n    this.measurePill()\n    if (typeof ResizeObserver === 'undefined') return\n    this.observer = new ResizeObserver(() => this.measurePill())\n    const nav = this.renderRoot.querySelector('[data-pill-nav]')\n    if (nav) this.observer.observe(nav)\n  }\n\n  private onScroll = () => {\n    this.scrolled = window.scrollY > 24\n  }\n\n  private onKeydown = (e: KeyboardEvent) => {\n    if (e.key.toLowerCase() !== 'k' || !(e.metaKey || e.ctrlKey)) return\n    e.preventDefault()\n    this.searchOpen = !this.searchOpen\n  }\n\n  private dismiss() {\n    this.dismissed = 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  // Measured from the live element, so the indicator fits any label length or\n  // font — no hard-coded widths to drift out of sync with the copy.\n  private measurePill(index = this.pillActive) {\n    const links = this.renderRoot.querySelectorAll<HTMLElement>('[data-pill-link]')\n    const el = links[index]\n    if (el) this.indicator = { left: el.offsetLeft, width: el.offsetWidth }\n  }\n\n  private mobileSheet(heading: string, body: unknown, side: 'right' | 'left' | 'top' = 'right') {\n    return html`\n      <uip-sheet\n        side=${side}\n        heading=${heading}\n        .open=${this.sheetOpen}\n        @open-change=${(e: CustomEvent<{ open: boolean }>) => {\n          this.sheetOpen = e.detail.open\n        }}\n      >\n        ${body}\n      </uip-sheet>\n    `\n  }\n\n  render() {\n    switch (this.variant) {\n      case 'announcement':\n        return this.renderAnnouncement()\n      case 'centered':\n        return this.renderCentered()\n      case 'pill':\n        return this.renderPill()\n      case 'mega':\n        return this.renderMega()\n      case 'search':\n        return this.renderSearch()\n      case 'transparent':\n        return this.renderTransparent()\n      default:\n        return this.renderDefault()\n    }\n  }\n\n  private renderDefault() {\n    return html`\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              ${icon(Boxes, 'boxes', 'size-4')}\n            </div>\n            <span class=\"text-base font-semibold\">Acme</span>\n          </a>\n\n          <nav class=\"hidden items-center gap-6 md:flex\" aria-label=\"Primary\">\n            ${defaultLinks.map(\n              (link) => html`<a\n                href=${link.href}\n                class=\"text-muted-foreground hover:text-foreground text-sm transition-colors\"\n              >\n                ${link.label}\n              </a>`,\n            )}\n          </nav>\n\n          <div class=\"hidden items-center gap-2 md:flex\">\n            <uip-button variant=\"ghost\" size=\"sm\">Sign in</uip-button>\n            <uip-button size=\"sm\">Start free trial</uip-button>\n          </div>\n\n          <div class=\"md:hidden\">\n            ${this.mobileSheet(\n              'Acme',\n              html`\n                <uip-button slot=\"trigger\" variant=\"ghost\" size=\"icon\" aria-label=\"Open menu\">\n                  ${icon(Menu, 'menu', 'size-5')}\n                </uip-button>\n                <nav class=\"flex flex-1 flex-col gap-1 p-4\" aria-label=\"Mobile\">\n                  ${defaultLinks.map(\n                    (link) => html`<a\n                      href=${link.href}\n                      class=\"hover:bg-muted rounded-md px-3 py-2 text-sm transition-colors\"\n                      @click=${() => {\n                        this.sheetOpen = false\n                      }}\n                    >\n                      ${link.label}\n                    </a>`,\n                  )}\n                </nav>\n                <div class=\"flex flex-col gap-2 border-t p-4\">\n                  <uip-button variant=\"outline\" class=\"w-full\">Sign in</uip-button>\n                  <uip-button class=\"w-full\">Start free trial</uip-button>\n                </div>\n              `,\n            )}\n          </div>\n        </div>\n      </header>\n    `\n  }\n\n  private renderAnnouncement() {\n    return html`\n      <div data-slot=\"header-announcement-stack\" class=\"sticky top-0 z-40\">\n        ${!this.dismissed\n          ? html`\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                  <uip-badge variant=\"secondary\" class=\"shrink-0\">New</uip-badge>\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\">\n                      Read the changelog\n                    </a>\n                  </p>\n                  ${icon(ArrowRight, 'arrow-right', 'text-muted-foreground hidden size-3.5 shrink-0 sm:block')}\n                  <uip-button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    class=\"ml-auto size-7 shrink-0\"\n                    aria-label=\"Dismiss announcement\"\n                    @click=${this.dismiss}\n                  >\n                    ${icon(X, 'x', 'size-3.5')}\n                  </uip-button>\n                </div>\n              </div>\n            `\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              ${icon(Layers, 'layers', 'text-primary size-5')} Northwind\n            </a>\n\n            <nav class=\"hidden items-center gap-1 md:flex\" aria-label=\"Primary\">\n              ${stackLinks.map(\n                (link) => html`<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                >\n                  ${link.label}\n                </a>`,\n              )}\n            </nav>\n\n            <div class=\"ml-auto hidden items-center gap-2 md:flex\">\n              <uip-button variant=\"ghost\" size=\"sm\">Sign in</uip-button>\n              <uip-button size=\"sm\">Book a demo</uip-button>\n            </div>\n\n            <div class=\"ml-auto md:hidden\">\n              ${this.mobileSheet(\n                'Menu',\n                html`\n                  <uip-button slot=\"trigger\" variant=\"ghost\" size=\"icon\" aria-label=\"Open navigation menu\">\n                    ${icon(Menu, 'menu', 'size-5')}\n                  </uip-button>\n                  <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n                    ${stackLinks.map(\n                      (link) => html`<a\n                        href=${link.href}\n                        class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                        @click=${() => {\n                          this.sheetOpen = false\n                        }}\n                      >\n                        ${link.label}\n                      </a>`,\n                    )}\n                  </nav>\n                  <uip-separator class=\"[&::part(base)]:my-5\"></uip-separator>\n                  <div class=\"grid gap-2\">\n                    <uip-button variant=\"outline\">Sign in</uip-button>\n                    <uip-button>Book a demo</uip-button>\n                  </div>\n                `,\n              )}\n            </div>\n          </div>\n        </header>\n      </div>\n    `\n  }\n\n  private renderCentered() {\n    return html`\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            ${centeredLeft.map(\n              (link) => html`<a href=${link.href} class=${centeredLinkClass}>${link.label}</a>`,\n            )}\n          </nav>\n\n          <div class=\"lg:hidden\">\n            ${this.mobileSheet(\n              'Menu',\n              html`\n                <uip-button slot=\"trigger\" variant=\"ghost\" size=\"icon\" aria-label=\"Open navigation menu\">\n                  ${icon(Menu, 'menu', 'size-5')}\n                </uip-button>\n                <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n                  ${[...centeredLeft, ...centeredRight].map(\n                    (link) => html`<a\n                      href=${link.href}\n                      class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                      @click=${() => {\n                        this.sheetOpen = false\n                      }}\n                    >\n                      ${link.label}\n                    </a>`,\n                  )}\n                </nav>\n                <uip-separator class=\"[&::part(base)]:my-5\"></uip-separator>\n                <uip-button class=\"w-full\">Account</uip-button>\n              `,\n              'left',\n            )}\n          </div>\n\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            ${icon(Compass, 'compass', 'text-primary size-4')} Halden\n          </a>\n\n          <nav class=\"hidden flex-1 basis-0 items-center justify-end gap-1 lg:flex\" aria-label=\"Primary right\">\n            ${centeredRight.map(\n              (link) => html`<a href=${link.href} class=${centeredLinkClass}>${link.label}</a>`,\n            )}\n          </nav>\n\n          <div class=\"flex items-center gap-1 lg:ml-4\">\n            <uip-button variant=\"ghost\" size=\"icon\" aria-label=\"Account\">\n              ${icon(User, 'user', 'size-4')}\n            </uip-button>\n            <uip-button variant=\"ghost\" size=\"icon\" aria-label=\"Bag\">\n              ${icon(ShoppingBag, 'shopping-bag', 'size-4')}\n            </uip-button>\n          </div>\n        </div>\n      </header>\n    `\n  }\n\n  private renderPill() {\n    return html`\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            ${icon(CircleDot, 'circle-dot', 'text-primary size-4')} Verity\n          </a>\n\n          <nav data-pill-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: ${this.indicator.left}px; width: ${this.indicator.width}px`}\n              aria-hidden=\"true\"\n            ></span>\n            ${pillLinks.map(\n              (link, index) => html`<a\n                href=${link.href}\n                data-pill-link\n                class=${`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                  index === this.pillActive ? 'text-foreground' : 'text-muted-foreground hover:text-foreground'\n                }`}\n                aria-current=${index === this.pillActive ? 'page' : nothing}\n                @mouseenter=${() => this.measurePill(index)}\n                @mouseleave=${() => this.measurePill()}\n                @focus=${() => this.measurePill(index)}\n                @blur=${() => this.measurePill()}\n                @click=${() => {\n                  this.pillActive = index\n                }}\n              >\n                ${link.label}\n              </a>`,\n            )}\n          </nav>\n\n          <uip-button size=\"sm\" class=\"ml-auto [&::part(base)]:rounded-full\">Start free</uip-button>\n\n          <div class=\"md:hidden\">\n            ${this.mobileSheet(\n              'Menu',\n              html`\n                <uip-button\n                  slot=\"trigger\"\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  class=\"[&::part(base)]:rounded-full\"\n                  aria-label=\"Open navigation menu\"\n                >\n                  ${icon(Menu, 'menu', 'size-5')}\n                </uip-button>\n                <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n                  ${pillLinks.map(\n                    (link) => html`<a\n                      href=${link.href}\n                      class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                      @click=${() => {\n                        this.sheetOpen = false\n                      }}\n                    >\n                      ${link.label}\n                    </a>`,\n                  )}\n                </nav>\n              `,\n              'top',\n            )}\n          </div>\n        </header>\n      </div>\n    `\n  }\n\n  private renderMega() {\n    return html`\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            ${icon(Layers, 'layers', 'text-primary size-5')} Northwind\n          </a>\n\n          <div class=\"hidden lg:flex\">\n            <uip-navigation-menu>\n              ${megaMenus.map(\n                (menu) => html`\n                  <uip-navigation-menu-item>\n                    <span slot=\"trigger\">${menu.label}</span>\n                    <div slot=\"content\" class=\"grid w-[46rem] grid-cols-[1fr_1fr_16rem] gap-6 p-6\">\n                      ${menu.groups.map(\n                        (group) => html`\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                              ${group.items.map(\n                                (item) => html`\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                                      ${icon(item.icon, item.iconName, '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}</span\n                                        >\n                                      </span>\n                                    </a>\n                                  </li>\n                                `,\n                              )}\n                            </ul>\n                          </div>\n                        `,\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                        <uip-button variant=\"link\" class=\"mt-auto h-auto justify-start p-0 pt-4 text-xs\">\n                          ${menu.highlight.cta} ${icon(ArrowRight, 'arrow-right', 'ml-1 size-3')}\n                        </uip-button>\n                      </div>\n                    </div>\n                  </uip-navigation-menu-item>\n                `,\n              )}\n              ${megaPlainLinks.map(\n                (link) => html`\n                  <uip-navigation-menu-item>\n                    <uip-navigation-menu-link href=${link.href} trigger-style>${link.label}</uip-navigation-menu-link>\n                  </uip-navigation-menu-item>\n                `,\n              )}\n            </uip-navigation-menu>\n          </div>\n\n          <div class=\"ml-auto flex items-center gap-2\">\n            <span class=\"hidden sm:contents\">\n              <uip-button variant=\"ghost\" size=\"sm\">Sign in</uip-button>\n            </span>\n            <span class=\"hidden sm:contents\">\n              <uip-separator orientation=\"vertical\" class=\"[&::part(base)]:h-5!\"></uip-separator>\n            </span>\n            <uip-button size=\"sm\">Book a demo</uip-button>\n          </div>\n\n          <div class=\"ml-auto lg:hidden\">\n            ${this.mobileSheet(\n              'Menu',\n              html`\n                <uip-button slot=\"trigger\" variant=\"ghost\" size=\"icon\" aria-label=\"Open navigation menu\">\n                  ${icon(Menu, 'menu', 'size-5')}\n                </uip-button>\n                <nav class=\"mt-6 grid gap-5\" aria-label=\"Mobile\">\n                  ${megaMenus.map(\n                    (menu) => html`\n                      <div>\n                        <p class=\"text-muted-foreground/70 text-xs font-medium tracking-wide uppercase\">\n                          ${menu.label}\n                        </p>\n                        <ul class=\"mt-2 grid gap-1\">\n                          ${menu.groups.map((group) =>\n                            group.items.map(\n                              (item) => html`\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=${() => {\n                                      this.sheetOpen = false\n                                    }}\n                                  >\n                                    ${item.title}\n                                  </a>\n                                </li>\n                              `,\n                            ),\n                          )}\n                        </ul>\n                      </div>\n                    `,\n                  )}\n                  <uip-separator></uip-separator>\n                  ${megaPlainLinks.map(\n                    (link) => html`<a\n                      href=${link.href}\n                      class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                      @click=${() => {\n                        this.sheetOpen = false\n                      }}\n                    >\n                      ${link.label}\n                    </a>`,\n                  )}\n                  <uip-separator></uip-separator>\n                  <div class=\"grid gap-2\">\n                    <uip-button variant=\"outline\">Sign in</uip-button>\n                    <uip-button>Book a demo</uip-button>\n                  </div>\n                </nav>\n              `,\n            )}\n          </div>\n        </div>\n      </header>\n    `\n  }\n\n  private renderSearch() {\n    return html`\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            ${icon(Compass, 'compass', 'text-primary size-5')} Halden\n          </a>\n\n          <nav class=\"hidden items-center gap-1 md:flex\" aria-label=\"Primary\">\n            ${searchLinks.map(\n              (link) => html`<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              >\n                ${link.label}\n              </a>`,\n            )}\n          </nav>\n\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=${() => {\n              this.searchOpen = true\n            }}\n          >\n            ${icon(Search, 'search', 'size-4 shrink-0')}\n            <span class=\"truncate\">Search docs…</span>\n            <span class=\"hidden sm:contents\">\n              <uip-kbd class=\"ml-auto\">⌘K</uip-kbd>\n            </span>\n          </button>\n\n          <span class=\"hidden md:contents\">\n            <uip-separator orientation=\"vertical\" class=\"[&::part(base)]:h-5!\"></uip-separator>\n          </span>\n          <span class=\"hidden sm:contents\">\n            <uip-button size=\"sm\" class=\"shrink-0\">Start free</uip-button>\n          </span>\n\n          <div class=\"shrink-0 md:hidden\">\n            ${this.mobileSheet(\n              'Menu',\n              html`\n                <uip-button slot=\"trigger\" variant=\"ghost\" size=\"icon\" aria-label=\"Open navigation menu\">\n                  ${icon(Menu, 'menu', 'size-5')}\n                </uip-button>\n                <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n                  ${searchLinks.map(\n                    (link) => html`<a\n                      href=${link.href}\n                      class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                      @click=${() => {\n                        this.sheetOpen = false\n                      }}\n                    >\n                      ${link.label}\n                    </a>`,\n                  )}\n                </nav>\n                <uip-separator class=\"[&::part(base)]:my-5\"></uip-separator>\n                <div class=\"grid gap-2\">\n                  <uip-button variant=\"outline\">Sign in</uip-button>\n                  <uip-button>Start free</uip-button>\n                </div>\n              `,\n            )}\n          </div>\n        </div>\n\n        <uip-command-dialog\n          placeholder=\"Search documentation, guides, and stories…\"\n          .open=${this.searchOpen}\n          @open-change=${(e: CustomEvent<{ open: boolean }>) => {\n            this.searchOpen = e.detail.open\n          }}\n        >\n          <uip-command-empty>No results.</uip-command-empty>\n          ${searchGroups.map(\n            (group) => html`\n              <uip-command-group heading=${group.heading}>\n                ${group.items.map(\n                  (item) => html`\n                    <uip-command-item value=${item.label}>\n                      ${icon(item.icon, item.iconName, 'text-muted-foreground mr-2 size-4')} ${item.label}\n                    </uip-command-item>\n                  `,\n                )}\n              </uip-command-group>\n            `,\n          )}\n        </uip-command-dialog>\n      </header>\n    `\n  }\n\n  private renderTransparent() {\n    return html`\n      <header\n        data-slot=\"header-transparent-scroll\"\n        class=${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        <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            ${icon(Layers, 'layers', 'text-primary size-5')} Northwind\n          </a>\n\n          <nav class=\"hidden items-center gap-1 md:flex\" aria-label=\"Primary\">\n            ${transparentLinks.map(\n              (link) => html`<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              >\n                ${link.label}\n              </a>`,\n            )}\n          </nav>\n\n          <div class=\"ml-auto hidden items-center gap-2 md:flex\">\n            <uip-button variant=\"ghost\" size=\"sm\">Sign in</uip-button>\n            <uip-button size=\"sm\">Start free</uip-button>\n          </div>\n\n          <div class=\"ml-auto md:hidden\">\n            ${this.mobileSheet(\n              'Menu',\n              html`\n                <uip-button slot=\"trigger\" variant=\"ghost\" size=\"icon\" aria-label=\"Open navigation menu\">\n                  ${icon(Menu, 'menu', 'size-5')}\n                </uip-button>\n                <nav class=\"mt-6 grid gap-1\" aria-label=\"Mobile\">\n                  ${transparentLinks.map(\n                    (link) => html`<a\n                      href=${link.href}\n                      class=\"hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors\"\n                      @click=${() => {\n                        this.sheetOpen = false\n                      }}\n                    >\n                      ${link.label}\n                    </a>`,\n                  )}\n                </nav>\n                <uip-separator class=\"[&::part(base)]:my-5\"></uip-separator>\n                <div class=\"grid gap-2\">\n                  <uip-button variant=\"outline\">Sign in</uip-button>\n                  <uip-button>Start free</uip-button>\n                </div>\n              `,\n            )}\n          </div>\n        </div>\n      </header>\n    `\n  }\n}\n\ncustomElements.get('uip-header') || customElements.define('uip-header', UipHeader)\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'uip-header': UipHeader\n  }\n}\n",
      "type": "registry:file",
      "target": "src/uip/blocks/header/header.ts"
    }
  ],
  "dependencies": [
    "lit",
    "lucide"
  ],
  "registryDependencies": [
    "https://uipkge.dev/r/lit/badge.json",
    "https://uipkge.dev/r/lit/button.json",
    "https://uipkge.dev/r/lit/command.json",
    "https://uipkge.dev/r/lit/kbd.json",
    "https://uipkge.dev/r/lit/lit-core.json",
    "https://uipkge.dev/r/lit/navigation-menu.json",
    "https://uipkge.dev/r/lit/separator.json",
    "https://uipkge.dev/r/lit/sheet.json"
  ]
}
