src/components/cta/CtaEmail.astro
---
/**
* CtaEmail
* Gecentreerde e-mail-opt-in: kop, sub en een inline pill-formulier (input +
* knop) met disclaimer. Achtergrond via variant.
*
* Props:
* - headline: string
* - sub?: string
* - placeholder?: string
* - button?: string
* - disclaimer?: string
* - action?: string
* - bg?: 'white' | 'light' | 'accent' | 'dark' default 'light'
*/
interface Props {
headline: string;
sub?: string;
placeholder?: string;
button?: string;
disclaimer?: string;
action?: string;
bg?: 'white' | 'light' | 'accent' | 'dark';
}
const {
headline,
sub,
placeholder = 'Je e-mailadres',
button = 'Aanmelden',
disclaimer,
action = '#',
bg = 'light',
} = Astro.props;
---
<section class:list={['bl-section', 'cte__section', `cte__bg-${bg}`]}>
<div class="bl-inner bl-inner--narrow cte__inner">
<h2 class="cte__headline">{headline}</h2>
{sub && <p class="cte__sub">{sub}</p>}
<form class="cte__form" action={action} method="post" novalidate>
<div class="cte__pill">
<label class="cte__label-sr" for="cte-email">E-mailadres</label>
<input class="cte__input" id="cte-email" type="email" name="email" placeholder={placeholder} autocomplete="email" required />
<button class="cte__btn" type="submit">{button}</button>
</div>
{disclaimer && <p class="cte__disclaimer">{disclaimer}</p>}
</form>
</div>
</section>
<style>
.cte__inner{display:flex;flex-direction:column;align-items:center;gap:1rem;text-align:center}
.cte__bg-white{background:var(--color-bg,#fff)}
.cte__bg-light{background:#f9fafb}
.cte__bg-accent{background:var(--color-accent,#6366f1)}
.cte__bg-dark{background:var(--color-primary,#0a0a0a)}
.cte__bg-accent .cte__headline,.cte__bg-dark .cte__headline{color:#fff}
.cte__bg-accent .cte__sub,.cte__bg-dark .cte__sub{color:#e8e8e8}
.cte__bg-accent .cte__disclaimer,.cte__bg-dark .cte__disclaimer{color:#cbd5e1}
.cte__headline{margin:0;font-size:clamp(1.5rem,3vw,2.25rem);font-weight:800;letter-spacing:-.02em;color:var(--color-primary,#0a0a0a);line-height:1.2}
.cte__sub{margin:0;font-size:1.0625rem;line-height:1.65;color:var(--color-muted,#4b5563)}
.cte__label-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.cte__form{width:100%;display:flex;flex-direction:column;gap:.75rem;max-width:480px}
.cte__pill{display:flex;align-items:center;background:#fff;border:1.5px solid rgba(0,0,0,.12);border-radius:999px;padding:.25rem .25rem .25rem 1.25rem;gap:.5rem;width:100%;transition:border-color .2s ease,box-shadow .2s ease}
.cte__pill:focus-within{border-color:var(--color-accent,#6366f1);box-shadow:0 0 0 3px #6366f126}
.cte__bg-accent .cte__pill,.cte__bg-dark .cte__pill{background:#ffffff14;border-color:#ffffff40}
.cte__input{flex:1;border:none;outline:none;background:transparent;font-size:1rem;color:var(--color-primary,#0a0a0a);min-width:0}
.cte__input::placeholder{color:var(--color-muted,#6b7280)}
.cte__bg-accent .cte__input,.cte__bg-dark .cte__input{color:#fff}
.cte__bg-accent .cte__input::placeholder,.cte__bg-dark .cte__input::placeholder{color:#ffffffb3}
.cte__btn{display:inline-flex;align-items:center;justify-content:center;padding:.625rem 1.25rem;border-radius:999px;background:var(--color-accent,#6366f1);color:#fff;font-size:1rem;font-weight:700;border:none;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:opacity .2s ease}
.cte__btn:hover{opacity:.88}
.cte__bg-accent .cte__btn,.cte__bg-dark .cte__btn{background:#fff;color:var(--color-primary,#0a0a0a)}
.cte__disclaimer{margin:0;font-size:.875rem;color:var(--color-muted,#6b7280);line-height:1.5}
</style>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
headline * | string | - | H2-kop |
sub | string | - | Ondertitel |
placeholder | string | naam@voorbeeld.nl | Placeholder van het invoerveld |
button | string | Aanmelden | Knoptekst |
disclaimer | string | - | Kleine tekst onder het formulier |
action | string | # | Formulier-action |
bg | 'white' | 'light' | 'accent' | 'dark' | 'light' | Achtergrond-variant |
* = verplicht