{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "cta-band",
  "type": "registry:block",
  "title": "CTA band",
  "description": "A closing call to action band. Choose a muted, card, plain or primary-coloured background.",
  "categories": [
    "section"
  ],
  "registryDependencies": [
    "https://facadeui.dev/r/container.json",
    "https://facadeui.dev/r/cta-group.json",
    "https://facadeui.dev/r/eyebrow.json",
    "https://facadeui.dev/r/heading.json",
    "https://facadeui.dev/r/section.json",
    "https://facadeui.dev/r/types.json",
    "https://facadeui.dev/r/utils.json"
  ],
  "files": [
    {
      "path": "src/sections/cta-band.tsx",
      "type": "registry:component",
      "target": "components/sections/cta-band.tsx",
      "content": "/**\n * CtaBand — the closing call to action.\n *\n * a11y: `variant=\"primary\"` inverts the band, so it pairs `--primary` with\n * `--primary-foreground` rather than reaching for an arbitrary tint. That is the\n * one colour pair the token layer guarantees at 4.5:1 in every preset and both\n * modes, and `scripts/check-contrast.ts` keeps it that way.\n *\n * Dependencies: react, @/lib/types, @/lib/utils,\n * @/components/ui/container, @/components/ui/cta-group, @/components/ui/eyebrow,\n * @/components/ui/heading, @/components/ui/section.\n */\n\nimport type { ElementType, ReactNode } from \"react\"\n\nimport type {\n  CtaItem,\n  HeadingLevel,\n  LinkComponent,\n  StackSlotProps,\n} from \"@/lib/types\"\nimport { cn, slugId } from \"@/lib/utils\"\nimport { Container } from \"@/components/ui/container\"\nimport { CtaGroup } from \"@/components/ui/cta-group\"\nimport { Eyebrow } from \"@/components/ui/eyebrow\"\nimport { Heading } from \"@/components/ui/heading\"\nimport { Section } from \"@/components/ui/section\"\n\nexport interface CtaBandProps extends StackSlotProps {\n  title: string\n  description?: string\n  eyebrow?: ReactNode\n  actions?: CtaItem[]\n  link?: LinkComponent\n  note?: ReactNode\n  /**\n   * `muted` and `card` sit inside the container. `primary` uses the primary colour as the\n   * background.\n   */\n  variant?: \"muted\" | \"card\" | \"primary\" | \"plain\"\n  /** `center` stacks everything; `split` puts the buttons beside the copy. */\n  layout?: \"center\" | \"split\"\n  headingLevel?: HeadingLevel\n  as?: \"section\" | \"div\"\n  spacing?: \"sm\" | \"md\" | \"lg\" | \"none\"\n  className?: string\n  id?: string\n}\n\nconst surfaces = {\n  muted: \"bg-muted text-foreground\",\n  card: \"bg-card text-card-foreground border\",\n  primary: \"bg-primary text-primary-foreground\",\n  plain: \"\",\n} as const\n\nexport function CtaBand({\n  title,\n  description,\n  eyebrow,\n  actions,\n  link,\n  note,\n  variant = \"muted\",\n  layout = \"center\",\n  stackAs,\n  blockAs,\n  headingLevel = 2,\n  as = \"section\",\n  spacing = \"md\",\n  className,\n  id,\n}: CtaBandProps) {\n  const Stack = (stackAs ?? \"div\") as ElementType\n  const Block = (blockAs ?? \"div\") as ElementType\n  const titleId = id ? `${id}-title` : slugId(title)\n  const inverted = variant === \"primary\"\n  const centered = layout === \"center\"\n\n  return (\n    <Section\n      as={as}\n      spacing={spacing}\n      labelledBy={as === \"section\" ? titleId : undefined}\n      id={id}\n      className={className}\n    >\n      <Container>\n        <div\n          className={cn(\n            \"rounded-2xl px-6 py-14 sm:px-12\",\n            surfaces[variant],\n            variant === \"plain\" && \"px-0 py-0\",\n          )}\n        >\n          <Stack\n            className={cn(\n              \"flex flex-col gap-6\",\n              centered\n                ? \"items-center text-center\"\n                : \"lg:flex-row lg:items-center lg:justify-between lg:gap-12 lg:text-left\",\n            )}\n          >\n            <Block\n              className={cn(\n                \"flex flex-col gap-4\",\n                centered ? \"items-center\" : \"max-w-2xl\",\n              )}\n            >\n              {eyebrow ? (\n                <Eyebrow\n                  tone={inverted ? \"foreground\" : \"primary\"}\n                  className={inverted ? \"text-primary-foreground\" : undefined}\n                >\n                  {eyebrow}\n                </Eyebrow>\n              ) : null}\n\n              <Heading\n                level={headingLevel}\n                id={titleId}\n                className=\"text-display-sm text-balance font-semibold\"\n              >\n                {title}\n              </Heading>\n\n              {description ? (\n                <p\n                  className={cn(\n                    \"text-pretty text-lg\",\n                    // Full strength: a bright primary and its label can be\n                    // as close as 4.5:1, which leaves no room to fade.\n                    inverted ? \"text-primary-foreground\" : \"text-muted-foreground\",\n                    centered && \"max-w-2xl\",\n                  )}\n                >\n                  {description}\n                </p>\n              ) : null}\n            </Block>\n\n            {actions?.length ? (\n              <Block\n                className={cn(\n                  \"flex flex-col gap-3\",\n                  centered && \"w-full items-center sm:w-auto\",\n                )}\n              >\n                <CtaGroup\n                  items={\n                    inverted\n                      ? actions.map((action, index) => ({\n                          ...action,\n                          // Primary and ghost both vanish on an inverted band;\n                          // these variants bring their own surface.\n                          variant:\n                            action.variant ?? (index === 0 ? \"secondary\" : \"outline\"),\n                        }))\n                      : actions\n                  }\n                  link={link}\n                  size=\"lg\"\n                  align={centered ? \"center\" : \"start\"}\n                  stackOnMobile\n                />\n                {note ? (\n                  <p\n                    className={cn(\n                      \"text-pretty text-sm\",\n                      inverted ? \"text-primary-foreground\" : \"text-muted-foreground\",\n                      centered && \"text-center\",\n                    )}\n                  >\n                    {note}\n                  </p>\n                ) : null}\n              </Block>\n            ) : null}\n          </Stack>\n        </div>\n      </Container>\n    </Section>\n  )\n}\n"
    }
  ],
  "docs": "Import styles/facade-tokens.css in your global stylesheet, after @import \"tailwindcss\". Set headingLevel to fit the page outline (sections default to h2). Pass next/link and next/image through the link and image props. Docs: https://facadeui.dev/components/cta-band"
}
