diff --git a/CLAUDE.md b/CLAUDE.md index afb371b87..2ef38a783 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -93,7 +93,7 @@ resolve and the server-test project). | Alias | Target | | --- | --- | | `@` | `src/` | -| `$active-app`, `$adom`, `$auth`, `$bus`, `$cache`, `$clipboard`, `$color`, `$connection`, `$format`, `$http`, `$langs`, `$logger`, `$motion`, `$orca`, `$perm`, `$prefs`, `$session`, `$sium`, `$storage`, `$timer` | `src/arts/{name}` | +| `$active-app`, `$adom`, `$auth`, `$bus`, `$cache`, `$clipboard`, `$color`, `$connection`, `$format`, `$http`, `$langs`, `$logger`, `$motion`, `$orca`, `$perf`, `$perm`, `$prefs`, `$session`, `$sium`, `$storage`, `$timer` | `src/arts/{name}` | | `$libs`, `$locale`, `$reactive` | `src/libs`, `src/libs/locale`, `src/libs/reactive` | | `$svrs` | `src/svrs/` | | `$uix`, `$active-uix`, `$soma` | `src/uix`, `src/uix/active-uix`, `src/uix/soma` | @@ -112,7 +112,7 @@ consume. Each consumer reads the morfo via `compileMorfo(morfo)`, never by walking the raw declaration. ``` -arts/ → runtime artifacts: active-app, adom, motion, perm, prefs, ... +arts/ → runtime artifacts: active-app, adom, color, motion, perf, perm, prefs, ... libs/ → pure helpers (zero-dep): reactive, days, dom, locale, ... svrs/ → server-authoritative engines diff --git a/src/arts/README.md b/src/arts/README.md index 5f588ebef..91559f8df 100644 --- a/src/arts/README.md +++ b/src/arts/README.md @@ -114,7 +114,7 @@ errors are typed. | [`logger`](./logger/README.md) | `EngineLogger` | Structured logger: levels, transports, filters, vitals, dispose | — | | [`timer`](./timer/README.md) | `EngineTimers`, `ActiveTimers` | Deterministic timer scheduler: clock injection, one-shots, intervals, cancellation, snapshots, backoff | `$libs/timers`, `$logger` (optional) | | [`format`](./format/README.md) | `EngineFormat`, `ActiveFormat` | Localized formatting: numbers, currency, units, dates | `$logger` (currency) | -| [`adom`](./adom/README.md) | `ActiveDom` | Reactive DOM service: viewport, breakpoints, attribute writes, scroll lock | `$libs/dom`, `$reactive` | +| [`adom`](./adom/README.md) | `ActiveDom` | Reactive DOM service: viewport, breakpoints, attribute writes, scroll lock, post-layout read scheduling (`measure`) | `$libs/dom`, `$reactive` | | [`motion`](./motion/README.md) | `EngineMotion` | Animation runtime: registers + runs `--state` presets (CSS settle / JS drivers — spring / waapi / rect FLIP); the bridge BOTH UIX layers consume via `uix.motion` | `MotionDom` port (injected; `adom` satisfies it) | | [`clipboard`](./clipboard/README.md) | `ActiveClipboard` | Clipboard write capability with injectable writer and explicit unavailable errors | browser `navigator.clipboard` or injected writer | | [`sium`](./sium/README.md) | `EngineSium` | Validation contracts: schemas, issues, introspection, Standard Schema interop | `$langs` (optional), `$logger` (optional), `$libs/days`, `$libs/color` | @@ -125,6 +125,8 @@ errors are typed. | [`auth`](./auth/README.md) | `ActiveAuth` (`EngineAuth` in `$svrs/auth`) | Authentication: password flows, CSRF, current session reflector, devices, logout, server-authoritative auth handlers | `$libs/auth`, `$http`, `$cache`, `$svrs/auth` | | [`perm`](./perm/README.md) | `ActivePerms` (`EnginePerms` in `$svrs/perm`) | Authorization: policy runtime adapter, HTTP client/handlers, cache snapshot, `` guard | `$libs/perm`, `$libs/svrs`, `$http`, `$logger` (optional) | | [`cache`](./cache/README.md) | `ActiveCache` (`EngineCache` in `$svrs/cache`) | Data cache: deterministic keys, policies, scopes, stale/revalidate, tags, memory/storage adapters | `$libs/cache`, `$storage` (adapter), `$logger` (optional) | +| [`color`](./color/README.md) | `$color` namespace (`uix.color`) | Isomorphic colour math: OKLCH↔sRGB, APCA, scale/scheme generation, alpha. Pure + stateless — `Engine`-grade, no class | — (zero-dep; consumed by eidos at build + runtime) | +| [`perf`](./perf/README.md) | `ActivePerf` (`uix.perf`) | Dev forced-reflow detector: Long Animation Frames → attributed `forcedStyleAndLayoutDuration` reports; opt-in, inert in prod | platform LoAF API (Chromium) — zero-dep | | [`active-app`](./active-app/README.md) | `ActiveApp` | App composition: core Logger + Bus + Timers + Orca + Prefs, plus declared services via factories | every artifact above | ## Composition @@ -240,12 +242,14 @@ alias: { $auth: 'src/arts/auth', $cache: 'src/arts/cache', $clipboard: 'src/arts/clipboard', + $color: 'src/arts/color', $connection: 'src/arts/connection', $format: 'src/arts/format', $http: 'src/arts/http', $langs: 'src/arts/langs', $logger: 'src/arts/logger', $motion: 'src/arts/motion', + $perf: 'src/arts/perf', $perm: 'src/arts/perm', $session: 'src/arts/session', $sium: 'src/arts/sium', diff --git a/src/uix/active_architecture.md b/src/uix/active_architecture.md index 12fa29dbf..501fa97e5 100644 --- a/src/uix/active_architecture.md +++ b/src/uix/active_architecture.md @@ -691,6 +691,19 @@ Las invariantes operativas que mantienen el sistema coherente: `document/window`, consultas globales, foco imperativo y scroll de ventana pasan por `ActiveDom`. + **Timing, no solo ownership.** Esas lecturas que fuerzan layout + (`getBoundingClientRect`, `getComputedStyle`, `offset*`, `scroll*`, `client*`) + deben correr POST-LAYOUT, nunca síncronas justo tras una escritura de + DOM/estilo — leer-tras-escribir fuerza un reflow a mitad de turno (la familia + `[Violation] Forced reflow while executing JavaScript`). Difiérelas con + `dom.measure(read, node?)` (cola de lecturas coalescida por frame, el vehículo + sancionado) o desde un callback `dom.raf`; un `measure` pelado cumple igual + que `dom.apply` para las escrituras. Para resolver un token de tema a un color + concreto, usa `eidos.resolveToken(token)` (config + el motor `uix.color`) — NO + un probe `getComputedStyle`. El detector dev `uix.perf` (opt-in `reflowDetector`) + atribuye las violaciones en runtime vía Long Animation Frames. Así el framework + gobierna las LECTURAS de layout igual que `dom.apply` gobierna las escrituras. + 6. **`Eidos` consume DOM y `data-*`, no internals de Soma ni Sema.** Si lo necesita, debe estar declarado en morfo o emitido en una señal de sema. diff --git a/src/uix/eidos/COLOR_ENGINE_RFC.md b/src/uix/eidos/COLOR_ENGINE_RFC.md index b9735cf9b..de442416d 100644 --- a/src/uix/eidos/COLOR_ENGINE_RFC.md +++ b/src/uix/eidos/COLOR_ENGINE_RFC.md @@ -275,6 +275,13 @@ un *art* isomórfico (paralelo a `uix.motion`): servicio puro que consumen el bu (`render-css`) y el runtime (`ActiveEidos`). Esto absorbe el sueño white-label / live del documento de bloat **sin** la regresión de CSS-relative-colors. +**Estado 2026-06-29 — realizado.** `uix.color` existe como accessor *stateless* en +`ActiveUix` (tipo `EngineColor` — sin estado, por eso `Engine*` y no `Active*`), +descubrible junto a `uix.motion` / `uix.timers`; `eidos` sigue importando `$color` +directo para build/SSR. El consumidor recíproco —resolver un token de tema a un +color concreto en JS, sin probe `getComputedStyle`— es `eidos.resolveToken(token)` +(config + `$color`). + > **Frontera CSS-nativa (watch, no solución).** `contrast-color()` (CSS Color 5) > haría el pick de contraste en CSS puro algún día — pero no está listo (prototipo > Safari 18, nada en Chrome/Firefox en 2026), solo elige blanco/negro puro (no tus diff --git a/src/uix/eidos/README.md b/src/uix/eidos/README.md index e470f18d9..80569ce5a 100644 --- a/src/uix/eidos/README.md +++ b/src/uix/eidos/README.md @@ -65,6 +65,13 @@ Eidos tiene una clase activa: `prefs`, `dom`, `langs`, `format` y helpers visuales como `resolve(...)`, `breakpoint(...)` o `isBelow(...)`. Si `applyDom` esta activo, inyecta/quita `