# 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
43 KiB
| title | status | audience | language | last_updated | ||
|---|---|---|---|---|---|---|
| Scrum4Me — Styling & Design System | active |
|
nl | 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:
@import './styles/theme.css';
2. shadcn/ui initialiseren
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:
// 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>:
// 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):
// 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
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
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
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)
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)
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)
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
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)
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)
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)
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
// 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
// ~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
// 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)
// 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
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
// 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)
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
.darkclass
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)
- surface-container-lowest - Dialogs, modals, popovers
- surface-container-low - Cards, panels, elevated containers
- surface-container - Default container background
- surface-container-high - Nested containers, grouped elements
- surface-container-highest - Background-level containers
Tailwind Usage
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:
// 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:
// 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:
// 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
<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
<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
<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
<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
<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
<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
<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
<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
<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
<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
<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
<span className="bg-priority-low text-white px-2 py-1 rounded text-sm">
Low
</span>
Usage Examples
Product Backlog Item Card
<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
<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
<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
{/* 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
{/* 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:
/* 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:
// 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.
// 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:
- Status colors use distinct hues that remain distinguishable in deuteranopia, protanopia, and tritanopia
- Priority levels use a progression from cool (low) to warm (high) colors
- All status indicators should include text labels, not just color
Best Practices for Accessibility
// ✅ 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
<div className="shadow-lg">Card</div>
✅ Do use surface tones
<div className="bg-surface-container-low">Card</div>
2. Use Container Variants for Lower Emphasis
❌ Don't reduce opacity
<button className="bg-primary opacity-50">Secondary Action</button>
✅ Do use container variants
<button className="bg-primary-container text-primary-container-foreground">
Secondary Action
</button>
3. Consistent Status Colors
❌ Don't use arbitrary colors
<span className="bg-green-500">Complete</span>
<span className="bg-emerald-600">Finished</span>
✅ Do use semantic status colors
<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
<div className="bg-error">This is important information</div>
✅ Do use colors for their semantic meaning
<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
<button className="bg-primary">Click me</button>
✅ Do include foreground colors
<button className="bg-primary text-primary-foreground">Click me</button>
6. Layering and Nesting
When nesting containers, move down the elevation scale:
<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
// 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
// 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.mdfor additional examples - Refer to
/src/styles/theme.cssfor color definitions
End of Documentation