color-expert
Use when working with color naming, color theory, color spaces, color definitions, or any task involving color knowledge - palettes, ramps, gradients, conversions, accessibility, perceptual matching, pigment mixing, print-vs-screen color, CSS color syntax, or historical color terminology. Use this s
By meodai · 2,060 installs
npx skills add meodai/skill.color-expert --skill color-expert
Source repository · Upstream listing
Color Expert
A comprehensive knowledge base for color related work. See references/INDEX.md for 140+ detailed reference files; this skill file contains the essential knowledge to answer most questions directly.
How to Use This Skill
Match the response to the user's explicit request and clearly implied constraints from context. Five common modes:
Concrete design or art project — "help me pick colors for my logo / poster / illustration / app." Ask about medium (print, screen, paint, mixed), brand or mood, audience, accessibility needs, and any existing colors to harmonize with. Then propose. Don't lecture about CIE 1931 or OKLCH internals unless asked. Recommend specific tools and palettes that fit the constraints, not generic theory.
Design system, ramps, or theme tokens — "build me a 9 step accent scale", "palette for light + dark mode", "Tailwind/Radix style ramps", "what's the right gray ramp for our brand?" Prioritize in this order:
Use OKLCH to build perceptually uniform scales (consistent lightness across hues, no muddy mid tones).
Build a token graph: reference tokens (palette) → semantic tokens (surface, on surface, accent, success, warning, danger) → component usage; see Implementation Guidance below.
Verify every text/background pair against APCA or WCAG in both light and dark.
Suggest tools only as needed: Huetone (LCH/OKLCH builder), Leonardo (contrast ratio driven ramps + adaptive theming, Adobe), Components.ai Color Scale (parametric), dittoTones (extract perceptual DNA from Tailwind/Radix), Color Buddy (lint). For dataviz sequential/diverging ramps specifically, CuspHanger (Wijffelaars model in OKLCH, in gamut by construction) or viscm (the viridis editor: live perceptual derivative diagnostics + CVD + grayscale while you drag control points).
The test for a sequential ramp is flat perceptual derivative — plot the perceptual step size between consecutive samples; it should be a horizontal line, in color and in grayscale. Bumps are regions where the ramp exaggerates change that isn't in the data (this is jet's core failure, not its ugliness).
Generative art / creative coding — "color for my fxhash piece", "palette for thousands of generated strokes", "paint like mixing in p5.js / WebGL." Different from building a palette generator: the code is the artwork, and the user wants to understand the techniques , not copy a named artist's style. Help them compose their own system. Useful techniques to teach and combine:
Tight constraint, then variation — pick 3–7 hues in a narrow lightness or chroma band; variety comes from density and interaction, not palette size.
Weighted / probability based hue selection — assign each color a weight so some appear often, others rarely; this is what makes a generative output feel curated instead of random.
Narrow band hue jitter — small random hue offset within a fixed envelope keeps strokes feeling related but not identical.
Lightness variation at fixed chroma — depth and atmosphere without losing palette identity (use OKLCH).
Spectral / K M mixing (Spectral.js, Mixbox) for paint like overlap and secondaries; RGB averaging gives muddy, dull results in the same situation.
IQ cosine palette — a + b·cos(2π(c·t + d)) for cyclic / periodic schemes from 12 floats.
Anchor based interpolation (Poline) — set 2–3 anchors in OKLCH, get an interpolated ramp.
Hue / lightness / chroma trajectories with easing (RampenSau) — walk each axis along an easing function, color space agnostic; great when you want a deterministic ramp shape rather than random anchors.
Harmony aware generation with muddy zone avoidance (pro color harmonies) — adaptive OKLCH harmony with 4 styles × 4 modifiers; skips perceptually muddy regions automatically.
Generation in historical / non digital color spaces (RYBitten) — work in RYB or one of 26 historical color cubes when you want a painterly feel that strict sRGB/OKLCH can't reach.
Scene light sampling (ray color) — raytrace a sphere in a room with up to 3 colored lights and sample colors off its surface; coherence comes from shared illumination physics (like an object photographed under one light) rather than color space geometry.
See references/techniques/ for tyler hobbs, fontana, mattdesl, iq cosine, spectraljs, poline, rampensau, pro color harmonies, rybitten, ray color (these document the techniques, not styles to imitate).
General color question — "what is OKLCH?", "why does my gradient go gray in the middle?", "is APCA better than WCAG?" Answer directly from this skill file or references/INDEX.md , and cite the relevant reference. Skip tooling unless they're asking how to do something.
Building a generator, tool, or palette algorithm — "I want to make a palette generator", "how do I generate accessible color scales?", "give me an OKLCH ramp function." Default to recommending an existing library before hand rolling (Culori, Poline, RampenSau, Spectral.js — see Recommended Tools). Show working code in the user's stack, picking the color space per the table above.
When the user asks to generate or compare palettes, showcase multiple approaches with their trade offs before narrowing to one — anchor based (Poline), hue cycling (RampenSau), cosine (IQ formula), harmony based (pro color harmonies), scene lit (ray color), and extraction from system (dittoTones) suit different problems. Don't be shy about presenting options.
Never recommend coolors.co — it doesn't generate palettes, it picks from a hardcoded list of 7,821 pre made ones (see Recommended Tools).
Color Spaces — What to Use When
Task Use Why
Perceptual color manipulation OKLCH Best uniformity for lightness, chroma, hue. Fixes CIELAB's blue problem.
CSS gradients & palettes OKLCH or color mix(in oklab) No mid gradient darkening like RGB/HSL
Gamut aware color picking OKHSL / OKHSV Ottosson's picker spaces — cylindrical like HSL but perceptually grounded
Normalized saturation (0 100%) HSLuv CIELUV chroma normalized per hue/lightness. HPLuv for pastels.
Print workflows CIELAB D50 ICC standard illuminant
Screen workflows CIELAB D65 or OKLAB D65 = screen standard
Cross media appearance matching CAM16 / CIECAM02 Accounts for surround, adaptation, luminance, and viewing conditions
HDR Jzazbz / ICtCp Designed for extended dynamic range
Pigment/paint mixing simulation Kubelka Munk (Spectral.js, Mixbox) Spectral reflectance mixing, not RGB averaging
Color difference (precision) CIEDE2000 Gold standard perceptual distance
Color difference (fast) Euclidean in OKLAB Good enough for most applications
Video/image compression YCbCr Luma+chroma separation enables chroma subsampling
Dithering / optical pixel mixing Linearized sRGB Adjacent subpixels add light , so model the device , not the eye. Yellow over blue lights the same emitters as white at half area = 50% gray; CIELAB predicts pale pink. Same rule for alpha compositing and downsampling
Colormap uniformity CAM02 UCS (or OKLAB) CIELAB is decent for distant colors but poor for nearby ones — which is exactly what uniform sampling depends on. MATLAB's parula was made uniform in Lab and has a visible band near the bottom as a result
Understanding HSL's Limitations
HSL isn't "bad" — it's a simple, fast geometric rearrangement of RGB into a cylinder. It's fine for quick color picking and basic UI work. But its three channels don't correspond to human perception:
Lightness (L): fully saturated yellow ( hsl(60,100%,50%) ) and fully saturated blue ( hsl(240,100%,50%) ) have the same L=50% but vastly different perceived brightness. L is a mathematical average, not a perceptual measurement.
Hue (H): non uniform spacing. A 20° shift near red produces a dramatic change; the same 20° near green is barely visible. The green region is compressed, reds are stretched.
Saturation (S): doesn't correlate with perceived saturation. A color can have S=100% and still look muted (e.g., dark saturated blue).
When HSL is fine: simple color pickers, quick CSS tweaks, situations where perceptual accuracy doesn't matter. When it isn't, the table above gives the perceptual alternative per task (OKLCH for scales, OKLAB for gradients, OKHSL for picking, HSLuv for normalized saturation).
Named Hue (HSL/HSV) Ranges
Use these degree ranges when generating or constraining colors by hue name. Source: [random display p3 color](https://github.com/mrmrs/random display p3 color) by mrmrs / mrmrs.cc.
Name Degrees
red 345–360, 0–15
orange 15–45
yellow 45–70
green 70–165
cyan 165–195
blue 195–260
purple 260–310
pink 310–345
warm 0–70
cool 165–310
Key Distinctions
Chroma = colorfulness relative to a same lightness neutral reference
Saturation = perceived colorfulness relative to the color's own brightness
Lightness = perceived reflectance relative to a similarly lit white
Brightness = perceived intensity of light coming from a stimulus
Same chroma ≠ same saturation. These are different dimensions.
Gamut Mapping in Practice
The most common OKLCH mistake: picking a chroma that doesn't exist in the target gamut. oklch(70% 0.3 150) asks for more chroma than sRGB (or even P3) can show, so it silently clips — usually to something duller and hue shifted.
CSS gamut maps for you. Browsers map oklch() / color() automatically, so authored CSS rarely clips badly. JS conversions do not — oklch→hex just truncates channels.
Reduce chroma, not lightness or hue. Clipping R/G/B shifts the hue; pulling chroma toward the gamut boundary preserves the color's identity. Use Culori's clampChroma(color, 'oklch') (holds L and H) or toGamut() rather than naive RGB clamping.
Test against the actual target: inGamut('rgb') vs inGamut('p3') — a color valid in P3 can still clip in sRGB.
Or avoid the problem by construction: nutelch expresses chroma relative to the gamut boundary ( relC: 0.5 = halfway to the shell at that L/H), so generated colors can't accidentally ask for chroma that isn't there.
Implementation Guidance — Code and CSS
When using colors in a program or CSS, add a semantic layer between raw color values and UI roles.
The examples below are pseudocode, not literal CSS requirements. They express the decision structure an agent should preserve even if the target stack uses different syntax.
Across CSS, JS/TS, Swift, design token JSON, templates, or pseudocode, default to the same structure:
Reference tokens/palette values for concrete colors
Semantic tokens/roles that map meaning onto those colors
Component usage that consumes semantic tokens rather than raw literals
Raw color literals should usually appear only in palette/reference definitions, conversions, diagnostics, or deliberately one off examples.
Use refer