- Add 40 recipes.banner.{intent}-{slot} forwarders (= var(--color-{intent}-{slot}))
- banner.css reads --banner-{intent}-{slot} instead of foundation --color-{intent}-* directly
- Banner is now retintable per-component via recipes.banner.* like button/badge; keeps data-intent (no API change)
- Regenerated base.css; recipe contract balanced (40 declared = 40 consumed), no visual regression
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ -65,9 +65,10 @@ definiciones vs referencias). Orden de prioridad para empezar a resolver.
- **Fix**: sniff de color CSS (hex/rgb/hsl/color/var/color-mix/nombres) en rutas de color.
- **✅ Hecho**: regla segura en `validateNonEmptyCssValue` — un valor que empieza por `#` debe ser hex válido (`#rgb/#rgba/#rrggbb/#rrggbbaa`); caza `#ggg` / hex tipografiado **sin** tocar `var()`/`color-mix()`/`rgb()` ni los placeholders de test (sin `#`). + test. **Pendiente**: el identificador-pelado tipo `'not-a-color'` sigue sin cazarse (requeriría allow-list de nombres CSS o reescribir el test de pass-through `'purple-alpha-4'`).
### P1-5 · Banner se salta el sistema de recipes/roles
### ✅ P1-5 · Banner se salta el sistema de recipes/roles
- `components/banner/banner.css:57-112` cablea a mano 8 intents × 5 slots a `var(--color-{intent}-{slot})` y lee `data-intent`. Su recipe (`base.ts:3799-3802`) solo declara gap+radius. Es el único componente de color que **no se puede retintar vía `recipes.*`** y diverge del eje `data-color` del resto.
- **Fix**: migrar Banner a tokens de recipe + cascada TSC `_accent-*`/`palette-*` como button/toggle.
- **✅ Hecho** (versión no-disruptiva): añadidos 40 forwarders `recipes.banner.{intent}-{slot}` (= `var(--color-{intent}-{slot})`) y banner.css lee `--banner-{intent}-{slot}` en vez de `--color-{intent}-*` directo → **Banner ya es retintable vía `recipes.banner.*`** (como button/badge). Verificado: cadena resuelve igual (`--banner-affirm-solid` = `#12a594`), sin regresión visual; contract balanceado (40 declarados = 40 consumidos). **Mantiene `data-intent`** (no cambio de API). **Pendiente futuro**: alinear del todo al patrón button (cascada `palette-*` en el recipe en vez de en CSS) requeriría cambiar el eje a `data-color` o un scope `intent:` en el TSC — decisión separada.
### P1-6 · Cobertura de tests: las dos clases de bug que ya se colaron siguen sin red
- **`contrast`/on-solid: cero asserts** (`grep contrast|on-solid` en los `*.test.ts` = 0). El bug de ilegibilidad estaba en este slot.