Frontend Design
Purpose
Pre-coding design process with aesthetic principles for building beautiful, cohesive user interfaces. Covers typography, color theory, motion design, spatial composition, design tokens, and design system thinking. Includes anti-patterns to avoid.
Activation
Use this skill when the user asks about:
UI/UX design decisions before coding
Typography choices and scale
Color palettes and color theory
Animation and motion design
Layout composition and spacing
Design tokens and systems
Visual aesthetics and polish
Pre-Coding Design Process
Before writing any UI code, go through this process:
1. Define the Design Intent
Ask these questions:
What emotion should the interface evoke? (calm, energetic, professional, playful)
Who is the target audience? (developers, consumers, enterprise, creative)
What existing brand assets or guidelines exist?
What is the primary action on each screen?
2. Establish Visual Hierarchy
Every screen needs a clear hierarchy:
Primary element - The single most important thing (headline, CTA, hero image)
Secondary elements - Supporting content (descriptions, secondary actions)
Tertiary elements - Navigation, metadata, supplementary information
Background - Negative space, subtle patterns, container boundaries
3. Choose a Design Direction
Direction
Characteristics
Best For
Minimal
Lots of whitespace, monochrome, thin fonts
Developer tools, SaaS dashboards
Editorial
Large type, asymmetric layouts, serif fonts
Blogs, magazines, portfolios
Corporate
Clean grid, blue tones, system fonts
Enterprise, fintech, healthcare
Playful
Bold colors, rounded shapes, illustration
Consumer apps, education, games
Brutalist
Raw, high contrast, intentionally rough
Creative agencies, art, experimental
Typography
Type Scale
Use a mathematically consistent scale. The most common ratio is 1.250 (Major Third):
:root {
/* Base: 16px */
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
--text-3xl: 1.875rem; /* 30px */
--text-4xl: 2.25rem; /* 36px */
--text-5xl: 3rem; /* 48px */
--text-6xl: 3.75rem; /* 60px */
--text-7xl: 4.5rem; /* 72px */
}
Font Pairing Rules
One font family is usually enough - Use weight and size for hierarchy
Maximum two families - One for headings, one for body
Pair serif with sans-serif - Not two serifs or two sans-serifs
Match x-height - Paired fonts should have similar x-heights
Recommended Font Stacks
/* Modern sans-serif system stack */
--font-sans: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", sans-serif;
/* Monospace for code */
--font-mono: "JetBrains Mono", "Fira Code", "SF Mono", "Cascadia Code",
"Consolas", monospace;
/* Editorial serif */
--font-serif: "Newsreader", "Lora", "Merriweather", Georgia, "Times New Roman", serif;
/* Display / headings */
--font-display: "Cal Sans", "Cabinet Grotesk", "Satoshi", sans-serif;
Typography Anti-Patterns
Anti-Pattern
Why It Fails
Alternative
Arial / Helvetica as primary
Generic, overused, no personality
Inter, Geist, or system stack
More than 2 font families
Visual noise, inconsistent
One family with weight variation
Body text below 16px on mobile
Unreadable, fails accessibility
16px minimum for body text
Line height below 1.4 for body
Cramped, hard to read
1.5 - 1.7 for body text
All caps for long text
Harder to read
Use for short labels only
Centered text for paragraphs
Hard to scan left edge
Left-align body text
Line length over 75 characters
Eye tracking fatigue
45-75 characters per line
Color Theory
Building a Color Palette
Start with a single brand/primary color and derive everything else:
:root {
/* Primary: The brand color - used for CTAs, links, focus rings */
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-200: #bfdbfe;
--color-primary-300: #93c5fd;
--color-primary-400: #60a5fa;
--color-primary-500: #3b82f6; /* Base */
--color-primary-600: #2563eb;
--color-primary-700: #1d4ed8;
--color-primary-800: #1e40af;
--color-primary-900: #1e3a8a;
--color-primary-950: #172554;
/* Neutral: For text, backgrounds, borders */
--color-neutral-50: #fafafa;
--color-neutral-100: #f5f5f5;
--color-neutral-200: #e5e5e5;
--color-neutral-300: #d4d4d4;
--color-neutral-400: #a3a3a3;
--color-neutral-500: #737373;
--color-neutral-600: #525252;
--color-neutral-700: #404040;
--color-neutral-800: #262626;
--color-neutral-900: #171717;
--color-neutral-950: #0a0a0a;
/* Semantic colors */
--color-success: #22c55e;
--color-warning: #f59e0b;
--color-error: #ef4444;
--color-info: #3b82f6;
}
Color Usage Rules
60-30-10 rule - 60% neutral, 30% secondary, 10% accent
Primary for actions - Buttons, links, focus states
Neutral for content - Text, backgrounds, borders
Semantic for feedback - Success/error/warning/info states
Test contrast ratios - WCAG AA requires 4.5:1 for normal text, 3:1 for large text
Color Anti-Patterns
Anti-Pattern
Why It Fails
Alternative
Purple-to-pink gradients
Overused in 2020s, loses impact
Solid colors or subtle gradients
Pure black (#000) on white (#fff)
Too harsh, causes eye strain
Near-black (#171717) on off-white (#fafafa)
Too many accent colors
Visual chaos
One primary, one accent max
Color as only indicator
Fails for colorblind users
Add icons or text labels
Saturated colors for large areas
Overwhelming, tiring
Reserve saturation for small accents
Neon/fluorescent colors
Poor readability
Muted, accessible alternatives
Dark Mode
/* Light mode tokens */
:root {
--bg-primary: #ffffff;
--bg-secondary: #f5f5f5;
--bg-tertiary: #e5e5e5;
--text-primary: #171717;
--text-secondary:#525252;
--text-tertiary: #a3a3a3;
--border: #e5e5e5;
}
/* Dark mode tokens */
@media (prefers-color-scheme: dark) {
:root {
--bg-primary: #0a0a0a;
--bg-secondary: #171717;
--bg-tertiary: #262626;
--text-primary: #fafafa;
--text-secondary:#a3a3a3;
--text-tertiary: #525252;
--border: #262626;
}
}
Dark mode rules:
Never just invert colors - redesign the elevation system
Reduce saturation of colors in dark mode
Use elevation (lighter = closer) instead of shadows
Test all UI states in both modes
Motion Design
Animation Principles
:root {
/* Duration scale */
--duration-instant: 50ms; /* Micro-interactions (checkmarks) */
--duration-fast: 100ms; /* Button state changes */
--duration-normal: 200ms; /* Most transitions */
--duration-slow: 300ms; /* Page transitions, modals */
--duration-slower: 500ms; /* Complex animations */
/* Easing curves */
--ease-in: cubic-bezier(0.4, 0, 1, 0.2); /* Exits */
--ease-out: cubic-bezier(0, 0, 0.2, 1); /* Entrances */
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); /* Move within view */
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Bouncy, playful */
}
When to Animate
Interaction
Animation
Duration
Easing
Button hover/press
Scale + color
100ms
ease-out
Modal open
Fade + scale up
200ms
ease-out
Modal close
Fade + scale down
150ms
ease-in
Dropdown open
Slide down + fade
200ms
ease-out
Page transition
Fade
200ms
ease-in-out
Toast notification
Slide in
300ms
ease-spring
Skeleton loading
Pulse/shimmer
1.5s loop
ease-in-out
Checkbox toggle
Scale pop
150ms
ease-spring
Animation Anti-Patterns
Anti-Pattern
Why It Fails
Animation longer than 500ms
Feels sluggish, blocks interaction
Linear easing
Feels robotic, unnatural
Animating layout properties (width, height, top, left)
Causes reflow, janky performance
Animation without reduced-motion support
Accessibility violation
Entrance animation on page load for all elements
Distracting, slow perceived load
Bouncing/spinning loaders
Anxiety-inducing, feels slow
Respecting User Preferences
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
Spatial Composition
Spacing Scale
Use a consistent 4px base grid:
:root {
--space-0: 0;
--space-0.5: 0.125rem; /* 2px */
--space-1: 0.25rem; /* 4px */
--space-1.5: 0.375rem; /* 6px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-5: 1.25rem; /* 20px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-10: 2.5rem; /* 40px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
--space-20: 5rem; /* 80px */
--space-24: 6rem; /* 96px */
}
Spacing Rules
Proximity = relationship - Related items closer, unrelated items farther
Consistent internal padding - Cards, sections use the same internal spacing
Increase spacing as viewport grows - More whitespace on larger screens
Section spacing > component spacing > element spacing - Clear hierarchy
Never eyeball it - Always use the spacing scale
Border Radius Scale
:root {
--radius-none: 0;
--radius-sm: 0.25rem; /* 4px - subtle rounding */
--radius-md: 0.5rem; /* 8px - cards, inputs */
--radius-lg: 0.75rem; /* 12px - larger cards */
--radius-xl: 1rem; /* 16px - modals */
--radius-2xl: 1.5rem; /* 24px - pills */
--radius-full: 9999px; /* Circles, chips */
}
Pick one or two values and use them consistently. Mixing many different radii looks unpolished.
Design Tokens
Token Architecture
/* Level 1: Primitive tokens (raw values) */
:root {
--blue-500: #3b82f6;
--gray-900: #171717;
--radius-8: 0.5rem;
--font-size-16: 1rem;
}
/* Level 2: Semantic tokens (meaning) */
:root {
--color-action-primary: var(--blue-500);
--color-text-primary: var(--gray-900);
--border-radius-card: var(--radius-8);
--font-size-body: var(--font-size-16);
}
/* Level 3: Component tokens (specific usage) */
:root {
--button-bg: var(--color-action-primary);
--button-radius: var(--border-radius-card);
--card-radius: var(--border-radius-card);
--input-radius: var(--border-radius-card);
}
Tailwind CSS Design Tokens
// tailwind.config.ts
import type { Config } from "tailwindcss";
export default {
theme: {
extend: {
colors: {
brand: {
50: "#eff6ff",
// ... full scale
950: "#172554",
},
},
fontFamily: {
sans: ["Inter Variable", "Inter", ...defaultTheme.fontFamily.sans],
mono: ["JetBrains Mono", ...defaultTheme.fontFamily.mono],
},
borderRadius: {
card: "0.75rem",
},
animation: {
"fade-in": "fade-in 200ms ease-out",
"slide-up": "slide-up 300ms ease-out",
},
keyframes: {
"fade-in": {
from: { opacity: "0" },
to: { opacity: "1" },
},
"slide-up": {
from: { opacity: "0", transform: "translateY(8px)" },
to: { opacity: "1", transform: "translateY(0)" },
},
},
},
},
} satisfies Config;
Design System Thinking
Component API Design
When designing component props, think about:
// GOOD: Clear, constrained API
<Button variant="primary" size="md" disabled>
Save Changes
</Button>
// BAD: Too many open-ended props
<Button
color="#3b82f6"
hoverColor="#2563eb"
fontSize="14px"
padding="8px 16px"
borderRadius="8px"
>
Save Changes
</Button>
Design Checklist Before Coding
Color palette defined with accessible contrast ratios
Typography scale chosen (font family, sizes, weights, line heights)
Spacing scale defined (4px or 8px base)
Border radius consistency decided
Shadow/elevation scale defined
Dark mode token mapping complete
Motion/animation timing and easing defined
Breakpoints defined for responsive design
Component states covered (default, hover, focus, active, disabled, loading, error)
Empty states designed (no data, first-time user, error states)
1 --- 2 name: frontend-design 3 description: Pre-coding design process and aesthetic principles. Use when designing UIs, working with typography, color theory, motion design, or design tokens. 4 --- 5 6 # Frontend Design 7 8 ## Purpose 9 10 Pre-coding design process with aesthetic principles for building beautiful, cohesive user interfaces. Covers typography, color theory, motion design, spatial composition, design tokens, and design system thinking. Includes anti-patterns to avoid. 11 12 ## Activation 13 14 Use this skill when the user asks about: 15 - UI/UX design decisions before coding 16 - Typography choices and scale 17 - Color palettes and color theory 18 - Animation and motion design 19 - Layout composition and spacing 20 - Design tokens and systems 21 - Visual aesthetics and polish 22 23 ## Pre-Coding Design Process 24 25 Before writing any UI code, go through this process: 26 27 ### 1. Define the Design Intent 28 29 Ask these questions: 30 - What emotion should the interface evoke? (calm, energetic, professional, playful) 31 - Who is the target audience? (developers, consumers, enterprise, creative) 32 - What existing brand assets or guidelines exist? 33 - What is the primary action on each screen? 34 35 ### 2. Establish Visual Hierarchy 36 37 Every screen needs a clear hierarchy: 38 1. **Primary element** - The single most important thing (headline, CTA, hero image) 39 2. **Secondary elements** - Supporting content (descriptions, secondary actions) 40 3. **Tertiary elements** - Navigation, metadata, supplementary information 41 4. **Background** - Negative space, subtle patterns, container boundaries 42 43 ### 3. Choose a Design Direction 44 45 | Direction | Characteristics | Best For | 46 |---|---|---| 47 | Minimal | Lots of whitespace, monochrome, thin fonts | Developer tools, SaaS dashboards | 48 | Editorial | Large type, asymmetric layouts, serif fonts | Blogs, magazines, portfolios | 49 | Corporate | Clean grid, blue tones, system fonts | Enterprise, fintech, healthcare | 50 | Playful | Bold colors, rounded shapes, illustration | Consumer apps, education, games | 51 | Brutalist | Raw, high contrast, intentionally rough | Creative agencies, art, experimental | 52 53 ## Typography 54 55 ### Type Scale 56 57 Use a mathematically consistent scale. The most common ratio is 1.250 (Major Third): 58 59 ```css 60 :root { 61 /* Base: 16px */ 62 --text-xs: 0.75rem; /* 12px */ 63 --text-sm: 0.875rem; /* 14px */ 64 --text-base: 1rem; /* 16px */ 65 --text-lg: 1.125rem; /* 18px */ 66 --text-xl: 1.25rem; /* 20px */ 67 --text-2xl: 1.5rem; /* 24px */ 68 --text-3xl: 1.875rem; /* 30px */ 69 --text-4xl: 2.25rem; /* 36px */ 70 --text-5xl: 3rem; /* 48px */ 71 --text-6xl: 3.75rem; /* 60px */ 72 --text-7xl: 4.5rem; /* 72px */ 73 } 74 ``` 75 76 ### Font Pairing Rules 77 78 1. **One font family is usually enough** - Use weight and size for hierarchy 79 2. **Maximum two families** - One for headings, one for body 80 3. **Pair serif with sans-serif** - Not two serifs or two sans-serifs 81 4. **Match x-height** - Paired fonts should have similar x-heights 82 83 ### Recommended Font Stacks 84 85 ```css 86 /* Modern sans-serif system stack */ 87 --font-sans: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, 88 "Segoe UI", Roboto, "Helvetica Neue", sans-serif; 89 90 /* Monospace for code */ 91 --font-mono: "JetBrains Mono", "Fira Code", "SF Mono", "Cascadia Code", 92 "Consolas", monospace; 93 94 /* Editorial serif */ 95 --font-serif: "Newsreader", "Lora", "Merriweather", Georgia, "Times New Roman", serif; 96 97 /* Display / headings */ 98 --font-display: "Cal Sans", "Cabinet Grotesk", "Satoshi", sans-serif; 99 ``` 100 101 ### Typography Anti-Patterns 102 103 | Anti-Pattern | Why It Fails | Alternative | 104 |---|---|---| 105 | Arial / Helvetica as primary | Generic, overused, no personality | Inter, Geist, or system stack | 106 | More than 2 font families | Visual noise, inconsistent | One family with weight variation | 107 | Body text below 16px on mobile | Unreadable, fails accessibility | 16px minimum for body text | 108 | Line height below 1.4 for body | Cramped, hard to read | 1.5 - 1.7 for body text | 109 | All caps for long text | Harder to read | Use for short labels only | 110 | Centered text for paragraphs | Hard to scan left edge | Left-align body text | 111 | Line length over 75 characters | Eye tracking fatigue | 45-75 characters per line | 112 113 ## Color Theory 114 115 ### Building a Color Palette 116 117 Start with a single brand/primary color and derive everything else: 118 119 ```css 120 :root { 121 /* Primary: The brand color - used for CTAs, links, focus rings */ 122 --color-primary-50: #eff6ff; 123 --color-primary-100: #dbeafe; 124 --color-primary-200: #bfdbfe; 125 --color-primary-300: #93c5fd; 126 --color-primary-400: #60a5fa; 127 --color-primary-500: #3b82f6; /* Base */ 128 --color-primary-600: #2563eb; 129 --color-primary-700: #1d4ed8; 130 --color-primary-800: #1e40af; 131 --color-primary-900: #1e3a8a; 132 --color-primary-950: #172554; 133 134 /* Neutral: For text, backgrounds, borders */ 135 --color-neutral-50: #fafafa; 136 --color-neutral-100: #f5f5f5; 137 --color-neutral-200: #e5e5e5; 138 --color-neutral-300: #d4d4d4; 139 --color-neutral-400: #a3a3a3; 140 --color-neutral-500: #737373; 141 --color-neutral-600: #525252; 142 --color-neutral-700: #404040; 143 --color-neutral-800: #262626; 144 --color-neutral-900: #171717; 145 --color-neutral-950: #0a0a0a; 146 147 /* Semantic colors */ 148 --color-success: #22c55e; 149 --color-warning: #f59e0b; 150 --color-error: #ef4444; 151 --color-info: #3b82f6; 152 } 153 ``` 154 155 ### Color Usage Rules 156 157 1. **60-30-10 rule** - 60% neutral, 30% secondary, 10% accent 158 2. **Primary for actions** - Buttons, links, focus states 159 3. **Neutral for content** - Text, backgrounds, borders 160 4. **Semantic for feedback** - Success/error/warning/info states 161 5. **Test contrast ratios** - WCAG AA requires 4.5:1 for normal text, 3:1 for large text 162 163 ### Color Anti-Patterns 164 165 | Anti-Pattern | Why It Fails | Alternative | 166 |---|---|---| 167 | Purple-to-pink gradients | Overused in 2020s, loses impact | Solid colors or subtle gradients | 168 | Pure black (#000) on white (#fff) | Too harsh, causes eye strain | Near-black (#171717) on off-white (#fafafa) | 169 | Too many accent colors | Visual chaos | One primary, one accent max | 170 | Color as only indicator | Fails for colorblind users | Add icons or text labels | 171 | Saturated colors for large areas | Overwhelming, tiring | Reserve saturation for small accents | 172 | Neon/fluorescent colors | Poor readability | Muted, accessible alternatives | 173 174 ### Dark Mode 175 176 ```css 177 /* Light mode tokens */ 178 :root { 179 --bg-primary: #ffffff; 180 --bg-secondary: #f5f5f5; 181 --bg-tertiary: #e5e5e5; 182 --text-primary: #171717; 183 --text-secondary:#525252; 184 --text-tertiary: #a3a3a3; 185 --border: #e5e5e5; 186 } 187 188 /* Dark mode tokens */ 189 @media (prefers-color-scheme: dark) { 190 :root { 191 --bg-primary: #0a0a0a; 192 --bg-secondary: #171717; 193 --bg-tertiary: #262626; 194 --text-primary: #fafafa; 195 --text-secondary:#a3a3a3; 196 --text-tertiary: #525252; 197 --border: #262626; 198 } 199 } 200 ``` 201 202 Dark mode rules: 203 - Never just invert colors - redesign the elevation system 204 - Reduce saturation of colors in dark mode 205 - Use elevation (lighter = closer) instead of shadows 206 - Test all UI states in both modes 207 208 ## Motion Design 209 210 ### Animation Principles 211 212 ```css 213 :root { 214 /* Duration scale */ 215 --duration-instant: 50ms; /* Micro-interactions (checkmarks) */ 216 --duration-fast: 100ms; /* Button state changes */ 217 --duration-normal: 200ms; /* Most transitions */ 218 --duration-slow: 300ms; /* Page transitions, modals */ 219 --duration-slower: 500ms; /* Complex animations */ 220 221 /* Easing curves */ 222 --ease-in: cubic-bezier(0.4, 0, 1, 0.2); /* Exits */ 223 --ease-out: cubic-bezier(0, 0, 0.2, 1); /* Entrances */ 224 --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); /* Move within view */ 225 --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Bouncy, playful */ 226 } 227 ``` 228 229 ### When to Animate 230 231 | Interaction | Animation | Duration | Easing | 232 |---|---|---|---| 233 | Button hover/press | Scale + color | 100ms | ease-out | 234 | Modal open | Fade + scale up | 200ms | ease-out | 235 | Modal close | Fade + scale down | 150ms | ease-in | 236 | Dropdown open | Slide down + fade | 200ms | ease-out | 237 | Page transition | Fade | 200ms | ease-in-out | 238 | Toast notification | Slide in | 300ms | ease-spring | 239 | Skeleton loading | Pulse/shimmer | 1.5s loop | ease-in-out | 240 | Checkbox toggle | Scale pop | 150ms | ease-spring | 241 242 ### Animation Anti-Patterns 243 244 | Anti-Pattern | Why It Fails | 245 |---|---| 246 | Animation longer than 500ms | Feels sluggish, blocks interaction | 247 | Linear easing | Feels robotic, unnatural | 248 | Animating layout properties (width, height, top, left) | Causes reflow, janky performance | 249 | Animation without reduced-motion support | Accessibility violation | 250 | Entrance animation on page load for all elements | Distracting, slow perceived load | 251 | Bouncing/spinning loaders | Anxiety-inducing, feels slow | 252 253 ### Respecting User Preferences 254 255 ```css 256 @media (prefers-reduced-motion: reduce) { 257 *, 258 *::before, 259 *::after { 260 animation-duration: 0.01ms !important; 261 animation-iteration-count: 1 !important; 262 transition-duration: 0.01ms !important; 263 scroll-behavior: auto !important; 264 } 265 } 266 ``` 267 268 ## Spatial Composition 269 270 ### Spacing Scale 271 272 Use a consistent 4px base grid: 273 274 ```css 275 :root { 276 --space-0: 0; 277 --space-0.5: 0.125rem; /* 2px */ 278 --space-1: 0.25rem; /* 4px */ 279 --space-1.5: 0.375rem; /* 6px */ 280 --space-2: 0.5rem; /* 8px */ 281 --space-3: 0.75rem; /* 12px */ 282 --space-4: 1rem; /* 16px */ 283 --space-5: 1.25rem; /* 20px */ 284 --space-6: 1.5rem; /* 24px */ 285 --space-8: 2rem; /* 32px */ 286 --space-10: 2.5rem; /* 40px */ 287 --space-12: 3rem; /* 48px */ 288 --space-16: 4rem; /* 64px */ 289 --space-20: 5rem; /* 80px */ 290 --space-24: 6rem; /* 96px */ 291 } 292 ``` 293 294 ### Spacing Rules 295 296 1. **Proximity = relationship** - Related items closer, unrelated items farther 297 2. **Consistent internal padding** - Cards, sections use the same internal spacing 298 3. **Increase spacing as viewport grows** - More whitespace on larger screens 299 4. **Section spacing > component spacing > element spacing** - Clear hierarchy 300 5. **Never eyeball it** - Always use the spacing scale 301 302 ### Border Radius Scale 303 304 ```css 305 :root { 306 --radius-none: 0; 307 --radius-sm: 0.25rem; /* 4px - subtle rounding */ 308 --radius-md: 0.5rem; /* 8px - cards, inputs */ 309 --radius-lg: 0.75rem; /* 12px - larger cards */ 310 --radius-xl: 1rem; /* 16px - modals */ 311 --radius-2xl: 1.5rem; /* 24px - pills */ 312 --radius-full: 9999px; /* Circles, chips */ 313 } 314 ``` 315 316 Pick one or two values and use them consistently. Mixing many different radii looks unpolished. 317 318 ## Design Tokens 319 320 ### Token Architecture 321 322 ```css 323 /* Level 1: Primitive tokens (raw values) */ 324 :root { 325 --blue-500: #3b82f6; 326 --gray-900: #171717; 327 --radius-8: 0.5rem; 328 --font-size-16: 1rem; 329 } 330 331 /* Level 2: Semantic tokens (meaning) */ 332 :root { 333 --color-action-primary: var(--blue-500); 334 --color-text-primary: var(--gray-900); 335 --border-radius-card: var(--radius-8); 336 --font-size-body: var(--font-size-16); 337 } 338 339 /* Level 3: Component tokens (specific usage) */ 340 :root { 341 --button-bg: var(--color-action-primary); 342 --button-radius: var(--border-radius-card); 343 --card-radius: var(--border-radius-card); 344 --input-radius: var(--border-radius-card); 345 } 346 ``` 347 348 ### Tailwind CSS Design Tokens 349 350 ```typescript 351 // tailwind.config.ts 352 import type { Config } from "tailwindcss"; 353 354 export default { 355 theme: { 356 extend: { 357 colors: { 358 brand: { 359 50: "#eff6ff", 360 // ... full scale 361 950: "#172554", 362 }, 363 }, 364 fontFamily: { 365 sans: ["Inter Variable", "Inter", ...defaultTheme.fontFamily.sans], 366 mono: ["JetBrains Mono", ...defaultTheme.fontFamily.mono], 367 }, 368 borderRadius: { 369 card: "0.75rem", 370 }, 371 animation: { 372 "fade-in": "fade-in 200ms ease-out", 373 "slide-up": "slide-up 300ms ease-out", 374 }, 375 keyframes: { 376 "fade-in": { 377 from: { opacity: "0" }, 378 to: { opacity: "1" }, 379 }, 380 "slide-up": { 381 from: { opacity: "0", transform: "translateY(8px)" }, 382 to: { opacity: "1", transform: "translateY(0)" }, 383 }, 384 }, 385 }, 386 }, 387 } satisfies Config; 388 ``` 389 390 ## Design System Thinking 391 392 ### Component API Design 393 394 When designing component props, think about: 395 396 ```tsx 397 // GOOD: Clear, constrained API 398 <Button variant="primary" size="md" disabled> 399 Save Changes 400 </Button> 401 402 // BAD: Too many open-ended props 403 <Button 404 color="#3b82f6" 405 hoverColor="#2563eb" 406 fontSize="14px" 407 padding="8px 16px" 408 borderRadius="8px" 409 > 410 Save Changes 411 </Button> 412 ``` 413 414 ### Design Checklist Before Coding 415 416 - [ ] Color palette defined with accessible contrast ratios 417 - [ ] Typography scale chosen (font family, sizes, weights, line heights) 418 - [ ] Spacing scale defined (4px or 8px base) 419 - [ ] Border radius consistency decided 420 - [ ] Shadow/elevation scale defined 421 - [ ] Dark mode token mapping complete 422 - [ ] Motion/animation timing and easing defined 423 - [ ] Breakpoints defined for responsive design 424 - [ ] Component states covered (default, hover, focus, active, disabled, loading, error) 425 - [ ] Empty states designed (no data, first-time user, error states)