- Added `INVENTORY_DETAIL_BUDGET` and `RESOURCE_DETAIL_BUDGET` to define layout parameters for inventory and resource detail views. - Implemented `useContextualDetail` hook to manage visibility and focus transitions between inline and overlay modes. - Created `contextual-detail-layout` module to handle budget calculations and state management for contextual details. - Updated documentation to reflect changes in asset and resource handling, ensuring consistent UI behavior across different viewports. - Conducted regression tests to validate functionality and ensure no existing features were broken during the implementation.
57 KiB
V01 — Propuesta de navegación y layout responsive
Fecha de la propuesta: 21 de octubre de 2026. Arquitectura B híbrida aprobada para entregas incrementales. V01 resuelto en los escenarios verificados de V01.1–V01.4, con cierre el 22 de octubre de 2026.
Seguimiento: V01.1 — navegación móvil y franja contextual implementa la primera entrega, conservando escritorio y umbrales existentes. V01.2 — navegación responsive implementa después la política de navegación por capacidad en portátil/tablet. V01.3 — detalle de activos y V01.4 — recursos y cierre integral completan los inventarios y su regresión. El resto del documento conserva alternativas, mediciones originales y arquitectura objetivo. Las tablas originales describen la propuesta, no sustituyen las mediciones posteriores de las entregas.
1. Resumen ejecutivo
Recomiendo conservar los dos ámbitos de navegación, pero cambiar su presentación según la capacidad disponible: barra global expandida en escritorio amplio, compacta en portátil y superpuesta en ventanas estrechas; navegación de compañía permanente cuando quepa junto al contenido y superpuesta cuando reduzca su capacidad operativa. Una franja contextual mantiene visibles la compañía y la sección, incluso con ambas navegaciones cerradas.
El inventario decide entre tabla con panel y tabla con detalle modal por ancho de su propio contenedor, después de descontar navegaciones y rellenos. Contraer únicamente el menú global mejora el problema, pero no lo resuelve: a 1100 px la tabla pasa de 237 a 393 px con panel abierto, todavía insuficiente para comparar activos.
La intervención conserva React, Tailwind, Base UI, shadcn/ui, @repo/rdx-ui, iconografía, datos y rutas. No propone una barra horizontal de 21 destinos ni una nueva biblioteca. La arquitectura elegida combina B —superposición contextual— con el colapso global de A y una franja de orientación de C. No se necesita una refactorización general del shell.
Las cifras de propuesta son presupuestos de diseño pendientes de validación en una implementación. Las mediciones de la sección 4 pertenecen a la aplicación actual y están separadas de esas estimaciones. En esta tarea solo se crea este documento; no cambia DESIGN.md ni el estado de otros hallazgos.
2. Problema y evidencias
Se reutilizó el entorno sintético existente de scripts/visual-audit.py, con sesión privada de usuario ordinario en authenticated-vmpuj3f2. No se prepararon compañías, usuarios, bases ni servicios nuevos. El cliente MCP directo abrió inicialmente el acceso sin autenticar; para la matriz se utilizó el cliente stdio del preparador, con su archivo de sesión montado en modo lectura en un Chromium efímero. No se imprimieron cookies ni credenciales. Se bloquearon las peticiones HTTP de escritura desde el navegador.
Se navegaron seis escenarios en ocho resoluciones: 48 geometrías y 48 capturas, además de tres capturas y comprobaciones específicas de colapso/desplazamiento. Se esperó al workspace, a la desaparición de la carga visible, a las fuentes y a las animaciones finitas; se dejaron transcurrir dos frames antes de medir. Se abrieron explícitamente las capturas citadas de móvil, tablet y panel en escritorio. No se atribuyen resultados a un prototipo: las imágenes muestran exclusivamente la interfaz vigente.
Resultados principales:
- Las medidas antiguas de compañía se reproducen: inicio de
mainen Y=1429,66 a 390 px y Y=1496,31 a 320 px. La navegación contextual tiene 21 destinos y ocupa 1014 px de alto en ambos móviles. - A 768 px,
mainmide 300 px exteriores; descontando borde/rellenos quedan aproximadamente 251 px. El viewport interior de tabla mide 249 px. Esta diferencia de 2 px explica las distintas cifras sin contradecir la auditoría. - A 1100 px, tabla/panel miden 237/320 px. La tabla tiene 808 px de contenido desplazable: el viewport representa aproximadamente el 29 % de ese ancho.
- A 1440 px la tabla con panel mide ahora 551 px, frente a 495 px a 1366. No sustituir todas las cifras por la referencia anterior de 1366.
- Dashboard y directorio también acumulan navegación global en móvil: comienzan en Y=296 y Y=344 respectivamente.
- No se detectó scroll horizontal del documento en los 48 casos. Sí existe desplazamiento horizontal interno de tabla: es deliberado y debe conservarse.
- Tras desplazar el contenido de Activos a la vista en móvil, búsqueda global y sección activa quedan por encima del viewport. El problema afecta a la orientación además del espacio.
Evidencias: Activos a 390, Activos a 768, panel a 1440, panel a 1100, global contraída a 1100, contenido a 320 tras scroll.
3. Arquitectura actual
Composición, dimensiones y desplazamiento
CompaniesWorkspace — flex columna; desde shell, flex fila y h-dvh
├─ WorkspaceSidebar — 228 px / 72 px; móvil: bloque w-full anterior al contenido
│ ├─ marca
│ ├─ nav global + compañías, scroll propio en escritorio
│ └─ configuración y colapso, pie fuera del scroll del nav
└─ contenedor flex-1 min-w-0 overflow-y-auto
├─ WorkspaceHeader — 88 px escritorio; 74 px medidos en móvil
└─ CompanyDetail embedded — grid
├─ identidad compañía — columna izquierda / bloque superior móvil
├─ nav compañía — 240 px / bloque superior móvil
└─ main — minmax(0,1fr), p-6 / p-4
└─ inventario: listado + gap 24 + panel clamp(320px,24vw,400px)
shell=768px, inventory=1100px, dashboard=1200px son media queries de viewport. El @container de fichas no gobierna el reparto tabla/panel. useCompactDetail consulta (max-width:1099px): CSS y React duplican el umbral y conocen el viewport, no la capacidad restante.
La secundaria usa un grid fijo de 240 px. En móvil cambia de área, pero cada enlace sigue a ancho completo: envolver el nav con flex no compacta sus 21 destinos. En escritorio la secundaria comparte el desplazamiento del contenido; no tiene scroll independiente. El panel no es sticky ni tiene altura propia limitada: el ejemplo de 1100 px ocupa unos 3853 px de alto, con sus secciones abiertas. La tabla mantiene las acciones ancladas a la derecha mediante position:sticky; la cabecera de tabla solo es sticky en la variante layout="fill", no universalmente. Cabecera global e identidad no son sticky actualmente.
Navegación, DOM, estado y foco
El orden DOM es global → cabecera → identidad → navegación contextual → main; el teclado atraviesa enlaces anteriores al contenido. WorkspaceNavigationButton compone BrowserLink para destinos, con aria-current="page" y estado visual derivado del ámbito. CompanyDetail usa enlaces cuando recibe navegación por rutas y botones en el modo local. Mantener esa distinción, sin introducir menús de aplicación ARIA para una lista normal de enlaces.
La barra global persiste su booleano con metis-desk:sidebar-collapsed en localStorage del origen, compartido entre cuentas de ese navegador; se confirmó su recuperación al recargar. No hay preferencia equivalente para la compañía. La URL controla compañía, sección y fichas; búsqueda y plantilla están conectadas a la query. main key={tab} remonta al cambiar de sección. No existe aquí un contrato explícito general de foco al nuevo título ni un enlace de salto al contenido.
En activos, seleccionar la zona no interactiva de una fila mantiene la selección contextual local; el nombre enlaza a la ficha completa. Una URL directa de activo abre AssetDetailPage. En recursos hay diferencias en la relación entre selección y ruta. No unificar estas semánticas como efecto lateral del layout. Hay que probar cada controlador. El detalle compacto existente usa diálogos; Base UI resuelve modalidad y foco. El cambio de composición necesita coordinar ese contrato, no simplemente ocultar un aside con CSS.
4. Matriz de geometrías observadas
Todas las dimensiones siguientes son píxeles CSS, redondeadas a la unidad. Global expandida, una compañía sintética, columnas iniciales. main incluye rellenos; tabla útil es clientWidth de su contenedor horizontal. «—» indica que el elemento no existe o no ocupa ancho lateral, no una prueba pendiente.
Dashboard
| Viewport | Global | Nav. compañía | main | Tabla útil | Panel / diálogo | H previa | Búsqueda / compañía / sección visibles |
|---|---|---|---|---|---|---|---|
| 1920×1080 | 228 lateral | — | 1692 | 768 | — | 88 | sí / — / — |
| 1440×900 | 228 lateral | — | 1212 | 528 | — | 88 | sí / — / — |
| 1366×768 | 228 lateral | — | 1138 | 491 | — | 88 | sí / — / — |
| 1100×800 | 228 lateral | — | 872 | 782 | — | 88 | sí / — / — |
| 1024×768 | 228 lateral | — | 796 | 706 | — | 88 | sí / — / — |
| 768×1024 | 228 lateral | — | 540 | 450 | — | 88 | sí / — / — |
| 390×844 | 390 apilada | — | 390 | 324 | — | 296 | sí / — / — |
| 320×640 | 320 apilada | — | 320 | 254 | — | 344 | sí / — / — |
Compañías
| Viewport | Global | Nav. compañía | main | Tabla útil | Panel / diálogo | H previa | Búsqueda / compañía / sección visibles |
|---|---|---|---|---|---|---|---|
| 1920×1080 | 228 lateral | — | 1692 | 1642 | — | 88 | sí / — / — |
| 1440×900 | 228 lateral | — | 1212 | 1162 | — | 88 | sí / — / — |
| 1366×768 | 228 lateral | — | 1138 | 1088 | — | 88 | sí / — / — |
| 1100×800 | 228 lateral | — | 872 | 822 | — | 88 | sí / — / — |
| 1024×768 | 228 lateral | — | 796 | 746 | — | 88 | sí / — / — |
| 768×1024 | 228 lateral | — | 540 | 490 | — | 88 | sí / — / — |
| 390×844 | 390 apilada | — | 390 | 356 | — | 296 | sí / — / — |
| 320×640 | 320 apilada | — | 320 | 286 | — | 344 | sí / — / — |
Resumen de compañía
| Viewport | Global | Nav. compañía | main | Tabla útil | Panel / diálogo | H previa | Búsqueda / compañía / sección visibles |
|---|---|---|---|---|---|---|---|
| 1920×1080 | 228 lateral | 240 | 1452 | — | — | 88 | sí / sí / sí |
| 1440×900 | 228 lateral | 240 | 972 | — | — | 88 | sí / sí / sí |
| 1366×768 | 228 lateral | 240 | 898 | — | — | 88 | sí / sí / sí |
| 1100×800 | 228 lateral | 240 | 632 | — | — | 88 | sí / sí / sí |
| 1024×768 | 228 lateral | 240 | 556 | — | — | 88 | sí / sí / sí |
| 768×1024 | 228 lateral | 240 | 300 | — | — | 88 | sí / sí / sí |
| 390×844 | 390 apilada | 390 apilada | 390 | — | — | 1430 | sí / sí / sí |
| 320×640 | 320 apilada | 320 apilada | 320 | — | — | 1496 | sí / sí / sí |
Inventario de activos
| Viewport | Global | Nav. compañía | main | Tabla útil | Panel / diálogo | H previa | Búsqueda / compañía / sección visibles |
|---|---|---|---|---|---|---|---|
| 1920×1080 | 228 lateral | 240 | 1452 | 1401 | — | 88 | sí / sí / sí |
| 1440×900 | 228 lateral | 240 | 972 | 921 | — | 88 | sí / sí / sí |
| 1366×768 | 228 lateral | 240 | 898 | 847 | — | 88 | sí / sí / sí |
| 1100×800 | 228 lateral | 240 | 632 | 581 | — | 88 | sí / sí / sí |
| 1024×768 | 228 lateral | 240 | 556 | 505 | — | 88 | sí / sí / sí |
| 768×1024 | 228 lateral | 240 | 300 | 249 | — | 88 | sí / sí / sí |
| 390×844 | 390 apilada | 390 apilada | 390 | 356 | — | 1430 | sí / sí / sí |
| 320×640 | 320 apilada | 320 apilada | 320 | 286 | — | 1496 | sí / sí / no |
Ficha completa de activo
| Viewport | Global | Nav. compañía | main | Tabla útil | Panel / diálogo | H previa | Búsqueda / compañía / sección visibles |
|---|---|---|---|---|---|---|---|
| 1920×1080 | 228 lateral | 240 | 1452 | 1353 | — | 88 | sí / sí / sí |
| 1440×900 | 228 lateral | 240 | 972 | 873 | — | 88 | sí / sí / sí |
| 1366×768 | 228 lateral | 240 | 898 | 799 | — | 88 | sí / sí / sí |
| 1100×800 | 228 lateral | 240 | 632 | 533 | — | 88 | sí / sí / sí |
| 1024×768 | 228 lateral | 240 | 556 | 457 | — | 88 | sí / sí / sí |
| 768×1024 | 228 lateral | 240 | 300 | 201 | — | 88 | sí / sí / sí |
| 390×844 | 390 apilada | 390 apilada | 390 | 308 | — | 1430 | sí / sí / sí |
| 320×640 | 320 apilada | 320 apilada | 320 | 238 | — | 1496 | sí / sí / no |
Inventario con consulta contextual
| Viewport | Global | Nav. compañía | main | Tabla útil | Panel / diálogo | H previa | Búsqueda / compañía / sección visibles |
|---|---|---|---|---|---|---|---|
| 1920×1080 | 228 lateral | 240 | 1452 | 977 | 400 panel | 88 | sí / sí / sí |
| 1440×900 | 228 lateral | 240 | 972 | 551 | 346 panel | 88 | sí / sí / sí |
| 1366×768 | 228 lateral | 240 | 898 | 495 | 328 panel | 88 | sí / sí / sí |
| 1100×800 | 228 lateral | 240 | 632 | 237 | 320 panel | 88 | sí / sí / sí |
| 1024×768 | 228 lateral | 240 | 556 | 505 | 922 diálogo | 88 | sí / sí / sí |
| 768×1024 | 228 lateral | 240 | 300 | 249 | 691 diálogo | 88 | sí / sí / sí |
| 390×844 | 390 apilada | 390 apilada | 390 | 356 | 358 diálogo | 1430 | sí / sí / sí |
| 320×640 | 320 apilada | 320 apilada | 320 | 286 | 288 diálogo | 1496 | sí / sí / no |
En la columna «H previa», el escenario contextual utiliza la posición inicial del inventario antes de pulsar la fila. Las coordenadas posteriores al clic y al desplazamiento automático se conservan separadas en el JSON. El ancho de navegación apilada es el del bloque superior, no una reserva lateral. En dashboard/directorio no hay compañía ni sección contextual.
Altura y acceso al contenido
En desktop el encabezado precede al contenido con 88 px; la navegación queda al lado. En móvil el bloque global ocupa 222/270 px, seguido de cabecera de 74 px. En compañía se añaden identidad y 1014 px de navegación contextual. Las Y anteriores son la altura previa acumulada hasta main, no una medición aislada del nav.
Desde una URL ya cargada, dashboard/directorio requieren cero activaciones para ver su título en las ocho resoluciones; compañía también en seis tamaños desde 768 px. En 390/320 se necesita desplazamiento para alcanzar main, sin activación previa de un menú. Se ejecutó una operación scrollIntoViewIfNeeded por tamaño y el contenido quedó visible; esto no significa un único gesto físico ni mide tiempo de usuario. Abrir el panel/detalle contextual requirió una pulsación en una celda no interactiva de la fila, en los ocho tamaños. Acceso por teclado completo y coste en tabulaciones no se midieron en esta matriz.
Al cargar compañía: búsqueda global e identidad visibles en las ocho resoluciones; sección activa visible en siete, fuera de la primera pantalla en 320 px. Al desplazar Activos: en 390 la búsqueda queda en Y=−921 y la sección activa en Y≈−515; en 320, Y=−1223 y Y≈−799. Son posiciones asentadas tras desplazamiento, no geometrías transitorias. La matriz de panel registra también el desplazamiento provocado al pulsar la fila: sus Y no deben reemplazar las medidas iniciales sin panel.
La consola de la matriz autenticada terminó con 0 errores y 0 avisos. El acceso inicial del cliente directo sin sesión produjo respuestas de autenticación; no se contabilizan como fallo visual de la matriz autenticada.
5. Alternativas estudiadas
A — Dos navegaciones colapsables
Conservar global 228/72 y añadir modo compacto de compañía. Ventaja: destinos frecuentes a una pulsación y transición próxima al modelo actual. Inconveniente: 21 iconos contextuales, varios semánticamente próximos, dependen demasiado de reconocimiento y ayudas. Dos raíles siguen reservando ancho en tablet. En móvil no deben volver a apilarse todos los destinos: esta alternativa necesitaría además una superposición.
Persistir intención de expansión, mantener nombre accesible y tooltip al hover/foco. El tooltip ayuda a interpretar, pero no sustituye la etiqueta disponible en una navegación abierta. No persistir colapsos automáticos producidos por una ventana pequeña. El panel aún requiere regla de capacidad propia. Descartada como solución completa; se conserva su raíl global, ya implementado y con pocos destinos principales.
B — Navegación contextual superpuesta
Global permanente cuando quepa; compañía como Sheet lateral modal cuando su columna perjudique al contenido. Un botón «Secciones de [compañía]» junto al destino actual abre todos los enlaces en una lista etiquetada y desplazable. Identidad y sección se mantienen fuera de la superposición. Apertura/cierre, bloqueo de fondo y foco se delegan a Base UI.
Recupera los 240 px de la secundaria cuando se oculta. Añade una activación para cambiar de sección si estaba cerrada, a cambio de mostrar etiquetas y jerarquía completa. En escritorio amplio mantiene navegación permanente. Es coherente con 21 destinos y con el detalle modal existente. Es la base recomendada.
C — Navegación contextual integrada en cabecera
Sustituir la secundaria por un selector de sección próximo al título y a un selector de compañía. Recupera 240 px sin una columna permanente, incluso en escritorio amplio. Una barra horizontal con 21 enlaces requiere overflow, oculta destinos y confunde navegación contextual con las pestañas de plantilla del inventario. No recomendar esa barra.
Un botón con popover de enlaces es viable para ventanas amplias y pocas opciones; para el conjunto actual necesita scroll, grupos y adaptación a modal. Un Select de formulario no conserva naturalmente abrir en nueva pestaña ni clic modificado. Descartada como arquitectura principal por descubribilidad y navegación frecuente; se aprovecha su franja contextual de compañía/sección. No se añade un selector de compañía que duplique estados: cambiar compañía abre el selector global existente o sus enlaces.
6. Comparación de alternativas
Juicios de diseño, sin pruebas de usabilidad de alternativas y sin puntuación total. Recuperación de ancho calculada a partir de dimensiones actuales; complejidad y riesgos son valoraciones cualitativas.
| Criterio | A: dos colapsables | B: contextual superpuesta | C: contextual integrada |
|---|---|---|---|
| Espacio recuperado | Global: 156 px; secundaria: depende del raíl nuevo | 240 px contextuales; global puede recuperar 156 o 228 px | 240 px contextuales; añade banda superior |
| Jerarquía global/compañía | Clara expandida; dos raíles la debilitan | Clara con identidad permanente y dos activadores diferenciados | Clara si no se mezcla selector de compañía y sección |
| Cambio de sección | Una activación si visible | Una con secundaria fija; dos desde menú cerrado | Dos desde selector cerrado |
| Orientación | Etiquetas ocultas en compacto | Compañía y sección siempre visibles | Buena con franja persistente |
| Teclado | Muchos enlaces antes del contenido; requiere salto | Lista de enlaces en modal, retorno y salto | Popover/lista viable; Select limita enlaces |
| Móvil | Precisa mecanismo adicional | Resuelve navegación sin preceder al contenido | Selector viable; barra extensa inadecuada |
| Tablet | Dos raíles siguen restando | Cede ancho a la tarea | Cede ancho; apertura frecuente |
| Escritorio amplio | Familiar | Mantiene secundaria fija | Pierde exploración simultánea de destinos |
| Panel contextual | No resuelto por sí solo | Admite capacidad independiente | Admite capacidad independiente |
| Implementación | Media: segunda navegación compacta y adaptación móvil | Media: Sheet y una política responsive | Media: reubicar todos los destinos y adaptación popup/modal |
| Reutilización | Alta global; nueva secundaria de iconos | Alta: enlaces actuales, Sheet y diálogos | Media/alta: enlaces actuales; nuevo selector de destinos |
| Regresiones | Etiquetas, tooltips, anchos y estados de dos raíles | Foco, resize y scroll de overlay | Historial/clic modificado si se usa un Select |
| Mantenimiento | Dos colapsos y fallback móvil | Un modelo de destinos con presentaciones distintas | Manejo de overflow/subniveles y presentaciones |
| DESIGN.md | Conserva identidad, requiere revisar §4/10 | Conserva identidad, requiere aprobar cambio móvil §4/10 | Conserva identidad; revisar patrón de navegación y pestañas |
Elegir B híbrida porque preserva navegación directa donde hay capacidad y evita transformar la navegación de compañía en un vocabulario de iconos. El coste adicional de apertura queda explícito; no se afirma que produzca tiempos de tarea inferiores sin probarlo.
7. Arquitectura recomendada
Modelo y presupuestos propuestos
Separar preferencia de modo efectivo. Preferencia global actual expandida/contraída; secundaria inicialmente automática, con acción explícita «Ocultar navegación» cuando está fija y «Fijar navegación» cuando haya capacidad. Persistir solo esa intención si se aprueba, bajo clave propia versionada; no almacenar compañía, sesión, filtros o selección en esa clave. Los overlays siempre arrancan cerrados. La adaptación automática nunca sobrescribe la preferencia guardada.
Presupuestos iniciales para validar: lista operativa de referencia 800 px, secundaria 240, global expandida 228/compacta 72, rellenos desktop 48, gap tabla/panel 24, panel 320–400. Los valores existentes se conservan; 800 es una hipótesis de diseño, fundamentada en los 808 px de tabla mínima observada con columnas iniciales. Permite un pequeño scroll interno, pero evita reservar solo 237 px para comparar. No se exige ese mínimo a una pantalla cuyo ancho físico sea inferior; allí la tabla recibe toda la anchura disponible.
Reglas iniciales, expresadas en capacidad del shell y no en nombres de dispositivo:
- Si caben 72 + 48 + 800 = 920 px, global compacta disponible; por debajo, global superpuesta. No añadir un raíl de 72 px a un móvil de 320.
- Fijar secundaria solo si el espacio posterior a global admite 240 + 48 + 800 = 1088 px. Con global compacta, el umbral nominal equivale a 1160 px de shell.
- Global expandida automática en ancho suficiente para secundaria y tabla/panel mínimo: 228 + 240 + 48 + 800 + 24 + 320 = 1660 px. La preferencia contraída continúa respetándose por encima. Estas sumas son un criterio de partida, no un breakpoint vigente.
- Por debajo de esos presupuestos, la expansión global solicitada se presenta temporalmente como overlay sin reducir el contenido. Fijar la secundaria se deshabilita si no cabe y explica el motivo. No permitir estados permanentes que vulneren el presupuesto para ganar una preferencia visual.
- Evaluar panel después del modo de navegación; abrirlo no provoca automáticamente colapsos del shell. Así se evita una reacción circular navegación ↔ panel.
Presentación por capacidad
| Configuración representativa | Global | Compañía | Contenido y panel |
|---|---|---|---|
| 1920, escritorio amplio | Expandida o 72 según preferencia | 240 fija, ocultable | Tabla y panel si cumplen su regla; con valores actuales sí |
| 1440/1366, portátil | Raíl 72; expansión en overlay | 240 fija, ocultable | Tabla completa; detalle modal por defecto con secundaria fija |
| 1100/1024, portátil estrecho/tablet | Raíl 72 | Overlay | Prioridad a tabla; detalle modal si no cabe al lado |
| 768, tablet | Overlay | Overlay | Toda el área útil; sin dos menús superpuestos simultáneamente |
| 390/320, móvil | Overlay | Overlay | Contenido inmediato; tabla con scroll interno y detalle modal |
La tabla es la aplicación estimada de las reglas, no una implementación medida. Dashboard/directorio no reservan secundaria de compañía. Las fichas completas ocupan el ancho de contenido y no abren un panel paralelo adicional.
Cabecera, contexto y dimensiones verticales
Conservar cabecera desktop de 88 px. Proponer 56 px para cabecera compacta: menú global, marca compacta, acceso a búsqueda y cuenta; la campana sin servicio no debe desplazar controles necesarios, pero cambiar su función queda fuera de V01. Por debajo de la capacidad de un campo de búsqueda, usar botón «Buscar en Metis Desk» que abre la misma búsqueda limitada a compañías/destinos; no promete búsqueda transversal de activos. En anchos suficientes, mantener el input.
Añadir franja contextual nominal de 48 px en páginas de compañía: identidad con avatar pequeño, nombre accesible completo, sección y botón «Secciones». En móvil de 320 px puede ocupar dos filas hasta 72 px para que no desaparezca la sección. Nombre largo truncado visualmente con acceso al texto completo; no truncar el nombre accesible. El título de listado mantiene su receta y CTA. Editar compañía pasa a una acción contextual explícita; no eliminarla al retirar la gran identidad lateral móvil.
Cabecera y franja contextual sticky dentro de un único scroll principal; en desktop, la secundaria tiene scroll propio en el alto restante. No introducir un segundo scroll vertical en el listado normal. El scroll horizontal permanece dentro de la tabla. Ajustar scroll-padding-top/scroll-margin-top para no tapar foco, anclas o título con el bloque sticky. Con zoom/ventana de poca altura, permitir que la búsqueda abierta se desplace internamente y no añadir filas permanentes de controles.
Resize y recuperación
Cambiar modo no cambia URL, filtros, orden, página, selección ni entidad abierta. Mantener montada la tabla y sus nodos de scroll. El detalle puede cambiar de presentación conservando ID y lectura; no mantener a la vez una copia de panel y otra de diálogo con controles activos. No persistir coordenadas o anchos observados.
Si un overlay pasa a navegación fija al ensanchar: cerrar modalidad, liberar scroll/inert y llevar foco al enlace equivalente si estaba dentro. Si continúa superpuesto, conservar apertura. Al estrechar una navegación fija, no abrir un modal sin acción del usuario: si el foco queda en un enlace que desaparece, moverlo a «Secciones» o «Menú global». La selección no cambia. Si el foco estaba en tabla, no moverlo. Una única superposición de navegación puede estar abierta: abrir la otra cierra la primera con transferencia de foco al nuevo destino, sin salto intermedio al fondo.
8. Wireframes por tamaño
Esquemas de diseño, no capturas ni componentes implementados. Las cajas representan responsabilidades, no nuevas tarjetas. G = global; C = compañía.
Escritorio amplio, navegación y panel
┌─ G 228 ──────┬──── cabecera 88: búsqueda / cuenta ────────────────────┐
│ Metis Desk ├──── compañía · Activos · Secciones / editar compañía ──┤
│ Inicio │ C 240 │ Activos [Nuevo activo] │
│ Compañías │ Resumen │ pestañas / buscar │
│ Catálogos │ Personas │ ┌── tabla ≥800 ─────┐ ┌─ panel 320–400 ┐│
│ Compañía │ Activos ● │ │ nombre … acciones │ │ activo [Cerrar]││
│ … │ Recursos │ │ filas │ │ resumen/datos ││
│ Ajustes │ … scroll │ └─ paginación ──────┘ └───────────────┘│
└──────────────┴─────────────┴─────────────────────────────────────────┘
Portátil, inventario
┌ G72 ┬── cabecera: búsqueda / cuenta ────────────────────────────────┐
│logo ├── compañía · Activos · [Secciones] ──────────────────────────┤
│icon │ C240, ocultable │ Activos [Nuevo activo] │
│icon │ destinos │ buscar / filtros / columnas │
│icon │ Activos ● │ tabla: todo el espacio disponible │
│ … │ … │ paginación │
│ │ │ seleccionar → diálogo contextual │
└─────┴────────────────┴─────────────────────────────────────────────┘
Ocultar C puede habilitar panel si cumple capacidad; no se abre solo por ocultarla. La consulta seleccionada conserva su estado abierto/cerrado.
Tablet, navegación contextual abierta
┌ [Menú global] Metis / Buscar / cuenta ──────────────────────────┐
├ compañía · Activos [Secciones] ────────────┤
│ ┌─ Sheet C, título y [Cerrar] ──┐ fondo inerte │
│ │ compañía │ Activos [Nuevo activo] │
│ │ Resumen │ buscar / tabla │
│ │ Activos ● │ paginación │
│ │ todos los destinos, scroll │ selección → detalle modal │
│ └──────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
A 1024 puede haber raíl global; a 768 no se reserva. El botón dibujado es el caso de 768. El detalle modal y el menú no se abren simultáneamente por una misma acción.
Móvil, navegación cerrada
┌ [Menú] Metis [Buscar] [Cuenta] ┐
│ compañía sintética [Secciones] │
│ Activos │
├ Activos [Nuevo activo] ┤
│ pestañas / búsqueda │
│ columnas / orden │
│ tabla ↔ scroll propio, acciones │
│ paginación │
└──────────────────────────────────────┘
Seleccionar fila abre detalle modal; enlace de nombre conserva la ficha completa. Las acciones principales siguen en el contenido, no ocultas en navegación.
Móvil, navegación contextual abierta
┌ Secciones de compañía [Cerrar]┐
│ compañía sintética │
│ [Cambiar compañía] │
│ Resumen │
│ Personas (0) │
│ Activos (1) ← actual │
│ Recursos (0) │
│ … todos los destinos, scroll interno │
│ [Editar compañía] │
└──────────────────────────────────────┘
fondo modal bloqueado; global cerrada
Anchura del Sheet limitada al viewport; en 320 px puede ocuparlo completo. Botón de cierre visible y títulos etiquetados. Cambiar compañía cierra el contextual y abre navegación global en su bloque de compañías; no apila dos modales.
9. Contratos de interacción
| Acción/situación | Contrato propuesto |
|---|---|
| Tab / Shift+Tab | Orden DOM lógico. Primer acceso «Saltar al contenido»; después cabecera/contexto, navegación fija y contenido. En modal, recorrido contenido en la primitiva Base UI; no alcanzar el fondo. |
| Enter | Activa enlaces de destino y botones. Clic modificado/medio conserva comportamiento de enlace. |
| Espacio | Activa botones de apertura/cierre; en enlaces mantiene comportamiento nativo de página, sin emular un botón. |
| Abrir navegación | Botón con nombre, aria-expanded, relación con contenido; Sheet con título. Foco en enlace activo; si no existe, primer destino. No introducir búsqueda de secciones sin necesidad. |
| Escape / Cerrar / fondo | Cierra la navegación sin cambiar ruta y devuelve foco al disparador vigente. Si desapareció por resize, destino equivalente visible en cabecera; no al body. |
| Elegir destino ordinario | Navega mediante BrowserLink, cierra overlay y enfoca título principal de destino con tabIndex=-1; no devolver foco al disparador al mismo tiempo. Una única política de foco, apoyada en finalFocus de Base UI. |
| Elegir destino con Ctrl/Cmd/Shift/medio | Mantiene semántica del enlace; no cerrar ni mover el foco del documento original si no navega en él. Respetar target y download. |
| Sección activa | aria-current="page", estilo y texto. Lista contextual con nombre «Secciones de [compañía]» y global con nombre distinto. No marcar dos destinos del mismo ámbito como actuales. |
| Búsqueda global | Conservar ámbito actual y Escape. En compacto se abre mediante botón; foco en búsqueda y retorno al botón. Cerrar navegación antes de abrir búsqueda, sin cambiar ruta. V07/búsqueda de tildes queda fuera. |
| URL directa / recarga | Derivar identidad y sección de las rutas actuales; overlays cerrados. No derivarlas del último elemento pulsado ni de localStorage. |
| Atrás / Adelante | Conservar contratos de History API y filtros; apertura/cierre de menús no crea entradas. Cerrar una ficha conserva su retorno interno actual. |
| Cambio de compañía | Usar destino existente de resumen, actualizar contexto y cerrar overlay; no arrastrar filtros específicos o IDs de la compañía anterior. No diseñar aquí restauración nueva por compañía. |
| Panel lateral | Complementary con nombre y acción de cierre. Foco no atrapado; acción explícita «Ir al detalle» si se necesita acceso directo por teclado. Selección de fila no roba foco al ratón. |
| Detalle compacto | Dialog con título, foco inicial pertinente y retorno a fila/acción; fallback a búsqueda local. Escape cierra consulta, mantiene selección contextual cuando el consumidor lo permita. |
| Resize con detalle | Si foco estaba dentro del detalle que migra, trasladarlo a su equivalente; si estaba en tabla, no abrir modalidad por el mero resize: contraer la consulta y mantener selección con «Ver detalle». No remontar tabla. |
| Scroll / zoom | Fondo bloqueado solo durante modalidad; panel fijo no lo bloquea. Scroll interno de navegación larga; sin scroll horizontal del documento. A 200/400 %, composición según ancho CSS efectivo, foco no oculto bajo sticky. |
Reutilizar el Sheet instalado, basado en @base-ui/react/dialog, y sus APIs públicas. No escribir focus trap, listeners Escape globales o gestión manual de inert. El SheetContent vendor permite composición y props de Popup; el cierre traducido se aporta desde el consumidor si el cierre vendor tiene literal inglés. No editar vendor. La documentación de Dialog de Base UI respalda delegar modalidad y foco; las APIs concretas deberán contrastarse con los tipos instalados durante la implementación.
10. Reglas para tabla y panel contextual
Capacidad y mínimo operativo
Medir el content box estable del contenedor exterior del inventario, antes de repartir las columnas. Sea W ese ancho, T=800, G=24 y P el panel propuesto. Mostrar panel lateral solo si W ≥ T + G + P. El panel puede crecer de 320 a 400 usando el espacio sobrante, conservando W − G − P ≥ T. Umbral inicial mínimo: 1144 px de inventario. Bordes interiores de tabla reducen aproximadamente 2 px el viewport: las pruebas deben distinguir ancho de columna/listado de clientWidth de tabla.
La referencia de 800 procede del ancho de 808 observado con icono, nombre, plantilla, estado, sede y acciones. No garantiza que todas las columnas opcionales quepan; siguen desplazándose internamente. Validar con nombres largos, texto en inglés, 10/50 filas y combinaciones de columnas antes de fijar el umbral. No usar el ancho total dinámico de todas las columnas como condición: elegir más campos no debe provocar oscilación de presentación. Este mínimo es específico del inventario de referencia; otro listado deberá justificar su presupuesto.
CSS, ResizeObserver y fuente de verdad
- Solo container queries: suficientes para cambiar distribución, separaciones y controles visuales; insuficientes para decidir qué árbol semántico modal montar, transferir foco y conservar lectura.
- Solo ResizeObserver: puede decidir todo, pero trasladar todos los detalles visuales a React añade trabajo innecesario.
- Combinación recomendada: un único hook de capacidad del inventario con un
ResizeObserversobre el contenedor exterior estable; publica un modo discretoinline/overlay. React monta una presentación de detalle. El grid ySelectionPanelconsumen ese modo mediante atributo/variante explícita, sin volver a decidirlo coninventory:o un segundo umbral. Container queries se reservan al responsive interior de tabla, franja y detalle. ResizeObserver informa del tamaño del elemento; las container queries adaptan estilos de descendientes. No sustituir esto por medirwindow.innerWidth.
Leer anchura sin publicar cada píxel: notificar solo cambios de modo, limpiar el observer al desmontar y comenzar en modo seguro compacto hasta tener medida. No observar la columna de tabla que encoge al abrir panel. Con contenedor estable, no hace falta histéresis de partida; si se reproduce oscilación por scrollbar, corregir geometría/gutter antes de añadir umbrales diferentes. Un solo origen para constantes de capacidad; evitar duplicarlas en CSS y hook.
La política del shell se evalúa sobre su contenedor raíz, independiente de la apertura del detalle. Puede apoyarse en una suscripción discreta a sus límites estables; si la implementación usa medición de elemento, una sola medición por frontera real, nunca un observer por enlace. No crear un gestor responsive universal ni un contexto global de cada píxel.
Estimación de ganancia, no medición de solución
Con rellenos actuales y política propuesta: 1920 deja aproximadamente 1403 px interiores con ambas navegaciones; panel de 400 y gap 24 dejan unos 979 para listado, equivalente al escritorio amplio actual. A 1440/1366 con global de 72 y secundaria de 240 quedan unos 1079/1005 interiores; el detalle se abre en diálogo y el listado dispone de todo ese ancho. A 1100/1024 con global compacta y contextual superpuesta quedan unos 979/903; también diálogo. A 768 con ambas superpuestas y p-4 quedan unos 736; a 390/320, 358/288. Descontar bordes de tabla al comparar con las mediciones.
Ocultar manualmente secundaria en 1440 deja aproximadamente 1319 px interiores: puede habilitar tabla/panel conservando el mínimo. No cerrar/abrir panel automáticamente por cambiar columnas. Preservar búsqueda, plantilla, orden local, página, fila seleccionada y scroll horizontal/vertical durante cambios de modo, manteniendo estable la instancia de tabla. La restauración tras navegar a otra página, V05, sigue siendo otra tarea.
11. Impacto en componentes existentes
| Unidad | Cambio futuro acotado |
|---|---|
CompaniesWorkspace |
Coordinar modo global, cabecera compacta, franja y scroll principal; conservar contratos de datos y rutas. |
WorkspaceSidebar y preferencia |
Reutilizar destinos; separar intención guardada y modo efectivo; presentación permanente/Sheet sin duplicar enlaces focusables. |
WorkspaceHeader |
Activador global y búsqueda compacta; mantener ámbito de búsqueda y cuenta. |
WorkspaceNavigationButton |
Conservar BrowserLink, nombres y activo; tooltip real al foco en raíl. |
CompanyDetail |
Extraer navegación contextual por responsabilidad, mantener 21 destinos/contadores y edición; grid permanente u overlay. |
AssetInventoryPage y controlador |
Referencia estable de capacidad, presentación única de detalle, conservación del estado local y tabla. |
ResourcesPage y controlador |
Aplicar política equivalente tras comprobar diferencias de selección/ruta; presupuesto propio validado con fixture de recurso. |
SelectionPanel |
Consumir modo/layout explícito, eliminando dependencia rígida de viewport solo en consumidores migrados. Buscar todos los usos antes de cambiar contrato. |
useCompactDetail |
Sustituir usos de activos/recursos por capacidad; retirar solo si búsqueda completa demuestra que no quedan consumidores. |
AssetSelectionPanel, diálogos y contenido de detalle |
Reutilizar presentación y acciones; foco y lectura al migrar. La ficha completa permanece independiente. |
apps/web/src/global.css |
Tokens de capacidad/alto compacto y variantes propias después de aprobación; no alterar colores ni vendor. dashboard no cambia por V01. |
| Traducciones es/en | Activadores, cierre, fijar/ocultar, etiquetas y explicaciones breves de capacidad. |
Posibles extracciones: navegación contextual de compañía y overlay global en sus ficheros dentro del módulo, y hook genérico de capacidad con consumidores reales activos/recursos en rdx-ui. Mantener rutas, consultas y DTO en módulos. No introducir un megacomponente con flags para global/compañía/listado/modal. No hace falta envolver Sheet si la composición propia del módulo basta.
12. Plan de implementación incremental
- Aprobar presupuestos y contratos. Confirmar arquitectura B híbrida, hipótesis 800/1144, reglas de preferencias y franja sticky. Retener las mediciones como baseline. Sin aprobación no se aplica la propuesta.
- Navegación móvil y franja contextual. Extraer lista de destinos sin cambiarlos; Sheet global/contextual, títulos, foco, salto al contenido y edición de compañía. Conservar escritorio existente en esta primera entrega. Verificar ocho tamaños, 21 destinos, es/en y URLs directas. Reversión: revertir esta entrega, sin migraciones.
- Composición de portátil/tablet. Modo global compacto y secundaria por capacidad; intención persistida separada de modo, resize y overlays. Depende del paso 2. Probar localStorage ausente, inválido y bloqueado, estados expandidos/contraídos y regreso a escritorio. Revertible sin tocar datos; ignorar nueva preferencia si se retira.
- Capacidad tabla/detalle de activos. Introducir hook sobre inventario, presentación única y sincronía foco/scroll. Eliminar la doble decisión CSS/media query para este consumidor. Comparar a ambos lados del umbral y con navegaciones ocultas/fijas. No cambiar rutas de ficha ni selección local.
- Consumidor equivalente de recursos. Migrar su composición con fixture sintético autorizado, sin cambiar semántica de negocio; comprobar selección en URL/local y cierre. No darlo por validado por compartir componente con activos.
- Regresión y documentación normativa. Playwright, tests dirigidos y comprobaciones globales según AGENTS para cambio transversal. Revisar todos los consumidores, dark mode, zoom, foco y consola. Solo entonces actualizar DESIGN.md y los patrones con el comportamiento aprobado e implementado.
Pruebas unitarias de contratos: modo en límites y cambios de capacidad, preferencias y fallbacks, apertura/cierre y retorno de foco; no tests que repliquen clases CSS. Pruebas de navegador: tabla/scroll sin remount, selección y URL estables, editor anidado, búsqueda global, compañías con nombres largos y varias compañías. Build/tipos/lint/tests no se ejecutan para este documento porque no se modifica código; serán necesarios al implementar.
Separación de alcance: V01 no ajusta ayuda/progreso de asistentes (V04), estado al volver de ficha (V05), búsqueda (V07), selector de columnas (V08), detalle vacío (V10) ni estados de carga (V12). Las correcciones previas V02/V03/V06/V09 se conservan y se someten a regresión si sus componentes resultan afectados.
13. Criterios de aceptación
Son criterios propuestos para implementación futura; ninguno se declara superado por la auditoría actual.
| Criterio | Comprobación Playwright y origen |
|---|---|
| Contenido inmediato en móvil | A 390/320, navegación cerrada, main.y ≤ 128 px tras carga. Presupuesto: cabecera compacta 56 + contexto de hasta 72. Título del listado visible sin scroll; no depender de contar gestos. Validar primero con textos sintéticos actuales y luego nombres largos/es/en. |
| Orientación persistente | Compañía y sección visibles al cargar y tras scroll de contenido; accesibles completas aunque el texto visual se trunque. En ficha, sección Activos más nombre del activo en contenido. |
| Sin desbordamiento del shell | documentElement.scrollWidth ≤ clientWidth + 1 en las ocho resoluciones, con y sin overlay/panel, nombres largos y zoom. Margen de 1 px por redondeo CSS. No exigirlo al contenido interior desplazable de tabla. |
| Todos los destinos | Comparar href/nombre de los 21 enlaces de compañía antes/después, incluidos últimos destinos; navegar uno por grupo, URL directa, recarga y Atrás/Adelante. Repetir con varias compañías y roles disponibles. |
| Presupuesto tabla/panel | Cuando inline, ancho de listado ≥800 px y viewport de tabla aproximadamente ≥798 px, sujeto a bordes reales; listado + gap + panel ≤ W. Cuando no quepa, overlay y tabla usando todo W. Validar ±1 px del límite 1144 y sidebar expandida/compacta/oculta. |
| Tablet con contenido útil | A 768 con valores propuestos, contenido interior cercano a 736 px; no reservar las columnas 228+240. Esta cifra es objetivo calculado y debe ajustarse si cambian bordes/scrollbars, conservando el principio de ancho completo. |
| Escritorio amplio conservado | A 1920, ambas navegaciones y panel utilizables; tabla no menor que baseline ≈977 px con tolerancia de 2 px por bordes. No aplicar colapso automático innecesario. |
| Cambio de modo sin pérdida | Filtrar, ordenar, paginar cuando haya datos, desplazar tabla, seleccionar y redimensionar: mismos valores, ID y nodo de tabla; scroll conservado salvo clamp natural al crecer viewport. No generar entradas de historial por resize. |
| Modalidad y foco | Tab/Shift+Tab contenidos, Escape/cierre devuelven foco, fondo bloqueado; cambio de destino enfoca título. Resize libera modalidad y mantiene foco visible según §9; no existen dos copias focusables de navegación/detalle. |
| Acciones y enlaces | Enter en enlaces, Espacio en botones; Ctrl/Cmd/medio/target conservados. Enlaces de relación y acciones de fila sin interacciones anidadas. |
| Preferencias | Recarga conserva intención manual; estrechar/ampliar no escribe colapso automático. localStorage inaccesible no rompe navegación. |
| Accesibilidad ampliada | Zoom real 200/400 %, reducción de movimiento, teclado completo, comprobación con lector y contrastes de estados nuevos. No certificar WCAG global por superar solo la matriz geométrica. |
El mínimo 800 y los límites derivados quedan sujetos a aprobación y validación de contenido representativo; no convertirlos en norma definitiva sin esa comprobación.
14. Riesgos y cuestiones abiertas
Decisiones que requieren aprobación antes de desarrollo:
- Arquitectura B híbrida y prioridad automática del contenido sobre la expansión permanente de navegación.
- Presupuesto inicial de tabla 800, panel 320–400 y límites derivados 920/1160/1660; validar con datos densos antes de fijarlos.
- Franja contextual sticky de 48–72 px y cabecera compacta de 56; aceptar un botón de búsqueda en móvil conservando su ámbito actual.
- Si persistir la intención de fijar/ocultar navegación de compañía o mantenerla solo durante la sesión; recomendación: empezar en memoria y añadir persistencia únicamente si se confirma su utilidad. Mantener desde el inicio la preferencia global existente.
Riesgos técnicos: pérdida de foco al cambiar árbol modal, scroll bloqueado después de resize, reinicio de tabla al reorganizar layout, desincronización CSS/React, clases inventory: supervivientes y diferencias de rutas entre activos/recursos. Mitigar con una única decisión por frontera, composición estable y pruebas específicas.
Limitaciones de validación: una compañía y un activo sintéticos, sin inventarios grandes ni recursos; no se probaron usuarios con otros roles, muchas compañías, traducción inglesa, nombres arbitrariamente largos, zoom real o lector de pantalla en esta tarea. No existe prototipo para medir aprendizaje o tiempos. Esos límites no impiden confirmar V01, pero sí fijar números definitivos o declarar accesibilidad completa.
La documentación de componentes contiene descripciones históricas que ya no coinciden con todas las APIs instaladas, por ejemplo «no hay Avatar ni DropdownMenu»; se contrastó con código real y no se corrigió fuera de alcance. El patrón de listados describe navegación escritorio/modal móvil vigente: tras aprobar e implementar habrá que precisar su nueva condición por capacidad, sin modificar ahora la norma.
Actualizaciones futuras de DESIGN.md: §4 Layout y navegación, §6 Fichas (panel/diálogo), §9 Accesibilidad (salto y foco), §10 Responsive y densidad, §11 deuda/validación. En §3 solo registrar tokens propios nuevos si se introducen. Actualizar además las secciones Shell global y Panel lateral de componentes, el apartado responsive de listados y la descripción de umbral en rutas; no cambiar los href ni contratos HTTP.
15. Evidencias y referencias
Artefactos de esta tarea
- Mediciones de los 48 casos: rectángulos de navegación, main, tabla, panel/diálogo, visibilidad, scroll y overflow.
- Interacciones adicionales: colapso, recuperación tras recarga y desplazamiento móvil.
- Consola autenticada.
- Índice de capturas: dimensiones y SHA-256.
- Snapshots de seis escenarios y capturas por escenario/ancho en
.artifacts/playwright/v01-design/. Los artefactos están excluidos de Git; su enlace es local. Para revisión en otro equipo hay que entregar este directorio de evidencias, sin incluir ningún directorioauthenticated-*ni archivos de sesión. El documento conserva las medidas principales para ser legible sin imágenes.
Para reproducir: reutilizar una sesión sintética activa del preparador siguiendo Playwright MCP, abrir los seis destinos del informe de ese entorno, usar las ocho resoluciones de §4 y medir tras carga/fuentes/transiciones. Una sesión caducada requiere volver a autorizar/preparar el entorno correspondiente; no utilizar datos reales como sustituto. Los orquestadores temporales de medición se conservan en el directorio de evidencias para inspección; no son infraestructura de producción.
Fuentes locales realmente consultadas
- AGENTS.md, DESIGN.md, auditoría visual, V01, listados, diálogos, rutas, componentes, procedimiento MCP y preparador.
- Tokens efectivos, CompaniesWorkspace, WorkspaceSidebar, WorkspaceHeader, WorkspaceContent, WorkspaceNavigationButton, preferencia global y controlador de workspace en sus directorios actuales.
- CompanyDetail, su controlador, rutas reales, BrowserLink.
- Inventario de activos, controlador, panel, ficha completa, ResourcesPage y su controlador como consumidor equivalente.
- useCompactDetail, SelectionPanel, EntityTable/EntityTableContent y API pública de Sheet. Vendor consultado, sin modificaciones.
Skills y aplicación al análisis
| Skill leída | Referencias aplicables consultadas | Influencia concreta |
|---|---|---|
| frontend-design | Principios, planificación/wireframes y revisión contenidos en SKILL.md | Mantener identidad Inter/verde/turquesa/rojo y jerarquía operativa; evitar decoración o nuevo sistema visual. |
| shadcn | rules/composition.md, rules/base-vs-radix.md, rules/styling.md |
Sheet/Dialog existentes, títulos accesibles, composición render de Base UI y tokens semánticos. No aplicar sus procedimientos de regeneración vendor, incompatibles con AGENTS y esta tarea. |
| vercel-composition-patterns | architecture-avoid-boolean-props.md, state-context-interface.md |
Separar destinos/estado de su presentación; evitar megacomponente con múltiples flags y conocimiento de negocio en rdx-ui. |
| vercel-react-best-practices | client-event-listeners.md, rerender-derived-state-no-effect.md |
Suscripciones por frontera, modo discreto y preferencia separada del modo derivado; no duplicar estado remoto ni añadir SWR por el ejemplo de la skill. |
No se han aplicado skills inexistentes ni recomendaciones específicas de Next.js/RSC a esta SPA. Las recomendaciones estéticas generales ceden ante los patrones de Metis. Las tres referencias externas de §9/10 se consultaron para contrastar viabilidad; las medidas y conclusiones sobre Metis proceden del repositorio y del navegador.
Verificación de entrega
Se revisaron estructura, coherencia de wireframes/contratos, enlaces locales, evidencias y diff. La comparación con el estado inicial conserva los cambios previos del sprint sin alterarlos. Única modificación versionable de esta tarea: este documento. No se modificaron componentes, CSS, tokens, rutas, API, autenticación, vendor ni DESIGN.md. V01 y los demás hallazgos conservan su estado previo.
Seguimiento de implementación V01.3
La propuesta anterior y sus mediciones se conservan como historia. V01.3 implementa para activos el presupuesto de §9: caja exterior W ≥ 1144 px, tabla 800, separación 24 y panel 320–400. A 1100 de viewport la tabla útil pasa de 634 a 978 px al presentar el detalle mediante diálogo. A 1660, W=1143: se utiliza overlay incluso con viewport amplio. La apertura/cierre no cambia la capacidad, y el resize nunca abre un modal. El shell V01.2 conserva sus decisiones. V01 permanece parcialmente resuelto; recursos y la regresión final de V01.4 quedan pendientes de una nueva instrucción.
Seguimiento V01.4 — Cierre integral
El 22 de octubre de 2026, V01.4 migra recursos a capacidad propia: tabla 640 px, gap 24, panel 320–400 y mínimo W=984. Activos conserva 800/24/320–400 y mínimo W=1144. Ambos consumen useContextualDetail de rdx-ui; consultas, permisos, rutas y operaciones permanecen en sus módulos. Se conserva la selección en URL y el cierre compacto de recursos, distintos de activos.
La regresión final ejecuta 28 métodos Playwright MCP autenticados, siete de recursos y los 21 anteriores, en las once resoluciones requeridas. Todos pasan; no hay errores ni warnings de consola registrados ni overflow horizontal global en las matrices. Las 22 geometrías de activos coinciden con V01.3. Se corrigen los retornos de foco detectados, incluida la desaparición externa de un recurso, y se verifican V02/V03/V06/V09 sin rediseñarlos.
V01 queda resuelto en los escenarios verificados de V01.1–V01.4. Se conservan la propuesta histórica y sus límites. Los fallos globales preexistentes de typecheck/lint/check y dos expectativas SSR de compañías siguen identificados como fallos; checks dirigidos y build pasan. No cambia el estado de los hallazgos fuera de alcance. Datos, evidencias, contratos y retirada de la instancia sintética se detallan en el informe de cierre.