Primer componente del bloque F2-A, y el peor del catálogo con veredicto
verificado: 52 knobs y NINGUNA entrada de contrato. Ahora tiene 57 claves y no
le queda un solo privado.
censo 0 % → 98 % · global 38 % → 39 %
computed 8.091 valores en 8 estados (reposo · 5 tallas · abierto · hover):
**0 diffs**. El default no se movió.
**El eje `size`** sigue el patrón firmado en Sidebar: coordenadas por talla en
`root` + nombre RESUELTO con `declarations` (default `host` = md, overrides
`size:sm`/`size:lg`), que es lo único que la receta lee. Los bloques
`[data-size]` del CSS se RETIRAN: dejarlos vivos pisaría los tokens nuevos con
los valores viejos y el diff daría 0 porque la ruta vieja seguiría mandando —
la trampa que este eje ya pagó una vez. Las cuatro coordenadas casan 1:1 con el
bundle, medido (`--size-{k}-padding-inline` / `--size-{k}-font-size`), así que
leen la coordenada y no el primitivo suelto — que es justo lo que
`recipe-css-contract` exige, y lo cazó: `group-heading-font-size` entró como
`var(--font-size-xs)` y salió como `var(--size-xs-font-size)`.
**El radio y el modo Dialog**, que el veredicto marcaba como ⚠ colisión y no lo
era: dentro de `<Command.Dialog>` el panel que el usuario ve ES el del dialog,
así que la regla de contexto reapunta el propio público a
`var(--dialog-content-radius)`. Leer el público de un hermano donde ese hermano
ES la superficie es composición correcta, no un segundo token — y de paso el
componente se queda sin privados (antes el radio vivía en `--_command-radius`).
**El hueco del scrollbar** se resuelve con el patrón de combobox:
`viewport-padding-inline` + `scrollbar-inset`, y la regla del overflow los
compone.
**Centinela: 50/57 tokens mueven un computed.** Los 7 restantes, adjudicados
uno a uno en el navegador, no por conjetura:
5 `loading-*`, `viewport-padding`, `empty-*` — sus partes NO están montadas
en la demo (el estado vacío, la barra de carga y el scroller interno son
condicionales). No se puede medir lo que no existe.
1 `input-placeholder-fg` — `::placeholder` es pseudo-elemento y
`getComputedStyle` sobre el nodo no lo ve. Límite del instrumento.
1 `input-border` — FALSO NEGATIVO del centinela: comprobado a mano tres
veces (con la misma congelación de transición que él usa) el token SÍ
alcanza, `oklch(0.3485)` → `rgb(1, 2, 3)`. No he encontrado por qué el
centinela lo pierde; queda anotado como defecto del instrumento.
`R-5.1 exception: inline-size: 100%` — el panel rellena su contenedor; es
mecánica de layout, no apariencia. Es el 2 % que falta.
audit PASS (R-5.3 incluida) · eidos-lint 0 invalid · rtl 0 · docs 0 ·
suite: el único rojo es el conocido `skin-media-player`
README con la sección «Talla y tema» (molde navigation-menu).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
## 3. Privados de la receta — ¿de dónde sale su valor?
| privado | declaraciones | valor(es) | origen | ¿deriva de un público? |
| --- | ---: | --- | --- | :-: |
| `--_command-input-padding-inline` | 3 | `var(--space-3)`, `var(--space-2)`, `var(--space-4)` | global | no |
| `--_command-input-font-size` | 3 | `var(--font-size-md)`, `var(--font-size-sm)`, `var(--font-size-lg)` | global | no |
| `--_command-item-padding-inline` | 3 | `var(--space-3)`, `var(--space-2)`, `var(--space-4)` | global | no |
| `--_command-item-font-size` | 3 | `var(--font-size-md)`, `var(--font-size-sm)`, `var(--font-size-lg)` | global | no |
| `--_command-radius` | 2 | `var(--radius-lg)`, `var(--dialog-content-radius)` | global | no |
| `--_command-radius` | 2 | `var(--command-radius)`, `var(--dialog-content-radius)` | global, public | no |
Consumidos y **no declarados en el CSS** (vienen de `base.ts` o de un estilo inline del wrapper): `--_command-loading-progress`.
## 4. Propuesta de corrección
- **Consume la capa compartida `list-surface`.** Un eje que la capa posee se consume como `var(--_x, var(--x))`; el consumidor **no acuña**`--command-{eje}` para él — sería un vocabulario paralelo (README de `eidos/components`, «Capas compartidas» regla 2).
- **Tiene eje `size`**: los tokens dimensionales van por talla (`{part}-{eje}-{k}`) apuntando al bundle `--size-{k}-*`, nunca al primitivo crudo (theming §5; el guard `recipe-css-contract` prohíbe el primitivo).
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (58)
### 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
@ -113,80 +59,15 @@ no distingue lo que debería — se marca `⚠`.
- **⚠ 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** — 1: `inline-size`.
- **⚠ decisión: `border` es shorthand o eje físico — hay que partirlo en ejes lógicos antes de nombrarlo (recipe-contract §1, R-4.4)** — 1: `border`.
- **⚠ 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`.
- **⚠ decisión: `padding` es shorthand o eje físico — hay que partirlo en ejes lógicos antes de nombrarlo (recipe-contract §1, R-4.4)** — 1: `padding`.
### 4.3 Avisos sobre los tokens propuestos (6)
### 4.3 Avisos sobre los tokens propuestos (1)
- **el privado `--_command-radius` debe pasar a leer este público (o desaparecer)** — `--command-radius`
- **el privado `--_command-input-padding-inline` debe pasar a leer este público (o desaparecer)** — `--command-input-padding-inline-md`, `--command-input-padding-inline-sm`, `--command-input-padding-inline-lg`
- **el privado `--_command-input-font-size` debe pasar a leer este público (o desaparecer)** — `--command-input-font-size-md`, `--command-input-font-size-sm`, `--command-input-font-size-lg`
- **⚠ decisión: el valor es una expresión — el token puede llevar la expresión entera o sólo su término variable** — `--command-list-padding-inline`
- **el privado `--_command-item-padding-inline` debe pasar a leer este público (o desaparecer)** — `--command-group-heading-padding-inline-md`, `--command-group-heading-padding-inline-sm`, `--command-group-heading-padding-inline-lg`, `--command-item-padding-inline-md`, `--command-item-padding-inline-sm`, `--command-item-padding-inline-lg`, `--command-empty-padding-inline-md`, `--command-empty-padding-inline-sm`, `--command-empty-padding-inline-lg`
- **el privado `--_command-item-font-size` debe pasar a leer este público (o desaparecer)** — `--command-item-font-size-md`, `--command-item-font-size-sm`, `--command-item-font-size-lg`, `--command-empty-font-size-md`, `--command-empty-font-size-sm`, `--command-empty-font-size-lg`
### 4.4 Lo que hay que comprobar a mano (PLAN-theming §1.3 · §7.4)