/* ==========================================================================
   style.css — single stylesheet for the poker app
   --------------------------------------------------------------------------
   §1  TOKENS ............ colours · font sizes · spacing · radii — the ONLY
                          place raw values are defined
   §2  BASE / RESET ...... element defaults + the text ROLE classes
   §3  UTILITIES ......... the STRUCTURE block (panel → section → row →
                          container) + layout/spacing helpers (flex, gap,
                          margin, pad)
   §4  COMPONENTS ........ shared blocks: card, box, button, table, story, bar
   §5  FEATURES .......... range grid, equity viz, charts, sentence
   §7  RESPONSIVE ........ breakpoint overrides
   --------------------------------------------------------------------------
  
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
:root {
  /* surfaces */
  --bg: #07090a;
  --s1: #0e1410;
  --s2: #121a14;
  --border: #1a2a1c;
  --menu-bg: #1e3024;

  /* brand */
  --gold: #c8a94a;
  --gold2: #8a7030;

  /* status */
  --green: #3fad64;
  --red: #c94040;
  --amber: #d4842a;

  /* text */
  --text: #d0d8d0;
  --dim: #7a9a7a;
  --muted: #5a7a5c;
  --white: #fff;

  /* tints & overlays */
  --bg-overlay: rgba(0, 0, 0, 0.5);
  --bg-scrim: rgba(0, 0, 0, 0.85);
  --bg-translucent: rgba(7, 9, 10, 0.95);
  --tint-light: rgba(255, 255, 255, 0.03);
  --tint-light-2: rgba(255, 255, 255, 0.06);

  /* GTO / range viz */
  --gto-red: #b8403a;
  --gto-blue: #4a90d9;
  --gto-grey: #6a7068;
  --gto-white: #d0d4cf;
  --range-folded-opacity: 0.25;
  --gto-empty-bg: #0e1310;
  --gto-empty-fg: #2a3e2c;
  --gto-dark-fg: #1a1f1a;
  --dot-pos: rgba(160, 200, 240, 0.7);
  --dot-seat: rgba(200, 160, 220, 0.7);
  --dot-tag: rgba(200, 200, 200, 0.7);

  /* type */
  --mono: 'IBM Plex Mono', monospace;
  --serif: 'Cormorant Garamond', serif;
  /* one scale, one job per step, real gaps: 12 / 14 / 16 / 20 / 26 / 32.
     no off-scale 15/17/18/28px values anywhere. */
  --fs-xs: 12px;
  /* labels, eyebrows, badges (uppercase) */
  --fs-md: 14px;
  /* body, table cells, insight text */
  --fs-lg: 16px;
  /* lead callout (verdict box), inline value */
  --fs-xl: 20px;
  /* stat number */
  --fs-2xl: 26px;
  /* section title */
  --fs-3xl: 32px;
  /* page title */
  /* hero display size — loader / splash only, NOT the content scale */
  --fs-hero: clamp(40px, 7vw, 68px);
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --lh-none: 1;
  --lh-tight: 1.15;
  --lh-snug: 1.4;
  --lh-normal: 1.5;
  --lh-body: 1.6;

  /* border width (1px hairline — not a spacing step) */
  --bw: 1px;

  /* spacing — one 8-step scale: 2 / 4 / 6 / 8 / 12 / 16 / 24 / 32 */
  --sp-2: 2px;
  --sp-4: 4px;
  --sp-6: 6px;
  --sp-8: 8px;
  --sp-12: 12px;
  --sp-16: 16px;
  --sp-24: 24px;
  --sp-32: 32px;
  --sp-48: 48px;

  /* radius */
  --r-sm: 4px;
  --r-lg: 8px;
  --r-pill: 50%;
}

/* ==========================================================================
   2. BASE / RESET
   ========================================================================== */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

*,
*::before,
*::after {
  min-width: 0;
}

html {
  scroll-behavior: smooth;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  font-size: var(--fs-md);
  line-height: var(--lh-normal);
  min-height: 100vh;
}

/* form elements don't inherit font; make them, so nothing redeclares it */
button,
input,
textarea,
select {
  font-family: inherit;
}

/* one field primitive for text inputs, textareas, selects */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
textarea,
select {
  background: var(--s2);
  border: var(--bw) solid var(--border);
  color: var(--text);
  font-size: var(--fs-md);

  padding: var(--sp-6) var(--sp-8);
  border-radius: var(--r-sm);
  outline: none;
}

input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):focus,
textarea:focus,
select:focus {
  border-color: var(--gold2);
}

input::placeholder,
textarea::placeholder {
  color: var(--dim);
}

textarea {
  width: 100%;
  resize: vertical;
}

select {
  cursor: pointer;
}

a {
  color: inherit;
}

/* ==========================================================================
   3. UTILITIES
   ========================================================================== */

/* --- display / flow --- */
.hidden {
  display: none;
}

.block {
  display: block;
}

.overflow-x {
  overflow-x: auto;
}

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- STRUCTURE ---
   One hierarchy owns every panel, end to end:
     .panel        = one view (the #p-* elements in index.html). Hidden by
                     default; .on shows it as a vertical stack whose gap spaces
                     the header and each section.
     .panel-header = title + description block at the top. Title and description
                     sit tight; the panel's gap gives the space below.
     .section      = one .section-head (only when titled) + its .row(s), grouped
                     tight; the panel's gap separates section from section.
     .row          = puts its .container(s) side by side and splits the width
                     between them; wraps when there are many.
     .container    = padded content slot inside a row. Content and data-slots
                     live here, never on the row itself.
   Spacing is baked in here, never added in markup. */
.panel {
  display: none;
  max-width: 1600px;
  margin: 0 auto;
  padding: var(--sp-32);
}

.panel.on {
  display: flex;
  flex-direction: column;
  gap: var(--sp-48);
  min-height: 60vh;
}

.panel-header {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.section {
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-16);
}

.container {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
  padding: var(--sp-16);
}

/* Slot hosts are plumbing, not structure. A bare (class-less) [data-slot] div
   sitting directly under a panel is made transparent so its children join the
   panel's stack and pick up the panel gap. Slot hosts that carry a real class
   (a .section toggled via [hidden], the .subtabs bar) keep their own display.
   The [hidden] rule comes last so hiding always wins — over display:contents
   above, and over .section's flex (the UA [hidden] rule alone loses to any
   author display). */
.panel>[data-slot]:not([class]),
.modal>[data-slot]:not([class]) {
  display: contents;
}

.panel>[data-slot][hidden] {
  display: none;
}

/* --- content stacks & grids ---
   .list = a tight vertical stack of like-minded items (bars, cards, option
   rows). The one predefined class for "these things stack"; markup never
   carries ad-hoc column/gap utilities.
   The auto-grid group = card grids that fill the row and wrap. Each content
   class may set its own --col-min (and override the gap); this shared rule
   owns the grid itself. .ins-grid is the generic insight-card grid. */
.list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
}

/* --- Heading line, reused inside any component (modal, card, panel).
   .head = a heading line (title left, meta right). Content stacks use .list
   (or .inner-section for interior blocks) — there is no content-line class. */
.head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-16);
}

.ins-grid,
.dynamics-cards,
.saved-hands-list,
.cr-headline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--col-min, 280px), 1fr));
  gap: var(--sp-16);
}

/* row/col alignment modifiers */
.center {
  align-items: center;
}

/* cross-axis */
.start {
  align-items: flex-start;
}

/* cross-axis */
.middle {
  justify-content: center;
}

/* main-axis */
.between {
  justify-content: space-between;
}

.end {
  justify-content: flex-end;
}

.min-w-0 {
  min-width: 0;
}

.text-left {
  text-align: left;
}

/* --- text roles --- */
.title {
  font-family: var(--serif);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  margin-bottom: var(--sp-4);
}

.title-xl {
  font-size: var(--fs-3xl);
}

.title-lg {
  font-size: var(--fs-2xl);
}

.eyebrow {
  font-size: var(--fs-xs);
  letter-spacing: var(--sp-2);
  text-transform: uppercase;
  color: var(--dim);
}

/* Section sub-heading: introduces a table / stat group / chart block. A real
   heading (serif, larger than body), distinct from the tiny .eyebrow label. */
.section-head {
  font-family: var(--serif);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  color: var(--text);
}

/* Card title: heads a card / box / story / insight inside a section — one
   step BELOW .section-head. Margin baked in; colour defaults to --text. */
.card-title {
  font-family: var(--serif);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  margin-bottom: var(--sp-4);
}

.text-body {
  font-size: var(--fs-md);
  color: var(--dim);
  line-height: var(--lh-body);
}

.lead {
  font-size: var(--fs-lg);
  color: var(--text);
  line-height: var(--lh-normal);
}

.text-meta {
  font-size: var(--fs-md);
  color: var(--dim);
}

.text-meta {
  font-size: var(--fs-xs);
  color: var(--muted);
}

/* Stack before -> after: compact hero flow under a table cell. The modal's
   per-player stacks block is a plain .list of .row items now. */
.stack-flow {
  margin-top: var(--sp-2);
  white-space: nowrap;
}

.text-strong {
  color: var(--text);
}

.value {
  font-family: var(--serif);
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  line-height: var(--lh-none);
}

/* bigger display value (result tiles, hero figures) — size modifier on .value */
.value-lg {
  font-size: var(--fs-3xl);
}

/* --- text colour modifiers --- */
.c-gold {
  color: var(--gold);
}

.c-dim {
  color: var(--dim);
}

.c-muted {
  color: var(--muted);
}

.c-pos {
  color: var(--green);
}

.c-neg {
  color: var(--red);
}

.c-warn {
  color: var(--amber);
}

/* --- background fill modifiers (bar fills, dots, swatches, segments) --- */
.bg-gold {
  background: var(--gold);
}

.bg-pos {
  background: var(--green);
}

.bg-neg {
  background: var(--red);
}

.bg-warn {
  background: var(--amber);
}

.bg-muted {
  background: var(--muted);
}

.bg-dim {
  background: var(--dim);
}

/* --- weight / transform helpers --- */
.fw-medium {
  font-weight: var(--fw-medium);
}

.fw-semibold {
  font-weight: var(--fw-semibold);
}

.text-right {
  text-align: right;
}

.text-center {
  text-align: center;
}

/* ==========================================================================
   4. COMPONENTS   (built per CSS2-BUILD.md)
   ========================================================================== */

/* --- Card & box: padded, rounded containers ---
   .card  = outlined (border). Add .card-s1/.card-s2 for a surface fill.
   .box   = filled callout, no border (verdict, work-on, insight).
   .card-link = clickable, lifts on hover (works on either). */
.card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
  border: var(--bw) solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-12) var(--sp-16);
  text-align: left;
}

/* Inline markers never stretch when they're a direct flex child of a stacking
   container (card/box/section) — they keep their natural size, top-left. */
.tag {
  align-self: flex-start;
}

.card-s1 {
  background: var(--s1);
}

.card-s2 {
  background: var(--s2);
}

.box {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  background: var(--s2);
  border-radius: var(--r-lg);
  padding: var(--sp-16) var(--sp-16);
  text-align: left;
}

.card-link {
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .15s;
}

.card-link:hover {
  background: var(--s2);
  border-color: var(--gold2);
  transform: translateY(-1px);
}

/* highlighted card (e.g. a featured / hero card) */
.card-hero {
  border-color: color-mix(in srgb, var(--gold) 35%, transparent);
  background: color-mix(in srgb, var(--gold) 6%, transparent);
}

/* --- Table ---
   Plain rows with a header rule and per-row dividers; last row has none.
   Colour-coded cells use the .c-* utilities (c-gold/c-pos/c-neg) on the cell.
   .sortable header is clickable; .num right-aligns a column. */
.table {
  width: 100%;
  border-collapse: collapse;
}

.table th {
  font-size: var(--fs-xs);
  letter-spacing: var(--sp-2);
  text-transform: uppercase;
  font-weight: var(--fw-regular);
  color: var(--dim);
  text-align: left;
  padding: 0 var(--sp-16) var(--sp-12) 0;
  border-bottom: var(--bw) solid var(--border);
}

.table td {
  font-size: var(--fs-md);
  padding: var(--sp-16) var(--sp-16);
  padding-left: 0;
  border-bottom: var(--bw) solid var(--border);
  vertical-align: middle;
}

.table th:last-child,
.table td:last-child {
  padding-right: 0;
}

.table tr:last-child td {
  border-bottom: none;
}

.table .num {
  text-align: right;
}

/* clickable body rows (hand log) */
.table tr.link {
  cursor: pointer;
}

.table tbody tr.link:hover {
  background: var(--s1);
}

/* table extras: dimmed (excluded) row, small cell, inline spark bar */
.table tr.excluded {
  opacity: 0.35;
}

.cell-sm {
  font-size: var(--fs-xs);
}

.spark {
  display: inline-block;
  height: 10px;
  min-width: 2px;
  border-radius: var(--r-sm);
  vertical-align: middle;
  opacity: 0.5;
}

.table th.sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: color .2s;
}

.table th.sortable:hover {
  color: var(--gold);
}

/* --- Bar: label + track + fill + value/meta ---
   .bar is a grid row. Default cols = label | track | value; add .bar-3
   for an extra meta column. Fill colour comes from a .bg-* utility on
   .bar-fill, width is set inline (data-driven). */
.bar {
  display: grid;
  grid-template-columns: var(--bar-label, 110px) 1fr auto;
  gap: var(--sp-8);
  align-items: center;
}

.bar-3 {
  grid-template-columns: var(--bar-label, 110px) 1fr auto auto;
}

.bar-track {
  height: 6px;
  background: var(--s2);
  border-radius: var(--r-sm);
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  border-radius: var(--r-sm);
  transition: width .9s cubic-bezier(.4, 0, .2, 1);
}

/* Segmented / stacked bar: a flex track of .bar-seg pieces (widths inline). */
.bar-stack {
  display: flex;
  height: 18px;
  border-radius: var(--r-sm);
  overflow: hidden;
}

.bar-seg {
  height: 100%;
  transition: width .8s ease;
}

/* --- Insight card: built on .box ---
   Severity colour comes from utilities on the markup: the badge dot is
   .dot.bg-* and the badge word is .c-* (no per-severity classes here). */
.insight {
  position: relative;
}

/* type (12px uppercase tracking) comes from .eyebrow in markup; this owns the row layout */
.insight-badge {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  margin-bottom: var(--sp-8);
  text-transform: uppercase;
}

/* body text owns size + line-height via .text-body in markup */

/* Both sit below the insight body, separated by a top-border divider. The
   margin-top is the divider gap (insight body has no structure gap). */
.insight-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4) var(--sp-12);
  margin-top: var(--sp-12);
  padding-top: var(--sp-8);
  border-top: var(--bw) solid var(--border);
}

/* eyebrow + note stack tight; also hosts the dynamics coaching blocks */
.insight-coaching {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  margin-top: var(--sp-12);
  padding-top: var(--sp-8);
  border-top: var(--bw) solid var(--border);
}

/* --- Story card: an expandable insight (head + collapsible body) ---
   Compose on .box. One state class: add .open to expand (body shows,
   teaser hides, chevron flips); default (no .open) is collapsed. */
.story {
  padding: 0;
  cursor: pointer;
  transition: background .15s;
}

.story-head {
  position: relative;
  padding: var(--sp-16) var(--sp-16);
  border-radius: var(--r-lg);
  transition: background .15s;
}

.story:hover .story-head {
  background: var(--s1);
}

.story-chevron {
  position: absolute;
  top: var(--sp-16);
  right: var(--sp-16);
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--gold) 10%, transparent);
  border: var(--bw) solid var(--gold2);
  color: var(--gold);
  font-size: var(--fs-md);
  line-height: var(--lh-none);
  transition: transform .15s, background .15s, border-color .15s;
}

.story:hover .story-chevron {
  background: color-mix(in srgb, var(--gold) 20%, transparent);
  border-color: var(--gold);
}

.story.open .story-chevron {
  transform: rotate(180deg);
  border-color: var(--gold2);
}

/* Findings row: story cards sit directly in a .row (they are self-padded
   boxes, so no .container wrapper). A 40% basis puts two on a line (each
   grows to half); min-width wraps them to one per line on narrow screens.
   Top-aligned so a tall open card doesn't stretch its collapsed neighbour,
   and an open card takes the full line so its siblings reflow around it. */
[data-findings] {
  align-items: start;
}

.row>.story {
  flex: 1 1 40%;
  min-width: 280px;
}

.row>.story.open {
  flex-basis: 100%;
}

/* Body content shares the head's inset so title and body read as one aligned
   column. Left matches .story-head's --sp-16. Right matches the title's content
   edge: the head's --sp-16 plus the title's extra --sp-32 (which clears the
   chevron), so title and body stop at the same right inset. */
/* Nested section: a vertical stack inside a card or modal, with baked-in
   spacing between its children. Used for the story card's expanded body and
   for blocks inside modals (which use .inner-section, never .section). */
.inner-section {
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}

/* The story card's body is an inner-section, collapsed until the card opens. */
.story .inner-section {
  display: none;
  padding: 0 calc(var(--sp-16) + var(--sp-32)) var(--sp-16) var(--sp-16);
}

.story.open .inner-section {
  display: flex;
}

/* layout hook only — type/colour come from .text-body in markup; hidden when open */
.story-teaser {
  padding-right: var(--sp-24);
}

.story.open .story-teaser {
  display: none;
}

.story-branches {
  padding-left: var(--sp-16);
}

.story-branches li {
  margin-bottom: var(--sp-8);
}

.story-branches li:last-child {
  margin-bottom: 0;
}

.story-impact,
.story-sowhat {
  padding-top: var(--sp-12);
  border-top: var(--bw) solid var(--border);
}

/* --- Markers: dot, tag --- */
.dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: var(--r-pill);
}

.dot-lg {
  width: 11px;
  height: 11px;
}

.tag {
  font-size: var(--fs-xs);

  font-weight: var(--fw-semibold);
  padding: var(--sp-2) var(--sp-6);
  border-radius: var(--r-sm);
  border: var(--bw) solid var(--border);
  background: var(--tint-light);
  color: var(--dim);
  white-space: nowrap;
}

.tag-gold {
  color: var(--gold);
  border-color: color-mix(in srgb, var(--gold) 35%, transparent);
  background: color-mix(in srgb, var(--gold) 6%, transparent);
}

/* --- Buttons ---
   Serif face matches the live app. Padding/size come from tokens, not
   off-scale px. .btn-icon is a round single-glyph button. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-6);
  cursor: pointer;
  border: var(--bw) solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  transition: background .2s, color .2s, border-color .2s;
}

.btn[disabled] {
  opacity: .3;
  cursor: default;
}

.btn-primary {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--bg);
  font-family: var(--serif);
  font-size: var(--fs-lg);

  letter-spacing: .05em;

  padding: var(--sp-8);
}

.btn-primary:hover {
  background: var(--gold2);
  border-color: var(--gold2);
}

.btn-secondary {
  background: color-mix(in srgb, var(--gold) 8%, transparent);
  border-color: var(--gold2);
  color: var(--gold2);
  font-family: var(--serif);
  font-size: var(--fs-lg);

  letter-spacing: .05em;

  padding: var(--sp-8);
}

.btn-secondary:hover {
  background: var(--gold2);
  color: var(--bg);
}

.btn-ghost {
  background: var(--tint-light-2);
  border-color: var(--gold2);
  color: var(--text);
  padding: var(--sp-4) var(--sp-8);
  font-size: var(--fs-xs);
}

.btn-ghost:hover:not([disabled]) {
  border-color: var(--gold);
  color: var(--gold);
  background: color-mix(in srgb, var(--gold) 10%, transparent);
}

.btn-icon {
  width: 28px;
  height: 28px;
  border-radius: var(--r-pill);
  background: var(--tint-light);
  border-color: var(--border);
  color: var(--dim);
  font-family: var(--serif);
  font-weight: var(--fw-bold);
  padding: 0;
}

.btn-icon:hover {
  border-color: var(--gold);
  color: var(--gold);
  background: color-mix(in srgb, var(--gold) 8%, transparent);
}

/* star toggles (hand-log row, saved list, modal) go gold when active */
.btn-icon.starred {
  color: var(--gold);
  border-color: var(--gold2);
}

/* modal star sits in the header corner — position only, look from .btn-icon */
.modal-star-btn {
  position: absolute;
  top: var(--sp-8);
  right: 52px;
}

/* --- Form controls (field base lives in the reset) ---
   .select adds the caret chrome; .toggle is the $/BB segmented switch. */
.select {
  appearance: none;
  -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--dim) 50%),
    linear-gradient(135deg, var(--dim) 50%, transparent 50%);
  background-position: calc(100% - 16px) center, calc(100% - 11px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: var(--sp-24);
}

.bb-toggle {
  display: inline-flex;
  border: var(--bw) solid var(--border);
  border-radius: var(--r-sm);
  overflow: hidden;
  cursor: pointer;
  font-weight: var(--fw-semibold);
  font-size: var(--fs-md);

}

.bb-opt {
  padding: 5px 9px;
  color: var(--dim);
  background: var(--s2);
  transition: background .2s, color .2s;
  user-select: none;
}

.bb-opt.active {
  background: var(--gold2);
  color: var(--bg);
}

.check {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  cursor: pointer;
}

.check input[type="checkbox"] {
  accent-color: var(--gold);
  width: 14px;
  height: 14px;
}

/* The main tab nav (.tab-nav / .tab-menu / .tab-item) lives in the app-structure
   section below. Inline subtabs: */
.subtabs {
  display: flex;
  gap: var(--sp-4);
  border-bottom: var(--bw) solid var(--border);
  margin-bottom: var(--sp-16);
}

.subtab {
  padding: var(--sp-8) var(--sp-16);
  font-size: var(--fs-xs);

  letter-spacing: var(--bw);

  text-transform: uppercase;
  color: var(--dim);
  cursor: pointer;
  background: transparent;
  border: var(--bw) solid transparent;
  border-bottom: var(--sp-2) solid transparent;
  border-top-left-radius: var(--r-sm);
  border-top-right-radius: var(--r-sm);
  margin-bottom: calc(-1 * var(--bw));
  transition: color .15s, border-color .15s, background .15s;
}

.subtab:hover {
  color: var(--text);
  background: var(--s1);
}

.subtab.active {
  color: var(--gold);
  background: var(--s1);
  border-bottom-color: var(--gold);
}

/* --- Stat block: label + value. Reuse .value for the number ---
   .stat-grid = plain auto-fit grid (mini stat rows). */
.stat {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--sp-8);
}

/* Every stat-grid cell is a distinct tile at rest (bg + border), so adjacent
   stats read as separate entries without needing hover. */
.stat-grid>.stat {
  background: var(--s2);
  border: var(--bw) solid var(--border);
  border-radius: var(--r-sm);
  padding: var(--sp-12) var(--sp-16);
}

/* --- Legend: swatch + label --- */
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8) var(--sp-16);
}

.legend-item {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  font-size: var(--fs-xs);

  color: var(--text);
}

.swatch {
  display: inline-block;
  width: 11px;
  height: 11px;
  border-radius: var(--r-sm);
}

.swatch-line {
  width: 10px;
  height: 3px;
}

.swatch-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-pill);
}

/* --- Overlay / modal / popover / tooltip --- */
.overlay {
  position: fixed;
  inset: 0;
  background: var(--bg-scrim);
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s;
}

.overlay.show {
  opacity: 1;
  pointer-events: auto;
}

.modal {
  position: relative;
  background: var(--s2);
  border: var(--bw) solid var(--border);
  border-radius: var(--r-lg);
  width: 90vw;
  max-width: 600px;
  max-height: 80vh;
  overflow-y: auto;
  padding: var(--sp-24);
  /* Modals are built like panels: a .panel-header then .sections, stacked by
     the modal's own gap (same mechanism as .panel.on, scaled to the modal's
     sp-24 padding). Absolutely-positioned chrome (close/star) sits outside
     the flow. */
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}

.modal-close {
  position: absolute;
  top: var(--sp-12);
  right: var(--sp-16);
  background: none;
  border: none;
  color: var(--dim);
  font-size: var(--fs-lg);

  cursor: pointer;
}

.modal-close:hover {
  color: var(--text);
}

/* Equity-sim slot: plumbing inside the modal stack. Hidden while empty so it
   never claims a slice of the modal's gap before anything renders into it. */
.eq-slot:empty {
  display: none;
}

.modal-notes {
  display: none;
}

/* shown as a gapped column so the header + textarea space via the gap */
.modal-notes.show {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
}

.modal-notes-status {
  transition: color .3s;
}

/* The one hand row — every panel's example-hands modal. A grid owns the whole
   layout: position · hole · board · result on the top line, actions below.
   Each child has a single class; markup carries no layout utilities. */
.hand-row {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: baseline;
  column-gap: var(--sp-12);
  row-gap: var(--sp-4);
  padding: var(--sp-8);
  border-radius: var(--r-sm);
  border-bottom: var(--bw) solid var(--border);
  cursor: pointer;
}

.hand-row:last-child {
  border-bottom: none;
}

.hand-row:hover {
  background: var(--s2);
}

.hand-row-pos {
  min-width: 28px;
  font-size: var(--fs-xs);
  letter-spacing: var(--sp-2);
  text-transform: uppercase;
  color: var(--gold);
}

.hand-row-hole {
  font-family: var(--serif);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  line-height: var(--lh-none);
  color: var(--text);
}

.hand-row-board {
  font-size: var(--fs-md);
  color: var(--dim);
  letter-spacing: .5px;
}

.hand-row-result {
  justify-self: end;
  font-weight: var(--fw-semibold);
}

.hand-row-acts {
  grid-column: 2 / -1;
  font-size: var(--fs-md);
  color: var(--dim);
  line-height: var(--lh-snug);
}

.popover {
  position: absolute;
  background: var(--s1);
  border: var(--bw) solid var(--border);
  border-radius: var(--r-sm);
  box-shadow: 0 8px 32px var(--bg-overlay);
  padding: var(--sp-8) var(--sp-12);
  z-index: 200;
}

.tooltip {
  position: relative;
  display: inline-block;
  cursor: help;
}

.tooltip-box {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: var(--sp-6);
  min-width: 160px;
  max-width: 240px;
  padding: var(--sp-6) var(--sp-8);
  background: var(--s1);
  border: var(--bw) solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: var(--fs-md);

  line-height: var(--lh-normal);

  text-align: left;
  white-space: normal;
  pointer-events: none;
  z-index: 200;
  transition: opacity .15s;
}

.tooltip:hover .tooltip-box,
.tooltip.active .tooltip-box {
  visibility: visible;
  opacity: 1;
}

/* --- Spinner + loading row --- */
.spinner {
  width: 18px;
  height: 18px;
  border: var(--sp-2) solid var(--border);
  border-top-color: var(--gold);
  border-radius: var(--r-pill);
  animation: spin .8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-8);
  padding: var(--sp-32) 0;
  min-height: 160px;
}

/* --- Pagination (prev/next use .btn-ghost) --- */
/* --- Notice / banner (info / warn / danger) --- */
.notice {
  padding: var(--sp-8) var(--sp-16);
  border-radius: var(--r-sm);
  border: var(--bw) solid transparent;
  font-size: var(--fs-xs);

  letter-spacing: var(--bw);

}

/* ==========================================================================
   5. FEATURES   (built per CSS2-BUILD.md)
   ========================================================================== */

/* --- Range matrix cell ---
   The GTO matrix (data-gto) and the "your" matrix (data-hero) are SEPARATE
   grids, so a cell carries data-gto OR data-hero, never both. That makes it
   safe to merge same-colour rules across the two. Cell text colour stays
   white except where the fill is light (white/grey/blue/empty). */
.range-grid-sm {
  display: grid;
  grid-template-columns: repeat(13, 1fr);
  gap: var(--bw);
  max-width: 560px;
}

.rc {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-sm);
  cursor: default;
}

.rc span {
  font-size: var(--fs-xs);

  line-height: var(--lh-none);

  font-weight: var(--fw-semibold);
  text-align: center;
  color: var(--white);
  pointer-events: none;
}

.rc:hover {
  transform: scale(1.5);
  z-index: 20;
}

/* colour states */
.rc[data-gto="green"] {
  background: var(--green);
}

.rc[data-gto="red"] {
  background: var(--gto-red);
}

.rc[data-gto="blue"] {
  background: var(--gto-blue);
}

.rc[data-gto="grey"] {
  background: var(--gto-grey);
}

.rc[data-gto="white"] {
  background: var(--gto-white);
}

.rc[data-gto="white"] span {
  color: var(--gto-dark-fg);
}

.rc[data-gto="grey"] span,
.rc[data-gto="blue"] span {
  color: var(--white);
}

.rc[data-gto="none"],
.rc[data-hero="none"] {
  background: var(--gto-empty-bg);
  border: var(--bw) solid var(--border);
}

.rc[data-gto="none"] span,
.rc[data-hero="none"] span {
  color: var(--gto-empty-fg);
}

/* "Your range" cells coloured by the action YOU took, same palette as the
   GTO chart. The colour is the whole story — no right/wrong overlay. */
.rc[data-act="raise"] {
  background: var(--gto-red);
}

.rc[data-act="call"] {
  background: var(--green);
}

.rc[data-act="fold"] {
  background: var(--gto-grey);
}

.rc[data-act="fold"] span {
  color: var(--white);
}

/* Cells you were actually dealt in this spot open the hands behind them. */
.rc[data-act] {
  cursor: pointer;
}

/* --- Sentence builder: serif stem with clickable clause tokens --- */
.sentence {
  font-family: var(--serif);
  font-size: var(--fs-xl);

  line-height: var(--lh-body);

  color: var(--text);
}

.sentence-token {
  display: inline-block;
  padding: 0 var(--sp-2);
  color: var(--gold);
  border-bottom: var(--bw) dashed var(--gold2);
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.sentence-token:hover {
  color: var(--text);
  border-bottom-color: var(--gold);
}

.sentence-empty {
  color: var(--dim);
  font-style: italic;
}

.sentence-add {
  display: inline-block;
  margin-left: var(--sp-12);
  padding: var(--sp-4) var(--sp-8);
  background: transparent;
  border: var(--bw) dashed var(--border);
  border-radius: var(--r-sm);
  color: var(--dim);
  font-size: var(--fs-md);

  cursor: pointer;
  vertical-align: middle;
}

.sentence-add:hover {
  border-color: var(--gold2);
  color: var(--gold);
}

/* Centered divider between segment A and segment B in compare mode: the word
   "vs" sits in the middle with a rule running out to each side. */
.sentence-vs {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  margin: var(--sp-16) 0;
  text-transform: uppercase;
  letter-spacing: var(--sp-4);

  font-size: var(--fs-xs);

  color: var(--dim);
}

.sentence-vs::before,
.sentence-vs::after {
  content: "";
  flex: 1;
  height: var(--bw);
  background: var(--border);
}

/* --- Card-deal animation (loader) ---
   Cards start offset + transparent; adding .show deals each one in. */

/* Shared playing-card face (loader deal / hero splash). */
.card-face {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 66px;
  border-radius: var(--r-lg);
  background: var(--s2);
  border: var(--bw) solid var(--border);
  font-family: var(--serif);
  font-size: var(--fs-xl);

  font-weight: var(--fw-semibold);
  opacity: 0;
  transform: translateY(18px) scale(.92);
  transition: opacity .38s ease, transform .38s ease;
}

.card-face.show {
  opacity: 1;
  transform: none;
}

/* --- Screen show/hide states --- */
#loader {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  transition: opacity .8s;
}

#loader.out {
  opacity: 0;
  pointer-events: none;
}

#app {
  display: none;
}

#app.on {
  display: block;
}

#dash {
  display: none;
}

#dash.on {
  display: block;
}

/* .panel / .panel.on / .panel-header / .section live in the STRUCTURE block (§3). */
.panels-wrap.blurred {
  filter: blur(3px);
  pointer-events: none;
}

/* --- Dashboard header + hero stat strip --- */
.dash-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg-translucent);
  backdrop-filter: blur(8px);
  border-bottom: var(--bw) solid var(--border);
  padding: 0 var(--sp-32);
}

.header-inner {
  padding: var(--sp-12) 0;
}

.header-controls {
  display: flex;
  align-items: center;
  gap: var(--sp-16);
  flex-wrap: wrap;
}

.hero-strip {
  display: flex;
  gap: var(--bw);
  background: var(--border);
  border-bottom: var(--bw) solid var(--border);
  /* Break out of the .dash-header side padding so the strip spans edge to edge. */
  margin: 0 calc(-1 * var(--sp-32));
}

.hs {
  flex: 1;
  min-width: 0;
  background: var(--s1);
  padding: var(--sp-12) var(--sp-16);
}

.hs-l {
  margin-bottom: var(--sp-4);
  white-space: nowrap;
}

.hs-v {
  white-space: nowrap;
}

/* --- Tab nav (grouped dropdown menus) --- */
.tab-nav {
  display: flex;
  position: relative;
  z-index: 1001;
  border-bottom: var(--bw) solid var(--border);
  background: var(--menu-bg);
  /* Break out of the .dash-header side padding so the nav spans edge to edge. */
  margin: 0 calc(-1 * var(--sp-32));
}

.tab-menu {
  flex: 1;
  position: relative;
}

.tab-menu+.tab-menu {
  border-left: var(--bw) solid var(--border);
}

.tab-menu-btn {
  width: 100%;
  padding: var(--sp-12) var(--sp-16);
  font-size: var(--fs-xs);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--dim);
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  transition: color .2s, background .2s;
}

.tab-menu-btn:hover {
  color: var(--text);
  background: var(--tint-light);
}

.tab-menu-btn.active {
  color: var(--gold);
}

.tab-arrow {
  font-size: var(--fs-xs);
  opacity: .5;
  margin-left: var(--sp-4);
}

.tab-menu-btn.active .tab-arrow {
  opacity: 1;
}

.tab-menu-items {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 100%;
  background: var(--menu-bg);
  border: var(--bw) solid var(--tint-light-2);
  border-top: none;
  z-index: 1001;
  box-shadow: 0 8px 32px var(--bg-overlay);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

.tab-item {
  display: block;
  width: 100%;
  padding: var(--sp-8) var(--sp-16);
  font-size: var(--fs-xs);
  letter-spacing: var(--bw);
  text-transform: uppercase;
  color: var(--text);
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  transition: color .15s, background .15s;
}

.tab-item:hover {
  color: var(--white);
  background: var(--tint-light-2);
}

.tab-item.active {
  color: var(--gold);
}

/* --- Loader screen (cards deal in, progress sweeps) --- */
.l-title {
  font-size: var(--fs-hero);
  color: var(--gold);
  margin-bottom: var(--sp-4);
}

.l-sub {
  letter-spacing: 5px;
  margin-bottom: var(--sp-32);
}

.l-cards {
  display: flex;
  gap: var(--sp-12);
  margin-bottom: 44px;
}

.l-count {
  display: inline-block;
  min-width: 120px;
  font-size: var(--fs-hero);
  font-weight: var(--fw-regular);
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.l-prog {
  position: relative;
  width: 190px;
  height: 1px;
  margin: var(--sp-12) auto 0;
  background: var(--muted);
  overflow: hidden;
}

.l-prog-fill {
  width: 0;
  height: 100%;
  background: var(--gold);
  transition: width .06s linear;
}

.l-prog::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  transform: translateX(-100%);
  animation: l-prog-sweep 1.1s linear infinite;
}

@keyframes l-prog-sweep {
  to {
    transform: translateX(190px);
  }
}

/* --- Panel loading placeholder --- */
.panel-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-8);
  padding: var(--sp-32) 0;
  min-height: 160px;
}

.eq-spinner-ring {
  width: 18px;
  height: 18px;
  border: var(--sp-2) solid var(--border);
  border-top-color: var(--gold);
  border-radius: var(--r-pill);
  animation: eq-spin .8s linear infinite;
}

@keyframes eq-spin {
  to {
    transform: rotate(360deg);
  }
}

/* --- Paste / import pages --- */
/* structural wrap: centres the hero card + caps its width (no role/util covers
   a max-width column) */
#paste-wrap {
  max-width: 800px;
  margin: 0 auto;
  padding: var(--sp-32) var(--sp-24);
}

/* card+card-s1+section own border/radius/bg/stacking in markup; this keeps
   only the hero card's generous centred padding (card's own padding is tighter) */
.paste-box {
  padding: var(--sp-32) var(--sp-24);
  text-align: center;
}

/* decorative serif glyph (like card-glyph): its font-size is intentional */
.paste-suit {
  font-family: var(--serif);
  font-size: var(--fs-3xl);
  color: var(--gold2);
  opacity: .5;
}

/* justify-end + top padding; row supplies display/gap/wrap in markup */
.paste-nav {
  justify-content: flex-end;
  padding: var(--sp-12) var(--sp-24) 0;
}

/* hero-card buttons sit narrow and centred; section gap owns vertical spacing */
.paste-box .btn {
  width: 60%;
  align-self: center;
}

textarea#jin {
  min-height: 50px;
}

/* section stacks the divider block; this adds the rule + space above it */
.paste-manual {
  border-top: var(--bw) solid var(--border);
  padding-top: var(--sp-24);
}

/* --- Header style picker + page meta --- */
.page-meta-link {
  cursor: pointer;
  padding: var(--sp-4) var(--sp-8);
  border-radius: var(--r-sm);
  border: var(--bw) solid transparent;
  transition: border-color .2s, color .2s;
}

.page-meta-link:hover {
  border-color: var(--border);
  color: var(--gold);
}

.link-gold {
  color: var(--gold);
  text-decoration: underline;
}

.style-display {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-6);
  padding: var(--sp-4) var(--sp-8);
}

/* --- How it works box --- */
.step {
  display: grid;
  grid-template-columns: 32px 1fr;
  grid-template-rows: auto auto;
  column-gap: var(--sp-12);
  row-gap: var(--sp-4);
}

.step-num {
  grid-row: 1 / 3;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-pill);
  border: var(--bw) solid var(--gold2);
  color: var(--gold);
  font-family: var(--serif);
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
}

/* ==========================================================================
   6. PANEL-SPECIFIC  (genuinely-unique blocks: mygame, saved hands, style
      picker, custom popover, allin cards). Ported from the old styles.
      ========================================================================== */

/* shared verdict colours (from bandVerdict): used by dynamics tables/cards */
.v-ok {
  color: var(--green);
}

.v-low {
  color: var(--amber);
}

.v-high {
  color: var(--red);
}

.v-na {
  color: var(--muted);
}

/* hole-card display: serif gold heading for the saved-hand cards (merged) */
.saved-card-hole {
  font-family: var(--serif);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  font-size: var(--fs-lg);
  color: var(--gold);
}

.dynamics-vs.v-ok .dynamics-vs-verdict {
  color: var(--green);
}

.dynamics-vs.v-low .dynamics-vs-verdict {
  color: var(--amber);
}

.dot-cat-pos {
  background: var(--dot-pos);
}

.dot-cat-seat {
  background: var(--dot-seat);
}

.dot-cat-tag {
  background: var(--dot-tag);
}

.dynamics-cards {
  gap: var(--sp-12);
}

.dynamics-card {
  background: color-mix(in srgb, var(--white) 2%, transparent);
}

.dynamics-card-kv {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-8);
  padding: var(--sp-4) 0;
  border-top: var(--bw) solid color-mix(in srgb, var(--white) 4%, transparent);
}

/* value span keeps its layout (right-align + width cap) */
.dynamics-card-kv span:last-child {
  text-align: right;
  max-width: 65%;
}

.dynamics-vs {
  margin-top: var(--sp-8);
  padding: var(--sp-8) var(--sp-8);
  border-radius: var(--r-sm);
  border: var(--bw) solid var(--border);
  background: color-mix(in srgb, var(--white) 2%, transparent);
}

.dynamics-vs-stat {
  margin-bottom: var(--sp-4);
}

.dynamics-vs-top {
  gap: var(--sp-8);
}

.dynamics-vs-verdict {
  margin-top: var(--sp-4);
  font-weight: var(--fw-bold);
}

.dynamics-vs.v-ok {
  border-color: color-mix(in srgb, var(--green) 35%, transparent);
  background: color-mix(in srgb, var(--green) 6%, transparent);
}

.dynamics-vs.v-low {
  border-color: color-mix(in srgb, var(--amber) 35%, transparent);
  background: color-mix(in srgb, var(--amber) 6%, transparent);
}

.dynamics-vs.v-high {
  border-color: color-mix(in srgb, var(--red) 35%, transparent);
  background: color-mix(in srgb, var(--red) 8%, transparent);
}

.watch-star {
  font-size: var(--fs-lg) !important;

  color: var(--gold2) !important;
  transition: color .15s, transform .15s;
}

.watch-star:hover {
  color: var(--gold) !important;
  transform: scale(1.2);
}

.watch-star.watched {
  color: var(--gold) !important;
}

/* Player detail view: vertical rhythm between header, tendencies, and the
   shared-hands table so the sections read as distinct blocks. */
.player-detail-section .section-head:first-child {
  margin-top: 0;
}

.saved-section-divider {
  border-bottom: var(--bw) solid var(--border);
  padding-bottom: var(--sp-16);
}

.profile-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-16) var(--sp-32);
  margin-bottom: var(--sp-16);
  align-items: flex-start;
}

.profile-meta {
  margin-top: var(--sp-4);
}

.profile-type-block {
  flex: 1;
  min-width: 220px;
}

.profile-type-desc {
  margin-top: var(--sp-6);
}

.spark-cell {
  width: 80px;
}

.saved-toggle {
  cursor: pointer;
  user-select: none;
  padding: var(--sp-8) 0;
}

.saved-toggle:hover .eyebrow {
  color: var(--text);
}

.saved-toggle-arrow {
  font-size: var(--fs-xs);

  color: var(--dim);
  transition: transform .2s;
}

.saved-section-body {
  max-height: 300px;
  overflow-y: auto;
  padding-top: var(--sp-12);
}

.saved-hands-list {
  --col-min: 260px;
  gap: var(--sp-12);
}

.saved-card {
  position: relative;
}

.saved-pos {
  color: var(--gold2);
  font-weight: var(--fw-medium);
}

.saved-unsave {
  font-size: var(--fs-lg);

  color: var(--gold);
  padding: 0 0 0 var(--sp-8);
}

.saved-unsave:hover {
  color: var(--red);
}

.saved-card-acts {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.saved-card-note-wrap {
  padding: var(--sp-6) var(--sp-8);
}

.saved-note-preview {
  line-height: var(--lh-normal);

  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.saved-card-note-empty {
  font-style: italic;
}

.card-glyph.r {
  color: var(--red);
}

.card-glyph.b {
  color: var(--text);
}

.allin-caveat {
  margin-bottom: var(--sp-12);
  padding: var(--sp-8) var(--sp-12);
  background: color-mix(in srgb, var(--white) 2%, transparent);
}

/* Clause value picker. Positioned absolutely against the document and placed
   by inline top/left from _crShowPopover; without this it falls back into the
   page flow far below the sentence and looks like the click did nothing. */
.cr-pop {
  position: absolute;
  z-index: 200;
  padding: var(--sp-12);
  min-width: 220px;
  max-width: 320px;
  max-height: 60vh;
  overflow-y: auto;
  box-shadow: 0 var(--sp-8) 24px rgba(0, 0, 0, 0.4);
}

.cr-pop-section {
  margin: var(--sp-8) 0 var(--sp-4);
}

.cr-pop-opt {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  background: transparent;
  border: none;
  text-align: left;
  padding: var(--sp-6) var(--sp-8);
  border-radius: var(--r-sm);
  cursor: pointer;
  width: 100%;
}

.cr-pop-opt:hover {
  background: var(--menu-bg);
}

.cr-pop-opt.selected {
  background: var(--menu-bg);
  color: var(--gold);
}

.cr-pop-meta {
  margin-left: auto;
}

.cr-pop-remove {
  display: block;
  width: 100%;
  margin-top: var(--sp-12);
  padding: var(--sp-6) var(--sp-8);
  background: transparent;
  border: var(--bw) solid var(--border);
  color: var(--red);
  font-size: var(--fs-md);

  border-radius: var(--r-sm);
  cursor: pointer;
}

.cr-pop-remove:hover {
  border-color: var(--red);
}

.cr-headline {
  --col-min: 140px;
  gap: var(--sp-12);
}

.cr-headline-compare {
  --col-min: 220px;
}

.cr-tile-dim {
  opacity: 0.45;
}

.cr-tile-compare .cr-tile-trio {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--sp-12);
  align-items: end;
}

/* Cards panel: each hand-type bar is a button into its example hands. */
.cards-bar-row {
  cursor: pointer;
  padding: var(--sp-8);
  margin: calc(-1 * var(--sp-8));
  border-radius: var(--r-sm);
  transition: background .15s;
}

.cards-bar-row:hover {
  background: var(--s1);
}

.cards-row-cue {
  font-size: var(--fs-xs);
}

/* Stat cards that open the hands behind them. Sizing comes from the shared
   stat-grid tile rule; this only adds the interaction affordance. */
.stat-clickable {
  cursor: pointer;
  transition: background .15s;
}

.stat-clickable:hover {
  background: var(--s1);
}

/* Hand-modal stacks block: the component owns its rows — plain divs, each a
   grid of name | start | arrow | end | net so every row's numbers line up. */
.stacks-grid {
  display: flex;
  flex-direction: column;
}

.stacks-grid>div {
  display: grid;
  /* Fixed tracks (not max-content) so the columns line up across rows —
     each row is its own grid and would otherwise size independently. */
  grid-template-columns: minmax(0, 1fr) 11ch 2ch 11ch 11ch;
  gap: var(--sp-12);
  align-items: baseline;
  padding: var(--sp-8) 0;
  border-bottom: var(--bw) solid color-mix(in srgb, var(--border) 55%, transparent);
}

.stacks-grid>div:last-child {
  border-bottom: none;
}

.stacks-grid>div> :nth-child(4) {
  text-align: left;
}

.stacks-grid .stack-start,
.stacks-grid .stack-net {
  text-align: right;
}

.stacks-grid .stack-arrow {
  text-align: center;
}

.reveals-grid {
  display: flex;
  flex-direction: column;
}

.reveals-grid .reveal-row {
  display: grid;
  grid-template-columns: max-content max-content minmax(0, 1fr);
  gap: var(--sp-12);
  align-items: baseline;
  padding: var(--sp-8) 0;
  border-bottom: var(--bw) solid color-mix(in srgb, var(--border) 55%, transparent);
}

.reveals-grid .reveal-row:last-child {
  border-bottom: none;
}

.reveals-grid .reveal-hand {
  text-align: right;
}

/* --- Equity simulator: the labelled equity-bar row (street | pct | track).
   The card is a .list, each street a .list, so all spacing comes from the
   generics — only the bar row's column widths live here. --- */
.eq-street {
  min-width: 58px;
}

.eq-pct {
  text-align: right;
  min-width: 48px;
}

.eq-bar-track {
  flex: 1;
  height: 8px;
  background: var(--border);
  border-radius: var(--r-sm);
  overflow: hidden;
  min-width: 60px;
}

.eq-bar-fill {
  height: 100%;
  background: var(--green);
  border-radius: var(--r-sm);
  transition: width .3s;
}

.eq-spinner {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  padding: var(--sp-12) 0;
}

/* .eq-spinner-ring is defined once in §5 (Panel loading placeholder). */
/* ==========================================================================
   SESSIONS PANEL
   List of sittings → click through to a per-session read (charts, stats,
   story cards, phase table). Classes are namespaced sess-* to avoid the
   existing insight .story / .spark cards.
   ========================================================================== */
/* ==========================================================================
   GUIDED TOUR (intro.js)
   The intro.js stylesheet is injected from the CDN at tour start, AFTER this
   file, so these theme overrides need !important to win the cascade. Retheme
   the default light/blue widget to the app's dark/gold palette.
   ========================================================================== */
.introjs-tooltip {
  background: var(--s2) !important;
  color: var(--text) !important;
  border: var(--bw) solid var(--border) !important;
  border-radius: var(--r-lg) !important;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.6) !important;
  font-family: inherit !important;
  max-width: 340px !important;
}

.introjs-tooltiptext {
  color: var(--text) !important;
}

.introjs-tooltip strong {
  color: var(--gold) !important;
}

/* Tooltip pointer arrow — recolour to the tooltip surface on every side. */
.introjs-arrow.top,
.introjs-arrow.top-right,
.introjs-arrow.top-middle {
  border-bottom-color: var(--s2) !important;
}

.introjs-arrow.bottom,
.introjs-arrow.bottom-right,
.introjs-arrow.bottom-middle {
  border-top-color: var(--s2) !important;
}

.introjs-arrow.left {
  border-right-color: var(--s2) !important;
}

.introjs-arrow.right {
  border-left-color: var(--s2) !important;
}

.introjs-tooltipbuttons {
  border-top: none !important;
}

.introjs-button {
  background: transparent !important;
  border: var(--bw) solid var(--gold2) !important;
  color: var(--gold2) !important;
  text-shadow: none !important;
  border-radius: var(--r-sm) !important;
  font-family: var(--serif) !important;
}

.introjs-button:hover,
.introjs-button:focus {
  background: var(--gold) !important;
  border-color: var(--gold) !important;
  color: var(--bg) !important;
}

.introjs-disabled,
.introjs-disabled:hover {
  color: var(--muted) !important;
  border-color: var(--border) !important;
  background: transparent !important;
}

/* Progress bar (was the default blue). */
.introjs-progress {
  background: var(--border) !important;
}

.introjs-progressbar {
  background: var(--gold) !important;
}

/* Step bullets. */
.introjs-bullets ul li a {
  background: var(--muted) !important;
}

.introjs-bullets ul li a.active {
  background: var(--gold) !important;
}

.introjs-skipbutton {
  color: var(--dim) !important;
  text-shadow: none !important;
}

.introjs-skipbutton:hover {
  color: var(--gold) !important;
}

/* Spotlight ring around the highlighted element. */
.introjs-helperLayer {
  border-radius: var(--r-sm) !important;
  box-shadow: 0 0 0 2px var(--gold2), 0 0 0 5000px rgba(0, 0, 0, 0.6) !important;
}

/* ==========================================================================
   7. RESPONSIVE
   All @media overrides live here, LAST in the file, so they win the cascade
   over the base rules they narrow (which are defined in the sections above).
   ========================================================================== */

/* Tablet: collapse the saved-hands grid to one column. */
@media (max-width: 900px) {
  .saved-hands-list {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 560px) {
  .saved-hands-list {
    grid-template-columns: 1fr;
    gap: var(--sp-8);
  }

  .saved-card {
    padding: var(--sp-12);
  }
}

/* ===== Home & hub pages (nav redesign) =====
   The welcome tab is a compact home: hero band, three area hub cards, then a
   What's-new carousel beside a rotating tip. Each area also has a hub page of
   page cards. These panels run on their own tight rhythm, so the default
   .panel.on gap is zeroed and the blocks carry their own margins. */

/* Dropdowns open on hover; clicking the section label opens its hub page. */
.tab-menu:hover .tab-menu-items {
  display: block;
}

#p-welcome.on,
#p-hub-sum.on,
#p-hub-brk.on,
#p-hub-his.on {
  gap: 0;
}

/* home: compact hero — one tight band, not a full screen of headline */
.home-hero {
  margin-bottom: var(--sp-24);
}

.home-hero h1 {
  font-size: clamp(32px, 4vw, 44px);
  line-height: var(--lh-none);
  color: var(--gold);
}

.home-hero .lead {
  font-family: var(--mono);
  font-size: var(--fs-md);
  color: var(--dim);
  max-width: 60ch;
  margin-top: var(--sp-6);
}

.home-tour-btn {
  white-space: nowrap;
}

.areas-head {
  margin-bottom: var(--sp-16);
}

/* the hubs — the hero of the page: three tall cards, or one stacked column */
.hub-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-16);
}

@media (max-width: 980px) {
  .hub-grid {
    grid-template-columns: 1fr;
  }
}

.hub-card {
  text-align: left;
  justify-content: flex-start;
  gap: var(--sp-16);
  padding: var(--sp-24) var(--sp-24) var(--sp-16);
  min-height: 240px;
}

.hub-card h2 {
  color: var(--gold);
}

.hub-card .text-body {
  flex: 1;
}

.hub-card .hub-pages {
  padding-top: var(--sp-12);
  border-top: var(--bw) solid var(--border);
  color: var(--dim);
  font-size: var(--fs-xs);
  letter-spacing: .5px;
  text-transform: uppercase;
  line-height: var(--lh-snug);
}

.hub-card .go,
.page-card .go {
  color: var(--gold);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-md);
}

/* hub page */
.crumb {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-6);
  color: var(--dim);
  font-size: var(--fs-xs);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  margin-bottom: var(--sp-16);
}

.crumb:hover {
  color: var(--gold);
}

.hub-head {
  margin-bottom: var(--sp-48);
}

.hub-head h1 {
  color: var(--gold);
}

.hub-head .lead {
  font-size: var(--fs-xl);
  max-width: 760px;
  margin-top: var(--sp-12);
}

.subgroup-head {
  font-family: var(--serif);
  font-size: var(--fs-2xl);
  color: var(--text);
  margin: var(--sp-48) 0 var(--sp-16);
}

.hub-head+.subgroup-head {
  margin-top: 0;
}

.page-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-24);
}

@media (max-width: 620px) {
  .page-grid {
    grid-template-columns: 1fr;
  }
}

.page-card {
  text-align: left;
  padding: var(--sp-16);
}

.page-card h3 {
  color: var(--gold);
}

.page-card .go {
  margin-top: auto;
  padding-top: var(--sp-8);
}

/* home foot: What's new (left) + Tip (right) share one compact row */
.home-foot {
  display: grid;
  grid-template-columns: 1.7fr 1fr;
  gap: var(--sp-24);
  align-items: stretch;
  margin-top: var(--sp-24);
  padding-top: var(--sp-24);
  border-top: var(--bw) solid var(--border);
}

@media (max-width: 860px) {
  .home-foot {
    grid-template-columns: 1fr;
  }
}

.wn-head {
  margin-bottom: var(--sp-12);
}

.wn-controls {
  gap: var(--sp-8);
}

.whatsnew .card {
  text-align: left;
  padding: var(--sp-16);
}

.wn-slide {
  display: none;
}

.wn-slide.on {
  display: flex;
}

.wn-dots {
  display: flex;
  gap: var(--sp-6);
  align-items: center;
}

.wn-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-pill);
  background: var(--border);
  border: none;
  padding: 0;
  cursor: pointer;
}

.wn-dot.on {
  background: var(--gold);
}

.tip-panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--sp-8);

  border: var(--bw) solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-24);
}

.tip-panel .tip-label {
  font-size: var(--fs-xs);
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--gold2);
}

.tip-panel .tip-text {
  font-size: var(--fs-md);
  font-weight: 300;
  line-height: var(--lh-body);
  color: var(--text);
  transition: opacity .3s;
}

/* ===== Searchable player picker (compare modal) =====
   A text input with a floating, filterable option list — replaces the native
   <select> so long player pools can be typed to search. */
.compare-picker {
  position: relative;
  z-index: 2;
}

.combo {
  position: relative;
  flex: 1;
  min-width: 0;
}

.combo-input {
  width: 100%;
}

.combo-list {
  position: absolute;
  top: calc(100% + var(--sp-4));
  left: 0;
  right: 0;
  max-height: 240px;
  overflow-y: auto;
  background: var(--menu-bg, var(--s2));
  border: var(--bw) solid var(--tint-light-2, var(--border));
  border-radius: var(--r-sm);
  box-shadow: 0 8px 32px var(--bg-overlay);
  z-index: 1002;
}

.combo-option {
  padding: var(--sp-6) var(--sp-8);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.combo-option:hover,
.combo-option.selected {
  background: var(--tint-light);
  color: var(--gold);
}

.combo-empty {
  padding: var(--sp-6) var(--sp-8);
}

/* ===== Phone layout =====
   Rows are the side-by-side layout primitive (two containers, chart grids,
   header bars). On a phone there is no room for two columns, so every .row
   stacks and its children take the full width. This is what turns the 2x2
   chart grids (Trends, Sessions, Custom) into a single column on mobile. */
@media (max-width: 680px) {
  .row {
    flex-direction: column;
    gap: var(--sp-12);
  }

  .row>.container,
  .row>.story {
    width: 100%;
    flex-basis: auto;
  }

  /* Tighten the sticky header so the stat strip and nav are not cramped. */
  .dash-header {
    padding: 0 var(--sp-16);
  }

  .hero-strip,
  .tab-nav {
    margin: 0 calc(-1 * var(--sp-16));
  }

  /* The hero stat strip is a single squished flex row on desktop; on a phone
     lay the six stats out on a grid so each gets room to breathe. */
  .hero-strip {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }

  .hs {
    padding: var(--sp-8) var(--sp-12);
  }

  .hs-l,
  .hs-v {
    white-space: normal;
    word-break: break-word;
  }
}

@media (max-width: 440px) {
  .hero-strip {
    grid-template-columns: repeat(2, 1fr);
  }
}