:root {
  color-scheme: light dark;
  --ink: #efece4; --ink-dim: #b9b3a4; --accent: #ffd76a; --danger: #ff6b6b; --good: #7be08a;
  --panel: rgba(20, 18, 24, 0.62); --panel-border: rgba(255, 255, 255, 0.14);
  /* route-map-editor.css names its accent --selected (the authoring page defines it the same way). */
  --selected: var(--good);
  --bg-a: #201a2b; --bg-b: #171018; --stage-radius: 14px;
}
@media (prefers-color-scheme: light) {
  :root { --ink: #211a12; --ink-dim: #5c5346; --panel: rgba(255, 255, 255, 0.72); --panel-border: rgba(0, 0, 0, 0.12); --bg-a: #d9cdb4; --bg-b: #b7a689; }
}
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
/* The stage does not clip (its bars show the blurred arena), so a transformed HUD part at the window edge -- the
   Rotate core leaning on hover, the reveal halo -- must never widen the page into a horizontal scroll. `clip` (not
   `hidden`) leaves nothing to scroll even by focus; the root keeps its own overflow so body's is not handed to it. */
html { overflow: auto; }
body { overflow-x: clip; }
body { font: 14px/1.4 system-ui, sans-serif; color: var(--ink); background: #111; }

.stage {
  position: relative; width: 100vw; height: 100vh; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 16 / 9; margin: 0 auto;
  /* Bottom-HUD lengths are cqw of this stage (player-hud-tune.js), so they scale with the board. */
  container-type: size;
  /* Potions and the usable dock share one baseline at the bottom edge, below the board. */
  --hud-dock-bottom: calc(var(--player-hud-bottom, clamp(4px, 0.42cqw, 8px)) + clamp(1px, 0.21cqw, 4px));
}
@media (min-aspect-ratio: 16/9) { .stage { width: calc(100vh * 16 / 9); height: 100vh; } }
@media (max-aspect-ratio: 16/9) { .stage { width: 100vw; height: calc(100vw * 9 / 16); } }
/* A window wider than 16:9 letterboxes the stage; the bars show the blurred arena (.bg-layer::before), so the
   stage does not clip. The HUD stays inside the stage: the right group sits at the stage's right edge, never in
   a bar (user 2026-10-02). */
.stage { overflow: visible; }
.rotate-controls, .usables-dock { --stage-gutter-right: 0px; }

.bg-layer {
  position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 50% 20%, var(--bg-a), var(--bg-b));
  background-size: cover; background-position: center;
}
.bg-layer.has-image { background-image: var(--bg-image); }
/* The stage is 16:9; a window of another shape leaves bars around it. They show the same arena, blurred and
   dimmed, instead of black. The fill reaches the window edges from inside the stage (100cqw/cqh is the stage),
   below everything the stage paints. The box ends exactly at the window edges and is not transformed, so it
   never adds page scroll (the blur's spill is ink overflow only). */
.bg-layer.has-image::before {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  /* The stage is centred across and pinned to the top: side bars split the spare width, the spare height is below. */
  inset: 0 calc(-1 * max(0px, (100vw - 100cqw) / 2)) calc(-1 * max(0px, 100vh - 100cqh));
  background: var(--bg-image) center / cover no-repeat;
  filter: blur(24px) brightness(0.55);
}

/* Dev console bar: grouped controls on one compact panel row, clearly separate from player UI. */
.dev-mode .dev-map-toolbar { position: fixed; z-index: 1001; }
.topbar {
  position: absolute; top: 8px; left: 8px; right: 48px; z-index: 30;
  display: flex; gap: 0; align-items: center;
  font-size: 11px; color: var(--ink-dim);
  background: rgba(14, 12, 18, 0.82);
  border: 1px solid var(--panel-border);
  border-radius: 8px; padding: 3px 6px;
  backdrop-filter: blur(6px);
  flex-wrap: wrap; row-gap: 2px;
}
.topbar .tb-group {
  display: flex; gap: 4px; align-items: center;
  padding: 0 6px; border-left: 1px solid rgba(255, 255, 255, 0.12);
}
.topbar .tb-group:first-child { border-left: 0; padding-left: 2px; }
.dev-badge {
  font-size: 9px; font-weight: 800; letter-spacing: 0.08em;
  color: #ffb4a9; background: rgba(255, 99, 71, 0.16);
  border: 1px solid rgba(255, 99, 71, 0.5);
  border-radius: 4px; padding: 1px 5px;
}
/* which run the dev tools act on. Green = the real run; amber = a throwaway fixture scene. */
.dev-run-kind {
  font-size: 9px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap;
  border-radius: 4px; padding: 1px 5px; border: 1px solid;
}
.dev-run-kind[data-kind="live"] { color: #9be6a8; background: rgba(76, 175, 80, 0.14); border-color: rgba(76, 175, 80, 0.5); }
.dev-run-kind[data-kind="fixture"] { color: #ffd98a; background: rgba(255, 179, 0, 0.14); border-color: rgba(255, 179, 0, 0.5); }
.tb-brand { color: var(--ink); font-size: 11px; white-space: nowrap; }
.tb-field { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.tb-scene-title { color: var(--ink-dim); max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar select, .topbar button {
  font: inherit; color: var(--ink); background: var(--panel); border: 1px solid var(--panel-border);
  border-radius: 5px; padding: 2px 7px; backdrop-filter: blur(6px); white-space: nowrap;
}
.topbar select { max-width: 170px; }
.topbar button { cursor: pointer; }
.topbar .tb-btn-text { margin-left: 3px; }
.editor-link {
  color: var(--ink-dim); text-decoration: none; white-space: nowrap;
  border: 1px solid var(--panel-border); border-radius: 5px; padding: 2px 7px;
}
.editor-link:hover { color: var(--ink); border-color: rgba(255, 255, 255, 0.35); }
.editor-link--editor { color: #7be08a; }
.editor-link--items { color: #ffd166; }

/* The renderer positions board and characters in a full-stage canvas. */
.arena-wrap { position: absolute; inset: 0; }
.board-frame { position: absolute; inset: 0; }
canvas#arena { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: manipulation; }

.hud { position: absolute; z-index: 20; display: flex; flex-direction: column; gap: 8px; }
.hud-left { left: var(--player-hud-left, clamp(6px, 0.73cqw, 14px)); bottom: var(--player-hud-bottom, clamp(4px, 0.42cqw, 8px)); width: var(--player-hud-width, clamp(200px, 18.75cqw, 360px)); }
.hud-right { right: 14px; top: 44px; width: 260px; max-height: 46vh; }

/* Draw only live HP and Mana crystals above the complete player frame. */
.player-card {
  position: relative; width: 100%; aspect-ratio: 3 / 1; padding: 0; border: 0; background: none;
  filter: drop-shadow(0 7px 10px rgba(0,0,0,0.62)); transition: filter 0.15s ease;
}
.player-hud-skin { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; user-select: none; transform: translate(var(--player-skin-dx, 0px), var(--player-skin-dy, 0px)) scale(var(--player-skin-scale, 1)); }
.player-portrait-well {
  position: absolute; left: 8.2%; top: 14.1%; width: 23.9%; height: 71.8%;
  overflow: hidden; border-radius: 50%; z-index: 1; pointer-events: none; user-select: none;
  transform: translate(var(--player-skin-dx, 0px), var(--player-skin-dy, 0px)) scale(var(--player-skin-scale, 1));
  background: radial-gradient(ellipse at 48% 42%, #17483f 0%, #0b332e 62%, #082620 100%);
}
.player-portrait-image {
  display: block; width: 100%; height: 100%; object-fit: cover; transform: scale(1.1); transform-origin: center;
  pointer-events: none; user-select: none;
}
.player-portrait-debug-control { display: none; }
body.dev-mode .player-portrait-debug-control { display: block; }

/* Gold badge sits above the player frame, right of the portrait. */
.player-gold {
  position: absolute;
  left: var(--player-gold-left, 38%);
  top: var(--player-gold-top, -10px);
  transform: scale(var(--player-gold-scale, 1));
  transform-origin: left center;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px 2px 7px;
  background: rgba(18, 13, 12, 0.88);
  border: 1px solid rgba(214, 146, 45, 0.6);
  border-radius: 999px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.65), inset 0 1px 0 rgba(255, 230, 150, 0.22);
  pointer-events: auto;
  user-select: none;
}
.player-gold .gold-icon {
  font-size: 13px;
  line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.8));
}
.player-gold .gold-val {
  color: #ffd166;
  font: 800 clamp(11px, 1vw, 13px)/1.2 system-ui, sans-serif;
  letter-spacing: 0.03em;
  text-shadow: 0 1px 2px #000;
}

/* persistent run-level badge. Text-only overlay in the portrait
   corner; the accepted HP/crystal geometry and calibration defaults stay untouched. */
.player-level {
  position: absolute;
  left: 6px;
  top: 6px;
  z-index: 6;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(30, 27, 75, 0.88);
  border: 1px solid rgba(129, 140, 248, 0.65);
  color: #dbeafe;
  font: 800 clamp(10px, 0.9vw, 12px)/1.5 system-ui, sans-serif;
  letter-spacing: 0.04em;
  text-shadow: 0 1px 2px #000;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
}

.player-hp-track {
  /* The source frame's dark HP channel ends at about 80.85% width. */
  position: absolute; left: var(--player-hp-left, calc(48.15% - 8px)); top: var(--player-hp-top, calc(40.5% + 1px)); width: var(--player-hp-width, calc(32% + 11px)); height: var(--player-hp-height, 13.2%); overflow: hidden;
  background: rgba(11, 8, 10, 0.96);
  clip-path: polygon(0 0, 94% 0, 100% 50%, 94% 100%, 0 100%, -2px 75%, 2px 40%, 2px 15%);
  clip-path: polygon(
  0 0,
  94% 0,
  100% 50%,
  94% 100%,
  0 100%,
  4px 90%,
  8px 45%,
  8px 0%
);
  
}
.hp-fill {
  height: 100%; background: linear-gradient(180deg, #ff5264 0%, #d40d2c 52%, #760416 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.42), 0 0 8px rgba(255,35,61,0.52);
  transition: width 0.25s ease, filter 0.25s ease;
}
.hp-fill.low { filter: saturate(1.35) brightness(1.1); }
.player-card .hp-text {
  position: absolute; left: var(--player-hp-text-left, calc(48.15% - 4px)); top: var(--player-hp-text-top, calc(38.2% + 1px)); width: var(--player-hp-text-width, calc(32% + 6px)); height: var(--player-hp-text-height, 15%); margin: 0;
  display: grid; place-items: center; color: #fff9e8; font: 800 var(--player-hp-font, clamp(10px, 1vw, 14px))/1 system-ui, sans-serif;
  text-shadow: 0 1px 2px #140000, 0 0 4px #62000f; letter-spacing: 0.02em;
}
.player-charges { position: absolute; inset: 0; pointer-events: none; }
/* combat buffs overlay the player frame instead of joining its layout, so a buff can
   never shift the calibrated HP / crystal / gold geometry. Tune position with the two vars below. */
.player-buffs {
  position: absolute;
  left: var(--player-buffs-left, 1.5%);
  top: var(--player-buffs-top, -13px);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  z-index: 6;
  pointer-events: none;
}
.player-buff {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 7px 2px 5px;
  background: rgba(10, 20, 26, 0.88);
  border: 1px solid rgba(73, 211, 255, 0.62);
  border-radius: 999px;
  box-shadow: 0 0 10px rgba(73, 211, 255, 0.34), 0 2px 4px rgba(0, 0, 0, 0.6);
  animation: buff-pop 200ms ease-out;
}
/* An explicit rule is required: `display` on the class would otherwise beat the UA `[hidden]`. */
.player-buff[hidden] { display: none; }
/* ENCHANT-ANIM-001: the ward an Earth hit raises pops in with a stone-brown glow for its one enemy turn. */
.player-buff.earth-ward { animation: earth-ward-pop 1.8s ease-out both; }
@keyframes earth-ward-pop {
  0% { transform: scale(0.6); box-shadow: 0 0 0 0 rgba(214, 170, 100, 0.95); }
  18% { transform: scale(1.35); box-shadow: 0 0 14px 6px rgba(214, 170, 100, 0.85); }
  40% { transform: scale(1); }
  85% { opacity: 1; box-shadow: 0 0 8px 2px rgba(185, 135, 70, 0.5); }
  100% { opacity: 0.2; box-shadow: none; }
}
.player-buff-icon { width: 14px; height: 14px; object-fit: contain; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.8)); }
.player-buff-icon-slot { display: inline-flex; align-items: center; font-size: 12px; line-height: 1; }
.player-buff-val { color: #a8e8ff; font: 800 clamp(10px, 1vw, 12px)/1.2 system-ui, sans-serif; text-shadow: 0 1px 2px #000; }
@keyframes buff-pop {
  from { transform: scale(0.55); opacity: 0.2; }
  to { transform: scale(1); opacity: 1; }
}
/* JS places sockets in HUD-local px (`.crystals-px`, set by
   layoutPlayerCrystals); without it the legacy % rules below apply. */
.player-card.crystals-px .charge-diamond { top: auto; }
/* --player-crystal-shift-px (see PLAYER_HUD_TUNE)
   moves the whole diamond group; the per-diamond % below keep internal intervals. */
.charge-diamond {
  position: absolute; top: var(--player-crystal-top, 66.6%); width: 6.6%; aspect-ratio: 1; transform: rotate(45deg) scale(var(--player-crystal-scale, 0.7));
  border-radius: 12%; background: transparent; opacity: 0;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.48), 0 0 9px rgba(73,211,255,0.88);
  transition: opacity 140ms ease, transform 140ms ease;
}
.charge-diamond:nth-child(1) { left: calc(47.7% + var(--player-crystal-shift-px, -20px)); }
.charge-diamond:nth-child(2) { left: calc(57.6% + var(--player-crystal-shift-px, -20px)); }
.charge-diamond:nth-child(3) { left: calc(67.5% + var(--player-crystal-shift-px, -20px)); }
.charge-diamond:nth-child(4) { left: calc(77.4% + var(--player-crystal-shift-px, -20px)); }
.charge-diamond:nth-child(5) { left: calc(87.3% + var(--player-crystal-shift-px, -20px)); }
/* sockets beyond the run's Mana capacity are not shown at all; an empty socket
   inside the capacity is drawn (the frame art only carves three), a filled one glows as before. */
.charge-diamond.over-cap { display: none; }
/* the frame art carves three sockets; one beyond the capacity is plated over in the
   frame's bronze so the visible sockets always equal the capacity («1/2», not «1/3»). */
.charge-diamond.over-cap.sealed {
  display: block; opacity: 1; transform: rotate(45deg) scale(var(--player-crystal-filled-scale, 0.76));
  background: linear-gradient(135deg, #8a6a3e 0%, #5b4327 45%, #3a2a18 100%);
  box-shadow: inset 0 0 0 1px rgba(20, 12, 4, 0.8), inset 0 1px 2px rgba(255, 220, 160, 0.25);
}
.charge-diamond.socket:not(.filled) {
  opacity: 0.85; background: rgba(6, 18, 40, 0.72);
  box-shadow: inset 0 0 0 1.5px rgba(120, 200, 255, 0.8), 0 0 5px rgba(73, 211, 255, 0.35);
}
.charge-diamond.filled {
  opacity: 1; transform: rotate(45deg) scale(var(--player-crystal-filled-scale, 0.76));
  background: linear-gradient(135deg, #e9fbff 0%, #48dcff 36%, #1672d4 70%, #082e75 100%);
}
/* dev-gated calibrator preview paints uncharged sockets with the
   same filled-blue look so they can be calibrated. Visual only. */
.player-card.crystals-preview .charge-diamond {
  opacity: 1; transform: rotate(45deg) scale(var(--player-crystal-filled-scale, 0.76));
  background: linear-gradient(135deg, #e9fbff 0%, #48dcff 36%, #1672d4 70%, #082e75 100%);
}
.stage.hit-flash::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 40;
  background: radial-gradient(ellipse at center, transparent 55%, rgba(200, 30, 30, 0.45) 100%);
  animation: hitFlash 260ms ease-out;
}
@keyframes hitFlash { from { opacity: 1; } to { opacity: 0; } }

.msg-line { min-height: 1.4em; font-weight: 600; font-size: 13px; }
.msg-line.bad { color: var(--danger); }

/* Rotate control.
   The frame never moves. The stone core with the gold arrows is cut out of the same art and turns:
   hovering a half leans it toward that direction, pressing spins it 90° together with the board.
   The frame's hole is slightly smaller than the core, so the core's rotating edge stays hidden. */
.rotate-controls {
  position: absolute; right: calc(var(--rotate-right, clamp(2px, 0.21cqw, 4px)) - var(--stage-gutter-right)); bottom: var(--rotate-bottom, clamp(4px, 0.42cqw, 8px)); z-index: 20;
  width: var(--rotate-size, clamp(64px, 5.83cqw, 112px)); aspect-ratio: 1;
  filter: drop-shadow(0 7px 10px rgba(0,0,0,0.65));
  --rotate-core-lean: 0deg;
}
.rotate-skin, .rotate-core {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; user-select: none;
}
/* The rotated image's transparent corners still count towards scrollable overflow.
   Contain only the art; the circular halo and the count seal remain outside this box. */
.rotate-art { position: absolute; inset: 0; overflow: clip; pointer-events: none; }
.rotate-skin {
  -webkit-mask-image: radial-gradient(ellipse var(--rotate-frame-hole-r, 31.8%) var(--rotate-frame-hole-r, 31.8%) at var(--rotate-core-cx, 49.96%) var(--rotate-core-cy, 47.97%), transparent 94%, #000 100%);
  mask-image: radial-gradient(ellipse var(--rotate-frame-hole-r, 31.8%) var(--rotate-frame-hole-r, 31.8%) at var(--rotate-core-cx, 49.96%) var(--rotate-core-cy, 47.97%), transparent 94%, #000 100%);
}
.rotate-core {
  clip-path: circle(var(--rotate-core-r, 32.4%) at var(--rotate-core-cx, 49.96%) var(--rotate-core-cy, 47.97%));
  transform-origin: var(--rotate-core-cx, 49.96%) var(--rotate-core-cy, 47.97%);
  /* The art's two arrows both run clockwise; for counter-clockwise the core flips like a coin so
     its arrows point the way the board will actually turn. */
  transform: rotate(calc(var(--rotate-icon-deg, 90deg) + var(--rotate-core-turn, 0deg) + var(--rotate-core-lean))) scale(calc(var(--rotate-core-scale, 1) * var(--rotate-core-flip, 1)), var(--rotate-core-scale, 1));
  transition:
    transform var(--rotate-core-spin-ms, 340ms) cubic-bezier(0.34, 1.35, 0.5, 1),
    filter var(--rotate-transition-ms, 150ms) ease;
}
/* Hover right (CW) / left (CCW): the core leans the way the board will turn. */
.rotate-controls:hover:has(.rotate-btn-cw:hover:not(:disabled)),
.rotate-controls.hover-cw:has(.rotate-btn-cw:not(:disabled)) {
  --rotate-core-lean: var(--rotate-hover-spin-deg, 22deg);
}
.rotate-controls:hover:has(.rotate-btn-ccw:hover:not(:disabled)),
.rotate-controls.hover-ccw:has(.rotate-btn-ccw:not(:disabled)) {
  --rotate-core-lean: calc(-1 * var(--rotate-hover-spin-deg, 22deg));
  --rotate-core-flip: -1;
}
.rotate-controls:hover:has(.rotate-btn:hover:not(:disabled)) .rotate-core,
.rotate-controls.hover-cw:has(.rotate-btn-cw:not(:disabled)) .rotate-core,
.rotate-controls.hover-ccw:has(.rotate-btn-ccw:not(:disabled)) .rotate-core {
  --rotate-core-scale: var(--rotate-hover-scale, 1.04);
  filter: brightness(1.12);
}
/* Paint the halo outside the masked/clipped images. Their filters are cut to the image box,
   which made the reveal's frame shadow a bright square. This circle never handles input. */
.rotate-controls::after {
  content: ''; position: absolute; inset: 4%; z-index: -1; pointer-events: none; border-radius: 50%;
  background: radial-gradient(circle, transparent 55%, rgba(255, 188, 63, 0.72) 78%, rgba(255, 226, 146, 0.6) 90%, transparent 100%);
  box-shadow: 0 0 var(--rotate-hover-glow-px, 12px) 4px rgba(255, 187, 64, 0.65);
  filter: blur(2px); opacity: 0;
  transition: opacity var(--rotate-transition-ms, 150ms) ease;
}
.rotate-controls:hover:has(.rotate-btn:hover:not(:disabled))::after,
.rotate-controls.hover-cw:has(.rotate-btn-cw:not(:disabled))::after,
.rotate-controls.hover-ccw:has(.rotate-btn-ccw:not(:disabled))::after {
  opacity: 0.85;
  filter: blur(calc(var(--rotate-hover-glow-px, 12px) * 0.2));
}
.rotate-btn {
  position: absolute; top: 0; bottom: 0; width: 50%; padding: 0; cursor: pointer;
  background: transparent; border: 0; color: transparent; transition: opacity 0.1s ease;
}
.rotate-btn-ccw { left: 0; border-radius: 999px 0 0 999px; }
.rotate-btn-cw { right: 0; border-radius: 0 999px 999px 0; }
.rotate-btn:hover:not(:disabled) { background: transparent; }
.rotate-btn:focus-visible { outline: 2px solid #fff4b0; outline-offset: 2px; }
.rotate-btn:disabled { opacity: 0.24; cursor: default; }
.rotate-controls.is-hidden { display: none; }
/* while the Rotate reveal beat is on screen the button demos itself -- the core makes
   one board-turn per cycle inside a gold flame halo, so the player sees what the press does without
   pressing. Driven by --rotate-reveal-* (ROTATE_TUNE.reveal); stops when the beat is acknowledged. */
@keyframes rotateRevealPulse {
  0%, 100% { filter: drop-shadow(0 7px 10px rgba(0,0,0,0.65)); }
  50% { filter: drop-shadow(0 0 calc(var(--rotate-reveal-glow-px, 26px) * 0.8) rgba(255, 215, 106, 0.95)) brightness(1.25); }
}
@keyframes rotateRevealDemo {
  0%, 14% { transform: rotate(calc(var(--rotate-icon-deg, 90deg) + var(--rotate-core-turn, 0deg))) scale(var(--rotate-core-flip, 1), 1); }
  44%, 62% { transform: rotate(calc(var(--rotate-icon-deg, 90deg) + var(--rotate-core-turn, 0deg) + var(--rotate-reveal-dir, 1) * var(--rotate-reveal-spin-deg, 90deg))) scale(calc(var(--rotate-core-flip, 1) * var(--rotate-reveal-scale, 1.07)), var(--rotate-reveal-scale, 1.07)); }
  92%, 100% { transform: rotate(calc(var(--rotate-icon-deg, 90deg) + var(--rotate-core-turn, 0deg))) scale(var(--rotate-core-flip, 1), 1); }
}
/* The demo spins the way the board has to turn to reach the target. `--rotate-reveal-spin-deg`
   keeps its tuned magnitude; only its sign follows the turn, and a counter-clockwise turn flips the
   core like a coin — the same language the hover lean uses, because the art's arrows are drawn
   clockwise. While the pointer is on the control the demo pauses and the ordinary hover lean shows
   the hovered button's own direction, so the two cues never disagree. */
.rotate-controls.reveal-pulse.reveal-cw:not(:hover, .hover-cw, .hover-ccw) .rotate-core { --rotate-reveal-dir: 1; --rotate-core-flip: 1; }
.rotate-controls.reveal-pulse.reveal-ccw:not(:hover, .hover-cw, .hover-ccw) .rotate-core { --rotate-reveal-dir: -1; --rotate-core-flip: -1; }
@keyframes rotateRevealFlame {
  from { opacity: 0.4; filter: blur(2px); }
  to { opacity: 0.95; filter: blur(4px); }
}
.rotate-controls.reveal-pulse {
  animation: rotateRevealPulse var(--rotate-reveal-ms, 1600ms) ease-in-out infinite;
}
/* The frame stays still, so the demo turns the core; the frame carries the glow. */
.rotate-controls.reveal-pulse:not(:hover, .hover-cw, .hover-ccw) .rotate-core {
  animation: rotateRevealDemo var(--rotate-reveal-ms, 1600ms) cubic-bezier(0.65, 0, 0.35, 1) infinite;
}
.rotate-controls.reveal-pulse::after {
  box-shadow: 0 0 var(--rotate-reveal-glow-px, 26px) 6px rgba(255, 183, 57, 0.85);
  animation: rotateRevealFlame calc(var(--rotate-reveal-ms, 1600ms) / 2) ease-in-out infinite alternate;
}

@media (max-width: 760px) {
  .hud-left { left: 5px; bottom: 5px; width: min(43vw, 290px); }
  .rotate-controls { right: calc(5px - var(--stage-gutter-right)); bottom: 5px; width: min(15vw, 88px); }
}

.debug-panel {
  position: absolute; right: 14px; top: 44px; width: 300px; max-height: 70vh; overflow: auto; z-index: 25;
  background: var(--panel); border: 1px solid var(--panel-border); border-radius: 10px; padding: 10px;
  backdrop-filter: blur(6px); font: 11px/1.35 ui-monospace, monospace; white-space: pre-wrap;
}
.debug-panel.hidden { display: none; }
.debug-panel h4 { margin: 8px 0 2px; font: 700 11px system-ui; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-dim); }
/* Debug-only enemy pose controls; never gameplay state. */
.enemy-pose-row { display: flex; flex-wrap: wrap; gap: 4px; }
.enemy-pose-row button {
  font: 600 11px system-ui; color: var(--ink); background: transparent;
  border: 1px solid var(--panel-border); border-radius: 6px; padding: 3px 8px; cursor: pointer;
}
.enemy-pose-row button:hover:not(:disabled) { border-color: var(--accent); }
.enemy-pose-row button:disabled { opacity: 0.35; cursor: default; }

.overlay {
  position: absolute; inset: 0; display: none; place-items: center; text-align: center; z-index: 50;
  background: rgba(10, 8, 12, 0.6); backdrop-filter: blur(2px);
}
.overlay.show { display: grid; }
.overlay .card { background: var(--panel); border: 1px solid var(--panel-border); border-radius: 12px; padding: 22px 30px; backdrop-filter: blur(10px); }
.overlay .card h2 { margin: 0 0 8px; font-size: 20px; }
.overlay .card button { margin-top: 12px; font: inherit; padding: 8px 16px; border-radius: 8px; cursor: pointer; background: var(--accent); border: none; font-weight: 700; color: inherit; }
.overlay-buttons { display: flex; gap: 8px; justify-content: center; margin-top: 12px; flex-wrap: wrap; }
.overlay-buttons button { margin-top: 0; }
.overlay button.secondary-btn { background: transparent; border: 1px solid var(--panel-border); color: var(--ink); }
.overlay button.secondary-btn:hover { border-color: var(--accent); }

/* defeat / act-complete overlay in the game's dark-gold family (victory popup palette). */
.overlay .card {
  background: linear-gradient(180deg, #27272a 0%, #18181b 45%, #09090b 100%);
  border: 2px solid #eab308;
  border-radius: 14px;
  padding: 26px 34px 24px;
  min-width: 340px;
  max-width: calc(100vw - 32px);
  text-align: center;
  color: #e7dcc4;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.85), 0 0 22px rgba(234, 179, 8, 0.28);
}
.overlay .card h2 {
  font-family: Cinzel, "Cinzel Decorative", serif, Georgia;
  font-size: 28px;
  font-weight: 900;
  letter-spacing: 2px;
  margin: 0 0 10px;
  background: linear-gradient(180deg, #fffbeb 0%, #fde047 35%, #d97706 70%, #78350f 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 3px 10px rgba(0, 0, 0, 0.9));
}
.overlay .card #overlayBody { color: #d6c7a1; }
.overlay .card button {
  font-family: Cinzel, serif;
  font-weight: 800;
  letter-spacing: 1.5px;
  padding: 10px 22px;
  background: linear-gradient(180deg, #b45309 0%, #78350f 100%);
  border: 2px solid #f59e0b;
  color: #fef3c7;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.7);
  transition: transform 120ms ease, filter 120ms ease;
}
.overlay .card button:hover { transform: translateY(-2px); filter: brightness(1.15); }
.overlay .card button.secondary-btn {
  background: linear-gradient(180deg, #27272a 0%, #18181b 100%);
  border: 2px solid #a16207;
  color: #fde68a;
}
.overlay .card button.secondary-btn:hover { border-color: #eab308; }
.overlay.overlay-defeat .card { border-color: #dc2626; box-shadow: 0 24px 64px rgba(0, 0, 0, 0.85), 0 0 22px rgba(220, 38, 38, 0.3); }
.overlay.overlay-defeat .card h2 { background: linear-gradient(180deg, #fee2e2 0%, #f87171 35%, #dc2626 70%, #450a0a 100%); -webkit-background-clip: text; background-clip: text; }

.hint-line { font-size: 11px; color: var(--ink-dim); position: absolute; left: 14px; top: 44px; max-width: 260px; z-index: 20; pointer-events: auto; }
/* the battle hint box is mouse-draggable (see hint-drag.js);
   double-click returns it to the CSS default. Touch keeps native scrolling. */
.hint-line:not(:empty) { cursor: grab; }
.hint-line.is-dragging { cursor: grabbing; user-select: none; }
/* battle messages sit on busy arena art — give them a readable dark-gold backing when present. */
.hint-line:not(:empty) { background: linear-gradient(180deg, rgba(39, 39, 42, 0.82) 0%, rgba(9, 9, 11, 0.82) 100%); border: 1px solid rgba(161, 98, 7, 0.7); border-radius: 8px; padding: 6px 10px; color: #e7dcc4; font-size: 12px; line-height: 1.35; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); }

/* Clean game view hides admin chrome but keeps access through #adminToggle.
   Campaign/Pose editors are separate pages and are untouched. */
body.clean .admin-only { display: none !important; }
body.clean #restartBtn, body.clean #hintBtn { display: none !important; }
body.clean .debug-panel { display: none !important; }
/* Dev-mode only; it lives in the top-right corner, beside the dev topbar, so the bottom-right corner
   belongs to Rotate and the usable dock. */
.admin-toggle {
  position: absolute; right: 8px; top: 8px; z-index: 60;
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  font-size: 16px; color: var(--ink-dim); background: var(--panel);
  border: 1px solid var(--panel-border); backdrop-filter: blur(6px); opacity: 0.75;
}
.admin-toggle:hover { opacity: 1; color: var(--ink); }

/* usable dock — the approved HUD's "actions dock": a row of carved medallions to the
   left of Rotate, on the bottom-edge baseline. Every usable is the same bezel (assets/ui/slot-bezel.png, cut from the approved
   player-HUD medallion) with the item art inside and a bronze count seal; names live in tooltips. */
.usables-dock {
  position: absolute; z-index: 20; pointer-events: auto;
  --slot: var(--usables-slot-size, clamp(40px, 3.54cqw, 68px));
  right: calc(var(--rotate-right, clamp(2px, 0.21cqw, 4px)) + var(--rotate-size, clamp(64px, 5.83cqw, 112px)) + var(--usables-rotate-gap, clamp(5px, 0.52cqw, 10px)) - var(--stage-gutter-right));
  bottom: calc(var(--hud-dock-bottom) - var(--usables-dy, 0px));
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
}
.item-bar { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; position: relative; margin: 0; }
.item-slots-row { display: flex; align-items: center; gap: var(--usables-gap, 6px); }
.item-slot {
  position: relative; width: var(--slot); height: var(--slot); padding: 0; border: 0; cursor: pointer;
  background: url('assets/ui/slot-bezel.png') center / contain no-repeat;
  filter: drop-shadow(0 5px 7px rgba(0, 0, 0, 0.65));
  transition: transform 0.14s ease, filter 0.14s ease;
}
.item-slot-icon {
  position: absolute; inset: 21%; display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.item-slot-icon-img, .quiver-ammo-icon, .quiver-option-icon {
  width: 100%; height: 100%; object-fit: contain; pointer-events: none;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.75)); transition: transform 0.14s ease, filter 0.14s ease;
}
.item-slot-glyph { font: 700 calc(var(--slot) * 0.32)/1 Georgia, serif; color: #e8c98a; }
/* Ammo art is a slim diagonal arrow with generous padding: let it fill the socket. */
.quiver-ammo-icon, .quiver-option-icon { transform: scale(1.45); }
.arrow-tip-icon-piercing, .arrow-tip-icon-split { translate: 0 -2px; }
.item-slot:hover:not(:disabled) .quiver-ammo-icon { transform: scale(1.55); }
.item-count-seal {
  position: absolute; right: -2%; bottom: -2%; min-width: 34%; height: 34%; padding: 0 3px;
  display: flex; align-items: center; justify-content: center; box-sizing: border-box; border-radius: 999px;
  background: radial-gradient(circle at 38% 30%, #4a3520, #150e08 70%);
  border: 1.5px solid #c9924a; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7), inset 0 1px 1px rgba(255, 230, 170, 0.25);
  font: 700 calc(var(--slot) * 0.2)/1 Georgia, 'Times New Roman', serif; color: #fff1d0; text-shadow: 0 1px 2px #000;
  pointer-events: none;
}
.item-slot:hover:not(:disabled) { transform: translateY(-3px); filter: drop-shadow(0 0 6px rgba(255, 207, 107, 0.55)) drop-shadow(0 7px 8px rgba(0, 0, 0, 0.6)); }
.item-slot:hover:not(:disabled) .item-slot-icon-img { transform: scale(1.08); }
.item-slot:active:not(:disabled) { transform: translateY(0) scale(0.96); }
.item-slot:focus-visible { outline: 2px solid #fff4b0; outline-offset: 2px; border-radius: 50%; }
.item-slot:disabled { cursor: default; }
.item-slot.spent, .item-slot:disabled:not(.empty) { filter: grayscale(0.85) brightness(0.7) drop-shadow(0 5px 7px rgba(0, 0, 0, 0.65)); }
.item-slot.spent .item-count-seal { color: #b9a78a; border-color: #7d6446; }
/* an active already spent this turn carries a cold seal, so it reads as
   "waiting for the next turn" rather than the muted bronze of an exhausted charge. */
.item-slot.used-this-turn .item-count-seal { color: #a9c8dd; border-color: #43617a; }
.item-slot.used-this-turn .item-slot-icon { opacity: 0.62; }
/* a mana-paid active's seal shows its crystal price in the HUD crystal blue. */
.item-count-seal.item-mana-cost {
  background: radial-gradient(circle at 38% 30%, #1f5f9e, #06173a 72%);
  border-color: #48dcff; color: #e9fbff;
}
.item-slot.mana-short .item-count-seal.item-mana-cost { color: #ffb4a8; border-color: #b0443a; }
/* an active's uses left this fight («1/1») sit on the left, opposite the crystal price. */
.item-count-seal.item-uses-seal { right: auto; left: -2%; font-size: calc(var(--slot) * 0.17); }
.item-slot.empty { opacity: 0.42; filter: grayscale(1) brightness(0.8); }
/* Armed: the item whose board/arena pick is open. One warm pulsing light for every mode — the mode
   itself is told by the board (sockets / lit arrows / target rings), not by a colour code here. */
.item-slot.placing, .item-slot.charging, .item-slot.targeting {
  transform: translateY(-4px);
  animation: slot-armed 1.3s ease-in-out infinite;
}
@keyframes slot-armed {
  0%, 100% { filter: drop-shadow(0 0 5px rgba(255, 207, 107, 0.65)) drop-shadow(0 6px 7px rgba(0, 0, 0, 0.6)) brightness(1.05); }
  50% { filter: drop-shadow(0 0 14px rgba(255, 214, 120, 0.95)) drop-shadow(0 6px 7px rgba(0, 0, 0, 0.6)) brightness(1.18); }
}
@keyframes medal-breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
  .item-slot.placing, .item-slot.charging, .item-slot.targeting, .relic-chip.primed { animation: none; filter: drop-shadow(0 0 10px rgba(255, 207, 107, 0.85)); }
}

/* The Plain Arrow: same medallion. */
.quiver-slot-wrap { position: relative; display: inline-flex; }
/* Consumables (potions) ride right next to the player card's frame, on the bottom-edge baseline. The frame
   art ends at 92% of the card box (the rest is transparent), so the dock starts there, not at the box edge. */
.consumables-dock {
  position: absolute; z-index: 20; pointer-events: auto;
  --slot: var(--usables-slot-size, clamp(40px, 3.54cqw, 68px));
  left: calc(var(--player-hud-left, clamp(6px, 0.73cqw, 14px)) + var(--player-hud-width, clamp(200px, 18.75cqw, 360px)) * 0.92 + var(--consumables-gap, clamp(2px, 0.21cqw, 4px)));
  bottom: var(--hud-dock-bottom);
}
.consumables-dock .item-bar { align-items: flex-start; }

/* Modifications: one medallion; its face shows the armed charge, else the charge a click arms (the last one
   chosen). Hover (touch: long press) opens the chooser; after a pick it stays shut until the pointer leaves. */
.mods-slot-wrap { position: relative; display: inline-flex; }
.mods-picker-cue {
  position: absolute; left: 50%; top: 0; transform: translateX(-50%);
  border-left: 3px solid transparent; border-right: 3px solid transparent; border-bottom: 4px solid #edc87f;
  filter: drop-shadow(0 1px 2px #000); pointer-events: none;
}
.mods-slot-wrap:is(:hover, :focus-within, .open):not(.rested) .item-slot.mods-slot:not(:disabled) { filter: drop-shadow(0 0 9px rgba(255, 214, 120, 0.9)) drop-shadow(0 5px 7px rgba(0, 0, 0, 0.65)); }
.mods-slot-wrap.open .mods-slot .quiver-ammo-icon { transform: scale(1.45); }
/* A compact inventory of the arrows and charges actually held. Viewport units are independent of HUD zoom. */
.mods-chooser {
  --quiver-socket-size: 40px; --quiver-gap: 6px; --quiver-panel-width: 220px;
  position: fixed; z-index: 240; width: min(var(--quiver-panel-width), calc(100vw - 24px));
  max-height: calc(100vh - 24px); overflow-y: auto; overscroll-behavior: contain;
  display: none; padding: 8px;
  color: #f3e3c0; background: linear-gradient(145deg, #302b26, #171719 65%);
  border: 1px solid #9d7845; border-radius: 6px;
  box-shadow: 0 6px 16px #000a, inset 0 1px 0 #f5d59820;
}
.mods-chooser.is-open { display: block; animation: quiver-open 140ms ease-out both; }
@keyframes quiver-open { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
.quiver-close { position: absolute; right: 4px; top: 4px; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 4px; color: #d8c397; background: transparent; font: 20px/1 system-ui, sans-serif; cursor: pointer; }
.quiver-close:hover { background: #413324; color: #fff2cb; }
.quiver-group { margin-top: 6px; padding-top: 6px; border-top: 1px solid #a27b4138; }
/* The first section sits under the close button: no divider above it. */
.quiver-close + .quiver-group { margin-top: 0; padding-top: 0; border-top: 0; }
.quiver-group h3 { margin: 0 0 3px; font: 600 11px/1.3 Georgia, 'Times New Roman', serif; color: #d7bf92; }
.quiver-grid { display: grid; grid-template-columns: repeat(var(--quiver-columns, 4), minmax(0, var(--quiver-cell-width, 46px))); gap: var(--quiver-gap); }
.quiver-grid > .slot-tip { min-width: 0; }
.mods-chooser .quiver-option:focus-visible { outline: 2px solid #fff4b0; outline-offset: 2px; }

/* Modification options: smaller medallions rising into the chooser one after another. */
.quiver-option { position: relative; }

/* The fan: the Quiver's arrows rise out of it as a column of smaller medallions. */
.quiver-chooser {
  position: absolute; z-index: 30; left: 50%; bottom: calc(100% + 14px); transform: translateX(-50%);
  display: flex; flex-direction: column-reverse; align-items: center; gap: 6px;
}
.quiver-option {
  --slot: calc(var(--usables-slot-size, clamp(40px, 3.54cqw, 68px)) * 0.82);
  position: relative; width: var(--slot); height: var(--slot); padding: 0; border: 0; cursor: pointer;
  background: url('assets/ui/slot-bezel.png') center / contain no-repeat;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.7));
  animation: fan-rise 0.2s cubic-bezier(0.34, 1.4, 0.5, 1) both;
  animation-delay: calc(var(--fan-i, 0) * 35ms);
  transition: transform 0.12s ease, filter 0.12s ease;
}
@keyframes fan-rise { from { opacity: 0; transform: translateY(18px) scale(0.7); } to { opacity: 1; transform: none; } }
.quiver-option:hover:not(:disabled) { transform: scale(1.1); filter: drop-shadow(0 0 7px rgba(255, 207, 107, 0.75)) drop-shadow(0 4px 6px rgba(0, 0, 0, 0.7)); }
.quiver-option:disabled { cursor: default; filter: grayscale(0.9) brightness(0.65); }
.mods-chooser .quiver-option {
  width: 100%; height: auto; min-height: calc(var(--quiver-socket-size) + 6px); padding: 2px; display: flex; flex-direction: column; align-items: center;
  color: #e4d4b6; background: transparent;
  border: 1px solid transparent; border-radius: 4px; filter: none; animation: none;
}
.quiver-socket { --slot: var(--quiver-socket-size); position: relative; display: block; width: var(--slot); height: var(--slot); flex-shrink: 0; background: url('assets/ui/slot-bezel.png') center / contain no-repeat; filter: drop-shadow(0 3px 3px #000a); }
.mods-chooser .quiver-option:hover:not(:disabled) { transform: none; filter: none; background: linear-gradient(180deg, #70502455, #33271666); border-color: #d2a75e; color: #fff0c9; }
.mods-chooser .quiver-option:hover:not(:disabled) .quiver-socket { filter: drop-shadow(0 0 5px #efbd6677); }
.mods-chooser .quiver-option:disabled { opacity: 0.45; filter: grayscale(0.8); }
@media (prefers-reduced-motion: reduce) { .mods-chooser.is-open { animation: none; } }

@media (max-width: 760px) {
  /* Narrow stage: potions stack above the player card (beside it they would run under the dock), the
     right dock shrinks to fit left of Rotate, and empty active sockets are dropped. */
  .consumables-dock { --slot: clamp(30px, 8vw, 44px); left: 5px; bottom: calc(5px + min(43vw, 290px) / 3 + 4px); }
  .usables-dock { --slot: clamp(30px, 8vw, 44px); right: calc(5px + min(15vw, 88px) + 6px - var(--stage-gutter-right)); bottom: 8px; }
  .usables-dock .item-slots-row { gap: 3px; }
  .usables-dock .slot-tip:has(> .item-slot.empty) { display: none; }
}

/* Portrait phone: the 16:9 stage is a short strip at the top with the rest of the screen empty, and any
   HUD inside it would cover the board. The bottom HUD moves below the stage instead: player card and
   Rotate on the first row, potions and the usable dock on the second. */
@media (max-aspect-ratio: 3/4) {
  .stage { overflow: visible; --hud-portrait-gap: 10px; --hud-portrait-row2: calc(100% + var(--hud-portrait-gap) * 2 + min(24vw, 96px)); }
  .hud-left { top: calc(100% + var(--hud-portrait-gap)); bottom: auto; left: 8px; width: min(62vw, 300px); }
  .rotate-controls { top: calc(100% + var(--hud-portrait-gap)); bottom: auto; right: 8px; width: min(24vw, 96px); }
  .consumables-dock, .usables-dock { top: var(--hud-portrait-row2); bottom: auto; --slot: clamp(36px, 11vw, 52px); }
  .consumables-dock { left: 8px; }
  .usables-dock { right: 8px; }
  .usables-dock .item-slots-row { gap: 4px; }
  /* The arena hint would now spill over the HUD rows: it reads under them instead. Its offset keeps room
     for the largest slot (52px) and the usable dock's live status row (34px chip + 4px pad + 10px bar gap),
     which sits above the slots and pushes them down when a ward or another live state is up. */
  .hint-line { top: calc(var(--hud-portrait-row2) + 52px + 48px + var(--hud-portrait-gap) * 2); left: 8px; max-width: calc(100% - 16px); }
}

/* Live combat states: a row of small medallions above the usables (see the relic block below). */
.player-hud-layout {
  position: absolute; z-index: 20;
  left: calc(var(--player-hud-left) + var(--hud-side-inset, 0px));
  right: calc(var(--player-hud-left) + var(--hud-side-inset, 0px));
  bottom: calc(var(--player-hud-bottom) + var(--hud-bottom-inset, 0px));
  display: flex; align-items: flex-end; justify-content: space-between; gap: var(--hud-row-gap, 12px);
  pointer-events: none;
}
.player-hud-group { display: flex; align-items: flex-end; zoom: var(--hud-effective-scale, 1.3); }
.player-hud-layout :is(.hud-left, .rotate-controls, .consumables-dock, .usables-dock) {
  position: relative; inset: auto; flex-shrink: 0; pointer-events: auto;
}
.player-hud-layout .hud-left { width: var(--player-hud-width); }
.player-hud-layout .rotate-controls { width: var(--rotate-size); margin-left: var(--usables-rotate-gap); }
.player-hud-layout .rotate-controls.is-hidden { margin-left: 0; }
.player-hud-layout .consumables-dock {
  margin-left: calc(var(--player-hud-width) * -0.08 + var(--consumables-gap, 4px));
  margin-bottom: clamp(1px, 0.21cqw, 4px);
}
.player-hud-layout .usables-dock { margin-bottom: calc(clamp(1px, 0.21cqw, 4px) - var(--usables-dy)); }
@media (max-width: 760px) and (min-aspect-ratio: 3/4) {
  .player-hud-group-left { flex-direction: column; align-items: flex-start; }
  .player-hud-layout .consumables-dock { order: -1; margin-left: 0; }
}
@media (max-aspect-ratio: 3/4) {
  .player-hud-layout {
    top: calc(100% + 10px + var(--hud-bottom-inset, 0px)); bottom: auto;
    display: grid; grid-template-columns: max-content max-content; justify-content: space-between;
    align-items: end; row-gap: var(--hud-row-gap, 12px);
  }
  .player-hud-group { display: contents; zoom: 1; }
  .player-hud-layout :is(.hud-left, .rotate-controls, .consumables-dock, .usables-dock) { zoom: var(--hud-effective-scale, 1.3); margin: 0; }
  .player-hud-layout .hud-left { grid-area: 1 / 1; width: min(62vw, 300px); }
  .player-hud-layout .rotate-controls { grid-area: 1 / 2; width: min(24vw, 96px); justify-self: end; }
  .player-hud-layout .consumables-dock { grid-area: 2 / 1; }
  .player-hud-layout .usables-dock { grid-area: 2 / 2; justify-self: end; }
  .stage .hint-line { top: calc(var(--hud-portrait-end, var(--hud-portrait-row2)) + 16px); }
}

.item-status-row { order: -1; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; padding-bottom: 4px; }

/* Arena-pick banner (Bow / Frost Dart target, Snare side): a slate plaque with gold studs, like the
   approved HUD's bottom message bar; the Cancel control is a small bronze-edged stone button. */
.arrow-placement-banner {
  position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 25;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 7px 26px; color: #f3e6c8;
  font: 600 13px/1.3 Georgia, 'Times New Roman', serif; text-shadow: 0 1px 2px #000;
  background: linear-gradient(180deg, rgba(40, 40, 46, 0.95), rgba(16, 16, 20, 0.95));
  border: 1px solid rgba(201, 146, 74, 0.8); border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 235, 190, 0.08);
}
.arrow-placement-banner::before, .arrow-placement-banner::after {
  content: ''; position: absolute; top: 50%; width: 9px; height: 9px; transform: translateY(-50%) rotate(45deg);
  background: linear-gradient(135deg, #fff0b8, #c98f3a); box-shadow: 0 0 4px rgba(255, 210, 120, 0.7);
}
.arrow-placement-banner::before { left: 9px; }
.arrow-placement-banner::after { right: 9px; }
.arrow-placement-banner span { color: inherit; }
.arrow-placement-banner .secondary-btn {
  font: 600 12px/1 Georgia, serif; padding: 5px 12px; cursor: pointer; color: #f3e6c8;
  background: linear-gradient(180deg, #34343b, #1a1a1f); border: 1px solid #9c7040; border-radius: 3px;
}
.arrow-placement-banner .secondary-btn:hover { border-color: #e8b867; color: #fff3cf; }
.reward-draft h2 { margin: 0 0 10px; font-size: 20px; }
.reward-row { display: flex; gap: 12px; justify-content: center; }
.overlay .card .reward-card { width: 150px; margin: 0; min-height: 110px; border-radius: 12px; border: 1px solid var(--panel-border); background: rgba(255,255,255,0.04); color: var(--ink); font: inherit; padding: 12px 10px; cursor: pointer; text-align: center; display: flex; flex-direction: column; gap: 6px; align-items: center; justify-content: center; transition: transform 120ms, border-color 120ms; }
.overlay .card .reward-card:hover { transform: translateY(-3px); border-color: var(--accent); }
.reward-card .reward-title { font-weight: 800; font-size: 16px; }
.reward-card .reward-text { font-size: 12px; color: var(--ink-dim); }
.reward-card.reward-heal .reward-title { color: #9fe870; }
.reward-card.reward-gold .reward-title { color: #e8c15a; }
.overlay .card .reward-card.reward-item { border-color: #b98cff; box-shadow: 0 0 14px rgba(185,140,255,0.35); }
.reward-card.reward-item .reward-title { color: #d8c0ff; }
.item-gold { width: 100%; font-size: 11px; color: #e8c15a; font-weight: 700; }
.reward-card.reward-rotate .reward-title { color: #ffd166; }
.overlay .card .reward-card.reward-relic { border-color: #5cd0ff; box-shadow: 0 0 14px rgba(92,208,255,0.35); }
.reward-card.reward-relic .reward-title { color: #7ce0ff; }
.reward-note { margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; font-size: 12px; align-items: center; }
.reward-draft > .secondary-btn { margin-top: 12px; }
.overlay .card .reward-note button { margin: 0; padding: 4px 8px; font-size: 12px; }

/* Relic row, passive items and active combat buffs.
   live states are small carved medallions above the usable row (same bezel art), with
   a bronze value seal; the name and explanation stay in the hover tooltip. */
.item-slot.passive { opacity: 0.85; cursor: default; }
.item-pips.passive-tag { font-size: 9px; letter-spacing: 0; color: #5cd0ff; }
.item-buff, .item-ward, .relic-chip {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: var(--status-medal, 34px); height: var(--status-medal, 34px); padding: 0; cursor: help;
  background: url('assets/ui/slot-bezel.png') center / contain no-repeat;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.6));
  font: 700 10px/1 Georgia, 'Times New Roman', serif; color: #fff4d6; border: 0;
}
.item-buff > span:not(.relic-chip-icon), .item-ward > span:not(.relic-chip-icon) {
  position: absolute; left: 50%; bottom: -6px; transform: translateX(-50%);
  padding: 1px 5px; white-space: nowrap; border-radius: 999px;
  background: radial-gradient(circle at 40% 30%, #3a2a17, #140e08); border: 1px solid #c08a3e;
  text-shadow: 0 1px 1px #000;
}
.item-buff { display: inline-flex; }
.item-ward { --status-glow: rgba(96, 200, 255, 0.75); }
.item-buff.horn { --status-glow: rgba(255, 150, 110, 0.7); }
.item-buff.waste, .item-buff.chrono, .item-buff.snare { --status-glow: rgba(255, 209, 102, 0.6); }
.item-buff, .item-ward { filter: drop-shadow(0 0 5px var(--status-glow, rgba(255, 209, 102, 0.55))) drop-shadow(0 3px 4px rgba(0, 0, 0, 0.6)); }
.relic-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: center; }
.relic-chip-icon { display: inline-flex; align-items: center; justify-content: center; width: 58%; height: 58%; font-size: 14px; }
.relic-chip-icon-img { width: 100%; height: 100%; object-fit: contain; }
.relic-chip.empty { opacity: 0.5; cursor: default; }
.relic-chip.spent { opacity: 0.55; filter: grayscale(0.9) brightness(0.7); }
.relic-chip.spent .relic-chip-icon-img { opacity: 0.45; filter: grayscale(1); }
.relic-chip.primed { filter: drop-shadow(0 0 6px rgba(255, 209, 102, 0.8)) drop-shadow(0 3px 4px rgba(0, 0, 0, 0.6)); animation: medal-breathe 1.8s ease-in-out infinite; }

/* Route map, node topology, SVG connections and shop nodes. */
.map-toggle-btn {
  background: rgba(255, 209, 102, 0.15) !important;
  border-color: rgba(255, 209, 102, 0.5) !important;
  color: #ffd166 !important;
  font-weight: 700;
  cursor: pointer;
}
.map-toggle-btn:hover {
  background: rgba(255, 209, 102, 0.3) !important;
}

.route-map-modal {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 1000;
  background: #04060a;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0;
  overflow: hidden;
  animation: rmFadeIn 180ms ease-out;
}
.route-map-modal.hidden { display: none !important; }

@keyframes rmFadeIn {
  from { opacity: 0; transform: scale(0.98); }
  to { opacity: 1; transform: scale(1); }
}

.route-map-panel.fullscreen-map {
  position: relative;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #04060a;
  overflow: hidden;
}

/* Floating HUD Top Bar */
.route-map-floating-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 58px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding: 0 24px;
  background: linear-gradient(to bottom, rgba(4, 6, 10, 0.92) 0%, rgba(4, 6, 10, 0.4) 75%, transparent 100%);
  z-index: 40;
  pointer-events: none;
}
.route-map-breadcrumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: #fff;
  pointer-events: auto;
}
.breadcrumb-act {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.5px;
  color: #ffd166;
}
.breadcrumb-sep { opacity: 0.4; }
.breadcrumb-map { font-weight: 800; color: #fff; }
.breadcrumb-status { color: var(--ink-dim); font-size: 12px; margin-left: 6px; }

.route-map-header-stats {
  display: flex;
  gap: 8px;
  align-items: center;
  pointer-events: auto;
}
.stat-pill {
  padding: 4px 10px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: var(--ink);
  backdrop-filter: blur(4px);
}
.stat-pill.hp { color: #ff7d7d; border-color: rgba(255, 125, 125, 0.35); }
.stat-pill.rotate { color: #ffd166; border-color: rgba(255, 209, 102, 0.35); }
.stat-pill.gold { color: #f5d061; border-color: rgba(245, 208, 97, 0.35); }
.stat-pill.items { color: #9fe870; border-color: rgba(159, 232, 112, 0.35); }

.route-map-close-btn {
  background: rgba(20, 26, 38, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
  border-radius: 8px;
  width: 34px;
  height: 34px;
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms, transform 120ms, color 120ms;
  pointer-events: auto;
}
.route-map-close-btn:hover {
  background: rgba(255, 255, 255, 0.25);
  transform: scale(1.06);
}

/* Fullscreen Viewport & Board */
.route-map-viewport {
  position: absolute;
  inset: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #04060a;
}

.route-map-board {
  position: relative;
  aspect-ratio: 1672 / 941;
  width: 100vw;
  height: 100vh;
  max-width: calc(100vh * (1672 / 941));
  max-height: calc(100vw * (941 / 1672));
  user-select: none;
  box-shadow: 0 0 60px rgba(0, 0, 0, 0.95);
}

.route-map-artwork {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
  pointer-events: none;
  display: block;
}

/* Programmatic Labels Layer */
.route-map-labels-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 5;
}

/* Title Card in the top-left sky/mountains */
.map-title-card {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: 340px;
}
.map-title-badge {
  font-size: clamp(9px, 0.85vw, 13px);
  font-weight: 800;
  letter-spacing: 2.5px;
  color: #ffd166;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.95);
}
.map-title-heading {
  margin: 0;
  font-family: 'Cinzel', 'Georgia', serif;
  font-size: clamp(18px, 1.85vw, 30px);
  font-weight: 800;
  color: #fff;
  line-height: 1.15;
  letter-spacing: 0.5px;
  text-shadow:
    0 2px 6px rgba(0, 0, 0, 0.95),
    0 0 14px rgba(0, 0, 0, 0.85),
    -1px -1px 0 rgba(0, 0, 0, 0.8),
    1px -1px 0 rgba(0, 0, 0, 0.8),
    -1px 1px 0 rgba(0, 0, 0, 0.8),
    1px 1px 0 rgba(0, 0, 0, 0.8);
}
.map-title-prompt {
  margin-top: 3px;
  font-size: clamp(9px, 0.8vw, 12px);
  font-weight: 500;
  color: #d8e2ee;
  line-height: 1.35;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.95);
}

/* Terrain Labels */
.terrain-label {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: 'Cinzel', 'Georgia', serif;
  font-size: clamp(10px, 1.05vw, 16px);
  font-weight: 800;
  color: #f7f1e6;
  letter-spacing: 0.5px;
  white-space: nowrap;
  text-shadow:
    0 2px 4px rgba(0, 0, 0, 0.95),
    0 0 8px rgba(0, 0, 0, 0.85),
    0 0 2px #000,
    -1px -1px 0 rgba(0, 0, 0, 0.85),
    1px -1px 0 rgba(0, 0, 0, 0.85),
    -1px 1px 0 rgba(0, 0, 0, 0.85),
    1px 1px 0 rgba(0, 0, 0, 0.85);
  opacity: 0.95;
}

/* Wooden Signpost ("ТУТ НАЧИНАЮТСЯ ПРОБЛЕМЫ") */
.map-signpost {
  position: absolute;
  transform: translate(-50%, -50%);
  width: clamp(70px, 7.2vw, 122px);
  height: clamp(36px, 4.2vw, 70px);
  display: flex;
  align-items: center;
  justify-content: center;
}
.signpost-text {
  position: relative;
  left: 2px;
  top: 3px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transform: rotate(7.2deg);
  font-family: 'Arial Black', 'Trebuchet MS', 'Impact', sans-serif;
  font-weight: 900;
  color: #ede4d4;
  line-height: 1.08;
  text-align: center;
  letter-spacing: 0.5px;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.95),
    0 2px 4px rgba(0, 0, 0, 0.8),
    -1px -1px 0 rgba(0, 0, 0, 0.5),
    1px 1px 0 rgba(0, 0, 0, 0.5);
}
.signpost-text .sign-line-1 { font-size: clamp(8px, 0.8vw, 13px); }
.signpost-text .sign-line-2 { font-size: clamp(6.5px, 0.68vw, 11px); }
.signpost-text .sign-line-3 { font-size: clamp(7px, 0.72vw, 11.5px); }

/* Scalable SVG Roads Layer */
.route-map-svg-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 2;
}

.rm-path-shadow {
  fill: none;
  stroke: rgba(0, 0, 0, 0.65);
  stroke-width: 7px;
  stroke-linecap: round;
}

.rm-path {
  fill: none;
  stroke-linecap: round;
  transition: stroke 200ms;
}
.rm-line-locked {
  stroke: rgba(225, 210, 180, 0.35);
  stroke-width: 2.5px;
  stroke-dasharray: 5 4;
}
.rm-line-visited {
  stroke: #4ee085;
  stroke-width: 4px;
  opacity: 0.9;
  filter: drop-shadow(0 0 4px rgba(78, 224, 133, 0.7));
}
.rm-line-available {
  stroke: #ffd166;
  stroke-width: 4px;
  stroke-dasharray: 8 5;
  animation: rmDashMove 1.2s linear infinite;
  filter: drop-shadow(0 0 8px rgba(255, 209, 102, 0.85));
}
@keyframes rmDashMove {
  from { stroke-dashoffset: 26; }
  to { stroke-dashoffset: 0; }
}

/* Hotspot Pins Layer */
.route-map-pins-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
}

.map-hotspot-pin {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: default;
  z-index: 10;
}
.map-hotspot-pin:hover {
  z-index: 50;
}

/* Pin Beacons */
.pin-pulse-beacon {
  position: absolute;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  border: 2px solid #5cd0ff;
  pointer-events: none;
  animation: rmPulseBeacon 1.8s cubic-bezier(0.1, 0.8, 0.3, 1) infinite;
}
@keyframes rmPulseBeacon {
  0% { transform: scale(0.65); opacity: 0.9; }
  100% { transform: scale(1.6); opacity: 0; }
}

.pin-current-aura {
  position: absolute;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 209, 102, 0.55) 0%, transparent 70%);
  pointer-events: none;
  animation: rmCurrentGlow 2s ease-in-out infinite alternate;
}
@keyframes rmCurrentGlow {
  0% { transform: scale(0.9); opacity: 0.6; }
  100% { transform: scale(1.25); opacity: 1; }
}

/* Pin Token */
.pin-token {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.8);
  border: 2px solid;
  transition: transform 160ms cubic-bezier(0.2, 0, 0, 1), box-shadow 160ms, border-color 160ms;
  font-size: 16px;
  line-height: 1;
}

.type-boss .pin-token {
  width: 44px;
  height: 44px;
  font-size: 20px;
  border-width: 2.5px;
}

/* States */
.state-visited .pin-token {
  background: radial-gradient(circle, #253a2f 0%, #121d17 100%);
  border-color: #4ee085;
  color: #a4f0bf;
  opacity: 0.88;
}
.pin-check {
  position: absolute;
  top: -4px;
  right: -4px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #4ee085;
  color: #0c1c13;
  font-size: 9px;
  font-weight: 900;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.6);
}

.state-current .pin-token {
  background: radial-gradient(circle, #ffe685 0%, #d49826 100%);
  border-color: #fff;
  color: #221400;
  box-shadow: 0 0 20px rgba(255, 209, 102, 0.95), 0 4px 12px rgba(0, 0, 0, 0.85);
}

.state-available .pin-token {
  background: radial-gradient(circle, #2b4b73 0%, #14243b 100%);
  border-color: #5cd0ff;
  color: #fff;
  box-shadow: 0 0 16px rgba(92, 208, 255, 0.75), 0 4px 12px rgba(0, 0, 0, 0.8);
  cursor: pointer;
}
.state-available:hover .pin-token {
  transform: scale(1.18);
  border-color: #ffd166;
  box-shadow: 0 0 24px rgba(255, 209, 102, 0.95), 0 6px 16px rgba(0, 0, 0, 0.9);
}

.state-locked .pin-token {
  background: radial-gradient(circle, #202733 0%, #11151c 100%);
  border-color: rgba(255, 255, 255, 0.18);
  color: rgba(255, 255, 255, 0.35);
  opacity: 0.65;
  filter: grayscale(0.4);
}

/* Mini Label */
.pin-mini-label {
  margin-top: 3px;
  font-size: 10px;
  font-weight: 700;
  color: #f0e6d2;
  background: rgba(10, 14, 22, 0.9);
  border: 1px solid rgba(255, 215, 120, 0.3);
  border-radius: 4px;
  padding: 1px 6px;
  white-space: nowrap;
  pointer-events: none;
  text-shadow: 0 1px 2px #000;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.7);
  opacity: 0;
  transition: opacity 120ms;
}
.pin-mini-label.always-visible,
.map-hotspot-pin:hover .pin-mini-label {
  opacity: 1;
}

/* Rich Tooltip Popover */
.pin-tooltip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  opacity: 0;
  pointer-events: none;
  min-width: 180px;
  max-width: 240px;
  background: rgba(12, 17, 26, 0.97);
  border: 1px solid rgba(255, 215, 120, 0.4);
  border-radius: 10px;
  padding: 10px 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.95), 0 0 14px rgba(255, 209, 102, 0.25);
  transition: opacity 140ms ease, transform 140ms ease;
  z-index: 100;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.map-hotspot-pin:hover .pin-tooltip {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.tooltip-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  font-size: 9px;
}
.tooltip-type-badge {
  font-size: 9px;
  font-weight: 800;
  padding: 2px 5px;
  border-radius: 4px;
  text-transform: uppercase;
}
.tooltip-type-badge.battle { background: rgba(255, 85, 85, 0.25); color: #ff7575; }
.tooltip-type-badge.shop { background: rgba(92, 208, 255, 0.25); color: #7ce0ff; }
.tooltip-type-badge.event { background: rgba(126, 255, 170, 0.22); color: #9dffb9; }
.tooltip-type-badge.boss { background: rgba(255, 209, 102, 0.3); color: #ffe082; }

.tooltip-step {
  font-size: 9px;
  color: var(--ink-dim);
  font-weight: 700;
}
.tooltip-state-badge {
  font-size: 9px;
  font-weight: 700;
  padding: 2px 5px;
  border-radius: 4px;
}
.tooltip-state-badge.current { background: #ffd166; color: #111; font-weight: 800; }
.tooltip-state-badge.visited { background: rgba(78, 224, 133, 0.25); color: #4ee085; }
.tooltip-state-badge.available { background: rgba(92, 208, 255, 0.25); color: #5cd0ff; }
.tooltip-state-badge.locked { background: rgba(255, 255, 255, 0.08); color: var(--ink-dim); }

.tooltip-title {
  font-size: 12px;
  font-weight: 800;
  color: #fff;
  line-height: 1.25;
}
.tooltip-desc {
  font-size: 11px;
  line-height: 1.35;
  color: #b8c4d6;
}
.tooltip-prompt {
  font-size: 10px;
  font-weight: 700;
  color: var(--ink-dim);
  margin-top: 3px;
  padding-top: 3px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.tooltip-prompt.pickable {
  color: #ffd166;
  font-weight: 800;
}

/* Floating Bottom Bar */
.route-map-floating-bottom {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 24px;
  background: linear-gradient(to top, rgba(4, 6, 10, 0.92) 0%, rgba(4, 6, 10, 0.4) 75%, transparent 100%);
  font-size: 12px;
  z-index: 40;
  pointer-events: none;
}
.route-map-legend {
  display: flex;
  gap: 14px;
  align-items: center;
  /* The dev heat key shares this strip; a narrow window drops it to a second line instead of
     pushing the player's own legend off the map. */
  flex-wrap: wrap;
  row-gap: 4px;
  color: #c8d4e4;
  pointer-events: auto;
}
.legend-item { display: flex; align-items: center; gap: 4px; }
.legend-separator { opacity: 0.3; }
.legend-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
}
.legend-dot.current { background: #ffd166; }
.legend-dot.available { background: #5cd0ff; }
.legend-dot.visited { background: #4ee085; }
.route-map-hint {
  font-size: 12px;
  color: #ffd166;
  pointer-events: auto;
}

/* Shop dialog. */
.shop-dialog {
  position: absolute;
  inset: 0;
  z-index: 90;
  background: rgba(10, 14, 22, 0.92);
  backdrop-filter: blur(12px);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: rmFadeIn 200ms ease-out;
}
.shop-dialog.hidden { display: none !important; }

/* ==========================================================================
   Goblin Merchant fullscreen presentation
   ========================================================================== */

.shop-modal-container {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: #080c14;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  animation: rmFadeIn 250ms ease-out;
}
.shop-modal-container.hidden { display: none !important; }

.shop-viewport {
  position: relative;
  width: 100vw;
  height: 100vh;
  max-width: 1672px;
  max-height: 941px;
  aspect-ratio: 1672 / 941;
  overflow: hidden;
  box-shadow: 0 0 80px rgba(0, 0, 0, 0.9);
}

/* Layer 1: Background Outpost */
.shop-bg-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  pointer-events: none;
}

/* Layer 2: Merchant Wooden Stall (independent sprite) */
.shop-stall-layer {
  position: absolute;
  left: var(--shop-stall-x, 50%);
  top: var(--shop-stall-y, 44%);
  transform: translate(-50%, -50%) scale(var(--shop-stall-scale, 0.70));
  width: 100%;
  height: 100%;
  z-index: var(--shop-stall-z, 1);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  clip-path: var(--shop-stall-clip, none);
}
.shop-stall-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Layer 3: Goblin Merchant Character (independent sprite, main focal point) */
.shop-character-layer {
  position: absolute;
  left: var(--shop-merchant-x, 36%);
  top: var(--shop-merchant-y, 54%);
  transform: translate(-50%, -50%);
  z-index: var(--shop-merchant-z, 2);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.shop-character-img {
  width: auto;
  height: auto;
  max-height: 88vh;
  transform: scale(var(--shop-merchant-scale, 0.76));
  transform-origin: center center;
  filter: drop-shadow(0 18px 36px rgba(0, 0, 0, 0.85));
  animation: goblinBreathe 4s ease-in-out infinite alternate;
}

@keyframes goblinBreathe {
  0% { transform: translateY(0) scale(var(--shop-merchant-scale, 0.76)); }
  50% { transform: translateY(-5px) scale(calc(var(--shop-merchant-scale, 0.76) * 1.01)); }
  100% { transform: translateY(0) scale(var(--shop-merchant-scale, 0.76)); }
}

/* Top Bar Overlay */
.shop-top-bar {
  position: absolute;
  top: var(--shop-topbar-y, 18px);
  left: var(--shop-topbar-x, 24px);
  right: var(--shop-topbar-x, 24px);
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  z-index: var(--shop-topbar-z, 5);
  pointer-events: none;
}

/* Top-Left Title Plate */
.shop-title-plate {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: rgba(12, 16, 24, 0.88);
  border: 1px solid rgba(255, 209, 102, 0.4);
  border-radius: 12px;
  padding: 10px 16px;
  backdrop-filter: blur(8px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.7);
  pointer-events: auto;
  max-width: 280px;
}
.shop-badge-act {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.5px;
  color: #ffd166;
  text-transform: uppercase;
}
.shop-title-text {
  font-family: 'Cinzel', 'Georgia', serif;
  font-size: 18px;
  font-weight: 800;
  color: #fff;
  letter-spacing: 0.5px;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.9);
}
.shop-subtitle-text {
  font-size: 11px;
  font-style: italic;
  color: rgba(255, 255, 255, 0.65);
}

/* Top-Right Resources Plate */
.shop-resources-plate {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  background: rgba(12, 16, 24, 0.88);
  border: 1px solid rgba(255, 209, 102, 0.4);
  border-radius: 12px;
  padding: 10px 14px;
  backdrop-filter: blur(8px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.7);
  pointer-events: auto;
}
.shop-resources-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Merchant Speech Bubble (beside the goblin, not blocking face) */
.shop-speech-bubble {
  position: absolute;
  left: var(--shop-speech-x, 48%);
  top: var(--shop-speech-y, 14%);
  z-index: var(--shop-speech-z, 6);
  max-width: 320px;
  background: rgba(14, 18, 26, 0.94);
  border: 1.5px solid rgba(255, 209, 102, 0.6);
  border-radius: 12px;
  padding: 10px 16px;
  font-size: 13.5px;
  line-height: 1.35;
  color: #fce8bd;
  font-style: italic;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(8px);
  pointer-events: auto;
  animation: speechPop 200ms ease-out;
  transform: translate(0, 0);
}
.shop-speech-bubble .speech-tail {
  position: absolute;
  left: -8px;
  top: 16px;
  width: 0;
  height: 0;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-right: 8px solid rgba(255, 209, 102, 0.6);
}
.shop-speech-bubble.speech-pop {
  transform: scale(1.03);
}

.shop-stat-badge {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: rgba(0, 0, 0, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  font-size: 14px;
  font-weight: 800;
  color: #fff;
}
.shop-stat-badge .stat-icon { font-size: 16px; }
.shop-stat-badge.gold-badge {
  border-color: rgba(255, 209, 102, 0.5);
  background: rgba(255, 209, 102, 0.12);
  color: #ffd166;
}
.shop-stat-badge.gold-badge .stat-num { font-size: 17px; }

/* Current Inventory Row */
.shop-inventory-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 4px;
}
.shop-inventory-row .inv-label {
  font-size: 12px;
  font-weight: 800;
  color: #ffd166;
  text-transform: uppercase;
  letter-spacing: 1px;
}
.shop-inventory-row .inv-slots {
  display: flex;
  gap: 8px;
}
.shop-inv-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(14, 18, 26, 0.85);
  border: 1px solid rgba(255, 209, 102, 0.3);
  border-radius: 8px;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
}
.shop-inv-chip-img {
  width: 18px;
  height: 18px;
  object-fit: contain;
  vertical-align: middle;
}
.shop-inv-chip.empty {
  border: 1px dashed rgba(255, 255, 255, 0.2);
  color: rgba(255, 255, 255, 0.4);
  font-weight: 500;
}

/* Merchant Showcase Grid (shelf of cards mounted on counter) */
.shop-showcase {
  position: absolute;
  bottom: var(--shop-cards-bottom, 25px);
  left: var(--shop-cards-x, 50%);
  transform: translateX(-50%) scale(var(--shop-cards-scale, 1.0));
  display: flex;
  justify-content: center;
  align-items: stretch;
  gap: var(--shop-cards-gap, 14px);
  pointer-events: auto;
  z-index: var(--shop-cards-z, 4);
  /* an absolutely positioned box at left:50% only gets the right half of the screen with
     width:auto, which squeezed the cards to ~148px. Size to the cards instead. */
  width: max-content;
  max-width: 95vw;
}

/* Individual Shop Card */
.shop-item-card {
  flex: 0 1 var(--shop-card-w, 200px);
  max-width: var(--shop-card-w, 200px);
  background: linear-gradient(180deg, rgba(32, 24, 18, 0.94) 0%, rgba(18, 14, 12, 0.96) 100%);
  border: 2px solid rgba(255, 209, 102, 0.4);
  border-radius: 14px;
  padding: 14px 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.8), 0 0 14px rgba(255, 209, 102, 0.1);
  transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
  position: relative;
  backdrop-filter: blur(6px);
}
.shop-item-card:hover:not(.purchased) {
  transform: translateY(-5px);
  border-color: #ffd166;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.9), 0 0 24px rgba(255, 209, 102, 0.25);
}

.shop-item-card.purchased {
  filter: grayscale(0.85);
  opacity: 0.6;
  border-color: rgba(255, 255, 255, 0.15);
}

.card-badge-row {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
  min-height: 18px;
}
.card-type-badge {
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: #ffd166;
  background: rgba(255, 209, 102, 0.15);
  padding: 2px 6px;
  border-radius: 4px;
}
.shop-item-card.rarity-rare .card-type-badge {
  color: #ff9f43;
  background: rgba(255, 159, 67, 0.2);
}
.card-sold-stamp {
  font-size: 10px;
  font-weight: 900;
  color: #ff4757;
  border: 1px solid #ff4757;
  padding: 1px 4px;
  border-radius: 3px;
  letter-spacing: 1px;
}

.card-icon-frame {
  width: 58px;
  height: 58px;
  border-radius: 12px;
  background: radial-gradient(circle, rgba(255, 209, 102, 0.22) 0%, rgba(0, 0, 0, 0.5) 75%);
  border: 1px solid rgba(255, 209, 102, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 4px 0 8px 0;
  overflow: hidden;
}
.card-big-icon {
  font-size: 32px;
}
.shop-card-img-icon {
  width: 48px;
  height: 48px;
  object-fit: contain;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.75));
  transition: transform 0.18s ease;
  pointer-events: none;
}
.shop-item-card:hover:not(.purchased) .shop-card-img-icon {
  transform: scale(1.08);
}

.card-title {
  font-size: 14px;
  font-weight: 800;
  color: #fff;
  margin-bottom: 6px;
  line-height: 1.25;
}
.card-desc {
  font-size: 11.5px;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.72);
  margin-bottom: auto;
  min-height: 34px;
}

.card-footer {
  width: 100%;
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.card-price {
  font-size: 15px;
  font-weight: 800;
  color: #ffd166;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
.card-price.unaffordable {
  color: #ff6b6b;
}

.card-buy-btn {
  width: 100%;
  font: inherit;
  font-size: 13px;
  font-weight: 800;
  padding: 7px 12px;
  border-radius: 8px;
  border: none;
  background: linear-gradient(180deg, #ffd166 0%, #e0a92e 100%);
  color: #1a1208;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  transition: transform 120ms ease, background 120ms ease, opacity 120ms ease;
}
.card-buy-btn:hover:not(:disabled) {
  background: linear-gradient(180deg, #fff 0%, #ffd166 100%);
  transform: translateY(-1px);
}
.card-buy-btn:disabled {
  background: rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.35);
  cursor: not-allowed;
  box-shadow: none;
}

/* Bottom Bar (Helper info + Exit button) */
.shop-bottom-bar {
  position: absolute;
  bottom: var(--shop-bottombar-y, 18px);
  left: var(--shop-bottombar-x, 28px);
  right: var(--shop-bottombar-x, 28px);
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: var(--shop-bottombar-z, 5);
  pointer-events: none;
}
.shop-bottom-helper {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(12, 16, 24, 0.8);
  border: 1px solid rgba(255, 209, 102, 0.3);
  border-radius: 10px;
  padding: 7px 14px;
  font-size: 12px;
  color: #c9d1d9;
  backdrop-filter: blur(6px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
  pointer-events: auto;
}
.shop-bottom-helper .helper-bulb { font-size: 14px; }

/* Exit Button */
.shop-exit-btn {
  position: relative;
  font: inherit;
  font-size: 13px;
  font-weight: 800;
  padding: 9px 22px;
  border-radius: 10px;
  border: none;
  background: linear-gradient(180deg, #ffd166 0%, #e0a92e 100%);
  color: #1a1208;
  cursor: pointer;
  box-shadow: 0 4px 15px rgba(255, 209, 102, 0.25), 0 2px 8px rgba(0, 0, 0, 0.6);
  transition: transform 120ms ease, background 120ms ease;
  pointer-events: auto;
}
.shop-exit-btn:hover {
  background: linear-gradient(180deg, #fff 0%, #ffd166 100%);
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(255, 209, 102, 0.4);
}

/* Replace Slot Modal */
.shop-replace-modal {
  position: absolute;
  inset: 0;
  z-index: 10;
  background: rgba(8, 12, 20, 0.88);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: rmFadeIn 180ms ease-out;
}
.shop-replace-modal.hidden { display: none !important; }

.shop-replace-panel {
  background: #181d28;
  border: 2px solid #ffd166;
  border-radius: 16px;
  width: 90vw;
  max-width: 480px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.9), 0 0 30px rgba(255, 209, 102, 0.2);
  text-align: center;
}
.replace-title {
  font-size: 18px;
  font-weight: 800;
  color: #ffd166;
}
.replace-prompt {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.8);
  margin-bottom: 6px;
}
.replace-slots-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.replace-slot-choice-btn {
  font: inherit;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 209, 102, 0.3);
  border-radius: 10px;
  color: #fff;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.replace-slot-choice-btn:hover {
  background: rgba(255, 209, 102, 0.15);
  border-color: #ffd166;
  transform: translateX(4px);
}
.replace-slot-choice-btn .slot-idx {
  font-size: 11px;
  font-weight: 800;
  color: #ffd166;
}
.replace-slot-choice-btn .slot-icon {
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
}
.shop-slot-img-icon {
  width: 22px;
  height: 22px;
  object-fit: contain;
}
.replace-slot-choice-btn .slot-name { font-size: 14px; font-weight: 700; flex: 1; text-align: left; margin-left: 10px; }
.replace-slot-choice-btn .slot-charges { font-size: 12px; color: rgba(255, 255, 255, 0.6); }

.replace-cancel-btn {
  margin-top: 6px;
}

/* -------------------------------------------------------------------------- */
/* Player game shell and menu                                                 */
/* -------------------------------------------------------------------------- */

body:not(.dev-mode) #devTopbar {
  display: none !important;
}
body:not(.dev-mode) .admin-toggle {
  display: none !important;
}
body:not(.dev-mode) #playerTopbar {
  display: flex !important;
}
/* The debug panel belongs to developer mode only; the player shell never renders it. */
body:not(.dev-mode) #debugPanel {
  display: none !important;
}

body.dev-mode #devTopbar {
  display: flex !important;
}
/* «Скрыть / Показать» must clear the whole dev panel. `.tb-group-admin` and
   `.tb-group-links` are .admin-only, but `.tb-group-scene` (DEV badge + scene picker) is not, so
   clean mode used to leave the bar on screen half-empty. */
body.clean.dev-mode #devTopbar {
  display: none !important;
}
body.dev-mode #playerTopbar {
  display: none !important;
}
body.dev-mode .admin-toggle {
  display: block !important;
}

.player-topbar {
  position: absolute;
  top: 12px;
  right: 14px;
  /* z-index: auto keeps the row out of the stacking race, so one button inside it can be
     lifted over the game's modals (see .player-topbar .bug-capture-btn) without dragging
     «Билд» and «Меню» along — they keep the row's old layer. */
  z-index: auto;
  display: flex;
  gap: 8px;
  align-items: center;
}

.player-topbar .player-nav-btn { position: relative; z-index: 50; }

.player-nav-btn {
  background: linear-gradient(180deg, rgba(39, 39, 42, 0.92) 0%, rgba(9, 9, 11, 0.92) 100%);
  color: #fde68a;
  border: 1px solid #a16207;
  border-radius: 8px;
  padding: 6px 14px;
  font-family: Cinzel, serif;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 1px;
  cursor: pointer;
  backdrop-filter: blur(8px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  transition: background 150ms ease, border-color 150ms ease, transform 120ms ease;
}

.player-nav-btn:hover {
  filter: brightness(1.15);
  border-color: #eab308;
  transform: translateY(-1px);
}

.player-nav-btn:active {
  transform: translateY(0);
}

.player-mode-btn {
  background: rgba(37, 99, 235, 0.85);
  color: #ffffff;
  border: 1px solid rgba(96, 165, 250, 0.6);
  border-radius: 6px;
  padding: 3px 10px;
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  margin-left: auto;
  transition: background 120ms ease;
}

.player-mode-btn:hover {
  background: #2563eb;
}

/* Player Menu Overlay */
.player-menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: rgba(8, 6, 4, 0.8);
  backdrop-filter: blur(10px);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: menuFadeIn 200ms ease-out;
}

.player-menu-overlay.hidden {
  display: none !important;
}

@keyframes menuFadeIn {
  from { opacity: 0; transform: scale(0.98); }
  to { opacity: 1; transform: scale(1); }
}

.player-menu-card {
  width: 420px;
  max-width: calc(100vw - 32px);
  padding: 36px 32px 30px;
  background: rgba(15, 23, 42, 0.96);
  border: 1px solid rgba(148, 163, 184, 0.3);
  border-radius: 16px;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(255, 255, 255, 0.08);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  box-sizing: border-box;
}

.player-menu-crest {
  font-size: 38px;
  line-height: 1;
  margin-bottom: 12px;
  filter: drop-shadow(0 4px 12px rgba(255, 209, 102, 0.3));
}

.player-menu-crest-img {
  width: 64px;
  height: 64px;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgba(234, 179, 8, 0.45));
}

.player-menu-title {
  margin: 0;
  font-family: Cinzel, "Cinzel Decorative", serif, Georgia;
  font-size: 26px;
  font-weight: 900;
  letter-spacing: 2px;
  background: linear-gradient(180deg, #fffbeb 0%, #fde047 35%, #d97706 70%, #78350f 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 3px 10px rgba(0, 0, 0, 0.9)) drop-shadow(0 0 12px rgba(234, 179, 8, 0.35));
}

.player-menu-subtitle {
  margin: 8px 0 28px;
  font-size: 13px;
  color: #d6c7a1;
  line-height: 1.4;
}

.player-menu-actions {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.player-menu-btn {
  width: 100%;
  min-height: 48px;
  border-radius: 10px;
  border: 1px solid transparent;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 16px;
  box-sizing: border-box;
  transition: transform 120ms ease, box-shadow 150ms ease, background 150ms ease, border-color 150ms ease;
}

.player-menu-btn .btn-icon {
  font-size: 18px;
}

.player-menu-btn .btn-text {
  font-family: Cinzel, serif;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 1.5px;
}

.player-menu-btn .btn-label-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.player-menu-btn .btn-subtext {
  font-size: 11px;
  font-weight: 500;
  opacity: 0.85;
  margin-top: 2px;
}

.player-menu-btn.primary-btn {
  background: linear-gradient(180deg, #b45309 0%, #78350f 100%);
  color: #fef3c7;
  border: 2px solid #f59e0b;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.7), 0 0 14px rgba(245, 158, 11, 0.25);
}

.player-menu-btn.primary-btn:hover:not(:disabled) {
  filter: brightness(1.15);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.75), 0 0 20px rgba(245, 158, 11, 0.4);
}

.player-menu-btn.secondary-btn {
  background: linear-gradient(180deg, #27272a 0%, #18181b 100%);
  color: #fde68a;
  border: 2px solid #a16207;
}

.player-menu-btn.secondary-btn:hover:not(:disabled) {
  border-color: #eab308;
  color: #fef3c7;
  transform: translateY(-2px);
}

.player-menu-btn:disabled,
.player-menu-btn.disabled {
  opacity: 0.38;
  cursor: not-allowed;
  pointer-events: none;
  filter: grayscale(0.8);
}

.player-menu-footer {
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid rgba(234, 179, 8, 0.2);
  width: 100%;
  display: flex;
  justify-content: center;
}

.player-menu-dev-btn {
  background: transparent;
  border: none;
  color: #8a7a5c;
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
  padding: 4px 10px;
  border-radius: 6px;
  transition: color 150ms ease, background 150ms ease;
}

.player-menu-dev-btn:hover {
  color: #d6c7a1;
  background: rgba(255, 255, 255, 0.05);
}

/* =============================================================================
   Reward screen
   ============================================================================= */

.reward-screen-modal {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: flex;
  align-items: safe center;
  justify-content: center;
  overflow-y: auto;
  background: radial-gradient(circle at 50% 45%, rgba(22, 16, 32, 0.82) 0%, rgba(6, 5, 10, 0.95) 100%);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  user-select: none;
}

.reward-screen-modal.hidden {
  display: none !important;
}

.reward-screen-content {
  position: relative;
  width: 100%;
  max-width: 1000px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px 20px;
  box-sizing: border-box;
  animation: rewardFadeIn 240ms cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes rewardFadeIn {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.reward-top-bar {
  display: flex;
  gap: 28px;
  align-items: center;
  margin-bottom: 8px;
  font-size: 15px;
  font-weight: 700;
  color: #f1f5f9;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.9);
}

.reward-res-item {
  display: flex;
  align-items: center;
  gap: 6px;
  background: linear-gradient(180deg, rgba(39, 39, 42, 0.85) 0%, rgba(9, 9, 11, 0.85) 100%);
  padding: 4px 12px;
  border-radius: 16px;
  border: 1px solid rgba(161, 98, 7, 0.8);
}

.reward-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 24px;
  text-align: center;
}

.reward-crest {
  font-size: 28px;
  filter: drop-shadow(0 0 10px rgba(250, 204, 21, 0.6));
  margin-bottom: -4px;
}

.reward-title-main {
  font-family: Cinzel, "Cinzel Decorative", serif, Georgia;
  font-size: 44px;
  font-weight: 900;
  letter-spacing: 4px;
  margin: 0;
  background: linear-gradient(180deg, #fffbeb 0%, #fde047 35%, #d97706 70%, #78350f 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.9)) drop-shadow(0 0 24px rgba(234, 179, 8, 0.4));
}

.reward-ribbon {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, #991b1b 0%, #581c1c 100%);
  border: 1px solid #d97706;
  padding: 4px 28px;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.7), inset 0 1px 2px rgba(254, 240, 138, 0.3);
}

.ribbon-text {
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  color: #fef08a;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.reward-cards-row {
  display: flex;
  gap: 28px;
  justify-content: center;
  align-items: stretch;
  width: 100%;
  transition: opacity 200ms ease;
}

.reward-cards-row.faded {
  opacity: 0.15;
  pointer-events: none;
}

.reward-card {
  position: relative;
  width: 260px;
  min-height: 380px;
  display: flex;
  border-radius: 14px;
  cursor: pointer;
  transition: transform 220ms cubic-bezier(0.16, 1, 0.3, 1), filter 220ms;
}

.reward-card:hover {
  transform: translateY(-8px) scale(1.02);
}

.card-border-glow {
  position: absolute;
  inset: -2px;
  border-radius: 16px;
  pointer-events: none;
  opacity: 0.8;
  transition: opacity 200ms, filter 200ms;
}

.reward-card:hover .card-border-glow {
  opacity: 1;
  filter: brightness(1.3);
}

.card-inner-frame {
  position: relative;
  flex: 1;
  width: 100%;
  border-radius: 14px;
  border: 2px solid;
  background: radial-gradient(circle at 50% 30%, #1c1926 0%, #0c0a10 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px 16px;
  box-sizing: border-box;
  box-shadow: inset 0 0 22px rgba(0, 0, 0, 0.85), 0 8px 24px rgba(0, 0, 0, 0.7);
}

.card-gem {
  width: 13px;
  height: 13px;
  transform: rotate(45deg);
  border-radius: 2px;
  margin-bottom: 12px;
}

.card-header-title {
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-align: center;
  margin-bottom: 12px;
  font-family: Cinzel, serif, Georgia;
}

.card-icon-wrap {
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
}

.reward-svg {
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.6));
}

.reward-img-icon {
  width: 86px;
  height: 86px;
  object-fit: contain;
  filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.75));
  transition: transform 0.2s ease, filter 0.2s ease;
  pointer-events: none;
}

/* real perk PNG inside the Level Up card. Contain-fitted, centered,
   aspect preserved; lane glow/border stay on the card itself. */
.perk-icon-img {
  width: 100px;
  height: 100px;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.6));
  pointer-events: none;
}

.reward-card:hover .reward-img-icon {
  transform: scale(1.08);
  filter: drop-shadow(0 8px 22px rgba(0, 0, 0, 0.95));
}

.card-desc-text {
  font-size: 13px;
  line-height: 1.45;
  text-align: center;
  color: #cbd5e1;
  flex-grow: 1;
  margin-bottom: 14px;
  padding: 0 4px;
  /* long perk text grows the card; the stack line and the choose button never leave it */
  overflow-wrap: anywhere;
}

.reward-choose-btn {
  flex-shrink: 0;
  width: 100%;
  padding: 10px 0;
  border: 2px solid;
  background: linear-gradient(180deg, rgba(32, 26, 42, 0.95) 0%, rgba(10, 8, 15, 0.98) 100%);
  border-radius: 8px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 1.5px;
  cursor: pointer;
  transition: background 150ms, transform 150ms, filter 150ms;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.9);
}

.reward-choose-btn:hover {
  filter: brightness(1.25);
  transform: scale(1.02);
}

.reward-skip-wrap {
  margin-top: 24px;
}

.reward-skip-btn {
  background: linear-gradient(180deg, rgba(39, 39, 42, 0.9) 0%, rgba(9, 9, 11, 0.9) 100%);
  border: 1px solid #a16207;
  color: #fde68a;
  padding: 10px 26px;
  border-radius: 8px;
  font-family: Cinzel, serif;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 1.5px;
  cursor: pointer;
  transition: all 150ms;
}

.reward-skip-btn:hover {
  color: #fef3c7;
  border-color: #eab308;
  filter: brightness(1.15);
}

.reward-swap-drawer {
  position: absolute;
  bottom: 80px;
  background: rgba(18, 14, 26, 0.96);
  border: 2px solid #eab308;
  border-radius: 12px;
  padding: 18px 24px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.9);
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  animation: rewardFadeIn 180ms ease-out;
}

.reward-swap-drawer.hidden {
  display: none !important;
}

.swap-title {
  color: #fde047;
  font-size: 14px;
  font-weight: 700;
}

.swap-items {
  display: flex;
  gap: 10px;
}

.swap-item-btn {
  background: rgba(30, 25, 40, 0.9);
  border: 1px solid #d97706;
  border-radius: 8px;
  color: #f1f5f9;
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  transition: all 120ms;
}

.swap-item-btn:hover {
  border-color: #fde047;
  transform: translateY(-2px);
  background: rgba(45, 38, 60, 0.95);
}

.swap-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
}

.swap-item-img {
  width: 26px;
  height: 26px;
  object-fit: contain;
}

.swap-name {
  font-weight: 700;
  font-size: 13px;
}

.swap-replace-tag {
  font-size: 10px;
  color: #fde047;
  text-transform: uppercase;
}

.swap-cancel-btn {
  background: transparent;
  border: 1px solid #64748b;
  color: #94a3b8;
  padding: 4px 12px;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
}

/* =============================================================================
   Level up perk selection screen
   ============================================================================= */

.level-up-modal {
  z-index: 96;
}

.level-up-content {
  max-width: 1180px;
}

.level-up-cards-row {
  display: flex;
  gap: 20px;
  justify-content: center;
  align-items: stretch;
  flex-wrap: wrap;
}

.level-up-card {
  width: 240px;
  min-height: 380px;
}

.perk-stack-info {
  font-size: 13px;
  font-weight: 700;
  margin-top: 6px;
  margin-bottom: 6px;
  text-align: center;
}

.fallback-card {
  opacity: 0.95;
}

.level-up-modal.inspecting {
  display: none !important;
}

.level-up-footer {
  margin-top: 18px;
  display: flex;
  justify-content: center;
  width: 100%;
}

.level-up-inspect-btn {
  background: rgba(30, 27, 38, 0.85);
  border: 1px solid rgba(234, 179, 8, 0.45);
  color: #fef08a;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 22px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.15s ease;
  letter-spacing: 0.5px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

.level-up-inspect-btn:hover {
  background: rgba(45, 40, 58, 0.95);
  border-color: #facc15;
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(234, 179, 8, 0.2);
}

.level-up-inspect-banner {
  position: fixed;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1500;
  display: flex;
  align-items: center;
  gap: 14px;
  background: linear-gradient(180deg, rgba(32, 28, 38, 0.97) 0%, rgba(18, 16, 22, 0.97) 100%);
  border: 2px solid #eab308;
  border-radius: 12px;
  padding: 8px 18px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.85), 0 0 16px rgba(234, 179, 8, 0.3);
}

.level-up-inspect-banner.hidden {
  display: none !important;
}

.level-up-inspect-badge {
  font-size: 13px;
  font-weight: 600;
  color: #fef08a;
  letter-spacing: 0.5px;
}

.level-up-return-btn {
  background: linear-gradient(180deg, #ca8a04 0%, #a16207 100%);
  border: 1px solid #facc15;
  color: #fef08a;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  padding: 6px 18px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.15s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

.level-up-return-btn:hover {
  background: linear-gradient(180deg, #eab308 0%, #ca8a04 100%);
  color: #fff;
  border-color: #fef08a;
  transform: translateY(-1px);
}

/* =============================================================================
   Popup family: victory, boss intro, reward gained and unlock
   ============================================================================= */

.popup-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 950;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 12, 16, 0.76);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 1;
  transition: opacity 180ms ease-out;
}

.popup-modal-backdrop.hidden {
  opacity: 0;
  pointer-events: none;
}

.popup-card {
  position: relative;
  background: linear-gradient(180deg, #27272a 0%, #18181b 45%, #09090b 100%);
  border: 2px solid #52525b;
  border-radius: 14px;
  padding: 24px 32px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  user-select: none;
  overflow: visible;
  animation: popupCardEnter 260ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.popup-card.closing {
  animation: popupCardExit 180ms ease-in forwards;
}

@keyframes popupCardEnter {
  0% {
    opacity: 0;
    transform: translateY(14px) scale(0.94);
  }
  75% {
    transform: translateY(-2px) scale(1.01);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes popupCardExit {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(0.96);
  }
}

/* Boss specific heavy impact enter */
.popup-card-boss {
  border-color: #dc2626 !important;
  animation: popupBossEnter 300ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}

@keyframes popupBossEnter {
  0% {
    opacity: 0;
    transform: scale(0.97);
  }
  60% {
    transform: scale(1.02);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.popup-inner-frame {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
}

/* Crest Top Wrap */
.popup-crest-wrap {
  position: absolute;
  top: -46px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 5;
}

.popup-crest-svg {
  width: 110px;
  height: auto;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.85));
}

.popup-crest-img {
  width: 72px;
  height: 72px;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.9));
}

/* Flank Banners (Left & Right) */
.popup-flank {
  position: absolute;
  top: 10px;
  width: 38px;
  height: 90px;
  z-index: 4;
}

.popup-flank.flank-left {
  left: -20px;
}

.popup-flank.flank-right {
  right: -20px;
}

.flank-pennant {
  width: 100%;
  height: 100%;
  background: linear-gradient(180deg, #991b1b 0%, #7f1d1d 80%, #450a0a 100%);
  border: 1px solid #d97706;
  clip-path: polygon(0% 0%, 100% 0%, 100% 80%, 50% 100%, 0% 80%);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.6);
}

.flank-arrow {
  color: #fde047;
  font-size: 18px;
  font-weight: 900;
}

.boss-pennant {
  background: linear-gradient(180deg, #7f1d1d 0%, #450a0a 80%, #000 100%);
  border-color: #dc2626;
}

.flank-skull {
  color: #fca5a5;
  font-size: 16px;
}

/* Popup Body Content */
.popup-body {
  width: 100%;
  margin-top: 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Main Titles */
.popup-title {
  font-family: Cinzel, "Cinzel Decorative", serif, Georgia;
  font-size: 38px;
  font-weight: 900;
  letter-spacing: 3px;
  margin: 8px 0;
  text-align: center;
  filter: drop-shadow(0 3px 10px rgba(0, 0, 0, 0.9));
}

.popup-title-victory {
  background: linear-gradient(180deg, #fffbeb 0%, #fde047 35%, #d97706 70%, #78350f 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.9)) drop-shadow(0 0 16px rgba(234, 179, 8, 0.4));
}

.popup-title-boss {
  background: linear-gradient(180deg, #fee2e2 0%, #f87171 35%, #dc2626 70%, #450a0a 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.9)) drop-shadow(0 0 20px rgba(220, 38, 38, 0.5));
}

.popup-title-unlock {
  background: linear-gradient(180deg, #f0fdf4 0%, #86efac 35%, #16a34a 70%, #14532d 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.9)) drop-shadow(0 0 18px rgba(34, 197, 94, 0.45));
}

/* Header Labels */
.popup-header-label {
  font-family: Cinzel, serif;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 2px;
  margin: 6px 0 14px 0;
  color: #fde047;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.8));
}

/* Boss & Unlock Tag Plates */
.popup-boss-tag,
.popup-tag-plate {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 3px 18px;
  background: linear-gradient(180deg, #7f1d1d 0%, #450a0a 100%);
  border: 1px solid #dc2626;
  border-radius: 4px;
  margin-bottom: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
}

.popup-tag-plate {
  background: linear-gradient(180deg, #14532d 0%, #052e16 100%);
  border-color: #22c55e;
}

.tag-gem {
  color: #fbbf24;
  font-size: 10px;
}

.tag-text {
  font-family: Cinzel, sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: #fef2f2;
}

/* Subtitle */
.popup-subtitle-boss {
  font-size: 14px;
  color: #fca5a5;
  margin-top: 4px;
}

/* Crimson Ribbon (Victory) */
.popup-ribbon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 28px;
  border-radius: 4px;
  border: 1px solid #f59e0b;
  margin: 6px 0 16px 0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
}

.popup-ribbon .ribbon-text {
  font-size: 13px;
  font-weight: 700;
  color: #fef08a;
  letter-spacing: 1px;
}

/* Details Box */
.popup-details {
  font-size: 13px;
  color: #d4d4d8;
  margin-bottom: 16px;
  line-height: 1.5;
  background: rgba(0, 0, 0, 0.35);
  padding: 8px 18px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.08);
}

/* Icon Display (Center for Reward & Unlock) */
.popup-icon-display {
  position: relative;
  width: 140px;
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 10px 0 14px 0;
}

.popup-arcane-bg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: arcaneRotate 24s linear infinite;
}

@keyframes arcaneRotate {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.popup-arcane-svg {
  width: 100%;
  height: 100%;
}

.popup-icon-center {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
}

.popup-item-svg {
  width: 90px;
  height: 90px;
  filter: drop-shadow(0 0 16px rgba(56, 189, 248, 0.6));
}

.popup-item-img {
  width: 86px;
  height: 86px;
  object-fit: contain;
  filter: drop-shadow(0 0 18px rgba(255, 209, 102, 0.65));
}

/* Name Plaque */
.popup-name-plaque {
  padding: 5px 22px;
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid #71717a;
  border-radius: 6px;
  margin-bottom: 16px;
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.6);
}

.plaque-text {
  font-family: Cinzel, serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: #e4e4e7;
}

.popup-desc-text {
  font-size: 13px;
  color: #a1a1aa;
  max-width: 380px;
  margin-bottom: 16px;
  line-height: 1.4;
}

/* Primary Button */
.popup-action-wrap {
  margin-top: 8px;
  display: flex;
  justify-content: center;
  width: 100%;
}

.popup-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 24px;
  font-family: Cinzel, serif;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 2px;
  border: 2px solid;
  border-radius: 8px;
  cursor: pointer;
  transition: transform 120ms ease, filter 120ms ease, box-shadow 120ms ease;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.7);
}

.popup-btn:hover {
  transform: translateY(-2px) scale(1.02);
  filter: brightness(1.15);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.85);
}

.popup-btn:active {
  transform: translateY(1px) scale(0.98);
}

/* Settings use the popup's slate and bronze, with compact controls so the arena stays visible. */
.hud-settings {
  width: min(460px, calc(100vw - 24px)); max-height: calc(100dvh - 24px); margin: auto;
  padding: 22px 24px; overflow-y: auto; align-items: stretch; text-align: left;
  color: #fef3c7; border-color: #b58a46; box-shadow: 0 20px 64px #000b;
}
.hud-settings:not([open]) { display: none; }
.hud-settings::backdrop { background: #08090c70; }
.hud-settings-header { display: flex; justify-content: space-between; align-items: start; gap: 12px; margin-bottom: 18px; }
.hud-settings h2 { margin: 0; font: 700 24px/1.3 Cinzel, Georgia, serif; color: #fde68a; }
.hud-settings p { margin: 4px 0 0; font: 12px/1.4 system-ui, sans-serif; color: #c6b99c; }
.hud-settings-close { width: 36px; height: 36px; border: 1px solid #856b42; border-radius: 6px; background: #18181b; color: #fde68a; font-size: 24px; cursor: pointer; }
.hud-settings-controls { display: grid; gap: 12px; }
.hud-setting { padding-bottom: 10px; border-bottom: 1px solid #a5884438; }
.hud-setting-label { display: flex; justify-content: space-between; gap: 16px; font-weight: 650; }
.hud-setting output { color: #fde68a; font-variant-numeric: tabular-nums; }
.hud-setting input { appearance: none; width: 100%; height: 6px; margin: 16px 0 10px; border-radius: 8px; background: linear-gradient(to right, #c49a4e var(--range-fill), #43403a var(--range-fill)); cursor: pointer; }
.hud-setting input::-webkit-slider-thumb { appearance: none; width: 20px; height: 20px; border: 2px solid #fce4a5; border-radius: 50%; background: #9a6c2f; box-shadow: 0 2px 5px #0008; }
.hud-setting input::-moz-range-thumb { width: 16px; height: 16px; border: 2px solid #fce4a5; border-radius: 50%; background: #9a6c2f; }
.hud-setting-limits { display: flex; justify-content: space-between; font-size: 10px; color: #ac9f83; }
.hud-settings .hud-settings-note { margin: 12px 0 16px; }
.hud-settings-actions { display: flex; justify-content: space-between; gap: 12px; }
.hud-settings .popup-btn { font: 650 14px/1.3 system-ui, sans-serif; letter-spacing: 0; padding: 10px 18px; }
.hud-settings-reset { color: #dfd0b2; border-color: #7d6846; background: #242322; }
.hud-settings-done { color: #fef3c7; border-color: #d7a952; background: linear-gradient(#9a651e, #684115); }
.hud-settings :is(button, input):focus-visible { outline: 2px solid #fff1b5; outline-offset: 4px; }
@media (max-width: 480px) { .hud-settings { padding: 16px 18px; } }
@media (prefers-reduced-motion: reduce) { .hud-settings { animation: none; } }

.btn-diamond {
  font-size: 10px;
  opacity: 0.8;
}

/* =============================================================================
   Tutorial coachmarks
   Compact dark-fantasy panel with a warm brass edge and a short leader to the
   target. Geometry and color come from TUTORIAL_TUNE as --tutorial-* variables
   so manual tuning happens in one object, not here.
   ============================================================================= */
.tutorial-layer {
  position: fixed;
  inset: 0;
  z-index: var(--tutorial-z-index, 2400);
  pointer-events: none;
  color: var(--tutorial-text, #efece4);
  font: var(--tutorial-font-size, 13px)/var(--tutorial-line-height, 18px) system-ui, sans-serif;
}

.tutorial-layer.is-hidden {
  display: none;
}

.tutorial-scrim {
  position: absolute;
  inset: 0;
  display: none;
  background: rgba(8, 8, 12, var(--tutorial-scrim-opacity, 0.52));
}

/* Only a blocking coachmark may swallow gameplay input. */
.tutorial-layer.is-blocking .tutorial-scrim {
  display: block;
  pointer-events: auto;
}

.tutorial-bubble {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  gap: var(--tutorial-gap, 11px);
  max-width: var(--tutorial-max-width, 300px);
  padding: var(--tutorial-pad-y, 10px) var(--tutorial-pad-x, 13px);
  background: var(--tutorial-panel-bg, rgba(20, 18, 24, 0.96));
  border: var(--tutorial-border-width, 2px) solid var(--tutorial-panel-border, rgba(255, 215, 106, 0.55));
  border-radius: var(--tutorial-radius, 12px);
  box-shadow: var(--tutorial-glow, 0 0 18px rgba(255, 215, 106, 0.18));
  text-align: center;
  animation: tutorialBubbleIn var(--tutorial-enter-ms, 170ms) ease-out;
}

.tutorial-layer.is-blocking .tutorial-bubble {
  pointer-events: auto;
}

.tutorial-text {
  letter-spacing: 0.1px;
}

.tutorial-ack {
  align-self: center;
  width: var(--tutorial-ack-width, 130px);
  height: var(--tutorial-ack-height, 30px);
  font: inherit;
  font-weight: 700;
  color: var(--tutorial-ack-text, #fef08a);
  background: var(--tutorial-ack-bg, #b45309);
  border: 1px solid var(--tutorial-ack-border, #f59e0b);
  border-radius: 8px;
  cursor: pointer;
}

.tutorial-ack:hover {
  filter: brightness(1.12);
}

.tutorial-leader {
  position: absolute;
  top: 0;
  left: 0;
  height: var(--tutorial-leader-width, 2px);
  margin-top: calc(var(--tutorial-leader-width, 2px) / -2);
  background: var(--tutorial-leader, rgba(255, 215, 106, 0.75));
  transform-origin: 0 50%;
  border-radius: 2px;
}

.tutorial-leader.is-hidden {
  display: none;
}

.tutorial-marks {
  position: absolute;
  inset: 0;
}

.tutorial-mark {
  position: absolute;
  width: var(--tutorial-mark-size, 46px);
  height: var(--tutorial-mark-size, 46px);
  margin: calc(var(--tutorial-mark-size, 46px) / -2) 0 0 calc(var(--tutorial-mark-size, 46px) / -2);
  border: var(--tutorial-mark-width, 2px) solid var(--tutorial-ring, rgba(255, 215, 106, 0.85));
  border-radius: 50%;
  animation: tutorialMarkPulse var(--tutorial-mark-pulse, 900ms) ease-out infinite;
}

@keyframes tutorialBubbleIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes tutorialMarkPulse {
  0% { opacity: 0.9; transform: scale(0.86); }
  70% { opacity: 0.25; transform: scale(1.12); }
  100% { opacity: 0; transform: scale(1.12); }
}

/* ---------------------------------------------------------------------------
   POI event modal — simple choice UI over the map/battle view.
   --------------------------------------------------------------------------- */
.event-modal {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: grid;
  place-items: center;
  background: rgba(8, 6, 4, 0.78);
  backdrop-filter: blur(3px);
}
.event-modal.hidden { display: none !important; }
.event-panel {
  width: min(560px, calc(100vw - 48px));
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 26px 30px 24px;
  border: 2px solid #eab308; /* gold frame like the other game modals */
  border-radius: 14px;
  background: linear-gradient(180deg, #241a10 0%, #17110b 100%);
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.65), 0 0 22px rgba(234, 179, 8, 0.22);
  color: #e8d5b0;
  text-align: center;
}
.event-resources {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
}
.event-chip {
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid rgba(240, 201, 135, 0.25);
  background: rgba(0, 0, 0, 0.35);
  font-size: 13px;
  font-weight: 700;
}
.event-icon { font-size: 44px; line-height: 1; }
.event-title {
  margin: 0;
  font-family: Cinzel, "Cinzel Decorative", serif, Georgia;
  font-size: 26px;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: linear-gradient(180deg, #fffbeb 0%, #fde047 35%, #d97706 70%, #78350f 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.9));
}
.event-description {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: #c9b48d;
}
.event-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.event-option {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 16px;
  border: 1px solid rgba(240, 201, 135, 0.4);
  border-radius: 10px;
  background: rgba(240, 201, 135, 0.08);
  color: #f3e3c3;
  font: inherit;
  cursor: pointer;
  text-align: center;
  transition: background 0.15s ease, transform 0.1s ease;
}
.event-option:hover:not(:disabled) {
  border-color: #eab308;
  background: rgba(240, 201, 135, 0.18);
  transform: translateY(-1px);
}
.event-option:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.event-option.continue {
  border: 2px solid #f59e0b;
  background: linear-gradient(180deg, #b45309 0%, #78350f 100%);
  color: #fef3c7;
  font-family: Cinzel, serif;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.event-option-label { font-family: Cinzel, serif; font-size: 16px; font-weight: 800; letter-spacing: 0.03em; }
.event-option-desc { font-size: 13px; color: #c9b48d; }
.event-option-why { font-size: 12px; color: #ff9d9d; }
.event-resolved-summary {
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px dashed rgba(240, 201, 135, 0.35);
  font-size: 14px;
  color: #d9c49a;
}
.event-feedback {
  min-height: 18px;
  font-size: 13px;
  font-weight: 700;
  color: #ff9d9d;
}

/* visible marker on placeholder (TEMP) route maps. */
.route-map-temp-badge { color: #ffcf6b; font-weight: 700; margin-top: 4px; }

/* image stat icons in the shop top bar. */
.stat-icon-img { width: 20px; height: 20px; object-fit: contain; vertical-align: middle; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.8)); }

/* dev-only bug capture button + report panel. Hidden from a normal player session by
   .admin-only (body.clean) and by setDevMode, which never renders the button outside dev mode. */
/* A player must be able to report a bug at any moment, so in a player session the button floats over
   every game surface (popups 950, reward/shop 1000, events 1200, player menu 2000, armory 2100,
   tutorial 2400) and its dialog sits one step above the button. */
.bug-capture-btn { font-weight: 700; }
.player-topbar .bug-capture-btn { position: relative; z-index: 2600; }
.bug-modal {
  position: fixed;
  inset: 0;
  z-index: 2650;
  display: grid;
  place-items: center;
  background: rgba(8, 6, 4, 0.78);
  backdrop-filter: blur(3px);
}
.bug-modal.hidden { display: none !important; }
.bug-panel {
  width: min(520px, calc(100vw - 48px));
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 22px 26px 20px;
  border: 2px solid #eab308; /* modal family: gold frame */
  border-radius: 14px;
  background: linear-gradient(180deg, #241a10 0%, #17110b 100%);
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.65), 0 0 22px rgba(234, 179, 8, 0.22);
  color: #e8d5b0;
}
.bug-title { margin: 0; font-size: 20px; letter-spacing: 0.02em; }
.bug-note-label { font-size: 12px; opacity: 0.8; }
.bug-note {
  resize: vertical;
  min-height: 120px;
  padding: 8px 10px;
  border: 1px solid rgba(240, 201, 135, 0.28);
  border-radius: 8px;
  background: #120d08;
  color: inherit;
  font: 400 14px/1.4 system-ui, sans-serif;
}
/* the player is told how much of the note is still theirs to type */
.bug-counter { margin-top: -8px; text-align: right; font: 600 11px/1 ui-monospace, monospace; color: #b8a37a; }
.bug-result { min-height: 18px; font: 600 12px/1.4 ui-monospace, monospace; word-break: break-all; color: #bbf7d0; }
.bug-result.bad { color: #fecaca; }
.bug-actions { display: flex; gap: 10px; justify-content: flex-end; }
/* Game button styles apply inside .overlay .card and to .player-menu-btn.
   The dev modal lives on document.body, so it carries its own dark-gold button styles. */
.bug-actions button {
  font: inherit;
  padding: 8px 18px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 700;
  transition: filter 120ms ease;
}
.bug-actions .primary-btn { background: linear-gradient(180deg, #b45309 0%, #78350f 100%); border: 2px solid #f59e0b; color: #fef3c7; }
.bug-actions .secondary-btn { background: linear-gradient(180deg, #27272a 0%, #18181b 100%); border: 2px solid #a16207; color: #fde68a; }
.bug-actions button:hover { filter: brightness(1.15); border-color: #eab308; }

/* build screen — same dark/gold family as the victory popup and the player menu. */
.build-overlay {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, 0.62);
}
.build-overlay.hidden { display: none; }
.build-card {
  width: min(560px, 100%);
  max-height: min(86vh, 760px);
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, #27272a 0%, #18181b 45%, #09090b 100%);
  border: 2px solid #eab308;
  border-radius: 14px;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.85), 0 0 22px rgba(234, 179, 8, 0.28);
  color: #d6c7a1;
}
.build-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px 10px;
  border-bottom: 1px solid rgba(161, 98, 7, 0.55);
}
.build-title {
  margin: 0;
  font-family: Cinzel, Georgia, serif;
  font-size: 24px;
  font-weight: 800;
  color: #fde047;
  letter-spacing: 0.04em;
}
.build-close {
  background: linear-gradient(180deg, #27272a 0%, #18181b 100%);
  border: 1px solid #a16207;
  border-radius: 8px;
  color: #fde68a;
  font-weight: 700;
  font-size: 14px;
  padding: 8px 14px;
  cursor: pointer;
}
.build-close:hover { border-color: #eab308; filter: brightness(1.15); }
.build-body { overflow-y: auto; padding: 6px 20px 18px; }
.build-section h3 {
  margin: 14px 0 6px;
  font-family: Cinzel, Georgia, serif;
  font-size: 14px;
  font-weight: 800;
  color: #fde68a;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.build-row {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 7px 10px;
  margin-bottom: 6px;
  border: 1px solid rgba(161, 98, 7, 0.5);
  border-radius: 8px;
  background: rgba(24, 24, 27, 0.75);
}
.build-row.empty { opacity: 0.55; border-style: dashed; }
.build-row-icon { flex: 0 0 36px; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; }
.build-row-img { max-width: 36px; max-height: 36px; object-fit: contain; }
.build-row-body { display: flex; flex-direction: column; min-width: 0; }
.build-row-title { color: #fef3c7; font-weight: 700; font-size: 14px; }
.build-row-tail { margin-left: 8px; color: #eab308; font-weight: 600; font-size: 12px; }
.build-row-text { color: #d6c7a1; font-size: 13px; line-height: 1.35; }
.item-slot .item-count { color: #fde68a; font-weight: 800; }

.build-body { scrollbar-width: thin; scrollbar-color: #a16207 #18181b; }
.build-body::-webkit-scrollbar { width: 8px; }
.build-body::-webkit-scrollbar-track { background: #18181b; }
.build-body::-webkit-scrollbar-thumb { background: #a16207; border-radius: 4px; }

/* shared styled hover tooltip for player-facing combat controls.
   Same dark-panel + brass family as the route-map pin tooltip. Fixed + pointer-events:none so it
   floats next to the hovered control and never covers the board or blocks a click. */
.slot-tip { display: flex; }
/* A disabled/spent control must not swallow the anchor's hover; the non-disabled anchor shows it. */
.slot-tip > .item-slot:disabled { pointer-events: none; }
.rotate-controls .rotate-btn:disabled { pointer-events: none; }
.hud-tooltip {
  position: fixed; left: 0; top: 0; z-index: 300;
  min-width: 150px; max-width: 260px;
  padding: 9px 11px;
  display: flex; flex-direction: column; gap: 4px;
  text-align: left; pointer-events: none;
  opacity: 0; visibility: hidden; transform: translateY(4px);
  transition: opacity 130ms ease, transform 130ms ease;
  background: rgba(12, 17, 26, 0.97);
  border: 1px solid rgba(255, 215, 120, 0.42);
  border-radius: 10px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.92), 0 0 12px rgba(255, 209, 102, 0.2);
  color: #efe7d6;
}
.hud-tooltip.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.hud-tooltip__title { font-weight: 800; font-size: 13px; color: #ffe082; line-height: 1.15; }
.hud-tooltip__effect { font-size: 11.5px; line-height: 1.32; color: #e7dcc6; white-space: pre-line; }
.hud-tooltip__meta { display: flex; flex-direction: column; gap: 2px; margin-top: 1px; }
.hud-tooltip__row { font-size: 11px; font-weight: 700; }
.hud-tooltip__charges { color: #7ce0ff; }
.hud-tooltip__cost { color: #d9b45f; }
/* what the number printed on an enemy chip counts down to. */
.hud-tooltip__timer { color: #9adcff; }
.hud-tooltip__note { font-size: 10.5px; font-style: italic; color: #b9ae99; line-height: 1.3; }
@media (prefers-reduced-motion: reduce) { .hud-tooltip { transition: none; } }


/* admin test armory. A testing panel, not a shop redesign.
   It sits above every game surface (popups 950, reward/shop 1000, events 1200, player menu 2000,
   bug capture 2650): an admin overlay that a victory popup could cover would be unusable exactly when a
   tester wants to grant something between steps. */
.armory-overlay { position: fixed; inset: 0; z-index: 2100; background: rgba(6, 8, 14, 0.66); display: flex; align-items: center; justify-content: center; padding: 16px; }
.armory-overlay.hidden { display: none !important; }
/* Defence in depth: a session that neither runs the dev scene nor asked for the admin unlock cannot
   show the panel even if a stray call reaches it. The unlock is a session class on <body> only. */
body:not(.dev-mode):not(.admin-unlocked) .armory-overlay { display: none !important; }
/* The player shell's admin entry: only for an unlocked session, and only while the dev topbar is not
   already carrying the same control. Clean mode hides it like any other admin chrome. */
#playerArmoryBtn { display: none !important; }
body.admin-unlocked:not(.dev-mode) #playerArmoryBtn { display: flex !important; }
/* Clean view hides admin chrome, and must outrank the rule above rather than tie with it. */
body.clean.admin-unlocked:not(.dev-mode) #playerArmoryBtn { display: none !important; }
.armory-panel { position: relative; width: min(760px, 96vw); max-height: 88vh; display: flex; flex-direction: column; background: #14121a; border: 1px solid var(--panel-border); border-radius: 12px; box-shadow: 0 18px 48px rgba(0, 0, 0, 0.5); color: var(--ink); font-family: system-ui, sans-serif;
  /* The panel is always dark, so it carries its own ink tokens: a visitor on a light colour scheme
     would otherwise inherit the light-theme `:root` override and get dark-on-dark card titles. */
  --ink: #efece4; --ink-dim: #b9b3a4; --accent: #ffd76a; --good: #7be08a; }
.armory-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--panel-border); }
.armory-badge { font-size: 11px; font-weight: 800; letter-spacing: 0.08em; color: #0d0b12; background: var(--accent); padding: 2px 6px; border-radius: 5px; }
.armory-title { font-size: 15px; font-weight: 700; margin-right: auto; }
.armory-search { width: 210px; max-width: 40vw; padding: 6px 9px; font-size: 13px; color: var(--ink); background: rgba(255, 255, 255, 0.06); border: 1px solid var(--panel-border); border-radius: 7px; }
.armory-close { font-size: 16px; line-height: 1; color: var(--ink-dim); background: transparent; border: 0; cursor: pointer; padding: 4px 6px; border-radius: 6px; }
.armory-close:hover { color: var(--ink); background: rgba(255, 255, 255, 0.08); }
.armory-hint { padding: 6px 14px; font-size: 11.5px; color: var(--ink-dim); border-bottom: 1px solid var(--panel-border); }
.armory-body { overflow-y: auto; padding: 8px 14px 14px; }
.armory-empty { padding: 24px; text-align: center; color: var(--ink-dim); font-size: 13px; }
.armory-group { margin-top: 12px; }
.armory-group-title { margin: 0 0 6px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--accent); opacity: 0.9; }
.armory-card { display: grid; grid-template-columns: 40px 1fr auto; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 9px; }
.armory-card:hover { background: rgba(255, 255, 255, 0.04); }
.armory-card.is-owned { opacity: 0.62; }
.armory-card-icon { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; font-size: 22px; background: rgba(0, 0, 0, 0.28); border-radius: 8px; overflow: hidden; }
.armory-card-icon img { width: 100%; height: 100%; object-fit: contain; }
.armory-card-label { font-size: 13.5px; font-weight: 700; }
.armory-card-state { font-size: 11px; font-weight: 600; color: var(--good); margin-left: 4px; }
/* grantable in the DEV sandbox, withdrawn from every production pool. */
.armory-card-banned { font-size: 10px; font-weight: 800; letter-spacing: 0.6px; color: #ffd7d7; background: rgba(190, 36, 36, 0.55); border: 1px solid rgba(255, 120, 120, 0.7); border-radius: 5px; padding: 1px 5px; margin-left: 6px; vertical-align: 1px; }
.armory-card-text { font-size: 11.5px; color: var(--ink-dim); line-height: 1.3; }
.armory-card-btn { min-width: 96px; padding: 7px 10px; font-size: 12.5px; font-weight: 700; color: #0d0b12; background: var(--good); border: 0; border-radius: 8px; cursor: pointer; }
.armory-card-btn:hover { filter: brightness(1.06); }
.armory-card-btn:disabled { background: rgba(255, 255, 255, 0.12); color: var(--ink-dim); cursor: default; }
.armory-replace { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 22px; background: rgba(6, 8, 14, 0.72); border-radius: 12px; }
.armory-replace.hidden { display: none; }
.armory-replace > * { max-width: 420px; }
.armory-replace-title { font-size: 14px; font-weight: 700; }
.armory-replace-list { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.armory-replace-choice { display: flex; align-items: center; gap: 10px; padding: 8px 10px; font-size: 13px; color: var(--ink); background: #1c1a24; border: 1px solid var(--panel-border); border-radius: 9px; cursor: pointer; }
.armory-replace-choice:hover { border-color: var(--accent); }
.armory-replace-choice img { width: 26px; height: 26px; object-fit: contain; }
.armory-replace-name { font-weight: 700; margin-right: auto; }
.armory-replace-count { color: var(--ink-dim); font-size: 12px; }
.armory-replace-cancel { align-self: center; padding: 6px 14px; font-size: 12.5px; color: var(--ink-dim); background: transparent; border: 1px solid var(--panel-border); border-radius: 8px; cursor: pointer; }
.armory-status { position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%); padding: 5px 12px; font-size: 12px; color: #0d0b12; background: var(--accent); border-radius: 7px; opacity: 0; transition: opacity 160ms; pointer-events: none; }
.armory-status:empty { display: none; }
.armory-status:not(:empty) { opacity: 1; }

/* Forge slot (FORGE-SHOP-001): an item upgrade, set apart from merchandise by its ember border. */
.shop-item-card.kind-forge {
  border-color: rgba(255, 140, 60, 0.75);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.8), 0 0 16px rgba(255, 120, 40, 0.25);
}

/* Developer Mode: formula heat reads at a glance through a ring, halo and expected HP loss;
   the pre-board bot snapshot is secondary. The pin's own
   visited/current/locked state may not mute any of that. */
.map-hotspot-pin.has-difficulty .pin-token { box-shadow: 0 0 0 3px var(--diff-color), 0 0 16px 2px var(--diff-halo); }
.map-hotspot-pin.has-difficulty .pin-token::before {
  content: ''; position: absolute; inset: -11px; z-index: -1; border-radius: 50%;
  background: radial-gradient(circle, var(--diff-halo) 0%, transparent 70%);
  pointer-events: none;
}
.map-hotspot-pin.has-difficulty.state-locked .pin-token { opacity: 0.95; filter: none; color: rgba(255, 255, 255, 0.6); }
.map-hotspot-pin.has-difficulty.state-visited .pin-token { opacity: 1; }
.map-hotspot-pin.diff-tier-0 { --diff-color: #4ccf6a; --diff-halo: rgba(76, 207, 106, 0.55); }
.map-hotspot-pin.diff-tier-1 { --diff-color: #e8cf3a; --diff-halo: rgba(232, 207, 58, 0.55); }
.map-hotspot-pin.diff-tier-2 { --diff-color: #f59a3a; --diff-halo: rgba(245, 154, 58, 0.6); }
.map-hotspot-pin.diff-tier-3 { --diff-color: #ff4d3d; --diff-halo: rgba(255, 77, 61, 0.65); }

/* The four heat colours, once, so any host (pin, tooltip, legend chip) can carry a tier class. */
.diff-tier-0 { --diff-color: #4ccf6a; --diff-halo: rgba(76, 207, 106, 0.55); }
.diff-tier-1 { --diff-color: #e8cf3a; --diff-halo: rgba(232, 207, 58, 0.55); }
.diff-tier-2 { --diff-color: #f59a3a; --diff-halo: rgba(245, 154, 58, 0.6); }
.diff-tier-3 { --diff-color: #ff4d3d; --diff-halo: rgba(255, 77, 61, 0.65); }
/* The heat key lives in the map's own legend strip, so it can never sit on top of a map point. */
.map-diff-legend { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; max-width: 100%; }
.map-diff-legend[hidden], .map-diff-sep[hidden] { display: none; }
.map-diff-legend-title { font: 700 11px system-ui, sans-serif; color: #f5d598; letter-spacing: 0.02em; }
.map-diff-legend-row { display: inline-flex; align-items: center; gap: 4px; font: 600 11px system-ui, sans-serif; color: #e7dcc4; }
.map-diff-legend-row i { width: 9px; height: 9px; border-radius: 50%; background: var(--diff-color); box-shadow: 0 0 6px var(--diff-halo); }
.map-diff-legend-meta { font: 600 10px system-ui, sans-serif; color: #b8a37a; }
.pin-diff-pct {
  position: absolute;
  bottom: -9px;
  right: -14px;
  font: 800 9px/1 system-ui, sans-serif;
  padding: 2px 3px;
  border-radius: 4px;
  background: rgba(10, 14, 22, 0.92);
  color: var(--diff-color);
  border: 1px solid var(--diff-color);
  pointer-events: none;
}
.map-hotspot-pin.has-difficulty .pin-tooltip { max-width: 300px; min-width: 240px; }
.tooltip-difficulty {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 6px 8px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.04);
  border-left: 3px solid var(--diff-color, #888);
  font-size: 10.5px;
  line-height: 1.35;
  color: #e6dccb;
}
.tooltip-difficulty .diff-head { font-size: 11.5px; }
.tooltip-difficulty .diff-head b { color: var(--diff-color, #fff); }
.tooltip-difficulty .diff-badge {
  display: inline-block;
  margin-right: 4px;
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 9.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #0c1018;
  background: var(--diff-color, #888);
}
.tooltip-difficulty.diff-tier-0 { --diff-color: #4ccf6a; }
.tooltip-difficulty.diff-tier-1 { --diff-color: #e8cf3a; }
.tooltip-difficulty.diff-tier-2 { --diff-color: #f59a3a; }
.tooltip-difficulty.diff-tier-3 { --diff-color: #ff4d3d; }
.tooltip-difficulty .diff-enemies { color: #c9bda8; }
.tooltip-difficulty .diff-note { margin-top: 2px; font-size: 9px; color: #9a907f; }
.map-hotspot-pin.diff-tip-below .pin-tooltip { bottom: auto; top: calc(100% + 8px); }
.map-hotspot-pin.diff-tip-left .pin-tooltip { left: auto; right: -8px; transform: translateY(6px); }
.map-hotspot-pin.diff-tip-left:hover .pin-tooltip { transform: translateY(0); }
.map-hotspot-pin.diff-tip-right .pin-tooltip { left: -8px; transform: translateY(6px); }
.map-hotspot-pin.diff-tip-right:hover .pin-tooltip { transform: translateY(0); }
.map-hotspot-pin.has-difficulty:hover { z-index: 200; }
/* DIFFICULTY-FORMULA-001: expected damage from the enemies' HP, damage and control, then each enemy. */
/* Developer Mode difficulty panel: docked right, stays on the last pointed point, read in full. */
/* While the panel is open the map board fits the space left of it, so no point sits under the panel. */
.route-map-panel.fullscreen-map { --diff-panel-w: min(380px, 34vw); }
.route-map-panel.has-diff-panel .route-map-viewport { width: calc(100vw - var(--diff-panel-w) - 24px); right: auto; }
.route-map-panel.has-diff-panel .route-map-board {
  width: calc(100vw - var(--diff-panel-w) - 24px);
  max-height: calc((100vw - var(--diff-panel-w) - 24px) * (941 / 1672));
}
.route-diff-panel {
  position: absolute;
  top: 64px;
  right: 12px;
  max-height: calc(100% - 128px);
  width: var(--diff-panel-w);
  box-sizing: border-box;
  z-index: 300;
  display: flex;
  flex-direction: column;
  padding: 10px 12px 12px;
  border-radius: 10px;
  background: rgba(12, 16, 24, 0.94);
  border: 1px solid rgba(232, 207, 58, 0.35);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  color: #e9e1cf;
  font-size: 12.5px;
  overflow-y: auto;
}
.route-diff-panel[hidden] { display: none; }
.route-diff-close {
  position: absolute;
  top: 6px;
  right: 8px;
  background: none;
  border: 0;
  color: #9a907f;
  font-size: 14px;
  cursor: pointer;
}
.route-diff-close:hover { color: #fff; }
.route-diff-body { display: flex; flex-direction: column; gap: 8px; }
.route-diff-title { font-weight: 800; font-size: 15px; color: #fff; padding-right: 22px; }
.route-diff-desc { color: #c9bda8; line-height: 1.35; }
.route-diff-panel .tooltip-difficulty { font-size: 12px; gap: 4px; }
.route-diff-panel .tooltip-difficulty .diff-head { font-size: 13px; }
.route-diff-panel .tooltip-difficulty .diff-note { font-size: 10.5px; }
.tooltip-diff-hint { font-size: 10px; color: #9a907f; }
.tooltip-estimate { margin-bottom: 4px; }
.tooltip-estimate .est-enemy { color: #d8ccb6; line-height: 1.3; }
.tooltip-estimate .est-enemy b { color: #fff; font-weight: 700; }
.tooltip-estimate .est-enemy i { color: #9a907f; font-style: normal; }

/* PERF-LOAD-001: covers the stage while a fight's art is still arriving (art-cover.js). The stage is its own stacking layer, so 90
   sits above all of it and below every modal: reward (95), level-up (96), shop and build (120), popups (950), route map (1000),
   menu (2000). */
.art-loading {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
  background: radial-gradient(ellipse at center, #1a1510 0%, #0b0907 70%);
  color: #f0c987; font: 600 1rem/1.4 system-ui, sans-serif;
}
.art-loading.hidden { display: none; }
.art-loading-card { display: flex; align-items: center; gap: 12px; opacity: 0; animation: artLoadingIn 200ms ease-out 350ms forwards; }
.art-loading-spin { width: 20px; height: 20px; border-radius: 50%; border: 3px solid rgba(240, 201, 135, 0.3); border-top-color: #f0c987; animation: artLoadingSpin 800ms linear infinite; }
@keyframes artLoadingIn { to { opacity: 1; } }
@keyframes artLoadingSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .art-loading-spin { animation-duration: 2400ms; } }
