- TextInput/Textarea size="sm": text-xs, tighter padding (h-9, px-2.5
py-1.5) so placeholder/value match label scale.
- Checkbox: new size prop (sm = h-4 w-4 + text-xs leading-snug).
Switched container to flex/items-start so multi-line labels align
with checkbox top instead of vertically centering and pushing the
box halfway down the paragraph.
- ContactForm: consent checkbox uses size="sm"; privacy note + error
hint at text-[0.7rem] leading-snug to match.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Client renders explicit Turnstile widget (flexible, light theme) when
PUBLIC_TURNSTILE_SITE_KEY is set. Token sent with form payload, server
verifies via siteverify endpoint before forwarding to CMS. Skipped
entirely when no site key configured (dev fallback). New i18n keys:
contact_captcha_pending, contact_server_error_captcha. Deploy workflow
forwards PUBLIC_TURNSTILE_SITE_KEY + TURNSTILE_SECRET.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
InternalComponentBlock dispatches on `component` field value.
ContactFormComponent submits via /api/contact (SvelteKit proxy →
CMS /api/forms/kontakt/submit) with honeypot + client_age_ms.
BlockRenderer and block-types.ts updated accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>