{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "hero-waitlist-glow",
  "title": "Hero Waitlist Glow",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/hero-waitlist-glow/hero-waitlist-glow.component.ts",
      "content": "// High-conversion waitlist hero: role tracks with perks, a live launch countdown,\n// an email capture form and a success queue state with a referral booster.\n// Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit, computed, signal } from '@angular/core'\nimport { ArrowRight, Check, CheckCircle2, Copy, LucideAngularModule, Shield } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiCardComponent } from '@/ui/card/card.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\n\nexport type HeroWaitlistRole = 'frontend' | 'architect' | 'founder'\n\nexport interface HeroWaitlistRoleOption {\n  id: HeroWaitlistRole\n  label: string\n  perk: string\n}\n\nconst roleOptions: HeroWaitlistRoleOption[] = [\n  { id: 'frontend', label: 'Frontend / UI Engineer', perk: 'Direct access to raw SFC / TSX templates & Figma tokens' },\n  { id: 'architect', label: 'Solutions Architect', perk: 'Full unbundled AST registry spec & self-hosting blueprints' },\n  { id: 'founder', label: 'Founder / CTO', perk: 'Zero runtime dependency compliance & white-label enterprise SLA' },\n]\n\nfunction pad(value: number): string {\n  return String(value).padStart(2, '0')\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-hero-waitlist-glow, [ui-hero-waitlist-glow]',\n  standalone: true,\n  // React renders the root <section> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [LucideAngularModule, UiButtonComponent, UiCardComponent, UiInputComponent],\n  template: `\n    <section data-slot=\"hero-waitlist-glow\" [class]=\"rootClass\">\n      <!-- Center Radial Glow -->\n      <div\n        class=\"bg-primary/15 pointer-events-none absolute top-1/4 left-1/2 -z-10 h-96 w-full max-w-4xl -translate-x-1/2 -translate-y-1/2 rounded-full blur-xl\"\n      ></div>\n\n      <div class=\"mx-auto max-w-4xl space-y-10\">\n        <!-- Top Pill -->\n        <div\n          class=\"border-border bg-muted/40 inline-flex items-center gap-2 rounded-full border px-3.5 py-1 font-mono text-xs shadow-xs\"\n        >\n          <span class=\"bg-success size-2 rounded-full\"></span>\n          <span class=\"text-foreground font-medium\">Public Registry Release</span>\n          <span class=\"text-muted-foreground\">&bull;</span>\n          <span class=\"text-primary font-semibold\">96% Claimed</span>\n        </div>\n\n        <!-- Main Headline -->\n        <div class=\"mx-auto max-w-3xl space-y-4\">\n          <h1 class=\"text-foreground text-4xl leading-[1.12] font-bold tracking-tight sm:text-5xl lg:text-6xl\">\n            Unbundled UI components and composable application blocks.\n          </h1>\n          <p class=\"text-muted-foreground mx-auto max-w-2xl text-base leading-relaxed sm:text-lg\">\n            Join over thousands of developers building high-velocity web applications with unbundled Vue 3.5 & React 19\n            components.\n          </p>\n        </div>\n\n        <!-- Live Countdown Bar -->\n        <div class=\"mx-auto grid max-w-md grid-cols-4 gap-3\">\n          @for (unit of countdownUnits(); track unit.label) {\n            <div class=\"border-border bg-card/60 rounded-xl border p-3 backdrop-blur-sm\">\n              <p class=\"text-foreground font-mono text-2xl font-bold\">{{ unit.value }}</p>\n              <p class=\"text-muted-foreground mt-0.5 font-mono text-xs uppercase\">{{ unit.label }}</p>\n            </div>\n          }\n        </div>\n\n        <!-- Interactive Waitlist Workbench Card -->\n        <div\n          ui-card\n          class=\"border-border bg-card/95 mx-auto max-w-2xl overflow-hidden rounded-2xl p-6 text-left shadow-sm backdrop-blur-md sm:p-8\"\n        >\n          @if (!isSubmitted()) {\n            <div class=\"space-y-6\">\n              <!-- Role Selection Tabs -->\n              <div class=\"space-y-2\">\n                <label class=\"text-muted-foreground font-mono text-xs tracking-wider uppercase\"\n                  >Select Your Track</label\n                >\n                <div class=\"grid grid-cols-3 gap-2\">\n                  @for (opt of roles; track opt.id) {\n                    <button type=\"button\" [class]=\"roleClass(opt.id)\" (click)=\"selectedRole.set(opt.id)\">\n                      {{ opt.label.split(' ')[0] }}\n                    </button>\n                  }\n                </div>\n                <p class=\"text-muted-foreground pt-1 text-xs italic\">&rarr; {{ activeRole().perk }}</p>\n              </div>\n\n              <!-- Email Input & Submit -->\n              <form class=\"space-y-3\" (submit)=\"onSubmit($event)\">\n                <div class=\"flex flex-col items-center gap-2 sm:flex-row\">\n                  <ui-input\n                    [value]=\"email()\"\n                    (valueChange)=\"email.set($event)\"\n                    type=\"email\"\n                    placeholder=\"name@company.com\"\n                    aria-label=\"Email address\"\n                    required\n                    class=\"bg-background h-11 font-mono text-sm\"\n                  />\n                  <button\n                    ui-button\n                    type=\"submit\"\n                    size=\"lg\"\n                    class=\"h-11 w-full shrink-0 gap-2 px-6 font-semibold sm:w-auto\"\n                  >\n                    <span>Get Started</span>\n                    <lucide-icon [img]=\"ArrowRight\" class=\"size-4\" />\n                  </button>\n                </div>\n                <p class=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n                  <lucide-icon [img]=\"Shield\" class=\"text-success size-3.5\" />\n                  <span>Zero spam. Instant private registry token delivered upon verification.</span>\n                </p>\n              </form>\n            </div>\n          } @else {\n            <!-- Success Queue State -->\n            <div class=\"space-y-5 py-4 text-center\">\n              <div\n                class=\"border-success/20 bg-success/10 text-success mx-auto flex size-12 items-center justify-center rounded-full border\"\n              >\n                <lucide-icon [img]=\"CheckCircle2\" class=\"size-6\" />\n              </div>\n\n              <div class=\"space-y-1\">\n                <h3 class=\"text-foreground text-xl font-bold\">You're on the list!</h3>\n                <p class=\"text-primary font-mono text-xs font-semibold\">Priority Spot: #{{ queueNumber() }} in line</p>\n                <p class=\"text-muted-foreground mx-auto max-w-sm text-xs\">\n                  We dispatched an invitation link to <span class=\"text-foreground font-mono\">{{ email() }}</span\n                  >.\n                </p>\n              </div>\n\n              <!-- Referral Link Box -->\n              <div class=\"border-border bg-muted/30 mx-auto max-w-md space-y-2 rounded-xl border p-3\">\n                <div class=\"text-muted-foreground flex items-center justify-between font-mono text-xs\">\n                  <span>Jump 5 spots per referral</span>\n                  <span class=\"text-success font-bold\">+5 boost</span>\n                </div>\n                <div class=\"flex items-center gap-2\">\n                  <ui-input\n                    [value]=\"referralLink()\"\n                    readonly\n                    aria-label=\"Referral link\"\n                    class=\"bg-background h-9 font-mono text-xs\"\n                  />\n                  <button\n                    ui-button\n                    type=\"button\"\n                    size=\"sm\"\n                    variant=\"outline\"\n                    class=\"h-9 gap-1.5 px-3\"\n                    (click)=\"copyReferral()\"\n                  >\n                    @if (referralCopied()) {\n                      <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                    } @else {\n                      <lucide-icon [img]=\"Copy\" class=\"size-3\" />\n                    }\n                    <span>{{ referralCopied() ? 'Copied' : 'Copy' }}</span>\n                  </button>\n                </div>\n              </div>\n            </div>\n          }\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiHeroWaitlistGlowComponent implements OnInit, OnDestroy {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Check = Check\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Copy = Copy\n  protected readonly Shield = Shield\n\n  protected readonly roles = roleOptions\n\n  @Input('class') className?: string\n\n  readonly selectedRole = signal<HeroWaitlistRole>('frontend')\n  readonly email = signal('')\n  readonly isSubmitted = signal(false)\n  readonly queueNumber = signal<number | null>(null)\n  readonly referralCopied = signal(false)\n\n  readonly days = signal(14)\n  readonly hours = signal(8)\n  readonly minutes = signal(42)\n  readonly seconds = signal(19)\n\n  private timer: ReturnType<typeof setInterval> | undefined\n  private copyTimer: ReturnType<typeof setTimeout> | undefined\n\n  readonly activeRole = computed(() => roleOptions.find((r) => r.id === this.selectedRole()) ?? roleOptions[0]!)\n\n  readonly countdownUnits = computed(() => [\n    { label: 'Days', value: pad(this.days()) },\n    { label: 'Hours', value: pad(this.hours()) },\n    { label: 'Mins', value: pad(this.minutes()) },\n    { label: 'Secs', value: pad(this.seconds()) },\n  ])\n\n  readonly referralLink = computed(() => `https://uipkge.dev/join?ref=${this.queueNumber()}`)\n\n  get rootClass(): string {\n    return cn('bg-background relative overflow-hidden px-4 py-16 text-center sm:px-6 sm:py-24 lg:px-8', this.className)\n  }\n\n  roleClass(id: HeroWaitlistRole): string {\n    return cn(\n      'rounded-lg border p-2.5 text-center text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none',\n      this.selectedRole() === id\n        ? 'border-primary bg-primary/10 text-foreground font-semibold shadow-xs'\n        : 'border-border bg-background/50 text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  ngOnInit(): void {\n    this.timer = setInterval(() => this.tick(), 1000)\n  }\n\n  ngOnDestroy(): void {\n    clearInterval(this.timer)\n    clearTimeout(this.copyTimer)\n  }\n\n  tick(): void {\n    if (this.seconds() > 0) {\n      this.seconds.update((v) => v - 1)\n    } else {\n      this.seconds.set(59)\n      if (this.minutes() > 0) {\n        this.minutes.update((v) => v - 1)\n      } else {\n        this.minutes.set(59)\n        if (this.hours() > 0) {\n          this.hours.update((v) => v - 1)\n        }\n      }\n    }\n  }\n\n  onSubmit(event: Event): void {\n    event.preventDefault()\n    this.submitWaitlist()\n  }\n\n  submitWaitlist(): void {\n    if (!this.email() || !this.email().includes('@')) return\n    this.queueNumber.set(Math.floor(Math.random() * 80) + 120)\n    this.isSubmitted.set(true)\n  }\n\n  copyReferral(): void {\n    void navigator.clipboard?.writeText(`https://uipkge.dev/join?ref=${this.queueNumber() ?? 142}`)\n    this.referralCopied.set(true)\n    clearTimeout(this.copyTimer)\n    this.copyTimer = setTimeout(() => this.referralCopied.set(false), 2000)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/hero-waitlist-glow/hero-waitlist-glow.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/hero-waitlist-glow/index.ts",
      "content": "export {\n  UiHeroWaitlistGlowComponent,\n  type HeroWaitlistRole,\n  type HeroWaitlistRoleOption,\n} from './hero-waitlist-glow.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/hero-waitlist-glow/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/input.json"
  ],
  "description": "High-conversion early access waitlist hero with role tracks, dynamic live queue spot generator, launch countdown clock, and referral booster.",
  "categories": [
    "marketing"
  ],
  "deprecated": true,
  "replacedBy": "hero"
}