146 KiB
PLAN — Theming: que TODO componente sea personalizable por un tema (eje theme-reach)
Estado (act. 2026-08-23): EN EJECUCIÓN — alcance global 65 %, 25 componentes al 100 %, 24 sin contrato, 12 por debajo del 20 %. Vocabulario CERRADO (codemod + R-5.3 + muro de tipos), bloques F2-A y F2-B CERRADOS y la cola avanzando: dieciséis componentes el 2026-08-23. Las D-TH.1…8 de §4 FIRMADAS TODAS el 2026-08-20 (más las tres decisiones hermanas del mismo día: familia calendar = capa compartida, mandato Field ejecutable, hover→capa de estado — ver «Firmas del 2026-08-20» del CONTINUE). El registro con cifras y commits está en §8, y el punto de entrada diario es
CONTINUE-theming.md. Toda decisión NUEVA que surja se sigue presentando una por mensaje, con las cinco preguntas.Origen (conversación 2026-08-19): al arreglar
navigation-menusalió que el radio de su trigger vivía en un privado clavado a--radius-defaulty que el contrato del componente sólo publicaba tres knobs: ningún tema podía decir «píldora» sin mover el radio del sistema entero. El autor, textual: «esto ha abierto una duda importante, y es si los componentes creados son themables; si no lo son, es un error como framework. Necesitaríamos desarrollar un plan para auditar todos los componentes, verificar qué grado de personalización soportan y desarrollar una corrección a cada uno de ellos para que sean totalmente personalizables.» Y sobre la ejecución: «lo ejecutará Opus, y Opus falla mucho, por lo que tienes que establecer procesos de verificación en todo el plan.» Este documento obedece a las dos frases: §1 es la auditoría MEDIDA (reproducible por script, no por memoria), §5 son las fases, y §7 es el protocolo de verificación que cada sesión ejecuta sin excepción.Kickoff para sesión nueva: «Lee
docs/process/PLAN-theming.mdENTERO y despuésCONTINUE-theming.md; si las D-TH de §4 están firmadas, ejecuta el siguiente bloque de §5 con el protocolo de §7, un componente por commit; si no, PARA y preséntalas una a una.»Fuentes de doctrina que este plan cita y NO copia:
docs/theming/reference.md§1bis, §3, §5, §6, §7, §12, §16 ·docs/canon/tsc.md·docs/canon/recipe-contract.md§1–§5 ·docs/theming/motion.md§"When both writeanimationon ONE node" ·docs/guides/component-guide.md§Build contract ·src/uix/eidos/components/README.md· el precedente ejecutado y firmado:PLAN-sidebar.md§3 + F3 (el ejesizede la fila, 2026-08-19) ynavigation-menu(ae9e277fa·a82794845, el cromo del trigger en tokens públicos).
0. Veredicto corto
- La doctrina ya lo exige; los guards no lo comprueban. recipe-contract §1:
«Every recipe declares its knobs in
lib/recipes/base.ts»; theming §6: el token público de componente es--{c}-{slot}; la TSC decide dónde se emite. Pero R-1…R-4 comprueban que no haya literales (y que lo que haya sea unvar(), no que cada knob sea alcanzable por un tema. Una receta con todo envar(--radius-md)y en privados--_{c}-*pasacomponent:auditen PASS y la dimensión 10 «Adopción theming» de la ficha en ✓ — y sólo se puede temar moviendo el planeta. Es un error de framework porque rompe la promesa que el framework hace por escrito. - Medido, no opinado (§1,
scripts/theming-census.ts): de 5.205 knobs de apariencia en 162 recetas, 1.621 (33 %) pasan por un token público del componente; 1.880 atan directo a un primitivo global; 856 a privados; 614 son literales. 62 componentes no tienen una sola entrada en el contrato; 59 tienen alcance < 20 %; 6 están al 100 %.navigation-menu, tras el trabajo de hoy, está en 44 %: el eje no se cierra arreglando un componente. - La corrección es mecánica y ya tiene forma firmada: la de la fila del
Sidebar(D-SB.5/D-SB.6,PLAN-sidebar.md§3) y la del trigger del nav (ae9e277fa): tokens públicos por talla que apuntan al bundle--size-{k}-*, nombre RESUELTO pordata-size, acentos de estado enbackground-color, y el default queda idéntico — sólo cambia quién puede moverlo. Lo que NO hay que hacer: rediseñar nada por el camino. - Sin guard no hay cierre: el censo de hoy se repetirá en seis meses si
R-5 no existe. F0 crea el guard en
warncon la cifra de hoy como suelo; F3 lo gradúa aerrorcuando el backfill termina. Igual que hizo R-4.x el 2026-07-02.
1. Inventario medido (2026-08-19)
Instrumento: node --import tsx/esm scripts/theming-census.ts (añadido
con este plan; --json para máquina; --only {c} por componente). Cuenta, por
receta CSS, cada declaración de APARIENCIA (lista KNOB_PROPS en el script:
fondo, tinta, borde, radio, sombra, padding, gap, tipografía, tamaño, opacidad,
fill/stroke, filtros) y la clasifica por el ORIGEN de su valor:
| Clase | Qué es | ¿La alcanza un tema de componente? |
|---|---|---|
public |
var(--{c}-…) — token del contrato del componente |
Sí |
private |
var(--_{c}-…) — nombre interno |
No (salvo que el privado DERIVE de un público — el script no lo distingue, cuenta como no) |
global |
cualquier otro var(--…): --space-*, --radius-*, --color-*, --font-size-*, --size-*… |
Sólo moviendo el sistema |
literal |
sin var(: 8px, 1.25, #fff |
No, y además viola R-4/R-2 |
system |
sistemas transversales que una receta CONSUME: capa de estado, anillo de foco, planos de depth, motion, bandas z, opacidad, shape, floating-gap |
Sí, a nivel de sistema, por diseño (recipe-contract §2) — fuera del ratio |
Alcance = public / (public + private + global + literal).
1.1 Totales
| Medida | Valor |
|---|---|
| Componentes con receta CSS | 162 |
| Knobs de apariencia | 5.205 |
| Por token público del componente | 1.621 (33 %) |
| Por privado | 856 |
| Directo a primitivo global | 1.880 |
| Literales | 614 |
| Sistema transversal (fuera del ratio) | 234 |
| Sin ninguna entrada en el contrato | 62 |
| Alcance < 20 % | 59 |
| Alcance = 100 % | 6 |
Con eje data-size en la receta |
82 |
1.2 Por familia (propuesta de familias en D-TH.4 — el autor la firma o la cambia)
| Familia | Comp. | Knobs | Alcance | Sin contrato | Fuera del contrato |
|---|---|---|---|---|---|
| Tiempo (chronos · fecha/hora) | 15 | 879 | 9 % | 9 | 774 |
| Campos | 24 | 905 | 38 % | 9 | 526 |
| Controles · marcas | 33 | 867 | 39 % | 9 | 502 |
| Menús · listas · navegación | 24 | 735 | 37 % | 10 | 432 |
| Superficies · overlays · estado | 34 | 807 | 45 % | 10 | 429 |
WIP (palabras) |
1 | 471 | 22 % | 1 | 363 |
| Texto · tipografía | 12 | 238 | 9 % | 10 | 217 |
| Media · chat | 9 | 283 | 61 % | 1 | 104 |
| Layout (primitivos) | 9 | 14 | 93 % | 3 | 1 |
(separator, sin familia asignada) |
1 | 6 | 67 % | 0 | 2 |
1.3 Los tres defectos que el censo NO ve y la ejecución sí tiene que mirar
El script es un regex sobre texto: sobre-reporta, nunca infra-reporta. Tres clases de defecto de theming que un alcance del 100 % no garantiza:
- Privado que no deriva de un público (
--_c-radius: var(--radius-default)): cuenta comoprivate; la corrección es que el privado lea el público o desaparezca. - Velo o acento en el nodo equivocado:
archetype: 'item'en un<li>envoltorio (navigation-menu,822b78cf2), o el shorthandbackgroundmatando la capa de estado (SidebarF3,navigation-menuae9e277fa). No es un knob: es un nodo. Se detecta midiendo desde el píxel hacia arriba (§7.3). - Doble animación al mover un sello a una superficie con animación propia
(
navigation-menu822b78cf2:present-rise+ la entrada de receta). Se detecta con un registro deanimationstart/end, no congetComputedStyle.
1.4 Tabla completa por componente
Al final del documento (§9), ordenada por alcance. Se REGENERA con el script en cada bloque; no se edita a mano.
2. Contrato objetivo — qué significa «totalmente personalizable» (los cuatro ejes)
Un componente es personalizable cuando un tema puede moverlo sin tocar el sistema ni la receta, en estos ejes:
| Eje | Mecanismo canónico | Cómo se comprueba |
|---|---|---|
| A · Tokens (forma, color, espacio, tipografía) | todo knob de apariencia lee --{c}-{slot} del contrato (recipes/base.ts), nombre RESUELTO por talla/estado; los privados sólo derivan de públicos |
censo al 100 % + prueba de centinela (§7.4) |
| B · Talla | size → data-size en el wrapper; tokens {part}-{eje}-{k} apuntando al bundle --size-{k}-* (theming §5; recipe-contract §1) |
computed por talla = bundle; md idéntico al default anterior |
| C · Color / variante | data-color / data-variant vía paleta (--{c}-{role}-{slot}, --{c}-palette-*), los 9 roles (theming §4) |
cada variante lee tokens, ninguna un --scale-* (R-4.6) |
| D · Estados | hover/press/selected neutros = la capa del sistema en el nodo CON forma; acentos de estado (on-bg…) en background-color para que la capa componga |
background-image presente en hover, <li>/envoltorios sin velo, abierto + hover = acento + capa |
Regla de oro del eje: el default no cambia. Cada componente se mide antes y después en sus estados (reposo · hover · activo/abierto · disabled · foco) y tallas, y el diff de computed styles es cero salvo donde una decisión firmada diga lo contrario. Este eje mueve QUIÉN puede cambiar cada cosa, no QUÉ se ve.
3. Contrato objetivo — la regla R-5 «alcance de tema»
Nueva regla de component-audit (familia R-5), misma mecánica que R-4.x:
- R-5.1 — Toda declaración de apariencia (
KNOB_PROPS) en una receta lee (a) un públicovar(--{c}-…), (b) un privado--_{c}-*cuya definición en la misma receta lee un público, o (c) un token de sistema transversal (la listaSYSTEMdel censo). Otra cosa es fallo. - R-5.2 — Todo componente con receta tiene entrada en
recipes/base.ts. - R-5.3 — Los nombres de los tokens siguen recipe-contract §1 (ejes
lógicos,
{part}-{eje}-{k}) y theming §6 regla 7 (slots de color:bg, fg, border, on-bg, on-fg, on-border, hover-bg, on-hover-bg). Hoy no se cumple ni en recetas viejas (tabs:trigger-color-*) ni en las de hoy (navigation-menu:trigger-bg-active,trigger-color-active) — ver D-TH.6. - Válvula (recipe-contract §3):
R-5.1 exception: <razón>en el README del componente, greppable, UNA por knob o grupo de knobs con la razón (p. ej. «glifo ∝ diámetro, excepción canónica avatar/marker»). Sin razón escrita no hay excepción. - Severidad:
warndesde F0 con el suelo del censo;erroren F3 (D-TH.7 — firmada con enmienda: R-5.3 gradúa aerrordirecto tras el codemod, su deuda muere en el mismo pass; R-5.1/5.2 esperan F3).
4. Decisiones que firma el autor (una por mensaje, con sus cinco preguntas)
| Id | Decisión | Propuesta | Estado |
|---|---|---|---|
| D-TH.1 | ¿R-5 es regla DURA? («todo knob público salvo sistema transversal o excepción firmada») | Sí. Es lo que recipe-contract §1 ya dice sin guard. | FIRMADA 2026-08-20 tal cual. Ancla: la medición 2026-07-01 (canon sin guard deriva 30-85 %) y el mandato origen del eje. |
| D-TH.2 | Perímetro de «knob» | La lista KNOB_PROPS del script (apariencia; layout fuera). Cambios a la lista = cambio del guard, firmados aquí. |
FIRMADA 2026-08-20 con la opción (b) de la ficha heading: la familia tipográfica B5 mide su superficie por --style-* como sistema transversal (verdad estructural — la vertebración tipográfica RECHAZA acoplar componentes a la capa semántica; acuñar --heading-* = 36 alias de una capa ya pública, la clase que §39 mató). No se acuñan --{c}-* para los primitivos tipográficos. |
| D-TH.3 | Tracks WIP (palabras, words, chronos y su familia de fecha/hora) |
En el CENSO siempre; en R-5 error sólo cuando salgan de su carril (coherente con R-4.x, que los excluye). |
FIRMADA 2026-08-20 tal cual. |
| D-TH.4 | Familias y ORDEN del backfill | El de §5 F2: menús/navegación → campos → controles → superficies → texto → media/chat → tiempo (el último por ser el más grande y estar en carril propio). Dentro de cada familia, sin contrato primero, luego por knobs fuera del contrato. | FIRMADA 2026-08-20 con enmienda: la cola REVISADA del CONTINUE (fichas con veredicto §5 verificado) tiene prioridad sobre el orden de familias — trabajo revisado no se deja enfriar. |
| D-TH.5 | El default NO cambia en este eje | Sí. Toda mejora visual que aparezca se anota como deuda y se firma aparte (como hoy con navigation-menu). |
FIRMADA 2026-08-20 sin matices — es lo que hace verificable el eje (diff de computed = 0 como gate). Única excepción viva: la migración hover→capa de estado, firmada aparte el mismo día (ver «Firmas del 2026-08-20» del CONTINUE), que mueve píxel con captura y diff explicado. |
| D-TH.6 | Vocabulario de slots (R-5.3): ¿se NORMALIZAN los nombres que ya se desvían (trigger-color-* de tabs, *-bg-active/*-color-active del nav de hoy, …) con un codemod value-preserving como el de px/py del 2026-07-06? |
Sí, en F1, ANTES del backfill — si no, el backfill escribirá más nombres fuera de vocabulario. Inventario exacto de desviaciones sale en F0 (el censo añade --names). |
FIRMADA COMPLETA 2026-08-20, en dos actos. (1) El slot de tinta es fg; color como slot MUERE (196 claves cola). Razón: el principio de plataforma del 2026-07-06 gobierna los ejes DIMENSIONALES, no la pareja bg/fg (si gobernara, bg sería background-color); color colisiona con --color-*, data-color y los 9 roles; on-fg compone. (2) Modificador recipe-level DELANTE — regla: delante lo interactivo, detrás lo dimensional y contextual (hover-bg pero control-height-md, scrim-fg-over-dark); rol/paleta conserva su gramática propia (detrás, COLOR_ROLE_SLOTS — las 47 {rol}-{slot-de-rol} son canónicas). Modificador válido ∈ vocabulario universal (+current, aria) ∪ valores data-state/ejes del MORFO del componente (así partial de rating-group y read/failed de chat-message validan contra el compilado, igual que la parte). waveform.played/buffered = pseudo-partes eidos-only (played-fg). Los hovers neutros se EXCLUYEN del codemod: migran a la capa de estado (firma aparte, mismo día). Detalle operativo: CONTINUE §«Mañana». |
| D-TH.7 | Cuándo gradúa R-5 a error |
Cuando el censo global dé 100 % o excepción documentada (F3), nunca antes de terminar F2 — un error a medio backfill rompe el component:audit de todo el parque. |
FIRMADA 2026-08-20 con enmienda: R-5.3 (gramática de nombres) gradúa a error DIRECTO tras el codemod — su deuda muere en el mismo pass (precedente R-4.4, «sin allowlist»). R-5.1/R-5.2 esperan F3 como propone la fila. |
| D-TH.8 | ¿Entra la exposición en la demo de temas (/temas: un panel que liste los tokens públicos por componente y permita moverlos)? |
Sí pero DESPUÉS (F4, opcional): es la prueba viva de A; sin el backfill no hay nada que exponer. | FIRMADA 2026-08-20 tal cual — el instrumental existe (listRecipes() / getRecipeTokens(); la ruta /temas existe). |
5. Fases y gates
Cada fase: qué leer ANTES (entero), qué producir, guard. Ninguna arranca sin la anterior en verde. Todo bloque de F2 ejecuta el protocolo de §7 por componente, sin atajos: es la parte del plan que existe porque «Opus falla mucho».
F0 — Instrumento + guard en warn (una sesión)
- Leer: theming §1bis, §3, §5, §6, §7, §12, §16 · tsc.md entero ·
recipe-contract §1–§5 ·
scripts/component-audit.ts(cómo se declara una regla R-x,readmeException, severidades) ·src/uix/eidos/recipe-css-contract.test.ts(qué ya guarda) ·PLAN-sidebar.md§3 y F3 · este plan entero. - Producir: (a)
scripts/theming-census.tsendurecido:--names(inventario de nombres de token fuera del vocabulario §1/§6.7), detección «privado que deriva de público» (leer--_c-x: var(--c-y)en la misma receta y reclasificar), salida--jsonestable; (b) R-5.1/5.2/5.3 encomponent-auditcon severidadwarny la válvulaR-5.x exception:; (c)docs/theming/reference.md§12 (tabla de tooling) gana la fila del censo; (d) HECHO 2026-08-22 —src/uix/eidos/theming-reach-floor.test.ts, que fija el suelo: alcance global ≥ el de hoy (33 %) y literales ≤ 614 — el número SUBE o el test falla (muta-prueba: meter un literal en una receta y ver el rojo antes de dar el test por bueno — memoriaa-guard-that-inspects-nothing-passes. Ya pasó una vez HOY: la primera versión del censo no contaba una regla de una sola línea, y la mutaciónpadding-inline: 8pxno movió la cifra; se endureció el regex y la mutación pasó a 6→7→8). - Guard:
node --import tsx/esm scripts/theming-census.tsreproduce §1.1 a la cifra ·npm run component:auditNO añade ningúnerror(sólowarn) ·npx vitest run src/uix/eidossin nuevos rojos (el rojo conocido esskin-media-player, ajeno) ·npm run checkcon cero errores en los ficheros tocados (§7.6).
F1 — Doctrina + vocabulario (una sesión)
- Leer: F0 + theming §6 (reglas estrictas) + el codemod del 2026-07-06 (recipe-contract §1, bloque «Normalización ejecutada») como molde.
- Producir: recipe-contract §1 gana la regla R-5 (y §2 una fila «Alcance de
tema»), §4 la tabla de enforcement, §5 el checklist (punto 12: «censo del
componente al 100 % o excepción»); theming §6 referencia cruzada; el
checklist de cierre (
docs/guides/completion-checklist.md) y elCOMPONENT_AUDIT_GUIDEendurecen las dimensiones 5 y 10 («usa tokens» ≠ «es temable»: la ficha exige el % del censo). D-TH.6: codemod value-preserving de los nombres fuera de vocabulario (lista de F0), congenerated/base.cssregenerado y diff = renombres 1:1, computed idéntico en navegador (mismo triple muro que px/py). - Guard:
docs:check0 · el diff degenerated/base.cssson SOLO renombres · censo idéntico antes/después del codemod (un rename no cambia el alcance) · sonda de computed en 3 componentes renombrados = idéntico. - Repaso de lo ya ejecutado (2026-08-20): firmar una gramática obliga a
releer lo corregido ANTES de ella. Auditados los 7 de §8 contra
fg+ familias (scripts/__names-audit7.ts): 6 limpios, y una sola corrección —gradient-builder.checker-color→checker-fg(slot, no sustantivo; 4 consumos engradient-builder.css). Las 4 clavesstop-color-*del mismo componente son falso amigo verificado (stop-colores la PARTE) y NO se tocan. La corrección entra DENTRO del codemod. Detalle y tabla:CONTINUE-theming.md§«Primera posición».
F2 — Backfill por familias (6–8 bloques de sesión; un componente = un commit)
Orden propuesto (D-TH.4). Dentro de cada bloque: sin contrato primero, luego por knobs fuera del contrato. Cada componente sigue §7 entero.
| Bloque | Familia | Comp. | Knobs fuera | Entran primero (sin contrato) |
|---|---|---|---|---|
| B1 | Menús · listas · navegación | 24 | 432 | command, listbox, table, tree-grid, tree-view, grid-list, virtual-list, virtual-grid, menu-dial, feed — y navigation-menu (44 %) hasta el 100 % |
| B2 | Campos | 24 | 526 | combobox (1), textarea, css-field, mask-field, number-field, field-langs, gradient-builder, gradient-picker, label |
| B3 | Controles · marcas | 33 | 502 | knob, avatar, kbd, link, mark, highlight, clipboard, proof-of-human, aspect-ratio |
| B4 | Superficies · overlays · estado | 34 | 429 | alert-dialog, announce, carousel, link-preview, skeleton, spinner, scroll-frames, motion, mockup, cascade, card-group |
| B5 | Texto · tipografía | 12 | 217 | heading, text, s-text, display, code, code-block, text-* (los que no tienen contrato) |
| B6 | Media · chat | 9 | 104 | skin-media-player |
| B7 | Tiempo (chronos · fecha/hora) — si D-TH.3 lo mete | 15 | 774 | range-calendar, month-grid, year-grid, date-picker, date-range-picker, time-picker, time-range-picker, natural-time-picker, picker-shell |
| B8 | palabras — si D-TH.3 lo mete |
1 | 363 | — |
Por componente se produce: entrada (o ampliación) en recipes/base.ts con los
nombres de §1/§6.7 — dimensionales por talla si el componente tiene size
(patrón Sidebar: {part}-{eje}-{k} + nombre resuelto con declarations por
scope: 'size:{k}'), colores por rol/slot, acentos de estado; la receta
consume SOLO nombres resueltos (nunca un primitivo crudo, nunca un literal);
privados sólo si derivan de públicos; generated/base.css regenerado por el
script (jamás a mano, theming §16 F); README de eidos con la tabla de
tokens («Talla y tema», molde: navigation-menu); registro en §8.
- Guard por componente: §7 entero, y el censo
--only {c}al 100 % (oR-5.x exception:con razón) — si no llega, el commit NO se hace. - Guard por bloque: revisión adversarial (§7.7) antes de dar el bloque por cerrado: un pase escéptico por componente que intente REFUTAR «el default es idéntico» y «cada token alcanza» con medición propia, no con la del autor del commit.
F3 — R-5 a error + cierre (una sesión)
- Producir: severidad
erroren R-5.1/5.2/5.3 (D-TH.7); el test del suelo pasa a exigir 100 % global (o excepciones listadas); theming §12 y recipe-contract §4 lo reflejan;CONTINUE-theming.mdcerrado. - Guard:
component:auditPASS en los 162 · censo 100 % ·docs:check0.
F4 — Exposición en la demo de temas (opcional, D-TH.8)
- Producir: en
/temas(o en cada demo) un panel que lista los públicos del componente desderecipes/base.tsy los mueve en vivo — la prueba viva del eje A, y el detector de tokens que no alcanzan (mover y que nada cambie). - Guard: mover cada token del componente en la demo y ver cambiar el computed (automatizable con el centinela de §7.4).
6. Deuda transversal que este plan destapa — NO se ejecuta aquí
| Id | Dónde | Qué |
|---|---|---|
| T-TH.1 | component-audit dims 5 y 10 |
Dan ✓ a «usa tokens»; el criterio se endurece en F1. Las fichas ya escritas (docs/audit/components/*.md) quedan con el ✓ viejo: se corrigen al pasar cada componente por F2, no en masa. |
| T-TH.2 | Vocabulario de slots (theming §6.7) | Existe y no se guarda: tabs (trigger-color-*), navigation-menu (-bg-active, -color-active) y más lo incumplen. D-TH.6. |
| T-TH.3 | menubar |
Misma clase que el nav: cromo de barra en privados («the bar itself styles via foundation privates», recipes/base.ts) + commit-select en el trigger al DESPLEGAR (otra sesión, sema). |
| T-TH.4 | archetype: 'item' en envoltorios |
Hay que censar qué otras partes <li>/wrapper lo declaran (memoria archetype-item-pulls-interactive-styling: Timeline, Breadcrumb, NavigationMenu ya corregidos). Un guard de morfo («un item no envuelve a un trigger») es candidato. |
| T-TH.5 | --control-height-* en :root (T-6 del sidebar) |
La densidad/zoom por SUBÁRBOL no re-deriva; afecta a la promesa de theming «por ámbito». Eje de theming aparte. |
| T-TH.6 | 25 knobs visuales fuera del morfo (component-visual-attrs, eje Affix) |
Filas sin firmar image/skeleton/qr-code/s-text. El eje C (variantes) depende de ellas. |
7. PROTOCOLO DE VERIFICACIÓN — por componente, sin excepciones
Existe porque el que ejecuta falla, y porque en un solo día (2026-08-19,
navigation-menu) cuatro de estos pasos ausentes costaron cuatro commits de
corrección: se dio por arreglado un hover leyendo el nodo equivocado; se
resolvió un doble de animación en la dirección contraria a la doctrina; se
inventó un hover por componente; y se declaró «idéntico» sin captura. Cada paso
tiene un artefacto (número, captura, salida de comando) que va al mensaje
de commit. Sin artefacto, el paso no se ha hecho.
7.1 Antes de tocar el componente (las cinco preguntas + lectura)
- Las cinco preguntas del autor, UN componente por mensaje cuando haya decisión (nombres fuera de vocabulario, una excepción, un default que parece defecto): qué soluciona · leído todo o presupuesto · qué afecta · qué doctrina · qué modificaciones. Si no hay decisión nueva (el componente sólo necesita tokens con nombres canónicos), se ejecuta sin preguntar y se reporta.
- Leer ENTEROS: la receta del componente, su entrada en
recipes/base.ts, su README de eidos y de soma, su morfo (¿qué partes llevan arquetipo?), su ficha endocs/audit/components/. Y la doctrina de §0 (fuentes) si la sesión no la ha leído hoy. git status+git log -1: ¿hay otra sesión con el árbol sucio? Nuncagit stashpara medir una base (le arranca el trabajo a otro).
7.2 Medir ANTES (el suelo del «idéntico»)
node --import tsx/esm scripts/theming-census.ts --only {c}→ guardar la línea.- Sonda Playwright headless desde la raíz del repo (la pantalla oculta
congela rAF;
playwrightno resuelve desde el scratchpad) contra la demo del componente: para cada parte visible y cada talla, computed de los knobs (backgroundColor,backgroundImage,color,borderRadius,padding*,fontSize,lineHeight,blockSize/inlineSize,boxShadow,borderColor) en reposo · hover · activo/abierto · disabled ·:focus-visible. Muestrear FUERA de callbacks deMutationObserver(miden el instante anterior al flush). Guardar JSON. - Captura 2× de la demo en reposo y en hover (sirve de «antes» para la comparación a ojo).
6.bis — CUENTA LOS NODOS ANTES DE CREER NADA. La sonda imprime cuántos mide;
el guard, cuántos tokens mueven. Un recuento de 0–2 nodos, o un 0/N del guard, NO
es un resultado: es el instrumento ciego. Las siete causas medidas hasta el
2026-08-23, con el interruptor que las arregla (todos en COMPONENT_OVERRIDES
del guard y en EXTRA_NODES/DEMO_VARIANTS de la sonda):
| síntoma | causa | interruptor |
|---|---|---|
| 0 nodos, ruta 404 | el componente no tiene demo (picker-shell, mockup, surface, audio-player) | urls: ['/ruta/donde/sí/vive'] |
| 0–2 nodos con la página llena | sus partes no llevan data-{c}-*: hooks de clase (onion-menu, prose) o partes de OTRO chasis (audio-player) |
extraNodes / EXTRA_NODES |
| la superficie no está en el DOM | abre por hover, no por clic (tooltip, link-preview) | openBy: 'hover' |
| la superficie se CIERRA sola | nace abierta y el guard la pulsa (onion-menu) | openMarker |
| media docena de tokens muertos por variante | el panel/skin sólo existe tras un chip de la demo | openWith + DEMO_VARIANTS |
| todos los tonos muertos | la paleta resuelve por data-color o data-intent, y por VARIANTE |
barrido de tono (automático) + sweepAttr |
TimeoutError antes de medir |
la página nunca alcanza networkidle (image reintenta un src roto) |
caída a load (automática) |
Y tres lecturas que mienten aunque el nodo esté bien: una propiedad EN
TRANSICIÓN devuelve el valor viejo (congela antes de leer, salvo que el token SEA
la transición); un nodo ANIMADO devuelve el valor de la animación (congela
también animation, a mano); y ::placeholder sobre un input sin placeholder
devuelve el estilo del ELEMENTO.
7.3 Editar (la forma firmada — nada más)
- Tokens con los nombres de recipe-contract §1 / theming §6.7. Por talla si
hay
size. Acentos de estado enbackground-color. Hover/press/selected neutros = la capa del sistema (nuncabackground:a mano, nuncabackground-image: nonepara «limpiar», nunca una escalera de color propia). Privados sólo derivando de públicos. Literales: cero. npm run generate:eidos-cssygit diff --stat src/uix/eidos/generated/: el diff son SOLO los tokens del componente. Si toca otra cosa, parar.- Si un envoltorio lleva
archetype: 'item'/'option'/'trigger'sin ser el interactivo, es una DECISIÓN (morfo): se presenta, no se toca de oficio.
7.4 Medir DESPUÉS (los tres artefactos)
- Idéntico: repetir la sonda de 7.2 → diff de computed por parte/estado/talla = vacío. Un solo valor distinto = parar y explicar (o es defecto previo que se firma, o es error del commit).
- Alcanza: la prueba de centinela, que desde 2026-08-21 es el guard
R-5.4 (
npm run theming:sentinel -- {c} <url>, doctrina en recipe-contract §4) — por cada token público, un valor imposible de confundir (1234px,rgb(1, 2, 3),0.123) y algún computed tiene que seguirlo. Si un token no mueve nada, es un token que miente (fantasma, nombre equivocado, o una cascada que jamás gana) — o su silencio tiene una razón MEDIDA escrita en el ledger (scripts/theming-sentinel-exceptions.ts): el guard falla con un muerto sin adjudicar y avisa de excepciones STALE. - Desde el píxel hacia arriba en los estados de hover:
elementsFromPointen el centro del control y la pila de ancestros conbackgroundImage/backgroundColor— el velo cae en el nodo CON forma y en ningún envoltorio (memoriameasure-the-node-the-user-points-at). Si hay animación propia y un sello de sema en el mismo nodo, registro deanimationstart/end(nogetAnimationsen un solo instante): UNA entrada por ocurrencia (memoria motion.md §"when both writeanimation"). - Captura 2× después, al lado de la de antes. Mirarla.
7.5 Guards mecánicos (todos, cada componente)
node --import tsx/esm scripts/theming-census.ts --only {c}→ 100 % o excepción escrita. Y el global NO baja.node --import tsx/esm scripts/component-audit.ts --only {c}→ PASS, sin R-5 nuevos (enwarndurante F2, pero se listan y se resuelven).node --import tsx/esm scripts/eidos-lint.ts {c}→ 0 invalid.npx vitest run src/uix/eidos→ sin rojos nuevos (comparar por fichero de test, no por cifra: el rojo conocido esskin-media-player).npm run rtl:check0 ·npm run docs:check0 ·npx prettier --checken los ficheros tocados (ojo:autocrlf=truehace que prettier se queje del CRLF del checkout — comprobar el contenido normalizado a LF, no el fichero; git guarda LF).npm run check: atribuir errores por fichero (grep ERROR | grep {c}), nunca por cifra global; la rama tiene sesiones concurrentes y el total se mueve solo. Si el log no llega aCOMPLETED, estmp/lexical/: relanzar.
7.6 Commit (uno por componente)
git addcon rutas EXPLÍCITAS (sólo lo del componente +recipes/base.tsgenerated/base.css+ su README + este plan §8);git diff --cached --statygit show :rutapara verificar el ÁRBOL INDEXADO, no el de trabajo;git statuspara ver que no entra nada de otra sesión. Mensaje congit commit -F fichero(backticks en-mse ejecutan en bash), en castellano, con: qué knobs entran, la cifra del censo antes → después, el diff de computed (vacío), el centinela (n tokens probados), los guards. Nunca--amenden la rama compartida.
- Registro en §8 de este plan (componente · commit · censo antes→después ·
excepciones) y, si el bloque cierra, en
CONTINUE-theming.md.
7.7 Revisión adversarial por bloque
- Al cerrar un bloque, una pasada escéptica (otra sesión o un pase separado)
que por componente intente REFUTAR con medición propia: «el default es
idéntico» (sonda 7.2 vs 7.4 rehecha, no leída del commit), «cada token
alcanza» (centinela rehecho), «el velo cae donde debe» (píxel arriba),
«no hay doble animación». Hallazgos reales se arreglan en el bloque; los
refutados se anotan. El molde es la revisión del
Sidebar(21 hallazgos · 17 refutados · 4 reales,bae03e55c).
7.8 Lo que NO se hace en este eje (y se anota como deuda si aparece)
- Rediseñar un default (radio, color, altura…): deuda firmable, no cambio.
- Tocar sema/morfo salvo un arquetipo en un envoltorio (decisión aparte).
- Cascadear a otro componente «ya que estamos» (memoria
no-cascade-changes). - Inventar nombres de token fuera de §1/§6.7, o un hover/estado por componente.
- Editar
generated/base.cssa mano. - Dar un paso por hecho sin su artefacto.
8. Registro
-
2026-08-23 —
navigation-menu44 % → 100 % (85988785d), bloque B1. Contrato 26 → 44 claves: 19 nuevas y UNA retirada. Diff 0 sobre 2.752 valores en 8 estados; R-5.4 43/44 con una adjudicación.Los nombres los dio el catálogo: los gemelos cerrados el mismo día (
dropdown-menu,context-menu) paracontent-{min-width,padding,radius,fg}ychevron-{size,stroke};accordionparatrigger-font-familyydisabled-trigger-fg. Las CUATRO recetas que declaran un chevron lo dimensionan con un literal — un glifo no es un paso de la escala de espacio —, y al revés el subrayado: su2pxES--border-width-medium.La §4 generada falla de CINCO maneras, una nueva: llamaba
trigger-width/trigger-heightal CHEVRON (colisionando con la altura del control, que ya existe), fundía dos nodos encontent-radius, cruzabacontent-padding-*(era de la FILA) y llamabacontent-widtha unmin-inline-size— y abría exigiendo consumir la capamenu-indicator, que es homonimia: esa capa es el check de los CheckboxItem, no el subrayado de esta barra.Las filas del panel no son
item-nilink-: aquíitemes el<li>de la barra y elLinkde barra viste el cromo del trigger, así que esos nombres prometerían un nodo que no alcanzan.content-link-*nombra el nodo por donde vive. El privado era una ESCALA (tres fuentes por talla), y sube al TSC.indicator-xera declaración muerta — soma escribe el rect inline y la receta lee sólo-w/-h; retirada, 0 diffs.El instrumento, dos cegueras y una trampa (§13): sonda y centinela no veían el panel ni sus filas (los
<a>desnudos del consumidor: 10 nodos y ninguno era el panel — 9 de 19 knobs fuera del diff); el guard cerraba el panel que medía (abre porpointerenter, y el aparcado del puntero en (0,0) dispara el cierre) dando falso negativo Y falso positivo a la vez; ycolorestá EN TRANSICIÓN en esta parte, así que forzardata-disabledy leer en el acto devuelve el valor viejo — la trampa del cuentagotas, en otro componente. -
2026-08-23 —
audio-player37 % → 56 % (3 claves) y el instrumento medía CERO nodos. El 44 % restante es préstamo con dueño (ocho filas--media-player-*): es la piel de audio de ese chasis y se tema en su ficha.Acuñado lo único que añade sobre el chasis: el peso del título y la insignia LIVE (peso + tracking); los dos
600pasan avar(--font-weight-semibold).Tres cegueras encadenadas:
/uix/components/audio-playeres un 404 —el CUARTO canónico sin ruta—; sus partes sondata-media-player-*, nodata-audio-player-*(conextraNodes, la sonda pasa de 0 a 48 nodos); y sólo existe tras el chipmedia: audiode la demo del chasis (sonda y guard lo pulsan ahora, y el guard barre las cuatro variantes). Con eso, 0/8 → 6/8. -
2026-08-23 — COLA PEQUEÑA: seis componentes, cero claves nuevas.
section(— · cuatro claves RESUCITADAS),sticky0 → 100 %,button-group40 → 100 %,qr-code43 → 100 %,toggle-group33 → 50 % (su techo) ysplit-buttonADJUDICADO en 50 % (su techo). Global 65 %; 25 componentes al 100 % y los de alcance <20 % bajan de 14 a 12.El hallazgo está en
section: la receta TAPABA sus propias claves públicas. Declaraba los cuatro pasos de relleno en el host ([data-box][data-section] { --section-padding-block-sm: … }), y esa declaración gana a la que el contrato emite en:root: un tema que escribiera--section-padding-block-lgperdía contra la receta. Borrado el bloque —mismos valores, una sola fuente—, computado idéntico (48px antes y después), y las cuatro claves alcanzan.Lo demás es identidad: once
100 %entre las seis recetas y el centinela de 2px del sticky —el hilo invisible que el observador vigila—, todos con su razón escrita. Más un respaldo muerto retirado entoggle-group, sobre un token PRESTADO detoggle(el velo de un grupo deshabilitado es el del toggle, y se tema en su ficha).Y una clase de adjudicación nueva, que se repetirá: UN PASO POR INSTANCIA.
sectionyqr-codemapean su prop de talla avar(--{c}-{eje}-{k})y la escriben INLINE, así que sólo el paso ACTIVO alcanza; los otros cuatro leen muertos hasta que la prop cambia. No es deuda ni ceguera del instrumento: es cómo funciona una escala resuelta por prop.Gates: seis guards en verde · censo · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0.
-
2026-08-23 —
tooltip52 % → 75 % (3 claves, 4 literales anotados) y el planooverlayANULA SUS TRES VARIANTES. Global 65 %.Acuñados el desenfoque del velo
ghosty las dos tintas de la flechaoutline. No se acuñóghost-bg: lo intenté, el centinela lo delató y se retiró antes de commitear.⚠⚠ El plano no sólo se queda la tipografía: se queda el fondo, el borde y la sombra. Medido:
--tooltip-bg/-border/-shadowno mueven nada,--depth-overlay-*repinta. Y la consecuencia visual es peor que la contable:solid,outlineyghostcomputan lo MISMO —outlinees indistinguible desolid. → §13. Las cinco claves quedan adjudicadas, no retiradas: son la fuente de la máquina de variantes.Instrumento: el tooltip abre por HOVER (
openBy: 'hover', como link-preview) — 0/24 → 14/24—, y el resto se midió con el interruptoropende la demo, porque un panel abierto por puntero exige el ratón quieto toda la pasada. -
2026-08-23 —
time-range-field29 % → 100 % (4 claves), gemelo exacto dedate-range-fielddefecto incluido: la misma claverow-gapalimentando elcolumn-gap. Global 64 % → 65 %.Que los dos gemelos tuvieran el MISMO nombre equivocado dice algo: el error no se coló al escribir, se copió al duplicar. Donde hay un par, el defecto viene en par — mirar al gemelo es parte de la pasada.
-
2026-08-23 —
date-range-field29 % → 100 % (4 claves, una RENOMBRADA porque mentía). Centinela 7/7.row-gapalimentaba elcolumn-gap: la clave pública movía el hueco entre los dos campos, y el de fila —etiqueta ↔ campos— leía--space-1-5a pelo. Dos claves ahora, cada una con el nombre de lo que alimenta, y ningún computado se mueve. Un nombre equivocado es una perilla que gira otra cosa.La etiqueta se acuña con fecha de caducidad: la raíz del rango NO es un
[data-field]—lo dice la propia receta— así que no puede heredar la etiqueta de field.css y repetía los valores de la fundación. Nombrados aquí, y escrito en el contrato que el mandato §5.3-3 los borra cuando la raíz sea un campo. -
2026-08-23 —
surfaceADJUDICADO: el 25 % es su techo, cero claves nuevas. Es la cara de PINTURA de Box y lo que pinta no es suyo:bgyfgsalen del puente de paleta (THM-2) y el acabado es canal de valor del generador (§39). La ramainheritdelfgsuave es intencionada y está escrita en la receta.Pero no tiene ruta:
/uix/components/surfacees un 404 y el guard medía una página VACÍA — 0/25, incluido unradiusvivísimo. Apuntado a/temas/gradientes+/blocks/cta: 1/25, y el que mueve es el radio. Ya son TRES los canónicos sin demo (picker-shell, mockup, surface) → §13.Sus 24 claves de tono son la supersesión de paleta de hoy: patrón compartido.
-
2026-08-23 —
banner30 % → 100 % (11 claves) y el guard pasa de 4/42 a 53/53: sus 38 «muertos» estaban vivos, sólo que nadie los había mirado con el atributo puesto. Global 64 %.Cosida la densidad por talla, la interlínea y el trazo del anillo de
outline—la última fila que impedía al privado del borde derivar—. Dos ausencias firmadas: lostransparentdeoutline/ghosty losborder-width: 0, con el criterio de button.Dos cegueras del instrumento, arregladas: (1) su paleta resuelve por
data-intent, no pordata-color, y el barrido de tono estampaba sólo el segundo — ahora estampa los dos nombres; (2) y luego por VARIANTE, así que el guard recorredata-variantconsweepAttr. Es la diferencia entre «38 tokens que mienten» y «38 que nadie había mirado con el atributo puesto».Gates: sonda 0 diffs en 192 valores × 7 estados · centinela 53/53 · censo 100 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0 · captura de cuatro variantes × cuatro intenciones.
-
2026-08-23 —
anchor-nav20 % → 100 % (11 claves) y el censo aprende los bordes POR LADO. Global 64 %.Tenía dos knobs y todo lo demás a pelo: la escala (que ahora lee el bundle), el relleno y el radio del enlace, sus tres tintas, el peso del activo y las dos tintas del RAÍL, que es lo que da nombre al componente.
El raíl activo era INVISIBLE para la medida: su color vive en un
border-inline-start-coloryKNOB_PROPSsólo conocíaborder-colory los shorthands. El centinela mira esos longhands desde el 2026-08-22 (los añadió cuando prose y nav-tree leyeron muertos); el censo no. Añadidos los ocho por lado, color y grosor: +30 filas en el catálogo (5.101 → 5.131) y esta ficha baja a 18 % antes de coserse — el censo promete sobre-reportar, NUNCA infra-reportar.La tinta de reposo del raíl estaba escondida de otra manera: dentro de un shorthand que el censo clasifica por el PRIMER token que casa (el trazo, ya público). No hizo falta partirlo: basta nombrar el color dentro.
Un susto útil: una coma que faltaba en el contrato rompió el build de tokens y lo delató la SONDA midiendo 0 nodos — la página no renderizaba. El recuento de nodos es el canario.
Gates: sonda 0 diffs en 1.760 valores × 7 estados · centinela 11/12 · censo 100 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0.
-
2026-08-23 —
image60 % → 96 % (1 clave, 12 literales anotados) y dos instrumentos que morían en esta página. Global 64 %.Su deuda era casi toda IDENTIDAD: once
100 %(la imagen, el fallback, el error y sus dos<img>llenan su caja) y unopacity: 1(una imagen cargada es opaca). Lo acuñado es la barra del esqueleto, que leía--gradient-shimmera pelo.La página NO alcanza
networkidleNUNCA —monta unsrcroto a propósito para su estado de error— y sonda y guard morían conTimeoutErrorantes de medir un nodo. Las dos caen ahora al eventoloadsi la espera se agota.Un token bajo
@media (prefers-reduced-motion: reduce)lee muerto:placeholder-basesólo existe ahí. Emulando la preferencia, alcanza — y vale para cualquier token detrás de una media query de preferencia.Lectura fantasma cazada por repetición: el primer diff acusó
opacity: 0.925793 → 1en la imagen cargada; era el fade EN VUELO, como el rim animado deonion-menu. Repetida la medida, 0 diffs.Gates: sonda 0 diffs en 544 valores × 7 estados (repetida) · centinela 20/23 · censo 96 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0.
-
2026-08-23 —
checkbox59 % → 72 % (3 claves, 3 literales anotados) y un HUÉRFANO cableado. El 28 % restante es el puente de paleta (8 filas, THM-2).indicator-fgera un huérfano que el test de huérfanos no puede ver: la clave estaba en el contrato, pero la receta pintaba la tinta de la casilla marcada leyendo--color-content-on-solidDIRECTAMENTE, sin nombrarla — y el test busca el NOMBRE en los ficheros del componente. Cableada al privado de paleta (computado idéntico), el propio guard lo confirmó marcando su adjudicación como STALE: ahora mueve. Misma clase que el--popover-bgque vivía de un COMENTARIO, al revés.Acuñado el estado INVALID: el borde y el doble anillo de foco (hueco + anillo), que era una sombra con dos colores cableados; la geometría 2px/4px se queda dentro de la declaración, que es la forma del anillo.
Dos trampas de ALCANCE del instrumento, anotadas: el glifo sólo existe dentro de una casilla MARCADA (medir «el primer indicador del documento» mide otro nodo) y la etiqueta de grupo lleva su PROPIO
[data-disabled], no lo hereda.Gates: sonda 0 diffs en 2.688 valores × 7 estados · centinela 22/47 con todo adjudicado · censo 72 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0 · captura de cinco estados.
-
2026-08-23 —
dropdown-menu57 % → 96 % (9 claves, 18 respaldos muertos retirados) y la tipografía del gemelo, RETIRADA:context-menu90 % → 87 %, a la baja y a propósito. Global 64 %.Cosidos la tinta del panel y de la fila, su interlínea, el encabezado entero y el galón del submenú (trazo + caja). El filo del separador deja de ser un
1pxsuelto y pasa a--border-width. Las dos limpiezas del gemelo se repiten aquí:font-familyera respaldo de SÍ MISMO y el peso del encabezado llevaba un500muerto.Los 18 respaldos: cada
var(--dropdown-menu-x, …)llevaba detrás un valor que no puede ocurrir —las claves están en el contrato— y sólo servía para envejecer contra él; dos ya discrepaban en la FUENTE.⚠
content-font-familyno se acuña, y la decontext-menuse RETIRA. El panel llevadata-depth='overlay'y el plano gana (quinta prueba de §12.9). Tenerla acuñada con una adjudicación escrita —como quedó ayer en el gemelo— era media doctrina: un público que no alcanza es un token que miente (R-5.4). Las dos recetas vuelven a la fuente literal con la razón encima.comboboxtiene la misma clave sobre el mismo plano: medido, registrado en §13, no tocado aquí.Gates: sonda 0 diffs en 928 valores × 8 estados · centinela 27/28 · censo 96 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0 · captura del panel.
-
2026-08-23 —
empty-state29 % → 100 % (20 claves, 6 → 26) y el centinela 26/26 sin una sola adjudicación. Global 64 %.Su deuda era de una clase: la escala de talla vivía entera en privados que leían el bundle a pelo. Cada paso tiene ya su público (relleno, título, cuerpo y glifo en
sm/md/lg) y los privados los derivan; con eso el resto —peso, interlínea y tinta del título, interlínea y tinta de la descripción— sale solo. La caja del glifo se sigue derivando (2×) de su tamaño, ahora público.Siete respaldos muertos retirados, dos de ellos MENTIROSOS: el
, 1.4de--font-line-height-sm(vale 1.45) y el, 1.5de--font-line-height-md. Mismo defecto quecallouthoy: un respaldo escrito a mano envejece contra el token.Gates: sonda 0 diffs en 1.056 valores × 7 estados · centinela 26/26 · censo 100 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0 · captura de las tres tallas.
-
2026-08-23 —
callout27 % → 79 % (7 claves, un literal anotado). Global 63 % → 64 %. El 21 % restante es el PUENTE DE PALETA (THM-2), que no es deuda.Cosidos el hueco de fila, la tipografía del cuerpo, la tinta, el tamaño del icono y el peso del título, todos leyendo el BUNDLE. La línea base óptica del icono deja de repetir las métricas del sistema: la misma derivación, ahora sobre los tokens del propio callout, así que un tema que agrande la copia mueve la caja del glifo con ella.
Cinco respaldos muertos retirados (
var(--callout-gap, var(--space-3))y compañía: las claves están en el contrato) incluido el, 1.5de--font-line-height-md, que además mentía — el token existe y vale 1.45.Los 24 rojos del guard son los TONOS: la supersesión que
buttondestapó el mismo día, adjudicada con el patrón compartido.Gates: sonda 0 diffs en 896 valores × 7 estados · centinela 10/34 · censo 79 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0 · captura de cuatro tonos.
-
2026-08-23 —
button55 % → 91 % (1 clave, 17 declaraciones anotadas) y el hallazgo más gordo del eje: la cascada de paleta ANULA los tonos del componente — 419 claves en el catálogo. Global 63 %.Acuñado lo único que faltaba: el paso
fullde la escala de radio ([data-rounded='full']leía el primitivo global a pelo). Anotadas 7 identidades (fit-content× 2, el100 %de[data-block], los cuatro1pxde las cajas sr-only) y 10 ausencias: lostransparentdesoft,outline,ghostyplain— la variante ES la ausencia de cromo, y diez claves detransparenthabrían sido el antipatrón que la doctrina avisa.Para que la ausencia cuente, el censo aprende la válvula de recipe-contract §3 un piso más abajo: un PRIVADO cuyo valor es un literal CON su razón escrita es una ausencia firmada, no deuda (
derivesFromPublicla acepta). Sin eso, cuatro privados marcaban «no deriva» y seis knobs leían inalcanzables mientras todas las demás ramas del mismo privado leen un público. El censo global sube 5 knobs por esto, no por retoque de ratio.⚠⚠ EL HALLAZGO. El último bloque del forward,
[data-button][data-color], resuelve--button-palette-*desde el--palette-*GLOBAL —que[data-color='{tono}']llena desde--color-{tono}-*— y gana a las reglas por tono por ORDEN, con la misma especificidad (0,2,0). Medido sobredata-color='risk':--button-risk-solidno mueve nada, ni en:rootni en el nodo;--palette-solidy--color-risk-soliden el nodo repintan. Las sieteprimary-*son el RESPALDO de esa regla y sólo actúan SINdata-color. 49 recetas emiten ese mismo forward y el catálogo tiene 419 claves de tono; medido igual enbadgeycallout. → §13, con el arreglo propuesto (orden de emisión) y su contrapartida (la jaula del color).El techo restante son dos filas de canal de valor (
--_button-fill-finish, el acabado que el generador deriva por instancia; su dial es del sistema).Un error de método que casi cuela: anclé la clave nueva en la primera línea
'radius-xl'del fichero y aterrizó enmeter. Lo delató el navegador (--button-radius-fullsin definir ⇒ radio 0). Una inserción se ancla en el BLOQUE del componente, nunca en una línea de clave.Instrumento: el guard aprende
sweepAttr(barrer una variante mientras mide) y a estampar el tono que la clave nombra; y el fichero de excepciones gana patrones (SENTINEL_PATTERN_EXCEPTIONS), para que una razón arquitectónica se escriba UNA vez y no 56.Gates: sonda 0 diffs (416 valores; la demo monta UN botón) · equivalencia del paso
fullcomprobada aparte · centinela 34/106 con el resto adjudicado · censo 91 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0 · captura de las seis variantes + píldora + tonorisk. -
2026-08-23 —
onion-menu29 % → 84 % (7 claves + 5 literales anotados), y una regla del recipe que el navegador DESCARTA. Global 63 %.Acuñados el color del anillo del sector —UNO para los dos estados: el propio CSS dice que el hover usa «el mismo color que el anillo de selección, más claro», y lo que los separa es la opacidad que ya tenía token—, la tipografía de la etiqueta, el radio y la tinta del disparador y las dos piezas del glifo
+→×. Dos limpiezas de paso: unvar(--style-label-font-family, var(--style-label-font-family))—respaldo de sí mismo, el defecto de context-menu— y dosvar(--radius-full, …)con respaldo imposible.⚠
.onion-menu-icon :global(svg)NO EXISTE::global()es un envoltorio de Svelte y esto es un CSS plano, así que el selector es inválido y la regla entera se descarta. Medido: el glifo computa 14px (el tamaño propio del Icon) y el70 %que el fichero cree pintar no pinta. Acuñéicon-glyph-size, el centinela lo delató y lo RETIRÉ: arreglar el selector mueve píxel. Mismo bug entimeline.css:331;image-picker.cssya documentaba la trampa. → §13.Tres cegueras del instrumento, dos nuevas y genéricas:
- El guard CERRABA la superficie. Este menú nace ABIERTO y el clic de
«abrir» lo cerraba — 12 de 20 tokens muertos. Ahora, si hay
openMarkery ya casa, no se pulsa nada (8 → 14 de golpe). - Sus tripas cuelgan de CLASES, no de
data-onion-*: sonda y guard las miden conextraNodes(37 nodos en reposo contra 5). - Congelar las transiciones no basta cuando el nodo está ANIMADO:
rim-glow-opacityleía 0,482956 —el valor animado— y parecía muerto; congelando también la animación computa 0,45 y sigue al token.
Los cuatro tokens del rim son del look
luminous, que la demo del componente no renderiza (prop de Svelte que emite otro marcado, no hay atributo que forzar): medidos en/active/docs/agnt.Gates: sonda 0 diffs en 7.328 valores × 8 estados · centinela 14/19 con las cinco adjudicadas · censo 84 % · audit PASS · suite con el rojo conocido ajeno · rtl 0 · docs 0 ·
checksin errores propios · capturas. - El guard CERRABA la superficie. Este menú nace ABIERTO y el clic de
«abrir» lo cerraba — 12 de 20 tokens muertos. Ahora, si hay
-
2026-08-23 —
field73 % → 98 % (8 claves + 8 literales ANOTADOS) y sus 18 rojos, medidos. Global 63 %. El 2 % que falta es el puente de paleta (THM-2), que no es deuda.Es el componente más COMPUESTO del sistema: lo que otras fichas llaman «préstamo con dueño» se cobra aquí, así que su techo pesa más que el de nadie.
Acuñados el disparador de control —el icono que abre el calendario, el reloj o la muestra, y revela la contraseña:
size,radius,fgy sus dos estados—, el indicadoroptional(gemelo delrequired, que ya tenía token) y el lateral de la etiqueta flotante, que es lo que CORTA el borde bajo el texto. La caja del disparador se mide enema propósito, así que el token guarda la RAZÓN (1.75em), no un píxel por talla.Ocho literales pasan a excepción firmada por IDENTIDAD, no por inflar el ratio: cuatro
inline-size: 100%, dosline-height: 1de un glifo suelto y dos1emdel icono dentro del disparador (el glifo ES el tamaño del texto).Los 20 rojos del guard estaban VIVOS, y tres enseñan algo:
disabled-opacityvive en el CONTROL y el guard leía la raíz;control-placeholder-fgno leía porque el input de la demo NO TIENEplaceholder—sin atributo no hay caja::placeholderygetComputedStyle(nd, '::placeholder')devuelve el estilo del ELEMENTO—; ysegment-heightes un token de FAMILIA que field posee y los pickers consumen, además de RESUELTO: desde:rootno se mueve por diseño (medido en/time-picker: desde el host 28px → 1234px, moviendo la coordenada--field-control-height-md28px → 992px).Instrumento: el disparador de control no lo monta NINGUNA demo de field, así que el guard mide ahora
fieldsobre DOS rutas (/field+/date-picker).Gates: sonda 0 diffs en 2.280 valores × 8 estados · equivalencia del disparador comprobada aparte · centinela 48/68 con las 20 adjudicadas · censo 98 % ·
--names0 · audit PASS · rtl 0 · docs 0 · suite eidos con el rojo conocido ajeno ·checksin errores propios · capturas de reposo, invalid, disabled, etiqueta flotante y disparador. -
2026-08-23 —
menubar15 % → 88 % (30 claves, 5 → 35). Global 62 % → 63 %. Las tres filas que quedan fuera NO son deuda de este eje.Cosidas la barra (superficie, marco, radio desacoplado de la talla, y las tres escalas
gap/padding/height), el disparador (tinta, tipografía, escala defont-sizey depadding-inline, el par de la entrada ABIERTA y la tinta deshabilitada) y el Panelrole=dialog(tinta + escala). Los pasos leen el BUNDLE (--size-{k}-control-height/--size-{k}-font-size), no el primitivo crudo que el CSS venía consumiendo, y elcalc(var(--space-1) * 0.5)del pasosmpasa avar(--space-0-5)(mismo computado).El hueco del panel deja de repetir el valor del padding: las tres reglas de
--floating-gapcompensaban el sangrado del disparador con una COPIA del padding de la barra; ahora leen--menubar-padding-{k}, su fuente. No pueden leer el privado: esas superficies viajan por PORTAL, y un privado de la raíz no cruza esa frontera (la ley de ayer, aplicada al derecho).⚠ El plano
overlayGANA a la receta — cuarta prueba de §12.9, y la primera con MECANISMO. Acuñépanel-font-familyypanel-line-height; el centinela las dio muertas. Medido:[data-depth='overlay']declara las dos con la MISMA especificidad (0,1,0) y más tarde en la cascada, así que gana, mientraspanel-fgypanel-font-size-*—del mismo bloque— sí alcanzan. Retiradas del contrato, devueltas a su fuente literal con la razón en el CSS. Mientras §12.9 no se firme, un token de tipografía en cualquier superficieoverlaymiente, y eso vale para los veinte componentes del empate.El hover no se acuña: es del eje navigation-menu.
background: var(--color-surface-overlay)sobre el disparador mata la capa del sistema —medido:background-imagecomputanoneen hover con--state-hovervivo—, por las dos razones quenavigation-menu.cssya documenta al haber retirado esa misma regla: el shorthand reseteabackground-image, y la regla del arquetipo va en:where()(especificidad CERO). Acuñarhover-trigger-bghabría fosilizado la invención. → §13.Instrumento: la barra suelta DOS superficies y el Panel —el que lleva sus knobs— cuelga de la entrada «Format», no de la primera; sonda (
OPEN_TRIGGER) y guard (openWith) aprenden a abrir la que toca. Y el guard necesitóopenMarker: su comprobación de «ya está abierto» busca[data-{c}-content], que aquí no existe, así que volvía a pulsar el disparador antes de cada token y CERRABA el panel.Gates: sonda 0 diffs en 1.470 valores × 8 estados · centinela 34/35 (la deshabilitada adjudicada) · censo 88 % ·
--names0 · audit PASS · rtl 0 · docs 0 · suite eidos con el rojo conocido ajeno ·checksin errores propios · capturas de barra, tallas, menú y panel. -
2026-08-23 — Los dos rojos que quedaban del bloque viejo, medidos:
metrics(18) ycolor-picker(25). Los dos guards en verde; sin cambios de código.metrics: los 18 están VIVOS, uno por uno. Ninguno miente — lo que faltaba era el escenario: seis piden el pasoxxl(la demo llega axl), dos el icono SINdata-color(el defecto que sólo pinta cuando no hay color, y todos los iconos de la demo llevan uno), dos las formascircle/square(la demo montarounded), cuatro la fila de acciones (no montada), uno el gráfico enend(la demo los colocafull), uno el borde de la varianteoutline, y dos el sello de sema durante el hold (data-event-family=signal+phase=active): el destello del valor se mide estampando el sello a mano, porque cuando el guard lee ya se ha ido.color-picker: 23 de 25 vivos, y los otros dos son un DEFECTO REAL — el ejesizemuere en el portal.--_color-picker-content-widthse declara TRES veces y no lo consume NADIE: la anchura del panel la fija--_popover-content-width-overridecableada al pasomd, así que un pickersmy unolgabren el mismo panel de 344 px. Lo mismo con las muestras dentro del panel (--_color-picker-swatch-sizeclavado amd): fuera del portal los tres pasos alcanzan (20 / 24 / 28 px), dentro sólo elmd. La causa es una sola y vale como ley: el portal es una frontera de cascada — un privado declarado en la raíz del componente no la cruza. → §13, porque arreglarlo mueve píxel ensmylg.Tres cegueras del instrumento, medidas y anotadas: el guard congela las transiciones y
transition-duration/transition-easeSON la transición (sin congelar: 0.12s → 11.5s) — es genérico, cualquier componente con esos dos públicos los reportará muertos; una lectura inmediata de una propiedad en transición devuelve el valor VIEJO, que es lo que hacía ilegible el fondo del cuentagotas; y la demo pisa el cuentagotas con su propia regla de ámbito (.cp-tools-rowle poneinline-size:autoybackground), así que sus dos tokens sólo se pueden medir devolviéndole el consumo. -
2026-08-22 —
drawer: los 24 rojos que arrastraba, medidos uno a uno — y uno era un DEFECTO REAL. El guard queda en verde; sin cambios de código.EL VELO DEL CAJÓN NO PINTA. Su regla es
color-mix(in srgb, var(--drawer-overlay-bg) var(--drawer-overlay-opacity), transparent)y soma escribe--drawer-overlay-opacity: 1INLINE —su progreso de arrastre, un número sin unidad—.color-mixexige ahí un PORCENTAJE: con1la función entera es inválida y el fondo cae atransparent. Medido (rgba(0, 0, 0, 0)en el velo abierto; con80%en el nodo, pinta) y VISTO en captura: el fondo tras el cajón sale desenfocado pero sin atenuar. Mueve píxel y toca soma, así que va a §13 con su lección: un valor que soma escribe inline y una receta consume tiene que compartir UNIDAD, o el fallo es silencioso.El segundo hallazgo: las tallas son canal de valor en el eje que manda — soma escribe
width/heightinline según el lado, así quecontent-width-*no gana desde:rooten un cajón izquierda/derecha (el eje cruzado sí:height-sm260px → 976px). Misma clase que elitem-gapde carousel, pero aquí el token sigue siendo la fuente del valor que soma resuelve: retirar o no es firma.Los otros 22 son lo esperable y quedan medidos: el asa (no montada, y su tamaño INTERCAMBIA ejes según el lado), el anillo de arrastre, el padding
full, la cabecera y el pie opcionales, la z de la variante inline. -
2026-08-22 — REVISIÓN ADVERSARIAL DEL BLOQUE (§7.7): 5 hipótesis, 1 hallazgo real, 4 refutadas. Bloque de CATORCE componentes; global 56 % → 62 %.
HALLAZGO REAL — la anomalía de
float-paneltenía causa, y era del guard.resize-grip-fgmovía aislado y leía muerto en una corrida completa. La causa: la pasada de HOVER deja el puntero sobre el último nodo que tocó, y una regla:hovergana a la de reposo con la que comparte nodo (el asa re-apunta su color al acento). Es decir: cualquier token de reposo probado después de un tokenhover-*podía leer muerto — misma clase que el envenenamiento por clic-foco que F2-A arregló, una pasada más tarde. Arreglado aparcando el puntero tras la pasada de hover. El propio guard delató entonces DOS excepciones STALE —float-panel.resize-grip-fgymedia-player.track—, retiradas: dos tokens que se daban por muertos están vivos. Se confirma la regla de F2-A: un falso negativo siempre tiene causa; registrarlo como «sin causa» era el paso previo, no el final.REFUTADA «hay tokens huérfanos»: comprobación ESTRICTA (comentarios despojados —el hueco que dejó vivo el
popover.bg— sobre todo el CSS del árbol) de las 553 claves de los catorce bloques: ninguna declarada sin que una regla la lea.REFUTADA «el cambio de instrumento rompió algo»: los 27 componentes con ledger re-verificados tras aparcar el puntero — cero regresiones. Los tres rojos que quedan (
drawer24,metrics16,color-picker23) son ANTERIORES al bloque y están anotados.REFUTADA «quedan fantasmas del barrido en lo tocado»: el barrido pasa de 9 a 8 — el
--color-content-tertiaryde float-panel murió con su costura. Los ocho restantes son de componentes que este bloque no tocó.CONFIRMADO, y ya estaba escrito: hay gates FINOS.
popovermide 1 nodo en reposo (7 en abierto),drawer1,context-menu1 + 14 en abierto,color-picker5 + 12. Cada veredicto lo dice; el forzado a mano de sus estados es lo que sostiene esas cifras, no la sonda. -
2026-08-22 —
password-field41 % → 62 % (7 claves) y el guard en VERDE: sus siete silencios quedan medidos, incluidos los tres que arrastraba de antes.Los cuatro peldaños del medidor de fuerza son una ESCALA DE INTENCIÓN —cada uno lee su rol: pérdida, riesgo, cumplimiento, afirmación—, así que un tema puede recorrerla entera sin tocar los roles del sistema. Fuera, por composición: el padding del medidor y el tamaño de su rótulo leen privados de FIELD (§5.3-3, se teman en la ficha del dueño).
Gates: sonda 0 diffs en 3.060 valores · censo 62 % · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 · captura mirada.
-
2026-08-22 —
context-menu53 % → 90 % (11 claves,globala cero), y el instrumento aprende a abrir un menú contextual: se abre con clic DERECHO y con nada más, así que sonda y guard medían UN nodo. ConopenBy: 'contextmenu'y el clic derecho en la sonda: 14 nodos en abierto y el guard en 27/29.Dos limpiezas: el
font-familyera respaldo de sí mismo y el peso del encabezado llevaba un500muerto. Dos adjudicaciones, y una es la TERCERA ocurrencia de §12.9 (el planooverlayimpone la tipografía del panel).Gates: sonda 0 diffs en 600 valores · censo 90 % · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 · captura del panel mirada.
-
2026-08-22 —
metrics74 % → 82 % (4 claves + prefijo abreviado fuera,globala cero).--_mi-*violaba theming §6 r5 —segundo caso del día tras--cp-*—: 16 ocurrencias renombradas a--_metrics-icon-*. Son el conmutador del icono por variante y ya derivaban de públicos, así que el censo los reclasifica solo. Cosido: el ritmo del trend y las TRES formas del icono (una clave por valor dedata-shape; el radio es lo único que las distingue). Dos adjudicaciones forzando las formas que la demo no monta. Sonda 0 diffs en 1.590 valores · censo 82 % · audit PASS · lint 0 · captura mirada. -
2026-08-22 —
float-panel59 % → 84 % (12 claves,globala cero).Las dos variantes que ajustan desde el default elevado, los botones de la barra y el asa. Muere uno de los nueve fantasmas del barrido: el asa leía
var(--color-content-tertiary, …)y ese primitivo no existe — el contrato guarda lo que de verdad pintaba.Once adjudicaciones medidas (la demo monta la variante por defecto y no tiene botón de acción genérico) y una ANOMALÍA registrada:
resize-grip-fgmueve bajo una réplica a mano de la secuencia del propio guard y aun así lo da por muerto; causa no encontrada, descartadas cuatro. El token está vivo; la lectura es lo que está en duda → §13, primer sitio por donde empezar la revisión adversarial de este bloque.Los 12 rojos que quedan son anteriores, y seis son el mismo conjunto que en
popover: el plano de profundidad gana sobre el panel (§12.9).Gates: sonda 0 diffs en 1.890 valores · censo 84 % ·
--namessin desviadas · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 · captura mirada (cabecera, cierre y asa en su sitio). -
2026-08-22 —
nav-tree4 % → 96 % (17 claves; tenía UNA). Global 61 %.La FILA es link + trigger a la vez —mismo padding, tinta, radio y hover—, así que el knob es de la fila (pseudo-parte, molde de
waveform), con el modificador DELANTE en lo interactivo (hover-/active-/disabled-row-fg) y DETRÁS en lo contextual (trail-row-fg). El galón es una escuadra de dos bordes: lado y trazo, como la esquina detext-focus.La suite cazó un incumplimiento heredado, tercera vez en el eje: el contrato copió
var(--font-size-sm)verbatim del CSS y ésa es la coordenada CRUDA querecipe-css-contractprohíbe. Al bundle, computa idéntico.Dos cegueras más del guard: la fila es un
<div>pelado sin atributo (sugapleía muerto) y no leía el ANCHO de un borde que no fuera el de arriba. Con las dos: 18/18 sin una sola excepción. Los nueve componentes con ledger re-verificados tras tocar las PROPS: sin regresiones ni STALE.Gates: sonda 0 diffs en 22.140 valores (102 nodos × 8 estados) · censo 96 % ·
--namessin desviadas · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 · captura del escenario mirada. -
2026-08-22 —
drawer57 % → 72 % (10 claves: el disparador, gemelo del de popover, conmin-block-sizeal bundle). Global 61 %.Lo que queda fuera es la FIRMA DE SALIDA (los cuatro bordes base que
data-last-actiontiñe al cerrar) → §13, y ocho privados que son canales de valor del wrapper.Una adjudicación de clase nueva: el guard ABRE el cajón antes de probar y el velo tapa el disparador, así que la pasada de hover no puede posarse en él. Con el cajón cerrado y hover a mano,
hover-trigger-bgalcanza. Los otros 24 rojos son anteriores (asa, anillo de arrastre, tallas del panel).Gates: sonda 0 diffs en 390 valores · censo 72 % ·
--namessin desviadas · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0. -
2026-08-22 —
aura43 % → 80 % (13 claves). Global 61 %.Su texto de estado baja un paso del bundle por talla y las TRES coordenadas viajan juntas: doce declaraciones, doce valores, doce claves (1:1, sin inflación). Más
idle-opacity. Identidad fuera: el radio del anillo, los cuatro100%y el1pxde la región sr-only.Doce adjudicaciones medidas: las seis tintas de estado y el halo pintan el fondo del INDICADOR y la demo corre con el canvas WebGL montado —
:has(canvas)ponebackground: nonea propósito—; quitando el canvas en vivo, el gradiente vuelve y las siete siguen. El arco y el halo son SLOTS que sólo existen en los estados de trabajo: montados como<circle>en el SVG real, alcanzan. Y el guard no veía ese SVG (sus<circle>no llevandata-aura*): tercera vez queextraNodessalva tokens vivos.Gates: sonda 0 diffs en 1.710 valores · centinela 25/37 con las doce adjudicadas · censo 80 % ·
--namessin desviadas · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0. -
2026-08-22 —
color-picker51 % → 75 % (20 costuras + un prefijo abreviado retirado). Global 60 % → 61 %.--cp-*violaba theming §6 r5 (no abreviar el nombre del componente): cinco nombres, 45 ocurrencias en 8 ficheros, tres de SOMA —el provider los estampa inline, su test los lee, sus tipos los declaran—. Renombrados a--_color-picker-*congit ls-filesy 0 diffs; dos ya derivaban de un público, así que el censo los reclasifica solo. Precedente: los--gb-*de F2-A.Cosido el ritmo, la tinta de la etiqueta, la tipografía del disparador y la del VALOR (metadato: mono/regular/tinta propia), el borde de la muestra, el raíl de canal y su pulgar, el hueco del anillo y el borde del cuentagotas. El pulgar lleva DOS sombras que hacen una cosa (contorno + elevación): un token, y la regla de foco lo compone con su tercer anillo.
El instrumento no veía dos familias de nodo: las muestras del picker SON
<ColorSwatch>(data-color-swatch) y sus sliders SON sliders (data-slider-*); cuatro tokens vivos leían muertos. ConextraNodespara las dos, 46/71.Lo rojo que queda es anterior: 23 sin adjudicar (eran 24), del bloque viejo — su pase propio queda en §13, con dos causas ya descartadas (el panel SÍ abre y sobrevive al forzado de talla; el guard ya ve sus nodos).
Gates: sonda 0 diffs en 1.350 valores, medida DOS veces (tras el renombrado y tras la costura) · tests de soma del color-picker 7/7 · censo 75 % ·
--namessin desviadas · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 ·checksin errores propios. -
2026-08-22 —
popover46 % → 67 % (11 claves para el disparador + una RETIRADA). Global 60 %.El disparador genérico —el que no lleva el arquetipo
field-trigger— montaba su cromo sobre primitivos crudos: once costuras, contrigger-heightleyendo el BUNDLE y no el primitivo, y hover/abierto con su par cada uno (mismo valor hoy, dos estados distintos).bgretirado: era un huérfano que el test de huérfanos no veía. Ninguna regla lo consumía; lo único que lo nombraba era un COMENTARIO depopover-arrow.svelte, y ese test busca el nombre como texto en los ficheros del componente. La superficie la pinta el plano de profundidad. → §13.Los doce que quedan son la FIRMA DE SALIDA y no se cosen aquí: la misma matriz
data-last-action× 3 intents × 4 lados está repetida en drawer (22) y dialog (9), y ya ha derivado (dialog tiñe sólo el color; popover y drawer también el grosor). La tabla morfo→eidos la sitúa como mapeo transversal, así que la salida es una regla sobre el arquetipo, no tres copias. → §13.Dos cegueras del instrumento: la página tiene CINCO disparadores y el guard abría el primero del documento en vez del del escenario; y
content-zse consume sobre el ENVOLTORIO FLOTANTE, un nodo sin atributodata-popover*, así que leía muerto moviendo 80 → 4321. Las dos arregladas enCOMPONENT_OVERRIDES.Gates: sonda 0 diffs en 420 valores (8 estados) · centinela 33/46 con trece adjudicaciones medidas —nueve de partes que la demo no monta, dos del overlay opcional y dos que el plano
overlaygana (§12.9, pendiente de firma)— · censo 67 % ·--namessin desviadas · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0. -
2026-08-22 —
radio-cards60 % → 61 %: una sola clave, y ése es su techo. 21 de sus 23 knobs fuera de alcance no son suyos: es un SKIN sobre RadioGroup —renderiza<RadioGroup.Provider>y su indicador ES un radio—, así que lee--radio-group-*y el puente de paleta del anfitrión. Mandato de composición (theming-audit§5.3-3): se teman en la ficha del dueño. Lo suyo es la TARJETA:invalid-border. Los dos--radius-fulldel indicador son identidad (un radio es redondo por definición).La lección de la medición: la primera lectura de
invalid-borderdio «sin efecto» porque la tarjeta transicionaborder-colory leer justo después de escribir devuelve el valor de PARTIDA. Con las transiciones congeladas —lo que el guard hace por defecto y mi sonda a mano no— alcanza. Una medición forzada tiene que congelar también.Gates: sonda 0 diffs en 3.540 valores · centinela 35/40 con las cinco adjudicadas y medidas · censo 61 % ·
--namessin desviadas · audit PASS · lint 0. -
2026-08-22 —
prose1 % → 83 % (35 claves de costura, 2 → 37). Global 59 % → 60 %;globaldel catálogo 1.064 → 1.021.Estiliza HTML CRUDO por
:where([data-prose] el), así que sus partes son ELEMENTOS y la costura va por parte, como enresult. Su escala editorialem-relativa no entra: es decisión de diseño de su README («No 5× duplicated scale») y va anotada/* literal: */— las 21 excepciones que el censo aprendió a leer esta misma sesión. Dos literales se cambiaron por su paso de escala con idéntico valor (3px→--border-width-thick, los1px→--border-width).El instrumento estaba ciego de dos maneras, las dos arregladas antes de medir: sonda y centinela filtran por
data-{c}-*y aquí NINGUNA parte lo lleva —la sonda medía 1 nodo y el guard daba 27 de 37 por muertos—, así que ambos ganan un selector de nodos extra (63 nodos con él); y el centinela no leía el color de un borde que no fuera el de arriba, con lo que el blockquote (border-inline-start) y la tabla (bordes de bloque) leían muertos estando vivos.Ocho adjudicaciones medidas: cinco las tapa el harness de la documentación (
[data-uix-docs] code|pre(0,2,0) gana a:where(…)(0,0,0) — la incidencia ya escrita paracode-block) y tres son elementos que el HTML de ejemplo no usa, montados dentro del contenedor real.Gates: sonda 0 diffs en 11.910 valores (63 nodos × 7 estados) · centinela 29/37 · censo 83 % ·
--names37/37 · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 ·checksin errores propios. Los del ledger re-verificados tras tocar el guard: sin regresiones. -
2026-08-22 —
listboxADJUDICADO: 68 % es su techo, y coserlo habría mentido. Sin cambios de código: su veredicto §5.Cinco de sus nueve privados adoptan la capa
list-surface(el ritmo de fila compartido con select, combobox, command y los tres menús), dos son el puente de paleta y el noveno sí deriva de un público. La cola decía «cose como sus hermanos» —dropdown-menuycontext-menusí acuñan el puente—, y la medición lo desmontó: ninguno de los dos nombres alcanza desde:root(fila a 36 px,--dropdown-menu-item-heighty--list-item-heighta1234pxen:root→ 36 px). La capa declara sobre[data-list-surface][data-size]y el puente sobre[data-{c}-content]: las dos ganan a:root. Copiar el puente habría subido la cifra sin dar alcance — un token que miente, la clase que R-5.4 existe para cazar.Se arregla EN LA CAPA (entrada de receta, como
calendar-surface), toca diez componentes y es su propio eje → §13. Y avisa sobre el instrumento: el centinela da por vivos estos tokens porque escribe inline en el nodo; para un token que un tema sólo puede escribir en:root, «mueve un computed» no equivale a «un tema lo alcanza». -
2026-08-22 — El censo aprende a leer la válvula del canon: clase
exception. Global 58 % → 59 %, sin tocar una línea de CSS.recipe-contract§3 dice que una desviación anotada/* literal: <razón> */en su propia declaración es válida, ycomponent-auditya la honra desde siempre (declarationWindow+/literal:/ien R-2.1/2.6/2.7). El censo era el único instrumento que no: sustrip()blanquea los comentarios ANTES de clasificar, así que las 81 anotaciones del catálogo contaban como deuda. Dos instrumentos, un canon, dos respuestas.Ahora un literal anotado cae en la clase
exception, fuera del ratio comosystem— y por la misma razón: no es que un tema no lo alcance, es que el canon ya aceptó por escrito que ahí no va un token. 54 knobs en 12 componentes:prose21 (su escala editorialem-relativa, decisión de diseño firmada en su README),proof-of-human16 (la escena de tono fijo),palabras3,timeline2 (73 % → 77 %),result1 (86 % → 90 %), y siete más con una cada uno.La anotación vale para la DECLARACIÓN entera, no sólo para su primera línea: un valor partido en varias líneas lleva la nota al final, y así se mide. Muta-prueba: retirar una anotación de
prosemueve el knob deexceptionaliteral(21 → 20) y devuelve el conteo al restaurarla.Efecto colateral bueno: las fichas ganan una §1.4 que LISTA las excepciones con su razón. Antes estaban escritas en el CSS y no se leían desde ninguna parte.
-
2026-08-22 — Tres techos adjudicados: el PUENTE DE PALETA no es deuda.
tag-group65 %,stepper79 %,timeline73 % — sin cambios de código, sus tres veredictos §5.Los tres tienen
globala cero: lo único fuera de alcance son sus privados--_{c}-palette-*, el puente THM-2 que la capa compartida alimenta por instancia desde[data-color]. Un público encima del puente dejaría que un tema lo fijara y matara en silencio elcolor=de cada instancia — la misma clase de daño que «declarar un público de facto mata una escala». Ya exponen sus nueve roles × variante en claves públicas (91 entag-group): ésa ES su superficie de color.timelinesuma la segunda razón firmada: sus--_timeline-hue-*son un CONMUTADOR pordata-intent(doctrina F2-B, cinco precedentes) cuya rama por defecto es el puente.Medido para no adjudicar de oído: de las 687 declaraciones del catálogo que leen un privado, 130 leen un
--_{c}-palette-*, y son las que dominan la columnaprivatede todo componente con paleta (tag-group 14/14, stepper 11/11, radio-group 10, checkbox 8, file-upload 8, calendar / editable / los tres grids 7). El techo de un componente con paleta no es el 100 % y su cifra no compara con la de uno sin ella — registrado en §13, junto con la única salida si algún día se quiere comparabilidad: una clasebridgeen el censo, no acuñar los tokens. -
2026-08-22 — LA COSTURA:
chart49 % → 89 % yresult23 % → 86 % (6 + 15 claves). Global 57 % → 58 %;globaldel catálogo 1.113 → 1.064.Corrige una lectura mía de las dos horas anteriores. Al tokenizar
chartyresultdi por doctrina que «el texto no recibe tokens del componente» porque su valor viene del canon —la capa de estilos con nombre, las ranuras de contenido, el bundle de talla— y lo dejé leyendo el canon A PELO desde el CSS. Eso es media doctrina: el valor es del sistema, pero el knob tiene que ser del componente (PLAN §2-A: todo knob de apariencia lee--{c}-{slot}). Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin movercaptionen toda la app, ygetRecipeTokens()//temasno ven esa superficie. El molde ya estaba escrito en la vertebración tipográfica (--accordion-trigger-font-family: var(--style-label-font-family)) y D-TH.2 aclara que sólo los seis PRIMITIVOS quedan fuera («un componente que sólo LEE un named style para un eje no es un primitivo»).Dos formas, porque los componentes son distintos — y ésa es la parte que se firmó:
chart, por ROL: dos roles del canon (captionpara las anotaciones,labelpara el cromo) × tres ejes = 6 claves para 19 nodos de texto. Nombrar por parte habría dado ~30 claves con dos valores. Tamaño y tinta son ORTOGONALES a propósito (emptyybar-list-valueson tamañolabelcon tintacaption). El readout del gauge no tiene rol en el canon y su costura toma el bundle.result, por PARTE: cinco partes con tipografía distinta y ningún rol que las cubra → 15 clavestitle-*,description-*,extra-*,code-*,media-*. Es la forma dominante del catálogo.
Nombres: los tres que propuse primero no aguantaron la revisión (
label-font-sizechocando con las seis partes*-label,emphasis-*inventando vocabulario,fg-mutedapoyado en un solo precedente). Se nombra por el ROL DEL CANON que el texto adopta, y la tinta lee el color DEL ROL (var(--style-caption-color)), no la ranura a pelo.Con esto
globalcae a CERO en los dos: lo que queda fuera son los diez literales de identidad de chart (nueve100%+max-content) y tres de result.Gates: sonda 0 diffs en 161.850 valores (chart, 16 rutas × 7 estados) y 990 (result) · centinela chart 43/45 y result 15/27, y las doce que callan están medidas SOBRE NODOS REALES con los controles de la demo (chip
not-foundpara el código HTTP, casilla delextra, quitardata-statuspara la tinta por defecto del glifo) · censo 89 % / 86 % ·--names45/45 y 27/27 · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 ·checksin errores propios.Y retira una nota equivocada de §13: escribí que el censo penalizaba consumir la capa tipográfica. El censo medía bien; faltaba la costura. La lección queda escrita ahí: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento.
listbox(68 %, ritmo de fila prestado delist-surface) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. -
2026-08-22 —
result14 % → 23 % (4 claves, 8 → 12). Global 57 %, <20 % 18 → 17. Aplicación directa de la doctrina que cerróchart: la receta posee su CAJA —inset de página, ritmo entre bloques— y nada más. Su tipo ya leía el BUNDLE DE TALLA (--size-{k}-font-size), que es lo que recipe-contract §1 prescribe, y su tinta las ranuras de contenido: acuñar--result-title-font-sizehabría sido tipografía por componente. Las trece lecturas de canon siguen contandoglobal— §13, tercera ocurrencia.Higiene de paso: el privado
--_result-media-color→--_result-media-fg(D-TH.6 dicefg; R-5.3 no mira privados).Gates: sonda 0 diffs en 990 valores · centinela 7/12 con cinco adjudicaciones medidas sobre nodos REALES —los tres acentos pulsando su chip de estado, el bloque
extramarcando su casilla— y no sobre nodos fabricados (la lección dedrag-drop) · censo --only 23 % · --names 12/12 · audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 ·checksin errores propios. -
2026-08-22 —
chart9 % → 49 % (22 claves nuevas fusionadas en su bloque, 17 → 39). El mayor de los de alcance <20 % que no estaba bloqueado.La ficha pedía 71 claves y ~20 habrían llevado el mismo valor. Lo decidió la medición: las 84 filas fuera de alcance colapsan a 26 valores distintos (9×
content-secondary, 9×content-primary, 9×100%, 6×font-size-sm, 6×font-size-xs, 6×font-weight-medium, 5×surface-default). La inflación despinnercon otra forma: nombrar por parte lo que es un concepto.El texto no recibe tokens de chart: toma su ROL DE TAMAÑO de los estilos con nombre (
captionpara anotaciones,labelpara el cromo) y su tinta y peso de las ranuras del sistema. Acuñarlos sería tipografía por componente, lo que el autor prohibió el mismo día. Precedente de consumir la capa:code-block,kbd,announce. La receta sólo posee la tinta de lo que no es texto —axis-fg,grid-fg,separator-fg(el pelo de superficie que separa marcas contiguas: cinco partes, una idea),smith-boundary-fg,track-bg— más 17 de geometría de cromo. Identidad fuera de contrato: los nueve100%y elmax-contentdel tooltip.Incumplimiento heredado corregido: el CSS leía la coordenada CRUDA
var(--control-height-sm, var(--space-7))(respaldo muerto); el contrato guarda el bundlevar(--size-sm-control-height), 1:1.El instrumento estaba ciego de TRES maneras, arregladas antes de medir:
- La superficie de chart vive en 16 rutas de demo, una por tipo:
/chartmonta 58 nodos de los 302 de la página y el resto vive en rutas hermanas. El guard ganaurls: un token está VIVO si ALGUNA superficie del componente lo sigue, y cada URL sólo re-prueba lo que sigue pendiente. De pasopicker-shellrecibe la suya (su ruta propia es un 404, se mide dentro del date-picker: 0/31 → 6/31 sin pasar la URL a mano). - El guard no leía NINGUNA propiedad SVG — sin
fill/stroke/strokeWidth/fillOpacity/r/rx, doce claves de un componente que dibuja en SVG leían muertas estando vivas. Misma clase que el hueco defilterdel día anterior. - El valor centinela se elegía por SUBCADENA:
slice-stroke-widthrecibíargb(1, 2, 3)por contener «stroke» — inválido para una longitud, así que leía muerta. Ahora la dimensión se decide por el final del nombre.
Gates: sonda 0 diffs en 161.850 valores (16 rutas × 7 estados, 892 nodos en reposo) · centinela 37/39 con dos adjudicaciones medidas sin la congelación (
transition-duration0.12s → 11.5s,-ease→ steps(4)) · censo--only49 % y global 56 % → 57 % (2.638 → 2.675 públicos, <20 % 19 → 18) ·--names39/39 conformes · audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl 0 · docs 0 ·checksin errores en los ficheros tocados. Los 28 componentes con ledger re-verificados tras los tres cambios de instrumento: cero regresiones, cero STALE.Abre (→ §13): el censo penaliza consumir la capa tipográfica si no eres un primitivo (las doce declaraciones correctas siguen contando
global) — la nota delistboxcon una segunda ocurrencia; y el número del gauge no tiene estilo con nombre que lo represente (un readout de dato no es unh2). - La superficie de chart vive en 16 rutas de demo, una por tipo:
-
2026-08-22 —
text-scrambleADJUDICADO: sin contrato que escribir (y el barrido de fantasmas, hecho). Sin cambios de código: su veredicto §5.Su 50 % no es ni deuda ni logro. Dos literales son la técnica sr-only (
width/height: 1px), idéntica atext-blur. Los dos «públicos» son tipografía que el componente no debería acuñar —fontysize, consumidos con fallback y sin declarar—, o sea la firma 1.bis: escribirles contrato ahora sería acuñar exactamente lo que esa firma propone retirar. Context-scramblela cuenta de esa firma sube a 7 claves en 4 de los 5 componentes de la familia (text-blures el único limpio: hereda).Y su
fontapunta a un fantasma:var(--font-mono, …)no existe —el canónico es--font-family-mono— así que pintaui-monospacee ignora la mono del tema (Azeret Mono). Medido en navegador.El barrido mecánico que
--radius-xsy--font-size-4xlpedían está HECHO: 5.793 nombres declarados ensrc/uix/eidoscontra losvar(--x, fallback)de las recetas → 9 referencias fantasma, tabla en next-features §13. La más grave no es de esta familia:--color-content-tertiarysigue vivo en TRES recetas (el caso histórico querecipe-contract§1 cita como origen de su regla) y los cuatro--style-*-font-variation-settingsdetext.csssignifican que el eje de fuente variable no llega nunca al primitivoText. Ninguna se arregla aquí; el barrido debería ser un guard (misma lógica que el test de fantasmas sin fallback, con el filtro de vocabulario de sistema encima). -
2026-08-22 —
text-gradient67 % → 100 % (7 claves, entrada nueva). Tercero de la familia text-* con la forma detext-circular/text-focus(públicos «de facto» con fallback y sin declarar), pero la propuesta §4 generada fallaba en las tres decisiones y las tres se resolvieron midiendo contra el CATÁLOGO, no contra el CSS de partida:weight→font-weight: 77 clavesfont-weighten el catálogo contra 4weighta secas, dos de ellas escritas el mismo 22 en esta familia. Y500esvar(--font-weight-medium).calc(100% - 2px)no son dos knobs de eje físico (que es lo que la ficha marcaba con ⚠) sino UNO: los 2 px son el trazo del marco asomando a cada lado. Knob =border-widthconvar(--border-width)(el pasothin, no un literal igual a un paso), y el hueco DERIVA de él.blur(4px)→var(--blur-sm):blures familia MÉTRICA del ejescaling(theming §23) y un literal es ciego al zoom global.
Fuera del contrato por naturaleza:
durationyplay-direction, que el wrapper escribe INLINE desdeanimationSpeed/yoyo— misma clase que elitem-gapdecarousely elpreview-zdedrag-drop.Dos puntos ciegos del instrumento, arreglados ANTES de medir (la lección de F2-B aplicada por adelantado): la demo arranca con
showBorder=false, así que sonda y centinela veían 2 nodos y NINGUNO de los tres tokens del marco; y la sonda no leíabackdropFilter, que el censo sí cuenta como knob. La sonda gana un mapaDEMO_VARIANTS(chips de variante que se re-pulsan tras cada recarga) y el centinela una entradaopenWithque no abre un panel sino que ENCIENDE UNA VARIANTE — un uso nuevo del mismo gancho.Gates: 4 nodos · 720 valores × 7 estados · 0 diffs · centinela 7/7 sin excepciones · censo
--only100 % y global 2.634 → 2.638 públicos ·--names7/7 conformes · audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido (skin-media-player) · rtl 0 · docs 0 ·checksin errores en los ficheros tocados. Demo con pestaña Tokens (y fuera la tabla de tokens escrita a mano, que este mismo renombrado dejaba obsoleta).Abre (→ next-features §13, pendiente de firma, apuntado para después): la familia text-effects ACUÑA tipografía propia contra el canon — cinco claves (
text-focus.word-sizevía el fantasma--font-size-4xlyword-weight·text-circular.weightyfont-size·text-gradient.font-weight, ésta subida aquí), opiniones del seed que el «valor verbatim» hizo contrato. Doctrina F2-B regla 2: se CONSUME la capa (--style-*) o se HEREDA (link); un efecto de pintura sobre texto real no tiene tipografía propia. Resolución propuesta: retirar las cinco y heredar (mueve defaults → firma). El módulo de tipografía es canon y no se toca. Las demos NO forman parte del eje (autor, 2026-08-22). -
2026-08-22 — Bloque F2-B: 21 componentes tokenizados + 5 adjudicados como «0 % estructural». Global 45 % → 50 %; sin contrato 49 → 29; al 100 % 7 → 10; alcance <20 % 43 → 22. Uno por commit, protocolo §7 entero, sonda antes/después = 0 diffs en todos.
componente alcance commit grid-list0 → 85 % 60b5b9896textarea0 → 80 % 893aeaf81tree-view0 → 92 % dd188f125code-block0 → 81 % 354d166dfcard-group0 → 90 % c56d6544espinner0 → 70 % 42a3e7413picker-shell0 → 76 % 67b4c810clink-preview0 → 100 % 7a0fc2eaddrag-drop0 → 89 % 650d76aa0kbd0 → 86 % adb77863clink0 → 36 % d3089e880code0 → 100 % e4bcd505dvirtual-list0 → 67 % 070145786virtual-grid0 → 73 % e3f39ce28skeleton0 → 45 % a6d4d4f5alabel0 → 100 % 7565eff47announce0 → 88 % d568577ebclipboard0 → 63 % 151e5159bscroll-frames0 → 33 % 1f692629emark0 → 60 % 9f24a31ebmenu-dial0 → 25 % 471ba96d25 estructurales (fichas) 0 % FINAL ed2e3cd7cLo que el bloque enseñó, y no estaba en el plan:
- Un alcance bajo puede ser doctrina bien aplicada.
menu-dial25 % porque sus ejes de colocación son de la capaviewport-placementy la receta escribe en sus RANURAS DE OVERRIDE;link36 % porque sus escotillas caen eninherit, que es semántico;scroll-frames33 % porque es layout puro. El % no es la métrica de calidad. - Un privado con DOS fuentes es un conmutador, no deuda — cinco casos
con el mismo veredicto (
textarea,spinner,skeleton,code,label): aplanarlo obligaría a duplicar cada regla por color. - Lo que la capa tipográfica posee no se acuña — cinco casos
(
code-block,kbd,announce,code,label). - Cinco componentes tienen 0 % POR NATURALEZA y ninguna deuda:
aspect-ratio(faceta de Box, knob prestado),text-blur(sr-only),cascadeymotion(gate antiparpadeo del canal),date-picker(correcciónmax-contentde composición). El censo no los distingue de la deuda real, así que el gate de F3 «censo 100 %» es inalcanzable por construcción hasta que exista una clasestructural— §13. - La propuesta §4 generada hereda el incumplimiento del CSS de partida:
copia el valor verbatim, y si ese valor ya violaba
recipe-css-contract(primitivo crudo en vez del bundle), la propuesta lo repite. Lo cazó la suite encode-block. - La inflación del generador puede ser 4×: en
spinnerproponía 71 tokens para 23 knobs, multiplicando UNA coordenada de talla por variante × parte × dimensión.
El guard R-5.4 ganó SEIS capacidades, todas nacidas de una medición y con los componentes del ledger re-verificados sin regresión tras cada una: puntero parqueado tras el blur (
reopen()corre antes de cada token),::placeholderen el snapshot (la nota de §13 que decía que no se lee era falsa),COMPONENT_OVERRIDESde prefijo y selector de apertura, apertura porhoverpara hover-cards, ytext-decoration-thickness/-underline-offseten la lista de propiedades.Revisión adversarial §7.7 — HECHA 2026-08-22. Molde F2-A: worktree en la base del bloque (
8400e5bdd) con su propio dev server, medición independiente. 4 hipótesis · 3 refutadas · 1 hallazgo real.- REFUTADA «el default cambió en algún sitio que la demo no mira»: 77 casos FORZADOS (variantes, formas, tallas y estados que las demos NO montan, en los 21 componentes) comparados base vs HEAD → 0 diferencias.
- REFUTADA «hay tokens huérfanos»: 339 públicos de los 21 bloques, 0 sin consumo. Con muta-prueba: un token falso inyectado sale detectado, y el árbol se restaura.
- REFUTADA «el gate de 0 diffs pasó sobre casi nada»: se contaron los
nodos que ve cada sonda. Cuatro componentes miden 1 nodo (
link,code,skeleton,link-preview), y por eso se forzaron sus variantes en el punto anterior — ahí es donde viven sus tokens, y salieron idénticos. - HALLAZGO REAL:
drag-drop.preview-zmentía. El ledger lo daba por vivo con «forzado → alcanza», pero el nodo se había creado a mano; el preview REAL que soma monta durante un arrastre llevaz-index: 9999INLINE, así que ninguna cascada puede ganarle. Retirado con 0 diffs. Misma clase que elitem-gap*de carousel en F2-A. La lección: una adjudicación «forzado → alcanza» vale lo que valga el nodo que se forzó. Re-verificado el resto de la clase contra nodos reales (clipboard,picker-shell): correctos.
Dos hallazgos de INSTRUMENTO en la propia revisión, ambos registrados en §13: el orden de carga no es el mismo en dev que en producción (medido con build + CDP; el ganador coincide por casualidad), y un worktree cuyo
node_moduleses una junction fuera del root no hidrata — Vite responde 403 a@fs/…y la primera pasada de esta revisión comparó contra una base muerta sin que nada lo delatara. - Un alcance bajo puede ser doctrina bien aplicada.
-
2026-08-21 — La capa
calendar-surface(firma 1 del acta, diseño presentado y firmado el mismo día). La medición desmontó el encargo: la capa ya existía de hecho —--calendar-*en:root, yrange-calendar/month-grid/year-gridcon 114 / 77 / 77 referencias prestadas y CERO tokens propios. Se le dio nombre y casa (lib/calendar-surface.css, hookdata-calendar-surface, cuatro coordenadas xs..lg sin xl, celda dos pasos bajo el bundle) y se cerró el defecto que la justificaba: las dos sombras del anillo se emitían con ámbito[data-calendar]y los otros tres las leían vacías, así que el anillo sema no pintaba en tres componentes. Capa HÍBRIDA: el vocabulario se queda en la entrada de receta (76 claves semánticas alcanzables por config), la capa posee la resolución por talla y la forma del anillo. Siete wrappers estampan, no cuatro — los pickers renderizan la superficie soma por los suyos y un panel portalado no hereda. Censo:LAYER_VOCABULARYdeja de penalizar consumir una capa; global 43 % → 45 %,calendar75 % → 84 %. -
2026-08-21 — Revisión adversarial de F2-A (§7.7) + nace R-5.4. Molde Sidebar sobre worktree con solo el CSS revertido a la base: 34 hipótesis · 26 refutadas · 8 reales, todas las de código arregladas con diff de computed VACÍO (command 8.091 · carousel 2.842 valores). Retiradas: el re-point muerto de
--command-radiusen el Dialog (su comentario mentía: el input nunca lo leyó) y el tríoitem-gap*de carousel (elgapINLINE de soma gana siempre — canal de valor, no knob). Tokenizado: el2.25vertical del indicador activo. El instrumento viejo cargaba 22 falsos negativos de 26 «no effect» (clic-foco · override solo en[data-{c}]· pseudos) y la no-determinación defeedera la demo cargando — cuatro causas arregladas. R-5.4:theming-sentinel.ts+ ledger de adjudicaciones, los ocho componentes en verde con 46 excepciones medidas. Elstripedinerte se firmó y ejecutó el mismo día::nth-child(even of [data-table-row])+:where(:not([data-selected]))al mismo (0,6,0) — 12 diffs exactos, hover y selected verificados, la excepción del ledger retirada (table 42/45). Pendiente de firma: elitemen fila Y celda, y el gap de soma. Detalle enCONTINUE-theming.md§«Registro». -
2026-08-20/21 — Las 14 firmas, el vocabulario y el bloque F2-A. El día se abrió presentando D-TH.6 y acabó con las catorce decisiones pendientes firmadas en bloque, el vocabulario normalizado con guard, y ocho componentes tokenizados. Detalle en
CONTINUE-theming.md§«Registro de la sesión».El vocabulario (
f09e04fabacta ·bd916ef3fcodemod ·93017975csegunda pasada ·7781d6e4cguard + doctrina ·476da2dd2muro de tipos): 307 claves al idioma firmado —tintafg, modificador interactivo delante— con censo de alcance IDÉNTICO y 0 diffs de computed. R-5.3 entra enerrordirecto; el tipo dedefineRecipesimpide la regresión sin ejecutar nada. La medición corrigió el inventario heredado: 370 «desviadas» eran 301, porque 47 claves{rol}-{slot-de-rol}son canónicas por construcción y un codemod sobre ellas habría rotobuttonentero.El bloque F2-A (pieza 0
bd032534b+ ocho componentes): global 37 % → 43 %, sin contrato 56 → 49, al 100 % 6 → 7.command98 % ·table86 % ·media-player88 % ·tree-grid95 % ·gradient-picker88 % ·listbox68 % (techo deliberado: su ritmo es delist-surface) ·carousel77 % ·feed94 %. Protocolo §7 entero en los ocho; diff de computed vacío en todos.Lo que el bloque destapó y NO se arregló aquí está en
next-features.md§12 y §13: el contrato de cascada del velo de estado (131 declaraciones-atajo en 45 componentes, la prophoverableque no suprime nada, un empate de especificidad resuelto por orden de carga) y los huecos de instrumento y demo. La regla que el eje adoptó: si una incidencia mueve píxel o toca morfo, se mide, se anota y se sigue.Tres veredictos de ocho tenían un error de lectura que sólo apareció midiendo, y esa es la lección de método del bloque: el veredicto orienta, la medición decide.
Además: la demo enseña ahora el contrato de tokens (
90aa6dc5f,TokensPanelleyendogetRecipeTokens()en vivo) — hasta ese día ninguna demo mostraba la superficie que este eje construye. -
2026-08-19 — Censo medido (§1) con
scripts/theming-census.ts(añadido en este commit como instrumento, sin guard). Plan entregado. Nada firmado, nada construido. Precedente ejecutado hoy que fija la forma:navigation-menu(ae9e277fa: tokens del trigger por talla, default idéntico;a82794845: el hover es el del sistema;822b78cf2: el<li>sin arquetipo) — y aun así el componente queda en 44 %, prueba de que hace falta el guard. -
2026-08-20 — Informe + primeros siete componentes (
2591ec2f0el informe y el instrumento;3bfe0d413la revisión de las fichas 11-20). El censo pasa a--report:docs/audit/theming/con un README de conjunto y 170 fichas (162 recetas + 8 sin receta), cada una con análisis, propuesta derivada de la doctrina y un bloque de veredicto que se conserva al regenerar.Componente Censo antes → después Commit Excepciones / lo que queda fuera gradient-builder(piloto)0 % → 80 % 3cdb5b5f0foco (sistema) + 3 literales de layout; damero tapado por el backgroundinline del wrapper (anotado)combobox0 % → 76 % cef2d32f13 hovers bespoke (esperan firma) + 6 literales; content-font-family/-line-heightinertes bajo[data-depth='overlay']natural-time-picker0 % → 61 % e774ca7e8cielos = excepción de tono fijo ya firmada; panel presta --popover-*por composicióndate-range-picker0 % → 42 % 07778b597mitad calendario (§B) + mitad campo (§5.3-3) time-range-picker0 % → 19 % 68eb8af26préstamos de Field/Slider/Toggle time-picker0 % → 18 % e4fcdd62epréstamos de Field proof-of-human0 % → 14 % ae91573c3escena = FIXED_TONE_COMPONENTS; hooks de clase (eje aparte)Global: 33 % → 37 % (1.621 → 1.841 públicos; 62 → 56 sin contrato). Protocolo §7 aplicado entero en los siete: diff de computed vacío en todos (6.612 · 1.566 · 6.438 · 493 · 725 · 580 · 406 valores, 7-8 estados cada uno), centinela por token,
component:auditPASS,eidos-lint0 invalid,rtl:check0,docs:check0, suite eidos con el único rojo conocido (skin-media-player).Cuatro defectos del método que la verificación destapó y que el handoff recoge: clave duplicada en
recipes/base.tsdescarta el bloque en silencio · dejar vivos los bloques[data-size]del CSS hace que el diff dé 0 por la ruta vieja · la sonda debe congelartransitionpero noanimation(Presence no monta) · un token RESUELTO no se mueve desde:rootpor diseño.Prefijos abreviados o ajenos corregidos de paso (el censo los contaba como
globaly se cruzarían al anidar):--gb-*,--_ntp-*,--_time-field-*en los dos time-pickers,--_date-field-*y--_calendar-font-sizeen el date-range-picker.
9. Tabla completa por componente (2026-08-19 — regenerar con el script, no editar)
| Componente | Familia | Alcance | Knobs | Público | Privado | Global | Literal | Sistema | Contrato | size |
|---|---|---|---|---|---|---|---|---|---|---|
range-calendar |
Tiempo (chronos · fecha/hora) | 0% | 98 | 0 | 7 | 84 | 4 | 3 | 0 | y |
combobox |
Campos | 0% | 96 | 0 | 15 | 67 | 6 | 8 | 1 | y |
proof-of-human |
Controles · marcas | 0% | 95 | 0 | 18 | 36 | 37 | 4 | 0 | y |
time-range-picker |
Tiempo (chronos · fecha/hora) | 0% | 88 | 0 | 6 | 61 | 17 | 4 | 0 | y |
natural-time-picker |
Tiempo (chronos · fecha/hora) | 0% | 78 | 0 | 0 | 69 | 7 | 2 | 0 | y |
gradient-builder |
Campos | 0% | 62 | 0 | 8 | 46 | 3 | 5 | 0 | y |
month-grid |
Tiempo (chronos · fecha/hora) | 0% | 61 | 0 | 13 | 40 | 5 | 3 | 0 | y |
year-grid |
Tiempo (chronos · fecha/hora) | 0% | 61 | 0 | 13 | 40 | 5 | 3 | 0 | y |
time-picker |
Tiempo (chronos · fecha/hora) | 0% | 59 | 0 | 3 | 42 | 12 | 2 | 0 | y |
date-range-picker |
Tiempo (chronos · fecha/hora) | 0% | 55 | 0 | 0 | 49 | 3 | 3 | 0 | y |
command |
Menús · listas · navegación | 0% | 52 | 0 | 9 | 35 | 6 | 2 | 0 | y |
table |
Menús · listas · navegación | 0% | 46 | 0 | 23 | 14 | 5 | 4 | 0 | y |
media-player |
Media · chat | 0% | 45 | 0 | 0 | 37 | 8 | 0 | 2 | y |
tree-grid |
Menús · listas · navegación | 0% | 42 | 0 | 29 | 8 | 2 | 3 | 0 | y |
field-langs |
Campos | 0% | 41 | 0 | 0 | 31 | 8 | 2 | 0 | – |
gradient-picker |
Campos | 0% | 38 | 0 | 7 | 23 | 5 | 3 | 0 | y |
listbox |
Campos | 0% | 38 | 0 | 9 | 23 | 3 | 3 | 0 | – |
carousel |
Superficies · overlays · estado | 0% | 36 | 0 | 14 | 12 | 5 | 5 | 0 | y |
heading |
Texto · tipografía | 0% | 36 | 0 | 36 | 0 | 0 | 0 | 0 | – |
feed |
Menús · listas · navegación | 0% | 33 | 0 | 13 | 16 | 3 | 1 | 0 | y |
grid-list |
Menús · listas · navegación | 0% | 32 | 0 | 8 | 17 | 2 | 5 | 0 | y |
textarea |
Campos | 0% | 28 | 0 | 16 | 5 | 4 | 3 | 0 | y |
tree-view |
Menús · listas · navegación | 0% | 28 | 0 | 8 | 14 | 4 | 2 | 0 | y |
code-block |
Texto · tipografía | 0% | 26 | 0 | 2 | 24 | 0 | 0 | 0 | – |
card-group |
Superficies · overlays · estado | 0% | 24 | 0 | 0 | 18 | 4 | 2 | 0 | y |
text |
Texto · tipografía | 0% | 24 | 0 | 24 | 0 | 0 | 0 | 0 | – |
spinner |
Superficies · overlays · estado | 0% | 23 | 0 | 15 | 4 | 4 | 0 | 0 | y |
picker-shell |
Tiempo (chronos · fecha/hora) | 0% | 21 | 0 | 4 | 17 | 0 | 0 | 0 | y |
link-preview |
Superficies · overlays · estado | 0% | 17 | 0 | 4 | 9 | 1 | 3 | 0 | y |
drag-drop |
Controles · marcas | 0% | 16 | 0 | 3 | 6 | 0 | 7 | 1 | – |
kbd |
Controles · marcas | 0% | 14 | 0 | 1 | 9 | 4 | 0 | 0 | – |
link |
Controles · marcas | 0% | 14 | 0 | 4 | 2 | 5 | 3 | 0 | – |
code |
Texto · tipografía | 0% | 13 | 0 | 6 | 3 | 4 | 0 | 0 | – |
virtual-list |
Menús · listas · navegación | 0% | 13 | 0 | 2 | 6 | 4 | 1 | 0 | y |
virtual-grid |
Menús · listas · navegación | 0% | 12 | 0 | 2 | 6 | 3 | 1 | 0 | y |
skeleton |
Superficies · overlays · estado | 0% | 11 | 0 | 9 | 1 | 1 | 0 | 0 | y |
skin-media-player |
Media · chat | 0% | 11 | 0 | 0 | 2 | 7 | 2 | 0 | y |
scroll-frames |
Superficies · overlays · estado | 0% | 9 | 0 | 1 | 4 | 4 | 0 | 0 | – |
announce |
Superficies · overlays · estado | 0% | 8 | 0 | 0 | 8 | 0 | 0 | 0 | – |
clipboard |
Controles · marcas | 0% | 8 | 0 | 2 | 5 | 1 | 0 | 0 | – |
label |
Campos | 0% | 8 | 0 | 6 | 2 | 0 | 0 | 0 | – |
menu-dial |
Menús · listas · navegación | 0% | 8 | 0 | 3 | 1 | 4 | 0 | 0 | y |
display |
Texto · tipografía | 0% | 6 | 0 | 6 | 0 | 0 | 0 | 0 | – |
mark |
Controles · marcas | 0% | 5 | 0 | 2 | 1 | 2 | 0 | 0 | – |
aspect-ratio |
Controles · marcas | 0% | 3 | 0 | 0 | 1 | 2 | 0 | 0 | – |
date-picker |
Tiempo (chronos · fecha/hora) | 0% | 2 | 0 | 0 | 0 | 2 | 0 | 0 | – |
sticky |
Superficies · overlays · estado | 0% | 2 | 0 | 1 | 0 | 1 | 0 | 1 | – |
text-blur |
Texto · tipografía | 0% | 2 | 0 | 0 | 0 | 2 | 0 | 0 | – |
cascade |
Menús · listas · navegación | 0% | 1 | 0 | 0 | 0 | 1 | 0 | 0 | – |
motion |
Superficies · overlays · estado | 0% | 1 | 0 | 0 | 0 | 1 | 0 | 0 | – |
section |
Layout (primitivos) | 0% | 1 | 0 | 0 | 0 | 1 | 0 | 4 | – |
chronos |
Tiempo (chronos · fecha/hora) | 1% | 245 | 2 | 22 | 202 | 12 | 7 | 9 | y |
prose |
Texto · tipografía | 1% | 74 | 1 | 0 | 43 | 30 | 0 | 2 | y |
nav-tree |
Menús · listas · navegación | 4% | 25 | 1 | 0 | 17 | 6 | 1 | 1 | – |
s-text |
Texto · tipografía | 7% | 30 | 2 | 28 | 0 | 0 | 0 | 3 | – |
chart |
Controles · marcas | 9% | 92 | 8 | 0 | 66 | 14 | 4 | 17 | – |
result |
Superficies · overlays · estado | 9% | 22 | 2 | 1 | 15 | 4 | 0 | 8 | – |
mockup |
Superficies · overlays · estado | 14% | 29 | 4 | 7 | 13 | 5 | 0 | 0 | – |
menubar |
Menús · listas · navegación | 15% | 27 | 4 | 6 | 16 | 0 | 1 | 5 | y |
anchor-nav |
Menús · listas · navegación | 20% | 11 | 2 | 0 | 8 | 0 | 1 | 2 | – |
banner |
Superficies · overlays · estado | 20% | 10 | 2 | 6 | 1 | 1 | 0 | 42 | y |
button |
Controles · marcas | 21% | 30 | 6 | 16 | 0 | 7 | 1 | 105 | y |
palabras |
WIP (tracks paralelos) | 22% | 471 | 103 | 1 | 272 | 90 | 5 | 0 | – |
toggle |
Controles · marcas | 22% | 28 | 6 | 17 | 1 | 3 | 1 | 119 | y |
date-range-field |
Tiempo (chronos · fecha/hora) | 25% | 9 | 2 | 0 | 4 | 2 | 1 | 3 | – |
time-range-field |
Tiempo (chronos · fecha/hora) | 25% | 9 | 2 | 0 | 4 | 2 | 1 | 3 | – |
surface |
Superficies · overlays · estado | 25% | 4 | 1 | 3 | 0 | 0 | 0 | 25 | – |
callout |
Superficies · overlays · estado | 27% | 15 | 4 | 3 | 7 | 1 | 0 | 28 | – |
meter |
Superficies · overlays · estado | 29% | 14 | 4 | 6 | 2 | 2 | 0 | 28 | y |
knob |
Controles · marcas | 29% | 27 | 7 | 4 | 9 | 4 | 3 | 0 | y |
onion-menu |
Menús · listas · navegación | 29% | 27 | 7 | 0 | 8 | 9 | 3 | 12 | – |
empty-state |
Superficies · overlays · estado | 29% | 17 | 5 | 7 | 5 | 0 | 0 | 6 | y |
search-field |
Campos | 31% | 14 | 4 | 5 | 0 | 4 | 1 | 17 | y |
password-field |
Campos | 31% | 36 | 11 | 5 | 9 | 10 | 1 | 23 | y |
aura |
Superficies · overlays · estado | 31% | 35 | 11 | 4 | 14 | 6 | 0 | 24 | y |
toggle-group |
Controles · marcas | 33% | 3 | 1 | 0 | 1 | 1 | 0 | 1 | – |
background |
Superficies · overlays · estado | 35% | 26 | 8 | 6 | 6 | 3 | 3 | 31 | – |
avatar |
Controles · marcas | 36% | 36 | 13 | 17 | 0 | 6 | 0 | 0 | y |
audio-player |
Media · chat | 37% | 19 | 7 | 0 | 8 | 4 | 0 | 5 | – |
tooltip |
Superficies · overlays · estado | 38% | 22 | 8 | 9 | 3 | 1 | 1 | 20 | y |
button-group |
Controles · marcas | 40% | 5 | 2 | 0 | 0 | 3 | 0 | 1 | – |
badge |
Controles · marcas | 41% | 22 | 9 | 10 | 1 | 2 | 0 | 65 | y |
popover |
Superficies · overlays · estado | 42% | 51 | 20 | 6 | 22 | 0 | 3 | 36 | y |
qr-code |
Controles · marcas | 43% | 7 | 3 | 0 | 0 | 4 | 0 | 10 | – |
navigation-menu |
Menús · listas · navegación | 44% | 38 | 15 | 1 | 13 | 5 | 4 | 26 | y |
waveform |
Media · chat | 45% | 11 | 5 | 1 | 1 | 4 | 0 | 10 | y |
color-picker |
Campos | 46% | 82 | 36 | 10 | 22 | 11 | 3 | 54 | y |
checkbox |
Controles · marcas | 48% | 34 | 16 | 12 | 2 | 3 | 1 | 45 | y |
progress |
Superficies · overlays · estado | 49% | 35 | 17 | 9 | 3 | 6 | 0 | 41 | y |
tag-group |
Controles · marcas | 49% | 46 | 21 | 21 | 0 | 1 | 3 | 91 | y |
color-swatch |
Controles · marcas | 50% | 10 | 5 | 2 | 3 | 0 | 0 | 12 | y |
text-scramble |
Texto · tipografía | 50% | 4 | 2 | 0 | 0 | 2 | 0 | 0 | – |
split-button |
Controles · marcas | 50% | 2 | 1 | 0 | 1 | 0 | 0 | 1 | y |
timeline |
Superficies · overlays · estado | 51% | 49 | 25 | 21 | 0 | 3 | 0 | 45 | y |
field |
Campos | 51% | 73 | 35 | 15 | 7 | 11 | 5 | 60 | y |
context-menu |
Menús · listas · navegación | 53% | 33 | 16 | 0 | 11 | 3 | 3 | 18 | – |
rating-group |
Controles · marcas | 53% | 16 | 8 | 4 | 1 | 2 | 1 | 25 | y |
metrics |
Controles · marcas | 54% | 50 | 27 | 10 | 9 | 4 | 0 | 68 | y |
sidebar |
Menús · listas · navegación | 55% | 45 | 23 | 0 | 14 | 5 | 3 | 50 | – |
drawer |
Superficies · overlays · estado | 55% | 62 | 33 | 9 | 13 | 5 | 2 | 44 | y |
color-field |
Campos | 56% | 16 | 9 | 0 | 2 | 5 | 0 | 22 | y |
image |
Controles · marcas | 57% | 35 | 20 | 2 | 1 | 12 | 0 | 22 | y |
dropdown-menu |
Menús · listas · navegación | 57% | 30 | 16 | 0 | 9 | 3 | 2 | 19 | – |
switch |
Controles · marcas | 57% | 22 | 12 | 8 | 1 | 0 | 1 | 52 | y |
s-text-virtual-list |
Menús · listas · navegación | 58% | 12 | 7 | 0 | 3 | 2 | 0 | 9 | – |
form |
Campos | 59% | 52 | 30 | 14 | 5 | 2 | 1 | 54 | y |
float-panel |
Superficies · overlays · estado | 59% | 53 | 29 | 3 | 12 | 5 | 4 | 28 | – |
slider |
Controles · marcas | 59% | 33 | 19 | 12 | 0 | 1 | 1 | 39 | y |
radio-cards |
Controles · marcas | 60% | 72 | 42 | 0 | 24 | 4 | 2 | 39 | y |
card |
Superficies · overlays · estado | 60% | 36 | 21 | 14 | 0 | 0 | 1 | 97 | y |
cropper |
Controles · marcas | 60% | 27 | 15 | 0 | 3 | 7 | 2 | 15 | – |
emoji-picker |
Campos | 61% | 32 | 17 | 0 | 8 | 3 | 4 | 17 | – |
pin-input |
Campos | 61% | 19 | 11 | 0 | 6 | 1 | 1 | 20 | y |
editable |
Campos | 63% | 44 | 25 | 12 | 1 | 2 | 4 | 56 | y |
text-focus |
Texto · tipografía | 63% | 8 | 5 | 0 | 1 | 2 | 0 | 0 | – |
spin-field |
Campos | 64% | 27 | 16 | 0 | 8 | 1 | 2 | 20 | – |
file-upload |
Campos | 64% | 61 | 38 | 16 | 1 | 4 | 2 | 98 | y |
tags-input |
Campos | 67% | 46 | 28 | 13 | 1 | 0 | 4 | 90 | y |
toolbar |
Menús · listas · navegación | 67% | 35 | 22 | 10 | 0 | 1 | 2 | 54 | y |
image-adjustments |
Controles · marcas | 67% | 18 | 10 | 0 | 4 | 1 | 3 | 12 | – |
text-gradient |
Texto · tipografía | 67% | 9 | 6 | 0 | 0 | 3 | 0 | 0 | – |
separator |
SIN FAMILIA | 67% | 6 | 4 | 0 | 0 | 2 | 0 | 3 | – |
select |
Campos | 69% | 72 | 45 | 14 | 3 | 3 | 7 | 101 | y |
dialog |
Superficies · overlays · estado | 70% | 33 | 23 | 5 | 4 | 1 | 0 | 37 | y |
image-picker |
Campos | 71% | 20 | 12 | 0 | 1 | 4 | 3 | 13 | – |
pagination |
Menús · listas · navegación | 71% | 26 | 17 | 7 | 0 | 0 | 2 | 34 | y |
stepper |
Menús · listas · navegación | 71% | 60 | 40 | 15 | 0 | 1 | 4 | 69 | y |
skip-link |
Superficies · overlays · estado | 71% | 8 | 5 | 0 | 0 | 2 | 1 | 8 | – |
date-field |
Tiempo (chronos · fecha/hora) | 73% | 11 | 8 | 3 | 0 | 0 | 0 | 21 | y |
time-field |
Tiempo (chronos · fecha/hora) | 73% | 11 | 8 | 3 | 0 | 0 | 0 | 21 | y |
calendar |
Tiempo (chronos · fecha/hora) | 75% | 71 | 51 | 13 | 0 | 4 | 3 | 76 | y |
accordion |
Superficies · overlays · estado | 77% | 65 | 49 | 10 | 0 | 5 | 1 | 76 | y |
radio-group |
Controles · marcas | 77% | 75 | 56 | 10 | 7 | 0 | 2 | 61 | y |
chat-log |
Media · chat | 77% | 42 | 30 | 0 | 4 | 5 | 3 | 31 | – |
chat-composer |
Media · chat | 79% | 44 | 31 | 0 | 3 | 5 | 5 | 31 | – |
chat-message |
Media · chat | 82% | 84 | 63 | 2 | 6 | 6 | 7 | 75 | y |
fab |
Controles · marcas | 82% | 17 | 14 | 0 | 2 | 1 | 0 | 10 | – |
toast |
Superficies · overlays · estado | 83% | 42 | 35 | 6 | 0 | 1 | 0 | 85 | – |
text-circular |
Texto · tipografía | 83% | 6 | 5 | 0 | 1 | 0 | 0 | 0 | – |
tabs |
Menús · listas · navegación | 88% | 76 | 66 | 6 | 2 | 1 | 1 | 79 | y |
chat-typing |
Media · chat | 89% | 9 | 8 | 0 | 1 | 0 | 0 | 7 | – |
breadcrumb |
Menús · listas · navegación | 90% | 23 | 18 | 2 | 0 | 0 | 3 | 28 | y |
collapsible |
Superficies · overlays · estado | 90% | 12 | 9 | 0 | 1 | 0 | 2 | 11 | – |
scroll-area |
Superficies · overlays · estado | 94% | 17 | 15 | 0 | 0 | 1 | 1 | 13 | – |
splitter |
Superficies · overlays · estado | 100% | 19 | 18 | 0 | 0 | 0 | 1 | 16 | – |
chat-list |
Media · chat | 100% | 18 | 18 | 0 | 0 | 0 | 0 | 18 | – |
box |
Layout (primitivos) | 100% | 9 | 9 | 0 | 0 | 0 | 0 | 43 | – |
barcode |
Controles · marcas | 100% | 5 | 5 | 0 | 0 | 0 | 0 | 7 | – |
flex |
Layout (primitivos) | 100% | 2 | 2 | 0 | 0 | 0 | 0 | 7 | – |
grid |
Layout (primitivos) | 100% | 2 | 2 | 0 | 0 | 0 | 0 | 13 | – |
alert-dialog |
Superficies · overlays · estado | — | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |
auto-grid |
Layout (primitivos) | — | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |
container |
Layout (primitivos) | — | 0 | 0 | 0 | 0 | 0 | 0 | 1 | – |
css-field |
Campos | — | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |
float |
Superficies · overlays · estado | — | 0 | 0 | 0 | 0 | 0 | 0 | 1 | – |
group |
Layout (primitivos) | — | 0 | 0 | 0 | 0 | 0 | 0 | 1 | – |
highlight |
Controles · marcas | — | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |
icon |
Controles · marcas | — | 0 | 0 | 0 | 0 | 0 | 0 | 2 | – |
mask-field |
Campos | — | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |
number-field |
Campos | — | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |
stack |
Layout (primitivos) | — | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |
wrap |
Layout (primitivos) | — | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |