Browse Source

feat(skills): Add color-ops skill for color spaces, accessibility, and CSS color functions

Lightweight operational color skill inspired by meodai/skill.color-expert.
Covers OKLCH/OKLAB color spaces, WCAG/APCA contrast, CSS Color Level 4/5
functions, design token architecture, palette generation, CVD simulation,
and gamut management. Includes two reference files (tools-and-libraries,
css-color-reference) and subagent dispatch patterns for complex color work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0xDarkMatter 3 weeks ago
parent
commit
5818c9baea

+ 2 - 1
.claude-plugin/plugin.json

@@ -1,7 +1,7 @@
 {
   "name": "claude-mods",
   "version": "2.3.0",
-  "description": "Custom commands, skills, and agents for Claude Code - session continuity, 23 expert agents, 64 skills, 3 commands, 5 rules, 3 hooks, 4 output styles, modern CLI tools",
+  "description": "Custom commands, skills, and agents for Claude Code - session continuity, 23 expert agents, 65 skills, 3 commands, 5 rules, 3 hooks, 5 output styles, modern CLI tools",
   "author": "0xDarkMatter",
   "repository": "https://github.com/0xDarkMatter/claude-mods",
   "license": "MIT",
@@ -58,6 +58,7 @@
       "skills/claude-code-hooks",
       "skills/cli-ops",
       "skills/code-stats",
+      "skills/color-ops",
       "skills/container-orchestration",
       "skills/data-processing",
       "skills/doc-scanner",

+ 1 - 1
AGENTS.md

@@ -5,7 +5,7 @@
 This is **claude-mods** - a collection of custom extensions for Claude Code:
 - **23 expert agents** for specialized domains (React, Python, Go, Rust, AWS, git, etc.)
 - **3 commands** for session management (/sync, /save) and experimental features (/canvas)
-- **64 skills** for CLI tools, patterns, workflows, and development tasks
+- **65 skills** for CLI tools, patterns, workflows, and development tasks
 - **5 output styles** for response personality (Vesper, Spartan, Mentor, Executive, Pair)
 - **3 hooks** for pre-commit linting, post-edit formatting, and dangerous command warnings
 

File diff suppressed because it is too large
+ 4 - 3
README.md


+ 323 - 0
skills/color-ops/SKILL.md

@@ -0,0 +1,323 @@
+---
+name: color-ops
+description: "Color for developers - color spaces, accessibility contrast, palette generation, CSS color functions, design tokens, dark mode, and CVD simulation. Use for: color, colour, palette, contrast, accessibility, WCAG, APCA, OKLCH, OKLAB, HSL, color picker, color-mix, dark mode colors, design tokens, color system, color scale, color ramp, gradient, CVD, color blind, gamut, P3, sRGB, color naming, color harmony, color temperature, semantic colors."
+allowed-tools: "Read Write Bash"
+related-skills: [tailwind-ops, react-ops, frontend-design]
+---
+
+# Color Operations
+
+Practical color knowledge for developers and designers. Covers color spaces, accessibility, palette generation, CSS implementation, and design token architecture.
+
+> Inspired by [meodai/skill.color-expert](https://github.com/meodai/skill.color-expert) - a comprehensive 286K-word color science knowledge base with 113 reference files. This is a lightweight operational skill for everyday frontend and design work. For deep color science (spectral mixing, historical color theory, CAM16, pigment physics), install the full skill.
+
+## Color Space Decision Table
+
+Pick the right space for the task. This is the single most impactful color decision you'll make.
+
+| Task | Use | Why |
+|------|-----|-----|
+| Perceptual color manipulation | **OKLCH** | Best uniformity for lightness, chroma, hue |
+| CSS gradients & palettes | **OKLCH** or `color-mix(in oklab)` | No mid-gradient grey/brown deadzone |
+| Gamut-aware color picking | **OKHSL / OKHSV** | Cylindrical like HSL but perceptually grounded |
+| Normalized saturation (0-100%) | **HSLuv** | CIELUV chroma normalized per hue/lightness |
+| Print workflows | **CIELAB D50** | ICC standard illuminant |
+| Screen workflows | **OKLAB** | D65 standard, perceptually uniform |
+| Color difference (precision) | **CIEDE2000** | Gold standard perceptual distance metric |
+| Color difference (fast) | **Euclidean in OKLAB** | Good enough for most applications |
+| Quick prototyping | **HSL** | Simple, fast, every tool supports it |
+
+### Why HSL Falls Short
+
+HSL is fine for quick prototyping. It fails for anything perceptual:
+
+- **Lightness is a lie**: `hsl(60,100%,50%)` (yellow) and `hsl(240,100%,50%)` (blue) have the same L=50% but vastly different perceived brightness
+- **Hue is non-uniform**: 20 degrees near red is a dramatic shift; 20 degrees near green is barely visible
+- **Saturation doesn't correlate**: S=100% dark blue still looks muted
+
+**Rule of thumb**: Use HSL for throwaway work. Use OKLCH for anything that ships.
+
+### Key Distinctions
+
+- **Chroma** = colorfulness relative to a same-lightness neutral
+- **Saturation** = perceived colorfulness relative to the color's own brightness
+- **Lightness** = perceived reflectance relative to a similarly lit white
+- Same chroma != same saturation. These are different dimensions.
+
+## Accessibility - Contrast Numbers That Matter
+
+### The Odds Are Against You
+
+Of ~281 trillion hex color pairs:
+
+| Threshold | % passing | Odds |
+|-----------|-----------|------|
+| WCAG 3:1 (large text) | 26.49% | ~1 in 4 |
+| WCAG 4.5:1 (AA body) | 11.98% | ~1 in 8 |
+| WCAG 7:1 (AAA) | 3.64% | ~1 in 27 |
+| APCA 60 | 7.33% | ~1 in 14 |
+| APCA 75 (fluent reading) | 1.57% | ~1 in 64 |
+| APCA 90 (preferred body) | 0.08% | ~1 in 1,250 |
+
+### WCAG vs APCA
+
+| | WCAG 2.x | APCA (WCAG 3 draft) |
+|---|----------|---------------------|
+| Model | Simple luminance ratio | Perceptual contrast, polarity-aware |
+| Dark-on-light vs light-on-dark | Same ratio | Different - accounts for spatial frequency |
+| Text size/weight | Only large vs normal | Continuous scale with font lookup table |
+| Accuracy | Known problems with blue, dark mode | Much better perceptual accuracy |
+| Status | Current standard, legally referenced | Draft - not yet a requirement |
+
+**Practical guidance**: Test with WCAG 2.x for compliance. Use APCA for better perceptual results. When they disagree, APCA is usually more accurate.
+
+### Quick Contrast Checks
+
+```css
+/* Use relative color syntax to auto-generate readable text */
+--surface: oklch(0.95 0.02 250);
+--on-surface: oklch(from var(--surface) calc(l - 0.6) c h);
+
+/* Or simpler: light surface = dark text, dark surface = light text */
+--text: oklch(from var(--surface) calc(1 - l) 0 h);
+```
+
+```javascript
+// Quick WCAG 2.x relative luminance contrast
+function contrastRatio(l1, l2) {
+  const lighter = Math.max(l1, l2);
+  const darker = Math.min(l1, l2);
+  return (lighter + 0.05) / (darker + 0.05);
+}
+
+function relativeLuminance(r, g, b) {
+  const [rs, gs, bs] = [r, g, b].map(c => {
+    c /= 255;
+    return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
+  });
+  return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
+}
+```
+
+### Color Vision Deficiency (CVD)
+
+~8% of men and ~0.5% of women have some form of color vision deficiency. Design accordingly.
+
+| Type | Affects | Prevalence | What breaks |
+|------|---------|------------|-------------|
+| Protanopia | Red perception | ~1% men | Red/green distinction, red appears dark |
+| Deuteranopia | Green perception | ~1% men | Red/green distinction (most common) |
+| Tritanopia | Blue perception | ~0.01% | Blue/yellow distinction (rare) |
+
+**Rules**:
+- Never use color alone to convey information (add icons, labels, patterns)
+- Test with CVD simulation tools (see references)
+- Red/green is the most dangerous pair - always add a secondary signal
+
+## CSS Color Functions - Modern Syntax
+
+### Core Functions (Baseline 2024+)
+
+```css
+/* OKLCH - the recommended default */
+color: oklch(0.7 0.15 150);           /* lightness chroma hue */
+color: oklch(0.7 0.15 150 / 0.5);     /* with alpha */
+
+/* OKLAB - for interpolation and mixing */
+color: oklab(0.7 -0.1 0.1);           /* lightness a b */
+
+/* color-mix() - blend two colors in any space */
+color: color-mix(in oklch, #3b82f6 70%, white);
+color: color-mix(in oklab, var(--primary), black 20%);
+
+/* Relative color syntax - transform existing colors */
+color: oklch(from var(--brand) calc(l + 0.1) c h);          /* lighten */
+color: oklch(from var(--brand) calc(l - 0.1) c h);          /* darken */
+color: oklch(from var(--brand) l calc(c * 0.5) h);          /* desaturate */
+color: oklch(from var(--brand) l c calc(h + 180));           /* complement */
+
+/* P3 wide gamut */
+color: color(display-p3 1 0.5 0);     /* ~25% more colors than sRGB */
+
+/* Fallback pattern for wide gamut */
+color: #ff8800;                        /* sRGB fallback */
+color: oklch(0.79 0.17 70);           /* oklch version */
+color: color(display-p3 1 0.55 0);    /* P3 if supported */
+```
+
+### Gradients That Don't Muddy
+
+```css
+/* BAD - RGB interpolation goes through grey/brown */
+background: linear-gradient(to right, blue, yellow);
+
+/* GOOD - OKLCH interpolation stays vivid */
+background: linear-gradient(in oklch, blue, yellow);
+
+/* GOOD - OKLAB also works well */
+background: linear-gradient(in oklab, blue, yellow);
+
+/* Longer hue path for rainbow-style gradients */
+background: linear-gradient(in oklch longer hue, red, red);
+```
+
+## Design Token Architecture
+
+### Three-Layer Pattern
+
+```css
+/* Layer 1: Reference tokens (the palette) */
+:root {
+  --ref-blue-50: oklch(0.97 0.01 250);
+  --ref-blue-100: oklch(0.93 0.03 250);
+  --ref-blue-500: oklch(0.62 0.18 250);
+  --ref-blue-900: oklch(0.25 0.09 250);
+  --ref-red-500: oklch(0.63 0.22 25);
+  --ref-neutral-50: oklch(0.97 0.005 250);
+  --ref-neutral-900: oklch(0.15 0.005 250);
+}
+
+/* Layer 2: Semantic tokens (meaning) */
+:root {
+  --color-surface: var(--ref-neutral-50);
+  --color-on-surface: var(--ref-neutral-900);
+  --color-primary: var(--ref-blue-500);
+  --color-error: var(--ref-red-500);
+  --color-border: oklch(from var(--color-surface) calc(l - 0.15) 0.01 h);
+}
+
+/* Layer 3: Dark mode swaps semantics, not components */
+[data-theme="dark"] {
+  --color-surface: var(--ref-neutral-900);
+  --color-on-surface: var(--ref-neutral-50);
+  --color-primary: var(--ref-blue-100);
+  --color-border: oklch(from var(--color-surface) calc(l + 0.15) 0.01 h);
+}
+```
+
+### Generating Scales in OKLCH
+
+```javascript
+// Generate a perceptually uniform color scale
+function generateScale(hue, steps = 10) {
+  return Array.from({ length: steps }, (_, i) => {
+    const t = i / (steps - 1);
+    return {
+      step: (i + 1) * 100,  // 100..1000
+      l: 0.97 - t * 0.82,   // 0.97 (lightest) to 0.15 (darkest)
+      c: Math.sin(t * Math.PI) * 0.18,  // peak chroma in midtones
+      h: hue,
+    };
+  });
+}
+
+// Usage: generateScale(250) for a blue scale
+// Format: oklch(${l} ${c} ${h})
+```
+
+## Palette & Harmony
+
+### What Actually Works
+
+Geometric hue harmony (complementary, triadic, etc.) is a weak predictor of good palettes on its own. Better approaches:
+
+- **Character-first**: Organize by mood (pale/muted/deep/vivid/dark). Chroma + lightness drive emotional response more than hue.
+- **60-30-10 rule**: 60% dominant, 30% secondary, 10% accent. One color dominates.
+- **Lightness variation = legibility**: Same character + varied lightness is readable. Same lightness across hues is illegible.
+- **Grayscale sanity check**: If your UI doesn't work in grayscale, the color system has a structural problem.
+
+### Practical Palette Workflow
+
+1. Pick a brand hue in OKLCH
+2. Generate a 10-step scale (lightness 0.97 to 0.15, chroma peaks at midtones)
+3. Pick a neutral (same hue, near-zero chroma) for another 10-step scale
+4. Add 1-2 semantic accent hues (success green, error red, warning amber)
+5. Map to semantic tokens: surface, on-surface, primary, secondary, error
+6. Test contrast at every text/surface combination (WCAG 4.5:1 minimum)
+7. Swap semantic mappings for dark mode (don't just invert)
+
+### Quick Harmony Shortcuts
+
+```css
+/* Complementary (opposite hue) */
+--complement: oklch(from var(--primary) l c calc(h + 180));
+
+/* Analogous (adjacent hues) */
+--analogous-1: oklch(from var(--primary) l c calc(h - 30));
+--analogous-2: oklch(from var(--primary) l c calc(h + 30));
+
+/* Triadic */
+--triadic-1: oklch(from var(--primary) l c calc(h + 120));
+--triadic-2: oklch(from var(--primary) l c calc(h + 240));
+
+/* Tint (lighter, less chroma) */
+--tint: oklch(from var(--primary) calc(l + 0.2) calc(c * 0.5) h);
+
+/* Shade (darker, slightly less chroma) */
+--shade: oklch(from var(--primary) calc(l - 0.2) calc(c * 0.8) h);
+```
+
+## Gamut & Wide Color
+
+### sRGB vs P3 vs Rec2020
+
+| Gamut | Coverage | Support |
+|-------|----------|---------|
+| sRGB | Baseline | Universal - every screen |
+| Display P3 | ~25% more than sRGB | Modern Apple, high-end Android, new monitors |
+| Rec2020 | ~37% more than P3 | HDR content, limited device support |
+
+```css
+/* Progressive enhancement for wide gamut */
+.brand-accent {
+  /* sRGB fallback - every browser */
+  background: #ff6b00;
+
+  /* P3 if supported - more vivid */
+  @supports (color: color(display-p3 1 0 0)) {
+    background: color(display-p3 1 0.42 0);
+  }
+}
+
+/* Or use @media for gamut detection */
+@media (color-gamut: p3) {
+  :root {
+    --accent: oklch(0.75 0.2 50);  /* Can push chroma higher in P3 */
+  }
+}
+```
+
+### Gamut Mapping
+
+When a color is out of gamut (e.g., high-chroma OKLCH on an sRGB screen), browsers clamp it. Control this:
+
+```css
+/* Browser auto-maps (default) */
+color: oklch(0.7 0.3 150);  /* if out of sRGB, browser reduces chroma */
+
+/* Explicit gamut check in JS */
+// CSS.supports('color', 'color(display-p3 1 0 0)')
+```
+
+## Agent Dispatch
+
+For complex color work beyond this skill's scope, dispatch to specialized agents:
+
+- **Palette generation algorithms** (RampenSau, Poline, IQ cosine): Route to `frontend-design` skill or a dedicated subagent with `references/tools-and-libraries.md` preloaded
+- **Accessibility audits** (full APCA + CVD simulation): Route to a subagent that runs contrast checks across all component/token combinations
+- **Design system color architecture**: Route to `tailwind-ops` for Tailwind-specific implementation, or handle directly for CSS custom properties
+
+## Reference Files
+
+| File | Content |
+|------|---------|
+| `references/tools-and-libraries.md` | Palette generators, analysis tools, color libraries, online tools, browser extensions |
+| `references/css-color-reference.md` | Complete CSS Color Level 4/5 function reference, browser support, conversion formulas |
+
+## See Also
+
+- `tailwind-ops` - Tailwind color configuration and dark mode patterns
+- `react-ops` - Theme context and color mode implementation in React
+- [meodai/skill.color-expert](https://github.com/meodai/skill.color-expert) - Full color science skill (113 references, spectral mixing, historical theory)
+- [oklch.com](https://oklch.com/) - Interactive OKLCH picker by Evil Martians
+- [Huetone](https://huetone.ardov.me/) - Accessible color system builder

+ 0 - 0
skills/color-ops/assets/.gitkeep


+ 324 - 0
skills/color-ops/references/css-color-reference.md

@@ -0,0 +1,324 @@
+# CSS Color Reference
+
+Complete reference for CSS Color Level 4 and Level 5 functions. Baseline 2024+ unless noted.
+
+## Color Functions
+
+### oklch()
+
+The recommended default for CSS color work. Perceptually uniform, intuitive cylindrical coordinates.
+
+```css
+oklch(L C H)
+oklch(L C H / alpha)
+
+/* L: lightness 0-1 (0 = black, 1 = white) */
+/* C: chroma 0-0.4 (0 = grey, higher = more vivid) */
+/* H: hue 0-360 (degrees on color wheel) */
+
+color: oklch(0.7 0.15 250);           /* medium blue */
+color: oklch(0.7 0.15 250 / 0.5);     /* 50% transparent */
+color: oklch(0.9 0.04 90);            /* pale yellow */
+color: oklch(0.3 0.2 30);             /* deep red */
+```
+
+**Practical chroma ranges by context:**
+
+| Context | Chroma Range | Notes |
+|---------|-------------|-------|
+| Neutral/grey | 0 - 0.02 | Near-zero, slight warmth/coolness via hue |
+| Muted/pastel | 0.02 - 0.08 | Backgrounds, large surfaces |
+| Medium | 0.08 - 0.15 | Body text links, secondary UI |
+| Vivid | 0.15 - 0.25 | Primary actions, brand colors |
+| Maximum | 0.25 - 0.37 | Saturated accents (gamut-dependent) |
+
+**OKLCH hue map (approximate):**
+
+| Hue | Color |
+|-----|-------|
+| 0-30 | Pink / Red |
+| 30-70 | Orange / Amber |
+| 70-110 | Yellow / Lime |
+| 110-160 | Green |
+| 160-200 | Teal / Cyan |
+| 200-260 | Blue |
+| 260-310 | Indigo / Violet |
+| 310-360 | Magenta / Pink |
+
+### oklab()
+
+Cartesian version of OKLCH. Better for interpolation and mixing.
+
+```css
+oklab(L a b)
+oklab(L a b / alpha)
+
+/* L: lightness 0-1 */
+/* a: green(-) to red(+), roughly -0.4 to 0.4 */
+/* b: blue(-) to yellow(+), roughly -0.4 to 0.4 */
+
+color: oklab(0.7 -0.1 0.1);           /* greenish */
+color: oklab(0.5 0.15 -0.1);          /* purplish */
+```
+
+### color-mix()
+
+Blend two colors in any color space.
+
+```css
+color-mix(in <colorspace>, <color1> <percentage>?, <color2> <percentage>?)
+
+/* Default: 50/50 mix */
+color: color-mix(in oklch, blue, white);
+
+/* Weighted mix */
+color: color-mix(in oklch, #3b82f6 70%, white);        /* 70% blue, 30% white */
+color: color-mix(in oklab, var(--primary), black 20%);  /* 80% primary, 20% black */
+
+/* Hue interpolation control */
+color: color-mix(in oklch shorter hue, red, blue);      /* shorter arc */
+color: color-mix(in oklch longer hue, red, blue);       /* longer arc (rainbow) */
+```
+
+**Supported color spaces for interpolation:**
+`srgb`, `srgb-linear`, `display-p3`, `a98-rgb`, `prophoto-rgb`, `rec2020`, `lab`, `oklab`, `xyz`, `xyz-d50`, `xyz-d65`, `hsl`, `hwb`, `lch`, `oklch`
+
+**Best spaces for mixing:**
+
+| Space | Result |
+|-------|--------|
+| `oklch` | Vivid, predictable hue path |
+| `oklab` | Smooth, no hue shift surprises |
+| `srgb` | Legacy default, can muddy |
+| `hsl` | Unpredictable brightness |
+
+### Relative Color Syntax
+
+Transform an existing color by modifying its components. Game-changer for design systems.
+
+```css
+/* Syntax: <colorspace>(from <origin> <component-expressions>) */
+
+/* Lighten */
+color: oklch(from var(--brand) calc(l + 0.1) c h);
+
+/* Darken */
+color: oklch(from var(--brand) calc(l - 0.1) c h);
+
+/* Desaturate */
+color: oklch(from var(--brand) l calc(c * 0.5) h);
+
+/* Saturate */
+color: oklch(from var(--brand) l calc(c * 1.5) h);
+
+/* Shift hue (complement) */
+color: oklch(from var(--brand) l c calc(h + 180));
+
+/* Auto readable text (invert lightness) */
+color: oklch(from var(--surface) calc(1 - l) 0 h);
+
+/* Extract and modify alpha */
+color: oklch(from var(--brand) l c h / 0.5);
+
+/* Works with any origin format */
+color: oklch(from #3b82f6 calc(l + 0.2) c h);
+color: oklch(from rgb(59 130 246) l calc(c * 0.5) h);
+```
+
+**Available channel keywords by space:**
+
+| Space | Keywords |
+|-------|----------|
+| oklch | `l` `c` `h` |
+| oklab | `l` `a` `b` |
+| hsl | `h` `s` `l` |
+| srgb | `r` `g` `b` |
+
+### color()
+
+Access predefined color spaces directly. Primary use: Display P3 wide gamut.
+
+```css
+color(<colorspace> <values>)
+color(<colorspace> <values> / alpha)
+
+/* Display P3 (wider gamut than sRGB) */
+color: color(display-p3 1 0.5 0);
+color: color(display-p3 0.3 0.8 0.2 / 0.9);
+
+/* sRGB (explicit) */
+color: color(srgb 0.5 0.5 0.5);
+
+/* Other spaces */
+color: color(a98-rgb 0.44 0.5 0.37);
+color: color(prophoto-rgb 0.36 0.48 0.14);
+color: color(rec2020 0.42 0.47 0.13);
+```
+
+### light-dark()
+
+Return different values based on computed color-scheme.
+
+```css
+/* Requires color-scheme to be set */
+:root { color-scheme: light dark; }
+
+color: light-dark(#333, #eee);
+background: light-dark(white, oklch(0.2 0.01 250));
+border-color: light-dark(
+  oklch(0.8 0.02 250),
+  oklch(0.3 0.02 250)
+);
+```
+
+**Browser support:** Baseline 2024
+
+## Gradients
+
+### Interpolation Space
+
+```css
+/* Default (sRGB) - often muddy */
+background: linear-gradient(blue, yellow);
+
+/* OKLCH - vivid, predictable */
+background: linear-gradient(in oklch, blue, yellow);
+
+/* OKLAB - smooth, no hue surprises */
+background: linear-gradient(in oklab, blue, yellow);
+
+/* Hue interpolation for oklch/hsl/lch */
+background: linear-gradient(in oklch shorter hue, red, blue);
+background: linear-gradient(in oklch longer hue, red, red);  /* rainbow */
+background: linear-gradient(in oklch increasing hue, red, blue);
+background: linear-gradient(in oklch decreasing hue, red, blue);
+```
+
+### Common Gradient Patterns
+
+```css
+/* Smooth multi-stop */
+background: linear-gradient(in oklch,
+  oklch(0.6 0.2 30),   /* warm red */
+  oklch(0.7 0.18 60),  /* orange */
+  oklch(0.8 0.15 90)   /* gold */
+);
+
+/* Eased gradient (manual) - smoother than default linear */
+background: linear-gradient(in oklch,
+  oklch(0.3 0.15 250) 0%,
+  oklch(0.35 0.14 250) 10%,
+  oklch(0.45 0.12 250) 30%,
+  oklch(0.6 0.08 250) 60%,
+  oklch(0.8 0.04 250) 85%,
+  oklch(0.95 0.01 250) 100%
+);
+
+/* Radial in oklch */
+background: radial-gradient(in oklch, oklch(0.8 0.2 60), oklch(0.3 0.1 30));
+
+/* Conic in oklch (color wheel) */
+background: conic-gradient(in oklch longer hue, red, red);
+```
+
+## Conversion Formulas
+
+### Hex to sRGB
+
+```javascript
+function hexToRgb(hex) {
+  const n = parseInt(hex.replace('#', ''), 16);
+  return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
+}
+```
+
+### sRGB to Linear RGB
+
+```javascript
+function srgbToLinear(c) {
+  c /= 255;
+  return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
+}
+```
+
+### Linear RGB to OKLAB
+
+```javascript
+function linearRgbToOklab(r, g, b) {
+  const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
+  const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
+  const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
+
+  return [
+    0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s,
+    1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s,
+    0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s,
+  ];
+}
+```
+
+### OKLAB to OKLCH
+
+```javascript
+function oklabToOklch(L, a, b) {
+  const C = Math.sqrt(a * a + b * b);
+  const H = (Math.atan2(b, a) * 180 / Math.PI + 360) % 360;
+  return [L, C, H];
+}
+```
+
+### Relative Luminance (WCAG 2.x)
+
+```javascript
+function relativeLuminance(r, g, b) {
+  const [rs, gs, bs] = [r, g, b].map(srgbToLinear);
+  return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
+}
+
+function contrastRatio(l1, l2) {
+  const lighter = Math.max(l1, l2);
+  const darker = Math.min(l1, l2);
+  return (lighter + 0.05) / (darker + 0.05);
+}
+```
+
+## @media and @supports Queries
+
+```css
+/* Detect wide gamut display */
+@media (color-gamut: p3) {
+  :root { --can-p3: true; }
+}
+@media (color-gamut: rec2020) {
+  :root { --can-rec2020: true; }
+}
+
+/* Detect color scheme preference */
+@media (prefers-color-scheme: dark) { /* dark mode */ }
+@media (prefers-color-scheme: light) { /* light mode */ }
+
+/* Detect reduced motion (relevant for animated gradients) */
+@media (prefers-reduced-motion: reduce) { /* tone it down */ }
+
+/* Detect contrast preference */
+@media (prefers-contrast: more) { /* increase contrast */ }
+@media (prefers-contrast: less) { /* decrease contrast */ }
+
+/* Feature detection */
+@supports (color: oklch(0 0 0)) { /* oklch supported */ }
+@supports (color: color(display-p3 1 0 0)) { /* P3 supported */ }
+@supports (color: color-mix(in oklch, red, blue)) { /* color-mix supported */ }
+```
+
+## Browser Support Summary
+
+| Feature | Chrome | Firefox | Safari | Baseline |
+|---------|--------|---------|--------|----------|
+| oklch() / oklab() | 111+ | 113+ | 15.4+ | 2023 |
+| color-mix() | 111+ | 113+ | 16.2+ | 2023 |
+| Relative color syntax | 119+ | 128+ | 16.4+ | 2024 |
+| color() (P3, etc.) | 111+ | 113+ | 15+ | 2023 |
+| light-dark() | 123+ | 120+ | 17.5+ | 2024 |
+| Gradient interpolation | 111+ | 127+ | 16.2+ | 2024 |
+
+All features listed here are Baseline 2023-2024 - safe for production with a simple sRGB fallback for older browsers.

+ 109 - 0
skills/color-ops/references/tools-and-libraries.md

@@ -0,0 +1,109 @@
+# Color Tools & Libraries
+
+Curated toolkit for practical color work. Organized by task.
+
+## JavaScript Libraries
+
+### Manipulation & Conversion
+
+| Library | Size | Strengths | Install |
+|---------|------|-----------|---------|
+| [Culori](https://culorijs.org/) | ~15KB | 50+ color spaces, tree-shakeable, OKLCH native | `npm i culori` |
+| [Color.js](https://colorjs.io/) | ~40KB | CSS Color Level 4/5 reference impl, by Lea Verou & Chris Lilley | `npm i colorjs.io` |
+| [chroma.js](https://gka.github.io/chroma.js/) | ~14KB | Great API, bezier interpolation, battle-tested | `npm i chroma-js` |
+| [tinycolor2](https://github.com/bgrins/TinyColor) | ~10KB | Lightweight, good enough for simple tasks | `npm i tinycolor2` |
+
+### Palette Generation
+
+| Library | Approach | Best For |
+|---------|----------|----------|
+| [RampenSau](https://github.com/meodai/rampensau) | Hue cycling with easing | Generative palettes, art-directed ramps |
+| [Poline](https://meodai.github.io/poline/) | Positionable anchor points in OKLCH | Perceptually smooth multi-stop gradients |
+| [IQ Cosine Palettes](https://iquilezles.org/articles/palettes/) | 4-coefficient cosine function | Procedural palettes, shader-friendly |
+| [Leonardo](https://leonardocolor.io/) | Contrast-ratio targeting | Accessible design systems (by Adobe) |
+
+### Accessibility
+
+| Library | Purpose | Install |
+|---------|---------|---------|
+| [apca-w3](https://github.com/nickmarcucci/apca-w3) | APCA contrast calculation | `npm i apca-w3` |
+| [colorParsley](https://github.com/nickmarcucci/colorparsley) | Parse any CSS color string | `npm i colorparsley` |
+
+### Spectral & Physical Mixing
+
+| Library | What It Does |
+|---------|-------------|
+| [Spectral.js](https://github.com/rvanwijnen/spectral.js) | Kubelka-Munk spectral mixing - colors mix like paint, not light |
+| [mixbox](https://github.com/scrtwpns/mixbox) | Pigment-based mixing by Scratchapixel |
+
+## Online Tools
+
+### Color Pickers & Explorers
+
+| Tool | URL | Best For |
+|------|-----|----------|
+| OKLCH Picker | oklch.com | Interactive OKLCH exploration (Evil Martians) |
+| Huetone | huetone.ardov.me | Building accessible color systems with contrast checks |
+| Color Buddy | colorbuddy.app | Quick palette exploration |
+| Coolors | coolors.co | Fast palette generation with locking |
+| Realtime Colors | realtimecolors.com | See palette applied to a real page layout |
+
+### Contrast Checkers
+
+| Tool | URL | Algorithm |
+|------|-----|-----------|
+| WebAIM Contrast Checker | webaim.org/resources/contrastchecker | WCAG 2.x |
+| APCA Contrast Calculator | apcacontrast.com | APCA (WCAG 3 draft) |
+| Polypane Contrast | polypane.app/color-contrast | Both WCAG + APCA |
+| Colour Contrast Analyzer | colourcontrast.cc | WCAG 2.x with visual preview |
+
+### CVD Simulation
+
+| Tool | URL | Notes |
+|------|-----|-------|
+| Sim Daltonism | michelf.ca/projects/sim-daltonism | macOS app, real-time screen filter |
+| Chrome DevTools | Built-in (Rendering > Emulate vision deficiencies) | No install needed |
+| Stark (Figma plugin) | getstark.co | WCAG + CVD inside Figma |
+
+### Design System Tools
+
+| Tool | URL | Best For |
+|------|-----|----------|
+| Leonardo | leonardocolor.io | Contrast-ratio-based scale generation (Adobe) |
+| Radix Colors | radix-ui.com/colors | Pre-built accessible scales for UI |
+| Open Props Colors | open-props.style | CSS custom property color system |
+| Tailwind Color Generator | uicolors.app/create | Generate Tailwind-compatible scales |
+
+## CSS-Native Features
+
+No library needed - these ship in browsers (Baseline 2024+):
+
+```css
+/* oklch() */
+color: oklch(0.7 0.15 250);
+
+/* color-mix() */
+color: color-mix(in oklch, #3b82f6 70%, white);
+
+/* Relative color syntax */
+color: oklch(from var(--brand) calc(l + 0.1) c h);
+
+/* color() for P3 */
+color: color(display-p3 1 0.5 0);
+```
+
+## Color Naming
+
+| Resource | URL | Notes |
+|----------|-----|-------|
+| meodai/color-names | github.com/meodai/color-names | 30K+ crowd-sourced color names with hex values |
+| Name That Color | chir.ag/projects/name-that-color | Quick hex-to-name lookup |
+
+## Figma Plugins
+
+| Plugin | Purpose |
+|--------|---------|
+| Stark | Accessibility contrast + CVD simulation |
+| Realtime Colors | Apply palette to realistic layouts |
+| Color Blind | Simulate all CVD types on selected frames |
+| P3 Color Picker | Pick Display P3 colors natively |

+ 0 - 0
skills/color-ops/scripts/.gitkeep