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/card.md

169 lines
12 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
# card — 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): la cola eran TREINTA Y CUATRO, no once — y dos huecos más del instrumento Ejecuta P3, P4 y P5 del plan de la revisión del 24. P4 — LA COLA DEL HANDOFF ESTABA MAL, Y ERA MI ERROR La bala que escribí al cerrar la tanda listaba once pendientes. Contados contra el censo y el registro §8 son treinta y cuatro, y la lista sin separar tampoco servía, porque mezcla dos cosas distintas: - 16 que NUNCA han pasado por el eje (sin entrada §8 ni README): field-langs, chronos, mockup, sidebar, image-adjustments, separator, chat-message, fab, tags-input, chat-typing, collapsible, toolbar, scroll-area, tabs, slider, toast. Ésa es la cola de verdad. - 18 que SÍ pasaron y sólo les falta el README «Talla y tema»: el paso se volvió obligatorio después de que cerraran y e522e04e6 recuperó 21, pero éstos quedaron fuera. No es cola de tokenización, es deuda de documentación. Queda escrito además cómo regenerar la lista, para que nadie la escriba de memoria otra vez: alcance < 100 % y sin sección «Talla y tema», y el desempate entre A y B es si tiene entrada en §8. P3 — LA FECHA DE MEDIDA DE SEIS FICHAS select, calendar, radio-group, rating-group, toggle y card se midieron y commitearon pasada la medianoche; sus fichas decían 23. La fecha es parte del artefacto. P5 — DOS HUECOS DE INSTRUMENTO EN §13 - eidos-lint no conoce las exenciones que el test de vitest SÍ tiene (CSS_ONLY_LAYERS, WIP_TRACKS, KNOWN_MISSING_MORFO, raíces competidoras): sobre spin-field muere con «No morfo file» en vez de eximirlo. El guard de la suite y el script de línea de comandos discrepan sobre la misma ley, y el que se corre a mano es el que miente. - La columna `size` del censo se apaga cuando el eje de talla SUBE al contrato: la calcula leyendo bloques [data-size] del CSS, así que promover una escala con scope 'size:{k}' —la forma canónica— la borra del recuento. Bajó de 57 a 55 justo al hacerlo mejor. El instrumento premia la forma vieja. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Medido**: 2026-08-24 · **Alcance**: **78%** — 28 de 36 knobs por token público
uix(anchor-nav): temable — 20 % → 100 %, y el censo aprende los bordes POR LADO 11 claves nuevas (2 → 13). Tenía dos knobs y todo lo demás a pelo: la escala del índice (que ahora lee el bundle, no `--font-size-sm` suelto), el relleno y el radio del enlace, sus tres tintas —reposo, hover y activo—, el peso del activo y LAS DOS TINTAS DEL RAÍL, que es lo que da nombre al componente. EL RAÍL ACTIVO ESTABA INVISIBLE PARA EL CENSO. Su color vive en un `border-inline-start-color`, y `KNOB_PROPS` sólo conocía `border-color` y los shorthands: los ocho longhands por lado (`border-{top,bottom,left,right, block-start,block-end,inline-start,inline-end}-{color,width}`) no eran knobs para la medida. El centinela los mira desde el 2026-08-22 —los añadió cuando prose y nav-tree leyeron muertos—; el censo, no. Corregido: +30 FILAS EN EL CATÁLOGO (5.101 → 5.131 knobs), y esta ficha baja de 20 % a 18 % antes de coserse, que es lo honesto: el censo promete sobre-reportar, nunca infra-reportar. La tinta de reposo del raíl estaba escondida de otra manera: dentro del shorthand `border-inline-start: var(--anchor-nav-rail-width) solid var(--color-border-subtle)`, que el censo clasifica por el PRIMER token que casa —el trazo, ya público— y da la fila por alcanzable. No hizo falta partir el shorthand: basta con nombrar el color dentro. Un susto útil: una coma que faltaba en el contrato rompió el build de tokens, y lo que lo delató fue la SONDA midiendo 0 nodos — la página no renderizaba. El recuento de nodos es el canario, tal como dice el handoff. Gates: sonda 0 diffs en 1.760 valores × 7 estados (8 nodos) · centinela 11/12 con el radio del foco adjudicado (el guard desenfoca a propósito) · censo 100 % · `component:audit` PASS · suite eidos con el rojo conocido ajeno · `rtl:check` 0 · `docs:check` 0 · captura del raíl. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Knobs de apariencia**: 37 — público 28 · privado 8 · global 0 · literal 0 · sistema 1 · excepción 0 _(los dos últimos, fuera del ratio)_
uix(card): temable — 78 % → 78 %, y el número CERRADO es el resultado Card es un primitivo con paleta, y su columna `private` no es deuda: es el puente THM-2. Clasificados uno a uno sus ocho knobs fuera de alcance ANTES de tocar una línea —que es la mitad del trabajo—: - cuatro leen `--_card-palette-*` DIRECTO: el velo de hover de `ghost` y `outline`, la descripción en `solid` y el filete del pie en `solid`; - los otros cuatro leen el conmutador por VARIANTE (`--_card-bg`, 4 fuentes; `--_card-fg`, 2) en la raíz, el título y el cuerpo, y sus ramas son ese mismo puente. Un público encima de cualquiera dejaría que un tema lo fijara y matara en silencio el `color=` de cada instancia (CONTINUE-theming §3.pre). El techo de card **no es el 100 %**, y forzar la cifra habría sido romper la jaula del color. Lo único que faltaba era **la costura**: la rama `outline` del conmutador leía `var(--color-surface-default)` a pelo — el valor es del sistema, el knob es de la card. Entra **`outline-bg`** con ese valor verbatim, y el centinela lo confirma vivo. Ni `ghost` ni el borde transparente se acuñan: son identidad. Censo: 37 knobs · 28 públicos · **78 %** (idéntico, y así queda escrito en la ficha). Contrato 97 → **98** claves. Global del catálogo sin bajar (68 %). Diff de computed: **VACÍO**. 1.216 valores en 7 estados (sonda estándar, 6 nodos = la card y sus cinco ranuras) más 2.484 valores en 18 celdas de variante / tono / rounded / selected / disabled / lift, con `transition` y `animation` congeladas — porque el escenario monta UNA card `soft` y la sonda no barre variantes. Capturas 2× antes y después, miradas. Centinela R-5.4: **49/98, 49 adjudicadas**, verde. 40 por PATRÓN (la cascada de paleta, medida aquí: con `data-color=primary` `--card-primary-track` no mueve nada, `--palette-track` sobre el mismo nodo repinta, y sin `data-color` `--card-neutral-track` vuelve a pintar) y 9 forzadas sobre el nodo real. Dos merecen leerse: - **el trío `emerge-*` no pinta en la demo, y no es culpa de la demo**: el montaje CEDE al sistema de motion (`:not([data-animation-style])`) y el escenario arranca con el preset `select-pop`. Quitado el atributo, los tres alcanzan — y `emerge-distance` tiene ADEMÁS una segunda causa: alimenta `--motion-distance-md` y la animación acaba en `translate 0` con `fill-mode: both`, así que `transform` en reposo no puede enseñarlo nunca (se mide leyendo el hook, 8px → 1234px); - **`hover-lift` y `press-scale` mueven `transform`, que el guard no fotografía** — mismo hueco que `rating-group.item-hover-offset` (§13). Hallazgo de composición, MEDIDO y no forzado: dentro de un `CardGroup` el eje `radius` de la card está muerto — `[data-card-group] [data-card]` es (0,2,0) contra la (0,1,0) de la receta, así que manda `--card-group-card-radius` (`--card-radius-md: 1234px` no mueve nada; el del grupo mueve las dos cards). Es la anidación concéntrica de §30, deliberada y documentada en `card-group.css`; se registra porque significa que el token de la card no tiene efecto en ese contexto. Guards: censo `--only card` 78 % · `component-audit --only card` PASS · `eidos-lint card` 0 invalid · `vitest run src/uix/eidos` sin rojos nuevos (el conocido `skin-media-player` en `lint.test.ts`) · `rtl:check` 0 · `docs:check` 0 · `check` sin errores en ningún fichero tocado · prettier sin desviaciones NUEVAS sobre el árbol indexado. Anotado, fuera del eje: la raíz declara `background:` en ATAJO, lo que fija `background-image: none` y cancela el velo del sistema — card es uno de los 45 componentes de la incidencia §12 de next-features. Arreglarlo mueve píxel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Contrato hoy** (`lib/recipes/base.ts`): 98 pública(s) — `padding-inline-xs`, `padding-inline-sm`, `padding-inline-md`, `padding-inline-lg`, `padding-inline-xl`, `padding-block-xs`, `padding-block-sm`, `padding-block-md`, `padding-block-lg`, `padding-block-xl`, `gap-xs`, `gap-sm`, `gap-md`, `gap-lg`, `gap-xl`, `font-family`, `line-height`, `title-font-family`, `title-font-size-xs`, `title-font-size-sm`, `title-font-size-md`, `title-font-size-lg`, `title-font-size-xl`, `title-font-weight`, `title-line-height`, `title-letter-spacing`, `description-font-family`, `description-font-size-xs`, `description-font-size-sm`, `description-font-size-md`, `description-font-size-lg`, `description-font-size-xl`, `description-line-height`, `description-fg`, `body-font-size-xs`, `body-font-size-sm`, `body-font-size-md`, `body-font-size-lg`, `body-font-size-xl`, `body-line-height`, `border-width`, `radius-sm`, `radius-md`, `radius-lg`, `header-gap`, `footer-gap`, `footer-padding-start`, `footer-border-fg`, `emerge-duration`, `emerge-ease`, `emerge-distance`, `hover-lift`, `hover-shadow`, `press-scale`, `press-duration`, `selected-ring-width`, `disabled-opacity`, `outline-bg`, `primary-solid`, `primary-text`, `primary-contrast`, `secondary-solid`, `secondary-text`, `secondary-contrast`, `neutral-solid`, `neutral-text`, `neutral-contrast`, `affirm-solid`, `affirm-text`, `affirm-contrast`, `fulfill-track`, `fulfill-border`, `fulfill-solid`, `fulfill-text`, `fulfill-contrast`, `risk-solid`, `risk-text`, `risk-contrast`, `threat-solid`, `threat-text`, `threat-contrast`, `loss-track`, `loss-border`, `loss-solid`, `loss-text`, `loss-contrast`, `primary-track`, `primary-border`, `secondary-track`, `secondary-border`, `neutral-track`, `neutral-border`, `affirm-track`, `affirm-border`, `risk-track`, `risk-border`, `threat-track`, `threat-border` · 5 privada(s) forward — `_palette-track`, `_palette-border`, `_palette-solid`, `_palette-text`, `_palette-contrast`
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`**: sí · **ficheros**: `card.css`
## 1. Knobs fuera de alcance
### 1.1 Directo a primitivo global (0)
_Ninguno._
uix(anchor-nav): temable — 20 % → 100 %, y el censo aprende los bordes POR LADO 11 claves nuevas (2 → 13). Tenía dos knobs y todo lo demás a pelo: la escala del índice (que ahora lee el bundle, no `--font-size-sm` suelto), el relleno y el radio del enlace, sus tres tintas —reposo, hover y activo—, el peso del activo y LAS DOS TINTAS DEL RAÍL, que es lo que da nombre al componente. EL RAÍL ACTIVO ESTABA INVISIBLE PARA EL CENSO. Su color vive en un `border-inline-start-color`, y `KNOB_PROPS` sólo conocía `border-color` y los shorthands: los ocho longhands por lado (`border-{top,bottom,left,right, block-start,block-end,inline-start,inline-end}-{color,width}`) no eran knobs para la medida. El centinela los mira desde el 2026-08-22 —los añadió cuando prose y nav-tree leyeron muertos—; el censo, no. Corregido: +30 FILAS EN EL CATÁLOGO (5.101 → 5.131 knobs), y esta ficha baja de 20 % a 18 % antes de coserse, que es lo honesto: el censo promete sobre-reportar, nunca infra-reportar. La tinta de reposo del raíl estaba escondida de otra manera: dentro del shorthand `border-inline-start: var(--anchor-nav-rail-width) solid var(--color-border-subtle)`, que el censo clasifica por el PRIMER token que casa —el trazo, ya público— y da la fila por alcanzable. No hizo falta partir el shorthand: basta con nombrar el color dentro. Un susto útil: una coma que faltaba en el contrato rompió el build de tokens, y lo que lo delató fue la SONDA midiendo 0 nodos — la página no renderizaba. El recuento de nodos es el canario, tal como dice el handoff. Gates: sonda 0 diffs en 1.760 valores × 7 estados (8 nodos) · centinela 11/12 con el radio del foco adjudicado (el guard desenfoca a propósito) · censo 100 % · `component:audit` PASS · suite eidos con el rojo conocido ajeno · `rtl:check` 0 · `docs:check` 0 · captura del raíl. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 1.2 A través de un privado (8)
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(theming): el censo aprende que un privado DERIVADO sí alcanza — 50 % → 56 % Seis puntos de alcance sin tocar una línea de componente: **la medición estaba mal, no el código**. EL DEFECTO. F0 encargaba «detección "privado que deriva de público" (leer `--_c-x: var(--c-y)` en la misma receta y reclasificar)». Se implementó a medias: el censo CALCULA `derives` y lo imprime en la columna «¿deriva de un público?» de la §3 de cada ficha, pero **el contador nunca lo usó** — esos knobs seguían puntuando como deuda. Medido: **240 privados en 59 componentes** estaban en ese estado, es decir, haciendo exactamente lo que la doctrina prescribe («privados sólo si derivan de públicos») y penalizados por ello. Lo destapó tokenizar `avatar`: sus 17 privados YA leían públicos (`--_avatar-size: var(--avatar-size-md)`), así que no había nada que tokenizar — había que arreglar el instrumento. LA CORRECCIÓN. Segunda pasada tras recoger privados y knobs: un knob que lee `var(--_c-x)` pasa a `public` si ese privado alcanza un público. El cierre es **TRANSITIVO** (`--_a: calc(var(--_b) * .3)` alcanza si `--_b` alcanza) con conjunto de visitados para que un ciclo no lo cuelgue. **Muta-prueba** (obligatoria, memoria `a-guard-that-inspects-nothing-passes`): apuntar `--_avatar-radius` al primitivo crudo baja avatar de 75 % a 72 % y el knob vuelve a `private`; revertirlo lo devuelve a 75 % y deja el árbol idéntico. EFECTO MEDIDO: - Global **50 % → 56 %** · privados 625 → 341 · al 100 % 10 → 14 · <20 % 22 → 20. - `avatar` 36 % → **75 %**, `picker-shell` 76 % → **95 %**, `menu-dial` 25 % → 38 %, y otras 51 fichas con cifras nuevas — **ninguna por cambio de código**. - Los READMEs de `picker-shell` y `menu-dial` se actualizan con la cifra nueva y con la razón, para que nadie crea que el componente cambió. ⚠ **Cualquier cifra anterior a este commit no es comparable con las de ahora.** Queda escrito en el handoff. Y un hueco de F0 que sale al hacerlo, registrado en §13: **el test del SUELO que el plan pedía NO EXISTE** («alcance global ≥ el de hoy y literales ≤ 614 — el número sube o el test falla»). Hoy nada impide que el alcance BAJE entre sesiones: sólo se vería mirando la cifra a mano. Con el censo ya endurecido, es el momento de escribirlo. Gates: `component:audit` 162 PASS / 4 NEEDS-WORK (preexistentes) · `--names` DESVIADAS 0 · suite eidos sin rojos nuevos · rtl:check 0 · docs:check 0 · el censo compila. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 months ago
| 1 | `card.css:60` | `[data-card]` | `background` | `var(--_card-bg)` |
| 2 | `card.css:61` | `[data-card]` | `color` | `var(--_card-fg)` |
| 3 | `card.css:198` | `[data-card][data-lift][data-variant='ghost']:hover:not([data-disabled])` | `background` | `var(--_card-palette-track)` |
| 4 | `card.css:202` | `[data-card][data-lift][data-variant='outline']:hover:not([data-disabled])` | `background` | `var(--_card-palette-track)` |
| 5 | `card.css:293` | `[data-card-title]` | `color` | `var(--_card-fg)` |
| 6 | `card.css:309` | `[data-card][data-variant='solid'] [data-card-description]` | `color` | `color-mix(in srgb, var(--_card-palette-contrast) 80%, transparent)` |
| 7 | `card.css:317` | `[data-card-body]` | `color` | `var(--_card-fg)` |
uix(anchor-nav): temable — 20 % → 100 %, y el censo aprende los bordes POR LADO 11 claves nuevas (2 → 13). Tenía dos knobs y todo lo demás a pelo: la escala del índice (que ahora lee el bundle, no `--font-size-sm` suelto), el relleno y el radio del enlace, sus tres tintas —reposo, hover y activo—, el peso del activo y LAS DOS TINTAS DEL RAÍL, que es lo que da nombre al componente. EL RAÍL ACTIVO ESTABA INVISIBLE PARA EL CENSO. Su color vive en un `border-inline-start-color`, y `KNOB_PROPS` sólo conocía `border-color` y los shorthands: los ocho longhands por lado (`border-{top,bottom,left,right, block-start,block-end,inline-start,inline-end}-{color,width}`) no eran knobs para la medida. El centinela los mira desde el 2026-08-22 —los añadió cuando prose y nav-tree leyeron muertos—; el censo, no. Corregido: +30 FILAS EN EL CATÁLOGO (5.101 → 5.131 knobs), y esta ficha baja de 20 % a 18 % antes de coserse, que es lo honesto: el censo promete sobre-reportar, nunca infra-reportar. La tinta de reposo del raíl estaba escondida de otra manera: dentro del shorthand `border-inline-start: var(--anchor-nav-rail-width) solid var(--color-border-subtle)`, que el censo clasifica por el PRIMER token que casa —el trazo, ya público— y da la fila por alcanzable. No hizo falta partir el shorthand: basta con nombrar el color dentro. Un susto útil: una coma que faltaba en el contrato rompió el build de tokens, y lo que lo delató fue la SONDA midiendo 0 nodos — la página no renderizaba. El recuento de nodos es el canario, tal como dice el handoff. Gates: sonda 0 diffs en 1.760 valores × 7 estados (8 nodos) · centinela 11/12 con el radio del foco adjudicado (el guard desenfoca a propósito) · censo 100 % · `component:audit` PASS · suite eidos con el rojo conocido ajeno · `rtl:check` 0 · `docs:check` 0 · captura del raíl. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| 8 | `card.css:333` | `[data-card][data-variant='solid'] [data-card-footer]` | `border-block-start-color` | `color-mix(in srgb, var(--_card-palette-contrast) 18%, transparent)` |
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.3 Literales (0)
_Ninguno._
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 (1) — informativo, fuera del ratio
Un tema los alcanza **a nivel de sistema**, por diseño (recipe-contract §2).
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `card.css:226` | `[data-card][data-interactive]:focus-visible` | `outline` | `var(--focus-ring-width) solid var(--focus-ring-color)` |
## 3. Privados de la receta — ¿de dónde sale su valor?
| privado | declaraciones | valor(es) | origen | ¿deriva de un público? |
| --- | ---: | --- | --- | :-: |
| `--_card-padding-inline` | 5 | `var(--card-padding-inline-md)`, `var(--card-padding-inline-xs)`, `var(--card-padding-inline-sm)`, `var(--card-padding-inline-lg)`, `var(--card-padding-inline-xl)` | public | **sí** |
| `--_card-padding-block` | 5 | `var(--card-padding-block-md)`, `var(--card-padding-block-xs)`, `var(--card-padding-block-sm)`, `var(--card-padding-block-lg)`, `var(--card-padding-block-xl)` | public | **sí** |
| `--_card-gap` | 5 | `var(--card-gap-md)`, `var(--card-gap-xs)`, `var(--card-gap-sm)`, `var(--card-gap-lg)`, `var(--card-gap-xl)` | public | **sí** |
| `--_card-title-font-size` | 5 | `var(--card-title-font-size-md)`, `var(--card-title-font-size-xs)`, `var(--card-title-font-size-sm)`, `var(--card-title-font-size-lg)`, `var(--card-title-font-size-xl)` | public | **sí** |
| `--_card-description-font-size` | 5 | `var(--card-description-font-size-md)`, `var(--card-description-font-size-xs)`, `var(--card-description-font-size-sm)`, `var(--card-description-font-size-lg)`, `var(--card-description-font-size-xl)` | public | **sí** |
| `--_card-body-font-size` | 5 | `var(--card-body-font-size-md)`, `var(--card-body-font-size-xs)`, `var(--card-body-font-size-sm)`, `var(--card-body-font-size-lg)`, `var(--card-body-font-size-xl)` | public | **sí** |
| `--_card-radius` | 3 | `var(--card-radius-md)`, `var(--card-radius-sm)`, `var(--card-radius-lg)` | public | **sí** |
uix(card): temable — 78 % → 78 %, y el número CERRADO es el resultado Card es un primitivo con paleta, y su columna `private` no es deuda: es el puente THM-2. Clasificados uno a uno sus ocho knobs fuera de alcance ANTES de tocar una línea —que es la mitad del trabajo—: - cuatro leen `--_card-palette-*` DIRECTO: el velo de hover de `ghost` y `outline`, la descripción en `solid` y el filete del pie en `solid`; - los otros cuatro leen el conmutador por VARIANTE (`--_card-bg`, 4 fuentes; `--_card-fg`, 2) en la raíz, el título y el cuerpo, y sus ramas son ese mismo puente. Un público encima de cualquiera dejaría que un tema lo fijara y matara en silencio el `color=` de cada instancia (CONTINUE-theming §3.pre). El techo de card **no es el 100 %**, y forzar la cifra habría sido romper la jaula del color. Lo único que faltaba era **la costura**: la rama `outline` del conmutador leía `var(--color-surface-default)` a pelo — el valor es del sistema, el knob es de la card. Entra **`outline-bg`** con ese valor verbatim, y el centinela lo confirma vivo. Ni `ghost` ni el borde transparente se acuñan: son identidad. Censo: 37 knobs · 28 públicos · **78 %** (idéntico, y así queda escrito en la ficha). Contrato 97 → **98** claves. Global del catálogo sin bajar (68 %). Diff de computed: **VACÍO**. 1.216 valores en 7 estados (sonda estándar, 6 nodos = la card y sus cinco ranuras) más 2.484 valores en 18 celdas de variante / tono / rounded / selected / disabled / lift, con `transition` y `animation` congeladas — porque el escenario monta UNA card `soft` y la sonda no barre variantes. Capturas 2× antes y después, miradas. Centinela R-5.4: **49/98, 49 adjudicadas**, verde. 40 por PATRÓN (la cascada de paleta, medida aquí: con `data-color=primary` `--card-primary-track` no mueve nada, `--palette-track` sobre el mismo nodo repinta, y sin `data-color` `--card-neutral-track` vuelve a pintar) y 9 forzadas sobre el nodo real. Dos merecen leerse: - **el trío `emerge-*` no pinta en la demo, y no es culpa de la demo**: el montaje CEDE al sistema de motion (`:not([data-animation-style])`) y el escenario arranca con el preset `select-pop`. Quitado el atributo, los tres alcanzan — y `emerge-distance` tiene ADEMÁS una segunda causa: alimenta `--motion-distance-md` y la animación acaba en `translate 0` con `fill-mode: both`, así que `transform` en reposo no puede enseñarlo nunca (se mide leyendo el hook, 8px → 1234px); - **`hover-lift` y `press-scale` mueven `transform`, que el guard no fotografía** — mismo hueco que `rating-group.item-hover-offset` (§13). Hallazgo de composición, MEDIDO y no forzado: dentro de un `CardGroup` el eje `radius` de la card está muerto — `[data-card-group] [data-card]` es (0,2,0) contra la (0,1,0) de la receta, así que manda `--card-group-card-radius` (`--card-radius-md: 1234px` no mueve nada; el del grupo mueve las dos cards). Es la anidación concéntrica de §30, deliberada y documentada en `card-group.css`; se registra porque significa que el token de la card no tiene efecto en ese contexto. Guards: censo `--only card` 78 % · `component-audit --only card` PASS · `eidos-lint card` 0 invalid · `vitest run src/uix/eidos` sin rojos nuevos (el conocido `skin-media-player` en `lint.test.ts`) · `rtl:check` 0 · `docs:check` 0 · `check` sin errores en ningún fichero tocado · prettier sin desviaciones NUEVAS sobre el árbol indexado. Anotado, fuera del eje: la raíz declara `background:` en ATAJO, lo que fija `background-image: none` y cancela el velo del sistema — card es uno de los 45 componentes de la incidencia §12 de next-features. Arreglarlo mueve píxel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| `--_card-bg` | 5 | `var(--_card-palette-track)`, `var(--_card-palette-solid)`, `var(--card-outline-bg)`, `transparent` | literal, private, public | no |
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
| `--_card-fg` | 5 | `var(--_card-palette-text)`, `var(--_card-palette-contrast)` | private | no |
| `--_card-border-color` | 5 | `transparent`, `var(--_card-palette-border)` | literal, private | no |
Consumidos y **no declarados en el CSS** (vienen de `base.ts` o de un estilo inline del wrapper): `--_card-palette-border`, `--_card-palette-contrast`, `--_card-palette-solid`, `--_card-palette-text`, `--_card-palette-track`.
## 4. Propuesta de corrección
- **Tiene eje `size`**: los tokens dimensionales van por talla (`{part}-{eje}-{k}`) apuntando al bundle `--size-{k}-*`, nunca al primitivo crudo (theming §5; el guard `recipe-css-contract` prohíbe el primitivo).
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (4)
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 (`--card-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
uix(card): temable — 78 % → 78 %, y el número CERRADO es el resultado Card es un primitivo con paleta, y su columna `private` no es deuda: es el puente THM-2. Clasificados uno a uno sus ocho knobs fuera de alcance ANTES de tocar una línea —que es la mitad del trabajo—: - cuatro leen `--_card-palette-*` DIRECTO: el velo de hover de `ghost` y `outline`, la descripción en `solid` y el filete del pie en `solid`; - los otros cuatro leen el conmutador por VARIANTE (`--_card-bg`, 4 fuentes; `--_card-fg`, 2) en la raíz, el título y el cuerpo, y sus ramas son ese mismo puente. Un público encima de cualquiera dejaría que un tema lo fijara y matara en silencio el `color=` de cada instancia (CONTINUE-theming §3.pre). El techo de card **no es el 100 %**, y forzar la cifra habría sido romper la jaula del color. Lo único que faltaba era **la costura**: la rama `outline` del conmutador leía `var(--color-surface-default)` a pelo — el valor es del sistema, el knob es de la card. Entra **`outline-bg`** con ese valor verbatim, y el centinela lo confirma vivo. Ni `ghost` ni el borde transparente se acuñan: son identidad. Censo: 37 knobs · 28 públicos · **78 %** (idéntico, y así queda escrito en la ficha). Contrato 97 → **98** claves. Global del catálogo sin bajar (68 %). Diff de computed: **VACÍO**. 1.216 valores en 7 estados (sonda estándar, 6 nodos = la card y sus cinco ranuras) más 2.484 valores en 18 celdas de variante / tono / rounded / selected / disabled / lift, con `transition` y `animation` congeladas — porque el escenario monta UNA card `soft` y la sonda no barre variantes. Capturas 2× antes y después, miradas. Centinela R-5.4: **49/98, 49 adjudicadas**, verde. 40 por PATRÓN (la cascada de paleta, medida aquí: con `data-color=primary` `--card-primary-track` no mueve nada, `--palette-track` sobre el mismo nodo repinta, y sin `data-color` `--card-neutral-track` vuelve a pintar) y 9 forzadas sobre el nodo real. Dos merecen leerse: - **el trío `emerge-*` no pinta en la demo, y no es culpa de la demo**: el montaje CEDE al sistema de motion (`:not([data-animation-style])`) y el escenario arranca con el preset `select-pop`. Quitado el atributo, los tres alcanzan — y `emerge-distance` tiene ADEMÁS una segunda causa: alimenta `--motion-distance-md` y la animación acaba en `translate 0` con `fill-mode: both`, así que `transform` en reposo no puede enseñarlo nunca (se mide leyendo el hook, 8px → 1234px); - **`hover-lift` y `press-scale` mueven `transform`, que el guard no fotografía** — mismo hueco que `rating-group.item-hover-offset` (§13). Hallazgo de composición, MEDIDO y no forzado: dentro de un `CardGroup` el eje `radius` de la card está muerto — `[data-card-group] [data-card]` es (0,2,0) contra la (0,1,0) de la receta, así que manda `--card-group-card-radius` (`--card-radius-md: 1234px` no mueve nada; el del grupo mueve las dos cards). Es la anidación concéntrica de §30, deliberada y documentada en `card-group.css`; se registra porque significa que el token de la card no tiene efecto en ese contexto. Guards: censo `--only card` 78 % · `component-audit --only card` PASS · `eidos-lint card` 0 invalid · `vitest run src/uix/eidos` sin rojos nuevos (el conocido `skin-media-player` en `lint.test.ts`) · `rtl:check` 0 · `docs:check` 0 · `check` sin errores en ningún fichero tocado · prettier sin desviaciones NUEVAS sobre el árbol indexado. Anotado, fuera del eje: la raíz declara `background:` en ATAJO, lo que fija `background-image: none` y cancela el velo del sistema — card es uno de los 45 componentes de la incidencia §12 de next-features. Arreglarlo mueve píxel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| `bg` | `root` | ⚠ `var(--_card-palette-track)` / `var(--_card-palette-solid)` / `var(--card-outline-bg)` / `transparent` | 5 |
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
| `fg` | `root` | ⚠ `var(--_card-palette-text)` / `var(--_card-palette-contrast)` | 5 |
| `title-fg` | `root` | ⚠ `var(--_card-palette-text)` / `var(--_card-palette-contrast)` | 5 |
| `body-fg` | `root` | ⚠ `var(--_card-palette-text)` / `var(--_card-palette-contrast)` | 5 |
uix(anchor-nav): temable — 20 % → 100 %, y el censo aprende los bordes POR LADO 11 claves nuevas (2 → 13). Tenía dos knobs y todo lo demás a pelo: la escala del índice (que ahora lee el bundle, no `--font-size-sm` suelto), el relleno y el radio del enlace, sus tres tintas —reposo, hover y activo—, el peso del activo y LAS DOS TINTAS DEL RAÍL, que es lo que da nombre al componente. EL RAÍL ACTIVO ESTABA INVISIBLE PARA EL CENSO. Su color vive en un `border-inline-start-color`, y `KNOB_PROPS` sólo conocía `border-color` y los shorthands: los ocho longhands por lado (`border-{top,bottom,left,right, block-start,block-end,inline-start,inline-end}-{color,width}`) no eran knobs para la medida. El centinela los mira desde el 2026-08-22 —los añadió cuando prose y nav-tree leyeron muertos—; el censo, no. Corregido: +30 FILAS EN EL CATÁLOGO (5.101 → 5.131 knobs), y esta ficha baja de 20 % a 18 % antes de coserse, que es lo honesto: el censo promete sobre-reportar, nunca infra-reportar. La tinta de reposo del raíl estaba escondida de otra manera: dentro del shorthand `border-inline-start: var(--anchor-nav-rail-width) solid var(--color-border-subtle)`, que el censo clasifica por el PRIMER token que casa —el trazo, ya público— y da la fila por alcanzable. No hizo falta partir el shorthand: basta con nombrar el color dentro. Un susto útil: una coma que faltaba en el contrato rompió el build de tokens, y lo que lo delató fue la SONDA midiendo 0 nodos — la página no renderizaba. El recuento de nodos es el canario, tal como dice el handoff. Gates: sonda 0 diffs en 1.760 valores × 7 estados (8 nodos) · centinela 11/12 con el radio del foco adjudicado (el guard desenfoca a propósito) · censo 100 % · `component:audit` PASS · suite eidos con el rojo conocido ajeno · `rtl:check` 0 · `docs:check` 0 · captura del raíl. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 4.2 Sin nombre mecánico (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
- **⚠ decisión: el privado que alimenta este knob no se declara en el CSS (viene de `base.ts` o de un estilo inline) — hay que resolverlo antes de nombrarlo** — 3: `background`, `color`.
uix(anchor-nav): temable — 20 % → 100 %, y el censo aprende los bordes POR LADO 11 claves nuevas (2 → 13). Tenía dos knobs y todo lo demás a pelo: la escala del índice (que ahora lee el bundle, no `--font-size-sm` suelto), el relleno y el radio del enlace, sus tres tintas —reposo, hover y activo—, el peso del activo y LAS DOS TINTAS DEL RAÍL, que es lo que da nombre al componente. EL RAÍL ACTIVO ESTABA INVISIBLE PARA EL CENSO. Su color vive en un `border-inline-start-color`, y `KNOB_PROPS` sólo conocía `border-color` y los shorthands: los ocho longhands por lado (`border-{top,bottom,left,right, block-start,block-end,inline-start,inline-end}-{color,width}`) no eran knobs para la medida. El centinela los mira desde el 2026-08-22 —los añadió cuando prose y nav-tree leyeron muertos—; el censo, no. Corregido: +30 FILAS EN EL CATÁLOGO (5.101 → 5.131 knobs), y esta ficha baja de 20 % a 18 % antes de coserse, que es lo honesto: el censo promete sobre-reportar, nunca infra-reportar. La tinta de reposo del raíl estaba escondida de otra manera: dentro del shorthand `border-inline-start: var(--anchor-nav-rail-width) solid var(--color-border-subtle)`, que el censo clasifica por el PRIMER token que casa —el trazo, ya público— y da la fila por alcanzable. No hizo falta partir el shorthand: basta con nombrar el color dentro. Un susto útil: una coma que faltaba en el contrato rompió el build de tokens, y lo que lo delató fue la SONDA midiendo 0 nodos — la página no renderizaba. El recuento de nodos es el canario, tal como dice el handoff. Gates: sonda 0 diffs en 1.760 valores × 7 estados (8 nodos) · centinela 11/12 con el radio del foco adjudicado (el guard desenfoca a propósito) · censo 100 % · `component:audit` PASS · suite eidos con el rojo conocido ajeno · `rtl:check` 0 · `docs:check` 0 · captura del raíl. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **⚠ decisión: la propiedad no tiene slot canónico en el vocabulario** — 1: `border-block-start-color`.
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
### 4.3 Avisos sobre los tokens propuestos (2)
- **el privado `--_card-bg` debe pasar a leer este público (o desaparecer)** — `--card-bg`
- **el privado `--_card-fg` debe pasar a leer este público (o desaparecer)** — `--card-fg`, `--card-title-fg`, `--card-body-fg`
### 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(card): temable — 78 % → 78 %, y el número CERRADO es el resultado Card es un primitivo con paleta, y su columna `private` no es deuda: es el puente THM-2. Clasificados uno a uno sus ocho knobs fuera de alcance ANTES de tocar una línea —que es la mitad del trabajo—: - cuatro leen `--_card-palette-*` DIRECTO: el velo de hover de `ghost` y `outline`, la descripción en `solid` y el filete del pie en `solid`; - los otros cuatro leen el conmutador por VARIANTE (`--_card-bg`, 4 fuentes; `--_card-fg`, 2) en la raíz, el título y el cuerpo, y sus ramas son ese mismo puente. Un público encima de cualquiera dejaría que un tema lo fijara y matara en silencio el `color=` de cada instancia (CONTINUE-theming §3.pre). El techo de card **no es el 100 %**, y forzar la cifra habría sido romper la jaula del color. Lo único que faltaba era **la costura**: la rama `outline` del conmutador leía `var(--color-surface-default)` a pelo — el valor es del sistema, el knob es de la card. Entra **`outline-bg`** con ese valor verbatim, y el centinela lo confirma vivo. Ni `ghost` ni el borde transparente se acuñan: son identidad. Censo: 37 knobs · 28 públicos · **78 %** (idéntico, y así queda escrito en la ficha). Contrato 97 → **98** claves. Global del catálogo sin bajar (68 %). Diff de computed: **VACÍO**. 1.216 valores en 7 estados (sonda estándar, 6 nodos = la card y sus cinco ranuras) más 2.484 valores en 18 celdas de variante / tono / rounded / selected / disabled / lift, con `transition` y `animation` congeladas — porque el escenario monta UNA card `soft` y la sonda no barre variantes. Capturas 2× antes y después, miradas. Centinela R-5.4: **49/98, 49 adjudicadas**, verde. 40 por PATRÓN (la cascada de paleta, medida aquí: con `data-color=primary` `--card-primary-track` no mueve nada, `--palette-track` sobre el mismo nodo repinta, y sin `data-color` `--card-neutral-track` vuelve a pintar) y 9 forzadas sobre el nodo real. Dos merecen leerse: - **el trío `emerge-*` no pinta en la demo, y no es culpa de la demo**: el montaje CEDE al sistema de motion (`:not([data-animation-style])`) y el escenario arranca con el preset `select-pop`. Quitado el atributo, los tres alcanzan — y `emerge-distance` tiene ADEMÁS una segunda causa: alimenta `--motion-distance-md` y la animación acaba en `translate 0` con `fill-mode: both`, así que `transform` en reposo no puede enseñarlo nunca (se mide leyendo el hook, 8px → 1234px); - **`hover-lift` y `press-scale` mueven `transform`, que el guard no fotografía** — mismo hueco que `rating-group.item-hover-offset` (§13). Hallazgo de composición, MEDIDO y no forzado: dentro de un `CardGroup` el eje `radius` de la card está muerto — `[data-card-group] [data-card]` es (0,2,0) contra la (0,1,0) de la receta, así que manda `--card-group-card-radius` (`--card-radius-md: 1234px` no mueve nada; el del grupo mueve las dos cards). Es la anidación concéntrica de §30, deliberada y documentada en `card-group.css`; se registra porque significa que el token de la card no tiene efecto en ese contexto. Guards: censo `--only card` 78 % · `component-audit --only card` PASS · `eidos-lint card` 0 invalid · `vitest run src/uix/eidos` sin rojos nuevos (el conocido `skin-media-player` en `lint.test.ts`) · `rtl:check` 0 · `docs:check` 0 · `check` sin errores en ningún fichero tocado · prettier sin desviaciones NUEVAS sobre el árbol indexado. Anotado, fuera del eje: la raíz declara `background:` en ATAJO, lo que fija `background-image: none` y cancela el velo del sistema — card es uno de los 45 componentes de la incidencia §12 de next-features. Arreglarlo mueve píxel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**EJECUTADO 2026-08-23 — 78 % → 78 %, contrato 97 → 98 claves. El componente
está CERRADO en su número, y ése es el hallazgo.**
`card` es un PRIMITIVO con paleta, y su columna `private` no es deuda: es el
puente THM-2. Clasificados uno a uno los ocho knobs de §1.2:
| # | knob | clase | veredicto |
| ---: | --- | --- | --- |
| 3, 4 | el velo de hover de `ghost` y `outline` (`--_card-palette-track`) | **puente THM-2** | no se acuña |
| 6 | la descripción en `solid` (mezcla sobre `--_card-palette-contrast`) | **puente THM-2** | no se acuña |
| 8 | el filete del pie en `solid` (misma mezcla) | **puente THM-2** | no se acuña |
| 1 | `background: var(--_card-bg)` | **conmutador por VARIANTE**, 4 fuentes | privado; 3 de sus 4 ramas son el puente |
| 2, 5, 7 | `color: var(--_card-fg)` en raíz, título y cuerpo | **conmutador por VARIANTE**, 2 fuentes | privado; las dos ramas son el puente |
Un público encima de cualquiera de ellos dejaría que un tema lo fijara y matara
en silencio el `color=` de cada instancia (`CONTINUE-theming` §3.pre). El techo
de `card` **no es el 100 %**.
**La única costura real, y entró**: la rama `outline` del conmutador leía
`var(--color-surface-default)` a pelo — el valor es del sistema, el knob es de
la card. Nace `--card-outline-bg` con ese valor verbatim. No mueve el ratio (el
conmutador sigue teniendo ramas privadas), y sí cierra el único agujero de
alcance que quedaba: el centinela lo confirma vivo.
**Diff de computed: VACÍO.** 1.216 valores en 7 estados (sonda estándar) más
2.484 valores en 18 celdas de variante / tono / `rounded` / `selected` /
`disabled` / `lift` (barrido dirigido, porque el escenario de la demo monta UNA
card `soft` y la sonda no barre variantes). Capturas 2× antes y después,
idénticas.
**Centinela R-5.4: 49/98, 49 adjudicadas** — 40 por PATRÓN (la cascada de
paleta, medida aquí: con `data-color=primary`, `--card-primary-track` no mueve
nada y `--palette-track` sí) y 9 individuales, cada una forzada sobre el nodo
real. Dos merecen leerse:
- **el trío `emerge-*` no pinta en la demo y no es culpa de la demo**: el
montaje CEDE al sistema de motion (`:not([data-animation-style])`) y el
escenario arranca con el preset `select-pop`. Quitado el atributo, los tres
alcanzan. Y `emerge-distance` tiene además una segunda causa: alimenta
`--motion-distance-md` y la animación termina en `translate 0` con
`fill-mode: both`, así que `transform` en reposo NUNCA puede enseñarlo — se
mide leyendo el hook (8px → 1234px).
- **`hover-lift` y `press-scale` mueven `transform`, que el guard no
fotografía** (mismo hueco que `rating-group.item-hover-offset`).
**Hallazgo de composición (medido, no forzado)**: dentro de un `CardGroup` el
eje `radius` de la card está MUERTO — `[data-card-group] [data-card]` es
(0,2,0) contra la (0,1,0) de la receta, así que manda
`--card-group-card-radius`. Es la anidación concéntrica de §30, deliberada y
documentada en `card-group.css`; se registra porque significa que
`--card-radius-*` no tiene efecto en ese contexto. Medido:
`--card-radius-md: 1234px` no mueve nada, `--card-group-card-radius: 1234px`
mueve las dos cards.
**Anotado, fuera del eje**: la raíz declara `background:` en atajo, lo que fija
`background-image: none` y cancela el velo del sistema — card es uno de los 45
componentes de la incidencia §12 (`next-features`). Arreglarlo mueve píxel.
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.