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

7.0 KiB

knob — 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-22 · Alcance: 75% — 18 de 24 knobs por token público
  • Knobs de apariencia: 27 — público 18 · privado 1 · global 1 · literal 4 · sistema 3 (fuera del ratio)
  • Contrato hoy (lib/recipes/base.ts): 33 pública(s) — gap-sm, gap-md, gap-lg, gap-xl, diameter-sm, diameter-md, diameter-lg, diameter-xl, label-font-size-sm, label-font-size-md, label-font-size-lg, label-font-size-xl, value-font-size-sm, value-font-size-md, value-font-size-lg, value-font-size-xl, gap, diameter, label-font-size, value-font-size, radius, shadow, dragging-shadow, track-bg, face-bg, arc-width, pointer-inset, pointer-width, pointer-bg, indicator-radius, value-fg, label-fg, label-line-height
  • Eje size: no · ficheros: knob.css

1. Knobs fuera de alcance

1.1 Directo a primitivo global (1)

# fichero:línea selector propiedad valor
1 knob.css:127 [data-knob-value-field] [data-spin-field-input]:focus-visible border-radius var(--radius-sm)

1.2 A través de un privado (1)

# fichero:línea selector propiedad valor
1 knob.css:114 [data-knob-value-field] [data-spin-field-input] inline-size calc(var(--_knob-value-digits, 3) * 1ch)

1.3 Literales (4)

# fichero:línea selector propiedad valor
1 knob.css:71 [data-knob-value-text] line-height 1
2 knob.css:120 [data-knob-value-field] [data-spin-field-input] line-height 1
3 knob.css:149 [data-knob-indicator]::before block-size 28%
4 knob.css:159 [data-knob-control]:hover filter brightness(1.08)

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 knob.css:125 [data-knob-value-field] [data-spin-field-input]:focus-visible outline var(--focus-ring-width) solid var(--focus-ring-color)
2 knob.css:163 [data-knob-control]:focus-visible outline var(--focus-ring-width) solid var(--focus-ring-color)
3 knob.css:174 [data-knob][data-disabled] [data-knob-control] opacity var(--opacity-disabled)

3. Privados de la receta — ¿de dónde sale su valor?

La receta no declara privados propios en su CSS.

Consumidos y no declarados en el CSS (vienen de base.ts o de un estilo inline del wrapper): --_knob-value-digits.

4. Propuesta de corrección

  • Consume la capa compartida spin-field. Un eje que la capa posee se consume como var(--_x, var(--x)); el consumidor no acuña --knob-{eje} para él — sería un vocabulario paralelo (README de eidos/components, «Capas compartidas» regla 2).

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

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 (--knob-…) scope TSC valor propuesto usos
value-field-radius root var(--radius-sm) 1
indicator-height root 28% 1
hover-control-filter root brightness(1.08) 1

4.2 Sin nombre mecánico (3)

  • ⚠ decisión: 1 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: line-height.
  • ⚠ 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: inline-size.

4.4 Lo que hay que comprobar a mano (PLAN-theming §1.3 · §7.4)

  • Privado que no deriva de un público — §3 lo marca; el privado debe leer el público o desaparecer.
  • Velo o acento en el nodo equivocado (archetype: 'item' en un envoltorio, un background en shorthand que mata la capa de estado) — se mide desde el píxel hacia arriba.
  • Doble animación al mover un sello a una superficie con animación propia — registro de animationstart/animationend.
  • Diff de computed = 0 en reposo · hover · abierto · disabled · foco, por talla, antes y después.
  • Centinela por token nuevo: valor imposible en el root → el nodo lo sigue. Si no, el token miente.

5. Veredicto

Medido 2026-08-22 (sonda ×2 = 0 diffs en 754 valores · 7 estados). El knob ya tenía siete públicos «de facto» —consumidos con la forma var(--knob-x, <default>)— pero ninguno declarado en el contrato, así que un tema no los ve en getRecipeTokens() y el censo los cuenta bien por casualidad. La tokenización consiste sobre todo en DECLARAR lo que ya se consume, y en separar dos cosas que compartían nombre.

  1. Cuatro --knob-* NO son de tema: son canal de valor. El provider los escribe INLINE desde el estado del control (knob-provider.svelte.ts:358): --knob-progress, --knob-angle, --knob-start-angle y --knob-sweep. Ningún contrato puede ganarles y ninguno debe intentarlo — es la clase de carousel.item-gap y de la z del preview de drag-drop.
  2. ⚠ --knob-arc-width significa DOS cosas con DOS defaults distintos: el inset de la cara del dial (--space-3, líneas 80 y 113) y la separación superior del puntero (--space-2, línea 165). Un tema que lo escriba mueve las tres a la vez, pero sin tema cada una vale algo distinto — «un nombre que no distingue lo que debería», que es la definición de colisión. Se separan: arc-width (la cara) y pointer-inset (el puntero), cada uno con su valor verbatim. Cambia la superficie, no el píxel.
  3. Las cuatro coordenadas por talla suben al TSC. Hoy el default por talla vive en un privado y el público es un OVERRIDE que va DELANTE (var(--knob-gap, var(--_knob-gap))), así que declarar --knob-gap en el contrato mataría la escala: ganaría siempre. La forma correcta es la del resto del eje — coordenadas {eje}-{k} + nombre resuelto por data-size, y la receta lee el resuelto a secas. El eje es sm|md|lg|xl, sin xs.
  4. El diámetro es control-height × 2 por talla: una PROPORCIÓN del bundle, que se conserva verbatim en cada coordenada.

Powered by TurnKey Linux.