@ -9,6 +9,164 @@
---
## ESTADO 2026-07-18 — capa de edición EN LÍNEA (bubble + slash + find) ✅ · menubar pulido
> ⚠️ La sección «2026-07-17 MENUBAR v4 MENÚ-NATIVO» de abajo es HISTÓRICA: ese enfoque
> (menú-nativo `e2172aec4` ) fue **REVERTIDO** el mismo día. El menubar vigente es el de
> **INSPECTORES PLANOS** : una entrada de barra POR SECCIÓN del elemento, cada una suelta un
> `Menubar.Panel` (role=dialog) con controles reales. Esta sección de arriba es el estado REAL.
### Lo hecho hoy (todo en `alpha-0.1-sec-dom` → `gita` )
**A. Menubar pulido**
- `44c481b70` inspector **ANCHO-ADAPTATIVO sin scroll** : el componente calcula `--pcols` (1/2/3)
por densidad de la sección; superficie `fit-content` sobre ancho EXPLÍCITO por tier
(~17/26/35rem, evita el sizing circular fit-content↔fr); mega-controles auto-fit; FUERA el tope
de scroll interno (la superficie `[data-menubar-panel]` , con su `overflow:auto` del recipe, es el
único límite). Verificado: cero scroll en 5 secciones × 10 tipos a 900 y 800.
- `f8f94d38f` **Ajustes** : sliders a 2 COLUMNAS FIJAS ~256px. LECCIÓN DURA (el usuario explotó):
el `auto-fit minmax(7rem)` los empaquetaba a 4× 120px → pistas SOLAPANDO la etiqueta vecina. Un
slider es control ANCHO, no va en auto-fit estrecho. Reset compacto a la derecha (no barra full).
- `3da8bf800` **Editar** gana **Deshacer/Rehacer** (`api.undo/redo` + `canUndo/canRedo` ); el trigger
«Editar» pasa a estar SIEMPRE habilitado (undo/redo son globales del doc), los items de elemento
(mover/copiar/pegar/eliminar) se gatean por `loc` .
- `b0cbb7fc2` panel **Documento** en menubar: quitada su CABECERA propia (título «Documento» + chip)
— la entrada de barra ya lo nombra; abre directo en las secciones (guard `mode !== 'menubar'` ).
- `378e1ed9f` panel **Documento = SOLO PROPIEDADES** (Documento·Texto·Paleta): quitados el ** Índice
y el recuento** (decisión del usuario: un índice es NAVEGACIÓN, no una propiedad de página).
Borradas `idPathOf` /`jumpToHeading` + su CSS. **NO re-añadir el índice al panel de propiedades.**
**B. Capa de edición EN LÍNEA — el mayor hueco P0, cerradas las 3 superficies**
**HALLAZGO CLAVE**: el MOTOR ya exporta los contratos como componentes + snippets —
`Words.BubbleMenu` / `SlashMenu` / `FindReplace` / `LinkEditor` + ** `Words.CommandButton` ** (restaura
el rango, refleja `data-active` ). Estaban SIN chrome desde el borrado de `words` → eran CABLEAR, no
construir de cero. Referencia difunta del bubble:
`git show 326a25ec4^:src/uix/eidos/components/words/words-bubble.svelte` . Focus-scope: cualquier tool
debe estar en `isInsideWordsTool` (`words-provider.svelte.ts:1691`; `[data-words-bubble-menu]` /
`-slash-menu` /`-find-replace`/`-link-editor`/`-external-tool` ya listados).
- `99a7e1c23` **BUBBLE** (`palabras-bubble.svelte`, §4.3): formato de selección B/I/U/S/código
(`Words.CommandButton`) + enlace inline (`insertLink`/`selectedLink`/`unlink`). Posición del
contenedor: `--_words-bubble-x/y` + `data-side` . PENDIENTE: **F2.4** tipografía de rango
(tamaño/familia/sub/sup) + «→propiedades» tras un overflow (máx 8 ítems).
- `43c1e1c6a` **SLASH «/»** (`palabras-slash.svelte`, §4.2): renderiza `Words.SlashMenu` (14 tipos,
icono `blockTypeIcon(typeOf(id))` + label + descripción, activo resaltado; **el TECLADO lo maneja
el MOTOR**; clic/hover → `commit` /`setActiveIndex`). Los labels del motor (`WordsBlockMenuEntry`)
son INGLÉS → re-etiquetados a castellano en el componente con `ts()` + fallbacks. Posición:
`--_words-slash-x/y` (cae debajo del caret). DEUDA: el posicionador soma **no hace flip↑** (caret
muy al fondo → el menú roza el borde; cap 20rem + scroll interno).
- `8c2a4d511` **FIND/REPLACE** (`palabras-find.svelte`, Ctrl+F): `Words.FindReplace` da SOLO
estado+métodos (findQuery/findMatches/currentMatchIndex + case/word/regex + next/prev/replace/
replaceAll), **NO open ni posición** → el chrome pone **Ctrl/⌘F** (listener keydown `capture:true` ,
abre solo si el editor tiene foco — el motor NO intercepta Ctrl+F) + panel FIJO arriba-derecha
(`[data-words-find-replace]{position:fixed}`); Esc/✕ cierra (el `{#if open}` desmonta → limpia
query+highlights). El **resaltado en el doc lo pone el MOTOR** (`< mark data-words-find-match > `,
decoración F1) al hacer `setFindQuery` .
Los 3 cableados en TODOS los modos (`{#if contentEl}` en `palabras.svelte` ), verificados en Chrome
real headless (Playwright: el pane MCP congela rAF; gotcha = colocar una **Selection REAL**
programática antes de disparar bubble/slash).
### DÓNDE RETOMAR (P0 restante de edición — todos MOTOR-LISTOS = cablear)
1. **saveas UI** (F3.3): `api.exportContent('json'|'html'|'md')` ya existe — falta la affordance
(botón/menú de descarga). Barato, cierra F3.3.
2. **Bubble F2.4** : tipografía de rango tras un overflow del bubble. Marcas paramétricas vía
`applyCommand({type:'toggleMark'|'addMark', mark:{type:'fontSize'|'fontFamily'|'sub'|'sup', …}})`
— comprobar la forma exacta en `WordsCommand` .
3. **Menciones @** (F4.6): 2º plugin sobre `Words.SlashMenu` , trigger «@» (mismo patrón que slash).
4. **A11y del chrome** (F3.6): atajo abrir panel del bloque activo, focus-trap/return, announce.
Luego F4 (resize de tablas por arrastre · touch/móvil · demos v2 + salir de guards DG-10) y F5 (gama
alta, 0%: historia por DELTAS [hoy undo/redo = snapshots], colaboración, comentarios, export DOCX/
PDF). Análisis de completion: memoria del proyecto + `PLAN-EJECUCION.md` (F0-F5).
### Reglas de proceso (vigentes)
- Índice git COMPARTIDO entre sesiones → SIEMPRE `git reset -q` + `git add` de rutas EXPLÍCITAS de
palabras; push a ** `gita` ** (remoto único), rama `alpha-0.1-sec-dom` . NO commitear `web/routes/alpha` .
- Verificación de menús/floating/selección = **Chrome real** (Playwright headless tiene frame loop; el
Browser pane MCP congela rAF con esta página → menús a (0,-800)). Colocar Selection REAL antes de disparar.
- `check` de la rama = baseline (~76 err AJENOS de `menubar-provider.test` /`grafito`/`connection` +
un clon lexical en `tmp/` ); el filtro es «0 errores NUEVOS en palabras». Ojo: los «exit 0» de un
`npm run check | tail/grep` son del pipe, no de svelte-check — mirar el conteo de errores.
- Dev server de verificación: config `verify` (autoPort) — esta sesión en `localhost:64130` .
---
## ESTADO 2026-07-17 — MENUBAR v4 MENÚ-NATIVO ✅ (estudio ratificado + implementado)
Sesión larga sobre el **modo `panelMode='menubar'`** . Tres intentos previos
(v1 ventana flotante · v2 panel entero colgado · v3 cuerpos de tab pelados)
**RECHAZADOS** por el usuario («el mismo puto panel»). Se hizo un **estudio de
usabilidad multi-agente** ([`ESTUDIO-MENUBAR.md`](./ESTUDIO-MENUBAR.md)) y el
usuario ratificó la **opción B (menú-nativo + presets inline)** . Implementado,
verificado en Chrome real y empujado a `gita` .
### La doctrina (de `ESTUDIO-MENUBAR.md` )
Ningún editor serio mete formularios en menús. **Menú** = elecciones discretas
(radio/check con estado, submenús); **panel/superficie** = lo que se escribe o
arrastra. Patrón «enumerar-y-escapar»: presets como radios + verbo «…» que abre
UN campo. La barra además MUESTRA el estado (valor actual al final del submenú).
### Commits (rama `alpha-0.1-sec-dom` , remoto `gita` )
- `e2172aec4` — **v4 menú-nativo** . `palabras-element-menu.svelte` (NUEVO):
dado `api` +`scheme`+`tab`+`onEdit`, renderiza el schema del bloque como items
de `Menubar.Content` : `pills` →RadioGroup (inline en Contenido con
GroupHeading; Sub con valor al final en Diseño), `shadow` →Sub Ninguna/S/M/L,
`toggle` →CheckboxItem, `slider` →Sub de presets+«Personalizado…», resto→verbo
«Etiqueta…»→`onEdit`. Read/write COPIADO de `fieldControl` (mismos comandos;
shadow/customWhen fieles). Panel gana prop `menuField` = renderiza UN campo
con su control real, pelado. Menubar: entradas de elemento pasan de
`Menubar.Panel` a `Menubar.Content` ; props `scheme` +`onEditField`; fuera
`blockPanel` . Shell abre el escape.
- `6c10e7837` — **color inline + popover opaco** . Color de texto/Fondo (1 prop)
= submenú de **muestras de la paleta** (chip+nombre RadioItem + Personalizado…),
NO superficie. El escape pasa de Dialog MODAL a **Popover no-modal** anclado a
la barra (`customAnchor` en `Popover.Content` , no en root) y **opaco** (mata el
frost de cristal en `[data-depth]` ).
- `83c7c9ed9` — **Enter confirma+cierra** el popover (los text confirman en vivo
por `oninput` ; `onkeydown` Enter en input de 1 línea hace blur+cierra; textarea
conserva salto).
- `eb62b6f8d` — **el popover bloquea la barra de debajo** : Popover `modal` +
`Popover.Overlay` TRANSPARENTE (`rgba(0,0,0,0)`) — captura el puntero (mata el
hover-open/click-through de debajo) SIN oscurecer; clic fuera cierra
(`interactOutsideBehavior="close"`).
### Verificado en Chrome real (capturas MIRADAS + valores)
[Encabezado]=menú real (NIVEL radios H1-HC + Texto…/Enlace…; `aria-haspopup=menu` ,
NO dialog); [Diseño]=menú con valores al final (Sombra Ninguna·Opacidad 100%·
Alineación —·Color de texto ▸ muestras) + verbos compuestos; picar H3→heading a
H3; «Enlace…»→popover opaco de 1 campo, Enter cierra con el valor, overlay
transparente bloquea la barra, clic fuera cierra.
### PENDIENTE (siguiente sesión) — cerrar «B pleno» + limpieza
1. **Descomponer «Tipografía…»** en submenús de preset **Interlineado ▸** y
**Tamaño ▸** (escriben visual `lineHeight` /`fontSize`; presets =
`PALABRAS_LEADING` y `sizeScale` del esquema) + «Tipografía…» verbo para el
resto del mega-control. Es lo que falta para B pleno (leading/size viven
DENTRO del compuesto y ahora salen solo como verbo).
2. **Podar código muerto v3** : el branch `menuTab` de `palabras-panel.svelte`
(prop + rama en `panelContent` ) y su CSS `[data-palabras-menu-tab]` ya no los
usa nadie (se fue `blockPanel` ). Borrar; conservar `tabContenido/tabDiseno/
tabAvanzado/blockFoot` (los usa la rama flotante/acoplada).
3. **Documento en menubar** : sigue soltando su `docPanel` (superficie) — no era
la queja, pero por coherencia con v4 valorar menú-ificarlo (Márgenes/Texto/
Paleta como submenús + escapes). Confrontar antes.
4. **Gap DEL COMPONENTE Menubar** (sesión ajena, no parchear aquí): con un
Content/Panel abierto, clic directo trigger→trigger puede pedir 2º clic.
### ⚠️ Notas de proceso
- Índice git COMPARTIDO con otra(s) sesión(es) → SIEMPRE `git reset -q` + `git
add` de rutas explícitas; NO commitear `web/routes/alpha` ni ficheros del
componente `menubar` (soma/eidos) — son de la sesión que lo construye.
- La OTRA sesión edita el componente `menubar` → dispara HMR en MI dev server
(mismo árbol): remonta el demo y **resetea `panelMode` a 'floating'** a mitad
de verificación. Re-armar estado por dispatch DOM; no culpar al cableado.
- Verificación de menús/popover = **Chrome real** (claude-in-chrome); el Browser
pane congela rAF y el ethereal no posiciona (menús a (0,-800)).
- `.svelte.ts` /CSS: el disk-cache del navegador solo lo busta **Ctrl+Shift+R** .
- Límite de sesión de agentes tocado hoy (workflow del estudio cortado; síntesis
hecha a mano desde `journal.jsonl` ); reset ~3:20 Madrid.
---
## ESTADO 2026-07-16 — §6 COMPLETA: element-específicos + `doc` v2 (palanca #3 ) ✅
Sesión larga ejecutando la ** §6 de `ESTUDIO-PANELES.md` **: el diseño-específico por