# Conflicts: # .gitignore # AGENTS.md # CLAUDE.md # README.md # docs/API.md # docs/MD3_Color_Scheme_Documentation.md # docs/api.md # docs/api/rest-contract.md # docs/architecture.md # docs/backlog.md # docs/backlog/index.md # docs/backlog/product-historical.md # docs/decisions/agent-instructions-history.md # docs/design/styling.md # docs/functional.md # docs/md3-color-scheme.md # docs/patterns/claude-question-channel.md # docs/patterns/dialog.md # docs/patterns/qr-login.md # docs/personas.md # docs/plans/M10-qr-pairing-login.md # docs/plans/M11-claude-questions.md # docs/plans/M9-active-product-backlog.md # docs/plans/ST-1114-copilot-reviews.md # docs/plans/tweede-claude-agent-planning.md # docs/product-backlog.md # docs/qa/api-test-plan.md # docs/scrum4me-backlog.md # docs/scrum4me-functional-spec.md # docs/scrum4me-personas.md # docs/scrum4me-product-backlog.md # docs/scrum4me-test-plan.md # docs/solo-paneel-spec.md # docs/specs/functional.md # docs/specs/personas.md # docs/styling.md # docs/test-plan.md
1601 lines
43 KiB
Markdown
1601 lines
43 KiB
Markdown
---
|
||
title: "Scrum4Me — Styling & Design System"
|
||
status: active
|
||
audience: [ai-agent, contributor]
|
||
language: nl
|
||
last_updated: 2026-05-03
|
||
---
|
||
|
||
# Scrum4Me — Styling & Design System
|
||
|
||
**Versie:** 0.1 — april 2026
|
||
**Onderdeel van:** CLAUDE.md context-set
|
||
|
||
---
|
||
|
||
## Overzicht
|
||
|
||
Scrum4Me gebruikt **Material Design 3 (MD3)** als kleurfilosofie, geïmplementeerd via CSS custom properties in `theme.css` en direct bruikbaar als Tailwind utility classes. **shadcn/ui** levert alle UI-primitieven (Button, Dialog, Sheet, Badge, etc.) en is volledig compatibel met het MD3-kleurensysteem via de legacy-token-mapping.
|
||
|
||
Lees dit document voordat je een component schrijft. Gebruik **nooit** willekeurige Tailwind-kleuren zoals `bg-blue-500` of `bg-green-600` — gebruik altijd de semantische tokens uit dit systeem.
|
||
|
||
---
|
||
|
||
## Setup
|
||
|
||
### 1. theme.css plaatsen
|
||
|
||
Kopieer het meegeleverde `theme.css` bestand naar:
|
||
|
||
```
|
||
app/globals.css ← importeer theme.css hier, of plak de inhoud direct
|
||
```
|
||
|
||
Of als apart bestand:
|
||
```
|
||
styles/theme.css
|
||
```
|
||
|
||
Importeer in `app/globals.css`:
|
||
```css
|
||
@import './styles/theme.css';
|
||
```
|
||
|
||
### 2. shadcn/ui initialiseren
|
||
|
||
```bash
|
||
npx shadcn@latest init
|
||
```
|
||
|
||
Kies bij de setup:
|
||
- Style: **Default**
|
||
- Base color: **Slate** (wordt overschreven door theme.css)
|
||
- CSS variables: **Yes**
|
||
|
||
De `theme.css` overschrijft alle shadcn default-kleuren via CSS custom properties. Geen extra configuratie nodig.
|
||
|
||
### 3. Tailwind configuratie
|
||
|
||
`theme.css` registreert alle tokens via `@theme inline` — ze zijn direct beschikbaar als Tailwind utility classes:
|
||
|
||
```tsx
|
||
// Werkt direct:
|
||
className="bg-primary text-primary-foreground"
|
||
className="bg-surface-container-low"
|
||
className="bg-status-done"
|
||
className="bg-priority-critical"
|
||
```
|
||
|
||
### 4. Dark mode
|
||
|
||
Dark mode werkt via de `.dark` class op `<html>`:
|
||
|
||
```tsx
|
||
// components/theme-toggle.tsx
|
||
'use client'
|
||
import { useState, useEffect } from 'react'
|
||
|
||
export function ThemeToggle() {
|
||
const [isDark, setIsDark] = useState(false)
|
||
|
||
useEffect(() => {
|
||
const stored = localStorage.getItem('theme')
|
||
if (stored === 'dark') {
|
||
document.documentElement.classList.add('dark')
|
||
setIsDark(true)
|
||
}
|
||
}, [])
|
||
|
||
const toggle = () => {
|
||
document.documentElement.classList.toggle('dark')
|
||
const next = !isDark
|
||
setIsDark(next)
|
||
localStorage.setItem('theme', next ? 'dark' : 'light')
|
||
}
|
||
|
||
return (
|
||
<button onClick={toggle} className="text-muted-foreground hover:text-foreground">
|
||
{isDark ? '☀️' : '🌙'}
|
||
</button>
|
||
)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Kleurfilosofie
|
||
|
||
Drie hoofdrollen, elk met een semantische betekenis voor een Scrum-planner:
|
||
|
||
| Rol | Kleur | Betekenis | Gebruik in Scrum4Me |
|
||
|---|---|---|---|
|
||
| **Primary** | Blauw `#0061a4` | Productiviteit, vertrouwen | Primaire knoppen, actieve navigatie, Sprint Goal |
|
||
| **Secondary** | Paars `#5b5e71` | Planning, organisatie | Secundaire acties, filters, toolbar-items |
|
||
| **Tertiary** | Teal `#006874` | Voortgang, data | Voortgangsindicatoren, story-tellers, metrics |
|
||
|
||
Diepte wordt gecreëerd via **tonal elevation** (lichtere/donkerdere oppervlakken), niet via schaduwen.
|
||
|
||
---
|
||
|
||
## Surface Elevation System
|
||
|
||
Gebruik deze hiërarchie consequent — nooit `shadow-lg` voor diepte:
|
||
|
||
```
|
||
HOOGSTE ELEVATIE (voorgrond)
|
||
surface-container-lowest → dialogs, modals, popovers
|
||
surface-container-low → kaarten, panelen
|
||
surface-container → standaard container
|
||
surface-container-high → geneste containers
|
||
surface-container-highest → achtergrondcontainers
|
||
LAAGSTE ELEVATIE (achtergrond)
|
||
background → app-achtergrond
|
||
```
|
||
|
||
### In Scrum4Me specifiek
|
||
|
||
| Element | Surface token |
|
||
|---|---|
|
||
| App achtergrond | `bg-background` |
|
||
| Navigatiebalk | `bg-surface-container-low` |
|
||
| Gesplitst scherm (elk paneel) | `bg-surface-container-low` |
|
||
| PBI-rij | `bg-surface-container` |
|
||
| Geselecteerde PBI-rij | `bg-primary-container` |
|
||
| Story-blok | `bg-surface-container-low border border-border` |
|
||
| Story-blok (geselecteerd) | `bg-primary-container border border-primary` |
|
||
| Taakregel | `bg-surface-container` |
|
||
| Dialogs / modals | `bg-surface-container-lowest` |
|
||
| Slide-over (story detail) | `bg-surface-container-lowest` |
|
||
| Todo-item | `bg-surface-container` |
|
||
| Navigatiebar per paneel | `bg-surface-container-highest` |
|
||
|
||
---
|
||
|
||
## Statuskleur mapping
|
||
|
||
### Story- en taakstatus
|
||
|
||
Gebruik **altijd** icoon + tekst naast kleur (toegankelijkheid):
|
||
|
||
```tsx
|
||
// Status badge component
|
||
const statusConfig = {
|
||
OPEN: {
|
||
label: 'Open',
|
||
className: 'bg-status-todo text-white',
|
||
},
|
||
IN_SPRINT: {
|
||
label: 'In Sprint',
|
||
className: 'bg-status-in-progress text-white',
|
||
},
|
||
DONE: {
|
||
label: 'Done',
|
||
className: 'bg-status-done text-white',
|
||
},
|
||
}
|
||
|
||
// Taakstatus
|
||
const taskStatusConfig = {
|
||
TO_DO: {
|
||
label: 'To Do',
|
||
className: 'bg-status-todo text-white',
|
||
},
|
||
IN_PROGRESS: {
|
||
label: 'In Progress',
|
||
className: 'bg-status-in-progress text-white',
|
||
},
|
||
DONE: {
|
||
label: 'Done',
|
||
className: 'bg-status-done text-white',
|
||
},
|
||
}
|
||
```
|
||
|
||
### Prioriteitskleur mapping
|
||
|
||
```tsx
|
||
const priorityConfig = {
|
||
1: {
|
||
label: 'Kritiek',
|
||
className: 'bg-priority-critical text-white',
|
||
borderClassName: 'border-l-4 border-priority-critical',
|
||
},
|
||
2: {
|
||
label: 'Hoog',
|
||
className: 'bg-priority-high text-white',
|
||
borderClassName: 'border-l-4 border-priority-high',
|
||
},
|
||
3: {
|
||
label: 'Middel',
|
||
className: 'bg-priority-medium text-white',
|
||
borderClassName: 'border-l-4 border-priority-medium',
|
||
},
|
||
4: {
|
||
label: 'Laag',
|
||
className: 'bg-priority-low text-white',
|
||
borderClassName: 'border-l-4 border-priority-low',
|
||
},
|
||
}
|
||
```
|
||
|
||
### Story-activiteitenlog
|
||
|
||
```tsx
|
||
const logTypeConfig = {
|
||
IMPLEMENTATION_PLAN: {
|
||
label: 'Implementatieplan',
|
||
className: 'bg-info-container text-info-container-foreground border-l-4 border-info',
|
||
},
|
||
TEST_RESULT: {
|
||
PASSED: {
|
||
label: 'Tests geslaagd',
|
||
className: 'bg-success-container text-success-container-foreground border-l-4 border-success',
|
||
},
|
||
FAILED: {
|
||
label: 'Tests mislukt',
|
||
className: 'bg-error-container text-error-container-foreground border-l-4 border-error',
|
||
},
|
||
},
|
||
COMMIT: {
|
||
label: 'Commit',
|
||
className: 'bg-secondary-container text-secondary-container-foreground border-l-4 border-secondary',
|
||
},
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## shadcn/ui componenten — gebruik in Scrum4Me
|
||
|
||
Alle shadcn-componenten gebruiken automatisch het MD3-kleurensysteem. Hieronder de aanbevolen varianten per context.
|
||
|
||
### Button
|
||
|
||
```tsx
|
||
import { Button } from '@/components/ui/button'
|
||
|
||
// Primaire actie (Sprint starten, PBI aanmaken, Opslaan)
|
||
<Button>Sprint starten</Button>
|
||
|
||
// Secundaire actie (Annuleren, Filters, Exporteren)
|
||
<Button variant="secondary">Annuleren</Button>
|
||
|
||
// Destructieve actie (Verwijderen, Archiveren)
|
||
<Button variant="destructive">Verwijderen</Button>
|
||
|
||
// Ghost (icon-knoppen in navigatiebar)
|
||
<Button variant="ghost" size="icon">
|
||
<PlusIcon className="h-4 w-4" />
|
||
</Button>
|
||
|
||
// Outline (minder urgente acties)
|
||
<Button variant="outline">Details bekijken</Button>
|
||
```
|
||
|
||
### Badge (status en prioriteit)
|
||
|
||
```tsx
|
||
import { Badge } from '@/components/ui/badge'
|
||
|
||
// Gebruik custom className voor MD3-kleuren
|
||
// shadcn Badge variant="secondary" is ook bruikbaar voor neutrale badges
|
||
|
||
<Badge className="bg-status-done text-white">Done</Badge>
|
||
<Badge className="bg-priority-critical text-white">Kritiek</Badge>
|
||
<Badge className="bg-status-in-progress text-white">In Sprint</Badge>
|
||
|
||
// Neutrale info badge (bijv. "3 taken")
|
||
<Badge variant="secondary">3 taken</Badge>
|
||
```
|
||
|
||
**PBI-status (READY / BLOCKED / DONE):** hergebruikt bestaande tokens —
|
||
`status-todo` voor READY, `status-blocked` voor BLOCKED, `status-done` voor
|
||
DONE. Centraal gedefinieerd in `components/shared/pbi-status-select.tsx`
|
||
(`PBI_STATUS_LABELS`, `PBI_STATUS_COLORS`); importeer die in plaats van
|
||
kleuren ad-hoc te kopiëren.
|
||
|
||
### Dialog (bevestigingsdialogen)
|
||
|
||
```tsx
|
||
import {
|
||
AlertDialog,
|
||
AlertDialogAction,
|
||
AlertDialogCancel,
|
||
AlertDialogContent,
|
||
AlertDialogDescription,
|
||
AlertDialogFooter,
|
||
AlertDialogHeader,
|
||
AlertDialogTitle,
|
||
} from '@/components/ui/alert-dialog'
|
||
|
||
// Standaard bevestigingsdialoog voor verwijderacties
|
||
<AlertDialogContent className="bg-surface-container-lowest">
|
||
<AlertDialogHeader>
|
||
<AlertDialogTitle>PBI verwijderen?</AlertDialogTitle>
|
||
<AlertDialogDescription>
|
||
Dit verwijdert ook alle gekoppelde stories en taken. Deze actie is niet ongedaan te maken.
|
||
</AlertDialogDescription>
|
||
</AlertDialogHeader>
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel>Annuleren</AlertDialogCancel>
|
||
<AlertDialogAction className="bg-destructive text-destructive-foreground">
|
||
Verwijderen
|
||
</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
```
|
||
|
||
### Sheet (story detail slide-over)
|
||
|
||
```tsx
|
||
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'
|
||
|
||
<Sheet>
|
||
<SheetContent
|
||
side="right"
|
||
className="w-[480px] bg-surface-container-lowest border-l border-border"
|
||
>
|
||
<SheetHeader>
|
||
<SheetTitle className="text-foreground">{story.title}</SheetTitle>
|
||
</SheetHeader>
|
||
{/* story detail inhoud */}
|
||
</SheetContent>
|
||
</Sheet>
|
||
```
|
||
|
||
### Input en Textarea
|
||
|
||
```tsx
|
||
import { Input } from '@/components/ui/input'
|
||
import { Textarea } from '@/components/ui/textarea'
|
||
|
||
// shadcn Input gebruikt --input-background automatisch uit theme.css
|
||
<Input
|
||
placeholder="PBI titel"
|
||
className="bg-input-background border-border focus:ring-primary"
|
||
/>
|
||
|
||
<Textarea
|
||
placeholder="Omschrijving (optioneel)"
|
||
className="bg-input-background border-border focus:ring-primary resize-none"
|
||
/>
|
||
```
|
||
|
||
### Select (prioriteit dropdown)
|
||
|
||
```tsx
|
||
import {
|
||
Select,
|
||
SelectContent,
|
||
SelectItem,
|
||
SelectTrigger,
|
||
SelectValue,
|
||
} from '@/components/ui/select'
|
||
|
||
<Select>
|
||
<SelectTrigger className="bg-input-background border-border">
|
||
<SelectValue placeholder="Prioriteit" />
|
||
</SelectTrigger>
|
||
<SelectContent className="bg-surface-container-lowest border-border">
|
||
<SelectItem value="1">
|
||
<span className="flex items-center gap-2">
|
||
<span className="w-2 h-2 rounded-full bg-priority-critical" />
|
||
Kritiek
|
||
</span>
|
||
</SelectItem>
|
||
<SelectItem value="2">
|
||
<span className="flex items-center gap-2">
|
||
<span className="w-2 h-2 rounded-full bg-priority-high" />
|
||
Hoog
|
||
</span>
|
||
</SelectItem>
|
||
<SelectItem value="3">
|
||
<span className="flex items-center gap-2">
|
||
<span className="w-2 h-2 rounded-full bg-priority-medium" />
|
||
Middel
|
||
</span>
|
||
</SelectItem>
|
||
<SelectItem value="4">
|
||
<span className="flex items-center gap-2">
|
||
<span className="w-2 h-2 rounded-full bg-priority-low" />
|
||
Laag
|
||
</span>
|
||
</SelectItem>
|
||
</SelectContent>
|
||
</Select>
|
||
```
|
||
|
||
### Skeleton (loading states)
|
||
|
||
```tsx
|
||
import { Skeleton } from '@/components/ui/skeleton'
|
||
|
||
// PBI lijst skeleton
|
||
function PbiListSkeleton() {
|
||
return (
|
||
<div className="space-y-2 p-4">
|
||
{Array.from({ length: 5 }).map((_, i) => (
|
||
<Skeleton key={i} className="h-12 w-full bg-surface-container-high" />
|
||
))}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// Story blokken skeleton
|
||
function StoryGridSkeleton() {
|
||
return (
|
||
<div className="flex flex-wrap gap-3 p-4">
|
||
{Array.from({ length: 6 }).map((_, i) => (
|
||
<Skeleton key={i} className="h-24 w-[10%] min-w-[100px] bg-surface-container-high" />
|
||
))}
|
||
</div>
|
||
)
|
||
}
|
||
```
|
||
|
||
### Tooltip (demo-gebruiker write-protection)
|
||
|
||
```tsx
|
||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||
|
||
// Gebruik voor alle uitgeschakelde knoppen bij demo-gebruiker
|
||
function DemoProtectedButton({ children, isDemo, onClick, ...props }) {
|
||
if (!isDemo) {
|
||
return <Button onClick={onClick} {...props}>{children}</Button>
|
||
}
|
||
|
||
return (
|
||
<TooltipProvider>
|
||
<Tooltip>
|
||
<TooltipTrigger asChild>
|
||
<span>
|
||
<Button disabled {...props}>{children}</Button>
|
||
</span>
|
||
</TooltipTrigger>
|
||
<TooltipContent className="bg-surface-container-lowest border-border">
|
||
<p className="text-sm text-muted-foreground">Niet beschikbaar in demo-modus</p>
|
||
</TooltipContent>
|
||
</Tooltip>
|
||
</TooltipProvider>
|
||
)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Scrum4Me component patronen
|
||
|
||
### PBI-rij
|
||
|
||
```tsx
|
||
// Geselecteerd PBI heeft primary-container achtergrond
|
||
<div
|
||
className={cn(
|
||
"flex items-center gap-3 px-4 py-3 rounded-lg cursor-pointer transition-colors border-l-4",
|
||
priorityConfig[pbi.priority].borderClassName,
|
||
isSelected
|
||
? "bg-primary-container text-primary-container-foreground"
|
||
: "bg-surface-container hover:bg-surface-container-high"
|
||
)}
|
||
onClick={() => setSelectedPbi(pbi.id)}
|
||
>
|
||
<span className="flex-1 text-sm font-medium truncate">{pbi.title}</span>
|
||
<Badge className={priorityConfig[pbi.priority].className}>
|
||
{priorityConfig[pbi.priority].label}
|
||
</Badge>
|
||
</div>
|
||
```
|
||
|
||
### Story-blok
|
||
|
||
```tsx
|
||
// ~10% schermbreedte, compacte weergave
|
||
<div
|
||
className={cn(
|
||
"relative flex flex-col gap-1 p-3 rounded-lg border cursor-pointer",
|
||
"min-w-[100px] w-[10%] h-24 text-xs",
|
||
"transition-colors hover:border-primary",
|
||
"bg-surface-container-low border-border"
|
||
)}
|
||
>
|
||
<span className="font-medium leading-tight line-clamp-2">{story.title}</span>
|
||
<div className="mt-auto flex items-center justify-between">
|
||
<span className={cn("px-1.5 py-0.5 rounded text-[10px] font-medium", statusConfig[story.status].className)}>
|
||
{statusConfig[story.status].label}
|
||
</span>
|
||
<span className={cn("w-2 h-2 rounded-full", `bg-priority-${priorityLabel}`)}>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### Prioriteitsgroep scheidingslijn
|
||
|
||
```tsx
|
||
// Visuele scheiding per prioriteitsgroep in PBI-lijst en story-grid
|
||
<div className="mt-4 mb-2">
|
||
<div className="flex items-center gap-2">
|
||
<span className={cn(
|
||
"text-xs font-semibold uppercase tracking-wider",
|
||
priority === 1 && "text-priority-critical",
|
||
priority === 2 && "text-priority-high",
|
||
priority === 3 && "text-priority-medium",
|
||
priority === 4 && "text-priority-low",
|
||
)}>
|
||
{priorityConfig[priority].label}
|
||
</span>
|
||
<div className={cn(
|
||
"flex-1 h-px",
|
||
priority === 1 && "bg-priority-critical/30",
|
||
priority === 2 && "bg-priority-high/30",
|
||
priority === 3 && "bg-priority-medium/30",
|
||
priority === 4 && "bg-priority-low/30",
|
||
)} />
|
||
<span className="text-xs text-muted-foreground">{count}</span>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### Voortgangsindicator (story → taken)
|
||
|
||
```tsx
|
||
// Gebruikt tertiary kleur voor voortgang
|
||
function StoryProgress({ done, total }: { done: number; total: number }) {
|
||
const pct = total === 0 ? 0 : Math.round((done / total) * 100)
|
||
|
||
return (
|
||
<div className="flex items-center gap-2 text-xs">
|
||
<div className="flex-1 h-1.5 bg-surface-container-highest rounded-full overflow-hidden">
|
||
<div
|
||
className="h-full bg-tertiary rounded-full transition-all"
|
||
style={{ width: `${pct}%` }}
|
||
/>
|
||
</div>
|
||
<span className="text-muted-foreground tabular-nums">
|
||
{done}/{total}
|
||
</span>
|
||
</div>
|
||
)
|
||
}
|
||
```
|
||
|
||
### Activiteitenlog entry
|
||
|
||
```tsx
|
||
function LogEntry({ entry }: { entry: StoryLog }) {
|
||
const config = entry.type === 'TEST_RESULT'
|
||
? logTypeConfig.TEST_RESULT[entry.status ?? 'PASSED']
|
||
: logTypeConfig[entry.type]
|
||
|
||
return (
|
||
<div className={cn("rounded-lg p-3 text-sm", config.className)}>
|
||
<div className="flex items-center justify-between mb-1">
|
||
<span className="font-medium text-xs uppercase tracking-wide">
|
||
{config.label}
|
||
</span>
|
||
<span className="text-xs opacity-70">
|
||
{formatDate(entry.created_at)}
|
||
</span>
|
||
</div>
|
||
<p className="text-sm leading-relaxed whitespace-pre-wrap">
|
||
{entry.content}
|
||
</p>
|
||
{entry.commit_hash && (
|
||
<a
|
||
href={`${repoUrl}/commit/${entry.commit_hash}`}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="mt-1 inline-flex items-center gap-1 text-xs font-mono opacity-80 hover:opacity-100 underline"
|
||
>
|
||
{entry.commit_hash.slice(0, 7)} — {entry.commit_message}
|
||
</a>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|
||
```
|
||
|
||
### Sprint Goal banner
|
||
|
||
```tsx
|
||
// Prominent bovenaan Sprint-schermen
|
||
<div className="bg-primary-container text-primary-container-foreground rounded-lg px-4 py-3 mb-4">
|
||
<span className="text-xs font-semibold uppercase tracking-wider opacity-70">
|
||
Sprint Goal
|
||
</span>
|
||
<p className="mt-0.5 font-medium">{sprint.sprint_goal}</p>
|
||
</div>
|
||
```
|
||
|
||
### Toast notificaties (Sonner)
|
||
|
||
```tsx
|
||
import { toast } from 'sonner'
|
||
|
||
// Success (aanmaken, opslaan)
|
||
toast.success('PBI aangemaakt')
|
||
toast.success('Story toegevoegd aan Sprint')
|
||
|
||
// Error (mislukte Server Action)
|
||
toast.error('Opslaan mislukt. Probeer opnieuw.')
|
||
|
||
// Info (neutrale melding)
|
||
toast.info('Sprint afgerond')
|
||
|
||
// Geen toast bij drag-and-drop (te frequent)
|
||
```
|
||
|
||
---
|
||
|
||
## Regels (nooit overtreden)
|
||
|
||
```
|
||
❌ bg-blue-500, bg-green-600, bg-red-400 → gebruik semantische tokens
|
||
❌ shadow-lg, shadow-md → gebruik surface elevation
|
||
❌ opacity-50 op een primary button → gebruik -container variant
|
||
❌ Kleur alleen voor status (geen tekst) → altijd tekst + kleur
|
||
❌ Hardcoded hex-waarden in className → altijd via CSS token
|
||
❌ bg-white of bg-black → bg-background of bg-foreground
|
||
|
||
✅ bg-primary text-primary-foreground
|
||
✅ bg-surface-container-low
|
||
✅ bg-status-done + tekst "Done"
|
||
✅ bg-error-container text-error-container-foreground
|
||
✅ border-l-4 border-priority-critical
|
||
```
|
||
|
||
---
|
||
|
||
## Bestandslocaties
|
||
|
||
```
|
||
styles/
|
||
theme.css ← bronbestand, niet aanpassen
|
||
app/
|
||
globals.css ← importeert theme.css
|
||
components/
|
||
ui/ ← shadcn/ui (auto-gegenereerd, niet aanpassen)
|
||
shared/
|
||
status-badge.tsx ← herbruikbare status badge
|
||
priority-badge.tsx ← herbruikbare prioriteit badge
|
||
demo-button.tsx ← Button met demo-protection tooltip
|
||
story-log.tsx ← activiteitenlog entries
|
||
story-progress.tsx ← voortgangsindicator
|
||
priority-group.tsx ← prioriteitsgroep scheidingslijn
|
||
```
|
||
|
||
---
|
||
|
||
## Toegankelijkheid
|
||
|
||
- Alle kleurcombinaties voldoen aan **WCAG AA** (contrast ratio ≥ 4.5:1 voor normale tekst)
|
||
- Gebruik **altijd** tekst + kleur voor statusindicatoren, nooit kleur alleen
|
||
- Alle interactieve elementen hebben een zichtbare `focus:ring-primary`
|
||
- Dark mode is volledig ondersteund via de `.dark` class
|
||
|
||
---
|
||
|
||
*Bijlage bij CLAUDE.md — lees beide voor je begint met bouwen.*
|
||
|
||
|
||
---
|
||
|
||
## MD3 Color Scheme
|
||
|
||
## Color Philosophy
|
||
|
||
This color scheme follows Material Design 3 principles with three main color roles optimized for productivity software:
|
||
|
||
- **Primary (Blue)** - Represents productivity, trust, and professionalism. Used for main actions and navigation.
|
||
- **Secondary (Purple)** - Represents planning and organization. Used for supporting UI elements.
|
||
- **Tertiary (Teal)** - Represents progress and data visualization. Used for highlights and metrics.
|
||
|
||
The system uses **tonal elevation** instead of shadows to create depth, providing a modern, clean interface suitable for extended desktop work sessions.
|
||
|
||
---
|
||
|
||
## Complete Color Palette
|
||
|
||
### Light Theme Colors
|
||
|
||
#### Primary Colors (Blue - Productivity)
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--primary` | `#0061a4` | Primary buttons, key actions |
|
||
| `--primary-foreground` | `#ffffff` | Text on primary background |
|
||
| `--primary-container` | `#d1e4ff` | Low emphasis primary elements |
|
||
| `--primary-container-foreground` | `#001d36` | Text on primary container |
|
||
|
||
#### Secondary Colors (Purple - Planning)
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--secondary` | `#5b5e71` | Secondary buttons, less critical actions |
|
||
| `--secondary-foreground` | `#ffffff` | Text on secondary background |
|
||
| `--secondary-container` | `#dfe1f9` | Low emphasis secondary elements |
|
||
| `--secondary-container-foreground` | `#181b2c` | Text on secondary container |
|
||
|
||
#### Tertiary Colors (Teal - Progress)
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--tertiary` | `#006874` | Highlights, progress indicators |
|
||
| `--tertiary-foreground` | `#ffffff` | Text on tertiary background |
|
||
| `--tertiary-container` | `#97f0ff` | Low emphasis tertiary elements |
|
||
| `--tertiary-container-foreground` | `#001f24` | Text on tertiary container |
|
||
|
||
#### Surface Colors (Elevation System)
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--background` | `#fdfcff` | Main app background |
|
||
| `--foreground` | `#1b1b1f` | Main text color |
|
||
| `--surface-container-lowest` | `#ffffff` | Highest elevation (dialogs) |
|
||
| `--surface-container-low` | `#f7f5fc` | Cards, elevated containers |
|
||
| `--surface-container` | `#f1eff6` | Default container background |
|
||
| `--surface-container-high` | `#ebeaf0` | Nested containers |
|
||
| `--surface-container-highest` | `#e6e3ea` | Lowest elevation |
|
||
|
||
#### Semantic State Colors
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--success` | `#006e1c` | Success states, completed items |
|
||
| `--success-foreground` | `#ffffff` | Text on success background |
|
||
| `--success-container` | `#92f894` | Low emphasis success |
|
||
| `--warning` | `#735b00` | Warning states, attention needed |
|
||
| `--warning-foreground` | `#ffffff` | Text on warning background |
|
||
| `--warning-container` | `#ffdf9d` | Low emphasis warning |
|
||
| `--error` | `#ba1a1a` | Error states, failures |
|
||
| `--error-foreground` | `#ffffff` | Text on error background |
|
||
| `--error-container` | `#ffdad6` | Low emphasis error |
|
||
| `--info` | `#006493` | Information, neutral alerts |
|
||
| `--info-foreground` | `#ffffff` | Text on info background |
|
||
| `--info-container` | `#c9e6ff` | Low emphasis info |
|
||
|
||
#### Project Management Specific Colors
|
||
|
||
**Work Item Status**
|
||
| Color Token | Hex Code | Status |
|
||
|-------------|----------|--------|
|
||
| `--status-todo` | `#6750a4` | Not started (Purple) |
|
||
| `--status-in-progress` | `#0061a4` | Active work (Blue) |
|
||
| `--status-done` | `#006e1c` | Completed (Green) |
|
||
| `--status-blocked` | `#ba1a1a` | Blocked/Issues (Red) |
|
||
|
||
**Priority Levels**
|
||
| Color Token | Hex Code | Priority |
|
||
|-------------|----------|----------|
|
||
| `--priority-critical` | `#ba1a1a` | Critical (Red) |
|
||
| `--priority-high` | `#c75300` | High (Orange) |
|
||
| `--priority-medium` | `#735b00` | Medium (Yellow) |
|
||
| `--priority-low` | `#006874` | Low (Teal) |
|
||
|
||
---
|
||
|
||
### Dark Theme Colors
|
||
|
||
#### Primary Colors (Blue - Productivity)
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--primary` | `#9fcbfa` | Primary buttons, key actions |
|
||
| `--primary-foreground` | `#003257` | Text on primary background |
|
||
| `--primary-container` | `#00497b` | Low emphasis primary elements |
|
||
| `--primary-container-foreground` | `#d1e4ff` | Text on primary container |
|
||
|
||
#### Secondary Colors (Purple - Planning)
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--secondary` | `#c3c4dd` | Secondary buttons |
|
||
| `--secondary-foreground` | `#2c2f42` | Text on secondary background |
|
||
| `--secondary-container` | `#434659` | Low emphasis secondary elements |
|
||
| `--secondary-container-foreground` | `#dfe1f9` | Text on secondary container |
|
||
|
||
#### Tertiary Colors (Teal - Progress)
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--tertiary` | `#4fd8eb` | Highlights, progress indicators |
|
||
| `--tertiary-foreground` | `#00363d` | Text on tertiary background |
|
||
| `--tertiary-container` | `#004f58` | Low emphasis tertiary elements |
|
||
| `--tertiary-container-foreground` | `#97f0ff` | Text on tertiary container |
|
||
|
||
#### Surface Colors (Elevation System)
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--background` | `#1b1b1f` | Main app background |
|
||
| `--foreground` | `#e4e1e9` | Main text color |
|
||
| `--surface-container-lowest` | `#0f0e13` | Highest elevation (dialogs) |
|
||
| `--surface-container-low` | `#232227` | Cards, elevated containers |
|
||
| `--surface-container` | `#27262b` | Default container background |
|
||
| `--surface-container-high` | `#322f36` | Nested containers |
|
||
| `--surface-container-highest` | `#3d3a41` | Lowest elevation |
|
||
|
||
#### Semantic State Colors
|
||
| Color Token | Hex Code | Usage |
|
||
|-------------|----------|-------|
|
||
| `--success` | `#77db77` | Success states |
|
||
| `--success-container` | `#005313` | Low emphasis success |
|
||
| `--warning` | `#efc047` | Warning states |
|
||
| `--warning-container` | `#574400` | Low emphasis warning |
|
||
| `--error` | `#ffb4ab` | Error states |
|
||
| `--error-container` | `#93000a` | Low emphasis error |
|
||
| `--info` | `#87ceff` | Information |
|
||
| `--info-container` | `#004c6d` | Low emphasis info |
|
||
|
||
#### Project Management Specific Colors (Dark)
|
||
|
||
**Work Item Status**
|
||
| Color Token | Hex Code | Status |
|
||
|-------------|----------|--------|
|
||
| `--status-todo` | `#cfbdfe` | Not started (Purple) |
|
||
| `--status-in-progress` | `#9fcbfa` | Active work (Blue) |
|
||
| `--status-done` | `#77db77` | Completed (Green) |
|
||
| `--status-blocked` | `#ffb4ab` | Blocked/Issues (Red) |
|
||
|
||
**Priority Levels**
|
||
| Color Token | Hex Code | Priority |
|
||
|-------------|----------|----------|
|
||
| `--priority-critical` | `#ffb4ab` | Critical (Red) |
|
||
| `--priority-high` | `#ffb68d` | High (Orange) |
|
||
| `--priority-medium` | `#efc047` | Medium (Yellow) |
|
||
| `--priority-low` | `#4fd8eb` | Low (Teal) |
|
||
|
||
---
|
||
|
||
## Surface Elevation System
|
||
|
||
Material Design 3 uses **tonal elevation** to create depth. Higher surfaces are lighter (in light mode) or darker (in dark mode).
|
||
|
||
### Hierarchy (from highest to lowest elevation)
|
||
|
||
1. **surface-container-lowest** - Dialogs, modals, popovers
|
||
2. **surface-container-low** - Cards, panels, elevated containers
|
||
3. **surface-container** - Default container background
|
||
4. **surface-container-high** - Nested containers, grouped elements
|
||
5. **surface-container-highest** - Background-level containers
|
||
|
||
### Tailwind Usage
|
||
|
||
```tsx
|
||
bg-surface-container-lowest
|
||
bg-surface-container-low
|
||
bg-surface-container
|
||
bg-surface-container-high
|
||
bg-surface-container-highest
|
||
```
|
||
|
||
---
|
||
|
||
## Color Roles
|
||
|
||
### Primary (Productivity & Trust)
|
||
|
||
Use for:
|
||
- Main action buttons
|
||
- Navigation highlights
|
||
- Active states
|
||
- Key interactive elements
|
||
|
||
**Examples:**
|
||
```tsx
|
||
// Filled button
|
||
<button className="bg-primary text-primary-foreground">
|
||
Create Sprint
|
||
</button>
|
||
|
||
// Outline button (less emphasis)
|
||
<button className="border-2 border-primary text-primary">
|
||
View Details
|
||
</button>
|
||
|
||
// Container variant (even less emphasis)
|
||
<div className="bg-primary-container text-primary-container-foreground">
|
||
Selected item
|
||
</div>
|
||
```
|
||
|
||
### Secondary (Planning & Support)
|
||
|
||
Use for:
|
||
- Secondary actions
|
||
- Supporting UI elements
|
||
- Less critical interactive elements
|
||
- Toolbar items
|
||
|
||
**Examples:**
|
||
```tsx
|
||
// Secondary action
|
||
<button className="bg-secondary text-secondary-foreground">
|
||
Filter
|
||
</button>
|
||
|
||
// Subtle highlight
|
||
<div className="bg-secondary-container text-secondary-container-foreground">
|
||
Planning phase
|
||
</div>
|
||
```
|
||
|
||
### Tertiary (Progress & Highlights)
|
||
|
||
Use for:
|
||
- Progress indicators
|
||
- Data visualization accents
|
||
- Highlights and callouts
|
||
- Metrics
|
||
|
||
**Examples:**
|
||
```tsx
|
||
// Progress indicator
|
||
<div className="bg-tertiary text-tertiary-foreground">
|
||
75% Complete
|
||
</div>
|
||
|
||
// Metric badge
|
||
<span className="bg-tertiary-container text-tertiary-container-foreground">
|
||
+12 stories
|
||
</span>
|
||
```
|
||
|
||
---
|
||
|
||
## Semantic States
|
||
|
||
### Success (Completed, Positive)
|
||
|
||
Use for:
|
||
- Completed tasks
|
||
- Success messages
|
||
- Positive confirmations
|
||
- Achievement indicators
|
||
|
||
```tsx
|
||
<div className="bg-success text-success-foreground">
|
||
✓ Sprint completed successfully
|
||
</div>
|
||
|
||
<div className="bg-success-container text-success-container-foreground">
|
||
8 stories completed this week
|
||
</div>
|
||
```
|
||
|
||
### Warning (Attention Needed)
|
||
|
||
Use for:
|
||
- Warnings
|
||
- Potential issues
|
||
- Items needing attention
|
||
- Approaching deadlines
|
||
|
||
```tsx
|
||
<div className="bg-warning text-warning-foreground">
|
||
⚠ Sprint deadline in 2 days
|
||
</div>
|
||
|
||
<div className="bg-warning-container text-warning-container-foreground">
|
||
3 stories at risk
|
||
</div>
|
||
```
|
||
|
||
### Error (Failures, Critical Issues)
|
||
|
||
Use for:
|
||
- Errors
|
||
- Failed operations
|
||
- Blocked items
|
||
- Critical alerts
|
||
|
||
```tsx
|
||
<div className="bg-error text-error-foreground">
|
||
✗ Failed to save changes
|
||
</div>
|
||
|
||
<div className="bg-error-container text-error-container-foreground">
|
||
1 story blocked
|
||
</div>
|
||
```
|
||
|
||
### Info (Neutral Information)
|
||
|
||
Use for:
|
||
- Informational messages
|
||
- Tips and hints
|
||
- Neutral notifications
|
||
- Help text
|
||
|
||
```tsx
|
||
<div className="bg-info text-info-foreground">
|
||
ℹ New feature available
|
||
</div>
|
||
|
||
<div className="bg-info-container text-info-container-foreground">
|
||
Tip: Use drag-and-drop to reorder
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## Project Management Colors
|
||
|
||
### Work Item Status Colors
|
||
|
||
These colors are specifically designed for Scrum workflow states:
|
||
|
||
#### To Do (Purple - #6750a4 / #cfbdfe)
|
||
- Not started items
|
||
- Backlog items
|
||
- Planned work
|
||
|
||
```tsx
|
||
<span className="bg-status-todo text-white px-3 py-1 rounded-full">
|
||
To Do
|
||
</span>
|
||
```
|
||
|
||
#### In Progress (Blue - #0061a4 / #9fcbfa)
|
||
- Active development
|
||
- Current sprint items
|
||
- Work in flight
|
||
|
||
```tsx
|
||
<span className="bg-status-in-progress text-white px-3 py-1 rounded-full">
|
||
In Progress
|
||
</span>
|
||
```
|
||
|
||
#### Done (Green - #006e1c / #77db77)
|
||
- Completed items
|
||
- Accepted work
|
||
- Delivered features
|
||
|
||
```tsx
|
||
<span className="bg-status-done text-white px-3 py-1 rounded-full">
|
||
Done
|
||
</span>
|
||
```
|
||
|
||
#### Blocked (Red - #ba1a1a / #ffb4ab)
|
||
- Blocked items
|
||
- Impediments
|
||
- Issues preventing progress
|
||
|
||
```tsx
|
||
<span className="bg-status-blocked text-white px-3 py-1 rounded-full">
|
||
Blocked
|
||
</span>
|
||
```
|
||
|
||
### Priority Level Colors
|
||
|
||
#### Critical (Red - #ba1a1a / #ffb4ab)
|
||
- Production issues
|
||
- Show-stopper bugs
|
||
- Immediate action required
|
||
|
||
```tsx
|
||
<span className="bg-priority-critical text-white px-2 py-1 rounded text-sm">
|
||
Critical
|
||
</span>
|
||
```
|
||
|
||
#### High (Orange - #c75300 / #ffb68d)
|
||
- Important features
|
||
- Significant bugs
|
||
- Near-term priorities
|
||
|
||
```tsx
|
||
<span className="bg-priority-high text-white px-2 py-1 rounded text-sm">
|
||
High
|
||
</span>
|
||
```
|
||
|
||
#### Medium (Yellow - #735b00 / #efc047)
|
||
- Standard priority
|
||
- Regular backlog items
|
||
- Scheduled work
|
||
|
||
```tsx
|
||
<span className="bg-priority-medium text-white px-2 py-1 rounded text-sm">
|
||
Medium
|
||
</span>
|
||
```
|
||
|
||
#### Low (Teal - #006874 / #4fd8eb)
|
||
- Nice-to-have features
|
||
- Minor improvements
|
||
- Future considerations
|
||
|
||
```tsx
|
||
<span className="bg-priority-low text-white px-2 py-1 rounded text-sm">
|
||
Low
|
||
</span>
|
||
```
|
||
|
||
---
|
||
|
||
## Usage Examples
|
||
|
||
### Product Backlog Item Card
|
||
|
||
```tsx
|
||
<div className="bg-card text-card-foreground p-6 rounded-lg border border-border">
|
||
<div className="flex items-start justify-between mb-3">
|
||
<h3 className="text-lg">Implement OAuth2 Authentication</h3>
|
||
<span className="bg-priority-high text-white px-3 py-1 rounded-md text-sm">
|
||
High
|
||
</span>
|
||
</div>
|
||
|
||
<p className="text-muted-foreground mb-4">
|
||
Add OAuth2 support for Google and GitHub authentication providers
|
||
with proper session management and refresh token handling.
|
||
</p>
|
||
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex gap-2">
|
||
<span className="bg-status-in-progress text-white px-3 py-1 rounded-full text-sm">
|
||
In Progress
|
||
</span>
|
||
<span className="text-muted-foreground text-sm">
|
||
Story Points: 8
|
||
</span>
|
||
</div>
|
||
|
||
<div className="text-sm text-muted-foreground">
|
||
Assigned to: Sarah
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### Sprint Dashboard Card
|
||
|
||
```tsx
|
||
<div className="bg-surface-container-low p-6 rounded-xl">
|
||
<h2 className="mb-4">Sprint 12 Progress</h2>
|
||
|
||
<div className="bg-surface-container p-4 rounded-lg mb-4">
|
||
<div className="space-y-3">
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-muted-foreground">Total Stories</span>
|
||
<span className="text-xl">15</span>
|
||
</div>
|
||
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-muted-foreground">Completed</span>
|
||
<span className="text-xl text-success">10</span>
|
||
</div>
|
||
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-muted-foreground">In Progress</span>
|
||
<span className="text-xl text-info">4</span>
|
||
</div>
|
||
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-muted-foreground">Blocked</span>
|
||
<span className="text-xl text-error">1</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
<div className="flex justify-between text-sm">
|
||
<span className="text-muted-foreground">Progress</span>
|
||
<span>67%</span>
|
||
</div>
|
||
<div className="w-full bg-surface-container-highest rounded-full h-3">
|
||
<div
|
||
className="bg-success h-3 rounded-full transition-all"
|
||
style={{ width: '67%' }}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### Kanban Board Column
|
||
|
||
```tsx
|
||
<div className="bg-surface-container p-4 rounded-lg min-w-80">
|
||
<div className="flex items-center justify-between mb-4">
|
||
<h3 className="flex items-center gap-2">
|
||
<span className="w-3 h-3 rounded-full bg-status-in-progress" />
|
||
In Progress
|
||
</h3>
|
||
<span className="bg-surface-container-high text-muted-foreground px-2 py-1 rounded text-sm">
|
||
4
|
||
</span>
|
||
</div>
|
||
|
||
<div className="space-y-3">
|
||
{/* Story card */}
|
||
<div className="bg-surface-container-low p-3 rounded-lg border border-border hover:border-primary cursor-pointer transition-colors">
|
||
<div className="flex items-start justify-between mb-2">
|
||
<h4 className="text-sm">Fix login redirect issue</h4>
|
||
<span className="bg-priority-critical text-white px-2 py-0.5 rounded text-xs">
|
||
Critical
|
||
</span>
|
||
</div>
|
||
<p className="text-xs text-muted-foreground mb-3">
|
||
Users are redirected to wrong page after login
|
||
</p>
|
||
<div className="flex items-center justify-between">
|
||
<span className="text-xs text-muted-foreground">SP: 3</span>
|
||
<div className="w-6 h-6 rounded-full bg-primary text-primary-foreground flex items-center justify-center text-xs">
|
||
JD
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### Action Buttons
|
||
|
||
```tsx
|
||
{/* Primary action */}
|
||
<button className="px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:opacity-90 transition-opacity">
|
||
Start Sprint
|
||
</button>
|
||
|
||
{/* Secondary action */}
|
||
<button className="px-6 py-3 bg-secondary text-secondary-foreground rounded-lg hover:opacity-90 transition-opacity">
|
||
Save as Draft
|
||
</button>
|
||
|
||
{/* Outlined action */}
|
||
<button className="px-6 py-3 border-2 border-primary text-primary rounded-lg hover:bg-primary-container transition-colors">
|
||
View Backlog
|
||
</button>
|
||
|
||
{/* Tertiary/text action */}
|
||
<button className="px-6 py-3 text-primary hover:bg-primary-container rounded-lg transition-colors">
|
||
Cancel
|
||
</button>
|
||
|
||
{/* Destructive action */}
|
||
<button className="px-6 py-3 bg-error text-error-foreground rounded-lg hover:opacity-90 transition-opacity">
|
||
Delete Sprint
|
||
</button>
|
||
```
|
||
|
||
### Status Badges
|
||
|
||
```tsx
|
||
{/* Pill-shaped status badges */}
|
||
<div className="flex gap-2">
|
||
<span className="inline-flex items-center gap-1 px-3 py-1 bg-status-todo text-white rounded-full text-sm">
|
||
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 8 8">
|
||
<circle cx="4" cy="4" r="3" />
|
||
</svg>
|
||
To Do
|
||
</span>
|
||
|
||
<span className="inline-flex items-center gap-1 px-3 py-1 bg-status-in-progress text-white rounded-full text-sm">
|
||
<svg className="w-3 h-3 animate-spin" fill="none" viewBox="0 0 24 24">
|
||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
|
||
</svg>
|
||
In Progress
|
||
</span>
|
||
|
||
<span className="inline-flex items-center gap-1 px-3 py-1 bg-status-done text-white rounded-full text-sm">
|
||
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
|
||
</svg>
|
||
Done
|
||
</span>
|
||
|
||
<span className="inline-flex items-center gap-1 px-3 py-1 bg-status-blocked text-white rounded-full text-sm">
|
||
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fillRule="evenodd" d="M13.477 14.89A6 6 0 015.11 6.524l8.367 8.368zm1.414-1.414L6.524 5.11a6 6 0 018.367 8.367zM18 10a8 8 0 11-16 0 8 8 0 0116 0z" clipRule="evenodd" />
|
||
</svg>
|
||
Blocked
|
||
</span>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## Implementation Guide
|
||
|
||
### Setting Up the Color System
|
||
|
||
The color system is defined in `/src/styles/theme.css`. All colors use CSS custom properties (variables) for easy theming.
|
||
|
||
### Tailwind CSS Configuration
|
||
|
||
All color tokens are automatically available as Tailwind classes through the `@theme inline` directive:
|
||
|
||
```css
|
||
/* Colors are available as: */
|
||
bg-primary
|
||
text-primary-foreground
|
||
border-primary-container
|
||
bg-surface-container-low
|
||
bg-status-in-progress
|
||
bg-priority-high
|
||
/* etc. */
|
||
```
|
||
|
||
### Dark Mode Toggle
|
||
|
||
Toggle dark mode with JavaScript:
|
||
|
||
```tsx
|
||
// Toggle dark mode
|
||
document.documentElement.classList.toggle('dark');
|
||
|
||
// Set dark mode
|
||
document.documentElement.classList.add('dark');
|
||
|
||
// Set light mode
|
||
document.documentElement.classList.remove('dark');
|
||
|
||
// React component example
|
||
function DarkModeToggle() {
|
||
const [isDark, setIsDark] = useState(false);
|
||
|
||
const toggleDark = () => {
|
||
setIsDark(!isDark);
|
||
document.documentElement.classList.toggle('dark');
|
||
};
|
||
|
||
return (
|
||
<button onClick={toggleDark}>
|
||
{isDark ? '☀️ Light Mode' : '🌙 Dark Mode'}
|
||
</button>
|
||
);
|
||
}
|
||
```
|
||
|
||
### Using with shadcn Components
|
||
|
||
All shadcn/ui components work seamlessly with this color system. The legacy color tokens (card, popover, muted, accent, destructive) are mapped to appropriate MD3 colors.
|
||
|
||
```tsx
|
||
// shadcn Button component automatically uses the color system
|
||
<Button>Primary Action</Button>
|
||
<Button variant="secondary">Secondary Action</Button>
|
||
<Button variant="destructive">Delete</Button>
|
||
<Button variant="outline">Outlined</Button>
|
||
```
|
||
|
||
---
|
||
|
||
## Accessibility
|
||
|
||
### Contrast Ratios
|
||
|
||
All color combinations meet **WCAG AA** standards:
|
||
|
||
- **Normal text**: Minimum 4.5:1 contrast ratio
|
||
- **Large text**: Minimum 3:1 contrast ratio
|
||
- **UI components**: Minimum 3:1 contrast ratio
|
||
|
||
### Color Blindness Considerations
|
||
|
||
The color system is designed to be distinguishable for users with common types of color blindness:
|
||
|
||
1. **Status colors** use distinct hues that remain distinguishable in deuteranopia, protanopia, and tritanopia
|
||
2. **Priority levels** use a progression from cool (low) to warm (high) colors
|
||
3. **All status indicators** should include text labels, not just color
|
||
|
||
### Best Practices for Accessibility
|
||
|
||
```tsx
|
||
// ✅ Good: Color + Icon + Text
|
||
<span className="bg-status-done text-white px-3 py-1 rounded-full">
|
||
<CheckIcon className="w-4 h-4 inline" />
|
||
Done
|
||
</span>
|
||
|
||
// ❌ Bad: Color only
|
||
<span className="w-4 h-4 bg-status-done rounded-full" />
|
||
|
||
// ✅ Good: Semantic HTML + ARIA
|
||
<button
|
||
className="bg-primary text-primary-foreground"
|
||
aria-label="Start new sprint"
|
||
>
|
||
Start Sprint
|
||
</button>
|
||
|
||
// ✅ Good: Status with aria-label
|
||
<div
|
||
className="bg-status-blocked"
|
||
role="status"
|
||
aria-label="This item is blocked"
|
||
>
|
||
Blocked
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## Best Practices
|
||
|
||
### 1. Use Surface Elevation for Depth
|
||
|
||
❌ **Don't use shadows for elevation**
|
||
```tsx
|
||
<div className="shadow-lg">Card</div>
|
||
```
|
||
|
||
✅ **Do use surface tones**
|
||
```tsx
|
||
<div className="bg-surface-container-low">Card</div>
|
||
```
|
||
|
||
### 2. Use Container Variants for Lower Emphasis
|
||
|
||
❌ **Don't reduce opacity**
|
||
```tsx
|
||
<button className="bg-primary opacity-50">Secondary Action</button>
|
||
```
|
||
|
||
✅ **Do use container variants**
|
||
```tsx
|
||
<button className="bg-primary-container text-primary-container-foreground">
|
||
Secondary Action
|
||
</button>
|
||
```
|
||
|
||
### 3. Consistent Status Colors
|
||
|
||
❌ **Don't use arbitrary colors**
|
||
```tsx
|
||
<span className="bg-green-500">Complete</span>
|
||
<span className="bg-emerald-600">Finished</span>
|
||
```
|
||
|
||
✅ **Do use semantic status colors**
|
||
```tsx
|
||
<span className="bg-status-done">Complete</span>
|
||
<span className="bg-status-done">Finished</span>
|
||
```
|
||
|
||
### 4. Semantic Color Usage
|
||
|
||
❌ **Don't use colors for decoration only**
|
||
```tsx
|
||
<div className="bg-error">This is important information</div>
|
||
```
|
||
|
||
✅ **Do use colors for their semantic meaning**
|
||
```tsx
|
||
<div className="bg-error text-error-foreground">
|
||
Error: Failed to save changes
|
||
</div>
|
||
|
||
<div className="bg-info text-info-foreground">
|
||
This is important information
|
||
</div>
|
||
```
|
||
|
||
### 5. Proper Text Contrast
|
||
|
||
❌ **Don't forget foreground colors**
|
||
```tsx
|
||
<button className="bg-primary">Click me</button>
|
||
```
|
||
|
||
✅ **Do include foreground colors**
|
||
```tsx
|
||
<button className="bg-primary text-primary-foreground">Click me</button>
|
||
```
|
||
|
||
### 6. Layering and Nesting
|
||
|
||
When nesting containers, move down the elevation scale:
|
||
|
||
```tsx
|
||
<div className="bg-surface-container-low p-6">
|
||
{/* Outer container */}
|
||
|
||
<div className="bg-surface-container p-4">
|
||
{/* Inner container - lower elevation */}
|
||
|
||
<div className="bg-surface-container-high p-3">
|
||
{/* Deepest container - lowest elevation */}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### 7. Interactive States
|
||
|
||
```tsx
|
||
// Buttons with hover states
|
||
<button className="bg-primary text-primary-foreground hover:opacity-90 transition-opacity">
|
||
Click me
|
||
</button>
|
||
|
||
// Cards with hover states
|
||
<div className="bg-card border border-border hover:border-primary transition-colors cursor-pointer">
|
||
Interactive card
|
||
</div>
|
||
|
||
// Focus states (automatically handled by theme)
|
||
<input className="border border-border focus:ring-2 focus:ring-primary" />
|
||
```
|
||
|
||
---
|
||
|
||
## Quick Reference
|
||
|
||
### Most Common Combinations
|
||
|
||
```tsx
|
||
// Primary button
|
||
bg-primary text-primary-foreground
|
||
|
||
// Secondary button
|
||
bg-secondary text-secondary-foreground
|
||
|
||
// Card
|
||
bg-card text-card-foreground border border-border
|
||
|
||
// Success message
|
||
bg-success-container text-success-container-foreground
|
||
|
||
// Warning banner
|
||
bg-warning text-warning-foreground
|
||
|
||
// Error alert
|
||
bg-error text-error-foreground
|
||
|
||
// Info panel
|
||
bg-info-container text-info-container-foreground
|
||
|
||
// Status badge - To Do
|
||
bg-status-todo text-white
|
||
|
||
// Status badge - In Progress
|
||
bg-status-in-progress text-white
|
||
|
||
// Status badge - Done
|
||
bg-status-done text-white
|
||
|
||
// Priority badge - High
|
||
bg-priority-high text-white
|
||
|
||
// Muted text
|
||
text-muted-foreground
|
||
|
||
// Border
|
||
border-border
|
||
```
|
||
|
||
---
|
||
|
||
## Additional Resources
|
||
|
||
### Color Tools
|
||
- **Material Theme Builder**: https://m3.material.io/theme-builder
|
||
- **Contrast Checker**: https://webaim.org/resources/contrastchecker/
|
||
- **Color Blind Simulator**: https://www.color-blindness.com/coblis-color-blindness-simulator/
|
||
|
||
### Documentation
|
||
- **Material Design 3**: https://m3.material.io
|
||
- **Tailwind CSS**: https://tailwindcss.com
|
||
- **shadcn/ui**: https://ui.shadcn.com
|
||
|
||
---
|
||
|
||
## Version History
|
||
|
||
### Version 1.0 (April 22, 2026)
|
||
- Initial color scheme based on Material Design 3
|
||
- Complete light and dark theme support
|
||
- Project management specific colors (status, priority)
|
||
- Full shadcn/ui compatibility
|
||
- Accessibility WCAG AA compliant
|
||
|
||
---
|
||
|
||
## Support
|
||
|
||
For questions or issues with the color system:
|
||
- Review the live demo in the application
|
||
- Check `COLOR_SYSTEM.md` for additional examples
|
||
- Refer to `/src/styles/theme.css` for color definitions
|
||
|
||
---
|
||
|
||
**End of Documentation**
|