You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Priority: P2 — tooling. Found while diagnosing text-fg-muted vs shadcn (2026-08-04); a working prototype exists.
Nothing in the UI says what a rung is. neutral-900 is "text low-contrast" in the 12-job ladder, and that fact lives in a docstring in www/src/registry/theme/semantics.ts and nowhere a user can see. Nothing shows which rungs are adjustable and which are solver outputs. And the existing ramp visual actively hides the ladder's geometry.
Diagnosing a single muted-text question took a full session of hand-computed APCA arithmetic. It should have been one glance.
The visualization defect
ColorRampsVisual (www/src/modules/create/panel/schema.tsx:167) renders every step as flex-1 — equal width. Every ramp looks evenly spaced whether or not it is. The real spacing at the text end:
800 → 900 gap
light
~7.5 Lc
dark
~21.7 Lc
That 3× asymmetry is invisible today, and it is precisely why the muted step behaves so differently per mode.
What to build
A color-lab section (www/src/modules/color-lab/sections/) — not in the /create panel, which is queued for a full rewrite from an experience spec. color-lab is the sanctioned playground for the color rewrite and already has the section scaffolding plus SystemPreview.
For one palette at a time:
Rungs positioned by real L*, not equal-width, in both modes on a shared axis. The spacing defect must be the first thing you see.
Each rung labeled with its job — 25 app-bg · 50 subtle-bg · 100/200/300 ui rest/hover/active · 400/500/600 borders · 700/800 solid/hover · 900/950 text low/high.
Selecting a rung shows what governs it — not a dial to drag it.
Point 3 is the design idea worth keeping. Seven of twelve rungs are solver outputs, so a per-rung "adjust" affordance promises control that doesn't exist:
rung
governed by
25
background axis, via transposeSkeleton
50–300
the skeleton — moves as a group with 25, not individually
nothing — hoverSolid derives it from 700, shrinking to protect the on-label bars
900/950
solveText vs BARS.text900/950, anchored at TEXT_TARGETS
The "no control, and here's why" cells are the most valuable in the view — they teach the engine's architecture instead of hiding it.
A "Feeds" column: rung → semantic token → consuming components. No component consumes neutral-900; they consume --color-fg-muted (609 call sites / 229 files). The middle link is what makes the first column legible. Same map the relaxed-policy warnings need — build once, use twice.
Prototype
LadderRow exists in Control Lab (www/src/modules/control-lab/rows.tsx + page.tsx, at /internal/panel-lab/controls#ladder-row) — L*-positioned strips for both modes, rung rail with family brackets, inspector with job name, CSS var, per-mode swatch, gap-to-next, "Governed by", and live "Feeds" chips from DEFAULT_SEMANTICS. Not wired into anything.
Two known defects to fix when promoting it:
The 900/950 copy is wrong. It says "the bars own this rung — there is no dial." True in dark (Lc 61.5 vs bar 60), false in light, where the anchor binds and both bars have headroom (5.31 vs 4.5, Lc 71.5 vs 60). It teaches the opposite of the actual mechanism. It should distinguish anchor-bound from bar-bound per mode.
Best follow-up: make the 900 anchor a live control clamped by the bars. The asymmetry then becomes something you feel — light pulls back a long way before stopping, dark stops in ~1.5 Lc — instead of a table.
Priority: P2 — tooling. Found while diagnosing
text-fg-mutedvs shadcn (2026-08-04); a working prototype exists.Nothing in the UI says what a rung is.
neutral-900is "text low-contrast" in the 12-job ladder, and that fact lives in a docstring inwww/src/registry/theme/semantics.tsand nowhere a user can see. Nothing shows which rungs are adjustable and which are solver outputs. And the existing ramp visual actively hides the ladder's geometry.Diagnosing a single muted-text question took a full session of hand-computed APCA arithmetic. It should have been one glance.
The visualization defect
ColorRampsVisual(www/src/modules/create/panel/schema.tsx:167) renders every step asflex-1— equal width. Every ramp looks evenly spaced whether or not it is. The real spacing at the text end:That 3× asymmetry is invisible today, and it is precisely why the muted step behaves so differently per mode.
What to build
A color-lab section (
www/src/modules/color-lab/sections/) — not in the/createpanel, which is queued for a full rewrite from an experience spec. color-lab is the sanctioned playground for the color rewrite and already has the section scaffolding plusSystemPreview.For one palette at a time:
Point 3 is the design idea worth keeping. Seven of twelve rungs are solver outputs, so a per-rung "adjust" affordance promises control that doesn't exist:
backgroundaxis, viatransposeSkeletonsolveBorderTarget, floorsBARS.border400/500/600preserveSeed)hoverSolidderives it from 700, shrinking to protect the on-label barssolveTextvsBARS.text900/950, anchored atTEXT_TARGETSThe "no control, and here's why" cells are the most valuable in the view — they teach the engine's architecture instead of hiding it.
neutral-900; they consume--color-fg-muted(609 call sites / 229 files). The middle link is what makes the first column legible. Same map the relaxed-policy warnings need — build once, use twice.Prototype
LadderRowexists in Control Lab (www/src/modules/control-lab/rows.tsx+page.tsx, at/internal/panel-lab/controls#ladder-row) — L*-positioned strips for both modes, rung rail with family brackets, inspector with job name, CSS var, per-mode swatch, gap-to-next, "Governed by", and live "Feeds" chips fromDEFAULT_SEMANTICS. Not wired into anything.Two known defects to fix when promoting it:
Best follow-up: make the 900 anchor a live control clamped by the bars. The asymmetry then becomes something you feel — light pulls back a long way before stopping, dark stops in ~1.5 Lc — instead of a table.
Links