From ebfa1ce5ef8a2d3c45726f7c0839bf27929b578d Mon Sep 17 00:00:00 2001 From: dev Date: Sun, 23 Aug 2026 22:29:46 +0200 Subject: [PATCH] =?UTF-8?q?fix(theming):=20el=20guard=20da=20por=20VIVO=20?= =?UTF-8?q?lo=20que=20un=20tema=20no=20alcanza=20=E2=80=94=20y=20dos=20blo?= =?UTF-8?q?ques=20del=20ledger=20se=20descartaban=20en=20silencio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dos defectos del instrumental, los dos medidos, ninguno arreglado en el guard todavía (el arreglo toca a todos los componentes y pide su re-verificación). EL GUARD TIENE FALSOS POSITIVOS: ESCRIBE EL CENTINELA EN EL style INLINE `staticPass` escribe el token en documentElement Y en todos los nodos del componente — y ahí es donde vive el canal inline de los wrappers. Si un wrapper escribe un token PÚBLICO en el `style` del nodo, el guard lo pisa, ve el cambio y lo da por VIVO, aunque un tema (que sólo puede escribir en :root o en una hoja) no lo alcance jamás. Es la cara opuesta de drag-drop.preview-z. Censo: siete wrappers escriben un --{c}-* público inline y DOS están en el contrato — dialog.overlay-opacity y drawer.overlay-opacity. Medido en dialog con el diálogo abierto y las animaciones congeladas: desde :root el fondo del velo NO se mueve (color(srgb 0.1098 0.098 0.0902 / 0.2518) idéntico), desde el inline SÍ. Su token MIENTE y el guard lo bendice. Los otros cinco no están en ningún contrato: son sólo canal. El arreglo propuesto va en §13: escribir en todos los nodos MENOS en los cuyo `style` ya declara ese mismo token, y avisar cuando ocurra — no basta con escribir sólo en :root, porque eso es justo lo que hace medibles los paneles portalados. Con re-verificación del ledger entero, así que no entra aquí. El veredicto de dialog (commiteado hoy) queda corregido con la medición. DOS BLOQUES DEL LEDGER SE DESCARTABAN EN SILENCIO `metrics` y `color-picker` aparecían DOS VECES en el mismo literal de objeto, así que el primero de cada par no existía para el guard — la trampa que el handoff documenta para base.ts, un piso más abajo. Comprobado antes de tocar nada: en los dos casos el bloque que gana es SUPERCONJUNTO del muerto, así que no se perdía ninguna adjudicación; era deuda con riesgo futuro, no un rojo. Retirados los dos bloques muertos: 69 → 67 entradas, cero duplicados, y `metrics` (54/72) y `color-picker` (46/71) siguen en verde. De paso, el fichero baja de 63 a 61 hunks de prettier preexistentes. Lo destapó la sesión de `progress` al leer el fichero para añadir su bloque. Rama con varias sesiones en paralelo: índice construido desde HEAD + sólo mis hunks, verificado con git diff --cached. Co-Authored-By: Claude Opus 5 --- docs/audit/theming/dialog.md | 12 ++++++++++++ docs/next-features.md | 23 +++++++++++++++++++++++ scripts/theming-sentinel-exceptions.ts | 13 ------------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/docs/audit/theming/dialog.md b/docs/audit/theming/dialog.md index 0f63c515e..3a5d3d849 100644 --- a/docs/audit/theming/dialog.md +++ b/docs/audit/theming/dialog.md @@ -131,6 +131,18 @@ botón de cierre **no lleva `data-position` en esta demo**, aunque todas las reglas que leen `close-inset` lo exigen. Forzar el atributo correcto las mueve las dos. +⚠⚠ **CORRECCIÓN del mismo día: `overlay-opacity` es un FALSO POSITIVO del +guard.** Lo dio por vivo, y no lo es: `dialog-overlay.svelte` escribe +`--dialog-overlay-opacity` en el `style` INLINE del velo, y el guard escribe su +centinela en el `style` de cada nodo — así que se pisa a sí mismo y ve un +cambio. Medido como lo haría un TEMA, sólo desde `:root` y con las animaciones +congeladas: el fondo del velo **no se mueve** +(`color(srgb 0.1098 0.098 0.0902 / 0.2518)` antes y después); desde el inline sí. +**La clave está en el contrato y ningún tema la alcanza.** Es la cara opuesta de +`drag-drop.preview-z` y la misma familia que el velo de `drawer` que no pinta. +Registrado en §13 con el arreglo propuesto para el guard; retirar o rescatar la +clave es decisión aparte, porque cambia quién controla la opacidad del velo. + **Verificación**: sonda antes/después **0 diffs** (480 valores · 8 estados · 8 nodos con el diálogo abierto) · R-5.4 **37/44** con las siete adjudicadas, exit 0 · `component:audit` PASS · censo 89 % con las cuatro escotillas explicadas · diff --git a/docs/next-features.md b/docs/next-features.md index 1f49e37e7..268940b23 100644 --- a/docs/next-features.md +++ b/docs/next-features.md @@ -1354,6 +1354,29 @@ Lo que `chart` destapó (2026-08-22): dimensionan por `-height-{k}`, uno por `-min-block-size-{k}`) y la tabla del propio censo, que ya mapea `min-block-size → height`. Extender R-5.3 con esa tabla —propiedad → ranura— cierra la clase entera. +- **⚠⚠ EL GUARD TIENE FALSOS POSITIVOS: escribe el centinela en el `style` INLINE + de cada nodo** (medido 2026-08-23). `staticPass` escribe el token en + `documentElement` **y en todos los nodos del componente**, y ahí es donde vive + el canal inline de los wrappers: si el wrapper escribe un token PÚBLICO en el + `style` del nodo, el guard lo pisa, ve el cambio y lo da por VIVO — aunque un + tema, que sólo puede escribir en `:root` o en una hoja, **no lo alcance + jamás**. Es la cara opuesta de `drag-drop.preview-z`. + + Censo de lo afectado: siete wrappers escriben un `--{c}-*` público inline y + **dos de ellos están en el contrato** — `dialog.overlay-opacity` y + `drawer.overlay-opacity`. Medido en `dialog` con el diálogo abierto y las + animaciones congeladas: desde `:root` el fondo del velo NO se mueve + (`color(srgb 0.1098 0.098 0.0902 / 0.2518)` idéntico), desde el inline SÍ. **Su + token miente**, y el guard lo da por bueno. Los otros cinco + (`avatar.badge-color-custom`, `emoji-picker.columns`, + `text-focus.border-color` / `-glow-color`, `text-gradient.duration`) no están + en ningún contrato, así que sólo son canal. + + El arreglo del guard: escribir el centinela **sólo en `:root` y en el host**, + nunca en el `style` de cada nodo — pero eso rompería la medida de los paneles + PORTALADOS, que es justo por lo que se escribe en todos. La forma correcta es + escribir en todos MENOS en los nodos cuyo `style` inline ya declara ese mismo + token, y avisar cuando eso ocurra. Con re-verificación del ledger entero. - **El guard no fotografía `translate` ni `transform`** (medido 2026-08-23 en `background`, y ya latente en `drawer.handle-active-scale`). El paralaje entra por `translate` sobre la capa; con `data-parallax` forzado y speed 1 el token diff --git a/scripts/theming-sentinel-exceptions.ts b/scripts/theming-sentinel-exceptions.ts index 2be245f21..996dbf2aa 100644 --- a/scripts/theming-sentinel-exceptions.ts +++ b/scripts/theming-sentinel-exceptions.ts @@ -590,12 +590,6 @@ export const SENTINEL_EXCEPTIONS: Record> = { // components). Writing the token moves nothing while the plane does. 'item-disabled-opacity': 'no disabled item in the demo; forced data-disabled -> reaches (0.55 -> 0.123)' }, - metrics: { - // The demo's icon runs the `rounded` shape; the other two only paint under - // their own data-shape value. Forced in place 2026-08-22. - 'icon-circle-radius': 'the demo icon is data-shape=rounded; forced circle -> reaches (9999px -> 1234px)', - 'icon-square-radius': 'same; forced square -> reaches (6px -> 1234px)' - }, 'float-panel': { // The demo mounts the DEFAULT variant and no generic action button (only the // close control). Forced in place 2026-08-22, transitions frozen. @@ -710,13 +704,6 @@ export const SENTINEL_EXCEPTIONS: Record> = { 'transition-duration': 'the guard freezes transitions on purpose; the orb tint and the arc stroke transition on it', 'transition-ease': 'same freeze, same pair of properties' }, - 'color-picker': { - // The demo mounts no swatch TRIGGER: its presets render as - // components, so the two parts these paint never enter the panel. Mounted - // inside the OPEN panel 2026-08-22 with the attrs the CSS selects. - 'swatch-border-width': 'no swatch trigger in the demo panel; mounted in place -> reaches (1px -> 1234px)', - 'swatch-ring-gap': 'the ring gap of the checked swatch and of its indicator; mounted in place -> reaches (oklch(0.9911 0 0) 0 0 0 1px -> rgb(1,2,3) 0 0 0 1px)' - }, popover: { // The demo renders neither Title nor Description. Mounted inside the OPEN // panel with the attrs the CSS selects (2026-08-22): all nine reach; the two