docs: architectuurdocs, styleguides en release notes intake/behandelplan

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
colinislit
2026-07-09 23:16:28 +02:00
parent 9195eb9fed
commit c0a4fa24f2
15 changed files with 12143 additions and 0 deletions

433
docs/styleguide-ux.md Normal file
View File

@@ -0,0 +1,433 @@
# Mini-EPD Style Guide & UX
> Geëxtraheerd uit de mini-epd-prototype codebase. Gebruik dit document om dezelfde look & feel in een ander project toe te passen.
---
## 1. Tech Stack & Tooling
| Categorie | Keuze | Versie |
|---|---|---|
| Framework | Next.js (App Router) | 14.2 |
| Taal | TypeScript | 5.x |
| Styling | Tailwind CSS | 3.4 |
| Component variants | `class-variance-authority` (CVA) | 0.7 |
| Class merging | `tailwind-merge` | 3.4 |
| Animaties | `tailwindcss-animate` + Framer Motion | 1.0 / 12.x |
| UI primitives | Radix UI | diverse |
| Iconen | Lucide React | 0.553 |
| State management | Zustand | 5.x |
| Formulieren | React Hook Form + Zod | 7.x / 4.x |
| Rich text | TipTap | 3.x |
### Utility helper
```ts
// lib/utils.ts
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
```
---
## 2. Kleurensysteem
### 2.1 Basiskleuren
| Token | Hex | Gebruik |
|---|---|---|
| `app-background` | `#F8FAFC` | Pagina-achtergrond (slate-50) |
| `surface` | `#FFFFFF` | Cards, panels |
| `surface-sub` | `#F1F5F9` | Secundaire achtergrond (slate-100) |
| `text-primary` | `#0F172A` | Primaire tekst (slate-900) |
| `text-secondary` | `#475569` | Secundaire/meta-tekst (slate-600) |
| `border` | `#E2E8F0` | Standaard borders (slate-200) |
### 2.2 Brand (Teal-first)
De primaire brandkleur is **teal**. Alle interactieve elementen, focus-states en links gebruiken deze kleur.
| Token | Hex | Ratio | Gebruik |
|---|---|---|---|
| `brand-50` | `#F0FDFA` | — | Subtiele achtergrond |
| `brand-100` | `#CCFBF1` | — | Info-subtiel |
| `brand-200` | `#99F6E4` | — | Lichte tint |
| `brand-400` | `#2DD4BF` | — | Decoratief |
| `brand-500` | `#14B8A6` | — | Accent |
| `brand-600` | `#0D9488` | 3:1 | UI-componenten (non-text) |
| **`brand-700`** | **`#0F766E`** | **5.47:1** | **Primaire tekst & CTA (WCAG AA) ✓** |
| `brand-800` | `#115E59` | — | Hover state |
| `brand-900` | `#134E4A` | — | Donkerste tint |
```css
/* CSS custom properties */
--color-brand: #0F766E;
--color-brand-hover: #115E59;
--color-brand-active: #0D9488;
--color-brand-subtle: #F0FDFA;
```
### 2.3 AI Features (Amber)
AI-gerelateerde acties worden visueel onderscheiden door een **amber** kleurenpalet.
| Token | Hex | Gebruik |
|---|---|---|
| `ai-50` | `#FFFBEB` | Subtiele AI-achtergrond |
| `ai-500` | `#F59E0B` | Primaire AI-kleur |
| `ai-600` | `#D97706` | AI-tekst (WCAG AA large) |
| `ai-700` | `#B45309` | AI hover |
### 2.4 Module-accenten
Verschillende modules hebben een eigen kleurig accent:
| Module | Achtergrond | Accent | Border |
|---|---|---|---|
| Afspraken | `#E8F8EF` | `#16A34A` (groen) | `#CDECDC` |
| Medicatie | `#FEF6DC` | `#F59E0B` (amber) | `#F6E7B6` |
| Lab | `#FFEBDC` | `#F97316` (oranje) | `#FFD2B8` |
### 2.5 Status & Feedback
| Status | Kleur | Subtiel |
|---|---|---|
| Success | `#16A34A` | `#ECFDF5` |
| Warning | `#EAB308` | `#FEFCE8` |
| Error | `#DC2626` | `#FEF2F2` |
| Info | `#0F766E` (teal) | `#CCFBF1` |
### 2.6 Severity Badges (DSM-light)
| Ernst | Achtergrond | Tekst |
|---|---|---|
| Low | `#E5E7EB` | `#374151` |
| Medium | `#FEF3C7` | `#92400E` |
| High | `#FEE2E2` | `#991B1B` |
### 2.7 Dark Mode
Dark mode is optioneel geïmplementeerd (MVP = licht thema):
```css
.dark {
--color-bg: #0a0a0a;
--color-surface: #1a1a1a;
--color-text: #ededed;
--color-text-secondary: #a1a1a1;
--color-border: #333333;
}
```
---
## 3. Typografie
### 3.1 Font Families
Drie fonts worden lokaal geladen via `next/font/local`:
| Variabele | Font | Gewichten | Gebruik |
|---|---|---|---|
| `--font-serif` | **Lora** | 400, 400i, 600 | Long-form content, manifesto teksten |
| `--font-sans` | **Roboto** | 400, 500, 600 (+italic) | UI, navigatie, metadata, body |
| `--font-mono` | **Source Code Pro** | 400, 600 | Code, technische details, nummers |
**Body default:** `var(--font-sans), system-ui, -apple-system, sans-serif`
### 3.2 Typografische Schaal
| Token | Waarde | Toepassing |
|---|---|---|
| `--text-hero` | `clamp(2.5rem, 6vw, 4rem)` | Hero quotes |
| `--text-h1` | `clamp(2rem, 5vw, 3rem)` | Sectie-koppen |
| `--text-h2` | `clamp(1.5rem, 4vw, 2.5rem)` | Subsecties |
| `--text-body` | `1.25rem` | Content, lopende tekst |
| `--text-small` | `0.875rem` | Metadata, labels |
### 3.3 Line Heights
| Token | Waarde | Gebruik |
|---|---|---|
| `--line-height-tight` | `1.2` | Headings |
| `--line-height-relaxed` | `1.8` | Body/content |
---
## 4. Shadows & Border Radius
### Shadows
| Token | Waarde |
|---|---|
| `shadow-sm` | `0 1px 2px rgba(15,23,42,0.06)` |
| `shadow-md` | `0 2px 6px rgba(15,23,42,0.08)` |
| `shadow-lg` | `0 8px 20px rgba(15,23,42,0.10)` |
> Alle shadows zijn gebaseerd op **slate-900** alpha — geen hard zwart.
### Border Radius
| Token | Waarde |
|---|---|
| `--radius` | `0.625rem` (10px) |
| `rounded-lg` | `var(--radius)` |
| `rounded-md` | `calc(var(--radius) - 2px)` ≈ 8px |
| `rounded-sm` | `calc(var(--radius) - 4px)` ≈ 6px |
---
## 5. Formulieren
| State | Property | Waarde |
|---|---|---|
| Default | bg | `#FFFFFF` |
| Default | border | `#CBD5E1` |
| Default | tekst | `#0F172A` |
| Placeholder | kleur | `#94A3B8` |
| Hover | border | `#94A3B8` |
| Focus | ring/border | `#0F766E` (teal-700) |
| Disabled | bg | `#F1F5F9` |
| Disabled | tekst | `#94A3B8` |
| Invalid | border | `#DC2626` |
| Invalid | tekst | `#B91C1C` |
**Input component patroon:**
```tsx
<input className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1
text-base shadow-sm transition-colors placeholder:text-muted-foreground
focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring
disabled:cursor-not-allowed disabled:opacity-50 md:text-sm" />
```
---
## 6. Component Patronen
### 6.1 Component Architectuur
- Alle componenten gebruiken **`React.forwardRef`** voor ref-forwarding
- Varianten via **`class-variance-authority`** (CVA)
- Styling via Tailwind classes + `cn()` utility
- Radix UI als headless primitives (Dialog, Tabs, Select, Popover, etc.)
- **Default = server component**; `"use client"` alleen wanneer interactiviteit vereist is
### 6.2 Button
| Variant | Stijl |
|---|---|
| `default` | `bg-primary text-primary-foreground hover:bg-primary/90` |
| `destructive` | `bg-destructive text-destructive-foreground hover:bg-destructive/90` |
| `outline` | `border border-input bg-background hover:bg-accent` |
| `secondary` | `bg-secondary text-secondary-foreground hover:bg-secondary/80` |
| `ghost` | `hover:bg-accent hover:text-accent-foreground` |
| `link` | `text-primary underline-offset-4 hover:underline` |
| Size | Afmetingen |
|---|---|
| `default` | `h-10 px-4 py-2` |
| `sm` | `h-9 px-3` |
| `lg` | `h-11 px-8` |
| `icon` | `h-10 w-10` |
### 6.3 AI Button
Speciaal component voor AI-acties. Visueel onderscheiden door **amber gradient**.
| Variant | Stijl |
|---|---|
| `default` | Amber gradient (`from-amber-600 to-amber-700`) + witte tekst |
| `outline` | `border-2 border-amber-500`, tekst `amber-700` |
| `ghost` | Transparant, tekst `amber-700`, hover `amber-50` |
Features:
- Sparkle-icoon (✨) als visuele AI-indicator
- Loading state met `Loader2` spinner
- Drie maten: `sm`, `md`, `lg`
### 6.4 Card
```
┌─────────────────────────────┐
│ CardHeader (p-6) │
│ CardTitle (semibold) │
│ CardDescription (muted) │
│ CardContent (p-6 pt-0) │
│ CardFooter (p-6 pt-0) │
└─────────────────────────────┘
```
- `rounded-xl`, `border`, `bg-card`, `shadow`
### 6.5 Badge
Varianten: `default`, `secondary`, `destructive`, `outline`
Base: `rounded-md`, `px-2.5 py-0.5`, `text-xs font-semibold`
### 6.6 Tabs
- `TabsList`: `rounded-lg bg-muted p-1`
- `TabsTrigger`: `rounded-md px-3 py-1 text-sm font-medium`
- Active state: `bg-background text-foreground shadow`
### 6.7 Toast
- Positie: top op mobile, bottom-right op desktop
- Swipe-to-dismiss ondersteuning
- Slide-in animatie (top op mobile, bottom op desktop)
- Varianten: `default` en `destructive`
---
## 7. Layout & Navigatie
### 7.1 App Shell
```
┌──────────────────────────────────────┐
│ ┌──────────┐ ┌─────────────────────┐ │
│ │ │ │ │ │
│ │ Sidebar │ │ Main Content │ │
│ │ (fixed) │ │ (scrollable) │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ └──────────┘ └─────────────────────┘ │
└──────────────────────────────────────┘
```
- **Container**: `min-h-screen bg-slate-50 flex`
- **Sidebar**: fixed, `w-78` open / `w-28` collapsed
- **Main content**: flex-grow, scrollable
### 7.2 Sidebar UX
| Eigenschap | Waarde |
|---|---|
| Desktop breedte (open) | `w-78` (312px) |
| Desktop breedte (collapsed) | `w-28` (112px) |
| Achtergrond | `bg-white` |
| Border | `border-r border-slate-200` |
| Transition | `duration-300 ease-in-out` |
| Mobile | Full overlay met `bg-black/40 backdrop-blur-sm` |
**Active nav item**: `bg-teal-50 text-teal-700` + icoon `text-teal-600`
**Inactive nav item**: `text-slate-600 hover:bg-slate-50 hover:text-slate-900`
**Collapsed state**: tooltips verschijnen links met een pijl-indicator (`bg-slate-800 text-white`)
**Profiel sectie**: avatar cirkel, naam, rol, online-indicator (`bg-green-500` dot)
**Logout**: `text-red-600 hover:bg-red-50`
---
## 8. Animaties
### 8.1 Float Animatie
Subtiele zweef-animatie voor badges of decoratieve elementen:
```css
@keyframes float {
0%, 100% { transform: translateY(0px) rotate(0deg); }
25% { transform: translateY(-5px) rotate(0.5deg); }
50% { transform: translateY(-3px) rotate(-0.5deg); }
75% { transform: translateY(-7px) rotate(0.3deg); }
}
.animate-float { animation: float 5s ease-in-out infinite; }
```
### 8.2 Artifact Slide-in
Panel slide-in van rechts:
```css
@keyframes artifact-enter {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
.artifact-enter { animation: artifact-enter 200ms ease-out; }
```
### 8.3 Transition Defaults
- Navigatie / sidebar: `transition-all duration-300 ease-in-out`
- Buttons / interactie: `transition-colors` of `transition-all duration-200`
- Toasts: slide-in + fade via `tailwindcss-animate`
### 8.4 Reduced Motion
Volledige `prefers-reduced-motion` ondersteuning:
```css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.02ms !important;
transition-duration: 0.03ms !important;
scroll-behavior: auto !important;
}
}
```
---
## 9. Toegankelijkheid (A11y)
| Aspect | Implementatie |
|---|---|
| Focus indicator | `outline: 2px solid var(--color-brand)`, `outline-offset: 2px` |
| Focus ring (components) | `ring-2 ring-ring ring-offset-2` |
| Skip to main | Verborgen link, zichtbaar bij focus |
| Kleurcontrast | Brand teal-700 = 5.47:1 op wit (WCAG AA ✓) |
| ARIA labels | Alle interactieve elementen (toggle buttons, sidebar) |
| Reduced motion | Alle animaties gerespecteerd |
| Iconen | `aria-hidden="true"` op decoratieve iconen |
| Taal | `<html lang="nl">` |
---
## 10. AI UX Conventies
AI-functies worden visueel onderscheiden van standaard UI:
| Element | Conventie |
|---|---|
| Kleur | Amber-palet (geel/goud), nooit teal |
| Button | `AIButton` component met Sparkle-icoon (✨) |
| Highlight | `.ai-source-highlight` — lichtgeel (`#fef08a`) met `border-radius: 2px` |
| Loading | `Loader2` spinner (animatie: `animate-spin`) |
| Feedback | Confidence indicators bij AI-gegenereerde content |
---
## 11. Quick-Start Checklist
Om deze stijl in een nieuw project over te nemen:
1. **Installeer dependencies:**
```bash
pnpm add class-variance-authority clsx tailwind-merge tailwindcss-animate
pnpm add lucide-react framer-motion
pnpm add @radix-ui/react-dialog @radix-ui/react-tabs @radix-ui/react-select
# + overige Radix primitives naar behoefte
```
2. **Kopieer fonts** (Lora, Roboto, Source Code Pro) naar `public/fonts/` en configureer in `layout.tsx`
3. **Kopieer CSS custom properties** uit `globals.css` (sectie `:root`)
4. **Kopieer Tailwind config** — met name `colors`, `boxShadow`, `borderRadius` extensies
5. **Kopieer `cn()` utility** naar `lib/utils.ts`
6. **Kopieer UI components** uit `components/ui/` (shadcn-patroon met CVA)
7. **Zet `antialiased`** op de `<body>` tag
8. **Zet `lang="nl"`** op de `<html>` tag
---
*Gegenereerd op basis van de mini-epd-prototype codebase (maart 2026).*