/* ===== HFTA-X · tema verde, con modo claro y oscuro ===== */
:root {
  /* El verde de la casa. Llevaba el nombre del cliente, y ese nombre viajaba
     dentro de la hoja de estilo que se descarga: el color se queda, la marca
     no. El detalle, en el historial de git. */
  --verde: #8cc63f;
  --verde-medio: #6ba32c;
  --verde-hondo: #4e7d1e;
  --accent: #8cc63f;
  --accent2: #ffb454;
}
/* --- tema oscuro ---
   Subido un escalon entero el 23/09/2026. El anterior era casi negro
   (#10150f de fondo, #0d1108 en las casillas) y en una pantalla normal
   —no un panel bueno a oscuras— se comia las barras de probabilidad y las
   lineas de la rejilla: quedaban dos tonos de casi-negro sin contraste
   suficiente para distinguirlos.

   El verde sigue siendo el mismo, solo que con mas luz debajo. La rejilla y
   los bordes son los que mas suben, porque son justo lo que hay que VER para
   leer una grafica. */
:root, :root[data-theme="dark"] {
  --bg: #1a2118;
  --panel: #232d1f;
  --panel2: #2d3928;
  --text: #eef5e6;
  --muted: #b3c4a2;
  --border: #4a5c33;
  --ok: #a6d95f;
  --err: #ff8a8a;
  --chartgrid: #455733;
  --chartgrid0: #607845;
  --inputbg: #161d13;
}
/* --- tema claro --- */
:root[data-theme="light"] {
  --bg: #f2f5ec;
  --panel: #ffffff;
  --panel2: #f6f9ef;
  --text: #223016;
  --muted: #5d6e4a;
  --border: #cdd9b8;
  --ok: #4e7d1e;
  --err: #c0392b;
  --chartgrid: #dfe7cf;
  --chartgrid0: #b5c89e;
  --inputbg: #ffffff;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  background: var(--bg); color: var(--text);
  font: 14px/1.45 "Segoe UI", system-ui, sans-serif;
}

/* ---------- cabecera ---------- */
header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 18px; background: var(--panel);
  border-bottom: 2px solid var(--verde);
}
.brand { display: flex; flex-direction: column; }
/* fila 1: HFTA-X + versión · fila 2: descripción + firma */
.brandline { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.brandline.sub { gap: 8px; margin-top: 1px; }
header h1 { margin: 0; font-size: 20px; letter-spacing: 1px; color: var(--verde); }
/* El numero de version es un boton: al pulsarlo sale el registro de cambios
   en PDF. Se le quita todo lo que delata a un <button> —marco, fondo propio,
   tipografia del sistema— y se le deja el cursor de mano, que es la unica
   pista de que se puede pulsar. El subrayado punteado al pasar por encima
   remata la pista sin ensuciar la cabecera. */
.verchip {
  font-size: 11px; color: var(--bg); background: var(--verde);
  border-radius: 6px; padding: 1px 6px; vertical-align: middle; font-weight: 700;
  border: 0; font-family: inherit; line-height: inherit; cursor: pointer;
}
.verchip:hover { filter: brightness(1.12); text-decoration: underline dotted; }
.verchip:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }
.subtitle { color: var(--muted); font-size: 11.5px; }
.byline { color: var(--muted); font-size: 11.5px; font-style: italic; opacity: .85; }
/* El indicativo, derecho y en negrita. Va aparte de la cadena traducida
   porque un indicativo no se traduce: estaba repetido en los trece idiomas
   y era trece sitios donde equivocarse. El separador lo pone el CSS para
   que no haya que acordarse de el en cada lengua. */
.byline.indicativo { font-style: normal; font-weight: 700; opacity: 1; }
.byline.indicativo::before { content: " \00b7 "; font-weight: 400; opacity: .85; }

/* iconos sociales: contorno verde; al pasar el ratón, color original */
.social { display: flex; gap: 6px; }
.social .soc {
  width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--verde); border-radius: 6px; transition: background .15s, border-color .15s;
}
.social .soc svg { width: 17px; height: 17px; fill: none; stroke: var(--verde); stroke-width: 1.6; }
.social .soc:hover svg { fill: currentColor; stroke: none; }
.social .soc:nth-child(1):hover { color: #1877F2; border-color: #1877F2; }
.social .soc:nth-child(2):hover { color: #000; border-color: #000; background: #fff; }
.social .soc:nth-child(3):hover { color: #FF0000; border-color: #FF0000; }
:root[data-theme="dark"] .social .soc:nth-child(2):hover { color: #fff; background: #000; border-color: #fff; }
#langSel { width: auto; min-width: 120px; font-size: 12px; padding: 4px 6px; }
.headtools { display: flex; align-items: center; gap: 10px; }
/* modo reducido: se ocultan cabecera y barra superior para ganar altura útil.
   El botón de pantalla completa sigue accesible para deshacerlo. */
body.fs-lite header { padding: 3px 10px; }
body.fs-lite .brand, body.fs-lite #topbar, body.fs-lite .social { display: none; }
body.fs-lite header { justify-content: flex-end; }
.headtools .icon {
  background: var(--panel2); border: 1px solid var(--border); color: var(--text);
  border-radius: 6px; width: 32px; height: 32px; cursor: pointer; font-size: 15px;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1; padding: 0;
}
.headtools .icon:hover { border-color: var(--verde); }
.headtools a { display: inline-flex; }
/* halo alrededor del logo para que destaque sobre fondo oscuro */
/* ---------- barra superior ---------- */
#topbar {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
  padding: 5px 16px; background: var(--panel2);
  border-bottom: 1px solid var(--border); font-size: 12.5px;
}
#topbar .grp { display: flex; align-items: center; gap: 6px; }
#topbar .grp.right { margin-left: auto; }
.grplabel { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .5px; }
.badge {
  font-size: 10px; color: var(--muted); border: 1px solid var(--border);
  border-radius: 8px; padding: 1px 7px;
}
.badge.on { color: var(--bg); background: var(--verde); border-color: var(--verde); }

/* ---------- layout ---------- */
#layout { display: flex; height: calc(100vh - 46px - 34px); }

#panel {
  width: 430px; min-width: 400px; overflow-y: auto;
  background: var(--panel); border-right: 1px solid var(--border);
  padding: 10px 14px 20px;
}
#panel section {
  background: var(--panel2); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px 10px; margin-bottom: 10px;
}
#panel h2 { font-size: 13px; margin: 2px 0 8px; color: var(--verde); font-weight: 700; }
/* secciones plegables */
.collapsible > h2 { cursor: pointer; user-select: none; display: flex; align-items: center; gap: 6px; margin-bottom: 0; }
.collapsible > h2::before { content: "▸"; font-size: 11px; transition: transform .15s; }
.collapsible.open > h2::before { transform: rotate(90deg); }
.collapsible > h2:hover { filter: brightness(1.15); }
.collapsible > .secbody { display: none; padding-top: 8px; }
.collapsible.open > .secbody { display: block; }
/* El atributo `hidden` del HTML vale `display: none` en la hoja del
   navegador, que es la de MENOS peso: cualquier clase propia que ponga un
   display la gana. `.row` pone `display: flex`, asi que un `<div class="row"
   hidden>` se seguia viendo. Es un fallo silencioso de los peores, porque en
   el HTML pone `hidden` y uno lo da por hecho. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------------------------
   Utilidades: lo que antes iba en atributos `style=` dentro del HTML.

   No es cosmetica. Mientras el HTML llevara `style="..."`, la politica de
   contenidos necesitaba `style-src 'unsafe-inline'`, y esa palabra abre la
   puerta a que valga CUALQUIER estilo en linea, incluido el que meta un
   atacante. Sacando los siete que habia, la politica puede cerrarse.

   `.oculto` va SIN `!important`, al reves que `[hidden]` de arriba: hay cajas
   que el JS ensenia con `elemento.style.display = "block"`, y un estilo en
   linea puesto desde JavaScript gana a una clase pero no a un `!important`.
   --------------------------------------------------------------------------- */
.oculto { display: none; }
.verde  { color: var(--verde); }
.sep10  { margin-top: 10px; }
.sep12  { margin-top: 12px; }
.sep14  { margin-top: 14px; }

/* Estas cuatro salieron de `app.js`, que las escribia dentro de
   plantillas: `<span style="color:var(--err)">`. Igual que las de
   arriba, el motivo de sacarlas es la politica de contenidos. */
.c-aviso { color: var(--accent2); }
.c-ok    { color: var(--verde); }
.c-err   { color: var(--err); }
.sep-izq { margin-left: 10px; }

.row { display: flex; gap: 10px; margin-bottom: 6px; align-items: end; flex-wrap: wrap; }
label { display: block; font-size: 12px; color: var(--muted); flex: 1; white-space: nowrap; }
label > input, label > select { display: block; width: 100%; margin-top: 3px; }
label .rng { display: flex; align-items: center; gap: 5px; margin-top: 3px; }
label .rng input { display: block; width: 100%; margin-top: 0; }
/* las 3 alturas a comparar se rellenan solas: tienen que poder leerse */
#wH1, #wH2, #wH3 { min-width: 64px; text-align: center; }
label.chk { display: flex; flex-direction: row; align-items: center; gap: 6px; color: var(--text); white-space: normal; }
label.chk > input { display: inline-block; width: auto; margin-top: 0; }
input, select {
  background: var(--inputbg); color: var(--text); border: 1px solid var(--border);
  border-radius: 5px; padding: 5px 7px; font-size: 13px; width: 100%;
}
input:focus, select:focus { outline: none; border-color: var(--verde); }
input[type=checkbox] { width: auto; accent-color: var(--verde); }
/* control de capas de Leaflet: etiquetas legibles (no heredar el estilo del panel) */
.leaflet-control-layers label { display: flex; flex-direction: row; align-items: center;
  gap: 6px; color: #2a2a2a; white-space: nowrap; margin: 2px 0; font-size: 13px; }
.leaflet-control-layers input { width: auto; margin: 0 4px 0 0; }
.leaflet-control-layers-selector { margin-top: 0; }
.leaflet-control-layers-list { color: #2a2a2a; }
input[type=file] { padding: 3px; font-size: 11px; }
.hint { font-size: 11px; color: var(--muted); margin: 4px 0; }
.hint code { color: var(--accent2); }
.advice { font-size: 11.5px; margin: 2px 0; }
.advice .a-warn { color: var(--err); }
.advice .a-info { color: var(--accent2); }
.advice .a-ok { color: var(--ok); }

/* botón de acción propio de cada sección plegable */
.secact {
  margin-top: 10px; padding-top: 9px;
  border-top: 1px dashed var(--border);
}
.secact .act {
  width: 100%; text-align: center; line-height: 1.25; min-height: 38px;
  font-size: 13px; font-weight: 600;
}
.secact .act.primary { font-size: 13.5px; min-height: 42px; }
#buttons { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }

/* Cuenta atras debajo del boton que se acaba de pulsar.
   Debajo y no dentro del rotulo: metida en el texto, el boton cambiaba de
   ancho cada segundo y bailaba, y en los cortos el numero no cabia.
   `flex-basis: 100%` es lo que la hace caer a la linea siguiente cuando el
   contenedor es flex (.aztools, los botones del mapa); en un contenedor
   normal (.secact) ya cae sola por ser de bloque. */
/* Por defecto va EN LA MISMA LINEA que el boton. Antes llevaba `width: 100%`
   y `flex-basis: 100%`, que dentro de un contenedor flex la manda a un renglon
   propio: en la barra de los mapas eso costaba una linea entera de alto que le
   hacia falta al mapa. */
.cuentaAtras {
  font-size: 11.5px; color: var(--muted);
  font-variant-numeric: tabular-nums;   /* que no baile al cambiar de cifra */
  white-space: nowrap;
}
/* En el menu lateral SI va debajo: ahi el boton ocupa todo el ancho, asi que
   ponerla al lado no cabria. */
.secact .cuentaAtras {
  display: block; width: 100%; flex-basis: 100%;
  margin-top: 4px; text-align: center;
}

/* indicador de cálculo: círculo girando, elegante */
.spin {
  display: inline-block; width: 13px; height: 13px; margin-right: 7px;
  border: 2px solid rgba(140,198,63,.30); border-top-color: var(--verde);
  border-radius: 50%; animation: spin .7s linear infinite; vertical-align: -2px;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* el propio botón muestra su spinner mientras trabaja */
button.busy { position: relative; color: transparent !important; pointer-events: none; }
button.busy::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 15px; height: 15px;
  margin: -8px 0 0 -8px; border: 2px solid rgba(0,0,0,.25);
  border-top-color: currentColor; border-radius: 50%; animation: spin .7s linear infinite;
  color: #0c1207;
}
button.busy.act:not(.primary)::after { border-color: rgba(140,198,63,.3); border-top-color: var(--verde); }
#status.busy { color: var(--accent2); }
button {
  background: var(--panel2); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 14px; cursor: pointer; font-size: 13px;
}
button:hover { border-color: var(--verde); }
button.primary { background: var(--verde); color: #0c1207; font-weight: 700; border-color: var(--verde); }
button.primary:hover { filter: brightness(1.08); }
button.mini { padding: 4px 10px; font-size: 12px; }
button:disabled { opacity: 0.45; cursor: default; }
#status { margin-top: 8px; font-size: 12px; min-height: 18px; }
#status.err { color: var(--err); }
#status.ok { color: var(--ok); }
#status.busy { color: var(--accent2); }

/* ---------- área principal ---------- */
#main { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0; }
#mapwrap { position: relative; height: 44%; min-height: 90px; }
#map { width: 100%; height: 100%; }
#layoutToggle { display: flex; gap: 2px; background: var(--panel); border: 1px solid var(--border); border-radius: 6px; padding: 2px; }
#layoutToggle button { padding: 3px 9px; font-size: 11px; border: none; background: transparent; }
#layoutToggle button.active { background: var(--verde); color: #0c1207; border-radius: 4px; font-weight: 600; }

/* divisores arrastrables */
#vsplit { flex: 0 0 6px; cursor: col-resize; background: var(--border); }
#vsplit:hover, #vsplit.drag { background: var(--verde); }
#hsplit { flex: 0 0 6px; height: 6px; cursor: row-resize; background: var(--border); }
#hsplit:hover, #hsplit.drag { background: var(--verde); }

#tabs { display: flex; gap: 2px; background: var(--panel); padding: 4px 8px 0; flex-wrap: wrap; }
#tabs button { border-radius: 6px 6px 0 0; border-bottom: none; background: var(--panel); color: var(--muted); }
#tabs button.active { background: var(--panel2); color: var(--text); border-color: var(--verde); }
.tab { display: none; flex: 1; overflow-y: auto; padding: 10px 14px; background: var(--panel2); }
.tab.active { display: block; }

/* modos de layout */
body.layout-map #mapwrap { height: 100% !important; }
body.layout-map #tabs, body.layout-map .tab, body.layout-map #hsplit { display: none; }
body.layout-results #mapwrap, body.layout-results #hsplit { display: none; }

.chartbox { position: relative; height: 46vh; min-height: 240px; background: var(--inputbg);
  border: 1px solid var(--border); border-radius: 8px; padding: 8px; }
.chartbox.small { height: 42vh; }
.exports { margin-top: 8px; }

table.results { border-collapse: collapse; margin-top: 10px; font-size: 12.5px; width: 100%; }
table.results th, table.results td { border: 1px solid var(--border); padding: 4px 9px; text-align: left; }
table.results th { background: var(--panel); color: var(--muted); }
.swatch { display: inline-block; width: 11px; height: 11px; border-radius: 2px; margin-right: 5px; }
.big { font-size: 15px; }
#optimizeSummary .best { color: var(--ok); font-weight: 700; }
#optimizeSummary .range { color: var(--accent2); font-weight: 700; }

/* mapa azimutal */
.aztools { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
/* Barra de los mapas: cabia en cuatro lineas con mucho hueco muerto porque el
   desplegable de resolucion se estiraba a ocupar lo que sobrara. Con ancho
   fijo y un hueco elastico, la fila se lee de izquierda a derecha y los dos
   botones de la derecha quedan pegados al borde. */
.aztools.apretada { gap: 9px; margin-bottom: 6px; }
.elastico { flex: 1 1 auto; min-width: 0; }
select.anchofijo { max-width: 270px; }
/* Anchos fijos para que la barra de «Ahora» quepa en una linea: sin esto
   el campo del indicativo se estira a lo que sobre y parte la fila. */
.anchocorto { width: 88px; flex: 0 0 auto; }
select.anchomedio { width: 96px; flex: 0 0 auto; }
/* El selector de origen lleva frases, no numeros: con 96px se cortaba en
   «RBN: qu...» y no se sabia cual estaba puesto. */
select.anchofrase { width: 208px; flex: 0 0 auto; }

/* El indicador de carga, al lado de la línea de versión.
   Tres estados y nada más: verde mientras haya sitio, ámbar cuando el último
   hueco de VOACAP está cogido, y rojo sólo cuando de verdad hay cola. Un
   indicador que se pone rojo por costumbre deja de mirarse. */
.carga { margin-left: 8px; font-size: 12px; font-weight: 700;
         white-space: nowrap; border: 1px solid currentColor;
         border-radius: 4px; padding: 0 5px; color: #7aa84f; cursor: default; }
.carga.lleno { color: #ffb020; }
.carga.cola  { color: #ff3b30; }
/* El numero es de hace un rato: el servidor no contesta ahora mismo. Se
   deja puesto en vez de esconderlo, porque «no lo se» y «cero» no son lo
   mismo y un hueco se lee como que no hay nadie. */
.carga.dudoso { opacity: .45; font-style: italic; }
@media (max-width: 700px) { .carga { display: none; } }
/* La muestra de color de la leyenda de la tabla de VOACAP: el mismo
   sombreado que las celdas, en un cuadradito. */
.voaLeyenda .muestra { display: inline-block; width: 13px; height: 11px;
  border: 1px solid var(--border); border-radius: 2px;
  vertical-align: -1px; margin: 0 3px 0 9px; }
/* Los mismos cinco fondos que las celdas. Van repetidos y no heredados
   porque los de la tabla estan atados a `td.opN`, asi que en un `span`
   no pintaban nada: la leyenda salia con cinco cuadrados vacios, que es
   peor que no ponerla. Si se retoca la escala hay que tocar los dos
   sitios, y por eso estan pegados uno debajo del otro. */
.voaLeyenda .muestra.op0 { background: rgba(120,120,120,.18); }
.voaLeyenda .muestra.op1 { background: rgba(140,198,63,.20); }
.voaLeyenda .muestra.op2 { background: rgba(140,198,63,.45); }
.voaLeyenda .muestra.op3 { background: rgba(140,198,63,.75); }
.voaLeyenda .muestra.op4 { background: rgba(140,198,63,1); }
/* El chip se pulsa: abre el panel de quien ha pasado por aqui. El cursor lo
   dice, porque un recuadro con un numero no parece un boton. */
.carga { cursor: pointer; }
.carga:hover { filter: brightness(1.25); }
.visCajas { display: flex; gap: 10px; flex-wrap: wrap; margin: 14px 0; }
.visCaja { flex: 1 1 110px; text-align: center; padding: 10px 6px;
           border: 1px solid var(--border); border-radius: 6px;
           background: var(--panel2); }
.visCaja b { display: block; font-size: 26px; line-height: 1.1;
             color: var(--ok); }
.visCaja span { font-size: 12px; color: var(--muted); }
.visGrafica { height: 190px; margin: 14px 0 6px; }
/* El de resolucion: sin la palabra «Resolución» delante —el propio
   desplegable ya dice grados, circuitos y tiempo— y con ancho justo, que
   es lo que hacia que la barra no cupiera en una linea. */
select.anchores { width: 182px; flex: 0 0 auto; }

/* El deslizador de la hora. Ancho fijo y generoso: con 24 pasos, menos de
   unos 150 px hace que cada hora caiga a seis pixeles y no se pueda
   apuntar. El rotulo va en ancho fijo tambien, o la fila entera se mueve
   al pasar de «9:00» a «10:00». */
#hourRange { width: 190px; flex: 0 0 auto; accent-color: var(--verde);
  cursor: pointer; }
.horarot { color: var(--verde); font-variant-numeric: tabular-nums;
  width: 52px; display: inline-block; text-align: center; }

#ahoraMapWrap { position: relative; margin: 10px 0 4px; }
#ahoraCanvas { width: 100%; height: auto; display: block;
  border-radius: 8px; background: #0d1117; }

/* Pestania «Ahora». El aviso va arriba y bien visible a proposito: la
   diferencia entre medida y prediccion es lo unico que hay que entender
   de esta pantalla, y si no se ve, alguien va a leer estos numeros como
   si fueran un pronostico. */
.avisomedido { background: rgba(255,193,7,.10);
  border-left: 3px solid #ffc107; border-radius: 6px;
  padding: 9px 12px; margin-bottom: 12px; font-size: 13px;
  color: var(--text); }
.fichas { display: flex; gap: 10px; flex-wrap: wrap; margin: 10px 0; }
.ficha { flex: 1 1 150px; background: var(--panel2, rgba(255,255,255,.04));
  border: 1px solid var(--linea, #2a3a22); border-radius: 8px;
  padding: 9px 12px; }
.ficha .rot { font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .06em; }
.ficha .val { font-size: 19px; font-weight: 700; color: var(--verde); }
.ficha .sub { font-size: 11.5px; color: var(--muted); }
.ficha.mal .val { color: #ff7043; }
.barras { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.barras th { text-align: left; color: var(--verde); font-weight: 700;
  padding: 3px 8px; }
.barras td { padding: 3px 8px; white-space: nowrap; }
.barras td.n { text-align: right; }
/* La barra se dibuja en la propia celda: con nueve bandas, una tabla de
   numeros sueltos no dice de un vistazo cual esta abierta. */
.barras td.b { width: 100%; }
.barras .bar { height: 13px; border-radius: 3px;
  background: linear-gradient(90deg, var(--verde), #4e7d1e); }

/* Estadistica ACTUAL. La tabla puede tener 35 filas de angulo por 9 bandas,
   asi que va con su propio desplazamiento y la cabecera pegada arriba: sin
   eso hay que subir a ver que banda es cada columna. */
.estpanel { margin-top: 10px; border-top: 1px solid var(--linea, #2a3a22);
  padding-top: 8px; }
#estDetalle summary { cursor: pointer; color: var(--verde);
  font-size: 12.5px; padding: 3px 0; }
.esttabla { max-height: 260px; overflow: auto; margin-top: 6px; }
.esttabla table { border-collapse: collapse; font-size: 12px; width: 100%; }
.esttabla th, .esttabla td { padding: 2px 7px; text-align: right;
  white-space: nowrap; }
.esttabla thead th { position: sticky; top: 0; background: var(--panel);
  color: var(--verde); font-weight: 700; }
.esttabla tbody tr:nth-child(even) { background: rgba(255,255,255,.03); }
.esttabla td.ang { text-align: left; color: var(--muted); }
/* La barra dentro de la celda dice el peso de un vistazo: con 35x9 numeros
   sueltos no se ve donde esta el grueso del reparto. */
.esttabla td { background-image: linear-gradient(to right,
  rgba(140,198,63,.30) var(--p, 0%), transparent var(--p, 0%)); }
/* El sello «9/2026» al lado del rotulo: sin el, «ACTUAL» no dice de cuando
   es, que es justo lo unico que lo diferencia de la de la ARRL. */
.sello { color: var(--verde); font-weight: 700; font-size: 11.5px;
  margin-left: 4px; }

/* Pantalla completa del mapa. El navegador pinta el fondo de negro por
   defecto; se le pone el del panel para que no cante, y el lienzo crece hasta
   ocupar el alto disponible sin deformarse. */
/* Plan B cuando el navegador no deja pantalla completa de verdad: se oculta
   todo menos el mapa. `fs-lite` ya quita la cabecera; esto quita ademas las
   pestanias y los botones de informe, que en ese modo solo estorban. */
body.mapa-solo #tabs, body.mapa-solo #tab-propmap > .aztools:last-of-type { display: none; }
body.mapa-solo #propCanvas { height: calc(100vh - 150px); width: 100%; object-fit: contain; }

#mapWrap:fullscreen { background: var(--panel); padding: 10px; }
#mapWrap:fullscreen #propCanvas { width: 100%; height: calc(100vh - 20px);
  object-fit: contain; }
/* los campos de VOACAP no deben encogerse hasta ser ilegibles */
#voaTools label { flex: 0 0 auto; }
#voaTools input[type=number] { width: 84px; }
#voaPreset { min-width: 160px; }
#voaMode { min-width: 118px; }
#azWrap, #azWorldWrap { display: flex; justify-content: center; background: var(--inputbg);
  border: 1px solid var(--border); border-radius: 8px; padding: 8px; }
#azCanvas { max-width: 100%; height: auto; cursor: crosshair; }
#worldCanvas { max-width: 100%; height: auto; }
.legend { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 8px; font-size: 12px; justify-content: center; }
.legend .item { display: flex; align-items: center; gap: 5px; }
.worldgrid { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-start; }
.worldgrid .chartbox { flex: 1; min-width: 300px; }
/* rendimiento global: polar arriba, mapa azimutal (tenue) debajo, mismo eje */
#worldStack { position: relative; }
#worldStack .chartbox.small { height: 44vh; min-height: 260px; }
/* tirador para agrandar el plano bajando la tabla de resultados */
#polarGrip {
  height: 14px; margin: 3px 0 6px; cursor: ns-resize;
  display: flex; align-items: center; justify-content: center;
  border-radius: 7px; background: transparent; transition: background .15s;
}
#polarGrip span {
  display: block; width: 74px; height: 4px; border-radius: 3px;
  background: var(--border); transition: background .15s;
}
#polarGrip:hover { background: rgba(140,198,63,.08); }
#polarGrip:hover span, #polarGrip.dragging span { background: var(--verde); }
#azWorldWrap { margin-top: 12px; }
#worldCanvas { max-width: 620px; }
.polartip {
  position: fixed; pointer-events: none; z-index: 9999; display: none;
  background: #0c1207; color: #e7f0dd; border: 1px solid var(--verde);
  border-radius: 6px; padding: 4px 8px; font-size: 12px; white-space: nowrap;
}
.polartip.show { display: block; }

/* tooltip contextual */
.tooltip {
  position: fixed; z-index: 9999; max-width: 300px; pointer-events: none;
  background: #0c1207; color: #e7f0dd; border: 1px solid var(--verde);
  border-radius: 7px; padding: 7px 10px; font-size: 12px; line-height: 1.4;
  box-shadow: 0 6px 20px rgba(0,0,0,.45); opacity: 0; transition: opacity .12s;
}
.tooltip.show { opacity: 1; }

/* propagación */
.solarbox { display: flex; gap: 14px; flex-wrap: wrap; margin: 8px 0;
  background: var(--inputbg); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; }
.solarbox .sv { display: flex; flex-direction: column; }
.solarbox .sv b { color: var(--verde); font-size: 15px; }
.solarbox .sv span { color: var(--muted); font-size: 11px; }
table.prop { border-collapse: collapse; width: 100%; font-size: 11.5px; margin-top: 8px; }
table.prop th, table.prop td { border: 1px solid var(--border); padding: 3px 5px; text-align: center; }
table.prop th { background: var(--panel); color: var(--muted); }
table.prop td.reg { text-align: left; white-space: nowrap; }
td.op { font-weight: 700; }
td.op0 { background: rgba(120,120,120,.18); color: var(--muted); }
td.op1 { background: rgba(140,198,63,.20); }
td.op2 { background: rgba(140,198,63,.45); }
td.op3 { background: rgba(140,198,63,.75); color: #0c1207; }
td.op4 { background: rgba(140,198,63,1); color: #0c1207; font-weight: 700; }
#btnVoaPick.active { background: var(--verde); color: #0c1207; font-weight: 600; }

/* mapas de propagación */
.btngroup { display: flex; gap: 3px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 6px; padding: 3px; }
.btngroup.wrap { flex-wrap: wrap; max-width: 100%; }
.btngroup button { padding: 3px 8px; font-size: 11.5px; border: none; background: transparent; min-width: 30px; }
.btngroup button.active { background: var(--verde); color: #0c1207; border-radius: 4px; font-weight: 700; }
#mapWrap { position: relative; background: var(--inputbg); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px; margin-top: 8px; }
#propCanvas { width: 100%; height: auto; display: block; }
.maplegend { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: 11px; color: var(--muted); flex-wrap: wrap; }
.maplegend .ramp { display: inline-block; width: 190px; height: 11px; border-radius: 3px;
  border: 1px solid var(--border);
  background: linear-gradient(90deg,#b3e0ff,#6fd3e8,#4cd97b,#d8e84a,#ffb454,#ff6b3d,#e5352b); }

/* modal explicativo */
.modal { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: none; z-index: 10000; }
.modal.show { display: flex; align-items: center; justify-content: center; }
.modalbox { position: relative; background: var(--panel); color: var(--text);
  border: 1px solid var(--verde); border-radius: 10px; max-width: 860px; width: 92%;
  max-height: 86vh; overflow-y: auto; padding: 22px 26px; }
.modalbox h3 { color: var(--verde); margin: 16px 0 6px; font-size: 15px; }
.modalbox h2 { color: var(--verde); margin: 0 0 8px; font-size: 19px; }
.modalbox p, .modalbox li { font-size: 13px; line-height: 1.55; }
.modalbox table { border-collapse: collapse; width: 100%; font-size: 12px; margin: 8px 0; }
.modalbox th, .modalbox td { border: 1px solid var(--border); padding: 4px 8px; text-align: left; }
.modalbox th { background: var(--panel2); color: var(--muted); }
.modalbox .warnbox { background: rgba(255,180,84,.14); border-left: 4px solid var(--accent2);
  padding: 8px 12px; border-radius: 4px; margin: 10px 0; }
.modalclose { position: absolute; top: 10px; right: 12px; padding: 3px 10px; }
/* navegador de carpetas */
.fsbar { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0; }
.fslist { list-style: none; margin: 0; padding: 0; max-height: 46vh; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 6px; background: var(--inputbg); }
.fslist li { padding: 5px 10px; cursor: pointer; font-size: 13px; border-bottom: 1px solid var(--border); }
.fslist li:hover { background: rgba(140,198,63,.18); }

.leaflet-container { background: #cfe0bd; }

/* barras de desplazamiento verdes y finas */
* { scrollbar-width: thin; scrollbar-color: var(--verde-medio) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--verde-medio); border-radius: 8px;
  border: 2px solid transparent; background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--verde); border: 2px solid transparent; background-clip: padding-box;
}
::-webkit-scrollbar-corner { background: transparent; }

/* =========================================================== segunda torre
   El bloque de T2 va dentro de la sección 1 y se abre con la casilla. Se
   marca con una barra al margen para que se vea de un vistazo que todo lo
   que hay dentro es de la OTRA torre y no de la principal. */
#t2box {
  margin: 6px 0 2px; padding: 6px 0 2px 10px;
  border-left: 3px solid var(--accent2);
}

/* El marcador de T2 en el mapa. El de T1 es la chincheta de siempre; este es
   un disco naranja con el rótulo dentro, para no confundirlos ni depender de
   un icono de imagen que haya que servir aparte. */
.t2marker { background: none; border: 0; }
.t2pin {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent2); color: #1a1a1a;
  font: 700 11px/23px system-ui, sans-serif; text-align: center;
  border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, .55);
  cursor: grab;
}

/* El selector de torre de las pestañas que son por posición. Va al final de
   la fila de pestañas, empujado a la derecha, para que no parezca una más. */
.vistaTorre {
  margin-left: auto; display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--muted); padding: 0 6px 4px;
}
.vistaTorre select { padding: 2px 6px; }

/* Los avisos que no son errores pero que hay que leer antes de creerse un
   número. Se distinguen del resto de `.hint`, que son explicaciones. */
.hint.aviso {
  color: var(--accent2); border-left: 3px solid var(--accent2);
  padding-left: 8px; margin: 4px 0;
}

/* La tabla que compara T1 con T2 en el optimizador. La fila que gana va
   marcada: si hay que buscar el número más grande a ojo, la tabla no está
   haciendo su trabajo. */
table.results.cmp td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.results.cmp tr.gana { background: rgba(140, 198, 63, .14); }
table.results.cmp tr.gana td:first-child { color: var(--accent); font-weight: 700; }
table.results.cmp tr.gana td:first-child::after { content: " \2714"; }

/* ===================================== los tramos de suelo de la trayectoria */
#tramosSuelo:empty { display: none; }
.tramo {
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
  margin: 4px 0; padding: 4px 0 4px 8px;
  border-left: 3px solid var(--agua);
}
.tramo input[type=number] { width: 80px; }
.tramo select { flex: 1 1 130px; min-width: 110px; }
.tramo .quitar {
  padding: 2px 8px; line-height: 1.2; color: var(--err);
  border-color: var(--err); background: transparent;
}
/* El azul del agua. En claro se apaga, que sobre blanco un azul saturado
   compite con las curvas del diagrama y aqui solo hace de fondo. */
/* Dos azules: el mar y el agua dulce. Se distinguen porque en un perfil
   pueden salir los dos --un embalse tierra adentro y el mar al fondo-- y
   pintarlos igual seria decir que son lo mismo cuando tienen constantes
   distintas y el mar ademas se nivela y el embalse no. */
:root, :root[data-theme="dark"] {
  --agua: #58a6ff; --aguaDulce: #4dd0c7;
}
:root[data-theme="light"] {
  --agua: #2b6cb0; --aguaDulce: #16897f;
}

/* El fallo del optimizador, justo debajo de su boton. En rojo y con la barra
   a la izquierda, como los avisos, para que se vea que es algo que leer y no
   una explicación más. */
.hint.error {
  color: var(--err); border-left: 3px solid var(--err);
  padding-left: 8px; margin: 6px 0; font-size: 12px;
}

/* Lo que se ha encontrado de agua: en azul, el mismo del mapa y de la linea,
   para que se lea como «esto es lo que hay pintado ahi». */
.hint.agua {
  color: var(--agua); border-left: 3px solid var(--agua);
  padding-left: 8px; margin: 4px 0;
}

