You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/docs/audit/theming/chart.md

176 lines
10 KiB

docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
# chart — alcance de tema: análisis y propuesta
> Generado por `node --import tsx/esm scripts/theming-census.ts --report`.
> Lo **medido** y la **propuesta** se regeneran; el **Veredicto** (§5) se conserva.
> Vista de conjunto: [README](./README.md) · método y protocolo:
> [`PLAN-theming.md`](../../process/PLAN-theming.md) §1, §2, §7.
docs(theming): 164 fichas regeneradas — dos perdían prosa medida, y el generador es el culpable Una sesión regeneró todas las fichas de docs/audit/theming con el --report del censo y las dejó sucias en el árbol. Antes de commitearlas las clasifiqué una a una en vez de mirar la cifra: - 155 sólo cambiaban la FECHA de medida. Inocuo, y correcto: el censo corrió hoy. - 7 traían cifras nuevas y buenas (collapsible y toolbar, que acaban de cerrar) o retiraban una propuesta §4 ya cumplida. Mejora. - 2 —chat-log y chat-composer— BORRABAN prosa medida: donde un humano escribió «_Ninguno_ — los cuatro que había (el padding-block del divisor, el radio de foco de la fila de evento…) están cosidos», la plantilla dejaba «_Ninguno._», y en chat-composer se llevaba además el bloque de las cuatro declaraciones retiradas por muertas. Esas dos van cosidas: el cuerpo de HEAD con la línea de cabecera regenerada. El resto entra tal cual. Que la regeneración sea mayoritariamente buena y ocasionalmente destructiva es el peor reparto posible, porque nadie la mira. Registrado en §13 con su arreglo: extender los marcadores tipo veredicto:end a cualquier bloque que un humano haya ampliado, o que el generador respete una línea que no empiece por su propia plantilla. Mientras tanto, regenerar fichas y commitear sin leer el diff es una pérdida de datos silenciosa. Y con él, la hermana que reportó una sesión de la tanda: snapshot-y-restaura sobre un directorio COMPARTIDO pisa a quien escriba en medio. Dos sesiones hicieron cp -r de docs/audit/theming y la segunda restauró desde un snapshot anterior al trabajo de la primera, devolviéndole sus veredictos a «pendiente» a media faena. El árbol de trabajo también es compartido: respalda por FICHERO tocado, nunca por directorio. Quedan fuera a propósito las fichas de chat-message y tags-input: sus sesiones siguen trabajando. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Medido**: 2026-08-24 · **Alcance**: **89%** — 81 de 91 knobs por token público
tooling(theming): el censo aprende a leer la válvula del canon — clase `exception` Global 58 % → **59 %** sin tocar una línea de CSS: 54 knobs que eran deuda resultan ser desviaciones que el canon ya había firmado. `recipe-contract` §3 dice que una desviación anotada `/* literal: <razón> */` EN SU PROPIA DECLARACIÓN es válida, y `component-audit` la honra desde siempre (`declarationWindow` + `/literal:/i` en R-2.1, R-2.6 y R-2.7). El censo era el único instrumento que no: su `strip()` blanquea los comentarios ANTES de clasificar, así que las **81 anotaciones del catálogo** contaban como literales sin excusa. Dos instrumentos, un canon, dos respuestas — y la que mandaba era la del que no sabía leerlo. Ahora un literal anotado cae en la clase **`exception`, fuera del ratio** como `system`, 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**: `prose` 21 (su escala editorial em-relativa, que su README documenta como decisión — «No 5× duplicated scale»), `proof-of-human` 16 (la escena de tono fijo), `palabras` 3, `timeline` 2 (73 % → **77 %**), `result` 1 (86 % → **90 %**), y siete más con una cada uno. Detalles que costaron medición: - **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. Se comprueban todas las líneas que abarca la declaración. - **`strip()` blanquea en el sitio** (sustituye por espacios, conserva los saltos), así que el cuerpo despojado y el crudo quedan alineados línea a línea y basta con guardar el crudo al lado. - Muta-prueba: retirar una anotación de `prose` mueve el knob de `exception` a `literal` (21 → 20) y el conteo vuelve al restaurarla. Efecto colateral bueno: cada ficha gana una **§1.4 «Excepciones firmadas»** que las LISTA con su razón. Estaban escritas en el CSS y no se leían desde ninguna parte; ahora la ficha del componente las enseña, que es donde se decide si una sigue siendo cierta. Las 163 fichas cambian porque la plantilla cambia (sección nueva + la línea de reparto); el README de la auditoría gana la fila de la clase y la nota de que `system` y `exception` quedan fuera del denominador. Guards: `--names` 4.105 claves, DESVIADAS 0 · component-audit PASS · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Knobs de apariencia**: 95 — público 81 · privado 0 · global 0 · literal 10 · sistema 4 · excepción 0 _(los dos últimos, fuera del ratio)_
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Contrato hoy** (`lib/recipes/base.ts`): 45 pública(s) — `line-width`, `axis-width`, `grid-width`, `bar-radius`, `point-radius`, `area-opacity`, `slice-stroke-width`, `transition-duration`, `transition-ease`, `tooltip-bg`, `tooltip-border`, `tooltip-radius`, `tooltip-shadow`, `tooltip-padding`, `tooltip-gap`, `crosshair-fg`, `crosshair-width`, `caption-font-size`, `caption-fg`, `label-font-size`, `label-fg`, `label-font-weight`, `gauge-label-font-size`, `axis-fg`, `grid-fg`, `separator-fg`, `smith-boundary-fg`, `track-bg`, `track-height`, `track-radius`, `gap`, `legend-row-gap`, `legend-column-gap`, `legend-item-gap`, `swatch-size`, `swatch-radius`, `tooltip-swatch-size`, `bar-list-row-gap`, `bar-list-column-gap`, `bar-segment-gap`, `bar-segment-track-gap`, `bar-segment-track-radius`, `bar-segment-fill-min-inline-size`, `bar-segment-legend-row-gap`, `bar-segment-legend-column-gap`
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Eje `size`**: no · **ficheros**: `chart.css`
## 1. Knobs fuera de alcance
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 1.1 Directo a primitivo global (0)
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
_Ninguno._
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 1.2 A través de un privado (0)
_Ninguno._
uix(chart): temable — 9 % → 49 %, y la ficha pedía 71 claves de las que 20 llevaban el mismo valor 22 claves nuevas fusionadas en el bloque existente (17 → 39). Censo chart 9 % → **49 %**; global **56 % → 57 %** (2.638 → 2.675 públicos; <20 % 19 → 18). LO QUE DECIDIÓ LA MEDICIÓN, no la ficha: Las 84 filas fuera de alcance colapsaban 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`, 4× `radius-sm`. Nombrar por parte habría dado cinco claves para el pelo que separa marcas y nueve para la tinta de anotación: la inflación de `spinner` con otra cara. **El texto no recibe tokens de chart.** Toma su ROL DE TAMAÑO de los estilos con nombre del canon —`caption` (xs) para las anotaciones, `label` (sm) para el texto de cromo— y su tinta y su peso de las ranuras del sistema. Acuñar `--chart-label-font-size` sería tipografía por componente, prohibido el mismo día para text-effects. Precedente de consumir la capa: `code-block`, `kbd`, `announce`. Doce declaraciones cambian de `var(--font-size-xs|sm)` a `var(--style-caption|label-font-size)`, mismo valor. **La receta sólo posee la tinta de lo que NO es texto**, cinco claves y cada una un concepto que el CSS repite: `axis-fg` (eje + rejilla smith + conector del funnel), `grid-fg` (rejilla + radar), `separator-fg` (el pelo de superficie entre marcas contiguas: porción, punto activo, punto smith, pétalo, segmento), `smith-boundary-fg` y `track-bg` (raíl del bar-list y del gauge). Más 17 de geometría de cromo (gap, los pares row/column-gap, swatch, track, bar-segment). **Incumplimiento heredado, corregido**: el CSS leía la coordenada CRUDA `var(--control-height-sm, var(--space-7))` —lo que `recipe-css-contract` prohíbe— con un respaldo muerto. El contrato guarda el bundle `var(--size-sm-control-height)`, 1:1 con él. **Identidad fuera de contrato**: los nueve `100%` («ocupa a tu padre») y el `min-inline-size: max-content` del tooltip, misma clase ya adjudicada en `date-picker`. Por eso el techo es 49 %, y está escrito en el veredicto §5. EL INSTRUMENTO ESTABA CIEGO DE TRES MANERAS, arregladas ANTES de medir: 1. **La superficie de chart vive en DIECISÉIS rutas de demo**, una por tipo: `/chart` monta 58 nodos de los 302 de la página y el resto vive en rutas hermanas. El guard gana `urls`: un token está VIVO si ALGUNA superficie del componente lo sigue, y cada URL sólo re-prueba lo pendiente (el caso de una sola ruta cuesta exactamente lo que costaba). De paso `picker-shell` recibe la suya: su ruta propia es un 404 y se mide dentro del date-picker — pasa de 0/31 con seis sin adjudicar a 6/31 sin tener que saberlo. 2. **El guard no leía NINGUNA propiedad SVG.** Sin `fill` / `stroke` / `strokeWidth` / `fillOpacity` / `r` / `rx`, doce de las 39 claves de un componente que dibuja en SVG leían muertas estando vivas. Misma clase que el hueco de `filter` / `backdrop-filter` de ayer. 3. **El valor centinela se elegía por SUBCADENA**: `slice-stroke-width` recibía `rgb(1, 2, 3)` por contener «stroke» —inválido para una longitud— y leía muerta. La dimensión se decide ahora por el FINAL del nombre. Los 28 componentes con ledger re-verificados tras los tres cambios: cero regresiones, cero STALE. (Ojo: doce a la vez contra el mismo dev server dan falsos exit=1 por timeout; repetir a solas antes de creerse una regresión.) Gates: sonda **0 diffs en 161.850 valores computados** (16 rutas × 7 estados, 892 nodos en reposo) · centinela **37/39**, con `transition-duration` y `-ease` adjudicadas midiéndolas sin la congelación (0,12s → 11,5s · cubic-bezier → steps(4)) · censo --only 49 % · --names 39/39 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido (`skin-media-player`) · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Abre (→ next-features §13): el censo **penaliza consumir la capa tipográfica** si no eres un primitivo —las doce declaraciones correctas siguen contando `global`—, que es la nota de `listbox` con una segunda ocurrencia; y el número del gauge no tiene estilo con nombre que lo represente (un readout de dato no es un `h2`), así que sigue leyendo `--font-size-xl`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 1.3 Literales (10)
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| 1 | `chart.css:27` | `[data-chart-frame]` | `inline-size` | `100%` |
| 2 | `chart.css:31` | `[data-chart-plot]` | `inline-size` | `100%` |
| 3 | `chart.css:37` | `[data-chart]` | `inline-size` | `100%` |
| 4 | `chart.css:47` | `[data-chart-empty]` | `block-size` | `100%` |
| 5 | `chart.css:137` | `[data-chart-tooltip]` | `min-inline-size` | `max-content` |
| 6 | `chart.css:173` | `[data-chart-figure]` | `inline-size` | `100%` |
| 7 | `chart.css:217` | `[data-chart-bar-list]` | `inline-size` | `100%` |
| 8 | `chart.css:239` | `[data-chart-bar-list-bar]` | `block-size` | `100%` |
| 9 | `chart.css:256` | `[data-chart-bar-segment]` | `inline-size` | `100%` |
| 10 | `chart.css:266` | `[data-chart-bar-segment-fill]` | `block-size` | `100%` |
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
tooling(theming): el censo aprende a leer la válvula del canon — clase `exception` Global 58 % → **59 %** sin tocar una línea de CSS: 54 knobs que eran deuda resultan ser desviaciones que el canon ya había firmado. `recipe-contract` §3 dice que una desviación anotada `/* literal: <razón> */` EN SU PROPIA DECLARACIÓN es válida, y `component-audit` la honra desde siempre (`declarationWindow` + `/literal:/i` en R-2.1, R-2.6 y R-2.7). El censo era el único instrumento que no: su `strip()` blanquea los comentarios ANTES de clasificar, así que las **81 anotaciones del catálogo** contaban como literales sin excusa. Dos instrumentos, un canon, dos respuestas — y la que mandaba era la del que no sabía leerlo. Ahora un literal anotado cae en la clase **`exception`, fuera del ratio** como `system`, 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**: `prose` 21 (su escala editorial em-relativa, que su README documenta como decisión — «No 5× duplicated scale»), `proof-of-human` 16 (la escena de tono fijo), `palabras` 3, `timeline` 2 (73 % → **77 %**), `result` 1 (86 % → **90 %**), y siete más con una cada uno. Detalles que costaron medición: - **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. Se comprueban todas las líneas que abarca la declaración. - **`strip()` blanquea en el sitio** (sustituye por espacios, conserva los saltos), así que el cuerpo despojado y el crudo quedan alineados línea a línea y basta con guardar el crudo al lado. - Muta-prueba: retirar una anotación de `prose` mueve el knob de `exception` a `literal` (21 → 20) y el conteo vuelve al restaurarla. Efecto colateral bueno: cada ficha gana una **§1.4 «Excepciones firmadas»** que las LISTA con su razón. Estaban escritas en el CSS y no se leían desde ninguna parte; ahora la ficha del componente las enseña, que es donde se decide si una sigue siendo cierta. Las 163 fichas cambian porque la plantilla cambia (sección nueva + la línea de reparto); el README de la auditoría gana la fila de la clase y la nota de que `system` y `exception` quedan fuera del denominador. Guards: `--names` 4.105 claves, DESVIADAS 0 · component-audit PASS · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 1.4 Excepciones firmadas (0) — fuera del ratio
Literales que llevan su anotación `/* literal: <razón> */` en la propia
declaración: la válvula de recipe-contract §3, la misma que honra
`component-audit`. **Una desviación firmada no es deuda** — se listan para que la
razón se lea, no para acuñarlas.
_Ninguno._
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
## 2. Sistema transversal (4) — informativo, fuera del ratio
Un tema los alcanza **a nivel de sistema**, por diseño (recipe-contract §2).
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| 1 | `chart.css:273` | `[data-chart-bar-segment-fill][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 2 | `chart.css:315` | `[data-chart-heat-cell][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 3 | `chart.css:323` | `[data-chart-cal-cell][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 4 | `chart.css:363` | `[data-chart-polar-petal][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
## 3. Privados de la receta — ¿de dónde sale su valor?
_La receta no declara privados propios en su CSS._
## 4. Propuesta de corrección
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (1)
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
Valor **verbatim** del CSS de hoy: el default no se mueve, sólo cambia quién
puede moverlo. Nombres derivados de recipe-contract §1 (ejes lógicos, talla
al final) y theming §6.7 (slots de color, modificador delante). Un token con
DOS valores distintos es una colisión de nombre: son dos knobs, o el nombre
no distingue lo que debería — se marca `⚠`.
| token (`--chart-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
| `tooltip-width` | `root` | `max-content` | 1 |
### 4.2 Sin nombre mecánico (9)
- **⚠ decisión: `100%` es un valor identidad o geometría de layout, no un knob de tema — el perímetro de «knob» es D-TH.2, sin firmar** — 9: `inline-size`, `block-size`.
### 4.4 Lo que hay que comprobar a mano (PLAN-theming §1.3 · §7.4)
- [ ] **Privado que no deriva de un público** — §3 lo marca; el privado debe leer el público o desaparecer.
- [ ] **Velo o acento en el nodo equivocado** (`archetype: 'item'` en un envoltorio, un `background` en shorthand que mata la capa de estado) — se mide desde el píxel hacia arriba.
- [ ] **Doble animación** al mover un sello a una superficie con animación propia — registro de `animationstart`/`animationend`.
- [ ] **Diff de computed = 0** en reposo · hover · abierto · disabled · foco, por talla, antes y después.
- [ ] **Centinela por token nuevo**: valor imposible en el root → el nodo lo sigue. Si no, el token miente.
## 5. Veredicto
<!-- veredicto:start -->
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**EJECUTADO 2026-08-22 — 9 % → 49 % → 89 %**, en dos pasadas: 22 claves de
tinta-no-texto y geometría, y luego **6 de COSTURA para el texto**. El 89 % es
el techo: lo que queda fuera son los diez literales de identidad.
uix(chart): temable — 9 % → 49 %, y la ficha pedía 71 claves de las que 20 llevaban el mismo valor 22 claves nuevas fusionadas en el bloque existente (17 → 39). Censo chart 9 % → **49 %**; global **56 % → 57 %** (2.638 → 2.675 públicos; <20 % 19 → 18). LO QUE DECIDIÓ LA MEDICIÓN, no la ficha: Las 84 filas fuera de alcance colapsaban 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`, 4× `radius-sm`. Nombrar por parte habría dado cinco claves para el pelo que separa marcas y nueve para la tinta de anotación: la inflación de `spinner` con otra cara. **El texto no recibe tokens de chart.** Toma su ROL DE TAMAÑO de los estilos con nombre del canon —`caption` (xs) para las anotaciones, `label` (sm) para el texto de cromo— y su tinta y su peso de las ranuras del sistema. Acuñar `--chart-label-font-size` sería tipografía por componente, prohibido el mismo día para text-effects. Precedente de consumir la capa: `code-block`, `kbd`, `announce`. Doce declaraciones cambian de `var(--font-size-xs|sm)` a `var(--style-caption|label-font-size)`, mismo valor. **La receta sólo posee la tinta de lo que NO es texto**, cinco claves y cada una un concepto que el CSS repite: `axis-fg` (eje + rejilla smith + conector del funnel), `grid-fg` (rejilla + radar), `separator-fg` (el pelo de superficie entre marcas contiguas: porción, punto activo, punto smith, pétalo, segmento), `smith-boundary-fg` y `track-bg` (raíl del bar-list y del gauge). Más 17 de geometría de cromo (gap, los pares row/column-gap, swatch, track, bar-segment). **Incumplimiento heredado, corregido**: el CSS leía la coordenada CRUDA `var(--control-height-sm, var(--space-7))` —lo que `recipe-css-contract` prohíbe— con un respaldo muerto. El contrato guarda el bundle `var(--size-sm-control-height)`, 1:1 con él. **Identidad fuera de contrato**: los nueve `100%` («ocupa a tu padre») y el `min-inline-size: max-content` del tooltip, misma clase ya adjudicada en `date-picker`. Por eso el techo es 49 %, y está escrito en el veredicto §5. EL INSTRUMENTO ESTABA CIEGO DE TRES MANERAS, arregladas ANTES de medir: 1. **La superficie de chart vive en DIECISÉIS rutas de demo**, una por tipo: `/chart` monta 58 nodos de los 302 de la página y el resto vive en rutas hermanas. El guard gana `urls`: un token está VIVO si ALGUNA superficie del componente lo sigue, y cada URL sólo re-prueba lo pendiente (el caso de una sola ruta cuesta exactamente lo que costaba). De paso `picker-shell` recibe la suya: su ruta propia es un 404 y se mide dentro del date-picker — pasa de 0/31 con seis sin adjudicar a 6/31 sin tener que saberlo. 2. **El guard no leía NINGUNA propiedad SVG.** Sin `fill` / `stroke` / `strokeWidth` / `fillOpacity` / `r` / `rx`, doce de las 39 claves de un componente que dibuja en SVG leían muertas estando vivas. Misma clase que el hueco de `filter` / `backdrop-filter` de ayer. 3. **El valor centinela se elegía por SUBCADENA**: `slice-stroke-width` recibía `rgb(1, 2, 3)` por contener «stroke» —inválido para una longitud— y leía muerta. La dimensión se decide ahora por el FINAL del nombre. Los 28 componentes con ledger re-verificados tras los tres cambios: cero regresiones, cero STALE. (Ojo: doce a la vez contra el mismo dev server dan falsos exit=1 por timeout; repetir a solas antes de creerse una regresión.) Gates: sonda **0 diffs en 161.850 valores computados** (16 rutas × 7 estados, 892 nodos en reposo) · centinela **37/39**, con `transition-duration` y `-ease` adjudicadas midiéndolas sin la congelación (0,12s → 11,5s · cubic-bezier → steps(4)) · censo --only 49 % · --names 39/39 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido (`skin-media-player`) · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Abre (→ next-features §13): el censo **penaliza consumir la capa tipográfica** si no eres un primitivo —las doce declaraciones correctas siguen contando `global`—, que es la nota de `listbox` con una segunda ocurrencia; y el número del gauge no tiene estilo con nombre que lo represente (un readout de dato no es un `h2`), así que sigue leyendo `--font-size-xl`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**La propuesta §4 pedía 71 claves y habría escrito ~20 con el MISMO valor.** La
medición que lo decidió: las 84 filas fuera de alcance colapsaban a **26 valores
feat(color)!: una palabra, un significado - primary/secondary son SIEMPRE jerarquia La homonimia muere: `primary`/`secondary` significan JERARQUIA DE MARCA en el catalogo ENTERO, tambien dentro de los seis primitivos de tinta (text, heading, display, code, label, s-text). El paso de tinta del 82 % se llama `subtle` - PROP y TOKEN, sin excepcion: el nombre es el contrato en el artefacto (la misma ley que la FIRMA B' y la 12.9; se rechazo por escrito la via "solo el prop con tabla de traduccion" - las excepciones legitimas son las FIRMADAS con razon, no las inventadas al decidir para abaratar). - Los seis CONTENT_INK, IDENTICOS: {subtle, muted, disabled, on-solid}; el nivel-1 es el DEFAULT sin prop. `label` gana `on-solid` (cierra la divergencia de familia registrada en e4fa616e5). - Renombre completo: --color-content-secondary -> --color-content-subtle y la clave de config content.secondary -> content.subtle (RUPTURA de API de tema). 355 referencias por patrones acotados; la raiz SIN prefijo (cssVar('color-content-secondary'), render-css.ts) incluida; en grafito.ts conviven tres claves `subtle` (content/border/shadow) y solo cambio content. El generado, reproducido BYTE A BYTE aplicando solo el renombre al anterior. - Codemod value-preserving: 11 call sites (6 secondary->subtle incl. expresiones y ternarias; 5 primary->fuera, incl. TRES defaults de prop) con la condicion ROJA caracterizada (--style-caption-color es el UNICO estilo cuya tinta default no es primary; los 5 sitios caen en ramas body). alpha/ (untracked, TERMINATED) fuera. - Las 6 demos migradas al vocabulario nuevo (s-text: CERO cambios, no tiene lista de tinta); label arranca en el default y pinta IDENTICO (contrafactual medido: el estado viejo habria pintado el morado de marca). - Neutra en pixel, MEDIDO: nivel 1 ESTRICTO CERO en 71.200 valores (blocks enteros, s-text entero, subarboles data-*); nivel 2: 31 diffs, todos trazados a las ediciones firmadas del harness (anchos de chips, reindexado de la lista de label con las tintas supervivientes byte a byte). Total 171.712 valores + 59.072 de re-corridas a 0 de ruido. - Guards: CONTENT_INK identicos entre los seis y sin nombres de rol (mutacion: muerde), y el generado sin rastro del token viejo con las 6 definiciones del nuevo. Dos cronicas fechadas en docs/old-deprecated, intactas a proposito. - Docs: changelog 54 - reference (eje de tinta) - next-features 13 (divergencia de label RESUELTA). Supervision: verificador independiente pre-firma (dos claims MURIERON en verificacion antes de tocar codigo), tres agentes en fases (censo+baseline -> implementacion+codemod -> demos -> verificacion de dos niveles -> docs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 months ago
distintos** — 9× `content-subtle`, 9× `content-primary`, 9× `100%`, 6×
uix(chart): temable — 9 % → 49 %, y la ficha pedía 71 claves de las que 20 llevaban el mismo valor 22 claves nuevas fusionadas en el bloque existente (17 → 39). Censo chart 9 % → **49 %**; global **56 % → 57 %** (2.638 → 2.675 públicos; <20 % 19 → 18). LO QUE DECIDIÓ LA MEDICIÓN, no la ficha: Las 84 filas fuera de alcance colapsaban 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`, 4× `radius-sm`. Nombrar por parte habría dado cinco claves para el pelo que separa marcas y nueve para la tinta de anotación: la inflación de `spinner` con otra cara. **El texto no recibe tokens de chart.** Toma su ROL DE TAMAÑO de los estilos con nombre del canon —`caption` (xs) para las anotaciones, `label` (sm) para el texto de cromo— y su tinta y su peso de las ranuras del sistema. Acuñar `--chart-label-font-size` sería tipografía por componente, prohibido el mismo día para text-effects. Precedente de consumir la capa: `code-block`, `kbd`, `announce`. Doce declaraciones cambian de `var(--font-size-xs|sm)` a `var(--style-caption|label-font-size)`, mismo valor. **La receta sólo posee la tinta de lo que NO es texto**, cinco claves y cada una un concepto que el CSS repite: `axis-fg` (eje + rejilla smith + conector del funnel), `grid-fg` (rejilla + radar), `separator-fg` (el pelo de superficie entre marcas contiguas: porción, punto activo, punto smith, pétalo, segmento), `smith-boundary-fg` y `track-bg` (raíl del bar-list y del gauge). Más 17 de geometría de cromo (gap, los pares row/column-gap, swatch, track, bar-segment). **Incumplimiento heredado, corregido**: el CSS leía la coordenada CRUDA `var(--control-height-sm, var(--space-7))` —lo que `recipe-css-contract` prohíbe— con un respaldo muerto. El contrato guarda el bundle `var(--size-sm-control-height)`, 1:1 con él. **Identidad fuera de contrato**: los nueve `100%` («ocupa a tu padre») y el `min-inline-size: max-content` del tooltip, misma clase ya adjudicada en `date-picker`. Por eso el techo es 49 %, y está escrito en el veredicto §5. EL INSTRUMENTO ESTABA CIEGO DE TRES MANERAS, arregladas ANTES de medir: 1. **La superficie de chart vive en DIECISÉIS rutas de demo**, una por tipo: `/chart` monta 58 nodos de los 302 de la página y el resto vive en rutas hermanas. El guard gana `urls`: un token está VIVO si ALGUNA superficie del componente lo sigue, y cada URL sólo re-prueba lo pendiente (el caso de una sola ruta cuesta exactamente lo que costaba). De paso `picker-shell` recibe la suya: su ruta propia es un 404 y se mide dentro del date-picker — pasa de 0/31 con seis sin adjudicar a 6/31 sin tener que saberlo. 2. **El guard no leía NINGUNA propiedad SVG.** Sin `fill` / `stroke` / `strokeWidth` / `fillOpacity` / `r` / `rx`, doce de las 39 claves de un componente que dibuja en SVG leían muertas estando vivas. Misma clase que el hueco de `filter` / `backdrop-filter` de ayer. 3. **El valor centinela se elegía por SUBCADENA**: `slice-stroke-width` recibía `rgb(1, 2, 3)` por contener «stroke» —inválido para una longitud— y leía muerta. La dimensión se decide ahora por el FINAL del nombre. Los 28 componentes con ledger re-verificados tras los tres cambios: cero regresiones, cero STALE. (Ojo: doce a la vez contra el mismo dev server dan falsos exit=1 por timeout; repetir a solas antes de creerse una regresión.) Gates: sonda **0 diffs en 161.850 valores computados** (16 rutas × 7 estados, 892 nodos en reposo) · centinela **37/39**, con `transition-duration` y `-ease` adjudicadas midiéndolas sin la congelación (0,12s → 11,5s · cubic-bezier → steps(4)) · censo --only 49 % · --names 39/39 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido (`skin-media-player`) · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Abre (→ next-features §13): el censo **penaliza consumir la capa tipográfica** si no eres un primitivo —las doce declaraciones correctas siguen contando `global`—, que es la nota de `listbox` con una segunda ocurrencia; y el número del gauge no tiene estilo con nombre que lo represente (un readout de dato no es un `h2`), así que sigue leyendo `--font-size-xl`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
`font-size-sm`, 6× `font-size-xs`, 6× `font-weight-medium`, 5×
`surface-default`, 4× `radius-sm`, 3× `border-default`. Nombrar por parte
habría dado cinco claves para el pelo que separa marcas y nueve para la tinta
de anotación. Es la inflación que F2-B ya cazó en `spinner`, con otra forma.
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**El texto adopta DOS ROLES del canon, con costura** (firmado 2026-08-22). La
primera pasada dejó el CSS leyendo `var(--style-caption-font-size)` y
`var(--color-content-*)` a pelo: el VALOR era correcto pero faltaba la costura
que PLAN §2-A exige —todo knob lee `--{c}-{slot}`—, y sin ella un tema no puede
aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app,
ni `getRecipeTokens()` ve esa superficie. Seis claves:
```
--chart-caption-font-size var(--style-caption-font-size) eje · leyenda · tooltip · smith
--chart-caption-fg var(--style-caption-color)
--chart-label-font-size var(--style-label-font-size) título · bar-list · funnel · empty
--chart-label-fg var(--style-label-color)
--chart-label-font-weight var(--style-label-font-weight) los seis nodos en medium
--chart-gauge-label-font-size var(--size-xl-font-size) el readout, sin rol en el canon
```
Es el molde que la propia vertebración tipográfica documenta
(`--accordion-trigger-font-family: var(--style-label-font-family)`), y NO el
alias que §39 mató: aquello espejaba 36 claves de una capa; esto acuña **una
costura por eje**, tres ejes sobre 19 nodos de texto. **Tamaño y tinta son
ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con
tinta `caption`, y el CSS lo dice.
D-TH.2 no aplica aquí y su propio texto lo aclara: los seis primitivos
tipográficos quedan fuera porque la capa ES su API, y «un componente que sólo
LEE un named style para un eje no es un primitivo y no está en el conjunto».
**Con la costura, `global` cae a CERO** y el alcance a 89 %. La nota que dejé
en §13 diciendo que el censo penalizaba hacer lo correcto era mía y estaba
equivocada: el censo medía bien, faltaba la costura.
uix(chart): temable — 9 % → 49 %, y la ficha pedía 71 claves de las que 20 llevaban el mismo valor 22 claves nuevas fusionadas en el bloque existente (17 → 39). Censo chart 9 % → **49 %**; global **56 % → 57 %** (2.638 → 2.675 públicos; <20 % 19 → 18). LO QUE DECIDIÓ LA MEDICIÓN, no la ficha: Las 84 filas fuera de alcance colapsaban 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`, 4× `radius-sm`. Nombrar por parte habría dado cinco claves para el pelo que separa marcas y nueve para la tinta de anotación: la inflación de `spinner` con otra cara. **El texto no recibe tokens de chart.** Toma su ROL DE TAMAÑO de los estilos con nombre del canon —`caption` (xs) para las anotaciones, `label` (sm) para el texto de cromo— y su tinta y su peso de las ranuras del sistema. Acuñar `--chart-label-font-size` sería tipografía por componente, prohibido el mismo día para text-effects. Precedente de consumir la capa: `code-block`, `kbd`, `announce`. Doce declaraciones cambian de `var(--font-size-xs|sm)` a `var(--style-caption|label-font-size)`, mismo valor. **La receta sólo posee la tinta de lo que NO es texto**, cinco claves y cada una un concepto que el CSS repite: `axis-fg` (eje + rejilla smith + conector del funnel), `grid-fg` (rejilla + radar), `separator-fg` (el pelo de superficie entre marcas contiguas: porción, punto activo, punto smith, pétalo, segmento), `smith-boundary-fg` y `track-bg` (raíl del bar-list y del gauge). Más 17 de geometría de cromo (gap, los pares row/column-gap, swatch, track, bar-segment). **Incumplimiento heredado, corregido**: el CSS leía la coordenada CRUDA `var(--control-height-sm, var(--space-7))` —lo que `recipe-css-contract` prohíbe— con un respaldo muerto. El contrato guarda el bundle `var(--size-sm-control-height)`, 1:1 con él. **Identidad fuera de contrato**: los nueve `100%` («ocupa a tu padre») y el `min-inline-size: max-content` del tooltip, misma clase ya adjudicada en `date-picker`. Por eso el techo es 49 %, y está escrito en el veredicto §5. EL INSTRUMENTO ESTABA CIEGO DE TRES MANERAS, arregladas ANTES de medir: 1. **La superficie de chart vive en DIECISÉIS rutas de demo**, una por tipo: `/chart` monta 58 nodos de los 302 de la página y el resto vive en rutas hermanas. El guard gana `urls`: un token está VIVO si ALGUNA superficie del componente lo sigue, y cada URL sólo re-prueba lo pendiente (el caso de una sola ruta cuesta exactamente lo que costaba). De paso `picker-shell` recibe la suya: su ruta propia es un 404 y se mide dentro del date-picker — pasa de 0/31 con seis sin adjudicar a 6/31 sin tener que saberlo. 2. **El guard no leía NINGUNA propiedad SVG.** Sin `fill` / `stroke` / `strokeWidth` / `fillOpacity` / `r` / `rx`, doce de las 39 claves de un componente que dibuja en SVG leían muertas estando vivas. Misma clase que el hueco de `filter` / `backdrop-filter` de ayer. 3. **El valor centinela se elegía por SUBCADENA**: `slice-stroke-width` recibía `rgb(1, 2, 3)` por contener «stroke» —inválido para una longitud— y leía muerta. La dimensión se decide ahora por el FINAL del nombre. Los 28 componentes con ledger re-verificados tras los tres cambios: cero regresiones, cero STALE. (Ojo: doce a la vez contra el mismo dev server dan falsos exit=1 por timeout; repetir a solas antes de creerse una regresión.) Gates: sonda **0 diffs en 161.850 valores computados** (16 rutas × 7 estados, 892 nodos en reposo) · centinela **37/39**, con `transition-duration` y `-ease` adjudicadas midiéndolas sin la congelación (0,12s → 11,5s · cubic-bezier → steps(4)) · censo --only 49 % · --names 39/39 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido (`skin-media-player`) · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Abre (→ next-features §13): el censo **penaliza consumir la capa tipográfica** si no eres un primitivo —las doce declaraciones correctas siguen contando `global`—, que es la nota de `listbox` con una segunda ocurrencia; y el número del gauge no tiene estilo con nombre que lo represente (un readout de dato no es un `h2`), así que sigue leyendo `--font-size-xl`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**Lo que la receta sí posee: la tinta de lo que no es texto** — cinco claves,
cada una un concepto que el CSS repite: `axis-fg` (eje + rejilla smith +
conector del funnel), `grid-fg` (rejilla + radar), `separator-fg` (el pelo de
superficie entre marcas contiguas: porción, punto activo, punto smith, pétalo,
segmento), `smith-boundary-fg` (el borde del disco, más fuerte a propósito) y
`track-bg` (raíl del bar-list y del gauge). Más 17 de geometría de cromo.
**Un incumplimiento heredado, corregido**: el CSS leía
`var(--control-height-sm, var(--space-7))` — coordenada CRUDA, que
`recipe-css-contract` prohíbe en un token de receta, con un respaldo muerto (el
primitivo existe). El contrato guarda `var(--size-sm-control-height)`, el
bundle, que es 1:1 con él.
**Fuera de contrato por identidad** (los 10 literales): nueve `100%` que
significan «ocupa a tu padre» y el `min-inline-size: max-content` del tooltip,
que es la corrección de composición de la misma clase ya adjudicada en
`date-picker`. Moverlos no es tematizar, es romper el layout.
uix(chart): la COSTURA del texto — 49 % → 89 %, y `global` a cero Seis claves. El valor sigue siendo el del canon; lo que faltaba era el knob. CORRIGE MI LECTURA DE HACE DOS HORAS. Al tokenizar chart di por doctrina que «el texto no recibe tokens del componente» porque su valor viene de la capa de estilos con nombre, y dejé el CSS leyendo `var(--style-caption-font-size)` y `var(--color-content-*)` A PELO. Eso es media doctrina: PLAN §2-A pide que TODO knob de apariencia lea `--{c}-{slot}`. Sin la costura, un tema no puede aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app, y `getRecipeTokens()` / `/temas` no 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 y no está en el conjunto». POR ROL, NO POR PARTE — y se decidió midiendo: --chart-caption-font-size var(--style-caption-font-size) --chart-caption-fg var(--style-caption-color) --chart-label-font-size var(--style-label-font-size) --chart-label-fg var(--style-label-color) --chart-label-font-weight var(--style-label-font-weight) --chart-gauge-label-font-size var(--size-xl-font-size) Dos roles × tres ejes = 6 claves para 19 nodos de texto; nombrarlo por parte habrían sido ~30 claves con dos valores. **Tamaño y tinta son ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con tinta `caption`, y el CSS lo dice. El readout del gauge no tiene rol en el canon —un `h2` es un encabezado, no un dato— así que su costura toma el bundle de talla; con eso se cierra la escotilla que dejé abierta en el commit anterior. Tres nombres de mi primera propuesta no aguantaron la revisión y no entran: `label-font-size` a secas chocaba con las seis partes `*-label` del componente (se acepta el choque, pero nombrando por el ROL del canon, que dice la verdad: las etiquetas de eje SON captions), `emphasis-*` inventaba vocabulario fuera de §1/§6.7, y `fg-muted` se apoyaba en un único precedente. La tinta lee el color DEL ROL (`var(--style-caption-color)`), no la ranura a pelo. Y RETIRA UNA NOTA EQUIVOCADA DE §13: escribí que el censo penalizaba consumir la capa tipográfica cuando no eres un primitivo. El censo medía bien; faltaba la costura. Con ella, `global` cae a CERO y el alcance a 89 % — el techo, porque lo que queda son los diez literales de identidad (nueve `100%` + el `max-content` del tooltip). La lección queda escrita: cuando la métrica y la doctrina discrepan, sospecha de la lectura antes que del instrumento. `listbox` (68 %, ritmo de fila prestado de `list-surface`) es la misma pregunta un piso más arriba y queda pendiente de revisar con este molde. Gates: sonda antes/después **0 diffs en 161.850 valores computados** (16 rutas × 7 estados) · centinela **43/45**, las dos de transición adjudicadas · censo --only **89 %** con `global` 36 → 0 · --names 45/45 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**La escotilla del gauge, cerrada**: su número es un READOUT de dato y ningún
estilo con nombre juega ese papel (un `h2` es un encabezado), así que su
costura toma el bundle de talla en vez de un rol.
uix(chart): temable — 9 % → 49 %, y la ficha pedía 71 claves de las que 20 llevaban el mismo valor 22 claves nuevas fusionadas en el bloque existente (17 → 39). Censo chart 9 % → **49 %**; global **56 % → 57 %** (2.638 → 2.675 públicos; <20 % 19 → 18). LO QUE DECIDIÓ LA MEDICIÓN, no la ficha: Las 84 filas fuera de alcance colapsaban 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`, 4× `radius-sm`. Nombrar por parte habría dado cinco claves para el pelo que separa marcas y nueve para la tinta de anotación: la inflación de `spinner` con otra cara. **El texto no recibe tokens de chart.** Toma su ROL DE TAMAÑO de los estilos con nombre del canon —`caption` (xs) para las anotaciones, `label` (sm) para el texto de cromo— y su tinta y su peso de las ranuras del sistema. Acuñar `--chart-label-font-size` sería tipografía por componente, prohibido el mismo día para text-effects. Precedente de consumir la capa: `code-block`, `kbd`, `announce`. Doce declaraciones cambian de `var(--font-size-xs|sm)` a `var(--style-caption|label-font-size)`, mismo valor. **La receta sólo posee la tinta de lo que NO es texto**, cinco claves y cada una un concepto que el CSS repite: `axis-fg` (eje + rejilla smith + conector del funnel), `grid-fg` (rejilla + radar), `separator-fg` (el pelo de superficie entre marcas contiguas: porción, punto activo, punto smith, pétalo, segmento), `smith-boundary-fg` y `track-bg` (raíl del bar-list y del gauge). Más 17 de geometría de cromo (gap, los pares row/column-gap, swatch, track, bar-segment). **Incumplimiento heredado, corregido**: el CSS leía la coordenada CRUDA `var(--control-height-sm, var(--space-7))` —lo que `recipe-css-contract` prohíbe— con un respaldo muerto. El contrato guarda el bundle `var(--size-sm-control-height)`, 1:1 con él. **Identidad fuera de contrato**: los nueve `100%` («ocupa a tu padre») y el `min-inline-size: max-content` del tooltip, misma clase ya adjudicada en `date-picker`. Por eso el techo es 49 %, y está escrito en el veredicto §5. EL INSTRUMENTO ESTABA CIEGO DE TRES MANERAS, arregladas ANTES de medir: 1. **La superficie de chart vive en DIECISÉIS rutas de demo**, una por tipo: `/chart` monta 58 nodos de los 302 de la página y el resto vive en rutas hermanas. El guard gana `urls`: un token está VIVO si ALGUNA superficie del componente lo sigue, y cada URL sólo re-prueba lo pendiente (el caso de una sola ruta cuesta exactamente lo que costaba). De paso `picker-shell` recibe la suya: su ruta propia es un 404 y se mide dentro del date-picker — pasa de 0/31 con seis sin adjudicar a 6/31 sin tener que saberlo. 2. **El guard no leía NINGUNA propiedad SVG.** Sin `fill` / `stroke` / `strokeWidth` / `fillOpacity` / `r` / `rx`, doce de las 39 claves de un componente que dibuja en SVG leían muertas estando vivas. Misma clase que el hueco de `filter` / `backdrop-filter` de ayer. 3. **El valor centinela se elegía por SUBCADENA**: `slice-stroke-width` recibía `rgb(1, 2, 3)` por contener «stroke» —inválido para una longitud— y leía muerta. La dimensión se decide ahora por el FINAL del nombre. Los 28 componentes con ledger re-verificados tras los tres cambios: cero regresiones, cero STALE. (Ojo: doce a la vez contra el mismo dev server dan falsos exit=1 por timeout; repetir a solas antes de creerse una regresión.) Gates: sonda **0 diffs en 161.850 valores computados** (16 rutas × 7 estados, 892 nodos en reposo) · centinela **37/39**, con `transition-duration` y `-ease` adjudicadas midiéndolas sin la congelación (0,12s → 11,5s · cubic-bezier → steps(4)) · censo --only 49 % · --names 39/39 conformes · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido (`skin-media-player`) · rtl:check 0 · docs:check 0 · `check` con 72 errores globales y 0 en los ficheros tocados. Abre (→ next-features §13): el censo **penaliza consumir la capa tipográfica** si no eres un primitivo —las doce declaraciones correctas siguen contando `global`—, que es la nota de `listbox` con una segunda ocurrencia; y el número del gauge no tiene estilo con nombre que lo represente (un readout de dato no es un `h2`), así que sigue leyendo `--font-size-xl`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**El instrumento estaba ciego de tres maneras, y las tres se arreglaron ANTES
de medir** (ninguna era culpa de los tokens):
1. **La superficie de chart vive en DIECISÉIS rutas de demo**, una por tipo de
gráfico: `/chart` monta una línea con área y nada más (58 nodos de 302 en la
página). El guard ganó `urls` — un token está VIVO si alguna superficie del
componente lo sigue— y la sonda se corrió por las dieciséis.
2. **El guard no leía NINGUNA propiedad SVG.** Sin `fill` / `stroke` /
`strokeWidth` / `fillOpacity` / `r` / `rx`, doce de las 39 claves de un
componente que dibuja en SVG leían muertas estando vivas. Misma clase que el
hueco de `filter` / `backdrop-filter` del día anterior.
3. **El valor centinela se elegía por SUBCADENA**: `slice-stroke-width` recibía
`rgb(1, 2, 3)` por contener «stroke», valor inválido para una longitud, y
leía muerta. Ahora la dimensión se decide por el final del nombre.
Con eso: sonda **0 diffs en 161.850 valores computados** (16 rutas × 7 estados)
y centinela **37/39**, con `transition-duration` y `-ease` adjudicadas y
medidas sin la congelación (0.12s → 11.5s · cubic-bezier → steps(4)).
docs(theming): la auditoría de alcance de tema, componente a componente, con su propuesta El censo medía el eje y no lo explicaba: 5.205 knobs en dos tablas del plan no dicen QUÉ knob de QUÉ línea no alcanza un tema, ni qué token habría que crear. Ahora `theming-census.ts --report` escribe la auditoría entera bajo `docs/audit/theming/`: un README con la vista de conjunto y 170 fichas — 162 recetas con CSS + 8 componentes sin receta, el árbol completo de `eidos/components/`. Cada ficha de receta: knobs fuera de alcance con fichero:línea Y selector (agrupados por clase), sistema transversal aparte, los privados con la columna que decide («¿deriva de un público?»), y una PROPUESTA de corrección — el token a declarar en `base.ts` con su valor VERBATIM y su scope TSC. La propuesta deriva los nombres de recipe-contract §1 y theming §6.7; donde la doctrina no decide, marca `⚠ decisión` en vez de inventar. Y no propone acuñar lo que la doctrina prohíbe: lo que posee una capa compartida, el foco, la capa de estado, un token prestado de otra receta, un shorthand o un eje físico. Las 8 fichas sin receta dicen —medido, no supuesto— dónde vive su visual: el componente que componen (icon-button → button), la capa que consumen (affix → viewport-placement) o la receta ajena que pinta sus attrs (svg → badge/button). Defectos del instrumento corregidos en el mismo pase, todos encontrados mirando la salida: un `@import` pegado al primer selector se comía 2 knobs de color-picker (el suelo del censo no puede moverse); `:not(:disabled)` se leía como estado y producía `hover-disabled-*`; un knob que lee un privado se proponía a sí mismo en vez de resolverse por talla; `--icon-size-sm` se reportaba como préstamo del componente `icon` (ahora el préstamo se verifica contra las claves del dueño en `base.ts`); y el default de talla salía sin nombrar en vez de `-md`. Verificación: censo global idéntico al suelo publicado (5205 · 1621/33% · 856 · 1880 · 614 · 234) y COMPONENTE A COMPONENTE contra la tabla §9 del plan — 0 diferencias en 162 · regenerar dos veces da el árbol idéntico · el bloque de veredicto escrito a mano sobrevive · docs:check 0 errores sobre 813 docs · prettier limpio (el árbol generado entra en .prettierignore junto a eidos/generated). Las 10 primeras fichas llevan ya su veredicto de revisión: análisis correcto en las 10, propuesta apta en 2 (gradient-builder como piloto, combobox con cinco correcciones — dos de ellas evitaban romper el default), y 5 que no se tokenizan en solitario porque son alias de --calendar-*/--field-* y esperan la decisión de familia. Cuatro destaparon privados con prefijo ajeno o abreviado declarados en su propio CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
<!-- veredicto:end -->

Powered by TurnKey Linux.