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

12 KiB

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 · método y protocolo: PLAN-theming.md §1, §2, §7.

  • Medido: 2026-08-24 · 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
  • Eje size: no · ficheros: background.css

1. Knobs fuera de alcance

1.1 Directo a primitivo global (0)

Ninguno.

1.2 A través de un privado (1)

# fichero:línea selector propiedad valor
1 background.css:265 [data-background-layer][data-kind='gradient'] background var(--_background-gradient-image, transparent)

1.3 Literales (0)

Ninguno.

1.4 Excepciones firmadas (3) — fuera del ratio

Literales que llevan su anotación /* literal: <razón> */ en la propia declaración: la válvula de recipe-contract §3, la misma que honra component-audit. Una desviación firmada no es deuda — se listan para que la razón se lea, no para acuñarlas.

# 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")

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í
--_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í
--_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
--_background-spotlight-ink 2 var(--background-spotlight-fg), var(--palette-solid, var(--background-spotlight-fg)) public sí

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

4.1 Tokens a declarar en lib/recipes/base.ts (1)

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
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

4.2 Sin nombre mecánico (3)

  • ⚠ 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

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.

Powered by TurnKey Linux.