|
|
# CONTINUE — visibilidad por breakpoint (`visibleFrom` / `hiddenFrom`) (handoff, act. 2026-08-19)
|
|
|
|
|
|
**Estado: F1–F3 HECHAS, AUDITADAS, VERIFICADAS en Chrome real y COMMITEADAS**
|
|
|
(2026-08-19, `uix(box): ocultar por CSS descarga el vídeo igual…`). La auditoría
|
|
|
de cierre encontró tres desviaciones menores, las tres corregidas antes del
|
|
|
commit (ver §Auditoría). Nada bloquea el uso.
|
|
|
|
|
|
**Por dónde entrar: [§Qué queda, por orden](#qué-queda-por-orden).** Lo único
|
|
|
pendiente es F4 (rollout al hero), y sólo si el autor lo pide.
|
|
|
|
|
|
## Qué es
|
|
|
|
|
|
Dos props en `Box` que **NO RENDERIZAN** el elemento fuera de su rango de
|
|
|
breakpoints — el subárbol no está en el DOM, sus efectos no corren y su media
|
|
|
no se pide. Es la mitad que `display={{ base: 'none' }}` no puede dar (oculta,
|
|
|
pero monta). Por herencia la ganan los once contenedores que componen `Box`
|
|
|
(Section, Container, Flex, Grid, Stack, Group, Wrap, AutoGrid, Surface,
|
|
|
AspectRatio, Float) sin tocar sus ficheros.
|
|
|
|
|
|
- `visibleFrom="md"` → no existe por debajo de `md` (desktop-only).
|
|
|
- `hiddenFrom="md"` → no existe desde `md` (mobile-only).
|
|
|
- Ambos → rango contiguo. `base` excluido del tipo a propósito.
|
|
|
|
|
|
La puerta es `eidos.dom.isAtLeast(bp)` —el predicado que `ActiveDom` ya tenía,
|
|
|
sobre los breakpoints que configura el app— en un `$derived` y un `{#if}`
|
|
|
alrededor de la raíz de `box.svelte`. Sin atributos nuevos, sin generador.
|
|
|
|
|
|
**Fuente viva de las decisiones**: `C:\Users\dev\.claude\plans\elegant-weaving-lark.md`
|
|
|
(D-V.1…4 firmadas 2026-08-18, con el estudio de cómo lo hacen Mantine, Chakra,
|
|
|
MUI, Vuetify, Framer y Webflow — todos por CSS o pagando flash/adivinando el
|
|
|
ancho). Su contenido de decisiones debería moverse a un lugar del repo si el eje
|
|
|
sigue creciendo (hoy vive en el README de Box y en `docs/architecture/eidos.md`).
|
|
|
|
|
|
## Auditoría de cierre (2026-08-19) — hallazgos y correcciones
|
|
|
|
|
|
| # | Hallazgo | Corrección |
|
|
|
| --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
|
| 1 | El tipo aceptaba `base`: `visibleFrom="base"` = «siempre», `hiddenFrom="base"` = «nunca renderiza» — y la demo (correctamente) no lo ofrecía en los chips: paridad rota entre tipo y demo | `Exclude<Breakpoint, 'base'>` en ambas props, con el porqué en el JSDoc. El mismo `Exclude` bajó a la demo (`$state` + chips) el 2026-08-19: sin él `npm run check` daba 2 errores en `box/`. **HECHO** |
|
|
|
| 2 | README decía «los doce contenedores que componen Box» y listaba once (el doceavo es Box) | «once… — doce con Box». **HECHO** |
|
|
|
| 3 | El plan pedía en Gaps la exclusión de Card / Banner / ScrollArea / Sticky (raíz propia, no heredan) y faltaba | Fila añadida con la regla del `as` (≥2 casos reales). **HECHO** |
|
|
|
| 4 | Dos afirmaciones del informe no se habían LEÍDO en consola: «Svelte repara el `{#if}` sin aviso» y «sin `effect_update_depth_exceeded` al cruzar con capas que se registran» | Medido en Chrome con consola capturada desde la carga: **cero** avisos de hidratación, **cero** bucles en 3 ciclos con un `Background.Gradient animate` dentro; `Stack → Flex → Box` hereda. **CONFIRMADO** |
|
|
|
| 5 | La nota documental fue a `docs/architecture/eidos.md` y no a `theming/reference.md` como decía el plan | `theming/reference.md` no tiene sección responsive; el párrafo del «puente responsive» vive en `eidos.md` §tokens. Desvío justificado, no error |
|
|
|
|
|
|
Verificado (Chrome real, 2026-08-18/19): a 2133px conviven `visibleFrom="md"`
|
|
|
presente, `hiddenFrom="md"` ausente y rango `sm–lg` ausente · al cerrar la puerta
|
|
|
en vivo desaparecen sección, `<video>` e `<input>` del DOM; al reabrir el input
|
|
|
vuelve **vacío** (la renuncia D-V.4, medida) · el par cambia con un `resize` ·
|
|
|
`npm run build` → `200.html` de 1.815 bytes, shell puro: **en producción no hay
|
|
|
SSR** que pueda pintar mal · en DEV sí: el dev server sirve la variante `base` y
|
|
|
pide su media antes de que la hidratación la pode (documentado en el README de
|
|
|
Box como caveat de desarrollo).
|
|
|
|
|
|
## Qué queda, por orden
|
|
|
|
|
|
> **Commit hecho el 2026-08-19** con las seis rutas del eje
|
|
|
> (`box/{box.svelte,types.ts,README.md}`, la demo, `eidos.md`, este handoff) y
|
|
|
> `git add` por ruta, nunca `-A`: otra sesión editaba `app-shell` en paralelo.
|
|
|
> Gates en verde ese día: `check` sin nada en `box/`, `blocks:check` 0,
|
|
|
> `morfo:check` PASS box, `docs:check` 0, `npx vitest run src/uix/eidos` 434/435
|
|
|
> (el fallo es `skin-media-player`, ajeno), prettier OK — salvo `eidos.md`, que
|
|
|
> **ya fallaba en HEAD** en tablas ajenas al eje y por eso no se reformatea.
|
|
|
|
|
|
> **F4 HECHA el 2026-08-19.** La receta vive donde se usa — `hero/README.md`
|
|
|
> §«The responsive backdrop» — y el vehículo es el backdrop de `HeroSite`. La
|
|
|
> puerta va DENTRO del snippet, nunca alrededor del `<Hero>`: envolver el block
|
|
|
> duplicaría título, copy, formulario y acciones por breakpoint (lo que hace
|
|
|
> Framer). `display="contents"` en las dos Box: una puerta decide presencia, no
|
|
|
> añade geometría. **Medido sobre build de PRODUCCIón** (`npm run build` +
|
|
|
> `vite preview`, Chrome): a **375** → 0 `<video>` en el DOM y **ninguna**
|
|
|
> petición de `video.mp4`; a **1280** → 1 `<video>` y **una** peticion
|
|
|
> (`206 Partial Content`). La afirmación central del eje deja de estar medida
|
|
|
> sólo en dev, donde es falsa.
|
|
|
>
|
|
|
> ⚠️ **Hallazgo ajeno, medido de paso**: la media dentro de un
|
|
|
> `Background.Layer` DESBORDA la capa — el mínimo automático del ítem de rejilla
|
|
|
> gana a `block-size: 100%`. Hero a 1280: capa 567px, `<video>` **714px**; y en
|
|
|
> la demo del propio canon con `<Background.Video>`: capa 288px, vídeo **435px**.
|
|
|
> `min-block-size: 0` lo colapsa exacto en ambos. `overflow: clip` lo esconde, y
|
|
|
> por eso nunca se vio. Es del eje `background` (cerrado el 2026-08-18), escrito
|
|
|
> en `hero/README.md` §Found while composing — marcado, no arreglado.
|
|
|
|
|
|
1. **Si algún día hay SSR/prerender** — el puente C está escrito en el README de
|
|
|
Box §Gaps con su disparador: `data-visible-from`/`data-hidden-from`, dos
|
|
|
reglas `@media` por breakpoint en `render-css.ts` (junto a las de
|
|
|
tipografía), y la puerta `hidratado ? resuelto : true`. Hoy sería un atributo
|
|
|
que nadie lee — no construir sin el disparador.
|
|
|
2. **Card, Banner, ScrollArea, Sticky** — no heredan (raíz propia). Regla del
|
|
|
`as`: a mano cuando aparezcan ≥2 casos reales; mientras, envolver en `<Box>`.
|
|
|
|
|
|
## Lo que este eje enseñó
|
|
|
|
|
|
- **Pregunta «¿y si no tenemos SSR?» antes de diseñar el puente.** Iba a
|
|
|
construir la híbrida (CSS hasta hidratar + desmontar después) por «framework de
|
|
|
referencia»; el repo respondió: `adapter-static` + `fallback` sin ninguna ruta
|
|
|
`prerender = true` = SPA puro. La mitad cara del diseño era para un despliegue
|
|
|
que no existe.
|
|
|
- **El panel oculto miente para esto también**: `innerWidth` 0 ⇒ todo resuelve a
|
|
|
`base`. La verificación exige Chrome visible (`claude-in-chrome`), y aun ahí
|
|
|
una ventana maximizada no admite `resize` — cruza el umbral por el breakpoint
|
|
|
(`hiddenFrom` con un botón), que recorre el mismo `$derived`.
|
|
|
- **Una sonda que no puede cerrar la puerta no prueba nada**: a 2133px
|
|
|
`visibleFrom="xxl"` sigue abierta (1536 < 2133). Elegir el eje que sí cruza.
|
|
|
|
|
|
## Mapa de ficheros
|
|
|
|
|
|
| Qué | Dónde |
|
|
|
| ---------------------------------------- | --------------------------------------------------------------- |
|
|
|
| La puerta | `src/uix/eidos/components/box/box.svelte` (`visible` + `{#if}`) |
|
|
|
| El tipo y su JSDoc | `src/uix/eidos/components/box/types.ts` |
|
|
|
| Decisiones, medidas, caveat de dev, gaps | `src/uix/eidos/components/box/README.md` |
|
|
|
| La demo (chips + snippet en paridad) | `web/routes/uix/components/box/+page.svelte` |
|
|
|
| La receta (caso real, con cifras) | `src/uix/blocks/hero/README.md` §«The responsive backdrop» |
|
|
|
| El caso real | `web/routes/blocks/hero/HeroSite.svelte` (snippet `backdrop`) |
|
|
|
| El párrafo de arquitectura | `docs/architecture/eidos.md` §«responsive bridge» |
|
|
|
| El predicado que reutiliza | `src/arts/adom/active-dom.svelte.ts` `isAtLeast` |
|