6593bdf689
Extracted real production usage from 8 KDC repos and consolidated the consensus (kdcsurveyadd / kdcvault / kdc_void_planner) into the canonical design.md + tokens. Highlights: - brand.ink #000000 -> #1A1530 (purple-tinted, matches real usage) - brand.canvas #F5F4F0 -> #F7F4ED (warm) - neutral ramp rebuilt around ink (purple-tinted, not cold slate) - semantic palette retuned for warm canvas + soft tints - elevation shadows retinted with brand-ink rgb - new accent.gold (product) and accent.mint (marketing) tokens - real themes/light, themes/dark, themes/high-contrast - fleshed out every component + foundation README - docs/consolidation-2026-05.md captures the full audit + drift inventory Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Forms
Form composition: field stack, label / helper / error pairing, multi-step wizards. Reference: kdcsurveyadd/components/surveys/SurveyWizard.tsx (4-step wizard) and kdcsurveyadd/components/surveys/StepIndicator.tsx.
Anatomy
See anatomy.svg. Field row = label + optional helper hint + control + error slot. Sections separated by 32px; fields within a section by 16px.
Field structure
<label> field name (bodyM, 600, text.default)
<helper> optional hint (bodyS, 400, text.muted)
<input> (input.default)
<error> message when invalid (bodyS, 500, semantic.danger, role="alert")
Layout
- Single column by default — multi-column only for ≥ 3 closely-related short fields (address, date range).
- Field width matches expected content: numeric → 120px, short text → 240px, free text → fill container.
- Required indicator — append
*to label insemantic.danger; never use placeholder text or icon-only. - Optional fields — append
(optional)intext.mutedcaption.
Wizard pattern (multi-step)
- Step indicator on top:
step n of N+ horizontal progress (StepIndicator). - Context strip below — pills summarising decisions so far (jump-back affordance).
- Footer fixed:
Back(ghost, left) ·Save & exit(outline) ·Continue/Submit(primary or accent, right). - Validate per-step on
Continue; never reveal stepn+1errors prematurely.
Tokens used
components.input.*, components.button.*, colors.semantic.danger, typography.bodyM/bodyS/caption.
Accessibility
- Use a
<form>element with explicit<button type="submit">. - Group related fields with
<fieldset>+<legend>. - Errors are announced via
role="alert"and referenced byaria-describedby. - On submit failure, focus moves to the first invalid field.
- Wizard step indicator uses
aria-current="step"on the active step.
Do / Don't
- ✅ Validate on blur for individual fields; on submit for the whole form.
- ✅ Preserve user input across step changes — never silently discard.
- ❌ Don't show inline validation on first focus (only on blur or submit attempt).
- ❌ Don't disable the submit button to indicate invalid state — show the errors instead.