Cero claves acuñadas, y eso es el resultado: el censo daba `global 0` — la
receta ya lee su propio contrato en cada declaración, con el eje `size`
resuelto por el TSC a través de siete privados que sólo reapuntan claves
públicas por talla. Lo que quedaba fuera del alcance eran tres cosas
CLASIFICADAS, no tres deudas. La mitad del trabajo de este eje es adjudicar.
1. Los DOS privados son CONMUTADORES por variante, medidos variante a variante
sobre el nodo real: `--_toolbar-bg` vale `var(--toolbar-bg)`
(oklch(0.9821 0 0)) en `surface` y `transparent` en `outline` y `ghost`;
`--_toolbar-shadow` vale `var(--toolbar-shadow)` y `none` en las mismas. Ese
segundo valor es la IDENTIDAD de la variante, no un knob: una barra `ghost`
ES la que no tiene relleno ni sombra, y un público encima dejaría que un tema
la rellenara y matara la variante en silencio. Se quedan privados (clase
«conmutador» de F2-B, sexto caso tras textarea, spinner, skeleton, code y
label). Ni escala por talla ni puente THM-2: esta barra no tiene paleta.
2. El único literal es una IDENTIDAD y ahora está FIRMADO: el
`inline-size: 100%` del separador horizontal abarca el eje transversal de la
barra — el mismo trabajo que `align-self: stretch` hace en el gemelo vertical
(medido: 112 px sobre un contenedor de 126 px). Su grosor y su suelo sí son
tokens. Con su anotación `/* literal: */` sale del ratio.
3. LA CASCADA DEL COMPONENTE COMPUESTO NO LE CUESTA UNA SOLA CLAVE, y es la
lección. `Toolbar.Button` compone el `<Button>` canónico, así que sus nodos
llevan `data-button` Y `data-toolbar-button`, y `[data-button]` casa con la
misma especificidad (0,1,0) pero se emite DESPUÉS. La diferencia con `form`
—que conserva 24 declaraciones que Button anula— es que esta receta YA CEDIÓ
el cromo del botón (A-112) y no escribe ni una regla `[data-toolbar-button]`.
Medido ANTES de tocar nada: 51/54 vivos, y ninguna de las tres silenciosas
era del botón. Las claves `control-*` visten el Link y el GroupItem, que sí
son superficie de la barra.
Censo: 35 → 34 knobs · público 30 · privado 2 · literal 1 → 0 · excepción
0 → 1 · sistema 2 · 91 % → 94 %. Contrato 54 claves, intacto. Global del
catálogo 68 %, sin bajar.
Diff de computed: VACÍO — 2.464 valores en 7 estados sobre 11 nodos (la barra,
sus tres botones compuestos, dos separadores, el grupo, sus tres items y el
enlace). Capturas 2× antes/después: idénticas.
Centinela R-5.4: 52/54, dos adjudicadas, cero muertas sin razón.
- `transition-duration` / `transition-ease` SON la transición que el guard
congela para poder leer todo lo demás. Medidas sin congelar sobre el Link
real, que transiciona CUATRO propiedades: `0.12s ×4 → 4.321s ×4` y
`cubic-bezier(0.4, 0, 0.2, 1) ×4 → steps(3) ×4`. Al ledger con esa razón.
- `disabled-opacity` NO se adjudica: se ARREGLA. El guard enciende ahora el
interruptor «group disabled» de la demo, y comprobado que no tapa nada — la
regla de hover es `[data-toolbar-link]:hover,
[data-toolbar-group-item]:hover:not([data-disabled])` y el Link no pertenece
al grupo, así que conserva las dos claves de hover. Corrido antes y después
del control: 51/54 → 52/54, el conjunto muerto encoge en uno y no gana
ninguno.
Guards: censo `--only` 94 % · `component-audit --only toolbar` PASS ·
`eidos-lint toolbar` 16 morfo-backed / 5 eidos-only / 0 invalid ·
`vitest run src/uix/eidos` 35/36 ficheros (el rojo es `skin-media-player`, el
conocido) · `rtl:check` 0 · `docs:check` 0 · `check` COMPLETED sin un solo
error atribuible a este componente · prettier: la anotación `/* literal: */`
sobrevive en la MISMA línea y mi bloque del README queda limpio; los 12 hunks
de deriva del README y los 12 de la demo son PREEXISTENTES en HEAD y no se
tocan.
Artefactos de documentación del protocolo: README con su `## Talla y tema`
derivada del contrato (los nueve ejes + la clasificación de los privados),
pestaña `Tokens` en la demo (54 claves resueltas en vivo, verificada en
navegador) y veredicto §5 de la ficha.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>