refactor(theme): switch color generation from HSL to OKLCH

OKLCH is a perceptually uniform color space — equal lightness values
produce equal perceived brightness across all hues, unlike HSL where
blue at 50% looks much darker than yellow at 50%.

Color scales now output oklch() CSS values directly:
  --gray-500: oklch(0.530 0.035 285);
  --accent-500: oklch(0.595 0.230 286);

The browser handles gamut mapping natively. Scale definitions in
tokens.edn use [label lightness chroma] tuples where L is 0-1
perceptual lightness, C is chroma (colorfulness), H is hue degrees.

Theme adapter updated: sliders now control OKLCH hue/chroma,
swatches render with oklch() CSS, Copy EDN outputs OKLCH config.

gen.clj includes oklch->srgb and oklch->hex for validation/tools.
This commit is contained in:
Florian Schroedl
2026-03-11 12:04:33 +01:00
parent 41811dba88
commit 59d46700bc
6 changed files with 222 additions and 175 deletions

View File

@@ -16,20 +16,27 @@
(is (= "--bg-0" (gen/token->css-var :bg-0)))))
(deftest generate-color-scale-test
(testing "generates CSS variables for a color scale"
(testing "generates OKLCH CSS variables for a color scale"
(let [scale (gen/generate-color-scale
:gray {:hue 240 :saturation 18
:steps [[50 97] [950 5]]})]
:gray {:hue 285 :chroma 0.025
:steps [[50 0.975] [950 0.145]]})]
(is (str/includes? scale "--gray-50:"))
(is (str/includes? scale "--gray-950:"))
(is (str/includes? scale "#"))))
(is (str/includes? scale "oklch("))))
(testing "per-step saturation override"
(testing "per-step chroma override"
(let [scale (gen/generate-color-scale
:accent {:hue 252 :saturation 96
:steps [[500 67 96] [400 75 93]]})]
:accent {:hue 286 :chroma 0.23
:steps [[500 0.595 0.230] [400 0.690 0.170]]})]
(is (str/includes? scale "--accent-500:"))
(is (str/includes? scale "--accent-400:")))))
(is (str/includes? scale "--accent-400:"))
(is (str/includes? scale "oklch(0.595 0.2300 286.0)"))))
(testing "oklch->hex roundtrip produces valid hex"
(let [hex (gen/oklch->hex [0.595 0.23 286])]
(is (string? hex))
(is (str/starts-with? hex "#") "should start with #")
(is (= 7 (count hex))))))
(deftest generate-css-test
(let [token-data (gen/read-tokens "src/theme/tokens.edn")