# Waitlist Pages

> Pre-launch screens: an early-access waitlist that turns into a queue card whose position rolls down as referrals land, and a blueprint-grid launch page with an exploded drawing, rolling countdown and a reserve-a-seat ticket stamp.

- Collection: Pages
- Tier: pro
- Docs: https://geturui.com/docs/waitlist-pages
- Install: `npx shadcn@latest add @geturui-pro/waitlist-pages`
- Dependencies: motion, lucide-react

## Variants

### Early access

Email capture with a live join counter over breathing rings, then a queue card: rolling position, people-in-line strip, copyable invite link and progress toward skipping the line.

Install: `npx shadcn@latest add @geturui-pro/waitlist-pages-early-access`

```tsx
import { EarlyAccess } from "@/components/pages/waitlist-pages/early-access";

export default function Waitlist({ referrals }: { referrals: number }) {
  return (
    <EarlyAccess
      productName="Acme Copilot"
      referrals={referrals}
      onJoin={async (email) => {
        const res = await api.waitlist.join(email);
        return { position: res.position, referralUrl: res.link };
      }}
    />
  );
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| productName | `string` | "Kestrel Copilot" | Header lockup. |
| eyebrow | `string` | — | Pill above the headline. |
| headline | `string` | — | Main headline. |
| subcopy | `string` | — | Paragraph under the headline. |
| joinedCount | `number` | 4812 | Starting value of the live join counter. |
| spotsPerReferral | `number` | 120 | Spots gained per referral. |
| referralGoal | `number` | 3 | Referrals needed to skip the line. |
| onJoin | `(email: string) => Promise<{ position; referralUrl } | void>` | — | Joins the list. Return nothing to use a generated position and link. Throw to show an error. |
| referralBase | `string` | — | Prefix for generated referral links. |
| referrals | `number` | — | Controlled referral count; hides the simulate button. |
| simulateReferrals | `boolean` | true | Show a button that simulates a friend joining. |
| className | `string` | — | Classes for the outer container. |

### Blueprint launch

Launch page drawn on a blueprint grid: drawing-sheet frame with ruler and title block, exploded isometric plates that draw themselves, a rolling countdown and a seat ticket that gets an Approved stamp.

Install: `npx shadcn@latest add @geturui-pro/waitlist-pages-blueprint-launch`

```tsx
import { BlueprintLaunch } from "@/components/pages/waitlist-pages/blueprint-launch";

export default function Launch() {
  return (
    <BlueprintLaunch
      productName="Acme Engine 3"
      launchAt="2026-11-04T16:00:00Z"
      layers={["Assistant", "Engine", "Collector"]}
      onReserve={(email) => api.launch.reserve(email)}
    />
  );
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| productName | `string` | "Kestrel Engine 3" | Shown on the dimension line and title block. |
| drawingNo | `string` | "KST-ENG-003" | Drawing number in the title block. |
| headline | `string` | — | Main headline. |
| subcopy | `string` | — | Paragraph under the headline. |
| launchAt | `string | number` | — | Launch moment (ISO or epoch ms). Defaults to about 9 days after the page opens. |
| layers | `[string, string, string]` | ["Copilot", "Query engine", "Collector"] | Labels for the exploded plates, top to bottom. |
| onReserve | `(email: string) => void | Promise<void>` | — | Reserves a seat. Throw to show an error. |
| className | `string` | — | Classes for the outer container. |

## Accessibility

- Email fields are labelled and validated with inline errors; focus returns to the field on error.
- Queue position and countdown changes are exposed as text (aria-live and role=timer with a full-sentence label).
- Looping backdrop and drawing animations stop under reduced motion; digits fade instead of rolling.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
