module
UI::DesignTokens::Conversion
Overview
OKLCH ↔ sRGB conversion based on Björn Ottosson's OKLab/OKLCH algorithm.
Reference: https://bottosson.github.io/posts/oklab/
All routines are deterministic and round-trip stable within the tolerances documented on each method. Out-of-gamut OKLCH triples are mapped into the sRGB gamut by reducing chroma in fixed steps (0.001 chroma units) until the result lies within [0, 1] on every linear-RGB channel. This is perceptually preferable to naive RGB clamping (which warps hue).
Internal convention: L is on [0, 1] (NOT [0, 100]); chroma is unbounded in principle but in practice ≤ ~0.4 for displayable sRGB colors; hue is in degrees on [0, 360).
Extended Modules
Defined in:
ui/design_tokens/conversion.crInstance Method Summary
-
#cbrt(x : Float64) : Float64
Cube root that preserves sign (handles negative LMS values cleanly).
-
#delta_e_2000(l1 : Float64, c1 : Float64, h1 : Float64, l2 : Float64, c2 : Float64, h2 : Float64) : Float64
ΔE2000 color difference between two OKLCH (or sRGB-derived OKLCH) triples.
-
#linear_to_srgb(x : Float64) : Float64
Gamma-encode a linear sRGB channel into companded sRGB.
-
#oklch_to_srgb(l : Float64, c : Float64, h : Float64) : Tuple(Float64, Float64, Float64)
Convert OKLCH to sRGB (each channel on [0, 1]).
-
#oklch_to_srgb_unchecked(l : Float64, c : Float64, h : Float64) : Tuple(Float64, Float64, Float64)
Raw OKLCH → sRGB conversion that may return out-of-gamut channel values.
-
#srgb_to_linear(x : Float64) : Float64
Decode a companded sRGB channel into linear sRGB.
-
#srgb_to_oklch(r : Float64, g : Float64, b : Float64) : Tuple(Float64, Float64, Float64)
Convert sRGB (each channel on [0, 1]) to OKLCH.
Instance Method Detail
Cube root that preserves sign (handles negative LMS values cleanly).
ΔE2000 color difference between two OKLCH (or sRGB-derived OKLCH) triples. Used by validation specs; not on the hot path.
The reference algorithm is in CIE Lab, so we convert OKLCH → linear sRGB → CIE XYZ → CIE Lab and compare in that space. This matches the perceptual-difference bar the Architect tightened to ΔE2000 ≤ 1.0 at the five canonical palette comparison points.
Convert OKLCH to sRGB (each channel on [0, 1]).
If the OKLCH triple is out of gamut, chroma is iteratively reduced (by 0.001 per step) until the resulting sRGB lies within [0, 1] on all channels. The hue is preserved exactly; only chroma is squeezed.
Raw OKLCH → sRGB conversion that may return out-of-gamut channel values.
Used internally by #oklch_to_srgb (which adds gamut mapping).
Convert sRGB (each channel on [0, 1]) to OKLCH.