{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "template-relay",
  "title": "Relay: developer API platform",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "A paper-and-ink, terminal-flavoured site for a developer API: a live send console, the life of an event, a delivery map, language-synced docs, usage pricing and a status page.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.ballmac.com/r/accordion.json",
    "https://ui.ballmac.com/r/api-endpoint.json",
    "https://ui.ballmac.com/r/dotted-map.json",
    "https://ui.ballmac.com/r/marquee.json",
    "https://ui.ballmac.com/r/number-ticker.json",
    "https://ui.ballmac.com/r/slider.json",
    "https://ui.ballmac.com/r/snippet-tabs.json",
    "https://ui.ballmac.com/r/table-of-contents.json"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/templates/relay/relay-fonts.ts",
      "content": "// Ballmac UI: Relay template fonts. https://ui.ballmac.com/templates/template-relay\nimport { Hanken_Grotesk, IBM_Plex_Mono } from \"next/font/google\"\n\nexport const relaySans = Hanken_Grotesk({ variable: \"--relay-sans\", subsets: [\"latin\"], display: \"swap\", preload: false })\nexport const relayMono = IBM_Plex_Mono({ variable: \"--relay-mono\", subsets: [\"latin\"], weight: [\"400\", \"500\", \"600\"], display: \"swap\", preload: false })\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/relay/relay-fonts.ts"
    },
    {
      "path": "registry/ballmac/components/templates/relay/relay-theme.tsx",
      "content": "// Ballmac UI: Relay template shell. https://ui.ballmac.com/templates/template-relay\n\"use client\"\n\nimport * as React from \"react\"\nimport { ArrowUpRight, Menu, X } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { relayMono, relaySans } from \"@/components/ballmac/templates/relay/relay-fonts\"\n\ntype RelayPage = \"home\" | \"docs\" | \"pricing\" | \"status\"\ntype RelayHrefs = Record<RelayPage, string>\n\nconst defaultHrefs: RelayHrefs = { home: \"/relay\", docs: \"/relay/docs\", pricing: \"/relay/pricing\", status: \"/relay/status\" }\n\n/** Relay's palette: warm paper and black ink with a single orange signal. Dark mode inverts to ink. */\nconst relayCss = `\n.relay-theme{--background:oklch(0.975 0.008 85);--foreground:oklch(0.17 0.01 60);--card:oklch(0.99 0.006 85);--card-foreground:oklch(0.17 0.01 60);--popover:oklch(0.99 0.006 85);--popover-foreground:oklch(0.17 0.01 60);--primary:oklch(0.17 0.01 60);--primary-foreground:oklch(0.975 0.008 85);--secondary:oklch(0.94 0.012 85);--secondary-foreground:oklch(0.17 0.01 60);--muted:oklch(0.94 0.012 85);--muted-foreground:oklch(0.48 0.02 70);--accent:oklch(0.93 0.016 80);--accent-foreground:oklch(0.17 0.01 60);--border:oklch(0.17 0.01 60 / 14%);--input:oklch(0.17 0.01 60 / 20%);--ring:oklch(0.62 0.2 45);--surface:oklch(0.96 0.01 85);--destructive:oklch(0.55 0.22 27);--chart-1:oklch(0.52 0.19 42);--chart-2:oklch(0.46 0.12 160);--chart-3:oklch(0.7 0.15 85);--chart-4:oklch(0.5 0.17 265);--chart-5:oklch(0.55 0.2 330);--radius:0.375rem}\n.dark .relay-theme{--background:oklch(0.15 0.008 60);--foreground:oklch(0.95 0.01 85);--card:oklch(0.185 0.01 60);--card-foreground:oklch(0.95 0.01 85);--popover:oklch(0.2 0.01 60);--popover-foreground:oklch(0.95 0.01 85);--primary:oklch(0.95 0.01 85);--primary-foreground:oklch(0.17 0.01 60);--secondary:oklch(0.24 0.012 60);--secondary-foreground:oklch(0.95 0.01 85);--muted:oklch(0.23 0.012 60);--muted-foreground:oklch(0.72 0.02 80);--accent:oklch(0.27 0.014 60);--accent-foreground:oklch(0.95 0.01 85);--border:oklch(0.95 0.01 85 / 14%);--input:oklch(0.95 0.01 85 / 20%);--ring:oklch(0.72 0.19 50);--surface:oklch(0.17 0.009 60);--destructive:oklch(0.7 0.19 25);--chart-1:oklch(0.74 0.18 50);--chart-2:oklch(0.78 0.14 165);--chart-3:oklch(0.83 0.14 90);--chart-4:oklch(0.72 0.14 265);--chart-5:oklch(0.74 0.17 335)}\n`\n\nfunction RelayMark({ className }: { className?: string }) {\n  return (\n    <svg viewBox=\"0 0 28 28\" fill=\"none\" aria-hidden=\"true\" className={cn(\"size-6\", className)}>\n      <rect x=\"1.5\" y=\"1.5\" width=\"25\" height=\"25\" rx=\"5\" stroke=\"currentColor\" strokeWidth=\"1.8\" />\n      <path d=\"M7 14h6l3-5 3 10 3-5h2\" stroke=\"var(--chart-1)\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n    </svg>\n  )\n}\n\nconst links: { key: RelayPage; label: string }[] = [\n  { key: \"docs\", label: \"Docs\" },\n  { key: \"pricing\", label: \"Pricing\" },\n  { key: \"status\", label: \"Status\" },\n]\n\ntype RelayShellProps = React.ComponentProps<\"div\"> & {\n  /** The page being shown, so its nav link is marked current. */\n  page: RelayPage\n  /** Override where pages live (used by previews). */\n  hrefs?: Partial<RelayHrefs>\n}\n\n/** Relay's frame: paper-and-ink theme, fonts, a ruled header and footer. Wrap every Relay page in it. */\nfunction RelayShell({ page, hrefs: overrides, className, style, children, ...props }: RelayShellProps) {\n  const hrefs = { ...defaultHrefs, ...overrides }\n  const [open, setOpen] = React.useState(false)\n  return (\n    <div\n      data-slot=\"relay\"\n      className={cn(\"relay-theme bg-background text-foreground relative min-h-dvh overflow-x-clip\", relaySans.variable, relayMono.variable, className)}\n      style={{ fontFamily: \"var(--relay-sans), ui-sans-serif, system-ui, sans-serif\", ...style }}\n      {...props}\n    >\n      <style>{relayCss}</style>\n      <header className=\"bg-background/85 sticky top-0 z-40 border-b backdrop-blur-xl\">\n        <div className=\"mx-auto flex h-14 max-w-6xl items-center justify-between px-4 sm:px-6\">\n          <a href={hrefs.home} className=\"focus-visible:ring-ring/50 flex items-center gap-2.5 rounded-sm font-semibold tracking-tight outline-none focus-visible:ring-[3px]\">\n            <RelayMark /> <span style={{ fontFamily: \"var(--relay-mono)\" }}>relay</span>\n          </a>\n          <nav aria-label=\"Main\" className=\"hidden items-center gap-1 md:flex\">\n            {links.map((l) => (\n              <a\n                key={l.key}\n                href={hrefs[l.key]}\n                aria-current={page === l.key ? \"page\" : undefined}\n                className=\"text-muted-foreground hover:text-foreground aria-[current=page]:text-foreground aria-[current=page]:bg-accent focus-visible:ring-ring/50 rounded-md px-3 py-1.5 text-sm outline-none transition-colors focus-visible:ring-[3px]\"\n              >\n                {l.label}\n              </a>\n            ))}\n            <a href=\"#\" className=\"text-muted-foreground hover:text-foreground focus-visible:ring-ring/50 inline-flex items-center gap-1 rounded-md px-3 py-1.5 text-sm outline-none transition-colors focus-visible:ring-[3px]\">\n              GitHub <ArrowUpRight className=\"size-3.5 rtl:-scale-x-100\" aria-hidden=\"true\" />\n            </a>\n          </nav>\n          <div className=\"flex items-center gap-2\">\n            <a href=\"#\" className=\"text-muted-foreground hover:text-foreground hidden px-2 text-sm sm:block\">Log in</a>\n            <a href=\"#\" className=\"bg-foreground text-background focus-visible:ring-ring/50 inline-flex h-9 items-center rounded-md px-3.5 text-sm font-medium outline-none transition-opacity hover:opacity-90 focus-visible:ring-[3px]\" style={{ fontFamily: \"var(--relay-mono)\" }}>\n              Get API key\n            </a>\n            <button\n              type=\"button\"\n              aria-label={open ? \"Close menu\" : \"Open menu\"}\n              aria-expanded={open}\n              aria-controls=\"relay-mobile-menu\"\n              onClick={() => setOpen((v) => !v)}\n              className=\"text-muted-foreground hover:text-foreground focus-visible:ring-ring/50 inline-flex size-9 items-center justify-center rounded-md outline-none focus-visible:ring-[3px] md:hidden\"\n            >\n              {open ? <X className=\"size-5\" aria-hidden=\"true\" /> : <Menu className=\"size-5\" aria-hidden=\"true\" />}\n            </button>\n          </div>\n        </div>\n        {open && (\n          <nav id=\"relay-mobile-menu\" aria-label=\"Mobile\" className=\"border-t px-4 py-2 md:hidden\">\n            {links.map((l) => (\n              <a key={l.key} href={hrefs[l.key]} className=\"hover:bg-accent block rounded-md px-3 py-2.5 text-sm\">{l.label}</a>\n            ))}\n          </nav>\n        )}\n      </header>\n      {children}\n      <footer className=\"border-t\">\n        <div className=\"mx-auto grid max-w-6xl gap-10 px-4 py-14 sm:grid-cols-2 sm:px-6 lg:grid-cols-[1.4fr_repeat(3,1fr)]\">\n          <div>\n            <a href={hrefs.home} className=\"flex items-center gap-2.5 font-semibold\"><RelayMark /> <span style={{ fontFamily: \"var(--relay-mono)\" }}>relay</span></a>\n            <p className=\"text-muted-foreground mt-3 max-w-xs text-sm text-pretty\">Reliable webhook delivery for teams that can’t afford to drop an event.</p>\n          </div>\n          {[\n            { title: \"Product\", items: [[\"Delivery\", \"home\"], [\"Retries\", \"home\"], [\"Replay\", \"home\"], [\"Pricing\", \"pricing\"]] },\n            { title: \"Developers\", items: [[\"Documentation\", \"docs\"], [\"API reference\", \"docs\"], [\"SDKs\", \"docs\"], [\"Status\", \"status\"]] },\n            { title: \"Company\", items: [[\"About\", \"home\"], [\"Security\", \"home\"], [\"Careers\", \"home\"], [\"Contact\", \"home\"]] },\n          ].map((c) => (\n            <div key={c.title}>\n              <h2 className=\"text-xs font-semibold tracking-wider uppercase\" style={{ fontFamily: \"var(--relay-mono)\" }}>{c.title}</h2>\n              <ul className=\"mt-4 space-y-2.5\">\n                {c.items.map(([label, key]) => (\n                  <li key={label}><a href={hrefs[key as RelayPage]} className=\"text-muted-foreground hover:text-foreground text-sm transition-colors\">{label}</a></li>\n                ))}\n              </ul>\n            </div>\n          ))}\n        </div>\n        <div className=\"mx-auto max-w-6xl border-t px-4 py-5 sm:px-6\">\n          <p className=\"text-muted-foreground text-xs\" style={{ fontFamily: \"var(--relay-mono)\" }}>© 2026 Relay, Inc. · SOC 2 Type II · 99.99% delivery SLA</p>\n        </div>\n      </footer>\n    </div>\n  )\n}\n\nexport { RelayMark, RelayShell, defaultHrefs as relayDefaultHrefs, type RelayHrefs, type RelayPage, type RelayShellProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/relay/relay-theme.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/relay/relay-samples.ts",
      "content": "// Ballmac UI: Relay code samples. https://ui.ballmac.com/templates/template-relay\nimport type { Snippet } from \"@/components/ballmac/snippet-tabs\"\n\n/** The package the samples install. Kept in a variable so it is documentation, not a dependency of this file. */\nconst pkg = \"@relay/sdk\"\n\n/** Sending an event, in four languages. */\nexport const sendSnippets: Snippet[] = [\n  {\n    label: \"curl\",\n    language: \"bash\",\n    code: `curl https://api.relay.dev/v1/events \\\\\n  -H \"Authorization: Bearer {{key}}\" \\\\\n  -H \"Content-Type: application/json\" \\\\\n  -d '{\n    \"type\": \"invoice.paid\",\n    \"endpoint\": \"ep_billing\",\n    \"data\": { \"id\": \"inv_1042\", \"amount\": 4900 }\n  }'`,\n  },\n  {\n    label: \"TypeScript\",\n    language: \"typescript\",\n    code: `import { Relay } from ${JSON.stringify(pkg)}\n\nconst relay = new Relay(\"{{key}}\")\n\nawait relay.events.send({\n  type: \"invoice.paid\",\n  endpoint: \"ep_billing\",\n  data: { id: \"inv_1042\", amount: 4900 },\n})`,\n  },\n  {\n    label: \"Python\",\n    language: \"python\",\n    code: `from relay import Relay\n\nrelay = Relay(\"{{key}}\")\n\nrelay.events.send(\n    type=\"invoice.paid\",\n    endpoint=\"ep_billing\",\n    data={\"id\": \"inv_1042\", \"amount\": 4900},\n)`,\n  },\n  {\n    label: \"Go\",\n    language: \"go\",\n    code: `client := relay.New(\"{{key}}\")\n\n_, err := client.Events.Send(ctx, relay.Event{\n    Type:     \"invoice.paid\",\n    Endpoint: \"ep_billing\",\n    Data:     map[string]any{\"id\": \"inv_1042\", \"amount\": 4900},\n})`,\n  },\n]\n\n/** Verifying a signature, in four languages. */\nexport const verifySnippets: Snippet[] = [\n  {\n    label: \"curl\",\n    language: \"bash\",\n    code: `# Recompute the signature yourself to check a delivery\nSIGNED=\"$TIMESTAMP.$BODY\"\nprintf '%s' \"$SIGNED\" | openssl dgst -sha256 -hmac \"$RELAY_SECRET\"\n# The result must match the Relay-Signature header`,\n  },\n  {\n    label: \"TypeScript\",\n    language: \"typescript\",\n    code: `import { verify } from ${JSON.stringify(pkg)}\n\nexport async function POST(req: Request) {\n  const body = await req.text()\n  const event = verify(body, req.headers, process.env.RELAY_SECRET!)\n  // event.id is stable across retries: use it to dedupe\n  return new Response(\"ok\")\n}`,\n  },\n  {\n    label: \"Python\",\n    language: \"python\",\n    code: `from relay import verify\n\n@app.post(\"/webhooks\")\ndef webhook(request):\n    event = verify(request.body, request.headers, RELAY_SECRET)\n    # event.id is stable across retries: use it to dedupe\n    return \"ok\"`,\n  },\n  {\n    label: \"Go\",\n    language: \"go\",\n    code: `func webhook(w http.ResponseWriter, r *http.Request) {\n    body, _ := io.ReadAll(r.Body)\n    event, err := relay.Verify(body, r.Header, secret)\n    // event.ID is stable across retries: use it to dedupe\n    w.WriteHeader(http.StatusOK)\n}`,\n  },\n]\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/relay/relay-samples.ts"
    },
    {
      "path": "registry/ballmac/components/templates/relay/relay-home.tsx",
      "content": "// Ballmac UI: Relay home page. https://ui.ballmac.com/templates/template-relay\n\"use client\"\n\nimport * as React from \"react\"\nimport { ArrowRight, Check, Clock, History, KeyRound, ListRestart, Radar, ShieldCheck, Shuffle, X } from \"lucide-react\"\n\nimport { DottedMap } from \"@/components/ballmac/dotted-map\"\nimport { Marquee } from \"@/components/ballmac/marquee\"\nimport { NumberTicker } from \"@/components/ballmac/number-ticker\"\nimport { SnippetTabs } from \"@/components/ballmac/snippet-tabs\"\nimport { RelayShell, type RelayHrefs } from \"@/components/ballmac/templates/relay/relay-theme\"\nimport { sendSnippets, verifySnippets } from \"@/components/ballmac/templates/relay/relay-samples\"\nimport { cn } from \"@/lib/utils\"\n\nconst mono = { fontFamily: \"var(--relay-mono)\" } as const\nconst label = \"text-muted-foreground text-xs font-semibold tracking-wider uppercase\"\n\nconst attempts = [\n  { n: 1, t: \"0.0 s\", status: \"503\", note: \"billing.acme.co unavailable\", ok: false },\n  { n: 2, t: \"+30 s\", status: \"timeout\", note: \"No response in 10 s\", ok: false },\n  { n: 3, t: \"+5 min\", status: \"200\", note: \"Delivered in 142 ms\", ok: true },\n]\n\nconst features = [\n  { icon: ListRestart, title: \"Retries that make sense\", text: \"Exponential backoff with jitter for 3 days. Circuit breakers pause a sick endpoint instead of hammering it.\" },\n  { icon: ShieldCheck, title: \"Signed and verifiable\", text: \"Every delivery is signed with a rotating secret and a timestamp. Verifying takes five lines in any language.\" },\n  { icon: History, title: \"Replay anything\", text: \"Re-send one event or a whole day to any endpoint, including your laptop, with one click or one command.\" },\n  { icon: Shuffle, title: \"Transform in flight\", text: \"Reshape payloads, filter by field and fan out to many endpoints without changing your producer.\" },\n  { icon: Radar, title: \"See every attempt\", text: \"Request, response, headers and latency for each try, searchable for 90 days and exportable to your logs.\" },\n  { icon: KeyRound, title: \"Per-endpoint controls\", text: \"Rate limits, IP allow-lists and mTLS for each destination, so one slow consumer never slows the rest.\" },\n]\n\nconst regions = [\n  { name: \"iad1\", city: \"Virginia\", ms: 11, lat: 38.9, lng: -77.4 },\n  { name: \"sfo1\", city: \"San Francisco\", ms: 14, lat: 37.7, lng: -122.4 },\n  { name: \"gru1\", city: \"São Paulo\", ms: 23, lat: -23.5, lng: -46.6 },\n  { name: \"fra1\", city: \"Frankfurt\", ms: 9, lat: 50.1, lng: 8.7 },\n  { name: \"bom1\", city: \"Mumbai\", ms: 19, lat: 19.1, lng: 72.9 },\n  { name: \"sin1\", city: \"Singapore\", ms: 12, lat: 1.35, lng: 103.8 },\n  { name: \"syd1\", city: \"Sydney\", ms: 16, lat: -33.9, lng: 151.2 },\n]\n\nfunction Console() {\n  const [state, setState] = React.useState<\"idle\" | \"sending\" | \"done\">(\"idle\")\n  const timer = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n  React.useEffect(() => () => clearTimeout(timer.current), [])\n  function send() {\n    setState(\"sending\")\n    clearTimeout(timer.current)\n    timer.current = setTimeout(() => setState(\"done\"), 650)\n  }\n  return (\n    <div className=\"bg-card min-w-0 overflow-hidden rounded-lg border shadow-[6px_6px_0_0_var(--border)]\">\n      <SnippetTabs snippets={sendSnippets} storageKey=\"relay-language\" variables={{ key: \"rl_live_8f3k…\" }} title=\"Send an event\" bodyClassName=\"max-h-64\" />\n      <div className=\"flex items-center justify-between gap-3 border-t px-4 py-3\">\n        <p className=\"text-muted-foreground text-xs\" style={mono} aria-live=\"polite\">\n          {state === \"idle\" ? \"POST /v1/events\" : state === \"sending\" ? \"Sending…\" : \"202 Accepted · 38 ms · iad1\"}\n        </p>\n        <button\n          type=\"button\"\n          onClick={send}\n          disabled={state === \"sending\"}\n          className=\"bg-chart-1 text-background focus-visible:ring-ring/50 inline-flex h-9 items-center gap-1.5 rounded-md px-3.5 text-sm font-semibold outline-none transition-opacity hover:opacity-90 focus-visible:ring-[3px] disabled:opacity-60\"\n          style={mono}\n        >\n          {state === \"done\" ? \"Send again\" : \"Send\"} <ArrowRight className=\"size-4 rtl:rotate-180\" aria-hidden=\"true\" />\n        </button>\n      </div>\n      {state === \"done\" && (\n        <div className=\"bg-surface border-t px-4 py-4 text-xs\" style={mono}>\n          <p className=\"text-chart-2 font-semibold\">HTTP/1.1 202 Accepted</p>\n          <pre className=\"text-muted-foreground mt-2 overflow-x-auto\" tabIndex={0}>{`{\n  \"id\": \"evt_9x2k\",\n  \"status\": \"queued\",\n  \"attempts\": [],\n  \"endpoint\": \"ep_billing\"\n}`}</pre>\n        </div>\n      )}\n    </div>\n  )\n}\n\ntype RelayHomeProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<RelayHrefs> }\n\n/** The Relay home page: hero with a live console, the life of an event, features, a delivery map and code. */\nfunction RelayHome({ hrefs, ...props }: RelayHomeProps) {\n  return (\n    <RelayShell page=\"home\" hrefs={hrefs} {...props}>\n      <main>\n        <section className=\"relative border-b\">\n          <div aria-hidden=\"true\" className=\"absolute inset-0 [background-image:linear-gradient(var(--border)_1px,transparent_1px),linear-gradient(90deg,var(--border)_1px,transparent_1px)] [background-size:56px_56px] [mask-image:linear-gradient(to_bottom,black,transparent_85%)]\" />\n          <div className=\"relative mx-auto grid max-w-6xl items-center gap-14 px-4 py-16 sm:px-6 sm:py-24 lg:grid-cols-[1.05fr_1fr]\">\n            <div>\n              <p className={cn(label, \"text-chart-1 flex items-center gap-2\")} style={mono}><span className=\"bg-chart-1 size-1.5 rounded-full\" aria-hidden=\"true\" /> Webhook infrastructure</p>\n              <h1 className=\"mt-5 text-5xl leading-[0.98] font-semibold tracking-[-0.05em] text-balance sm:text-7xl\">Never lose a webhook again.</h1>\n              <p className=\"text-muted-foreground mt-6 max-w-lg text-lg text-pretty\">\n                Relay delivers your events to every customer endpoint with retries, signatures, replay and a complete audit trail. You send one request. We make sure it lands.\n              </p>\n              <div className=\"mt-9 flex flex-wrap items-center gap-3\">\n                <a href=\"#\" className=\"bg-foreground text-background focus-visible:ring-ring/50 inline-flex h-12 items-center gap-2 rounded-md px-5 font-medium outline-none transition-opacity hover:opacity-90 focus-visible:ring-[3px]\" style={mono}>\n                  Get your API key <ArrowRight className=\"size-4 rtl:rotate-180\" aria-hidden=\"true\" />\n                </a>\n                <a href={hrefs?.docs ?? \"/relay/docs\"} className=\"hover:bg-accent focus-visible:ring-ring/50 inline-flex h-12 items-center rounded-md border px-5 font-medium outline-none transition-colors focus-visible:ring-[3px]\" style={mono}>\n                  Read the docs\n                </a>\n              </div>\n              <p className=\"text-muted-foreground mt-6 text-sm\">Free up to 100,000 events a month. No card needed.</p>\n            </div>\n            <Console />\n          </div>\n        </section>\n\n        <section aria-label=\"Customers\" className=\"border-b\">\n          <div className=\"mx-auto max-w-6xl px-4 py-9 sm:px-6\">\n            <Marquee speed={28} gap={64} fade pauseOnHover>\n              {[\"Stripeline\", \"Northbeam\", \"Cashew\", \"Lumen\", \"Paddock\", \"Vantage\", \"Ironclad Co\", \"Helix\"].map((c) => (\n                <span key={c} className=\"text-muted-foreground text-lg font-semibold tracking-tight\" style={mono}>{c}</span>\n              ))}\n            </Marquee>\n          </div>\n        </section>\n\n        {/* Life of an event */}\n        <section className=\"border-b\">\n          <div className=\"mx-auto grid max-w-6xl gap-12 px-4 py-20 sm:px-6 lg:grid-cols-[1fr_1.1fr]\">\n            <div>\n              <p className={label} style={mono}>The life of an event</p>\n              <h2 className=\"mt-4 text-3xl font-semibold tracking-[-0.04em] text-balance sm:text-5xl\">Your customer’s server was down. Your event still arrived.</h2>\n              <p className=\"text-muted-foreground mt-5 max-w-md text-pretty sm:text-lg\">\n                Endpoints fail all the time. Relay keeps trying on a schedule that respects the receiver, then tells you exactly what happened.\n              </p>\n            </div>\n            <ol className=\"bg-card rounded-lg border\" aria-label=\"Delivery attempts for evt_9x2k\">\n              <li className=\"flex items-center justify-between gap-4 border-b px-5 py-4 text-sm\" style={mono}>\n                <span>evt_9x2k · invoice.paid</span>\n                <span className=\"text-muted-foreground\">received 09:41:02</span>\n              </li>\n              {attempts.map((a) => (\n                <li key={a.n} className=\"flex items-start gap-4 border-b px-5 py-4 last:border-b-0\">\n                  <span className={cn(\"mt-0.5 flex size-6 shrink-0 items-center justify-center rounded-full border\", a.ok ? \"border-chart-2 text-chart-2\" : \"border-destructive/50 text-destructive\")}>\n                    {a.ok ? <Check className=\"size-3.5\" aria-hidden=\"true\" /> : <X className=\"size-3.5\" aria-hidden=\"true\" />}\n                    <span className=\"sr-only\">{a.ok ? \"Delivered\" : \"Failed\"}</span>\n                  </span>\n                  <div className=\"min-w-0 flex-1\">\n                    <p className=\"text-sm font-medium\">Attempt {a.n} <span className=\"text-muted-foreground font-normal\">· {a.status}</span></p>\n                    <p className=\"text-muted-foreground mt-0.5 text-sm\">{a.note}</p>\n                  </div>\n                  <span className=\"text-muted-foreground flex shrink-0 items-center gap-1.5 text-xs\" style={mono}><Clock className=\"size-3\" aria-hidden=\"true\" />{a.t}</span>\n                </li>\n              ))}\n            </ol>\n          </div>\n        </section>\n\n        {/* Features in a ruled grid */}\n        <section className=\"border-b\">\n          <div className=\"mx-auto max-w-6xl px-4 py-20 sm:px-6\">\n            <p className={label} style={mono}>What you get</p>\n            <h2 className=\"mt-4 max-w-2xl text-3xl font-semibold tracking-[-0.04em] text-balance sm:text-5xl\">Everything between “send” and “received”.</h2>\n            <ul className=\"mt-12 grid overflow-hidden rounded-lg border sm:grid-cols-2 lg:grid-cols-3\">\n              {features.map((f, i) => (\n                <li key={f.title} className={cn(\"bg-card p-7\", \"border-b sm:[&:nth-child(odd)]:border-e lg:[&:nth-child(odd)]:border-e-0 lg:[&:not(:nth-child(3n))]:border-e\", i >= 4 && \"sm:border-b-0\", i >= 3 && \"lg:border-b-0\", i < 3 && \"lg:border-b\")}>\n                  <f.icon className=\"text-chart-1 size-6\" aria-hidden=\"true\" />\n                  <h3 className=\"mt-6 font-semibold\">{f.title}</h3>\n                  <p className=\"text-muted-foreground mt-2 text-sm text-pretty\">{f.text}</p>\n                </li>\n              ))}\n            </ul>\n          </div>\n        </section>\n\n        {/* Map */}\n        <section className=\"border-b\">\n          <div className=\"mx-auto grid max-w-6xl items-center gap-12 px-4 py-20 sm:px-6 lg:grid-cols-[1.2fr_1fr]\">\n            <div className=\"order-2 lg:order-1\">\n              <DottedMap\n                tone=\"foreground\"\n                dots={120}\n                latRange={[-50, 70]}\n                label=\"Relay delivery regions\"\n                markers={regions.map((r) => ({ lat: r.lat, lng: r.lng, label: r.city, tone: \"primary\" as const }))}\n                arcs={[\n                  { from: [38.9, -77.4], to: [50.1, 8.7], tone: \"primary\" },\n                  { from: [37.7, -122.4], to: [38.9, -77.4], tone: \"primary\" },\n                  { from: [50.1, 8.7], to: [19.1, 72.9], tone: \"primary\" },\n                  { from: [1.35, 103.8], to: [-33.9, 151.2], tone: \"primary\" },\n                ]}\n                className=\"text-muted-foreground/70\"\n              />\n            </div>\n            <div className=\"order-1 lg:order-2\">\n              <p className={label} style={mono}>Global delivery</p>\n              <h2 className=\"mt-4 text-3xl font-semibold tracking-[-0.04em] text-balance sm:text-4xl\">Seven regions. Closest one wins.</h2>\n              <dl className=\"mt-8 divide-y rounded-lg border\" style={mono}>\n                {regions.map((r) => (\n                  <div key={r.name} className=\"flex items-center justify-between px-4 py-2.5 text-sm\">\n                    <dt>{r.name} <span className=\"text-muted-foreground\">· {r.city}</span></dt>\n                    <dd className=\"text-chart-2 tabular-nums\">{r.ms} ms</dd>\n                  </div>\n                ))}\n              </dl>\n            </div>\n          </div>\n        </section>\n\n        {/* Verify */}\n        <section className=\"border-b\">\n          <div className=\"mx-auto grid max-w-6xl items-center gap-12 px-4 py-20 sm:px-6 lg:grid-cols-2\">\n            <div>\n              <p className={label} style={mono}>Receiving</p>\n              <h2 className=\"mt-4 text-3xl font-semibold tracking-[-0.04em] text-balance sm:text-4xl\">Verify in five lines. Dedupe for free.</h2>\n              <p className=\"text-muted-foreground mt-5 max-w-md text-pretty sm:text-lg\">Choose a language once. Every sample in these docs follows you.</p>\n            </div>\n            <div className=\"min-w-0\"><SnippetTabs snippets={verifySnippets} storageKey=\"relay-language\" title=\"Receive an event\" bodyClassName=\"max-h-64\" /></div>\n          </div>\n        </section>\n\n        {/* Stats */}\n        <section aria-label=\"Relay in numbers\" className=\"border-b\">\n          <dl className=\"mx-auto grid max-w-6xl divide-y sm:grid-cols-2 sm:divide-y-0 lg:grid-cols-4 lg:divide-x\">\n            {[\n              { v: 12.8, s: \"B\", l: \"Events delivered each month\", d: 1 },\n              { v: 99.99, s: \"%\", l: \"Delivery success within 3 days\", d: 2 },\n              { v: 38, s: \" ms\", l: \"Median time to first attempt\", d: 0 },\n              { v: 90, s: \" days\", l: \"Searchable attempt history\", d: 0 },\n            ].map((x) => (\n              <div key={x.l} className=\"px-6 py-10\">\n                <dd className=\"text-4xl font-semibold tracking-[-0.04em] tabular-nums\" style={mono}><NumberTicker value={x.v} format={{ minimumFractionDigits: x.d, maximumFractionDigits: x.d }} />{x.s}</dd>\n                <dt className=\"text-muted-foreground mt-2 text-sm\">{x.l}</dt>\n              </div>\n            ))}\n          </dl>\n        </section>\n\n        <section className=\"px-4 py-20 sm:px-6\">\n          <div className=\"bg-foreground text-background mx-auto max-w-6xl rounded-lg px-6 py-16 text-center sm:py-20\">\n            <h2 className=\"mx-auto max-w-2xl text-3xl font-semibold tracking-[-0.045em] text-balance sm:text-5xl\">Send your first event in two minutes.</h2>\n            <p className=\"mx-auto mt-4 max-w-md text-pretty opacity-70\">One API key, one request. The free plan includes 100,000 events a month.</p>\n            <a href=\"#\" className=\"bg-chart-1 text-background focus-visible:ring-ring mt-8 inline-flex h-12 items-center gap-2 rounded-md px-6 font-semibold outline-none transition-opacity hover:opacity-90 focus-visible:ring-[3px]\" style={mono}>\n              Get your API key <ArrowRight className=\"size-4 rtl:rotate-180\" aria-hidden=\"true\" />\n            </a>\n          </div>\n        </section>\n      </main>\n    </RelayShell>\n  )\n}\n\nexport { RelayHome, type RelayHomeProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/relay/relay-home.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/relay/relay-docs.tsx",
      "content": "// Ballmac UI: Relay docs page. https://ui.ballmac.com/templates/template-relay\n\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronRight } from \"lucide-react\"\n\nimport { ApiEndpoint } from \"@/components/ballmac/api-endpoint\"\nimport { SnippetTabs } from \"@/components/ballmac/snippet-tabs\"\nimport { TableOfContents } from \"@/components/ballmac/table-of-contents\"\nimport { RelayShell, type RelayHrefs } from \"@/components/ballmac/templates/relay/relay-theme\"\nimport { sendSnippets, verifySnippets } from \"@/components/ballmac/templates/relay/relay-samples\"\nimport { cn } from \"@/lib/utils\"\n\nconst mono = { fontFamily: \"var(--relay-mono)\" } as const\n\nconst nav = [\n  { title: \"Get started\", items: [\"Introduction\", \"Quickstart\", \"Authentication\"] },\n  { title: \"Concepts\", items: [\"Events and endpoints\", \"Retries and backoff\", \"Signatures\", \"Replay\"] },\n  { title: \"API reference\", items: [\"Send an event\", \"List attempts\", \"Replay an event\"] },\n  { title: \"Guides\", items: [\"Verify in Next.js\", \"Test locally\", \"Go to production\"] },\n]\n\nconst h2 = \"scroll-mt-24 text-2xl font-semibold tracking-[-0.03em]\"\n\ntype RelayDocsProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<RelayHrefs> }\n\n/** Relay docs: sidebar, a quickstart with language-synced samples, API reference and an on-page contents list. */\nfunction RelayDocs({ hrefs, ...props }: RelayDocsProps) {\n  return (\n    <RelayShell page=\"docs\" hrefs={hrefs} {...props}>\n      <div className=\"mx-auto grid max-w-6xl gap-10 px-4 sm:px-6 lg:grid-cols-[14rem_minmax(0,1fr)] xl:grid-cols-[14rem_minmax(0,1fr)_13rem]\">\n        <aside className=\"hidden lg:block\">\n          <nav aria-label=\"Documentation\" className=\"sticky top-14 max-h-[calc(100dvh-3.5rem)] space-y-6 overflow-y-auto py-10 pe-2\">\n            {nav.map((g) => (\n              <div key={g.title}>\n                <h2 className=\"text-xs font-semibold tracking-wider uppercase\" style={mono}>{g.title}</h2>\n                <ul className=\"mt-2.5 space-y-0.5\">\n                  {g.items.map((i) => (\n                    <li key={i}>\n                      <a\n                        href=\"#\"\n                        aria-current={i === \"Quickstart\" ? \"page\" : undefined}\n                        className=\"text-muted-foreground hover:text-foreground aria-[current=page]:bg-accent aria-[current=page]:text-foreground block rounded-md px-2.5 py-1.5 text-sm transition-colors\"\n                      >\n                        {i}\n                      </a>\n                    </li>\n                  ))}\n                </ul>\n              </div>\n            ))}\n          </nav>\n        </aside>\n\n        <main className=\"min-w-0 py-10 lg:py-12\">\n          <nav aria-label=\"Breadcrumb\" className=\"text-muted-foreground flex items-center gap-1 text-sm\">\n            Get started <ChevronRight className=\"size-3.5 rtl:rotate-180\" aria-hidden=\"true\" /> <span className=\"text-foreground\">Quickstart</span>\n          </nav>\n          <h1 className=\"mt-5 text-4xl font-semibold tracking-[-0.045em] text-balance sm:text-5xl\">Quickstart</h1>\n          <p className=\"text-muted-foreground mt-4 max-w-2xl text-lg text-pretty\">Send your first event and watch it arrive. This takes about two minutes.</p>\n\n          <div className=\"prose-none mt-12 space-y-14\">\n            <section>\n              <h2 id=\"get-a-key\" className={h2}>1. Get an API key</h2>\n              <p className=\"text-muted-foreground mt-3 max-w-2xl text-pretty\">\n                Create a key in the dashboard under <span className=\"bg-muted rounded px-1.5 py-0.5 text-[0.85em]\" style={mono}>Settings → API keys</span>. Keys starting with <span className=\"bg-muted rounded px-1.5 py-0.5 text-[0.85em]\" style={mono}>rl_test_</span> never reach real endpoints.\n              </p>\n            </section>\n\n            <section>\n              <h2 id=\"send-an-event\" className={h2}>2. Send an event</h2>\n              <p className=\"text-muted-foreground mt-3 mb-5 max-w-2xl text-pretty\">Pick your language. Your choice is remembered across every sample in the docs.</p>\n              <SnippetTabs snippets={sendSnippets} storageKey=\"relay-language\" variables={{ key: \"rl_test_8f3k…\" }} lineNumbers />\n            </section>\n\n            <section>\n              <h2 id=\"receive-it\" className={h2}>3. Receive it</h2>\n              <p className=\"text-muted-foreground mt-3 mb-5 max-w-2xl text-pretty\">Verify the signature, then return a 2xx. Anything else is retried.</p>\n              <SnippetTabs snippets={verifySnippets} storageKey=\"relay-language\" lineNumbers />\n              <div className=\"bg-chart-1/10 border-chart-1/30 mt-6 rounded-lg border p-4 text-sm text-pretty\">\n                <p className=\"font-semibold\">Dedupe on event.id</p>\n                <p className=\"text-muted-foreground mt-1\">Relay delivers at least once. The id is stable across retries and replays, so store it and skip repeats.</p>\n              </div>\n            </section>\n\n            <section>\n              <h2 id=\"api-reference\" className={h2}>API reference</h2>\n              <div className=\"mt-6 space-y-4\">\n                <ApiEndpoint\n                  method=\"POST\"\n                  path=\"/v1/events\"\n                  summary=\"Send an event\"\n                  description=\"Queues an event for delivery to one endpoint, or every endpoint subscribed to its type.\"\n                  baseUrl=\"https://api.relay.dev\"\n                  auth=\"Bearer token\"\n                  defaultOpen\n                  parameters={[\n                    { name: \"type\", in: \"body\", type: \"string\", required: true, description: \"Event type, such as invoice.paid.\" },\n                    { name: \"endpoint\", in: \"body\", type: \"string\", description: \"Send to one endpoint. Omit to fan out by subscription.\" },\n                    { name: \"data\", in: \"body\", type: \"object\", required: true, description: \"The payload your customer receives.\" },\n                    { name: \"Idempotency-Key\", in: \"header\", type: \"string\", description: \"Makes retries of this request safe for 24 hours.\" },\n                  ]}\n                  requestExample={`{\n  \"type\": \"invoice.paid\",\n  \"endpoint\": \"ep_billing\",\n  \"data\": { \"id\": \"inv_1042\", \"amount\": 4900 }\n}`}\n                  requestLanguage=\"json\"\n                  responses={[\n                    { status: 202, description: \"Event queued\", example: `{ \"id\": \"evt_9x2k\", \"status\": \"queued\" }`, language: \"json\" },\n                    { status: 422, description: \"Invalid payload\", example: `{ \"error\": \"data is required\" }`, language: \"json\" },\n                  ]}\n                />\n                <ApiEndpoint\n                  method=\"GET\"\n                  path=\"/v1/events/{id}/attempts\"\n                  summary=\"List attempts\"\n                  description=\"Every delivery attempt for an event, newest first, with status codes and latency.\"\n                  baseUrl=\"https://api.relay.dev\"\n                  auth=\"Bearer token\"\n                  parameters={[{ name: \"id\", in: \"path\", type: \"string\", required: true, description: \"The event id.\" }]}\n                  responses={[{ status: 200, description: \"Attempts\", example: `{ \"data\": [{ \"n\": 3, \"status\": 200, \"ms\": 142 }] }`, language: \"json\" }]}\n                />\n              </div>\n            </section>\n          </div>\n        </main>\n\n        <aside className=\"hidden xl:block\">\n          <div className={cn(\"sticky top-14 py-12\")}>\n            <TableOfContents\n              title=\"On this page\"\n              offset={80}\n              items={[\n                { id: \"get-a-key\", title: \"1. Get an API key\" },\n                { id: \"send-an-event\", title: \"2. Send an event\" },\n                { id: \"receive-it\", title: \"3. Receive it\" },\n                { id: \"api-reference\", title: \"API reference\" },\n              ]}\n            />\n          </div>\n        </aside>\n      </div>\n    </RelayShell>\n  )\n}\n\nexport { RelayDocs, type RelayDocsProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/relay/relay-docs.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/relay/relay-pricing.tsx",
      "content": "// Ballmac UI: Relay pricing page. https://ui.ballmac.com/templates/template-relay\n\"use client\"\n\nimport * as React from \"react\"\nimport { Check, Minus } from \"lucide-react\"\n\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from \"@/components/ballmac/accordion\"\nimport { Slider } from \"@/components/ballmac/slider\"\nimport { RelayShell, type RelayHrefs } from \"@/components/ballmac/templates/relay/relay-theme\"\nimport { cn } from \"@/lib/utils\"\n\nconst mono = { fontFamily: \"var(--relay-mono)\" } as const\nconst money = new Intl.NumberFormat(\"en-US\", { style: \"currency\", currency: \"USD\", maximumFractionDigits: 0 })\nconst moneyExact = new Intl.NumberFormat(\"en-US\", { style: \"currency\", currency: \"USD\", minimumFractionDigits: 2 })\nconst count = new Intl.NumberFormat(\"en-US\")\n\nconst plans = [\n  { name: \"Free\", price: \"$0\", per: \"forever\", events: \"100,000 events / mo\", cta: \"Start free\", features: [\"3 endpoints\", \"Retries for 24 hours\", \"7-day attempt history\", \"Community support\"] },\n  { name: \"Pro\", price: \"$49\", per: \"per month\", events: \"1M events / mo\", cta: \"Start Pro\", featured: true, features: [\"Unlimited endpoints\", \"Retries for 3 days\", \"90-day attempt history\", \"Replay and transformations\", \"Email support\"] },\n  { name: \"Scale\", price: \"Custom\", per: \"annual\", events: \"Billions of events\", cta: \"Contact sales\", features: [\"Dedicated delivery pool\", \"mTLS and IP allow-lists\", \"1-year retention\", \"99.99% SLA\", \"Shared Slack channel\"] },\n]\n\nconst rows: { feature: string; free: boolean | string; pro: boolean | string; scale: boolean | string }[] = [\n  { feature: \"Endpoints\", free: \"3\", pro: \"Unlimited\", scale: \"Unlimited\" },\n  { feature: \"Retry window\", free: \"24 hours\", pro: \"3 days\", scale: \"7 days\" },\n  { feature: \"Attempt history\", free: \"7 days\", pro: \"90 days\", scale: \"1 year\" },\n  { feature: \"Replay\", free: false, pro: true, scale: true },\n  { feature: \"Transformations\", free: false, pro: true, scale: true },\n  { feature: \"Per-endpoint rate limits\", free: false, pro: true, scale: true },\n  { feature: \"mTLS and IP allow-lists\", free: false, pro: false, scale: true },\n  { feature: \"Uptime SLA\", free: false, pro: \"99.9%\", scale: \"99.99%\" },\n]\n\nconst faqs = [\n  { q: \"What is an event?\", a: \"One message you send to Relay, no matter how many endpoints it fans out to or how many retries it needs. Replays count as new events.\" },\n  { q: \"What happens above my plan’s events?\", a: \"You pay the rate shown in the calculator. Nothing is throttled, and you can set a hard cap that pauses sending instead.\" },\n  { q: \"Can I try Pro before paying?\", a: \"Every account starts with a 14-day Pro trial, no card required. You fall back to Free afterwards.\" },\n]\n\nfunction Cell({ v }: { v: boolean | string }) {\n  if (typeof v === \"string\") return <span className=\"text-sm\">{v}</span>\n  return v ? <Check className=\"text-chart-2 mx-auto size-4\" aria-label=\"Included\" role=\"img\" /> : <Minus className=\"text-muted-foreground mx-auto size-4\" aria-label=\"Not included\" role=\"img\" />\n}\n\ntype RelayPricingProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<RelayHrefs> }\n\n/** Relay pricing: plans, a per-volume estimator with a stepped rate, a comparison table and questions. */\nfunction RelayPricing({ hrefs, ...props }: RelayPricingProps) {\n  const [events, setEvents] = React.useState(3_000_000)\n  const included = 1_000_000\n  const extra = Math.max(0, events - included)\n  const t1 = Math.min(extra, 4_000_000)\n  const t2 = Math.max(0, extra - 4_000_000)\n  const overage = (t1 / 1_000_000) * 8 + (t2 / 1_000_000) * 5\n  const total = 49 + overage\n  return (\n    <RelayShell page=\"pricing\" hrefs={hrefs} {...props}>\n      <main>\n        <section className=\"border-b\">\n          <div className=\"mx-auto max-w-6xl px-4 py-16 sm:px-6 sm:py-24\">\n            <p className=\"text-chart-1 text-xs font-semibold tracking-wider uppercase\" style={mono}>Pricing</p>\n            <h1 className=\"mt-4 max-w-3xl text-4xl font-semibold tracking-[-0.05em] text-balance sm:text-6xl\">Priced per event. Cheaper as you grow.</h1>\n            <p className=\"text-muted-foreground mt-5 max-w-xl text-lg text-pretty\">No seats, no endpoint fees, no surprise tiers. Every plan gets the full delivery engine.</p>\n            <div className=\"mt-12 grid overflow-hidden rounded-lg border lg:grid-cols-3\">\n              {plans.map((p) => (\n                <article key={p.name} className={cn(\"bg-card flex flex-col border-b p-7 last:border-b-0 lg:border-e lg:border-b-0 lg:last:border-e-0\", p.featured && \"bg-surface\")}>\n                  <div className=\"flex items-center justify-between\">\n                    <h2 className=\"text-lg font-semibold\" style={mono}>{p.name}</h2>\n                    {p.featured && <span className=\"bg-chart-1 text-background rounded-sm px-2 py-0.5 text-[11px] font-semibold\" style={mono}>POPULAR</span>}\n                  </div>\n                  <p className=\"mt-6 flex items-baseline gap-2\"><span className=\"text-5xl font-semibold tracking-[-0.05em]\">{p.price}</span><span className=\"text-muted-foreground text-sm\">{p.per}</span></p>\n                  <p className=\"text-muted-foreground mt-2 text-sm\" style={mono}>{p.events}</p>\n                  <a href=\"#\" className={cn(\"focus-visible:ring-ring/50 mt-6 inline-flex h-11 items-center justify-center rounded-md text-sm font-semibold outline-none transition-colors focus-visible:ring-[3px]\", p.featured ? \"bg-foreground text-background hover:opacity-90\" : \"hover:bg-accent border\")} style={mono}>{p.cta}</a>\n                  <ul className=\"mt-7 space-y-3 text-sm\">\n                    {p.features.map((f) => <li key={f} className=\"flex items-start gap-2.5\"><Check className=\"text-chart-2 mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />{f}</li>)}\n                  </ul>\n                </article>\n              ))}\n            </div>\n          </div>\n        </section>\n\n        <section className=\"border-b\" aria-labelledby=\"relay-estimator\">\n          <div className=\"mx-auto grid max-w-6xl gap-10 px-4 py-16 sm:px-6 lg:grid-cols-[1.2fr_1fr] lg:gap-16\">\n            <div>\n              <h2 id=\"relay-estimator\" className=\"text-2xl font-semibold tracking-[-0.03em]\">Estimate your Pro bill</h2>\n              <p className=\"text-muted-foreground mt-2 text-sm text-pretty\">$49 includes 1M events. Then $8 per million up to 5M, and $5 per million beyond.</p>\n              <div className=\"mt-10\">\n                <div className=\"flex items-baseline justify-between\"><label id=\"relay-events\" className=\"text-muted-foreground text-sm\">Events per month</label><output className=\"text-xl font-medium tabular-nums\" style={mono} aria-live=\"polite\">{count.format(events)}</output></div>\n                <Slider className=\"mt-5\" aria-labelledby=\"relay-events\" min={500_000} max={50_000_000} step={500_000} value={[events]} onValueChange={(v) => setEvents(v[0] ?? events)} formatValue={(v) => `${count.format(v)} events`} />\n                <div className=\"text-muted-foreground mt-2 flex justify-between text-xs\" style={mono}><span>500k</span><span>50M</span></div>\n              </div>\n            </div>\n            <div className=\"bg-card space-y-3 rounded-lg border p-5 text-sm\" style={mono}>\n              <dl className=\"space-y-3\">\n                <div className=\"flex justify-between\"><dt className=\"text-muted-foreground\">Pro base</dt><dd>$49.00</dd></div>\n                <div className=\"flex justify-between\"><dt className=\"text-muted-foreground\">{count.format(extra)} extra events</dt><dd className=\"tabular-nums\">{moneyExact.format(overage)}</dd></div>\n                <div className=\"flex items-baseline justify-between border-t pt-4\"><dt className=\"font-semibold\">Per month</dt><dd className=\"text-3xl font-semibold tabular-nums\">{money.format(total)}</dd></div>\n              </dl>\n              <p className=\"text-muted-foreground text-xs\" style={{ fontFamily: \"var(--relay-sans)\" }}>Effective rate: {moneyExact.format(total / (events / 1_000_000))} per million events.</p>\n            </div>\n          </div>\n        </section>\n\n        <section className=\"border-b\">\n          <div className=\"mx-auto max-w-6xl px-4 py-16 sm:px-6\"><div tabIndex={0} role=\"region\" aria-label=\"Plan comparison\" className=\"focus-visible:ring-ring/50 overflow-x-auto rounded-md outline-none focus-visible:ring-[3px]\">\n            <table className=\"w-full min-w-[34rem] text-start\">\n              <caption className=\"sr-only\">Plan comparison</caption>\n              <thead>\n                <tr className=\"border-b text-xs tracking-wider uppercase\" style={mono}>\n                  <th scope=\"col\" className=\"py-3 pe-4 font-semibold\">Feature</th>\n                  {plans.map((p) => <th key={p.name} scope=\"col\" className=\"px-4 py-3 text-center font-semibold\">{p.name}</th>)}\n                </tr>\n              </thead>\n              <tbody>\n                {rows.map((r) => (\n                  <tr key={r.feature} className=\"border-b\">\n                    <th scope=\"row\" className=\"py-3.5 pe-4 text-sm font-normal\">{r.feature}</th>\n                    <td className=\"px-4 py-3.5 text-center\"><Cell v={r.free} /></td>\n                    <td className=\"bg-surface px-4 py-3.5 text-center\"><Cell v={r.pro} /></td>\n                    <td className=\"px-4 py-3.5 text-center\"><Cell v={r.scale} /></td>\n                  </tr>\n                ))}\n              </tbody>\n            </table>\n          </div></div>\n        </section>\n\n        <section className=\"mx-auto max-w-3xl px-4 py-16 sm:px-6\" aria-labelledby=\"relay-faq\">\n          <h2 id=\"relay-faq\" className=\"text-2xl font-semibold tracking-[-0.03em]\">Questions</h2>\n          <Accordion type=\"single\" collapsible className=\"mt-5\">\n            {faqs.map((f) => (\n              <AccordionItem key={f.q} value={f.q}><AccordionTrigger>{f.q}</AccordionTrigger><AccordionContent className=\"text-muted-foreground text-pretty\">{f.a}</AccordionContent></AccordionItem>\n            ))}\n          </Accordion>\n        </section>\n      </main>\n    </RelayShell>\n  )\n}\n\nexport { RelayPricing, type RelayPricingProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/relay/relay-pricing.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/relay/relay-status.tsx",
      "content": "// Ballmac UI: Relay status page. https://ui.ballmac.com/templates/template-relay\nimport * as React from \"react\"\nimport { CheckCircle2 } from \"lucide-react\"\n\nimport { RelayShell, type RelayHrefs } from \"@/components/ballmac/templates/relay/relay-theme\"\nimport { cn } from \"@/lib/utils\"\n\nconst mono = { fontFamily: \"var(--relay-mono)\" } as const\n\ntype Day = \"up\" | \"degraded\" | \"down\"\n\n/** Ninety days of history. Fixed, so the server and browser draw the same bars. */\nfunction history(seed: number, degraded: number[], down: number[]): Day[] {\n  return Array.from({ length: 90 }, (_, i) => (down.includes(i + seed) ? \"down\" : degraded.includes(i + seed) ? \"degraded\" : \"up\"))\n}\n\nconst components: { name: string; uptime: string; days: Day[] }[] = [\n  { name: \"Event ingestion API\", uptime: \"99.998%\", days: history(0, [41], []) },\n  { name: \"Delivery workers\", uptime: \"99.991%\", days: history(0, [12, 57], [58]) },\n  { name: \"Dashboard\", uptime: \"99.987%\", days: history(0, [23, 24, 71], []) },\n  { name: \"Replay and search\", uptime: \"99.996%\", days: history(0, [66], []) },\n  { name: \"Webhooks to customers (global)\", uptime: \"99.994%\", days: history(0, [57, 58], []) },\n]\n\nconst incidents = [\n  { date: \"Sep 24, 2026\", title: \"Delayed deliveries in eu-central\", status: \"Resolved\", body: \"A partial network failure in Frankfurt slowed deliveries by up to 4 minutes. Events were queued and delivered in order; nothing was lost.\", duration: \"37 minutes\" },\n  { date: \"Aug 15, 2026\", title: \"Dashboard search timeouts\", status: \"Resolved\", body: \"Searches over 30 days of history timed out for 11 minutes after an index rebuild. Ingestion and delivery were unaffected.\", duration: \"11 minutes\" },\n  { date: \"Jul 29, 2026\", title: \"Elevated 5xx on the ingestion API\", status: \"Resolved\", body: \"A bad deploy returned errors for 0.4 percent of requests. We rolled back in 6 minutes. Clients using idempotency keys retried safely.\", duration: \"6 minutes\" },\n]\n\nconst tone: Record<Day, string> = { up: \"bg-chart-2\", degraded: \"bg-chart-3\", down: \"bg-destructive\" }\nconst word: Record<Day, string> = { up: \"operational\", degraded: \"degraded\", down: \"outage\" }\n\ntype RelayStatusProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<RelayHrefs> }\n\n/** Relay status: an overall banner, 90-day uptime bars per component and recent incidents. */\nfunction RelayStatus({ hrefs, ...props }: RelayStatusProps) {\n  return (\n    <RelayShell page=\"status\" hrefs={hrefs} {...props}>\n      <main className=\"mx-auto max-w-4xl px-4 py-14 sm:px-6 sm:py-20\">\n        <p className=\"text-chart-1 text-xs font-semibold tracking-wider uppercase\" style={mono}>System status</p>\n        <h1 className=\"mt-4 text-4xl font-semibold tracking-[-0.05em] text-balance sm:text-5xl\">Status</h1>\n        <div role=\"status\" className=\"border-chart-2/40 bg-chart-2/10 mt-8 flex items-center gap-3 rounded-lg border px-5 py-4\">\n          <CheckCircle2 className=\"text-chart-2 size-6 shrink-0\" aria-hidden=\"true\" />\n          <div>\n            <p className=\"font-semibold\">All systems operational</p>\n            <p className=\"text-muted-foreground text-sm\">Updated 09:41 UTC · Median delivery latency 38 ms</p>\n          </div>\n        </div>\n\n        <section aria-labelledby=\"relay-uptime\" className=\"mt-12\">\n          <h2 id=\"relay-uptime\" className=\"text-xl font-semibold tracking-[-0.02em]\">Uptime, last 90 days</h2>\n          <ul className=\"mt-5 space-y-3\">\n            {components.map((c) => (\n              <li key={c.name} className=\"bg-card rounded-lg border p-5\">\n                <div className=\"flex items-baseline justify-between gap-3\">\n                  <h3 className=\"font-medium\">{c.name}</h3>\n                  <span className=\"text-chart-2 text-sm tabular-nums\" style={mono}>{c.uptime}</span>\n                </div>\n                <div className=\"mt-4 flex h-8 gap-px\" role=\"img\" aria-label={`${c.name}: ${c.days.filter((d) => d === \"up\").length} of 90 days operational, ${c.days.filter((d) => d === \"degraded\").length} degraded, ${c.days.filter((d) => d === \"down\").length} outage`}>\n                  {c.days.map((d, i) => <span key={i} className={cn(\"min-w-0 flex-1 rounded-[1px]\", tone[d])} title={`${90 - i} days ago: ${word[d]}`} />)}\n                </div>\n                <div className=\"text-muted-foreground mt-2 flex justify-between text-xs\" style={mono}><span>90 days ago</span><span>Today</span></div>\n              </li>\n            ))}\n          </ul>\n          <ul className=\"text-muted-foreground mt-4 flex flex-wrap gap-x-5 gap-y-1 text-xs\">\n            {([\"up\", \"degraded\", \"down\"] as Day[]).map((d) => <li key={d} className=\"flex items-center gap-1.5\"><span className={cn(\"size-2.5 rounded-[2px]\", tone[d])} aria-hidden=\"true\" />{word[d][0].toUpperCase() + word[d].slice(1)}</li>)}\n          </ul>\n        </section>\n\n        <section aria-labelledby=\"relay-incidents\" className=\"mt-14\">\n          <h2 id=\"relay-incidents\" className=\"text-xl font-semibold tracking-[-0.02em]\">Past incidents</h2>\n          <ol className=\"mt-5 space-y-6\">\n            {incidents.map((i) => (\n              <li key={i.title} className=\"border-s-2 ps-5\">\n                <p className=\"text-muted-foreground text-xs\" style={mono}>{i.date} · {i.duration}</p>\n                <h3 className=\"mt-1 font-semibold\">{i.title} <span className=\"bg-chart-2/15 ms-1 rounded px-1.5 py-0.5 text-[11px] font-medium\">{i.status}</span></h3>\n                <p className=\"text-muted-foreground mt-2 text-sm text-pretty\">{i.body}</p>\n              </li>\n            ))}\n          </ol>\n        </section>\n      </main>\n    </RelayShell>\n  )\n}\n\nexport { RelayStatus, type RelayStatusProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/relay/relay-status.tsx"
    },
    {
      "path": "registry/ballmac/app/relay/page.tsx",
      "content": "// Ballmac UI: Relay template route. https://ui.ballmac.com/templates/template-relay\nimport type { Metadata } from \"next\"\n\nimport { RelayHome } from \"@/components/ballmac/templates/relay/relay-home\"\n\nexport const metadata: Metadata = {\n  title: \"Relay: Never lose a webhook again\",\n  description: \"Reliable webhook delivery with retries, signatures, replay and a full audit trail.\",\n}\n\nexport default function Page() {\n  return <RelayHome />\n}\n",
      "type": "registry:page",
      "target": "app/relay/page.tsx"
    },
    {
      "path": "registry/ballmac/app/relay/docs/page.tsx",
      "content": "// Ballmac UI: Relay template route. https://ui.ballmac.com/templates/template-relay\nimport type { Metadata } from \"next\"\n\nimport { RelayDocs } from \"@/components/ballmac/templates/relay/relay-docs\"\n\nexport const metadata: Metadata = {\n  title: \"Relay docs: Quickstart\",\n  description: \"Send your first event and verify it in two minutes.\",\n}\n\nexport default function Page() {\n  return <RelayDocs />\n}\n",
      "type": "registry:page",
      "target": "app/relay/docs/page.tsx"
    },
    {
      "path": "registry/ballmac/app/relay/pricing/page.tsx",
      "content": "// Ballmac UI: Relay template route. https://ui.ballmac.com/templates/template-relay\nimport type { Metadata } from \"next\"\n\nimport { RelayPricing } from \"@/components/ballmac/templates/relay/relay-pricing\"\n\nexport const metadata: Metadata = {\n  title: \"Relay pricing\",\n  description: \"Priced per event, and cheaper as you grow.\",\n}\n\nexport default function Page() {\n  return <RelayPricing />\n}\n",
      "type": "registry:page",
      "target": "app/relay/pricing/page.tsx"
    },
    {
      "path": "registry/ballmac/app/relay/status/page.tsx",
      "content": "// Ballmac UI: Relay template route. https://ui.ballmac.com/templates/template-relay\nimport type { Metadata } from \"next\"\n\nimport { RelayStatus } from \"@/components/ballmac/templates/relay/relay-status\"\n\nexport const metadata: Metadata = {\n  title: \"Relay status\",\n  description: \"Uptime and incidents for every Relay component.\",\n}\n\nexport default function Page() {\n  return <RelayStatus />\n}\n",
      "type": "registry:page",
      "target": "app/relay/status/page.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "template",
      "developer",
      "api",
      "docs",
      "devtool",
      "pricing",
      "status page",
      "landing page"
    ],
    "version": "1.0.0",
    "updated": "2026-10-01",
    "ai": {
      "summary": "Installs a four-page site for a developer API or infrastructure product. Change the palette in relayCss (relay-theme.tsx), the samples in relay-samples.ts, and the copy in each page file.",
      "whenToUse": [
        "Marketing and docs sites for APIs, SDKs and developer infrastructure",
        "Brands that want a precise, terminal-flavoured look in light and dark"
      ],
      "whenNotToUse": [
        "Consumer apps or soft, editorial brands (use a Northwind-style template)"
      ],
      "composesWith": [
        "api-endpoint",
        "snippet-tabs",
        "faq-2"
      ],
      "a11y": [],
      "customization": [
        "Edit relayCss for the light and dark palettes",
        "Replace relay-samples.ts with your own languages",
        "Swap fonts in relay-fonts.ts"
      ]
    },
    "examples": [
      "template-relay-demo",
      "template-relay-docs",
      "template-relay-pricing",
      "template-relay-status"
    ],
    "url": "https://ui.ballmac.com/components/template-relay"
  },
  "docs": "Pages are at /relay, /relay/docs, /relay/pricing and /relay/status. The light and dark palettes are the relayCss string in relay-theme.tsx; code samples live in relay-samples.ts.",
  "categories": [
    "templates"
  ],
  "type": "registry:block"
}