/* ══════════════════════════════════════════════════════════
   Magistrate — Grimdark Arcane Design System
   Mobile-first, Android WebView optimised
   ══════════════════════════════════════════════════════════ */

/* ── Design Tokens ───────────────────────────────────────── */
:root {
  /* Backgrounds */
  --bg:        #08080d;
  --bg-1:      #0d0d13;
  --bg-2:      #121218;
  --bg-3:      #181821;
  --bg-4:      #20202b;
  --bg-5:      #292936;

  /* Borders */
  --border:    #2d2938;
  --border-2:  #433a56;

  /* Text */
  --t1:        #f4f0fb;
  --t2:        #aaa2b8;
  --t3:        #615b70;

  /* Accent — violet/purple primary */
  --accent:    #7c6cf8;
  --accent-l:  #9d91ff;
  --accent-d:  #5548c8;
  --accent-dim: rgba(124,108,248,.12);

  /* Semantic */
  --red:       #f43f5e;
  --red-dim:   rgba(244,63,94,.12);
  --green:     #10b981;
  --green-dim: rgba(16,185,129,.12);
  --amber:     #f59e0b;
  --amber-dim: rgba(245,158,11,.12);
  --blue:      #3b82f6;
  --blue-dim:  rgba(59,130,246,.12);
  --bone:      #f4f0fb;
  --gold:      #c9a85a;
  --gold-dim:  rgba(201,168,90,.12);
  --panel-grad: linear-gradient(180deg, rgba(22,21,31,.98), rgba(10,10,14,.98));

  /* Layout */
  --nav-h:     64px;
  --header-h:  56px;
  --safe-b:    env(safe-area-inset-bottom, 0px);
  --safe-t:    env(safe-area-inset-top, 0px);
  --safe-r:    env(safe-area-inset-right, 0px);
  --safe-l:    env(safe-area-inset-left, 0px);
  --radius:    12px;
  --radius-sm: 8px;
  --radius-xs: 5px;

  /* Typography */
  --font:      'Inter', -apple-system, sans-serif;
  --font-head: 'Space Grotesk', -apple-system, sans-serif;
  --font-brand:'Cinzel', Georgia, serif;
}

/* ── Reset ───────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  height: 100%;
  -webkit-text-size-adjust: 100%;
  touch-action: manipulation;
}
body {
  height: 100%;
  background:
    radial-gradient(circle at 50% -8%, rgba(124,108,248,.09), transparent 34%),
    var(--bg);
  color: var(--t1);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
button {
  cursor: pointer;
  font-family: var(--font);
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  border: none;
  background: none;
}
input, select, textarea {
  font-family: var(--font);
  -webkit-appearance: none;
  appearance: none;
}
img { display: block; }
::-webkit-scrollbar { width: 0; height: 0; display: none; }
::-webkit-scrollbar-thumb { background: transparent; }
.web-only { display: none !important; }
body.web-runtime .web-only { display: block !important; }
body.web-runtime .native-only { display: none !important; }

/* ── App shell ───────────────────────────────────────────── */
/* Use 100% (chains from html { height: 100% }) rather than 100dvh.
   On Android 15 (SDK 35) with edge-to-edge enforcement, dvh can
   over-report — the dynamic viewport height includes screen area
   that's not actually inside the WebView's render zone. With dvh,
   #app exceeds its parent body's actual layout height and content
   visually overshoots the bottom of the WebView, producing a black
   band where the player grid SHOULD be drawn but the device renders
   nothing because that area is outside the WebView. Switching to
   100% keeps #app exactly matched to body's real height. */
#app { height: 100%; display: flex; flex-direction: column; overflow: hidden; }

/* ── Auth screen ─────────────────────────────────────────── */
.auth-screen {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100%;
  padding: calc(2rem + var(--safe-t)) max(1.5rem, var(--safe-r))
           calc(2rem + var(--safe-b)) max(1.5rem, var(--safe-l));
  background:
    radial-gradient(circle at 50% 20%, rgba(124,108,248,.16), transparent 28%),
    radial-gradient(ellipse at 10% 10%, rgba(4,20,16,.85), transparent 42%),
    radial-gradient(ellipse at 85% 85%, rgba(0,0,0,.72), transparent 46%),
    linear-gradient(145deg, #020606 0%, #0d0b12 55%, #060608 100%);
  gap: 2rem;
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.auth-screen::before {
  content: '';
  position: absolute;
  inset: -18%;
  background:
    linear-gradient(90deg, transparent 49.5%, rgba(124,108,248,.10) 50%, transparent 50.5%),
    linear-gradient(0deg, transparent 49.5%, rgba(124,108,248,.05) 50%, transparent 50.5%);
  transform: rotate(-12deg);
  opacity: .42;
  pointer-events: none;
  z-index: -1;
}
.auth-screen::after {
  content: '';
  position: absolute;
  width: 360px;
  height: 520px;
  border: 1px solid rgba(124,108,248,.14);
  border-bottom: 0;
  border-radius: 180px 180px 0 0;
  top: 5%;
  left: 50%;
  transform: translateX(-50%);
  box-shadow: 0 0 80px rgba(0,0,0,.45) inset;
  pointer-events: none;
  z-index: -1;
}
.auth-screen.active { display: flex; }
.auth-brand { text-align: center; max-width: 420px; }
.auth-logo {
  width: 132px;
  height: 132px;
  margin: 0 auto .8rem;
  display: grid;
  place-items: center;
  filter: drop-shadow(0 0 28px rgba(124,108,248,.34)) drop-shadow(0 16px 28px rgba(0,0,0,.55));
}
.auth-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.auth-title {
  font-family: var(--font-brand);
  font-size: clamp(2rem, 11vw, 3.05rem);
  font-weight: 800;
  color: var(--t1);
  line-height: 1.15;
  letter-spacing: .075em;
  text-transform: uppercase;
  text-shadow: 0 2px 0 #000, 0 0 24px rgba(124,108,248,.22);
}
.auth-card {
  width: 100%;
  max-width: 400px;
  background: linear-gradient(180deg, rgba(19,19,26,.96), rgba(11,11,15,.96));
  border: 1px solid rgba(124,108,248,.22);
  border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: 0 20px 60px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.03);
}
.auth-provider-divider {
  display: flex;
  align-items: center;
  gap: .75rem;
  margin: 1rem 0;
  color: var(--t3);
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .08em;
}
.auth-provider-divider::before,
.auth-provider-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(214,207,238,.18), transparent);
}
.btn-google {
  width: 100%;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  border: 1px solid rgba(214,207,238,.22);
  border-radius: var(--radius-xs);
  background: rgba(246,244,255,.96);
  color: #15151b;
  font-weight: 700;
  font-size: .9rem;
  box-shadow: 0 10px 24px rgba(0,0,0,.22);
  transition: transform .12s ease, filter .12s ease;
}
.btn-google:active { transform: scale(.99); }
.btn-google:disabled { opacity: .7; }
.google-g {
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #fff;
  color: #4285f4;
  font-family: Arial, sans-serif;
  font-size: .95rem;
  font-weight: 800;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
}
.auth-legal {
  margin-top: .85rem;
  text-align: center;
  font-size: .78rem;
}
.auth-err {
  color: var(--red);
  font-size: .82rem;
  text-align: center;
  margin-top: .75rem;
  display: none;
  background: var(--red-dim);
  border-radius: var(--radius-xs);
  padding: .5rem .75rem;
}

/* ── App header ──────────────────────────────────────────── */
#app-header {
  /* The header has a fixed content area (--header-h) PLUS the OS safe area
     pushed in via padding-top. Setting only padding without growing the
     box was wrong — content would overflow into the safe area on edge-to-
     edge devices. */
  min-height: calc(var(--header-h) + var(--safe-t));
  padding: var(--safe-t) max(1rem, var(--safe-r)) 0 max(1rem, var(--safe-l));
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Solid background-color (not background shorthand) ensures no
     transparency. The header's children all paint on top, so content
     scrolling below the header never appears to bleed through. */
  background:
    linear-gradient(180deg, rgba(18,18,25,.98), rgba(9,9,13,.98));
  border-bottom: 1px solid var(--border);
  isolation: isolate;
  flex-shrink: 0;
  z-index: 10;
}
.header-left { display: flex; align-items: center; gap: .6rem; }
.header-logo {
  width: 28px;
  height: 28px;
  display: inline-grid;
  place-items: center;
  filter: drop-shadow(0 0 10px rgba(124,108,248,.28));
}
.header-logo img { width: 100%; height: 100%; object-fit: contain; }
.header-title {
  font-family: var(--font-brand);
  font-size: 1.02rem;
  font-weight: 800;
  color: var(--t1);
  letter-spacing: .08em;
  text-transform: uppercase;
}
.header-right { display: flex; align-items: center; gap: .5rem; }
.icon-action {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--bg-3);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 1rem;
  color: var(--t2);
  transition: all .15s;
  touch-action: manipulation;
}
.icon-action:active { background: var(--bg-4); color: var(--t1); }
.rune-icon,
.nav-icon,
.ghi-icon,
.qa-icon,
.pending-banner-icon,
.notif-emoji,
.elim-icon {
  font-family: var(--font-brand);
  font-weight: 800;
  line-height: 1;
}
.user-avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--accent-dim);
  border: 1.5px solid var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem;
  font-weight: 700;
  color: var(--accent-l);
  cursor: pointer;
  touch-action: manipulation;
  text-transform: uppercase;
}

/* ── App shell / screen container ────────────────────────── */
#app-shell { display: flex; flex-direction: column; height: 100%; min-height: 0; }
#screen-container {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding-bottom: calc(var(--nav-h) + var(--safe-b) + 1rem);
}

/* ── Screens ─────────────────────────────────────────────── */
.screen {
  display: none;
  padding: 1rem max(1rem, var(--safe-r)) 1rem max(1rem, var(--safe-l));
}
.screen.active { display: block; }
.auth-screen.active { display: flex; }

/* ── AdMob banner-aware layout ───────────────────────────── */
/* Approach: the native AdMob banner sits FLUSH to the device bottom
   edge (margin: 0 passed to the plugin). The bottom nav is lifted up
   by --ad-banner-h via the body.ad-banner-visible selector so the nav
   remains visible above the banner.

   Why this works: the AdMob plugin resizes the WebView to make room
   for the banner ONLY when margin == 0. With a non-zero margin, the
   plugin overlays the banner on top of the WebView, hiding any DOM
   content (including the nav) at that screen position. So flush-bottom
   + CSS nav-lift is the only architecture that reliably keeps both
   visible.

   --ad-banner-h is set initially to 60px as a worst-case adaptive
   banner height, then overridden at runtime by the plugin's
   SizeChanged event with the actual rendered height. */
:root { --ad-banner-h: 60px; }

body.ad-banner-visible #app-nav {
  bottom: var(--ad-banner-h);
}
body.ad-banner-visible #screen-container {
  padding-bottom: calc(var(--nav-h) + var(--safe-b) + var(--ad-banner-h) + 1rem);
}

/* Smooth slide animation when the banner appears/disappears (entering
   or leaving an active game). Gated by body.ad-transitions-ready so
   the very first banner appearance on app load doesn't animate from
   bottom: 0 — that would look like a layout glitch. ads.js adds the
   class after the first frame settles. The cubic-bezier matches
   Material's "standard easing" curve for natural motion. */
body.ad-transitions-ready #app-nav {
  transition: bottom 280ms cubic-bezier(0.4, 0, 0.2, 1);
}
body.ad-transitions-ready #screen-container {
  transition: padding-bottom 280ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Accessibility: when the user has set their OS preference to reduce
   motion (Android Settings → Accessibility → Remove animations, or
   the equivalent on other platforms), disable layout-shift animations
   that can trigger vestibular issues. The nav still moves to its new
   position when the banner shows/hides — it just snaps there instantly
   rather than sliding. Following the Web Content Accessibility
   Guidelines (WCAG 2.3.3) and the Android accessibility guide. */
@media (prefers-reduced-motion: reduce) {
  body.ad-transitions-ready #app-nav,
  body.ad-transitions-ready #screen-container {
    transition: none;
  }
}

/* ── Bottom nav ──────────────────────────────────────────── */
#app-nav {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  height: calc(var(--nav-h) + var(--safe-b));
  padding: 0 var(--safe-r) var(--safe-b) var(--safe-l);
  background:
    linear-gradient(180deg, rgba(18,18,25,.98), rgba(9,9,13,.98));
  border-top: 1px solid var(--border);
  isolation: isolate;
  display: flex;
  align-items: stretch;
  z-index: 20;
}

/* Visual extension below the nav. When the nav is lifted by the ad
   banner (body.ad-banner-visible #app-nav { bottom: var(--ad-banner-h) }),
   the area BETWEEN the nav's bottom edge and the top of the ad would
   otherwise expose the WebView's scrollable content underneath — which
   can perceptually flicker as the user scrolls AND can be visible even
   while still, depending on scroll position and ad load timing.

   This ::after pseudo extends the nav background DOWNWARD from the
   nav's own bottom edge all the way to bottom: 0 (device edge). The
   native AdMob banner then draws on top of this pseudo-element rather
   than directly on top of WebView content, eliminating any chance of
   content showing through the gap.

   Accessibility note: content showing through a fixed nav (even briefly)
   is a known trigger for motion-sensitive users — vestibular issues
   and migraines in particular. This pseudo-element is the defensive
   barrier that prevents the issue regardless of ad timing or layout
   edge cases. */
#app-nav::after {
  content: '';
  position: absolute;
  top: 100%;     /* immediately below the nav's bottom edge */
  left: 0;
  right: 0;
  /* Cover the entire region from nav bottom down to device bottom,
     even if the ad is short or fails to load. ad-banner-h is the
     reserved height; +safe-b covers the gesture-pill safe area. */
  height: calc(var(--ad-banner-h) + var(--safe-b));
  background-color: var(--bg-2);
  pointer-events: none;
  z-index: -1;   /* sits behind nav children but in front of WebView */
}
/* When the banner isn't visible, the nav sits at bottom: 0 so there's
   nothing for the pseudo to cover. Hiding it avoids painting a strip
   that would extend off-screen. */
body:not(.ad-banner-visible) #app-nav::after {
  display: none;
}
.nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .2rem;
  color: var(--t3);
  font-size: .62rem;
  font-weight: 500;
  letter-spacing: .3px;
  transition: color .15s;
  touch-action: manipulation;
  padding: .3rem;
}
.nav-icon { font-size: 1.14rem; line-height: 1; }
.nav-label {
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.nav-item.active { color: var(--accent-l); }
.nav-item:active  { opacity: .7; }

/* ── Typography helpers ──────────────────────────────────── */
.screen-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.25rem;
}
.screen-title {
  font-family: var(--font-brand);
  font-size: 1.24rem;
  font-weight: 800;
  color: var(--t1);
  letter-spacing: .08em;
  text-transform: uppercase;
}
.screen-sub { color: var(--t2); font-size: .85rem; margin-top: .15rem; }
.section-label {
  font-size: .7rem;
  font-weight: 600;
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: .6rem;
  display: block;
}
.fw-600 { font-weight: 600; }

/* ── Form elements ───────────────────────────────────────── */
.field { margin-bottom: 1rem; }
.field label, label {
  display: block;
  font-size: .72rem;
  font-weight: 600;
  color: var(--t2);
  text-transform: uppercase;
  letter-spacing: .8px;
  margin-bottom: .4rem;
}
input[type=text], input[type=email], input[type=password],
input[type=number], select, textarea {
  width: 100%;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--t1);
  font-family: var(--font);
  font-size: .95rem;
  padding: .65rem .85rem;
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
input::placeholder, textarea::placeholder { color: var(--t3); }
select option { background: var(--bg-3); }
textarea { resize: vertical; }

/* ── Buttons ─────────────────────────────────────────────── */
.btn-primary {
  display: block;
  width: 100%;
  padding: .8rem;
  background: linear-gradient(180deg, var(--accent-l), var(--accent-d));
  border: 1px solid rgba(180, 156, 255, .32);
  border-radius: var(--radius-sm);
  color: #fff;
  font-family: var(--font);
  font-size: .9rem;
  font-weight: 600;
  letter-spacing: .02em;
  transition: opacity .15s, transform .1s;
  touch-action: manipulation;
}
.btn-primary:active { opacity: .85; transform: scale(.99); }
.btn-primary:disabled { opacity: .4; }

.btn-ghost {
  display: block;
  width: 100%;
  padding: .7rem;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--t2);
  font-size: .88rem;
  font-weight: 500;
  transition: all .15s;
  touch-action: manipulation;
  margin-top: .6rem;
  text-align: center;
}
.btn-ghost:active { border-color: var(--border-2); color: var(--t1); }

.btn-sm {
  padding: .45rem .9rem;
  background: var(--bg-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  color: var(--t2);
  font-size: .78rem;
  font-weight: 500;
  transition: all .15s;
  touch-action: manipulation;
}
.btn-sm:active { border-color: var(--accent); color: var(--accent-l); }

.btn-icon {
  width: 32px; height: 32px;
  border-radius: var(--radius-xs);
  background: var(--bg-4);
  border: 1px solid var(--border);
  color: var(--t2);
  display: flex; align-items: center; justify-content: center;
  font-size: .85rem;
  transition: all .12s;
  touch-action: manipulation;
  flex-shrink: 0;
}
.btn-icon:active { background: var(--bg-5); color: var(--t1); }
.btn-icon.danger { color: var(--red); border-color: transparent; }

/* ── Tab bar ─────────────────────────────────────────────── */
.tab-bar {
  display: flex;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 3px;
  gap: 3px;
  margin-bottom: 1.25rem;
}
.tab {
  flex: 1;
  padding: .5rem;
  border-radius: 6px;
  color: var(--t3);
  font-size: .8rem;
  font-weight: 500;
  transition: all .15s;
  text-align: center;
  touch-action: manipulation;
}
.tab.active { background: var(--bg-5); color: var(--t1); box-shadow: 0 1px 3px rgba(0,0,0,.3); }

/* ── Cards / surfaces ────────────────────────────────────── */
.card {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.card-body { padding: 1rem; }

.info-box {
  background: var(--accent-dim);
  border: 1px solid rgba(124,108,248,.25);
  border-radius: var(--radius-sm);
  padding: .75rem 1rem;
  font-size: .84rem;
  color: var(--t2);
  line-height: 1.55;
}
.info-box strong { color: var(--t1); }

.badge {
  display: inline-flex;
  align-items: center;
  padding: .2rem .55rem;
  background: var(--bg-4);
  border: 1px solid var(--border);
  border-radius: 20px;
  font-size: .7rem;
  font-weight: 600;
  color: var(--t2);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.badge.green { background: var(--green-dim); border-color: rgba(16,185,129,.3); color: var(--green); }
.badge.red   { background: var(--red-dim);   border-color: rgba(244,63,94,.3);  color: var(--red); }
.badge.amber { background: var(--amber-dim); border-color: rgba(245,158,11,.3); color: var(--amber); }
.badge.accent{ background: var(--accent-dim);border-color: rgba(124,108,248,.3);color: var(--accent-l); }
.badge.format-oath { background: rgba(180, 83, 9, 0.15); border-color: rgba(180, 83, 9, 0.4); color: #fbbf24; }

/* ── Home screen ─────────────────────────────────────────── */
.home-hero {
  padding: .5rem 0 1.25rem;
}
.home-greeting { font-size: .85rem; color: var(--t3); margin-bottom: .1rem; }
.home-name {
  font-family: var(--font-brand);
  font-size: 1.8rem;
  font-weight: 800;
  color: var(--t1);
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.1;
}

/* "Remove ads" pill shown under the welcome name for free-tier users.
   Visually subtle: small, low contrast, tinted with the accent so it
   reads as an option rather than an interruption. Hidden entirely for
   paid users (UI renders empty string). */
.home-premium-pill {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  margin-top: .65rem;
  padding: .35rem .7rem;
  font-size: .72rem;
  font-weight: 600;
  color: var(--accent-l);
  background: rgba(124, 108, 248, .1);
  border: 1px solid rgba(124, 108, 248, .25);
  border-radius: 999px;
  cursor: pointer;
  transition: background 150ms ease;
}
.home-premium-pill:hover,
.home-premium-pill:active {
  background: rgba(124, 108, 248, .2);
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: .5rem;
  margin-bottom: 1.25rem;
}
.stat-tile {
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .85rem .5rem;
  text-align: center;
}
.stat-val {
  font-family: var(--font-brand);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--t1);
  line-height: 1;
  display: block;
}
.stat-lbl {
  font-size: .6rem;
  font-weight: 500;
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: .6px;
  margin-top: .25rem;
  display: block;
}

.home-section { margin-bottom: 1.25rem; }

.form-track { display: flex; gap: .4rem; }
.form-pip {
  width: 30px; height: 30px;
  border-radius: var(--radius-xs);
  display: flex; align-items: center; justify-content: center;
  font-size: .75rem;
  font-weight: 700;
}
.form-pip.W { background: var(--green-dim); color: var(--green); }
.form-pip.L { background: var(--red-dim);   color: var(--red); }

.quick-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .75rem;
  margin-bottom: 1.25rem;
}
.quick-action {
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  display: flex;
  align-items: center;
  gap: .75rem;
  transition: border-color .15s;
  touch-action: manipulation;
  cursor: pointer;
}
.quick-action:active { border-color: var(--accent); }
.qa-icon {
  width: 40px; height: 40px;
  border-radius: var(--radius-sm);
  background: var(--accent-dim);
  border: 1px solid rgba(180, 156, 255, .22);
  color: var(--accent-l);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.2rem;
  flex-shrink: 0;
}
.qa-label { font-size: .88rem; font-weight: 600; color: var(--t1); }
.qa-sub   { font-size: .72rem; color: var(--t3); margin-top: .1rem; }

.fav-deck-row {
  display: flex;
  align-items: center;
  gap: .85rem;
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .85rem;
  cursor: pointer;
  touch-action: manipulation;
  transition: border-color .12s, background .12s;
}
.fav-deck-row:active {
  background: var(--bg-3);
  border-color: var(--accent);
}
.fav-deck-info {
  flex: 1;
  min-width: 0;
}
.fav-deck-arrow {
  flex-shrink: 0;
  color: var(--t3);
  font-size: 1.4rem;
  font-weight: 300;
  padding: 0 .25rem;
}
.fav-deck-art {
  width: 48px; height: 64px;
  border-radius: var(--radius-xs);
  object-fit: cover;
  background: var(--bg-4);
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--t3); font-size: 1.2rem;
}
.fav-deck-name { font-weight: 600; font-size: .92rem; color: var(--t1); }
.fav-deck-cmd  { font-size: .78rem; color: var(--t2); margin-top: .15rem; }
.fav-deck-wr   { font-size: .75rem; color: var(--t3); margin-top: .25rem; }

/* Brief highlight when scrolling a deck tile into view (favourite-deck tap) */
@keyframes deckTileFlash {
  0%   { box-shadow: 0 0 0 0 var(--accent), 0 0 0 0 var(--accent-dim); }
  30%  { box-shadow: 0 0 0 3px var(--accent), 0 0 18px 4px var(--accent-dim); }
  100% { box-shadow: 0 0 0 0 transparent, 0 0 0 0 transparent; }
}
.deck-tile-highlight {
  animation: deckTileFlash 1.6s ease-out;
}

/* Getting Started / app guide */
.getting-started {
  display: flex;
  flex-direction: column;
  gap: .65rem;
}
.gs-step {
  display: flex;
  align-items: center;
  gap: .85rem;
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .8rem;
}
.gs-step-num {
  width: 28px; height: 28px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent-dim);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700;
  font-size: .85rem;
}
.gs-step-body { flex: 1; min-width: 0; }
.gs-step-title {
  font-weight: 600;
  font-size: .88rem;
  color: var(--t1);
}
.gs-step-sub {
  font-size: .76rem;
  color: var(--t3);
  margin-top: .2rem;
  line-height: 1.45;
}
.gs-tip {
  background: var(--bg-3);
  border: 1px dashed var(--border-2);
  border-radius: var(--radius-sm);
  padding: .7rem .8rem;
  font-size: .76rem;
  color: var(--t2);
  line-height: 1.55;
  margin-top: .35rem;
}
.gs-tip strong { color: var(--t1); }

.guide-modal {
  max-width: 620px;
}
.guide-list {
  display: flex;
  flex-direction: column;
  gap: .65rem;
}
.guide-list.compact {
  gap: .6rem;
}
.guide-step {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) auto;
  align-items: center;
  gap: .8rem;
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .85rem;
}
.guide-step-num {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--accent-dim);
  color: var(--accent-l);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .82rem;
  font-weight: 800;
  flex-shrink: 0;
}
.guide-step-body {
  min-width: 0;
}
.guide-step-title {
  color: var(--t1);
  font-weight: 700;
  font-size: .9rem;
}
.guide-step-sub {
  color: var(--t2);
  font-size: .78rem;
  line-height: 1.5;
  margin-top: .22rem;
}
.guide-step-action {
  align-self: center;
  white-space: nowrap;
}
.guide-actions {
  display: grid;
  margin-top: .75rem;
}
.guide-note {
  margin-top: .85rem;
  padding: .75rem .85rem;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border-2);
  background: var(--bg-3);
  color: var(--t2);
  font-size: .78rem;
  line-height: 1.5;
}

@media (max-width: 520px) {
  .guide-step {
    grid-template-columns: 28px minmax(0, 1fr);
  }
  .guide-step-action {
    grid-column: 2;
    justify-self: start;
  }
}

/* Coaching insights */
.insight-card {
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .9rem;
  margin-bottom: .6rem;
}
.insight-header { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: .4rem; gap: .5rem; }
.insight-title { font-weight: 600; font-size: .88rem; color: var(--t1); flex: 1; }
.insight-body  { font-size: .82rem; color: var(--t2); line-height: 1.55; }
.insight-cards { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .5rem; }
.card-pill {
  /* Was inline span with no tap affordance. Now usable as a tappable
     "open this card" pill — see ui.openCardByName. The size and
     colors stay close to the original so existing layouts aren't
     disrupted; the changes are: cursor: pointer, transition for
     press feedback, slightly larger padding for a touch-comfortable
     tap target. */
  display: inline-block;
  font-size: .7rem;
  background: var(--bg-4);
  border: 1px solid var(--border);
  border-radius: 20px;
  /* Padding bumped slightly so the tap target meets ~32px tall on
     phone DPRs. Previous .2rem .55rem was visually fine but cramped
     for thumbs. */
  padding: .3rem .65rem;
  margin: .1rem .15rem .1rem 0;
  color: var(--t2);
  cursor: pointer;
  /* Prevent double-tap zoom; the only intended action is "open card". */
  touch-action: manipulation;
  transition: background .12s, border-color .12s, color .12s, transform .08s;
  /* Long names like "Malevolent Hermit // Benevolent Geist" can be
     long; allow them to wrap naturally rather than clipping. Pills
     that exceed one row's width still display the full name. */
  max-width: 100%;
  vertical-align: middle;
  line-height: 1.3;
}
.card-pill:active {
  background: var(--bg-3);
  border-color: var(--accent);
  color: var(--accent-l);
  transform: scale(.97);
}
@media (hover: hover) {
  .card-pill:hover {
    border-color: var(--accent);
    color: var(--accent-l);
  }
}

/* ── Setup screen ────────────────────────────────────────── */
.count-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .85rem 1rem;
  margin-bottom: 1rem;
}
.count-label { font-weight: 600; color: var(--t1); font-size: .92rem; }
.count-ctrl  { display: flex; align-items: center; gap: .75rem; }
.count-btn {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--bg-4);
  border: 1px solid var(--border);
  color: var(--t1);
  font-size: 1.1rem;
  display: flex; align-items: center; justify-content: center;
  touch-action: manipulation;
  transition: all .12s;
}
.count-btn:active { background: var(--accent-dim); border-color: var(--accent); color: var(--accent-l); }
.count-val {
  font-family: var(--font-head);
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--t1);
  min-width: 2ch;
  text-align: center;
}

.player-config { display: flex; flex-direction: column; gap: .6rem; }
.setup-row {
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .75rem;
}
.setup-row-top {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-bottom: .5rem;
}
/* Player name row — sits ABOVE the deck/link row so the name doesn't get
   visually crowded out by the deck dropdown. Important for large pods
   where you need to glance at "who is this?" quickly. */
.setup-row-name {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-bottom: .55rem;
}
.setup-row-name .setup-name-input {
  font-size: .98rem;
  font-weight: 600;
}
.setup-num {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--accent-dim);
  color: var(--accent-l);
  font-size: .7rem;
  font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.setup-name-input {
  flex: 1;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding: .25rem .1rem;
  font-size: .92rem;
  color: var(--t1);
}
.setup-name-input:focus { border-color: var(--accent); outline: none; box-shadow: none; }
.setup-deck-sel {
  font-size: .78rem;
  padding: .3rem .5rem;
  width: auto;
  max-width: 130px;
  background: var(--bg-4);
}
.setup-cmd-input { font-size: .88rem; }

.setup-live-sync-row {
  margin-top: 1rem;
}
.setup-live-sync-toggle {
  display: flex;
  align-items: stretch;
  gap: .7rem;
  background: linear-gradient(180deg, rgba(35, 30, 58, .88), rgba(16, 15, 24, .96));
  border: 1px solid rgba(124, 108, 248, .34);
  border-radius: var(--radius);
  padding: .8rem .9rem;
  cursor: pointer;
}
.setup-live-sync-toggle input {
  width: 1.1rem;
  height: 1.1rem;
  margin-top: .18rem;
  flex: 0 0 auto;
  border: 1px solid var(--border-2);
  border-radius: 5px;
  background: var(--bg-3);
}
.setup-live-sync-toggle input:checked {
  background: var(--accent);
  border-color: var(--accent-l);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
.setup-live-sync-shell {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: .12rem;
}
.setup-live-sync-title {
  color: var(--t1);
  font-size: .88rem;
  font-weight: 800;
}
.setup-live-sync-sub {
  color: var(--t2);
  font-size: .74rem;
  line-height: 1.35;
}

/* Format dropdown on game-setup landing — same general aesthetic as the
   stats deck filter so it reads as a "high-level toggle". */
.setup-format-sel {
  background: var(--bg-3);
  color: var(--t1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .35rem .6rem;
  font-size: .82rem;
  font-family: var(--font);
  cursor: pointer;
  touch-action: manipulation;
}
.setup-format-sel:focus {
  outline: none;
  border-color: var(--accent);
}

/* ── Game screen ─────────────────────────────────────────── */
.game-screen { padding: .75rem; }
/* ── Center command rail ──────────────────────────────────────────────
   The landscape grid reserves a real lane between the top and bottom
   player rows. This rail sits in that lane, so menu and turn controls
   do not cover player card content. */
.game-hub {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 18;
  display: flex;
  align-items: center;
  gap: .35rem;
  max-width: min(94vw, 760px);
  padding: .28rem;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 999px;
  background: rgba(18, 18, 24, .9);
  box-shadow:
    0 10px 30px rgba(0,0,0,.46),
    0 0 0 2px rgba(10, 15, 30, .72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  pointer-events: auto;
  --active-player-color: var(--accent);
  --active-player-color-rgb: 124, 108, 248;
}
.game-hub-main {
  display: flex;
  align-items: center;
  gap: .4rem;
  min-width: 0;
}
.game-hub-status {
  display: flex;
  align-items: center;
  gap: .45rem;
  min-width: 0;
  padding: 0 .2rem;
  color: var(--t2);
  font-size: .68rem;
  font-weight: 800;
  white-space: nowrap;
}
.game-hub-round-label {
  color: var(--active-player-color);
  font-variant-numeric: tabular-nums;
}
.game-hub-icon {
  font-family: var(--font-head);
  font-size: .92rem;
  font-weight: 900;
}
.game-hub-active {
  max-width: 128px;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--t1);
}
.game-hub.has-seat-color .game-hub-active {
  color: var(--active-player-color);
}
.game-hub-active:empty { display: none; }
.game-hub-btn,
.game-hub-state-btn,
.game-hub-live-btn,
.game-hub-next {
  min-height: 34px;
  border-radius: 999px;
  padding: 0 .7rem;
  border: 1px solid var(--border);
  background: var(--bg-3);
  color: var(--t1);
  font-size: .68rem;
  font-weight: 800;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .28rem;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform .12s, background .12s, border-color .12s;
}
.game-hub-btn:active,
.game-hub-state-btn:active,
.game-hub-live-btn:active,
.game-hub-next:active,
.game-hub-item:active {
  transform: scale(.96);
}
.game-hub.open .game-hub-btn {
  border-color: var(--active-player-color);
  background: rgba(var(--active-player-color-rgb), .18);
}
.game-hub-state-btn {
  color: var(--accent-l);
  border-color: rgba(124, 108, 248, .34);
  background: rgba(124, 108, 248, .10);
}
.game-hub-state-btn.has-active {
  border-color: rgba(124, 108, 248, .7);
  background: linear-gradient(180deg, rgba(124, 108, 248, .28), rgba(124, 108, 248, .12));
  color: var(--t1);
}
.game-hub-live-btn {
  color: var(--green);
  border-color: rgba(16, 185, 129, .4);
  background: rgba(16, 185, 129, .10);
}
.game-hub-live-btn.host {
  color: var(--accent-l);
  border-color: rgba(124, 108, 248, .52);
  background: rgba(124, 108, 248, .12);
}
.game-hub-live-btn.pending {
  color: var(--amber);
  border-color: rgba(245, 158, 11, .5);
  background: rgba(245, 158, 11, .12);
}
.game-hub-state-count {
  min-width: 1rem;
  height: 1rem;
  border-radius: 999px;
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: white;
  font-size: .55rem;
  line-height: 1;
}
.game-hub-state-count:not(:empty) {
  display: inline-flex;
}
.game-hub-states {
  display: flex;
  align-items: center;
  gap: .24rem;
  max-width: min(34vw, 280px);
  overflow: hidden;
}
.game-hub-state-chip {
  appearance: none;
  cursor: pointer;
  min-height: 26px;
  max-width: 126px;
  padding: 0 .45rem 0 .25rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(255, 255, 255, .04);
  color: var(--t2);
  display: inline-flex;
  align-items: center;
  gap: .24rem;
  font-size: .6rem;
  font-weight: 800;
  white-space: nowrap;
  flex: 0 1 auto;
}
.game-hub-state-chip.day {
  border-color: rgba(245, 158, 11, .42);
  color: var(--amber);
  background: rgba(245, 158, 11, .10);
}
.game-hub-state-chip.night {
  border-color: rgba(124, 108, 248, .48);
  color: var(--accent-l);
  background: rgba(124, 108, 248, .12);
}
.game-hub-state-chip.monarch {
  border-color: rgba(201, 168, 90, .45);
  color: var(--gold);
}
.game-hub-state-chip.initiative {
  border-color: rgba(86, 180, 233, .44);
  color: var(--blue);
}
.game-hub-state-mark {
  width: 1rem;
  height: 1rem;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .08);
  color: currentColor;
  font-size: .52rem;
  flex: 0 0 auto;
}
.game-hub-state-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.game-hub-next {
  border-color: rgba(var(--active-player-color-rgb), .58);
  background: linear-gradient(180deg, rgba(var(--active-player-color-rgb), .30), rgba(var(--active-player-color-rgb), .16));
  color: var(--t1);
}
.game-hub-menu-icon {
  font-size: .78rem;
  line-height: 1;
}

/* The opened menu is an inline extension of the rail, not a floating
   panel over player cards. It uses clear labels and keeps destructive
   End last. */
.game-hub-menu {
  display: flex;
  align-items: center;
  gap: .25rem;
  max-width: 0;
  opacity: 0;
  visibility: hidden;
  overflow: hidden;
  pointer-events: none;
  transition: max-width .18s ease-out, opacity .14s, visibility 0s linear .14s;
}
.game-hub.open .game-hub-menu {
  max-width: 420px;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: max-width .18s ease-out, opacity .14s;
}
.game-hub.open .game-hub-menu::before {
  content: "";
  width: 1px;
  height: 26px;
  margin: 0 .08rem;
  background: var(--border);
  flex-shrink: 0;
}
.game-hub-item {
  min-height: 34px;
  min-width: 50px;
  padding: 0 .46rem;
  border-radius: 999px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--t2);
  font-size: .62rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .2rem;
  cursor: pointer;
  white-space: nowrap;
  touch-action: manipulation;
}
.game-hub-item:active {
  background: var(--bg-3);
  border-color: var(--border);
  color: var(--t1);
}
.game-hub-item.danger {
  color: var(--red);
}
.game-hub-item.danger:active { background: var(--red-dim); }
.ghi-icon {
  font-size: .82rem;
  line-height: 1;
}
.ghi-label {
  line-height: 1;
}
@media (max-width: 720px) {
  .game-hub {
    max-width: min(98vw, 760px);
  }
  .game-hub-main {
    gap: .28rem;
  }
  .game-hub-state-btn,
  .game-hub-btn,
  .game-hub-live-btn,
  .game-hub-next {
    padding: 0 .55rem;
  }
  .game-hub-states {
    max-width: 22vw;
  }
  .game-hub-state-chip {
    max-width: 34px;
    padding: 0 .24rem;
  }
  .game-hub-state-text {
    display: none;
  }
}

/* In-game screen needs a positioning context for the hub */
#game-screen.active {
  position: relative;
  background:
    radial-gradient(circle at 50% 50%, rgba(32, 26, 48, .48), transparent 64%),
    linear-gradient(135deg, rgba(201, 168, 90, .04), transparent 42%),
    var(--bg);
}

/* Turn track */
.turn-track {
  display: flex;
  gap: .4rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: .6rem;
}
.turn-pip {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--bg-3);
  border: 1.5px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: .6rem;
  font-weight: 600;
  color: var(--t3);
  touch-action: manipulation;
  cursor: pointer;
  transition: all .15s;
  user-select: none;
}
.turn-pip.current { border-color: var(--accent); background: var(--accent-dim); color: var(--accent-l); }
.turn-pip.elim    { opacity: .3; border-style: dashed; }

/* ── Players grid ────────────────────────────────────────── */
.players-grid {
  display: grid;
  gap: .55rem;
  grid-template-columns: 1fr;
}
@media (min-width:480px) {
  .players-grid.cols-2,.players-grid.cols-3,
  .players-grid.cols-4,.players-grid.cols-5,
  .players-grid.cols-6,.players-grid.cols-7,
  .players-grid.cols-8 { grid-template-columns: 1fr 1fr; }
}
@media (min-width:900px) {
  .players-grid.cols-3,.players-grid.cols-6 { grid-template-columns: repeat(3,1fr); }
  .players-grid.cols-4,.players-grid.cols-8 { grid-template-columns: repeat(2,1fr); }
}

/* ── In-game chrome hiding ──────────────────────────────────────────────
   When a game is active (body.game-active set by lockGameOrientation),
   the global header (logo / search / notifications) and bottom nav tabs
   are hidden so the player cards have all the available space. The
   in-game header (turn info + Menu / Log / Next / Dice / End) provides
   the navigation needed during play, including the Menu button to leave
   without ending the game. */
body.game-active #app-header,
body.game-active #app-nav {
  display: none !important;
}
/* Reclaim the bottom padding that was reserved for the fixed nav.
   !important is defensive — the base #screen-container rule sets
   padding-bottom: calc(nav-h + safe-b + 1rem) which reserves space
   for the bottom nav that we've hidden during gameplay. We want zero
   bottom padding in game-active regardless of base or override order. */
body.game-active #screen-container {
  padding-bottom: 0 !important;
  height: 100%;
  overflow: hidden !important;
}
/* Force the ad-banner-visible padding to zero during active gameplay.
   The ads.js module hides the banner on screen-change to 'game', but
   the body class may still be applied during the transition or in any
   edge case where the screen-change handler hasn't fired yet. This
   override ensures the player grid always fills the screen during
   gameplay — no black bar from leftover banner padding. */
body.game-active.ad-banner-visible #screen-container {
  padding-bottom: 0 !important;
}

/* ── In-game landscape layout ──────────────────────────────────────────
   Driven by `body.in-landscape` which JS sets when the game becomes
   active. The native Capacitor ScreenOrientation plugin lock guarantees
   the device is actually landscape by the time CSS layout matters, so
   no JS-side viewport detection or CSS rotation hacks are needed. We
   render the game in a landscape-shaped layout: seats spread
   horizontally with rotated top-row cards. */
body.in-landscape {
  /* Make the game screen fill the viewport so the grid has height to expand into.
     When Capacitor 8 edge-to-edge is active the WebView extends under the
     system bars; using env(safe-area-inset-*) keeps player cards safely
     visible while the WebView background fills the full screen.

     On Samsung devices, the gesture pill in landscape orientation sits
     on the RIGHT EDGE (not the bottom). Some Android WebView versions
     incorrectly report a non-zero safe-area-inset-bottom in landscape
     anyway — likely a holdover from the portrait inset value. That was
     creating a persistent black strip under the player grid: the WebView
     was reserving space for a system bar that wasn't actually there.

     Fix: zero the bottom padding in landscape regardless of what env()
     reports. Left/right keep the inset-respecting padding because the
     gesture pill genuinely lives there. Top is small because the status
     bar is also lifted away by Android's immersive mode during gameplay. */
  #game-screen.screen.active {
    /* Use percentage of parent rather than 100vh. 100vh on Android in
       landscape can over-report (it may include the area behind system
       bars even when those bars aren't actually overlaying us), making
       the game-screen taller than its container. The parent
       #screen-container has flex:1 in the body's flex column, and the
       header/nav are display:none in game-active, so the parent is
       already the full available height. Inheriting that height keeps
       us exactly within the container and prevents the grid's bottom
       row from being clipped. */
    height: 100%;
    min-height: 0;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: max(.5rem, env(safe-area-inset-top))
             max(1.5rem, env(safe-area-inset-right))
             0
             max(1.5rem, env(safe-area-inset-left));
    --game-rail-gap: clamp(2.85rem, 7.4vh, 3.6rem);
  }
  /* The grid becomes one row that fills all remaining vertical space */
  #game-screen.active .players-grid {
    flex: 1;
    height: 100%;
    min-height: 0;     /* allow children to shrink below their content height */
    column-gap: .4rem;
    row-gap: var(--game-rail-gap);   /* reserved centre command rail lane */
    align-items: stretch;
  }

  /* ── Per-pod seat layouts ────────────────────────────────────────────
     Seats are placed via grid-template-areas so we can give different
     pod sizes the right physical arrangement (e.g. 3-player = 2 on top
     + 1 spanning bottom). Each pcard gets a `seat-N` class that maps
     to a specific area, plus a rotation transform so its life total
     faces the player sitting there.

     Rotation convention:
       180° = card is upside-down (top of screen, player sits across)
         0° = card upright (bottom of screen, player sits in front)
     Larger pods don't try to use 90°/270° side rotations — keeping all
     life numbers readable from the main two viewing axes is more
     important than seat realism. */

  /* 2 players: stacked vertically — one player at top, one at bottom */
  #game-screen.active .players-grid.cols-2 {
    grid-template-columns: 1fr;
    grid-template-rows:    minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "p0"
      "p1";
  }

  /* 3 players: 2 on top + 1 spanning bottom (Option A from reference) */
  #game-screen.active .players-grid.cols-3 {
    grid-template-columns: 1fr 1fr;
    grid-template-rows:    minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "p0 p1"
      "p2 p2";
  }

  /* 4 players: 2x2 */
  #game-screen.active .players-grid.cols-4 {
    grid-template-columns: 1fr 1fr;
    grid-template-rows:    minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "p0 p1"
      "p2 p3";
  }

  /* 5 players: 2 top + 3 bottom */
  #game-screen.active .players-grid.cols-5 {
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
    grid-template-rows:    minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "p0 p0 p0 p1 p1 p1"
      "p2 p2 p3 p3 p4 p4";
  }

  /* 6 players: 2x3 */
  #game-screen.active .players-grid.cols-6 {
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows:    minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "p0 p1 p2"
      "p3 p4 p5";
  }

  /* 7 players: 3 top + 4 bottom */
  #game-screen.active .players-grid.cols-7 {
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
    grid-template-rows:    minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "p0 p0 p0 p0 p1 p1 p1 p1 p2 p2 p2 p2"
      "p3 p3 p3 p4 p4 p4 p5 p5 p5 p6 p6 p6";
  }

  /* 8 players: 2x4 */
  #game-screen.active .players-grid.cols-8 {
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-rows:    minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "p0 p1 p2 p3"
      "p4 p5 p6 p7";
  }

  /* ── Seat assignments + rotations ───────────────────────────────────
     Each pcard.seat-N falls in the grid area p{N}. Top-row players (the
     ones farther from the device user) are rotated 180° so their card
     reads correctly to whoever's sitting on that side of the table.
     Bottom-row players are upright. */
  #game-screen.active .players-grid .pcard.seat-0  { grid-area: p0; }
  #game-screen.active .players-grid .pcard.seat-1  { grid-area: p1; }
  #game-screen.active .players-grid .pcard.seat-2  { grid-area: p2; }
  #game-screen.active .players-grid .pcard.seat-3  { grid-area: p3; }
  #game-screen.active .players-grid .pcard.seat-4  { grid-area: p4; }
  #game-screen.active .players-grid .pcard.seat-5  { grid-area: p5; }
  #game-screen.active .players-grid .pcard.seat-6  { grid-area: p6; }
  #game-screen.active .players-grid .pcard.seat-7  { grid-area: p7; }

  /* Rotation rules per pod size. We rotate via a class on the pcard
     itself so the transform is inherited by everything inside. Touch
     events still work correctly through transformed elements. */
  /* 2 players */
  #game-screen.active .players-grid.cols-2 .pcard.seat-0 { transform: rotate(180deg); }
  /* 3 players: top two are 180°, bottom is upright */
  #game-screen.active .players-grid.cols-3 .pcard.seat-0,
  #game-screen.active .players-grid.cols-3 .pcard.seat-1 { transform: rotate(180deg); }
  /* 4 players: top row 180°, bottom row upright */
  #game-screen.active .players-grid.cols-4 .pcard.seat-0,
  #game-screen.active .players-grid.cols-4 .pcard.seat-1 { transform: rotate(180deg); }
  /* 5 players: top two are 180° */
  #game-screen.active .players-grid.cols-5 .pcard.seat-0,
  #game-screen.active .players-grid.cols-5 .pcard.seat-1 { transform: rotate(180deg); }
  /* 6 players: top row 180° */
  #game-screen.active .players-grid.cols-6 .pcard.seat-0,
  #game-screen.active .players-grid.cols-6 .pcard.seat-1,
  #game-screen.active .players-grid.cols-6 .pcard.seat-2 { transform: rotate(180deg); }
  /* 7 players: top three 180° */
  #game-screen.active .players-grid.cols-7 .pcard.seat-0,
  #game-screen.active .players-grid.cols-7 .pcard.seat-1,
  #game-screen.active .players-grid.cols-7 .pcard.seat-2 { transform: rotate(180deg); }
  /* 8 players: top row 180° */
  #game-screen.active .players-grid.cols-8 .pcard.seat-0,
  #game-screen.active .players-grid.cols-8 .pcard.seat-1,
  #game-screen.active .players-grid.cols-8 .pcard.seat-2,
  #game-screen.active .players-grid.cols-8 .pcard.seat-3 { transform: rotate(180deg); }

  /* Cards in the rotated layout — let them use available space without
     the previous overflow-scroll which doesn't compose well with rotation */
  #game-screen.active .players-grid .pcard {
    min-width: 0;
    min-height: 0;
    height: 100%;
    /* Allow internal content to scale; we want the life number to be
       the visual centerpiece, not an overflowing detail. */
    overflow: hidden;
  }
  #game-screen.active .players-grid .pcard-compact {
    min-height: 0;
  }
  /* Hide the turn track in landscape — it eats vertical real estate.
     The active player is already indicated by the highlighted pcard. */
  #game-screen.active .turn-track {
    display: none;
  }
}

/* ── Player card ─────────────────────────────────────────── */
.pcard {
  background:
    linear-gradient(180deg, rgba(255,255,255,.018), transparent 42%),
    var(--bg-2);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  position: relative;
  display: flex;
  flex-direction: column;
  transition: border-color .25s, box-shadow .25s, background .25s;
}
.pcard.active-turn {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-dim), 0 4px 20px rgba(124,108,248,.1);
}
.pcard.has-color {
  border-color: rgba(var(--player-color-rgb), .58);
  box-shadow:
    inset 0 0 0 1px rgba(var(--player-color-rgb), .10),
    0 6px 20px rgba(0,0,0,.22);
}
.pcard.has-color.active-turn {
  border-color: var(--player-color);
  box-shadow:
    0 0 0 1px rgba(var(--player-color-rgb), .38),
    0 0 26px rgba(var(--player-color-rgb), .22),
    0 6px 24px rgba(0,0,0,.32);
}
.pcard.eliminated { opacity: .38; }

/* Temporary per-game seat identity. The color is intentionally not
   persistent; new games return to default. A selected seat style renders
   as a stronger edge stripe plus a subtle pattern/wash so players can
   identify their seat without relying on color alone. */
.pcard-seat-pattern {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  display: none;
  opacity: .34;
}
.pcard.has-color .pcard-seat-pattern { display: block; }
.pcard.seat-pattern-lines-a .pcard-seat-pattern {
  background:
    radial-gradient(circle at 50% 50%, rgba(var(--player-color-rgb), .18), transparent 48%),
    repeating-linear-gradient(45deg, rgba(var(--player-color-rgb), .32) 0 2px, transparent 2px 14px);
}
.pcard.seat-pattern-dots .pcard-seat-pattern {
  background:
    radial-gradient(circle at 50% 50%, rgba(var(--player-color-rgb), .18), transparent 48%),
    radial-gradient(circle, rgba(var(--player-color-rgb), .46) 0 1.6px, transparent 1.8px);
  background-size: auto, 14px 14px;
}
.pcard.seat-pattern-grid .pcard-seat-pattern {
  background:
    linear-gradient(rgba(var(--player-color-rgb), .20), rgba(var(--player-color-rgb), .04)),
    repeating-linear-gradient(0deg, rgba(var(--player-color-rgb), .25) 0 1px, transparent 1px 14px),
    repeating-linear-gradient(90deg, rgba(var(--player-color-rgb), .25) 0 1px, transparent 1px 14px);
}
.pcard.seat-pattern-lines-b .pcard-seat-pattern {
  background:
    radial-gradient(circle at 50% 50%, rgba(var(--player-color-rgb), .14), transparent 48%),
    repeating-linear-gradient(-45deg, rgba(var(--player-color-rgb), .30) 0 2px, transparent 2px 13px);
}
.pcard.seat-pattern-rings .pcard-seat-pattern {
  background:
    radial-gradient(circle at 50% 50%, transparent 0 22%, rgba(var(--player-color-rgb), .28) 23% 26%, transparent 27% 46%, rgba(var(--player-color-rgb), .20) 47% 50%, transparent 51%);
}
.pcard.seat-pattern-bars .pcard-seat-pattern {
  background:
    linear-gradient(90deg, rgba(var(--player-color-rgb), .24), transparent 44%, rgba(var(--player-color-rgb), .18)),
    repeating-linear-gradient(90deg, rgba(var(--player-color-rgb), .26) 0 4px, transparent 4px 16px);
}
.pcard.seat-pattern-checks .pcard-seat-pattern {
  background:
    linear-gradient(45deg, rgba(var(--player-color-rgb), .20) 25%, transparent 25% 75%, rgba(var(--player-color-rgb), .20) 75%),
    linear-gradient(45deg, rgba(var(--player-color-rgb), .20) 25%, transparent 25% 75%, rgba(var(--player-color-rgb), .20) 75%);
  background-position: 0 0, 8px 8px;
  background-size: 16px 16px;
}
.pcard.seat-pattern-grain .pcard-seat-pattern {
  background:
    radial-gradient(circle at 20% 30%, rgba(var(--player-color-rgb), .28), transparent 2px),
    radial-gradient(circle at 70% 55%, rgba(var(--player-color-rgb), .22), transparent 2px),
    radial-gradient(circle at 42% 78%, rgba(var(--player-color-rgb), .20), transparent 1.5px);
  background-size: 18px 18px, 22px 22px, 14px 14px;
}
.pcard-color-stripe {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 10px;
  background:
    linear-gradient(180deg, rgba(255,255,255,.22), transparent 28%),
    var(--player-color, transparent);
  border-radius: var(--radius) 0 0 var(--radius);
  box-shadow: 0 0 18px rgba(var(--player-color-rgb), .28);
  z-index: 2;
  pointer-events: none;
  display: none;
}
.pcard.has-color .pcard-color-stripe { display: block; }

/* Color picker row in the drawer — sits at the bottom, below counters.
   Compact label + swatch grid layout. */
.pcard-drawer-color-row {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .65rem;
  margin: .1rem 0 .45rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,.018);
}
.pcard-drawer-color-label {
  font-size: .65rem;
  font-weight: 700;
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: .8px;
  flex-shrink: 0;
}
.pcard-color-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem;
  flex: 1;
  justify-content: flex-end;
}

/* Individual color swatch — at least 32×32 visually but the tap target
   extends to 44×44 via padding-box, meeting Android's minimum touch
   target guidance. Selected state shows a white ring + checkmark
   overlay so colorblind users see the active state without relying
   on color alone. */
.pcard-color-swatch {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid var(--border);
  cursor: pointer;
  padding: 0;
  margin: 6px;             /* extends touch target to 44×44 */
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: .9rem;
  font-weight: 700;
  overflow: hidden;
  /* Background set inline (per-color); none-of-the-above swatch styled below. */
}
.pcard-color-swatch.pcard-color-none {
  background: var(--bg-3);
  color: var(--t3);
}
.pcard-color-swatch.selected {
  /* White ring around the selected swatch, visible regardless of color.
     Combined with the inner checkmark, this gives a colorblind-safe
     selection indicator. */
  border-color: #fff;
  box-shadow: 0 0 0 2px var(--accent), 0 0 8px rgba(124, 108, 248, .4);
}
.pcard-color-swatch-pattern {
  position: absolute;
  inset: 0;
  opacity: .42;
  pointer-events: none;
}
.pcard-color-swatch.seat-pattern-lines-a .pcard-color-swatch-pattern {
  background: repeating-linear-gradient(45deg, rgba(0,0,0,.45) 0 2px, transparent 2px 8px);
}
.pcard-color-swatch.seat-pattern-dots .pcard-color-swatch-pattern {
  background: radial-gradient(circle, rgba(0,0,0,.55) 0 1.5px, transparent 1.8px);
  background-size: 8px 8px;
}
.pcard-color-swatch.seat-pattern-grid .pcard-color-swatch-pattern {
  background:
    repeating-linear-gradient(0deg, rgba(0,0,0,.42) 0 1px, transparent 1px 8px),
    repeating-linear-gradient(90deg, rgba(0,0,0,.42) 0 1px, transparent 1px 8px);
}
.pcard-color-swatch.seat-pattern-lines-b .pcard-color-swatch-pattern {
  background: repeating-linear-gradient(-45deg, rgba(0,0,0,.45) 0 2px, transparent 2px 8px);
}
.pcard-color-swatch.seat-pattern-rings .pcard-color-swatch-pattern {
  background: radial-gradient(circle, transparent 0 36%, rgba(0,0,0,.45) 38% 44%, transparent 46%);
}
.pcard-color-swatch.seat-pattern-bars .pcard-color-swatch-pattern {
  background: repeating-linear-gradient(90deg, rgba(0,0,0,.42) 0 4px, transparent 4px 9px);
}
.pcard-color-swatch.seat-pattern-checks .pcard-color-swatch-pattern {
  background:
    linear-gradient(45deg, rgba(0,0,0,.38) 25%, transparent 25% 75%, rgba(0,0,0,.38) 75%),
    linear-gradient(45deg, rgba(0,0,0,.38) 25%, transparent 25% 75%, rgba(0,0,0,.38) 75%);
  background-position: 0 0, 5px 5px;
  background-size: 10px 10px;
}
.pcard-color-swatch.seat-pattern-grain .pcard-color-swatch-pattern {
  background:
    radial-gradient(circle at 20% 30%, rgba(0,0,0,.40), transparent 2px),
    radial-gradient(circle at 70% 55%, rgba(0,0,0,.34), transparent 2px);
  background-size: 9px 9px, 11px 11px;
}
.pcard-color-swatch-mark {
  position: relative;
  z-index: 1;
  text-shadow: 0 1px 3px rgba(0,0,0,.85);
}
.pcard-color-check {
  /* Checkmark for selected colored swatches. Text-shadow gives it
     contrast against ANY swatch color since the shadow is dark. */
  position: absolute;
  right: 3px;
  bottom: 1px;
  z-index: 2;
  font-size: .72rem;
  text-shadow: 0 0 3px rgba(0, 0, 0, .8);
}
.pcard-color-custom {
  min-height: 32px;
  margin: 6px;
  padding: .18rem .46rem .18rem .22rem;
  border-radius: 999px;
  border: 2px solid var(--border);
  background: var(--bg-3);
  color: var(--t2);
  display: inline-flex;
  align-items: center;
  gap: .32rem;
  position: relative;
  cursor: pointer;
  font-size: .62rem;
  font-weight: 800;
  touch-action: manipulation;
}
.pcard-color-custom.selected {
  border-color: #fff;
  box-shadow: 0 0 0 2px var(--accent), 0 0 8px rgba(124, 108, 248, .4);
  color: var(--t1);
}
.pcard-color-custom-input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.pcard-color-custom-swatch {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.3);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.22);
}
.pcard-color-custom-text {
  line-height: 1;
  white-space: nowrap;
}

/* ── Compact card view — life-front-and-center ──────────────────────────
   The compact view fills the pcard. Life number is the visual centerpiece;
   corner buttons offer ±1/±5; transparent tap zones over left/right halves
   provide tap-and-hold mechanics. The ⋮ button opens the drawer. */
.pcard-compact {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 8rem;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;   /* disable double-tap zoom on the card */
}
.pcard.has-color .pcard-compact {
  background:
    radial-gradient(circle at center, rgba(var(--player-color-rgb), .12), transparent 50%),
    linear-gradient(180deg, rgba(var(--player-color-rgb), .045), transparent 55%);
}
.pcard-seat-tag {
  position: absolute;
  left: .55rem;
  bottom: .35rem;
  z-index: 3;
  display: none;
  align-items: center;
  gap: .25rem;
  max-width: 36%;
  padding: .16rem .44rem .16rem .25rem;
  border-radius: 999px;
  border: 1px solid rgba(var(--player-color-rgb), .26);
  background: rgba(12, 12, 16, .68);
  color: var(--player-color);
  font-size: .62rem;
  font-weight: 800;
  line-height: 1.1;
  box-shadow: 0 3px 12px rgba(0,0,0,.22);
}
.pcard.has-color .pcard-seat-tag { display: inline-flex; }
.pcard-seat-mark {
  flex-shrink: 0;
  font-size: .8rem;
  line-height: 1;
  text-shadow: 0 1px 2px rgba(0,0,0,.55);
}
.pcard-seat-tag-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--t1);
}
body.in-landscape .pcard-seat-tag {
  max-width: 28%;
  padding-right: .28rem;
}
body.in-landscape .pcard-seat-tag-text { display: none; }

/* Compact header — thumbnail + name in top-left. Wraps both so they
   sit next to each other and share positioning. The whole header is
   absolutely positioned so it doesn't push the centered life number. */
.pcard-compact-header {
  position: absolute;
  top: .25rem;
  left: .45rem;
  display: flex;
  align-items: center;
  gap: .25rem;
  z-index: 3;
  max-width: min(78%, calc(100% - 2.4rem));
  min-width: 0;
}
.pcard.has-color .pcard-compact-header {
  padding: .14rem .38rem .14rem .24rem;
  margin: -.14rem 0 0 -.24rem;
  border-radius: 999px;
  border: 1px solid rgba(var(--player-color-rgb), .22);
  background: rgba(var(--player-color-rgb), .10);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.pcard.active-turn .pcard-compact-header {
  max-width: max(2.2rem, min(52%, calc(100% - 10.8rem)));
}
body.in-landscape .pcard.active-turn .pcard-compact-header {
  max-width: max(2.2rem, min(48%, calc(100% - 9.8rem)));
}

/* Drag handle visual + touch behaviour. The compact-header doubles
   as the seat-swap drag handle, and the Move pill makes that action
   discoverable on touch devices where cursor hints don't exist.
   touch-action: none stops the WebView from interpreting the
   long-press-then-drag as a system gesture. */
.pcard-drag-handle {
  touch-action: none;
  cursor: grab;
  /* Padding extends the touchable area without changing the visual
     bounds — makes the handle easier to grip. */
  padding: .15rem .25rem .15rem 0;
  margin: -.15rem 0 -.15rem -.25rem;
  border-radius: var(--radius-xs);
}
.pcard-drag-handle:active { cursor: grabbing; }
.pcard-seat-move {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .18rem;
  min-width: 1.32rem;
  min-height: 1.32rem;
  padding: .1rem .34rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .18);
  background: rgba(255, 255, 255, .08);
  color: var(--t2);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08);
  flex-shrink: 0;
}
.pcard.has-color .pcard-seat-move {
  border-color: rgba(var(--player-color-rgb), .45);
  background: rgba(var(--player-color-rgb), .22);
  color: var(--t1);
}
.pcard-seat-move-grip {
  font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
  line-height: 1;
  opacity: .8;
}
.pcard-seat-move-text { line-height: 1; }
body.in-landscape .pcard-seat-move-text { display: none; }
body.in-landscape .pcard-seat-move {
  width: 1.38rem;
  padding: 0;
}

.pcard.is-seat-drag-arming {
  border-color: rgba(255, 255, 255, .32);
  box-shadow:
    0 0 0 2px rgba(255, 255, 255, .10),
    0 0 22px rgba(255, 255, 255, .10);
}
.pcard.is-seat-drag-arming .pcard-seat-move {
  border-color: var(--accent-l);
  background: rgba(255, 255, 255, .14);
  color: var(--t1);
}

/* When a card is being dragged: lift it visually with a slight scale,
   higher shadow, and accent border. The drag-dx/dy CSS vars (set by
   the JS handler) translate it to follow the pointer. Inline transform
   uses translate vars so JS does not have to clobber card transforms. */
.pcard.is-being-dragged {
  transform: translate(var(--drag-dx, 0px), var(--drag-dy, 0px)) scale(1.04);
  z-index: 100;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .6);
  border-color: var(--accent);
  /* Cards in the top row have an existing rotate(180deg) via seat
     classes — we re-apply it here when in drag state so the rotation
     stays correct while dragging. */
  transition: box-shadow .12s, border-color .12s;
}
/* Re-apply 180deg rotation when a top-row card is being dragged. The
   seat-N selectors mirror what's in the in-game grid rules — we only
   need the dragged-state version here. */
#game-screen.active .players-grid.cols-2 .pcard.seat-0.is-being-dragged,
#game-screen.active .players-grid.cols-3 .pcard.seat-0.is-being-dragged,
#game-screen.active .players-grid.cols-3 .pcard.seat-1.is-being-dragged,
#game-screen.active .players-grid.cols-4 .pcard.seat-0.is-being-dragged,
#game-screen.active .players-grid.cols-4 .pcard.seat-1.is-being-dragged,
#game-screen.active .players-grid.cols-5 .pcard.seat-0.is-being-dragged,
#game-screen.active .players-grid.cols-5 .pcard.seat-1.is-being-dragged,
#game-screen.active .players-grid.cols-6 .pcard.seat-0.is-being-dragged,
#game-screen.active .players-grid.cols-6 .pcard.seat-1.is-being-dragged,
#game-screen.active .players-grid.cols-6 .pcard.seat-2.is-being-dragged,
#game-screen.active .players-grid.cols-7 .pcard.seat-0.is-being-dragged,
#game-screen.active .players-grid.cols-7 .pcard.seat-1.is-being-dragged,
#game-screen.active .players-grid.cols-7 .pcard.seat-2.is-being-dragged,
#game-screen.active .players-grid.cols-8 .pcard.seat-0.is-being-dragged,
#game-screen.active .players-grid.cols-8 .pcard.seat-1.is-being-dragged,
#game-screen.active .players-grid.cols-8 .pcard.seat-2.is-being-dragged,
#game-screen.active .players-grid.cols-8 .pcard.seat-3.is-being-dragged {
  transform: translate(var(--drag-dx, 0px), var(--drag-dy, 0px)) scale(1.04) rotate(180deg);
}

/* Drop target — the card the user is hovering over while dragging. */
.pcard.is-drop-target {
  border-color: var(--accent-l);
  outline: 2px solid rgba(255, 255, 255, .62);
  outline-offset: -6px;
  box-shadow:
    0 0 0 3px var(--accent-dim),
    0 0 28px rgba(255, 255, 255, .18);
}
.pcard.is-drop-target::after {
  content: "Swap here";
  position: absolute;
  left: 50%;
  bottom: .65rem;
  transform: translateX(-50%);
  z-index: 8;
  padding: .22rem .48rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .28);
  background: rgba(10, 15, 30, .84);
  color: var(--t1);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .02em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
}

/* Commander thumbnail — small clickable image. 28×28 is small enough
   not to dominate but big enough to recognise. Tappable to open the
   card detail. Pointer-events enabled (overrides .pcard-compact-name's
   pointer-events: none) so taps register on the image. */
.pcard-cmd-thumb {
  width: 28px;
  height: 28px;
  border-radius: 4px;
  object-fit: cover;
  object-position: top;   /* card art is usually top-aligned */
  border: 1px solid var(--border);
  cursor: pointer;
  pointer-events: auto;
  flex-shrink: 0;
}

/* Signature spell thumbnail — visually distinguished from the
   oathbreaker thumbnail with a subtle accent border so players can
   tell them apart at a glance. Used only in Oathbreaker format. */
.pcard-cmd-thumb-spell {
  border-color: var(--accent-l);
  /* Slight inner ring effect via box-shadow to mark it as the "paired"
     element to the oathbreaker. Doesn't change overall size. */
  box-shadow: inset 0 0 0 1px rgba(124, 108, 248, .25);
}
.pcard-cmd-thumb-partner {
  border-color: rgba(201, 168, 90, .78);
  box-shadow: inset 0 0 0 1px rgba(201, 168, 90, .24);
}

/* Player name. Was previously absolutely positioned at top: .35rem;
   left: .55rem — now lives inside .pcard-compact-header which provides
   that positioning. Drop the absolute positioning here, keep the
   typography. */
.pcard-compact-name {
  font-size: .78rem;
  font-weight: 600;
  color: var(--t2);
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;   /* allow ellipsis truncation inside flex */
}

/* ⋮ menu button — top-right corner, opens the drawer */
/* ⋮ menu button was previously here. Removed because the drawer is now
   opened by swiping upward on the card (or downward on rotated top-row
   cards). The corresponding .pcard-more rules are gone — if you see
   them in old rendered HTML, that's stale; the new render in ui.js
   does not emit this element. */

/* Warning icon — only renders when an opponent has ≥14 commander damage
   on this player. Sits in the top-right corner where the ⋮ button used
   to be. The swipe gesture is the only way to access the drawer now;
   tapping this icon opens the drawer scrolled to the commander damage
   section. */
.pcard-warn {
  position: absolute;
  top: .25rem;
  right: .35rem;
  width: 26px; height: 26px;
  background: var(--red-dim);
  border: 1px solid rgba(244,63,94,.4);
  color: var(--red);
  font-size: .85rem;
  font-weight: 700;
  cursor: pointer;
  z-index: 4;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  animation: pcard-warn-pulse 1.4s ease-in-out infinite;
}
@keyframes pcard-warn-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(244,63,94,.5); }
  50%      { box-shadow: 0 0 0 6px rgba(244,63,94,0); }
}
.pcard-turn-panel {
  position: absolute;
  top: .25rem;
  right: .35rem;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: clamp(.28rem, .9vmin, .48rem);
  max-width: calc(100% - 1rem);
  padding: clamp(.16rem, .5vmin, .24rem) clamp(.2rem, .65vmin, .34rem) clamp(.16rem, .5vmin, .24rem) clamp(.46rem, 1vmin, .68rem);
  border: 1px solid rgba(var(--player-color-rgb, 124, 108, 248), .42);
  border-radius: 999px;
  background: rgba(18, 18, 26, .76);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 8px 18px rgba(0,0,0,.22);
  pointer-events: auto;
}
.pcard.active-turn .pcard-warn {
  top: 2.45rem;
}
.pcard-turn-time {
  min-width: clamp(2.75rem, 5.8vmin, 3.6rem);
  color: var(--t1);
  font-size: clamp(.74rem, 1.45vmin, .94rem);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  text-align: center;
}
.pcard-next-turn-btn {
  appearance: none;
  min-height: clamp(38px, 5.2vmin, 54px);
  min-width: clamp(78px, 10vmin, 118px);
  padding: 0 clamp(.78rem, 2vmin, 1.25rem);
  border: 1px solid rgba(var(--player-color-rgb, 124, 108, 248), .56);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(var(--player-color-rgb, 124, 108, 248), .34), rgba(var(--player-color-rgb, 124, 108, 248), .16));
  color: var(--t1);
  font-size: clamp(.82rem, 1.55vmin, 1rem);
  font-weight: 900;
  cursor: pointer;
  touch-action: manipulation;
}
.pcard-next-turn-btn:active {
  transform: scale(.97);
  filter: brightness(1.08);
}
body.in-landscape .pcard-turn-panel {
  top: .28rem;
  right: .38rem;
  padding-left: clamp(.34rem, .8vmin, .56rem);
}
body.in-landscape .pcard-turn-time {
  min-width: clamp(2.35rem, 4.2vmin, 3.25rem);
  font-size: clamp(.68rem, 1.15vmin, .86rem);
}
body.in-landscape .pcard-next-turn-btn {
  min-height: clamp(34px, 4.6vmin, 50px);
  min-width: clamp(68px, 8.4vmin, 104px);
  padding: 0 clamp(.62rem, 1.3vmin, 1rem);
  font-size: clamp(.74rem, 1.15vmin, .92rem);
}

.pcard-turn-total-pill {
  position: absolute;
  right: .55rem;
  bottom: .35rem;
  z-index: 3;
  display: inline-flex;
  align-items: baseline;
  justify-content: center;
  gap: .25rem;
  max-width: 42%;
  min-width: 0;
  padding: .18rem .48rem;
  border: 1px solid rgba(var(--player-color-rgb, 124, 108, 248), .24);
  border-radius: 999px;
  background: rgba(12, 12, 16, .66);
  color: var(--t3);
  font-size: clamp(.58rem, 1.1vmin, .72rem);
  font-weight: 850;
  line-height: 1;
  box-shadow: 0 3px 12px rgba(0,0,0,.18);
  pointer-events: none;
}
.pcard-turn-total-pill strong {
  color: var(--t1);
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
}
.pcard-turn-total-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.in-landscape .pcard-turn-total-pill {
  right: .42rem;
  bottom: .32rem;
  max-width: 32%;
  padding: .15rem .36rem;
  font-size: clamp(.55rem, .9vmin, .66rem);
}
body.in-landscape .pcard-turn-total-label {
  display: none;
}

.players-grid.cdmg-mode .pcard {
  transition: border-color .18s ease, box-shadow .18s ease;
}
.players-grid.cdmg-mode .pcard.cdmg-mode-target {
  border-color: rgba(255, 255, 255, .10);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.025);
}
.players-grid.cdmg-mode .pcard.cdmg-mode-source {
  border-color: rgba(var(--player-color-rgb, 201, 168, 90), .30);
}
.pcard-cdmg-mode-compact {
  position: absolute;
  inset: 0;
  padding: 0;
  overflow: hidden;
  background: #050505;
  touch-action: none;
}
.pcard-cdmg-mode-target-card,
.pcard-cdmg-mode-source-card {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
}
.pcard-cdmg-mode-target-card {
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    linear-gradient(135deg, rgba(255,255,255,.035), transparent 45%),
    #343240;
  color: #fff;
}
.pcard-cdmg-mode-title {
  max-width: min(82%, 520px);
  text-align: center;
  text-transform: uppercase;
  color: #fff;
  font-family: var(--font-head);
  font-size: clamp(2.1rem, 7vw, 5.7rem);
  font-weight: 950;
  line-height: .92;
  letter-spacing: .02em;
  pointer-events: none;
}
.pcard-cdmg-mode-target-name {
  position: absolute;
  right: .8rem;
  bottom: .7rem;
  max-width: 62%;
  color: rgba(255,255,255,.64);
  font-weight: 800;
  font-size: .72rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.pcard-cdmg-mode-return {
  position: absolute;
  left: .55rem;
  top: 50%;
  transform: translateY(-50%) rotate(-90deg);
  transform-origin: center;
  z-index: 5;
  min-width: 132px;
  min-height: 40px;
  border: 0;
  border-radius: 999px;
  background: #FFC107;
  color: #090909;
  font-size: .78rem;
  font-weight: 950;
  text-transform: uppercase;
  letter-spacing: .03em;
  cursor: pointer;
  touch-action: manipulation;
  box-shadow: 0 8px 18px rgba(0,0,0,.25);
}
.pcard-cdmg-mode-return:active {
  transform: translateY(-50%) rotate(-90deg) scale(.97);
  filter: brightness(.96);
}
.pcard-cdmg-mode-source-card {
  background: #050505;
}
.pcard-cdmg-mode-slots {
  height: 100%;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
}
.pcard-cdmg-mode-source-card.split .pcard-cdmg-mode-slots {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.pcard-cdmg-mode-slot {
  position: relative;
  min-width: 0;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(var(--cmd-source-rgb, 201, 168, 90), .58), rgba(var(--cmd-source-rgb, 201, 168, 90), .42)),
    #050505;
  isolation: isolate;
}
.pcard-cdmg-mode-source-card.split .pcard-cdmg-mode-slot + .pcard-cdmg-mode-slot {
  border-left: 2px solid rgba(0,0,0,.78);
}
.pcard-cdmg-mode-slot::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--cmd-dmg-pct, 0%);
  background: linear-gradient(0deg, rgba(255,255,255,.18), rgba(255,255,255,.04));
  z-index: 0;
  transition: height .18s ease-out;
}
.pcard-cdmg-mode-slot.warn {
  background:
    linear-gradient(180deg, rgba(245, 158, 11, .68), rgba(var(--cmd-source-rgb, 201, 168, 90), .45)),
    #050505;
}
.pcard-cdmg-mode-slot.lethal {
  background:
    linear-gradient(180deg, rgba(244, 63, 94, .78), rgba(244, 63, 94, .50)),
    #050505;
}
.pcard-cdmg-mode-op,
.pcard-cdmg-mode-total {
  position: absolute;
  z-index: 3;
  appearance: none;
  border: 0;
  background: transparent;
  color: #fff;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.pcard-cdmg-mode-op {
  width: clamp(42px, 8vw, 72px);
  height: clamp(42px, 8vw, 72px);
  border-radius: 999px;
  color: rgba(255,255,255,.50);
  font-size: clamp(1.6rem, 4vw, 3rem);
  font-weight: 950;
}
.pcard-cdmg-mode-op.minus {
  left: .8rem;
  top: 50%;
  transform: translateY(-50%);
}
.pcard-cdmg-mode-op.plus {
  right: .8rem;
  top: 50%;
  transform: translateY(-50%);
}
.pcard-cdmg-mode-op:active {
  background: rgba(255,255,255,.12);
  color: #fff;
}
.pcard-cdmg-mode-total {
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  min-width: 78px;
  min-height: 78px;
  border-radius: 999px;
  font-family: var(--font-head);
  font-size: clamp(4.8rem, 16vw, 12rem);
  font-weight: 950;
  line-height: .9;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 4px 16px rgba(0,0,0,.55);
}
.pcard-cdmg-mode-total.warn { color: #fff7cc; }
.pcard-cdmg-mode-total.lethal {
  color: #fff;
  animation: pulse 1s ease infinite;
}
.pcard-cdmg-mode-name {
  position: absolute;
  left: .65rem;
  right: .65rem;
  bottom: .6rem;
  z-index: 2;
  display: flex;
  align-items: baseline;
  gap: .35rem;
  min-width: 0;
  color: rgba(255,255,255,.72);
  text-shadow: 0 2px 10px rgba(0,0,0,.65);
  pointer-events: none;
}
.pcard-cdmg-mode-name span {
  flex: 0 0 auto;
  font-size: .58rem;
  font-weight: 950;
  letter-spacing: .10em;
  text-transform: uppercase;
}
.pcard-cdmg-mode-name strong {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: .78rem;
  font-weight: 850;
}

body.in-landscape .pcard-cdmg-mode-title {
  font-size: clamp(2.3rem, 7.6vw, 6.2rem);
}
body.in-landscape .pcard-cdmg-mode-total {
  font-size: clamp(4.2rem, 13vw, 10rem);
}
body.in-landscape .pcard-cdmg-mode-op {
  width: clamp(38px, 6vw, 58px);
  height: clamp(38px, 6vw, 58px);
}
body.in-landscape .pcard-cdmg-mode-name {
  display: none;
}

.pcard-cdmg-handle {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translate(-1px, -50%);
  z-index: 4;
  min-width: 28px;
  min-height: 58px;
  padding: .38rem .18rem;
  border: 1px solid rgba(201, 168, 90, .40);
  border-left: 0;
  border-radius: 0 999px 999px 0;
  background: rgba(201, 168, 90, .13);
  color: var(--gold);
  font-size: .56rem;
  font-weight: 900;
  letter-spacing: .08em;
  writing-mode: vertical-rl;
  text-orientation: mixed;
  cursor: pointer;
  touch-action: manipulation;
  box-shadow: 0 4px 14px rgba(0,0,0,.20);
}
.pcard-cdmg-handle:active {
  background: rgba(201, 168, 90, .24);
  border-color: rgba(201, 168, 90, .62);
}
.pcard.has-color .pcard-cdmg-handle {
  border-color: rgba(var(--player-color-rgb), .42);
  background: rgba(var(--player-color-rgb), .14);
  color: var(--player-color);
}

.pcard-cdmg-menu {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  padding: .65rem;
  border-radius: var(--radius);
  background:
    linear-gradient(180deg, rgba(201, 168, 90, .075), transparent 38%),
    var(--bg-2);
  transform: translateX(-100%);
  transition: transform .22s ease-out;
  pointer-events: none;
  visibility: hidden;
  overflow: hidden;
  touch-action: none;
}
.pcard.has-color .pcard-cdmg-menu {
  background:
    linear-gradient(180deg, rgba(var(--player-color-rgb), .12), transparent 35%),
    var(--bg-2);
}
.pcard.is-cdmg-open .pcard-cdmg-menu {
  transform: translateX(0);
  pointer-events: auto;
  visibility: visible;
}
.pcard.is-cdmg-open .pcard-compact {
  visibility: hidden;
}
.pcard.is-cdmg-open .pcard-drawer {
  visibility: hidden;
  pointer-events: none;
}
.pcard-cdmg-menu-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .55rem;
  flex: 0 0 auto;
}
.pcard-cdmg-eyebrow,
.pcard-cdmg-title {
  display: block;
  line-height: 1.05;
}
.pcard-cdmg-eyebrow {
  color: var(--gold);
  font-size: .58rem;
  font-weight: 900;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.pcard-cdmg-title {
  color: var(--t1);
  font-family: var(--font-head);
  font-size: clamp(1.1rem, 2.7vw, 1.75rem);
  font-weight: 900;
  letter-spacing: .02em;
  text-transform: uppercase;
}
.pcard-cdmg-return {
  flex: 0 0 auto;
  min-height: 38px;
  padding: .35rem .6rem;
  border: 1px solid rgba(201, 168, 90, .45);
  border-radius: 999px;
  background: rgba(201, 168, 90, .14);
  color: var(--gold);
  font-size: .68rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .04em;
  cursor: pointer;
  touch-action: manipulation;
}
.pcard-cdmg-return:active { background: rgba(201, 168, 90, .24); }
.pcard-cdmg-target {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  padding: .35rem .5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,.025);
  flex: 0 0 auto;
}
.pcard-cdmg-target-name {
  min-width: 0;
  color: var(--t1);
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pcard-cdmg-target-sub {
  color: var(--t3);
  font-size: .62rem;
  font-weight: 700;
  text-align: right;
}
.pcard-cdmg-sources {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(145px, 1fr));
  gap: .45rem;
  overflow-y: auto;
  padding-right: .1rem;
}
.pcard-cdmg-source {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: .28rem;
}
.pcard-cdmg-source-head {
  display: flex;
  align-items: center;
  gap: .25rem;
  min-width: 0;
  color: var(--t2);
  font-size: .62rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .06em;
}
.pcard-cdmg-source-mark {
  flex: 0 0 auto;
  color: var(--source-color, var(--gold));
}
.pcard-cdmg-source-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pcard-cdmg-slot-grid {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: .3rem;
}
.pcard-cdmg-source.has-partner .pcard-cdmg-slot-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.pcard-cdmg-slot {
  position: relative;
  min-height: clamp(7rem, 22vh, 12rem);
  border-radius: calc(var(--radius) - 2px);
  border: 1px solid rgba(255,255,255,.09);
  background:
    linear-gradient(180deg, rgba(255,255,255,.035), transparent 44%),
    rgba(0,0,0,.42);
  overflow: hidden;
  isolation: isolate;
}
.pcard-cdmg-slot::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--cmd-dmg-pct, 0%);
  background: linear-gradient(0deg, rgba(201, 168, 90, .72), rgba(201, 168, 90, .22));
  z-index: 0;
  transition: height .18s ease-out;
}
.pcard-cdmg-slot.warn::before {
  background: linear-gradient(0deg, rgba(245, 158, 11, .78), rgba(245, 158, 11, .24));
}
.pcard-cdmg-slot.lethal::before {
  background: linear-gradient(0deg, rgba(244, 63, 94, .82), rgba(244, 63, 94, .25));
}
.pcard-cdmg-slot-art {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: .30;
}
.pcard-cdmg-slot-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  filter: saturate(.88) contrast(.96);
}
.pcard-cdmg-slot-placeholder {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  color: rgba(255,255,255,.18);
  font-family: var(--font-head);
  font-size: 3rem;
  font-weight: 900;
}
.pcard-cdmg-slot-copy {
  position: absolute;
  left: .45rem;
  right: .45rem;
  bottom: .45rem;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: .08rem;
  pointer-events: none;
}
.pcard-cdmg-slot-label {
  color: rgba(255,255,255,.76);
  font-size: .54rem;
  font-weight: 900;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.pcard-cdmg-slot-name {
  color: var(--t1);
  font-size: .66rem;
  font-weight: 800;
  line-height: 1.05;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-shadow: 0 1px 8px rgba(0,0,0,.80);
}
.pcard-cdmg-op,
.pcard-cdmg-total {
  position: absolute;
  z-index: 4;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--t1);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.pcard-cdmg-op {
  top: .42rem;
  width: 42px;
  height: 42px;
  border-radius: 999px;
  color: rgba(255,255,255,.55);
  font-size: 1.5rem;
  font-weight: 900;
}
.pcard-cdmg-op.minus { left: .35rem; }
.pcard-cdmg-op.plus  { right: .35rem; }
.pcard-cdmg-op:active {
  background: rgba(255,255,255,.10);
  color: var(--t1);
}
.pcard-cdmg-total {
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  min-width: 52px;
  min-height: 52px;
  border-radius: 999px;
  font-family: var(--font-head);
  font-size: clamp(2.3rem, 9vw, 5.3rem);
  font-weight: 900;
  line-height: 1;
  color: var(--t1);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 12px rgba(0,0,0,.66);
}
.pcard-cdmg-total.warn { color: var(--amber); }
.pcard-cdmg-total.lethal {
  color: var(--red);
  animation: pulse 1s ease infinite;
}

body.in-landscape .pcard-cdmg-menu {
  padding: .5rem;
  gap: .35rem;
}
body.in-landscape .pcard-cdmg-sources {
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: .35rem;
}
body.in-landscape .pcard-cdmg-slot {
  min-height: clamp(4.8rem, 19vh, 8.8rem);
}
body.in-landscape .pcard-cdmg-target-sub,
body.in-landscape .pcard-cdmg-eyebrow {
  display: none;
}
body.in-landscape .pcard-cdmg-return {
  min-height: 32px;
  padding: .25rem .45rem;
  font-size: .58rem;
}
body.in-landscape .pcard-cdmg-op {
  width: 34px;
  height: 34px;
  font-size: 1.25rem;
}

/* The compact view owns the pointer events for the entire card surface,
   so touch-action: none lives here (was on the tap zones in a previous
   build). This is what enables drawer-swipe detection: without it, the
   WebView interprets vertical movement as a scroll and steals the
   pointer mid-gesture. */
.pcard-compact {
  touch-action: none;
}

/* Tap zones — invisible halves of the card. No pointer handlers any
   more — the parent .pcard-compact owns them. These divs remain for:
   1. :active press feedback (subtle accent tint on the half the user
      is currently pressing)
   2. aria-label semantics for screen readers
   pointer-events: none so they don't intercept the parent's pointer
   events. The :active state still works because :active applies to
   any element under a pressed pointer. */
.pcard-tapzone {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  z-index: 1;
  pointer-events: none;
  -webkit-tap-highlight-color: transparent;
}
.pcard-tapzone.left  { left: 0;  }
.pcard-tapzone.right { right: 0; }
/* Subtle press feedback for the side under the user's finger */
.pcard-compact:active .pcard-tapzone:active {
  background: rgba(124, 108, 248, 0.06);
}

/* Corner +/- glyphs — visible ±1 hints with no background or border.
   The whole half-card surface is tap-active via the .pcard-compact
   pointer handlers; these glyphs just communicate "tap this side to
   add/subtract." Were previously full circular buttons with their own
   click handlers; now they're decorative — the parent card handles
   the tap. pointer-events: none so they don't intercept events from
   the swipe gesture / tap zones beneath.

   Long-press on the tap zone fires ±10. */
.pcard-corner-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 56px;
  height: 56px;
  /* No background, no border, no border-radius — just the glyph. */
  background: transparent;
  border: none;
  color: var(--t3);
  font-size: 1.5rem;
  font-weight: 700;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  /* Decorative — the parent .pcard-compact owns the press handling
     for the whole card surface. */
  pointer-events: none;
  /* Slight opacity so the glyphs read as "hints" rather than primary
     controls. */
  opacity: .55;
}
.pcard-corner-btn.tl { left:  .75rem; }
.pcard-corner-btn.tr { right: .75rem; }
/* When the half-side under the glyph is being pressed, brighten the
   glyph so the user gets visual confirmation that the tap registered.
   The :active state lives on the tap zones (which sit under the
   glyphs); we mirror via sibling-state selectors. */
.pcard-compact:active .pcard-corner-btn { opacity: .85; }

/* Drawer handle — visible, tappable affordance that opens the player
   drawer. Replaces the older ⋮ menu button and the bobbing chevron
   hint with a more discoverable grabber pill at the bottom-inner edge
   of each card.

   Why this design (notes from Copilot review + UX iteration):
   - Visible affordance beats hidden gesture for discoverability
   - Tap opens the drawer; the seat-aware drawer swipe also opens it (both
     work, both wired to the same togglePcardDrawer)
   - Bottom-center on every card means it sits near the table-center
     seam on both top-row (rotated) and bottom-row cards. Players reach
     it naturally from their perspective.
   - No conflict with Android edge gestures: this position is in the
     middle of the screen vertically, nowhere near the top edge
     (notification shade) or screen edges (back gesture, home).
   - Visually compact: doesn't dominate the card the way the old +5/-5
     buttons did. Backdrop-blur and translucent fill make it read as
     an overlay element rather than primary content. */
.pcard-drawer-handle {
  position: absolute;
  bottom: .25rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;

  display: flex;
  align-items: center;
  justify-content: center;

  /* Compact size — was a pill with label, now just a grabber bar with
     minimal padding. The label "CONTROLS" was useful for first-time
     discoverability but it dominates small cards in 4-player landscape
     and visually competes with the player name + commander icon at
     the opposite corner. The grabber bar alone is enough now that
     the gesture pattern is established. */
  padding: .35rem .9rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .08);
  background: rgba(20, 20, 28, .55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);

  cursor: pointer;
  touch-action: manipulation;

  /* Subtle pulse keeps the affordance discoverable without crowding. */
  animation: pcardHandlePulse 3s ease-in-out infinite;
}
.pcard-drawer-handle:active {
  background: rgba(124, 108, 248, .25);
  border-color: rgba(124, 108, 248, .5);
}
.pcard.has-color .pcard-drawer-handle {
  border-color: rgba(var(--player-color-rgb), .28);
  background: rgba(var(--player-color-rgb), .14);
}
.pcard.has-color .pcard-drawer-handle:active {
  background: rgba(var(--player-color-rgb), .24);
  border-color: rgba(var(--player-color-rgb), .46);
}

.pcard-drawer-handle-grabber {
  width: 28px;
  height: 3px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .65);
}
.pcard.has-color .pcard-drawer-handle-grabber {
  background: var(--player-color);
  box-shadow: 0 0 10px rgba(var(--player-color-rgb), .32);
}

/* Label removed for compactness — kept the class so the JS+HTML can
   stay simple, but the visual element collapses to nothing. If you
   want the label back at any point, change display: none to inline
   and re-add some margin above the grabber. */
.pcard-drawer-handle-label {
  display: none;
}

@keyframes pcardHandlePulse {
  0%, 100% { opacity: .82; }
  50%      { opacity: 1; }
}

/* Hide the handle while the drawer is open — the user found it; no
   need to keep pulsing. The drawer's own close mechanism takes over. */
.pcard.is-drawer-open .pcard-drawer-handle {
  opacity: 0;
  pointer-events: none;
}
.pcard.is-drawer-open .pcard-cdmg-handle,
.pcard.is-cdmg-open .pcard-cdmg-handle,
.pcard.is-cdmg-open .pcard-drawer-handle {
  opacity: 0;
  pointer-events: none;
}

/* Respect reduced-motion preference: skip the pulse animation. The
   handle is still visible as a static affordance. */
@media (prefers-reduced-motion: reduce) {
  .pcard-drawer-handle { animation: none; }
}

/* Center life number — this is THE focal point of the compact view */
.pcard-life-center {
  position: relative;
  z-index: 2;
  cursor: pointer;
  text-align: center;
  -webkit-tap-highlight-color: transparent;
  /* Don't take up the full width — we want the tap zones reachable. */
  min-width: 30%;
  padding: 0 .5rem;
}
.pcard-life-num {
  /* Use clamp so the number scales with available card size — much
     bigger when the card is large (2-player landscape), smaller when
     the card is small (8-player landscape). */
  font-size: clamp(2.5rem, 11vw, 5.5rem);
  font-weight: 800;
  line-height: 1;
  color: var(--t1);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
.pcard-life-num.low      { color: var(--amber); }
.pcard-life-num.critical { color: var(--red); }

/* Bottom-edge badges — tax, poison. Hidden if zero. */
.pcard-badges {
  position: absolute;
  bottom: .35rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: .35rem;
  z-index: 3;
  pointer-events: none;
}
.pcard-tax-badge,
.pcard-poison-badge,
.pcard-blessing-badge,
.pcard-ring-badge,
.pcard-rad-badge {
  appearance: none;
  font-size: .7rem;
  font-weight: 700;
  padding: .15rem .45rem;
  border-radius: var(--radius-sm);
  background: var(--bg-3);
  border: 1px solid var(--border);
  cursor: pointer;
  pointer-events: auto;
}
.pcard-tax-badge {
  color: var(--accent-l);
}
.pcard-tax-mana {
  font-weight: 500;
  color: var(--t3);
  font-size: .64rem;
}
.pcard-poison-badge {
  color: var(--green);
}
.pcard-poison-badge.lethal {
  color: var(--red);
  background: var(--red-dim);
  border-color: rgba(244,63,94,.4);
}
.pcard-blessing-badge {
  color: var(--gold);
  border-color: rgba(201, 168, 90, .42);
  background: rgba(201, 168, 90, .10);
}
.pcard-ring-badge {
  color: var(--accent-l);
  border-color: rgba(124, 108, 248, .48);
  background: rgba(124, 108, 248, .12);
}
.pcard-rad-badge {
  color: var(--blue);
  border-color: rgba(86, 180, 233, .44);
  background: rgba(86, 180, 233, .10);
}

/* ── Drawer ─────────────────────────────────────────────────────────────
   The drawer overlays the compact card. Hidden by default; slides in via
   transform when the parent has `is-drawer-open`. Inherits the parent
   pcard's rotation, so a top-row card's drawer reads correctly to that
   seat. */
.pcard-drawer {
  position: absolute;
  inset: 0;
  background: var(--bg-2);
  border-radius: var(--radius);
  padding: var(--pcard-drawer-pad, .55rem);
  z-index: 5;
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateY(100%);
  transition: transform .22s ease-out;
  pointer-events: none;
  /* Hide the slot until the drawer is open so layout is preserved
     for the compact view's flex/grid sizing. */
  visibility: hidden;
}
.pcard.has-color .pcard-drawer {
  background:
    linear-gradient(180deg, rgba(var(--player-color-rgb), .12), transparent 32%),
    var(--bg-2);
}
.pcard.is-drawer-open .pcard-drawer {
  transform: translateY(0);
  pointer-events: auto;
  visibility: visible;
}
/* Hide the compact view when drawer is open so they don't overlap visually
   under the rotation transform (rotated z-index gets weird at the edges). */
.pcard.is-drawer-open .pcard-compact {
  visibility: hidden;
}

/* On larger in-game layouts the drawer panel can be much taller than its
   compact controls. Only the control grid absorbs that spare height: header
   buttons, commander chips, and seat swatches keep their natural size while
   the counter cells stretch with their divider lines intact. */
@media (min-height: 560px) {
  body.in-landscape #game-screen.active .pcard-drawer {
    min-height: 0;
    overflow-y: auto;
  }
  body.in-landscape #game-screen.active .pcard-drawer-head,
  body.in-landscape #game-screen.active .pcard-drawer-cmds,
  body.in-landscape #game-screen.active .pcard-player-states,
  body.in-landscape #game-screen.active .pcard-drawer-color-row {
    flex: 0 0 auto;
  }
  body.in-landscape #game-screen.active .pcard-drawer-control-grid {
    flex: 1 1 0;
    min-height: 0;
    display: grid;
    grid-auto-rows: minmax(0, 1fr);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  body.in-landscape #game-screen.active .pcard-drawer-control-grid .pcard-drawer-cdmg-row,
  body.in-landscape #game-screen.active .pcard-drawer-control-grid .counters-row {
    min-height: 0;
    border-bottom: 0;
  }
  body.in-landscape #game-screen.active .pcard-drawer-cdmg-row .ctr,
  body.in-landscape #game-screen.active .counters-row .ctr {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  body.in-landscape #game-screen.active .pcard-drawer-control-grid .ctr {
    min-width: 0;
  }
  body.in-landscape #game-screen.active .pcard-drawer-color-row {
    margin-top: .45rem;
    margin-bottom: 0;
  }
}
.pcard-drawer-head {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin-bottom: .35rem;
}
.pcard-drawer-head .pcard-name {
  flex: 1;
  font-weight: 600;
  font-size: .85rem;
}
.pcard-drawer-cmds {
  /* Was flex-direction: column — stacking oathbreaker and signature
     spell on separate rows. For Oathbreaker decks the user wants them
     side by side: planeswalker + spell as a pair, like the game shows
     them at the table. Wrapping kicks in only if the chips can't fit
     side by side on very narrow cards. */
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: .3rem;
  margin-bottom: .5rem;
}
.pcard-turn-summary {
  display: flex;
  align-items: center;
  gap: .35rem;
  flex-wrap: wrap;
  margin: -.15rem 0 .5rem;
  padding: .38rem .48rem;
  border: 1px solid rgba(255,255,255,.07);
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,.025);
  color: var(--t3);
  font-size: .62rem;
  font-weight: 800;
}
.pcard-turn-summary strong {
  color: var(--t1);
  font-variant-numeric: tabular-nums;
}
.pcard-turn-summary span {
  white-space: nowrap;
}

.pcard-head {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .55rem .7rem;
  background: var(--bg-3);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.pcard-name {
  font-weight: 600;
  font-size: .84rem;
  color: var(--t1);
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.active-turn .pcard-name::before { content: '▸ '; color: var(--accent-l); }

.pcard-cmd {
  display: flex;
  align-items: center;
  gap: .3rem;
  background: var(--bg-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: .2rem .45rem;
  cursor: pointer;
  /* Cap individual chips but let them grow inside a flex row so
     paired oathbreaker + signature spell share available width evenly.
     min-width gives the names enough room to show useful prefix
     characters even when both chips are present. */
  max-width: 160px;
  min-width: 0;
  flex: 1 1 auto;
  touch-action: manipulation;
  transition: border-color .12s;
}
.pcard-cmd:active { border-color: var(--accent); }
.pcard-cmd-img { width: 18px; height: 24px; object-fit: cover; border-radius: 2px; flex-shrink: 0; }
.pcard-cmd-name { font-size: .66rem; color: var(--t2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 500; }
.pcard-cmd.no-cmd { color: var(--t3); font-size: .66rem; cursor: default; }
/* Settable empty slot — when no card is set in Oathbreaker mode (or any
   game where the user wants to fill in the commander mid-game). */
.pcard-cmd.no-cmd.settable {
  cursor: pointer;
  border-style: dashed;
  border-color: var(--border-2);
  color: var(--t2);
}
.pcard-cmd.no-cmd.settable .pcard-cmd-name { color: var(--accent-l); font-weight: 600; }
.pcard-cmd.no-cmd.settable:active {
  border-color: var(--accent);
  background: var(--accent-dim);
}
.pcard-hbtns { display: flex; gap: .3rem; flex-shrink: 0; }

/* Eliminate / Restore pill in the drawer header. Distinct from the
   close ✕ by being a labeled text button with a colour tint:
   - Eliminate: red text + faint red background, signals destructive
   - Restore: green, signals the inverse action
   Both use the same compact sizing as the adjacent "Set Life" pill so
   the row reads as three uniform pills + a small close icon at the end. */
.pcard-elim-btn {
  padding: .3rem .55rem;
  font-size: .65rem;
  color: var(--red);
  background: rgba(244, 63, 94, .12);
  border: 1px solid rgba(244, 63, 94, .35);
}
.pcard-elim-btn:hover,
.pcard-elim-btn:active {
  background: rgba(244, 63, 94, .22);
}
.pcard-elim-btn.restore {
  color: var(--green);
  background: rgba(16, 185, 129, .12);
  border-color: rgba(16, 185, 129, .35);
}
.pcard-elim-btn.restore:hover,
.pcard-elim-btn.restore:active {
  background: rgba(16, 185, 129, .22);
}

/* Life row */
.life-row {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--border);
  min-height: 72px;
}
.life-btn {
  background: var(--bg-3);
  border: none;
  border-right: 1px solid var(--border);
  color: var(--t3);
  font-size: .85rem;
  font-weight: 600;
  min-width: 38px;
  display: flex; align-items: center; justify-content: center;
  transition: all .1s;
  touch-action: manipulation;
  user-select: none;
}
.life-btn.last { border-right: none; border-left: 1px solid var(--border); }
.life-btn.big  { min-width: 30px; font-size: .7rem; color: var(--t3); }
.life-btn:active { background: var(--bg-4); color: var(--t1); }
.life-center {
  flex: 1;
  background: var(--bg-3);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  cursor: pointer;
  padding: .3rem;
  touch-action: manipulation;
}
.life-num {
  font-family: var(--font-head);
  font-size: clamp(1.8rem, 5vw, 2.4rem);
  font-weight: 700;
  color: var(--t1);
  line-height: 1;
  transition: color .3s;
  letter-spacing: -.02em;
}
.life-num.low      { color: var(--amber); }
.life-num.critical { color: var(--red); animation: pulse 1.2s ease infinite; }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:.45} }
.life-lbl { font-size: .55rem; font-weight: 600; color: var(--t3); text-transform: uppercase; letter-spacing: 1px; margin-top: 2px; }

/* Counters */
.counters-row {
  display: flex;
  flex-wrap: wrap;       /* allow wrapping when commander damage chips
                            push the row past available width */
  border-bottom: 1px solid var(--border);
}
.ctr {
  flex: 1 1 0;
  min-width: 60px;       /* prevent overflow chips from getting unreadable */
  padding: .45rem .2rem;
  text-align: center;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.ctr:last-child { border-right: none; }
.ctr-lbl { font-size: .5rem; font-weight: 700; letter-spacing: 1.2px; text-transform: uppercase; display: block; margin-bottom: 1px; }
.ctr-lbl.accent { color: var(--accent-l); }
.ctr-lbl.green  { color: var(--green); }
.ctr-lbl.blue   { color: var(--blue); }
.ctr-lbl.amber  { color: var(--amber); }
.ctr-lbl.violet { color: var(--accent-l); }
.ctr-lbl.red    { color: var(--red); }
.ctr-val { font-family: var(--font-head); font-size: 1.15rem; font-weight: 700; line-height: 1; display: block; }
.ctr-val.accent { color: var(--accent-l); }
.ctr-val.green  { color: var(--green); }
.ctr-val.blue   { color: var(--blue); }
.ctr-val.amber  { color: var(--amber); }
.ctr-val.violet { color: var(--accent-l); }
.ctr-val.danger { color: var(--red); animation: pulse 1s ease infinite; }
.ctr-sub { font-size: .52rem; color: var(--t3); display: block; margin-bottom: 3px; }
.ctr-btns { display: flex; justify-content: center; gap: 3px; margin-top: 3px; }
.ctr-btn {
  width: 22px; height: 22px;
  background: var(--bg-4);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--t3);
  font-size: .85rem;
  font-family: monospace;
  display: flex; align-items: center; justify-content: center;
  touch-action: manipulation;
  transition: all .1s;
}
.ctr-btn:active { background: var(--bg-5); color: var(--t1); }
/* Commander-damage variant of .ctr — distinguishable label color
   tints automatically based on the threat level (warn/lethal) which is
   set inline by the renderer. */
.ctr.cdmg-ctr {
  background: var(--bg-2);
}

/* Commander damage row in the player drawer — same flex layout as
   .counters-row so the .ctr.cdmg-ctr chips share their look and
   wrapping behaviour. Lives directly above the counters row and shows
   only in commander mode (oathbreaker hides this whole row). When a
   game has many opponents the chips wrap to a second line. */
.pcard-drawer-cdmg-row {
  display: flex;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
}
.pcard-drawer-cdmg-row:empty { display: none; }

body.in-landscape #game-screen.active .pcard-drawer {
  --pcard-drawer-pad: clamp(.32rem, 1.05vmin, .55rem);
}
body.in-landscape #game-screen.active .pcard-drawer-head {
  gap: clamp(.22rem, .72vmin, .4rem);
  margin-bottom: clamp(.18rem, .58vmin, .35rem);
}
body.in-landscape #game-screen.active .pcard-drawer-cmds {
  gap: clamp(.16rem, .5vmin, .3rem);
  margin-bottom: clamp(.22rem, .72vmin, .5rem);
}
body.in-landscape #game-screen.active .pcard-drawer-color-row {
  gap: clamp(.28rem, .78vmin, .5rem);
  padding: clamp(.28rem, .85vmin, .5rem) clamp(.38rem, 1.05vmin, .65rem);
}
body.in-landscape #game-screen.active .pcard-color-swatches {
  gap: clamp(.08rem, .38vmin, .25rem);
}
body.in-landscape #game-screen.active .pcard-color-swatch {
  width: clamp(24px, 4.4vmin, 32px);
  height: clamp(24px, 4.4vmin, 32px);
  margin: clamp(2px, .72vmin, 6px);
}
body.in-landscape #game-screen.active .pcard-color-custom {
  min-height: clamp(24px, 4.4vmin, 32px);
  margin: clamp(2px, .72vmin, 6px);
  padding: .14rem .38rem .14rem .18rem;
}
body.in-landscape #game-screen.active .pcard-player-states {
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: clamp(.2rem, .58vmin, .35rem);
  padding-top: clamp(.22rem, .65vmin, .45rem);
}
body.in-landscape #game-screen.active .pcard-state-toggle {
  min-height: clamp(34px, 5.9vmin, 42px);
  padding: clamp(.28rem, .7vmin, .45rem) clamp(.42rem, .86vmin, .6rem);
}
body.in-landscape #game-screen.active .pcard-player-states .rules-help-btn,
body.in-landscape #game-screen.active .pcard-ring-state .rules-help-btn {
  width: clamp(28px, 4.8vmin, 34px);
  min-width: clamp(28px, 4.8vmin, 34px);
  min-height: clamp(34px, 5.9vmin, 42px);
}
body.in-landscape #game-screen.active .pcard-ring-steps .ctr-btn {
  width: clamp(24px, 4.4vmin, 28px);
  min-height: clamp(34px, 5.9vmin, 42px);
}

@media (orientation: landscape) and (max-height: 760px) {
  body.in-landscape #game-screen.screen.active {
    --game-rail-gap: clamp(2.55rem, 6.8vh, 3.2rem);
  }
  body.in-landscape #game-screen.active .pcard-drawer-head .pcard-name {
    font-size: .78rem;
  }
  body.in-landscape #game-screen.active .pcard-hbtns {
    gap: .2rem;
  }
  body.in-landscape #game-screen.active .pcard-hbtns .btn-sm,
  body.in-landscape #game-screen.active .pcard-hbtns .btn-icon {
    min-height: 30px;
    padding: .24rem .46rem;
    font-size: .6rem;
  }
  body.in-landscape #game-screen.active .pcard-cmd-img {
    width: 16px;
    height: 21px;
  }
  body.in-landscape #game-screen.active .pcard-cmd-name {
    font-size: .6rem;
  }
  body.in-landscape #game-screen.active .ctr {
    padding: .3rem .14rem;
    min-width: 52px;
  }
  body.in-landscape #game-screen.active .ctr-val {
    font-size: 1rem;
  }
  body.in-landscape #game-screen.active .ctr-btn {
    width: 20px;
    height: 20px;
  }
  body.in-landscape #game-screen.active .pcard-state-sub,
  body.in-landscape #game-screen.active .pcard-drawer-color-label {
    font-size: .54rem;
  }
}
.pcard-player-states {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: .35rem;
  padding: .45rem 0 0;
}
.pcard-state-control {
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .25rem;
  align-items: stretch;
}
.pcard-player-states .rules-help-btn,
.pcard-ring-state .rules-help-btn {
  width: 34px;
  min-width: 34px;
  height: 100%;
  min-height: 42px;
  border-radius: var(--radius-sm);
}
.pcard-state-toggle {
  width: 100%;
  min-height: 42px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-3);
  color: var(--t2);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  padding: .45rem .6rem;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
}
.pcard-state-toggle:active {
  background: var(--bg-4);
  border-color: var(--accent);
}
.pcard-state-toggle.selected {
  border-color: rgba(201, 168, 90, .58);
  background: rgba(201, 168, 90, .12);
  color: var(--t1);
}
.pcard-state-toggle.ring.selected {
  border-color: rgba(124, 108, 248, .58);
  background: rgba(124, 108, 248, .14);
}
.pcard-state-title {
  font-size: .68rem;
  font-weight: 800;
  color: inherit;
}
.pcard-state-sub {
  font-size: .58rem;
  font-weight: 700;
  color: var(--t3);
  text-align: right;
}
.pcard-state-toggle.selected .pcard-state-sub {
  color: var(--gold);
}
.pcard-state-toggle.ring.selected .pcard-state-sub {
  color: var(--accent-l);
}
.pcard-ring-state {
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: .25rem;
}
.pcard-ring-steps {
  display: flex;
  align-items: center;
  gap: .2rem;
}
.pcard-ring-steps .ctr-btn {
  width: 28px;
  height: 100%;
  min-height: 42px;
}

/* Commander damage */
.cdmg-section { padding: .55rem .7rem; }
.cdmg-list    { display: flex; flex-direction: column; gap: .35rem; }
.cdmg-row {
  display: flex;
  align-items: center;
  gap: .4rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: .35rem .5rem;
  transition: border-color .15s;
}
.cdmg-row.lethal { border-color: rgba(244,63,94,.6); }
.cdmg-row.warn   { border-color: rgba(245,158,11,.5); }
.cdmg-src  { display: flex; align-items: center; gap: .3rem; max-width: 80px; flex: 0 0 auto; }
.cdmg-img  { width: 16px; height: 22px; object-fit: cover; border-radius: 2px; flex-shrink: 0; }
.cdmg-ph   { width: 16px; height: 22px; background: var(--bg-4); border-radius: 2px; flex-shrink: 0; }
.cdmg-name { font-size: .64rem; font-weight: 500; color: var(--t2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Streamlined commander damage value: a single clickable button on the
   right of each row. Tapping opens a number-input prompt to set the
   exact damage value. Replaces the previous slider + ± buttons. */
.cdmg-input-btn {
  margin-left: auto;             /* push to the right edge of the row */
  min-width: 48px;
  height: 32px;
  padding: 0 .55rem;
  background: var(--bg-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--t1);
  font-weight: 700;
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  touch-action: manipulation;
}
.cdmg-input-btn:active { background: var(--bg-5); }
.cdmg-input-btn.warn {
  color: var(--amber);
  border-color: rgba(245,158,11,.5);
  background: rgba(245,158,11,.08);
}
.cdmg-input-btn.lethal {
  color: var(--red);
  border-color: rgba(244,63,94,.55);
  background: var(--red-dim);
}

/* New control group: − [slider] + [value] */
.cdmg-controls {
  flex: 1;
  display: flex;
  align-items: center;
  gap: .35rem;
  min-width: 0;
}
.cdmg-slider {
  flex: 1;
  min-width: 40px;
  height: 28px;          /* generous tap target */
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  touch-action: pan-x;
}
.cdmg-slider::-webkit-slider-runnable-track {
  height: 4px;
  background: var(--bg-5);
  border-radius: 2px;
}
.cdmg-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  margin-top: -7px;
  border: 2px solid var(--bg-2);
  cursor: pointer;
}
.cdmg-row.lethal .cdmg-slider::-webkit-slider-thumb { background: var(--red); }
.cdmg-slider::-moz-range-track {
  height: 4px;
  background: var(--bg-5);
  border-radius: 2px;
}
.cdmg-slider::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg-2);
}
.cdmg-row.lethal .cdmg-slider::-moz-range-thumb { background: var(--red); }

.cdmg-val  {
  font-family: var(--font-head); font-size: .95rem; font-weight: 700;
  color: var(--t1); min-width: 26px; text-align: center;
  cursor: pointer; touch-action: manipulation;
  padding: 2px 4px; border-radius: 3px;
}
.cdmg-val:active { background: var(--bg-5); }
.cdmg-val.lethal { color: var(--red); }

.cdmg-btn  {
  width: 26px; height: 26px;
  background: var(--bg-4); border: 1px solid var(--border);
  border-radius: 4px; color: var(--t1); font-size: .9rem;
  font-family: monospace; display: flex; align-items: center; justify-content: center;
  touch-action: manipulation; flex-shrink: 0;
}
.cdmg-btn:active { background: var(--accent-dim); border-color: var(--accent); }

/* Elim stamp */
.elim-stamp {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none; z-index: 4;
}
.elim-inner {
  font-size: .9rem;
  font-weight: 700;
  color: var(--red);
  border: 2px solid var(--red);
  padding: .25rem .7rem;
  border-radius: var(--radius-xs);
  transform: rotate(-10deg);
  opacity: .9;
  text-align: center;
  white-space: pre-line;
  background: rgba(15,15,18,.8);
}

/* History */
/* History log — now lives inside #log-modal as a scrollable list.
   Always rendered (display: block) so entries accumulate even when the
   modal is closed; the modal overlay handles visibility. */
.history-log {
  display: block;
  max-height: 60vh;
  overflow-y: auto;
  padding: .25rem 0;
}
.hist-entry {
  font-size: .82rem;
  color: var(--t1);
  padding: .5rem .25rem;
  border-bottom: 1px solid var(--border);
}
.hist-entry:last-child { border-bottom: none; }
.history-log:empty::before {
  content: 'No events yet.';
  display: block;
  text-align: center;
  color: var(--t3);
  font-size: .85rem;
  padding: 2rem 1rem;
}
/* Tall modal variant — for when the modal needs more vertical room
   than the default (e.g., the log can have many entries). */
.modal.modal-tall {
  max-height: 85vh;
  display: flex;
  flex-direction: column;
}
.modal.modal-tall .modal-title {
  flex-shrink: 0;
}

/* ── Deck screen ─────────────────────────────────────────── */
.deck-grid { display: flex; flex-direction: column; gap: .75rem; }

/* Format filter bar above the deck grid. Same visual language as the
   stats screen filter (familiar pattern for the user). Hidden when the
   user has decks of only one format. */
.deck-filter-bar {
  display: flex;
  align-items: center;
  gap: .5rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .5rem .75rem;
  margin-bottom: .8rem;
}

/* Free-tier hint shown above the deck grid. Slim and unobtrusive when
   below the cap; styled with an amber accent when AT or OVER the cap so
   the user notices. */
.deck-tier-hint {
  font-size: .8rem;
  padding: .5rem .75rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: .8rem;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .25rem;
}

/* Minimal link-styled button used in the upgrade modal and tier hint. */
.btn-link {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent-l);
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}
.btn-link:hover, .btn-link:active { color: var(--accent); }
.deck-filter-label {
  font-size: .75rem;
  font-weight: 600;
  color: var(--t2);
  text-transform: uppercase;
  letter-spacing: .5px;
}
.deck-format-filter {
  flex: 1;
  background: var(--bg-3);
  color: var(--t1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .35rem .5rem;
  font-size: .85rem;
  font-family: var(--font);
  cursor: pointer;
  touch-action: manipulation;
}
.deck-format-filter:focus {
  outline: none;
  border-color: var(--accent);
}
@media (min-width:480px) { .deck-grid { display: grid; grid-template-columns: 1fr 1fr; } }

.deck-tile {
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color .15s;
}
.deck-tile:active { border-color: var(--accent); }
.deck-tile-top {
  display: flex;
  gap: .75rem;
  padding: .85rem;
  background: var(--bg-3);
  border-bottom: 1px solid var(--border);
}
.deck-art {
  width: 50px; height: 68px;
  border-radius: var(--radius-xs);
  object-fit: cover;
  background: var(--bg-4);
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--t3); font-size: 1.3rem;
}
.deck-tile-info { flex: 1; min-width: 0; }
.deck-tile-name { font-weight: 700; font-size: .92rem; color: var(--t1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.deck-tile-name .fav-star { color: var(--amber); font-size: .9em; margin-right: 1px; }
.deck-tile-cmd  { font-size: .78rem; color: var(--t2); margin-top: .15rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.deck-tile-colors { font-size: .72rem; color: var(--t3); margin-top: .1rem; }
.wr-bar { height: 3px; background: var(--bg-5); border-radius: 2px; margin-top: .5rem; overflow: hidden; }
.wr-fill { height: 100%; background: var(--accent); border-radius: 2px; transition: width .4s; }

.deck-tile-stats {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  border-bottom: 1px solid var(--border);
}
.ds { padding: .5rem .3rem; text-align: center; border-right: 1px solid var(--border); }
.ds:last-child { border-right: none; }
.ds-val { font-family: var(--font-head); font-size: .95rem; font-weight: 700; color: var(--t1); display: block; }
.ds-lbl { font-size: .52rem; font-weight: 600; color: var(--t3); text-transform: uppercase; letter-spacing: .6px; display: block; margin-top: .1rem; }

.deck-tile-actions { display: flex; gap: .4rem; padding: .6rem .85rem; flex-wrap: wrap; }

/* AI suggestions */
.ai-suggestions { margin-top: .75rem; }
.deck-tip-summary {
  background: linear-gradient(180deg, rgba(124,92,255,.10), rgba(255,255,255,.02));
  border: 1px solid rgba(124,92,255,.25);
  border-radius: var(--radius-sm);
  padding: .7rem;
  margin-bottom: .55rem;
}
.deck-tip-summary-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .65rem;
  margin-bottom: .45rem;
}
.deck-tip-summary-head span {
  color: var(--t1);
  font-size: .82rem;
  font-weight: 700;
}
.deck-tip-summary-head small {
  color: var(--t3);
  font-size: .68rem;
  text-align: right;
}
.deck-tip-overlap-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: .35rem;
}
.deck-tip-overlap {
  text-align: left;
  background: var(--bg-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--t1);
  padding: .45rem .55rem;
  cursor: pointer;
  touch-action: manipulation;
}
.deck-tip-overlap span {
  display: block;
  font-size: .74rem;
  font-weight: 700;
}
.deck-tip-overlap small {
  display: block;
  color: var(--t3);
  font-size: .63rem;
  margin-top: .12rem;
}
.ai-suggestion {
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .75rem;
  margin-bottom: .5rem;
}
.ai-suggestion.high   { border-left: 3px solid var(--red); }
.ai-suggestion.medium { border-left: 3px solid var(--amber); }
.ai-suggestion.low    { border-left: 3px solid var(--green); }
.ai-sug-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .5rem;
  margin-bottom: .3rem;
}
.ai-sug-title { font-weight: 600; font-size: .85rem; color: var(--t1); margin-bottom: .3rem; }
.ai-sug-title-row .ai-sug-title { margin-bottom: 0; }
.ai-sug-body  { font-size: .8rem; color: var(--t2); line-height: 1.55; }
.ai-sug-source {
  flex-shrink: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: .16rem .45rem;
  color: var(--t3);
  background: var(--bg-4);
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .4px;
  text-transform: uppercase;
}

/* ── Analytics screen ────────────────────────────────────── */
.analytics-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .6rem;
  margin-bottom: 1.25rem;
}
.analytics-tile {
  background: var(--panel-grad);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .85rem;
}
.analytics-tile.full { grid-column: 1/-1; }
.analytics-survey-cta {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .75rem .85rem;
  margin: -.55rem 0 1rem;
  background: rgba(124, 92, 255, .12);
  border: 1px solid rgba(124, 92, 255, .45);
  border-radius: var(--radius);
  color: var(--t1);
  font-size: .82rem;
  text-align: left;
  cursor: pointer;
}
.analytics-survey-cta strong {
  color: var(--accent-l);
  font-size: .76rem;
  white-space: nowrap;
}
.at-val  { font-family: var(--font-head); font-size: 1.6rem; font-weight: 700; color: var(--t1); line-height: 1; }
.at-sub  { font-size: .72rem; color: var(--t3); margin-top: .25rem; }
.at-label { font-size: .7rem; font-weight: 600; color: var(--t3); text-transform: uppercase; letter-spacing: .6px; margin-bottom: .6rem; display: block; }
.analytics-trend {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .7rem;
}
.trend-label {
  display: block;
  color: var(--t3);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  margin-bottom: .35rem;
}
.trend-pips { display: flex; flex-wrap: wrap; gap: .3rem; }
.fun-pip {
  min-width: 24px;
  height: 24px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(245, 158, 11, .14);
  border: 1px solid rgba(245, 158, 11, .32);
  color: var(--amber);
  font-size: .74rem;
  font-weight: 800;
}
.analytics-diagnostic-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .45rem;
}
.analytics-diagnostic-grid.compact { margin-top: .45rem; }
.diag-pill {
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .55rem .6rem;
  min-width: 0;
}
.diag-pill strong {
  display: block;
  color: var(--t1);
  font-family: var(--font-head);
  font-size: 1rem;
  line-height: 1;
}
.diag-pill span {
  display: block;
  color: var(--t3);
  font-size: .68rem;
  font-weight: 700;
  margin-top: .25rem;
  text-transform: uppercase;
  letter-spacing: .4px;
}
.analytics-subblock {
  margin-top: .75rem;
  padding-top: .65rem;
  border-top: 1px solid var(--border);
}

.card-freq-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .4rem 0;
  border-bottom: 1px solid var(--border);
  font-size: .82rem;
}
.card-freq-row:last-child { border-bottom: none; }
.card-freq-name  { color: var(--t1); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-freq-count { font-weight: 700; color: var(--accent-l); font-size: .8rem; flex-shrink: 0; margin-left: .5rem; }
.card-freq-row-button {
  cursor: pointer;
  touch-action: manipulation;
  border-radius: var(--radius-sm);
  padding-left: .35rem;
  padding-right: .35rem;
  transition: background .12s, color .12s, transform .08s;
}
.card-freq-row-button:active {
  background: var(--bg-3);
  transform: scale(.99);
}
@media (hover: hover) {
  .card-freq-row-button:hover {
    background: var(--bg-3);
  }
  .card-freq-row-button:hover .card-freq-name {
    color: var(--accent-l);
  }
}

.opp-row {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .45rem 0;
  border-bottom: 1px solid var(--border);
  font-size: .82rem;
}
.opp-row:last-child { border-bottom: none; }
.opp-name { flex: 1; color: var(--t1); }
.opp-count { font-size: .72rem; color: var(--t3); }
.opp-wr   { font-weight: 600; font-size: .8rem; }
.opp-wr.good { color: var(--green); }
.opp-wr.bad  { color: var(--red); }

/* ── Settings screen ─────────────────────────────────────── */
.settings-section { margin-bottom: 1.5rem; }
.settings-section-title {
  font-size: .72rem;
  font-weight: 700;
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: .8px;
  margin-bottom: .75rem;
  display: block;
}
.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .85rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: .5rem;
}
.settings-label { font-size: .88rem; font-weight: 500; color: var(--t1); }
.settings-sub   { font-size: .75rem; color: var(--t3); margin-top: .1rem; }
.settings-profile-form {
  padding: .85rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.settings-profile-controls {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .5rem;
  align-items: center;
}
.settings-profile-form code {
  color: var(--t2);
  word-break: break-word;
}
.settings-danger .settings-row {
  background: linear-gradient(180deg, rgba(244,63,94,.08), var(--bg-2));
  border-color: rgba(244,63,94,.35);
}
.settings-danger .settings-section-title { color: var(--red); }

/* ── Modals ──────────────────────────────────────────────── */
.overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,.75);
  z-index: 100;
  align-items: center;
  justify-content: center;
  padding: calc(1rem + var(--safe-t)) calc(1rem + var(--safe-r))
           calc(1rem + var(--safe-b)) calc(1rem + var(--safe-l));
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  overflow-y: auto;
}
.overlay.open { display: flex; }
.modal {
  background: var(--panel-grad);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 1.5rem;
  width: 100%;
  max-width: 480px;
  position: relative;
  margin: auto;
  max-height: calc(100dvh - var(--safe-t) - var(--safe-b) - 2rem);
  overflow-y: auto;
}
.modal-sm { max-width: 340px; text-align: center; }
.modal-md { max-width: 440px; }
.modal-lg { max-width: 540px; }

/* ── Card lookup modal — restructured layout ─────────────────────────
   The default .modal has `overflow-y: auto` so long content scrolls.
   For the card lookup modal that caused a real problem: the dropdown
   results panel is absolutely-positioned inside the search wrap, and
   absolutely-positioned children get clipped by ancestors with
   non-visible overflow. The result was the dropdown showing only ~1
   item before being clipped at the modal's boundary.

   Fix: split the modal into two regions.
   1. Top region (.card-lookup-top): title + search input + dropdown.
      Doesn't scroll. Dropdown can render at its full natural size
      below the input without being clipped.
   2. Bottom region (.card-lookup-detail): card image + rulings.
      Scrolls vertically when content is tall.

   The outer modal sets overflow: visible so neither region clips
   the dropdown. Each region manages its own overflow internally. */
.modal.modal-cardlookup {
  display: flex;
  flex-direction: column;
  overflow: visible;   /* critical — let the dropdown extend past modal bounds if needed */
  /* The bottom region's own overflow handles long content; we don't
     need the outer modal's overflow-y any more. */
}
.card-lookup-top {
  flex-shrink: 0;
  position: relative;
  /* Stack above the detail so the dropdown's z-index works as expected
     when it overlaps onto the card-detail visually. */
  z-index: 2;
  margin-bottom: .75rem;
}
.card-lookup-detail {
  flex: 1;
  min-height: 0;       /* allow shrinking in the flex column */
  overflow-y: auto;
  /* Subtle inner padding so the rulings text doesn't hug the modal edge. */
  padding-right: .25rem;
}
.modal-title {
  font-family: var(--font-brand);
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--t1);
  margin-bottom: .35rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.modal-sub { font-size: .82rem; color: var(--t2); margin-bottom: 1rem; }
.modal-close {
  position: absolute; top: 1rem; right: 1rem;
  color: var(--t3); font-size: 1rem; line-height: 1;
  background: var(--bg-4); border: 1px solid var(--border);
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  touch-action: manipulation;
  /* Critical: must sit above .card-lookup-top (z-index: 2), the
     dropdown-results overlay, and any other positioned children
     inside the modal. Without this, clicks at the X's visible
     position were captured by the search-container flex child
     which has a higher z-index, so the modal stayed open. */
  z-index: 10;
  cursor: pointer;
}
.modal-close:active { color: var(--t1); }

.table-state-modal {
  max-width: 520px;
}
.table-state-section {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .025);
  padding: .7rem;
  margin-top: .65rem;
}
.table-state-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  margin-bottom: .5rem;
}
.table-state-label {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}

.rules-help-btn {
  width: 22px;
  height: 22px;
  min-width: 22px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-4);
  color: var(--accent-l);
  display: inline-grid;
  place-items: center;
  font-size: .68rem;
  font-weight: 900;
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
}
.rules-help-btn:active {
  border-color: var(--accent);
  transform: scale(.96);
}

.rules-reminder-card {
  display: grid;
  gap: .45rem;
}
.rules-reminder-line {
  border-left: 2px solid var(--accent);
  background: var(--bg-3);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: .55rem .7rem;
  color: var(--t2);
  font-size: .82rem;
  line-height: 1.5;
}
.rules-reminder-note {
  color: var(--t3);
  font-size: .74rem;
  line-height: 1.5;
  margin-top: .85rem;
}

.table-state-label {
  color: var(--t1);
  font-size: .78rem;
  font-weight: 800;
}
.table-state-help {
  color: var(--t3);
  font-size: .62rem;
  font-weight: 700;
}
.table-state-segmented,
.table-state-choice-grid {
  display: grid;
  gap: .35rem;
}
.table-state-segmented {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.table-state-choice-grid {
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
}
.table-state-segmented button,
.table-state-choice {
  min-height: 40px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-3);
  color: var(--t2);
  font-size: .75rem;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
}
.table-state-segmented button:active,
.table-state-choice:active {
  background: var(--bg-4);
  border-color: var(--accent);
  color: var(--t1);
}
.table-state-segmented button.selected,
.table-state-choice.selected {
  border-color: rgba(124, 108, 248, .7);
  background: rgba(124, 108, 248, .18);
  color: var(--t1);
}
.table-state-choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: .45rem .55rem;
  text-align: left;
}
.table-state-choice:disabled {
  opacity: .45;
  cursor: not-allowed;
}
.table-state-choice-name {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.table-state-choice-sub {
  color: var(--t3);
  font-size: .58rem;
  margin-top: .1rem;
}

.privacy-modal {
  max-height: 88dvh;
  display: flex;
  flex-direction: column;
}
.privacy-content {
  overflow-y: auto;
  padding-right: .25rem;
  color: var(--t2);
  font-size: .84rem;
  line-height: 1.6;
}
.privacy-content h3 {
  color: var(--t1);
  font-size: .82rem;
  font-weight: 800;
  letter-spacing: .5px;
  margin: 1rem 0 .35rem;
  text-transform: uppercase;
}
.privacy-content p { margin: 0 0 .75rem; }
.privacy-content ul {
  margin: 0 0 .8rem 1.1rem;
  padding: 0;
}
.privacy-content li { margin-bottom: .35rem; }
.privacy-content a {
  color: var(--accent-l);
  text-decoration: underline;
}

/* Dice */
.dice-results { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin: 1rem 0; }
.dice-item {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: var(--bg-3); border: 1.5px solid var(--border);
  border-radius: var(--radius); padding: .6rem .8rem; min-width: 70px;
  transition: all .3s;
}
.dice-item.winner { border-color: var(--accent); background: var(--accent-dim); }
.d-name { font-size: .68rem; font-weight: 600; color: var(--t2); }
.d-val  { font-family: var(--font-head); font-size: 1.8rem; font-weight: 700; color: var(--t1); line-height: 1; }
.dice-item.winner .d-val { color: var(--accent-l); }
.d-crown { font-size: .9rem; display: none; }
.dice-item.winner .d-crown { display: block; }
.dice-winner { font-weight: 600; color: var(--accent-l); text-align: center; display: none; font-size: .95rem; }
.dice-winner.show { display: block; }

/* Generic dice picker — grid of die-type buttons, plus a result area
   that animates the rolled value. Standalone from the "who goes first"
   dice modal which has its own player-list logic. */
.dice-picker-grid {
  display: grid;
  /* 3 columns. Standard dice in the first 2 rows (D4–D20), then
     D100 + Coin in the third row. Empty slot in row 3 keeps the
     grid balanced and matches Lotus's layout from the reference. */
  grid-template-columns: repeat(3, 1fr);
  gap: .55rem;
  margin: 1rem 0 .5rem;
}
.dice-picker-btn {
  /* Vertical stack: slot (icon OR value) on top, label below. The
     slot has a fixed height so swapping content doesn't reflow the
     grid — without this, a "17" replacing a D20 icon would change
     the tile height and make the layout jump. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .35rem;
  padding: .75rem .3rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--t1);
  font-family: var(--font-head);
  cursor: pointer;
  touch-action: manipulation;
  transition: background .12s, border-color .12s, transform .08s;
}
.dice-picker-btn:active {
  background: var(--bg-4);
  border-color: var(--accent);
  color: var(--accent-l);
  transform: scale(.96);
}
/* The slot is a fixed-size box that holds either the icon SVG or the
   rolled value <span>. Fixed dimensions prevent layout jumps when the
   content swaps. */
.dice-picker-slot {
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.dice-picker-icon {
  width: 100%;
  height: 100%;
  color: var(--accent-l);
}
.dice-picker-btn:active .dice-picker-icon {
  color: var(--accent);
}
/* Rolled value — replaces the icon in the slot. Sized to fit the slot
   comfortably; auto-shrinks for 3-digit d100 results via responsive
   font-size. */
.dice-picker-value {
  font-family: var(--font-head);
  font-size: 1.65rem;
  font-weight: 800;
  line-height: 1;
  color: var(--accent-l);
  /* Tighten letter-spacing so "Heads"/"Tails" fits without overflowing
     the 38px slot. The slot has a small bit of overflow tolerance
     thanks to no `overflow: hidden` constraint. */
  letter-spacing: -.02em;
  /* For multi-character text (Heads/Tails) shrink the font so it fits. */
}
.dice-picker-value:not(:empty) { white-space: nowrap; }
/* When a die tile has a result, tint the border + brighten the
   background so the rolled tile reads as "this is the active result"
   among its siblings. */
.dice-picker-btn.has-result {
  border-color: var(--accent);
  background: var(--accent-dim);
}
.dice-picker-lbl {
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .5px;
}
/* Pop animation — same dpr-pop keyframe as before, retriggered on
   each new roll via .rolled class. */
.dice-picker-btn.rolled .dice-picker-value {
  animation: dpr-pop .35s ease-out;
}

/* Heads/Tails text is longer than a number — shrink the font to keep
   it within the slot. Detect via the longer-text marker class we add
   only for coin results in JS — or just use a smaller font size for
   coin results specifically. Cleaner approach: any value with > 3
   chars uses a smaller size. We tag with a class for that. */
.dice-picker-btn[data-die="coin"] .dice-picker-value {
  font-size: .95rem;
}
@keyframes dpr-pop {
  0%   { transform: scale(.4); opacity: 0; }
  60%  { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Elim modal */
.elim-icon   { font-size: 3.5rem; margin-bottom: .5rem; display: block; }
.elim-name   { font-family: var(--font-head); font-size: 1.4rem; font-weight: 700; color: var(--t1); display: block; margin-bottom: .3rem; }
.elim-reason { font-size: .92rem; color: var(--red); display: block; margin-bottom: .5rem; font-weight: 500; }

/* Life set */
.life-set-input {
  font-family: var(--font-head) !important;
  font-size: 2.2rem !important;
  font-weight: 700 !important;
  text-align: center;
  margin-bottom: .85rem;
  letter-spacing: -.02em;
}

/* Card detail */
.card-detail-wrap { display: flex; gap: 1rem; margin-top: .85rem; flex-wrap: wrap; }
.card-img-col     { display: flex; flex-direction: column; align-items: center; gap: .4rem; }
.card-img-wrap img { width: 130px; border-radius: var(--radius-sm); display: block; }

/* The small card image is tappable to enlarge — hint via a magnifier
   badge in the top-right corner of the image. Subtle but signals
   interactivity for users who wouldn't otherwise know they can tap. */
.card-img-wrap.zoomable {
  position: relative;
  cursor: zoom-in;
  display: inline-block;
}
.card-img-wrap.zoomable .card-img-zoom-hint {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: .82rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

/* Flip button under dual-face cards in the detail view. Sits below the
   image and shows the OTHER face's name ("↻ Flip · Werewolf Form") so
   users see what they're flipping to. */
.card-flip-btn {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  padding: .35rem .65rem;
  font-size: .7rem;
  font-weight: 600;
  color: var(--accent-l);
  background: rgba(124, 108, 248, .12);
  border: 1px solid rgba(124, 108, 248, .35);
  border-radius: var(--radius-xs);
  cursor: pointer;
  white-space: nowrap;
  max-width: 130px;       /* match image width so it doesn't overflow */
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-flip-btn:hover,
.card-flip-btn:active {
  background: rgba(124, 108, 248, .22);
}

/* Fullscreen image zoom overlay. Hidden by default; .open sets it
   visible. Tap the dark backdrop OR the × to dismiss; tap the card
   itself to flip (for dual-face cards). Sits above all other UI.

   Padding respects Android's system insets (status bar at top, gesture
   nav bar at bottom) via the --safe-t / --safe-b vars established at
   the :root level. Without this, the close ✕ ends up partly behind the
   status bar and the flip button slips under the gesture pill. */
.card-img-zoom-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .92);
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
  /* Account for the AdMob banner at the bottom when present — without
     this, the centered image visually shifts under the banner. The
     padding pushes the image up so it stays centered in the VISIBLE
     space (overlay minus banner area). var(--ad-banner-h) is 0 by
     default and only set to the banner height when the banner is
     showing, so the math degrades cleanly for paid users. */
  padding: calc(var(--safe-t, 0px) + 2rem) 1rem
           calc(var(--safe-b, 0px) + 2rem) 1rem;
}
body.ad-banner-visible .card-img-zoom-overlay {
  padding-bottom: calc(var(--safe-b, 0px) + 2rem + var(--ad-banner-h));
}
.card-img-zoom-overlay.open { display: flex; }
.card-img-zoom-img {
  max-width: 100%;
  /* Account for both system insets in the height budget. 90vh on its
     own would still drift under the system bars on devices with large
     gesture areas. Subtract the safe-area insets plus a bit of breathing
     room for the close/flip buttons. */
  max-height: calc(100vh - var(--safe-t, 0px) - var(--safe-b, 0px) - 8rem);
  width: auto;
  height: auto;
  border-radius: var(--radius-md);
  box-shadow: 0 8px 32px rgba(0, 0, 0, .6);
  touch-action: none;
  user-select: none;
  transform-origin: center center;
  will-change: transform;
}
.card-img-zoom-img.is-zoomed {
  cursor: grab !important;
}
.card-img-zoom-img.is-zoomed:active {
  cursor: grabbing !important;
}
.card-img-zoom-close {
  position: absolute;
  /* 1rem below the status bar inset, 1rem from the right edge. */
  top: calc(var(--safe-t, 0px) + 1rem);
  right: 1rem;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .15);
  color: #fff;
  font-size: 1.15rem;
  font-weight: 700;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.card-img-zoom-close:hover,
.card-img-zoom-close:active {
  background: rgba(255, 255, 255, .28);
}
.card-img-zoom-flip {
  position: absolute;
  /* 1.5rem above the gesture-pill inset so the button always floats
     fully visible above Android's bottom system bar. When the AdMob
     banner is showing, lift by an additional --ad-banner-h so the
     button isn't hidden behind the banner. */
  bottom: calc(var(--safe-b, 0px) + 1.5rem);
  left: 50%;
  transform: translateX(-50%);
  padding: .65rem 1.2rem;
  font-size: .85rem;
  font-weight: 600;
  color: #fff;
  background: rgba(124, 108, 248, .85);
  border: 1px solid rgba(124, 108, 248, 1);
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .4);
}
body.ad-banner-visible .card-img-zoom-flip {
  bottom: calc(var(--safe-b, 0px) + 1.5rem + var(--ad-banner-h));
}
.card-img-zoom-flip:hover,
.card-img-zoom-flip:active {
  background: rgba(124, 108, 248, 1);
}

/* Small caption under the Flip button telling users they can also tap
   the card image to flip — the existing tap-to-flip behaviour wasn't
   discoverable. The hint is small and low-contrast so it doesn't
   compete with the card art for attention, but it's readable enough
   to communicate the interaction model. */
.card-img-zoom-tap-hint {
  position: absolute;
  /* Sit immediately below the Flip button. Mirror its lift logic so
     the hint moves up with the button when the ad banner is visible. */
  bottom: calc(var(--safe-b, 0px) + .35rem);
  left: 50%;
  transform: translateX(-50%);
  font-size: .68rem;
  font-weight: 500;
  color: rgba(255, 255, 255, .55);
  letter-spacing: .3px;
  pointer-events: none;
  white-space: nowrap;
}
body.ad-banner-visible .card-img-zoom-tap-hint {
  bottom: calc(var(--safe-b, 0px) + .35rem + var(--ad-banner-h));
}
/* When there's no back face (single-face card), the Flip button is
   hidden via inline style. The hint should hide too so we don't tell
   the user to tap-to-flip on a card that doesn't flip. */
.card-img-zoom-overlay.no-flip .card-img-zoom-tap-hint {
  display: none;
}
.card-text    { flex: 1; min-width: 160px; }
.card-title   { font-family: var(--font-head); font-size: 1rem; font-weight: 700; color: var(--t1); margin-bottom: .25rem; }
.card-mana    { font-size: .8rem; color: var(--accent-l); font-weight: 600; margin-bottom: .25rem; }
.card-type    { font-size: .78rem; color: var(--t2); margin-bottom: .5rem; }
.card-oracle  { font-size: .84rem; color: var(--t1); line-height: 1.65; margin-bottom: .75rem; white-space: pre-line; }
.card-pt      { font-size: .8rem; font-weight: 700; color: var(--t2); margin-bottom: .5rem; }
.rulings-hdr  { font-size: .68rem; font-weight: 700; color: var(--t3); text-transform: uppercase; letter-spacing: .8px; margin-bottom: .5rem; }
.ruling       { font-size: .8rem; color: var(--t2); border-left: 2px solid var(--accent); padding: .3rem .55rem; margin-bottom: .4rem; line-height: 1.55; }
.ruling-date  { font-size: .68rem; color: var(--t3); display: block; margin-bottom: 2px; font-weight: 600; }
.no-rulings   { font-size: .8rem; color: var(--t3); }
.card-printings {
  margin: .75rem 0 .9rem;
}
.card-printings-btn {
  width: 100%;
  justify-content: center;
}
.card-printings-list {
  margin-top: .55rem;
}
.card-printings-list.collapsed {
  display: none;
}
.card-printings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: .45rem;
}
.card-printing {
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--t2);
  padding: .35rem;
  text-align: center;
  cursor: pointer;
  touch-action: manipulation;
}
.card-printing.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(124,108,248,.35);
}
.card-printing img {
  width: 100%;
  max-width: 88px;
  border-radius: 4px;
  display: block;
  margin: 0 auto .28rem;
}
.card-printing span,
.card-printing small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-printing span {
  font-size: .66rem;
  font-weight: 800;
  color: var(--t1);
}
.card-printing small {
  font-size: .58rem;
  color: var(--t3);
}

/* Post-game survey */
.survey-q { margin-bottom: 1.25rem; }
.survey-q-label {
  font-size: .82rem; font-weight: 600; color: var(--t1);
  margin-bottom: .5rem; display: block;
}
.survey-q-sub { font-size: .75rem; color: var(--t3); margin-bottom: .5rem; display: block; }
.survey-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.survey-chip {
  padding: .35rem .7rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: 20px;
  font-size: .78rem;
  font-weight: 500;
  color: var(--t2);
  cursor: pointer;
  touch-action: manipulation;
  transition: all .12s;
  user-select: none;
}
.survey-chip.selected { background: var(--accent-dim); border-color: var(--accent); color: var(--accent-l); }
.survey-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .75rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: .4rem;
  touch-action: manipulation;
  cursor: pointer;
}
.survey-toggle.on { border-color: rgba(16,185,129,.4); }
.toggle-label { font-size: .85rem; color: var(--t1); font-weight: 500; }
.toggle-dot {
  width: 40px; height: 22px;
  background: var(--bg-5);
  border-radius: 11px;
  position: relative;
  transition: background .2s;
  flex-shrink: 0;
}
.toggle-dot::after {
  content: '';
  position: absolute;
  width: 16px; height: 16px;
  background: var(--t3);
  border-radius: 50%;
  top: 3px; left: 3px;
  transition: all .2s;
}
.survey-toggle.on .toggle-dot { background: var(--green); }
.survey-toggle.on .toggle-dot::after { left: 21px; background: #fff; }

.star-rating { display: flex; gap: .4rem; }
.star {
  font-size: 1.6rem;
  color: var(--bg-5);
  cursor: pointer;
  touch-action: manipulation;
  transition: color .1s;
  user-select: none;
}
.star.active { color: var(--amber); }

.survey-winner-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .4rem; }
.winner-option {
  padding: .6rem .75rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: .82rem;
  font-weight: 500;
  color: var(--t2);
  cursor: pointer;
  touch-action: manipulation;
  transition: all .12s;
  text-align: center;
}
.winner-option.selected { background: var(--accent-dim); border-color: var(--accent); color: var(--accent-l); }

/* Manual deck card builder */
.manual-card-builder { position: relative; }
.manual-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
}
.manual-card-count {
  font-size: .68rem;
  color: var(--t3);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.manual-card-list {
  margin-top: .5rem;
  display: flex;
  flex-direction: column;
  gap: .4rem;
  max-height: min(260px, 34dvh);
  overflow-y: auto;
  padding-right: .15rem;
}
.manual-card-empty {
  color: var(--t3);
  font-size: .78rem;
  line-height: 1.35;
  padding: .65rem .7rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,.025);
}
.manual-card-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .55rem;
  padding: .45rem .5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-3);
}
.manual-card-main {
  min-width: 0;
  flex: 1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .3rem;
}
.manual-card-qty {
  min-width: 1.35rem;
  text-align: center;
  color: var(--accent-l);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.manual-card-name {
  min-width: 0;
  max-width: 100%;
  color: var(--t1);
  font-size: .78rem;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.manual-card-type {
  flex-basis: 100%;
  margin-left: 1.65rem;
  color: var(--t3);
  font-size: .66rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.manual-card-actions {
  display: flex;
  align-items: center;
  gap: .25rem;
  flex-shrink: 0;
}
.manual-card-actions .ctr-btn,
.manual-card-actions .chip-clear {
  width: 28px;
  height: 28px;
  min-width: 28px;
  border-radius: 7px;
  display: grid;
  place-items: center;
  background: var(--bg-4);
  border: 1px solid var(--border);
}
.manual-card-actions .chip-clear {
  padding: 0;
  color: var(--t2);
}

.csalt-bracket-select {
  width: 100%;
  background: var(--bg-3);
  color: var(--t1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .65rem .7rem;
  font-size: .85rem;
}

/* Import UI */
.import-preview-box {
  background: var(--bg-3);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: .85rem;
  margin-bottom: .85rem;
}
.import-preview-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .4rem; }
.import-cmd-chip-inner { display: flex; align-items: center; gap: .5rem; }
.import-cmd-name { font-size: .82rem; font-weight: 600; color: var(--t1); flex: 1; }
.import-cmd-ok   { color: var(--green); font-size: .85rem; }
.import-err-line { font-size: .74rem; color: var(--amber); padding: .1rem 0; }
.import-size-warn {
  margin-top: .5rem;
  padding: .45rem .65rem;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.4);
  border-radius: var(--radius-sm);
  color: var(--amber);
  font-size: .76rem;
  font-weight: 500;
}
.loading-row {
  display: flex; align-items: center; gap: .5rem;
  font-size: .8rem; color: var(--t2); padding: .4rem 0;
}

/* Dropdowns */
.dropdown-results {
  position: absolute; top: 100%; left: 0; right: 0;
  background: var(--bg-3);
  border: 1px solid var(--accent);
  border-top: none;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  /* Show 5-6 results at the default item height. The list scrolls
     vertically if more match. Cap at dvh-based value so it never
     extends below the visible viewport when the keyboard is open. */
  max-height: min(360px, 40dvh);
  overflow-y: auto;
  z-index: 50;
}
.dropdown-item {
  display: flex; align-items: center; gap: .65rem;
  padding: .55rem .75rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background .1s;
  touch-action: manipulation;
  /* Min-height ensures each item is comfortably tappable (≥44px tap target). */
  min-height: 50px;
}
.dropdown-item:last-child { border-bottom: none; }
.dropdown-item:active { background: var(--bg-4); }
.drop-thumb    { width: 30px; height: 42px; object-fit: cover; border-radius: 3px; flex-shrink: 0; }
.drop-thumb-ph { width: 30px; height: 42px; background: var(--bg-5); border-radius: 3px; flex-shrink: 0; }
.drop-name { font-size: .82rem; font-weight: 500; color: var(--t1); }
.drop-type { font-size: .7rem; color: var(--t2); }
/* Hint text inside a dropdown when the search can't run yet (e.g.
   sigspell search needs an oathbreaker picked first) or when no
   results match the format restrictions. */
.dropdown-empty {
  padding: .65rem .8rem;
  font-size: .78rem;
  color: var(--t2);
  font-style: italic;
  background: var(--bg-2);
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border);
}

/* Commander chip */
.cmd-chip {
  display: flex; align-items: center; gap: .45rem;
  background: var(--bg-3); border: 1px solid var(--accent);
  border-radius: var(--radius-xs); padding: .35rem .6rem; margin-top: .4rem;
}
.cmd-chip img { width: 24px; height: 33px; object-fit: cover; border-radius: 2px; }
.cmd-chip-name { font-size: .8rem; font-weight: 600; color: var(--t1); flex: 1; }
.chip-clear {
  color: var(--t3); font-size: .9rem; line-height: 1; padding: .1rem;
  touch-action: manipulation;
}
.chip-clear:active { color: var(--red); }

/* Search */
.search-input {
  padding-right: 2.5rem !important;
}

/* Spinners */
.spinner-inline {
  position: absolute; right: .7rem; top: 50%;
  transform: translateY(-50%);
  width: 16px; height: 16px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .6s linear infinite;
}
.spinner-sm {
  width: 14px; height: 14px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .6s linear infinite;
  flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Toast */
#toast-wrap {
  position: fixed;
  bottom: calc(var(--nav-h) + var(--safe-b) + .75rem);
  right: .75rem;
  z-index: 999;
  display: flex; flex-direction: column; gap: .35rem;
  pointer-events: none;
}
.toast {
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-sm);
  padding: .6rem 1rem;
  font-size: .8rem;
  font-weight: 500;
  color: var(--t1);
  max-width: 260px;
  box-shadow: 0 4px 20px rgba(0,0,0,.5);
  opacity: 1;
  transition: opacity .3s;
}
.toast.error { border-color: rgba(244,63,94,.4); color: var(--red); }

/* States */
.empty-state { color: var(--t3); text-align: center; padding: 3rem 1rem; font-size: .88rem; }
.loading-state { color: var(--t2); text-align: center; padding: 2rem; font-size: .85rem; }
.deck-update-progress {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: linear-gradient(180deg, rgba(124,92,255,.1), rgba(255,255,255,.02));
  padding: .75rem;
  color: var(--t2);
  overflow: hidden;
}
.deck-update-progress-head {
  display: flex;
  align-items: center;
  gap: .45rem;
  font-size: .82rem;
  font-weight: 700;
  color: var(--t1);
}
.deck-update-progress-msg {
  margin-top: .28rem;
  font-size: .75rem;
  color: var(--t3);
}
.deck-update-progress-bar {
  position: relative;
  height: 4px;
  margin-top: .65rem;
  border-radius: 999px;
  background: rgba(255,255,255,.08);
  overflow: hidden;
}
.deck-update-progress-fill {
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width .28s ease;
}
.deck-update-progress-fill.active::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.35), transparent);
  animation: progressSheen 1s linear infinite;
}
@keyframes progressSheen {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}
.fatal-error {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 60vh; text-align: center; padding: 2rem;
}
.fatal-error-icon { font-size: 2.5rem; margin-bottom: 1rem; }
.fatal-error-msg  { color: var(--red); font-size: .9rem; max-width: 340px; line-height: 1.6; }
.fatal-error-code { color: var(--t3); font-size: .78rem; margin-top: .75rem; font-family: monospace; }

/* ── Bottom nav: 5 items now ─────────────────────────────── */
#app-nav .nav-item { padding: .25rem; }
#app-nav .nav-label { font-size: .56rem; }
#app-nav .nav-icon  { font-size: 1.1rem; }

/* ══════════════════════════════════════════════════════════
   Friends & Social Games UI
   ══════════════════════════════════════════════════════════ */

/* Notification badge on header icon */
.notif-badge {
  position: absolute;
  top: -3px; right: -3px;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--red);
  color: #fff;
  font-size: .65rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--bg-2);
  line-height: 1;
}

/* Pending survey banner */
.pending-banner {
  background: linear-gradient(135deg, var(--accent-dim), rgba(124,108,248,.05));
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  margin-bottom: 1rem;
  overflow: hidden;
  animation: slideDown .4s ease;
}
@keyframes slideDown { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }

.pending-banner-inner {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .75rem 1rem;
}
.pending-banner-icon {
  font-size: 1.5rem;
  flex-shrink: 0;
}
.pending-banner-text { flex: 1; min-width: 0; }
.pending-banner-title {
  font-weight: 700;
  font-size: .9rem;
  color: var(--t1);
}
.pending-banner-sub {
  font-size: .75rem;
  color: var(--t2);
  margin-top: .15rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pending-banner-btn {
  padding: .5rem 1rem;
  background: var(--accent);
  border-radius: var(--radius-sm);
  color: #fff;
  font-size: .8rem;
  font-weight: 600;
  flex-shrink: 0;
  touch-action: manipulation;
}
.pending-banner-btn:active { opacity: .85; }
.pending-banner-close {
  width: 24px; height: 24px;
  color: var(--t3);
  font-size: .9rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  touch-action: manipulation;
}

/* Friends screen */
.friend-row {
  display: flex;
  align-items: center;
  gap: .75rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .75rem;
  margin-bottom: .5rem;
}
.friend-av {
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--accent-dim);
  border: 1.5px solid var(--accent);
  color: var(--accent-l);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: .9rem;
  flex-shrink: 0;
  text-transform: uppercase;
}
.friend-info { flex: 1; min-width: 0; }
.friend-name {
  font-weight: 600;
  color: var(--t1);
  font-size: .9rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.friend-sub {
  font-size: .72rem;
  color: var(--t3);
  margin-top: .1rem;
}
.friend-actions {
  display: flex;
  gap: .4rem;
  flex-shrink: 0;
}

/* Setup row when linked to a friend */
.setup-row-linked {
  border-color: var(--accent) !important;
  background: linear-gradient(135deg, var(--bg-2), var(--accent-dim)) !important;
}
.linked-player-chip {
  display: flex;
  align-items: center;
  gap: .55rem;
  flex: 1;
  min-width: 0;
}
.linked-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--accent-dim);
  border: 1.5px solid var(--accent);
  color: var(--accent-l);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: .78rem;
  flex-shrink: 0;
}
.linked-info { flex: 1; min-width: 0; }
.linked-name {
  font-weight: 600;
  color: var(--t1);
  font-size: .85rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.linked-tag {
  font-size: .65rem;
  color: var(--accent-l);
  font-weight: 600;
  letter-spacing: .3px;
  margin-top: .1rem;
}
.btn-link-friend {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--accent-dim);
  border: 1px solid var(--accent);
  color: var(--accent-l);
  font-size: .85rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  touch-action: manipulation;
  transition: all .15s;
}
.btn-link-friend:active {
  background: var(--accent);
  color: #fff;
}

/* Friend picker bottom sheet */
/* Friend picker — full-viewport bottom sheet */
.friend-picker-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  z-index: 1000;
  pointer-events: none;
  transition: background .18s ease;
}
.friend-picker-overlay.open {
  background: rgba(0, 0, 0, 0.55);
  pointer-events: auto;
}
.friend-picker-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 75dvh;
  background: var(--bg-2);
  border-top: 1px solid var(--accent);
  border-top-left-radius: 18px;
  border-top-right-radius: 18px;
  padding: .5rem calc(1rem + var(--safe-r)) calc(1.25rem + var(--safe-b)) calc(1rem + var(--safe-l));
  transform: translateY(100%);
  transition: transform .22s ease;
  z-index: 1001;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
}
.friend-picker-overlay.open .friend-picker-sheet {
  transform: translateY(0);
}
.friend-picker-handle {
  width: 38px;
  height: 4px;
  background: var(--border-2);
  border-radius: 2px;
  margin: .35rem auto .75rem;
  flex-shrink: 0;
}
.friend-picker-inner {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
}
.friend-picker-title {
  font-weight: 700;
  color: var(--t1);
  font-size: .9rem;
  margin-bottom: .75rem;
  flex-shrink: 0;
}
.friend-picker-list {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.friend-picker-item {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .65rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  touch-action: manipulation;
  transition: all .12s;
}
.friend-picker-item:active {
  border-color: var(--accent);
  background: var(--accent-dim);
}
.friend-picker-name {
  flex: 1;
  font-weight: 500;
  color: var(--t1);
  font-size: .85rem;
}
.friend-picker-arrow {
  color: var(--t3);
  font-size: 1.2rem;
}

/* ══════════════════════════════════════════════════════════
   Events
   ══════════════════════════════════════════════════════════ */

.event-section.active { margin-top: .25rem; }

.event-empty {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: .9rem;
  margin-top: .5rem;
}
.event-empty-text {
  color: var(--t2);
  font-size: .82rem;
  line-height: 1.45;
  margin-bottom: .85rem;
}
.event-empty-actions {
  display: flex;
  gap: .65rem;
}
.event-empty-actions > * { flex: 1; }

/* Active event banner */
.event-banner {
  background: linear-gradient(135deg, var(--accent-dim), rgba(124,108,248,.12));
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  padding: .85rem;
  margin-top: .5rem;
}
.event-banner-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .5rem;
}
.event-banner-name {
  font-size: 1rem;
  font-weight: 700;
  color: var(--t1);
  font-family: var(--font-head);
}
.event-banner-meta {
  font-size: .72rem;
  color: var(--t3);
  margin-top: .15rem;
}
.event-banner-actions { display: flex; gap: .35rem; }

.event-code-row {
  display: flex;
  align-items: center;
  gap: .65rem;
  margin-top: .8rem;
  padding: .55rem .75rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.event-code-label {
  font-size: .65rem;
  font-weight: 700;
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: 1px;
}
.event-code-value {
  font-family: var(--font-mono, monospace);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 1.5px;
  flex: 1;
  cursor: pointer;
  touch-action: manipulation;
}
.event-code-value:active {
  opacity: .6;
}
.event-share-btn {
  background: var(--accent);
  color: #fff;
  font-size: .72rem;
  font-weight: 600;
  padding: .4rem .7rem;
  border-radius: var(--radius-sm);
  border: none;
  cursor: pointer;
  touch-action: manipulation;
  white-space: nowrap;
  flex-shrink: 0;
}
.event-share-btn:active {
  opacity: .8;
}
.event-code-hint {
  font-size: .65rem;
  color: var(--t3);
}

/* Participant rows in event section */
.event-part-row {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .5rem .65rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: .35rem;
}
.event-part-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  min-width: 0;
}
.event-part-name {
  font-size: .85rem;
  font-weight: 500;
  color: var(--t1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.event-part-table {
  font-size: .68rem;
  color: var(--accent);
  font-weight: 500;
}
.event-part-table.free {
  color: var(--t3);
  font-style: italic;
}

/* Friend picker sections */
.friend-picker-section {
  margin-bottom: .75rem;
}
.friend-picker-section-label {
  font-size: .62rem;
  font-weight: 700;
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: .35rem;
  padding-left: .25rem;
}
.friend-av.event {
  background: linear-gradient(135deg, var(--accent), rgba(124,108,248,.5));
}

/* ══════════════════════════════════════════════════════════
   Notifications panel
   ══════════════════════════════════════════════════════════ */

.icon-action-wrap {
  position: relative;
}
.modal-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin-bottom: .25rem;
}
.modal-title-row .modal-title { margin-bottom: 0; }

.notif-row {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  padding: .65rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: .4rem;
}
.notif-icon-cell {
  width: 36px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.notif-emoji { font-size: 1.4rem; }
.notif-body  { flex: 1; min-width: 0; }
.notif-title {
  font-size: .85rem;
  font-weight: 500;
  color: var(--t1);
}
.notif-sub {
  font-size: .73rem;
  color: var(--t2);
  margin-top: .15rem;
}
.notif-meta {
  font-size: .68rem;
  color: var(--t3);
  margin-top: .2rem;
}
.notif-actions {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  align-items: flex-end;
  flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════
   Recent Games on Decks screen
   ══════════════════════════════════════════════════════════ */

.recent-game-row {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .55rem .7rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: .35rem;
}
.recent-game-info {
  flex: 1;
  min-width: 0;
}
.recent-game-top {
  display: flex;
  align-items: center;
  gap: .35rem;
  font-size: .85rem;
  color: var(--t1);
}
.recent-game-deck {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.recent-game-deck.unassigned {
  color: var(--amber);
  font-style: italic;
}
.recent-game-meta {
  font-size: .68rem;
  color: var(--t3);
  margin-top: .2rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ══════════════════════════════════════════════════════════
   Setup row commander UI (primary + partner)
   ══════════════════════════════════════════════════════════ */

.cmd-area {
  margin-top: .4rem;
}
.cmd-input-area {
  position: relative;
}
.cmd-chip-area {
  display: flex;
  flex-direction: column;
  gap: .35rem;
}
.btn-add-partner {
  margin-top: .25rem;
  padding: .35rem .65rem;
  background: transparent;
  border: 1px dashed var(--accent);
  border-radius: var(--radius-sm);
  color: var(--accent);
  font-size: .72rem;
  font-weight: 500;
  cursor: pointer;
  touch-action: manipulation;
  align-self: flex-start;
}
.btn-add-partner:active {
  background: var(--accent-dim);
}

/* ══════════════════════════════════════════════════════════
   Deck cards browser (grouped by type)
   ══════════════════════════════════════════════════════════ */

.deck-cards-group {
  margin-bottom: 1rem;
}
.deck-cards-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .35rem 0;
  border-bottom: 1px solid var(--border);
  margin-bottom: .35rem;
}
.deck-cards-group-name {
  font-weight: 700;
  color: var(--accent);
  font-size: .82rem;
  text-transform: uppercase;
  letter-spacing: .8px;
}
.deck-cards-group-count {
  background: var(--bg-3);
  color: var(--t2);
  padding: .15rem .5rem;
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 600;
}
.deck-cards-row {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .4rem .5rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  touch-action: manipulation;
}
.deck-cards-row:active {
  background: var(--accent-dim);
}
.deck-cards-qty {
  flex-shrink: 0;
  min-width: 22px;
  text-align: right;
  font-weight: 600;
  color: var(--t3);
  font-size: .82rem;
}
.deck-cards-name {
  flex: 1;
  font-size: .85rem;
  color: var(--t1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.deck-cards-type {
  font-size: .68rem;
  color: var(--t3);
  font-style: italic;
  flex-shrink: 0;
  max-width: 40%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ══════════════════════════════════════════════════════════
   Tips header with refresh button
   ══════════════════════════════════════════════════════════ */

.ai-sug-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: .25rem;
  margin-bottom: .35rem;
}
.ai-sug-head .btn-sm {
  font-size: .72rem;
}

/* ══════════════════════════════════════════════════════════
   Tips perspective picker
   ══════════════════════════════════════════════════════════ */

.ai-sug-controls {
  display: flex;
  gap: .35rem;
  align-items: center;
  flex-shrink: 0;
}
.ai-sug-perspective {
  background: var(--bg-3);
  color: var(--t1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .3rem .5rem;
  font-size: .72rem;
  max-width: 60vw;
  cursor: pointer;
  touch-action: manipulation;
}
.ai-sug-perspective:focus {
  outline: none;
  border-color: var(--accent);
}
.ai-sug-refresh {
  flex-shrink: 0;
  font-size: .9rem;
  padding: .2rem .55rem;
  line-height: 1;
}

/* Type-based left-border color (overrides priority-based) */
.ai-suggestion.ai-sug-keep    { border-left: 3px solid var(--green); }
.ai-suggestion.ai-sug-cut     { border-left: 3px solid var(--red); }
.ai-suggestion.ai-sug-info    { border-left: 3px solid var(--accent); }

/* ══════════════════════════════════════════════════════════
   Deck cards detail flyout (slides over the grouped list)
   ══════════════════════════════════════════════════════════ */

/* Modal becomes a fixed-height column. Header is non-scroll;
   list scrolls; flyout covers the whole modal area. */
.deck-cards-shell {
  position: relative;
  max-height: 88dvh;
  height: 88dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;     /* the children handle their own scrolling */
  padding: 0;           /* shell handles padding internally on header/list */
}
.deck-cards-header {
  flex-shrink: 0;
  padding: 1.5rem 1.5rem .5rem;
}
.deck-cards-list-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
  padding: 0 1.5rem 1.5rem;
}

.deck-cards-detail {
  position: absolute;
  inset: 0;
  background: var(--bg-2);
  border-radius: var(--radius);
  padding: .85rem;
  display: flex;
  flex-direction: column;
  gap: .65rem;
  z-index: 5;
  overflow: hidden;     /* outer is fixed; only the body scrolls */
}
.deck-cards-detail-body {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}
.deck-cards-detail-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  flex-wrap: wrap;
  flex-shrink: 0;
  /* Reserve clearance on the right edge for the modal's absolutely-
     positioned X close button (.modal-close: right:1rem, width:28px,
     z-index:10). Without this padding, the rightmost child of this
     bar (the Next button) sits directly under the X, clipping its
     label and stealing taps. The 3rem value covers the 28px button
     + 1rem offset + small visual breathing room. */
  padding-right: 3rem;
}
.deck-cards-detail-nav {
  display: flex;
  align-items: center;
  gap: .35rem;
}
.deck-cards-detail-counter {
  font-size: .72rem;
  color: var(--t3);
  font-variant-numeric: tabular-nums;
  min-width: 50px;
  text-align: center;
}
.deck-cards-detail-typebar {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .65rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  flex-wrap: wrap;
  flex-shrink: 0;
}
.deck-cards-detail-typelabel {
  font-size: .68rem;
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: .8px;
  font-weight: 600;
}
.deck-cards-detail-typevalue {
  flex: 1;
  font-size: .82rem;
  color: var(--t1);
  font-weight: 500;
}
.deck-cards-overridetag {
  font-size: .62rem;
  color: var(--accent);
  background: var(--accent-dim);
  padding: 1px 5px;
  border-radius: 999px;
  margin-left: .35rem;
  vertical-align: middle;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .5px;
}

/* Manual card resolution (shown for unresolved Unknown cards) */
.unknown-card-resolver {
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 1rem;
}
.unknown-card-resolver-title {
  font-weight: 700;
  color: var(--t1);
  font-size: .9rem;
  margin-bottom: .35rem;
}
.unknown-card-resolver-sub {
  font-size: .78rem;
  color: var(--t2);
  margin-bottom: .85rem;
  line-height: 1.45;
}
.unknown-card-resolver .field {
  position: relative;
}
.unknown-card-resolver-results {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-top: .25rem;
  max-height: 280px;
  overflow-y: auto;
  z-index: 10;
}
.unknown-card-resolver-results.open { display: block; }
.unknown-card-resolver-result {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .55rem .65rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  touch-action: manipulation;
}
.unknown-card-resolver-result:last-child { border-bottom: none; }
.unknown-card-resolver-result:active { background: var(--accent-dim); }
.unknown-card-resolver-result-thumb {
  width: 32px;
  height: 44px;
  border-radius: 3px;
  flex-shrink: 0;
}
.unknown-card-resolver-result-info {
  flex: 1;
  min-width: 0;
}
.unknown-card-resolver-result-name {
  font-weight: 500;
  font-size: .85rem;
  color: var(--t1);
}
.unknown-card-resolver-result-type {
  font-size: .72rem;
  color: var(--t3);
  margin-top: .15rem;
}
.unknown-card-actions {
  display: flex;
  gap: .5rem;
  margin-top: .65rem;
}

/* Type override picker buttons */
.type-picker-options {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: .35rem;
  margin-top: .65rem;
}
.type-picker-btn {
  padding: .55rem .65rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--t1);
  font-size: .82rem;
  font-weight: 500;
  cursor: pointer;
  touch-action: manipulation;
  transition: all .12s;
}
.type-picker-btn:active {
  background: var(--accent-dim);
  border-color: var(--accent);
}
.type-picker-btn.active {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}
.type-picker-btn.type-picker-clear {
  grid-column: span 2;
  font-size: .72rem;
  font-weight: 400;
  color: var(--t2);
  font-style: italic;
}

/* ══════════════════════════════════════════════════════════
   Games tab landing screen
   ══════════════════════════════════════════════════════════ */

.games-action-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .7rem;
  align-items: stretch;
  margin: .5rem 0 1.5rem;
}
.games-new-btn {
  width: 100%;
  font-size: .95rem;
  padding: .9rem 1rem;
}
.games-join-live-btn {
  width: auto;
  white-space: nowrap;
  padding-left: 1rem;
  padding-right: 1rem;
}

.live-sync-panel {
  display: flex;
  flex-direction: column;
  gap: .75rem;
}
.live-sync-status {
  padding: .75rem .85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgba(35, 30, 58, .86), rgba(14, 13, 20, .96));
}
.live-sync-status.host {
  border-color: rgba(124, 108, 248, .45);
}
.live-sync-status.participant {
  border-color: rgba(16, 185, 129, .45);
}
.live-sync-status-title {
  color: var(--t1);
  font-weight: 800;
  font-size: .92rem;
}
.live-sync-status-sub {
  color: var(--t2);
  font-size: .76rem;
  line-height: 1.38;
  margin-top: .18rem;
}
.live-sync-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .55rem .75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-3);
  color: var(--t2);
  font-size: .78rem;
}
.live-sync-row strong {
  color: var(--t1);
  text-align: right;
}
.live-code-row {
  margin-top: 0;
}

@media (max-width: 460px) {
  .games-action-row {
    grid-template-columns: 1fr;
  }
  .games-join-live-btn {
    width: 100%;
  }
}

.active-game-banner {
  display: flex;
  align-items: center;
  gap: .85rem;
  background: var(--bg-2);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: .85rem 1rem;
  margin-bottom: 1rem;
  box-shadow: 0 0 0 0 var(--accent-dim);
  animation: activeGamePulse 2.4s ease-in-out infinite;
}
.live-game-banner {
  border-color: rgba(16, 185, 129, .62);
  background: linear-gradient(180deg, rgba(16, 185, 129, .08), rgba(18, 18, 24, .98));
}
.live-game-banner .active-game-title {
  color: var(--green);
}
.active-game-info { flex: 1; min-width: 0; }
.active-game-title {
  font-weight: 700;
  color: var(--accent);
  font-size: .9rem;
}
.active-game-sub {
  font-size: .76rem;
  color: var(--t2);
  margin-top: .15rem;
}
/* The Resume button inside this banner must NOT inherit the global
   .btn-primary { width: 100% } — that would claim the entire row and
   squash the info text into a single-character-wide column (which is
   exactly what previously happened). Override to natural width plus
   a comfortable horizontal padding. */
.active-game-banner .btn-primary {
  width: auto;
  flex-shrink: 0;
  padding: .65rem 1.25rem;
}

@keyframes activeGamePulse {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50%      { box-shadow: 0 0 0 4px var(--accent-dim); }
}

/* ══════════════════════════════════════════════════════════
   Survey card picker — searchable replacement for chip grid
   ══════════════════════════════════════════════════════════ */

.survey-picker {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
.survey-picker-selected {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  min-height: 0;
}
.survey-picker-selected:empty {
  display: none;
}
.survey-pick-chip {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  background: var(--accent-dim);
  border: 1px solid var(--accent);
  color: var(--t1);
  padding: .25rem .35rem .25rem .55rem;
  border-radius: 999px;
  font-size: .76rem;
  font-weight: 500;
  line-height: 1.2;
}
.survey-pick-chip-x {
  background: transparent;
  border: none;
  color: var(--t2);
  font-size: 1rem;
  line-height: 1;
  padding: 0 .25rem;
  cursor: pointer;
  touch-action: manipulation;
  border-radius: 50%;
}
.survey-pick-chip-x:active {
  background: var(--bg-3);
  color: var(--t1);
}

.survey-picker-search {
  position: relative;
}
.survey-picker-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.survey-picker-input {
  width: 100%;
  padding: .55rem 2.25rem .55rem .75rem;   /* right padding for clear button */
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--t1);
  font-size: .85rem;
  font-family: var(--font);
}
.survey-picker-input:focus {
  outline: none;
  border-color: var(--accent);
}
.survey-picker-clear {
  position: absolute;
  right: .35rem;
  top: 50%;
  transform: translateY(-50%);
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--bg-4);
  border: 1px solid var(--border);
  color: var(--t2);
  font-size: .75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  touch-action: manipulation;
}
.survey-picker-clear:active {
  background: var(--accent-dim);
  color: var(--accent);
}
.survey-picker-results {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: .25rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  max-height: 240px;
  overflow-y: auto;
  z-index: 20;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
}
.survey-picker-results.open { display: block; }
.survey-picker-result {
  padding: .55rem .75rem;
  font-size: .82rem;
  color: var(--t1);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  touch-action: manipulation;
}
.survey-picker-result:last-child { border-bottom: none; }
.survey-picker-result:active {
  background: var(--accent-dim);
  color: var(--accent);
}
.survey-picker-empty {
  padding: .65rem .75rem;
  font-size: .78rem;
  color: var(--t3);
  font-style: italic;
}

/* Tappable counter values + form pips. Affordance is subtle — the
   cursor change + a slight active state — since the +/- buttons remain
   the primary interaction. */
.ctr-val.tappable {
  cursor: pointer;
  touch-action: manipulation;
  border-radius: 4px;
  padding: 0 .15rem;
  transition: background .12s;
}
.ctr-val.tappable:active {
  background: var(--bg-5);
}
.form-pip.tappable {
  cursor: pointer;
  touch-action: manipulation;
  transition: transform .1s;
}
.form-pip.tappable:active {
  transform: scale(.92);
}

/* Stats screen — screen-wide deck filter at the top of the dashboard.
   Renders as a sticky-feeling row that anchors what scope you're viewing. */
.stats-filter-bar {
  display: flex;
  align-items: center;
  gap: .5rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .5rem .75rem;
  margin-bottom: .8rem;
}
.stats-filter-label {
  font-size: .75rem;
  font-weight: 600;
  color: var(--t2);
  flex-shrink: 0;
  text-transform: uppercase;
  letter-spacing: .5px;
}
.stats-filter-bar .stats-deck-filter {
  flex: 1;
  font-size: .85rem;
  padding: .35rem .5rem;
  max-width: none;
}

/* Legacy per-section header (still in CSS in case any layout reuses it) */
.stats-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin-bottom: .35rem;
}
.stats-deck-filter {
  background: var(--bg-3);
  color: var(--t1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .25rem .5rem;
  font-size: .72rem;
  max-width: 60vw;
  cursor: pointer;
  touch-action: manipulation;
}
.stats-deck-filter:focus {
  outline: none;
  border-color: var(--accent);
}


/* ── Pill-list navigation bar inside the card-detail modal ─────────
   Appears at the top of the card detail when the user opened the
   card from a suggestion section with multiple cards. Lets them
   step Prev / Next through the list without closing and re-tapping.
   Renders only when ui._pillNavState is set (a list of 2+ cards). */
.pill-nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin-bottom: .85rem;
  /* Right-padding bumped from .65rem to 3rem to clear the modal's
     absolutely-positioned X close button. See .deck-cards-detail-bar
     for the same rationale — this bar's rightmost child (the Next
     button) would otherwise sit directly under the X. */
  padding: .5rem 3rem .5rem .65rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.pill-nav-btn {
  background: var(--bg-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  color: var(--t1);
  padding: .4rem .8rem;
  font-size: .85rem;
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
  transition: background .12s, border-color .12s, color .12s;
  /* Generous min-width so both buttons are similar size visually
     even though "Next ›" is shorter than "‹ Prev". */
  min-width: 4.5rem;
}
.pill-nav-btn:active {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent-l);
}
.pill-nav-btn:disabled {
  opacity: .35;
  cursor: not-allowed;
}
.pill-nav-btn:disabled:active {
  /* Override the :active state so disabled buttons don't flash
     as if they responded to the tap. */
  background: var(--bg-4);
  border-color: var(--border);
  color: var(--t1);
}
.pill-nav-pos {
  font-size: .8rem;
  color: var(--t2);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
