:root {
  --bg: #0b0d12;
  --bg-elev: #14171e;
  --bg-card: #171a21;
  --bg-hover: #1c2029;
  --bg-sunken: #10141c;
  --border: #262a33;
  --border-strong: #3a4050;
  --fg: #e6e7ea;
  --fg-dim: #a2a6b0;
  --fg-faint: #6a6f7a;
  --accent: #8ec5ff;
  --pos: #5eeb8a;
  --neg: #eb6b6b;
  --warn: #e9c35e;
  --ink: #0b0d12;
  /* alias used by compare.html; resolves per-theme via --fg-dim */
  --muted: var(--fg-dim);
}

/* ---------------- Light theme ---------------- */
/* Toggled by stamping data-theme="light" on <html> (lobby.js). Overrides the
   CSS variables (covers most of the UI) plus the handful of hardcoded dark
   backgrounds/gradients/overlays that would otherwise stay dark. */
:root[data-theme="light"] {
  --bg: #eef1f6;
  --bg-elev: #ffffff;
  --bg-card: #ffffff;
  --bg-hover: #e7ebf1;
  --bg-sunken: #eef1f6;
  --border: #d9dee7;
  --border-strong: #bcc3cf;
  --fg: #171b23;
  --fg-dim: #566072;
  --fg-faint: #8a93a2;
  --accent: #2563eb;
  --pos: #128a46;
  --neg: #d0362e;
  --warn: #b07a10;
  --ink: #ffffff;
  color-scheme: light;
}
:root[data-theme="light"] body { background: var(--bg); }
:root[data-theme="light"] button.primary { background: #2563eb; border-color: #1d4ed8; color: #fff; }
:root[data-theme="light"] button.primary:hover { background: #1d4ed8; }
:root[data-theme="light"] button.danger:hover { background: #fbe9e9; }
:root[data-theme="light"] .tile-confirm-ok { background: #fbe9e9; border-color: #e6a3a0; color: #b3261e; }
:root[data-theme="light"] .tile-confirm-ok:hover { background: #f6d9d8; border-color: #d0362e; }
:root[data-theme="light"] .tile .thumb { background: linear-gradient(135deg, #e6ecf5, #d7e0ee); }
:root[data-theme="light"] .tile .badges .b { background: #ffffffe0; }
:root[data-theme="light"] .tile .badges .b.danger { background: #fdeceb; }
:root[data-theme="light"] .tile .badges .b.warn { border-color: #e6c98a; }
:root[data-theme="light"] .tile .badges .b.err { border-color: #e6a3a0; }
:root[data-theme="light"] #health-pill.status-pill-wait { background: #fbf1d3; }
:root[data-theme="light"] #health-pill.status-pill-stale { background: #fbe3e2; }
:root[data-theme="light"] .rules-chips .chip.on { background: #e6f0ff; border-color: #2563eb; }
:root[data-theme="light"] .spy-tc { background: linear-gradient(180deg, #ffffff, #f3f6fb); }
:root[data-theme="light"] .spy-tc.spy-tc-pos { border-color: #7fcf9c; }
:root[data-theme="light"] .spy-tc.spy-tc-neg { border-color: #e6a3a0; }

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--fg);
  font-size: 14px;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
button {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: inherit;
  padding: 6px 12px;
  border-radius: 6px;
  font: inherit;
  cursor: pointer;
}
button:hover { background: var(--bg-hover); border-color: var(--border-strong); }
button.primary { background: #1a3a5a; border-color: #2d5d8f; color: #d8ecff; }
button.primary:hover { background: #204d75; }
button.ghost { background: transparent; }
button.small { padding: 3px 8px; font-size: 12px; }
button.danger { color: var(--neg); border-color: #3b1c1c; }
button.danger:hover { background: #2a1818; }
input, select {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: inherit;
  padding: 6px 10px;
  border-radius: 6px;
  font: inherit;
}
input:focus, select:focus { outline: none; border-color: var(--border-strong); }

/* ---------- Shell ---------- */

header.app {
  padding: 14px 24px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  align-items: center;
  position: sticky; top: 0; z-index: 10;
}
header.app h1 {
  margin: 0;
  font-size: 16px;
  letter-spacing: .02em;
  font-weight: 600;
}
header.app .sub {
  color: var(--fg-dim);
  font-size: 12px;
}
header.app .spacer { flex: 1; }

main { padding: 20px 24px 40px; max-width: 1400px; margin: 0 auto; }
/* Лобби — на всю ширину: на мелком зуме/широком мониторе сетка добирает колонки, а не оставляет поля */
main.lobby { max-width: none; }

/* ---------- Filters bar (stats.html; лобби с 22.09 — фильтры в шапке) ---------- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-bottom: 16px;
  padding: 12px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.filters .sep { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }
.filters label { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--fg-dim); }
.filters input[type=checkbox] { accent-color: var(--accent); }
.filters .count-badge {
  display: inline-block;
  padding: 1px 6px;
  background: var(--bg-hover);
  border-radius: 10px;
  font-size: 11px;
  color: var(--fg-dim);
}

/* ---------- Lobby header: фильтры в шапке (макет tmp/mockups/header-redesign.html, 22.09) ---------- */

header.app:has(.fdrop) { gap: 8px; padding: 10px 20px; }
header.app .logo {
  display: inline-flex; align-items: center; gap: 7px; margin-right: 6px;
  font-weight: 700; font-size: 15px; color: var(--fg); white-space: nowrap; text-decoration: none;
}
header.app .logo:hover { text-decoration: none; }
header.app .logo .suit { color: var(--accent); font-size: 18px; }
header.app .hsep { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }
header.app .hcount { color: var(--fg-faint); font-size: 12px; white-space: nowrap; }
header.app #f-sort { width: auto; padding: 6px 9px; border-radius: 7px; }

.pill-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg-card); color: var(--fg-dim);
  font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
}
.pill-btn:hover { color: var(--fg); border-color: var(--border-strong); }
.pill-btn[hidden] { display: none; }
.pill-btn.on { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, var(--border)); background: color-mix(in srgb, var(--accent) 12%, var(--bg-card)); }
.pill-btn.hot.on { background: var(--pos); border-color: var(--pos); color: #0b0d12; font-weight: 600; }
.pill-btn.hot.on:hover { color: #0b0d12; filter: brightness(1.08); }
.pill-btn.all.on { background: #2d2640; border-color: #6b58d6; color: #c9bfff; }
:root[data-theme="light"] .pill-btn.hot.on { color: #fff; }
:root[data-theme="light"] .pill-btn.hot.on:hover { color: #fff; }
:root[data-theme="light"] .pill-btn.all.on { background: #ece8ff; border-color: #a89bf0; color: #4a3a9a; }
.fbadge { background: var(--accent); color: var(--ink); border-radius: 999px; padding: 0 6px; font-size: 11px; font-weight: 700; line-height: 16px; }
.fbadge:empty { display: none; }
.admin-mark { font-size: 10px; padding: 0 5px; border-radius: 4px; background: #3a2d12; color: var(--warn); }
:root[data-theme="light"] .admin-mark { background: #fbf1d3; }

.fchips { display: flex; gap: 6px; flex-wrap: wrap; }
.fchips:empty { display: none; }
.fchip {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 5px 4px 10px; border-radius: 999px; font-size: 12px;
  background: color-mix(in srgb, var(--accent) 12%, var(--bg-card)); color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border));
}
.fchip button { background: none; border: 0; color: inherit; cursor: pointer; font-size: 14px; line-height: 1; padding: 0 3px; opacity: .7; }
.fchip button:hover { opacity: 1; background: none; }

.switch { display: inline-flex; align-items: center; gap: 7px; color: var(--fg-dim); font-size: 13px; cursor: pointer; user-select: none; white-space: nowrap; padding: 0 4px; position: relative; }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch i { width: 28px; height: 16px; border-radius: 999px; background: var(--border-strong); position: relative; transition: background .15s; }
.switch i::after { content: ""; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }
.switch input:checked + i { background: var(--accent); }
.switch input:checked + i::after { left: 14px; }
.switch input:focus-visible + i { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Круглая иконка в шапке лобби (⚠ жалоба): текстовая кнопка переносила шапку на 2 строки. */
button.icon-btn { width: 32px; height: 32px; padding: 0; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 15px; line-height: 1; }
.fdrop-panel .frow .switch { justify-self: start; padding: 0; font-size: 12px; }

.fdrop { position: relative; }
.fdrop-panel {
  position: absolute; left: 0; top: calc(100% + 8px); z-index: 30;
  width: 340px; max-width: calc(100vw - 32px);
  display: grid; gap: 12px; padding: 14px;
  background: var(--bg-elev); border: 1px solid var(--border-strong); border-radius: 12px;
  box-shadow: 0 14px 34px rgba(0,0,0,.5);
}
.fdrop-panel[hidden] { display: none; }
.fdrop-panel .frow { display: grid; gap: 6px; }
.fdrop-panel .frow > span { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--fg-faint); font-weight: 600; }
.fdrop-panel select { width: 100%; }
.seg { display: flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.seg button { flex: 1; background: var(--bg-card); color: var(--fg-dim); border: 0; border-right: 1px solid var(--border); border-radius: 0; padding: 6px; font: inherit; font-size: 12px; cursor: pointer; }
.seg button:last-child { border-right: 0; }
.seg button:hover { color: var(--fg); background: var(--bg-hover); }
.seg button.on { background: color-mix(in srgb, var(--accent) 18%, var(--bg-card)); color: var(--accent); }
.stepper { display: flex; align-items: center; gap: 6px; }
.stepper button { width: 30px; height: 30px; padding: 0; }
.stepper input { width: 70px; text-align: center; font-weight: 600; -moz-appearance: textfield; }
.stepper input::-webkit-inner-spin-button, .stepper input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.fdrop-foot { display: flex; justify-content: space-between; align-items: center; border-top: 1px solid var(--border); padding-top: 10px; }
.linkbtn { background: none; border: 0; color: var(--fg-dim); cursor: pointer; font: inherit; padding: 0; }
.linkbtn:hover { color: var(--fg); background: none; }

/* Пилюля статуса + поповер: столы всем, аккаунты — только админу */
.status-wrap { position: relative; }
.status-pop {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 30; width: 270px;
  padding: 12px 14px; display: none;
  background: var(--bg-elev); border: 1px solid var(--border-strong); border-radius: 10px;
  box-shadow: 0 12px 30px rgba(0,0,0,.45); font-size: 13px;
}
.status-wrap:hover .status-pop, .status-wrap:focus-within .status-pop { display: block; }
/* мостик над зазором: курсор по дороге к поповеру не выходит из hover-области */
.status-pop::before { content: ""; position: absolute; left: 0; right: 0; top: -9px; height: 9px; }
.status-pop .grp[hidden] { display: none; }
.status-pop .grp + .grp { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.status-pop h4 { margin: 0 0 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--fg-faint); font-weight: 600; display: flex; gap: 6px; align-items: center; }
.status-pop .prow { display: flex; justify-content: space-between; gap: 10px; padding: 3px 0; color: var(--fg-dim); }
.status-pop .prow b { color: var(--fg); font-weight: 600; }
.status-pop .prow b.warn { color: var(--warn); }
.status-pop .pbar { height: 5px; border-radius: 3px; background: var(--border); overflow: hidden; margin: 4px 0 2px; }
.status-pop .pbar i { display: block; height: 100%; background: var(--pos); }
.status-pop a { color: var(--accent); font-size: 12px; display: inline-block; margin-top: 6px; }

@media (max-width: 760px) {
  header.app:has(.fdrop) { padding: 10px 16px; }
}

/* ---------- Lobby grid ---------- */

#grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
#grid.compact { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
/* Пак 58: плитки из кэша вкладки до первого ответа сети — приглушены (lobby.js). */
#grid.from-cache { opacity: .55; transition: opacity .2s; }

.tile {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  position: relative;
  cursor: pointer;
  transition: border-color .15s, transform .15s;
}
.tile:hover { border-color: var(--border-strong); }
/* Живая плитка — ссылка <a>: без цвета и подчёркивания ссылки */
a.tile { display: block; color: inherit; text-decoration: none; }
.tile.hot { border-color: #3d6a3d; box-shadow: 0 0 0 1px #5eeb8a44; }
.tile.cold { border-color: #6a3d3d; }
.tile.catalog { opacity: 0.72; }
/* «Все столы» (админ): живой раннер без карты за 60 с — бледный, пунктир */
.tile.idle-live { opacity: .5; border-style: dashed; }
.tile.idle-live:hover { opacity: 1; }
/* Провайдер — плашкой на превью (раньше строкой под названием) */
.tile .prov-tag {
  position: absolute; left: 8px; top: 8px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 7px; border-radius: 5px; font-size: 10.5px; letter-spacing: .02em;
  background: #0e151ed0; color: #cfd3da; backdrop-filter: blur(4px); text-transform: capitalize;
}
.tile .prov-tag .health-dot { margin-right: 0; vertical-align: 0; }
.tile.catalog:hover { opacity: 1; }
.tile.catalog .tc { color: var(--fg-faint); font-size: 14px; }

/* Health dot — indicates last frame age */
.health-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: 4px;
  vertical-align: 1px;
}
.health-dot.ok { background: var(--pos); box-shadow: 0 0 6px #5eeb8a55; }
.health-dot.slow { background: var(--warn); }
.health-dot.stale { background: var(--neg); }
.health-dot.idle { background: var(--fg-faint); }

/* Header menu dropdown */
.menu-wrap { position: relative; }
.menu {
  position: absolute;
  right: 0; top: calc(100% + 6px);
  min-width: 260px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.4);
  padding: 6px;
  z-index: 20;
  display: flex;
  flex-direction: column;
}
/* `.menu` sets `display:flex`, which has the same specificity as the UA
   rule `[hidden]{display:none}` but wins by source order — leaving the
   dropdown visible despite the `hidden` attribute and overlapping the
   header content. Restore the hidden semantics explicitly. */
.menu[hidden] { display: none; }
.menu a, .menu button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--fg);
  text-decoration: none;
  font: inherit;
  cursor: pointer;
}
.menu a:hover, .menu button:hover { background: var(--bg-hover); text-decoration: none; }
/* Та же ловушка у пунктов: `display:block` выше перебивал `hidden`, и обычный
   пользователь видел «Админку», «Статистику», «Жалобы» (пак 97, 29.09). */
.menu a[hidden], .menu button[hidden] { display: none; }

/* Health pill in header */
#health-pill { font: inherit; font-size: 12px; padding: 6px 11px; border-radius: 999px; border: 1px solid transparent; align-items: center; gap: 7px; cursor: default; }
#health-pill .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; box-shadow: 0 0 6px currentColor; }
#health-pill.status-pill-ok { background: #193a24; color: var(--pos); border-color: #2a6b40; }
#health-pill.status-pill-wait { background: #37321b; color: var(--warn); }
#health-pill.status-pill-stale { background: #3b1c1c; color: var(--neg); }
.tile .thumb {
  aspect-ratio: 16 / 9;
  background: linear-gradient(135deg, #1a2533, #0f1a25);
  display: flex; align-items: center; justify-content: center;
  color: var(--fg-faint);
  font-size: 11px;
}
.tile .thumb img { width: 100%; height: 100%; object-fit: cover; }
.tile .body { padding: 10px 12px; }
.tile .name {
  font-weight: 600;
  font-size: 14px;
  margin: 0 0 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tile .id {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 10px;
  color: var(--fg-faint);
  margin: 0 0 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tile .metrics {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}
.tile .tc {
  font-size: 22px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.tile .tc small { font-size: 10px; font-weight: 500; color: var(--fg-faint); margin-left: 4px; }
/* Красная карта в текущем шузе: карточка у TC (22.09); «в шузе» — пунктиром, ещё не вышла */
.tile .tc .red-card {
  display: inline-block;
  width: 11px;
  height: 16px;
  margin-left: 6px;
  vertical-align: -1px;
  background: #e0302a;
  border: 1px solid #ff8a84;
  border-radius: 2px;
  box-shadow: 0 0 6px #e0302a99;
  cursor: help;
}
.tile .tc .red-card.in-shoe { background: transparent; border: 1.5px dashed #e0302a; box-shadow: none; }
.tile .min-bet {
  font-size: 12px;
  color: var(--fg-dim);
  padding: 2px 8px;
  background: var(--bg-hover);
  border-radius: 10px;
}
/* «Скопировать название» — сразу за именем стола (владелец 27.09): длинное имя
   режется многоточием, кнопка остаётся видна. Выше строки имени — отрицательный
   margin, чтобы плитка не росла. */
.tile .name-row { display: flex; align-items: center; gap: 6px; margin: 0 0 2px; }
.tile .name-row .name { margin: 0; min-width: 0; }
.tile .tile-copy {
  flex: none;
  width: 26px; height: 26px; padding: 0; margin: -4px 0;
  display: inline-grid; place-items: center;
  border-radius: 50%; background: var(--bg-hover); color: var(--fg-faint);
  transition: color .15s, border-color .15s;
}
.tile .tile-copy svg { width: 14px; height: 14px; }
.tile .tile-copy:hover { color: var(--fg); border-color: var(--border-strong); background: var(--bg-hover); }
.tile .tile-copy.copied { animation: tile-copied .9s ease-out; }
#grid.compact .tile .tile-copy { width: 22px; height: 22px; margin: -2px 0; }
#grid.compact .tile .tile-copy svg { width: 12px; height: 12px; }
@keyframes tile-copied {
  0%, 60% { color: var(--pos); border-color: var(--pos); }
  100% { color: var(--fg-faint); border-color: var(--border); }
}
.tile .progress {
  height: 6px;
  background: var(--bg-hover);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 6px;
}
.tile .progress .fill { height: 100%; background: linear-gradient(90deg, var(--accent), #5eebbc); }
.tile.hot .progress .fill { background: linear-gradient(90deg, var(--pos), #a4f0ba); }
.tile.cold .progress .fill { background: linear-gradient(90deg, var(--neg), #f0a4a4); }
.tile .row {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--fg-dim);
  margin-top: 4px;
}
.tile .badges {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  gap: 4px;
  flex-direction: column;
  align-items: flex-end;
}
.tile .badges .b {
  font-size: 10px;
  padding: 2px 6px;
  background: #0e151ed0;
  border: 1px solid var(--border);
  color: var(--fg-dim);
  border-radius: 4px;
  backdrop-filter: blur(4px);
}
.tile .badges .b.warn { color: var(--warn); border-color: #4d3e1c; }
.tile .badges .b.err { color: var(--neg); border-color: #4d1c1c; }
/* Пак 42: казино, чей SID кормит evo-стол */
.tile .badges .b.casino-bcgame { color: #8fd18f; border-color: #2f5a2f; }
.tile .badges .b.danger {
  color: #ff6b6b;
  border-color: #4d1c1c;
  background: #2a1717d0;
  font-weight: 600;
}
/* TC unreliable: both streams went silent — value may be stale */
.tile .tc.tc-stale {
  opacity: 0.4;
  text-decoration: line-through;
  text-decoration-color: #ff6b6b80;
  text-decoration-thickness: 2px;
}
/* Кнопки плитки (владелец 29.09): тихие серые кружки, видны на ховере плитки.
   «До следующей красной» — снизу справа превью, надпись раскрывается влево только
   наведением на сам кружок (с задержкой — чтобы не раскрыть, ведя мышь к столу). */
.tile .thumb { position: relative; }
.tile .tile-act {
  position: absolute; z-index: 2; opacity: 0;
  height: 26px; min-width: 26px; padding: 0 7px;
  display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px;
  font-size: 11.5px; color: #b9bec8; background: #0e151ed8;
  border: 1px solid #ffffff1c; border-radius: 13px; backdrop-filter: blur(4px);
  transition: opacity .15s, color .15s, border-color .15s, background .15s;
}
.tile:hover .tile-act { opacity: 1; }
@media (hover: none) { .tile .tile-act { opacity: .85; } }
.tile .tile-act svg { flex: none; width: 13px; height: 13px; }
.tile .tile-act-shoe {
  right: 8px; bottom: 8px; max-width: 26px; overflow: hidden; white-space: nowrap;
  transition: max-width .22s ease .12s, opacity .15s, color .15s, border-color .15s, background .15s;
}
.tile .tile-act-shoe svg { order: 2; }
.tile .tile-act-shoe .txt { order: 1; opacity: 0; transition: opacity .12s; }
.tile .tile-act-shoe:hover, .tile .tile-act-shoe.open {
  max-width: 260px; color: #f0d6b8; border-color: #8a6a3a99; background: #17130ee8;
}
.tile .tile-act-shoe:hover .txt, .tile .tile-act-shoe.open .txt { opacity: 1; transition-delay: .2s; }
#grid.compact .tile .tile-act-shoe .full { display: none; }
#grid:not(.compact) .tile .tile-act-shoe .short { display: none; }
/* Админское «исключить для всех» — сверху справа; бейджи на ховере уезжают под него */
.tile .tile-act-stop { right: 8px; top: 8px; width: 26px; padding: 0; justify-content: center; }
.tile .tile-act-stop:hover { color: var(--neg); border-color: #8a2f2799; background: #1d1212e8; }
.tile .badges { transition: transform .15s; }
.tile:hover .badges:has(~ .tile-act-stop) { transform: translateY(32px); }
/* Окно подтверждения действия с плиткой (lobby.js confirmModal) */
.tile-confirm-sub { margin: -6px 0 12px; font-size: 13px; }
.tile-confirm-facts {
  display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0 0 12px;
  font-size: 13px; background: var(--bg-sunken); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 12px;
}
.tile-confirm-facts dt { color: var(--fg-faint); }
.tile-confirm-facts dd { margin: 0; font-variant-numeric: tabular-nums; }
.tile-confirm-input {
  width: 100%; box-sizing: border-box; margin: 0 0 12px; font: inherit; font-size: 13px;
  background: var(--bg-card); color: inherit; border: 1px solid var(--border); border-radius: 6px; padding: 7px 9px;
}
.tile-confirm-ok { background: #3a1e1c; border-color: #6b3530; color: #f3d3cf; font-weight: 600; }
.tile-confirm-ok:hover { background: #4a2420; border-color: #8a4038; }
.tile-confirm-ok:disabled { opacity: .45; cursor: not-allowed; }

.tc.pos { color: var(--pos); }
.tc.neg { color: var(--neg); }
.tc.zero { color: var(--fg-dim); }

.status {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.status-running { background: #193a24; color: var(--pos); }
.status-starting { background: #37321b; color: var(--warn); }
.status-stopped { background: #2b2f39; color: var(--fg-dim); }
.status-error { background: #3b1c1c; color: var(--neg); }

/* ---------- Modal (жалоба «Сообщить о проблеме», пак 62) ---------- */

.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.6);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 50;
}
.modal-backdrop.open { display: flex; }
.modal {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 24px;
  width: min(460px, 92vw);
}
.modal h2 { margin: 0 0 12px; font-size: 16px; }
.modal form { display: grid; gap: 10px; }
.modal .row { display: flex; gap: 8px; justify-content: flex-end; margin-top: 6px; }

/* Пак 62: жалоба «Сообщить о проблеме» (report_ui.js) */
#report-modal textarea {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 110px;
  background: var(--bg-card); color: inherit; border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 10px; font: inherit;
}
#report-modal textarea:focus { outline: none; border-color: var(--border-strong); }
.report-hint { font-size: 12px; margin: 0; }
.report-err { font-size: 12px; margin: 0; color: var(--neg); }
.report-toast {
  position: fixed; right: 16px; bottom: 16px; z-index: 60;
  background: var(--bg-elev); color: var(--fg); border: 1px solid var(--border-strong);
  border-radius: 8px; padding: 10px 14px; font-size: 13px; box-shadow: 0 4px 16px rgba(0,0,0,.35);
}

/* ---------- Detail page (spy view) ---------- */

/*
  Spy hero strip — gc.com parity: small dealer thumbnail + title block on the
  left, oversized True Count card on the right. The TC value is the visual
  anchor of the page, mirroring how gc.com leads with a single big number.
  Everything else is sized down so it doesn't fight for attention.
*/
.spy-hero {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: 16px;
  align-items: stretch;
  margin-bottom: 12px;
}
@media (max-width: 760px) { .spy-hero { grid-template-columns: 1fr; } }

.spy-id {
  display: flex;
  gap: 14px;
  align-items: center;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
}
.spy-id .dealer-thumb {
  width: 120px;
  height: 80px;
  aspect-ratio: 16/9;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--border);
  flex-shrink: 0;
}
.spy-title { flex: 1; min-width: 0; }
.table-uptime {
  align-self: flex-end;
  color: var(--fg-dim);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  cursor: help;
  white-space: nowrap;
}
.spy-title h1 { margin: 0 0 6px; font-size: 22px; line-height: 1.1; }
/* Имя стола копируется кликом: моргает акцентом и «пам» — короткий подскок (table.js) */
.spy-title h1.copyable { display: inline-block; cursor: pointer; border-radius: 4px; transform-origin: left center; transition: color .15s; }
.spy-title h1.copyable:hover { color: var(--accent); }
.spy-title h1.copied { animation: title-copied .55s ease-out; }
@keyframes title-copied {
  0%   { transform: scale(1);    background: transparent; }
  25%  { transform: scale(1.06); background: color-mix(in srgb, var(--accent) 35%, transparent); color: var(--accent); }
  100% { transform: scale(1);    background: transparent; }
}
.spy-sub {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  font-size: 13px;
  color: var(--fg-dim);
  margin-bottom: 6px;
}
.spy-sub .provider { color: var(--fg-dim); }
.spy-sub .min-bet {
  padding: 1px 8px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 11px;
  color: var(--fg-dim);
  background: var(--bg-sunken);
}

.spy-tc {
  background: linear-gradient(180deg, #14181f, #0f1218);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  position: relative;
  overflow: hidden;
}
.spy-tc::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at top right, rgba(94,235,138,0), transparent 60%);
  pointer-events: none;
}
.spy-tc.spy-tc-pos { border-color: #2d5d3f; }
.spy-tc.spy-tc-pos::before { background: radial-gradient(ellipse at top right, rgba(94,235,138,.15), transparent 60%); }
.spy-tc.spy-tc-neg { border-color: #5d2d2d; }
.spy-tc.spy-tc-neg::before { background: radial-gradient(ellipse at top right, rgba(235,107,107,.12), transparent 60%); }
.spy-tc-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--fg-faint);
}
.spy-tc-value {
  font-size: 48px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  margin: 4px 0;
  color: var(--fg);
}
.spy-tc-value.pos { color: var(--pos); }
.spy-tc-value.neg { color: var(--neg); }
/* TC unreliable: kept visible (so user can still read the number) but
   visually marked as untrustworthy. MUST be in sync with the banner
   #lt-tc-stale-banner — same trigger, same visual signal. */
.spy-tc-value.tc-stale {
  opacity: 0.45;
  text-decoration: line-through;
  text-decoration-color: rgba(255, 107, 107, 0.6);
  text-decoration-thickness: 3px;
}
.spy-tc.tc-stale {
  border-color: rgba(255, 107, 107, 0.4) !important;
}
.spy-tc-value.zero { color: var(--fg-dim); }
.spy-tc-sub { font-size: 11px; color: var(--fg-dim); }

.rules-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.rules-chips .chip {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: 2px 7px;
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--fg-dim);
  background: var(--bg-sunken);
}
.rules-chips .chip.on { color: var(--accent); border-color: #2d5d8f; background: #0f2233; }
.rules-chips .chip.off { color: #6a6f7a; }
/* Правила стола + «до следующей красной» справа от них (владелец 29.09): серый кружок
   размером с чип, надпись раскрывается вправо только наведением на него самого. */
.spy-chips-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.spy-tc-invalid {
  height: 22px; min-width: 22px; max-width: 22px; padding: 0 5px;
  display: inline-flex; align-items: center; gap: 6px; overflow: hidden; white-space: nowrap;
  font-size: 11px; color: var(--fg-faint); background: var(--bg-sunken);
  border: 1px solid var(--border); border-radius: 11px;
  transition: max-width .22s ease .12s, color .15s, border-color .15s, background .15s;
}
.spy-tc-invalid[hidden] { display: none; }
.spy-tc-invalid svg { flex: none; width: 12px; height: 12px; }
.spy-tc-invalid .txt { opacity: 0; transition: opacity .12s; }
.spy-tc-invalid:hover, .spy-tc-invalid.open { max-width: 280px; color: #f0d6b8; border-color: #8a6a3a99; background: #17130ee8; }
.spy-tc-invalid:hover .txt, .spy-tc-invalid.open .txt { opacity: 1; transition-delay: .2s; }
:root[data-theme="light"] .spy-tc-invalid:hover, :root[data-theme="light"] .spy-tc-invalid.open { color: #8a5a12; border-color: #d9b56f; background: #fbf3e2; }

/* TC у дилера (владелец 29.09): компактная копия большого TC под именем — видна,
   когда камеру прокрутили к сукну. Цвет — тот же tcClassBy. */
.dealer-tc {
  display: inline-flex; align-items: baseline; gap: 4px; margin-top: 4px;
  padding: 2px 8px; border-radius: 6px; border: 1px solid var(--border-strong); background: var(--bg-sunken);
  font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.25; color: var(--fg);
}
.dealer-tc[hidden] { display: none; }
.dealer-tc small { font-size: 9.5px; font-weight: 600; color: var(--fg-faint); letter-spacing: .05em; }
.dealer-tc.pos { color: var(--pos); border-color: #2d5d3f; }
.dealer-tc.neg { color: var(--neg); border-color: #5d2d2d; }
.dealer-tc.tc-stale { opacity: .45; text-decoration: line-through; text-decoration-color: rgba(255,107,107,.7); text-decoration-thickness: 2px; }

/*
  Shoe progress strip — thin, full-width. gc.com shows just the bar; we keep
  the cut-card marker so users can spot the cut-card pen at a glance.
*/
.shoe-strip {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 12px;
}

/*
  Compact KPI chip-strip — secondary metrics (Hi-Lo RC, decks remaining,
  ten density, insurance EV) in a single row. Each chip is small and quiet
  so the hero TC stays prominent.
*/
.kpi-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 12px;
}
@media (max-width: 720px) { .kpi-strip { grid-template-columns: repeat(2, 1fr); } }
.kpi-chip {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.kpi-chip .label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--fg-faint);
}
.kpi-chip .value {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.kpi-chip .value.pos { color: var(--pos); }
.kpi-chip .value.neg { color: var(--neg); }
.kpi-chip .sub { font-size: 10px; color: var(--fg-dim); }

.panel {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 12px;
}
.panel h3 {
  margin: 0;
  font-size: 11px;
  color: var(--fg-dim);
  text-transform: uppercase;
  letter-spacing: .05em;
  font-weight: 600;
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.panel-head h3 { margin: 0; }
/* Feature panel (matrix) — slightly more breathing room since gc.com makes
   it the centerpiece of the page. */
.panel-feature { padding: 16px 18px; }
.panel-feature .matrix-wrap { margin-top: 4px; }

.shoe-bar {
  height: 12px;
  background: var(--bg-hover);
  border-radius: 6px;
  overflow: hidden;
  position: relative;
  border: 1px solid var(--border);
}
/* Полоска — остаток шуза (владелец 23.09): полная на старте, тает справа налево.
   Приглушена — яркий градиент бил в глаза рядом с TC. */
.shoe-bar .fill { height: 100%; background: linear-gradient(90deg, #5d7fa3, #4f9a86); opacity: .75; }
.shoe-bar .cut-marker {
  position: absolute;
  top: -2px; bottom: -2px;
  width: 2px;
  background: var(--neg);
  opacity: .7;
}
.shoe-meta { display: flex; justify-content: space-between; align-items: baseline; font-size: 11px; color: var(--fg-dim); margin-top: 6px; }
.shoe-meta #shoe-left { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--fg); }
/* Insurance EV promoted into the shoe strip — sits between the card count
   and the shoe code, quiet label + loud value so it reads in one glance. */
.shoe-ins { display: inline-flex; align-items: baseline; gap: 6px; }
.shoe-ins .label { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--fg-faint); }
.shoe-ins .value { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }
.shoe-ins .value.pos { color: var(--pos); }
.shoe-ins .value.neg { color: var(--neg); }
.shoe-ins .sub { font-size: 11px; color: var(--fg-dim); }

.kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; }
.kpi { display: flex; flex-direction: column; gap: 2px; padding: 6px 0; }
.kpi .label { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--fg-faint); }
.kpi .value { font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; }
.kpi .value.small { font-size: 16px; }
.kpi .sub { font-size: 11px; color: var(--fg-dim); }

/* ---------- Live table view ---------- */

/* Палитра сукна — графит (владелец 23.09): зелёное снято, на нём тонули
   зелёные пилюли решений («Stand» на зелёном месте). Выбор палитры в
   настройках владелец отклонил — одна на всех. Светлая тема перекрывает
   поверхности своими правилами ниже, переменные ей не мешают. */
:root {
  --felt-bg-1: #16191f; --felt-bg-2: #111318; --felt-border: #262a33;
  --felt-head: #a2a6b0; --felt-role: #8a909c;
  --felt-dealer-1: #1c2027; --felt-dealer-2: #15181e; --felt-dealer-border: #2a2f39;
  --seat-bg-1: #1a1d24; --seat-bg-2: #15181e; --seat-border: #262a33;
  --seat-occ-1: #1f232b; --seat-occ-2: #181b22; --seat-occ-border: #3a4050;
  --felt-line: #2e3440; --felt-sep: #6a6f7a;
  --pill-unk-bg: #22262e; --pill-unk-fg: #b4b8c2; --pill-unk-ring: #3a4050;
}

/*
  The live felt is the page's primary surface. We pull it forward visually
  with a dark gradient from the felt palette above,
  and we let the cards breathe — corner-labels, big centered pip, gentle
  hover lift. Animations are scoped to .lt-card.is-new so re-renders of
  pre-existing cards stay still (only the just-dealt card flutters in).
*/
.live-felt {
  background:
    radial-gradient(ellipse 80% 60% at 50% -10%, rgba(255,255,255,0.04), transparent 70%),
    linear-gradient(180deg, var(--felt-bg-1) 0%, var(--felt-bg-2) 100%);
  border-color: var(--felt-border);
  padding: 18px 18px 20px;
}
.felt-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
}
.felt-head h3 {
  margin: 0;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--felt-head);
}

/* Live heartbeat — ticks every second so the user has a concrete
   signal "the connection is alive" even if no card has been dealt
   recently. Three colour states: fresh / slow / stalled. */
.lt-heartbeat {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, Menlo, monospace;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--seat-bg-2);
  color: var(--felt-head);
  border: 1px solid var(--felt-border);
  white-space: nowrap;
}
.lt-heartbeat.fresh {
  background: #143324;
  color: #6ee08c;
  border-color: #2c5a45;
}
.lt-heartbeat.slow {
  background: #2c2410;
  color: #f0c968;
  border-color: #4d4017;
}
/* Стол жив, но раунда давно нет — пустой стол / тасовка. */
.lt-heartbeat.idle {
  background: #14212c;
  color: #8fb8dc;
  border-color: #26455e;
}
.lt-heartbeat.stalled {
  background: #2c1414;
  color: #ff8888;
  border-color: #5a1f1f;
  animation: heartbeat-pulse 1.4s ease-in-out infinite;
}
@keyframes heartbeat-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 90, 90, 0.4); }
  50%      { box-shadow: 0 0 0 6px rgba(255, 90, 90, 0); }
}

/* Stale banner — appears prominently when no frames in 30s+. */
.lt-stale-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  margin: 0 0 12px;
  border-radius: 8px;
  background: linear-gradient(180deg, #3a2e18, #2c2410);
  border: 1px solid #4d4017;
  color: #f0c968;
  font-size: 13px;
  font-weight: 600;
}
.lt-stale-banner[hidden] { display: none; }

/* TC unreliable banner (владелец 21.09 вернул): причина сомнения в TC словами.
   [hidden] с !important — JS переключает атрибут hidden. */
.lt-tc-stale-banner {
  background: #3a1818;
  border-left: 3px solid #ff6b6b;
  color: #ffd0d0;
  padding: 8px 12px;
  font-size: 13px;
  border-radius: 4px;
  margin: 8px 0;
  display: flex;
  gap: 10px;
  align-items: center;
}
.lt-tc-stale-banner[hidden] { display: none !important; }
.lt-tc-stale-banner .lt-tc-stale-icon { font-size: 18px; }

/* Per-rank cards-remaining strip (mirrors GC detail-page layout) */
.lt-rankstrip {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 8px 14px;
  background: rgba(0,0,0,0.15);
  border-bottom: 1px solid var(--border);
  font-family: var(--mono, "SF Mono", monospace);
  font-size: 12px;
  user-select: none;
}
.lt-rankstrip .rk {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 8px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 4px;
  min-width: 56px;
  justify-content: space-between;
}
.lt-rankstrip .rk .rank-name {
  font-weight: 700;
  color: var(--fg);
}
.lt-rankstrip .rk .rank-count {
  color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}
/* depletion shading — chip turns red as remaining shrinks */
.lt-rankstrip .rk.depleted {
  background: rgba(255,80,80,0.12);
  border-color: rgba(255,100,100,0.30);
}
.lt-rankstrip .rk.depleted .rank-count { color: #ff8a8a; }
.lt-rankstrip .rk.heavy-depleted {
  background: rgba(255,40,40,0.20);
  border-color: rgba(255,60,60,0.45);
}
.lt-rankstrip .rk.heavy-depleted .rank-count { color: #ff5050; font-weight: 600; }
/* Обрывы наблюдения в шузе (владелец 21.09): «⚠ N» в шапке «Стол сейчас» рядом
   с game #, подробности при наведении. */
.lt-gaps {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: 10px; padding: 1px 7px; border-radius: 4px;
  color: #e0a93b; background: rgba(224,169,59,0.08);
  border: 1px solid rgba(224,169,59,0.30);
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; cursor: help;
}
.lt-gaps[hidden] { display: none; }
.lt-gaps.lt-gaps-waiting { background: rgba(224,169,59,0.16); border-color: rgba(224,169,59,0.55); }
:root[data-theme="light"] .lt-gaps { color: #9a6a00; }
.lt-stale-banner.severe {
  background: linear-gradient(180deg, #3b1c1c, #2c1414);
  border-color: #5a1f1f;
  color: #ff9d9d;
}
.lt-stale-icon { font-size: 16px; }

/* Subtle border pulse triggered programmatically when any WS message
   arrives — proves the stream is alive between card events. */
.live-felt.is-pulsing {
  animation: felt-pulse 600ms ease-out 1;
}
@keyframes felt-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(110, 224, 140, 0.35); }
  100% { box-shadow: 0 0 0 12px rgba(110, 224, 140, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .lt-heartbeat.stalled,
  .live-felt.is-pulsing { animation: none; }
}

.live-table .lt-dealer {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 14px 16px;
  background:
    radial-gradient(ellipse 50% 100% at 50% 0%, rgba(255,255,255,0.05), transparent 75%),
    linear-gradient(180deg, var(--felt-dealer-1), var(--felt-dealer-2));
  border: 1px solid var(--felt-dealer-border);
  border-radius: 10px;
  margin-bottom: 14px;
  box-shadow: 0 4px 14px -6px rgba(0, 0, 0, 0.6) inset;
}
.live-table .lt-dealer-label { min-width: 120px; }
.live-table .lt-role {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--felt-role);
}
.live-table .lt-name { font-weight: 600; font-size: 14px; color: #e6e8ea; }
.live-table .lt-dealer .lt-cards { flex: 1; min-height: 92px; }
.live-table .lt-dealer .lt-score {
  font-size: 28px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 64px;
  text-align: right;
  color: #f0c968;
}
/* Inline Insurance EV badge, shown only when dealer upcard is Ace and the
   round is live. Green pill for positive EV (take it), red for negative. */
.lt-insurance-badge {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 4px 8px;
  border-radius: 14px;
  font-family: ui-monospace, Menlo, monospace;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  align-self: center;
}
.lt-insurance-badge.ins-pos {
  background: #0f2419;
  color: #7fdc8a;
  box-shadow: 0 0 0 1px rgba(127, 220, 138, 0.35);
}
.lt-insurance-badge.ins-neg {
  background: #2c1414;
  color: #ff8888;
  box-shadow: 0 0 0 1px rgba(255, 136, 136, 0.35);
}
.lt-insurance-badge.hidden { display: none; }

.lt-seats {
  display: grid;
  /* Always ONE row of 7 seats. minmax(0, 1fr) lets columns shrink below
     content width so the whole table stays on a single row at any viewport
     — seats (and the cards inside them) get smaller on resize instead of
     wrapping to a second row. No breakpoints: never wrap. */
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 6px;
}

.lt-seat {
  background: linear-gradient(180deg, var(--seat-bg-1), var(--seat-bg-2));
  border: 1px solid var(--seat-border);
  border-radius: 8px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 140px;
}
.lt-seat.occupied {
  border-color: var(--seat-occ-border);
  background: linear-gradient(180deg, var(--seat-occ-1), var(--seat-occ-2));
}
/* Empty seats stay visible (so the row layout doesn't collapse) but
   are visually de-emphasized — half-opacity, no card-empty dashes. */
.lt-seat.empty {
  min-height: 0;
  opacity: 0.45;
  background: transparent;
  border-style: dashed;
}
.lt-seat.empty .lt-hand-empty { display: none; }
.lt-seat.empty .lt-player { color: var(--fg-faint); }
.lt-seathead {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 11px;
  border-bottom: 1px dashed var(--felt-line);
  padding-bottom: 4px;
}
.lt-seathead .lt-num {
  color: var(--felt-role);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
/* Nickname is how the user finds "their" seat on a fast table — it reads
   before anything else in the tile, so it gets the largest type here. */
.lt-seathead .lt-player {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.01em;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #eef3ef;
}
.lt-seathead .lt-country { font-size: 10px; color: var(--felt-role); }

.lt-hand {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* Recommendation block — GC-parity layout: compact inline summary
 * (best green ✋ + worst-of-relevant red ✋ with strikethrough), click/tap
 * reveals a popup with EV percentages for every action. */
/* Слот под плашку совета (пак 25.3). Держит высоту, даже когда плашки нет:
   иначе в момент хода блок схлопывается и карточки сидений ниже прыгают —
   на живом столе это дёргается по нескольку раз за раздачу.
   Высота посчитана по составляющим, а не на глаз: `.lt-rec` margin-top 6 +
   padding 4+4; `.lt-rec-summary` две строки по 11px × line-height 1.3 = 14.3
   плюс gap 2 → 30.6; `.lt-rec-badge` margin-top 4 + padding 2+2 + border 1+1 +
   строка ~13 → 23. Итого ≈ 68. Берём по ДВУХСТРОЧНОЙ плашке (лучший ход +
   отвергнутый): она максимальная, поэтому исчезновение не двигает вёрстку
   вообще. Однострочная оставит немного воздуха снизу — это дешевле прыжка.
   ⚠ Пак 25.3 поднимал высоту до 82px под замороженную плашку «на момент хода»
   и вернул обратно вместе с ней: после хода блока EV нет вовсе, слот снова
   просто держит место. */
.lt-rec-slot {
  min-height: 68px;
}
.lt-rec {
  position: relative;
  margin-top: 6px;
  padding: 4px;
  border-radius: 4px;
  cursor: pointer;
  outline: none;
  transition: background-color 120ms ease;
}
.lt-rec:hover { background: rgba(255, 255, 255, 0.03); }
.lt-rec:focus { background: rgba(255, 255, 255, 0.05); }
.lt-rec.expanded { background: rgba(255, 255, 255, 0.04); }

.lt-rec-summary {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 11px;
}
.lt-rec-row {
  display: flex;
  align-items: center;
  gap: 5px;
  line-height: 1.3;
}
.lt-rec-icon {
  font-size: 10px;
  flex: 0 0 auto;
}
.lt-rec-label {
  flex: 1;
}
.lt-rec-best {
  color: #6ee7a3;
}
.lt-rec-best .lt-rec-icon {
  color: #6ee7a3;
  filter: hue-rotate(70deg) saturate(1.4);
}
.lt-rec-worse {
  color: #ef6464;
}
.lt-rec-worse .lt-rec-label {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  opacity: 0.85;
}
.lt-rec-worse .lt-rec-icon {
  opacity: 0.6;
  filter: hue-rotate(-30deg) saturate(0.6);
}

/* Popup with full EV breakdown — hidden by default, shown when .expanded */
.lt-rec-popup {
  display: none;
  position: absolute;
  z-index: 50;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 2px;
  padding: 4px;
  background: #0f1614;
  border: 1px solid #2c4a3c;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
  font-size: 11px;
}
.lt-rec.expanded .lt-rec-popup { display: block; }
.lt-rec-pop-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 3px 6px;
  border-radius: 2px;
}
.lt-rec-pop-row + .lt-rec-pop-row { margin-top: 1px; }
/* Сноска под списком вариантов: расхождение с GC на дилерской десятке —
   ожидаемое, см. `dealerTenNoteHTML` в table.js. Приглушённая и мелкая
   намеренно: это справка для сверки экранов, а не сигнал тревоги, и она не
   должна конкурировать взглядом с самими EV. */
.lt-rec-pop-note {
  margin-top: 5px;
  padding: 3px 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.09);
  font-size: 10px;
  line-height: 1.3;
  color: #8b95a5;
  cursor: help;
}
.lt-rec-pop-row.lt-rec-best {
  background: rgba(110, 231, 163, 0.1);
}
.lt-rec-pop-row.lt-rec-worse {
  color: #ef6464;
}
.lt-rec-pop-row.lt-rec-worse .lt-rec-pop-label {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.lt-rec-pop-row.lt-rec-pop-cashout-exact {
  background: rgba(250, 204, 21, 0.12);
  border-left: 2px solid #facc15;
  padding-left: 4px;
}
.lt-rec-exact-badge {
  margin-left: 3px;
  font-size: 0.8em;
}
.lt-rec-pop-ev {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Bottom badge — `H +24.3%` style. Green normally, yellow when marginal. */
.lt-rec-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
  font-size: 10px;
  padding: 2px 5px;
  border-radius: 3px;
  background: rgba(110, 231, 163, 0.12);
  border: 1px solid rgba(110, 231, 163, 0.4);
}
.lt-rec-stale {
  display: inline-flex;
  align-items: center;
  margin-top: 4px;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 3px;
  color: #e8b45a;
  background: rgba(232, 180, 90, 0.10);
  border: 1px solid rgba(232, 180, 90, 0.35);
  cursor: default;
}
.lt-rec-badge-letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 14px;
  height: 14px;
  padding: 0 3px;
  border-radius: 2px;
  background: #6ee7a3;
  color: #0a1411;
  font-weight: 700;
  font-size: 9px;
}
.lt-rec-badge-delta {
  color: #6ee7a3;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.lt-rec-marginal {
  background: rgba(231, 200, 110, 0.12);
  border-color: rgba(231, 200, 110, 0.4);
}
.lt-rec-marginal .lt-rec-badge-letter {
  background: #e7c86e;
}
.lt-rec-marginal .lt-rec-badge-delta {
  color: #e7c86e;
}

.lt-hand + .lt-hand {
  border-top: 1px dashed var(--felt-line);
  padding-top: 6px;
  margin-top: 2px;
}

.lt-cards {
  display: flex;
  /* nowrap: cards never reflow to a new line — they shrink to fit the seat
     width instead (see the fluid .lt-cards .lt-card rule below). */
  flex-wrap: nowrap;
  gap: 6px;
  align-items: center;
  min-height: 92px;
}

/*
  Card itself — proper playing-card proportions (~5:7), corner labels,
  centered pip, soft cream gradient for the face. We use box-shadow with
  multiple stops to suggest a real card sitting on felt: tight ambient
  shadow + soft lift + subtle inset highlight on top.
*/
.lt-card {
  position: relative;
  display: inline-block;
  width: 58px;
  height: 84px;
  background: linear-gradient(160deg, #fafaf3, #ebe5d4);
  border: 1px solid #a39a83;
  border-radius: 6px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-weight: 700;
  user-select: none;
  flex-shrink: 0;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.5),
    0 4px 10px -4px rgba(0, 0, 0, 0.45),
    0 0 0 1px rgba(255, 255, 255, 0.08) inset;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.lt-card:hover {
  transform: translateY(-2px) rotate(-1deg);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.5),
    0 8px 16px -4px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(255, 255, 255, 0.12) inset;
}
.lt-card .corner {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  line-height: 1;
}
.lt-card .corner.tl { top: 5px; left: 6px; }
.lt-card .corner.br {
  bottom: 5px;
  right: 6px;
  transform: rotate(180deg);
  transform-origin: center;
}
.lt-card .corner .r { font-size: 14px; letter-spacing: -0.02em; }
.lt-card .corner .s { font-size: 11px; }
.lt-card .pip {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  line-height: 1;
  opacity: 0.92;
}
.lt-card.lt-red { color: #b9341e; }
.lt-card.lt-black { color: #1a1d24; }

/*
  Fluid cards (seat + dealer only — trace mini-cards live in .lt-trace and
  keep their own fixed size). Each card is a flex item that shrinks to share
  the seat width equally, capped at the natural 58px, and never wraps. The
  card is its own container-query context so the corner labels and centre pip
  scale with the card's ACTUAL rendered width — so a hand of 2, 3 or 4 cards
  all stays on one line, just smaller. Ratios below reproduce the original
  58x84 proportions (14/58 ~= 24%, 32/58 ~= 55%, 5/58 ~= 8.6%, 6/58 ~= 10.3%).
*/
.lt-cards .lt-card {
  flex: 1 1 0;
  min-width: 0;
  max-width: 58px;
  width: auto;
  height: auto;
  aspect-ratio: 58 / 84;
  container-type: inline-size;
  /* % of the card's own box - cqi cannot be used here (a container
     cannot query itself; it would resolve against the viewport and
     balloon the radius into an oval). */
  border-radius: 8%;
}
.lt-cards .lt-card .corner.tl { top: 8.6cqi; left: 10.3cqi; }
.lt-cards .lt-card .corner.br { bottom: 8.6cqi; right: 10.3cqi; }
.lt-cards .lt-card .corner .r { font-size: 24cqi; }
.lt-cards .lt-card .corner .s { font-size: 19cqi; }
.lt-cards .lt-card .pip { font-size: 55cqi; }

/* Newest card pulses gently to draw the eye */
.lt-card.is-newest {
  animation: card-newest-pulse 1.6s ease-out 1;
}
@keyframes card-newest-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(240, 201, 104, 0.55),
                     0 4px 10px -4px rgba(0, 0, 0, 0.45),
                     0 0 0 1px rgba(255, 255, 255, 0.08) inset; }
  60%  { box-shadow: 0 0 0 8px rgba(240, 201, 104, 0),
                     0 4px 10px -4px rgba(0, 0, 0, 0.45),
                     0 0 0 1px rgba(255, 255, 255, 0.08) inset; }
  100% { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5),
                     0 4px 10px -4px rgba(0, 0, 0, 0.45),
                     0 0 0 1px rgba(255, 255, 255, 0.08) inset; }
}

/* Just-dealt card: slides in from above + slight rotate, then settles */
.lt-card.is-new {
  animation: card-deal-in 380ms cubic-bezier(0.18, 0.88, 0.36, 1) 1;
}
@keyframes card-deal-in {
  0% {
    opacity: 0;
    transform: translate(40px, -60px) rotate(-18deg) scale(0.85);
  }
  60% {
    opacity: 1;
    transform: translate(2px, 2px) rotate(2deg) scale(1.02);
  }
  100% {
    opacity: 1;
    transform: translate(0, 0) rotate(0) scale(1);
  }
}
@media (prefers-reduced-motion: reduce) {
  .lt-card.is-new,
  .lt-card.is-newest { animation: none; }
}

.lt-empty {
  font-size: 11px;
  color: var(--felt-role);
  padding: 8px 4px;
  font-style: italic;
}

.lt-handmeta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  font-size: 12px;
}
.lt-handmeta .lt-score {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 16px;
  color: #f0c968;
}
.lt-result {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--bg-hover);
  color: var(--fg-dim);
  font-weight: 700;
}
.lt-result.win { background: #193a24; color: var(--pos); }
.lt-result.lose, .lt-result.bust { background: #3b1c1c; color: var(--neg); }
.lt-result.push { background: #37321b; color: var(--warn); }
.lt-result.blackjack { background: #14283f; color: var(--accent); }

/*
  Trace: inline timeline of [card] → action → [card] → action → … → result.
  Lives directly under each hand so the player's narrative is readable at
  a glance, no jumping to the decisions table. The arrow is a thin line
  with the action chip floating mid-arrow; flex-wrap so long traces wrap
  on narrow screens instead of horizontal-scrolling.
*/
.lt-trace {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  padding-top: 8px;
  border-top: 1px dashed var(--felt-line);
}
/* One step of the trace = one decision pill. The "▸" separator sits on the
   step wrapper so the pills themselves stay clean coloured blocks. */
.lt-trace-step {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.lt-trace-step + .lt-trace-step::before {
  content: "▸";
  font-size: 10px;
  color: var(--felt-sep);
  margin: 0 5px 0 1px;
}
/* Colour = verdict, nothing else. Green: played the optimal action.
   Yellow: missed it by less than 1% of the stake — a near-tie, same palette
   as the marginal live badge. Red: deviated from it. Neutral: we couldn't
   verify the decision. */
.lt-trace-action {
  position: relative;
  z-index: 1;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 3px 9px;
  border-radius: 4px;
  white-space: nowrap;
}
.lt-trace-action.is-right   { background: #143324; color: #7fdc8a; box-shadow: 0 0 0 1px #2c6a32; }
.lt-trace-action.is-marginal { background: #33290f; color: #e7c86e; box-shadow: 0 0 0 1px #7a6424; }
.lt-trace-action.is-wrong   { background: #3a1616; color: #ff8f8f; box-shadow: 0 0 0 1px #7a2c2c; }
.lt-trace-action.is-unknown { background: var(--pill-unk-bg); color: var(--pill-unk-fg); box-shadow: 0 0 0 1px var(--pill-unk-ring); }

/* GC-parity per-decision EV popup. The pill itself stays inline-block in the
   trace; the popup is absolutely positioned so it doesn't push siblings, and
   toggled by the `.expanded` class via onclick on the pill. */
.lt-trace-action--clickable { cursor: pointer; }
.lt-trace-action--clickable:hover { filter: brightness(1.15); }
.lt-trace-action--clickable:focus { outline: 1px solid rgba(255,255,255,0.35); outline-offset: 1px; }
.lt-trace-popup {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 10;
  background: #0f1217;
  border: 1px solid #2a3038;
  border-radius: 5px;
  padding: 5px 6px;
  box-shadow: 0 8px 20px rgba(0,0,0,0.55);
  min-width: 130px;
  font-family: ui-monospace, Menlo, monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
  text-align: left;
  white-space: nowrap;
}
.lt-trace-action.expanded .lt-trace-popup { display: block; }
.lt-trace-popup .lt-rec-pop-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 4px;
  border-radius: 3px;
  text-decoration: none;  /* override the active-hand "worse" line-through */
}
.lt-trace-popup .lt-rec-pop-row + .lt-rec-pop-row { margin-top: 1px; }
/* Sign-based coloring like GC: positive EV = green, negative = red. The best
   row also gets a subtle highlight tint so the recommended action stands out
   independently of sign. */
.lt-trace-popup .lt-trace-ev-pos { color: #7fdc8a; }
.lt-trace-popup .lt-trace-ev-neg { color: #ff8888; }
.lt-trace-popup .lt-trace-pop-best { background: rgba(110, 231, 163, 0.12); }
.lt-trace-popup .lt-rec-pop-label {
  font-weight: 700;
  text-decoration: none;
}
.lt-trace-popup .lt-rec-pop-ev { font-variant-numeric: tabular-nums; }
.lt-trace-popup .lt-rec-pop-played {
  color: #f0c968;
  font-weight: 800;
  margin-left: 4px;
}
.lt-trace-end {
  font-size: 11px;
  font-weight: 700;
  color: #f0c968;
  font-variant-numeric: tabular-nums;
  padding-left: 6px;
}

/* Legacy chip row — kept as a fallback when trace isn't applicable */
.lt-decisions { display: flex; flex-wrap: wrap; gap: 3px; }
.lt-dec {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
  font-family: ui-monospace, Menlo, monospace;
  letter-spacing: .04em;
}
.lt-dec-H { background: #7ecb7e55; color: #9deb9d; }
.lt-dec-S { background: #f0c96855; color: #ffd97a; }
.lt-dec-D { background: #5ea3eb55; color: #a4d0ff; }
.lt-dec-P { background: #c078eb55; color: #e1aaff; }
.lt-dec-R { background: #eb6b6b55; color: #ff9d9d; }

.lt-dec-acc {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 4px;
  margin-left: 2px;
  border-radius: 3px;
  font-family: ui-monospace, Menlo, monospace;
  letter-spacing: .02em;
  vertical-align: baseline;
}
.lt-dec-acc.acc-good { background: #19381f; color: #7fdc8a; }
.lt-dec-acc.acc-ok   { background: #2a3320; color: #c8d97a; }
.lt-dec-acc.acc-warn { background: #3a2e18; color: #f0b450; }
.lt-dec-acc.acc-bad  { background: #3b1c1c; color: #ff8888; }

/* ---------- Strategy matrix ---------- */

.matrix-tabs { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.matrix-tabs button { border-radius: 6px; padding: 5px 12px; font-size: 13px; }
.matrix-tabs button.active { background: var(--bg-hover); border-color: var(--border-strong); color: var(--fg); }
.matrix-tabs button.ghost { padding: 5px 10px; opacity: .7; }
.matrix-tabs button.ghost:hover { opacity: 1; }

.matrix-wrap { overflow-x: auto; }
table.matrix {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  min-width: 460px;
}
table.matrix th, table.matrix td {
  padding: 6px 0;
  text-align: center;
  border: 1px solid var(--bg-sunken);
}
table.matrix thead th {
  background: var(--bg-sunken);
  color: var(--fg-dim);
  font-weight: 500;
  font-size: 11px;
}
table.matrix tbody th {
  background: var(--bg-sunken);
  color: var(--fg-dim);
  padding-left: 6px;
  padding-right: 6px;
  font-weight: 500;
  width: 44px;
}
td.act { font-weight: 700; cursor: help; position: relative; }
td.act.S { background: #f0c96855; color: #ffd97a; }
td.act.H { background: #7ecb7e55; color: #9deb9d; }
td.act.D { background: #5ea3eb55; color: #a4d0ff; }
td.act.P { background: #c078eb55; color: #e1aaff; }
td.act.R { background: #eb6b6b55; color: #ff9d9d; }
td.act.deviation { outline: 1px dashed var(--accent); outline-offset: -2px; }

.legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; font-size: 11px; color: var(--fg-dim); }
.legend .sw { display: inline-block; width: 14px; height: 14px; border-radius: 3px; margin-right: 4px; vertical-align: -3px; }

.tooltip {
  position: absolute;
  z-index: 100;
  background: #05080d;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 11px;
  color: var(--fg);
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 4px 16px rgba(0,0,0,.6);
}
.tooltip .ev { display: flex; justify-content: space-between; gap: 16px; font-variant-numeric: tabular-nums; }
.tooltip .ev.best { color: var(--pos); font-weight: 600; }

/* ---------- Event log / tables ---------- */

table.plain { width: 100%; border-collapse: collapse; font-size: 12px; }
table.plain th, table.plain td { padding: 5px 8px; text-align: left; border-bottom: 1px solid var(--bg-hover); }
table.plain th { color: var(--fg-dim); font-weight: 500; }
.win { color: var(--pos); }
.lose { color: var(--neg); }
.push { color: var(--warn); }
.blackjack { color: var(--accent); font-weight: 600; }
.bust { color: var(--neg); }

/* misc */
.muted { color: var(--fg-dim); }
/* Пак 47: бейдж детектора по превьюшке (теневой режим). */
.evo-preview { color: var(--fg-dim); font-size: 0.85em; margin-left: 0.6em; }
.evo-preview.evo-preview-empty { color: #e0a030; font-weight: 600; }
.evo-preview.evo-preview-off { color: #e05050; font-weight: 600; }   /* пак 55: превью не работает */
.mono { font-family: ui-monospace, Menlo, monospace; }
.hidden { display: none !important; }
.no-data { color: var(--fg-faint); font-size: 12px; padding: 16px; text-align: center; }

/* rules editor (modal) */
.rules-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; }
.rules-grid label { display: flex; align-items: center; gap: 8px; font-size: 13px; }

/* Closed catalog tile — gc.com parity: still render the tile so users see the
   full universe, but visually de-emphasize it. */
.tile.catalog.closed { opacity: 0.45; filter: grayscale(0.6); cursor: not-allowed; }
.tile.catalog.closed:hover { opacity: 0.6; border-color: var(--border); }
.tile .badges .b.dim { color: var(--fg-faint); border-color: #2b2f39; background: var(--bg-sunken)b0; }

/* Deviations tab on detail page — chip-style table; .active rows pop with the
   same accent the matrix uses for deviation outlines so visual language matches. */
.dev-table th, .dev-table td { padding: 6px 8px; font-size: 12px; }
.dev-table tr.dev-row.active td { background: #0f2233; }
.dev-table tr.dev-row.active td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* === Decision-log analytics (2026-05-29): per-seat aggregate, heatmap, anomalies. === */

.dec-sum {
  margin: 6px 0 10px;
  display: flex; flex-direction: column; gap: 6px;
}
.dec-sum-head {
  display: flex; align-items: baseline; gap: 8px;
  padding: 6px 10px; border-radius: 6px; font-size: 13px;
  background: #0e1218; border: 1px solid var(--border);
}
.dec-sum-head-label { color: var(--fg-dim); }
.dec-sum-head-pct { font-weight: 600; font-size: 16px; }
.dec-sum-head-n   { color: var(--fg-dim); font-size: 11px; }
.dec-sum-head-loss { margin-left: auto; color: var(--fg-dim); }

.dec-sum-good .dec-sum-head-pct { color: #4ec069; }
.dec-sum-ok   .dec-sum-head-pct { color: #d4b94a; }
.dec-sum-bad  .dec-sum-head-pct { color: #e26060; }

.dec-sum-seats { display: flex; gap: 4px; flex-wrap: wrap; }
.dec-sum-seat {
  min-width: 64px;
  padding: 4px 6px; border-radius: 5px;
  background: #11151c; border: 1px solid var(--border);
  display: flex; flex-direction: column; align-items: center;
  cursor: help; font-size: 11px; line-height: 1.2;
}
.dec-sum-seatnum { color: var(--fg-dim); font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; }
.dec-sum-pct     { font-weight: 600; font-size: 14px; }
.dec-sum-n       { color: var(--fg-faint); font-size: 10px; }
.dec-sum-loss    { color: var(--fg-faint); font-size: 10px; }
.dec-sum-good .dec-sum-pct { color: #4ec069; }
.dec-sum-ok   .dec-sum-pct { color: #d4b94a; }
.dec-sum-bad  .dec-sum-pct { color: #e26060; }
.dec-sum-bad             { border-color: #6a2828; }

.dec-alerts {
  margin: 6px 0 10px;
  display: flex; flex-direction: column; gap: 4px;
}
.dec-alert {
  display: flex; gap: 8px; align-items: flex-start;
  padding: 6px 10px; border-radius: 5px;
  background: #2a1a10; border: 1px solid #8a4d20;
  font-size: 12px; color: #fbcfa3;
}
.dec-alert-icon { color: #f08a40; font-weight: 700; }

/* heatmap rows already get inline `background:...` via heatStyle() */
.dec-row td { padding: 4px 6px; }
.dec-played-wrong { color: #ff7a7a; font-weight: 600; }
.dec-evpop { cursor: help; opacity: 0.65; }
.dec-evpop:hover { opacity: 1; }
.dec-blunder { box-shadow: inset 2px 0 0 #ff5050; }
.dec-mistake { box-shadow: inset 2px 0 0 #f0a050; }
.dec-marginal { box-shadow: inset 2px 0 0 #b09030; }
.dec-perfect { box-shadow: inset 2px 0 0 #50c070; }

/* Active-hand recommendation: pulse the badge subtly so the eye finds the
   action that needs decision attention. Animates only while delta is big. */
.lt-rec-badge:not(.lt-rec-marginal) {
  animation: rec-pulse 2.2s ease-in-out infinite;
}
@keyframes rec-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(78, 192, 105, 0.35); }
  50%      { box-shadow: 0 0 0 5px rgba(78, 192, 105, 0); }
}
.lt-rec-marginal { animation: none; }

/* Free-seats indicator on live tiles */
.tile .seats { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 7px; font-size: 11px; color: var(--fg-dim); }
.tile .seat-pips { display: inline-flex; gap: 3px; }
.tile .seat-pip { width: 9px; height: 9px; border-radius: 50%; background: var(--bg-hover); border: 1px solid var(--border-strong); box-sizing: border-box; }
.tile .seat-pip.free { background: var(--pos); border-color: var(--pos); }
.tile .seats-n { font-weight: 700; color: var(--pos); white-space: nowrap; }
.tile .seats-n.full { color: var(--neg); }
.tile.compact .seats { margin-top: 4px; }
.tile.compact .seat-pip { width: 7px; height: 7px; }

/* ============================================================
   Light theme — live felt
   ------------------------------------------------------------
   The felt was authored dark-only: its greens, seat tiles, trace pills
   and popups are hardcoded hex, so flipping data-theme left the whole
   "Стол сейчас" block black-on-white-page. Everything below re-states
   those surfaces for the light palette. Card faces (.lt-card) keep
   their cream face in both themes — a playing card is a playing card —
   but their drop shadows lighten so they don't smear on a white page.
   ============================================================ */

/* Panel + head */
:root[data-theme="light"] .live-felt {
  background: linear-gradient(180deg, #ffffff 0%, #f3f7f4 100%);
  border-color: #d7e2db;
}
:root[data-theme="light"] .felt-head h3 { color: #2f7a55; }

/* Heartbeat pill */
:root[data-theme="light"] .lt-heartbeat { background: #eef4f0; color: #3d7a5c; border-color: #cfe0d6; }
:root[data-theme="light"] .lt-heartbeat.fresh { background: #e3f6e9; color: #12864a; border-color: #a5d9ba; }
:root[data-theme="light"] .lt-heartbeat.slow { background: #fbf3d8; color: #8a6a12; border-color: #e6d089; }
:root[data-theme="light"] .lt-heartbeat.idle { background: #e8f0f8; color: #2f5f8a; border-color: #b9d0e6; }
:root[data-theme="light"] .lt-heartbeat.stalled { background: #fdeaea; color: #b52b25; border-color: #eeaba7; }

/* Banners */
:root[data-theme="light"] .lt-stale-banner {
  background: linear-gradient(180deg, #fdf6de, #f9efcd);
  border-color: #e6d089;
  color: #7a5c0f;
}
:root[data-theme="light"] .lt-stale-banner.severe {
  background: linear-gradient(180deg, #fdeaea, #fadedd);
  border-color: #eeaba7;
  color: #b52b25;
}

/* Rank strip */
:root[data-theme="light"] .lt-rankstrip { background: rgba(0, 0, 0, 0.03); }
:root[data-theme="light"] .lt-rankstrip .rk {
  background: #ffffff;
  border-color: #d7e2db;
}
:root[data-theme="light"] .lt-rankstrip .rk.depleted { background: #fdeaea; border-color: #eeaba7; }
:root[data-theme="light"] .lt-rankstrip .rk.depleted .rank-count { color: #c0392b; }
:root[data-theme="light"] .lt-rankstrip .rk.heavy-depleted { background: #fadedd; border-color: #e08c86; }
:root[data-theme="light"] .lt-rankstrip .rk.heavy-depleted .rank-count { color: #a52a20; }

/* Dealer strip */
:root[data-theme="light"] .live-table .lt-dealer {
  background: linear-gradient(180deg, #ffffff, #eef4f0);
  border-color: #d7e2db;
  box-shadow: 0 2px 8px -6px rgba(0, 0, 0, 0.25) inset;
}
:root[data-theme="light"] .live-table .lt-role { color: #4d7a63; }
:root[data-theme="light"] .live-table .lt-name { color: var(--fg); }
:root[data-theme="light"] .live-table .lt-dealer .lt-score { color: #a67c0d; }

/* Seat tiles */
:root[data-theme="light"] .lt-seat {
  background: linear-gradient(180deg, #ffffff, #f4f8f5);
  border-color: #dde6e0;
}
:root[data-theme="light"] .lt-seat.occupied {
  background: linear-gradient(180deg, #ffffff, #eaf4ee);
  border-color: #b6d6c3;
}
:root[data-theme="light"] .lt-seathead { border-bottom-color: #d3e0d8; }
:root[data-theme="light"] .lt-seathead .lt-num { color: #4d7a63; }
:root[data-theme="light"] .lt-seathead .lt-player { color: var(--fg); }
:root[data-theme="light"] .lt-seathead .lt-country { color: #6a8f7c; }
:root[data-theme="light"] .lt-hand + .lt-hand { border-top-color: #d3e0d8; }
:root[data-theme="light"] .lt-empty { color: #7a9c8a; }

/* Cards keep the cream face; only the shadow lightens for a white page */
:root[data-theme="light"] .lt-card {
  border-color: #c3bba6;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.14),
    0 4px 10px -4px rgba(0, 0, 0, 0.16),
    0 0 0 1px rgba(255, 255, 255, 0.5) inset;
}
:root[data-theme="light"] .lt-card:hover {
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.16),
    0 8px 16px -4px rgba(0, 0, 0, 0.2),
    0 0 0 1px rgba(255, 255, 255, 0.6) inset;
}

/* Hand meta + result badges */
:root[data-theme="light"] .lt-handmeta .lt-score { color: #a67c0d; }
:root[data-theme="light"] .lt-result.win { background: #e3f6e9; }
:root[data-theme="light"] .lt-result.lose,
:root[data-theme="light"] .lt-result.bust { background: #fdeaea; }
:root[data-theme="light"] .lt-result.push { background: #f8f1da; }
:root[data-theme="light"] .lt-result.blackjack { background: #e6eefb; }

/* Decision trace */
:root[data-theme="light"] .lt-trace { border-top-color: #d3e0d8; }
:root[data-theme="light"] .lt-trace-step + .lt-trace-step::before { color: #7aa38c; }
:root[data-theme="light"] .lt-trace-action.is-right   { background: #e3f6e9; color: #11703e; box-shadow: 0 0 0 1px #a5d9ba; }
:root[data-theme="light"] .lt-trace-action.is-marginal { background: #fbf1d6; color: #8a6a12; box-shadow: 0 0 0 1px #e3c77c; }
:root[data-theme="light"] .lt-trace-action.is-wrong   { background: #fdeaea; color: #b02a24; box-shadow: 0 0 0 1px #eeaba7; }
:root[data-theme="light"] .lt-trace-action.is-unknown { background: #eef2ef; color: #55665d; box-shadow: 0 0 0 1px #d3ddd7; }
:root[data-theme="light"] .lt-trace-action--clickable:focus { outline-color: rgba(0, 0, 0, 0.35); }
:root[data-theme="light"] .lt-trace-popup {
  background: #ffffff;
  border-color: #d3ddd7;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.16);
}
:root[data-theme="light"] .lt-trace-popup .lt-trace-ev-pos { color: #12864a; }
:root[data-theme="light"] .lt-trace-popup .lt-trace-ev-neg { color: #c0392b; }
:root[data-theme="light"] .lt-trace-popup .lt-trace-pop-best { background: rgba(18, 134, 74, 0.1); }
:root[data-theme="light"] .lt-trace-popup .lt-rec-pop-played { color: #a67c0d; }
:root[data-theme="light"] .lt-trace-end { color: #a67c0d; }

/* Recommendation block */
:root[data-theme="light"] .lt-rec:hover { background: rgba(0, 0, 0, 0.035); }
:root[data-theme="light"] .lt-rec:focus,
:root[data-theme="light"] .lt-rec.expanded { background: rgba(0, 0, 0, 0.05); }
:root[data-theme="light"] .lt-rec-best,
:root[data-theme="light"] .lt-rec-best .lt-rec-icon { color: #12864a; }
:root[data-theme="light"] .lt-rec-worse,
:root[data-theme="light"] .lt-rec-pop-row.lt-rec-worse { color: #c0392b; }
:root[data-theme="light"] .lt-rec-popup {
  background: #ffffff;
  border-color: #d3ddd7;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.16);
}
:root[data-theme="light"] .lt-rec-pop-row.lt-rec-best { background: rgba(18, 134, 74, 0.1); }
:root[data-theme="light"] .lt-rec-pop-row.lt-rec-pop-cashout-exact {
  background: rgba(176, 122, 16, 0.12);
  border-left-color: #b07a10;
}
:root[data-theme="light"] .lt-rec-badge {
  background: rgba(18, 134, 74, 0.1);
  border-color: rgba(18, 134, 74, 0.35);
}
:root[data-theme="light"] .lt-rec-badge-letter { background: #12864a; color: #ffffff; }
:root[data-theme="light"] .lt-rec-badge-delta { color: #12864a; }
:root[data-theme="light"] .lt-rec-marginal {
  background: rgba(176, 122, 16, 0.12);
  border-color: rgba(176, 122, 16, 0.4);
}
:root[data-theme="light"] .lt-rec-marginal .lt-rec-badge-letter { background: #b07a10; color: #ffffff; }
:root[data-theme="light"] .lt-rec-marginal .lt-rec-badge-delta { color: #8a6a12; }

/* Legacy chip row (панель «Решения») — same dark-only problem */
:root[data-theme="light"] .lt-dec-H { background: #dff2e2; color: #11703e; }
:root[data-theme="light"] .lt-dec-S { background: #f8eed2; color: #8a6a12; }
:root[data-theme="light"] .lt-dec-D { background: #e0ecfb; color: #1d4ed8; }
:root[data-theme="light"] .lt-dec-P { background: #f0e2fb; color: #7429a8; }
:root[data-theme="light"] .lt-dec-R { background: #fbe1e1; color: #b02a24; }
:root[data-theme="light"] .lt-dec-acc.acc-good { background: #e3f6e9; color: #11703e; }
:root[data-theme="light"] .lt-dec-acc.acc-ok   { background: #eef4d9; color: #63701c; }
:root[data-theme="light"] .lt-dec-acc.acc-warn { background: #f8eed2; color: #8a6a12; }
:root[data-theme="light"] .lt-dec-acc.acc-bad  { background: #fbe1e1; color: #b02a24; }


/* ═══════════════════════════════════════════════════════════════════════
   Сукно v2 (2026-09-21, решение владельца по моку tmp/mock/compact-mock.html).
   Один дизайн для двух режимов:
     .live-felt             — большой: слова в трассе, всё влево как раньше;
     .live-felt.is-compact  — суперкомпакт: буквы в трассе, по центру, плотнее.
   Режим ставит table.js только по ширине сукна (< FELT_COMPACT_PX);
   ручной тумблер снят 21.09.
   Всё процентное: карты игроков считаются от ширины места (cqw), карты
   дилера — от ширины сукна, поэтому размер плавно следует за окном, а
   семь мест ВСЕГДА остаются в одном ряду в порядке стола.
   ═══════════════════════════════════════════════════════════════════════ */
.live-felt { container-type: inline-size; container-name: felt; }

/* Полоска шуза: риска заметная (ожидаемое место cut card — 50%), без свечения (владелец 23.09) */
.shoe-bar { overflow: visible; }
.shoe-bar .cut-marker { width: 4px; top: -5px; bottom: -5px; border-radius: 2px; opacity: .8; }

/* Остатки по рангам: читаемо, влево */
.lt-rankstrip { justify-content: flex-start; }
.lt-rankstrip .rk { padding: 3px 7px; font-size: 13px; }
.lt-rankstrip .rk .rank-count { font-size: 14px; font-weight: 700; }

/* Дилер: карты влево с отступом от имени, ~1.3× карт игроков, растут с сукном.
   min-height ряда = высота карты: блок не прыгает между «ждём раздачу» и картами. */
.live-table .lt-dealer { --dw: clamp(48px, 9cqw, 62px); padding: 8px 12px; gap: 10px; margin-bottom: 8px; }
.live-table .lt-dealer-label { min-width: 0; flex: 0 0 auto; margin-right: 14px; }
/* Карты дилера по центру ряда (владелец 21.09) */
.live-table .lt-dealer .lt-cards { min-height: calc(var(--dw) * 84 / 58); justify-content: center; gap: 6px; }
.live-table .lt-dealer .lt-cards .lt-card { max-width: var(--dw); flex-basis: var(--dw); }
.live-table .lt-dealer .lt-score { font-size: 24px; min-width: 40px; }

/* Места: 7 равных колонок в ряд — плитка игрока одной ширины при любой посадке */
.lt-seats { gap: 4px; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.lt-seat { padding: 6px 4px; gap: 5px; min-height: 0; border-radius: 6px; }
.lt-seat.empty { padding: 6px 4px; }
.lt-seat.empty .lt-player { display: none; }
.lt-seathead { gap: 6px; font-size: 11px; padding-bottom: 4px; }
.lt-seathead .lt-num { opacity: .75; }
.lt-seathead .lt-num::after { content: ""; display: inline-block; width: 1px; height: 9px; background: var(--seat-occ-border); margin-left: 6px; vertical-align: -1px; }
.lt-seathead .lt-player { font-size: 12px; flex: 0 1 auto; }
.lt-seathead .lt-country { display: none; }

/* Карты игроков: ширина = 54% ширины места (26–46px), место — контейнер
   (cqw = ширина места). Карты ВСЕГДА лежат внахлёст (владелец 21.09:
   экономия места): минимум 35% карты, а когда N карт не влезают — до 66%,
   чтобы угол с рангом оставался виден. Порядок раздачи слева направо,
   последняя карта сверху с обводкой. `--n` (число карт) ставит table.js.
   Высота блоков ФИКСИРОВАНА (карты / очки / трасса / совет), чтобы плитка не
   прыгала, когда карты только появляются или совет пропадает. */
.lt-seat { container-type: inline-size; }
.lt-seat .lt-hand {
  --cw: clamp(26px, 54cqw, 46px);
  --card-h: calc(var(--cw) * 84 / 58);
  /* карты (+3 обводка) + 5 gap + очки 20 + 5 + трасса 24 + 5 + совет 24 */
  min-height: calc(var(--card-h) + 3px + 83px);
}
.lt-seat .lt-cards {
  min-height: calc(var(--card-h) + 3px); gap: 0; justify-content: flex-start; padding-top: 3px;
}
.lt-seat .lt-cards .lt-card {
  flex: 0 0 var(--cw); width: var(--cw); height: var(--card-h); max-width: none; aspect-ratio: auto;
  container-type: normal; border-radius: 5px;
}
.lt-seat .lt-cards .lt-card + .lt-card {
  margin-left: clamp(calc(var(--cw) * -0.66),
                     calc((100cqw - 8px - var(--cw) * var(--n, 2)) / (var(--n, 2) - 1)),
                     calc(var(--cw) * -0.35));
}
.lt-seat .lt-cards .lt-card .corner.tl { top: calc(var(--cw) * .08); left: calc(var(--cw) * .1); }
.lt-seat .lt-cards .lt-card .corner.br { display: none; }
/* Крайняя правая карта веера открыта целиком — у неё нижний уголок есть, как у дилера (владелец 22.09) */
.lt-seat .lt-cards .lt-card:last-child .corner.br { display: flex; bottom: calc(var(--cw) * .08); right: calc(var(--cw) * .1); }
.lt-seat .lt-cards .lt-card .corner .r { font-size: calc(var(--cw) * .32); }
.lt-seat .lt-cards .lt-card .corner .s { font-size: calc(var(--cw) * .26); }
/* Центральная масть — только у открытой (правой) карты и строго по центру: у карт
   под веером центр закрыт соседом, наружу торчала половинка масти («съехало») */
.lt-seat .lt-cards .lt-card .pip { font-size: calc(var(--cw) * .5); }
.lt-seat .lt-cards .lt-card:not(:last-child) .pip { display: none; }
.lt-seat .lt-cards .lt-card.is-newest { z-index: 1; box-shadow: 0 0 0 2px rgba(240,201,104,.75), 0 3px 8px -3px rgba(0,0,0,.45); }
.lt-seat .lt-cards .lt-card:hover { transform: none; }

/* Очки (и метка 1/2 у сплита) слева, результат справа */
.lt-handmeta { justify-content: flex-start; gap: 5px; flex-wrap: wrap; min-height: 20px; }
.lt-handmeta .lt-score { font-size: 16px; margin-right: auto; }
.lt-result { font-size: 9px; padding: 1px 6px; letter-spacing: 0; }
.lt-hand-tag {
  display: inline-block; font-size: 8px; font-weight: 700; color: var(--felt-role);
  border: 1px solid var(--seat-occ-border); border-radius: 3px; padding: 0 3px; line-height: 1.4;
}
.lt-hand + .lt-hand { margin-top: 2px; padding-top: 4px; }

/* Трасса: слова в большом, буквы в компакте; попап по тапу в обоих.
   Решения и совет — по центру плитки в обоих режимах (владелец 21.09). */
.lt-trace { padding-top: 4px; border-top: 0; gap: 3px; justify-content: center; }
.lt-trace-popup { left: 50%; transform: translateX(-50%); }
.lt-trace-step + .lt-trace-step::before { margin: 0 2px; font-size: 9px; }
.lt-trace-action { font-size: 11px; padding: 2px 7px; }
.lt-trace-action .short { display: none; }
.is-compact .lt-trace-action .full { display: none; }
.is-compact .lt-trace-action .short { display: inline; }

/* Совет: только бейдж «H −25.1%», список вариантов — по тапу.
   Слот держит ровно высоту бейджа (24px), не 68px как раньше: дыры под
   сплитом нет, но и прыжка при появлении/исчезновении совета тоже. */
.lt-rec-slot { min-height: 24px; }
.lt-rec { margin-top: 2px; padding: 2px 0; text-align: center; }
.lt-rec-summary { display: none; }
.lt-rec-badge { margin-top: 0; font-size: 11px; }

/* EV при ev_stale: показываем оценку с «~», а не прячем (владелец 21.09:
   карты считаем всё равно, «примерно» полезнее пустоты). */
.lt-rec.is-approx .lt-rec-badge { border-style: dashed; opacity: .85; }
.lt-rec.is-approx .lt-rec-badge-letter { background: #b9c9bf; }
.lt-rec.is-approx .lt-rec-badge-delta { color: #b9c9bf; }
.lt-rec-pop-ev.is-approx { color: #b9c9bf; }

/* ── Суперкомпакт ── */
.is-compact .lt-seats { gap: 3px; }
.is-compact .lt-seat { padding: 5px 3px; gap: 4px; }
.is-compact .lt-seathead { font-size: 10px; gap: 4px; justify-content: center; }
.is-compact .lt-seathead .lt-num::after { margin-left: 4px; }
.is-compact .lt-seathead .lt-player { font-size: 11px; }
.is-compact .lt-seat .lt-cards { justify-content: center; }
.is-compact .lt-handmeta { justify-content: center; min-height: 19px; }
.is-compact .lt-handmeta .lt-score { font-size: 15px; margin-right: 0; }
.is-compact .lt-result { font-size: 8px; padding: 1px 5px; }
.is-compact .lt-trace { justify-content: center; }
.is-compact .lt-trace-action { padding: 2px 6px; }
.is-compact .lt-trace-popup { left: 50%; transform: translateX(-50%); }

.is-compact .live-table .lt-dealer { padding: 8px 10px; }
.is-compact .live-table .lt-dealer-label { margin-right: 8px; }

/* Шапка: TC слева, стол справа (владелец 21.09) */
.spy-hero { grid-template-columns: 280px 1fr; }
.spy-hero .spy-tc { order: -1; }

/* Шапка в узком окне: без превью, TC и название в одну строку */
@media (max-width: 700px) {
  .spy-hero { grid-template-columns: auto 1fr; gap: 8px; }
  .spy-id .dealer-thumb { display: none; }
  .spy-title h1 { font-size: 16px; }
  .spy-tc { padding: 8px 12px; }
  .spy-tc-value { font-size: 26px; }
  .spy-tc-sub { display: none; }
  header.app #page-title, header.app #page-sub { display: none; }
}

/* Красная карта у дилера: крайняя раздача шуза (владелец 21.09).
   Пол-размера карты дилера (--dw), пластиковая кат-карта. */
.lt-shoe-mark {
  flex: 0 0 auto; width: calc(var(--dw, 58px) * .5); aspect-ratio: 58 / 84;
  border-radius: 4px; cursor: help;
  background: linear-gradient(160deg, #e03a3a, #a51717);
  border: 1px solid #ff8a8a;
  box-shadow: 0 1px 2px rgba(0,0,0,.5), 0 3px 8px -3px rgba(0,0,0,.45);
}
.lt-shoe-mark[hidden] { display: none; }

/* ── Сукно v3 (владелец 21.09, референс GC): совет в рамке по центру, под ним
   история решений столбиком сверху вниз. Рамка стоит и без совета — история
   у всех мест начинается с одной высоты. ── */
.lt-seat .lt-hand {
  /* карты (+3) + очки 20 + рамка совета 30 + трасса ≥24, между ними gap 5 */
  min-height: calc(var(--card-h) + 3px + 92px);
}
.lt-seat .lt-rec-slot {
  min-height: 30px; display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--seat-occ-border); border-radius: 6px; background: transparent;
}
.lt-seat .lt-rec-slot:empty { opacity: .45; }
.lt-seat .lt-rec-slot > .lt-rec { width: 100%; margin: 0; padding: 3px 0; }
.lt-seat .lt-trace { flex-direction: column; flex-wrap: nowrap; align-items: center; gap: 3px; padding-top: 2px; }
.lt-seat .lt-trace-step + .lt-trace-step::before { content: none; }
.is-compact .lt-seat .lt-rec-slot { min-height: 26px; }
:root[data-theme="light"] .lt-seat .lt-rec-slot { border-color: #b9d3c3; background: transparent; }

/* Сукно v3.1 (владелец 21.09): в большом режиме тоже всё по центру плитки;
   номер места снят; ранги — всегда одной строкой, чипы делят ширину поровну. */
.lt-seathead { justify-content: center; }
.lt-seat .lt-cards { justify-content: center; }
.lt-handmeta { justify-content: center; }
.lt-handmeta .lt-score { margin-right: 0; }
.lt-rankstrip { flex-wrap: nowrap; gap: 4px; }
.lt-rankstrip .rk { flex: 1 1 0; min-width: 0; justify-content: center; gap: 4px; padding: 3px 4px; }
.is-compact .lt-rankstrip { padding: 6px 8px; gap: 3px; }
.is-compact .lt-rankstrip .rk { font-size: 11px; gap: 3px; padding: 3px 2px; }
.is-compact .lt-rankstrip .rk .rank-count { font-size: 11px; }
.lt-seat .lt-hand-empty .lt-empty { text-align: center; }

/* Сукно v3.2 (владелец 21.09): история не слипается — пилюли поменьше и
   с воздухом; сплит в истории синий, вердикт у него — цветом рамки. */
.lt-seat .lt-trace { gap: 9px; padding-top: 5px; }
.lt-seat .lt-trace-action { font-size: 10.5px; padding: 1px 7px; line-height: 1.5; }
.lt-trace-action.act-P            { background: #152a4a; color: #8fb8ff; box-shadow: 0 0 0 1px #2f5aa0; }
.lt-trace-action.act-P.is-wrong   { box-shadow: 0 0 0 1px #c04848; }
.lt-trace-action.act-P.is-marginal { box-shadow: 0 0 0 1px #b09030; }
:root[data-theme="light"] .lt-trace-action.act-P { background: #e3ecfc; color: #1d4fb0; box-shadow: 0 0 0 1px #a9c2ef; }
:root[data-theme="light"] .lt-trace-action.act-P.is-wrong { box-shadow: 0 0 0 1px #e08a86; }
:root[data-theme="light"] .lt-trace-action.act-P.is-marginal { box-shadow: 0 0 0 1px #d4b050; }

/* Компакт: результат (WIN/LOSE/CASHOUT) всегда второй строкой под очками —
   у всех мест одинаково, высота строки зарезервирована и без результата. */
.is-compact .lt-handmeta { flex-direction: column; flex-wrap: nowrap; gap: 2px; min-height: 34px; justify-content: flex-start; }
.is-compact .lt-handmeta .lt-score { line-height: 16px; }
.is-compact .lt-seat .lt-hand { min-height: calc(var(--card-h) + 3px + 106px); }
.lt-score-row { display: inline-flex; align-items: center; gap: 5px; }

/* Буква в бейдже совета читаемая (владелец 21.09): была 9px на плашке 14px — мыло. */
.lt-rec-badge { font-size: 12px; gap: 5px; padding: 2px 6px; }
.lt-rec-badge-letter { min-width: 18px; height: 18px; padding: 0 4px; font-size: 12px; font-weight: 800; color: #04110b; border-radius: 3px; }
.lt-rec.is-approx .lt-rec-badge-letter { color: #0e1a14; }

/* Цвет хода — только у квадратика с буквой (владелец 24.09: один зелёный на всё
   приедается, нужна реакция на цвет). Рамка и процент остаются зелёными, у
   marginal — жёлтыми; квадратик держит цвет хода и там. Серый approx главнее. */
.lt-rec:not(.is-approx) .lt-rec-badge.act-H .lt-rec-badge-letter { background: #6ee7a3; }
.lt-rec:not(.is-approx) .lt-rec-badge.act-S .lt-rec-badge-letter { background: #ff5a5a; color: #0b1310; }
.lt-rec:not(.is-approx) .lt-rec-badge.act-D .lt-rec-badge-letter { background: #ff9f43; }
.lt-rec:not(.is-approx) .lt-rec-badge.act-P .lt-rec-badge-letter { background: #5ab4ff; color: #06122a; }
.lt-rec:not(.is-approx) .lt-rec-badge.act-C .lt-rec-badge-letter { background: #000000; color: #ffffff; box-shadow: 0 0 0 1px #5d6b64; }
.lt-rec:not(.is-approx) .lt-rec-badge.act-R .lt-rec-badge-letter { background: #f472b6; }
:root[data-theme="light"] .lt-rec:not(.is-approx) .lt-rec-badge.act-H .lt-rec-badge-letter { background: #12864a; color: #ffffff; }
:root[data-theme="light"] .lt-rec:not(.is-approx) .lt-rec-badge.act-S .lt-rec-badge-letter { background: #d62f2f; color: #0b1310; }
:root[data-theme="light"] .lt-rec:not(.is-approx) .lt-rec-badge.act-D .lt-rec-badge-letter { background: #e0780f; color: #ffffff; }
:root[data-theme="light"] .lt-rec:not(.is-approx) .lt-rec-badge.act-P .lt-rec-badge-letter { background: #1d6fd0; color: #ffffff; }
:root[data-theme="light"] .lt-rec:not(.is-approx) .lt-rec-badge.act-C .lt-rec-badge-letter { background: #000000; color: #ffffff; }
:root[data-theme="light"] .lt-rec:not(.is-approx) .lt-rec-badge.act-R .lt-rec-badge-letter { background: #c9408a; color: #ffffff; }

/* Попап EV под пилюлей истории перекрывала следующая пилюля (у всех z-index 1,
   попап живёт внутри своей) — раскрытая пилюля поднимается над соседями. */
.lt-trace-action.expanded { z-index: 30; }
.lt-rec.expanded { z-index: 30; }
/* Значок подключения стола (админ): белый / жёлтый / красный, поповер по наведению. */
.spy-id { position: relative; }
.conn-badge {
  position: absolute; top: 8px; right: 8px;
  width: 20px; height: 20px; padding: 0; border-radius: 50%;
  border: 1.5px solid currentColor; background: transparent;
  font: italic 700 12px/1 Georgia, serif; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.conn-badge.conn-ok { color: var(--fg); opacity: .75; }
.conn-badge.conn-warn { color: var(--warn); }
.conn-badge.conn-bad { color: var(--neg); }
.conn-badge.conn-copied { color: var(--pos); opacity: 1; }
.conn-badge:hover, .conn-badge:focus-visible { opacity: 1; border-color: currentColor; background: transparent; }
.conn-pop {
  display: none; position: absolute; top: 26px; right: 0; z-index: 30;
  min-width: 230px; padding: 8px 10px; border-radius: 6px;
  background: var(--bg-elev); border: 1px solid var(--border-strong);
  color: var(--fg); font: 12px/1.5 ui-monospace, SFMono-Regular, Consolas, monospace;
  font-style: normal; font-weight: 400; text-align: left; white-space: pre;
  box-shadow: 0 6px 20px rgba(0,0,0,.35);
}
.conn-badge:hover .conn-pop, .conn-badge:focus-visible .conn-pop { display: block; }
.conn-line-warn { color: var(--warn); font-weight: 600; }
.conn-line-bad { color: var(--neg); font-weight: 600; }
.conn-line-dim { color: var(--fg-dim); }
.conn-line-hint { color: var(--fg-faint); margin-top: 4px; font-size: 11px; }

/* ── Сплит в ряд (владелец 22.09, мок tmp/mock/split-mock.html): руки места —
   колонками слева направо, а не столбиком. Каждая рука — свой контейнер, и
   размер карт, и нахлёст (100cqw в формуле) считаются от ширины РУКИ.
   ⚠ cqw внутри custom property вычисляется там, где var() читают (на карте →
   контейнер = рука), поэтому min-height руки (он бы считался от места)
   снят: высоту колонок выравнивает сетка. ── */
.lt-hands { display: flex; flex-direction: column; gap: 5px; }
/* Первая рука сплита — СПРАВА, как у казино (владелец 23.09: жалобы игроков, руки
   стояли зеркально). Сетка идёт справа налево (rtl): 2 | 1, ниже 4 | 3; внутри руки
   направление обычное. Порядок в данных и подписи 1/2, 2/2 не меняются. */
.lt-hands.is-split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; direction: rtl; }
.lt-hands.is-split .lt-hand {
  --cw: clamp(18px, 56cqw, 42px);
  container-type: inline-size; min-width: 0; min-height: 0; margin: 0; padding: 0 3px;
  direction: ltr;
}
/* разделитель колонок — у левой (чётной) руки по правому краю; у правой колонки
   второго ряда (3-я рука) пунктира по внешнему краю места нет */
.lt-hands.is-split .lt-hand + .lt-hand { margin-top: 0; padding-top: 0; border-top: 0; }
.lt-hands.is-split .lt-hand:nth-child(even) { border-right: 1px dashed var(--seat-occ-border); }
:root[data-theme="light"] .lt-hands.is-split .lt-hand:nth-child(even) { border-right-color: #b9d3c3; }
/* Карт больше, чем влезает, — карта ужимается, чтобы N карт с нахлёстом 66%
   (ранг в уголке виден) ВСЕГДА помещались в колонку и не лезли за разделитель.
   Объявлено на .lt-cards, а не на руке: там стоит --n, а var() подставляется
   на том элементе, где объявлен custom property. */
.lt-hands.is-split .lt-cards {
  --cw: clamp(16px, min(56cqw, calc((100cqw - 6px) / (1 + (var(--n, 2) - 1) * .34))), 42px);
  --card-h: calc(var(--cw) * 84 / 58);
}
/* уголок мини-карты читаемый */
.lt-hands.is-split .lt-cards .lt-card .corner .r { font-size: max(10px, calc(var(--cw) * .34)); }
.lt-hands.is-split .lt-cards .lt-card .corner .s { font-size: max(8px, calc(var(--cw) * .27)); }
/* пилюли трассы и бейдж совета не шире колонки */
.lt-hands.is-split .lt-trace-action { padding: 1px 5px; }
.lt-hands.is-split .lt-rec-badge { gap: 3px; padding: 2px 4px; max-width: 100%; box-sizing: border-box; }
.lt-hands.is-split .lt-rec-slot { margin: 0 1px; }
.lt-hands.is-split .lt-rec { padding: 4px 0; }
/* Узкая колонка руки (владелец 23.09: бейдж «D -17%» и «Split» заезжали на
   соседнюю руку): бейдж складывается в столбик — буква над процентом; совсем
   узкая — одна буква, процент в попапе по тапу. Пилюли трассы — буквой, как
   в компакте. Меряется ширина самой руки (она container), а не окна. */
@container (max-width: 60px) {
  .lt-hands.is-split .lt-rec-badge { flex-direction: column; gap: 1px; padding: 2px 3px; }
  .lt-hands.is-split .lt-rec-badge-delta { font-size: 9px; line-height: 1.1; }
  .lt-hands.is-split .lt-trace-action { padding: 1px 4px; }
  .lt-hands.is-split .lt-trace-action .full { display: none; }
  .lt-hands.is-split .lt-trace-action .short { display: inline; }
}
@container (max-width: 34px) {
  .lt-hands.is-split .lt-rec-badge-delta { display: none; }
}
/* активная рука (её доигрывают) — золотые очки, доигранная — приглушена */
.lt-hands.is-split .lt-hand.is-active .lt-score { color: #f0c968; }
.lt-hands.is-split .lt-hand.is-done { opacity: .72; }
/* место со сплитом шире соседей — колонки ставит table.js: в большом режиме
   при 4+ картах в руке сплита, в компакте при любом сплите */
.lt-seats { grid-template-columns: var(--seat-cols, repeat(7, minmax(0, 1fr))); }
.is-compact .lt-seats { grid-template-columns: var(--seat-cols-compact, repeat(7, minmax(0, 1fr))); }

/* ── Компакт + сплит (владелец 22.09) ──
   Совет у руки сплита — только буква, проценты по тапу в попапе. */
.is-compact .lt-hands.is-split .lt-rec-badge-delta { display: none; }
/* Длинный сплит (4+ карты) — маленькие плашки ShadowPlay/Shadow Deck (.pc)
   вместо картинок, которые ужались бы до ~20px. Одним рядом внахлёст от
   ЛЕВОГО края (владелец 22.09): ранг прижат влево и виден из-под соседки,
   последняя плашка открыта целиком. Влезают без нахлёста — зазор 2px;
   не влезают — наезжают сильнее, но ряд не выходит за колонку. Фон белый. */
.lt-chips { display: none; }
.is-compact .lt-hands.has-long .lt-cards { display: none; }
.is-compact .lt-hands.has-long .lt-chips {
  --chw: clamp(16px, 40cqw, 22px);
  display: flex; flex-wrap: nowrap; justify-content: flex-start; align-items: center;
  padding: 3px 0 0 1px; min-height: 24px;
}
.lt-chip {
  flex: 0 0 var(--chw); width: var(--chw); box-sizing: border-box; position: relative;
  font-family: "Cascadia Code", Consolas, ui-monospace, monospace; font-weight: 700;
  font-size: 11px; line-height: 1.25; letter-spacing: -.5px; white-space: nowrap;
  overflow: hidden; text-align: left; padding: 1px 0 1px 2px; border-radius: 3px;
  background: #f4efe1; color: #15191c; border: 1px solid #cfc6ae;
  box-shadow: -1px 0 2px rgba(0,0,0,.45);
}
.lt-chip.lt-red { color: #c62828; }
.lt-chip + .lt-chip {
  margin-left: clamp(calc(var(--chw) * -0.72),
                     calc((100cqw - 2px - var(--chw) * var(--n, 2)) / (var(--n, 2) - 1)),
                     2px);
}
.lt-chip.is-newest { z-index: 1; box-shadow: 0 0 0 2px rgba(240,201,104,.8), -1px 0 3px rgba(0,0,0,.5); }
