/* The live arena. The playfield stays visible around a compact HUD, so every
   panel is pointer-transparent unless it holds a control. */

#arena { position: fixed; inset: 0; overflow: hidden; background: #050b16; }
#game-canvas { display: block; width: 100%; height: 100%; outline: none; cursor: crosshair; }
.arena-vignette { position: absolute; inset: 0; pointer-events: none; box-shadow: inset 0 0 120px #02061075; }

.hud-top-right, .hud-top-center, .hud-bottom-left, .hud-bottom-center, .hud-bottom-right {
  position: absolute;
  z-index: 2;
  pointer-events: none;
}

.hud-top-center { top: 24px; left: 50%; width: min(420px, 35vw); transform: translateX(-50%); }


/* --- Top right: leaderboard and kill feed ------------------------------- */

.hud-top-right { top: 24px; right: 22px; width: 219px; }
.leaderboard { text-shadow: 0 1px 4px #000c, 0 0 12px #0008; }
.panel-caption {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
  font-size: var(--label-md);
  letter-spacing: 1.5px;
  color: #cde3f7;
}
.panel-caption span:last-child { align-self: center; font-size: var(--label-sm); letter-spacing: .5px; color: #8ba3bc; }
.leaderboard-row {
  display: grid;
  grid-template-columns: 18px 1fr 43px;
  gap: 8px;
  padding: 4px 0;
  font-size: 10px;
  color: #b7c6d8;
}
.leaderboard-row > span:first-child { color: #7590a8; }
.leaderboard-row > strong { font-weight: 500; text-align: right; color: #dcecf9; }
/* Your row; in Teams it takes your team's colour (set inline as --me-color). */
.leaderboard-row.me, .leaderboard-row.me strong { color: var(--me-color, #91deff); }
.leaderboard-row .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crown-icon { width: 11px; height: 8px; margin-right: 5px; vertical-align: 0; fill: #f5cb5c; filter: drop-shadow(0 0 3px #ffcf5a99); }
/* Captions and names share the XP caption's face and weight; ranks, scores
   and keycaps keep the UI face. */
.panel-caption, .leaderboard-row .name, .upgrade-heading, .upgrade-row > span, .weapon-heading { font-family: var(--font-display); font-weight: 500; }

.kill-feed { margin-top: 14px; font-size: 10px; line-height: 1.9; color: #a1b2c7; text-shadow: 0 1px 4px #000c, 0 0 12px #0008; }
.kill-feed span { font-size: var(--label-sm); letter-spacing: 1px; color: #6e8398; }
.kill-feed b { font-weight: 500; color: #e3beae; }
.kill-feed div.entering { animation: feed-in .3s ease; }
@keyframes feed-in {
  from { opacity: 0; transform: translateY(-5px); }
  to { opacity: 1; transform: none; }
}

/* --- Evolution offer --------------------------------------------------- */

/* The in-flight evolution offer: one card per branch, keyed Z / X / C, with
   the stat changes against the current ship. Tinted by the starter colour. */
.evolution-panel {
  --accent: #77d8ff;
  position: absolute;
  z-index: 4;
  top: 78px;
  left: 50%;
  width: 540px;
  padding: 12px 14px 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent);
  border-radius: 8px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 9%, #091522f2), #060e1af2);
  box-shadow: 0 10px 40px #0006, inset 0 1px #ffffff0a;
  transform: translateX(-50%);
  animation: offer-in .35s cubic-bezier(.2, .8, .2, 1);
}
@keyframes offer-in { from { opacity: 0; transform: translate(-50%, -8px); } }
.evolution-caption {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-bottom: 10px;
  font-family: var(--font-display);
  font-weight: 500;
}
.evolution-caption strong { font-size: 13px; font-weight: 500; letter-spacing: 2px; color: var(--accent); }
.evolution-caption span { font-size: var(--label-sm); letter-spacing: 1.2px; color: #8aa3ba; }
.evolution-caption small { display: flex; gap: 4px; margin-left: auto; }
.evolution-caption kbd { padding: 2px 5px; font-size: 9px; }
/* Up to three cards a row, a third of the width each; one or two branches sit centred. */
#evolution-options { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
#evolution-options > .evolve-card { flex: 0 0 calc((100% - 16px) / 3); min-width: 0; }
.evolution-panel.apex-offer { max-height: calc(100dvh - 220px); overflow-y: auto; }
.apex-offer .evolution-caption { flex-wrap: wrap; gap: 8px; }
.evolve-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  padding: 8px 8px 10px;
  border: 1px solid #7ca6c533;
  border-radius: 6px;
  background: #0d1a2a99;
  color: #d1e5f6;
  text-align: center;
}
.evolve-card:hover, .evolve-card:focus-visible {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, #0d1a2a);
  box-shadow: 0 0 20px color-mix(in srgb, var(--accent) 20%, transparent);
}
.evolve-card kbd { position: absolute; top: 7px; left: 7px; font-size: 9px; }
.evolve-card canvas { display: block; width: 92px; height: 66px; margin: 0 auto 4px; }
.evolve-card strong { font-family: var(--font-display); font-size: 14px; font-weight: 500; color: #eef8ff; }
.evolve-role { margin-top: 2px; font-family: var(--font-display); font-size: var(--label-sm); font-weight: 500; letter-spacing: 1px; color: var(--accent); text-transform: uppercase; }
.evolve-weapon { max-width: 100%; margin-top: 5px; overflow: hidden; font-size: var(--label-sm); color: #8ba3b9; text-overflow: ellipsis; white-space: nowrap; }
/* Three fixed mini stats, so every card and every offer has the same size. */
.evolve-changes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; width: 100%; margin-top: 8px; }
.evolve-changes em {
  display: grid;
  gap: 1px;
  padding: 3px 2px;
  border-radius: 3px;
  background: #5470892e;
  font-family: var(--font-display);
  font-size: 9px;
  font-style: normal;
  font-weight: 500;
  letter-spacing: .5px;
  color: #93a9bd;
}
.evolve-changes em small { font-size: 7px; letter-spacing: 1px; opacity: .8; }
.evolve-changes em.up { background: #78ddb51f; color: #86e3bf; }
.evolve-changes em.down { background: #e39a8a1f; color: #eba89a; }

/* --- Bottom left: upgrades --------------------------------------------- */

.hud-bottom-left { bottom: 22px; left: 24px; width: 235px; pointer-events: auto; }
.upgrade-heading {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: var(--label-sm);
  letter-spacing: 1px;
  color: #8fa8c0;
}
.upgrade-heading strong { margin-left: auto; font-size: var(--label-sm); font-weight: 500; letter-spacing: .7px; color: #d4dca0; }
.upgrade-heading button {
  display: grid;
  place-items: center;
  width: 20px;
  height: 19px;
  padding: 0;
  border: 1px solid #6c8aaa44;
  background: none;
  color: #88a6be;
}
/* The list slides open while points are waiting and closes once they are
   spent; the toggle button still opens or closes it at any time. */
.upgrade-drawer {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows .38s cubic-bezier(.2, .8, .2, 1), opacity .28s ease;
}
.upgrade-drawer.collapsed { grid-template-rows: 0fr; opacity: 0; }
#upgrade-list { min-height: 0; overflow: hidden; }
#upgrade-list > :first-child { margin-top: 10px; }
.upgrade-row {
  display: grid;
  grid-template-columns: 19px 1fr 59px 16px;
  align-items: center;
  gap: 7px;
  width: 100%;
  height: 29px;
  margin-bottom: 4px;
  padding: 6px;
  border: 1px solid var(--hud-edge);
  border-radius: 3px;
  background: var(--hud-fill);
  color: #b3c7da;
  text-align: left;
}
.upgrade-row:hover:not(:disabled) { border-color: #8dcce688; background: #1e374bcf; }
/* Unavailable rows dim their contents only, so the panel fill stays the same as the ship status. */
.upgrade-row:disabled > * { opacity: .65; }
.upgrade-row kbd { padding: 3px; font-size: var(--label-sm); text-align: center; }
.upgrade-row > span { font-size: var(--label-md); }
.upgrade-row b { font-size: 15px; font-weight: 400; color: var(--upgrade-color); }
.upgrade-bars { display: flex; gap: 2px; }
.upgrade-bars i { width: 5px; height: 10px; border-radius: 1px; background: #83a0ba26; }
.upgrade-bars i.filled { background: var(--upgrade-color); }

/* Weapon reload, under the upgrades. Its colour tracks firepower (app.js):
   blue at full strength, through yellow to red as guns and wings are lost. */
.weapon-status { --weapon-color: #93dcff; margin-top: 12px; }
.weapon-heading {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
  font-size: var(--label-md);
  letter-spacing: 1.4px;
  color: color-mix(in srgb, var(--weapon-color) 80%, #c6d6e3);
  transition: color .8s ease;
}
.weapon-track { height: 2px; background: #54708930; }
.weapon-track > div {
  width: 100%;
  height: 100%;
  background: var(--weapon-color);
  box-shadow: 0 0 8px color-mix(in srgb, var(--weapon-color) 45%, transparent);
  transition: width .06s linear, background-color .8s ease, box-shadow .8s ease;
}

/* --- Bottom centre: component health ----------------------------------- */

.hud-bottom-center { bottom: 22px; left: 50%; width: min(540px, 42vw); transform: translateX(-50%); }
.damage-status {
  display: grid;
  grid-template-columns: 1fr 1fr auto 1fr 1fr;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  /* Same fill, opacity and edge as the System Upgrades rows (tokens.css). */
  border: 1px solid var(--hud-edge);
  border-radius: 3px;
  background: var(--hud-fill);
}
/* Health states: healthy, worn (< 65%), critical (< 25%) and offline (detached). */
.damage-status [data-state='ok'] { --part: #7fd3ff; }
.damage-status [data-state='worn'] { --part: #f2c46d; }
.damage-status [data-state='critical'] { --part: #ff8a66; }
.damage-status [data-state='offline'] { --part: #ff5f55; }
.damage-status [data-state='rebuilding'] { --part: #6fdcff; }
.part { display: grid; grid-template-columns: 1fr auto; align-items: baseline; row-gap: 5px; column-gap: 6px; }
.part-name { font-family: var(--font-display); font-size: 10px; font-weight: 500; letter-spacing: 1.2px; color: #9db4c8; white-space: nowrap; }
.part-value { font-size: 10px; font-weight: 500; font-variant-numeric: tabular-nums; color: var(--part); transition: color .25s; }
.part-bar { grid-column: 1 / -1; display: flex; height: 4px; overflow: hidden; border-radius: 2px; background: #54708933; }
.part-bar em { width: 100%; background: var(--part); box-shadow: 0 0 6px var(--part); transition: width .25s ease, background-color .25s; }
/* The right-hand side reads outward from the centre, like the left. */
.part.mirrored .part-name { order: 2; text-align: right; }
.part.mirrored .part-bar { order: 3; justify-content: flex-end; }
.part[data-state='critical'] .part-bar em, .part-schematic [data-state='critical'] { animation: part-alarm .9s steps(2, jump-none) infinite; }
.part[data-state='offline'] .part-name { color: #c98d86; }
.part[data-state='offline'] .part-value { letter-spacing: 1px; }
.part[data-state='offline'] .part-bar { background: repeating-linear-gradient(135deg, #ff5f5540 0 3px, transparent 3px 6px); }
@keyframes part-alarm { 50% { opacity: .35; } }

.part-schematic { width: 54px; height: 42px; overflow: visible; filter: drop-shadow(0 0 5px #0009); }
.part-schematic [data-part] { fill: color-mix(in srgb, var(--part) 45%, transparent); stroke: var(--part); stroke-width: 1; transition: fill .25s, stroke .25s; }
.part-schematic [data-state='offline'] { fill: none; stroke-dasharray: 2 2; opacity: .7; }
.part-hull { fill: color-mix(in srgb, var(--part) 30%, transparent); stroke: color-mix(in srgb, var(--part) 80%, transparent); stroke-width: 1; transition: fill .25s, stroke .25s; }
/* A part being rebuilt: a steady dashed outline, filling in as it comes back. */
.part-schematic [data-state='rebuilding'] { fill: color-mix(in srgb, var(--part) 18%, transparent); stroke-dasharray: 2 1.5; }
.part[data-state='rebuilding'] .part-value { letter-spacing: 1px; }

.xp-heading { display: flex; justify-content: center; align-items: center; margin-top: 8px; }
.xp-heading strong { font-size: 12px; font-weight: 500; letter-spacing: 1px; color: #d0eaff; }
.xp-track {
  height: 10px;
  padding: 2px;
  overflow: hidden;
  border: 1px solid #7ba7c95c;
  border-radius: 4px;
  background: #06111be0;
}
.xp-track div {
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, #409dc5, #8ae3ff);
  box-shadow: 0 0 8px #7ce2ff88;
  transition: width .15s;
}

/* --- Bottom right: sector, score and radar ------------------------------ */

/* A right-aligned column: the flight block may run wider than the radar and
   grows to the left, between the kill feed above and the map below. */
.hud-bottom-right { right: 24px; bottom: 22px; display: flex; flex-direction: column; align-items: flex-end; gap: 18px; }
.radar-panel { width: 166px; }
/* Same face, weight and tracking as the level caption on the XP bar. */
.hud-flight { text-align: right; text-shadow: 0 1px 4px #000c, 0 0 12px #0008; }
.match-stats { display: flex; justify-content: flex-end; gap: 22px; }
.match-stats div { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }
.match-stats span { font-family: var(--font-display); font-size: var(--label-sm); font-weight: 500; letter-spacing: 1px; color: #8098b1; }
.match-stats strong { font-size: 19px; font-weight: 500; }
.radar-caption, .radar-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: var(--label-sm);
  letter-spacing: 1.3px;
  color: #86a7c3;
}
.radar-caption > span:last-child { font-size: var(--label-sm); letter-spacing: .5px; color: #7793ac; }
#radar { width: 166px; height: 166px; border: 1px solid #86b4d84d; border-radius: 5px; background: #081522ca; }
#coordinates { display: inline-flex; gap: 12px; font-variant-numeric: tabular-nums; }
/* Server ping beside the coordinates, coloured by quality. */
.latency { margin-right: 6px; font-variant-numeric: tabular-nums; color: #8ea6bd; }
.latency:empty { display: none; }
.latency[data-quality='good'] { color: #78ddb5; }
.latency[data-quality='fair'] { color: #f2c46d; }
.latency[data-quality='poor'] { color: #ff8a66; }
.radar-footer { justify-content: center; gap: 7px; margin: 8px 0 0; font-size: var(--label-sm); }

/* --- Sector hazards ---------------------------------------------------- */

.sector-events {
  position: absolute;
  top: 24px;
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  pointer-events: none;
  transform: translateX(-50%);
}
.sector-events span {
  padding: 9px 16px;
  border: 1px solid color-mix(in srgb, var(--event-color), transparent 55%);
  border-radius: 4px;
  background: #060e1bc9;
  font-size: 10px;
  letter-spacing: 1.8px;
  color: var(--event-color);
}
.fog-status {
  position: absolute;
  display: flex;
  gap: 18px;
  top: 130px;
  left: 50%;
  font-size: var(--label-md);
  letter-spacing: 1.4px;
  color: #a9c1df;
  text-align: center;
  pointer-events: none;
  transform: translateX(-50%);
}

/* --- Top left: Zone Fight and Teams match readout ---------------------- */

/* No panel: a caption over one bar, shadowed like the leaderboard so it
   stays legible over any background. */
.match-hud {
  position: absolute;
  z-index: 2;
  top: 24px;
  left: 24px;
  display: grid;
  gap: 8px;
  width: 240px;
  font-family: var(--font-display);
  font-weight: 500;
  text-shadow: 0 1px 4px #000c, 0 0 12px #0008;
  pointer-events: none;
}
.match-caption { display: flex; justify-content: space-between; align-items: baseline; font-size: var(--label-md); letter-spacing: 1.5px; color: #cde3f7; }
.match-caption time { font-size: var(--label-md); letter-spacing: 1px; font-variant-numeric: tabular-nums; color: #8ba3bc; }
.match-row { display: flex; align-items: center; gap: 9px; }
.match-row b { font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; color: var(--team-color, #eef8ff); }
.match-row b.mine { text-shadow: 0 0 10px var(--team-color), 0 1px 4px #000c; }
.match-bar, .match-split { position: relative; flex: 1; display: flex; height: 6px; overflow: hidden; border-radius: 3px; background: #06111be0; box-shadow: inset 0 0 0 1px #7ba7c93d; }
.match-bar em, .match-split em { background: var(--team-color); box-shadow: 0 0 8px var(--team-color); transition: width .3s ease; }
.match-split em.end { margin-left: auto; }
/* The target sits in the middle of the split bar. */
.match-split::after { content: ''; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: #cde3f766; }
.match-row[data-zone] { --team-color: #f2c36b; }
.match-row[data-zone='alone'] { --team-color: #78ddb5; }
.match-row[data-zone='contested'] { --team-color: #ff9d6b; }
.match-row[data-zone] b { color: #f6e3b8; }
/* Inside your own base: no damage taken. */
.match-safe { font-size: var(--label-sm); letter-spacing: 1.4px; color: var(--team-color); }

/* End of round: the winner, the reward, and the countdown to the next round. */
.round-banner {
  position: absolute;
  z-index: 6;
  top: 26%;
  left: 50%;
  display: grid;
  justify-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-weight: 500;
  text-align: center;
  text-shadow: 0 2px 16px #000;
  pointer-events: none;
  transform: translateX(-50%);
  animation: banner-in .5s cubic-bezier(.2, .8, .2, 1);
}
@keyframes banner-in { from { opacity: 0; transform: translate(-50%, -10px) scale(.96); } }
.round-kicker { font-size: var(--label-md); letter-spacing: 4px; color: #9fb6cb; }
.round-banner strong { font-size: 40px; font-weight: 600; letter-spacing: 4px; color: var(--winner-color); text-shadow: 0 0 30px color-mix(in srgb, var(--winner-color) 45%, transparent), 0 2px 16px #000; white-space: nowrap; }
.round-banner em { font-size: 14px; font-style: normal; letter-spacing: 2px; color: var(--gold); }
.round-banner small { font-size: var(--label-sm); letter-spacing: 2px; color: #8ea6bd; }

.team-dot { display: inline-block; width: 6px; height: 6px; margin-right: 6px; border-radius: 50%; background: var(--team-color); box-shadow: 0 0 6px var(--team-color); vertical-align: 1px; }
.kill-feed em { font-style: normal; }

/* --- Notices and overlays ---------------------------------------------- */

/* Notices sit just under the level bar, clear of the pilot, as plain text:
   they hold for a moment and then fade out. While an evolution offer is
   open they drop below it. */
.toast {
  --toast-color: #7fd3ff;
  position: absolute;
  z-index: 5;
  top: 82px;
  left: 50%;
  max-width: min(460px, calc(100vw - 32px));
  text-align: center;
  text-shadow: 0 1px 3px #000, 0 0 14px #000c;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-50%);
  transition: opacity .9s ease;
}
.toast.visible { opacity: 1; transition-duration: .2s; }
#evolution-panel:not([hidden]) ~ .toast { top: var(--below-offer, 290px); }
.toast[data-kind='level'] { --toast-color: #edce8d; }
.toast[data-kind='kill'] { --toast-color: #ffa477; }
.toast[data-kind='evolve'] { --toast-color: #b99cff; }
.toast[data-kind='alert'] { --toast-color: #ff7a6b; }
.toast[data-kind='zone'] { --toast-color: #f2c36b; }
.toast-copy { display: grid; gap: 4px; }
.toast-copy strong { font-family: var(--font-display); font-size: 14px; font-weight: 500; letter-spacing: 1.6px; text-transform: uppercase; color: #eef8ff; }
.toast-copy span { font-family: var(--font-display); font-size: 12px; font-weight: 500; letter-spacing: .4px; color: color-mix(in srgb, var(--toast-color) 70%, #d6e6f2); }
.toast-copy span:empty { display: none; }

.death-notice {
  position: absolute;
  z-index: 5;
  top: 39%;
  left: 50%;
  text-align: center;
  text-shadow: 0 2px 14px #000;
  pointer-events: none;
  transform: translateX(-50%);
}
.death-notice > span { font-size: 18px; letter-spacing: 5px; color: #d7e8f4; }
.death-notice p { margin-top: 12px; font-size: 10px; letter-spacing: 1px; color: #96adc1; }

.screen-overlay {
  position: absolute;
  z-index: 10;
  inset: 0;
  display: grid;
  place-items: center;
  background: #030911b0;
  backdrop-filter: blur(12px);
}
/* The arena keeps running under the overlay, so a blur behind it is redone every
   frame; phones get a deeper tint instead. */
@media (pointer: coarse) { .screen-overlay { background: #030911d9; backdrop-filter: none; } }
.death-card {
  width: min(465px, 90vw);
  padding: 38px;
  border: 1px solid #839eb952;
  border-radius: 10px;
  background: linear-gradient(140deg, #14273beb, #091522f5);
  box-shadow: 0 30px 130px #0008;
  text-align: center;
}
.death-card > .eyebrow { justify-content: center; }
.death-card h2 { margin: 19px 0 13px; font-size: 30px; font-weight: 500; letter-spacing: -.6px; }
.death-card p { font-size: 12px; line-height: 1.8; color: #8ea9c1; }

/* --- Session ended: the arena falls apart (session-collapse.js) -------- */

/* No z-index: the HUD panels after it in the page stay on top while they fall. */
.session-collapse { position: absolute; inset: 0; background: #000; pointer-events: none; }
.session-collapse > canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
/* The boot screen's warp stars come back behind the notice. */
.session-collapse > .collapse-warp { opacity: 0; transition: opacity 1.4s ease; }
.session-collapse.is-warping > .collapse-warp { opacity: 1; }
/* The panels flicker with the failing signal, then come loose and drop off the
   screen. The individual translate and rotate properties add to each panel's
   own transform rather than replacing it; the easing's dip lifts a panel a
   touch before it falls. */
#arena.is-collapsing .collapse-piece { animation: hud-glitch .16s steps(2, jump-none) infinite; }
#arena.is-collapsing .collapse-piece.is-falling { animation: hud-fall var(--fall-time) cubic-bezier(.45, -.18, .85, .4) var(--fall-delay) both; }
#arena.is-dark .collapse-piece { visibility: hidden; }
@keyframes hud-glitch {
  0% { translate: 0 0; filter: none; }
  50% { translate: var(--jitter-x) 0; filter: brightness(1.8) saturate(.4); }
  100% { translate: calc(var(--jitter-x) * -.5) 1px; filter: brightness(.6); }
}
@keyframes hud-fall { to { translate: var(--fall-x) 115vh; rotate: var(--fall-rot); } }

.collapse-message {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  gap: 12px;
  justify-items: center;
  text-align: center;
  white-space: nowrap;
  opacity: 0;
  translate: -50% -50%;
  transition: scale .7s cubic-bezier(.6, 0, .9, .4), opacity .5s ease, filter .6s ease;
}
.collapse-message strong { font-family: var(--font-display); font-size: 18px; font-weight: 500; letter-spacing: 6px; color: #d7e8f4; text-shadow: 0 0 18px #6dcaff88; }
.collapse-message span { font-family: var(--font-display); font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: #7f98ae; }
/* No fill: once the flicker ends, the jump below can fade the notice. */
.collapse-message.is-shown { opacity: 1; animation: collapse-flicker .6s linear; }
@keyframes collapse-flicker { 0% { opacity: 0; } 10% { opacity: .8; } 16% { opacity: .1; } 30% { opacity: 1; } 38% { opacity: .3; } 46%, 100% { opacity: 1; } }
/* The jump home, as at launch (boot.css): the notice rushes past, the stars
   stretch, and the overlay rises above the page to flash into the hangar. */
.session-collapse.is-jumping .collapse-message { scale: 1.6; opacity: 0; filter: blur(6px); }
.session-collapse.is-lifted { position: fixed; z-index: 1000; }
.session-collapse::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, #ffffff 0%, #bff0ff 30%, #6dcaff00 75%);
  opacity: 0;
  pointer-events: none;
}
.session-collapse.is-revealing { opacity: 0; transition: opacity .6s ease; }
.session-collapse.is-revealing::after { animation: boot-flash .65s ease-out both; }
.death-card .play-button { font-size: 14px; letter-spacing: 3px; text-indent: 3px; }
.death-card .text-button { margin: 17px auto 0; font-size: var(--label-md); }
.death-card .flight-settings { margin-top: 16px; }

/* --- Responsive -------------------------------------------------------- */

@media (max-width: 1150px) {
  .evolution-panel { width: 460px; }
  .hud-top-right { width: 185px; }
  .match-stats { gap: 18px; }
}
@media (max-width: 850px) {
  .hud-bottom-left { left: 12px; bottom: 15px; width: 196px; }
  .upgrade-row { grid-template-columns: 15px 1fr 52px 12px; gap: 4px; }
  .upgrade-row > span { font-size: var(--label-sm); }
  .upgrade-bars { gap: 1px; }
  .upgrade-heading { gap: 5px; font-size: 7px; }
  .upgrade-heading strong { font-size: 6px; }
  .hud-bottom-center { left: 52%; bottom: 18px; width: 35vw; }
  .hud-top-center { width: 35vw; }
  .hud-bottom-right { right: 12px; bottom: 16px; gap: 12px; }
  .radar-panel { width: 115px; }
  #radar { width: 115px; height: 115px; }
  .radar-caption > span:last-child { display: none; }
  .hud-top-right { right: 12px; width: 160px; }
  .leaderboard { padding: 10px; }
  .panel-caption { font-size: var(--label-sm); letter-spacing: .7px; }
  .panel-caption span:last-child { display: none; }
  .match-stats { gap: 14px; }
  .match-stats span { font-size: 6px; }
  .match-stats strong { font-size: 15px; }
  .xp-heading strong { font-size: 10px; }
  .evolution-panel { top: 202px; width: 370px; }
  .damage-status { gap: 7px; padding: 8px 10px; }
  .part-name, .part-value { font-size: 7px; letter-spacing: .6px; }
  .part-schematic { width: 36px; height: 28px; }
  #evolution-panel:not([hidden]) ~ .toast { top: 82px; }
  .toast { max-width: calc(100vw - 360px); }
  .kill-feed { font-size: var(--label-sm); }
  .match-hud { top: 14px; left: 12px; width: 180px; }
  .match-caption { font-size: var(--label-sm); letter-spacing: 1px; }
  .round-banner strong { font-size: 28px; letter-spacing: 2px; }
}
@media (max-width: 560px) {
  .match-hud { top: auto; bottom: 230px; width: 140px; }
}
@media (max-width: 560px) {
  .hud-top-right { top: 14px; width: 130px; }
  .leaderboard-row { grid-template-columns: 14px 1fr 30px; gap: 5px; padding: 5px 0; font-size: var(--label-sm); }
  .leaderboard-row .bot-tag { display: none; }
  .match-stats { gap: 11px; }
  .match-stats strong { font-size: 14px; }
  .match-stats span { font-size: 5px; }
  .hud-bottom-left { width: 155px; }
  .upgrade-row { grid-template-columns: 13px 1fr 40px 10px; gap: 3px; height: 26px; padding: 4px; }
  .upgrade-row > span { font-size: 7px; }
  .upgrade-bars i { width: 4px; height: 8px; }
  .upgrade-heading > span { font-size: 6px; }
  .upgrade-heading strong { font-size: 5px; }
  .hud-bottom-center { left: auto; right: 12px; bottom: 19px; width: calc(100vw - 195px); transform: none; }
  .hud-top-center { width: calc(100vw - 195px); }
  .hud-bottom-right { bottom: 173px; }
  .radar-panel { width: 90px; }
  #radar { width: 90px; height: 90px; }
  .xp-heading strong { font-size: var(--label-sm); white-space: nowrap; }
  .evolution-panel { top: 196px; width: calc(100vw - 24px); max-width: 360px; }
  .apex-offer .evolve-card canvas { width: 82px; height: 59px; }
  .damage-status { gap: 5px; padding: 6px 8px; }
  .part-name { display: none; }
  .part-schematic { width: 30px; height: 24px; }
  .death-card { padding: 26px; }
  .death-card h2 { font-size: 27px; }
  .toast { max-width: calc(100vw - 300px); }
  .toast-copy strong { font-size: 11px; }
}

/* --- Touch joysticks --------------------------------------------------- */

/* On touch screens with Settings > Controls on JOYSTICKS (#arena.has-sticks):
   movement bottom left, attack bottom right. Each rests at its spot and jumps
   under the thumb while held (touch-sticks.js); the attack stick turns warm while it aims. */
.stick {
  display: none;
  position: absolute;
  z-index: 2;
  bottom: 34px;
  width: 140px;
  height: 140px;
  border: 1px solid #86b4d84d;
  border-radius: 50%;
  background: radial-gradient(circle, #0c1a2a33 0 55%, #0c1a2a99 100%);
  opacity: .5;
  pointer-events: none;
  transition: opacity .15s;
}
#arena.has-sticks .stick { display: block; }
.stick i { position: absolute; top: 50%; left: 50%; width: 56px; height: 56px; margin: -28px 0 0 -28px; border: 1px solid #b9e6ff88; border-radius: 50%; background: #9fd6f455; }
/* In the app the sticks wait in the bottom corners (the movement stick below the
   system upgrades column, whose buttons still take their own taps). On the website
   the upgrades and the radar keep those corners, so the sticks wait beside them. */
.move-stick { left: calc(60px + var(--cutout-left, 0px)); }
.aim-stick { right: calc(60px + var(--cutout-right, 0px)); }
html:not(.is-app) .move-stick { left: 280px; }
html:not(.is-app) .aim-stick { right: 220px; }
/* The attack stick is warm; its reload ring below takes the same colour. */
.aim-stick { --aim-color: #ffb08a; }
.aim-stick i { border-color: #ffc2a888; background: #ff9d7a55; }
.stick.held { opacity: 1; }
.stick.aiming { border-color: color-mix(in srgb, var(--aim-color) 60%, transparent); }
/* Pulled past its rim, the movement stick thrusts (touch-sticks.js). */
.stick.boosting { border-color: #80e3fa; box-shadow: 0 0 18px #80e3fa66, inset 0 0 18px #80e3fa33; }
.stick.boosting i { border-color: #e3f7ff; background: #80e3fa88; }
/* The weapon's reload runs round the attack stick, in its colour, and glows once it is ready (app.js). */
.stick-charge { position: absolute; top: -9px; left: -9px; width: calc(100% + 18px); height: calc(100% + 18px); overflow: visible; transform: rotate(-90deg); }
.stick-charge circle { fill: none; stroke: var(--aim-color); stroke-width: 2.5; stroke-dasharray: 100; stroke-linecap: round; opacity: .7; transition: stroke-dashoffset .1s linear; }
.aim-stick.ready .stick-charge circle { opacity: 1; filter: drop-shadow(0 0 4px var(--aim-color)); }

/* --- Android app ------------------------------------------------------- */

/* app.js moves the radar into the system upgrades column and the flight stats
   over the ship status, so the column runs down the top left (radar, weapon,
   upgrades opening downward) and the bottom corners stay free for the sticks.
   The corner panels are drawn at --hud-zoom and every edge panel keeps clear of
   the camera cutout; a zoomed panel scales its own offsets too, so the cutout
   is divided back. */
html.is-app .hud-top-right, html.is-app .hud-bottom-left, html.is-app .match-hud { zoom: var(--hud-zoom); }
html.is-app .hud-top-right { right: calc(22px + var(--cutout-right) / var(--hud-zoom)); }
html.is-app .hud-bottom-left { top: 20px; bottom: auto; left: calc(24px + var(--cutout-left) / var(--hud-zoom)); display: flex; flex-direction: column; width: 248px; }
/* With the radar folded away while they are open, the upgrades take a touch more room. */
html.is-app .upgrade-row { height: 32px; margin-bottom: 5px; }
/* The radar folds up out of the way while the upgrades are open (app.js), so the
   list takes its place instead of piling up under it, and unfolds once they close.
   Closing the upgrades waits a beat, so the list is gone before the map returns. */
html.is-app .radar-drawer { order: -2; display: grid; grid-template-rows: 1fr; transition: grid-template-rows .42s cubic-bezier(.2, .8, .2, 1) .1s; }
html.is-app .radar-drawer .radar-panel { min-height: 0; overflow: hidden; padding-bottom: 14px; transform-origin: top left; transition: opacity .32s ease .16s, transform .42s cubic-bezier(.2, .8, .2, 1) .1s, padding .42s cubic-bezier(.2, .8, .2, 1) .1s; }
html.is-app #arena.upgrades-open .radar-drawer { grid-template-rows: 0fr; transition-delay: 0s; }
html.is-app #arena.upgrades-open .radar-panel { padding-bottom: 0; opacity: 0; transform: translateY(-12px) scale(.9); transition-duration: .2s, .38s, .38s; transition-delay: 0s; }
html.is-app .weapon-status { order: -1; margin: 0 0 16px; }
/* On a phone the weapon goes unnamed, and with the joysticks its reload is the ring round the attack stick. */
html.is-app #weapon-name { display: none; }
html.is-app #arena.has-sticks .weapon-status { display: none; }
html.is-app .hud-bottom-right { display: none; }
/* The ship status is drawn 5% smaller; the flight stats above it keep their size. */
html.is-app .hud-bottom-center { zoom: .95; }
html.is-app .hud-bottom-center .hud-flight { zoom: calc(1 / .95); margin-bottom: 10px; text-align: center; }
html.is-app .hud-bottom-center .match-stats, html.is-app .hud-bottom-center .match-stats div { justify-content: center; align-items: center; }
/* Zone Fight and Teams: the match readout sits right of the column, clear of the level bar. */
html.is-app .match-hud { left: calc(282px + var(--cutout-left) / var(--hud-zoom)); width: 190px; }
