UI Theme Reference
Configurable design token registry used by ui-best-practices rules.
Every hardcoded value in the best practices MUST reference a token defined here.
To customize: override values below or generate via /pwdev-uiux:theme create.
How to Use
Rules in the ui-best-practices skill reference tokens as theme.<section>.<token>.
When implementing, map these tokens to your stack:
| Stack |
Token format |
File |
| shadcn-vue |
hsl(var(--<token>)) |
src/assets/index.css |
| shadcn-react |
hsl(var(--<token>)) |
src/app/globals.css |
| primevue |
var(--p-<token>) |
src/assets/theme.css |
| tailwind-only |
Tailwind config theme.extend |
tailwind.config.ts |
| custom |
Any CSS variable scheme |
project-specific |
1. Colors
1.1 Surfaces
| Token |
Light |
Dark |
Usage |
--background |
#F9FAFB · 210 20% 98% |
#0A0F1A · 222 84% 5% |
Page background |
--foreground |
#1D2939 · 220 26% 16% |
#F0F4F8 · 210 40% 96% |
Primary text |
--card |
#FFFFFF · 0 0% 100% |
#111827 · 222 47% 11% |
Card / surface background |
--card-foreground |
#1D2939 · 220 26% 16% |
#F0F4F8 · 210 40% 96% |
Text on cards |
--popover |
#FFFFFF · 0 0% 100% |
#111827 · 222 47% 11% |
Popover / dropdown bg |
--popover-foreground |
#1D2939 · 220 26% 16% |
#F0F4F8 · 210 40% 96% |
Text on popovers |
1.2 Text Hierarchy
| Token |
Light |
Dark |
Usage |
--foreground |
#1D2939 |
#F0F4F8 |
Primary text, headings |
--muted-foreground |
#667085 |
#94A3B8 |
Secondary text, labels, placeholders |
1.3 Interactive
| Token |
Light |
Dark |
Usage |
--primary |
brand color |
brand color (adjusted) |
Buttons, links, focus rings |
--primary-foreground |
#FFFFFF |
#FFFFFF |
Text on primary backgrounds |
--secondary |
#F1F5F9 |
#1E293B |
Secondary buttons, subtle actions |
--secondary-foreground |
#1D2939 |
#F0F4F8 |
Text on secondary backgrounds |
--accent |
#F1F5F9 |
#1E293B |
Hover highlights, active states |
--accent-foreground |
#1D2939 |
#F0F4F8 |
Text on accent backgrounds |
1.4 Feedback
| Token |
Light |
Dark |
Usage |
--success |
#039855 |
#34D399 |
Positive states, confirmations |
--success-foreground |
#FFFFFF |
#022C22 |
Text on success backgrounds |
--warning |
#F79009 |
#FBBF24 |
Alerts, caution states |
--warning-foreground |
#422006 |
#422006 |
Text on warning backgrounds |
--destructive |
#D92D20 |
#FCA5A5 |
Errors, delete actions |
--destructive-foreground |
#FFFFFF |
#450A0A |
Text on destructive backgrounds |
--info |
#2563EB |
#60A5FA |
Informational, tips |
--info-foreground |
#FFFFFF |
#172554 |
Text on info backgrounds |
1.5 Structure
| Token |
Light |
Dark |
Usage |
--border |
#EAECF0 |
#1E293B |
Dividers, separators |
--input |
#D0D5DD |
#334155 |
Input borders |
--ring |
primary |
primary |
Focus ring color |
--muted |
#F1F5F9 |
#1E293B |
Muted backgrounds (badges, tags) |
1.6 Reserved Semantic Colors
These colors carry universal meaning. Never repurpose them for decorative or categorical use:
| Color |
Meaning |
Allowed usage |
Green (--success) |
Good / positive / complete |
Success states, positive KPIs, completion |
Orange (--warning) |
Caution / attention needed |
Warnings, pending actions, approaching limits |
Red (--destructive) |
Bad / error / danger |
Errors, failures, destructive actions, negative KPIs |
For categorical/chart colors, use the chart palette below.
1.7 Chart Palette
Dedicated colors for data visualization — independent from feedback semantics:
| Token |
Default |
Usage |
--chart-1 |
#2563EB |
Primary data series |
--chart-2 |
#7C3AED |
Secondary data series |
--chart-3 |
#0891B2 |
Tertiary data series |
--chart-4 |
#C026D3 |
Fourth data series |
--chart-5 |
#EA580C |
Fifth data series |
--chart-muted |
#D1D5DB |
De-emphasized / comparison series |
2. Typography
2.1 Font Stack
| Token |
Default |
Fallbacks |
--font-sans |
Inter |
system-ui, -apple-system, sans-serif |
--font-mono |
JetBrains Mono |
ui-monospace, monospace |
2.2 Type Scale
Progressive scale — adjacent levels must not skip more than one step:
| Token |
Size |
Line Height |
Weight |
Usage |
--text-xs |
12px |
16px |
400 |
Footnotes, badges, captions (minimum allowed) |
--text-sm |
14px |
20px |
400 |
Default body text, form labels |
--text-base |
16px |
24px |
400 |
Emphasized body, card titles |
--text-lg |
18px |
28px |
500 |
Section headings |
--text-xl |
20px |
28px |
600 |
Page sub-titles |
--text-2xl |
24px |
32px |
600 |
Page titles |
--text-3xl |
30px |
36px |
700 |
Hero headings |
--text-4xl |
36px |
40px |
700 |
Display / marketing headings |
Constraint: never jump more than 2 steps between adjacent text elements (e.g., text-3xl → text-sm is forbidden; use text-3xl → text-xl → text-base → text-sm).
2.3 Font Weight Scale
| Token |
Value |
Usage |
--font-normal |
400 |
Body text |
--font-medium |
500 |
Labels, nav items |
--font-semibold |
600 |
Headings, emphasis |
--font-bold |
700 |
Hero, display text |
3. Spacing
Base unit: 4px. All spacing must be a multiple of 4.
| Token |
Value |
Tailwind |
Typical Usage |
--space-0.5 |
2px |
gap-0.5 |
Micro adjustments only |
--space-1 |
4px |
gap-1 |
Icon ↔ label gap |
--space-1.5 |
6px |
gap-1.5 |
Compact inline gap |
--space-2 |
8px |
gap-2 |
Internal gap, small padding |
--space-3 |
12px |
gap-3 |
Badge padding, compact lists |
--space-4 |
16px |
gap-4, p-4 |
Default card padding (min) |
--space-5 |
20px |
gap-5 |
Medium card padding |
--space-6 |
24px |
gap-6, p-6 |
Default card padding (max), section gaps |
--space-8 |
32px |
gap-8, p-8 |
Large section padding |
--space-10 |
40px |
gap-10 |
Page-level vertical spacing |
--space-12 |
48px |
gap-12 |
Major section dividers |
--space-16 |
64px |
gap-16 |
Page top/bottom margins |
Card Padding Rule
| Card context |
Recommended padding |
| Compact (sidebar, list items) |
--space-3 to --space-4 (12–16px) |
| Standard (content cards) |
--space-4 to --space-6 (16–24px) |
| Featured / hero cards |
--space-6 to --space-8 (24–32px) |
| Ceiling |
Never exceed --space-8 (32px) in cards |
4. Sizing
4.1 Interactive Elements
| Token |
Value |
Usage |
--height-input |
40px |
Inputs, selects, single-line controls |
--height-button |
40px |
All buttons (must match input height) |
--height-button-sm |
32px |
Compact buttons (tables, toolbars) |
--height-button-lg |
48px |
Hero CTAs, prominent actions |
--min-touch-target |
44px |
Minimum tap area on touch devices (WCAG 2.5.8) |
4.2 Content Width
| Token |
Value |
Usage |
--max-w-form |
560px |
Form containers (onboarding, settings) |
--max-w-button |
400px |
Max button width in wide forms |
--max-w-content |
768px |
Article/text-heavy content |
--max-w-page |
1280px |
Page container |
4.3 Textarea Height
| Context |
Rows |
Approx Height |
| Short input (tagline, slug) |
2 |
~56px |
| Medium input (description) |
4–5 |
~112px |
| Long input (feedback, notes) |
6–8 |
~168px |
Always enable auto-resize to grow with content.
5. Border Radius
| Token |
Value |
Usage |
--radius |
8px (configurable) |
Base radius — defines product personality |
--radius-sm |
calc(var(--radius) - 4px) |
Badges, small elements |
--radius-md |
calc(var(--radius) - 2px) |
Inputs, buttons |
--radius-lg |
var(--radius) |
Cards, modals |
--radius-xl |
calc(var(--radius) + 4px) |
Feature cards, large containers |
--radius-full |
9999px |
Avatars, pills, tags |
Personality Guide
| Brand Style |
--radius value |
| Modern / trendy |
12px–16px |
| Neutral / corporate (safe default) |
8px |
| Enterprise / dense |
4px |
| Sharp / editorial |
0px–2px |
6. Shadows
All shadows use #000000 with controlled opacity. No colored shadows.
| Token |
Value |
Usage |
--shadow-xs |
0 1px 2px rgba(0,0,0,0.05) |
Subtle lift (inputs, badges) |
--shadow-sm |
0 2px 4px rgba(0,0,0,0.06) |
Cards at rest |
--shadow-md |
0 4px 16px rgba(0,0,0,0.08) |
Elevated cards, dropdowns |
--shadow-lg |
0 8px 24px rgba(0,0,0,0.10) |
Modals, popovers |
--shadow-xl |
0 16px 48px rgba(0,0,0,0.12) |
Command palette, overlays |
Constraints:
- Minimum opacity:
0.05 (below is invisible)
- Maximum opacity:
0.12 (above feels heavy)
- Never use colored shadows
- Never use gradients as shadow replacements
7. Z-Index Scale
Managed scale to prevent z-index wars:
| Token |
Value |
Usage |
--z-base |
0 |
Default stacking |
--z-dropdown |
10 |
Dropdowns, tooltips |
--z-sticky |
20 |
Sticky headers, fixed navs |
--z-drawer |
30 |
Side drawers, panels |
--z-modal |
40 |
Modals, dialogs |
--z-popover |
50 |
Popovers over modals |
--z-toast |
60 |
Toast notifications |
--z-command |
70 |
Command palette (Cmd+K) |
--z-overlay |
80 |
Full-screen overlays |
8. Breakpoints
| Token |
Value |
Tailwind |
Usage |
--bp-sm |
640px |
sm: |
Large phones landscape |
--bp-md |
768px |
md: |
Tablets |
--bp-lg |
1024px |
lg: |
Small laptops |
--bp-xl |
1280px |
xl: |
Desktops |
--bp-2xl |
1536px |
2xl: |
Large screens |
Navigation Breakpoint Rules
| Viewport |
Max nav items |
Menu style |
< md |
4 visible |
Bottom bar or hamburger |
md–lg |
5–6 visible |
Top bar or compact sidebar |
≥ lg |
Unlimited |
Full sidebar |
9. Motion & Animation
| Token |
Value |
Usage |
--duration-instant |
100ms |
Hover color changes, opacity |
--duration-fast |
150ms |
Button press, toggle switch |
--duration-normal |
200ms |
Dropdown open, tooltip appear |
--duration-slow |
300ms |
Drawer slide, modal enter |
--duration-slower |
500ms |
Page transitions, skeleton fade |
--ease-default |
cubic-bezier(0.4, 0, 0.2, 1) |
General purpose easing |
--ease-in |
cubic-bezier(0.4, 0, 1, 1) |
Elements leaving the screen |
--ease-out |
cubic-bezier(0, 0, 0.2, 1) |
Elements entering the screen |
Constraint: always respect prefers-reduced-motion: reduce — disable or minimize all animations.
10. Focus & Accessibility
| Token |
Value |
Usage |
--ring-width |
2px |
Focus ring thickness |
--ring-offset |
2px |
Gap between element and focus ring |
--ring-color |
var(--ring) |
Focus ring color (defaults to primary) |
Contrast Requirements (WCAG AA)
| Element Type |
Minimum Ratio |
| Normal text (< 18px) |
4.5:1 |
| Large text (≥ 18px or ≥ 14px bold) |
3:1 |
| UI components (borders, icons) |
3:1 |
| Non-text contrast (graphs, charts) |
3:1 |
CSS Variable Template
Minimal starter for any project — copy and customize:
@layer base {
:root {
/* Surfaces */
--background: 210 20% 98%;
--foreground: 220 26% 16%;
--card: 0 0% 100%;
--card-foreground: 220 26% 16%;
--popover: 0 0% 100%;
--popover-foreground: 220 26% 16%;
--muted: 210 40% 96%;
--muted-foreground: 215 16% 47%;
/* Interactive */
--primary: 221 83% 53%; /* ← your brand color */
--primary-foreground: 0 0% 100%;
--secondary: 210 40% 96%;
--secondary-foreground: 220 26% 16%;
--accent: 210 40% 96%;
--accent-foreground: 220 26% 16%;
/* Feedback */
--destructive: 0 72% 51%;
--destructive-foreground: 0 0% 100%;
--success: 160 84% 39%;
--success-foreground: 0 0% 100%;
--warning: 32 95% 44%;
--warning-foreground: 26 83% 14%;
--info: 221 83% 53%;
--info-foreground: 0 0% 100%;
/* Structure */
--border: 220 13% 91%;
--input: 218 14% 86%;
--ring: var(--primary);
/* Geometry */
--radius: 0.5rem;
/* Shadows */
--shadow-sm: 0 2px 4px rgba(0,0,0,0.06);
--shadow-md: 0 4px 16px rgba(0,0,0,0.08);
--shadow-lg: 0 8px 24px rgba(0,0,0,0.10);
/* Motion */
--duration-fast: 150ms;
--duration-normal: 200ms;
--duration-slow: 300ms;
/* Focus */
--ring-width: 2px;
--ring-offset: 2px;
}
.dark {
--background: 222 84% 5%;
--foreground: 210 40% 96%;
--card: 222 47% 11%;
--card-foreground: 210 40% 96%;
--popover: 222 47% 11%;
--popover-foreground: 210 40% 96%;
--muted: 217 33% 17%;
--muted-foreground: 215 20% 65%;
--primary: 217 91% 60%;
--primary-foreground: 222 47% 11%;
--secondary: 217 33% 17%;
--secondary-foreground: 210 40% 96%;
--accent: 217 33% 17%;
--accent-foreground: 210 40% 96%;
--destructive: 0 63% 31%;
--destructive-foreground: 210 40% 98%;
--success: 142 69% 58%;
--success-foreground: 144 61% 10%;
--warning: 48 96% 53%;
--warning-foreground: 22 78% 10%;
--info: 217 91% 60%;
--info-foreground: 222 47% 11%;
--border: 217 33% 17%;
--input: 217 33% 17%;
--ring: 224 76% 48%;
--shadow-sm: 0 2px 4px rgba(0,0,0,0.20);
--shadow-md: 0 4px 16px rgba(0,0,0,0.25);
--shadow-lg: 0 8px 24px rgba(0,0,0,0.30);
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
}
Integration with Plugin Commands
| Command |
How it uses this reference |
/pwdev-uiux:theme create |
Generates a customized version of the CSS template above |
/pwdev-uiux:theme validate |
Checks all foreground/background pairs against contrast requirements |
/pwdev-uiux:theme from-figma |
Maps Figma variables to this token structure |
/pwdev-uiux:scan |
Audits existing UI against these tokens |
/pwdev-uiux:push-to-figma tokens |
Syncs these tokens to Figma variables |
1---2name: ui-theme-reference3description: Canonical design token registry covering colors, typography, spacing, sizing, border radius, shadows, z-index, breakpoints, motion, and focus tokens, with a CSS variable template for project setup.4---56# UI Theme Reference78> Configurable design token registry used by `ui-best-practices` rules.9> Every hardcoded value in the best practices MUST reference a token defined here.10> To customize: override values below or generate via `/pwdev-uiux:theme create`.1112---1314## How to Use1516Rules in the `ui-best-practices` skill reference tokens as `theme.<section>.<token>`.17When implementing, map these tokens to your stack:1819| Stack | Token format | File |20|-------|-------------|------|21| shadcn-vue | `hsl(var(--<token>))` | `src/assets/index.css` |22| shadcn-react | `hsl(var(--<token>))` | `src/app/globals.css` |23| primevue | `var(--p-<token>)` | `src/assets/theme.css` |24| tailwind-only | Tailwind config `theme.extend` | `tailwind.config.ts` |25| custom | Any CSS variable scheme | project-specific |2627---2829## 1. Colors3031### 1.1 Surfaces3233| Token | Light | Dark | Usage |34|-------|-------|------|-------|35| `--background` | `#F9FAFB` · `210 20% 98%` | `#0A0F1A` · `222 84% 5%` | Page background |36| `--foreground` | `#1D2939` · `220 26% 16%` | `#F0F4F8` · `210 40% 96%` | Primary text |37| `--card` | `#FFFFFF` · `0 0% 100%` | `#111827` · `222 47% 11%` | Card / surface background |38| `--card-foreground` | `#1D2939` · `220 26% 16%` | `#F0F4F8` · `210 40% 96%` | Text on cards |39| `--popover` | `#FFFFFF` · `0 0% 100%` | `#111827` · `222 47% 11%` | Popover / dropdown bg |40| `--popover-foreground` | `#1D2939` · `220 26% 16%` | `#F0F4F8` · `210 40% 96%` | Text on popovers |4142### 1.2 Text Hierarchy4344| Token | Light | Dark | Usage |45|-------|-------|------|-------|46| `--foreground` | `#1D2939` | `#F0F4F8` | Primary text, headings |47| `--muted-foreground` | `#667085` | `#94A3B8` | Secondary text, labels, placeholders |4849### 1.3 Interactive5051| Token | Light | Dark | Usage |52|-------|-------|------|-------|53| `--primary` | *brand color* | *brand color (adjusted)* | Buttons, links, focus rings |54| `--primary-foreground` | `#FFFFFF` | `#FFFFFF` | Text on primary backgrounds |55| `--secondary` | `#F1F5F9` | `#1E293B` | Secondary buttons, subtle actions |56| `--secondary-foreground` | `#1D2939` | `#F0F4F8` | Text on secondary backgrounds |57| `--accent` | `#F1F5F9` | `#1E293B` | Hover highlights, active states |58| `--accent-foreground` | `#1D2939` | `#F0F4F8` | Text on accent backgrounds |5960### 1.4 Feedback6162| Token | Light | Dark | Usage |63|-------|-------|------|-------|64| `--success` | `#039855` | `#34D399` | Positive states, confirmations |65| `--success-foreground` | `#FFFFFF` | `#022C22` | Text on success backgrounds |66| `--warning` | `#F79009` | `#FBBF24` | Alerts, caution states |67| `--warning-foreground` | `#422006` | `#422006` | Text on warning backgrounds |68| `--destructive` | `#D92D20` | `#FCA5A5` | Errors, delete actions |69| `--destructive-foreground` | `#FFFFFF` | `#450A0A` | Text on destructive backgrounds |70| `--info` | `#2563EB` | `#60A5FA` | Informational, tips |71| `--info-foreground` | `#FFFFFF` | `#172554` | Text on info backgrounds |7273### 1.5 Structure7475| Token | Light | Dark | Usage |76|-------|-------|------|-------|77| `--border` | `#EAECF0` | `#1E293B` | Dividers, separators |78| `--input` | `#D0D5DD` | `#334155` | Input borders |79| `--ring` | *primary* | *primary* | Focus ring color |80| `--muted` | `#F1F5F9` | `#1E293B` | Muted backgrounds (badges, tags) |8182### 1.6 Reserved Semantic Colors8384These colors carry universal meaning. **Never repurpose them** for decorative or categorical use:8586| Color | Meaning | Allowed usage |87|-------|---------|---------------|88| Green (`--success`) | Good / positive / complete | Success states, positive KPIs, completion |89| Orange (`--warning`) | Caution / attention needed | Warnings, pending actions, approaching limits |90| Red (`--destructive`) | Bad / error / danger | Errors, failures, destructive actions, negative KPIs |9192For categorical/chart colors, use the chart palette below.9394### 1.7 Chart Palette9596Dedicated colors for data visualization — independent from feedback semantics:9798| Token | Default | Usage |99|-------|---------|-------|100| `--chart-1` | `#2563EB` | Primary data series |101| `--chart-2` | `#7C3AED` | Secondary data series |102| `--chart-3` | `#0891B2` | Tertiary data series |103| `--chart-4` | `#C026D3` | Fourth data series |104| `--chart-5` | `#EA580C` | Fifth data series |105| `--chart-muted` | `#D1D5DB` | De-emphasized / comparison series |106107---108109## 2. Typography110111### 2.1 Font Stack112113| Token | Default | Fallbacks |114|-------|---------|-----------|115| `--font-sans` | `Inter` | `system-ui, -apple-system, sans-serif` |116| `--font-mono` | `JetBrains Mono` | `ui-monospace, monospace` |117118### 2.2 Type Scale119120Progressive scale — adjacent levels must not skip more than one step:121122| Token | Size | Line Height | Weight | Usage |123|-------|------|-------------|--------|-------|124| `--text-xs` | `12px` | `16px` | 400 | Footnotes, badges, captions (minimum allowed) |125| `--text-sm` | `14px` | `20px` | 400 | **Default body text**, form labels |126| `--text-base` | `16px` | `24px` | 400 | Emphasized body, card titles |127| `--text-lg` | `18px` | `28px` | 500 | Section headings |128| `--text-xl` | `20px` | `28px` | 600 | Page sub-titles |129| `--text-2xl` | `24px` | `32px` | 600 | Page titles |130| `--text-3xl` | `30px` | `36px` | 700 | Hero headings |131| `--text-4xl` | `36px` | `40px` | 700 | Display / marketing headings |132133**Constraint:** never jump more than 2 steps between adjacent text elements (e.g., `text-3xl` → `text-sm` is forbidden; use `text-3xl` → `text-xl` → `text-base` → `text-sm`).134135### 2.3 Font Weight Scale136137| Token | Value | Usage |138|-------|-------|-------|139| `--font-normal` | `400` | Body text |140| `--font-medium` | `500` | Labels, nav items |141| `--font-semibold` | `600` | Headings, emphasis |142| `--font-bold` | `700` | Hero, display text |143144---145146## 3. Spacing147148Base unit: **4px**. All spacing must be a multiple of 4.149150| Token | Value | Tailwind | Typical Usage |151|-------|-------|----------|---------------|152| `--space-0.5` | `2px` | `gap-0.5` | Micro adjustments only |153| `--space-1` | `4px` | `gap-1` | Icon ↔ label gap |154| `--space-1.5` | `6px` | `gap-1.5` | Compact inline gap |155| `--space-2` | `8px` | `gap-2` | Internal gap, small padding |156| `--space-3` | `12px` | `gap-3` | Badge padding, compact lists |157| `--space-4` | `16px` | `gap-4, p-4` | Default card padding (min) |158| `--space-5` | `20px` | `gap-5` | Medium card padding |159| `--space-6` | `24px` | `gap-6, p-6` | Default card padding (max), section gaps |160| `--space-8` | `32px` | `gap-8, p-8` | Large section padding |161| `--space-10` | `40px` | `gap-10` | Page-level vertical spacing |162| `--space-12` | `48px` | `gap-12` | Major section dividers |163| `--space-16` | `64px` | `gap-16` | Page top/bottom margins |164165### Card Padding Rule166167| Card context | Recommended padding |168|--------------|-------------------|169| Compact (sidebar, list items) | `--space-3` to `--space-4` (12–16px) |170| Standard (content cards) | `--space-4` to `--space-6` (16–24px) |171| Featured / hero cards | `--space-6` to `--space-8` (24–32px) |172| **Ceiling** | Never exceed `--space-8` (32px) in cards |173174---175176## 4. Sizing177178### 4.1 Interactive Elements179180| Token | Value | Usage |181|-------|-------|-------|182| `--height-input` | `40px` | Inputs, selects, single-line controls |183| `--height-button` | `40px` | All buttons (must match input height) |184| `--height-button-sm` | `32px` | Compact buttons (tables, toolbars) |185| `--height-button-lg` | `48px` | Hero CTAs, prominent actions |186| `--min-touch-target` | `44px` | Minimum tap area on touch devices (WCAG 2.5.8) |187188### 4.2 Content Width189190| Token | Value | Usage |191|-------|-------|-------|192| `--max-w-form` | `560px` | Form containers (onboarding, settings) |193| `--max-w-button` | `400px` | Max button width in wide forms |194| `--max-w-content` | `768px` | Article/text-heavy content |195| `--max-w-page` | `1280px` | Page container |196197### 4.3 Textarea Height198199| Context | Rows | Approx Height |200|---------|------|---------------|201| Short input (tagline, slug) | 2 | `~56px` |202| Medium input (description) | 4–5 | `~112px` |203| Long input (feedback, notes) | 6–8 | `~168px` |204205Always enable auto-resize to grow with content.206207---208209## 5. Border Radius210211| Token | Value | Usage |212|-------|-------|-------|213| `--radius` | `8px` *(configurable)* | Base radius — defines product personality |214| `--radius-sm` | `calc(var(--radius) - 4px)` | Badges, small elements |215| `--radius-md` | `calc(var(--radius) - 2px)` | Inputs, buttons |216| `--radius-lg` | `var(--radius)` | Cards, modals |217| `--radius-xl` | `calc(var(--radius) + 4px)` | Feature cards, large containers |218| `--radius-full` | `9999px` | Avatars, pills, tags |219220### Personality Guide221222| Brand Style | `--radius` value |223|-------------|-----------------|224| Modern / trendy | `12px–16px` |225| Neutral / corporate (safe default) | `8px` |226| Enterprise / dense | `4px` |227| Sharp / editorial | `0px–2px` |228229---230231## 6. Shadows232233All shadows use `#000000` with controlled opacity. No colored shadows.234235| Token | Value | Usage |236|-------|-------|-------|237| `--shadow-xs` | `0 1px 2px rgba(0,0,0,0.05)` | Subtle lift (inputs, badges) |238| `--shadow-sm` | `0 2px 4px rgba(0,0,0,0.06)` | Cards at rest |239| `--shadow-md` | `0 4px 16px rgba(0,0,0,0.08)` | Elevated cards, dropdowns |240| `--shadow-lg` | `0 8px 24px rgba(0,0,0,0.10)` | Modals, popovers |241| `--shadow-xl` | `0 16px 48px rgba(0,0,0,0.12)` | Command palette, overlays |242243**Constraints:**244- Minimum opacity: `0.05` (below is invisible)245- Maximum opacity: `0.12` (above feels heavy)246- Never use colored shadows247- Never use gradients as shadow replacements248249---250251## 7. Z-Index Scale252253Managed scale to prevent z-index wars:254255| Token | Value | Usage |256|-------|-------|-------|257| `--z-base` | `0` | Default stacking |258| `--z-dropdown` | `10` | Dropdowns, tooltips |259| `--z-sticky` | `20` | Sticky headers, fixed navs |260| `--z-drawer` | `30` | Side drawers, panels |261| `--z-modal` | `40` | Modals, dialogs |262| `--z-popover` | `50` | Popovers over modals |263| `--z-toast` | `60` | Toast notifications |264| `--z-command` | `70` | Command palette (Cmd+K) |265| `--z-overlay` | `80` | Full-screen overlays |266267---268269## 8. Breakpoints270271| Token | Value | Tailwind | Usage |272|-------|-------|----------|-------|273| `--bp-sm` | `640px` | `sm:` | Large phones landscape |274| `--bp-md` | `768px` | `md:` | Tablets |275| `--bp-lg` | `1024px` | `lg:` | Small laptops |276| `--bp-xl` | `1280px` | `xl:` | Desktops |277| `--bp-2xl` | `1536px` | `2xl:` | Large screens |278279### Navigation Breakpoint Rules280281| Viewport | Max nav items | Menu style |282|----------|--------------|------------|283| `< md` | 4 visible | Bottom bar or hamburger |284| `md–lg` | 5–6 visible | Top bar or compact sidebar |285| `≥ lg` | Unlimited | Full sidebar |286287---288289## 9. Motion & Animation290291| Token | Value | Usage |292|-------|-------|-------|293| `--duration-instant` | `100ms` | Hover color changes, opacity |294| `--duration-fast` | `150ms` | Button press, toggle switch |295| `--duration-normal` | `200ms` | Dropdown open, tooltip appear |296| `--duration-slow` | `300ms` | Drawer slide, modal enter |297| `--duration-slower` | `500ms` | Page transitions, skeleton fade |298| `--ease-default` | `cubic-bezier(0.4, 0, 0.2, 1)` | General purpose easing |299| `--ease-in` | `cubic-bezier(0.4, 0, 1, 1)` | Elements leaving the screen |300| `--ease-out` | `cubic-bezier(0, 0, 0.2, 1)` | Elements entering the screen |301302**Constraint:** always respect `prefers-reduced-motion: reduce` — disable or minimize all animations.303304---305306## 10. Focus & Accessibility307308| Token | Value | Usage |309|-------|-------|-------|310| `--ring-width` | `2px` | Focus ring thickness |311| `--ring-offset` | `2px` | Gap between element and focus ring |312| `--ring-color` | `var(--ring)` | Focus ring color (defaults to primary) |313314### Contrast Requirements (WCAG AA)315316| Element Type | Minimum Ratio |317|-------------|---------------|318| Normal text (< 18px) | **4.5:1** |319| Large text (≥ 18px or ≥ 14px bold) | **3:1** |320| UI components (borders, icons) | **3:1** |321| Non-text contrast (graphs, charts) | **3:1** |322323---324325## CSS Variable Template326327Minimal starter for any project — copy and customize:328329```css330@layer base {331 :root {332 /* Surfaces */333 --background: 210 20% 98%;334 --foreground: 220 26% 16%;335 --card: 0 0% 100%;336 --card-foreground: 220 26% 16%;337 --popover: 0 0% 100%;338 --popover-foreground: 220 26% 16%;339 --muted: 210 40% 96%;340 --muted-foreground: 215 16% 47%;341342 /* Interactive */343 --primary: 221 83% 53%; /* ← your brand color */344 --primary-foreground: 0 0% 100%;345 --secondary: 210 40% 96%;346 --secondary-foreground: 220 26% 16%;347 --accent: 210 40% 96%;348 --accent-foreground: 220 26% 16%;349350 /* Feedback */351 --destructive: 0 72% 51%;352 --destructive-foreground: 0 0% 100%;353 --success: 160 84% 39%;354 --success-foreground: 0 0% 100%;355 --warning: 32 95% 44%;356 --warning-foreground: 26 83% 14%;357 --info: 221 83% 53%;358 --info-foreground: 0 0% 100%;359360 /* Structure */361 --border: 220 13% 91%;362 --input: 218 14% 86%;363 --ring: var(--primary);364365 /* Geometry */366 --radius: 0.5rem;367368 /* Shadows */369 --shadow-sm: 0 2px 4px rgba(0,0,0,0.06);370 --shadow-md: 0 4px 16px rgba(0,0,0,0.08);371 --shadow-lg: 0 8px 24px rgba(0,0,0,0.10);372373 /* Motion */374 --duration-fast: 150ms;375 --duration-normal: 200ms;376 --duration-slow: 300ms;377378 /* Focus */379 --ring-width: 2px;380 --ring-offset: 2px;381 }382383 .dark {384 --background: 222 84% 5%;385 --foreground: 210 40% 96%;386 --card: 222 47% 11%;387 --card-foreground: 210 40% 96%;388 --popover: 222 47% 11%;389 --popover-foreground: 210 40% 96%;390 --muted: 217 33% 17%;391 --muted-foreground: 215 20% 65%;392393 --primary: 217 91% 60%;394 --primary-foreground: 222 47% 11%;395 --secondary: 217 33% 17%;396 --secondary-foreground: 210 40% 96%;397 --accent: 217 33% 17%;398 --accent-foreground: 210 40% 96%;399400 --destructive: 0 63% 31%;401 --destructive-foreground: 210 40% 98%;402 --success: 142 69% 58%;403 --success-foreground: 144 61% 10%;404 --warning: 48 96% 53%;405 --warning-foreground: 22 78% 10%;406 --info: 217 91% 60%;407 --info-foreground: 222 47% 11%;408409 --border: 217 33% 17%;410 --input: 217 33% 17%;411 --ring: 224 76% 48%;412413 --shadow-sm: 0 2px 4px rgba(0,0,0,0.20);414 --shadow-md: 0 4px 16px rgba(0,0,0,0.25);415 --shadow-lg: 0 8px 24px rgba(0,0,0,0.30);416 }417418 @media (prefers-reduced-motion: reduce) {419 *, *::before, *::after {420 animation-duration: 0.01ms !important;421 transition-duration: 0.01ms !important;422 }423 }424}425```426427---428429## Integration with Plugin Commands430431| Command | How it uses this reference |432|---------|--------------------------|433| `/pwdev-uiux:theme create` | Generates a customized version of the CSS template above |434| `/pwdev-uiux:theme validate` | Checks all foreground/background pairs against contrast requirements |435| `/pwdev-uiux:theme from-figma` | Maps Figma variables to this token structure |436| `/pwdev-uiux:scan` | Audits existing UI against these tokens |437| `/pwdev-uiux:push-to-figma tokens` | Syncs these tokens to Figma variables |