/* =============================================================================
   OECSA — tokens de marca
   Fuente: Manual de Aplicación de Logotipo, OE Constructores, S.A.
   Los componentes usan estas variables. Nunca hex sueltos en las plantillas.
   ============================================================================= */

:root {
  /* Corporativos */
  --oecsa-verde: #C3D600;
  --oecsa-gris: #A8ACA1;
  --oecsa-negro: #231F20;

  /* Neutros de apoyo */
  --oecsa-gris-claro: #D8D7D7;
  --oecsa-gris-medio: #BDBCBC;
  --oecsa-fila: #F5F5F3;
  --oecsa-blanco: #FFFFFF;

  /* Estados — fuera de marca, uso funcional */
  --estado-ok-bg: #EAF3DE;
  --estado-ok-tx: #27500A;
  --estado-alerta-bg: #FAEEDA;
  --estado-alerta-tx: #633806;
  --estado-error-bg: #FCEBEB;
  --estado-error-tx: #791F1F;
  --estado-info-bg: #E6F1FB;
  --estado-info-tx: #0C447C;
  --estado-neutro-bg: #F1EFE8;
  --estado-neutro-tx: #444441;

  /* Tipografía — Geomanist es la corporativa pero es de pago */
  --oecsa-font: "Poppins", "Montserrat", "Century Gothic", sans-serif;

  /* Geometría */
  --oecsa-radio: 8px;
  --oecsa-radio-card: 12px;
  --oecsa-borde: 0.5px solid var(--oecsa-gris-claro);
  --oecsa-barra: 9px;
}

/* -----------------------------------------------------------------------------
   Reglas de color del manual — no violar

   1. Fondo blanco por defecto. El verde es acento, NUNCA fondo de página.
   2. NUNCA texto verde sobre blanco: el #C3D600 es muy luminoso y no contrasta.
      El verde se usa como relleno con texto --oecsa-negro encima.
   3. El negro corporativo es #231F20, no #000000.
   4. Monocromo solo válido en blanco y negro. Nunca logo verde ni gris.
   -------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
   Reinicio

   `border-box` en todo: con el modelo de caja de por omisión, un campo con
   `width: 100%` y relleno horizontal mide 100% *más* el relleno, y se sale de
   su contenedor. Va acá y no como parche de una pantalla, porque le pasa a
   cualquier control con ancho completo.
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  font-family: var(--oecsa-font);
  color: var(--oecsa-negro);
  background: var(--oecsa-blanco);
  font-weight: 400;
  line-height: 1.6;
}

/* Título con barra verde — el recurso característico de la marca.
   La barra es un **acento**, no un separador: no se extiende hasta el margen.
   `flex: 0 1` para que no crezca, pero sí ceda en pantallas angostas. */
.oecsa-titulo {
  display: flex;
  align-items: center;
  gap: 20px;
  font-weight: 400;
  font-size: 18px;
  color: var(--oecsa-negro);
  margin: 0 0 18px;
}
.oecsa-titulo::after {
  content: "";
  flex: 0 1 300px;
  height: var(--oecsa-barra);
  background: var(--oecsa-verde);
}

/* Franja verde inferior — portadas y pantallas de acceso */
.oecsa-franja {
  height: 8px;
  background: var(--oecsa-verde);
}

/* Filete vertical — hojas y paneles laterales */
.oecsa-filete {
  border-left: 4px solid var(--oecsa-verde);
  border-radius: 0;
}

/* Botones */
.btn-primario {
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
  border: none;
  padding: 9px 20px;
  border-radius: var(--oecsa-radio);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
.btn-secundario {
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
  border: 0.5px solid var(--oecsa-negro);
  padding: 9px 20px;
  border-radius: var(--oecsa-radio);
  font-size: 14px;
  cursor: pointer;
}
.btn-peligro {
  background: var(--oecsa-blanco);
  color: #A32D2D;
  border: 0.5px solid #F09595;
  padding: 9px 20px;
  border-radius: var(--oecsa-radio);
  font-size: 14px;
  cursor: pointer;
}

/* Campos */
.campo {
  height: 38px;
  width: 100%;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  padding: 0 12px;
  font-family: var(--oecsa-font);
  font-size: 14px;
  color: var(--oecsa-negro);
  background: var(--oecsa-blanco);
}
.campo:focus {
  outline: none;
  border-color: var(--oecsa-negro);
}
.campo-etiqueta {
  display: block;
  font-size: 12px;
  font-weight: 500;
  margin-bottom: 5px;
}
.campo-ayuda {
  font-size: 11px;
  color: var(--oecsa-gris);
  margin-top: 5px;
}
.campo-error {
  font-size: 12px;
  color: var(--estado-error-tx);
  margin-top: 5px;
}

/* Insignias de estado */
.insignia {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--oecsa-radio);
  font-size: 11px;
  line-height: 1.7;
}
.insignia-activo   { background: var(--estado-ok-bg);     color: var(--estado-ok-tx); }
.insignia-pendiente{ background: var(--estado-alerta-bg); color: var(--estado-alerta-tx); }
.insignia-inactivo { background: var(--estado-error-bg);  color: var(--estado-error-tx); }
.insignia-info     { background: var(--estado-info-bg);   color: var(--estado-info-tx); }
.insignia-neutro   { background: var(--estado-neutro-bg); color: var(--estado-neutro-tx); }
.insignia-admin    { background: var(--oecsa-verde);      color: var(--oecsa-negro); }

/* Tablas — encabezado negro, filas alternas */
.tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.tabla thead th {
  background: var(--oecsa-negro);
  color: var(--oecsa-blanco);
  text-align: left;
  padding: 9px 12px;
  font-weight: 500;
}
.tabla tbody td {
  padding: 10px 12px;
}
.tabla tbody tr:nth-child(even) {
  background: var(--oecsa-fila);
}
.tabla-marco {
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  overflow: hidden;
}

/* Tarjeta de métrica */
.metrica {
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio);
  padding: 12px;
}
.metrica-etiqueta {
  font-size: 12px;
  color: var(--oecsa-gris);
  margin: 0;
}
.metrica-valor {
  font-size: 22px;
  font-weight: 500;
  margin: 2px 0 0;
}
.metrica-valor.alerta { color: var(--estado-alerta-tx); }

/* Tarjeta */
.tarjeta {
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  padding: 16px 20px;
}

/* Avatar de iniciales */
.avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--estado-neutro-bg);
  color: var(--estado-neutro-tx);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 500;
  flex-shrink: 0;
}
.avatar-destacado {
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
}

/* -----------------------------------------------------------------------------
   Zona de campo — /campo/
   Captura desde obra, en celular, con guantes y bajo el sol.
   Controles más grandes y contraste más alto que en las pantallas de oficina.
   -------------------------------------------------------------------------- */

.campo-movil .btn-primario {
  min-height: 52px;
  font-size: 17px;
  width: 100%;
}
.campo-movil .campo {
  height: 52px;
  font-size: 17px;
}
.campo-movil .campo-etiqueta {
  font-size: 15px;
}

/* Indicador de sincronización pendiente */
.sin-conexion {
  background: var(--estado-alerta-bg);
  color: var(--estado-alerta-tx);
  padding: 10px 14px;
  border-radius: var(--oecsa-radio);
  font-size: 14px;
}

/* -----------------------------------------------------------------------------
   Pantalla de acceso — /ingresar/
   Tarjeta centrada sobre fondo de fila, franja verde abajo. Es la única
   pantalla sin navegación.
   -------------------------------------------------------------------------- */

.acceso {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: var(--oecsa-fila);
  padding: 36px 24px;
}
.acceso-tarjeta {
  width: 100%;
  max-width: 380px;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  overflow: hidden;
}
.acceso-cuerpo {
  padding: 36px;
  text-align: center;
}
.acceso-logo {
  width: 62px;
  height: auto;
  display: block;
  margin: 0 auto 10px;
}
.acceso-sistema {
  font-size: 12px;
  color: var(--oecsa-gris);
  margin: 0 0 32px;
}
.acceso-formulario {
  text-align: left;
}
.acceso-nota {
  font-size: 11px;
  color: var(--oecsa-gris);
  margin: 18px 0 0;
  text-align: center;
  line-height: 1.6;
}
.acceso-firma {
  font-size: 11px;
  color: var(--oecsa-gris);
  margin: 0;
  text-align: center;
}

/* Campo con icono adentro */
.campo-grupo {
  position: relative;
  margin-bottom: 16px;
}
.campo-grupo .campo {
  padding-left: 38px;
}
.campo-icono {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 17px;
  height: 17px;
  pointer-events: none;
}

/* Botón que ocupa el ancho del contenedor */
.btn-bloque {
  width: 100%;
  display: block;
}

/* Fila de dos extremos — casilla a la izquierda, enlace a la derecha */
.fila-extremos {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin: 0 0 24px;
}
.casilla {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--oecsa-negro);
}
.enlace-sobrio {
  font-size: 12px;
  color: var(--oecsa-negro);
  text-decoration: underline;
}

/* Mensaje de error de formulario completo, no de un campo suelto */
.mensaje-error {
  background: var(--estado-error-bg);
  color: var(--estado-error-tx);
  border-radius: var(--oecsa-radio);
  padding: 10px 12px;
  font-size: 12px;
  line-height: 1.5;
  margin: 0 0 16px;
}

/* Contenedor de página — ancho de lectura con aire a los lados */
.contenedor {
  max-width: 760px;
  margin: 40px auto;
  padding: 0 24px;
}
.dato-secundario {
  color: var(--oecsa-gris);
}

/* -----------------------------------------------------------------------------
   Disposición de la aplicación — encabezado y navegación lateral
   La pantalla de acceso no la usa: es la única sin navegación.
   -------------------------------------------------------------------------- */

.encabezado {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 22px;
  border-bottom: var(--oecsa-borde);
  background: var(--oecsa-blanco);
}
.encabezado-marca {
  width: 26px;
  height: 26px;
  display: block;
}
.encabezado-sistema {
  font-size: 14px;
  font-weight: 500;
}
.encabezado-relleno {
  flex: 1;
}
.encabezado-persona {
  font-size: 13px;
  color: var(--oecsa-gris);
}

.disposicion {
  display: flex;
  align-items: stretch;
  min-height: calc(100vh - 56px);
}

.lateral {
  width: 210px;
  flex-shrink: 0;
  border-right: var(--oecsa-borde);
  padding: 18px 0;
  background: var(--oecsa-blanco);
}
.lateral-titulo {
  font-size: 11px;
  color: var(--oecsa-gris);
  margin: 0 0 6px;
  padding: 0 22px;
}
.lateral-grupo {
  margin-bottom: 18px;
}
.lateral-enlace {
  display: block;
  padding: 7px 22px;
  font-size: 13px;
  color: var(--oecsa-negro);
  text-decoration: none;
  border-left: 3px solid transparent;
}
.lateral-enlace:hover {
  background: var(--oecsa-fila);
}
.lateral-enlace.activo {
  border-left-color: var(--oecsa-verde);
  font-weight: 500;
  background: var(--oecsa-fila);
}
/* Módulo que todavía no existe. No es un enlace: no lleva a ningún lado. */
.lateral-proximo {
  display: block;
  padding: 7px 22px;
  font-size: 13px;
  color: var(--oecsa-gris-medio);
  border-left: 3px solid transparent;
  cursor: default;
}

.principal {
  flex: 1;
  min-width: 0;
  padding: 22px;
}

/* -----------------------------------------------------------------------------
   Listado — métricas, filtros y paginación
   -------------------------------------------------------------------------- */

.metricas {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 20px;
}

.filtros {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
  flex-wrap: wrap;
  align-items: center;
}
.filtros .campo {
  width: auto;
  height: 36px;
}
.filtro-busqueda {
  flex: 1;
  min-width: 180px;
}

/* Celda de dos renglones: el nombre arriba, el uid abajo */
.celda-persona {
  display: block;
}
.celda-secundaria {
  display: block;
  color: var(--oecsa-gris);
  font-size: 11px;
}

.paginacion {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 12px;
  font-size: 11px;
  color: var(--oecsa-gris);
}
.paginacion-enlace {
  padding: 5px 9px;
  min-width: 30px;
  text-align: center;
  color: var(--oecsa-negro);
  text-decoration: none;
  border: var(--oecsa-borde);
  border-radius: 6px;
}
.paginacion-enlace:hover {
  border-color: var(--oecsa-negro);
}
/* La página actual no es un enlace: no se va a ninguna parte pulsándola. */
.paginacion-actual {
  padding: 5px 9px;
  min-width: 30px;
  text-align: center;
  color: var(--oecsa-negro);
  border: 1px solid var(--oecsa-negro);
  border-radius: 6px;
  font-weight: 500;
}
.paginacion-hueco {
  padding: 5px 2px;
  color: var(--oecsa-gris);
}
.paginacion-conteo {
  margin: 6px 0 0;
  font-size: 11px;
  color: var(--oecsa-gris);
}

/* --- Los cuatro filtros de fecha del listado -------------------------------
   Botones y no una lista desplegable: cuál está puesto se ve sin abrir nada.
   El activo se distingue por borde y peso, no solo por color. */
.filtros-fecha {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 12px;
}
.filtro-fecha {
  padding: 6px 12px;
  font-size: 12px;
  color: var(--oecsa-gris);
  text-decoration: none;
  border: var(--oecsa-borde);
  border-radius: 8px;
}
.filtro-fecha:hover {
  color: var(--oecsa-negro);
  border-color: var(--oecsa-negro);
}
.filtro-activo {
  color: var(--oecsa-negro);
  border-color: var(--oecsa-negro);
  font-weight: 500;
}
.filtro-un-dia {
  display: flex;
  align-items: center;
  gap: 6px;
}
.filtro-un-dia .campo {
  width: auto;
  margin: 0;
}
.tabla-vacia {
  padding: 22px;
  text-align: center;
  font-size: 13px;
  color: var(--oecsa-gris);
}

/* Página de error — 403 y parientes */
.error-pagina {
  max-width: 520px;
  margin: 80px auto;
  padding: 0 24px;
  text-align: center;
}

/* -----------------------------------------------------------------------------
   Respaldo sin JavaScript

   El botón «Filtrar» vive dentro de un <noscript>: con JavaScript no aparece
   —los filtros ya se aplican al cambiar— y sin JavaScript sí, y el formulario
   funciona como un GET normal.

   **No tocar el `display` de <noscript>.** Cuando hay JavaScript, el navegador
   no interpreta su contenido como marcado sino como texto, y lo esconde con
   `display: none`. Cualquier regla que lo destape —`display: contents`, por
   ejemplo— imprime el HTML literal en la pantalla.
   -------------------------------------------------------------------------- */

/* Fila de una persona desactivada.
   Se atenúa en gris, sin insignia ni columna que lo repita: el dato ya está
   en la fila. Sigue siendo legible, solo deja de competir con las activas. */
.fila-inactiva td {
  color: var(--oecsa-gris);
}

/* -----------------------------------------------------------------------------
   Detalle — ficha de una persona
   -------------------------------------------------------------------------- */

.miga {
  font-size: 12px;
  margin: -8px 0 18px;
}

/* Datos que vienen del directorio: se ven, no se editan */
.datos-directorio {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio);
  padding: 14px;
  margin-bottom: 6px;
}
.dato-etiqueta {
  font-size: 11px;
  color: var(--oecsa-gris);
  margin: 0;
}
.dato-valor {
  font-size: 13px;
  margin: 2px 0 0;
  word-break: break-all;
}

.rejilla-campos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin: 22px 0;
}
.campo-bloque {
  min-width: 0;
  margin-bottom: 14px;
}

/* Las obras del alcance, en una caja con desplazamiento propio */
.lista-proyectos {
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  padding: 12px 14px;
  max-height: 240px;
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 6px 14px;
}
.lista-proyectos .casilla {
  font-size: 13px;
}

.acciones {
  display: flex;
  gap: 9px;
  margin: 22px 0;
}

/* Avisos de una operación, no de un campo */
.mensaje-ok {
  background: var(--estado-ok-bg);
  color: var(--estado-ok-tx);
  border-radius: var(--oecsa-radio);
  padding: 10px 12px;
  font-size: 12px;
  margin: 0 0 16px;
}
.mensaje-alerta {
  background: var(--estado-alerta-bg);
  color: var(--estado-alerta-tx);
  border-radius: var(--oecsa-radio);
  padding: 10px 12px;
  font-size: 12px;
  margin: 0 0 16px;
}

/* Botón que existe pero todavía no lleva a ningún lado */
.btn-secundario:disabled {
  color: var(--oecsa-gris);
  border-color: var(--oecsa-gris-claro);
  cursor: default;
}

/* La fila entera del listado lleva al detalle, sin JavaScript */
.tabla tbody tr {
  position: relative;
}
.enlace-fila {
  color: var(--oecsa-negro);
  text-decoration: none;
}
.enlace-fila::after {
  content: "";
  position: absolute;
  inset: 0;
}
.enlace-fila:hover {
  text-decoration: underline;
}

/* Módulo que existe pero al que esta persona no tiene acceso.
   Se distingue del que todavía no tiene pantallas: acá sí hay algo que pedir,
   y el subrayado punteado con el cursor de ayuda anuncian que el texto al pasar
   el cursor lo explica. */
.lateral-vedado {
  display: block;
  padding: 7px 22px;
  font-size: 13px;
  color: var(--oecsa-gris);
  border-left: 3px solid transparent;
  cursor: help;
  text-decoration: underline dotted var(--oecsa-gris-claro);
  text-underline-offset: 3px;
}

/* -----------------------------------------------------------------------------
   Escritorio — la pantalla de entrada
   Tres columnas: quién soy, qué puedo hacer, qué hay de nuevo.
   -------------------------------------------------------------------------- */

.escritorio {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr) 260px;
  gap: 22px;
  align-items: start;
}
@media (max-width: 980px) {
  .escritorio {
    grid-template-columns: minmax(0, 1fr);
  }
}

.escritorio-persona,
.escritorio-noticias {
  min-width: 0;
}
.escritorio-centro {
  min-width: 0;
}
.escritorio-subtitulo {
  font-size: 13px;
  font-weight: 500;
  margin: 0 0 10px;
}

/* Reloj — se refresca solo con HTMX, sin JavaScript propio */
.reloj {
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio);
  padding: 14px;
  text-align: center;
  margin-bottom: 16px;
}
.reloj-hora {
  font-size: 30px;
  font-weight: 500;
  margin: 0;
  line-height: 1.2;
}
.reloj-fecha {
  font-size: 12px;
  color: var(--oecsa-gris);
  margin: 2px 0 0;
}

/* Marcador de la fotografía: el campo todavía no existe en el modelo */
.foto-marcador {
  width: 96px;
  height: 96px;
  margin: 0 auto;
  border-radius: 50%;
  background: var(--estado-neutro-bg);
  color: var(--estado-neutro-tx);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  font-weight: 500;
}
.foto-nota {
  text-align: center;
  margin-top: 6px;
}
.escritorio-nombre {
  font-size: 15px;
  font-weight: 500;
  text-align: center;
  margin: 10px 0 16px;
}

/* Ficha de datos de la persona */
.ficha {
  margin: 0;
  font-size: 12px;
}
.ficha dt {
  color: var(--oecsa-gris);
  font-size: 11px;
}
.ficha dd {
  margin: 0 0 10px;
}

/* Cuadrícula de aplicaciones */
.cuadricula {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 12px;
}
.aplicacion {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 18px 12px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
  text-decoration: none;
  text-align: center;
}
.aplicacion:hover {
  background: var(--oecsa-fila);
}
.aplicacion-inicial {
  width: 42px;
  height: 42px;
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  font-weight: 500;
}
.aplicacion-nombre {
  font-size: 13px;
  line-height: 1.3;
}
/* Tiene el permiso, falta la pantalla */
.aplicacion-pendiente {
  cursor: default;
}
.aplicacion-pendiente:hover {
  background: var(--oecsa-blanco);
}
.aplicacion-pendiente .aplicacion-inicial {
  background: var(--estado-neutro-bg);
  color: var(--oecsa-gris);
}
.aplicacion-pendiente .aplicacion-nombre {
  color: var(--oecsa-gris);
}
.aplicacion-nota {
  font-size: 11px;
  color: var(--oecsa-gris);
}

/* Estado vacío dentro de una tarjeta */
.vacio {
  text-align: center;
  color: var(--oecsa-gris);
  font-size: 13px;
}
.vacio p {
  margin: 0 0 4px;
}

/* El logo del encabezado lleva al escritorio */
.encabezado-inicio {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  color: var(--oecsa-negro);
}

/* Escritorio: primer enlace de la barra, suelto arriba de los grupos.
   Es el único con icono, porque es el único que no pertenece a un módulo. */
.lateral-inicio {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 22px;
  margin-bottom: 14px;
  font-size: 13px;
  color: var(--oecsa-negro);
  text-decoration: none;
  border-left: 3px solid transparent;
}
.lateral-inicio:hover {
  background: var(--oecsa-fila);
}
.lateral-inicio.activo {
  border-left-color: var(--oecsa-verde);
  font-weight: 500;
  background: var(--oecsa-fila);
}
.lateral-icono {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* -----------------------------------------------------------------------------
   Noticias
   -------------------------------------------------------------------------- */

.destacadas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px;
  margin-bottom: 22px;
}
.lista-noticias {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}
.noticia-tarjeta {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
  text-decoration: none;
}
.noticia-tarjeta:hover {
  background: var(--oecsa-fila);
}
.noticia-destacada {
  border-left: 4px solid var(--oecsa-verde);
}
.noticia-titulo {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
}
.noticia-portada {
  width: 100%;
  height: 140px;
  object-fit: cover;
  border-radius: var(--oecsa-radio);
}
.noticia-portada-grande {
  width: 100%;
  max-height: 420px;
  object-fit: cover;
  border-radius: var(--oecsa-radio-card);
  margin-bottom: 18px;
}
.noticia-firma {
  margin: -10px 0 16px;
  font-size: 12px;
}
.noticia-contenido {
  max-width: 70ch;
  margin-bottom: 22px;
}

.galeria {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
  margin-bottom: 22px;
}
.galeria img {
  width: 100%;
  height: 150px;
  object-fit: cover;
  border-radius: var(--oecsa-radio);
}

/* Video: proporción 16:9 sin depender del alto del iframe */
.video-marco {
  position: relative;
  padding-top: 56.25%;
  margin-bottom: 16px;
  border-radius: var(--oecsa-radio);
  overflow: hidden;
  background: var(--oecsa-fila);
}
.video-marco iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.video-propio {
  width: 100%;
  max-height: 420px;
  border-radius: var(--oecsa-radio);
  margin-bottom: 16px;
  background: var(--oecsa-negro);
}
/* Lo que no se puede incrustar va como tarjeta con botón, no como iframe roto */
.video-tarjeta {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  margin-bottom: 16px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  color: var(--oecsa-negro);
  text-decoration: none;
}
.video-tarjeta:hover {
  background: var(--oecsa-fila);
}
.video-tarjeta-icono {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--oecsa-verde);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* Reacciones */
.reacciones {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 22px 0;
}
.reaccion {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: var(--oecsa-borde);
  border-radius: 999px;
  background: var(--oecsa-blanco);
  font-size: 14px;
  cursor: pointer;
}
.reaccion:hover {
  background: var(--oecsa-fila);
}
.reaccion-mia {
  background: var(--oecsa-verde);
  border-color: var(--oecsa-verde);
}
.reaccion-cuenta {
  font-size: 12px;
  color: var(--estado-neutro-tx);
}

/* Comentarios */
.comentarios {
  max-width: 70ch;
  margin-top: 22px;
}
.comentario {
  padding: 12px 0;
  border-bottom: var(--oecsa-borde);
}
.comentario-firma {
  font-size: 12px;
  font-weight: 500;
  margin: 0 0 4px;
}
.comentario-texto {
  margin: 0;
  font-size: 13px;
}
.comentario-borrar {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-size: 12px;
}
.comentario-nuevo {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

/* Noticias en la columna del escritorio */
.noticias-breves {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.noticia-breve {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 12px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  color: var(--oecsa-negro);
  text-decoration: none;
}
.noticia-breve:hover {
  background: var(--oecsa-fila);
}
.noticia-breve-titulo {
  font-size: 13px;
  line-height: 1.35;
}

/* Fotografía de la persona. Comparte tamaño con el marcador, para que la
   pantalla no se mueva cuando alguien todavía no tiene foto. */
.foto-persona {
  width: 96px;
  height: 96px;
  margin: 0 auto;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  background: var(--estado-neutro-bg);
}
.ficha-encabezado {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
}
.foto-ficha {
  width: 72px;
  height: 72px;
  margin: 0;
  font-size: 22px;
}

/* ---------------------------------------------------------------------------
   Mensajería
   --------------------------------------------------------------------------- */

.oecsa-subtitulo {
  font-weight: 500;
  font-size: 14px;
  color: var(--oecsa-negro);
  margin: 28px 0 10px;
}

/* --- El selector de destino ------------------------------------------------

   Vive fuera del formulario: dentro, pulsar Enter en el cuadro de búsqueda
   enviaría la solicitud a medio llenar, y evitarlo pediría JavaScript. El valor
   viaja igual con form="form-solicitud". */

.selector-destino {
  margin-bottom: 14px;
}

/* Altura máxima con desplazamiento propio: la lista no puede empujar el resto
   del formulario fuera de la pantalla. */
.opciones-destino {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 260px;
  overflow-y: auto;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  padding: 8px;
  margin-top: 8px;
  background: var(--oecsa-blanco);
}

.opcion-direccion {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px;
  border-radius: var(--oecsa-radio);
  cursor: pointer;
}
.opcion-direccion:hover {
  background: var(--oecsa-gris-claro);
}
.opcion-direccion input {
  margin-top: 3px;
  flex: 0 0 auto;
}

.opcion-direccion-texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.opcion-direccion-nombre {
  font-size: 13px;
  color: var(--oecsa-negro);
}

/* Elegida: una línea, y la lista deja de ocupar media pantalla. */
.destino-elegido {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 12px;
  border: var(--oecsa-borde);
  border-left: 3px solid var(--oecsa-verde);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-blanco);
}
.destino-elegido-texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.enlace-boton {
  flex: 0 0 auto;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12px;
  color: var(--oecsa-verde);
  text-decoration: underline;
  cursor: pointer;
}

.sin-coincidencias {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 4px;
}
.sin-coincidencias-texto {
  margin: 0;
  font-size: 12px;
  color: var(--oecsa-gris);
}

/* --- Plegables sin JavaScript ----------------------------------------------

   Una casilla oculta gobierna el bloque que la sigue, por `:checked ~`. Los dos
   tienen que ser hermanos directos, así que la casilla NO va dentro de su
   etiqueta. La etiqueta puede estar en cualquier parte del documento: basta que
   su `for` coincida con el `id`, y por eso el botón «agregar al catálogo», que
   está fuera del formulario, abre el bloque de alta que está adentro. */

.interruptor-grupo {
  margin: 14px 0;
}

.interruptor {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.interruptor-etiqueta {
  display: inline-block;
  font-size: 13px;
  color: var(--oecsa-negro);
  cursor: pointer;
}
.interruptor + .interruptor-etiqueta::before {
  content: "▸ ";
  color: var(--oecsa-verde);
}
.interruptor:checked + .interruptor-etiqueta::before {
  content: "▾ ";
}
/* El foco tiene que verse: la casilla que lo recibe es invisible. */
.interruptor:focus-visible + .interruptor-etiqueta {
  outline: 2px solid var(--oecsa-verde);
  outline-offset: 2px;
}

.bloque-plegable {
  display: none;
  margin-top: 10px;
  padding: 12px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
}
.interruptor:checked ~ .bloque-plegable,
input[type="checkbox"]:checked ~ .bloque-plegable {
  display: block;
}

/* --- Botones de opción -----------------------------------------------------

   Tres opciones no son una lista desplegable. Abrir y elegir son dos
   pulsaciones; esto es una. */

.opciones-linea {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.opcion-boton {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  font-size: 13px;
  color: var(--oecsa-negro);
  background: var(--oecsa-blanco);
  cursor: pointer;
}
.opcion-boton:hover {
  background: var(--oecsa-gris-claro);
}
.opcion-boton:has(input:checked) {
  border-color: var(--oecsa-verde);
  box-shadow: inset 0 0 0 1px var(--oecsa-verde);
}

/* --- La pantalla del mensajero ---------------------------------------------

   Paleta de marca y nada más: verde C3D600, gris A8ACA1, negro 231F20. El rojo
   sobrio de los tokens de estado aparece solo para la solicitud que cerró sin
   entregarse. Sin animaciones. */

/* Pestañas: enlaces normales, así funcionan sin HTMX y se pueden guardar. */
.pestanas {
  display: flex;
  gap: 4px;
  margin: 0 0 14px;
  border-bottom: var(--oecsa-borde);
}

.pestana {
  padding: 8px 14px;
  font-size: 13px;
  color: var(--oecsa-gris);
  text-decoration: none;
  border-bottom: 3px solid transparent;
}
.pestana:hover {
  color: var(--oecsa-negro);
}
.pestana-activa {
  color: var(--oecsa-negro);
  border-bottom-color: var(--oecsa-verde);
}

/* --- El distintivo de estado -----------------------------------------------

   Cuatro familias, no ocho colores. Y el color NO es el único portador: cada
   familia lleva su propia forma —el radio del borde— y su propio peso, de modo
   que se distinguen en escala de grises. El nombre del estado va escrito
   adentro, que es lo que de verdad lo hace legible para cualquiera. */

.distintivo {
  display: inline-block;
  padding: 3px 10px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--oecsa-negro);
  white-space: nowrap;
}

/* Por salir: esquina suave, peso normal. Todavía no pasó nada. */
.distintivo-por-salir {
  border-radius: var(--oecsa-radio);
  font-weight: 400;
  background: var(--oecsa-gris-claro);
}

/* En movimiento: cápsula, peso medio. Es lo único que está ocurriendo ahora. */
.distintivo-en-movimiento {
  border-radius: 999px;
  font-weight: 500;
  background: var(--oecsa-verde);
}

/* Cerrada: rectángulo recto, peso medio. Terminó y no se mueve más. */
.distintivo-cerrada-bien {
  border-radius: 2px;
  font-weight: 500;
  background: var(--oecsa-gris);
}

/* Cerrada sin entregar: rectángulo recto con contorno, peso fuerte. */
.distintivo-cerrada-mal {
  border-radius: 2px;
  font-weight: 600;
  color: var(--estado-error-tx);
  background: var(--estado-error-bg);
  box-shadow: inset 0 0 0 1px var(--estado-error-tx);
}

/* El efectivo tiene que verse de un vistazo en la fila: se sabe antes de salir,
   no en la calle. */
.marca-efectivo {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: var(--oecsa-radio);
  font-size: 11px;
  background: var(--estado-alerta-bg);
  color: var(--estado-alerta-tx);
}

/* --- Las acciones ----------------------------------------------------------

   Van al principio del detalle: quien abre esa pantalla viene a hacer algo. */

.acciones-estado {
  margin: 0 0 22px;
}

.acciones-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
}
.accion-directa,
.accion-envuelta {
  margin: 0;
}

/* El avance natural del estado. Relleno verde con texto negro: el manual de
   marca prohíbe el verde como color de texto sobre blanco. */
.accion-principal {
  display: inline-block;
  height: 38px;
  padding: 0 18px;
  border: 1px solid var(--oecsa-verde);
  border-radius: var(--oecsa-radio);
  font-family: var(--oecsa-font);
  font-size: 13px;
  line-height: 36px;
  color: var(--oecsa-negro);
  background: var(--oecsa-verde);
  cursor: pointer;
}

/* Lo que saca la solicitud del carril: contorno, sin relleno. */
.accion-contorno {
  display: inline-block;
  height: 38px;
  padding: 0 18px;
  border: 1px solid var(--oecsa-gris);
  border-radius: var(--oecsa-radio);
  font-family: var(--oecsa-font);
  font-size: 13px;
  line-height: 36px;
  color: var(--oecsa-negro);
  background: transparent;
  cursor: pointer;
}
.accion-contorno:hover {
  border-color: var(--oecsa-negro);
}

.accion-disparo {
  vertical-align: top;
}
.interruptor:focus-visible + .accion-disparo {
  outline: 2px solid var(--oecsa-negro);
  outline-offset: 2px;
}
.accion-confirma {
  margin-top: 10px;
}

/* Las que cierran: debajo, con una línea de por medio. No se deshacen. */
.acciones-cierre {
  margin-top: 16px;
  padding-top: 12px;
  border-top: var(--oecsa-borde);
}
.acciones-cierre-aviso {
  margin: 0 0 8px;
  font-size: 11px;
  color: var(--oecsa-gris);
}
.acciones-cierre .accion-contorno {
  border-color: var(--estado-error-tx);
  color: var(--estado-error-tx);
}
.acciones-cierre .accion-contorno:hover {
  background: var(--estado-error-bg);
}

/* Cuando el grupo de cierre va solo no hay nada de lo que separarse. */
.acciones-cierre-solas {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.acciones-vacio {
  margin: 0 0 22px;
  padding: 12px 14px;
  border: var(--oecsa-borde);
  border-left: 3px solid var(--oecsa-gris);
  border-radius: var(--oecsa-radio);
  font-size: 12px;
  color: var(--oecsa-negro);
}

/* --- La pantalla de firma --------------------------------------------------

   La abre alguien de fuera de la empresa, en el teléfono del mensajero. No
   hereda de base.html: sin barra, sin menú y sin un solo enlace al resto del
   sistema. Pensada para una hoja sostenida con una mano. */

.pagina-firma {
  margin: 0;
  padding: 16px;
  font-family: var(--oecsa-font);
  font-size: 14px;
  color: var(--oecsa-negro);
  background: var(--oecsa-fila);
}

.firma-hoja {
  max-width: 520px;
  margin: 0 auto;
  padding: 20px;
  border-radius: var(--oecsa-radio-card);
  background: var(--oecsa-blanco);
}

.firma-titulo {
  margin: 0 0 4px;
  font-size: 18px;
  font-weight: 500;
}
.firma-memo {
  margin: 0 0 18px;
  font-size: 12px;
  color: var(--oecsa-gris);
}

.firma-datos {
  margin: 0 0 22px;
  padding: 14px;
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-fila);
}
.firma-datos dt {
  font-size: 11px;
  color: var(--oecsa-gris);
}
.firma-datos dd {
  margin: 0 0 10px;
  font-size: 13px;
}
.firma-datos dd:last-child {
  margin-bottom: 0;
}

.firma-lienzo-caja {
  position: relative;
  margin-bottom: 8px;
}

/* `touch-action: none` es lo que impide que arrastrar el dedo para firmar
   desplace la página en vez de dibujar. */
.firma-lienzo {
  display: block;
  width: 100%;
  height: 200px;
  border: 1px solid var(--oecsa-gris);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-blanco);
  touch-action: none;
  cursor: crosshair;
}

/* Se muestra por omisión y lo esconde el propio script al arrancar: si no
   carga, el aviso se queda y la pantalla no queda muda. */
.firma-sin-js {
  margin: 0 0 8px;
  padding: 10px 12px;
  border-radius: var(--oecsa-radio);
  font-size: 12px;
  color: var(--estado-alerta-tx);
  background: var(--estado-alerta-bg);
}

.firma-acciones {
  margin-bottom: 18px;
}

.firma-enviar {
  width: 100%;
  height: 46px;
  line-height: 44px;
  text-align: center;
  font-size: 15px;
}

.firma-confirmacion {
  margin: 0 0 14px;
  padding: 14px;
  border-radius: var(--oecsa-radio);
  font-size: 14px;
  color: var(--estado-ok-tx);
  background: var(--estado-ok-bg);
}

.firma-pie {
  margin: 18px 0 0;
  font-size: 11px;
  color: var(--oecsa-gris);
}

/* --- Lo que le toca al solicitante ------------------------------------------

   «Datos incompletos» es el único estado que exige algo de quien pidió. Sin
   marcarlo, la fila se ve igual que las demás y la persona no se entera de que
   la pelota está de su lado. */

.fila-le-toca > td {
  background: var(--estado-alerta-bg);
}
.fila-le-toca > td:first-child {
  box-shadow: inset 3px 0 0 var(--estado-alerta-tx);
}

.enlace-corregir {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  color: var(--estado-alerta-tx);
}

.aviso-firma-caducada {
  margin-top: 14px;
  padding: 12px 14px;
  border: var(--oecsa-borde);
  border-left: 3px solid var(--estado-alerta-tx);
  border-radius: var(--oecsa-radio);
}

.enlace-para-copiar {
  font-size: 12px;
}

.firma-correo {
  margin: 0 0 14px;
  font-size: 13px;
}


.firma-volver {
  margin: 0 0 8px;
}
.firma-volver .accion-principal {
  display: block;
  width: 100%;
  height: 46px;
  line-height: 44px;
  text-align: center;
  text-decoration: none;
}

/* --- Mi día ----------------------------------------------------------------

   Alan mira esto caminando y necesita el día completo de un vistazo. La medida
   es que entren seis u ocho paradas en la pantalla de un teléfono, así que cada
   fila son dos líneas y no pasa de unos 68 px de alto. */

.barra-dia {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  padding-bottom: 10px;
  border-bottom: var(--oecsa-borde);
}

/* Se usan caminando: 44 px es el mínimo con el que un pulgar acierta. */
.boton-dia {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  font-size: 18px;
  line-height: 1;
  color: var(--oecsa-negro);
  background: var(--oecsa-blanco);
  text-decoration: none;
}
.boton-dia:hover {
  background: var(--oecsa-gris-claro);
}

.barra-dia-fecha {
  font-size: 14px;
  color: var(--oecsa-negro);
  white-space: nowrap;
}
.barra-dia-relleno {
  flex: 1;
}

.bloque-dia {
  margin-bottom: 20px;
}

/* El nombre del bloque y su cuenta, en la MISMA línea. */
.bloque-encabezado {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 4px;
  padding-bottom: 4px;
  border-bottom: var(--oecsa-borde);
}
.bloque-titulo {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--oecsa-negro);
}
.bloque-cuenta {
  margin: 0;
  font-size: 11px;
  color: var(--oecsa-gris);
  white-space: nowrap;
}

/* Sin viñetas: es una lista de trabajo, no una enumeración. */
.lista-dia {
  margin: 0;
  padding: 0;
  list-style: none;
}

.parada {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-bottom: var(--oecsa-borde);
}

/* Las flechas con el número en medio: una sola columna angosta. */
.parada-mover {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
  width: 30px;
}
.parada-mover form {
  margin: 0;
  line-height: 0;
}
.parada-orden {
  font-size: 11px;
  line-height: 14px;
  color: var(--oecsa-gris);
}
.boton-mover {
  width: 30px;
  height: 18px;
  padding: 0;
  border: 0;
  font-size: 9px;
  line-height: 18px;
  color: var(--oecsa-negro);
  background: none;
  cursor: pointer;
}
.boton-mover:disabled {
  color: var(--oecsa-gris-medio);
  cursor: default;
}
/* Relleno y no color de texto: el manual de marca prohibe el verde como color
   de letra. */
.boton-mover:not(:disabled):hover {
  background: var(--oecsa-verde);
  border-radius: 3px;
}

.parada-cuerpo {
  flex: 1;
  min-width: 0;
  text-decoration: none;
}

.parada-linea {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* El peso fuerte de la fila: es lo que Alan está buscando. */
.parada-destino {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--oecsa-negro);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.parada-detalle {
  display: block;
  font-size: 11px;
  color: var(--oecsa-gris);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.parada-accion {
  flex: 0 0 auto;
}
.parada-accion form {
  margin: 0;
}

.accion-corta {
  height: 30px;
  padding: 0 10px;
  font-size: 11px;
  line-height: 28px;
  text-decoration: none;
  white-space: nowrap;
}

.parada-sin-asignar {
  background: var(--oecsa-fila);
}

.fila-grupo > td {
  padding-top: 14px;
  font-size: 11px;
  color: var(--oecsa-gris);
  background: var(--oecsa-fila);
}

/* --- Avisos ----------------------------------------------------------------

   El número solo dice que algo cambió; el texto dice qué. Estas piezas se
   pintan con lo que el aviso guardó, así que sirven para cualquier módulo. */

/* Una linea en el escritorio, no un panel: el escritorio es el lanzador de
   aplicaciones y la bandeja vive en /avisos/. */
.avisos-linea {
  margin: 12px 0;
  font-size: 12px;
}

/* El numero sobre el mosaico del modulo. */
.aplicacion {
  position: relative;
}
.aplicacion-avisos {
  position: absolute;
  top: 6px;
  right: 6px;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  text-align: center;
  color: var(--oecsa-negro);
  background: var(--oecsa-verde);
}

.lista-avisos {
  margin: 0;
  padding: 0;
  list-style: none;
}

.aviso {
  border-bottom: var(--oecsa-borde);
}
.aviso:last-child {
  border-bottom: 0;
}
.aviso form {
  margin: 0;
}

.aviso-boton {
  display: block;
  width: 100%;
  padding: 7px 4px;
  border: 0;
  border-left: 3px solid var(--oecsa-verde);
  padding-left: 8px;
  font-family: var(--oecsa-font);
  text-align: left;
  background: none;
  cursor: pointer;
}
.aviso-boton:hover {
  background: var(--oecsa-fila);
}

.aviso-texto {
  display: block;
  font-size: 12px;
  color: var(--oecsa-negro);
}
.aviso-pie {
  display: block;
  margin-top: 2px;
  font-size: 10px;
  color: var(--oecsa-gris);
}

/* Los ya leídos siguen visibles pero sin llamar la atención. */
.aviso-leido .aviso-boton {
  border-left-color: var(--oecsa-gris-claro);
}
.aviso-leido .aviso-texto {
  color: var(--oecsa-gris);
}

.avisos-pie {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 0;
  font-size: 11px;
}

.avisos-numero {
  min-width: 22px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  text-align: center;
  color: var(--oecsa-negro);
  background: var(--oecsa-verde);
}

.avisos-modulo {
  font-size: 11px;
  color: var(--oecsa-gris);
}

.avisos-vacio {
  margin: 0;
  font-size: 11px;
  color: var(--oecsa-gris);
}

/* El estado del correo del memo, a la vista en el detalle. */
.correo-estado {
  margin: 8px 0;
  padding: 8px 10px;
  border-radius: var(--oecsa-radio);
  font-size: 12px;
}
.correo-ok {
  color: var(--estado-ok-tx);
  background: var(--estado-ok-bg);
}
.correo-pendiente {
  color: var(--estado-alerta-tx);
  background: var(--estado-alerta-bg);
}
.correo-fallo {
  color: var(--estado-error-tx);
  background: var(--estado-error-bg);
}

/* ---------------------------------------------------------------- salas
   El calendario de reserva de salas. Todo con los tokens de arriba: el verde
   es acento y nunca fondo de página, y el color nunca es el único portador
   —la reserva de prioridad lleva además la etiqueta de su tipo—. */

.salas-barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin: 16px 0;
}
.salas-navegar {
  display: flex;
  align-items: center;
  gap: 6px;
}
.salas-cuando {
  font-size: 15px;
  font-weight: 500;
  margin-left: 8px;
}
/* Solo la primera letra. `capitalize` ponía «Lunes 7 De Septiembre De 2026»,
   que es Title Case y el manual lo prohíbe: la interfaz va en sentence case. */
.salas-cuando::first-letter {
  text-transform: uppercase;
}

.calendario-dia .calendario-hora {
  width: 68px;
  font-size: 12px;
  color: var(--oecsa-gris);
  font-weight: 400;
  text-align: right;
  vertical-align: top;
  white-space: nowrap;
}
.calendario-celda {
  vertical-align: top;
  padding: 2px;
  border-left: var(--oecsa-borde);
  height: 34px;
}
.calendario-libre { background: var(--oecsa-blanco); }
.calendario-hueco {
  display: block;
  height: 100%;
  min-height: 30px;
  line-height: 30px;
  text-align: center;
  color: var(--oecsa-gris-medio);
  text-decoration: none;
  border-radius: var(--oecsa-radio);
}
.calendario-hueco:hover {
  background: var(--oecsa-fila);
  color: var(--oecsa-negro);
}

/* Las dos clases de reserva. La normal es neutra; la de prioridad lleva el
   verde de marca como relleno, con el texto negro encima. */
.reserva {
  display: block;
  height: 100%;
  padding: 6px 8px;
  border-radius: var(--oecsa-radio);
  text-decoration: none;
  color: var(--oecsa-negro);
  font-size: 12px;
  overflow: hidden;
}
.reserva-normal {
  background: var(--estado-neutro-bg);
  border-left: 3px solid var(--oecsa-gris-medio);
}
.reserva-prioridad {
  background: var(--oecsa-verde);
  border-left: 3px solid var(--oecsa-negro);
}
.reserva-mia { box-shadow: inset 0 0 0 1px var(--oecsa-negro); }
.reserva-horario {
  display: block;
  font-weight: 500;
}
.reserva-motivo {
  display: block;
  margin-top: 1px;
}
.reserva-quien {
  display: block;
  font-size: 11px;
  color: var(--estado-neutro-tx);
}
.reserva-prioridad .reserva-quien { color: var(--oecsa-negro); }

.calendario-semana {
  display: grid;
  grid-template-columns: repeat(6, minmax(130px, 1fr));
  gap: 8px;
  padding: 8px;
}
.calendario-dia-columna {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 120px;
}
.calendario-encabezado {
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
  color: var(--oecsa-negro);
  text-transform: capitalize;
  padding-bottom: 4px;
  border-bottom: var(--oecsa-borde);
}
.calendario-hoy { background: var(--oecsa-fila); }

.calendario-mes .calendario-celda-mes {
  vertical-align: top;
  height: 92px;
  width: 14.28%;
  padding: 4px;
  border-left: var(--oecsa-borde);
}
.calendario-relleno { background: var(--oecsa-fila); }
.calendario-numero {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--oecsa-negro);
  text-decoration: none;
  margin-bottom: 3px;
}
.reserva-linea {
  display: block;
  font-size: 11px;
  padding: 2px 5px;
  margin-bottom: 2px;
  border-radius: 4px;
  text-decoration: none;
  color: var(--oecsa-negro);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.reserva-linea.reserva-normal { background: var(--estado-neutro-bg); }
.reserva-linea.reserva-prioridad { background: var(--oecsa-verde); }

/* --------------------------------------------------------- organigrama
   Un diagrama de cajas de arriba hacia abajo. Las líneas se dibujan con
   `::before` y `::after` sobre el HTML anidado: sin SVG, sin canvas y sin
   una sola coordenada calculada. Es la desviación aprobada del mockup, que
   era una lista sangrada. */

.organigrama-marco {
  /* El árbol se recorre dentro de su caja; la página no se desplaza entera.
     Es la misma regla que las tablas anchas. */
  overflow-x: auto;
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio);
  padding: 20px 16px;
  margin: 16px 0 24px;
}

.organigrama,
.nodo-reportes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
}
.organigrama {
  /* Varias raíces se apilan; los reportes de un mismo jefe van en fila.
     `align-items: stretch` y no `center`: con `center` cada raíz se centraba
     sobre su propio ancho y quedaban escalonadas. Estiradas, cada una centra
     su propio subárbol y todas caen sobre el mismo eje. */
  flex-direction: column;
  /* `flex-start` y no `center` ni `stretch`: con las dos, cada raíz se
     centraba sobre el ancho de la MÁS ancha, y como una tiene siete reportes
     abiertos, las otras cuatro quedaban con mil píxeles de blanco a la
     izquierda. Cada raíz arranca en el margen y centra lo suyo. */
  align-items: flex-start;
  gap: 28px;
  width: max-content;
  min-width: 100%;
}

.nodo {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  /* La separación entre hermanos es relleno y no `gap`: el `::after` que
     dibuja la horizontal cubre el relleno, y con `gap` la línea salía
     cortada entre caja y caja. */
  padding: 18px 7px 0;
}
/* La vertical corta que entra a cada tarjeta desde la horizontal de arriba. */
.nodo::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 1px;
  height: 18px;
  background: var(--oecsa-gris-claro);
}
/* La horizontal que une a los hermanos. El primero la recorta por la
   izquierda y el último por la derecha, para que no sobresalga del grupo. */
.nodo::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--oecsa-gris-claro);
}
.nodo:first-child::after { left: 50%; }
.nodo:last-child::after { right: 50%; }
.nodo:only-child::after { left: 50%; right: 50%; }
/* Las raíces cuelgan de nada: sin líneas ni hueco arriba. */
.organigrama > .nodo {
  padding-top: 0;
}
.organigrama > .nodo::before,
.organigrama > .nodo::after {
  content: none;
}

.nodo-plegable {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.nodo-resumen {
  /* `display: block` y ancho al contenido. Por omisión un `<summary>` es
     `list-item` a lo ancho de su caja, y entonces la tarjeta quedaba a la
     izquierda del centro y la línea del jefe no caía sobre la de sus
     reportes. */
  display: block;
  width: max-content;
  max-width: 100%;
  list-style: none;
  cursor: pointer;
}
.nodo-resumen::-webkit-details-marker { display: none; }
/* La vertical que baja de la tarjeta del jefe hacia sus reportes. Solo
   cuando está abierto: cerrado no hay nada abajo que unir. */
.nodo-plegable[open] > .nodo-reportes {
  position: relative;
  margin-top: 18px;
  align-items: flex-start;
}
.nodo-plegable[open] > .nodo-reportes::before {
  content: "";
  position: absolute;
  top: -18px;
  left: 50%;
  width: 1px;
  height: 18px;
  background: var(--oecsa-gris-claro);
}

.nodo-tarjeta {
  /* Ancho fijo: todas las cajas del diagrama miden lo mismo, que es lo que
     hace que un organigrama se lea. Los nombres largos —hay de cuarenta
     caracteres— parten en dos líneas dentro de la caja. */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  width: 250px;
  padding: 9px 12px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-blanco);
  text-align: left;
}
.nodo-tarjeta .celda-persona {
  /* `min-width: 0` para que el texto largo parta en vez de estirar la caja. */
  flex: 1;
  min-width: 0;
}
.nodo-tarjeta .celda-persona > a {
  overflow-wrap: anywhere;
}
/* La raíz con el borde negro, como en el mockup. */
.nodo-tarjeta-raiz { border-color: var(--oecsa-negro); }
/* Los que quedan solo como camino con un departamento filtrado. Mantienen
   sus líneas: se tiene que ver por dónde cuelga el departamento. */
.nodo-contexto > .nodo-plegable > .nodo-resumen > .nodo-tarjeta,
.nodo-contexto > .nodo-tarjeta {
  background: var(--oecsa-fila);
  opacity: 0.7;
}
.nodo-insignias {
  /* En su propia línea: al lado del nombre le robaban el ancho y los nombres
     largos partían en tres líneas mientras la insignia se salía de la caja. */
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  flex-basis: 100%;
}
.nodo-insignias:empty { display: none; }

.banda-pendientes {
  margin-top: 24px;
  padding-top: 12px;
  border-top: var(--oecsa-borde);
}

@media print {
  /* Lo único que se hace por imprimir: quitar lo que no es el diagrama.
     No hay botón de exportar. */
  .encabezado,
  .lateral,
  .filtros,
  .acciones { display: none; }
  .disposicion { display: block; }
  .principal { padding: 0; }
  .organigrama-marco {
    overflow: visible;
    background: var(--oecsa-blanco);
    padding: 0;
  }
  .nodo-tarjeta { break-inside: avoid; }
}

/* --- Mesa de ayuda IT ------------------------------------------------------
   El aviso del bloqueo. Es lo primero que ve quien no puede abrir un ticket, y
   por eso pesa: borde ámbar y fondo claro, como los demás avisos que piden una
   acción. No es un error —no hizo nada mal— así que no va en rojo. */
.aviso-bloqueo {
  margin: 0 0 16px;
  padding: 14px 16px;
  border: 1px solid var(--oecsa-ambar-borde, #FAC775);
  background: var(--oecsa-ambar-fondo, #FAEEDA);
  border-radius: 8px;
}
.aviso-bloqueo-titulo {
  margin: 0 0 6px;
  font-weight: 500;
  font-size: 13px;
}
.aviso-bloqueo p {
  margin: 0 0 6px;
  font-size: 12px;
}
.aviso-bloqueo-lista {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: 12px;
}

/* La tarjeta de calificar va primero en el detalle y se distingue: es lo único
   que se le pide a quien mira. */
.tarjeta-calificar {
  border-color: var(--oecsa-negro);
}

/* Las cinco opciones, una por línea y con área de toque cómoda: calificar tiene
   que costar un clic, no puntería. */
.calificacion {
  margin: 0 0 12px;
  padding: 0;
  border: 0;
}
.calificacion legend {
  padding: 0;
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 500;
}
.calificacion ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.calificacion li {
  margin: 0 0 2px;
}
.calificacion label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  font-size: 13px;
  cursor: pointer;
}

.estado-ticket {
  font-size: 12px;
}

.lista-comentarios {
  margin: 0;
  padding: 0;
  list-style: none;
}
.comentario {
  padding: 10px 0;
  border-bottom: var(--oecsa-borde);
}
.comentario:last-child {
  border-bottom: 0;
}
.comentario p {
  margin: 0 0 4px;
  font-size: 13px;
}
.comentario-quien {
  font-size: 11px;
  color: var(--oecsa-gris);
}
/* El interno se distingue por fondo Y por la insignia: el color nunca es el
   único portador. */
.comentario-interno {
  background: var(--oecsa-hueso, #F5F5F3);
  padding-left: 10px;
  padding-right: 10px;
}
