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
# background — 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.
uix(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Medido**: 2026-08-23 · **Alcance** : **95%** — 19 de 20 knobs por token público
- **Knobs de apariencia**: 23 — público 19 · privado 1 · global 0 · literal 0 · sistema 3 · excepción 3 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 37 pública(s) — `pattern-rule` , `pattern-cell` , `pattern-dot-size` , `pattern-glow-size` , `pattern-glow-at` , `pattern-glow-strength` , `pattern-mesh-image` , `pattern-mesh-opacity` , `pattern-noise-opacity` , `pattern-vignette-strength` , `pattern-lines-width` , `pattern-lines-gap` , `pattern-lines-angle` , `pattern-rings-width` , `pattern-rings-gap` , `fade-size` , `fade-at` , `scrim-fg` , `scrim-fg-over-dark` , `scrim-fg-over-light` , `scrim-blur-sm` , `scrim-blur-md` , `scrim-blur-lg` , `scrim-blur-xl` , `scrim-blur-xxl` , `scrim-strength-xs` , `scrim-strength-sm` , `scrim-strength-md` , `scrim-strength-lg` , `scrim-strength-xl` , `gradient-drift-duration` , `pause-offset` , `pause-z` , `parallax-travel` , `spotlight-size` , `spotlight-strength` , `spotlight-fg`
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** : `background.css`
## 1. Knobs fuera de alcance
uix(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
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(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
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
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.2 A través de un privado (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
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
uix(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| 1 | `background.css:265` | `[data-background-layer][data-kind='gradient']` | `background` | `var(--_background-gradient-image, 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
uix(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 1.3 Literales (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(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
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
uix(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
### 1.4 Excepciones firmadas (3) — fuera del ratio
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
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.
uix(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `background.css:76` | `[data-background-layer] :where(img, video)` | `inline-size` | `100%` |
| 2 | `background.css:77` | `[data-background-layer] :where(img, video)` | `block-size` | `100%` |
| 3 | `background.css:240` | `[data-background-layer][data-pattern='noise']` | `background-image` | `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E")` |
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 (3) — 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 | `background.css:100` | `[data-background-layer][data-opacity='subtle']` | `opacity` | `var(--opacity-subtle)` |
| 2 | `background.css:103` | `[data-background-layer][data-opacity='muted']` | `opacity` | `var(--opacity-muted)` |
| 3 | `background.css:106` | `[data-background-layer][data-opacity='ghost']` | `opacity` | `var(--opacity-ghost)` |
## 3. Privados de la receta — ¿de dónde sale su valor?
| privado | declaraciones | valor(es) | origen | ¿deriva de un público? |
| --- | ---: | --- | --- | :-: |
| `--_background-tint` | 2 | `var(--color-primary-solid)` , `var(--palette-solid, var(--color-primary-solid))` | global | no |
| `--_background-rule` | 1 | `var(--background-pattern-rule)` | public | **sí** |
| `--_background-cell` | 1 | `var(--background-pattern-cell)` | public | **sí** |
refactor(eidos): el catálogo habla un idioma — 269 claves al vocabulario firmado
D-TH.6, ejecutada. El slot de tinta pasa a `fg` y el modificador interactivo
se pone delante, que es lo que theming §6.7 r7 documentaba sin guard desde
que se escribió. Value-preserving: renombra la clave en `recipes/base.ts` y
sus 793 referencias en 101 ficheros; no toca un solo valor.
claves renombradas 269 en 66 componentes
referencias 793 en 101 ficheros
censo antes/después 162 recetas · 5.203 knobs · 1.841 públicos (37 %) · 56
sin contrato — IDÉNTICO, como debe ser un rename
--names antes/después 269 desviadas → 0
Qué NO entra, y por qué:
47 `{rol}-{slot-de-rol}` canónicas: COLOR_ROLE_SLOTS pone el modificador
detrás POR CONSTRUCCIÓN (`primary-solid-hover`)
13 exentas firmadas `--focus-ring-*` es familia del sistema; el color
de `aura` es un sustantivo; `stop-color` ES una
parte de gradient-builder
47 hovers neutros por VALOR: migran a la capa de estado
(§38 + R-4.3), no se renombran — firma 3
6 ocurrencias en historia changelog, errores-toxico, PLAN-affix/background:
reescribir un registro fechado lo vuelve mentira
El clasificador vive en el censo (`--names`), no en un script suelto, para que
el guard R-5.3 consuma la MISMA gramática que el codemod. Su muta-prueba
(`__names-mutatest.ts`, 27 casos) es lo que hizo el trabajo: cazó que yo
promovía al frente CUALQUIER valor declarado por el morfo, y así
`--sidebar-width-icon` (la anchura del raíl colapsado) se convertía en
`--sidebar-icon-width` (la anchura de un icono), que es otra cosa. La firma
dice «delante lo interactivo, detrás lo dimensional y contextual»: ahora sólo
promociona el vocabulario interactivo cerrado, y lo contextual —`below`,
`loaded`, `vertical`, `icon`— se queda donde estaba. Los cinco casos de
regresión están en la muta-prueba.
También cazó que `dropdown-menu.item-bg-hover` lee `var(--color-primary-element)`:
es un hover CON VALENCIA (el palette swap de recipe-contract §2), no el hover
bespoke que §38 deprecó. Clasificar por el nombre lo habría metido en una
migración que no le toca; se clasifica por el VALOR.
Verificación (§7.4, artefacto por paso):
diff de generated/ 269 renombres 1:1 · 0 cambios de valor · 22 privados
reapuntados a los nombres nuevos (`__names-verify-diff`)
computed tag-group · field · tabs: 6.467 valores en 23 estados,
0 diffs — y comprobado en el navegador que sirve el CSS
nuevo, para que ese 0 no sea el de una copia cacheada
huérfanos 0 en código
suite eidos 434 pasan · 1 rojo, el conocido (`skin-media-player`).
`recipe-css-contract` verde: es el guard que caza el
`var()` sin fallback a un nombre que ya no se emite,
o sea el fallo exacto de un rename a medias
component:audit 163 PASS · 3 NEEDS-WORK, los tres SIN TOCAR por esto
check 0 errores en ficheros tocados (los 73 globales son de
otras sesiones de la rama; se atribuye por fichero)
rtl:check 0 · docs:check 0
formato el renombrado no alarga ninguna línea: ningún fichero
tiene más líneas de 100 chars que antes, así que no se
pasa prettier — hacerlo reformateaba 300 ficheros de
deriva ajena
Entra aquí la corrección del repaso de los 7 ya hechos:
`gradient-builder.checker-color` → `checker-fg` (el damero de transparencia;
ahí `color` era slot). Sus `stop-color-*` no se tocan.
Queda para el paso siguiente: R-5.3 no puede graduar a `error` directo
mientras los 47 hovers neutros sigan hablando el idioma viejo — o migran
antes (firma 3, ya firmada), o el guard necesita una exención greppable.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| `--_background-scrim-ink` | 4 | `var(--background-scrim-fg)` , `var(--background-scrim-fg-over-dark)` , `var(--background-scrim-fg-over-light)` , `var(--palette-solid, var(--background-scrim-fg))` | public | **sí** |
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
| `--_background-scrim-weight` | 5 | `var(--background-scrim-strength-md)` , `var(--background-scrim-strength-xs)` , `var(--background-scrim-strength-sm)` , `var(--background-scrim-strength-lg)` , `var(--background-scrim-strength-xl)` | public | **sí** |
| `--_background-parallax-offset` | 3 | `calc(var(--_background-parallax-travel) * -1)` , `var(--_background-parallax-travel)` , `calc( (var(--background-progress, 0.5) - 0.5) * 2 * var(--_background-parallax-travel) )` | private, public | no |
| `--_background-parallax-travel` | 1 | `calc( var(--background-parallax-travel) * var(--_background-speed, 0) )` | public | **sí** |
| `--_background-bleed-size` | 1 | `var( --_background-bleed, max(var(--_background-parallax-travel), var(--_background-parallax-travel) * -1) )` | private | no |
refactor(eidos): el catálogo habla un idioma — 269 claves al vocabulario firmado
D-TH.6, ejecutada. El slot de tinta pasa a `fg` y el modificador interactivo
se pone delante, que es lo que theming §6.7 r7 documentaba sin guard desde
que se escribió. Value-preserving: renombra la clave en `recipes/base.ts` y
sus 793 referencias en 101 ficheros; no toca un solo valor.
claves renombradas 269 en 66 componentes
referencias 793 en 101 ficheros
censo antes/después 162 recetas · 5.203 knobs · 1.841 públicos (37 %) · 56
sin contrato — IDÉNTICO, como debe ser un rename
--names antes/después 269 desviadas → 0
Qué NO entra, y por qué:
47 `{rol}-{slot-de-rol}` canónicas: COLOR_ROLE_SLOTS pone el modificador
detrás POR CONSTRUCCIÓN (`primary-solid-hover`)
13 exentas firmadas `--focus-ring-*` es familia del sistema; el color
de `aura` es un sustantivo; `stop-color` ES una
parte de gradient-builder
47 hovers neutros por VALOR: migran a la capa de estado
(§38 + R-4.3), no se renombran — firma 3
6 ocurrencias en historia changelog, errores-toxico, PLAN-affix/background:
reescribir un registro fechado lo vuelve mentira
El clasificador vive en el censo (`--names`), no en un script suelto, para que
el guard R-5.3 consuma la MISMA gramática que el codemod. Su muta-prueba
(`__names-mutatest.ts`, 27 casos) es lo que hizo el trabajo: cazó que yo
promovía al frente CUALQUIER valor declarado por el morfo, y así
`--sidebar-width-icon` (la anchura del raíl colapsado) se convertía en
`--sidebar-icon-width` (la anchura de un icono), que es otra cosa. La firma
dice «delante lo interactivo, detrás lo dimensional y contextual»: ahora sólo
promociona el vocabulario interactivo cerrado, y lo contextual —`below`,
`loaded`, `vertical`, `icon`— se queda donde estaba. Los cinco casos de
regresión están en la muta-prueba.
También cazó que `dropdown-menu.item-bg-hover` lee `var(--color-primary-element)`:
es un hover CON VALENCIA (el palette swap de recipe-contract §2), no el hover
bespoke que §38 deprecó. Clasificar por el nombre lo habría metido en una
migración que no le toca; se clasifica por el VALOR.
Verificación (§7.4, artefacto por paso):
diff de generated/ 269 renombres 1:1 · 0 cambios de valor · 22 privados
reapuntados a los nombres nuevos (`__names-verify-diff`)
computed tag-group · field · tabs: 6.467 valores en 23 estados,
0 diffs — y comprobado en el navegador que sirve el CSS
nuevo, para que ese 0 no sea el de una copia cacheada
huérfanos 0 en código
suite eidos 434 pasan · 1 rojo, el conocido (`skin-media-player`).
`recipe-css-contract` verde: es el guard que caza el
`var()` sin fallback a un nombre que ya no se emite,
o sea el fallo exacto de un rename a medias
component:audit 163 PASS · 3 NEEDS-WORK, los tres SIN TOCAR por esto
check 0 errores en ficheros tocados (los 73 globales son de
otras sesiones de la rama; se atribuye por fichero)
rtl:check 0 · docs:check 0
formato el renombrado no alarga ninguna línea: ningún fichero
tiene más líneas de 100 chars que antes, así que no se
pasa prettier — hacerlo reformateaba 300 ficheros de
deriva ajena
Entra aquí la corrección del repaso de los 7 ya hechos:
`gradient-builder.checker-color` → `checker-fg` (el damero de transparencia;
ahí `color` era slot). Sus `stop-color-*` no se tocan.
Queda para el paso siguiente: R-5.3 no puede graduar a `error` directo
mientras los 47 hovers neutros sigan hablando el idioma viejo — o migran
antes (firma 3, ya firmada), o el guard necesita una exención greppable.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| `--_background-spotlight-ink` | 2 | `var(--background-spotlight-fg)` , `var(--palette-solid, var(--background-spotlight-fg))` | public | **sí** |
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
Consumidos y **no declarados en el CSS** (vienen de `base.ts` o de un estilo inline del wrapper): `--_background-bleed` , `--_background-depth` , `--_background-gradient-image` , `--_background-speed` .
## 4. Propuesta de corrección
uix(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
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 (`--background-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
uix(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| `layer-bg-image` | `root` | `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E")` | 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
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
### 4.2 Sin nombre mecánico (3)
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: `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** — 2: `inline-size` , `block-size` .
- **⚠ 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** — 1: `background` .
### 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(background): temable — 57 % → 95 %, y montar MÁS capas hacía medir MENOS
Seis claves nuevas (31 → 37), tres literales firmados, un privado adjudicado y
19 tokens preexistentes medidos uno a uno: no había pasado por R-5.4.
LAS SEIS CLAVES SON LA MISMA COSTURA, DOS VECES
El patrón mesh leía var(--gradient-aurora) y los cinco pasos de escarcha leían
var(--blur-*), los dos A PELO: el VALOR es del sistema, el KNOB es del
componente. Con scrim-blur-* hay además una razón dura — `blur` es familia
MÉTRICA del eje `scaling` (theming §23), así que un literal ahí sería ciego al
zoom global.
TRES LITERALES FIRMADOS, Y EL GRANO NO SE ACUÑA
El 100% de img/video es identidad (una capa de medio ES la caja de su capa). El
grano del ruido es un feTurbulence en un data-URI: la textura ES la técnica —el
único patrón que el UA no elimina bajo forced-colors— y re-escaparlo para
meterlo en el contrato cambiaría el valor serializado sin cambiar la imagen. Su
mando sigue siendo pattern-noise-opacity.
EL 5 % QUE QUEDA ES CANAL DE VALOR
--_background-gradient-image lo escribe background-gradient.svelte EN LÍNEA
desde la prop `colors`. Un público encima no lo alcanzaría —el inline gana— y
mentiría: el caso de --gp-current-gradient y del preview-z que F2-B retiró.
UNA SOSPECHA MÍA, REFUTADA MIDIENDO
La línea del mesh hace lo que un apunte da por roto: un gradiente MESH por el
longhand background-image (su color base final no es capa de imagen válida →
computa `none`). Medido aquí: --gradient-aurora PINTA, porque su serialización
empieza por un radial-gradient. No hay defecto. La nota vale para un mesh
serializado con color base final, no para este token.
EL GUARD: DE 3/37 A 18/37, Y UNA LECCIÓN AL REVÉS
Las partes de este componente son CAPAS OPT-IN independientes (velo, foco,
pausa…), cada una tras su control, y sólo un patrón se renderiza a la vez: sobre
el escenario por defecto casi todo el contrato no tiene nodo que pintar. Nace
`prepareWith` — enciende TODOS los controles que se le den, al contrario que
`openWith`, que para en el primero — y con el barrido de data-pattern sube a 18.
Y la lección: MONTAR MÁS PUEDE MEDIR MENOS. Encender además el foco puntual, la
velocidad de paralaje y la profundidad bajó la corrida de 17 a 9: los tres
repintan el background-image y el translate de la MISMA capa donde se miden los
patrones. prepareWith se dejó en lo que no tapa.
LAS 19 ADJUDICACIONES, FORZANDO SOBRE LA CAPA REAL
Nunca sobre un nodo fabricado. Las dos del mask (fade-*, que el guard no puede
ver porque no fotografía mask-image — hueco de instrumento, §13), las dos del
contexto de tinta (on=dark/light), los ocho pasos de las dos escalas (blur 4→33,
8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4 · 0.7 → 0.9), el
gradient-drift-duration (24s → 42s, en una capa gradient que EXCLUYE a la de
patrón), los tres del foco puntual (40% → 42px…, y spotlight-fg sólo cuando la
capa NO lleva data-color: con él manda --palette-solid, por diseño), el
parallax-travel (sólo entra por las keyframes ligadas al scroll) y los dos de la
pausa (la demo no monta ese control: cero nodos).
AVISO: LOS CHIPS DE ESTA DEMO SE APLICAN CON RETRASO
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada IGUAL en las dos
corridas: un gate verde sobre dos medidas equivocadas. La prueba buena fue la de
EQUIVALENCIA, determinista: cada token nuevo resuelve al mismo valor que el
primitivo que sustituyó (pattern-mesh-image = --gradient-aurora; scrim-blur-{k}
= --blur-{k} = 4/8/12/16/24 px) y lo pintado al forzar el atributo es idéntico
(el mesh pinta el aurora, el ruido pinta su data-URI intacto).
VERIFICACIÓN
Sonda estándar antes/después 0 diffs (384 valores · 7 estados) · equivalencia
token↔primitivo exacta en las seis · R-5.4 18/37 con las 19 restantes
adjudicadas y medidas, cero STALE · component:audit PASS · censo 95 % ·
eidos-lint 3 morfo-backed / 63 eidos-only / 0 invalid / 0 class-hooks ·
rtl:check 0 · docs:check 0 · suite eidos 439/440 (el rojo es skin-media-player,
el conocido). Tras el cambio del guard, command, table, tooltip,
navigation-menu y waveform re-verificados sin regresión ni STALE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**EJECUTADO 2026-08-23 — 57 % → 95 %.** Seis claves nuevas (31 → 37), tres
literales firmados, un privado adjudicado y **19 tokens preexistentes medidos
uno a uno**: el componente no había pasado por R-5.4.
**Las seis claves son la MISMA costura, dos veces.** El patrón `mesh` leía
`var(--gradient-aurora)` y los cinco pasos de escarcha leían `var(--blur-*)` ,
los dos a pelo: el VALOR es del sistema, el KNOB es del componente. Con
`scrim-blur-*` hay además una razón dura — `blur` es familia MÉTRICA del eje
`scaling` (theming §23), así que un literal ahí sería ciego al zoom global.
**Tres literales firmados.** El `100%` de `img` / `video` es identidad (una capa
de medio ES la caja de su capa). Y el **grano del ruido no se acuña** : es un
`feTurbulence` en un data-URI, la textura ES la técnica —el único patrón que el
UA no elimina bajo `forced-colors` — y re-escaparlo para meterlo en el contrato
cambiaría el valor serializado sin cambiar la imagen. Su mando sigue siendo
`pattern-noise-opacity` .
**El 5 % que queda es el privado, y es canal de valor.**
`--_background-gradient-image` lo escribe `background-gradient.svelte` EN LÍNEA
desde la prop `colors` . Un público encima no lo alcanzaría —el inline gana— y
mentiría: es el caso de `--gp-current-gradient` del gradient-picker y del
`preview-z` de drag-drop que la revisión de F2-B retiró.
**Una sospecha mía, refutada midiendo.** La línea del mesh hacía exactamente lo
que un apunte de referencia da por roto: un gradiente MESH consumido por el
longhand `background-image` (su color base final no es una capa de imagen
válida, así que computa `none` ). Medido aquí: `--gradient-aurora` **pinta** —su
serialización empieza por un `radial-gradient` y el navegador la acepta—, así
que no hay defecto. La nota vale para un mesh serializado con color base
final, no para este token.
**El guard midió 3 de 37 y ahora mide 18, con un campo nuevo.** Las partes de
este componente son CAPAS OPT-IN independientes (velo, foco, pausa…), cada una
tras su control, y sólo un patrón se renderiza a la vez: sobre el escenario por
defecto casi todo el contrato no tiene nodo que pintar. `prepareWith` (nuevo:
enciende TODOS los controles que se le den, al contrario que `openWith` , que
para en el primero) más el barrido de `data-pattern` lo llevan a 18.
**Y una lección del propio guard: montar MÁS puede medir MENOS.** Encender
además el foco puntual, la velocidad de paralaje y la profundidad hizo que la
corrida bajase de **17 a 9** : los tres repintan el `background-image` y el
`translate` de la misma capa donde se medían los patrones. `prepareWith` se dejó
en lo que no tapa.
**Las 19 adjudicaciones, todas medidas forzando el atributo sobre la capa REAL**
(nunca sobre un nodo fabricado): las dos del mask (`fade-*`, que el guard no
puede ver porque no fotografía `mask-image` — hueco de instrumento, §13), las
dos del contexto de tinta (`on='dark'` / `on='light'` ), los ocho pasos de las
dos escalas (blur 4→33, 8→33, 12→33, 24→33 px; strength alpha 0.08 · 0.13 · 0.4
· 0.7 → 0.9), el `gradient-drift-duration` (24s → 42s, en una capa `gradient`
que EXCLUYE a la de patrón), los tres del foco puntual (40% → 42px…, y
`spotlight-fg` sólo cuando la capa NO lleva `data-color` : con él manda
`--palette-solid` , por diseño), el `parallax-travel` (sólo entra por las
keyframes ligadas al scroll, que el escenario medido no tiene) y los dos de la
pausa (la demo no monta ese control: cero nodos en la página).
**Un aviso para quien mida aquí: los chips de esta demo se aplican con RETRASO.**
Una comparación por chips capturó cada estado con el patrón ANTERIOR —el estado
«mesh» guardaba el glow— y dio 0 diffs por estar desfasada igual en las dos
corridas. La prueba buena fue la de EQUIVALENCIA, determinista: cada token nuevo
resuelve al mismo valor que el primitivo que sustituyó
(`pattern-mesh-image` = `--gradient-aurora` ; `scrim-blur-{k}` = `--blur-{k}` =
4/8/12/16/24 px), y lo pintado al forzar el atributo es idéntico (el mesh pinta
el aurora, el ruido pinta su data-URI intacto).
**Verificación**: sonda estándar antes/después **0 diffs** (384 valores · 7
estados) · equivalencia token↔primitivo exacta en las seis claves · R-5.4 18/37
con las 19 restantes adjudicadas y medidas, cero STALE · `component:audit` PASS
· censo 95 % · `eidos-lint` 3 morfo-backed / 63 eidos-only / **0 invalid, 0
class-hooks** · `docs:check` 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
<!-- veredicto:end -->