/* Game header */
.game-header {
  margin-bottom: 20px;
}

.game-header h2 {
  font-family: 'Outfit', sans-serif;
  font-size: 20px;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: -0.3px;
}

.game-header .log-link {
  font-size: 13px;
  color: var(--text-dim);
  word-break: break-all;
}

.game-header .log-link a {
  color: var(--accent-dim);
  text-decoration: none;
}

.game-header .log-link a:hover { text-decoration: underline; }

/* Filters panel — "Filters" heading + cumulative severity slider + tier labels,
   sitting above the summary bar (which reflects the slider). */
.filters-panel {
  background: var(--bg-card);
  border-radius: 8px;
  padding: 10px 16px 12px;
  margin-bottom: 12px;
}
.filters-head {
  font-family: 'Outfit', sans-serif;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-dim);
  margin-bottom: 8px;
}
.filters-row {
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-width: 440px;
}
.sev-slider {
  width: 100%;
  height: 6px;
  margin: 2px 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.sev-ticks {
  display: flex;
  justify-content: space-between;
}
/* Severity tier labels under the slider double as click targets. Off tiers are
   dimmed; the slider level lights them up cumulatively (Severe..Unsure). */
.sev-tick {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  opacity: 0.45;
  cursor: pointer;
  padding: 1px 4px;
  border-radius: 4px;
  transition: opacity 0.12s ease, color 0.12s ease;
}
.sev-tick.on {
  opacity: 1;
  color: var(--tick);
}
.sev-tick:hover {
  opacity: 1;
}

/* Summary bar */
.summary-bar {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  padding: 12px 16px;
  background: var(--bg-card);
  border-radius: 8px;
  margin-bottom: 20px;
  font-size: 13px;
}

.summary-bar .stat {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.summary-bar .stat .value {
  font-size: 18px;
  font-weight: 700;
  color: var(--accent);
}

.summary-bar .stat .label {
  color: var(--text-dim);
  font-size: 11px;
  text-transform: uppercase;
}

/* Concept-level EV breakdown — two ledgers at the top of a game. */
/* Two ledgers side by side, each filling half the full content width. Collapses
   to a single column only when there's genuinely no room. */
.concept-breakdown {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-bottom: 20px;
}
.concept-ledger {
  background: var(--bg-card);
  border-radius: 8px;
  padding: 12px 14px;
}
.concept-ledger-head {
  display: flex;
  flex-direction: column;
  margin-bottom: 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border, rgba(255, 255, 255, 0.08));
}
.concept-ledger-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
}
.concept-ledger-sub {
  font-size: 11px;
  color: var(--text-dim);
}
/* pill (fills) | severity chips | EV. EV is the last column and flush-right
   (justify-self:end), so every row's EV right-edge lands on the same vertical
   line no matter how many severity chips precede it — the chip count is absorbed
   by the 1fr pill, never by the EV column. */
.concept-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
  font-size: 12px;
}
/* First column: the group pill plus its per-dim sub-pills, inline on one row
   (wraps if there are many). */
.concept-row-left {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}
/* The concept rendered as a group-coloured pill. `--grp` is the
   group colour (compare-dimensions.GROUP_META), set inline per row. */
.concept-pill {
  justify-self: start;
  padding: 2px 9px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 700;
  color: var(--grp);
  background: color-mix(in srgb, var(--grp) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--grp) 38%, transparent);
}
/* Clickable pills double as the rounds-view concept filter. */
.concept-pill-btn {
  cursor: pointer;
  transition: filter 0.12s ease, opacity 0.12s ease, box-shadow 0.12s ease;
}
.concept-pill-btn:hover {
  filter: brightness(1.25);
}
/* Selected filter: solid fill so the active concept reads as a pressed control. */
.concept-pill-active {
  color: var(--bg, #1a1a1a);
  background: var(--grp);
  border-color: var(--grp);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--grp) 45%, transparent);
}
/* Non-selected pills recede while a filter is active. */
.concept-pill-dim {
  opacity: 0.5;
}
.concept-pill-dim:hover {
  opacity: 1;
}
.concept-ev {
  justify-self: end;
  color: var(--accent);
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.concept-tiers {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}
/* Per-dim sub-pills next to a group pill (Tanyao, Yakuhai, Dora, Dora
   acceptance…). Each is a small group-coloured chip carrying its own EV. */
.concept-sub {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 1px 4px 1px 8px;
  border-radius: 9px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--grp);
  background: color-mix(in srgb, var(--grp) 11%, transparent);
  border: 1px solid color-mix(in srgb, var(--grp) 28%, transparent);
}
.concept-sub-ev {
  padding: 0 5px;
  border-radius: 7px;
  background: color-mix(in srgb, var(--grp) 22%, transparent);
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
/* Sub-pills are clickable filters too (narrower than their group pill). */
.concept-sub-btn {
  cursor: pointer;
  transition: filter 0.12s ease, opacity 0.12s ease, box-shadow 0.12s ease;
}
.concept-sub-btn:hover {
  filter: brightness(1.25);
}
.concept-sub-active {
  color: var(--bg, #1a1a1a);
  background: var(--grp);
  border-color: var(--grp);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--grp) 45%, transparent);
}
.concept-sub-active .concept-sub-ev {
  background: color-mix(in srgb, #000 22%, transparent);
  color: var(--bg, #1a1a1a);
}
.concept-sub-dim {
  opacity: 0.5;
}
.concept-sub-dim:hover {
  opacity: 1;
}
/* Disclaimer under the breakdown: one mistake can win pills in several concepts,
   so a row's EV is attributed to every concept it touches (columns don't sum to
   total EV). */
.concept-note {
  grid-column: 1 / -1;
  margin-top: 2px;
  font-size: 11px;
  font-style: italic;
  color: var(--text-dim);
}

/* Trade-off boxes — stacked below the "Losing points here" ledger inside
   .concept-breakdown, replacing the old "Overvaluing these" ledger. One box per
   trade-off axis, stacked vertically; each box lists individual mistakes as
   "your play vs better play" rows. */
.tradeoff-boxes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.tradeoff-box {
  background: var(--bg-card);
  border-radius: 8px;
  padding: 12px 14px;
}
.tradeoff-box-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.tradeoff-box-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
}
.tradeoff-box-ev {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
/* You | AI column layout — mirrors the mistake-view comparison: a red You band
   and a green AI band split by a vertical divider, under column labels. The
   header + all rows live in ONE grid (.tradeoff-grid) and inherit its column
   tracks via subgrid, so the divider is a single straight line across every row
   (a per-row grid would let the auto EV column drift the split). Row gap is 0 so
   the tinted bands read as continuous columns. Third column = shared EV + jump. */
.tradeoff-grid {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  margin-top: 4px;
}
.tradeoff-colhead,
.tradeoff-row {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;
  align-items: stretch;
  font-size: 12px;
}
.tradeoff-colhead {
  align-items: center;
}
.to-colhead {
  padding: 3px 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
}
.to-colhead-you { color: var(--sev-major); border-bottom: 2px solid color-mix(in srgb, var(--sev-major) 45%, transparent); }
.to-colhead-ai  { color: var(--sev-minor); border-bottom: 2px solid color-mix(in srgb, var(--sev-minor) 45%, transparent); }
.to-pole {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 5px;
  min-width: 0;
  padding: 5px 8px;
}
/* You = red band, AI = green band, split by a divider (border on the You cell so
   it runs down both header and rows). Tints match .col-actual / .col-expected. */
.to-pole-you {
  background: rgba(239, 83, 80, 0.08);
  border-right: 1px solid var(--border, rgba(255, 255, 255, 0.1));
}
.to-pole-ai { background: rgba(102, 187, 106, 0.08); }
.to-pole-empty { color: var(--text-dim); }
.to-pole .tile-sm { width: 20px; height: auto; vertical-align: middle; }
.to-end {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 0 5px 10px;
}
.to-ev {
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.to-goto {
  justify-self: end;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 5px;
  font-weight: 700;
  text-decoration: none;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  transition: background 0.12s ease, filter 0.12s ease;
}
.to-goto:hover { filter: brightness(1.3); background: color-mix(in srgb, var(--accent) 26%, transparent); }
.to-goto-off { color: var(--text-dim); background: transparent; cursor: default; }

.filter-banner {
  padding: 8px 14px;
  margin-bottom: 14px;
  border-radius: 6px;
  background: rgba(255, 183, 77, 0.1);
  border: 1px solid rgba(255, 183, 77, 0.25);
  color: #ffb74d;
  font-size: 13px;
}

/* Concept-filter banner: carries an inline group pill + a clear button. */
.concept-filter-banner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}
.concept-filter-banner .concept-pill {
  cursor: default;
}
.concept-filter-clear {
  margin-left: auto;
  padding: 3px 10px;
  border-radius: 6px;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.concept-filter-clear:hover {
  background: rgba(255, 183, 77, 0.15);
}

.categorization-banner {
  padding: 8px 14px;
  margin-bottom: 14px;
  border-radius: 6px;
  font-size: 13px;
}
.categorization-banner.pending {
  background: rgba(100, 181, 246, 0.1);
  border: 1px solid rgba(100, 181, 246, 0.25);
  color: #64b5f6;
}
.categorization-banner.failed {
  background: rgba(239, 83, 80, 0.1);
  border: 1px solid rgba(239, 83, 80, 0.25);
  color: #ef5350;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.cat-progress-bar {
  margin-top: 8px;
  height: 6px;
  background: rgba(100, 181, 246, 0.15);
  border-radius: 3px;
  overflow: hidden;
}
.cat-progress-fill {
  height: 100%;
  background: #64b5f6;
  border-radius: 3px;
  transition: width 0.5s ease;
}

/* Round */
.round {
  margin-bottom: 16px;
}

.round-header {
  font-size: 14px;
  font-weight: 700;
  padding: 6px 12px;
  background: var(--bg-card);
  border-radius: 6px;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.round-header .outcome {
  font-size: 16px;
}

.round-header .round-count {
  font-weight: 400;
  font-size: 12px;
  color: var(--text-dim);
}

/* Game rating */
.game-rating-icon {
  font-size: 13px;
  color: var(--sev-minor);
}

.game-rating {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 8px;
  margin-bottom: 16px;
  font-size: 13px;
  font-weight: 600;
}

.game-rating.rating-excellent {
  background: rgba(102, 187, 106, 0.1);
  color: var(--sev-minor);
  border: 1px solid rgba(102, 187, 106, 0.25);
}

.game-rating.rating-great {
  background: rgba(79, 195, 247, 0.08);
  color: var(--accent);
  border: 1px solid rgba(79, 195, 247, 0.2);
}

.game-rating-star {
  font-size: 18px;
}

.game-rating-detail {
  font-weight: 400;
  opacity: 0.7;
  margin-left: 4px;
}

/* Clean round */
.clean-badge {
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 3px;
  background: rgba(102, 187, 106, 0.15);
  color: var(--sev-minor);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* Mistake card.
   Severity colours come from --sev-color / --sev-tint, which the .sev-*
   modifier classes (defined in style-theme.css) set on the host element. */
.mistake {
  padding: 10px 14px;
  background: var(--bg-card);
  border-radius: 8px;
  margin-bottom: 6px;
  border-left: 3px solid var(--sev-color, var(--border));
  transition: border-color 0.15s;
}

/* Brief highlight when navigated to via #m<id>, so the target card
   doesn't blend into the round it lives in once scrolled into view. */
.mistake.mistake-flash {
  animation: mistake-flash-anim 1.8s ease-out;
}
@keyframes mistake-flash-anim {
  0%   { box-shadow: 0 0 0 2px var(--accent), 0 0 14px rgba(79, 195, 247, 0.5); }
  100% { box-shadow: 0 0 0 2px transparent, 0 0 14px rgba(79, 195, 247, 0); }
}

.mistake-top {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.mistake .turn-num {
  font-weight: 700;
  font-size: 14px;
  min-width: 28px;
  white-space: nowrap;
}

.severity {
  font-weight: 700;
  font-size: 13px;
  padding: 1px 6px;
  border-radius: 4px;
  color: var(--sev-color);
  background: var(--sev-tint);
}

.ev-loss {
  font-size: 13px;
  color: var(--text-dim);
}

.shanten {
  font-size: 12px;
  color: var(--text-dim);
  background: var(--bg);
  padding: 1px 6px;
  border-radius: 4px;
}

.discard-comparison {
  font-size: 13px;
}

.discard-comparison .played { color: var(--sev-major); }
.discard-comparison .ai { color: var(--sev-minor); }

/* Yaku panel (v1.3) — right-aside strip of pills on each opened seat's row,
   one pill per yaku that survives the seat's melds. Green = locked (✓),
   gold = possible (◐); yakuhai carries tile chips, honitsu a suit tile (+清
   pip when chinitsu is alive). Each pill lifts a hover detail above the row. */
.yaku-strip {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
/* Column label introducing the pill strip ("Possible yakus  [pill] [pill]"). */
.yaku-strip .yp-label {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-dim);
  white-space: nowrap;
  margin-right: 2px;
}

.yp {
  position: relative;
  cursor: help;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 10px;
  line-height: 16px;
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.yp.locked {
  color: #9fd9a2;
  background: rgba(102, 187, 106, 0.10);
  border-color: rgba(102, 187, 106, 0.5);
}
.yp.possible {
  color: #d8b766;
  background: rgba(201, 166, 87, 0.07);
  border-color: rgba(201, 166, 87, 0.4);
}
.yp .yp-state { font-size: 10px; line-height: 1; font-weight: 700; }
.yp.locked   .yp-state { color: #66bb6a; }
.yp.possible .yp-state { color: #c9a657; }
.yp .yp-name { font-size: 10px; letter-spacing: 0.2px; }
.yp.yp-empty {
  cursor: default;
  color: var(--text-dim);
  opacity: 0.7;
}

/* Inline tile chips — shared by the yakuhai pill (count chips) and the
   honitsu pill (suit chips). */
.yp .yp-tiles {
  display: inline-flex;
  gap: 2px;
  align-items: center;
  margin-left: 2px;
  padding-left: 4px;
  border-left: 1px solid rgba(255, 255, 255, 0.08);
}
.yp .yp-suit-tile {
  height: 16px;
  width: auto;
  border: 0;
  border-radius: 2px;
}
/* Chinitsu upgrade marker — green pip after the suit tile(s). */
.yp .yp-upgrade {
  display: inline-flex;
  align-items: center;
  margin-left: 3px;
  padding: 0 4px;
  border-radius: 8px;
  font-size: 9px;
  font-weight: 700;
  background: rgba(102, 187, 106, 0.15);
  color: #9fd9a2;
  border: 1px solid rgba(102, 187, 106, 0.4);
  line-height: 13px;
}
.yp .yp-tile-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 9.5px;
}
.yp .yp-tile-chip .tile {
  height: 16px;
  width: auto;
  border: 0;
}
.yp .yp-tile-chip .yp-tile-count {
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.yp.locked .yp-tile-chip.is-locked .tile {
  outline: 1.5px solid #66bb6a;
  outline-offset: 1px;
  border-radius: 2px;
}
.yp.locked .yp-tile-chip.is-locked .yp-tile-count { color: #9fd9a2; }
/* A reachable yakuhai where one copy sits in YOUR hand — the tile you're being
   warned not to discard. Warmer accent than a plain possible chip. */
.yp .yp-tile-chip.yp-tile-chip-inhand {
  padding: 0 3px;
  border-radius: 6px;
  background: rgba(255, 169, 77, 0.12);
  border: 1px solid rgba(255, 169, 77, 0.55);
}
.yp .yp-tile-chip.yp-tile-chip-inhand .yp-tile-count { color: #ffc98a; }

/* Hover detail — lifts above the discard row. */
.yp .yp-detail {
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 11px;
  color: var(--text);
  width: 240px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
  z-index: 50;
  line-height: 1.4;
  white-space: normal;
  text-align: left;
}
.yp .yp-detail b { color: var(--text); }
.yp .yp-detail .muted { color: var(--text-dim); }
.yp:hover .yp-detail { opacity: 1; pointer-events: auto; }
.yp.yp-empty .yp-detail { display: none; }

/* ── Dead yakuhai pill + collapsible toggle (v1.3 dead row) ───────────
   Surfaces yakuhai honors whose pon is no longer possible (unseen<2 or
   live<3 and not melded). Hidden by default behind a dashed "N dead ▸"
   toggle at the end of the strip; expanded inline on click. Dead
   sanshoku/ittsuu (`.yp.ss.dead`) ride the same toggle — they keep their
   v1.5 strike-through styling, but :not(.ss) below applies the dim/dashed
   look only to yakuhai pills (where the strike is on the .yp-name span). */
.yp.dead:not(.ss) {
  color: var(--text-dim);
  background: transparent;
  border-color: var(--border);
  border-style: dashed;
  opacity: 0.7;
}
.yp.dead:not(.ss) .yp-name {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(211, 84, 84, 0.7);
}
.yp.dead:not(.ss) .yp-state { color: #d35454; }
.yp.dead:not(.ss) .yp-tile-chip img.tile {
  filter: grayscale(1) brightness(0.78);
  outline: 1.5px solid rgba(211, 84, 84, 0.55);
  outline-offset: 1px;
  border-radius: 2px;
}
.yp.dead:not(.ss) .yp-tile-chip .yp-tile-count {
  color: #d35454;
  font-weight: 700;
}

/* Both the eliminated (.dead) pills and the demoted-but-live (.yp-more) pills
   stay hidden until the "more" toggle expands the strip. */
.yaku-strip .yp.dead,
.yaku-strip .yp.yp-more,
.yaku-strip .yp-dead-sep { display: none; }
.yaku-strip[data-expanded="true"] .yp.dead,
.yaku-strip[data-expanded="true"] .yp.yp-more,
.yaku-strip[data-expanded="true"] .yp-dead-sep { display: inline-flex; }

.yp-dead-sep {
  width: 1px;
  height: 14px;
  background: var(--border);
  margin: 0 4px;
  align-self: center;
}

.yp-dead-toggle {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 6px 1px 7px;
  border-radius: 999px;
  font-size: 10px;
  line-height: 16px;
  color: var(--text-dim);
  background: transparent;
  border: 1px dashed var(--border);
  cursor: pointer;
  font-family: inherit;
  user-select: none;
  transition: color 0.12s, border-color 0.12s;
}
.yp-dead-toggle:hover {
  color: var(--text);
  border-color: rgba(211, 84, 84, 0.5);
}
.yp-dead-toggle .toggle-arrow {
  font-size: 8px;
  line-height: 1;
  transition: transform 0.15s ease;
}
.yaku-strip[data-expanded="true"] .yp-dead-toggle {
  color: var(--text);
  border-color: rgba(211, 84, 84, 0.5);
}
.yaku-strip[data-expanded="true"] .yp-dead-toggle .toggle-arrow {
  transform: rotate(90deg);
}

/* ── Sanshoku pill (v1.5) ─────────────────────────────────────────────
   Variant B in the strip: run number + the run's start tile per suit
   (opaque + green outline = melded, dim = pending, dim + red = dead). Two
   new states beyond locked/possible: close (2/3, orange — one tile from the
   yaku, worth a defensive read) and dead (strike + ×). Hover lifts Variant D
   below. */
.yp.ss.close {
  color: #f0c674;
  background: rgba(255, 167, 38, 0.08);
  border-color: rgba(255, 167, 38, 0.45);
}
.yp.ss.close .yp-state { color: #ffa726; }
.yp.ss.dead {
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.02);
  border-color: var(--border);
  opacity: 0.6;
}
.yp.ss.dead .yp-state { color: var(--sev-major); }
.yp.ss.dead .yp-name,
.yp.ss.dead .yp-seq {
  text-decoration: line-through;
  text-decoration-color: rgba(239, 83, 80, 0.7);
  text-decoration-thickness: 1px;
}
.yp .yp-seq {
  font-family: 'Outfit', sans-serif;
  font-weight: 500;
  font-size: 10.5px;
  color: var(--text);
  letter-spacing: 0.4px;
  padding: 0 1px;
}
.yp.ss.dead .yp-seq { color: var(--text-dim); }
.yp .yp-ss-tile {
  height: 16px;
  width: auto;
  border: 0;
  border-radius: 2px;
  background: #f6f4ec;
  opacity: 0.32;
  filter: grayscale(0.4);
}
.yp .yp-ss-tile.done {
  opacity: 1;
  filter: none;
  outline: 1.5px solid #66bb6a;
  outline-offset: 1px;
}
.yp .yp-ss-tile.dead {
  opacity: 0.18;
  filter: grayscale(1);
  outline: 1.5px solid rgba(239, 83, 80, 0.5);
  outline-offset: 1px;
}

/* Variant D popover — full sequence per suit with copies-remaining counts. */
.yp .ss-detail {
  width: auto;
  min-width: 250px;
  max-width: 340px;
  padding: 10px 12px 11px;
}
.yp .ss-detail-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.yp .ss-detail-head .ssd-title {
  font-family: 'Outfit', sans-serif;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text);
}
.yp .ss-detail-head .ssd-state { font-size: 10px; margin-left: auto; }
.yp .ssd-state.locked   { color: #9fd9a2; }
.yp .ssd-state.close    { color: #ffa726; }
.yp .ssd-state.possible { color: #d8b766; }
.yp .ssd-state.dead     { color: var(--sev-major); }
.yp .ss-detail-rows {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 8px 10px;
  align-items: center;
}
.yp .ssd-row { display: contents; }
.yp .ssd-suit {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: 'Outfit', sans-serif;
  font-size: 10.5px;
  color: var(--text-dim);
  letter-spacing: 0.4px;
}
.yp .ssd-suit .ssd-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.yp .ssd-suit.m .ssd-dot { background: var(--tile-m); }
.yp .ssd-suit.p .ssd-dot { background: var(--tile-p); }
.yp .ssd-suit.s .ssd-dot { background: var(--tile-s); }
.yp .ssd-tiles { display: inline-flex; gap: 3px; }
.yp .ssd-tile {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}
.yp .ssd-tile img.tile {
  height: 24px;
  width: auto;
  border: 0;
  border-radius: 3px;
  background: #f6f4ec;
  opacity: 0.4;
  filter: grayscale(0.3);
}
.yp .ssd-tile .ssd-count {
  font-family: 'Outfit', sans-serif;
  font-size: 9px;
  line-height: 1;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  min-width: 10px;
  text-align: center;
}
.yp .ssd-status {
  font-family: 'Outfit', sans-serif;
  font-size: 10px;
  letter-spacing: 0.3px;
  white-space: nowrap;
}
/* Done row — full-opacity tiles + green outline, counts hidden. */
.yp .ssd-row.done .ssd-tile img.tile {
  opacity: 1;
  filter: none;
  outline: 1.5px solid #66bb6a;
  outline-offset: 1px;
}
.yp .ssd-row.done .ssd-count { visibility: hidden; }
.yp .ssd-row.done .ssd-status { color: #9fd9a2; }
/* Pending row — dim tiles, count = copies remaining. */
.yp .ssd-row.possible .ssd-tile.low .ssd-count { color: #f0c674; }
.yp .ssd-row.possible .ssd-status { color: var(--text-dim); font-variant-numeric: tabular-nums; }
.yp .ssd-row.possible.low .ssd-status { color: #f0c674; }
/* Deal-in tile — a last copy you hold (0 unseen). Warm amber outline + count,
   matching the yakuhai in-hand chip: the tile you're warned not to discard. */
.yp .ssd-tile.dealin img.tile {
  opacity: 0.85;
  filter: none;
  outline: 1.5px solid rgba(255, 169, 77, 0.7);
  outline-offset: 1px;
}
.yp .ssd-tile.dealin .ssd-count { color: #ffc98a; font-weight: 600; }
.yp .ssd-row.possible.dealin .ssd-status { color: #ffc98a; font-weight: 500; }
/* Dead row — the exhausted tile gets a red outline + 0. */
.yp .ssd-row.dead .ssd-tile img.tile { opacity: 0.25; filter: grayscale(1); }
.yp .ssd-row.dead .ssd-tile.zero img.tile {
  opacity: 0.18;
  outline: 1.5px solid rgba(239, 83, 80, 0.7);
  outline-offset: 1px;
}
.yp .ssd-tile.zero .ssd-count { color: var(--sev-major); font-weight: 700; }
/* Suit killed by two last-copies in hand — outline both so it's clear which
   pair can't both be fed. */
.yp .ssd-row.dead .ssd-tile.dealin img.tile {
  outline: 1.5px solid rgba(255, 169, 77, 0.6);
  outline-offset: 1px;
}
.yp .ssd-row.dead .ssd-status { color: var(--sev-major); font-weight: 500; }
.yp .ss-detail-foot {
  margin-top: 9px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 10.5px;
  color: var(--text-dim);
  line-height: 1.45;
}
.yp .ss-detail-foot b { color: var(--text); font-weight: 500; }

/* Pills for non-tile actions on the mistake header comparison line —
   mirrors the pill styling used in the discards view. */
.action-pill {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 1px 8px;
  border-radius: 999px;
  vertical-align: middle;
  line-height: 16px;
  text-transform: uppercase;
}
.action-riichi {
  color: #ffa94d;
  background: rgba(255, 169, 77, 0.1);
  border: 1px solid rgba(255, 169, 77, 0.5);
}
.action-pass {
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
}
.action-win {
  color: var(--sev-minor);
  background: rgba(102, 187, 106, 0.12);
  border: 1px solid rgba(102, 187, 106, 0.5);
}
.discard-comparison .played .action-pill { box-shadow: 0 0 0 1px rgba(239,83,80,0.4); }
.discard-comparison .ai .action-pill { box-shadow: 0 0 0 1px rgba(102,187,106,0.4); }

.meld-group {
  display: inline-flex;
  align-items: flex-end;
  gap: 1px;
  padding: 2px 6px;
  background: var(--bg);
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  margin-right: 4px;
}
.meld-wind {
  font-size: 9px;
  color: var(--text-dim);
  margin-left: 1px;
  vertical-align: super;
}
.meld-called {
  display: inline-flex;
  align-items: flex-end;
}
.meld-called > .tile {
  transform: rotate(90deg);
  margin: -3px 0;
  /* Dashed outline mirrors the called tile's ghost in the discard pool
     (.tile.ghost-tile) so the eye links "thrown here" to "called into here". */
  border: 2px dashed var(--text-dim);
  border-radius: 3px;
}
.meld-kakan {
  position: relative;
  margin-top: 18px;
}
.meld-kakan-added {
  position: absolute;
  bottom: calc(100% - 6px);
  left: 0;
}
.meld-kakan-added > .tile {
  transform: rotate(90deg);
  margin: -3px 0;
}

.action-meld {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  font-size: 12px;
  font-weight: 600;
  vertical-align: middle;
}

.discard-comparison .played .tile,
.discard-comparison .played .action-text {
  border-color: var(--sev-major);
  box-shadow: 0 0 4px rgba(239,83,80,0.3);
}

.discard-comparison .ai .tile,
.discard-comparison .ai .action-text {
  border-color: var(--sev-minor);
  box-shadow: 0 0 4px rgba(102,187,106,0.3);
}

.discard-comparison .arrow {
  margin: 0 4px;
  color: var(--text-dim);
  vertical-align: middle;
}

/* Top actions */
.top-actions {
  margin-top: 6px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12px;
}

.top-action {
  padding: 3px 8px;
  background: var(--bg);
  border-radius: 4px;
  color: var(--text-dim);
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.top-action .tile { height: 26px; }

.top-action:first-child { color: var(--sev-minor); }

.top-action .prob {
  opacity: 0.6;
}

/* EV Comparison table */
.ev-comparison {
  margin-top: 8px;
  overflow-x: auto;
}

.ev-table {
  border-collapse: collapse;
  font-size: 12px;
  width: 100%;
}

.ev-table th {
  font-size: 10px;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 3px 8px;
  text-align: right;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.ev-table th:first-child { text-align: left; }

.ev-table td {
  padding: 4px 8px;
  text-align: right;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}

.ev-table td:first-child { text-align: left; }

.ev-table .tile-cell {
  display: flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}

.ev-tile { height: 26px; }

/* Shanten pill sits to the left of each discard glyph in the column header.
   Colour is a grey→gold gradient keyed on the shanten value (tenpai = gold,
   matching the "Mortal raised shanten" badge; higher shanten steps toward
   grey). The colour/background/border are set inline per pill — see
   shantenPillStyle() in ev-table.js. */
.ev-table .shanten-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  padding: 1px 5px;
  border-radius: 9px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
  text-transform: lowercase;
}

/* Riichi / dama pill in the column header for 5A/5B riichi decisions. Sits
   next to the shanten pill and the discard glyph. Riichi reads as the bold
   "committed" call (gold), dama as the quieter "stay closed" alternative
   (grey/blue), mirroring how the rest of the UI tints those choices. */
.ev-table .reach-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 1px 6px;
  border-radius: 9px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  text-transform: lowercase;
  letter-spacing: 0.02em;
}
.ev-table .reach-pill-riichi {
  color: #ffcb80;
  background: rgba(255, 165, 0, 0.14);
  border: 1px solid rgba(255, 165, 0, 0.5);
}
.ev-table .reach-pill-dama {
  color: #8fb8e6;
  background: rgba(100, 150, 230, 0.12);
  border: 1px solid rgba(100, 150, 230, 0.4);
}

.ev-table .mortal-col { color: #81c784; }
.ev-table .shanten-col { color: #64b5f6; }
.ev-table .dealin-col { color: var(--text-dim); font-variant-numeric: tabular-nums; }
/* Dealin cells are bold; colour comes from an inline HSL gradient driven
   by the deal-in rate. Safe cells still use the theme green for visual
   consistency with the "Safe" label. */
.ev-table .dealin-cell { font-weight: 700; }
.ev-table .dealin-genbutsu { color: var(--sev-minor); font-weight: 700; }
/* Legacy classes kept for any pre-gradient call sites. */
.ev-table .dealin-suji { color: var(--sev-medium); font-weight: 700; }
.ev-table .dealin-no-suji { color: var(--sev-major); font-weight: 700; }
.ev-table .dim { color: var(--border); }

.waits-row > .waits-row-cell {
  padding: 4px 8px 6px 8px;
  font-size: 11px;
  color: var(--text-dim);
  border-top: none;
}
.waits-row-label {
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-right: 6px;
  opacity: 0.75;
}
.waits-row-list {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
  vertical-align: middle;
}
.waits-entry {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 5px;
  background: rgba(100, 181, 246, 0.06);
  border: 1px solid rgba(100, 181, 246, 0.18);
  border-radius: 3px;
}
/* Suji / half-suji badge prepended to the waits list: shows the specific
   opponent-discard partner that provides (partial) protection against the
   tile's ryanmen wait. Full = both partners for middle tiles, or the single
   partner for edge tiles. Half = only one partner for middle tiles. */
.waits-suji-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 600;
}
.waits-suji-label {
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-size: 10px;
}
.waits-cluster {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
  gap: 2px;
}
.waits-tiles {
  display: inline-flex;
  gap: 1px;
}
.waits-tile-img { height: 18px; }
.waits-left {
  color: var(--text-dim);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.2px;
  min-height: 12px;
}
.waits-rate {
  color: var(--sev-medium);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.waits-entry { cursor: help; }
.waits-entry.waits-entry-dead {
  background: rgba(100, 181, 246, 0.02);
  border-color: rgba(100, 181, 246, 0.08);
  opacity: 0.55;
}
.waits-dead { color: var(--text-dim); font-weight: 500; }

/* Deal-in cell rendered as a sum: per-wait pills joined by "+", the tile's
   total deal-in rate after "=". Center every term vertically so the operators
   and the trailing sum line up with the tile-bearing wait pills. */
.dealin-sum { align-items: center; }
.dealin-sum-op,
.dealin-sum-eq {
  color: var(--text-dim);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Developer IDs — muted, barely-there tags so the owner can jump to a game or
   mistake by number without cluttering the UI for normal users. */
.dev-id {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 10px;
  font-weight: 400;
  color: var(--text-dim);
  opacity: 0.35;
  margin-left: 4px;
  letter-spacing: 0;
  text-decoration: none;
  cursor: pointer;
}
.dev-id:hover { opacity: 0.75; text-decoration: underline; }

/* Furiten — loudest 5A signal, worth a dedicated tag. */
.furiten-badge {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 1px 6px;
  color: #ff9999;
  background: rgba(255, 107, 107, 0.12);
  border: 1px solid rgba(255, 107, 107, 0.5);
  border-radius: 4px;
}
.raised-shanten-badge {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 1px 6px;
  color: #ffcb80;
  background: rgba(255, 165, 0, 0.12);
  border: 1px solid rgba(255, 165, 0, 0.5);
  border-radius: 4px;
  cursor: help;
}
/* All-last (final round) — situational chip rather than a mistake-quality
   warning. Cool gold/amber to evoke endgame without competing with the red
   defense palette or the orange raised-shanten warning. */
.all-last-badge {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 1px 6px;
  color: #ffe39a;
  background: rgba(255, 200, 80, 0.10);
  border: 1px solid rgba(255, 200, 80, 0.45);
  border-radius: 4px;
  cursor: help;
}
.furiten-alert {
  display: inline-block;
  font-weight: 700;
  color: #ff9999;
  padding: 1px 6px;
  margin-right: 4px;
  background: rgba(255, 107, 107, 0.12);
  border: 1px solid rgba(255, 107, 107, 0.5);
  border-radius: 4px;
}
.furiten-tile { height: 18px; margin: 0 1px; vertical-align: middle; }
.furiten-wait-tile { height: 18px; margin: 0 1px; vertical-align: middle; opacity: 0.85; }

/* Tenpai-waits row on 5A / 5B mistake cards — sits under the discards so the
   student can visually tie waits to what's been thrown. */
.tenpai-waits-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  margin: 6px 0;
  background: rgba(74, 158, 255, 0.05);
  border-left: 3px solid rgba(74, 158, 255, 0.4);
  border-radius: 3px;
  font-size: 11px;
}
.tenpai-waits-label {
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 600;
}
.tenpai-waits-tiles {
  display: inline-flex;
  gap: 2px;
}
.ev-table .best-val { font-weight: 700; }

.ev-table .row-actual { background: rgba(239,83,80,0.08); }
.ev-table .row-expected { background: rgba(102,187,106,0.08); }

/* ---- Transposed (column) EV layout ------------------------------------
   Picks (You / AI) are columns; attributes (acceptance, EV, shanten,
   deal-in, type, waits) are rows. The first column of every row is the
   axis label (.ev-axis, a left-aligned <th>); data cells centre under
   each pick's tile. You/AI columns get the same red/green tint the old
   row layout used, applied per-cell via .col-actual / .col-expected. */
/* Fixed layout so the axis-label column and the pick columns are the same
   width on every mistake card — content (ukeire chips, wait shapes) wraps
   within its cell instead of stretching the column. The two pick columns
   share the remaining width equally; with table-layout:fixed any column
   without an explicit width splits the leftover evenly. */
.ev-table-cols { table-layout: fixed; }
.ev-table-cols td { text-align: center; vertical-align: middle; }
.ev-table-cols th.ev-axis {
  width: 150px;
  text-align: left;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  font-weight: 600;
  white-space: normal;
}
.ev-table-cols thead th.ev-axis { border-bottom: 1px solid var(--border); }
.ev-table-cols th.ev-col-head {
  text-align: center;
  border-bottom: 1px solid var(--border);
}
.ev-table-cols th.ev-col-head .tile-cell {
  display: inline-flex;
  justify-content: center;
}
.ev-table-cols .col-actual { background: rgba(239,83,80,0.08); }
.ev-table-cols .col-expected { background: rgba(102,187,106,0.08); }

/* Mobile: drop the axis-label column ("Tile acceptance" / "Deal-in" /
   "Summary") to give the pick columns the full width. The labels are
   redundant once you know the row order, and the extra room matters more on a
   narrow screen. With table-layout:fixed the two pick columns reclaim the
   freed space automatically. */
@media (max-width: 640px) {
  .ev-table-cols th.ev-axis { display: none; }
}
/* Acceptance cell holds the diff/full ukeire chips; let it wrap and centre. */
.ev-table-cols .ukeire-acc-cell {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}
.ev-table-cols .ukeire-acc { justify-content: center; }

/* ---- Riichi/dama "Value" row (5A/5B) ---------------------------------------
   Replaces the tile-acceptance row on riichi decisions: each pick's column
   shows the point value of its own call (riichi vs dama), scored per wait. */
.ev-table-cols .rsc-cell { display: flex; justify-content: center; }
/* 3-column grid — pills | wait tiles | point values — so the tile column
   left-aligns across every wait group (each group is `display: contents`, so
   its three children drop straight into the shared columns). Sized to content
   and centered by .rsc-cell. */
.ev-table .rsc {
  display: inline-grid;
  grid-template-columns: auto auto auto;
  gap: 6px 8px;
  align-items: center;
}
.ev-table .rsc-group { display: contents; }
.ev-table .rsc-tiles { display: inline-flex; gap: 6px; flex-shrink: 0; }
/* One wait tile + its live count, stacked. Mirrors the old EV-bars tile column
   so "how many of this wait are live" reads at a glance. */
.ev-table .rsc-tile-entry {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}
.ev-table .rsc-count {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.ev-table .rsc-count-furiten {
  color: var(--sev-major, #ef5350);
  text-decoration: line-through;
}
.ev-table .rsc-vals {
  display: flex;
  flex-direction: column;
  gap: 1px;
  align-items: flex-start;
  font-variant-numeric: tabular-nums;
}
/* Yaku/dora pills already present on the wait — first grid column, to the LEFT
   of the wait tiles, right-aligned so they hug the tile column. */
.ev-table .rsc-yaku {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  justify-content: flex-end;
  justify-self: end;
}
.ev-table .rsc-yaku .yaku-none {
  font-size: 10.5px;
  font-style: italic;
  color: var(--text-dim);
}
.ev-table .rsc-line { display: flex; gap: 6px; align-items: baseline; line-height: 1.35; }
.ev-table .rsc-mode {
  min-width: 38px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}
.ev-table .rsc-pts { font-weight: 700; font-size: 13px; }
/* Han/fu trailing the points, e.g. "1,300 (1 han · 40 fu)" — dimmed so the
   point total stays the headline. */
.ev-table .rsc-hanfu {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
/* Riichi column reads gold/committed; dama quieter blue — matching the header
   riichi/dama pills. */
.ev-table .rsc-riichi .rsc-pts { color: #ffcb80; }
.ev-table .rsc-dama .rsc-pts { color: #8fb8e6; }
.ev-table .rsc-bonus .rsc-mode,
.ev-table .rsc-bonus .rsc-pts { color: var(--text-dim); font-weight: 600; font-size: 11px; }
.ev-table .rsc-noyaku .rsc-pts { color: var(--text-dim); font-weight: 600; font-style: italic; }
/* Deal-in cell stacks the rate over its contributing wait shapes (the old
   separate "Deal-in waits" row is folded in here). */
.ev-table-cols .dealin-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}
.ev-table-cols .dealin-stack .waits-row-list { justify-content: center; }

/* Multi-threat deal-in: one row per live opponent (seat wind · its wait shapes ·
   its deal-in %), stacked, with the aggregated total on the final "=" line.
   Each row is a 3-column grid so the seat chips and rates align across rows. */
.ev-table-cols .dealin-multi { gap: 3px; align-items: stretch; }
.dealin-threat-line {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 2px 4px;
  border-radius: 4px;
}
.dealin-threat-line + .dealin-threat-line { border-top: 1px solid rgba(255,255,255,0.04); }
.dealin-threat-seat {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-dim);
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: help;
}
/* Tint the wind box to match the discard-row danger pills for the threat it
   represents — riichi reads red (.riichi-tag), an open threat reads amber
   outlined (.danger-tag), and a ≥2-han open threat reads solid amber
   (.danger-tag.strong). All three pull from the shared --threat-* vars in
   style-theme.css, so recolouring a pill recolours the box automatically. */
.dealin-threat-seat.threat-riichi {
  color: color-mix(in srgb, var(--threat-riichi) 70%, #fff);
  border-color: color-mix(in srgb, var(--threat-riichi) 50%, transparent);
  background: color-mix(in srgb, var(--threat-riichi) 12%, transparent);
}
.dealin-threat-seat.threat-open {
  color: var(--threat-open);
  border-color: color-mix(in srgb, var(--threat-open) 55%, transparent);
  background: color-mix(in srgb, var(--threat-open) 12%, transparent);
}
.dealin-threat-seat.threat-open-dora {
  color: #1a1a2e;
  border-color: transparent;
  background: var(--threat-open);
}
.dealin-threat-waits {
  justify-content: flex-start !important;
  min-height: 18px;
}
.dealin-threat-none {
  font-size: 10px;
  color: var(--text-dim);
  opacity: 0.6;
  font-style: italic;
}
.dealin-threat-rate {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 12px;
  justify-self: end;
}
.dealin-threat-total {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 4px 4px 0;
  margin-top: 1px;
  border-top: 1px solid rgba(255,255,255,0.12);
}
.dealin-threat-total-label {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-dim);
  opacity: 0.7;
}
.dealin-threat-total .dealin-sum-eq { justify-self: end; }
.dealin-threat-total .dealin-cell { font-size: 13px; font-weight: 700; justify-self: end; }

.marker {
  font-size: 9px;
  font-weight: 700;
  padding: 1px 4px;
  border-radius: 3px;
}

.marker.played { background: rgba(239,83,80,0.2); color: var(--sev-major); }
.marker.ai { background: rgba(102,187,106,0.2); color: var(--sev-minor); }
.marker.speed { background: rgba(100,181,246,0.2); color: #64b5f6; }
.marker.threat { background: rgba(255,169,77,0.18); color: #ffa94d; }

/* Note row */
.note-row {
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.note-input {
  flex: 1;
  padding: 5px 10px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--bg-input);
  color: var(--text);
  font-size: 12px;
}

.note-input:focus {
  border-color: var(--accent-dim);
  outline: none;
}

.note-input::placeholder {
  color: var(--text-dim);
  opacity: 0.6;
}

.note-row .save-indicator {
  font-size: 11px;
  color: var(--success);
  opacity: 0;
  transition: opacity 0.3s;
}

.note-row .save-indicator.show { opacity: 1; }

/* Category feedback row */
.report-row {
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  font-size: 12px;
}
.report-ask {
  font-size: 11px;
  color: var(--text-dim);
  margin-right: 2px;
}
.report-btn {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 11px;
  cursor: pointer;
  transition: border-color 0.1s, color 0.1s, background 0.1s;
}
.report-btn:hover {
  border-color: var(--text-dim);
  color: var(--text);
}
.report-btn.active {
  background: rgba(74, 158, 255, 0.15);
  border-color: var(--accent);
  color: var(--accent);
}
.report-undo {
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 11px;
  cursor: pointer;
  padding: 3px 6px;
  text-decoration: underline;
}
.report-undo:hover { color: var(--text); }
.report-status {
  font-size: 11px;
  color: var(--text-dim);
  margin-left: 4px;
}
.report-status.saving { color: var(--text-dim); }
.report-status.ok { color: #86efac; }
.report-status.err { color: #ff6b6b; }
.report-details {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.report-details-cat {
  display: flex;
  gap: 6px;
  align-items: center;
}
.report-details-label {
  font-size: 11px;
  color: var(--text-dim);
}
.report-category {
  padding: 3px 6px;
  border-radius: 4px;
  font-size: 12px;
  background: var(--bg-main);
  color: var(--text);
  border: 1px solid var(--border);
}
.report-reason {
  flex: 1;
  min-width: 180px;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  background: var(--bg-main);
  color: var(--text);
  border: 1px solid var(--border);
}
.report-reason:focus {
  border-color: var(--accent);
  outline: none;
}

/* Complex-gap feedback funnel (EXTRAS-A): embedded INSIDE the trainer's speech
   bubble on complex cards — right where the trainer admits the stats can't
   explain Mortal's pick, we ask the player. Reads as a CTA under the teaching
   text, divided off by a hairline rather than boxed. */
.complex-gap-row {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}
.complex-gap-prompt {
  font-size: 12px;
  color: var(--text);
  font-weight: 500;
  line-height: 1.45;
}
.complex-gap-help { color: var(--text-dim); font-weight: 400; }
.complex-gap-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.complex-tag {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 11px;
  cursor: pointer;
  transition: border-color 0.1s, color 0.1s, background 0.1s;
}
.complex-tag:hover {
  border-color: var(--text-dim);
  color: var(--text);
}
.complex-tag.active {
  background: rgba(74, 158, 255, 0.15);
  border-color: var(--accent);
  color: var(--accent);
}
.complex-gap-input {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

/* Summary view */
.game-summary {
  padding: 16px;
  background: var(--bg-card);
  border-radius: 8px;
}

.game-summary h3 {
  font-size: 14px;
  color: var(--accent);
  margin-bottom: 8px;
}

/* Category badge on mistake cards */
.cat-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 4px;
  white-space: nowrap;
}

/* Grouped category summary */
.category-groups {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.cat-group {
  padding: 8px 12px;
  background: var(--bg);
  border-radius: 6px;
}

.cat-group-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 4px;
}

.cat-group-name {
  font-weight: 700;
  font-size: 14px;
}

.cat-group-stat {
  font-size: 12px;
  color: var(--text-dim);
}

.cat-sub {
  display: grid;
  grid-template-columns: 130px 32px 70px repeat(4, 80px);
  align-items: center;
  gap: 8px;
  padding: 2px 0 2px 12px;
  font-size: 12px;
}

.cat-sub-label {
  color: var(--text);
}

.cat-sub-count {
  color: var(--text-dim);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.cat-sub-ev {
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.tier-count {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--sev-color);
}
.cat-expand {
  font-size: 10px;
  opacity: 0.5;
}
/* Mascot speech bubble */
.mascot-speech {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 6px;
}

.mascot-speech .mascot-avatar {
  width: 32px;
  height: auto;
  flex-shrink: 0;
  opacity: 0.85;
}

.speech-bubble .trigger-line {
  display: block;
  font-weight: 500;
  color: var(--text);
  margin-bottom: 6px;
}

/* Defense-context line shown above the lead of meld/riichi/kan cards when an
   opponent is in riichi. Same red palette as the Defense group colour. */
.speech-bubble .defense-context-line {
  display: block;
  font-weight: 500;
  color: #ffb3b3;
  margin-bottom: 6px;
  padding-left: 8px;
  border-left: 3px solid rgba(255, 107, 107, 0.5);
}
.defense-context-line .defense-tile {
  font-family: var(--mono, monospace);
  padding: 0 3px;
  background: rgba(255, 107, 107, 0.12);
  border-radius: 3px;
}
.defense-context-line .defense-dealin {
  font-weight: 700;
  color: #ff9999;
}

/* All-last note above the lead of a 5A card — same shape as
   .defense-context-line, gold accent to match .all-last-badge. */
.speech-bubble .all-last-context-line {
  display: block;
  font-weight: 500;
  color: #ffe39a;
  margin-bottom: 6px;
  padding-left: 8px;
  border-left: 3px solid rgba(255, 200, 80, 0.5);
}

/* Inline hint when Mortal raised shanten on a 5A — distinct from the header
   badge so it reads as part of the prose, not a chip. */
.raised-shanten-hint {
  display: inline;
  color: #ffd28a;
}

.mascot-speech .speech-bubble {
  position: relative;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-dim);
  padding: 8px 14px;
  background: rgba(255,255,255,0.04);
  border-radius: 8px;
  border: 1px solid var(--border);
  flex: 1;
}

.mascot-speech .speech-bubble::before {
  content: "";
  position: absolute;
  left: -7px;
  top: 12px;
  width: 0;
  height: 0;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-right: 7px solid var(--border);
}

.mascot-speech .speech-bubble::after {
  content: "";
  position: absolute;
  left: -5px;
  top: 13px;
  width: 0;
  height: 0;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-right: 6px solid rgba(255,255,255,0.04);
}

/* Category-report card. Each card is a wrapper that:
   1. Identifies the report (id / kind / user) in a top strip with the
      Delete action.
   2. Shows the reporter's quoted reason (and optional category suggestion).
   3. Embeds the full mistake card the reporter actually saw, so the admin
      can review the same UI the user reported on.
   The mistake card itself comes straight from renderMistakeCard, so its
   border/padding bleed through; we strip its outer chrome with a wrapper. */
.report-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 18px;
  overflow: hidden;
}

.report-card .report-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 16px;
  background: rgba(0, 0, 0, 0.18);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.report-card .report-id {
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: 0.3px;
}
.report-card .report-id .hash { color: var(--text-dim); font-weight: 500; }

.report-card .report-kind {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 3px 8px;
  border-radius: 3px;
  text-transform: uppercase;
}
.report-card .report-kind.wrong_category {
  background: rgba(239, 83, 80, 0.13);
  color: var(--sev-major);
  border: 1px solid rgba(239, 83, 80, 0.3);
}
.report-card .report-kind.wrong_text {
  background: rgba(255, 169, 77, 0.13);
  color: #ffa94d;
  border: 1px solid rgba(255, 169, 77, 0.3);
}

.report-card .report-orig-cat {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border);
  color: var(--text-dim);
}

.report-card .report-by {
  font-size: 12px;
  color: var(--text-dim);
}
.report-card .report-by .user { color: var(--text); font-weight: 600; }
.report-card .report-by .date { color: var(--text-dim); margin-left: 6px; opacity: 0.8; }

.report-card .report-actions {
  margin-left: auto;
  display: inline-flex;
  gap: 6px;
}

.report-card .report-reason {
  padding: 10px 16px;
  background: rgba(0, 0, 0, 0.12);
  border-bottom: 1px solid var(--border);
  font-size: 12.5px;
  color: var(--text);
  line-height: 1.55;
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.report-card .report-reason .quote-mark {
  color: var(--text-dim);
  font-weight: 700;
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
  margin-top: 1px;
  opacity: 0.7;
}
.report-card .report-reason .reason-text { flex: 1; }
.report-card .report-reason .reason-suggested {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--text-dim);
}
.report-card .report-reason .reason-suggested .arrow {
  color: var(--text-dim);
  margin: 0 6px;
  opacity: 0.7;
}
.report-card .report-reason .reason-suggested .from {
  text-decoration: line-through;
  color: var(--text-dim);
  opacity: 0.7;
}
.report-card .report-reason .reason-suggested .to {
  color: var(--accent);
  font-weight: 600;
}

/* The embedded mistake card brings its own background/margin from .mistake;
   neutralise both so it sits flush inside the report wrapper while keeping
   its severity-coloured left accent. */
.report-card .report-mistake-embed .mistake {
  margin: 0;
  border-radius: 0;
  background: transparent;
}

.report-card .report-trainer-empty {
  margin: 8px 14px 4px;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--text-dim);
  background: rgba(255, 169, 77, 0.06);
  border: 1px dashed rgba(255, 169, 77, 0.35);
  border-radius: 4px;
}
.report-card .report-trainer-empty code {
  background: rgba(0, 0, 0, 0.25);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 11px;
}

.report-card .report-footer {
  padding: 9px 16px;
  background: rgba(79, 195, 247, 0.04);
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-dim);
  display: flex;
  gap: 14px;
  align-items: center;
}
.report-card .report-footer b { color: var(--text); }

/* --- Ukeire inline in EV table --- */

/* ---- Tile-acceptance column ------------------------------------------- */
/* Header is left-aligned like the Tile column. */
.ev-table th.ukeire-acc-h { text-align: left; }

/* "N shared" pill living on the left of each acceptance cell — click to expand
   that cell (and the whole row) in place to the pick's full ukeire list. */
.ukeire-shared-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 7px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
  vertical-align: middle;
  white-space: nowrap;
}
.ukeire-shared-pill:hover {
  color: var(--text);
  border-color: var(--text-dim);
}
.ukeire-shared-caret {
  font-size: 9px;
}

/* Collapsed (shared + gains) vs expanded (full acceptance) views live in the
   same cell; the whole row swaps when any pill is toggled. Qualified with
   .ukeire-acc so these beat the plain .ukeire-acc { display: inline-flex }
   declared below them (equal specificity would otherwise let source order win,
   leaving both views — and both carets — visible at once). */
.ukeire-acc.ukeire-expanded { display: none; }
.ev-comparison.shared-expanded .ukeire-acc.ukeire-collapsed { display: none; }
.ev-comparison.shared-expanded .ukeire-acc.ukeire-expanded { display: inline-flex; }

.ev-table td.ukeire-acc-cell {
  text-align: left;
  white-space: normal;
  vertical-align: middle;
}
/* The diff "+N" gain or the full "N tiles" total, each followed by its
   tiles. Wraps as a unit so the tiles flow under a long count if needed. */
.ukeire-acc {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
}
.ukeire-gain {
  font-size: 14px;
  font-weight: 800;
  color: var(--sev-minor);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ukeire-acc-total {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ukeire-inline-tiles {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  vertical-align: middle;
}

.ukeire-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 1px 4px 1px 1px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.ukeire-chip-count {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-dim);
  line-height: 1;
}
/* Dead-wait chips (0 tiles left) — kept in the row so the student sees the
   wait shape, but dimmed so live waits read first. */
.ukeire-chip-dead {
  opacity: 0.45;
  background: rgba(255, 255, 255, 0.02);
}
/* Furiten-overlap chip on the tenpai-waits row — the wait tile that's
   already in the player's own discards. Red outline, no dimming. */
.ukeire-chip-furiten {
  box-shadow: 0 0 0 2px rgba(255, 107, 107, 0.6);
  border-color: rgba(255, 107, 107, 0.6);
}

.ukeire-tile-img {
  height: 22px !important;
  width: auto;
}

/* Feature-summary row: per-pick pills summarising every dimension the
   categorizer gathers (ukeire / dora / dora-acceptance / safety = positive,
   shanten = negative). Pills wrap within the cell. */
.feat-pills {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  align-items: center;
  justify-content: center;
}
.feat-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.feat-pill-pos {
  color: var(--sev-minor);
  background: rgba(102, 187, 106, 0.14);
  border: 1px solid rgba(102, 187, 106, 0.3);
}
.feat-pill-neg {
  color: var(--sev-major);
  background: rgba(239, 83, 80, 0.14);
  border: 1px solid rgba(239, 83, 80, 0.3);
}
/* Deal-in downside pill: neutral chrome so the inline deal-in gradient (set on
   `color`) carries the meaning, exactly like the Deal-in cell. */
.feat-pill-dealin {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
}
/* Group-tinted winning pill: `--feat-grp` is the group colour (set inline by
   ev-table.js's renderWinPill). Replaces the flat green feat-pill-pos chrome so
   every pill reads its concept's category at a glance. */
.feat-pill-grp {
  color: var(--feat-grp);
  background: color-mix(in srgb, var(--feat-grp) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--feat-grp) 40%, transparent);
}
/* Push/fold context clause on a deal-in pill ("· dealer riichi", "· open 3han").
   Muted + lighter weight so it reads as a qualifier of the deal-in %, not a
   second number. The leading middot is drawn here so it never shows without
   context. */
.feat-pill-ctx {
  font-weight: 600;
  opacity: 0.75;
}
.feat-pill-ctx::before {
  content: " · ";
  opacity: 0.6;
}
.feat-pill-tiles {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.feat-pill-tiles .tile-sm {
  height: 18px !important;
  width: auto;
}

.yaku-hints {
  display: inline-block;
  margin: 4px 0;
}

.yaku-tag {
  display: inline-block;
  padding: 1px 6px;
  margin: 0 2px;
  border-radius: 10px;
  font-size: 10.5px;
  font-weight: 600;
  background: rgba(168, 85, 247, 0.18);
  color: #c084fc;
  border: 1px solid rgba(168, 85, 247, 0.35);
}
.yaku-tag.dora-tag {
  background: rgba(245, 158, 11, 0.18);
  color: #fbbf24;
  border-color: rgba(245, 158, 11, 0.4);
}
/* Riichi declaration as a yaku pill in the Value cell — gold/committed, matching
   the header riichi pill (.reach-pill-riichi). Distinct class name from the
   discard-row threat pill (.riichi-tag) so its font-size/padding don't leak in
   and shift the text baseline against the other yaku tags. */
.yaku-tag.riichi-yaku {
  background: rgba(255, 165, 0, 0.14);
  color: #ffcb80;
  border-color: rgba(255, 165, 0, 0.5);
}

/* ============ Bad-Riichi EV bars (5A / 5B mistake cards) ============ */
/* Replaces the legacy tenpai-waits chip strip on Riichi-category cards.
   Each wait is one .bar-row: tile + count on the left, then stacked Ron and
   Tsumo bars on the right. All numbers live in the breakdown line ABOVE the
   bar so the colored segments can be pure visual proportion — no text inside
   them to overflow at small widths. */
.bad-riichi-waits-section {
  /* Local palette tokens — match the design variables. */
  --dama: var(--accent);
  --riichi: var(--sev-major);
  --premium: var(--sev-medium);

  padding: 10px 12px 14px;
  margin: 6px 0;
  background: linear-gradient(180deg, rgba(239,83,80,0.04) 0%, rgba(239,83,80,0) 70%);
  border-left: 3px solid rgba(239, 83, 80, 0.45);
  border-radius: 3px;
}
.bad-riichi-waits-section .waits-section-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.bad-riichi-waits-section .h-label {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--text);
  text-transform: uppercase;
}
.bad-riichi-waits-section .h-count {
  font-size: 11px; color: var(--text-dim); font-weight: 500;
}
.bad-riichi-waits-section .h-legend {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 10.5px; color: var(--text-dim);
  margin-left: auto;
}
.bad-riichi-waits-section .h-legend .legend-dot {
  width: 8px; height: 8px; border-radius: 50%;
}
.bad-riichi-waits-section .legend-dot.dama   { background: var(--dama); }
.bad-riichi-waits-section .legend-dot.riichi { background: var(--riichi); }
.bad-riichi-waits-section .legend-dot.bonus  {
  background: repeating-linear-gradient(135deg,
    rgba(255,167,38,0.7) 0 3px,
    rgba(255,167,38,0.1) 3px 6px);
}
.bad-riichi-waits-section .h-legend .sep { color: var(--text-dim); opacity: 0.6; padding: 0 2px; }

.bad-riichi-waits-section .wait-bars {
  display: flex; flex-direction: column; gap: 18px;
}
.bad-riichi-waits-section .bar-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  column-gap: 14px;
  align-items: start;
}
.bad-riichi-waits-section .bar-tile-col {
  display: flex; flex-direction: column;
  align-items: center; gap: 8px;
  padding-top: 2px;
}
.bad-riichi-waits-section .bar-tile-entry {
  display: flex; flex-direction: column;
  align-items: center; gap: 4px;
}
.bad-riichi-waits-section .tile.tile-big-wait {
  height: 44px;
}
.bad-riichi-waits-section .live-count {
  font-weight: 700; font-size: 11.5px;
  color: var(--text);
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.1);
  padding: 1px 6px;
  border-radius: 10px;
  font-variant-numeric: tabular-nums;
  line-height: 1.3;
}
.bad-riichi-waits-section .live-count-furiten {
  color: #ef9a9a;
  background: rgba(239,83,80,0.12);
  border-color: rgba(239,83,80,0.4);
}

.bad-riichi-waits-section .bar-body {
  display: flex; flex-direction: column; gap: 6px;
}
.bad-riichi-waits-section .bar-meta {
  display: flex; align-items: center; gap: 10px;
  font-size: 11.5px; color: var(--text-dim);
  flex-wrap: wrap;
}
.bad-riichi-waits-section .yaku-list {
  margin-right: auto;
  display: inline-flex; gap: 4px; flex-wrap: wrap;
}
.bad-riichi-waits-section .yaku-none {
  font-size: 10.5px;
  font-style: italic;
  color: var(--text-dim);
}
.bad-riichi-waits-section .bar-verdict {
  font-size: 10.5px;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 10px;
  letter-spacing: 0.2px;
}
.bad-riichi-waits-section .bar-verdict.bad {
  background: rgba(239,83,80,0.12);
  color: #ef9a9a;
  border: 1px solid rgba(239,83,80,0.3);
}

.bad-riichi-waits-section .bar-stack {
  display: flex; flex-direction: column; gap: 8px;
}
.bad-riichi-waits-section .bar-block {
  display: flex; flex-direction: column; gap: 4px;
}
.bad-riichi-waits-section .bar-breakdown {
  display: flex; align-items: baseline;
  gap: 6px 12px;
  flex-wrap: wrap;
  font-size: 11.5px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.bad-riichi-waits-section .bd-mode {
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-dim);
  opacity: 0.8;
  margin-right: 2px;
}
.bad-riichi-waits-section .bd-item {
  display: inline-flex; align-items: baseline; gap: 5px;
}
.bad-riichi-waits-section .bd-item .bd-tag {
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
}
.bad-riichi-waits-section .bd-item.dama   .bd-tag { color: var(--dama); }
.bad-riichi-waits-section .bd-item.riichi .bd-tag { color: #ef9a9a; }
.bad-riichi-waits-section .bd-item.bonus  .bd-tag { color: var(--sev-medium); }
.bad-riichi-waits-section .bd-hanfu {
  font-size: 10.5px; color: var(--text-dim);
}
.bad-riichi-waits-section .bd-points {
  font-weight: 700;
  font-size: 13px;
  color: var(--text);
  letter-spacing: -0.2px;
}
.bad-riichi-waits-section .bd-sep { color: var(--text-dim); opacity: 0.5; }

.bad-riichi-waits-section .bar-track {
  position: relative;
  height: 14px;
  background: rgba(255,255,255,0.025);
  border: 1px solid rgba(42,58,90,0.6);
  border-radius: 3px;
  overflow: hidden;
}
.bad-riichi-waits-section .bar-seg {
  position: absolute; top: 0; bottom: 0;
}
.bad-riichi-waits-section .bar-seg.dama {
  background: linear-gradient(90deg, rgba(79,195,247,0.55) 0%, rgba(79,195,247,0.35) 100%);
  border-right: 1px solid rgba(79,195,247,0.7);
}
.bad-riichi-waits-section .bar-seg.riichi {
  background: linear-gradient(90deg, rgba(239,83,80,0.45) 0%, rgba(239,83,80,0.25) 100%);
  border-right: 1px solid rgba(239,83,80,0.6);
}
.bad-riichi-waits-section .bar-bonus {
  position: absolute; top: 0; bottom: 0;
  background: repeating-linear-gradient(135deg,
    rgba(255,167,38,0.55) 0 4px,
    rgba(255,167,38,0.15) 4px 8px);
  border-right: 1px dashed rgba(255,167,38,0.7);
}
