/* Layout de sidebar + topbar + contenido (CLAUDE.md seccion 20).
   Requiere theme.css cargado antes.

   Rediseño 2026-08-07: contenido claro, sidebar oscuro. El sidebar es la
   UNICA superficie oscura del sistema -- ancla la navegacion, le da peso a
   la marca, y separa "donde estoy" de "que estoy haciendo" sin necesitar
   bordes gruesos. */

/* El sidebar y la topbar son los MISMOS en todas las pantallas: se les da
   nombre propio para que la transición entre páginas los deje quietos en
   vez de redibujarlos. La regla que activa todo esto vive en theme.css,
   que sí lo cargan todas las pantallas (incluida Cargas, que no usa este
   layout). */
.shell-sidebar {
  view-transition-name: shell-sidebar;
}
.shell-topbar {
  view-transition-name: shell-topbar;
}

::view-transition-group(shell-sidebar),
::view-transition-group(shell-topbar) {
  animation: none;
}
::view-transition-old(shell-sidebar),
::view-transition-new(shell-sidebar),
::view-transition-old(shell-topbar),
::view-transition-new(shell-topbar) {
  animation: none;
  mix-blend-mode: normal;
}

/* `minmax(0, 1fr)` y no `1fr`: el default de una pista de grilla es
   `min-width: auto`, asi que una tabla ancha ensancha la columna y arrastra
   toda la pagina hacia el costado. Con el minimo en 0 la columna se planta y
   el scroll horizontal queda adentro de la tabla, que es donde tiene sentido. */
.shell {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  min-height: 100vh;
}

/* --- Sidebar (superficie oscura) ---------------------------------------- */

.shell-sidebar {
  background: var(--sidebar-bg);
  color: var(--color-dark-text);
  padding: 0 0 12px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  z-index: 20;
}

.shell-sidebar .marca {
  padding: 18px 18px 16px;
  border-bottom: 1px solid var(--color-dark-border);
  margin-bottom: 10px;
}

.shell-sidebar .marca img {
  width: 100%;
  max-width: 172px;
  height: auto;
  display: block;
  /* El logo es navy sobre blanco -- sobre el sidebar oscuro necesita
     invertirse para leerse. Mismo archivo, sin pedir un asset nuevo. */
  filter: brightness(0) invert(1);
  opacity: 0.95;
}

/* LA LETRA MAS CHICA DE LA APP (22/09/2026). Cuatro lugares de este archivo
   -- este subtitulo, la insignia del portal, los titulos de grupo del menu y
   el redondel de ayuda -- estaban en 0,62rem, o sea 9,9 px: por DEBAJO del
   paso mas chico de la escala, que es --texto-micro (10,4 px). Ninguno tenia
   por que serlo; eran numeros tipeados de a uno antes de que la escala
   existiera. Tres de los cuatro ademas van en gris, que es justo lo que el
   dueño marco: "demasiada informacion secundaria con poco contraste".
   Medio pixel no parece nada, pero es la diferencia entre estar adentro de la
   escala y estar abajo de todo -- y estos son los carteles que le dicen a
   alguien que recien empieza DONDE esta parado. */
/* Logo CUADRADO (SAREXP): redondo, a color, con el nombre al lado. El
   filtro que invierte el logo ancho lo volvia una mancha blanca. */
.shell-sidebar .marca.logo-redondo {
  display: flex;
  align-items: center;
  gap: 12px;
}
.shell-sidebar .marca.logo-redondo img {
  width: 48px;
  height: 48px;
  max-width: none;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--base-white);
  filter: none;
  opacity: 1;
}
.shell-sidebar .marca .nombre {
  display: block;
  font-size: var(--texto-grande);
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--color-dark-text);
}
/* El logo ANCHO ya trae el nombre escrito adentro. */
.shell-sidebar .marca.logo-ancho .nombre {
  display: none;
}

.shell-sidebar .marca .sub {
  display: block;
  font-size: var(--texto-micro);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-dark-text-faint);
  margin-top: 7px;
}

.shell-sidebar .marca .badge-portal {
  display: inline-block;
  font-size: var(--texto-micro);
  font-weight: 700;
  color: var(--base-navy-deep);
  background: var(--base-yellow);
  padding: 2px 8px;
  border-radius: 4px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-top: 8px;
}

.shell-nav {
  padding: 0 10px;
  flex: 1;
}

.shell-nav a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  margin-bottom: 2px;
  border-radius: 8px;
  color: var(--color-dark-text-dim);
  text-decoration: none;
  font-size: 0.86rem;
  font-weight: 500;
  transition: background 0.12s ease, color 0.12s ease;
}

.shell-nav a i {
  width: 17px;
  text-align: center;
  font-size: 0.9rem;
  opacity: 0.75;
}

.shell-nav a:hover {
  background: var(--color-dark-hover);
  color: var(--color-dark-text);
}

/* Item activo en amarillo -- es el unico uso del amarillo de marca en toda
   la app, justamente para que signifique una sola cosa: "estas aca". */
.shell-nav a.activo {
  background: var(--base-yellow);
  color: var(--base-navy-deep);
  font-weight: 700;
}
.shell-nav a.activo i {
  opacity: 1;
}

.shell-nav .grupo-titulo {
  font-size: var(--texto-micro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--color-dark-text-faint);
  margin: 16px 12px 6px;
}
.shell-nav .grupo-titulo:first-child {
  margin-top: 4px;
}

/* --- Main --------------------------------------------------------------- */

.shell-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--color-bg);
}

/* La barra de arriba, y por que podia perder el boton de Salir -------------
   Medido sobre un telefono de 390 px: la barra era un flex SIN `flex-wrap`,
   con 24 px de padding a cada lado -- 342 px utiles -- y adentro tenia que
   entrar hamburguesa + migas + selector de Empresa (con `min-width: 190px`
   clavado) + campanita de 38 px + Salir. Solo el bloque de la derecha pedia
   ~322 px. Sin permiso para bajar de linea y sin permiso para encoger, el
   sobrante se iba FUERA de la pantalla: "Salir" quedaba cortado del lado
   derecho, y el unico ajuste movil que existia escondia el nombre del usuario
   a partir de 860 px, que no resolvia nada de esto.

   Se arregla de raiz con tres permisos que antes no estaban:
     1) la barra puede bajar de linea (`flex-wrap`);
     2) cada bloque puede encoger (`min-width: 0` -- sin eso un flex item nunca
        baja de su contenido, que es lo que hacia desbordar);
     3) el selector de Empresa tiene un ancho COMODO, no un ancho MINIMO.
   Y abajo de 720 px las acciones se llevan una fila entera para ellas. */
.shell-topbar {
  background: var(--topbar-bg);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-border);
  padding: 12px 24px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  position: sticky;
  top: 0;
  z-index: 10;
}

/* El bloque de la izquierda (hamburguesa + migas) lo arma shell.js con estilo
   en linea; lo unico que le falta es poder encoger. */
.shell-topbar > :first-child {
  min-width: 0;
}

.shell-breadcrumbs {
  font-size: 0.82rem;
  color: var(--color-text-dim);
  font-weight: 500;
  /* Que se corte con puntos suspensivos antes que empujar a los botones fuera
     de la pantalla: saber donde estoy es util, apretar Salir es necesario. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.shell-breadcrumbs .actual {
  color: var(--color-heading);
  font-weight: 700;
}

.shell-topbar-acciones {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* El titulo de la pantalla y, a su derecha, la Empresa (28/09/2026: la Empresa
   se elige ADENTRO de la pantalla, no en la barra de arriba; ver
   _montarFiltroEmpresa en shell.js). El margen de abajo es el que tenia el h1
   solo, asi el parrafo que sigue queda donde estaba. */
.titulo-con-empresa {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin-bottom: 12px;
}

.titulo-con-empresa h1 {
  margin: 0;
}

.filtro-empresa {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* El `display: flex` de arriba le ganaria al atributo `hidden`. */
.filtro-empresa[hidden] {
  display: none;
}

.filtro-empresa label {
  font-size: var(--texto-chico);
  color: var(--color-text-dim);
  white-space: nowrap;
  margin: 0;
}

.filtro-empresa select,
.filtro-empresa .desplegable {
  width: 220px;
  max-width: 100%;
  font-weight: 600;
}

/* Quien esta logueado. Deliberadamente sobrio -- es una referencia que se
   consulta, no un control que compita con el selector de Empresa. */
.shell-usuario {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.15;
  padding-left: 12px;
  border-left: 1px solid var(--color-border);
  min-width: 0;
}

.shell-usuario .nombre {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--color-heading);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 180px;
}

.shell-usuario .rol {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-dim);
}

/* El rol privilegiado se distingue: no es lo mismo estar por operar como
   Admin que como Empleado (seccion 16). */
.shell-usuario .rol[data-rol="admin"] {
  color: var(--base-navy);
}

@media (max-width: 860px) {
  .shell-usuario {
    display: none;
  }
}

.campanita {
  position: relative;
  background: var(--base-white);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-dim);
  width: 38px;
  height: 38px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-sm);
}
.campanita:hover {
  background: var(--base-slate-50);
  color: var(--color-heading);
}

.campanita .contador {
  position: absolute;
  top: -6px;
  right: -6px;
  background: var(--color-danger);
  /* Era `white` a secas: el unico color de estos dos archivos que no salia de
     un token. La palabra suelta se escapa del cerco -- la prueba busca hex --
     y el dia que el blanco de la marca deje de ser #fff este quedaria solo. */
  color: var(--base-white);
  font-size: var(--texto-micro);
  font-weight: 700;
  min-width: 18px;
  height: 18px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  border: 2px solid var(--base-white);
}

.campanita,
.menu-hamburguesa {
  flex-shrink: 0;
}

/* El boton de Salir no encoge ni se corta: es la salida de una sesion con
   datos de clientes adentro. Si algo tiene que ceder espacio, no es este. */
#btn-logout {
  flex-shrink: 0;
  white-space: nowrap;
}

.menu-hamburguesa {
  display: none;
  background: var(--base-white);
  border: 1px solid var(--color-border-strong);
  color: var(--color-heading);
  font-size: 1rem;
  padding: 8px 11px;
  box-shadow: none;
}

.shell-content {
  padding: 24px;
  flex: 1;
  /* Sin tope de ancho (22/09): en la pantalla del dueño (2560 px) el tope de
     1560 dejaba 1000 px en blanco mientras la tabla de Inventario cortaba
     columnas. Un sistema de tablas usa todo el ancho; lo que tiene que quedar
     angosto para leerse (los parrafos de ayuda) ya lleva su max-width en ch. */
  max-width: none;
  width: 100%;
  /* Sin esto, una tabla ancha adentro estira el contenedor y aparece el scroll
     horizontal de toda la pagina en vez del scroll propio de la tabla. */
  min-width: 0;
}

.shell-content > h1 {
  font-size: 1.5rem;
  margin-bottom: 18px;
}

/* --- Cards -------------------------------------------------------------- */

.grid-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--card-radius);
  padding: 18px;
  box-shadow: var(--shadow-sm);
}

.card .card-titulo {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-dim);
  margin-bottom: 8px;
}

.card .card-valor {
  font-family: var(--font-mono);
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--color-heading);
  line-height: 1.1;
}

/* Tarjeta clickeable */
a.card {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease;
}
a.card:hover {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
  a.card {
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
  }
  a.card:hover {
    transform: none;
  }
}

/* --- Métricas de Inicio -------------------------------------------------- */

.grid-metricas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  gap: 14px;
  align-items: start;
}

.metrica {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.metrica-titulo {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-dim);
}

.metrica-valor {
  font-family: var(--font-mono);
  font-size: 1.85rem;
  font-weight: 700;
  line-height: 1.05;
  color: var(--color-heading);
  font-variant-numeric: tabular-nums;
}

/* La unidad acompaña al número sin competir con él. */
.metrica-valor .unidad {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-text-dim);
}

.metrica-detalle {
  font-size: 0.78rem;
  color: var(--color-text-dim);
  line-height: 1.35;
}

/* "Hay algo que hacer acá" -- ámbar, nunca rojo: un pendiente es trabajo
   normal del día, no una falla del sistema (sección 20). La barra lateral
   lo distingue sin depender solo del color. */
.metrica.tono-atencion {
  border-color: color-mix(in srgb, var(--color-warning) 45%, var(--card-border));
}
.metrica.tono-atencion::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  border-radius: var(--card-radius) 0 0 var(--card-radius);
  background: var(--color-warning);
}
/* #d97706 sobre blanco da ~4.0:1 -- suficiente para texto grande (el número
   va en 1.85rem bold, el umbral ahí es 3:1), no para el detalle chico, que
   por eso se deja en el gris de siempre. */
.metrica.tono-atencion .metrica-valor {
  color: var(--color-warning);
}

/* El "?" de ayuda: chico, discreto, y con área de click cómoda. */
.ayuda {
  all: unset;
  cursor: help;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-dim);
  font-size: var(--texto-micro);
  font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
}
.ayuda:hover,
.ayuda[aria-expanded="true"] {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--base-white);
}
.ayuda:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.ayuda-texto {
  margin: 8px 0 0;
  padding-top: 8px;
  border-top: 1px dashed var(--color-border);
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--color-text);
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}

/* --- Tablas densas ------------------------------------------------------ */

.filtros-fijos {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin-bottom: 16px;
  padding: 14px 16px;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--card-radius);
  box-shadow: var(--shadow-sm);
}

/* `min(170px, 100%)` y no `170px` a secas: en un telefono angosto un piso fijo
   hace que el filtro sobresalga de su propia tarjeta. Asi se estira hasta 170
   cuando hay lugar y se adapta cuando no. */
.filtros-fijos .campo {
  margin-bottom: 0;
  min-width: min(170px, 100%);
  flex: 1 1 170px;
  max-width: 320px;
}

.tabla-densa-wrap {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--card-radius);
  overflow: auto;
  box-shadow: var(--shadow-sm);
}

table.tabla-densa {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
}

table.tabla-densa th,
table.tabla-densa td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  white-space: nowrap;
}

table.tabla-densa th {
  color: var(--color-text-dim);
  font-weight: 700;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  position: sticky;
  top: 0;
  background: var(--base-slate-50);
  border-bottom: 1px solid var(--color-border-strong);
}

table.tabla-densa td {
  color: var(--color-text);
  font-weight: 500;
}

table.tabla-densa tbody tr:last-child td {
  border-bottom: none;
}

/* El NUMERO va en mono (se alinea digito con digito); el ENCABEZADO no: si
   no, la misma fila de titulos salia con dos letras distintas. */
table.tabla-densa td.num,
table.tabla-densa th.num {
  text-align: right;
}
table.tabla-densa td.num {
  font-family: var(--font-mono);
}

table.tabla-densa tbody tr:hover {
  background: var(--base-slate-50);
}

/* --- Responsive --------------------------------------------------------- */

@media (max-width: 900px) {
  .shell {
    grid-template-columns: minmax(0, 1fr);
  }

  .shell-sidebar {
    position: fixed;
    left: -260px;
    top: 0;
    width: 248px;
    z-index: 40;
    transition: left 0.2s ease;
    box-shadow: var(--shadow-lg);
  }

  .shell-sidebar.abierta {
    left: 0;
  }

  .menu-hamburguesa {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .shell-content {
    padding: 16px;
  }
}

/* Abajo de 720 px las acciones se toman una fila entera: el selector de
   Empresa se estira, la campanita y Salir quedan enteros a la derecha, y nada
   depende de que "justo entre". Dos filas cortas antes que una fila cortada. */
@media (max-width: 720px) {
  .shell-topbar {
    padding: 10px 16px;
  }

  .shell-topbar-acciones {
    flex: 1 1 100%;
    justify-content: space-between;
    flex-wrap: nowrap;
  }

  .filtro-empresa {
    flex: 1 1 auto;
  }

  .filtro-empresa select,
  .filtro-empresa .desplegable {
    width: 100%;
  }
}

@media (max-width: 560px) {
  .shell-content {
    padding: 12px;
  }

  /* Una tabla densa no se puede "adaptar" a 360 px sin mentir sobre los datos:
     lo honesto es que se deslice dentro de su propia tarjeta -- que es lo que
     `.tabla-densa-wrap` ya hace -- y que la pagina entera NO se mueva al
     costado. El tirón horizontal es lo que el dueño ve como desborde. */
  .tabla-densa-wrap {
    -webkit-overflow-scrolling: touch;
  }

  table.tabla-densa th,
  table.tabla-densa td {
    padding: 9px 10px;
  }
}

/* El filtro de Empresa de cada pantalla, con el desplegable propio. */
.filtro-empresa .desplegable-boton {
  min-height: 36px;
  padding: 7px 12px;
  font-weight: 600;
}
