{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "newsletter-signup",
  "title": "Newsletter Signup",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/newsletter-signup/NewsletterSignup.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { ArrowRight, BellRing, BookOpen, Check, Mail, Send } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Separator } from '@/components/ui/separator'\nimport { cn } from '@/lib/utils'\n\nexport interface NewsletterSignupProps {\n  variant?: 'centered' | 'split'\n}\n\ninterface ChannelOption {\n  id: string\n  title: string\n  frequency: string\n  description: string\n  badge: string\n}\n\nconst channels: ChannelOption[] = [\n  {\n    id: 'architecture',\n    title: 'Architecture & Token Deep Dives',\n    frequency: 'Bi-Weekly',\n    description: 'Technical breakdowns on OKLCH color science, headless AST transformers, and zero-lockin paradigms.',\n    badge: 'Flagship',\n  },\n  {\n    id: 'releases',\n    title: 'Registry Ship Notes & RFCs',\n    frequency: 'Monthly',\n    description: 'Direct changelogs, new workbench releases, breaking primitive refactors, and roadmap discussions.',\n    badge: 'Changelog',\n  },\n  {\n    id: 'security',\n    title: 'Security & Dependency Bulletins',\n    frequency: 'As-Needed',\n    description: 'Zero-day vulnerability alerts, upstream headless primitive fixes, and patch notifications.',\n    badge: 'Critical',\n  },\n]\n\nconst recentIssues = [\n  {\n    id: 48,\n    date: 'Aug 2026',\n    title: 'The Death of Monolithic npm UI Packages',\n    reads: '4 min read',\n    tags: ['Architecture', 'Registry', 'AST'],\n    snippet:\n      'Why the next decade of frontend engineering belongs to unbundled registries where the consumer owns the source code.',\n  },\n  {\n    id: 47,\n    date: 'Jul 2026',\n    title: 'OKLCH Theming in Tailwind CSS v4',\n    reads: '6 min read',\n    tags: ['Tailwind v4', 'Color Science', 'Tokens'],\n    snippet:\n      'Mastering perceptual lightness, chroma gamut mapping, and dynamic theme switching without runtime CSS bloat.',\n  },\n]\n\nexport function NewsletterSignup({ variant = 'split' }: NewsletterSignupProps) {\n  const [email, setEmail] = React.useState('')\n  const [selectedChannel, setSelectedChannel] = React.useState('architecture')\n  const [submitted, setSubmitted] = React.useState(false)\n  const [activePreviewIssue, setActivePreviewIssue] = React.useState(0)\n  const [isSubmitting, setIsSubmitting] = React.useState(false)\n\n  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n    event.preventDefault()\n    if (!email || !email.includes('@')) return\n\n    setIsSubmitting(true)\n    setTimeout(() => {\n      setIsSubmitting(false)\n      setSubmitted(true)\n    }, 400)\n  }\n\n  return (\n    <section\n      data-slot=\"newsletter-signup\"\n      className=\"bg-background relative overflow-hidden px-4 py-16 sm:px-6 lg:px-8\"\n    >\n      <div className=\"mx-auto max-w-6xl space-y-10\">\n        {/* Section Header */}\n        <div className=\"max-w-3xl space-y-3\">\n          <Badge variant=\"secondary\" className=\"gap-1.5 px-3 py-1 font-mono text-xs shadow-xs\">\n            <Mail className=\"text-primary size-3.5\" />\n            Engineering Dispatch & Architecture Radar\n          </Badge>\n          <h2 className=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">\n            Ship notes, not marketing fluff.\n          </h2>\n          <p className=\"text-muted-foreground text-sm leading-relaxed sm:text-base\">\n            Join 18,400+ frontend architects, design engineers, and systems builders. Plain-text insights into component\n            architecture, token systems, and dual-framework engineering.\n          </p>\n        </div>\n\n        {/* Main Layout */}\n        <div className=\"grid grid-cols-1 items-start gap-8 lg:grid-cols-12\">\n          {/* Left Column: Channel Selector & Live Dispatch Form (7 Cols) */}\n          <div className=\"space-y-6 lg:col-span-7\">\n            <Card className=\"border-border bg-card overflow-hidden shadow-sm\">\n              <CardHeader className=\"bg-muted/20 border-border/60 border-b pb-4\">\n                <div className=\"flex items-center justify-between\">\n                  <CardTitle className=\"flex items-center gap-2 text-base font-semibold\">\n                    <BellRing className=\"text-primary size-4\" />\n                    Select Dispatch Track\n                  </CardTitle>\n                  <span className=\"text-muted-foreground font-mono text-xs\">Zero Spam Guarantee</span>\n                </div>\n                <CardDescription className=\"text-xs\">\n                  Choose the telemetry streams you want delivered to your inbox.\n                </CardDescription>\n              </CardHeader>\n\n              <CardContent className=\"space-y-5 p-6\">\n                {/* Channel Radio Cards */}\n                <div className=\"space-y-2.5\">\n                  {channels.map((ch) => {\n                    const isSelected = selectedChannel === ch.id\n                    return (\n                      <div\n                        key={ch.id}\n                        className={cn(\n                          'group cursor-pointer rounded-xl border p-3.5 transition-colors',\n                          isSelected\n                            ? 'border-primary bg-primary/5 ring-primary/20 shadow-xs ring-1'\n                            : 'border-border bg-background hover:bg-muted/40',\n                        )}\n                        onClick={() => setSelectedChannel(ch.id)}\n                      >\n                        <div className=\"flex items-center justify-between gap-2\">\n                          <div className=\"flex items-center gap-2\">\n                            <div\n                              className={cn(\n                                'flex size-3.5 items-center justify-center rounded-full border transition-colors',\n                                isSelected ? 'border-primary bg-primary' : 'border-muted-foreground/40',\n                              )}\n                            >\n                              {isSelected && <div className=\"bg-primary-foreground size-1.5 rounded-full\" />}\n                            </div>\n                            <span className=\"text-foreground text-xs font-semibold\">{ch.title}</span>\n                          </div>\n                          <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                            {ch.frequency}\n                          </Badge>\n                        </div>\n                        <p className=\"text-muted-foreground mt-1.5 pl-5.5 text-xs leading-relaxed\">{ch.description}</p>\n                      </div>\n                    )\n                  })}\n                </div>\n\n                <Separator />\n\n                {/* Dispatch Subscription Input */}\n                {!submitted ? (\n                  <form className=\"space-y-3\" onSubmit={handleSubmit}>\n                    <div className=\"flex flex-col gap-2 sm:flex-row\">\n                      <Input\n                        type=\"email\"\n                        placeholder=\"architect@company.com\"\n                        value={email}\n                        onChange={(e) => setEmail(e.target.value)}\n                        required\n                        className=\"h-10 flex-1 font-mono text-xs\"\n                        aria-label=\"Email address for dispatch\"\n                      />\n                      <Button type=\"submit\" disabled={isSubmitting} className=\"h-10 gap-1.5 px-5 text-xs font-semibold\">\n                        <span>Subscribe to Stream</span>\n                        <Send className=\"size-3.5\" />\n                      </Button>\n                    </div>\n                    <div className=\"text-muted-foreground flex items-center justify-between pt-1 font-mono text-xs\">\n                      <span>Plain text &bull; 1-click unsubscribe</span>\n                      <span className=\"text-success font-semibold\">18,412 Active Subscribers</span>\n                    </div>\n                  </form>\n                ) : (\n                  <div className=\"border-success/20 bg-success/10 space-y-2 rounded-xl border p-5 text-center\">\n                    <div className=\"bg-success/20 text-success mx-auto flex size-9 items-center justify-center rounded-full\">\n                      <Check className=\"size-5\" />\n                    </div>\n                    <p className=\"text-foreground text-sm font-semibold\">Dispatches Activated!</p>\n                    <p className=\"text-muted-foreground text-xs\">\n                      Verification sent to <strong className=\"text-foreground font-mono\">{email}</strong>. Check your\n                      inbox to confirm delivery.\n                    </p>\n                  </div>\n                )}\n              </CardContent>\n            </Card>\n          </div>\n\n          {/* Right Column: Recent Issue Sampler & Archives (5 Cols) */}\n          <div className=\"space-y-4 lg:col-span-5\">\n            <div className=\"flex items-center justify-between\">\n              <p className=\"text-muted-foreground flex items-center gap-1.5 font-mono text-xs tracking-wider uppercase\">\n                <BookOpen className=\"text-primary size-3.5\" /> Archive Sampler\n              </p>\n              <span className=\"text-muted-foreground font-mono text-xs\">\n                Issue #{recentIssues[activePreviewIssue].id}\n              </span>\n            </div>\n\n            {/* Interactive Issue Cards */}\n            <div className=\"space-y-3\">\n              {recentIssues.map((issue, idx) => (\n                <div\n                  key={issue.id}\n                  className={cn(\n                    'bg-card cursor-pointer rounded-xl border p-4 transition-colors',\n                    activePreviewIssue === idx ? 'border-primary/50 shadow-xs' : 'border-border hover:border-border/80',\n                  )}\n                  onClick={() => setActivePreviewIssue(idx)}\n                >\n                  <div className=\"text-muted-foreground mb-1.5 flex items-center justify-between font-mono text-xs\">\n                    <span>\n                      {issue.date} &bull; Issue #{issue.id}\n                    </span>\n                    <span className=\"text-foreground font-medium\">{issue.reads}</span>\n                  </div>\n                  <h3 className=\"text-foreground mb-1.5 text-sm leading-snug font-bold\">{issue.title}</h3>\n                  <p className=\"text-muted-foreground text-xs leading-relaxed\">{issue.snippet}</p>\n\n                  <div className=\"mt-3 flex flex-wrap gap-1.5\">\n                    {issue.tags.map((tag) => (\n                      <Badge key={tag} variant=\"secondary\" className=\"px-1.5 py-0 font-mono text-xs\">\n                        #{tag}\n                      </Badge>\n                    ))}\n                  </div>\n                </div>\n              ))}\n            </div>\n\n            {/* RSS note */}\n            <div className=\"border-border bg-muted/20 text-muted-foreground flex items-center justify-between rounded-lg border p-3.5 text-xs\">\n              <span className=\"font-mono\">Prefer RSS feeds?</span>\n              <a\n                href=\"https://uipkge.dev/rss.xml\"\n                target=\"_blank\"\n                rel=\"noreferrer\"\n                className=\"text-primary inline-flex items-center gap-1 font-mono hover:underline\"\n              >\n                uipkge.dev/rss.xml <ArrowRight className=\"size-3\" />\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>\n  )\n}\nexport default NewsletterSignup\n",
      "type": "registry:block",
      "target": "~/components/blocks/NewsletterSignup.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/separator.json"
  ],
  "description": "Engineering dispatch and release radar workbench with channel tracks (Architecture, Releases, Security), live archive previews, and subscriber metrics.",
  "categories": [
    "marketing"
  ],
  "deprecated": true,
  "replacedBy": "newsletter"
}