# Continue tomorrow Fecha de corte: **2026-05-27**. Rama: `active-uix`. Working tree con cambios sin commitear listos para push. ## TL;DR de la sesión Sesión maratón del Token Scope Contract — del bug del toggle (ya conocido) hasta cobertura universal sin excepciones arquitectónicas: 1. **Diagnóstico inicial**: usuario reporta "el toggle no funciona, el color del intent no cambia". Eager-resolution de CSS custom properties en el cascade del toggle. 2. **TSC v1 → v2 → v2.1 → v2.2**: 4 iteraciones del Token Scope Contract. Cada una cerrando un gap (scope explícito, álgebra de cobertura, private tokens, multi-part + composition). 3. **Universal migration**: 18 componentes con `data-color` migrados a TSC (15 con TSC v2.1, + 3 con extensiones v2.2 de hoy). 4. **Bug crítico post-composition**: la toggle-group composition correctamente override `--toggle-palette-*` pero el cascade colapsaba downstream porque los derived tokens (`--toggle-solid-on-bg` etc.) viven en scope `[data-toggle]` (sibling, no ancestor, de `[data-toggle-group-item]`). Fix: inlined derivations en toggle-group.css con palette-direct refs. 5. **Bundle JIT purge** (`scripts/eidos-purge.ts`): tool standalone que tree-shakes el `generated/base.css` por componente, var() ref, data-attr y component import. Reduce ~50% el bundle final. 6. **Docs**: THEMING.md (~1700 líneas) como referencia canónica del theming. CLAUDE.md con 5 hand-offs del 2026-05-27. Eidos README actualizado. ## Tareas completadas hoy (resumen) Total: 87 tareas TaskList. Sprint TSC ocupa #50–#87. Highlights: - **TSC v1** (#50–#56): primera versión — `scope`/`depends` explícitos, generator agrupando por scope. - **TSC v2** (#57–#62): álgebra de scope (ScopeSet covers), cross-axis collision detection, var() auto-inferred deps, color:* rename. - **P0–P2 housekeeping** (#63–#68): rename `--{c}-color-{role}-{slot}` → `--{c}-{role}-{slot}`, JIT purge script. - **CONSOL + GAP** (#69–#73): consolidación de docs, universal anti-eager- resolution guard test. - **UNIV** (#75–#79): private tokens (`_` prefix) + migración universal de 13 componentes. - **EXT** (#80–#86): TSC v2.2 — multi-part `parts` + cross-recipe `composition` + 3 componentes restantes migrados (`select`, `toggle-group`, `avatar`) + docs. - **EXT-FIX** (#87): bug del toggle-group color cascade tras la composition migration. ## Patrones canon nuevos en esta sesión ### Token Scope Contract (TSC) — la fuente de verdad Cada recipe token tiene un **scope explícito** que materializa el selector CSS donde se emite. El generator infiere deps de los `var()` y valida álgebra de cobertura. **Imposible introducir el bug eager-resolution si declaras tokens en TSC** — el validator lo rechaza antes de generar CSS. Formas: ```ts recipes.toggle = { 'height-md': '32px', // shorthand → root 'solid-on-bg': { // single decl value: 'var(--toggle-palette-solid)', scope: 'host' }, 'palette-solid': { // multi-decl declarations: [ { value: 'var(--toggle-neutral-solid)', scope: 'host' }, { value: 'var(--toggle-affirm-solid)', scope: 'color:affirm' } ] } } ``` ### TSC v2.2 — `parts: [...]` para multi-part scope ```ts '_accent-track': { parts: ['trigger', 'content'], declarations: [ { value: 'var(--select-primary-track)', scope: 'host' }, { value: 'var(--select-affirm-track)', scope: 'color:affirm' } ] } // → emits: // [data-select-trigger], [data-select-content] { --_select-accent-track: ... } // [data-select-trigger][data-color='affirm'], [data-select-content][data-color='affirm'] { ... } ``` Único consumer hoy: `select` (Trigger + Content). Cualquier componente que tenga atributos cascadeados per-part (no en root) usa este patrón. ### TSC v2.2 — `composition: { ... }` para cross-recipe override ```ts 'toggle-group': { gap: 'var(--space-1)', composition: { toggle: { // foreign recipe targetSelector: '[data-toggle-group-item]', tokens: { 'palette-solid': { declarations: [ { value: 'var(--toggle-affirm-solid)', scope: 'color:affirm' }, { value: 'var(--toggle-risk-solid)', scope: 'color:risk' } ] } } } } } // → emits: // [data-toggle-group][data-color='affirm'] [data-toggle-group-item] { // --toggle-palette-solid: var(--toggle-affirm-solid); // } ``` Único consumer hoy: `toggle-group`. Pattern reutilizable para futuros wrappers compositivos (button-group, nav-menu, etc.). ### Private tokens (`_` prefix) Recipe key `_palette-solid` → CSS var `--_toggle-palette-solid` (con underscore prefix). NO aparece en el public CSS contract. Solo accesible desde la propia CSS recipe del componente. Convención: usar para slots intermedios de derivation que no quieres exponer como theming knobs. ### Inline derivation cuando el ancestor scope no aplica **Anti-pattern**: leer `var(--{foreign-component}-derived-token)` desde un elemento que NO es descendant del scope donde se declaró ese token. Resultado: undefined → cascade colapsa. **Pattern correcto**: inline la derivation expression localmente. Ejemplo en `toggle-group.css` para `[data-toggle-group-item]` — replica las expressions de `recipes/base.ts > toggle.{solid,outline,ghost}-*` directamente. Duplicación documentada y aceptada como trade-off. ## Trabajo acumulado SIN commitear ``` Modificados (eidos + soma touched durante TSC sprint): M src/uix/eidos/components/avatar/avatar.css M src/uix/eidos/components/badge/badge.css M src/uix/eidos/components/button/button.css M src/uix/eidos/components/card/card.css M src/uix/eidos/components/checkbox/checkbox.css M src/uix/eidos/components/editable/editable.css M src/uix/eidos/components/file-upload/file-upload.css M src/uix/eidos/components/radio-group/radio-group.css M src/uix/eidos/components/select/select.css M src/uix/eidos/components/stepper/stepper.css M src/uix/eidos/components/switch/switch.css M src/uix/eidos/components/tag-group/tag-group.css M src/uix/eidos/components/tags-input/tags-input.css M src/uix/eidos/components/toggle-group/toggle-group.css M src/uix/eidos/components/toggle/toggle.css M src/uix/eidos/README.md M CLAUDE.md M package.json (npm script para eidos:purge añadido) Modificados (words component sprint en paralelo — no este chat): M src/uix/eidos/components/words/* M src/uix/soma/components/words/* M src/uix/words/README.md M web/routes/uix/components/words/* Eliminado: D src/docs/libro_semantica_completo.txt (reemplazado por .docx) Untracked (TSC v2.2 + auxiliares): ?? scripts/eidos-purge.ts ?? scripts/probe-*.ts (5 probe scripts del debug session) ?? src/docs/Disenando_lo_que_ocurre_manuscrito_completo_revisado_v2.docx ?? src/uix/eidos/THEMING.md ?? src/uix/eidos/THEMING_AUDIT_2026-05-27.md ?? src/uix/eidos/components/words/* (slash menu, family menu, code lang picker) ?? src/uix/soma/components/words/components/words-slash-menu.svelte ?? src/uix/soma/components/words/engine/code-highlight.ts ?? src/uix/words/references/* (4 audit docs + 1 screenshot) ``` ## Cómo retomar mañana 1. **Probar toggle-group en navegador**: - El bug del cascade fue corregido inlining derivations en `toggle-group.css`. Pero el fix no se probó en navegador. Si el cascade sigue roto en algún caso, revisar las inlined expressions contra `recipes/base.ts > toggle.{solid,outline,ghost}-*`. 2. **Avatar regenerado**: la migración TSC v2.2 produce un orden de selector ligeramente distinto al original (`[data-color][data-variant]` en lugar de `[data-variant][data-color]`). Mismo CSS efectivo — misma especificidad. Si algún test snapshot rompe, regenerar. 3. **Próximo trabajo natural en TSC** (NO urgent): - Si más componentes necesitan multi-part scope o composition, ya está todo soportado — solo añadir las recipes. - Considerar `radius:`/`ring-color:` como AtomicScope adicionales si el avatar `ring-color` cascade emerge como pattern recurrente. ## Comandos útiles ```bash cd G:/dev/svelte/vicen npm run check # svelte-check npm run test # full vitest run npx vitest run src/uix/eidos # eidos-only (100 tests) npm run generate:eidos-css # regen src/uix/eidos/generated/base.css npx tsx scripts/eidos-purge.ts # JIT purge para una ruta ``` ## Referencias canónicas tras la sesión - **Theming completo**: `src/uix/eidos/THEMING.md` (1700+ líneas, §18 reescrito hoy como "Cobertura universal de TSC", §7 ampliado con multi-part + composition). - **Hand-offs**: `CLAUDE.md` §"Session hand-off — 2026-05-27 #5" (TSC v2.2 + cobertura universal de theming). - **Recipe authoring guide**: `THEMING.md` §7 (TSC) + §8 (añadir componente nuevo). - **Anti-eager-resolution guard**: `src/uix/eidos/recipe-css-contract.test.ts` test "forbids palette-derived tokens at :root scope".