/* GambitCoach - themeable.  Default = "mint" (teal/pale-green palette).
   Switch palettes via the topbar palette button - click to open a popover
   with all available themes.  Each theme overrides the variables defined in
   the default :root block; the chess.com category colors stay constant. */
* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0; height: 100%;
  font-family: var(--font-body);
  background: var(--bg-0); color: var(--text);
  -webkit-font-smoothing: antialiased;
}

:root {
  /* ===== v2 Design System - Iris Violet Edition (Ship 1, 2026-06-13) ===== */
  color-scheme: dark;

  /* Move category colors - palette-independent (unchanged) */
  /* v0.195.62: --cat-brilliant was #26c2c1 (teal); flipped to magenta/pink
     to match CATEGORY_COLORS.BRILLIANT in app.js (#d63a8e) so the board
     last-move highlight, the coach explainer, and the "Insane" badge all
     share the same accent. Lucas: "the squares should be coloured in pink,
     the same colour as the move." */
  --cat-brilliant:  #d63a8e;
  --cat-great:      #749bbf;
  --cat-best:       #95bc6a;
  --cat-excellent:  #95bc6a;
  --cat-good:       #95af6c;
  --cat-book:       #a88865;
  --cat-forced:     #7280a0;
  --cat-inaccuracy: #f7c245;
  --cat-mistake:    #ffa459;
  --cat-miss:       #ff7769;
  --cat-blunder:    #fa412d;

  /* === Surfaces === */
  --bg-0: #0B0B0D;
  --bg-1: #141416;
  --bg-2: #1A1A1E;
  --bg-3: #2A2A2E;
  --bg-4: #353436;

  /* === Text ladder === */
  --text-primary:   #FAFAF7;
  --text-secondary: #D1CEC4;
  --text-tertiary:  #A39F90;
  --text-muted:     #736F60;
  /* Legacy aliases so existing selectors keep working */
  --text:     #FAFAF7;
  --text-dim: #D1CEC4;
  --text-faint: #736F60;

  /* === Borders === */
  --border-subtle:  #1A1A1E;
  --border-default: #2A2A2E;
  --border-strong:  #3A3A40;

  /* === Iris Violet brand palette === */
  --iris-50:  #F0ECFF;
  --iris-100: #E1D9FF;
  --iris-200: #C2B2FF;
  --iris-300: #A38BFF;
  --iris-400: #8564FF;
  --iris-500: #7C5CFF;
  --iris-600: #6347CC;
  --iris-700: #4A3599;
  --iris-800: #322366;
  --iris-900: #191233;

  /* === Semantic accent (iris as primary) === */
  --accent:      #7C5CFF;
  --accent-d:    #6347CC;
  --accent-rgb:  124, 92, 255;
  --accent-soft: rgba(124, 92, 255, 0.13);
  --accent-2:    #F59E0B;
  --on-accent:   #FAFAF7;

  /* === Semantic colors === */
  --amber-500:   #F59E0B;
  --emerald-500: #10B981;
  --crimson-500: #EF4444;

  /* === Board colors === */
  --light-sq: #E8E6E1;
  --dark-sq:  #2A2A2E;
  --board-ring: var(--border-default);
  --board-glow: 0 8px 28px rgba(0, 0, 0, 0.65);
}

/* ============================================================
   Light theme (v0.195.50). Lucas explicit ask in autopilot session:
   "an option to switch to dark/light mode and make the dark mode
   (current) the default". Inverts the --bg-* / --text-* ladder so
   surfaces become warm off-white and text becomes near-black.
   Accent (--iris-* / --accent*) is unchanged so the brand colour
   reads identically in both modes. Board squares fall through to
   the same board-season palette (light squares stay light, dark
   squares stay dark) so swapping themes never makes the board
   unreadable. Lighter ambient shadow under the board so the
   surface doesn't feel like a hole on a bright background.
   Storage key cm_theme, attribute data-theme. Default ("" or
   "dark") keeps the v2 dark chrome. */
:root[data-theme="light"] {
  --bg-0: #F7F7F5;
  --bg-1: #ECECEA;
  --bg-2: #E2E0DC;
  --bg-3: #D1CEC4;
  --bg-4: #B8B5AB;

  --text-primary:   #0B0B0D;
  --text-secondary: #2A2A2E;
  --text-tertiary:  #4F4D45;
  --text-muted:     #736F60;
  --text:     #0B0B0D;
  --text-dim: #2A2A2E;
  --text-faint: #736F60;

  --border-subtle:  #ECECEA;
  --border-default: #D1CEC4;
  --border-strong:  #B8B5AB;

  --board-glow: 0 8px 24px rgba(11, 11, 13, 0.12);

  color-scheme: light;
}

/* ============================================================
   Board themes (v0.195.45). Familiar palettes chess players know
   from chess.com / lichess / classic wood sets. Strictly overrides
   --light-sq and --dark-sq for every board surface that already
   reads those variables (main #board / #playBoard SVG via
   .square-light / .square-dark, .v2-mini-board, .hub-mini-board,
   player avatars). Distinct attribute + storage key
   (data-board-season / cm_board_season) keeps this scoped to
   board squares only and away from the retired full-app season
   system. The attribute name is legacy; the values are not
   seasonal anymore. */
:root[data-board-season="green"] {
  /* chess.com default */
  --light-sq: #EEEED2;
  --dark-sq:  #769656;
}
:root[data-board-season="brown"] {
  /* lichess default - classic wood */
  --light-sq: #F0D9B5;
  --dark-sq:  #B58863;
}
:root[data-board-season="wood"] {
  /* Maple (light) + walnut (dark) - realistic wood tones */
  --light-sq: #D4A76A;
  --dark-sq:  #7A4422;
}
/* Layered wood-grain texture: combines tight grain lines, wider
   annual rings, and subtle knot-like radial spots for realism. */
:root[data-board-season="wood"] .board-wrap::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 1;
  background:
    /* Layer 1: fine grain lines (tight, slightly angled) */
    repeating-linear-gradient(
      2deg,
      transparent 0px,
      transparent 2px,
      rgba(80, 40, 10, 0.08) 2px,
      rgba(80, 40, 10, 0.03) 3px,
      transparent 3.5px
    ),
    /* Layer 2: wider annual-ring bands */
    repeating-linear-gradient(
      -1deg,
      transparent 0px,
      transparent 8px,
      rgba(60, 25, 5, 0.07) 8px,
      rgba(60, 25, 5, 0.04) 10px,
      transparent 12px
    ),
    /* Layer 3: subtle wavy grain variation (offset angle) */
    repeating-linear-gradient(
      4deg,
      transparent 0px,
      transparent 14px,
      rgba(100, 55, 20, 0.05) 14px,
      rgba(100, 55, 20, 0.02) 16px,
      transparent 18px
    ),
    /* Layer 4: very wide tonal bands simulating heartwood variation */
    repeating-linear-gradient(
      1deg,
      rgba(90, 50, 15, 0.0) 0px,
      rgba(90, 50, 15, 0.04) 30px,
      rgba(90, 50, 15, 0.0) 60px
    ),
    /* Layer 5: radial highlights (faint knot-like glow) */
    radial-gradient(ellipse 200% 60% at 25% 40%, rgba(120, 70, 20, 0.06) 0%, transparent 50%),
    radial-gradient(ellipse 150% 80% at 70% 65%, rgba(50, 25, 5, 0.05) 0%, transparent 45%);
  mix-blend-mode: multiply;
}
/* Lighter grain highlight (screen blend) for depth on light squares */
:root[data-board-season="wood"] .board-wrap::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 1;
  background:
    repeating-linear-gradient(
      2deg,
      transparent 0px,
      transparent 4px,
      rgba(255, 220, 160, 0.04) 4px,
      rgba(255, 220, 160, 0.02) 5px,
      transparent 6px
    ),
    repeating-linear-gradient(
      -1deg,
      transparent 0px,
      transparent 20px,
      rgba(255, 200, 130, 0.03) 20px,
      rgba(255, 200, 130, 0.01) 24px,
      transparent 28px
    );
  mix-blend-mode: screen;
}
:root[data-board-season="blue"] {
  /* lichess blue - cool, low-contrast for long sessions */
  --light-sq: #DEE3E6;
  --dark-sq:  #8CA2AD;
}
:root[data-board-season="ice"] {
  /* clean pale - light-mode friendly */
  --light-sq: #F1F5F9;
  --dark-sq:  #94A3B8;
}
:root[data-board-season="timber"] {
  /* Maple + walnut. The flat vars cover mini-boards / avatars; the real
     board squares are repainted with the grain patterns below. */
  --light-sq: #D8B782;
  --dark-sq:  #8C5E39;
}
/* Photographic parquet: fill each square with the maple/walnut grain pattern
   (defined in index.html). Textures only the squares, so pieces stay clean. */
:root[data-board-season="timber"] .square-light { fill: url(#timber-light-pattern); }
:root[data-board-season="timber"] .square-dark  { fill: url(#timber-dark-pattern); }

/* ============================================================
   Color palettes (v0.195.38). Independent of board season; lets
   users repaint the accent / brand colour without touching the
   board palette. Strictly overrides --iris-*, --accent*, and the
   semantic --on-accent text colour. Surfaces (--bg-*) and text
   ladder stay constant so the dark v2 chrome is preserved.
   Distinct attribute + storage key (data-color-palette /
   cm_color_palette). Default ("" or "iris") keeps the v2 Iris
   Violet brand. */
:root[data-color-palette="emerald"] {
  --iris-50:  #ECFDF5;
  --iris-100: #D1FAE5;
  --iris-200: #A7F3D0;
  --iris-300: #6EE7B7;
  --iris-400: #34D399;
  --iris-500: #10B981;
  --iris-600: #059669;
  --iris-700: #047857;
  --iris-800: #065F46;
  --iris-900: #064E3B;
  --accent:      #10B981;
  --accent-d:    #059669;
  --accent-rgb:  16, 185, 129;
  --accent-soft: rgba(16, 185, 129, 0.13);
  --on-accent:   #0B0B0D;
}
:root[data-color-palette="coral"] {
  --iris-50:  #FFF1F2;
  --iris-100: #FFE4E6;
  --iris-200: #FECDD3;
  --iris-300: #FDA4AF;
  --iris-400: #FB7185;
  --iris-500: #F43F5E;
  --iris-600: #E11D48;
  --iris-700: #BE123C;
  --iris-800: #9F1239;
  --iris-900: #881337;
  --accent:      #F43F5E;
  --accent-d:    #E11D48;
  --accent-rgb:  244, 63, 94;
  --accent-soft: rgba(244, 63, 94, 0.13);
  --on-accent:   #FAFAF7;
}
:root[data-color-palette="sapphire"] {
  --iris-50:  #EFF6FF;
  --iris-100: #DBEAFE;
  --iris-200: #BFDBFE;
  --iris-300: #93C5FD;
  --iris-400: #60A5FA;
  --iris-500: #3B82F6;
  --iris-600: #2563EB;
  --iris-700: #1D4ED8;
  --iris-800: #1E40AF;
  --iris-900: #1E3A8A;
  --accent:      #3B82F6;
  --accent-d:    #2563EB;
  --accent-rgb:  59, 130, 246;
  --accent-soft: rgba(59, 130, 246, 0.13);
  --on-accent:   #FAFAF7;
}

:root {
  /* === Typography === */
  --font-display:   "Space Grotesk", sans-serif;
  --font-body:      "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-editorial: "Newsreader", "Georgia", serif;
  /* Legacy alias */
  --serif: "Newsreader", "Georgia", serif;

  /* 6-step type scale */
  --text-display: 700 48px/1.05 var(--font-display);
  --text-h1:      700 32px/1.1  var(--font-display);
  --text-h2:      600 24px/1.3  var(--font-display);
  --text-h3:      600 18px/1.4  var(--font-body);
  --text-body:    400 16px/1.5  var(--font-body);
  --text-caption: 500 12px/1.4  var(--font-body);

  /* === 4px spacing scale === */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-8:  32px;
  --space-10: 40px;
  --space-12: 48px;

  /* === Radii === */
  --radius-sm:   4px;
  --radius-md:   8px;
  --radius-lg:   12px;
  --radius-pill: 999px;

  /* === Shadows === */
  --shadow-card:      0 1px 3px rgba(0, 0, 0, 0.4), 0 4px 12px rgba(0, 0, 0, 0.3);
  --shadow-elevated:  0 8px 24px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.35);
  --shadow-iris-glow: 0 0 24px rgba(124, 92, 255, 0.25);

  /* Opening difficulty level tokens */
  --diff-beginner:        #5cc46b;
  --diff-beginner-fg:     #0e2c12;
  --diff-intermediate:    #e8c547;
  --diff-intermediate-fg: #2b2200;
  --diff-advanced:        #e85a4f;
  --diff-advanced-fg:     #2e0a06;
}




/* ===== left nav rail + app shell ============================
   The navrail is a fixed left column 60px wide containing icons for the
   top-level pages (Home / Play / Stats). Everything else lives inside
   .app-shell, which is offset by the rail's width. */
:root { --navrail-w: 72px; --topbar-h: 56px; --player-strip-h: 52px; }

/* v0.140.4 / updated v0.155.x: topbar (GambitCoach mark + user pill) is
   Home-only - hidden on every other page so other tabs have more vertical
   real estate. --topbar-h tracks the live height so calc() consumers stay
   correct on the pages where the topbar is hidden. */
body { --topbar-h: 0px; }
body[data-page="home"] { --topbar-h: 56px; }
/* v0.176.7: when a game is open, float the topbar as a transparent
   overlay docked to the upper-right of .app-shell. The brand is
   hidden so the sidebar + board-area reclaim the previously empty
   vertical strip above them (Lucas: "left side is unused, move the
   board up"), while the user-info pill and palette picker stay
   visible in the upper-right. The rightpane reserves 56px at the
   top so its content (mentor / tabs) does not sit under the
   floating pill. --topbar-h stays 0 so .layout uses the full 100vh. */
body[data-page="home"][data-game-open="1"] { --topbar-h: 0px; }
body[data-page="home"][data-game-open="1"] .topbar {
  position: absolute; top: 0; right: 0;
  height: 56px;
  background: transparent;
  z-index: 40;
  pointer-events: none;
}
body[data-page="home"][data-game-open="1"] .topbar .brand { display: none; }
body[data-page="home"][data-game-open="1"] .topbar-right { pointer-events: auto; }
/* v0.195.111: while reviewing one game, hide the global top-right
   widgets (games/reviewed counts, notifications bell, "Viewing as"
   user pill). They collided with the review header's "Open PGN" /
   "Play this opening" action buttons, which live in the same top-
   right corner. The review header's Games back-button + headline
   already provide context; the user switcher is reachable from the
   gallery. */
body[data-page="home"][data-game-open="1"] .topbar-right .user-info,
body[data-page="home"][data-game-open="1"] .topbar-right .view-as-pill,
body[data-page="home"][data-game-open="1"] .topbar-right .v2-topbar-btn { display: none !important; }
body[data-page="home"][data-game-open="1"] .rightpane { padding-top: 8px; }
/* Floating topbar (56px) overlaps the top of the game review header.
   Push the header content below it so action buttons aren't clipped. */
/* v0.195.60: trim the 56 -> 24 padding above the page header.
   The floating user pill is ~36px tall; 56px clearance felt
   excessive and wasted the entire top strip Lucas pointed to. */
body[data-page="home"][data-game-open="1"] .v2-gr-page-header { padding-top: 10px; }
.topbar { display: none; }
.navrail {
  position: fixed; left: 0; top: 0; bottom: 0;
  width: var(--navrail-w);
  display: flex; flex-direction: column; align-items: center;
  padding: 12px 0; gap: 6px;
  background: var(--bg-1);
  z-index: 30;
}
.navrail-btn {
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: none; border-radius: 10px;
  color: var(--text-dim);
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.navrail-btn:hover { background: var(--bg-3); color: var(--text); }
.navrail-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.navrail-btn.active {
  background: var(--accent-soft);
  color: var(--accent);
}
/* Instant, styled tooltip to the right of any navrail button (v0.168.10).
   Pulls label from `aria-label` so it stays accessible. Replaces the
   sluggish browser-default `title` popup. */
.navrail-btn { position: relative; }
.navrail-btn[aria-label]::after {
  content: attr(aria-label);
  position: absolute;
  left: calc(100% + 10px); top: 50%;
  transform: translateY(-50%);
  background: var(--bg-2);
  color: var(--text);
  font-size: 12px; font-weight: 600;
  padding: 5px 9px; border-radius: 6px;
  border: 1px solid var(--bg-4);
  box-shadow: 0 8px 24px rgba(0,0,0,0.42);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0; visibility: hidden;
  transition: opacity 90ms ease-out, visibility 90ms;
  z-index: 60;
}
.navrail-btn[aria-label]::before {
  content: "";
  position: absolute;
  left: calc(100% + 4px); top: 50%;
  transform: translateY(-50%);
  border: 5px solid transparent;
  border-right-color: var(--bg-3);
  pointer-events: none;
  opacity: 0; visibility: hidden;
  transition: opacity 90ms ease-out, visibility 90ms;
  z-index: 60;
}
.navrail-btn[aria-label]:hover::after,
.navrail-btn[aria-label]:focus-visible::after,
.navrail-btn[aria-label]:hover::before,
.navrail-btn[aria-label]:focus-visible::before {
  opacity: 1; visibility: visible;
}
/* Pushes anything after it to the bottom of the vertical navrail. */
.navrail-spacer { flex: 1 1 auto; min-height: 12px; }
.app-shell { margin-left: var(--navrail-w); }

/* Page container - only the .active page is visible. */
.page { display: none; }
.page.active { display: block; }

/* v0.94: page-transition animations applied on tab switch. The JS adds
   `.page-anim-<mode>` to the activated .page, then removes it on
   animationend. Keep these short -- ~220ms feels snappy, not draggy --
   and use translateZ(0) to nudge the GPU compositor on Windows so the
   fade doesn't tear on slow integrated graphics. */
@keyframes cmPageFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes cmPageSlide {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes cmPagePop {
  0%   { opacity: 0; transform: scale(0.96); }
  60%  { opacity: 1; transform: scale(1.012); }
  100% { opacity: 1; transform: scale(1); }
}
.page-anim-fade  { animation: cmPageFade  0.22s ease-out both; will-change: opacity; }
.page-anim-slide { animation: cmPageSlide 0.26s cubic-bezier(0.2, 0.7, 0.2, 1) both; will-change: opacity, transform; }
.page-anim-pop   { animation: cmPagePop   0.28s cubic-bezier(0.34, 1.56, 0.64, 1) both; will-change: opacity, transform; }
@media (prefers-reduced-motion: reduce) {
  .page-anim-fade, .page-anim-slide, .page-anim-pop { animation: none; }
}

/* ===== topbar ===== (Home-only as of v0.155.1) */
.topbar {
  display: none;
}
body[data-page="home"] .topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 20px; background: var(--bg-1);
  height: 56px;
}
.topbar > .user-info { margin-left: auto; }
/* v0.88 - Viewing-as pill in the topbar. Clickable chip showing the
   active chess.com user; click opens the user-picker modal for
   switching. Hidden when no cookie (the picker overlay covers that
   case anyway). The wrapper groups the pill + userInfo on the right
   so they stay aligned regardless of order. */
.topbar-right {
  display: flex; align-items: center; gap: 12px; margin-left: auto;
}
.topbar > .topbar-right > .user-info { margin-left: 0; }
.view-as-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 12px; border-radius: 999px;
  background: var(--bg-3); border: 1px solid var(--bg-3);
  color: var(--text); font: inherit; font-size: 13px;
  cursor: pointer;
  transition: background 120ms, border-color 120ms, transform 80ms;
}
.view-as-pill:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.view-as-pill:active { transform: translateY(1px); }
.view-as-pill .vap-icon { color: var(--accent); font-size: 14px; line-height: 1; }
.view-as-pill .vap-label { color: var(--text-dim); }
.view-as-pill .vap-label strong { color: var(--accent); font-weight: 700; margin-left: 4px; }
.view-as-pill .vap-caret { font-size: 9px; opacity: 0.55; margin-left: 2px; }
.view-as-pill[hidden] { display: none; }

.brand { display: flex; align-items: baseline; gap: 10px; }
.brand .logo { font-size: 30px; color: var(--accent); line-height: 1; }
.brand .title {
  font-family: var(--serif); font-weight: 700; font-size: 22px;
  color: var(--text); letter-spacing: 0.2px;
}
.brand .sub {
  font-family: var(--serif); font-style: italic;
  font-size: 13px; color: var(--text-faint);
}
.user-info { color: var(--text-dim); font-size: 13px; }

/* ===== global view toggle ===== */
.hidden { display: none !important; }
.brand { cursor: pointer; user-select: none; }

/* v0.139: brand header is only shown on the Home (welcome) page.
   All other pages hide the GambitCoach wordmark to reduce chrome clutter.
   body[data-page] is set synchronously by showPage() in app.js. */
.brand-header { display: none; }
body[data-page="welcome"] .brand-header { display: flex; }

/* v0.140.4: navrail user-switch pill - tiny avatar button at the bottom
   of the nav rail, visible only on non-home pages (where the topbar and
   its "Viewing as" chip are hidden). Clicking opens the same user-picker
   modal as the topbar pill. Hidden on Welcome because the full topbar
   pill is present there. */
.navrail-user-pill { display: none; }
body:not([data-page="welcome"]) .navrail-user-pill { display: flex; }
.navrail-user-pill .nup-icon { font-size: 15px; line-height: 1; color: var(--accent); }
.navrail-user-pill[title] { position: relative; }

/* v0.170.0: navrail auth widget - sits at the very bottom of the rail.
   Signed out: "Sign in" link with a person icon.
   Signed in: avatar circle (initial) + truncated email + sign-out button.
   All dynamic strings (email, display_name) go through escapeHtml before
   being set as innerHTML, per the H1 XSS policy. */
.navrail-auth-widget {
  display: flex; flex-direction: column; align-items: center;
  width: 100%; padding: 6px 0 4px; gap: 0;
}
.naw-signin {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px;
  width: 40px; height: 40px; border-radius: 10px;
  color: var(--accent); text-decoration: none;
  font-size: 9px; font-weight: 600;
  transition: background 120ms, color 120ms;
}
.naw-signin:hover { background: var(--bg-3); }
.naw-user {
  display: flex; flex-direction: column; align-items: center;
  gap: 3px; width: 52px; padding: 4px 0;
}
.naw-avatar {
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--accent); color: var(--bg-0);
  font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; user-select: none; cursor: default;
}
.naw-email {
  font-size: 9px; color: var(--text-dim, var(--text));
  max-width: 52px; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis;
  text-align: center; line-height: 1.3;
}
.naw-signout {
  font-size: 9px; color: var(--accent);
  background: none; border: none; cursor: pointer;
  padding: 2px 6px; border-radius: 4px;
  transition: background 120ms;
  white-space: nowrap;
}
.naw-signout:hover { background: var(--bg-3); }
.naw-signout:disabled { opacity: 0.5; cursor: not-allowed; }

/* ============================================================ */
/* HOME VIEW (gallery of game cards)                            */
/* ============================================================ */
.home-view {
  height: calc(100vh - var(--topbar-h)); overflow-y: auto;
  padding: 32px clamp(24px, 6vw, 80px) 60px;
  background: var(--bg-0);
}
.home-hero {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 26px;
}
.home-hero h1 {
  font-family: var(--serif); font-weight: 700; font-size: 32px;
  color: var(--text); margin: 0; letter-spacing: -0.4px;
}
.home-actions { display: flex; gap: 10px; }
.icon-btn {
  min-width: 40px; height: 40px; padding: 0 12px; border-radius: 10px;
  background: var(--bg-2); border: 1px solid var(--bg-3); color: var(--text);
  font-size: 17px; line-height: 1; white-space: nowrap; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.12s, border-color 0.12s;
}
.icon-btn:hover { background: var(--bg-3); border-color: var(--bg-4); }
/* v0.85: text-label variant of .icon-btn (used for "PGN" + "Sync" on
   the home toolbar). Slightly smaller font + tighter horizontal padding
   so the label sits visually centred in the pill instead of pushing
   against the rounded edges. Without this, "+ PGN" at 17px+12px-pad
   looked cramped and made the button feel oversized for its label. */
.icon-btn-label {
  font-size: 14px; padding: 0 14px; min-width: 0; border-radius: 999px;
  font-weight: 600; letter-spacing: 0.02em;
}

/* Static red aura that highlights the king while in check. Drawn as
   an SVG <rect> with a radial-gradient fill (defs injected per board).
   v0.195.24: removed the pulsing animation per user request; the
   solid red glow still tells the user which king is in check without
   the distracting pulse. */
.king-check-aura {
  pointer-events: none;
}

.home-toolbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 18px;
}

/* Weekly coach digest card (v0.69). Shows headline + KPI tiles +
   biggest miss + top opening. Sits above the activity heatmap. */
.home-digest {
  background: linear-gradient(135deg,
    rgba(122, 91, 199, 0.10), rgba(122, 91, 199, 0.04));
  border: 1px solid rgba(122, 91, 199, 0.35);
  border-radius: 12px;
  padding: 12px 14px;
  margin-bottom: 14px;
}
.home-digest.collapsed .hdg-headline,
.home-digest.collapsed .hdg-body { display: none; }
.home-digest.collapsed { padding: 8px 14px; }
.hdg-h { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.hdg-title { margin: 0; font-size: 14px; font-weight: 700;
  color: var(--text); letter-spacing: 0.01em; }
.hdg-window { color: var(--text-dim); font-size: 12px; }
.hdg-toggle {
  margin-left: auto;
  background: transparent; border: none; cursor: pointer;
  color: var(--text-faint); font-size: 14px; line-height: 1;
  padding: 2px 8px; border-radius: 6px;
  transition: color 0.12s, background 0.12s, transform 0.18s;
}
.hdg-toggle:hover { color: var(--text); background: rgba(255,255,255,0.04); }
.home-digest.collapsed .hdg-toggle { transform: rotate(-90deg); }
.hdg-headline {
  margin-top: 4px;
  font-size: 13.5px; color: var(--text);
  font-weight: 600;
}
.hdg-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
  margin-top: 10px;
}
.hdg-tile {
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 8px;
  padding: 8px 10px;
}
.hdg-tile-l { color: var(--text-faint); font-size: 10px;
  text-transform: uppercase; letter-spacing: 0.10em; font-weight: 700; }
.hdg-tile-v { color: var(--text); font-size: 14.5px; font-weight: 700; margin-top: 2px; }
.hdg-delta { font-size: 11px; font-weight: 700; margin-left: 6px; }
.hdg-up   { color: #6ec84e; }
.hdg-down { color: #fa412d; }
.hdg-flat { color: var(--text-faint); }
.hdg-extras {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  margin-top: 10px;
}
@media (min-width: 900px) {
  /* When both blocks are visible, lay them out side-by-side so they
     don't double the digest's vertical footprint. The :has() selector
     covers the common case (modern Chromium / Safari); the fallback
     above is fine on older browsers (just stacked). */
  .hdg-extras:has(.hdg-blunder:not([hidden])):has(.hdg-opening:not([hidden])) {
    grid-template-columns: 1.4fr 1fr;
  }
}
.hdg-blunder, .hdg-opening {
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12.5px;
  color: var(--text);
  line-height: 1.45;
  margin: 0;
}
.hdg-blunder-h, .hdg-opening-h {
  font-size: 11px; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700;
  margin-bottom: 4px;
}
.hdg-link {
  color: var(--accent); text-decoration: none;
  margin-left: 6px; border-bottom: 1px dashed transparent;
}
.hdg-link:hover { border-bottom-color: var(--accent); }

/* Activity heatmap (v0.68). 7-row x N-column grid of daily game counts. */
.home-heatmap {
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 14px;
  padding: 16px 18px 14px;
  margin-bottom: 18px;
}
.hmap-h { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  margin-bottom: 12px; }
.hmap-title { margin: 0; font-size: 15px; font-weight: 700;
  color: var(--text); letter-spacing: 0.02em; }
.hmap-summary { color: var(--text-dim); font-size: 12.5px; }
.hmap-grid-wrap {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 6px;
}
.hmap-dows {
  display: grid; grid-template-rows: repeat(7, 1fr); gap: 2px;
  font-size: 10px; color: var(--text-faint);
}
.hmap-dow { line-height: 11px; display: flex; align-items: center; }
.hmap-grid { display: grid; gap: 2px; }
.hmap-cell {
  display: inline-block;
  width: 11px; height: 11px;
  border-radius: 2px;
  background: var(--bg-3);
  transition: outline 0.12s;
}
.hmap-cell:hover { outline: 1px solid var(--accent); cursor: default; }
.hmap-pad { background: transparent !important; pointer-events: none; }
.hmap-l0 { background: var(--bg-3); }
.hmap-l1 { background: rgba(110, 200, 78, 0.25); }
.hmap-l2 { background: rgba(110, 200, 78, 0.50); }
.hmap-l3 { background: rgba(110, 200, 78, 0.75); }
.hmap-l4 { background: rgba(110, 200, 78, 1.00); }
.hmap-legend {
  display: flex; align-items: center; gap: 6px; justify-content: flex-end;
  margin-top: 10px; font-size: 11px; color: var(--text-faint);
}
.hmap-legend .hmap-cell { width: 11px; height: 11px; }

.pill-tabs { display: flex; gap: 4px; background: var(--bg-2); padding: 4px;
  border-radius: 999px; border: 1px solid var(--bg-3); }
.pill {
  background: transparent; border: none; color: var(--text-dim);
  padding: 8px 18px; font-size: 13px; font-weight: 700; cursor: pointer;
  border-radius: 999px; transition: background 0.12s, color 0.12s;
}
.pill:hover { color: var(--text); }
.pill.active { background: var(--bg-3); color: var(--accent); }

.toolbar-filters {
  display: flex; gap: 10px; align-items: center; flex: 1;
  min-width: 280px;
}
.toolbar-filters input[type="search"] {
  flex: 1; min-width: 200px;
  background: var(--bg-2); border: 1px solid var(--bg-3); color: var(--text);
  border-radius: 10px; padding: 10px 14px; font-size: 13.5px;
  font-family: inherit;
}
.toolbar-filters input[type="search"]::placeholder { color: var(--text-faint); }
.toolbar-filters input[type="search"]:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.22);
}
.toolbar-filters select {
  background: var(--bg-2); border: 1px solid var(--bg-3); color: var(--text);
  border-radius: 10px; padding: 10px 12px; font-size: 13px;
  font-family: inherit; cursor: pointer;
}
.toolbar-filters select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.22);
}

.home-meta {
  color: var(--text-faint); font-size: 12px; margin-bottom: 14px;
  text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700;
}

/* Card grid - 3 per row, responsive */
.game-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
  gap: 18px;
}

.game-card {
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 14px; padding: 18px 18px 14px;
  cursor: pointer;
  transition: background 0.15s, transform 0.12s, border-color 0.15s, box-shadow 0.15s;
  display: flex; flex-direction: column; gap: 11px;
  position: relative;
}
.game-card.pinned {
  border-color: rgba(var(--accent-rgb), 0.45);
}
.card-pin {
  position: absolute; top: 6px; right: 8px;
  background: transparent; border: none; cursor: pointer;
  font-size: 18px; line-height: 1; padding: 4px 6px;
  color: var(--text-faint); opacity: 0.45;
  transition: opacity 0.12s, color 0.12s, transform 0.12s;
  z-index: 1;
}
.card-pin:hover { opacity: 1; color: var(--accent); transform: scale(1.15); }
.card-pin.on { color: var(--accent); opacity: 1; }
.card-pin.on:hover { color: var(--accent); }
/* v0.94: bot-game delete (✕) lives top-LEFT so it doesn't fight with the
   pin star. Only rendered on bot / pgn-paste cards via JS. */
.card-delete {
  position: absolute; top: 6px; left: 8px;
  background: transparent; border: none; cursor: pointer;
  font-size: 13px; line-height: 1; padding: 4px 7px; border-radius: 6px;
  color: var(--text-faint); opacity: 0.35;
  transition: opacity 0.12s, color 0.12s, background 0.12s, transform 0.12s;
  z-index: 1;
}
.card-delete:hover {
  opacity: 1; color: #ff8b7f;
  background: rgba(231,76,60,0.12);
  transform: scale(1.10);
}
.game-card.bot .card-head .src.src-bot {
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.game-card:hover {
  background: #382a1c; border-color: var(--bg-4); transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(0,0,0,0.45);
}

.card-head {
  display: flex; align-items: center; gap: 10px;
  font-size: 11.5px; color: var(--text-faint);
}
.card-head .tc { color: var(--text-dim); font-weight: 600; font-family: "Consolas", monospace; }
.card-head .src { color: var(--text-faint); }
.card-head .res-badge {
  margin-left: auto; padding: 4px 11px; border-radius: 999px;
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.1em;
}
.card-head .res-badge.win  { background: rgba(95,150,76,0.20);  color: #a3d36c; }
.card-head .res-badge.loss { background: rgba(231,76,60,0.20);  color: #ff8b7f; }
.card-head .res-badge.draw { background: rgba(176,154,118,0.20); color: var(--text-dim); }

.card-players { display: flex; flex-direction: column; gap: 4px; }
.card-players .prow {
  display: flex; align-items: center; gap: 10px;
  font-size: 13.5px; color: var(--text);
}
.card-players .prow.mine .nm { font-weight: 700; }
.card-players .cc {
  width: 14px; height: 14px; border-radius: 3px; flex-shrink: 0;
  border: 1px solid var(--bg-4);
}
.card-players .cc.white { background: #e9d6b3; }
.card-players .cc.black { background: #1a130b; }
.card-players .nm { flex: 1; }
.card-players .rt { color: var(--text-dim); font-size: 12.5px; font-family: "Consolas", monospace; }

.card-opening {
  background: rgba(0,0,0,0.22); border-radius: 8px;
  padding: 8px 11px; font-size: 12.5px; color: var(--text-dim);
  border: 1px solid var(--bg-3);
}

.card-foot {
  display: flex; align-items: center; gap: 10px;
  margin-top: auto; padding-top: 4px;
}
.card-foot .fm { font-size: 11.5px; color: var(--text-faint); }
.card-btn {
  margin-left: auto;
  background: var(--accent); color: var(--on-accent); border: none;
  padding: 7px 18px; border-radius: 999px; font-size: 12px;
  font-weight: 800; cursor: pointer; letter-spacing: 0.3px;
  transition: background 0.12s;
}
.card-btn:hover { background: #e8cda6; }
.card-btn.reviewed {
  background: var(--bg-3); color: var(--text-dim);
}
.card-btn.reviewed:hover { background: var(--bg-4); color: var(--text); }

/* ============================================================ */
/* GAME VIEW layout                                              */
/* ============================================================ */

/* v0.194.10: v2-gr-view wraps the header + .layout so the header
   can have a fixed height deducted from the inner layout. */
.v2-gr-view {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

/* v2 Game Review page header
   v0.195.30: trimmed vertical padding (was 20/16) to reclaim the empty
   strip Lucas pointed out above the board, and slimmed the right padding
   so the action buttons sit at the right edge of the (wider) Mentor
   column rather than floating above the board's top rank. */
.v2-gr-page-header {
  flex-shrink: 0;
  padding: 4px 32px 8px 32px;
  background: transparent;
}
.v2-gr-header-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.v2-gr-left { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.v2-gr-eyebrow {
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.v2-gr-headline-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.v2-gr-player-headline {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* v0.195.30: prominent always-visible back button in the page header.
   Lucas could not find the existing one because it lived inside the
   scrollable sidebar and was easy to miss. This one sits at the very
   top-left of the review and is impossible to overlook. */
.v2-gr-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px 0 10px;
  border-radius: 8px;
  border: 1px solid var(--border-default, var(--bg-3));
  background: var(--bg-2);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 140ms, border-color 140ms, transform 120ms, color 140ms;
  flex-shrink: 0;
}
.v2-gr-back:hover {
  background: rgba(var(--accent-rgb), 0.10);
  border-color: rgba(var(--accent-rgb), 0.45);
  color: var(--accent);
  transform: translateX(-1px);
}
.v2-gr-back:active { transform: translateX(0); }
/* Outcome chip - v2 Victory/Defeat/Draw */
.v2-gr-outcome-chip {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid var(--border-default, var(--bg-3));
  background: transparent;
  color: var(--text-dim);
  white-space: nowrap;
  flex-shrink: 0;
}
.v2-gr-outcome-chip[data-outcome="victory"] {
  border-color: rgba(34,197,94,0.4);
  background: rgba(34,197,94,0.08);
  color: #4ade80;
}
.v2-gr-outcome-chip[data-outcome="defeat"] {
  border-color: rgba(239,68,68,0.4);
  background: rgba(239,68,68,0.08);
  color: #f87171;
}
.v2-gr-outcome-chip[data-outcome="draw"] {
  border-color: rgba(161,161,170,0.35);
  background: rgba(161,161,170,0.07);
  color: var(--text-dim);
}
/* Action buttons row */
.v2-gr-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.v2-gr-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  border-radius: 8px;
  border: 1px solid var(--border-default, var(--bg-3));
  background: var(--bg-2);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 140ms, border-color 140ms, transform 120ms;
  white-space: nowrap;
}
.v2-gr-action-btn:hover {
  background: var(--bg-3);
  border-color: var(--bg-4);
  transform: translateY(-1px);
}
.v2-gr-action-btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.v2-gr-action-btn--primary:hover {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
}

.layout {
  display: grid;
  /* v0.193.4: trim sidebar 320->296 and rightpane 480->420 so the board
     gets more breathing room and the side panels don't visually sit
     "on top of" the board at common 1280-1440px viewports.
     v0.195.14: pull left padding in (16px) so the sidebar sits closer
     to the navrail; right side keeps 32px because the floating user
     widgets live there. */
  grid-template-columns: 280px 1fr 440px;
  gap: 40px;
  padding: 16px 32px 16px 16px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
/* When .layout is NOT inside v2-gr-view (legacy), keep full height */
.layout:not(.v2-gr-view .layout) {
  height: calc(100vh - var(--topbar-h));
}
/* v0.180.0: columns are transparent so the body --bg-0 shows through the
   layout padding and between stacked pill cards inside each column. All
   visible "panels" (sidebar cards, Mentor pill, Game Report pill) now share
   a single --bg-1 surface colour for a consistent slightly-lighter-than-body
   feel across themes. */
.sidebar, .board-area, .rightpane { background: transparent; overflow: hidden; }
.sidebar { display: flex; flex-direction: column; }
.rightpane { display: flex; flex-direction: column; }
/* v0.195.12: give the rightpane in the game-review view a solid card so
   --bg-0 doesn't bleed through as a "black square" behind the report panel.
   v0.195.14: same treatment on the left sidebar so the back button + game
   header + eval chart + move list sit on a single card surface, not on a
   dark patchwork of body bg. */
.v2-gr-view .rightpane,
.v2-gr-view .sidebar {
  background: transparent;
  border: none;
  overflow-y: auto;
  min-width: 0;
  /* v0.195.111: must be able to shrink below content height so the
     grid row (minmax(0,1fr) below) constrains them and the internal
     overflow-y:auto actually produces a scrollbar instead of the
     column growing past the viewport and hiding the stats below. */
  min-height: 0;
}
/* v0.195.16: the game-review layout needs its own column sizing so the
   board, the sidebar, and the rightpane never overlap at common 1280-1600
   viewports. Side columns shrink, board is capped to actual middle-column
   width via --board-w override on .board-area.
   v0.195.30: widened both side panels (240 -> 290 sidebar, 380 -> 420
   rightpane) and pushed them further from the board (gap 32 -> 56) so
   the sidebar moves rooms cards have breathing room and the Mentor /
   Game Report column isn't visually glued to the board.
   v0.195.57: Lucas asked to move the panels further from the board.
   Gap is now responsive via clamp(56px, 5vw, 96px): keeps the prior
   56px floor on 1280px viewports so the middle board doesn't crush
   under the side panels, but at 1440+ scales up to ~72-96px so the
   sidebar moves cards and Mentor / Game Report column aren't visually
   glued to the board. */
/* v0.195.78: panels pulled closer to the board. Horizontal padding
   pushes the whole three-column grid inward so the sidebar and
   rightpane aren't glued to the viewport edges. */
.v2-gr-view .layout {
  grid-template-columns: 300px minmax(0, 1fr) 440px;
  /* v0.195.111: cap the single grid row to the layout's own (flex-
     constrained) height. Without an explicit row track the implicit
     row is content-sized, so the tallest column (sidebar move list /
     rightpane report) stretched the row past the viewport and the
     bottom stats were clipped by .v2-gr-view's overflow:hidden with
     no scrollbar. minmax(0,1fr) forces the columns to scroll instead. */
  grid-template-rows: minmax(0, 1fr);
  gap: 0;
  padding: 0 clamp(20px, 4vw, 100px) 16px;
}
.v2-gr-view .board-area {
  container-type: inline-size;
  --board-w: min(660px, calc(100vh - 256px), 100cqw);
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  overflow: visible;
}
.v2-gr-view #board {
  width: var(--board-w);
  height: var(--board-w);
  max-width: 100%;
}

/* ===== left sidebar (back button + game header + mini eval + moves) ===== */
/* v0.182.1: refreshed the topbar to look less like a 90s text link.
   The topbar now reads as a soft pill: the back button sits inside
   --bg-2 with a hover lift, the pin button is visually balanced as a
   peer (not a stuck-on tab), and the divider line is dropped in favour
   of the cards below providing structure. */
.sidebar-topbar {
  display: flex; align-items: stretch;
  padding: 10px 12px 0;
  gap: 8px;
  /* v0.195.30: pin to the top of the sidebar so the back button never
     scrolls out of sight when the move list grows tall. The page header
     also has a redundant back button, but keeping this one always visible
     mirrors Lichess and chess.com habits. */
  position: sticky;
  top: 0;
  z-index: 2;
  background: linear-gradient(180deg, var(--bg-0) 0%, var(--bg-0) 70%, transparent 100%);
}

/* ============================================================ */
/*  v2 DESIGN SYSTEM - App Shell + Hub (v0.194.0)              */
/* ============================================================ */

/* --- Global font reset for v2 --- */
html {
  font-family: var(--font-body);
}

/* --- v2 Nav Rail --- */
.v2-rail {
  position: fixed;
  left: 0;
  top: 0;
  height: 100%;
  width: 72px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 24px 0;
  background: var(--bg-1);
  border-right: 1px solid var(--border-default);
  z-index: 60;
  transition: width 180ms ease-out 250ms;
}
.v2-rail:hover,
.v2-rail.open {
  width: 240px;
  transition: width 180ms ease-out 0ms;
}
.v2-rail .navrail-list {
  list-style: none;
  margin: 0;
  padding: 0 var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.v2-rail .navrail-spacer {
  flex: 1;
}
.v2-rail .navrail-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  width: 40px;
  height: 40px;
  margin: 0 auto;
  padding: 0;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition: width 180ms ease-out, padding 180ms ease-out, background 180ms ease-out, color 180ms ease-out;
  text-align: left;
  overflow: hidden;
}
.v2-rail:hover .navrail-btn,
.v2-rail.open .navrail-btn {
  width: 100%;
  justify-content: flex-start;
  padding: 0 12px 0 16px;
}
.v2-rail .navrail-btn i {
  font-size: 20px;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.v2-rail .navrail-btn .navrail-label {
  display: none;
  white-space: nowrap;
}
.v2-rail:hover .navrail-btn .navrail-label,
.v2-rail.open .navrail-btn .navrail-label {
  display: inline;
}
.v2-rail .navrail-btn:hover {
  background: var(--bg-3);
  color: var(--text-primary);
}
.v2-rail .navrail-btn.active {
  background: rgba(124, 92, 255, 0.12);
  color: var(--iris-400);
}
.v2-rail .navrail-btn.active i.ph {
  display: none;
}
.v2-rail .navrail-btn.active i.ph-duotone {
  display: inline;
}
.v2-rail .navrail-btn:not(.active) i.ph-duotone {
  display: none;
}
.v2-rail .navrail-auth-widget {
  padding: 0 var(--space-3);
}

/* --- v2 Hub brand (homepage wordmark) --- */
.v2-hub-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 32px;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  padding: 32px 0 16px;
  user-select: none;
  /* v0.195.183: nudge the wordmark slightly left of dead-center per
     Lucas's request, for better optical balance against the navrail. */
  transform: translateX(-40px);
}
.v2-hub-brand .v2-wordmark-gambit {
  color: var(--accent);
}
.v2-hub-brand-logo {
  width: 44px;
  height: 44px;
  color: var(--accent);
  flex-shrink: 0;
}
.v2-hub-brand-text {
  display: inline-block;
  line-height: 1;
}

/* --- v2 Topbar --- */
.v2-topbar {
  position: absolute;
  top: 0;
  right: 0;
  left: var(--navrail-w);
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--space-8);
  background: transparent;
  z-index: 40;
}
.v2-wordmark {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-primary);
}
.v2-wordmark-gambit {
  color: var(--iris-400);
}
.v2-topbar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
  font-size: 18px;
  transition: color 180ms ease-out, background 180ms ease-out;
}
.v2-topbar-btn:hover {
  color: var(--text-primary);
  background: var(--bg-3);
}

/* --- v2 Hub Canvas --- */
.v2-hub-canvas {
  margin-left: 0;
  padding: var(--space-8);
  min-height: 100vh;
  max-width: 1600px;
}

/* v0.195.18: hub uses a single full-width main column. The Coach's
   Note + Daily Tactics aside was removed at Lucas's request, so the
   grid wrapper just passes through to .v2-hub-main. */
.v2-hub-grid {
  display: block;
}
.v2-hub-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Hero */
.v2-hub-hero {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding-top: var(--space-6);
  padding-bottom: var(--space-8);
}
@media (min-width: 768px) {
  .v2-hub-hero {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
  }
}
.v2-hub-dateline {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0 0 var(--space-3) 0;
}
/* v0.195.135: account-status pill on the dashboard hero. Coarse tier from
   /api/me (admin / basic today; gold + premium later). Reuses theme tokens. */
.account-tier-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 var(--space-3) 0;
  padding: 4px 11px 4px 9px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  border: 1px solid var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}
.account-tier-pill iconify-icon {
  font-size: 14px;
}
.account-tier-pill[data-tier="basic"] {
  border-color: var(--border-strong, rgba(255, 255, 255, 0.18));
  color: var(--text-tertiary);
  background: rgba(255, 255, 255, 0.04);
}
.account-tier-pill[data-tier="gold"],
.account-tier-pill[data-tier="premium"] {
  border-color: var(--accent-2);
  color: var(--accent-2);
  background: rgba(245, 158, 11, 0.12);
}
.v2-hub-headline {
  font-family: var(--font-display);
  font-size: 48px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--text-primary);
  margin: 0 0 var(--space-4) 0;
}
.v2-hub-headline-name {
  color: var(--iris-400);
}
.v2-hub-subline {
  font-size: 16px;
  color: var(--text-tertiary);
  margin: 0;
}
.activity-streak-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: var(--space-3);
  padding: 4px 11px 4px 9px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
  border: 1px solid var(--accent-2);
  color: var(--accent-2);
  background: rgba(245, 158, 11, 0.12);
}
.activity-streak-pill iconify-icon {
  font-size: 15px;
}
.activity-streak-pill.is-zero {
  border-color: var(--border-strong, rgba(255,255,255,0.18));
  color: var(--text-tertiary);
  background: rgba(255,255,255,0.04);
}
.v2-hub-hero-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* Buttons */
.v2-btn-primary {
  height: 40px;
  padding: 0 var(--space-5);
  border: none;
  border-radius: var(--radius-md);
  background: var(--iris-600);
  color: #fff;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 180ms ease-out, transform 180ms ease-out;
}
.v2-btn-primary:hover {
  background: var(--iris-500);
  transform: translateY(-1px);
}
.v2-btn-ghost {
  height: 40px;
  padding: 0 var(--space-5);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 180ms ease-out, color 180ms ease-out, transform 180ms ease-out;
}
.v2-btn-ghost:hover {
  background: var(--bg-3);
  color: var(--text-primary);
  transform: translateY(-1px);
}
/* Bright premium upgrade CTA (gold to iris), draws the eye on the Hub hero. */
.v2-btn-upgrade {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 40px;
  padding: 0 var(--space-5);
  border: none;
  border-radius: var(--radius-md);
  background: linear-gradient(100deg, var(--amber-500) 0%, var(--iris-500) 100%);
  color: #fff;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 6px 18px rgba(245, 158, 11, 0.32);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out, filter 180ms ease-out;
}
.v2-btn-upgrade iconify-icon {
  font-size: 16px;
}
.v2-btn-upgrade:hover {
  transform: translateY(-1px);
  filter: brightness(1.06);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12), 0 8px 24px rgba(245, 158, 11, 0.42);
}
@media (prefers-reduced-motion: reduce) {
  .v2-btn-upgrade { transition: none; }
  .v2-btn-upgrade:hover { transform: none; }
}
/* display:inline-flex above wins over UA [hidden]{display:none}; force-hide it. */
.v2-btn-upgrade[hidden] { display: none !important; }
.v2-btn-sm {
  height: 32px;
  padding: 0 var(--space-3);
  font-size: 12px;
}

/* KPI Ribbon */
.v2-hub-kpi-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  margin-bottom: var(--space-8);
}
@media (min-width: 768px) {
  .v2-hub-kpi-row {
    grid-template-columns: repeat(3, 1fr);
  }
}
.v2-kpi-card {
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}
.v2-kpi-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-card);
}
#v2KpiRating,
#v2KpiWinrate {
  cursor: pointer;
}
.v2-kpi-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: var(--space-4);
}
.v2-kpi-label {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-tertiary);
  margin: 0;
}
.v2-kpi-icon {
  font-size: 20px;
  color: var(--border-strong);
}
.v2-kpi-value-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.v2-kpi-value {
  font-family: var(--font-display);
  font-size: 48px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  line-height: 1;
}
.v2-kpi-delta {
  display: inline-flex;
  align-items: center;
  padding: 4px 8px;
  border-radius: var(--radius-pill);
  background: rgba(16, 185, 129, 0.1);
  color: var(--emerald-500);
  font-size: 12px;
  font-weight: 500;
  margin-bottom: 4px;
}
.v2-kpi-delta.negative {
  background: rgba(239, 68, 68, 0.1);
  color: var(--crimson-500);
}
.v2-kpi-sub {
  font-size: 14px;
  color: var(--text-muted);
  margin: 0;
}
.v2-kpi-sparkline {
  height: 32px;
  width: 100%;
  margin-top: var(--space-4);
  background: var(--bg-3);
  border-radius: var(--radius-sm);
  overflow: hidden;
  position: relative;
}
.v2-kpi-sparkline svg {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
/* W/D/L bar */
.v2-kpi-wdl {
  margin-top: var(--space-4);
}
.v2-kpi-wdl-labels {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  margin-bottom: var(--space-1);
}
.v2-kpi-wdl-track {
  height: 8px;
  width: 100%;
  border-radius: var(--radius-pill);
  overflow: hidden;
  display: flex;
}
.v2-kpi-wdl-w { background: var(--emerald-500); height: 100%; }
.v2-kpi-wdl-d { background: var(--border-strong); height: 100%; }
.v2-kpi-wdl-l { background: var(--crimson-500); height: 100%; }

/* Last Game + Daily Insight row */
.v2-hub-deep {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  margin-bottom: var(--space-8);
}
/* v0.195.17: Coach's Note moved to .v2-hub-aside, so the deep row
   now contains only the Last Game card and stays single-column. */
.v2-lastgame-card {
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}
.v2-lastgame-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-card);
}
.v2-lastgame-inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
@media (min-width: 640px) {
  .v2-lastgame-inner {
    flex-direction: row;
    align-items: flex-start;
  }
}
.v2-mini-board {
  width: 160px;
  height: 160px;
  flex-shrink: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  overflow: hidden;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  position: relative;
}
.v2-mini-board .sq-light { background: var(--light-sq); }
.v2-mini-board .sq-dark  { background: var(--dark-sq); }
.v2-mini-piece {
  position: absolute;
  width: 12.5%;
  height: 12.5%;
  pointer-events: none;
  object-fit: contain;
}
.v2-lastgame-details {
  flex: 1;
  min-width: 0;
}
.v2-lastgame-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-2);
}
.v2-lastgame-badges {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.v2-lastgame-badge {
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  background: var(--bg-3);
  color: var(--text-tertiary);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.v2-lastgame-badge.outcome-win   { color: var(--emerald-500); }
.v2-lastgame-badge.outcome-loss  { color: var(--crimson-500); }
.v2-lastgame-badge.outcome-draw  { color: var(--text-tertiary); }
.v2-lastgame-when {
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.v2-lastgame-title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  color: var(--text-primary);
  margin: 0 0 var(--space-4) 0;
}
.v2-lastgame-players {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
}
.v2-lastgame-player-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
}
.v2-lastgame-player-info {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.v2-player-chip {
  width: 12px;
  height: 12px;
  border-radius: 2px;
  flex-shrink: 0;
}
.v2-player-chip-white { background: var(--text-secondary); }
.v2-player-chip-black { background: var(--bg-3); border: 1px solid var(--border-strong); }
.v2-lastgame-player-name { color: var(--text-secondary); }
.v2-lastgame-player-name.is-me { color: var(--text-primary); font-weight: 500; }
.v2-lastgame-player-rating {
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
  font-size: 13px;
}
.v2-lastgame-empty { color: var(--text-muted); font-size: 14px; margin: 0; }
.v2-lastgame-action-row {
  display: flex;
  gap: var(--space-3);
}
.v2-btn-link {
  padding: 8px 16px;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: 14px;
  cursor: pointer;
  transition: background 180ms ease-out;
}
.v2-btn-link:hover { background: var(--bg-3); }
.v2-btn-analyze {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px 16px;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--iris-400);
  font-family: var(--font-body);
  font-size: 14px;
  cursor: pointer;
  transition: background 180ms ease-out;
}
.v2-btn-analyze:hover { background: rgba(124, 92, 255, 0.1); }

/* Daily Insight */
.v2-insight-card {
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}
.v2-insight-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-card);
}
.v2-insight-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(124, 92, 255, 0.3);
  background: rgba(124, 92, 255, 0.1);
  color: var(--iris-400);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: var(--space-4);
  align-self: flex-start;
}
.v2-insight-quote {
  font-family: var(--font-editorial);
  font-style: italic;
  font-size: 18px;
  line-height: 1.5;
  color: var(--text-secondary);
  margin: 0 0 var(--space-6) 0;
  flex: 1;
}
.v2-insight-tactics {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--bg-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-top: auto;
}
.v2-insight-tactics-title {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-secondary);
  margin: 0 0 2px 0;
}
.v2-insight-tactics-sub {
  font-size: 12px;
  color: var(--text-muted);
  margin: 0;
}

/* Bottom row */
.v2-hub-bottom {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 1280px) {
  .v2-hub-bottom {
    grid-template-columns: 7fr 5fr;
    align-items: start;
  }
}
.v2-activity-card,
.v2-opening-card {
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}
.v2-opening-card {
  min-height: 220px;
}
.v2-activity-card:hover,
.v2-opening-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-card);
}
.v2-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-6);
}
.v2-card-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  color: var(--text-primary);
  margin: 0;
}
.v2-card-link {
  font-size: 12px;
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 500;
  transition: color 180ms ease-out;
}
.v2-card-link:hover { color: var(--text-secondary); }

/* Activity list */
.v2-activity-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.v2-activity-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}
.v2-activity-icon {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 16px;
  margin-top: 2px;
}
.v2-activity-icon.win    { background: rgba(16, 185, 129, 0.1); border: 1px solid rgba(16, 185, 129, 0.2); color: var(--emerald-500); }
.v2-activity-icon.loss   { background: rgba(239, 68, 68, 0.1);  border: 1px solid rgba(239, 68, 68, 0.2);  color: var(--crimson-500); }
.v2-activity-icon.puzzle { background: rgba(124, 92, 255, 0.1); border: 1px solid rgba(124, 92, 255, 0.2); color: var(--iris-400); }
.v2-activity-icon.opening { background: rgba(245, 158, 11, 0.1); border: 1px solid rgba(245, 158, 11, 0.2); color: var(--amber-500); }
.v2-activity-body {
  flex: 1;
  border-bottom: 1px solid var(--border-subtle);
  padding-bottom: var(--space-4);
}
.v2-activity-item:last-child .v2-activity-body {
  border-bottom: none;
  padding-bottom: 0;
}
.v2-activity-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 2px;
}
.v2-activity-desc { font-size: 14px; color: var(--text-secondary); }
.v2-activity-desc strong { color: var(--text-primary); }
.v2-activity-time { font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.v2-activity-meta { font-size: 12px; color: var(--text-tertiary); }
.v2-activity-empty { font-size: 14px; color: var(--text-muted); }

/* Top Opening card */
.v2-opening-name {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  margin: 0 0 var(--space-2) 0;
}
.v2-opening-meta {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  font-size: 14px;
  color: var(--text-tertiary);
}
.v2-opening-meta strong { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.v2-opening-meta .win-rate { color: var(--emerald-500); font-weight: 500; font-variant-numeric: tabular-nums; }
.v2-opening-wdl { margin-bottom: var(--space-6); }
/* Legacy compat hidden */
.v2-legacy-compat { display: none !important; }

/* ================================================================
   v2 Stats Page (Ship 2)
   ================================================================ */

.v2-stats-canvas {
  margin-left: 72px;
  padding: var(--space-8);
  min-height: 100vh;
  max-width: 1440px;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.v2-eyebrow {
  font: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-tertiary);
  display: block;
  margin-bottom: var(--space-1);
}

.v2-stats-h1 {
  font: var(--text-h1);
  color: var(--text-primary);
  letter-spacing: -0.02em;
  margin: 0;
}

/* Generic v2 content card (stats) */
.v2-stats-card {
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: 16px;
  padding: var(--space-6);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}
.v2-stats-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

/* KPI ribbon (6-up compact cards) */
.v2-stats-kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--space-4);
}
.v2-stats-kpi-card {
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-2);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}
.v2-stats-kpi-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-card);
}
.v2-stats-kpi-lbl {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-tertiary);
}
.v2-stats-kpi-val-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.v2-stats-kpi-val {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  line-height: 1;
}
.v2-stats-kpi-val.amber { color: var(--amber-500); }
.v2-stats-kpi-badge {
  font-size: 11px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
}
.v2-stats-kpi-badge.pos { background: rgba(16, 185, 129, 0.12); color: var(--emerald-500); }
.v2-stats-kpi-badge.neg { background: rgba(239, 68, 68, 0.12); color: var(--crimson-500); }
.v2-stats-kpi-sub {
  font-size: 12px;
  color: var(--text-muted);
}

/* Charts row: 8/4 split */
.v2-stats-charts-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 1024px) {
  .v2-stats-charts-row { grid-template-columns: 2fr 1fr; }
}
.v2-stats-chart-wrap {
  min-height: 240px;
  position: relative;
}
.v2-stats-chart-wrap canvas { max-height: 240px; }

.v2-stats-rating-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-6);
}
.v2-stats-legend-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.v2-stats-legend-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.v2-stats-legend-label {
  font-size: 12px;
  color: var(--text-tertiary);
}
.v2-stats-legend-delta {
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
}
.v2-stats-legend-delta.pos { background: rgba(16, 185, 129, 0.12); color: var(--emerald-500); }
.v2-stats-legend-delta.neg { background: rgba(239, 68, 68, 0.12); color: var(--crimson-500); }
.v2-stats-legend-delta.neu { background: rgba(163, 161, 156, 0.15); color: var(--text-tertiary); }

/* Move quality donut */
.v2-stats-mq-card { display: flex; flex-direction: column; }
.v2-stats-mq-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  flex: 1;
}
.v2-stats-mq-donut {
  position: relative;
  width: 180px;
  height: 180px;
  border-radius: 50%;
  flex-shrink: 0;
}
.v2-stats-mq-donut-center {
  position: absolute;
  inset: 25%;
  background: var(--bg-2);
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.v2-stats-mq-donut-total {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.v2-stats-mq-donut-sub {
  font-size: 10px;
  color: var(--text-tertiary);
  text-align: center;
  margin-top: 2px;
}
.v2-stats-mq-legend {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 16px;
  width: 100%;
}
.v2-stats-mq-legend-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.v2-stats-mq-legend-left {
  display: flex;
  align-items: center;
  gap: 6px;
}
.v2-stats-mq-legend-dot {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex-shrink: 0;
}
.v2-stats-mq-legend-name { font-size: 12px; color: var(--text-tertiary); }
.v2-stats-mq-legend-pct {
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

/* Splits row: 2-col grid */
.v2-stats-splits-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 768px) {
  .v2-stats-splits-row { grid-template-columns: 1fr 1fr; }
}

/* By color */
.v2-stats-color-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.v2-stats-color-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: var(--space-2);
}
.v2-stats-color-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.v2-stats-color-chip-w {
  width: 16px; height: 16px;
  border-radius: 3px;
  background: #E8E6E1;
  border: 1px solid #A3A19C;
  flex-shrink: 0;
}
.v2-stats-color-chip-b {
  width: 16px; height: 16px;
  border-radius: 3px;
  background: #1A1A1E;
  border: 1px solid var(--border-default);
  flex-shrink: 0;
}
.v2-stats-color-name {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-primary);
}
.v2-stats-color-count {
  font-size: 12px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}
.v2-stats-wdl-wrap {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.v2-stats-wdl-track {
  flex: 1;
  display: flex;
  height: 10px;
  border-radius: var(--radius-pill);
  overflow: hidden;
  background: var(--bg-3);
}
.v2-stats-wdl-w { background: var(--emerald-500); height: 100%; }
.v2-stats-wdl-d { background: var(--border-strong); height: 100%; }
.v2-stats-wdl-l { background: var(--crimson-500); height: 100%; }
.v2-stats-wdl-pct {
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--emerald-500);
  min-width: 36px;
  text-align: right;
}

/* Tables */
.v2-stats-table-wrap { overflow-x: auto; }
.v2-stats-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}
.v2-stats-table thead th {
  padding: var(--space-3) var(--space-2);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
  border-bottom: 1px solid var(--border-default);
  white-space: nowrap;
}
.v2-stats-table thead th.r { text-align: right; }
.v2-stats-table tbody tr {
  border-bottom: 1px solid rgba(42, 42, 46, 0.5);
  transition: background 120ms;
}
.v2-stats-table tbody tr:last-child { border-bottom: none; }
.v2-stats-table tbody tr:hover { background: rgba(255, 255, 255, 0.02); }
.v2-stats-table td {
  padding: var(--space-3) var(--space-2);
  font-size: 14px;
  color: var(--text-secondary);
  vertical-align: middle;
}
.v2-stats-table td.r { text-align: right; }
.v2-stats-table td.nm { color: var(--text-primary); font-weight: 500; }
.v2-stats-table td.serif {
  font-family: var(--font-editorial);
  font-style: italic;
  color: var(--text-primary);
  font-size: 15px;
}
.v2-stats-table td.win {
  color: var(--emerald-500); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.v2-stats-table td.loss {
  color: var(--crimson-500); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.v2-stats-table td.hi {
  color: var(--amber-500); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.v2-stats-table td.num { font-variant-numeric: tabular-nums; }
.v2-stats-table td.center { text-align: center; }
.v2-stats-delta {
  font-size: 11px;
  font-weight: 500;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  font-variant-numeric: tabular-nums;
  display: inline-block;
}
.v2-stats-delta.pos { background: rgba(16, 185, 129, 0.12); color: var(--emerald-500); }
.v2-stats-delta.neg { background: rgba(239, 68, 68, 0.12); color: var(--crimson-500); }
.v2-stats-delta.neu { background: rgba(163, 161, 156, 0.15); color: var(--text-tertiary); }

/* Game outcomes bar */
.v2-stats-outcomes-bar {
  width: 100%;
  height: 40px;
  display: flex;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border-default);
  margin-bottom: var(--space-4);
}
.v2-stats-outcomes-seg {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: opacity 120ms;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  padding: 0 8px;
  white-space: nowrap;
}
.v2-stats-outcomes-seg:hover { opacity: 0.8; }
.v2-stats-outcomes-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  font-size: 12px;
  color: var(--text-tertiary);
  justify-content: center;
}
.v2-stats-outcomes-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
}
.v2-stats-outcomes-legend-dot {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
}

/* ================================================================
   v2 Settings Page (Ship 3)
   ================================================================ */

.v2-settings-canvas {
  padding: var(--space-8);
  min-height: calc(100vh - 56px);
  max-width: 1120px;
}

.v2-settings-header {
  margin-bottom: var(--space-8);
}

.v2-settings-body {
  display: flex;
  gap: var(--space-10);
  align-items: flex-start;
}

/* Left sub-nav */
.v2-settings-subnav {
  width: 200px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: sticky;
  top: var(--space-8);
}

.v2-settings-navlink {
  display: block;
  padding: 8px 12px;
  border-radius: var(--radius-md);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-tertiary);
  text-decoration: none;
  transition: color 180ms ease-out, background 180ms ease-out;
}

.v2-settings-navlink:hover {
  color: var(--text-primary);
  background: rgba(255, 255, 255, 0.05);
}

.v2-settings-navlink--active {
  color: var(--iris-400);
  background: rgba(124, 92, 255, 0.1);
}

.v2-settings-navlink--danger {
  color: rgba(239, 68, 68, 0.7);
}

.v2-settings-navlink--danger:hover {
  color: var(--crimson-500);
  background: rgba(239, 68, 68, 0.08);
}

.v2-settings-navdivider {
  height: 1px;
  background: var(--border-default);
  margin: var(--space-2) var(--space-3);
}

/* Right content column */
.v2-settings-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* Settings card */
.v2-settings-card {
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: 16px;
  padding: var(--space-6);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}

.v2-settings-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.v2-settings-card--danger {
  border-color: rgba(239, 68, 68, 0.2);
}

.v2-settings-card--danger:hover {
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.08);
}

/* Card header row (icon + title) */
.v2-settings-card-hd {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.v2-settings-card-hd i {
  font-size: 20px;
  color: var(--iris-400);
  flex-shrink: 0;
}

.v2-settings-card--danger .v2-settings-card-hd i {
  color: var(--crimson-500);
}

.v2-settings-card-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
}

.v2-settings-card-title--danger {
  color: var(--crimson-500);
}

/* Settings row (label + control) */
.v2-settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--border-subtle);
}

.v2-settings-row:first-of-type {
  border-top: none;
}

.v2-settings-row--col {
  flex-direction: column;
  align-items: flex-start;
}

.v2-settings-row-label {
  flex: 1 1 auto;
  min-width: 0;
}

.v2-settings-row-name {
  display: block;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-primary);
}

.v2-settings-row-desc {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 3px;
  line-height: 1.45;
}

/* Inline control group (badge + button) */
.v2-settings-row-ctrl {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* User badge pill */
.v2-settings-user-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: rgba(124, 92, 255, 0.12);
  border: 1px solid rgba(124, 92, 255, 0.25);
  font-size: 13px;
  font-weight: 500;
  color: var(--iris-300);
  font-variant-numeric: tabular-nums;
}

/* Ghost button */
.v2-btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 7px 14px;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border-default);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
  font-family: var(--font-body);
  transition: background 180ms ease-out, color 180ms ease-out;
  white-space: nowrap;
}

.v2-btn-ghost:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-primary);
}

/* Danger button */
.v2-btn-danger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 7px 14px;
  border-radius: var(--radius-md);
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.2);
  font-size: 13px;
  font-weight: 500;
  color: var(--crimson-500);
  cursor: pointer;
  font-family: var(--font-body);
  transition: background 180ms ease-out;
  white-space: nowrap;
}

.v2-btn-danger:hover {
  background: rgba(239, 68, 68, 0.15);
}

/* Responsive: collapse subnav on narrow screens */
@media (max-width: 860px) {
  .v2-settings-subnav { display: none; }
}

/* =============================================================
   v2-puzzles - Puzzles page (Ship 4 of redesign train, v0.194.5)
   ============================================================= */

.v2-puzzles-canvas {
  padding: var(--space-8);
  min-height: calc(100vh - 56px);
  max-width: 1280px;
  /* v0.195.35: center the puzzles canvas in the available app-shell
     width instead of left-aligning it. Without this, on wide viewports
     the board sat hard against the navrail with a large dead zone on
     the right. The hero KPI row + mode tabs + board layout all live
     inside this canvas so a single margin:auto handles them all. */
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* Page header */
.v2-puzzles-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  padding-top: var(--space-4);
  padding-bottom: var(--space-2);
}

.v2-puzzles-h1 {
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: 0 0 var(--space-1) 0;
}

.v2-puzzles-subline {
  font-size: 14px;
  color: var(--text-tertiary);
  margin: 0;
}

/* KPI row: 3 stat cards */
.v2-puzzles-kpi-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
}

.v2-puzzles-kpi-card {
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}

.v2-puzzles-kpi-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.v2-puzzles-kpi-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-2);
}

.v2-puzzles-kpi-lbl {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-tertiary);
}

.v2-puzzles-kpi-icon {
  font-size: 18px;
  opacity: 0.75;
}

.v2-puzzles-kpi-card--amber .v2-puzzles-kpi-icon { color: var(--amber-500); }
.v2-puzzles-kpi-card--emerald .v2-puzzles-kpi-icon { color: var(--emerald-500); }
.v2-puzzles-kpi-card--iris .v2-puzzles-kpi-icon { color: var(--iris-400); }

.v2-puzzles-kpi-val {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.v2-puzzles-kpi-card--amber .v2-puzzles-kpi-val { color: var(--amber-500); }

.v2-puzzles-kpi-sub {
  font-size: 12px;
  color: var(--text-tertiary);
  margin-top: var(--space-1);
}

/* Mode bar wrapper */
.v2-puzzles-modes-wrap {
  margin-bottom: calc(-1 * var(--space-2));
}

/* Filters wrapper (random mode) */
.v2-puzzles-filters {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Banner cards for modes (daily / rush / lessons / spaced) */
.v2-puzzles-banner {
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}

.v2-puzzles-banner:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

/* Board section: two-column grid */
.v2-puzzles-board-section {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}

/* v0.195.19: bigger puzzle board. Side panel slimmed from 1fr to a
   fixed 360px column so the board absorbs the extra width. */
@media (min-width: 800px) {
  .v2-puzzles-board-section {
    grid-template-columns: minmax(0, 1fr) 360px;
    align-items: start;
  }
}

/* v0.195.19: remove the difficulty selector + theme chips + per-puzzle
   theme pills + stats drawer from the puzzles page. Lucas wants one big
   pool with no filtering. */
#pagePuzzles .v2-puzzles-filters,
#pagePuzzles .puz-difficulty-row,
#pagePuzzles .puz-theme-filter,
#pagePuzzles .puz-themes,
#pagePuzzles .v2-puzzles-stats-section {
  display: none !important;
}

/* Side panel card */
.v2-puzzles-side {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.v2-puzzles-side-card {
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Stats section */
.v2-puzzles-stats-section {
  margin-top: var(--space-2);
}

@media (max-width: 600px) {
  .v2-puzzles-kpi-row { grid-template-columns: 1fr; }
  .v2-puzzles-canvas { padding: 20px 16px 48px; gap: var(--space-4); }
  .v2-puzzles-h1 { font-size: 28px; }
  .v2-puzzles-kpi-val { font-size: 32px; }
}

@media (max-width: 800px) {
  .v2-puzzles-kpi-row { grid-template-columns: repeat(3, 1fr); }
}

/* =====================================================================
   v2-trainer -- Trainer (Endgames) page redesign (Ship 5, v0.194.7)
   ===================================================================== */
.v2-trainer-canvas {
  padding: var(--space-8);
  min-height: calc(100vh - 56px);
  max-width: 1280px;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* Page header */
.v2-trainer-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  padding-top: var(--space-4);
  flex-wrap: wrap;
}

.v2-trainer-header-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
  flex-shrink: 0;
}

.v2-trainer-h1 {
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: 0 0 var(--space-1) 0;
}

.v2-trainer-subline {
  font-size: 14px;
  color: var(--text-tertiary);
  margin: 0;
  max-width: 480px;
  line-height: 1.55;
}

/* Today's Plan card */
.v2-trainer-plan-card {
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  padding: var(--space-6);
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}

.v2-trainer-plan-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.v2-trainer-plan-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid rgba(42, 42, 46, 0.5);
}

.v2-trainer-plan-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.v2-trainer-plan-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 100px;
  background: rgba(16, 185, 129, 0.1);
  color: #10B981;
  font-size: 12px;
  font-weight: 500;
}

.v2-trainer-plan-stepper {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

@media (min-width: 700px) {
  .v2-trainer-plan-stepper {
    flex-direction: row;
    justify-content: space-between;
    gap: var(--space-2);
  }
}

.v2-trainer-plan-loading {
  font-size: 13px;
  color: var(--text-tertiary);
}

.v2-trainer-plan-step {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 1;
}

@media (min-width: 700px) {
  .v2-trainer-plan-step {
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    text-align: center;
  }
}

.v2-trainer-step-dot {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 14px;
}

.v2-trainer-step-dot--done {
  background: #10B981;
  color: #0B0B0D;
}

.v2-trainer-step-dot--active {
  background: var(--accent, #7C5CFF);
  color: white;
  box-shadow: 0 0 0 3px var(--bg-0, #0B0B0D), 0 0 0 5px var(--accent, #7C5CFF);
}

.v2-trainer-step-dot--pending {
  background: var(--bg-1);
  border: 2px solid var(--border-default);
  color: var(--text-tertiary);
}

.v2-trainer-step-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.v2-trainer-step-name {
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.v2-trainer-step-name--done    { color: var(--text-secondary); }
.v2-trainer-step-name--active  { color: var(--accent, #7C5CFF); }
.v2-trainer-step-name--pending { color: var(--text-tertiary); }

.v2-trainer-step-dur {
  font-size: 11px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.v2-trainer-plan-cta {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(42, 42, 46, 0.5);
  display: flex;
  justify-content: flex-end;
}

.v2-trainer-plan-start-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 40px;
  padding: 0 20px;
  border-radius: var(--radius-lg);
  background: var(--accent, #7C5CFF);
  color: white;
  font-size: 14px;
  font-weight: 500;
  border: none;
  cursor: pointer;
  transition: background 180ms ease-out;
}

.v2-trainer-plan-start-btn:hover { background: #6848EB; }

/* Catalog section */
.v2-trainer-catalog-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.v2-trainer-catalog-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.v2-trainer-catalog-h2 {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
}

/* Category filter chips */
.v2-trainer-cat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.v2-trainer-chip {
  padding: 6px 14px;
  border-radius: 100px;
  border: 1px solid var(--border-default);
  background: var(--bg-1);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 180ms ease, color 180ms ease, border-color 180ms ease;
  line-height: 1;
}

.v2-trainer-chip:hover {
  background: var(--bg-2);
  color: var(--text-primary);
}

.v2-trainer-chip.active {
  background: rgba(124, 92, 255, 0.1);
  border-color: var(--accent, #7C5CFF);
  color: var(--accent, #7C5CFF);
}

/* Recently completed section */
.v2-trainer-recent-section {
  padding-bottom: var(--space-8);
}

.v2-trainer-recent-h {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-tertiary);
  margin: 0 0 var(--space-3) 0;
}

.v2-trainer-recent-list {
  background: rgba(42, 42, 46, 0.3);
  border: 1px solid rgba(42, 42, 46, 0.5);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.v2-trainer-recent-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  border-bottom: 1px solid rgba(42, 42, 46, 0.5);
  transition: background 180ms ease;
}

.v2-trainer-recent-row:last-child { border-bottom: none; }
.v2-trainer-recent-row:hover { background: rgba(42, 42, 46, 0.8); }

.v2-trainer-recent-left {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 1;
  min-width: 0;
}

.v2-trainer-recent-icon {
  font-size: 16px;
  color: #10B981;
  flex-shrink: 0;
}

.v2-trainer-recent-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.v2-trainer-recent-dot {
  color: var(--text-tertiary);
  font-size: 14px;
  flex-shrink: 0;
}

.v2-trainer-recent-cat {
  font-size: 13px;
  color: var(--text-tertiary);
  white-space: nowrap;
  flex-shrink: 0;
}

.v2-trainer-recent-replay {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-tertiary);
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--radius);
  transition: color 180ms ease;
  opacity: 0;
  flex-shrink: 0;
}

.v2-trainer-recent-row:hover .v2-trainer-recent-replay,
.v2-trainer-recent-row:focus-within .v2-trainer-recent-replay {
  opacity: 1;
}

.v2-trainer-recent-replay:hover { color: var(--text-primary); }

.v2-trainer-recent-empty {
  padding: var(--space-5) var(--space-6);
  color: var(--text-tertiary);
  font-size: 14px;
}

@media (max-width: 700px) {
  .v2-trainer-canvas { padding: 20px 16px 48px; gap: var(--space-4); }
  .v2-trainer-h1 { font-size: 28px; }
  .v2-trainer-header { align-items: flex-start; }
  .v2-trainer-header-actions { align-items: flex-start; }
  .v2-trainer-cat-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 4px;
  }
  .v2-trainer-chip { flex-shrink: 0; }
  .v2-trainer-catalog-hd { flex-direction: column; align-items: flex-start; }
}

/* =====================================================================
   v2-op -- Openings Explorer detail/practice view (Ship 6, v0.194.8)
   ===================================================================== */

/* Two-column grid: board card on the left, side card on the right */
.v2-op-detail-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-6);
  align-items: flex-start;
}

/* Board panel card surface */
.v2-op-board-card {
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
  box-shadow: var(--shadow-card);
  transition: transform 180ms ease, box-shadow 180ms ease;
}
.v2-op-board-card:hover { transform: translateY(-1px); box-shadow: var(--shadow-elevated); }

/* Side panel card surface */
.v2-op-side-card {
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  box-shadow: var(--shadow-card);
  min-width: 0;
  overflow-y: auto;
}

/* Override side panel flex defaults when using card variant */
.op-side-panel.v2-op-side-card { flex: unset; }

/* Opening detail header area */
.v2-op-detail-header { margin-bottom: var(--space-5); }

/* Opening name: Space Grotesk display (v0.195.44 swap from italic Newsreader) */
.v2-op-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 28px;
  line-height: 1.2;
  color: var(--text);
  margin: 0 0 var(--space-1) 0;
}

/* ECO code eyebrow above the name */
.v2-op-eco-eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 4px;
}

/* Color badge (White / Black) next to title */
.v2-op-color-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
}
.v2-op-color-badge.op-badge-w { background: rgba(255,255,255,0.12); color: var(--text); }
.v2-op-color-badge.op-badge-b { background: rgba(0,0,0,0.35); color: var(--text-dim); border: 1px solid var(--border-default); }

/* Difficulty badge */
.v2-op-diff-badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: capitalize;
}
.v2-op-diff-badge[data-diff="beginner"]     { background: var(--diff-beginner);     color: var(--diff-beginner-fg); }
.v2-op-diff-badge[data-diff="intermediate"] { background: var(--diff-intermediate); color: var(--diff-intermediate-fg); }
.v2-op-diff-badge[data-diff="advanced"]     { background: var(--diff-advanced);     color: var(--diff-advanced-fg); }

/* Detail title row */
.v2-op-detail-title-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

/* Summary text */
.v2-op-summary {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.55;
  margin: 0 0 var(--space-2) 0;
}

/* Theme chips row */
.v2-op-themes { display: flex; gap: 6px; flex-wrap: wrap; }
.v2-op-theme-chip {
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  font-size: 11px;
  color: var(--text-dim);
}

/* Practice CTA (v2 Iris button) */
.v2-op-practice-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 11px 24px;
  border-radius: var(--radius-md);
  background: var(--iris-500);
  color: #fff;
  border: none;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s, transform 0.1s, box-shadow 0.1s;
  box-shadow: 0 4px 14px rgba(124, 92, 255, 0.3);
}
.v2-op-practice-cta-btn:hover {
  background: var(--iris-400);
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(124, 92, 255, 0.4);
}
.v2-op-practice-cta-btn:active {
  transform: scale(0.97);
  transition: transform 60ms;
}

/* Practice header h2 */
.v2-op-practice-header h2 {
  font-size: 18px;
  margin: 0 0 var(--space-4) 0;
  color: var(--text);
}
.v2-op-practice-header h2 strong {
  font-family: var(--font-display);
  color: var(--iris-400);
  font-weight: 600;
}

/* Board toolbar sits above the board in practice view */
.op-board-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
}

/* Model game: update inline SVG toggle arrow → Phosphor-consistent caret */
.op-model-details summary::before { display: none; }
.op-model-details summary .v2-op-caret {
  transition: transform 0.25s ease;
  margin-right: var(--space-2);
}
.op-model-details[open] summary .v2-op-caret { transform: rotate(90deg); }

/* Responsive: stack columns at ≤900px */
@media (max-width: 900px) {
  .v2-op-detail-grid {
    grid-template-columns: 1fr;
  }
  .v2-op-board-card { width: 100%; box-sizing: border-box; }
  .v2-op-side-card { max-height: none; overflow-y: visible; }
  .op-board.op-board { width: 100% !important; height: auto !important; }
  .op-controls.op-controls { width: 100% !important; box-sizing: border-box; }
}

.sidebar-topbar .back-btn {
  flex: 1;
  border-radius: 10px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  padding: 9px 14px;
  font-size: 12.5px; font-weight: 700;
  letter-spacing: 0.3px;
  color: var(--text-dim);
  text-align: left;
  cursor: pointer;
  transition: color 0.12s, background 0.12s, border-color 0.12s, transform 0.08s;
  display: flex; align-items: center; gap: 8px;
}
.sidebar-topbar .back-btn:hover {
  color: var(--text);
  background: rgba(var(--accent-rgb), 0.08);
  border-color: rgba(var(--accent-rgb), 0.35);
}
.sidebar-topbar .back-btn:active { transform: translateY(1px); }
.sidebar-pin {
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 10px;
  cursor: pointer;
  width: 38px;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; line-height: 1;
  color: var(--text-faint); opacity: 0.85;
  transition: opacity 0.12s, color 0.12s, transform 0.12s, border-color 0.12s, background 0.12s;
}
.sidebar-pin:hover {
  opacity: 1; color: var(--accent); transform: scale(1.06);
  border-color: rgba(var(--accent-rgb), 0.45);
  background: rgba(var(--accent-rgb), 0.08);
}
.sidebar-pin.on { color: var(--accent); opacity: 1; border-color: rgba(var(--accent-rgb), 0.45); }
/* legacy .back-btn kept for back-compat in case other pages reference it */
.back-btn {
  background: transparent; border: none; color: var(--text-dim);
  padding: 12px 16px; font-size: 12.5px; font-weight: 700; cursor: pointer;
  text-align: left;
  display: flex; align-items: center; gap: 8px;
  letter-spacing: 0.3px;
  transition: color 0.12s, background 0.12s;
}
.back-btn:hover { color: var(--accent); background: rgba(var(--accent-rgb), 0.05); }

/* Inner container holds all stacked cards. The back button stays pinned
   at the top and the keyboard-shortcuts pill stays pinned at the bottom.
   The moves card is flex:1, and its inner .side-moves scrolls - so the
   header cards stay visible while a long move list scrolls. */
.sidebar-scroll {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px 12px 8px;
  overflow: hidden;
}

/* Generic "card" used to wrap each section of the sidebar with rounded
   corners and a subtle border, matching the chess.com-style review UI. */
.sg-card {
  background: var(--bg-1);
  border: 1px solid var(--border-default, var(--bg-3));
  border-radius: var(--radius-card, 12px);
  overflow: hidden;
  box-shadow: var(--shadow-card, 0 1px 0 rgba(0,0,0,0.25));
  transition: transform 140ms, box-shadow 140ms;
}
.sg-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-elevated, 0 4px 20px rgba(0,0,0,0.3));
}

/* Result pill removed in v0.195.128 (the standalone "White wins" sidebar
   panel); the Victory/Defeat/Draw chip in the page header conveys it. */

.side-game-header {
  /* legacy block kept for backwards-compat - visuals now come from .sg-card */
}
.sg-opening-card .sg-opening {
  background: transparent;
  border: none;
  padding: 11px 14px;
}
.sg-opening {
  /* v0.195.44: Lucas asked for a less curvy font on opening titles.
     Switched from italic Newsreader to the regular display sans (Space
     Grotesk) used on headings throughout the app. */
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13.5px;
  color: var(--text);
  padding: 11px 16px 9px;
  white-space: normal; overflow: visible; text-overflow: clip;
  line-height: 1.35;
  word-break: break-word;
}
.sg-players {
  display: flex; flex-direction: column; gap: 4px;
  padding: 10px 14px 6px;
}
.sg-prow {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text);
  padding: 3px 0;
}
/* v2 player row avatar disc */
.sg-prow-avatar {
  width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  font-size: 11px;
  color: var(--bg-1);
}
.sg-prow-avatar.white {
  background: #ecd9b9;
  border: 1.5px solid #ecd9b9;
  color: #3a2e1a;
}
.sg-prow-avatar.black {
  background: #1f1f23;
  border: 1.5px solid #2a2a2e;
  color: #d6c39e;
}
.sg-prow .nm { flex: 1; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sg-prow .rt { color: var(--text-dim); font-family: "Consolas", monospace; font-size: 12px; }
.sg-meta-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 14px 11px;
  font-size: 11.5px; color: var(--text-faint);
  border-top: 1px solid var(--border-default, rgba(0,0,0,0.18));
  margin-top: 4px;
}
.sg-tc { display: inline-flex; align-items: center; gap: 5px; }
.sg-tc-ico { opacity: 0.6; flex-shrink: 0; }
.sg-date { font-family: "Consolas", monospace; }

/* Mini eval chart (chess.com-style cream area). v0.176: rounded edges
   on the chart container so the win% chart visually matches the new
   rounded eval bar + report-card aesthetic.
   v0.176.2: dropped the 8/10/4 padding so the cream chart-fill
   actually meets the rounded corners of the container instead of
   sitting inset with sharp 90 corners. Bumped radius 12->14 to
   read clearly through the overflow clip. */
.eval-card { padding: 0; }
.side-eval-mini {
  position: relative; height: 120px;
  padding: 0;
  background: var(--bg-2);
  border-radius: 14px;
  overflow: hidden;
}
.side-eval-mini canvas { width: 100% !important; height: 100% !important; display: block; }

/* Moves card takes the remaining vertical space inside the scroll area. */
.moves-card { flex: 1; display: flex; flex-direction: column; min-height: 180px; }
/* v0.176.10: move-list scroll chrome hidden so the visible
   scrollbar no longer sits immediately to the left of the Mentor
   + Report pills. Scrolling still works (mousewheel, drag, keyboard);
   we just suppress the rendered scrollbar in both Firefox and the
   WebKit/Blink family. */
.side-moves {
  flex: 1; overflow-y: auto;
  scrollbar-width: none;
}
.side-moves::-webkit-scrollbar { width: 0; height: 0; display: none; }
.side-moves .move-table { width: 100%; border-collapse: collapse; }

/* Keyboard-shortcuts pill pinned at the very bottom of the sidebar. */
.kbd-help-pill {
  margin: 8px 12px 14px;
  padding: 10px 14px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 999px;
  color: var(--text-dim);
  font-size: 12.5px; font-weight: 600;
  letter-spacing: 0.15px;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  transition: color 0.12s, background 0.12s, border-color 0.12s;
}
.kbd-help-pill:hover {
  color: var(--accent);
  background: rgba(var(--accent-rgb), 0.06);
  border-color: rgba(var(--accent-rgb), 0.35);
}
.kbd-help-pill .ico { font-size: 14px; opacity: 0.85; }

/* Keyboard-shortcuts modal */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.55);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  backdrop-filter: blur(2px);
}
.modal-backdrop[hidden] { display: none; }
.modal-card {
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 14px;
  min-width: 320px;
  max-width: 420px;
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}
.modal-card-wide { max-width: 640px; width: 92vw; }
.pgn-import-hint { color: var(--text-dim); font-size: 13px; margin: 0 0 6px; }
.pgn-import-hint code {
  background: rgba(0,0,0,0.35); padding: 1px 5px; border-radius: 4px;
  font-family: "Consolas", monospace; font-size: 12px; color: var(--text);
}
.pgn-import-text {
  width: 100%; box-sizing: border-box;
  background: var(--bg-1); border: 1px solid var(--bg-3); border-radius: 8px;
  color: var(--text); padding: 10px 12px;
  font-family: "Consolas", monospace; font-size: 12.5px; line-height: 1.4;
  resize: vertical; min-height: 160px;
}
.pgn-import-text:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.22);
}
.pgn-import-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 6px; font-size: 13px; color: var(--text-dim);
}
.pgn-import-color select {
  background: var(--bg-1); color: var(--text); border: 1px solid var(--bg-3);
  border-radius: 6px; padding: 4px 8px; margin-left: 6px;
}
.pgn-import-error { color: #e96; font-size: 12px; }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--bg-3);
  font-family: var(--serif); font-weight: 700; font-size: 15px;
  color: var(--text);
}
.modal-x {
  background: transparent; border: none; color: var(--text-faint);
  font-size: 22px; line-height: 1; cursor: pointer;
  padding: 0 4px;
}
.modal-x:hover { color: var(--accent); }
.modal-body { padding: 14px 18px 18px; display: flex; flex-direction: column; gap: 8px; }
.kbd-group-h {
  margin-top: 6px;
  font-size: 10px; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--accent); font-weight: 700;
}
.kbd-group-h:first-child { margin-top: 0; }
.kbd-row { display: flex; align-items: center; gap: 12px; color: var(--text-dim); font-size: 13px; }
.kbd-row kbd {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 38px; padding: 4px 8px;
  background: rgba(0,0,0,0.35); border: 1px solid var(--bg-3);
  border-radius: 6px;
  font-family: "Consolas", monospace; font-size: 12px;
  color: var(--text);
  box-shadow: inset 0 -2px 0 rgba(0,0,0,0.35);
}

/* ===== board area ===== */
.board-area {
  display: flex; flex-direction: column; align-items: center;
  /* Issue E v0.147.1: extra 40px on the right shifts the centering
     point ~20px leftward, giving the Mentor more clearance on the
     right side at wide viewports. At 1440px the board sits near the
     left edge of the board-area; at 1920px+ the shift is visible and
     comfortable. Player-strips and controls shift consistently since
     they also center in the same content box.
     v0.180.1: shrunk right padding 56 -> 18 so the board sits more centred
     in its column and the Mentor + Game Report pills appear closer to the
     board (matching Lucas's "move panels closer to the board" feedback). */
  padding: 18px 18px 18px 16px;
  gap: 9px; overflow-y: auto;
  /* v0.182.1: hide the column's scrollbar chrome so the board area no
     longer shows a visible scrollbar between the board and the right
     pane (matching .side-moves + .tab-content). Scrolling still works
     via wheel / touch / keyboard. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.board-area::-webkit-scrollbar { width: 0; height: 0; display: none; }
.player-strip {
  display: flex; align-items: center; gap: 12px;
  width: var(--board-w, 560px); padding: 9px 14px;
  background: var(--bg-2); border-radius: 6px;
  border: 1px solid var(--bg-3);
}
/* v0.195.99: evolving "current opening" label above the opponent strip.
   Shows the position-specific opening (from the curated ECO database) that
   updates as the user steps through the game. The top-left card keeps the
   overall opening name. */
.sg-current-opening {
  width: var(--board-w, 560px);
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--accent);
  padding: 2px 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sg-current-opening[hidden] { display: none; }
.player-strip .pavatar {
  width: 32px; height: 32px; border-radius: 5px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 16px; font-family: var(--serif);
}
.player-strip .pavatar.white { background: var(--light-sq); color: #1a1a1a; border: 1px solid rgba(0,0,0,0.15); }
.player-strip .pavatar.black { background: var(--dark-sq); color: var(--light-sq); border: 1px solid var(--bg-4); }
.player-strip .pinfo {
  display: flex; gap: 8px; align-items: baseline;
  flex: 1; min-width: 0;
}
.player-strip .pname {
  font-weight: 700; font-size: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 200px;
}
.player-strip .prating { color: var(--text-dim); font-size: 13px; flex-shrink: 0; }

/* right-side cluster: captured pieces, clock, accuracy */
.player-strip .pmeta {
  margin-left: auto; display: flex; align-items: center; gap: 14px; flex-shrink: 0;
}

.pmaterial { display: flex; align-items: center; gap: 1px; }
.pmaterial.empty { display: none; }
.pmaterial .pc {
  font-family: "Segoe UI Symbol", "Apple Symbols", "DejaVu Sans", sans-serif;
  font-size: 14px; line-height: 1; opacity: 0.8;
  letter-spacing: -2px;
}
.pmaterial .pc.white { color: #ecd9b9; }
/* Issue C v0.147.1: white drop-shadow halo so black glyphs stay visible
   on every dark palette (--on-accent is near-black on most themes). The
   filter follows the glyph outline, giving a subtle white halo without
   altering the fill colour. Applies to both Game Review and Play (Tony's
   shared paintCaptured renderer uses the same .pc.black class). */
.pmaterial .pc.black { color: var(--on-accent); filter: drop-shadow(0 0 1px rgba(255,255,255,0.55)) drop-shadow(0 0 0.5px rgba(255,255,255,0.4)); }
.pmaterial .pdiff {
  margin-left: 6px; font-size: 11.5px; color: var(--text-dim);
  font-family: "Consolas", monospace; font-weight: 700;
}

.pclock {
  font-family: "Consolas", "JetBrains Mono", monospace;
  font-size: 15px; font-weight: 700; color: var(--text);
  background: rgba(0,0,0,0.32); border: 1px solid var(--bg-3);
  padding: 5px 11px; border-radius: 5px; letter-spacing: 0.5px;
  min-width: 70px; text-align: center;
}
.pclock.empty { display: none; }
.pclock.active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.pclock.low { color: var(--cat-blunder); }

.player-strip .pacc {
  display: flex; align-items: center; gap: 8px;
}
.pacc.empty { display: none !important; }
.pacc .acc-badge {
  font-size: 17px; font-weight: 800; padding: 5px 13px;
  border-radius: 5px; line-height: 1; min-width: 66px; text-align: center;
  background: rgba(0,0,0,0.25);
  font-family: "Consolas", "JetBrains Mono", monospace;
  border: 1px solid var(--bg-3); color: var(--text);
}
.pacc .acc-badge.high { color: #95bc6a; border-color: rgba(149,188,106,0.55); background: rgba(149,188,106,0.08); }
.pacc .acc-badge.med  { color: var(--cat-inaccuracy); border-color: rgba(247,194,69,0.55); background: rgba(247,194,69,0.06); }
.pacc .acc-badge.low  { color: var(--cat-blunder); border-color: rgba(250,65,45,0.55); background: rgba(250,65,45,0.06); }
.pacc .acc-label {
  font-size: 10px; color: var(--text-faint); text-transform: uppercase;
  letter-spacing: 0.7px; font-weight: 700;
}

.board-row { display: flex; align-items: flex-start; gap: 10px; }
/* board-col: vertical stack of player strips, the board SVG, controls and ply-line.
   All children share the same --board-w width so they're always aligned. */
.board-col { display: flex; flex-direction: column; gap: 9px; }
/* Legacy wrapper class - kept to avoid orphan refs but no longer used. */
.board-stack { position: relative; display: inline-block; line-height: 0; }
.board-wrap { position: relative; line-height: 0; }

/* One-shot "pop" when a piece is selected (click or drag-start). The
   highlight rect is recreated each render, so the animation replays only
   when a fresh selection is drawn. Subtle scale-up from the square centre.
   Disabled under prefers-reduced-motion. */
/* v0.195.158: hold a stable, clearly-yellow opacity for the selected square.
   The pop animation used to end at opacity:1 then (fill-mode none) revert to
   the faint .last-move 0.42, so the square flashed the correct yellow and
   then settled into an off-yellow/beige blend. This higher-specificity rule
   (two classes) beats .last-move's 0.42 and the keyframe now ends on the same
   value, so there is no post-pop colour shift -- and it also holds for
   reduced-motion users who get no animation at all. */
.last-move.sel-sq-pulse { opacity: 0.72; }
.sel-sq-pulse {
  transform-box: fill-box;
  transform-origin: center;
  animation: sel-sq-pop 180ms cubic-bezier(.34, 1.56, .64, 1) 1;
}
@keyframes sel-sq-pop {
  0%   { transform: scale(0.7); opacity: 0.45; }
  100% { transform: scale(1);   opacity: 0.72; }
}
@media (prefers-reduced-motion: reduce) {
  .sel-sq-pulse { animation: none; }
}
#board {
  width: var(--board-w, 560px); height: var(--board-w, 560px);
  border-radius: 5px;
  box-shadow: var(--board-glow), 0 0 0 1px var(--board-ring);
}

/* v0.195.168: optional rounded / soft board corners. The Settings >
   Board & Pieces "Rounded board edges" toggle sets data-board-round="1"
   on <html>. We round the board SVG itself: an outer <svg> clips its
   content to its viewport, so a border-radius on it rounds away the four
   corner squares. The box-shadow ring lives on the same element (or on
   the wrapper for the puzzle board) so the frame follows the radius too.
   Kept modest (18px) so the result/badge sticker near a corner still
   reads. Applies to every board: analyse, play, puzzles, trainer. */
html[data-board-round="1"] #board,
html[data-board-round="1"] #playBoard,
html[data-board-round="1"] #puzBoard,
html[data-board-round="1"] #openingsBoard,
html[data-board-round="1"] #openingsPracticeBoard,
html[data-board-round="1"] #egPlayBoard,
html[data-board-round="1"] #coursesBoard {
  border-radius: 18px !important;
}
/* The puzzle board lives in a wrapper with overflow:hidden, so the wrapper
   must round too or it re-clips the SVG corners to its smaller radius. The
   #pagePuzzles-scoped rule below outranks the existing card-radius rule. */
html[data-board-round="1"] #pagePuzzles .puz-board-wrap {
  border-radius: 18px !important;
}

/* ----- Move explanation panel (Mentor) -----
   Desktop (≥1880px): position:fixed so it floats beside the board without
   participating in any flex layout - the board never shifts when this
   panel shows/hides. left formula updated for v0.147.1 (Issue E board
   shift): board center = 50vw - 4px after the extra right-padding;
   board right = 50vw + board-w/2 + 6px; Mentor left = board-right + 10px.
   Medium desktop (721px-1879px): position:relative so it flows IN-FLOW
   below the controls bar - eliminates overlap with the Game Report panel
   at 1440px where there isn't enough horizontal clearance. Board-area
   has overflow-y:auto so users scroll down to see the Mentor.
   Mobile (<720 px): position:static !important overrides (unchanged).
   v0.140.7: moved out of .board-row into .board-area so centering is clean. */
/* Fix 6 (Wanda-19): Mentor card lives in the right column (rightpane),
   above the tab bar. No longer position:fixed - it's a normal block
   element. Tab content scrolls independently via flex: 1 / overflow-y: auto. */
.move-explainer {
  flex-shrink: 0;
  /* v0.176.2: pin Mentor to the top of the rightpane so it stays
     visible above whatever tab/panel is rendered below. The
     rightpane itself has overflow:hidden, but sticky is cheap
     insurance for the few callsites that wrap the panel in a
     scroll container. z-index keeps it above the .tabs shadow.
     v0.176.8: tiny inset + rounded corners turn it into a "pill"
     card. top:8px sets the gap below the rightpane's padding-top
     (which already clears the floating topbar overlay). The
     bottom margin creates the visible gap between this pill and
     the Report/Review/Book pill below. */
  position: sticky; top: 8px; z-index: 5;
  margin: 8px 6px 10px 0;
  border-radius: 14px;
  overflow: hidden;
  /* v0.180.0: switched from hardcoded earthy RGB gradient to --bg-1 so
     the Mentor pill matches the Game Report pill and the sidebar cards
     under any theme (steel / midnight / light all looked off before).
     v0.180.1: bumped to --bg-2 for a touch more contrast against the
     body --bg-0, matching Lucas's "panels still need more pop" feedback. */
  background: var(--bg-2);
  color: var(--text-1, #ece6d8);
  padding: 14px 16px 12px;
  font-size: 13px;
  line-height: 1.5;
}
@keyframes explainer-pop {
  from { opacity: 0; transform: translateY(-4px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ----- Edge Coach panel (v0.136) -------------------------------------- */
/* BUG FIX: the HTML [hidden] attribute (display:none equivalent) loses
   to author-defined `display: flex`/`display: block` rules. Force it
   here so toggling .hidden actually hides the children. Without this,
   both the teaser AND the active state render at once. */
.coach-teaser[hidden],
.coach-active[hidden] { display: none !important; }

/* Avatar = small bulb-with-base glyph; uses currentColor so it adopts
   the active palette. */
.coach-avatar {
  flex: 0 0 auto;
  width: 28px; height: 28px;
  border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(155deg,
    color-mix(in srgb, var(--accent, #b6d99a) 85%, white 5%),
    color-mix(in srgb, var(--accent, #b6d99a) 30%, #1a1410));
  color: #1b1410;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.20), 0 1px 2px rgba(0,0,0,0.45);
}

/* ----- Teaser state (coach disabled) ----- */
.coach-teaser {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 4px 2px 2px;
}
.coach-teaser-icon {
  width: 36px; height: 36px;
  border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(155deg,
    color-mix(in srgb, var(--accent, #b6d99a) 75%, white 5%),
    color-mix(in srgb, var(--accent, #b6d99a) 25%, #1a1410));
  color: #1b1410;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), 0 1px 2px rgba(0,0,0,0.4);
}
.coach-teaser-title {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-1, #ece6d8);
  letter-spacing: 0.05px;
}
.coach-teaser-sub {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-2, #a8a193);
}
.coach-teaser-btn {
  margin-top: 2px;
  width: 100%;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent, #b6d99a) 100%, transparent),
    color-mix(in srgb, var(--accent, #b6d99a) 78%, #1a1410));
  color: #1b1410;
  border: none;
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.15px;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 2px 6px rgba(0,0,0,0.35);
  transition: filter 120ms, transform 120ms;
}
.coach-teaser-btn:hover { filter: brightness(1.08); }
.coach-teaser-btn:active { transform: translateY(1px); }

/* ----- Active state (coach enabled) ----- */
.coach-active {
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.coach-head {
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(255,255,255,0.07);
}
.coach-title {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-1, #ece6d8);
  letter-spacing: 0.15px;
}
.coach-cat {
  margin-left: auto;
  display: inline-flex; align-items: center;
  gap: 5px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.35px;
  color: var(--text-2, #b9b0a0);
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.07);
}
.coach-cat .cat-icon { width: 12px; height: 12px; }
.coach-mute {
  background: transparent;
  border: none;
  color: var(--text-2, #8a8174);
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 7px;
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.coach-mute:hover { background: rgba(255,255,255,0.08); color: var(--text-1, #fff); }
.coach-body {
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-1, #e8e1d4);
  min-height: 48px;
}
.coach-body em {
  font-style: normal;
  font-weight: 600;
  color: var(--accent, #b6d99a);
}
.coach-body u {
  text-decoration: underline;
  text-decoration-color: var(--accent, #b6d99a);
  text-decoration-style: dotted;
  text-underline-offset: 3px;
  text-decoration-thickness: 1.5px;
  cursor: help;
}
.coach-body code {
  font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
  font-size: 12px;
  background: rgba(255,255,255,0.06);
  padding: 1px 5px;
  border-radius: 4px;
  color: var(--text-1, #ece6d8);
}

/* Suggestion chips */
.coach-chips {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.coach-chip {
  text-align: left;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  color: var(--text-1, #e8e1d4);
  font-size: 12.5px;
  line-height: 1.4;
  padding: 9px 11px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 120ms, border-color 120ms, transform 80ms;
}
.coach-chip:hover {
  background: rgba(255,255,255,0.08);
  border-color: color-mix(in srgb, var(--accent, #b6d99a) 40%, transparent);
}
.coach-chip:active { transform: translateY(1px); }
.coach-chip.is-asked {
  background: color-mix(in srgb, var(--accent, #b6d99a) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent, #b6d99a) 35%, transparent);
  color: var(--text-1, #ece6d8);
}

/* Category-tinted accent on the small label in the head row. */
.coach-cat.cat-BRILLIANT  { color: #d63a8e; border-color: color-mix(in srgb, #d63a8e 32%, transparent); }
.coach-cat.cat-GREAT      { color: #5b9bd9; border-color: color-mix(in srgb, #5b9bd9 32%, transparent); }
.coach-cat.cat-BEST       { color: #81b64c; border-color: color-mix(in srgb, #81b64c 32%, transparent); }
.coach-cat.cat-EXCELLENT  { color: #95c25b; border-color: color-mix(in srgb, #95c25b 32%, transparent); }
.coach-cat.cat-GOOD       { color: #9eb37a; border-color: color-mix(in srgb, #9eb37a 32%, transparent); }
.coach-cat.cat-BOOK       { color: #c9a76a; border-color: color-mix(in srgb, #c9a76a 32%, transparent); }
.coach-cat.cat-FORCED     { color: #8aa0c8; border-color: color-mix(in srgb, #8aa0c8 32%, transparent); }
.coach-cat.cat-INACCURACY { color: #f2c94c; border-color: color-mix(in srgb, #f2c94c 32%, transparent); }
.coach-cat.cat-MISTAKE    { color: #e8973c; border-color: color-mix(in srgb, #e8973c 32%, transparent); }
.coach-cat.cat-MISS       { color: #d76b6b; border-color: color-mix(in srgb, #d76b6b 32%, transparent); }
.coach-cat.cat-BLUNDER    { color: #d44545; border-color: color-mix(in srgb, #d44545 32%, transparent); }

/* Legacy move-explainer-* rules kept only as defensive fallback. */
.move-explainer-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.move-explainer-cat {
  display: inline-flex; align-items: center; gap: 6px;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.2px;
}
.move-explainer-cat-label { line-height: 1; }
.move-explainer-san {
  margin-left: auto;
  font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
  font-size: 12px;
  color: var(--text-2, #b9b0a0);
}
.move-explainer-x {
  background: transparent;
  border: none;
  color: var(--text-2, #b9b0a0);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
  border-radius: 6px;
  transition: background 120ms;
}
.move-explainer-x:hover { background: rgba(255,255,255,0.08); color: var(--text-1, #fff); }
.move-explainer-body {
  color: var(--text-1, #e8e1d4);
  font-size: 12.5px;
}
/* Category-tinted left border to match the move's color in the move list. */
.move-explainer.cat-BRILLIANT,  .move-explainer-cat.cat-BRILLIANT  { color: #d63a8e; }
.move-explainer.cat-GREAT,      .move-explainer-cat.cat-GREAT      { color: #5b9bd9; }
.move-explainer.cat-BEST,       .move-explainer-cat.cat-BEST       { color: #81b64c; }
.move-explainer.cat-EXCELLENT,  .move-explainer-cat.cat-EXCELLENT  { color: #95c25b; }
.move-explainer.cat-GOOD,       .move-explainer-cat.cat-GOOD       { color: #9eb37a; }
.move-explainer.cat-BOOK,       .move-explainer-cat.cat-BOOK       { color: #c9a76a; }
.move-explainer.cat-FORCED,     .move-explainer-cat.cat-FORCED     { color: #8aa0c8; }
.move-explainer.cat-INACCURACY, .move-explainer-cat.cat-INACCURACY { color: #f2c94c; }
.move-explainer.cat-MISTAKE,    .move-explainer-cat.cat-MISTAKE    { color: #e8973c; }
.move-explainer.cat-MISS,       .move-explainer-cat.cat-MISS       { color: #d76b6b; }
.move-explainer.cat-BLUNDER,    .move-explainer-cat.cat-BLUNDER    { color: #d44545; }


/* eval bar (black top, white bottom). v0.176: thicker + rounded edges. */
.eval-bar {
  width: 30px; height: var(--board-w, 560px);
  /* Offset past the player-strip + gap so the bar sits beside the board,
     not beside the player-strip header (v0.140.7). */
  margin-top: calc(var(--player-strip-h, 52px) + 9px);
  /* Fix 2 (Wanda-19): always black/white regardless of palette */
  background: #1a1a1a;
  border-radius: 10px; overflow: hidden;
  position: relative;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.35);
  border: 1px solid #111;
}
.eval-white {
  position: absolute; bottom: 0; left: 0; right: 0;
  /* Fix 2 (Wanda-19): hardcoded white - palette-independent */
  background: #f5f5f5;
  height: 50%;
  transition: height 0.4s cubic-bezier(.4,0,.2,1);
}
.eval-mark {
  position: absolute; left: 0; right: 0; height: 1px;
  background: #cc4444; opacity: 0; pointer-events: none;
  bottom: 50%;
}
.eval-num {
  position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%);
  /* Fix 2 (Wanda-19): larger, pill-style, not monospace */
  font-size: 13px; font-weight: 700; color: #1a1a1a;
  font-family: "Segoe UI", -apple-system, sans-serif; z-index: 2;
  background: rgba(245,245,245,0.88); padding: 2px 5px; border-radius: 999px;
  line-height: 1; min-width: 24px; text-align: center;
}
.eval-num.dark {
  color: #f5f5f5; background: rgba(26,26,26,0.88);
  bottom: auto; top: 4px;
}

/* ===== board controls bar (chess.com-style minimal icon row) =====
   Layout: [ flip ]  ............  [ ⏮ ⬅ ▶ ➡ ⏭ ]  ............  [ ⚙ ]
   Width matches the board, sits in a single rounded panel. */
.controls {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  width: var(--board-w, 560px);
  margin-top: 10px;
  padding: 10px 14px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 14px;
  box-shadow: 0 1px 0 rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.02);
}
/* Left column: flip button (anchored to the left of the grid cell). */
.controls > .ctrl-circle:first-child { justify-self: start; }
/* Right column: gear button (anchored to the right). */
.controls > .ctrl-circle:last-child  { justify-self: end; }
/* Center column: the 5 nav icons. */
.ctrl-center {
  display: flex; align-items: center; justify-content: center;
  gap: 18px;
}

/* Small circular icon button used for Flip and Gear. */
.ctrl-circle {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 50%;
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.12s, background 0.12s, border-color 0.12s;
}
.ctrl-circle:hover {
  color: var(--accent);
  background: rgba(var(--accent-rgb), 0.08);
  border-color: rgba(var(--accent-rgb), 0.25);
}
.ctrl-circle svg { display: block; }

/* Square-ish icon button for the 5 nav controls. No background, no border -
   just the icon, with a soft hover halo. */
.ctrl-ico {
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  border-radius: 8px;
  transition: color 0.12s, background 0.12s;
  padding: 0;
}
.ctrl-ico:hover         { color: var(--accent); background: rgba(var(--accent-rgb), 0.08); }
.ctrl-ico:active        { background: rgba(var(--accent-rgb), 0.14); }
.ctrl-ico:disabled      { opacity: 0.3; cursor: default; background: transparent; color: var(--text-dim); }
.ctrl-ico svg           { display: block; }
.ctrl-ico.ctrl-play     { color: var(--text); }
.ctrl-ico.ctrl-play:hover { color: var(--accent); }
.ctrl-ico.ctrl-play.is-playing { color: var(--accent); }

/* Ply label line under the controls, centered and small. */
.ply-line {
  width: var(--board-w, 560px);
  text-align: center;
  padding: 6px 0 0;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
}
.ply-line .ply-label {
  color: var(--text-faint); font-size: 11.5px;
  font-family: "Consolas", monospace;
  letter-spacing: 0.5px;
}
.copy-row { display: flex; gap: 6px; }
.copy-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px;
  font: inherit; font-size: 11px; letter-spacing: 0.6px;
  color: var(--text-faint);
  background: transparent; border: 1px solid var(--bg-3); border-radius: 6px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.copy-btn:hover { color: var(--accent); border-color: var(--accent); }
.copy-btn.copied {
  color: #6ec84e; border-color: #6ec84e;
  background: rgba(110,200,78,0.08);
}
.copy-btn svg { flex: 0 0 auto; }

/* Toast for copy / share feedback. Positioned bottom-center, fades in/out. */
.cm-toast {
  position: fixed; left: 50%; bottom: 30px; transform: translateX(-50%) translateY(10px);
  padding: 10px 18px; border-radius: 10px;
  background: var(--bg-2); color: var(--text); border: 1px solid var(--accent);
  box-shadow: 0 8px 24px rgba(0,0,0,0.45);
  font-size: 13px;
  opacity: 0; pointer-events: none;
  transition: opacity 180ms, transform 180ms;
  z-index: 9000;
}
.cm-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* =====================================================================
 * Book / repertoire panel (right-pane tab on the analyse page).
 * Renders a list of moves the user has played from the current position
 * with W/D/L scoring bars. See refreshBookPanel/renderBookPanel in app.js.
 * ===================================================================== */
.book-panel { padding: 10px 12px; color: var(--text); }
.book-empty { padding: 14px 8px; color: var(--text-dim); font-size: 13px; line-height: 1.5; }
.book-empty-h { font-weight: 600; color: var(--text); margin-bottom: 4px; }
.book-head { margin-bottom: 10px; }
.book-head-h { font-size: 14px; font-weight: 600; }
.book-head-s { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.book-xp-hint {
  font-size: 0.75em;
  color: var(--text-dim);
  cursor: help;
  vertical-align: super;
}
.book-list { display: flex; flex-direction: column; gap: 8px; }
.book-row {
  padding: 8px 10px; border-radius: 8px;
  background: var(--bg-2); border: 1px solid var(--bg-3);
}
.book-row.book-row-mine { border-left: 3px solid var(--accent); }
.book-row.book-row-opp  { border-left: 3px solid var(--text-dim); opacity: 0.92; }
.book-row-h {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 13px;
}
.book-san { font-weight: 700; font-family: "Iosevka", "JetBrains Mono", monospace; }
.book-pov {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--text-dim); padding: 1px 5px; border-radius: 4px;
  background: rgba(255,255,255,0.04);
}
.book-row-mine .book-pov { color: var(--accent); }
.book-games { color: var(--text-dim); margin-left: auto; font-size: 11px; }
.book-score { font-weight: 600; font-size: 12px; min-width: 36px; text-align: right; }
.book-bar {
  display: flex; height: 6px; border-radius: 3px; overflow: hidden;
  margin-top: 6px; background: var(--bg-1);
}
.book-bar-w { background: #4caf50; }
.book-bar-d { background: #9e9e9e; }
.book-bar-l { background: #e53935; }

/* =====================================================================
 * Endgame Trainer page
 * ===================================================================== */
.endgames-view { max-width: 1200px; margin: 0 auto; padding: 32px 28px 80px; }

/* =====================================================================
 * Trainer tab - shared wrapper + sub-mode switcher (v0.140.0)
 * ===================================================================== */
.trainer-view { max-width: 1200px; margin: 0 auto; padding: 32px 28px 80px; }
.trainer-submode-bar { margin-bottom: 24px; }
.trainer-submode-pills {
  display: inline-flex; gap: 4px;
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 12px; padding: 4px;
}
.trainer-submode-pill {
  padding: 7px 20px; border-radius: 9px;
  background: transparent; color: var(--text-dim);
  border: none; font: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; transition: background 0.15s, color 0.15s;
}
.trainer-submode-pill:hover { color: var(--text); background: var(--bg-3); }
.trainer-submode-pill.active {
  background: var(--accent); color: var(--on-accent, #fff);
}
.trainer-mode-panel { /* sub-mode container */ }

/* =====================================================================
 * Openings Trainer - View 1: list grid (v0.140.0)
 * ===================================================================== */
.op-hero { margin-bottom: 32px; }
.op-hero h1 {
  font-family: var(--font-display, var(--serif)); font-weight: 700;
  font-size: 38px; margin: 0 0 6px;
  color: var(--accent); letter-spacing: -0.4px;
}
.op-hero-sub { color: var(--text-dim); max-width: 680px; line-height: 1.55; font-size: 14px; margin: 0; }

/* ===== Courses (Trainer read-only learn mode) ===== */
.courses-grid { display: flex; flex-direction: column; gap: 28px; }
.cs-group-title {
  font-family: var(--font-display, var(--serif)); font-weight: 700;
  font-size: 18px; margin: 0 0 12px; color: var(--text);
  letter-spacing: -0.2px;
}
.cs-group-cards {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
}
.cs-card {
  display: flex; align-items: center; gap: 18px; text-align: left;
  padding: 24px; border-radius: 16px; cursor: pointer; min-height: 116px;
  background: var(--bg-2); border: 1px solid var(--border, rgba(255,255,255,0.08));
  color: var(--text); transition: transform .12s ease, border-color .12s ease, background .12s ease;
}
.cs-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: var(--bg-3);
}
.cs-card-icon {
  flex: 0 0 auto; width: 56px; height: 56px; border-radius: 14px;
  display: grid; place-items: center; font-size: 28px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}
.cs-card-body { flex: 1 1 auto; min-width: 0; }
.cs-card-title { font-size: 17px; font-weight: 650; margin: 0 0 5px; color: var(--text); }
.cs-card-sub { font-size: 13.5px; color: var(--text-dim); margin: 0 0 10px; line-height: 1.45; }
.cs-card-meta { font-size: 11.5px; font-weight: 600; color: var(--accent); text-transform: uppercase; letter-spacing: .4px; }
.cs-card-arrow { flex: 0 0 auto; font-size: 20px; color: var(--text-dim); }

/* Per-course completion bar shown on each list card (v0.195.102). */
.cs-card-progress { display: flex; align-items: center; gap: 9px; margin-top: 12px; }
.cs-card-progress-track {
  flex: 1 1 auto; height: 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--text-dim) 22%, transparent);
  overflow: hidden;
}
.cs-card-progress-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 60%, #6ec84e));
  transition: width .3s ease;
}
.cs-card-progress-label {
  flex: 0 0 auto; font-size: 11px; font-weight: 600; color: var(--text-dim);
  white-space: nowrap;
}
.cs-card.is-complete .cs-card-progress-fill { background: var(--cat-best, #6ec84e); }
.cs-card.is-complete .cs-card-progress-label { color: var(--cat-best, #6ec84e); }

/* Opening-card completion bar + check mark (v0.195.115). Mirrors the courses
   completion treatment so openings show the same "X% complete / Completed"
   progress users already know from courses. */
.op-card-progress { display: flex; align-items: center; gap: 9px; margin-top: 10px; }
.op-card-progress-track {
  flex: 1 1 auto; height: 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--text-dim) 22%, transparent);
  overflow: hidden;
}
.op-card-progress-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 60%, #6ec84e));
  transition: width .3s ease;
}
.op-card-progress-label {
  flex: 0 0 auto; font-size: 11px; font-weight: 600; color: var(--text-dim);
  white-space: nowrap;
}
.op-card.is-complete .op-card-progress-fill { background: var(--cat-best, #6ec84e); }
.op-card.is-complete .op-card-progress-label { color: var(--cat-best, #6ec84e); }
.op-card-complete-mark {
  display: inline-flex; align-items: center; color: var(--cat-best, #6ec84e);
  font-size: 16px; line-height: 1;
}
@media (prefers-reduced-motion: reduce) {
  .op-card-progress-fill { transition: none; }
}

/* Live course-completion bar in the lesson reader (v0.195.102). */
.cs-course-progress { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.cs-course-progress-track {
  flex: 1 1 auto; height: 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--text-dim) 20%, transparent);
  overflow: hidden;
}
.cs-course-progress-fill {
  height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 55%, #6ec84e));
  transition: width .35s cubic-bezier(.2,.7,.2,1);
}
.cs-course-progress-pct {
  flex: 0 0 auto; font-size: 12px; font-weight: 650; color: var(--text-dim);
  min-width: 92px; text-align: right;
}

/* Atomic entrance for each lesson/quiz step. Played only when the step
   actually changes (see csPlayStepAnim), so the new content fades in from
   opacity 0 and the previous content is never visible at the same time -
   this is what removes the brief text-overlap flicker on lesson switch. */
@keyframes csStepIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.cs-step-anim { animation: csStepIn 170ms cubic-bezier(.2,.7,.2,1) both; will-change: opacity, transform; }
@media (prefers-reduced-motion: reduce) {
  .cs-step-anim { animation: none; }
  .cs-card-progress-fill, .cs-course-progress-fill { transition: none; }
}

.cs-lesson-header { margin-bottom: 18px; }
.cs-lesson-eyebrow {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; color: var(--accent);
  text-transform: uppercase; letter-spacing: .5px; margin-bottom: 6px;
}
.cs-lesson-h1 {
  font-family: var(--font-display, var(--serif)); font-weight: 700;
  font-size: 28px; margin: 0; color: var(--text); letter-spacing: -0.3px;
}
.cs-controls { align-items: center; justify-content: center; }
.cs-progress {
  font-size: 13px; font-weight: 600; color: var(--text-dim);
  min-width: 110px; text-align: center;
}
/* Wide, labelled lesson navigation under the lesson text (replaces the small
   caret buttons that used to sit beside the board). */
.cs-lesson-nav {
  display: flex; align-items: stretch; gap: 12px;
  margin-top: 18px;
}
.cs-lesson-nav .cs-progress {
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
}
.cs-nav-btn {
  flex: 1 1 0; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 13px 18px;
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 10px;
  font-size: 14px; font-weight: 600; cursor: pointer;
  transition: background 0.15s, color 0.15s, transform 120ms, opacity 120ms;
}
.cs-nav-btn .ph { font-size: 17px; }
.cs-nav-next { background: var(--accent); color: #fff; border-color: var(--accent); }
.cs-nav-btn:hover:not(:disabled) { transform: translateY(-1px); }
.cs-nav-prev:hover:not(:disabled) { background: var(--bg-3); color: var(--text); }
.cs-nav-next:hover:not(:disabled) { filter: brightness(1.08); }
.cs-nav-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cs-nav-btn:active:not(:disabled) { transform: scale(0.98); opacity: 0.9; transition: transform 60ms, opacity 60ms; }
.cs-nav-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.cs-lesson-text { font-size: 14.5px; line-height: 1.6; color: var(--text); margin-bottom: 18px; }
.cs-block { margin-bottom: 14px; }
.cs-block-hd {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .5px; margin-bottom: 7px;
}
.cs-block-list { margin: 0; padding-left: 18px; }
.cs-block-list li { font-size: 13.5px; line-height: 1.5; color: var(--text); margin-bottom: 4px; }
.cs-goals .cs-block-hd { color: var(--cat-best, #6ec84e); }
.cs-watch .cs-block-hd { color: var(--accent); }
.cs-avoid .cs-block-hd { color: var(--cat-blunder, #d04040); }

/* ===== Course quiz phases (v0.195.98: judge + find) ===== */
.cs-quiz-cta {
  display: flex; align-items: center; gap: 10px;
  margin-top: 16px; padding: 12px 14px; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  font-size: 13.5px; color: var(--text); line-height: 1.45;
}
.cs-quiz-cta iconify-icon { font-size: 22px; color: var(--accent); flex: 0 0 auto; }
.cs-quiz-tag {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .5px; color: var(--accent); margin-bottom: 10px;
}
.cs-quiz-q { font-size: 15px; font-weight: 600; line-height: 1.5; color: var(--text); margin: 0 0 8px; }
.cs-quiz-blurb { font-size: 13.5px; line-height: 1.5; color: var(--text-dim); margin: 0 0 16px; }
.cs-quiz-actions { display: flex; gap: 10px; margin-top: 8px; }
.cs-quiz-btn {
  flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center;
  gap: 7px; padding: 12px 10px; border-radius: 10px; cursor: pointer;
  font-size: 14px; font-weight: 650; color: var(--text);
  background: var(--bg-1, #1d2330); border: 1.5px solid var(--border, #333a4a);
  transition: transform .12s ease, border-color .12s ease, background .12s ease;
}
.cs-quiz-btn iconify-icon { font-size: 18px; }
.cs-quiz-btn:hover { transform: translateY(-1px); }
.cs-quiz-good:hover { border-color: var(--cat-best, #6ec84e); background: color-mix(in srgb, var(--cat-best, #6ec84e) 14%, transparent); }
.cs-quiz-bad:hover  { border-color: var(--cat-blunder, #d04040); background: color-mix(in srgb, var(--cat-blunder, #d04040) 14%, transparent); }
.cs-quiz-result {
  display: flex; align-items: center; gap: 8px; margin: 4px 0 12px;
  padding: 11px 13px; border-radius: 10px; font-size: 14.5px; font-weight: 650;
}
.cs-quiz-result iconify-icon { font-size: 20px; flex: 0 0 auto; }
.cs-quiz-result.is-correct { background: color-mix(in srgb, var(--cat-best, #6ec84e) 16%, transparent); color: var(--cat-best, #6ec84e); }
.cs-quiz-result.is-wrong   { background: color-mix(in srgb, var(--cat-blunder, #d04040) 16%, transparent); color: var(--cat-blunder, #d04040); }
.cs-quiz-expl { font-size: 14px; line-height: 1.6; color: var(--text); margin: 0 0 16px; }
.cs-quiz-retry {
  display: flex; align-items: center; gap: 7px; margin: 10px 0;
  font-size: 13.5px; font-weight: 600; color: var(--cat-blunder, #d04040);
}
.cs-quiz-next-btn, .cs-quiz-ghost-btn, .cs-quiz-reveal {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 11px 18px; border-radius: 10px; cursor: pointer;
  font-size: 14px; font-weight: 650; border: none;
}
.cs-quiz-next-btn { background: var(--accent); color: #fff; }
.cs-quiz-next-btn:hover { filter: brightness(1.08); }
.cs-quiz-reveal {
  margin-top: 6px; background: transparent; color: var(--text-dim);
  border: 1.5px solid var(--border, #333a4a);
}
.cs-quiz-reveal:hover { color: var(--text); border-color: var(--accent); }
.cs-quiz-ghost-btn {
  background: transparent; color: var(--text); border: 1.5px solid var(--border, #333a4a);
}
.cs-quiz-ghost-btn:hover { border-color: var(--accent); }
.cs-quiz-next-btn iconify-icon, .cs-quiz-reveal iconify-icon, .cs-quiz-ghost-btn iconify-icon { font-size: 18px; }
.cs-done { text-align: center; padding: 18px 6px; }
.cs-done-icon iconify-icon { font-size: 56px; color: var(--cat-best, #6ec84e); }
.cs-done-h { font-size: 22px; font-weight: 700; margin: 10px 0 6px; color: var(--text); }
.cs-done-score { font-size: 15px; color: var(--text); margin: 0 0 12px; }
.cs-done-breakdown {
  display: flex; gap: 16px; justify-content: center; margin-bottom: 20px;
  font-size: 13.5px; color: var(--text-dim);
}
.cs-done-breakdown span { display: inline-flex; align-items: center; gap: 6px; }
.cs-done-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

.op-list-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.op-empty { padding: 60px 0; text-align: center; color: var(--text-dim); }

/* Opening list row (chess.com-style large card) */
.op-card {
  display: flex; flex-direction: row; align-items: stretch; gap: 0; padding: 0;
  text-align: left; width: 100%; min-height: 130px;
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 12px;
  cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
  overflow: hidden;
}
.op-card:hover {
  border-color: var(--accent); background: var(--bg-3);
  box-shadow: 0 4px 18px rgba(0,0,0,0.28);
}

/* Left: square board thumbnail */
.op-card-thumb {
  width: 130px; min-width: 130px;
  position: relative;
  background: var(--bg-1);
  border-right: 1px solid var(--bg-3);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.op-card-thumb-board { width: 100%; height: 100%; display: block; }
.op-card-thumb-overlay {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.38); font-size: 28px; color: rgba(255,255,255,0.9);
  opacity: 0; transition: opacity 0.15s; pointer-events: none;
}
.op-card:hover .op-card-thumb-overlay { opacity: 1; }

/* Right: body */
.op-card-body {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; justify-content: center; gap: 7px;
  padding: 16px 22px;
}
.op-card-title-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.op-card-name {
  font-family: var(--font-display, var(--serif)); font-weight: 700;
  font-size: 22px;
  color: var(--accent); line-height: 1.2; letter-spacing: -0.2px;
}
.op-card-summary {
  color: var(--text-dim); font-size: 14px; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.op-card-meta {
  display: flex; align-items: center; gap: 14px;
  font-size: 12px; color: var(--text-faint);
}
.op-card-meta-item { display: flex; align-items: center; gap: 4px; }

.op-color-badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.4px;
}
.op-badge-w { background: rgba(255,255,255,0.15); color: var(--text); }
.op-badge-b { background: rgba(0,0,0,0.25); color: var(--text-dim); border: 1px solid var(--bg-3); }
.op-badge-intro {
  background: var(--accent-soft, rgba(182,217,154,0.18));
  color: var(--accent);
  border: 1px solid var(--accent);
}
.op-badge-intro-seen {
  background: rgba(255,255,255,0.06);
  color: var(--text-dim);
  border: 1px solid var(--bg-3);
}
/* Difficulty badge - small informational pill on each opening card and detail header */
.op-diff-badge {
  display: inline-block; padding: 2px 7px; border-radius: 999px;
  font-size: 10px; font-weight: 600; letter-spacing: 0.3px;
  white-space: nowrap; flex-shrink: 0;
}
.op-diff-badge[data-diff="beginner"]     { background: rgba(92,196,107,0.18); color: var(--diff-beginner);     border: 1px solid rgba(92,196,107,0.40); }
.op-diff-badge[data-diff="intermediate"] { background: rgba(232,197,71,0.18); color: var(--diff-intermediate); border: 1px solid rgba(232,197,71,0.40); }
.op-diff-badge[data-diff="advanced"]     { background: rgba(232,90,79,0.18);  color: var(--diff-advanced);     border: 1px solid rgba(232,90,79,0.40); }

/* Difficulty filter chip row - appears above the catalog grid, list view only */
.op-diff-filter-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 0 0 12px;
}
.op-diff-chip {
  display: inline-flex; align-items: center;
  padding: 5px 14px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--bg-3); color: var(--text-dim);
  font: inherit; font-size: 12px; cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  white-space: nowrap;
}
.op-diff-chip:hover { border-color: var(--accent); color: var(--text); }
.op-diff-chip[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

.op-card-intro {
  border: 1px solid var(--accent);
  background: linear-gradient(135deg, rgba(182,217,154,0.06), rgba(182,217,154,0.02));
}
/* Acknowledged state: same layout as a regular card (no accent border,
   no tinted background). The "?" icon thumbnail stays so the guide is
   still visually distinct from named openings. */
.op-card-intro-seen { }
.op-intro-ack {
  display: inline-block;
  margin-top: 14px;
  padding: 9px 22px;
  background: var(--accent);
  color: var(--bg-1, #1b1612);
  border: none; border-radius: 8px;
  font-weight: 700; font-size: 14px; cursor: pointer;
  transition: filter .15s ease, transform .05s ease;
}
.op-intro-ack:hover  { filter: brightness(1.08); }
.op-intro-ack:active { transform: translateY(1px); }
.op-intro-ack.ghost {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--bg-3);
  font-weight: 600;
}
.op-intro-ack.ghost:hover { color: var(--text); border-color: var(--accent); }
.op-card-thumb-intro {
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2);
  color: var(--accent);
}
.op-intro-detail { padding: 8px 0 32px; }
.op-intro-card {
  max-width: 760px; margin: 0 auto;
  background: var(--bg-1, var(--bg-2));
  border: 1px solid var(--bg-3);
  border-radius: 14px;
  padding: 28px 32px;
  line-height: 1.65;
}
.op-intro-h1 {
  margin: 0 0 12px; font-size: 28px; font-weight: 700;
  color: var(--text);
}
.op-intro-lead {
  font-size: 16px; color: var(--text);
  margin: 0 0 18px;
}
.op-intro-h2 {
  margin: 22px 0 8px; font-size: 18px; font-weight: 700;
  color: var(--accent);
  border-bottom: 1px solid var(--bg-3);
  padding-bottom: 4px;
}
.op-intro-card p { margin: 0 0 12px; color: var(--text); }
.op-intro-list { margin: 8px 0 14px; padding-left: 22px; color: var(--text); }
.op-intro-list li { margin: 6px 0; }
.op-intro-cta {
  margin-top: 22px; padding: 12px 16px;
  background: var(--bg-2);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
}
@media (max-width: 640px) {
  .op-intro-card { padding: 18px 16px; }
  .op-intro-h1   { font-size: 22px; }
}
.op-theme-chip {
  padding: 1px 7px; border-radius: 999px; font-size: 10.5px; font-weight: 600;
  background: var(--accent-soft, rgba(182,217,154,0.15));
  color: var(--accent);
}

/* Mobile: stack thumbnail above body at ≤640px */
@media (max-width: 640px) {
  .op-card { flex-direction: column; min-height: auto; }
  .op-card-thumb { width: 100%; min-width: 0; height: 140px; border-right: none; border-bottom: 1px solid var(--bg-3); }
}

/* =====================================================================
 * Openings Trainer - View 2: detail (board + side panel) (v0.140.0)
 * ===================================================================== */
.op-nav-row { margin-bottom: 14px; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.op-back-btn {
  background: transparent; color: var(--text-dim);
  border: 1px solid var(--bg-3); border-radius: 8px;
  padding: 6px 14px; font: inherit; font-size: 13px;
  cursor: pointer; transition: color 0.15s, border-color 0.15s;
}
.op-back-btn:hover { color: var(--text); border-color: var(--accent); }
.op-detail-header { margin-bottom: 18px; }
.op-detail-title-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-bottom: 6px;
}
.op-detail-h1 {
  font-family: var(--font-display, var(--serif)); font-weight: 700;
  font-size: 32px; margin: 0;
  color: var(--accent); letter-spacing: -0.3px;
}
.op-detail-summary { color: var(--text-dim); font-size: 14px; line-height: 1.5; margin: 4px 0 8px; }
.op-detail-themes { display: flex; gap: 6px; flex-wrap: wrap; }

/* Detail layout: board left, side panel right */
.op-detail-layout {
  display: flex; gap: 28px; align-items: flex-start;
}
.op-board-col { flex: 0 0 auto; display: flex; flex-direction: column; gap: 10px; }
.op-board {
  width: var(--board-w, 480px); height: var(--board-w, 480px);
  border-radius: 5px;
  box-shadow: var(--board-glow), 0 0 0 1px var(--board-ring);
}
.op-controls {
  display: flex; align-items: center; gap: 6px;
  width: var(--board-w, 480px);
}
.op-ctrl-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: var(--bg-2); color: var(--text-dim);
  border: 1px solid var(--bg-3); border-radius: 8px;
  cursor: pointer; transition: background 0.15s, color 0.15s, transform 120ms, opacity 120ms;
}
.op-ctrl-btn:hover:not(:disabled) { background: var(--bg-3); color: var(--text); transform: translateY(-1px); }
.op-ctrl-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.op-ctrl-btn:active:not(:disabled) { transform: scale(0.95); opacity: 0.85; transition: transform 60ms, opacity 60ms; }
.op-ctrl-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.op-speed-label { font-size: 12px; color: var(--text-faint); margin-left: 6px; }
.op-speed-select {
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 7px;
  padding: 4px 8px; font: inherit; font-size: 12px; cursor: pointer;
}

/* Side panel */
.op-side-panel {
  flex: 1 1 280px; min-width: 0;
  display: flex; flex-direction: column; gap: 16px;
  overflow-y: auto;
}
/* Move-list removed in v0.144.2 - Mentor panel is the primary coaching surface */

/* Variations */
.op-section-h {
  font-size: 13px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--text-faint);
  margin: 0 0 8px; padding-bottom: 4px;
  border-bottom: 1px solid var(--bg-3);
}
.op-var-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.op-var-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 12px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--bg-3); color: var(--text-dim);
  font: inherit; font-size: 12px; cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.op-var-chip:hover { border-color: var(--accent); color: var(--text); }
.op-var-chip.active { background: var(--accent-soft, rgba(182,217,154,0.15)); border-color: var(--accent); color: var(--accent); }
.op-var-main-chip { color: var(--text-faint); font-style: italic; }
.op-var-desc { font-size: 12px; color: var(--text-dim); line-height: 1.45; }

/* Model game */
.op-model-coming-soon {
  font-size: 12.5px; color: var(--text-faint); font-style: italic;
  padding: 10px 0;
}
.op-model-details { padding: 0; }
.op-model-details summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center;
  padding: 10px 14px;
  font-size: 13px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--accent);
  background: var(--bg-2); border-radius: 8px;
  border: 1px solid var(--bg-3);
  transition: background 0.15s, border-color 0.15s;
  user-select: none;
}
.op-model-details summary::-webkit-details-marker { display: none; }
.op-model-details summary:hover { background: var(--bg-3); border-color: var(--accent); }

/* Model game open animation (grid-template-rows trick) */
.model-game-anim-wrap {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 280ms ease;
}
.op-model-details[open] .model-game-anim-wrap { grid-template-rows: 1fr; }
.model-game-anim-inner {
  overflow: hidden; opacity: 0;
  transition: opacity 200ms ease 80ms;
  padding-top: 0;
}
.op-model-details[open] .model-game-anim-inner { opacity: 1; }

.op-mg-board-wrap { padding-top: 10px; }
.op-model-meta {
  font-size: 12px; color: var(--text-dim); margin: 8px 0 10px;
}
.op-model-stop { font-style: italic; }
.op-model-moves { font-size: 13px; line-height: 1.8; word-spacing: 3px; }
.op-model-move { display: inline; }
.op-ann-mark {
  color: var(--accent); font-weight: 700; cursor: help; font-size: 10px;
}
.op-annotations { margin-top: 10px; display: flex; flex-direction: column; gap: 5px; }
.op-ann-row { font-size: 12px; color: var(--text-dim); line-height: 1.4; }
.op-ann-ply {
  font-size: 10px; font-weight: 700; color: var(--text-faint);
  margin-right: 5px;
}

/* Practice CTA */
.op-practice-cta-row { margin-top: 18px; }
.op-practice-cta-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 24px; border-radius: 10px;
  background: var(--accent); color: var(--on-accent, #fff);
  border: none; font: inherit; font-size: 15px; font-weight: 700;
  cursor: pointer; transition: filter 0.15s, transform 0.1s;
  box-shadow: 0 4px 14px rgba(0,0,0,0.3);
}
.op-practice-cta-btn:hover { filter: brightness(1.08); transform: translateY(-1px); }

/* =====================================================================
 * Openings Trainer - View 3: practice (v0.140.0)
 * ===================================================================== */
.op-practice-h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  letter-spacing: -0.01em;
  margin: 0 0 14px; color: var(--text);
}
.op-practice-h2 strong { color: var(--accent); }
.op-color-picker {
  display: flex; align-items: center; gap: 8px;
  width: var(--board-w, 480px); margin-bottom: 6px;
}
.op-cp-label { font-size: 13px; font-weight: 600; color: var(--text-dim); }
.op-cp-btn {
  padding: 5px 14px; border-radius: 999px;
  background: var(--bg-2); color: var(--text-dim);
  border: 1px solid var(--bg-3); font: inherit; font-size: 13px;
  cursor: pointer; transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.op-cp-btn:hover { border-color: var(--accent); color: var(--text); }
.op-cp-btn.active {
  background: var(--accent); color: var(--on-accent, #fff); border-color: var(--accent);
}
/* Mentor box - enlarged in v0.144.2 as primary teaching surface */
.op-mentor-box {
  background: var(--bg-2); border: 1px solid var(--bg-3); border-radius: 12px;
  border-left: 4px solid var(--accent);
  padding: 20px 22px; min-height: 100px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.18);
}
.op-mentor-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 10px;
  font-size: 13px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--accent);
}
.op-mentor-title { color: var(--accent); }
.op-mentor-text { font-size: 17px; line-height: 1.6; color: var(--text); }
.op-mentor-text.op-mentor-hint { color: var(--cat-inaccuracy, #f7c245); }
.op-mentor-sidelines {
  margin-top: 14px;
  display: grid;
  gap: 10px;
}
.op-mentor-sideline-card {
  padding: 12px 14px;
  border: 1px solid var(--bg-3);
  border-left: 4px solid var(--accent);
  border-radius: 10px;
  background: var(--bg-1);
  color: var(--text);
}
.op-mentor-sideline-card summary {
  cursor: pointer;
  color: var(--accent);
  font-weight: 700;
}
.op-mentor-sideline-card p {
  margin: 10px 0 8px;
  line-height: 1.55;
}
.op-mentor-sideline-preview {
  color: var(--text-dim);
  font-size: 13px;
}
.op-practice-done-btns { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.op-practice-retry-btn {
  padding: 9px 20px; border-radius: 9px;
  background: var(--accent); color: var(--on-accent, #fff);
  border: none; font: inherit; font-size: 13px; font-weight: 700;
  cursor: pointer; transition: filter 0.15s;
}
.op-practice-retry-btn:hover { filter: brightness(1.1); }

/* Counter-mode toggle segmented control (v0.144.1) */
.op-counter-toggle {
  display: flex; align-items: center; gap: 0;
  width: var(--board-w, 480px); margin-bottom: 4px;
  border: 1px solid var(--bg-3); border-radius: 999px; overflow: hidden;
  background: var(--bg-2);
}
.op-counter-btn {
  flex: 1; padding: 6px 14px;
  background: transparent; color: var(--text-dim);
  border: none; font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}
.op-counter-btn:hover { color: var(--text); background: var(--bg-3); }
.op-counter-btn.active {
  background: var(--accent); color: var(--on-accent, #fff); font-weight: 700;
}
.op-counter-hint {
  font-size: 12px; color: var(--text-dim); font-style: italic;
  width: var(--board-w, 480px); margin-bottom: 4px; padding: 0 2px;
  line-height: 1.4;
}
@media (max-width: 860px) {
  .op-counter-toggle { width: 100% !important; box-sizing: border-box; }
  .op-counter-hint  { width: 100% !important; box-sizing: border-box; }
}

/* Fix 2 (Tony-16): random line button row */
.op-practice-extra-btns {
  display: flex; gap: 8px; margin-bottom: 4px;
}
/* 2b: Random button removed; kept for any still-cached HTML referencing the class */
.op-practice-random-btn { display: none; }
/* Fix 3 (Tony-18): variation picker dropdown - styled to match toolbar buttons */
.op-practice-var-select {
  padding: 5px 10px; border-radius: 999px;
  background: var(--bg-2); color: var(--text-dim);
  border: 1px solid var(--bg-3); font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s, transform 120ms, opacity 120ms;
  white-space: nowrap; max-width: 180px;
  appearance: auto;
}
.op-practice-var-select:hover { background: var(--bg-3); color: var(--text); border-color: var(--accent); }
.op-practice-var-select:focus { outline: none; border-color: var(--accent); }
.op-practice-var-select:active { transform: scale(0.97); opacity: 0.9; transition: transform 60ms, opacity 60ms; }
/* Fix 2 (Tony-18): from-square tint shown when user plays wrong move */
.op-hint-from-sq { fill: rgba(255, 235, 130, 0.38); pointer-events: none; }
@media (max-width: 860px) {
  .op-practice-var-select { max-width: 140px; font-size: 12px; }
}
/* variation badge inline in the practice header */
.op-random-badge {
  font-size: 13px; font-weight: 500; color: var(--text-dim);
  background: var(--bg-3); border-radius: 6px; padding: 1px 7px; margin-left: 8px;
  vertical-align: middle;
}
/* Fix 5 (Tony-17): prev/next history navigation row */
.op-practice-nav-row {
  display: flex; align-items: center; gap: 6px; margin-top: 6px;
}
.op-practice-review-badge {
  font-size: 11px; font-weight: 600; letter-spacing: 0.3px;
  color: var(--on-accent, #fff); background: var(--accent);
  border-radius: 999px; padding: 2px 9px;
  flex: 1; text-align: center;
}

/* Practice board: pointer cursor + click-capture overlay */
#openingsPracticeBoard { cursor: default; }
.board-click-capture { cursor: pointer; }

/* Model-game board (smaller, sits inside the detail side panel) */
.op-mg-board {
  width: 260px !important; height: 260px !important;
  flex-shrink: 0;
}
.op-mg-board-wrap {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 6px; margin: 10px 0 6px;
}
.op-mg-controls { width: 260px !important; }
.op-mg-annotation {
  font-size: 12px; color: var(--text-dim); font-style: italic;
  min-height: 1.3em; line-height: 1.4; max-width: 260px;
}
/* Note: .op-mg-movelist / .op-mg-move rules removed in v0.141.3 - move list deleted from Model Game card */

/* =====================================================================
 * Openings + Endgames Trainer - mobile stacking (v0.141.0)
 * At ≤860px: board column stacks above side panel; board fills width.
 * At ≤620px: puzzle banners stack vertically.
 * ===================================================================== */
@media (max-width: 860px) {
  .op-detail-layout { flex-direction: column; gap: 20px; }
  .op-board-col { width: 100%; }
  .op-board { width: 100% !important; height: auto !important; }
  .op-controls { width: 100% !important; box-sizing: border-box; }
  .op-color-picker { width: 100% !important; box-sizing: border-box; }
  .op-side-panel { max-height: none; width: 100%; }
  .op-mg-board { width: 100% !important; height: auto !important; }
  .op-mg-controls, .op-mg-annotation { width: 100% !important; max-width: 100%; }
}

.endgames-hero { margin-bottom: 28px; }
.endgames-hero h1 {
  font-family: var(--font-display, var(--serif)); font-weight: 700;
  font-size: 38px; margin: 0 0 6px;
  color: var(--accent); letter-spacing: -0.4px;
}
.endgames-sub { color: var(--text-dim); max-width: 720px; line-height: 1.55; font-size: 14px; }

/* Compact variant (v0.168.10): single-row hero - H1 + 1-line subtitle
   + inline difficulty picker - to reduce vertical clutter at the top
   of the Endgame Trainer. */
.endgames-hero-compact {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 18px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--bg-3);
}
.endgames-hero-compact h1 { font-size: 26px; margin: 0; flex: 0 0 auto; }
.endgames-hero-compact .endgames-sub {
  flex: 1 1 240px; max-width: none; font-size: 13px; line-height: 1.4; margin: 0;
}
.endgames-diff-picker-compact {
  margin: 0; padding: 5px 10px; flex: 0 0 auto;
}
.endgames-diff-picker-compact label { font-size: 12px; }
.endgames-diff-picker-compact .trainer-diff-select {
  padding: 4px 8px; font-size: 12px;
}

/* v0.123: bot-difficulty picker on the Endgame Trainer page. Sits
   under the description, controls which Elo the trainer starts at. */
.endgames-diff-picker {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 16px;
  padding: 10px 14px;
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 10px;
  max-width: 720px;
}
.endgames-diff-picker label {
  font-size: 13px; font-weight: 600; color: var(--text);
}
.trainer-diff-select {
  background: var(--bg-1); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 8px;
  padding: 6px 10px; font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
}
.trainer-diff-select:focus,
.settings-select:focus,
.popover-select:focus,
.op-speed-select:focus,
.pgn-import-color select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.22);
}
.trainer-diff-select option,
.settings-select option,
.popover-select option,
.op-speed-select option {
  background: var(--bg-1);
  color: var(--text);
}
.endgames-diff-hint {
  font-size: 12px; color: var(--text-faint); font-style: italic;
}
.endgames-grid { display: flex; flex-direction: column; gap: 18px; }
.trainer-section-h {
  font-family: var(--serif); font-size: 17px; font-weight: 700;
  color: var(--text-dim); margin: 0 0 10px; text-transform: uppercase;
  letter-spacing: 0.5px;
  border-bottom: 1px solid var(--bg-3); padding-bottom: 6px;
}
/* v0.168.14: trainer cards switched back to a compact multi-column
   grid (2-3 cards per row depending on viewport) per Lucas' request.
   Still uses the .op-card horizontal layout (board thumb left, body
   right) but with shrunk thumb + tighter typography. */
.trainer-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 10px;
}
.trainer-card-big { min-height: 96px; }
.trainer-card-big .op-card-thumb { width: 96px; min-width: 96px; }
.trainer-card-big .op-card-body {
  padding: 10px 14px; gap: 5px; justify-content: center;
}
.trainer-card-big .op-card-name { font-size: 19px; }
.trainer-card-big .op-card-summary { font-size: 12px; -webkit-line-clamp: 2; }
.trainer-card-big .op-card-title-row { gap: 6px; }
.trainer-card-big .op-color-badge { font-size: 10px; padding: 1px 6px; }
.trainer-card-big .op-card-meta { font-size: 11px; gap: 8px; }
.trainer-card-big .trainer-solved-badge { font-size: 15px; }
@media (max-width: 720px) {
  .trainer-cards { grid-template-columns: 1fr; }
}
/* Visual recolour for the badges that ride inside .op-card-title-row
   for trainer cards. Goal / difficulty / color-played reuse the
   .op-color-badge pill shape from openings. */
.trainer-card-big .op-color-badge.trainer-goal-win {
  background: rgba(110, 200, 78, 0.20); color: #8fdc6f;
}
.trainer-card-big .op-color-badge.trainer-goal-draw {
  background: rgba(180, 180, 180, 0.20); color: var(--text-dim);
}
.trainer-card-big .op-color-badge.trainer-diff-easy {
  background: rgba(110, 200, 78, 0.14); color: #8fdc6f;
}
.trainer-card-big .op-color-badge.trainer-diff-medium {
  background: rgba(247, 194, 69, 0.18); color: #f7c245;
}
.trainer-card-big .op-color-badge.trainer-diff-hard {
  background: rgba(250, 65, 45, 0.18); color: #ff7769;
}
.trainer-card-big .op-color-badge.trainer-card-color {
  background: var(--accent-soft); color: var(--accent);
  font-size: 14px; padding: 1px 8px;
}
.trainer-card-big.solved {
  border-color: #6ec84e;
  background: linear-gradient(135deg, rgba(110,200,78,0.06), var(--bg-2));
}
.trainer-card-big .trainer-solved-badge {
  color: #6ec84e; font-weight: 700; font-size: 18px; margin-left: auto;
}
.trainer-card-big .trainer-card-link {
  color: var(--accent); cursor: pointer;
  border-bottom: 1px dashed transparent;
}
.trainer-card-big .trainer-card-link:hover { border-bottom-color: var(--accent); }
.trainer-card:hover { border-color: var(--accent); transform: translateY(-1px); }
.trainer-card.solved { border-color: #6ec84e; background: linear-gradient(135deg, rgba(110,200,78,0.08), var(--bg-2)); }
.trainer-card-h { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.trainer-card-title { font-weight: 700; font-size: 13.5px; line-height: 1.3; }
.trainer-solved-badge { color: #6ec84e; font-weight: 700; font-size: 15px; }
.trainer-card-tags { display: flex; gap: 4px; flex-wrap: wrap; font-size: 10px; align-items: center; }
.trainer-card-tags > span {
  padding: 1px 6px; border-radius: 999px; background: var(--bg-3);
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px;
}
.trainer-goal-win { background: rgba(110, 200, 78, 0.20) !important; color: #8fdc6f; }
.trainer-goal-draw { background: rgba(180, 180, 180, 0.20) !important; color: var(--text-dim); }
.trainer-diff-easy { background: rgba(110, 200, 78, 0.14) !important; color: #8fdc6f; }
.trainer-diff-medium { background: rgba(247, 194, 69, 0.18) !important; color: #f7c245; }
.trainer-diff-hard { background: rgba(250, 65, 45, 0.18) !important; color: #ff7769; }
.trainer-card-color { background: var(--accent-soft) !important; color: var(--accent); }
.trainer-card-desc { color: var(--text-dim); font-size: 12.5px; line-height: 1.45; }
.trainer-card-link {
  display: inline-block;
  margin-top: 8px;
  font-size: 12px;
  color: var(--accent);
  cursor: pointer;
  border-bottom: 1px dashed transparent;
}
.trainer-card-link:hover { border-bottom-color: var(--accent); }
.trainer-empty { padding: 60px 0; text-align: center; color: var(--text-dim); }

/* Endgame Trainer - self-contained play view (v0.143.1) */
.eg-play-header { margin-bottom: 8px; }
.eg-play-goal-box {
  background: var(--bg-2);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  padding: 10px 14px;
  margin-bottom: 12px;
  font-size: 13px;
  line-height: 1.55;
}
.eg-play-goal-box strong { display: block; font-size: 15px; margin-bottom: 4px; }
.eg-play-status {
  font-size: 13.5px;
  color: var(--text-dim);
  margin-bottom: 10px;
  min-height: 1.4em;
}
.eg-play-hist {
  font-size: 13px;
  color: var(--text-dim);
  max-height: 200px;
  overflow-y: auto;
  margin-bottom: 12px;
}
.eg-move-list {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 6px;
  align-items: baseline;
}
.eg-move-num { color: var(--text-faint); font-size: 12px; }
.eg-move-san { font-family: monospace; font-size: 13px; }
.eg-play-result {
  font-size: 14px;
  font-weight: 600;
  padding: 10px 12px;
  border-radius: 8px;
  margin-bottom: 10px;
  line-height: 1.45;
}
.eg-play-result.win  { background: rgba(110,200,78,0.15);  color: #6ec84e; }
.eg-play-result.draw { background: rgba(200,180,80,0.14);  color: var(--text); }
.eg-play-result.loss { background: rgba(220,60,60,0.12);   color: #e05555; }
.eg-play-btns { display: flex; gap: 8px; }
.eg-resign-btn {
  padding: 6px 14px;
  background: var(--bg-3);
  border: 1px solid var(--bg-3);
  color: var(--text-dim);
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  transition: border-color 120ms, color 120ms;
}
.eg-resign-btn:hover { border-color: var(--accent); color: var(--accent); }

/* Floating board-options popover (anchored under the gear button). */
.popover {
  position: fixed;
  width: 220px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 12px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.55);
  padding: 10px 12px;
  z-index: 900;
  display: flex; flex-direction: column; gap: 8px;
}
.popover[hidden] { display: none; }
.popover-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  font-size: 13px; color: var(--text-dim);
}
.popover-label { font-weight: 600; }
.popover-select {
  background: var(--bg-1); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 6px;
  padding: 4px 8px; font-size: 12.5px;
  cursor: pointer;
}
.popover-range {
  width: 130px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* Compact iOS-style toggle for the sound option. */
.toggle { position: relative; display: inline-block; width: 36px; height: 20px; }
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
  position: absolute; inset: 0;
  background: var(--bg-3); border-radius: 999px;
  transition: background 0.15s;
  cursor: pointer;
}
.toggle-slider::before {
  content: ""; position: absolute;
  height: 14px; width: 14px; left: 3px; top: 3px;
  background: #ecd9b9; border-radius: 50%;
  transition: transform 0.15s;
}
.toggle input:checked + .toggle-slider             { background: rgba(149,188,106,0.55); }
.toggle input:checked + .toggle-slider::before     { transform: translateX(16px); }

/* (eval-chart-wrap was removed - the mini eval chart now lives in .side-eval-mini) */

/* ===== right pane tabs (v0.176.4: unified into one continuous panel) =====
   Both .tabs and .tab-content share a background so there's no
   card-edge or colour seam between the tab row and the body. The
   active tab is indicated only by a brighter text colour and a thin
   accent underline.
   v0.176.8: the combined surface is inset from the rightpane's
   left/right edges and rounded on both ends so it reads as a single
   "pill" card sitting below the Mentor pill. .tabs rounds the top,
   .tab-content rounds the bottom; they meet seamlessly because both
   use the same background.
   v0.176.9: pill bg switched from --bg-1 (rightpane tone) to --bg-0
   (the deeper page background) so the pill reads as a recessed
   surface against the rightpane, with the rounded edges giving the
   inset shape definition. */
.rightpane { display: flex; flex-direction: column; }
.tabs {
  display: flex; background: var(--bg-2);
  padding: 0; gap: 0;
  margin: 0 6px 0 0;
  border-radius: 14px 14px 0 0;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}
.tab {
  flex: 1; background: transparent; color: var(--text-dim); border: none;
  padding: 14px 0; font-size: 13px; cursor: pointer; font-weight: 600;
  border-radius: 0;
  transition: color 0.12s;
  letter-spacing: 0.4px;
  position: relative;
}
.tab.active {
  color: var(--text);
  background: transparent;
  box-shadow: none;
}
.tab.active::after {
  content: ""; position: absolute; left: 18%; right: 18%; bottom: -1px;
  height: 2px; background: var(--accent); border-radius: 2px;
}
.tab:hover:not(.active) { color: var(--text); background: transparent; }
.tab-content {
  flex: 1; overflow-y: auto; padding: 16px;
  background: var(--bg-2);
  margin: 0 6px 10px 0;
  border-radius: 0 0 14px 14px;
  /* v0.180.1: hide the right-pane scrollbar Lucas flagged. The panel
     still scrolls (overflow-y: auto above), the chrome is just suppressed
     to match .side-moves and #pillTabs. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.tab-content::-webkit-scrollbar { width: 0; height: 0; display: none; }
.tab-content.hidden { display: none; }

/* analyze box (chess.com-style "Get insights" prompt - lives at the top of the right pane) */
.analyze-box {
  background: var(--bg-2);
  border: 1px solid rgba(var(--accent-rgb), 0.30); border-radius: 12px;
  padding: 12px 16px; margin: 4px 14px 12px;
}
.analyze-box.hidden { display: none; }
.analyze-head {
  display: flex; align-items: center; gap: 10px; margin-bottom: 9px;
}
.analyze-head .ai-title {
  color: var(--text); font-size: 13px; font-weight: 600; line-height: 1.4;
}
.analyze-box button {
  width: 100%;
  background: var(--accent); color: var(--on-accent); border: none;
  padding: 11px 0; border-radius: 8px; cursor: pointer;
  font-weight: 800; font-size: 13.5px; transition: background 0.12s;
  letter-spacing: 0.4px;
}
.analyze-box button:hover { background: #e8cda6; }
.analyze-box button:disabled { background: var(--bg-3); color: var(--text-faint); cursor: wait; }
.analyze-progress { margin-top: 12px; }
.analyze-progress.hidden { display: none; }
.analyze-progress .bar {
  height: 6px; background: rgba(0,0,0,0.40); border-radius: 3px; overflow: hidden;
}
.analyze-progress .fill {
  height: 100%; background: var(--accent); width: 0%; transition: width 0.3s;
}
.analyze-progress .lbl {
  font-size: 11px; color: var(--text-faint); margin-top: 5px;
  font-family: "Consolas", monospace;
}

/* ===== move table ===== */
.move-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.move-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg-2); color: var(--text-faint);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 10px 14px; text-align: left;
  border-bottom: 1px solid var(--bg-3);
}
.move-table thead th.col-num { text-align: center; width: 38px; }
.move-table tbody td {
  padding: 3px 8px; font-size: 13.5px; vertical-align: middle;
}
.move-table tbody td.move-no {
  color: var(--text-faint); font-weight: 600; width: 38px; text-align: center;
  font-family: "Consolas", monospace; font-size: 12px;
}
/* v0.176.2: Lucas asked for the visible "lines" between move plays
   to disappear. The alternating row backgrounds (was rgba(0,0,0,0.18)
   on odd rows) were drawing visible bands; now all rows share the
   same transparent bg, with only the hover + .active states providing
   feedback. The header still gets a single subtle border-bottom from
   .move-table thead th above. */
.move-table tbody tr                 { background: transparent; }
.move-table tbody tr:hover           { background: rgba(var(--accent-rgb), 0.06); }

.move-table .move-pill {
  display: inline-flex; align-items: baseline; gap: 6px;
  cursor: pointer; padding: 5px 11px; border-radius: 999px;
  color: var(--text); font-weight: 600;
  min-height: 24px;
  transition: background 0.1s, color 0.1s;
}
.move-table .move-pill:hover { background: rgba(var(--accent-rgb), 0.10); }
.move-table .move-pill.active { font-weight: 800; }
.move-table .move-pill .san { letter-spacing: 0.01em; }
.move-table .move-pill .nag {
  font-family: "Segoe UI", sans-serif; font-weight: 800; font-size: 12.5px;
  letter-spacing: -0.5px;
}
.move-table .move-pill .nag.brilliant  { color: var(--cat-brilliant); }
.move-table .move-pill .nag.great      { color: var(--cat-great); }
.move-table .move-pill .nag.inaccuracy { color: var(--cat-inaccuracy); }
.move-table .move-pill .nag.mistake    { color: var(--cat-mistake); }
.move-table .move-pill .nag.miss       { color: var(--cat-miss); }
.move-table .move-pill .nag.blunder    { color: var(--cat-blunder); }
.move-table .move-pill .nag.forced     { color: var(--cat-forced); }

/* Active-pill background tinted by category (suppresses row striping visually) */
.move-table .move-pill.active                 { background: rgba(var(--accent-rgb), 0.22); color: var(--text); }
.move-table .move-pill.active.cat-brilliant   { background: rgba(38,194,193,0.32);  color: #c8fffd; }
.move-table .move-pill.active.cat-great       { background: rgba(116,155,191,0.32); color: #d6e6ff; }
.move-table .move-pill.active.cat-best,
.move-table .move-pill.active.cat-excellent,
.move-table .move-pill.active.cat-good        { background: rgba(149,188,106,0.26); color: #e8f5d3; }
.move-table .move-pill.active.cat-book        { background: rgba(168,136,101,0.30); color: #f1e3c8; }
.move-table .move-pill.active.cat-forced      { background: rgba(114,128,160,0.28); color: #d6dcef; }
.move-table .move-pill.active.cat-inaccuracy  { background: rgba(247,194,69,0.28);  color: #fff3d4; }
.move-table .move-pill.active.cat-mistake     { background: rgba(255,164,89,0.30);  color: #ffe2c9; }
.move-table .move-pill.active.cat-miss        { background: rgba(238,107,88,0.28);  color: #ffd9d3; }
.move-table .move-pill.active.cat-blunder     { background: rgba(250,65,45,0.30);   color: #ffd6cf; }

/* category icon badge - used inline in stats/move lists.  Now a SVG container. */
.cat-icon {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; line-height: 1;
}
.cat-icon svg { display: block; }

/* ===== STATS TAB - chess.com Game Review layout ===== */
.stats-section { margin-bottom: 20px; }
.stats-section .stats-title {
  font-size: 11px; color: var(--text-faint); text-transform: uppercase;
  letter-spacing: 0.8px; font-weight: 800; margin-bottom: 10px;
}

/* Fix 1 (Wanda-19): card wrapper for Game Report - rounded card, clean dividers.
   v0.176: card now blends with the outer pane (transparent bg, no border)
   so the section looks like one continuous panel instead of a nested card. */
.stats-report-card {
  background: transparent;
  border: none;
  border-radius: 14px;
  overflow: hidden;
}

.stats-players-row, .stats-acc-row, .stats-cat-row, .stats-rating-row {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 14px;
  padding: 10px 20px; background: transparent;
  /* v0.176: dividers softened so the section reads as one continuous
     panel instead of stacked cards. */
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.stats-players-row {
  background: transparent; border-radius: 14px 14px 0 0;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.stats-players-row .pcell {
  display: flex; align-items: center; gap: 8px;
}
.stats-players-row .pcell.empty { min-height: 30px; }
.stats-players-row .pcell.right { justify-content: flex-end; flex-direction: row-reverse; }
/* v0.176.4: centred pair of letter avatars (names dropped per Lucas).
   v0.176.6: wider gap (10 -> 36) so the two pieces sit clearly apart.
   v0.176.9: spread further so they read as White / Black sitting at the
   row edges rather than clustered in the centre. Min-width plus
   space-between forces the wrapper to occupy real horizontal real
   estate inside the auto grid cell. */
.stats-players-row .pavatars {
  display: flex; align-items: center; justify-content: space-between;
  min-width: 260px; padding: 0 10px; gap: 0;
}
.stats-players-row .pavatar {
  width: 34px; height: 34px; border-radius: 6px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 16px; font-family: var(--serif);
}
.stats-players-row .pavatar.white { background: var(--light-sq); color: #1a1a1a; border: 1px solid rgba(0,0,0,0.15); }
.stats-players-row .pavatar.black { background: var(--dark-sq); color: var(--light-sq); border: 1px solid var(--bg-4); }
.stats-players-row .pname-stack { display: flex; flex-direction: column; line-height: 1.2; }
.stats-players-row .pname-stack .pn { font-weight: 700; font-size: 13px; color: var(--text); }
.stats-players-row .pname-stack .pr { font-size: 11px; color: var(--text-dim); }
.stats-players-row .label { font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.6px; font-weight: 800; }

.stats-acc-row .acc-val {
  /* v0.176.4: switched from Consolas to the app sans stack so the
     accuracy numbers read clean and modern, not as a monospaced
     "pixel" font.
     v0.176.9: dropped from 24px to 20px so the number feels less
     overpowering against the rest of the report panel. */
  font-family: var(--sans, "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);
  font-weight: 700; font-size: 20px; letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  text-align: center; line-height: 1.3;
  /* v0.176.6: do NOT colour-code the accuracy by quality. Lucas
     wants the number to read as a neutral stat, not a verdict. */
  color: var(--text);
}
.stats-acc-row .acc-val.left { text-align: left; }
.stats-acc-row .acc-val.right { text-align: right; }
.stats-acc-row .acc-val.high,
.stats-acc-row .acc-val.med,
.stats-acc-row .acc-val.low { color: var(--text); }
.stats-acc-row .acc-val.na   { color: var(--text-faint); }
/* v0.176.9: uppercase section labels (ACCURACY, GAME RATING, etc.)
   bumped from weight 700 to 800 for a slightly thicker, more
   confident silhouette without growing the type size. */
.stats-acc-row .label { font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.6px; font-weight: 800; text-align: center; }

.stats-cat-row {
  background: transparent;
  padding: 9px 20px;
  line-height: 1.5;
}
.stats-cat-row:hover { background: rgba(var(--accent-rgb), 0.05); }
.stats-cat-row .cnt {
  font-family: "Consolas", monospace; font-weight: 700; font-size: 16px;
  color: var(--text); min-width: 28px;
}
/* v0.176.6: push count numbers toward the outer edges of the row so
   they sit clearly away from the centered icon+label. */
.stats-cat-row .cnt.left  { text-align: left;  padding-left: 8px;  }
.stats-cat-row .cnt.right { text-align: right; padding-right: 8px; }
.stats-cat-row .cnt.zero { color: var(--text-faint); font-weight: 400; }
.stats-cat-row .cat-cell {
  display: flex; align-items: center; gap: 8px; justify-content: center;
  min-width: 130px;
}
.stats-cat-row .cat-cell .cat-label-text {
  color: var(--text); font-weight: 600; font-size: 13px;
}

.stats-rating-row { border-bottom: none; }
.stats-rating-row .rating-val {
  font-family: "Consolas", monospace; font-weight: 800; font-size: 16px;
  color: var(--text);
}
.stats-rating-row .rating-val.left { text-align: left; }
.stats-rating-row .rating-val.right { text-align: right; }
.stats-rating-row .label { font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.6px; font-weight: 800; text-align: center; }

.stats-table {
  /* v0.176.1: was rgba(0,0,0,0.18) + border - that dark inner shell
     didn't match the tab-content background. Now transparent + no
     border so the report rows sit directly on the pane and read as
     one continuous panel (matches the .stats-report-card fix). */
  background: transparent; border: none; border-radius: 6px;
  overflow: hidden;
}

/* phase rows */
.phase-row {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 14px;
  padding: 9px 12px;
  border-top: 1px solid var(--bg-2);
}
.phase-row:first-child { border-top: none; }
.phase-row .pside {
  display: flex; align-items: center; gap: 7px;
}
.phase-row .pside.right { justify-content: flex-end; }
.phase-row .pside .pacc {
  font-family: "Consolas", monospace; font-weight: 700; font-size: 14px;
  min-width: 42px;
}
.phase-row .pside .pacc.high { color: #95bc6a; }
.phase-row .pside .pacc.med  { color: var(--cat-inaccuracy); }
.phase-row .pside .pacc.low  { color: var(--cat-blunder); }
.phase-row .pside .pacc.na   { color: var(--text-faint); }
.phase-row .phase-label {
  text-align: center; font-size: 12px; color: var(--text);
  font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px;
  min-width: 110px;
}
.phase-row .phase-label .phase-range {
  display: block; font-size: 10px; color: var(--text-faint);
  font-weight: 500; letter-spacing: 0.3px; margin-top: 2px;
  font-family: "Consolas", monospace; text-transform: none;
}

/* ===== Accuracy-by-phase: grouped bar chart (chess.com-style) ===== */
.phase-chart {
  display: flex; align-items: flex-end; gap: 10px;
  padding: 14px 8px 6px 4px;
}
.phase-chart-axis {
  position: relative;                /* anchor for absolutely-positioned ticks */
  padding-right: 6px; min-width: 22px;
  font-family: "Consolas", monospace; font-size: 11px;
  color: var(--text-faint);
}
.phase-axis-tick {
  position: absolute;
  right: 6px;
  line-height: 1;
  transform: translateY(50%);        /* vertically center the label on its gridline */
}
.phase-chart-plot {
  position: relative; flex: 1;
  display: flex; align-items: flex-end; justify-content: space-around;
  border-left: 1px solid var(--bg-3);
}
.phase-chart-gridline {
  position: absolute; left: 0; right: 0; height: 1px;
  background: var(--bg-3); opacity: 0.45; pointer-events: none;
}
.phase-bar-group {
  display: flex; flex-direction: column; align-items: center;
  flex: 1; max-width: 110px;
  height: 100%; justify-content: flex-end;
}
.phase-bar-pair {
  display: flex; align-items: flex-end; justify-content: center;
  gap: 4px; width: 100%; height: 100%;
}
.phase-bar {
  position: relative;
  /* v0.176: wider columns + softer accuracy palette (set inline). */
  width: 48px;
  border-radius: 8px 8px 0 0;
  transition: height 0.4s cubic-bezier(.2,.7,.3,1);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 4px;
}
/* Fix 5 (Wanda-19): bar colors are now accuracy-driven, set via inline style.
   No palette CSS vars here - green/amber/red scale is semantic. */
.phase-bar-left  { /* background set inline via accBarColor() */ }
.phase-bar-right { /* background set inline via accBarColor() */ }
/* .phase-bar.low and .phase-bar-right.low removed - accBarColor covers this */
.phase-bar-val {
  font-family: "Consolas", monospace; font-size: 10px;
  color: var(--on-accent); font-weight: 700;
  opacity: 0; transition: opacity 0.15s;
}
.phase-bar-right .phase-bar-val { color: var(--text); }
.phase-bar:hover .phase-bar-val { opacity: 1; }
.phase-bar-label {
  margin-top: 0; font-size: 11.5px; color: var(--text-faint);
  letter-spacing: 0.2px; text-align: center;
}
/* Label row sits BELOW the plot (was previously nested inside each bar
   group, which shifted the bars upward off the "0" baseline). */
.phase-chart-labels {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 4px 8px 8px 4px;
}
.phase-chart-labels-axis-spacer { min-width: 22px; padding-right: 6px; }
.phase-chart-labels-inner {
  flex: 1; display: flex; justify-content: space-around;
  /* Match the left border padding of .phase-chart-plot so labels line up
     under their bar groups. */
  border-left: 1px solid transparent;
}

/* ===== Hide scrollbars in the sidebar while keeping scroll functional ===== */
.sidebar-scroll { scrollbar-width: none; -ms-overflow-style: none; }
.sidebar-scroll::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ===== Global thin, theme-blending scrollbars =====
   Applies to every scrollable container so the move list, Report panel,
   stats panel, etc. don't show a chunky default-OS scrollbar against the
   dark theme. Track is fully transparent, thumb is a faint white that
   only becomes visible when the user hovers. */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.10) transparent;
}
*::-webkit-scrollbar { width: 8px; height: 8px; background: transparent; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.10);
  border-radius: 4px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.22); background-clip: padding-box; }
*::-webkit-scrollbar-corner { background: transparent; }
/* Re-assert the fully-hidden sidebar scrollbar overrides the global rule. */
.sidebar-scroll::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ===== ANALYSIS (Review) tab ===== */
.findings-section-title {
  font-size: 11px; font-weight: 800; letter-spacing: 0.16em;
  color: var(--text-faint); text-transform: uppercase;
  margin: 18px 0 10px 0; padding-bottom: 6px;
  border-bottom: 1px solid var(--bg-3);
}
.findings-section-title:first-child { margin-top: 4px; }
.finding {
  border-left: 4px solid var(--bg-3); padding: 12px 14px; margin-bottom: 10px;
  background: var(--bg-1); border-radius: 0 10px 10px 0; cursor: pointer;
  transition: background 0.1s, transform 0.08s;
}
.finding.opp { opacity: 0.88; }
.finding:hover { background: var(--bg-3); transform: translateX(2px); }
.finding.cat-BRILLIANT  { border-left-color: var(--cat-brilliant); }
.finding.cat-GREAT      { border-left-color: var(--cat-great); }
.finding.cat-BLUNDER    { border-left-color: var(--cat-blunder); }
.finding.cat-FORCED     { border-left-color: var(--cat-forced); }
.finding-head {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px;
}
.finding-head .move-notation { font-weight: 700; font-family: "Consolas", monospace; font-size: 14px; }
.finding-head .loss {
  color: var(--cat-blunder); font-size: 12px; margin-left: auto; font-weight: 700;
  font-family: "Consolas", monospace;
}
.finding-body { font-size: 12.5px; color: var(--text); line-height: 1.6; }
.finding-body .why { margin: 5px 0; }
.finding-body .why.faint { color: var(--text-dim); font-style: italic; }
.finding-body .why .lab {
  color: var(--text-faint); font-weight: 700; margin-right: 5px;
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.3px;
}
.finding-body .bestline {
  font-family: "Consolas", monospace; color: var(--accent); font-size: 11.5px;
  margin-top: 8px; padding: 6px 8px; background: var(--accent-soft);
  border-radius: 4px; border-left: 2px solid var(--accent);
}

/* (engine panel removed - live engine UI is no longer part of the SPA) */

/* ===== board SVG bits ===== */
.square-light { fill: var(--light-sq); }
.square-dark  { fill: var(--dark-sq); }
.last-move    { fill: var(--last-move-fill, #f7d76e); opacity: 0.42; }
/* v0.176: last-move highlight tinted by move category so the squares
   the piece came from / went to read in the same color as the move
   badge (BRILLIANT teal, BLUNDER red, INACCURACY yellow, etc.). Only
   the analyze board (renderBoard) emits these classes; the Play /
   Puzzle / Endgame boards keep the neutral yellow shade.
   v0.176.2: opacities bumped - the green/blue tints were barely
   visible against the wood-toned dark squares, and Lucas asked for
   stronger category colouring. */
.last-move.cat-BRILLIANT  { fill: #d63a8e; opacity: 0.55; }
.last-move.cat-GREAT      { fill: #749bbf; opacity: 0.55; }
.last-move.cat-BEST       { fill: #95bc6a; opacity: 0.55; }
.last-move.cat-EXCELLENT  { fill: #95bc6a; opacity: 0.52; }
.last-move.cat-GOOD       { fill: #95af6c; opacity: 0.48; }
.last-move.cat-BOOK       { fill: #a88865; opacity: 0.50; }
.last-move.cat-FORCED     { fill: #7280a0; opacity: 0.50; }
.last-move.cat-INACCURACY { fill: #f7c245; opacity: 0.55; }
.last-move.cat-MISTAKE    { fill: #ffa459; opacity: 0.55; }
.last-move.cat-MISS       { fill: #ff7769; opacity: 0.58; }
.last-move.cat-BLUNDER    { fill: #fa412d; opacity: 0.58; }
/* Puzzle hint highlight: glows the from-square of the next expected
   move when the user clicks Hint. Orange so it's distinct from the
   yellow last-move highlight. */
.puz-hint-square { fill: #ffaa00; opacity: 0.55; }
/* Premove highlight (queued user move while bot is thinking). Reddish
   tint so it's visually distinct from the yellow last-move shade. */
.premove-sq   { fill: #d96a5a; opacity: 0.50; }
/* Coord labels: switch to a clean rounded sans + crisper SVG rendering so
   the file/rank glyphs don't look pixelated at small board sizes. */
.coord {
  font-family: "Inter", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-size: 10px;
  font-weight: 600;
  pointer-events: none; user-select: none;
  letter-spacing: 0.1px;
  text-rendering: geometricPrecision;
  -webkit-font-smoothing: antialiased;
  shape-rendering: geometricPrecision;
  opacity: 0.95;
}
.coord.file { text-anchor: end; }
.arrow-best {
  stroke: #6ec84e; fill: #6ec84e; opacity: 0.62;
  stroke-linejoin: round;
}
.arrow-punish {
  stroke: #d04040; fill: #d04040; opacity: 0.62;
  stroke-linejoin: round;
}
/* User-drawn arrows (right-click drag on the board). Orange with a
   touch of transparency so they sit clearly over both light and dark
   squares without obscuring the piece icons underneath. */
.arrow-user {
  stroke: #f59f3b; fill: #f59f3b; opacity: 0.78;
  stroke-linejoin: round;
  pointer-events: none;
}
.board-cat-badge { pointer-events: none; }
/* Courses (Trainer learn-mode) board overlays. Arrows: plan = accent so
   it reads as "the right plan" without colliding with green-best / red-bad.
   Marks: translucent square fills drawn under the pieces. */
.arrow-plan {
  stroke: var(--accent, #7c5cff); fill: var(--accent, #7c5cff); opacity: 0.66;
  stroke-linejoin: round;
  pointer-events: none;
}
.mark-good { fill: #6ec84e; opacity: 0.42; }
.mark-bad  { fill: #d04040; opacity: 0.42; }
.mark-key  { fill: var(--accent, #7c5cff); opacity: 0.40; }
/* Piece movement animation (used by renderBoard) */
.piece-animating { will-change: transform; }

/* Drag-ghost: the floating piece image that follows the cursor while the
   user is dragging. Slightly enlarged so it reads as "lifted" off the
   board. The inline cssText on the element sets size/position only, so the
   transform here always wins. Applied across every mode (Play, Puzzles,
   Openings Trainer, Endgames). */
.drag-ghost { transform: scale(1.08); }
@media (prefers-reduced-motion: no-preference) {
  .drag-ghost { animation: drag-ghost-pop 90ms ease-out; }
}
@keyframes drag-ghost-pop {
  from { transform: scale(0.96); }
  to   { transform: scale(1.08); }
}

/* Picked-up / click-selected piece grows ever so slightly about its own
   centre, so a tap on a piece gives the same "lifted" feedback as a drag.
   The actual scale transform is emitted inline by boardPieceNode() with an
   explicit centre (translate-scale-translate in user units) because Chromium
   ignores `transform-box: fill-box` on <use> sprite pieces and would otherwise
   scale them about the SVG root origin, drifting them toward the bottom-right
   of the square. Here we only own the transition. */
@media (prefers-reduced-motion: no-preference) {
  image.piece-selected,
  use.piece-selected { transition: transform 90ms ease; }
}

/* ===== Checkmate overlay (v0.173, chess.com-style) =====
   On the final mate position both king squares flash a coloured square
   (red on the loser, green on the winner) that fades IN, holds, then
   fades back out in place (v0.195.138). As the square fades out a small
   round corner badge (white crown on the winner, black X on the loser)
   fades in, slightly overhanging the neighbouring squares, leaving the
   king image untouched. */
.mate-fill {
  pointer-events: none;
  animation: mate-fill-fade 1.0s ease-in-out forwards;
}
.mate-fill-win  { fill: #6ec84e; }
.mate-fill-lose { fill: #d04040; }
/* v0.195.138: the coloured square now fades IN (instead of appearing at
   full opacity), holds briefly, then fades back out in place. The whole
   flash is slightly faster (1.0s, was 1.4s) and the corner badge fades in
   as the square fades out (~0.55s). Lucas asked for a smoother fade-in /
   fade-out instead of the square popping in. */
@keyframes mate-fill-fade {
  0%   { opacity: 0.0;  }
  18%  { opacity: 0.82; }
  55%  { opacity: 0.82; }
  100% { opacity: 0.0;  }
}
.mate-icon-svg {
  pointer-events: none;
  opacity: 0;
  overflow: visible;
  transform-box: fill-box; transform-origin: center;
  animation: mate-icon-in 0.32s ease-out 0.55s forwards;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,0.5));
}
/* v0.195.138: the crown / X now purely fades in (no scale) as the coloured
   square fades out, so it reads as appearing in place rather than flying or
   zooming in. */
@keyframes mate-icon-in {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
.mate-disc-win  { fill: #6ec84e; stroke: #fff; stroke-width: 1.2; }
.mate-disc-lose { fill: #d04040; stroke: #fff; stroke-width: 1.2; }
.mate-glyph {
  fill: white; stroke: white; stroke-width: 0;
  stroke-linecap: round; stroke-linejoin: round;
}
.mate-glyph-x { fill: none; stroke-width: 3.2; }
/* v0.195.97: black cross on the loser badge (red disc + black X). The
   black stroke overrides the default white .mate-glyph colour and keeps
   it distinct from the white-X "Miss" move-category badge. */
.mate-glyph-cross { fill: none; stroke: #111; stroke-width: 3.2; }
/* v0.176.9: chess-notation hash "#" for the loser badge - drawn as
   two pairs of parallel lines so it stays visually distinct from
   the Missed Opportunity X badge. Wide strokes keep it readable
   at every board size. */
.mate-glyph-hash { fill: none; stroke-width: 2.4; }
/* v0.195.166: white flag on the loser badge for non-mate decisive endings
   (resignation / timeout / abandonment). Pole is a thin white stroke; the
   pennant is a filled white triangle that reads clearly on the red disc. */
.mate-glyph-flagpole { fill: none; stroke: #fff; stroke-width: 2; }
.mate-glyph-flag { fill: #fff; stroke: #fff; stroke-width: 0.6; }

/* ===== Full-screen "Analysing your game" overlay (chess.com-style) ===== */
.analyze-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(8, 10, 14, 0.78);
  backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity 0.22s ease;
  pointer-events: none;
}
.analyze-overlay.visible { opacity: 1; pointer-events: auto; }
.analyze-overlay-inner {
  display: flex; flex-direction: column; align-items: center;
  color: #f1ecdf; text-align: center; padding: 32px; max-width: 360px;
}
.analyze-spinner {
  width: 84px; height: 84px;
  fill: rgba(241, 236, 223, 0.92);
  animation: analyze-pulse 1.6s ease-in-out infinite;
  margin-bottom: 22px;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.45));
}
.analyze-spinner-eye { fill: #1d2128; }
@keyframes analyze-pulse {
  0%, 100% { transform: scale(1);    opacity: 0.85; }
  50%      { transform: scale(1.08); opacity: 1;    }
}
.analyze-overlay-title {
  font-size: 22px; font-weight: 600; letter-spacing: 0.3px;
  margin-bottom: 10px;
}
.analyze-overlay-pct {
  font-size: 28px; font-weight: 700; color: #6ec84e;
  font-variant-numeric: tabular-nums;
  margin-bottom: 12px;
}
.analyze-overlay-bar {
  width: 280px; height: 6px; border-radius: 999px;
  background: rgba(255,255,255,0.12);
  overflow: hidden;
}
.analyze-overlay-fill {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, #6ec84e, #aae08a);
  border-radius: 999px;
  transition: width 0.35s cubic-bezier(.2,.7,.3,1);
}
.analyze-overlay-sub {
  margin-top: 14px; font-size: 13px;
  color: rgba(241, 236, 223, 0.65);
  font-variant-numeric: tabular-nums;
}

/* ===== Responsive: scale board with viewport (slimmer overall) ===== */
@media (min-width: 1500px) { :root { --board-w: 620px; } }
@media (min-width: 1700px) { :root { --board-w: 660px; } }
@media (max-width: 1300px) { :root { --board-w: 500px; } }
@media (max-width: 1100px) { :root { --board-w: 430px; } }

/* v0.176.2: at narrow desktop widths the 480px rightpane crowds the
   board. Step it back down so 320 sidebar + 1fr board + rightpane
   still fits without scroll until the 720px stack-vertically
   breakpoint kicks in. */
@media (max-width: 1300px) {
  .layout { grid-template-columns: 320px 1fr 440px; }
}
@media (max-width: 1100px) {
  .layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto;
    height: auto;
    min-height: calc(100vh - var(--topbar-h));
  }
  .sidebar, .board-area, .rightpane {
    overflow: visible;
    height: auto;
    max-height: none;
    border: none;
  }
  .sidebar { order: 2; border-top: 1px solid var(--bg-3); }
  .board-area { order: 1; min-width: 0; overflow-x: hidden; }
  .rightpane { order: 3; border-top: 1px solid var(--bg-3); min-width: 0; overflow-x: hidden; }
}


/* ===== App version badge (bottom-right). Bump APP_VERSION in app.js after
   every change - stay in 0.x range (beta). ===== */
.app-version {
  position: fixed;
  right: 10px; bottom: 8px;
  font-family: "JetBrains Mono", "Consolas", monospace;
  font-size: 10.5px;
  color: rgba(232, 225, 212, 0.45);
  background: rgba(20, 16, 12, 0.55);
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  letter-spacing: 0.4px;
  pointer-events: none;
  z-index: 5;
  -webkit-user-select: none;
  user-select: none;
}

/* Legal footer links - bottom-left, subtle. */
.app-legal-footer {
  position: fixed;
  left: 88px; bottom: 8px;
  display: flex;
  gap: .4rem;
  align-items: center;
  font-size: 10.5px;
  color: rgba(232, 225, 212, 0.35);
  z-index: 5;
}
.app-legal-footer a {
  color: rgba(232, 225, 212, 0.35);
  text-decoration: none;
}
.app-legal-footer a:hover {
  color: var(--text-dim);
  text-decoration: underline;
}
.app-legal-footer span {
  color: rgba(232, 225, 212, 0.2);
}
/* Buy-Me-a-Coffee link in the legal footer. Auto-hidden on Pro tier
   when document.body has the .has-pro class (Phase 2). */
.app-legal-footer .app-bmc-link {
  color: rgba(255, 198, 109, 0.6);
}
.app-legal-footer .app-bmc-link:hover {
  color: rgb(255, 198, 109);
  text-decoration: underline;
}
body.has-pro .app-bmc-sep,
body.has-pro .app-bmc-link {
  display: none;
}


/* ============================================================ */
/*  PLAY page - Choose Opponent UI                              */
/* ============================================================ */
.play-view {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 28px;
  padding: 24px 28px;
  max-width: 1280px;
  margin: 0 auto;
  align-items: start;
}
@media (max-width: 900px) {
  .play-view { grid-template-columns: 1fr; }
}

/* ---- Screen state machine: character-select vs in-game.  When
   #pagePlay[data-play-screen="select"] we hide the board area and the
   in-game aside, and let the #playSelect section span the full width.
   When "playing" the inverse holds. */
#pagePlay[data-play-screen="select"] .play-view {
  grid-template-columns: 1fr;
}
#pagePlay[data-play-screen="select"]  #playBoardArea,
#pagePlay[data-play-screen="select"]  #playPanel { display: none !important; }
#pagePlay[data-play-screen="playing"] #playSelect { display: none !important; }
/* Once a match is on, the chosen-bot character card is redundant -- the
   user just picked it -- so hide it and let the moves panel float higher.
   The bot identity now lives in the mini avatar on the top strip. */
#pagePlay[data-play-screen="playing"] #playCurrentBot { display: none; }
/* With the bot card gone, give the panel a slimmer footprint so the
   board claims the centre of the screen. */
#pagePlay[data-play-screen="playing"] .play-view {
  grid-template-columns: minmax(0, 1fr) 320px;
}

.play-board-area {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  min-width: 0;
  position: relative;
}
/* The board lives inside .board-wrap. In this flex column with
   align-items:center the wrapper shrinks to its content, so an SVG with no
   intrinsic width attribute fell back to its 300px replaced-element default
   (board stuck tiny in the upper-left). Give the wrapper a definite size so
   the SVG (width:100% below) can grow to fill the column. The size is
   clamped by BOTH the column width and the viewport height (minus the room
   the strips + controls + page chrome need) so the board never overflows a
   short window nor collapses to the 300px fallback. The first declaration is
   a vh fallback for engines without svh support. */
.play-board-area .board-wrap {
  width: min(100%, 640px, calc(100vh - 250px));
  width: min(100%, 640px, calc(100svh - 250px));
  margin: 0 auto;
}
.play-board-area svg {
  width: 100%; aspect-ratio: 1/1; height: auto;
  display: block;
  border-radius: 6px;
  touch-action: none;
  cursor: grab;
  user-select: none;
}
.play-board-area svg:active { cursor: grabbing; }
.play-board-area svg text { pointer-events: none; user-select: none; }
.play-board-area svg image,
.play-board-area svg use { pointer-events: all; }

/* ============================================================
   Character-selection screen (#playSelect)
   ============================================================ */
.play-select {
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
  display: flex; flex-direction: column; align-items: center;
  gap: 22px;
  padding: 8px 0 32px;
}
.play-select-head {
  text-align: center;
  margin-bottom: 4px;
}
.play-select-title {
  margin: 0 0 6px;
  font-family: var(--serif);
  font-size: 30px; font-weight: 700; color: var(--text);
  letter-spacing: 0.5px;
}
.play-select-sub {
  margin: 0;
  color: var(--text-dim); font-size: 14px;
}
.play-select-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(280px, 1fr));
  gap: 20px;
  width: 100%;
}
@media (max-width: 720px) {
  .play-select-grid { grid-template-columns: 1fr; }
}
.play-card {
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 14px;
  padding: 20px 18px 18px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 8px;
  position: relative;
  overflow: hidden;
  transition: border-color 140ms ease, transform 140ms ease, box-shadow 140ms ease;
}
.play-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35);
}
.play-card::before {
  /* Accent glow behind the avatar - uses the card's own palette
     variables so each persona can tint it differently. */
  content: "";
  position: absolute; top: -30px; left: 50%;
  width: 180px; height: 180px;
  transform: translateX(-50%);
  background: radial-gradient(circle, var(--card-glow, var(--accent-soft)) 0%, transparent 70%);
  pointer-events: none;
}
.play-card-avatar {
  position: relative;
  width: 86px; height: 86px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--card-c1, var(--accent)) 0%, var(--card-c2, var(--accent-d)) 100%);
  color: var(--on-accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 36px; font-weight: 700;
  border: 3px solid var(--bg-3);
  box-shadow: 0 4px 14px rgba(0,0,0,0.35);
  margin-bottom: 4px;
}
.play-card-avatar svg.persona-icon {
  width: 72%; height: 72%;
  display: block;
  /* Slight white outline behind the strokes so the hand-drawn lines pop
     against the gradient even when the displacement filter pushes them
     to the edge of the avatar. */
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.25));
}
.play-card-name {
  position: relative;
  font-family: var(--serif); font-weight: 700; font-size: 22px;
  color: var(--card-c1, var(--accent));
}
.play-card-tag {
  position: relative;
  display: inline-block;
  padding: 2px 10px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase;
  background: rgba(var(--accent-rgb), 0.15);
  border: 1px solid rgba(var(--accent-rgb), 0.30);
  color: var(--accent);
  border-radius: 999px;
}
.play-card-desc {
  position: relative;
  color: var(--text-dim); font-size: 13px; line-height: 1.45;
  min-height: 3.6em;
  padding: 2px 4px;
}
.play-card-diff {
  position: relative;
  width: 100%;
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 4px;
}
.play-card-diff-head {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px;
}
.play-card-diff-val {
  font-family: "JetBrains Mono", monospace;
  font-weight: 700; font-size: 13px; color: var(--text);
  text-transform: none;
}
.play-card-diff-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 8px;
  padding: 4px;
}
.play-card-diff-btn {
  padding: 6px 4px;
  background: transparent;
  color: var(--text-dim);
  border: none;
  border-radius: 5px;
  font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.2px;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, transform 80ms ease;
}
.play-card-diff-btn:hover { color: var(--text); background: var(--bg-2); }
.play-card-diff-btn:active { transform: scale(0.96); }
.play-card-diff-btn.active {
  background: var(--card-c1, var(--accent));
  color: var(--on-accent);
}
.play-card-btn {
  width: 100%;
  margin-top: 6px;
  padding: 11px 14px;
  border-radius: 8px;
  font-weight: 700; font-size: 14px;
  background: var(--accent); color: var(--on-accent);
  border: 1px solid var(--accent);
  cursor: pointer;
  transition: background 120ms ease, transform 80ms ease;
}
.play-card-btn:hover { background: var(--accent-d); }
.play-card-btn:active { transform: scale(0.98); }
/* Per-persona palette overrides - applied via a data attribute on the
   card so each opponent feels distinct. Falls back to the global accent
   if the persona id isn't recognised. */
.play-card[data-persona="balanced"]   { --card-c1: #93b8e0; --card-c2: #5a7fb0; --card-glow: rgba(147, 184, 224, 0.16); }
.play-card[data-persona="aggressive"] { --card-c1: #e08a6a; --card-c2: #a85c3e; --card-glow: rgba(224, 138, 106, 0.18); }
.play-card[data-persona="defensive"]  { --card-c1: #9ad0b0; --card-c2: #5a9077; --card-glow: rgba(154, 208, 176, 0.16); }
.play-card[data-persona="mimic"]      { --card-c1: #bda8d8; --card-c2: #7e6aa8; --card-glow: rgba(189, 168, 216, 0.17); }

/* Shared row below the persona grid: side picker + time-control picker.
   Compact horizontal layout - no framed background, just two clusters of
   tiny labels above small pill rows. Side cluster stays tight, TC cluster
   gets the remaining width. */
.play-select-shared {
  width: 100%;
  max-width: 720px;
  display: flex; flex-wrap: wrap; align-items: flex-end;
  gap: 18px 24px;
  padding: 6px 4px 0;
}
.play-shared-cluster {
  display: flex; flex-direction: column; gap: 6px;
  min-width: 0;
}
.play-shared-cluster-tc {
  flex: 1 1 360px;
}
.play-shared-label {
  font-size: 10.5px; color: var(--text-dim); text-transform: uppercase;
  letter-spacing: 0.7px; font-weight: 600;
  padding-left: 2px;
}
.seg-side {
  width: 132px;
}

/* ============================================================
   In-game aside: current bot card + actions + history
   ============================================================ */
.play-current-bot {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 10px;
}
.play-current-avatar {
  width: 48px; height: 48px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--card-c1, var(--accent)) 0%, var(--card-c2, var(--accent-d)) 100%);
  color: var(--on-accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 22px; font-weight: 700;
  border: 2px solid var(--bg-3);
  flex-shrink: 0;
}
.play-current-avatar svg.persona-icon {
  width: 74%; height: 74%;
  display: block;
}
.play-current-meta { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.play-current-name { font-family: var(--serif); font-weight: 700; font-size: 17px; color: var(--text); }
.play-current-tag  { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; }
.play-current-elo  { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--text-dim); }
/* Per-persona palette mirrored on the in-game aside card. */
.play-current-bot[data-persona="balanced"]   { --card-c1: #93b8e0; --card-c2: #5a7fb0; }
.play-current-bot[data-persona="aggressive"] { --card-c1: #e08a6a; --card-c2: #a85c3e; }
.play-current-bot[data-persona="defensive"]  { --card-c1: #9ad0b0; --card-c2: #5a9077; }
.play-current-bot[data-persona="mimic"]      { --card-c1: #bda8d8; --card-c2: #7e6aa8; }

/* Review-navigation controls under the Play board. Reuses .controls /
   .ctrl-circle / .ctrl-ico / .ctrl-center from the analyze page but
   sized down to match the Play board's smaller dimensions. */
.play-controls {
  width: min(100%, 640px);
  margin-top: 10px;
}
.play-strip {
  width: min(100%, 640px);
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  background: var(--bg-2); border: 1px solid var(--bg-3); border-radius: 10px;
}
.play-strip-name { color: var(--text); font-weight: 600; font-size: 14px; white-space: nowrap; }
/* Mini circular avatar shown inside the top/bottom strip next to the
   player name. Picks up the same per-persona palette as the big card
   via [data-persona] on .play-strip so each opponent keeps its identity
   even when the full character card is hidden. */
.play-strip-avatar {
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; overflow: hidden;
  background: linear-gradient(140deg, var(--card-c1, #4d6577), var(--card-c2, #2c3e4c));
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
}
.play-strip-avatar svg { width: 72%; height: 72%; display: block; }
.play-strip-avatar svg.persona-icon { width: 78%; height: 78%; }
.play-strip-avatar-user {
  background: linear-gradient(140deg, #6c8a9a, #3a4d57);
  color: rgba(255,255,255,0.85);
}
/* Match the per-persona colour palette on the strip so the mini avatar
   matches the bot the user picked. Mirrors .play-current-bot[data-persona]. */
.play-strip[data-persona="balanced"]   { --card-c1: #93b8e0; --card-c2: #5a7fb0; }
.play-strip[data-persona="aggressive"] { --card-c1: #e08a6a; --card-c2: #a85c3e; }
.play-strip[data-persona="defensive"]  { --card-c1: #9ad0b0; --card-c2: #5a9077; }
.play-strip[data-persona="mimic"]      { --card-c1: #bda8d8; --card-c2: #7e6aa8; }
.play-strip-mat  {
  flex: 1;
  color: var(--text-dim);
  font-size: 16px;
  letter-spacing: 1px;
  line-height: 1;
  /* Captured glyphs are rendered as unicode chess characters. Tighten
     letter-spacing keeps repeated pawns from looking too sparse. */
  font-family: "Segoe UI Symbol", "DejaVu Sans", "Apple Symbols", sans-serif;
  min-height: 1em;
}
.play-strip-rt   { color: var(--text-dim); font-family: "JetBrains Mono", monospace; font-size: 13px; }
/* Clocks: monospaced and large so glances at the strip are unambiguous.
   .is-active brightens the side currently on the move; .is-low turns the
   clock orange under 10s and red under 5s for a chess.com-ish urgency cue. */
.play-strip-clock {
  font-family: "JetBrains Mono", "Consolas", monospace;
  font-size: 18px; font-weight: 700; letter-spacing: 0.5px;
  color: var(--text-dim);
  padding: 4px 10px;
  border-radius: 6px;
  background: rgba(0,0,0,0.18);
  min-width: 78px; text-align: right;
}
.play-strip-clock.is-active { color: var(--text); background: rgba(var(--accent-rgb), 0.20); }
.play-strip-clock.is-low    { color: #ffae5e; }
.play-strip-clock.is-crit   { color: #ff5b5b; background: rgba(255, 80, 80, 0.16); }

.play-panel {
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 14px;
  padding: 20px 20px 22px;
  display: flex; flex-direction: column; gap: 16px;
  position: sticky; top: 14px;
}
.play-title {
  margin: 0; font-family: var(--serif);
  font-size: 24px; color: var(--text); text-align: center;
}

/* ---- Persona carousel ---- */
.persona-carousel {
  display: grid;
  grid-template-columns: 36px 1fr 36px;
  gap: 8px;
  align-items: stretch;
}
.carousel-arrow {
  background: var(--bg-1); border: 1px solid var(--bg-3);
  color: var(--text); border-radius: 50%;
  width: 36px; height: 36px; align-self: center;
  cursor: pointer; font-size: 20px; line-height: 1;
  transition: background 120ms, transform 80ms;
}
.carousel-arrow:hover { background: var(--bg-3); }
.carousel-arrow:active { transform: scale(0.92); }

.persona-card {
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 12px;
  padding: 16px 14px 14px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  text-align: center;
  position: relative;
  min-height: 220px;
  overflow: hidden;
}
.persona-card::before {
  /* Subtle accent halo behind the avatar */
  content: "";
  position: absolute; top: -20px; left: 50%;
  width: 160px; height: 160px; transform: translateX(-50%);
  background: radial-gradient(circle, var(--accent-soft) 0%, transparent 70%);
  pointer-events: none;
}
.persona-avatar {
  position: relative;
  width: 96px; height: 96px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-d) 100%);
  color: var(--on-accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 44px; font-weight: 700;
  border: 3px solid var(--bg-2);
  box-shadow: 0 4px 14px rgba(0,0,0,0.35);
}
.persona-name {
  position: relative;
  font-family: var(--serif); font-weight: 700; font-size: 22px;
  color: var(--accent); margin-top: 4px;
}
.persona-tag {
  position: relative;
  display: inline-block;
  padding: 2px 10px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
}
.persona-desc {
  position: relative;
  color: var(--text-dim); font-size: 12.5px; line-height: 1.4;
  padding: 0 4px;
}
.persona-dots {
  display: flex; justify-content: center; gap: 6px;
}
.persona-dot {
  width: 26px; height: 4px; border-radius: 2px;
  background: var(--bg-3); cursor: pointer;
  transition: background 120ms, width 120ms;
}
.persona-dot.active { background: var(--accent); width: 32px; }

.play-section { display: flex; flex-direction: column; gap: 8px; }
.play-row { display: flex; align-items: center; gap: 10px; }
.play-row input[type=range] { flex: 1; }
.play-label {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.6px;
  color: var(--text-faint); font-weight: 600;
}
.play-elo-val {
  font-family: "JetBrains Mono", "Consolas", monospace;
  font-size: 15px; color: var(--accent); font-weight: 700;
  min-width: 42px; text-align: right;
}
#playEloRange { width: 100%; accent-color: var(--accent); }

.seg {
  display: flex; background: var(--bg-1); border: 1px solid var(--bg-3);
  border-radius: 10px; padding: 2px; gap: 2px;
}
.seg-btn {
  flex: 1; padding: 5px 0;
  background: transparent; border: none; color: var(--text-dim);
  cursor: pointer; border-radius: 7px; font-size: 12.5px; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
  transition: background 120ms, color 120ms;
}
.seg-btn:hover { color: var(--text); }
.seg-btn.active { background: var(--accent); color: var(--on-accent); }
.side-swatch {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; line-height: 1;
}
.side-swatch.white { color: #f3e3c4; text-shadow: 0 0 2px rgba(0,0,0,0.6); }
.side-swatch.black { color: #1a1a1a; text-shadow: 0 0 2px rgba(255,255,255,0.3); }
.seg-btn.active .side-swatch.white,
.seg-btn.active .side-swatch.black { text-shadow: none; }
/* Time-control segmented row: compact monospace pills, all six fit on one
   line. Disabled (greyed out) while a game is in progress so the user
   can't change the time control mid-game. */
.seg-tc .seg-btn {
  font-size: 11.5px; font-weight: 600;
  font-family: "JetBrains Mono", "Consolas", monospace;
  padding: 5px 2px;
  min-width: 0; flex: 1;
}
.seg.is-disabled { opacity: 0.55; pointer-events: none; }

/* v0.99: inline segmented controls used in the Play setup (Variant +
   Bot speed) were visually cluttered - inactive pills had no background
   so the labels "Standard Chess960" / "Instant Fast Normal Slow" ran
   together as one wall of text. Give inactive pills a soft chip
   background so each option reads as a distinct option. The 2px gap
   from `.seg` then acts as a clear divider, and a subtle hover bump
   reinforces clickability. The active pill keeps the accent fill from
   the base `.seg-btn.active` rule. */
.seg-variant .seg-btn:not(.active),
.seg-bot-speed .seg-btn:not(.active) {
  background: var(--bg-2);
}
.seg-variant .seg-btn:not(.active):hover,
.seg-bot-speed .seg-btn:not(.active):hover {
  background: var(--bg-3);
}
/* Bot speed has 5 short labels; give it a touch more horizontal room
   per pill so "Adaptive" doesn't get cramped. */
.seg-bot-speed .seg-btn { font-size: 12px; padding: 5px 4px; }

/* ============================================================
   Time-control popover (v0.79) - replaces the flat seg-tc row
   with a dropdown that opens a categorised panel
   (Unlimited / Bullet / Blitz / Rapid). All pills are still
   rendered into #playTimeControl with class="seg-btn" so the
   existing startPlayGame() selector keeps working unchanged.
   ============================================================ */
.tc-wrap { position: relative; }
.tc-trigger {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  min-width: 168px;
  border-radius: 8px;
  border: 1px solid var(--bg-3);
  background: var(--bg-1);
  color: var(--text);
  font: inherit; font-size: 13px; font-weight: 600;
  font-family: "JetBrains Mono", "Consolas", monospace;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}
.tc-trigger:hover { border-color: var(--accent); background: var(--bg-2); }
.tc-trigger[aria-expanded="true"] { border-color: var(--accent); background: var(--bg-2); }
.tc-trigger-label { flex: 1; text-align: left; }
.tc-trigger-caret { color: var(--text-dim); font-size: 11px; }
.tc-panel {
  position: absolute; z-index: 40;
  top: calc(100% + 6px); left: 0;
  min-width: 320px; max-width: 380px;
  padding: 14px 16px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(0,0,0,0.45);
  display: flex; flex-direction: column; gap: 14px;
}
.tc-panel[hidden] { display: none; }
.tc-group { display: flex; flex-direction: column; gap: 7px; }
.tc-group-head {
  font-size: 10.5px; font-weight: 700;
  color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.9px;
}
.tc-group-row {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.tc-group-row .seg-btn {
  flex: 0 1 auto;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--bg-3);
  background: var(--bg-2);
  color: var(--text);
  font-size: 12.5px; font-weight: 600;
  font-family: "JetBrains Mono", "Consolas", monospace;
  min-width: 56px;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.tc-group-row .seg-btn:hover { border-color: var(--accent); }
.tc-group-row .seg-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
/* When the parent cluster is locked (game in progress), grey out both
   the trigger and the panel so the user can't change TC mid-game.
   v0.81: extended to also cover the strength popover. */
.play-shared-cluster-tc.is-disabled .tc-trigger,
.play-shared-cluster-tc.is-disabled .tc-panel,
.play-shared-cluster-strength.is-disabled .tc-trigger,
.play-shared-cluster-strength.is-disabled .tc-panel { opacity: 0.55; pointer-events: none; }

/* ============================================================
   Strength popover (v0.81) - visually identical to the time
   control popover. Slightly tighter min-width since it has a
   single column of 5 pills (Easy/Casual/Skilled/Expert/Insane).
   ============================================================ */
.play-shared-cluster-strength .tc-panel { min-width: 220px; max-width: 280px; }
.play-shared-cluster-strength { min-width: 168px; }

.play-btn {
  padding: 10px 14px;
  background: var(--bg-3); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 9px;
  cursor: pointer; font-weight: 600; font-size: 13.5px;
  transition: background 120ms, transform 80ms;
}
.play-btn:hover:not(:disabled) { background: var(--bg-4); }
.play-btn:active:not(:disabled) { transform: scale(0.97); }
.play-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.play-btn.primary {
  background: var(--accent); color: var(--on-accent);
  border-color: var(--accent-d);
}
.play-btn.primary:hover:not(:disabled) { background: var(--accent-d); }
.play-btn.big { padding: 14px; font-size: 15px; }
.play-btn.ghost {
  background: transparent; color: var(--text-dim); border-color: var(--bg-3);
}
.play-btn.ghost:hover:not(:disabled) { background: var(--bg-1); color: var(--text); }
.play-btn.danger {
  background: #b8323a; color: #fff; border-color: #9e252c;
}
.play-btn.danger:hover:not(:disabled) { background: #cf3c44; }

.play-secondary { display: flex; gap: 8px; }
.play-secondary .play-btn { flex: 1; }

.play-status {
  background: var(--bg-1); border: 1px solid var(--bg-3);
  padding: 10px 12px; border-radius: 9px;
  color: var(--text-dim); font-size: 12.5px; min-height: 38px;
}
.play-status b { color: var(--accent); }

.play-history-card {
  background: var(--bg-1); border: 1px solid var(--bg-3);
  border-radius: 9px; overflow: hidden;
  display: flex; flex-direction: column; min-height: 110px; max-height: 220px;
}
.play-history-head {
  padding: 7px 12px; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.6px; color: var(--text-faint);
  background: var(--bg-2); border-bottom: 1px solid var(--bg-3);
}
.play-history {
  flex: 1; overflow-y: auto; padding: 6px 12px;
  font-family: "JetBrains Mono", "Consolas", monospace; font-size: 12.5px;
  color: var(--text);
}
.play-history .row { display: flex; gap: 10px; padding: 1px 0; }
.play-history .row .num { color: var(--text-faint); width: 24px; text-align: right; }
.play-history .row .w, .play-history .row .b { width: 58px; }

/* Captured-pieces panel (v0.152.0) - matches .play-history-card visual. */
.play-captured-card {
  background: var(--bg-1); border: 1px solid var(--bg-3);
  border-radius: 9px; overflow: hidden;
}
.play-captured-head {
  padding: 7px 12px; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.6px; color: var(--text-faint);
  background: var(--bg-2); border-bottom: 1px solid var(--bg-3);
}
.play-captured-body {
  padding: 8px 12px; display: flex; flex-direction: column; gap: 6px;
}
.play-captured-row {
  display: flex; align-items: center; gap: 8px; min-height: 22px;
}
.play-captured-label {
  font-size: 11px; color: var(--text-faint); min-width: 28px;
  text-transform: uppercase; letter-spacing: 0.4px; flex-shrink: 0;
}
/* Slightly larger glyphs in the panel vs the inline strip. */
.play-captured-card .pmaterial .pc { font-size: 16px; }
.play-captured-card .pmaterial .pdiff { font-size: 12px; color: var(--accent); font-weight: 700; }

.promo-picker {
  position: absolute;
  background: var(--bg-2); border: 1px solid var(--bg-3); border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.5);
  display: flex; flex-direction: column;
  z-index: 60;
}
/* `display: flex` above overrides the browser default `[hidden]{display:none}`,
   so setting `picker.hidden = true` had no visual effect and the picker
   lingered on screen after the user picked a piece. (v0.74) */
.promo-picker[hidden] { display: none; }
.promo-picker button {
  background: transparent; border: none; cursor: pointer;
  color: var(--text); font-size: 22px; padding: 6px 12px;
}
.promo-picker button:hover { background: var(--accent-soft); color: var(--accent); }

/* Universal promotion picker (v0.148.0) - shared overlay for ALL gamemodes.
   Horizontal row of 4 piece images: Q, N, R, B.
   Animate in with 140ms fade + scale, matching GcSelect motion language.   */
.promo-picker-universal {
  position: fixed;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.6), 0 2px 8px rgba(0,0,0,0.35);
  display: flex;
  flex-direction: row;
  gap: 2px;
  padding: 4px;
  z-index: 9000;
  opacity: 0;
  transform: scale(0.95);
  transition: opacity 140ms ease-out, transform 140ms ease-out;
}
.promo-picker-universal[hidden] { display: none; }
.promo-picker-universal.open {
  opacity: 1;
  transform: scale(1);
}
@media (prefers-reduced-motion: reduce) {
  .promo-picker-universal { transition: none; }
}
.promo-picker-universal button {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 100ms;
}
.promo-picker-universal button:hover { background: var(--accent-soft); }
.promo-picker-universal button img { display: block; width: 52px; height: 52px; }

/* Opening pill (v0.75): inline status badge below the play status line
   that names the book opening matching the moves played so far. Click
   does nothing (informational); ECO badge is muted. */
.play-opening-pill {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 8px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--bg-3);
  color: var(--text); font-size: 13px; line-height: 1.2;
  max-width: 100%; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis;
}
.play-opening-pill[hidden] { display: none; }
.play-opening-pill .op-icon { opacity: 0.75; }
.play-opening-pill .op-name { font-weight: 600; }
/* .play-opening-pill .op-eco removed v0.140.13 - Jose: no more ECO badges anywhere */

.play-over-actions { display: flex; gap: 8px; margin-top: 12px; justify-content: flex-end; }

/* ============================================================ */
/*  WELCOME page (v0.76)                                        */
/* ============================================================ */
.welcome-view {
  padding: 72px 40px 80px;
  max-width: 1100px;
  margin: 0 auto;
  position: relative;
}
.welcome-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin: 0 auto 28px;
  color: var(--text);
}
.welcome-brand-mark {
  display: block;
  width: 88px;
  height: 88px;
  color: var(--accent);
}
.welcome-brand-mark svg { width: 100%; height: 100%; display: block; }
.welcome-brand-word {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 30px;
  letter-spacing: 0.2px;
  line-height: 1;
  color: var(--text);
}
.welcome-hero {
  margin-bottom: 32px;
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: nowrap;
}
.welcome-avatar {
  flex: 0 0 auto;
  width: 112px; height: 112px;
  padding: 0;
  border: none;
  border-radius: 18px;
  /* v0.156.0: default to a neutral light-gray chip so the unthemed
     hero feels calm; per-season rules at lines 565/569/573/788 still
     win for Christmas/Halloween/Pride/Codex via higher specificity. */
  background: var(--bg-3);
  color: var(--text-dim);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  overflow: hidden;
  transition: transform 100ms ease, box-shadow 120ms ease;
  box-shadow: 0 2px 10px rgba(0,0,0,0.25);
}
.welcome-avatar:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0,0,0,0.35); }
.welcome-avatar:active { transform: translateY(0); }
.welcome-avatar > svg { width: 68%; height: 68%; }
.welcome-avatar > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.welcome-avatar > .avatar-glyph {
  font-family: "DejaVu Sans", "Segoe UI Symbol", serif;
  font-size: 72px; line-height: 1;
  user-select: none;
}
.welcome-hero-text { flex: 1 1 auto; min-width: 0; }
.welcome-greeting {
  color: var(--text-dim);
  font-size: 17px;
  margin: 0 0 6px;
  font-weight: 500;
}
.welcome-username {
  font-family: var(--serif);
  font-size: 44px;
  line-height: 1.05;
  color: var(--text);
  margin: 0;
  word-break: break-word;
}
/* v0.82: .welcome-upgrade removed (no paywall planned). The hero text
   block now stretches across the remaining row width. */

/* "Play vs Bot" CTA card sits between the hero and the stat grid.
   Wired in loadWelcome() to navigate to the Play page. */
.welcome-cta {
  appearance: none;
  display: flex; align-items: center; gap: 16px;
  width: 100%;
  padding: 16px 22px;
  margin-bottom: 22px;
  border: 1px solid var(--bg-3);
  border-radius: 14px;
  background: linear-gradient(135deg, var(--bg-2) 0%, var(--bg-3) 100%);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: transform 100ms ease, border-color 120ms ease, background 120ms ease;
}
.welcome-cta:hover { border-color: var(--accent); transform: translateY(-1px); }
.welcome-cta:active { transform: translateY(0); }
.welcome-cta-icon {
  flex: 0 0 auto;
  width: 44px; height: 44px; border-radius: 10px;
  background: rgba(255,255,255,0.06);
  display: flex; align-items: center; justify-content: center;
  color: var(--text);
}
.welcome-cta-icon svg { width: 60%; height: 60%; }
.welcome-cta-text {
  flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px;
  text-align: left;
}
.welcome-cta-title { font-family: var(--serif); font-weight: 700; font-size: 20px; color: var(--text); }
.welcome-cta-sub   { font-size: 13px; color: var(--text-dim); }
.welcome-cta-go {
  flex: 0 0 auto;
  padding: 8px 22px;
  border-radius: 999px;
  background: rgba(255,255,255,0.08);
  color: var(--text);
  font-weight: 700; font-size: 13.5px;
}
.welcome-cta:hover .welcome-cta-go { background: var(--accent); color: var(--on-accent); }

/* Small popover that opens under the avatar. Lazy-rendered in JS
   (presets injected on first open) and absolutely positioned. */
.avatar-picker {
  position: absolute;
  z-index: 60;
  padding: 14px 16px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(0,0,0,0.45);
  min-width: 240px;
  max-width: 320px;
  display: flex; flex-direction: column; gap: 12px;
}
.avatar-picker[hidden] { display: none; }
.avatar-picker-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.8px;
  color: var(--text-dim); font-weight: 700;
}
.avatar-picker-presets {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.avatar-picker-presets button {
  appearance: none;
  width: 100%; aspect-ratio: 1 / 1;
  border-radius: 10px;
  border: 1px solid var(--bg-3);
  background: var(--bg-2);
  color: var(--text);
  font-size: 28px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: transform 100ms ease, border-color 120ms ease, background 120ms ease;
}
.avatar-picker-presets button:hover { border-color: var(--accent); transform: translateY(-1px); }
.avatar-picker-presets button.active {
  border-color: var(--accent);
  background: var(--bg-3);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.avatar-picker-presets button svg { width: 70%; height: 70%; }
/* v0.155.1: avatar background-color picker - row of solid color swatches
   the user can apply to the welcome-avatar slot. Default chip resets to
   the per-theme/season gradient. Selected color is stored in localStorage
   key `avatar_bg_v1` and applied as an inline style on #welcomeAvatar so it
   wins over the per-season .welcome-avatar background rules. */
.avatar-picker-subtitle {
  margin: 4px 2px 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.avatar-picker-bg-row {
  display: flex; flex-wrap: wrap; gap: 7px;
  margin-bottom: 10px;
}
.avatar-picker-bg-row button {
  width: 28px; height: 28px;
  border: 2px solid transparent;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  position: relative;
  transition: transform 100ms ease, border-color 120ms ease;
  background-clip: padding-box;
}
.avatar-picker-bg-row button:hover { transform: translateY(-1px) scale(1.08); }
.avatar-picker-bg-row button.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--bg-1), 0 0 0 4px var(--accent);
}
.avatar-picker-bg-row button[data-avatar-bg="default"] {
  background:
    linear-gradient(135deg, transparent 47%, var(--text-dim) 47%, var(--text-dim) 53%, transparent 53%),
    var(--bg-2);
}
.avatar-picker-upload {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 9px 14px;
  border: 1px dashed var(--bg-3);
  border-radius: 10px;
  cursor: pointer;
  font-weight: 600; font-size: 13px;
  color: var(--text-dim);
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.avatar-picker-upload:hover { border-color: var(--accent); color: var(--text); background: var(--bg-2); }
.welcome-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}
.welcome-card {
  appearance: none;
  text-align: left;
  border: 1px solid var(--bg-3);
  background: var(--bg-2);
  color: var(--text);
  border-radius: 14px;
  padding: 18px 20px 20px;
  cursor: pointer;
  transition: transform 90ms ease, border-color 90ms ease, background 90ms ease;
  font: inherit;
  display: flex; flex-direction: column; gap: 6px;
  min-height: 108px;
}
.welcome-card:hover {
  border-color: var(--accent, #88aaff);
  background: var(--bg-3);
  transform: translateY(-1px);
}
.welcome-card:active { transform: translateY(0); }
.welcome-card-label {
  color: var(--text-dim);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  font-weight: 600;
}
.welcome-card-value {
  font-family: var(--serif);
  font-size: 30px;
  line-height: 1.05;
  color: var(--text);
}
.welcome-card-sub {
  color: var(--text-faint);
  font-size: 13px;
  margin-top: auto;
}
/* v0.181.1: inline retry link inside a "Couldn't load X" subtitle. Lets
   the user re-fetch just one card after a transient network/server blip,
   without the alarm of a hard page refresh. */
.welcome-card-sub .wc-retry {
  margin-left: 6px;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 600;
}
.welcome-card-sub .wc-retry:hover { opacity: 0.85; }
.welcome-card-wide {
  grid-column: 1 / -1;
}
.welcome-card-wide .welcome-card-value {
  font-size: 22px;
  font-family: inherit;
  font-weight: 600;
}

/* ============================================================ */
/*  Sync from chess.com button (v0.77)                          */
/* ============================================================ */
.sync-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px;
  border-radius: 999px;
  border: 1px solid var(--bg-3);
  background: var(--bg-2);
  color: var(--text);
  font: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer;
  transition: transform 90ms ease, border-color 90ms ease, background 90ms ease;
  white-space: nowrap;
}
.sync-btn:hover:not(:disabled) {
  border-color: var(--accent, #88aaff);
  transform: translateY(-1px);
}
.sync-btn:active:not(:disabled) { transform: translateY(0); }
.sync-btn:disabled {
  opacity: 0.7;
  cursor: progress;
}
.sync-btn .sync-icon {
  display: inline-block;
  font-size: 16px;
  line-height: 1;
}
.sync-btn.is-syncing .sync-icon {
  animation: syncSpin 0.9s linear infinite;
}
.icon-btn.is-syncing { opacity: 0.7; cursor: progress; }
.icon-btn.is-syncing::before {
  content: "";
  display: inline-block;
  width: 12px; height: 12px; margin-right: 6px; vertical-align: -2px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: syncSpin 0.7s linear infinite;
}
@keyframes syncSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ============================================================ */
/*  Endgame trainer: "From your games" random-pick pill (v0.76) */
/* ============================================================ */
.trainer-rand-pill {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 14px 22px;
  border-radius: 999px;
  border: 1px solid var(--bg-3);
  background: linear-gradient(135deg, var(--bg-2), var(--bg-3));
  color: var(--text);
  font: inherit; font-size: 15px; font-weight: 600;
  cursor: pointer;
  transition: transform 90ms ease, border-color 90ms ease, box-shadow 90ms ease;
}
.trainer-rand-pill:hover {
  border-color: var(--accent, #88aaff);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(0,0,0,0.18);
}
.trainer-rand-pill:active { transform: translateY(0); }
.trainer-rand-pill .trainer-rand-emoji { font-size: 18px; }
.trainer-rand-pill .trainer-rand-count {
  color: var(--text-dim); font-size: 12.5px;
  padding: 3px 9px; border-radius: 999px;
  background: var(--bg-1); border: 1px solid var(--bg-3);
  font-weight: 600; letter-spacing: 0.3px;
}
.trainer-section-personal .trainer-rand-pill {
  margin-bottom: 8px;
}

/* ============================================================ */
/*  STATS page                                                  */
/* ============================================================ */
.stats-view { padding: 30px 36px; max-width: 1280px; margin: 0 auto; }
.stats-hero { display: flex; align-items: baseline; gap: 14px; margin-bottom: 22px; }
.stats-hero h1 { font-family: var(--serif); font-size: 28px; color: var(--text); margin: 0; }
.stats-sub { color: var(--text-faint); font-size: 14px; }
.stats-loading { color: var(--text-dim); font-style: italic; padding: 20px 0; }

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px; margin-bottom: 24px;
}
.stat-card {
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 12px; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 4px;
}
.stat-card .lbl {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.6px;
  color: var(--text-faint); font-weight: 600;
}
.stat-card .val {
  font-family: var(--serif); font-size: 26px; color: var(--text); font-weight: 700;
}
.stat-card .sub { font-size: 12px; color: var(--text-dim); }
.stat-card.accent .val { color: var(--accent); }

.stats-charts { display: grid; gap: 18px; grid-template-columns: 1fr; }
@media (min-width: 1100px) { .stats-charts { grid-template-columns: 1fr 1fr; } }
.stats-chart-card {
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 12px; padding: 14px 16px;
}
.stats-chart-card h3 { margin: 0 0 10px; font-size: 15px; color: var(--text); font-weight: 600; }
.stats-chart-card .chart-wrap { position: relative; height: 240px; }
.stats-chart-card.full { grid-column: 1 / -1; }

.stats-list { list-style: none; margin: 0; padding: 0; }
.stats-list li {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 0; border-bottom: 1px solid var(--bg-3);
}
.stats-list li:last-child { border-bottom: none; }
.stats-list .nm { flex: 1; color: var(--text); font-size: 13px; }
.stats-list .ct { color: var(--text-dim); font-family: "JetBrains Mono", monospace; font-size: 12px; }
.stats-list .rec { color: var(--text-faint); font-size: 11.5px; font-family: "JetBrains Mono", monospace; }

.stats-mq { display: flex; gap: 8px; flex-wrap: wrap; }
.stats-mq .pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px;
  background: var(--bg-1); border: 1px solid var(--bg-3);
  font-size: 12px; color: var(--text);
}
.stats-mq .pill .ct { color: var(--text-dim); font-family: "JetBrains Mono", monospace; }

/* ============================================================
   Settings page (accessed via the gear icon in the navrail).
   Sections: Appearance / Pieces / Sound / Motion.
   Each row has a left label/description and a right control.
   ============================================================ */
.settings-view {
  max-width: 880px; margin: 0 auto;
  padding: 24px 28px 64px;
  display: flex; flex-direction: column; gap: 24px;
}
.settings-hero { display: flex; flex-direction: column; gap: 4px; }
.settings-hero h1 {
  font-family: var(--serif); font-weight: 700; font-size: 30px;
  color: var(--text); margin: 0;
}
.settings-sub { font-size: 13.5px; color: var(--text-dim); }

.settings-section {
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 14px; padding: 18px 20px;
  display: flex; flex-direction: column; gap: 4px;
}
.settings-section-title {
  font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--text-dim);
  margin: 0 0 10px;
}
.settings-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; padding: 12px 0;
  border-top: 1px solid var(--bg-3);
}
.settings-row:first-of-type { border-top: none; }
.settings-row-label { flex: 1 1 auto; min-width: 0; }
.settings-row-name {
  font-size: 14px; color: var(--text); font-weight: 600;
}
.settings-row-desc {
  font-size: 12.5px; color: var(--text-dim); margin-top: 2px;
  line-height: 1.4;
}

.settings-select {
  background: var(--bg-1); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 8px;
  padding: 6px 10px; font: inherit; font-size: 13px;
  min-width: 120px; cursor: pointer;
}
.settings-range {
  width: 200px; accent-color: var(--accent);
}


/* Piece-set grid: each tile shows a king + queen preview rendered from
   the bundled local SVG sets (lichess-org/lila, GPL - see THIRD_PARTY.md). */
.settings-piece-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 8px; min-width: 340px; max-width: 560px;
}
.settings-piece-tile {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 8px; background: var(--bg-1);
  border: 1px solid var(--bg-3); border-radius: 10px;
  cursor: pointer; transition: border-color 120ms, transform 120ms;
  color: var(--text); font: inherit; font-size: 12.5px; font-weight: 600;
}
.settings-piece-tile:hover { border-color: var(--accent); transform: translateY(-1px); }
.settings-piece-tile.active {
  border-color: var(--accent); background: var(--accent-soft); color: var(--accent);
}
.settings-piece-preview {
  display: flex; align-items: center; justify-content: center; gap: 2px;
  background: var(--light-sq);
  border-radius: 6px; padding: 4px;
}
.settings-piece-preview img {
  width: 32px; height: 32px;
}

/* v0.195.34: Board theme picker. Mirrors .settings-piece-tile so it
   sits comfortably above the piece grid in Settings > Board & Pieces.
   Each swatch is a 2x2 grid that previews the season's light/dark
   squares. Uses literal hex values from STATE.boardSeason tiles
   (not the live --light-sq/--dark-sq vars) so every tile keeps its
   own colour preview regardless of the active season. */
.settings-board-seasons {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 8px; min-width: 340px; max-width: 560px;
}
/* v0.195.157: last-move highlight colour picker row. */
.settings-lastmove-row {
  display: flex; align-items: center; gap: 12px;
}
.settings-lastmove-row input[type="color"] {
  width: 52px; height: 36px; padding: 2px;
  background: var(--bg-1); border: 1px solid var(--bg-3);
  border-radius: 8px; cursor: pointer;
}
.settings-lastmove-reset { font-size: 13px; }
.settings-board-tile {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 8px; background: var(--bg-1);
  border: 1px solid var(--bg-3); border-radius: 10px;
  cursor: pointer; transition: border-color 120ms, transform 120ms;
  color: var(--text); font: inherit; font-size: 12.5px; font-weight: 600;
}
.settings-board-tile:hover { border-color: var(--accent); transform: translateY(-1px); }
.settings-board-tile.active {
  border-color: var(--accent); background: var(--accent-soft); color: var(--accent);
}
.settings-board-swatch {
  display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
  gap: 0; width: 56px; height: 56px;
  border-radius: 6px; overflow: hidden;
  border: 1px solid var(--bg-4);
}
.settings-board-swatch > span { display: block; width: 100%; height: 100%; }
/* v0.195.38: single solid swatch for the colour palette picker (one
   chip per palette instead of the four-square board preview). */
.settings-palette-swatch {
  display: block; width: 56px; height: 56px;
  border-radius: 14px; border: 1px solid var(--bg-4);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25) inset;
}

/* ============================================================
   Settings -> About (v0.98). Compact key/value rows for version
   + license info, followed by the non-affiliation disclaimer and
   third-party credits paragraph.
   ============================================================ */
.settings-about { display: flex; flex-direction: column; gap: 8px; }
.settings-about-row {
  display: flex; gap: 12px; align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px solid var(--bg-2);
}
.settings-about-row:last-of-type { border-bottom: 0; }
.settings-about-key {
  min-width: 110px;
  font-size: 12.5px; font-weight: 600;
  color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.05em;
}
.settings-about-val { font-size: 13.5px; color: var(--text); }
.settings-about-val a { color: var(--accent); text-decoration: none; }
.settings-about-val a:hover { text-decoration: underline; }
.settings-about-disclaimer {
  margin: 12px 0 4px;
  padding: 10px 12px;
  background: var(--bg-2);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  font-size: 12.5px; color: var(--text-dim);
  line-height: 1.5;
}
.settings-about-disclaimer strong { color: var(--text); }
.settings-about-credits {
  margin: 6px 0 0;
  font-size: 12px; color: var(--text-faint); line-height: 1.55;
}
.settings-about-credits a { color: var(--text-dim); text-decoration: underline; }
.settings-about-credits a:hover { color: var(--accent); }

/* ============================================================
   Puzzles page (Lichess CC0 dataset).
   Layout: hero with attribution, difficulty pill row, then a
   two-column board+side panel that collapses on narrow viewports.
   ============================================================ */
.puzzles-view {
  max-width: 1120px; margin: 0 auto;
  padding: 32px 28px 64px;
  display: flex; flex-direction: column; gap: 24px;
}
.puzzles-hero { display: flex; flex-direction: column; gap: 6px; }
.puzzles-hero h1 {
  font-family: var(--serif); font-weight: 700; font-size: 38px;
  color: var(--accent); margin: 0 0 4px;
}
.puzzles-sub { font-size: 13.5px; color: var(--text-dim); }
.puzzles-sub a { color: var(--accent); text-decoration: none; }
.puzzles-sub a:hover { text-decoration: underline; }

.puz-difficulty-row {
  display: flex; flex-wrap: wrap; gap: 8px;
}
/* ---- Daily puzzle banner ---- */
.puz-daily {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 14px 18px;
  background: linear-gradient(135deg, var(--bg-2), var(--bg-1));
  border: 1px solid var(--accent); border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.25);
}
.puz-daily-left { display: flex; flex-direction: column; gap: 2px; }
.puz-daily-right { display: flex; align-items: center; gap: 18px; }
.puz-daily-label {
  font-size: 10px; letter-spacing: 1.6px; font-weight: 700;
  color: var(--accent); text-transform: uppercase;
}
.puz-daily-date {
  font-family: var(--serif); font-size: 20px; font-weight: 700;
  color: var(--text);
}
.puz-daily-meta {
  display: flex; align-items: center; gap: 10px;
  font-size: 12.5px; color: var(--text-dim);
}
.puz-daily-rating {
  background: var(--bg-3); border-radius: 6px; padding: 2px 8px;
  font-weight: 700; color: var(--text);
}
.puz-daily-status.solved { color: #6ec84e; font-weight: 600; }
.puz-daily-streak {
  display: flex; flex-direction: column; align-items: center;
  padding: 4px 10px;
  border-right: 1px solid var(--bg-3);
}
.puz-daily-streak-n {
  font-family: var(--serif); font-size: 24px; font-weight: 800;
  color: var(--accent); line-height: 1;
}
.puz-daily-streak-l {
  font-size: 10px; letter-spacing: 1px; color: var(--text-dim);
  text-transform: uppercase; margin-top: 2px;
}

/* Puzzle Rush banner -- a sibling of .puz-daily that toggles between a
 * "start" pitch and a live "score / strikes / timer" readout. */
.puz-rush {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 12px 18px;
  background: linear-gradient(135deg, rgba(255, 90, 60, 0.10), var(--bg-2));
  border: 1px solid rgba(255, 90, 60, 0.55); border-radius: 12px;
}
.puz-rush-left { display: flex; flex-direction: column; gap: 2px; }
.puz-rush-right { display: flex; align-items: center; gap: 14px; }
.puz-rush-label {
  font-size: 10px; letter-spacing: 1.6px; font-weight: 700;
  color: #ff7a55; text-transform: uppercase;
}
.puz-rush-sub { font-size: 12.5px; color: var(--text-dim); }
.puz-rush-stats {
  display: flex; align-items: center; gap: 12px;
  padding: 4px 12px; border-right: 1px solid var(--bg-3);
}
.puz-rush-timer {
  font-family: var(--serif); font-size: 22px; font-weight: 800;
  color: var(--text); min-width: 60px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.puz-rush-timer.urgent { color: #ff7a55; animation: rushPulse 0.7s ease-in-out infinite alternate; }
@keyframes rushPulse { from { transform: scale(1); } to { transform: scale(1.06); } }
.puz-rush-score {
  font-family: var(--serif); font-size: 20px; font-weight: 800;
  color: var(--accent); min-width: 30px; text-align: center;
}
.puz-rush-strikes { font-size: 16px; letter-spacing: 4px; color: var(--text-dim); }
.puz-rush-strikes .struck { color: #ff5a3c; font-weight: 700; }
.puz-rush-best {
  display: flex; flex-direction: column; align-items: center;
}
.puz-rush-best-n {
  font-family: var(--serif); font-size: 22px; font-weight: 800;
  color: #ff7a55; line-height: 1;
}
.puz-rush-best-l {
  font-size: 10px; letter-spacing: 1px; color: var(--text-dim);
  text-transform: uppercase; margin-top: 2px;
}
.puz-diff-btn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 8px 14px;
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 10px;
  font: inherit; cursor: pointer;
  transition: border-color 120ms, transform 120ms, background 120ms;
  min-width: 110px;
}

/* "Lessons from your games" banner - mined from the user's own MISS /
 * MISTAKE / BLUNDER moves in their analysed library. Visually distinct
 * from Daily (accent-tinted) and Rush (orange-tinted) - uses a soft
 * teal-ish coach palette so the user can tell the three banners apart
 * at a glance. */
.puz-personal {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 12px 18px;
  background: linear-gradient(135deg, rgba(60, 200, 170, 0.10), var(--bg-2));
  border: 1px solid rgba(60, 200, 170, 0.55); border-radius: 12px;
}
.puz-personal-left  { display: flex; flex-direction: column; gap: 2px; }
.puz-personal-right { display: flex; align-items: center; gap: 14px; }
.puz-personal-label {
  font-size: 10px; letter-spacing: 1.6px; font-weight: 700;
  color: #3ccaa3; text-transform: uppercase;
}
.puz-personal-sub { font-size: 12.5px; color: var(--text-dim); }
.puz-personal-progress {
  display: flex; align-items: baseline; gap: 4px;
  padding: 4px 12px; border-right: 1px solid var(--bg-3);
}
.puz-personal-progress-n {
  font-family: var(--serif); font-size: 22px; font-weight: 800; color: #3ccaa3;
}
.puz-personal-progress-l {
  font-size: 11px; letter-spacing: 0.6px; color: var(--text-dim);
}

/* Personal-lesson context card: revealed below the puzzle controls when
 * a personal puzzle is solved or failed, so the user can compare what
 * they originally played against what the engine wanted. */
.puz-personal-context {
  display: flex; flex-direction: column; gap: 4px;
  margin-top: 10px; padding: 10px 12px;
  background: var(--bg-2); border: 1px solid var(--bg-3); border-radius: 10px;
  font-size: 13px;
}
.puz-personal-context .ppc-row {
  display: flex; align-items: baseline; gap: 8px;
}
.puz-personal-context .ppc-k {
  flex: 0 0 100px; color: var(--text-dim); font-size: 11.5px;
  letter-spacing: 0.4px; text-transform: uppercase;
}
.puz-personal-context .ppc-v {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-weight: 700;
}
.puz-personal-context .ppc-bad  { color: #ff7a55; }
.puz-personal-context .ppc-good { color: #6ec84e; }
.puz-personal-context .ppc-loss {
  color: var(--text-dim); font-size: 11.5px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
}
.puz-personal-context .ppc-meta {
  margin-top: 4px; padding-top: 6px; border-top: 1px dashed var(--bg-3);
  font-size: 12px; color: var(--text-dim);
}
.puz-personal-context .ppc-meta a {
  color: var(--accent); text-decoration: none;
}
.puz-personal-context .ppc-meta a:hover { text-decoration: underline; }

/* Spaced-repetition review banner - purple/violet accent so it visually
 * stacks with Daily (accent), Rush (orange), and Personal (teal) without
 * collision. Only renders when there are puzzles due, so the puzzles
 * page stays clean for new users with empty SRS queues. */
.puz-srs {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 12px 18px;
  background: linear-gradient(135deg, rgba(150, 110, 230, 0.12), var(--bg-2));
  border: 1px solid rgba(150, 110, 230, 0.55); border-radius: 12px;
}
.puz-srs-left  { display: flex; flex-direction: column; gap: 2px; }
.puz-srs-right { display: flex; align-items: center; gap: 14px; }
.puz-srs-label {
  font-size: 10px; letter-spacing: 1.6px; font-weight: 700;
  color: #a890ee; text-transform: uppercase;
}
.puz-srs-sub  { font-size: 12.5px; color: var(--text-dim); }
.puz-srs-stats {
  display: flex; align-items: baseline; gap: 4px;
  padding: 4px 12px; border-right: 1px solid var(--bg-3);
}
.puz-srs-due {
  font-family: var(--serif); font-size: 22px; font-weight: 800; color: #a890ee;
}
.puz-srs-due-l {
  font-size: 11px; letter-spacing: 0.6px; color: var(--text-dim);
}
/* Repertoire drill banner (v0.70) - amber accent so it's visually
   distinct from the purple SRS banner and pink personal banner. */
.puz-rep {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 12px 18px;
  background: linear-gradient(135deg, rgba(247, 194, 69, 0.14), var(--bg-2));
  border: 1px solid rgba(247, 194, 69, 0.50); border-radius: 12px;
}
.puz-rep-left  { display: flex; flex-direction: column; gap: 2px; }
.puz-rep-right { display: flex; align-items: center; gap: 14px; }
.puz-rep-label {
  font-size: 10px; letter-spacing: 1.6px; font-weight: 700;
  color: #e9b341; text-transform: uppercase;
}
.puz-rep-sub  { font-size: 12.5px; color: var(--text-dim); }
.puz-rep-progress {
  display: flex; align-items: baseline; gap: 4px;
  padding: 4px 12px; border-right: 1px solid var(--bg-3);
}
.puz-rep-progress-n {
  font-family: var(--serif); font-size: 22px; font-weight: 800; color: #e9b341;
}
.puz-rep-progress-l {
  font-size: 11px; letter-spacing: 0.6px; color: var(--text-dim);
}
.puz-diff-btn:hover { border-color: var(--accent); transform: translateY(-1px); }
.puz-diff-btn.active {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}
.puz-diff-btn .pdb-name { font-weight: 700; font-size: 14px; }
.puz-diff-btn .pdb-range {
  font-size: 11.5px; color: var(--text-dim);
  font-family: "JetBrains Mono", ui-monospace, monospace;
}
.puz-diff-btn.active .pdb-range { color: var(--accent); }

/* Theme filter chips: smaller than difficulty pills, scrollable on
   narrow screens. "All" lives in the same row as the first chip and is
   the default selection. */
.puz-theme-filter {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.puz-theme-chip {
  padding: 4px 10px;
  font: inherit; font-size: 12px; letter-spacing: 0.2px;
  background: var(--bg-2); color: var(--text-dim);
  border: 1px solid var(--bg-3); border-radius: 14px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.puz-theme-chip:hover { color: var(--accent); border-color: var(--accent); }
.puz-theme-chip.active {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}

/* Last-N-attempts history strip. Each chip is a tiny square showing
   ✓ green for solved, ✗ red for failed, ◯ muted for revealed/skipped.
   The most-recent attempt is on the right. */
.puz-history {
  display: flex; align-items: center; gap: 4px;
  min-height: 16px;
  color: var(--text-faint); font-size: 10.5px; letter-spacing: 1px;
}
.puz-history-label {
  text-transform: uppercase; margin-right: 4px;
}
.puz-h-chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 4px;
  font-size: 10px; font-weight: 700; line-height: 1;
  background: var(--bg-3); color: var(--text-faint);
  border: 1px solid transparent;
}
.puz-h-chip.ok   { background: rgba(110,200,78,0.22); color: #6ec84e; border-color: rgba(110,200,78,0.35); }
.puz-h-chip.fail { background: rgba(220,80,80,0.22); color: #e26060; border-color: rgba(220,80,80,0.35); }
.puz-h-chip.skip { background: var(--bg-3); color: var(--text-faint); }
.puz-h-empty {
  font-size: 11px; font-style: italic; color: var(--text-faint);
  letter-spacing: 0;
}

/* =====================================================================
 * Per-theme performance panel (v0.60). Aggregates from puzzle history.
 * ===================================================================== */
.puz-tstats {
  margin: 8px 0 12px;
  padding: 12px 14px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 10px;
}
.puz-tstats-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 8px;
}
.puz-tstats-label {
  font-size: 11px; font-weight: 700;
  letter-spacing: 1.2px; color: var(--text-dim);
}
.puz-tstats-hint { font-size: 11px; color: var(--text-faint); font-style: italic; }
.puz-tstat-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 6px 18px;
}
.puz-tstat-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 60px 42px 36px;
  align-items: center; gap: 8px;
  font-size: 12px;
}
.puz-tstat-theme {
  color: var(--text); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.puz-tstat-bar {
  position: relative; height: 6px; background: var(--bg-3); border-radius: 3px; overflow: hidden;
}
.puz-tstat-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; }
.puz-tstat-fill-ok  { background: #6ec84e; }
.puz-tstat-fill-mid { background: #f7c245; }
.puz-tstat-fill-bad { background: #e26060; }
.puz-tstat-num { color: var(--text-faint); font-variant-numeric: tabular-nums; text-align: right; }
.puz-tstat-acc { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.puz-tstat-acc-ok  { color: #6ec84e; }
.puz-tstat-acc-mid { color: #f7c245; }
.puz-tstat-acc-bad { color: #e26060; }


/* =================================================================
 * Mode picker bar (v0.155.0) - replaces the old stack of always-
 * visible banner cards.  One bar, six mode buttons; clicking shows
 * only the active mode's content panel above the board.
 * ================================================================= */
.puz-mode-bar {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 4px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 14px;
}
.puz-mode-btn {
  padding: 7px 16px;
  background: transparent; color: var(--text-dim);
  border: 1px solid transparent; border-radius: 10px;
  font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.puz-mode-btn:hover { color: var(--text); background: var(--bg-3); }
.puz-mode-btn.active {
  color: var(--accent); border-color: var(--accent);
  background: var(--accent-soft); font-weight: 700;
}

/* Mentor panel (v0.156.0) - lives inside .puz-card between the status
   line and the theme chips. Same visual language as the Openings-page
   Mentor (.op-mentor-box) so users recognise it across modes. Hidden
   by default; puzMentorSay(text) reveals + populates it. */
.puz-mentor-box {
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 10px;
  border-left: 3px solid var(--accent);
  padding: 10px 12px;
  margin: 4px 0 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.puz-mentor-head {
  display: flex; align-items: center; gap: 6px;
  margin-bottom: 4px;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.8px; color: var(--accent);
}
.puz-mentor-icon { font-size: 12px; }
.puz-mentor-title { color: var(--accent); }
.puz-mentor-text {
  font-size: 13.5px; line-height: 1.5; color: var(--text);
}
.puz-mentor-text.puz-mentor-hint { color: var(--cat-inaccuracy, #f7c245); }
.puz-mentor-text.puz-mentor-bad  { color: var(--cat-mistake,    #e26060); }
.puz-mentor-text.puz-mentor-ok   { color: var(--cat-good,       #b8d488); }

/* Mode content panels - one visible at a time. v0.156.0: flex column
   with gap so the difficulty pills and theme-filter chips inside
   #puzModeContent-random no longer crowd / visually overlap each
   other on wrap. Single-child panels (daily/rush/lessons/spaced)
   are unaffected. */
.puz-mode-content {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 4px;
}
/* v0.161.0 - restore the [hidden] attribute. Author rule above wins over
   the UA's [hidden]{display:none} because they have identical specificity,
   so without this override all 6 mode panels (Daily/Rush/Lessons/Spaced/
   Repertoire) render at once even when "Random" is active. */
.puz-mode-content[hidden] { display: none; }

/* =================================================================
 * Collapsible stats drawer (v0.155.0) - history + per-theme chart
 * live here instead of above the board.  Default: collapsed.
 * ================================================================= */
.puz-stats-section {
  margin-top: 4px;
}
.puz-stats-toggle {
  width: 100%; text-align: left;
  padding: 8px 14px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3); border-radius: 8px;
  color: var(--text-dim);
  font: inherit; font-size: 12.5px;
  cursor: pointer;
  transition: color 100ms, background 100ms;
}
.puz-stats-toggle:hover { color: var(--text); background: var(--bg-3); }
.puz-stats-drawer {
  margin-top: 6px;
  display: flex; flex-direction: column; gap: 8px;
}

/* Mobile: mode bar wraps naturally; stats drawer is already full-width. */
@media (max-width: 860px) {
  .puz-mode-btn { padding: 6px 12px; font-size: 12px; }
}

.puz-layout {
  display: grid; grid-template-columns: minmax(0, 1fr) 340px;
  gap: 24px; align-items: start;
}
@media (max-width: 980px) {
  .puz-layout { grid-template-columns: 1fr; }
  .puz-side { order: -1; }
}

@media (max-width: 620px) {
  .puzzles-view { padding: 20px 16px 48px; gap: 16px; }
  .puz-daily, .puz-rush, .puz-personal, .puz-srs, .puz-rep {
    flex-direction: column; align-items: flex-start; gap: 12px;
  }
  .puz-daily-right, .puz-rush-right, .puz-personal-right,
  .puz-srs-right, .puz-rep-right { flex-wrap: wrap; }
  .puzzles-hero h1 { font-size: 30px; }
}

.puz-board-wrap {
  border-radius: 8px; overflow: hidden;
  box-shadow: var(--board-glow), 0 0 0 1px var(--board-ring);
  /* v0.195.168: enlarge the puzzle board. Lucas felt the v0.195.44 cap of
     560px made it too small. Raised to 680px; the side panel column stays
     fixed at 360px so the board absorbs the extra width on wide screens. */
  width: 100%;
  max-width: 680px;
  margin: 0 auto;
}
.puz-board {
  display: block; width: 100%; height: auto;
  /* board internals (.square-light/.square-dark, .last-move, .coord, etc.)
     are styled higher up in this file */
}

.puz-side {
  display: flex; flex-direction: column; gap: 14px;
}
.puz-stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.puz-stat {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 14px 6px;
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 10px;
}
.puz-stat .ps-k {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.8px;
  color: var(--text-dim);
}
.puz-stat .ps-v {
  font-size: 22px; font-weight: 700; color: var(--text);
  font-family: "JetBrains Mono", ui-monospace, monospace;
}

.puz-card {
  background: var(--bg-2); border: 1px solid var(--bg-3);
  border-radius: 12px; padding: 16px;
  display: flex; flex-direction: column; gap: 10px;
}
.puz-card-row {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.puz-rating-pill {
  padding: 4px 10px;
  background: var(--bg-1); border: 1px solid var(--bg-3);
  border-radius: 999px;
  font-size: 12px; font-weight: 600;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  color: var(--text);
}
.puz-turn {
  font-size: 12.5px; color: var(--text-dim);
}
.puz-status {
  font-size: 15px; line-height: 1.5; color: var(--text);
  min-height: 52px; font-weight: 500; padding: 4px 0;
}
.puz-status.ok { color: #5bbf7a; }
.puz-status.bad { color: #d97a6e; }
.puz-status.hint { color: var(--accent); }
.puz-themes {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.puz-theme-tag {
  font-size: 11px; padding: 2px 8px;
  background: var(--bg-1); border: 1px solid var(--bg-3);
  border-radius: 999px; color: var(--text-dim);
}
.puz-controls {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px;
}
.puz-btn {
  padding: 8px 12px; font: inherit; font-size: 13px;
  background: var(--bg-1); color: var(--text);
  border: 1px solid var(--bg-3); border-radius: 8px;
  cursor: pointer;
  transition: border-color 120ms, background 120ms;
}
.puz-btn:hover:not(:disabled) { border-color: var(--accent); }
.puz-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.puz-btn-primary {
  grid-column: 1 / -1;
  background: var(--accent); color: var(--bg-1);
  border-color: var(--accent); font-weight: 600;
}
.puz-btn-primary:hover:not(:disabled) { filter: brightness(1.05); }
.puz-meta {
  font-size: 12px; color: var(--text-dim);
  display: flex; justify-content: flex-end;
}
.puz-meta a { color: var(--accent); text-decoration: none; }
.puz-meta a:hover { text-decoration: underline; }


/* ============================================================ */
/* v0.83 multi-user: Switch user button + user picker modal     */
/* ============================================================ */
.welcome-switch-user {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--border, rgba(255,255,255,0.12));
  border-radius: 999px;
  padding: 4px 12px;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  margin-top: 8px;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.welcome-switch-user:hover {
  background: var(--accent-bg, rgba(255,255,255,0.06));
  color: var(--text);
  border-color: var(--accent, #c9a96e);
}

/* ===================================================================
   First-run product tour (v0.195.171)
   PowerPoint-style intro slideshow shown once ever to new visitors.
   Theme-safe neutral overlays so it reads on both dark and light.
   =================================================================== */
.tour-backdrop {
  position: fixed; inset: 0; z-index: 9500;
  background: rgba(0, 0, 0, 0.66);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  backdrop-filter: blur(4px);
}
.tour-backdrop[hidden] { display: none; }
.tour-modal {
  position: relative;
  background:
    radial-gradient(120% 130% at 0% 0%, rgba(var(--accent-rgb), 0.16), transparent 55%),
    var(--bg-1, #141416);
  color: var(--text-primary, #fafaf7);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.10));
  border-radius: 18px;
  width: 100%; max-width: 560px;
  box-shadow: 0 40px 80px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  display: flex; flex-direction: column;
}
.tour-close {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  width: 32px; height: 32px; border-radius: 8px;
  background: rgba(128, 128, 140, 0.14); color: var(--text-secondary);
  border: 1px solid transparent; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; transition: background 0.12s, color 0.12s;
}
.tour-close:hover { background: rgba(128, 128, 140, 0.24); color: var(--text-primary); }
.tour-viewport { overflow: hidden; }
.tour-track {
  display: flex;
  transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
}
.tour-slide {
  flex: 0 0 100%; min-width: 100%;
  box-sizing: border-box;
  padding: 50px 44px 26px;
  text-align: center;
  display: flex; flex-direction: column; align-items: center;
}
.tour-slide-icon {
  width: 74px; height: 74px; border-radius: 18px;
  display: flex; align-items: center; justify-content: center;
  font-size: 38px; color: var(--accent);
  background: var(--accent-soft, rgba(124, 92, 255, 0.13));
  margin-bottom: 22px;
}
.tour-kicker {
  text-transform: uppercase; letter-spacing: 0.14em;
  font-size: 11px; font-weight: 600; color: var(--accent);
  margin: 0 0 10px;
}
.tour-slide h2 {
  margin: 0 0 12px; font-size: 25px; font-weight: 700;
  letter-spacing: -0.02em; line-height: 1.18;
}
.tour-slide p {
  margin: 0; font-size: 15px; line-height: 1.6;
  color: var(--text-secondary); max-width: 42ch;
}
.tour-points {
  list-style: none; margin: 18px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 10px;
  text-align: left; width: 100%; max-width: 42ch;
}
.tour-points li {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 14px; color: var(--text-secondary); line-height: 1.45;
}
.tour-points li iconify-icon {
  color: var(--accent); font-size: 18px; flex: 0 0 auto; margin-top: 1px;
}
.tour-footer {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px 16px;
  border-top: 1px solid var(--border, rgba(255, 255, 255, 0.08));
}
.tour-skip {
  background: none; border: none; cursor: pointer;
  color: var(--text-tertiary); font: inherit; font-size: 13px;
  padding: 6px 2px; flex: 0 0 auto;
}
.tour-skip:hover { color: var(--text-secondary); }
.tour-skip[hidden] { visibility: hidden; }
.tour-dots { display: flex; gap: 7px; margin: 0 auto; }
.tour-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: rgba(128, 128, 140, 0.34); border: none; padding: 0;
  cursor: pointer; transition: background 0.15s, width 0.15s;
}
.tour-dot.is-active { background: var(--accent); width: 20px; border-radius: 4px; }
.tour-nav { display: flex; gap: 8px; flex: 0 0 auto; }
.tour-btn {
  font: inherit; font-size: 14px; font-weight: 600;
  border-radius: 9px; padding: 9px 18px; cursor: pointer;
  border: 1px solid transparent; transition: background 0.12s, opacity 0.12s;
}
.tour-btn-ghost { background: rgba(128, 128, 140, 0.16); color: var(--text-secondary); }
.tour-btn-ghost:hover { background: rgba(128, 128, 140, 0.26); }
.tour-btn-ghost[hidden] { display: none; }
.tour-btn-primary { background: var(--accent); color: #fff; }
.tour-btn-primary:hover { background: var(--accent-d, #6347cc); }
@media (prefers-reduced-motion: reduce) {
  .tour-track { transition: none; }
}
@media (max-width: 560px) {
  .tour-slide { padding: 44px 22px 22px; }
  .tour-slide h2 { font-size: 22px; }
  .tour-footer { flex-wrap: wrap; }
}
/* Help FAB that replays the tour. Home (Welcome) page only; sits just
   above the version badge in the bottom-right corner. */
.tour-help-fab {
  position: fixed;
  right: 10px; bottom: 40px;
  width: 38px; height: 38px;
  border-radius: 50%;
  display: none;
  align-items: center; justify-content: center;
  background: var(--accent-soft, rgba(124, 92, 255, 0.13));
  color: var(--accent);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.10));
  cursor: pointer; font-size: 20px;
  z-index: 6;
  transition: background 0.12s, transform 0.12s, color 0.12s;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
body[data-page="welcome"] .tour-help-fab { display: flex; }
.tour-help-fab:hover {
  background: var(--accent); color: #fff; transform: translateY(-1px);
}
.tour-help-fab:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
@media (max-width: 720px) {
  .tour-help-fab { right: 8px; bottom: 38px; width: 34px; height: 34px; font-size: 18px; }
}

/* Feedback FAB: sits just above the help FAB, home page only. */
.feedback-fab {
  position: fixed;
  right: 10px; bottom: 86px;
  width: 38px; height: 38px;
  border-radius: 50%;
  display: none;
  align-items: center; justify-content: center;
  background: var(--accent-soft, rgba(124, 92, 255, 0.13));
  color: var(--accent);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.10));
  cursor: pointer; font-size: 19px;
  z-index: 6;
  transition: background 0.12s, transform 0.12s, color 0.12s;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
body[data-page="welcome"] .feedback-fab { display: flex; }

/* v0.195.182: the homepage (hub) hides the notifications bell and the
   "Viewing as" switcher pill in the topbar. They remain available on the
   other pages; the hub keeps a clean, centered brand. */
body[data-page="welcome"] .topbar-right .view-as-pill,
body[data-page="welcome"] .topbar-right .v2-topbar-btn { display: none !important; }

.feedback-fab:hover {
  background: var(--accent); color: #fff; transform: translateY(-1px);
}
.feedback-fab:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
@media (max-width: 720px) {
  .feedback-fab { right: 8px; bottom: 78px; width: 34px; height: 34px; font-size: 17px; }
}

/* Feedback modal */
.feedback-card { max-width: 460px; width: 92%; }
.feedback-intro {
  margin: 0 0 14px; color: var(--text-dim, #9aa4b2); font-size: 14px; line-height: 1.45;
}
.feedback-cats { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.feedback-cat {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 12px; border-radius: 9px;
  background: var(--bg-1, rgba(255, 255, 255, 0.03));
  border: 1px solid var(--border, rgba(255, 255, 255, 0.10));
  color: var(--text, #e6edf3); font-size: 14px; text-align: left;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.feedback-cat iconify-icon { font-size: 18px; color: var(--accent); }
.feedback-cat:hover { border-color: var(--accent); }
.feedback-cat.active {
  border-color: var(--accent);
  background: var(--accent-soft, rgba(124, 92, 255, 0.13));
}
.feedback-textarea {
  width: 100%; box-sizing: border-box; resize: vertical;
  min-height: 96px; padding: 10px 12px; border-radius: 9px;
  background: var(--bg-1, rgba(255, 255, 255, 0.03));
  border: 1px solid var(--border, rgba(255, 255, 255, 0.10));
  color: var(--text, #e6edf3); font: inherit; font-size: 14px; line-height: 1.45;
}
.feedback-textarea:focus { outline: none; border-color: var(--accent); }
.feedback-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 14px;
}
.feedback-status { font-size: 13px; color: var(--text-dim, #9aa4b2); }
.feedback-status.err { color: var(--cat-blunder, #fa5252); }
.feedback-status.ok { color: var(--cat-best, #51cf66); }
.feedback-send {
  padding: 9px 18px; border-radius: 9px; border: none;
  background: var(--accent); color: #fff; font: inherit; font-weight: 600;
  font-size: 14px; cursor: pointer;
  transition: filter 0.12s, opacity 0.12s;
}
.feedback-send:hover { filter: brightness(1.08); }
.feedback-send:disabled { opacity: 0.55; cursor: default; }

.user-picker-backdrop {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(0, 0, 0, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  backdrop-filter: blur(2px);
}
.user-picker-backdrop[hidden] { display: none; }
.user-picker-modal {
  background: var(--panel, #1f1f1f);
  color: var(--text, #eaeaea);
  border: 1px solid var(--border, rgba(255,255,255,0.10));
  border-radius: 14px;
  width: 100%; max-width: 420px;
  padding: 22px 22px 18px;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.55);
}
.user-picker-modal h2 {
  margin: 0 0 4px; font-size: 20px; font-weight: 600;
  letter-spacing: -0.01em;
}
.user-picker-sub {
  margin: 0 0 14px; color: var(--text-dim); font-size: 13px;
}
.user-picker-list {
  list-style: none; margin: 0 0 14px; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
  max-height: 220px; overflow-y: auto;
}
.user-picker-list:empty { display: none; }
.user-picker-list li button {
  width: 100%; text-align: left;
  background: rgba(255,255,255,0.04);
  color: var(--text);
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 9px 12px;
  font: inherit; font-size: 14px;
  cursor: pointer;
  display: flex; justify-content: space-between; align-items: center;
  gap: 10px;
  transition: background 0.1s, border-color 0.1s;
}
.user-picker-list li button:hover {
  background: rgba(255,255,255,0.08);
  border-color: var(--accent, #c9a96e);
}
.user-picker-list li button.is-active {
  border-color: var(--accent, #c9a96e);
  background: rgba(201, 169, 110, 0.10);
}
.user-picker-list .upl-name { font-weight: 500; }
.user-picker-list .upl-size { color: var(--text-dim); font-size: 12px; }

.user-picker-add label {
  display: block; font-size: 12px; color: var(--text-dim);
  margin-bottom: 6px;
}
.user-picker-row {
  display: flex; gap: 8px;
}
.user-picker-row input {
  flex: 1; min-width: 0;
  background: rgba(0,0,0,0.25);
  color: var(--text);
  border: 1px solid var(--border, rgba(255,255,255,0.12));
  border-radius: 8px;
  padding: 8px 10px;
  font: inherit; font-size: 14px;
}
.user-picker-row input:focus {
  outline: none; border-color: var(--accent, #c9a96e);
}
.user-picker-row button {
  background: var(--accent, #c9a96e); color: #1f1f1f;
  border: none; border-radius: 8px;
  padding: 8px 16px; font: inherit; font-weight: 600;
  cursor: pointer;
  transition: filter 0.1s, opacity 0.1s;
}
.user-picker-row button:hover:not(:disabled) { filter: brightness(1.05); }
.user-picker-row button:disabled { opacity: 0.55; cursor: not-allowed; }
.user-picker-hint {
  margin: 6px 0 0; font-size: 12px; color: var(--text-dim);
  min-height: 1em;
}
.user-picker-hint.is-error { color: #e57373; }
.user-picker-spinner {
  display: inline-block;
  width: 12px; height: 12px;
  margin-right: 8px;
  vertical-align: -1px;
  border: 1.5px solid var(--text-dim, rgba(255,255,255,0.30));
  border-top-color: var(--accent, #7c4dff);
  border-radius: 50%;
  animation: userPickerSpin 0.8s linear infinite;
}
@keyframes userPickerSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .user-picker-spinner { animation: none; }
}
.user-picker-actions {
  display: flex; justify-content: flex-end; margin-top: 14px;
}
.user-picker-close {
  background: transparent; color: var(--text-dim);
  border: 1px solid var(--border, rgba(255,255,255,0.12));
  border-radius: 8px;
  padding: 6px 14px;
  font: inherit; font-size: 13px;
  cursor: pointer;
}
.user-picker-close:hover { color: var(--text); }

/* ============================================================
 * Account sign-in modal (v0.195.85)
 * Reuses .user-picker-backdrop / .user-picker-modal chrome; only
 * the IdP button stack + helper note need bespoke rules.
 * ============================================================ */
.signin-modal .signin-modal-btns {
  display: flex; flex-direction: column; gap: 10px;
  margin: 4px 0 10px;
}
.signin-modal .v2-auth-btn { width: 100%; }
.signin-modal-note {
  margin: 0; font-size: 12px; color: var(--text-dim);
  text-align: center;
}
.signin-modal .user-picker-actions { justify-content: center; }

/* Email magic-link option inside the sign-in modal (v0.195.91) */
.signin-modal .signin-email {
  border-top: 1px solid var(--border-default);
  margin: 4px 0 10px;
  padding-top: 10px;
}
.signin-modal .signin-email-toggle {
  width: 100%;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 13px;
  cursor: pointer;
  padding: 6px 0;
  text-decoration: underline;
}
.signin-modal .signin-email-toggle:hover { color: var(--text); }
.signin-modal .signin-email-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* The display:flex above outranks the UA [hidden]{display:none}, so without
   this guard the email + code forms render even while their `hidden` attribute
   is set. That made the whole email menu sit open instead of only appearing
   after the user presses "Continue with email instead". */
.signin-modal .signin-email-form[hidden] { display: none; }
.signin-modal .signin-email-label {
  font-size: 12px;
  color: var(--text-dim);
  text-align: left;
}
.signin-modal .signin-email-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border-default);
  background: var(--bg-2);
  color: var(--text);
  font-size: 14px;
}
.signin-modal .signin-email-input:focus {
  outline: none;
  border-color: var(--accent);
}
.signin-modal .signin-code-input {
  text-align: center;
  font-size: 22px;
  letter-spacing: 8px;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono, monospace);
}
.signin-modal .signin-email-submit { width: 100%; }
.signin-modal .signin-email-status {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--text-dim);
  text-align: center;
}
.signin-modal .signin-email-status[data-kind="ok"]  { color: var(--accent); }
.signin-modal .signin-email-status[data-kind="err"] { color: var(--cat-blunder, #EF4444); }

/* ============================================================
 * Account modal (v0.195.86)
 * Unified modal: identity (sign in / signed-in-as + sign out) plus a
 * chess.com connect/change section. Reuses the .user-picker-modal chrome.
 * ============================================================ */
.account-modal { text-align: left; }
.account-modal .account-section {
  margin: 0 0 18px;
  padding: 0 0 16px;
  border-bottom: 1px solid var(--border, rgba(255,255,255,0.08));
}
.account-modal .account-section:last-of-type { border-bottom: none; padding-bottom: 0; }
.account-section-head {
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-dim);
  margin: 0 0 10px;
}
.account-identity {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.account-identity-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.account-identity-info strong {
  font-size: 14px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis;
}
.account-identity-info span { font-size: 12.5px; color: var(--text-dim); }
.account-identity-btn {
  flex: 0 0 auto;
  background: transparent; color: var(--text);
  border: 1px solid var(--border, rgba(255,255,255,0.14));
  border-radius: 8px; padding: 7px 14px;
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: filter 0.1s, border-color 0.1s;
}
.account-identity-btn:hover { border-color: var(--accent, #7c5cff); }
.account-identity-btn.is-primary {
  background: var(--accent, #7c5cff); color: #fff; border-color: transparent;
}
.account-identity-btn.is-primary:hover { filter: brightness(1.08); }
.account-current { margin: 0 0 10px; font-size: 13px; color: var(--text-dim); }
.account-current strong { color: var(--text); }
.account-note { margin: 6px 0 0; font-size: 12px; color: var(--text-dim); }
.account-modal .user-picker-add[hidden] { display: none; }
.account-modal .user-picker-add input:disabled,
.account-modal .user-picker-add button:disabled {
  opacity: 0.5; cursor: not-allowed;
}

/* Danger zone: delete account (v0.195.147) */
#accountDangerSection[hidden] { display: none; }
#accountDangerSection .account-section-head { color: var(--cat-blunder, #ef4444); }
.account-danger-btn {
  margin-top: 8px;
  background: transparent; color: var(--cat-blunder, #ef4444);
  border: 1px solid var(--cat-blunder, #ef4444);
  border-radius: 8px; padding: 7px 14px;
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: filter 0.1s, background 0.1s, color 0.1s;
}
.account-danger-btn:hover { background: var(--cat-blunder, #ef4444); color: #fff; }
.account-danger-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.account-danger-btn:disabled:hover { background: transparent; color: var(--cat-blunder, #ef4444); }
.account-delete-confirm[hidden] { display: none; }
.account-delete-confirm { margin-top: 12px; }
.account-delete-confirm label { display: block; font-size: 13px; margin-bottom: 6px; }

/* ============================================================
 * chess.com connect reminder banner (v0.195.85)
 * Small dismissible prompt shown in Hub + Analyze when an account
 * is present but no chess.com username is loaded.
 * ============================================================ */
.chesscom-reminder {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-2, rgba(255,255,255,0.04));
  border: 1px solid var(--border, rgba(255,255,255,0.10));
  border-left: 3px solid var(--accent, #7c5cff);
  border-radius: var(--radius-md, 10px);
  padding: 12px 14px;
  margin: 0 0 18px;
}
.chesscom-reminder[hidden] { display: none; }
.chesscom-reminder-ico {
  font-size: 20px; color: var(--accent, #7c5cff);
  flex: 0 0 auto;
}
.chesscom-reminder-text {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0; flex: 1 1 auto;
}
.chesscom-reminder-text strong {
  font-size: 14px; font-weight: 600; color: var(--text);
}
.chesscom-reminder-text span {
  font-size: 12.5px; color: var(--text-dim);
}
.chesscom-reminder-actions {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
}
.chesscom-reminder-connect {
  background: var(--accent, #7c5cff); color: #fff;
  border: none; border-radius: 8px;
  padding: 7px 14px; font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
  transition: filter 0.1s;
}
.chesscom-reminder-connect:hover { filter: brightness(1.08); }
.chesscom-reminder-dismiss {
  background: transparent; color: var(--text-dim);
  border: 1px solid var(--border, rgba(255,255,255,0.12));
  border-radius: 8px;
  padding: 7px 12px; font: inherit; font-size: 13px;
  cursor: pointer;
}
.chesscom-reminder-dismiss:hover { color: var(--text); }
@media (max-width: 720px) {
  .chesscom-reminder { flex-wrap: wrap; }
  .chesscom-reminder-actions { width: 100%; justify-content: flex-end; }
}


/* ============================================================
 * OPENINGS TRAINER - medium viewport collapse (≤ 1100px)
 * Stack board + side panel vertically at tablet width.
 * ============================================================ */
@media (max-width: 1100px) {
  .op-detail-layout { flex-direction: column; align-items: stretch; }
  .op-side-panel { max-height: none; overflow-y: visible; }
}

/* ============================================================
 * MOBILE / NARROW VIEWPORT (v0.122)
 *
 * Single comprehensive breakpoint covering iPhone (390-430px),
 * Pixel (412px), folded tablets, and small landscape phones up to
 * 720px. The goal: every page is FULLY usable on a 390px viewport
 * with no horizontal overflow, no off-screen primary content, and
 * tap targets >= 44x44 px. Layout strategy: stack any 2-col / 3-col
 * grids vertically; let the page scroll the document instead of
 * locking each panel into its own viewport.
 * ============================================================ */
@media (max-width: 720px) {
  /* Slim the navrail so it eats less of the precious 390px width.
     Icons stay 36px square (was 40) -- still well above the 44px
     touch-target floor when combined with surrounding padding. */
  :root { --navrail-w: 48px; }
  .navrail { padding: 8px 0; }
  .navrail-btn { width: 36px; height: 36px; }

  /* Topbar -- hide the italic "Game Review" subtitle, shrink brand
     text, let the right-side group breathe via flex-wrap. */
  .topbar { padding: 8px 10px; height: auto; min-height: 56px; gap: 8px; flex-wrap: wrap; }
  .brand .logo { font-size: 24px; }
  .brand .title { font-size: 17px; }
  .brand .sub { display: none; }
  .topbar-right { gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
  .view-as-pill { font-size: 12px; padding: 4px 9px; }
  .view-as-pill .vap-caret { display: none; }
  .user-info { font-size: 11px; }

  /* ---- Welcome page: stack avatar above text, shrink username,
     tighten paddings, single-column CTA. */
  .welcome-view { padding: 18px 14px 60px; }
  .welcome-brand { margin-bottom: 16px; gap: 4px; }
  .welcome-brand-mark { width: 64px; height: 64px; }
  .welcome-brand-word { font-size: 22px; }
  .welcome-hero { gap: 14px; margin-bottom: 18px; flex-wrap: wrap; }
  .welcome-avatar { width: 72px; height: 72px; }
  .welcome-greeting { font-size: 14px; }
  .welcome-username { font-size: clamp(26px, 8vw, 36px); line-height: 1.1; }
  .welcome-cta { padding: 12px 14px; gap: 12px; }
  .welcome-cta-icon { width: 36px; height: 36px; }
  .welcome-cta-title { font-size: 16px; }
  .welcome-cta-sub { font-size: 12px; }
  .welcome-cta-go { padding: 6px 14px; font-size: 12.5px; }

  /* ---- Coach digest: 5-tile row becomes 2-col grid; outer paddings
     trimmed; extras always stack. */
  #homeDigestSection { padding: 12px 14px !important; }
  .hdg-stats { grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
               min-width: 0 !important; }
  .hdg-stat { min-width: 0 !important; }
  .hdg-extras { grid-template-columns: 1fr !important; }

  /* ---- Analyse page (the .layout grid). Stack ALL three columns
     vertically: board first (highest priority), then sidebar with
     move list + eval, then rightpane with stats. Drop the
     calc(100vh - var(--topbar-h)) lock so the whole document scrolls. */
  .layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto;
    height: auto;
    min-height: calc(100vh - var(--topbar-h));
  }
  .sidebar, .board-area, .rightpane {
    overflow: visible;
    height: auto;
    max-height: none;
    border: none;
  }
  .sidebar { order: 2; border-top: 1px solid var(--bg-3); }
  .board-area { order: 1; padding: 8px 6px 12px; min-width: 0; overflow-x: hidden; }
  .rightpane { order: 3; border-top: 1px solid var(--bg-3); min-width: 0; overflow-x: hidden; }
  /* Board fills the viewport minus: navrail (48), eval-bar (22),
     gap (10), board-area padding (12), and a couple of px buffer for
     border-box rounding. The --board-w cascade includes ours last
     because it lives at the end of the file -- safe override. */
  :root { --board-w: calc(100vw - var(--navrail-w) - 56px); }
  .board-row { gap: 6px; min-width: 0; max-width: 100%; }
  .player-strip, .controls { width: var(--board-w) !important; max-width: 100%; }
  /* Fix 6 (Wanda-19): .move-explainer is now in the rightpane flex column;
     no position override needed on mobile - it just stacks naturally.
     v0.176.8: zero out the desktop pill insets so the card fills the
     mobile rightpane (otherwise the 10px horizontal margins push past
     the viewport edge). */
  .move-explainer {
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    border-radius: 0 !important;
  }
  .rightpane .tabs,
  .rightpane .tab-content {
    margin: 0 !important;
    border-radius: 0 !important;
  }
  /* Stats panels inside rightpane may have 3-col rigid grids that
     bust the viewport -- give them a breakable layout. */
  .rightpane .stats-cat-row,
  .rightpane .game-rating-row { min-width: 0; max-width: 100%; }
  .rightpane * { max-width: 100%; }
  /* Move-list rows get a touch-friendly minimum height so finger
     taps don't miss the small "1." numbers. */
  .move-table tr { min-height: 32px; }
  .move-pill { min-height: 28px; padding: 4px 8px; }

  /* ---- Game gallery: let cards stretch to fill the available
     row instead of stamping a 330px minimum (which on a 390px
     viewport with a 60px navrail leaves only 330px and forces an
     awkward 1-card row + horizontal scroll if any card paddings
     push it over). */
  .game-grid { grid-template-columns: 1fr; gap: 12px; }
  .game-card { padding: 14px 14px 12px; }

  /* ---- Pill tab strip (Analyze filters): scroll horizontally
     instead of wrapping into a tall stack. */
  #pillTabs {
    flex-wrap: nowrap !important;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: 4px;
  }
  #pillTabs::-webkit-scrollbar { display: none; }
  #pillTabs .pill { flex: 0 0 auto; }

  /* ---- Stats page: trim padding, force single-column charts. */
  .stats-view { padding: 16px 12px 60px !important; }
  .stats-charts { grid-template-columns: 1fr !important; }

  /* Activity heatmap is a wide grid (53 weeks * 11px ≈ 600px) - wrap
     it in a horizontal scroller so the page doesn't overflow.
     v0.195.55: minmax(0, 1fr) so the grid column actually shrinks to
     the available track width; without it the grid sizes to content
     and expands the parent past viewport, blowing out the bottom
     tab bar's width too. */
  .home-heatmap { padding: 12px 14px; }
  .hmap-grid-wrap {
    grid-template-columns: 28px minmax(0, 1fr) !important;
  }
  .hmap-grid-wrap > .hmap-grid {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    min-width: 0;
    max-width: 100%;
  }

  /* ---- Settings page: trim padding so form rows aren't squeezed,
     stack each row vertically so the label gets full width and the
     control gets its own line below. Otherwise theme/season grids
     (320px min) starve the label column to ~0. */
  .settings-view, #pageSettings .settings-view { padding: 16px 14px 60px !important; }
  .settings-row {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  /* Piece-set grid has a 340px min-width that overflows on iPhone SE;
     reset and let the auto-fit do the work. */
  .settings-piece-grid {
    min-width: 0 !important; max-width: 100% !important;
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)) !important;
  }
  .settings-select, .settings-range { width: 100%; min-width: 0; }

  /* Puzzle Rush banner: stack the left pitch + right stats vertically
     so the START button doesn't push past the viewport edge. */
  .puz-rush {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .puz-rush-right { justify-content: space-between; flex-wrap: wrap; }
  .puz-rush-stats { border-right: none; padding: 4px 0; }

  /* Stats chart cards: their canvas may push to 334px; cap to row. */
  .stats-chart-card { max-width: 100%; min-width: 0; }
  .stats-chart-card .chart-wrap { max-width: 100%; }

  /* ---- Endgames page. */
  .endgames-view { padding: 16px 14px 60px !important; }
  /* ---- Trainer / Openings page: stack board + side panel vertically. */
  .trainer-view { padding: 16px 14px 60px !important; }
  .op-detail-layout { flex-direction: column; align-items: stretch; }
  .op-board, .op-controls, .op-color-picker {
    width: 100% !important; max-width: calc(100vw - var(--navrail-w) - 28px);
  }
  .op-side-panel { max-height: none; overflow-y: visible; }
  .op-list-grid { flex-direction: column; } /* was grid override; flex is now canonical */

  /* ---- Puzzles page already stacks at 980px; just trim padding. */
  #pagePuzzles .puz-layout { gap: 14px; }

  /* ---- Play page already stacks at 900px; trim panel min-width
     so a 5+3 / 10+0 strength popover doesn't clip off-screen. */
  .play-view { padding: 14px 12px; gap: 14px; }
  .play-card { padding: 14px; }
  .play-shared-cluster { min-width: 0 !important; max-width: 100% !important; }
  /* Bot-game in-progress panel: stack the chat + move-list under
     the board instead of side-by-side. */
  #pagePlay[data-play-screen="playing"] .play-view {
    grid-template-columns: 1fr;
  }

  /* ---- Modals: dialog cards should never overflow the viewport. */
  .modal-card, .modal-card-wide { width: 92vw; max-width: 92vw; }

  /* ---- Touch targets. Make every icon button big enough to hit
     reliably on touch screens. Apple HIG = 44pt, Material 48dp;
     we land at 40px which is the existing baseline + the surrounding
     padding usually pushes the hit area to 44+. */
  .icon-btn, .pill, .seg-btn, .tc-trigger {
    min-height: 36px;
  }

  /* ---- App version badge: keep visible but make sure it doesn't
     sit on top of the bottom-tab area on iPhones with a notch. */
  .app-version { right: 6px; bottom: 6px; font-size: 9.5px; }
}

/* Very narrow phones (e.g. iPhone SE 1st gen, 320px). The 720px
   rules above mostly cover this, but a few elements need a final
   nudge to avoid 1-2px overflows that ruin the iOS rubber-band. */
@media (max-width: 380px) {
  .welcome-username { font-size: clamp(22px, 7.5vw, 30px); }
  .brand .title { font-size: 15px; }
  :root { --navrail-w: 44px; }
}

.gc-select {
  position: relative;
  display: inline-block;
}
.gc-select-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  min-width: 100px;
  width: 100%;
  text-align: left;
  transition: background 120ms, border-color 120ms;
}
.gc-select-trigger:hover { background: var(--bg-3); }
.gc-select-trigger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.gc-select-label { flex: 1 1 0; overflow: hidden; text-overflow: ellipsis; }
.gc-select-chevron {
  color: var(--accent);
  font-size: 11px;
  flex-shrink: 0;
  transition: transform 140ms ease-out;
}
.gc-select-trigger[aria-expanded="true"] .gc-select-chevron {
  transform: rotate(180deg);
}
.gc-select-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 100%;
  max-height: 260px;
  overflow-y: auto;
  list-style: none;
  margin: 0;
  padding: 4px;
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.55), 0 2px 8px rgba(0,0,0,0.35);
  z-index: 900;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 140ms ease-out, transform 140ms ease-out;
}
.gc-select-list.open {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .gc-select-list,
  .gc-select-chevron { transition: none; }
}
.gc-select-option {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 7px 10px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text);
  font-size: 13px;
  line-height: 1.35;
  transition: background 80ms;
  outline: none;
}
.gc-select-option:hover,
.gc-select-option:focus {
  background: var(--accent-soft);
  color: var(--accent);
}
.gc-select-option.selected { background: var(--bg-3); color: var(--accent); }
.gc-select-option.selected::before {
  content: "✓";
  color: var(--accent);
  font-size: 11px;
  line-height: 1;
  flex-shrink: 0;
}
.gc-select-option:not(.selected)::before {
  content: "";
  display: inline-block;
  width: 11px;
  flex-shrink: 0;
}

/* Size variants that mirror the old native-select class sizing */
.gc-select--settings-select .gc-select-trigger {
  min-width: 120px; font-size: 13px;
}
.gc-select--popover-select .gc-select-trigger {
  font-size: 12.5px; padding: 4px 8px; min-width: 80px;
}
.gc-select--trainer-diff-select .gc-select-trigger {
  font-size: 13px; font-weight: 600; min-width: 160px;
}





/* ================================================================
 * Welcome / Hub page
 * Maps existing .welcome-* markup to the Stitch Hub layout.
 * ================================================================ */
#pageWelcome {
  background: var(--bg-0) !important;
  color: var(--text) !important;
  padding: var(--space-6) !important;
  max-width: 1440px;
  margin: 0 auto !important;
}

#pageWelcome .welcome-brand {
  display: flex !important;
  flex-direction: column !important;
  align-items: flex-start !important;
  gap: 4px !important;
  background: transparent !important;
  border: none !important;
  padding: 0 0 var(--space-6) 0 !important;
  margin-bottom: var(--space-6) !important;
  border-bottom: 1px solid var(--bg-3) !important;
  position: relative;
}
#pageWelcome .welcome-brand-mark,
#pageWelcome .welcome-brand-word {
  display: none !important;
}
#pageWelcome .welcome-greeting,
#pageWelcome .welcome-eyebrow {
  font-family: var(--font-body) !important;
  color: var(--text-dim) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0.12em !important;
  text-transform: uppercase !important;
  margin-bottom: 4px !important;
}
#pageWelcome .welcome-username {
  font-family: var(--font-display) !important;
  color: var(--text) !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  line-height: 1.1 !important;
  letter-spacing: -0.02em !important;
  text-shadow: none !important;
  margin: 0 !important;
}
#pageWelcome .welcome-username::after {
  content: ".";
  color: var(--accent) !important;
}
#pageWelcome .welcome-avatar {
  position: absolute;
  top: 0;
  right: 200px;
  width: 40px !important;
  height: 40px !important;
  border-radius: var(--radius-pill) !important;
  border: 1px solid var(--bg-3) !important;
  background: var(--bg-3) !important;
}
#pageWelcome .welcome-switch-user {
  background: transparent !important;
  border: 1px solid var(--bg-3) !important;
  color: var(--text-dim) !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  border-radius: var(--radius-sm) !important;
  padding: 8px 14px !important;
  margin-top: 12px !important;
  transition: all 0.15s ease;
}
#pageWelcome .welcome-switch-user:hover {
  border-color: var(--accent) !important;
  color: var(--accent) !important;
}
#pageWelcome .welcome-cta {
  position: absolute;
  top: var(--space-6);
  right: var(--space-6);
  background: var(--accent-d) !important;
  color: var(--text) !important;
  border: none !important;
  border-radius: var(--radius-sm) !important;
  padding: 0 24px !important;
  height: 40px !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  box-shadow: none !important;
  transition: background 0.15s ease;
}
#pageWelcome .welcome-cta:hover {
  background: var(--accent) !important;
  color: var(--on-accent) !important;
}

#pageWelcome .welcome-stats {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: var(--space-4) !important;
  background: transparent !important;
  padding: 0 !important;
  border: none !important;
}
#pageWelcome .welcome-card {
  background: var(--bg-0) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  padding: 16px !important;
  display: flex !important;
  flex-direction: column !important;
  justify-content: space-between !important;
  min-height: 120px;
  text-align: left !important;
  transition: border-color 0.15s ease;
  box-shadow: none !important;
  position: relative;
  overflow: hidden;
  cursor: pointer;
}
#pageWelcome .welcome-card:hover {
  border-color: var(--accent) !important;
}
#pageWelcome .welcome-card-label {
  font-family: var(--font-body) !important;
  color: var(--text-dim) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  margin-bottom: 24px !important;
}
#pageWelcome .welcome-card-value {
  font-family: var(--font-display) !important;
  color: var(--text) !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  line-height: 1 !important;
  letter-spacing: -0.02em !important;
  margin: 0 !important;
}
#pageWelcome .welcome-card-sub {
  font-family: var(--font-body) !important;
  color: var(--text-faint) !important;
  font-size: 13px !important;
  font-weight: 400 !important;
  margin-top: 8px !important;
}
#pageWelcome .welcome-card-wide,
#pageWelcome .welcome-card-lastgame {
  grid-column: 1 / -1 !important;
  background: var(--bg-1) !important;
  flex-direction: row !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 24px !important;
  padding: 20px !important;
}
#pageWelcome .welcome-card-lastgame .welcome-card-label {
  margin-bottom: 6px !important;
}
#pageWelcome .welcome-card-lastgame .welcome-card-value {
  font-size: 24px !important;
  font-family: var(--font-display) !important;
}

/* Material Symbols Outlined - ensure variation settings work */
.material-symbols-outlined {
  font-family: "Material Symbols Outlined" !important;
  font-weight: 400;
  font-style: normal;
  font-size: 24px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  -webkit-font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
}
/* Navrail uses the 22px icon size matching Stitch's icon-rail. The
   v0.193.6 redesign switched from iconify SVGs to Material Symbols so
   the icon set + weight perfectly matches the Stitch design system
   (grid_view, psychology, stadia_controller, school, extension,
   monitoring, account_circle, settings). */
.navrail .material-symbols-outlined {
  font-size: 22px !important;
}
.navrail-btn:not(.active) .material-symbols-outlined {
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}
.navrail-btn.active .material-symbols-outlined {
  font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}

/* PP welcome CTA - compact pill (override the multi-line legacy layout) */
#pageWelcome .welcome-cta {
  position: absolute !important;
  top: 0 !important;
  right: 0 !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  min-height: 40px !important;
  height: 40px !important;
  width: auto !important;
  background: var(--accent-d) !important;
  color: var(--text) !important;
  border-radius: var(--radius-sm) !important;
  padding: 0 18px !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  box-shadow: none !important;
  border: none !important;
  margin: 0 !important;
}
#pageWelcome .welcome-cta-icon {
  width: 18px !important;
  height: 18px !important;
  flex: 0 0 auto !important;
  background: transparent !important;
  border: none !important;
}
#pageWelcome .welcome-cta-icon svg {
  width: 18px !important;
  height: 18px !important;
}
#pageWelcome .welcome-cta-text {
  display: inline-flex !important;
  flex-direction: column !important;
  align-items: flex-start !important;
  line-height: 1 !important;
  gap: 0 !important;
}
#pageWelcome .welcome-cta-title {
  font-size: 12px !important;
  font-weight: 700 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  color: inherit !important;
}
#pageWelcome .welcome-cta-sub {
  display: none !important;
}
#pageWelcome .welcome-cta-go {
  display: none !important;
}
#pageWelcome .welcome-cta:hover {
  background: var(--accent) !important;
  color: var(--on-accent) !important;
}

/* Bind grid to the actual class .welcome-grid (legacy IS welcome-grid not -stats) */
#pageWelcome .welcome-grid {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: var(--space-4) !important;
  background: transparent !important;
  padding: 0 !important;
  border: none !important;
  max-width: none !important;
}

/* Avatar: keep it visible with persona graphic */
#pageWelcome .welcome-avatar {
  position: absolute !important;
  top: 0 !important;
  right: 160px !important;
  width: 40px !important;
  height: 40px !important;
  border-radius: var(--radius-pill) !important;
  border: 1px solid var(--bg-3) !important;
  background: var(--bg-3) !important;
  padding: 0 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  overflow: hidden !important;
}
#pageWelcome .welcome-avatar svg,
#pageWelcome .welcome-avatar img {
  width: 100% !important;
  height: 100% !important;
}

/* Footer (Terms · Imprint) - more legible */
body:has(.page.active#pageWelcome) .topbar-footer,
body:has(.page.active#pageWelcome) .legal-footer,
body:has(.page.active#pageWelcome) .imprint-footer {
  color: var(--text-faint) !important;
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  letter-spacing: 0.05em !important;
}

/* Version pill bottom-right */
body:has(.page.active#pageWelcome) .version-pill,
body:has(.page.active#pageWelcome) #versionPill {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  color: var(--text-dim) !important;
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  border-radius: var(--radius-sm) !important;
}

/* Headlines on every page */
.home-hero h1,
.stats-hero h1,
.puzzles-hero h1,
.settings-hero h1,
.play-select-title,
.op-hero h1,
.eg-hero h1,
#opListView h1,
#egListView h1 {
  font-family: var(--font-display) !important;
  font-weight: 700 !important;
  font-size: 40px !important;
  line-height: 1.1 !important;
  letter-spacing: -0.02em !important;
  color: var(--text) !important;
  margin: 0 0 8px 0 !important;
}
.stats-sub,
.puzzles-sub,
.settings-sub,
.op-hero-sub,
.eg-hero-sub,
.play-select-sub {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text-dim) !important;
  margin: 0 !important;
}

/* Generic button - btn, .icon-btn, .seg-btn defaults */
button,
.btn,
.icon-btn {
  font-family: var(--font-body) !important;
  border-radius: var(--radius-sm) !important;
}

.icon-btn,
.icon-btn-label {
  background: var(--bg-2) !important;
  color: var(--text) !important;
  border: 1px solid var(--bg-3) !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  border-radius: var(--radius-sm) !important;
  padding: 0 12px !important;
  height: 36px !important;
  transition: all 0.15s ease;
}
.icon-btn:hover,
.icon-btn-label:hover {
  background: var(--bg-3) !important;
  border-color: var(--text-faint) !important;
}

/* Generic inputs */
input[type="text"],
input[type="number"],
input[type="search"],
input[type="url"],
input[type="email"],
select,
textarea {
  background: var(--bg-1) !important;
  color: var(--text) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  padding: 0 12px !important;
  height: 40px !important;
}
textarea {
  height: auto !important;
  padding: 12px !important;
}
input:focus,
select:focus,
textarea:focus {
  outline: none !important;
  border-color: var(--accent) !important;
}

/* Modal overlay (analyze / play / settings modals) */
.modal,
.modal-backdrop,
.overlay {
  background: rgba(0, 0, 0, 0.6) !important;
  backdrop-filter: blur(8px) !important;
}
.modal-content,
.modal-panel,
.modal-card,
.dialog-content {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  color: var(--text) !important;
  font-family: var(--font-body) !important;
}

/* ================================================================
 * #pageHome (Analyze library + game review)
 * Stitch: search/filter header + card grid; review = board + sidebar
 * ================================================================ */

#pageHome {
  background: var(--bg-0) !important;
  color: var(--text) !important;
  padding: var(--space-6) !important;
  max-width: 1440px;
  margin: 0 auto !important;
}
/* v0.195.63: when a game review is open, the v2-gr-view should claim
   the full app-shell width (not be capped to the 1440px library cap).
   Without this the layout grid is forced into a 1440 box and the
   board cannot grow past ~620px even on a 1920px monitor. */
body[data-page="home"][data-game-open="1"] #pageHome {
  max-width: none !important;
  padding: 0 !important;
}
#pageHome .home-hero {
  display: flex !important;
  align-items: flex-end !important;
  justify-content: space-between !important;
  margin-bottom: 24px !important;
  padding-bottom: 16px !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pageHome .home-hero h1 {
  font-family: var(--font-display) !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  letter-spacing: -0.02em !important;
  margin: 0 !important;
}
#pageHome .home-actions {
  display: flex !important;
  gap: 8px !important;
}

/* Coach digest panel */
#pageHome .home-digest,
#pageHome .digest-card {
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  color: var(--text) !important;
}
/* v0.195.87: the digest header row used to inherit the card's grey
   border, drawing a redundant inner outline around just the title. Keep
   it transparent so only the outer card has an edge. */
#pageHome .hdg-h {
  background: transparent !important;
  border: none !important;
  color: var(--text) !important;
}
#pageHome .home-digest {
  padding: 16px !important;
  margin-bottom: 16px !important;
}
#pageHome .hdg-title {
  font-family: var(--font-display) !important;
  font-size: 20px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
}
#pageHome .hdg-window {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--text-dim) !important;
  letter-spacing: 0.05em !important;
}

/* Filter bar / filter chips */
#pageHome .home-filters,
#pageHome .home-filters-bar,
#pageHome .filter-bar {
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  padding: 12px !important;
  margin-bottom: 16px !important;
}
#pageHome .filter-chip,
#pageHome .home-filter-chip,
#pageHome .chip {
  background: transparent !important;
  border: 1px solid var(--bg-3) !important;
  color: var(--text-dim) !important;
  border-radius: var(--radius-pill) !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  padding: 0 12px !important;
  height: 32px !important;
}
#pageHome .filter-chip.active,
#pageHome .home-filter-chip.active,
#pageHome .chip.active {
  background: var(--accent-d) !important;
  color: var(--text) !important;
  border-color: var(--accent-d) !important;
}

/* Game list cards */
#pageHome .game,
#pageHome .game-item,
#pageHome .game-row,
#pageHome .home-game-row,
#pageHome #gamesList > *,
#pageHome .games-list > * {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  transition: border-color 0.15s ease;
}
#pageHome .game:hover,
#pageHome .game-item:hover,
#pageHome .game-row:hover,
#pageHome .home-game-row:hover {
  border-color: var(--accent) !important;
}

/* Win/loss/draw outcome badges */
#pageHome .result-win,
#pageHome .game-win,
#pageHome .game.win {
  border-left: 3px solid #e9c349 !important;
}
#pageHome .result-loss,
#pageHome .game-loss,
#pageHome .game.loss {
  border-left: 3px solid #ffb4ab !important;
}
#pageHome .result-draw,
#pageHome .game-draw,
#pageHome .game.draw {
  border-left: 3px solid var(--text-faint) !important;
}

/* Game review board area */
#pageHome .board-wrap,
#pageHome .board-container,
#pageHome .review-board {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
}
#pageHome .move-list,
#pageHome .moves,
#pageHome .notation {
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  font-family: var(--font-body) !important;
  font-size: 13px !important;
}
#pageHome .move-list .move.active,
#pageHome .moves .move.active,
#pageHome .notation .move.active {
  background: rgba(94, 92, 230, 0.15) !important;
  color: var(--accent) !important;
  border-left: 2px solid var(--accent) !important;
}

/* ================================================================
 * #pagePlay (picker + active game)
 * Stitch: 4-col opponent picker; split board + notation sidebar
 * ================================================================ */

#pagePlay {
  background: var(--bg-0) !important;
  color: var(--text) !important;
  padding: var(--space-6) !important;
  max-width: 1440px;
  margin: 0 auto !important;
}
#pagePlay .play-select-head {
  margin-bottom: 24px !important;
  padding-bottom: 16px !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pagePlay .play-select-title {
  font-family: var(--font-display) !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  letter-spacing: -0.02em !important;
  color: var(--text) !important;
  margin: 0 0 8px 0 !important;
}
#pagePlay .play-select-sub {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text-dim) !important;
  margin: 0 !important;
}
#pagePlay .play-select-grid {
  display: grid !important;
  grid-template-columns: repeat(4, 1fr) !important;
  gap: var(--space-4) !important;
}
@media (max-width: 1100px) {
  #pagePlay .play-select-grid { grid-template-columns: repeat(2, 1fr) !important; }
}
@media (max-width: 640px) {
  #pagePlay .play-select-grid { grid-template-columns: 1fr !important; }
}

/* Persona card */
#pagePlay .persona-card,
#pagePlay .play-card,
#pagePlay .play-select-card,
#pagePlay .play-select-grid > * {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  overflow: hidden !important;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
#pagePlay .persona-card:hover,
#pagePlay .play-card:hover,
#pagePlay .play-select-card:hover,
#pagePlay .play-select-grid > *:hover {
  border-color: var(--accent) !important;
}
#pagePlay .persona-card.selected,
#pagePlay .play-card.selected,
#pagePlay .play-select-card.selected,
#pagePlay .play-select-grid > *.selected {
  border-color: var(--accent) !important;
  box-shadow: 0 0 0 1px var(--accent) inset !important;
}

/* Shared cluster (side / strength / start) */
#pagePlay .play-select-shared {
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  padding: 16px !important;
  margin-top: 16px !important;
}
#pagePlay .play-shared-label {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  color: var(--text-dim) !important;
}
#pagePlay .seg-btn {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  color: var(--text-dim) !important;
  border-radius: var(--radius-sm) !important;
  font-family: var(--font-body) !important;
}
#pagePlay .seg-btn.active {
  background: var(--accent-d) !important;
  color: var(--text) !important;
  border-color: var(--accent-d) !important;
}

/* Active game board area */
#pagePlay .play-board-area,
#pagePlay #playBoardArea {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  padding: 12px !important;
}
#pagePlay .play-controls,
#pagePlay .controls.play-controls {
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  padding: 8px 12px !important;
  margin-top: 12px !important;
}
#pagePlay .player-strip,
#pagePlay .play-clock,
#pagePlay .clock {
  background: var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  letter-spacing: 0.05em !important;
}
#pagePlay .clock.active,
#pagePlay .play-clock.active {
  background: var(--accent-d) !important;
  color: var(--text) !important;
}

/* ================================================================
 * #pageStats
 * Stitch: KPI bento + rating chart + colour donuts + heatmap
 * ================================================================ */

#pageStats {
  background: var(--bg-0) !important;
  color: var(--text) !important;
  padding: var(--space-6) !important;
  max-width: 1440px;
  margin: 0 auto !important;
}
#pageStats .stats-hero {
  display: flex !important;
  align-items: flex-end !important;
  justify-content: space-between !important;
  margin-bottom: 24px !important;
  padding-bottom: 16px !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pageStats .stats-hero h1 {
  font-family: var(--font-display) !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  letter-spacing: -0.02em !important;
  margin: 0 !important;
}
#pageStats .stats-sub {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text-dim) !important;
}

/* Stats grid + cards */
#pageStats .stats-grid,
#pageStats #statsGrid {
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)) !important;
  gap: var(--space-4) !important;
  margin-bottom: 16px !important;
}
@media (min-width: 1100px) {
  #pageStats .stats-grid,
  #pageStats #statsGrid {
    grid-template-columns: repeat(6, minmax(0, 1fr)) !important;
  }
}
#pageStats .stats-card,
#pageStats .stat-card,
#pageStats .stats-tile,
#pageStats .stats-grid > * {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  color: var(--text) !important;
  padding: 16px !important;
  font-family: var(--font-body) !important;
}
#pageStats .stats-card-label,
#pageStats .stat-label {
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: var(--text-dim) !important;
  margin-bottom: 8px !important;
}
#pageStats .stats-card-value,
#pageStats .stat-value {
  font-family: var(--font-display) !important;
  font-size: 36px !important;
  font-weight: 700 !important;
  letter-spacing: -0.02em !important;
  color: var(--text) !important;
  line-height: 1.1 !important;
}

/* Chart panels */
#pageStats .stats-charts,
#pageStats #statsCharts {
  display: grid !important;
  grid-template-columns: 1fr !important;
  gap: var(--space-4) !important;
}
#pageStats .chart-card,
#pageStats .stats-chart,
#pageStats .stats-charts > * {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  padding: 16px !important;
}

/* Activity heatmap */
#pageStats .home-heatmap {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  padding: 16px !important;
  margin-bottom: 16px !important;
}
#pageStats .hmap-title {
  font-family: var(--font-display) !important;
  font-size: 18px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
}
#pageStats .hmap-summary {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--text-dim) !important;
}

/* ================================================================
 * #pagePuzzles
 * Stitch: mode tabs + board + right info rail
 * ================================================================ */

#pagePuzzles .puzzles-hero {
  margin-bottom: 24px !important;
  padding-bottom: 16px !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pagePuzzles .puzzles-hero h1 {
  font-family: var(--font-display) !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  letter-spacing: -0.02em !important;
  margin: 0 0 8px 0 !important;
}
#pagePuzzles .puzzles-sub {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text-dim) !important;
}

/* Mode tab bar */
#pagePuzzles .puz-mode-bar,
#pagePuzzles .puzzles-mode-bar,
#pagePuzzles .mode-tabs {
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  padding: 4px !important;
  margin-bottom: 16px !important;
  gap: 2px !important;
}
#pagePuzzles .puz-mode-btn,
#pagePuzzles .mode-tab {
  background: transparent !important;
  border: none !important;
  color: var(--text-dim) !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  border-radius: 2px !important;
  padding: 8px 16px !important;
}
#pagePuzzles .puz-mode-btn.active,
#pagePuzzles .mode-tab.active {
  background: var(--bg-3) !important;
  color: var(--accent) !important;
}

/* Puzzle board + sidebar */
#pagePuzzles .puz-board-wrap,
#pagePuzzles .puzzle-board,
#pagePuzzles .puz-board {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  padding: 12px !important;
}
#pagePuzzles .puz-info,
#pagePuzzles .puz-info-card,
#pagePuzzles .puz-side-panel,
#pagePuzzles .puz-stats {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-sm) !important;
  padding: 12px !important;
  color: var(--text) !important;
}
#pagePuzzles .puz-theme,
#pagePuzzles .puz-rating,
#pagePuzzles .puz-tag {
  background: transparent !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-pill) !important;
  color: var(--text-dim) !important;
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  padding: 4px 10px !important;
}
#pagePuzzles .puz-hint,
#pagePuzzles .hint-card {
  background: var(--bg-1) !important;
  border: 1px solid var(--accent) !important;
  border-radius: var(--radius-sm) !important;
  color: var(--text) !important;
  padding: 12px !important;
}

/* ================================================================
 * #pageEndgames (Trainer - openings catalog + endgame trainer)
 * Stitch: catalog grid + active training board+sidebar
 * ================================================================ */

#pageEndgames {
  background: var(--bg-0) !important;
  color: var(--text) !important;
  padding: var(--space-6) !important;
  max-width: 1440px;
  margin: 0 auto !important;
}

/* Sub-mode bar (Openings | Endgames). v0.195.13: the bar itself is just
   a spacer; the pill group provides the single box. */
#pageEndgames .trainer-submode-bar {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  display: block !important;
  margin-bottom: 16px !important;
}
#pageEndgames .trainer-submode-pill {
  background: transparent !important;
  border: none !important;
  color: var(--text-dim) !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  border-radius: 2px !important;
  padding: 8px 16px !important;
}
#pageEndgames .trainer-submode-pill.active {
  background: var(--bg-3) !important;
  color: var(--accent) !important;
}

/* Hero / titles */
#pageEndgames .op-hero,
#pageEndgames .eg-hero {
  margin-bottom: 24px !important;
  padding-bottom: 16px !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pageEndgames .op-hero h1,
#pageEndgames .eg-hero h1 {
  font-family: var(--font-display) !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  letter-spacing: -0.02em !important;
  margin: 0 0 8px 0 !important;
}
#pageEndgames .op-hero-sub,
#pageEndgames .eg-hero-sub {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text-dim) !important;
}

/* Catalog list. v0.195.13: V1-style stacked rows (full-width cards),
   not a 280px grid. Lucas prefers reading top-to-bottom. */
#pageEndgames .op-list-grid,
#pageEndgames .eg-list-grid,
#pageEndgames .op-grid,
#pageEndgames .eg-grid {
  display: flex !important;
  flex-direction: column !important;
  gap: var(--space-3) !important;
}
#pageEndgames .op-card,
#pageEndgames .eg-card,
#pageEndgames .opening-card,
#pageEndgames .endgame-card,
#pageEndgames .op-list-grid > *,
#pageEndgames .eg-list-grid > * {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  overflow: hidden !important;
  padding: 0 !important;
  transition: border-color 0.15s ease;
}
#pageEndgames .op-card:hover,
#pageEndgames .eg-card:hover,
#pageEndgames .opening-card:hover,
#pageEndgames .endgame-card:hover {
  border-color: var(--accent) !important;
}
#pageEndgames .op-card-title,
#pageEndgames .eg-card-title {
  font-family: var(--font-display) !important;
  font-size: 18px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
}
#pageEndgames .op-diff,
#pageEndgames .eg-diff,
#pageEndgames .op-difficulty,
#pageEndgames .eg-difficulty {
  background: transparent !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-pill) !important;
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  padding: 2px 10px !important;
  color: var(--text-dim) !important;
}

/* Difficulty filter chips */
#pageEndgames .op-diff-filter-row,
#pageEndgames .op-difficulty-filter,
#pageEndgames .eg-diff-filter {
  display: flex !important;
  gap: 8px !important;
  flex-wrap: wrap !important;
  margin-bottom: 16px !important;
}
#pageEndgames .op-diff-filter-row button,
#pageEndgames .op-difficulty-filter button {
  background: transparent !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-pill) !important;
  color: var(--text-dim) !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  padding: 6px 14px !important;
  height: auto !important;
}
#pageEndgames .op-diff-filter-row button.active,
#pageEndgames .op-difficulty-filter button.active {
  background: var(--accent-d) !important;
  color: var(--text) !important;
  border-color: var(--accent-d) !important;
}

/* Active training board area (opening practice / endgame trainer) */
#pageEndgames .op-board-wrap,
#pageEndgames .eg-board-wrap,
#pageEndgames .training-board {
  background: var(--bg-2) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  padding: 12px !important;
}
#pageEndgames .op-goal,
#pageEndgames .eg-goal,
#pageEndgames .goal-card {
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-left: 3px solid #e9c349 !important;
  border-radius: var(--radius-sm) !important;
  color: var(--text) !important;
  padding: 12px 16px !important;
  font-family: var(--font-body) !important;
}

/* ================================================================
 * #pageSettings
 * Stitch: stacked sections; appearance palette swatch grid
 * ================================================================ */

#pageSettings {
  background: var(--bg-0) !important;
  color: var(--text) !important;
  padding: var(--space-6) !important;
  max-width: 920px !important;
  margin: 0 auto !important;
}
#pageSettings .settings-hero {
  margin-bottom: 24px !important;
  padding-bottom: 16px !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pageSettings .settings-hero h1 {
  font-family: var(--font-display) !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  letter-spacing: -0.02em !important;
  margin: 0 0 8px 0 !important;
}
#pageSettings .settings-sub {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text-dim) !important;
}
#pageSettings .settings-section {
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  padding: 24px !important;
  margin-bottom: 16px !important;
}
#pageSettings .settings-section-title {
  font-family: var(--font-display) !important;
  font-size: 18px !important;
  font-weight: 600 !important;
  letter-spacing: -0.01em !important;
  color: var(--text) !important;
  margin: 0 0 16px 0 !important;
  padding-bottom: 8px !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pageSettings .settings-row {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) auto !important;
  gap: 16px !important;
  align-items: center !important;
  padding: 12px 0 !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pageSettings .settings-row:last-child {
  border-bottom: none !important;
}
#pageSettings .settings-row-name {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
}
#pageSettings .settings-row-desc {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--text-dim) !important;
  margin-top: 2px !important;
}


/* Toggle switch */
#pageSettings .toggle .toggle-slider,
#pageSettings .toggle-slider {
  background: var(--bg-3) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-pill) !important;
}
/* v0.195.87: the 1px border above shrinks the slider's content box and
   pushes the knob (positioned from the content-box top) ~2px low. Pull it
   up by 1px so the knob is vertically centered in the track again. */
#pageSettings .toggle .toggle-slider::before,
#pageSettings .toggle-slider::before {
  top: 2px !important;
  left: 2px !important;
}
#pageSettings .toggle input:checked + .toggle-slider {
  background: var(--accent-d) !important;
  border-color: var(--accent-d) !important;
}

/* Range slider track */
#pageSettings input[type="range"] {
  height: auto !important;
  background: transparent !important;
  border: none !important;
}
/* ================================================================
 * PP PHASE 2 (v0.192.0)
 * - Remap legacy --bg-* / --accent / --text tokens so all unstyled
 *   surfaces inherit PP colours (kills the brown-leather wash on
 *   pages we haven't explicitly overridden).
 * - Navrail labels reveal via ::after { content: attr(aria-label) }.
 * - data-pp-shape="pill" mode (toggleable from Settings).
 * - Shared motion: card hover-lift, button press, page fade-in.
 * ================================================================ */

/* v0.193.4: legacy-to-PP token remap DELETED. Was creating a circular
   var() dependency with the inverse mapping at the new :root PP block
   (which now defines --pp-* AS aliases of --bg-* / --accent / --text).
   With the cycle broken, the palette picker actually drives PP UI. */

/* Force PP background on every direct page wrapper so the brown
   wash from legacy .home-view / .stats-view / etc. can't bleed
   through. */
.page,
.page > main,
.home-view,
.stats-view,
.puzzles-view,
.trainer-view,
.play-view,
.settings-view {
  background: var(--bg-0) !important;
  color: var(--text) !important;
}

/* ----------------------------------------------------------------
 * Shape toggle infrastructure
 * data-pp-shape="squared" (default) -> existing 4px radii
 * data-pp-shape="pill" -> larger soft radii + pill chips/inputs
 * ---------------------------------------------------------------- */
html[data-pp-shape="pill"] .icon-btn,
html[data-pp-shape="pill"] .icon-btn-label,
html[data-pp-shape="pill"] .seg-btn,
html[data-pp-shape="pill"] .navrail-btn,
html[data-pp-shape="pill"] input[type="text"],
html[data-pp-shape="pill"] input[type="search"],
html[data-pp-shape="pill"] input[type="number"],
html[data-pp-shape="pill"] select,
html[data-pp-shape="pill"] .welcome-cta,
html[data-pp-shape="pill"] .filter-chip,
html[data-pp-shape="pill"] .chip,
html[data-pp-shape="pill"] .puz-mode-btn,
html[data-pp-shape="pill"] .trainer-submode-pill {
  border-radius: var(--radius-pill) !important;
}

/* ----------------------------------------------------------------
 * Navrail labels (icon + label, Stitch style)
 * Reveal text from aria-label using ::after content.
 * Settings + user-pill keep icon-only (no aria-label content).
 * ---------------------------------------------------------------- */
.navrail {
  width: 80px !important;
  padding-top: 16px !important;
  padding-bottom: 16px !important;
  gap: 4px;
}
.navrail-btn {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 4px !important;
  padding: 10px 4px !important;
  min-height: 64px !important;
  font-family: var(--font-body) !important;
  position: relative;
}
/* v0.193.4: static text labels under each navrail icon removed.
   Stitch reference (stitch-batch-2/.../hub_desktop) shows an icons-only
   compact rail with hover tooltips, no permanent labels. The original
   hover-tooltip rule at .navrail-btn[aria-label]::after (lines ~982-1016)
   is restored by killing the static-label hijacks that used to live here
   and at lines 8054-8090 (PP v0.192.0 patch). */
.navrail-btn svg {
  width: 22px !important;
  height: 22px !important;
}

/* Topbar should not have width that pushes content - shrink topbar-brand */
.topbar { padding-left: 24px !important; padding-right: 24px !important; }

/* ----------------------------------------------------------------
 * Animations baseline
 * - Cards: hover lifts 2px and brightens border
 * - Buttons: press = scale 0.98
 * - Page enter = fade in
 * - Reduced motion: respected
 * ---------------------------------------------------------------- */

@keyframes pp-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes pp-pop-in {
  from { opacity: 0; transform: scale(0.97); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes pp-shimmer {
  0% { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}

.page.active {
  animation: pp-fade-in 240ms cubic-bezier(0.2, 0, 0.2, 1);
}

button,
.btn,
.icon-btn,
.welcome-cta,
.seg-btn,
.persona-card,
.play-card,
.play-select-card,
.welcome-card {
  transition: transform 150ms cubic-bezier(0.2, 0, 0.2, 1),
              background-color 150ms ease,
              border-color 150ms ease,
              color 150ms ease,
              box-shadow 150ms ease;
}
button:active,
.btn:active,
.icon-btn:active,
.welcome-cta:active,
.seg-btn:active {
  transform: scale(0.97);
}
.welcome-card:hover,
.persona-card:hover,
.play-card:hover,
.play-select-card:hover,
.play-select-grid > *:hover,
#pageHome .game:hover,
#pageHome .game-item:hover,
#pageHome .game-row:hover,
#pageEndgames .op-card:hover,
#pageEndgames .eg-card:hover,
#pageEndgames .opening-card:hover,
#pageEndgames .endgame-card:hover {
  transform: translateY(-2px);
}

/* Filter chips colour transition */
.filter-chip,
.home-filter-chip,
.chip,
.puz-mode-btn,
.mode-tab,
.trainer-submode-pill,
.op-diff-filter-row button,
.op-difficulty-filter button {
  transition: background-color 150ms ease,
              color 150ms ease,
              border-color 150ms ease,
              transform 100ms ease;
}

/* Modal slide-up */
.modal-content,
.modal-panel,
.modal-card,
.dialog-content {
  animation: pp-pop-in 200ms cubic-bezier(0.2, 0, 0.2, 1);
}

/* Loading shimmer for skeletons (opt-in via .pp-skeleton class) */
.pp-skeleton {
  background: linear-gradient(
    90deg,
    var(--bg-2) 0%,
    var(--bg-3) 50%,
    var(--bg-2) 100%
  );
  background-size: 800px 100%;
  animation: pp-shimmer 1.4s linear infinite;
  border-radius: var(--radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* v0.193.4: PP v0.192.0 patch DELETED. The static-label hijack and the
 * width:88px override conflicted with the unified Stitch-style navrail
 * (now applied globally above). All width + button styling lives in the
 * stripped pp_block at line ~6515. Tooltip-on-hover is provided by the
 * base .navrail-btn[aria-label]::after rule at lines 982-1016.
 *
 * Short-form tooltip overrides for long aria-labels:
 */
.navrail-btn[data-page="welcome"][aria-label]::after { content: "Hub" !important; }
.navrail-btn[data-page="home"][aria-label]::after { content: "Analyze" !important; }
.navrail-btn[data-page="endgames"][aria-label]::after { content: "Trainer" !important; }

/* PP v0.192.0 patch B: hide labels on theme/season toggle navrail buttons
 * (they share .navrail-btn class but should remain icon-only popovers). */
#btnTheme[aria-label]::after,
#btnSeason[aria-label]::after,
.theme-toggle[aria-label]::after,
.season-toggle[aria-label]::after {
  display: none !important;
  content: none !important;
}
#btnTheme::after, #btnSeason::after { content: none !important; }

/* ================================================================
 * PP v0.192.0 - Persona card image-header treatment
 * Restyle play-card to look like Stitch persona cards:
 *  - tall radial-gradient image header with big icon
 *  - role badge top-right (per persona color)
 *  - big serif name
 *  - wide CTA at bottom, filled indigo on hover / selected
 * ================================================================ */

#pagePlay .play-card {
  display: flex !important;
  flex-direction: column !important;
  padding: 0 !important;
  position: relative;
  overflow: hidden !important;
  min-height: 480px;
}
#pagePlay .play-card-avatar {
  position: relative !important;
  width: 100% !important;
  height: 220px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  border-radius: 0 !important;
  margin: 0 !important;
  background: radial-gradient(ellipse at 50% 60%, var(--bg-3) 0%, var(--bg-0) 90%) !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
#pagePlay .play-card-avatar svg,
#pagePlay .play-card-avatar .persona-icon {
  width: 150px !important;
  height: 150px !important;
  color: var(--text) !important;
  opacity: 1 !important;
}
/* Boost stroke width so persona linework reads as crisp + intentional at
   hero size. The base SVGs use stroke-width=2.2 inside a 64-viewBox; at
   150px display that's only ~5px of effective stroke. */
#pagePlay .play-card-avatar svg g {
  stroke-width: 3 !important;
}
/* v0.193.5: Disable the inner sketch-wobble filter on persona icons at
   large display sizes - the turbulence/displacement looks visibly fuzzy
   when scaled past ~64px. Keep crisp linework instead. */
#pagePlay .play-card-avatar svg g[filter] {
  filter: none !important;
}

/* Per-persona radial backdrop tint */
#pagePlay .play-card[data-persona="balanced"] .play-card-avatar {
  background: radial-gradient(ellipse at 50% 60%, rgba(94, 92, 230, 0.38) 0%, var(--bg-0) 90%) !important;
}
#pagePlay .play-card[data-persona="balanced"] .play-card-avatar svg { color: #c2c1ff !important; opacity: 1 !important; }
#pagePlay .play-card[data-persona="aggressive"] .play-card-avatar {
  background: radial-gradient(ellipse at 50% 60%, rgba(255, 138, 102, 0.36) 0%, var(--bg-0) 90%) !important;
}
#pagePlay .play-card[data-persona="aggressive"] .play-card-avatar svg { color: #ffb786 !important; opacity: 1 !important; }
#pagePlay .play-card[data-persona="defensive"] .play-card-avatar {
  background: radial-gradient(ellipse at 50% 60%, rgba(120, 200, 130, 0.36) 0%, var(--bg-0) 90%) !important;
}
#pagePlay .play-card[data-persona="defensive"] .play-card-avatar svg { color: #b6d99a !important; opacity: 1 !important; }
#pagePlay .play-card[data-persona="mimic"] .play-card-avatar {
  background: radial-gradient(ellipse at 50% 60%, rgba(206, 156, 232, 0.36) 0%, var(--bg-0) 90%) !important;
}
#pagePlay .play-card[data-persona="mimic"] .play-card-avatar svg { color: #d8b6e3 !important; opacity: 1 !important; }

/* Subtle grid pattern overlay on image header for sci-fi feel */
#pagePlay .play-card-avatar::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px);
  background-size: 24px 24px;
  pointer-events: none;
}

/* Role badge top-right (content per persona) */
#pagePlay .play-card::before {
  content: "";
  position: absolute;
  top: 14px;
  right: 14px;
  background: rgba(20, 19, 20, 0.72);
  backdrop-filter: blur(6px);
  border: 1px solid var(--bg-3);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 5px 11px;
  color: var(--text);
  z-index: 2;
  white-space: nowrap;
}
#pagePlay .play-card[data-persona="balanced"]::before { content: "● Principled"; color: #c2c1ff; }
#pagePlay .play-card[data-persona="aggressive"]::before { content: "● Aggressive"; color: #ffb786; }
#pagePlay .play-card[data-persona="defensive"]::before { content: "● Defensive"; color: #b6d99a; }
#pagePlay .play-card[data-persona="mimic"]::before { content: "● Adaptive"; color: #d8b6e3; }

/* Hide legacy "The X" tag below name (replaced by role badge) */
#pagePlay .play-card-tag { display: none !important; }

/* Big serif persona name */
#pagePlay .play-card-name {
  font-family: var(--font-display) !important;
  font-size: 30px !important;
  font-weight: 700 !important;
  letter-spacing: -0.01em !important;
  color: var(--text) !important;
  margin: 20px 22px 10px !important;
  line-height: 1.1 !important;
}

/* Body description */
#pagePlay .play-card-desc {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  line-height: 1.55 !important;
  color: var(--text-dim) !important;
  margin: 0 22px 20px !important;
  flex: 1 1 auto !important;
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
}

/* Wide Challenge CTA - outline by default, fills on hover / selected */
#pagePlay .play-card-btn {
  width: calc(100% - 32px) !important;
  margin: 0 16px 16px !important;
  height: 44px !important;
  background: transparent !important;
  border: 1px solid var(--bg-3) !important;
  color: var(--text) !important;
  border-radius: var(--radius-sm) !important;
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em !important;
  cursor: pointer;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease, transform 100ms ease;
}
#pagePlay .play-card-btn::before {
  content: "⚔";
  font-size: 14px;
  opacity: 0.9;
}
#pagePlay .play-card-btn:hover,
#pagePlay .play-card.selected .play-card-btn {
  background: var(--accent-d) !important;
  border-color: var(--accent-d) !important;
  color: var(--text) !important;
}
#pagePlay .play-card-btn:active { transform: scale(0.98); }

/* Card hover lift */
#pagePlay .play-card:hover {
  border-color: var(--accent) !important;
  transform: translateY(-2px);
}

/* ===================================================================
 * v0.193.0 - Welcome page upgrade (round 1)
 * Brand wordmark in topbar, KPI watermarks, WLD bar, rich Last Game,
 * Daily Tactics sidebar. Designed to push toward the Stitch Hub spec
 * without restructuring HTML beyond a single new Daily Tactics card.
 * =================================================================== */

/* --- Topbar wordmark visible + styled on Welcome ------------------ */

body[data-page="welcome"] .topbar {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  padding: 0 24px !important;
}
body[data-page="welcome"] .topbar .brand-header {
  display: inline-flex !important;
  align-items: center !important;
  gap: 10px !important;
}
body[data-page="welcome"] .topbar .brand .logo {
  font-size: 28px !important;
  color: var(--accent) !important;
}
body[data-page="welcome"] .topbar .brand .title {
  font-family: var(--font-display) !important;
  font-weight: 700 !important;
  font-size: 22px !important;
  color: var(--text) !important;
  letter-spacing: -0.01em !important;
}

/* Hide the in-body brand wordmark on welcome (it lives in the topbar
   now) and tighten the hero spacing. */
#pageWelcome .welcome-brand { display: none !important; }
#pageWelcome .welcome-view {
  padding-top: 28px !important;
}

/* --- KPI cards: rating watermark + cleaner layout ----------------- */

#pageWelcome .welcome-card {
  position: relative !important;
  overflow: hidden !important;
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  padding: 22px 24px !important;
  min-height: 140px !important;
  transition: transform 160ms cubic-bezier(0.2, 0, 0.2, 1),
              border-color 160ms ease,
              box-shadow 160ms ease !important;
}
#pageWelcome .welcome-card:hover {
  transform: translateY(-3px) !important;
  border-color: var(--accent) !important;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35) !important;
}
#pageWelcome .welcome-card-label {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: var(--text-dim) !important;
  margin-bottom: 12px !important;
}
#pageWelcome .welcome-card-value {
  font-family: var(--font-display) !important;
  font-weight: 700 !important;
  font-size: 44px !important;
  line-height: 1 !important;
  color: var(--text) !important;
}
#pageWelcome .welcome-card-sub {
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  color: var(--text-dim) !important;
  margin-top: 8px !important;
}

/* Rating card: huge rook glyph watermark in the bottom-right */
#pageWelcome .welcome-card-rating::after {
  content: "";
  position: absolute;
  right: -8px; bottom: -16px;
  width: 130px; height: 130px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 45 45'><g fill='%23c2c1ff' opacity='0.08'><path d='M9 39h27v-3H9v3zm3-3v-4h21v4H12zm-1-22V9h4v2h5V9h5v2h5V9h4v5H11zm1 18v-9.5l3-1V14h15v7.5l3 1V32H12zm5-3h11v-7h-11v7zM12 36h21' stroke='%23c2c1ff' stroke-width='1.5' fill='none'/></g></svg>");
  background-size: contain;
  background-repeat: no-repeat;
  pointer-events: none;
}

/* Winrate card: WLD stacked bar */
.wc-wld-bar {
  display: flex !important;
  width: 100% !important;
  height: 10px !important;
  margin-top: 14px !important;
  border-radius: 999px !important;
  overflow: hidden !important;
  background: var(--bg-3) !important;
}
.wc-wld-bar > span { display: block; height: 100%; }
.wc-wld-bar .wc-wld-w { background: var(--accent); }
.wc-wld-bar .wc-wld-d { background: var(--text-dim); }
.wc-wld-bar .wc-wld-l { background: #e9c349; }

/* Personal puzzles card: matching watermark with a knight glyph for variety */
#pageWelcome .welcome-card-personal::after {
  content: "";
  position: absolute;
  right: -4px; bottom: -10px;
  width: 110px; height: 110px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 45 45'><path d='M22 10c10.5 1 16.5 8 16 29H15c0-9 10-6.5 8-21' fill='%23e0c97f' opacity='0.08' stroke='%23e0c97f' stroke-width='1.5'/><path d='M24 18c.38 2.91-5.55 7.37-8 9-3 2-2.82 4.34-5 4-1.04-.94 1.41-3.04 0-3-1 0 .19 1.23-1 2-1 0-4.003 1-4-4 0-2 6-12 6-12s1.89-1.9 2-3.5c-.73-.994-.5-2-.5-3 1-1 3 2.5 3 2.5h2s.78-1.992 2.5-3c1 0 1 3 1 3' fill='%23e0c97f' opacity='0.08' stroke='%23e0c97f' stroke-width='1.5'/></svg>");
  background-size: contain;
  background-repeat: no-repeat;
  pointer-events: none;
}

/* --- Last Game card: dramatic + outcome-tinted accent ------------- */

#pageWelcome .welcome-grid {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: 18px !important;
  margin-top: 24px !important;
}
#pageWelcome .welcome-card-lastgame {
  grid-column: 1 / 3 !important;
  grid-row: 2 !important;
  flex-direction: column !important;
  align-items: stretch !important;
  justify-content: flex-start !important;
  min-height: 200px !important;
  padding: 26px 28px !important;
  background: linear-gradient(135deg,
              var(--bg-1) 0%,
              var(--bg-0) 100%) !important;
  border-left: 3px solid var(--bg-3) !important;
}
#pageWelcome .welcome-card-lastgame[data-outcome="win"]  { border-left-color: var(--accent) !important; }
#pageWelcome .welcome-card-lastgame[data-outcome="loss"] { border-left-color: #e9c349 !important; }
#pageWelcome .welcome-card-lastgame[data-outcome="draw"] { border-left-color: var(--text-dim) !important; }

#pageWelcome .welcome-card-lastgame .welcome-card-label {
  margin-bottom: 14px !important;
}
#pageWelcome .welcome-card-lastgame .welcome-card-value {
  font-size: 28px !important;
  line-height: 1.2 !important;
}
.wc-lg-outcome {
  font-family: var(--font-display) !important;
  font-weight: 700 !important;
  padding: 2px 12px !important;
  border-radius: 999px !important;
  font-size: 22px !important;
  margin-right: 10px !important;
}
.wc-lg-outcome-win  { background: rgba(194, 193, 255, 0.18); color: var(--accent); }
.wc-lg-outcome-loss { background: rgba(255, 183, 134, 0.18); color: #e9c349; }
.wc-lg-outcome-draw { background: var(--bg-3); color: var(--text-dim); }
.wc-lg-vs {
  font-family: var(--font-body) !important;
  font-weight: 500 !important;
  font-size: 20px !important;
  color: var(--text) !important;
}
#pageWelcome .welcome-card-lastgame .welcome-card-sub {
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  margin-top: auto !important;
  padding-top: 18px !important;
}
.wc-lg-pill {
  background: var(--bg-3) !important;
  color: var(--text) !important;
  padding: 4px 10px !important;
  border-radius: 999px !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  text-transform: capitalize !important;
  letter-spacing: 0.03em !important;
}
.wc-lg-when {
  color: var(--text-dim) !important;
  font-size: 13px !important;
}
.wc-lg-cta {
  margin-left: auto !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
  color: var(--accent) !important;
  font-weight: 600 !important;
  font-size: 14px !important;
  text-transform: uppercase !important;
  letter-spacing: 0.05em !important;
}

/* --- Daily Tactics sidebar card ----------------------------------- */

#pageWelcome .welcome-card-tactics {
  grid-column: 3 !important;
  grid-row: 2 !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 14px !important;
  min-height: 200px !important;
  padding: 22px 24px !important;
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  text-decoration: none !important;
  color: inherit !important;
  transition: transform 160ms cubic-bezier(0.2, 0, 0.2, 1),
              border-color 160ms ease,
              box-shadow 160ms ease !important;
}
#pageWelcome .welcome-card-tactics:hover {
  transform: translateY(-3px) !important;
  border-color: var(--accent) !important;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35) !important;
}
.wc-tactics-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border-radius: 12px;
  background: var(--accent);
  color: var(--on-accent);
}
.wc-tactics-icon svg { width: 24px; height: 24px; }
.wc-tactics-body { display: flex; flex-direction: column; gap: 8px; flex: 1; }
.wc-tactics-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 20px;
  color: var(--text);
}
.wc-tactics-text {
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-dim);
}
.wc-tactics-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: auto;
  padding-top: 6px;
  color: var(--accent);
  font-weight: 600;
  font-size: 14px;
}

/* Responsive: collapse to single column under 980px */
@media (max-width: 980px) {
  #pageWelcome .welcome-grid {
    grid-template-columns: 1fr !important;
  }
  #pageWelcome .welcome-card-lastgame,
  #pageWelcome .welcome-card-tactics {
    grid-column: 1 !important;
    grid-row: auto !important;
  }
}

/* ===================================================================
 * v0.193.1 - cross-page polish
 * - Topbar GambitCoach wordmark on every page (not just Welcome)
 * - Activity heatmap recolored to indigo to match the PP palette
 * - Stat cards get icon prefix + PP styling + hover lift
 * - Persona Side selector buttons gain visible labels and color
 * =================================================================== */

/* --- Topbar wordmark visible on every page ------------------------ */
.brand-header { display: inline-flex !important; align-items: center !important; gap: 10px !important; }
body[data-page] .topbar .brand .logo {
  font-size: 26px !important;
  color: var(--accent) !important;
}
body[data-page] .topbar .brand .title {
  font-family: "Literata", Georgia, serif !important;
  font-style: italic !important;
  font-weight: 600 !important;
  font-size: 22px !important;
  color: var(--accent) !important;
  letter-spacing: -0.01em !important;
}

/* --- Activity heatmap recolored to indigo (PP primary) ------------ */
.hmap-l0 { background: var(--bg-3) !important; }
.hmap-l1 { background: rgba(194, 193, 255, 0.18) !important; }
.hmap-l2 { background: rgba(194, 193, 255, 0.40) !important; }
.hmap-l3 { background: rgba(194, 193, 255, 0.70) !important; }
.hmap-l4 { background: rgba(194, 193, 255, 1.00) !important; }
.hmap-cell:hover { outline: 1px solid var(--accent) !important; }
.hmap-legend { color: var(--text-dim) !important; }

/* --- Stat cards get PP polish + icon prefix ----------------------- */
#pageStats .stat-card {
  position: relative !important;
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: var(--radius-md) !important;
  padding: 18px 20px !important;
  transition: transform 160ms cubic-bezier(0.2, 0, 0.2, 1),
              border-color 160ms ease,
              box-shadow 160ms ease !important;
}
#pageStats .stat-card:hover {
  transform: translateY(-3px) !important;
  border-color: var(--accent) !important;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35) !important;
}
#pageStats .stat-card .lbl {
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: var(--text-dim) !important;
  margin-bottom: 8px !important;
  display: inline-block !important;
}
#pageStats .stat-card .val {
  font-family: var(--font-display) !important;
  font-weight: 700 !important;
  font-size: 30px !important;
  line-height: 1 !important;
  color: var(--text) !important;
}
#pageStats .stat-card.accent .val {
  color: var(--accent) !important;
}
#pageStats .stat-card .sub {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--text-dim) !important;
  margin-top: 6px !important;
}
.stat-card-icon {
  position: absolute !important;
  top: 14px !important;
  right: 16px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 28px !important;
  height: 28px !important;
  color: var(--accent) !important;
  opacity: 0.85 !important;
}
.stat-card-icon svg {
  width: 22px !important;
  height: 22px !important;
}

/* --- Persona Side selector buttons: clearer + colorful ------------ */
#pagePlay .seg-side .seg-btn {
  min-width: 56px !important;
  padding: 10px 14px !important;
  font-weight: 600 !important;
}
#pagePlay .seg-side .seg-btn[data-side="white"] { color: #f5f5f5 !important; }
#pagePlay .seg-side .seg-btn[data-side="black"] { color: #1a1a22 !important; background: #d0d0d0 !important; }
#pagePlay .seg-side .seg-btn[data-side="random"] { color: var(--text-dim) !important; }
#pagePlay .seg-side .seg-btn.active {
  background: var(--accent) !important;
  color: var(--on-accent) !important;
  border-color: var(--accent) !important;
}

/* --- "115 of 115 games" caption gets PP eyebrow look -------------- */
#pageHome .gallery-count,
#pageHome [class*="-count"]:not([class*="moves"]) {
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: var(--text-dim) !important;
}

/* --- Stats hero gets a subtitle slot (CSS-only) ------------------- */
#pageStats .stats-hero h1 + .stats-sub,
#pageStats .stats-hero h1 + #statsSub {
  display: inline-block !important;
  margin-top: 6px !important;
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text-dim) !important;
}

/* v0.193.5: Settings shape toggle (Squared | Pill) was collapsing to
   ~50px wide because `.seg-btn { flex: 1 }` on a flex:0-basis pair
   inside an `auto`-sized grid column. Give the settings shape seg
   a usable min-width so both pills are tappable. */
#pageSettings .seg-shape {
  min-width: 160px;
}
#pageSettings .seg-shape .seg-btn {
  padding: 6px 12px;
  font-size: 13px;
}
/* v0.195.87: the Theme (Dark | Light) segmented control was collapsing
   to its content width, so the two pills sat cramped together. Give it a
   comfortable fixed width and roomier pills so it reads as a clean
   two-option toggle. */
#pageSettings #settingsThemeSeg {
  min-width: 200px;
  padding: 3px;
  gap: 4px;
}
#pageSettings #settingsThemeSeg .seg-btn {
  padding: 7px 14px;
  font-size: 13px;
}


/* ===================================================================
 * v0.193.8 - Stitch Hub layout for #pageWelcome
 *
 * Direct port of the canonical Stitch Hub - Desktop screen (see
 * stitch-batch-4/screen.png and .copilot/skills/chess-master/
 * references/stitch-design-system.md). The DOM lives in index.html
 * (#pageWelcome > main.hub-canvas). The Hub is INSIDE the existing
 * navrail + topbar shell of the app, so these styles only own the
 * canvas contents - sidebar/topbar styling stays as-is.
 *
 * Token mapping (Stitch DESIGN.md to chess-master CSS custom props):
 *   surface              -> var(--bg-0)
 *   surface-container-low -> var(--bg-1) / --pp-surface-container-low
 *   surface-container     -> var(--bg-2)
 *   surface-container-high -> var(--bg-3)
 *   surface-container-highest -> var(--bg-4)
 *   outline-variant       -> var(--bg-3)
 *   outline               -> var(--text-faint)
 *   on-surface            -> var(--text)
 *   on-surface-variant    -> var(--text-dim)
 *   primary               -> var(--accent)
 *   primary-container     -> var(--accent)
 *   on-primary            -> #1800a7
 * In non-Stitch palettes the same tokens still produce a coherent
 * card-bento grid (just in the user's selected accent colour).
 * =================================================================== */

#pageWelcome .hub-canvas {
  display: flex !important;
  flex-direction: column !important;
  gap: 24px !important;
  max-width: 1440px !important;
  margin: 0 auto !important;
  padding: 24px !important;
  width: 100% !important;
  background: transparent !important;
}

/* ----- Hero row ----- */
.hub-hero {
  display: flex !important;
  flex-direction: row !important;
  justify-content: space-between !important;
  align-items: flex-end !important;
  gap: 24px !important;
  padding-bottom: 24px !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
.hub-hero-text { flex: 1 1 auto; min-width: 0; }
.hub-eyebrow {
  font-family: "Geist", "Inter", system-ui, sans-serif !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  line-height: 1 !important;
  letter-spacing: 0.12em !important;
  text-transform: uppercase !important;
  color: var(--text-dim) !important;
  margin: 0 0 12px 0 !important;
}
.hub-display {
  font-family: "Literata", Georgia, serif !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  line-height: 1.1 !important;
  letter-spacing: -0.02em !important;
  color: var(--text) !important;
  margin: 0 !important;
  word-break: break-word;
}
.hub-display-greeting { color: var(--text); }
.hub-display-name { color: var(--accent); }
.hub-display-period { color: var(--text); }

.hub-play-now {
  flex: 0 0 auto !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  height: 40px !important;
  padding: 0 24px !important;
  background: var(--accent) !important;
  color: var(--on-accent) !important;
  border: none !important;
  border-radius: 4px !important;
  font-family: "Geist", "Inter", system-ui, sans-serif !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  cursor: pointer !important;
  transition: background 160ms ease, transform 100ms ease !important;
  box-shadow: none !important;
}
.hub-play-now:hover { background: var(--accent-d, var(--accent)) !important; }
.hub-play-now:active { transform: scale(0.97) !important; }
.hub-play-now .material-symbols-outlined {
  font-size: 18px !important;
  color: inherit !important;
}

/* ----- Stat bento (3-column KPI row) ----- */
.hub-stats {
  display: grid !important;
  grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  gap: 16px !important;
}
.hub-stat-card {
  position: relative !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 24px !important;
  padding: 16px !important;
  min-height: 128px !important;
  background: var(--bg-0) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: 4px !important;
  overflow: hidden !important;
  text-align: left !important;
  cursor: pointer !important;
  transition: border-color 160ms ease, background 160ms ease !important;
  font-family: "Geist", "Inter", system-ui, sans-serif !important;
  color: var(--text) !important;
  appearance: none !important;
  box-shadow: none !important;
}
.hub-stat-card:hover {
  border-color: var(--accent) !important;
  background: var(--bg-1) !important;
}
.hub-stat-card:focus-visible {
  outline: 2px solid var(--accent) !important;
  outline-offset: 2px !important;
}
.hub-stat-head {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  z-index: 1 !important;
}
.hub-stat-icon {
  font-size: 20px !important;
  color: var(--text-dim) !important;
}
.hub-stat-label {
  flex: 1 1 auto;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: var(--text-dim) !important;
  line-height: 1 !important;
}
.hub-stat-side {
  flex: 0 0 auto;
  font-family: "Geist", monospace !important;
  font-size: 13px !important;
  font-weight: 400 !important;
  letter-spacing: -0.01em !important;
  color: var(--text-faint) !important;
  line-height: 1 !important;
}
.hub-stat-body {
  display: flex !important;
  align-items: flex-end !important;
  gap: 12px !important;
  z-index: 1 !important;
}
.hub-stat-value {
  font-family: "Literata", Georgia, serif !important;
  font-size: 48px !important;
  font-weight: 700 !important;
  line-height: 1 !important;
  letter-spacing: -0.02em !important;
  color: var(--text) !important;
}
.hub-stat-delta {
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
  font-family: "Geist", monospace !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  color: var(--accent) !important;
  margin-bottom: 6px !important;
}
.hub-stat-suffix {
  font-size: 14px !important;
  color: var(--text-dim) !important;
  margin-bottom: 6px !important;
}
.hub-stat-sub {
  font-size: 12px !important;
  color: var(--text-dim) !important;
  line-height: 1.4 !important;
}
.hub-stat-bg-icon {
  position: absolute !important;
  right: -18px !important;
  bottom: -18px !important;
  opacity: 0.06 !important;
  pointer-events: none !important;
  transition: opacity 160ms ease !important;
  z-index: 0 !important;
}
.hub-stat-card:hover .hub-stat-bg-icon { opacity: 0.12 !important; }
.hub-stat-bg-icon .material-symbols-outlined {
  font-size: 120px !important;
  color: var(--text) !important;
}

/* Win-rate inline progress segments (rendered by JS into wcWinrateValue). */
.hub-winrate-bar {
  display: flex;
  height: 4px;
  width: 100%;
  background: var(--bg-3);
  border-radius: 9999px;
  overflow: hidden;
  margin-top: 8px;
}
.hub-winrate-bar > span { display: block; height: 100%; }
.hub-winrate-w { background: var(--accent); }
.hub-winrate-d { background: var(--text-faint); }
.hub-winrate-l { background: var(--cat-blunder, #fa412d); }

/* ----- Deep row: 8-col last game + 4-col tactics ----- */
.hub-deep {
  display: grid !important;
  grid-template-columns: 2fr 1fr !important;
  gap: 16px !important;
  margin-top: 8px !important;
}

.hub-lastgame {
  display: flex !important;
  flex-direction: column !important;
  background: var(--bg-1) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: 4px !important;
  overflow: hidden !important;
}
.hub-lastgame-head {
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
  gap: 12px !important;
  padding: 16px 20px !important;
  background: var(--bg-0) !important;
  border-bottom: 1px solid var(--bg-3) !important;
}
.hub-lastgame-title {
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  margin: 0 !important;
  font-family: "Literata", Georgia, serif !important;
  font-size: 20px !important;
  font-weight: 500 !important;
  line-height: 1.4 !important;
  color: var(--text) !important;
}
.hub-lastgame-title .material-symbols-outlined {
  font-size: 22px !important;
  color: var(--accent) !important;
}
.hub-lastgame-pills {
  display: inline-flex !important;
  gap: 8px !important;
}
.hub-lastgame-pill {
  display: inline-block;
  padding: 4px 8px;
  background: var(--bg-4);
  border-radius: 4px;
  font-family: "Geist", monospace;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1;
}
.hub-lastgame-body {
  display: flex !important;
  flex-direction: row !important;
  gap: 24px !important;
  padding: 20px !important;
  align-items: stretch !important;
}
.hub-mini-board {
  flex: 0 0 128px;
  width: 128px;
  height: 128px;
  border: 1px solid var(--bg-3);
  border-radius: 2px;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  overflow: hidden;
}
.hub-mini-board .sq { width: 100%; height: 100%; }
.hub-mini-board .sq-light { background-color: var(--light-sq); opacity: 0.85; }
.hub-mini-board .sq-dark  { background-color: var(--dark-sq); }

.hub-lastgame-match {
  flex: 1 1 auto !important;
  display: flex !important;
  flex-direction: column !important;
  justify-content: center !important;
  gap: 12px !important;
  min-width: 0 !important;
}
.hub-lastgame-row {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  gap: 12px !important;
  padding-bottom: 8px !important;
}
.hub-lastgame-row + .hub-lastgame-row {
  border-top: 1px solid var(--bg-3);
  padding-top: 8px;
  padding-bottom: 0;
}
.hub-lastgame-player {
  display: inline-flex !important;
  align-items: center !important;
  gap: 12px !important;
  min-width: 0 !important;
}
.hub-lastgame-chip {
  width: 16px;
  height: 16px;
  border-radius: 2px;
  border: 1px solid var(--bg-3);
  flex-shrink: 0;
}
.hub-lastgame-chip-white { background: var(--text); }
.hub-lastgame-chip-black { background: var(--bg-0); }
.hub-lastgame-name {
  font-family: "Geist", "Inter", system-ui, sans-serif;
  font-size: 16px;
  font-weight: 400;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hub-lastgame-name.is-me {
  color: var(--accent);
  font-weight: 500;
}
.hub-lastgame-rating {
  font-family: "Geist", monospace;
  font-size: 13px;
  color: var(--text-faint);
}
.hub-lastgame-score {
  font-family: "Geist", monospace;
  font-size: 13px;
  font-weight: 700;
  flex-shrink: 0;
}
.hub-lastgame-score.is-win   { color: var(--accent); }
.hub-lastgame-score.is-loss  { color: var(--cat-blunder, #fa412d); }
.hub-lastgame-score.is-draw  { color: var(--text-dim); }
.hub-lastgame-empty {
  margin: 0;
  color: var(--text-dim);
  font-size: 14px;
}
.hub-lastgame-actions {
  display: flex !important;
  gap: 12px !important;
  margin-top: 8px !important;
}
.hub-lastgame-btn {
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  height: 32px !important;
  padding: 0 16px !important;
  background: var(--bg-0) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: 4px !important;
  color: var(--text) !important;
  font-family: "Geist", "Inter", system-ui, sans-serif !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  cursor: pointer !important;
  transition: border-color 160ms ease !important;
}
.hub-lastgame-btn:hover {
  border-color: var(--accent) !important;
}
.hub-lastgame-btn .material-symbols-outlined {
  font-size: 16px !important;
}

/* ----- Daily Tactics ----- */
.hub-tactics {
  display: flex !important;
  flex-direction: column !important;
  justify-content: space-between !important;
  gap: 16px !important;
  padding: 20px !important;
  background: var(--bg-0) !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: 4px !important;
  text-decoration: none !important;
  color: var(--text) !important;
  transition: border-color 160ms ease, background 160ms ease !important;
}
.hub-tactics:hover {
  border-color: var(--accent) !important;
  background: var(--bg-1) !important;
}
.hub-tactics-icon {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 40px !important;
  height: 40px !important;
  background: var(--accent) !important;
  color: var(--on-accent) !important;
  border-radius: 4px !important;
  margin-bottom: 4px !important;
}
.hub-tactics-icon .material-symbols-outlined { font-size: 22px !important; }
.hub-tactics-title {
  font-family: "Literata", Georgia, serif !important;
  font-size: 20px !important;
  font-weight: 500 !important;
  line-height: 1.4 !important;
  color: var(--text) !important;
  margin: 0 !important;
}
.hub-tactics-text {
  font-family: "Geist", "Inter", system-ui, sans-serif !important;
  font-size: 14px !important;
  font-weight: 400 !important;
  line-height: 1.5 !important;
  color: var(--text-dim) !important;
  margin: 0 0 12px 0 !important;
}
.hub-tactics-btn {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  width: 100% !important;
  height: 40px !important;
  border: 1px solid var(--bg-3) !important;
  border-radius: 4px !important;
  background: transparent !important;
  color: var(--text) !important;
  font-family: "Geist", "Inter", system-ui, sans-serif !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  transition: background 160ms ease, border-color 160ms ease !important;
}
.hub-tactics:hover .hub-tactics-btn {
  background: var(--bg-3) !important;
  border-color: var(--accent) !important;
}
.hub-tactics-btn .material-symbols-outlined { font-size: 16px !important; }

/* ----- Mobile (collapse to single column) ----- */
@media (max-width: 900px) {
  #pageWelcome .hub-canvas { padding: 16px !important; gap: 16px !important; }
  .hub-hero { flex-direction: column !important; align-items: stretch !important; }
  .hub-display { font-size: 32px !important; }
  .hub-stats { grid-template-columns: 1fr !important; }
  .hub-deep { grid-template-columns: 1fr !important; }
  .hub-lastgame-body { flex-direction: column !important; align-items: center !important; }
  .hub-stat-value { font-size: 40px !important; }
}

/* ----- Override legacy welcome-* styles inside the Stitch hub ----- */
#pageWelcome.hub-canvas,
#pageWelcome .welcome-view.hub-canvas {
  padding-top: 24px !important;
}
#pageWelcome .welcome-brand,
#pageWelcome .welcome-hero,
#pageWelcome .welcome-cta:not(.hub-play-now):not(#welcomeCta.hub-play-now),
#pageWelcome .welcome-grid {
  display: none !important;
}
#pageWelcome .hub-legacy-compat { display: none !important; }

/* ============================================================ */
/*  v2 DESIGN SYSTEM - Ship 1 final overrides                  */
/* ============================================================ */
body {
  background: var(--bg-0) !important;
  color: var(--text) !important;
  font-family: var(--font-body) !important;
}
.app-shell {
  margin-left: 72px !important;
}
.navrail.v2-rail {
  position: fixed !important;
  left: 0 !important;
  top: 0 !important;
  height: 100% !important;
  width: 72px !important;
  overflow: hidden !important;
  display: flex !important;
  flex-direction: column !important;
  padding: 24px 0 !important;
  gap: 0 !important;
  background: var(--bg-1) !important;
  border-right: 1px solid var(--border-default) !important;
  box-shadow: none !important;
  z-index: 60 !important;
  /* v0.195.37: single, undelayed width transition. The labels live
     in flow at all times and are clipped by the rail's overflow:hidden
     when collapsed (label sits LEFT of icon, slides off the left edge
     during collapse). No stagger or delay needed. */
  will-change: width !important;
  contain: layout style !important;
  transition: width 220ms cubic-bezier(0.4, 0, 0.2, 1) !important;
}
.navrail.v2-rail:hover,
.navrail.v2-rail.open {
  width: 240px !important;
}
.navrail.v2-rail .navrail-list {
  list-style: none !important;
  margin: 0 !important;
  /* v0.195.37: padding zeroed to give the buttons the full 72px /
     240px rail width to play with. Per-button padding handles the
     internal icon position. */
  padding: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  gap: var(--space-2) !important;
  width: 100% !important;
  min-width: 0 !important;
}
.navrail.v2-rail .navrail-list li {
  width: 100% !important;
  min-width: 0 !important;
}
.navrail.v2-rail .navrail-spacer {
  flex: 1 1 auto !important;
  min-height: 0 !important;
}
.navrail.v2-rail .navrail-btn {
  /* v0.195.37: labels-on-left layout (per Lucas). DOM order is
     icon-then-label, so flex-direction:row-reverse flips the visual
     order to [label] [icon] without HTML changes. Buttons are always
     100% wide so the rail's width transition is the ONLY animation
     running. The icon sits flush right (justify-content:flex-start
     in row-reverse) with a 24px right pad so it is centered in the
     72px collapsed rail (icon_center = 72 - 24 - 12 = 36 = rail
     center). When the rail expands to 240px the same icon slides
     right by 168px as the rail grows; the label fills the new space
     to the left of the icon. Earlier hover overrides for
     width/padding/justify-content removed: the layout is constant,
     only the parent rail width changes. */
  display: flex !important;
  flex-direction: row-reverse !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 14px !important;
  width: 100% !important;
  /* CRITICAL: flexbox default is min-width:auto (== content min-width),
     which would let the button grow to fit label+icon (~127px) and
     spill out the left side of the 72px collapsed rail. min-width:0
     forces the button to honour width:100% even when overflowing. */
  min-width: 0 !important;
  box-sizing: border-box !important;
  height: 40px !important;
  margin: 0 !important;
  min-height: 0 !important;
  padding: 0 24px 0 16px !important;
  border: none !important;
  border-right: none !important;
  border-radius: var(--radius-md) !important;
  background: transparent !important;
  color: var(--text-secondary) !important;
  font-family: var(--font-body) !important;
  font-weight: 500 !important;
  white-space: nowrap !important;
  text-align: left !important;
  overflow: hidden !important;
  /* Only one transition runs during expand/collapse: the rail width.
     Buttons inherit by being width:100%, so we just animate color
     state changes here. */
  transition: background 180ms ease-out, color 180ms ease-out !important;
}
.navrail.v2-rail .navrail-btn i {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 24px !important;
  height: 24px !important;
  font-size: 22px !important;
}
.navrail.v2-rail .navrail-btn .navrail-label {
  /* v0.195.37: label always in flow, but opacity-fades with the rail
     width transition. The label sits left of the icon (row-reverse)
     so when the rail collapses to 72px the label's right edge lands
     near the rail's left edge, with a sliver still visible. opacity
     is a paint-only property so this runs on the compositor without
     causing reflow; combined with the SAME 220ms duration as the
     rail width, it looks like one fluid motion. */
  display: inline !important;
  flex: 0 0 auto !important;
  white-space: nowrap !important;
  opacity: 0 !important;
  transition: opacity 220ms cubic-bezier(0.4, 0, 0.2, 1) !important;
}
.navrail.v2-rail:hover .navrail-btn .navrail-label,
.navrail.v2-rail.open .navrail-btn .navrail-label {
  opacity: 1 !important;
}
.navrail.v2-rail .navrail-btn:hover {
  background: var(--bg-3) !important;
  color: var(--text-primary) !important;
}
.navrail.v2-rail .navrail-btn.active {
  /* v0.195.38: use accent vars so the active-page indicator follows
     the chosen colour palette (iris/emerald/coral/sapphire). */
  background: var(--accent-soft) !important;
  color: var(--accent) !important;
  position: relative !important;
}
.navrail.v2-rail .navrail-btn.active::before {
  display: none !important;
}
.navrail.v2-rail:hover .navrail-btn.active::before {
  display: none !important;
}
.navrail.v2-rail .navrail-btn.active i.ph {
  display: none !important;
}
.navrail.v2-rail .navrail-btn.active i.ph-duotone {
  display: inline-block !important;
}
.navrail.v2-rail .navrail-btn:not(.active) i.ph-duotone {
  display: none !important;
}
.navrail.v2-rail .navrail-auth-widget {
  width: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  display: block !important;
}
/* v0.195.84: the auth widget must track the rail exactly like a
   .navrail-btn. Both the signed-out "Sign in" link and the signed-in
   user block lay out as row-reverse rows: the icon/avatar is pinned
   flush-right (same x as the nav icons, centered in the 72px collapsed
   rail) and the text label/meta sits to its left, fading in only when
   the rail expands. Previously the widget was display:block, so its
   fixed-width content hugged the LEFT edge and visibly drifted out of
   line with the right-aligned nav icons. */
.navrail.v2-rail .naw-signin {
  display: flex !important;
  flex-direction: row-reverse !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 14px !important;
  width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
  height: 40px !important;
  padding: 0 24px 0 16px !important;
  border-radius: var(--radius-md) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  white-space: nowrap !important;
  overflow: hidden !important;
}
.navrail.v2-rail .naw-signin svg {
  width: 22px !important;
  height: 22px !important;
  flex: 0 0 auto !important;
}
.navrail.v2-rail .naw-signin span {
  flex: 0 0 auto !important;
  opacity: 0 !important;
  transition: opacity 220ms cubic-bezier(0.4, 0, 0.2, 1) !important;
}
.navrail.v2-rail:hover .naw-signin span,
.navrail.v2-rail.open .naw-signin span {
  opacity: 1 !important;
}
.navrail.v2-rail .naw-user {
  display: flex !important;
  flex-direction: row-reverse !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 14px !important;
  width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
  /* v0.195.87: match the .navrail-btn icon box exactly (24px right pad)
     so the avatar's center AND right edge line up with the nav icons. */
  padding: 0 24px 0 16px !important;
  overflow: hidden !important;
}
.navrail.v2-rail .naw-avatar {
  flex: 0 0 auto !important;
  width: 24px !important;
  height: 24px !important;
  font-size: 12px !important;
}
.navrail.v2-rail .naw-meta {
  display: flex !important;
  flex-direction: column !important;
  align-items: flex-start !important;
  gap: 2px !important;
  min-width: 0 !important;
  opacity: 0 !important;
  transition: opacity 220ms cubic-bezier(0.4, 0, 0.2, 1) !important;
}
.navrail.v2-rail:hover .naw-meta,
.navrail.v2-rail.open .naw-meta {
  opacity: 1 !important;
}
.navrail.v2-rail .naw-email {
  max-width: 150px !important;
  text-align: left !important;
}
.topbar.v2-topbar {
  position: absolute !important;
  top: 0 !important;
  right: 0 !important;
  left: 72px !important;
  height: 56px !important;
  padding: 0 var(--space-8) !important;
  background: transparent !important;
}
#pageWelcome {
  padding: 0 !important;
  max-width: none !important;
  margin: 0 !important;
  background: transparent !important;
}
.v2-hub-canvas {
  margin-left: auto !important;
  margin-right: auto !important;
  padding: var(--space-8) !important;
  min-height: 100vh !important;
  max-width: 1600px !important;
}

/* ================================================================
 * v0.194.12 - v2 Play page (Ship 9 of redesign train)
 * Picker: v2 header + control bar (Color/Time/Rating) + persona cards
 * Active game: v2 surfaces, Phosphor icons, mentor card.
 * ================================================================ */

/* -- Picker page header -- */
.v2-play-picker {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 28px;
  padding: 0 0 40px;
}
.v2-play-hd {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.v2-play-eyebrow {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-faint);
}
.v2-play-h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  line-height: 1.15;
}
.v2-play-sub {
  margin: 0;
  font-size: 14px;
  color: var(--text-dim);
  line-height: 1.5;
}

/* -- Control bar -- */
.v2-play-ctrl-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px 28px;
  background: var(--bg-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: 14px 20px;
}
.v2-play-ctrl-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.v2-play-ctrl-label {
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-faint);
}

/* -- Color segmented control -- */
.v2-play-seg {
  display: flex;
  background: var(--bg-1);
  border-radius: 8px;
  padding: 3px;
  gap: 2px;
}
.v2-play-seg .seg-btn {
  padding: 5px 14px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  border: none;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  transition: background 140ms, color 140ms;
}
.v2-play-seg .seg-btn:hover {
  color: var(--text);
  background: rgba(var(--accent-rgb), 0.08);
}
.v2-play-seg .seg-btn.active {
  background: var(--border-default);
  color: var(--text);
}

/* -- Time-control inline pills -- */
.v2-play-tc-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.v2-play-tc-pill {
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--border-default);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  transition: border-color 140ms, color 140ms, background 140ms;
}
.v2-play-tc-pill:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.v2-play-tc-pill.active {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), 0.12);
  color: var(--accent);
}
/* Disable styles when game is in progress */
.play-shared-cluster-tc.is-disabled .v2-play-tc-pills { opacity: 0.5; pointer-events: none; }

/* -- Target rating chip -- */
.v2-play-rating-wrap { position: relative; }
.v2-play-rating-trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-default);
  background: var(--bg-1);
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 140ms, color 140ms;
}
.v2-play-rating-trigger:hover {
  border-color: var(--accent);
  color: var(--text);
}
.v2-play-rating-trigger i { font-size: 14px; }
.v2-play-rating-caret { font-size: 10px; opacity: 0.6; }
.v2-play-rating-label { color: var(--text); font-weight: 700; }
/* Lock while playing */
.play-shared-cluster-strength.is-disabled .v2-play-rating-trigger { opacity: 0.5; pointer-events: none; }

/* -- Advanced options disclosure -- */
.v2-play-advanced {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-1);
  overflow: hidden;
}
.v2-play-advanced-toggle {
  padding: 14px 18px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-dim);
  cursor: pointer;
  list-style: none;
  user-select: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: color 160ms ease-out, background 160ms ease-out;
}
.v2-play-advanced-toggle:hover { color: var(--text); background: var(--bg-2); }
.v2-play-advanced-toggle::after {
  content: "";
  width: 8px; height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 200ms ease-out;
  margin-right: 4px;
}
details.v2-play-advanced[open] .v2-play-advanced-toggle::after {
  transform: rotate(-135deg);
}
.v2-play-advanced-toggle::-webkit-details-marker { display: none; }
details.v2-play-advanced[open] .v2-play-advanced-toggle { color: var(--text); }
.v2-play-advanced-row {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 18px 18px 20px;
  border-top: 1px solid var(--border-default);
}
.v2-play-advanced-row .v2-play-ctrl-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.v2-play-advanced-row .v2-play-ctrl-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.v2-play-advanced-row .seg {
  align-self: flex-start;
  padding: 4px;
  gap: 4px;
}
.v2-play-advanced-row .seg-btn {
  flex: 0 0 auto;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 500;
}
details.v2-play-advanced[open] .v2-play-advanced-row {
  animation: v2AdvancedSlide 220ms ease-out;
}
@keyframes v2AdvancedSlide {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  details.v2-play-advanced[open] .v2-play-advanced-row { animation: none; }
  .v2-play-advanced-toggle::after { transition: none; }
}

/* -- Persona card v2 updates -- */
/* Gradient portrait backgrounds per task spec: grey/crimson/emerald/iris */
#pagePlay .play-card[data-persona="balanced"] .play-card-avatar {
  background: radial-gradient(ellipse at 50% 60%,
    rgba(130, 126, 148, 0.42) 0%, var(--bg-0) 90%) !important;
}
#pagePlay .play-card[data-persona="balanced"] .play-card-avatar svg {
  color: #c8c8d8 !important; opacity: 1 !important;
}
#pagePlay .play-card[data-persona="aggressive"] .play-card-avatar {
  background: radial-gradient(ellipse at 50% 60%,
    rgba(239, 68, 68, 0.38) 0%, var(--bg-0) 90%) !important;
}
#pagePlay .play-card[data-persona="aggressive"] .play-card-avatar svg {
  color: #fca5a5 !important; opacity: 1 !important;
}
#pagePlay .play-card[data-persona="defensive"] .play-card-avatar {
  background: radial-gradient(ellipse at 50% 60%,
    rgba(16, 185, 129, 0.32) 0%, var(--bg-0) 90%) !important;
}
#pagePlay .play-card[data-persona="defensive"] .play-card-avatar svg {
  color: #6ee7b7 !important; opacity: 1 !important;
}
#pagePlay .play-card[data-persona="mimic"] .play-card-avatar {
  background: radial-gradient(ellipse at 50% 60%,
    rgba(124, 92, 255, 0.36) 0%, var(--bg-0) 90%) !important;
}
#pagePlay .play-card[data-persona="mimic"] .play-card-avatar svg {
  color: #c4b5fd !important; opacity: 1 !important;
}

/* Role badge text updated to match new palette */
#pagePlay .play-card[data-persona="balanced"]::before   { content: "Universal";  color: #c8c8d8; }
#pagePlay .play-card[data-persona="aggressive"]::before { content: "Aggressive"; color: #fca5a5; }
#pagePlay .play-card[data-persona="defensive"]::before  { content: "Defensive";  color: #6ee7b7; }
#pagePlay .play-card[data-persona="mimic"]::before      { content: "Adaptive";   color: #c4b5fd; }

/* Italic Newsreader quote for card desc */
#pagePlay .play-card-desc {
  font-family: var(--font-editorial) !important;
  font-style: italic !important;
  font-size: 14px !important;
  color: var(--text-dim) !important;
  line-height: 1.5 !important;
}

/* Elo badge */
.v2-pc-elo-badge {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  background: rgba(var(--accent-rgb), 0.07);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  margin: -4px 22px 0;
  align-self: flex-start;
}

/* Style / Book attribute rows */
.v2-pc-attrs {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0 22px 12px;
}
.v2-pc-attr-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}
.v2-pc-attr-label {
  width: 36px;
  color: var(--text-faint);
  font-weight: 500;
  flex-shrink: 0;
}
.v2-pc-attr-val {
  color: var(--text-dim);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Persona grid: 2x2 on medium, 1x4 on wide screens */
#pagePlay .play-select-grid {
  display: grid !important;
  grid-template-columns: repeat(2, minmax(260px, 1fr)) !important;
  gap: 20px !important;
  width: 100% !important;
}
@media (min-width: 1100px) {
  #pagePlay .play-select-grid {
    grid-template-columns: repeat(4, minmax(200px, 1fr)) !important;
  }
}
@media (max-width: 600px) {
  #pagePlay .play-select-grid { grid-template-columns: 1fr !important; }
}

/* -- Active game: v2 player strips -- */
.v2-play-strip {
  background: var(--bg-1) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: 10px !important;
  padding: 10px 14px !important;
  gap: 10px !important;
  width: min(100%, 640px);
}
.v2-play-strip-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.v2-play-strip .play-strip-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}
.v2-play-strip .play-strip-clock {
  font-family: var(--font-mono, "JetBrains Mono", monospace) !important;
  font-size: 17px !important;
  font-weight: 600 !important;
  background: var(--bg-2) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: 6px !important;
  padding: 4px 10px !important;
  min-width: 66px;
  text-align: center;
}
/* User avatar: accent ring */
.v2-play-strip .play-strip-avatar-user {
  background: rgba(var(--accent-rgb), 0.16) !important;
  border: 1px solid rgba(var(--accent-rgb), 0.30) !important;
  color: var(--accent) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: 18px !important;
}
/* Active clock: accent pulse */
.v2-play-strip .play-strip-clock.is-active {
  border-color: var(--accent) !important;
  color: var(--accent) !important;
}

/* -- Active game: v2 panel -- */
.v2-play-panel {
  background: var(--bg-1) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: 16px !important;
}

/* Bot identity card */
.v2-play-current-bot {
  background: var(--bg-0) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: 10px !important;
  padding: 12px 14px !important;
}

/* Mentor / coach card */
.v2-play-mentor-card {
  background: var(--bg-0);
  border: 1px solid rgba(var(--accent-rgb), 0.25);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
  overflow: hidden;
}
.v2-play-mentor-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg,
    rgba(var(--accent-rgb), 0.05) 0%, transparent 60%);
  pointer-events: none;
}
.v2-play-mentor-head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--accent);
  position: relative;
  z-index: 1;
}
.v2-play-mentor-head i { font-size: 15px; }
.v2-play-mentor-card .play-status {
  position: relative;
  z-index: 1;
  font-family: var(--font-editorial);
  font-style: italic;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
  background: none !important;
  border: none !important;
  padding: 0 !important;
}

/* Move history card v2 */
.v2-play-history-card {
  border: 1px solid var(--border-default) !important;
  border-radius: 10px !important;
  overflow: hidden !important;
}
.v2-play-history-card .play-history-head {
  background: rgba(var(--accent-rgb), 0.06) !important;
  border-bottom: 1px solid var(--border-default) !important;
  padding: 8px 14px !important;
  font-family: var(--font-body) !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.1em !important;
  color: var(--text-faint) !important;
}

/* Action buttons v2 */
.v2-play-secondary {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.v2-play-secondary .play-btn {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
}
.v2-play-secondary .play-btn i { font-size: 15px; }

/* Control bar icons (Phosphor replaces inline SVGs) */
.play-controls .ctrl-circle i,
.play-controls .ctrl-ico i {
  display: block;
  font-size: 18px;
  line-height: 1;
}
/* Ensure icon buttons still size correctly */
.play-controls .ctrl-circle { display: flex; align-items: center; justify-content: center; }
.play-controls .ctrl-ico { display: flex; align-items: center; justify-content: center; }

@media (max-width: 720px) {
  .v2-play-ctrl-bar { flex-direction: column; align-items: stretch; gap: 14px; }
  .v2-play-picker { gap: 20px; }
  .v2-play-h1 { font-size: 24px; }
}

/* ================================================================
   v2 SIGN-IN PAGE  (Ship 10, v0.194.13)
   Full-viewport split-screen: LEFT login panel + RIGHT decorative board.
   #pageSignin lives OUTSIDE .app-shell so it is never offset by the navrail.
   ================================================================ */

/* Hide navrail + app-shell content while the signin page is active. */
body[data-page="signin"] .navrail    { display: none; }
body[data-page="signin"] .app-shell  { visibility: hidden; pointer-events: none; }

/* Override the base .page rule so the signin page uses flex, not block. */
#pageSignin { display: none; }
#pageSignin.active {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 200;
  background: #0B0B0D;
  color: #FAFAF7;
  font-family: var(--font-body, 'Inter', sans-serif);
  overflow: hidden;
}

/* ---- LEFT panel ---- */
.v2-auth-left {
  flex: 0 0 50%;
  display: flex;
  flex-direction: column;
  padding: 48px 64px;
  position: relative;
  z-index: 2;
  overflow-y: auto;
}

.v2-auth-wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0;
  font-family: var(--font-display, 'Space Grotesk', sans-serif);
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
  margin-bottom: auto;
  padding-bottom: 64px;
}
.v2-auth-wm-gambit { color: #7C5CFF; }
.v2-auth-wm-coach  { color: #FAFAF7; }

.v2-auth-content {
  display: flex;
  flex-direction: column;
  gap: 32px;
  max-width: 400px;
}

.v2-auth-headers {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.v2-auth-eyebrow {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #B0ADA5;
}

.v2-auth-h1 {
  font-family: var(--font-display, 'Space Grotesk', sans-serif);
  font-size: 2.5rem;
  line-height: 1.1;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: #FAFAF7;
  margin: 0;
}

.v2-auth-sub {
  font-size: 1rem;
  line-height: 1.6;
  color: #B0ADA5;
  margin: 0;
}

.v2-auth-btns {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.v2-auth-btn {
  width: 100%;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: #1F1F22;
  border: 1px solid #2A2A2E;
  border-radius: 8px;
  color: #FAFAF7;
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 140ms, border-color 140ms;
}
.v2-auth-btn:hover  { background: #2A2A2E; border-color: #3F3F46; }
.v2-auth-btn:focus-visible { outline: 2px solid #7C5CFF; outline-offset: 2px; }
.v2-auth-btn:active { background: #3A3A40; }

.v2-auth-idp-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.v2-auth-terms {
  font-size: 0.8125rem;
  color: #8A867D;
  line-height: 1.6;
  margin: 0;
}

.v2-auth-link {
  color: #B0ADA5;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: #4D4A44;
  transition: color 120ms;
}
.v2-auth-link:hover { color: #D6D4CD; }

/* ---- RIGHT panel ---- */
.v2-auth-right {
  flex: 0 0 50%;
  background: #0F0F12;
  border-left: 1px solid rgba(42, 42, 46, 0.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 40px;
  position: relative;
  overflow: hidden;
  padding: 48px;
}

.v2-auth-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 45%, rgba(124, 92, 255, 0.14) 0%, transparent 68%);
  pointer-events: none;
  z-index: 0;
}

/* Board wrapper: board + labels */
.v2-auth-board-wrap {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.v2-auth-ranks {
  position: absolute;
  left: -24px;
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  padding: 3% 0;
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  color: rgba(124, 92, 255, 0.55);
  user-select: none;
}

.v2-auth-board {
  width: min(340px, 42vmin);
  height: min(340px, 42vmin);
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  border: 1px solid rgba(250, 250, 247, 0.08);
  border-radius: 2px;
  overflow: hidden;
  position: relative;
  box-shadow: 0 32px 64px rgba(0, 0, 0, 0.6);
}

.v2-auth-sq { width: 100%; height: 100%; }
.v2-auth-sq--l { background: #2A2A2E; }
.v2-auth-sq--d { background: #1F1F22; }

.v2-auth-files {
  display: flex;
  justify-content: space-around;
  padding: 0 3%;
  width: 100%;
  margin-top: 8px;
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  color: rgba(124, 92, 255, 0.55);
  user-select: none;
}

/* Piece + highlight overlays: positioned via CSS custom properties --sq-col (0-7) and --sq-row (0-7) */
.v2-auth-highlight,
.v2-auth-piece {
  position: absolute;
  width: 12.5%;
  height: 12.5%;
  left:  calc(var(--sq-col) * 12.5%);
  top:   calc(var(--sq-row) * 12.5%);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.v2-auth-highlight {
  z-index: 1;
}

/* Amber pulsing dot for the queen-sac square */
.v2-auth-highlight::after {
  content: '';
  width: 45%;
  height: 45%;
  border-radius: 50%;
  background: rgba(245, 158, 11, 0.45);
  mix-blend-mode: screen;
  animation: v2AuthPulse 2.2s ease-in-out infinite;
}

@keyframes v2AuthPulse {
  0%, 100% { opacity: 0.6; transform: scale(1);    }
  50%       { opacity: 1;   transform: scale(1.18); }
}

@media (prefers-reduced-motion: reduce) {
  .v2-auth-highlight::after { animation: none; }
}

.v2-auth-piece { z-index: 3; }
.v2-auth-piece svg { width: 72%; height: 72%; }

/* Dashed iris arrow SVG: stretches over the whole board */
.v2-auth-arrow {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 4;
}

/* ---- Pull-quote ---- */
.v2-auth-quote {
  position: relative;
  z-index: 1;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 440px;
}

.v2-auth-quote-text {
  font-family: var(--font-editorial, 'Newsreader', serif);
  font-style: italic;
  font-size: 1.5rem;
  line-height: 1.3;
  color: #7C5CFF;
  margin: 0;
}

.v2-auth-quote-attr {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: #8A867D;
  margin: 0;
}

/* ---- Mobile: stack left-over-right, hide right panel ---- */
@media (max-width: 900px) {
  #pageSignin.active { flex-direction: column; overflow-y: auto; }
  .v2-auth-left  { flex: none; padding: 32px 24px; }
  .v2-auth-right { display: none; }
  .v2-auth-wordmark { padding-bottom: 40px; }
  .v2-auth-h1 { font-size: 2rem; }
}
/* ================================================================= */
/* PRICING PAGE (Ship 11 v2)                                         */
/* ================================================================= */

.v2-pricing-wrap {
  padding: 32px 40px 80px;
  max-width: 1160px;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
}

/* --- Header --- */
.v2-pricing-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 48px;
}
.v2-pricing-eyebrow {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--accent);
  margin-bottom: 8px;
}
.v2-pricing-h1 {
  margin: 0 0 10px;
  font: 700 40px/1.1 var(--font-display);
  letter-spacing: -0.02em;
  color: var(--text);
}
.v2-pricing-sub {
  margin: 0;
  font-size: 16px;
  color: #A1A1AA;
  max-width: 520px;
}

/* --- Billing toggle --- */
.v2-pricing-toggle-wrap {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: 4px;
  flex-shrink: 0;
}
.v2-pricing-toggle-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: #71717A;
  font: 500 13px/1 var(--font-body);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.v2-pricing-toggle-btn--active {
  background: var(--bg-3);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0,0,0,0.35);
}
.v2-pricing-save-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  background: rgba(124,92,255,0.13);
  padding: 2px 6px;
  border-radius: 4px;
}

/* --- Cards grid --- */
.v2-pricing-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 80px;
}

/* --- Individual card --- */
.v2-pricing-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: 16px;
  padding: 24px;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.v2-pricing-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-elevated);
}
.v2-pricing-card--pro {
  border: 2px solid var(--accent);
  box-shadow: 0 0 24px rgba(124,92,255,0.15);
  z-index: 1;
}
.v2-pricing-card--club {
  border: 1px solid rgba(245,158,11,0.3);
}
.v2-pricing-card--club:hover {
  border-color: var(--amber-500);
}

/* Popular badge */
.v2-pricing-popular-badge {
  position: absolute;
  top: -13px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}

/* Card header block */
.v2-pricing-card-top {
  padding-bottom: 20px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--border-default);
}
.v2-pricing-tier-name {
  margin: 0 0 8px;
  font: 600 20px/1.2 var(--font-display);
  color: var(--text);
}
.v2-pricing-tier-name--iris  { color: var(--accent); }
.v2-pricing-tier-name--amber { color: var(--amber-500); }

.v2-pricing-price-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin-bottom: 6px;
}
.v2-pricing-price-col {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 6px;
}
.v2-pricing-price-col .v2-pricing-price-row { margin-bottom: 0; }
.v2-pricing-amount {
  font: 700 36px/1 var(--font-display);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.v2-pricing-period {
  font-size: 13px;
  color: #A1A1AA;
}
.v2-pricing-strike {
  font-size: 12px;
  color: #71717A;
  text-decoration: line-through;
  font-variant-numeric: tabular-nums;
}
.v2-pricing-tagline {
  margin: 0;
  font-size: 13px;
  color: #A1A1AA;
}

/* Feature list */
.v2-pricing-features {
  list-style: none;
  margin: 0 0 auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 28px;
}
.v2-pricing-features li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 13px;
  color: var(--text);
}
.v2-pricing-features li .ph {
  font-size: 16px;
  flex-shrink: 0;
  margin-top: 1px;
  color: #A1A1AA;
}
.v2-pricing-card--pro .v2-pricing-features li .ph { color: var(--accent); }
.v2-pricing-card--club .v2-pricing-features li .ph { color: var(--amber-500); }

.v2-pricing-feature--highlight {
  font-weight: 600;
}
.v2-pricing-feature--amber .ph { color: var(--amber-500) !important; }

/* CTAs */
.v2-pricing-cta {
  width: 100%;
  padding: 12px 16px;
  border-radius: var(--radius-md);
  font: 500 14px/1.4 var(--font-body);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  text-align: center;
}
.v2-pricing-cta--ghost {
  background: transparent;
  border: 1px solid var(--border-default);
  color: var(--text);
}
.v2-pricing-cta--ghost:hover { background: var(--bg-3); }
.v2-pricing-cta--primary {
  background: var(--accent);
  border: 1px solid var(--accent);
  color: #fff;
  box-shadow: 0 2px 8px rgba(124,92,255,0.3);
}
.v2-pricing-cta--primary:hover { background: var(--accent-d); border-color: var(--accent-d); }
.v2-pricing-cta--amber {
  background: transparent;
  border: 1px solid var(--amber-500);
  color: var(--amber-500);
}
.v2-pricing-cta--amber:hover { background: rgba(245,158,11,0.1); }

.v2-pricing-cta-group { margin-top: auto; }
.v2-pricing-no-cc {
  text-align: center;
  font-size: 11px;
  color: #71717A;
  margin: 10px 0 0;
}

/* --- Auto-renewal disclosure (legal transparency) --- */
.v2-pricing-fineprint {
  max-width: 760px;
  margin: -56px auto 80px;
  text-align: center;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-dim);
}

/* --- Compare table --- */
.v2-pricing-compare { margin-bottom: 80px; }
.v2-pricing-section-h {
  font: 700 24px/1.2 var(--font-display);
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 0 0 28px;
}
.v2-pricing-section-h--center { text-align: center; }
.v2-pricing-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--bg-2);
}
.v2-pricing-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}
.v2-pricing-table thead tr {
  border-bottom: 1px solid var(--border-default);
  background: rgba(42,42,46,0.5);
}
.v2-pricing-table th {
  padding: 14px 16px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}
.v2-pt-col-feat { width: 34%; }
.v2-pt-col-tier { width: 22%; text-align: center; }
.v2-pt-col-iris  { color: var(--accent); }
.v2-pt-col-amber { color: var(--amber-500); }
.v2-pricing-table tbody tr {
  border-bottom: 1px solid var(--border-default);
  transition: background 0.12s;
}
.v2-pricing-table tbody tr:last-child { border-bottom: none; }
.v2-pricing-table tbody tr:hover { background: rgba(42,42,46,0.3); }
.v2-pt-row-alt { background: rgba(0,0,0,0.12); }
.v2-pt-label {
  padding: 14px 16px;
  font-size: 13px;
  color: #A1A1AA;
}
.v2-pt-val {
  padding: 14px 16px;
  font-size: 13px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.v2-pt-val--minus { color: #71717A; }
.v2-pt-val--no    { color: #71717A; }
.v2-pt-val--yes   { color: #6EE7B7; }
.v2-pt-val--iris  { color: var(--accent); }
.v2-pt-val--amber { color: var(--amber-500); }
.v2-pt-val .ph { font-size: 18px; }

/* --- Highlighted Gold (iris) + Platinum (amber) columns in the compare
   table: full-height outline boxes with a faint tint, mirroring the
   highlighted pricing cards above. Columns are 3 (Gold) and 4 (Platinum). */
.v2-pricing-table th:nth-child(3),
.v2-pricing-table td:nth-child(3) {
  border-left: 1.5px solid color-mix(in srgb, var(--accent) 60%, transparent);
  border-right: 1.5px solid color-mix(in srgb, var(--accent) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.v2-pricing-table th:nth-child(4),
.v2-pricing-table td:nth-child(4) {
  border-left: 1.5px solid color-mix(in srgb, var(--amber-500) 60%, transparent);
  border-right: 1.5px solid color-mix(in srgb, var(--amber-500) 60%, transparent);
  background: color-mix(in srgb, var(--amber-500) 7%, transparent);
}
.v2-pricing-table thead th:nth-child(3) {
  border-top: 1.5px solid color-mix(in srgb, var(--accent) 60%, transparent);
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
}
.v2-pricing-table thead th:nth-child(4) {
  border-top: 1.5px solid color-mix(in srgb, var(--amber-500) 60%, transparent);
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
}
.v2-pricing-table tbody tr:last-child td:nth-child(3) {
  border-bottom: 1.5px solid color-mix(in srgb, var(--accent) 60%, transparent);
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
}
.v2-pricing-table tbody tr:last-child td:nth-child(4) {
  border-bottom: 1.5px solid color-mix(in srgb, var(--amber-500) 60%, transparent);
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
}
/* Keep the highlighted-column tint readable on hover + alt rows. */
.v2-pricing-table tbody tr:hover td:nth-child(3),
.v2-pricing-table .v2-pt-row-alt td:nth-child(3) {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.v2-pricing-table tbody tr:hover td:nth-child(4),
.v2-pricing-table .v2-pt-row-alt td:nth-child(4) {
  background: color-mix(in srgb, var(--amber-500) 12%, transparent);
}

/* --- FAQ --- */
.v2-pricing-faq { margin-bottom: 80px; }
.v2-pricing-faq-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  max-width: 840px;
  margin-inline: auto;
}
.v2-pricing-faq-item {
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color 0.15s;
}
.v2-pricing-faq-item:hover { border-color: #71717A; }
.v2-pricing-faq-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px;
  background: transparent;
  border: none;
  color: var(--text);
  font: 500 13px/1.4 var(--font-body);
  cursor: pointer;
  text-align: left;
}
.v2-pricing-faq-caret {
  font-size: 18px;
  color: #71717A;
  flex-shrink: 0;
  transition: transform 0.2s, color 0.15s;
}
.v2-pricing-faq-trigger:hover .v2-pricing-faq-caret { color: var(--text); }
.v2-pricing-faq-item[data-open="true"] .v2-pricing-faq-caret { transform: rotate(180deg); }
.v2-pricing-faq-body {
  padding: 0 20px 18px;
  font-size: 13px;
  color: #A1A1AA;
  line-height: 1.6;
}
.v2-pricing-faq-body p { margin: 0; }

/* --- Footer editorial card --- */
.v2-pricing-footer-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  background: var(--bg-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: 32px;
}
.v2-pricing-editorial {
  margin: 0;
  font-family: var(--font-editorial);
  font-size: 22px;
  font-style: italic;
  color: rgba(250,250,247,0.9);
  max-width: 480px;
  line-height: 1.45;
}
.v2-pricing-privacy-link {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--accent);
  font: 500 14px/1 var(--font-body);
  text-decoration: none;
  transition: color 0.15s;
  flex-shrink: 0;
}
.v2-pricing-privacy-link:hover { color: var(--accent-d); }
.v2-pricing-privacy-link .ph {
  font-size: 16px;
  transition: transform 0.15s;
}
.v2-pricing-privacy-link:hover .ph { transform: translateX(3px); }

/* --- Responsive --- */
@media (max-width: 900px) {
  .v2-pricing-cards { grid-template-columns: 1fr; }
  .v2-pricing-faq-grid { grid-template-columns: 1fr; }
  .v2-pricing-wrap { padding: 24px 20px 60px; }
  .v2-pricing-h1 { font-size: 28px; }
  .v2-pricing-header { flex-direction: column; align-items: flex-start; }
}

/* ============================================================ */
/*  v0.195.54 - Mobile responsive Phase 1                       */
/*  Bottom tab bar instead of left nav rail under 720px so the  */
/*  full viewport width is available for content. Also makes    */
/*  the legal footer + version pill sit ABOVE the tab bar so    */
/*  they no longer overlap page content.                        */
/* ============================================================ */
@media (max-width: 720px) {
  /* Hide the navrail-only widgets that don't make sense in a   */
  /* horizontal bottom tab bar. Auth lives on Settings page.    */
  .navrail .navrail-auth-widget,
  .navrail.v2-rail .navrail-auth-widget,
  .navrail .navrail-user-pill,
  .navrail.v2-rail .navrail-user-pill,
  .navrail .navrail-spacer,
  .navrail.v2-rail .navrail-spacer { display: none !important; }
  /* Hide the hover-tooltip overlay (no hover on touch). */
  .navrail-btn[aria-label]::after,
  .navrail-btn[aria-label]::before { display: none !important; }
  /* Navrail itself becomes a bottom tab bar. Override the      */
  /* desktop fixed-left layout from rules at lines 304 + 1118.  */
  .navrail.v2-rail,
  .navrail {
    position: fixed !important;
    inset: auto 0 0 0 !important;
    width: 100% !important;
    height: 56px !important;
    flex-direction: row !important;
    justify-content: space-around !important;
    align-items: center !important;
    padding: 0 !important;
    gap: 0 !important;
    border-top: 1px solid var(--bg-3) !important;
    background: var(--bg-2) !important;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.32) !important;
    z-index: 40;
    /* Honor iOS home-indicator safe area. */
    padding-bottom: env(safe-area-inset-bottom, 0) !important;
    height: calc(56px + env(safe-area-inset-bottom, 0)) !important;
  }
  /* Use `display: contents` on the <ul> lists so each <li> becomes a */
  /* direct flex child of .navrail. That puts all 8 nav buttons       */
  /* (Hub/Analyze/Play/Trainer/Puzzles/Stats/Account/Settings) on the */
  /* same row with equal flex share.                                  */
  .navrail .navrail-list,
  .navrail.v2-rail .navrail-list {
    display: contents !important;
  }
  .navrail .navrail-list li,
  .navrail.v2-rail .navrail-list li {
    flex: 1 1 0 !important;
    width: auto !important;
    min-width: 0 !important;
    display: flex !important;
    justify-content: center;
    align-items: stretch;
    padding: 0 !important;
    margin: 0 !important;
  }
  .navrail .navrail-btn,
  .v2-rail .navrail-btn,
  .navrail.v2-rail .navrail-btn {
    width: 100% !important;
    height: 56px !important;
    border-radius: 0 !important;
    padding: 0 !important;
    justify-content: center !important;
    flex-direction: column !important;
    gap: 2px !important;
    margin: 0 !important;
  }
  /* Label visible under each icon as a tiny caption (mobile-app feel). */
  .v2-rail .navrail-btn .navrail-label,
  .navrail .navrail-btn .navrail-label {
    display: inline !important;
    font-size: 10px !important;
    line-height: 1 !important;
    text-transform: none;
    letter-spacing: 0;
  }
  /* Active-tab indicator: top accent bar (Material-style). */
  .navrail .navrail-btn.active,
  .v2-rail .navrail-btn.active {
    background: transparent !important;
    color: var(--accent) !important;
    position: relative;
  }
  .navrail .navrail-btn.active::after,
  .v2-rail .navrail-btn.active::after {
    content: "";
    position: absolute;
    top: 0; left: 50%;
    transform: translateX(-50%);
    width: 32px; height: 2px;
    background: var(--accent);
    border-radius: 0 0 2px 2px;
  }
  /* Stop the v2-rail hover-expand from kicking in on touch. */
  .v2-rail:hover .navrail-btn,
  .v2-rail.open .navrail-btn {
    width: 100% !important;
    justify-content: center !important;
    padding: 0 !important;
  }
  /* Reclaim the left-margin originally reserved for the rail.  */
  .app-shell {
    margin-left: 0 !important;
    /* Leave room for the bottom tab bar + safe area. */
    padding-bottom: calc(56px + env(safe-area-inset-bottom, 0) + 8px);
  }
  /* Footer + version: lift above the tab bar so they don't     */
  /* clip behind it. Keep them out of the way of page content.  */
  .app-legal-footer {
    left: 0 !important; right: 0 !important;
    bottom: calc(56px + env(safe-area-inset-bottom, 0) + 4px) !important;
    justify-content: center;
    flex-wrap: wrap;
    padding: 0 12px;
    font-size: 9.5px !important;
    pointer-events: none;
  }
  .app-legal-footer a { pointer-events: auto; }
  .app-version {
    right: 8px !important;
    bottom: calc(56px + env(safe-area-inset-bottom, 0) + 26px) !important;
    font-size: 9px !important;
  }
  /* Stats canvas: kill the desktop margin-left:72px (which assumed a    */
  /* left navrail). With the nav now at the bottom, the canvas must     */
  /* start at x=0 so cards aren't squeezed into a 318px right slice.    */
  .v2-stats-canvas {
    margin-left: 0 !important;
    padding: var(--space-4) !important;
    max-width: 100% !important;
    box-sizing: border-box !important;
  }
  /* Openings table is wider than viewport: let the card itself scroll  */
  /* horizontally so the page doesn't grow past 390px. */
  .v2-stats-card { max-width: 100%; box-sizing: border-box; }
  .v2-stats-card:has(> table.v2-stats-table),
  .v2-stats-card .v2-stats-tbl-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Settings color-palette / board-season grid has min-width:340px and  */
  /* its tiles want ~110px each; with 4-6 tiles it overflows the         */
  /* viewport (measured 545px doc width). Drop the min, let the grid    */
  /* auto-fit to whatever fits and wrap onto extra rows.                 */
  .settings-board-seasons {
    min-width: 0 !important;
    max-width: 100% !important;
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)) !important;
  }
  .settings-card { min-width: 0; max-width: 100%; box-sizing: border-box; }
  /* Settings rows: stack label above control on narrow screens, so the */
  /* description doesn't shrink to one-word-per-line next to the pill.  */
  .v2-settings-row {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: var(--space-3) !important;
  }
  .v2-settings-row-ctrl { flex-wrap: wrap; gap: var(--space-2); }
  /* Signin page replaces the whole shell -- still hide the bar there. */
  body[data-page="signin"] .navrail { display: none !important; }
  body[data-page="signin"] .app-shell { padding-bottom: 0; }

  /* ---- Bottom-nav compensation: layout vars and leftover offsets ---- */
  /* Nav is now at the bottom, so no left-column width to account for.   */
  :root { --navrail-w: 0px; }
  /* Fix topbar: the override at Ship-1 hardcodes left:72px for the left
     rail. With the nav at the bottom that gap is unwanted. */
  .topbar.v2-topbar,
  .v2-topbar { left: 0 !important; }
  /* Hub wordmark: the translateX(-40px) nudge was designed to optically
     center the brand relative to the 72px left rail. Remove it on mobile
     so the wordmark stays centred in the full-width viewport. */
  .v2-hub-brand { transform: none; }
  /* Hub canvas: 32px horizontal padding is generous on 390px screens. */
  .v2-hub-canvas { padding: 20px !important; }
  /* FABs: lift above the 56px bottom tab bar so they are tappable. */
  .tour-help-fab {
    bottom: calc(56px + env(safe-area-inset-bottom, 0) + 8px) !important;
  }
  .feedback-fab {
    bottom: calc(56px + env(safe-area-inset-bottom, 0) + 52px) !important;
  }

  /* ---- Game Review: scrollable single-column layout on mobile ----
     The desktop layout locks .v2-gr-view to height:100vh with a
     300px + 1fr + 440px grid totalling >740px. On a 390px screen this
     causes horizontal overflow (clipped by overflow:hidden) and the
     bottom 56px of the panel sits behind the tab bar. Switch to a
     vertically-scrolling single-column stack: board first, sidebar
     (move list + eval) second, rightpane (report) third. */
  .v2-gr-view {
    height: auto !important;
    overflow: visible !important;
    overflow-x: hidden !important;
  }
  .v2-gr-view .layout {
    grid-template-columns: 1fr !important;
    grid-template-rows: auto auto auto !important;
    height: auto !important;
    overflow: visible !important;
    padding: 8px 16px 16px !important;
    gap: 16px !important;
  }
  .v2-gr-view .board-area  { order: 1 !important; }
  .v2-gr-view .sidebar     { order: 2 !important; }
  .v2-gr-view .rightpane   { order: 3 !important; }
  /* Board area: fill the 1fr column; subtract eval-bar (30px) + gap
     (6px) so the board-row doesn't overflow the column. Cap height to
     70svh so the board doesn't push the move list off-screen entirely. */
  .v2-gr-view .board-area {
    --board-w: min(calc(100cqw - 36px), calc(70svh - 80px)) !important;
    padding: 0 !important;
    overflow: visible !important;
    min-height: 0 !important;
  }
  .v2-gr-view #board {
    width: var(--board-w) !important;
    height: var(--board-w) !important;
    max-width: 100% !important;
  }
  .v2-gr-view .sidebar,
  .v2-gr-view .rightpane {
    overflow: visible !important;
    overflow-y: visible !important;
    max-height: none !important;
    min-height: 0 !important;
    height: auto !important;
  }
  /* Page-header padding matches the layout padding on mobile. */
  .v2-gr-page-header { padding: 4px 16px 8px !important; }
}

/* Lock badge overlay on gated cards */
.cs-card--locked,
.op-card--locked,
.eg-card--locked {
  opacity: 0.65;
  cursor: pointer;
  position: relative;
}
.cs-card--locked::after,
.op-card--locked::after,
.eg-card--locked::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: transparent;
}
.lock-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  color: var(--accent);
  font-size: 1rem;
  pointer-events: none;
  z-index: 1;
}

/* -- First-run onboarding (v0.195.196) -------------------------------- */
.onb-section {
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
  padding: var(--gap, 20px);
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.onb-hero {
  text-align: center;
  padding: 2rem 1rem 0;
}
.onb-title {
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  font-weight: 700;
  color: var(--tx-0, #f0f0f0);
  margin: 0 0 0.75rem;
}
.onb-sub {
  font-size: 1.05rem;
  color: var(--tx-1, #aaa);
  max-width: 560px;
  margin: 0 auto;
  line-height: 1.6;
}
.onb-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1rem;
}
.onb-feature {
  background: var(--bg-1, #1e1e1e);
  border: 1px solid var(--bd-0, #333);
  border-radius: 12px;
  padding: 1.25rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.onb-feature-icon {
  font-size: 1.5rem;
  color: var(--accent, #7c9a5e);
}
.onb-feature-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--tx-0, #f0f0f0);
  margin: 0;
}
.onb-feature-desc {
  font-size: 0.82rem;
  color: var(--tx-1, #aaa);
  line-height: 1.5;
  margin: 0;
}
.onb-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}
.onb-btn-primary,
.onb-btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.65rem 1.4rem;
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  border: none;
  transition: opacity 0.15s;
}
.onb-btn-primary:hover,
.onb-btn-secondary:hover { opacity: 0.85; }
.onb-btn-primary {
  background: var(--accent, #7c9a5e);
  color: #fff;
}
.onb-btn-secondary {
  background: var(--bg-2, #2a2a2a);
  color: var(--tx-0, #f0f0f0);
  border: 1px solid var(--bd-0, #333);
}
.onb-disclaimer {
  text-align: center;
  font-size: 0.78rem;
  color: var(--tx-2, #666);
  margin: 0;
}
@media (max-width: 480px) {
  .onb-features { grid-template-columns: 1fr 1fr; }
  .onb-btn-primary, .onb-btn-secondary { width: 100%; justify-content: center; }
}
