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/process/CONTINUE-blocks.md

208 lines
12 KiB

feat(blocks): `banner` — el aviso de arriba, y tres defectos del canon que no existían F2.11. El block más FINO del tier a propósito: cuando el canon ya tiene la pieza, el block es colocación y nada más. Reenvía la superficie entera del `Banner` con `Omit<BannerProps, 'children'>` —sin re-declarar `intent`/`variant`/`size` ni estrecharlos—, lo mete en columna con `Container` (`width="100%"` + `paddingX={0}`: a sangre por fuera, en columna por dentro), envuelve la fila con `Wrap` en vez de aplastarla, y cablea `Banner.Close` solo si llega `onDismiss`. La visibilidad NO es suya: es la decisión que ya tomó el componente («composición, no un booleano `dismissible`»), así que el app envuelve en su `{#if}`. Un block que guardara ese estado sería una segunda fuente de verdad. Tampoco emite sema: el canon declara cero eventos para `Banner` a propósito, y un aviso persistente sin descarte es tan legítimo como uno descartable. La demo lo enseña **encima del `site-header` de verdad**, con página para desplazarse. Un aviso dentro de un recuadro no se parece a un aviso. ## El hallazgo que la fase 0 anticipó `Banner` estampa `role="banner"` DESPUÉS de sus rest props, así que no se puede relajar a una región normal. Con el `site-header` en la misma página —que es la única colocación que shipean las referencias— quedan **dos landmarks `banner`**. Medido en la vista previa: dos. Lo único que puede hacer un app hoy es nombrarlos con `aria-label`, y eso hace la demo. ## Y una lección de método que costó una sesión Reporté tres «defectos del canon» —`aria-label` ausente en `Banner.Close`, `type` desaparecido de todo `Button`, `IconButton` tragándose el `onclick`— y **los tres eran falsos**. La causa era la misma: medir demasiado pronto. Los `data-variant` / `data-size` los escribe el componente de eidos al renderizar, así que están desde el primer frame; `type`, `aria-label` y los handlers los aplica la **runtime del morfo en un efecto posterior**. A ~1s: `type` ausente en 3 de 3 botones y ningún clic disparando. A ~6s: `type="button"`, `aria-label="Descartar"` y el descarte funcionando. La espera válida es un atributo que solo pueda haber puesto la runtime —`waitForFunction(() => boton.hasAttribute('type'))`—, no que el nodo exista ni que se vea. La regla queda afinada en `CONTINUE-blocks.md`, que ya avisaba de esperar la condición y no el reloj: fallé al elegir la condición. De paso, un aviso de soma que sí era real y era mío: `Tabs.List` sin nombre accesible en `BlockDemo.svelte`. Afectaba a las 12 demos del tier. Verificado en navegador: los 4 intents, los 3 tratamientos, `descartable` sí/no (con `no` el botón deja de renderizarse, no se oculta), claro/oscuro/RTL y 420px, la tira siempre por encima de la cabecera, cero desbordamiento horizontal, el descarte con la página recolocándose, y los controles de la demo moviendo la vista previa en línea. Gates: `blocks:check` verde (12 blocks) · `svelte-check` sin errores propios · `docs:check` sin errores míos · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
# CONTINUE — F2 blocks de sitio (handoff, act. 2026-07-31)
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
feat(blocks): `team` — las personas, y un contexto que sirve para una sola cosa F2.12. Compound porque `Member` SE REPITE (el app mapea sobre N), como `feature-grid`. Pero es el primero del tier cuyo **contexto existe para una sola cosa**: el `align` de la sección viaja a cada `Member` y a su fila de enlaces, así que la foto, el nombre, el cargo y los enlaces comparten eje sin que el app repita la alineación en cada tarjeta. Un `align` explícito en una parte siempre gana. Esa es la diferencia con `feature-grid`, cuyos ítems solo se repiten y por eso no llevan contexto: **la regla de forma se aplica parte por parte, no block por block**. ## Dos decisiones de forma - **Sin `.MemberAvatar`.** El plan la dibujaba; no tendría nada que añadir sobre `<Avatar size radius>` y escondería su API (`Image`, `Fallback`, los estados de carga). El app compone el `Avatar` del canon directamente dentro del `Member`. Se envuelve lo que el block DEFAULTEA —tipografía, retícula, eje—, no lo que solo reenvía. - **El nombre es un `Heading level={3}`** apagado con `size="sm"`: una persona en una retícula tiene nombre, y las referencias lo marcan igual. El nivel es estructura del documento; el tamaño, tipografía. Así un lector de pantalla puede saltar de persona a persona. Y un detalle que separa cumplir de sobresalir: la fila de enlaces va pegada al fondo de la tarjeta (`marginTop: auto`). Con biografías de distinto largo las filas quedaban a alturas distintas y la retícula se leía descuadrada; sin biografías las tarjetas ya miden lo mismo y la regla no cambia nada. ## Encontrado al verificar **Un `columns` fijo no colapsa.** A 420px, cuatro columnas dejan celdas de ~90px con el nombre partido en tres líneas y el avatar desbordando. El default del block es fluido (`minChildWidth`), así que el fallo era de la demo: ahora pasa `columns={{ base: 2, md: N }}` — para eso están los props responsivos. Anotado en el README. Verificado en navegador, esperando el atributo que pone la runtime del morfo y no el reloj: 2/3/4 columnas, `align` center/start propagándose por contexto al eje de cada miembro, biografía sí/no, claro/oscuro/RTL y 420px, seis avatares, doce botones de icono **con nombre propio por persona** («Escribir a Ada Lovelace», no «correo»), escalonado estructural con índices 0,1,2…, cero desbordamiento horizontal y cero errores de página. Gates: `blocks:check` verde (13 blocks) · `svelte-check` sin errores propios · `docs:check` 0 · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**Estado: F1 CERRADA (8/8) · F2 13 de 15.** Hechos: site-header · hero ·
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
feature-grid · **feature-split** · pricing · testimonials · faq · stats-band ·
feat(blocks): `team` — las personas, y un contexto que sirve para una sola cosa F2.12. Compound porque `Member` SE REPITE (el app mapea sobre N), como `feature-grid`. Pero es el primero del tier cuyo **contexto existe para una sola cosa**: el `align` de la sección viaja a cada `Member` y a su fila de enlaces, así que la foto, el nombre, el cargo y los enlaces comparten eje sin que el app repita la alineación en cada tarjeta. Un `align` explícito en una parte siempre gana. Esa es la diferencia con `feature-grid`, cuyos ítems solo se repiten y por eso no llevan contexto: **la regla de forma se aplica parte por parte, no block por block**. ## Dos decisiones de forma - **Sin `.MemberAvatar`.** El plan la dibujaba; no tendría nada que añadir sobre `<Avatar size radius>` y escondería su API (`Image`, `Fallback`, los estados de carga). El app compone el `Avatar` del canon directamente dentro del `Member`. Se envuelve lo que el block DEFAULTEA —tipografía, retícula, eje—, no lo que solo reenvía. - **El nombre es un `Heading level={3}`** apagado con `size="sm"`: una persona en una retícula tiene nombre, y las referencias lo marcan igual. El nivel es estructura del documento; el tamaño, tipografía. Así un lector de pantalla puede saltar de persona a persona. Y un detalle que separa cumplir de sobresalir: la fila de enlaces va pegada al fondo de la tarjeta (`marginTop: auto`). Con biografías de distinto largo las filas quedaban a alturas distintas y la retícula se leía descuadrada; sin biografías las tarjetas ya miden lo mismo y la regla no cambia nada. ## Encontrado al verificar **Un `columns` fijo no colapsa.** A 420px, cuatro columnas dejan celdas de ~90px con el nombre partido en tres líneas y el avatar desbordando. El default del block es fluido (`minChildWidth`), así que el fallo era de la demo: ahora pasa `columns={{ base: 2, md: N }}` — para eso están los props responsivos. Anotado en el README. Verificado en navegador, esperando el atributo que pone la runtime del morfo y no el reloj: 2/3/4 columnas, `align` center/start propagándose por contexto al eje de cada miembro, biografía sí/no, claro/oscuro/RTL y 420px, seis avatares, doce botones de icono **con nombre propio por persona** («Escribir a Ada Lovelace», no «correo»), escalonado estructural con índices 0,1,2…, cero desbordamiento horizontal y cero errores de página. Gates: `blocks:check` verde (13 blocks) · `svelte-check` sin errores propios · `docs:check` 0 · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
cta · newsletter · site-footer · banner · team. **Quedan 2**: contact (§F2.13) ·
content-section (§F2.14).
feat(blocks): F2.3 `feature-grid` — el primer block compound del tier `<FeatureGrid>` + `.Header` + `.Items` + `.Item` + `.ItemIcon`/`.ItemTitle`/ `.ItemText`: una cabecera sobre una rejilla responsive de features (icono · título · texto). Es la sección que responde «qué hace», la nº1 tras el hero. Primer block COMPOUND del tier, y aplica la regla de forma que fijamos: el `.Item` se REPITE (el app mapea sobre N features) → gana sub-componentes, donde `hero`/`site-header` usan slots de snippet (partes fijas de layout). Las partes no coordinan —sin contexto ni estado entre ellas—: la rejilla es del padre, las celdas del app. `.Items` es el envoltorio honesto de la rejilla (`AutoGrid`), que deja la cabecera fuera sin un `grid-column: 1/-1` a pelo. - El block coloca (Section · Container · AutoGrid · Surface · Heading · Text); el app pone todo el contenido por children (B-7). - `.Items` fluido por `minChildWidth` (tantas columnas como quepan) o `columns` fijas; `.Item` `align` start/center; `.ItemIcon` chip `Surface`; `.ItemTitle` `Heading` h3; `.ItemText` `Text` apagado. - `align` de sección (center/start) coloca la cabecera coherente con las columnas. Dos cosas encontradas al construir, resueltas: - **Los sub-componentes de bloque extienden los props del componente canon que envuelven** (`BoxProps`, `StackProps`, `HeadingProps`…), **no `HTMLAttributes`**: el `style: string|null` del atributo HTML crudo choca con el `style: string` del canon al hacer spread (+ "union type too complex"). - **`.ItemIcon` por defecto `solid`, no `soft`**: el soft-primary en claro es casi blanco (oklch 0.99) → el chip era invisible; solid da el chip con glifo on-solid (la tinta de contraste la pone `Surface`). Demo (`web/routes/blocks/feature-grid/`): full-bleed + ruta `preview`, con control de columnas (fluido/2/3/4), align, nº de items y dir; 6 features con iconos del canon. Hueco a decisión del usuario (en los Gaps del block): el **feature-split/ alternante** (texto junto a un screenshot, lados alternos) — la brecha nº1 del dossier — es otra disposición (filas de 2 columnas, no rejilla de iconos): probablemente un block hermano `feature-split`. Presentado, no resuelto. Verificado en navegador (Playwright, módulos frescos): center/start × claro/ oscuro × LTR/RTL, columnas fluidas y fijas, 3/4/6 items, chips visibles. `blocks:check` verde (3 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
(El plan fijó 14; `feature-split` se añadió como block hermano con
scope-approval, así que el tier tiene 15 y el denominador honesto es 15.)
fix(blocks): lo que la auditoría encontró DENTRO del tier Una auditoría multi-agente (7 dimensiones doctrinales + refutación adversarial) confirmó 32 hallazgos sobre la pasada de calidad. Esto corrige los que caen dentro de `blocks/`; la deuda de fuera queda REGISTRADA, no tocada (`PLAN-blocks-quality.md` §6). - **B-7 roto en `pricing`**: el block traía tres strings castellanas propias como defaults del toggle — dos visibles y un nombre accesible. Hardcodeaba un idioma DENTRO del framework y esquivaba `langs`, en el mismo block cuyo README predica «cero strings propias». Ahora los tres son props REQUERIDAS y las pone la app. - **El block pintaba**: `pricing.Plan` metía `box-shadow` por `style=` porque `Card` no expone elevación. Retirado; el hueco queda registrado como candidato a canon en vez de falseado. - **El escalonado estaba roto y el comentario mentía**: puse `spring-pop` (driver JS) en los planes, y un driver JS no lee el `animation-delay` donde vive el stagger — entraban TODOS a la vez mientras el comentario afirmaba lo contrario. Vuelto al preset CSS: verificado, índices 0,1,2 a 70ms. - **Comentario falso en la demo del hero**: atribuía al `intent` visual una consecuencia sonora/háptica que ningún camino produce (el morfo del Button dice explícitamente que `contact-activate` NO lleva intent). Reescrito. - **Composition maps mentían**: los 6 blocks que ahora componen `Motion` no lo decían; el hero seguía diciendo `Heading` (es `Display`), sin `Backdrop` ni `decor`, y declaraba DIFERIDO un preset de cromo de media que ya está shipeado (`Mockup`). Al día, sin filas duplicadas ni datos rancios (el chip de feature-grid es `solid`, no `soft`). - **Handoff y plan**: el plan seguía prescribiendo un `<Reveal>` que esta misma sesión creó y retiró; el handoff daba `feature-split` por «sin decidir» estando hecho, y los gates con números falsos. Verificado: `blocks:check` verde (7) · `svelte-check` sin errores propios · en el navegador, pricing escalona de nuevo, las etiquetas vienen de la app y ninguna tarjeta pinta sombra. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2 months ago
feat(blocks): `banner` — el aviso de arriba, y tres defectos del canon que no existían F2.11. El block más FINO del tier a propósito: cuando el canon ya tiene la pieza, el block es colocación y nada más. Reenvía la superficie entera del `Banner` con `Omit<BannerProps, 'children'>` —sin re-declarar `intent`/`variant`/`size` ni estrecharlos—, lo mete en columna con `Container` (`width="100%"` + `paddingX={0}`: a sangre por fuera, en columna por dentro), envuelve la fila con `Wrap` en vez de aplastarla, y cablea `Banner.Close` solo si llega `onDismiss`. La visibilidad NO es suya: es la decisión que ya tomó el componente («composición, no un booleano `dismissible`»), así que el app envuelve en su `{#if}`. Un block que guardara ese estado sería una segunda fuente de verdad. Tampoco emite sema: el canon declara cero eventos para `Banner` a propósito, y un aviso persistente sin descarte es tan legítimo como uno descartable. La demo lo enseña **encima del `site-header` de verdad**, con página para desplazarse. Un aviso dentro de un recuadro no se parece a un aviso. ## El hallazgo que la fase 0 anticipó `Banner` estampa `role="banner"` DESPUÉS de sus rest props, así que no se puede relajar a una región normal. Con el `site-header` en la misma página —que es la única colocación que shipean las referencias— quedan **dos landmarks `banner`**. Medido en la vista previa: dos. Lo único que puede hacer un app hoy es nombrarlos con `aria-label`, y eso hace la demo. ## Y una lección de método que costó una sesión Reporté tres «defectos del canon» —`aria-label` ausente en `Banner.Close`, `type` desaparecido de todo `Button`, `IconButton` tragándose el `onclick`— y **los tres eran falsos**. La causa era la misma: medir demasiado pronto. Los `data-variant` / `data-size` los escribe el componente de eidos al renderizar, así que están desde el primer frame; `type`, `aria-label` y los handlers los aplica la **runtime del morfo en un efecto posterior**. A ~1s: `type` ausente en 3 de 3 botones y ningún clic disparando. A ~6s: `type="button"`, `aria-label="Descartar"` y el descarte funcionando. La espera válida es un atributo que solo pueda haber puesto la runtime —`waitForFunction(() => boton.hasAttribute('type'))`—, no que el nodo exista ni que se vea. La regla queda afinada en `CONTINUE-blocks.md`, que ya avisaba de esperar la condición y no el reloj: fallé al elegir la condición. De paso, un aviso de soma que sí era real y era mío: `Tabs.List` sin nombre accesible en `BlockDemo.svelte`. Afectaba a las 12 demos del tier. Verificado en navegador: los 4 intents, los 3 tratamientos, `descartable` sí/no (con `no` el botón deja de renderizarse, no se oculta), claro/oscuro/RTL y 420px, la tira siempre por encima de la cabecera, cero desbordamiento horizontal, el descarte con la página recolocándose, y los controles de la demo moviendo la vista previa en línea. Gates: `blocks:check` verde (12 blocks) · `svelte-check` sin errores propios · `docs:check` sin errores míos · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
Todo commiteado y pusheado a `gita/alpha-0.1-sec-dom`.
feat(blocks): F2.3 `feature-grid` — el primer block compound del tier `<FeatureGrid>` + `.Header` + `.Items` + `.Item` + `.ItemIcon`/`.ItemTitle`/ `.ItemText`: una cabecera sobre una rejilla responsive de features (icono · título · texto). Es la sección que responde «qué hace», la nº1 tras el hero. Primer block COMPOUND del tier, y aplica la regla de forma que fijamos: el `.Item` se REPITE (el app mapea sobre N features) → gana sub-componentes, donde `hero`/`site-header` usan slots de snippet (partes fijas de layout). Las partes no coordinan —sin contexto ni estado entre ellas—: la rejilla es del padre, las celdas del app. `.Items` es el envoltorio honesto de la rejilla (`AutoGrid`), que deja la cabecera fuera sin un `grid-column: 1/-1` a pelo. - El block coloca (Section · Container · AutoGrid · Surface · Heading · Text); el app pone todo el contenido por children (B-7). - `.Items` fluido por `minChildWidth` (tantas columnas como quepan) o `columns` fijas; `.Item` `align` start/center; `.ItemIcon` chip `Surface`; `.ItemTitle` `Heading` h3; `.ItemText` `Text` apagado. - `align` de sección (center/start) coloca la cabecera coherente con las columnas. Dos cosas encontradas al construir, resueltas: - **Los sub-componentes de bloque extienden los props del componente canon que envuelven** (`BoxProps`, `StackProps`, `HeadingProps`…), **no `HTMLAttributes`**: el `style: string|null` del atributo HTML crudo choca con el `style: string` del canon al hacer spread (+ "union type too complex"). - **`.ItemIcon` por defecto `solid`, no `soft`**: el soft-primary en claro es casi blanco (oklch 0.99) → el chip era invisible; solid da el chip con glifo on-solid (la tinta de contraste la pone `Surface`). Demo (`web/routes/blocks/feature-grid/`): full-bleed + ruta `preview`, con control de columnas (fluido/2/3/4), align, nº de items y dir; 6 features con iconos del canon. Hueco a decisión del usuario (en los Gaps del block): el **feature-split/ alternante** (texto junto a un screenshot, lados alternos) — la brecha nº1 del dossier — es otra disposición (filas de 2 columnas, no rejilla de iconos): probablemente un block hermano `feature-split`. Presentado, no resuelto. Verificado en navegador (Playwright, módulos frescos): center/start × claro/ oscuro × LTR/RTL, columnas fluidas y fijas, 3/4/6 items, chips visibles. `blocks:check` verde (3 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
Dónde vive cada cosa:
feat(blocks): F2.2 `hero` — center · split · background, por slots Segundo block del tier. API por SLOTS DE SNIPPET, no compound: la forma se razonó con el usuario y con el paisaje de referencia. Compound se reserva para partes que COORDINAN (estado/contexto/ARIA entre ellas — Accordion, Dialog); un hero son cinco slots de layout que no se hablan entre sí y que el root arregla, así que snippets. Además el campo entero shippea marketing como copy-paste plano —nadie aplica compound a una sección—, y los slots por zona son la historia de personalización que distingue al tier del copy-paste. `<Hero layout="center|split|background" level container size>` + `eyebrow/title/description/actions/media/background/children`. - El block **envuelve** título y subtítulo en `Heading`/`Text`: así posee el `id` que nombra el `<section aria-labelledby>` y el nivel del encabezado, mientras la app pone las palabras (B-7). `eyebrow`/`actions`/`media` son contenido libre (ahí los componentes del canon SON la API). - `center` = `Stack` centrado, media debajo (ancho-capado); `split` = `Grid` de dos columnas (una sola sin media), apila en estrecho. - **`background` (cover)** — añadido por scope-approval del usuario: la media a sangre detrás de la copy, con velo de contraste (`--color-overlay` a `--opacity-scrim`), texto `on-solid` y `object-fit: cover` vía un `<style>` justificado (D-BLK.2). Son las ÚNICAS reglas que el block posee, todas sobre tokens del ecosistema — cero color a mano. Capas por orden de fuente, sin `z-index`. Demo (`web/routes/blocks/hero/`): full-bleed en la página + ruta `preview` para anchos de dispositivo, cada prop un control vivo, y el backdrop del layout cover dogfooda el sistema de color — es un `Surface color="primary" gradient` (finish aurora = `--gradient-aurora`, derivado de los roles del tema; cambia con la paleta). Mini-site compartido por las dos superficies (`HeroSite.svelte`). Encontrado al componer, registrado no resuelto: `Box`/`Surface` `flex`/`grow` no hicieron crecer un hijo flex (bars a 0-width, `flex: 0 1 auto`; la prop no la usa ningún componente shipped). La demo usó `Grid` (tracks `1fr`). Flag en el README del block y en el handoff para revisar el cableado de `--box-flex`. Verificado en navegador (Playwright headless, módulos frescos): center/split/ background × claro/oscuro × LTR/RTL, media on/off, y el landmark nombrado (región con `aria-labelledby` que resuelve al título). `blocks:check` verde (2 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Plan y bitácora por block**: `docs/process/PLAN-blocks.md` (fichas §F2.x +
registro cronológico al final, con el detalle de cada cierre).
- **Contrato del tier**: `docs/architecture/blocks.md` (B-1..B-11, D-BLK).
- **Suelo de paridad**: `docs/process/RESEARCH-blocks-references.md` (el dossier).
- **Deuda de canon congelada**: `docs/process/PLAN-blocks-quality.md` §6.
- **Decisiones por block**: el README de cada uno (`src/uix/blocks/{kebab}/`).
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
---
feat(blocks): `team` — las personas, y un contexto que sirve para una sola cosa F2.12. Compound porque `Member` SE REPITE (el app mapea sobre N), como `feature-grid`. Pero es el primero del tier cuyo **contexto existe para una sola cosa**: el `align` de la sección viaja a cada `Member` y a su fila de enlaces, así que la foto, el nombre, el cargo y los enlaces comparten eje sin que el app repita la alineación en cada tarjeta. Un `align` explícito en una parte siempre gana. Esa es la diferencia con `feature-grid`, cuyos ítems solo se repiten y por eso no llevan contexto: **la regla de forma se aplica parte por parte, no block por block**. ## Dos decisiones de forma - **Sin `.MemberAvatar`.** El plan la dibujaba; no tendría nada que añadir sobre `<Avatar size radius>` y escondería su API (`Image`, `Fallback`, los estados de carga). El app compone el `Avatar` del canon directamente dentro del `Member`. Se envuelve lo que el block DEFAULTEA —tipografía, retícula, eje—, no lo que solo reenvía. - **El nombre es un `Heading level={3}`** apagado con `size="sm"`: una persona en una retícula tiene nombre, y las referencias lo marcan igual. El nivel es estructura del documento; el tamaño, tipografía. Así un lector de pantalla puede saltar de persona a persona. Y un detalle que separa cumplir de sobresalir: la fila de enlaces va pegada al fondo de la tarjeta (`marginTop: auto`). Con biografías de distinto largo las filas quedaban a alturas distintas y la retícula se leía descuadrada; sin biografías las tarjetas ya miden lo mismo y la regla no cambia nada. ## Encontrado al verificar **Un `columns` fijo no colapsa.** A 420px, cuatro columnas dejan celdas de ~90px con el nombre partido en tres líneas y el avatar desbordando. El default del block es fluido (`minChildWidth`), así que el fallo era de la demo: ahora pasa `columns={{ base: 2, md: N }}` — para eso están los props responsivos. Anotado en el README. Verificado en navegador, esperando el atributo que pone la runtime del morfo y no el reloj: 2/3/4 columnas, `align` center/start propagándose por contexto al eje de cada miembro, biografía sí/no, claro/oscuro/RTL y 420px, seis avatares, doce botones de icono **con nombre propio por persona** («Escribir a Ada Lovelace», no «correo»), escalonado estructural con índices 0,1,2…, cero desbordamiento horizontal y cero errores de página. Gates: `blocks:check` verde (13 blocks) · `svelte-check` sin errores propios · `docs:check` 0 · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
## Lo siguiente: F2.13 `contact`
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
feat(blocks): `team` — las personas, y un contexto que sirve para una sola cosa F2.12. Compound porque `Member` SE REPITE (el app mapea sobre N), como `feature-grid`. Pero es el primero del tier cuyo **contexto existe para una sola cosa**: el `align` de la sección viaja a cada `Member` y a su fila de enlaces, así que la foto, el nombre, el cargo y los enlaces comparten eje sin que el app repita la alineación en cada tarjeta. Un `align` explícito en una parte siempre gana. Esa es la diferencia con `feature-grid`, cuyos ítems solo se repiten y por eso no llevan contexto: **la regla de forma se aplica parte por parte, no block por block**. ## Dos decisiones de forma - **Sin `.MemberAvatar`.** El plan la dibujaba; no tendría nada que añadir sobre `<Avatar size radius>` y escondería su API (`Image`, `Fallback`, los estados de carga). El app compone el `Avatar` del canon directamente dentro del `Member`. Se envuelve lo que el block DEFAULTEA —tipografía, retícula, eje—, no lo que solo reenvía. - **El nombre es un `Heading level={3}`** apagado con `size="sm"`: una persona en una retícula tiene nombre, y las referencias lo marcan igual. El nivel es estructura del documento; el tamaño, tipografía. Así un lector de pantalla puede saltar de persona a persona. Y un detalle que separa cumplir de sobresalir: la fila de enlaces va pegada al fondo de la tarjeta (`marginTop: auto`). Con biografías de distinto largo las filas quedaban a alturas distintas y la retícula se leía descuadrada; sin biografías las tarjetas ya miden lo mismo y la regla no cambia nada. ## Encontrado al verificar **Un `columns` fijo no colapsa.** A 420px, cuatro columnas dejan celdas de ~90px con el nombre partido en tres líneas y el avatar desbordando. El default del block es fluido (`minChildWidth`), así que el fallo era de la demo: ahora pasa `columns={{ base: 2, md: N }}` — para eso están los props responsivos. Anotado en el README. Verificado en navegador, esperando el atributo que pone la runtime del morfo y no el reloj: 2/3/4 columnas, `align` center/start propagándose por contexto al eje de cada miembro, biografía sí/no, claro/oscuro/RTL y 420px, seis avatares, doce botones de icono **con nombre propio por persona** («Escribir a Ada Lovelace», no «correo»), escalonado estructural con índices 0,1,2…, cero desbordamiento horizontal y cero errores de página. Gates: `blocks:check` verde (13 blocks) · `svelte-check` sin errores propios · `docs:check` 0 · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
Ficha en `PLAN-blocks.md` §F2.13. Del dossier: 7 en Tailwind Plus. Es
**`newsletter` a lo grande**: `Form` + varios `Field` (nombre, correo, mensaje) +
`Form.Submit`, más una columna de datos de contacto al lado.
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
feat(blocks): `team` — las personas, y un contexto que sirve para una sola cosa F2.12. Compound porque `Member` SE REPITE (el app mapea sobre N), como `feature-grid`. Pero es el primero del tier cuyo **contexto existe para una sola cosa**: el `align` de la sección viaja a cada `Member` y a su fila de enlaces, así que la foto, el nombre, el cargo y los enlaces comparten eje sin que el app repita la alineación en cada tarjeta. Un `align` explícito en una parte siempre gana. Esa es la diferencia con `feature-grid`, cuyos ítems solo se repiten y por eso no llevan contexto: **la regla de forma se aplica parte por parte, no block por block**. ## Dos decisiones de forma - **Sin `.MemberAvatar`.** El plan la dibujaba; no tendría nada que añadir sobre `<Avatar size radius>` y escondería su API (`Image`, `Fallback`, los estados de carga). El app compone el `Avatar` del canon directamente dentro del `Member`. Se envuelve lo que el block DEFAULTEA —tipografía, retícula, eje—, no lo que solo reenvía. - **El nombre es un `Heading level={3}`** apagado con `size="sm"`: una persona en una retícula tiene nombre, y las referencias lo marcan igual. El nivel es estructura del documento; el tamaño, tipografía. Así un lector de pantalla puede saltar de persona a persona. Y un detalle que separa cumplir de sobresalir: la fila de enlaces va pegada al fondo de la tarjeta (`marginTop: auto`). Con biografías de distinto largo las filas quedaban a alturas distintas y la retícula se leía descuadrada; sin biografías las tarjetas ya miden lo mismo y la regla no cambia nada. ## Encontrado al verificar **Un `columns` fijo no colapsa.** A 420px, cuatro columnas dejan celdas de ~90px con el nombre partido en tres líneas y el avatar desbordando. El default del block es fluido (`minChildWidth`), así que el fallo era de la demo: ahora pasa `columns={{ base: 2, md: N }}` — para eso están los props responsivos. Anotado en el README. Verificado en navegador, esperando el atributo que pone la runtime del morfo y no el reloj: 2/3/4 columnas, `align` center/start propagándose por contexto al eje de cada miembro, biografía sí/no, claro/oscuro/RTL y 420px, seis avatares, doce botones de icono **con nombre propio por persona** («Escribir a Ada Lovelace», no «correo»), escalonado estructural con índices 0,1,2…, cero desbordamiento horizontal y cero errores de página. Gates: `blocks:check` verde (13 blocks) · `svelte-check` sin errores propios · `docs:check` 0 · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
Lo que ya sabemos y no hay que volver a descubrir (está en el README del
`newsletter`): el handler va SIEMPRE en `createForm` —`Form.Provider` ignora
`onValidSubmit` sobre un `form` ya construido—, los mensajes de SIUM son
idlangref y se resuelven con `uix.langs.t(issue.message, issue.params)`, y con
más de un campo entra en juego `Form.ErrorSummary`, que el `newsletter` no
necesitaba. Fase 0: leer su README y el del `Form` antes de componer.
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
feat(blocks): `team` — las personas, y un contexto que sirve para una sola cosa F2.12. Compound porque `Member` SE REPITE (el app mapea sobre N), como `feature-grid`. Pero es el primero del tier cuyo **contexto existe para una sola cosa**: el `align` de la sección viaja a cada `Member` y a su fila de enlaces, así que la foto, el nombre, el cargo y los enlaces comparten eje sin que el app repita la alineación en cada tarjeta. Un `align` explícito en una parte siempre gana. Esa es la diferencia con `feature-grid`, cuyos ítems solo se repiten y por eso no llevan contexto: **la regla de forma se aplica parte por parte, no block por block**. ## Dos decisiones de forma - **Sin `.MemberAvatar`.** El plan la dibujaba; no tendría nada que añadir sobre `<Avatar size radius>` y escondería su API (`Image`, `Fallback`, los estados de carga). El app compone el `Avatar` del canon directamente dentro del `Member`. Se envuelve lo que el block DEFAULTEA —tipografía, retícula, eje—, no lo que solo reenvía. - **El nombre es un `Heading level={3}`** apagado con `size="sm"`: una persona en una retícula tiene nombre, y las referencias lo marcan igual. El nivel es estructura del documento; el tamaño, tipografía. Así un lector de pantalla puede saltar de persona a persona. Y un detalle que separa cumplir de sobresalir: la fila de enlaces va pegada al fondo de la tarjeta (`marginTop: auto`). Con biografías de distinto largo las filas quedaban a alturas distintas y la retícula se leía descuadrada; sin biografías las tarjetas ya miden lo mismo y la regla no cambia nada. ## Encontrado al verificar **Un `columns` fijo no colapsa.** A 420px, cuatro columnas dejan celdas de ~90px con el nombre partido en tres líneas y el avatar desbordando. El default del block es fluido (`minChildWidth`), así que el fallo era de la demo: ahora pasa `columns={{ base: 2, md: N }}` — para eso están los props responsivos. Anotado en el README. Verificado en navegador, esperando el atributo que pone la runtime del morfo y no el reloj: 2/3/4 columnas, `align` center/start propagándose por contexto al eje de cada miembro, biografía sí/no, claro/oscuro/RTL y 420px, seis avatares, doce botones de icono **con nombre propio por persona** («Escribir a Ada Lovelace», no «correo»), escalonado estructural con índices 0,1,2…, cero desbordamiento horizontal y cero errores de página. Gates: `blocks:check` verde (13 blocks) · `svelte-check` sin errores propios · `docs:check` 0 · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
Después: content-section (composición de `prose` + `Section`), y F2 queda cerrada.
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
feat(blocks): `team` — las personas, y un contexto que sirve para una sola cosa F2.12. Compound porque `Member` SE REPITE (el app mapea sobre N), como `feature-grid`. Pero es el primero del tier cuyo **contexto existe para una sola cosa**: el `align` de la sección viaja a cada `Member` y a su fila de enlaces, así que la foto, el nombre, el cargo y los enlaces comparten eje sin que el app repita la alineación en cada tarjeta. Un `align` explícito en una parte siempre gana. Esa es la diferencia con `feature-grid`, cuyos ítems solo se repiten y por eso no llevan contexto: **la regla de forma se aplica parte por parte, no block por block**. ## Dos decisiones de forma - **Sin `.MemberAvatar`.** El plan la dibujaba; no tendría nada que añadir sobre `<Avatar size radius>` y escondería su API (`Image`, `Fallback`, los estados de carga). El app compone el `Avatar` del canon directamente dentro del `Member`. Se envuelve lo que el block DEFAULTEA —tipografía, retícula, eje—, no lo que solo reenvía. - **El nombre es un `Heading level={3}`** apagado con `size="sm"`: una persona en una retícula tiene nombre, y las referencias lo marcan igual. El nivel es estructura del documento; el tamaño, tipografía. Así un lector de pantalla puede saltar de persona a persona. Y un detalle que separa cumplir de sobresalir: la fila de enlaces va pegada al fondo de la tarjeta (`marginTop: auto`). Con biografías de distinto largo las filas quedaban a alturas distintas y la retícula se leía descuadrada; sin biografías las tarjetas ya miden lo mismo y la regla no cambia nada. ## Encontrado al verificar **Un `columns` fijo no colapsa.** A 420px, cuatro columnas dejan celdas de ~90px con el nombre partido en tres líneas y el avatar desbordando. El default del block es fluido (`minChildWidth`), así que el fallo era de la demo: ahora pasa `columns={{ base: 2, md: N }}` — para eso están los props responsivos. Anotado en el README. Verificado en navegador, esperando el atributo que pone la runtime del morfo y no el reloj: 2/3/4 columnas, `align` center/start propagándose por contexto al eje de cada miembro, biografía sí/no, claro/oscuro/RTL y 420px, seis avatares, doce botones de icono **con nombre propio por persona** («Escribir a Ada Lovelace», no «correo»), escalonado estructural con índices 0,1,2…, cero desbordamiento horizontal y cero errores de página. Gates: `blocks:check` verde (13 blocks) · `svelte-check` sin errores propios · `docs:check` 0 · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
**F2.12 `team` HECHO** — compound (`Member` se repite) y el primero cuyo contexto
sirve para UNA cosa: el `align` de la sección viaja a cada miembro y a su fila de
enlaces. Sin `.MemberAvatar`: el app compone el `Avatar` del canon directamente
(envolver lo que solo se reenvía esconde la API). La fila de enlaces va pegada al
fondo para que biografías de distinto largo no descuadren la retícula. Encontrado
al verificar: **un `columns` fijo no colapsa** — a 420px cuatro columnas dejan
celdas de ~90px; la demo pasa `columns={{ base: 2, md: N }}`.
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
---
## La regla de forma del tier (no la re-decidas)
Compound **solo** si las partes:
- **SE REPITEN** — el app mapea sobre N (`feature-grid.Item`,
`testimonials.Item`, `pricing.Plan`, `faq.Item`, `stats-band.Stat`,
`site-footer.Column`), o
- **COORDINAN** — se hablan por contexto (`pricing.Switch` ↔ `PlanPrice`).
Si no hacen ninguna de las dos: **slots de snippet** en la raíz (`hero`, `cta`,
`newsletter`, y la marca / alta / social / legal / extra de `site-footer`). El
plan original dibujaba varias de esas como partes; la desviación está registrada
en cada README.
---
## Los 8 hallazgos de canon que dejó el tier (congelados)
Restricción del usuario en vigor: **no tocar componentes ni librerías fuera de
`src/uix/blocks/` y `web/routes/blocks/`**. Están todos medidos en navegador
y listados en `PLAN-blocks-quality.md` §6 (F15–F22) — más los de motion (A1, A2,
A4, C7, C8, C10, D12, E14) de la pasada de calidad.
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| # | Qué |
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| F15 | `Surface variant='soft'` **no acota un panel**: su track queda a 0.002 de luminancia del fondo de página en claro, y `Surface` no tiene borde. `Card outline` sí acota pero no acepta `gradient` → «panel sosegado con borde» no tiene primitivo. |
| F16 | La ranura `contrast` de la paleta es **blanca en todo escalón sólido**, así que un lienzo de luminancia media deja el cuerpo bajo AA: `primary` 5.18 · `indigo` 5.21 · `plum` 4.75 pasan; `neutral` 3.32 · `secondary`/`slate` 3.30 · `teal` 3.07 fallan en claro. |
| F17 | **`Text align` es inerte por defecto**: renderiza un `span` y `text-align` no hace nada sobre caja inline. Hay que pedir `as="p"`. |
| F18 | **La fundación de eidos no trae reset de modelo de caja y lo asume del app.** Bajo `content-box`, `[data-field-control]` (`inline-size:100%` + padding) mide 30px más que su contenedor. Resuelto en app-land: `web/routes/blocks/_lib/reset.css`. |
| F19 | **`onValidSubmit`/`onInvalidSubmit` son no-op silenciosos** si se pasa un `form` ya construido: el componente solo los reenvía al `createForm` que hace él mismo. El handler va SIEMPRE en `createForm`. |
| F20 | Los mensajes de SIUM son **idlangref** (`#?sium.errors.email\|…`): resolver con `uix.langs.t(issue.message, issue.params)`. La demo de docs del `Form` los parte a mano y por eso siempre salen en inglés. |
| F21 | **Los primitivos de layout no pueden cambiar de elemento**: `Text`/`Heading` aceptan `as`, pero `Box` —y `Stack`/`Flex`/`Grid`/`Group`/`Wrap`/`Container`/`Section`— es un `<div>` fijo. Una columna de enlaces no puede ser `ul`/`li`. |
| F22 | **Un `Select` controlado muestra el VALOR crudo hasta abrirse una vez**: las etiquetas las registran los `Select.Item` al montarse y el `Content` portaleado está cerrado. Rodeo: el `child` de `Select.Value`. |
Y dos huecos anteriores que siguen abiertos: **`Box`/`Surface` `flex`/`grow` no
hacen crecer a un hijo flex** (se rodea con tracks `1fr` de `Grid`) y **`Group` no
apila** (usa `Flex direction={{ base: 'column', sm: 'row' }}`; `hero` todavía
compone sus acciones con `Group`).
---
## La plantilla ya existe — cópiala, no la reinventes
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
```text
src/uix/blocks/{kebab}/
├── README.md # Función · Mapa de composición · Decisiones · Gaps
├── index.ts # export del compound + tipos
├── types.ts # props (todo contenido entra por snippets, B-5/B-7)
└── {kebab}.svelte # composición: solo componentes del canon, sin CSS
web/routes/blocks/{kebab}/
├── +page.svelte # BlockDemo + controles vivos + pestañas de doc
├── {Name}Site.svelte # el block dentro de contenido REAL de producto
└── preview/
├── +layout@.svelte # `@` resetea el layout: la vista previa es su página
└── +page.svelte # sirve {Name}Site leyendo la URL
```
Y luego: marcar `shipped: true` en `web/routes/blocks/_lib/catalog.ts` (raíl y
galería leen esa única fuente) y `npm run blocks:check`.
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
---
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
## Reglas que ya costaron sangre (no las re-aprendas)
- **El block se enseña A SANGRE en la página.** Nada entre el block y el borde:
ni marco con relleno, ni caja con scroll, ni cromo pegajoso encima. Medido: un
`Card` desplazaba 21px un header con `offset: 0` (su recipe pinta con
`--card-padding-*`, que `padding={0}` de la capa Box no alcanza), y un
`position: sticky` dentro de un div con scroll es un comportamiento que nadie
vive. **Si un block se ancla a algo, se mide contra lo que se anclará en
producción.**
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Verifica esperando la CONDICIÓN, nunca un timeout fijo.** Con `Form`+`Field`+
SIUM el dev server tarda ~2,5s en hidratar y un screenshot temprano fotografía
el panel todavía invisible (`data-animation-pending` puesto). Esperar a que ese
atributo desaparezca es la diferencia entre verificar y reportar un bug que no
existe.
feat(blocks): `banner` — el aviso de arriba, y tres defectos del canon que no existían F2.11. El block más FINO del tier a propósito: cuando el canon ya tiene la pieza, el block es colocación y nada más. Reenvía la superficie entera del `Banner` con `Omit<BannerProps, 'children'>` —sin re-declarar `intent`/`variant`/`size` ni estrecharlos—, lo mete en columna con `Container` (`width="100%"` + `paddingX={0}`: a sangre por fuera, en columna por dentro), envuelve la fila con `Wrap` en vez de aplastarla, y cablea `Banner.Close` solo si llega `onDismiss`. La visibilidad NO es suya: es la decisión que ya tomó el componente («composición, no un booleano `dismissible`»), así que el app envuelve en su `{#if}`. Un block que guardara ese estado sería una segunda fuente de verdad. Tampoco emite sema: el canon declara cero eventos para `Banner` a propósito, y un aviso persistente sin descarte es tan legítimo como uno descartable. La demo lo enseña **encima del `site-header` de verdad**, con página para desplazarse. Un aviso dentro de un recuadro no se parece a un aviso. ## El hallazgo que la fase 0 anticipó `Banner` estampa `role="banner"` DESPUÉS de sus rest props, así que no se puede relajar a una región normal. Con el `site-header` en la misma página —que es la única colocación que shipean las referencias— quedan **dos landmarks `banner`**. Medido en la vista previa: dos. Lo único que puede hacer un app hoy es nombrarlos con `aria-label`, y eso hace la demo. ## Y una lección de método que costó una sesión Reporté tres «defectos del canon» —`aria-label` ausente en `Banner.Close`, `type` desaparecido de todo `Button`, `IconButton` tragándose el `onclick`— y **los tres eran falsos**. La causa era la misma: medir demasiado pronto. Los `data-variant` / `data-size` los escribe el componente de eidos al renderizar, así que están desde el primer frame; `type`, `aria-label` y los handlers los aplica la **runtime del morfo en un efecto posterior**. A ~1s: `type` ausente en 3 de 3 botones y ningún clic disparando. A ~6s: `type="button"`, `aria-label="Descartar"` y el descarte funcionando. La espera válida es un atributo que solo pueda haber puesto la runtime —`waitForFunction(() => boton.hasAttribute('type'))`—, no que el nodo exista ni que se vea. La regla queda afinada en `CONTINUE-blocks.md`, que ya avisaba de esperar la condición y no el reloj: fallé al elegir la condición. De paso, un aviso de soma que sí era real y era mío: `Tabs.List` sin nombre accesible en `BlockDemo.svelte`. Afectaba a las 12 demos del tier. Verificado en navegador: los 4 intents, los 3 tratamientos, `descartable` sí/no (con `no` el botón deja de renderizarse, no se oculta), claro/oscuro/RTL y 420px, la tira siempre por encima de la cabecera, cero desbordamiento horizontal, el descarte con la página recolocándose, y los controles de la demo moviendo la vista previa en línea. Gates: `blocks:check` verde (12 blocks) · `svelte-check` sin errores propios · `docs:check` sin errores míos · prettier limpio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Y la condición tiene que ser algo que escriba la RUNTIME del morfo, no el
render.** Los `data-variant` / `data-size` los pone el componente de eidos al
renderizar, así que están desde el primer frame; `type`, `aria-label` y los
handlers los aplica la runtime en un efecto POSTERIOR. Esperar a que exista el
nodo (o a que se vea) no basta: a ~1s medí `type` ausente en TODOS los `Button`
del árbol y ningún `onclick` disparando, y a ~6s los mismos botones tenían
`type="button"`, `aria-label="Descartar"` y el clic funcionando. Reporté tres
«defectos del canon» que no existían. **La espera correcta es
`waitForFunction(() => boton.hasAttribute('type'))`** — un atributo que solo
puede haber puesto la runtime.
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Playwright headless SÍ sirve para foco y teclado.** El pane suspendido no
(congela rAF y pierde `activeElement`), pero un `page.keyboard.type()` real
dispara `:placeholder-shown` y `:focus-within`: así se verificó que la etiqueta
flotante del `Field` sube al borde. `page.fill()` usa el setter nativo y NO los
dispara. Un script del scratchpad debe importar
`file:///G:/dev/svelte/vicen/node_modules/playwright/index.mjs` (no resuelve
`playwright` por ruta relativa).
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
- **Los anchos de dispositivo (375/768) van por la ruta `preview` en iframe**, y
es opt-in: en dev, dos documentos sin empaquetar a la vez agotan las
conexiones del navegador (`ERR_INSUFFICIENT_RESOURCES` mata las DOS páginas).
- **Cada prop público, un control vivo** en la demo; los ejes de sección (tema,
idioma, dirección, densidad) ya los da el shell, no los repitas.
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Un slot que se apaga se pasa como `undefined`, no se renderiza vacío.**
Declara el snippet arriba y pásalo por prop
(`signup={activo ? banda : undefined}`): así el `{#if}` del block quita también
su hueco. Y **cuidado con el sombreado**: `{#snippet signup()}` pisa un prop
llamado `signup` dentro del componente.
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
- **Nada de backticks de markdown dentro de `<Text>`**: se ven literales. Lo que
es código va en `<Code>`.
- **Ojo con las variables de layout que heredan.** `justify` de `Group` se
hereda a los clusters anidados (pon `justify` explícito) y las de `Box` YA no
heredan desde 2026-07-23 (`docs/theming/changelog.md` §46).
- **Un hueco del canon se registra, no se falsea.** Si al componer falta algo,
va a los Gaps del block como candidato a canon y la demo usa lo que hay.
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- **Los números de layout se miden.** Tres defaults de `site-footer` (`container`,
la razón de la rejilla, el gap de columnas) salieron mal a la primera y solo el
navegador lo dijo. Si un default decide cuántas cosas caben en una fila, se
comprueba con el contenido real.
---
## Deuda del arnés de demos (mía, sin tocar)
- La galería (`web/routes/blocks/+layout@.svelte`) **arranca UIX en línea** en vez
de usar `_lib/BootUix.svelte`, que es lo que usan los previews: la misma cadena
escrita dos veces, y el motivo de que `reset.css` haya que importarlo en los dos
sitios.
- En `BlockDemo`, a ~1400px, el conmutador de anchos de dispositivo se solapa con
el párrafo que lo precede. Idéntico en los 11 blocks → es del arnés, no de un
block.
---
## Deuda a decisión tuya
Siguen sin decidir, cada una entra por el contrato B con **fase 0 ligera**
(mirar ≥2 catálogos del dossier y anotar adoptado/descartado en el README):
1. **Tabla de comparación** de features×planes en `pricing` (recurre en las refs;
sería un hermano `pricing-table`).
2. **Cita en spotlight** en `testimonials` (la variante modal de TODAS las refs;
el grid es minoría, 2 de 8 en TW).
3. **Lista estática 2/3 columnas** en `faq` (6 de 7 en TW no son acordeón).
4. **`form-in-hero`** (slot de alta al boletín dentro del hero).
Resueltas ya: feature-split/alternante (F2.3b, con `Mockup`) · hero con fondo
cover (layout `background`) · CTA que navega y parece botón (el `child` de
`Button` entrega un snippet `content`; `Button` sigue sin `href` y `Link` sigue
poseyendo la navegación — doctrina en el README de eidos Button §«CTA que
navega»).
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
---
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff Documentación al día de lo que se cerró hoy y handoff para retomar mañana. - `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu` (arreglado en el canon, no parcheado en el block), el hueco del CTA que navega y parece botón (registrado, no falseado) y el defecto de framework que destapó la demo. - `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de heredarse. Un `Section` regalaba su padding a cada descendiente —la galería arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display` ajenos. `@property { inherits: false }`, radio verificado sin regresiones. Lección: una variable que un componente escribe para SÍ MISMO debe declararse `inherits: false`; si no, deja de ser un prop y se vuelve un contagio. - `architecture/blocks.md` B-9: la demo de un block se construye sobre el harness compartido y el block se enseña A SANGRE — nunca dentro de un marco con relleno ni de una caja con scroll, porque eso cambia lo que el block hace. - `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta `preview`, `DocRow`, catálogo único, ejes en el shell). - `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe solo para anchos de dispositivo, cada prop un control, nada de backticks en `<Text>`, ojo con las variables que heredan), la deuda declarada que es decisión del usuario y el estado exacto de los gates. Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los 3 fallos ajenos conocidos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
## Estado de gates al parar
docs(process): el handoff de blocks, reescrito para entrar en frío mañana El fichero se había convertido en una pila cronológica: la cabecera seguía contando el estado de hace tres blocks y los gates decían «8 blocks». Ahora es un punto de entrada. - **Estado honesto arriba**: 11 de **15** (el plan fijó 14; `feature-split` entró como hermano con scope-approval, así que el denominador real es 15), qué queda con su §, y dónde vive cada cosa (plan, contrato, dossier, deuda, READMEs). - **F2.11 `banner` con fase 0 en pasos**: leer primero el README del componente `Banner` que YA existe —si el descarte, la persistencia o el `role` son suyos, el block los compone, no los reinventa—, contrastar ≥2 catálogos, decidir la forma, y enseñarlo ENCIMA del header, que es donde vive. - **La regla de forma del tier** en su propia sección, con los ejemplos ya shipeados de cada lado (repiten / coordinan / slots). - **Los 8 hallazgos de canon (F15–F22) en una tabla**, cada uno con su número medido, en vez de repartidos por cinco párrafos. Más los dos huecos viejos que siguen abiertos (`flex` que no crece, `Group` que no apila). - **Tres reglas nuevas de las que costaron sangre**: esperar la CONDICIÓN y no un timeout (con Form+Field+SIUM la hidratación tarda ~2,5s y un screenshot temprano fotografía el panel invisible); Playwright headless SÍ vale para foco y teclado reales, `page.fill()` no; y un slot que se apaga se pasa como `undefined`, con el aviso de que `{#snippet signup()}` sombrea un prop del mismo nombre. - **Gates remedidos, no heredados**: `blocks:check` 11 blocks, `svelte-check` sin errores propios, y los 3 fallos de `contracts.test.ts` verificados uno a uno como ajenos (escrituras DOM en soma, data-attrs hardcodeados, claves camelCase de `aura`) — ninguno apunta a `blocks/`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- `npm run blocks:check` **verde (11 blocks)**.
- `svelte-check`: **sin errores propios** (73 en el repo, todos ajenos:
`file-upload`, etc.).
- `prettier`: limpio en mis ficheros del tier.
- `vitest src/uix/contracts.test.ts`: **3 fallos AJENOS** (35 pasan) — escrituras
DOM directas en soma, data-attrs hardcodeados y las claves camelCase de `aura`
(`components.aura.announce.returnedStopped`, …). Ninguno apunta a `blocks/`.

Powered by TurnKey Linux.