/* 03-arena.css: game arena.
   Canvas, overhead names/health/speech, ping, countdown, chat, readiness controls, skills, and results. */

/* ===================================================================
   GAME WINDOW AND CANVAS
   =================================================================== */
#gameScreen, #gameScreen * {
  -webkit-user-select: none;
  user-select: none;
}
#gameScreen :is(input, textarea, [contenteditable="true"]) {
  -webkit-user-select: text;
  user-select: text;
}
#gameScreen :is(img, a) { -webkit-user-drag: none; }

.game-layout {
  display: grid;
  grid-template-columns: 1fr var(--ui-room-sidebar-width);
  gap: var(--ui-game-layout-gap);
  align-items: start;
}

/* Unified game window container. */
.world-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: var(--ui-world-max-width);
  border: var(--ui-world-border);
  background: var(--ui-world-background);
  box-shadow: var(--ui-world-shadow);
  overflow: hidden;
}

/* Arena canvas: --ui-canvas-aspect-ratio controls #world.
   Other canvases (queue icons, shops, and podiums) have their own size and background. */
.world-wrap canvas#world {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--ui-canvas-background);
  image-rendering: pixelated;
  object-fit: contain;
}
/* The world as shown: over #world (same box, set by 05-realtime-render.js) at the screen's real
   pixels, so the browser does not stretch it; clicks go through to #world. */
.world-wrap canvas#worldDisplay { position: absolute; z-index: 0; pointer-events: none; image-rendering: auto; }

.game-view {
  position: relative;
}

/* JavaScript changes only scale (--player-unit); group 6 in 00-variables.css supplies styles. */

/* ===================================================================
   SKILL STATUS ABOVE PLAYERS
   Status icons appear above names, health shields are white, and skill preparation uses a yellow bar.
   =================================================================== */
.player-statuses {
  position: absolute;
  bottom: calc((var(--player-name-offset) + 10) * var(--player-unit));
  left: calc(var(--player-name-offset-x) * var(--player-unit));
  transform: translateX(-50%);
  font-size: calc(8 * var(--player-unit));
  line-height: 1;
  white-space: nowrap;
  filter: drop-shadow(0 0 1px #000);
}
.player-hud-entry.is-hall .player-statuses { display: none; }
.player-health-shield { position: absolute; top: 0; height: 100%; background: #e3fbff; opacity: .9; }
.player-health-shield[hidden], .player-cast[hidden] { display: none; }
.player-cast {
  position: absolute;
  bottom: calc((var(--player-health-offset) - 5) * var(--player-unit));
  left: calc(var(--player-health-offset-x) * var(--player-unit));
  transform: translateX(-50%);
  width: calc(var(--player-health-width) * var(--player-unit));
  height: calc(3 * var(--player-unit));
  background: #182029;
}
.player-cast-fill { display: block; width: 0; height: 100%; background: #ffd23f; }

/* ===================================================================
   PLAYER NAME, HEALTH, AND SPEECH
   Values are defined in group 6 of 00-variables.css.
   =================================================================== */
.player-hud-layer {
  --player-unit: 1px;
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
}
.player-hud-entry {
  position: absolute;
  width: 0;
  height: 0;
}
.player-hud-entry[hidden] { display: none; }
.player-name {
  --player-name-anchor-offset: var(--player-name-offset);
  position: absolute;
  bottom: calc(var(--player-name-offset) * var(--player-unit));
  left: calc(var(--player-name-offset-x) * var(--player-unit));
  transform: translateX(-50%);
  padding: var(--player-name-padding);
  border: var(--player-name-border);
  border-radius: var(--player-name-radius);
  background: var(--player-name-background);
  color: var(--player-name-color);
  font-family: var(--player-name-font-family);
  font-size: calc(var(--player-name-font-size) * var(--player-unit));
  font-weight: var(--player-name-font-weight);
  line-height: 1;
  text-shadow: var(--player-name-shadow);
  white-space: nowrap;
}
.player-name.has-rank-art {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(2 * var(--player-unit));
  box-sizing: border-box;
  /* Nameplate width follows Rank > Name above character; zero uses the name's width. */
  min-width: calc(var(--rank-hall-name-min, 0) * var(--player-unit));
  max-width: calc(var(--rank-hall-name-max, 100000) * var(--player-unit));
  padding: calc(2 * var(--player-unit)) calc(3 * var(--player-unit));
  image-rendering: pixelated;
}
.podium-rank-portrait { position: relative; box-sizing: border-box; width: 100%; aspect-ratio: 1; clip-path: var(--result-portrait-clip, none); background: var(--ui-podium-card-background); image-rendering: pixelated; }
.podium-player > .result-portrait-border { border: var(--ui-podium-card-border); }
.podium-player.rank-1 > .result-portrait-border { border-color: var(--ui-podium-first-border); }
.podium-player.rank-3 > .result-portrait-border { border-color: var(--ui-podium-third-border); }
.result-portrait-skin .podium-avatar { margin: 0 !important; }
.player-hud-entry.is-hall .player-name { --player-name-anchor-offset: var(--player-name-offset-hall); bottom: calc(var(--player-name-offset-hall) * var(--player-unit)); }
.player-health {
  position: absolute;
  bottom: calc(var(--player-health-offset) * var(--player-unit));
  left: calc(var(--player-health-offset-x) * var(--player-unit));
  transform: translateX(-50%);
  width: calc(var(--player-health-width) * var(--player-unit));
  height: calc(var(--player-health-height) * var(--player-unit));
  border: 0;
}
.player-health-back, .player-health-fill, .player-health-outline {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  image-rendering: pixelated;
  pointer-events: none;
}
.player-health-back { background-image: url('../../assets/icons/hp-bar/bar_hp_back.png'); }
.player-health-fill { background-image: url('../../assets/icons/hp-bar/bar_hp_fill.png'); filter: hue-rotate(270deg); }
.player-health-outline { background-image: url('../../assets/icons/hp-bar/hp_bar_outline.png'); }
.player-hud-entry.is-self .player-health-fill { filter: none; }
.player-hud-entry.is-ally .player-health-fill { filter: hue-rotate(200deg); }
.player-health-track { position: absolute; left: 5.084746%; top: 27.777778%; width: 67.79661%; height: 44.444444%; overflow: hidden; }
.player-health-damage { display: block; height: 100%; background: #ffe3a1; }
.player-health[hidden] { display: none; }
.player-health-level {
  position: absolute;
  left: 74.576271%;
  width: 20.338983%;
  top: 50%;
  transform: translateY(-50%);
  color: #fff4cf;
  font-family: Arial, sans-serif;
  font-size: calc(7 * var(--player-unit));
  font-weight: bold;
  line-height: 1;
  text-align: center;
  text-shadow: 0 1px #151b20;
  white-space: nowrap;
}
.player-speech {
  position: absolute;
  bottom: calc(var(--player-speech-offset) * var(--player-unit));
  left: calc(var(--player-speech-offset-x) * var(--player-unit));
  transform: translateX(-50%);
  box-sizing: border-box;
  width: max-content;
  min-width: calc(var(--player-speech-min-width) * var(--player-unit));
  max-width: calc(var(--player-speech-max-width) * var(--player-unit));
  padding: calc(var(--player-speech-padding-y) * var(--player-unit)) calc(var(--player-speech-padding-x) * var(--player-unit));
  border: calc(var(--player-speech-border-width) * var(--player-unit)) solid var(--player-speech-border-color);
  border-radius: var(--player-speech-border-radius, var(--player-speech-radius));
  background: var(--player-speech-background);
  color: var(--player-speech-color);
  font-family: var(--player-speech-font-family);
  font-size: calc(var(--player-speech-font-size) * var(--player-unit));
  line-height: 1.2;
  text-align: center;
  overflow-wrap: anywhere;
}
.player-speech[hidden] { display: none; }
.player-speech-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.player-speech::before,
.player-speech::after {
  display: var(--player-speech-tail-display);
  content: '';
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
.player-speech::before {
  top: 100%;
  width: calc(6 * var(--player-unit));
  height: calc(5 * var(--player-unit));
  border-right: calc(2 * var(--player-unit)) solid var(--player-speech-border-color);
  border-left: calc(2 * var(--player-unit)) solid var(--player-speech-border-color);
  background: var(--player-speech-background);
}
.player-speech::after {
  top: calc(100% + 4 * var(--player-unit));
  width: calc(8 * var(--player-unit));
  height: calc(3 * var(--player-unit));
  background: var(--player-speech-border-color);
}

/* ===================================================================
   PING AND ELIMINATION NOTICE
   =================================================================== */
.ping-indicator {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 2;
  padding: 5px 8px;
  border: var(--ui-ping-border);
  background: var(--ui-ping-background);
  color: var(--ui-ping-color);
  font-size: var(--ui-ping-size);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.ping-indicator[data-quality="good"] { color: #96e072; }
.ping-indicator[data-quality="fair"] { color: #ffe080; }
.ping-indicator[data-quality="poor"] { color: #ff8a65; }
.ping-indicator[data-quality="offline"] { color: #d9dee5; }

.elimination-status {
  position: absolute;
  z-index: 2;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 10px;
  border: 2px solid var(--ink);
  background: var(--ui-elimination-background);
  color: var(--ui-elimination-color);
  font-size: var(--ui-elimination-size);
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
  pointer-events: none;
}
.elimination-status[hidden] { display: none; }

.mobile-controls {
  display: none;
}

/* ===================================================================
   CHAT
   =================================================================== */
/* Lower interface below the canvas. */
.world-footer {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  background: var(--ui-mobile-controls-background);
  border-top: 4px solid var(--ink);
}

/* Chat panel fixed at the game window's bottom. */
.chat-card {
  position: static;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 165px;
  padding: var(--ui-chat-padding);
  border: var(--ui-chat-border);
  background: var(--ui-chat-background);
  box-shadow: none;
}

.chat-card #messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  touch-action: pan-y;
  overscroll-behavior-y: contain;
  margin: 6px 0;
  padding: 0 4px;
  font-size: var(--ui-chat-message-size);
  line-height: 1.35;
  color: var(--ui-chat-text-color);
}

.chat-card .section-title b { color: var(--ui-chat-title-color); }

.message {
  margin: 0 0 5px;
  word-break: break-word;
}

/* Player names stand out from messages; the local player's name uses a different color. */
.message .chat-name { color: var(--ui-chat-name-color); font-weight: bold; }
.message.own .chat-name { color: var(--ui-chat-own-name-color); }
.chat-card .message.system { color: var(--ui-chat-system-color); font-size: var(--ui-chat-notice-size); }
.chat-card .message.kill { color: var(--ui-chat-kill-color); font-style: normal; }

.system {
  color: var(--muted);
  font-style: italic;
}

.chat-card form {
  display: flex;
  flex-shrink: 0;
}

.chat-card input {
  width: 100%;
  min-width: 0;
  padding: var(--ui-chat-input-padding);
}

.chat-card button {
  background: var(--orange);
}

/* ===================================================================
   PLAYER LIST, ROOM, AND KILL RANKING
   =================================================================== */
/* Room sidebar and menus. */
.sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--ui-sidebar-gap);
}

.battle-map-picker {
  display: grid;
  gap: 6px;
  margin: 10px 0;
  font-size: 18px;
  font-weight: 700;
}

.battle-map-picker select {
  width: 100%;
}
.battle-map-picker[hidden] { display: none; }

.sidebar section {
  padding: var(--ui-sidebar-card-padding);
  border: var(--ui-sidebar-card-border);
  background: var(--ui-sidebar-card-background);
}

.room-card strong {
  font: var(--ui-room-code-size) var(--ui-heading-font);
  letter-spacing: 2px;
}

.section-title {
  display: flex;
  justify-content: space-between;
}

.players-card ul {
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

.players-card li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--ui-list-divider);
  font-size: var(--ui-player-list-size);
}

.player-list-name { min-width: 0; overflow-wrap: anywhere; }
.kick-player { flex: none; font-size: 18px; }

.kill-rank-list { list-style: none; margin: 0; padding: 0; max-height: min(45vh, 420px); overflow-y: auto; }
.kill-rank-list li { display: grid; grid-template-columns: 2.5em minmax(6em, 1fr) auto auto; gap: 8px; align-items: center; padding: 8px; border-bottom: 1px solid var(--ui-list-divider); font-size: 18px; }
.kill-rank-name { min-width: 0; overflow-wrap: anywhere; }
.kill-rank-position { font-weight: bold; }
.kill-rank-list .my-kill-rank { color: var(--mint); }
#arenaKillRanking { margin-top: 16px; }
#arenaKillRanking h2, .winner-kill-ranking h2 { margin: 0 0 8px; font-size: 18px; }

.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 7px;
  background: var(--c);
}

/* ===================================================================
   MATCH RESULTS AND PODIUM
   =================================================================== */
.winner-overlay {
  position: absolute;
  inset: 0;
  z-index: 8;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  color: var(--ui-winner-color);
  background: var(--ui-winner-background);
  text-align: center;
  padding: 16px;
  overflow-y: auto;
}

.winner-overlay[hidden] {
  display: none !important;
}

.winner-overlay > span {
  position: relative;
  z-index: 1;
  color: var(--mint);
  font: var(--ui-winner-title-size) var(--ui-heading-font);
  text-shadow: 4px 4px var(--ink);
}

.podium {
  display: flex;
  align-items: end;
  justify-content: center;
  gap: var(--ui-podium-gap);
  min-height: 145px;
}

.winner-results { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 18px; width: min(96%, 980px); }
.winner-kill-ranking { flex: 1 1 270px; max-width: 380px; min-width: 240px; padding: 12px; border: 2px solid var(--ui-list-divider); background: var(--ui-podium-card-background); text-align: left; }
.winner-kill-ranking .kill-rank-list { max-height: min(42vh, 390px); }

.podium-player {
  --podium-portrait-size: 200px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: var(--podium-portrait-size);
  min-width: 0;
  padding: 0;
  gap: 0;
  border: 0;
  background: transparent;
  font-size: 18px;
  text-align: center;
}

.podium-player.rank-1 {
  --podium-portrait-size: var(--result-podium-size-1, 280px);
  order: 2;
}

.podium-player.rank-2 {
  --podium-portrait-size: var(--result-podium-size-2, 240px);
  order: 1;
}

.podium-player.rank-3 {
  --podium-portrait-size: var(--result-podium-size-3, 200px);
  order: 3;
}

.podium-rank {
  font-size: 18px;
  margin-bottom: 4px;
}

.result-ranked-points {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 36px;
  min-height: 0;
  padding: 4px 6px;
  border: var(--ui-podium-card-border);
  background: var(--ui-podium-card-background);
  color: var(--paper);
  font: 700 16px var(--ui-heading-font);
  white-space: nowrap;
}
.result-ranked-points .positive { color: var(--mint); }
.result-ranked-points .negative { color: var(--ui-team-result-lost-title); }
.team-result-row.won .result-ranked-points { border-color: var(--ui-team-result-won-border); }
.team-result-row.lost .result-ranked-points { border-color: var(--ui-team-result-lost-border); }
.team-result-card:has(.result-ranked-points) .team-result-mvp { top: 23px; }

.podium-avatar {
  margin: 0 !important;
}

#gameScreen .world-wrap canvas.podium-skin {
  flex: none;
  width: 80px;
  height: 80px;
  aspect-ratio: auto;
  background: transparent;
  image-rendering: pixelated;
}

/* Sprites fill larger frames while preserving pixel art. */
/* Character size and position come from Game settings > Result screen. */
.podium-player.rank-1 .podium-avatar {
  transform: translate(var(--result-skin-x, 0px), var(--result-skin-y, 0px)) scale(var(--result-podium-zoom-1, 3));
}

.podium-player.rank-2 .podium-avatar {
  transform: translate(var(--result-skin-x, 0px), var(--result-skin-y, 0px)) scale(var(--result-podium-zoom-2, 2.4));
}

.podium-player.rank-3 .podium-avatar {
  transform: translate(var(--result-skin-x, 0px), var(--result-skin-y, 0px)) scale(var(--result-podium-zoom-3, 2));
}

/* Card layers are configured in Game settings > Result screen > Layers; higher values appear on top.
   Background, character, border, text, league emblem, and MVP each have their own element.
   Portrait elements occupy the portrait grid cell; absolute grid children use that cell as their bounds. */
.podium-player, .team-result-card { position: relative; isolation: isolate; }
.podium-rank-portrait, .team-result-square { z-index: var(--result-layer-background, 1); }
.result-portrait-skin {
  position: absolute; inset: 0; grid-area: portrait; z-index: var(--result-layer-sprite, 2);
  display: flex; align-items: center; justify-content: center;
  /* The portrait row reserves space; it must not cut a larger character at the information row.
     The card has one backing behind both areas. Size and offsets still come from the editor. */
  overflow: visible; clip-path: none; pointer-events: none;
}
:is(.podium-player, .team-result-card) > .rank-portrait-frame { position: absolute; inset: 0; grid-area: portrait; z-index: var(--result-layer-frame, 3); }
.result-portrait-border {
  position: absolute; inset: 0; grid-area: portrait; z-index: var(--result-layer-frame, 3); box-sizing: border-box;
  border: var(--result-border-width, 2px) solid var(--ui-team-result-won-border);
  clip-path: var(--result-portrait-clip, none); pointer-events: none;
}
.team-result-row.lost .result-portrait-border { border-color: var(--ui-team-result-lost-border); }
.result-info-bg {
  position: absolute; inset: 0; z-index: var(--result-layer-background, 1); box-sizing: border-box; pointer-events: none;
  border: var(--ui-podium-card-border); border-top: 0; background: var(--ui-podium-card-background);
}
:is(.podium-info, .team-result-info) :is(.result-player-name, small), .result-ranked-points, .podium-rank { position: relative; z-index: var(--result-layer-text, 4); }
/* The league emblem is a separate card layer centered on the lower frame edge. It must not
   follow information offsets or end up on the character. Rank offsets still move it from here. */
.podium-rank-badge, .team-result-rank-badge {
  position: absolute; grid-column: 1; grid-row: 2 / 4;
  z-index: var(--result-layer-emblem, 5); left: calc(50% - 16px);
  top: auto; bottom: -16px; width: 32px; height: 32px; margin: 0;
  object-fit: contain; image-rendering: pixelated;
}

.podium-info, .team-result-info {
  box-sizing: border-box;
  display: grid;
  justify-items: var(--result-info-justify, center);
  align-content: start;
  gap: var(--result-info-gap, 3px);
  width: 100%;
  padding: var(--result-info-padding, 5px 3px);
  font-size: var(--result-line-size, 14px);
  text-align: var(--result-info-align, center);
  /* Moved by offsets, not transform: a transform would close its texts and emblem in a layer of their own. */
  position: relative;
  left: var(--result-info-x, 0px);
  top: var(--result-info-y, 0px);
}
.podium-info b, .team-result-info b {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: var(--result-info-justify, center);
  gap: 3px;
  max-width: 100%;
  min-width: 0;
  color: var(--result-name-color, inherit);
  font-size: var(--result-name-size, 14px);
}
.result-player-name {
  min-width: 0;
  overflow-wrap: anywhere;
  text-align: var(--result-info-align, center);
}

.podium-player small {
  color: var(--result-line-color, var(--mint));
  font-size: var(--result-line-size, 14px);
  overflow-wrap: anywhere;
}
/* Reserve an external band below each card for optional points. Receiving points must never
   resize the portrait, information or league frame, even when no score is available yet. */
.podium-player, .team-result-card {
  display: grid; grid-template-columns: 100%; grid-template-rows: 32px auto auto auto;
  grid-template-areas: "rank" "portrait" "info" "points"; align-content: start;
}
.podium-rank { grid-area: rank; }
.result-card-extras { grid-area: points; display: grid; min-width: 0; min-height: calc(var(--result-points-gap, 50px) + 36px); padding-top: var(--result-points-gap, 50px); box-sizing: border-box; overflow: hidden; }
.podium-rank-portrait, .team-result-square { grid-area: portrait; }
.podium-info, .team-result-info { grid-area: info; }
body[data-result-info="above"] :is(.podium-player, .team-result-card) { grid-template-areas: "rank" "info" "portrait" "points"; }
body[data-result-info="above"] .result-info-bg { border-top: var(--ui-podium-card-border); border-bottom: 0; }
body[data-result-info="over"] :is(.podium-info, .team-result-info) { grid-area: portrait; align-self: end; }
body[data-result-info="over"] .result-info-bg { border-top: var(--ui-podium-card-border); }

/* Team results: winners above (MVP = most kills), defeated players below in red frames.
   Colors are defined in 00-variables.css. */
.winner-overlay.layout-teams .podium { display: block; width: 100%; min-height: 0; }
.winner-overlay.layout-teams .winner-kill-ranking,
.winner-overlay.layout-teams > span { display: none; }
.team-results { display: grid; gap: var(--result-row-gap, 14px); }
.team-result-row h3 { margin: 0 0 10px; font: 18px var(--ui-heading-font); text-shadow: 2px 2px var(--ink); }
.team-result-row.won h3 { color: var(--ui-team-result-won-title); }
.team-result-row.lost h3 { color: var(--ui-team-result-lost-title); margin-bottom: 20px; }
.team-result-cards { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px var(--result-card-gap, 10px); }
.team-result-info { gap: var(--result-info-gap, 5px); padding: var(--result-info-padding, 10px 8px); }
.team-result-card {
  position: relative;
  display: grid;
  align-items: stretch;
  gap: 0;
  width: var(--result-card-width, var(--ui-team-result-card-width));
  padding: 0;
  border: 0;
  background: transparent;
  font-size: 18px;
}
.team-result-row.won .result-info-bg { border-color: var(--ui-team-result-won-border); }
.team-result-row.lost .result-info-bg { border-color: var(--ui-team-result-lost-border); }
.team-result-card.is-me .result-info-bg { box-shadow: inset 0 -2px var(--mint); }
.team-result-square {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  height: var(--result-portrait-height, var(--result-card-width, var(--ui-team-result-card-width)));
  /* The frame's shape (editor): a clip, since the pixel theme sets every border-radius to 0. */
  clip-path: var(--result-portrait-clip, none);
  background: var(--ui-team-result-won-square);
}
.rank-portrait-frame { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; image-rendering: pixelated; pointer-events: none; }
.team-result-row.lost .team-result-square { background: var(--ui-team-result-lost-square); }
/* Enlarge the sprite to fill the portrait despite transparent space in its frame. */
.team-result-skin { flex: none; width: calc(var(--result-card-width, var(--ui-team-result-card-width)) * var(--result-skin-zoom, var(--ui-team-result-skin-zoom))); max-width: none; height: auto; image-rendering: pixelated;
  transform: translate(var(--result-skin-x, 0px), var(--result-skin-y, 0px)); }
.team-result-mvp {
  position: absolute;
  box-sizing: border-box;
  min-width: 72px;
  height: 26px;
  text-align: center;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  padding: 1px 7px;
  border: 2px solid var(--ink);
  background: var(--ui-team-result-mvp-background);
  color: var(--ui-team-result-mvp-color);
  font: 700 18px/20px var(--ui-heading-font);
}
.team-result-card small { color: var(--result-line-color, var(--mint)); font-size: var(--result-line-size, 14px); overflow-wrap: anywhere; text-align: var(--result-info-align, center); }
.team-result-row.lost .team-result-status { color: var(--ui-team-result-lost-title); }

.winner-actions {
  display: flex;
  gap: 12px;
}

/* ===================================================================
   GAME SCREEN LAYOUT
   Chat over the canvas, battle countdown, and chat visibility control.
   =================================================================== */
/* Gameplay uses one canvas with interface panels over it. */
.shell:has(#gameScreen:not([hidden])) {
  max-width: var(--ui-game-shell-width);
  padding: var(--ui-game-shell-padding);
}
.shell:has(#gameScreen:not([hidden])) > header { display: none; }
#gameScreen .game-layout { display: block; }
#gameScreen .world-wrap { max-width: none; width: 100%; }
#gameScreen .world-wrap canvas#world { aspect-ratio: var(--ui-canvas-aspect-ratio); }
/* Game settings can hide the ping display. */
body.hide-ping #pingIndicator { display: none !important; }
#gameScreen .game-view { width: 100%; }
#gameScreen .world-footer {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: block;
  padding: 0;
  background: transparent;
  border: 0;
  pointer-events: none;
}
#gameScreen .world-footer > * { pointer-events: auto; }
#gameScreen .world-footer > .ability-hud { pointer-events: none; }
#gameScreen .chat-card {
  position: absolute;
  left: var(--ui-chat-left);
  bottom: var(--ui-chat-bottom);
  width: var(--chat-user-width, var(--ui-chat-width));
  height: var(--chat-user-height, var(--ui-chat-height));
  min-height: var(--ui-chat-min-height);
  min-width: 240px;
  max-width: 94%;
  max-height: 92%;
  resize: none;
  overflow: hidden;
  margin: 0;
  background: var(--ui-chat-background);
  border: var(--ui-chat-border);
  box-shadow: none;
}
.chat-resize-handle {
  position: absolute;
  z-index: 2;
  top: 0;
  right: 0;
  width: 22px;
  height: 22px;
  cursor: nesw-resize;
  touch-action: none;
}
.chat-resize-handle::after {
  content: '';
  position: absolute;
  top: 5px;
  right: 5px;
  width: 9px;
  height: 9px;
  border-top: 3px solid #a9e878;
  border-right: 3px solid #a9e878;
}
.battle-countdown {
  position: absolute;
  z-index: 7;
  inset: 0;
  display: grid;
  place-content: center;
  color: #fff6dc;
  font: 52px var(--ui-heading-font);
  text-align: center;
  text-shadow: 4px 4px 0 #182029;
  pointer-events: none;
}
.battle-countdown[hidden] { display: none; }
.battle-countdown small { display: block; margin-bottom: 14px; font: 18px var(--ui-heading-font); }
.kill-notices {
  position: absolute;
  z-index: 7;
  top: 15%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  gap: 6px;
  width: min(90%, 720px);
  pointer-events: none;
  padding: 20px;
}
.kill-notices[hidden] { display: none; }
.kill-notice {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 48px;
  padding: 8px 14px;
  border: 3px solid var(--z-outline, #1e140c);
  background: var(--z-night-2, #2a2016);
  color: var(--z-light-text, #f7ecce);
  box-shadow: inset 0 0 0 2px var(--z-gold-dark, #a8711d), 4px 4px 0 #0009;
  font: 18px/1.25 var(--ui-game-font);
  text-align: center;
  overflow-wrap: anywhere;
}
.kill-notice-skill {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 2px solid var(--z-wood-light, #8d5d34);
  background: var(--z-wood-dark, #3b2516);
  pointer-events: auto;
  cursor: help;
}
.kill-notice-skill .ability-icon { font-size: calc(26px * var(--slot-icon-scale, 1)); line-height: 1; color: var(--slot-icon-color, inherit); }
.kill-notice-skill .icon-image { width: 1em; height: 1em; image-rendering: pixelated; }
@media (max-width: 600px) {
  .kill-notice { gap: 8px; min-height: 40px; padding: 5px 8px; font-size: 14px; }
  .kill-notice-skill { width: 30px; height: 30px; }
}
.match-clock { position: absolute; z-index: 6; top: 14px; left: 50%; transform: translateX(-50%); padding: 7px 10px;
  background: #182029dd; color: #fff6dc; border: 2px solid #a9e878; font: 18px var(--ui-heading-font); pointer-events: none; }
.elimination-status:not([hidden]) ~ .match-clock { top: 54px; }
.match-clock[hidden] { display: none; }
#gameScreen .chat-card[hidden],
#gameScreen .menu-overlay[hidden],
#gameScreen .menu-panel[hidden],
#gameScreen .menu-content > [hidden] { display: none !important; }
.hud-toggle {
  position: absolute;
  z-index: 6;
  background: var(--paper);
  box-shadow: 3px 3px 0 var(--ink);
  font-size: 18px;
  padding: 7px 10px;
}
.chat-toggle { left: var(--ui-chat-toggle-left); bottom: var(--ui-chat-toggle-bottom); min-width: 34px; font-size: 18px; line-height: 1; padding: 4px 7px; }
.world-wrap:has(.chat-card[hidden]) .chat-toggle { bottom: 1.5%; }
#gameScreen .ping-indicator { top: var(--ui-ping-top); left: var(--ui-ping-left); }
/* Training bot controls sit below the ping and match clock.
   They move down when elimination notices appear, avoiding overlap on narrow screens. */
.practice-controls { position: absolute; z-index: 6; top: max(calc(var(--ui-ping-top) + 34px), 58px); left: var(--ui-ping-left); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; max-width: 70%; }
.game-view:has(> .elimination-status:not([hidden])) > .practice-controls { top: max(calc(var(--ui-ping-top) + 34px), 98px); }
.practice-controls[hidden] { display: none; }
.practice-controls button { padding: 5px 9px; background: var(--paper); box-shadow: 3px 3px 0 var(--ink); font-size: 18px; font-weight: 700; }
.practice-controls button[hidden] { display: none; }
.practice-controls button:disabled { opacity: .5; }
.practice-controls #botDifficultyButton[data-difficulty="easy"] { background: #c7ecaa; }
.practice-controls #botDifficultyButton[data-difficulty="super-easy"] { background: #aee6f0; }
.practice-bot-count { padding: 3px 6px; background: var(--ui-ping-background); color: var(--paper); font-size: 18px; font-weight: 700; }
.practice-bot-count:empty { display: none; }
/* Spectating controls follow a living player at the left-center of the screen.
   The main button enables following; the adjacent arrow chooses the player. */
.spectator-follow {
  position: absolute;
  z-index: 6;
  left: 1.5%;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: stretch;
  max-width: 44%;
}
.spectator-follow[hidden] { display: none; }
.spectator-follow > button {
  background: var(--paper);
  box-shadow: 3px 3px 0 var(--ink);
  font-size: 18px;
  font-weight: 700;
  padding: 7px 10px;
}
#spectatorFollowButton { display: flex; align-items: center; gap: 6px; min-width: 0; }
#spectatorFollowMenuButton { margin-left: 3px; padding: 7px 8px; font-size: 18px; line-height: 1; }
#spectatorFollowButton[aria-pressed="true"] { background: var(--ui-ping-background); color: var(--paper); }
.spectator-follow-icon { font-size: 18px; line-height: 1; }
#spectatorFollowLabel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spectator-follow-menu {
  position: absolute;
  left: 0;
  top: calc(100% + 6px);
  display: flex;
  flex-direction: column;
  min-width: 100%;
  max-height: 220px;
  overflow-y: auto;
  background: var(--paper);
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
}
.spectator-follow-menu[hidden] { display: none; }
.spectator-follow-menu button {
  text-align: left;
  font-size: 18px;
  padding: 7px 10px;
  border: 0;
  box-shadow: none;
  background: transparent;
  white-space: nowrap;
}
.spectator-follow-menu button[aria-checked="true"] { background: #0000001a; }

/* ===================================================================
   READY / START PANEL
   =================================================================== */
.lobby-hud {
  --lobby-requested-right: var(--ui-lobby-right);
  position: absolute;
  z-index: 7;
  top: var(--ui-lobby-top);
  right: clamp(var(--ui-lobby-margin), var(--lobby-requested-right), max(var(--ui-lobby-margin), calc(100% - var(--ui-lobby-width) - var(--ui-lobby-margin))));
  width: var(--ui-lobby-width);
  max-width: calc(100% - 2 * var(--ui-lobby-margin));
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ui-lobby-gap);
  padding: var(--ui-lobby-padding);
  border: var(--ui-lobby-border);
  background: var(--ui-lobby-background);
  box-shadow: var(--ui-lobby-shadow);
}
.lobby-hud[hidden], .lobby-hud button[hidden] { display: none !important; }
.lobby-ready-count { min-width: 0; max-width: 100%; overflow-wrap: anywhere; font-size: var(--ui-lobby-count-size); font-weight: 700; }
.lobby-hud button { min-width: 0; max-width: 100%; flex: 1 1 auto; padding: 7px 10px; font-size: var(--ui-lobby-button-size); white-space: normal; overflow-wrap: anywhere; }

/* ===================================================================
   BATTLE SKILL SLOTS
   =================================================================== */
.ability-hud { position: absolute; z-index: 5; left: 50%; bottom: var(--ui-ability-bottom); display: flex; flex-direction: column; align-items: stretch; width: max-content; gap: 6px; transform: translateX(-50%); padding: 0; background: transparent; border: 0; color: var(--ui-ability-slot-color); font: 18px monospace; }
.battle-stats { position: absolute; z-index: 6; right: var(--ui-dock-right); bottom: calc(var(--ui-dock-bottom) + 90px); width: 180px; max-width: 35%; color: #fff3c6; font: 14px/1.2 var(--ui-game-font); filter: drop-shadow(3px 3px 0 #101419); }
.battle-stats[hidden] { display: none !important; }
.battle-stats summary { display: flex; align-items: center; justify-content: space-between; gap: 5px; min-height: 30px; padding: 4px 8px; border: 2px solid #101419; background: #5a351e; color: #fff3c6; cursor: pointer; list-style: none; }
.battle-stats summary::-webkit-details-marker { display: none; }
.battle-stats summary b { color: #a9e878; margin-left: auto; white-space: nowrap; }
.battle-stats-arrow { display: inline-block; transition: transform .12s; }
.battle-stats[open] .battle-stats-arrow { transform: rotate(180deg); }
.battle-stats-content { position: absolute; bottom: 100%; left: 0; width: 100%; box-sizing: border-box; padding: 5px 8px 7px; border: 2px solid #101419; border-bottom: 0; background: #211d19ee; }
.battle-stats-content > div { display: flex; justify-content: space-between; gap: 8px; padding: 3px 0; border-bottom: 1px solid #8d5d3466; }
.battle-stats-content > div:last-child { border-bottom: 0; }
.battle-stats-content b { color: #fff; text-align: right; white-space: nowrap; }
.battle-stats summary:focus-visible { outline: 2px solid #fff3c6; outline-offset: 2px; }
/* Energy below the slots regenerates over time and from map orbs.
   Slots align at the bottom because skill labels sit above them; dash has no label. */
/* Classes can have up to eight skills. Narrow screens wrap the bar into two rows,
   leaving space for the second row's level-up buttons. */
/* Skill information appears above the bar and closes when dismissed. */
.skill-info-popup { position: absolute; z-index: 8; left: 50%; bottom: calc(var(--ui-ability-bottom) + var(--ui-ability-slot-size) + 64px); width: min(420px, 90%);
  transform: translateX(-50%); padding: 10px 12px; border: 3px solid var(--ink); background: #182029f2; color: #fff3c6; box-shadow: 4px 4px 0 #101419; }
.skill-info-popup[hidden] { display: none; }
.skill-info-close { display: block; margin-top: 8px; font-size: 14px; opacity: .7; text-align: center; }
.ability-slots { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-end; gap: var(--ui-ability-gap); }
.ability-slots.has-points { row-gap: calc(var(--ui-ability-gap) + 30px); }
.energy-bar { position: relative; display: grid; gap: 2px; order: 1; }
/* One segment per 10 energy: full segments glow; the current segment fills gradually. */
.energy-sections { display: flex; gap: 3px; height: 18px; padding: 3px; border: 2px solid var(--ink); background: #182029e6; box-shadow: 2px 2px 0 #101419; }
.energy-section { position: relative; flex: 1 1 0; min-width: 2px; background: #2c3a47; overflow: hidden; }
.energy-section i { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--energy-fill-background, #2f86b8); }
.energy-section.full i { background: var(--energy-full-background, var(--energy-fill-background, linear-gradient(#9fe8ff, #35b9f1))); }
.energy-text { display: block; text-align: center; font-size: 18px; line-height: 12px; color: #e3fbff; text-shadow: 1px 1px var(--ink); order: -1; }
.ability-hud[hidden], .mobile-ability[hidden] { display: none !important; }
/* Each skill's slot appearance is configured in js/skill-slot.js:
   icon, background, border, and the position, color, and size of cost, level, key, and cooldown. */
.ability-slot { position: relative; display: grid; place-items: center; width: var(--ui-ability-slot-size); height: var(--ui-ability-slot-size); padding: 0; border: var(--ui-ability-slot-border); background: var(--slot-background, var(--ui-ability-slot-background)); color: var(--ui-ability-slot-color); font: inherit; cursor: pointer; box-shadow: 3px 3px 0 #101419; pointer-events: auto; }
.ability-slot.has-border-color { border-color: var(--slot-border-color); }
.ability-slot .ability-icon { font-size: calc(var(--ui-icon-ability-size) * var(--slot-icon-scale, 1)); line-height: 1; color: var(--slot-icon-color, inherit); }
.ability-slot .ability-cost { position: absolute; color: var(--slot-color, #9fe8ff); font-size: var(--slot-size, 10px); font-weight: bold; text-shadow: 1px 1px var(--ink); }
/* Nine anchor positions for slot information. */
.ability-slot .slot-at-top-left { top: 2px; left: 3px; }
.ability-slot .slot-at-top { top: 2px; left: 50%; transform: translateX(-50%); }
.ability-slot .slot-at-top-right { top: 2px; right: 4px; }
.ability-slot .slot-at-left { top: 50%; left: 3px; transform: translateY(-50%); }
.ability-slot .slot-at-center { top: 50%; left: 50%; transform: translate(-50%, -50%); }
.ability-slot .slot-at-right { top: 50%; right: 4px; transform: translateY(-50%); }
.ability-slot .slot-at-bottom-left { bottom: 2px; left: 3px; }
.ability-slot .slot-at-bottom { bottom: 2px; left: 50%; transform: translateX(-50%); }
.ability-slot .slot-at-bottom-right { bottom: 2px; right: 4px; }
/* Cooldown overlay recedes as the remaining time decreases. */
.ability-cooldown { position: absolute; inset: auto 0 0 0; height: 0; background: #101419c4; display: grid; place-items: center; pointer-events: none; }
.ability-cooldown span { color: var(--slot-color, #fff3c6); font-size: var(--slot-size, 13px); font-weight: bold; font-style: normal; text-shadow: 1px 1px var(--ink); }
.ability-cooldown.no-number span { display: none; }
.ability-slot.no-energy .ability-icon { opacity: .35; filter: grayscale(1); }
.ability-slot.no-energy .ability-cost { color: #ff8a65; }
.ability-slot.empty { opacity: .45; cursor: default; }
.ability-slot.denied { animation: ability-denied .32s ease; }
@keyframes ability-denied { 25% { transform: translateX(-3px); border-color: #ff665e; } 75% { transform: translateX(3px); border-color: #ff665e; } }
.ability-slot .ability-key { position: absolute; color: var(--slot-color, #fff3c6); font-size: var(--slot-size, 13px); text-shadow: 1px 1px var(--ink); }
/* Dash (Space) is separated from skill slots by a dashed line. */
.ability-slot.dash-slot { margin-left: 22px; }
.ability-slot.dash-slot::before { content: ''; position: absolute; left: -15px; top: 10%; height: 80%; border-left: 2px dashed rgba(159, 232, 255, .6); pointer-events: none; }
/* A level-up button spends an available skill point on that skill. */
.ability-slot-wrap { position: relative; display: flex; flex-direction: column; align-items: center; width: var(--ui-ability-slot-size); }
/* Active skills and buffs appear centered above the bar, with remaining-duration indicators. */
.ability-actives { order: -1; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; min-height: 0; transform: translateY(-10vh); }
.ability-actives:empty { display: none; }
.ability-active-chip { display: grid; justify-items: center; gap: 3px; width: 47px; }
.ability-active-icon { display: grid; place-items: center; width: 44px; height: 44px; border: 2px solid var(--ink); background: var(--slot-background, var(--ui-ability-slot-background)); color: var(--slot-icon-color, var(--ui-ability-slot-color)); box-shadow: 2px 2px 0 #101419; font-size: calc(26px * var(--slot-icon-scale, 1)); line-height: 1; overflow: hidden; }
.ability-active-icon .icon-image { width: 1em; height: 1em; }
.ability-active-chip.is-status .ability-active-icon { font-size: 23px; }
.ability-active-bar { display: block; width: 100%; height: 6px; border: 1px solid var(--ink); background: #182029cc; }
.ability-active-bar i { display: block; height: 100%; width: 100%; background: #96e072; }
.ability-active-chip.is-status .ability-active-bar i { background: #8fd3ff; }
/* Charged skills show stored uses in the slot's upper-right corner. */
.ability-charges { position: absolute; z-index: 2; right: -5px; bottom: calc(var(--ui-ability-slot-size) - 9px); min-width: 16px; padding: 0 3px;
  border: 2px solid #182029; background: #ffd23f; color: #182029; font-size: 18px; line-height: 14px; text-align: center; pointer-events: none; }
.ability-charges.is-empty { background: #6b6f78; color: #fff3c6; }
.ability-slots.has-points { padding-top: 28px; }
.skill-up { position: absolute; left: 50%; bottom: calc(100% + 5px); z-index: 2; display: grid; place-items: center; width: 24px; height: 24px; padding: 0; transform: translateX(-50%); pointer-events: auto;
  border: 2px solid #101419; background: #ffd23f; color: #101419; font: 700 18px/1 monospace; box-shadow: 2px 2px 0 #101419; cursor: pointer; animation: skill-up-bob 1.1s ease-in-out infinite; }
.skill-up:hover, .skill-up:focus-visible { background: #fff3a0; outline: 2px solid #fff3c6; outline-offset: 1px; }
@keyframes skill-up-bob { 50% { transform: translateX(-50%) translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .skill-up { animation: none; } }
.ability-slot .ability-level { position: absolute; color: var(--slot-color, #ffd23f); font-size: var(--slot-size, 9px); font-weight: bold; text-shadow: 1px 1px var(--ink); }
.ability-slot.dash-slot .ability-icon { font-weight: 700; letter-spacing: -2px; }
.ability-slot.selected { border-color: var(--ui-ability-selected-border); background: var(--ui-ability-selected-background); box-shadow: 0 0 0 2px #fff3c6, 3px 3px 0 #101419; }
.ability-slot:disabled { opacity: .62; cursor: default; }
.mobile-ability { align-self: center; max-width: 68px; background: #f6c464; border: 2px solid #182029; color: #182029; font-size: 18px; font-weight: bold; padding: 8px 4px; transition: opacity .15s; }
.mobile-ability.inactive { opacity: var(--ui-mobile-ability-inactive-opacity); }

/* ===================================================================
   CENTERED GAME WINDOW
   fitGameWindow in 01-core.js computes the largest window with the configured aspect ratio that fits the browser.
   =================================================================== */
.shell:has(#gameScreen:not([hidden])) {
  box-sizing: border-box;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
#gameScreen .world-wrap { margin-inline: auto; }
/* Tournament badge and notice stay inside the game window. */
#gameScreen .world-wrap > .tournament-status-badge {
  position: absolute;
  top: calc(var(--ui-ping-top) + 34px);
  left: var(--ui-ping-left);
}
#gameScreen .world-wrap:has(#practiceControls:not([hidden])) > .tournament-status-badge { top: calc(max(calc(var(--ui-ping-top) + 34px), 58px) + 42px); }
#gameScreen .world-wrap > .global-tournament-notice { position: absolute; top: 12px; max-width: min(90%, 550px); }
/* The badge opens tournaments and hides while that panel is open. */
#gameScreen .world-wrap:has(#tournamentMenu:not([hidden])) > .tournament-status-badge { display: none; }
/* ===================================================================
   INTERFACE SCALE
   Overlays follow the game window using --ui-scale, computed by fitGameWindow and ui-scale.js.
   Game settings > Interface defines reference size and bounds. Panels only shrink via --ui-panel-scale.
   Overhead labels follow --player-unit. Mobile controls below the world retain touch-friendly sizes.
   Within zoomed elements, px and viewport units scale together; percentages remain relative to the game window.
   =================================================================== */
#gameScreen .world-wrap > :is(.tournament-status-badge, .global-tournament-notice),
#gameScreen .game-view > :not(canvas, .player-hud-layer),
#gameScreen .world-footer > :is(.ability-hud, .chat-card, .skill-info-popup) { zoom: var(--ui-scale, 1); }
#gameScreen .world-wrap > .menu-overlay { zoom: var(--ui-panel-scale, 1); }
@media (max-width: 720px) {
  #gameScreen .world-footer > :is(.ability-hud, .chat-card, .skill-info-popup),
  #gameScreen .world-wrap > .menu-overlay { zoom: 1; }
}
/* Results fill the mobile screen (05-mobile.css) and retain touch-friendly sizing. */
@media (max-width: 600px) { #gameScreen .game-view > .winner-overlay { zoom: 1; } }

/* On mobile, the panel sheet rises above the controls and stays within the game width.
   syncMobileSheet computes its horizontal bounds. */
@media (max-width: 720px) {
  #gameScreen .world-wrap .menu-overlay:not(:has(#tournamentMenu:not([hidden]))):not(:has(#rankMenu:not([hidden]))) {
    left: var(--mobile-sheet-left, 0);
    right: var(--mobile-sheet-right, 0);
    bottom: var(--mobile-sheet-bottom, 0);
  }
}

/* ===================================================================
   FULL SCREEN (DOCK BUTTON OR ALT+ENTER)
   The game window is centered at the largest fitting size. Remaining space stays black and noninteractive.
   =================================================================== */
html.game-fullscreen,
html.game-fullscreen body { height: 100%; overflow: hidden; background: #000; }
html.game-fullscreen body::before,
html.game-fullscreen body::after { display: none; }
html.game-fullscreen .shell:has(#gameScreen:not([hidden])) {
  max-width: none;
  height: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;
}
html.game-fullscreen #gameScreen .world-wrap { border: 0; box-shadow: none; }

/* ===== Training (js/training.js) ===== */
/* Battles > Training: two main choices. */
.training-modes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 10px; }
.training-mode { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 10px; align-items: center; padding: 10px 12px; border: 2px solid var(--ink); background: var(--paper); color: var(--ink); box-shadow: 3px 3px 0 var(--ink); text-align: left; }
.training-mode > span { grid-row: 1 / 3; font-size: 28px; }
.training-mode small { font-size: 14px; font-weight: 400; line-height: 1.3; opacity: .8; }
.training-mode:hover { background: #fff5d9; }
/* The guided tutorial's coach, over the game (right, under the minimap). */
.training-coach { position: absolute; z-index: 7; top: 180px; right: var(--ui-ping-left); width: min(360px, 42%); padding: 10px 12px; border: 3px solid var(--ink); background: var(--paper); color: var(--ink); box-shadow: 4px 4px 0 var(--ink); font-size: 16px; line-height: 1.35; }
.training-coach[hidden] { display: none; }
/* While the guided coach is open the kill lines (raised to the top layer by notice-layers.js) would cross its text;
   the eliminations still show in the chat. */
body.training-guided #killNotices { visibility: hidden; }
.training-coach h3 { margin: 6px 0 4px; font-size: 18px; }
.training-coach p { margin: 6px 0 0; }
.training-coach-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.training-coach-head small { font-weight: 700; color: #6b4a1f; }
.training-coach-leave { min-height: 0; padding: 0 7px; border: 2px solid var(--ink); background: #e8d8b0; font-size: 18px; line-height: 1.2; }
.training-coach-dots { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.training-coach-dots i { width: 12px; height: 12px; border: 2px solid var(--ink); background: #d9cba6; }
.training-coach-dots i.done { background: #6fbf4a; }
.training-coach-dots i.current { background: #f2c14e; }
.training-coach-step { font-weight: 700; }
.training-coach-skill { font-size: 14px; color: #566174; }
.training-coach progress { width: 100%; height: 10px; margin-top: 8px; accent-color: #6fbf4a; }
.training-coach-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
/* A new account's first entry: the characters and the tutorial. */
.tutorial-intro { position: absolute; z-index: 30; inset: 0; display: grid; place-items: center; padding: 16px; background: rgb(16 20 25 / .72); }
.tutorial-intro[hidden] { display: none; }
.tutorial-intro-card { width: min(920px, 100%); max-height: 100%; overflow: auto; padding: 18px 20px; border: 4px solid var(--ink); background: var(--paper); color: var(--ink); box-shadow: 6px 6px 0 var(--ink); }
.tutorial-intro-card h2 { margin: 0 0 6px; font-size: 26px; }
.tutorial-intro-card > p { margin: 0 0 12px; }
.tutorial-intro-classes { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }
.tutorial-intro-class { display: grid; justify-items: center; align-content: start; gap: 6px; padding: 12px; border: 3px solid var(--ink); background: #fffaf0; color: var(--ink); box-shadow: 3px 3px 0 var(--ink); text-align: center; }
.tutorial-intro-class canvas { width: 120px; height: 120px; background: #33404e; image-rendering: pixelated; }
.tutorial-intro-class b { font-size: 20px; }
.tutorial-intro-class p { margin: 0; font-size: 14px; font-weight: 400; line-height: 1.3; }
.tutorial-intro-class.selected { outline: 4px solid #f2c14e; outline-offset: 2px; background: #fff2cf; }
.tutorial-intro-stats { display: grid; gap: 2px; width: 100%; font-size: 14px; }
.tutorial-intro-stats span { display: flex; justify-content: space-between; gap: 6px; }
.tutorial-intro-hint { margin: 12px 0 0; font-size: 14px; opacity: .8; }
.tutorial-intro-actions { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 10px; margin-top: 12px; }

.world-wrap #nativeMapFrame { position:absolute; z-index:0; border:0; pointer-events:none; }
.world-wrap canvas#world.native-map-active { background:transparent; position:relative; }

/* Presentation uses the teams result cards, without result-only information. */
#winnerOverlay.is-intro {
  background: var(--intro-background, #10191d) var(--intro-image, none) center / cover no-repeat;
  overflow: hidden; gap: 12px; padding: 16px;
}
#winnerOverlay.is-intro > #winnerTitle { display: block; flex: none; font-size: 24px; color: var(--ui-winner-color); }
#winnerOverlay.is-intro .winner-results { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; align-items: safe center; padding: 8px 12px 24px; box-sizing: border-box; }
#winnerOverlay.is-intro :is(.winner-actions, .winner-kill-ranking, .result-card-extras) { display: none; }
#winnerOverlay.is-intro .team-result-row h3 { color: var(--ui-winner-color); }
.battle-intro-progress { flex: none; width: min(96%, 980px); padding: 8px 12px; box-sizing: border-box; background: var(--intro-background, #10191d); }
.battle-intro-progress[hidden] { display: none; }
.battle-intro-progress p { margin: 0 0 8px; font-size: 18px; }
.battle-intro-track { height: 16px; border: 2px solid var(--t-card-border, #8d5d34); background: var(--intro-bar-background, #263a31); overflow: hidden; }
.battle-intro-track i { display: block; width: 100%; height: 100%; background: var(--intro-bar-color, #8ac75a); transform: scaleX(0); transform-origin: left; }

/* Keep navigation and floating notices out of the presentation. */
#gameScreen:has(#winnerOverlay.is-intro:not([hidden])) :is(#gameDock, .event-notice-sidebar, .tournament-status-badge, .global-tournament-notice, #menuOverlay) { visibility: hidden; pointer-events: none; }

#gameScreen .world-wrap:has(#winnerOverlay.is-intro:not([hidden])) { overflow: visible; }
