/* =========================================================================
   HUD de misión (encima del canvas)
   ========================================================================= */
.mission-hud{ position:absolute; inset:0; pointer-events:none; z-index:10; }
.mission-fx{ position:absolute; inset:0; pointer-events:none; z-index:11; overflow:hidden; }

/* Barra superior de la misión */
.mh-top{
  position:absolute; top:calc(var(--safe-t) + 8px); left:10px; right:10px;
  display:flex; align-items:center; gap:8px; pointer-events:auto;
}
.mh-pause{
  width:34px; height:34px; flex:0 0 34px; border-radius:10px; font-size:15px;
  background:rgba(10,14,28,.8); border:1px solid var(--stroke); color:var(--tx-mid);
}
.mh-progress{ flex:1; position:relative; height:12px; border-radius:99px; background:rgba(3,6,14,.8); border:1px solid var(--stroke); overflow:hidden; }
.mh-progress i{ display:block; height:100%; background:var(--g-primary); box-shadow:var(--glow-blue); transition:width .2s linear; }
.mh-progress .flag{
  position:absolute; top:-3px; width:2px; height:18px; background:rgba(255,255,255,.4);
}
.mh-progress .boss-flag{ right:0; width:4px; background:var(--bad); box-shadow:0 0 8px var(--bad); }
.mh-stage{ font-size:12px; font-weight:800; color:var(--tx-mid); white-space:nowrap; }

/* Contador de tropa: gigante y satisfactorio */
.mh-army{
  position:absolute; top:calc(var(--safe-t) + 30px); left:50%; transform:translateX(-50%);
  display:flex; flex-direction:column; align-items:center; gap:2px;
}
.mh-army .n{
  font-size:44px; font-weight:900; line-height:1; letter-spacing:1px;
  color:#fff; text-shadow:0 0 18px rgba(57,255,136,.65), 0 3px 0 rgba(0,0,0,.6);
  font-variant-numeric:tabular-nums;
}
.mh-army .n.bump{ animation:armyBump .28s var(--ease-back); }
.mh-army .n.down{ animation:armyDown .3s var(--ease-out); }
@keyframes armyBump{ 0%{transform:scale(1)} 40%{transform:scale(1.42); color:var(--c-neon)} 100%{transform:scale(1)} }
@keyframes armyDown{ 0%{transform:scale(1)} 40%{transform:scale(.78); color:var(--bad)} 100%{transform:scale(1)} }
.mh-army .lb{ font-size:9.5px; letter-spacing:3px; color:var(--tx-lo); text-transform:uppercase; }

/* Buffs activos */
.mh-buffs{
  position:absolute; top:calc(var(--safe-t) + 96px); left:10px;
  display:flex; flex-direction:column; gap:5px;
}
.buff{
  display:flex; align-items:center; gap:5px; padding:3px 9px 3px 4px; border-radius:99px;
  background:rgba(10,14,28,.82); border:1px solid var(--stroke); font-size:11px; font-weight:800;
  animation:buffIn .35s var(--ease-back);
}
.buff .bi{ width:18px; height:18px; border-radius:50%; display:grid; place-items:center; font-size:11px; background:var(--g-primary); }
.buff.neon{ border-color:var(--stroke-hot); color:var(--c-neon); }
@keyframes buffIn{ from{opacity:0; transform:translateX(-24px)} }

/* Jefe */
.mh-boss{
  position:absolute; top:calc(var(--safe-t) + 54px); left:14%; right:14%;
  display:none; flex-direction:column; gap:3px; align-items:center;
}
.mh-boss.on{ display:flex; animation:bossIn .5s var(--ease-back); }
/*
 * Con jefe en pantalla el contador de tropa baja para no quedar debajo del
 * rótulo. Se mueve el contador y no el panel del jefe porque a la izquierda, a
 * la altura donde habría que llevarlo, ya viven los buffs (`.mh-buffs`, a
 * +96 px), y la barra de vida ocupa del 14 % al 86 % del ancho: se pisarían.
 * La transición evita que el número pegue un salto al aparecer el jefe.
 */
.mh-army{ transition:top .32s var(--ease-out); }
/* 68 px: el panel ya no lleva nombre ni barra de vida —se fueron a la barra
   flotante del jefe—, así que sólo hay que despejar el reloj. Con los 94 px de
   antes quedaba un hueco muerto. */
.mission-hud.boss-on .mh-army{ top:calc(var(--safe-t) + 68px); }
@keyframes bossIn{ from{opacity:0; transform:translateY(-20px) scale(.85)} }

/* =========================================================================
   HABILIDADES DEL HÉROE · el dique de la esquina
   ------------------------------------------------------------------------
   El botón vivía en la esquina y las dos barras del pie —definitiva y ADN—
   cruzaban la pantalla enteras por debajo, así que les caía encima. No era sólo
   feo: la parte tapada de la barra de la definitiva es justo la que dice cuánto
   falta para poder usarla.

   `--dique` es el ancho que este bloque se reserva, y las barras lo restan de
   su lado derecho. Así el tamaño del botón y el recorte de las barras salen del
   MISMO número: cambiar uno reajusta lo otro solo, en vez de tres valores que
   hay que acordarse de mover a la vez.
   ========================================================================= */
:root{
  --lado-skill:50px;                        /* era 56: algo más pequeño */
  --dique:calc(var(--lado-skill) + 20px);   /* botón + margen a los dos lados */
}
.mh-skills{
  position:absolute; right:10px; bottom:calc(var(--safe-b) + 18px);
  display:flex; flex-direction:column; gap:9px; pointer-events:auto;
  z-index:30;
}
.skill-btn{
  position:relative; width:var(--lado-skill); height:var(--lado-skill);
  border-radius:15px; font-size:21px;
  background:linear-gradient(160deg,#2A3A72,#131A38); border:1.5px solid var(--stroke);
  display:grid; place-items:center; box-shadow:var(--sh-2);
  transition:transform var(--t-fast) var(--ease-back);
}
.skill-btn:active{ transform:scale(.9); }
.skill-btn.ready{ border-color:var(--c-neon); box-shadow:var(--glow-neon); }
/*
 * EL LATIDO, POR `opacity`. Ver la nota de `navBig` en holo.css.
 *
 * Éste importa el doble: corre DURANTE EL COMBATE, cuando el hilo ya está
 * ocupado con el juego. Animar `box-shadow` repinta el botón y su halo en cada
 * fotograma; `opacity` no repinta nada.
 *
 * `::after` y no `::before` porque el velo de recarga del botón ya ocupa una
 * capa propia con `inset:0` — se comprobó que no hay ningún pseudo-elemento
 * declarado sobre `.skill-btn`.
 */
.skill-btn.ready::after{
  content:""; position:absolute; inset:0;
  border-radius:inherit; pointer-events:none;
  box-shadow:0 0 26px rgba(57,255,136,.85);
  animation:skillReady 1.6s ease-in-out infinite;
}
@keyframes skillReady{ 0%,100%{ opacity:.47 } 50%{ opacity:1 } }
.skill-btn .cd{
  position:absolute; inset:0; border-radius:inherit; background:rgba(3,6,14,.72);
  display:grid; place-items:center; font-size:15px; font-weight:900; color:#fff;
}

/* =========================================================================
   BARRA DE DEFINITIVA
   Se carga sola y con las bajas. Al llenarse cambia de estado y pide el gesto
   explícitamente: el jugador ya tiene el dedo en la pantalla, sólo hay que
   decirle que lo levante.
   ========================================================================= */
.mh-ult{
  /*
   * MARGEN SIMÉTRICO: el dique se descuenta por LOS DOS LADOS.
   *
   * El primer intento recortaba sólo por la derecha (`left:14px`), que despeja
   * el botón pero deja la barra descentrada respecto a la pantalla — y esta
   * barra está bajo un contador de tropa centrado y una formación centrada, así
   * que el desvío canta. Quitando lo mismo a cada lado se conserva el eje y se
   * paga con un poco de anchura, que aquí no importa.
   */
  position:absolute; left:var(--dique); right:var(--dique); bottom:calc(var(--safe-b) + 74px);
  display:flex; flex-direction:column; align-items:center; gap:5px;
  pointer-events:none;
}
.mh-ult .ulabel{
  font-size:10px; letter-spacing:2.4px; text-transform:uppercase;
  color:var(--tx-lo); transition:color var(--t-mid), text-shadow var(--t-mid);
  /*
   * CONTORNO OSCURO PERMANENTE, no un color más claro.
   *
   * El rótulo se perdía «en algunos niveles»: su color es fijo y el fondo no
   * —cada bioma trae su cielo, y sobre el naranja del volcánico o el verde de
   * la selva un gris medio desaparece—. Aclararlo lo arreglaría en esos dos y
   * lo rompería en los claros.
   *
   * Con una sombra negra cerrada alrededor se lee sobre CUALQUIER fondo sin
   * tocar su color, que es el que comunica el estado de la definitiva (gris =
   * cargando, verde = lista, ámbar = disparando) y por tanto no puede cambiarse
   * por motivos de legibilidad.
   */
  text-shadow:
    0 1px 3px rgba(0,0,0,.95),
    0 0 6px rgba(0,0,0,.85),
    0 0 2px rgba(0,0,0,1);
}
.mh-ult .ubar{
  position:relative; width:100%; height:11px; border-radius:99px; overflow:hidden;
  background:rgba(3,6,14,.85); border:1px solid var(--stroke);
}
.mh-ult .ubar i{
  display:block; height:100%; width:0;
  background:linear-gradient(90deg,#12A455,#39FF88);
  transition:width .18s linear;
}
.mh-ult .ushine{
  position:absolute; inset:0; opacity:0;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent);
}

/* Cargada: la barra late y el rótulo pide el gesto */
.mh-ult.ready .ulabel{ color:var(--c-neon); text-shadow:0 0 12px rgba(57,255,136,.8); }
.mh-ult.ready .ubar{
  border-color:var(--c-neon);
  animation:ultPulse 1.05s ease-in-out infinite;
}
.mh-ult.ready .ubar i{ background:linear-gradient(90deg,#39FF88,#A8FFCB,#39FF88); }
.mh-ult.ready .ushine{ opacity:1; animation:ultShine 1.05s linear infinite; }
@keyframes ultPulse{
  0%,100%{ box-shadow:0 0 0 0 rgba(57,255,136,.55) }
  60%{ box-shadow:0 0 0 10px rgba(57,255,136,0) }
}
@keyframes ultShine{ from{ transform:translateX(-110%) } to{ transform:translateX(110%) } }

/* Disparando */
.mh-ult.firing .ulabel{ color:#FFF3C4; text-shadow:0 0 14px rgba(255,243,196,.9); }
.mh-ult.firing .ubar{ border-color:#FFF3C4; animation:none; }
.mh-ult.firing .ubar i{ background:linear-gradient(90deg,#FFB020,#FFF3C4); }

@media (prefers-reduced-motion: reduce){
  .mh-ult.ready .ubar, .mh-ult.ready .ushine{ animation:none }
}

/* Indicador de arrastre */
.mh-hint{
  position:absolute; bottom:calc(var(--safe-b) + 30px); left:50%; transform:translateX(-50%);
  font-size:11.5px; letter-spacing:2px; text-transform:uppercase; color:rgba(255,255,255,.6);
  padding:6px 16px; border-radius:99px; background:rgba(3,6,14,.6); border:1px solid var(--stroke);
  animation:hintPulse 2s ease-in-out infinite;
}
@keyframes hintPulse{ 0%,100%{opacity:.45} 50%{opacity:1} }

/* Texto grande de anuncio (OLEADA 3, ¡JEFE!, etc.) */
.mh-shout{
  position:absolute; top:38%; left:0; right:0; text-align:center;
  font-size:30px; font-weight:900; letter-spacing:5px; text-transform:uppercase;
  color:#fff; text-shadow:0 0 24px rgba(46,107,255,.9), 0 4px 0 rgba(0,0,0,.5);
  animation:shout 1.5s var(--ease-out) forwards; pointer-events:none;
}
@keyframes shout{
  0%{ opacity:0; transform:scale(2.4); letter-spacing:24px; }
  22%{ opacity:1; transform:scale(1); letter-spacing:5px; }
  74%{ opacity:1; }
  100%{ opacity:0; transform:scale(1.1); }
}

/* Flash de pantalla */
.mh-flash{ position:absolute; inset:0; background:#fff; opacity:0; pointer-events:none; }
.mh-flash.on{ animation:flashHit .22s ease-out; }
@keyframes flashHit{ from{opacity:.5} to{opacity:0} }

/* Viñeta de daño */
.mh-vignette{
  position:absolute; inset:0; pointer-events:none; opacity:0;
  background:radial-gradient(ellipse at center, transparent 45%, rgba(255,45,85,.55) 100%);
}
.mh-vignette.on{ animation:vig .5s ease-out; }
@keyframes vig{ 0%{opacity:1} 100%{opacity:0} }

/* Combo / multiplicador de kills */
.mh-combo{
  position:absolute; top:calc(var(--safe-t) + 150px); right:12px; text-align:right;
}
.mh-combo .cx{
  font-size:26px; font-weight:900; font-style:italic;
  color:var(--cc, var(--warn));
  text-shadow:0 0 14px var(--cg, rgba(255,197,61,.7));
  transition:font-size .18s var(--ease-back), color .2s;
}
.mh-combo .cl{ font-size:9px; letter-spacing:2px; color:var(--tx-lo); text-transform:uppercase; }
/*
 * EL NOMBRE DEL TRAMO, encima del número.
 *
 * Es lo que hace que la racha se recuerde: «MASACRE» se cuenta luego, «x50» no.
 * Los umbrales son los mismos que anuncia el motor por voz (ver `COMBO_HITOS`
 * en `game/mission.js`), así que lo que se oye y lo que se lee coinciden.
 */
.mh-combo .cn{
  font-size:10px; font-weight:900; letter-spacing:2.4px; font-style:italic;
  text-transform:uppercase; color:var(--cc, var(--warn));
  text-shadow:0 0 10px var(--cg, rgba(255,197,61,.55));
}
/* Escala de calor: ámbar → verde → cian → violeta → rojo. El rojo se reserva
   para el último tramo; usarlo antes le quita el sitio a lo verdaderamente
   raro, y en este juego el rojo ya significa peligro. */
.mh-combo.t0{ --cc:#FFC53D; --cg:rgba(255,197,61,.55); }
.mh-combo.t1{ --cc:#39FF88; --cg:rgba(57,255,136,.6); }
.mh-combo.t2{ --cc:#55E6FF; --cg:rgba(85,230,255,.65); }
.mh-combo.t3{ --cc:#C4A6FF; --cg:rgba(196,166,255,.7); }
.mh-combo.t4{ --cc:#FF8A3D; --cg:rgba(255,138,61,.8); }
.mh-combo.t5{ --cc:#FF4D6D; --cg:rgba(255,77,109,.9); }
/* El número crece con el tramo: la racha se lee sin leer la cifra. */
.mh-combo.t2 .cx{ font-size:30px; }
.mh-combo.t3 .cx{ font-size:34px; }
.mh-combo.t4 .cx{ font-size:38px; }
.mh-combo.t5 .cx{ font-size:42px; }

/* Tirón por baja: la racha «respira» en vez de quedarse quieta subiendo. */
.mh-combo .cx.late{ animation:comboLate .22s var(--ease-out); }
@keyframes comboLate{ 0%{ transform:scale(1.28) } 100%{ transform:scale(1) } }
/* A partir de MASACRE el rótulo palpita solo: la racha ya es un suceso. */
.mh-combo.t3 .cn, .mh-combo.t4 .cn, .mh-combo.t5 .cn{ animation:comboPulso 1s ease-in-out infinite; }
@keyframes comboPulso{ 0%,100%{ opacity:1 } 50%{ opacity:.45 } }

@media (prefers-reduced-motion: reduce){
  .mh-combo .cx.late{ animation:none; }
  .mh-combo .cn{ animation:none !important; }
}

/* Botón de continuar / recoger */
.mh-bottom{
  position:absolute; left:10px; right:10px; bottom:calc(var(--safe-b) + 10px);
  pointer-events:auto; display:flex; gap:8px;
}

/* Números de daño flotantes (DOM sólo para críticos grandes) */
.dmg{
  position:absolute; font-size:15px; font-weight:900; pointer-events:none;
  text-shadow:0 2px 4px rgba(0,0,0,.8); will-change:transform,opacity;
}
.dmg.crit{ font-size:22px; color:var(--warn); }

/* ---------- CARRERA DE DAÑO (Súper Jefe) ----------
   Sustituye a la barra de vida cuando el jefe no está pensado para morir: se
   LLENA hacia el último tramo de premio en vez de vaciarse. Ver ui/hud.js. */
/* LAS DOS BARRAS, no una en lugar de otra.
   La primera versión escondía la vida del jefe y dejaba sólo la de carrera, y
   el resultado fue peor que el problema: «el boss no tiene barra de vida». La
   vida del coloso es información real —dice si va a caer— y quitarla deja al
   jugador sin saber contra qué pelea. La de carrera se AÑADE debajo, más fina
   y con su rótulo, porque miden cosas distintas: una, lo que le queda al jefe;
   otra, lo que te llevas tú. */
.mh-duelo{ display:none; }
.mh-boss.duelo-on .mh-duelo{ display:flex; align-items:center; gap:8px; margin-top:3px; }
.mh-duelo .et{
  font-size:8.5px; letter-spacing:1.4px; text-transform:uppercase;
  color:var(--tx-lo); white-space:nowrap;
}
.bar.duelo{
  position:relative; flex:1; height:9px; border-radius:99px; overflow:visible;
  background:rgba(5,7,15,.75); border:1px solid rgba(255,61,127,.45);
}
.bar.duelo > i{
  display:block; height:100%; border-radius:99px;
  background:linear-gradient(90deg,#FF3D7F,#FFD34E);
  box-shadow:0 0 12px rgba(255,61,127,.7);
  transition:width .25s linear;
}
/* Marcas de los tramos. Sin ellas la barra sube pero no dice HACIA QUÉ: el
   jugador no sabe si va bien hasta que termina el intento. */
.bar.duelo .marcas{ position:absolute; inset:0; pointer-events:none; }
.bar.duelo .marcas b{
  position:absolute; top:-3px; width:2px; height:18px; margin-left:-1px;
  background:rgba(255,255,255,.45); border-radius:1px;
}
.bar.duelo .marcas b.ok{ background:var(--c-neon); box-shadow:0 0 8px var(--c-neon); }
.mh-duelo .pct{
  min-width:52px; text-align:right; font-size:13px; font-weight:900;
  font-variant-numeric:tabular-nums; color:#FFD34E;
  text-shadow:0 1px 4px rgba(0,0,0,.9);
}
.mh-duelo .pct.meta{ color:var(--c-neon); }

/* Cuenta atrás del duelo. Sin ella el intento se cortaba de golpe: el jugador
   peleaba contra un jefe con vida de sobra y le saltaba la pantalla de final
   sin previo aviso. Un límite de tiempo que no se ve no es una regla. */
.mh-reloj{ display:none; }
.mh-boss.duelo-on .mh-reloj{
  display:block; margin-top:4px; text-align:center;
  font-size:15px; font-weight:900; font-variant-numeric:tabular-nums;
  color:var(--tx-mid); text-shadow:0 1px 4px rgba(0,0,0,.9);
}
.mh-boss.duelo-on .mh-reloj.urgente{
  color:#FF3D7F; animation:relojUrge .7s var(--ease-out) infinite;
}
@keyframes relojUrge{ 0%,100%{ transform:scale(1) } 50%{ transform:scale(1.18) } }

/* =========================================================================
   MINI ACELERACIÓN / TURBO BOOST HUD WIDGET
   ========================================================================= */
.mh-turbo-boost {
  position: absolute;
  /* Se apoya justo encima de la barra de ADN (que está en calc(var(--safe-b) + 110px)) */
  bottom: calc(var(--safe-b) + 132px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: auto;
  z-index: 25;
  cursor: pointer;
  user-select: none;
}
.turbo-track {
  position: relative;
  width: 160px;
  height: 24px;
  background: rgba(8, 14, 28, 0.88);
  border: 1.5px solid rgba(0, 240, 255, 0.4);
  border-radius: 99px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.6), 0 0 10px rgba(0, 240, 255, 0.2);
  transition: transform 0.15s ease, border-color 0.2s ease;
}
.turbo-track.ready {
  border-color: #00F0FF;
  box-shadow: 0 0 18px rgba(0, 240, 255, 0.5), 0 4px 14px rgba(0, 0, 0, 0.6);
  animation: turboPulse 1.6s ease-in-out infinite;
}
.turbo-track.active {
  border-color: #FFD34E;
  box-shadow: 0 0 24px rgba(255, 211, 78, 0.8), 0 0 12px #00F0FF;
  animation: turboFlash 0.3s ease-in-out infinite alternate;
}
.turbo-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 100%;
  background: linear-gradient(90deg, #0077FF, #00F0FF);
  transition: width 0.1s linear;
  opacity: 0.8;
}
.turbo-track.ready .turbo-fill {
  background: linear-gradient(90deg, #00E5FF, #39FF88);
  opacity: 0.95;
}
.turbo-track.active .turbo-fill {
  background: linear-gradient(90deg, #FF9900, #FFE57F);
  opacity: 1;
}
.turbo-txt {
  position: relative;
  z-index: 2;
  font-size: 10px;
  font-weight: 900;
  color: #fff;
  letter-spacing: 0.6px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9);
  text-transform: uppercase;
}
@keyframes turboPulse {
  0%, 100% { transform: scale(1); filter: brightness(1); }
  50% { transform: scale(1.04); filter: brightness(1.2); }
}
@keyframes turboFlash {
  0% { transform: scale(1.02); filter: brightness(1.1); }
  100% { transform: scale(1.08); filter: brightness(1.4); }
}
