@import url('https://fonts.googleapis.com/css2?family=Oxanium:wght@400;500;600;700;800&family=Manrope:wght@300;400;500;600;700&display=swap');

/* ── Variables ─────────────────────────────────────────────── */
:root {
  --bg:          #0d1117;
  --panel:       #111a11;
  --panel-alt:   #162016;
  --border:      #1e2d1e;
  --text:        #d0ddd0;
  --muted:       #6b8c6b;
  --green:       #00e676;
  --green-dim:   #00c853;
  --red:         #ff5252;
  --blue:        #40c4ff;
  --yellow:      #cccc00;

  /* 4-colour deck */
  --hearts:   #ff5252;
  --spades:   #d0ddd0;
  --diamonds: #40c4ff;
  --clubs:    #00e676;

  --font-head: 'Oxanium', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'Manrope', 'Segoe UI', system-ui, sans-serif;

  /* Brand palette (sampled from reference icon + wordmark lockup) */
  --color-bg:                 #0B161F;
  --color-bg-black:           #000000;
  --color-brand-green:        #3CAC53;
  --color-brand-green-dark:   #28763A;
  --color-accent-green:       #39B577;
  --color-accent-green-dark:  #1D5D3D;

  /* ── Semantic tokens ─────────────────────────────────────────
     These carry the values that must FLIP between themes. The dark
     values live here on :root (the default); the light theme
     redefines them under [data-theme="light"] below. Everything
     else (the deck colours, the greens/reds) is themed by
     redefining the base token, not by adding a new one.

     The overlay tokens are the crux of light mode: on dark they are
     white-alpha washes; on light they become black-alpha, so the
     ~40 `#ffffffXX` separators/hovers scattered through the app
     don't vanish on a pale ground. */
  color-scheme: dark;
  --placeholder:  var(--placeholder);
  --hairline:     rgba(255,255,255,.10);
  --overlay-lo:   rgba(255,255,255,.04);
  --overlay-mid:  rgba(255,255,255,.08);
  --overlay-hi:   rgba(255,255,255,.14);
  --overlay-max:  rgba(255,255,255,.22);
  --scrim:        rgba(0,0,0,.62);
  --shadow-card:  0 4px 24px rgba(0,0,0,.40);
  --win:          #00e676;
  --loss:         #ff5252;
  /* Raised "felt" surface for the hero import card + accent haze */
  --felt-raise:   #17211a;
  --accent-glow:  rgba(0,230,118,.30);
}

/* ── Light theme — "card-room daylight" ──────────────────────────
   A warm parchment ground under a deep felt green, not a cold grey
   SaaS light. Bright neon `--green` would fail contrast as text on
   bone, so in light it becomes a deep emerald that reads both as
   text and as a button fill; the deck suits and the win/loss greens
   deepen to stay legible on the pale ground. Applied only when
   <html data-theme="light"> is set (see the no-flash head snippet in
   every template). */
[data-theme="light"] {
  color-scheme: light;

  --bg:          #EFEADC;
  --panel:       #FBF9F3;
  --panel-alt:   #F3EEDF;
  --border:      #D8CFB8;
  --text:        #16221A;
  --muted:       #5C6B5A;

  --green:       #147a41;
  --green-dim:   #0f6636;
  --red:         #cc2f39;
  --blue:        #1f7fb8;
  --yellow:      #8a6d00;

  /* 4-colour deck, deepened for the pale ground */
  --hearts:      #cc2f39;
  --spades:      #16221A;
  --diamonds:    #1f7fb8;
  --clubs:       #147a41;

  --placeholder: #9a917d;
  --hairline:    rgba(20,30,20,.14);
  --overlay-lo:  rgba(20,30,20,.035);
  --overlay-mid: rgba(20,30,20,.065);
  --overlay-hi:  rgba(20,30,20,.11);
  --overlay-max: rgba(20,30,20,.17);
  --scrim:       rgba(30,40,25,.34);
  --shadow-card: 0 6px 22px rgba(70,58,24,.14);
  --win:         #0f8a48;
  --loss:        #cc2f39;
  --felt-raise:  #F6F2E6;
  --accent-glow: rgba(20,122,65,.20);
}

/* ── Bootstrap compatibility in light theme ──────────────────────
   Bootstrap components that hard-code a dark look (`.table-dark`,
   `.btn-close-white`) don't follow our tokens, so they'd stay dark
   on a light page. Re-point their own CSS variables at our tokens. */
[data-theme="light"] .table-dark {
  --bs-table-bg:          var(--panel);
  --bs-table-color:       var(--text);
  --bs-table-border-color:var(--border);
  --bs-table-striped-bg:  var(--overlay-lo);
  --bs-table-striped-color:var(--text);
  --bs-table-hover-bg:    var(--overlay-mid);
  --bs-table-hover-color: var(--text);
  color: var(--text);
}
[data-theme="light"] .btn-close-white {
  filter: none;
}

/* ── Skip link (accessibility Fix 4) ───────────────────────── */
.skip-link {
  position: absolute;
  top: -100%;
  left: 0;
  background: var(--green);
  color: #000;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: .9rem;
  padding: .5rem 1rem;
  z-index: 9999;
  text-decoration: none;
  border-radius: 0 0 4px 0;
}
.skip-link:focus {
  top: 0;
}

/* ── Base ──────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ── Ambient background — every page ─────────────────────────────
   A single body rule, so it's automatic on every page that loads this
   stylesheet (index, admin, leaks, tournaments, offline) with no template
   changes. static/icons/bg-flow.svg is a tall (900x1800) tile of soft,
   low-opacity brand-gradient ribbons and oversized spade watermarks —
   its own file comment has the design notes. background-position drifts
   downward by exactly one tile-height on a slow loop; since the art tiles
   seamlessly on repeat-y, the loop reset is invisible, so it reads as a
   continuous slow scroll rather than a snap. Dark theme only — the art
   is tuned for the near-black background and would just look muddy on
   light's parchment tone, so light theme keeps a flat --bg instead. */
html:not([data-theme="light"]) body {
  background-image: url('/static/icons/bg-flow.svg');
  background-repeat: repeat-y;
  background-position: center top;
  background-size: 100% 1800px;
  animation: bg-flow-drift 150s linear infinite;
}
@keyframes bg-flow-drift {
  from { background-position: center 0; }
  to   { background-position: center 1800px; }
}
@media (prefers-reduced-motion: reduce) {
  html:not([data-theme="light"]) body { animation: none; }
}

.container-fluid { flex: 1; }

.site-footer { margin-top: auto; }

/* ── App header ───────────────────────────────────────────── */
.app-title {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Fixed size at every viewport — the brand mark never shrinks to fit. A
   viewport too narrow for it gets horizontal scroll on the page instead
   (no max-width cap here), rather than a smaller logo. */
.app-title-wordmark {
  width: 483px;
  height: auto;
  filter: drop-shadow(0 0 24px var(--accent-glow));
}

.app-tagline {
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 2px;
}

/* ── Side banner (vertical, auto-rotating) ────────────────────
   Fixed to the right edge. The Task's AC forbids overlapping content, and
   the original 1900px floor bought that by never showing at all: a 1920px
   monitor is ~1900 CSS px of viewport once chrome and scrollbar are off,
   so the slot was invisible on everything short of an ultrawide.

   Instead of waiting for a gutter wide enough to appear on its own, the
   layout now *makes* one: `main` takes a matching padding-right (below) so
   the fixed banner sits in reserved space rather than over the content
   column. The column's max-width:1400px is a max, not a fixed width, so it
   simply narrows on screens too small to keep both at full size. */
.side-banner {
  position: fixed;
  top: 50%;
  right: 16px;
  transform: translateY(-50%);
  width: 120px;
  height: 480px;
  background: var(--color-bg-black);
  border: 1px solid var(--color-accent-green-dark);
  border-radius: 10px;
  overflow: hidden;
  z-index: 20;
  box-shadow: 0 4px 20px rgba(0,0,0,.4);
}
.side-banner-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity .4s ease;
}

/* Below this the page has no width to spare: reserving 152px would squeeze
   the content column harder than a promo slot justifies, so the banner is
   dropped rather than shown over the content. 1440px keeps it on common
   laptop screens (1440/1512/1728) and up. */
@media (max-width: 1439.98px) {
  .side-banner { display: none; }
}

/* right:16px + 120px wide + 16px breathing gap. Applied only while a banner
   is actually on screen (`has-side-banner` is set by _initSideBanner once it
   has at least one image), so a slot an admin has cleared costs no layout.
   !important overrides Bootstrap's own !important .px-md-5 on <main>. */
@media (min-width: 1440px) {
  body.has-side-banner #main-content { padding-right: 152px !important; }
}

/* ── Mid-page banner (horizontal) ─────────────────────────────
   Static promo slot between the free-vs-pro pitch and the results
   section. Configured at /admin (see _initMidBanner in app.js); when the
   image is cleared the slot renders nothing and reserves no height, rather
   than showing an empty box. */
.mid-banner {
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--color-accent-green-dark);
  border-radius: 10px;
  overflow: hidden;
  background: var(--color-bg-black);
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
.mid-banner:hover {
  border-color: var(--color-accent-green);
  box-shadow: 0 0 16px rgba(0,230,118,.18);
}
.mid-banner:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
}
/* Both banner slots ride on a hardcoded brand-black behind their image;
   on the light theme a black rectangle among parchment reads as broken
   layout, so match the ground instead. The image (when set) still sits
   on top via object-fit: cover. */
[data-theme="light"] .mid-banner,
[data-theme="light"] .side-banner {
  background: var(--panel-alt);
  border-color: var(--border);
  box-shadow: var(--shadow-card);
}
.mid-banner-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 180px;
  object-fit: cover;
}

/* ── Feature banner ──────────────────────────────────────── */
.feature-banner {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Info tiles strip — the five modal buttons.
   They hold a single line at every width: instead of wrapping, the whole
   strip scales down with the viewport. Its type shrinks faster than the
   wordmark above it (1.5vw against the wordmark's 53vw floor of 253px), so
   the tiles are what give way first as the window narrows. */
.info-tiles {
  display: flex;
  gap: clamp(2px, .7vw, 8px);
  flex-wrap: nowrap;
  justify-content: center;
  max-width: 100%;
}

.info-tile {
  display: inline-flex;
  align-items: center;
  gap: clamp(2px, .6vw, 7px);
  padding: clamp(5px, .9vw, 7px) clamp(5px, 1.5vw, 16px);
  background: rgba(0,230,118,.07);
  border: 1px solid rgba(0,230,118,.22);
  border-radius: 8px;
  white-space: nowrap;
  color: var(--green);
  font-family: var(--font-head);
  font-size: clamp(.42rem, 1.6vw, .82rem);
  font-weight: 600;
  letter-spacing: .4px;
  flex: 0 1 auto;
  min-width: 0;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.info-tile:hover {
  background: rgba(0,230,118,.14);
  border-color: rgba(0,230,118,.45);
  color: var(--green);
}
.info-tile svg {
  opacity: .85;
  flex-shrink: 0;
  width: clamp(11px, 1.7vw, 20px);
  height: clamp(11px, 1.7vw, 20px);
}

/* Free vs Pro comparison */
.tier-compare {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 10px;
  align-items: stretch;
}
/* Hidden-until-resolved: cleared by _applyTierVisibility() once the tier is known. */
.tier-pending {
  display: none !important;
}
.tier-vs {
  display: flex;
  align-items: center;
}

@media (max-width: 500px) {
  .tier-compare {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
  }
  .tier-vs { display: none; }
}

.tier-card {
  border-radius: 10px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
}

.tier-free {
  background: var(--panel);
  border: 1px solid var(--border);
}

.tier-pro {
  background: linear-gradient(135deg, #1a200a 0%, #111a11 100%);
  border: 1px solid var(--yellow);
  box-shadow: 0 0 18px rgba(204,204,0,.1);
}
[data-theme="light"] .tier-pro {
  background: linear-gradient(135deg, #FFF7D6 0%, #FBF3D0 100%);
  border-color: rgba(138,109,0,.55);
  box-shadow: 0 0 0 1px rgba(138,109,0,.10), var(--shadow-card);
}
[data-theme="light"] .tier-pro .tier-name,
[data-theme="light"] .tier-pro .tier-early-note,
[data-theme="light"] .tier-pro .tier-list li { color: var(--text); }

.tier-name {
  font-family: var(--font-head);
  font-size: .9rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin-bottom: 10px;
}
.tier-free .tier-name { color: var(--muted); }
.tier-pro  .tier-name { color: var(--yellow); }

/* Full price, struck through while a discounted plan is the active one. */
.tier-price-was {
  color: var(--muted);
  font-weight: 600;
  opacity: .75;
  margin-right: 2px;
}

/* Early Access price framing — sits under the tier name, deliberately quiet */
.tier-early-note {
  font-size: .68rem;
  line-height: 1.3;
  color: var(--muted);
  margin: -6px 0 10px;
}

.tier-list {
  list-style: none;
  padding: 0; margin: 0 0 12px;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.tier-list li {
  font-family: var(--font-body);
  font-size: .82rem;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 7px;
}
.tier-check { color: var(--green); font-weight: 700; font-size: .85rem; }
.tier-x     { color: var(--muted); font-weight: 700; font-size: .85rem; }
.tier-free .tier-x ~ * { color: var(--muted); }

.tier-cta {
  width: 100%;
  padding: 9px 0;
  background: var(--yellow);
  border: none;
  border-radius: 7px;
  color: #000;
  font-family: var(--font-head);
  font-size: .9rem;
  font-weight: 700;
  letter-spacing: .5px;
  cursor: pointer;
  transition: background .15s, box-shadow .15s;
  min-height: 40px;
}
.tier-cta:hover { background: #e6e600; box-shadow: 0 0 12px rgba(204,204,0,.3); }

.tier-vs {
  font-family: var(--font-head);
  font-size: .85rem;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 2px;
  justify-content: center;
}

/* ── Hero row — import card + medal card ───────────────────────
   Wide screens: the medal card sits to the left of the import card (order
   swaps it ahead despite coming after it in the DOM) as a ~30%-width
   column, capped at 280px — wide enough for the medal art + title to sit
   side by side without wrapping too tightly, but past that width it holds
   still rather than growing further; the import card (flex: 1 1 auto)
   absorbs all the extra room instead. align-items: stretch makes both
   cards match the row's tallest natural height. Narrow screens: same
   order, stacked in a column, where the stretch instead makes each card
   span the full width. */
.hero-row {
  display: flex;
  gap: 1rem;
  max-width: 1400px;
  margin: 0 auto;
  align-items: stretch;
}
.hero-row .import-card { order: 1; flex: 1 1 auto; min-width: 0; }
.hero-row #gam-block-right { order: 0; flex: 0 1 30%; max-width: 280px; min-width: 0; }
@media (max-width: 767.98px) {
  .hero-row { flex-direction: column; }
  .hero-row .import-card,
  .hero-row #gam-block-right { flex: 1 1 auto; }
  .hero-row #gam-block-right { max-width: none; }
}

/* ── Import card — the hero ───────────────────────────────────
   This is the page's single job on first load, so it reads as a
   raised patch of felt with an accent rim rather than just another
   panel. The eyebrow + hint frame it without competing. */
.import-card {
  background: var(--felt-raise);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 0 0 1px var(--accent-glow), var(--shadow-card);
  padding: 18px 20px 16px;
}
.import-eyebrow {
  font-family: var(--font-head);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--green);
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 11px;
}
/* The app's own mark leads the label — it replaced the dealt-card tick
   that used to sit here, so the card is branded rather than decorated. */
.import-eyebrow-logo {
  width: 26px;
  height: 26px;
  object-fit: contain;
  flex: 0 0 auto;
}
.import-input {
  flex: 1 1 0;
  /* Small floor rather than 0 — the button never wraps below it (flex-nowrap
     on the row), so past this width the row itself overflows instead of the
     input becoming too narrow to paste a link into. */
  min-width: 120px;
  font-size: 1.02rem;
}
.form-label {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1rem;
  color: var(--text);
  letter-spacing: .5px;
}

.form-control {
  background: var(--bg) !important;
  border: 1px solid var(--border) !important;
  color: var(--text) !important;
  border-radius: 8px;
  font-family: var(--font-body);
  min-height: 48px;
}
.form-control:focus {
  border-color: var(--green) !important;
  box-shadow: 0 0 0 0.2rem rgba(0,230,118,.15) !important;
}
.form-control::placeholder { color: var(--placeholder); font-size: .88rem; }

/* Site-wide hint/ghost-text style (Task: "Layout updates") — every plain
   input/textarea gets the same themed placeholder as .form-control instead
   of falling back to the browser/OS default. */
input::placeholder,
textarea::placeholder { color: var(--placeholder); font-size: .88rem; }

.btn-import {
  background: var(--green);
  border: none;
  color: #000;
  font-family: var(--font-head);
  font-size: .95rem;
  font-weight: 800;
  letter-spacing: 2px;
  text-transform: uppercase;
  border-radius: 8px;
  min-height: 48px;
  padding: 0 28px;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background .15s, box-shadow .15s;
}
.btn-import:hover   { background: var(--green-dim); color: #000; box-shadow: 0 0 12px rgba(0,230,118,.35); }
.btn-import:disabled { opacity: .5; cursor: not-allowed; }

/* Secondary modal-confirm button (e.g. "Apply", "Send Magic Link") —
   was duplicated inline across modals with identical values. */
.btn-outline-accent {
  background: rgba(0,230,118,.12);
  border: 1px solid rgba(0,230,118,.5);
  color: var(--green);
  font-family: var(--font-head);
  font-size: .8rem;
  letter-spacing: .5px;
}
.btn-outline-accent:hover:not(:disabled) { background: rgba(0,230,118,.2); }
.btn-outline-accent:disabled { opacity: .5; cursor: not-allowed; }

/* ── Validation strip ─────────────────────────────────────── */
.val-strip  { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 2px; }
.val-pill   {
  display: inline-flex; align-items: baseline; gap: 4px;
  font-size: .75rem; padding: 2px 9px;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 20px; white-space: nowrap;
  font-family: var(--font-body);
}
.val-pill strong      { color: var(--green); font-size: .82rem; font-family: var(--font-head); font-weight: 700; }
.val-pill-label       { color: var(--muted); font-size: .7rem; }
.val-sep              { color: var(--border); font-size: .75rem; padding: 0 2px; user-select: none; }

/* ── Export cards (Hand History panel) ───────────────────── */
.export-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
@media (max-width: 540px) { .export-cards { grid-template-columns: 1fr; } }

.export-card {
  display: flex; flex-direction: column; gap: 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
}

.export-card-label {
  font-family: var(--font-head);
  font-size: .8rem; font-weight: 700;
  color: var(--green); text-transform: uppercase; letter-spacing: 1px;
}

/* ── 2×2 icon grid inside each export card ────────────────── */
.export-btn-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.export-grid-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 10px 6px;
  background: rgba(0,230,118,.08);
  border: 1px solid rgba(0,230,118,.4);
  border-radius: 8px;
  color: var(--green);
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .3px;
  text-transform: uppercase;
  min-height: 64px;
  transition: background .15s, border-color .15s, box-shadow .15s;
  cursor: pointer;
}
.export-grid-btn:hover  { background: rgba(0,230,118,.22); border-color: var(--green); box-shadow: 0 0 14px rgba(0,230,118,.35); color: var(--green); }
.export-grid-btn img    { border-radius: 3px; }
.export-grid-btn svg    { flex-shrink: 0; }
.export-grid-btn span   { line-height: 1.1; text-align: center; }

/* Legacy full-width buttons (kept for any remaining references) */
.export-full-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 14px;
  background: var(--green);
  border: none;
  border-radius: 8px;
  color: #000;
  font-family: var(--font-head);
  font-size: .9rem;
  font-weight: 700;
  letter-spacing: .3px;
  min-height: 48px;
  transition: background .15s;
}
.export-full-btn:hover { background: var(--green-dim); color: #000; }
.export-full-btn img { border-radius: 3px; flex-shrink: 0; }
.export-full-btn span { flex: 1; text-align: center; }

/* ── Export icon buttons (tournament row) ─────────────────── */
.export-icon-btn {
  width: 38px;
  height: 38px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(0,230,118,.08);
  border: 1px solid rgba(0,230,118,.4);
  border-radius: 7px;
  color: var(--green);
  font-size: .7rem;
  font-weight: 700;
  transition: background .15s, border-color .15s, box-shadow .15s;
}
.export-icon-btn:hover { background: rgba(0,230,118,.22); border-color: var(--green); box-shadow: 0 0 10px rgba(0,230,118,.3); color: var(--green); }
.export-icon-btn img { display: block; border-radius: 3px; }

/* Signed out, the four export icons collapse into one honest label. */
.signin-export-btn {
  width: auto;
  height: auto;
  gap: 6px;
  padding: 5px 10px;
  white-space: nowrap;
  background: rgba(227,179,65,.08);
  border-color: rgba(227,179,65,.4);
  color: var(--yellow);
  font-size: .72rem;
  letter-spacing: .02em;
}
.signin-export-btn:hover {
  background: rgba(227,179,65,.2);
  border-color: var(--yellow);
  box-shadow: 0 0 10px rgba(227,179,65,.25);
  color: var(--yellow);
}

/* ── Section cards ────────────────────────────────────────── */
.section-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  /* A flat black shadow reads on light mode's pale ground but disappears
     against dark mode's near-black background — so both themes get a
     brand-tinted rim (the wordmark's green, via --accent-glow) stacked on
     the theme's own --shadow-card, same recipe as .import-card above. */
  box-shadow: 0 0 0 1px var(--accent-glow), var(--shadow-card);
}

.section-header {
  background: var(--panel-alt);
  border-bottom: 1px solid var(--border);
  padding: 12px 18px;
}

.section-header h5,
.section-header h2 {
  font-family: var(--font-head);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--green);
  letter-spacing: .8px;
  margin: 0;
  text-transform: uppercase;
}

/* Right-hand context in a section header (hand count, date). --muted on the
   header's lighter panel is barely legible, so this sits closer to --text. */
.section-header .section-hint {
  font-family: var(--font-head);
  font-size: .78rem;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: .4px;
  white-space: nowrap;
}

/* Section header — prevent icon+title from wrapping awkwardly */
.section-header h5,
.section-header h2 { flex-wrap: nowrap; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.section-header h5 small,
.section-header h2 small { white-space: normal; }

/* ── Player badge ─────────────────────────────────────────── */
.player-badge {
  background: rgba(0,230,118,.05);
  border: 1px solid rgba(0,230,118,.18);
  color: var(--text);
  border-radius: 10px;
  padding: 10px 14px;
  font-family: var(--font-head);
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .3px;
}

.player-avatar {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid var(--green);
  background: rgba(0,230,118,.1);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-head);
  font-size: .85rem;
  font-weight: 800;
  color: var(--green);
  letter-spacing: 1px;
}

.player-badge-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 14px;
}

.player-badge-top > .d-flex {
  flex: 1 1 180px;
  min-width: 0;
}

.player-tz {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.tz-label {
  font-size: .82rem;
  color: var(--muted);
  white-space: nowrap;
  font-family: var(--font-body);
  font-weight: 500;
}

.tz-select {
  background: var(--panel-alt);
  border: 1px solid rgba(0,230,118,.25);
  color: var(--text);
  font-family: var(--font-body);
  font-size: .82rem;
  border-radius: 6px;
  padding: 3px 8px;
  min-width: 72px;
  width: auto;
}

.tz-select:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 2px rgba(0,230,118,.15);
}

@media (max-width: 360px) {
  .player-badge-top {
    flex-direction: column;
    align-items: flex-start;
  }
  .player-badge-top > .d-flex {
    flex: none;
  }
}

/* ── Loaded Hands pills (inside player badge) ─────────────── */
/* The pills themselves are .val-pill, shared with the tournament-summary
   strip; only the row layout is specific to the player badge. */
.loaded-hands-row {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 6px;
}

/* ── Playing card chips ───────────────────────────────────── */
.playing-card {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-width: 30px;
  height: 36px;
  padding: 3px 5px;
  background: #ffffff;
  border: 1px solid #c0c0c0;
  border-radius: 5px;
  margin-right: 3px;
  box-shadow: 0 2px 6px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.9);
  user-select: none;
  vertical-align: middle;
  line-height: 1;
}
.card-rank {
  font-family: 'Georgia', serif;
  font-weight: 700;
  font-size: .9rem;
  line-height: 1;
  letter-spacing: -.5px;
}
.card-suit { font-size: .95rem; line-height: 1; }
.playing-card.suit-hearts   { color: #cc0000; }
.playing-card.suit-spades   { color: #0d0d0d; }
.playing-card.suit-diamonds { color: #1155bb; }
.playing-card.suit-clubs    { color: #008833; }
.playing-card.suit-unknown  { color: #999; }

/* ── Profit / Loss ────────────────────────────────────────── */
.profit-pos  { color: var(--green);  font-weight: 600; font-family: var(--font-head); }
.profit-neg  { color: var(--red);    font-weight: 600; font-family: var(--font-head); }
.profit-zero { color: var(--muted); }

/* ── Result badges ────────────────────────────────────────── */
.badge-won  {
  background: rgba(0,230,118,.12); color: var(--green);
  border: 1px solid rgba(0,230,118,.35);
  padding: 3px 9px; border-radius: 5px;
  font-family: var(--font-head); font-size: .82rem; font-weight: 700;
  letter-spacing: .4px;
}
.badge-lost {
  background: rgba(255,82,82,.12); color: var(--red);
  border: 1px solid rgba(255,82,82,.35);
  padding: 3px 9px; border-radius: 5px;
  font-family: var(--font-head); font-size: .82rem; font-weight: 700;
  letter-spacing: .4px;
}
.badge-break {
  background: rgba(107,140,107,.1); color: var(--muted);
  border: 1px solid rgba(107,140,107,.3);
  padding: 3px 9px; border-radius: 5px;
  font-family: var(--font-head); font-size: .82rem;
}

/* ── Position / street badges ─────────────────────────────── */
/* Both are fixed-width so a column of them reads as a column rather than a
   ragged edge — each group sized to its own longest label (UTG+2 / Showdown),
   which also keeps the graph's hand card from resizing as you scrub. */
.pos-badge {
  display: inline-flex;
  align-items: center; justify-content: center;
  min-width: 4.2rem;
  padding: 2px 6px; border-radius: 4px;
  font-family: var(--font-head); font-size: .78rem; font-weight: 700;
  background: rgba(64,196,255,.1);
  color: var(--blue);
  border: 1px solid rgba(64,196,255,.25);
  letter-spacing: .3px;
}
.pos-btn { background: rgba(204,204,0,.1); color: var(--yellow); border-color: rgba(204,204,0,.3); }
.pos-bl  { background: rgba(107,140,107,.08); color: var(--muted); border-color: rgba(107,140,107,.2); }

.street-badge { min-width: 5.6rem; }
.street-vpip  { color: var(--yellow); border-color: rgba(227,179,65,.3); background: rgba(227,179,65,.12); }
.street-flop  { color: var(--blue);   border-color: rgba(88,166,255,.3); background: rgba(88,166,255,.12); }
.street-turn  { color: var(--yellow); border-color: rgba(227,179,65,.3); background: rgba(227,179,65,.12); }
.street-river { color: var(--green);  border-color: rgba(63,185,80,.3);  background: rgba(63,185,80,.12); }
.street-sd    { color: #a371f7;       border-color: rgba(163,113,247,.3); background: rgba(163,113,247,.12); }

/* ── Stat cards grid ──────────────────────────────────────── */
.stat-card {
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 12px 14px;
  text-align: center;
  height: 100%;
}
.stat-value {
  font-family: var(--font-head);
  font-size: 1.75rem; font-weight: 700;
  color: var(--green); line-height: 1.1;
  letter-spacing: .5px;
}
.stat-value.neg   { color: var(--red); }
.stat-value.muted { color: var(--muted); }
.stat-label {
  font-family: var(--font-head);
  font-size: .7rem; color: var(--muted); margin-top: 5px;
  text-transform: uppercase; letter-spacing: 1px;
  font-weight: 600;
}

/* ── Tables ───────────────────────────────────────────────── */
.table-dark {
  --bs-table-bg: transparent;
  --bs-table-striped-bg: rgba(0,230,118,.025);
  --bs-table-hover-bg:   rgba(0,230,118,.05);
  color: var(--text);
  margin-bottom: 0;
  font-family: var(--font-body);
}
.table-dark thead th {
  font-family: var(--font-head);
  color: var(--muted);
  font-size: .74rem;
  text-transform: uppercase;
  letter-spacing: .6px;
  border-bottom: 1px solid var(--border) !important;
  font-weight: 700;
  padding: 10px 9px;
}
.table-dark tbody td {
  border-color: var(--border) !important;
  vertical-align: middle;
  font-size: 1rem;
  padding: 10px 9px;
}
.table-dark .text-muted { color: var(--muted) !important; }

.replay-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1.5px solid rgba(0,230,118,.45);
  color: var(--green);
  text-decoration: none;
  font-size: .95rem;
  line-height: 1;
  transition: background .15s, border-color .15s;
}
.replay-link:hover {
  background: rgba(0,230,118,.12);
  border-color: var(--green);
  color: var(--green);
}

.no-wrap { white-space: nowrap; }

/* Copy-hand-id button in When column */
.hand-when-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.copy-hand-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1.5px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  opacity: 1;
  transition: color .2s, border-color .2s, background .2s, transform .15s;
  flex-shrink: 0;
}
.copy-hand-btn:hover {
  color: var(--green);
  border-color: rgba(0,230,118,.45);
  background: rgba(0,230,118,.08);
}
.copy-hand-btn.copied {
  color: var(--green);
  border-color: var(--green);
  background: rgba(0,230,118,.15);
  transform: scale(1.12);
}
.copy-hand-btn svg {
  width: 12px;
  height: 12px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity .15s;
}

/* Auto-layout: browser distributes width across whichever columns are visible */
.hand-table { table-layout: auto; width: 100%; }
.hand-table colgroup { display: none; }
.hand-table td, .hand-table th { white-space: nowrap; }
.hand-table th:first-child, .hand-table td:first-child { width: 16%; }

@media (max-width: 767px) {
  .hand-table th, .hand-table td { font-size: .88rem; padding: 8px 6px; }
}

/* ── Timezone select ──────────────────────────────────────── */
.tz-select {
  background: var(--panel-alt) !important;
  border: 1px solid var(--border) !important;
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  font-size: .82rem !important;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath fill='%236b8c6b' d='M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right .65rem center !important;
  background-size: 12px !important;
  padding-right: 2rem !important;
}
.tz-select:focus {
  border-color: var(--green) !important;
  box-shadow: 0 0 0 0.15rem rgba(0,230,118,.15) !important;
  outline: none;
}
.tz-select option { background: var(--panel-alt); color: var(--text); }

/* ── Spinner ──────────────────────────────────────────────── */
.spinner-border { color: var(--green) !important; }

/* ── Freemium gates ───────────────────────────────────────── */

/* Tournament table: hide export column in free tier */
.pro-lock-col          { display: none; }
#tournaments-table.tourney-table-free .export-col   { display: none; }
#tournaments-table.tourney-table-free .pro-lock-col { display: table-cell; }

/* Pro-lock cell — yellow dashed border section */
.pro-lock-cell {
  cursor: pointer;
  text-align: center;
  white-space: nowrap;
  color: var(--yellow);
  font-family: var(--font-head);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .4px;
}
.pro-lock-cell:hover { color: var(--yellow); }
.pro-lock-cell svg   { vertical-align: middle; margin-right: 4px; }

/* Pro badge section border for tournament export area */
.pro-gate-section {
  border: 1px dashed var(--yellow);
  border-radius: 8px;
  padding: 8px 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  color: var(--yellow);
  font-family: var(--font-head);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .5px;
  transition: background .15s;
}
.pro-gate-section:hover { background: rgba(204,204,0,.07); }

/* ── Tournament Pro gate (overlay ON TOP of blurred buttons) */
.tourney-gate-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.tourney-gate-blur {
  filter: blur(3px);
  opacity: 0.35;
  pointer-events: none;
  user-select: none;
}

.tourney-gate-overlay {
  position: absolute;
  inset: -4px -6px;          /* slightly wider than the buttons */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
  background: var(--scrim);
  border: 1px dashed rgba(204,204,0,.45);
  border-radius: 8px;
  backdrop-filter: blur(2px);
  padding: 4px 8px;
  z-index: 1;
}

.tourney-gate-label {
  color: var(--yellow);
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .3px;
  white-space: nowrap;
}

.tourney-gate-btn {
  background: rgba(204,204,0,.15);
  border: 1px solid rgba(204,204,0,.55);
  border-radius: 6px;
  color: var(--yellow);
  font-family: var(--font-head);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .4px;
  padding: 3px 9px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s;
}
.tourney-gate-btn:hover { background: rgba(204,204,0,.28); }

/* Export All gate — block-level wrapper (reuses tourney-gate-* internals) */
.export-gate-wrap {
  position: relative;
}

/* Per-hand export counter */
.export-counter {
  font-size: .82rem;
  color: var(--green);
  font-family: var(--font-body);
  text-align: center;
}

.export-counter-limit {
  color: var(--yellow);
}

.btn-link-inline {
  background: none;
  border: none;
  padding: 0;
  color: var(--yellow);
  font-size: inherit;
  font-family: inherit;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.btn-link-inline:hover { opacity: .8; }

/* Generic blurred overlay for future stat gates */
.pro-lock-overlay { position: relative; overflow: hidden; }
.pro-lock-overlay::after {
  content: '';
  position: absolute; inset: 0;
  backdrop-filter: blur(4px);
  background: var(--scrim);
  border-radius: inherit;
  pointer-events: none;
}

/* ── Raw JSON button (legacy) ─────────────────────────────── */
.btn-raw-json {
  background: transparent;
  border: 1px solid var(--green);
  color: var(--green);
  font-family: var(--font-head);
  font-weight: 700;
  border-radius: 7px;
  transition: background .15s, color .15s;
}
.btn-raw-json:hover { background: rgba(0,230,118,.1); color: var(--green); }

/* ── Info badge button (ⓘ in section headers) ────────────── */
.info-badge-btn {
  background: none;
  border: none;
  color: var(--muted);
  font-size: .85rem;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
  opacity: .7;
  transition: opacity .15s, color .15s;
  flex-shrink: 0;
}
.info-badge-btn:hover { opacity: 1; color: var(--green); }

/* ── Header row (auth + connection status left, settings right) ─────
   flex-wrap on both clusters means a narrow viewport wraps controls onto
   their own line instead of shrinking/overlapping them. */
/* The header bar sits a tone above the page background so it reads as its own
   surface rather than floating controls. Shared with .top-bar on the sub-pages
   (see "Shared page top bar" below) so every page's header matches. */
.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 8px 14px;
  /* Keeps clear air under the bar. Don't move this to an inline style on the
     element — `margin:0 auto` there would silently zero it out. */
  margin: 0 auto 12px;
}
.header-row-left,
.header-row-right {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

/* ── Smart selects (Language / Timezone) ─────────────────────
   Native <select> elements dressed up as icon-led pill buttons, matching
   the round "User" button's visual weight in the header. */
.smart-select {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(0,230,118,.06);
  border: 1px solid rgba(0,230,118,.2);
  border-radius: 20px;
  padding: 4px 10px;
  cursor: pointer;
}
.smart-select-icon { color: var(--muted); flex-shrink: 0; }
.smart-select-input {
  background: none;
  border: none;
  color: var(--text);
  font-family: var(--font-body);
  font-size: .78rem;
  padding: 0;
  cursor: pointer;
}
.smart-select-input:focus { outline: none; }
.smart-select-input option { background: var(--panel-alt); color: var(--text); }

/* ── Auth bar ─────────────────────────────────────────────── */
.auth-bar {
  display: flex;
  justify-content: flex-end;
  min-height: 28px;
}

/* Round "User" button + its dropdown menu (replaces the email pill). */
.user-btn {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 2px solid var(--green);
  background: rgba(0,230,118,.1);
  color: var(--green);
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .5px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background .15s, box-shadow .15s;
}
.user-btn:hover { background: rgba(0,230,118,.2); box-shadow: 0 0 10px rgba(0,230,118,.3); }

/* Positioned here rather than by Bootstrap's Popper: /admin and /leaks load
   Bootstrap's CSS but not its JS, and header.js drives the .show class itself
   so the menu behaves identically on every page. */
.user-menu { position: relative; }
.user-dropdown-menu {
  position: absolute;
  top: 100%;
  /* Anchored to the button's left edge by default — on the main page the User
     button sits at the far left of the header, where a right-anchored menu
     opens off the side of the viewport. The sub-page top bars put the button
     on the right instead, and flip this below. */
  left: 0;
  right: auto;
  z-index: 1000;
  display: none;
  margin: 6px 0 0;
  list-style: none;
  min-width: 210px;
  padding: 6px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 8px 28px rgba(0,0,0,.45);
}
.user-dropdown-menu.show { display: block; }
/* Sub-page top bars (/tournaments, /admin, /leaks) end with the User button, so
   the menu hangs off its right edge to stay on screen. */
.top-bar-right .user-dropdown-menu { left: auto; right: 0; }
.user-dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: .84rem;
  text-decoration: none;
  cursor: pointer;
  transition: background .12s;
}
.user-dropdown-item svg { flex-shrink: 0; color: var(--muted); }
.user-dropdown-item:hover { background: rgba(0,230,118,.1); color: var(--text); }
.user-dropdown-item-danger:hover { background: rgba(255,82,82,.12); }
.user-dropdown-item-danger:hover svg { color: var(--red); }

/* Deploy-version row — admin-only, non-interactive, shown below the menu
   items instead of as a hover tooltip so it's visible without guessing
   which item to hover. */
.user-dropdown-version {
  display: block;
  margin-top: 4px;
  padding: 6px 10px 4px;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-family: var(--font-body);
  font-size: .68rem;
  line-height: 1.4;
  white-space: normal;
  cursor: default;
}

.auth-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: rgba(0,230,118,.06);
  border: 1px solid rgba(0,230,118,.2);
  border-radius: 20px;
  padding: 4px 12px 4px 10px;
  font-size: .78rem;
  font-family: var(--font-body);
  color: var(--muted);
  cursor: default;
  text-decoration: none;
}

button.auth-chip { background: none; }

.auth-chip.auth-signin-btn {
  cursor: pointer;
  color: var(--green);
  transition: background .18s, border-color .18s;
}

.auth-chip.auth-signin-btn:hover {
  background: rgba(0,230,118,.14);
  border-color: rgba(0,230,118,.5);
}

.auth-email {
  color: var(--text);
  font-size: .78rem;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.auth-signout-btn {
  background: none;
  border: 1px solid rgba(255,82,82,.35);
  border-radius: 20px;
  padding: 4px 11px;
  margin-left: 6px;
  color: var(--red);
  font-size: .72rem;
  font-family: var(--font-body);
  cursor: pointer;
  line-height: 1;
  transition: background .15s, border-color .15s;
}

.auth-signout-btn:hover {
  background: rgba(255,82,82,.12);
  border-color: var(--red);
}

/* ── My Account modal ─────────────────────────────────────── */
.account-info-list {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 14px;
  margin: 0;
}
.account-info-list dt {
  color: var(--muted);
  font-size: .78rem;
  font-weight: 500;
}
.account-info-list dd {
  margin: 0;
  color: var(--text);
  font-size: .84rem;
  text-align: right;
}

/* ── Shared page top bar ──────────────────────────────────── */
/* Used by /admin and /tournaments so the sub-pages share one identity:
   brand on the left, auth pill on the right, page title below. */
.top-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  /* Same raised tone as the main page's .header-row, so the sub-page headers
     read as the same component. */
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 8px 14px;
  margin-bottom: 16px;
}

.top-bar-brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-head);
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: .4px;
  color: var(--green);
  text-decoration: none;
  white-space: nowrap;
  transition: color .15s;
}

.top-bar-brand:hover { color: var(--green-dim); }

.top-bar-right {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

@media (max-width: 560px) {
  .top-bar-brand { font-size: .88rem; }
  .auth-email { max-width: 130px; }
}

.btn-google-signin {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 10px 16px;
  background: #fff;
  color: #3c4043;
  border: none;
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: .9rem;
  font-weight: 500;
  cursor: pointer;
  transition: background .15s, box-shadow .15s;
  letter-spacing: .01em;
}

.btn-google-signin:hover {
  background: #f1f3f4;
  box-shadow: 0 2px 8px rgba(0,0,0,.25);
}
.btn-google-signin:disabled {
  opacity: .45;
  cursor: not-allowed;
}

.auth-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 16px 0 14px;
  color: var(--muted);
  font-size: .78rem;
  font-family: var(--font-body);
}

.auth-divider::before,
.auth-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

.auth-divider span { flex-shrink: 0; }

/* ── Site footer ──────────────────────────────────────────── */
.site-footer {
  background: var(--panel);
  border-top: 1px solid var(--border);
  margin-top: 40px;
  padding: 20px 24px 20px;
  font-family: var(--font-body);
  color: var(--muted);
  font-size: .8rem;
  line-height: 1.6;
}
.site-footer-inner { max-width: 1400px; margin: 0 auto; }

/* Collapsible legal panel */
.footer-legal { margin-top: 12px; }
.footer-legal-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  list-style: none;
  padding: 8px 0;
  border-top: 1px solid var(--border);
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
  user-select: none;
  transition: color .15s;
}
.footer-legal-toggle::-webkit-details-marker { display: none; }
.footer-legal-toggle:hover { color: var(--text); }
.footer-chevron { font-size: .7rem; transition: transform .2s; }
.footer-legal[open] .footer-chevron { transform: rotate(180deg); }
.footer-legal[open] .footer-legal-toggle { color: var(--text); }

.footer-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
  padding: 20px 0 8px;
}
@media (max-width: 767px) {
  .footer-cols { grid-template-columns: 1fr; gap: 20px; }
}

.footer-heading {
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text);
  margin-bottom: 10px;
}
.footer-col p { margin-bottom: 8px; }
.footer-col p:last-child { margin-bottom: 0; }

.footer-links {
  list-style: none;
  padding: 0;
  margin: 6px 0 10px;
}
.footer-links li { margin-bottom: 4px; }
.footer-links a {
  color: var(--green);
  text-decoration: none;
  opacity: .85;
}
.footer-links a:hover { opacity: 1; text-decoration: underline; }

.footer-bottom {
  border-top: 1px solid var(--border);
  padding-top: 16px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font-size: .75rem;
  color: var(--muted);
}
.footer-sep { opacity: .4; }
.footer-link-btn {
  background: none;
  border: none;
  padding: 0;
  color: var(--green);
  font-family: var(--font-body);
  font-size: .75rem;
  cursor: pointer;
  opacity: .85;
}
.footer-link-btn:hover { opacity: 1; text-decoration: underline; }

/* ── Mobile-first utilities ───────────────────────────────── */
@media (max-width: 575px) {
  .container-fluid { padding-left: 12px !important; padding-right: 12px !important; }
  .section-header { padding: 10px 14px; }
  .table-dark tbody td { padding: 8px 6px; }
  .export-grid-btn { min-height: 58px; font-size: .68rem; }
}

/* .import-input + .btn-import sit in a flex-nowrap row (see index.html).
   Bootstrap's own .flex-nowrap utility ships with !important, so an
   unqualified override here is silently ignored — needs its own
   !important to actually win. The breakpoint has to match .hero-row's
   own column switch (767.98px, above), not the generic 575px mobile
   cutoff: below that width .import-card shares the row with
   #gam-block-right (up to 280px), so it can run out of room for
   input+button well before the page itself looks "mobile" — including
   at desktop-window browser zoom levels, which shrink the effective
   CSS viewport the same way narrowing the window would. */
@media (max-width: 767.98px) {
  .hero-row .import-card .d-flex.flex-nowrap { flex-wrap: wrap !important; }
  .import-input { width: 100%; }
  .btn-import { width: 100%; }
}

/* ── Shared modal chrome ───────────────────────────────────────
   One visual pattern for every modal in the app (colors, typography,
   spacing) — originally built for the 5 read-only "info" modals, now
   applied everywhere so functional modals (export warning, pro upgrade,
   date range, survey, gate stub, auth) share the same look instead of
   each repeating background/border/color inline. Per-modal specifics
   (dialog max-width, modal-fullscreen-sm-down, footer button layout)
   stay as situational Bootstrap utility classes on top of this. */
.app-modal-content {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--text);
}
.app-modal-header {
  background: var(--panel-alt);
  border-bottom: 1px solid var(--border);
  border-radius: 12px 12px 0 0;
  padding: 14px 20px;
}
.app-modal-header .modal-title {
  font-family: var(--font-head);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--text);
}
.app-modal-body {
  padding: 20px 22px;
  font-family: var(--font-body);
  font-size: .9rem;
  line-height: 1.65;
  color: var(--text);
}
.app-modal-footer {
  border-top: 1px solid var(--border);
  padding: .75rem 1rem;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.app-modal-body p { margin-bottom: 12px; }
.app-modal-body p:last-child { margin-bottom: 0; }
.app-modal-body ul, .app-modal-body ol {
  padding-left: 20px;
  margin-bottom: 12px;
}
.app-modal-body li { margin-bottom: 7px; }
.app-modal-body strong { color: var(--text); }
.app-modal-body code {
  background: rgba(0,230,118,.08);
  border: 1px solid rgba(0,230,118,.15);
  border-radius: 4px;
  padding: 1px 6px;
  font-size: .82rem;
  color: var(--green);
  word-break: break-all;
}

/* Gate-stub ad video (import / hand-export unlock modals). The shipped ad
   clips are portrait, so the player is sized by height and centered rather
   than stretched to the modal width — a full-width portrait video would tower
   over the dialog. width/height auto with both max constraints keeps the
   aspect ratio and also fits a landscape upload (capped by width instead). */
.gate-stub-video {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(58vh, 440px);
  background: #000;
}

/* How to Use steps */
.howto-steps {
  padding-left: 0;
  list-style: none;
  counter-reset: step;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.howto-steps li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 12px;
  align-items: start;
}
.howto-steps li::before {
  content: counter(step);
  width: 32px;
  height: 32px;
  background: var(--green);
  color: #000;
  font-family: var(--font-head);
  font-size: .8rem;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  flex-shrink: 0;
  margin-top: 1px;
}
.howto-step-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.howto-step-text strong {
  color: var(--text);
  font-family: var(--font-head);
  font-size: .92rem;
  font-weight: 700;
  letter-spacing: .2px;
}
.howto-step-text span {
  color: var(--muted);
  font-size: .86rem;
  line-height: 1.55;
}
.howto-step-text code {
  margin-top: 4px;
  align-self: flex-start;
}

/* Free vs Pro tier table */
.tier-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: .87rem;
}
.tier-table th {
  font-family: var(--font-head);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--muted);
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}
.tier-table td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
}
.tier-table td:first-child { color: var(--muted); }
.tier-table td:nth-child(3) { color: var(--yellow); font-weight: 600; }
.tier-table tr:last-child td { border-bottom: none; }

.tier-cta {
  display: block;
  width: 100%;
  padding: 13px;
  background: var(--yellow);
  border: none;
  border-radius: 8px;
  color: #000;
  font-family: var(--font-head);
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: .3px;
  cursor: pointer;
  transition: opacity .15s;
}
.tier-cta:hover { opacity: .88; }

/* Release notes */
.release-block {
  border-left: 3px solid var(--border);
  padding: 4px 0 4px 16px;
  margin-bottom: 20px;
  position: relative;
}
.release-block.release-latest { border-left-color: var(--green); }
.release-version {
  font-family: var(--font-head);
  font-size: .88rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: .4px;
  margin-bottom: 6px;
}
.release-tag {
  display: inline-block;
  background: rgba(0,230,118,.12);
  border: 1px solid rgba(0,230,118,.3);
  color: var(--green);
  font-family: var(--font-head);
  font-size: .65rem;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 4px;
  margin-bottom: 8px;
}
.release-block ul { padding-left: 18px; }
.release-block li { margin-bottom: 5px; font-size: .87rem; color: var(--muted); }
.release-block li::marker { color: var(--border); }

/* Roadmap — shares the Release Notes block layout, own class names since
   it's timeframes rather than shipped versions */
.roadmap-block {
  border-left: 3px solid var(--border);
  padding: 4px 0 4px 16px;
  margin-bottom: 20px;
  position: relative;
}
.roadmap-block.roadmap-now { border-left-color: var(--green); }
.roadmap-period {
  font-family: var(--font-head);
  font-size: .88rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: .4px;
  margin-bottom: 6px;
}
.roadmap-block ul { padding-left: 18px; }
.roadmap-block li { margin-bottom: 5px; font-size: .87rem; color: var(--muted); }
.roadmap-block li::marker { color: var(--border); }

/* ── Export toast ───────────────────────────────────────────── */
#export-toast {
  position: fixed;
  bottom: 1.75rem;
  left: 50%;
  transform: translateX(-50%) translateY(10px);
  z-index: 1070;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: .55rem 1rem;
  font-size: .82rem;
  box-shadow: 0 4px 20px rgba(0,0,0,.45);
  opacity: 0;
  transition: opacity .18s ease, transform .18s ease;
  pointer-events: none;
  max-width: 90vw;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#export-toast.et-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}


/* ── Title ────────────────────────────────────────────────────
   Stays alone in its own row above .header-flanked (Task: "Update layout"). */
.header-title-block {
  max-width: 1400px;
  margin: 0 auto 1rem;
}

/* ── Header row (info tiles, centered) ───────────────────────
   Used to be flanked by the two rewards blocks; both moved out (Task:
   "Layout updates") — gam-stats into .header-row next to the User button,
   gam-side down into its own .reward-card above the import section. This
   row is now just the centered tile nav. */
.header-flanked {
  display: flex;
  justify-content: center;
  max-width: 1400px;
  margin: 0 auto 1rem;
  /* Keeps the nowrap tile strip from spilling past the viewport at very
     narrow widths — the tiles then shrink further via .info-tile's clamps. */
  overflow: hidden;
}
.header-flanked-tiles { min-width: 0; max-width: 100%; }

/* ── Gamification ───────────────────────────────────────────── */
/* Points/streak/rank pill, sized to sit next to the round User button in
   .header-row (a smaller, tighter variant of the old .header-flanked card). */
.header-row .gam-stats {
  background: rgba(0,230,118,.07);
  border: 1px solid rgba(0,230,118,.22);
  border-radius: 20px;
  padding: 4px 14px;
  gap: 1.1rem;
}
.gam-stats { display: flex; align-items: center; gap: 1.5rem; }
.gam-stat  { display: flex; flex-direction: column; line-height: 1.15; }
/* Demoted from three glowing green numerals to a quiet, tabular
   readout — the card-medallion shelf is where the reward system
   earns attention, not the header counters. */
.gam-stat-value {
  font-family: var(--font-head);
  font-size: .98rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: .3px;
  font-variant-numeric: tabular-nums;
}
.gam-stat-label {
  font-family: var(--font-head);
  font-size: .58rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .8px;
}
.gam-side {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}
/* Horizontal reward-game card, above the import section (Task: "Layout
   updates") — same panel look as .import-card, but left-aligned since it no
   longer flanks anything. */
.reward-card {
  background: rgba(0,230,118,.07);
  border: 1px solid rgba(0,230,118,.22);
  border-radius: 12px;
  padding: .7rem 1.1rem;
  justify-content: flex-start;
}
.gam-badge {
  font-family: var(--font-head);
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--green);
  background: rgba(0,230,118,.12);
  border: 1px solid rgba(0,230,118,.3);
  border-radius: 20px;
  padding: .16rem .55rem;
  white-space: nowrap;
}
.gam-next, .gam-signin { font-size: .74rem; color: var(--muted); }
.gam-next strong { color: var(--text); font-weight: 600; }

/* Toast — same mechanics as #export-toast, but allowed to wrap onto several lines. */
#gam-toast {
  position: fixed;
  bottom: 1.75rem;
  left: 50%;
  transform: translateX(-50%) translateY(10px);
  z-index: 1075;
  background: var(--panel);
  border: 1px solid rgba(0,230,118,.35);
  border-radius: 10px;
  padding: .7rem 1.1rem;
  font-size: .8rem;
  box-shadow: 0 4px 24px rgba(0,0,0,.5);
  opacity: 0;
  transition: opacity .18s ease, transform .18s ease;
  pointer-events: none;
  max-width: min(92vw, 30rem);
}
#gam-toast.gam-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
.gam-toast-head {
  font-family: var(--font-head);
  font-size: .95rem;
  font-weight: 800;
  color: var(--green);
  letter-spacing: .5px;
  margin-bottom: .3rem;
}
.gam-toast-rows { display: flex; flex-direction: column; gap: .1rem; margin-bottom: .1rem; }
.gam-toast-row  { display: flex; justify-content: space-between; gap: 1.5rem; color: var(--text); }
.gam-toast-row span:last-child { color: var(--green); font-weight: 600; }
.gam-toast-badges {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem;
  margin-top: .45rem;
  padding-top: .45rem;
  border-top: 1px solid var(--border);
}
.gam-toast-unlock {
  font-family: var(--font-head);
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--yellow);
  background: rgba(204,204,0,.1);
  border: 1px solid rgba(204,204,0,.3);
  border-radius: 20px;
  padding: .16rem .55rem;
}

@media (max-width: 575.98px) {
  .gam-stats  { gap: 1.1rem; }
}

/* Top banner (.header-row): never wraps onto a second line and never grows
   taller as the viewport narrows. */
@media (max-width: 767.98px) {
  .header-row,
  .header-row-left,
  .header-row-right { flex-wrap: nowrap; }
  .header-row .gam-stats { gap: .6rem; padding: 4px 10px; }
}
/* Below phone width there isn't room for the row to stay on one line with
   labels attached, so below that the points/streak/rank labels ("Points",
   "Day Streak", "Weekly Rank") are dropped entirely — the numbers alone
   give the row enough room to stay on one line without shrinking the round
   User button or the language/timezone controls. Wider portrait screens
   (tablets) keep the labels. */
@media (max-width: 599.98px) {
  .gam-stat-label { display: none; }
}


/* ── Tournament Summary drill-down ───────────────────────────── */

/* The Seats/Avg Hands/Avg Duration/Hands-per-hr stat columns used to hide
   behind Bootstrap breakpoints as the viewport narrowed. Now they always
   render, and .table-responsive's built-in horizontal scroll (inherited
   from Bootstrap) takes over instead — nowrap keeps the header/cell text
   from wrapping first, which would just make the table taller instead of
   wider, defeating the scroll. */
#tournament-summary-section table th,
#tournament-summary-section table td,
#cash-games-summary-section table th,
#cash-games-summary-section table td {
  white-space: nowrap;
}

.tsum-summary-row {
  cursor: pointer;
}

/* Temporary highlight for rows/cards touched by the most recent import */
@keyframes rowFlash {
  0%   { background-color: rgba(0,230,118,.3); }
  100% { background-color: transparent; }
}
tr.row-flash > td {
  animation: rowFlash 60s ease-out forwards;
}

@keyframes cardFlash {
  0%   { background-color: rgba(0,230,118,.2); border-color: rgba(0,230,118,.7); }
  100% { background-color: var(--panel-alt);   border-color: var(--border); }
}
.tsum-event-card.card-flash {
  animation: cardFlash 60s ease-out forwards;
}

.tsum-chevron {
  display: inline-block;
  vertical-align: -1px;
  margin-right: 6px;
  color: var(--green);
  transition: transform .2s ease;
}
.tsum-chevron-open {
  transform: rotate(90deg);
}

.tsum-detail-row > td {
  background: transparent !important;
  padding: 0 !important;
  border: none !important;
}

.tsum-detail-wrap {
  max-height: 0;
  overflow: hidden;
  transition: max-height .35s ease;
  background: rgba(0,0,0,.18);
}
.tsum-detail-wrap.tsum-detail-open {
  max-height: 2000px;
}

.tsum-event-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
  padding: 14px 18px;
  align-items: stretch;
}

.tsum-event-card {
  display: flex;
  flex-direction: column;
  max-width: 320px;
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 14px 12px;
  cursor: pointer;
  transition: transform .15s ease, border-color .15s ease;
  container-type: inline-size;
  container-name: tsumcard;
}
.tsum-event-card:hover {
  transform: translateY(-2px);
  border-color: var(--green);
}
.tsum-event-card.selected {
  border-color: var(--green);
  background: rgba(0,230,118,.10);
  box-shadow: 0 0 0 1px var(--green) inset;
}

/* Signed-out Tournament History rows are the way into each tournament's graph,
   so they need to read as clickable — the signed-in view uses cards for this. */
.anon-tourney-row { cursor: pointer; }
.anon-tourney-row:hover > td { background: rgba(0,230,118,.06); }
.anon-tourney-row:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: -2px;
}
.anon-tourney-row.selected > td {
  background: rgba(0,230,118,.12);
  box-shadow: inset 0 -1px 0 var(--green), inset 0 1px 0 var(--green);
}

.tsum-event-stats {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  margin-bottom: 10px;
}

.tsum-stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  flex: 1 1 0;
  min-width: 0;
}
.tsum-stat-stacked {
  min-width: 0;
  padding: 4px 3px;
}
.tsum-stat-icon {
  width: 12px;
  height: 12px;
  opacity: .6;
  flex-shrink: 0;
  color: var(--blue);
}
.tsum-stat-full,
.tsum-stat-short {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.tsum-stat-short { display: none; }
@container tsumcard (max-width: 265px) {
  .tsum-stat-full  { display: none; }
  .tsum-stat-short { display: inline; }
}

.tsum-event-actions {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.tsum-event-actions .export-icon-btn {
  flex: 1 1 0;
  min-width: 0;
  width: auto;
  height: 32px;
}

/* Tournament Details: brief highlight when a tournament is loaded into it */
@keyframes tdFlash {
  0%   { background-color: rgba(0,230,118,.18); }
  100% { background-color: transparent; }
}
.section-card.td-flash {
  animation: tdFlash 1.6s ease-out;
}

.tsum-event-top {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  justify-content: space-between;
  gap: 6px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.tsum-event-top > * {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tsum-event-date {
  font-family: var(--font-head);
  letter-spacing: .03em;
  font-size: .8rem;
  white-space: nowrap;
}
.tsum-stat-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .68rem;
  padding: 2px 9px;
  border-radius: 12px;
  font-family: var(--font-head);
  letter-spacing: .02em;
  white-space: nowrap;
  background: rgba(64,196,255,.1);
  border: 1px solid rgba(64,196,255,.3);
  color: var(--blue);
}
.tsum-event-top .tsum-stat-pill {
  background: rgba(0,230,118,.08);
  border: 1px solid rgba(0,230,118,.4);
  color: var(--green);
}
/* ── TS / CGS filter bar ──────────────────────────────────────── */
/* ── Inline filter pills (TS / CGS section headers) ─────────────────────── */
.ts-filter-pills {
  display: flex;
  align-items: center;
  gap: 4px;
}
.ts-filter-prefix {
  font-family: var(--font-body);
  font-size: .7rem;
  color: var(--muted);
  white-space: nowrap;
  margin-right: 2px;
}
.ts-filter-select {
  background: var(--panel-alt);
  border: 1px solid rgba(0,230,118,.3);
  border-radius: 20px;
  color: var(--green);
  font-family: var(--font-body);
  font-size: .7rem;
  font-weight: 600;
  padding: 2px 10px 2px 9px;
  line-height: 1.6;
  cursor: pointer;
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%2300e676'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  padding-right: 22px;
  transition: border-color .15s, box-shadow .15s;
}
.ts-filter-select:hover {
  border-color: rgba(0,230,118,.55);
  box-shadow: 0 0 6px rgba(0,230,118,.15);
}
.ts-filter-select option {
  background: var(--panel);
  color: var(--fg);
}
/* Tournament Summary / Cash & Play Money Games section headers: the title
   cluster (icon + h2 + count pills) is what gives way as the header
   narrows, since the Interval filter is the control someone's actually
   trying to reach — never wrapped off past this row, never squeezed off
   past the edge. h2 already ellipsizes (.section-header h2 above); it just
   needs room to actually shrink into, which flex-shrink-0 on this wrapper
   was blocking before it lost that class. */
.ts-summary-header { flex-wrap: nowrap; }
.ts-summary-title { min-width: 0; overflow: hidden; flex-shrink: 1; }
@media (max-width: 767.98px) {
  .ts-summary-pills { display: none; }
}
.ts-filter-active-label {
  font-family: var(--font-head);
  font-size: .6rem;
  color: var(--green);
  letter-spacing: .03em;
  padding-left: 2px;
}

/* ── Sortable column headers ──────────────────────────────────── */
.sort-th {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: background .15s, color .15s;
}
.sort-th:hover {
  color: var(--green);
  background: rgba(0,230,118,.08);
  outline: 1px solid rgba(0,230,118,.2);
  outline-offset: -1px;
}
.sort-icon { font-size: .7em; color: var(--green); }

/* ── Export All Hands section ─────────────────────────────────── */
.player-export-all-btns .export-btn-grid {
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

/* ── Tournament Progress Graph ─────────────────────────────────── */
.tourney-graph-wrap {
  border-bottom: 1px solid var(--border);
  padding: 14px 18px 16px;
  background: rgba(0,0,0,.12);
}

.tourney-graph-warning {
  border-bottom: 1px solid var(--border);
  padding: 12px 18px;
  background: rgba(255, 193, 7, .08);
  color: var(--yellow);
  font-family: var(--font-body);
  font-size: .86rem;
}

.tourney-graph-title {
  font-family: var(--font-head);
  letter-spacing: .03em;
  font-size: .95rem;
  color: var(--green);
  text-align: center;
  flex: 1 1 auto;
}

.tourney-graph-controls {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.tg-controls-right {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  margin-left: auto;
}

@media (max-width: 767px) {
  .tourney-graph-title { flex-basis: 100%; order: 2; margin: 4px 0; }
  .tg-controls-right { order: 3; }
}

.tg-group-xaxis {
  margin-left: auto;
}

.tg-played-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-body);
  font-size: .75rem;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
.tg-played-label input[type="checkbox"] {
  accent-color: var(--green);
  width: 13px;
  height: 13px;
  cursor: pointer;
}
.tg-played-label:hover { color: var(--text); }

.tg-group {
  display: flex;
  align-items: center;
  gap: 4px;
}

.tg-label {
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .05em;
  margin-right: 4px;
  white-space: nowrap;
}

.tg-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 5px;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: .75rem;
  font-weight: 500;
  padding: 3px 9px;
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s;
  line-height: 1.4;
}
.tg-btn:hover {
  color: var(--text);
  border-color: var(--green-dim);
}
.tg-btn.active {
  background: rgba(0,230,118,.12);
  border-color: var(--green);
  color: var(--green);
  font-weight: 600;
}

.tg-pill {
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 700;
  border-radius: 20px;
  padding: 2px 10px;
  letter-spacing: .4px;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  background: var(--overlay-lo);
  color: var(--muted);
  border: 1px solid var(--overlay-hi);
  transition: opacity .15s, background .15s;
}
.tg-pill.active {
  background: rgba(0,230,118,.15);
  color: var(--green);
  border-color: rgba(0,230,118,.5);
}
.tg-pill:not(.active) { opacity: .4; }

/* PH Only + Chips pills share the graph's Chips-line blue instead of green. */
.tg-pill-blue.active {
  background: rgba(64,196,255,.15);
  color: var(--blue);
  border-color: rgba(64,196,255,.5);
}

.tourney-graph-canvas-wrap {
  position: relative;
  height: 260px;
}

@media (min-width: 768px) {
  .tourney-graph-canvas-wrap { height: 310px; }
}
@media (max-width: 575px) {
  .tourney-graph-wrap { padding: 10px 12px 14px; }
  .tourney-graph-canvas-wrap { height: 220px; }
  .tg-btn { font-size: .7rem; padding: 2px 7px; }
}

/* ── Graph legend ──────────────────────────────────────────────── */
.tg-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 14px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
  font-family: var(--font-body);
  font-size: .7rem;
  color: var(--muted);
}
/* Inside the Legend modal there's nothing above it to separate from. */
.tg-legend.tg-legend-modal {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
  font-size: .8rem;
  gap: 10px 16px;
}
.tg-lg {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.tg-lg-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.tg-lg-dot.won  { background: var(--win); }
.tg-lg-dot.lost { background: var(--loss); }
.tg-lg-dot.sd   { width: 11px; height: 11px; background: var(--muted); }
.tg-lg-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px; height: 15px;
  flex: 0 0 auto;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-style: normal;
  font-size: .55rem;
  font-weight: 700;
  line-height: 1;
}
.tg-lg-line {
  width: 12px;
  flex: 0 0 auto;
  border-top: 1px dashed var(--muted);
}
.tg-lg-note { color: var(--muted); font-style: italic; }

@media (max-width: 575px) {
  .tg-legend { gap: 4px 10px; font-size: .66rem; }
}

/* ── Graph hand card (hover preview / pinned) ──────────────────── */
/* Replaces the canvas tooltip: real DOM, so it can hold the replay link.
   Ignores the pointer while it trails the cursor; takes it once pinned. */
.tg-hand-card {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 5;
  display: none;
  /* Fixed, not min/max: the card is repositioned on every mousemove, and a
     width that tracked its contents would make it twitch as you scrub. */
  width: 184px;
  padding: 7px 8px 7px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
  box-shadow: 0 4px 18px rgba(0,0,0,.55);
  font-family: var(--font-body);
  font-size: .74rem;
  color: var(--text);
  pointer-events: none;
}
.tg-hand-card.show   { display: block; }
.tg-hand-card.pinned {
  pointer-events: auto;
  border-color: rgba(0,230,118,.55);
  box-shadow: 0 4px 18px rgba(0,0,0,.55), 0 0 0 1px rgba(0,230,118,.12);
}

/* Top-right identifier pill (Hand # · L#) — floats over the card so the badges
   below stay visually centred. */
.tg-card-head-pill {
  position: absolute;
  top: 5px;
  right: 6px;
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(0,230,118,.10);
  border: 1px solid rgba(0,230,118,.28);
  line-height: 1.2;
}
.tg-card-hand {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: .68rem;
  color: var(--green);
  letter-spacing: .02em;
}
.tg-card-meta { color: var(--muted); font-size: .62rem; }
.tg-card-close {
  position: absolute;
  top: 4px;
  left: 6px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: .76rem;
  line-height: 1;
  cursor: pointer;
}
.tg-card-close:hover { color: var(--text); }

.tg-card-badges {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin: 4px 0 6px;
}
/* Position pill sits beside the centred hole-cards. */
.tg-card-badges .pos-badge {
  min-width: 3.4rem;
  font-size: .68rem;
}
.tg-card-badges .playing-card:last-of-type { margin-right: 0; }
.tg-card-dim { color: var(--muted); }

/* Three equal columns rather than a flex row that bunches to the left — the
   card is a fixed width, so the stats may as well use all of it. */
.tg-card-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  font-size: .7rem;
}
.tg-card-stats span { white-space: nowrap; }
.tg-card-stats span + span  { text-align: center; }
.tg-card-stats span:last-child { text-align: right; }
.tg-card-stats i {
  display: block;
  font-style: normal;
  font-size: .58rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
}

.tg-card-hint {
  margin-top: 7px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  font-size: .68rem;
  color: var(--muted);
}

.tg-card-actions {
  display: flex;
  gap: 6px;
  margin-top: 7px;
  padding-top: 7px;
  border-top: 1px solid var(--border);
}
.tg-card-btn {
  flex: 1 1 0;
  padding: 4px 8px;
  border: 1px solid rgba(0,230,118,.45);
  border-radius: 6px;
  background: rgba(0,230,118,.08);
  color: var(--green);
  font-family: var(--font-head);
  font-size: .72rem;
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background .15s, border-color .15s, box-shadow .15s;
}
.tg-card-btn:hover {
  background: rgba(0,230,118,.22);
  border-color: var(--green);
  box-shadow: 0 0 10px rgba(0,230,118,.3);
  color: var(--green);
}
.tg-card-btn.is-disabled {
  border-color: var(--border);
  background: transparent;
  color: var(--muted);
  cursor: default;
  box-shadow: none;
}

/* Brief highlight when the card jumps to a hand's row. Deliberately not
   `row-flash` — that one is the 60s "just imported" highlight. */
@keyframes handJumpFlash {
  0%   { background-color: rgba(0,230,118,.28); }
  100% { background-color: transparent; }
}
tr.hand-jump-flash > td {
  animation: handJumpFlash 1.6s ease-out forwards;
}

/* ══════════════════════════════════════════════════════════════════
   MAIN-PAGE REDESIGN
   Empty state, card-medallion badge system, table refinements, the
   deal-in reveal, and the theme toggle. Appended last so these win
   over the base component rules above at equal specificity.
   ══════════════════════════════════════════════════════════════════ */

/* ── Theme toggle (sun/moon) ────────────────────────────────────
   One button, no JS to keep the icon in sync: the current
   data-theme decides which glyph shows. It reads as "tap for the
   other mode" — a sun while you're in the dark, a moon while you're
   in daylight. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: var(--overlay-lo);
  border: 1px solid var(--border);
  color: var(--muted);
  cursor: pointer;
  transition: color .15s, background .15s, border-color .15s;
}
.theme-toggle:hover {
  color: var(--green);
  border-color: rgba(0,230,118,.45);
  background: var(--overlay-mid);
}
.theme-toggle:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
}
.theme-toggle svg { width: 16px; height: 16px; }
.theme-toggle .icon-moon { display: none; }
.theme-toggle .icon-sun  { display: block; }
[data-theme="light"] .theme-toggle .icon-sun  { display: none; }
[data-theme="light"] .theme-toggle .icon-moon { display: block; }

/* ── Empty state — the invitation under the hero import ──────────
   A quiet, poker-voice three-beat of what actually happens, in the
   real order it happens. Not a boxed "how it works" marketing strip;
   it disappears (#empty-hint gets .d-none in app.js) the moment
   there's a session on screen. */
.empty-hint {
  max-width: 1400px;
  margin: 16px auto 0;
  padding: 2px 4px;
}
.deal-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.deal-step {
  display: flex;
  align-items: baseline;
  gap: 11px;
  color: var(--muted);
  font-size: .9rem;
  line-height: 1.4;
}
.deal-step .chev {
  color: var(--green);
  font-family: var(--font-head);
  font-weight: 700;
  flex: 0 0 auto;
}
.deal-step b { color: var(--text); font-weight: 600; }

/* ── The Grind — one medal, and the door to the ladder ──────────
   The signature. Each badge is drawn as the actual poker hand its code
   names (7-2 offsuit, Big Slick, pocket aces, a made-hand fan), so the
   reward system speaks the subject's own language instead of trophies
   and stars. The card shows only the newest unlock — one medal, lit —
   plus the running count and the next milestone; the whole card is the
   button that opens the full ladder. */
.reward-card.gam-side {
  display: grid;
  gap: .5rem .85rem;
  /* Column layout for the narrow desktop slot: title row, medal, next —
     left-aligned. The middle row is 1fr so it claims whatever height the
     card has beyond its head/next rows, and the medal (a grid item, which
     stretches to fill its area by default) centers within that — so the
     medal stays vertically centered as the card's height changes, without
     the card itself ever needing to change height on its own. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "head" "hero" "next";
  /* Button reset — the card is a real <button> so click and keyboard both
     open the ladder without a JS handler. */
  width: 100%;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.reward-card.gam-side:hover {
  border-color: rgba(0,230,118,.45);
  box-shadow: 0 0 18px rgba(0,230,118,.14);
}
.reward-card.gam-side:active { transform: translateY(1px); }
.reward-card.gam-side:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
}
.grind-head {
  grid-area: head;
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  min-width: 0;
}
.grind-title {
  font-family: var(--font-head);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--green);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
}
.grind-title svg { width: 19px; height: 19px; opacity: .9; flex-shrink: 0; }
/* The card is narrower than "Your Medals" wants on one line at some sizes —
   hidden (ellipsis) rather than wrapped, so the card's height never moves. */
.grind-title-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Medals earned out of the ladder's total — the card's one number. */
.grind-count {
  flex: 0 0 auto;
  font-family: var(--font-head);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The medal(s) on show. With only a single piece of art in the card it can
   afford to be lit properly — a soft green halo behind it, brighter on
   hover, instead of sitting flat in a row of siblings. #gam-hero is the
   viewport (its width is what _renderHeroFrame measures against); the
   track inside is what actually swaps/slides. */
.grind-hero {
  grid-area: hero;
  display: flex;
  align-items: center;
  min-width: 0;
  overflow: hidden;
}
.grind-hero.is-empty { display: none; }
.grind-hero-track {
  display: flex;
  align-items: center;
  gap: .7rem;
  min-width: 0;
  transition: opacity .2s, transform .2s;
}
/* One chip: let it shrink and ellipsize like any other flex content — the
   card's height must never move for a long name, so hidden beats wrapped.
   Two chips (portrait only, added by _renderHeroFrame/_isPortraitHeroLayout
   once they're measured to fit): natural width instead, so a name already
   confirmed to fit is shown in full rather than getting shrunk anyway. */
.medal-chip { display: flex; align-items: center; gap: .55rem; min-width: 0; flex: 1 1 auto; }
.grind-hero-track.has-two-chips .medal-chip { flex: 0 0 auto; }
.grind-hero-art {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
}
.grind-hero-art::before {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(0,230,118,.32), rgba(0,230,118,0) 68%);
  transition: opacity .2s;
}
.grind-hero-art img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 0 6px rgba(0,230,118,.35));
}
.reward-card.gam-side:hover .grind-hero-art::before { opacity: .75; }
/* Hidden (ellipsis) rather than wrapped — see .medal-chip above for why a
   two-chip row is exempt. */
.grind-hero-title {
  font-family: var(--font-head);
  font-size: .92rem;
  font-weight: 700;
  letter-spacing: .4px;
  line-height: 1.2;
  color: var(--text);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Cross-fade (desktop) while _startHeroCycle swaps the track's contents. */
.grind-hero-track.is-swapping { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .grind-hero-track { transition: none; }
  .grind-hero-track.is-swapping { opacity: 1; }
}
/* Hidden (ellipsis) rather than wrapped, like the title/medal name above —
   a long "N hands to next level" must not grow the card's height. */
.gam-next {
  grid-area: next;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Portrait/mobile: the card is a full-width block, so the same three
   pieces re-lay as one horizontal row — the card header on the LEFT, the
   medal(s) left-aligned right next to it, the next-level countdown on the
   right — instead of a tall stack. */
@media (max-width: 767.98px) {
  .reward-card.gam-side {
    /* header | medal (grows, but content stays left-aligned within it) |
       counter — the counter's column is held to what its longest line
       naturally wants so it doesn't wrap word by word. */
    grid-template-columns: auto minmax(0, 1fr) max-content;
    grid-template-rows: auto;
    grid-template-areas: "head hero next";
    align-items: center;
    text-align: left;
    justify-items: stretch;
    gap: .3rem .45rem;
    padding: .5rem .55rem;
  }
  .reward-card.gam-side .grind-title svg { display: none; }
  .reward-card.gam-side .grind-hero-art { width: 38px; height: 38px; }
  .reward-card.gam-side .grind-hero-track { gap: .4rem; }
  .reward-card.gam-side .grind-hero-title { font-size: .8rem; }
  .reward-card.gam-side .grind-head { justify-self: start; min-width: 0; }
  /* Let the title scale down before it clips — never cut a letter off "MEDALS". */
  .reward-card.gam-side .grind-title { font-size: clamp(.66rem, 3.2vw, 1.05rem); }
  /* Stays justify-self: stretch (the grid default) so the box is held to
     the "hero" track's actual width and can't spill into the counter
     column next to it — .grind-hero's own flex default (justify-content:
     flex-start) is what left-aligns the medal(s) within that box, near
     the header, instead of floating centered in the leftover width. */
  .reward-card.gam-side .gam-next   {
    justify-self: end;
    text-align: right;
    font-size: .66rem;
    line-height: 1.25;
    white-space: nowrap;
  }
  /* No count chip beside the title in portrait — the ladder modal shows it. */
  .grind-count { display: none; }
  /* Slide, not fade, for the portrait reel — a horizontal nudge reads as
     "the next medal is arriving from the side" rather than a plain cross-fade. */
  .reward-card.gam-side .grind-hero-track.is-swapping { transform: translateX(14px); }
}
@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {
  .reward-card.gam-side .grind-hero-track.is-swapping { transform: none; }
}
/* Phone widths only: clip "N hands to next level" to an ellipsis so the
   row's height stays fixed instead of squeezing the medal art. Wider
   portrait screens (tablets) have room to show it in full. */
@media (max-width: 599.98px) {
  .reward-card.gam-side .gam-next {
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 7ch;
  }
}

/* The medal's name used to print underneath it as a caption; it now lives
   in a "ghost helper" tooltip instead (see .ghost-host below), so the
   unlock toast is just a row of art. */
.medal {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  cursor: default;
}
.medal-art { width: 40px; height: 40px; object-fit: contain; }

/* ── Ghost helpers — Bootstrap tooltips on the medal shelf ────────────
   `.ghost-host` just marks the trigger; the actual popup is Bootstrap's
   own `.tooltip`, initialised with trigger:'hover focus' (app.js) so it
   opens on mouse hover on desktop and on tap-to-focus on touch, matching
   the info ⓘ buttons elsewhere on the page. Focus outline is suppressed
   here since the tooltip itself is the visible affordance. */
.ghost-host { outline: none; }
.ghost-host:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

.gam-next strong { font-variant-numeric: tabular-nums; }

/* ── The ladder modal ───────────────────────────────────────────
   Every rung of the reward game: what's still to climb on top, dimmed,
   and what's already unlocked below it, lit — so the eye lands on the
   boundary between the two. Kept to a square in landscape (never wider
   than it is tall) so it reads as a panel rather than a page. */
.ladder-dialog { max-width: min(94vw, 620px); }
@media (orientation: landscape) {
  .ladder-dialog { max-width: min(94vw, 88vh, 620px); }
}
.ladder-body { padding-top: .5rem; }
.ladder-scroll {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  max-height: min(62vh, 460px);
  overflow-y: auto;
  padding-right: .25rem;
}
.ladder-count {
  font-size: .8rem;
  font-weight: 700;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-left: .5rem;
}
.ladder-group-title {
  font-family: var(--font-head);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 .55rem;
  padding-bottom: .3rem;
  border-bottom: 1px solid var(--border);
}
.ladder-group-title.is-earned { color: var(--green); border-bottom-color: rgba(0,230,118,.3); }
.ladder-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: .55rem;
}
.ladder-empty { margin: .2rem 0 0; font-size: .78rem; color: var(--muted); }

.rung {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .2rem;
  padding: .6rem .4rem .5rem;
  border: 1px solid rgba(0,230,118,.22);
  border-radius: 10px;
  background: rgba(0,230,118,.06);
  text-align: center;
  cursor: help;
}
.rung-art { width: 42px; height: 42px; object-fit: contain; }
.rung-title {
  font-family: var(--font-head);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .3px;
  color: var(--text);
  line-height: 1.2;
}
.rung-name { font-size: .66rem; color: var(--muted); line-height: 1.2; }
/* Still to climb — present but plainly out of reach. */
.rung.is-locked {
  border-color: var(--border);
  background: var(--overlay-lo);
}
.rung.is-locked .rung-art { filter: grayscale(1); opacity: .38; }
.rung.is-locked .rung-title { color: var(--muted); }
.rung.is-locked .rung-name { opacity: .7; }
.rung.is-locked:hover .rung-art { opacity: .6; }

/* ── Table refinements ──────────────────────────────────────────
   Grinders scan numeric columns; tabular figures keep them from
   dancing as values change. Net P/L reads in win/loss colour. */
.table td, .table th { font-variant-numeric: tabular-nums; }
.net-pos { color: var(--win) !important; font-weight: 600; }
.net-neg { color: var(--loss) !important; font-weight: 600; }

/* Slightly lifted summary rows so the volume tables read as a scan
   surface rather than a wall of dark stripes. */
#tourney-summary-tbody tr,
#cgs-summary-tbody tr { transition: background .12s; }

/* ── Deal-in reveal ─────────────────────────────────────────────
   When an import lands, the results sections fan onto the table in
   sequence like dealt streets. Staggered by source order; fully off
   under reduced-motion. */
@keyframes dealIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: no-preference) {
  #results-section:not(.d-none) > .player-badge,
  #results-section:not(.d-none) > .section-card {
    animation: dealIn .42s cubic-bezier(.2,.7,.3,1) both;
  }
  #results-section:not(.d-none) > *:nth-of-type(1) { animation-delay: .00s; }
  #results-section:not(.d-none) > *:nth-of-type(2) { animation-delay: .06s; }
  #results-section:not(.d-none) > *:nth-of-type(3) { animation-delay: .12s; }
  #results-section:not(.d-none) > *:nth-of-type(4) { animation-delay: .18s; }
  #results-section:not(.d-none) > *:nth-of-type(5) { animation-delay: .24s; }
  #results-section:not(.d-none) > *:nth-of-type(6) { animation-delay: .30s; }
}
