:root {
  --bg: #0b0c0e;
  --panel: #14161a;
  --grid: #2a2e36;
  --text: #f2f0ea;
  --muted: #c8c6c0;
  --dim: #8a8882;
  --accent: #9fd4ee;
  --easy: #6a8f6a;
  --mid: #8a8a6a;
  --hard: #8a6a6a;
  --border: #2a2e36;
  --row-border: #1e222a;
  --shadow: rgba(0, 0, 0, 0.45);
  --cta-bg: rgba(20, 22, 26, 0.72);
  --cta-border: rgba(159, 212, 238, 0.35);
  --cta-shadow: rgba(0, 0, 0, 0.35);
  --btn-text: #0b0c0e;
  --ok: #8ef0b0;
  --warn: #ffd166;
  --err: #ff7a7a;
  --input-bg: #0f1114;
  --input-hover: #1e2230;
  --chip-bg: #0f1114;
  --chip-border: #2e3644;
  --chip-hover: #1a2030;
  --chip-active-bg: #1e2a3a;
  --ctrl-btn-bg: #1e2430;
  --ctrl-btn-border: #3a4250;
  --ctrl-btn-hover: #2a3344;
  --ctrl-btn-muted-bg: #16191f;
  --ctrl-btn-muted-hover: #1e2230;
  --spinner-track: #2a2e36;
  --token-ok-bg: rgba(142, 240, 176, 0.14);
  --token-ok-fg: #8ef0b0;
  --token-ok-bd: rgba(142, 240, 176, 0.55);
  --token-warn-bg: rgba(255, 209, 102, 0.1);
  --token-warn-fg: #ffd166;
  --token-warn-bd: rgba(255, 209, 102, 0.45);
  --token-fail-bg: rgba(255, 122, 122, 0.12);
  --token-fail-fg: #ff9a9a;
  --token-fail-bd: rgba(255, 122, 122, 0.6);
  --skip-bg: rgba(255, 209, 102, 0.08);
  --skip-bd: rgba(255, 209, 102, 0.45);
}

/* Creamy haze light theme (~15% warm cream, not pure white) */
html[data-theme="light"] {
  --bg: #f0ebe3;          /* soft cream page */
  --panel: #e8e1d4;       /* warmer panel haze */
  --grid: #d0c8ba;
  --text: #1c1914;
  --muted: #4a453c;
  --dim: #6e675c;
  --accent: #2f6f8f;      /* deeper accent for contrast on cream */
  --easy: #5a7a5a;
  --mid: #7a7a55;
  --hard: #7a5555;
  --border: #c9bfb0;
  --row-border: #d8d0c4;
  --shadow: rgba(60, 45, 20, 0.18);
  --cta-bg: rgba(240, 235, 227, 0.82);
  --cta-border: rgba(47, 111, 143, 0.35);
  --cta-shadow: rgba(60, 45, 20, 0.18);
  --btn-text: #f0ebe3;
  --ok: #1a7a45;
  --warn: #9a6a00;
  --err: #b03030;
  --input-bg: #f7f3eb;    /* creamy input, not dark */
  --input-hover: #ebe4d6;
  --chip-bg: #f7f3eb;
  --chip-border: #c9bfb0;
  --chip-hover: #ebe4d6;
  --chip-active-bg: #e0d6c6;
  --ctrl-btn-bg: #f7f3eb;
  --ctrl-btn-border: #c9bfb0;
  --ctrl-btn-hover: #ebe4d6;
  --ctrl-btn-muted-bg: #efe8dc;
  --ctrl-btn-muted-hover: #e4dccf;
  --spinner-track: #d0c8ba;
  --token-ok-bg: rgba(26, 122, 69, 0.12);
  --token-ok-fg: #1a7a45;
  --token-ok-bd: rgba(26, 122, 69, 0.4);
  --token-warn-bg: rgba(154, 106, 0, 0.12);
  --token-warn-fg: #9a6a00;
  --token-warn-bd: rgba(154, 106, 0, 0.4);
  --token-fail-bg: rgba(176, 48, 48, 0.08);
  --token-fail-fg: #a03030;
  --token-fail-bd: rgba(176, 48, 48, 0.5);
  --skip-bg: rgba(154, 106, 0, 0.08);
  --skip-bd: rgba(154, 106, 0, 0.4);
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  min-height: 100%;
  overflow-x: hidden;
  /* clip (not hidden) so body isn't a scroll container — position: sticky
     (shared-cache alphabet bar) then sticks to the viewport. */
  overflow-x: clip;
}

body {
  padding: 1rem 1.25rem 2rem;
  max-width: none;
  width: 100%;
  margin: 0;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

header,
header.top-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem 1rem;
  margin-bottom: 0.75rem;
}

.controls-theme-row {
  flex: 1 1 100%;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.15rem;
}

.wipe-local {
  margin-left: 0;
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  padding: 0.3rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--ctrl-btn-bg);
  color: var(--text);
  cursor: pointer;
}
.wipe-local:hover {
  border-color: #e07070;
  color: #e07070;
  background: var(--ctrl-btn-hover);
}
.controls button.wipe-local {
  background: var(--ctrl-btn-bg);
  color: var(--text);
  border: 1px solid var(--border);
  font-weight: 600;
  font-size: 1rem;
  padding: 0.3rem 0.55rem;
  min-height: auto;
  box-shadow: none;
}
.controls button.wipe-local:hover {
  background: var(--ctrl-btn-hover);
  border-color: #e07070;
  color: #e07070;
}

/* 🏆 Rankings (index.html) / 🔍 back to player search (ranks.html): icon-only
   links, same pill as 🗑️. On index the 🏆 is pinned to the left end of its row. */
.controls .ranks-link { margin-right: auto; }
.controls .ranks-link,
.icon-nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  padding: 0.3rem 0.55rem;
  border-radius: 6px; /* same as the 🗑️ button (.controls button) */
  border: 1px solid var(--border);
  background: var(--ctrl-btn-bg);
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.controls .ranks-link:hover,
.controls .ranks-link:focus-visible,
.icon-nav-btn:hover,
.icon-nav-btn:focus-visible {
  background: var(--ctrl-btn-hover);
  border-color: var(--accent);
}
.controls .ranks-link:focus-visible,
.icon-nav-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* t303u: on index the 🏆 Rankings link is a full-size button, same height /
   padding / font as 🔍 Analyze (but neutral colours, it's navigation). */
.controls a.ranks-link#ranksLink {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  padding: 0 1.2rem;
  height: var(--ctl-h);
  white-space: nowrap;
}

/* t312u: desktop puts 🔍 Analyze (+ 🔗) left-aligned on its own line directly
   under the names field (names box takes the full row). Phones unchanged. */
@media (min-width: 601px) {
  .controls .names-box { flex: 1 1 100%; }
}

/* index: spacer | 🏆 Rankings | 🗑️ ☀️. Mobile: 🏆 pinned left (spacer hidden).
   t344u: desktop puts [🏆 Rankings][›] at the left, same left edge as
   [🔍 Analyze][🔗] above it (was centred, t304u). */
.ranks-row .ranks-row-spacer { display: none; }
.ranks-row .ranks-row-end { display: inline-flex; align-items: center; gap: 0.4rem; }
@media (min-width: 601px) {
  .controls-theme-row.ranks-row { justify-content: flex-start; }
  .controls .ranks-row .ranks-link { margin: 0; }
  .ranks-row .ranks-row-end { display: none; }
}

/* t341u: 🗑️ and ☀️ Light sit on the 📦 Shared cache line, right-aligned, as
   tall as 🔍 Analyze; the closed shared-cache box is that tall too. */
.cache-row {
  flex: 1 1 100%;
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  min-width: 0;
}
.cache-row .cache-chips { flex: 1 1 0; min-width: 0; }
.cache-row-end {
  flex: 0 0 auto;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.cache-row .cache-shared > summary {
  line-height: calc(var(--ctl-h) - 0.75rem - 2px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.controls .cache-row-end button.wipe-local,
.controls .cache-row-end button.theme-toggle {
  box-sizing: border-box;
  height: var(--ctl-h);
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.controls .cache-row-end button.wipe-local { width: var(--ctl-h); padding: 0; font-size: 1.15rem; }
.controls .cache-row-end button.theme-toggle { padding: 0 0.85rem; font-size: 0.9rem; }

/* Open list on phones: the chips get the full width; 🗑️ ☀️ stay on the
   summary line, inside the panel's top-right corner. */
@media (max-width: 600px) {
  .cache-row { position: relative; }
  .cache-row:has(.cache-shared[open]) .cache-row-end {
    position: absolute; top: 0.3rem; right: 0.3rem; gap: 0.3rem;
  }
  .cache-row:has(.cache-shared[open]) .cache-row-end button {
    height: calc(var(--ctl-h) - 0.6rem) !important;
  }
  .cache-row:has(.cache-shared[open]) .cache-row-end button.wipe-local { width: calc(var(--ctl-h) - 0.6rem) !important; }
  .cache-row:has(.cache-shared[open]) .cache-shared > summary { padding-right: 9rem; }
  /* t360u: open 💾 list gets the full width too (🗑️ ☀️ float top-right). */
  .cache-row:has(.cache-browser[open]) .cache-row-end {
    position: absolute; top: 0; right: 0;
  }
  .cache-row:has(.cache-browser[open]) .cache-shared { margin-right: 9.2rem; width: auto; }
}

/* t341u/t342u: 🏆 Rankings exactly as big as 🔍 Analyze, and a separate
   small › button next to it styled like 🔗 (mirrors Analyze + 🔗). Both open
   Rankings. Phones: Rankings fills the row up to the › (like Analyze / 🔗). */
.controls button#analyzeBtn,
.controls a.ranks-link#ranksLink { width: 10.5rem; flex: 0 0 auto; }
.ranks-pair { display: inline-flex; align-items: center; gap: 0.6rem; min-width: 0; }
.controls a.ranks-go {
  flex: 0 0 auto;
  box-sizing: border-box;
  width: var(--ctl-h);
  height: var(--ctl-h);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1px solid var(--ctrl-btn-border);
  background: var(--ctrl-btn-muted-bg);
  color: var(--accent);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.controls a.ranks-go:hover,
.controls a.ranks-go:focus-visible { background: var(--ctrl-btn-muted-hover); border-color: var(--accent); }
.controls a.ranks-go:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ranks-go .ranks-chev { display: block; }
@media (max-width: 600px) and (orientation: portrait) {
  .controls button#analyzeBtn,
  .controls a.ranks-link#ranksLink { width: auto; flex: 1 1 auto; }
  .ranks-pair { flex: 1 1 auto; }
  .ranks-row .ranks-row-end { display: none; }
}

.theme-toggle {
  margin-left: 0;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.35rem 0.75rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--ctrl-btn-bg);
  color: var(--text);
  cursor: pointer;
}
.theme-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--ctrl-btn-hover);
}
.controls button.theme-toggle {
  background: var(--ctrl-btn-bg);
  color: var(--text);
  border: 1px solid var(--border);
  font-weight: 600;
  font-size: 0.82rem;
  padding: 0.35rem 0.75rem;
  min-height: auto;
  box-shadow: none;
}
.controls button.theme-toggle:hover {
  background: var(--ctrl-btn-hover);
  border-color: var(--accent);
  color: var(--accent);
}

header h1 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 650;
  letter-spacing: 0.02em;
}

header .sub {
  color: var(--muted);
  font-size: 0.85rem;
}

.controls {
  /* One height for the names field (single row), 🔍 Analyze and the square 🔗 */
  --ctl-h: 2.9rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: flex-start;
  margin-bottom: 1rem;
  padding: 0.75rem 0.9rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.controls label {
  font-size: 0.8rem;
  color: var(--muted);
}

/* Tokenized name field — chips+input scroll/wrap; × pinned right */
.names-box {
  flex: 1 1 280px;
  min-width: 180px;
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 0.25rem;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.25rem 0.3rem 0.25rem 0.45rem;
  box-sizing: border-box;
  min-height: var(--ctl-h);
  cursor: text;
  position: relative;
}

.names-box-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
}

.names-box .clear-names {
  appearance: none;
  flex: 0 0 auto;
  flex-shrink: 0;
  align-self: center;
  width: 1.85rem;
  height: 1.85rem;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--dim);
  font-size: 1.35rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  pointer-events: auto;
  position: relative;
}

.names-box .clear-names:hover {
  background: var(--input-hover);
  color: var(--text);
}

.names-box .clear-names:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.names-box:focus-within {
  outline: 1px solid var(--accent);
  border-color: var(--accent);
}

.name-tokens {
  display: contents;
}

.names-box input#namesInput {
  /* Small basis so the typing spot stays on the chips' line while there is room */
  flex: 1 1 4rem;
  min-width: 3rem;
  background: transparent;
  border: none;
  color: var(--text);
  padding: 0.2rem 0.25rem;
  font-size: 0.95rem;
  min-height: 1.6rem;
  outline: none;
}

.names-box input#namesInput:focus {
  outline: none;
  border: none;
}

/* Name chips inside the input box */
.name-token {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border-radius: 999px;
  padding: 0.15rem 0.55rem;
  font-size: 0.8rem;
  line-height: 1.35;
  cursor: pointer;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.name-token.fetched {
  background: var(--token-ok-bg);
  color: var(--token-ok-fg);
  border: 1px solid var(--token-ok-bd);
}

.name-token.unfetched {
  background: var(--token-warn-bg);
  color: var(--token-warn-fg);
  border: 1px solid var(--token-warn-bd);
}

/* Name the last Analyze couldn't fetch (misspelled / not real / network) */
.name-token.failed {
  background: var(--token-fail-bg);
  color: var(--token-fail-fg);
  border: 1px dashed var(--token-fail-bd);
}
.name-token.failed .name-token-text {
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.name-token:hover {
  filter: brightness(1.12);
}

/* Failed chip = group of two buttons: ↻ struck name (retry) + × (remove). */
.name-token.failed {
  cursor: default;
  padding-right: 0.3rem;
}
.name-token.failed:hover { filter: none; }
.name-token-retry,
.name-token-x,
.controls .names-box .name-token-retry,
.controls .names-box .name-token-x,
.controls .names-box .name-token-retry:hover,
.controls .names-box .name-token-x:hover {
  appearance: none;
  background: transparent;
  border: none;
  color: inherit;
  font: inherit;
  line-height: inherit;
  padding: 0;
  margin: 0;
  cursor: pointer;
}
.name-token-retry {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}
.name-token-retry:hover .name-token-text,
.name-token-retry:focus-visible .name-token-text {
  text-decoration: underline;
}
.name-token-retry:hover .name-token-icon { filter: brightness(1.25); }
.name-token-x,
.controls .names-box .name-token-x {
  font-size: 0.95rem;
  line-height: 1;
  padding: 0 0.15rem;
  border-radius: 999px;
  opacity: 0.75;
}
.name-token-x:hover,
.name-token-x:focus-visible,
.controls .names-box .name-token-x:hover,
.controls .names-box .name-token-x:focus-visible { opacity: 1; background: color-mix(in srgb, currentColor 15%, transparent); }
.name-token-retry:focus-visible,
.name-token-x:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-radius: 999px;
}

.name-token:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.controls input[type="text"] {
  flex: 1 1 280px;
  min-width: 180px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.5rem 0.65rem;
  border-radius: 6px;
  font-size: 0.95rem;
  min-height: 2.35rem;
}

.controls input:focus {
  outline: 1px solid var(--accent);
  border-color: var(--accent);
}

.controls button {
  background: var(--ctrl-btn-bg);
  color: var(--text);
  border: 1px solid var(--ctrl-btn-border);
  padding: 0.45rem 0.9rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.9rem;
}

.controls button:hover { background: var(--ctrl-btn-hover); }
.controls button:disabled { opacity: 0.5; cursor: wait; }

/* × must stay a compact pin — beat .controls button cascade */
.controls .names-box .clear-names {
  background: transparent;
  border: none;
  padding: 0;
  width: 1.85rem;
  height: 1.85rem;
  font-size: 1.35rem;
  color: var(--dim);
  flex-shrink: 0;
  z-index: 2;
  pointer-events: auto;
}
.controls .names-box .clear-names:hover {
  background: var(--input-hover);
  color: var(--text);
}
.controls .names-box .clear-names:disabled {
  opacity: 1;
  cursor: pointer;
}
.controls button.btn-muted,
.controls button#copyLinkBtn {
  background: var(--ctrl-btn-muted-bg);
  color: var(--muted);
  border-color: var(--ctrl-btn-border);
}
.controls button.btn-muted:hover,
.controls button#copyLinkBtn:hover {
  background: var(--ctrl-btn-muted-hover);
  color: var(--text);
}

/* 🔗 Copy link: square, same height and corner radius as 🔍 Analyze */
.controls button#copyLinkBtn {
  flex: 0 0 auto;
  box-sizing: border-box;
  width: var(--ctl-h);
  height: var(--ctl-h);
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  line-height: 1;
}
.controls button#copyLinkBtn.copied {
  color: var(--ok);
  border-color: var(--ok);
  font-weight: 700;
}

/* Narrow portrait phones: names field full width, chips in an aligned grid of
   two equal columns (each chip fills its cell; long names ellipsize only when
   the cell is too narrow); the typing spot spans both columns.
   Analyze stretches so its right edge (with 🔗) lines up with the field. */
@media (max-width: 600px) and (orientation: portrait) {
  .names-box { flex: 1 1 100%; }
  .names-box-main {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: center;
  }
  .controls .names-box-main .name-token {
    width: 100%;
    justify-self: stretch;
    /* Tighter sides than the generic .controls button padding: more room for the name */
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }
  .controls .names-box-main .name-token.failed { padding-right: 0.3rem; }
  .names-box-main .name-token.failed { justify-content: space-between; }
  .names-box input#namesInput {
    grid-column: 1 / -1;
    flex: 0 0 auto;
    align-self: stretch;
    width: 100%;
    min-width: 0;
  }
  .controls button#analyzeBtn { flex: 1 1 auto; }
  /* × stays at the top-right of the (taller) list instead of floating mid-box */
  .controls .names-box .clear-names { align-self: flex-start; }
}

/* t355u: roomy typing — the typing spot always gets its own full-width line
   under the chips (a comfortable empty line to type into), bigger text for
   typed names and chips. Rankings' pick box uses the same numbers. */
.names-box { min-height: 3.4rem; }
.controls .names-box .clear-names { align-self: flex-start; margin-top: 0.3rem; }
.names-box input#namesInput {
  flex: 1 1 100%;
  width: 100%;
  min-width: 0;
  min-height: 2.6rem;
  font-size: 1.1rem;
  padding: 0.35rem 0.3rem;
}
.controls .names-box-main .name-token { font-size: 1rem; }

/* Primary action: Analyze pairs with the names input */
.controls button#analyzeBtn {
  background: #6cb2ff;
  color: var(--btn-text);
  border: 1px solid #6cb2ff;
  font-weight: 700;
  font-size: 0.95rem;
  padding: 0 1.2rem;
  box-sizing: border-box;
  height: var(--ctl-h);
  letter-spacing: 0.01em;
  box-shadow: 0 0 0 1px rgba(108, 178, 255, 0.25);
}
.controls button#analyzeBtn:hover {
  background: #8cc4ff;
  border-color: #8cc4ff;
  color: var(--btn-text);
}
.controls button#analyzeBtn:disabled {
  opacity: 0.55;
  cursor: wait;
}

.fresh-row {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem 0.75rem;
}

.fresh-label {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--text);
  cursor: pointer;
  user-select: none;
}

.fresh-eta {
  margin-left: -0.35rem; /* sits right after the checkbox label */
  font-size: 0.8rem;
  color: var(--muted);
  white-space: nowrap;
}
.fresh-eta[hidden] { display: none; }
.fresh-label input {
  accent-color: var(--accent);
}

.fresh-hint {
  font-size: 0.75rem;
  color: var(--dim);
}

.cache-chips {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  min-height: 0;
  align-items: center;
}

.cache-chips:empty { display: none; }

/* Collapsible shared-cache chip list (matches Public Census details style) */
.cache-shared {
  flex: 1 1 100%;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.35rem 0.6rem 0.4rem;
  margin: 0;
}

.cache-shared > summary {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  list-style: none;
}

.cache-shared > summary::-webkit-details-marker { display: none; }

/* t360u: 💾 names saved only in this browser — icon-only toggle, chips inside. */
.cache-browser { flex: 1 1 100%; min-width: 0; margin: 0; }
.cache-browser > summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1.45rem;
  line-height: 1;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  user-select: none;
}
.cache-browser > summary::-webkit-details-marker { display: none; }
.cache-browser > summary:hover { border-color: var(--accent, var(--muted)); }
.cache-browser[open] > summary { border-color: var(--accent, var(--muted)); }
.cache-browser-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.35rem;
  max-height: 11.5rem; /* ~50 names: scrolls instead of pushing the page down */
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.35rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.cache-shared > summary::before {
  content: "▸ ";
  color: var(--dim);
}

.cache-shared[open] > summary::before { content: "▾ "; }

.cache-shared-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.4rem;
}

/* Letter separators in the shared-cache chip list: each group [#] [A] [B] …
   gets its own heading line (dashed divider above, except the first), and the
   group's chips start on the next line. Not a chip: non-interactive. */
.cache-shared-chips { align-items: center; }
.chip-sep {
  flex: 0 0 100%;
  box-sizing: border-box;
  font-size: 0.8rem;
  font-weight: 700;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: 0.04em;
  color: var(--muted);
  line-height: 1.3;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
  white-space: nowrap;
}
/* Long unbreakable names must not widen the panel past a phone screen; leave a
   right gutter so the floating ⬆ / ⬇ quick jumps never sit on a chip. */
.cache-chips, .cache-shared { min-width: 0; }
.cache-shared-chips { padding-right: 2.75rem; }
.cache-shared-chips .chip { max-width: 100%; min-width: 0; }
@media (max-width: 600px) { .cache-shared-chips { padding-right: 1.25rem; } }
/* Shared-cache alphabet jump bar (# A … Z), sticky at the top while the list scrolls.
   Rules are scoped `.alpha-bar .alpha-btn` (0,2,0) on purpose: the bar lives inside
   .controls, whose generic `.controls button` (0,1,1: padding .45rem .9rem, 0.9rem
   font) used to win, making each letter ~31px wide in a ~20px phone grid cell —
   neighbours overlapped by ~8px like fish scales. Fixed size, box-sizing, no padding,
   a real 4px / 3px gap, and the button fills (never exceeds) its cell. */
.alpha-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  box-sizing: border-box;
  margin: 0.35rem 0 0;
  padding: 0.3rem 0;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
}
.alpha-bar .alpha-btn {
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  flex: 0 0 auto;
  width: 1.8rem;
  min-width: 0;
  height: 1.8rem;
  margin: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 6px;
  border: 1px solid var(--chip-border);
  background: var(--chip-bg);
  color: var(--accent);
  box-shadow: none;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.alpha-bar .alpha-btn:hover:not(:disabled),
.alpha-bar .alpha-btn:focus-visible {
  border-color: var(--accent);
  background: var(--chip-hover);
}
.alpha-bar .alpha-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.alpha-bar .alpha-btn:disabled {
  opacity: 0.32;
  cursor: default;
  color: var(--dim);
}
@media (max-width: 600px) {
  /* Phones: two even rows of 14 (# A–M / N–Z); each button exactly fills its cell */
  .alpha-bar {
    display: grid;
    grid-template-columns: repeat(14, minmax(0, 1fr));
    gap: 4px 3px;
  }
  .alpha-bar .alpha-btn { width: 100%; height: 1.95rem; font-size: 0.8rem; justify-self: stretch; }
}
.chip-group:not(:first-child) {
  margin-top: 0.1rem;
  padding-top: 0.3rem;
  border-top: 1px dashed color-mix(in srgb, var(--muted) 35%, transparent);
}
/* t305u: collapsible letter blocks — the [A] heading is the clickable summary. */
.chip-group { flex: 0 0 100%; min-width: 0; }
.chip-group > summary.chip-sep {
  display: block;
  list-style: none;
  cursor: pointer;
  pointer-events: auto;
  padding: 0.3rem 0;
  min-height: 1.6rem;
  -webkit-tap-highlight-color: transparent;
}
.chip-group > summary.chip-sep::-webkit-details-marker { display: none; }
.chip-group > summary.chip-sep::before { content: "▸ "; color: var(--dim); }
.chip-group[open] > summary.chip-sep::before { content: "▾ "; }
.chip-group > summary.chip-sep:hover { color: var(--text); }
.chip-group-picked { color: var(--accent); font-weight: 700; }
.chip-group-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  padding: 0.15rem 0 0.35rem;
}
.chip-group-chips .chip { max-width: 100%; min-width: 0; }

.chip {
  appearance: none;
  background: var(--chip-bg);
  color: var(--accent);
  border: 1px solid var(--chip-border);
  border-radius: 999px;
  padding: 0.2rem 0.65rem;
  font-size: 0.78rem;
  cursor: pointer;
  line-height: 1.4;
}

.chip:hover {
  background: var(--chip-hover);
  border-color: var(--accent);
}

.chip.active {
  background: var(--chip-active-bg);
  border-color: var(--accent);
  color: var(--text);
}

.chip.shared {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
}
.controls .hint {
  flex: 1 1 100%;
  font-size: 0.75rem;
  color: var(--dim);
}

#status {
  min-height: 1.2em;
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 0.5rem;
}
/* No idle "Ready" text any more: an empty status line takes no space. */
#status:empty { min-height: 0; margin-bottom: 0; }

#status .err { color: var(--err); }
#status .ok { color: var(--ok); }
#status .warn { color: var(--warn); }
#status .src { color: var(--dim); }

/* Amber (not red) note listing names an Analyze run had to skip */
#status .skipped-warning {
  padding: 0.4rem 0.65rem;
  background: var(--skip-bg);
  border: 1px solid var(--skip-bd);
  border-left-width: 3px;
  border-radius: 8px;
  line-height: 1.4;
  margin-bottom: 0.15rem;
}
#status .skipped-warning .skipped-name { font-weight: 700; }
#status .skipped-warning .skipped-reason { font-weight: 400; opacity: 0.85; }
#status .skipped-warning .skipped-tail { color: var(--muted); }

/* Repeat-Analyze hint when the graph is already ready for this name set */
#status.graph-ready {
  color: var(--accent);
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.35;
  padding: 0.45rem 0.7rem;
  background: var(--chip-active-bg);
  border: 1px solid var(--accent);
  border-radius: 8px;
  margin-bottom: 0.65rem;
  transition: opacity 0.45s ease;
}
#status.graph-ready.graph-ready-fade {
  opacity: 0;
}
#status.graph-ready .graph-ready-hint {
  display: block;
}
#status.graph-ready .graph-ready-hint > div + div {
  font-weight: 500;
  color: var(--muted);
  margin-top: 0.15rem;
}

/* Full-screen analyzing / fetching popup */
.progress-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
}

.progress-modal[hidden] {
  display: none !important;
}

.progress-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: blur(3px);
}

.progress-modal-card {
  position: relative;
  z-index: 1;
  width: min(420px, 100%);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 18px 48px var(--shadow);
  padding: 1.6rem 1.5rem 1.4rem;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}

/* ✕ cancel — top-right, ≥44px tap target for mobile */
.progress-cancel {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  font-size: 1.35rem;
  line-height: 1;
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.progress-cancel:hover,
.progress-cancel:active {
  background: var(--ctrl-btn-hover);
  border-color: var(--ctrl-btn-border);
  color: var(--text);
}

.progress-cancel:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  color: var(--text);
}

.progress-modal-spinner {
  margin-bottom: 0.35rem;
}

.progress-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 650;
  color: var(--text);
  letter-spacing: 0.01em;
}

.progress-text {
  margin: 0.15rem 0 0.55rem;
  font-size: 0.92rem;
  color: var(--muted);
  line-height: 1.4;
  max-width: 100%;
  word-break: break-word;
}

.progress-bar-track {
  width: 100%;
  height: 12px;
  background: var(--spinner-track);
  border-radius: 999px;
  overflow: hidden;
  border: 1px solid var(--border);
}

.progress-bar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--accent), #6ec6a0);
  border-radius: 999px;
  transition: width 0.28s linear;
}

.progress-meta {
  display: flex;
  justify-content: space-between;
  width: 100%;
  margin-top: 0.45rem;
  font-size: 0.88rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  gap: 0.75rem;
}

#progressPct {
  font-weight: 650;
  color: var(--accent);
}

.progress-timing,
#progressTiming {
  color: var(--muted);
  text-align: right;
  margin-left: auto;
  font-size: 0.82rem;
  line-height: 1.35;
}

.spinner {
  width: 14px;
  height: 14px;
  border: 2px solid var(--spinner-track);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  flex-shrink: 0;
  display: inline-block;
}

.spinner-lg {
  width: 42px;
  height: 42px;
  border-width: 4px;
}

body.progress-open {
  overflow: hidden;
}

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

html[data-theme="light"] .progress-modal-backdrop {
  background: rgba(40, 32, 20, 0.42);
}

.chart-wrap {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.25rem 0.75rem;
  overflow: hidden;
  max-width: 100%;
  margin-top: 0;
}

#chart {
  width: 100%;
  height: auto;
  display: block;
  touch-action: manipulation;
}

#chart[hidden] {
  display: none;
}

/* Graph view toggle (📈 Raw = cumulative | 🎚️ Smooth = banded) — small segmented pill above the plot */
/* Row above the plot: [ghost caption] [toggle pill], right-aligned */
.chart-mode-row {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0.6rem 0.3rem;
}
.chart-wrap.empty .chart-mode-row {
  display: none;
}
.chart-mode-bar {
  display: flex;
  justify-content: flex-end;
  flex: 0 0 auto;
  width: fit-content;
  margin: 0;
  padding: 2px;
  gap: 2px;
  border: 1px solid var(--ctrl-btn-border);
  border-radius: 999px;
  background: var(--ctrl-btn-muted-bg);
}
.chart-wrap.empty .chart-mode-bar {
  display: none;
}
.chart-mode-btn {
  font: inherit;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.2;
  padding: 0.2rem 0.6rem;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}
.chart-mode-btn:hover {
  background: var(--ctrl-btn-muted-hover);
  color: var(--text);
}
.chart-mode-btn.active {
  background: var(--accent);
  color: var(--btn-text);
}
.chart-mode-sep {
  width: 1px;
  margin: 3px 1px;
  background: var(--ctrl-btn-border);
}
.chart-ghost-btn:not(.active) {
  opacity: 0.6;
}
.chart-ghost-btn.active {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--text);
}
/* Small 2-line caption next to 👻 Ghost (only while ghost lines are drawn) */
.ghost-caption {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 1 auto;
  min-width: 0;
  font-size: 0.64rem;
  line-height: 1.2;
  color: var(--dim);
  text-align: right;
}
.ghost-caption[hidden] {
  display: none;
}
.ghost-caption-swatch[hidden] { display: none; }
.ghost-caption-swatch {
  flex: 0 0 auto;
  width: 14px;
  height: 0;
  border-top: 2px dashed var(--dim);
}
.ghost-caption-text {
  min-width: 0;
  white-space: nowrap;
}
.chart-mode-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
@media (max-width: 520px) {
  /* Phones: pill centred over the chart (as before the caption existed);
     caption on its own line, centred beneath it, so it never moves the pill. */
  .chart-mode-row {
    display: grid;
    grid-template-columns: 1fr;
    justify-items: center;
    row-gap: 0.25rem;
    margin: 0 auto 0.3rem;
  }
  .chart-mode-bar { grid-row: 1; justify-self: center; }
  .ghost-caption {
    grid-row: 2;
    justify-self: center;
    justify-content: center;
    text-align: center;
    font-size: 0.6rem;
  }
  .chart-mode-btn {
    font-size: 0.68rem;
    padding: 0.18rem 0.5rem;
  }
}

@media (min-width: 601px) {
  /* PC: pill centred over the graph; ghost caption sits to its left
     (its own column) so it never pushes the pill off centre. */
  .chart-mode-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    column-gap: 0.6rem;
  }
  .chart-mode-bar { grid-column: 2; grid-row: 1; justify-self: center; }
  .ghost-caption { grid-column: 1; grid-row: 1; justify-self: end; }
}

/* Y-axis zoom — bare overlay on plot top-right (may overlap lines; no chrome box) */
.chart-y-zoom {
  position: absolute;
  /* A bit lower than the plot top edge (+ the view-toggle row above the plot) */
  top: calc(9% + 1.4rem);
  right: 6.5%;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
  pointer-events: auto;
}
.chart-wrap.empty .chart-y-zoom,
.chart-y-zoom[hidden] {
  display: none !important;
}
#yZoomSlider {
  -webkit-appearance: slider-vertical;
  appearance: slider-vertical;
  writing-mode: vertical-lr;
  direction: rtl;
  width: 22px;
  height: min(118px, 28vh);
  margin: 0;
  padding: 0;
  background: transparent;
  outline: none;
  border: none;
  cursor: pointer;
  accent-color: var(--accent);
}
#yZoomSlider::-webkit-slider-runnable-track {
  width: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--grid) 80%, transparent);
}
/* Flat wide thumb (===) instead of round O — short along track, wide across */
#yZoomSlider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 5px;
  margin-left: -7.5px;
  border-radius: 1px;
  background: var(--accent);
  border: none;
  box-shadow: 0 1px 3px var(--shadow);
  cursor: pointer;
}
#yZoomSlider::-moz-range-track {
  width: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--grid) 80%, transparent);
}
#yZoomSlider::-moz-range-thumb {
  width: 18px;
  height: 5px;
  border-radius: 1px;
  background: var(--accent);
  border: none;
  box-shadow: 0 1px 3px var(--shadow);
  cursor: pointer;
}
.chart-y-zoom-reset {
  font: inherit;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 0.18rem 0.4rem;
  border-radius: 6px;
  border: 1px solid var(--ctrl-btn-border);
  background: color-mix(in srgb, var(--ctrl-btn-bg) 85%, transparent);
  color: var(--text);
  cursor: pointer;
  line-height: 1.2;
}
.chart-y-zoom-reset:hover {
  background: var(--ctrl-btn-hover);
}
@media (max-width: 520px) {
  .chart-y-zoom {
    top: calc(8% + 1.4rem);
    right: 5.5%;
    gap: 0.22rem;
  }
  #yZoomSlider {
    height: min(96px, 24vh);
    width: 20px;
  }
  #yZoomSlider::-webkit-slider-thumb {
    width: 16px;
    height: 4px;
    margin-left: -6.5px;
  }
  #yZoomSlider::-moz-range-thumb {
    width: 16px;
    height: 4px;
  }
}

.chart-placeholder {
  display: none;
  position: relative;
  width: 100%;
  max-width: 100%;
  margin: 0;
  border-radius: 6px;
  overflow: hidden;
  aspect-ratio: 1800 / 1044;
  max-height: min(70vh, 560px);
  background: #0f1114;
}

.chart-wrap.empty .chart-placeholder {
  display: block;
}

.chart-wrap.empty #chart {
  display: none;
}

.chart-placeholder .ph-img {
  display: none;
  width: 100%;
  max-width: 100%;
  height: 100%;
  margin: 0;
  object-fit: cover;
  object-position: center;
  border-radius: 6px;
  pointer-events: none;
  user-select: none;
}
.chart-placeholder .ph-dark {
  display: block;
  opacity: 0.95;
  filter: brightness(1.18) contrast(1.12) saturate(1.08);
}
.chart-placeholder .ph-light {
  display: none;
  opacity: 0.92;
  filter: brightness(1.02) contrast(1.04) saturate(0.95);
}
html[data-theme="light"] .chart-placeholder {
  background: #e8e1d4;
}
html[data-theme="light"] .chart-placeholder .ph-dark {
  display: none;
}
html[data-theme="light"] .chart-placeholder .ph-light {
  display: block;
}
html[data-theme="light"] .chart-placeholder-overlay {
  background: linear-gradient(
    180deg,
    rgba(240, 235, 227, 0.08) 0%,
    rgba(232, 225, 212, 0.18) 45%,
    rgba(232, 225, 212, 0.28) 100%
  );
}

.chart-placeholder-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(
    180deg,
    rgba(11, 12, 14, 0.04) 0%,
    rgba(11, 12, 14, 0.12) 45%,
    rgba(11, 12, 14, 0.18) 100%
  );
  pointer-events: none;
}

/* Whole placeholder image is clickable (= 🔍 Analyze); the centre pill is a
   real button that keeps the original frosted "▶️ Press Analyze" look. */
.chart-placeholder {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.chart-placeholder-cta {
  pointer-events: auto;
  cursor: pointer;
  font-family: inherit;
  line-height: inherit;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text);
  padding: 0.55rem 1.15rem;
  border-radius: 999px;
  background: var(--cta-bg);
  border: 1px solid var(--cta-border);
  box-shadow: 0 8px 28px var(--cta-shadow);
  backdrop-filter: blur(6px);
  transition: transform 0.12s ease, filter 0.12s ease;
  touch-action: manipulation;
}
.chart-placeholder:hover .chart-placeholder-cta,
.chart-placeholder-cta:hover,
.chart-placeholder-cta:focus-visible {
  transform: scale(1.04);
  filter: brightness(1.12);
}
.chart-placeholder-cta:focus-visible {
  outline: 2px solid var(--cta-border);
  outline-offset: 3px;
}
.chart-placeholder:active .chart-placeholder-cta,
.chart-placeholder-cta:active {
  transform: scale(0.97);
}

.chart-wrap:not(.empty) .chart-placeholder {
  display: none;
}

.stats-panel {
  margin-top: 0.35rem;
  margin-bottom: 0.85rem;
}

.stats-panel:empty { display: none; }

.stats-section {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.55rem 0.75rem 0.7rem;
  margin-bottom: 0.55rem;
}

.stats-section > summary,
.stats-section .section-title {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
  cursor: default;
  list-style: none;
}

.stats-section > summary {
  cursor: pointer;
  user-select: none;
}

.stats-section > summary::-webkit-details-marker { display: none; }
.stats-section > summary::before {
  content: "▸ ";
  color: var(--dim);
}
.stats-section[open] > summary::before { content: "▾ "; }

.stats-table-wrap {
  overflow-x: auto;
  margin-top: 0.45rem;
}

.stats-table {
  width: max-content;
  min-width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.stats-table th,
.stats-table td {
  padding: 0.28rem 0.55rem;
  border-bottom: 1px solid var(--row-border);
  text-align: left;
  white-space: nowrap;
}

/* ⚡ ivi below zero shown as 0 ("Below the rating scale") */
.stats-table td.below-scale {
  opacity: 0.55;
  cursor: help;
}

/* 🏃 Activity / 🦁 Brave "—" below MIN_FIGHTS (hover explains why) */
td.thin-sample {
  opacity: 0.55;
  cursor: help;
}

.stats-table .stats-name,
.stats-table th.stats-name,
.stats-table td.stats-name {
  text-align: left;
  font-weight: 600;
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--panel);
  box-shadow: 4px 0 8px -4px var(--shadow);
}

.stats-table thead th {
  color: var(--text);
  font-weight: 600;
  border-bottom-color: var(--border);
}

.stats-table thead th.stats-name {
  color: var(--dim);
  font-weight: 500;
  z-index: 2;
}

.stats-table tbody tr:last-child td,
.stats-table tbody tr:last-child th {
  border-bottom: none;
}

/* Legend: real grid so every column starts at the same x (2 columns on phones). */
.legend {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 10rem), 1fr));
  gap: 0.6rem 1.25rem;
  margin-top: 0.85rem;
  font-size: 0.85rem;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}
.legend-label {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  min-width: 0;
}
.legend-label .nm { flex: 0 1 auto; min-width: 0; }

/* Legend names → Honu profile: keep the series color, underline on hover only. */
.legend-link,
.legend-link:visited {
  color: inherit;
  text-decoration: none;
}
.legend-link:hover,
.legend-link:focus-visible {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.legend-swatch {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}

footer {
  margin-top: 1.5rem;
  font-size: 0.75rem;
  color: var(--dim);
  line-height: 1.45;
}

footer a { color: var(--accent); }

/* Footer first line: repo link left, "show older debug stats" right (wraps on narrow screens). */
footer .footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 1rem;
}
footer .footer-row { margin: 0.75rem 0; }
footer .footer-row p { margin: 0; }
footer .debug-cols-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: auto;
  cursor: pointer;
  user-select: none;
  min-height: 1.75rem; /* comfortable tap target on mobile */
}
footer .debug-cols-toggle input { margin: 0; cursor: pointer; }

/* Collapsed legal-style disclaimer at the very bottom of the footer. */
footer .disclaimer { margin: 0.5rem 0 0.75rem; color: var(--dim); }
footer .disclaimer summary {
  cursor: pointer;
  display: inline-block;
  min-height: 1.5rem;
  opacity: 0.8;
  user-select: none;
}
footer .disclaimer summary:hover,
footer .disclaimer[open] summary { opacity: 1; color: var(--muted); }
footer .disclaimer p {
  margin: 0.4rem 0 0;
  max-width: 60rem;
  font-size: 0.7rem;
  overflow-wrap: anywhere;
}

@media (max-width: 640px) {
  body { padding: 0.75rem; }
}


.stats-table thead th.sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.stats-table thead th.sortable:hover {
  color: var(--accent);
}
.stats-table thead th.sortable.sorted {
  color: var(--accent);
}
.stats-table .sort-ind {
  display: inline-block;
  min-width: 0.85em;
  margin-left: 0.2rem;
  font-size: 0.7em;
  opacity: 0.35;
  vertical-align: middle;
}
.stats-table .sort-ind.active {
  opacity: 1;
}


.stats-table .player-num {
  font-weight: 700;
  margin-right: 0.2rem;
  opacity: 0.95;
  font-variant-numeric: tabular-nums;
}

.legend-meta {
  color: var(--dim);
  font-size: 0.8em;
}


html[data-theme="light"] .cache-chips .chip.shared {
  background: var(--chip-bg);
  color: var(--accent);
}

/* Cache chip currently in the name input: accent ring + tinted fill + ✓.
   Placed last / with theme selector so it beats .chip.shared overrides. */
.cache-chips .chip.selected,
html[data-theme="light"] .cache-chips .chip.selected {
  background: color-mix(in srgb, var(--accent) 24%, var(--chip-bg));
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  color: var(--text);
  font-weight: 600;
}
.cache-chips .chip.selected::before {
  content: "✓ ";
  color: var(--accent);
}
.cache-chips .chip.selected:hover,
html[data-theme="light"] .cache-chips .chip.selected:hover {
  background: color-mix(in srgb, var(--accent) 34%, var(--chip-bg));
}
html[data-theme="light"] .cache-chips .chip.selected {
  background: color-mix(in srgb, var(--accent) 16%, var(--chip-bg));
}
html[data-theme="light"] .cache-chips .chip.selected:hover {
  background: color-mix(in srgb, var(--accent) 24%, var(--chip-bg));
}

.shared-add-note {
  margin-top: 4px;
  font-size: 0.85em;
  opacity: 0.75;
}
.shared-add-note[hidden] { display: none; }

/* ⬆ / ⬇ floating quick jumps (jump-btns.mjs; ranks.html + index.html shared cache).
   Fixed bottom-right, shown after ~1 screen of scrolling. Below popups/toasts (z 1000+). */
.jump-btns {
  position: fixed; z-index: 30;
  right: max(12px, env(safe-area-inset-right));
  bottom: max(14px, env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 0.45rem;
  pointer-events: none;
}
.jump-btn {
  position: relative;
  pointer-events: auto;
  width: 2.75rem; height: 2.75rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid var(--border); background: var(--ctrl-btn-bg); color: var(--accent);
  box-shadow: 0 4px 14px var(--shadow);
  cursor: pointer; padding: 0;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 0.15s ease, transform 0.15s ease, border-color 0.12s ease, background-color 0.12s ease;
}
.jump-btn[hidden] { display: none; }
.jump-btn svg { display: block; }
.jump-btn:hover, .jump-btn:focus-visible { border-color: var(--accent); background: var(--ctrl-btn-hover); }
.jump-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.jump-btn:active { transform: scale(0.94); }
.jump-btn::after {
  content: attr(data-hint);
  position: absolute; right: calc(100% + 8px); top: 50%; transform: translate(3px, -50%);
  white-space: nowrap; padding: 0.25rem 0.55rem; border-radius: 6px;
  font-size: 0.78rem; font-weight: 600;
  background: var(--bg); color: var(--text); border: 1px solid var(--accent);
  box-shadow: 0 4px 14px var(--shadow);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s linear 0.12s;
}
@media (hover: hover) and (pointer: fine) {
  .jump-btn:hover::after { opacity: 1; visibility: visible; transform: translate(0, -50%); transition: opacity 0.12s ease 0.15s, transform 0.12s ease 0.15s, visibility 0s; }
}
.jump-btn:focus-visible::after { opacity: 1; visibility: visible; transform: translate(0, -50%); }

/* "10 players limit reached" toast at the clicked shared-cache chip (fixed: no layout shift) */
.limit-toast {
  position: fixed;
  z-index: 1100;
  max-width: min(18rem, calc(100vw - 16px));
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.5rem 0.8rem;
  border-radius: 8px;
  background: var(--panel);
  color: var(--warn);
  border: 1px solid var(--warn);
  border-left-width: 3px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
  font-size: 0.85rem;
  line-height: 1.3;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.limit-toast[hidden] { display: none; }
.limit-toast .limit-toast-sub { color: var(--muted); font-size: 0.75rem; }
.limit-toast.limit-toast-docked {
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
}
.limit-toast.limit-toast-pop { animation: limit-toast-pop 0.18s ease-out; }
.limit-toast.limit-toast-docked.limit-toast-pop { animation: none; }
@keyframes limit-toast-pop {
  from { opacity: 0; transform: translateY(4px) scale(0.97); }
  to { opacity: 1; transform: none; }
}

/* Long player names: cap at ~80% of cached name lengths (18 chars incl. "[TAG] ");
   full name in the title + name-peek.mjs popup (tap / long-press on touch). */
.nm {
  display: inline-block;
  max-width: 18ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
/* Cache chips keep the 18ch cap (dense list). Input chips and legend names
   truncate by SPACE instead: full name whenever it fits, ellipsis only when the
   chip / cell is really too narrow (name-peek popup checks scrollWidth). */
.chip .nm { max-width: min(18ch, 100%); }
.name-token .nm,
.legend-label .nm { max-width: 100%; }
.name-token > .nm { flex: 0 1 auto; min-width: 0; }
.name-token-retry .name-token-text { flex: 0 1 auto; min-width: 0; }
.name-token-icon,
.name-token-x { flex: 0 0 auto; }

.name-peek {
  position: fixed;
  z-index: 1100;
  max-width: calc(100vw - 16px);
  padding: 0.45rem 0.75rem;
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--accent);
  border-left-width: 3px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
  cursor: pointer;
  user-select: text;
}
.name-peek[hidden] { display: none; }
.name-peek.name-peek-pop { animation: limit-toast-pop 0.18s ease-out; }

/* Stats tables: small dimmed "−28%" gap to the column top beside each value */
.stats-table td .pct {
  margin-left: 0.3em;
  font-size: 0.72em;
  color: var(--dim);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* Phones: stack the % under the number so columns stay narrow */
@media (max-width: 600px) {
  .stats-table td .pct {
    display: block;
    margin-left: 0;
    line-height: 1.1;
  }
}

/* Census busy/down: friendly retry button + notes in the status line */
.census-retry-btn {
  margin-left: 0.4em;
  padding: 0.15em 0.6em;
  border-radius: 999px;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.9em;
  cursor: pointer;
}
.census-retry-btn:hover { background: rgba(127, 127, 127, 0.15); }
.census-note { margin-top: 0.25em; line-height: 1.5; }

/* Small disclaimer under the legend; only once a graph (legend) is drawn. */
.pooled-note {
  margin: 0.6rem 0 0;
  font-size: 0.74rem;
  line-height: 1.4;
  color: var(--dim);
  overflow-wrap: anywhere;
}
.legend:empty + .pooled-note {
  display: none;
}

/* 🚩 stat padder marker "*" (padding.mjs): kills on farm accounts excluded. */
.pad-mark {
  margin-left: 0.1em;
  font-weight: 800;
  cursor: help;
}
.legend-note {
  grid-column: 1 / -1;
  font-size: 0.78rem;
  opacity: 0.7;
}
/* † stats adjusted (under review): lighter than the padding "*" */
.pad-mark.mark-adjusted {
  font-weight: 600;
  opacity: 0.75;
}

/* ◦ older top-50 opponent sample (upgrading to 200 on its next refresh): subtle. */
.sample-fresh {
  margin-left: 0.2em;
  font-size: 0.75em;
  color: var(--dim);
  cursor: help;
}
.sample-legacy {
  margin-left: 0.15em;
  font-size: 0.8em;
  opacity: 0.45;
  cursor: help;
}

/* Account flairs (flairs.mjs): 🪦 inactive, 👴🏽 veteran; chart name list only. */
.flair {
  margin-left: 0.25em;
  font-size: 0.85em;
  cursor: help;
  white-space: nowrap;
}
/* In the chart legend the flair takes the colored dot's place (name keeps the line color). */
.legend-flair {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.legend-flair .flair { margin-left: 0; font-size: 0.8rem; }

/* Under ✨ Adjusted: collapsed "⚠️" note, opens to who is "—" and why. */
.stats-thin-note {
  margin: 0.4rem 0 0;
  font-size: 0.76rem;
  color: var(--muted);
  opacity: 0.85;
}

/* Collapsed-by-default small notes (vehicle pooling, * † ◦ marks; ♿ summary):
   one short muted summary line; the full text only when opened. */
.fold-note > summary {
  cursor: pointer;
  list-style: none;
  display: inline-block;
  font-size: 0.74rem;
  line-height: 1.4;
  color: var(--dim, var(--muted));
  opacity: 0.85;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  padding: 0.15rem 0;
}
.fold-note > summary::-webkit-details-marker { display: none; }
.fold-note > summary::after { content: " ▸"; opacity: 0.7; }
.fold-note[open] > summary::after { content: " ▾"; }
.fold-note > summary:hover,
.fold-note > summary:focus-visible { opacity: 1; text-decoration: underline dotted; }
.fold-note > p { margin: 0.2rem 0 0; }
.legend .fold-note { grid-column: 1 / -1; }
.ranks-status .fold-note > p.legend-note { margin: 0.15rem 0 0; }

/* ---------- Big desktop monitors (t299u) ----------
 * At 2560×1440 the text stayed at 16px-root sizes while the graph scaled to the
 * full width (~1450px tall, taller than the screen). From 1400px wide only:
 * grow the root font with the viewport (16px → ~17.5px @1920 → ~21px @2560,
 * so every rem-sized table / legend / control grows with it), keep content to a
 * readable width, and cap the graph at ~62% of the screen height (its width
 * follows the 1000:580 aspect). Mobile / narrow layouts are untouched. */
@media (min-width: 1400px) {
  html { font-size: clamp(16px, calc(0.6vw + 6px), 22px); }
  body { max-width: 100rem; margin-inline: auto; }
  .chart-wrap {
    /* svg height = width × 0.58 ≤ 62vh; + horizontal padding/border */
    max-width: calc(62vh * 1000 / 580 + 0.5rem + 2px);
    margin-inline: auto;
  }
  #legend { max-width: calc(62vh * 1000 / 580 + 0.5rem + 2px); margin-inline: auto; }
}
/* t313u: main page — one shared desktop content width for header / controls,
 * stats table, graph, legend and footer, all aligned. The graph fills it, so
 * the width is set by the graph's height cap: svg height = width × 0.58 ≤ 68vh
 * (2560×1440 → ~1700px wide graph, 1920×1080 → ~1280px), in between the old
 * graph (62vh) and the old 100rem header. Other pages keep the 100rem rule. */
@media (min-width: 1400px) {
  body.main-page {
    --desk-w: calc(68vh * 1000 / 580 + 0.5rem + 2px);
    max-width: calc(var(--desk-w) + 2.5rem); /* + body side padding (border-box) */
  }
  body.main-page .chart-wrap,
  body.main-page #legend { max-width: none; }
}

/* ---------- t315u: full player names on wide screens (main page) ----------
 * Same caps as the Rankings (t311u): phones keep the 18ch cap / 10rem legend
 * columns; >600px names may use 28ch, >1100px 42ch ([TAG] + 32-char name).
 * Ellipsis + title / name-peek stay for anything longer or truly cramped. */
@media (min-width: 601px) {
  .stats-table .nm { max-width: 28ch; }
  .chip .nm { max-width: min(28ch, 100%); }
  .legend { grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr)); }
}
@media (min-width: 1100px) {
  .stats-table .nm { max-width: 42ch; }
  .chip .nm { max-width: min(42ch, 100%); }
  .legend { grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr)); }
}

/* ======================================================================
 * t356u: 🏆 Rankings on the main page (was ranks.html; rankings.mjs).
 * ====================================================================== */
.rankings { margin: 1.25rem 0 0.5rem; }
.ranks-meta { color: var(--dim); font-size: 0.85rem; margin: 0 0 0.5rem; }
.ranks-meta:empty { display: none; }
/* 🏅 where the selected players rank (rank # + percentile per metric) */
.rk-positions { margin: 0 0 0.85rem; }
.rk-pos-hint { color: var(--dim); font-size: 0.85rem; margin: 0.2rem 0 0.4rem; }
.rk-pos-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 8px; background: var(--panel); -webkit-overflow-scrolling: touch; }
.rk-pos-table { border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%; font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.rk-pos-table th, .rk-pos-table td { padding: 0.35rem 0.6rem; border-bottom: 1px solid var(--row-border); white-space: nowrap; text-align: right; background: var(--panel); }
.rk-pos-table tbody tr:last-child th, .rk-pos-table tbody tr:last-child td { border-bottom: none; }
.rk-pos-table thead th { color: var(--text); font-weight: 600; }
.rk-pos-table .rk-pos-name { text-align: left; position: sticky; left: 0; z-index: 1; font-weight: 600; box-shadow: 4px 0 8px -4px var(--shadow); }
.rk-pos-table .rk-pos-name a { text-decoration: none; }
.rk-pos-table .rk-pos-name a:hover { text-decoration: underline; }
.rk-pos-table td b { font-weight: 700; }
.rk-pos-table td .pct { margin-left: 0.35em; font-size: 0.75em; color: var(--dim); }
/* Table filter (selection itself is the names box at the top) */
.rk-filter-row { margin: 0 0 0.5rem; }
.rk-filter-row input[type="search"] {
  box-sizing: border-box; width: 100%; max-width: 28rem;
  font: inherit; font-size: 1rem; padding: 0.5rem 0.7rem; min-height: 2.6rem;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--input-bg); color: var(--text); outline: none;
}
.rk-filter-row input[type="search"]:focus { border-color: var(--accent); outline: 1px solid var(--accent); }

.ranks-status { min-height: 1.35rem; margin: 0 0 0.5rem; font-size: 0.9rem; }
.ranks-status:empty { display: none; }

.ranks-table-wrap {
  overflow: auto;
  max-height: calc(100vh - 11rem);
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
}
.ranks-table {
  width: max-content; min-width: 100%;
  border-collapse: separate; border-spacing: 0;
  font-size: 0.8rem; font-variant-numeric: tabular-nums;
}
.ranks-table th, .ranks-table td {
  padding: 0.28rem 0.55rem;
  border-bottom: 1px solid var(--row-border);
  white-space: nowrap; text-align: right;
  background: var(--panel);
}
.ranks-table th.rk-name, .ranks-table td.rk-name,
.ranks-table th.rk-pick, .ranks-table td.rk-pick { text-align: left; }
.ranks-table thead th {
  position: sticky; top: 0; z-index: 3;
  color: var(--text); font-weight: 600;
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 var(--border);
}
.ranks-table thead th.sortable { cursor: pointer; user-select: none; }
.ranks-table thead th.sortable:hover,
.ranks-table thead th.sortable.sorted { color: var(--accent); }
.ranks-table .sort-ind {
  display: inline-block; min-width: 0.85em; margin-left: 0.15rem;
  font-size: 0.7em; opacity: 0.35; vertical-align: middle;
}
.ranks-table .sort-ind.active { opacity: 1; }
/* Sticky left: checkbox + # + Player */
.ranks-table th.rk-pick, .ranks-table td.rk-pick {
  position: sticky; left: 0; z-index: 1; width: 1.6rem; padding-right: 0.2rem;
  box-shadow: none;
}
.ranks-table th.rk-num, .ranks-table td.rk-num {
  position: sticky; left: 1.6rem; z-index: 1; width: 2.6rem;
  text-align: right; color: var(--dim); font-weight: 600;
  padding-left: 0.2rem; padding-right: 0.4rem;
}
.ranks-table th.rk-name, .ranks-table td.rk-name {
  position: sticky; left: 4.2rem; z-index: 1; font-weight: 600;
  box-shadow: 4px 0 8px -4px var(--shadow);
}
.ranks-table thead th.rk-pick,
.ranks-table thead th.rk-num,
.ranks-table thead th.rk-name { z-index: 4; }
.ranks-table td.rk-name a {
  color: inherit; text-decoration: none;
}
.ranks-table td.rk-name a:hover { color: var(--accent); text-decoration: underline; }
/* Player names (t311u): phones keep the global 18ch cap (styles.css .nm);
   wider screens have room, so names show in full ([TAG] + 32-char name ≈ 40ch)
   and only truly huge ones still get the ellipsis + title / name-peek. */
@media (min-width: 601px) { .ranks-table td.rk-name .nm { max-width: 28ch; } }
@media (min-width: 1100px) { .ranks-table td.rk-name .nm { max-width: 42ch; } }
.ranks-table tbody tr:hover td { background: var(--input-hover); }
.ranks-table td .pct {
  margin-left: 0.3em; font-size: 0.72em; color: var(--dim);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.ranks-table td.below-scale { opacity: 0.55; cursor: help; }
.ranks-table input[type="checkbox"] { margin: 0; cursor: pointer; vertical-align: middle; }
/* 📊 Distribution (hand-rolled SVG like the main chart) */
.dist-section {
  margin: 0 0 0.85rem; border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel); padding: 0.45rem 0.75rem 0.6rem;
}
.dist-section > summary { cursor: pointer; list-style: none; user-select: none; font-weight: 600; font-size: 0.95rem; }
.dist-section > summary::-webkit-details-marker { display: none; }
.dist-section > summary::before { content: "▸ "; color: var(--dim); }
.dist-section[open] > summary::before { content: "▾ "; }
.dist-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.9rem; margin: 0.5rem 0 0.35rem; font-size: 0.85rem; }
.dist-controls select {
  font: inherit; font-size: 0.9rem; padding: 0.3rem 0.5rem; border-radius: 6px;
  border: 1px solid var(--border); background: var(--input-bg); color: var(--text);
}
.dist-summary { color: var(--dim); }
.dist-chart { position: relative; width: 100%; }
.dist-chart svg { display: block; width: 100%; height: auto; touch-action: manipulation; }
.dist-chart .dist-hit { cursor: pointer; outline: none; }
.dist-chart .dist-hit:focus-visible { stroke: var(--accent); stroke-width: 1.5; }
.dist-tip .dist-jump-hint { display: block; margin-top: 0.2rem; color: var(--dim); font-size: 0.75rem; }
/* Chart bar → table jump (t308u): brief highlight of that range's rows. */
@keyframes rkFlash { 0%, 55% { background: var(--rk-flash); } 100% { background: var(--panel); } }
.ranks-table tbody tr.rk-flash td { animation: rkFlash 2.4s ease-out 1; }
.ranks-table tbody tr.rk-sep td {
  padding: 0.18rem 0.55rem 0.12rem; text-align: left; font-size: 0.72rem; font-weight: 600;
  color: var(--dim); background: var(--input-bg, var(--panel)); letter-spacing: 0.01em;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.ranks-table tbody tr.rk-sep td span { position: sticky; left: 0.55rem; white-space: nowrap; }
.ranks-table tbody tr.rk-sep td span::before { content: "— "; }
.ranks-table tbody tr.rk-sep td span::after { content: " —"; }
.ranks-table tbody tr.rk-sep:hover td { background: var(--input-bg, var(--panel)); }
:root { --rk-flash: rgba(159, 212, 238, 0.28); }
:root[data-theme="light"] { --rk-flash: rgba(31, 95, 134, 0.22); }
.dist-tip {
  position: absolute; z-index: 5; pointer-events: none;
  max-width: min(20rem, calc(100% - 8px));
  padding: 0.4rem 0.65rem; border-radius: 8px; font-size: 0.8rem; line-height: 1.35;
  background: var(--bg); color: var(--text); border: 1px solid var(--accent);
  border-left-width: 3px; box-shadow: 0 6px 20px var(--shadow);
}
.dist-tip[hidden] { display: none; }
#distSvg .dist-name { cursor: pointer; }
#distSvg .dist-name:hover { text-decoration: underline; }
#distSvg .dist-name:focus-visible { outline: 2px solid var(--accent); }
.dist-tip b { color: var(--accent); }
.dist-note { color: var(--dim); font-size: 0.75rem; margin-top: 0.25rem; }
@media (max-width: 600px) {
  .ranks-table td .pct { display: block; margin-left: 0; line-height: 1.1; }
  .ranks-table-wrap { max-height: calc(100vh - 13rem); }
}

/* t357u: collapsible big table block (same frame as 📊 Distribution) */
.rk-table-section[open] > summary { margin-bottom: 0.5rem; }
.rk-table-section .rk-table-count { color: var(--dim); font-weight: 400; font-size: 0.85rem; }
.rk-table-section .ranks-table-wrap { border-radius: 6px; }

/* t358u: 🏅 positions block folds like the chart / table */
.rk-pos-section[open] > summary { margin-bottom: 0.5rem; }
.rk-pos-section .rk-positions { margin: 0; }
