/* Pegamento de layout, y nada más.
   Regla del proyecto: acá NO hay vidrio, ni colores, ni sombras propias. Sólo posición y
   tamaño. Todo lo visual sale de los componentes de Vidrio o de sus tokens citados por
   nombre (var(--v-…)), jamás por valor. */

body { margin: 0; min-height: 100vh; }

/* ------------------------------------------------------------- el armazón */

/* Tres columnas sobre el mapa: menú, trabajo, operación. Los costados se pliegan a 0 y el
   mapa queda entero y libre —no hay barra de iconos residual, igual que en la consola de
   Jupiter Voice—. El ancho vive en dos variables para que plegar sea una sola transición
   y no cuatro reglas peleándose. */
.sp-armazon {
  --sp-izq: 0px;
  --sp-der: 0px;
  position: fixed;
  inset: 0;
  z-index: 1;
  display: grid;
  grid-template-columns: var(--sp-izq) minmax(0, 1fr) var(--sp-der);
  pointer-events: none;                 /* el fondo es el mapa: se panea a través */
  transition: grid-template-columns .16s ease;
}
.sp-armazon--izq { --sp-izq: 276px; }
.sp-armazon--der { --sp-der: clamp(340px, 26vw, 420px); }

/* Cada costado es una pila: las secciones se apilan de arriba abajo y la que manda —el
   menú, el panel— se queda con el alto sobrante. */
.sp-col { min-width: 0; overflow: hidden; padding: 14px; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 10px; }
.sp-col > * { pointer-events: auto; min-height: 0; }
.sp-armazon:not(.sp-armazon--izq) .sp-col--izq,
.sp-armazon:not(.sp-armazon--der) .sp-col--der { display: none; }

/* Cada tramo se queda clavado en SU columna. Sin esto, plegar un costado lo saca del flujo
   —`display: none` no ocupa celda— y los dos que quedan se corren una columna a la
   izquierda: el panel derecho aterrizaba en la columna del centro, con el ancho del centro,
   y tapaba el mapa entero. Es el panel raro que aparecia al contraer el menu. */
.sp-col--izq { grid-column: 1; }
.sp-centro   { grid-column: 2; }
.sp-col--der { grid-column: 3; }

/* Menú y panel son columnas altas: la cabeza y el pie quedan fijos y sólo rueda el cuerpo.
   Un panel que arrastra su encabezado al hacer scroll pierde el único ancla del turno. */
.sp-col .v-sidenav, .sp-panel { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.sp-col .v-sidenav__body, .sp-panel__cuerpo { overflow-y: auto; min-height: 0; }

.sp-panel__cabeza,
.sp-panel__cuerpo { padding: 14px 15px; }
.sp-panel__cabeza { display: flex; flex-direction: column; gap: 12px; border-bottom: 1px solid var(--v-edge-color); }
.sp-panel__pie { padding: 10px 15px; border-top: 1px solid var(--v-edge-color); }

/* El centro sólo existe cuando hay trabajo que mostrar: en la vista A va vacío y el mapa se
   ve completo. El scroll vive en la columna, pero el puntero sólo lo toma el lienzo — el
   aire de los costados sigue siendo mapa que se puede arrastrar. */
.sp-centro { overflow-y: auto; padding: 14px; box-sizing: border-box; }
.sp-centro__lienzo { width: min(100%, 640px); pointer-events: auto; }
/* La barra de salida se queda pegada arriba: si hay que rodar hasta el final del trabajo
   para encontrar cómo cerrarlo, no es una salida. */
.sp-centro__barra { position: sticky; top: 0; z-index: 3; }

/* Las asas de vuelta, cuando el lado está plegado. */
.sp-asa { position: fixed; top: 14px; z-index: 2; pointer-events: auto; }
.sp-asa--izq { left: 14px; }
.sp-asa--der { right: 14px; }

/* En pantalla chica los costados no comparten el ancho: se montan encima del mapa a lo alto
   y el trabajo ocupa la fila entera. */
@media (max-width: 900px) {
  .sp-armazon--izq, .sp-armazon--der { --sp-izq: 0px; --sp-der: 0px; }
  .sp-col { position: fixed; top: 0; bottom: 0; z-index: 2; width: min(330px, 88vw); }
  .sp-col--izq { left: 0; }
  .sp-col--der { right: 0; }
  .sp-centro { grid-column: 1 / -1; }
  .sp-centro__lienzo { width: 100%; }
}

/* El conmutador se puede desbordar horizontalmente antes que romper la línea. */
.sp-tabs { overflow-x: auto; }

/* En el panel, en cambio, NO se desborda: una pestaña cortada por el canto se lee como
   pantalla rota, y peor, se esconde. La píldora se parte en dos líneas y se ven las tres. */
/* Al partirse en dos lineas el estante deja de ser una pastilla de una fila y pasa a ser
   una caja alta; con el radio de pastilla la curva del canto cruza por encima de las
   pestanas de las esquinas y la seleccionada —que es la blanca— se ve salida del estante.
   Con el radio mediano el estante sigue siendo el del DS y ninguna pestana se le escapa. */
.sp-panel .v-tabs { display: flex; flex-wrap: wrap; row-gap: 2px; border-radius: var(--v-r-md); }

/* Mapbox GL es el fondo visible y táctil de toda la consola. No queda raster debajo, así
   que el fondo pintado de la raíz se apaga: lo que se ve detrás del vidrio es el mapa. */
:root[data-fondo] .v-root__bg { display: none; }

/* CERO SOMBRAS en las tarjetas —instrucción dura de Jose, repetida—. Es la ÚNICA
   desviación del design system en toda la consola, y se hace donde el propio sistema deja
   la perilla: los dos tokens de sombra. No se toca ni una regla de `.v-glass`, así que la
   receta, el tinte, el filo y los radios siguen siendo los del DS, byte por byte.
   Sobre un mapa `day` casi blanco, `0 26px 58px -24px rgba(0,0,0,.72)` dibujaba un halo
   sucio alrededor de cada panel; el volumen del vidrio ya lo da la refracción del canto,
   no la sombra —la galería «La superficie» lo dice con todas las letras.

   Va como sombra transparente y NO como `none`: el DS tiene reglas que componen el filo
   con la sombra en una sola lista —`box-shadow: inset 0 0 0 1px var(--v-hair), var(--v-shadow)`
   en el globo de ayuda—. Con `none` adentro esa lista deja de ser un `box-shadow` valido,
   el navegador descarta la declaracion entera y el globo pierde tambien su filo. Con una
   sombra de radio cero y alfa cero no se ve nada y la lista sigue siendo valida. */
:root[data-fondo] {
  --v-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
  --v-shadow-alta: 0 0 0 0 rgba(0, 0, 0, 0);
}

/* El mapa va TAL CUAL sale de Mapbox — la misma imagen que el playground de Standard con
   `theme: monochrome` (`day` en claro, `night` en oscuro). NINGUN `filter` toca el canvas:
   un brightness() encima es una segunda opinion sobre cartografia que Mapbox ya calibro,
   y es lo que producia el gris lavado. El `filter` computado debe ser `none` en los dos
   modos: es un chequeo de QA, no una preferencia. */
.sp-mapa-vivo { position: fixed; inset: 0; z-index: 0; }
.v-root__body { z-index: 1; pointer-events: none; }
.sp-mapa-vivo, .sp-mapa-vivo .mapboxgl-canvas-container, .sp-mapa-vivo .mapboxgl-control-container { pointer-events: auto; }
.sp-mapa-vivo .mapboxgl-canvas { cursor: grab; }
.sp-mapa-vivo .mapboxgl-canvas:active { cursor: grabbing; }
.sp-mapa-vivo .mapboxgl-ctrl-bottom-right { margin: 0 12px 12px 0; }
.sp-mapa-vivo .mapboxgl-ctrl-group {
  background: var(--v-tint-oscuro);
  box-shadow: var(--v-shadow);
  border: 1px solid var(--v-edge-color);
}
.sp-mapa-vivo .mapboxgl-ctrl button .mapboxgl-ctrl-icon { filter: invert(1); }
/* Los controles de Mapbox son suyos y viven fuera de `.v-root`, asi que no heredan la
   tipografia del sistema y salian en la de por defecto del navegador. Se les pasa la letra
   y nada mas: la caja, el color y los iconos siguen siendo los de Mapbox. */
.sp-mapa-vivo .mapboxgl-ctrl,
.sp-mapa-vivo .mapboxgl-ctrl button,
.sp-mapa-vivo .mapboxgl-ctrl-attrib,
.sp-mapa-vivo .mapboxgl-ctrl-attrib a { font-family: var(--v-font); }
.sp-capa-mapa { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
/* En móvil el mapa sigue vivo de fondo pero las marcas se van: los paneles apilados ocupan
   el ancho entero y las marcas sólo asoman entre tarjeta y tarjeta, que se lee como
   suciedad. La cola escrita del panel sigue diciendo lo mismo, y mejor. */
@media (max-width: 900px) { .sp-capa-mapa { display: none; } }

/* La capa de marcas no se recorta a ninguna banda: desde que las coordenadas son reales,
   una marca cae donde le toca en el mundo, y empujarla dentro de un recuadro la volvería a
   convertir en decoración. */
.sp-marca { position: absolute; transform: translate(-50%, -50%); pointer-events: auto; }

/* Centro del recuadro de video mediado. */
.sp-video { display: flex; align-items: center; justify-content: center; height: 100%; }


/* El mapa táctico de la vista D. Es un recuadro, no el fondo: acá el mapa SÍ es contenido
   —el «dónde» de un incidente concreto— así que vive dentro de un panel.

   `aspect-ratio` no es decoración: el raster se horneó a 760×480 y las marcas se ubican en
   porcentaje de ancho y de alto por separado. Si la caja se deforma, la proyección miente y
   el sitio cae en la casa del vecino. Por eso la relación se clava y la imagen va `cover`
   con el centro anclado, que es exactamente el centro del encuadre que pidió Mapbox.

   Cada encuadre tiene dos rasters Mapbox Standard monocromos: `night` para oscuro y
   `dawn` para claro. La geometría no cambia entre modos; sólo cambia la luz cartográfica. */
.sp-tactico {
  position: relative;
  aspect-ratio: 760 / 480;
  border-radius: var(--v-r-lg);
  border: 1px solid var(--v-edge-color);
  overflow: hidden;
  background-size: cover;
  background-position: center;
}
.sp-tactico > svg { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Dos trazos sobre el mismo camino: el tramo recorrido lleno y el que falta punteado.
   `non-scaling-stroke` va en el marcado —el viewBox está deformado a propósito— y acá sólo
   queda el grosor y el color, que salen de los tokens de Vidrio. */
.sp-ruta { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.sp-ruta--falta { stroke: var(--v-ink-faint); stroke-width: 2px; stroke-dasharray: 5 5; }
.sp-ruta--hecho { stroke: var(--v-activo); stroke-width: 3px; }
