Color theory beyond palette generation: color harmony rules (complementary, analogous, triadic, split-complementary), color psychology by industry, dark mode color strategy (perceptual lightness, not inversion), simultaneous contrast, color blindness design patterns, and HSL/OKLCH color space decisions. The reasoning behind color choices, not just the output.
From clarcnpx claudepluginhub marvinrichter/clarc --plugin clarcThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
invert() filterHarmony rules predict which colors feel intentional together vs. random.
Based on hue (0–360°):
0° Red
30° Orange
60° Yellow
90° Yellow-green
120° Green
150° Blue-green
180° Cyan
210° Blue-cyan
240° Blue
270° Violet
300° Magenta
330° Rose
360° Red (same as 0°)
| Harmony | Formula | Character |
|---|---|---|
| Monochromatic | Same hue, vary lightness/saturation | Cohesive, calm, can feel flat |
| Analogous | 3 hues within 30-60° of each other | Natural, comfortable, low tension |
| Complementary | Hues 180° apart | High contrast, energetic, can vibrate |
| Split-complementary | Base + two hues 150° from base | Contrast without vibration |
| Triadic | 3 hues 120° apart | Vivid, balanced, complex |
| Tetradic / Square | 4 hues 90° apart | Rich palette, hard to balance |
SaaS / productivity tool → Monochromatic (calm) + semantic accent colors
Marketing / landing page → Split-complementary (energetic but controlled)
Brand identity → Analogous (memorable cohesion) + 1 complementary accent
Data visualization → Triadic or tetradic (maximum differentiation)
Emergency / health UI → Complementary avoided — red+green is color-blind problematic
60% — Dominant color (usually neutral)
30% — Secondary color (brand or supporting)
10% — Accent color (CTA, highlights, alerts)
Never flip this ratio. More than 10% accent creates visual noise.
Colors carry cultural weight. Use this as a starting point — always validate with your target audience.
| Color | Positive associations | Negative associations | Industry fit |
|---|---|---|---|
| Blue | Trust, calm, competence | Cold, corporate, distance | Finance, healthcare, SaaS, B2B |
| Green | Growth, nature, success | Envy, naive | Fintech, sustainability, health |
| Orange | Energy, warmth, approachable | Cheap, aggressive | Consumer apps, food, e-commerce |
| Red | Urgency, passion, strength | Danger, debt, aggression | Sales CTAs, alerts, food |
| Purple | Luxury, creativity, wisdom | Pretentious, distant | Beauty, premium, creative tools |
| Yellow | Optimism, attention, warmth | Caution, cheap | Children, food, attention-seeking |
| Black | Sophistication, power, premium | Cold, inaccessible | Luxury, fashion, premium tech |
| White | Clean, minimal, honest | Empty, clinical | Healthcare, minimal design, Apple-influenced |
Dark mode is not filter: invert(1). It requires a separate color system.
HSL lightness is not perceptual. A yellow at L50 looks much brighter than a blue at L50.
Use OKLCH (perceptually uniform) for dark mode tokens:
/* Light mode */
:root {
--surface-default: oklch(98% 0.005 260); /* near-white, slightly cool */
--surface-raised: oklch(96% 0.005 260);
--surface-overlay: oklch(93% 0.005 260);
--text-primary: oklch(18% 0.010 260); /* near-black */
--text-secondary: oklch(42% 0.010 260);
--text-disabled: oklch(65% 0.005 260);
}
/* Dark mode */
[data-theme="dark"] {
--surface-default: oklch(14% 0.010 260); /* NOT black — dark indigo-tinted */
--surface-raised: oklch(18% 0.010 260); /* slightly lighter = "raised" */
--surface-overlay: oklch(22% 0.010 260);
--text-primary: oklch(92% 0.005 260); /* NOT white — slightly warm */
--text-secondary: oklch(65% 0.005 260);
--text-disabled: oklch(40% 0.005 260);
}
| Element | Light → Dark strategy |
|---|---|
| Surfaces | Light grey → Dark grey (not black) |
| Text | Dark grey → Light grey (not white) |
| Brand/accent color | Often stays same hue, reduce saturation slightly |
| Semantic colors | Success/warning/error lighten 15-20% (need contrast on dark bg) |
| Shadows | Reduce opacity or replace with elevation via color (lighter surface = higher elevation) |
| Borders | Often removed on dark (use surface color contrast instead) |
Light mode: elevation = shadow depth
Dark mode: elevation = surface lightness (higher = lighter)
--surface-level-0: oklch(14% 0.010 260) /* base */
--surface-level-1: oklch(18% 0.010 260) /* cards */
--surface-level-2: oklch(22% 0.010 260) /* floating panels */
--surface-level-3: oklch(26% 0.010 260) /* modals */
--surface-level-4: oklch(30% 0.010 260) /* tooltips */
WRONG: background: #000000 → Harsh, unnatural
RIGHT: background: ~#0f1117 → Slightly off-black
WRONG: color: #ffffff → Harsh against dark bg
RIGHT: color: #e8eaf0 → Warm off-white
WRONG: Same saturation as light mode → Neon, glaring
RIGHT: Desaturate brand color 10-15% in dark mode
Colors look different depending on what surrounds them. This affects UI decisions.
The same grey looks lighter on dark background and darker on light background:
[light grey on black] looks almost white
[light grey on white] looks almost mid-grey
The eye adapts to the ambient light color. In dark mode, slightly warm neutrals (hue ~250-280) feel neutral. Pure grey (hue 0) looks cold and clinical in dark mode.
~8% of males have color vision deficiency. Do not rely on color alone.
| Type | Description | Prevalence (males) |
|---|---|---|
| Deuteranopia | Cannot distinguish red/green | 5% |
| Protanopia | Red appears dark/black | 2.5% |
| Tritanopia | Cannot distinguish blue/yellow | 0.003% |
| Achromatopsia | No color perception | 0.003% |
Never use red+green as the only distinguisher (success vs. error)
WRONG: green check vs. red X — looks identical to deuteranopes
RIGHT: green check vs. red X + different shapes + label text
Add a secondary cue: icon, pattern, label, or position
Test with simulation tools:
Use colorblind-safe palettes for data visualization:
Okabe-Ito palette (colorblind safe):
#E69F00 Orange
#56B4E9 Sky Blue
#009E73 Bluish Green
#F0E442 Yellow
#0072B2 Blue
#D55E00 Vermillion
#CC79A7 Reddish Purple
#000000 Black
| Space | Pros | Cons | Use for |
|---|---|---|---|
| HSL | Simple, widely understood | Not perceptually uniform | Quick palette building, compatibility |
| HSLuv | Perceptually uniform lightness | Less browser support | Design tools, color scales |
| OKLCH | Best perceptual uniformity, CSS native | Learning curve | Production design tokens (modern browsers) |
| sRGB (Hex) | Universal compatibility | No meaningful mental model | Final output only |
/* Format: oklch(lightness% chroma hue) */
oklch(75% 0.15 160) /* green-ish */
oklch(55% 0.25 30) /* warm orange */
oklch(40% 0.18 270) /* violet */
/* Compared to HSL, OKLCH ensures:
oklch(75% 0.15 160) and oklch(75% 0.15 30)
have the same PERCEIVED lightness — HSL does not guarantee this */
Token definition: OKLCH (perceptual precision)
Figma work: HSL (tool compatibility)
Code output: oklch() with fallback hex
Tailwind config: oklch() via CSS custom properties
invert or simple negation