Skip to main content

kb-design-system

Reference data, not a reviewer. Validate design system tokens for WCAG AA/AAA contrast. Compute color token contrast, focus ring validation (WCAG 2.4.13), motion tokens, and spacing for touch targets across frameworks.

Quellinformationen

Repository
Community-Access/accessibility-agents
Letzte Quellaktivität
22. September 2026 um 02:24
Erkannte Sprache von SKILL.md
Englisch
Sterne
425
Forks
53

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
2 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
kb-design-system
description
Reference data, not a reviewer. Validate design system tokens for WCAG AA/AAA contrast. Compute color token contrast, focus ring validation (WCAG 2.4.13), motion tokens, and spacing for touch targets across frameworks.
license
MIT
disable-model-invocation
true
user-invocable
false
metadata
{"tier":"reference","domain":"cross-cutting","output":"none","effort":"low","title":"Design System"}
## Design System Accessibility Skill This skill provides reference data for design token contrast validation, focus ring compliance, and spacing audits. Used by `design-system-auditor.agent.md`. --- ## WCAG Contrast Ratio - Computation Reference ### Step 1: Linearize sRGB Channel For each channel `C` in `[0, 255]`: ```text c = C / 255 c_lin = c / 12.92 if c <= 0.04045 c_lin = ((c + 0.055) / 1.055)^2.4 otherwise ``` ### Step 2: Relative Luminance ```text L = 0.2126 * R_lin + 0.7152 * G_lin + 0.0722 * B_lin ``` ### Step 3: Contrast Ratio ```text ratio = (L_lighter + 0.05) / (L_darker + 0.05) ``` ### Quick JavaScript Implementation ```js function relativeLuminance(hex) { const c = hex.replace('#', '').match(/.{2}/g) .map(h => parseInt(h, 16) / 255) .map(c => c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)); return 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2]; } function contrastRatio(hex1, hex2) { const L1 = relativeLuminance(hex1); const L2 = relativeLuminance(hex2); const lighter = Math.max(L1, L2); const darker = Math.min(L1, L2); return (lighter + 0.05) / (darker + 0.05); } // Example contrastRatio('#6B7280', '#FFFFFF'); // 5.74:1 - PASSES AA (was a common misconception) contrastRatio('#9CA3AF', '#FFFFFF'); // 2.85:1 - FAILS AA ``` ### HSL to Hex Conversion (for CSS variable tokens) Many design systems store colors as HSL triplets (e.g., shadcn/ui, Radix): ```js function hslToHex(h, s, l) { s /= 100; l /= 100; const a = s * Math.min(l, 1 - l); const f = n => { const k = (n + h / 30) % 12; return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); }; return '#' + [f(0), f(8), f(4)] .map(x => Math.round(x * 255).toString(16).padStart(2, '0')) .join(''); } // shadcn/ui: --muted-foreground: 215.4 16.3% 46.9% hslToHex(215.4, 16.3, 46.9); // -> approximately #6B7280 ``` --- ## WCAG Contrast Thresholds Each WCAG contrast threshold, with use case, AA, AAA and notes. | Use Case | AA | AAA | Notes | |----------|-----|-----|-------| | Normal text (< 18pt / < 14pt bold) | 4.5:1 | 7:1 | Most body text | | Large text (>= 18pt / >= 14pt bold) | 3:1 | 4.5:1 | Headings, display text | | UI components (borders, icons) | 3:1 | - | Input borders, icon buttons | | Focus indicators (WCAG 2.4.13, 2.2) | 3:1 | - | Against adjacent colors | | Placeholder text | 4.5:1 | - | Counts as normal text | | Disabled state | Exempt | Exempt | Documented exemption | | Logo / brand | Exempt | Exempt | No requirement | | Decorative content | Exempt | Exempt | Must be marked decorative | --- ## Framework Token Paths - Complete Reference ### Tailwind CSS ```js // tailwind.config.js / tailwind.config.ts module.exports = { theme: { // Base colors (Tailwind default palette) colors: { // All color scales: slate, gray, zinc, neutral, stone, red, orange, amber, // yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, // purple, fuchsia, pink, rose // Each scale: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950 }, extend: { colors: { // Custom semantic colors - CHECK ALL PAIRS brand: { primary: '#...', secondary: '#...' }, background: '#...', foreground: '#...', muted: '#...', 'muted-foreground': '#...', accent: '#...', 'accent-foreground': '#...', destructive: '#...', 'destructive-foreground': '#...', card: '#...', 'card-foreground': '#...', popover: '#...', 'popover-foreground': '#...', border: '#...', // UI component - check 3:1 against background input: '#...', // UI component - check 3:1 against background ring: '#...', // Focus ring - check 3:1 against background primary: '#...', 'primary-foreground': '#...', secondary: '#...', 'secondary-foreground': '#...', }, ringColor: { DEFAULT: '...' }, // Focus state ringWidth: { DEFAULT: '2px' }, // Must be >= 2px for WCAG 2.4.13 } } } ``` ### shadcn/ui / Radix CSS Variables ```css /* globals.css - HSL triplets without hsl() wrapper */ :root { --background: 0 0% 100%; --foreground: 222.2 84% 4.9%; --card: 0 0% 100%; --card-foreground: 222.2 84% 4.9%; --popover: 0 0% 100%; --popover-foreground: 222.2 84% 4.9%; --primary: 222.2 47.4% 11.2%; --primary-foreground: 210 40% 98%; --secondary: 210 40% 96.1%; --secondary-foreground: 222.2 47.4% 11.2%; --muted: 210 40% 96.1%; --muted-foreground: 215.4 16.3% 46.9%; /* HIGH RISK - check on --background */ --accent: 210 40% 96.1%; --accent-foreground: 222.2 47.4% 11.2%; --destructive: 0 84.2% 60.2%; /* HIGH RISK - red on white */ --destructive-foreground: 210 40% 98%; --border: 214.3 31.8% 91.4%; /* UI component - check 3:1 */ --input: 214.3 31.8% 91.4%; /* UI component - check 3:1 */ --ring: 222.2 84% 4.9%; /* Focus ring - check 3:1 */ } .dark { --background: 222.2 84% 4.9%; --foreground: 210 40% 98%; /* ... all dark mode variants */ } ``` ### Material UI (MUI) v5+ ```js // Token paths in createTheme() palette: { primary: { main: '#1976d2', // text-on-white: 4.56:1 light: '#42a5f5', // text-on-white: 2.86:1 (do not use as text color) dark: '#1565c0', // text-on-white: 5.91:1 contrastText: '#fff', // check on main }, secondary: { main: '#9c27b0', // text-on-white: 4.56:1 (barely) light: '#ba68c8', // text-on-white: 2.55:1 dark: '#7b1fa2', contrastText: '#fff', }, error: { main: '#d32f2f', // text-on-white: 5.08:1 light: '#ef5350', // text-on-white: 3.04:1 }, warning: { main: '#ed6c02', // text-on-white: 2.94:1 COMMON FAILURE light: '#ff9800', // text-on-white: 2.02:1 dark: '#e65100', // text-on-white: 3.84:1 (still fails!) contrastText: 'rgba(0, 0, 0, 0.87)', // check on warning.main }, info: { main: '#0288d1', // text-on-white: 4.54:1 (barely) light: '#03a9f4', // text-on-white: 2.88:1 }, success: { main: '#2e7d32', // text-on-white: 7.24:1 light: '#4caf50', // text-on-white: 2.52:1 }, text: { primary: 'rgba(0,0,0,0.87)', // -> ~#212121: 16.07:1 on white secondary: 'rgba(0,0,0,0.6)', // -> ~#666: 5.74:1 on white disabled: 'rgba(0,0,0,0.38)', // -> ~#9E9E9E: 2.34:1 (exempt when disabled) }, background: { paper: '#fff', default: '#fafafa' }, action: { active: 'rgba(0,0,0,0.54)', // ~4.48:1 for small icons disabled: 'rgba(0,0,0,0.26)', // exempt when disabled } } ``` ### Chakra UI v2/v3 ```js // Token paths in extendTheme() const theme = extendTheme({ colors: { // Direct palette values brand: { 50: '#f5f3ff', 500: '#7C3AED', 600: '#6D28D9', 700: '#5B21B6', 900: '#2E1065' }, gray: { 50: '#F9FAFB', 100: '#F3F4F6', 200: '#E5E7EB', 300: '#D1D5DB', 400: '#9CA3AF', // text-on-white: 2.85:1 500: '#6B7280', // text-on-white: 4.48:1 (near-miss) 600: '#4B5563', // text-on-white: 7.44:1 700: '#374151', 800: '#1F2937', 900: '#111827' }, }, semanticTokens: { colors: { 'chakra-body-text': { default: 'gray.800', _dark: 'whiteAlpha.900' }, 'chakra-body-bg': { default: 'white', _dark: 'gray.800' }, 'chakra-placeholder-color': { default: 'gray.400', _dark: 'whiteAlpha.400' }, // gray.400 on white = 2.85:1 - placeholder fails AA } }, components: { Button: { variants: { solid: (props) => ({ bg: `${props.colorScheme}.500`, // check colorScheme.500 on white color: 'white', // white on colorScheme.500 - check 3:1 }), ghost: (props) => ({ color: `${props.colorScheme}.600`, // text-on-white variant }), } } } }); ``` ### Style Dictionary (W3C Design Tokens) ```json { "color": { "text": { "primary": { "$value": "#111827", "$type": "color" }, "secondary": { "$value": "#6B7280", "$type": "color" }, // 4.48:1 on white
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen