{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "section-header",
  "type": "registry:ui",
  "title": "Section header",
  "description": "An eyebrow, a heading and a description. It also sets the heading id that a section uses for its accessible name.",
  "categories": [
    "atom"
  ],
  "registryDependencies": [
    "https://facadeui.dev/r/eyebrow.json",
    "https://facadeui.dev/r/heading.json",
    "https://facadeui.dev/r/types.json",
    "https://facadeui.dev/r/utils.json"
  ],
  "files": [
    {
      "path": "src/ui/section-header.tsx",
      "type": "registry:ui",
      "target": "components/ui/section-header.tsx",
      "content": "/**\n * SectionHeader — eyebrow, heading, and supporting copy, used by every section.\n *\n * Owns two things sections keep getting wrong: the heading *level* and the id\n * that the section's `aria-labelledby` points at. Both are explicit props, and\n * the id falls back to a slug of the title so the wiring works without the\n * caller having to invent one.\n *\n * a11y: `headingLevel` must reflect the surrounding outline, not the visual\n * size — `size` controls appearance and is completely independent. The eyebrow\n * is a paragraph, never a heading.\n *\n * Dependencies: react, @/lib/types, @/lib/utils, ./eyebrow, ./heading.\n */\n\nimport type { ReactNode } from \"react\"\n\nimport type { HeadingLevel } from \"@/lib/types\"\nimport { cn, slugId } from \"@/lib/utils\"\nimport { Eyebrow } from \"@/components/ui/eyebrow\"\nimport { Heading } from \"@/components/ui/heading\"\n\nexport interface SectionHeaderProps {\n  title: ReactNode\n  /** Small label above the heading. */\n  eyebrow?: ReactNode\n  /** Text below the heading. */\n  description?: ReactNode\n  /** Heading level. Defaults to `2`. Does not affect `size`. */\n  headingLevel?: HeadingLevel\n  /** Visual size. Defaults to `md`. Does not affect `headingLevel`. */\n  size?: \"sm\" | \"md\" | \"lg\" | \"xl\"\n  align?: \"start\" | \"center\"\n  /**\n   * The heading's id, for the parent's `aria-labelledby`. Made from the title when\n   * omitted. Pass one if two headings would get the same id.\n   */\n  titleId?: string\n  /** Buttons or links shown beside or under the heading. */\n  actions?: ReactNode\n  className?: string\n  children?: ReactNode\n}\n\nconst headingSizes: Record<NonNullable<SectionHeaderProps[\"size\"]>, string> = {\n  sm: \"text-2xl font-semibold tracking-tight sm:text-3xl\",\n  md: \"text-display-sm font-semibold text-balance\",\n  lg: \"text-display-md font-semibold text-balance\",\n  xl: \"text-display-lg font-semibold text-balance\",\n}\n\nconst descriptionSizes: Record<NonNullable<SectionHeaderProps[\"size\"]>, string> = {\n  sm: \"text-base\",\n  md: \"text-base sm:text-lg\",\n  lg: \"text-lg sm:text-xl\",\n  xl: \"text-lg sm:text-xl\",\n}\n\n/** Derives the heading id the way `SectionHeader` does, for `aria-labelledby`. */\nexport function sectionTitleId(title: string, explicit?: string): string {\n  return explicit ?? slugId(title)\n}\n\nexport function SectionHeader({\n  title,\n  eyebrow,\n  description,\n  headingLevel = 2,\n  size = \"md\",\n  align = \"start\",\n  titleId,\n  actions,\n  className,\n  children,\n}: SectionHeaderProps) {\n  const resolvedId = titleId ?? (typeof title === \"string\" ? slugId(title) : undefined)\n\n  return (\n    <div\n      className={cn(\n        \"flex flex-col gap-4\",\n        align === \"center\" && \"items-center text-center\",\n        actions && \"md:flex-row md:items-end md:justify-between md:gap-10\",\n        className,\n      )}\n    >\n      <div\n        className={cn(\n          \"flex max-w-2xl flex-col gap-4\",\n          align === \"center\" && \"items-center\",\n        )}\n      >\n        {eyebrow ? <Eyebrow tone=\"primary\">{eyebrow}</Eyebrow> : null}\n        <Heading level={headingLevel} id={resolvedId} className={cn(headingSizes[size])}>\n          {title}\n        </Heading>\n        {description ? (\n          <p className={cn(\"text-muted-foreground text-pretty\", descriptionSizes[size])}>\n            {description}\n          </p>\n        ) : null}\n        {children}\n      </div>\n      {actions ? <div className=\"flex shrink-0 flex-wrap gap-3\">{actions}</div> : null}\n    </div>\n  )\n}\n"
    }
  ],
  "docs": "Import styles/facade-tokens.css in your global stylesheet, after @import \"tailwindcss\". Docs: https://facadeui.dev/components/section-header"
}
