{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "cta-section",
  "type": "registry:ui",
  "title": "Cta Section",
  "description": "Call-to-action section. Title + description + 1-2 action buttons in a centred column on a tinted surface. The shape every landing page reaches for (\"Ready to ship?\" / \"Start your trial\" / \"Read the docs\"). Server component.",
  "author": "ofri-peretz <https://github.com/ofri-peretz>",
  "categories": [
    "marketing",
    "pattern"
  ],
  "dependencies": [],
  "registryDependencies": [
    "https://ds.interlace.tools/r/theme.json",
    "https://ds.interlace.tools/r/cn.json",
    "https://ds.interlace.tools/r/container.json",
    "https://ds.interlace.tools/r/skeleton.json",
    "https://ds.interlace.tools/r/stack.json",
    "https://ds.interlace.tools/r/typography.json"
  ],
  "files": [
    {
      "path": "registry/interlace-ui/patterns/cta-section.tsx",
      "target": "components/ui/patterns/cta-section.tsx",
      "type": "registry:ui",
      "content": "import * as React from 'react';\n\n// @interlace/cta-section v1.0.0 — Interlace design system.\n// Docs, props and live preview: https://ds.interlace.tools/c/cta-section\n// What changed since: https://ds.interlace.tools/c/cta-section#history\n// Generated banner — keep it, the upgrade diff reads this version.\n\n/**\n * @interlace/ui — CTASection\n *\n * Call-to-action section. Title + description + 1-2 action buttons in a\n * centred column on a tinted surface. The shape every landing page reaches\n * for (\"Ready to ship?\" / \"Start your trial\" / \"Read the docs\"). Server\n * component.\n *\n * ## Anatomy\n *\n *   <section data-slot=\"cta-section\" data-min-viewport=\"320\">\n *     <Container>\n *       <Stack align=\"center\">\n *         <Typography variant=\"h2\">{title}</Typography>\n *         <Typography variant=\"long\">{description}</Typography>\n *         <div>{actions}</div>\n *       </Stack>\n *     </Container>\n *   </section>\n *\n * | Rule | Concept                          | Where in this file                                          |\n * | ---- | -------------------------------- | ----------------------------------------------------------- |\n * | R4   | Extends native el                | `React.ComponentProps<'section'>` + CTASection props        |\n * | R6   | data-slot on root                | `data-slot=\"cta-section\"`                                   |\n * | R7   | className merged + ...rest       | `cn(BASE, className)` + `{...props}`                        |\n * | R10  | Composition seam (slots)         | `title` / `description` / `actions` ReactNode props         |\n * | R14  | Declares min viewport            | `data-min-viewport={String(MIN_VIEWPORT)}` + exported const |\n * | R18  | Tailwind only                    | Zero inline `style`; utility classes only                   |\n * | R19  | Tokens only                      | `bg-primary-subtle` / `text-foreground` / spacing scale     |\n * | R20  | AA contrast                      | accent foreground on tinted surface                         |\n * | R25  | Server component                 | No hooks                                                    |\n * | R26  | A11y                             | `<section>` with `aria-labelledby` when title is text       |\n */\n\nimport { cn } from '@/lib/utils';\nimport { Container } from '@/components/ui/container';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Stack } from '@/components/ui/stack';\nimport { Typography } from '@/components/ui/typography';\n\nexport const MIN_VIEWPORT = 320 as const;\n\ntype CTATone = 'subtle' | 'primary' | 'neutral';\n\ninterface CTASectionProps extends Omit<React.ComponentProps<'section'>, 'title'> {\n  title?: React.ReactNode;\n  description?: React.ReactNode;\n  /** Actions row — typically 1-2 Buttons. */\n  actions?: React.ReactNode;\n  /**\n   * Surface tone. `subtle` (default) uses brand-tinted neutral;\n   * `primary` is fully branded; `neutral` is plain card. Stick to one\n   * `primary` CTA per page.\n   */\n  tone?: CTATone;\n  /** When true, render a skeleton card placeholder. */\n  loading?: boolean;\n}\n\nconst TONE_CLASSES: Record<CTATone, string> = {\n  subtle: 'bg-muted text-foreground',\n  primary: 'bg-primary text-primary-foreground',\n  neutral: 'bg-card text-card-foreground border-y border-border',\n};\n\nfunction CTASection({\n  title,\n  description,\n  actions,\n  tone = 'subtle',\n  loading,\n  className,\n  ...props\n}: CTASectionProps) {\n  if (loading) {\n    return (\n      <Skeleton\n        variant=\"card\"\n        data-slot=\"cta-section\"\n        data-min-viewport={String(MIN_VIEWPORT)}\n        className={cn('h-40 w-full', className)}\n      />\n    );\n  }\n  return (\n    <section\n      data-slot=\"cta-section\"\n      data-min-viewport={String(MIN_VIEWPORT)}\n      data-tone={tone}\n      className={cn('py-2xl', TONE_CLASSES[tone], className)}\n      {...props}\n    >\n      <Container size=\"content\">\n        <Stack gap=\"md\" align=\"center\" className=\"text-center\">\n          {title ? (\n            <Typography variant=\"h2\" as=\"h2\" className=\"text-balance\">\n              {title}\n            </Typography>\n          ) : null}\n          {description ? (\n            <Typography\n              variant=\"long\"\n              tone={tone === 'primary' ? 'default' : 'muted'}\n              className={cn(\n                'max-w-prose',\n                // On `primary` tone the background is the brand colour. Use\n                // the full primary-foreground (no opacity) so contrast clears\n                // AAA — `/90` would knock it to ~6:1, sub-AAA.\n                tone === 'primary' && 'text-primary-foreground',\n              )}\n            >\n              {description}\n            </Typography>\n          ) : null}\n          {actions ? (\n            <div className=\"mt-md flex flex-col items-center gap-sm sm:flex-row\">\n              {actions}\n            </div>\n          ) : null}\n        </Stack>\n      </Container>\n    </section>\n  );\n}\nCTASection.displayName = 'CTASection';\n\nexport { CTASection };\nexport type { CTASectionProps };\n"
    }
  ],
  "meta": {
    "tier": "pattern",
    "client": false,
    "minViewport": 320,
    "loading": true,
    "version": "1.0.0",
    "since": "1.0.0"
  },
  "docs": "## @interlace/cta-section\n\nInstalled to `components/ui/patterns/cta-section.tsx`.\n\n```tsx\nimport { /* … */ } from '@/components/ui/patterns/cta-section';\n```\n\nProps, a11y contract, live preview and source: https://ds.interlace.tools/c/cta-section\n\nRequires the `@interlace/theme` CSS baseline (installed automatically as a registry dependency)."
}
