docs: architectuurdocs, styleguides en release notes intake/behandelplan
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
433
docs/styleguide-ux.md
Normal file
433
docs/styleguide-ux.md
Normal 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).*
|
||||
Reference in New Issue
Block a user