/* ============================================================================
   Battle HUD
   ----------------------------------------------------------------------------
   The field is a canvas; this is everything drawn over it. Three bands:

     top     who is winning, and how long is left
     middle  nothing — the fight owns it
     bottom  the squad's rage, and the controls, where a thumb already is

   Depends on tokens.css and kit.css.
   ========================================================================== */

/* Exactly one screen tall, and it does not scroll.
   It had no height at all, so the canvas — `flex: 1 1 auto` with no basis —
   took its attribute height and grew to 750px inside a 553px viewport at
   360x640. The bottom third of the field, which is where the front rank
   stands, was simply below the fold, and the page scrolled to reach it. */
.battle-screen {
  position: relative;
  overflow: hidden;
  height: 100%;
  display: flex;
}

/* --- top band ------------------------------------------------------------- */

.bt-top {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: var(--z-hud);
  padding: max(var(--s2), env(safe-area-inset-top)) var(--s3) var(--s3);
  display: grid;
  gap: var(--s2);
  background: linear-gradient(180deg, rgba(5, 7, 13, 0.92) 0%, rgba(5, 7, 13, 0.64) 68%, transparent 100%);
  pointer-events: none;
}
.bt-top > * { pointer-events: auto; }

.bt-top-row { display: flex; align-items: center; gap: var(--s2); }

.bt-top .kit-btn.icon.sm {
  width: 38px;
  height: 38px;
  min-width: 38px;
  min-height: 38px;
}
/* The visual button is 38px but the hit area stays at the 48dp floor. */
.bt-top .kit-btn.icon.sm::before {
  content: '';
  position: absolute;
  inset: -5px;
}

.bt-title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-display);
  font-size: var(--fz-body);
  color: var(--text-cream);
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.7);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The clock sits in its own carved frame so it reads as an instrument. */
.bt-clock-frame {
  display: grid;
  place-items: center;
  min-width: 62px;
  padding: 3px 10px;
  border-radius: var(--rad-sm);
  border: 2px solid var(--gold-800);
  background: var(--panel-sunken);
  box-shadow: var(--carve), 0 2px 0 rgba(0, 0, 0, 0.5);
}
.bt-clock { font-size: var(--fz-body); color: var(--gold-200); }
.bt-clock.warn { color: var(--warn); }
.bt-clock.danger { color: var(--alert); animation: bt-pulse 900ms var(--ease-out) infinite; }
@keyframes bt-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

/* Two bars facing each other across the centre. Which side is losing has to
   be answerable without reading anything. */
.bt-teams {
  display: grid;
  grid-template-columns: auto 1fr 1fr auto;
  align-items: center;
  gap: 6px;
}

.bt-team-label {
  font-size: var(--fz-tiny);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.bt-team-label.right { text-align: right; }

.bt-teambar {
  position: relative;
  height: 13px;
  border-radius: var(--rad-pill);
  background: rgba(4, 6, 11, 0.88);
  box-shadow: var(--carve), inset 0 0 0 1px rgba(255, 255, 255, 0.12);
  overflow: hidden;
}

.bt-teambar i {
  position: absolute;
  top: 0;
  bottom: 0;
  display: block;
  border-radius: inherit;
  transition: width 120ms linear;
}

/* The trail drains behind the fill, so damage is seen leaving. */
.bt-teambar-trail { background: rgba(255, 252, 245, 0.55); }
.bt-teambar-fill::after {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 4px;
  border-radius: inherit;
  background: rgba(255, 255, 255, 0.3);
}

.bt-teambar.ally i { left: 0; }
.bt-teambar.ally .bt-teambar-fill { background: linear-gradient(180deg, #7df09a, #27923f); }
.bt-teambar.foe i { right: 0; }
.bt-teambar.foe .bt-teambar-fill { background: linear-gradient(180deg, #ff7f76, #a3241c); }

/* --- bottom band ---------------------------------------------------------- */

.bt-bottom {
  position: absolute;
  inset: auto 0 0 0;
  z-index: var(--z-hud);
  display: grid;
  gap: var(--s2);
  padding: var(--s3) var(--s3) max(var(--s3), env(safe-area-inset-bottom));
  background: linear-gradient(0deg, rgba(5, 7, 13, 0.94) 0%, rgba(5, 7, 13, 0.7) 62%, transparent 100%);
}

/* --- rage orbs ------------------------------------------------------------ */

.bt-orbs {
  display: grid;
  grid-auto-flow: column;
  justify-content: center;
  gap: var(--s2);
}

.bt-orb {
  position: relative;
  width: 54px;
  height: 54px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  --rage: 0deg;
}
/* 54px visual, 48dp floor honoured by the element itself. */

/* The rage meter is the ring: a conic sweep that fills clockwise. */
.bt-orb-ring {
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  background:
    conic-gradient(from 180deg, var(--info) 0deg, var(--info) var(--rage), rgba(8, 11, 18, 0.85) var(--rage));
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.55);
}

.bt-orb-face {
  position: absolute;
  inset: 2px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--ink-800);
  box-shadow: inset 0 0 0 2px rgba(6, 8, 14, 0.9);
}
.bt-orb-face .portrait {
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 50%;
}
.bt-orb-face .portrait-img { width: 100%; height: 100%; object-fit: cover; }
.bt-orb-face .portrait-faction { display: none; }

/* A thin health read under the portrait, so the orb answers both questions. */
.bt-orb-hp {
  position: absolute;
  left: 11px;
  right: 11px;
  bottom: -1px;
  height: 4px;
  border-radius: var(--rad-pill);
  background: rgba(4, 6, 11, 0.9);
  overflow: hidden;
}
.bt-orb-hp > i {
  display: block;
  height: 100%;
  background: linear-gradient(180deg, #7df09a, #27923f);
  transition: width 120ms linear;
}

/* Full rage: the ring goes gold, the orb lifts and shakes, and it becomes
   worth tapping. */
.bt-orb.is-full .bt-orb-ring {
  background: conic-gradient(from 180deg, var(--gold-200) 0deg, var(--gold-300) 360deg);
  box-shadow: 0 0 14px 2px rgba(255, 196, 92, 0.6), 0 2px 5px rgba(0, 0, 0, 0.55);
}
.bt-orb.is-full { animation: bt-ready 1.5s var(--ease-out) infinite; }
@keyframes bt-ready {
  0%, 72%, 100% { transform: translateY(0) rotate(0deg); }
  78% { transform: translateY(-4px) rotate(-3deg); }
  84% { transform: translateY(-4px) rotate(3deg); }
  90% { transform: translateY(0) rotate(0deg); }
}

.bt-orb.is-down { filter: grayscale(1) brightness(0.5); }
.bt-orb.is-down .bt-orb-ring { background: rgba(8, 11, 18, 0.85); box-shadow: none; }

/* --- controls ------------------------------------------------------------- */

.bt-controls {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--s2);
}

.bt-ctl { min-width: 54px; }
.bt-ctl.is-on {
  --kit-btn-face: linear-gradient(180deg, var(--success) 0%, var(--success-deep) 100%);
  --kit-btn-edge: #12512a;
  --kit-btn-shelf: #12512a;
  --kit-btn-fg: #08210f;
}

/* --- ultimate cut-in ------------------------------------------------------- */

.bt-cutin {
  position: absolute;
  inset: 0;
  z-index: var(--z-overlay);
  display: grid;
  place-items: center;
  pointer-events: none;
  overflow: hidden;
  background: rgba(3, 5, 10, 0.55);
  animation: kit-fade 140ms var(--ease-out);
}
.bt-cutin[hidden] { display: none; }

/* The portrait sweeps across on a tilted band — the genre's own grammar for
   "this one matters". It runs over live playback rather than pausing it, so
   four ultimates in a fight never add up to four interruptions. */
.bt-cutin-sweep {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s4);
  width: 150%;
  /* The BAND is 150% wide so it bleeds past both edges — that is the
     look. Its CONTENT must not: centred, a 150% band hangs 25% off each
     side, and the portrait is the first flex child, so it sat a quarter
     of a screen to the left of the screen. Only a sliver of it was ever
     visible, which read as a cut-in with no portrait at all.
     
     25% puts the content back at the band's visible middle; the extra
     gap is breathing room inside that. */
  padding: var(--s3) calc(25% + var(--s4));
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(10, 14, 24, 0.92) 18%,
    rgba(26, 34, 56, 0.95) 50%,
    rgba(10, 14, 24, 0.92) 82%,
    transparent 100%);
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.6);
  transform: rotate(-4deg);
  animation: bt-sweep 1s var(--ease-out);
}
@keyframes bt-sweep {
  0% { opacity: 0; transform: rotate(-4deg) translateX(-26%); }
  16% { opacity: 1; }
  78% { opacity: 1; transform: rotate(-4deg) translateX(2%); }
  100% { opacity: 0; transform: rotate(-4deg) translateX(8%); }
}

.bt-cutin-art {
  width: 108px;
  flex: none;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.7));
  animation: bt-cutin-art 1s var(--ease-back);
}
@keyframes bt-cutin-art {
  0% { transform: scale(0.74) translateX(-30px); }
  100% { transform: none; }
}
.bt-cutin-art .portrait { border-width: 3px; border-radius: var(--rad-md); }

.bt-cutin-who {
  font-family: var(--font-display);
  font-size: var(--fz-body);
  color: var(--text-muted);
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.7);
}
.bt-cutin-skill {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 7vw, 2rem);
  line-height: 1.05;
  color: var(--gold-200);
  text-shadow: 0 3px 0 rgba(0, 0, 0, 0.75), 0 0 26px rgba(255, 200, 110, 0.55);
}

@media (prefers-reduced-motion: reduce) {
  .bt-orb.is-full, .bt-clock.danger { animation: none; }
  .bt-cutin-sweep, .bt-cutin-art { animation-duration: 1ms; }
}

/* --- turn order -------------------------------------------------------------
   Who acts next, six deep, newest on the left. The engine has emitted a
   `turn` event since the first version of this code and nothing read it;
   this is that event finally on screen.

   Side colour does the work: a player scanning this wants to know whether
   the next three turns are theirs, not which specific hero is fourth. */

.bt-order {
  display: flex;
  gap: 3px;
  justify-content: center;
  margin-top: var(--s1);
  pointer-events: none;
}

.bt-order-pip {
  position: relative;
  display: block;
  width: 26px;
  height: 26px;
  overflow: hidden;
  border: 2px solid var(--iron-500);
  border-radius: 50%;
  opacity: 0.62;
  background: var(--ink-800);
}
/* Blue for ours, red for theirs. It was green/red, which reads as
   healthy/hurt rather than as a side — and the health bars are already
   using green and red to mean exactly that. */
.bt-order-pip.ally { border-color: var(--ally-ring, #5aa9ff); }
.bt-order-pip.foe { border-color: var(--alert); }

/* Fallen: still shown for a beat so the player can see the order change,
   but plainly not going to act. */
.bt-order-pip.is-dead {
  border-color: var(--iron-600, #4a5366);
  opacity: 0.3;
  filter: grayscale(1);
}

/* The one acting now reads first: full size, full opacity, a ring. */
.bt-order-pip.is-next {
  width: 32px;
  height: 32px;
  opacity: 1;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--gold-300) 60%, transparent);
}

.bt-order-pip .portrait,
.bt-order-pip img,
.bt-order-pip canvas {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

@media (max-width: 380px) {
  /* Four is enough when the top band is tight; the far end of the strip is
     the least reliable part of it anyway. */
  .bt-order-pip:nth-child(n + 5) { display: none; }
}

/* --- Fury -------------------------------------------------------------------
   From round 13 the rules change: damage climbs, defence falls, healing is
   cut. The player needs to know that happened without reading a changelog,
   and then needs to be left alone about it. */

/* `hidden` has to win. A bare `display: inline-flex` outranks the UA's
   `[hidden] { display: none }`, so the badge was set hidden at build time,
   stayed hidden in the DOM sense, and rendered anyway — a red 0 sitting
   under the round counter from the first round of every fight, which is
   exactly the "unlabelled red counter" in the brief. It is the Fury stack
   count and it belongs to round 13 onward. */
.bt-fury[hidden] { display: none; }

.bt-fury {
  display: inline-flex;
  gap: 3px;
  align-items: center;
  margin-left: var(--s2);
  padding: 1px var(--s2);
  border-radius: var(--rad-pill);
  background: color-mix(in srgb, var(--alert) 30%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--alert) 70%, transparent);
  color: var(--alert);
  font-size: var(--fz-tiny);
  font-weight: 800;
}
.bt-fury b { font-family: var(--font-num); }

/* The edge of the screen bleeds while Fury is running. Deliberately a
   vignette and not an overlay: it must never sit between the player and the
   fight, only around it. */
.battle-screen.is-fury::after {
  position: absolute;
  z-index: var(--z-hud);
  content: '';
  inset: 0;
  animation: bt-fury-pulse 2.4s var(--ease-out) infinite;
  background: radial-gradient(130% 95% at 50% 50%,
    transparent 58%, color-mix(in srgb, var(--alert) 26%, transparent) 100%);
  pointer-events: none;
}
@keyframes bt-fury-pulse {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}

.bt-fury-banner {
  position: absolute;
  z-index: var(--z-overlay);
  top: 38%;
  left: 0;
  display: grid;
  width: 100%;
  justify-items: center;
  gap: 2px;
  animation: bt-fury-in 1.8s var(--ease-out) forwards;
  pointer-events: none;
  text-align: center;
}
.bt-fury-banner span {
  color: var(--alert);
  font-size: var(--fz-display);
  font-weight: 900;
  letter-spacing: 0.18em;
  text-shadow: 0 0 20px color-mix(in srgb, var(--alert) 70%, transparent),
               0 2px 0 rgba(0, 0, 0, 0.6);
}
.bt-fury-banner small {
  color: var(--text-muted);
  font-size: var(--fz-tiny);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
@keyframes bt-fury-in {
  0% { opacity: 0; transform: scale(0.82); }
  18% { opacity: 1; transform: scale(1.04); }
  28% { transform: scale(1); }
  80% { opacity: 1; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .battle-screen.is-fury::after { animation: none; opacity: 0.8; }
  .bt-fury-banner { animation: none; }
}

/* Manual casting: the orbs stop being a read-out and become a control, so
   they say so. A full bar waiting on the player pulses; the others do not. */
.battle-screen.is-manual .bt-orb { cursor: pointer; }
.battle-screen.is-manual .bt-orb.is-full {
  box-shadow: 0 0 0 2px var(--gold-300), 0 0 14px var(--gold-300);
}
.battle-screen.is-manual .bt-orb.is-full::after {
  position: absolute;
  inset: auto 0 -13px 0;
  content: 'TAP';
  color: var(--gold-200);
  font-size: 0.5rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-align: center;
}
