|
|
|
|
|
# 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 |
|
|
|
|
|
|
|
uix(background): la línea de tiempo la capturaba un overflow, y el puntero se iba con el scroll
El travel llevaba dos días escrito y sin medir, porque el panel oculto nunca
activa una animación scroll-driven declarada en CSS. Con el Chrome del autor
delante se pudo medir, y lo que apareció no fue una confirmación: fueron dos
defectos que ninguna sonda había estado en posición de ver. La puerta es
`document.visibilityState` — con la pestaña oculta la `ViewTimeline` existe, con
`source` y `subject` correctos y `playState: 'running'`, y `currentTime` es
`null` para siempre; ahí ni un `await requestAnimationFrame` resuelve.
El primero estaba en la demo y el límite es del componente. `[data-uix-stage]`
declaraba `overflow: hidden`, y eso es un scroll container aunque no pueda
scrollear nunca: `view()` se ancló al stage y el progreso quedó clavado en 52,63%
en toda posición de scroll, sin error, sin aviso y con un `translate` de aspecto
perfectamente razonable. Con `overflow: clip` —recorta igual, respeta el radio, y
no es scroll container— el travel aparece: progreso 43,5% → 95,5%, `translate`
`0px -8,34px` → `0px 58,19px`, monótono, y los `4rem` completos de
`--background-parallax-travel` en el extremo. Entra en el README como quinto
límite porque el caso real no es un harness de demos: es el `overflow-x: hidden`
con el que cualquier landing contiene su decoración, que convierte al elemento en
scroll container en los DOS ejes.
El segundo era del componente. El rect del anfitrión se cacheaba en coordenadas
de viewport y sólo lo invalidaban `pointerenter` y un resize; el scroll mueve el
anfitrión sin disparar ninguno de los dos. Medido con ratón real: un tick de
rueda sobre un anfitrión de 288px dejaba `--background-pointer-y` 0,77 fuera de
sitio —los 111px de scroll sobre media altura, a la centésima—, o sea fuera del
rango −1…1 que la variable promete, con el spotlight despegado del cursor unos
115px y sin recuperarse hasta salir y volver a entrar. Cacheada la caja en
coordenadas de DOCUMENTO y normalizando contra `pageX`/`pageY`, que en un evento
real ya traen el scroll incorporado: error 0 en los dos movimientos, halo a 1px
del píxel pedido, sin lectura de layout en el camino caliente y sin el listener
de scroll que este componente existe para no tener. Queda dicho el residuo: un
scroller anidado vuelve a desviar, porque `pageY` no lo ve, y se autocura al
reentrar.
Y lo que era el encargo, medido: 60 fps con mediana de 16,7ms, p95 17,0, máximo
17,1 y 0 de 200 frames por encima de 20ms con el travel vivo —la base con
`speed: 0` salió peor, que es ruido de entorno—; y 0ms de reflow forzado en esos
mismos 200 frames moviendo los DOS ejes, con el observador de Long Animation
Frames que usa `arts/perf`. El cero está validado por mutación: un thrash
deliberado de 65ms en la misma página se reporta con 43ms forzados y el script
atribuido, porque un instrumento que no ve nada y un cero real se leen igual.
Sigue pendiente la rama `@supports not`, que sólo se ejercita en Firefox.
Las 174 demos comparten ese stage, así que el cambio se auditó: `affix` idéntico
y `sticky` idéntico —cuatro pasadas alternando `clip` y `hidden`, porque la
primera miente—, y `anchor-nav` cambia a mejor: su rail `position: sticky` es
hermano del scroller interno, con `hidden` no se pegaba nunca y se escapaba por
arriba perdiendo media lista, y ahora se mantiene a la vista. Ninguna demo tocada.
Dos avisos para quien vuelva. Un `PointerEvent` construido reporta
`pageY === clientY`, sin sumar el scroll, así que los eventos sintéticos sirven
para DESCUBRIR este defecto pero no para verificarlo: con ellos el arreglo bueno
mide −1,389 donde el ratón real da −0,008. Y leer las variables después de un
screenshot puede devolver el `write(0, 0)` de un `pointerleave` en vez de la
medición; el valor que vale es el del último `pointermove`, trazado.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
**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](#qué-queda).** Nada bloquea el uso del
|
uix(background): el velo tenía una escala que no ordenaba, y una tinta que le pone techo
Cierra el eje salvo dos firmas. La escala `strength` dejaba de crecer a mitad de
camino: tomaba prestada `--opacity-*`, que nombra cuán opaco es un ELEMENTO, y
leída como pesos de velo salía `ghost` 0,30 · `scrim` 0,45 · `overlay` 0,65 ·
`muted` 0,65 · `subtle` 0,80 — es decir, un consumidor que pedía `subtle` recibía
el velo MÁS pesado del conjunto, y `overlay` y `muted` eran el mismo número con
dos nombres. Ahora el velo tiene su propia escala de cinco pasos
(`--background-scrim-strength-xs`…`-xl`) y la unión pasa a `xs|sm|md|lg|xl`,
ordenada por construcción: medido en Chrome, α 0,084 · 0,126 · 0,189 · 0,273 ·
0,420, estrictamente creciente. `md` sostiene el 0,45 que shipeó el hero, así que
el default pinta exactamente lo que pintaba. Era cambio de API y se hizo mientras
el único consumidor era la demo: ningún block nombra `strength`.
Y midiendo eso apareció que la tabla de contraste del README era falsa por la
mitad, en la dirección incómoda. Estaba calculada sobre una tinta de α 0,66;
`--color-overlay` resuelve a `rgba(28, 25, 23, 0.42)`. Los valores reales, ahora
compuestos en un canvas y leídos por píxel en vez de calculados: el default da
1,48:1 sobre foto blanca —no 2,10— y el paso más fuerte 2,14 —no 4,42—. Lo que
eso destapa no es un número peor sino un TECHO: `xl` gasta la tinta entera y
llega a 2,66:1, de modo que ningún paso nuevo puede alcanzar AA, porque el límite
es el alpha del token y no la escala. Con tinta opaca los mismos pesos dan 5,45:1
a 0,65 y 9,22:1 a 0,80. Queda como decisión del autor, reescrita con estas
cifras, porque es sobre qué ES un scrim y no sobre subir un valor.
La rama `@supports not (animation-timeline: view())` queda ejercitada, que era el
último hueco de verificación. Chromium ya no puede desactivar scroll-driven
—estable, flag de runtime retirado: seis candidatos probados, los seis siguen
reportando soporte—, pero el Firefox de Playwright NO lo soporta por sí mismo, así
que la rama está viva ahí sin emulación ninguna. Con el fichero de receta real:
`--background-progress` 0 → −64px, 0,5 → 0, 1 → +64px, con `animation-name: none`
y cero animaciones. Son los mismos extremos que el camino CSS medido en Chrome, o
sea que los dos caminos concuerdan; y en Chromium la rama no aplica y escribir la
var no mueve nada, que es la exclusión mutua que el README afirmaba sin haberla
medido. Sin ejercitar queda un eslabón —que `ScrollProgress` escriba la var
extremo a extremo—: desde el shell de este entorno no hay ruta a localhost, y
Firefox no alcanza el dev server.
El paseo de la checklist A–H, que estaba listado como lectura de F4 y nunca
registrado, encontró tres cosas. Faltaba la excepción `A2.3` con su ID (las tres
partes llevan `data: []` porque sus attrs son de wrapper y su único estado vive en
el Button que compone) y faltaba `## Subset` (color: el conjunto completo, porque
en decoración restringir la paleta sería arbitrario; intent: no se acepta). Y una
deriva documental: el README decía en TRES sitios que el control de pausa «IS the
canonical Toggle» y que dispara `commit-toggle`, cuando D-BG.18 lo cambió a
`IconButton` con etiqueta que cambia y sin `aria-pressed` — el evento es
`contact-activate` de `button.ts`. Vestigios de la era D-BG.4 que la enmienda no
barrió; corregidos, incluido el comentario del propio morfo.
La banda de `feature-split` queda firmada POR SECCIÓN, enmendando el plan en sus
tres menciones y `PLAN-blocks-quality` §3 columna B, que la pedía por fila: por
fila obliga a cada `Row` a poseer el estado de alternancia —su índice y el de sus
hermanas— y un block que coordina deja de ser un block que no posee nada.
Gates: audit PASS 0/0 · morfo:check (6 de 160 fallan, background no) · eidos-lint
invalid 0 y class-hooks 0 · rtl:check 0/180 · smoke del componente PASS · vitest
eidos 434/435 (el rojo es `skin-media-player`, el de siempre) · `check` con los
mismos 72 errores preexistentes y ninguno en ficheros propios.
Tres fantasmas costaron tiempo y son el mismo patrón: leer las vars tras un
screenshot devuelve el `write(0,0)` de un `pointerleave`; dar por muerto el
`strength` leyendo `backgroundColor` de un scrim GRADUADO, que pinta por
`background-image`; y juzgar `fade` y `pause` sin la precondición que necesitan.
El instrumento miente antes que el código, y aquí mintió tres veces.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
componente. Lo que queda son **DOS firmas tuyas** (borrar `backdrop/` · qué hacer
|
|
|
|
|
|
con el techo de contraste del scrim) y **dos tareas de otros ejes**. La
|
|
|
|
|
|
verificación en navegador está cerrada, incluida la rama `@supports not`.
|
|
|
|
|
|
|
|
|
|
|
|
## ⚠️ 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
|
uix(background): el velo tenía una escala que no ordenaba, y una tinta que le pone techo
Cierra el eje salvo dos firmas. La escala `strength` dejaba de crecer a mitad de
camino: tomaba prestada `--opacity-*`, que nombra cuán opaco es un ELEMENTO, y
leída como pesos de velo salía `ghost` 0,30 · `scrim` 0,45 · `overlay` 0,65 ·
`muted` 0,65 · `subtle` 0,80 — es decir, un consumidor que pedía `subtle` recibía
el velo MÁS pesado del conjunto, y `overlay` y `muted` eran el mismo número con
dos nombres. Ahora el velo tiene su propia escala de cinco pasos
(`--background-scrim-strength-xs`…`-xl`) y la unión pasa a `xs|sm|md|lg|xl`,
ordenada por construcción: medido en Chrome, α 0,084 · 0,126 · 0,189 · 0,273 ·
0,420, estrictamente creciente. `md` sostiene el 0,45 que shipeó el hero, así que
el default pinta exactamente lo que pintaba. Era cambio de API y se hizo mientras
el único consumidor era la demo: ningún block nombra `strength`.
Y midiendo eso apareció que la tabla de contraste del README era falsa por la
mitad, en la dirección incómoda. Estaba calculada sobre una tinta de α 0,66;
`--color-overlay` resuelve a `rgba(28, 25, 23, 0.42)`. Los valores reales, ahora
compuestos en un canvas y leídos por píxel en vez de calculados: el default da
1,48:1 sobre foto blanca —no 2,10— y el paso más fuerte 2,14 —no 4,42—. Lo que
eso destapa no es un número peor sino un TECHO: `xl` gasta la tinta entera y
llega a 2,66:1, de modo que ningún paso nuevo puede alcanzar AA, porque el límite
es el alpha del token y no la escala. Con tinta opaca los mismos pesos dan 5,45:1
a 0,65 y 9,22:1 a 0,80. Queda como decisión del autor, reescrita con estas
cifras, porque es sobre qué ES un scrim y no sobre subir un valor.
La rama `@supports not (animation-timeline: view())` queda ejercitada, que era el
último hueco de verificación. Chromium ya no puede desactivar scroll-driven
—estable, flag de runtime retirado: seis candidatos probados, los seis siguen
reportando soporte—, pero el Firefox de Playwright NO lo soporta por sí mismo, así
que la rama está viva ahí sin emulación ninguna. Con el fichero de receta real:
`--background-progress` 0 → −64px, 0,5 → 0, 1 → +64px, con `animation-name: none`
y cero animaciones. Son los mismos extremos que el camino CSS medido en Chrome, o
sea que los dos caminos concuerdan; y en Chromium la rama no aplica y escribir la
var no mueve nada, que es la exclusión mutua que el README afirmaba sin haberla
medido. Sin ejercitar queda un eslabón —que `ScrollProgress` escriba la var
extremo a extremo—: desde el shell de este entorno no hay ruta a localhost, y
Firefox no alcanza el dev server.
El paseo de la checklist A–H, que estaba listado como lectura de F4 y nunca
registrado, encontró tres cosas. Faltaba la excepción `A2.3` con su ID (las tres
partes llevan `data: []` porque sus attrs son de wrapper y su único estado vive en
el Button que compone) y faltaba `## Subset` (color: el conjunto completo, porque
en decoración restringir la paleta sería arbitrario; intent: no se acepta). Y una
deriva documental: el README decía en TRES sitios que el control de pausa «IS the
canonical Toggle» y que dispara `commit-toggle`, cuando D-BG.18 lo cambió a
`IconButton` con etiqueta que cambia y sin `aria-pressed` — el evento es
`contact-activate` de `button.ts`. Vestigios de la era D-BG.4 que la enmienda no
barrió; corregidos, incluido el comentario del propio morfo.
La banda de `feature-split` queda firmada POR SECCIÓN, enmendando el plan en sus
tres menciones y `PLAN-blocks-quality` §3 columna B, que la pedía por fila: por
fila obliga a cada `Row` a poseer el estado de alternancia —su índice y el de sus
hermanas— y un block que coordina deja de ser un block que no posee nada.
Gates: audit PASS 0/0 · morfo:check (6 de 160 fallan, background no) · eidos-lint
invalid 0 y class-hooks 0 · rtl:check 0/180 · smoke del componente PASS · vitest
eidos 434/435 (el rojo es `skin-media-player`, el de siempre) · `check` con los
mismos 72 errores preexistentes y ninguno en ficheros propios.
Tres fantasmas costaron tiempo y son el mismo patrón: leer las vars tras un
screenshot devuelve el `write(0,0)` de un `pointerleave`; dar por muerto el
`strength` leyendo `backgroundColor` de un scrim GRADUADO, que pinta por
`background-image`; y juzgar `fade` y `pause` sin la precondición que necesitan.
El instrumento miente antes que el código, y aquí mintió tres veces.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
§6, y el registro de ejecución fase por fase en §7.bis…§7.decies, cada uno con
|
|
|
|
|
|
sus mediciones. Este handoff indexa; el plan manda.
|
|
|
|
|
|
|
|
|
|
|
|
## Qué queda
|
|
|
|
|
|
|
uix(background): la línea de tiempo la capturaba un overflow, y el puntero se iba con el scroll
El travel llevaba dos días escrito y sin medir, porque el panel oculto nunca
activa una animación scroll-driven declarada en CSS. Con el Chrome del autor
delante se pudo medir, y lo que apareció no fue una confirmación: fueron dos
defectos que ninguna sonda había estado en posición de ver. La puerta es
`document.visibilityState` — con la pestaña oculta la `ViewTimeline` existe, con
`source` y `subject` correctos y `playState: 'running'`, y `currentTime` es
`null` para siempre; ahí ni un `await requestAnimationFrame` resuelve.
El primero estaba en la demo y el límite es del componente. `[data-uix-stage]`
declaraba `overflow: hidden`, y eso es un scroll container aunque no pueda
scrollear nunca: `view()` se ancló al stage y el progreso quedó clavado en 52,63%
en toda posición de scroll, sin error, sin aviso y con un `translate` de aspecto
perfectamente razonable. Con `overflow: clip` —recorta igual, respeta el radio, y
no es scroll container— el travel aparece: progreso 43,5% → 95,5%, `translate`
`0px -8,34px` → `0px 58,19px`, monótono, y los `4rem` completos de
`--background-parallax-travel` en el extremo. Entra en el README como quinto
límite porque el caso real no es un harness de demos: es el `overflow-x: hidden`
con el que cualquier landing contiene su decoración, que convierte al elemento en
scroll container en los DOS ejes.
El segundo era del componente. El rect del anfitrión se cacheaba en coordenadas
de viewport y sólo lo invalidaban `pointerenter` y un resize; el scroll mueve el
anfitrión sin disparar ninguno de los dos. Medido con ratón real: un tick de
rueda sobre un anfitrión de 288px dejaba `--background-pointer-y` 0,77 fuera de
sitio —los 111px de scroll sobre media altura, a la centésima—, o sea fuera del
rango −1…1 que la variable promete, con el spotlight despegado del cursor unos
115px y sin recuperarse hasta salir y volver a entrar. Cacheada la caja en
coordenadas de DOCUMENTO y normalizando contra `pageX`/`pageY`, que en un evento
real ya traen el scroll incorporado: error 0 en los dos movimientos, halo a 1px
del píxel pedido, sin lectura de layout en el camino caliente y sin el listener
de scroll que este componente existe para no tener. Queda dicho el residuo: un
scroller anidado vuelve a desviar, porque `pageY` no lo ve, y se autocura al
reentrar.
Y lo que era el encargo, medido: 60 fps con mediana de 16,7ms, p95 17,0, máximo
17,1 y 0 de 200 frames por encima de 20ms con el travel vivo —la base con
`speed: 0` salió peor, que es ruido de entorno—; y 0ms de reflow forzado en esos
mismos 200 frames moviendo los DOS ejes, con el observador de Long Animation
Frames que usa `arts/perf`. El cero está validado por mutación: un thrash
deliberado de 65ms en la misma página se reporta con 43ms forzados y el script
atribuido, porque un instrumento que no ve nada y un cero real se leen igual.
Sigue pendiente la rama `@supports not`, que sólo se ejercita en Firefox.
Las 174 demos comparten ese stage, así que el cambio se auditó: `affix` idéntico
y `sticky` idéntico —cuatro pasadas alternando `clip` y `hidden`, porque la
primera miente—, y `anchor-nav` cambia a mejor: su rail `position: sticky` es
hermano del scroller interno, con `hidden` no se pegaba nunca y se escapaba por
arriba perdiendo media lista, y ahora se mantiene a la vista. Ninguna demo tocada.
Dos avisos para quien vuelva. Un `PointerEvent` construido reporta
`pageY === clientY`, sin sumar el scroll, así que los eventos sintéticos sirven
para DESCUBRIR este defecto pero no para verificarlo: con ellos el arreglo bueno
mide −1,389 donde el ratón real da −0,008. Y leer las variables después de un
screenshot puede devolver el `write(0, 0)` de un `pointerleave` en vez de la
medición; el valor que vale es el del último `pointermove`, trazado.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
### 1. ✅ HECHA con Chrome visible (2026-08-18) — y destapó dos defectos, ya arreglados
|
|
|
|
|
|
|
|
|
|
|
|
Registro completo en `PLAN-background.md` §7.nonies. Resumen:
|
|
|
|
|
|
|
uix(background): la línea de tiempo la capturaba un overflow, y el puntero se iba con el scroll
El travel llevaba dos días escrito y sin medir, porque el panel oculto nunca
activa una animación scroll-driven declarada en CSS. Con el Chrome del autor
delante se pudo medir, y lo que apareció no fue una confirmación: fueron dos
defectos que ninguna sonda había estado en posición de ver. La puerta es
`document.visibilityState` — con la pestaña oculta la `ViewTimeline` existe, con
`source` y `subject` correctos y `playState: 'running'`, y `currentTime` es
`null` para siempre; ahí ni un `await requestAnimationFrame` resuelve.
El primero estaba en la demo y el límite es del componente. `[data-uix-stage]`
declaraba `overflow: hidden`, y eso es un scroll container aunque no pueda
scrollear nunca: `view()` se ancló al stage y el progreso quedó clavado en 52,63%
en toda posición de scroll, sin error, sin aviso y con un `translate` de aspecto
perfectamente razonable. Con `overflow: clip` —recorta igual, respeta el radio, y
no es scroll container— el travel aparece: progreso 43,5% → 95,5%, `translate`
`0px -8,34px` → `0px 58,19px`, monótono, y los `4rem` completos de
`--background-parallax-travel` en el extremo. Entra en el README como quinto
límite porque el caso real no es un harness de demos: es el `overflow-x: hidden`
con el que cualquier landing contiene su decoración, que convierte al elemento en
scroll container en los DOS ejes.
El segundo era del componente. El rect del anfitrión se cacheaba en coordenadas
de viewport y sólo lo invalidaban `pointerenter` y un resize; el scroll mueve el
anfitrión sin disparar ninguno de los dos. Medido con ratón real: un tick de
rueda sobre un anfitrión de 288px dejaba `--background-pointer-y` 0,77 fuera de
sitio —los 111px de scroll sobre media altura, a la centésima—, o sea fuera del
rango −1…1 que la variable promete, con el spotlight despegado del cursor unos
115px y sin recuperarse hasta salir y volver a entrar. Cacheada la caja en
coordenadas de DOCUMENTO y normalizando contra `pageX`/`pageY`, que en un evento
real ya traen el scroll incorporado: error 0 en los dos movimientos, halo a 1px
del píxel pedido, sin lectura de layout en el camino caliente y sin el listener
de scroll que este componente existe para no tener. Queda dicho el residuo: un
scroller anidado vuelve a desviar, porque `pageY` no lo ve, y se autocura al
reentrar.
Y lo que era el encargo, medido: 60 fps con mediana de 16,7ms, p95 17,0, máximo
17,1 y 0 de 200 frames por encima de 20ms con el travel vivo —la base con
`speed: 0` salió peor, que es ruido de entorno—; y 0ms de reflow forzado en esos
mismos 200 frames moviendo los DOS ejes, con el observador de Long Animation
Frames que usa `arts/perf`. El cero está validado por mutación: un thrash
deliberado de 65ms en la misma página se reporta con 43ms forzados y el script
atribuido, porque un instrumento que no ve nada y un cero real se leen igual.
Sigue pendiente la rama `@supports not`, que sólo se ejercita en Firefox.
Las 174 demos comparten ese stage, así que el cambio se auditó: `affix` idéntico
y `sticky` idéntico —cuatro pasadas alternando `clip` y `hidden`, porque la
primera miente—, y `anchor-nav` cambia a mejor: su rail `position: sticky` es
hermano del scroller interno, con `hidden` no se pegaba nunca y se escapaba por
arriba perdiendo media lista, y ahora se mantiene a la vista. Ninguna demo tocada.
Dos avisos para quien vuelva. Un `PointerEvent` construido reporta
`pageY === clientY`, sin sumar el scroll, así que los eventos sintéticos sirven
para DESCUBRIR este defecto pero no para verificarlo: con ellos el arreglo bueno
mide −1,389 donde el ratón real da −0,008. Y leer las variables después de un
screenshot puede devolver el `write(0, 0)` de un `pointerleave` en vez de la
medición; el valor que vale es el del último `pointermove`, trazado.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
- **travel real** ✓ progreso 43,5%→95,5%, `translate` −8,34px→+58,19px, hasta
|
|
|
|
|
|
`0px 64px` = `4rem` en 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);
|
uix(background): el velo tenía una escala que no ordenaba, y una tinta que le pone techo
Cierra el eje salvo dos firmas. La escala `strength` dejaba de crecer a mitad de
camino: tomaba prestada `--opacity-*`, que nombra cuán opaco es un ELEMENTO, y
leída como pesos de velo salía `ghost` 0,30 · `scrim` 0,45 · `overlay` 0,65 ·
`muted` 0,65 · `subtle` 0,80 — es decir, un consumidor que pedía `subtle` recibía
el velo MÁS pesado del conjunto, y `overlay` y `muted` eran el mismo número con
dos nombres. Ahora el velo tiene su propia escala de cinco pasos
(`--background-scrim-strength-xs`…`-xl`) y la unión pasa a `xs|sm|md|lg|xl`,
ordenada por construcción: medido en Chrome, α 0,084 · 0,126 · 0,189 · 0,273 ·
0,420, estrictamente creciente. `md` sostiene el 0,45 que shipeó el hero, así que
el default pinta exactamente lo que pintaba. Era cambio de API y se hizo mientras
el único consumidor era la demo: ningún block nombra `strength`.
Y midiendo eso apareció que la tabla de contraste del README era falsa por la
mitad, en la dirección incómoda. Estaba calculada sobre una tinta de α 0,66;
`--color-overlay` resuelve a `rgba(28, 25, 23, 0.42)`. Los valores reales, ahora
compuestos en un canvas y leídos por píxel en vez de calculados: el default da
1,48:1 sobre foto blanca —no 2,10— y el paso más fuerte 2,14 —no 4,42—. Lo que
eso destapa no es un número peor sino un TECHO: `xl` gasta la tinta entera y
llega a 2,66:1, de modo que ningún paso nuevo puede alcanzar AA, porque el límite
es el alpha del token y no la escala. Con tinta opaca los mismos pesos dan 5,45:1
a 0,65 y 9,22:1 a 0,80. Queda como decisión del autor, reescrita con estas
cifras, porque es sobre qué ES un scrim y no sobre subir un valor.
La rama `@supports not (animation-timeline: view())` queda ejercitada, que era el
último hueco de verificación. Chromium ya no puede desactivar scroll-driven
—estable, flag de runtime retirado: seis candidatos probados, los seis siguen
reportando soporte—, pero el Firefox de Playwright NO lo soporta por sí mismo, así
que la rama está viva ahí sin emulación ninguna. Con el fichero de receta real:
`--background-progress` 0 → −64px, 0,5 → 0, 1 → +64px, con `animation-name: none`
y cero animaciones. Son los mismos extremos que el camino CSS medido en Chrome, o
sea que los dos caminos concuerdan; y en Chromium la rama no aplica y escribir la
var no mueve nada, que es la exclusión mutua que el README afirmaba sin haberla
medido. Sin ejercitar queda un eslabón —que `ScrollProgress` escriba la var
extremo a extremo—: desde el shell de este entorno no hay ruta a localhost, y
Firefox no alcanza el dev server.
El paseo de la checklist A–H, que estaba listado como lectura de F4 y nunca
registrado, encontró tres cosas. Faltaba la excepción `A2.3` con su ID (las tres
partes llevan `data: []` porque sus attrs son de wrapper y su único estado vive en
el Button que compone) y faltaba `## Subset` (color: el conjunto completo, porque
en decoración restringir la paleta sería arbitrario; intent: no se acepta). Y una
deriva documental: el README decía en TRES sitios que el control de pausa «IS the
canonical Toggle» y que dispara `commit-toggle`, cuando D-BG.18 lo cambió a
`IconButton` con etiqueta que cambia y sin `aria-pressed` — el evento es
`contact-activate` de `button.ts`. Vestigios de la era D-BG.4 que la enmienda no
barrió; corregidos, incluido el comentario del propio morfo.
La banda de `feature-split` queda firmada POR SECCIÓN, enmendando el plan en sus
tres menciones y `PLAN-blocks-quality` §3 columna B, que la pedía por fila: por
fila obliga a cada `Row` a poseer el estado de alternancia —su índice y el de sus
hermanas— y un block que coordina deja de ser un block que no posee nada.
Gates: audit PASS 0/0 · morfo:check (6 de 160 fallan, background no) · eidos-lint
invalid 0 y class-hooks 0 · rtl:check 0/180 · smoke del componente PASS · vitest
eidos 434/435 (el rojo es `skin-media-player`, el de siempre) · `check` con los
mismos 72 errores preexistentes y ninguno en ficheros propios.
Tres fantasmas costaron tiempo y son el mismo patrón: leer las vars tras un
screenshot devuelve el `write(0,0)` de un `pointerleave`; dar por muerto el
`strength` leyendo `backgroundColor` de un scrim GRADUADO, que pinta por
`background-image`; y juzgar `fade` y `pause` sin la precondición que necesitan.
El instrumento miente antes que el código, y aquí mintió tres veces.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
- **`@supports not`** ✅ ejercitada (§7.decies) en el Firefox de Playwright, que
|
|
|
|
|
|
NO soporta `view()` — 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: que `ScrollProgress` escriba la var extremo a extremo, porque desde
|
|
|
|
|
|
este entorno Firefox no alcanza el dev server.
|
|
|
|
|
|
|
uix(background): la línea de tiempo la capturaba un overflow, y el puntero se iba con el scroll
El travel llevaba dos días escrito y sin medir, porque el panel oculto nunca
activa una animación scroll-driven declarada en CSS. Con el Chrome del autor
delante se pudo medir, y lo que apareció no fue una confirmación: fueron dos
defectos que ninguna sonda había estado en posición de ver. La puerta es
`document.visibilityState` — con la pestaña oculta la `ViewTimeline` existe, con
`source` y `subject` correctos y `playState: 'running'`, y `currentTime` es
`null` para siempre; ahí ni un `await requestAnimationFrame` resuelve.
El primero estaba en la demo y el límite es del componente. `[data-uix-stage]`
declaraba `overflow: hidden`, y eso es un scroll container aunque no pueda
scrollear nunca: `view()` se ancló al stage y el progreso quedó clavado en 52,63%
en toda posición de scroll, sin error, sin aviso y con un `translate` de aspecto
perfectamente razonable. Con `overflow: clip` —recorta igual, respeta el radio, y
no es scroll container— el travel aparece: progreso 43,5% → 95,5%, `translate`
`0px -8,34px` → `0px 58,19px`, monótono, y los `4rem` completos de
`--background-parallax-travel` en el extremo. Entra en el README como quinto
límite porque el caso real no es un harness de demos: es el `overflow-x: hidden`
con el que cualquier landing contiene su decoración, que convierte al elemento en
scroll container en los DOS ejes.
El segundo era del componente. El rect del anfitrión se cacheaba en coordenadas
de viewport y sólo lo invalidaban `pointerenter` y un resize; el scroll mueve el
anfitrión sin disparar ninguno de los dos. Medido con ratón real: un tick de
rueda sobre un anfitrión de 288px dejaba `--background-pointer-y` 0,77 fuera de
sitio —los 111px de scroll sobre media altura, a la centésima—, o sea fuera del
rango −1…1 que la variable promete, con el spotlight despegado del cursor unos
115px y sin recuperarse hasta salir y volver a entrar. Cacheada la caja en
coordenadas de DOCUMENTO y normalizando contra `pageX`/`pageY`, que en un evento
real ya traen el scroll incorporado: error 0 en los dos movimientos, halo a 1px
del píxel pedido, sin lectura de layout en el camino caliente y sin el listener
de scroll que este componente existe para no tener. Queda dicho el residuo: un
scroller anidado vuelve a desviar, porque `pageY` no lo ve, y se autocura al
reentrar.
Y lo que era el encargo, medido: 60 fps con mediana de 16,7ms, p95 17,0, máximo
17,1 y 0 de 200 frames por encima de 20ms con el travel vivo —la base con
`speed: 0` salió peor, que es ruido de entorno—; y 0ms de reflow forzado en esos
mismos 200 frames moviendo los DOS ejes, con el observador de Long Animation
Frames que usa `arts/perf`. El cero está validado por mutación: un thrash
deliberado de 65ms en la misma página se reporta con 43ms forzados y el script
atribuido, porque un instrumento que no ve nada y un cero real se leen igual.
Sigue pendiente la rama `@supports not`, que sólo se ejercita en Firefox.
Las 174 demos comparten ese stage, así que el cambio se auditó: `affix` idéntico
y `sticky` idéntico —cuatro pasadas alternando `clip` y `hidden`, porque la
primera miente—, y `anchor-nav` cambia a mejor: su rail `position: sticky` es
hermano del scroller interno, con `hidden` no se pegaba nunca y se escapaba por
arriba perdiendo media lista, y ahora se mantiene a la vista. Ninguna demo tocada.
Dos avisos para quien vuelva. Un `PointerEvent` construido reporta
`pageY === clientY`, sin sumar el scroll, así que los eventos sintéticos sirven
para DESCUBRIR este defecto pero no para verificarlo: con ellos el arreglo bueno
mide −1,389 donde el ratón real da −0,008. Y leer las variables después de un
screenshot puede devolver el `write(0, 0)` de un `pointerleave` en vez de la
medición; el valor que vale es el del último `pointermove`, trazado.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
**Los dos defectos que salieron, ambos arreglados y verificados:**
|
|
|
|
|
|
|
uix(background): la línea de tiempo la capturaba un overflow, y el puntero se iba con el scroll
El travel llevaba dos días escrito y sin medir, porque el panel oculto nunca
activa una animación scroll-driven declarada en CSS. Con el Chrome del autor
delante se pudo medir, y lo que apareció no fue una confirmación: fueron dos
defectos que ninguna sonda había estado en posición de ver. La puerta es
`document.visibilityState` — con la pestaña oculta la `ViewTimeline` existe, con
`source` y `subject` correctos y `playState: 'running'`, y `currentTime` es
`null` para siempre; ahí ni un `await requestAnimationFrame` resuelve.
El primero estaba en la demo y el límite es del componente. `[data-uix-stage]`
declaraba `overflow: hidden`, y eso es un scroll container aunque no pueda
scrollear nunca: `view()` se ancló al stage y el progreso quedó clavado en 52,63%
en toda posición de scroll, sin error, sin aviso y con un `translate` de aspecto
perfectamente razonable. Con `overflow: clip` —recorta igual, respeta el radio, y
no es scroll container— el travel aparece: progreso 43,5% → 95,5%, `translate`
`0px -8,34px` → `0px 58,19px`, monótono, y los `4rem` completos de
`--background-parallax-travel` en el extremo. Entra en el README como quinto
límite porque el caso real no es un harness de demos: es el `overflow-x: hidden`
con el que cualquier landing contiene su decoración, que convierte al elemento en
scroll container en los DOS ejes.
El segundo era del componente. El rect del anfitrión se cacheaba en coordenadas
de viewport y sólo lo invalidaban `pointerenter` y un resize; el scroll mueve el
anfitrión sin disparar ninguno de los dos. Medido con ratón real: un tick de
rueda sobre un anfitrión de 288px dejaba `--background-pointer-y` 0,77 fuera de
sitio —los 111px de scroll sobre media altura, a la centésima—, o sea fuera del
rango −1…1 que la variable promete, con el spotlight despegado del cursor unos
115px y sin recuperarse hasta salir y volver a entrar. Cacheada la caja en
coordenadas de DOCUMENTO y normalizando contra `pageX`/`pageY`, que en un evento
real ya traen el scroll incorporado: error 0 en los dos movimientos, halo a 1px
del píxel pedido, sin lectura de layout en el camino caliente y sin el listener
de scroll que este componente existe para no tener. Queda dicho el residuo: un
scroller anidado vuelve a desviar, porque `pageY` no lo ve, y se autocura al
reentrar.
Y lo que era el encargo, medido: 60 fps con mediana de 16,7ms, p95 17,0, máximo
17,1 y 0 de 200 frames por encima de 20ms con el travel vivo —la base con
`speed: 0` salió peor, que es ruido de entorno—; y 0ms de reflow forzado en esos
mismos 200 frames moviendo los DOS ejes, con el observador de Long Animation
Frames que usa `arts/perf`. El cero está validado por mutación: un thrash
deliberado de 65ms en la misma página se reporta con 43ms forzados y el script
atribuido, porque un instrumento que no ve nada y un cero real se leen igual.
Sigue pendiente la rama `@supports not`, que sólo se ejercita en Firefox.
Las 174 demos comparten ese stage, así que el cambio se auditó: `affix` idéntico
y `sticky` idéntico —cuatro pasadas alternando `clip` y `hidden`, porque la
primera miente—, y `anchor-nav` cambia a mejor: su rail `position: sticky` es
hermano del scroller interno, con `hidden` no se pegaba nunca y se escapaba por
arriba perdiendo media lista, y ahora se mantiene a la vista. Ninguna demo tocada.
Dos avisos para quien vuelva. Un `PointerEvent` construido reporta
`pageY === clientY`, sin sumar el scroll, así que los eventos sintéticos sirven
para DESCUBRIR este defecto pero no para verificarlo: con ellos el arreglo bueno
mide −1,389 donde el ratón real da −0,008. Y leer las variables después de un
screenshot puede devolver el `write(0, 0)` de un `pointerleave` en vez de la
medición; el valor que vale es el del último `pointermove`, trazado.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
1. **Un ancestro `overflow: hidden` mata el travel en silencio** — `view()` se
|
|
|
|
|
|
ancla al scroll container más cercano y `hidden` lo es aunque no scrollee.
|
|
|
|
|
|
La demo lo sufría (`[data-uix-stage]`), progreso clavado en 52,63%. Arreglado
|
|
|
|
|
|
con `overflow: clip` en el stage + **quinto límite** en el README del
|
|
|
|
|
|
componente, porque el caso real es el `overflow-x: hidden` de cualquier
|
|
|
|
|
|
landing. Las 174 demos que comparten el stage: `affix` y `sticky` idénticos,
|
|
|
|
|
|
`anchor-nav` cambia a mejor (su rail sticky ya no se escapa por arriba).
|
|
|
|
|
|
2. **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 contra `pageX`/`pageY`; error
|
|
|
|
|
|
0 con ratón real, halo del spotlight a 1px del cursor. ⚠️ Un `PointerEvent`
|
|
|
|
|
|
sintético NO puede verificarlo (`pageY === clientY` en eventos construidos).
|
|
|
|
|
|
|
uix(background): la línea de tiempo la capturaba un overflow, y el puntero se iba con el scroll
El travel llevaba dos días escrito y sin medir, porque el panel oculto nunca
activa una animación scroll-driven declarada en CSS. Con el Chrome del autor
delante se pudo medir, y lo que apareció no fue una confirmación: fueron dos
defectos que ninguna sonda había estado en posición de ver. La puerta es
`document.visibilityState` — con la pestaña oculta la `ViewTimeline` existe, con
`source` y `subject` correctos y `playState: 'running'`, y `currentTime` es
`null` para siempre; ahí ni un `await requestAnimationFrame` resuelve.
El primero estaba en la demo y el límite es del componente. `[data-uix-stage]`
declaraba `overflow: hidden`, y eso es un scroll container aunque no pueda
scrollear nunca: `view()` se ancló al stage y el progreso quedó clavado en 52,63%
en toda posición de scroll, sin error, sin aviso y con un `translate` de aspecto
perfectamente razonable. Con `overflow: clip` —recorta igual, respeta el radio, y
no es scroll container— el travel aparece: progreso 43,5% → 95,5%, `translate`
`0px -8,34px` → `0px 58,19px`, monótono, y los `4rem` completos de
`--background-parallax-travel` en el extremo. Entra en el README como quinto
límite porque el caso real no es un harness de demos: es el `overflow-x: hidden`
con el que cualquier landing contiene su decoración, que convierte al elemento en
scroll container en los DOS ejes.
El segundo era del componente. El rect del anfitrión se cacheaba en coordenadas
de viewport y sólo lo invalidaban `pointerenter` y un resize; el scroll mueve el
anfitrión sin disparar ninguno de los dos. Medido con ratón real: un tick de
rueda sobre un anfitrión de 288px dejaba `--background-pointer-y` 0,77 fuera de
sitio —los 111px de scroll sobre media altura, a la centésima—, o sea fuera del
rango −1…1 que la variable promete, con el spotlight despegado del cursor unos
115px y sin recuperarse hasta salir y volver a entrar. Cacheada la caja en
coordenadas de DOCUMENTO y normalizando contra `pageX`/`pageY`, que en un evento
real ya traen el scroll incorporado: error 0 en los dos movimientos, halo a 1px
del píxel pedido, sin lectura de layout en el camino caliente y sin el listener
de scroll que este componente existe para no tener. Queda dicho el residuo: un
scroller anidado vuelve a desviar, porque `pageY` no lo ve, y se autocura al
reentrar.
Y lo que era el encargo, medido: 60 fps con mediana de 16,7ms, p95 17,0, máximo
17,1 y 0 de 200 frames por encima de 20ms con el travel vivo —la base con
`speed: 0` salió peor, que es ruido de entorno—; y 0ms de reflow forzado en esos
mismos 200 frames moviendo los DOS ejes, con el observador de Long Animation
Frames que usa `arts/perf`. El cero está validado por mutación: un thrash
deliberado de 65ms en la misma página se reporta con 43ms forzados y el script
atribuido, porque un instrumento que no ve nada y un cero real se leen igual.
Sigue pendiente la rama `@supports not`, que sólo se ejercita en Firefox.
Las 174 demos comparten ese stage, así que el cambio se auditó: `affix` idéntico
y `sticky` idéntico —cuatro pasadas alternando `clip` y `hidden`, porque la
primera miente—, y `anchor-nav` cambia a mejor: su rail `position: sticky` es
hermano del scroller interno, con `hidden` no se pegaba nunca y se escapaba por
arriba perdiendo media lista, y ahora se mantiene a la vista. Ninguna demo tocada.
Dos avisos para quien vuelva. Un `PointerEvent` construido reporta
`pageY === clientY`, sin sumar el scroll, así que los eventos sintéticos sirven
para DESCUBRIR este defecto pero no para verificarlo: con ellos el arreglo bueno
mide −1,389 donde el ratón real da −0,008. Y leer las variables después de un
screenshot puede devolver el `write(0, 0)` de un `pointerleave` en vez de la
medición; el valor que vale es el del último `pointermove`, trazado.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
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.
|
|
|
|
|
|
|
uix(background): el velo tenía una escala que no ordenaba, y una tinta que le pone techo
Cierra el eje salvo dos firmas. La escala `strength` dejaba de crecer a mitad de
camino: tomaba prestada `--opacity-*`, que nombra cuán opaco es un ELEMENTO, y
leída como pesos de velo salía `ghost` 0,30 · `scrim` 0,45 · `overlay` 0,65 ·
`muted` 0,65 · `subtle` 0,80 — es decir, un consumidor que pedía `subtle` recibía
el velo MÁS pesado del conjunto, y `overlay` y `muted` eran el mismo número con
dos nombres. Ahora el velo tiene su propia escala de cinco pasos
(`--background-scrim-strength-xs`…`-xl`) y la unión pasa a `xs|sm|md|lg|xl`,
ordenada por construcción: medido en Chrome, α 0,084 · 0,126 · 0,189 · 0,273 ·
0,420, estrictamente creciente. `md` sostiene el 0,45 que shipeó el hero, así que
el default pinta exactamente lo que pintaba. Era cambio de API y se hizo mientras
el único consumidor era la demo: ningún block nombra `strength`.
Y midiendo eso apareció que la tabla de contraste del README era falsa por la
mitad, en la dirección incómoda. Estaba calculada sobre una tinta de α 0,66;
`--color-overlay` resuelve a `rgba(28, 25, 23, 0.42)`. Los valores reales, ahora
compuestos en un canvas y leídos por píxel en vez de calculados: el default da
1,48:1 sobre foto blanca —no 2,10— y el paso más fuerte 2,14 —no 4,42—. Lo que
eso destapa no es un número peor sino un TECHO: `xl` gasta la tinta entera y
llega a 2,66:1, de modo que ningún paso nuevo puede alcanzar AA, porque el límite
es el alpha del token y no la escala. Con tinta opaca los mismos pesos dan 5,45:1
a 0,65 y 9,22:1 a 0,80. Queda como decisión del autor, reescrita con estas
cifras, porque es sobre qué ES un scrim y no sobre subir un valor.
La rama `@supports not (animation-timeline: view())` queda ejercitada, que era el
último hueco de verificación. Chromium ya no puede desactivar scroll-driven
—estable, flag de runtime retirado: seis candidatos probados, los seis siguen
reportando soporte—, pero el Firefox de Playwright NO lo soporta por sí mismo, así
que la rama está viva ahí sin emulación ninguna. Con el fichero de receta real:
`--background-progress` 0 → −64px, 0,5 → 0, 1 → +64px, con `animation-name: none`
y cero animaciones. Son los mismos extremos que el camino CSS medido en Chrome, o
sea que los dos caminos concuerdan; y en Chromium la rama no aplica y escribir la
var no mueve nada, que es la exclusión mutua que el README afirmaba sin haberla
medido. Sin ejercitar queda un eslabón —que `ScrollProgress` escriba la var
extremo a extremo—: desde el shell de este entorno no hay ruta a localhost, y
Firefox no alcanza el dev server.
El paseo de la checklist A–H, que estaba listado como lectura de F4 y nunca
registrado, encontró tres cosas. Faltaba la excepción `A2.3` con su ID (las tres
partes llevan `data: []` porque sus attrs son de wrapper y su único estado vive en
el Button que compone) y faltaba `## Subset` (color: el conjunto completo, porque
en decoración restringir la paleta sería arbitrario; intent: no se acepta). Y una
deriva documental: el README decía en TRES sitios que el control de pausa «IS the
canonical Toggle» y que dispara `commit-toggle`, cuando D-BG.18 lo cambió a
`IconButton` con etiqueta que cambia y sin `aria-pressed` — el evento es
`contact-activate` de `button.ts`. Vestigios de la era D-BG.4 que la enmienda no
barrió; corregidos, incluido el comentario del propio morfo.
La banda de `feature-split` queda firmada POR SECCIÓN, enmendando el plan en sus
tres menciones y `PLAN-blocks-quality` §3 columna B, que la pedía por fila: por
fila obliga a cada `Row` a poseer el estado de alternancia —su índice y el de sus
hermanas— y un block que coordina deja de ser un block que no posee nada.
Gates: audit PASS 0/0 · morfo:check (6 de 160 fallan, background no) · eidos-lint
invalid 0 y class-hooks 0 · rtl:check 0/180 · smoke del componente PASS · vitest
eidos 434/435 (el rojo es `skin-media-player`, el de siempre) · `check` con los
mismos 72 errores preexistentes y ninguno en ficheros propios.
Tres fantasmas costaron tiempo y son el mismo patrón: leer las vars tras un
screenshot devuelve el `write(0,0)` de un `pointerleave`; dar por muerto el
`strength` leyendo `backgroundColor` de un scrim GRADUADO, que pinta por
`background-image`; y juzgar `fade` y `pause` sin la precondición que necesitan.
El instrumento miente antes que el código, y aquí mintió tres veces.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
### 1.bis ✅ Cierre ejecutado (2026-08-18) — §7.decies
|
|
|
|
|
|
|
|
|
|
|
|
- **Escala del scrim ORDENADA**: `strength` pasa de `scrim|overlay|muted|subtle|ghost`
|
|
|
|
|
|
a **`xs|sm|md|lg|xl`** con tokens propios; α 0,084…0,420 estrictamente creciente,
|
|
|
|
|
|
`md` conserva 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 en
|
|
|
|
|
|
`PLAN-blocks-quality` §3 col. B.
|
|
|
|
|
|
- **Paseo A–H registrado**: añadidas al README la excepción `A2.3` y la sección
|
|
|
|
|
|
`## Subset`; corregida una deriva de TRES sitios que llamaba `Toggle` al control
|
|
|
|
|
|
de pausa (compone `IconButton`, evento `contact-activate`).
|
|
|
|
|
|
|
|
|
|
|
|
### 2. Lo que queda de tus firmas: DOS
|
|
|
|
|
|
|
|
|
|
|
|
De las cuatro, dos quedaron ejecutadas en §7.decies (la escala del scrim, ordenada
|
|
|
|
|
|
con tokens propios; la banda de `feature-split`, por sección y enmendada en los
|
|
|
|
|
|
tres sitios del plan más el de calidad). Quedan:
|
|
|
|
|
|
|
|
|
|
|
|
- ⛔ **Borrar `src/uix/eidos/components/backdrop/`** — D-BG.1 lo firmó y no lo usa
|
|
|
|
|
|
nadie (sólo se cita como baseline en el README de `Background` y en tres docs de
|
|
|
|
|
|
proceso, citas históricas que se conservan). **No lo he tocado**: la regla del
|
|
|
|
|
|
repo exige orden de borrado explícita, y «ejecuta el plan» no la sustituye. Una
|
|
|
|
|
|
palabra tuya y va.
|
|
|
|
|
|
- ⛔ **El techo de contraste del scrim, con las cifras corregidas.** Lo que había
|
|
|
|
|
|
escrito era falso por la mitad: el README asumía una tinta de α 0,66 y
|
|
|
|
|
|
`--color-overlay` trae **0,42**, así que el default no da 2,10:1 sobre foto
|
|
|
|
|
|
blanca sino **1,48:1**, y el paso más fuerte no da 4,42 sino **2,14**. Peor aún,
|
|
|
|
|
|
hay un **techo**: `xl` gasta la tinta entera y llega a **2,66:1**, de modo que
|
|
|
|
|
|
**ningún paso nuevo puede alcanzar AA** — el límite es el alpha del token, no la
|
|
|
|
|
|
escala. Las tres salidas, medidas por píxel:
|
|
|
|
|
|
1. **que el velo deje de heredar ese alpha** (con tinta opaca los mismos pesos
|
|
|
|
|
|
dan 5,45:1 a 0,65 y 9,22:1 a 0,80) — cambia qué ES un scrim y su relación con
|
|
|
|
|
|
el velo del modal;
|
|
|
|
|
|
2. **doctrinar que la respuesta es el scrim graduado**, y que sobre foto clara la
|
|
|
|
|
|
copia se pone en el extremo calmado;
|
|
|
|
|
|
3. dejarlo dicho y que cada consumidor oscurezca su propia foto.
|
|
|
|
|
|
Es decisión sobre la naturaleza del componente, no sobre un número.
|
|
|
|
|
|
|
|
|
|
|
|
### 3. Tareas de otros ejes que este abrió
|
|
|
|
|
|
|
|
|
|
|
|
- **`Ambient` honrando la pausa** (D-BG.8): el canon publica el contexto
|
|
|
|
|
|
(`paused`, `reduced`, `seen`); el pack lo lee y llama `handle.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>` (`ImageProvider` en `soma/layers`) y ninguno para vídeo.
|
|
|
|
|
|
Hoy `ScrollFrames` escucha a mano y `Background.Video` también. Dos consumidores
|
|
|
|
|
|
es el umbral que este repo usa para extraer una capa. (Anotado en
|
|
|
|
|
|
`next-features.md` §11.)
|
|
|
|
|
|
- Los huecos `Display` / `Link` bajo `data-on` siguen siendo candidatos de canon
|
|
|
|
|
|
aparte, como los dejó el hero.
|
|
|
|
|
|
|
|
|
|
|
|
## Lo que este eje enseñó, y conviene no volver a aprender
|
|
|
|
|
|
|
|
|
|
|
|
1. **A30 no es estilo, es supervivencia.** Registrarse con el padre desde un
|
|
|
|
|
|
`$effect` escribe 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 en `declare.svelte.ts` con sus dos mitades
|
|
|
|
|
|
(registrar desde el init, y seguir el prop sin escribir en la primera pasada).
|
|
|
|
|
|
2. **`revert-layer` sin `@layer` es `revert`.** Costó dos defectos distintos: la
|
|
|
|
|
|
regla de anfitrión que no posicionaba (D-BG.16) y el `flex` de `Box` que no
|
|
|
|
|
|
crecía. Cuando una declaración «no hace nada», mira si un shorthand vecino la
|
|
|
|
|
|
borró.
|
|
|
|
|
|
3. **La demo destapa lo que una sonda no.** El registro de «esta capa se mueve»
|
|
|
|
|
|
era un hecho de montaje: encender `animate` en caliente no hacía aparecer el
|
|
|
|
|
|
control de pausa. Invisible en una sonda, obvio con un interruptor.
|
|
|
|
|
|
4. **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.
|
|
|
|
|
|
5. **La decoración que parece mejor puede ser la ilegible.** Dentro del panel
|
|
|
|
|
|
sólido del `cta`, el `glow` hunde 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` |
|