El `data-color` de los morfos declaraba enums de 3 a 8 valores cuando la prop acepta 42. No era descuido: es que **el morfo no puede nombrar ese vocabulario**. `COLOR_ROLES` y `PALETTE_SCALES` viven en eidos; `INTENTS` vive en `src/uix/intent.ts`, propiedad de UIX y de ninguna capa. Y `src/uix/morfo/**` no importa de eidos jamás — su único import cruzado es `../../intent`. Nadie podía traer la lista real, así que se copió a mano un subconjunto y se fosilizó: `<Switch color="teal">` siempre emitió `data-color="teal"`, un valor que su propia declaración negaba. ## Dos ejes, no uno - `data-color` = **direccionamiento de paleta**: qué fila de la tabla lee la instancia. `renderSharedPaletteLayer` emite un bloque por nombre canónico y el recipe consume los `--palette-*` resultantes. Soma lo resuelve aplicando la doctrina «el intent evaluativo gana a la jerarquía». - `data-intent` = **estado evaluativo persistente**, cuyo gemelo transitorio es `data-event-intent`. Ya lo declaraban `knob`, `timeline` y `toast`. Estaban fusionados en un solo atributo (`switch`/`toggle` llegaban a listar `primary, secondary` junto a cuatro intents en el mismo enum), y por eso no se podía asignar limpiamente a ninguna capa. ## Cambios - `intentsExcept()` en `src/uix/intent.ts`: narra un subconjunto por EXCLUSIÓN, tipado contra `Intent`. Un componente toma los 6 o menos, pero nunca vuelve a escribir el vocabulario — si mañana entra un séptimo intent canónico llega solo a todo el que no lo haya rechazado. `knob` migrado (conjunto idéntico, verificado). - `dialog` → `data-intent`. Aquí SÍ era intent mal etiquetado: 0 usos de `--palette-*`, sin `resolveComponentColor`, y reglas propias cuyos valores eran todos intents. El provider declaraba `intent` **y** `color` con la misma expresión exacta — una copia, no una traducción. Migrados morfo (×2), provider y las 4 reglas CSS. - `switch`, `toggle`, `button`, `card`, `avatar`: enum de `data-color` fuera, `emit: 'value'` en su lugar. El DOM no se mueve: `enumValues` no lo consume nadie en runtime y `evalAttrPlan` hace `case 'enum': case 'string': return raw`. Ambos comprobados antes de tocar. - De paso, los 10 morfos que escribían `expression:` con comilla doble en un corpus de 173 que usa comilla simple. ## Verificación 514 tests de morfo + contracts + eidos · 7/7 del provider de button (cubre `data-color='primary'` por defecto y `'threat'` con intent evaluativo) · `eidos-lint` con `invalid: 0` en los seis componentes tocados · `check` sin errores nuevos. En navegador: `dialog` con `risk` y `threat` tiñe borde y título con los valores exactos de `--color-risk-border` / `--color-threat-border`; `switch` resuelve fila de paleta distinta para `neutral`, `primary`, `threat` y `teal` — esta última una de las 33 escalas donantes que el enum viejo negaba. `rose`, que no es canónica, sale vacía y sirvió de control negativo. Nota: `chronos` ya declaraba la forma correcta (`emit: 'value'`, sin enum). Lo tenía excluido de la auditoría, así que deduje desde cero un patrón que ya estaba en el árbol. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>alpha-0.1-sec-dom
parent
4e785d32bf
commit
f8e35b8fd8
Loading…
Reference in new issue