/* =========================================================================
   SANKUMA — hoja de estilos base (login, recuperación de contraseña,
   escritorio mínimo). Fuente empaquetada localmente (@font-face), no
   depende de que el navegador/sistema tenga Poppins instalada.
   ========================================================================= */

@font-face {
  font-family: 'Poppins';
  src: url("../fonts/poppins-regular.9212f6f9860f.woff2") format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Poppins';
  src: url("../fonts/poppins-medium.a09f2fccfee3.woff2") format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Poppins';
  src: url("../fonts/poppins-bold.25b0e113ca7c.woff2") format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Azul de marca, extraído del logo SANKUMA */
  --sankuma-azul: #312783;
  --sankuma-azul-hover: #251d63;

  /* Escala de grises: solo se combinan pares con contraste comprobado.
     Nunca texto sobre gris medio (--gris-400/500). */
  --gris-900: #1a1a1e;   /* texto principal sobre fondos claros */
  --gris-600: #57575f;   /* texto secundario sobre fondos claros */
  --gris-300: #d7d7dc;   /* bordes */
  --gris-100: #f4f4f6;   /* fondo de página */
  --blanco: #ffffff;

  --radio: 2px;
  --sombra: 0 4px 24px rgba(26, 26, 30, 0.08);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: 'Poppins', 'Century Gothic', 'Futura', sans-serif;
  background: var(--gris-100);
  color: var(--gris-900);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

/* Login y recuperación de contraseña (páginas con .sankuma-card):
   fondo de PÁGINA blanco, invertido respecto al resto (que sigue en
   gris-100 por defecto, ej. detrás del escritorio). */
body:has(.sankuma-card) {
  background: var(--blanco);
}

.sankuma-card {
  background: var(--gris-100);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 40px 36px;
  width: 100%;
  max-width: 380px;
}

.sankuma-logo {
  text-align: center;
  margin-bottom: 32px;
}

.sankuma-logo img {
  max-width: 220px;
  height: auto;
}

.sankuma-form label {
  display: block;
  font-weight: 500;
  font-size: 14px;
  color: var(--gris-900);
  margin-bottom: 6px;
}

.sankuma-form .campo {
  margin-bottom: 20px;
}

.sankuma-form input[type="text"],
.sankuma-form input[type="email"],
.sankuma-form input[type="password"],
.sankuma-form input[type="datetime-local"],
.sankuma-form input[type="number"],
.sankuma-form input[type="date"],
.sankuma-form select,
.sankuma-form textarea {
  width: 100%;
  padding: 12px 14px;
  font-family: inherit;
  font-size: 15px;
  color: var(--gris-900);
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  outline: none;
}

.sankuma-form textarea {
  resize: vertical;
}

.sankuma-form input:focus,
.sankuma-form select:focus,
.sankuma-form textarea:focus {
  border-color: var(--sankuma-azul);
}

/* Casilla (ej. "Fijar en el panel"): en línea con su propia etiqueta,
   no apilada como el resto de campos — .campo ya le da separación
   respecto al campo siguiente. */
.sankuma-form .campo-casilla {
  display: flex;
  align-items: center;
  gap: 8px;
}

.sankuma-form .campo-casilla label {
  margin-bottom: 0;
}

/* Fila del diálogo "Configurar indicadores" (Fase B): casilla + etiqueta
   a la izquierda, desplegable de orden empujado al extremo derecho —
   misma .campo-casilla de siempre, solo añade el hueco a la derecha. */
.sankuma-form .campo-indicador-fila {
  justify-content: space-between;
}

.sankuma-form .campo-indicador-fila select {
  width: 60px;
}

/* Lista de casillas de un ModelMultipleChoiceField (ej. "Acceso a
   módulos" al crear un usuario, Fase D3.1) — Django la renderiza como
   un <ul> con un <li><label><input>...</label></li> por opción; se
   quita el estilo de lista y cada opción se trata como una mini
   .campo-casilla (checkbox + etiqueta en línea, no apiladas). */
.sankuma-form .campo-casillas-lista ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sankuma-form .campo-casillas-lista li {
  display: flex;
  align-items: center;
  gap: 8px;
}

.sankuma-form .campo-casillas-lista li label {
  display: inline;
  margin-bottom: 0;
  font-weight: 400;
}

.sankuma-form .campo-ayuda {
  margin-top: 6px;
  margin-bottom: 0;
  font-size: 13px;
  color: var(--gris-600);
}

/* Mismo tono que .sankuma-error, pero por campo en vez de un único
   aviso arriba del formulario — para que el error quede pegado al
   campo que lo causó. */
.sankuma-form .campo-error {
  margin-top: 6px;
  font-size: 13px;
  color: #8a1f13;
}

.sankuma-boton {
  display: block;
  width: 100%;
  padding: 13px 14px;
  font-family: inherit;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.5px;
  color: var(--blanco);
  background: var(--sankuma-azul);
  border: none;
  border-radius: var(--radio);
  cursor: pointer;
  text-align: center;
  text-decoration: none;
}

.sankuma-boton:hover {
  background: var(--sankuma-azul-hover);
}

/* Acción irreversible (vaciar la papelera): mismo tono que
   .sankuma-error, pero como botón sólido en vez de aviso de texto —
   suficientemente distinto del azul para no confundirse con una
   acción normal. */
.sankuma-boton-peligro {
  background: #8a1f13;
}

.sankuma-boton-peligro:hover {
  background: #6e190f;
}

.sankuma-titulo-confirmacion {
  font-size: 20px;
  font-weight: 700;
  color: var(--gris-900);
  text-align: center;
  margin: 0 0 16px;
}

.sankuma-enlace-secundario {
  display: block;
  text-align: center;
  margin-top: 20px;
  font-size: 14px;
  color: var(--sankuma-azul);
  text-decoration: none;
}

.sankuma-enlace-secundario:hover {
  text-decoration: underline;
}

.sankuma-error {
  background: #fdeceb;
  color: #8a1f13;
  border: 1px solid #f3b9b1;
  border-radius: var(--radio);
  padding: 12px 14px;
  font-size: 14px;
  margin-bottom: 20px;
}

/* Mensajes de confirmación (django.contrib.messages) — tarea 3.11,
   primer sitio que los usa. .sankuma-mensaje-error reutiliza EXACTAMENTE
   los mismos tonos que .sankuma-error (es el mismo tipo de aviso, solo
   que llega vía messages en vez de errores de formulario);
   -success usa el mismo verde ya establecido en .prioridad-baja-suave/
   .prioridad-badge.prioridad-baja, no un tono nuevo. */
.sankuma-mensaje {
  border-radius: var(--radio);
  padding: 12px 14px;
  font-size: 14px;
  margin-bottom: 20px;
}

.sankuma-mensaje-success {
  background: #e9f5ed;
  color: #2f7a3d;
  border: 1px solid #b7ddbc;
}

.sankuma-mensaje-error {
  background: #fdeceb;
  color: #8a1f13;
  border: 1px solid #f3b9b1;
}

/* Warning (3.12): primer uso, para el aviso de "cliente creado pero
   el correo de bienvenida falló" — mismo ámbar ya establecido en
   .prioridad-media-suave/.prioridad-badge.prioridad-media, no un tono
   nuevo. */
.sankuma-mensaje-warning {
  background: #fbefdc;
  color: #9c5b00;
  border: 1px solid #f0c98a;
}

.sankuma-ayuda,
.sankuma-texto-secundario {
  color: var(--gris-600);
  font-size: 14px;
  text-align: center;
  line-height: 1.5;
}

/* =========================================================================
   Escritorio (Fase F) — layout ancho, distinto de la tarjeta estrecha de
   login/recuperación. sobrescribe {% block body %} en vez de "content".
   ========================================================================= */

body:has(.sankuma-escritorio) {
  background: var(--blanco);
  align-items: flex-start;
  padding-top: 48px;
}

.sankuma-escritorio {
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
}

.sankuma-header {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
  background: var(--sankuma-azul);
  color: var(--blanco);
  padding: 16px 24px;
  border-radius: var(--radio);
  margin-bottom: 28px;
}

/* =========================================================================
   Mi perfil (3.11) — página propia, layout ancho igual que el
   escritorio (fondo blanco, misma cabecera), pero de una sola columna
   y más estrecha: es un formulario de ajustes, no un panel con varias
   secciones lado a lado.
   ========================================================================= */

body:has(.sankuma-perfil) {
  background: var(--blanco);
  align-items: flex-start;
  padding-top: 48px;
}

.sankuma-perfil {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

.perfil-titulo {
  font-size: 22px;
  font-weight: 700;
  color: var(--gris-900);
  margin: 4px 0 20px;
}

.perfil-seccion {
  margin-bottom: 20px;
}

.perfil-valor-fijo {
  margin: 0;
  padding: 12px 14px;
  font-size: 15px;
  color: var(--gris-600);
  background: var(--gris-100);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
}

/* Izquierda: logo + nombre del cliente (o "Acceso máster..."). */
.cabecera-izquierda {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.cabecera-logo {
  display: block;
  height: 24px;
  width: auto;
}

.cabecera-cliente {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--blanco);
}

/* Centro: nombre y apellidos del usuario (+ " · Responsable" si aplica). */
.cabecera-centro {
  flex: 1 1 auto;
  text-align: center;
  font-size: 14px;
  font-weight: 500;
  color: var(--blanco);
}

/* Derecha: Avisos, Perfil, Salir. */
.cabecera-derecha {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}

.cabecera-enlace {
  color: var(--blanco);
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
}

.cabecera-enlace:hover {
  text-decoration: underline;
}

/* Avisos/Perfil (tareas 3.9 y 3.11): preparados visualmente, sin
   destino funcional todavía. Opacidad reducida para no aparentar más
   actividad de la real; el href="#" nunca da 404. */
.cabecera-enlace-pendiente {
  opacity: 0.7;
}

.cabecera-form-salir {
  margin: 0;
  display: flex;
}

.sankuma-boton-salir {
  font-family: inherit;
  font-weight: 500;
  font-size: 14px;
  color: var(--blanco);
  background: transparent;
  border: 1px solid var(--blanco);
  border-radius: var(--radio);
  padding: 9px 18px;
  cursor: pointer;
}

.sankuma-boton-salir:hover {
  background: rgba(255, 255, 255, 0.12);
}

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

/* Blancas de nuevo: "Mis aplicaciones" ahora vive dentro de su propia
   caja-gris (gris-100), así que una tarjeta también gris-100 se
   fundiría con su contenedor — el mismo problema que ya resolvimos
   una vez para las franjas, ahora reaparecido un nivel más adentro.
   Las tres se siguen distinguiendo por el color del borde y de la
   insignia de estado, igual que antes. */
.sankuma-modulo-card {
  background: var(--blanco);
  border-radius: var(--radio);
  padding: 22px 18px;
  text-align: center;
  border: 1px solid var(--gris-300);
}

.sankuma-modulo-card.activo {
  border-color: var(--sankuma-azul);
}

/* Caducada: ni azul (ya no es un acceso pleno) ni gris de "no
   contratado" (el cliente SÍ tuvo/tiene derecho a consultar). Ámbar
   sobrio, mismo patrón de contraste que .sankuma-error (texto oscuro
   sobre fondo claro del mismo tono, nunca sobre el gris intermedio). */
.sankuma-modulo-card.caducado {
  border-color: #f0c987;
}

/* No contratada / próximamente (D4.3 ampliado): borde gris — igual que
   el borde por defecto, así que ninguna de las dos necesita regla
   propia; queda documentado aquí para que se note que es una decisión,
   no un olvido. Mismo patrón visual a propósito, solo cambia el texto
   del badge (ver escritorio.html). */

.sankuma-modulo-card .nombre {
  font-weight: 700;
  font-size: 15px;
  margin-bottom: 12px;
  color: var(--gris-900);
}

/* Insignias: SIEMPRE texto oscuro/azul/ámbar sobre fondo blanco, nunca
   sobre un gris intermedio, para no arriesgar el contraste — y ahora
   son la principal seña de identidad de cada estado, junto al borde. */
.sankuma-modulo-card .estado-badge {
  display: inline-block;
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 4px 12px;
  border-radius: var(--radio);
  background: var(--blanco);
}

.sankuma-modulo-card.activo .estado-badge {
  color: var(--sankuma-azul);
  border: 1px solid var(--sankuma-azul);
}

.sankuma-modulo-card.no-contratado .estado-badge {
  color: var(--gris-600);
  border: 1px solid var(--gris-300);
}

.sankuma-modulo-card.caducado .estado-badge {
  color: #8a5a00;
  border: 1px solid #f0c987;
  background: #fdf3e0;
}

.modulo-aviso-caducado {
  margin: 8px 0 0;
  font-size: 12px;
  color: #8a5a00;
}

/* Contratado por el cliente, pero sin acceso para ESTE usuario --
   mismo tono neutro que "no contratado" (gris-600, sin insignia de
   aviso propia: no es una alerta, solo informa de por qué no hay
   enlace). */
.modulo-aviso-sin-acceso {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--gris-600);
}

.modulo-contador {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--gris-600);
}

.modulo-enlace-provisional {
  display: inline-block;
  margin-top: 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--sankuma-azul);
}

.etiqueta-provisional {
  font-weight: 400;
  opacity: 0.75;
}

.modulo-enlace-info {
  display: inline-block;
  margin-top: 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--sankuma-azul);
  text-decoration: none;
}

/* Enlace a la sección nueva de licitaIA (Fase 1, paso 1.2), JUNTO al
   provisional (.modulo-enlace-provisional), no en su lugar -- de ahí
   margin-left en vez de otro margin-top: cuando los dos están
   visibles, se quiere uno junto al otro, no uno debajo del otro. */
.modulo-enlace-nuevo {
  display: inline-block;
  margin-top: 12px;
  margin-left: 14px;
  font-size: 13px;
  font-weight: 500;
  color: var(--sankuma-azul);
  text-decoration: none;
}

.modulo-enlace-info:hover,
.modulo-enlace-provisional:hover,
.modulo-enlace-nuevo:hover {
  text-decoration: underline;
}

/* =========================================================================
   Franjas del escritorio (avisos, notas) — encima de las tarjetas de
   módulos. Mismo gris que las tarjetas de módulo (--gris-100), para
   que resalten contra el fondo BLANCO de la página (antes eran
   blancas sobre blanco, solo se notaban por el borde). Avisos y notas
   comparten el mismo tratamiento de contenedor, coherentes entre sí;
   se distinguen por el título de cada una y por el color de sus
   líneas (prioridad en avisos, amarillo fijo en notas).
   ========================================================================= */
.sankuma-franja {
  background: var(--gris-100);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 14px 18px;
  margin-bottom: 16px;
}

.franja-cabecera {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}

.franja-titulo {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--gris-600);
}

.franja-ver-todos {
  font-size: 13px;
  color: var(--sankuma-azul);
  text-decoration: none;
}

.franja-ver-todos:hover {
  text-decoration: underline;
}

/* Cada línea es un bloque redondeado con su propio fondo suave (según
   prioridad en avisos, amarillo fijo en notas) en vez de filas
   separadas por una línea divisoria — con fondos de color distintos
   entre líneas, un borde superior habría quedado raro cruzando dos
   tonos distintos. El hueco entre líneas lo da el margin-top. */
.franja-linea {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border-radius: var(--radio);
}

.franja-linea + .franja-linea {
  margin-top: 4px;
}

.franja-texto {
  font-size: 14px;
  color: var(--gris-900);
  flex: 1 1 auto;
  min-width: 0;
  word-break: break-word;
}

.franja-detalle {
  color: var(--gris-600);
  font-size: 13px;
}

/* Prioridad de avisos: fondo desaturado, la insignia de abajo aporta
   el contraste fuerte y el texto por escrito.

   DOS variantes por prioridad — no leído vs. leído — a partir del
   mismo tinte base, sin colores nuevos:
     -intenso: más saturado. Reutiliza justo los valores de una ronda
       anterior que habíamos descartado por "gritar demasiado" para un
       uso general — aquí son exactamente lo que hace falta para un
       aviso SIN LEER (contraste 1.17–1.24 contra el contenedor
       gris-100). Se usa también en la franja de arriba, que por
       definición solo enseña avisos sin leer. SIN TOCAR en este ajuste.
     -suave: apenas insinúa el tinte — mismo nivel de sutileza que el
       amarillo de notas (1.043) o un pelín menos (1.02–1.034), para
       que el salto respecto a -intenso se note de un vistazo. Se usa
       para avisos YA leídos en la bandeja, y en la ventana emergente
       (que solo se muestra después de marcar como leído).
   gris-900 en negrita (no leído) o gris-600 normal (leído) — la regla
   de peso/color del texto está más abajo — mantienen contraste alto
   de sobra en las seis combinaciones (6.3–13.46:1). */
.prioridad-alta-intenso {
  background: #f6d5d5;
}

.prioridad-media-intenso {
  background: #f7dfba;
}

.prioridad-baja-intenso {
  background: #cfe9d7;
}

.prioridad-alta-suave {
  background: #fbeeee;
}

.prioridad-media-suave {
  background: #fbefdc;
}

.prioridad-baja-suave {
  background: #e9f5ed;
}

/* Notas: amarillo, fijo para todas (Nota no tiene prioridad). El más
   discreto de los cuatro con diferencia, a propósito: apenas un tinte,
   más claro que el gris-100 del contenedor (los otros tres son más
   oscuros que el contenedor; este es más CLARO — un blanco cálido, no
   un amarillo con cuerpo). Contraste 1.043 contra gris-100, claramente
   por debajo del 1.085 del naranja de media. */
.franja-linea-nota {
  background: #fefade;
}

/* Insignia de prioridad: mismo patrón de contraste que el resto de la
   app (texto/borde de color sobre fondo BLANCO, nunca color sobre
   color) — aquí es aún más importante porque el fondo de la línea ya
   está teñido; poner la insignia también en color sobre color habría
   arriesgado el contraste. */
.prioridad-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  padding: 2px 8px;
  margin-right: 6px;
  border-radius: var(--radio);
  background: var(--blanco);
}

.prioridad-badge.prioridad-alta {
  color: #a3242c;
  border: 1px solid #f0b8bc;
}

.prioridad-badge.prioridad-media {
  color: #9c5b00;
  border: 1px solid #f0c98a;
}

.prioridad-badge.prioridad-baja {
  color: #2f7a3d;
  border: 1px solid #b7ddbc;
}

/* Licencia caducada/expirada (Fase D4.1): dos tonos nuevos, ninguno
   de los tres de arriba encajaba — no son una prioridad, son un
   periodo del ciclo de vida distinto entre sí (uno con acceso de
   solo lectura, el otro sin ninguno), así que necesitan poder
   distinguirse a simple vista sin depender solo del texto. */
.prioridad-badge.licencia-caducada {
  color: #6b21a8;
  border: 1px solid #d8b4f0;
}

.prioridad-badge.licencia-expirada {
  color: #1d4ed8;
  border: 1px solid #bfdbfe;
}

/* --- Pestaña Soporte (3.10) --- */
/* Incidencia no tiene prioridad que colorear (decisión de la tarea
   3.10) — blanca por defecto como una nota, con un tinte azul tenue
   cuando hay_novedad (respuesta de SANKUMA sin ver): la insignia de
   estado ya aporta el contraste fuerte, esto es solo la señal de
   "algo ha cambiado aquí". */
.incidencia-item {
  background: var(--blanco);
  /* Hueco preexistente: esta fila es un <a href> en el máster (Soporte
     normal y Supervisión) y ningún ancestro (.franja-linea/.hilo-abrir)
     resetea el subrayado nativo, a diferencia del resto de filas
     clicables del proyecto. En escritorio.html es un <button>, que
     nunca lo tuvo — aquí no cambia nada. */
  text-decoration: none;
}

.incidencia-item.hilo-no-leido {
  background: #eeeef9;
}

/* Reutiliza la forma de .prioridad-badge (mismo elemento, dos clases),
   con su propio color por estado: rojo "necesita atención" (mismo
   tono que prioridad-alta), naranja "en marcha" (mismo tono que
   prioridad-media), gris "ya resuelta". */
.incidencia-estado-abierta {
  color: #a3242c;
  border: 1px solid #f0b8bc;
}

.incidencia-estado-en_progreso {
  color: #9c5b00;
  border: 1px solid #f0c98a;
}

.incidencia-estado-cerrada {
  color: var(--gris-600);
  border: 1px solid var(--gris-300);
}

.franja-form-x {
  margin: 0;
  flex: 0 0 auto;
}

.franja-boton-x {
  background: transparent;
  border: none;
  color: var(--gris-600);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--radio);
}

.franja-boton-x:hover {
  background: var(--gris-100);
  color: var(--gris-900);
}

/* =========================================================================
   Estructura de dos columnas (3.9, segunda tanda): pestañas (2/3) +
   Mis aplicaciones (1/3). En pantallas estrechas pasa a una columna,
   con las pestañas primero — ya son las primeras en el HTML, así que
   solo hace falta colapsar el grid, sin reordenar nada.
   ========================================================================= */
.sankuma-dos-columnas {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 20px;
  align-items: start;
}

.columna-titulo {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--gris-600);
  margin: 0 0 10px;
}

/* Caja gris compartida por los cuatro bloques (avisos, notas, soporte,
   Mis aplicaciones) — mismo tratamiento que las franjas de arriba:
   gris-100 sobre el fondo BLANCO de la página. Dentro de esta caja,
   cada elemento va en blanco por defecto y solo se tiñe cuando tiene
   un color propio que mostrar (la prioridad del raíz de un hilo). */
.caja-gris {
  background: var(--gris-100);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 14px 18px;
}

.pestanas-nav {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--gris-300);
  margin-bottom: 16px;
}

.pestana-enlace {
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 500;
  color: var(--gris-600);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}

.pestana-enlace:hover {
  color: var(--gris-900);
}

.pestana-enlace.activa {
  color: var(--sankuma-azul);
  border-bottom-color: var(--sankuma-azul);
  font-weight: 700;
}

/* Botón de crear CON TEXTO ("+ Nuevo aviso"/"+ Nueva nota"/"+ Nueva
   incidencia") — lo primero bajo la barra de pestañas, dentro de la
   caja. Uno solo visible, el de la pestaña abierta (por eso vive
   dentro del if/elif de cada pestaña en la plantilla, no en el nav).
   Preparado visualmente (parte 2a), sin funcionalidad todavía —
   opacidad reducida y title explicativo, mismo lenguaje que los
   enlaces "pendientes" ya usados en la cabecera. */
.boton-crear {
  display: inline-block;
  margin-bottom: 14px;
  padding: 7px 14px;
  border: 1px solid var(--sankuma-azul);
  border-radius: var(--radio);
  color: var(--sankuma-azul);
  background: var(--blanco);
  text-decoration: none;
  font-size: 13px;
  font-weight: 600;
  opacity: 0.7;
}

.boton-crear:hover {
  opacity: 1;
}

/* Fila de acciones sobre la bandeja: "+ Nuevo aviso" (botón, arriba)
   junto a Archivados/Papelera (enlaces de texto, menor peso — no son
   la acción principal de la pantalla). */
.avisos-acciones-cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-bottom: 14px;
}

.avisos-vista-enlace {
  font-size: 13px;
  color: var(--gris-600);
  text-decoration: none;
}

.avisos-vista-enlace:hover {
  color: var(--gris-900);
  text-decoration: underline;
}

.avisos-vista-enlace.activa {
  color: var(--sankuma-azul);
  font-weight: 600;
}

.avisos-vaciar-papelera {
  color: #8a1f13;
}

/* Fase 2a de Supervisión — cuando .avisos-acciones-cabecera vive DENTRO
   de .master-ficha-bloque-cabecera (la fila título+acciones), su propio
   margin-bottom:14px (pensado para separarla del listado cuando es una
   fila suelta) descentra el grupo de enlaces: el margen cuenta como
   alto del hijo flex, así que align-items:center lo deja pegado arriba
   de la fila en vez de centrado con el título. Aquí no hace falta ese
   margen — el espaciado con el cuerpo ya lo da
   .master-ficha-bloque-cabecera. Selector específico: solo afecta a
   este anidamiento, no a los usos sueltos de la misma clase dentro de
   .master-caja-cuerpo (el selector Ver:, el selector de agente de
   Supervisión, etc.), que sí necesitan su margen normal. */
.master-ficha-bloque-cabecera .avisos-acciones-cabecera {
  margin-bottom: 0;
}

/* Título + "Supervisión" agrupados a la izquierda de la cabecera
   (Fase 2a), en la misma línea y a la misma altura que el título —
   mismo align-items:center que .avisos-acciones-cabecera, sin su
   margin-bottom (no hace falta: solo agrupa dos elementos ya alineados
   por la fila padre). */
.master-caja-titulo-grupo {
  display: flex;
  align-items: center;
  gap: 12px;
}

.avisos-volver-bandeja {
  display: inline-block;
  margin-bottom: 12px;
  font-size: 13px;
  color: var(--sankuma-azul);
  text-decoration: none;
}

.avisos-volver-bandeja:hover {
  text-decoration: underline;
}

/* Acciones dentro de la ventana emergente (archivar/borrar o
   desarchivar/restaurar, según el estado actual del hilo). Aquí y no
   como botón suelto en cada fila de la bandeja: la fila ya es un
   <button> entero para abrir el hilo. */
.dialogo-acciones {
  display: flex;
  gap: 10px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--gris-300);
}

/* text-decoration/display: la mayoría de estos botones son <button>
   dentro de un <form> (archivar/borrar de un aviso), pero "Borrar
   nota" es un <a href> a la página de confirmación (no un POST
   directo) — el mismo reset que ya lleva .sankuma-boton para poder
   usarse indistintamente como botón o como enlace. */
.dialogo-boton-secundario {
  display: inline-block;
  padding: 7px 14px;
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  background: var(--blanco);
  color: var(--gris-900);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.dialogo-boton-secundario:hover {
  background: var(--gris-100);
}

.dialogo-boton-peligro {
  border-color: #f3b9b1;
  color: #8a1f13;
}

.dialogo-boton-peligro:hover {
  background: #fdeceb;
}

/* --- Pestaña Avisos: bandeja completa (leídos y no leídos mezclados) --- */
.hilo-item {
  margin-bottom: 10px;
}

/* Bug de maquetación DE RAÍZ (ya salió dos veces en sitios distintos:
   la bandeja y la ventana emergente — de ahí esta clase compartida en
   vez de otro parche por ubicación).

   Cuando franja-texto/hilo-contexto comparten fila flex con VARIOS
   metadatos hermanos (insignia, remitente, fecha, acuse...) y alguno
   es largo (un remitente = email + cliente, por ejemplo), sin
   flex-wrap el navegador exprime el texto a un ancho casi nulo y lo
   parte letra a letra (min-width:0 permite encogerse, pero nada le
   daba una línea propia). En la franja de arriba esto NO pasa porque
   la insignia va ANIDADA dentro de franja-texto, no al lado — es la
   única fila de mensaje que no necesita esta clase.

   Cualquier fila NUEVA que combine texto de mensaje + metadatos como
   hermanos flex debe llevar esta clase — no reinventar el arreglo por
   ubicación cada vez. */
.fila-con-metadatos {
  flex-wrap: wrap;
}

.fila-con-metadatos .franja-texto,
.fila-con-metadatos .hilo-contexto {
  flex-basis: 100%;
  min-width: 0;
}

/* La fila raíz es un <button> real (dentro de un <form method="post">)
   para abrir la ventana emergente — pinchar el aviso escribe (marca
   como leído), nunca puede ser un <a href>. Reset de los estilos
   nativos de <button> para que siga siendo visualmente idéntica a la
   fila de antes; el resto (fondo, borde, tipografía) ya lo pone
   .franja-linea/.prioridad-X, que se siguen aplicando igual. */
.hilo-abrir {
  border: none;
  margin: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.hilo-abrir:hover {
  filter: brightness(0.98);
}

/* Fase 1b (ajustes de la bandeja de Avisos del máster): un <button>
   con display:flex no se estira a lo ancho de su contenedor igual que
   un <div> — se encoge al contenido salvo que algo lo fuerce. En
   escritorio.html (lado usuario) nunca hizo falta forzarlo porque su
   propio layout ya lo resuelve; aquí sí. Scoped a .master-caja-avisos
   (clase exclusiva del panel máster, no existe en escritorio.html) en
   vez de tocar .hilo-abrir directamente, para no alterar en nada el
   lado usuario. */
.master-caja-avisos .hilo-abrir {
  width: 100%;
}

/* Fase 1b (ajustes): un aviso ENVIADO por el propio usuario no tiene
   estado de lectura que mostrar (si lo escribió él, ya está "leído"
   por definición) — fondo blanco fijo, sin negrita, el badge de
   prioridad (elemento aparte) sigue con su color de siempre. Scoped a
   .master-caja-avisos por el mismo motivo que la regla de ancho de
   arriba: esta distinción enviado/recibido no existe en
   escritorio.html. */
.master-caja-avisos .hilo-abrir.avisos-enviado-propio {
  background: var(--blanco);
}

.hilo-remitente {
  font-size: 13px;
  font-weight: 600;
  color: var(--gris-600);
}

.hilo-fecha {
  font-size: 12px;
  color: var(--gris-600);
  flex: 0 0 auto;
}

.hilo-acuse {
  font-size: 12px;
  color: var(--gris-600);
  flex: 0 0 auto;
}

/* Línea de contexto ("licitaIA · Expediente 3291/2026 · Punto 5"):
   menor jerarquía que el mensaje — más pequeña, sin negrita nunca
   (ni siquiera en un hilo no leído, a propósito: es información de
   apoyo, no el contenido en sí). Su propia línea (flex-basis: 100%
   arriba), justo debajo del mensaje. */
.hilo-contexto {
  display: block;
  font-size: 12px;
  color: var(--gris-600);
}

/* Leído: peso normal, contraste reducido. No leído (hilo-no-leido,
   aplicada junto a franja-linea o a hilo-respuesta): negrita y
   contraste alto — la comprobación es sobre CADA mensaje individual,
   no sobre el hilo entero. Todo esto va con el prefijo ".hilo-item"
   para no afectar a la franja de arriba (que reutiliza las mismas
   clases franja-linea/franja-texto pero solo enseña avisos sin leer,
   así que no necesita esta distinción y su estilo debe quedar tal
   como estaba). */
.hilo-item .franja-linea .franja-texto,
.hilo-item .hilo-respuesta .franja-texto {
  font-weight: 400;
  color: var(--gris-600);
}

.hilo-item .hilo-no-leido .franja-texto {
  font-weight: 700;
  color: var(--gris-900);
}

.hilo-respuestas {
  margin: 8px 0 0 16px;
  padding-left: 12px;
  border-left: 2px solid var(--gris-300);
}

.hilo-respuestas summary {
  font-size: 12px;
  color: var(--gris-600);
  cursor: pointer;
  margin-bottom: 6px;
}

/* Sin color propio (el color del hilo lo marca solo el raíz, nunca
   una respuesta) — blanca dentro de la caja gris, como pedido. */
.hilo-respuesta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  background: var(--blanco);
  border-radius: var(--radio);
  padding: 6px 10px;
}

.hilo-respuesta + .hilo-respuesta {
  margin-top: 4px;
}

/* --- Pestaña Notas --- */
/* Nota no tiene un atributo tipo "prioridad" que colorear — siempre
   blanca dentro de la caja gris, como el resto de líneas "sin color".
   Es un <a href> (abrir una nota no escribe nada, a diferencia de un
   aviso), así que hacen falta el reset de subrayado/color heredado y
   un cursor/hover que la sigan mostrando como una fila pinchable —
   mismo tratamiento que .hilo-abrir, adaptado a enlace en vez de
   botón. */
.nota-item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  background: var(--blanco);
  border-radius: var(--radio);
  padding: 8px 10px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}

.nota-item:hover {
  filter: brightness(0.98);
}

.nota-item + .nota-item {
  margin-top: 4px;
}

.nota-estado {
  font-size: 12px;
  color: var(--gris-600);
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Cabecera del escritorio en móvil: los 3 bloques (izquierda/centro/
   derecha) se apilan en vertical y se centran, en vez de intentar
   mantener las 3 columnas de escritorio en un ancho que no les cabe. */
@media (max-width: 640px) {
  .sankuma-header {
    flex-direction: column;
    align-items: stretch;
    text-align: center;
  }

  .cabecera-izquierda,
  .cabecera-derecha {
    justify-content: center;
  }

  .cabecera-centro {
    order: 2;
  }
}

/* Dos columnas -> una sola en pantallas estrechas. Umbral algo mayor
   que el de la cabecera: con 2/3 + 1/3 el punto en el que se sienten
   apretadas llega antes que con la cabecera (3 bloques flexibles). */
/* Altura máxima del listado (avisos: bandeja, Archivados y Papelera
   comparten esta misma clase; notas) con su propio scroll — SOLO el
   listado, no la caja entera: nav, botón de crear y enlaces de
   Archivados/Papelera quedan fuera de este div (ver la plantilla), así
   que se quedan fijos y visibles al desplazar. ~600px es "generosa" a
   propósito: unas 3-4 tarjetas de Mis aplicaciones (≈150px cada una
   con su gap) caben a su lado, para que las dos columnas queden más o
   menos igualadas por abajo. min() con vh evita que sea excesiva en
   una ventana baja. overflow-x:hidden, por si acaso: no debe aparecer
   ningún desplazamiento horizontal aquí, solo vertical.

   Va ANTES de la media query de abajo a propósito: con la misma
   especificidad, la regla que aparece más tarde en la hoja gana, así
   que la excepción de móvil (que quita el límite) tiene que venir
   DESPUÉS de esta para poder anularla — si el orden fuera al revés,
   esta regla ganaría siempre y la excepción no haría nada. */
.lista-con-scroll {
  max-height: min(600px, 65vh);
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 4px;
}

@media (max-width: 780px) {
  .sankuma-dos-columnas {
    grid-template-columns: 1fr;
  }

  /* En una sola columna, el límite de altura estorba más que ayuda
     (nadie necesita "alinear" nada con Mis aplicaciones si ya no
     están lado a lado, y un scroll interno dentro del scroll de la
     página es una experiencia rara en móvil) — se quita del todo. */
  .lista-con-scroll {
    max-height: none;
    overflow-y: visible;
  }
}

/* =========================================================================
   Ventana emergente de un hilo (3.9, parte 2b) — <dialog> nativo.
   ========================================================================= */
.dialogo-hilo {
  width: min(600px, 92vw);
  max-height: min(80vh, 720px);
  margin: auto;
  padding: 0;
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  font-family: 'Poppins', 'Century Gothic', 'Futura', sans-serif;
}

.dialogo-hilo::backdrop {
  background: rgba(26, 26, 30, 0.5);
}

.dialogo-cerrar-form {
  display: flex;
  justify-content: flex-end;
  margin: 0;
  padding: 8px 12px 0;
}

.dialogo-cerrar {
  background: transparent;
  border: none;
  color: var(--gris-600);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--radio);
}

.dialogo-cerrar:hover {
  background: var(--gris-100);
  color: var(--gris-900);
}

.dialogo-contenido {
  padding: 4px 20px 20px;
  overflow-y: auto;
  max-height: calc(min(80vh, 720px) - 44px);
}

.dialogo-contenido .franja-linea,
.dialogo-contenido .hilo-respuesta {
  margin-bottom: 8px;
}

/* Diálogos de crear aviso/nota (3.9, parte 2c): reutilizan
   .dialogo-hilo/.dialogo-contenido/.dialogo-cerrar-form enteros (misma
   ventana, mismo cierre), solo añaden un título y, en el caso de la
   nota, el aviso de privacidad. */
.dialogo-titulo {
  margin: 4px 0 16px;
  font-size: 18px;
  font-weight: 700;
  color: var(--gris-900);
}

.dialogo-nota-privada {
  margin: -8px 0 20px;
  font-size: 13px;
  color: var(--gris-600);
}

/* Diálogo de crear cliente (3.12, Fase C): primer diálogo con dos
   grupos de campos distintos dentro del mismo formulario (datos del
   cliente / primer usuario responsable) — .dialogo-subtitulo los
   separa visualmente sin ser tan grande como .dialogo-titulo. */
.dialogo-subtitulo {
  margin: 24px 0 4px;
  font-size: 14px;
  font-weight: 700;
  color: var(--gris-900);
}

.dialogo-subtitulo:first-of-type {
  margin-top: 4px;
}

/* Aviso de "esta nota está en la papelera" dentro de su ventana: tono
   ámbar (ni el rojo de .sankuma-error, que sugeriría que algo ha ido
   mal, ni gris neutro, que pasaría desapercibido) — se puede seguir
   editando con normalidad, pero hay que dejar claro que, hasta que se
   restaure, no aparecerá en ningún otro sitio. */
.dialogo-aviso-papelera {
  background: #fdf6ec;
  color: #7a5b0f;
  border: 1px solid #f0dfb4;
  border-radius: var(--radio);
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  margin: -8px 0 20px;
}

.dialogo-sin-respuesta {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-300);
  font-size: 13px;
  color: var(--gris-600);
}

.dialogo-form-responder {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-300);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.dialogo-form-responder textarea {
  width: 100%;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 14px;
  color: var(--gris-900);
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  resize: vertical;
}

.dialogo-form-responder textarea:focus {
  outline: none;
  border-color: var(--sankuma-azul);
}

/* Móvil: la ventana ocupa casi todo el ancho (92vw ya cubre esto,
   pero se reduce el margen lateral efectivo aún más) y el contenido
   sigue con scroll propio en vez de desbordar la pantalla. */
@media (max-width: 640px) {
  .dialogo-hilo {
    width: 96vw;
    max-height: 90vh;
  }

  .dialogo-contenido {
    max-height: calc(90vh - 44px);
  }
}

/* =========================================================================
   Panel máster (3.12, rehecho como panel ÚNICO) — marca visual
   INVERTIDA a propósito: fondo azul SANKUMA, cabecera BLANCA con el
   logo azul (no la versión blanca del símbolo, que aquí no se vería).
   Para que de un vistazo se distinga sin ninguna duda del panel de
   usuario (blanco) — nunca confundir en qué lado se está.

   .caja-gris se reutiliza TAL CUAL dentro de este panel, sin ninguna
   variante nueva: gris-100 sobre azul saturado ya tiene contraste de
   sobra por sí solo (una caja clara flotando sobre un fondo oscuro),
   no hace falta tocarla.
   ========================================================================= */

body:has(.master-layout) {
  background: var(--sankuma-azul);
  align-items: flex-start;
  padding-top: 32px;
}

/* Ancho PROPIO del panel máster, más amplio que el resto del portal
   (960px) — tiene su propia hoja de estilos invertida y sus tablas
   (clientes, usuarios de la ficha) necesitan más sitio del que cabía
   sin scroll horizontal. Escrito aquí, en un único punto: todo lo
   demás dentro de .master-layout (cabecera, indicadores, cajas,
   ficha) usa ancho relativo/flex/grid, así que crece con este valor
   sin tocar nada más. El scroll horizontal de .master-tabla-scroll
   sigue existiendo como red de seguridad en pantallas estrechas. */
.master-layout {
  width: 100%;
  max-width: 1320px;
  margin: 0 auto;
}

.master-header {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  background: var(--blanco);
  padding: 16px 24px;
  border-radius: var(--radio);
  margin-bottom: 28px;
}

/* Izquierda/derecha con el mismo flex-basis (0, crecen igual) para
   que el nombre del centro quede REALMENTE centrado en la cabecera,
   no solo "entre los otros dos" — con justify-content: space-between
   a secas, un lado más ancho que el otro descentra visualmente el
   texto de en medio. */
.master-header-izquierda,
.master-header-derecha {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1 1 0;
}

.master-header-derecha {
  justify-content: flex-end;
}

.master-header-logo {
  height: 28px;
  width: auto;
}

/* Nivel de acceso (Máster/Agente/...) junto al logo — ver
   Usuario.nivel_panel_master, extensible a más niveles sin tocar esta
   regla: es solo texto, el mismo estilo sirve para cualquier etiqueta
   que llegue. */
.master-header-nivel {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--sankuma-azul);
  background: var(--gris-100);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 3px 8px;
}

.master-header-centro {
  flex: 1 1 0;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  color: var(--gris-900);
}

.master-header-enlace {
  color: var(--sankuma-azul);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
}

.master-header-enlace:hover {
  text-decoration: underline;
}

.master-header-form-salir {
  margin: 0;
}

.master-boton-salir {
  background: transparent;
  border: 1px solid var(--sankuma-azul);
  color: var(--sankuma-azul);
  padding: 6px 14px;
  border-radius: var(--radio);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.master-boton-salir:hover {
  background: var(--sankuma-azul);
  color: var(--blanco);
}

/* --- Franja de indicadores: caja con cabecera propia (Fase B — antes
   no tenía título ni botón), igual que el resto de cajas del panel. */
.master-caja-indicadores {
  margin-bottom: 20px;
}

/* Cada indicador un COMPARTIMENTO igual — número grande arriba,
   etiqueta debajo, centrado. Grid (no flex + flex:1) a propósito: con
   auto-fit + minmax, todas las columnas de una fila miden EXACTAMENTE
   lo mismo Y se mantienen alineadas entre filas cuando envuelve en
   pantallas estrechas — mismo patrón ya usado en .master-ficha-datos,
   aquí con una columna mínima más estrecha porque el contenido es solo
   un número y una etiqueta corta. Sin separadores de texto entre
   columnas: el espaciado es el gap del grid. */
.master-indicadores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  align-items: start;
  gap: 16px;
}

.master-indicador {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-decoration: none;
  text-align: center;
}

.master-indicador-clicable {
  cursor: pointer;
  border-radius: var(--radio);
}

.master-indicador-clicable:hover {
  filter: brightness(0.98);
}

.master-indicador-valor {
  font-size: 28px;
  font-weight: 700;
  color: var(--sankuma-azul);
  line-height: 1.1;
}

.master-indicador-etiqueta {
  font-size: 13px;
  font-weight: 600;
  color: var(--gris-600);
  text-align: center;
}

.master-indicador-nota {
  font-size: 11px;
  color: var(--gris-600);
}

/* --- Caja Clientes (central, la más grande) --- */
.master-caja-clientes {
  margin-bottom: 20px;
}

/* flex-end, no space-between: ahora solo tiene un hijo (el buscador +
   botón), sin título a la izquierda que equilibrar — todo el bloque
   va pegado a la esquina superior derecha de la caja. */
/* space-between con dos hijos directos (buscador, botón): cada uno a
   un extremo — buscador pegado a la izquierda, "+ Cliente nuevo"
   pegado a la derecha. Con un único hijo (sin el botón, agente sin
   permiso de crear), ese hijo se queda a la izquierda igualmente. */
.master-caja-cabecera {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.master-caja-titulo {
  font-size: 16px;
  font-weight: 700;
  color: var(--gris-900);
  margin: 0;
}

/* font-family/border/cursor explícitos (causa de raíz, 12/09/2026):
   esta clase nació para usarse solo en <a> ("+ Nuevo módulo",
   "Editar"...), que no traen tipografía ni borde por defecto del
   navegador -- así que nunca hizo falta resetearlos aquí. Al aplicarla
   por primera vez a un <button> real ("Consultar cambio BCE", "Filtrar"
   en Prompts de IA), sí se notó: un <button> SÍ trae su propia fuente
   de sistema y un borde por defecto si no se anulan explícitamente
   (a diferencia de un <a>). Mismo criterio que ya siguen
   .sankuma-boton/.licitaia-boton-contorno/.master-boton-como-enlace,
   que sí se diseñaron desde el principio para <button>. */
.master-boton-secundario {
  display: inline-block;
  background: var(--sankuma-azul);
  color: var(--blanco);
  text-decoration: none;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  padding: 8px 16px;
  border: none;
  border-radius: var(--radio);
  cursor: pointer;
}

.master-boton-secundario:hover {
  background: var(--sankuma-azul-hover);
}

/* --- Fila Soporte (alta, izquierda) + Avisos/Notas apiladas (derecha,
   más pequeñas) --- */
.master-fila-soporte {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 20px;
}

/* Altura de referencia FIJA (no min-height): junto con la misma
   altura en .master-columna-avisos-notas, deja las dos columnas de
   .master-fila-soporte alineadas arriba Y abajo. display:flex aquí
   separa cabecera (fija) de .master-caja-cuerpo (el listado, con su
   propio scroll) — ver más abajo. */
.master-caja-soporte {
  display: flex;
  flex-direction: column;
  height: 570px;
  /* Sin esto, el min-height:auto implícito de los grid items deja que
     el contenido de dentro empuje la altura por encima de 570px —
     y como .master-fila-soporte es un grid, la FILA entera crece con
     ella, arrastrando también a la columna de al lado. */
  min-height: 0;
}

/* Cerradas plegadas (Fase 1, caja Soporte) — <details> nativo, sin
   JS: solo un poco de aire respecto a las activas y al summary. */
.master-soporte-cerradas {
  margin-top: 12px;
}

.master-soporte-cerradas summary {
  cursor: pointer;
  font-size: 14px;
  color: var(--gris-600);
  margin-bottom: 8px;
}

/* gap: 16px — a propósito el MISMO valor que el gap de
   .master-fila-soporte (no lo toques por separado si cambia el de
   arriba): es lo que hace que Avisos+Notas apiladas terminen
   alineadas abajo con Soporte. height: 570px — misma altura de
   referencia que .master-caja-soporte, para que ambas columnas
   queden igual de altas. */
.master-columna-avisos-notas {
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 570px;
  /* Mismo motivo que .master-caja-soporte: sin esto, el min-height
     automático de los grid items deja que Avisos empuje esta columna
     (y con ella toda la fila del grid) por encima de 570px. */
  min-height: 0;
}

.master-caja {
  display: flex;
  flex-direction: column;
  min-height: 134px;
  margin-bottom: 20px;
}

/* Dentro de master-fila-soporte/master-columna-avisos-notas el
   espaciado ya lo dan sus propios gap — el margin-bottom de arriba es
   solo para cuando .master-caja aparece SUELTA (ej. Avisos/Notas
   apiladas a ancho completo si no hay permiso de Soporte). */
.master-fila-soporte .master-caja,
.master-columna-avisos-notas .master-caja {
  margin-bottom: 0;
}

/* Cabecera (título + botones/enlaces) siempre fuera de esto y por
   tanto siempre fija — el CUERPO (el listado) es lo único que hace
   scroll. Mismo espíritu que .lista-con-scroll del panel de usuario,
   en flex porque aquí la altura del cuerpo la da el reparto 2.5/1.5
   de más abajo, no un max-height suelto. */
.master-caja-cuerpo {
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}

/* Altura fija propia — caso "sin Soporte" (Avisos/Notas a ancho
   completo, cada una independiente, nada con qué alinearse). Mismo
   ratio 2.5:1.5 (5:3) que el reparto de abajo, escalado a la misma
   altura de referencia (570px) que .master-caja-soporte/
   .master-columna-avisos-notas, en números redondos. */
.master-caja-avisos {
  height: 525px;
}
.master-caja-notas {
  height: 315px;
}

/* Dentro de la columna junto a Soporte: el reparto real es
   proporcional (2.5/1.5) sobre la altura de referencia ya fijada por
   .master-columna-avisos-notas — más específico que la regla de
   arriba, así que gana aquí. min-height:0 anula el suelo genérico de
   134px de .master-caja: aquí manda flex-grow, no un mínimo fijo. */
.master-columna-avisos-notas .master-caja-avisos {
  height: auto;
  flex: 2.5 1 0;
  min-height: 0;
}
.master-columna-avisos-notas .master-caja-notas {
  height: auto;
  flex: 1.5 1 0;
  min-height: 0;
}

/* Ancho completo, separada del resto a propósito — ver el comentario
   en index.html: así el panel de un agente es "el mismo quitando esta
   caja", nunca un hueco raro en medio de una fila. */
.master-caja-equipo {
  margin-top: 8px;
}

/* Mismo motivo que .master-caja-equipo: ancho completo, separada del
   resto (D4.3). */
.master-caja-modulos {
  margin-top: 8px;
}

.master-proximamente {
  color: var(--gris-600);
  font-size: 14px;
  margin: 0;
}

/* --- Buscador + tabla de clientes (pieza 2) --- */
.master-buscador {
  margin: 0;
}

.master-buscador-input {
  padding: 8px 12px;
  font-family: inherit;
  font-size: 14px;
  color: var(--gris-900);
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  outline: none;
  min-width: 200px;
}

.master-buscador-input:focus {
  border-color: var(--sankuma-azul);
}

/* Scroll horizontal PROPIO de la tabla (nunca el body entero) en
   pantallas estrechas — mismo criterio que .lista-con-scroll en el
   panel de usuario, adaptado a horizontal en vez de vertical. */
.master-tabla-scroll {
  overflow-x: auto;
}

.master-tabla {
  width: 100%;
  border-collapse: collapse;
  background: var(--blanco);
  border-radius: var(--radio);
  overflow: hidden;
}

.master-tabla th,
.master-tabla td {
  padding: 10px 12px;
  text-align: left;
  font-size: 13px;
  white-space: nowrap;
  border-bottom: 1px solid var(--gris-300);
  /* top, no el "middle" por defecto de las celdas: "Expedientes" mide
     dos líneas (su aclaración debajo) y las demás cabeceras solo una
     — con vertical-align:top, la PRIMERA línea de todas queda a la
     misma altura y la aclaración cuelga por debajo sin descolocar la
     fila; con "middle" (el valor por defecto), la cabecera de dos
     líneas empuja su propio texto más arriba que las de una sola. */
  vertical-align: top;
}

.master-tabla th {
  font-weight: 700;
  color: var(--gris-900);
  background: var(--gris-100);
}

.master-tabla th a {
  color: var(--gris-900);
  text-decoration: none;
}

.master-tabla th a:hover {
  color: var(--sankuma-azul);
  text-decoration: underline;
}

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

.master-tabla tbody tr:hover {
  background: var(--gris-100);
}

.master-tabla-pendiente {
  color: var(--gris-600);
  font-style: italic;
}

/* Selector compuesto (.master-tabla th/td + .master-tabla-centro), no
   .master-tabla-centro sola: la regla base ".master-tabla th, .master-tabla
   td" (arriba) tiene MÁS especificidad que una clase suelta (dos
   selectores encadenados frente a uno), así que una clase sola nunca
   le habría ganado — por eso los números no se centraban aunque la
   clase ya estaba puesta. */
.master-tabla th.master-tabla-centro,
.master-tabla td.master-tabla-centro {
  text-align: center;
}

.master-tabla th.master-tabla-centro a {
  display: block;
}

/* Segunda línea de la cabecera "Expedientes" ("en curso / cerrados")
   — el elemento de MENOR peso visual de toda la cabecera: sin
   negrita, más pequeña y más tenue que el resto (que hereda 13px en
   gris-900 desde .master-tabla th). */
.master-tabla-subcabecera {
  display: block;
  font-weight: 400;
  font-size: 10px;
  color: var(--gris-600);
}

/* --- Ficha desplegable de cliente (Fase D, D1) --- */
.master-enlace-cliente {
  color: var(--gris-900);
  text-decoration: none;
  font-weight: 600;
}

.master-enlace-cliente:hover {
  color: var(--sankuma-azul);
  text-decoration: underline;
}

.master-ficha-flecha {
  display: inline-block;
  width: 10px;
  color: var(--gris-600);
}

/* Fondo distinto para saber de un vistazo qué fila está desplegada,
   incluso con el scroll bajado y la cabecera fuera de vista. */
.master-fila-cliente-abierta td {
  background: var(--gris-100);
}

/* La fila de la ficha no es una fila de datos normal (es una única
   celda colspan) — sin el hover gris de .master-tabla tbody tr:hover,
   que no pinta nada aquí y solo confundiría. */
.master-fila-ficha:hover {
  background: none;
}

/* > td, no "td" a secas: esta regla es solo para el <td colspan>
   envoltorio de la ficha (índice.html). Un selector descendiente
   alcanzaría también los <td> de cualquier tabla anidada dentro de
   la ficha (con la misma especificidad que ".master-tabla td" pero
   apareciendo más abajo en el archivo, así que ganaría) y les
   robaría el padding — como le pasó a la tabla de licencias, que no
   tenía (a diferencia de la de usuarios) una clase propia con más
   especificidad que la protegiera. */
.master-fila-ficha > td {
  white-space: normal;
  padding: 0;
  border-bottom: 1px solid var(--gris-300);
}

.master-ficha {
  margin: 10px;
}

.master-ficha-cabecera {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 14px;
}

.master-ficha-titulo {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: var(--gris-900);
}

.master-ficha-cerrar {
  color: var(--gris-600);
  font-size: 13px;
  text-decoration: none;
}

.master-ficha-cerrar:hover {
  color: var(--sankuma-azul);
  text-decoration: underline;
}

/* Enlace de acción por fila dentro de una tabla anidada de la ficha
   (ej. "Editar" en Usuarios del cliente, D3.2) — deliberadamente más
   discreto que .master-boton-secundario: son muchas filas, un botón
   con fondo de color en cada una sería demasiado ruido visual. */
.master-enlace-accion {
  color: var(--sankuma-azul);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}

.master-enlace-accion:hover {
  text-decoration: underline;
}

/* El interruptor de rol (Fase D3.3) es un <button> dentro de un
   <form>, no un <a> — sin este reset arrastraría el fondo/borde/
   padding por defecto del navegador y no se vería como el resto de
   enlaces de acción de la tabla. */
.master-boton-como-enlace {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font-family: inherit;
  cursor: pointer;
}

/* El <form> del interruptor de rol vive DENTRO de una celda de
   tabla — sin esto se comporta como bloque y añade un salto de línea
   que no pinta nada en una celda de una sola palabra. */
.master-form-en-linea {
  display: inline;
  margin: 0;
}

/* Tres acciones apiladas por fila (Fase D3.5: Editar · Desactivar/
   Activar · Borrar) — una por línea, centradas, con un gap pequeño
   entre ellas. Va en un <div> DENTRO del <td> (que solo lleva
   master-tabla-centro), nunca en el propio <td>: un <td> con
   display:flex deja de comportarse como celda de tabla (dixit CSS
   Display) y ya no se estira para igualar la altura de la fila —
   en una fila con una celda de al lado más alta (ej. muchos permisos
   en Equipo SANKUMA), esta celda se quedaba corta y su borde inferior
   no cuadraba con el resto de la fila. */
.master-acciones-usuario {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

/* Mismo tono que .prioridad-badge.prioridad-alta — reutiliza el rojo
   ya establecido en la paleta en vez de inventar uno nuevo, para
   "Borrar" (la única acción irreversible de la fila). */
.master-enlace-accion-peligro {
  color: #a3242c;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}

.master-enlace-accion-peligro:hover {
  text-decoration: underline;
}

/* Mismo tono que .incidencia-estado-cerrada (gris-600) — para acciones
   NO destructivas que no deben leerse en rojo, ej. "Cancelar" un
   aviso programado (Fase 1a de la bandeja de Avisos del máster): que
   el botón haga juego con el badge gris "Cancelado" que aparece al
   lado, en vez de parecer una acción peligrosa. */
.master-enlace-accion-neutro {
  color: var(--gris-600);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}

.master-enlace-accion-neutro:hover {
  text-decoration: underline;
}

/* Usuario desactivado (Fase D3.5): fila entera atenuada para
   distinguirla de un vistazo, sin gastar una columna aparte — se
   suma sin conflicto a .master-fila-responsable (negrita) si un
   responsable se desactiva, cada regla toca una propiedad distinta. */
.master-fila-inactiva td {
  opacity: 0.55;
}

.master-etiqueta-inactivo {
  margin-left: 4px;
  font-size: 11px;
  font-style: italic;
  font-weight: 400;
  color: var(--gris-600);
}

/* Fase D4.2: campo visible pero no editable (modo restringido de
   "Editar acceso", o casillas de módulos de un responsable) — misma
   opacidad que .master-fila-inactiva, para que el idioma visual de
   "esto está bloqueado" sea el mismo en todo el panel. */
.master-campo-bloqueado {
  opacity: 0.55;
}

.master-ficha-bloque {
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 14px 16px;
  margin-bottom: 12px;
}

.master-ficha-bloque:last-child {
  margin-bottom: 0;
}

.master-ficha-bloque-cabecera {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.master-ficha-bloque-titulo {
  margin: 0 0 10px;
  font-size: 14px;
  font-weight: 700;
  color: var(--gris-900);
}

.master-ficha-bloque-cabecera .master-ficha-bloque-titulo {
  margin-bottom: 0;
}

.master-boton-pequeno {
  padding: 4px 10px;
  font-size: 12px;
}

.master-ficha-datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px 20px;
}

.master-ficha-dato {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.master-ficha-dato-etiqueta {
  font-size: 11px;
  font-weight: 600;
  color: var(--gris-600);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

.master-ficha-dato-valor {
  font-size: 14px;
  color: var(--gris-900);
}

/* Tabla de usuarios de la ficha (Fase D3, ajuste visual): anchos fijos
   vía colgroup en vez de dejar que el navegador los reparta solo por
   contenido de celda — con auto, "Expedientes" (siempre corto, "0/0")
   salía enorme y Nombre/Email (el texto más largo) quedaban
   apretados. table-layout:fixed hace que colgroup mande de verdad, y
   white-space:normal (contra el nowrap de .master-tabla base) permite
   que Código/Rol/Expedientes envuelvan su texto corto sin forzar la
   columna a ensancharse. */
.master-tabla-usuarios {
  table-layout: fixed;
}

.master-tabla-usuarios th,
.master-tabla-usuarios td {
  white-space: normal;
  /* white-space:normal por sí solo SOLO envuelve en espacios — un
     email ("nuevo.responsable.d3@example.com") no tiene ninguno, así
     que sin esto se queda como una única "palabra" que desborda su
     celda y se monta visualmente sobre la columna vecina (el bug
     reportado), por ancho que le demos en el colgroup. word-break
     fuerza el corte DENTRO de la palabra si hace falta, así ninguna
     celda invade nunca a la de al lado, sea cual sea el email. */
  overflow-wrap: break-word;
  word-break: break-word;
}

/* Más padding lateral que el resto de tablas del panel (12px de
   .master-tabla th/td se quedaba corto con columnas ya ajustadas al
   contenido: el texto de una columna casi tocaba el de la siguiente).
   Selector table.master-tabla-usuarios (no solo .master-tabla-usuarios
   suelto): mismo motivo que .master-tabla th.master-tabla-centro más
   abajo en este fichero — una clase sola empataría en especificidad
   con la regla base ".master-tabla th, .master-tabla td" y perdería
   por orden de aparición; añadir el tipo "table" la hace más
   específica de verdad, sin depender del orden en la hoja de estilos. */
table.master-tabla-usuarios th,
table.master-tabla-usuarios td {
  padding-left: 16px;
  padding-right: 16px;
}

/* Responsable: SIN insignia — la fila entera en negrita es la única
   marca (puede haber varios responsables, cada uno con su fila en
   negrita). Sustituye a la insignia azul anterior: con varias filas
   en la tabla, una caja de color por fila resultaba más ruido que
   ayuda; la negrita se ve de un vistazo sin añadir color. */
.master-fila-responsable td {
  font-weight: 700;
}

/* Módulos accesibles: uno por línea (vía <br> en la plantilla) en vez
   de una lista separada por comas que envolvía de forma impredecible
   con la columna ya estrecha — line-height ajustado para que varias
   líneas no infravaloren la fila más de la cuenta. */
.master-modulos-lista {
  line-height: 1.5;
}

/* .master-indicadores (flex-wrap) y .master-header (flex-wrap) ya se
   apilan solos en móvil sin nada más. .master-fila-soporte SÍ necesita
   su propia regla: usa un grid de dos columnas fijas (no auto-fit),
   así que hay que forzar el apilado en pantallas estrechas aquí. */
@media (max-width: 720px) {
  .master-fila-soporte {
    grid-template-columns: 1fr;
  }

  .master-caja-soporte {
    height: auto;
    min-height: 200px;
  }

  .master-columna-avisos-notas {
    height: auto;
  }

  .master-caja-avisos,
  .master-caja-notas {
    height: auto;
  }

  .master-columna-avisos-notas .master-caja-avisos,
  .master-columna-avisos-notas .master-caja-notas {
    flex: none;
    min-height: 134px;
  }

  /* Nada de scroll dentro de scroll en móvil — mismo criterio que ya
     aplica .lista-con-scroll en el panel de usuario. */
  .master-caja-cuerpo {
    max-height: none;
    overflow-y: visible;
  }
}

/* =========================================================================
   licitaIA — listado y creación de expedientes (Fase 1, paso 1.2, con
   el ajuste visual posterior). Página propia (fondo BLANCO, como
   .sankuma-perfil/.sankuma-escritorio), nunca invertida como el panel
   máster: mismo criterio de todo el lado cliente. Mismo ancho máximo
   que .sankuma-escritorio (960px, no un valor propio) para que se
   sienta la misma anchura de página en todo el lado cliente.
   ========================================================================= */

body:has(.sankuma-licitaia) {
  background: var(--blanco);
  align-items: flex-start;
  padding-top: 48px;
}

/* 1080px (antes 960px, igual que el escritorio): la pantalla del
   expediente (paso 1.3) necesita algo más de aire para el contenido
   del punto. Compartido por las tres pantallas de licitaIA a
   propósito, para que el ancho de página se sienta igual en las tres;
   el índice lateral de la pantalla de expediente tiene su propio
   ancho FIJO (.licitaia-panel), así que este extra va entero al
   contenido, nunca al índice. */
.sankuma-licitaia {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
}

.licitaia-cabecera-lista {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

/* Botón sólido, a diferencia de .boton-crear (contorno, pensado para
   los diálogos del escritorio) — este SÍ es "el" botón destacado de la
   pantalla, no una acción secundaria entre otras. Tamaño ajustado al
   contenido (a diferencia de .sankuma-boton, pensado para ocupar todo
   el ancho de un formulario estrecho). */
.licitaia-boton-solido {
  display: inline-block;
  padding: 11px 20px;
  font-family: inherit;
  font-weight: 700;
  font-size: 14px;
  color: var(--blanco);
  background: var(--sankuma-azul);
  border: none;
  border-radius: var(--radio);
  text-decoration: none;
  text-align: center;
  cursor: pointer;
}

.licitaia-boton-solido:hover {
  background: var(--sankuma-azul-hover);
}

/* Versión inerte de .licitaia-boton-solido, para cuando "Cerrar
   expediente" no procede todavía -- se muestra igual (regla explícita
   del ajuste: la explicación de qué falta solo tiene sentido pegada al
   propio botón que no funciona) pero apagado y sin comportarse como un
   enlace. Es un <span>, no un <a>: no hay URL a la que llevar. */
/* opacity, no un gris más claro (ajuste posterior, fallo real
   encontrado: con el mismo gris que .licitaia-boton-solido-secundario,
   "Cerrar expediente" deshabilitado y "Puntos de control" -- que SÍ se
   puede pulsar -- eran indistinguibles). Aclarar el fondo directamente
   no serviría: este botón vive dentro de caja-gris, cuyo propio fondo
   YA es gris-100 -- en algún punto de aclarado desaparecería contra su
   propio contenedor. La opacidad funde el botón hacia lo que tenga
   detrás sin inventar un color nuevo, y es la convención ya universal
   para "esto no funciona ahora" (mismo criterio que usan Material
   Design/iOS). .licitaia-boton-solido-secundario, aparte, se queda
   sólido y sin opacity: debe leerse como pulsable, solo que no es la
   acción principal -- ver la nota sobre el cuarto estado (deshabilitado)
   en la revisión visual pendiente. */
.licitaia-boton-solido-deshabilitado {
  background: var(--gris-300);
  color: var(--gris-600);
  opacity: 0.6;
  cursor: default;
}

.licitaia-boton-solido-deshabilitado:hover {
  background: var(--gris-300);
  opacity: 0.6;
}

/* Botón sólido SECUNDARIO (ajuste posterior): mismo override que
   -deshabilitado ahí arriba (se aplica JUNTO a .licitaia-boton-solido,
   nunca solo -- de ahí no repetir forma/tamaño aquí), pero para una
   acción secundaria que SÍ funciona, como "Puntos de control" junto a
   "Cerrar expediente" (la principal, que se queda azul). Texto en
   gris-900 -- a propósito más oscuro que el gris-600 de
   -deshabilitado: esa versión es INERTE (no se puede pulsar), esta es
   una acción activa y debe leerse como tal.

   Nota para el repaso visual pendiente (transversal, todo el portal):
   esta es la jerarquía de tres niveles que falta generalizar --
   principal (azul, .licitaia-boton-solido), intermedia (blanco con
   contorno, todavía sin clase propia en ningún sitio) y secundaria
   (gris, esta) -- hoy cada pantalla decide el aspecto de cada botón
   por su cuenta, sin ningún criterio común. */
.licitaia-boton-solido-secundario {
  background: var(--gris-300);
  color: var(--gris-900);
}

.licitaia-boton-solido-secundario:hover {
  background: #c5c5cc;
}

/* "Cerrar expediente" arriba a la derecha de la cabecera (ajuste
   posterior): ya no es "el" botón destacado de toda la pantalla --
   compite en la esquina con el resto de la cabecera, así que baja al
   tamaño habitual de un botón del portal (mismo padding/tamaño que
   .boton-crear), sin tocar el color/relleno propios de
   .licitaia-boton-solido. */
.licitaia-boton-solido-pequeno {
  padding: 7px 14px;
  font-size: 13px;
}

/* Caja que envuelve el contenido de verdad (filtros + tabla, o el
   mensaje de "sin resultados") — mismo patrón que .caja-gris en
   perfil.html/escritorio.html: el título de página (h1) queda FUERA,
   el bloque de contenido va DENTRO de su propia caja. Antes este
   contenido iba suelto directamente sobre el fondo blanco. */
.licitaia-contenido {
  padding: 20px;
}

/* Estado vacío (paso 1.2): explica qué es un expediente en vez de
   enseñar una tabla en blanco — el hueco cuenta como texto, no como
   "esto está roto". */
.licitaia-vacio {
  text-align: center;
  padding: 36px 24px;
}

.licitaia-vacio .columna-titulo {
  margin-top: 0;
}

.licitaia-vacio p {
  max-width: 480px;
  margin: 0 auto 20px;
}

/* Barra de filtro/búsqueda: reutiliza el aspecto de .sankuma-form
   (mismos input/select), pero en fila en vez de apilado -- de ahí
   anular el margin-bottom de .campo, que asume formulario vertical.
   Buscador y estado tienen cada uno su propia clase (en vez de dejar
   que ".campo" a secas reparta el espacio) porque un <div> sin ancho
   propio, con un <input>/<select> hijo al 100%, no tiene un tamaño de
   sobra fiable dentro de un flex row: sin esto, cada campo tiende a
   pedir más sitio del que le corresponde y todos acaban en su propia
   línea, aunque sobre ancho de sitio. */
.licitaia-filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 16px;
  margin-bottom: 20px;
}

.licitaia-filtros .campo {
  margin-bottom: 0;
}

.licitaia-campo-buscar {
  flex: 1 1 240px;
}

.licitaia-campo-estado {
  flex: 0 0 180px;
}

/* Botón "Filtrar": la clase de botón sólido del lado cliente
   (.sankuma-boton) tal cual, con el ancho/bloque propios de un
   formulario estrecho anulados aquí para que encaje como un elemento
   más de esta fila, en vez de ocupar todo el ancho disponible. */
.licitaia-filtros .sankuma-boton {
  display: inline-block;
  width: auto;
}

/* Tabla del lado cliente -- NO es .master-tabla (esa vive en el tema
   invertido del panel máster): fondo blanco de página, cabecera en
   gris-100, mismos tokens que el resto del lado cliente. Padding algo
   más generoso que .master-tabla (12px/16px en vez de 10px/12px): el
   panel máster es una vista densa de administración, el lado cliente
   puede permitirse respirar más. */
.sankuma-tabla-scroll {
  overflow-x: auto;
}

.sankuma-tabla {
  width: 100%;
  border-collapse: collapse;
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
}

.sankuma-tabla th,
.sankuma-tabla td {
  padding: 12px 16px;
  text-align: left;
  font-size: 13px;
  line-height: 1.4;
  border-bottom: 1px solid var(--gris-300);
}

.sankuma-tabla th {
  font-weight: 700;
  color: var(--gris-900);
  background: var(--gris-100);
}

/* Referencia es la columna que actúa como identificador corto (ej.
   "260905 - Servicio - ..."): más ancha y sin partirse en dos líneas,
   para que nunca compita por espacio con Título en una fila estrecha. */
.sankuma-tabla-col-referencia {
  width: 220px;
  white-space: nowrap;
}

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

.sankuma-tabla tbody tr:hover {
  background: var(--gris-100);
}

@media (max-width: 720px) {
  .licitaia-filtros {
    flex-direction: column;
    align-items: stretch;
  }

  .licitaia-campo-buscar,
  .licitaia-campo-estado {
    flex: 1 1 auto;
  }

  .licitaia-filtros .sankuma-boton {
    width: 100%;
  }
}

/* =========================================================================
   licitaIA — pantalla del expediente abierto (Fase 1, paso 1.3).
   Insignias de estado: misma forma que .prioridad-badge (color + texto
   siempre juntos, nunca solo color -- ya establecido en las prioridades
   de avisos), con un color por estado propio de Punto/Expediente, igual
   que ya hace .incidencia-estado-*.
   ========================================================================= */

.expediente-estado-en_curso {
  color: var(--sankuma-azul);
  border: 1px solid var(--sankuma-azul);
}

.expediente-estado-cerrado {
  color: var(--gris-600);
  border: 1px solid var(--gris-300);
}

.punto-estado-borrador {
  color: var(--gris-600);
  border: 1px solid var(--gris-300);
}

.punto-estado-por_revisar {
  color: #9c5b00;
  border: 1px solid #f0c98a;
}

.punto-estado-aprobado {
  color: #2f7a3d;
  border: 1px solid #b7ddbc;
}

/* Mismo tono que "borrador" a propósito (no un color de alarma: un
   punto descartado es una decisión normal del flujo, no un error) --
   lo que lo distingue del resto es la cursiva, aquí y en la fila del
   índice. */
.punto-estado-descartado {
  color: var(--gris-600);
  border: 1px solid var(--gris-300);
  font-style: italic;
}

.licitaia-expediente-cabecera {
  margin-bottom: 20px;
}

/* Primera línea: la referencia -- el identificador fijo, "una
   matrícula" (motivo explícito del ajuste), sin negrita, con su botón
   de editar al lado. El estado NO va aquí: cambia con el trabajo, así
   que vive junto al título (línea de abajo), no junto a un
   identificador que no cambia.

   Ajuste posterior: esta línea pasa a repartirse en dos extremos --
   referencia+editar a la izquierda (agrupados en .licitaia-expediente-
   referencia-grupo, para que space-between no los separe entre sí) y,
   arriba a la derecha de toda la cabecera, "Cerrar expediente". */
.licitaia-expediente-referencia-fila {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 6px;
}

.licitaia-expediente-referencia-grupo {
  display: flex;
  align-items: center;
  gap: 10px;
}

.licitaia-expediente-referencia {
  font-size: 14px;
  color: var(--gris-600);
}

/* Arriba a la derecha de la cabecera: "Estados guardados" (siempre) y
   "Cerrar expediente" (solo en curso) -- sin ningún texto explicativo
   junto a "Cerrar expediente" cuando está deshabilitado (tres rondas
   de ajuste, la última pidiendo quitarlo sin excepción): el propio
   botón gris e inerte ya comunica que falta trabajo, y la barra de
   progreso de debajo dice cuánto. Renombrada de "-cerrar-area" (ajuste
   posterior: ya no es solo el botón de cerrar). */
.licitaia-expediente-acciones-area {
  display: flex;
  flex-shrink: 0;
  gap: 10px;
}

.licitaia-expediente-titulo-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.licitaia-expediente-titulo {
  margin: 0;
}

.licitaia-expediente-tipos {
  text-align: left;
  margin: 6px 0 16px;
}

.licitaia-progreso {
  margin-bottom: 16px;
}

.licitaia-progreso-pista {
  height: 8px;
  background: var(--gris-300);
  border-radius: 4px;
  overflow: hidden;
}

.licitaia-progreso-relleno {
  height: 100%;
  background: var(--sankuma-azul);
}

.licitaia-progreso-texto {
  display: inline-block;
  margin-top: 6px;
  font-size: 13px;
  color: var(--gris-600);
}

/* Panel de dos zonas (índice + punto actual). Una sola columna por
   defecto (móvil): el índice es un <details> nativo, cerrado salvo que
   el usuario lo toque -- así no se come la pantalla antes del propio
   contenido del punto, que es lo que se ha venido a leer/editar. A
   partir de 721px hay sitio de sobra para las dos zonas en paralelo,
   así que el índice deja de comportarse como un desplegable: se oculta
   el "summary" (nada que desplegar) y se fuerza visible su contenido
   pase lo que pase con el atributo [open] nativo. */
.licitaia-panel {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  align-items: start;
}

/* Convención del portal, precisada tras el primer ajuste: el blanco
   marca dónde se PUEDE ESCRIBIR, no cualquier zona de contenido. En el
   índice no se escribe nada -- toda la caja va en gris, sin islas
   blancas dentro (la única excepción es el interior de la propia
   insignia de estado, .prioridad-badge, que ya es blanca por su
   cuenta y no se toca aquí). */
.licitaia-indice {
  background: var(--gris-100);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 14px 16px;
}

.licitaia-indice summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--gris-900);
}

.licitaia-indice-lista {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* "Exportar a Word" arriba y abajo del índice (Fase 4, Entrega 2,
   ajuste posterior): mismo margen de 12px que ya separa el índice de
   su cabecera (.licitaia-indice-lista), y a lo ancho completo de la
   columna -- un botón suelto sin esto quedaría pegado al texto y
   angosto dentro de una caja estrecha (280px). */
.licitaia-indice-exportar {
  margin: 12px 0 0;
}

/* Mismo ancho, alto y relleno que las cajas de los puntos del índice
   (.licitaia-indice-item a/button, más abajo: padding 8px 10px, sin
   font-size propio -- heredan el del cuerpo de la página). Sin esto,
   el tamaño por defecto de .licitaia-boton-solido (pensado para un
   botón suelto, no para encajar en una columna de 280px) desentonaría
   con el resto de filas del índice. */
.licitaia-indice-exportar .licitaia-boton-solido {
  display: block;
  width: 100%;
  padding: 8px 10px;
  font-size: inherit;
}

/* Bloque, no flex: el título ocupa todo el ancho de la columna (ya no
   comparte fila con la insignia, ver .licitaia-indice-item
   .prioridad-badge más abajo) y, si envuelve, lo hace a lo ancho
   completo, no a la mitad.

   También aplica a <button> (ajuste posterior: cuando el punto actual
   es editable, cada fila del índice es un botón asociado a form-punto,
   para guardar antes de navegar -- ver punto_detalle.html) -- de ahí
   el reset de fondo/borde/fuente/ancho que un <a> nunca necesitó. */
.licitaia-indice-item a,
.licitaia-indice-item button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--radio);
  text-decoration: none;
  text-align: left;
  color: var(--gris-900);
  background: none;
  border: 1px solid transparent;
  font: inherit;
  cursor: pointer;
}

.licitaia-indice-item a:hover,
.licitaia-indice-item button:hover {
  background: var(--gris-300);
}

/* Blanco de fondo (ajuste posterior, revierte la decisión del segundo
   ajuste: el gris quedaba demasiado parecido al resto de filas y no
   destacaba). Se distingue del resto de la caja gris por el propio
   blanco, más el borde de color que ya llevaba. */
.licitaia-indice-actual a,
.licitaia-indice-actual button {
  background: var(--blanco);
  border-color: var(--sankuma-azul);
  font-weight: 700;
}

/* Número y título en un único bloque de texto (no dos elementos flex
   por separado): así, cuando el título es largo y envuelve, la
   segunda línea sigue dentro de ESTE bloque -- alineada con el
   título, nunca como una fila nueva colgando bajo el número. */
.licitaia-indice-titulo {
  display: block;
}

.licitaia-indice-numero {
  color: var(--gris-600);
}

/* La insignia de estado baja a su propia línea, bajo el título (antes
   iba a su derecha en la misma fila y le quitaba la mitad del ancho,
   partiendo los títulos largos en varias líneas). Es un <span> con
   .prioridad-badge, que ya es display:inline-block -- basta con que
   .licitaia-indice-titulo sea de bloque (arriba) para que la insignia
   caiga sola a la línea siguiente; aquí solo se ajusta el hueco antes
   de ella, el aspecto propio de la insignia no se toca. */
.licitaia-indice-item .prioridad-badge {
  margin-top: 6px;
}

/* Atenuado pero legible/accesible (regla explícita del encargo): color
   secundario ya aprobado en el resto de la app (mismo gris-600 que
   .sankuma-texto-secundario, nunca opacity -- eso arriesgaría el
   contraste), más cursiva. El badge de estado no se toca aquí: ya
   lleva su propio color con el contraste que le corresponde. */
.licitaia-indice-descartado .licitaia-indice-titulo {
  color: var(--gris-600);
  font-style: italic;
}

.licitaia-punto-actual {
  background: var(--gris-100);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 20px;
}

.licitaia-punto-cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.licitaia-punto-titulo {
  margin: 0;
  font-size: 18px;
}

/* Formulario dinámico del punto (Fase 1, paso 1.4). Reutiliza
   .sankuma-form tal cual (mismos input/select/textarea, ya en blanco
   sobre esta caja gris -- ahí está lo "escribible", el resto de la
   pantalla no lo es) — aquí solo se separan más los campos entre sí:
   "deben respirar", un formulario largo que se rellena despacio, no
   un cuestionario rápido (regla explícita del encargo). */
.licitaia-form-punto .campo {
  margin-bottom: 28px;
}

/* El texto redactado (Fase 1.4, ajuste posterior) es la caja más
   importante del formulario -- lo que de verdad va a la memoria, no
   materia prima como el resto de campos. Separación de sobra por
   encima y una etiqueta en mayúsculas para que no se confunda con "un
   campo más" al pasar la vista rápido por la pantalla. */
.licitaia-campo-redactado {
  margin-top: 36px;
  padding-top: 28px;
  border-top: 1px solid var(--gris-300);
}

.licitaia-campo-redactado label {
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.5px;
  color: var(--gris-600);
}

/* Debajo de la caja de texto redactado (ajuste posterior --
   reorganización): solo dos líneas, "El resultado de la caja es
   editable." y "Borrar texto" -- la marca de "generado por IA" ya no
   vive aquí, se fundió en el propio rótulo de la caja (ver el
   template). Mismo 6px entre las dos que ya separa la caja de su
   ayuda (.campo-ayuda): son un grupo, deben leerse pegados. Antes
   "Borrar texto" iba a 16px, deliberadamente MENOR ahora -- ese hueco
   quedaba demasiado grande para algo que es del mismo grupo. */
#licitaia-boton-borrar-texto {
  display: inline-block;
  margin-top: 6px;
}

/* .sankuma-boton es block/100% por defecto (pensado para ir solo en
   una caja estrecha) -- aquí va solo, entre los campos del formulario
   y la caja de texto, pero tampoco debe ocupar el ancho entero. */
#licitaia-boton-generar-ia {
  display: inline-block;
  width: auto;
}

/* "Generar texto con IA" (ajuste posterior -- reorganización): sube
   aquí, justo tras los campos del formulario. Mismo 28px que ya
   separa un campo del siguiente en este formulario
   (.licitaia-form-punto .campo) -- es "una cosa más en la fila del
   formulario", no una sección aparte; la caja de texto que viene
   después conserva su propio salto grande (.licitaia-campo-redactado,
   36px), así que la transición hacia ella no cambia. */
.licitaia-punto-acciones-generar {
  margin-top: 28px;
}

/* Superposición mientras genera (ajuste posterior): un único mecanismo
   para las tres exigencias a la vez -- visible donde mira el usuario
   (centrada, no solo en el botón), explica que la espera es normal, y
   BLOQUEA el resto de la pantalla por estar literalmente encima (más
   simple y más fiable que deshabilitar uno a uno cada botón/enlace de
   la pantalla: da igual cuántos haya o dónde estén, ninguno recibe el
   clic mientras esto está delante). position:fixed + inset:0 cubre
   todo el viewport pase lo que pase con el scroll. [hidden] con más
   especificidad que la regla base para ganarle al display:flex de
   abajo -- si no, el atributo hidden nativo no podría ocultarla. */
.licitaia-overlay-generando {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
}

.licitaia-overlay-generando[hidden] {
  display: none;
}

.licitaia-overlay-generando-caja {
  max-width: 380px;
  padding: 32px 40px;
  text-align: center;
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);
}

.licitaia-overlay-generando-spinner {
  width: 36px;
  height: 36px;
  margin: 0 auto 16px;
  border: 4px solid var(--gris-300);
  border-top-color: var(--sankuma-azul);
  border-radius: 50%;
  animation: licitaia-overlay-girar 0.8s linear infinite;
}

@keyframes licitaia-overlay-girar {
  to {
    transform: rotate(360deg);
  }
}

.licitaia-overlay-generando-texto {
  margin: 0 0 6px;
  font-weight: 700;
  color: var(--gris-900);
}

.licitaia-overlay-generando-subtexto {
  margin: 0;
  font-size: 13px;
  color: var(--gris-600);
}

/* Misma caja en lectura (punto aprobado, descartado, o expediente
   cerrado): fondo BLANCO -- aquí sí es, literalmente, el documento que
   se está redactando, distinto del resto de la pantalla de solo
   lectura (que es texto plano sin caja, ver .licitaia-respuestas-lectura
   más abajo). */
.licitaia-texto-redactado-lectura {
  margin-top: 20px;
}

.licitaia-punto-contenido {
  margin-top: 8px;
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 16px 18px;
  line-height: 1.6;
  white-space: pre-line;
}

/* Lectura de las respuestas ya guardadas (punto aprobado, o
   expediente cerrado): texto plano, nada de fondo blanco -- aquí no
   se escribe nada, así que nada de esto es una zona "escribible". */
.licitaia-respuestas-lectura {
  margin-bottom: 20px;
}

.licitaia-respuesta-item {
  padding: 10px 0;
  border-bottom: 1px solid var(--gris-300);
}

.licitaia-respuesta-item:last-child {
  border-bottom: none;
}

.licitaia-respuesta-etiqueta {
  display: block;
  font-weight: 500;
  color: var(--gris-900);
  margin-bottom: 4px;
}

.licitaia-respuesta-valor {
  display: block;
  color: var(--gris-600);
  white-space: pre-line;
}

/* Guardar y Aprobar/Enviar a revisión, en la misma caja y la misma
   línea, en extremos opuestos (ajuste posterior: antes un divisor y un
   rótulo "Estado de este punto" los separaba en dos bloques -- ya no
   hace falta, guardar el contenido y avanzar el estado son la misma
   sesión de trabajo). Guardar cae a la izquierda, el grupo de estado
   (.licitaia-punto-acciones) a la derecha, sin más que
   justify-content -- si algún día no hay ni Enviar a revisión ni
   Aprobar que mostrar, Guardar simplemente queda solo a la izquierda. */
/* Los tres botones (Generar / Guardar / Aprobar o Enviar a revisión)
   en una sola fila, en ese orden (ajuste posterior -- antes Guardar
   iba en un bloque aparte, ya no: "extremos opuestos" con
   justify-content:space-between no tiene sentido con tres botones
   relacionados en el mismo orden de lectura, así que pasan a ir
   juntos, alineados a la izquierda). Mismo 16px de margen que ya
   separa el resto de este tramo -- grupo distinto (la fila de
   acciones), mismo salto que el que la precede. */
.licitaia-punto-acciones-principales {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-top: 16px;
  margin-bottom: 20px;
}

/* Enviar a revisión / Aprobar (ajuste posterior): visibles, pero con
   menos peso que Guardar -- contorno en vez de relleno, ya no enlaces
   de texto al pie como antes. Aprobar y Enviar a revisión conviven, no
   son excluyentes (ver Punto.puede_aprobar): quien puede las dos las
   ve las dos a la vez. */
.licitaia-boton-contorno {
  display: inline-block;
  padding: 10px 18px;
  font-family: inherit;
  font-weight: 700;
  font-size: 14px;
  color: var(--sankuma-azul);
  background: none;
  border: 1.5px solid var(--sankuma-azul);
  border-radius: var(--radio);
  text-decoration: none;
  text-align: center;
  cursor: pointer;
}

.licitaia-boton-contorno:hover {
  background: var(--sankuma-azul);
  color: var(--blanco);
}

/* Aprobar (ajuste posterior): mismo contorno, pero con el interior en
   blanco -- para que resalte sobre el gris de .licitaia-punto-actual,
   a diferencia de Enviar a revisión, que se queda transparente. */
.licitaia-boton-contorno-blanco {
  background: var(--blanco);
}

.licitaia-boton-contorno-blanco:hover {
  background: var(--sankuma-azul);
}

.licitaia-punto-acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

/* Devolver a borrador / Descartar / Reactivar (ajuste posterior): son
   marcha atrás o excepción, no continuación del trabajo -- de ahí que
   vivan aparte de Guardar/Enviar a revisión/Aprobar, con el mismo
   aspecto discreto de enlace de texto que ya tenían. */
.licitaia-punto-acciones-secundarias {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-300);
}

.licitaia-punto-acciones-secundarias form {
  margin: 0;
}

/* Mismo botón-enlace para devolver a borrador (formulario, va por
   POST) y descartar/reactivar (enlaces, van por GET a su propia
   confirmación) -- visualmente son la misma familia de acción
   discreta, aunque técnicamente uno sea <button> y el otro <a>. */
.licitaia-accion-boton {
  display: inline-block;
  padding: 0;
  margin: 0;
  border: none;
  background: none;
  font: inherit;
  font-size: 14px;
  color: var(--sankuma-azul);
  text-decoration: none;
  cursor: pointer;
}

.licitaia-accion-boton:hover {
  text-decoration: underline;
}

.licitaia-punto-navegacion {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-300);
}

/* También aplica cuando son <button> (ajuste posterior: guardan antes
   de navegar, ver punto_detalle.html) -- el reset de fondo/borde deja
   un botón indistinguible del <a> que sustituye. */
.licitaia-nav-anterior,
.licitaia-nav-siguiente {
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: var(--sankuma-azul);
  background: none;
  border: none;
  padding: 0;
  text-decoration: none;
  text-align: left;
  cursor: pointer;
  max-width: 45%;
}

.licitaia-nav-siguiente {
  margin-left: auto;
  text-align: right;
}

.licitaia-nav-anterior:hover,
.licitaia-nav-siguiente:hover {
  text-decoration: underline;
}

.licitaia-resumen-lista {
  margin: 4px 0 16px;
  padding-left: 20px;
}

/* =========================================================================
   Punto económico (Fase 1, paso 1.5, segunda parte) — tres tablas de
   partidas (una por categoría activa), presupuesto/IVA, valor
   estimado y la vista previa del desglose. Reutiliza .sankuma-tabla/
   .sankuma-tabla-scroll y los input/select de .sankuma-form tal cual
   (regla explícita del encargo: "las mismas clases del lado cliente")
   -- lo único nuevo de verdad es la alineación numérica y el tamaño
   de columna, abajo.
   ========================================================================= */

.licitaia-economico-categoria {
  margin-bottom: 28px;
}

.licitaia-economico-categoria-titulo {
  margin: 0 0 10px;
  font-size: 15px;
  font-weight: 700;
  color: var(--gris-900);
}

/* Números SIEMPRE alineados a la derecha (regla explícita del
   encargo) -- tanto en la cabecera como en cada celda, editable o de
   solo lectura, para que la columna entera se lea como una columna de
   cifras y no como texto suelto. */
.licitaia-col-numero,
.licitaia-celda-numero {
  text-align: right;
}

.sankuma-tabla input.licitaia-input-numero {
  text-align: right;
}

.licitaia-col-quitar {
  width: 40px;
}

/* Reset de botón (mismo patrón que .licitaia-accion-boton): un
   "quitar" discreto, no un botón de peligro a todo trapo -- quitar
   una línea de un formulario que aún no se ha guardado no es una
   acción destructiva de verdad. */
.licitaia-boton-quitar-fila {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  background: var(--blanco);
  color: var(--gris-600);
  font-size: 13px;
  cursor: pointer;
}

.licitaia-boton-quitar-fila:hover {
  border-color: #8a1f13;
  color: #8a1f13;
}

.licitaia-economico-categoria-pie {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
}

.licitaia-economico-subtotal {
  margin: 0;
  font-weight: 700;
  color: var(--gris-900);
}

/* Presupuesto/IVA/total (apartado B) -- caja propia en blanco (aquí
   SÍ se escribe: el tipo de IVA es un <select> real), separada de las
   tablas de arriba por el propio margen de .licitaia-economico-categoria. */
.licitaia-economico-resumen {
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 16px 18px;
  margin-bottom: 20px;
}

.licitaia-economico-resumen-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--gris-300);
}

.licitaia-economico-resumen-fila:last-child {
  border-bottom: none;
}

.licitaia-economico-resumen-fila label {
  margin-bottom: 0;
  font-weight: 500;
}

.licitaia-economico-resumen-fila select {
  width: auto;
  min-width: 100px;
}

.licitaia-economico-resumen-total {
  font-weight: 700;
  font-size: 16px;
  color: var(--gris-900);
}

.licitaia-separador-economico {
  border-top: 1px solid var(--gris-300);
  margin: 28px 0 20px;
}

.licitaia-economico-valor-estimado .campo {
  margin-bottom: 16px;
}

/* Cabecera de la tabla de valor estimado, en blanco (ajuste
   posterior): el gris por defecto de .sankuma-tabla th no se
   distinguía del resto de la fila. Solo esta tabla -- las demás
   (partidas, vista previa) se quedan con el gris de siempre. */
.licitaia-tabla-valor-estimado th {
  background: var(--blanco);
}

.licitaia-fila-ve-total {
  font-weight: 700;
}

/* De dónde sale cada importe propuesto (ajuste posterior): apoyo
   discreto, no debe competir con la cifra de arriba -- de ahí el
   tamaño reducido y el gris en vez del negro/azul del resto de la
   tabla. :empty lo oculta entero cuando el componente no tiene
   propuesta (factor/porcentaje vacío): la raya se queda sola, sin un
   cálculo huérfano debajo. */
.licitaia-propuesta-calculo {
  margin-top: 2px;
  font-size: 12px;
  font-weight: 400;
  color: var(--gris-600);
}

.licitaia-propuesta-calculo:empty {
  display: none;
}

.licitaia-fila-ve-total td {
  border-top: 2px solid var(--gris-300);
}

/* Fila de acción dentro de la tabla de valor estimado (ajuste
   posterior: antes era un botón aparte debajo de la tabla). Centrada
   en las tres columnas, sin fondo propio -- el fondo gris de
   :hover ya viene de .sankuma-tabla tbody tr:hover, así que la fila
   se percibe pulsable igual que cualquier otra fila con acción. */
.licitaia-fila-ve-accion td {
  text-align: center;
}

.licitaia-economico-ve-ayuda {
  text-align: right;
}

.licitaia-avisos-economicos {
  margin-top: 16px;
}

.licitaia-avisos-economicos p {
  margin: 0;
}

.licitaia-avisos-economicos p + p {
  margin-top: 6px;
}

/* Vista previa del desglose (apartado D) y modo consulta: SIEMPRE
   solo lectura, tono ligeramente distinto (fondo de página, no
   blanco) para que no se confunda con las tablas editables de arriba
   cuando las dos conviven en la misma pantalla. */
.licitaia-economico-desglose {
  background: var(--gris-100);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 18px 20px;
}

.licitaia-economico-desglose .licitaia-economico-resumen,
.licitaia-economico-valor-estimado-lectura {
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 16px 18px;
}

.licitaia-economico-valor-estimado-lectura {
  margin-top: 20px;
}

/* Utilidad genérica (primer uso: la cabecera "Quitar línea" de las
   tablas de partidas, que solo hace falta para lectores de pantalla —
   la propia "✕" del botón ya la comunica visualmente). */
.sankuma-visualmente-oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Pantalla estrecha (apartado E): las tablas de partidas ya heredan
   .sankuma-tabla-scroll (el mismo patrón de scroll horizontal que
   usa el resto del portal para tablas anchas, en vez de inventar un
   diseño de tarjetas nuevo solo para esta pantalla) -- lo único que
   hace falta aquí es que el resumen y el pie de cada categoría, que
   SÍ son flex-row, no se apelmacen en un móvil estrecho. */
@media (max-width: 640px) {
  .licitaia-economico-resumen-fila {
    flex-wrap: wrap;
  }

  .licitaia-economico-categoria-pie {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (min-width: 721px) {
  .licitaia-panel {
    grid-template-columns: 280px 1fr;
  }

  .licitaia-indice summary {
    display: none;
  }

  .licitaia-indice > :not(summary) {
    display: block !important;
  }
}

/* =========================================================================
   licitaIA v2, paso 2.3 — panel máster de configuración de IA (catálogo
   de modelos/niveles, configuración de IA por cliente, editor de
   prompts). Mismo tono invertido del resto del panel máster: cajas
   grises, tablas .master-tabla, sin CSS propio aparte.
   ========================================================================= */

/* Precio a cero, MUY VISIBLE (mismo tono que .sankuma-form .campo-error,
   #8a1f13) — un modelo con el precio sin configurar hace que el coste
   de sus generaciones se registre como 0 €, y eso tiene que saltar a
   la vista, no descubrirse mirando la tabla con lupa. */
.master-aviso-precio {
  color: #8a1f13;
  font-size: 12px;
}

/* Ajuste de moneda (precios de ModeloIA en dólares, conversión a
   euros bajo demanda): dos botones agrupados en la cabecera de la
   caja de Modelos -- mismo gap de 12px ya usado en el resto del
   panel para "controles relacionados uno junto a otro". */
.master-caja-acciones-cabecera {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* El aviso del cambio consultado ("1 € = X $ -- BCE del dd/mm/aaaa")
   reutiliza el mismo aspecto que .master-prompts-alcance: una nota
   destacada, no una ayuda que pase desapercibida -- la fecha del
   cambio es precisamente lo que no puede perderse de vista. */
.master-cambio-bce-aviso {
  margin: 12px 0;
  padding: 10px 12px;
  background: var(--gris-100);
  border-radius: var(--radio);
  font-size: 14px;
}

/* El equivalente en euros de cada fila, junto al dólar guardado --
   informativo, no un aviso (por eso el gris de "no disponible" del
   portal, no el rojo de .master-aviso-precio, que es para lo que sí
   hay que corregir). */
.master-cambio-bce-equivalencia {
  color: var(--gris-600);
  font-size: 12px;
}

/* Columna "Configuración" de la tabla de Módulos: el módulo SIN
   pantalla propia todavía (el chatbot, hoy) muestra "Configurar" en
   texto llano -- ni negrita ni azul como .master-enlace-accion (eso
   es para el que SÍ enlaza), ni siquiera un <a>, así que ya no tiene
   ni cursor de mano ni cambia al pasar el ratón por sí solo. El gris
   es el mismo que ya usa el portal para "no disponible"
   (.master-tabla-pendiente/.master-etiqueta-inactivo, var(--gris-600))
   -- que la diferencia con el activo sea de COLOR, no solo de peso,
   para que no se confundan al vistazo. */
.master-configuracion-apagada {
  color: var(--gris-600);
  font-weight: 400;
}

/* Diálogo ancho (editor de prompts): el textarea y la comparación de
   dos columnas necesitan más espacio que el diálogo por defecto
   (min(600px, 92vw)) — se usa JUNTO a .dialogo-hilo, nunca en su
   lugar, para conservar el resto de sus reglas (backdrop, radio...). */
.dialogo-ancho {
  width: min(920px, 96vw);
  max-height: min(90vh, 920px);
}

.dialogo-ancho .dialogo-contenido {
  max-height: calc(min(90vh, 920px) - 44px);
}

.master-filtro-prompts-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}

.master-filtro-prompts-fila .campo {
  margin-bottom: 0;
  min-width: 180px;
}

/* Panel "de un vistazo" (paso 2.3C) — una fila por capa, para ver de
   un vistazo cuál está personalizada y cuál hereda, sin abrir nada. */
.master-prompts-vistazo {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-300);
}

.master-prompts-vistazo-fila {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 0;
}

.master-prompts-vistazo-etiqueta {
  font-weight: 600;
  min-width: 140px;
}

.master-prompts-alcance {
  margin: 12px 0;
  padding: 10px 12px;
  background: var(--gris-100);
  border-radius: var(--radio);
  font-size: 14px;
}

.master-prompts-probar {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-300);
}

.master-prompts-resultado {
  margin-top: 16px;
  padding: 12px;
  background: var(--gris-100);
  border-radius: var(--radio);
}

/* .campo-ayuda ya define este mismo aspecto (13px, gris-600, 6px de
   separación) para las ayudas de campo del portal — pero esa regla
   está encadenada a ".sankuma-form" (.sankuma-form .campo-ayuda), y
   los textos de apoyo de "Probar y comparar" y del resultado de la
   prueba no viven dentro de un formulario. Mismos valores, ampliados
   solo a estos dos contenedores de esta pantalla — no una regla
   ".campo-ayuda" suelta que cambiaría su aspecto en el resto del
   portal. */
.master-prompts-probar > .campo-ayuda,
.master-prompts-resultado .campo-ayuda {
  margin-top: 6px;
  margin-bottom: 0;
  font-size: 13px;
  color: var(--gris-600);
}

/* El hueco entre esta explicación y el primer campo ("Expediente de
   prueba") debe ser el mismo que separa un .campo del siguiente
   (.sankuma-form .campo, margin-bottom: 20px) — mismo valor, no uno
   nuevo. Sin esto, el <p> (fuera del <form>, margin-bottom: 0 de la
   regla de arriba) y la primera etiqueta quedaban pegados: el <form>
   no aporta separación propia por defecto. */
#form-probar-prompt {
  margin-top: 20px;
}

.master-prompts-comparacion {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.master-prompts-comparacion-columna h4 {
  margin: 0 0 6px;
  font-size: 13px;
  color: var(--gris-600);
}

.master-prompts-resultado-texto {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 14px;
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 10px;
  max-height: 300px;
  overflow-y: auto;
}

.master-prompts-historial {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-300);
}

/* "Guardar", reubicado tras Probar/comparar (el orden pasa a ser
   texto -> probar -> guardar -> historial): mismo separador que
   .master-prompts-probar/.master-prompts-historial, para que se lea
   como su propia sección, no como una coletilla de la anterior. */
.master-prompts-guardar {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-300);
}

@media (min-width: 721px) {
  .master-prompts-comparacion {
    grid-template-columns: 1fr 1fr;
  }
}

/* =========================================================================
   licitaIA v2, Fase 3 — historial de versiones de un punto, comparar
   dos versiones, y fotos de expediente. Mismo tono del resto del lado
   cliente: caja-gris, .sankuma-tabla-scroll donde hace falta scroll
   horizontal, .lista-con-scroll (ya usada en avisos/notas del
   escritorio) para que un historial largo no se coma la pantalla.
   ========================================================================= */

/* Una versión del historial, en tarjeta -- mismo espíritu que
   .hilo-item de avisos (fila con metadatos + acción), no una tabla:
   el contenido íntegro de una versión cabe mal en una celda. */
.licitaia-version-item {
  padding: 12px 0;
  border-bottom: 1px solid var(--gris-300);
}

.licitaia-version-item:last-child {
  border-bottom: none;
}

.licitaia-version-cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 4px;
}

.licitaia-version-numero {
  font-weight: 700;
}

.licitaia-version-meta {
  color: var(--gris-600);
  font-size: 13px;
}

.licitaia-version-detalle-ia {
  color: var(--gris-600);
  font-size: 13px;
  margin: 2px 0 6px;
}

.licitaia-version-acciones {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 6px;
}

/* Casilla "Comparar" de una versión (ajuste posterior: sustituye a los
   selectores "A"/"B" de antes, que nadie entendía sin explicación) --
   en línea con el resto de la cabecera, no una columna aparte de la
   tarjeta. El máximo de dos marcadas a la vez lo impone el JS de la
   plantilla (ver punto_historial.html), deshabilitando las demás
   casillas -- aquí solo el aspecto normal/deshabilitado. */
.licitaia-version-marcar {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--gris-600);
}

.licitaia-version-marcar:has(input:disabled) {
  color: var(--gris-300);
}

.licitaia-version-texto {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 14px;
  background: var(--gris-100);
  border-radius: var(--radio);
  padding: 10px 12px;
  margin-top: 8px;
}

/* Comparación lado a lado (apartado B) -- mismo patrón de grid que
   .master-prompts-comparacion en el panel máster (probar/comparar
   prompts): una columna en móvil, dos a partir de 721px. Namespace
   propio (licitaia-, no master-) porque esto vive en el lado cliente,
   no en el panel máster -- misma técnica, clases separadas (regla
   explícita del encargo: "las clases del lado cliente"). */
.licitaia-comparacion {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.licitaia-comparacion-columna h3 {
  margin: 0 0 6px;
  font-size: 14px;
}

/* Preservar saltos de línea del contenido original -- mismo criterio
   que .master-prompts-resultado-texto. ins/del ya aportan su propia
   forma (subrayado/tachado) además del color, para no depender solo
   de este último (regla explícita del encargo, misma convención que
   .prioridad-badge: nunca solo color). Mismos tonos que
   .prioridad-baja-intenso/.prioridad-alta-intenso y el color de texto
   de .prioridad-badge.prioridad-baja/-alta -- ningún color nuevo. */
.licitaia-comparacion-texto {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 14px;
  background: var(--blanco);
  border: 1px solid var(--gris-300);
  border-radius: var(--radio);
  padding: 12px;
}

.licitaia-comparacion-texto ins.licitaia-diff-anadido {
  background: #cfe9d7;
  text-decoration: underline;
  text-decoration-color: #2f7a3d;
}

.licitaia-comparacion-texto del.licitaia-diff-quitado {
  background: #f6d5d5;
  text-decoration: line-through;
  text-decoration-color: #a3242c;
}

.licitaia-comparacion-leyenda {
  display: flex;
  gap: 16px;
  font-size: 13px;
  color: var(--gris-600);
  margin-bottom: 12px;
}

@media (min-width: 721px) {
  .licitaia-comparacion {
    grid-template-columns: 1fr 1fr;
  }
}

/* Fotos de expediente (apartado C): misma tarjeta que una versión de
   punto (.licitaia-version-item de arriba), reutilizada tal cual para
   la cabecera; solo hace falta una regla propia para la lista de
   puntos capturados dentro de cada foto. */
.licitaia-foto-item {
  padding: 12px 0;
  border-bottom: 1px solid var(--gris-300);
}

.licitaia-foto-item:last-child {
  border-bottom: none;
}

.licitaia-foto-etiqueta {
  font-weight: 700;
}

.licitaia-foto-meta {
  color: var(--gris-600);
  font-size: 13px;
}

.licitaia-foto-motivo {
  margin: 4px 0;
}

.licitaia-foto-puntos-item {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
  border-bottom: 1px dashed var(--gris-300);
}

.licitaia-foto-puntos-item:last-child {
  border-bottom: none;
}
