Centered Hero
A centred headline, sub-copy and a pair of CTAs under an eyebrow badge - the default landing hero.
6 frameworksBeginner
A headline over an inline email field and submit - the whole hero is the signup.
<!--
A real <form> with a real <label>. The label is visually hidden, not absent -
placeholder text is not a label: it vanishes the moment you type, it is not
reliably announced, and it leaves the field nameless to a screen reader.
type="email" gets the right mobile keyboard and free browser validation;
autocomplete="email" lets the browser fill it. Neither is optional polish on
the one field standing between a visitor and a signup.
-->
<section class="hero-form">
<p class="hero-form__kicker">Launching this autumn</p>
<h1 class="hero-form__title">Get on the list</h1>
<p class="hero-form__copy">
One email when we open the doors. No drip campaign, no spam.
</p>
<form class="hero-form__form" action="/api/subscribe" method="post">
<label class="hero-form__label" for="hero-form-email">Email address</label>
<div class="hero-form__row">
<input
class="hero-form__input"
id="hero-form-email"
name="email"
type="email"
autocomplete="email"
placeholder="you@company.com"
required
/>
<button class="hero-form__submit" type="submit">Get early access</button>
</div>
</form>
<p class="hero-form__note">We only email once. Unsubscribe any time.</p>
</section>| Prop | Type | Default | Description |
|---|---|---|---|
titlerequired | string | - | Heading text for the card. |
kicker | string | - | Small label shown above the title. |
copy | string | - | Body text shown under the title. |
ctaLabel | string | 'Get early access' | Call-to-action button text. |
loading | boolean | false | Shows a spinner and blocks input while true. |
className | string | - | Additional classes merged onto the root element. |
The label is hidden, not missing. A placeholder is not a label: it vanishes on the first keystroke, it is not reliably announced, and it leaves the field nameless in the accessibility tree - so `sr-only` (a clip-rect, not `display:none`) keeps it there for the people who need it. `type="email"` earns the right mobile keyboard and free browser validation, and `autocomplete="email"` lets the browser fill it; on the one field standing between a visitor and a signup, neither is optional polish. The row goes vertical below `sm` - a 90px-wide email input is not a form, it is a rumour. Drive `loading` from your submit handler so a double-tap cannot double-subscribe.