/* ============================================================
   Primitivas — las piezas con las que se arman todas las pantallas.
   Construidas SOBRE design-tokens.css: aquí no hay ni un color suelto,
   solo var(--…). Si necesitas un valor que no existe, se pregunta antes
   de inventarlo.

   Las seis reglas de identidad:
   1. El violeta es acción, el verde es identidad. No se intercambian.
   2. 4px domina en radios. Nada muy redondeado.
   3. Sombras mínimas: la jerarquía se hace con borde y superficie.
      En pantallas de trabajo, --shadow-sm como máximo.
   4. Todo número lleva cifras de ancho fijo (clase .tabular), y el estado
      nunca se comunica solo por color: color + palabra + icono.
   5. DENSIDAD DE HERRAMIENTA, no de página web: 8 / 12 / 16. Filas bajas,
      rellenos cortos, rótulo pequeño en mayúsculas encima del valor. Esto no
      es una web con aire: es algo que alguien tiene abierto ocho horas.
   ============================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--texto-cuerpo);
  line-height: 1.45;
  color: var(--text-body);
  background: var(--surface-app);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  color: var(--text-strong);
  line-height: 1.2;
  margin: 0 0 var(--space-2);
}

h1 { font-size: 22px; font-weight: 700; }
h2 { font-size: var(--texto-titulo); font-weight: 700; }
h3 { font-size: 15px; font-weight: 700; }

/* ---------- Enlace ---------- */
.enlace,
a {
  color: var(--link);
  text-decoration: none;
}

.enlace:hover,
a:hover {
  text-decoration: underline;
}

/* ---------- Botones ----------
   Un botón primario por vista como máximo: es el "haz esto". */
.boton {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--texto-chico);
  font-weight: 700;
  line-height: 1;
  min-height: var(--alto-control);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;   /* «Programar ahora» no se parte en dos renglones */
  transition: background var(--motion-fast) var(--easing);
}

.boton:disabled {
  background: var(--disabled-bg);
  color: var(--disabled-fg);
  border-color: var(--disabled-bd);
  box-shadow: none;
  cursor: not-allowed;
}

.boton--primario {
  background: var(--color-primary);
  color: #fff;
}

.boton--primario:hover:not(:disabled) {
  background: var(--color-primary-hover);
}

.boton--secundario {
  background: var(--surface-0);
  color: var(--text-strong);
  border-color: var(--surface-0);
  box-shadow: 0 1px 3px rgba(25, 36, 53, .14);
}

.boton--secundario:hover:not(:disabled) {
  background: var(--surface-1);
}

.boton--destructivo {
  background: var(--danger-solid);
  color: #fff;
}

.boton--destructivo:hover:not(:disabled) {
  background: #A82C24;
}

/* Versión compacta para barras de herramientas y filas de tabla. */
.boton--compacto {
  font-size: var(--texto-etiqueta);
  min-height: var(--alto-boton-compacto);
  padding: 0 10px;
}

/* ---------- Tarjeta ---------- */
.tarjeta {
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--relleno-tarjeta);
}

/* --radius-lg y --radius-xl NO se usan en la aplicación: el radio de Nexum es
   6px. Nada muy redondeado. */
.tarjeta--destacada {
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}

/* Los cuatro anchos de una tarjeta centrada. Ninguna plantilla vuelve a
   escribir un número: si hace falta uno que no está, se agrega su token en
   design-tokens.css y se usa desde aquí. */
.tarjeta--angosta  { max-width: var(--ancho-tarjeta-angosta); }
.tarjeta--compacta { max-width: var(--ancho-tarjeta-compacta); }
.tarjeta--media    { max-width: var(--ancho-tarjeta-media); }
.tarjeta--ancha    { max-width: var(--ancho-tarjeta-ancha); }

/* En una página de trabajo, la tarjeta usa todo el lienzo. Los límites de
   lectura siguen aplicándose a diálogos y documentos impresos. */
.contenido > :is(.tarjeta--media, .tarjeta--ancha) {
  width: 100%;
  max-width: none;
}

/* Un título de sección NO es un encabezado de artículo: es un rótulo.
   Pequeño, en mayúsculas y en gris, para que el dato de abajo mande. */
.tarjeta__titulo {
  font-size: var(--texto-micro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .7px;
  color: var(--text-muted);
  margin: 0 0 var(--space-2);
}

.tarjeta__nota {
  font-size: var(--texto-chico);
  color: var(--text-muted);
  margin: 0;
}

/* ---------- Insignia de estado ----------
   Seis variantes semánticas. Siempre color + palabra + icono. */
.insignia {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--texto-micro);
  font-weight: 700;
  line-height: 1;
  padding: 4px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  white-space: nowrap;
}

.insignia svg {
  width: 12px;
  height: 12px;
  flex: none;
}

.insignia--exito     { background: var(--success-bg);  color: var(--success-fg);  border-color: var(--success-bd); }
.insignia--neutro    { background: var(--neutral-bg);  color: var(--neutral-fg);  border-color: var(--neutral-bd); }
.insignia--aviso     { background: var(--warning-bg);  color: var(--warning-fg);  border-color: var(--warning-bd); }
.insignia--informacion { background: var(--info-bg);   color: var(--info-fg);     border-color: var(--info-bd); }
.insignia--peligro   { background: var(--danger-bg);   color: var(--danger-fg);   border-color: var(--danger-bd); }
.insignia--inactivo  { background: var(--disabled-bg); color: var(--disabled-fg); border-color: var(--disabled-bd); }

/* ---------- Formulario ---------- */
.campo {
  display: block;
  margin-bottom: var(--entre-campos);
  min-width: 0;
}

/* LA MARCA DE LA CASA: el rótulo encima, pequeño, en mayúsculas y en gris;
   el valor debajo, más grande y oscuro. Vale igual para un formulario y para
   una ficha, y es lo que hace que un bloque de datos se lea de un vistazo. */
.campo__etiqueta {
  display: block;
  font-size: var(--texto-micro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--text-muted);
  margin-bottom: var(--rotulo-a-caja);
}

/* Y la pantalla de ingreso, que usa el formulario que trae Django tal cual
   —para que una cuenta desactivada reciba SU mensaje y no el de «contraseña
   incorrecta»—, y cuyos controles no pasan por FormularioBase y por eso no
   traen la clase puesta. Se suman a estas mismas reglas en vez de copiarlas:
   el aspecto es el de siempre porque es LA MISMA regla. */
.entrada,
.ingreso .campo input {
  width: 100%;
  min-height: var(--alto-control);
  font-family: var(--font-sans);
  font-size: var(--texto-cuerpo);
  color: var(--text-strong);
  background: var(--surface-0);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  transition: border-color var(--motion-fast) var(--easing),
              box-shadow var(--motion-fast) var(--easing);
}

.entrada::placeholder,
.ingreso .campo input::placeholder {
  color: var(--text-muted);
}

.entrada:focus,
.ingreso .campo input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}

.entrada:disabled,
.ingreso .campo input:disabled {
  background: var(--disabled-bg);
  color: var(--disabled-fg);
  border-color: var(--disabled-bd);
}

.campo__ayuda {
  font-size: var(--texto-micro);
  color: var(--text-muted);
  margin: 3px 0 0;
}

.campo__error {
  font-size: var(--texto-micro);
  font-weight: 600;
  color: var(--danger-fg);
  margin: 3px 0 0;
}

/* ============================================================
   Plantilla de página: barra lateral oscura + cabecera + contenido
   ============================================================ */
.disposicion {
  display: grid;
  grid-template-columns: var(--ancho-barra-lateral) minmax(0, 1fr);
  min-height: 100vh;
}

.barra-lateral {
  /* SE QUEDA QUIETA MIENTRAS EL CONTENIDO SE DESPLAZA. Sin esto, en una lista
     de cuarenta filas se pierden a la vez las dos cosas que dicen dónde
     estás: los destinos y cómo salir de aquí.
     Y `overflow-y: auto` por si sus destinos no caben — con cincuenta
     pantallas por delante van a dejar de caber. */
  position: sticky;
  z-index: 30;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  background: var(--ink-dark);
  color: #fff;
  padding: var(--space-3) var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.barra-lateral__marca {
  font-size: 15px;
  padding: 0 var(--space-2) var(--space-1);
  font-weight: 800;
  color: #fff;
  letter-spacing: .2px;
}

.barra-lateral__grupo {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--text-inverse-soft);
  margin: 0 0 var(--space-1);
  padding: 0 var(--space-2);
}

.barra-lateral__enlace {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text-inverse-soft);
  font-size: var(--texto-chico);
  font-weight: 600;
  padding: 6px var(--space-2);
  border-radius: var(--radius-xs);
  text-decoration: none;
  /* Deja sitio a la barra del ítem activo para que nada se mueva al cambiar. */
  border-left: 3px solid transparent;
}

.barra-lateral__enlace svg { width: 18px; height: 18px; flex: none; }

.barra-lateral__enlace:hover {
  background: var(--ink-dark-2);
  color: #fff;
  text-decoration: none;
}

/* El ítem activo se marca con una barra a la izquierda en el color de acción.
   Es lo que hace que se sepa dónde estás sin leer. */
.barra-lateral__enlace--activo {
  background: var(--ink-dark-2);
  color: #fff;
  border-left-color: var(--color-primary);
}

/* ── EL MÓDULO: la cabeza que se pulsa y los destinos que despliega ──────
   Es un <details> de HTML, sin una línea de JavaScript. Sólo uno queda
   abierto —el de la pantalla en la que se está—, y eso lo decide el servidor
   al pintar: con ocho módulos y cuarenta pantallas, abrirlos todos es volver
   a la lista plana que esto vino a arreglar. */
.modulo { margin-bottom: 1px; }

.modulo > summary {
  list-style: none;   /* fuera el triangulito del navegador: tenemos flecha */
  cursor: pointer;
}

.modulo > summary::-webkit-details-marker { display: none; }

.modulo__cabeza {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 7px var(--space-2);
  border-radius: var(--radius-xs);
  color: #fff;
  font-size: var(--texto-chico);
  font-weight: 700;
}

.modulo__cabeza svg { width: 18px; height: 18px; flex: none; }
.modulo__texto { flex: 1; min-width: 0; }

.modulo > summary:hover { background: var(--ink-dark-2); }

.modulo__flecha {
  opacity: .6;
  transition: transform var(--motion-fast) var(--easing);
}

.modulo[open] > summary .modulo__flecha { transform: rotate(180deg); }

/* Los destinos van sangrados hasta debajo del texto de su módulo, no debajo
   de su icono: así se lee la columna de nombres de corrido. */
.modulo__destinos { padding: 2px 0 var(--space-2) 26px; }
.modulo__destinos .barra-lateral__enlace { padding-left: var(--space-2); }

/* ── LO QUE ESTÁ PREVISTO Y TODAVÍA NO EXISTE ────────────────────────────
   Se anuncia atenuado, con su marca de entrega, y NO se puede pulsar. Es la
   diferencia entre «esto no es para ti» —que se esconde— y «esto todavía no
   está», que se dice. Callarlo hace que cada quien se invente cuándo llega. */
.modulo__cabeza--previsto,
.barra-lateral__enlace--previsto {
  color: var(--text-inverse-soft);
  opacity: .55;
  cursor: default;
}

.entrega {
  flex: none;
  margin-left: auto;
  padding: 1px 5px;
  border: 1px solid currentColor;
  border-radius: var(--radius-xs);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .4px;
}

.barra-lateral__enlace--previsto {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* ── PLEGAR LA BARRA ─────────────────────────────────────────────────────
   La casilla no se ve, pero SIGUE ESTANDO: es lo que hace que esto se alcance
   con el tabulador y se active con la barra espaciadora. Escondida con
   `position:absolute` y no con `display:none`, porque lo segundo la saca del
   orden del teclado y deja el control muerto para quien no usa ratón. */
.plegado__casilla {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.plegado {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px var(--space-2);
  margin-bottom: var(--space-2);
  border-radius: var(--radius-xs);
  color: var(--text-inverse-soft);
  font-size: var(--texto-etiqueta);
  font-weight: 600;
  cursor: pointer;
}

.plegado:hover { background: var(--ink-dark-2); color: #fff; }
.plegado svg { flex: none; transition: transform var(--motion-fast) var(--easing); }

/* El foco se pinta sobre la ETIQUETA aunque el foco lo tenga la casilla: es
   la etiqueta lo que se ve. Sin esto, moverse con el tabulador pasa por aquí
   sin que se note. */
.plegado__casilla:focus-visible + .plegado {
  outline: var(--foco);
  outline-offset: var(--foco-separacion);
}

/* `:has()` y no una clase puesta por JavaScript: el estado ya vive en la
   casilla, y duplicarlo en una clase es tener dos verdades. */
.disposicion:has(.plegado__casilla:checked) {
  grid-template-columns: 52px minmax(0, 1fr);
}

.disposicion:has(.plegado__casilla:checked) .modulo__texto,
.disposicion:has(.plegado__casilla:checked) .modulo__flecha,
.disposicion:has(.plegado__casilla:checked) .modulo__destinos,
.disposicion:has(.plegado__casilla:checked) .entrega,
.disposicion:has(.plegado__casilla:checked) .plegado__texto,
.disposicion:has(.plegado__casilla:checked) .barra-lateral__grupo,
.disposicion:has(.plegado__casilla:checked) .barra-lateral__salida span,
.disposicion:has(.plegado__casilla:checked) .barra-lateral__marca {
  display: none;
}

.disposicion:has(.plegado__casilla:checked) .modulo__cabeza,
.disposicion:has(.plegado__casilla:checked) .plegado,
.disposicion:has(.plegado__casilla:checked) .barra-lateral__enlace {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}

.disposicion:has(.plegado__casilla:checked) .plegado svg {
  transform: rotate(180deg);
}
.disposicion:has(.plegado__casilla:checked) .barra-lateral { overflow: visible; }
.disposicion:has(.plegado__casilla:checked) .modulo { position: relative; }
.disposicion:has(.plegado__casilla:checked) .modulo[open] .modulo__destinos {
  display: block;
  position: absolute;
  z-index: 20;
  top: 0;
  left: calc(100% + var(--space-2));
  min-width: 13rem;
  padding: var(--space-2);
  background: var(--ink-dark);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
}
.disposicion:has(.plegado__casilla:checked) .modulo__destinos .barra-lateral__enlace {
  justify-content: flex-start;
  padding: 6px var(--space-2);
  white-space: normal;
}
.disposicion:has(.plegado__casilla:checked) .barra-lateral__cuenta span { display: none; }
.barra-lateral__cuenta span, .barra-lateral__salida span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.barra-lateral__sesion {
  margin-top: auto;
}

/* ---------- El conmutador de apariencia ----------
   Tres botones pegados dentro de la barra lateral, con el puesto encendido.
   Se apoya en el ink de la barra y no inventa ningún color: sobre oscuro sólo
   hacen falta dos tonos —el hueco y el puesto— y los dos ya existen. */
/* ⚠️ EN COLUMNA Y NO EN FILA, y es la tercera forma que toma esto: en fila,
   los rótulos tenían que caber en 65px cada uno, así que o se pegaban unos
   con otros o el bloque se partía en dos renglones descuadrados en cuanto el
   navegador iba con el zoom subido. Con «Por defecto» ya no cabía de ninguna
   manera. Apilados, el ancho deja de ser el problema: cada opción ocupa el
   renglón entero, el rótulo se lee de corrido y el icono queda alineado con
   los de la navegación de arriba. */
/* ⚠️ SIN USO POR AHORA: el bloque que llevaba estas clases se retiró de
   base.html el 2026-09-22, a pedido de Ángel. Las reglas se dejan escritas
   para que devolver el conmutador sea recuperar el HTML y nada más. */
.apariencia {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 var(--space-2) var(--space-4);
  padding: 2px;
  background: var(--ink-dark-2);
  border-radius: var(--radius-sm);
}

/* EL ICONO ENCIMA DEL RÓTULO Y NO AL LADO, aunque al lado se lea mejor: la
   barra mide 200px y los tres en fila —«Claro», «Oscuro», «Equipo»— se
   pegaban unos con otros sin un hueco entre ellos. En columna caben los tres
   holgados, y ninguno pierde sus palabras. */
.apariencia__opcion {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px var(--space-2);
  border: 0;
  border-radius: var(--radius-xs);
  background: transparent;
  font-family: var(--font-sans);
  font-size: var(--texto-etiqueta);
  font-weight: 600;
  line-height: 1;
  text-align: left;
  color: var(--text-inverse-soft);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--motion-fast) var(--easing);
}

/* EL ALTO SE FIJA EN EL SVG Y NO SE HEREDA. Un <svg> sin medida ocupa
   300x150 de fábrica: si esta regla no llega —porque el navegador se quedó
   con la hoja vieja en la memoria—, los tres iconos salen gigantes y la barra
   se descuadra entera. Pasó, y por eso está dicho aquí. */
.apariencia__opcion svg { width: 14px; height: 14px; flex: none; }
.apariencia__opcion:hover { color: #fff; }

/* EL PUESTO SE MARCA CON FONDO Y CON COLOR, no sólo con color: sobre el ink
   de la barra, la diferencia entre un gris claro y un blanco es demasiado
   fina para verla de reojo, que es como se mira esto. */
.apariencia__opcion--puesta {
  background: var(--ink-dark);
  color: #fff;
}

.apariencia__opcion:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

.apariencia__nota {
  margin: calc(var(--space-4) * -1 + 4px) var(--space-2) var(--space-4);
  padding: 0 var(--space-1);
  font-size: 10px;
  line-height: 1.35;
  color: var(--text-inverse-soft);
}

.barra-lateral__formulario-salida {
  margin: 0;
}

.barra-lateral__salida {
  width: 100%;
  background: transparent;
  border-top: 0;
  border-right: 0;
  border-bottom: 0;
  font: inherit;
  cursor: pointer;
  text-align: left;
}

.principal {
  display: flex;
  flex-direction: column;
  background: var(--surface-app);
  min-width: 0;
}

.cabecera {
  /* Igual que la barra: se queda arriba. El z-index es el MISMO token que ya
     usa la cabecera de la tabla —no un número inventado—, y no hace falta
     agregarle fondo: `--surface-0` ya es opaco, así que lo que se desplaza
     por debajo no se transparenta. */
  position: sticky;
  top: 0;
  z-index: var(--capa-pegado);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  background: var(--surface-0);
  border-bottom: 1px solid var(--border);
  min-height: var(--alto-cabecera);
  padding: var(--space-2) var(--space-4);
}

.cabecera__titulo {
  font-size: var(--texto-titulo);
  font-weight: 700;
  color: var(--text-strong);
  margin: 0;
  line-height: 1.2;
}

.cabecera__acciones {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* El margen de página al extremo denso de la escala: 12px, no 16. Son 8px de
   ancho útil más en cada pantalla, y ninguna pantalla acota su contenido en
   una caja centrada — eso sería tirar un tercio del monitor. */
.contenido {
  padding: var(--space-3);
  flex: 1;
}

.rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--separacion-bloques);
}

@media (max-width: 900px) {
  .disposicion {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
}
