Color & Palette Development

Perceptual Color

Eido works in OKLAB/OKLCH — perceptually uniform color spaces where mathematical distance matches visual difference:

(require '[eido.color :as color])

;; Convert and manipulate
(color/rgb->oklch [255 100 50])
(color/oklch 0.7 0.15 30)

;; Perceptual interpolation
(color/lerp-oklab color-a color-b 0.5)

;; Contrast checking (WCAG 2.0)
(color/contrast :white :black)   ;=> 21.0
(color/contrast :white :yellow)  ;=> 1.07

OKLCH uses lightness, chroma, and hue — intuitive axes for artistic color decisions.

Palette Generation

(require '[eido.color.palette :as palette])

;; Built-in palettes
(:sunset palette/palettes)
(:ocean palette/palettes)

;; Generate from color theory
(palette/complementary base-color)
(palette/analogous base-color 5)
(palette/triadic base-color)

;; Assign semantic roles
(palette/with-roles pal
  {:background 0 :primary 1 :accent 2 :text 3})
Rendered output

Palette Manipulation

Transform entire palettes while preserving relationships:

;; Temperature and saturation — rotate hue in degrees,
;; desaturate/saturate in 0–1
(palette/warmer pal 12)
(palette/cooler pal 12)
(palette/muted pal 0.4)
(palette/vivid pal 0.4)

;; Lightness
(palette/darker pal 0.1)
(palette/lighter pal 0.1)

;; General adjustment
(palette/adjust pal {:lightness 0.1 :chroma -0.05})
Rendered output

Palette Analysis

Check that your palette works before committing to it:

;; Minimum pairwise contrast (WCAG)
(palette/min-contrast pal)

;; Sort by perceptual lightness
(palette/sort-by-lightness pal)

;; Visual preview at the REPL
(palette/swatch pal)

min-contrast returns the lowest WCAG contrast ratio between any two colors in the palette — useful for ensuring text readability or visual separation.

Extracting from Images

Pull a palette from an existing image using k-means clustering in OKLAB space:

(palette/from-image "reference.jpg" 5)
;=> [[:color/rgb 42 38 35]
;    [:color/rgb 180 140 90]
;    [:color/rgb 220 200 170]
;    [:color/rgb 80 100 60]
;    [:color/rgb 150 50 40]]
Rendered output

The number is how many dominant colors to extract. Clustering in OKLAB produces perceptually balanced palettes.

Applying Color

Use palette and noise together for organic color distribution:

(require '[eido.gen.vary :as vary])

;; Assign palette colors by index
(vary/by-palette 10 pal {:seed 42})

;; Noise-driven palette mapping
(vary/by-noise-palette positions pal
  {:noise-scale 0.01 :seed 42})

;; Weighted random palette — some colors appear more often
(palette/weighted-pick pal [0.4 0.3 0.2 0.1] {:seed 42})

The vary functions take seeds for deterministic results — same seed, same color assignment every time.