/* ================= DISEÑO LÍQUIDO Y ADAPTABLE ================= */
/* El `min-width: 430px` con `overflow-x: auto` existía porque las cabeceras de tarjeta
   iban en `nowrap` y desbordaban: la barra horizontal era el parche. Ahora el título
   cede con ellipsis, así que el contenido cabe a cualquier ancho y la barra sobra —
   con el panel a 430 px forzaba 8 px de desbordamiento contra su propia barra vertical. */
body {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--tipo);
  font-size: var(--t-s);
  color: var(--gw-texto);
  margin: 0;
  padding: 0;                /* el relleno lo pone cada sección: la cabecera va a sangre */
  background: var(--gw-fondo);
}

/* 🔴 EL TARIFARIO ES LA ÚNICA VISTA A LA QUE SE LE SUELTA EL ANCHO, y es una excepción
   con motivo: una tabla de veinte rutas con su agente, su precio, su tránsito y su
   vigencia no entra en una columna de 400 px. La cotización se queda exactamente como
   está —su diseño asume la columna estrecha— y por eso la regla se ata a la clase que
   pone `tarCambiarModo`, no a la vista de pestaña en general. */
body.tarifario-ancho.en-pestana .contenedor,
body.tarifario-ancho.en-pestana { max-width: none; }

/* Abierta en pestaña (navegador sin panel lateral, ver background.js). Se centra en vez
   de estirarse: todo el diseño asume una columna estrecha, y a 1900 px de ancho las
   tarjetas quedarían ilegibles. Solo layout — ni un color nuevo (regla 15). */
body.en-pestana {
  max-width: 720px;
  margin: 0 auto;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);
}

/* ================= CABECERA =================
   Banda verde a sangre con el lockup del PDF corporativo. Sustituye al <h2> centrado:
   el verde de marca da 12.24:1 con texto blanco, mientras que el #4CAF50 de la pestaña
   activa anterior se quedaba en 2.78:1 — el peor contraste de la extensión. */
.gw-cab {
  background: var(--gw-verde);
  padding: var(--e-3) var(--e-3) 0;
}

.gw-marca {
  margin: 0 0 var(--e-3);
  font-size: 13px;
  letter-spacing: .34em;
  color: #fff;
  font-weight: 400;
  line-height: 1.1;
}
.gw-marca span {
  display: block;
  font-size: 8px;
  letter-spacing: .34em;
  color: var(--gw-magenta);
  font-weight: 700;
  margin-top: 3px;
}

/* Pestañas: filete magenta bajo la activa en lugar de un bloque relleno. Es el recurso
   que usa el propio PDF para marcar sección, y de paso el texto blanco sobre verde
   cumple AA de sobra. */
.tabs { display: flex; gap: var(--e-4); }

.tab-btn {
  flex: none;
  padding: 0 0 9px;
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  color: #9DB3A6;
  font-weight: 600;
  font-size: var(--t-s);
  cursor: pointer;
  border-radius: 0;
}
.tab-btn:hover { color: #D6E2DA; }
.tab-btn.active { color: #fff; border-bottom-color: var(--gw-magenta); }
.tab-btn:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }

.tab-content { display: none; padding: var(--e-3); }
.tab-content.active { display: block; }

/* Contorneado y no sólido: el único relleno verde de la pantalla es "Guardar Cambios",
   que es lo que escribe en la hoja. Dos botones sólidos compiten y ninguno destaca. */
.btn-nueva {
  background: #fff;
  color: var(--gw-verde);
  padding: 9px;
  border: 1px solid var(--gw-verde);
  border-radius: var(--r-s);
  cursor: pointer;
  margin-bottom: var(--e-3);
  width: 100%;
  font-weight: 600;
  font-size: var(--t-s);
}
.btn-nueva:hover { background: var(--gw-verde-tenue); }

/* ================= PAGINACIÓN ================= */
.gw-paginacion {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--e-3);
  margin-top: var(--e-4);
  padding-bottom: var(--e-3);
}

.gw-pag-btn {
  background: #fff;
  color: var(--gw-verde);
  border: 1px solid var(--gw-borde);
  padding: 6px 12px;
  font-weight: 600;
  white-space: nowrap;
}
.gw-pag-btn:hover:not(:disabled) { border-color: var(--gw-verde); background: var(--gw-verde-tenue); }
.gw-pag-btn:disabled { color: var(--gw-tenue); border-color: var(--gw-borde); cursor: not-allowed; opacity: .55; }

/* "Pág 1 de 27" partía en tres líneas y descuadraba la fila. Tabular para que el ancho
   no cambie al pasar de la página 9 a la 10. */
.gw-pag-info {
  font-size: var(--t-s);
  font-weight: 700;
  color: var(--gw-texto-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ================= BUSCADORES Y BOTONES ================= */
.search-box { display: flex; gap: var(--e-2); margin-bottom: var(--e-2); }

input[type="text"], input[type="date"], input[type="number"], select {
  width: 100%;
  padding: 6px;
  border: 1px solid var(--gw-borde);
  border-radius: var(--r-s);
  box-sizing: border-box;
  font-size: var(--t-s);
  font-family: inherit;
  color: var(--gw-texto);
  background: #fff;
}

input:focus, select:focus {
  border-color: var(--gw-verde);
  outline: none;
  box-shadow: 0 0 0 2px rgba(15, 61, 38, .15);
}

button {
  padding: 6px 12px;
  border: none;
  border-radius: var(--r-s);
  cursor: pointer;
  font-weight: 600;
  font-size: var(--t-s);
  font-family: inherit;
}

#btnBuscar1, #btnBuscar2 {
  background: #fff;
  color: var(--gw-verde);
  border: 1px solid var(--gw-borde);
}
#btnBuscar1:hover, #btnBuscar2:hover { background: var(--gw-verde-tenue); border-color: var(--gw-verde); }

/* ================= TARJETAS Y ACORDEÓN ================= */
.tarjeta {
  background: var(--gw-blanco);
  border: 1px solid var(--gw-borde);
  border-left: 3px solid var(--gw-verde);
  border-radius: var(--r-m);
  box-shadow: var(--sombra-1);
  margin-bottom: var(--e-2);
  padding: 0;
  overflow: hidden;
}
/* Una rechazada se distingue de un vistazo en la lista sin tener que leer la píldora. */
.tarjeta.es-rechazada { border-left-color: var(--gw-borde-fuerte); }

/* Definición única de la cabecera. Antes vivía aquí y otra vez en el <style> de
   popup.html, que ganaba por orden: dos fuentes para lo mismo y cambios que no se
   veían. Los valores conservados son los que ganaban (padding 12, fuente 12). */
.accordion-header {
  background-color: var(--gw-blanco);
  cursor: pointer;
  padding: var(--e-3);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: var(--e-2);
  border-bottom: 1px solid transparent;
  color: var(--gw-texto);
  font-size: var(--t-s);
}
.accordion-header:hover { background-color: var(--gw-superficie); }
.accordion-header:focus-visible { outline: 2px solid var(--gw-verde); outline-offset: -2px; }
/* La línea inferior solo aparece cuando hay contenido debajo que separar. */
.accordion-header[aria-expanded="true"] { border-bottom-color: var(--gw-borde); }

/* El código de la cotización no se corta nunca: es lo que se busca a ojo en la lista.
   Tabular para que la columna no baile entre tarjetas. Con el verde de marca da 10.6:1
   incluso sobre el fondo aclarado del hover; el #2e7d32 anterior se quedaba en 4.09. */
.acc-clave {
  flex: none;
  font-family: var(--tipo-mono);
  font-variant-numeric: tabular-nums;
  color: var(--gw-verde);
}

/* El que cede espacio. `min-width:0` es imprescindible: sin él un hijo flex no baja
   de su contenido y el ellipsis no llega a activarse nunca. */
.acc-titulo {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: normal;
}

.acc-icon { flex: none; color: var(--gw-tenue); font-size: 10px; }

/* ================= PÍLDORA DE ESTATUS =================
   Molde tomado del PDF corporativo (las etiquetas CRÍTICO / ALTO / MODERADO de su
   tabla de puertos): relleno pálido, borde del mismo tono y versalitas espaciadas.
   Lleva color Y texto, así que no depende del color para entenderse. */
.acc-estado, .gw-pastilla {
  flex: none;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: var(--r-pill);
  border: 1px solid;
  white-space: nowrap;
}
.acc-estado[data-tono="bueno"],  .gw-pastilla[data-tono="bueno"]  { background: var(--gw-exito-fondo);   color: var(--gw-exito);   border-color: var(--gw-exito-borde); }
.acc-estado[data-tono="malo"],   .gw-pastilla[data-tono="malo"]   { background: var(--gw-peligro-fondo); color: var(--gw-peligro); border-color: var(--gw-peligro-borde); }
.acc-estado[data-tono="espera"], .gw-pastilla[data-tono="espera"] { background: var(--gw-aviso-fondo);   color: var(--gw-aviso);   border-color: var(--gw-aviso-borde); }
.acc-estado[data-tono="neutro"], .gw-pastilla[data-tono="neutro"] { background: var(--gw-superficie);    color: var(--gw-texto-2); border-color: var(--gw-borde); }

.accordion-content {
  padding: var(--e-3);
  display: none;
}
.accordion-content.active { display: block; }

/* ================= TÍTULOS DE SECCIÓN =================
   Molde del PDF corporativo: texto en verde de marca y un filete magenta corto debajo.
   Antes eran <h5> en gris #666 sin ninguna jerarquía, indistinguibles de una etiqueta
   de campo dentro de una tarjeta ya muy densa. */
.gw-seccion {
  display: flex;
  align-items: center;
  margin: 0 0 var(--e-3);
  padding-bottom: 6px;
  font-size: var(--t-m);
  font-weight: 600;
  color: var(--gw-verde);
  border-bottom: 1px solid var(--gw-borde);
  position: relative;
}
/* El filete cubre solo el ancho del título, no toda la línea: es un acento, no un marco. */
.gw-seccion::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 34px;
  height: 2px;
  background: var(--gw-magenta);
}

/* ================= CAMPOS "ULTRA-DENSOS" ================= */
.campo { margin-bottom: var(--e-2); }

/* Antes 9px en #777 (3.85:1, por debajo de AA). Ahora 11px en --gw-texto-3, que da
   7.05:1. Se conservan las versalitas espaciadas: es el recurso del PDF y funcionaba. */
.campo label {
  display: block;
  font-size: 10px;
  color: var(--gw-texto-3);
  margin-bottom: 3px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
}

/* Dos columnas en el panel estrecho y tantas como quepan al ensancharlo. Antes eran
   dos fijas a cualquier ancho, así que a 760px media pantalla quedaba vacía. */
.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--e-2);
}
@media (min-width: 700px) {
  .grid-2 { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
}

/* ================= FILA DE BULTO =================
   Iban seis columnas en una sola línea repartidas por `flex:N`, así que a 430 px los
   campos numéricos quedaban en 46 px: "0.650" se veía "0.6" y "475.5" se cortaba. No
   se podía leer la cifra que se estaba editando.
   Ahora cada campo tiene un ancho mínimo y la línea envuelve: a 430 px caen tres por
   fila, y al ensanchar el panel se recolocan solos. Sin breakpoint que mantener. */
.bulto-linea {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: flex-end;
  margin-bottom: 5px;
}
.bulto-campo { flex: 1 1 84px; min-width: 84px; }
.bulto-campo.ancho { flex: 2 1 150px; }

.bulto-campo label {
  display: block;
  font-size: 10px;
  color: var(--gw-texto-3);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  margin-bottom: 3px;
}
.bulto-campo input, .bulto-campo select { width: 100%; }

/* Toda cifra alineada a la derecha y con dígitos de ancho fijo: si no, la columna
   baila a cada tecla porque el "1" es más estrecho que el "0". */
.bulto-campo input[type="number"], .bulto-calc { text-align: right; font-variant-numeric: tabular-nums; }

/* Los dos campos calculados. Siguen siendo <input readonly> porque el motor de
   volumetría los lee y escribe por `.value` en seis sitios; lo que cambia es que ya
   no aparentan editables. */
.bulto-calc { background: var(--gw-superficie); border: 1px solid var(--gw-borde); color: var(--gw-verde); font-weight: 700; }

.btn-remove-bulto {
  flex: none;
  background: #fff;
  color: var(--gw-peligro);
  border: 1px solid var(--gw-peligro-borde);
  border-radius: var(--r-s);
  padding: 0 9px;
  height: 27px;
  cursor: pointer;
  font-weight: 700;
}
.btn-remove-bulto:hover { background: var(--gw-peligro-fondo); border-color: var(--gw-peligro); }

/* ================= AVISO DE CAMPO MACRO =================
   Cliente, Origen, Destino y Modo forman la llave de rastreo. No se bloquean, pero
   cambiarlos deja de pasar desapercibido. Ámbar y no rojo a propósito: no es un error,
   es una advertencia con una salida correcta al lado. */
.macro-alterado {
  border-color: var(--gw-naranja) !important;
  background: #FDF7F0;
  box-shadow: 0 0 0 2px rgba(194, 102, 10, .14);
}

.macro-aviso {
  background: var(--gw-alerta-fondo);
  border: 1px solid var(--gw-alerta-borde);
  border-radius: var(--r-s);
  padding: var(--e-2) 9px;
  margin-top: 5px;
  font-size: var(--t-micro);
  line-height: 1.45;
  color: #5C3D14;
}
.macro-aviso strong { color: var(--gw-alerta); }

.macro-deshacer, .macro-corregir {
  display: inline-block;
  margin-right: 6px;
  margin-top: 7px;
  background: #fff;
  border: 1px solid var(--gw-naranja);
  color: var(--gw-alerta);
  border-radius: var(--r-s);
  padding: 4px 12px;
  font-size: var(--t-micro);
  font-weight: 700;
  cursor: pointer;
}
.macro-deshacer:hover, .macro-corregir:hover { background: #F6E4D2; }
.macro-corregir { background: var(--gw-alerta); color: #fff; }

/* ================= AVISOS DEL PANEL =================
   Pegados bajo la cabecera con `sticky`, no `fixed`: así siguen a la vista al hacer
   scroll pero nunca tapan la barra de acciones del pie, donde está Guardar.
   Vacío no ocupa nada. */
#gw_avisos {
  position: sticky;
  top: 0;
  z-index: 50;
}
#gw_avisos:not(:empty) {
  padding: var(--e-2) var(--e-3) 0;
  background: var(--gw-fondo);
}

.gw-aviso {
  position: relative;
  border: 1px solid;
  border-left-width: 3px;
  border-radius: 0 var(--r-s) var(--r-s) 0;
  padding: 9px 30px 9px 11px;
  margin-bottom: 6px;
  box-shadow: var(--sombra-2);
  animation: gw-desplegar 180ms ease-out;
}

.gw-aviso-titulo {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  margin-bottom: 3px;
}
.gw-aviso-texto { font-size: var(--t-micro); line-height: 1.5; white-space: pre-line; }

.gw-aviso-exito { background: var(--gw-exito-fondo);   border-color: var(--gw-exito-borde);   color: var(--gw-exito);   border-left-color: var(--gw-exito); }
.gw-aviso-error { background: var(--gw-peligro-fondo); border-color: var(--gw-peligro-borde); color: var(--gw-peligro); border-left-color: var(--gw-peligro); }
.gw-aviso-aviso { background: var(--gw-alerta-fondo);  border-color: var(--gw-alerta-borde);  color: var(--gw-alerta);  border-left-color: var(--gw-naranja); }
.gw-aviso-info  { background: var(--gw-superficie);    border-color: var(--gw-borde);         color: var(--gw-texto-2); border-left-color: var(--gw-borde-fuerte); }

.gw-aviso-cerrar {
  position: absolute;
  top: 5px;
  right: 5px;
  background: none;
  border: none;
  padding: 3px;
  color: inherit;
  opacity: .65;
  cursor: pointer;
  line-height: 0;
}
.gw-aviso-cerrar:hover { opacity: 1; }

.gw-aviso-accion {
  margin-top: 7px;
  background: #fff;
  border: 1px solid currentColor;
  color: inherit;
  border-radius: var(--r-s);
  padding: 4px 12px;
  font-size: var(--t-micro);
  font-weight: 700;
  cursor: pointer;
}

/* Un enlace dentro de un aviso (el libro «Tarifas históricas», 2026-10-25): al lado del
   botón de acción, con su mismo tamaño, y subrayado porque abre otra pestaña. */
.gw-aviso-enlace {
  display: inline-block;
  margin: 7px 0 0 10px;
  color: inherit;
  font-size: var(--t-micro);
  font-weight: 700;
  text-decoration: underline;
}

/* El campo que provocó el aviso, para que no haya que buscarlo. */
.gw-campo-culpable {
  border-color: var(--gw-peligro) !important;
  box-shadow: 0 0 0 2px rgba(158, 14, 63, .15);
}

/* ================= CONFIRMACIÓN MODAL ================= */
.gw-modal {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(15, 61, 38, .5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--e-4);
}
.gw-modal-caja {
  background: #fff;
  border-radius: var(--r-m);
  padding: var(--e-4);
  max-width: 380px;
  width: 100%;
  box-shadow: 0 8px 28px rgba(15, 61, 38, .28);
}
.gw-modal-titulo {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--gw-magenta);
  margin-bottom: 7px;
}
.gw-modal-texto { font-size: var(--t-s); line-height: 1.55; color: var(--gw-texto); white-space: pre-line; }
.gw-modal-pie { display: flex; justify-content: flex-end; gap: var(--e-2); margin-top: var(--e-4); }
.gw-modal-no { background: none; color: var(--gw-texto-3); padding: 7px 14px; }
.gw-modal-no:hover { text-decoration: underline; }
.gw-modal-si { background: var(--gw-verde); color: #fff; padding: 7px 16px; }
.gw-modal-si:hover { background: var(--gw-verde-claro); }
.gw-modal-si.peligro { background: var(--gw-peligro); }

/* La nota bajo un campo de solo lectura ("Cargable mínimo 1 CBM: la carga da 0.40 CBM"). */
.nota-campo { display: block; font-size: 11px; line-height: 1.3; color: var(--gw-texto-3); margin-top: 2px; }

/* ================= EL MODO CON CLAUDE (2026-10-12) =================
   Lo rellenado por Claude va en ámbar (los tokens de "aviso") hasta que se toca. */
.ia-barra { display: flex; gap: 6px; flex-wrap: wrap; }
.ia-barra .btn-nueva { flex: 1 1 140px; }
.btn-ia { background: var(--gw-aviso-fondo); color: var(--gw-aviso); border: 1px solid var(--gw-aviso-borde); }

/* ================= EL MODAL DE RUTEO: avisos fijos y "Revisar con Claude" (2026-10-23) ==
   Los avisos fijos salen sin Claude mientras se escribe; la revisión compara el ruteo con
   la herramienta de costos y con los correos de la ACP. Las dos informan y no bloquean. */
.ruteo-avisos { background: var(--gw-aviso-fondo); border: 1px solid var(--gw-aviso-borde); color: var(--gw-aviso); border-radius: 5px; padding: 8px 10px; margin-bottom: 12px; font-size: 12px; }
.ruteo-avisos ul { margin: 4px 0 0; padding-left: 18px; }
.ruteo-revision-barra { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 4px; }
.ruteo-btn { width: auto; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-weight: 700; }
.ruteo-btn:disabled { opacity: .6; cursor: default; }
.ruteo-btn-cancelar { width: auto; }
.ruteo-revision-ayuda { font-size: 11px; color: var(--gw-texto-3); }
#ruteo_revision { font-size: 12px; margin-bottom: 12px; }
#ruteo_revision:empty { display: none; }
.ruteo-rev-bloque { border: 1px solid var(--gw-borde); border-radius: 5px; padding: 8px 10px; margin: 8px 0; background: var(--gw-superficie); }
.ruteo-rev-aviso { border-color: var(--gw-aviso-borde); background: var(--gw-aviso-fondo); color: var(--gw-aviso); }
.ruteo-rev-resumen { margin: 6px 0; color: var(--gw-texto); }
.ruteo-rev-linea { margin: 3px 0; color: var(--gw-texto-2); }
.ruteo-rev-titulo { margin: 10px 0 4px; font-size: 12px; color: var(--gw-texto-2); }
.ruteo-rev-lista { list-style: none; padding: 0; margin: 0; }
.ruteo-rev-dif, .ruteo-rev-serv { border-left: 3px solid var(--gw-borde-fuerte); padding: 4px 8px; margin: 4px 0; }
.ruteo-rev-dif.ruteo-rev-alta, .ruteo-rev-serv.ruteo-rev-alta { border-left-color: var(--gw-peligro); }
.ruteo-rev-dif.ruteo-rev-media { border-left-color: var(--gw-naranja); }
.ruteo-rev-sev { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; margin-right: 4px; color: var(--gw-texto-3); }
.ruteo-rev-alta .ruteo-rev-sev, .ruteo-rev-linea.ruteo-rev-alta { color: var(--gw-peligro); }
.ruteo-rev-motivo, .ruteo-rev-fuente { display: block; color: var(--gw-texto-3); font-size: 11px; }
.ruteo-rev-aplicar { width: auto; padding: 2px 8px; font-size: 11px; margin-top: 3px; border: 1px solid var(--gw-borde); border-radius: 4px; background: var(--gw-blanco); color: var(--gw-texto-2); cursor: pointer; }
.ruteo-rev-aplicar:disabled { color: var(--gw-exito); border-color: var(--gw-exito-borde); cursor: default; }
.ruteo-rev-tabla-cont { overflow-x: auto; }
.ruteo-rev-tabla { border-collapse: collapse; width: 100%; font-size: 11px; font-variant-numeric: tabular-nums; }
.ruteo-rev-tabla th, .ruteo-rev-tabla td { border-bottom: 1px solid var(--gw-borde); padding: 3px 4px; text-align: left; vertical-align: top; }
.ruteo-rev-det summary { cursor: pointer; margin: 8px 0 4px; font-weight: 700; color: var(--gw-texto-2); }
.ruteo-rev-det summary:focus-visible { outline: 2px solid var(--gw-verde); outline-offset: 2px; }
.ruteo-rev-notas { margin-top: 10px; }
.ruteo-rev-notas .ruteo-btn { margin-top: 4px; }
.campo-ia { background: var(--gw-aviso-fondo) !important; border-color: var(--gw-aviso-borde) !important; }
.ia-panel { background: var(--gw-blanco); border: 1px solid var(--gw-aviso-borde); border-radius: 6px; padding: 10px; margin: 8px 0; }
.ia-panel-cab { display: flex; justify-content: space-between; align-items: center; }
.ia-btn-cerrar { background: none; border: none; cursor: pointer; color: var(--gw-texto-3); padding: 2px; }
.ia-panel-ayuda { font-size: 11px; color: var(--gw-texto-3); margin: 4px 0 6px; line-height: 1.4; }
.ia-rotulo { font-size: 11px; font-weight: 700; color: var(--gw-texto-3); display: block; margin-bottom: 2px; }
.ia-texto { width: 100%; box-sizing: border-box; font-family: inherit; font-size: 12px; border: 1px solid var(--gw-borde); border-radius: 4px; padding: 6px; resize: vertical; }
.ia-panel-acciones { display: flex; gap: 6px; margin-top: 6px; }
.ia-estado { font-size: 12px; margin-top: 6px; color: var(--gw-texto-2); white-space: pre-line; }
.ia-estado-error { color: var(--gw-peligro); }
.ia-estado-ok { color: var(--gw-exito); }
.ia-rutas .ia-ruta { display: block; width: 100%; margin: 4px 0; text-align: left; }
.ia-chips { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; margin-top: 3px; }
.ia-chips-rotulo { font-size: 11px; color: var(--gw-texto-3); }
.ia-chip { font-size: 11px; padding: 2px 8px; border-radius: 10px; border: 1px solid var(--gw-aviso-borde); background: var(--gw-aviso-fondo); color: var(--gw-aviso); cursor: pointer; }
.ia-chip:focus-visible, .btn-ia:focus-visible { outline: 2px solid var(--gw-verde); outline-offset: 2px; }
.ia-borrador { display: flex; justify-content: space-between; gap: 8px; align-items: center; border-top: 1px solid var(--gw-borde); padding: 6px 0; }
.ia-borrador-acciones { display: flex; gap: 4px; }

/* ================= UTILIDADES GLOBALES ================= */
.oculto { display: none !important; }

/* T1.2 · el obligatorio que falta, marcado (color de tokens.css, como manda la regla 16) */
.campo input.campo-falta, .campo select.campo-falta, .campo textarea.campo-falta {
  border-color: var(--gw-peligro);
  box-shadow: 0 0 0 2px var(--gw-peligro-fondo);
}
/* T1.3 · "buscado en todo el historial", encima del listado */
.gw-nota-rango { font-size: 11px; color: var(--gw-texto-3); margin: 0 0 8px; }
/* T2.4 · sección plegable dentro de una tarjeta */
.gw-plegable-cab { cursor: pointer; user-select: none; display: flex; align-items: center; justify-content: space-between; }
.gw-plegable-cab:focus-visible { outline: 2px solid var(--gw-verde); outline-offset: 2px; }
.gw-plegable-flecha { font-size: 11px; color: var(--gw-texto-3); margin-left: 6px; }
/* T2.2 · el campo de gwPedir */
.gw-modal-campo { display: flex; align-items: center; gap: var(--e-2); margin-top: var(--e-3); }
.gw-modal-campo input { width: 90px; padding: 4px 6px; border: 1px solid var(--gw-borde); border-radius: 4px; font: inherit; }
.gw-modal-sufijo { color: var(--gw-texto-2); }
/* T3.1 · el «?» que abre el manual en su punto */
.gw-ayuda { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px;
  margin-left: 6px; border-radius: 50%; border: 1px solid var(--gw-borde); color: var(--gw-texto-3);
  font-size: 11px; font-weight: bold; text-decoration: none; line-height: 1; vertical-align: middle; flex: 0 0 auto; }
.gw-ayuda:hover, .gw-ayuda:focus-visible { color: var(--gw-verde); border-color: var(--gw-verde); }
/* T3.2 · la bienvenida de la primera vez */
.gw-bienvenida { margin: var(--e-3) var(--e-3) 0; padding: var(--e-3); border-radius: 6px;
  background: var(--gw-verde-tenue); border: 1px solid var(--gw-borde); font-size: 12px; color: var(--gw-texto-2); }
.gw-bienvenida-titulo { font-weight: bold; color: var(--gw-verde); margin-bottom: var(--e-2); }
.gw-bienvenida ul { margin: 0 0 var(--e-2); padding-left: 18px; }
.gw-bienvenida li { margin-bottom: 3px; }
.gw-bienvenida-ok { background: var(--gw-verde); color: #fff; border: 0; border-radius: 4px; padding: 5px 12px; cursor: pointer; font: inherit; }
#loader { text-align: center; color: var(--gw-texto-3); padding: var(--e-3); font-size: var(--t-s); font-weight: 600; }

/* ================= ESTADOS VACÍOS Y DE CARGA =================
   Los dos contenedores de resultados se quedaban literalmente vacíos: al entrar,
   tras limpiar la pantalla y cuando una búsqueda no devolvía nada. Un panel en
   blanco no distingue "no has buscado todavía" de "no hay nada" ni de "se rompió",
   y las tres cosas se arreglan de manera distinta. */
.gw-vacio {
  text-align: center;
  padding: var(--e-5) var(--e-3);
  color: var(--gw-texto-3);
}
.gw-vacio .gw-ico {
  color: var(--gw-borde-fuerte);
  margin: 0 0 var(--e-2);
}
.gw-vacio-titulo {
  margin: 0 0 var(--e-1);
  font-size: var(--t-m);
  font-weight: 700;
  color: var(--gw-texto-2);
}
.gw-vacio-cuerpo {
  margin: 0;
  font-size: var(--t-s);
  line-height: 1.55;
  max-width: 34em;
  margin-inline: auto;
}
.gw-vacio-cuerpo strong { color: var(--gw-texto); }

/* Esqueleto de carga: tres tarjetas fantasma con la silueta de las de verdad, para
   que la lista no salte de la nada. `getInitData` puede tardar más de 20 s y el
   aviso de texto suelto no daba ninguna señal de que algo estuviera pasando. */
.gw-esqueleto { padding: var(--e-1) 0; }
.gw-esq-fila {
  height: 42px;
  margin-bottom: var(--e-2);
  border: 1px solid var(--gw-borde);
  border-radius: var(--r-m);
  background: linear-gradient(100deg,
    var(--gw-superficie) 30%, var(--gw-verde-tenue) 50%, var(--gw-superficie) 70%);
  background-size: 300% 100%;
  animation: gw-latido 1.4s ease-in-out infinite;
}
.gw-esq-fila:nth-child(2) { animation-delay: .15s; }
.gw-esq-fila:nth-child(3) { animation-delay: .30s; }
@keyframes gw-latido {
  from { background-position: 150% 0; }
  to   { background-position: -150% 0; }
}

/* El botón de buscar se queda pulsado mientras dura el fetch: sin esto se puede
   volver a pulsar y lanzar dos búsquedas que compiten por el mismo contenedor. */
.gw-hilando::before {
  content: "";
  display: inline-block;
  width: 11px; height: 11px;
  margin-right: .5em;
  vertical-align: -1px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: gw-girar 700ms linear infinite;
}
@keyframes gw-girar { to { transform: rotate(360deg); } }

/* ================= BARRA DE ACCIONES =================
   Era `position: static` al final del scroll. Con una tarjeta abierta el documento pasa
   de 2.400 px, así que para guardar había que bajar hasta el fondo. Fija al pie queda
   siempre a mano, y la sombra hacia arriba deja claro que el contenido sigue debajo. */
/* Vive fuera de los paneles de pestaña, así que el relleno lateral se lo pone ella
   misma: sin esto los botones quedan pegados a los bordes del panel. */
#accionesGlobales {
  position: sticky;
  bottom: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
  margin-top: var(--e-4);
  padding: var(--e-2) var(--e-3) var(--e-3);
  background: var(--gw-fondo);
  border-top: 1px solid var(--gw-borde);
  box-shadow: var(--sombra-flotante);
}

/* Un solo botón sólido por pantalla: el que escribe en la hoja. */
.btn-primary {
  background: var(--gw-verde);
  color: #fff;
  width: 100%;
  padding: 9px;
}
.btn-primary:hover { background: var(--gw-verde-claro); }

/* "Limpiar Pantalla" descarta lo que hay en curso: se aparta del primario y baja de
   peso para que no se pulse por inercia. */
.btn-secondary {
  background: none;
  color: var(--gw-texto-3);
  width: 100%;
  font-weight: 400;
  padding: 5px;
}
.btn-secondary:hover { color: var(--gw-peligro); text-decoration: underline; }

#contenedorResultados1, #contenedorResultados2 { padding-right: 2px; }

/* ================= SCROLLBAR ================= */
::-webkit-scrollbar { width: 8px; height: 10px; }
::-webkit-scrollbar-track { background: var(--gw-superficie); border-radius: var(--r-s); }
::-webkit-scrollbar-thumb { background: #B7C3BB; border-radius: var(--r-s); }
::-webkit-scrollbar-thumb:hover { background: var(--gw-verde); }