@ -5,53 +5,16 @@
> Vista de conjunto: [README ](./README.md ) · método y protocolo:
> [`PLAN-theming.md` ](../../process/PLAN-theming.md ) §1, §2, §7.
- **Medido** : 2026-08-22 · **Alcance** : ** 49%** — 45 de 91 knobs por token público
- **Knobs de apariencia** : 95 — público 45 · privado 0 · global 36 · literal 10 · sistema 4 _(fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 39 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 `, `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`
- **Medido** : 2026-08-22 · **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 _(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 (36 )
### 1.1 Directo a primitivo global (0 )
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `chart.css:46` | `[data-chart-empty]` | `color` | `var(--color-content-secondary)` |
| 2 | `chart.css:47` | `[data-chart-empty]` | `font-size` | `var(--style-label-font-size)` |
| 3 | `chart.css:58` | `[data-chart-axis-label]` | `fill` | `var(--color-content-secondary)` |
| 4 | `chart.css:59` | `[data-chart-axis-label]` | `font-size` | `var(--style-caption-font-size)` |
| 5 | `chart.css:133` | `[data-chart-tooltip]` | `font-size` | `var(--style-caption-font-size)` |
| 6 | `chart.css:134` | `[data-chart-tooltip]` | `color` | `var(--color-content-primary)` |
| 7 | `chart.css:141` | `[data-chart-tooltip-x]` | `font-weight` | `var(--font-weight-medium)` |
| 8 | `chart.css:142` | `[data-chart-tooltip-x]` | `color` | `var(--color-content-primary)` |
| 9 | `chart.css:148` | `[data-chart-tooltip-row]` | `color` | `var(--color-content-secondary)` |
| 10 | `chart.css:159` | `[data-chart-tooltip-value]` | `color` | `var(--color-content-primary)` |
| 11 | `chart.css:176` | `[data-chart-title]` | `font-size` | `var(--style-label-font-size)` |
| 12 | `chart.css:177` | `[data-chart-title]` | `font-weight` | `var(--font-weight-medium)` |
| 13 | `chart.css:178` | `[data-chart-title]` | `color` | `var(--color-content-primary)` |
| 14 | `chart.css:193` | `[data-chart-legend-item]` | `font-size` | `var(--style-caption-font-size)` |
| 15 | `chart.css:194` | `[data-chart-legend-item]` | `color` | `var(--color-content-secondary)` |
| 16 | `chart.css:224` | `[data-chart-bar-list-label]` | `font-size` | `var(--style-label-font-size)` |
| 17 | `chart.css:225` | `[data-chart-bar-list-label]` | `color` | `var(--color-content-primary)` |
| 18 | `chart.css:242` | `[data-chart-bar-list-value]` | `font-size` | `var(--style-label-font-size)` |
| 19 | `chart.css:243` | `[data-chart-bar-list-value]` | `color` | `var(--color-content-secondary)` |
| 20 | `chart.css:283` | `[data-chart-bar-segment-legend-item]` | `font-size` | `var(--style-caption-font-size)` |
| 21 | `chart.css:284` | `[data-chart-bar-segment-legend-item]` | `color` | `var(--color-content-secondary)` |
| 22 | `chart.css:287` | `[data-chart-bar-segment-legend-value]` | `color` | `var(--color-content-primary)` |
| 23 | `chart.css:335` | `[data-chart-smith-label]` | `fill` | `var(--color-content-secondary)` |
| 24 | `chart.css:336` | `[data-chart-smith-label]` | `font-size` | `var(--style-caption-font-size)` |
| 25 | `chart.css:345` | `[data-chart-smith-point-label]` | `fill` | `var(--color-content-primary)` |
| 26 | `chart.css:346` | `[data-chart-smith-point-label]` | `font-size` | `var(--style-caption-font-size)` |
| 27 | `chart.css:347` | `[data-chart-smith-point-label]` | `font-weight` | `var(--font-weight-medium)` |
| 28 | `chart.css:370` | `[data-chart-funnel-label]` | `font-size` | `var(--style-label-font-size)` |
| 29 | `chart.css:371` | `[data-chart-funnel-label]` | `font-weight` | `var(--font-weight-medium)` |
| 30 | `chart.css:380` | `[data-chart-funnel-side]` | `font-size` | `var(--style-label-font-size)` |
| 31 | `chart.css:383` | `[data-chart-funnel-name]` | `fill` | `var(--color-content-primary)` |
| 32 | `chart.css:384` | `[data-chart-funnel-name]` | `font-weight` | `var(--font-weight-medium)` |
| 33 | `chart.css:387` | `[data-chart-funnel-meta]` | `fill` | `var(--color-content-secondary)` |
| 34 | `chart.css:399` | `[data-chart-gauge-label]` | `fill` | `var(--color-content-primary)` |
| 35 | `chart.css:400` | `[data-chart-gauge-label]` | `font-size` | `var(--font-size-xl)` |
| 36 | `chart.css:401` | `[data-chart-gauge-label]` | `font-weight` | `var(--font-weight-medium)` |
_Ninguno._
### 1.2 A través de un privado (0)
@ -61,16 +24,16 @@ _Ninguno._
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `chart.css:2 5 ` | `[data-chart-frame]` | `inline-size` | `100%` |
| 2 | `chart.css: 29 ` | `[data-chart-plot]` | `inline-size` | `100%` |
| 3 | `chart.css:3 5 ` | `[data-chart]` | `inline-size` | `100%` |
| 4 | `chart.css:4 5 ` | `[data-chart-empty]` | `block-size` | `100%` |
| 5 | `chart.css:13 5 ` | `[data-chart-tooltip]` | `min-inline-size` | `max-content` |
| 6 | `chart.css:17 1 ` | `[data-chart-figure]` | `inline-size` | `100%` |
| 7 | `chart.css:21 5 ` | `[data-chart-bar-list]` | `inline-size` | `100%` |
| 8 | `chart.css:23 7 ` | `[data-chart-bar-list-bar]` | `block-size` | `100%` |
| 9 | `chart.css:25 4 ` | `[data-chart-bar-segment]` | `inline-size` | `100%` |
| 10 | `chart.css:26 4 ` | `[data-chart-bar-segment-fill]` | `block-size` | `100%` |
| 1 | `chart.css:2 7 ` | `[data-chart-frame]` | `inline-size` | `100%` |
| 2 | `chart.css: 31 ` | `[data-chart-plot]` | `inline-size` | `100%` |
| 3 | `chart.css:3 7 ` | `[data-chart]` | `inline-size` | `100%` |
| 4 | `chart.css:4 7 ` | `[data-chart-empty]` | `block-size` | `100%` |
| 5 | `chart.css:13 7 ` | `[data-chart-tooltip]` | `min-inline-size` | `max-content` |
| 6 | `chart.css:17 3 ` | `[data-chart-figure]` | `inline-size` | `100%` |
| 7 | `chart.css:21 7 ` | `[data-chart-bar-list]` | `inline-size` | `100%` |
| 8 | `chart.css:23 9 ` | `[data-chart-bar-list-bar]` | `block-size` | `100%` |
| 9 | `chart.css:25 6 ` | `[data-chart-bar-segment]` | `inline-size` | `100%` |
| 10 | `chart.css:26 6 ` | `[data-chart-bar-segment-fill]` | `block-size` | `100%` |
## 2. Sistema transversal (4) — informativo, fuera del ratio
@ -78,10 +41,10 @@ Un tema los alcanza **a nivel de sistema**, por diseño (recipe-contract §2).
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `chart.css:27 1 ` | `[data-chart-bar-segment-fill][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 2 | `chart.css:31 3 ` | `[data-chart-heat-cell][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 3 | `chart.css:32 1 ` | `[data-chart-cal-cell][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 4 | `chart.css:36 1 ` | `[data-chart-polar-petal][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 1 | `chart.css:27 3 ` | `[data-chart-bar-segment-fill][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 2 | `chart.css:31 5 ` | `[data-chart-heat-cell][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 3 | `chart.css:32 3 ` | `[data-chart-cal-cell][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
| 4 | `chart.css:36 3 ` | `[data-chart-polar-petal][data-dim='true']` | `opacity` | `var(--opacity-scrim)` |
## 3. Privados de la receta — ¿de dónde sale su valor?
@ -89,7 +52,7 @@ _La receta no declara privados propios en su CSS._
## 4. Propuesta de corrección
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (37 )
### 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
@ -99,43 +62,7 @@ no distingue lo que debería — se marca `⚠`.
| token (`--chart-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
| `empty-fg` | `root` | `var(--color-content-secondary)` | 1 |
| `empty-font-size` | `root` | `var(--style-label-font-size)` | 1 |
| `axis-label-fill` | `root` | `var(--color-content-secondary)` | 1 |
| `axis-label-font-size` | `root` | `var(--style-caption-font-size)` | 1 |
| `tooltip-font-size` | `root` | `var(--style-caption-font-size)` | 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-value-fg` | `root` | `var(--color-content-primary)` | 1 |
| `title-font-size` | `root` | `var(--style-label-font-size)` | 1 |
| `title-font-weight` | `root` | `var(--font-weight-medium)` | 1 |
| `title-fg` | `root` | `var(--color-content-primary)` | 1 |
| `legend-item-font-size` | `root` | `var(--style-caption-font-size)` | 1 |
| `legend-item-fg` | `root` | `var(--color-content-secondary)` | 1 |
| `bar-list-label-font-size` | `root` | `var(--style-label-font-size)` | 1 |
| `bar-list-label-fg` | `root` | `var(--color-content-primary)` | 1 |
| `bar-list-value-font-size` | `root` | `var(--style-label-font-size)` | 1 |
| `bar-list-value-fg` | `root` | `var(--color-content-secondary)` | 1 |
| `bar-segment-legend-item-font-size` | `root` | `var(--style-caption-font-size)` | 1 |
| `bar-segment-legend-item-fg` | `root` | `var(--color-content-secondary)` | 1 |
| `bar-segment-legend-value-fg` | `root` | `var(--color-content-primary)` | 1 |
| `smith-label-fill` | `root` | `var(--color-content-secondary)` | 1 |
| `smith-label-font-size` | `root` | `var(--style-caption-font-size)` | 1 |
| `smith-point-label-fill` | `root` | `var(--color-content-primary)` | 1 |
| `smith-point-label-font-size` | `root` | `var(--style-caption-font-size)` | 1 |
| `smith-point-label-font-weight` | `root` | `var(--font-weight-medium)` | 1 |
| `funnel-label-font-size` | `root` | `var(--style-label-font-size)` | 1 |
| `funnel-label-font-weight` | `root` | `var(--font-weight-medium)` | 1 |
| `funnel-side-font-size` | `root` | `var(--style-label-font-size)` | 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-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)
@ -153,9 +80,9 @@ no distingue lo que debería — se marca `⚠`.
<!-- veredicto:start -->
**EJECUTADO 2026-08-22 — 9 % → 49 %**, 22 claves nuevas fusionadas en el bloqu e
existente (17 → 39). El 49 % es el techo de este diseño, no un trabajo a medias:
lo que queda fuera está medido y cada clase tiene su razón escrita abajo .
**EJECUTADO 2026-08-22 — 9 % → 49 % → 89 %**, en dos pasadas: 22 claves d e
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
@ -165,19 +92,36 @@ distintos** — 9× `content-secondary`, 9× `content-primary`, 9× `100%`, 6×
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 NO recibe tokens de chart, por doctrina.** Toma su ROL DE TAMAÑO de
los estilos con nombre —`caption` (xs) para las anotaciones y `label` (sm) para
el texto de cromo— y su TINTA y PESO de las ranuras del sistema
(`--color-content-*`, `--font-weight-*` ). Acuñar `--chart-label-font-size`
sería inventar tipografía por componente, que es exactamente lo que el autor
prohibió el mismo día para la familia text-effects. Precedente de consumir la
capa: `code-block` , `kbd` , `announce` . Doce declaraciones cambian de
`var(--font-size-xs|sm)` a `var(--style-caption|label-font-size)` , mismo valor.
**Consecuencia medida en la métrica**: esas doce y las veinte de tinta/peso
siguen contando como `global` , porque el censo sólo exime `--style-*` a los
PRIMITIVOS tipográficos y chart no lo es. El censo penaliza aquí hacer lo
correcto — la misma nota que dejó `listbox` en F2-A (§13).
**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 +
@ -197,9 +141,9 @@ 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.
**Una escotilla sin cerrar**: el `--font-size-xl` del número del gauge. N ingún
estilo con nombre juega ese papel (un readout de dato no es un `h2` ) y acuñar
`gauge-label-font-size` sería tipografía por componente. Anotado en §13 .
**La escotilla del gauge, cerrada**: su número es un READOUT de dato y n ingú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):