/* ============================================================
   Battle screen — "Forged Lantern". Loaded after ui-design-system.css (same
   tokens: everything colour-related derives from --h). Layout (see
   docs/subsystems/battle-ui.md):
     >1250px   [ inspector | board | right column ], the hex grid sized from
               the full height; both columns as wide as the inspector when
               the screen allows, so the battlefield is centred. Right
               column: turn chip, deployment box, 3 spell cards stacked,
               Unselect, End Turn. The ☰ menu sits on the inspector's top.
     901-1250  same, the inspector collapsed to a rail that opens as a
               drawer over the map (the grid never resizes).
     601-900   board, then one tray row: Inspect/Unselect | 3 spells |
               turn chip + End Turn; no header (☰ floats on the map).
     ≤600px    header, board, tray (3 spells, then End Turn/Inspect/Unselect).
   The header, .layout, .boardCol, .boardStage and .trayRow become
   `display: contents` in the grid layouts, so their children are placed
   straight into #battleScreen's grid; ids never move. #mapLayer, #board,
   #towerLayer and #boardAnimLayer stay in .board-frame (CLAUDE.md §2);
   #deploymentPanel sits next to it in .boardStage (a pill over the board in
   portrait, a grid item of the right column in landscape), never in #board.
   Cursors: never a bare value (§4). No backdrop-filter on these panels.
   ============================================================ */

/* ---------- header ---------- */
#battleScreen header{ border: 0; padding: 0 2px; margin: 0 0 2px; align-items: center; min-height: 0; }
#battleScreen header h1{ font-size: 1.7rem; }
#battleScreen .battleMenuToggle{
  width: 40px; height: 40px; min-height: 40px; padding: 0; border-radius: 50%; font-size: 1.1rem;
}
#battleScreen .battleMenuDropdown{
  top: calc(100% + 8px); left: 0; min-width: 210px; padding: 8px; gap: 2px; border-radius: 20px;
  background: hsl(var(--h) 14% 7% / .985); border: 1px solid var(--c-line); box-shadow: var(--sh-2);
  animation: ddIn var(--t-med) var(--ease);
}
#battleScreen .battleMenuDropdown button{
  justify-content: flex-start; min-height: 46px; border: 0; border-radius: 12px; background: transparent;
  color: var(--c-text); padding: 0 14px; font-weight: 500; font-size: .95rem; width: 100%; text-align: left;
}
#battleScreen .battleMenuDropdown button:hover{ background: hsl(var(--h) 30% 92% / .08); }
#battleScreen .battleMenuDropdown #surrenderBtn{ color: var(--c-danger); }
#battleScreen .battleMenuDropdown #surrenderBtn:hover{ background: var(--c-danger); color: #1a0705; }
#battleScreen header .status{
  display: inline-flex; align-items: center; flex-wrap: wrap; gap: .5em; padding: 6px 16px; border-radius: 999px;
  font: 600 .9rem var(--f-body); letter-spacing: 0; text-transform: none; color: var(--c-dim);
  background-image: var(--grain), var(--glass-bg); background-color: var(--glass-fill);
  border: 1px solid var(--c-line); box-shadow: var(--sh-1), inset 0 1px 0 hsl(var(--h) 40% 100% / .09);
}
#battleScreen header .status b{ color: var(--c-text); font-variant-numeric: tabular-nums; }
#battleScreen header .status #turnSide{ color: var(--accent-hi); }
#battleScreen header .status .liveMatchTimer{ margin-left: 4px; }

/* ---------- layout: shared ---------- */
#battleScreen{ padding: 6px 10px 6px; gap: 4px; }
#battleScreen .layout{
  display: grid; grid-template-columns: clamp(330px, 26vw, 460px) minmax(0, 1fr); gap: 10px;
  flex: 1; min-height: 0; align-items: stretch;
}
#battleScreen .battleSide{
  grid-column: 1; grid-row: 1;
  flex: none; max-height: none; min-height: 0; overflow: auto; padding: 12px 14px;
  display: flex; flex-direction: column; gap: 12px;
}
.boardCol{ grid-column: 2; grid-row: 1; display: flex; flex-direction: column; gap: 4px; min-height: 0; min-width: 0; }
/* .boardStage = the board frame + the deployment pill floating over it (portrait). */
.boardStage{ position: relative; flex: 1; min-height: 0; min-width: 0; display: flex; flex-direction: column; }

/* Tower HP chips sit inside their own hex (render/board.js) — no band. */
#battleScreen .board-frame{
  flex: 1; min-height: 0; border-radius: 26px; border: 1px solid var(--c-line); box-shadow: var(--sh-2);
  padding: 3px 2px; isolation: isolate;
}
#battleScreen .mapLayer{ border-radius: 25px; }
#battleScreen .board-frame::after{
  content: ""; position: absolute; inset: 0; border-radius: 25px; pointer-events: none; z-index: 0;
  background: radial-gradient(120% 90% at 50% 40%, hsl(var(--h) 20% 5% / .1), hsl(var(--h) 25% 4% / .55));
}
/* Side panels are see-through glass over the player's own Interface background
   (#appBackground), so the map (the battle) and the interface read apart. */
#battleScreen .battleSide{ background-color: hsl(var(--h) 14% 8% / .5); border-color: hsl(var(--h) 40% 80% / .2); }
#battleSide .inspStats div, #battleSide .attrBox, #battleSide .hchip, #battleSide .spellCard.inspCard{ background-color: hsl(var(--h) 16% 8% / .62); }
.inspToggle{ display: none; }

/* ---------- layout: landscape (>900px), one grid ---------- */
@media (min-width: 901px){
  #battleScreen{
    /* local (zoomed) viewport size, CLAUDE.md §7: vw / dvh are real pixels */
    --bs-W: calc(100vw / var(--ui-zoom)); --bs-H: calc(100dvh / var(--ui-zoom));
    --bs-pad: 4px; --bs-gap: 8px;
    --bs-colL: clamp(330px, 26vw, 460px);
    /* the full-height grid's width (9.5 / 14.72 hex radii), its hex at most 160 screen px tall (board.js HEX_MAX_SCREEN_PX) */
    --bs-gridW: min(calc((var(--bs-H) - 2 * var(--bs-pad) - 8px) * 0.6453), calc(877.5px / var(--ui-zoom)));
    /* right column: the inspector's width when the screen has room for it, never under 250px */
    --bs-colR: clamp(250px, calc(var(--bs-W) - 2 * var(--bs-pad) - 2 * var(--bs-gap) - var(--bs-gridW) - var(--bs-colL) - 8px), var(--bs-colL));
    max-width: none; position: relative;
    padding: var(--bs-pad); column-gap: var(--bs-gap); row-gap: 0;
    display: grid;
    grid-template-columns: var(--bs-colL) minmax(0, 1fr) var(--bs-colR);
    grid-template-rows: auto auto minmax(0, 1fr) auto auto auto;
  }
  #battleScreen header, #battleScreen .layout, #battleScreen .boardCol, #battleScreen .boardStage, #battleScreen .trayRow{ display: contents; }
  /* right column glass, painted behind its items */
  #battleScreen::before{
    content: ""; grid-column: 3; grid-row: 1 / -1; border-radius: 22px; pointer-events: none;
    background-image: var(--grain), var(--glass-bg); background-color: hsl(var(--h) 14% 8% / .5);
    border: 1px solid hsl(var(--h) 40% 80% / .2); box-shadow: inset 0 1px 0 hsl(var(--h) 40% 100% / .1);
  }
  #battleScreen .battleSide{ grid-column: 1; grid-row: 1 / -1; padding: 66px 14px 12px; border-radius: 22px; }
  #battleScreen header .titleRow{ grid-column: 1; grid-row: 1; align-self: start; justify-self: start; z-index: 6; margin: 12px 0 0 14px; }
  #battleScreen header h1{ display: none; }
  #battleScreen header .status{ grid-column: 3; grid-row: 1; justify-self: end; align-self: start; z-index: 1; margin: 12px 12px 0; }
  #battleScreen .toastWrap{ grid-column: 2; grid-row: 1; }
  #battleScreen .board-frame{ grid-column: 2; grid-row: 1 / -1; padding: 2px; border-radius: 22px; }
  #battleScreen .mapLayer, #battleScreen .board-frame::after{ border-radius: 21px; }
  #battleScreen .board{ margin-top: 0; margin-bottom: 0; }
  /* the deployment box sits low, just above the spell slots: your deployment rows are at the bottom of the board, so the drag is short */
  #battleScreen #deploymentPanel{ grid-column: 3; grid-row: 3; align-self: end; width: auto; margin: 12px 12px 18px; z-index: 1; }   /* the id: the shared .deploymentPanel rule further down resets margin to 0 */
  #battleScreen .trayRow .spellTray{ grid-column: 3; grid-row: 4; margin: 0 12px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; z-index: 1; }
  #battleScreen .trayRow .selControls{ grid-column: 3; grid-row: 5; width: auto; min-height: 48px; margin: 10px 12px 0; display: flex; gap: 8px; z-index: 1; }
  #battleScreen .trayRow .selControls button{ min-height: 48px; border-radius: 18px; }
  #battleScreen .trayRow #endTurnBtn{ grid-column: 3; grid-row: 6; width: auto; min-height: 64px; margin: 10px 12px 12px; font-size: 1.15rem; z-index: 1; }
  .spellCard{ height: 68px; }
}
/* Tablet landscape: the inspector collapses to a 64px rail (☰, the inspected
   unit's portrait, a toggle); open, it is a drawer over the map, so the grid
   never resizes. */
@media (min-width: 901px) and (max-width: 1250px){
  #battleScreen{ --bs-colL: 64px; --bs-colR: clamp(250px, 24vw, 320px); }
  #battleScreen .battleSide{ padding: 62px 8px 10px; align-items: center; overflow: hidden; }
  #battleScreen .battleSide:not(.open) .inspPanel > :not(.inspHead), #battleSide:not(.open) .inspHead > :not(.inspPortrait), #battleSide:not(.open) .inspEmpty, #battleSide:not(.open) .hint{ display: none; }
  #battleSide:not(.open) .inspPanel{ overflow: hidden; }
  #battleSide:not(.open) .inspPortrait, #battleSide:not(.open) .inspPortrait.inspHex{ width: 48px; height: 41.6px; }
  #battleScreen header .titleRow{ margin: 10px 0 0 12px; }
  .inspToggle{
    display: inline-flex; align-items: center; justify-content: center; margin-top: auto; flex: none;
    width: 44px; height: 44px; min-height: 44px; padding: 0; border-radius: 50%;
  }
  .inspToggle svg{ width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform var(--t-fast); }
  #battleScreen #battleSide.open{
    position: absolute; grid-column: 1 / 3; left: 0; top: 0; bottom: 0; width: min(380px, 100%); z-index: 5;
    align-items: stretch; padding: 66px 14px 12px; background-color: hsl(var(--h) 14% 8% / .97); box-shadow: var(--sh-2);
  }
  #battleSide.open .inspToggle{ align-self: flex-end; }
  #battleSide.open .inspToggle svg{ transform: rotate(180deg); }
}

/* ---------- tiles ---------- */
#board .tile{ background: hsl(var(--h) 16% 10% / .34); border: 0; }
#board .tile.alt{ background: hsl(var(--h) 16% 10% / .34); }
#board .tile.castle-enemy, #board .tile.castle-player{ background: hsl(var(--h) 16% 8% / .5); }
.hexOutline polygon{ stroke: hsl(var(--h) 30% 88% / .3); stroke-width: 3.4; stroke-linejoin: round; }
.tile.moveable .hexOutline polygon, .tile.attackable .hexOutline polygon, .tile.healable .hexOutline polygon,
.tile.swappable .hexOutline polygon{ stroke-width: 5.5; }

/* ---------- tokens ---------- */
/* A unit token (render/token-style.js): the portrait clipped to the flat-top
   hex and filling it, a relief bevel drawn as SVG faces in the unit's tone.
   Tones are FIXED (not hue-driven) and relative to the viewer; blue and orange
   stay apart for colour-blind players and also differ in lightness. */
.token, .miniToken, .inspHex{ --tk-h: 214; --tk-s: 18%; --tk-l: 74%; }
.token.tk-mine, .miniToken.tk-mine, .inspHex.tk-mine{ --tk-h: 212; --tk-s: 80%; --tk-l: 62%; }       /* yours, can still act */
.token.tk-grey, .miniToken.tk-grey, .inspHex.tk-grey{ --tk-h: 214; --tk-s: 18%; --tk-l: 74%; }       /* yours, nothing left / not your turn */
.token.tk-enemy, .inspHex.tk-enemy{ --tk-h: 18; --tk-s: 92%; --tk-l: 57%; }                         /* enemy */
.token.tk-enemydim, .inspHex.tk-enemydim{ --tk-h: 20; --tk-s: 36%; --tk-l: 45%; }                      /* enemy, finished during its turn */
.token.tk-third, .inspHex.tk-third{ --tk-h: 276; --tk-s: 62%; --tk-l: 68%; }                        /* Raising faction, a Rage unit */
/* Every token is a hex wherever it is drawn: on the board, but also as a drag
   ghost (wirePointerDrag clones it into <body>), an animation ghost on the
   overlay layer (fxGhost, the clone split) and the Settings / Dev animation
   stage — never scope this to #board / #battleScreen. */
.token, .miniToken{
  border-radius: 0; box-shadow: none; background: #111; overflow: hidden; flex: none;
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}
#board .token, #battleScreen .miniToken, .tokenDemo .token{ position: relative; }
.token.acted, .token.casting, .token.cast-ready{ filter: none; box-shadow: none; animation: none; }
.token.active-pick{ transform: none; box-shadow: none; }
.token .heroPortrait, .miniToken .heroPortrait, .inspHex .heroPortrait{
  position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 0; box-shadow: none;
}
.token.tk-dim .heroPortrait{ filter: saturate(.55) brightness(.8); }
/* inspector header (panel + Inspect sheet): the same hex token */
.inspPortrait.inspHex{
  width: 78px; height: 67.5px; border: 0; border-radius: 0; position: relative; overflow: hidden; background: #111;
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}
.hcHead .inspPortrait.inspHex{ width: 92px; height: 79.7px; }
/* Dev > Units > Art: the hex token preview of the portrait focus */
.devPfRow{ display: flex; flex-wrap: wrap; gap: 10px; }
.devPfRow label{ display: inline-flex; align-items: center; gap: 6px; }
.devPfRow input{ width: 76px; }
.tokenDemo.devPfPreview .token{ width: 140px; height: 121.2px; }
.tokBevel{ position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.tokBevel .tbOut, .tokBevel .tbIn{ fill: none; stroke: rgba(0,0,0,.6); stroke-width: .9; vector-effect: non-scaling-stroke; }
/* selection: a ring between the token and the tile's edge, in the UI accent */
.selRing{ position: absolute; pointer-events: none; z-index: 4; }
.selRing svg{ display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 0 4px hsl(var(--h) 55% 70% / .7)); }
.selRing polygon{ fill: none; stroke: var(--accent-hi); stroke-width: 2.6; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
/* badges sit centred on a hex corner / edge middle (hexBadgeOffset) */
#board [class*="hexAt-"], .tokenDemo [class*="hexAt-"]{ transform: translate(-50%, -50%); }
#board .hexAt-bl.tempoBadge, .tokenDemo .hexAt-bl.tempoBadge{ transform: translate(calc(-100% + 10px), -50%); }
/* Encyclopedia › Rules › Reading the board (ui/encyclopedia.js) */
.encReadBoard{ display: flex; flex-wrap: wrap; gap: 18px 28px; align-items: center; }
.encTokenDemo{ position: relative; flex: none; max-width: 100%; }
.encReadList{ margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; color: var(--c-dim); flex: 1 1 280px; min-width: 0; }
.encReadList b{ color: var(--c-text); }
.encReadList .encTones{ list-style: none; margin-left: -18px; display: flex; flex-wrap: wrap; gap: 8px 14px; }
.encToneSw{ display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; }
.encToneSw .tokenDemo{ display: inline-block; }   /* grows to the left, never under the HP pill */
.badge.unitMark{
  font: 700 .56rem/1.6 var(--f-body); letter-spacing: .05em; padding: 0 .45em; border-radius: 999px; color: var(--c-text);
  background: hsl(var(--h) 25% 10% / .95); border: 1px solid hsl(var(--h) 30% 80% / .3); box-shadow: 0 2px 6px rgba(0,0,0,.5); white-space: nowrap;
}
.badge.unitMark.rage{ background: hsl(276 45% 26% / .97); color: #e6ccff; border-color: hsl(276 50% 70% / .5); }
/* Tempo Passives: a see-through pill (it may lie over a neighbour), icons opaque */
.badge.tempoBadge{
  z-index: 4; display: inline-flex; align-items: center; gap: 1px; padding: 0 .3em; border-radius: 999px; font-size: .8rem; line-height: 1.45;
  background: hsl(var(--h) 30% 10% / .38); border: 1px solid hsl(var(--h) 55% 70% / .35); white-space: nowrap;
}
.badge.tempoBadge .tpI{ display: inline-flex; filter: drop-shadow(0 1px 1px rgba(0,0,0,.85)); }
.badge.tempoBadge .tpI.off{ opacity: .35; filter: grayscale(1); }
.badge.tempoBadge .itemArt{ width: 1.1em; height: 1.1em; }
.badge.hpchip.e, .hpchip.e{ background: hsl(6 52% 30% / .96); }
.badge{ font-family: var(--f-body); font-variant-numeric: tabular-nums; }
.badge.atk, .badge.mana{
  min-width: 1.35em; text-align: center; border-radius: 999px; padding: 0 .4em; font-size: .68rem; font-weight: 700; line-height: 1.5;
  color: #fff; border: 1px solid rgba(255,255,255,.22); box-shadow: 0 2px 6px rgba(0,0,0,.5);
}
.badge.atk{ background: hsl(6 62% 36% / .95); }
.badge.mana{ background: hsl(212 62% 40% / .95); }
.hpchip{
  min-width: 2.1em; text-align: center; border-radius: 999px; padding: 0 .55em; font-size: .68rem; font-weight: 700; line-height: 1.5;
  color: #fff; border: 1px solid rgba(255,255,255,.2); background: hsl(160 40% 22% / .95); box-shadow: 0 2px 6px rgba(0,0,0,.5);
  font-variant-numeric: tabular-nums;
}
.token.enemy ~ .hpchip{ background: hsl(6 52% 30% / .96); }
.keepHpChip{
  font: 700 .72rem/1.25 var(--f-body); color: var(--c-text); text-shadow: none; padding: 2px 9px; border-radius: 999px;
  background: hsl(var(--h) 25% 7% / .88); border: 1px solid var(--c-line); box-shadow: 0 3px 10px rgba(0,0,0,.5);
}

/* ---------- tray row (portrait; the landscape grid places these one by one) ---------- */
.trayRow{ flex: none; display: flex; gap: 12px; align-items: stretch; padding: 8px 0 4px; }
.trayRow .spellTray{
  flex: 1; min-width: 0; margin: 0; padding: 0; border: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px;
}
.trayRow .selControls{ flex: none; width: clamp(110px, 10vw, 150px); display: flex; align-items: stretch; gap: 8px; }
.trayRow .selControls:empty{ display: block; }   /* keep the slot's width so the tray never shifts */
.trayRow .selControls button, .trayRow #endTurnBtn{
  flex: 1; min-height: 80px; border-radius: 22px; font: 700 1rem var(--f-display); white-space: nowrap;
}
.trayRow #endTurnBtn{ flex: none; width: clamp(110px, 10vw, 150px); }
.trayRow .selControls .selInspect{ display: none; }   /* wide: the inspector panel already shows the unit */

.spellCard{
  height: 68px; border-radius: 20px; border: 1px solid var(--c-line); color: var(--c-text);
  background-image: var(--grain), var(--glass-bg); background-color: hsl(var(--h) 16% 8% / .86);
  box-shadow: var(--sh-1), inset 0 1px 0 hsl(var(--h) 40% 100% / .09);
}
.spellCard .sc-body{ padding: 7px 14px; justify-content: center; gap: 2px; border-radius: 20px; }
/* A long name wraps to 2 lines, and only past 2 lines gets an ellipsis; the
   type never shrinks. The card is as short as 2 lines + the stats line allow. */
.spellCard .sc-title{ font: 700 .98rem/1.12 var(--f-display); letter-spacing: 0; color: var(--c-text); gap: 8px; white-space: normal; min-width: 0; padding-right: 10px; }
.spellCard .sc-title .scName{ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; min-width: 0; }
.spellCard .sc-title > span:first-child{ font-size: 1.15rem; }
.spellCard .sc-title .heroPortrait{ width: 24px; height: 24px; }
.spellCard .sc-stats{ gap: 8px; font: 600 .85rem var(--f-body); font-variant-numeric: tabular-nums; }
.spellCard .sc-dmg{ font-weight: 800; font-size: 1rem; }
.spellCard .sc-tag{ background: none; padding: 0; gap: 3px; font-weight: 700; }
.spellCard .sc-mod{ width: 19px; height: 19px; font-size: .68rem; background: hsl(150 32% 26% / .95); color: #d6f2dc; border: 1px solid hsl(150 40% 50% / .5); }
.spellCard:not(.disabled):not(.emptySlot):hover{ transform: translateY(-4px); border-color: hsl(var(--h) 45% 64% / .6); box-shadow: var(--sh-1); }
.spellCard{ transition: transform var(--t-med) var(--ease), border-color var(--t-med), box-shadow var(--t-med); }
.spellCard.active{ border-color: hsl(8 80% 66%); box-shadow: 0 0 0 2px hsl(8 80% 62% / .55), var(--sh-1); }
.spellCard.active .sc-title{ color: hsl(8 80% 74%); }
.spellCard.disabled{ opacity: .42; filter: grayscale(.5); }
.spellCard.emptySlot{ background: none; border: 1px dashed var(--c-line); box-shadow: none; backdrop-filter: none; display: flex; align-items: center; justify-content: center; }
.scEmpty{ margin: auto; text-align: center; font: 500 .8rem/1.35 var(--f-body); color: var(--c-dim); opacity: .8; padding: 0 8px; }
/* Rooted spell (engine/action-economy.js): an anchor badge at the top-left
   corner; a Cast Time badge, when there is one, moves right of it. */
.spellCard .sc-rooted{
  position: absolute; top: -9px; left: -9px; z-index: 1;
  width: 22px; height: 22px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  font-size: .72rem; line-height: 1;
  background: radial-gradient(circle at 35% 30%, hsl(28 45% 52%), hsl(24 50% 24%));
  border: 2px solid hsl(var(--h) 20% 8%); box-shadow: 0 2px 6px rgba(0,0,0,.5);
}
.spellCard .sc-rooted ~ .sc-casttime{ left: 17px; }
.spellCard.inspCard .sc-rooted{ width: 20px; height: 20px; font-size: .64rem; }
.spellCard.inspCard .sc-rooted ~ .sc-casttime{ left: 15px; }
.spellCard .sc-mana, .spellCard .sc-casttime, .spellCard .sc-cooldown, .spellCard .sc-needsclick{
  border: 2px solid hsl(var(--h) 20% 8%); box-shadow: 0 2px 6px rgba(0,0,0,.5);
}

/* ---------- deployment: a box in the right column (landscape) / a floating pill over the board (portrait) ---------- */
#battleScreen .deploymentPanel{
  position: relative; z-index: 8; padding: 12px 14px; margin: 0; border-radius: 20px;
  background-image: var(--grain), var(--glass-bg); background-color: hsl(var(--h) 16% 8% / .78);
  border: 1px solid var(--c-line); box-shadow: inset 0 1px 0 hsl(var(--h) 40% 100% / .09);
}
#battleScreen .deploymentPanel.hidden{ display: none; }
#battleScreen .deploymentPanel h3{ font: 700 1rem var(--f-display); margin: 0 0 10px; color: var(--c-text); white-space: nowrap; }
#battleScreen .deploymentPanel .depCap{ font: 500 .76rem var(--f-body); color: var(--c-dim); margin-left: 6px; }
/* 3 per row in the column; a token is as wide as a third of it, at most 96px */
#battleScreen .deployRoster{ display: grid; grid-template-columns: repeat(3, minmax(0, 96px)); gap: 10px; justify-content: start; }
#battleScreen .miniToken{ width: 100%; height: auto; aspect-ratio: 2 / 1.732; }
#battleScreen .miniToken.armed{ --tk-h: var(--h); --tk-s: 55%; --tk-l: 74%; }   /* armed for placement: the UI accent */
.depCount{ display: none; }
.depGrip{
  display: none; width: 44px; height: 44px; min-height: 44px; padding: 0; border-radius: 50%; flex: none; color: var(--c-dim);
}
.depGrip svg{ width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Floating pill (portrait): docked at the board's top edge by default (away from
   your own deployment rows, which are always at the bottom — the guest's view
   is turned); the grip moves it to the bottom edge. */
@media (max-width: 900px){
  #battleScreen .deploymentPanel{
    position: absolute; left: 50%; top: 8px; bottom: auto; width: auto; max-width: calc(100% - 16px); transform: translateX(-50%);
    display: flex; align-items: center; gap: 8px; padding: 6px 12px 6px 6px; border-radius: 999px;
    background-color: hsl(var(--h) 16% 8% / .9); box-shadow: var(--sh-2), inset 0 1px 0 hsl(var(--h) 40% 100% / .09);
  }
  #battleScreen .deploymentPanel.hidden{ display: none; }
  #battleScreen .deploymentPanel.atBottom{ top: auto; bottom: 8px; }
  #battleScreen .deploymentPanel h3{ display: none; }
  #battleScreen .deployRoster{ display: flex; flex-wrap: nowrap; gap: 8px; }
  #battleScreen .miniToken{ width: 64px; height: auto; flex: none; }
  .depGrip{ display: inline-flex; }
  .depCount{ display: inline; font: 600 .74rem var(--f-body); color: var(--c-dim); white-space: nowrap; }
}
@media (max-width: 600px){
  #battleScreen .miniToken{ width: 50px; }
}

/* ---------- inspector (left panel) ---------- */
.inspPanel{ flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 12px; padding: 2px 0 0; }
.inspEmpty{ margin: auto; text-align: center; display: flex; flex-direction: column; gap: 8px; color: var(--c-dim); font: 500 .88rem/1.5 var(--f-body); }
.inspEmpty b{ font: 700 1rem var(--f-display); color: var(--c-text); }
.inspHead{ display: flex; gap: 14px; align-items: center; }
.inspHead b{ display: block; font: 700 1.2rem/1.15 var(--f-display); color: var(--accent-hi); }
.inspHead span{ font: 500 .8rem/1.4 var(--f-body); color: var(--c-dim); }
.inspPortrait{
  flex: none; width: 68px; height: 68px; min-height: 0; padding: 0; border-radius: 50%; overflow: hidden; background: #111;
  border: 3px solid hsl(178 42% 58%); cursor: var(--cur-click, pointer);
}
.inspPortrait.e{ border-color: hsl(8 62% 56%); }
.inspPortrait .heroPortrait{ width: 100%; height: 100%; border-radius: 0; box-shadow: none; -webkit-user-drag: none; user-select: none; pointer-events: none; }
.inspNote{ margin: 0; font: 400 .88rem/1.5 var(--f-body); color: var(--c-dim); }
.inspNote b{ color: var(--c-text); }
.inspStats{ display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 8px; }
.inspStats div{ padding: 8px 6px; border-radius: 14px; background: hsl(var(--h) 25% 96% / .06); text-align: center; }
.inspStats span{ display: block; font: 500 .7rem var(--f-body); color: var(--c-dim); white-space: nowrap; }
.inspStats b{ font: 700 .98rem var(--f-body); font-variant-numeric: tabular-nums; }
.flask{ width: 1.05em; height: 1.05em; vertical-align: -.17em; display: inline-block; }
.inspLine{ font: 500 .82rem var(--f-body); color: var(--c-dim); }
.inspLine.casting{ color: #ad8adf; }
.inspLine.ready{ color: var(--accent-hi); }
.attrBox{ display: flex; flex-direction: column; border-radius: 16px; background: hsl(var(--h) 25% 96% / .04); border: 1px solid var(--c-line); padding: 4px 12px; }
.attrRow{ display: flex; justify-content: space-between; gap: 12px; align-items: center; padding: 6px 0; border-bottom: 1px dashed hsl(var(--h) 20% 90% / .1); font: 500 .84rem var(--f-body); color: var(--c-dim); }
.attrRow:last-child{ border-bottom: 0; }
.attrRow b{ color: var(--c-text); font-weight: 600; text-align: right; }
.inspSec h5{ margin: 2px 0 6px; font: 700 .72rem var(--f-body); letter-spacing: .08em; text-transform: uppercase; color: var(--c-dim); }
.inspSp{ display: flex; gap: 6px; flex-wrap: wrap; }
.hchip{
  display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 12px; border-radius: 999px; border: 1px solid var(--c-line);
  background: hsl(var(--h) 25% 96% / .07); color: var(--c-text); font: 600 .82rem var(--f-body); cursor: var(--cur-click, pointer);
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: none;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.hchip:hover, .hchip.held{ background: hsl(var(--h) 40% 70% / .16); border-color: hsl(var(--h) 45% 64% / .6); }
.hchip.debuff{ color: #e8955f; }
.hchip.buff{ color: #7fd4cc; }
.holdVal{
  color: var(--c-text); border-bottom: 2px dotted hsl(var(--h) 45% 70% / .55); cursor: var(--cur-click, pointer);
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: none; padding-bottom: 1px;
}
.holdVal:hover, .holdVal.held{ color: var(--accent-hi); border-bottom-color: var(--accent-hi); }
.holdHint{ margin: 0; font: 400 .76rem/1.45 var(--f-body); color: var(--c-dim); opacity: .8; }
/* side / bottom padding >= the 9px every corner badge overhangs its card (mana, cast time,
   cooldown), or the last card's badges stick out and the inspector scrolls sideways */
.inspCards{ display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 12px; padding: 10px 10px 10px; }
.spellCard.inspCard{
  height: 76px; flex: none; border-radius: 16px; cursor: var(--cur-click, pointer); touch-action: none;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.spellCard.inspCard:hover{ transform: none; }
.spellCard.inspCard.held{ border-color: hsl(var(--h) 45% 64% / .7); }
.spellCard.inspCard .sc-body{ padding: 8px; }
.spellCard.inspCard .sc-title{ font-size: .8rem; gap: 4px; padding-right: 6px; white-space: normal; line-height: 1.15; overflow: visible; }
.spellCard.inspCard .sc-title > span:first-child{ font-size: 1rem; }
.spellCard.inspCard .sc-stats{ gap: 4px; font-size: .76rem; }
.spellCard.inspCard .sc-mana, .spellCard.inspCard .sc-casttime, .spellCard.inspCard .sc-cooldown{ min-width: 20px; height: 20px; font-size: .64rem; }

/* press-and-hold Encyclopedia popup */
.holdPop{
  position: fixed; z-index: 300; width: min(310px, calc(100vw / var(--ui-zoom, 1) - 16px)); padding: 16px 16px 12px; border-radius: 22px; pointer-events: none;
  background-image: var(--grain), var(--glass-bg); background-color: hsl(var(--h) 14% 7% / .97);
  border: 1px solid hsl(var(--h) 40% 70% / .35); box-shadow: var(--sh-2), inset 0 1px 0 hsl(var(--h) 40% 100% / .1);
  animation: ddIn var(--t-fast) var(--ease);
}
.holdPop[hidden]{ display: none; }
.holdPop.art{ width: min(300px, calc(100vw / var(--ui-zoom, 1) - 16px)); padding: 8px 8px 12px; }
.hpHead{ display: flex; gap: 12px; align-items: center; margin-bottom: 10px; }
.hpIcon{ width: 42px; height: 42px; border-radius: 14px; display: grid; place-items: center; font-size: 1.4rem; background: hsl(var(--h) 25% 96% / .08); border: 1px solid var(--c-line); }
.hpHead b{ display: block; font: 700 1.08rem var(--f-display); color: var(--accent-hi); }
.hpHead small{ font: 500 .76rem var(--f-body); color: var(--c-dim); }
.hpRow{ display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; border-bottom: 1px dashed hsl(var(--h) 20% 90% / .1); font: 500 .84rem var(--f-body); color: var(--c-dim); }
.hpRow b{ color: var(--c-text); font-weight: 600; text-align: right; }
.holdPop p{ margin: 10px 0 0; font: 400 .84rem/1.5 var(--f-body); color: var(--c-dim); }
.hpFoot{ display: block; margin-top: 10px; font: 600 .68rem var(--f-body); letter-spacing: .08em; text-transform: uppercase; color: var(--c-dim); opacity: .6; }
.hpArt{ display: block; width: 100%; max-height: calc(100dvh / var(--ui-zoom, 1) - 90px); object-fit: contain; border-radius: 16px; background: #0b0e0c; }
.hpCap{ margin-top: 8px; text-align: center; font: 700 1rem var(--f-display); color: var(--accent-hi); }

/* ---------- portrait phones / tablets ---------- */
@media (max-width: 900px){
  #battleScreen{ padding: 3px 3px 4px; gap: 2px; }
  #battleScreen header{ margin: 0; }
  #battleScreen header h1{ font-size: 1.35rem; }
  #battleScreen .battleMenuToggle{ width: 36px; height: 36px; min-height: 36px; }
  #battleScreen .layout{ grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr); gap: 4px; }
  #battleScreen .board-frame{ padding: 2px 0; border-radius: 16px; }
  #battleScreen .mapLayer, #battleScreen .board-frame::after{ border-radius: 15px; }
  .boardCol{ gap: 2px; }
  .boardCol{ grid-column: 1; }
  #battleScreen .battleSide{ display: none; }   /* the Inspect button opens the full-screen sheet instead */
  .trayRow{
    display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px 8px; padding: 6px 0 2px;
    grid-template-areas: "tray tray tray" "end sel sel";
  }
  .trayRow .spellTray{ grid-area: tray; gap: 8px; }
  .trayRow #endTurnBtn{ grid-area: end; width: auto; min-height: 46px; }
  .trayRow .selControls{ grid-area: sel; width: auto; }
  .trayRow .selControls:empty{ display: block; }
  .trayRow .selControls button{ min-height: 46px; }
  .trayRow .selControls .selInspect{ display: inline-flex; }
  .spellCard{ height: 54px; border-radius: 14px; }
  .spellCard .sc-body{ padding: 5px 10px; border-radius: 14px; gap: 1px; }
  .spellCard .sc-title{ font-size: .8rem; line-height: 1.02; gap: 5px; }
  .spellCard .sc-title > span:first-child{ font-size: .95rem; }
  .spellCard .sc-stats{ font-size: .7rem; gap: 5px; }
  .spellCard .sc-dmg{ font-size: .82rem; }
  #battleScreen header .status{ padding: 4px 12px; font-size: .82rem; }
}
/* Tablet portrait: no header row (☰ floats over the map's top-left corner,
   the turn chip sits on End Turn) and one tray row, so the board — limited by
   height here — gets the room. */
@media (min-width: 601px) and (max-width: 900px){
  #battleScreen{
    padding: 4px; display: grid; gap: 6px 8px;
    grid-template-columns: 104px minmax(0, 1fr) 150px;
    grid-template-rows: minmax(0, 1fr) auto auto;
  }
  #battleScreen header, #battleScreen .layout, #battleScreen .boardCol, #battleScreen .trayRow{ display: contents; }
  #battleScreen .boardStage{ grid-column: 1 / -1; grid-row: 1; }
  #battleScreen header h1{ display: none; }
  #battleScreen header .titleRow{ grid-column: 1; grid-row: 1; align-self: start; justify-self: start; z-index: 9; margin: 8px 0 0 8px; }
  #battleScreen header .status{ grid-column: 3; grid-row: 2; justify-self: stretch; justify-content: center; padding: 2px 6px; font-size: .7rem; gap: .3em; }
  #battleScreen .toastWrap{ grid-column: 2 / -1; grid-row: 1; }
  #battleScreen .trayRow .selControls{ grid-column: 1; grid-row: 2 / 4; width: auto; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
  #battleScreen .trayRow .spellTray{ grid-column: 2; grid-row: 2 / 4; align-self: stretch; }
  #battleScreen .trayRow #endTurnBtn{ grid-column: 3; grid-row: 3; width: auto; min-height: 44px; border-radius: 14px; font-size: 1.05rem; }
  /* Inspect / Unselect as icon buttons, full tray height (>= 44px targets) */
  #battleScreen .trayRow .selControls button{ min-height: 44px; height: 100%; padding: 0; border-radius: 14px; font-size: 0; }
  #battleScreen .trayRow .selControls .selInspect::before{ content: "ⓘ"; font-size: 1.25rem; }
  #battleScreen .trayRow .selControls .selUnselect::before{ content: "✕"; font-size: 1.1rem; }
  .spellCard{ height: 68px; border-radius: 16px; }
  .spellCard .sc-body{ padding: 7px 12px; border-radius: 16px; gap: 2px; }
  .spellCard .sc-title{ font-size: .92rem; line-height: 1.1; }
}
@media (max-width: 480px){
  #battleScreen header h1{ font-size: 1.3rem; }
}
@media (max-height: 640px) and (min-width: 901px){
  .spellCard{ height: 62px; }
  #battleScreen .trayRow #endTurnBtn{ min-height: 52px; }
}
@media (prefers-reduced-motion: reduce){
  .spellCard{ transition: none; }
  .holdPop, #battleScreen .battleMenuDropdown{ animation: none; }
}
.inspSp .hchip{ flex: none; width: auto; }

/* ---------- battle overlays: "F modal" (game over, room intro, Endless wave, log, audio, Inspect sheet…) ---------- */
.overlay:has(.fModal){ background: hsl(var(--h) 25% 3% / .66); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); padding: 18px; }
.overlay.show:has(.fModal){ animation: ovIn .28s var(--ease); }
@keyframes ovIn{ from{ opacity: 0; } to{ opacity: 1; } }
.modal.fModal{
  position: relative; width: min(100%, 440px); max-width: none; max-height: calc(100dvh - 36px); overflow: auto;
  padding: 30px 28px 26px; border-radius: 30px; text-align: center; display: flex; flex-direction: column; gap: 14px;
  background-image: var(--grain), var(--glass-bg); background-color: hsl(var(--h) 14% 8% / .94);
  border: 1px solid var(--c-line); box-shadow: var(--sh-2), inset 0 1px 0 hsl(var(--h) 40% 100% / .1);
}
.overlay.show .modal.fModal{ animation: modalIn .34s var(--ease); }
@keyframes modalIn{ from{ opacity: 0; transform: translateY(16px) scale(.97); } to{ opacity: 1; transform: none; } }
.modal.fModal h2{ font: 700 2rem/1.1 var(--f-display); letter-spacing: -.01em; color: var(--c-text); margin: 0; }
.modal.fModal p{ color: var(--c-dim); font: 400 1rem/1.55 var(--f-body); margin: 0; }
.modal.fModal .hint{ font-size: .85rem; border: 0; padding: 0; }
.modal.fModal > div[style*="justify-content:center"]{ flex-wrap: wrap; }
.modal.fModal > div[style*="justify-content:center"] button{ flex: 1 1 120px; }
.modal.fModal.wide{ width: min(100%, 520px); text-align: left; }
.modal.fModal.wide h2, .modal.fModal.wide h3{ font-size: 1.5rem; padding-right: 56px; margin: 0; }
.modal.fModal.battleLogModal{ width: min(100%, 900px); }
.modal.fModal .closeX{ position: absolute; top: 16px; right: 16px; width: 44px; height: 44px; min-height: 44px; padding: 0; border-radius: 50%; float: none; z-index: 2; }
.crest{
  width: 64px; height: 64px; margin: 0 auto; border-radius: 50%; display: grid; place-items: center; flex: none;
  background: hsl(var(--h) 24% 96% / .06); border: 1px solid var(--c-line); color: var(--accent-hi);
}
.crest svg{ width: 30px; height: 30px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.modal.win .crest{ box-shadow: 0 0 0 6px hsl(var(--h) 40% 60% / .1); }
.modal.win h2{ color: var(--accent-hi); }
.modal.lose .crest{ color: var(--c-danger); box-shadow: 0 0 0 6px hsl(8 70% 60% / .1); }
.modal.lose h2{ color: var(--c-danger); }
#endlessWaveClearOverlay .modal > div[style*="flex-direction:column"]{ width: 100%; max-width: 280px; margin: 6px auto 0; gap: 10px !important; }
#battleAudioOverlay .modal h2{ padding-right: 56px; }
.battleLogModal .log{ text-align: left; border-radius: 18px; background: hsl(var(--h) 14% 6% / .7); border: 1px solid var(--c-line); padding: 6px 14px; }

/* Inspect sheet body (render/inspector.js's buildInspectSheetHTML) */
#heroCardContent{ display: flex; flex-direction: column; gap: 12px; }
.hcHead{ display: flex; gap: 16px; align-items: center; padding-right: 48px; }
.hcHead .inspPortrait{ width: 84px; height: 84px; }
.hcHead b{ display: block; font: 700 1.6rem var(--f-display); color: var(--accent-hi); }
.hcHead span{ color: var(--c-dim); font: 500 .85rem var(--f-body); }
.hcBox{ border-radius: 20px; border: 1px solid var(--c-line); background: hsl(var(--h) 24% 96% / .04); padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; }
.hcBox h4{ font: 700 .95rem var(--f-display); color: var(--accent-hi); margin: 0; }
.hcBox .attrBox{ border: 0; padding: 0; background: none; }
.hcBox .inspSec + .inspSec{ margin-top: 2px; }
.hcBox .inspStats{ grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); }
.hcBox .inspCards{ padding: 10px 10px 10px; }
.xpBarOuter{ height: 8px; border-radius: 999px; background: hsl(var(--h) 25% 6% / .9); border: 1px solid var(--c-line); overflow: hidden; }
.xpBarInner{ height: 100%; background: var(--btn-fill); }
.xpLabel{ font: 500 .85rem var(--f-body); color: var(--c-dim); }
@media (max-width: 900px){
  #heroCardOverlay{ padding: 0; align-items: stretch; }
  #heroCardOverlay .modal.fModal{ width: 100%; max-width: none; max-height: 100dvh; height: 100%; border-radius: 0; border-left: 0; border-right: 0; padding: 24px 14px 20px; justify-content: flex-start; }
}
@media (prefers-reduced-motion: reduce){
  .overlay.show:has(.fModal), .overlay.show .modal.fModal{ animation: none; }
}

.hpIcon{ overflow: hidden; }
.hpIcon .heroPortrait{ width: 100%; height: 100%; border-radius: 14px; box-shadow: none; object-fit: cover; -webkit-user-drag: none; }

/* The spell-card drag's target reticle (render/highlights.js's showSpellReticle):
   a ring with 4 ticks on the hex under the pointer, on #boardAnimLayer. Green
   with a dot where releasing casts the spell, orange with a cross where it
   doesn't; small with a deep shadow over a unit, large and flat over an empty
   hex. Size, colour and position glide. */
.spellReticle{
  position: absolute; z-index: 6; pointer-events: none; transform: translate(-50%, -50%);
  color: hsl(var(--h) 62% 68%); opacity: 0;
  filter: drop-shadow(0 3px 4px rgba(0,0,0,.6));
  transition: left 110ms ease-out, top 110ms ease-out, width 240ms cubic-bezier(.3,1.4,.5,1), height 240ms cubic-bezier(.3,1.4,.5,1), color 220ms ease, filter 240ms ease, opacity 150ms ease;
}
.spellReticle.srInstant{ transition: none; }
.spellReticle.shown{ opacity: 1; }
.spellReticle.no{ color: hsl(18 100% 68%); }
.spellReticle.onUnit{ filter: drop-shadow(0 12px 10px rgba(0,0,0,.6)); }
.spellReticle i{ position: absolute; display: block; }
.spellReticle .srRing{ inset: 0; border: 3px solid currentColor; border-radius: 50%; box-sizing: border-box; }
.spellReticle .srTick{ background: currentColor; border-radius: 2px; }
.spellReticle .srT, .spellReticle .srB{ left: 50%; width: 3px; height: 12px; margin-left: -1.5px; }
.spellReticle .srT{ top: -7px; } .spellReticle .srB{ bottom: -7px; }
.spellReticle .srL, .spellReticle .srR{ top: 50%; width: 12px; height: 3px; margin-top: -1.5px; }
.spellReticle .srL{ left: -7px; } .spellReticle .srR{ right: -7px; }
.spellReticle .srMark{ left: 50%; top: 50%; width: 0; height: 0; }
.spellReticle.ok .srMark{ width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: currentColor; }
.spellReticle.no .srMark::before, .spellReticle.no .srMark::after{
  content: ''; position: absolute; left: -9px; top: -1.5px; width: 18px; height: 3px; border-radius: 2px; background: currentColor; transform: rotate(45deg);
}
.spellReticle.no .srMark::after{ transform: rotate(-45deg); }
@media (prefers-reduced-motion: reduce){ .spellReticle{ transition: opacity 150ms ease; } }
