10 KiB
CONTINUE — eje Background (handoff, act. 2026-08-18)
Estado: F0 → F5 CERRADAS Y COMMITEADAS. El componente existe, tiene demo,
está documentado y el tier lo usa. Cuatro commits en alpha-0.1-background:
| Commit | Qué cerró |
|---|---|
70f45033f |
F1 — la pila y la adopción del anfitrión (+ F1.5, con el bug de Box flex) |
33031c2ad |
F2 — Image · Video · Pause, y el hero se queda sin CSS |
740274a84 |
F3 + F3.5 + F4 — parallax, puntero, attach, la demo v2 y el registro documental |
331912cf2 |
F5 — rollout a los seis blocks |
La verificación con Chrome visible está HECHA (2026-08-18, §1 abajo): travel
real, 60 fps y 0 reflows, con dos defectos encontrados y arreglados — el
overflow: hidden del stage que congelaba la timeline, y el rect cacheado del
puntero que se desviaba con el scroll. Sin commitear todavía.
Por dónde entrar mañana: §Qué queda. El eje está CERRADO:
tus cuatro firmas ejecutadas, la verificación en navegador completa (incluida la
rama @supports not) y backdrop/ borrado. Lo único vivo son dos tareas de
otros ejes — y son de esos ejes, no de éste.
⚠️ LO PRIMERO: la fuente viva es el PLAN, no este fichero
docs/process/PLAN-background.md — decisiones firmadas D-BG.1…D-BG.18 en
§6, y el registro de ejecución fase por fase en §7.bis…§7.terdecies, cada uno con
sus mediciones. Este handoff indexa; el plan manda.
Qué queda
1. ✅ HECHA con Chrome visible (2026-08-18) — y destapó dos defectos, ya arreglados
Registro completo en PLAN-background.md §7.nonies. Resumen:
- travel real ✓ progreso 43,5%→95,5%,
translate−8,34px→+58,19px, hasta0px 64px=4remen el extremo (los keyframes van −travel→+travel, así que la amplitud pico a pico es el doble del token); - 60 fps ✓ mediana 16,7ms · p95 17,0 · max 17,1 · 0 de 200 frames >20ms;
- detector de reflow ✓ 0ms forzados en 200 frames moviendo LOS DOS ejes, con el instrumento validado por mutación (un thrash de 65ms sí se reporta);
@supports not✅ ejercitada (§7.decies) en el Firefox de Playwright, que NO soportaview()— la rama está viva ahí sin emulación: progress 0→−64px, 0,5→0, 1→+64px, los mismos extremos que el camino CSS, y en Chromium la rama no aplica ni la var mueve nada (exclusión mutua, medida). Queda sin ejercitar UN eslabón: queScrollProgressescriba la var extremo a extremo, porque desde este entorno Firefox no alcanza el dev server.
Los dos defectos que salieron, ambos arreglados y verificados:
- Un ancestro
overflow: hiddenmata el travel en silencio —view()se ancla al scroll container más cercano yhiddenlo es aunque no scrollee. La demo lo sufría ([data-uix-stage]), progreso clavado en 52,63%. Arreglado conoverflow: clipen el stage + quinto límite en el README del componente, porque el caso real es eloverflow-x: hiddende cualquier landing. Las 174 demos que comparten el stage:affixystickyidénticos,anchor-navcambia a mejor (su rail sticky ya no se escapa por arriba). - El eje del puntero se desviaba exactamente lo scrolleado — rect cacheado
en coordenadas de viewport, invalidado sólo por
pointerenter/resize. Arreglado cacheando en coordenadas de DOCUMENTO contrapageX/pageY; error 0 con ratón real, halo del spotlight a 1px del cursor. ⚠️ UnPointerEventsintético NO puede verificarlo (pageY === clientYen eventos construidos).
Lo que ya estaba medido antes: la composición de los dos ejes en un translate
(parallax solo 0px 30px; con puntero y depth: 20px → 20px 10px — ratificado
por la aritmética de ahora), el puntero entero, attach='fixed', y RTL.
1.bis ✅ Cierre ejecutado (2026-08-18) — §7.decies
- Escala del scrim ORDENADA:
strengthpasa descrim|overlay|muted|subtle|ghostaxs|sm|md|lg|xlcon tokens propios; α 0,084…0,420 estrictamente creciente,mdconserva el 0,45 del hero. Cambio de API hecho con la demo como único consumidor. - La tabla de contraste del README estaba MAL (asumía tinta α 0,66; es 0,42): el default da 1,48:1 sobre foto blanca, no 2,10, y el techo es 2,66:1. Re-medida por píxel.
feature-split: banda por SECCIÓN, enmendado en el plan (×3) y enPLAN-blocks-quality§3 col. B.- Paseo A–H registrado: añadidas al README la excepción
A2.3y la sección## Subset; corregida una deriva de TRES sitios que llamabaToggleal control de pausa (componeIconButton, eventocontact-activate). - D-BG.19 · un fondo NUNCA suena (§7.undecies, firmada por el autor):
muteddeja de ser prop y se escribetruesiempre, así que la API no puede expresar un fondo audible. No estaba resuelto, estaba evitado: conmuted={false}el clip sonaba FUERA dearts/sound— ni buscontent, ni audio focus, ni duck del busui, ni MediaSession, ni el slotsoundde$prefs. Un clip que debe oírse es contenido:MediaPlayer, que ya es ciudadano desound.media().
1.ter ✅ D-BG.20 — la tinta del scrim (2026-08-18, §7.duodecies)
Firmada tras leer la doctrina entera, que corrigió mi propia recomendación. El
velo ya no toma prestado --color-overlay (= surface.backdrop, el dim modal,
afinado por MODO): su tinta es el SUELO de la tinta que on puso en vigor
(D12) — #1c1917 bajo on="dark", blanco bajo on="light", la superficie de
la página sin on. Tres roles existentes, ninguno inventado.
- Arregla un defecto que no había visto: con
on="light"el velo era OSCURO bajo tinta oscura — combatía a su propia tinta. - Quita el techo: con tinta opaca el peso ES el alpha, y
xl(0,70) promete legibilidad sobre cualquier foto contra los cuatro suelos del framework (APCA ≥ 60 ∧ WCAG ≥ 3 deon-solid.ts, y AA 4,5 de §40) en ambos contextos: 6,45:1 / Lc 85 y 8,29:1 / Lc 61. Medido con$color, confirmado por píxel. - Escala:
xs0,08 ·sm0,13 ·md0,19 ·lg0,40 ·xl0,70. - Paridad exacta en el consumidor: el hero en layout
backgroundsigue dando 1,48 / 5,17. Los heroes en modo oscuro se aclaran (0,297 → 0,19), que es lo correcto: el modo no debía tocar la legibilidad. - ⚠️ El selector de contexto va en
:where(): a pelo llegaba a (0,4,0) y ganaba a[data-color], derrotando el sistema de color abierto (§25).
2. ✅ Tus cuatro firmas, TODAS ejecutadas
- La escala del scrim — ordenada, con tokens propios (§7.decies).
- El techo de contraste — resuelto de raíz en D-BG.20 (§7.duodecies): cambiando la TINTA, no subiendo un número.
- La banda de
feature-split— por sección, enmendada en el plan (×3) y enPLAN-blocks-quality§3 col. B. - Borrar
backdrop/— hecho el 2026-08-18 con tu orden explícita (§7.terdecies): cinco ficheros (el componente y su morfo), cero consumidores,git rm. Los gates lo confirman por aritmética:morfo:checkpasa de 168 a 167 morfos y de 8 a 7 saltados sin demo. Las CITAS se conservan: la §Baseline del README sigue nombrando aBackdrop, ahora fechada, porque explica por qué el componente se llamaBackground.
3. Tareas de otros ejes que este abrió
Ambienthonrando la pausa (D-BG.8): el canon publica el contexto (paused,reduced,seen); el pack lo lee y llamahandle.pause(). Es tarea DEL PACK — la dependencia corre pack → framework y nunca al revés.- Un puerto de estado para
<video>compartido: el framework tiene contrato de carga para<img>(ImageProviderensoma/layers) y ninguno para vídeo. HoyScrollFramesescucha a mano yBackground.Videotambién. Dos consumidores es el umbral que este repo usa para extraer una capa. (Anotado ennext-features.md§11.) - Los huecos
Display/Linkbajodata-onsiguen siendo candidatos de canon aparte, como los dejó el hero.
Lo que este eje enseñó, y conviene no volver a aprender
- A30 no es estilo, es supervivencia. Registrarse con el padre desde un
$effectescribe su estado en fase de efectos, el hermano que lo lee re-entra y el flush no cierra:effect_update_depth_exceeded. No hace ruido — mata el efecto raíz, así que la superficie se pinta una vez y luego ignora todos los clics en silencio. La ley vive endeclare.svelte.tscon sus dos mitades (registrar desde el init, y seguir el prop sin escribir en la primera pasada). revert-layersin@layeresrevert. Costó dos defectos distintos: la regla de anfitrión que no posicionaba (D-BG.16) y elflexdeBoxque no crecía. Cuando una declaración «no hace nada», mira si un shorthand vecino la borró.- La demo destapa lo que una sonda no. El registro de «esta capa se mueve»
era un hecho de montaje: encender
animateen caliente no hacía aparecer el control de pausa. Invisible en una sonda, obvio con un interruptor. - Mide antes de afirmar rendimiento. Escribí tres veces que el travel «va en el compositor»; animar una custom property registrada no se puede compositar. Lo cierto era «sin listener ni rAF», que es otra cosa.
- La decoración que parece mejor puede ser la ilegible. Dentro del panel
sólido del
cta, elglowhunde el titular blanco de 5,18:1 a 3,06:1.
Mapa de ficheros
| Qué | Dónde |
|---|---|
| Plan + decisiones firmadas | docs/process/PLAN-background.md |
| El componente | src/uix/eidos/components/background/ (README con todas las mediciones) |
| El morfo | src/uix/morfo/components/background.ts |
| Los dos puertos que abrió | src/arts/adom/scroll-progress.svelte.ts · reduced-data.svelte.ts |
| La regla de anfitrión | src/uix/eidos/lib/render-css.ts → renderBackgroundHostBlock |
| La demo | web/routes/uix/components/background/+page.svelte |
| Ledger del tier | docs/process/AUDIT-blocks-ledger.md — filas A-100…A-105 |