/* Геометрия стола: разделы 1-6 разбора лейаута.
   Внутри #stage координаты пиксельные, вписывание одним transform: scale(). */

.page--table { overflow: hidden; }

#stage-wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

#stage {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--stage-w);
  height: var(--stage-h);
  transform-origin: 50% 50%;
  transform: translate(-50%, -50%) scale(1);
}

/* координата = центр элемента (§2.3) */
.at {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* --------------------------------------------------------------- овал */

.rim {
  position: absolute;
  left: 50%;
  top: var(--oval-y);
  width: var(--oval-w);
  height: var(--oval-h);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--rim);
  box-shadow: var(--rim-shadow);
  z-index: var(--z-felt);
}

.felt {
  position: absolute;
  inset: var(--rim-th);
  border-radius: 50%;
  background: var(--felt);
  box-shadow: var(--felt-inset);
}

/* --------------------------------------------------------------- поды */

.seat {
  width: var(--pod-w);
  height: var(--pod-h);
  z-index: var(--z-pod);
}
#seat-ai { top: var(--y-ai-seat); }
#seat-hero { top: var(--y-hero-seat); }

/* ОТСТУПЛЕНИЕ ОТ §3.1 (паддинг 6px сверху/снизу, gap 2px): строк в плашке не
   две, как в разборе, а ТРИ - ник, стек и добавленная при вёрстке вторая
   строка (итог руки, пометка ожидания). Арифметика десктопа: плашка 56, минус
   рамка 2+2 = 52 полезных; строки при line-height 1.1 просят 16.5 + 19.8 +
   13.2 = 49.5 плюс два зазора по 2 = 53.5. Не влезало на 13.5px, и flex-shrink
   ужимал КОРОБКИ строк ниже их же line-height: строка стека получала 14.4px
   вместо 19.8 и `overflow: hidden` срезал буквы по нижней кромке - ровно то,
   что владелец увидел на скриншоте 2026-08-29 («38bb» без пары пикселей снизу).
   Автоминимум flex (`min-height: auto`) тут не спасает: он отключён как раз
   тем `overflow: hidden`, который нужен многоточию в длинном нике.
   Лечится тремя вещами: паддинг 1px, зазор 0 и вторая строка 11px вместо 12
   (48.4 из 50 доступных - запас 1.6px), строки получают `flex: 0 0 auto` и
   больше не сжимаются НИКОГДА, а их коробка обрезки расширена паддингом с
   отрицательным полем (см. ниже). Телефон: 40 - 4 - 2 = 34 полезных, вторая
   строка там спрятана, строки просят 12.1 + 16.5 = 28.6 - запас 5.4px.
   Геометрия плашки (264x56 и 172x40, радиус) не изменилась. */
.seat__plate {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0;
  padding: 1px 18px;
  border-radius: var(--pod-r);
  background: var(--pod-bg);
  box-shadow: var(--pod-shadow);
  border: 2px solid transparent;
  overflow: hidden;
}
/* сторона аватара: он накрывает плашку на (аватар - вынос), и текст обязан
   начинаться за ним - иначе ник уезжает под кружок (разбор §3.1 даёт 24px,
   но при аватаре 60 и выносе 20 этого не хватает; исправлено при вёрстке) */
.seat--hero .seat__plate {
  padding-left: calc(var(--avatar) - var(--avatar-out) + 8px);
  padding-right: 18px;
}
.seat--ai .seat__plate {
  padding-right: calc(var(--avatar) - var(--avatar-out) + 8px);
  padding-left: 18px;
}

/* Строки плашки НЕ сжимаются и НЕ обрезаются по вертикали.

   `flex: 0 0 auto` - чтобы коробка строки никогда не стала ниже своего
   line-height (см. арифметику выше).

   Паддинг 3px с таким же отрицательным полем - чтобы коробка ОБРЕЗКИ была выше
   строки, а раскладка от этого не поехала: `overflow: hidden` режет по краю
   паддинга, а line-height 1.1 меньше собственной высоты шрифта (у Roboto и
   Arial Rounded это ~1.17em), поэтому кончики букв торчат из строки и без
   flex-shrink. Многоточию в нике этот паддинг не мешает - оно про ширину. */
.seat__name,
.seat__value,
.seat__sub {
  flex: 0 0 auto;
  padding-block: 3px;
  margin-block: -3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.seat__name {
  font: 600 var(--pod-name)/1.1 var(--font-ui);
  letter-spacing: .2px;
  color: var(--text);
}
.seat__value {
  font: 700 var(--pod-value)/1.1 var(--font-display);
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.seat__sub {
  /* 11px, а не 12: полтора пикселя из бюджета плашки (см. арифметику выше) */
  font: 400 11px/1.1 var(--font-ui);
  color: var(--text-muted);
}
/* Пустая вторая строка ДЕРЖИТ высоту: пока рука идёт, ей нечего сказать (единица
   теперь одна, дублировать стек нечем), но плашка не должна прыгать, когда в
   конце руки там появляется итог, а у ИИ - пометка ожидания. */
.seat__sub:empty::before { content: "\00a0"; }
/* Ожидание сверх calm_wait_s - НОРМАЛЬНАЯ работа: строка становится заметнее,
   но не красной. Тревожный цвет включается только рядом со сторожем пула. */
.seat__sub.is-wait { color: var(--text); }
.seat__sub.is-danger { color: var(--danger); }
/* итог руки во второй строке пода (стек стола на итоге у обоих один) */
.seat__sub.is-plus { color: var(--brand-lite); }
.seat__sub.is-minus { color: var(--danger); }

.seat__avatar {
  position: absolute;
  top: 50%;
  width: var(--avatar);
  height: var(--avatar);
  margin-top: calc(var(--avatar) / -2);
  border-radius: 50%;
  border: 2px solid var(--line);
  display: grid;
  place-items: center;
  background: radial-gradient(circle at 35% 30%, #4a4a4a, #2a2a2a);
  z-index: 1;
}
.seat--hero .seat__avatar { left: calc(var(--avatar-out) * -1); }
.seat--ai .seat__avatar {
  right: calc(var(--avatar-out) * -1);
  background: radial-gradient(circle at 35% 30%, #0aa864, var(--brand-dark));
}
.seat__initial {
  font: 700 calc(var(--avatar) * .4)/1 var(--font-display);
  color: var(--text-strong);
  text-transform: uppercase;
}

.seat__bar {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 4px;
  border-radius: 0 0 var(--pod-r) var(--pod-r);
  overflow: hidden;
  opacity: 0;
}
.seat__bar::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 35%;
  height: 100%;
  background: var(--brand);
  animation: seatbar 1.1s linear infinite;
}
@keyframes seatbar {
  from { transform: translateX(-100%); }
  to   { transform: translateX(285%); }
}

/* индикатор неопределённой длительности, НЕ таймер (§3.2, Р17) */
.seat.is-thinking .seat__bar { opacity: 1; }

.seat.is-active > .seat__plate,
.seat.is-thinking > .seat__plate {
  border-color: var(--brand);
  box-shadow: 0 0 20px var(--brand-glow), var(--pod-shadow);
}
.seat.is-active .seat__name,
.seat.is-thinking .seat__name { color: var(--text-strong); }

.seat.is-allin > .seat__plate { border-color: var(--gold); }
.seat.is-allin .seat__value { color: var(--gold); }

.seat.is-winner > .seat__plate {
  border-color: var(--gold);
  box-shadow: 0 0 28px var(--gold-glow), var(--pod-shadow);
}
.seat.is-folded { opacity: .45; }

.seat.is-showdown .seat__value { font-size: 13px; font-weight: 600; color: var(--gold); }

.seat__delta {
  position: absolute;
  left: 50%;
  top: -18px;
  transform: translateX(-50%);
  font: 700 16px/1 var(--font-display);
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  opacity: 0;
  pointer-events: none;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .8);
}
.seat--ai .seat__delta { top: auto; bottom: -18px; }
.seat__delta.is-on { animation: deltapop 1.2s ease-out; }
@keyframes deltapop {
  0%   { opacity: 0; transform: translate(-50%, 6px); }
  18%  { opacity: 1; transform: translate(-50%, -2px); }
  75%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -14px); }
}

/* -------------------------------------------------------------- карты */

.card {
  position: relative;
  flex: 0 0 auto;
  background: var(--card-face);
  border: 1px solid var(--card-edge);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  --suit-color: var(--suit-black);
  --rank-size: var(--rank-board);
  --suit-size: var(--suit-board);
  width: var(--card-board-w);
  height: var(--card-board-h);
  border-radius: var(--card-board-r);
}
.card.s-s { --suit-color: var(--suit-s); }
.card.s-h { --suit-color: var(--suit-h); }
.card.s-d { --suit-color: var(--suit-d); }
.card.s-c { --suit-color: var(--suit-c); }

.card__corner {
  position: absolute;
  left: 5px;
  top: 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}
.card__rank {
  font: 700 var(--rank-size)/1 var(--font-display);
  color: var(--suit-color);
  font-variant-numeric: tabular-nums;
}
.card__suit-sm {
  width: var(--suit-sm);
  height: var(--suit-sm);
  fill: var(--suit-color);
}
.card__suit-big {
  position: absolute;
  right: 5px;
  bottom: 5px;
  width: var(--suit-size);
  height: var(--suit-size);
  fill: var(--suit-color);
  opacity: .95;
}

.card--hero {
  width: var(--card-hero-w); height: var(--card-hero-h);
  border-radius: var(--card-hero-r);
  --rank-size: var(--rank-hero); --suit-size: var(--suit-hero);
}
.card--ai {
  width: var(--card-ai-w); height: var(--card-ai-h);
  border-radius: var(--card-ai-r);
  --rank-size: var(--rank-ai); --suit-size: var(--suit-ai);
}

/* рубашка: своя графика, ничего чужого (§4.3) */
.card--back {
  background: repeating-linear-gradient(45deg,
    var(--card-back-a) 0 6px, var(--card-back-b) 6px 12px);
  box-shadow: var(--card-shadow), inset 0 0 0 3px var(--card-face),
              inset 0 0 0 4px var(--gold-dim);
}
.card--back .card__corner, .card--back .card__suit-big { display: none; }

.card.is-best {
  transform: translateY(-8px);
  border-color: var(--gold);
  box-shadow: 0 0 18px var(--gold-glow);
}
/* Пятёрки проигравшего своей подсветки НЕ имеют (правка 2026-08-29): горит
   только выигравшая комбинация, остальные карты - затухшие. Класса
   `.is-mine-best` больше нет ни здесь, ни в render.js. */
.card.is-dim { filter: brightness(.5) saturate(.65); }

.pair { display: flex; z-index: var(--z-cards); }
#hero-cards { top: var(--y-hero-cards); gap: var(--card-hero-gap); }
#ai-cards { top: var(--y-ai-cards); gap: var(--card-ai-gap); }

.board {
  top: var(--y-board);
  display: flex;
  gap: var(--card-board-gap);
  z-index: var(--z-board);
  /* Слоты стоят на месте, а контейнер сдвинут так, чтобы выложенные карты
     были по оси стола: до флопа борд не съезжает влево на два пустых слота.
     Отступление от §4.4, согласовано координатором. */
  --board-shift: 0px;
  transform: translate(-50%, -50%) translateX(var(--board-shift));
  transition: transform var(--dur-board) cubic-bezier(.2, .7, .3, 1);
}
.board .card.is-hidden { visibility: hidden; }

.card.is-dealt { animation: dealin var(--dur-card) cubic-bezier(.2, .7, .3, 1) backwards; }
@keyframes dealin {
  from { transform: scale(.55) rotate(-12deg); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.card.is-opened { animation: boardin var(--dur-board) cubic-bezier(.2, .7, .3, 1) backwards; }
@keyframes boardin {
  from { transform: translateY(-14px) scale(.86) rotateY(90deg); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.pair.is-mucked { transition: transform var(--dur-flip), opacity var(--dur-flip); }
.pair.is-mucked.is-gone { transform: translate(-50%, -50%) translateY(-18px) rotate(-6deg); opacity: 0; }

/* --------------------------------------------------------- банк и фишки */

.pot {
  top: var(--y-pot);
  z-index: var(--z-pot);
  /* Пилюля и стопка фишек - один узел в ряд, как у ставок игроков
     (`.bet`): те же 8px между фишками и числом, тот же порядок чтения.
     Стопка справа от пилюли, ближе к центру сукна: слева от банка сукно
     кончается бортом, и высокая стопка вылезала бы на него. */
  display: flex;
  align-items: center;
  gap: 8px;
  /* Сдвиг влево от оси - см. `--pot-shift` в tokens.css: там же и причина
     отступления от §5.2. Баннер результата остаётся НА ОСИ: он появляется,
     когда пилюля уже спрятана, ставок на столе нет и спорить ему не с чем. */
  transform: translate(-50%, -50%) translate(var(--pot-shift), var(--pot-drop));
}
.pot__line {
  padding: 4px 14px;
  border-radius: 14px;
  background: rgba(0, 0, 0, .35);
  border: 1px solid rgba(255, 255, 255, .08);
  font: 600 var(--pot-font)/1.2 var(--font-display);
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pot__label { color: var(--text-muted); margin-right: 4px; }

.banner {
  top: var(--y-pot);
  z-index: var(--z-pot);
  padding: 5px 16px;
  border-radius: 14px;
  background: rgba(0, 0, 0, .55);
  border: 1px solid var(--gold-dim);
  font: 700 16px/1.2 var(--font-display);
  color: var(--gold);
  white-space: nowrap;
  text-align: center;
}
html.lay-phone .banner { font-size: 13px; padding: 4px 10px; }

.bet {
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: var(--z-chips);
}
#bet-ai { top: var(--y-ai-bet); }
#bet-hero { top: var(--y-hero-bet); }

/* Коробка стопки одна и та же у ставок и у банка: фишки в ней позиционируются
   абсолютно от НИЖНЕГО края, поэтому высокая стопка растёт вверх, а низ
   остаётся на месте - и у банка, и у ставок это одна и та же манера. */
.bet__stack, .pot__stack { position: relative; width: 36px; height: 34px; flex: 0 0 auto; }
.bet__labels { text-align: left; }
.bet__amount {
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(0, 0, 0, .45);
  font: 700 var(--bet-font)/1.2 var(--font-display);
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.chip {
  position: absolute;
  left: 0;
  width: 34px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid var(--chip-edge);
  background: var(--chip-100);
}
/* Прирост стопки банка: новая фишка падает сверху, уже лежащие не трогаются.
   Длительность - общая ручка `--dur-chip`, поэтому выключатель анимаций в
   настройках и `prefers-reduced-motion` гасят её вместе со всем остальным
   (в этом случае JS класс даже не вешает - фишка просто появляется). */
.chip.is-dropped {
  animation: chipdrop var(--dur-chip) cubic-bezier(.2, .7, .3, 1) backwards;
}
@keyframes chipdrop {
  from { transform: translateY(-16px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

.chip::after {
  content: "";
  position: absolute;
  inset: 2px;
  border-radius: 50%;
  background: repeating-conic-gradient(var(--chip-edge) 0deg 8deg, transparent 8deg 90deg);
  opacity: .55;
}
.chip.v5 { background: var(--chip-5); }
.chip.v25 { background: var(--chip-25); }
.chip.v100 { background: var(--chip-100); }
.chip.v500 { background: var(--chip-500); }
.chip.v1000 { background: var(--chip-1000); }

/* ------------------------------------------------------ дилер-баттон */

.dealer {
  position: absolute;
  width: var(--dealer-size);
  height: var(--dealer-size);
  margin-left: calc(var(--dealer-size) / -2);
  margin-top: calc(var(--dealer-size) / -2);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff, #d9d9d9);
  border: 1px solid rgba(0, 0, 0, .35);
  box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
  display: grid;
  place-items: center;
  z-index: var(--z-button);
  left: var(--x-dealer-hero);
  top: var(--y-dealer-hero);
  transition: left var(--dur-move) ease, top var(--dur-move) ease;
}
.dealer span {
  font: 700 var(--dealer-font)/1 var(--font-display);
  color: var(--bg-page);
}
.dealer.is-ai { left: var(--x-dealer-ai); top: var(--y-dealer-ai); }

/* ------------------------------------------------------- служебное */

.fly {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: var(--z-fly);
}
.fly .chip, .fly .card { position: absolute; }

.flags {
  position: absolute;
  left: 50%;
  top: 8px;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  z-index: var(--z-pot);
}
.flag {
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .5);
  border: 1px solid var(--gold-dim);
  font-size: 11px;
  color: var(--gold);
  white-space: nowrap;
}

.connstrip {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  padding: 4px 0;
  text-align: center;
  background: var(--danger);
  color: var(--text-strong);
  font-size: 12px;
  z-index: var(--z-fly);
}
