Color Model: OKLCH
Espalier uses OKLCH as its internal color model. OKLCH describes colors using three axes: L (perceived lightness, 0–1), C (chroma / color intensity, 0–0.37+), and H (hue angle, 0–360).
This model drives the entire palette generation pipeline: seed color input, color-theory variant generation, semantic token derivation, and APCA contrast enforcement all operate in OKLCH before values are emitted as CSS custom properties.
What this means when writing theme colors
You can provide the seedColor theme field in any valid CSS color format.
OKLCH is the most direct:
// Any of these are valid seed colors
{ seedColor: 'oklch(0.65 0.18 240)' } // OKLCH — direct
{ seedColor: '#3b82f6' } // hex — converted internally
{ seedColor: 'hsl(217 91% 60%)' } // HSL — converted internally
Using OKLCH directly gives you the most predictable results because the numbers you write correspond to perceived brightness (L) and color intensity (C) rather than hardware channel values.
OKLCH in application CSS
Because --esp-color-* tokens are emitted as OKLCH values, you can use
Relative Color Syntax
to derive related values in your own CSS:
/* Lighten a token by shifting its L channel */
background: oklch(from var(--esp-color-primary) calc(l + 0.05) c h);
/* Desaturate by reducing chroma */
color: oklch(from var(--esp-color-text) l calc(c * 0.5) h);
Lightness ramp tokens
Espalier also exposes the raw lightness values it uses internally as
--esp-l-* tokens (e.g. --esp-l-surface, --esp-l-text). These are useful
when you need to apply the same perceptual lightness levels to custom colors
that are outside the standard palette.