# Waitlist page design: one screen that earns the email

[Canonical HTML page](https://gradiently.design/guide/waitlist-page-design)

A pre-launch page has one job. Here is how to write the line, build an accessible email form, design the moment after the click and make the page, the share card and the launch post look like one brand.

## The short version

- A waitlist page should fit on one screen: one line about the outcome, one labelled email field, one button and a sentence about what happens next.
- Ask only for an email address on the page, and save any extra questions for the confirmation screen.
- An accessible waitlist form uses a visible label, type email with autocomplete, targets at least 44 px tall, text errors linked with aria-describedby and a status message on success.
- Text on the page's gradient ground needs at least 4.5:1 contrast against the lightest part behind it, or 3:1 for large headings.
- Use the same ground and the same line in the 1200 × 630 share image and the launch posts so every link looks like the same product.

Good **waitlist page design** is one screen that does one job: earn an email address. The page needs a single line that says what you are making and for whom, one email field with a visible label, a button that names the action, one short sentence about what happens next, and a confirmation state that tells people they are in. Put it all on a ground that already looks like your brand, so the page, the share image and the launch post read as the same product from day one.

## What a waitlist page needs, and nothing else

A waitlist page is a [landing page](https://gradiently.design/guide/landing-page-design) with the argument cut down to its first screen. Nobody can try the product yet. What converts is clarity: who it is for, what changes for them, and how little they have to give to hear more.

### Avoid

- A headline about the company instead of the reader
- Name, company, role and team size fields
- A button that says Submit
- Navigation, a blog link and five social icons
- A stock photo of people pointing at a laptop
- Silence after the click

### Do

- One line about the outcome: *Invoices that chase themselves.*
- One field: email, with a visible label
- A button that says what happens: *Join the waitlist*
- A logo and nothing else to click away to
- Your brand ground filling the whole screen
- A clear confirmation and one next step

## Write the one line first

The headline carries the whole page, so write it before you choose a colour. Lead with the result your reader wants, in their words, in under ten words. Then add one supporting sentence that names who it is for or how it works.

| Weak line | Stronger line | Why |
| --- | --- | --- |
| The future of finance ops | Invoices that chase themselves. | Says what changes, not what you aspire to be |
| Pocketfern is coming soon | Your plants text you when they are thirsty. | The reader sees themselves using it |
| Join our exciting journey | Get early access before the public launch. | Names the reward for signing up |

Fictional products. The right column tells a stranger what they get.

## Design the form so everyone can use it

The form is the only interactive part of the page, so it has to work for keyboards, screen readers and thumbs.

1. **Give the field a real label** A visible `<label for>` tied to the input, never placeholder text alone. Placeholders vanish as people type and are often too faint to read. See [WebAIM on accessible forms](https://webaim.org/techniques/forms/).
2. **Use the right input type** `type="email"` brings up the email keyboard on phones and `autocomplete="email"` lets browsers fill it in one tap. Keep the input text at 16 px or larger so mobile browsers do not zoom in on focus.
3. **Make targets big enough to hit** Give the field and button at least 44 px of height. WCAG's minimum target size is 24 px, but a thumb on a phone is happier at 44 or more.
4. **Write errors people can act on** Show the error as text next to the field, start it with the word Error, connect it with `aria-describedby` and set `aria-invalid` on the input. Colour alone is not an error message.
5. **Announce the result** When the email is accepted, replace the form with a message in a `role="status"` region and move focus to it, so screen reader users hear that it worked.
6. **Check contrast on the ground** Body text needs at least 4.5:1 against the lightest part of the background behind it, large headings 3:1, and the field and button edges 3:1. [MDN explains the contrast rules](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Perceivable/Color_contrast).

## A minimal accessible waitlist hero you can copy

This hero is plain HTML and CSS: a full screen gradient ground, one line, one labelled field and a hint that says what happens next. Text sits in white and pale lilac on a ground that never gets lighter than `#6d28d9`, so white text clears 7:1 and the lilac `#e9d5ff` clears 5:1 at the brightest corner. A solid `background-color` sits under the gradient as a fallback.

```html
<main class="waitlist">
  <p class="eyebrow">Tidewell · opening this spring</p>
  <h1>Invoices that chase themselves.</h1>
  <p class="lede">Tidewell sends the polite reminder so you never have to.</p>

  <form class="join" action="/api/waitlist" method="post" novalidate>
    <label for="email">Work email</label>
    <div class="row">
      <input id="email" name="email" type="email" autocomplete="email"
             required aria-describedby="email-hint email-error">
      <button type="submit">Join the waitlist</button>
    </div>
    <p id="email-hint" class="hint">One email when we open. No newsletter.</p>
    <p id="email-error" class="error"></p>
  </form>
  <p class="done" role="status" tabindex="-1"></p>
</main>

<style>
  .waitlist {
    min-height: 100svh;
    display: grid;
    align-content: center;
    gap: 1rem;
    padding: 2rem max(1.25rem, calc(50% - 17rem));
    color: #ffffff;
    background-color: #3b0f78;
    background-image: linear-gradient(160deg, #1e0b3d 0%, #3b0f78 55%, #6d28d9 100%);
    font: 1rem/1.5 system-ui, sans-serif;
  }
  .waitlist h1 { font-size: clamp(2rem, 7vw, 3.5rem); line-height: 1.05; margin: 0; }
  .eyebrow, .lede, .hint { color: #e9d5ff; margin: 0; }
  .join label { display: block; font-weight: 600; margin-bottom: .375rem; }
  .row { display: flex; flex-wrap: wrap; gap: .5rem; }
  .row input {
    flex: 1 1 14rem;
    min-height: 3rem;
    padding: 0 .875rem;
    font: inherit;           /* 16px: no zoom on focus */
    color: #1e0b3d;
    background: #ffffff;
    border: 2px solid #ffffff;
    border-radius: .5rem;
  }
  .row input[aria-invalid="true"] { border-color: #fecaca; }
  .row button {
    min-height: 3rem;
    padding: 0 1.25rem;
    font: inherit;
    font-weight: 700;
    color: #3b0f78;
    background: #ffffff;
    border: 0;
    border-radius: .5rem;
    cursor: pointer;
  }
  .error { color: #fecaca; font-weight: 600; margin: 0; }
  .waitlist :focus-visible { outline: 3px solid #fde68a; outline-offset: 3px; }
  @media (max-width: 30rem) { .row button { flex: 1 1 100%; } }
</style>
```

A fictional product, Tidewell. The gradient is one CSS value, so it costs no download and paints with the first frame.

## The confirmation state is half the page

Most waitlist pages stop at the click. The moment after is when people are most interested, so use it. Tell them they are in, tell them exactly what happens next, and give them one thing to do: confirm the email, or share the page.

```js
const form = document.querySelector('.join')
const email = form.elements.email
const error = document.getElementById('email-error')
const done = document.querySelector('.done')

form.addEventListener('submit', async (event) => {
  event.preventDefault()
  if (!email.validity.valid) {
    error.textContent = 'Error: enter an email like name@studio.com'
    email.setAttribute('aria-invalid', 'true')
    email.focus()
    return
  }
  const res = await fetch(form.action, { method: 'POST', body: new FormData(form) })
  if (!res.ok) {
    error.textContent = 'Error: that did not go through. Please try again.'
    return
  }
  form.hidden = true
  done.textContent = 'You are on the list. Check your inbox to confirm your email.'
  done.focus()
})
```

Errors and success are written as text into regions the form already points to, so they are read aloud and visible without colour.

- **Say what happens next.** One email when you open, a confirmation link now, or both. Then do exactly that.
- **Send the confirmation email straight away** and make its header match the page, so people recognise it in a crowded inbox.
- **Offer one share action**, such as copying the page link. A confirmed fan is your best channel before launch.

## Make the share image match the page

Every waitlist link gets pasted into chats, posts and DMs, and the preview card is often the first thing people see. Give the page a 1200 × 630 Open Graph image with the same ground and the same line as the hero. [Open Graph image size](https://gradiently.design/guide/open-graph-image-size) covers the tags, and if the card comes out bare, [OG image not showing](https://gradiently.design/guide/og-image-not-showing) walks through the fixes.

- Page hero: 1920 × 1080
- Share image: 1200 × 630
- X post: 1600 × 900
- Story: 1080 × 1920

One ground and one line across the four places a waitlist shows up before launch.

A wide waitlist hero with one bold line on a purple gradient ground

The waitlist hero at 1920 × 1080: the ground fills the screen and the line sits in its calmest area.

A tall story version of the same waitlist announcement on the same purple ground

The same ground and line as a 1080 × 1920 story, so the post and the page feel like one thing.

This is where a Mark helps. A Mark is a living gradient ground that renders behind your words and keeps them readable, so the hero, the share image and the launch post can all wear the same one. Claim a Mark and nobody else can design with it, which means no other waitlist ends up looking like yours. If you want to see your name on a few grounds before deciding, [Try on your brand](/try) shows your brand on a site, an X header and more in a minute, with no account.

## Choose a brand ground that lets the line win

The ground does the work a photo would do on a normal landing page, without competing with the words. Pick one with a calm, darker region where the headline sits and keep the busiest colour away from the field. [Text on a gradient](https://gradiently.design/guide/text-on-gradient) goes deeper on keeping type readable.

- Night violet: `linear-gradient(160deg, #1e0b3d 0%, #3b0f78 55%, #6d28d9 100%)`
- Violet corner light: `radial-gradient(circle at 80% 20%, #7c3aed 0%, #2e1065 45%, #12062b 100%)`
- Deep teal: `linear-gradient(135deg, #0b1f3a 0%, #134e6f 50%, #0f766e 100%)`
- Ember dusk: `linear-gradient(180deg, #1c1917 0%, #44403c 60%, #9a3412 100%)`

Dark grounds that keep white text above 4.5:1 everywhere. Check your own lightest stop before you ship.

## Keep it fast on a phone

Most people open a waitlist link from a social app on their phone, so design at 390 px wide first and widen later. Speed is part of the design: a CSS gradient ground needs no download, the form needs no framework, and the whole page can paint in one round trip. Aim for a Largest Contentful Paint under 2.5 seconds, the threshold [web.dev](https://web.dev/articles/lcp) calls good. If the ground moves, keep it slow and honour [reduced motion](https://gradiently.design/guide/reduced-motion). [CSS gradient performance](https://gradiently.design/guide/css-gradient-performance) explains why gradients are cheap and when a large image or video is not.

## FAQ

### What should a waitlist page include?

A headline about the outcome, one supporting sentence, an email field with a visible label, a button that names the action, a line about what happens next and a confirmation state. Everything else can wait until launch.

### Should a waitlist form ask for a name?

Usually not. Each extra field gives people a reason to leave, so ask only for email and put any optional question on the confirmation screen.

### How do I make a waitlist form accessible?

Use a real label, `type="email"` with `autocomplete="email"`, targets at least 44 px tall, text errors linked with `aria-describedby`, and announce success in a `role="status"` region.

### Can I use a gradient background on a waitlist page?

Yes. A CSS gradient needs no download and fills any screen. Keep text above 4.5:1 contrast against the lightest stop behind it and set a solid background colour as a fallback.

### What size should the waitlist share image be?

Use 1200 × 630 for the Open Graph image, with the same ground and headline as the page, so links look the same in every chat and feed.
