# V01.1 — Navegación móvil y franja contextual Primera entrega de la [arquitectura responsive V01](propuesta-navegacion-responsive-v01.md), 21 de octubre de 2026. V01 sigue parcialmente pendiente: esta entrega solo modifica la composición por debajo de 768 px. ## Comportamiento implementado - Cabecera móvil compacta: menú global, marca, búsqueda y cuenta. La búsqueda reutiliza estado, filtrado y destinos actuales, sin consultar activos/personas. - Franja sticky con compañía, sección actual y botón Secciones; nombre completo accesible y tooltip para texto truncado. No hay 21 enlaces apilados antes del contenido. - Sheet global con destinos, compañías y configuración; Sheet contextual con los 21 destinos, contadores, cambio de compañía y edición existentes. Una raíz modal y una presentación activa; el cambio contextual → global conserva modalidad sin apilar Sheet. - Destinos con BrowserLink nativo, `aria-current` y estilos de Button; botones para acciones. Enter navega, Espacio conserva la interacción nativa de enlaces. Se verificaron Ctrl+clic y clic central abriendo otra pestaña, sin cerrar el menú original ni cambiar su URL. - Escape/cierre devuelve foco al disparador; navegación ordinaria lo traslada al contenido. Cancelar edición de compañía desde el menú devuelve foco a Secciones. Base UI conserva el trap y el bloqueo de fondo; no se implementan manualmente. - Enlace Saltar al contenido al inicio del teclado, con destino `main` real y separación del bloque sticky. Scroll vertical principal único; scroll propio en menús extensos y tabla horizontal cuando lo requiere. - Cruzar a 768 px cierra el menú y devuelve foco visible; volver a móvil no reabre menús. Apertura efímera, sin nuevas preferencias. Las barras de escritorio, el colapso manual 228/72, la secundaria de 240, los filtros, paginación, rutas y permisos permanecen con sus contratos anteriores. La edición usa la acción ya disponible en la ficha: no se inventa un permiso ni se amplía acceso. No cambian `inventory=1100`, `dashboard=1200` ni `useCompactDetail`; V01.2–V01.4 quedan pendientes. ## Componentes y decisiones `CompaniesWorkspace` compone `WorkspaceMobileNavigationProvider`, salto al contenido, sidebar y cabecera sobre el scroll existente. `WorkspaceMobileSheet` encapsula popup, título, cierre traducido y foco; el consumidor aporta contenido. Los controles de modalidad pertenecen a Base UI. `WorkspaceNavigationContent` comparte destinos globales entre escritorio y móvil. `useCompanyNavigationEntries` concentra los 21 destinos contextuales; `CompanySectionNavigation` comparte presentación y contadores. `CompanyContextBar` y `CompanyNavigationSheet` contienen las responsabilidades móviles; `CompanyHeader` conserva el encabezado desktop extraído del componente anterior. `WorkspaceSearch` conserva una sola consulta local; `WorkspaceSearchContent` comparte input/resultados entre las presentaciones. No duplica consultas remotas ni crea otro motor. El catálogo semántico propio incorpora MenuIcon de Tabler. No se modifica vendor ni se añaden dependencias. Los estilos nuevos se limitan al shell móvil, sticky y separación de foco. El breakpoint de 768 es el existente; no se introducen 920/1160/1660 ni observadores de capacidad. Los enlaces de navegación usan las variantes públicas de Button sin el comportamiento de teclado de un botón no nativo. ## Geometría medida Mismo entorno sintético, cuatro pantallas y siete resoluciones antes/después: 28 geometrías por fase. Se esperó a carga, fuentes y transiciones. No son wireframes. | Resolución | Activos: Y de main antes → después | Ancho main antes/después | Tabla útil antes/después | | --- | --- | --- | --- | | 320×640 | 1496,31 → 106 | 320 | 286 | | 390×844 | 1429,66 → 106 | 390 | 356 | | 768×1024 | 88 → 88 | 300 | 249 | | 1024×768 | 88 → 88 | 556 | 505 | | 1366×768 | 88 → 88 | 898 | 847 | | 1440×900 | 88 → 88 | 972 | 921 | | 1920×1080 | 88 → 88 | 1452 | 1401 | A tamaño normal, cabecera/franja miden 57/49 px efectivos incluidos bordes. Ambos móviles cumplen `main.y <= 128` y muestran título sin scroll. No hay overflow horizontal del documento en la matriz; la tabla conserva su scroll propio. Dashboard/directorio comienzan tras la cabecera compacta, sin franja de compañía. La escasa capacidad de tablet a 768 continúa como deuda de V01.2, no se presenta como corregida. ## Validación ejecutada Se preparó una única instancia desechable con `scripts/visual-audit.py`: no había archivo de sesión reutilizable. Login real de usuario ordinario, compañía y activo sintéticos, servicios/puertos propios. Las pruebas visuales bloquean escrituras HTTP; altas y ediciones se cancelan. No se accede a datos reales ni se retiran contenedores anteriores ajenos. Al terminar, el preparador retiró su entorno y eliminó la sesión privada; las evidencias permanecen sin credenciales. Pruebas de componentes: nuevos casos es/en en `apps/web/src/app.test.tsx` y `companies-page.test.tsx`, con 21 href únicos, estado activo, nombres accesibles y menús cerrados sin compañía. Ambos casos pasan. No dependen de clases para simular interacciones; teclado/modalidad se comprueban en Chromium. Se amplía `scripts/visual-audit-ui.test.py`, usando el mismo cliente MCP y preparador, sin otro framework. El directorio de salida es configurable y restringido a `.artifacts/playwright/`: ```bash METIS_PLAYWRIGHT_STORAGE_STATE=.artifacts/playwright/authenticated-ID/session.json \ METIS_UI_AUDIT_DIRECTORY=.artifacts/playwright/v01-1/after \ python3 scripts/visual-audit-ui.test.py ``` Sustituir ID por la sesión activa, manteniendo el preparador abierto. La suite comprueba geometría, 21 destinos y último enlace por teclado, Tab/Shift+Tab/Espacio/Enter/Escape, retorno de foco, rutas y Atrás/Adelante, clics modificados, transferencia entre menús, búsqueda, sticky, resize, cuenta/idioma y edición cancelada. Incluye regresiones V02, V03, V06 y V09. Se espera al foco final de la primitiva tras atravesar sus guardas, no a una espera fija. **Resultado final:** nueve pruebas MCP pasan en 288,506 s. Después se amplió el caso de teclado con un ciclo inverso de 26 pulsaciones Shift+Tab y se repitió ese caso completo: pasa en 25,263 s. En ambos sentidos se mantiene el foco en el Sheet y se alcanza el último destino. Logs: `technical/visual-ui.log` y `technical/visual-keyboard.log`. Se simula un nombre largo mediante respuestas GET interceptadas, sin guardarlo. A 320 px conserva el presupuesto de 106 y no desborda. En 320×360 se alcanza el último enlace y el cierre permanece visible. La ampliación de fuente raíz al 200 % mantiene el ancho sin overflow y aumenta main.y a 210 px: excepción justificada al presupuesto nominal por ampliación de texto. Se conserva contenido y scroll; no se fuerza un alto fijo recortando textos. El intento de zoom real con atajos de Chromium headless no cambió devicePixelRatio. No se declara comprobado zoom real 200/400 %: ampliar fuente y probar viewport de 320 son comprobaciones distintas. También quedan pendientes Cmd+clic en macOS, lector de pantalla, modo oscuro completo y combinaciones de muchos roles/compañías. El usuario ordinario no recibe enlace de administración de usuarios; el comportamiento administrativo conserva su condición existente. ## Comprobaciones técnicas | Comprobación | Resultado | | --- | --- | | Typecheck dirigido compañías y web | Pasa | | Biome de los archivos TS/TSX/JSON modificados | Pasa | | Espaciado ESLint dirigido | Pasa tras corregir cuatro separaciones | | Nuevos tests de componentes es/en | 2 pasan | | `pnpm build` | Pasa; conserva aviso de chunk grande | | `pnpm typecheck` | Falla en vendor `calendar.tsx:165`, contrato locale de react-day-picker; sin modificar vendor | | `pnpm lint` | Falla con 15 errores en código ajeno de fotos/procesos/migraciones; además avisos de assets de skills | | `pnpm check` | Falla global; archivos modificados comprobados separadamente | | `pnpm test` con BD aislada | Falla en dos expectativas antiguas de `companies-page.test.tsx`: «Personas (1)» y texto antiguo sobre acceso de persona. No se corrigen fuera de alcance; la suite global no se declara aprobada | La BD de tests se crea en otro contenedor y se elimina al terminar. Se conserva el log de Turbo para distinguir paquetes ejecutados/cacheados y no atribuir validación a suites que su fallo haya interrumpido. Los fallos citados estaban documentados antes de V01.1; se contrastan con los archivos implicados, no se supone que todo error nuevo sea previo. La consola de la suite final no registra errores ni warnings. En la matriz previa apareció un 404 accesorio de favicon; no bloquea navegación. Durante desarrollo se corrigieron una expansión indebida del separador móvil y expectativas/esperas de las propias pruebas. Los intentos parciales no sustituyen el resultado final. No se ignora un fallo de la aplicación para hacer pasar una prueba. ## Evidencias y documentación Evidencias locales, excluidas de Git: - [Baseline](../.artifacts/playwright/v01-1/before/measurements.json) y [matriz posterior](../.artifacts/playwright/v01-1/after-layout/measurements.json). - [Últimos resultados por escenario](../.artifacts/playwright/v01-1/after/summary-latest.json), [historial de mediciones interactivas](../.artifacts/playwright/v01-1/after/measurements.json), [ciclo de teclado ampliado](../.artifacts/playwright/v01-1/keyboard/measurements.json), [consola](../.artifacts/playwright/v01-1/after/console.json) e [índice de capturas con dimensiones y SHA-256](../.artifacts/playwright/v01-1/evidence-index.json). - [Activos 320 antes](../.artifacts/playwright/v01-1/before/assets-320.png), [después](../.artifacts/playwright/v01-1/after-layout/assets-320.png), [Sheet contextual](../.artifacts/playwright/v01-1/after/navigation-company-menu-390.png), [global](../.artifacts/playwright/v01-1/after/navigation-global-menu-390.png) y [búsqueda](../.artifacts/playwright/v01-1/after/navigation-search-320.png). - Logs de comandos en `.artifacts/playwright/v01-1/technical/`. Las capturas se abrieron y examinaron; geometría, snapshot y comportamiento son pruebas distintas. Para compartir evidencias, entregar solo `v01-1/`; no incluir `authenticated-*`, sesiones ni credenciales. Se actualizan DESIGN.md y componentes de interfaz para esta entrega, conservando los estados de los otros hallazgos. Skills consultadas: `ux-navigation` dirige orientación y separación de ámbitos; `shadcn` aporta contratos Sheet/Base UI y primitivas existentes; `frontend-design` conserva identidad y jerarquía; composición y reglas React justifican modelos compartidos, estado efímero y suscripción responsive acotada. La CLI informativa shadcn falló por DNS; se consultaron sus [docs oficiales de Sheet](https://ui.shadcn.com/docs/components/base/sheet) y [Dialog de Base UI](https://base-ui.com/react/components/dialog), contrastadas con el código instalado. No se aplicaron auditores no instalados ni se instalaron herramientas.