suelo :where([data-{c}]) (0,0,0) < forward [data-{c}]:where([data-color],
[data-color-custom]) (0,1,0) < tono [data-{c}][data-color='X'] (0,2,0).
El orden de emision deja de decidir: la especificidad ES el contrato,
legible en el artefacto (doctrina hermana de la FIRMA 12.9).
- Emisor (render-css.ts): isPaletteSlotToken PARTE el bucket host - solo
las ranuras de paleta bajan al suelo, el chasis del componente queda a
(0,1,0). 49 suelos + 49 forwards reescritos + 0 pares viejos; bloques
por tono (112), capa compartida y gradient finish byte-identicos.
- Neutra en pixel, MEDIDO: ~297.000 valores computados antes/despues
(105.248 planos lotes A+B, 57.720 planos lote C, 134.464 con los tonos
ESTAMPADOS en las 49 unidades, incluidos 5 @active), 0 diffs reales.
Los 17 crudos, probados ruido por reproduccion sobre codigo identico.
- Guarda por MUTACION (active-eidos-config.test.ts): suelo con contenido,
forward de un peldano, par viejo ausente, tono sin envolver, particion
del host, cierre estructural (toda declaracion de paleta vive en un
peldano) - 6 mutaciones inyectadas, 6 mordidas. El contrato del forward
pasa de vigilar 2 recetas a 49 (privadas incluidas, multi-parte bien).
- Ledger: PALETTE_SUPERSEDED muere (describia el mundo viejo); 207 de sus
353 claves pasan a VIVAS y las 146 restantes quedan bajo PALETTE_FLOOR
(el tono-default estampado resuelve por el forward: quitar el atributo
ES hablar en silencio) o TONE_UNREACHED (ningun paso del guard estampa
tono Y hoverea), con razon medida. stepper y tag-group, barridos por
primera vez. El detector STALE es CIEGO a patrones: la retirada fue
manual y por estrechamiento, guiada por medida.
- Docs: changelog 53 - reference THM-2 - next-features 13 (RESUELTA) -
CONTINUE-theming.
Supervision: 4 agentes Opus en 5 fases (baseline plano + baseline
estampado, emisor, guarda, verificacion de parque completo, docs), con
refutacion del supervisor sobre censo, emisor y guarda.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
// 2026-08-24. Four reasons, all measured on the real nodes with a real
// pointer; the twenty-four tone keys are the palette cascade and ride the
// PATTERN entry below.
// pointer. Of the twenty-four tone keys the old palette defect buried,
// SEVEN came back alive with firma B′; the seventeen still dead ride the
// two PATTERN entries below, and neither is the old supersession.
'item-fg':
"the ARCHETYPE ink always wins: the morfo stamps aria-selected='true' as a LITERAL on EVERY tag, so archetypes.css's `[data-archetype='item'][aria-selected='true']:not([data-state='checked']):not([data-state='on'])` (0,4,0) out-ranks the recipe's `[data-tags-input-item]` (0,1,0) on every item, at rest and always. Measured 2026-08-24: with the attribute as shipped the token moves nothing (the ink stays oklch(0.2435 0 0) = --color-content-primary, the archetype's); set aria-selected=false on the real tag and the same write reaches (rgb(1, 2, 3)). Same class as table.selected-row-fg and the listbox ink (next-features §12); the aria literal is a morfo decision and is registered, not touched from this axis",
'same xxl step, on AvatarGroup; forced data-size=xxl on the real group -> reaches (margin-inline-start -33.6px -> 37px)'
},
editable:{
// 2026-08-23. Only two reasons, both measured: the transition pair IS the
// transition the guard freezes, and the twelve tone keys are the palette
// cascade (adjudicated by PATTERN below).
// 2026-08-23, revised 2026-08-24. The transition pair IS the transition the
// guard freezes. Of the twelve tone keys the old palette defect buried, TEN
// came back alive the moment firma B′ landed; only the two `primary-*` are
// still covered, by PATTERN below, and for a different reason (the floor).
'submit-fg':
'OSCILLATES: read ALIVE in 3 of 4 runs on the same HEAD (42/56) and dead in the fourth (41/56). Leaving the edit mode is what a blur does, and the guard opens by focus + prepareWith, so the surface it measures is not deterministic. Measured alive with the editor open and transitions frozen -> reaches. Without this entry the fourth run fails R-5.4 with a token that does not lie (2026-08-23)',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 4.321s on the three transitioned properties of the preview)',
// NOT the palette pattern: this one key is ALSO read straight by the invalid
// rules, so its silence has a second, different cause — the demo is valid.
'risk-border':
'the palette path is superseded like its eleven siblings, but this key is ALSO the invalid tint, read directly by three rules; forced data-invalid on the real root -> reaches on the input AND on the control (oklch(0.8059 0.1123 59.96) -> rgb(1, 2, 3))'
'transition-duration':'the guard freezes transitions to measure and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s, five properties)',
'disabled-opacity':'no disabled button in the demo; forced data-disabled -> reaches (0.4 -> 0.137)',
'primary-track':'the FALLBACK of the palette forward: it acts only on an instance with NO data-color, and the demo stamps data-color=primary. Removed the attribute -> reaches. See the pattern entry below for the other seven tones',
'primary-element':'same fallback, same condition',
'primary-border':'same fallback, same condition',
'primary-solid':'same fallback: without data-color it repaints (oklch(0.5556 0.1829 305.86) -> rgb(1,2,3)); with data-color=primary the generic forward rule supersedes it',
'primary-solid-hover':'same fallback, same condition',
'primary-text':'same fallback, same condition',
'primary-contrast':'same fallback, same condition',
'palette-track':'a RESOLVED name, declared on [data-button] by the forward, so a :root write loses BY DESIGN - a theme moves the tone or the scale. Measured on a soft button: from :root nothing, from the node oklch(0.9932 0.0034 325.6) -> rgb(4,5,6)',
// The seven `primary-*` keys moved to a PATTERN entry below when firma B′
// (2026-08-24) replaced the order-decides defect with the ladder: they are
// the FLOOR under the forward now, one fact, not seven accidents.
'palette-track':'a RESOLVED name, declared on the node itself — by the floor :where([data-button]) at (0,0,0) and, on a coloured instance, by the forward at (0,1,0). Either way it is a declaration ON the element, so a :root write loses BY DESIGN (an inherited value never beats one declared on the node, whatever its specificity) - a theme moves the tone or the scale. Measured on a soft button: from :root nothing, from the node oklch(0.9932 0.0034 325.6) -> rgb(4,5,6)',
'palette-element':'same resolved name; the theme moves its coordinate',
'palette-border':'same resolved name; the theme moves its coordinate',
'palette-text':'same resolved name; the theme moves its coordinate'
'TWO reasons, and either alone would be enough: the edge fade only exists under `[data-scrollable]`, an opt-in switch the stage boots OFF, and it paints through `mask-image`, which is not in the guard read set. Measured 2026-08-24 with the demo switch on and transitions frozen -> reaches (the mask reads `linear-gradient(to right, transparent, black 16px, black calc(100% - 16px), transparent)` and the write moves both stops to 1234px)'
},
// ── First sweep 2026-08-24, riding the firma B′ run. Neither component had a
// ledger before: the palette ladder is what made them measurable at all. ──
stepper:{
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen 2026-08-24 -> reaches (0.12s -> 4.321s on all four transitioned properties: background, border-color, color, box-shadow)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3) on the same four)',
// NOT a tone problem: stepper emits a `neutral` block and the ladder gives
// it to the node. The instrument is what cannot see it.
'neutral-text':
"the SENTINEL VALUE, not the token: `sentinelFor` picks a colour only for keys matching /color|bg$|fg$|border$|ring$|…|track$/, and `neutral-text` matches none of them, so the guard writes `1234px` — invalid for `color`, which then falls back to the inherited ink. Neutral's text tone IS practically that ink, so the fallback lands on the same computed value and nothing moves. Measured 2026-08-24 with a real colour on the current indicator, tone stamped: --stepper-neutral-text repaints it (rgb(1, 2, 3)). The same instrument gap would hide any `{tone}-text` whose tone sits near the inherited ink"
},
'tag-group':{
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen 2026-08-24 -> reaches on the four transitioned properties of the tag',
'the ink of the SOLID variant, and the ficha mounts its tags SOFT (measured: 12 nodes, one data-variant=soft); the guard declares no sweep for tag-group. Forced data-variant=solid on the real selected tag 2026-08-24 -> reaches (rgb(255, 255, 255) -> rgb(1, 2, 3))',
'hover-item-fg':
"the ARCHETYPE ink wins, exactly as it does on tags-input's item-fg: archetypes.css paints `[data-archetype='item']:hover:not([data-disabled]):not([data-state='checked']):not([data-state='on'])` at (0,4,0) and the recipe's `[data-tag-group-item]:hover:not([data-disabled])` is (0,3,0), so the hover ink is the system's, never the recipe's. Measured 2026-08-24 with a real pointer on a real tag (`:hover` confirmed true): the colour stays oklch(0.2435 0 0) = --color-content-primary, the archetype's, and the write moves nothing — with or without aria-selected. The hover is the system's by doctrine, so this is a token that should not exist rather than a token that lies; registered, not touched from this axis"
'SUPERSEDED, not missing: the generic [data-{c}][data-color] block of the palette forward is emitted LAST and wins by source order at equal specificity, so the tone keys are bypassed and the paint comes from the global --palette-* (see next-features 13, measured on button, badge and callout 2026-08-23)';
constPALETTE_FLOOR=
'THE FLOOR UNDER THE FORWARD: this tone is the recipe HOST DEFAULT, so it has no [data-{c}][data-color=X] block — its values are the floor :where([data-{c}]) at (0,0,0). soma stamps data-color on every instance, so the forward [data-{c}]:where([data-color], [data-color-custom]) at (0,1,0) always covers it and resolves from the shared --palette-*. REMOVE data-color from the same node and the key repaints — measured 2026-08-24, firma B′';
'ALIVE, unmeasurable by THIS guard: the slot needs its tone AND a state the guard cannot hold at once (the static pass stamps data-color but never hovers; the hover pass hovers but never stamps data-color)';
' — button defaults to PRIMARY. Measured 2026-08-24 on the ficha button with data-color REMOVED: --button-primary-solid repaints the fill (oklch(0.5556 0.1829 305.86) -> rgb(1, 2, 3)) and, with a real pointer on it, --button-primary-solid-hover too (oklch(0.5246 0.1755 305.39) -> rgb(1, 2, 3)). These seven replace the seven exact entries the old order-decides defect needed'
" — button declares no COMPONENT_OVERRIDES, so no data-variant is swept, and its ficha mounts ONE button, solid: `solid` and `contrast` are the only slices that paint there at rest, and both read ALIVE for the seven tones (14 keys the ladder gave back). Measured by hand 2026-08-24 on that same button with data-color=secondary — forced soft: --button-secondary-track repaints the background (oklch(0.9913 0.0013 286.38) -> rgb(1, 2, 3)) and --button-secondary-text the ink; forced outline: --button-secondary-border repaints; hovered: --button-secondary-solid-hover (oklch(0.6108 0.0155 272.56) -> rgb(1, 2, 3)) and, on soft, --button-secondary-element (oklch(0.956 0.004 286.32) -> rgb(1, 2, 3)). Not one of the five is dead; the stage is"
' — the slot lives at [data-checkbox][data-variant=solid][data-state=checked]:hover. Measured 2026-08-24 on the real CHECKED box with the tone stamped and a real pointer on it: --checkbox-neutral-solid-hover repaints background and border (oklch(0.61 0 0) -> rgb(1, 2, 3))'
},
{
component:'radio-group',
pattern:/^primary-solid$/,
reason:
PALETTE_FLOOR+
' — same shape as its twin checkbox: radio-group defaults to PRIMARY, and the secondary / neutral / affirm `-solid` keys read ALIVE on this run (they were dead under the old order-decides defect). Measured 2026-08-24 with data-color stripped from the real group -> reaches'
' — the same four tones x two slots as its twin checkbox, and PRIMARY falls with them: the eidos wrapper always resolves a colour and stamps data-color, so the generic block matches on every instance and the fallback that names the component key never applies. Measured 2026-08-23 on an affirm instance: --radio-group-affirm-solid moves nothing (oklch(0.6491 0.1136 181.96) stays), --palette-solid on the same node repaints (rgb(4, 5, 6))'
TONE_UNREACHED +
' — the slot lives at [data-radio-group][data-variant=solid] [data-radio-group-item][data-state=checked]:hover, the item twin of the checkbox entry above. Measured 2026-08-24 on the real CHECKED item with the tone stamped and a real pointer on it: --radio-group-neutral-solid-hover repaints background and border (oklch(0.61 0 0) -> rgb(1, 2, 3))'
' — measured here 2026-08-23 with the mechanism in the open: the node carries --palette-solid (oklch(0.5556 …)) from the shared per-instance layer, the generic block reads it, and the fallback that names the component key never applies; strip data-color from the same instance and --editable-primary-solid paints again (rgb(1, 2, 3)). soma always stamps data-color, so no instance escapes'
PALETTE_FLOOR+
' — editable defaults to PRIMARY; its other five tones x two slots (10 keys) read ALIVE on this run, `risk-border` among them — the exact entry that key used to carry went with the fix'
' — track / border / text paint ONLY on [data-file-upload-dropzone]:hover (or [data-dragging]) and solid-hover only on [data-file-upload-trigger]:hover; none of the four key names contains "hover", so not even the hover pass runs for them. Measured 2026-08-24 with a real pointer and the tone stamped, all four repaint: --file-upload-secondary-track and -border and -text on the hovered dropzone, --file-upload-secondary-solid-hover on the hovered trigger (oklch(0.6108 0.0155 272.56) -> rgb(1, 2, 3)). The seven `-solid` keys, which paint at rest on the trigger, read ALIVE'
},
{
component:'switch',
pattern:/^neutral-(solid|solid-hover)$/,
reason:
PALETTE_SUPERSEDED+
' — the eight tones x five slots, 40 of its 97 keys. Measured 2026-08-23 on the trigger (solid) and on the hovered dropzone (track) for the eight tones: not one moves, while --palette-solid on the node repaints (oklch(0.6908 …) -> rgb(4,5,6)). Its host default is `primary`, and the demo passes color explicitly, so the fallback never applies either'
PALETTE_FLOOR+
' — switch defaults to NEUTRAL. Measured 2026-08-24 on the real track forced checked with data-color removed: --switch-neutral-solid repaints it (oklch(0.6434 0 0) -> rgb(1, 2, 3))'
' — and here NEUTRAL falls with the rest: soma always stamps data-color (it is the resolved colour, neutral by default), so the generic block matches on every instance and the fallback the other recipes keep alive never applies. Measured checked 2026-08-23: --switch-neutral-solid moves nothing, --palette-solid on the node repaints (oklch(0.5556 …) -> rgb(4,5,6))'
TONE_UNREACHED +
' — every palette slot of switch hangs off [data-switch][data-state=checked], its ficha mounts ONE switch and it boots UNCHECKED (measured: 1 node, data-state=unchecked), and the guard declares no data-state sweep for switch. That is the whole reason all twelve read dead while the ladder works. Forced checked with the tone stamped 2026-08-24: --switch-secondary-solid repaints the track (oklch(0.6453 0.0165 277.7) -> rgb(1, 2, 3)) and --switch-primary-solid too (oklch(0.5556 0.1829 305.86) -> rgb(1, 2, 3))'
' — toggle defaults to NEUTRAL, and the guard STAMPS data-color=neutral to test these eight, which is exactly what turns the forward on. Measured 2026-08-24 on the real toggle forced solid/on with data-color removed: --toggle-neutral-solid repaints the fill (oklch(0.6434 0 0) -> rgb(1, 2, 3))'
' — the six tones toggle forwards x eight slots, 48 of its 126 keys (it excludes fulfill/loss by doctrine: a toggle is neither completion nor irreversible loss). Measured 2026-08-23 on the real pressed toggle with transitions frozen: with data-color=primary, --toggle-primary-solid moves NOTHING (the fill stays oklch(0.5556 0.1829 305.86)) while --palette-solid on the same node repaints it (rgb(1, 2, 3)); strip data-color and --toggle-neutral-solid paints again (oklch(0.6434 0 0) -> rgb(1, 2, 3)). The neutral eight fall with the rest for a second reason worth writing down: the guard STAMPS data-color=neutral to test them, which is exactly what turns the generic block on'
TONE_UNREACHED +
' — toggle DOES sweep data-variant x data-state, which is why 30 of its 48 tone keys read alive on this run; the two hover slots are the one thing no sweep can add. Measured 2026-08-24 with a real pointer and the tone stamped: --toggle-primary-solid-hover on solid+on repaints (oklch(0.5246 0.1755 305.39) -> rgb(1, 2, 3)), and --toggle-primary-hover on outline+on — the only slice that reads it, through --toggle-outline-on-hover-bg — repaints too (oklch(0.9333 0.0386 312.65) -> rgb(1, 2, 3)). It excludes fulfill/loss by doctrine: a toggle is neither completion nor irreversible loss'
' — the eight tones x five slots, 40 of its 98 keys. Measured 2026-08-23 on the real stage card with transitions frozen: with data-color=primary, --card-primary-track moves NOTHING (the surface stays oklch(0.9932 0.0034 325.6)) while --palette-track on the same node repaints it (rgb(1, 2, 3)); strip data-color and --card-neutral-track paints again (oklch(0.9911 0 0) -> rgb(1, 2, 3)). The wrapper stamps data-color on every instance, so the named fallback never applies'
PALETTE_FLOOR+
' — card defaults to NEUTRAL, not primary; its other seven tones x five slots (35 keys) read ALIVE on this run, primary-track among them (it was the headline of the old defect: with data-color=primary the surface would not move)'
' — the eight tones x three slots, 24 of its 91 keys. Measured 2026-08-24 on the real tag forced into data-state=active with transitions frozen: with data-color=primary (the wrapper resolves `color` and stamps it on EVERY instance, default included) --tags-input-primary-border moves NOTHING (the tag border stays oklch(0.8043 0.0918 309.69)) while --palette-border on the same node repaints it (rgb(4, 5, 6)); strip data-color and --tags-input-primary-border paints again (rgb(1, 2, 3)). The generic `[data-tags-input][data-color], [data-tags-input][data-color-custom]` block is emitted LAST at the same (0,2,0) as the eight per-tone blocks. The three `*-text` slots carry a SECOND cause on top: even unsuperseded they cannot tint the item, because the archetype ink beats them (see the item-fg entry above)'
PALETTE_FLOOR+
' — tags-input defaults to PRIMARY; the seven other `-border` keys read ALIVE on this run'
' — the three slots share ONE rule, [data-tags-input-item][data-state=active], and the guard sweeps data-focus / data-invalid / data-disabled for this component, never data-state; `border` reads alive because the CONTROL paints it under data-focus, which IS swept. Measured 2026-08-24 forcing data-state=active on the real tag with the tone stamped: --tags-input-secondary-track repaints it (oklch(0.9913 0.0013 286.38) -> rgb(1, 2, 3)) and --tags-input-secondary-text the ink. The eight `-text` keys carry a SECOND cause on top: the archetype ink beats the recipe on every tag (see the item-fg entry above)'
' — select defaults to PRIMARY, and here the ladder is the TSC v2.2 MULTI-PART one (parts trigger + content, because the panel portals out): floor `:where([data-select-trigger], [data-select-content])`, forward `[data-select-trigger]:where([data-color], [data-color-custom]), …`, tone `[data-select-trigger][data-color=X], …`. Its other seven tones x three slots (21 keys) read ALIVE on this run'
},
// ── stepper — first sweep (2026-08-24), so nothing here is a narrowing ──
{
component:'stepper',
pattern:/^primary-(solid|track|border|text)$/,
reason:
PALETTE_FLOOR+
' — stepper defaults to PRIMARY. Measured 2026-08-24 with data-color stripped from the real indicator: --stepper-primary-solid repaints it. Its secondary / neutral / affirm / fulfill blocks read ALIVE on this run'
},
// ── tag-group — first sweep (2026-08-24) ───────────────────────────────
' — tag-group names its slots {tone}-{variant}-{bg|fg} and defaults to PRIMARY. Measured 2026-08-24 with data-color stripped from the real tag forced selected: --tag-group-primary-soft-bg repaints it (rgba(128, 0, 223, 0.03) -> rgb(1, 2, 3)) and --tag-group-primary-soft-fg the ink (oklch(0.5168 0.1733 305.88) -> rgb(1, 2, 3))'
' — every palette slot of tag-group hangs off [data-state=selected] AND a data-variant, its ficha mounts ONE selected tag in the SOFT variant (measured: 12 nodes, one data-variant=soft), and the guard declares no sweep for tag-group — which is why the soft slots of the seven tones are exactly what reads alive. Measured 2026-08-24 forcing selected + the variant with the tone stamped: --tag-group-secondary-solid-bg repaints under solid (oklch(0.6453 0.0165 277.7) -> rgb(1, 2, 3)) and --tag-group-secondary-outline-border under outline (oklch(0.853 0.0111 280.45) -> rgb(1, 2, 3))'
' — the eight tones x three slots, 24 of its 103 keys, and here the cascade is the TSC v2.2 MULTI-PART one (parts trigger + content, because the panel portals out): the last block emitted is `[data-select-trigger][data-color], [data-select-content][data-color], …` reading `var(--palette-track, var(--select-primary-track))`. Measured 2026-08-24 on the open trigger, which carries data-color=primary: --select-primary-border moves NOTHING (border stays oklch(0.8043 0.0918 309.69)) while --palette-border on the same node repaints it (rgb(4, 5, 6)). soma always stamps data-color, so the named fallback never applies on any instance'
TONE_UNREACHED +
' — the soft hover of a selected tag. `hover-affirm-soft-bg` is deliberately NOT in this pattern: the ficha tag is affirm+soft, so the hover pass reaches that one and it reads alive — if a future stage stops mounting it, the key must earn its own reason rather than hide in here. Measured 2026-08-24 with a real pointer, tone stamped, tag forced selected: --tag-group-hover-secondary-soft-bg repaints it (rgba(0, 0, 51, 0.06) -> rgb(1, 2, 3))'