{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "cta-04",
  "title": "CTA 04",
  "description": "Centered CTA card with a subtle grid background, bold headline, description, and action button. Use it as a section-closing block that re-engages visitors who scrolled past earlier conversion points.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "button",
    "https://shadcnship.com/r/social-icons.json"
  ],
  "files": [
    {
      "path": "src/registry/blocks/cta-04/cta.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { ArrowUpRight, Book } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { LogoIcon } from \"../social-icons/icons\";\n\nconst GRID = 80;\n\nconst GridBackground = () => {\n  const ref = useRef<HTMLDivElement>(null);\n  const [grid, setGrid] = useState({ cols: 0, rows: 0, cellW: 0, cellH: 0 });\n\n  useEffect(() => {\n    const update = () => {\n      if (!ref.current) return;\n      const { width, height } = ref.current.getBoundingClientRect();\n      const cols = Math.max(1, Math.round(width / GRID));\n      const rows = Math.max(1, Math.round(height / GRID));\n      setGrid({ cols, rows, cellW: width / cols, cellH: height / rows });\n    };\n    update();\n    window.addEventListener(\"resize\", update);\n    return () => window.removeEventListener(\"resize\", update);\n  }, []);\n\n  const { cols, rows, cellW, cellH } = grid;\n  const total = cols * rows;\n\n  return (\n    <div ref={ref} className=\"absolute inset-0 overflow-hidden\">\n      {total > 0 && (\n        <div\n          className=\"h-full w-full\"\n          style={{\n            display: \"grid\",\n            gridTemplateColumns: `repeat(${cols}, ${cellW}px)`,\n            gridTemplateRows: `repeat(${rows}, ${cellH}px)`,\n          }}\n        >\n          {Array.from({ length: total }).map((_, i) => (\n            <div key={i} className=\"border-r border-b border-white/6\" />\n          ))}\n        </div>\n      )}\n    </div>\n  );\n};\n\ninterface Cta04Props {\n  title?: string;\n  description?: string;\n  buttons?: {\n    text: string;\n    url?: string;\n    icon?: React.ReactNode;\n    variant?: \"default\" | \"outline\" | \"ghost\" | \"secondary\" | \"link\";\n  }[];\n  icon?: React.ReactNode;\n  className?: string;\n}\n\nconst Cta04 = ({\n  title = \"Ship faster. Build better.\",\n  description = \"Production-ready shadcn/ui blocks for your next project.\",\n  icon = <LogoIcon className=\"size-6 invert\" />,\n  buttons = [\n    {\n      text: \"Get Started now\",\n      url: \"#\",\n      icon: <ArrowUpRight className=\"size-4\" />,\n      variant: \"secondary\",\n    },\n    {\n      text: \"View Docs\",\n      url: \"#\",\n      icon: <Book className=\"size-4\" />,\n      variant: \"outline\",\n    },\n  ],\n  className,\n}: Cta04Props) => (\n  <section className={cn(\"w-full\", className)}>\n    <div className=\"relative flex items-center justify-center overflow-hidden bg-zinc-950 py-16 text-white md:py-24 lg:py-32\">\n      <GridBackground />\n      <div className=\"relative z-10 container mx-auto flex flex-col items-center gap-4 px-8 text-center\">\n        <div className=\"grid size-12 place-items-center rounded-md border border-white/6 bg-primary text-primary-foreground dark:border dark:bg-background\">\n          {icon}\n        </div>\n        <h2 className=\"max-w-3xl text-4xl font-medium tracking-tight md:text-5xl lg:text-6xl\">\n          {title}\n        </h2>\n        <p className=\"max-w-lg text-base leading-relaxed text-white/50 md:text-lg\">\n          {description}\n        </p>\n        {buttons && buttons.length > 0 && (\n          <div className=\"flex w-full flex-col gap-4 sm:w-auto sm:flex-row\">\n            {buttons.map((btn, i) => (\n              <Button\n                key={i}\n                size=\"lg\"\n                variant={btn.variant ?? \"secondary\"}\n                className={cn(\n                  \"w-full sm:w-auto\",\n                  btn.variant === \"outline\" &&\n                    \"border-white/20 bg-transparent text-white hover:bg-white/10 hover:text-white\",\n                )}\n                asChild\n              >\n                <a href={btn.url}>\n                  {btn.text} {btn.icon}\n                </a>\n              </Button>\n            ))}\n          </div>\n        )}\n      </div>\n    </div>\n  </section>\n);\n\nexport default Cta04;\n",
      "type": "registry:component",
      "target": "components/cta-04.tsx"
    }
  ],
  "meta": {
    "image": "/r/previews/cta-04.webp",
    "imageDark": "/r/previews/cta-04-dark.webp",
    "prose": {
      "about": "CTA 04 is a centered full-width card with a subtle grid background pattern, a bold headline, a description paragraph, and a single primary action button. Built with shadcn/ui Card and Tailwind CSS, the grid background adds visual interest without competing with the call-to-action copy. It is designed as a section-closing block that re-engages visitors who scrolled past earlier CTAs.",
      "whenToUse": [
        "Bottom of long landing pages as a final conversion prompt before the footer",
        "After a feature section or pricing table where users have seen enough information to decide",
        "Pages that need a visually distinct closing section that feels different from a flat horizontal CTA",
        "Situations where a single, unambiguous CTA without a secondary option performs better for your audience"
      ],
      "notes": "The grid background is a pure CSS pattern — no image files. The CTA headline here should be action-oriented and specific: 'Start your free trial' outperforms 'Get started' for conversion."
    }
  },
  "categories": [
    "cta"
  ],
  "type": "registry:block"
}