/* =====================================================================
   game.css — Haki-Arena recreation : 960x700 selection + battle
   Matches the haki-arena.site in-client look.
   ===================================================================== */
:root {
  --screen-w: 960px; --screen-h: 700px;
  --screen-w-num: 960; --screen-h-num: 700;   /* unitless, for scale() ratios */
  --face: 50px; --skill: 50px;
  --red: #e0241c; --red-d: #9e1812; --green: #4fa02e;
  --tan: #efe6cc; --tan-d: #d8c79c; --ink: #1a1a1a;
}

.stage { background: #d98e00; min-height: 100vh; padding: 16px 0 40px;
  font-family: "Trebuchet MS", Verdana, sans-serif; }
.stage .home-link { display: block; width: var(--screen-w); margin: 0 auto 8px; color: #3a2400;
  font-weight: bold; text-decoration: none; font-size: 12px; }
.screen {
  width: var(--screen-w); height: var(--screen-h); position: relative; overflow: hidden;
  margin: 0 auto; border: 2px solid #1e1e1e; box-shadow: 0 4px 18px #0007;
  background-size: cover; background-position: center; color: #111; font-size: 12px;
  user-select: none;
}

/* ---- standalone game window (opened from "Start Playing") ----
   The game screen fits-to-window: it scales DOWN uniformly so the whole
   design (960x700 select / 770x560 battle) is always visible even in a
   smaller window, and never scales UP past 1:1 native on its own. Both
   screens use this identical rule, so they are ALWAYS the same on-screen
   size — no exceptions.

   NA.applyFitScale() (js/app.js) reads the viewport and writes --fit-scale;
   it's read-only (never resizes the window itself, so there's no feedback
   loop). It's re-run on the window's "resize" event. Browser zoom (Ctrl +/-,
   Ctrl+scroll, pinch) also fires "resize", so applyFitScale specifically
   compares PHYSICAL pixel size (innerWidth * devicePixelRatio) rather than
   raw CSS pixels — zoom changes those two in lockstep so physical size stays
   put, and only a genuine window resize moves it. This is what lets the
   person zoom in or out as much as they want without the game fighting them
   back to its old size. */
body.game-window { background: #1a1a1a; margin: 0; overflow: auto; }
body.game-window .stage { height: 100vh; width: 100vw; min-height: 0; padding: 0;
  display: flex; align-items: center; justify-content: center; overflow: auto; }
body.game-window .stage .home-link { display: none; }
body.game-window .screen {
  position: relative; left: auto; top: auto; margin: 0; flex: none;
  border: none; box-shadow: none;
  /* scale is set by NA.applyFitScale() which reads the viewport and writes
     --fit-scale (read-only: it never resizes the window, so no feedback loop
     like the old bug). Defaults to 1 until JS runs. */
  transform: scale(var(--fit-scale, 1));
  transform-origin: center center;
}
body.game-window .log { display: none; }

/* chakra squares */
.ck-row { display: flex !important; justify-content: space-between; align-items: center;
  width: 193px; margin: 4px auto 0; box-sizing: border-box; }
.ck-item { display: inline-flex; align-items: center; gap: 3px; flex: none; }
.ck-sq { display: inline-block; width: 10px; height: 10px; border: 1px solid #000; flex: none; }
/* Strength / Weapon / Devil Fruit / Concentration / Random */
.ck-sq.t { background: #7f047f; } .ck-sq.n { background: #0cff00; }
.ck-sq.g { background: #f12529; } .ck-sq.b { background: #fc6527; } .ck-sq.r { background: #888; }
.ck-t { font-weight: bold; }
/* reference: "x N" labels are 14px REGULAR black on a 41px pitch */
.ck-n { font-size: 14px; color: #000; font-weight: 400 !important; }

/* =====================================================================
   SELECTION / LOBBY  (960x700 client — matches reference screenshots)
   ===================================================================== */
/* Both screens now share one native size, so the game window can be a
   fixed 770x560. Geometry below is measured from the reference client at
   the same stage size, so positions transfer 1:1. */
#select.screen { width: 770px; height: 560px; }

/* ---- top bar : language (left) + volume (right) ---- */
/* reference: toggle 37x18 at (106,6) with two 12x7 flags at x=111 and x=149 */
.s-lang { position: absolute; top: 6px; left: 106px; display: flex; align-items: center;
  justify-content: space-between; box-sizing: border-box;
  width: 37px; gap: 0; height: 18px; padding: 0 5px; border-radius: 9px;
  background: linear-gradient(#243a5c, #16243c); border: 1px solid #4a6a9a;
  box-shadow: 0 1px 3px #0006; }
.s-lang .flag { width: 12px; height: 7px; border-radius: 1px; cursor: pointer;
  box-shadow: 0 0 0 1px #0007; position: relative; overflow: hidden; opacity: .55; }
.s-lang .flag.active { opacity: 1; box-shadow: 0 0 0 1px #ffe07a; }
.flag.us { background: repeating-linear-gradient(#b22234 0 2px, #fff 2px 4px); }
.flag.us::before { content: ""; position: absolute; left: 0; top: 0; width: 9px; height: 9px;
  background: #3c3b6e; }
.flag.br { background: #169b46; }
.flag.br::before { content: ""; position: absolute; left: 50%; top: 50%; width: 13px; height: 13px;
  background: #ffd000; transform: translate(-50%, -50%) rotate(45deg); }
.flag.br::after { content: ""; position: absolute; left: 50%; top: 50%; width: 6px; height: 6px;
  background: #1d3f8a; border-radius: 50%; transform: translate(-50%, -50%); }


/* reference volume cluster: 11x11 minus @685, 36x11 slider @697,
   11x11 plus @737, speaker 13x13 @749 — all on y=8 */
.s-vol { position: absolute; top: 8px; left: 685px; right: auto; display: flex;
  align-items: center; justify-content: space-between; box-sizing: border-box;
  width: 77px; gap: 0; height: 13px; color: #f3ead2; user-select: none; }
.s-vol .vb { cursor: pointer; font-size: 11px; line-height: 1; width: 11px; text-align: center;
  text-shadow: 0 1px 2px #000; }
.s-vol .vb:hover { color: #ffd24a; }
.s-vol .wedge { width: 46px; height: 14px; background: #6b6b6b; position: relative;
  clip-path: polygon(0 100%, 100% 0, 100% 100%); cursor: pointer; }
.s-vol .wedge .vf { position: absolute; left: 0; top: 0; bottom: 0; background: #f1f1f1; }
.s-vol .spk { cursor: pointer; font-size: 15px; text-shadow: 0 1px 2px #000; }
.s-vol .spk.muted { opacity: .45; }

/* ---- game-mode buttons ---- */
/* Reference row: y=255, four buttons at x=23/152/358/563. Anchored left at
   23 with a fixed gap so the row spans 23..755 and never exceeds 770. */
/* Reference row: LOGOUT 118x57 @x23, then 192x57 at x=152/358/563, y=255 */
.s-modes { position: absolute; top: 255px; left: 0; right: 0; height: 57px; }
.s-mode { position: absolute; top: 0; display: inline-flex; align-items: center;
  height: 57px; width: 192px; justify-content: center;
  padding: 0 26px 0 10px; cursor: pointer; text-decoration: none; font-weight: bold;
  font-size: 12px; letter-spacing: .2px; color: #3a2a10; overflow: hidden;
  background: linear-gradient(#f7efdc, #d9c38a); border: 1px solid #7a6128;
  border-radius: 21px; box-shadow: 0 2px 6px #0006, inset 0 1px 0 #fff8; white-space: nowrap; }
.s-mode:hover { filter: brightness(1.05); color: #3a2a10; }
.s-mode:nth-of-type(1) { left: 23px;  width: 118px; }
.s-mode:nth-of-type(2) { left: 152px; }
.s-mode:nth-of-type(3) { left: 358px; }
.s-mode:nth-of-type(4) { left: 563px; }
.s-mode[disabled] { opacity: .5; cursor: not-allowed; filter: grayscale(.3); }
.s-mode .fan { position: absolute; right: 3px; top: 50%; transform: translateY(-50%);
  width: 26px; height: 26px; border-radius: 50%; background: #15233f;
  border: 2px solid #f4ecd6; box-shadow: 0 1px 4px #0007;
  display: flex; align-items: center; justify-content: center; }
.s-mode .fan img { width: 16px; height: 16px; }

/* ---- character detail panel (shown when a character is clicked) ---- */
/* Character detail = an unrolling scroll. The rod (ScrollSmall.png, kept at
   its 46:239 ratio) starts in the middle; on open it slides LEFT while the
   parchment (Rectangle.png) unrolls out from it. Clicking the rod rolls it
   back up and closes the box. No CSS background — the art is everything. */
.s-detail { position: absolute; left: 105px; top: 30px; width: 750px; height: 268px;
  display: none; z-index: 8; }
.s-detail.show { display: block; }
.s-detail .paper { position: absolute; left: 0; right: 38px; top: 6px; bottom: 6px;
  background: url(../assets/placeholder/Rectangle.png) no-repeat; background-size: 100% 100%;
  clip-path: inset(0 47% 0 53%); transition: clip-path 1.35s ease; }
.s-detail.open .paper { clip-path: inset(0 0 0 0); }
.s-detail .rod { position: absolute; top: -6px; width: 55px; height: 284px;   /* 284/55 = the art's ratio */
  left: calc(50% - 27px); transition: left 1.35s ease; cursor: pointer; z-index: 3;
  filter: drop-shadow(2px 3px 4px #0006); }
.s-detail.open .rod { left: calc(100% - 55px); }
.s-detail .rod img { width: 100%; height: 100%; }
.s-detail .rod:hover { filter: drop-shadow(2px 3px 4px #0006) brightness(1.08); }
.s-detail.instant .paper, .s-detail.instant .rod { transition: none; }
.s-detail .d-inner { position: absolute; left: 34px; right: 72px; top: 24px; bottom: 20px;
  opacity: 0; transition: opacity .45s ease .9s; overflow: hidden; }
.s-detail.open .d-inner { opacity: 1; }
.s-detail .close { position: absolute; top: 0; right: 0; cursor: pointer; color: #9a3a1a;
  font-weight: bold; font-size: 16px; line-height: 1; z-index: 2; }
.s-detail .close:hover { color: #bd2511; }
/* Top row: the character's face then its skill icons, every tile the same
   size and every tile with the same 1px black border, so they line up
   exactly along both their top and bottom edges. */
.s-detail .d-row { display: flex; gap: 14px; align-items: flex-end; }
.s-detail h4 { margin: 0 0 6px; color: #c01818; font-size: 15px; letter-spacing: .4px; }
.s-detail .d-face, .s-detail .d-port, .s-detail .d-skill {
  width: 86px; height: 86px; border: 1px solid #000; background: #cfc4a4;
  flex: none; box-sizing: border-box; overflow: hidden; }
.s-detail .d-face img, .s-detail .d-skill img, .s-detail .d-port img,
.s-detail .d-face .sprite, .s-detail .d-port .sprite,
.s-detail .d-skill .sprite { width: 100%; height: 100%; display: block; }
.s-detail .d-skills { display: flex; gap: 14px; align-items: flex-end; }
.s-detail .d-skill, .s-detail .d-face { cursor: pointer; }
.s-detail .d-skill:hover, .s-detail .d-face:hover { outline: 2px solid #e0241c; outline-offset: -1px; }
.s-detail .d-skill.sel, .s-detail .d-face.sel { outline: 2px solid #e0241c; outline-offset: -1px;
  box-shadow: 0 0 0 3px #e0241c44; }

/* Lower half: title on the left with the energy cost pinned to the right of
   the same line, then the description, then CLASSES left / COOLDOWN right. */
.s-detail .d-bottom { display: flex; gap: 18px; align-items: flex-start; margin-top: 10px; }
.s-detail .d-bio { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.s-detail .d-titlerow { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.s-detail .d-titlerow h4 { margin: 0; }
.s-detail .d-bio p { margin: 4px 0 0; color: #5a3214; font-weight: bold; font-size: 12px;
  line-height: 1.45; text-transform: uppercase; }
.s-detail .d-meta { margin-top: auto; padding-top: 8px; display: flex;
  justify-content: space-between; align-items: baseline; gap: 16px;
  font-size: 10px; font-weight: bold; color: #6b3a1a; text-transform: uppercase; }
.s-detail .d-cost { display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; font-weight: bold; color: #6b3a1a; text-transform: uppercase;
  white-space: nowrap; }
.s-detail .d-cost .ck-sq { width: 10px; height: 10px; border: 1px solid #000; }
.s-detail .d-cd { white-space: nowrap; }

/* ---- selection entrance animation ----
   The character panel unrolls open the same way the description scroll
   does, and the profile block fades up just behind it. Plays once, on the
   first draw of the selection screen only. Uses the same easing and a
   comparable duration to the detail scroll so the two feel related. */
@keyframes s-unroll {
  from { clip-path: inset(0 50% 0 50%); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes s-riseIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.s-panel.entering { animation: s-unroll 1.1s ease both; }
.s-info.entering  { animation: s-riseIn .55s ease .75s both; }
/* respect a reduced-motion preference rather than forcing the animation */
@media (prefers-reduced-motion: reduce) {
  .s-panel.entering, .s-info.entering { animation: none; }
}

/* ---- bottom panel : scroll + grid + footer + profile ---- */
/* the panel art (bg_charlist.png, 944x300) carries its own scroll rod and
   red frame — no CSS background/border on top of it. Content is padded to
   the parchment area measured in the art: x 62..926, y 17..283. */
.s-panel { position: absolute; left: 52px; top: 315px; width: 697px; height: 222px;
  background: url(../assets/placeholder/bg_charlist.png) no-repeat; background-size: 100% 100%;
  padding: 0; overflow: visible; }

/* Reference arrows are 41x44; the "previous" arrow rides the scroll rod at
   x=50, LEFT of the panel, so these are positioned against the screen
   rather than the panel (which would clip them). */
.s-page { position: absolute; width: 41px; height: 44px; cursor: pointer; z-index: 8;
  background: url(../assets/placeholder/Arrow.png) center/contain no-repeat; }
/* prev arrow rides ON the scroll rod (left of the grid, level with the
   top row), barely touching the first face; next arrow hangs off the
   bottom-right face's outer edge, pointing out of the grid */
/* panel-relative: the panel origin is (54,317), so these land at stage
   (50,332) and (505,468) — the "prev" arrow rides the rod just outside the
   panel's left edge, which is why the panel must not clip. */
.s-page.up   { left: -4px;  top: 15px; transform: scaleX(-1); }
.s-page.down { left: 451px; top: 151px; }
.s-page.off  { cursor: default; }
.s-page:not(.off):hover { filter: drop-shadow(0 0 3px #fff) brightness(1.05); }

/* left box: the character list. It fills the space left of the player
   details and centers the grid + footer inside it (both axes). */
.s-mid { position: static; }
/* 7 x 3 of 50x50. Reference column pitch is 61 (50 + 11 gap) and row
   pitch 60 (50 + 10 gap). */
.s-grid { position: absolute; left: 35px; top: 25px;
  display: grid; grid-template-columns: repeat(7, 50px); grid-auto-rows: 50px;
  column-gap: 11px; row-gap: 10px; }
/* Every tile carries a loading placeholder behind its art and fades the
   real image in over 0.35s, so a slow or failed CDN fetch reads as
   "loading" rather than a blank hole. Art is moving to imgur, so this
   matters. */
.s-cell { width: 50px; height: 50px; border: 1px solid #000; background: #d8cba6;
  background-image: url("../assets/placeholder/img_loading.png");
  background-size: 24px 24px; background-position: center; background-repeat: no-repeat;
  cursor: pointer; position: relative; overflow: hidden; }
.s-cell img, .s-cell .sprite { width: 100%; height: 100%; display: block;
  animation: s-fadein .35s ease both; }
@keyframes s-fadein { from { opacity: 0; } to { opacity: 1; } }
.s-cell:hover { outline: 2px solid #e0241c; outline-offset: -1px; z-index: 2; }
.s-cell.locked { filter: grayscale(1) brightness(.55); cursor: not-allowed; }
.s-cell.locked:hover { outline: none; }
.s-cell.picked { outline: 2px solid #2e8f2e; outline-offset: -1px; z-index: 2; }
.s-cell.picked::after { content: "\2714"; position: absolute; top: 0; right: 0; background: #2e8f2e;
  color: #fff; font-size: 9px; width: 13px; height: 13px; line-height: 13px; text-align: center; }
.s-cell.empty { background: #e7dcc0; cursor: default; }
.s-cell.empty:hover { outline: none; }

/* reference labels: 10px weight-700 in #591307; MISSIONS carries wider
   tracking (1.1px) than FILTER/STYLES (0.6px) */
.s-foot { position: absolute; left: 34px; top: 198px; width: 620px;
  display: flex; align-items: center; gap: 0; font-size: 10px; color: #591307;
  font-weight: 700; letter-spacing: .6px; }
.s-foot .lbl.mid { letter-spacing: 1.1px; }
/* !important here overrides a more specific rule elsewhere in the sheet;
   the reference values are 10px / 700 / #591307 and must win. */
.s-foot .lbl { position: absolute; height: 14px; line-height: 12px; text-align: center;
  font-size: 10px !important; font-weight: 700; color: #591307 !important;
  background: #f3e9cf; border: 1px solid #8a7a52; border-radius: 3px;
  padding: 3px 8px; font-weight: bold; font-size: 11px; color: #4a3414; cursor: pointer; letter-spacing: .3px; }
/* reference: FILTER 55px @x34, MISSIONS 115px @x186, STYLES 55px @x397
   (panel-relative), all 14px tall on one row */
.s-foot .lbl:nth-of-type(1) { left: 0;    width: 55px; }
.s-foot .lbl.mid            { left: 152px; width: 115px; }
.s-foot .lbl:nth-of-type(3) { left: 363px; width: 55px; }
/* one line, always — a wrapped label spills out of the panel */
.s-foot .lbl { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.s-foot .lbl:hover { color: #bd2511; border-color: #bd2511; }


/* right box: the player details. A fixed-width column, centered
   vertically in the parchment and with every section centered in it. */
.s-info { position: absolute; left: 487px; top: 26px; width: 210px; height: 100px;
  overflow: visible; display: flex; flex-direction: column;
  justify-content: center; align-items: center; text-align: center; }
.s-id { display: flex; gap: 12px; text-align: left; }
/* 75x75 including its 1px black border (box-sizing is border-box globally) */
.s-id .av { width: 77px; height: 77px; position: relative; flex: none;
  background: #cfc4a4; border: 1px solid #000; }
.s-id .av img { width: 100%; height: 100%; display: block; }
/* reference: 12px REGULAR (not bold), black, 16px line pitch */
.s-id .lines { font-size: 12px; line-height: 16px; color: #000; font-weight: 400; }
.s-id .lines .nm { font-size: 12px; letter-spacing: normal; font-weight: 400; }
.s-id .lines .rankline { display: flex; align-items: center; }

/* reference team row: panel-relative (447,128), slots 56x56 on a 66px pitch */
/* selection team slots: 50x50 on a 61px pitch, panel-rel (487,128)
   -> info-relative (0,102). The 56x56 figure belonged to the battle panel. */
.s-team { position: absolute; left: 0; top: 102px; width: 200px;
  display: flex; flex-direction: column; align-items: flex-start; margin: 0; }
.s-team .slots { display: flex; gap: 11px; justify-content: flex-start; }
.s-team .slot { width: 50px; height: 50px; border: 1px solid #000; background: #d8cba6;
  cursor: pointer; overflow: hidden; }
.s-team .slot img, .s-team .slot .sprite { width: 100%; height: 100%; display: block; pointer-events: none; }
.s-team .slot.empty { background: #e7dcc0; cursor: default; display: flex;
  align-items: center; justify-content: center; color: #a99d7d;
  font-weight: bold; font-size: 26px; }        /* empty spot keeps its number */
.s-team .slots.drop-ok { outline: 2px dashed #2e8f2e; outline-offset: 3px; border-radius: 4px; }
.s-cell img { pointer-events: none; }
.s-grid.drop-ok { outline: 2px dashed #c9302c; outline-offset: 2px; border-radius: 4px; }
.s-ready { position: absolute; left: -42px; top: 35px; width: 210px; text-align: center;
  font-weight: bold; color: #000; font-size: 12px; margin: 0; letter-spacing: normal;
  width: 100%; box-sizing: border-box; text-align: center; white-space: nowrap; }
.s-ready.no { color: #2a2010; }
.s-ready .drag { color: #e0241c; }
.btn-tm { position: absolute; left: 23px; top: 56px; width: 84px; height: 14px; line-height: 12px; margin: 0;
  font-size: 8px !important; font-weight: 700; color: #591307 !important; padding: 0; background: linear-gradient(#e64a3a, #cf1d1d);
  color: #fff; border: 1px solid #8a1410; font-weight: bold; text-align: center;
  padding: 5px 0; cursor: pointer; border-radius: 3px; font-size: 12px; letter-spacing: .5px; }
.btn-tm:hover { filter: brightness(1.08); }
/* =====================================================================
   BATTLE  (770x560 native client)
   ===================================================================== */
#battle.screen { width: 770px; height: 560px; font-family: "Trebuchet MS", Verdana, sans-serif; }

/* ---- top bar : players + ready/timer bar + chakra + exchange ---- */
.b-top { position: absolute; top: 0; left: 0; right: 0; height: 66px; z-index: 8; }
/* the ready/timer bar is dead-center; both player boxes are anchored to the
   center line at the same distance, so they mirror each other exactly */
/* Reference top bar: avatars 50x50 at x=223 (mine) and x=506 (enemy), both
   at y=9; name baseline y=22 at 20px, rank y=43 at 16px. Names sit on the
   OUTSIDE, avatars toward the centre. */
.b-player { position: absolute; top: 9px; display: flex; gap: 8px; align-items: flex-start; cursor: pointer; }
/* avatars sit toward the CENTER, 20px from the timer bar (bar spans
   289.5..480.5); names/ranks on the OUTSIDE. p1: [name][avatar->269.5];
   p2: [500.5<-avatar][name]. */
.b-player.p1 { left: 8px; width: 263px; justify-content: flex-end; overflow: hidden; }
.b-player.p2 { left: 506px; width: 262px; overflow: hidden; }
.b-player img.av { width: 50px; height: 50px; border: 1px solid #1a1a1a; background: #cfc4a4;
  box-shadow: 0 1px 3px #0007; flex: none; }
.b-player .txt { padding-top: 13px; display: inline-flex; flex-direction: column; flex: none;
  width: auto; }
.b-player.p1 .txt { align-items: flex-end; }    /* name+rank right edges 9px from avatar */
.b-player.p2 .txt { align-items: flex-start; }
.b-player .nm { color: #bd262c; font-weight: bold; font-size: 20px; letter-spacing: .3px; line-height: 1;
  text-shadow: 1px 1px 0 #f5eed8, -1px -1px 0 #f5eed8, 1px -1px 0 #f5eed8, -1px 1px 0 #f5eed8; }
.b-player .rk { color: #151311; font-weight: bold; font-size: 16px; letter-spacing: .3px; line-height: 1;
  margin-top: 7px; text-shadow: 1px 1px 0 #f5eed8aa; }
.b-player:hover .nm { color: #ff544a; }

.b-center { position: absolute; left: 290px; top: 10px; transform: none; width: 200px;
  text-align: center; }
.b-ready { display: block; cursor: pointer; text-decoration: none; }
.b-ready .label { font-weight: normal; font-size: 16px; letter-spacing: .3px; color: #151311;
  text-align: center; line-height: 18px; }
.b-ready.mine .label { font-weight: bold; }   /* PRESS WHEN READY is bold; OPPONENT TURN is not */
.b-ready .bar { width: 193px; height: 12px; margin: 0 auto; background: #ffffff; border: 1px solid #000000;
  overflow: hidden; position: relative; }
.b-ready .bar .fill { position: absolute; left: 0; top: 0; bottom: 0; width: 100%;
  background: #ba1921; }
.b-ready .bar .fill.smooth { transition: width 1.5s linear; }
.b-ready[disabled] { cursor: default; }
.b-chakra { margin-top: 4px; }
.b-chakra .ck-n { text-shadow: 1px 1px 0 #f5eed8; font-weight: bold; }
.b-exchange { display: inline-block; margin-top: 4px; font-size: 12px; font-weight: 400;
  color: #151311; letter-spacing: .4px; cursor: pointer; text-shadow: 1px 1px 0 #f5eed8; }
.b-exchange:hover { color: #bd2511; text-decoration: underline; }
.b-exchange.off { opacity: .45; cursor: default; text-decoration: none; }

/* ---- team columns ---- */
/* Row rhythm taken from the reference: skill-bar tops at 87/208/329
   (121px pitch). Face sits 24px above its bar, health bar 55px below it,
   status icons 19px above it. */
.b-col { position: absolute; top: 63px; bottom: 0; width: 140px; }
.b-col.ally { left: 0; }
.b-col.foe  { right: 0; }

.b-unit { position: absolute; width: 134px; height: 152px; z-index: 6; }  /* above the skill scroll */
.b-unit.r0 { top: 0; } .b-unit.r1 { top: 121px; } .b-unit.r2 { top: 242px; }
/* Rank "hat" (110x140): rests over the head, 2px in from the unit's outer
   side margin, positioned like the screenshot (angled over the top-left of
   the face). The PNG's own transparency controls what shows. z-index above
   the portrait so it overlaps the top of the head. */
/* Rank "hat" (110x140): its BOTTOM edge ends 17px below the health bar's
   bottom (with border). hp bottom = 116 (rel to unit) -> hat bottom = 133 ->
   hat top = 133 - 140 = -7. Positioned 2px in from the unit's side margin. */
.b-unit .deco { position: absolute; top: -5px; width: 110px; height: 140px;
  pointer-events: none; z-index: 7; object-fit: contain; object-position: top; }
.b-col.ally .deco { left: 2px; }
.b-col.foe .deco { right: 2px; transform: scaleX(-1); }

/* Face picture: 75x75 + 1px border = 77x77 */
.b-portrait { position: absolute; top: 0; width: 77px; height: 77px; border: 1px solid #101010;
  background: #cfc4a4; box-shadow: 0 2px 5px #0007; overflow: hidden; }
.b-col.ally .b-portrait { left: 32px; } .b-col.foe .b-portrait { right: 34px; }
.b-portrait img, .b-portrait .sprite { width: 100%; height: 100%; display: block; }
.b-unit.dead .b-portrait { filter: none; }
.b-portrait .death-x { width: 100%; height: 100%; display: block; object-fit: cover;
  image-rendering: auto; }
.b-unit.dimmed { filter: sepia(.55) brightness(.92); }
@keyframes na-blink { 0%, 100% { opacity: .5; } 50% { opacity: .22; } }
.b-unit.targetable { cursor: pointer; }
/* Reference marks valid targets with a FLAT gold wash across the whole
   portrait — no outline, no pulse. It reads instantly across the board,
   which is the point: you see every legal target without scanning. */
.b-unit.targetable .b-portrait::after { content: ""; position: absolute; inset: 0;
  background: #ffd400; opacity: .55; pointer-events: none; mix-blend-mode: multiply; }
.b-unit.targetable:hover .b-portrait::after { opacity: .72; }
.b-portrait:hover { outline: 2px solid #ffd400; outline-offset: 1px; cursor: pointer; }

/* Health bar: 75x14 + 1px border, 2px gap below the face picture (border to
   border). Face box is 77 tall at top 23 -> bottom at 100; +2 gap => top 102. */
.b-hp { position: absolute; top: 79px; width: 77px; height: 16px; background: #101010;
  border: 1px solid #101010; box-shadow: 0 1px 3px #0006; }
.b-col.ally .b-hp { left: 32px; } .b-col.foe .b-hp { right: 34px; }
.b-hp .fill { position: absolute; left: 0; top: 0; bottom: 0;
  background: linear-gradient(#8ee24a, #4fa02e); }
.b-hp .fill.mid { background: linear-gradient(#f2b02a, #cf8410); }
.b-hp .fill.low { background: linear-gradient(#e84030, #a81c12); }
.b-hp .txt { position: relative; z-index: 2; font-size: 12px; font-weight: 400; color: #151311;
  text-align: center; line-height: 14px; }
.b-hp .def { position: absolute; top: -7px; right: -3px; background: #3f7fcf; color: #faf4e1;
  font-size: 9px; font-weight: bold; padding: 0 3px; border-radius: 2px; z-index: 3; }

/* Effect / status icons: 20x20 (no border), sitting NEXT TO the face picture
   with a 5px gap, and 2px above the skill bar. Skill bar top is 131 (see
   below), so the icon row bottom = 129, top = 109. */
.b-minis { position: absolute; top: 5px; display: flex; gap: 3px; z-index: 6;
  pointer-events: none; }
.b-minis .mi { pointer-events: auto; }   /* keep the hover tooltips */
.b-col.ally .b-minis { left: 118px; }
.b-col.foe .b-minis { right: 118px; flex-direction: row-reverse; }
.b-minis .mi { width: 22px; height: 22px; background: #cfc4a4; overflow: hidden;
  border: 1px solid #000; box-sizing: border-box; box-shadow: 0 1px 2px #0007; }
.b-minis .mi img, .b-minis .mi .sprite { width: 100%; height: 100%; display: block; }
.b-minis .mi.fx { display: flex; align-items: center; justify-content: center; color: #faf4e1;
  font-size: 7px; font-weight: bold; }
.mi.fx.stun { background: #b02018; } .mi.fx.invuln { background: #2f6fb0; } .mi.fx.reduce { background: #2f7d4e; }
.mi.fx.dot { background: #7a2f9a; } .mi.fx.hot { background: #2f8a85; } .mi.fx.counter { background: #9a7320; }
.mi.fx.boost { background: #b0531e; } .mi.fx.weaken { background: #6b6048; }

/* ---- red skill scrolls (allies) ----
   324x81 bar. It slides 27px UNDER the face picture on the left (the portrait
   paints on top, see z-index) via the left padding. Its top sits 13px below
   the health bar's bottom (hp bottom = 118 -> skill bar top = 131). */
/* Constant 381x79 bar at x=26 for BOTH turns — the reference does not
   resize it when the leading slot is hidden. */
.b-scroll { position: absolute; left: 26px; width: 381px; height: 79px; z-index: 5; box-sizing: border-box;
  display: flex; gap: 6px; align-items: center;
  background: linear-gradient(#e6382a, #b31408); border: 2px solid #6e0c05; border-radius: 5px;
  box-shadow: inset 0 0 0 2px #f0a08c55, 0 2px 6px #0007; }
/* my turn: 400px wide, the "?" slot at 44px from the bar's left edge, then a
   20px gap to the first skill. Enemy turn: 324px wide (left edge FIXED so the
   bar shortens from the RIGHT), no "?", first skill at 43px. */
/* "?" slot starts 22px into the bar (x=48); the first skill starts at
   x=124, i.e. 20px past the slot. On the enemy turn the slot is hidden and
   the skills keep their positions, so the row never shifts. */
.b-scroll:not(.busy) { padding: 0 8px 0 20px; }
.b-scroll.busy { padding: 0 8px 0 96px; }
/* Q10 anchoring: bar top = face top + 23. Face tops (screen) = 80/202/324
   (Q8: first row 80px from top margin, 45px face-bottom to next face-top,
   pitch = 77+45 = 122). */
.b-scroll.s0 { top: 87px; } .b-scroll.s1 { top: 208px; } .b-scroll.s2 { top: 329px; }
.b-scroll::before, .b-scroll::after { content: ""; position: absolute; top: -6px; bottom: -6px;
  width: 10px; background: linear-gradient(#8d1206, #5c0a03); border: 1px solid #3c0501; border-radius: 4px; }
.b-scroll::before { left: -8px; } .b-scroll::after { right: -8px; }
.b-scroll .knob { position: absolute; right: -16px; top: 50%; transform: translateY(-50%);
  width: 9px; height: 14px; background: linear-gradient(#a8968a, #6d5c50);
  border: 1px solid #3a2c22; border-radius: 2px; }
.b-scroll.busy { filter: sepia(.5) saturate(.55) brightness(.9); }
.b-scroll.dimmed { filter: sepia(.65) brightness(.85); }

.b-skill { width: 56px; height: 56px; border: 2px solid #101010; background: #e7dab8;
  position: relative; cursor: pointer; flex: none; box-sizing: border-box; }
.b-skill img, .b-skill .sprite { width: 100%; height: 100%; display: block; }
.b-skill.q { background: #4a4a4a; margin-right: 14px; /* 6 flex gap + 14 = 20 */ display: flex; align-items: center; justify-content: center;
  color: #e6e6e6; font-weight: bold; font-size: 26px; cursor: default; }
/* A skill you cannot pay for reads as dead BEFORE you click it: heavily
   desaturated and dimmed, so the energy pool's constraint is legible at a
   glance across all twelve tiles. */
.b-skill.unaffordable img, .b-skill.cooldown img,
.b-skill.unaffordable .sprite, .b-skill.cooldown .sprite {
  opacity: .3; filter: grayscale(1) brightness(.65); }
.b-skill.unaffordable { border-color: #4a4034; background: #bdb298; }
.b-skill.unaffordable, .b-skill.cooldown { cursor: pointer; }   /* still clickable for info */
/* the armed skill keeps pulsing yellow — slowly — until a target is picked
   or it is clicked again */
/* The armed skill LIGHTS UP rather than just gaining an outline: a glow
   overlay sits on the tile and pulses, which reads instantly across the
   board the way the reference client's does. */
.b-skill.selected { border-color: #ffd400; box-shadow: 0 0 0 3px #ffd400ee; }
/* No glow on the armed tile: the reference puts all the emphasis on the
   TARGETS instead, so a competing glow here would fight it. A plain border
   is enough to show which skill is held. */
@keyframes na-armed { 0%, 100% { box-shadow: 0 0 0 3px #ffd400ee, 0 0 14px 2px #ffd40088; }
  50% { box-shadow: 0 0 0 3px #ffd40055, 0 0 8px 1px #ffd40033; } }

/* the "?" slot once a target is chosen: shows the queued skill; click it to
   cancel the action and pick another skill */
.b-skill.q.filled { background: #e7dab8; cursor: pointer; font-size: 0;
  border-color: #37e037; box-shadow: 0 0 0 2px #37e037aa; }
.b-skill.q.filled:hover { border-color: #e0241c; box-shadow: 0 0 0 2px #e0241caa; }
/* the gap a skill leaves behind once it moves up to the leading slot:
   keeps the row's spacing but reads as clearly empty */
.b-skill.vacated { background: #00000026; border: 2px dashed #6e0c05aa;
  cursor: default; pointer-events: none; }
.b-skill.denied { animation: na-deny .35s; }
@keyframes na-deny { 50% { box-shadow: 0 0 0 3px #e0241c; border-color: #e0241c; } }
.b-skill.queued { border-color: #37e037; box-shadow: 0 0 0 2px #37e037aa; }
.b-skill:hover { border-color: #ffe680; }
/* Cooldown is a LARGE centred numeral over a dimmed tile — legible at a
   glance from across the board, rather than a small corner badge. */
.b-skill .cd { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 34px; font-weight: bold; line-height: 1; color: #f4f4f4; background: #0009;
  text-shadow: 0 2px 4px #000, 0 0 2px #000; letter-spacing: -1px; }

/* "Click on a skill" block inside the bottom info panel (character view),
   reused on the skill view to swap skills / go back to the character */
.b-info .inspect { flex: none; align-self: center; width: 200px; }
.b-info .inspect .cap { background: #101010; color: #faf4e1; font-weight: bold; font-size: 11px;
  text-align: center; padding: 3px 0; letter-spacing: .3px; text-transform: uppercase; }
.b-info .inspect .cap.link { cursor: pointer; }
.b-info .inspect .cap.link:hover { color: #ffd400; }
.b-info .inspect .row { display: flex; gap: 4px; margin-top: 4px; justify-content: center; }
.b-info .inspect .row .b-skill { width: 42px; height: 42px; }
.b-info .inspect .row .b-skill.sel { border-color: #e0241c; box-shadow: 0 0 0 2px #e0241caa; }

/* ---- bottom area ---- */
.b-bottom { position: absolute; left: 0; right: 0; bottom: 0; height: 162px; z-index: 10; }
.b-announcer { position: absolute; left: 125px; bottom: 0; width: 150px; height: 130px;
  object-fit: contain; object-position: bottom; pointer-events: none; z-index: 12; }

/* Q11 staircase, all measured from the left margin, stacked bottom-to-top
   with 2px gaps: volume strip (bottom) left 7 / bottom 0; OPEN CHAT left 30 /
   bottom 29 (27 vol + 2); SURRENDER left 54 / bottom 77 (29 + 46 + 2). */
.bb-btns { position: absolute; inset: 0; z-index: 11; pointer-events: none; }
.bb-btns > * { pointer-events: auto; }
.bb-btn { position: absolute; display: block; width: 200px; height: 62px; line-height: 60px;
  padding: 0 10px 0 24px; background: linear-gradient(#f6efdc, #e2d3a8);
  border: 1px solid #6e5a2a; color: #2c1e08; font-weight: bold; font-size: 12px; letter-spacing: .4px;
  cursor: pointer; box-shadow: 0 2px 4px #0007, inset 0 1px 0 #fff8; white-space: nowrap;
  box-sizing: border-box; font-size: 13px; font-weight: 400; color: #151311; }
/* reference staircase: SURRENDER (53,426), OPEN CHAT (30,468),
   volume (7,509) — each 200x62, stepping left and down */
.bb-btn.w1 { left: 53px; top: 28px; bottom: auto; }
.bb-btn.w2 { left: 30px; top: 70px; bottom: auto; }
.bb-btn::before { content: ""; position: absolute; left: -10px; top: 5px; width: 20px; height: 36px;
  background: linear-gradient(#4a9a2e, #2f6a1c); border: 2px solid #1e4a10; border-radius: 8px; }
.bb-btn:hover { filter: brightness(1.06); color: #bd2511; }
.bb-vol { position: absolute; left: 7px; top: 111px; bottom: auto; display: flex; align-items: center; gap: 8px; height: 27px; width: 150px;
  padding: 0 12px 0 26px; background: linear-gradient(#f6efdc, #e2d3a8); border: 1px solid #6e5a2a;
  box-shadow: 0 2px 4px #0007, inset 0 1px 0 #fff8; }
.bb-vol::before { content: ""; position: absolute; left: -10px; top: -5px; width: 20px; height: 36px;
  background: linear-gradient(#4a9a2e, #2f6a1c); border: 2px solid #1e4a10; border-radius: 8px; }
.bb-vol .vb { cursor: pointer; font-weight: bold; font-size: 15px; color: #2c1e08; }
.bb-vol .vb:hover { color: #bd2511; }
.bb-vol .wedge { width: 44px; height: 13px; background: #6b6b6b; position: relative;
  clip-path: polygon(0 100%, 100% 0, 100% 100%); cursor: pointer; }
.bb-vol .wedge .vf { position: absolute; left: 0; top: 0; bottom: 0; background: #2c1e08; }
.bb-vol .spk { cursor: pointer; font-size: 13px; }
.bb-vol .spk.muted { opacity: .4; }

/* info panel: skill details / character bio / player profile */
.b-info { position: absolute; left: 247px; top: 28px; width: 521px; height: 132px;
  background: linear-gradient(#f6eed6, #ecdfbc); border: 3px solid #8f1408; border-radius: 4px;
  box-shadow: 0 2px 8px #0007; padding: 8px 12px 8px 16px; overflow: hidden; }
.b-info::before { content: ""; position: absolute; left: -12px; top: -8px; bottom: -8px; width: 18px;
  background: linear-gradient(90deg, #2f6a1c, #4a9a2e 55%, #2f6a1c); border: 2px solid #1e4a10;
  border-radius: 8px; }
.b-info .wrap { display: flex; align-items: flex-start; gap: 10px; height: 100%;
  padding: 28px 0 0 31px; box-sizing: border-box; }
.b-info .pic { width: 78px; height: 78px; border: 2px solid #101010; background: #cfc4a4; flex: none; }
/* the player/clan avatar view specifically: 75x75, no frame at all */
.b-info .pic.av-pic { width: 75px; height: 75px; border: none; }
.b-info .av-media { display: flex; gap: 6px; flex: none; }
.b-info .pic img, .b-info .pic .sprite { width: 100%; height: 100%; display: block; }
.b-info .body { flex: 1; min-width: 0; position: relative; height: 100%; }
/* title at a FIXED position (top of the body), never moving with description
   length; red like everywhere else */
.b-info .ttl { color: #cb0400; font-weight: 400; font-size: 15px; letter-spacing: .2px;
  text-transform: uppercase; position: absolute; top: 0; left: 0; right: 74px; }
/* description: black body, starts below the fixed title, scrolls if too long */
.b-info .desc { position: absolute; top: 16px; left: 0; right: 8px; bottom: 20px;
  font-size: 9px; font-weight: bold; line-height: 1.45; color: #151311; text-transform: uppercase;
  overflow-y: auto; padding-right: 4px; }
.b-info .desc .hl { color: #d86a10; text-decoration: underline; }
.b-info .desc .hl.blue { color: #2f6fb0; }
.b-info .classes { position: absolute; bottom: 0; left: 0; right: 8px; font-size: 9px;
  color: #6b5a3a; font-weight: bold; text-transform: uppercase; letter-spacing: .3px; }
/* ENERGY cost, top-right corner (like the reference skill card) */
.b-info .corner { position: absolute; top: 7px; right: 12px; display: flex; gap: 4px;
  align-items: center; font-size: 9px; font-weight: bold; color: #151311; }
.b-info .corner .ck-sq { width: 11px; height: 11px; border: 1px solid #000; }
.b-info .cdline { position: absolute; bottom: 7px; right: 12px; font-size: 9px; font-weight: bold;
  color: #151311; text-transform: uppercase; }
/* player-profile lines (level/clan/rank etc.): 8px, black 151311, 6px row gap */
.b-info .lines { font-size: 8px; font-weight: bold; line-height: 1; color: #151311; }
.b-info .lines > * { margin-bottom: 6px; }
.b-info .lines > *:last-child { margin-bottom: 0; }
/* team view: 21px from the right, 10px gap between faces, vertically centered */
/* team faces: 56x56 with a 66px pitch, matching the reference row */
.b-info .team { position: absolute; left: 314px; top: 38px; display: flex; gap: 10px; }
.b-info .team img, .b-info .team .sprite { width: 56px; height: 56px; border: 1px solid #101010;
  background-color: #cfc4a4; cursor: pointer; }
.b-info .team img:hover, .b-info .team .sprite:hover { outline: 2px solid #ffd400; }

/* ---- modals : exchange chakra / chat / surrender (scroll dialogs) ---- */
.b-dim { position: absolute; inset: 0; z-index: 20; background: #0003; display: none; }
.b-dim.show { display: block; }
.b-dialog { position: absolute; left: 50%; top: 130px; transform: translateX(-50%); z-index: 21;
  width: 470px; min-height: 200px; background: linear-gradient(#f9f1dc, #f1e5c4);
  border: 3px solid #8f1408; border-radius: 3px; box-shadow: 0 6px 24px #000a;
  padding: 26px 34px 22px 96px; display: none; }
.b-dialog.show { display: block; }
.b-dialog .rod { position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 46px; height: 239px; filter: drop-shadow(2px 3px 4px #0006); }  /* ScrollSmall native ratio */
.b-dialog .rod img { width: 100%; height: 100%; }
.b-dialog h3 { margin: 0 0 14px; font-size: 14px; letter-spacing: .4px; color: #101010;
  text-align: center; text-transform: uppercase; }
.b-dialog h3 .num { color: #c01818; }
.b-dialog h3.sub { margin: 4px 0 10px; font-size: 12px; color: #3a2a10; }

/* end-turn skill queue: caster face + skill icon pairs, in casting order */
.b-dialog .q-row { display: flex; gap: 12px; justify-content: center; margin-bottom: 12px;
  min-height: 48px; flex-wrap: wrap; }
.b-dialog .q-pair { display: flex; cursor: grab; }
.b-dialog .q-pair.dragging { opacity: .4; }
.b-dialog .q-cell { width: 44px; height: 44px; border: 2px solid #101010; background: #cfc4a4;
  overflow: hidden; }
.b-dialog .q-pair .q-cell + .q-cell { border-left: none; }
.b-dialog .ex-col.wide { width: 240px; margin: 0 auto; }
.b-dialog .btnrow { display: flex; gap: 22px; justify-content: center; margin-top: 18px; }
.b-btn { display: inline-block; min-width: 96px; text-align: center; padding: 5px 12px;
  background: linear-gradient(#f8f1dd, #e6d7ae); border: 2px solid #101010; font-weight: bold;
  font-size: 13px; letter-spacing: 1px; cursor: pointer; text-transform: uppercase; color: #101010; }
.b-btn:hover { filter: brightness(1.05); color: #bd2511; }
.b-btn.off { opacity: .45; cursor: default; }
.b-btn.off:hover { color: #101010; filter: none; }

/* exchange dialog columns */
.ex-cols { display: flex; gap: 34px; }
.ex-col { flex: 1; }
.ex-col h4 { margin: 0 0 8px; font-size: 11px; letter-spacing: .4px; color: #101010; text-transform: uppercase; }
.ex-row { display: flex; align-items: center; gap: 6px; margin-bottom: 7px; font-size: 11px;
  font-weight: bold; color: #101010; text-transform: uppercase; }
.ex-row .ck-sq { width: 12px; height: 12px; flex: none; }
.ex-row .nmm { flex: 1; }
.ex-row .cnt { width: 16px; text-align: center; }
.ex-row .pm { width: 16px; height: 16px; line-height: 14px; text-align: center; border: 1px solid #101010;
  background: #f6efdc; cursor: pointer; font-weight: bold; user-select: none; }
.ex-row .pm:hover { color: #bd2511; }
.ex-row .pm.off { opacity: .35; cursor: default; }
.ex-row .pm.off:hover { color: #101010; }
.ex-skill { width: 44px; height: 44px; border: 2px solid #101010; margin-top: 6px; }
.ex-skill img { width: 100%; height: 100%; }

/* chat dialog */
.b-dialog.chat { width: 560px; padding-bottom: 16px; }
.chat-close { position: absolute; top: -40px; right: -6px; background: linear-gradient(#e6382a, #b31408);
  color: #faf4e1; border: 1px solid #6e0c05; font-weight: bold; font-size: 12px; letter-spacing: .5px;
  padding: 6px 14px; cursor: pointer; box-shadow: 0 2px 5px #0008; }
.chat-close:hover { filter: brightness(1.1); }
.chat-msgs { height: 190px; overflow-y: auto; display: flex; flex-direction: column; gap: 4px;
  font-size: 12px; color: #2a2010; padding: 4px 2px; }
.chat-msgs .empty { margin: auto; color: #c01818; font-weight: bold; font-size: 14px;
  letter-spacing: .4px; text-transform: uppercase; }
.chat-msgs .m b { color: #c01818; }
.chat-form { display: flex; gap: 6px; margin-top: 10px; }
.chat-form input { flex: 1; border: 2px solid #8f1408; background: #fdf8ea; padding: 7px 9px;
  font-size: 12px; font-family: inherit; color: #2a2010; }
.chat-form .cbtn { background: linear-gradient(#e6382a, #b31408); color: #faf4e1; border: 1px solid #6e0c05;
  font-weight: bold; font-size: 12px; padding: 0 13px; cursor: pointer; }
.chat-form .cbtn:hover { filter: brightness(1.1); }
.chat-form .cbtn.muted { filter: grayscale(.6); }

/* surrender dialog */
.b-dialog.sur { text-align: center; }
.b-dialog.sur .pic { width: 220px; height: 140px; border: 2px solid #101010; margin: 0 auto;
  background: #cfc4a4; }
.b-dialog.sur .pic img { width: 100%; height: 100%; display: block; }

/* ---- team manager : saved teams panel ---- */
.s-dim { position: absolute; inset: 0; background: #0005; z-index: 14; }
.s-tm { position: absolute; left: 150px; top: 130px; width: 660px; height: 380px; z-index: 15; }
.s-tm .rod { position: absolute; left: -24px; top: 50%; transform: translateY(-50%);
  width: 46px; height: 239px; z-index: 2; filter: drop-shadow(2px 3px 4px #0006); }
.s-tm .rod img { width: 100%; height: 100%; }
.s-tm .tm-inner { position: absolute; inset: 0;
  background: url(../assets/placeholder/Rectangle.png) no-repeat; background-size: 100% 100%;
  padding: 20px 40px 18px 48px; display: flex; flex-direction: column; }
.s-tm h4 { margin: 0 34px 8px 0; color: #c01818; font-size: 16px; letter-spacing: .5px; text-align: center; }
.s-tm .close { position: absolute; top: 12px; right: 22px; cursor: pointer; color: #9a3a1a;
  font-weight: bold; font-size: 18px; line-height: 1; z-index: 3; padding: 4px; }
.s-tm .close:hover { color: #bd2511; }
.s-tm .tm-saverow { display: flex; gap: 8px; margin-bottom: 8px; flex: none; }
.s-tm .tm-saverow input { flex: 1; border: 2px solid #8f1408; background: #fdf8ea;
  padding: 6px 9px; font-size: 12px; font-family: inherit; color: #2a2010; }
.tm-btn { background: linear-gradient(#e64a3a, #cf1d1d); color: #fff; border: 1px solid #8a1410;
  font-weight: bold; font-size: 11px; letter-spacing: .4px; padding: 6px 12px; cursor: pointer;
  border-radius: 3px; white-space: nowrap; align-self: center; }
.tm-btn:hover { filter: brightness(1.08); }
.tm-btn.off { opacity: .45; cursor: default; }
.tm-btn.off:hover { filter: none; }
.tm-btn.del { background: linear-gradient(#7d7d7d, #565656); border-color: #3a3a3a; }
.s-tm .tm-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.s-tm .tm-empty { margin: auto; color: #9a3a1a; font-weight: bold; font-size: 13px; letter-spacing: .4px; }
.s-tm .tm-row { display: flex; gap: 10px; align-items: center; background: #f2e9cdcc;
  border: 1px solid #c9b98c; border-radius: 3px; padding: 7px 10px; }
.s-tm .tm-row .tm-name { width: 170px; border: 1px solid #c9b98c; background: #fdf8ea;
  padding: 5px 8px; font-size: 12px; font-weight: bold; color: #2a2010; font-family: inherit; }
.s-tm .tm-row .tm-faces { display: flex; gap: 5px; flex: 1; }
.s-tm .tm-row .tm-faces .sprite { border: 1px solid #101010; }
.s-tm .tm-row .tm-faces .gone { width: 38px; height: 38px; border: 1px solid #101010;
  background: #d8cba6; display: flex; align-items: center; justify-content: center;
  font-weight: bold; color: #9a3a1a; }

/* sprite-sheet cells (see js/data.js SPRITE SHEETS) */
.sprite { background-repeat: no-repeat; flex: none; display: block;
  image-rendering: auto; pointer-events: none; }

/* tooltip + overlay (shared) */
.tip { position: fixed; z-index: 50; max-width: 240px; background: #1c130a; color: #f3e9d2;
  border: 1px solid var(--red); padding: 7px 9px; font-size: 11px; pointer-events: none; display: none; border-radius: 3px; }
.tip h5 { margin: 0 0 3px; color: #ffb070; font-size: 12px; }
.tip .meta { color: #c9b894; margin-bottom: 4px; }
/* effect-icon typewriter tooltip: a blinking cursor trails the typed text */
.tip.efftip .typed { white-space: pre-wrap; }
.tip.efftip .typed::after { content: "\2588"; margin-left: 1px; color: #ffb070;
  animation: na-caret .7s steps(1) infinite; }
@keyframes na-caret { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
.overlay { position: fixed; inset: 0; background: #000a; display: none; align-items: center; justify-content: center; z-index: 100; }
.overlay .card { background: var(--tan); border: 3px solid var(--red); padding: 22px 36px; text-align: center; border-radius: 4px; }
.overlay .card.result-card { width: 645px; max-width: 645px; height: 320px; box-sizing: border-box;
  position: relative; padding: 0; display: block; }
/* the win/lose art: 238x226, 80px from the left, vertically centered */
.overlay .card.result-card .result-pic { position: absolute; left: 80px; top: 50%;
  transform: translateY(-50%); width: 238px; height: 226px; object-fit: contain; }
/* text content sits to the right of the picture (picture ends at 80+238=318) */
.overlay .card.result-card > *:not(.result-pic) { margin-left: 340px; margin-right: 24px; }
.overlay .card.result-card h2 { padding-top: 34px; }
.overlay .blurb { font-size: 12px; font-weight: bold; margin: 4px 0 10px; line-height: 1.5; }
.overlay .notes-lbl { font-size: 11px; font-weight: bold; margin: 0 0 4px; text-align: left; }
.overlay .notes { margin: 0; padding-left: 18px; text-align: left; font-size: 10.5px; color: #444; line-height: 1.6; }
.overlay h2 { margin: 0 0 6px; font-size: 26px; }
.overlay h2.win { color: #2e8f2e; } .overlay h2.lose { color: var(--red); }
.overlay .btn { display: inline-block; background: var(--red); color: #faf4e1; border: 1px solid var(--red-d);
  padding: 5px 14px; font-weight: bold; border-radius: 3px; text-decoration: none; margin: 0 4px; }

.log { width: var(--screen-w); margin: 8px auto 0; height: 92px; overflow-y: auto; background: #faf4e1;
  border: 1px solid #bbb; padding: 5px 9px; font-size: 11px; color: #222; }
.log .turnsep { color: var(--red-d); font-weight: bold; margin-top: 3px; }

/* rank badge shown beside rank text (select / battle headers) */
.rank-ico { display: inline-block; width: 14px; height: 14px; margin-right: 4px; vertical-align: middle; }
.rankline { display: inline; }

/* =====================================================================
   OG-CLIENT JUICE: turn playback animations, sounds feedback, buttons
   ===================================================================== */

/* hp bars slide between values during playback */
.b-hp .fill { transition: width .5s ease; }

/* skill announcement banner over the battlefield while a skill resolves */
.b-announce { position: absolute; left: 50%; top: 76px; transform: translateX(-50%);
  z-index: 9; display: flex; align-items: center; gap: 8px; padding: 5px 12px;
  background: linear-gradient(#f6eed6, #ecdfbc); border: 2px solid #8f1408; border-radius: 4px;
  box-shadow: 0 3px 10px #0008; pointer-events: none;
  animation: na-announce .25s ease-out; }
.b-announce .cell { width: 44px; height: 44px; border: 2px solid #101010;
  background: #cfc4a4; overflow: hidden; }
.b-announce .txt { font-weight: bold; font-size: 12px; color: #101010;
  letter-spacing: .4px; max-width: 280px; }
@keyframes na-announce { from { opacity: 0; transform: translate(-50%, -8px) scale(.92); }
  to { opacity: 1; transform: translate(-50%, 0) scale(1); } }

/* no hit/heal flash or shake: the original has no extra visual effects */

/* floating damage / heal numbers over the face picture */
.floater { position: absolute; left: 51px; top: 40px; transform: translateX(-50%);
  z-index: 9; font-weight: bold; font-size: 19px; pointer-events: none; white-space: nowrap;
  text-shadow: 1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000;
  animation: na-float 1.05s ease-out forwards; }
.floater.bad { color: #ff4a3a; }
.floater.good { color: #5aff6a; }
@keyframes na-float { 0% { opacity: 0; transform: translate(-50%, 8px); }
  15% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%, -28px); } }

/* timer bar stays a plain solid color the whole time — no pulse or gradient */

/* buttons physically press down like the OG client */
.bb-btn:active, .b-btn:not(.off):active, .cbtn:active, .chat-close:active,
.b-ready:not([disabled]):active .label, .vb:active, .spk:active {
  transform: translateY(1px); filter: brightness(.93); }
.b-skill:not(.q):active, .b-skill.q.filled:active { transform: scale(.96); }
.b-exchange:not(.off):active { filter: brightness(.85); }

/* result card pops in */
.overlay .card { animation: na-card .35s ease-out; }
@keyframes na-card { from { transform: scale(.72); opacity: 0; }
  to { transform: scale(1); opacity: 1; } }

/* ---- OPPONENT FOUND interstitial ----
   Sits over the selection screen between "searching" and the battle board
   loading, so the transition reads as one continuous sequence. */
.s-found-wrap { position: absolute; inset: 0; z-index: 40; display: flex;
  align-items: center; justify-content: center; background: #0007; }
.s-found { width: 320px; padding: 18px 20px 22px; text-align: center;
  background: linear-gradient(#f6efdc, #e6d7ae); border: 3px solid #b31408;
  box-shadow: 0 6px 24px #000a, inset 0 0 0 2px #f0a08c55;
  animation: s-found-in .35s ease both; }
.s-found h3 { margin: 0 0 10px; color: #bd262c; font-size: 16px; letter-spacing: 1px; }
.s-found-sub { margin-top: 12px; font-size: 12px; font-weight: bold; color: #151311;
  letter-spacing: .6px; animation: s-found-pulse 1s ease-in-out infinite; }
@keyframes s-found-in { from { opacity: 0; transform: scale(.94); }
  to { opacity: 1; transform: scale(1); } }
@keyframes s-found-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) {
  .s-found, .s-found-sub { animation: none; }
}


/* ---- remote-art loading treatment (all screens) ----
   Battle art comes from the same CDN as the selection grid, so every image
   slot carries the placeholder behind it and fades the real picture in.
   Without this a slow fetch leaves blank tiles that read as broken. */
.b-skill, .b-portrait, .b-info .pic, .s-team .slot {
  background-image: url("../assets/placeholder/img_loading.png");
  background-size: 24px 24px; background-position: center; background-repeat: no-repeat;
}
.b-portrait { background-size: 32px 32px; }
.b-info .pic { background-size: 32px 32px; }
.b-skill img, .b-skill .sprite,
.b-portrait img, .b-portrait .sprite,
.b-info .pic img, .b-info .pic .sprite,
.s-team .slot img, .s-team .slot .sprite { animation: s-fadein .35s ease both; }
/* the "?" slot and the vacated gap are UI, not remote art — no placeholder */
.b-skill.q, .b-skill.vacated { background-image: none; }


/* ---- character detail panel (measured from the reference) ----
   545x222 at stage (141,24) — it opens OVER the splash area above the
   roster, not as a full-screen overlay. Everything below is panel-relative.
   Opened by DOUBLE-clicking a face; a single click picks the character. */
.s-detail { position: absolute; left: 141px; top: 24px; width: 545px; height: 222px;
  box-sizing: border-box; overflow: hidden; }
/* title 15px in the reference red, top and again above the bio */
.s-detail h4 { font-size: 15px; font-weight: 400; color: #b91921; margin: 0; }
.s-detail .d-row { position: absolute; left: 27px; top: 32px; gap: 18px; }
.s-detail .d-face, .s-detail .d-skill, .s-detail .d-port {
  width: 77px; height: 77px; box-sizing: border-box; }
/* skills run on a 95px pitch: 164 / 259 / 354 / 449 panel-relative */
.s-detail .d-skills { display: flex; gap: 18px; }
.s-detail .d-bottom { position: absolute; left: 29px; top: 121px; width: 500px; margin: 0; }
.s-detail .d-bio p { font-size: 12px; font-weight: 400; color: #000; line-height: 1.35;
  width: 415px; }
.s-detail .d-cost, .s-detail .d-meta { font-size: 10px; font-weight: 400; color: #877956; }
.s-detail .d-port { position: absolute; left: 449px; top: 123px; }

/* ---- page arrows: yellow glow while held ---- */
.s-page { transition: filter .12s ease; }
.s-page:not(.off):active,
.s-page.flash { filter: drop-shadow(0 0 6px #ffd400) drop-shadow(0 0 12px #ffd40088) brightness(1.15); }
