# Color Guide Color is the emotional backbone of UI. Get it wrong and your product looks either amateur or AI-generated. Get it right and everything feels intentional. --- ## 0. Context First Before touching palettes, answer these questions: | Question | Why It Matters | |----------|----------------| | **Product UI or marketing?** | Product: fewer colors, more neutrals, strict semantics. Marketing: more emotion, gradients, contrast allowed. | | **Data density?** | Dashboards need muted accents, high text contrast, no "glowing" colors. Content-focused UI can be softer. | | **Is brand defined?** | No brand: use safe preset, refine later. Existing brand: translate brand color into system tokens, don't paint everything with it. | **Hard rule:** > When in doubt — fewer colors, more neutrals, stricter purpose. Restraint beats "colorful." This single rule eliminates 50% of AI-slop before you start. --- ## 1. Color Space Why most palettes "break" when you try to extend them. ### The Problem with HSL HSL is intuitive but poorly represents perceptual brightness. A "50% lightness" yellow looks much brighter than "50% lightness" blue. This makes consistent scales nearly impossible. ### The Solution: OKLCH OKLCH (or LCH) provides perceptually uniform lightness. Steps from 50→950 actually look even. **Practical workflow:** - Generate and adjust palettes in OKLCH - Store production values as hex - Keep OKLCH logic as source of truth ```css /* OKLCH example */ --primary-500: oklch(0.55 0.2 250); /* Base */ --primary-600: oklch(0.48 0.2 250); /* Hover */ --primary-700: oklch(0.41 0.2 250); /* Active */ ``` **For MVP:** You can skip OKLCH. Use curated palettes (Tailwind, Radix, Open Color). But know why they work. --- ## 2. Palette Structure You need 4 layers, not "30 beautiful colors." ### 2.1 Neutrals (Most Important) Neutrals are 70–90% of your UI. This is where you win or lose. **Requirements:** - 10-12 steps: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950 - Slight character (warm or cool), not colorful circus - Consistent across light and dark themes **Scale reference:** | Step | Use | Example | |------|-----|---------| | 50 | Near-white backgrounds | `#fafafa` | | 100-200 | Surfaces, cards | `#f5f5f5`, `#e5e5e5` | | 300-400 | Borders, dividers | `#d4d4d4`, `#a3a3a3` | | 500 | Placeholder text | `#737373` | | 600-700 | Secondary text | `#525252`, `#404040` | | 800-900 | Primary text | `#262626`, `#171717` | | 950 | Near-black | `#0a0a0a` | **Hard rules:** - Never use pure `#000` on white as body text - Don't make text gray "for breathing room" — spacing creates breathing room, not faded text ### 2.2 Primary Accent One brand color. It should: - Have good contrast on both white and dark backgrounds - Have a full scale (50–950), not just one hex - Be used sparingly and purposefully **Typical usage:** | Step | Use | |------|-----| | 50-100 | Tinted backgrounds | | 500-600 | Default state | | 600-700 | Hover state | | 700-800 | Active/pressed state | ### 2.3 Semantic Colors Usually 3-4: - **Success** — Green (confirmations, completion) - **Warning** — Amber/Yellow (attention needed) - **Danger** — Red (errors, destructive actions) - **Info** — Blue (neutral information) — optional **Important:** Semantics work through pairs, not single colors. ```css /* Each semantic needs: */ --success: #16a34a; /* Icon, text accent */ --success-bg: #f0fdf4; /* Background */ --success-border: #86efac; /* Border */ --on-success: #ffffff; /* Text on solid success */ ``` ### 2.4 Effects (Only If Needed) - Gradients - Glows - Illustration tints **Rule:** In product UI, effects should be rare and localized. Save drama for marketing. --- ## 3. The 60/30/10 Rule Distribution that works for any interface: | Percentage | Elements | |------------|----------| | 60-80% | Neutrals (backgrounds, surfaces, borders) | | 10-20% | Text hierarchy (different gray levels) | | 5-10% | Accents and semantics | ### Component Color Limit **Maximum 2 colors per component.** If a button has brand gradient + colored border + colored shadow + colored text, it's almost always garbage. ### State Changes: Structure, Not Circus Hover and Active should be: - Slightly darker/lighter - Slightly more contrast - Subtle shadow enhancement **Don't** repaint every state with a new random color. ```css /* Good */ .button { background: var(--primary); } .button:hover { background: var(--primary-hover); /* Just darker */ } /* Bad */ .button:hover { background: linear-gradient(135deg, #ff6b6b, #feca57); box-shadow: 0 0 20px #ff6b6b; } ``` --- ## 4. Contrast and Readability Not about checking boxes — about actual readability. ### Minimum Requirements | Text Type | WCAG AA Ratio | |-----------|---------------| | Body text (≤16px) | 4.5:1 | | Large text (18px+ bold, 24px+ regular) | 3:1 | | UI components, icons | 3:1 | ### Common Failures 1. **Secondary text too pale** — The #1 issue. If it looks fine on your Retina display at noon, it fails on cheap monitors at 9pm. 2. **Text on tinted backgrounds** — "Almost readable" text on colored backgrounds fails in real conditions (tired eyes, ambient light, older monitors). ### Practical Check - Test secondary text on multiple devices - If you squint and text disappears, it's too light - Ask: "Would my parents read this easily?" --- ## 5. Light and Dark Themes ### The Wrong Way Inverting colors mechanically: white → black, black → white. Result: eye-burning contrast, amateur look. ### The Right Way **Dark theme gets its own neutral scale.** ```css /* Light */ :root { --bg: #ffffff; --surface: #f7f7f7; --text: #0b0b0b; --text-muted: #5f6368; } /* Dark — NOT just inverted */ [data-theme="dark"] { --bg: #0f0f0f; /* Not #000 */ --surface: #1a1a1a; --text: #f0f0f0; /* Not #fff */ --text-muted: #a1a1a1; } ``` ### Dark Theme Elevation In dark UI, surfaces and layers communicate through: - Slightly lighter backgrounds for elevated elements - Subtle borders (1px, low contrast) - Very soft shadows or no shadows at all ```css [data-theme="dark"] { --surface-elevated: #242424; /* Lighter than base */ --border: rgba(255, 255, 255, 0.1); } ``` ### Dark Mode: Technical Implementation Browser-level settings that most developers miss: ```html ``` ```css /* On — fixes scrollbars, form controls, system dialogs */ :root { color-scheme: light; } [data-theme="dark"] { color-scheme: dark; } ``` **Why this matters:** - Without `color-scheme: dark`, scrollbars stay light gray on dark backgrounds - Form inputs (``, `