Template
Tandem
A one-screen 'coming soon' product launch page with a two-column layout: orange 'Coming Soon' kicker, bold waitlist headline, product pitch and an inline email form on the left, and laptop plus phone device mockups on a soft gray panel on the right. It lets founders and SaaS teams collect early signups before the product exists.
Coming-soon launch page · Website · SaaS landing page · static site
A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.
Start from this templateRead the build prompt
Typefaces
Google Sans is a clean, friendly platform-style sans, so the hardware teaser keeps the native product-page feel.
- Google SansHeadings: two-line heading 40px 700 at -1.2px
- Google SansBody: body 16px
Who it is for
- Founders validating demand
- SaaS teams teasing a product
- Agencies spinning up pre-launch pages
- Makers collecting early-access emails
Layout
- Left column (~40%) on white: orange 'Coming Soon.' line, black 'Join the waitlist.' headline, product description paragraph, smaller launch note in gray, 'Get early access' label, email input + orange 'Notify me' button
- Right column (~60%) on light gray: overlapping laptop and phone mockups showing the same art-directed image, bleeding off the right edge
- Stacks vertically on mobile with mockups below the form
- Success state after signup (toast)
Palette
Clean, optimistic, simple, product-focused, warm. Like a premium hardware teaser with a sunset glow.
- background
#ffffff - panel
#f7f7f7 - text
#111111 - primary/accent (warm orange)
#bf4f10 - muted text
#666666 - input border
#949494
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on white | 18.88:1 | 4.5:1 |
| Aa | muted note on white | 5.74:1 | 4.5:1 |
| Aa | muted text on gray panel | 5.36:1 | 4.5:1 |
| Aa | white label on orange button | 4.84:1 | 4.5:1 |
| Aa | orange kicker text on white | 4.84:1 | 4.5:1 |
| input border on white | 3.03:1 | 3:1 | |
| Aa | dark mode body text | 17.43:1 | 4.5:1 |
| Aa | dark mode primary text | 7.78:1 | 4.5:1 |
| Aa | dark mode label on primary | 7.78:1 | 4.5:1 |
| Aa | dark mode text on panel | 16.13:1 | 4.5: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
- SF Pro Display / system sans 700, 40px two-line heading with -1.2px tracking, first line in orange (SF Pro Display is not on Google Fonts; a vibld project loads Google Sans)
- Body
- SF Pro Text / system sans 16px (SF Pro Text is not on Google Fonts; a vibld project loads Google Sans)
Native platform system type for a clean, product-page feel; color splits the two headline lines.
Spacing and imagery
Single viewport, 40/60 split, left content vertically centered with ~66px padding, tiny 2px radius on input and button.
Photo-real laptop and phone device mockups displaying a warm sunset mountain wallpaper as a stand-in for the product UI.
Components
- Two-tone headline
- Product description
- Launch note
- Labeled email input
- Orange submit button
- Laptop mockup
- Phone mockup
- Gray showcase panel
- Success toast
- Dark mode tokens
Interactions
- Email validation with inline error
- Submit loading and success toast
- Responsive stacking of columns
- Hover/focus states on button and input
Data
Subscriber{email, created_at, source}LaunchConfig{productName, pitch, launchNote, accentColor, screenshots{desktop, mobile}}
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 a template'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 templates) - 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.
### Goal
Build **Tandem**, a one-screen pre-launch page for a fictional all-in-one team workspace. Visitors arrive from social posts; in five seconds they should understand what is coming, see it on real devices and drop their email. The page must be trivial to rebrand for the next product.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Input, Button, Label, Form), lucide-react, react-hook-form + zod, Sonner for the success toast. No backend except a small serverless function (or a Supabase insert-only `subscribers` table) that stores emails. All copy, colors and screenshot paths come from a `launch.config.ts` file and CSS variables.
### Pages & layout
1. **Launch page (single viewport)** – desktop split 40/60.
- Left (white): an orange line "Coming soon." directly above a black headline "Join the waitlist." (same size, bold, tight tracking); a two-sentence product pitch; a smaller gray note about perks for founding members; a visible label "Get early access"; an inline row with an email input and an orange "Notify me" button.
- Right (very light gray panel): a laptop mockup with a phone mockup overlapping its lower-left corner, both showing product screenshots (use a bright, art-directed placeholder until real UI exists); the laptop bleeds off the right edge.
- Mobile: stack the text first, then the mockups scaled to fit, no horizontal scroll.
2. **Privacy** – short page explaining what the email is used for.
### Design system
- Tokens: `--background: #ffffff`, `--panel: #f7f7f7`, `--foreground: #111111`, `--primary: #bf4f10`, `--primary-foreground: #ffffff`, `--muted-foreground: #666666`, `--border: #949494`, `--radius: 2px`. Dark tokens: background `#0f0f10`, panel `#18181a`, foreground `#f4f4f5`, primary `#f28a4f`, primary-foreground `#0f0f10`.
- Fonts: system UI stack (`-apple-system, "SF Pro Text", Google Sans, sans-serif`), headings 700 with -0.03em tracking. Scale: 13 / 16 / 17 / 24 / 40 / 48.
- Spacing: 8px base; left column padding 64px; 24px between blocks; input height 40px.
- Motion: mockups fade and rise 500ms on load; button hover darkens 150ms; no other animation.
### Components & interactions
Device mockup component (frame SVG + screenshot slot, `desktop` and `mobile` variants, lazy image with blur placeholder), email form (idle, focus ring, invalid "Enter a valid email", submitting with spinner and disabled button, success toast plus inline "You're on the list" text, duplicate handled gracefully, network error with retry), dark mode via `prefers-color-scheme`.
### Data & state
`Subscriber{email, createdAt, source}`; `LaunchConfig{productName, kicker, headline, pitch, note, accent, screenshots{desktop, mobile}, privacyUrl}`. Form state in react-hook-form; no global state needed. Use placeholder imagery, not real product UI from another company.
### Accessibility
The warm orange is set to `#bf4f10` so white button labels reach 4.8:1 and the orange kicker passes on white (4.8:1) and the gray panel (4.5:1). Dark mode labels on the `#f28a4f` primary are `#0f0f10` (7.8:1). Gray note `#666666` passes (5.7:1). The input border is `#949494` (3:1). Keep a real `<label>` for the email field, `autocomplete="email"`, and `aria-describedby` for errors. Success is announced in a polite live region. Device mockups have alt text describing the product view. The whole page works at 200% zoom.
Verified contrast: body text on white #111111 on #ffffff = 18.88:1; muted note on white #666666 on #ffffff = 5.74:1; muted text on gray panel #666666 on #f7f7f7 = 5.36:1; white label on orange button #ffffff on #bf4f10 = 4.84:1; orange kicker text on white #bf4f10 on #ffffff = 4.84:1.
### Security
Proportionate: zod validation on the client and the function, email normalization, honeypot field, per-IP rate limiting, optional Turnstile. If Supabase is used, RLS allows anon insert only and a unique constraint on email; no public reads. No keys other than the anon key in client code. Link to the privacy page near the form.
### Performance & SEO
One viewport, so aim for a perfect score: preload the laptop screenshot, serve AVIF/WebP at 1x/2x, system fonts (no web-font cost), JS under ~80KB. Title, description and an OG image showing the mockups. Lighthouse 100 target.
### Guardrails
- Placeholder product name, copy and screenshots; avoid brand names or trademarked device marks on the mockups.
- Don't claim fake signup counts or press mentions.
- Store only the email and timestamp.
- Small typed components, no `any`, visible errors.
- Done when: the layout matches the 40/60 split on desktop and stacks cleanly on a 360px phone; the form validates, prevents double submits and confirms; button contrast is fixed; config changes rebrand the page without touching components.