16 KiB
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 · método y protocolo:PLAN-theming.md§1, §2, §7.
- Medido: 2026-08-19 · Alcance: 9% — 8 de 88 knobs por token público
- Knobs de apariencia: 92 — público 8 · privado 0 · global 66 · literal 14 · sistema 4 (fuera del ratio)
- Contrato hoy (
lib/recipes/base.ts): 17 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-color,crosshair-width - Eje
size: no · ficheros:chart.css
1. Knobs fuera de alcance
1.1 Directo a primitivo global (66)
| # | fichero:línea | selector | propiedad | valor |
|---|---|---|---|---|
| 1 | chart.css:14 |
[data-chart-frame] |
gap |
var(--space-2) |
| 2 | chart.css:36 |
[data-chart-empty] |
color |
var(--color-content-secondary) |
| 3 | chart.css:37 |
[data-chart-empty] |
font-size |
var(--font-size-sm) |
| 4 | chart.css:43 |
[data-chart-axis-line], [data-chart-axis-tick] |
stroke |
var(--color-border-default) |
| 5 | chart.css:48 |
[data-chart-axis-label] |
fill |
var(--color-content-secondary) |
| 6 | chart.css:49 |
[data-chart-axis-label] |
font-size |
var(--font-size-xs) |
| 7 | chart.css:54 |
[data-chart-grid-line] |
stroke |
var(--color-border-subtle) |
| 8 | chart.css:82 |
[data-chart-slice] |
stroke |
var(--color-surface-default) |
| 9 | chart.css:98 |
[data-chart-active-dot] |
stroke |
var(--color-surface-default) |
| 10 | chart.css:123 |
[data-chart-tooltip] |
font-size |
var(--font-size-xs) |
| 11 | chart.css:124 |
[data-chart-tooltip] |
color |
var(--color-content-primary) |
| 12 | chart.css:131 |
[data-chart-tooltip-x] |
font-weight |
var(--font-weight-medium) |
| 13 | chart.css:132 |
[data-chart-tooltip-x] |
color |
var(--color-content-primary) |
| 14 | chart.css:138 |
[data-chart-tooltip-row] |
color |
var(--color-content-secondary) |
| 15 | chart.css:143 |
[data-chart-tooltip-swatch] |
border-radius |
var(--radius-sm) |
| 16 | chart.css:149 |
[data-chart-tooltip-value] |
color |
var(--color-content-primary) |
| 17 | chart.css:160 |
[data-chart-figure] |
gap |
var(--space-2) |
| 18 | chart.css:166 |
[data-chart-title] |
font-size |
var(--font-size-sm) |
| 19 | chart.css:167 |
[data-chart-title] |
font-weight |
var(--font-weight-medium) |
| 20 | chart.css:168 |
[data-chart-title] |
color |
var(--color-content-primary) |
| 21 | chart.css:174 |
[data-chart-legend] |
gap |
var(--space-1-5) var(--space-4) |
| 22 | chart.css:181 |
[data-chart-legend-item] |
gap |
var(--space-1-5) |
| 23 | chart.css:182 |
[data-chart-legend-item] |
font-size |
var(--font-size-xs) |
| 24 | chart.css:183 |
[data-chart-legend-item] |
color |
var(--color-content-secondary) |
| 25 | chart.css:189 |
[data-chart-swatch] |
border-radius |
var(--radius-sm) |
| 26 | chart.css:202 |
[data-chart-bar-list] |
gap |
var(--space-2) var(--space-3) |
| 27 | chart.css:212 |
[data-chart-bar-list-label] |
font-size |
var(--font-size-sm) |
| 28 | chart.css:213 |
[data-chart-bar-list-label] |
color |
var(--color-content-primary) |
| 29 | chart.css:219 |
[data-chart-bar-list-track] |
block-size |
var(--control-height-sm, var(--space-7)) |
| 30 | chart.css:220 |
[data-chart-bar-list-track] |
background |
var(--color-surface-muted) |
| 31 | chart.css:221 |
[data-chart-bar-list-track] |
border-radius |
var(--radius-sm) |
| 32 | chart.css:226 |
[data-chart-bar-list-bar] |
border-radius |
var(--radius-sm) |
| 33 | chart.css:230 |
[data-chart-bar-list-value] |
font-size |
var(--font-size-sm) |
| 34 | chart.css:231 |
[data-chart-bar-list-value] |
color |
var(--color-content-secondary) |
| 35 | chart.css:241 |
[data-chart-bar-segment] |
gap |
var(--space-3) |
| 36 | chart.css:246 |
[data-chart-bar-segment-track] |
gap |
var(--border-width-medium) |
| 37 | chart.css:247 |
[data-chart-bar-segment-track] |
block-size |
var(--control-height-sm, var(--space-7)) |
| 38 | chart.css:248 |
[data-chart-bar-segment-track] |
border-radius |
var(--radius-md) |
| 39 | chart.css:253 |
[data-chart-bar-segment-fill] |
min-inline-size |
var(--border-width-thick) |
| 40 | chart.css:264 |
[data-chart-bar-segment-legend] |
gap |
var(--space-2) var(--space-4) |
| 41 | chart.css:269 |
[data-chart-bar-segment-legend-item] |
gap |
var(--space-1-5) |
| 42 | chart.css:270 |
[data-chart-bar-segment-legend-item] |
font-size |
var(--font-size-xs) |
| 43 | chart.css:271 |
[data-chart-bar-segment-legend-item] |
color |
var(--color-content-secondary) |
| 44 | chart.css:274 |
[data-chart-bar-segment-legend-value] |
color |
var(--color-content-primary) |
| 45 | chart.css:282 |
[data-chart-radar-ring], [data-chart-radar-spoke] |
stroke |
var(--color-border-subtle) |
| 46 | chart.css:313 |
[data-chart-smith-boundary] |
stroke |
var(--color-content-secondary) |
| 47 | chart.css:318 |
[data-chart-smith-grid] |
stroke |
var(--color-border-default) |
| 48 | chart.css:322 |
[data-chart-smith-label] |
fill |
var(--color-content-secondary) |
| 49 | chart.css:323 |
[data-chart-smith-label] |
font-size |
var(--font-size-xs) |
| 50 | chart.css:328 |
[data-chart-smith-point] |
stroke |
var(--color-surface-default) |
| 51 | chart.css:332 |
[data-chart-smith-point-label] |
fill |
var(--color-content-primary) |
| 52 | chart.css:333 |
[data-chart-smith-point-label] |
font-size |
var(--font-size-xs) |
| 53 | chart.css:334 |
[data-chart-smith-point-label] |
font-weight |
var(--font-weight-medium) |
| 54 | chart.css:340 |
[data-chart-polar-petal] |
stroke |
var(--color-surface-default) |
| 55 | chart.css:353 |
[data-chart-funnel-segment] |
stroke |
var(--color-surface-default) |
| 56 | chart.css:357 |
[data-chart-funnel-label] |
font-size |
var(--font-size-sm) |
| 57 | chart.css:358 |
[data-chart-funnel-label] |
font-weight |
var(--font-weight-medium) |
| 58 | chart.css:363 |
[data-chart-funnel-connector] |
stroke |
var(--color-border-default) |
| 59 | chart.css:367 |
[data-chart-funnel-side] |
font-size |
var(--font-size-sm) |
| 60 | chart.css:370 |
[data-chart-funnel-name] |
fill |
var(--color-content-primary) |
| 61 | chart.css:371 |
[data-chart-funnel-name] |
font-weight |
var(--font-weight-medium) |
| 62 | chart.css:374 |
[data-chart-funnel-meta] |
fill |
var(--color-content-secondary) |
| 63 | chart.css:380 |
[data-chart-gauge-track] |
fill |
var(--color-surface-muted) |
| 64 | chart.css:386 |
[data-chart-gauge-label] |
fill |
var(--color-content-primary) |
| 65 | chart.css:387 |
[data-chart-gauge-label] |
font-size |
var(--font-size-xl) |
| 66 | chart.css:388 |
[data-chart-gauge-label] |
font-weight |
var(--font-weight-medium) |
1.2 A través de un privado (0)
Ninguno.
1.3 Literales (14)
| # | fichero:línea | selector | propiedad | valor |
|---|---|---|---|---|
| 1 | chart.css:15 |
[data-chart-frame] |
inline-size |
100% |
| 2 | chart.css:19 |
[data-chart-plot] |
inline-size |
100% |
| 3 | chart.css:25 |
[data-chart] |
inline-size |
100% |
| 4 | chart.css:35 |
[data-chart-empty] |
block-size |
100% |
| 5 | chart.css:125 |
[data-chart-tooltip] |
min-inline-size |
max-content |
| 6 | chart.css:141 |
[data-chart-tooltip-swatch] |
inline-size |
0.6em |
| 7 | chart.css:142 |
[data-chart-tooltip-swatch] |
block-size |
0.6em |
| 8 | chart.css:161 |
[data-chart-figure] |
inline-size |
100% |
| 9 | chart.css:187 |
[data-chart-swatch] |
inline-size |
0.75em |
| 10 | chart.css:188 |
[data-chart-swatch] |
block-size |
0.75em |
| 11 | chart.css:203 |
[data-chart-bar-list] |
inline-size |
100% |
| 12 | chart.css:225 |
[data-chart-bar-list-bar] |
block-size |
100% |
| 13 | chart.css:242 |
[data-chart-bar-segment] |
inline-size |
100% |
| 14 | chart.css:252 |
[data-chart-bar-segment-fill] |
block-size |
100% |
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:259 |
[data-chart-bar-segment-fill][data-dim='true'] |
opacity |
var(--opacity-scrim) |
| 2 | chart.css:300 |
[data-chart-heat-cell][data-dim='true'] |
opacity |
var(--opacity-scrim) |
| 3 | chart.css:308 |
[data-chart-cal-cell][data-dim='true'] |
opacity |
var(--opacity-scrim) |
| 4 | chart.css:348 |
[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 (71)
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 |
|---|---|---|---|
frame-gap |
root |
var(--space-2) |
1 |
empty-fg |
root |
var(--color-content-secondary) |
1 |
empty-font-size |
root |
var(--font-size-sm) |
1 |
axis-line-stroke |
root |
var(--color-border-default) |
1 |
axis-label-fill |
root |
var(--color-content-secondary) |
1 |
axis-label-font-size |
root |
var(--font-size-xs) |
1 |
grid-line-stroke |
root |
var(--color-border-subtle) |
1 |
slice-stroke |
root |
var(--color-surface-default) |
1 |
active-dot-stroke |
root |
var(--color-surface-default) |
1 |
tooltip-font-size |
root |
var(--font-size-xs) |
1 |
tooltip-fg |
root |
var(--color-content-primary) |
1 |
tooltip-width |
root |
max-content |
1 |
tooltip-x-font-weight |
root |
var(--font-weight-medium) |
1 |
tooltip-x-fg |
root |
var(--color-content-primary) |
1 |
tooltip-row-fg |
root |
var(--color-content-secondary) |
1 |
tooltip-swatch-width |
root |
0.6em |
1 |
tooltip-swatch-height |
root |
0.6em |
1 |
tooltip-swatch-radius |
root |
var(--radius-sm) |
1 |
tooltip-value-fg |
root |
var(--color-content-primary) |
1 |
figure-gap |
root |
var(--space-2) |
1 |
title-font-size |
root |
var(--font-size-sm) |
1 |
title-font-weight |
root |
var(--font-weight-medium) |
1 |
title-fg |
root |
var(--color-content-primary) |
1 |
legend-gap |
root |
var(--space-1-5) var(--space-4) |
1 |
legend-item-gap |
root |
var(--space-1-5) |
1 |
legend-item-font-size |
root |
var(--font-size-xs) |
1 |
legend-item-fg |
root |
var(--color-content-secondary) |
1 |
swatch-width |
root |
0.75em |
1 |
swatch-height |
root |
0.75em |
1 |
swatch-radius |
root |
var(--radius-sm) |
1 |
bar-list-gap |
root |
var(--space-2) var(--space-3) |
1 |
bar-list-label-font-size |
root |
var(--font-size-sm) |
1 |
bar-list-label-fg |
root |
var(--color-content-primary) |
1 |
bar-list-track-height |
root |
var(--control-height-sm, var(--space-7)) |
1 |
bar-list-track-bg |
root |
var(--color-surface-muted) |
1 |
bar-list-track-radius |
root |
var(--radius-sm) |
1 |
bar-list-bar-radius |
root |
var(--radius-sm) |
1 |
bar-list-value-font-size |
root |
var(--font-size-sm) |
1 |
bar-list-value-fg |
root |
var(--color-content-secondary) |
1 |
bar-segment-gap |
root |
var(--space-3) |
1 |
bar-segment-track-gap |
root |
var(--border-width-medium) |
1 |
bar-segment-track-height |
root |
var(--control-height-sm, var(--space-7)) |
1 |
bar-segment-track-radius |
root |
var(--radius-md) |
1 |
bar-segment-fill-width |
root |
var(--border-width-thick) |
1 |
bar-segment-legend-gap |
root |
var(--space-2) var(--space-4) |
1 |
bar-segment-legend-item-gap |
root |
var(--space-1-5) |
1 |
bar-segment-legend-item-font-size |
root |
var(--font-size-xs) |
1 |
bar-segment-legend-item-fg |
root |
var(--color-content-secondary) |
1 |
bar-segment-legend-value-fg |
root |
var(--color-content-primary) |
1 |
radar-ring-stroke |
root |
var(--color-border-subtle) |
1 |
smith-boundary-stroke |
root |
var(--color-content-secondary) |
1 |
smith-grid-stroke |
root |
var(--color-border-default) |
1 |
smith-label-fill |
root |
var(--color-content-secondary) |
1 |
smith-label-font-size |
root |
var(--font-size-xs) |
1 |
smith-point-stroke |
root |
var(--color-surface-default) |
1 |
smith-point-label-fill |
root |
var(--color-content-primary) |
1 |
smith-point-label-font-size |
root |
var(--font-size-xs) |
1 |
smith-point-label-font-weight |
root |
var(--font-weight-medium) |
1 |
polar-petal-stroke |
root |
var(--color-surface-default) |
1 |
funnel-segment-stroke |
root |
var(--color-surface-default) |
1 |
funnel-label-font-size |
root |
var(--font-size-sm) |
1 |
funnel-label-font-weight |
root |
var(--font-weight-medium) |
1 |
funnel-connector-stroke |
root |
var(--color-border-default) |
1 |
funnel-side-font-size |
root |
var(--font-size-sm) |
1 |
funnel-name-fill |
root |
var(--color-content-primary) |
1 |
funnel-name-font-weight |
root |
var(--font-weight-medium) |
1 |
funnel-meta-fill |
root |
var(--color-content-secondary) |
1 |
gauge-track-fill |
root |
var(--color-surface-muted) |
1 |
gauge-label-fill |
root |
var(--color-content-primary) |
1 |
gauge-label-font-size |
root |
var(--font-size-xl) |
1 |
gauge-label-font-weight |
root |
var(--font-weight-medium) |
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, unbackgrounden 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
(pendiente — lo escribe el autor; se conserva al regenerar)