{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "waitlist-referral-position",
  "title": "Waitlist — Referral Position",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/waitlist-referral-position/WaitlistReferralPosition.tsx",
      "content": "'use client'\n\nimport { useState, type FormEvent } from 'react'\nimport { Check, Copy, Users } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Progress } from '@/components/ui/progress'\nimport { Separator } from '@/components/ui/separator'\n\ninterface WaitlistReferralPositionProps {\n  position?: number\n  nextTierAt?: number\n}\n\nconst referralLink = 'https://northwind.dev/w/8f2a41'\n\nexport function WaitlistReferralPosition({ position = 1284, nextTierAt = 1000 }: WaitlistReferralPositionProps) {\n  const [email, setEmail] = useState('')\n  const [joined, setJoined] = useState(false)\n  const [copied, setCopied] = useState(false)\n\n  // How far from the current position to the next access tier, as a percentage.\n  const span = position - nextTierAt\n  const progress = span <= 0 ? 100 : Math.round(((position - span) / position) * 100)\n\n  function join(event: FormEvent) {\n    event.preventDefault()\n    if (!email.trim()) return\n    setJoined(true)\n  }\n\n  async function copyLink() {\n    try {\n      await navigator.clipboard.writeText(referralLink)\n      setCopied(true)\n      setTimeout(() => setCopied(false), 1600)\n    } catch {\n      // Clipboard blocked: the link stays visible and selectable.\n    }\n  }\n\n  return (\n    <section data-slot=\"waitlist-referral-position\" className=\"bg-background\">\n      <div className=\"mx-auto max-w-xl px-6 py-20 text-center lg:py-28\">\n        <Badge variant=\"secondary\" className=\"gap-1.5\">\n          <Users className=\"size-3\" aria-hidden=\"true\" />\n          8,400 waiting\n        </Badge>\n\n        <h2 className=\"mt-5 text-3xl font-semibold tracking-tight text-balance sm:text-4xl\">\n          Early access opens a cohort at a time\n        </h2>\n        <p className=\"text-muted-foreground mt-3 text-lg\">\n          Join the list, then move up it. Every person who joins through your link moves you forward.\n        </p>\n\n        {/* One card that swaps contents rather than two stacked states, so the\n            section height barely changes between before and after. */}\n        <Card className=\"mt-8 text-left\">\n          <CardContent className=\"p-6\">\n            {!joined ? (\n              <form onSubmit={join}>\n                <label htmlFor=\"waitlist-email\" className=\"text-sm font-medium\">\n                  Work email\n                </label>\n                <div className=\"mt-2 flex gap-2\">\n                  <Input\n                    id=\"waitlist-email\"\n                    value={email}\n                    onChange={(event) => setEmail(event.target.value)}\n                    type=\"email\"\n                    required\n                    placeholder=\"you@company.com\"\n                    autoComplete=\"email\"\n                  />\n                  <Button type=\"submit\" className=\"shrink-0\">\n                    Join\n                  </Button>\n                </div>\n                <p className=\"text-muted-foreground mt-2 text-xs\">\n                  No product emails while you wait — one message when your cohort opens.\n                </p>\n              </form>\n            ) : (\n              <div aria-live=\"polite\">\n                <div className=\"flex items-baseline justify-between gap-4\">\n                  <div>\n                    <p className=\"text-muted-foreground text-xs tracking-wide uppercase\">Your position</p>\n                    <p className=\"font-display mt-1 text-3xl font-bold tracking-tight\">#{position.toLocaleString()}</p>\n                  </div>\n                  <p className=\"text-muted-foreground text-right text-xs\">\n                    Next cohort opens\n                    <br />\n                    at #{nextTierAt.toLocaleString()}\n                  </p>\n                </div>\n\n                <Progress value={progress} className=\"mt-4 h-1.5\" aria-label=\"Progress to the next cohort\" />\n\n                <Separator className=\"my-5\" />\n\n                <p className=\"text-sm font-medium\">Move up the list</p>\n                <p className=\"text-muted-foreground mt-1 text-xs\">\n                  Each signup through your link moves you forward 12 places.\n                </p>\n                <div className=\"border-border bg-muted/30 mt-3 flex items-stretch overflow-hidden rounded-md border\">\n                  <code className=\"min-w-0 flex-1 truncate px-3 py-2 font-mono text-xs\">{referralLink}</code>\n                  <Button\n                    variant=\"ghost\"\n                    className=\"border-border h-auto shrink-0 rounded-none border-l px-3\"\n                    aria-label=\"Copy referral link\"\n                    onClick={copyLink}\n                  >\n                    {copied ? (\n                      <Check className=\"text-success size-4\" aria-hidden=\"true\" />\n                    ) : (\n                      <Copy className=\"size-4\" aria-hidden=\"true\" />\n                    )}\n                  </Button>\n                </div>\n              </div>\n            )}\n          </CardContent>\n        </Card>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/WaitlistReferralPosition.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/separator.json"
  ],
  "description": "Waitlist capture that swaps on submit to show queue position, the referral link that moves it, and a progress meter to the next tier of early access.",
  "categories": [
    "marketing"
  ]
}