/* ===========================================================================
   Commander Table

   Layout brief: Magic needs more space than a phone has, so the screen is split
   into fixed chrome and one scrolling table.

     - opponent strip  (sticky top)    who they are, life, zone counts; event
                                      chips stack beneath it
     - combat panel    (when needed)   attackers / blockers / damage
     - table area      (scrolls)       six battlefield rows, mirrored like a real
                                      table, each scrolling horizontally; empty
                                      rows collapse so the early game is compact
     - selection bar   (on demand)     contextual actions for what you tapped
     - your dashboard  (sticky)        phase track, [back | now | next], your
                                      seat, tools
     - hand tray       (sticky bottom) horizontal scroll

   Card width is one variable (--cw); everything else derives from it, so the
   size control rescales the whole table at once.
   ========================================================================= */

:root {
  --cw-base: 86px;                 /* the size control sets this */
  --cw: var(--cw-base);            /* card width */
  --ch: calc(var(--cw) * 1.396);   /* 63x88mm */
  --radius: 11px;

  --bg: #14161a;
  --bg-2: #1b1e24;
  --surface: #21252c;
  --surface-2: #2a2f38;
  --line: #343a45;
  --line-soft: #282d35;

  --text: #e8eaee;
  --text-dim: #9aa3b0;
  --text-faint: #6b7382;

  --gold: #d8a03a;
  --gold-dim: #a87b26;
  --green: #4caf7d;
  --amber: #e0a33c;
  --red: #e0533c;
  --blue: #4a90d9;

  --mana-w: #f6f0da; --mana-u: #b3ceea; --mana-b: #cbc2bf;
  --mana-r: #eeaa8e; --mana-g: #a3cfa9; --mana-c: #d0cfcb;

  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  /* viewport-fit=cover lets the page into a display cutout, so the sides need
     insetting too -- on a landscape Android with a notch these are non-zero. */
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);

  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, sans-serif;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; touch-action: manipulation; }
[hidden] { display: none !important; }
.spacer { flex: 1 1 auto; }
.muted { color: var(--text-dim); }
.stack > * + * { margin-top: 10px; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 42px; padding: 0 14px;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 9px;
  font-weight: 550; white-space: nowrap;
  flex: 0 0 auto; max-width: 100%;
}
/* Buttons laid out in a grid get a fixed column, so their label must wrap
   rather than clip -- "Put onto battlefield" does not fit on one line at 118px. */
.action-grid .btn, .btn-wrap {
  white-space: normal; line-height: 1.2; height: auto;
  min-height: 46px; padding: 9px 10px; text-align: center;
}
.btn .ico { font-size: 15px; line-height: 1; flex: 0 0 auto; }
.btn-block { justify-content: center; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: default; transform: none; }
.btn-primary { background: var(--gold); color: #1a1305; border-color: var(--gold); }
.btn-primary:disabled { background: var(--surface-2); color: var(--text-faint); border-color: var(--line); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-dim); }
.btn-danger { background: transparent; border-color: #5c2a22; color: #f0917e; }
.btn-sm { min-height: 34px; padding: 0 11px; font-size: 14px; }
.btn-xs { min-height: 28px; padding: 0 9px; font-size: 13px; }
.btn-block { width: 100%; }
.icon-btn {
  position: relative; flex: 0 0 auto;
  width: 38px; height: 38px; display: grid; place-items: center;
  background: transparent; border: 0; border-radius: 9px;
  color: var(--text-dim); font-size: 19px;
}
.icon-btn:active { background: var(--surface-2); }
.icon-btn.is-on { background: var(--surface-2); color: var(--gold); }
.badge {
  position: absolute; top: -1px; right: -3px;
  min-width: 17px; height: 17px; padding: 0 4px;
  background: var(--gold); color: #1a1305;
  border-radius: 9px; font-size: 11px; font-weight: 700;
  display: grid; place-items: center;
}

/* ---------------------------------------------------------------- avatars */
.avatar {
  display: inline-grid; place-items: center; flex: 0 0 auto;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--line);
  font-size: 15px; line-height: 1;
}
.avatar.is-letter { color: var(--gold); font: 700 13px/1 Georgia, serif; }
.avatar.lg { width: 34px; height: 34px; font-size: 19px; }
.avatar.xl { width: 52px; height: 52px; font-size: 30px; }
.avatar-slot { display: inline-flex; }
.avatar-slot:empty { display: none; }

/* ---------------------------------------------------------------- screens */
.screen { min-height: 100%; }
.center-screen { display: grid; place-items: center; padding: 24px 16px; }

.brand { font: 600 22px/1.1 Georgia, "Times New Roman", serif; margin: 0; letter-spacing: .2px; }
.brand span { color: var(--gold); }
.brand.sm { font-size: 17px; }

.login-card {
  width: 100%; max-width: 380px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px; padding: 22px;
}
.login-card h1 { margin-bottom: 6px; }
.login-card p.muted { margin: 0 0 18px; font-size: 14px; }
.login-card label { display: block; margin: 14px 0 5px; font-size: 13px; color: var(--text-dim); }
.login-card input {
  width: 100%; min-height: 46px; padding: 0 12px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 9px;
}
.login-card input:focus { outline: 2px solid var(--gold-dim); outline-offset: 0; }
.hint { font-size: 12.5px; color: var(--text-faint); margin: 12px 0 16px; }
.form-error {
  background: #3a1f1a; border: 1px solid #6b3228; color: #f3a392;
  padding: 9px 11px; border-radius: 8px; font-size: 14px; margin-bottom: 12px;
}

/* ---------------------------------------------------------------- home */
.app-bar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 10px;
  padding: calc(10px + var(--safe-t)) 12px 10px;
  background: var(--bg); border-bottom: 1px solid var(--line-soft);
}
/* The profile button is the way to the avatar picker, so it reads as a control
   rather than as a label. */
.profile-btn {
  gap: 8px; padding: 4px 12px 4px 5px; min-height: 38px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  color: var(--text); font-weight: 600;
}
.me-avatar { position: relative; background: none; border: 0; padding: 0; }
.me-avatar .me-avatar-edit {
  position: absolute; right: -2px; bottom: -2px;
  width: 20px; height: 20px; border-radius: 50%; font-size: 10px;
  display: grid; place-items: center;
  background: var(--gold); color: #1a1305; border: 2px solid var(--surface);
}
.tabs {
  position: sticky; top: 0; z-index: 10;
  display: flex; gap: 4px; padding: 0 12px;
  background: var(--bg); border-bottom: 1px solid var(--line-soft);
}
.tab {
  background: none; border: 0; border-bottom: 2px solid transparent;
  padding: 11px 10px; color: var(--text-dim); font-weight: 550;
}
.tab.is-active { color: var(--text); border-bottom-color: var(--gold); }
.pill-count {
  display: inline-grid; place-items: center; min-width: 19px; height: 19px;
  margin-left: 5px; padding: 0 5px; border-radius: 10px;
  background: var(--gold); color: #1a1305; font-size: 11.5px; font-weight: 700;
}
.home-body { padding: 14px 12px calc(28px + var(--safe-b)); max-width: 720px; margin: 0 auto; }
.row-actions { display: flex; gap: 9px; margin-bottom: 14px; }
.row-actions .btn { flex: 1 1 auto; }
.empty-note { color: var(--text-faint); font-size: 14px; text-align: center; padding: 26px 12px; }
.home-section { margin-top: 18px; }
.home-section h3, .list-title {
  margin: 0 0 8px; font-size: 11.5px; letter-spacing: .9px;
  text-transform: uppercase; color: var(--text-faint);
}
.list-title { margin-top: 18px; }
.stack > .list-title { margin-top: 18px; }
.stack > .list-title:first-child { margin-top: 0; }

/* game cards on the home screen */
.game-card {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--line); border-radius: 12px; padding: 12px 13px;
}
.game-card.cta-your-turn { border-left-color: var(--gold); background: #241f14; }
.game-card.cta-resume    { border-left-color: var(--blue); }
.game-card.cta-parked,
.game-card.cta-waiting-opponent { border-left-color: var(--amber); }
.game-card.cta-finished  { opacity: .72; }
.game-card .gc-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.game-card .gc-name { font-weight: 600; }
.game-card .gc-code {
  font: 600 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 1.5px; color: var(--text-faint);
  border: 1px solid var(--line); border-radius: 5px; padding: 4px 6px;
}
.game-card .gc-sub { font-size: 13.5px; color: var(--text-dim); margin-top: 5px;
  display: flex; align-items: center; gap: 6px; }
.game-card .gc-faces { display: inline-flex; gap: 2px; }
.game-card .gc-faces:empty { display: none; }
.game-card .gc-faces .avatar { width: 20px; height: 20px; font-size: 12px; }
.game-card .gc-foot { display: flex; align-items: center; margin-top: 2px; }
.game-card .gc-foot .gc-sub { margin-top: 0; }
.tagline {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
  padding: 3px 7px; border-radius: 5px;
}
.tagline.your-turn { background: var(--gold); color: #1a1305; }
.tagline.resume { background: #1d3449; color: #9cc9f0; }
.tagline.parked, .tagline.waiting-opponent { background: #3a2d14; color: #e7c079; }
.tagline.their-turn { background: var(--surface-2); color: var(--text-dim); }
.tagline.finished { background: var(--surface-2); color: var(--text-faint); }
.tagline.mulligan, .tagline.pick-deck { background: #1f3329; color: #8fd3ab; }

/* invites + online friends on the games tab */
.invite-card {
  display: flex; align-items: center; gap: 10px;
  background: #241f14; border: 1px solid var(--gold-dim); border-radius: 12px;
  padding: 10px 12px;
}
.invite-card + .invite-card { margin-top: 8px; }
#invites-list:not(:empty) { margin-bottom: 12px; }
.online-strip {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-bottom: 12px; font-size: 13px;
}
.os-label { color: var(--text-faint); font-size: 11.5px; letter-spacing: .8px; text-transform: uppercase; margin-right: 2px; }
.os-friend {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  padding: 3px 10px 3px 3px; color: var(--text); font-size: 13px;
}
.os-friend .avatar { width: 22px; height: 22px; font-size: 13px; }
.os-friend .os-note { color: var(--text-faint); font-size: 11.5px; }

/* friends tab */
.me-card {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 12px; margin-bottom: 14px;
}
.friend-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  padding: 9px 11px;
}
.friend-row + .friend-row, .home-section .friend-row + .friend-row { margin-top: 8px; }
.friend-row.is-online { border-color: #2f5a40; }
.fr-main { flex: 1 1 auto; min-width: 0; }
.fr-name { font-weight: 600; display: flex; align-items: center; gap: 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-sub { font-size: 12.5px; color: var(--text-dim); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.fr-actions { display: flex; align-items: center; gap: 5px; flex: 0 0 auto; }
.friend-hero { display: flex; align-items: center; gap: 14px; }
.friend-hero .fr-name { font-size: 17px; }
.friend-hero .fr-sub { white-space: normal; }
.search-results:not(:empty) { margin-top: 8px; }
.avatar-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(46px, 1fr)); gap: 6px; }
.avatar-pick {
  height: 46px; border-radius: 10px; font-size: 24px; line-height: 1;
  background: var(--surface-2); border: 1px solid var(--line);
}
.avatar-pick.is-on { background: #3a2d14; border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }

/* deck cards */
.deck-add { margin-bottom: 14px; }
.deck-add label { display: block; font-size: 13px; color: var(--text-dim); margin-bottom: 6px; }
.input-row { display: flex; gap: 8px; }
.input-row input {
  flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 12px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 9px;
}
.deck-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 13px;
}
.deck-card.is-illegal { border-color: #5c2a22; }
.deck-top { display: flex; align-items: flex-start; gap: 10px; }
.deck-name { font-weight: 600; }
.deck-sub { font-size: 13px; color: var(--text-dim); margin-top: 3px; }
.deck-actions { display: flex; gap: 7px; margin-top: 11px; flex-wrap: wrap; }
.legality {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 11px; padding: 12px; margin-bottom: 14px; font-size: 14px;
}
.legality.bad { border-color: #5c2a22; background: #2a1b18; }
.legality.good { border-color: #2a4a36; background: #18251d; }
.legality h3 { margin: 0 0 8px; font-size: 15px; }
.legality ul { margin: 6px 0 0; padding-left: 19px; }
.legality li { margin: 4px 0; }

/* colour identity pips */
.ci { display: inline-flex; gap: 3px; vertical-align: middle; }
.ci i {
  width: 13px; height: 13px; border-radius: 50%;
  border: 1px solid rgba(0,0,0,.35); display: inline-block;
}
.ci i[data-c="W"] { background: var(--mana-w); }
.ci i[data-c="U"] { background: var(--mana-u); }
.ci i[data-c="B"] { background: var(--mana-b); }
.ci i[data-c="R"] { background: var(--mana-r); }
.ci i[data-c="G"] { background: var(--mana-g); }
.ci i[data-c="C"] { background: var(--mana-c); }

/* mana cost pips */
.mana { display: inline-flex; gap: 2px; vertical-align: -1px; }
.mana b {
  min-width: 15px; height: 15px; padding: 0 2px;
  border-radius: 50%; background: var(--mana-c); color: #1a1a1a;
  font: 700 10.5px/15px ui-monospace, Menlo, monospace;
  text-align: center; display: inline-block;
}
.mana b[data-c="W"] { background: var(--mana-w); }
.mana b[data-c="U"] { background: var(--mana-u); }
.mana b[data-c="B"] { background: var(--mana-b); }
.mana b[data-c="R"] { background: var(--mana-r); }
.mana b[data-c="G"] { background: var(--mana-g); }

/* =========================================================== THE TABLE === */
/* Rows are assigned explicitly rather than by source order: the banner and the
   lobby pane are display:none most of the time, and a hidden child is not a grid
   item, so positional assignment would shift every row up and hand the flexible
   track to the wrong element. minmax(0,1fr) keeps a wide row from widening the
   whole column instead of scrolling inside itself. The event feed shares the
   table's cell and floats over its top-left corner. */
.game-screen {
  position: fixed; inset: 0;
  padding-left: var(--safe-l); padding-right: var(--safe-r);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto auto minmax(0, 1fr) auto auto auto;
  overflow: hidden;
}
.opp-bar      { grid-row: 1; grid-column: 1; }
.banner       { grid-row: 2; grid-column: 1; }
.phase-pane   { grid-row: 3; grid-column: 1; }
.combat       { grid-row: 4; grid-column: 1; }
.table-area   { grid-row: 5; grid-column: 1; min-height: 0; }
/* The feed shares the table's cell rather than taking one of its own: without
   an explicit column it auto-places into an implicit second column, which
   leaves a strip of dead space down the right of the whole screen. */
.feed         { grid-row: 5; grid-column: 1; align-self: start; justify-self: start; z-index: 30; }
.sel-bar      { grid-row: 6; grid-column: 1; }
.you-bar      { grid-row: 7; grid-column: 1; }
.hand-tray    { grid-row: 8; grid-column: 1; }
.game-screen > * { min-width: 0; }

/* --- opponent strip --- */
.opp-bar {
  display: flex; align-items: center; gap: 5px;
  padding: calc(6px + var(--safe-t)) 5px 6px;
  background: var(--bg-2); border-bottom: 1px solid var(--line);
  min-height: 48px;
}
.opp-bar .icon-btn { width: 34px; height: 34px; }
/* Shrinkable, with min-width:0 so the name inside can actually ellipsise: a
   long name must give up room to the zone counts, not swallow them. */
.seat-chip {
  display: inline-flex; align-items: center; gap: 6px;
  flex: 0 1 auto; min-width: 0;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 10px 4px 5px; min-height: 36px;
  transition: box-shadow .15s ease;
}
.seat-chip.you { border-color: var(--gold-dim); }
/* The name yields space before the counts do: an ellipsis costs you nothing,
   an unreachable graveyard count costs you the game state. */
.seat-name { font-weight: 600; font-size: 14px; max-width: 9ch;
  flex: 0 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 520px) { .seat-name { max-width: 14ch; } }
@media (min-width: 680px) { .seat-name { max-width: 20ch; } }
.seat-life { font: 700 17px/1 ui-monospace, Menlo, monospace; color: var(--gold); }
.seat-life.low { color: var(--red); }
.seat-life.dead { color: #fff; background: var(--red); border-radius: 5px; padding: 1px 4px; }
.presence {
  width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint);
  flex: 0 0 auto; box-shadow: 0 0 0 2px rgba(0,0,0,.25);
}
.presence.here { background: var(--green); }
.presence.away { background: var(--amber); }
.is-active-seat { box-shadow: 0 0 0 2px var(--gold-dim); }
/* Whoever holds priority gets the brighter ring: at a glance, who the table is
   waiting on. */
.seat-chip.has-priority { box-shadow: 0 0 0 2px var(--gold); }

/* Zone counters. The strip asks for a real share of the row rather than taking
   the leftovers: a flex-basis the bar cannot satisfy means the name chip has to
   shrink too, so a long name ellipsises instead of eating every counter. */
.zone-mini { display: flex; gap: 3px; flex-wrap: nowrap; overflow: hidden;
  flex: 1 1 165px; min-width: 0; }
.zone-btn {
  display: inline-flex; align-items: center; gap: 3px; flex: 0 0 auto;
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: 8px; padding: 4px 6px; min-height: 30px;
  font-size: 12px; color: var(--text-dim); white-space: nowrap;
}
.zone-btn .ico { font-size: 13px; line-height: 1; }
.zone-btn b { color: var(--text); font: 700 12.5px/1 ui-monospace, Menlo, monospace; }
.zone-btn.is-static { cursor: default; }
.zone-btn.ctr { border-color: var(--line); }
.zone-btn.ctr.danger { border-color: var(--red); color: #f3a392; }
.zone-btn.ctr.danger b { color: #ffd9d0; }
.zone-btn.ctr.gold { border-color: var(--gold-dim); color: var(--gold); }
/* the overflow chip */
.zone-btn.more { border-style: dashed; border-color: var(--line); }
.zone-btn.more b { color: var(--text-dim); }

/* the sheet behind the overflow chip */
.zone-rows { display: flex; flex-direction: column; gap: 5px; }
.zone-row {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 12px; color: inherit; text-align: left;
}
.zone-row.is-danger { border-color: var(--red); }
.zone-row .zr-ico { font-size: 17px; flex: 0 0 auto; }
.zone-row .zr-label { flex: 1 1 auto; min-width: 0; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zone-row .zr-val { font: 700 15px/1 ui-monospace, Menlo, monospace; color: var(--text);
  flex: 0 0 auto; }
.zone-row.is-danger .zr-val { color: #f3a392; }

/* --- the event feed: chips under the opponent's bar --- */
.feed {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  padding: 6px 8px; max-width: min(84vw, 380px); pointer-events: none;
}
.chip {
  display: inline-flex; align-items: flex-start; gap: 7px; max-width: 100%;
  padding: 6px 11px 6px 9px; border-radius: 12px; text-align: left;
  background: rgba(33,37,44,.96); border: 1px solid var(--line);
  border-left: 3px solid var(--text-faint);
  box-shadow: 0 8px 22px rgba(0,0,0,.45);
  color: var(--text); font-size: 12.5px; line-height: 1.3;
  pointer-events: auto; cursor: pointer;
  animation: chip-in .22s cubic-bezier(.2,1.2,.4,1);
  transition: opacity .25s, transform .25s;
}
.chip .chip-icon { font-size: 14px; line-height: 1.2; flex: 0 0 auto; }
.chip .chip-text { min-width: 0; overflow-wrap: anywhere; }
.chip .chip-sub { display: block; color: var(--text-dim); font-size: 11.5px; }
.chip.danger { border-left-color: var(--red); background: rgba(58,31,26,.97); }
.chip.combat { border-left-color: #e0533c; }
.chip.spell  { border-left-color: #b98cf0; }
.chip.chat   { border-left-color: var(--blue); background: rgba(29,52,73,.97); }
.chip.quiet  { opacity: .82; }
.chip.step   { border-left-color: var(--gold-dim); color: var(--text-dim); padding-top: 4px; padding-bottom: 4px; }
.chip.fade   { opacity: 0; transform: translateX(-10px); }
@keyframes chip-in { from { transform: translateX(-14px); opacity: 0; } }

/* --- banner --- */
.banner {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; background: #3a2d14; border-bottom: 1px solid #5a4620;
  font-size: 13.5px; color: #f0d49a;
}
.banner.is-parked { background: #1d2e42; border-bottom-color: #2d4a68; color: #a8d2f5; }
.banner-text { flex: 1 1 auto; }

/* --- lobby / mulligan pane --- */
.phase-pane {
  padding: 14px 12px; background: var(--bg-2);
  border-bottom: 1px solid var(--line); max-height: 62vh; overflow-y: auto;
}
.phase-pane h2 { margin: 0 0 4px; font-size: 17px; }
.phase-pane p { margin: 0 0 12px; font-size: 14px; color: var(--text-dim); }
.seat-grid { display: grid; gap: 9px; margin-bottom: 13px; }
.seat-row {
  display: flex; align-items: center; gap: 9px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 11px;
}
.seat-row .sr-name { font-weight: 600; }
.seat-row .sr-deck { font-size: 13px; color: var(--text-dim); }
.seat-row .seat-empty { min-width: 0; }
.code-box { text-align: center; margin: 6px 0 14px; }
.code-box .code {
  font: 700 30px/1 ui-monospace, Menlo, monospace; letter-spacing: 7px;
  color: var(--gold); display: block; margin-bottom: 5px;
}

/* --- battlefield --- */
.table-area {
  overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  background:
    radial-gradient(120% 60% at 50% 0%,   rgba(80,110,160,.07), transparent 70%),
    radial-gradient(120% 60% at 50% 100%, rgba(200,160,60,.07), transparent 70%);
}
.side { padding: 4px 0 6px; }
/* Both sides take their width from :root now; this is left as a hook for
   sizing the far board differently, and deliberately changes nothing. */

.bf-row { position: relative; padding: 0 0 2px; }
.bf-row-label {
  position: absolute; left: 8px; top: 2px; z-index: 1;
  font-size: 10px; letter-spacing: .8px; text-transform: uppercase;
  color: var(--text-faint); pointer-events: none;
}
.bf-strip {
  display: flex; align-items: flex-start; gap: 5px;
  padding: 14px 10px 4px; overflow-x: auto; overflow-y: hidden;
  scrollbar-width: thin; -webkit-overflow-scrolling: touch;
  min-height: calc(var(--ch) + 20px);
}
.bf-strip::-webkit-scrollbar { height: 5px; }
.bf-strip::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }
.bf-strip.is-empty { min-height: 0; padding: 0; }

/* table edge: the midline between the two players */
.table-edge {
  position: relative; min-height: 3px;
  background: linear-gradient(90deg, transparent, var(--line) 12%, var(--line) 88%, transparent);
}
.stack-zone {
  margin: 8px 10px; padding: 8px 10px;
  background: #241f2e; border: 1px solid #433a55; border-radius: 11px;
}
.stack-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.stack-label {
  font-size: 10.5px; letter-spacing: 1px; text-transform: uppercase;
  color: #b9a6d8;
}
.stack-actions { display: flex; gap: 5px; }
.stack-items { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 3px; }

/* --- the card --- */
.card {
  position: relative; flex: 0 0 auto;
  width: var(--cw); height: var(--ch);
  border-radius: var(--radius); background: var(--surface-2);
  border: 1px solid #000; overflow: hidden;
  padding: 0; color: inherit;
  transition: transform .12s ease, box-shadow .12s ease, outline-color .12s ease;
  -webkit-tap-highlight-color: transparent;
  outline: 2px solid transparent; outline-offset: 0;
}
.card img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  pointer-events: none; background: #0d0f12;
}
.card.is-tapped { transform: rotate(90deg) scale(.74); }
.card-mini { --cw: 36px; --ch: 50px; --radius: 4px; cursor: default; }
.card-mini:not(:disabled) { cursor: pointer; }
.card-mini .card-combat { display: none !important; }
/* A mini card sits beside its own name, so the fallback shrinks to a hint
   rather than repeating it -- but a blank tile reads as broken, so a token
   with no art still shows something. */
.card-mini .card-fallback { font-size: 7px; line-height: 1.05; padding: 2px 1px; opacity: .75; }
.card-mini.is-sick::before { display: none; }

/* A card that just changed zone pulses, so "where did that go?" answers itself.
   Only box-shadow and brightness animate -- a transform here would fight the
   90deg rotation a tapped card is already carrying. Three hard blinks rather
   than one soft glow: a single fade was too easy to miss when it happened on
   the far side of the board. */
@keyframes card-flash {
  0%, 100%      { box-shadow: 0 0 0 3px var(--gold), 0 0 24px 7px rgba(216,160,58,.7);
                  filter: brightness(1.6) saturate(1.15); }
  18%, 52%, 86% { box-shadow: 0 0 0 0 rgba(216,160,58,0);
                  filter: brightness(.72); }
}
.card.just-moved { animation: card-flash 1.05s steps(1, end) 3; z-index: 4; }

@keyframes pill-flash {
  0%   { background: var(--gold); color: #1a1305; border-color: var(--gold);
         transform: scale(1.14); }
  100% { transform: scale(1); }
}
.zone-btn.flash { animation: pill-flash .75s ease-out; }
.zone-btn.flash b { color: inherit; }

/* Selection is the outline; combat state is the shadow. They no longer fight,
   so a selected attacker shows both. */
.card.is-selected { outline-color: var(--gold); box-shadow: 0 3px 12px rgba(0,0,0,.5); z-index: 2; }
.card.is-attacking { box-shadow: 0 0 0 2px var(--red); }
.card.is-blocking  { box-shadow: 0 0 0 2px var(--blue); }
.card.can-attack { box-shadow: 0 0 0 2px rgba(224,83,60,.45); }
.card.can-block  { box-shadow: 0 0 0 2px rgba(74,144,217,.5); }
.card.is-picked  { box-shadow: 0 0 0 3px var(--blue), 0 0 18px rgba(74,144,217,.6); z-index: 2; }
.card.is-facedown img { display: none; }
.card.is-hidden { background:
  repeating-linear-gradient(135deg, #262b33 0 6px, #20242b 6px 12px); }
.card.is-sick::before {
  content: "✦"; position: absolute; top: 2px; left: 3px; z-index: 3;
  font-size: 10px; color: #ffd98a; text-shadow: 0 0 3px #000;
}
.card-fallback {
  position: absolute; inset: 0; padding: 4px 3px;
  font-size: 9px; line-height: 1.15; color: var(--text-dim);
  display: flex; align-items: center; text-align: center; justify-content: center;
  overflow: hidden;
}
.card-badges {
  position: absolute; bottom: 0; left: 0; right: 0; z-index: 3;
  display: flex; flex-wrap: wrap; gap: 2px; padding: 2px;
  background: linear-gradient(transparent, rgba(0,0,0,.82));
}
.cbadge {
  font: 700 9.5px/1 ui-monospace, Menlo, monospace;
  padding: 2px 3px; border-radius: 4px;
  background: rgba(0,0,0,.8); color: #ffe9b8; border: 1px solid rgba(255,255,255,.16);
}
.cbadge.pt { color: #fff; background: rgba(20,20,20,.92); }
.cbadge.cmd { color: #1a1305; background: var(--gold); border-color: var(--gold); }
.cbadge.note { color: #cfe6ff; }
/* the combat corner: "⚔️ Bob" on an attacker, "🛡️ Bear" on a blocker */
.card-combat {
  position: absolute; top: 2px; right: 2px; z-index: 3; max-width: calc(100% - 6px);
  font: 700 9px/1.1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  padding: 2px 4px; border-radius: 4px; background: rgba(20,20,20,.9); color: #fff;
  border: 1px solid rgba(255,255,255,.2); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis;
}
.card.is-attacking .card-combat { border-color: var(--red); }
.card.is-blocking .card-combat { border-color: var(--blue); }
.card-count {
  position: absolute; top: 2px; right: 3px; z-index: 3;
  font: 700 10px/1 ui-monospace, Menlo, monospace; color: #fff;
  background: rgba(0,0,0,.78); border-radius: 4px; padding: 2px 3px;
}
.attached-wrap { position: relative; flex: 0 0 auto; display: flex; }
.attached-wrap .card + .card { margin-left: calc(var(--cw) * -0.74); }

/* --- selection bar: only while something is selected --- */
.sel-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 8px; background: var(--surface);
  border-top: 1px solid var(--gold-dim); border-bottom: 1px solid var(--line);
  animation: sel-in .14s ease;
}
@keyframes sel-in { from { transform: translateY(6px); opacity: 0; } }
.sel-info { font-size: 13px; color: var(--text-dim); max-width: 34%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto;
  display: flex; align-items: center; gap: 6px; }
.sel-info .si-name { overflow: hidden; text-overflow: ellipsis; }
.sel-info .si-pt { font: 700 12px/1 ui-monospace, Menlo, monospace; color: var(--text);
  background: var(--surface-2); border-radius: 4px; padding: 3px 5px; flex: 0 0 auto; }
.sel-actions { display: flex; gap: 6px; overflow-x: auto; flex: 1 1 auto;
  scrollbar-width: none; }
.sel-actions::-webkit-scrollbar { display: none; }

/* --- your dashboard --- */
.you-bar {
  background: var(--bg-2); border-top: 1px solid var(--line);
  padding: 3px 6px 6px;
}

/* Step reminders: what the rules do here that the table cannot do for you. */
.reminders { display: flex; flex-direction: column; gap: 4px; padding: 5px 2px 2px; }
.reminder {
  display: flex; align-items: flex-start; gap: 7px;
  background: #2a2313; border: 1px solid var(--gold-dim); border-radius: 8px;
  padding: 6px 9px; font-size: 12.5px; color: #f0d49a; line-height: 1.3;
}
.reminder .rm-ico { font-size: 14px; line-height: 1.2; flex: 0 0 auto; }
.reminder .rm-text { min-width: 0; }

/* the countdown that auto-pass shows instead of the Done button */
.step-btn.interrupt.is-counting {
  background: #3a2d14; border-color: var(--gold); color: #f0d49a;
}

/* Scry / surveil: piles you can see into, not a list of radio buttons. Cards
   are big enough to read, and tapping one moves it to the next pile. */
.scry-pile {
  border: 1px solid var(--line); border-left: 3px solid var(--line);
  border-radius: 10px; padding: 7px 9px 9px; margin-bottom: 9px;
  background: var(--bg-2);
}
.scry-pile.is-top { border-left-color: var(--gold); }
.scry-pile.is-bottom { border-left-color: var(--text-faint); }
.scry-pile.is-graveyard { border-left-color: #6b3228; }
.scry-pile-head { display: flex; align-items: baseline; gap: 7px; margin-bottom: 7px; }
.scry-pile-head .sp-name { font-size: 12px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--text); }
.scry-pile.is-top .sp-name { color: var(--gold); }
.scry-pile-head .sp-count {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--surface-2); color: var(--text);
  font: 700 11px/18px ui-monospace, Menlo, monospace; text-align: center;
}
.scry-pile-head .sp-note { font-size: 11.5px; color: var(--text-faint); }
.scry-cards { display: flex; gap: 7px; flex-wrap: wrap; }
.scry-card {
  position: relative; width: 92px; padding: 0; border-radius: 7px;
  background: var(--surface-2); border: 1px solid #000; overflow: hidden;
  color: inherit; -webkit-tap-highlight-color: transparent;
}
.scry-card img { width: 100%; aspect-ratio: 5 / 7; object-fit: cover; display: block; }
.scry-card .sc-fallback {
  display: grid; place-items: center; aspect-ratio: 5 / 7; padding: 4px;
  font-size: 10px; text-align: center; color: var(--text-dim);
}
.scry-card .sc-rank {
  position: absolute; top: 3px; left: 3px;
  background: var(--gold); color: #1a1305; border-radius: 5px; padding: 2px 5px;
  font: 700 10px/1 ui-monospace, Menlo, monospace;
}
.scry-card .sc-move {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 3px 4px;
  background: rgba(0,0,0,.82); color: var(--text-dim);
  font-size: 9.5px; line-height: 1.15; text-align: center;
}
.scry-card:active { transform: translateY(1px); }
.scry-empty { color: var(--text-faint); font-size: 13px; padding: 4px 2px; }

/* crewing a vehicle: pick creatures, watch the total */
.crew-total {
  display: flex; align-items: baseline; gap: 8px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 12px; margin-bottom: 10px;
}
.crew-total.is-enough { border-color: #2f5a40; background: #18251d; }
.crew-total .ct-num { font: 700 26px/1 ui-monospace, Menlo, monospace; color: var(--gold); }
.crew-total.is-enough .ct-num { color: var(--green); }
.crew-total .ct-of { font-size: 13px; color: var(--text-dim); }
.crew-total .ct-state { font-size: 12.5px; font-weight: 600; color: var(--text-dim); }
.crew-total.is-enough .ct-state { color: var(--green); }
.crew-list { display: flex; flex-direction: column; gap: 6px; }
.crew-pick {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 6px 10px 6px 6px; color: inherit; text-align: left;
}
.crew-pick.is-on { border-color: var(--gold); background: #241f14; }
.crew-pick .cp-name { flex: 1 1 auto; min-width: 0; font-size: 13.5px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crew-pick .cp-pow {
  font: 700 14px/1 ui-monospace, Menlo, monospace; color: #fff;
  background: rgba(0,0,0,.45); border-radius: 5px; padding: 4px 7px; flex: 0 0 auto;
}
.crew-pick .cp-tick { width: 16px; color: var(--gold); font-weight: 700; flex: 0 0 auto; }
.cbadge.crew { color: #1a1305; background: #8fd3ab; border-color: #8fd3ab; }
/* a P/T that is only true until end of turn */
.cbadge.pt.is-temp { color: #1a1305; background: #e0a33c; border-color: #ffd98a; }

.temp-pt {
  display: flex; align-items: baseline; gap: 9px; margin-bottom: 9px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 8px 12px;
}
.temp-pt.is-on { border-color: var(--amber); background: #2a2313; }
.temp-pt .tp-now { font: 700 20px/1 ui-monospace, Menlo, monospace; color: var(--text-dim); }
.temp-pt.is-on .tp-now { color: var(--amber); }
.temp-pt .tp-note { font-size: 12.5px; color: var(--text-faint); }

/* the dismiss on the watching banner */
.banner-close { width: 30px; height: 30px; font-size: 14px; color: inherit; flex: 0 0 auto; }

/* The turn as a track: twelve segments in five groups, the current one lit.
   Group gaps are the little pauses in a turn -- main phase, combat, main phase. */
.phase-track { display: flex; align-items: center; gap: 2px; padding: 4px 2px 3px; }
.pt-seg {
  flex: 1 1 0; height: 14px; padding: 0; border: 0; background: none; position: relative;
  min-width: 0; cursor: default;
}
.pt-seg:not(:disabled) { cursor: pointer; }
.pt-seg::before {
  content: ""; position: absolute; left: 0; right: 0; top: 5px; height: 4px;
  border-radius: 2px; background: var(--line); transition: background .15s, height .15s, top .15s;
}
.pt-seg.is-first { margin-left: 5px; }
.pt-seg.is-first:first-child { margin-left: 0; }
.pt-seg.is-done::before { background: var(--gold-dim); }
.pt-seg.is-now::before { background: var(--gold); top: 3px; height: 8px;
  box-shadow: 0 0 8px rgba(216,160,58,.6); }
.pt-seg[data-group="combat"]::before { border-radius: 1px; }
.pt-seg[data-group="combat"].is-now::before { background: var(--red);
  box-shadow: 0 0 8px rgba(224,83,60,.6); }
.pt-seg:not(:disabled):hover::before { background: var(--text-dim); }
.phase-track.theirs .pt-seg.is-done::before { background: #3c5a78; }
.phase-track.theirs .pt-seg.is-now::before { background: var(--blue);
  box-shadow: 0 0 8px rgba(74,144,217,.6); }

/* [back | now | next]. Naming the step on each button means you always know
   where the arrow takes you; the right-hand button is whatever the situation
   needs -- next step, End turn (red), Resume, Respond, Confirm blocks. */
.step-nav {
  display: flex; align-items: stretch; gap: 5px; padding: 2px 2px 6px;
}
.step-btn {
  flex: 1 1 0; min-width: 0; min-height: 40px; padding: 0 8px;
  display: flex; align-items: center; justify-content: center; gap: 5px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 9px;
  color: var(--text-dim); font-size: 12.5px; font-weight: 550;
}
.step-btn .sn-name {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.step-btn .sn-arrow { flex: 0 0 auto; opacity: .75; font-size: 11px; }
.step-btn:disabled { opacity: .38; cursor: default; }
.step-btn.is-wait:disabled { opacity: .7; font-style: italic; }
.step-btn.is-endturn {
  background: #5c2018; border-color: var(--red); color: #ffd9d0; font-weight: 700;
}
.step-btn.is-endturn .sn-arrow { opacity: 1; }
.step-btn.is-go {
  background: var(--gold); border-color: var(--gold); color: #1a1305; font-weight: 700;
}
.step-btn.is-go .sn-arrow { opacity: 1; }

.step-now {
  flex: 1.15 1 0; min-width: 0; min-height: 40px; padding: 0 8px;
  background: #2c2413; border: 1px solid var(--gold); border-radius: 9px;
  color: var(--gold); font-size: 13px; font-weight: 700;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  line-height: 1.12; overflow: hidden;
}
.step-now:disabled { cursor: default; }
.step-now .sn-turn {
  font-size: 9.5px; letter-spacing: .9px; text-transform: uppercase;
  color: var(--text-faint); font-weight: 600; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.step-now .sn-cur {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.step-now.is-parked { background: #1d2e42; border-color: #2d4a68; color: #a8d2f5; }

/* Their turn: the whole bar changes character so there is no chance of reading
   it as yours, and the only control offered is the one that matters. */
.step-nav.theirs .step-now {
  background: var(--surface); border-color: var(--line); color: var(--text-dim);
  font-weight: 600;
}
.step-nav.theirs .step-now .sn-turn { color: var(--blue); }
.step-btn.interrupt {
  flex: 0 0 auto; padding: 0 14px;
  background: #1d3449; border-color: #3c6a96; color: #bcdcff; font-weight: 650;
}
.step-btn.interrupt.is-armed {
  background: var(--blue); border-color: var(--blue); color: #fff;
}
.step-nav.theirs .step-btn.is-go { flex: 0 0 auto; padding: 0 14px; }
.step-nav.blocked .step-now { opacity: .7; }

.you-row { display: flex; align-items: center; gap: 7px; min-width: 0; }

/* the tools: icon buttons, labels appear once there is room */
.toolbar { display: flex; gap: 0; flex: 0 0 auto; }
.tb-btn {
  display: inline-flex; align-items: center; gap: 5px; min-height: 36px;
  padding: 0 5px; border-radius: 9px; background: transparent; border: 1px solid transparent;
  color: var(--text-dim); font-size: 12.5px; font-weight: 550;
}
.tb-btn:active { background: var(--surface-2); }
.tb-btn .tb-ico { font-size: 17px; line-height: 1; }
.tb-btn .tb-label { display: none; }
/* A button whose meaning does not survive being reduced to its icon keeps its
   words at every width. */
.tb-btn.has-label .tb-label { display: inline; }
.tb-btn.has-label { padding: 0 10px; border-color: var(--line); }
.tb-btn.is-dim { opacity: .45; }

/* --- hand --- */
.hand-tray {
  background: var(--bg); border-top: 1px solid var(--line);
  padding: 4px 0 var(--safe-b);
}
.hand-head {
  display: flex; align-items: center; gap: 8px; padding: 0 10px 3px;
  font-size: 11px; letter-spacing: .8px; text-transform: uppercase;
  color: var(--text-faint); cursor: pointer; user-select: none;
}
.hand-head .hh-toggle { color: var(--text-faint); font-size: 11px; }
.hand-cards {
  display: flex; gap: 5px; padding: 2px 10px 7px;
  overflow-x: auto; min-height: calc(var(--ch) + 8px);
  -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.hand-cards::-webkit-scrollbar { height: 5px; }
.hand-cards::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }
.hand-cards .card.is-selected { transform: translateY(-7px); }
.hand-tray.collapsed .hand-cards { display: none; }
.hand-tray.collapsed { padding-bottom: calc(4px + var(--safe-b)); }

/* ====================================================== combat panel === */
.combat {
  background: #251a1a; border-bottom: 1px solid #5a3030;
  max-height: 46vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.combat.is-block { background: #1a2230; border-bottom-color: #2f4a68; }
.combat.is-damage { background: #221d14; border-bottom-color: #5a4620; }
.combat.is-waitAttack, .combat.is-waitBlock { background: var(--bg-2); border-bottom-color: var(--line); }
.combat.is-collapsed { max-height: none; overflow: visible; }
.combat-head {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; gap: 8px; padding: 7px 8px 7px 10px;
  background: inherit; border-bottom: 1px solid rgba(255,255,255,.06);
}
.combat.is-collapsed .combat-head { border-bottom: 0; }
.combat-icon { font-size: 18px; line-height: 1; flex: 0 0 auto; }
.combat-titles { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.combat-title { font-size: 13.5px; font-weight: 700; color: #f0a08a; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.combat.is-block .combat-title { color: #8fc0f0; }
.combat.is-damage .combat-title { color: var(--gold); }
.combat.is-waitAttack .combat-title, .combat.is-waitBlock .combat-title { color: var(--text); }
.combat-sub { font-size: 11.5px; color: var(--text-dim); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.combat-collapse { width: 32px; height: 32px; font-size: 15px; }
.combat-body { padding: 6px 10px 9px; }
.combat-hint { font-size: 12px; color: var(--text-faint); margin: 7px 0 0; }
.combat-go { flex: 0 0 auto; }
.combat-prompt {
  background: rgba(0,0,0,.22); border-radius: 9px;
  padding: 7px 10px; margin-bottom: 8px; font-size: 13px; color: var(--text);
}
.combat-prompt b { color: var(--gold); font-weight: 700; }
.combat.is-block .combat-prompt b { color: #8fc0f0; }
.combat-actions { display: flex; gap: 7px; margin-top: 9px; flex-wrap: wrap; align-items: center; }
.combat-done {
  display: flex; align-items: center; gap: 7px;
  color: var(--green); font-size: 13px; font-weight: 600; margin: 2px 0 8px;
}

.target-row { display: flex; align-items: center; gap: 6px; overflow-x: auto; padding-bottom: 8px;
  scrollbar-width: none; }
.target-row::-webkit-scrollbar { display: none; }
.target-label { font-size: 11.5px; color: var(--text-faint); text-transform: uppercase;
  letter-spacing: .6px; flex: 0 0 auto; }
.target-btn {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; padding: 0 11px; border-radius: 9px;
  background: var(--surface); border: 1px solid var(--line); color: var(--text-dim);
  font-size: 13px; white-space: nowrap;
}
.target-btn.is-on {
  background: var(--red); border-color: var(--red); color: #fff; font-weight: 650;
}
.target-btn .tb-sub { font-size: 11px; color: inherit; opacity: .8; }

/* one row per attacker: attacker → target, then who is in front of it */
.duel-list { display: flex; flex-direction: column; gap: 6px; }
.duel {
  position: relative; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; padding: 6px 8px; font-size: 13px;
}
.duel.unblocked { border-color: #6b3228; }
.duel.blocked { border-color: #2f5a40; }
.combat.is-block .duel { cursor: pointer; }
.duel.is-picked { border-color: var(--blue); box-shadow: 0 0 0 1px var(--blue), 0 0 14px rgba(74,144,217,.35); }
.duel-atk { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1 1 150px; }
.duel-info { min-width: 0; line-height: 1.25; }
.duel-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: flex; align-items: center; gap: 5px; }
.duel-tag { font: 700 9px/1 ui-monospace, Menlo, monospace; padding: 2px 3px; border-radius: 3px; }
.duel-tag.cmd { background: var(--gold); color: #1a1305; }
.duel-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 11.5px; color: var(--text-dim); }
.duel-pt {
  font: 700 11.5px/1 ui-monospace, Menlo, monospace; color: #fff;
  background: rgba(0,0,0,.45); border-radius: 4px; padding: 3px 5px; flex: 0 0 auto;
}
.duel-kw { color: var(--text-dim); font-style: italic; }
.duel-kw.warn { color: #ffd98a; font-style: normal; }
.duel-tap {
  background: none; border: 1px solid var(--line); border-radius: 999px;
  color: var(--text-faint); font-size: 10.5px; padding: 2px 7px;
}
.duel-tap.is-on { border-color: var(--green); color: #a8e0c0; }
.duel-tgt { display: inline-flex; align-items: center; gap: 5px; color: var(--text-dim);
  flex: 0 0 auto; }
.duel-tgt.is-tappable { cursor: pointer; text-decoration: underline dotted; }
.duel-arrow { color: var(--text-faint); }
.duel-tgt-name { font-weight: 600; color: var(--text); }
.duel-blk { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; flex: 1 1 100%; }
.duel-blocker {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(74,144,217,.15); border: 1px solid #3c6a96; border-radius: 999px;
  color: #cfe6ff; font-size: 12px; padding: 3px 9px 3px 7px;
}
.duel-blocker:disabled { cursor: default; opacity: 1; }
.duel-blocker.can-remove:active { background: rgba(224,83,60,.25); }
.duel-blocker .x { color: var(--text-dim); }
.duel-unblocked { font-size: 12px; color: #f0917e; }
.duel-add { border-style: dashed; }
.duel-out { flex: 1 1 100%; font-size: 12px; color: var(--gold); }
.combat.is-damage .duel-out { color: #ffd98a; }
.duel-remove { position: absolute; top: 2px; right: 2px; width: 28px; height: 28px; font-size: 13px; }

/* the damage review: one editable line per thing about to happen */
.plan-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.plan-line {
  display: flex; align-items: center; gap: 9px; padding: 5px 8px;
  background: rgba(0,0,0,.2); border-radius: 8px; font-size: 13px; cursor: pointer;
}
.plan-line.is-off { opacity: .5; text-decoration: line-through; }
.plan-line input[type=checkbox] { width: 19px; height: 19px; accent-color: var(--gold); flex: 0 0 auto; margin: 0; }
.plan-line .pl-label { flex: 1 1 auto; min-width: 0; }
.plan-line .pl-label b { color: var(--gold); font-size: 14px; }
.plan-line .pl-unit { color: var(--text-dim); }
.plan-line .pl-step { display: flex; gap: 4px; flex: 0 0 auto; }
.plan-line .pl-step .btn { min-width: 30px; }

/* ============================================================ overlays === */
.sheet-host { position: fixed; inset: 0; z-index: 80; display: flex;
  align-items: flex-end; justify-content: center; }
.sheet-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.58); }
.sheet {
  position: relative; width: 100%; max-width: 620px;
  max-height: 88vh; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px 16px 0 0;
  padding-bottom: var(--safe-b);
  animation: sheet-up .18s ease;
}
@keyframes sheet-up { from { transform: translateY(14px); opacity: .6; } }
.sheet-grip { width: 38px; height: 4px; border-radius: 2px; background: var(--line);
  margin: 8px auto 0; }
.sheet-head { display: flex; align-items: center; gap: 8px; padding: 8px 12px 6px; }
.sheet-head h2 { margin: 0; font-size: 16px; }
.sheet-body { overflow-y: auto; padding: 4px 12px 16px; -webkit-overflow-scrolling: touch; }

.action-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 7px; }
.action-grid .btn { width: 100%; }
.sheet-section { margin-top: 16px; }
.sheet-section h3 {
  margin: 0 0 8px; font-size: 11.5px; letter-spacing: .9px;
  text-transform: uppercase; color: var(--text-faint);
}
.card-hero { display: flex; gap: 12px; margin-bottom: 6px; }
.card-hero img { width: 124px; border-radius: 8px; flex: 0 0 auto; background: #0d0f12; }
.card-hero-meta { min-width: 0; font-size: 13px; }
.card-hero-meta .chm-name { font-weight: 650; font-size: 15px; }
.card-hero-meta .chm-type { color: var(--text-dim); margin: 3px 0 6px; }
.card-hero-meta .chm-text { color: var(--text-dim); font-size: 12.5px;
  white-space: pre-wrap; max-height: 9.4em; overflow-y: auto; }

.zone-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--cw), 1fr));
  gap: 6px;
}
.counter-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.counter-row .cr-label { flex: 1 1 auto; font-size: 14px; }
.counter-row .cr-val { font: 700 17px/1 ui-monospace, Menlo, monospace;
  min-width: 2.4ch; text-align: center; }
.stepper { display: flex; gap: 5px; }
.stepper .btn { min-width: 42px; }
.life-big { font: 700 44px/1 ui-monospace, Menlo, monospace; text-align: center;
  color: var(--gold); margin: 2px 0 10px; }
.field { margin-bottom: 10px; }
.field label { display: block; font-size: 12.5px; color: var(--text-dim); margin-bottom: 4px; }
.field input, .field select, .field textarea {
  width: 100%; min-height: 42px; padding: 0 11px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px;
}
.field textarea { min-height: 64px; padding: 9px 11px; resize: vertical; }
.field-row { display: flex; gap: 8px; }
.field-row .field { flex: 1 1 0; }
.check-row { display: flex; align-items: center; gap: 10px; padding: 9px 0;
  border-top: 1px solid var(--line-soft); }
/* flex:0 0 auto or the longest label in the row squashes the box: a flex item
   defaults to shrinkable, so "First mulligan is free" came out narrower than
   its neighbours. */
.check-row input[type=checkbox] {
  width: 21px; height: 21px; flex: 0 0 auto; accent-color: var(--gold); margin: 0;
}
.check-row .cr-text { flex: 1 1 auto; font-size: 14px; }
.check-row .cr-text small { display: block; color: var(--text-faint); font-size: 12px; }

/* log drawer */
.drawer { position: fixed; inset: 0; z-index: 70; }
.drawer-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.5); }
.drawer-panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(400px, 92vw); display: flex; flex-direction: column;
  background: var(--bg-2); border-left: 1px solid var(--line);
  padding-top: var(--safe-t); padding-bottom: var(--safe-b);
  animation: drawer-in .18s ease;
}
@keyframes drawer-in { from { transform: translateX(18px); opacity: .5; } }
.drawer-head { display: flex; align-items: center; padding: 10px 12px;
  border-bottom: 1px solid var(--line); }
.drawer-head h2 { margin: 0; font-size: 16px; }
.digest {
  margin: 10px 12px; padding: 10px 11px;
  background: #241f14; border: 1px solid var(--gold-dim); border-radius: 10px;
  font-size: 13px;
}
.digest h3 { margin: 0 0 6px; font-size: 13px; color: var(--gold); }
.digest ul { margin: 0; padding-left: 17px; }
.log-list { flex: 1 1 auto; overflow-y: auto; padding: 8px 12px 12px; }
.log-line { font-size: 13px; padding: 5px 0; border-bottom: 1px solid var(--line-soft);
  color: var(--text-dim); }
.log-line .li { display: inline-block; width: 1.5em; font-size: 12px; opacity: .85; }
.log-line.k-turn { color: var(--gold); font-weight: 650; margin-top: 6px; }
.log-line.k-chat { color: var(--text); }
.log-line.k-step { color: var(--text-faint); }
/* Reactions sit in the log for the record, but muted -- they are chatter, and a
   run of them should never drown the account of what actually happened. */
.log-line.k-react { color: var(--text-faint); font-size: 15px; padding: 3px 0; }
.log-line .who { color: var(--text); font-weight: 600; }
.log-line .ts { color: var(--text-faint); font-size: 11px; margin-left: 5px; }
.log-line.is-new { border-left: 2px solid var(--gold); padding-left: 7px; margin-left: -9px; }
.chat-form { display: flex; gap: 7px; padding: 9px 12px;
  border-top: 1px solid var(--line); }
.chat-form input { flex: 1 1 auto; min-width: 0; min-height: 40px; padding: 0 11px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 9px; }

/* long-press zoom */
.peek { position: fixed; inset: 0; z-index: 95; display: grid; place-items: center;
  background: rgba(0,0,0,.78); padding: 20px; }
.peek img { max-width: min(92vw, 420px); max-height: 88vh; border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0,0,0,.6); }

/* toasts */
.toasts { position: fixed; left: 0; right: 0; bottom: calc(14px + var(--safe-b));
  z-index: 100; display: flex; flex-direction: column; align-items: center; gap: 7px;
  pointer-events: none; padding: 0 12px; }
.toast {
  max-width: 460px; padding: 10px 13px; border-radius: 10px;
  background: #2c323c; border: 1px solid var(--line); color: var(--text);
  font-size: 13.5px; box-shadow: 0 8px 24px rgba(0,0,0,.45);
  animation: toast-in .16s ease;
}
.toast.err { background: #3a1f1a; border-color: #6b3228; color: #f3a392; }
.toast.ok  { background: #1b2d22; border-color: #2f5a40; color: #a8e0c0; }
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } }

/* ====================================================== dice bubble === */
.dice-host {
  position: fixed; inset: 0; z-index: 92; display: grid; place-items: center;
  pointer-events: none;
}
.dice-bubble {
  background: rgba(20,22,26,.95); border: 2px solid var(--gold);
  border-radius: 20px; padding: 18px 30px; text-align: center;
  box-shadow: 0 20px 60px rgba(0,0,0,.6);
  animation: dice-pop .42s cubic-bezier(.2,1.4,.4,1);
}
@keyframes dice-pop {
  0%   { transform: scale(.4) rotate(-14deg); opacity: 0; }
  70%  { transform: scale(1.06) rotate(3deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}
.dice-bubble .dice-val {
  font: 800 54px/1 ui-monospace, Menlo, monospace; color: var(--gold);
}
.dice-bubble .dice-sub {
  font-size: 13px; color: var(--text-dim); margin-top: 6px;
}
.dice-bubble.fade { transition: opacity .3s, transform .3s; opacity: 0;
  transform: scale(.9); }

/* ====================================================== token picker === */
.token-tabs { display: flex; gap: 5px; overflow-x: auto; padding-bottom: 8px;
  scrollbar-width: none; }
.token-tabs::-webkit-scrollbar { display: none; }
.token-tab {
  flex: 0 0 auto; padding: 7px 12px; border-radius: 8px; font-size: 13px;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--text-dim);
}
.token-tab.is-on { background: var(--gold); border-color: var(--gold);
  color: #1a1305; font-weight: 650; }
.token-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 8px;
}
.token-pick {
  display: flex; flex-direction: column; gap: 4px; align-items: center;
  background: none; border: 0; padding: 0; color: inherit;
}
.token-pick img {
  width: 100%; aspect-ratio: 5 / 7; object-fit: cover;
  border-radius: 8px; border: 1px solid #000; background: #0d0f12;
}
.token-pick .tp-name {
  font-size: 11.5px; line-height: 1.15; text-align: center; color: var(--text-dim);
}
.token-pick.is-on img { box-shadow: 0 0 0 2px var(--gold); }
.count-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.count-chips .btn { flex: 0 0 auto; min-width: 46px; }
.token-search { position: relative; margin-bottom: 9px; }
.token-search input {
  width: 100%; min-height: 42px; padding: 0 34px 0 34px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 9px;
}
.token-search .ts-icon {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  color: var(--text-faint); font-size: 14px; pointer-events: none;
}
.token-search .ts-clear {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border: 0; background: none;
  color: var(--text-faint); font-size: 15px; border-radius: 7px;
}
.token-empty { color: var(--text-faint); font-size: 13.5px; padding: 14px 2px; }

/* ================================================== reactions === */
/* A reaction is a speech bubble pinned beside whoever sent it, not another line
   in the log -- loud enough to land, quiet enough to ignore. */
.bubble-slot { position: relative; flex: 0 0 auto; width: 0; height: 0; }
/* A reaction should read across the room, so it is sized like a gesture rather
   than like a label: a big emoji, a gold-rimmed bubble, and a bounce on the way
   in. It still sits beside whoever sent it and still leaves the log alone. */
.react-bubble {
  position: absolute; top: -10px; left: 0; z-index: 60;
  display: flex; align-items: center; gap: 9px; white-space: nowrap;
  padding: 10px 18px; border-radius: 22px;
  background: var(--surface-2); border: 2px solid var(--gold);
  box-shadow: 0 10px 30px rgba(0,0,0,.6), 0 0 22px rgba(216,160,58,.28);
  font-size: 16px; font-weight: 600; color: var(--text);
  animation: bubble-in .42s cubic-bezier(.18,1.5,.4,1);
  transform-origin: 22px bottom;
}
.react-bubble .rb-emoji {
  font-size: 40px; line-height: 1;
  animation: rb-pop .55s cubic-bezier(.2,1.7,.4,1);
}
.react-bubble::after {
  content: ""; position: absolute; left: 18px; bottom: -8px;
  width: 14px; height: 14px; background: var(--surface-2);
  border-right: 2px solid var(--gold); border-bottom: 2px solid var(--gold);
  transform: rotate(45deg);
}
.react-bubble.below { top: auto; bottom: -10px; transform-origin: 22px top; }
.react-bubble.below::after { bottom: auto; top: -8px;
  border: 0; border-left: 2px solid var(--gold); border-top: 2px solid var(--gold); }
@keyframes bubble-in { from { transform: translateY(10px) scale(.5); opacity: 0; } }
@keyframes rb-pop {
  0%   { transform: scale(.3) rotate(-18deg); }
  60%  { transform: scale(1.25) rotate(7deg); }
  100% { transform: scale(1) rotate(0); }
}
.react-bubble.fade { transition: opacity .4s, transform .4s;
  opacity: 0; transform: translateY(-14px) scale(.9); }
/* the picker tiles, matched to the new size */
.react-pick .rp-emoji { font-size: 32px; }

.react-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 8px;
}
.react-pick {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 10px 4px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--text-dim);
  font-size: 10.5px;
}
.react-pick .rp-emoji { font-size: 26px; line-height: 1; }

/* ================================================== interrupt toast === */
.interrupt-host {
  position: fixed; left: 0; right: 0; top: 0; z-index: 94;
  display: flex; justify-content: center; pointer-events: none;
  padding: calc(10px + var(--safe-t)) 12px 0;
}
.interrupt-card {
  display: flex; align-items: center; gap: 10px;
  background: #14314d; border: 2px solid var(--blue); border-radius: 13px;
  padding: 11px 16px; color: #dcecff; font-size: 14px; font-weight: 600;
  box-shadow: 0 14px 40px rgba(0,0,0,.55);
  animation: interrupt-in .3s cubic-bezier(.2,1.3,.4,1);
}
.interrupt-card .ic-emoji { font-size: 22px; }
@keyframes interrupt-in { from { transform: translateY(-18px); opacity: 0; } }
.interrupt-card.fade { transition: opacity .3s, transform .3s;
  opacity: 0; transform: translateY(-12px); }

/* ====================================================== wider screens === */
@media (min-width: 680px) {
  /* No --cw here. It used to be pinned to 78px on anything wider than a phone,
     which quietly beat the size control: only .side-opp re-derived it from
     --cw-base, so the opponent's board resized and your own board and hand did
     not. Card width has one source now, and the size control owns it. */
  .bf-strip { flex-wrap: wrap; overflow-x: visible; row-gap: 8px; }
  .hand-cards { flex-wrap: nowrap; }
  .toolbar { gap: 3px; }
  .tb-btn .tb-label { display: inline; }
  .tb-btn { padding: 0 10px; }
  .duel-blk { flex: 1 1 auto; }
  .duel-out { flex: 0 1 auto; margin-left: auto; }
  .combat { max-height: 40vh; }
}

/* Landscape / desktop: log becomes a permanent rail, table gets the rest. */
@media (min-width: 1000px) and (min-height: 560px) {
  .game-screen {
    grid-template-columns: minmax(0, 1fr) 340px;
    grid-template-rows: auto auto auto auto minmax(0, 1fr) auto auto auto;
  }
  /* A hidden grid item still leaves its track behind, so collapsing the rail
     has to remove the column as well as the drawer -- otherwise the board keeps
     staring at 340px of nothing. */
  .game-screen.log-hidden { grid-template-columns: minmax(0, 1fr); }
  .game-screen > *:not(.drawer) { grid-column: 1 / 2; }
  .drawer { position: static; grid-column: 2 / 3; grid-row: 1 / -1; }
  .drawer-backdrop { display: none; }
  .drawer-panel { position: static; width: auto; height: 100%; animation: none;
    border-left: 1px solid var(--line); }
  .sheet { border-radius: 16px; max-width: 560px; margin-bottom: 5vh; }
  .sheet-host { align-items: center; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
