{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "cta-band",
  "title": "CTA band",
  "description": "An inverted call-to-action band: headline, one sentence, one primary and one secondary action, and a fact line.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/manniche/cta-band/cta-band.tsx",
      "content": "// A call to action as one inverted Tiles band: a display headline, one sentence, a primary and a secondary action\n// and a small fact line. The band swaps to the opposite theme (dark on a light page, light on a dark one) and every\n// token inside follows, so the section is the single loud thing on its stretch of the page. Signature: on wide boxes\n// the actions sit at the right, level with the bottom of the text; on narrow ones they stack full width.\n// Screen readers get a labelled section with one h2, the sentence, two links and the fact line as a plain paragraph.\n// Nothing animates except the press feedback on the buttons, which is a 150 ms transform and is dropped under\n// reduced motion. The section adapts to its own box (container queries), not only to the viewport.\nimport { ArrowRight } from 'lucide-react'\nimport { useId, type ComponentProps, type CSSProperties, type ReactNode } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport type CtaAction = {\n  /** The visible text of the link. */\n  label: string\n  /** Where the link goes. */\n  href: string\n  /** Open in a new tab. Adds `rel=\"noopener noreferrer\"` and the hidden \"(opens in a new tab)\" text. */\n  external?: boolean\n  /** Called on click, for apps that handle the navigation themselves. */\n  onClick?: ComponentProps<'a'>['onClick']\n}\n\nexport type CtaBandLabels = {\n  /** Hidden text added after links that open in a new tab. Default \"(opens in a new tab)\". */\n  newTab?: string\n}\n\nexport type CtaBandProps = Omit<ComponentProps<'section'>, 'children' | 'title'> & {\n  /** The display line. Keep it short; it is set in the display face and balanced across lines. */\n  headline: ReactNode\n  /** One sentence under the headline that says what happens next. */\n  description?: ReactNode\n  /** The one primary action. */\n  primary: CtaAction\n  /** A quieter second action, such as \"Talk to us\". */\n  secondary?: CtaAction\n  /** A plain promise under the band's content, such as \"No card needed. Cancel any time.\" Never a statistic. */\n  fact?: ReactNode\n  /** Text for the interface itself, for translation. */\n  labels?: CtaBandLabels\n}\n\n// Snapshots of the page's tokens, taken on the outer element so the inner one can swap them without a cycle.\nconst INVERT_OUTER = {\n  '--tile-bg': 'var(--foreground)',\n  '--tile-fg': 'var(--background)',\n  '--tile-primary': 'var(--primary)',\n} as CSSProperties\n\nconst INVERT_INNER = {\n  '--card': 'var(--tile-bg)',\n  '--card-foreground': 'var(--tile-fg)',\n  '--foreground': 'var(--tile-fg)',\n  '--background': 'var(--tile-bg)',\n  '--muted': 'color-mix(in oklab, var(--tile-fg) 10%, var(--tile-bg))',\n  '--muted-foreground': 'color-mix(in oklab, var(--tile-fg) 64%, var(--tile-bg))',\n  '--border': 'color-mix(in oklab, var(--tile-fg) 15%, var(--tile-bg))',\n  '--primary': 'color-mix(in oklab, var(--tile-primary) 80%, var(--tile-fg))',\n  '--ring': 'color-mix(in oklab, var(--tile-primary) 80%, var(--tile-fg))',\n} as CSSProperties\n\nconst BUTTON =\n  'inline-flex min-h-11 w-full items-center justify-center gap-2 rounded-full px-6 text-[15px] font-medium whitespace-nowrap transition-[transform,opacity] duration-150 ease-out-quint active:scale-[0.97] motion-reduce:transition-none motion-reduce:active:scale-100 @min-[40rem]:w-auto'\n\nfunction ActionLink({ action, newTab, className, children }: { action: CtaAction; newTab: string; className: string; children?: ReactNode }) {\n  return (\n    <a\n      href={action.href}\n      onClick={action.onClick}\n      target={action.external ? '_blank' : undefined}\n      rel={action.external ? 'noopener noreferrer' : undefined}\n      className={className}\n    >\n      {action.label}\n      {action.external && <span className=\"sr-only\"> {newTab}</span>}\n      {children}\n    </a>\n  )\n}\n\n/** The inverted call-to-action band: headline, sentence, one primary and one secondary action, and a fact line. */\nexport function CtaBand({ headline, description, primary, secondary, fact, labels, className, ...rest }: CtaBandProps) {\n  const headingId = useId()\n  const newTab = labels?.newTab ?? '(opens in a new tab)'\n  return (\n    <section\n      aria-labelledby={headingId}\n      {...rest}\n      className={cn('@container mx-auto w-full max-w-6xl px-4 py-12 sm:px-6 @3xl:py-20', className)}\n    >\n      <div\n        className=\"rounded-[calc(var(--radius)*2+2px)] bg-foreground text-background\"\n        style={INVERT_OUTER}\n      >\n        <div className=\"px-6 py-10 @min-[40rem]:px-10 @min-[40rem]:py-12 @min-[64rem]:px-14 @min-[64rem]:py-16\" style={INVERT_INNER}>\n          <div className=\"grid gap-8 @min-[48rem]:grid-cols-[minmax(0,1fr)_auto] @min-[48rem]:items-end @min-[48rem]:gap-x-12\">\n            <div className=\"min-w-0\">\n              <h2\n                id={headingId}\n                className=\"max-w-[18ch] text-[clamp(2rem,7.5cqi,3.75rem)] leading-[1.02] font-extrabold tracking-[-0.04em] text-balance\"\n                style={{ fontFamily: 'var(--font-display, inherit)', fontStretch: '86%' }}\n              >\n                {headline}\n              </h2>\n              {description && (\n                <p className=\"mt-4 max-w-[46ch] text-base leading-relaxed text-pretty text-muted-foreground @min-[40rem]:text-[17px]\">\n                  {description}\n                </p>\n              )}\n            </div>\n            <div className=\"flex flex-col gap-3 @min-[40rem]:flex-row @min-[40rem]:flex-wrap @min-[48rem]:justify-end\">\n              <ActionLink action={primary} newTab={newTab} className={cn(BUTTON, 'bg-foreground text-background hover:opacity-90')}>\n                <ArrowRight aria-hidden className=\"size-4\" />\n              </ActionLink>\n              {secondary && (\n                <ActionLink\n                  action={secondary}\n                  newTab={newTab}\n                  className={cn(BUTTON, 'bg-transparent text-foreground shadow-[inset_0_0_0_1px_var(--border)] hover:bg-muted')}\n                />\n              )}\n            </div>\n          </div>\n          {fact && (\n            <p className=\"mt-8 border-t border-border pt-5 font-mono text-[12px] leading-relaxed tracking-[0.01em] text-muted-foreground\">\n              {fact}\n            </p>\n          )}\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "templates"
  ],
  "type": "registry:block"
}