From 7b54375f38f3b3c58201d0e726c58b67377eb5f7 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 8 Jun 2026 19:56:07 -0500 Subject: chore(todo): close Phase 2 picker readouts task --- todo.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/todo.org b/todo.org index f0318d92..06f32ed1 100644 --- a/todo.org +++ b/todo.org @@ -122,8 +122,8 @@ Extended the guarded =#selftest= harness (headless Chrome) to assert the accepta Spec (Ready, opens confirmed 2026-06-08): [[file:docs/design/theme-studio-perceptual-color-metrics-spec.org][docs/design/theme-studio-perceptual-color-metrics-spec.org]]. OKLCH model + perceptual-L/APCA readouts + pairwise ΔE, for building low-contrast themes by metric rather than by eye. Phases run in dependency order; the math core extracts to a Node-unit-tested =colormath.js= and the browser hash tests verify UI wiring. vNext deferrals (low-contrast preset, CIEDE2000) are the two [#D] tasks below. *** 2026-06-08 Mon @ 19:43:50 -0500 Color-math foundation + Node tests landed Pure color core in =scripts/theme-studio/colormath.js= (OKLab/OKLCH, APCA-W3 0.1.9 exact constants, ΔE-OK, binary-search gamut clamp returning ={hex,clamped}=) shipped in 49342bf5; this phase finished the integration in 78260018. =generate.py= now inlines the colormath.js body into the page script (export-stripped, =COLORMATH_J= placeholder), and the page's lin/rl/contrast/rating/hsv2rgb/rgb2hsv/hex2rgb/rgb2hex copies moved into the module — =rl= reuses the canonical =lin= (0.04045 cutoff), byte-identical to the old 0.03928 form on every #rrggbb (no 8-bit channel falls between the cutoffs; verified over 200k pairs, zero contrast change). =test-colormath.mjs= gained Normal/Boundary/Error cases for the migrated helpers, a seeded hsv-rgb round-trip property test, and an inline-integrity check that the generated page carries the module body verbatim. Gate met: =node --test scripts/theme-studio/*.mjs= 15 pass, colormath.js 100% line / 93.75% branch / 100% func; =node --check= on the spliced script clean; =#selftest= + =#cursortest= PASS in headless Chrome. NOTE: =node --test = directory-globbing is broken on Node v26 (tries to load the dir as a module) — use the =*.mjs= glob form. -*** TODO [#B] Picker OKLCH/APCA readouts :solo: -Phase 2. OKLCH L/C/H + signed APCA Lc (polarity label + tooltip) beside the WCAG ratio in the picker =.pinfo=; always shown. Tables unchanged. Gate: =#readouttest= + =#selftest= PASS, no behavior change. +*** 2026-06-08 Mon @ 19:55:53 -0500 Picker OKLCH/APCA readouts landed +Phase 2 shipped in 77c7f126. Second readout row (=.pinfo2=) under the WCAG ratio: OKLCH L/C/H + signed APCA Lc against the ground color, always shown; sign convention in the APCA tooltip + README. Tables unchanged (APCA picker-only per Agreed-decision #3). =pkReadout= drives the spans from the inlined colormath functions. Gate met: =#readouttest= asserts the spans match the live computation AND the known dupre-blue OKLCH reference (L 0.591 / C 0.052 / H 252°, APCA Lc -34 on ground) with WCAG unchanged; =#selftest= + =#cursortest= still PASS; 15 Node tests green. Headless-rendered values verified against a node cross-check. Visual eyeball is the open "Perceptual readouts read well in the picker" item under Manual testing. *** TODO [#B] Palette ΔE warnings :solo: Phase 3. Pairwise ΔE-OK across =PALETTE=; warn on pairs below 0.02 (named constant), sorted closest-first, capped at 5 with "and N more"; nearest-neighbor ΔE in each chip title. Gate: =#deltatest= PASS. *** TODO [#B] OKLCH sliders + color-model control :solo: -- cgit v1.2.3