You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/README.md

1114 lines
47 KiB

docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
# Eidos
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
`Eidos` es la **capa visual** de UIX. Cubre lo que en la rama muerta `air/`
era el "runtime visual" más el sistema de tokens — sin heredar código.
Lee del DOM lo que las capas anteriores han escrito (morfo runtime + sema
visual channel) y aplica estilos, animaciones y wrappers ergonómicos.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
```
Morfo declara la genética
↓
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Soma transcribe el comportamiento → DOM (data-state, data-color, aria-*)
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
↓
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Sema emite señales perceptivas → DOM (data-event-*) durante el hold
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
↓
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Eidos aplica el visual: tokens, themes, recipes, archetypes, wrappers
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
```
Eidos nunca importa internals de soma ni de sema. Su fuente de verdad es
**lo que está escrito en el DOM** (parts, data-attrs, ARIA, archetypes,
event signals) y los tipos públicos de Soma que necesita para componer
wrappers.
## Handoff 2026-05-14
Eidos queda congelado a nivel de componentes hasta reauditar la arquitectura
de UIX. No tocar `src/uix/eidos/components/*` salvo orden explicita.
Actualización 2026-05-17: la migración de componentes se reanudó por orden
explícita. La regla vigente no cambia: cada componente nuevo debe seguir
`components/README.md`, envolver partes públicas de Soma directamente y añadir
sólo superficie visual de Eidos.
Antes de seguir con wrappers o recipes por componente hay que respetar estas
decisiones:
- que contrato minimo consume `Eidos` desde `ActiveUix`;
- `ActiveEidos` asume authoring, validacion, generacion CSS, persistencia y
contexto visual;
- `events` es el servicio perceptivo runtime y `morfo.translations` es el
catalogo declarativo de texto owned por el componente;
- que parte se genera desde codigo y que parte puede venir solo por CSS;
- como se mantiene la regla de escritura DOM unica en standalone `dom:false`.
La referencia de arranque esta en
[`../active_architecture.md`](../active_architecture.md), seccion
`Handoff 2026-05-14`.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## No es solo CSS
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
El primer mental model fue "eidos = CSS reactivo". Insuficiente: hay
concerns visuales puros (variant, size, layout flags, icon slots) que
no son parte del comportamiento headless pero sí son ortogonales al CSS.
Eidos los aloja como **wrappers Svelte sobre el Soma**.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
```
src/uix/eidos/
active-eidos.svelte.ts → runtime/contexto visual y generacion CSS
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
index.css → entrypoint que importa todo el CSS
archetypes.css → reglas comunes a [data-archetype=*]
events.css → reacciones a [data-event-*] (sema visual)
generated/base.css → salida estatica generada desde EidosConfig base
themes/fonts.css → font faces usados por el theme base generado
lib/ → soporte de config, recipes, contrato CSS y tipos compartidos
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
components/{x}/ → recipe + wrapper + tipos por componente
{x}.css recipe CSS (selectores [data-{x}], etc.)
{x}.svelte wrapper Svelte sobre el componente Soma
types.ts props del wrapper (extiende el contrato público Soma)
index.ts namespace publico (default + partes attached)
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
```
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
`lib/` contiene el soporte puro de configuracion visual: primitivas, semantica
visual, themes, contrato CSS y render. `generated/base.css` es el primer
artefacto estatico generado desde esa configuracion (`npm run generate:eidos-css`).
Los antiguos `contracts/` y `themes/base/` CSS se retiraron del arbol activo:
el contrato publico se obtiene con `ActiveEidos.getCssContract()` /
`renderContractCss()` y el base visual sale de `generated/base.css`.
Los antiguos `tokens/components/*` tambien se retiraron: los nombres de
custom properties de recipe (`--toast-*`, `--dialog-*`, etc.) siguen siendo
el contrato estable, pero sus valores base viven en `EidosConfig.recipes` y
se generan en `generated/base.css`.
## Runtime activo
Eidos tiene una clase activa:
- `ActiveEidos` es el runtime activo y contexto visual de los wrappers Svelte.
Gestiona configuracion visual pura, primitivas, roles semanticos, themes,
validacion, render de CSS y persistencia. Conecta esa configuracion con los
servicios de `ActiveUix` cuando hay contexto:
`prefs`, `dom`, `langs`, `format` y helpers visuales como `resolve(...)`,
`breakpoint(...)` o `isBelow(...)`. Si `applyDom` esta activo, inyecta/quita
`<style data-uix-eidos>` usando `uix.dom`.
Regla de dependencia: un componente en `src/uix/eidos/components/*` no importa
`getActiveUix()` directamente. Consume `ActiveEidos.require()` y solo conoce la
superficie visual de Eidos.
Regla de ownership: `ActiveEidos` no crea servicios compartidos. En modo
contexto, `ActiveEidos.create(...)` obtiene esos servicios de `ActiveUix`; si
un wrapper requiere uno que no existe, lanza error. En modo explicito,
`createActiveEidos(...)` recibe servicios ya construidos. Con `applyDom:false`
queda como runtime sin escritura DOM: puede renderizar, serializar y validar
CSS sin insertar estilos.
Matiz importante: `prefs`, `langs` y `format` son opcionales durante la
construccion porque `ActiveEidos` tambien sirve para generar/serializar CSS.
Los getters `activeEidos.prefs` y `activeEidos.langs` si fallan temprano si un
wrapper visual los lee y no fueron inyectados. `dom` solo es obligatorio cuando
`applyDom` esta activo.
La configuracion vive en `EidosConfig`:
```ts
interface EidosConfig {
primitives: PrimitiveSet;
semantics: SemanticSet;
themes?: ThemeMap;
recipes?: RecipeTokenSet;
}
```
Para authoring incremental sobre el theme base existe
`EidosConfigPatch`. No sustituye al objeto completo: lo extiende de
forma profunda, preservando lo no declarado y reemplazando arrays completos
(por ejemplo `fallbacks` de una familia tipografica).
```ts
const config = createThemeBaseEidosConfig({
primitives: {
typography: {
families: {
primary: { family: 'Inter' }
}
}
},
semantics: {
color: {
roles: {
primary: 'blue'
}
}
}
});
```
Si la app quiere partir de cero, usa `defineEidosConfig()` con un
`EidosConfig` completo y lo pasa a `ActiveEidos.create({ config })`. Si quiere
partir del theme base, usa `createThemeBaseEidosConfig(patch)` o directamente
`ActiveEidos.create({ themeBase: patch })`.
`primitives` contiene las bases no semanticas: escalas de color de 12 pasos,
size map canonico, espacios, alturas de control, radios, borde, opacidad,
z-index, focus ring, layout, tipografia, sombras, motion e iconos.
`semantics.color.roles` mapea esas escalas a los roles canonicos:
```text
primary · secondary · tertiary · neutral · affirm · fulfill · risk · threat · loss
```
No hay `danger`, `success`, `warning` ni `info`: esos nombres pertenecen a
otros modelos. En Eidos los componentes hablan por intents y jerarquia visual.
`recipes` contiene los aliases publicos de cada recipe activa. No define
selectores ni estados de componente: solo valores para custom properties que
las recipes CSS consumen. Por ejemplo, `recipes.tooltip['content-z']` genera
`--tooltip-content-z`; `recipes.dialog['overlay-bg']` genera
`--dialog-overlay-bg`. Asi los componentes mantienen su CSS estable y el tema
puede persistir/editar esos valores desde el mismo objeto de authoring.
El contrato recipe/CSS se valida en `recipe-css-contract.test.ts`: si una
recipe CSS consume `--{component}-*`, ese alias debe existir en
`EidosConfig.recipes`; y si el theme base declara un alias publico, debe estar
consumido por el componente o por otro token compuesto. No hay reservas
fantasma ni paletas que el componente no pueda activar desde su API real.
Para editores de theme, `ActiveEidos.listRecipes()` enumera los componentes
con recipe tokens y `ActiveEidos.getRecipeTokens(component)` devuelve una
copia defensiva del mapa de aliases. No muta el config interno.
La decision vigente es mantener `recipes` como mapa plano de aliases
(`RecipeTokenSet`). Subir una recipe a tipo estructurado propio solo se
justifica cuando exista un builder o consumer real que necesite semantica
interna; mientras las recipes sigan siendo CSS plano, el contrato publico es
el custom property generado.
ActiveEidos genera tambien la escala alpha de cada paleta fisica:
```text
--scale-blue-a1 … --scale-blue-a12
--primitive-primary-a1 … --primitive-primary-a12
```
Si el theme declara `color.alphaScales`, esos valores se respetan. Si no, se
derivan desde el paso sólido de la escala (`--scale-{name}-9`) con una
progresion canonica de opacidad. Esto permite usar tintas translucidas para
overlays, rings, hovers suaves o scrims sin que cada recipe invente su propia
formula.
### Size canonico
`Size` es discreto y estable:
```text
xxs · xs · sm · md · lg · xl · xxl · full
```
`full` es semantica de layout y no genera primitiva fisica. La config mapea
solo `xxs..xxl` a tokens coordinados:
```text
--size-md-control-height
--size-md-font-size
--size-md-font-line-height
--size-md-font-letter-spacing
--size-md-icon-size
--size-md-padding-inline
--size-md-padding-block
--size-md-gap
--size-md-radius
```
La regla es: `md` no cambia de significado por viewport. Lo responsive decide
que size activo se usa (`ResponsiveProp<Size>`), no redefine los tokens de
`md`. Porcentajes, `vw`, `dvh`, `clamp()` o `min()` pertenecen a layouts
como `full`, panels y containers; no al size canonico de controles, iconos o
tipografia.
### Primitivas transversales
El bloque static ya genera las primitivas compartidas que suelen aparecer en
Radix Themes, Ark/Panda, Chakra, Tailwind o shadcn como foundation tokens:
- `layout`: anchuras de container, padding inline de container, anchuras de
contenido y ratios canonicos. Genera:
`--container-width-*`, `--container-padding-inline`,
`--content-width-*` y `--aspect-ratio-*`.
- `density`: escalas `compact · comfortable · spacious` para que las recipes
puedan ajustar espacio, altura de control o contenido sin redefinir los
tokens canonicos. Genera `--density-{key}-*` y aliases activos como
`--density-space-scale`.
- `border`: anchuras `none · hairline · thin · medium · thick`, estilos
`solid · dashed · dotted` y aliases `--border-width`, `--border-style`,
`--border`.
- `opacity`: `0 · muted · disabled · scrim · overlay · hover · press · full`.
- `zIndex`: `base · raised · sticky · dropdown · popover · tooltip · modal · toast`.
- `shadow`: escala fisica `1..6` más aliases semanticos
`none · subtle · raised · overlay` por theme.
La regla es la misma que en size: estos tokens no cambian de significado por
breakpoint. Un componente o wrapper puede elegir otro token en un viewport
concreto, pero `--shadow-3`, `--opacity-disabled` o `--z-index-modal` siguen
siendo la misma coordenada del sistema.
El bridge responsive vive en `ActiveDom`/`ActiveEidos`: los wrappers usan
`ActiveEidos.resolve(...)`, `breakpoint(...)`, `isAtLeast(...)` e
`isBelow(...)` para decidir que token canonico aplica en cada viewport.
`--container-width-md` o `--content-width-lg` no se recalculan por responsive;
lo que cambia es la eleccion del token. La densidad sigue el mismo principio:
`ActiveEidos` proyecta `data-density` y publica scalars activos:
```css
:root {
--density-compact-space-scale: 0.84;
--density-comfortable-space-scale: 1;
--density-spacious-space-scale: 1.16;
--density-space-scale: var(--density-comfortable-space-scale);
}
[data-density='compact'] {
--density-space-scale: var(--density-compact-space-scale);
}
```
Una recipe puede usar `calc(var(--space-4) * var(--density-space-scale))`.
`--space-4` no cambia de significado; cambia la policy visual activa.
`themes` permite sobrescribir escalas, roles, superficies, contenido, bordes,
focus y sombras por theme. El theme base actual expone `base-light` y
`base-dark`; `defaultActiveEidosThemeResolver` usa el theme activo si existe
como id exacto, preserva ids externos ya cualificados (`*-light`, `*-dark`) y,
si no, prueba `${theme}-${mode}`.
`ActiveEidos` no persiste CSS en disco. Si `applyDom` esta activo, escribe en
el DOM:
- `${styleId}-static` con primitivas estables (`renderStaticCss()`).
- `${styleId}-theme` con el theme resuelto cuando procede de la config.
`themeSource` decide de donde salen los valores de theme:
- `'auto'` (default): genera CSS si la config conoce el theme; si no lo
conoce, asume que viene de CSS externo y deja solo los tokens static.
- `'config'`: modo estricto; si el theme resuelto no existe en la config,
`renderThemeCss()` lanza error.
- `'css'`: nunca genera CSS de theme; el integrador aporta los valores con
CSS externo que respeta el contrato de custom properties.
Para inspeccionar o publicar ese contrato, `ActiveEidos` expone dos superficies:
- `getCssContract()` devuelve el contrato estructurado, typed, con cada token
(`name`, `cssVar`, `scope`, `category`, `path`). Es la superficie pensada
para editores de theme, validadores, tooling o persistencia de usuario.
- `renderContractCss()` renderiza ese mismo contrato como CSS vacío para
documentar o bootstrappear themes externos.
- `renderCssVariables()` acepta un mapa de custom properties y lo convierte
en CSS runtime validado contra el contrato de Eidos.
```ts
const tokens = eidos.getCssContract();
const recipes = eidos.listRecipes();
const tooltipTokens = eidos.getRecipeTokens('tooltip');
const contract = eidos.renderContractCss({
staticSelector: ':root',
themeSelector: "[data-theme='acme-light']"
});
```
El resultado no asigna valores reales; declara las custom properties que un
theme CSS-only puede aportar o sobrescribir:
```css
[data-theme='acme-light'] {
--scale-blue-9: ;
--scale-blue-a9: ;
--primitive-primary-9: ;
--primitive-primary-a9: ;
--color-primary-solid: ;
--size-md-control-height: ;
--border-width-thin: ;
--opacity-disabled: ;
--z-index-modal: ;
--shadow-3: ;
}
```
La persistencia usa un envelope versionado:
```ts
const document = eidos.toDocument();
const json = eidos.serialize();
const hydrated = createActiveEidos({
config: JSON.parse(json),
prefs,
dom
});
```
El documento tiene forma `{ kind: 'uix.eidos-config', version: 1, options }`.
`EidosConfig` no lleva `version` dentro: sigue siendo configuracion
visual pura. Si el shape cambia en el futuro, se sube
`EIDOS_CONFIG_DOCUMENT_VERSION`; Eidos no intenta compatibilidad silenciosa
con versiones no soportadas. La app decide dónde guardar ese documento
(prefs, backend, archivo, etc.) y qué metadata de producto lo envuelve
(`name`, owner, timestamps).
Al hidratar un documento como runtime (`config: document`,
`readEidosConfigFromDocument(...)` o `parseEidosConfigFromJson(...)`), Eidos
valida también las `options` contra el contrato completo de `EidosConfig`.
`parseEidosConfigDocument(...)` queda como parser de envelope: confirma
`kind/version/options`, pero no convierte ese envelope en configuracion
visual usable por si solo.
Integracion normal dentro de un arbol con `ActiveUix`:
```ts
const uix = createActiveUix({
langs: { schema, defaultLocale: 'es' }
});
setActiveUix(uix);
ActiveEidos.create({
themeBase: {
semantics: {
color: {
roles: { primary: 'blue' }
}
}
},
themeSource: 'auto',
themeResolver,
styleId: 'uix-eidos'
});
```
`config` acepta un `EidosConfig` completo o un `EidosConfigDocument`.
`themeBase` acepta solo un patch sobre el theme base. Son
mutuamente excluyentes para que no haya ambiguedad entre "config completa" y
"override del base".
`theme` en Eidos nombra la familia/theme visual (`base`, `acme`,
`acme-light`, etc.). `mode` nombra el esquema efectivo `light | dark` y
`density` nombra la ergonomia visual activa. Cuando `applyDom` esta activo,
`ActiveEidos` proyecta `data-theme`, `data-mode` y `data-density` en el
documento a traves de `ActiveDom`.
`mode` y `density` se inyectan como fuentes visuales, no como dimensiones de
`prefs`:
```ts
const eidos = ActiveEidos.create({
theme: 'base',
modeSource: {
get: () => colorMode,
onChange: (handler) => subscribeColorMode(handler)
},
densitySource,
applyDom: true
});
```
Si no se pasa `modeSource`, `ActiveEidos` usa `prefers-color-scheme` con
fallback `light`. Si no se pasa `densitySource`, usa `comfortable`. No leer ni
escribir `uix.prefs.theme` para UIX: el modo visual pertenece a Eidos.
Un theme CSS-only puede vivir fuera de TypeScript:
```css
[data-theme='acme-light'] {
--scale-blue-9: #006adc;
--scale-blue-a9: color-mix(in srgb, var(--scale-blue-9) 56%, transparent);
--primitive-primary-9: var(--scale-blue-9);
--primitive-primary-a9: var(--scale-blue-a9);
--color-primary-solid: var(--primitive-primary-9);
--font-family-primary: Inter, system-ui, sans-serif;
--size-md-control-height: 38px;
--shadow-3: 0 8px 24px rgb(15 23 42 / 0.12);
}
```
Para pasar valores desde runtime sin recompilar:
```ts
activeEidos.setCssVariables({
'--color-primary-solid': 'rebeccapurple',
'size-md-control-height': '40px',
'shadow-3': '0 10px 28px rgb(20 20 20 / 0.16)'
});
```
`ActiveEidos` lo escribe en `${styleId}-variables` como un `<style>`
gestionado. Por defecto valida los nombres contra `getCssContract()`; si una
app necesita variables locales fuera del contrato puede usar
`{ strict: false }`. La actualizacion es transaccional: primero renderiza y
valida el siguiente bloque, y solo reemplaza el estado runtime si el mapa es
usable. Un token desconocido no deja el style block anterior a medias.
No crear `ActiveEidos` desactiva la capa visual runtime de Eidos. Los
componentes Soma siguen funcionando headless porque el comportamiento pertenece
a Soma.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Qué consume
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
### De morfo (declaración)
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
| Pieza | Eidos la usa para |
| -------------------------------------------------------------- | --------------------------------------------------------- |
| `parts[].kebab` | selectores `[data-{component}-{kebab}]` |
| `parts[].archetype` | reglas transversales `[data-archetype=trigger]` |
| `parts[].states` + `data[].values` | variantes `[data-state=open]` |
| `parts[].data` con `data-starting-style` / `data-ending-style` | hooks de animación enter/exit |
| `events[].name` | selectores `[data-event=dismiss]`, `[data-event^=commit]` |
| `events[].semantic.family` + `.intent` | tinta semántica de transiciones |
| `events[].prewrite[]` (e.g. `data-last-action`) | tintar exit anim por causa |
| `focus.trap` | hint de layout para overlays |
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
### De Soma
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
Los wrappers de `components/*` importan las partes públicas de Soma
directamente (`$soma/components/{x}`) y sólo añaden superficie visual de
Eidos: tokens, recipes, layout shells y data-attrs de presentación. No hay
facade intermedio por componente. Ejemplo:
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
```ts
// eidos/components/toggle/types.ts
import type { ProviderProps } from '$soma/components/toggle';
export type ToggleProps = ProviderProps & { variant?: ToggleVariant; size?: ToggleSize; … };
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
```
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
El wrapper `.svelte` importa el namespace público de Soma y usa sus partes con
ese mismo namespace:
```svelte
import * as Select from '$soma/components/select';
<Select.Provider {...rest}>
<Select.Trigger />
<Select.Content />
</Select.Provider>
```
No usar aliases como `Parts`, `SelectBase` o `SomaSelectProvider`. Tampoco usar
etiquetas sueltas `<Provider>` / `<Trigger>` dentro de Eidos. El wrapper añade
los data-attrs de tokens visuales (`data-variant`, `data-size`, `data-block`,
`data-icon-only`) y no reimplementa el estado.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
### De sema (DOM)
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
Sólo el DOM. El visual channel proyecta `data-event-*` durante el hold
mediante `SignalProjector` y eidos reacciona vía `events.css`:
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
```css
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
[data-event-family='commit'][data-event-phase='active'] {
animation: eidos-commit-settle 260ms var(--ease-out);
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
}
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
[data-event-family='commit'][data-event-intent='threat'][data-event-phase='active'] {
animation: eidos-announce-pulse-threat 400ms var(--ease-spring);
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
}
```
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
`events.css` documenta los hold defaults por familia y por qué se usa
`animation: @keyframes` (no `transition`) para reacciones a señales.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Qué NO consume
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- **Computed state lógico** del provider (e.g. la composición de
`isDisabled` propio del componente con el `disabled` heredado de un
Field). Eidos sólo ve el resultado: `[data-disabled]` está o no está.
- **Internals de runtime**. No sabe si un attr lo escribió `dom.apply`,
Svelte render o el provider manualmente. Sólo le importa que esté.
- **Layers de soma** (Presence, Dismissal, ScrollLock, FocusScope).
Reacciona a sus efectos visibles, no a su existencia.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## La regla de los `--*` tokens
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Eidos posee el namespace `--*` en el visual layer. Razones:
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
1. **Authorship clarity en debug** — inspeccionar un elemento y ver
`--toggle-bg` informa que viene del visual layer de UIX.
2. **Override discipline** — un consumer que sobreescribe
`--color-primary-element` sabe que está tocando contrato visual,
no nombrando-colisionando con una variable local.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Las capas superiores (sema, soma, morfo) **NO consumen** estos tokens y
**no usan** el prefijo. Cada una carga sus propias concerns
(perceptual durations, behavior, contract DNA) ortogonales al
rendering visual.
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
feat(eidos): TSC v2.2 (parts + composition) + universal theming coverage Token Scope Contract universal — no más excepciones arquitectónicas. Los 3 componentes que vivían fuera de TSC v2.1 (select, avatar, toggle-group) ahora están dentro del contrato via dos extensiones nuevas. TSC v2.2 extensiones (lib/config-types.ts + render-css.ts + config.ts): - `parts: readonly string[]` en RecipeTokenMultiDeclaration — emite selectores comma-separados (`[data-{c}-x], [data-{c}-y]`) para componentes con data-color cascadeado per-part. Consumer: select. - `composition: { foreignRecipe: { targetSelector, tokens } }` sibling key — overrides cross-recipe scoped a la cascade del host. Consumer: toggle-group modifica `--toggle-palette-*` en sus items. Migraciones: - select: 3 private `_accent-{track,border,text}` con parts: ['trigger', 'content'] + 7 cascades color:X each. Removed orphan `_accent-solid` (CSS no consumía). - avatar: 6 tokens via composite scopes `['variant:X', 'color:Y']` con matrix helper inline. Badge usa parts: ['badge']. Reemplaza 24 bloques CSS × 2 partes. - toggle-group: composition block con 8 palette tokens × 4 colors. Reemplaza 4 bloques CSS per-color. Bug toggle-group post-composition (encontrado y arreglado): Tras la composition migration, el cascade del toggle-group seguía roto porque los tokens derivados (`--toggle-solid-on-bg`, `--toggle-outline-fg`, etc.) viven en scope `[data-toggle]`. El `[data-toggle-group-item]` es sibling (no descendant), así que `var(--toggle-solid-on-bg)` resolvía undefined. Fix: inlined derivation expressions directamente en `[data-toggle-group-item]` y sus variant cascades (solid/outline/ghost), referenciando palette tokens en su propio scope local. Validador + emisor + contract: - `validateRecipeComposition` valida el shape `{ targetSelector, tokens }` y rechaza composition entries con scope='root'. - `stripCompositionKey` + `emitComposition` separan el pipeline. - `appendRecipeContractTokens` skip-list para `composition` (no aparece como fake `--{c}-composition` knob). - `tokenKeys`/`tokenEntries` helpers en recipe-css-contract.test.ts filtran composition en todos los iteradores. Documentación: - THEMING.md §18 reescrito como "Cobertura universal de TSC". §7 extendido con subsecciones "Multi-part scope" y "Cross-recipe composition" + ejemplos completos. TOC actualizado. - eidos/README.md tabla de referencia ampliada con TSC v2.2 + §18. - CLAUDE.md gana hand-off "2026-05-27 #5" (TSC v2.2 + cobertura universal). - CONTINUE.md reescrito al estado actual de la sesión. Working tree también incluye sprint Words en paralelo (multiple authors): slash menu, find/replace regex, code language picker, table audit, toolbar family menu, code highlight engine. Tests: 786/786 pass en src/uix/{eidos,morfo,soma,sema}. `npm run check`: 6 errores pre-existentes (lib/_demo, soma/components/internal, web/routes/active) no relacionados. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 months ago
## Theming, tokens, bundle — ver `THEMING.md`
La doctrina completa del sistema de theming (token scope contract, token
layers, naming conventions, bundle purge, motion via `event:*`, comparación
con referencias, anti-patterns, FAQ) vive en
[`src/uix/eidos/THEMING.md`](./THEMING.md). Ese es el reference canónico.
Resumen rápido de lo que cubre, para no duplicar aquí:
| Tema | Sección en THEMING.md |
| --- | --- |
| Por qué el theming vive en Eidos y no en Morfo | §1.bis |
| 7 capas de tokens y override points | §3 |
| 9 roles canónicos de color | §4 |
| 6 sizes canónicos | §5 |
| Naming conventions | §6 |
| Token Scope Contract (TSC): tipo, álgebra de scope, cross-axis | §7 |
| TSC v2.2: multi-part scope (`parts: [...]`) + cross-recipe composition | §7 |
| Cómo añadir un componente nuevo | §8 |
| Cómo definir un theme | §9 |
| Cómo overridear tokens en runtime | §10 |
| Bundle strategy + `eidos:purge` | §11 |
| Integración con sema vía `event:*` | §13 |
| Anti-patterns y FAQ | §16, §17 |
| Cobertura universal de TSC (sin excepciones) | §18 |
feat(eidos): variants canon — EIDOS_VARIANTS + per-component lint Variants son canon del eidos, NO del theme. Decisión arquitectónica firmemente sostenida: el vocabulario de variants (solid/outline/ghost/ soft/surface/line/pills) está fijo a nivel del framework — paralelo a las 8 sema families del libro. Theme = retintar lo perceptualmente fijo; cambia QUÉ color es `affirm`, no QUÉ significa `outline`. Cambios: - lib/types.ts: nueva constante `EIDOS_VARIANTS` con los 5 archetypes canónicos (control / selection / chip / marker / tabs). Los 5 union types se derivan via `[number]` indexed access — valor y tipo no pueden desincronizarse. Nueva `EIDOS_VARIANT_VALUES` Set flat con todos los valores canónicos + utilidades cross-component (`plain`, `subtle`). - recipe-css-contract.test.ts: nuevo test "variant CSS selectors per component match the declared type union". Por cada componente: extrae el union type de `components/{c}/types.ts` (soporta literal unions + archetype aliases; cae a advisory mode en Extract<> y conditional types); compara con `[data-{c}][data-variant='X']` selectores en `{c}.css`; reporta typos y unauthorized extensions bidireccionalmente. - THEMING.md §19: nueva sección "Variants son canon del eidos, NO del theme" con argumentación (portabilidad, type safety, archetypes perceptuales paralelos a sema families), tabla de las 3 capas de la cebolla, referencia a `EIDOS_VARIANTS`, comparación con Radix Themes 3.x / Mantine 7 / Chakra v3 / Ark / shadcn. TOC actualizado. - eidos/README.md: tabla de referencia ampliada con §19. - CLAUDE.md: hand-off "2026-05-27 #6 (variants canon)". - CONTINUE.md: nota de la decisión arquitectónica. Variants component-specific permitidos (Banner inline/overlay/ persistent, Spinner bars/dots/ring, Button 'plain'): viven en cada `components/{c}/types.ts` y el lint los valida contra la CSS del componente. Tests: 101/101 pass en `src/uix/eidos`. `npm run check`: los mismos 6 errores pre-existentes (lib/_demo, soma/components/internal, web/ routes/active) — no relacionados. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 months ago
| Variants son canon del eidos, NO del theme (con `EIDOS_VARIANTS`) | §19 |
feat(eidos): TSC v2.2 (parts + composition) + universal theming coverage Token Scope Contract universal — no más excepciones arquitectónicas. Los 3 componentes que vivían fuera de TSC v2.1 (select, avatar, toggle-group) ahora están dentro del contrato via dos extensiones nuevas. TSC v2.2 extensiones (lib/config-types.ts + render-css.ts + config.ts): - `parts: readonly string[]` en RecipeTokenMultiDeclaration — emite selectores comma-separados (`[data-{c}-x], [data-{c}-y]`) para componentes con data-color cascadeado per-part. Consumer: select. - `composition: { foreignRecipe: { targetSelector, tokens } }` sibling key — overrides cross-recipe scoped a la cascade del host. Consumer: toggle-group modifica `--toggle-palette-*` en sus items. Migraciones: - select: 3 private `_accent-{track,border,text}` con parts: ['trigger', 'content'] + 7 cascades color:X each. Removed orphan `_accent-solid` (CSS no consumía). - avatar: 6 tokens via composite scopes `['variant:X', 'color:Y']` con matrix helper inline. Badge usa parts: ['badge']. Reemplaza 24 bloques CSS × 2 partes. - toggle-group: composition block con 8 palette tokens × 4 colors. Reemplaza 4 bloques CSS per-color. Bug toggle-group post-composition (encontrado y arreglado): Tras la composition migration, el cascade del toggle-group seguía roto porque los tokens derivados (`--toggle-solid-on-bg`, `--toggle-outline-fg`, etc.) viven en scope `[data-toggle]`. El `[data-toggle-group-item]` es sibling (no descendant), así que `var(--toggle-solid-on-bg)` resolvía undefined. Fix: inlined derivation expressions directamente en `[data-toggle-group-item]` y sus variant cascades (solid/outline/ghost), referenciando palette tokens en su propio scope local. Validador + emisor + contract: - `validateRecipeComposition` valida el shape `{ targetSelector, tokens }` y rechaza composition entries con scope='root'. - `stripCompositionKey` + `emitComposition` separan el pipeline. - `appendRecipeContractTokens` skip-list para `composition` (no aparece como fake `--{c}-composition` knob). - `tokenKeys`/`tokenEntries` helpers en recipe-css-contract.test.ts filtran composition en todos los iteradores. Documentación: - THEMING.md §18 reescrito como "Cobertura universal de TSC". §7 extendido con subsecciones "Multi-part scope" y "Cross-recipe composition" + ejemplos completos. TOC actualizado. - eidos/README.md tabla de referencia ampliada con TSC v2.2 + §18. - CLAUDE.md gana hand-off "2026-05-27 #5" (TSC v2.2 + cobertura universal). - CONTINUE.md reescrito al estado actual de la sesión. Working tree también incluye sprint Words en paralelo (multiple authors): slash menu, find/replace regex, code language picker, table audit, toolbar family menu, code highlight engine. Tests: 786/786 pass en src/uix/{eidos,morfo,soma,sema}. `npm run check`: 6 errores pre-existentes (lib/_demo, soma/components/internal, web/routes/active) no relacionados. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 months ago
Lo que sigue en este README son las decisiones operativas de la **capa
visual como módulo** (typography sourcing, picker patterns, API
conventions, runtime activo), independientes del sistema de theming.
feat(eidos foundation): vertebrate typography via named-style aliases + R-2.7 Single source of truth for typography values that the recipe layer consumes. The foundation aliases `--font-ui` and `--leading-ui` (read by ~30 recipe tokens in `lib/recipes/base.ts`) now derive from the canonical `label` named style instead of carrying duplicate literals: --style-label-font-family: var(--font-family-primary); --style-label-line-height: 1.25; --font-ui: var(--style-label-font-family, var(--font-family-primary)); --leading-ui: var(--style-label-line-height, 1.25); Chain: typography.ts styles → --style-{name}-* → --leading-ui / --font-ui → recipe tokens → component CSS. Editing `STATIC_TYPOGRAPHY.styles.label.lineHeight` now propagates to every recipe in one go. Why not push recipes to consume `--style-{name}-*` directly: - t-shirt sizes (xs/sm/md/lg/xl) don't map to four semantic buckets - per-component matices (description/caption/hint) need their own color / weight / letter-spacing - ref libraries (Radix Themes, Mantine, MUI, Chakra) all keep numerical scale for component internals; semantic layer is only for user-facing typography primitives (`<Text variant="body2">`) Audit rule R-2.7 (warn): detects literal font-size / font-weight / line-height / letter-spacing in eidos component CSS. Escape valves: var(...), numeric identities (0/0px/1), keywords (inherit/initial/ unset), or trailing `/* literal: <reason> */` comment. Current run flags 6 components with letter-spacing/font-size literals (all intentional micro-tracking and em-relative; can be annotated case by case). Documentation: - src/uix/eidos/README.md § "Vertebración tipográfica" — two-layer architecture rationale, alias chain diagram, comparison vs Radix Themes / Chakra / Mantine / MUI, escape valves - web/routes/uix/lib/COMPONENT_AUDIT_GUIDE.md § 4.11 — pointer to R-2.7 + cross-link to the foundation doc Verified end-to-end in browser at /uix/components/field: --font-ui → 'Instrument Sans', system-ui, sans-serif --style-label-font-family → 'Instrument Sans', system-ui, sans-serif --leading-ui → 1.25 --style-label-line-height → 1.25 computed [data-field-label].line-height → 17.5px (= 14 × 1.25) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Vertebración tipográfica — single source of truth en foundation
Eidos tiene **dos anclas tipográficas, en capas distintas, por diseño**.
Esta sección documenta por qué y cómo se relacionan.
### Las dos capas
```
src/uix/eidos/lib/primitives/typography.ts
│
├── families / sizes / weights (escala numérica)
│ ↓
│ foundation tokens
│ --font-family-{primary,secondary,display,mono}
│ --font-size-{xxs..xxxl}
│ --font-weight-{regular,medium,semibold,bold}
│ --font-line-height-{xxs..xxxl}
│
└── styles (capa semántica)
↓
named-style tokens
--style-{hero,h1..h6,body,prose,label,caption,code}-{font-family,
font-size,line-height,letter-spacing,font-weight,color}
```
| Capa | Quién la consume | Para qué |
|---|---|---|
| **Foundation numerical** (`--font-size-*`, `--font-family-primary`, …) | recipe tokens en `lib/recipes/base.ts` + foundation aliases (`--font-ui`, `--leading-ui`, …) | Internals de componentes (Field labels, Combobox triggers, Button text, …) — necesitan **escalado t-shirt** (`xs/sm/md/lg/xl`) que NO mapea limpio a una semántica fija. |
| **Named styles** (`--style-label-*`, `--style-body-*`, `--style-caption-*`, `--style-h{1..6}-*`, `--style-{hero,prose,code}-*`) | typography primitives (`<Text>`, `<Heading>`, `<Display>`, `<Code>`, `<Link>`, …) | API de usuario para componer contenido — el USUARIO eligió "label" o "body" y quiere que ese rol semántico se respete. |
**Las dos capas no son redundantes**: sirven a contextos distintos. La
numérica vertebra el _interior_ del sistema; la semántica vertebra la
_superficie_ que el consumer compone.
### Cómo se vertebran sin duplicarse — la chain de aliases
Donde un valor coincide entre las dos capas, **el foundation alias lee
del named style, no al revés**. Single source of truth: el named style.
```css
/* generated/base.css (vía render-css.ts) */
:root {
/* Named style — fuente de verdad */
--style-label-font-family: var(--font-family-primary);
--style-label-line-height: 1.25;
/* Foundation alias — vertebra los recipes */
--font-ui: var(--style-label-font-family, var(--font-family-primary));
--leading-ui: var(--style-label-line-height, 1.25);
}
/* recipes/base.ts → generated/base.css */
:root {
--field-label-line-height: var(--leading-ui);
--field-control-line-height: var(--leading-ui);
/* … docenas de recipe tokens más */
}
/* components/field/field.css */
[data-field-label] {
line-height: var(--field-label-line-height);
}
```
Cambiar `STATIC_TYPOGRAPHY.styles.label.lineHeight = '1.3'` (en
`primitives/typography.ts`) propaga a `--style-label-line-height` →
`--leading-ui` → todos los recipes → todos los componentes. **Una sola
edición** llega a Field, Form, Combobox, Select, Toolbar, Toast y los
typography primitives simultáneamente.
El fallback `, 1.25` / `, var(--font-family-primary)` garantiza que el
sistema sigue produciendo CSS válido si el consumer apaga los named
styles en su foundation override.
### Por qué los component recipes NO leen `--style-{name}-*` directamente
Tentación recurrente: "cada componente debería leer `--style-label-font-size`
para que sea coherente". **No es la forma.**
1. **Las t-shirts no caben en cuatro buckets.** Un Field con `size="xs"`
tiene un label más pequeño que el "label canónico". Si su recipe leyera
`--style-label-font-size`, perderías ese escalado o tendrías que crear
`--style-label-{xs,sm,md,lg,xl}-*`, replicando lo que ya viven los
recipe tokens.
2. **Los matices por componente son legítimos.** El message-de-Field, el
description-de-Tooltip y el subtitle-de-Card son todos "caption-ish"
pero cada uno quiere su color/weight/letter-spacing propios. Forzarlos
a un único `--style-caption-*` mata expresividad.
3. **Coupling lock-in.** Día 100 el sistema quiere `label-form`,
`label-table`, `label-chart`. Forzar acoplamiento día 1 te lleva a
replicar la jerarquía recipe en la capa semántica.
4. **Cómo lo hacen las referencias.** Radix Themes, Mantine, MUI todos
tienen escala numérica que los componentes leen; la capa semántica
existe sólo para los typography primitives (`<Text variant="body2">`).
Chakra v3 ofrece `textStyle` acoplable pero la mayoría de sus
componentes hardcodean igualmente. **Acoplar todo a la capa semántica
no es la práctica dominante** y por buenas razones (1-3).
### Auditoría: regla `R-2.7`
`scripts/component-audit.ts` detecta literales tipográficos en CSS de
componentes: `font-size: 12px`, `line-height: 1.4`, `font-weight: 500`,
`letter-spacing: 0.02em` que **no** estén envueltos en `var()`. Severidad
`warn`, no `error` — el componente sigue pasando, pero queda visible en
el report.
**Escape valves** (no cuentan como drift):
- valores en `var(...)`
- ceros e identidades: `0`, `0px`, `0em`, `0rem`, `1`
- keywords: `inherit`, `initial`, `unset`
- comentario en línea: `font-size: 13px; /* literal: tight icon affordance */`
Si necesitas un literal con justificación, anótalo. Si no, tokenizalo.
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## La regla "2-de-3" (heredada de morfo)
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Una extensión a morfo se justifica si **al menos dos de las tres capas**
(soma, sema, eidos) la consumen. Las que entraron por el voto de eidos:
docs: cross-layer articulation — eidos README + 2-of-3 rule across all layer docs Closes the documentation loop on the cross-layer extension pass: morfo now articulates between soma, sema, and (future) eidos. The "2-of-3 rule" formalizes when an extension to morfo is justified vs when it should stay as provider logic. src/uix/eidos/README.md (new) - Documents eidos's role and what it consumes from morfo + sema BEFORE any code exists, so the contract is preparedly clean when implementation starts. - Catalogs which morfo fields eidos reads (parts, archetype, states, data values, events, prewrite, focus, supportsNesting) and which it ignores (computed state, runtime internals, layers). - Documents the DOM-as-channel pattern: sema writes data-event* on emit; eidos reacts to selectors like `[data-event^="dismiss"]`. - Establishes the boundary with `air` (dead branch reference, not base). src/uix/README.md (top-level) - §8 Reglas de dependencia: adds the 2-of-3 rule table making the morfo-extension contract explicit, plus a list of canonical vocabularies (archetypes, verbs). - §10 Reading order: includes eidos README + lib/dom + clarifies which layers are dead branches. src/uix/morfo/README.md - New "Archetypes" section documenting the 24-verb vocabulary, the Provider-as-trigger vs Provider-as-container distinction, and the rule for adding new archetypes (≥2 components share the role). - New "The 2-of-3 rule" section with the same table as the top-level, listing which extensions did/didn't make it past the rule and why. - `parts[].archetype` mentioned in the "What morfo contains" list. src/uix/sema/README.md - New "Vocabulario canónico de verbs" section listing SEMA_VERBS by family and the `{verb}-{variant}` composite naming convention. - Documents `validateEventName()` as advisory tooling. src/uix/soma/SOMA_ARCHITECTURE.md - partProps documentation now mentions data-archetype emission. - New "Cross-layer hooks que soma emite por la regla 2-de-3" section listing the data-* attrs soma writes that sema and eidos consume. - Reading-order links updated. No code changes — all docs.
6 months ago
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- `archetype` — eidos + sema (+ soma como emisor)
- `events[].semantic.family/intent` — sema + eidos
- `events[].prewrite[]` — soma (ejecuta) + eidos (anima)
- `data-starting-style` / `data-ending-style` — soma (Presence) + eidos (anima)
## Convenciones del API — disciplined option C (vigente 2026-05-10)
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Las convenciones doctrinales viven en
[`src/docs/GUIA_IMPLEMENTACION_SEMAUIX.md`](../../docs/GUIA_IMPLEMENTACION_SEMAUIX.md)
sección 13 (operación instantánea = un evento; sistema
unificado de 8 tokens; intent ↔ color resolution; subset por
componente; iconOnly sr-only; sound prepare-time priming).
La convención del **shape público** del componente eidos vive en
[`components/README.md`](./components/README.md). Resumen — 7 reglas
duras:
1. **Un solo punto de entrada por componente** — la default export es
el componente root visual, llamado igual que el componente
(`<Drawer>`, `<Tabs>`, `<Checkbox>`). NO `<Drawer.Provider>`,
NO `<Drawer.Root>`.
2. **El root vive en `{name}.svelte`** — NO en `{name}-provider.svelte`.
Un solo fichero por root.
3. **NO exportar `Provider` públicamente.** La separación
"Provider compound vs flat" es invención retirada; hay UNA forma
compound (root + hijos atados como propiedades).
4. **Hijos siguen el naming de air / headless**: `Trigger`, `Content`,
`Overlay`, `Title`, `Description`, `Close`, `Portal`, `Header`,
`Footer`, `Item`, `Indicator`, `HiddenInput`, `Group`, `Label`.
No inventar nombres.
5. **`Portal` se incluye donde air lo tenía** (Dialog, Drawer, Popover,
Tooltip — overlays portaled). Importado de
`$soma/components/internal`.
6. **NO flat con snippet slots como API principal** —
`<Drawer trigger={...} title={...}>` está retirado. La compound
explícita expone las decisiones de composición que el flat escondía.
7. **Hijos atados con asignación explícita**, no `Object.assign`
(Svelte 5 puede manejar mal la mutación bulk del component
constructor durante hidratación):
```ts
const Drawer = DrawerRoot as DrawerNamespace;
Drawer.Trigger = Trigger;
Drawer.Content = Content;
```
Plus reglas de implementación:
8. **Wrapper, no fork.** El `.svelte` de eidos importa el namespace
público de Soma (`import * as Drawer from '$soma/components/drawer'`),
usa `<Drawer.Provider>` / `<Drawer.Trigger>` internamente y añade
los data-attrs de tokens visuales. No
reimplementa estado.
9. **`Size` desde `lib/types.ts`.** Componentes que aceptan tamaños
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
reusan el tipo compartido y narrowingan al subset que su recipe
soporta (`Extract<Size, 'sm' | 'md' | 'lg'>`).
10. **Sin prefijo `Eidos`** en los tipos. El path
`$uix/eidos/components/{x}` ya identifica la capa.
11. **CSS recipe sin prefijo `--eidos-`.** Los custom properties usan
`--{component}-…` para los públicos y `--_{component}-…` para los
internos.
### Por qué disciplined option C
El patrón anterior (default flat con snippet slots + Provider compound
duplicado) tenía dos problemas:
- **Doble verdad**: dos APIs (flat con `trigger`/`title`/`actions`
snippets, compound con children explícitos) llevaban a la misma
funcionalidad por caminos divergentes. Cualquier tweak visual
exigía actualizar ambas.
- **Inventaba sobre air**: air era pure compound (`<Drawer.Provider>`
con children). El flat con snippets fue una invención sin
baseline ni firma del usuario.
Option C disciplinada:
- Toma de **air** la convención de hijos (Trigger, Content, Portal, …)
- Toma de **bits-ui / shadcn-svelte** la ergonomía del root con propiedades
attached (`<Drawer><Drawer.Trigger>`)
- Elimina la invención del flat con snippets (no era ni air ni soma)
### Caso especial — Toast
Tiene dos roots independientes (no anidados):
- `<Toast>` — manual compound (consumer itera `toaster.toasts`)
- `<Toaster />` — imperative auto-mount (template default)
Export separados; `Toaster` NO va attached como `Toast.Toaster` porque
es un root competidor, no un hijo. Documentado en
[`components/toast/index.ts`](./components/toast/index.ts).
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
sema/morfo/eidos: typed selector builder + dialog wrapper + emerge color sema architecture - sema-map: 5-channel registry (motion / sound / color / presence / haptic) via SemaChannelSignatures declaration merging; engine stamps data-event-* tokens; flat CSS-style cascade replaces the eventLabel-overrides middle layer. - sema-map: emerge family gains base.color so intent deltas can shift hue / saturation / intensity. Without a base, the resolver was skipping the channel and Dialog open with intent='threat' rendered as neutral blue in the Sema tab visualisation. - types: SEMA_FAMILY_POLICY const drives compile-time + runtime intent requirements per family. Object shape so future per-family policy fields fit alongside. Emerge events MAY now declare intent (canon update — a Dialog confirming threat carries it in its very appearance). - chans: rename vibra→haptic, add HapticChannel V1 (Vibration API); SoundChannel eager-init on first user gesture (autoplay race fix). morfo selector discipline - morfo/selectors.ts (new): semaSelector(morfo, partKebab, matchers?) — type-checked against morfo.parts and morfo.events. Sema cascade rules MUST use it; hand-written strings are an architecture violation that breaks silently when morfo renames a part. - dialog morfo: open carries intent via fromProp; close-cancel / close-dismiss / close-dismiss-outside drop intent (cancellation has no evaluative load); close-save stays hardcoded fulfill (commit fulfils the user's decision regardless of dialog context). eidos dialog migration (4th pilot) - eidos/components/dialog/: full subdirectory wrapper — flat <Dialog> + compound Provider/Trigger/Overlay/Content/Title/Description/Close/Header/ Footer; size + position responsive props; sheet auto-form on narrow viewports; closePosition for the auto-X. - sema/components/dialog.ts: cascade rules use semaSelector(dialogMorfo, 'content', matchers?). Intent block adds character (haptic kind / pattern) but never overrides pitch / gain / contour — those are intent.deltas signature ownership and overriding flattens per-intent perceptual difference. demo controls + dialog page - src/lib/_demo (DemoSwitch / DemoEnum / DemoText / DemoRange) — unified controls reused across all component demos. - web/routes/dialog: live preview always rendered above tabs; per-event Sema tab with independent intent probe; signature visualisation + Play buttons with fallback target chain. documentation - CLAUDE.md: intent.deltas signature ownership rule; eidos drift defense doctrine (types over lint); 2026-05-09 hand-off entry. - morfo/README: Typed selector builder section. - eidos/README: linter section reframed as opt-in safety net for plain CSS recipes; the architectural mechanism is compile-time typing. - sema/README: open channel registry + flat cascade docs + override semantics + intent policy const + selector builder discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Defensa contra drift de selectores
La cadena morfo → soma → eidos depende de que los selectores que eidos
escribe (`[data-{component}]`, `[data-{component}-{part}]`,
`[data-state=...]`, `[data-event-*=...]`) se mantengan en sintonía con
los attrs que el morfo declara y el runtime emite. Hay dos defensas
distintas según el tipo de consumidor:
### Compile-time (TS / Svelte) — typed builder
Cualquier consumidor TypeScript que construya selectores
**MUST** usar `semaSelector(morfo, partKebab, matchers?)` desde
`$uix/morfo`. Esto cubre las cascade rules de `sema/components/*.ts` y
cualquier lógica TypeScript en `eidos/components/{x}/` que apunte a
attrs morfo-backed.
```ts
import { semaSelector } from '$uix/morfo';
import { toggleMorfo } from '$uix/morfo/components/toggle';
sema/morfo/eidos: typed selector builder + dialog wrapper + emerge color sema architecture - sema-map: 5-channel registry (motion / sound / color / presence / haptic) via SemaChannelSignatures declaration merging; engine stamps data-event-* tokens; flat CSS-style cascade replaces the eventLabel-overrides middle layer. - sema-map: emerge family gains base.color so intent deltas can shift hue / saturation / intensity. Without a base, the resolver was skipping the channel and Dialog open with intent='threat' rendered as neutral blue in the Sema tab visualisation. - types: SEMA_FAMILY_POLICY const drives compile-time + runtime intent requirements per family. Object shape so future per-family policy fields fit alongside. Emerge events MAY now declare intent (canon update — a Dialog confirming threat carries it in its very appearance). - chans: rename vibra→haptic, add HapticChannel V1 (Vibration API); SoundChannel eager-init on first user gesture (autoplay race fix). morfo selector discipline - morfo/selectors.ts (new): semaSelector(morfo, partKebab, matchers?) — type-checked against morfo.parts and morfo.events. Sema cascade rules MUST use it; hand-written strings are an architecture violation that breaks silently when morfo renames a part. - dialog morfo: open carries intent via fromProp; close-cancel / close-dismiss / close-dismiss-outside drop intent (cancellation has no evaluative load); close-save stays hardcoded fulfill (commit fulfils the user's decision regardless of dialog context). eidos dialog migration (4th pilot) - eidos/components/dialog/: full subdirectory wrapper — flat <Dialog> + compound Provider/Trigger/Overlay/Content/Title/Description/Close/Header/ Footer; size + position responsive props; sheet auto-form on narrow viewports; closePosition for the auto-X. - sema/components/dialog.ts: cascade rules use semaSelector(dialogMorfo, 'content', matchers?). Intent block adds character (haptic kind / pattern) but never overrides pitch / gain / contour — those are intent.deltas signature ownership and overriding flattens per-intent perceptual difference. demo controls + dialog page - src/lib/_demo (DemoSwitch / DemoEnum / DemoText / DemoRange) — unified controls reused across all component demos. - web/routes/dialog: live preview always rendered above tabs; per-event Sema tab with independent intent probe; signature visualisation + Play buttons with fallback target chain. documentation - CLAUDE.md: intent.deltas signature ownership rule; eidos drift defense doctrine (types over lint); 2026-05-09 hand-off entry. - morfo/README: Typed selector builder section. - eidos/README: linter section reframed as opt-in safety net for plain CSS recipes; the architectural mechanism is compile-time typing. - sema/README: open channel registry + flat cascade docs + override semantics + intent policy const + selector builder discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
semaSelector(toggleMorfo, 'provider', { eventName: 'commit-toggle' });
sema/morfo/eidos: typed selector builder + dialog wrapper + emerge color sema architecture - sema-map: 5-channel registry (motion / sound / color / presence / haptic) via SemaChannelSignatures declaration merging; engine stamps data-event-* tokens; flat CSS-style cascade replaces the eventLabel-overrides middle layer. - sema-map: emerge family gains base.color so intent deltas can shift hue / saturation / intensity. Without a base, the resolver was skipping the channel and Dialog open with intent='threat' rendered as neutral blue in the Sema tab visualisation. - types: SEMA_FAMILY_POLICY const drives compile-time + runtime intent requirements per family. Object shape so future per-family policy fields fit alongside. Emerge events MAY now declare intent (canon update — a Dialog confirming threat carries it in its very appearance). - chans: rename vibra→haptic, add HapticChannel V1 (Vibration API); SoundChannel eager-init on first user gesture (autoplay race fix). morfo selector discipline - morfo/selectors.ts (new): semaSelector(morfo, partKebab, matchers?) — type-checked against morfo.parts and morfo.events. Sema cascade rules MUST use it; hand-written strings are an architecture violation that breaks silently when morfo renames a part. - dialog morfo: open carries intent via fromProp; close-cancel / close-dismiss / close-dismiss-outside drop intent (cancellation has no evaluative load); close-save stays hardcoded fulfill (commit fulfils the user's decision regardless of dialog context). eidos dialog migration (4th pilot) - eidos/components/dialog/: full subdirectory wrapper — flat <Dialog> + compound Provider/Trigger/Overlay/Content/Title/Description/Close/Header/ Footer; size + position responsive props; sheet auto-form on narrow viewports; closePosition for the auto-X. - sema/components/dialog.ts: cascade rules use semaSelector(dialogMorfo, 'content', matchers?). Intent block adds character (haptic kind / pattern) but never overrides pitch / gain / contour — those are intent.deltas signature ownership and overriding flattens per-intent perceptual difference. demo controls + dialog page - src/lib/_demo (DemoSwitch / DemoEnum / DemoText / DemoRange) — unified controls reused across all component demos. - web/routes/dialog: live preview always rendered above tabs; per-event Sema tab with independent intent probe; signature visualisation + Play buttons with fallback target chain. documentation - CLAUDE.md: intent.deltas signature ownership rule; eidos drift defense doctrine (types over lint); 2026-05-09 hand-off entry. - morfo/README: Typed selector builder section. - eidos/README: linter section reframed as opt-in safety net for plain CSS recipes; the architectural mechanism is compile-time typing. - sema/README: open channel registry + flat cascade docs + override semantics + intent policy const + selector builder discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// → '[data-toggle][data-event="commit-toggle"]'
```
Renombrar una part o un evento en el morfo rompe el typecheck. Es
imposible que un selector TypeScript drifte silenciosamente. Ver
[`morfo/README.md#typed-selector-builder--semaselector`](../morfo/README.md#typed-selector-builder--semaselector).
### Run-time (CSS recipes) — `eidos-lint` como red de seguridad opt-in
Los recipes son CSS plano (`components/{x}/{x}.css`); no hay typed
builder en el lado CSS. Para esa superficie:
```bash
node scripts/eidos-lint.ts toggle # un componente
node scripts/eidos-lint-all.ts # todos
```
Clasifica cada selector `[data-*]` como:
- **morfo-backed** — declarado en el morfo; soma runtime lo emite;
el valor (si hay enum) cae dentro de `data[].values`.
- **eidos-only** — el marker está, pero al menos un `data-*` no está
declarado en el morfo. Válido por convención (tokens visuales como
`data-variant`, `data-size` vienen del wrapper).
- **invalid** — referencia un attr declarado pero con un valor fuera
del enum. Bug.
**El lint es una red de seguridad, no el contrato.** El contrato vive
en el morfo y se defiende a nivel de tipos donde se puede. El lint
existe sólo para la porción CSS-pura que aún no consume el morfo a
través de TypeScript. Cuando los recipes migren a un builder, el lint
podrá retirarse.
eidos: pilot wrapper pattern + doctrinal API conventions Toggle as the eidos pilot: subdirectory layout (recipe + Svelte wrapper + types + index + README) replacing the flat CSS-only form. Pattern is documented in eidos/components/README.md and the toggle README. Shared types live in eidos/lib/types.ts. First export is `Size` (8 values xxs..xxl + full); components narrow with `Extract<Size, ...>` per the per-component-subset doctrine. No `Eidos` prefix on types — module path already conveys the layer. API doctrine: - soma stays compound (Toggle.Provider) for symmetry with multi-part - eidos exports both default + Provider so single-part components accept both `<Toggle>` (ergonomic) and `<Toggle.Provider>` (compound-style consumers) SoundChannel eager-init fixes the autoplay race: AudioContext is created + resumed synchronously on the first user gesture (capture-phase listener registered in the constructor), avoiding the previous race where the first emit() scheduled the resume in a microtask outside the gesture window. Demo page (web/routes/toggle/+page.svelte) restructured so the live preview renders ALWAYS above the tablist — Sema-tab Play buttons can fire on the real toggle. Motion preview amplifies scale ×8 visually only; doctrinal values stay in the <dl>. Conventions 7-13 added to src/docs/sema-implementation-guide.md covering: directory structure, wrapper composition, no Eidos prefix, soma compound vs eidos flat, iconOnly sr-only body, sound eager-init, docs-preview amplification. CLAUDE.md gets a session hand-off block listing where things stand and next concrete steps (migrate switch/collapsible/dialog/drawer/popover/ toast/avatar; wire topbar sound mute to masterGain; rename theme tokens to drop the success/warning/danger fallback aliases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
docs: consolidate kind contract + composition norms (sweep) After several commits on pickers, the docs lagged behind the actual contract. This sweep aligns PENDIENTES + eidos README + DEMO_AUTHORING_GUIDE with what landed. PENDIENTES.md: - 'Pickers' section rewritten as a consolidated state table. Everything done is marked hecho; the two big items (MonthPicker/YearPicker, MonthRangePicker/YearRangePicker as separate components) are explicitly **descartar** because they're achieved via <DatePicker kind='X'> / <DateRangePicker kind='X'>. Duplicating component surfaces for what a prop captures is doctrinally rejected. - Promotion of YearView/MonthView to standalone <YearCalendar> / <MonthCalendar> is **diferir** — currently coupled to picker provider context, no real use case outside picker yet. - Time picker / color picker propagation of modal+Footer pattern marked **implementar**. - Playwright browser tests for the picker flows marked **implementar** — range state machine + kind chip + modal need coverage. - Range view: 'differentiate start/end vs in-range visually' added to theming backlog (currently all 3 use primary-solid, range tint not visible). - Two new norms N-6 and N-7: * N-6 picker kind = single source for input + view. Filtering lives at DateFieldProvider (soma), consumers iterate the segments output. Views are canonical Eidos parts. * N-7 composition over visibility props. Parts opt-in by inclusion, not by boolean prop. Demo wraps parts in {#if showX} with local state so the UI toggles still work without leaking demo logic into the parts. eidos/README.md: - New 'Cambios 2026-05-21 — pickers: kind + composition' section summarising kind + Footer composition + provider helpers + the 'composition wins, no separate variant components' decision. DEMO_AUTHORING_GUIDE.md: - §12.9 'Composition over visibility props': right vs wrong example for <DatePicker.Footer> with the Clear/Cancel/Close children. - §12.10 'Chakra-style kind for picker variants': demo skeleton for the Input snippet (no filter) and the Content {#if} branch. Task list: #29 retired (MonthRangePicker/YearRangePicker as separate components — replaced by <DateRangePicker kind='X'>). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Cambios 2026-05-21 — pickers: kind + composition
- **`kind: 'date' | 'month' | 'year'`** sobre `DatePicker` y
`DateRangePicker`. Single source for input segments + popover view.
Inputs filtran segments en el `DateFieldProvider` (soma) — los
consumers nunca filtran en el snippet. Views como parts canónicas
Eidos: `<DatePicker.YearView>`, `<DatePicker.MonthView>`, idem en
range. Range views implementan state machine: empty → start, pending
→ end (con swap automático si reverse), complete → reset.
- **Footer = composición pura**. Drop de `clearButton/cancelButton/
closeButton` root props. `<Picker.Footer>` contiene las parts que
compongas; cada part renderiza siempre que se monta (sin checks
internos). Modal mode no fuerza Close visible — el consumer es
responsable de incluirlo (documentado en la part).
- **Modal mode + footer pattern** documentado en
[`PENDIENTES.md`](../PENDIENTES.md) (norma N-6 y N-7).
- **Provider helpers**: `commit() / cancel() / clear()` en
DatePickerProvider y DateRangePickerProvider. `cancel()` revierte
al snapshot capturado en el OPEN edge vía `watch(open)`.
- **Composition wins**: no hay `MonthPicker` / `YearPicker` /
`MonthRangePicker` / `YearRangePicker` como componentes propios.
Esas variantes son `<DatePicker kind='month'>` /
`<DateRangePicker kind='year'>` etc.
## Picker patterns (contrato reutilizable)
Los pickers (`date-picker`, `date-range-picker`, y los futuros
`time-picker`, `time-range-picker`, `color-picker`) comparten un
contrato común. Documentado aquí como referencia canónica — cualquier
picker nuevo se construye sobre este esqueleto.
### P-1 · Provider helpers: `commit() / cancel() / clear()`
Cada `*PickerProvider` expone tres métodos imperativos consumidos por
las parts del Footer:
- **`commit()`** — cierra el popover preservando `value.current` tal
cual. Es la confirmación normal del valor seleccionado.
- **`cancel()`** — revierte `value.current` al snapshot capturado en
el **OPEN edge** y cierra el popover. El snapshot se toma vía
`watch(opts.open)` cuando `open` transita de `false → true`:
```ts
private valueOnOpen: TValue | undefined = undefined;
constructor(...) {
watch(() => this.opts.open.current, (isOpen) => {
if (isOpen) this.valueOnOpen = $state.snapshot(this.opts.value.current);
});
}
cancel() {
this.opts.value.current = this.valueOnOpen;
this.opts.open.current = false;
}
```
- **`clear()`** — pone `value.current = undefined`. NO cierra el
popover (es una acción destructiva visible que el usuario puede
querer seguir editando). Si el consumer quiere cierre tras clear,
compone `<Picker.Close/>` en el mismo footer.
Estas tres operaciones son ortogonales: cada part Footer hace exactamente
una. No mezcles (ej. `clear` no debe cerrar; `cancel` no debe limpiar).
### P-2 · `mode: 'inline' | 'modal'` → `popover.modal`
`mode` es un opt root del provider que se propaga al `Popover.modal`
underlying:
- **`mode='inline'`** (default) — popover no-modal. Outside-click
cierra. Escape cierra. Body scroll libre.
- **`mode='modal'`** — popover modal. Outside-click NO cierra (el
usuario debe usar `<Picker.Close/>` o `<Picker.Cancel/>`). Escape
sigue cerrando. Focus trap dentro del popover. Body scroll lock.
El consumer NO setea `popover.modal` directamente — eso es decisión
del provider:
```svelte
<Popover.Provider modal={provider.opts.mode.current === 'modal'} ...>
```
Modal mode obliga al consumer a componer un Footer con `<Cancel/>` o
`<Close/>` para escapar; sin ellos el popover sólo cierra por Escape.
Sigue siendo el consumer responsable (no auto-injecta nada).
### P-3 · Shell composition (Provider > Input > Portal > Content > view + Footer)
Layout canónico de un picker:
```svelte
<X.Provider value={...} open={...} mode='modal' kind='date'>
{#snippet trigger()}
<X.Input /> {!-- field input con segments, button, etc. --}
{/snippet}
{#snippet content()}
<X.Content>
{#if kind === 'year'} <X.YearView />
{:else if kind === 'month'} <X.MonthView />
{:else} <X.Calendar />
{/if}
<X.Footer>
<X.Clear />
<X.Cancel />
<X.Close />
</X.Footer>
</X.Content>
{/snippet}
</X.Provider>
```
- **Trigger snippet** — entry surface (input + segments, button, swatch…).
- **Content** — popover content; sólo `<X.Content>` puede ir aquí.
- **View** — `Calendar`, `YearView`, `MonthView`, `Clock`, `Picker`
(color), etc. El consumer hace branching estructural por `kind` o
variante (P-4 abajo).
- **Footer** — `<X.Footer>` es contenedor archetype='footer'. Las
parts (`Clear`, `Cancel`, `Close`, etc.) se componen dentro. Cada
part renderiza sin checks internos contra props del provider —
presencia = visibilidad (N-7).
Si quieres omitir el footer entero, no compones `<X.Footer>`. Si
quieres sólo `Close`, compones sólo `<X.Close>` dentro.
### P-4 · `kind` o equivalente como single source of truth
Cuando un picker tiene variantes de granularidad (date: day/month/year;
time: hour/minute/second), el opt `kind` (o equivalente) es el **único
punto de configuración**. Drives:
1. **Segments del input** — filtrado a nivel del FieldProvider (soma),
no en el snippet del consumer. El provider expone una derivación
tipo `visiblePartsByKind: Set<PartName>` y `segmentContents` filtra
`allSegmentContent.arr` colapsando literal runs.
2. **View del popover** — el consumer hace branching estructural sobre
el opt (`{#if kind === 'year'} <YearView/>` etc).
**No existen** componentes separados por variante (`MonthPicker`,
`HourPicker`, etc). Esas formas son `<X kind='month'>`,
`<X kind='hour'>`.
### P-5 · Range state machine (para `*-range-picker`)
Para selección de rangos, el provider mantiene un estado interno
implícito (no expuesto como opt):
- **empty** (`value === undefined` o `{start: undefined, end: undefined}`)
— siguiente click setea `start`. Estado pasa a `pending`.
- **pending** (`start` definido, `end` undefined) — siguiente click
setea `end`. Si el nuevo punto < `start`, **swap automático**
(start ↔ end). Estado pasa a `complete`.
- **complete** (`start` y `end` definidos) — siguiente click reinicia:
setea `start = click`, `end = undefined`. Estado pasa a `pending`.
Cada granularidad normaliza los endpoints:
- **Year range** — start = Jan 1, end = Dec 31.
- **Month range** — start = day 1, end = último día del mes.
- **Day range** — start/end son la fecha clickada tal cual.
- **Hour range** — start = `:00`, end = `:59:59`.
Implementado en `YearView`/`MonthView`/`Calendar` (range variant). El
provider sólo expone `setValue(start, end)`; la state machine vive
en los views.
eidos: theming fixes + size/variant parity batch + docs - theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
## Cambios 2026-05-21
- **Tokens muted añadidos al contrato.** `SurfaceColorRoles` y
`ContentColorRoles` ahora incluyen `muted` (entre `overlay`+`backdrop`
y entre `secondary`+`disabled` respectivamente). Mapeo base:
`--color-surface-muted: var(--primitive-neutral-3)` (light + dark) y
`--color-content-muted: var(--primitive-neutral-10)`. Antes existían
17+3 referencias rotas en recipes/components que el browser caía a
initial-value (texto invisible para placeholders, separadores,
weekday del calendar, group-heading del select, etc.). Solucionado
vía `themes/base.ts` + `render-css.ts` + regen.
- **Typo `--color-neutral-element-hover` corregido** en `form.css:76`
→ `--color-neutral-hover` (el token correcto existente).
- **Raw colors removidos.** `archetypes.css:122` (hsl indigo fijo para
`[aria-selected]`) y `events.css:eidos-commit-settle` (rgba indigo
fijo) sustituidos por `color-mix(var(--color-primary-solid) …)`. Ya
no quedan hex/rgb/hsl crudos en `src/uix/eidos/**/*.css` ni en
`recipes/base.ts`.
- **Cobertura de tamaños expandida.** 20 componentes pasan de
`sm·md·lg` a `xs·sm·md·lg·xl` (form controls + text inputs +
progress/meter + field/form) o a `xs·sm·md·lg` (nav controls:
breadcrumb, pagination, tag-group, toolbar). Categorización
documentada en
[`web/routes/uix/lib/DEMO_AUTHORING_GUIDE.md §12.8`](../../../web/routes/uix/lib/DEMO_AUTHORING_GUIDE.md).
Paneles compuestos (calendar, date-picker, date-range-picker,
file-upload, stepper, tooltip) mantienen `sm·md·lg`. La elección
responde a uso real, no a artificio: barras y controles tactiles
escalan limpio en 5 escalones; paneles compuestos no se benefician
por debajo de `sm`.
- **Paridad de chips en demos.** `field.variant` y `toolbar.variant`
dejaron de narrowar `ControlVariant` a 2 valores; ahora exponen los
3 (`surface | outline | ghost`). El CSS añade selectores
`[data-variant='outline']` con bg transparente + border visible para
ambos componentes. La norma queda fijada en CHECKLIST §D-7.4.
- **Scrollbar portaled.** Las reglas `::-webkit-scrollbar*` viven sin
scope en `web/routes/uix/uix.css` (sólo se carga bajo `/uix`).
`--uix-line` se duplica en `:root` con override
`:root[data-mode='dark']` (atributo escrito por `ActiveEidos`),
permitiendo que portals (Combobox listbox, Popover, Dialog, Drawer)
resuelvan el token aunque vivan fuera de `[data-uix-docs]`.
## Estado actual (2026-05-17)
- **ActiveEidos**: implementado como runtime/contexto visual y superficie de
configuracion. Gestiona primitivas, roles canonicos, themes, validacion,
contrato CSS, persistencia y render CSS (`renderStaticCss`,
`renderThemeCss`).
- **Authoring API**: `defineEidosConfig`, `extendEidosConfig` y
`createThemeBaseEidosConfig`
permiten crear configuraciones completas o extender el theme base sin
mutar las constantes del sistema. `getCssContract()` expone el contrato
estructurado, `renderContractCss()` lo materializa como CSS para themes
externos, `renderCssVariables()` permite escribir overrides runtime
contract-aware y `toDocument()` / `serialize()` exponen el envelope
versionado para persistencia.
- **Runtime CSS**: `ActiveEidos` reacciona a su `preferences` compuesto o a
fuentes explicitas `modeSource` / `densitySource`, soporta themes de config
y CSS-only via `themeSource`, acepta variables runtime en un style block
propio, y con `applyDom:false` no escribe en el DOM.
- **Wrappers por componente**: la superficie migrada desde Soma ya incluye
`toggle`, `switch`, `collapsible`, `dialog`, `drawer`, `popover`, `toast`,
`accordion`, `avatar`, `tooltip`, `tabs`, `checkbox`, `radio-group`,
`meter`, `progress`, `slider`, `pagination`, `rating-group`,
`search-field`, `number-field` y `breadcrumb`. Todos usan root visual +
partes attached, sin `Provider` público ni API flat.
- **Color**: basado en roles canonicos de jerarquia e intents
(`primary`, `secondary`, `tertiary`, `neutral`, `affirm`, `fulfill`,
`risk`, `threat`, `loss`) y escalas de 12 pasos. Por cada escala genera
alpha tokens `a1..a12`, derivadas automaticamente o sobrescribibles con
`color.alphaScales` por theme. Los roles semanticos validos son solo los
declarados por el contrato de Eidos.
- **Size**: `xxs..xxl` se renderiza como map global coordinado
(`control-height`, font, icon, padding, gap, radius). `full` queda como
eidos: theming fixes + size/variant parity batch + docs - theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
valor de layout, no como primitiva fisica. Cada componente declara
el sub-rango que su recipe mapea — la categorización canónica está
en `DEMO_AUTHORING_GUIDE.md §12.8` (form controls + text inputs +
progress/meter + field/form usan `xs..xl`; nav controls usan
`xs..lg`; paneles compuestos mantienen `sm..lg`).
- **Border / opacity / z-index / shadow**: ya forman parte del contrato
generado. Border define escala de width/style y aliases globales; opacity
cubre estados de UI y overlays; z-index cubre capas comunes; shadow combina
escala fisica `1..6` con aliases semanticos por theme.
- **Layout**: ya forma parte del contrato generado. Incluye
`containerWidth`, `containerPaddingInline`, `contentWidth` y `aspectRatio`
como tokens estables y authorables desde `EidosConfig`.
- **Density**: ya forma parte del contrato generado. Incluye `scale`,
`spaceScale`, `controlScale` y `contentScale` para los tres niveles
canonicos `compact`, `comfortable` y `spacious`, conectados al
`data-density` que proyecta `ActiveEidos`.
- **Tipografia**: usa tamaños canonicos `xxs` a `xxxl`, familias
libres por key y estilos tipograficos (`h1`, `h2`, `body`, etc.) como
`Record<string, TypographyStyle>`.
- **Convencion del API de componentes**: disciplined option C esta
documentada en [`components/README.md`](./components/README.md). La migracion
de componentes avanza por tandas pequenas y no debe arrastrar cambios de
demos/rutas ni reimplementar comportamiento que pertenece a Soma.
- **CSS generado**: `generated/base.css` ya se genera desde la config
base de Eidos con `npm run generate:eidos-css` y se importa como foundation
estatica. Los CSS historicos de `contracts/` y `themes/base/` ya no existen
en el arbol activo; el contrato se publica desde `ActiveEidos` y los valores
base desde `generated/base.css`. Los antiguos `tokens/components/*` tambien
salen del entrypoint: `EidosConfig.recipes` genera los aliases de recipe
estables.
- **Recipes**: quedan deliberadamente como `RecipeTokenSet` plano. No se crea
jerarquia estructurada hasta que una recipe tenga un builder/consumer real
que necesite mas semantica que aliases CSS. La guardia
`recipe-css-contract.test.ts` evita que el theme base declare aliases no
consumidos o que un CSS de componente use variables fuera del contrato.
- **Check del repo**: `npm run check` no reporta errores ni warnings en este
punto.

Powered by TurnKey Linux.