/* =============================================================================
   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;

  /* El cajón del menú: el velo que tapa la página y la sombra del panel.
     Salen del negro corporativo con transparencia, no de un gris aparte. */
  --oecsa-velo: rgba(35, 31, 32, 0.35);
  --oecsa-sombra: 0 8px 28px rgba(35, 31, 32, 0.18);
  --oecsa-ancho-menu: 264px;

  /* Los rellenos de la matriz de asistencia. Suaves a propósito: la letra
     encima tiene que leerse, y una cuadrícula de treinta columnas con colores
     saturados marea antes de informar. */
  --codigo-completo: #E8F0A8;
  --codigo-parcial: #FDEBC0;
  --codigo-incompleto: #FBD9D9;
  --codigo-ausente: #F5B9B9;
  --codigo-permiso: #D6ECF9;
  --codigo-otorgado: #E4DDF7;
  --codigo-descanso: #ECECEC;
  --codigo-asueto: #F0DCF5;
  --codigo-visita: #D9E6F7;
  --codigo-septimo: #CDE9E5;
}

/* -----------------------------------------------------------------------------
   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;
}

/* `hidden` esconde siempre (CONVENCIONES §16). Sin esto, cualquier clase con
   `display: flex` o `grid` le gana al atributo y el elemento sigue viéndose:
   pasó con el buscador de SYSO el 27/10/2026. */
[hidden] {
  display: none !important;
}

/* 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);
}
/* Un cuadro de texto largo con `.campo`: sin esto heredaba los 38 px de alto
   de una línea y nunca mostraba los renglones que pedía (27/10/2026). */
textarea.campo {
  height: auto;
  min-height: 38px;
  padding: 9px 12px;
  line-height: 1.5;
  resize: vertical;
}
.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;
}

/* Ordenar por columna y buscar en la tabla (DECISIONES 1.353). El botón lo
   pone `ordenar-tablas.js` en las tablas de una página; el enlace,
   `{% th_orden %}` en las paginadas, que ordenan en el servidor. Los dos se
   ven como el texto del encabezado, con una flecha. */
.tabla thead th .orden-columna,
.tabla thead th .orden-enlace {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  text-decoration: none;
  cursor: pointer;
}
.tabla thead th .orden-columna::after,
.tabla thead th .orden-enlace::after {
  content: "↕";
  font-size: 11px;
  opacity: 0.45;
}
.tabla thead th[aria-sort="ascending"] .orden-columna::after,
.tabla thead th[aria-sort="ascending"] .orden-enlace::after {
  content: "↑";
  opacity: 1;
}
.tabla thead th[aria-sort="descending"] .orden-columna::after,
.tabla thead th[aria-sort="descending"] .orden-enlace::after {
  content: "↓";
  opacity: 1;
}
.tabla thead th .orden-columna:focus-visible,
.tabla thead th .orden-enlace:focus-visible {
  outline: 2px solid var(--oecsa-verde);
  outline-offset: 2px;
}
.buscador-tabla {
  max-width: 520px;
  margin: 4px 0 10px;
}
.buscador-tabla .campo-ayuda {
  margin: 6px 0 0;
}
@media print {
  .buscador-tabla { display: none; }
  .tabla thead th .orden-columna::after,
  .tabla thead th .orden-enlace::after { content: none; }
}

/* 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;
}
/* La versión desplegada, al lado del nombre del sistema. Gris y pequeña: es un
   dato de apoyo, no parte del logotipo, y no puede competir con «OERP». */
.encabezado-version {
  font-size: 11px;
  color: var(--oecsa-gris);
  letter-spacing: 0.02em;
  margin-left: 8px;
  white-space: nowrap;
}
.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: var(--oecsa-ancho-menu);
  flex-shrink: 0;
  border-right: var(--oecsa-borde);
  padding: 18px 0;
  background: var(--oecsa-blanco);
}
/* El título del grupo es el `<summary>` de un `<details>`: se pliega sin
   JavaScript. El triángulo del navegador se cambia por una flecha propia. */
.lateral-titulo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 11px;
  font-weight: 500;
  color: var(--oecsa-negro);
  margin: 0;
  padding: 6px 22px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.lateral-titulo::-webkit-details-marker {
  display: none;
}
.lateral-titulo::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--oecsa-gris);
  border-bottom: 1.5px solid var(--oecsa-gris);
  transform: rotate(-45deg);
  transition: transform 0.15s;
}
.lateral-grupo[open] > .lateral-titulo::after {
  transform: rotate(45deg);
}
.lateral-titulo:hover {
  background: var(--oecsa-fila);
}
.lateral-titulo:focus-visible,
.lateral-enlace:focus-visible,
.lateral-inicio:focus-visible {
  outline: 2px solid var(--oecsa-negro);
  outline-offset: -2px;
}
.lateral-grupo {
  margin-bottom: 8px;
}
.lateral-grupo[open] {
  margin-bottom: 12px;
}
.lateral-enlace {
  display: flex;
  align-items: center;
  gap: 9px;
  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);
}
.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);
}

/* Fila que sale de una excepcion sobre el rol, no del rol.
   El ambar es el del mockup de permisos aprobado: es lo que hace visible que
   alguien decidio esto para esta persona en particular. Sin la marca, una
   excepcion se pierde entre las filas normales y nadie la audita nunca.
   El selector lleva `.tabla tbody tr` para ganarle al rayado de filas pares,
   que si no le pisa el fondo a la mitad de las excepciones. */
.tabla tbody tr.fila-excepcion td {
  background: var(--estado-alerta-bg);
}
.origen-excepcion {
  color: var(--estado-alerta-tx);
  font-weight: 500;
}

/* -----------------------------------------------------------------------------
   Detalle — ficha de una persona
   -------------------------------------------------------------------------- */

.miga {
  font-size: 12px;
  margin: -8px 0 18px;
}
/* El enlace de la miga no lleva clase propia en las plantillas, y en la hoja no
   hay ninguna regla para `a` suelto: sin esto sale azul y subrayado del
   navegador, que es justo lo que se reportó de la hoja de reportes. Se estila
   el descendiente y no `a` a secas para no subrayar los botones, que también
   son `<a>` —`.btn-primario`, `.accion-contorno`— y no declaran
   `text-decoration`. */
.miga a {
  color: var(--oecsa-negro);
  text-decoration: underline;
}
.miga a:hover {
  color: var(--oecsa-gris);
}

/* 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;
}
/* La capa que hace clicable la fila entera, **solo dentro de una fila de
   tabla**, que es la que tiene `position: relative`. Fuera de una tabla —las
   listas de la reunión de Impact, el detalle de una contratación— la capa se
   estiraba hasta el contenedor posicionado más cercano, tapaba la agenda y
   «Ir a este paso» mandaba a un cuello de botella (08/10/2026). */
.tabla tbody tr .enlace-fila::after {
  content: "";
  position: absolute;
  inset: 0;
}
.enlace-fila:hover {
  text-decoration: underline;
}
/* Si la fila trae controles —las celdas de captura de indicadores, un botón de
   baja, otro enlace—, el enlace no se estira: su capa invisible les quedaba
   encima y el clic se iba al detalle. En la captura de indicadores no dejaba
   escribir el número (05/10/2026). A esas filas se entra por el nombre. */
.tabla tbody tr:has(input, select, textarea, button, summary, a:not(.enlace-fila)) .enlace-fila::after {
  content: none;
}

/* -----------------------------------------------------------------------------
   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);
  }
}
/* Desde el 23/09/2026 el ancho que le toca al escritorio depende de si el menú
   está fijado, no solo de la pantalla. Se pregunta al marco y no a la ventana:
   con el menú fijo en 1024 px, las tres columnas dejaban 140 px para las
   aplicaciones. Donde no haya consultas de contenedor, queda la regla de
   arriba. */
.escritorio-marco {
  container-type: inline-size;
}
@container (min-width: 981px) {
  .escritorio {
    grid-template-columns: 240px minmax(0, 1fr) 260px;
  }
}
/* Con menos espacio, lo que baja es la ficha de la persona y no las noticias:
   las noticias van siempre a la derecha (DECISIONES 1.195). */
@container (max-width: 980px) {
  .escritorio {
    grid-template-columns: minmax(0, 1fr) 220px;
  }
  .escritorio-centro {
    grid-column: 1;
    grid-row: 1;
  }
  .escritorio-noticias {
    grid-column: 2;
    grid-row: 1;
  }
  .escritorio-persona {
    grid-column: 1 / -1;
    grid-row: 2;
  }
}
@container (max-width: 640px) {
  .escritorio {
    grid-template-columns: minmax(0, 1fr);
  }
  .escritorio-centro,
  .escritorio-noticias,
  .escritorio-persona {
    grid-column: auto;
    grid-row: auto;
  }
  /* En el teléfono no cabe una columna al lado: van las aplicaciones, después
     las noticias y al final la ficha de la persona. */
  .escritorio-centro {
    order: -2;
  }
  .escritorio-noticias {
    order: -1;
  }
}

.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;
}
/* El mosaico es la tarjeta; el enlace de adentro la ocupa entera con su
   `::after`, y la estrella queda encima en su propio formulario (un botón no
   puede ir dentro de un enlace). */
.aplicacion {
  position: relative;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  background: var(--oecsa-blanco);
}
.aplicacion:hover {
  background: var(--oecsa-fila);
}
.aplicacion-enlace {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 18px 12px 16px;
  color: var(--oecsa-negro);
  text-decoration: none;
  text-align: center;
}
.aplicacion-enlace::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--oecsa-radio-card);
}
.aplicacion-enlace:focus-visible {
  outline: none;
}
.aplicacion-enlace:focus-visible::after {
  outline: 2px solid var(--oecsa-negro);
  outline-offset: 2px;
}
/* El icono va sobre el verde, con el trazo negro: la única forma en que la
   marca deja usar el verde. */
.aplicacion-icono {
  width: 42px;
  height: 42px;
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-verde);
  display: flex;
  align-items: center;
  justify-content: center;
}
.aplicacion-icono img {
  width: 24px;
  height: 24px;
  display: block;
}
.aplicacion-nombre {
  font-size: 13px;
  line-height: 1.3;
}
.aplicacion-favorito {
  position: absolute;
  top: 4px;
  left: 4px;
  z-index: 1;
  margin: 0;
}
.boton-estrella {
  width: 30px;
  height: 30px;
  padding: 5px;
  border: 0;
  border-radius: var(--oecsa-radio);
  background: transparent;
  cursor: pointer;
  opacity: 0.45;
}
.boton-estrella img {
  width: 20px;
  height: 20px;
  display: block;
}
.boton-estrella[aria-pressed="true"],
.aplicacion:hover .boton-estrella,
.boton-estrella:focus-visible {
  opacity: 1;
}
.boton-estrella:hover {
  background: var(--oecsa-blanco);
}
.boton-estrella:focus-visible {
  outline: 2px solid var(--oecsa-negro);
}
@media (hover: none) {
  .boton-estrella {
    opacity: 0.8;
  }
}

/* Los grupos del escritorio: «Mis favoritos» y los mismos de la barra. */
.escritorio-grupo {
  margin-bottom: 22px;
}
.escritorio-ayuda {
  margin: 0;
}

/* 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;
}
/* El formulario de la foto, al lado del círculo. */
.ficha-foto-carga {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}
.ficha-foto-carga .campo-etiqueta,
.ficha-foto-carga .campo-ayuda {
  flex-basis: 100%;
  margin: 0;
}

/* ---------------------------------------------------------------------------
   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);
}

/* El botón del estado arriba y, debajo, «Comentar» y «Memo». Una columna para
   no robarle ancho al destino, que es lo que se busca en la fila. */
.parada-pila {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
.parada-extras {
  display: flex;
  gap: 4px;
}
.parada-extras .accion-corta {
  height: 26px;
  padding: 0 8px;
  line-height: 24px;
}

/* El cuadro de comentar de una parada: abierto, a lo ancho de toda la fila.
   Por eso la fila puede partirse en dos renglones. */
.parada {
  flex-wrap: wrap;
}
.parada > .parada-plegable {
  flex: 1 0 100%;
  margin-top: 4px;
  margin-bottom: 6px;
}

/* En el teléfono «Memo» sale de la fila y entra al cuadro de «Comentar»: los
   dos botones juntos le quitaban la mitad del ancho al destino. */
.parada-memo-alterno {
  display: none;
  margin: 10px 0 0;
  font-size: 13px;
}
@media (max-width: 600px) {
  .parada-extras .parada-memo {
    display: none;
  }
  .parada-memo-alterno {
    display: block;
  }
}

/* --- Comentarios de una solicitud -------------------------------------------

   Los comentarios sueltos y las notas de los cambios de estado, en el orden en
   que se escribieron. El estado del correo va debajo de cada uno, en gris. */

.conversacion {
  margin: 0 0 12px;
  padding: 0;
  list-style: none;
}
.conversacion-renglon {
  padding: 8px 0;
  border-bottom: var(--oecsa-borde);
}
.conversacion-encabezado {
  margin: 0 0 2px;
  font-size: 11px;
  color: var(--oecsa-gris);
}
.conversacion-encabezado strong {
  font-weight: 500;
  color: var(--oecsa-negro);
}
.conversacion-texto {
  margin: 0;
  font-size: 13px;
  color: var(--oecsa-negro);
  overflow-wrap: anywhere;
}
.conversacion-correo {
  margin: 2px 0 0;
  font-size: 11px;
  color: var(--oecsa-gris);
}
.conversacion-formulario {
  max-width: 560px;
  margin-bottom: 8px;
}

/* Las atrasadas de «Mi día»: una raya a la izquierda y no un fondo entero. El
   color no es el único portador: la fila dice además de qué día es. */
.parada-atrasada {
  border-left: 3px solid var(--estado-alerta-tx);
  padding-left: 8px;
}
.parada-atraso {
  font-size: 11px;
  color: var(--estado-alerta-tx);
  white-space: nowrap;
}

.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; }
/* La dirección general: una caja raíz con las tarjetas de quienes comparten
   el puesto, una al lado de la otra. El borde negro es el de la raíz. */
.nodo-direccion {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  padding: 8px;
  border: 1px solid var(--oecsa-negro);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-fila);
}
.nodo-direccion-titulo {
  flex-basis: 100%;
  text-align: center;
}

.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;
}
/* La evaluación del vale: tres preguntas de 1 a 5 estrellas. En renglón y no
   en columna, para que las tres quepan en la pantalla sin bajar. */
.calificacion-estrellas ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 16px;
}
.calificacion-estrellas label {
  letter-spacing: 1px;
}

.estado-ticket {
  font-size: 12px;
}

/* Cuatro clases que las plantillas de la mesa de ayuda ya usaban y que nunca
   se agregaron acá: el título de una tarjeta salía con el tamaño de `<h2>` del
   navegador, las filas del formulario sin separación, y `sr-only` —que existe
   para esconder una etiqueta de la vista y dejarla para el lector de
   pantalla— no escondía nada, así que la etiqueta se veía. */
.tarjeta-titulo {
  margin: 0 0 12px;
  font-size: 14px;
  font-weight: 500;
  color: var(--oecsa-negro);
}
.campo-fila {
  margin: 0 0 14px;
}
.campo-fila > label {
  display: block;
  margin: 0 0 4px;
  font-size: 12px;
  color: var(--oecsa-gris);
}
.ficha-detalle {
  margin: 12px 0 0;
  padding-top: 12px;
  border-top: var(--oecsa-borde);
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-line;
}
/* Fuera de la vista, presente para el lector de pantalla. Es el recorte de una
   línea que usa todo el mundo; no se inventa nada. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.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 «Borrar» de cada comentario va en la misma línea que quién y cuándo, así
   que su formulario tiene que dejar de ser un bloque. `.comentario-borrar` ya
   existe —es el de noticias— y se reusa tal cual. */
.comentario-borrar-forma {
  display: inline;
  margin-left: 6px;
}
.comentario-borrar {
  color: var(--oecsa-gris);
  text-decoration: underline;
}
.comentario-borrar:hover {
  color: var(--oecsa-negro);
}

/* 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;
}

/* -----------------------------------------------------------------------------
   Reportería
   ----------------------------------------------------------------------------- */

/* El índice: una tarjeta por reporte, en columna. No son mosaicos como el
   escritorio porque cada uno lleva una línea de explicación, y un mosaico de
   130 px no la aguanta. */
.lista-reportes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.reporte-tarjeta {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 10px;
  padding: 16px 18px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
  text-decoration: none;
}
.reporte-tarjeta:hover {
  background: var(--oecsa-fila);
}
.reporte-nombre {
  font-size: 14px;
  font-weight: 500;
}
.reporte-descripcion {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--oecsa-gris);
  line-height: 1.4;
}
/* Sin acceso al módulo del que salen los datos. Se ve, no se abre: quien no lo
   tiene necesita saber que existe para poder pedirlo. */
.reporte-vedado {
  cursor: default;
  background: var(--oecsa-fila);
}
.reporte-vedado:hover {
  background: var(--oecsa-fila);
}
.reporte-vedado .reporte-nombre {
  color: var(--oecsa-gris);
}

/* Cinco números en la fila del resumen, no cuatro. */
.metricas-cinco {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
@media (max-width: 980px) {
  .metricas-cinco {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
/* La letra chica de una métrica: sobre cuántas filas se calculó. Un promedio
   nunca se pinta solo. */
.metrica-nota {
  font-size: 11px;
  color: var(--oecsa-gris);
  line-height: 1.35;
  margin: 4px 0 0;
}

/* El panel de filtros del reporte. Los básicos arriba, el resto dentro de un
   <details> que abre solo si trae algo puesto. */
.filtros-reporte {
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  padding: 16px 18px;
  margin-bottom: 20px;
  background: var(--oecsa-blanco);
}
.filtros-linea {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
  align-items: start;
}
/* Un grupo de casillas va como <fieldset> para que su <legend> lo anuncie; sin
   esto traería el marco y el relleno que el navegador le pone por omisión. */
fieldset.filtro-campo {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}
.filtro-campo .campo {
  width: 100%;
}
.filtro-campo .campo-ayuda {
  margin: 4px 0 0;
}
/* Los de casillas —tipo, estado, jornada— toman el renglón entero: ocho
   estados en una columna de 190 px salen en ocho renglones. */
.filtro-campo-ancho {
  grid-column: 1 / -1;
}
/* Django pinta un grupo de casillas como un <div> contenedor con un <div> por
   opción. No es una lista, así que no hay <ul> que darle estilo. */
.filtro-campo-ancho > div {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 4px;
}
.filtro-campo-ancho > div label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  cursor: pointer;
}
.filtros-mas {
  margin-top: 14px;
  border-top: var(--oecsa-borde);
  padding-top: 12px;
}
.filtros-mas-titulo {
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.filtros-grupo {
  border: 0;
  padding: 0;
  margin: 14px 0 0;
}
.filtros-grupo-titulo {
  font-size: 12px;
  color: var(--oecsa-gris);
  padding: 0;
  margin-bottom: 6px;
}
.filtros-acciones {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 16px;
}

/* Un formulario de un solo control dentro de una celda: el select y su botón
   en la misma línea. Lo usa el mapeo de equipos del reloj, donde cada renglón
   se guarda por su cuenta. */
.fila-en-linea {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
/* `.campo` es de ancho completo, que dentro de una celda empuja el botón al
   siguiente renglón. Acá el control cede el ancho que el botón necesita. */
.fila-en-linea .campo {
  flex: 1 1 200px;
  width: auto;
  min-width: 0;
}

/* Una lista corta de nombres o códigos, sin la viñeta del navegador ni la
   sangría. Para enumerar lo que hay que arreglar, no para texto corrido. */
.lista-simple {
  list-style: none;
  padding: 0;
  margin: 8px 0 0;
}
.lista-simple li {
  padding: 4px 0;
  border-bottom: var(--oecsa-borde);
  font-size: 13px;
}
.lista-simple li:last-child {
  border-bottom: 0;
}

/* ── La matriz de asistencia ──────────────────────────────────────────────
   Una columna por día y hasta treinta y un días: la tabla no cabe en la
   pantalla y se desplaza dentro de su marco, con la columna de la persona
   fija para no perder de vista de quién es el renglón. */
.tabla-matriz {
  font-size: 12px;
}
.tabla-matriz .matriz-persona {
  position: sticky;
  left: 0;
  background: var(--oecsa-blanco);
  min-width: 190px;
  z-index: 1;
}
.tabla-matriz thead .matriz-persona {
  background: var(--oecsa-negro);
}
.tabla-matriz tbody tr:nth-child(even) .matriz-persona {
  background: var(--oecsa-fila);
}
.matriz-dia {
  text-align: center;
  min-width: 26px;
  padding: 6px 2px;
}
.matriz-celda {
  text-align: center;
  font-weight: 600;
  padding: 6px 2px;
  white-space: nowrap;
}

/* Los códigos, con relleno como en el sistema anterior: en una cuadrícula de
   treinta columnas, el color es lo que deja ver el patrón de un vistazo —quién
   falta los lunes, quién tiene la semana partida— sin leer letra por letra.
   Son los mismos colores de allá, ajustados para que el texto contraste.

   **El color acompaña a la letra, nunca la reemplaza.** La letra es la que
   planilla lee desde hace años, es la que sale en el CSV, y es la única que
   funciona en una impresión en blanco y negro o para quien no distingue esos
   tonos. Por eso los rellenos son suaves y el texto va oscuro. */
.matriz-celda {
  border-radius: 3px;
}
.codigo-X {
  background: var(--codigo-completo);
  color: var(--oecsa-negro);
}
.codigo-H {
  background: var(--codigo-parcial);
  color: #6B3E00;
}
.codigo-F {
  background: var(--codigo-incompleto);
  color: #8A2020;
}
.codigo-A {
  background: var(--codigo-ausente);
  color: #7A1414;
}
.codigo-P {
  background: var(--codigo-permiso);
  color: #10486F;
}
.codigo-G {
  background: var(--codigo-otorgado);
  color: #4B2D8F;
}
.codigo-D {
  background: var(--codigo-descanso);
  color: #4A4A4A;
}
.codigo-AS {
  background: var(--codigo-asueto);
  color: #6B2278;
}
.codigo-V {
  background: var(--codigo-visita);
  color: #1B4D8F;
}
.codigo-7 {
  background: var(--codigo-septimo);
  color: #0A5C55;
}

/* La leyenda usa la misma clase, así que el cuadrito de color y la celda de la
   tabla no se pueden desparejar. */
.leyenda-codigo {
  display: inline-block;
  min-width: 26px;
  padding: 2px 6px;
  border-radius: 3px;
  text-align: center;
  font-weight: 700;
}

/* ── La columna de selección de la matriz, y el subreporte ────────────────
   El número que aparece al marcar es el orden del subreporte, no un
   correlativo de la tabla: por eso se pinta al lado de la casilla y no en la
   cabecera. */
.matriz-elegir {
  position: sticky;
  left: 0;
  background: var(--oecsa-blanco);
  text-align: center;
  white-space: nowrap;
  min-width: 46px;
  z-index: 2;
}
.tabla-matriz thead .matriz-elegir {
  background: var(--oecsa-negro);
}
.tabla-matriz tbody tr:nth-child(even) .matriz-elegir {
  background: var(--oecsa-fila);
}
/* La columna de la persona corre a la derecha de la de selección. */
.tabla-matriz .matriz-persona {
  left: 46px;
}
.matriz-numero {
  font-weight: 700;
  font-size: 11px;
  margin-left: 3px;
}
.tabla-matriz .fila-elegida .matriz-persona,
.tabla-matriz .fila-elegida .matriz-elegir {
  background: var(--codigo-completo);
}

/* La hoja del subreporte: cada obra en su página cuando se pide así. */
.hoja {
  margin-bottom: 24px;
}
.hoja-encabezado {
  display: none;
  font-size: 11px;
  margin: 0 0 8px;
}

@media print {
  /* El subreporte y la matriz se imprimen con la impresión del navegador. No
     hay una vista aparte que armar ni un PDF que generar: la misma página, sin
     la barra ni los controles. El sistema viejo abría una ventana y escribía
     el HTML con JavaScript; esto hace lo mismo sin una línea de código. */
  .encabezado,
  .lateral,
  .no-imprimir,
  .filtros-reporte,
  .metricas,
  .paginacion { display: none; }
  .disposicion { display: block; }
  .principal { padding: 0; }
  .hoja-encabezado { display: block; }
  .hoja { break-after: page; }
  .hoja:last-child { break-after: auto; }
  .tabla-marco { overflow: visible; }
  .tabla-matriz { font-size: 8px; }
  .tabla-matriz .matriz-elegir,
  .tabla-matriz .matriz-persona {
    position: static;
  }
  /* Los rellenos de los códigos tienen que salir en papel: son la mitad de por
     qué la matriz se lee de un vistazo. */
  .matriz-celda,
  .leyenda-codigo {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  @page { size: landscape; margin: 10mm; }
}

/* El enlace de la celda no se pinta de azul ni se subraya: la celda ya dice
   con su color y su letra lo que pasa, y un subrayado en treinta columnas es
   ruido. Se descubre al pasar el cursor. */
.matriz-enlace {
  color: inherit;
  text-decoration: none;
  display: block;
}
.matriz-enlace:hover,
.matriz-enlace:focus {
  text-decoration: underline;
}

/* -----------------------------------------------------------------------------
   Directorio y firma de correo
   ----------------------------------------------------------------------------- */

.directorio-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}
.directorio-tarjeta {
  text-align: center;
  padding: 16px 12px;
}
.directorio-tarjeta .foto-persona,
.directorio-tarjeta .foto-marcador {
  margin: 0 auto 10px;
}
.directorio-nombre {
  margin: 0 0 4px;
  font-size: 13px;
  font-weight: 500;
  color: var(--oecsa-negro);
}
.directorio-puesto {
  margin: 0 0 2px;
  font-size: 12px;
  color: var(--oecsa-negro);
}
.directorio-extension {
  margin: 8px 0 2px;
  font-size: 13px;
  font-weight: 500;
}
.directorio-correo {
  font-size: 11px;
  word-break: break-all;
}
.directorio-cumpleanos {
  margin-bottom: 18px;
}
.directorio-cuentas {
  margin-top: 28px;
}

/* La vista previa de la firma. No reutiliza `.firma-lienzo`, que es el lienzo
   de dibujo de la firma de recibido en mensajería: son dos cosas distintas con
   el mismo nombre en castellano. */
.firma-correo-caja {
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-fila);
  padding: 16px;
  margin-bottom: 12px;
}
.firma-correo-vista {
  display: block;
  width: 100%;
  max-width: 800px;
  height: auto;
  background: var(--oecsa-blanco);
}

/* -----------------------------------------------------------------------------
   Timeboxing
   ----------------------------------------------------------------------------- */

.timebox-columnas {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
@media (max-width: 900px) {
  .timebox-columnas { grid-template-columns: minmax(0, 1fr); }
}
.timebox-cabecera,
.timebox-agenda {
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  padding: 16px 20px;
}
.timebox-estado {
  font-size: 11px;
  color: var(--oecsa-gris);
}
.timebox-estado-texto {
  font-size: 11px;
  color: var(--oecsa-gris);
}
.timebox-texto {
  font-size: 13px;
  margin: 0 0 10px;
  white-space: pre-line;
}
.timebox-bloques {
  list-style: none;
  padding: 0;
  margin: 8px 0 16px;
}
.timebox-bloque {
  border-bottom: var(--oecsa-borde);
}
.timebox-bloque:last-child {
  border-bottom: 0;
}
.timebox-bloque form {
  padding: 5px 0;
}
/* La hora: su texto, el selector y «Marcar» en una fila; debajo, sus tareas. */
.timebox-fila {
  display: flex;
  align-items: center;
  gap: 10px;
}
.timebox-hora {
  font-size: 12px;
  font-weight: 600;
  color: var(--oecsa-negro);
  width: 44px;
  flex-shrink: 0;
}
.timebox-actividad {
  flex: 1;
  min-width: 0;
}
.timebox-actividad-fija {
  flex: 1;
  font-size: 13px;
}
/* El botón de marcar la hora. **No lleva `btn-bloque`**: esa clase significa
   «botón que ocupa el ancho del contenedor» y la usan las pantallas de ingreso
   y de contraseña. Acá, dentro de la fila flex, pedía el 100% del ancho y
   aplastaba el campo de la actividad hasta dejarlo sin dónde escribir: el
   módulo entero parecía de solo lectura. El nombre coincidía por casualidad
   —«bloque» de ancho completo contra «bloque» de una hora— y por eso no se vio
   al escribirlo. */
.timebox-marcar {
  flex: none;
  padding: 5px 12px;
  font-size: 13px;
}
.timebox-hecho .timebox-marcar {
  background: var(--oecsa-verde);
  border-color: var(--oecsa-verde);
}
/* Un bloque cumplido se atenúa; no se tacha con color, que en una lista de once
   renglones se vuelve ruido. */
.timebox-hecho .timebox-actividad,
.timebox-hecho .timebox-actividad-fija {
  color: var(--oecsa-gris);
  text-decoration: line-through;
}

/* -----------------------------------------------------------------------------
   Tarjeta corporativa
   ----------------------------------------------------------------------------- */

/* Los montos alineados a la derecha y con cifras de ancho fijo: una columna de
   dinero se lee comparando, y para comparar tienen que estar alineados. */
.celda-monto {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- El kiosco de asistencia ------------------------------------------------

   La tableta fija de una ubicación. Como la firma de mensajería, no hereda de
   base.html. Todo es grande: se usa de pie, con el dedo, a veces con guantes, y
   un botón de 36 px en una tableta es un botón que se falla. */

.pagina-kiosco {
  margin: 0;
  padding: 24px 16px;
  min-height: 100vh;
  box-sizing: border-box;
  font-family: var(--oecsa-font);
  font-size: 18px;
  color: var(--oecsa-negro);
  background: var(--oecsa-fila);
}

.kiosco-hoja {
  max-width: 640px;
  margin: 0 auto;
  padding: 28px;
  border-radius: var(--oecsa-radio-card);
  background: var(--oecsa-blanco);
}

.kiosco-lugar {
  margin: 0 0 6px;
  font-size: 14px;
  color: var(--oecsa-gris);
}

.kiosco-titulo {
  margin: 0 0 20px;
  font-size: 28px;
  font-weight: 500;
}

.kiosco-texto {
  margin: 0 0 18px;
}

.kiosco-etiqueta {
  display: block;
  margin: 0 0 8px;
  font-size: 16px;
}

.kiosco-buscar,
.kiosco-foto,
.kiosco-pin {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin: 0 0 16px;
  padding: 14px 16px;
  border: 1px solid var(--oecsa-gris);
  border-radius: var(--oecsa-radio);
  font-family: inherit;
  font-size: 24px;
}

/* El PIN se lee de lejos por quien espera atrás si es grande y espaciado; por
   eso va con puntos y no con los dígitos. */
.kiosco-pin {
  letter-spacing: 0.4em;
  text-align: center;
}

.kiosco-botones {
  display: grid;
  gap: 12px;
  margin: 0 0 16px;
}

.kiosco-boton {
  display: block;
  width: 100%;
  min-height: 64px;
  margin: 0 0 12px;
  font-size: 22px;
}

.kiosco-lista {
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}

.kiosco-persona {
  display: block;
  width: 100%;
  min-height: 60px;
  margin: 0 0 10px;
  padding: 12px 16px;
  border: 0.5px solid var(--oecsa-negro);
  border-radius: var(--oecsa-radio);
  font-family: inherit;
  font-size: 20px;
  text-align: left;
  color: var(--oecsa-negro);
  background: var(--oecsa-blanco);
  cursor: pointer;
}

.kiosco-error {
  margin: 0 0 16px;
  padding: 14px 16px;
  border-radius: var(--oecsa-radio);
  color: var(--estado-error-tx);
  background: var(--estado-error-bg);
}

.kiosco-confirmacion {
  margin: 0 0 20px;
  padding: 20px;
  border-radius: var(--oecsa-radio);
  font-size: 22px;
  color: var(--estado-ok-tx);
  background: var(--estado-ok-bg);
}

/* --- La orden de cambio -----------------------------------------------------

   El residente la llena desde el teléfono, en la obra. Los renglones son
   tarjetas y no una tabla: siete columnas no caben en 360 px, y una tabla que
   se desplaza de lado es una tabla donde se teclea en la columna equivocada. */

.orden-renglon {
  margin: 0 0 12px;
  padding: 12px 14px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  background: var(--oecsa-blanco);
}

.orden-renglon-campos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px 12px;
}

/* La descripción y el selector del presupuesto son largos: ocupan la fila. */
.orden-renglon-ancho {
  grid-column: 1 / -1;
}

.orden-totales {
  max-width: 460px;
  margin: 0 0 22px auto;
}

.orden-totales th {
  text-align: left;
  font-weight: 400;
}

.orden-total-final th,
.orden-total-final td {
  font-weight: 500;
}

/* Tres o cuatro botones en fila no caben en el teléfono: se acomodan. */
.acciones-orden {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin: 18px 0;
}

/* Las tablas de lectura de la orden se desplazan de lado en el teléfono en vez
   de cortarse: `.tabla-marco` las recorta con `overflow: hidden`. */
.orden-tabla {
  overflow-x: auto;
}

@media (max-width: 600px) {
  .acciones-orden .btn-primario,
  .acciones-orden .btn-secundario,
  .acciones-orden .btn-peligro {
    flex: 1 1 100%;
  }
}

/* --- El menú como cajón -----------------------------------------------------

   Desde el 23/09/2026 la barra lateral está **escondida por omisión** y se
   abre con el botón «Menú» del encabezado, encima del contenido (DECISIONES
   1.191). Se cierra al elegir un módulo, al pulsar fuera o con Esc.

   Todo cuelga de `.con-js`, que pone `navegacion-temprano.js`: **sin
   JavaScript la barra se queda como estaba**, visible a la izquierda, porque
   no habría con qué abrirla.

   «Fijar el menú abierto» (`.menu-fijo`) la deja visible al lado del
   contenido, como antes, solo en pantallas de 1000 px o más: en una más
   angosta taparía la mitad de lo que se está leyendo. */

.encabezado-menu {
  display: none;
  align-items: center;
  gap: 7px;
  height: 36px;
  padding: 0 12px 0 10px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
  font-family: var(--oecsa-font);
  font-size: 13px;
  cursor: pointer;
}
.encabezado-menu:hover {
  background: var(--oecsa-fila);
}
.encabezado-menu:focus-visible,
.lateral-fijar:focus-visible,
.lateral-cerrar:focus-visible {
  outline: 2px solid var(--oecsa-negro);
  outline-offset: 1px;
}
.encabezado-menu[aria-expanded="true"] {
  background: var(--oecsa-fila);
  border-color: var(--oecsa-negro);
}
.encabezado-menu-icono {
  width: 18px;
  height: 18px;
  display: block;
}
.con-js .encabezado-menu {
  display: inline-flex;
}

/* La cabecera del cajón: fijar y cerrar. Sin JavaScript no hace nada, así
   que no se muestra. */
.lateral-cabecera {
  display: none;
}
.con-js .lateral-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 0 12px 12px 16px;
  margin-bottom: 8px;
  border-bottom: var(--oecsa-borde);
}
.lateral-fijar,
.lateral-cerrar {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 8px;
  border: 0;
  border-radius: var(--oecsa-radio);
  background: transparent;
  color: var(--oecsa-negro);
  font-family: var(--oecsa-font);
  font-size: 12px;
  cursor: pointer;
}
.lateral-fijar:hover,
.lateral-cerrar:hover {
  background: var(--oecsa-fila);
}
.lateral-fijar[aria-pressed="true"] {
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
}

.con-js .lateral {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 40;
  width: min(var(--oecsa-ancho-menu), 86vw);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-top: 12px;
  border-right: var(--oecsa-borde);
  box-shadow: var(--oecsa-sombra);
  transform: translateX(-100%);
  visibility: hidden;
  transition: transform 0.18s ease, visibility 0s linear 0.18s;
}
.con-js.menu-abierto .lateral {
  transform: none;
  visibility: visible;
  transition: transform 0.18s ease;
}
.lateral-velo {
  position: fixed;
  inset: 0;
  z-index: 39;
  background: var(--oecsa-velo);
}
.lateral-velo[hidden] {
  display: none;
}
.con-js.menu-abierto body {
  overflow: hidden;
}

@media (min-width: 1000px) {
  .con-js.menu-fijo .lateral {
    position: sticky;
    top: 0;
    height: 100vh;
    width: var(--oecsa-ancho-menu);
    transform: none;
    visibility: visible;
    box-shadow: none;
    transition: none;
  }
  .con-js.menu-fijo .lateral-cerrar {
    display: none;
  }
  .con-js.menu-fijo body {
    overflow: auto;
  }
}
/* En un teléfono el menú fijo no aplica, así que no se ofrece. */
@media (max-width: 999px) {
  .lateral-fijar {
    visibility: hidden;
  }
}
@media (prefers-reduced-motion: reduce) {
  .con-js .lateral,
  .con-js.menu-abierto .lateral {
    transition: none;
  }
}

/* --- «Ir a…» ------------------------------------------------------------------

   El buscador del encabezado (DECISIONES 1.194). La lista la arma
   `navegacion.js`; sin JavaScript el formulario va al escritorio, que busca en
   el servidor con los mismos sinónimos. */

.ir-a {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 280px;
  min-width: 0;
  margin: 0;
}
.ir-a-icono {
  position: absolute;
  left: 10px;
  width: 16px;
  height: 16px;
  pointer-events: none;
}
.ir-a-campo.campo {
  height: 36px;
  padding-left: 32px;
  padding-right: 52px;
}
.ir-a-atajo {
  position: absolute;
  right: 8px;
  padding: 1px 6px;
  border: var(--oecsa-borde);
  border-radius: 4px;
  font-family: var(--oecsa-font);
  font-size: 10px;
  color: var(--oecsa-gris);
  background: var(--oecsa-fila);
  pointer-events: none;
}
.ir-a-campo:focus + .ir-a-atajo {
  display: none;
}
.ir-a-lista {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 50;
  margin: 0;
  padding: 4px;
  list-style: none;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  box-shadow: var(--oecsa-sombra);
}
.ir-a-lista[hidden] {
  display: none;
}
.ir-a-opcion {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--oecsa-negro);
  text-decoration: none;
}
.ir-a-lista [aria-selected="true"] .ir-a-opcion,
.ir-a-opcion:hover {
  background: var(--oecsa-fila);
}
.ir-a-lista [aria-selected="true"] .ir-a-opcion {
  box-shadow: inset 3px 0 0 var(--oecsa-verde);
}
.ir-a-grupo {
  font-size: 11px;
  color: var(--oecsa-gris);
  white-space: nowrap;
}
.ir-a-vacio {
  padding: 8px 10px;
  font-size: 12px;
  color: var(--oecsa-gris);
}

/* --- El teléfono ------------------------------------------------------------

   Agregado el 23/09/2026 con la orden de cambio, que el residente llena desde
   la obra (DECISIONES 1.156). Desde la misma fecha, con el cajón, la barra ya
   no ocupa lugar en el teléfono: se abre con «Menú» igual que en la
   computadora (DECISIONES 1.191). El encabezado se acomoda en dos líneas, con
   «Ir a…» a lo ancho en la segunda.

   **Sin JavaScript** la barra no se puede abrir, así que se queda arriba del
   contenido, a lo ancho, con sus grupos plegables. */

@media (max-width: 700px) {
  .encabezado {
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 10px 14px;
  }
  .encabezado-persona {
    display: none;
  }
  .ir-a {
    order: 10;
    flex: 1 1 100%;
  }
  .ir-a-atajo {
    display: none;
  }
  .ir-a-campo.campo {
    padding-right: 12px;
  }
  .cuadricula {
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 8px;
  }
  .aplicacion-enlace {
    padding: 14px 8px 12px;
  }
  .disposicion {
    flex-direction: column;
    min-height: 0;
  }
  html:not(.con-js) .lateral {
    width: auto;
    padding: 6px 0;
    border-right: 0;
    border-bottom: var(--oecsa-borde);
  }
  .principal {
    padding: 14px;
  }
  .oecsa-titulo::after {
    flex: 0 0 48px;
  }
  .pestanas {
    overflow-x: auto;
  }
  .pestana {
    white-space: nowrap;
  }
}

/* =============================================================================
   SYSO y buzón de quejas
   ============================================================================= */

/* El punto que marca un campo obligatorio. No se usa asterisco: con lector de
   pantalla «asterisco» se lee y no significa nada. */
.campo-obligatorio {
  color: var(--oecsa-gris);
  font-weight: 600;
}

/* Un campo que ocupa el ancho de la rejilla: la descripción de una queja y la
   nota de seguimiento se escriben largas. */
.campo-ancho {
  grid-column: 1 / -1;
}

/* Texto que la gente escribió, no un dato del sistema. */
.texto-largo {
  max-width: 68ch;
  margin: 0 0 18px;
  line-height: 1.6;
  color: var(--oecsa-negro);
  white-space: normal;
}

/* --- La lista de controles de SYSO --- */
.syso-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin-bottom: 22px;
}
.syso-control {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  text-decoration: none;
  color: var(--oecsa-negro);
}
a.syso-control:hover {
  border-color: var(--oecsa-gris-medio);
  background: var(--oecsa-fila);
}
/* Sin permiso de captura la tarjeta se ve, pero no es un enlace: mostrarla
   como enlace sería ofrecer un 403. */
.syso-control-inerte {
  color: var(--estado-neutro-tx);
}
.syso-control-nombre {
  font-size: 14px;
  font-weight: 500;
}
.syso-control-nota {
  font-size: 12px;
  color: var(--estado-neutro-tx);
  line-height: 1.5;
}
.syso-control-puntos {
  margin-top: auto;
  padding-top: 6px;
  font-size: 11px;
  color: var(--oecsa-gris);
}

/* --- Las casillas de sí / no / no aplica ---
   Se llenan en el teléfono, con una mano y con guantes: los tres botones van
   en fila y con área de toque grande, no en una columna de radios pegados. */
.syso-casilla {
  grid-column: 1 / -1;
}
.syso-casilla ul {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}
.syso-casilla li {
  margin: 0;
}
.syso-casilla label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 6px 14px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  font-size: 13px;
  cursor: pointer;
}
.syso-casilla label:hover {
  background: var(--oecsa-fila);
}
.syso-casilla input:checked + span,
.syso-casilla label:has(input:checked) {
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
  border-color: var(--oecsa-verde);
}

/* --- Pantallas de captura, en tres bloques (CONVENCIONES §16) ---
   Nacieron en SYSO el 27/10/2026 y son para cualquier módulo: datos en
   rejilla (`.captura-datos`), revisión de Sí / No / No aplica en dos columnas
   (`.captura-revision` > `.captura-fila`) y observaciones con adjuntos al final
   (`.captura-cierre`). Antes SYSO era una sola columna: cada casilla a lo
   ancho, con sus tres botones uno debajo del otro, y la mitad derecha vacía. */
.buscador-lista {
  max-width: 520px;
  margin: 4px 0 14px;
}
.captura-datos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px 16px;
  margin: 16px 0;
}
.captura-datos .campo-bloque,
.captura-cierre .campo-bloque {
  margin-bottom: 0;
}
/* Lo que se escribe ocupa dos columnas: un área o un «qué pasó» no cabe en
   una cajita. */
.captura-ancho {
  grid-column: span 2;
}
.captura-revision {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  column-gap: 32px;
  /* Un fieldset trae `min-width: min-content` y en el teléfono se salía. */
  min-width: 0;
  margin: 0 0 16px;
  padding: 6px 16px 10px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
}
.captura-revision legend {
  padding: 0 6px;
}
.captura-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-bottom: var(--oecsa-borde);
}
.captura-fila-texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.captura-fila-etiqueta {
  font-size: 13px;
  line-height: 1.4;
}
.captura-fila-texto .campo-ayuda {
  margin: 0;
}
/* Django dibuja las opciones como `div` > `div` > `label`. */
.captura-opciones > div {
  display: flex;
  gap: 6px;
  flex: none;
}
.captura-opciones label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 36px;
  padding: 4px 10px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
}
.captura-opciones label:hover {
  background: var(--oecsa-fila);
}
.captura-opciones label:has(input:checked) {
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
  border-color: var(--oecsa-verde);
}
.captura-cierre {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 12px 16px;
  margin-bottom: 8px;
}
/* En el teléfono: una columna, y los botones con área de dedo. */
@media (max-width: 720px) {
  .captura-ancho {
    grid-column: auto;
  }
  .captura-revision {
    grid-template-columns: 1fr;
    padding: 4px 10px 8px;
  }
  /* Si la etiqueta es larga y no caben los tres botones al lado, bajan. */
  .captura-fila {
    flex-wrap: wrap;
    gap: 6px 8px;
  }
  .captura-opciones > div {
    gap: 4px;
  }
  .captura-cierre {
    grid-template-columns: 1fr;
  }
}
@media (pointer: coarse) {
  .captura-opciones label {
    min-height: 42px;
    padding: 6px 9px;
  }
}

/* --- La tarjeta del buzón público ---
   Más ancha que la de ingreso: acá se escribe un texto largo, no una
   contraseña. */
/* --- El buzón: la página pública del QR y los pasos del formulario, que
   comparte con la pantalla interna. --- */

.buzon-pagina {
  margin: 0;
  background: var(--oecsa-fila);
}
.buzon {
  max-width: 680px;
  margin: 0 auto;
  padding: 32px 24px 48px;
  font-family: var(--oecsa-font);
  color: var(--oecsa-negro);
}
.buzon-cabecera {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 18px;
}
.buzon-logo {
  width: 56px;
  height: auto;
  flex: none;
}
.buzon-empresa {
  font-size: 12px;
  color: var(--estado-neutro-tx);
  margin: 0;
}
.buzon-titulo {
  font-size: 22px;
  font-weight: 600;
  margin: 2px 0 8px;
}
.buzon-barra {
  width: 120px;
  height: var(--oecsa-barra);
  background: var(--oecsa-verde);
}
.buzon-intro {
  font-size: 14px;
  line-height: 1.55;
  margin: 0 0 16px;
}
.buzon-como {
  list-style: none;
  counter-reset: como;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  padding: 0;
  margin: 0 0 14px;
}
.buzon-como li {
  counter-increment: como;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  padding: 12px;
  font-size: 12px;
  line-height: 1.45;
}
.buzon-como li::before {
  content: counter(como);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
  font-weight: 600;
  margin-bottom: 6px;
}
.buzon-como strong {
  display: block;
}
.buzon-anonimo {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--estado-neutro-bg);
  border-radius: var(--oecsa-radio);
  padding: 10px 12px;
  font-size: 13px;
  margin: 0 0 18px;
}
.buzon-anonimo img {
  width: 18px;
  height: 18px;
  flex: none;
}
.buzon-formulario {
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  padding: 8px 24px 24px;
}
.buzon-enviar {
  width: 100%;
  height: 46px;
  font-size: 15px;
  margin-top: 8px;
}

.buzon-paso {
  border: 0;
  border-bottom: var(--oecsa-borde);
  padding: 20px 0 8px;
  margin: 0;
  min-width: 0;
}
.buzon-paso:last-of-type {
  border-bottom: 0;
}
.buzon-paso-titulo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  padding: 0;
  margin-bottom: 14px;
}
.buzon-paso-numero {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--oecsa-negro);
  color: var(--oecsa-blanco);
  font-size: 13px;
  flex: none;
}

/* El tipo, en tarjetas que se eligen de un toque. */
.buzon-opciones {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}
.buzon-opcion {
  position: relative;
  display: block;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  padding: 12px 12px 12px 38px;
  cursor: pointer;
}
.buzon-opcion input {
  position: absolute;
  left: 12px;
  top: 14px;
  margin: 0;
  accent-color: var(--oecsa-negro);
}
.buzon-opcion-nombre {
  display: block;
  font-size: 14px;
  font-weight: 600;
}
.buzon-opcion-ayuda {
  display: block;
  font-size: 12px;
  color: var(--estado-neutro-tx);
  margin-top: 2px;
  line-height: 1.4;
}
.buzon-opcion:has(input:checked) {
  border: 1.5px solid var(--oecsa-negro);
  box-shadow: inset 4px 0 0 var(--oecsa-verde);
}

/* El país, como dos botones pegados. */
.buzon-segmentos {
  display: inline-flex;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  overflow: hidden;
}
.buzon-segmento {
  cursor: pointer;
}
.buzon-segmento input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.buzon-segmento span {
  display: block;
  padding: 8px 16px;
  font-size: 13px;
}
.buzon-segmento + .buzon-segmento span {
  border-left: var(--oecsa-borde);
}
.buzon-segmento:has(input:checked) span {
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
  font-weight: 600;
}
.buzon-segmento:has(input:focus-visible) span {
  outline: 2px solid var(--oecsa-negro);
  outline-offset: -2px;
}

.buzon-dos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 14px;
}
.buzon-texto {
  height: auto;
  padding: 10px 12px;
  line-height: 1.5;
  resize: vertical;
}
.buzon-adjuntos {
  display: block;
  border: 1.5px dashed var(--oecsa-gris-medio);
  border-radius: var(--oecsa-radio);
  padding: 14px;
  cursor: pointer;
}
.buzon-adjuntos-titulo {
  display: block;
  font-size: 13px;
  font-weight: 600;
}
.buzon-adjuntos .campo-ayuda {
  display: block;
  margin: 2px 0 10px;
}
.buzon-adjuntos input {
  font-size: 12px;
  max-width: 100%;
}
.buzon-casilla {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio);
  padding: 12px;
  margin-bottom: 14px;
  font-size: 13px;
  cursor: pointer;
}
.buzon-casilla input {
  margin-top: 3px;
  accent-color: var(--oecsa-negro);
}
.buzon-casilla .campo-ayuda {
  display: block;
  margin-top: 2px;
}

@media (max-width: 720px) {
  .syso-rejilla {
    grid-template-columns: 1fr;
  }
  .buzon {
    padding: 20px 16px 36px;
  }
  .buzon-como,
  .buzon-opciones,
  .buzon-dos {
    grid-template-columns: 1fr;
  }
  .buzon-formulario {
    padding: 4px 16px 18px;
  }
  .buzon-como {
    gap: 6px;
  }
  .buzon-como li {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 8px 10px;
  }
  .buzon-como li::before {
    flex: none;
    margin-bottom: 0;
  }
}

/* =============================================================================
   Indicadores (KPI) — el tablero, la tarjeta con su barra de bandas, la
   gráfica del detalle y la rejilla de captura.

   El semáforo tiene cinco estados y los cinco llevan texto además de color:
   el color no es el único portador. El verde óptimo es el verde corporativo
   como relleno, con texto negro encima, como pide la marca.
   ============================================================================= */

:root {
  /* Verde óptimo es el oscuro —arriba del límite—; verde, el claro
     corporativo. Cambiado el 24/09/2026 a pedido: el claro va antes. */
  --semaforo-vo: #3E7D1E;
  --semaforo-vc: #C3D600;
  --semaforo-a: #E9A23B;
  --semaforo-r: #C8413B;
  --semaforo-sin: #BDBCBC;
}

.kpi-periodo {
  font-size: 13px;
  color: var(--oecsa-gris);
  margin: -6px 0 16px;
}

.kpi-columnas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  align-items: start;
}

.kpi-columna-titulo {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--oecsa-negro);
  border-bottom: 3px solid var(--oecsa-verde);
  padding-bottom: 6px;
  margin: 0 0 10px;
}

.kpi-tarjeta {
  display: block;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-left: 6px solid var(--semaforo-sin);
  border-radius: var(--oecsa-radio-card);
  padding: 12px 14px;
  margin-bottom: 10px;
  color: var(--oecsa-negro);
  text-decoration: none;
}
.kpi-tarjeta:hover { border-color: var(--oecsa-gris); }
.kpi-tarjeta-vo { border-left-color: var(--semaforo-vo); }
.kpi-tarjeta-vc { border-left-color: var(--semaforo-vc); }
.kpi-tarjeta-a  { border-left-color: var(--semaforo-a); }
.kpi-tarjeta-r  { border-left-color: var(--semaforo-r); }

.kpi-nombre {
  font-size: 13px;
  font-weight: 500;
  margin: 0 0 6px;
}
.kpi-cifras {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.kpi-valor {
  font-size: 22px;
  font-weight: 600;
  margin: 0;
}
.kpi-meta,
.kpi-pie {
  font-size: 12px;
  color: var(--oecsa-gris);
  margin: 0;
}
.kpi-pie { margin-top: 6px; }

.kpi-barra {
  display: block;
  width: 100%;
  height: 14px;
  margin: 8px 0 2px;
}
.kpi-banda-vo { fill: var(--semaforo-vo); }
.kpi-banda-vc { fill: var(--semaforo-vc); }
.kpi-banda-a  { fill: var(--semaforo-a); }
.kpi-banda-r  { fill: var(--semaforo-r); }
.kpi-marca    { fill: var(--oecsa-negro); }

/* El punto de color con su nombre al lado. */
.kpi-color {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  white-space: nowrap;
}
.kpi-color::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--semaforo-sin);
}
.kpi-color-vo::before { background: var(--semaforo-vo); }
.kpi-color-vc::before { background: var(--semaforo-vc); }
.kpi-color-a::before  { background: var(--semaforo-a); }
.kpi-color-r::before  { background: var(--semaforo-r); }

.kpi-grafica {
  display: block;
  width: 100%;
  max-width: 760px;
  height: auto;
  margin: 8px 0 20px;
}
.kpi-eje      { stroke: var(--oecsa-gris-claro); stroke-width: 1; }
.kpi-eje-texto{ fill: var(--oecsa-gris); font-size: 11px; font-family: var(--oecsa-font); }
.kpi-linea    { fill: none; stroke: var(--oecsa-negro); stroke-width: 2; }
.kpi-linea-meta { fill: none; stroke: var(--oecsa-gris); stroke-width: 1.5; stroke-dasharray: 6 4; }
.kpi-referencia { stroke-width: 1; stroke-dasharray: 2 4; }
.kpi-referencia-vo { stroke: var(--semaforo-vo); }
.kpi-referencia-vc { stroke: var(--semaforo-vc); }
.kpi-referencia-a  { stroke: var(--semaforo-a); }
.kpi-punto    { stroke: var(--oecsa-negro); stroke-width: 1; fill: var(--semaforo-sin); }
.kpi-punto-vo { fill: var(--semaforo-vo); }
.kpi-punto-vc { fill: var(--semaforo-vc); }
.kpi-punto-a  { fill: var(--semaforo-a); }
.kpi-punto-r  { fill: var(--semaforo-r); }

/* La rejilla de captura: doce meses por renglón. */
.kpi-rejilla td,
.kpi-rejilla th { padding: 4px; text-align: center; }
.kpi-rejilla td:first-child,
.kpi-rejilla th:first-child { text-align: left; min-width: 220px; }
.kpi-celda .campo {
  width: 84px;
  padding: 4px 6px;
  font-size: 12px;
  text-align: right;
}
.kpi-celda select.campo { width: 84px; margin-top: 2px; text-align: left; }
.kpi-celda-guardada .campo { border-color: var(--semaforo-vc); }
.kpi-celda-error .campo { border-color: var(--semaforo-r); }
.kpi-celda-no-toca { background: var(--oecsa-fila); }

/* La rejilla de captura se desplaza dentro de su marco, con los meses fijos
   arriba y el nombre del indicador fijo a la izquierda: son doce columnas y
   decenas de filas, y sin eso al bajar no se sabe qué mes es cada celda
   (05/10/2026). Tiene que ser su propio marco: `.tabla-marco` recorta con
   `overflow: hidden` y la rejilla es más ancha que la pantalla, así que el
   encabezado no se puede pegar a la ventana. */
.kpi-rejilla-marco {
  overflow: auto;
  max-height: 75vh;
}
.kpi-rejilla thead th {
  position: sticky;
  top: 0;
  z-index: 2;
}
.kpi-rejilla thead th:first-child {
  left: 0;
  z-index: 3;
}
.kpi-rejilla tbody tr:not(.fila-grupo) td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--oecsa-blanco);
}
.kpi-rejilla tbody tr:not(.fila-grupo):nth-child(even) td:first-child {
  background: var(--oecsa-fila);
}
.kpi-celda-cerrada { color: var(--oecsa-gris); font-size: 12px; }
.kpi-celda-sugerido { display: block; font-size: 10px; color: var(--oecsa-gris); }
.kpi-mes-cerrado { color: var(--oecsa-gris); font-weight: 400; }

.kpi-leyenda {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin: 0 0 14px;
}

@media (max-width: 980px) {
  .kpi-valor { font-size: 18px; }
}

/* El tablero en una sola vista: los pilares de columnas y un renglón por
   unidad de negocio. Las columnas van por clase —hasta ocho— porque las
   plantillas no llevan estilos en línea. */
.kpi-matriz {
  display: grid;
  gap: 8px 10px;
  align-items: start;
}
.kpi-matriz-1 { grid-template-columns: minmax(0, 1fr); }
.kpi-matriz-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kpi-matriz-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kpi-matriz-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.kpi-matriz-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.kpi-matriz-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.kpi-matriz-7 { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.kpi-matriz-8 { grid-template-columns: repeat(8, minmax(0, 1fr)); }
.kpi-matriz-encabezado { margin: 0; }
.kpi-seccion-titulo {
  grid-column: 1 / -1;
  margin: 10px 0 0;
  padding: 4px 8px;
  font-size: 13px;
  font-weight: 600;
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio);
}
.kpi-celda-pilar { display: none; }
.kpi-tarjeta-compacta {
  padding: 7px 9px;
  margin-bottom: 6px;
  border-left-width: 5px;
}
.kpi-tarjeta-compacta .kpi-nombre {
  font-size: 11px;
  line-height: 1.3;
  margin-bottom: 2px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kpi-tarjeta-compacta .kpi-valor { font-size: 16px; }
.kpi-tarjeta-compacta .kpi-meta { font-size: 11px; }
.kpi-tarjeta-compacta .kpi-barra { height: 10px; margin: 4px 0 2px; }
.kpi-tarjeta-compacta .kpi-pie { font-size: 10px; margin-top: 2px; }
.kpi-tarjeta-compacta .kpi-color { font-size: 10px; }

@media (max-width: 980px) {
  .kpi-matriz[class*="kpi-matriz-"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kpi-matriz-encabezado { display: none; }
  .kpi-celda-pilar {
    display: block;
    font-size: 11px;
    font-weight: 600;
    margin: 0 0 4px;
  }
}
@media (max-width: 560px) {
  .kpi-matriz[class*="kpi-matriz-"] { grid-template-columns: minmax(0, 1fr); }
}

/* Arriba del tablero, en una línea: filtros a la izquierda, acciones a la
   derecha. Y el título de la página más cerca, para que la matriz quepa en
   la primera pantalla. */
.kpi-barra-superior {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.kpi-barra-superior .kpi-filtros,
.kpi-barra-superior .kpi-acciones { margin: 0; }
.kpi-tarjeta-compacta .kpi-cifras { gap: 6px; }
.kpi-tarjeta-compacta .kpi-barra { margin-bottom: 0; }
.kpi-leyenda { margin-bottom: 8px; font-size: 12px; }
.kpi-periodo { margin: 0 0 6px; }

/* La tarjeta compacta: el valor y la barra en la misma línea. */
.kpi-fila-compacta {
  display: flex;
  align-items: center;
  gap: 6px;
}
.kpi-fila-compacta .kpi-valor { font-size: 14px; white-space: nowrap; }
.kpi-fila-compacta .kpi-meta { white-space: nowrap; }
.kpi-fila-compacta .kpi-barra { flex: 1; min-width: 30px; margin: 0; }
.kpi-tarjeta-compacta { margin-bottom: 5px; padding: 6px 8px; }
.kpi-seccion-titulo { margin-top: 6px; }
.kpi-resumen {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
}
.kpi-resumen .kpi-periodo,
.kpi-resumen .kpi-leyenda { margin: 0; }
.kpi-celda-vacia { color: var(--oecsa-gris); font-size: 12px; margin: 4px 0; }

/* La tarjeta pintada del color del indicador: fondo tenue y borde fuerte, con
   texto negro siempre. Lleva resultado, meta, cumplimiento y la definición de
   los umbrales, para leer el tablero sin abrir cada ficha. */
:root {
  --semaforo-vo-fondo: #DCEBD0;
  --semaforo-vc-fondo: #F2F7C4;
  --semaforo-a-fondo: #FBECD6;
  --semaforo-r-fondo: #F8DCDA;
}
.kpi-fondo-vo { background: var(--semaforo-vo-fondo); }
.kpi-fondo-vc { background: var(--semaforo-vc-fondo); }
.kpi-fondo-a  { background: var(--semaforo-a-fondo); }
.kpi-fondo-r  { background: var(--semaforo-r-fondo); }
.kpi-fondo-sin { background: var(--oecsa-fila); }

.kpi-datos {
  display: flex;
  gap: 10px;
  margin: 2px 0 4px;
}
.kpi-datos dt {
  font-size: 9px;
  color: var(--estado-neutro-tx);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.kpi-datos dd { margin: 0; font-size: 12px; font-weight: 500; white-space: nowrap; }
.kpi-datos .kpi-dato-principal { font-size: 15px; font-weight: 600; }
.kpi-umbrales {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 8px;
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
}
.kpi-umbrales .kpi-color { font-size: 10px; }
.kpi-umbrales .kpi-color::before { width: 8px; height: 8px; }
.kpi-estado {
  margin: 3px 0 0;
  font-size: 10px;
  font-weight: 600;
  color: var(--oecsa-negro);
}

/* El detalle del indicador: la gráfica a la izquierda y los comentarios a la
   derecha, como las noticias en el escritorio. */
.kpi-detalle {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 24px;
  align-items: start;
}
.kpi-detalle-principal { min-width: 0; }
.kpi-detalle-comentarios {
  position: sticky;
  top: 12px;
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  padding: 12px 14px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  background: var(--oecsa-blanco);
}
.kpi-comentario-nuevo { margin: 0 0 12px; align-items: stretch; }
.kpi-comentario-nuevo .campo { width: 100%; }
.kpi-comentario-nuevo .btn-primario { align-self: flex-start; }
.kpi-comentario-del-mes {
  border-left: 3px solid var(--oecsa-verde);
  padding-left: 8px;
}
@media (max-width: 980px) {
  .kpi-detalle { grid-template-columns: minmax(0, 1fr); }
  .kpi-detalle-comentarios { position: static; max-height: none; }
}

/* La ficha del indicador arriba del detalle: quién responde, de dónde sale el
   dato, cómo se calcula, umbrales y si acumula. */
.kpi-ficha {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  align-items: flex-start;
  padding: 10px 14px;
  margin: 0 0 12px;
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio-card);
}
.kpi-ficha .dato-etiqueta { margin: 0 0 2px; }
.kpi-ficha .dato-valor { margin: 0; font-size: 13px; }
.kpi-ficha .kpi-umbrales { margin: 2px 0 0; }
.kpi-ficha .kpi-umbrales .kpi-color { font-size: 12px; }
.kpi-ficha-editar { margin-left: auto; align-self: center; }

/* Lo que se abre al pedirlo: la tabla de meses, la ficha larga y el
   formulario de comentario. Con <details>, sin JavaScript. */
.kpi-plegable {
  margin: 12px 0;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  padding: 8px 12px;
}
.kpi-plegable > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
}
.kpi-plegable[open] > summary { margin-bottom: 8px; }
.kpi-agregar-comentario { margin: 0 0 10px; }
.kpi-agregar-comentario > summary {
  cursor: pointer;
  font-size: 13px;
  list-style: none;
}
.kpi-agregar-comentario > summary::-webkit-details-marker { display: none; }
.kpi-agregar-comentario[open] > summary { margin-bottom: 8px; }

/* =============================================================================
   Aviso emergente — cuando algo no se guardó y no puede pasar desapercibido.
   Hoy lo usan las dos pantallas de contraseña. Es un `<dialog open>` a pantalla
   completa sobre el velo, sin JavaScript: se cierra con su propio botón.
   ============================================================================= */

.aviso-emergente {
  position: fixed;
  inset: 0;
  z-index: 60;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 16px;
  border: 0;
  box-sizing: border-box;
  background: var(--oecsa-velo);
  display: flex;
  align-items: center;
  justify-content: center;
}
.aviso-emergente:not([open]) {
  display: none;
}
.aviso-emergente-caja {
  width: 100%;
  max-width: 420px;
  background: var(--oecsa-blanco);
  border-radius: var(--oecsa-radio-card);
  box-shadow: var(--oecsa-sombra);
  padding: 22px 22px 18px;
  border-top: 6px solid var(--estado-error-tx);
  font-family: var(--oecsa-font);
  text-align: left;
}
.aviso-emergente-titulo {
  font-size: 17px;
  font-weight: 600;
  color: var(--estado-error-tx);
  margin: 0 0 10px;
}
.aviso-emergente-lista {
  background: var(--estado-error-bg);
  color: var(--estado-error-tx);
  border-radius: var(--oecsa-radio);
  padding: 10px 12px 10px 28px;
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.5;
}
.aviso-emergente-nota {
  font-size: 12px;
  color: var(--estado-neutro-tx);
  margin: 0 0 14px;
}

/* Las reglas de la contraseña, antes de escribirla. */
.reglas-contrasena {
  background: var(--estado-info-bg);
  color: var(--estado-info-tx);
  border-radius: var(--oecsa-radio);
  padding: 10px 12px;
  margin: 0 0 16px;
  font-size: 12px;
  text-align: left;
}
.reglas-contrasena-titulo {
  font-weight: 600;
  margin: 0 0 4px;
}
.reglas-contrasena ul {
  margin: 0;
  padding-left: 18px;
}

/* Un formulario de una sola fila dentro de una celda: el selector y su botón. */
.fila-formulario {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.fila-formulario .campo {
  flex: 1 1 220px;
  width: auto;
}

/* ------------------------------------------------------------------ Impact
 * Las reuniones IMPACT, los seis sombreros y el PEUP. Mismos tokens que el
 * resto; nada de hex sueltos. */
.impact-columnas {
  display: grid;
  grid-template-columns: minmax(260px, 340px) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
@media (max-width: 900px) {
  .impact-columnas { grid-template-columns: minmax(0, 1fr); }
}
.impact-pila > * + * { margin-top: 16px; }
.impact-reloj {
  font-size: 40px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 1px;
  color: var(--oecsa-negro);
}
.impact-reloj.impact-sobretiempo { color: var(--estado-error-tx); }
.impact-reloj-paso { color: var(--oecsa-gris); font-size: 13px; }
.impact-agenda { list-style: none; margin: 0; padding: 0; }
.impact-agenda li {
  border-top: var(--oecsa-borde);
  padding: 10px 0;
}
.impact-agenda li:first-child { border-top: 0; }
.impact-paso-actual {
  background: var(--oecsa-fila);
  border-left: 4px solid var(--oecsa-verde);
  padding-left: 10px !important;
}
.impact-paso-cabeza {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: baseline;
}
.impact-paso-nombre { font-weight: 600; }
.impact-paso-meta { color: var(--oecsa-gris); font-size: 12px; }
.impact-paso-nota summary { cursor: pointer; font-size: 13px; }
.impact-red {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 16px;
}
.impact-grupo-titulo {
  font-weight: 600;
  margin: 16px 0 6px;
}
.impact-lista-compacta { list-style: none; margin: 0; padding: 0; }
.impact-lista-compacta li {
  border-top: var(--oecsa-borde);
  padding: 8px 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  align-items: baseline;
  justify-content: space-between;
}
.impact-lista-compacta li:first-child { border-top: 0; }
.impact-en-linea {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.impact-en-linea .campo { width: auto; min-width: 110px; }
.impact-atrasada { color: var(--estado-error-tx); font-weight: 600; }
/* ----------------------------------------------------------------- Minutas */
.minutas-columnas { grid-template-columns: minmax(0, 1fr) minmax(260px, 340px); }
@media (max-width: 900px) {
  .minutas-columnas { grid-template-columns: minmax(0, 1fr); }
}
.minutas-tema {
  font-size: 24px;
  font-weight: 600;
  border-width: 0 0 2px;
  border-color: var(--oecsa-verde);
  border-radius: 0;
  padding-left: 0;
  margin: 4px 0 6px;
  max-width: 900px;
}
/* El tema editable es el título de la cabecera (DECISIONES 1.340): ocupa lo
   que dejan las acciones, como `.oecsa-titulo`. */
.cabecera-pantalla .minutas-tema-forma { flex: 1 1 320px; min-width: 0; }
.cabecera-pantalla .minutas-tema { margin: 0; }
#minuta-notas .rico-cuadro { min-height: 420px; }
.rico-cuadro img,
.rico-texto img { max-width: 100%; height: auto; display: block; margin: 8px 0; }
.rico-subiendo { opacity: 0.6; cursor: progress; }
/* La reunión programada (DECISIONES 1.274): la hora en una fila, la lista de
   personas con su propio desplazamiento y lo que se abre al pedirlo. */
.minutas-horario {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}
@media (max-width: 600px) {
  .minutas-horario { grid-template-columns: minmax(0, 1fr); }
}
.minutas-rejilla { margin: 0; }
.minutas-elegir-lista {
  max-height: 420px;
  overflow-y: auto;
  margin: 8px 0 14px;
}
.minutas-programar > summary,
.minutas-agregar > summary { cursor: pointer; }
.minutas-programar[open] > summary { margin-bottom: 8px; }
.minutas-agregar { margin-top: 10px; }
.minutas-agregar[open] > summary { margin-bottom: 8px; }
.minutas-enlace { word-break: break-all; }
.minutas-cancelar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 8px;
}
.impact-acuse-error { font-size: 12px; color: var(--estado-error-tx); font-weight: 600; }
.impact-paso-hecho { color: var(--oecsa-gris); font-weight: 400; }
#paso .rico-cuadro { min-height: 220px; }
/* «+ Asignación», fijo abajo a la derecha en todos los pasos de la reunión. */
.impact-asignar {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 30;
  max-width: calc(100vw - 32px);
}
.impact-asignar > summary { list-style: none; cursor: pointer; display: inline-block; }
.impact-asignar > summary::-webkit-details-marker { display: none; }
.impact-asignar[open] > summary { float: right; }
.impact-asignar-panel {
  clear: both;
  width: 520px;
  max-width: 100%;
  max-height: 70vh;
  overflow-y: auto;
  margin-bottom: 8px;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  box-shadow: var(--oecsa-sombra);
  padding: 16px 20px;
}
@media (max-width: 600px) {
  .impact-asignar { right: 16px; bottom: 16px; }
}
.impact-avance {
  width: 80px;
  height: 8px;
  vertical-align: middle;
  accent-color: var(--oecsa-verde);
}
.impact-peup {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
}
.impact-peup-bloque h3 {
  margin: 0 0 4px;
  font-size: 15px;
}
.impact-peup-guia { color: var(--oecsa-gris); font-size: 12px; margin: 0 0 10px; }
.impact-peup-campo { margin: 10px 0 0; }
.impact-peup-etiqueta { font-size: 12px; color: var(--oecsa-gris); margin: 0; }
.impact-peup-renglon { margin: 2px 0; }
.impact-peup-pares {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 6px;
}
.impact-peup-niveles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
}
.impact-antes { background: var(--estado-error-bg); color: var(--estado-error-tx); }
.impact-despues { background: var(--estado-ok-bg); color: var(--estado-ok-tx); }
.impact-sombrero {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
}
.impact-firma-imagen { max-width: 220px; height: auto; border: var(--oecsa-borde); }
.impact-glosario dt { font-weight: 600; margin-top: 12px; }
.impact-glosario dd { margin: 2px 0 0; }
/* Imprimir la minuta o el PEUP: solo el documento. Se limita a las páginas
 * que lo traen, para no cambiar cómo imprime el resto del sistema. */
@media print {
  body:has(.impact-imprimible) .lateral,
  body:has(.impact-imprimible) .encabezado,
  body:has(.impact-imprimible) .pestanas,
  body:has(.impact-imprimible) .acciones,
  body:has(.impact-imprimible) form { display: none !important; }
}

/* ------------------------------------------------------------ PEUP en hoja
 * El PEUP igual a la hoja de Excel de la gerencia: mismas celdas, anchos y
 * colores (impact/peup_hoja.py). Los colores son los de la plantilla, que la
 * gerencia reconoce; viven acá como tokens y no en la plantilla HTML. */
:root {
  --peup-titulo: #2E75B5;
  --peup-banda: #BDD6EE;
  --peup-gris: #D9D9D9;
  --peup-claro: #DEEAF6;
  --peup-optimo: #548235;
  --peup-verde: #C5E0B3;
  --peup-amarillo: #FFFF00;
  --peup-rojo: #FF0000;
  --peup-linea: #8C8C8C;
}
.peup-marco { overflow-x: auto; margin: 12px 0 20px; }
.peup-hoja {
  width: 100%;
  min-width: 1100px;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 11px;
  line-height: 1.25;
  color: var(--oecsa-negro);
  background: var(--oecsa-blanco);
}
.peup-hoja td {
  padding: 2px 4px;
  vertical-align: top;
  overflow-wrap: anywhere;
}
.peup-hoja td.bd { border: 1px solid var(--peup-linea); }
.peup-hoja td.n { font-weight: 600; }
.peup-hoja td.g { font-size: 14px; }
.peup-hoja td.c { text-align: center; vertical-align: middle; }
.peup-hoja td.d { text-align: right; }
.peup-hoja td.titulo { background: var(--peup-titulo); color: var(--oecsa-blanco); vertical-align: middle; }
.peup-hoja td.banda { background: var(--peup-banda); }
.peup-hoja td.gris { background: var(--peup-gris); }
.peup-hoja td.claro { background: var(--peup-claro); }
.peup-hoja td.s-optimo { background: var(--peup-optimo); }
.peup-hoja td.s-verde { background: var(--peup-verde); }
.peup-hoja td.s-amarillo { background: var(--peup-amarillo); }
.peup-hoja td.s-rojo { background: var(--peup-rojo); }
.peup-hoja td.area { vertical-align: middle; }
.peup-entrada {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  color: inherit;
  padding: 1px 0;
  resize: vertical;
}
.peup-entrada:focus { outline: 2px solid var(--oecsa-verde); background: var(--oecsa-blanco); }
.peup-hoja td.titulo .peup-entrada { color: var(--oecsa-blanco); }
.peup-col-B { width: 1.03%; }
.peup-col-C { width: 8.51%; }
.peup-col-D { width: 1.03%; }
.peup-col-E { width: 8.51%; }
.peup-col-F { width: 1.03%; }
.peup-col-G { width: 7.34%; }
.peup-col-H { width: 5.70%; }
.peup-col-I { width: 1.03%; }
.peup-col-J { width: 9.86%; }
.peup-col-K { width: 4.77%; }
.peup-col-L { width: 2.66%; }
.peup-col-M { width: 1.03%; }
.peup-col-N { width: 10.10%; }
.peup-col-O { width: 6.17%; }
.peup-col-P { width: 2.20%; }
.peup-col-Q { width: 5.80%; }
.peup-col-R { width: 1.03%; }
.peup-col-S { width: 5.80%; }
.peup-col-T { width: 1.03%; }
.peup-col-U { width: 6.17%; }
.peup-col-V { width: 6.08%; }
.peup-col-W { width: 3.13%; }
@media print {
  @page { size: landscape; margin: 8mm; }
  .peup-hoja { min-width: 0; font-size: 8px; }
  .peup-marco { overflow: visible; }
}

.impact-apartados {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
  margin-bottom: 20px;
}

/* ------------------------------------------------------ texto con formato
 * El editor de static/js/texto-enriquecido.js y cómo se pinta lo escrito. */
.rico-barra {
  display: flex;
  gap: 4px;
  margin-bottom: 4px;
}
.rico-boton {
  min-width: 30px;
  height: 28px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
  font: inherit;
  cursor: pointer;
}
.rico-boton:hover { background: var(--oecsa-fila); }
.rico-bold { font-weight: 700; }
.rico-italic { font-style: italic; }
.rico-underline { text-decoration: underline; }
.rico-cuadro {
  min-height: 90px;
  max-height: 420px;
  overflow-y: auto;
  white-space: normal;
}
.rico-cuadro:focus { outline: 2px solid var(--oecsa-verde); }
.rico-cuadro ul, .rico-cuadro ol, .rico-texto ul, .rico-texto ol { margin: 4px 0; padding-left: 22px; }
.rico-cuadro p, .rico-texto p { margin: 0 0 6px; }
/* Las tablas del memo de mensajería (DECISIONES 1.294): con su cuadrícula
   en el editor y al pintarlas, y la fila de títulos con fondo de fila. */
.rico-barra { flex-wrap: wrap; }
.rico-tabla { padding: 0 8px; font-size: 12px; }
.rico-cuadro table, .rico-texto table {
  border-collapse: collapse;
  margin: 6px 0;
  max-width: 100%;
}
.rico-cuadro th, .rico-cuadro td, .rico-texto th, .rico-texto td {
  border: 1px solid var(--oecsa-gris-medio);
  padding: 4px 8px;
  min-width: 60px;
  vertical-align: top;
  text-align: left;
}
.rico-cuadro th, .rico-texto th { background: var(--oecsa-fila); font-weight: 600; }
.rico-cuadro[data-aviso]::before {
  content: attr(data-aviso);
  display: block;
  color: var(--estado-alerta-tx);
  font-size: 12px;
}


/* -----------------------------------------------------------------------------
   Tareas
   ----------------------------------------------------------------------------- */

/* La barra de alta rápida: el campo ancho, la fecha y la casilla a su lado.
   En el celular baja todo a renglones. */
.tareas-alta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  margin: 0 0 6px;
}
.tareas-alta .campo { width: auto; }
.tareas-alta input[type="text"] { flex: 1; min-width: 220px; }
.tareas-nota {
  font-size: 11px;
  color: var(--oecsa-gris);
  margin: 0 0 16px;
}
.tareas-lista { list-style: none; margin: 0 0 8px; padding: 0; }
.tareas-renglon {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  border-top: var(--oecsa-borde);
}
.tareas-renglon:first-child { border-top: 0; }
.tareas-renglon form { margin: 0; }
.tareas-cuerpo { flex: 1; min-width: 0; }
/* El título enlaza al detalle, pero **no con `enlace-fila`**: su capa invisible
   se estira hasta el contenedor posicionado más cercano, tapaba el check y el
   clic se iba a la tarea de otro renglón. */
.tareas-titulo {
  font-size: 13px;
  overflow-wrap: anywhere;
  color: var(--oecsa-negro);
  text-decoration: none;
}
a.tareas-titulo:hover { text-decoration: underline; }
.tareas-fin {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-size: 12px;
}
/* El check: una casilla del tamaño de un dedo. Hecha se rellena de verde con
   la marca en negro, que es el único uso permitido del verde. */
.tareas-check {
  width: 22px;
  height: 22px;
  flex: none;
  padding: 0;
  border: 1.5px solid var(--oecsa-gris-medio);
  border-radius: 6px;
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
button.tareas-check:hover { border-color: var(--oecsa-negro); }
.tareas-check-fijo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: default;
}
.tareas-hecha .tareas-check {
  background: var(--oecsa-verde);
  border-color: var(--oecsa-verde);
}
/* Una tarea hecha se atenúa y se tacha, como un bloque cumplido del
   timeboxing; una cancelada solo se atenúa. */
.tareas-hecha .tareas-titulo {
  color: var(--oecsa-gris);
  text-decoration: line-through;
}
.tareas-cancelada .tareas-titulo { color: var(--oecsa-gris); }
/* La lista única (12/10/2026). El renglón es una columna: la fila de siempre
   arriba y, si se abre, el hilo de comentarios debajo. */
.tareas-renglon { flex-direction: column; align-items: stretch; gap: 0; }
.tareas-renglon-fila {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.tareas-renglon-abierto { background: var(--oecsa-fila); }
.tareas-cuerpo {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.tareas-cabeza {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
}
/* De quién es: lo primero del renglón y a la vista. Fondo negro con letra
   blanca para otra persona; verde con letra negra para uno mismo, que es el
   único uso permitido del verde. */
.tareas-quien {
  display: inline-block;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--oecsa-negro);
  color: var(--oecsa-blanco);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
  flex: none;
}
.tareas-quien-yo {
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
}
[data-tema="oscuro"] .tareas-quien-yo { color: var(--tema-tinta-sobre-verde); }
/* El último comentario, debajo del título: cómo va sin abrirlo. */
.tareas-ultimo {
  font-size: 12px;
  color: var(--oecsa-negro);
  overflow-wrap: anywhere;
}
.tareas-ultimo-cuando { color: var(--oecsa-gris); }
.tareas-fecha { color: var(--oecsa-gris); white-space: nowrap; }
.tareas-fecha-vencida { color: var(--estado-error-tx); font-weight: 600; }
.tareas-fecha-hoy { color: var(--estado-alerta-tx); font-weight: 600; }
/* «Comentar» o «3 comentarios»: abre el hilo en el mismo renglón. */
.tareas-hilo-boton {
  padding: 3px 9px;
  border: var(--oecsa-borde);
  border-radius: 999px;
  font-size: 11px;
  color: var(--oecsa-gris);
  text-decoration: none;
  white-space: nowrap;
}
.tareas-hilo-boton:hover { color: var(--oecsa-negro); border-color: var(--oecsa-negro); }
.tareas-hilo-con { color: var(--oecsa-negro); font-weight: 500; }
.tareas-hilo {
  margin: 8px 0 4px 32px;
  padding: 10px 12px;
  border-left: 3px solid var(--oecsa-gris-claro);
  background: var(--oecsa-blanco);
  border-radius: 0 var(--oecsa-radio) var(--oecsa-radio) 0;
}
.tareas-hilo-lista { list-style: none; margin: 0 0 10px; padding: 0; }
.tareas-nota-hilo { padding: 6px 0; border-top: var(--oecsa-borde); }
.tareas-nota-hilo:first-child { border-top: 0; }
.tareas-nota-hilo p { margin: 0; }
.tareas-nota-texto { font-size: 13px; overflow-wrap: anywhere; }
.tareas-nota-avance .tareas-nota-texto { color: var(--oecsa-gris); font-style: italic; }
.tareas-hilo-form { display: flex; gap: 8px; align-items: flex-end; }
.tareas-hilo-form .campo { flex: 1; min-width: 0; }
/* Los grupos por urgencia: un encabezado con su cuenta y la lista debajo,
   en una sola columna. Vencidas y hoy llevan el filo del color de su estado. */
.tareas-grupo {
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  padding: 10px 16px 4px;
  margin: 0 0 14px;
}
.tareas-grupo-vencidas { border-left: 4px solid var(--estado-error-tx); }
.tareas-grupo-hoy { border-left: 4px solid var(--estado-alerta-tx); }
.tareas-grupo-titulo {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 2px 0 6px;
  font-size: 14px;
  font-weight: 600;
}
.tareas-grupo-n {
  font-size: 11px;
  font-weight: 500;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--estado-neutro-bg);
  color: var(--estado-neutro-tx);
}
/* Un botón por persona de su línea: cuánto tiene abierto y cuánto vencido. */
.tareas-gente {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 0 12px;
}
.tareas-persona {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: var(--oecsa-borde);
  border-radius: 999px;
  font-size: 12px;
  color: var(--oecsa-negro);
  text-decoration: none;
}
.tareas-persona:hover { border-color: var(--oecsa-negro); }
.tareas-persona-activa { border-color: var(--oecsa-negro); font-weight: 600; }
.tareas-persona-n { color: var(--oecsa-gris); }
.tareas-persona-vencidas { color: var(--estado-error-tx); font-weight: 600; }
.tareas-otra-persona .campo { width: auto; }
/* Pagos: el hilo de un pago se abre en una fila debajo de la suya, que vacía
   no se ve (12/10/2026). Usa las mismas piezas que el hilo de tareas. */
.pagos-hilo-fila td { padding: 0 12px; border-top: 0; }
.pagos-hilo-fila td:empty { padding: 0; border: 0; }
.pagos-hilo { margin: 0 0 10px; }
.pagos-hilo .casilla { white-space: nowrap; }
.tabla td .tareas-ultimo { display: block; margin-top: 2px; }
/* Dónde va el pago y a quién espera, debajo de su estado. */
.pagos-donde { display: block; margin-top: 4px; max-width: 220px; }
.pagos-donde-ficha { margin-left: 8px; font-size: 13px; font-weight: 500; }
/* Pagos: el siguiente paso en su columna de la bandeja (28/10/2026,
   DECISIONES 1.337). Verde de relleno con texto negro, como manda la marca;
   el formulario se abre en el renglón de abajo. */
.pagos-paso-boton {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.pagos-paso-boton:hover { box-shadow: inset 0 0 0 1px var(--oecsa-negro); }
.pagos-paso {
  margin: 4px 0 12px;
  padding: 12px 14px;
  border: var(--oecsa-borde);
  border-left: 4px solid var(--oecsa-verde);
  border-radius: 6px;
}
.pagos-paso .campo-fila { margin-bottom: 8px; }
/* La bandeja de facturas (DECISIONES 1.338): en el teléfono la tabla se
   desliza de lado en vez de cortarse, para llegar a «Siguiente paso», y el
   formulario que se abre debajo se queda a la vista, del ancho de la
   pantalla. */
.facturas-bandeja-marco { overflow-x: auto; }
.facturas-bandeja-marco .pagos-paso {
  position: sticky;
  left: 0;
  max-width: calc(100vw - 58px);
}
.pagos-paso-puntos { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 0 0 8px; padding: 0; list-style: none; }
/* La captura del voucher se pega aquí (DECISIONES 1.334). */
.pagos-pegar {
  min-height: 64px;
  border-style: dashed;
  resize: none;
  cursor: copy;
}
.pagos-pegados { margin: 4px 0 0; padding-left: 18px; font-size: 13px; }
/* Los botones de un formulario largo —la semana de una estimación de
   trescientos renglones— se quedan al pie de la pantalla mientras el
   formulario está a la vista, en vez de esperar al final de la tabla. */
.acciones-fijas {
  position: sticky;
  bottom: 0;
  z-index: 5;
  margin: 12px 0 0;
  padding: 10px 0;
  background: var(--oecsa-blanco);
  border-top: var(--oecsa-borde);
  box-shadow: 0 -6px 12px rgba(35, 31, 32, 0.06);
}
/* «Le toca a usted» arriba de una ficha larga: el enlace baja a la sección
   donde está la aprobación (DECISIONES 1.290). */
.le-toca { font-weight: 500; }
.le-toca-enlace {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
}
:target { scroll-margin-top: 16px; }
@media (max-width: 600px) {
  .tareas-renglon-fila { flex-wrap: wrap; }
  .tareas-fin { margin-left: 32px; flex-wrap: wrap; }
  .tareas-hilo { margin-left: 0; }
  .tareas-hilo-form { flex-direction: column; align-items: stretch; }
}
/* «Mi día» se llena desde Tareas (DECISIONES 1.263). La columna izquierda
   apila la cabecera del plan y la descarga mental. */
.timebox-pila {
  display: grid;
  gap: 20px;
  min-width: 0;
}
/* El selector de tareas y el texto libre se reparten la hora. */
.timebox-elegir {
  flex: 1;
  min-width: 0;
}
/* «Mi día» (12/10/2026): la jornada es lo que se trabaja todo el día y lleva
   dos tercios del ancho; el plan y la descarga mental, el tercio de al lado.
   Mitad y mitad dejaba cada hora con el selector, el texto y el botón
   apretados en poco más de 300 px. */
.timebox-columnas-dia {
  grid-template-columns: minmax(260px, 1fr) minmax(0, 2fr);
}
@media (max-width: 900px) {
  .timebox-columnas-dia { grid-template-columns: minmax(0, 1fr); }
}
/* El selector de tareas pesa menos que el texto libre: es un botón para
   elegir, no un campo donde se lee. */
.timebox-columnas-dia .timebox-elegir { flex: 0 1 230px; }
/* Una hora con tareas se distingue de una vacía sin leerla: fondo de fila y
   la hora con su marca a la izquierda. */
.timebox-con-tareas {
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio);
  border-bottom-color: transparent;
  margin: 4px 0;
  padding: 0 8px 6px;
}
.timebox-con-tareas .timebox-hora {
  box-shadow: inset 3px 0 0 var(--oecsa-negro);
  padding-left: 7px;
}
/* Las tareas de una hora, debajo de la fila, alineadas después de la hora.
   Cada una es una tarjeta: su check, qué es, de dónde viene y para cuándo. */
.timebox-tareas {
  list-style: none;
  margin: 6px 0 0 54px;
  padding: 0;
  display: grid;
  gap: 6px;
}
.timebox-tarea {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-left: 3px solid var(--oecsa-gris-medio);
  border-radius: var(--oecsa-radio);
}
.timebox-tarea-impact { border-left-color: var(--estado-info-tx); }
.timebox-tarea-ticket,
.timebox-tarea-legal { border-left-color: var(--estado-alerta-tx); }
.timebox-tarea .tareas-titulo { font-weight: 500; }
.timebox-tarea .celda-secundaria { font-size: 11px; }
.timebox-tarea-cuerpo {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.timebox-tarea-hecha .tareas-check {
  background: var(--oecsa-verde);
  border-color: var(--oecsa-verde);
}
.timebox-tarea-hecha .tareas-titulo {
  color: var(--oecsa-gris);
  text-decoration: line-through;
}
/* Sacar de la hora o quitar de la descarga: una equis al final del renglón. */
.timebox-quitar {
  flex: none;
  padding: 5px 9px;
  font-size: 13px;
}
.timebox-descargas {
  list-style: none;
  padding: 0;
  margin: 8px 0 0;
}
.timebox-descarga {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  padding: 6px 0;
  border-bottom: var(--oecsa-borde);
}
.timebox-descarga:last-child { border-bottom: 0; }
.timebox-descarga-texto {
  flex: 1 1 200px;
  min-width: 0;
  font-size: 13px;
  overflow-wrap: anywhere;
}
.timebox-descarga-acciones {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.timebox-descarga-acciones .campo { width: auto; }
/* En el teléfono la hora no alcanza para selector, texto y botón en una fila:
   el selector va al lado de la hora y el texto baja con «Marcar» al lado. */
@media (max-width: 600px) {
  .timebox-fila { flex-wrap: wrap; }
  .timebox-elegir,
  .timebox-columnas-dia .timebox-elegir { flex-basis: calc(100% - 54px); }
  .timebox-tareas { margin-left: 0; }
  .timebox-elegir ~ .timebox-actividad { margin-left: 54px; flex: 1 1 0; width: auto; }
}

/* ------------------------------------------------------------- modo oscuro
 * Grises con letras blancas y el verde OECSA de acento. Se enciende y se apaga
 * con el botón junto a la versión (static/js/tema.js); la preferencia vive en
 * el navegador y la aplica navegacion-temprano.js antes de pintar, para que no
 * parpadee. Lo que viene abajo es:
 *
 * 1. Los tokens en su versión oscura: casi todo el sistema se pinta con ellos.
 * 2. Lo que invierte los papeles —fondo negro con letra blanca, como los
 *    encabezados de tabla— queda oscuro con letra clara.
 * 3. Lo que va sobre verde conserva la letra negra: la regla de marca manda
 *    texto #231F20 sobre el verde, y con los tokens invertidos saldría clara.
 * 4. Lo que es papel —el PEUP, los códigos de la matriz, el semáforo— sigue
 *    claro: sus colores significan algo y en oscuro dejarían de leerse.
 */
[data-tema="oscuro"] {
  color-scheme: dark;
  --oecsa-negro: #ECECEC;
  --oecsa-blanco: #2A2A2A;
  --oecsa-fila: #323232;
  --oecsa-gris-claro: #474747;
  --oecsa-gris-medio: #5C5C5C;
  --oecsa-gris: #B4B8AE;
  --estado-ok-bg: #22381A;
  --estado-ok-tx: #CDE8B8;
  --estado-alerta-bg: #3D2E14;
  --estado-alerta-tx: #F5D59C;
  --estado-error-bg: #43201F;
  --estado-error-tx: #F5B8B5;
  --estado-info-bg: #1B2E42;
  --estado-info-tx: #B8D6F5;
  --estado-neutro-bg: #3A3935;
  --estado-neutro-tx: #DDDBD3;
  --oecsa-velo: rgba(0, 0, 0, 0.55);
  --oecsa-sombra: 0 8px 28px rgba(0, 0, 0, 0.5);
  --tema-fondo: #1F1F1F;
  --tema-oscuro: #141414;
  --tema-tinta-sobre-verde: #231F20;
}
[data-tema="oscuro"] body { background: var(--tema-fondo); }

[data-tema="oscuro"] .tabla thead th,
[data-tema="oscuro"] .video-propio,
[data-tema="oscuro"] .tabla-matriz thead .matriz-persona,
[data-tema="oscuro"] .tabla-matriz thead .matriz-elegir,
[data-tema="oscuro"] .buzon-paso-numero {
  background: var(--tema-oscuro);
  color: var(--oecsa-negro);
}

[data-tema="oscuro"] .oecsa-titulo::after,
[data-tema="oscuro"] .oecsa-franja,
[data-tema="oscuro"] .btn-primario,
[data-tema="oscuro"] .insignia-admin,
[data-tema="oscuro"] .avatar-destacado,
[data-tema="oscuro"] .aplicacion-icono,
[data-tema="oscuro"] .video-tarjeta-icono,
[data-tema="oscuro"] .reaccion-mia,
[data-tema="oscuro"] .distintivo-en-movimiento,
[data-tema="oscuro"] .accion-principal,
[data-tema="oscuro"] .boton-mover:not(:disabled):hover,
[data-tema="oscuro"] .aplicacion-avisos,
[data-tema="oscuro"] .avisos-numero,
[data-tema="oscuro"] .reserva-prioridad,
[data-tema="oscuro"] .reserva-linea.reserva-prioridad,
[data-tema="oscuro"] .timebox-hecho .timebox-marcar,
[data-tema="oscuro"] .lateral-fijar[aria-pressed="true"],
[data-tema="oscuro"] .syso-casilla input:checked + span,
[data-tema="oscuro"] .syso-casilla label:has(input:checked),
[data-tema="oscuro"] .captura-opciones label:has(input:checked),
[data-tema="oscuro"] .buzon-barra,
[data-tema="oscuro"] .buzon-como li::before,
[data-tema="oscuro"] .buzon-segmento:has(input:checked) span {
  color: var(--tema-tinta-sobre-verde);
}

[data-tema="oscuro"] .peup-hoja,
[data-tema="oscuro"] [class*="codigo-"],
[data-tema="oscuro"] .kpi-fondo-vo,
[data-tema="oscuro"] .kpi-fondo-vc,
[data-tema="oscuro"] .kpi-fondo-a,
[data-tema="oscuro"] .kpi-fondo-r,
[data-tema="oscuro"] .comentario-interno,
[data-tema="oscuro"] .aviso-bloqueo {
  --oecsa-negro: #231F20;
  --oecsa-blanco: #FFFFFF;
  --oecsa-fila: #F5F5F3;
  --oecsa-gris: #6B6E66;
  color: #231F20;
}

/* El símbolo del logotipo tiene el trazo negro: en oscuro va sobre un papel. */
[data-tema="oscuro"] .encabezado-marca,
[data-tema="oscuro"] .acceso-logo {
  background: #F2F2F2;
  border-radius: 4px;
}
/* Los iconos son trazos negros: en oscuro se aclaran, salvo los que van sobre
   el verde de las aplicaciones. */
[data-tema="oscuro"] img[src*="/img/icons/"] { filter: invert(0.9); }
[data-tema="oscuro"] .aplicacion-icono img { filter: none; }

.tema-boton {
  border: var(--oecsa-borde);
  border-radius: 999px;
  background: transparent;
  color: var(--oecsa-negro);
  font: inherit;
  font-size: 12px;
  padding: 2px 10px;
  margin-left: 8px;
  cursor: pointer;
  white-space: nowrap;
}
.tema-boton:hover { border-color: var(--oecsa-verde); }
.tema-boton[aria-pressed="true"] { background: var(--oecsa-verde); color: var(--tema-tinta-sobre-verde, #231F20); border-color: var(--oecsa-verde); }

/* ------------------------------------------------------------ Desarrollo
 * El portafolio en tablero por etapa y el camino de la ficha. Mismos tokens
 * que el resto; nada de hex sueltos. Las columnas son ocho y no caben en una
 * pantalla angosta: el tablero se desplaza de lado, la página no. */
.desarrollo-por-etapa { margin-bottom: 18px; overflow-x: auto; }
.desarrollo-tablero {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(200px, 1fr);
  gap: 12px;
  overflow-x: auto;
  padding-bottom: 8px;
  align-items: start;
}
.desarrollo-columna {
  background: var(--oecsa-fila);
  border-radius: var(--oecsa-radio);
  padding: 10px;
  min-height: 120px;
}
.desarrollo-columna-titulo {
  font-size: 12px;
  font-weight: 600;
  color: var(--oecsa-negro);
  border-bottom: 3px solid var(--oecsa-verde);
  padding-bottom: 6px;
  margin: 0 0 4px;
}
.desarrollo-columna-cuenta {
  font-size: 11px;
  color: var(--oecsa-gris);
  margin: 0 0 10px;
}
.desarrollo-columna-vacia { font-size: 12px; margin: 0; }
.desarrollo-tarjeta {
  display: block;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  padding: 8px 10px;
  margin-bottom: 8px;
  color: var(--oecsa-negro);
  text-decoration: none;
}
.desarrollo-tarjeta:hover { border-color: var(--oecsa-gris); }
.desarrollo-tarjeta-nombre { font-size: 13px; font-weight: 500; margin: 0; }
.desarrollo-tarjeta-dato { font-size: 11px; color: var(--oecsa-gris); margin: 2px 0 0; }

/* Las ocho etapas en fila, con la actual en verde y letra negra encima. */
.desarrollo-ruta {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 0;
  margin: 12px 0;
}
.desarrollo-ruta li {
  font-size: 11px;
  padding: 3px 10px;
  border: var(--oecsa-borde);
  border-radius: 999px;
  color: var(--oecsa-gris);
}
.desarrollo-ruta .desarrollo-ruta-actual {
  background: var(--oecsa-verde);
  border-color: var(--oecsa-verde);
  color: var(--oecsa-negro);
  font-weight: 600;
}
[data-tema="oscuro"] .desarrollo-ruta .desarrollo-ruta-actual {
  color: var(--tema-tinta-sobre-verde);
}

/* Las siete fechas del camino: la raya de arriba es verde cuando el hito ya
   tiene fecha. */
.desarrollo-camino {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
  padding: 0;
  margin: 0 0 18px;
}
.desarrollo-camino-hito {
  border-top: 4px solid var(--oecsa-gris-claro);
  padding-top: 6px;
}
.desarrollo-camino-hecho { border-top-color: var(--oecsa-verde); }
.desarrollo-camino-fecha { display: block; font-size: 13px; font-weight: 500; }

/* Los hitos de la ficha: el título de cada fase con su avance, la subtarea
   sangrada y el cambio de estado en la misma fila. */
.desarrollo-fase {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 14px;
  font-weight: 500;
  margin: 18px 0 8px;
}
.desarrollo-avance {
  width: 120px;
  height: 8px;
  accent-color: var(--oecsa-verde);
}
.desarrollo-subtarea {
  display: block;
  padding-left: 18px;
  border-left: 2px solid var(--oecsa-gris-claro);
}
.desarrollo-en-linea {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.desarrollo-en-linea .campo { width: auto; min-width: 120px; height: 32px; }

/* ------------------------------------------------------------ Comercial
 * La disponibilidad por desarrollo. La matriz de tipo por estado se desplaza
 * de lado en una pantalla angosta, la página no; la fila de totales va en
 * negrita para leerse como suma y no como un tipo más. */
.comercial-matriz { margin-bottom: 18px; overflow-x: auto; }
.comercial-total td { font-weight: 600; }

/* La tabla de unidades (14/10/2026): muchas columnas que cada quien elige.
 * Se desplaza dentro de su marco, con los títulos fijos arriba y la unidad fija
 * a la izquierda, como la rejilla de indicadores. Los títulos se arrastran. */
.comercial-tabla-marco { overflow: auto; max-height: 75vh; }
.comercial-tabla { font-size: 12px; }
.comercial-tabla th,
.comercial-tabla td { white-space: nowrap; }
.comercial-tabla thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  cursor: grab;
}
.comercial-tabla tbody td:first-child,
.comercial-tabla thead th:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--oecsa-blanco);
}
.comercial-tabla thead th:first-child { z-index: 3; }
.comercial-arrastrando { opacity: 0.45; }
.comercial-comentarios { white-space: normal; display: inline-block; max-width: 260px; }

/* El panel de columnas: una lista que se arrastra. Sin JavaScript, el número
 * de orden se escribe a mano; con él, se esconde y manda el arrastre. */
.comercial-columnas-lista {
  list-style: none;
  padding: 0;
  margin: 8px 0;
  columns: 3 240px;
}
.comercial-columna {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  margin-bottom: 4px;
  break-inside: avoid;
  background: var(--oecsa-blanco);
}
.comercial-columna label { flex: 1; font-size: 13px; }
.comercial-columna-asa { cursor: grab; color: var(--oecsa-gris); }
.comercial-columna-orden { width: 64px; }
.comercial-columnas-con-js .comercial-columna-orden { display: none; }

/* El diálogo de comentarios de la tabla. */
.comercial-dialogo {
  width: min(640px, 92vw);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  box-shadow: var(--oecsa-sombra);
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
}
.comercial-dialogo::backdrop { background: var(--oecsa-velo); }
.comercial-comentarios-lista li { margin-bottom: 10px; }
.comercial-comentarios-lista .celda-secundaria { display: block; }

/* El plazo de la promesa: a tiempo, por vencer y vencido, con el semáforo. */
.comercial-plazo-a_tiempo,
.comercial-plazo-a-tiempo { background: var(--estado-ok-bg); color: var(--estado-ok-tx); }
.comercial-plazo-por_vencer,
.comercial-plazo-por-vencer { background: var(--estado-alerta-bg); color: var(--estado-alerta-tx); }
.comercial-plazo-vencido { background: var(--estado-error-bg); color: var(--estado-error-tx); }

/* El mapa de hitos: el paso que sigue se ve distinto y se abre al hacer clic. */
.comercial-camino { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.comercial-camino .celda-secundaria { display: block; font-size: 11px; }
.comercial-camino-siguiente { border-top-color: var(--oecsa-negro); }
.comercial-camino .comercial-paso-vencido { border-top-color: var(--semaforo-r); }
.comercial-camino .comercial-paso-por_vencer { border-top-color: var(--semaforo-a); }
.comercial-camino-marcar summary {
  cursor: pointer;
  list-style: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.comercial-camino-marcar[open] {
  grid-column: 1 / -1;
  background: var(--oecsa-fila);
  padding: 8px;
  border-radius: var(--oecsa-radio);
}
.comercial-subpestanas { margin-top: 4px; }

/* Los resúmenes de los reportes: un número grande por estatus o motivo. */
.comercial-resumen {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 8px 0 16px;
}
.comercial-resumen-tarjeta {
  display: flex;
  flex-direction: column;
  min-width: 150px;
  padding: 8px 12px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  color: var(--oecsa-negro);
  text-decoration: none;
}
.comercial-resumen-activa { border-color: var(--oecsa-negro); }
.comercial-resumen-numero { font-size: 22px; font-weight: 600; }
.comercial-fila-cuello td { font-weight: 600; }
.comercial-fila-error td { background: var(--estado-error-bg); }
.comercial-elegir { border: 0; padding: 0; margin: 0; display: flex; gap: 10px; align-items: center; }
.comercial-elegir label { font-size: 13px; }

/* Las gráficas: SVG del servidor sin un color escrito (DECISIONES 1.212). */
.comercial-grafica { display: block; width: 100%; max-width: 960px; height: auto; margin: 8px 0 20px; }
.comercial-grafica-eje { stroke: var(--oecsa-gris-claro); stroke-width: 1; }
.comercial-grafica-texto { fill: var(--oecsa-negro); font-size: 12px; font-family: var(--oecsa-font); }
.comercial-grafica-etiqueta { font-size: 13px; }
.comercial-grafica-valor { fill: var(--oecsa-negro); font-size: 11px; font-family: var(--oecsa-font); }
.comercial-grafica-total { fill: var(--oecsa-negro); font-size: 12px; font-weight: 600; font-family: var(--oecsa-font); }
.comercial-grafica-alerta { fill: var(--semaforo-r); font-size: 11px; font-weight: 600; font-family: var(--oecsa-font); }
.comercial-grafica-disponible { fill: var(--oecsa-verde); }
.comercial-grafica-reservado { fill: var(--oecsa-gris); }
.comercial-grafica-no-disponible { fill: var(--oecsa-gris-claro); }
.comercial-grafica-estatus { fill: var(--oecsa-verde); }
.comercial-grafica-cuello { fill: var(--semaforo-r); }
.comercial-grafica-vencidas { fill: var(--semaforo-r); }
.comercial-leyenda { list-style: none; display: flex; gap: 16px; padding: 0; margin: 4px 0; font-size: 12px; }
.comercial-leyenda li::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 6px;
  border-radius: 2px;
}
.comercial-leyenda-disponible::before { background: var(--oecsa-verde); }
.comercial-leyenda-reservado::before { background: var(--oecsa-gris); }
.comercial-leyenda-no_disponible::before { background: var(--oecsa-gris-claro); }

/* =============================================================================
   La puerta de campo de SYSO — sin sesión, en el teléfono, de pie en la obra
   ============================================================================= */

.campo-pagina {
  background: var(--oecsa-fila);
  margin: 0;
}
.campo-hoja {
  max-width: 560px;
  margin: 0 auto;
  padding: 18px 16px 40px;
  background: var(--oecsa-blanco);
  min-height: 100vh;
}
.campo-hoja-acuse {
  text-align: center;
}
.campo-cabecera {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}
.campo-logo {
  height: 34px;
  width: auto;
}
.campo-quien {
  margin: 0;
  font-size: 12px;
  color: var(--estado-neutro-tx);
}
.campo-titulo {
  margin: 2px 0 0;
  font-size: 20px;
  font-weight: 500;
  color: var(--oecsa-negro);
}
.campo-barra {
  width: 180px;
  height: var(--oecsa-barra);
  margin: 8px 0 14px;
  background: var(--oecsa-verde);
}
.campo-hoja-acuse .campo-barra {
  margin-left: auto;
  margin-right: auto;
}
.campo-nota {
  margin: 0 0 16px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--estado-neutro-tx);
}

/* La lista de controles: renglones altos, que se tocan con el pulgar. */
.campo-lista {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.campo-control {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 56px;
  padding: 12px 16px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  text-decoration: none;
  color: var(--oecsa-negro);
}
.campo-control:hover,
.campo-control:focus {
  background: var(--oecsa-fila);
  border-color: var(--oecsa-gris-medio);
}
.campo-control-nombre {
  font-size: 15px;
  font-weight: 500;
}
.campo-control-foto {
  flex: none;
  font-size: 11px;
  color: var(--oecsa-gris);
}

/* El enlace que se copia de la lista de enlaces. */
.enlace-copiable {
  display: inline-block;
  max-width: 100%;
  overflow-wrap: anywhere;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--oecsa-fila);
  font-size: 11px;
  color: var(--estado-neutro-tx);
}

@media (max-width: 560px) {
  .campo-hoja {
    padding: 14px 12px 32px;
  }
  .campo-barra {
    width: 120px;
  }
}

/* ---- Pagos: el cuadro de estimaciones en línea ----
   Un campo numérico dentro de una celda: el % de la semana o la unidad. El
   `.campo` normal ocupa todo el ancho y en una tabla de siete columnas se
   come el renglón. */
.campo-celda {
  width: 7.5rem;
  text-align: right;
}
.cuadro-totales {
  max-width: 34rem;
}

/* ---- Pagos: el flujo del 08/10/2026 (DECISIONES 1.266) ----
 * Con cheque no se pide cuenta: el bloque de la transferencia se esconde
 * cuando se elige cheque. Sin `:has` (navegadores viejos) se ven los dos, y
 * el servicio ignora la cuenta de un cheque. */
form:has(input[name="forma_pago"][value="cheque"]:checked) .solo-transferencia {
  display: none;
}
/* Los pasos del pago, arriba de cada pantalla: dónde va y qué sigue. */
.pago-pasos {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  padding: 0;
  margin: 0 0 16px;
  font-size: 13px;
}
.pago-pasos li {
  padding: 4px 10px;
  border: var(--oecsa-borde);
  border-radius: 999px;
  color: var(--oecsa-gris);
}
.pago-pasos .pago-paso-actual {
  background: var(--oecsa-verde);
  border-color: var(--oecsa-verde);
  color: var(--oecsa-negro);
  font-weight: 600;
}
.pago-pasos .pago-paso-hecho {
  color: var(--oecsa-negro);
}
/* Una respuesta cuelga de su pregunta. */
.comentario-respuesta {
  margin-left: 24px;
  border-left: 3px solid var(--oecsa-verde);
  padding-left: 10px;
}
/* El precio presupuestado al lado del de la oferta: solo referencia. */
.precio-referencia {
  color: var(--oecsa-gris);
}
/* Un botón principal que todavía no se puede usar —«Aprobar» con preguntas
 * abiertas— no se ve verde: el verde dice «adelante». */
.btn-primario:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ------------------------------------------------------------------ procesos
 * El mapa de procesos y el flujo interactivo de un procedimiento
 * (templates/procesos/). El diagrama es un SVG calculado de los datos
 * (procesos/diagrama.py); sus colores salen de los tokens, así que el modo
 * oscuro lo cambia solo. Lo que va sobre verde lleva la tinta fija. */
.procesos-codigo { font-variant-numeric: tabular-nums; letter-spacing: 0.02em; font-weight: 500; }

.procesos-datos { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0 4px; }
.procesos-dato {
  display: flex; flex-direction: column; gap: 2px; flex: 1 1 200px; min-width: 0;
  padding: 10px 14px; border: var(--oecsa-borde); border-radius: var(--oecsa-radio);
  background: var(--oecsa-blanco);
}
.procesos-dato b { font-weight: 600; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.procesos-dato span { color: var(--oecsa-gris); font-size: 0.78rem; }
.procesos-dato-destacado { border: 2px solid var(--oecsa-verde); }

.procesos-camino { margin: 14px 0; }
.procesos-camino .oecsa-subtitulo { margin-top: 4px; }
.procesos-faltantes { margin: 0 0 8px; padding-left: 20px; }
.procesos-decidir { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start; }
.procesos-devolver { display: flex; flex-direction: column; gap: 6px; flex: 1 1 320px; }

.procesos-pestanas {
  display: flex; gap: 4px; overflow-x: auto; margin: 18px 0 16px;
  border-bottom: var(--oecsa-borde);
}
.procesos-pestanas button {
  font: inherit; background: none; border: 0; border-bottom: 3px solid transparent;
  color: var(--oecsa-gris); padding: 10px 14px; cursor: pointer; white-space: nowrap; font-weight: 500;
}
.procesos-pestanas button[aria-selected="true"] { color: var(--oecsa-negro); border-bottom-color: var(--oecsa-verde); }

.procesos-flujo { display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 24px; align-items: start; }
.procesos-roles { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 8px; }
.procesos-roles-etiqueta { color: var(--oecsa-gris); font-size: 0.78rem; margin-right: 4px; }
.procesos-chip {
  font: inherit; font-size: 0.82rem; cursor: pointer; padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--oecsa-gris); background: var(--oecsa-blanco); color: var(--oecsa-negro);
}
.procesos-chip[aria-pressed="true"] {
  background: var(--oecsa-verde); border-color: var(--oecsa-verde);
  color: var(--tema-tinta-sobre-verde, var(--oecsa-negro)); font-weight: 500;
}
.procesos-lienzo { border: var(--oecsa-borde); border-radius: var(--oecsa-radio); overflow-x: auto; background: var(--oecsa-blanco); }
.procesos-svg { display: block; width: 100%; min-width: 720px; height: auto; font-family: var(--oecsa-font); }
/* El diagrama acostado (DECISIONES 1.377): se ve a 70 % de su tamaño y
   «Ampliar diagrama» lo deja al 100 %; lo que no cabe se desliza de lado. */
.procesos-svg-acostado { min-width: max(720px, calc(var(--procesos-ancho) * 0.7px)); }
.procesos-ampliado .procesos-svg-acostado { min-width: calc(var(--procesos-ancho) * 1px); }
.procesos-flujo-diagrama .procesos-lienzo { margin-bottom: 8px; -webkit-overflow-scrolling: touch; }
.procesos-herramientas { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.procesos-etapas { display: flex; flex-wrap: wrap; gap: 8px; }
.procesos-lista { margin-top: 14px; }
.procesos-grupo { font-size: 0.74rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--oecsa-gris); margin: 14px 0 6px; font-weight: 600; }
.procesos-grupo:first-child { margin-top: 0; }
.procesos-lista-pasos button[aria-current="true"] { border-color: var(--oecsa-negro); box-shadow: inset 3px 0 0 var(--oecsa-verde); }
button.procesos-dato { font: inherit; text-align: left; color: var(--oecsa-negro); cursor: pointer; }
button.procesos-dato:hover { background: var(--oecsa-fila); }
.procesos-dato em {
  font-style: normal; font-size: 0.78rem; font-weight: 500;
  text-decoration: underline; text-decoration-color: var(--oecsa-verde); text-underline-offset: 3px;
}
/* Las pestañas de lectura —Tiempos, Reglas e indicadores, Manual—: título con
   la barra verde detrás, como los del MAN-LEG-16. */
.procesos-manual { max-width: 1100px; }
.procesos-manual p, .procesos-manual ul { max-width: 80ch; }
.procesos-sub { font-size: 1.05rem; font-weight: 500; margin: 26px 0 10px; display: flex; align-items: center; gap: 12px; scroll-margin-top: 16px; }
.procesos-sub::after { content: ""; flex: 1; max-width: 300px; height: 5px; background: var(--oecsa-verde); }
.procesos-manual > .procesos-sub:first-child, .procesos-indice + .procesos-sub { margin-top: 0; }
.procesos-subtitulo { font-size: 0.95rem; font-weight: 500; margin: 18px 0 8px; }
.procesos-manual .tabla-marco, .procesos-bloque .tabla-marco { margin: 8px 0 16px; }
.procesos-bloque p + p { margin-top: 6px; }
.procesos-indice { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 18px; }
.procesos-indice a { text-decoration: none; }
.procesos-ver-paso { padding: 3px 10px; font-size: 0.8rem; white-space: nowrap; }

.procesos-carril { fill: var(--oecsa-blanco); }
.procesos-carril-alterno { fill: var(--oecsa-fila); }
.procesos-separador { stroke: var(--oecsa-gris-claro); stroke-width: 1; }
.procesos-cabeza rect { fill: var(--oecsa-verde); }
.procesos-cabeza { cursor: pointer; }
.procesos-t-carril { fill: var(--tema-tinta-sobre-verde, var(--oecsa-negro)); font-weight: 600; font-size: 13px; }
.procesos-flecha { fill: none; stroke: var(--oecsa-negro); stroke-width: 1.4; transition: opacity 0.2s; }
.procesos-flecha-punteada { stroke: var(--oecsa-gris); stroke-dasharray: 5 4; }
.procesos-caliente { stroke-width: 2.6; }
.procesos-punta { fill: var(--oecsa-negro); }
.procesos-punta-tenue { fill: var(--oecsa-gris); }
.procesos-t-flecha { fill: var(--oecsa-negro); font-size: 10.5px; font-weight: 500; }
.procesos-nodo { cursor: pointer; transition: opacity 0.2s; }
.procesos-nodo:focus { outline: none; }
.procesos-caja { fill: var(--oecsa-blanco); stroke: var(--oecsa-negro); stroke-width: 1.6; }
.procesos-nodo-alterno .procesos-caja { stroke-dasharray: 5 4; }
.procesos-banda { fill: var(--oecsa-verde); }
.procesos-t-banda { fill: var(--tema-tinta-sobre-verde, var(--oecsa-negro)); font-weight: 600; font-size: 11px; }
.procesos-t-caja { fill: var(--oecsa-negro); font-size: 11.5px; }
.procesos-t-caja-chica { fill: var(--oecsa-negro); font-size: 10px; }
.procesos-rombo { fill: var(--estado-neutro-bg); stroke: var(--oecsa-negro); stroke-width: 1.6; }
.procesos-t-equis { fill: var(--oecsa-negro); font-weight: 600; font-size: 14px; }
.procesos-t-pregunta { fill: var(--oecsa-gris); font-size: 10.5px; font-style: italic; }
.procesos-evento { fill: var(--oecsa-blanco); stroke: var(--oecsa-negro); stroke-width: 1.4; }
.procesos-evento-inicio { fill: var(--oecsa-verde); stroke-width: 1.6; }
.procesos-evento-fin { stroke-width: 4; }
.procesos-reloj { fill: none; stroke: var(--oecsa-negro); stroke-width: 1.4; }
.procesos-t-rotulo { fill: var(--oecsa-negro); font-size: 10.5px; }
.procesos-halo { fill: none; stroke: var(--oecsa-verde); stroke-width: 7; opacity: 0; }
.procesos-sel .procesos-halo { opacity: 1; }
.procesos-nodo:hover .procesos-caja,
.procesos-nodo:hover .procesos-rombo,
.procesos-nodo:hover .procesos-evento { stroke-width: 2.6; }
.procesos-nodo:focus-visible .procesos-halo { opacity: 1; }
.procesos-sel .procesos-caja, .procesos-sel .procesos-rombo { stroke-width: 3.2; }
.procesos-tenue { opacity: 0.22; }
.procesos-conector { cursor: pointer; }
.procesos-conector circle { fill: var(--oecsa-blanco); stroke: var(--oecsa-gris); stroke-width: 1.2; }
.procesos-t-conector { fill: var(--oecsa-gris); font-size: 9.5px; font-weight: 600; }
.procesos-t-enlace { fill: var(--oecsa-gris); font-size: 10px; font-style: italic; }

.procesos-panel {
  position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow: auto;
  border: var(--oecsa-borde); border-radius: var(--oecsa-radio-card); background: var(--oecsa-blanco);
  box-shadow: var(--oecsa-sombra); padding: 18px 20px; font-size: 0.9rem;
}
.procesos-ficha { display: flex; flex-direction: column; gap: 14px; }
.procesos-ficha + .procesos-ficha { margin-top: 28px; padding-top: 20px; border-top: var(--oecsa-borde); }
.con-js .procesos-ficha { display: none; }
.con-js .procesos-ficha.procesos-ficha-activa { display: flex; margin-top: 0; padding-top: 0; border-top: 0; }
.procesos-ficha-cabeza { display: flex; align-items: flex-start; gap: 12px; }
.procesos-ficha-titulo { margin: 0; font-size: 1.12rem; font-weight: 500; line-height: 1.3; }
.procesos-ficha-carril { margin: 2px 0 0; color: var(--oecsa-gris); font-size: 0.78rem; }
.procesos-cerrar {
  margin-left: auto; font: inherit; font-size: 1.3rem; line-height: 1; background: none; border: 0;
  color: var(--oecsa-gris); cursor: pointer; padding: 4px 6px; display: none;
}
.procesos-numero {
  flex: none; min-width: 44px; height: 44px; padding: 0 8px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 1.05rem;
  background: var(--oecsa-verde); color: var(--tema-tinta-sobre-verde, var(--oecsa-negro));
}
.procesos-numero-otro { background: var(--estado-neutro-bg); color: var(--oecsa-negro); border: 1.5px solid var(--oecsa-negro); }
.procesos-kv { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: 6px 12px; margin: 0; font-size: 0.9rem; }
.procesos-kv dt { color: var(--oecsa-gris); font-size: 0.78rem; padding-top: 2px; }
.procesos-kv dd { margin: 0; }
.procesos-tiempo {
  display: inline-block; padding: 1px 10px; border-radius: 4px; font-weight: 600; font-size: 0.86rem;
  background: var(--oecsa-verde); color: var(--tema-tinta-sobre-verde, var(--oecsa-negro));
}
.procesos-tiempo-largo { display: block; color: var(--oecsa-gris); font-size: 0.84rem; margin-top: 2px; }
.procesos-bloque h3 { margin: 0 0 4px; font-size: 0.74rem; font-weight: 600; color: var(--oecsa-gris); letter-spacing: 0.06em; }
.procesos-bloque p { margin: 0; }
.procesos-io { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.procesos-io > div { background: var(--oecsa-fila); border-radius: 6px; padding: 10px 12px; min-width: 0; }
.procesos-checklist ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.procesos-checklist label { display: flex; gap: 8px; align-items: flex-start; cursor: pointer; }
.procesos-checklist input { margin-top: 4px; accent-color: var(--oecsa-verde); }
.procesos-aviso, .procesos-aviso-nota {
  border-left: 4px solid var(--oecsa-verde); background: var(--oecsa-fila);
  padding: 10px 12px; border-radius: 0 6px 6px 0;
}
.procesos-aviso-nota { border-left-color: var(--oecsa-gris); }
.procesos-aviso b, .procesos-aviso-nota b {
  display: block; font-size: 0.74rem; font-weight: 600; color: var(--oecsa-gris); margin-bottom: 2px;
}
.procesos-opciones { display: flex; flex-direction: column; gap: 8px; }
.procesos-opcion {
  font: inherit; text-align: left; display: flex; gap: 10px; align-items: center; cursor: pointer;
  border: 1px solid var(--oecsa-gris); background: var(--oecsa-blanco); color: var(--oecsa-negro);
  border-radius: 6px; padding: 10px 12px;
}
.procesos-opcion:hover { border-color: var(--oecsa-negro); }
.procesos-opcion-r { flex: none; font-weight: 600; min-width: 64px; }
.procesos-nav { display: flex; gap: 8px; justify-content: space-between; border-top: var(--oecsa-borde); padding-top: 14px; }
.procesos-lista-pasos { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.procesos-lista-pasos button {
  width: 100%; font: inherit; text-align: left; cursor: pointer; display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto; gap: 10px; align-items: center;
  border: var(--oecsa-borde); background: var(--oecsa-blanco); color: var(--oecsa-negro);
  padding: 8px 10px; border-radius: 6px;
}
.procesos-lista-pasos button:hover { border-color: var(--oecsa-negro); }
.procesos-n { font-weight: 600; }
.procesos-t { color: var(--oecsa-gris); font-size: 0.8rem; white-space: nowrap; }

.procesos-reglas {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px;
  margin: 0; padding: 0; list-style: none;
}
.procesos-reglas li { border: var(--oecsa-borde); border-radius: var(--oecsa-radio); padding: 14px 16px; background: var(--oecsa-blanco); }
.procesos-reglas b { display: block; font-weight: 600; margin-bottom: 4px; }
.procesos-columnas { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 24px; }
.procesos-plana { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; }
.procesos-definiciones { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.procesos-definiciones dt { font-weight: 600; }
.procesos-definiciones dd { margin: 0; color: var(--oecsa-gris); }
.procesos-en-linea { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; margin-top: 12px; }
.procesos-en-linea .campo { max-width: 140px; }

/* El mapa nivel 1: estratégicos arriba, la cadena de valor al centro y los
   de apoyo abajo, como el MAPN1. */
.procesos-mapa { display: flex; flex-direction: column; gap: 14px; margin: 12px 0 8px; }
.procesos-mapa-fila {
  border: var(--oecsa-borde); border-radius: var(--oecsa-radio-card); padding: 12px 14px;
  background: var(--oecsa-blanco);
}
.procesos-mapa-fila h2 { margin: 0 0 10px; font-size: 0.78rem; font-weight: 600; color: var(--oecsa-gris); letter-spacing: 0.06em; }
.procesos-mapa-clave { border: 2px solid var(--oecsa-verde); }
.procesos-areas { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px; }
.procesos-area {
  display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: var(--oecsa-radio);
  border: var(--oecsa-borde); background: var(--oecsa-fila); color: var(--oecsa-negro); text-decoration: none;
}
.procesos-area:hover { border-color: var(--oecsa-negro); }
.procesos-area-elegida { background: var(--oecsa-verde); border-color: var(--oecsa-verde); color: var(--tema-tinta-sobre-verde, var(--oecsa-negro)); }
.procesos-area b { font-weight: 500; }
.procesos-area span { font-size: 0.78rem; color: inherit; opacity: 0.75; }

/* El editor del borrador. */
.procesos-editor { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start; }
.procesos-editor .tarjeta + .tarjeta { margin-top: 16px; }
.procesos-formulario { display: flex; flex-direction: column; gap: 10px; }
.procesos-formulario .campo-ayuda { margin: 0; }
.procesos-rejilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px 14px; }
.procesos-figuras { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.procesos-figuras li { display: flex; gap: 10px; align-items: center; padding: 6px 8px; border-radius: 6px; }
.procesos-figuras li:nth-child(even) { background: var(--oecsa-fila); }
.procesos-figuras .procesos-figura-donde { color: var(--oecsa-gris); font-size: 0.8rem; margin-left: auto; white-space: nowrap; }
.procesos-alerta-checklist { color: var(--estado-alerta-tx); font-size: 0.78rem; }
.procesos-filas-formulario { display: flex; flex-direction: column; gap: 10px; }
.procesos-fila-formulario {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 8px;
  padding: 10px; border: var(--oecsa-borde); border-radius: var(--oecsa-radio);
}
.procesos-fila-tabla { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.procesos-flechas-form { display: flex; flex-direction: column; gap: 8px; }
.procesos-flecha-form { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 1fr) auto; gap: 8px; align-items: end; }

@media (max-width: 1080px) {
  .procesos-flujo, .procesos-editor { grid-template-columns: minmax(0, 1fr); }
  .procesos-panel {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; max-height: 72vh; z-index: 20;
    border-radius: 14px 14px 0 0; transform: translateY(105%); transition: transform 0.25s ease;
  }
  .procesos-panel.procesos-panel-abierto { transform: none; }
  .procesos-cerrar { display: block; }
}
@media (max-width: 520px) {
  .procesos-io, .procesos-kv, .procesos-fila-formulario, .procesos-flecha-form { grid-template-columns: 1fr; }
}

/* ---- Equipos (12/10/2026) ---- */
/* El organigrama por equipos: una tarjeta por jefe, con su gente en renglones.
   Las tarjetas propias («Mi equipo», «El equipo de su jefe») llevan el borde
   negro y una etiqueta verde con texto negro encima, nunca texto verde. */
.equipos-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
  align-items: start;
}
.equipos-tarjeta {
  scroll-margin-top: 16px;
}
.equipos-tarjeta:target {
  border-color: var(--oecsa-negro);
}
.equipos-tarjeta-destacada {
  border-color: var(--oecsa-negro);
}
.equipos-marca {
  display: inline-block;
  margin: 0 0 8px;
  padding: 2px 8px;
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-verde);
  color: var(--oecsa-negro);
  font-size: 12px;
  font-weight: 500;
}
.equipos-tarjeta .tarjeta-titulo {
  margin-bottom: 2px;
}
.equipos-tarjeta .nodo-insignias {
  margin: 6px 0;
}
.equipos-filas {
  list-style: none;
  padding: 0;
  margin: 10px 0 0;
}
.equipos-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  padding: 6px 0;
  border-bottom: var(--oecsa-borde);
  font-size: 13px;
  scroll-margin-top: 16px;
}
.equipos-fila:last-child {
  border-bottom: 0;
}
.equipos-fila-coincide {
  background: var(--oecsa-fila);
}
.equipos-editor {
  flex-basis: 100%;
}
.equipos-editor:empty {
  display: none;
}
.equipos-agregar {
  margin: 10px 0 0;
  font-size: 13px;
}
.equipos-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
  padding: 10px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-fila);
}
.equipos-form .campo {
  width: 100%;
}
.equipos-form-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.equipos-form-quitar {
  margin-top: 6px;
  font-size: 13px;
}
.equipos-editor-pagina {
  max-width: 560px;
}
.equipos-plegable {
  margin-top: 12px;
}
.equipos-plegable summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--oecsa-negro);
}
@media (max-width: 520px) {
  .equipos-rejilla {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* El filtro rápido de la matriz de asistencia (DECISIONES 1.295): botones
   por lugar que se prenden en verde y un buscador, sin recargar. */
.filtro-rapido { display: grid; gap: 8px; margin: 12px 0; }
.filtro-rapido[hidden] { display: none; }
.filtro-rapido-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.filtro-rapido-buscar { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.filtro-rapido-buscar .campo { max-width: 320px; }
.chip-filtro {
  font: inherit; font-size: 0.82rem; cursor: pointer; padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--oecsa-gris); background: var(--oecsa-blanco); color: var(--oecsa-negro);
}
.chip-filtro[aria-pressed="true"] {
  background: var(--oecsa-verde); border-color: var(--oecsa-verde);
  color: var(--tema-tinta-sobre-verde, var(--oecsa-negro)); font-weight: 500;
}
.tabla-matriz tr[hidden] { display: none; }

/* La miniatura del voucher en el reporte de pagados (DECISIONES 1.311). */
.voucher-miniatura {
  display: block;
  max-width: 160px;
  max-height: 120px;
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  background: var(--oecsa-fila);
  object-fit: contain;
}

/* Procesos: el menú del módulo, las auditorías y el semáforo de AuditOE. */
.procesos-menu { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 0 0 12px; font-size: 0.86rem; }
.procesos-menu a { color: var(--oecsa-gris); text-decoration: none; padding: 4px 0; border-bottom: 3px solid transparent; }
.procesos-menu a:hover { color: var(--oecsa-negro); }
.procesos-menu a[aria-current="page"] { color: var(--oecsa-negro); border-bottom-color: var(--oecsa-verde); }

.procesos-semaforo {
  display: inline-block; padding: 2px 10px; border-radius: 999px; font-weight: 600; font-size: 0.86rem;
}
.procesos-semaforo-excelente { background: var(--estado-ok-bg); color: var(--estado-ok-tx); }
.procesos-semaforo-alerta { background: var(--estado-alerta-bg); color: var(--estado-alerta-tx); }
.procesos-semaforo-deficiente { background: var(--estado-error-bg); color: var(--estado-error-tx); }

.procesos-seccion-auditoria { margin: 14px 0; }
.procesos-seccion-auditoria .oecsa-subtitulo { margin-top: 0; }
.procesos-pregunta { border: 0; border-top: var(--oecsa-borde); margin: 0; padding: 12px 0; }
.procesos-pregunta:first-of-type { border-top: 0; }
.procesos-pregunta legend { font-weight: 500; padding: 0; float: left; width: 100%; }
.procesos-pregunta legend + * { clear: both; }
.procesos-pregunta .campo-ayuda { margin: 2px 0 8px; }
.procesos-resultados { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.procesos-resultado { position: relative; cursor: pointer; }
.procesos-resultado input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.procesos-resultado span {
  display: inline-block; padding: 6px 12px; border-radius: 999px; font-size: 0.84rem;
  border: 1px solid var(--oecsa-gris); background: var(--oecsa-blanco); color: var(--oecsa-negro);
}
.procesos-resultado input:focus-visible + span { outline: 2px solid var(--oecsa-negro); outline-offset: 2px; }
.procesos-resultado-conforme input:checked + span { background: var(--estado-ok-bg); color: var(--estado-ok-tx); border-color: var(--estado-ok-tx); font-weight: 600; }
.procesos-resultado-parcial input:checked + span { background: var(--estado-alerta-bg); color: var(--estado-alerta-tx); border-color: var(--estado-alerta-tx); font-weight: 600; }
.procesos-resultado-no_conforme input:checked + span { background: var(--estado-error-bg); color: var(--estado-error-tx); border-color: var(--estado-error-tx); font-weight: 600; }
.procesos-resultado-no_aplica input:checked + span { background: var(--estado-neutro-bg); color: var(--estado-neutro-tx); border-color: var(--estado-neutro-tx); font-weight: 600; }
.procesos-resultado-insignia { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 0.8rem; font-weight: 600; }
.procesos-resultado-insignia.procesos-resultado-conforme { background: var(--estado-ok-bg); color: var(--estado-ok-tx); }
.procesos-resultado-insignia.procesos-resultado-parcial { background: var(--estado-alerta-bg); color: var(--estado-alerta-tx); }
.procesos-resultado-insignia.procesos-resultado-no_conforme { background: var(--estado-error-bg); color: var(--estado-error-tx); }
.procesos-resultado-insignia.procesos-resultado-no_aplica { background: var(--estado-neutro-bg); color: var(--estado-neutro-tx); }
.procesos-fotos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.procesos-fotos img { width: 96px; height: 72px; object-fit: cover; border-radius: 6px; border: var(--oecsa-borde); display: block; }
.procesos-guardar-fijo {
  position: sticky; bottom: 0; background: var(--oecsa-blanco); padding: 10px 0;
  border-top: var(--oecsa-borde); z-index: 5;
}

/* Procesos: la espina de Ishikawa, el análisis y el calendario del mes. */
.procesos-espina { display: block; width: 100%; min-width: 720px; height: auto; font-family: var(--oecsa-font); }
.procesos-espina-eje { stroke: var(--oecsa-negro); stroke-width: 3; }
.procesos-espina-hueso { stroke: var(--oecsa-negro); stroke-width: 1.6; }
.procesos-espina-cabeza { fill: var(--oecsa-verde); }
.procesos-espina-efecto { fill: var(--tema-tinta-sobre-verde, var(--oecsa-negro)); font-size: 12px; font-weight: 600; }
.procesos-espina-categoria-fondo { fill: var(--oecsa-negro); }
.procesos-espina-categoria { fill: var(--oecsa-blanco); font-size: 12px; font-weight: 600; }
.procesos-espina-causa-linea { stroke: var(--oecsa-gris); stroke-width: 1; }
.procesos-espina-causa { fill: var(--oecsa-negro); font-size: 10.5px; }
.procesos-analisis { margin: 12px 0; }
.procesos-mini-titulo { margin: 0 0 6px; font-size: 0.78rem; font-weight: 600; color: var(--oecsa-gris); letter-spacing: 0.06em; }
.procesos-porques { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 4px; }
.procesos-rejilla-ancha { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
details.procesos-camino > summary { cursor: pointer; list-style-position: inside; margin: 0; }
details.procesos-camino[open] > summary { margin-bottom: 12px; }

.procesos-mes-barra { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 6px 0 12px; }
.procesos-mes-nombre { margin: 0; font-size: 1.1rem; font-weight: 500; min-width: 180px; text-align: center; }
.procesos-mes-acciones { margin-left: auto; display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.procesos-mes { border: var(--oecsa-borde); border-radius: var(--oecsa-radio); overflow-x: auto; background: var(--oecsa-blanco); }
.procesos-mes-fila { display: grid; grid-template-columns: repeat(7, minmax(110px, 1fr)); min-width: 770px; }
.procesos-mes-cabeza div {
  padding: 8px; font-size: 0.78rem; font-weight: 600; text-transform: none;
  background: var(--oecsa-negro); color: var(--oecsa-blanco);
}
.procesos-mes-dia {
  min-height: 96px; padding: 6px; border-top: var(--oecsa-borde); border-left: var(--oecsa-borde);
  display: flex; flex-direction: column; gap: 4px;
}
.procesos-mes-dia:first-child { border-left: 0; }
.procesos-mes-fuera { background: var(--oecsa-fila); }
.procesos-mes-hoy .procesos-mes-numero {
  background: var(--oecsa-verde); color: var(--tema-tinta-sobre-verde, var(--oecsa-negro));
  border-radius: 999px; padding: 0 7px;
}
.procesos-mes-numero { font-size: 0.8rem; font-weight: 600; align-self: flex-start; }
.procesos-mes-evento {
  display: block; font-size: 0.74rem; line-height: 1.3; padding: 3px 6px; border-radius: 4px;
  text-decoration: none; color: var(--oecsa-negro); background: var(--estado-neutro-bg);
  border-left: 3px solid var(--oecsa-gris);
}
.procesos-mes-auditoria { background: var(--estado-info-bg); color: var(--estado-info-tx); border-left-color: var(--estado-info-tx); }
.procesos-mes-gemba { background: var(--estado-ok-bg); color: var(--estado-ok-tx); border-left-color: var(--estado-ok-tx); }
.procesos-mes-actividad { background: var(--estado-alerta-bg); color: var(--estado-alerta-tx); border-left-color: var(--estado-alerta-tx); }
a.procesos-mes-evento:hover { text-decoration: underline; }

/* -----------------------------------------------------------------------------
   Indicadores: la ficha del rediseño (22/10/2026, DECISIONES 1.320)
   ----------------------------------------------------------------------------- */
.mensaje-aviso {
  background: var(--estado-alerta-bg);
  color: var(--estado-alerta-tx);
  border-radius: var(--oecsa-radio);
  padding: 10px 12px;
  font-size: 12px;
  line-height: 1.5;
  margin: 0 0 16px;
}
.kpi-codigo {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 12px;
  color: var(--oecsa-gris);
  white-space: nowrap;
}
.kpi-editor-titulo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin: -8px 0 16px;
}
.kpi-editor-titulo:empty { display: none; }
.kpi-estado-borrador    { background: var(--estado-neutro-bg); color: var(--estado-neutro-tx); }
.kpi-estado-en_revision { background: var(--estado-info-bg);   color: var(--estado-info-tx); }
.kpi-estado-activo      { background: var(--estado-ok-bg);     color: var(--estado-ok-tx); }
.kpi-estado-suspendido  { background: var(--estado-alerta-bg); color: var(--estado-alerta-tx); }
.kpi-estado-retirado    { background: var(--estado-error-bg);  color: var(--estado-error-tx); }
.pestana-cuenta {
  font-size: 11px;
  color: var(--oecsa-gris);
  margin-left: 4px;
}
.kpi-falta {
  margin: 0;
  padding-left: 16px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--estado-error-tx);
}
.kpi-editor {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 24px;
  align-items: start;
}
.kpi-editor-principal { min-width: 0; }
.kpi-editor-seccion { border-bottom: var(--oecsa-borde); padding-bottom: 8px; margin-bottom: 8px; }
.kpi-editor-seccion .rejilla-campos { margin: 12px 0; }
.kpi-editor-seccion .campo-ancho { grid-column: 1 / -1; }
.kpi-editor-version {
  background: var(--estado-alerta-bg);
  border-radius: var(--oecsa-radio-card);
  padding: 4px 16px 8px;
}
.kpi-editor-lateral {
  display: grid;
  gap: 14px;
  position: sticky;
  top: 12px;
}
.kpi-editor-caja {
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio-card);
  padding: 14px 16px;
  min-width: 0;
}
.kpi-editor-caja .acciones { margin: 12px 0 0; flex-wrap: wrap; }
.kpi-editor-caja-titulo { font-size: 14px; font-weight: 600; margin: 0 0 8px; }
.kpi-editor-anterior { background: var(--oecsa-fila); }
.kpi-anterior { margin: 0; font-size: 12px; line-height: 1.45; }
.kpi-anterior dt { color: var(--oecsa-gris); margin-top: 6px; }
.kpi-anterior dd { margin: 0; overflow-wrap: anywhere; }
.kpi-versiones { margin: 0; padding: 0; list-style: none; font-size: 12px; display: grid; gap: 6px; }
.kpi-acciones-ficha { display: inline-flex; flex-wrap: wrap; gap: 4px 10px; }
.kpi-regla {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 4px 0 8px;
}
.kpi-regla-tramo {
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  padding: 4px 10px;
}
.kpi-regla-error .kpi-regla-tramo { color: var(--estado-error-tx); background: var(--estado-error-bg); }
.kpi-sigla { width: 7em; }
.kpi-orden { width: 6em; }
@media (max-width: 980px) {
  .kpi-editor { grid-template-columns: minmax(0, 1fr); }
  .kpi-editor-lateral { position: static; }
}

/* Políticas: el número de orden de un área, en su fila. */
.campo-orden { width: 6em; }

/* -----------------------------------------------------------------------------
   Notas del sistema (28/10/2026, DECISIONES 1.339)
   Los avisos de una operación salen flotando abajo a la derecha, no arriba del
   contenido: no empujan la pantalla ni tapan los botones del título. En el
   teléfono, arriba y a lo ancho, porque abajo va la barra de acciones.
   Las pinta `templates/_notas.html`; las cierra `static/js/notas.js`.
   -------------------------------------------------------------------------- */
.notas-sistema {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 70;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(380px, calc(100vw - 32px));
  pointer-events: none;
}
.nota {
  pointer-events: auto;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 24px;
  gap: 0 10px;
  align-items: start;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-left: 5px solid var(--estado-ok-tx);
  border-radius: var(--oecsa-radio-card);
  box-shadow: var(--oecsa-sombra);
  padding: 12px 10px 12px 12px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--oecsa-negro);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.nota-alerta { border-left-color: var(--estado-alerta-tx); }
.nota-error { border-left-color: var(--estado-error-tx); }
.nota-info { border-left-color: var(--estado-info-tx); }
.nota-saliendo { opacity: 0; transform: translateX(16px); }
.nota-icono {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 600;
  background: var(--estado-ok-bg);
  color: var(--estado-ok-tx);
}
.nota-alerta .nota-icono { background: var(--estado-alerta-bg); color: var(--estado-alerta-tx); }
.nota-error .nota-icono { background: var(--estado-error-bg); color: var(--estado-error-tx); }
.nota-info .nota-icono { background: var(--estado-info-bg); color: var(--estado-info-tx); }
.nota-texto { margin: 1px 0 0; overflow-wrap: anywhere; }
.nota-texto a { color: var(--oecsa-negro); }
.nota-cerrar {
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  font-size: 18px;
  line-height: 1;
  color: var(--oecsa-gris);
  padding: 0 2px;
  min-height: 24px;
}
.nota-cerrar:hover { color: var(--oecsa-negro); }
@media (max-width: 720px) {
  .notas-sistema { top: 12px; bottom: auto; left: 12px; right: 12px; width: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .nota { transition: none; }
}
@media print {
  .notas-sistema { display: none; }
}

/* -----------------------------------------------------------------------------
   Cabecera de pantalla (28/10/2026, DECISIONES 1.340)
   El título a la izquierda y sus acciones a la derecha, en un solo renglón
   que se queda pegado arriba al bajar: «Guardar» o «Nuevo» nunca quedan al
   fondo de la página. En un formulario largo, `acciones-arriba.js` trae acá
   una copia de sus botones; en el teléfono, en cambio, la barra de botones
   del formulario se pega abajo de la pantalla.
   -------------------------------------------------------------------------- */
.cabecera-pantalla {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 20px;
  margin: -10px 0 16px;
  padding: 10px 0 12px;
  background: var(--oecsa-blanco);
  border-bottom: var(--oecsa-borde);
}
[data-tema="oscuro"] .cabecera-pantalla { background: var(--tema-fondo); }
.cabecera-pantalla .oecsa-titulo { margin: 0; flex: 1 1 auto; min-width: 0; }
.cabecera-pantalla .oecsa-titulo::after { flex: 0 1 300px; min-width: 60px; }
.cabecera-pantalla .acciones { margin: 0; flex-wrap: wrap; justify-content: flex-end; }
.cabecera-pantalla .acciones-copiadas[hidden] { display: none; }
@media (max-width: 700px) {
  .cabecera-pantalla { position: static; margin-top: 0; }
  .cabecera-pantalla .oecsa-titulo::after { flex: 0 0 48px; min-width: 0; }
  .cabecera-pantalla .acciones { justify-content: flex-start; }
  .cabecera-pantalla .acciones-copiadas { display: none; }
  .acciones-pegadas {
    position: sticky;
    bottom: 0;
    z-index: 30;
    margin: 16px -14px 0;
    padding: 10px 14px;
    background: var(--oecsa-blanco);
    border-top: var(--oecsa-borde);
    box-shadow: 0 -6px 18px rgba(35, 31, 32, 0.08);
  }
  [data-tema="oscuro"] .acciones-pegadas { background: var(--tema-fondo); }
}
@media print {
  .cabecera-pantalla { position: static; border: 0; }
  .cabecera-pantalla .acciones { display: none; }
}

/* -----------------------------------------------------------------------------
   Columna «Siguiente paso» de una bandeja (DECISIONES 1.337 y 1.341)
   El botón del paso que le toca a quien mira, y el renglón que se abre debajo
   con su formulario. Pagos usa los suyos (`.pagos-paso*`); las demás apps,
   estos. Ver `static/js/bandeja-paso.js`.
   -------------------------------------------------------------------------- */
.paso-boton {
  display: inline-block;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--oecsa-verde);
  color: var(--tema-tinta-sobre-verde, var(--oecsa-negro));
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.paso-boton:hover { box-shadow: inset 0 0 0 1px var(--oecsa-negro); }
.paso-boton[aria-expanded="true"] { box-shadow: inset 0 0 0 2px var(--oecsa-negro); }
.paso-boton-sobrio {
  background: var(--oecsa-blanco);
  color: var(--oecsa-negro);
  box-shadow: inset 0 0 0 1px var(--oecsa-negro);
}
.paso-fila > td { padding-top: 0; padding-bottom: 0; }
.paso-fila > td:empty { padding: 0; border: 0; }
.paso-panel {
  margin: 4px 0 12px;
  padding: 14px 16px;
  border: var(--oecsa-borde);
  border-left: 4px solid var(--oecsa-verde);
  border-radius: 6px;
  background: var(--oecsa-blanco);
}
.paso-panel-quien { margin: 0 0 10px; }
.paso-panel-columnas {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 10px 24px;
}
.paso-panel .acciones { margin: 6px 0 0; flex-wrap: wrap; }
.paso-estados {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
  margin: 0 0 12px;
  padding: 0;
  border: 0;
}
.paso-estados legend { padding: 0; margin-bottom: 6px; }
.paso-estados label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: var(--oecsa-borde);
  border-radius: 999px;
  font-size: 12px;
  cursor: pointer;
}
.paso-estados label:has(input:checked) {
  background: var(--oecsa-verde);
  border-color: var(--oecsa-verde);
  color: var(--tema-tinta-sobre-verde, var(--oecsa-negro));
  font-weight: 500;
}
@media (pointer: coarse) {
  .paso-estados label { min-height: 42px; }
}
@media (max-width: 700px) {
  .paso-panel-columnas { grid-template-columns: 1fr; }
  /* La tabla se desplaza de lado en el teléfono; el formulario no: se queda
     a la vista, del ancho de la pantalla. */
  .paso-fila .paso-panel {
    position: sticky;
    left: 0;
    width: calc(100vw - 56px);
    box-sizing: border-box;
  }
}

/* Contadores de una bandeja en un solo renglón: se tocan para filtrar. */
.contadores {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 16px;
}
.contador {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--oecsa-fila);
  font-size: 12px;
  color: var(--estado-neutro-tx);
  text-decoration: none;
}
.contador strong { font-size: 16px; font-weight: 500; color: var(--oecsa-negro); }
a.contador:hover { box-shadow: inset 0 0 0 1px var(--oecsa-gris-medio); }
.contador-activo { background: var(--oecsa-verde); color: var(--tema-tinta-sobre-verde, var(--oecsa-negro)); }
.contador-activo strong { color: var(--tema-tinta-sobre-verde, var(--oecsa-negro)); }
.contador-alerta strong { color: var(--estado-error-tx); }

/* Legal: «Agregar a alguien» en «Quién más le da seguimiento» (DECISIONES 1.348). */
.legal-plegable { margin-top: 12px; }
.legal-plegable > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
}
.legal-plegable[open] > summary { margin-bottom: 8px; }

/* El buscador de una lista paginada, en el servidor (DECISIONES 1.353). */
.buscador-tabla-fila {
  display: flex;
  gap: 8px;
}
.buscador-tabla-fila .campo { flex: 1 1 auto; min-width: 0; }

/* Las cifras de una tabla, a la derecha y con dígitos del mismo ancho. */
.tabla th.num,
.tabla td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --- Estadísticas de SYSO (DECISIONES 1.354) ---
   Gráficas SVG del servidor (1.212). Verde de relleno para lo que cumple,
   rojo del semáforo para el hallazgo y gris para «no aplica». */
.syso-seccion { margin: 28px 0; }
.syso-subtitulo { font-size: 14px; font-weight: 600; margin: 18px 0 4px; }
.syso-grafica { display: block; width: 100%; max-width: 960px; height: auto; margin: 8px 0 16px; }
.syso-grafica-eje { stroke: var(--oecsa-gris-claro); stroke-width: 1; }
.syso-grafica-texto { fill: var(--oecsa-negro); font-size: 12px; font-family: var(--oecsa-font); }
.syso-grafica-total { fill: var(--oecsa-negro); font-size: 12px; font-weight: 600; font-family: var(--oecsa-font); }
.syso-grafica-conforme { fill: var(--oecsa-verde); }
.syso-grafica-hallazgo { fill: var(--semaforo-r); }
.syso-grafica-no-aplica { fill: var(--oecsa-gris-claro); }
.syso-grafica-linea { fill: none; stroke: var(--oecsa-negro); stroke-width: 2; }
.syso-grafica-punto { fill: var(--oecsa-verde); stroke: var(--oecsa-negro); stroke-width: 1.5; }
.syso-leyenda { list-style: none; display: flex; flex-wrap: wrap; gap: 16px; padding: 0; margin: 4px 0; font-size: 12px; }
.syso-leyenda li::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 6px;
  border-radius: 2px;
  vertical-align: -1px;
}
.syso-leyenda-conforme::before { background: var(--oecsa-verde); }
.syso-leyenda-hallazgo::before { background: var(--semaforo-r); }
.syso-leyenda-no-aplica::before { background: var(--oecsa-gris-claro); }
.syso-detalle { margin: 8px 0 0; }
.syso-detalle summary { cursor: pointer; font-size: 13px; margin-bottom: 8px; }
/* En el teléfono la gráfica no se encoge hasta no leerse ni la tabla ancha
   se corta: las dos se deslizan de lado dentro de su caja. */
.syso-desliza { overflow-x: auto; }
.tabla-marco.syso-desliza { overflow-x: auto; }
@media (max-width: 720px) {
  .syso-desliza > .syso-grafica { min-width: 640px; }
}

/* El plan de pagos (DECISIONES 1.364): la rejilla de semana × proyecto puede
   ser más ancha que la pantalla y se desliza dentro de su marco. */
.pagos-plan-marco { overflow-x: auto; margin-bottom: 18px; }

/* Varios proyectos en un filtro (DECISIONES 1.371): una lista que se
   despliega con una casilla por proyecto, encima de lo que sigue. */
.filtro-varios { position: relative; }
.filtro-varios > summary {
  display: flex;
  align-items: center;
  cursor: pointer;
  list-style: none;
  min-width: 200px;
}
.filtro-varios > summary::-webkit-details-marker { display: none; }
.filtro-varios > summary::after { content: "▾"; margin-left: auto; padding-left: 8px; }
.filtro-varios-lista {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  min-width: 280px;
  max-width: min(420px, 92vw);
  max-height: 320px;
  overflow-y: auto;
  padding: 8px 12px;
  background: var(--oecsa-blanco);
  border: var(--oecsa-borde);
  border-radius: var(--oecsa-radio);
  box-shadow: var(--oecsa-sombra);
}
.filtro-varios-lista .casilla { display: flex; gap: 8px; align-items: center; padding: 4px 0; }

