{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "footer-newsletter",
  "title": "Newsletter footer",
  "description": "Footer with a newsletter sign-up row, link columns and a live “All systems normal” status badge.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "input",
    "label",
    "https://velora.colorlib.com/r/stateful-button.json"
  ],
  "files": [
    {
      "path": "src/components/blocks/footer-newsletter.tsx",
      "content": "\"use client\";\n\nimport { useId } from \"react\";\nimport { MailIcon } from \"lucide-react\";\n\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { StatefulButton } from \"@/components/velora/stateful-button\";\n\nconst BRAND = \"Orbit\";\nconst BLURB = \"Deploy previews, feature flags and rollbacks for teams that ship every day.\";\n\nconst NEWSLETTER = {\n  title: \"Stay in orbit\",\n  description: \"One email a month with product updates and engineering notes. No spam, unsubscribe anytime.\",\n};\n\nconst COLUMNS = [\n  { title: \"Product\", links: [\"Previews\", \"Feature flags\", \"Rollbacks\", \"Pricing\", \"Changelog\"] },\n  { title: \"Developers\", links: [\"Documentation\", \"CLI\", \"API reference\", \"Status\"] },\n  { title: \"Company\", links: [\"About\", \"Blog\", \"Careers\", \"Contact\"] },\n  { title: \"Legal\", links: [\"Privacy\", \"Terms\", \"DPA\", \"Security\"] },\n];\n\nconst STATUS = \"All systems normal\";\n\n// Replace with a call to your email provider; reject to show the error state.\nfunction subscribe(email: string) {\n  void email;\n  return new Promise<void>((resolve) => setTimeout(resolve, 1200));\n}\n\nconst focusRing =\n  \"rounded-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\";\n\n/**\n * Footer with a newsletter sign-up row, a brand column carrying a live\n * status badge, and four link columns. The subscribe button morphs through\n * loading and success states while the request runs.\n */\nexport function FooterNewsletter() {\n  const emailId = useId();\n\n  return (\n    <footer className=\"border-t bg-background px-6 pt-16 pb-10 sm:pt-20 lg:px-8\">\n      <div className=\"mx-auto max-w-7xl\">\n        <div className=\"relative isolate overflow-hidden rounded-3xl border bg-card px-6 py-8 sm:px-10 sm:py-10\">\n          <div\n            aria-hidden\n            className=\"absolute inset-0 -z-10 bg-radial-[ellipse_at_100%_0%] from-brand/15 to-transparent to-60%\"\n          />\n          <div className=\"grid items-center gap-8 lg:grid-cols-2 lg:gap-16\">\n            <div className=\"flex gap-4\">\n              <span\n                aria-hidden\n                className=\"hidden size-11 shrink-0 place-items-center rounded-xl bg-primary/10 text-primary sm:grid\"\n              >\n                <MailIcon className=\"size-5\" />\n              </span>\n              <div>\n                <h2 className=\"text-xl font-semibold tracking-tight sm:text-2xl\">{NEWSLETTER.title}</h2>\n                <p className=\"mt-2 max-w-md text-sm text-pretty text-muted-foreground sm:text-base\">\n                  {NEWSLETTER.description}\n                </p>\n              </div>\n            </div>\n\n            <form onSubmit={(event) => event.preventDefault()} className=\"w-full lg:max-w-md lg:justify-self-end\">\n              <Label htmlFor={emailId} className=\"mb-2\">\n                Work email\n              </Label>\n              <div className=\"flex flex-col gap-3 sm:flex-row\">\n                <Input\n                  id={emailId}\n                  name=\"email\"\n                  type=\"email\"\n                  required\n                  autoComplete=\"email\"\n                  placeholder=\"you@company.com\"\n                  className=\"h-10 flex-1 rounded-full bg-background px-4\"\n                />\n                <StatefulButton\n                  type=\"submit\"\n                  successText=\"Subscribed\"\n                  errorText=\"Try again\"\n                  className=\"shrink-0\"\n                  onClick={(event) => {\n                    // Pressing Enter in the field also lands here, as a click.\n                    event.preventDefault();\n                    const form = event.currentTarget.form;\n                    if (!form?.reportValidity()) return;\n                    const email = new FormData(form).get(\"email\") as string;\n                    return subscribe(email).then(() => form.reset());\n                  }}\n                >\n                  Subscribe\n                </StatefulButton>\n              </div>\n            </form>\n          </div>\n        </div>\n\n        <div className=\"mt-16 grid gap-12 lg:grid-cols-[minmax(0,1fr)_minmax(0,2fr)] lg:gap-16\">\n          <div className=\"max-w-xs\">\n            <a href=\"#\" className={`inline-flex items-center gap-2.5 text-lg font-semibold tracking-tight ${focusRing}`}>\n              <svg aria-hidden viewBox=\"0 0 32 32\" fill=\"none\" strokeWidth=\"2.5\" className=\"size-8\">\n                <circle cx=\"16\" cy=\"16\" r=\"5\" className=\"fill-primary\" />\n                <ellipse cx=\"16\" cy=\"16\" rx=\"13\" ry=\"6\" transform=\"rotate(-30 16 16)\" className=\"stroke-primary/60\" />\n              </svg>\n              {BRAND}\n            </a>\n            <p className=\"mt-4 text-sm leading-relaxed text-pretty text-muted-foreground\">{BLURB}</p>\n            <a\n              href=\"#\"\n              className=\"mt-6 inline-flex items-center gap-2 rounded-full border bg-card px-3 py-1.5 text-xs font-medium transition-colors hover:bg-muted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n            >\n              <span aria-hidden className=\"relative flex size-2\">\n                <span className=\"absolute inset-0 rounded-full bg-emerald-500 opacity-75 motion-safe:animate-ping\" />\n                <span className=\"relative size-2 rounded-full bg-emerald-500\" />\n              </span>\n              {STATUS}\n            </a>\n          </div>\n\n          <nav aria-label=\"Footer\" className=\"grid grid-cols-2 gap-x-8 gap-y-10 sm:grid-cols-4\">\n            {COLUMNS.map((column) => (\n              <div key={column.title}>\n                <h3 className=\"text-sm font-semibold\">{column.title}</h3>\n                <ul className=\"mt-4 space-y-3 text-sm\">\n                  {column.links.map((label) => (\n                    <li key={label}>\n                      <a href=\"#\" className={`text-muted-foreground transition-colors hover:text-foreground ${focusRing}`}>\n                        {label}\n                      </a>\n                    </li>\n                  ))}\n                </ul>\n              </div>\n            ))}\n          </nav>\n        </div>\n\n        <p className=\"mt-16 border-t pt-8 text-sm text-muted-foreground\">\n          © 2026 {BRAND} Technologies, Inc. All rights reserved.\n        </p>\n      </div>\n    </footer>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/blocks/footer-newsletter.tsx"
    }
  ],
  "categories": [
    "footers"
  ],
  "type": "registry:block"
}