Skip to main content

Introduction to OKLCH

OKLCH is a cylindrical (polar coordinate) representation of the Oklab color space. The name stands for:
┌─────────────────────────────────────────────────────────────────────────────┐
│                           OKLCH COMPONENTS                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   O  =  Oklab (the underlying perceptual color space)                       │
│   L  =  Lightness (0-100%, perceptually uniform)                            │
│   C  =  Chroma (0-0.4, saturation/colorfulness)                             │
│   H  =  Hue (0-360 degrees, color wheel angle)                              │
│                                                                             │
│   OKLCH vs Oklab:                                                           │
│   ┌───────────────────────────────────────────────────────────────────────┐ │
│   │  Oklab (Cartesian)              OKLCH (Polar)                         │ │
│   │  ─────────────────              ─────────────                         │ │
│   │  L (Lightness)         <-->     L (Lightness)                         │ │
│   │  a (Green-Red axis)    <-->     C (Chroma = sqrt(a^2 + b^2))          │ │
│   │  b (Blue-Yellow axis)  <-->     H (Hue = atan2(b, a))                 │ │
│   └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

The Gravity Field Metaphor

In the Gestalt Color System, we use a gravitational lensing metaphor to understand color relationships:
┌─────────────────────────────────────────────────────────────────────────────┐
│                    OKLCH AS THE CORE GRAVITY FIELD                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   PHYSICAL ANALOGY:                                                         │
│   ─────────────────                                                         │
│                                                                             │
│   In general relativity, a massive object (like a star) creates a           │
│   gravitational field that bends spacetime around it. Light rays            │
│   passing near this object curve toward it.                                 │
│                                                                             │
│   Similarly, in OKLCH:                                                      │
│   - The CORE HUE acts as the "massive object" (gravity center)              │
│   - Other colors are "light rays" that curve toward the Core                │
│   - The polar coordinate system (L, C, H) naturally represents              │
│     distance and angle FROM the center                                      │
│                                                                             │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │                                                                     │   │
│   │                         Core Hue                                    │   │
│   │                            *                                        │   │
│   │                          /   \                                      │   │
│   │                        /       \    Frame Drag                      │   │
│   │                      /           \   (blend_hue)                    │   │
│   │                    /               \                                │   │
│   │                  /                   \                              │   │
│   │     o─────────/─────────────────────\──────────o                    │   │
│   │   color A   (dragged toward Core)             color B               │   │
│   │                                                                     │   │
│   │   Hue rotation in OKLCH = orbital path around Core                  │   │
│   │   Chroma (C) = distance from the center (orbital radius)            │   │
│   │   Lightness (L) = perpendicular dimension (elevation)               │   │
│   │                                                                     │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Why OKLCH for Core Colors?

OKLCH provides three core benefits that make it ideal for defining color identity:
  1. Perceptual Uniformity: L=50% appears equally bright regardless of hue
  2. Golden Angle Rotation: Produces visually equal color steps
  3. Hue-Independent Chroma: Yellow does not require special saturation handling (unlike HSL)
These properties make OKLCH ideal for defining “gravitational anchors” - colors with stable, well-defined identities that other colors can be “dragged” toward.

OKLCH Value Ranges

┌─────────────────────────────────────────────────────────────────────────────┐
│                         OKLCH VALUE RANGES                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   Component      Range           Unit        Description                    │
│   ─────────────────────────────────────────────────────────────────────────  │
│   Lightness (L)  0 - 100         %           0% = black, 100% = white       │
│   Chroma (C)     0 - 0.4         unitless    0 = gray, 0.4 = maximum color  │
│   Hue (H)        0 - 360         degrees     Color wheel position           │
│                                                                             │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │                        HUE COLOR WHEEL                              │   │
│   │                                                                     │   │
│   │                             0/360                                   │   │
│   │                               Red                                   │   │
│   │                                │                                    │   │
│   │                       330      │     30                             │   │
│   │                    Pink   \    │    /   Orange                      │   │
│   │                           \    │   /                                │   │
│   │               300  ────────────┼────────────  60                    │   │
│   │              Magenta    Core   │            Yellow                  │   │
│   │                         Hue    │                                    │   │
│   │                    Violet /    │    \ Yellow-Green                  │   │
│   │                       270      │     90                             │   │
│   │                               Blue                                  │   │
│   │                              180                                    │   │
│   │                               Cyan                                  │   │
│   │                                                                     │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│   PRACTICAL CHROMA VALUES:                                                  │
│   ─────────────────────────                                                 │
│   DEFAULT_CHROMA   = 0.12  (UI elements - subtle, professional)             │
│   MAX_SAFE_CHROMA  = 0.15  (maximum before sRGB clipping)                   │
│   Theoretical max  = 0.4   (may clip in sRGB gamut)                         │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Golden Angle Constants

The Gestalt Color System uses two golden angle values for different purposes:
┌───────────────────────────────────────────────────────────────────────┐
│  GOLDEN ANGLE CONSTANTS                                               │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  GOLDEN_ANGLE = 137.5077640500378                                     │
│       │                                                               │
│       └──► 360 / phi²  where phi = (1 + √5) / 2                       │
│            Maximum hue separation for file types, syntax colors       │
│                                                                       │
│  AGENT_GOLDEN_ANGLE = 27.5                                            │
│       │                                                               │
│       └──► 137.5 / 5  (fifth of golden angle)                         │
│            Subtle variation for terminal sessions, agent tabs         │
│                                                                       │
│  DEFAULT_CHROMA = 0.12  ──► Standard saturation for UI elements       │
│  MAX_SAFE_CHROMA = 0.15 ──► Maximum before sRGB gamut clipping        │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘
/** Golden angle for maximum color distribution */
export const GOLDEN_ANGLE = 137.5077640500378;

/** Agent color golden angle (smaller for subtle variation) */
export const AGENT_GOLDEN_ANGLE = 27.5;

/** Default chroma for UI elements */
export const DEFAULT_CHROMA = 0.12;

/** Maximum chroma before clipping in sRGB */
export const MAX_SAFE_CHROMA = 0.15;
┌─────────────────────────────────────────────────────────────────────────────┐
│                         GOLDEN ANGLE DISTRIBUTION                           │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   MATHEMATICAL FOUNDATION:                                                  │
│   ────────────────────────                                                  │
│   Golden Ratio (phi) = (1 + sqrt(5)) / 2 = 1.6180339887                     │
│   Golden Angle = 360 / phi^2 = 137.5077640500378                            │
│                                                                             │
│   WHY 137.5?                                                                │
│   ──────────                                                                │
│   This angle provides MAXIMUM DISTRIBUTION on a circle.                     │
│   Each new point is maximally separated from all previous points.           │
│                                                                             │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │  Color Distribution Pattern (Golden Angle 137.5):                   │   │
│   │                                                                     │   │
│   │  Index 1:   0 + (1 x 137.5) = 137.5                                 │   │
│   │  Index 2:   0 + (2 x 137.5) = 275.0                                 │   │
│   │  Index 3:   0 + (3 x 137.5) = 412.5 -> 52.5                         │   │
│   │  Index 4:   0 + (4 x 137.5) = 550.0 -> 190.0                        │   │
│   │  Index 5:   0 + (5 x 137.5) = 687.5 -> 327.5                        │   │
│   │  Index 6:   0 + (6 x 137.5) = 825.0 -> 105.0                        │   │
│   │                                                                     │   │
│   │  Result: Colors are evenly distributed, never clustering!           │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│   TWO GOLDEN ANGLES IN MONOLEX:                                             │
│   ─────────────────────────────                                             │
│   GOLDEN_ANGLE = 137.5       For maximum distinction (file types, etc.)     │
│   AGENT_GOLDEN_ANGLE = 27.5  For subtle variation (agent colors)            │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Color Conversion Pipeline

The system provides complete conversion between color spaces:
┌─────────────────────────────────────────────────────────────────────────────┐
│                    COLOR CONVERSION PIPELINE                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   ┌───────┐      ┌───────────┐      ┌───────┐      ┌─────────┐              │
│   │  RGB  │ ---> │ Linear RGB│ ---> │ Oklab │ ---> │  OKLCH  │              │
│   │(0-255)│      │ (gamma)   │      │ (L,a,b)│     │ (L,C,H) │              │
│   └───────┘      └───────────┘      └───────┘      └─────────┘              │
│                                       FLOW Space    CORE Space              │
│                                      (Cartesian)     (Polar)                │
│                                                                             │
│   HEX -> RGB:                                                               │
│   ┌───────────────────────────────────────────────────────────────────────┐ │
│   │  hexToRgb("#FF5733") -> { r: 255, g: 87, b: 51 }                      │ │
│   └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│   RGB -> Linear RGB (sRGB gamma removal):                                   │
│   ┌───────────────────────────────────────────────────────────────────────┐ │
│   │  v = c / 255                                                          │ │
│   │  if (v <= 0.04045):                                                   │ │
│   │      linear = v / 12.92                                               │ │
│   │  else:                                                                │ │
│   │      linear = ((v + 0.055) / 1.055) ^ 2.4                             │ │
│   └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│   Oklab -> OKLCH (Cartesian to Polar):                                      │
│   ┌───────────────────────────────────────────────────────────────────────┐ │
│   │  C = sqrt(a^2 + b^2)          <- Distance from center (gravity well)  │ │
│   │  H = atan2(b, a) x (180 / pi) <- Angle (orbital position)             │ │
│   │  if (H < 0) H += 360                                                  │ │
│   │  L = L x 100  (convert to percentage)                                 │ │
│   └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

CSS Generation Functions

OKLCH CSS String Generation

┌───────────────────────────────────────────────────────────────────────┐
│  toOklchCSS() - OKLCH to CSS String Conversion                        │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  INPUT:  OKLCH { l: 55, c: 0.15, h: 230 }                             │
│                    │       │       │                                  │
│                    V       V       V                                  │
│  FORMAT: oklch( L.00%   C.000   H.00 )                                │
│                    │       │       │                                  │
│                    V       V       V                                  │
│  OUTPUT: "oklch(55.00% 0.150 230.00)"                                 │
│                                                                       │
│  NOTE: toFixed(2) for L and H, toFixed(3) for C (higher precision)   │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘
export function toOklchCSS(oklch: OKLCH): string {
  return `oklch(${oklch.l.toFixed(2)}% ${oklch.c.toFixed(3)} ${oklch.h.toFixed(2)})`;
}

Color Mix CSS Generation

┌───────────────────────────────────────────────────────────────────────┐
│  colorMix() - CSS color-mix() String Generator                        │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  INPUTS:                                                              │
│  ───────                                                              │
│  color1:  First color (CSS value or variable)                         │
│  color2:  Second color (CSS value or variable)                        │
│  space:   Color space (oklch, oklab, srgb) - default: oklch           │
│  percent: Weight of color1 (0-100) - default: 50                      │
│                                                                       │
│  FORMULA:                                                             │
│  ────────                                                             │
│  "color-mix(in {space}, {color1} {percent}%, {color2})"               │
│                                                                       │
│  EXAMPLE:                                                             │
│  ────────                                                             │
│  colorMix("#FF0000", "#0000FF", "oklab", 70)                          │
│       │                                                               │
│       └──► "color-mix(in oklab, #FF0000 70%, #0000FF)"                │
│            Result: 70% red + 30% blue in OKLAB space                  │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘
export function colorMix(
  color1: string,
  color2: string,
  space: ColorMixSpace = "oklch",
  percent: number = 50
): string {
  return `color-mix(in ${space}, ${color1} ${percent}%, ${color2})`;
}
┌─────────────────────────────────────────────────────────────────────────────┐
│                      CSS OUTPUT FORMAT COMPARISON                           │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   FUNCTION                  OUTPUT EXAMPLE                                  │
│   ───────────────────────────────────────────────────────────────────────   │
│                                                                             │
│   toOklchCSS()              oklch(55.00% 0.150 230.00)                       │
│   (CORE - identity)         oklch(65.00% 0.120 85.00)                        │
│                                                                             │
│   colorMix()                color-mix(in oklch, #FF0000 50%, #0000FF)        │
│   (FLOW - transition)       color-mix(in oklab, var(--primary) 70%, white)  │
│                                                                             │
│   colorTransparent()        color-mix(in oklab, #FF0000, transparent 50%)   │
│   (FLOW - transparency)                                                     │
│                                                                             │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │  KEY INSIGHT: Color Space Choice                                    │   │
│   │                                                                     │   │
│   │  toOklchCSS()        -> OKLCH (polar) = CORE Space                  │   │
│   │                        Identity colors, fixed "gravity centers"     │   │
│   │                                                                     │   │
│   │  colorTransparent()  -> OKLAB (cartesian) = FLOW Space              │   │
│   │  colorDarker()         Transitions between gravity fields           │   │
│   │  colorLighter()        Linear paths avoiding gravitational distort  │   │
│   │                                                                     │   │
│   │  OKLCH = Core Colors (Identity, Hue-based, Anchor Points)           │   │
│   │  OKLAB = Flow Colors (Derivations, Linear mixing, Free space)       │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Accessibility Functions

The system includes built-in accessibility checking:
┌───────────────────────────────────────────────────────────────────────┐
│  ACCESSIBILITY FUNCTIONS                                              │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  hasEnoughContrast(textOklch, bgOklch)                                │
│       │                                                               │
│       └──► │text.L - bg.L│ > 40  →  true/false                        │
│            WCAG-inspired lightness difference check                   │
│                                                                       │
│  getContrastText(bgOklch)                                             │
│       │                                                               │
│       ├──► bg.L > 60  →  "black"  (dark text on light bg)             │
│       └──► bg.L ≤ 60  →  "white"  (light text on dark bg)             │
│                                                                       │
│  getAccessibleTextColor(bgOklch)                                      │
│       │                                                               │
│       ├──► bg.L > 60  →  { l: 20, c: 0.02, h: bg.h }  (dark text)     │
│       │                   Preserves background hue, minimal chroma    │
│       │                                                               │
│       └──► bg.L ≤ 60  →  { l: 95, c: 0.01, h: bg.h }  (light text)    │
│                           Preserves background hue, near-white        │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘
export function hasEnoughContrast(textOklch: OKLCH, bgOklch: OKLCH): boolean {
  return Math.abs(textOklch.l - bgOklch.l) > 40;
}

export function getContrastText(bgOklch: OKLCH): "white" | "black" {
  return bgOklch.l > 60 ? "black" : "white";
}

export function getAccessibleTextColor(bgOklch: OKLCH): OKLCH {
  if (bgOklch.l > 60) {
    return { l: 20, c: 0.02, h: bgOklch.h };
  } else {
    return { l: 95, c: 0.01, h: bgOklch.h };
  }
}

THE CENTER

How OKLCH Helps Humans Parse Information Flow

Connection to Core-Flow:
├── The color IDENTITY tells humans what type of information this is
├── Before reading text, color communicates: "This is a primary action"
└── Polar coordinates (L, C, H) map naturally to human perception
    - Lightness: How prominent is this information?
    - Chroma: How important/attention-grabbing is it?
    - Hue: What category does it belong to?
In Human-AI collaboration, users process streams of text from terminals, logs, and AI outputs. OKLCH provides the mathematical foundation that ensures:
  1. Equal perceived brightness - A yellow warning is not louder than a red error
  2. Consistent categorization - Hue reliably maps to meaning
  3. Predictable transitions - Flow colors derived from Core colors maintain identity

Complete API Reference

┌─────────────────────────────────────────────────────────────────────────────┐
│                    OKLCH COLOR UTILS - COMPLETE API                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   CONSTANTS:                                                                │
│   ──────────                                                                │
│   GOLDEN_ANGLE           137.5077640500378  (maximum distribution)          │
│   AGENT_GOLDEN_ANGLE     27.5               (subtle agent variation)        │
│   DEFAULT_CHROMA         0.12               (UI elements)                   │
│   MAX_SAFE_CHROMA        0.15               (sRGB safe maximum)             │
│                                                                             │
│   CONVERSIONS:                                                              │
│   ────────────                                                              │
│   hexToRgb(hex)                  HEX -> RGB                                 │
│   rgbToOklch(rgb)                RGB -> OKLCH                               │
│   oklchToRgb(oklch)              OKLCH -> RGB                               │
│   hexToOklch(hex)                HEX -> OKLCH                               │
│   oklchToHex(oklch)              OKLCH -> HEX                               │
│   hslToOklch(hsl)                HSL -> OKLCH                               │
│                                                                             │
│   CSS GENERATION:                                                           │
│   ───────────────                                                           │
│   toOklchCSS(oklch)              -> "oklch(L% C H)"                          │
│   colorMix(c1, c2, space, %)     -> "color-mix(in space, c1 %, c2)"         │
│   colorTransparent(c, opacity)   -> "color-mix(in oklab, c, transparent %)" │
│   colorDarker(c, amount)         -> "color-mix(in oklab, c %, black)"       │
│   colorLighter(c, amount)        -> "color-mix(in oklab, c %, white)"       │
│                                                                             │
│   COLOR GENERATION:                                                         │
│   ─────────────────                                                         │
│   getAgentColorOklch(idx, base, dark)     -> OKLCH for agent N              │
│   getExtensionColorOklch(hue, dark)       -> OKLCH for file type            │
│   generatePalette(base, count, step)      -> OKLCH[]                        │
│   adjustOklch(color, {l?, c?, h?})        -> adjusted OKLCH                 │
│                                                                             │
│   ACCESSIBILITY:                                                            │
│   ──────────────                                                            │
│   hasEnoughContrast(text, bg)             -> boolean (delta L > 40)         │
│   getContrastText(bg)                     -> "white" │ "black"              │
│   getAccessibleTextColor(bg)              -> OKLCH                          │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

CSS Variables Architecture

Learn how Core Colors are defined as CSS variables using the SMPC hierarchy