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

176 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# chart — 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.
- **Medido**: 2026-08-23 · **Alcance**: **89%** — 81 de 91 knobs por token público
- **Knobs de apariencia**: 95 — público 81 · privado 0 · global 0 · literal 10 · sistema 4 · excepción 0 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 45 pública(s) — `line-width`, `axis-width`, `grid-width`, `bar-radius`, `point-radius`, `area-opacity`, `slice-stroke-width`, `transition-duration`, `transition-ease`, `tooltip-bg`, `tooltip-border`, `tooltip-radius`, `tooltip-shadow`, `tooltip-padding`, `tooltip-gap`, `crosshair-fg`, `crosshair-width`, `caption-font-size`, `caption-fg`, `label-font-size`, `label-fg`, `label-font-weight`, `gauge-label-font-size`, `axis-fg`, `grid-fg`, `separator-fg`, `smith-boundary-fg`, `track-bg`, `track-height`, `track-radius`, `gap`, `legend-row-gap`, `legend-column-gap`, `legend-item-gap`, `swatch-size`, `swatch-radius`, `tooltip-swatch-size`, `bar-list-row-gap`, `bar-list-column-gap`, `bar-segment-gap`, `bar-segment-track-gap`, `bar-segment-track-radius`, `bar-segment-fill-min-inline-size`, `bar-segment-legend-row-gap`, `bar-segment-legend-column-gap`
- **Eje `size`**: no · **ficheros**: `chart.css`
## 1. Knobs fuera de alcance
### 1.1 Directo a primitivo global (0)
_Ninguno._
### 1.2 A través de un privado (0)
_Ninguno._
### 1.3 Literales (10)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `chart.css:27` | `[data-chart-frame]` | `inline-size` | `100%` |
| 2 | `chart.css:31` | `[data-chart-plot]` | `inline-size` | `100%` |
| 3 | `chart.css:37` | `[data-chart]` | `inline-size` | `100%` |
| 4 | `chart.css:47` | `[data-chart-empty]` | `block-size` | `100%` |
| 5 | `chart.css:137` | `[data-chart-tooltip]` | `min-inline-size` | `max-content` |
| 6 | `chart.css:173` | `[data-chart-figure]` | `inline-size` | `100%` |
| 7 | `chart.css:217` | `[data-chart-bar-list]` | `inline-size` | `100%` |
| 8 | `chart.css:239` | `[data-chart-bar-list-bar]` | `block-size` | `100%` |
| 9 | `chart.css:256` | `[data-chart-bar-segment]` | `inline-size` | `100%` |
| 10 | `chart.css:266` | `[data-chart-bar-segment-fill]` | `block-size` | `100%` |
### 1.4 Excepciones firmadas (0) — fuera del ratio
Literales que llevan su anotación `/* literal: <razón> */` en la propia
declaración: la válvula de recipe-contract §3, la misma que honra
`component-audit`. **Una desviación firmada no es deuda** — se listan para que la
razón se lea, no para acuñarlas.
_Ninguno._
## 2. Sistema transversal (4) — 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 | `chart.css:273` | `[data-chart-bar-segment-fill][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 2 | `chart.css:315` | `[data-chart-heat-cell][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 3 | `chart.css:323` | `[data-chart-cal-cell][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 4 | `chart.css:363` | `[data-chart-polar-petal][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
## 3. Privados de la receta — ¿de dónde sale su valor?
_La receta no declara privados propios en su CSS._
## 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 (`--chart-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
| `tooltip-width` | `root` | `max-content` | 1 |
### 4.2 Sin nombre mecánico (9)
- **⚠ 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** — 9: `inline-size`, `block-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
<!-- veredicto:start -->
**EJECUTADO 2026-08-22 — 9 % → 49 % → 89 %**, en dos pasadas: 22 claves de
tinta-no-texto y geometría, y luego **6 de COSTURA para el texto**. El 89 % es
el techo: lo que queda fuera son los diez literales de identidad.
**La propuesta §4 pedía 71 claves y habría escrito ~20 con el MISMO valor.** La
medición que lo decidió: las 84 filas fuera de alcance colapsaban a **26 valores
distintos** — 9× `content-secondary`, 9× `content-primary`, 9× `100%`, 6×
`font-size-sm`, 6× `font-size-xs`, 6× `font-weight-medium`, 5×
`surface-default`, 4× `radius-sm`, 3× `border-default`. Nombrar por parte
habría dado cinco claves para el pelo que separa marcas y nueve para la tinta
de anotación. Es la inflación que F2-B ya cazó en `spinner`, con otra forma.
**El texto adopta DOS ROLES del canon, con costura** (firmado 2026-08-22). La
primera pasada dejó el CSS leyendo `var(--style-caption-font-size)` y
`var(--color-content-*)` a pelo: el VALOR era correcto pero faltaba la costura
que PLAN §2-A exige —todo knob lee `--{c}-{slot}`—, y sin ella un tema no puede
aclarar las anotaciones de un gráfico denso sin mover `caption` en toda la app,
ni `getRecipeTokens()` ve esa superficie. Seis claves:
```
--chart-caption-font-size var(--style-caption-font-size) eje · leyenda · tooltip · smith
--chart-caption-fg var(--style-caption-color)
--chart-label-font-size var(--style-label-font-size) título · bar-list · funnel · empty
--chart-label-fg var(--style-label-color)
--chart-label-font-weight var(--style-label-font-weight) los seis nodos en medium
--chart-gauge-label-font-size var(--size-xl-font-size) el readout, sin rol en el canon
```
Es el molde que la propia vertebración tipográfica documenta
(`--accordion-trigger-font-family: var(--style-label-font-family)`), y NO el
alias que §39 mató: aquello espejaba 36 claves de una capa; esto acuña **una
costura por eje**, tres ejes sobre 19 nodos de texto. **Tamaño y tinta son
ortogonales a propósito**: `empty` y `bar-list-value` son tamaño `label` con
tinta `caption`, y el CSS lo dice.
D-TH.2 no aplica aquí y su propio texto lo aclara: los seis primitivos
tipográficos quedan fuera porque la capa ES su API, y «un componente que sólo
LEE un named style para un eje no es un primitivo y no está en el conjunto».
**Con la costura, `global` cae a CERO** y el alcance a 89 %. La nota que dejé
en §13 diciendo que el censo penalizaba hacer lo correcto era mía y estaba
equivocada: el censo medía bien, faltaba la costura.
**Lo que la receta sí posee: la tinta de lo que no es texto** — cinco claves,
cada una un concepto que el CSS repite: `axis-fg` (eje + rejilla smith +
conector del funnel), `grid-fg` (rejilla + radar), `separator-fg` (el pelo de
superficie entre marcas contiguas: porción, punto activo, punto smith, pétalo,
segmento), `smith-boundary-fg` (el borde del disco, más fuerte a propósito) y
`track-bg` (raíl del bar-list y del gauge). Más 17 de geometría de cromo.
**Un incumplimiento heredado, corregido**: el CSS leía
`var(--control-height-sm, var(--space-7))` — coordenada CRUDA, que
`recipe-css-contract` prohíbe en un token de receta, con un respaldo muerto (el
primitivo existe). El contrato guarda `var(--size-sm-control-height)`, el
bundle, que es 1:1 con él.
**Fuera de contrato por identidad** (los 10 literales): nueve `100%` que
significan «ocupa a tu padre» y el `min-inline-size: max-content` del tooltip,
que es la corrección de composición de la misma clase ya adjudicada en
`date-picker`. Moverlos no es tematizar, es romper el layout.
**La escotilla del gauge, cerrada**: su número es un READOUT de dato y ningún
estilo con nombre juega ese papel (un `h2` es un encabezado), así que su
costura toma el bundle de talla en vez de un rol.
**El instrumento estaba ciego de tres maneras, y las tres se arreglaron ANTES
de medir** (ninguna era culpa de los tokens):
1. **La superficie de chart vive en DIECISÉIS rutas de demo**, una por tipo de
gráfico: `/chart` monta una línea con área y nada más (58 nodos de 302 en la
página). El guard ganó `urls` — un token está VIVO si alguna superficie del
componente lo sigue— y la sonda se corrió por las dieciséis.
2. **El guard no leía NINGUNA propiedad SVG.** Sin `fill` / `stroke` /
`strokeWidth` / `fillOpacity` / `r` / `rx`, doce de las 39 claves de un
componente que dibuja en SVG leían muertas estando vivas. Misma clase que el
hueco de `filter` / `backdrop-filter` del día anterior.
3. **El valor centinela se elegía por SUBCADENA**: `slice-stroke-width` recibía
`rgb(1, 2, 3)` por contener «stroke», valor inválido para una longitud, y
leía muerta. Ahora la dimensión se decide por el final del nombre.
Con eso: sonda **0 diffs en 161.850 valores computados** (16 rutas × 7 estados)
y centinela **37/39**, con `transition-duration` y `-ease` adjudicadas y
medidas sin la congelación (0.12s → 11.5s · cubic-bezier → steps(4)).
<!-- veredicto:end -->

Powered by TurnKey Linux.