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/docs/theming/channels.md

144 lines
6.6 KiB

---
title: The channels as one system — synthesis
type: notes
audience: human + agent
authority: E3 — the capstone tying the per-channel RFCs to the book's thesis
status: current
source: migrated from src/uix/eidos/CHANNELS_SYNTHESIS.md (2026-07-02, docs-book F7.3)
---
# The channels as one system — synthesis ("Diseñando lo que ocurre")
> The **capstone** of the per-channel RFCs. The thesis of the book *Diseñando
> lo que ocurre*: an interaction **is not** color, or movement, or sound — it
> is **one perceptual occurrence spread across N channels**, under the
> **two-moment** model. This ties together [`rfc-color-engine`](../rfcs/rfc-color-engine.md) ·
> [`rfc-typography`](../rfcs/rfc-typography.md) · [`rfc-depth`](../rfcs/rfc-depth.md) ·
> [`rfc-shape`](../rfcs/rfc-shape.md) ·
> [`rfc-structure`](../rfcs/rfc-structure.md). Live demo: **`/temas/orquesta`** (the mixer).
## 1. Two moments, joined by a token: sema emits, eidos reads
An occurrence flows through **two moments**, connected by the **token**:
- **Sema's moment (emission)** — sema evaluates the occurrence and **emits**
it. Sound + haptics it **executes right there** (runtime channels); for the
visual, it **stamps it as tokens** `data-event-*` (family · intent ·
phase). Sema **knows no DOM/CSS**.
- **Eidos's moment (materialization)** — eidos **reads** those tokens
(+ `data-state`) and **materializes** them in CSS (the visual channel). It
is the **sole visual owner**.
The **token is the contract**: sema writes, eidos reads — which is why the
layers decouple (sema DOM-agnostic, eidos free of semantic logic).
Over that producer → consumer axis runs the **temporal** axis (motion F1) —
*which* token:
| Token | Nature | Who writes it | Eidos reads it as |
|---|---|---|---|
| `data-state` | persistent — what the element **is** | soma / morfo | `presets` |
| `data-event-*` | transient — what **occurs** (during the `hold`) | sema (emits) | `signatures` |
`sequence` (`pre` / `coincident` / `post`) orders the two.
## 2. Expression channels (the book) vs sema channels (runtime)
The book has **8 expression channels** (perceptual dimensions). The framework
implements them with sema's **runtime channels**, which are **3** — and here
is the key that avoids the classic confusion:
| Sema channel (runtime) | Covers (the book's expression) | Who materializes it |
|---|---|---|
| **visual** (sema projects `data-event-*`) | movement · presence · depth · shape · color | **eidos** — CSS over `data-event-*` + `data-state` |
| **sound** | sound | sema (`chans/sound`) |
| **haptic** | haptics | sema (`chans/haptic`) |
> **Don't get confused**: **motion · depth · shape · color are NOT "eidos
> channels"** — they are sema's **`visual` channel**, which sema projects and
> **eidos materializes**. Eidos is the visual channel's *materializer*, not
> the owner of channels of its own. The eidos RFCs (`COLOR/DEPTH/SHAPE_ENGINE`)
> describe *how* eidos materializes each visual facet — not independent
> channels.
Plus **space** ([`rfc-structure.md`](../rfcs/rfc-structure.md)) — **structural,
not expressive**: it doesn't "occur", it is the stage (state-only).
## 3. The layer chain (each with its role)
An occurrence **crosses the layers** — it is not "all sema", and eidos is not
a shim:
1. **morfo** — **declares** the event and its semantics (family · intent ·
verb). The contract / DNA; pure TypeScript, no runtime.
2. **soma** — **fires** it (`runtime.trigger`): the sequence `prewrite →
sema.emit → handler →` state attrs. It writes `data-state` (the
state-moment).
3. **sema** — **emits** it: dispatches the signal to its channels —
**executes** `sound` + `haptic`; **projects** the visual channel by
stamping `data-event-*`. It knows no DOM/CSS.
4. **eidos** — **materializes** it: reads `data-state` (`presets`) +
`data-event-*` (`signatures`) and renders them with its **token engines**
(color · motion · depth · shape · space — the RFCs). It is the **complete
visual system** and the sole owner of the visual.
> Eidos does **not "make sema visible"**: sema contributes the **what**
> (family / semantic intent), eidos contributes the **how** (the visual
> vocabulary and its materialization). Co-layers, not one subordinate.
(The full canonical narrative lives in `CLAUDE.md` → "Sema: open channel
registry".)
## 4. The composition — one event, N channels
The **signature** (`BUILTIN_SIGNATURES` + `BUILTIN_KEYFRAMES`) is
**cross-modal**: a single keyframe carries several modalities. A real example
(`press-squeeze`, family `contact`):
```
contact · press → scale 0.96 (motion)
+ box-shadow → flat (depth recede)
+ --shape-smoothing 2→3 (shape: the corner firms up)
+ tick (sema sound)
+ vibration (sema haptic)
```
One `engine.emit(...)` stamps `data-event-*` (the **visual** channel reacts —
eidos materializes it as color/motion/depth/shape) **and** fires sound +
haptic — from the **same** event. There are no systems coordinating by hand;
there is one occurrence expressing itself through sema's channels.
## 5. Runtime builders — the sextet (an open cage)
Every axis retunable at runtime, same pattern (seed → managed block), opt-in
over the authored scale:
fix(cleanroom): F2+F3+F4-C+SEM-4s1 — lote mecánico, censos con guard, corpus documental y el close polimórfico de los pickers VIVO F2 — lote mecánico (13 ítems): - DEP-2 ogl eliminado (0 imports) · DEP-1 clsx inlineado como toClassString propio + suite de contrato (props.test.ts; soma.md §12 cerrado). - THM-7: los 5 selectores manuales de sema.md reescritos con semaSelector (los ejemplos [data-toast-root] apuntaban a un part INEXISTENTE — la deriva que el builder previene, demostrada en el propio doc). - MOR-1 escape isomorfo + validación de attr-names en semaSelector + 9 tests (selectors.test.ts, matches() real con comillas/corchetes) · MOR-2 partMarkerAttr = única fuente compilador↔builder + test de paridad · MOR-3 _resetCompileCache borrado (0 usos). - SOM-2 keydown continue en match sin handler + keyboardFixtureMorfo · SOM-1 no-await de handlers (censo async = 0; contrato V1 cumplido) + pin. - SEM-2 trigger pre-attacha catch con logger (void trigger sin unhandled rejection; throw intacto para awaiters) + pin · SEM-3 fallback muerto de applyDominance → skip defensivo + timer tope de awaitExpression cancelado · SEC-1 adjudicado YA implementado (assertCssVariableValue desde 2026-05-11) + pin del path de VALOR. - accordion → outline (§32; su outline:none dejaba CERO anillo en HCM) — verificado en vivo · THM-6 radius-full 9999px · EID-4 recuentos 33. F3 — censos con guard: - SOM-3 cerrado: announcer + image-provider migrados a scheduler-preferred (consumidores cableados: date/time-field vía soma.uix.timers; avatar/image vía eidos.timers — verificado en vivo); guard de timers ENSANCHADO de soma/components a TODO soma y pasado a EVIDENCIA (setTimeout exige .schedule( en el fichero — layers/ y datetime/ escapaban del ámbito viejo). - THM-5: R-4.7 nueva (válvula same-line /* important: <razón> */, escaneo comment-blanked) + las 15 declaraciones anotadas con su razón + canon recipe-contract §3/§4. - SOM-4 adjudicado: el censo/guard YA existían (49 pins); knob/mask-field/ timeline pinneados (overrides documentados en call-site); media-player Batch-4 (35 hits, cero renderProps) = único batch restante, registrado. - THM-4 doctrinado en eidos.md §unused (comportamiento/composición = legítimo; deuda = eje visual sin consumidor; hotspots por lotes). F4-C — corpus documental (decisiones de usuario aplicadas): - DOC-3: los 15 enlaces muertos resueltos (repoint a la edición FINAL trackeada / des-link históricos) · docs:check I6-links WARN→ERROR. - DOC-1: tabla «Build contract» MIGRADA a component-guide con estados modernizados (A3–A5 → LIVE + guards de hoy); banners reapuntados; citas de CANON/sema.md historificadas; lápida-redirect en el §13 del fósil. - DOC-4: hold chain → holds.ts · FAQ event:* SUPERSEDED por signatures · gradient añadido a los DOS capstones (sextet real) · nota de paleta de demo-authoring corregida (universalPaletteDecls + decisión THM-2 = mecanismo universal como sucesor del tracker borrado). - DOC-5/6: recuentos anti-frágiles datados · §4.11 dup → §4.12 · Known gaps historificado · N-6/N-7 recuperadas de git (d68d2c45^) y canonizadas en eidos.md §pickers · authoring E2 → canon/tsc.md · air-old des-linkado · EID-3 (placement) en la fila RTL · AUX-2 disabledDom documentado. SEM-4 sesión 1 — el close polimórfico de los pickers, VIVO (D.11): - Reconciliación: los morfos ya no declaran close (delegated al Popover, de-dialoged 06-27); el agujero real era el cierre programático bypaseando dismissWith → save/cancel/select eran perceptualmente SILENCIOSOS. - Fix: PickerShellHandle.setPopoverDismiss + closeWith(cause) en los 5 providers (14 sitios; select/commit → 'save' = commit.save+fulfill, cancel → 'cancel' = emerge; fallback raw para headless) + UN inyector en el eidos PickerShell root (norma N-8). Picker genérico fuera a propósito (ya suena commit-set/cancel por diseño S9). - Verificado en vivo (date-picker): Done → close·commit·fulfill·active · Cancel → close·emerge · cierre real. Gates: matriz 141/141 (los 6 morfos nuevos de la pista de texto paralela también PASS) · contracts 38/38 · eidos 314 · sema 178 · morfo 94 · docs:check 0/0 con I6 en error · baseline propio 57. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
`applyColorScheme` · `applyTypeScale` · `applyDepth` · `applyShape` ·
`applySpacing` · `applyGradients`
And the **capstone composing them**: **`applyTheme(seed)`** — a single seed
fix(cleanroom): F2+F3+F4-C+SEM-4s1 — lote mecánico, censos con guard, corpus documental y el close polimórfico de los pickers VIVO F2 — lote mecánico (13 ítems): - DEP-2 ogl eliminado (0 imports) · DEP-1 clsx inlineado como toClassString propio + suite de contrato (props.test.ts; soma.md §12 cerrado). - THM-7: los 5 selectores manuales de sema.md reescritos con semaSelector (los ejemplos [data-toast-root] apuntaban a un part INEXISTENTE — la deriva que el builder previene, demostrada en el propio doc). - MOR-1 escape isomorfo + validación de attr-names en semaSelector + 9 tests (selectors.test.ts, matches() real con comillas/corchetes) · MOR-2 partMarkerAttr = única fuente compilador↔builder + test de paridad · MOR-3 _resetCompileCache borrado (0 usos). - SOM-2 keydown continue en match sin handler + keyboardFixtureMorfo · SOM-1 no-await de handlers (censo async = 0; contrato V1 cumplido) + pin. - SEM-2 trigger pre-attacha catch con logger (void trigger sin unhandled rejection; throw intacto para awaiters) + pin · SEM-3 fallback muerto de applyDominance → skip defensivo + timer tope de awaitExpression cancelado · SEC-1 adjudicado YA implementado (assertCssVariableValue desde 2026-05-11) + pin del path de VALOR. - accordion → outline (§32; su outline:none dejaba CERO anillo en HCM) — verificado en vivo · THM-6 radius-full 9999px · EID-4 recuentos 33. F3 — censos con guard: - SOM-3 cerrado: announcer + image-provider migrados a scheduler-preferred (consumidores cableados: date/time-field vía soma.uix.timers; avatar/image vía eidos.timers — verificado en vivo); guard de timers ENSANCHADO de soma/components a TODO soma y pasado a EVIDENCIA (setTimeout exige .schedule( en el fichero — layers/ y datetime/ escapaban del ámbito viejo). - THM-5: R-4.7 nueva (válvula same-line /* important: <razón> */, escaneo comment-blanked) + las 15 declaraciones anotadas con su razón + canon recipe-contract §3/§4. - SOM-4 adjudicado: el censo/guard YA existían (49 pins); knob/mask-field/ timeline pinneados (overrides documentados en call-site); media-player Batch-4 (35 hits, cero renderProps) = único batch restante, registrado. - THM-4 doctrinado en eidos.md §unused (comportamiento/composición = legítimo; deuda = eje visual sin consumidor; hotspots por lotes). F4-C — corpus documental (decisiones de usuario aplicadas): - DOC-3: los 15 enlaces muertos resueltos (repoint a la edición FINAL trackeada / des-link históricos) · docs:check I6-links WARN→ERROR. - DOC-1: tabla «Build contract» MIGRADA a component-guide con estados modernizados (A3–A5 → LIVE + guards de hoy); banners reapuntados; citas de CANON/sema.md historificadas; lápida-redirect en el §13 del fósil. - DOC-4: hold chain → holds.ts · FAQ event:* SUPERSEDED por signatures · gradient añadido a los DOS capstones (sextet real) · nota de paleta de demo-authoring corregida (universalPaletteDecls + decisión THM-2 = mecanismo universal como sucesor del tracker borrado). - DOC-5/6: recuentos anti-frágiles datados · §4.11 dup → §4.12 · Known gaps historificado · N-6/N-7 recuperadas de git (d68d2c45^) y canonizadas en eidos.md §pickers · authoring E2 → canon/tsc.md · air-old des-linkado · EID-3 (placement) en la fila RTL · AUX-2 disabledDom documentado. SEM-4 sesión 1 — el close polimórfico de los pickers, VIVO (D.11): - Reconciliación: los morfos ya no declaran close (delegated al Popover, de-dialoged 06-27); el agujero real era el cierre programático bypaseando dismissWith → save/cancel/select eran perceptualmente SILENCIOSOS. - Fix: PickerShellHandle.setPopoverDismiss + closeWith(cause) en los 5 providers (14 sitios; select/commit → 'save' = commit.save+fulfill, cancel → 'cancel' = emerge; fallback raw para headless) + UN inyector en el eidos PickerShell root (norma N-8). Picker genérico fuera a propósito (ya suena commit-set/cancel por diseño S9). - Verificado en vivo (date-picker): Done → close·commit·fulfill·active · Cancel → close·emerge · cierre real. Gates: matriz 141/141 (los 6 morfos nuevos de la pista de texto paralela también PASS) · contracts 38/38 · eidos 314 · sema 178 · morfo 94 · docs:check 0/0 con I6 en error · baseline propio 57. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
(`{ color?, type?, depth?, shape?, space?, gradient? }`) composes the six
axes in **one managed write** (vs six loose `apply*`), **atomically**: the
axes you pass are applied, the ones you omit revert to the authored
foundation. `clearTheme()` reverts everything. For surgical per-axis tweaks,
the individual `apply*` remain. No reference system gathers the six
perceptual axes under a single runtime theme builder.
## 6. Position vs the references
No reference system gathers the channels under **one semantic model**.
Material has shape morph + motion (ad-hoc, without integrated
sound/haptics); Apple, continuity + materials (platform-bound); everyone,
color. **UIX gathers them** — the visual channel (sema → eidos) + sound +
haptic (sema) — over the two-moment model, fired from one event, with
runtime builders and an open registry. That is the framework, not the sum of
its parts.
## 7. Demo
`/temas/orquesta` — the mixer: press a control and mute each facet to hear
its part. The **visual channel's** 4 facets materialize with eidos tokens
(toggleable so each can be muted one by one); **sound + haptic** are fired by
the real sema engine (`EngineSemantic.emit`, filtered channels). One event,
sema's channels.

Powered by TurnKey Linux.