docs: complete Stitch frontend replacement

This commit is contained in:
Jens
2026-07-22 20:48:48 +02:00
parent 5f435d030e
commit 0101660bd7
10 changed files with 268 additions and 327 deletions
+42 -114
View File
@@ -1,130 +1,58 @@
# Design system
# VacatureRadar design system
> Geactualiseerd voor VR-118. De volledige Stitch-mapping en bewuste afwijkingen staan in
> `docs/design/STITCH_INTEGRATION_PLAN.md`.
Dit document beschrijft de enige normale productiefrontend vanaf versie 0.3.0. De visuele bron van waarheid is de Stitch Intelligence Cockpit; het bindende contract en de schermmapping staan in `STITCH_FRONTEND_CONTRACT.md` en `STITCH_INTEGRATION_REPORT.md`.
## 1. Merkgevoel
## Visuele identiteit
Rustig, betrouwbaar, helder en technisch precies. De interface voelt als een professionele intelligence-cockpit:
donker marineblauw als standaard, signaalcyaan voor primaire interactie en tonale lagen in plaats van zware schaduwen.
De lichte variant behoudt dezelfde hiërarchie. Geen confetti, fictieve grafieken, eindeloze badges of agressieve notificatiekleuren.
De standaardervaring is een donkere, technische navycockpit. Signal Cyan markeert focus en primaire acties, Emerald aantoonbaar positieve of gezonde status, Intelligence Indigo automatisering en Amber/Coral aandacht of fout. Tonale oppervlakken en fijne borders vormen de hiërarchie; glows zijn beperkt tot focus en sterke signalen.
## 2. Visuele tokens
De productietokens staan uitsluitend in `static/css/tokens.css`:
De implementatie staat in `static/css/app.css`. Gebruik semantische custom properties in plaats van losse kleuren in componenten.
- oppervlakken: `--surface-lowest`, `--surface`, `--surface-low`, `--surface-container`, `--surface-high`, `--surface-highest`, `--surface-bright`;
- tekst: `--text`, `--text-strong`, `--text-muted`, `--text-faint`;
- signalen: `--cyan`, `--cyan-dim`, `--emerald`, `--indigo`, `--amber`, `--coral`, `--danger`;
- structuur: `--outline`, `--outline-strong`, `--sidebar-width`, `--topbar-height`, `--content-gutter`, radii en `--shadow-signal`.
Geïmplementeerde tokenrollen omvatten onder meer:
De light variant gebruikt dezelfde semantische tokens en informatiehiërarchie. Component-CSS bevat geen eigen hardcoded palette; uitzonderingen zijn alleen documentmetadata zoals `theme-color` en e-mailtemplates buiten de cockpit.
```css
--bg
--bg-deep
--surface
--surface-low
--surface-high
--surface-bright
--text
--text-soft
--muted
--border
--border-strong
--primary
--primary-strong
--positive
--warning
--danger
--signal-glow
--radius-sm
--radius
```
## Typografie en iconen
Donkere modus is de productstandaard. De gebruiker kan lokaal wisselen via `data-theme`; opslag is progressief en
mag in een afgeschermde browsercontext uitvallen zonder de bediening te breken.
- Headlines: lokale systeemstack die Geist benadert (`Segoe UI Variable Display`, Aptos Display, Segoe UI).
- Body: `Segoe UI Variable Text`, Aptos en systeemfallbacks.
- Technische metadata: Cascadia Mono, SFMono/Consolas.
- Geen externe font- of iconrequest; iconen komen uit één lokale inline SVG-sprite.
- Score, datum en metadata blijven tekstueel leesbaar en steunen nooit alleen op kleur of vorm.
## 3. Typografie
## Layoutsysteem
- systeemfontstack, geen externe fontrequest;
- basis 16px;
- body line-height ongeveer 1,55;
- compacte metadata 0,80,9rem maar nooit onder bruikbare leesgrootte;
- titels met duidelijke schaal, niet alleen gewicht;
- cijfers voor scores mogen tabular nums gebruiken.
- Vaste technische sidebar van 256 px en contexttopbar op desktop.
- Flexibel datacanvas met een maximum van 2240 px; op 1920/2560 px benutten feeds en intelligencepanelen de extra breedte.
- Bij 1180 px stapelen de zwaarste rails; bij 820 px wordt de sidebar een drawer met mobiele tabbar; bij 560 px worden cards, forms en intelligenceblokken éénkoloms.
- Kanban, pipeline en datatabellen mogen alleen binnen een gelabelde lokale container horizontaal scrollen. Het document zelf heeft geen horizontale overflow.
- Sticky actions houden rekening met de mobiele tabbar en bedekken geen essentiële informatie.
## 4. Spacing en layout
## Kerncomponenten
- 4/8px-gebaseerde schaal;
- contentcontainer maximaal 2240px; vanaf 1850px gebruikt de cockpit extra resultaatkolommen en
contextpanelen in plaats van alleen langere tekstregels;
- kaarten met consistente padding 2024px desktop, 16px mobiel;
- minimaal 44×44px touch targets voor primaire interactie;
- vaste zijbalk van 272px boven 900px, toegankelijke uitschuifnavigatie daaronder;
- grids breken rond 1850px, 1350px, 1180px, 900px en 680px logisch af;
- vaste/sticky elementen mogen content niet bedekken.
- `cockpit-sidebar`, `cockpit-topbar`, `mobile-tabbar`: globale shell en navigatie.
- `cockpit-heading`, `section-heading`, `eyebrow`, `section-kicker`: informatiehiërarchie.
- `stat-card`, `panel`, `tonal-panel`, `result-card`: tonale contentlagen.
- `pill-*`, `status-beacon`: status met zichtbare tekst naast kleur.
- `intelligence-score`, `hero-score`, `score-components`: match en datakwaliteit als afzonderlijke begrippen.
- `filter-console`, `active-filters`: server-side filters en deelbare querystrings.
- `pipeline-board`, `activity-timeline`, `data-table-wrap`: taakgerichte datapatronen met toegankelijke fallback.
- `form-section`, `choice-field`, `profile-preview`: echte Django-formulieren met begeleide selecties en server-rendered bewijs.
- `empty-state`, `toast-stack`, fouttemplates: consistente lege, success-, fout- en onbekende staten.
## 5. Componenten
## Interactie
### Button
Vanilla JavaScript is alleen progressive enhancement voor drawer, disclosures, viewtoggle, zoekshortcut en thema. Alle links, filters, formulieren, statuswijzigingen en mutaties werken server-side. Motion is functioneel, kort en uitgeschakeld via `prefers-reduced-motion`.
Varianten:
## Reviewchecklist
- primary — één primaire actie per context;
- secondary — normale navigatie/opslaan;
- ghost — lage nadruk;
- danger — destructief met bevestiging;
- compact icon+label — vacaturefeedback.
States: hover, focus-visible, active, disabled, busy. Disabled blijft leesbaar en verklaarbaar.
### Badge/status pill
Bevat altijd tekst. Rollen: strong, possible, weak, hidden, active, review, deny, quarantined, expired. Gebruik niet alleen rood/groen.
### Card
Semantische header/body/footer. Hele kaart niet klikbaar wanneer er meerdere interne acties zijn; titel/link is de primaire link.
### Score
Score = getal/100 + recommendationtekst. Confidence wordt als “Datakwaliteit hoog/middel/laag” of exact percentage in detail getoond. Geen cirkeldiagram nodig voor één waarde.
### Form
- label boven veld;
- hint vóór fout;
- fout gekoppeld via `aria-describedby`;
- required expliciet;
- JSON-achtige lijstvelden uiteindelijk vervangen door chips/multi-select;
- opslaan bevestigt, maar verliest scroll/focus niet onnodig.
### Alert
Info/success/warning/error met icoon, titel en tekst. Alerts zijn `role=status` of `role=alert` afhankelijk van urgentie.
### Table/list
Kolomkoppen semantisch; op mobiel cards of stacked definition list. Actiekolom niet te breed.
## 6. Motion
- alleen functionele transities 120200ms;
- respecteer `prefers-reduced-motion`;
- geen automatische carrousels, pulserende scores of decoratieve parallax.
## 7. Iconen
Gebruik eenvoudige inline SVG's met `aria-hidden=true` naast zichtbare tekst. Geen externe iconfont. Een icon-only button vereist accessible label/tooltips.
## 8. Datavisualisatie
Gebruik balken voor scorecomponenten met numerieke tekst. Kleur ondersteunt, maar label/waarde draagt betekenis. Grafieken zijn niet nodig zolang data laag-volume is.
## 9. Designreviewchecklist
- primaire taak binnen één scherm duidelijk;
- geen ruwe technische identifiers in dagelijkse UI;
- empty/error/loading states aanwezig;
- focusvolgorde logisch;
- contrast en zoom 200% gecontroleerd;
- mobiel 320px breed bruikbaar;
- lange titels/werkgevers/URL's breken veilig;
- Nederlands consistent;
- scoreverklaring niet verstopt achter kleur.
- één duidelijke primaire taak en één `h1` per pagina;
- echte data of expliciet “Niet gemeten/Onbekend/Niet geconfigureerd”;
- geen controls zonder serveractie;
- consistente focusring, tekstlabels en minimaal bruikbare touch targets;
- reflow zonder documentoverflow op 360 px en dynamische benutting tot 2560 px;
- lange Nederlandse labels, werkgeversnamen en URL's breken veilig;
- geen externe runtimeassets, oude shell of parallel frontendpad.