{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "newsletter",
  "title": "Newsletter",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-svelte/blocks/newsletter/NewsletterInlineBand.svelte",
      "content": "<script lang=\"ts\">\n  import { Check, Mail } from '@lucide/svelte'\n  import { Badge } from '$lib/components/ui/badge'\n  import { Button } from '$lib/components/ui/button'\n  import { Input } from '$lib/components/ui/input'\n\n  let email = $state('')\n  let submitted = $state(false)\n\n  function subscribe() {\n    if (!email.trim()) return\n    submitted = true\n  }\n</script>\n\n<section data-slot=\"newsletter-inline-band\" class=\"border-border bg-muted/40 border-y\">\n  <div class=\"mx-auto flex max-w-6xl flex-col gap-6 px-6 py-10 lg:flex-row lg:items-center lg:gap-12\">\n    <div class=\"min-w-0 lg:flex-1\">\n      <div class=\"flex items-center gap-2\">\n        <Mail class=\"text-muted-foreground size-4\" aria-hidden=\"true\" />\n        <Badge variant=\"secondary\">Monthly</Badge>\n      </div>\n      <p class=\"mt-2.5 text-lg leading-snug font-medium text-balance\">\n        Engineering notes on metric modelling, access control, and warehouse cost.\n      </p>\n      <p class=\"text-muted-foreground mt-1.5 text-sm\">\n        Read by 8,400 data and finance engineers. One email a month, no product announcements.\n      </p>\n    </div>\n\n    <form\n      class=\"lg:w-[26rem] lg:shrink-0\"\n      onsubmit={(e) => {\n        e.preventDefault()\n        subscribe()\n      }}\n    >\n      <div class=\"flex gap-2\">\n        <Input\n          bind:value={email}\n          type=\"email\"\n          required\n          placeholder=\"you@company.com\"\n          autocomplete=\"email\"\n          aria-label=\"Email address\"\n        />\n        <Button type=\"submit\" class=\"shrink-0\">Subscribe</Button>\n      </div>\n      <!-- Status row is reserved from first paint, so confirming does not\n           nudge the band's height and shift the page under the cursor. -->\n      <p class=\"mt-2 min-h-5 text-xs\" aria-live=\"polite\">\n        {#if submitted}\n          <span class=\"text-success inline-flex items-center gap-1.5\">\n            <Check class=\"size-3\" aria-hidden=\"true\" />\n            Check your inbox to confirm.\n          </span>\n        {:else}\n          <span class=\"text-muted-foreground\">Unsubscribe in one click. We never share the list.</span>\n        {/if}\n      </p>\n    </form>\n  </div>\n</section>\n",
      "type": "registry:block",
      "target": "~/src/lib/components/blocks/newsletter/NewsletterInlineBand.svelte"
    },
    {
      "path": "packages/registry-svelte/blocks/newsletter/NewsletterIssueArchive.svelte",
      "content": "<script lang=\"ts\" module>\n  export interface NewsletterIssue {\n    id: string\n    issueNumber: number\n    volumeDate: string\n    title: string\n    excerpt: string\n    category: 'Architecture' | 'Design Tokens' | 'Performance' | 'Interviews'\n    tags: string[]\n    readTime: string\n    date: string\n    commentsCount: number\n    likesCount: number\n    featured?: boolean\n  }\n\n  export interface NewsletterIssueArchiveProps {\n    publicationName?: string\n    subtitle?: string\n    subscriberCount?: string\n    class?: string\n  }\n</script>\n\n<script lang=\"ts\">\n  import {\n    ArrowRight,\n    Bookmark,\n    Calendar,\n    Check,\n    Clock,\n    Heart,\n    MessageSquare,\n    Newspaper,\n    Rss,\n    Search,\n    Users,\n    X,\n    Zap,\n  } from '@lucide/svelte'\n  import { cn } from '$lib/utils'\n  import { Badge } from '$lib/components/ui/badge'\n  import { Button } from '$lib/components/ui/button'\n  import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '$lib/components/ui/card'\n  import { Input } from '$lib/components/ui/input'\n\n  let {\n    publicationName = 'The Unbundled Engineer',\n    subtitle = 'Weekly architectural teardowns of modern design systems, web performance, and component registries.',\n    subscriberCount = '42,500+ Subscribers · Top 1% on Substack',\n    class: className,\n  }: NewsletterIssueArchiveProps = $props()\n\n  let email = $state('')\n  let isSubscribed = $state(false)\n  let searchQuery = $state('')\n  let selectedCategory = $state<string>('All Issues')\n\n  function handleSubscribe() {\n    if (!email || !email.includes('@')) return\n    isSubscribed = true\n  }\n\n  const categories = ['All Issues', 'Architecture', 'Design Tokens', 'Performance', 'Interviews'] as const\n\n  const featuredIssue: NewsletterIssue = {\n    id: 'issue-43',\n    issueNumber: 43,\n    volumeDate: 'Aug 2026',\n    title: 'The Death of npm Component Libraries: Why Unbundled Registry Architecture Won',\n    excerpt:\n      'How unbundled UI registries replaced monolithic node_modules packages, eliminated dependency hell, and gave full code ownership back to frontend engineering teams across the industry.',\n    category: 'Architecture',\n    tags: ['#architecture', '#registries', '#future-of-web', '#tooling'],\n    readTime: '9 min read',\n    date: 'Aug 25, 2026',\n    commentsCount: 128,\n    likesCount: 1420,\n    featured: true,\n  }\n\n  const archiveIssues: NewsletterIssue[] = [\n    {\n      id: 'issue-42',\n      issueNumber: 42,\n      volumeDate: 'Aug 2026',\n      title: 'Why Zero-Dependency Registries Are Winning',\n      excerpt:\n        'A deep dive into why enterprise engineering teams are abandoning monolithic UI packages in favor of composable own-your-code registry models that eliminate breaking upgrade cascades.',\n      category: 'Architecture',\n      tags: ['#architecture', '#web-performance', '#dx'],\n      readTime: '6 min read',\n      date: 'Aug 18, 2026',\n      commentsCount: 84,\n      likesCount: 642,\n    },\n    {\n      id: 'issue-41',\n      issueNumber: 41,\n      volumeDate: 'Aug 2026',\n      title: 'Mastering Tailwind v4: OKLCH Colors & Dynamic Themes',\n      excerpt:\n        'How modern CSS color spaces and inline theme definitions unlock mathematically perceptually uniform light/dark transitions without CSS variables explosion.',\n      category: 'Design Tokens',\n      tags: ['#design-tokens', '#css', '#theming'],\n      readTime: '8 min read',\n      date: 'Aug 11, 2026',\n      commentsCount: 56,\n      likesCount: 519,\n    },\n    {\n      id: 'issue-40',\n      issueNumber: 40,\n      volumeDate: 'Aug 2026',\n      title: 'Zero-CLS Island Hydration in Modern Web Frameworks',\n      excerpt:\n        'Eliminating Cumulative Layout Shift when server-rendered islands hydrate in Astro and SvelteKit. Practical patterns distilled from serving 1M+ monthly pageviews.',\n      category: 'Performance',\n      tags: ['#performance', '#core-web-vitals', '#sveltekit'],\n      readTime: '5 min read',\n      date: 'Aug 04, 2026',\n      commentsCount: 92,\n      likesCount: 730,\n    },\n    {\n      id: 'issue-39',\n      issueNumber: 39,\n      volumeDate: 'Jul 2026',\n      title: 'Interview: Building High-Craft Interfaces with Paco Coursey',\n      excerpt:\n        'The creator of cmdk and sonner breaks down spring physics, popover placement math, and why 60fps micro-interactions define software brand trust.',\n      category: 'Interviews',\n      tags: ['#interviews', '#craft', '#animation'],\n      readTime: '11 min read',\n      date: 'Jul 28, 2026',\n      commentsCount: 147,\n      likesCount: 1205,\n    },\n    {\n      id: 'issue-38',\n      issueNumber: 38,\n      volumeDate: 'Jul 2026',\n      title: 'Building Resilient Component APIs with Polymorphic Snippets',\n      excerpt:\n        'Why the child-snippet composition pattern beat standard prop drilling for accessible primitives, and how runes implement headless polymorphism without DOM overhead.',\n      category: 'Architecture',\n      tags: ['#architecture', '#svelte', '#runes'],\n      readTime: '7 min read',\n      date: 'Jul 21, 2026',\n      commentsCount: 63,\n      likesCount: 488,\n    },\n    {\n      id: 'issue-37',\n      issueNumber: 37,\n      volumeDate: 'Jul 2026',\n      title: 'Designing for Multi-Tenant White-Labeling at Scale',\n      excerpt:\n        'Architecting a headless token graph that dynamically maps corporate brand identities and custom color palettes across 500+ enterprise subdomains in real time.',\n      category: 'Design Tokens',\n      tags: ['#design-tokens', '#architecture', '#enterprise'],\n      readTime: '9 min read',\n      date: 'Jul 14, 2026',\n      commentsCount: 71,\n      likesCount: 610,\n    },\n  ]\n\n  function focusEmailInput() {\n    const el = document.getElementById('newsletter-archive-email')\n    el?.focus()\n  }\n\n  const filteredIssues = $derived.by(() => {\n    const query = searchQuery.trim().toLowerCase()\n    return archiveIssues.filter((issue) => {\n      const matchesCategory = selectedCategory === 'All Issues' || issue.category === selectedCategory\n\n      const matchesSearch =\n        !query ||\n        issue.title.toLowerCase().includes(query) ||\n        issue.excerpt.toLowerCase().includes(query) ||\n        issue.tags.some((tag) => tag.toLowerCase().includes(query)) ||\n        `issue #${issue.issueNumber}`.toLowerCase().includes(query)\n\n      return matchesCategory && matchesSearch\n    })\n  })\n\n  function getCategoryCount(cat: string) {\n    if (cat === 'All Issues') return archiveIssues.length\n    return archiveIssues.filter((issue) => issue.category === cat).length\n  }\n\n  function clearFilters() {\n    searchQuery = ''\n    selectedCategory = 'All Issues'\n  }\n</script>\n\n<div\n  data-slot=\"newsletter-issue-archive\"\n  class={cn('mx-auto w-full max-w-5xl space-y-12 px-4 py-8 sm:px-6 sm:py-12', className)}\n>\n  <!-- Newsletter Header Hero -->\n  <header class=\"mx-auto max-w-3xl space-y-4 text-center\">\n    <div\n      class=\"border-primary/20 bg-primary/5 text-primary inline-flex items-center gap-1.5 rounded-full border px-3.5 py-1 text-xs font-medium shadow-xs\"\n    >\n      <Users class=\"size-3.5 shrink-0\" aria-hidden=\"true\" />\n      <span>{subscriberCount}</span>\n    </div>\n\n    <h1 class=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl\">\n      {publicationName}\n    </h1>\n\n    <p class=\"text-muted-foreground mx-auto max-w-2xl text-base leading-relaxed sm:text-lg\">\n      {subtitle}\n    </p>\n\n    <!-- Subscribe Form -->\n    <div class=\"mx-auto w-full max-w-md pt-2\">\n      {#if !isSubscribed}\n        <form\n          class=\"flex flex-col gap-2 sm:flex-row sm:gap-0\"\n          onsubmit={(e) => {\n            e.preventDefault()\n            handleSubscribe()\n          }}\n        >\n          <Input\n            id=\"newsletter-archive-email\"\n            bind:value={email}\n            type=\"email\"\n            placeholder=\"Enter your work email...\"\n            required\n            class=\"bg-card h-11 text-sm shadow-xs sm:rounded-r-none\"\n            aria-label=\"Work email address\"\n          />\n          <Button type=\"submit\" class=\"h-11 shrink-0 px-6 font-medium sm:rounded-l-none\">Subscribe for Free</Button>\n        </form>\n        <p class=\"text-muted-foreground mt-2.5 flex flex-wrap items-center justify-center gap-x-2 gap-y-1 text-xs\">\n          <span>Free weekly issues</span>\n          <span>Zero spam</span>\n          <span>1-click unsubscribe</span>\n        </p>\n      {:else}\n        <div\n          class=\"border-success/30 bg-success/10 text-success inline-flex items-center gap-2.5 rounded-lg border px-4 py-3 text-sm font-medium shadow-xs\"\n        >\n          <Check class=\"size-4 shrink-0\" aria-hidden=\"true\" />\n          <span>You&rsquo;re subscribed! Check your inbox for confirmation.</span>\n        </div>\n      {/if}\n    </div>\n  </header>\n\n  <!-- Featured Issue Spotlight Card -->\n  <section aria-labelledby=\"featured-issue-heading\" class=\"space-y-3\">\n    <div class=\"flex items-center justify-between px-1\">\n      <h2 id=\"featured-issue-heading\" class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n        Pinned Spotlight Edition\n      </h2>\n      <Badge variant=\"outline\" class=\"text-primary border-primary/30 gap-1 text-xs\">\n        <Zap class=\"size-3\" aria-hidden=\"true\" /> Latest Release\n      </Badge>\n    </div>\n\n    <Card class=\"border-border/80 bg-card hover:border-primary/40 overflow-hidden shadow-xs transition-colors\">\n      <div class=\"grid grid-cols-1 gap-6 p-6 sm:p-8 lg:grid-cols-12\">\n        <!-- Text Content -->\n        <div class=\"flex flex-col justify-between space-y-4 lg:col-span-7\">\n          <div class=\"space-y-3\">\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <Badge variant=\"default\" class=\"font-mono text-xs\">\n                Issue #{featuredIssue.issueNumber} · {featuredIssue.volumeDate}\n              </Badge>\n              <Badge variant=\"secondary\" class=\"text-xs\">\n                {featuredIssue.category}\n              </Badge>\n              <span class=\"text-muted-foreground ml-auto inline-flex items-center gap-1 text-xs\">\n                <Clock class=\"size-3\" aria-hidden=\"true\" />\n                {featuredIssue.readTime}\n              </span>\n            </div>\n\n            <h3\n              class=\"text-foreground hover:text-primary cursor-pointer text-xl font-bold tracking-tight transition-colors sm:text-2xl\"\n            >\n              {featuredIssue.title}\n            </h3>\n\n            <p class=\"text-muted-foreground text-sm leading-relaxed sm:text-base\">\n              {featuredIssue.excerpt}\n            </p>\n          </div>\n\n          <div class=\"space-y-4 pt-2\">\n            <div class=\"flex flex-wrap gap-1.5\">\n              {#each featuredIssue.tags as tag (tag)}\n                <Badge variant=\"outline\" class=\"text-muted-foreground font-mono text-xs font-normal\">\n                  {tag}\n                </Badge>\n              {/each}\n            </div>\n\n            <div class=\"border-border/60 flex flex-wrap items-center justify-between gap-4 border-t pt-3\">\n              <div class=\"text-muted-foreground flex items-center gap-4 text-xs\">\n                <span class=\"inline-flex items-center gap-1.5\">\n                  <Calendar class=\"size-3.5\" aria-hidden=\"true\" />\n                  {featuredIssue.date}\n                </span>\n                <span class=\"inline-flex items-center gap-1.5\">\n                  <MessageSquare class=\"size-3.5\" aria-hidden=\"true\" />\n                  {featuredIssue.commentsCount} comments\n                </span>\n                <span class=\"inline-flex items-center gap-1.5\">\n                  <Heart class=\"size-3.5\" aria-hidden=\"true\" />\n                  {featuredIssue.likesCount}\n                </span>\n              </div>\n\n              <Button variant=\"default\" size=\"sm\" class=\"group gap-1.5 font-medium\">\n                Read Issue\n                <ArrowRight class=\"size-3.5 transition-transform group-hover:translate-x-0.5\" aria-hidden=\"true\" />\n              </Button>\n            </div>\n          </div>\n        </div>\n\n        <!-- Schematic Cover Illustration -->\n        <div class=\"flex items-center lg:col-span-5\">\n          <div class=\"border-border/80 bg-muted/40 w-full rounded-lg border p-4 font-mono text-xs sm:p-5\">\n            <div class=\"border-border/60 mb-3 flex items-center justify-between border-b pb-2.5\">\n              <div class=\"flex items-center gap-1.5\">\n                <span class=\"bg-destructive/60 inline-block size-2.5 rounded-full\"></span>\n                <span class=\"bg-warning/60 inline-block size-2.5 rounded-full\"></span>\n                <span class=\"bg-success/60 inline-block size-2.5 rounded-full\"></span>\n              </div>\n              <span class=\"text-muted-foreground text-xs\">registry-teardown.ts</span>\n            </div>\n            <div class=\"text-muted-foreground space-y-2\">\n              <div class=\"text-primary text-xs font-medium\">// Own your component code</div>\n              <div><span class=\"text-foreground\">$</span> npx shadcn-svelte@latest add @uipkge/svelte/card</div>\n              <div class=\"text-success\">✔ Fetched raw TypeScript Svelte</div>\n              <div class=\"text-success\">✔ Merged local Tailwind v4 tokens</div>\n              <div class=\"text-muted-foreground/80 pt-1\">// Zero runtime package lock-in</div>\n            </div>\n            <div class=\"border-border/40 mt-4 flex flex-wrap gap-1.5 border-t pt-3\">\n              <span class=\"bg-background text-foreground border-border rounded border px-2 py-0.5 text-xs\">\n                Zero npm deps</span\n              >\n              <span class=\"bg-background text-foreground border-border rounded border px-2 py-0.5 text-xs\">\n                Tailwind v4</span\n              >\n              <span class=\"bg-background text-foreground border-border rounded border px-2 py-0.5 text-xs\">OKLCH</span>\n            </div>\n          </div>\n        </div>\n      </div>\n    </Card>\n  </section>\n\n  <!-- Search and Filter Bar -->\n  <section aria-label=\"Search and filter archive\" class=\"space-y-4\">\n    <div class=\"flex flex-col items-stretch justify-between gap-4 md:flex-row md:items-center\">\n      <!-- Search Input -->\n      <div class=\"w-full md:max-w-md\">\n        <Input\n          bind:value={searchQuery}\n          type=\"search\"\n          placeholder=\"Search issues by title, topic, or tag...\"\n          prefixIcon={Search}\n          allowClear\n          class=\"bg-card shadow-xs\"\n          aria-label=\"Search archive issues\"\n        />\n      </div>\n\n      <!-- Result Counter -->\n      <div class=\"text-muted-foreground flex items-center justify-between gap-3 text-xs md:justify-end\">\n        <span>Showing {filteredIssues.length} {filteredIssues.length === 1 ? 'edition' : 'editions'}</span>\n        {#if searchQuery || selectedCategory !== 'All Issues'}\n          <button\n            type=\"button\"\n            class=\"text-primary focus-visible:ring-ring inline-flex items-center gap-1 rounded font-medium hover:underline focus-visible:ring-1 focus-visible:outline-none\"\n            onclick={clearFilters}\n          >\n            Reset filters\n            <X class=\"size-3\" aria-hidden=\"true\" />\n          </button>\n        {/if}\n      </div>\n    </div>\n\n    <!-- Category Filter Pills -->\n    <div class=\"flex flex-wrap items-center gap-1.5\" role=\"tablist\" aria-label=\"Filter by category\">\n      {#each categories as cat (cat)}\n        <button\n          type=\"button\"\n          role=\"tab\"\n          aria-selected={selectedCategory === cat}\n          class={cn(\n            'focus-visible:ring-ring inline-flex items-center gap-1.5 rounded-full px-3.5 py-1.5 text-xs transition-colors focus-visible:ring-2 focus-visible:outline-none',\n            selectedCategory === cat\n              ? 'bg-primary text-primary-foreground font-medium shadow-xs'\n              : 'bg-muted/70 text-muted-foreground hover:bg-muted hover:text-foreground',\n          )}\n          onclick={() => (selectedCategory = cat)}\n        >\n          <span>{cat}</span>\n          <span\n            class={cn(\n              'py-0.2 rounded-full px-1.5 text-xs',\n              selectedCategory === cat\n                ? 'bg-primary-foreground/20 text-primary-foreground'\n                : 'bg-background/80 text-muted-foreground',\n            )}\n          >\n            {getCategoryCount(cat)}\n          </span>\n        </button>\n      {/each}\n    </div>\n  </section>\n\n  <!-- Issue Archive List -->\n  <section aria-label=\"Archive issue list\">\n    {#if filteredIssues.length > 0}\n      <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2\">\n        {#each filteredIssues as issue (issue.id)}\n          <Card\n            class=\"group border-border/70 bg-card hover:border-primary/40 flex flex-col justify-between transition-colors hover:shadow-xs\"\n          >\n            <CardHeader class=\"pb-3\">\n              <div class=\"flex items-center justify-between gap-2\">\n                <Badge variant=\"outline\" class=\"font-mono text-xs\">\n                  Issue #{issue.issueNumber} · {issue.volumeDate}\n                </Badge>\n                <span class=\"text-muted-foreground inline-flex items-center gap-1 text-xs\">\n                  <Clock class=\"size-3\" aria-hidden=\"true\" />\n                  {issue.readTime}\n                </span>\n              </div>\n\n              <CardTitle\n                class=\"group-hover:text-primary cursor-pointer pt-2 text-base leading-snug font-semibold tracking-tight transition-colors sm:text-lg\"\n              >\n                {issue.title}\n              </CardTitle>\n\n              <CardDescription class=\"text-muted-foreground mt-1.5 line-clamp-3 text-sm leading-relaxed\">\n                {issue.excerpt}\n              </CardDescription>\n            </CardHeader>\n\n            <CardContent class=\"py-0\">\n              <div class=\"flex flex-wrap gap-1.5 pt-1\">\n                {#each issue.tags as tag (tag)}\n                  <Badge variant=\"secondary\" class=\"font-mono text-xs font-normal\">\n                    {tag}\n                  </Badge>\n                {/each}\n              </div>\n            </CardContent>\n\n            <CardFooter\n              class=\"border-border/60 text-muted-foreground mt-4 flex items-center justify-between border-t pt-4 text-xs\"\n            >\n              <div class=\"flex items-center gap-3\">\n                <span class=\"inline-flex items-center gap-1\">\n                  <Calendar class=\"size-3\" aria-hidden=\"true\" />\n                  {issue.date}\n                </span>\n                <span class=\"inline-flex items-center gap-1\">\n                  <MessageSquare class=\"size-3\" aria-hidden=\"true\" />\n                  {issue.commentsCount}\n                </span>\n                <span class=\"inline-flex items-center gap-1\">\n                  <Heart class=\"size-3\" aria-hidden=\"true\" />\n                  {issue.likesCount}\n                </span>\n              </div>\n\n              <a\n                href=\"#read\"\n                class=\"text-foreground group-hover:text-primary inline-flex items-center gap-1 font-medium transition-colors focus-visible:underline focus-visible:outline-none\"\n              >\n                <span>Read Issue</span>\n                <ArrowRight class=\"size-3.5 transition-transform group-hover:translate-x-0.5\" aria-hidden=\"true\" />\n              </a>\n            </CardFooter>\n          </Card>\n        {/each}\n      </div>\n    {:else}\n      <!-- Empty State -->\n      <div class=\"border-border bg-card/50 space-y-3 rounded-xl border border-dashed p-10 text-center\">\n        <Newspaper class=\"text-muted-foreground/60 mx-auto size-8\" aria-hidden=\"true\" />\n        <h3 class=\"text-foreground text-base font-semibold\">No issues found</h3>\n        <p class=\"text-muted-foreground mx-auto max-w-sm text-sm\">\n          No newsletter issues matched &ldquo;{searchQuery}&rdquo; in {selectedCategory}.\n        </p>\n        <div class=\"pt-2\">\n          <Button variant=\"outline\" size=\"sm\" onclick={clearFilters}>Clear search &amp; filters</Button>\n        </div>\n      </div>\n    {/if}\n  </section>\n\n  <!-- Publication Cadence & RSS Bar -->\n  <footer\n    class=\"border-border/80 bg-muted/30 flex flex-col items-center justify-between gap-4 rounded-xl border p-6 text-center shadow-xs sm:flex-row sm:text-left\"\n  >\n    <div>\n      <h3 class=\"text-foreground text-sm font-semibold\">Never miss a teardown</h3>\n      <p class=\"text-muted-foreground mt-0.5 text-xs\">\n        Published every Tuesday morning. Zero sponsor promotions, purely deep technical architecture.\n      </p>\n    </div>\n\n    <div class=\"flex shrink-0 items-center gap-2.5\">\n      <Button variant=\"outline\" size=\"sm\" class=\"gap-1.5 text-xs\">\n        <Rss class=\"size-3.5\" aria-hidden=\"true\" />\n        RSS Feed\n      </Button>\n      <Button variant=\"default\" size=\"sm\" class=\"gap-1.5 text-xs\" onclick={focusEmailInput}>\n        <Bookmark class=\"size-3.5\" aria-hidden=\"true\" />\n        Join Newsletter\n      </Button>\n    </div>\n  </footer>\n</div>\n",
      "type": "registry:block",
      "target": "~/src/lib/components/blocks/newsletter/NewsletterIssueArchive.svelte"
    },
    {
      "path": "packages/registry-svelte/blocks/newsletter/NewsletterSignup.svelte",
      "content": "<script lang=\"ts\" module>\n  export interface NewsletterSignupProps {\n    variant?: 'centered' | 'split'\n  }\n\n  export interface ChannelOption {\n    id: string\n    title: string\n    frequency: string\n    description: string\n    badge: string\n  }\n</script>\n\n<script lang=\"ts\">\n  import { ArrowRight, BellRing, BookOpen, Check, Mail, Send } from '@lucide/svelte'\n  import { Badge } from '$lib/components/ui/badge'\n  import { Button } from '$lib/components/ui/button'\n  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '$lib/components/ui/card'\n  import { Input } from '$lib/components/ui/input'\n  import { Separator } from '$lib/components/ui/separator'\n  import { cn } from '$lib/utils'\n\n  // Mirrors the twin's API; layout is fixed (channel selector + archive\n  // sampler) and the variant only selects which demo story renders it.\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  let { variant = 'split' }: NewsletterSignupProps = $props()\n\n  const channels: ChannelOption[] = [\n    {\n      id: 'architecture',\n      title: 'Architecture & Token Deep Dives',\n      frequency: 'Bi-Weekly',\n      description:\n        '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\n  const 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\n  let email = $state('')\n  let selectedChannel = $state('architecture')\n  let submitted = $state(false)\n  let activePreviewIssue = $state(0)\n  let isSubmitting = $state(false)\n\n  function handleSubmit() {\n    if (!email || !email.includes('@')) return\n    isSubmitting = true\n    setTimeout(() => {\n      isSubmitting = false\n      submitted = true\n    }, 400)\n  }\n</script>\n\n<section data-slot=\"newsletter-signup\" class=\"bg-background relative overflow-hidden px-4 py-16 sm:px-6 lg:px-8\">\n  <div class=\"mx-auto max-w-6xl space-y-10\">\n    <!-- Section Header -->\n    <div class=\"max-w-3xl space-y-3\">\n      <Badge variant=\"secondary\" class=\"gap-1.5 px-3 py-1 font-mono text-xs shadow-xs\">\n        <Mail class=\"text-primary size-3.5\" />\n        Engineering Dispatch & Architecture Radar\n      </Badge>\n      <h2 class=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">Ship notes, not marketing fluff.</h2>\n      <p class=\"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 multi-framework engineering.\n      </p>\n    </div>\n\n    <!-- Main Layout -->\n    <div class=\"grid grid-cols-1 items-start gap-8 lg:grid-cols-12\">\n      <!-- Left Column: Channel Selector & Live Dispatch Form (7 Cols) -->\n      <div class=\"space-y-6 lg:col-span-7\">\n        <Card class=\"border-border bg-card overflow-hidden shadow-sm\">\n          <CardHeader class=\"bg-muted/20 border-border/60 border-b pb-4\">\n            <div class=\"flex items-center justify-between\">\n              <CardTitle class=\"flex items-center gap-2 text-base font-semibold\">\n                <BellRing class=\"text-primary size-4\" />\n                Select Dispatch Track\n              </CardTitle>\n              <span class=\"text-muted-foreground font-mono text-xs\">Zero Spam Guarantee</span>\n            </div>\n            <CardDescription class=\"text-xs\">\n              Choose the telemetry streams you want delivered to your inbox.\n            </CardDescription>\n          </CardHeader>\n\n          <CardContent class=\"space-y-5 p-6\">\n            <!-- Channel Radio Cards -->\n            <div class=\"space-y-2.5\">\n              {#each channels as ch (ch.id)}\n                <div\n                  class={cn(\n                    'group cursor-pointer rounded-xl border p-3.5 transition-colors',\n                    selectedChannel === ch.id\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={() => (selectedChannel = ch.id)}\n                  onkeydown={(e) => {\n                    if (e.key === 'Enter' || e.key === ' ') {\n                      e.preventDefault()\n                      selectedChannel = ch.id\n                    }\n                  }}\n                  role=\"radio\"\n                  aria-checked={selectedChannel === ch.id}\n                  tabindex=\"0\"\n                >\n                  <div class=\"flex items-center justify-between gap-2\">\n                    <div class=\"flex items-center gap-2\">\n                      <div\n                        class={cn(\n                          'flex size-3.5 items-center justify-center rounded-full border transition-colors',\n                          selectedChannel === ch.id ? 'border-primary bg-primary' : 'border-muted-foreground/40',\n                        )}\n                      >\n                        {#if selectedChannel === ch.id}\n                          <div class=\"bg-primary-foreground size-1.5 rounded-full\"></div>\n                        {/if}\n                      </div>\n                      <span class=\"text-foreground text-xs font-semibold\">{ch.title}</span>\n                    </div>\n                    <Badge variant=\"outline\" class=\"font-mono text-xs\">\n                      {ch.frequency}\n                    </Badge>\n                  </div>\n                  <p class=\"text-muted-foreground mt-1.5 pl-5.5 text-xs leading-relaxed\">\n                    {ch.description}\n                  </p>\n                </div>\n              {/each}\n            </div>\n\n            <Separator />\n\n            <!-- Dispatch Subscription Input -->\n            {#if !submitted}\n              <form\n                class=\"space-y-3\"\n                onsubmit={(e) => {\n                  e.preventDefault()\n                  handleSubmit()\n                }}\n              >\n                <div class=\"flex flex-col gap-2 sm:flex-row\">\n                  <Input\n                    bind:value={email}\n                    type=\"email\"\n                    placeholder=\"architect@company.com\"\n                    required\n                    class=\"h-10 flex-1 font-mono text-xs\"\n                    aria-label=\"Email address for dispatch\"\n                  />\n                  <Button type=\"submit\" disabled={isSubmitting} class=\"h-10 gap-1.5 px-5 text-xs font-semibold\">\n                    <span>Subscribe to Stream</span>\n                    <Send class=\"size-3.5\" />\n                  </Button>\n                </div>\n                <div class=\"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 class=\"text-success font-semibold\">18,412 Active Subscribers</span>\n                </div>\n              </form>\n            {:else}\n              <!-- Subscription Success View -->\n              <div class=\"border-success/20 bg-success/10 space-y-2 rounded-xl border p-5 text-center\">\n                <div class=\"bg-success/20 text-success mx-auto flex size-9 items-center justify-center rounded-full\">\n                  <Check class=\"size-5\" />\n                </div>\n                <p class=\"text-foreground text-sm font-semibold\">Dispatches Activated!</p>\n                <p class=\"text-muted-foreground text-xs\">\n                  Verification sent to <strong class=\"text-foreground font-mono\">{email}</strong>. Check your inbox to\n                  confirm delivery.\n                </p>\n              </div>\n            {/if}\n          </CardContent>\n        </Card>\n      </div>\n\n      <!-- Right Column: Recent Issue Sampler & Archives (5 Cols) -->\n      <div class=\"space-y-4 lg:col-span-5\">\n        <div class=\"flex items-center justify-between\">\n          <p class=\"text-muted-foreground flex items-center gap-1.5 font-mono text-xs tracking-wider uppercase\">\n            <BookOpen class=\"text-primary size-3.5\" /> Archive Sampler\n          </p>\n          <span class=\"text-muted-foreground font-mono text-xs\">Issue #{recentIssues[activePreviewIssue].id}</span>\n        </div>\n\n        <!-- Interactive Issue Cards -->\n        <div class=\"space-y-3\">\n          {#each recentIssues as issue, idx (issue.id)}\n            <div\n              class={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={() => (activePreviewIssue = idx)}\n              onkeydown={(e) => {\n                if (e.key === 'Enter' || e.key === ' ') {\n                  e.preventDefault()\n                  activePreviewIssue = idx\n                }\n              }}\n              role=\"button\"\n              tabindex=\"0\"\n            >\n              <div class=\"text-muted-foreground mb-1.5 flex items-center justify-between font-mono text-xs\">\n                <span>{issue.date} &bull; Issue #{issue.id}</span>\n                <span class=\"text-foreground font-medium\">{issue.reads}</span>\n              </div>\n              <h3 class=\"text-foreground mb-1.5 text-sm leading-snug font-bold\">{issue.title}</h3>\n              <p class=\"text-muted-foreground text-xs leading-relaxed\">{issue.snippet}</p>\n\n              <div class=\"mt-3 flex flex-wrap gap-1.5\">\n                {#each issue.tags as tag (tag)}\n                  <Badge variant=\"secondary\" class=\"px-1.5 py-0 font-mono text-xs\">\n                    #{tag}\n                  </Badge>\n                {/each}\n              </div>\n            </div>\n          {/each}\n        </div>\n\n        <!-- RSS / Mastodon / CLI note -->\n        <div\n          class=\"border-border bg-muted/20 text-muted-foreground flex items-center justify-between rounded-lg border p-3.5 text-xs\"\n        >\n          <span class=\"font-mono\">Prefer RSS feeds?</span>\n          <a\n            href=\"https://uipkge.dev/rss.xml\"\n            target=\"_blank\"\n            rel=\"noreferrer\"\n            class=\"text-primary inline-flex items-center gap-1 font-mono hover:underline\"\n          >\n            uipkge.dev/rss.xml <ArrowRight class=\"size-3\" />\n          </a>\n        </div>\n      </div>\n    </div>\n  </div>\n</section>\n",
      "type": "registry:block",
      "target": "~/src/lib/components/blocks/newsletter/NewsletterSignup.svelte"
    },
    {
      "path": "packages/registry-svelte/blocks/newsletter/NewsletterSplitPreview.svelte",
      "content": "<script lang=\"ts\">\n  import { Check, Mail } from '@lucide/svelte'\n  import { Badge } from '$lib/components/ui/badge'\n  import { Button } from '$lib/components/ui/button'\n  import { Card, CardContent } from '$lib/components/ui/card'\n  import { Input } from '$lib/components/ui/input'\n  import { Separator } from '$lib/components/ui/separator'\n\n  const lastIssue = {\n    subject: 'Why we version metric definitions instead of dashboards',\n    date: 'Feb 18, 2026',\n    readTime: '9 min',\n    opening:\n      'Dashboards are the output. The definition is the thing teams argue about, so that is what belongs under review — with a diff, an owner, and a revert path. This issue walks through what changed when we moved ours into the repo.',\n  }\n\n  let email = $state('')\n  let submitted = $state(false)\n\n  function subscribe() {\n    if (!email.trim()) return\n    submitted = true\n  }\n</script>\n\n<section data-slot=\"newsletter-split-preview\" class=\"bg-background\">\n  <div class=\"mx-auto max-w-6xl px-6 py-20 lg:py-28\">\n    <div class=\"grid items-center gap-10 lg:grid-cols-2 lg:gap-16\">\n      <div>\n        <Badge variant=\"secondary\" class=\"gap-1.5\">\n          <Mail class=\"size-3\" aria-hidden=\"true\" />\n          Monthly\n        </Badge>\n        <h2 class=\"mt-4 text-3xl font-semibold tracking-tight text-balance sm:text-4xl\">\n          Notes from the people who build it\n        </h2>\n        <p class=\"text-muted-foreground mt-3 text-lg\">\n          One email a month on metric modelling, access control, and warehouse cost. No product announcements.\n        </p>\n\n        <form\n          class=\"mt-6 max-w-md\"\n          onsubmit={(e) => {\n            e.preventDefault()\n            subscribe()\n          }}\n        >\n          <div class=\"flex gap-2\">\n            <Input\n              bind:value={email}\n              type=\"email\"\n              required\n              placeholder=\"you@company.com\"\n              autocomplete=\"email\"\n              aria-label=\"Email address\"\n            />\n            <Button type=\"submit\" class=\"shrink-0\">Subscribe</Button>\n          </div>\n          <p class=\"mt-2 min-h-5 text-xs\" aria-live=\"polite\">\n            {#if submitted}\n              <span class=\"text-success inline-flex items-center gap-1.5\">\n                <Check class=\"size-3\" aria-hidden=\"true\" />\n                Check your inbox to confirm.\n              </span>\n            {:else}\n              <span class=\"text-muted-foreground\">8,400 subscribers · unsubscribe in one click.</span>\n            {/if}\n          </p>\n        </form>\n      </div>\n\n      <!-- Showing the last issue is the point: nobody should have to subscribe\n           to find out what they are subscribing to. -->\n      <Card>\n        <CardContent class=\"p-6\">\n          <div class=\"flex flex-wrap items-center gap-3\">\n            <Badge variant=\"outline\">Last issue</Badge>\n            <span class=\"text-muted-foreground text-xs\">{lastIssue.date} · {lastIssue.readTime}</span>\n          </div>\n\n          <h3 class=\"mt-4 text-lg leading-snug font-semibold tracking-tight text-balance\">\n            {lastIssue.subject}\n          </h3>\n\n          <Separator class=\"my-4\" />\n\n          <p class=\"text-muted-foreground text-sm leading-relaxed\">{lastIssue.opening}</p>\n\n          <Button variant=\"link\" class=\"mt-4 h-auto p-0 text-sm\">Read the full issue</Button>\n        </CardContent>\n      </Card>\n    </div>\n  </div>\n</section>\n",
      "type": "registry:block",
      "target": "~/src/lib/components/blocks/newsletter/NewsletterSplitPreview.svelte"
    }
  ],
  "dependencies": [
    "@lucide/svelte"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/svelte/badge.json",
    "https://uipkge.dev/r/svelte/button.json",
    "https://uipkge.dev/r/svelte/card.json",
    "https://uipkge.dev/r/svelte/input.json",
    "https://uipkge.dev/r/svelte/separator.json"
  ],
  "description": "Newsletter growth quartet: a slim inline signup band, a filterable issue archive with featured spotlight, centered and split signup forms, and a split section pairing the pitch with a preview of the last issue.",
  "categories": [
    "marketing",
    "media",
    "app"
  ]
}