Skip to main content
vibld

Template

Zephyrpost

The screen shown after sign-up while a developer confirms their email. It names the address the link went to, continues automatically once the link is clicked in another tab, and offers a manual 'I've verified' check, resend status and a way back to sign-up.

Check-your-inbox email verification card · App screen: verification · Small tools and apps · full-stack app (auth + DB)

A mock-up of the screen, drawn from its layout, palette and typefaces. A build follows the full prompt below.

Start from this screenRead the build prompt

Typefaces

The catalog's own faces. A screen composed into a template is drawn in that template's typefaces.

  • InterHeadings: Inter 500, 28px card heading
  • InterBody: Inter 400 16px / 1.5

Patterns

  • centred card on blueprint grid background
  • logo above card
  • auto-continue polling after verification
  • primary confirm button with secondary resend status
  • escape-hatch sign-out link
  • footnote under card

States it is designed for

  • Waiting (default)
  • Checking: button spinner
  • Not yet verified after manual check: inline message
  • Resent: toast 'New link sent'
  • Resend rate-limited: countdown with remaining seconds
  • Link expired (arriving from email): message and resend
  • Verified: brief success check then redirect

Who it is for

  • new sign-ups to a developer API
  • users who mistyped their email

Layout

  1. Background: light grey with faint architectural grid lines and small corner nodes
  2. Logo mark + wordmark centred at top
  3. Card (420px, radius 12px, white, soft shadow): H1, explanation with bold email, full-width blue primary button, full-width subtle 'Email sent' status row with small spinner/check, text link to log out and restart
  4. Footnote below the card in small muted text
  5. Mobile: card full width with 16px gutters; grid hidden

Palette

Calm and technical, like a blueprint: tidy grid, one blue action, nothing to worry about.

  • canvas#f5f5f5
  • surface#ffffff
  • text#141414
  • muted#5e5e5e
  • grid-line#e3e3e3
  • primary#1f6fe0
  • on-primary#ffffff
  • status-bg#fafafa
  • input-border#8c8c8c
  • focus#1f6fe0

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text18.42:14.5:1
Aamuted explanation6.48:14.5:1
Aafootnote on canvas5.95:14.5:1
Aaprimary button label4.76:14.5:1
Aastatus row text6.21:14.5:1
focus ring on white4.76:13:1
input border3.36:13:1

As vibld’s tokens

The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.

  • background
  • card
  • muted
  • primary
  • secondary
  • accent
  • destructive *

Type scale

Display
Inter 500, 28px card heading
Body
Inter 400 16px / 1.5

Footnote 13px muted. Similar to the observed neo-grotesk.

Spacing and imagery

Airy; 4px base; card padding 28px; 16px between stacked controls; radius 12px card, 10px buttons; shadow 0 4px 16px rgba(0,0,0,.06).

No imagery; background grid drawn with CSS; logo mark is two geometric shapes.

Components

  • BlueprintBackground
  • Logo
  • VerifyCard
  • EmailHighlight
  • PrimaryButton 'I've verified my email'
  • ResendStatusRow (sent / resend in Ns / resend)
  • SignOutLink
  • Footnote

Interactions

  • Page polls session every 4s (and on window focus) and redirects when email_confirmed_at is set
  • Primary button forces a check; if not yet verified, shows inline 'Not verified yet - check your inbox'
  • Status row cycles: 'Email sent' with check, then 'Resend in 30s' countdown, then 'Resend email' link
  • Sign-out link clears the session and returns to sign-up

Data

  • User{id, email, email_confirmed_at}
  • VerificationEmail{user_id, sent_at, attempt}

Guardrails

Experience

  • Show the exact address in bold so typos are obvious
  • Continue automatically when verification happens elsewhere
  • Offer a clear way out (sign out, change email)
  • Throttle resend with a visible countdown
  • Keep copy short: what happened, what to do, what happens next

Accessibility

  • Status changes announced in aria-live='polite'
  • Primary button uses aria-busy while checking
  • Grid background is decorative CSS only
  • Focus lands on the heading on load
  • Footnote 13px meets 4.5:1

Security

  • Rate-limit resend per user and per IP
  • Verification links single-use and expiring (e.g. 24h)
  • Do not reveal whether other emails exist
  • Polling hits a lightweight session endpoint only

Build prompt

The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.

The baseline
### How to use these prompts
Paste an entry's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project.

### Engineering baseline
- TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind).
- Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone.
- Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only.
- Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables.

### Data and auth baseline (full-stack entries)
- Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views.
- Store roles in a separate table checked by a security-definer function, never in a user-editable profile field.
- Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs.
- Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms.
- Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data.

### Accessibility and UX baseline
- Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change.
- Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels.
- Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images.
- Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives.
- Build mobile-first and test at 375px, 768px and 1280px.

### Content guardrails
- Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text.
- Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs.

### SaaS screen baseline
- Design every screen for its full set of states: first-run empty, loading skeleton, partial data, error with retry, permission-denied, and success feedback. Each entry lists the states its screen needs.
- Keep destructive actions (delete, revoke, downgrade, remove member) behind a confirmation that names the object, and prefer undo over a second dialog where the action is reversible.
- Enforce authorisation on the server for every action a screen exposes. Hiding a button is not access control; check the role again in the API or RLS policy.
- Never show secrets (API keys, tokens) in full after creation. Show them once, then mask them, and offer rotate and revoke.
- Keep the app shell (navigation, workspace switcher, account menu) consistent across screens, and preserve filters, sort and scroll position when the user navigates back.
### Goal
Build **Zephyrpost**, the 'Check your inbox' verification screen for a developer platform. After sign-up the user sees the address the link went to; the page continues on its own once they click the link, and offers a manual check, resend and sign-out.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui, lucide-react, TanStack Query (polling), zod. Supabase Auth email confirmation; a transactional email service sends the link.

### Pages & layout
1. **Background**: #f5f5f5 with a CSS grid of 1px lines and small node dots at intersections.
2. **Logo** centred 48px from top.
3. **Card** (420px): H1 'Check your inbox'; explanation 'We sent a link to **name@example.com**. Open it to confirm; this page will continue by itself.'; primary 'I've verified my email'; status row ('Email sent' with check / 'Resend in 30s' / 'Resend email'); link 'Sign out and use a different email'.
4. **Footnote**: 'After verifying we'll finish setting up your account.'
5. Mobile: full-width card, grid hidden.

### Design system
- Colors: `--canvas: #f5f5f5`, `--surface: #ffffff`, `--text: #141414`, `--muted: #5e5e5e`, `--grid-line: #e3e3e3`, `--primary: #1f6fe0`, `--on-primary: #ffffff`, `--status-bg: #fafafa`, `--input-border: #8c8c8c`, `--focus: #1f6fe0`.
- Fonts: Inter 400/500; body 16px/1.5; H1 28px; footnote 13px.
- Spacing: 4px scale; card padding 28px; 16px control gap.
- Radius: 12px card, 10px buttons.
- Shadows: 0 4px 16px rgba(0,0,0,.06).
- Motion: spinner in status row; success check scale-in 150ms; reduced motion shows static icons.

### Components & interactions
VerifyCard, PrimaryButton (idle/busy/not-yet message), ResendStatusRow (sent, countdown, resend link), SignOutLink, Toast, ExpiredLinkNotice.
Behaviour details: the status row is a single component with three modes driven by a timestamp of the last send, so a page refresh keeps the countdown accurate. When the user clicks the primary button and verification has already happened in another tab, skip the 'not yet' message and go straight to the success check. If the user arrives from the email link on a different device, show a small 'You're verified - return to your other tab or continue here' screen with a Continue button. Provide a tiny 'Wrong address?' action inside the sign-out link's sentence so users understand why they would sign out.

### Data & state
Uses Supabase Auth user (email, email_confirmed_at) and a `verification_emails(user_id, sent_at, attempt)` table for throttling. TanStack Query polls `getUser` every 4s and on focus; stops after verification or 15 minutes. Mock mode: toggle to simulate verification after 10s.
Keep a derived `verificationState` enum ('waiting' | 'checking' | 'not_yet' | 'verified' | 'expired') in one reducer so UI, copy and polling share a single source of truth. Log resend attempts server-side for abuse monitoring, not client-side.

### Accessibility
Heading receives focus on load; status updates in a polite live region; buttons have busy states; decorative grid is hidden from assistive tech; all text meets 4.5:1.
Verified contrast: body text: #141414 on #ffffff = 18.42:1; muted explanation: #5e5e5e on #ffffff = 6.48:1; footnote on canvas: #5e5e5e on #f5f5f5 = 5.95:1; primary button label: #ffffff on #1f6fe0 = 4.76:1; status row text: #5e5e5e on #fafafa = 6.21:1; focus ring on white: #1f6fe0 on #ffffff = 4.76:1; input border: #8c8c8c on #ffffff = 3.36:1.

### Security
Resend limited to one per 30s and five per hour per user/IP via an Edge Function; links single-use and expire; generic messages that don't reveal account existence; RLS owner-only on `verification_emails`.

### Performance & SEO
Tiny route; no images. Polling backs off when the tab is hidden. Auth routes noindex.

### Guardrails
- Placeholder email only (name@example.com).
- Never auto-resend without user action.
- Acceptance criteria: (1) verifying in another tab redirects this one; (2) manual check shows not-yet message; (3) resend countdown enforced server-side too; (4) sign-out returns to sign-up; (5) works at 390px.

Open the builderAll templatesThis palette on its own