astra
alpha-0.1-background
alpha-0.1-dir-prefs
alpha-0.1-sec-dom
menubar-v4-safe
active-uix
morfo-runtime
morfo-driven-soma
semantuix
glm-5
main
sium-v1.0
${ noResults }
5 Commits (6d4aa05fbd82e309d211515362c2dfd788aed271)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
aa3f0e3511 |
uix(navigation-menu): navegar no fija nada, y el megamenú que se abre solo no debería sonar
T-1 de PLAN-sidebar.md §6. El `Link` emitía `commit-select + affirm` al navegar.
El libro lo nombra: TABLA 9.3, «Success de navegación — cambio de contexto con
logro», corregido como «shift + commit.fulfill si procede»; cap. 27 §2 «shift no
es commit… ir a otra pantalla no implica que la operación haya terminado»; y la
apertura de cap. 10, «una navegación no es exitosa por cambiar de pantalla».
Nada queda fijado al pulsar un enlace del nav: `aria-current="page"` es la huella
que deja el router DESPUÉS, no un estado que la parte fije.
Ahora habla el par de cap. 22 §9 —«Link → contact.press seguido de shift.navigate:
la presión no es la navegación»—, el mismo que la fila del Sidebar declaró ayer:
- `contact-activate` ANCLADO en el enlace pulsado (parte repetida → `partInstance`).
- `shift-navigate` en el `provider`, sin anclar: `data-event-*` es UNA ranura por
elemento, y el sujeto del cruce es el `<nav>` que cruza como unidad, no el
control que lo inicia. Sólo si el `<a>` tiene `href` — aquí no es un opt, viaja
en restProps, así que se lee del elemento que la parte ya tenía atado.
Esto REABRE la decisión del 2026-08-05 (ledger A-54), no la pisa: mover el evento
fuera del marco estaba bien; la familia era el defecto.
El pack estuvo a punto de borrarse, y esa habría sido la equivocación de la
sesión. Al quitarle la regla del commit se quedaba con dos selectores vacíos y
propuse retirarlo como ruido. El autor paró y pidió releer: la pregunta no era
qué escribe el fichero, sino qué debe decir la aparición del megamenú. Se abre
por HOVER, y medido con el default de familia un barrido del puntero por dos
triggers y salir de la barra emitía `open` · `open` · `close` — tres sonidos, 6
osciladores, sin un solo clic. Cap. 17 §3 («emerge — normalmente no necesita
sonido»), cap. 26 §7, cap. 32 §10-§11, cap. 5 §11. Así que `emerge-open` y
`emerge-close` son SILENT, la postura que `tooltip` y el flyout del `sidebar`
(D-SB.3) ya tienen para el mismo gesto. El pack DIFIERE del default y vuelve a
ser un pack.
Enmienda D.6 de book-deviations.md (PROJECT_CANON): `navigation-menu` sale del
alcance del `commit.subtle`, y quedan corregidas tres cláusulas suyas caducadas
— el `emerge-open/close` declarado desde el 2026-08-05, el `commit.subtle` que
murió en
|
2 months ago |
|
|
e2754a2b6f |
docs(sidebar): el handoff del eje, y las seis deudas que abrió en otros
En este eje no queda nada: nueve decisiones firmadas, cinco fases ejecutadas y verificadas, y la revisión adversarial pasada con sus cuatro hallazgos arreglados. Lo que queda es de OTROS ejes, y por eso el handoff los lista con nombre y sitio en vez de dejarlos en la cabeza de quien estuvo aquí: T-1 (`navigation-menu` emite `commit-select` al navegar — el antipatrón «success de navegación»), T-2 (nav-tree · anchor-nav · breadcrumb siguen mudos por el contrato que aquí se retiró), T-3 y T-4 (dos fichas del ledger de blocks que suponen lo contrario de lo que ahora hay), T-5 (el guard del bundle sólo ve tokens, no reglas) y T-6 (la densidad y el zoom no bajan a un subárbol, y eso no está escrito en ninguna doc). El handoff también deja por escrito las dos veces que hoy mintió el INSTRUMENTO y no el código: con la pantalla del navegador oculta rAF se congela y `getBoundingClientRect` daba 256px para un panel de 52; y leer `animationName` dentro del callback de un MutationObserver mide el instante anterior al flush, que es como di por viva una animación que moría 3,5 ms después. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
2 months ago |
|
|
bae03e55c5 |
uix(sidebar): cuatro cosas que sólo se ven cuando alguien intenta refutarte
Revisión adversarial del eje (seis lentes, un escéptico por hallazgo): 21
hallazgos, 17 refutados, 4 reales. Los cuatro, arreglados.
1. El `MenuBadge` no llegaba nunca a `lg`. Indexaba la tabla de su excepción
por `part`, que ya venía capado en `md`, así que la rama `lg→md` era código
muerto y un sidebar `lg` sacaba el chip un paso pequeño. Ahora indexa por la
talla del sidebar: 26 · 26 · 30 · 36.
2. `emerge-close-sub` se sellaba en un nodo que el mismo tick ocultaba. El
`display:none` de `[data-state='closed']` mataba `dismiss-fade` antes de
pintar un frame y, como el pack silencia ese evento a propósito, la retirada
del flyout se quedaba sin NINGÚN canal: una ocurrencia declarada que no
ocurre. La regla se guarda ahora con `:not([data-event^='emerge-close'])`,
que es justo la ventana que el canal visual mantiene abierta. Medido:
opacidad 0,85 → 0,35 → 0,03 con la animación viva, y el nodo oculto a los
~516 ms, cuando el sello se retira.
⚠️ Mi primera sonda dijo que `dismiss-fade` corría, y era mentira: leía
`animationName` DENTRO del callback del MutationObserver, o sea antes del
flush que ocultaba el elemento. El instrumento midió el instante equivocado.
3. La pestaña sema de la demo clavaba las SEIS previsualizaciones en el panel.
Con cuatro eventos apuntando a otras partes, el ▶ de `contact-activate`
estampaba la familia en el panel de 16rem y `press-squeeze` encogía el panel
ENTERO —lo contrario de lo que el propio párrafo de al lado explica—, y los
dos `emerge-*-sub` no podían encontrarse con la regla que los silencia,
atada a `[data-sidebar-menu-sub]`. `SemaPanel` recibe ahora la acción
(parámetro opcional: las otras 23 páginas siguen con su thunk sin
argumentos) y la página resuelve la parte desde el contrato compilado.
Medido: contacto → una fila, open-sub → el sub, shift → el provider.
4. La fila de Gaps del README de `app-shell` seguía afirmando que «sus morfos
sólo declaran emerge-expand/collapse», que es exactamente lo que este eje
dejó de ser cierto. Reescrita: queda viva sólo la mitad que lo sigue siendo
—`NavigationMenu` emitiendo `commit-select` al navegar, el antipatrón
«success de navegación» del cap. 10 §12—, y se registra por qué se refutó la
lectura «la fila SELECCIONA la sección».
Gates: eidos-lint 49/0 invalid · component:audit PASS · rtl:check 0 ·
docs:check 0/639 · vitest eidos 434/435 (el rojo es ajeno) · suite del sidebar
8/8 · `check` con delta CERO contra la base medida con stash (72/72).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2 months ago |
|
|
63b2de03c7 |
uix(sidebar): un token de ESPACIO no es la altura de un control, y el raíl de iconos no es una constante
El componente vivía fuera del canon de talla: la fila clavaba
`min-block-size: var(--space-8)` —un token de la escala de ESPACIO haciendo de
altura de CONTROL, que es otra escala de densidad— y `font-size:
var(--font-size-sm)` escrito en el recipe, donde el guard del bundle no lo ve.
El rótulo clavaba `xs`, el trigger `sm`, el badge `xs`, y la acción no componía
`Button`: se quedaba con los 13,33px del user-agent y sin acuse perceptivo
propio.
Ahora el sidebar tiene eje `size` (xs..lg, default `md`, `data-size` en el
WRAPPER —nunca en el morfo, o la resolución de soma lo pisaría con undefined—)
y cada coordenada de la fila sale del bundle `--size-{k}-*`. Medido: 26/12 ·
30/14 · 36/16 · 44/20, con el glifo siguiendo (14/16/18/20) por `--icon-size`,
que es la costura que ya usa `Button` porque un `<Icon>` pinta su tamaño INLINE
y gana a cualquier regla de hoja.
El raíl de iconos deja de ser `3rem`: se DERIVA (fila + 2×padding), así que da
42 · 46 · 52 · 60 y a `md` ya no recorta la fila que tiene que contener.
Tres composiciones más, por la regla que ya existía (container→part capada en
`md`, precedente `Dialog.Close`): el `Trigger` deriva su talla, la `MenuAction`
pasa a ser `IconButton ghost` —y con ella llegan su cromo, su anillo, su capa
de estado y su `contact-activate`—, y el `MenuBadge` deriva con UNA excepción
firmada: baja un paso, porque con la regla al pie el chip sale a 36/16 junto a
una fila de 36/16 e iguala al control en vez de anotarlo.
El hover deja de ser un `--color-surface-raised` a mano y pasa a la capa
canónica `--state-hover`. Al medirlo salió un defecto que no buscaba: la fila
activa no daba NINGUNA respuesta al hover, porque su acento usaba el shorthand
`background`, que resetea el longhand `background-image` donde vive la capa.
Con `background-color` la capa compone encima, que es justo para lo que existe.
Verificado con Playwright headless (la pantalla del navegador estaba oculta y
ahí rAF se congela: las medidas de layout salían falsas). Gates: eidos-lint 49
morfo-backed / 0 invalid · component:audit PASS 0E/0W · vitest src/uix/eidos
434/435 (el rojo es `skin-media-player`, ajeno, idéntico en base) · rtl:check 0
· docs:check 0/639 · `check` con delta CERO contra la base medida con stash
(72/72).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2 months ago |
|
|
f6d5fa1595 |
uix(sidebar): la fila que navega decía «te sentí» a nadie, y el libro dice cómo se dice
«Navegar una fila es nativo y no suena» era una decisión de la fase 1 tomada en silencio (el plan la dejó como «decidir en fase 1») sobre una premisa falsa — «item = Link puro»—: la fila es `<button>` cuando no tiene `href`, la acción es un botón pelado y el `MenuItem` posee un flyout. Medido en navegador: pulsar fila, sub-fila o acción estampaba CERO; el Trigger sí acusaba recibo, porque compone `Button`. El libro no deja margen: cap. 22 §9 compone el enlace como «contact.press seguido de shift.navigate: la presión no es la navegación», cap. 27 §8 lo repite y cap. 22 §12 llama antipatrón al contacto mudo. Así que la fila declara las dos ocurrencias, y la aparición del flyout —cap. 26 §5-§6, un menú anclado— deja de ser un cambio de estado sin evento. Dónde se estampa cada una lo decidió la doctrina, no la comodidad: el gesto en la mano (la fila, anclado por instancia: es parte REPETIDA) y el cruce en la superficie que cruza como unidad (el provider). Eso evita la quinta pareja `queue` que yo iba a declarar: calendar ya movió su `shift-navigate` fuera del botón porque las dos ocurrencias se comían la única ranura y el press-squeeze no llegaba a pintarse. Voz: contact y shift toman la de su familia (`touch`, `slide`) sin escribir nada; los dos `emerge-*-sub` van SILENT como el tooltip — el flyout se abre al pasar el puntero, y un barrido por el raíl serían ocho apariciones sonando (cap. 26 §7, Criterio 12). El `trigger` NO declara contacto: lo trae por composición de `Button`. El `rail` sí, porque es una franja de cromo y nadie más lo estampa. Medido en el navegador tras el cambio: fila con href → `contact-activate` (press-squeeze corriendo) en ESA fila + `shift-navigate` en el shell; fila deshabilitada → nada; sub-fila → el mismo par; rail → contacto propio + `emerge-collapse` del panel; en modo icono, hover → `emerge-open-sub` (present-rise), hover repetido → nada, salir → `emerge-close-sub` (dismiss-fade). Suite nueva de 8 contratos, `check` con delta CERO contra la base medida con stash (72/72), morfo:check PASS, contracts sin fallos nuevos. Plan y decisiones firmadas: docs/process/PLAN-sidebar.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
2 months ago |