/* ═══════════════════════════════════════════════════════════
   ЭПОХА · combat.css — боевой экран (редизайн: чёрный+плетение,
   портреты по углам с «кровь-в-колбе» HP-кольцами, доска с кубиком
   и тёплым сиянием, лог под катом, круглая вдавленная кнопка,
   бесконечная карусель-рука). Токены — из style.css/game.css.

   ВХОД — двойное затухание: сперва весь экран гаснет в чёрное
   (.combat-veil opacity 0→1), затем ИЗ черноты проявляется бой
   (.cbt-stage opacity 0→1 с задержкой).
   ═══════════════════════════════════════════════════════════ */

/* Фаза 1: сплошная чёрная вуаль поверх игры. */
.combat-veil{
  position:fixed; inset:0; z-index:80; overflow:hidden;
  background:#000; opacity:0; transition:opacity .40s ease;
}
.combat-veil.is-active{opacity:1;}

/* Фаза 2: сцена боя проявляется из черноты (с задержкой — после затемнения).
   ФОН (0.83.0) — живописный пейзаж, один на весь поединок: файл выбирает
   combat.js и ставит инлайном (background-image), первым слоем идёт ровная
   вуаль rgba(0,0,0,.55). Прежнее оформление — чёрный радиальный градиент,
   ромбовидное плетение (.cbt-tex), зерно (.cbt-tex2) и тёплое кольцевое
   сияние под костью (.cbt-glow) — снято целиком: картина рисует сцену сама,
   а поверх неё эти слои читались как грязь на стекле.
   Резервный цвет остаётся чёрным — пока картинка грузится, экран не мигает. */
.cbt-stage{
  position:absolute; inset:0; overflow:hidden; opacity:0;
  transition:opacity .52s ease .40s;
  background-color:#050403;
  background-position:center; background-size:cover; background-repeat:no-repeat;
}
.combat-veil.is-active .cbt-stage{opacity:1;}
.cbt-stage > *{position:absolute;}

/* Верх-лево: режим/ход. */
.cbt-top{top:24px; left:32px; z-index:6; display:flex; flex-direction:column; gap:1px;}
.cbt-title{font-family:var(--f-display); color:var(--gold); font-size:1rem; letter-spacing:.04em;}
.cbt-turnno{font-family:var(--f-data); font-size:.8rem; color:var(--ink);}

/* Верх-центр: статус хода. */
.cbt-status{top:30px; left:50%; transform:translateX(-50%); z-index:6;
  font-family:var(--f-data); font-size:.9rem; color:var(--ink-soft); text-align:center; max-width:60vw;}
.cbt-status .yours{color:var(--gold);} .cbt-status .theirs{color:var(--muted);}
.cbt-timer{color:var(--ember); font-variant-numeric:tabular-nums;}

/* Лог под катом (слева-сверху, под режимом). */
.cbt-logwrap{top:70px; left:32px; z-index:6; display:flex; flex-direction:column; gap:8px;}
.cbt-logtab{font-family:var(--f-data); font-size:.78rem; color:var(--ink-soft); cursor:pointer; user-select:none;
  background:rgba(20,14,8,.6); border:1px solid var(--edge-glass); border-radius:999px; padding:5px 13px; width:max-content;}
.cbt-logtab:hover{background:rgba(226,183,94,.14);}
.cbt-feed{display:none; flex-direction:column; gap:8px; width:320px; max-height:52vh; overflow:auto; padding-right:4px;}
.cbt-feed.open{display:flex;}
.cbt-feed-empty{font-family:var(--f-data); font-size:.76rem; color:var(--muted);}
.cbt-round{font-family:var(--f-data); font-size:.72rem; line-height:1.35; color:var(--ink-soft);
  border-left:2px solid rgba(226,183,94,.3); padding:1px 0 1px 10px;}
.cbt-round--me{border-left-color:rgba(226,183,94,.55);}
.cbt-round--opp{border-left-color:rgba(192,90,62,.6);}
.cbt-round--skip{opacity:.55; border-left-color:rgba(160,145,120,.4);}
.cbt-round .r-who{color:var(--ink);} .cbt-round .r-die{color:var(--gold);}
.cbt-round .r-dmg{color:var(--ember);} .cbt-round .r-blk{color:#8fb0c8;}
.cbt-round .r-cardblk{color:var(--gold);} .cbt-round .r-hp{color:var(--muted);}
.cbt-round .r-crit{color:var(--ember); font-weight:700; letter-spacing:.06em;}
/* Яд (0.47.0): болотная зелень — читается отдельно от алого урона и золота карт. */
.cbt-round .r-poison{color:#8fbf4a;}
.cbt-round .r-poison-immune{color:#5f7a52;}

/* ── Герои по углам: соперник top-right, игрок bottom-left (симметрично) ── */
.cbt-hero{z-index:5; display:flex; flex-direction:column; align-items:center; gap:8px;}
.cbt-hero--opp{top:22px; right:36px;}
.cbt-hero--me{bottom:22px; left:36px;}
.cbt-hpwrap{position:relative; width:210px; height:210px; flex:none;}
.cbt-ring{position:absolute; inset:0; width:210px; height:210px;}
.cbt-hpwrap::after{content:''; position:absolute; inset:14px; border-radius:50%; pointer-events:none;
  background:radial-gradient(60% 50% at 32% 26%, rgba(255,255,255,.14), rgba(255,255,255,0) 60%);}
.cbt-portrait{position:absolute; inset:16px; border-radius:50%; overflow:hidden; border:2px solid rgba(20,14,8,.8);
  background:radial-gradient(circle at 50% 38%, #241a10, #0c0805 74%); display:grid; place-items:center;}
.cbt-portrait img{width:100%; height:100%; object-fit:cover;}
.cbt-portrait .glyph{font-size:3.4rem; color:rgba(226,183,94,.6);}
.cbt-hero.is-active .cbt-portrait{border-color:var(--gold); box-shadow:0 0 18px rgba(226,183,94,.3);}
.cbt-hinfo{text-align:center;}
.cbt-hname{font-family:var(--f-display); color:var(--ink); font-size:1.25rem; letter-spacing:.02em;}
.cbt-hero.is-active .cbt-hname{color:var(--gold);}
.cbt-hkind{font-family:var(--f-data); color:var(--muted); font-size:.82rem; text-transform:uppercase; letter-spacing:.06em; margin:2px 0 5px;}
.cbt-hstat{display:flex; gap:12px; justify-content:center; font-family:var(--f-data); font-size:.84rem; flex-wrap:wrap;}
.cbt-hp-num{color:#e88a86;} .cbt-rolls{color:var(--gold);}
.cbt-shield{color:#8fb0c8; background:rgba(90,140,180,.14); border:1px solid rgba(120,170,205,.4); border-radius:999px; padding:0 9px;}

/* Доска: кубик + сияние + тень.
   0.79.0: кость выросла в 1.6 раза (150 → 240). Тень и отступ под неё
   подняты тем же множителем, иначе кость «висела» бы над старым пятном. */
.cbt-board{left:50%; top:44%; transform:translate(-50%,-50%); z-index:3;
  display:flex; flex-direction:column; align-items:center; gap:8px;}
.cbt-die-shadow{position:absolute; left:50%; top:102px; width:253px; height:86px; transform:translate(-50%,-50%);
  background:radial-gradient(closest-side, rgba(0,0,0,.82), rgba(0,0,0,0) 72%); filter:blur(3px); z-index:-1;}
.cbt-die-host{width:240px; height:240px; flex:none; display:grid; place-items:center;}
/* 3D-кубик (dice3d.js): прозрачный WebGL-канвас в том же хосте.
   Тень и центр свечения привязаны к .cbt-die-host — их не трогаем. */
.die3d{display:block; width:240px; height:240px; pointer-events:none;}
/* Плоский жетон — запасной вид там, где нет WebGL. Растёт вместе с костью
   (122 → 195, тот же множитель 1.6): игрок со старым браузером не должен
   получать кубик вдвое мельче, чем все остальные. */
.die2d{width:195px; height:195px; border-radius:35px; display:grid; place-items:center;
  background:linear-gradient(158deg,#f6d885 4%,#dcac52 52%,#bd8a2c 96%); border:1px solid var(--rim);
  box-shadow:inset 0 2px 0 rgba(255,246,220,.6), inset 0 -8px 15px rgba(120,80,20,.45), 0 16px 30px rgba(0,0,0,.75), 0 0 40px rgba(255,225,155,.14);}
.die2d.is-rolling{animation:die-breathe .5s ease-in-out infinite;}
.die2d.is-landed{animation:die-land .34s cubic-bezier(.3,.5,.4,1);}
.die2d-num{font-family:var(--f-display); font-weight:700; font-size:5rem; color:#3a2a10; line-height:1;
  text-shadow:0 1px 0 rgba(255,246,220,.55); pointer-events:none; font-variant-numeric:tabular-nums;}
.die2d-num.is-big{font-size:3.2rem;}
@keyframes die-pop{0%{transform:scale(1)} 42%{transform:scale(1.13)} 100%{transform:scale(1)}}
/* 0.69.0 приземление кубика: падение → касание → мелкий отскок целиком
   (тот же язык твёрдого тела, что у фишки на карте). */
@keyframes die-land{0%{transform:translateY(-26%)} 55%{transform:translateY(0)} 75%{transform:translateY(-7%)} 100%{transform:translateY(0)}}
@keyframes die-breathe{0%,100%{transform:scale(1)} 50%{transform:scale(1.04)}}
.cbt-result{min-height:40px; display:flex; align-items:baseline; justify-content:center; gap:8px;}
.cbt-result .rv-lbl{font-family:var(--f-data); font-size:.72rem; letter-spacing:.12em; text-transform:uppercase; color:var(--muted);}
.cbt-result .rv-num{font-family:var(--f-display); font-weight:700; font-size:2.3rem; line-height:1; color:var(--gold);}
.cbt-result.is-spin .rv-num{color:var(--muted);}
.cbt-result.is-block .rv-num{color:#8fb0c8;}
.cbt-result.is-skip .rv-num{color:var(--muted); font-size:1.5rem;}
/* Критический удар Следопыта (0.45.0): кубик наливается кровью, метка бьёт вспышкой.
   Погашенный бронёй крит тоже помечен (is-block + is-crit) — но число остаётся
   холодным: удар был громовым, броня его съела. */
.cbt-result.is-crit .rv-num{color:var(--ember); text-shadow:0 0 18px rgba(200,40,30,.55); font-size:2.8rem;}
.cbt-result.is-block.is-crit .rv-num{color:#8fb0c8; text-shadow:none; font-size:2.3rem;}
.cbt-result .rv-crit{font-family:var(--f-data); font-size:.72rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ember); align-self:center; padding:2px 7px; border:1px solid rgba(200,40,30,.5); border-radius:3px;
  animation:crit-flash .6s ease-out;}
.cbt-result.is-block .rv-crit{color:#8fb0c8; border-color:rgba(143,176,200,.45); animation:none;}
@keyframes crit-flash{0%{transform:scale(1.35); opacity:0} 40%{transform:scale(1); opacity:1} 100%{opacity:1}}
.cbt-die-caption .crit{color:var(--ember); font-weight:700; letter-spacing:.08em;}
.cbt-die-caption{min-height:20px; font-family:var(--f-data); font-size:.9rem; color:var(--ink-soft); text-align:center;}
.cbt-die-caption b{color:var(--gold);} .cbt-die-caption .dmg{color:var(--ember);} .cbt-die-caption .blk{color:#8fb0c8;}

/* ── Слот выбранной карты «на столе», слева от кубика (0.71.0) ──
   Выбор карты разведён с броском: карта кладётся сюда и уходит в игру лишь по
   кнопке «Бросок». Виден всегда: пустой — подсказка, заполнен — миниатюра
   (крестик снимает). При awaiting_input (карта уже сыграна, ждёт N) — заперт,
   подпись «в игре», без крестика. Позиция: колонка слева от кубика, по
   вертикали — на уровне его центра (0.79.0: кость выросла до 240px, центр
   уехал с 75 на 120px, отступ поднят с 64 на 102px тем же множителем). */
.cbt-play-slot{position:absolute; top:102px; right:calc(50% + 178px); transform:translateY(-50%);
  width:150px; min-height:225px; z-index:4;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px;
  border-radius:14px; padding:10px;}
.cbt-play-slot.is-empty{border:1px dashed rgba(226,183,94,.3); background:rgba(20,14,7,.34);}
.cps-cap{font-family:var(--f-data); font-size:.64rem; letter-spacing:.1em; text-transform:uppercase; color:var(--gold);
  text-shadow:0 1px 3px rgba(0,0,0,.85);}
.cbt-play-slot.is-locked .cps-cap{color:#8fb0c8;}
/* Карта на столе (0.83.0): лицевая сторона из арта, размер по её пропорции
   (130 = 150 слота минус отступы, 130/0.668 ≈ 195). Название — по центру
   пергамента, отступы приходят классом редкости (см. .card-face в game.css). */
.cbt-slot-card{width:100%; height:195px; filter:drop-shadow(0 8px 16px rgba(0,0,0,.6));}
.cbt-play-slot.is-filled .cbt-slot-card{filter:drop-shadow(0 0 9px rgba(226,183,94,.7)) drop-shadow(0 8px 16px rgba(0,0,0,.6));}
.cbt-play-slot.is-locked .cbt-slot-card{filter:drop-shadow(0 0 9px rgba(143,176,200,.7)) drop-shadow(0 8px 16px rgba(0,0,0,.6));}
.cbt-slot-card .cc-name{font-family:var(--f-body); font-size:.86rem; line-height:1.2;}
.cps-clear{position:absolute; top:4px; right:4px; width:24px; height:24px; border-radius:50%;
  border:1px solid var(--rim); background:linear-gradient(180deg,#e9c67a,#c2922f); color:#2a1e0c;
  font-size:1.05rem; line-height:1; cursor:pointer; display:grid; place-items:center; box-shadow:0 2px 5px rgba(0,0,0,.5);}
.cps-clear:hover{filter:brightness(1.08);}
.cps-clear:active{transform:translateY(1px);}

/* Выбранная (но ещё не сыгранная) карта в руке — золотое свечение ярче pending.
   Рамкой-outline её больше не обводим: она прямоугольная, а карта — с рваным
   краем, и обводка висела бы вокруг пустоты. */
.cbt-card.is-selected{filter:drop-shadow(0 0 10px rgba(226,183,94,.85)) drop-shadow(0 0 22px rgba(226,183,94,.5)) drop-shadow(0 12px 22px rgba(0,0,0,.7));}
.cbt-card.is-center.is-selected{filter:drop-shadow(0 0 10px rgba(226,183,94,.85)) drop-shadow(0 0 24px rgba(226,183,94,.55)) drop-shadow(0 12px 22px rgba(0,0,0,.7));}

/* ── Низ: карусель-рука + круглая кнопка + управление ── */
.cbt-bottom{left:0; right:0; bottom:0; z-index:6; height:230px;}
.cbt-bottom > *{position:absolute;}

/* Бесконечная карусель: центр над кубиком, бока — в тень. */
.cbt-hand-wrap{bottom:26px; left:50%; transform:translateX(-50%); display:flex; align-items:center; gap:6px;}
.cbt-nav{width:38px; height:38px; border-radius:50%; border:1px solid var(--edge-glass); background:rgba(20,14,8,.55);
  color:var(--gold); font-size:1.25rem; line-height:1; cursor:pointer; flex:none;}
.cbt-nav:hover{background:rgba(226,183,94,.14);}
.cbt-carousel{width:420px; height:238px; position:relative; overflow:hidden; touch-action:pan-y; cursor:grab;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 24%,#000 76%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 24%,#000 76%,transparent 100%);}
.cbt-carousel.grabbing{cursor:grabbing;}
.cbt-track{position:absolute; top:26px; left:50%; transform:translateX(-50%); display:flex; gap:16px;}
/* Карта в руке (0.83.0): 134×200 — пропорция арта 0.668. Тень идёт через
   drop-shadow, а не box-shadow: у карты рваный край в альфе, прямоугольная
   тень торчала бы из-под него углами. */
.cbt-card{width:134px; height:200px; flex:none;
  filter:drop-shadow(0 10px 18px rgba(0,0,0,.6));
  cursor:pointer; user-select:none; transition:transform .28s ease, opacity .28s ease, filter .28s ease;}
.cbt-card .cc-name{font-family:var(--f-body); font-size:.88rem; line-height:1.18; pointer-events:none;}
.cbt-card.dim{opacity:.55; transform:scale(.9); filter:brightness(.5) drop-shadow(0 8px 14px rgba(0,0,0,.55));}
.cbt-card.dim2{opacity:.16; transform:scale(.78); filter:brightness(.32) drop-shadow(0 8px 14px rgba(0,0,0,.5));}
.cbt-card.is-center{transform:scale(1.04); filter:drop-shadow(0 12px 22px rgba(0,0,0,.7)) drop-shadow(0 0 14px rgba(226,183,94,.22));}
.cbt-card.is-center:hover{transform:scale(1.04) translateY(-10px);}
.cbt-card.is-pending{filter:drop-shadow(0 0 8px rgba(226,183,94,.6)) drop-shadow(0 12px 22px rgba(0,0,0,.7));}
.cbt-card.no-turn{cursor:default;}
.cbt-card.playing{animation:cbt-toVoid .5s cubic-bezier(.5,0,.75,0) forwards; z-index:50;}
@keyframes cbt-toVoid{to{transform:translateY(-200px) scale(.5) rotate(-7deg); opacity:0; filter:blur(5px) brightness(1.5);}}
.cbt-hand-empty{bottom:70px; left:50%; transform:translateX(-50%); font-family:var(--f-data); font-size:.84rem; color:var(--muted);}

/* Круглая вдавленная чёрно-серая кнопка «Бросок» — под иконкой соперника. */
.cbt-roll{bottom:58px; right:92px; width:108px; height:108px; border-radius:50%; border:none; cursor:pointer;
  background:radial-gradient(circle at 50% 40%, #3d3d40 0%, #202022 62%, #141416 100%); color:var(--gold);
  font-family:var(--f-display); font-size:1.05rem; letter-spacing:.02em; text-align:center;
  box-shadow:0 0 0 3px #4c4c50, 0 0 0 4px #08080a, 0 7px 16px rgba(0,0,0,.6), inset 0 6px 12px rgba(0,0,0,.8), inset 0 -5px 9px rgba(255,255,255,.07);}
.cbt-roll:hover{color:#ffe6a8;}
.cbt-roll:active{box-shadow:0 0 0 3px #4c4c50, 0 0 0 4px #08080a, inset 0 8px 16px rgba(0,0,0,.9);}
.cbt-roll:disabled{opacity:.5; cursor:default;}
.cbt-roll span{text-shadow:0 1px 2px rgba(0,0,0,.7);}

/* Доп. управление (зелья / ввод N) — слева-снизу, рядом с иконкой игрока. */
.cbt-extra{bottom:70px; left:280px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; max-width:360px;}
.cbt-input{display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
.cbt-input label{font-family:var(--f-data); font-size:.84rem; color:var(--ink-soft);}
.cbt-input input{width:82px; text-align:center; font-family:var(--f-data); font-size:1rem;
  background:rgba(18,12,6,.5); color:var(--ink); border:1px solid var(--edge-glass); border-radius:var(--r-sm); padding:7px 8px;}

/* ── Панель исхода (как было) ── */
/* 0.68.2. Было: радиальный градиент (в центре, ПОД карточкой, всего .6 —
   арена била сквозь) + карточка из стекла --panel-glass-2 (.42) — окно
   выглядело «недогруженным». Стало: та же вуаль, что у всех попапов игры
   (--veil), и СПЛОШНАЯ карточка --panel, как у .modal. z-index поднят с 9
   до 90: экран боя лежит на 80, окно исхода обязано быть выше него.
   Золотой отблеск --gold-sheen оставлен — он поверх непрозрачного фона. */
.cbt-outcome{position:fixed; inset:0; z-index:90; display:flex; align-items:center; justify-content:center; padding:22px;
  background:var(--veil); backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px);}
.cbt-outcome-card{width:min(100%, 420px); text-align:center;
  background:var(--gold-sheen), var(--panel); border:1px solid var(--edge-glass); border-radius:var(--r);
  box-shadow:var(--shadow); padding:26px 24px;}
.cbt-verdict{font-family:var(--f-display); font-size:2.1rem; letter-spacing:.03em; margin:0 0 4px;}
.cbt-verdict--win{color:var(--gold);} .cbt-verdict--loss{color:var(--ember);} .cbt-verdict--draw{color:var(--ink-soft);}
.cbt-verdict-sub{font-family:var(--f-data); font-size:.86rem; color:var(--muted); margin:0 0 16px;}
.cbt-rewards{text-align:left; display:flex; flex-direction:column; gap:7px; margin:0 0 20px;}
.cbt-rew-row{font-family:var(--f-data); font-size:.88rem; color:var(--ink-soft);
  background:var(--panel-glass-2); border:1px solid var(--edge-glass); border-radius:var(--r-sm); padding:8px 12px;}
.cbt-rew-row b{color:var(--gold);} .cbt-rew-row .lvlup{color:var(--ok);}

/* Журнал боя на карточке исхода: тумблер + свёрнутая по умолчанию лента.
   Строки — те же .cbt-round, что и в верхней ленте. */
.cbt-outcome-journal{margin:0 0 18px;}
.cbt-journal-tab{display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%;
  font-family:var(--f-data); font-size:.8rem; color:var(--ink-soft); cursor:pointer; user-select:none;
  background:var(--panel-glass-2); border:1px solid var(--edge-glass); border-radius:var(--r-sm); padding:9px 12px;}
.cbt-journal-tab:hover{background:rgba(226,183,94,.14); color:var(--ink);}
.cbt-journal-chev{color:var(--gold); transition:transform .18s ease;}
.cbt-journal-tab.is-open .cbt-journal-chev{transform:rotate(180deg);}
.cbt-outcome-log{display:none; flex-direction:column; gap:8px; text-align:left;
  max-height:34vh; overflow:auto; margin-top:10px; padding:2px 4px 2px 0;}
.cbt-outcome-log.open{display:flex;}

@media (max-width:620px){
  .cbt-hpwrap,.cbt-ring{width:150px; height:150px;}
  .cbt-carousel{width:250px;}
  .cbt-extra{left:16px; bottom:150px;}
}

/* ═══ Эффекты боя «Ярость» — 0.69.0 (combat-fx.js) ═══════════
   Слой поверх арены: тряска/вспышка/цифра урона живут здесь, а НЕ на
   портретах — портреты пересобираются каждый кадр (fillHero → innerHTML),
   анимация на них сорвалась бы. Узлы эффектов создаются на месте портрета
   жертвы и сами удаляются. Визуал утверждён на мокапе combat-fx-B. */
.cbt-fx-layer{position:absolute; inset:0; z-index:7; pointer-events:none;}
.cbt-fx{position:absolute; border-radius:50%; pointer-events:none;}

/* Обычный удар / крит: резкая тряска + алая царапина. Крит — сильнее. */
.cbt-fx--hit{animation:cfxShake .34s;}
.cbt-fx--hit::after{content:''; position:absolute; inset:0; border-radius:50%; animation:cfxSlash .4s ease-out;}
.cbt-fx--crit{animation:cfxShakeCrit .42s;}
.cbt-fx--crit::after{content:''; position:absolute; inset:0; border-radius:50%; animation:cfxSlashCrit .5s ease-out;}
/* Блок бронёй: голубая искра, БЕЗ тряски (удар не прошёл). */
.cbt-fx--block::after{content:''; position:absolute; inset:0; border-radius:50%; animation:cfxSlashBlock .45s ease-out;}
/* Яд: зелёное свечение расползается, лёгкая дрожь. */
.cbt-fx--poison{animation:cfxShiver .5s;}
.cbt-fx--poison::after{content:''; position:absolute; inset:0; border-radius:50%; animation:cfxVenom .7s ease-out;}

@keyframes cfxShake{0%,100%{transform:translate(0,0)}15%{transform:translate(-7px,3px)}45%{transform:translate(6px,-4px)}70%{transform:translate(-4px,2px)}}
@keyframes cfxShakeCrit{0%,100%{transform:translate(0,0) scale(1)}15%{transform:translate(-11px,5px) scale(1.03)}45%{transform:translate(9px,-6px) scale(1.02)}70%{transform:translate(-6px,3px)}}
@keyframes cfxSlash{0%{opacity:0}30%{opacity:1;background:radial-gradient(circle at 60% 40%, rgba(255,40,30,.55), transparent 60%)}100%{opacity:0}}
@keyframes cfxSlashCrit{0%{opacity:0}25%{opacity:1;background:radial-gradient(circle, rgba(255,210,120,.75), rgba(255,60,30,.5) 55%, transparent 72%)}100%{opacity:0}}
@keyframes cfxSlashBlock{0%{opacity:0}30%{opacity:1;background:radial-gradient(circle, rgba(150,200,240,.6), transparent 62%)}100%{opacity:0}}
@keyframes cfxShiver{0%,100%{transform:translate(0,0)}20%{transform:translate(-2px,1px)}50%{transform:translate(2px,-1px)}80%{transform:translate(-1px,1px)}}
@keyframes cfxVenom{0%{opacity:0}25%{opacity:1;background:radial-gradient(circle, rgba(120,190,60,.5), rgba(90,150,40,.25) 55%, transparent 74%)}100%{opacity:0}}

/* Крит: лучи из-за портрета жертвы (центр ставит JS). */
.cbt-rays{position:absolute; width:340px; height:340px; transform:translate(-50%,-50%); pointer-events:none; opacity:0;
  background:conic-gradient(from 0deg, rgba(255,210,120,.5) 0 6deg, transparent 6deg 30deg, rgba(255,210,120,.4) 30deg 36deg, transparent 36deg 60deg);}
.cbt-rays.go{animation:cfxRays .5s ease-out;}
@keyframes cfxRays{0%{opacity:0;transform:translate(-50%,-50%) scale(.4) rotate(0)}40%{opacity:.9}100%{opacity:0;transform:translate(-50%,-50%) scale(1.1) rotate(40deg)}}

/* Летящая цифра урона. */
.cbt-dmg{position:absolute; transform:translateX(-50%); font-family:var(--f-display); font-weight:700; font-size:2.1rem;
  color:#ff5a48; text-shadow:0 2px 6px rgba(0,0,0,.8); pointer-events:none;
  animation:cfxDmg 1.05s cubic-bezier(.2,.8,.3,1) forwards;}
.cbt-dmg--crit{font-size:3rem; color:#ffd24a; text-shadow:0 0 18px rgba(255,120,40,.8),0 2px 6px #000;}
.cbt-dmg--venom{font-size:1.7rem; color:#8fbf4a; text-shadow:0 0 10px rgba(120,190,60,.7),0 2px 5px #000;}
.cbt-dmg--block{font-size:1.5rem; color:#9fc8e6; text-shadow:0 2px 5px #000;}
/* Лечение — сочный зелёный (отличается от болотного яда): всплывающая «+N»,
   мягкое свечение над портретом, зелёная метка в логе. */
.cbt-dmg--heal{font-size:1.9rem; color:#86e07a; text-shadow:0 0 12px rgba(120,230,110,.75),0 2px 5px #000;}
.cbt-fx--heal::after{content:''; position:absolute; inset:0; border-radius:50%; animation:cfxHeal .7s ease-out;}
@keyframes cfxHeal{0%{opacity:0}25%{opacity:1;background:radial-gradient(circle, rgba(130,230,120,.55), rgba(90,190,90,.28) 55%, transparent 74%)}100%{opacity:0}}
.cbt-round .r-heal{color:#86e07a; font-weight:700;}
@keyframes cfxDmg{0%{opacity:0;transform:translateX(-50%) translateY(10px) scale(.6) rotate(-6deg)}18%{opacity:1;transform:translateX(-50%) translateY(-6px) scale(1.25) rotate(3deg)}40%{transform:translateX(-50%) translateY(-16px) scale(1) rotate(-2deg)}100%{opacity:0;transform:translateX(-50%) translateY(-46px) scale(.95)}}

@media (prefers-reduced-motion: reduce){
  .cbt-fx, .cbt-fx::after, .cbt-rays, .cbt-dmg{animation-duration:.01s;}
  .die2d.is-landed{animation:none;}
}

/* ══ ШЕРЕНГИ КАРУСЕЛИ (2.3, Блок «Карусель-2.3») ══════════════════════
   Колонки строя у портретов: своя растёт ВВЕРХ от нижнего портрета, чужая —
   ВНИЗ от верхнего. Карточка у портрета = кто на сцене (дублирует его: это
   шкала очереди). Правило тишины: сторона из одного бойца шеренги не имеет
   (hidden в JS) — соло-бой и любой зверь выглядят ровно как до 0.92.0.
   Всё абсолютом внутри сцены — страница не растёт, скроллов не порождает. */
.cbt-bench{z-index:5; display:flex; flex-direction:column; gap:13px; width:172px;}
.cbt-bench--opp{top:52px; right:262px;}
.cbt-bench--me{bottom:52px; left:262px; flex-direction:column-reverse;}
.cbt-bench-head{font-family:var(--f-data); font-size:.62rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--muted); padding-left:2px;}
/* Свой строй перевёрнут (растёт вверх) — заголовку наибольший order, чтобы
   визуально остаться НАД колонкой, как в утверждённом мокапе. */
.cbt-bench--me .cbt-bench-head{order:99;}

.cbt-bench-card{width:172px; height:54px; flex:none; position:relative;
  display:flex; align-items:center; gap:9px; padding:7px 10px 7px 8px;
  border:1px solid rgba(90,72,52,.75); border-radius:10px;
  background:linear-gradient(168deg, rgba(46,36,24,.92), rgba(26,19,12,.94));
  box-shadow:0 3px 10px rgba(0,0,0,.5), inset 0 1px 0 rgba(236,224,204,.05);}
.bcd-face{position:relative; width:38px; height:38px; flex:none; border-radius:50%; overflow:hidden;
  border:1.5px solid rgba(20,14,8,.9);
  background:radial-gradient(circle at 50% 36%, #3a2c1a, #140e07 76%);
  display:grid; place-items:center;}
.bcd-face img{width:100%; height:100%; object-fit:cover;}
.bcd-glyph{font-family:var(--f-display); font-size:1rem; color:rgba(226,183,94,.6);}
.bcd-body{flex:1; min-width:0; display:flex; flex-direction:column; gap:4px;}
.bcd-top{display:flex; align-items:center; gap:8px;}
.bcd-name{flex:1; min-width:0; font-family:var(--f-data); font-size:.8rem; font-weight:600; color:var(--ink-soft);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.bcd-die{flex:none; min-width:17px; height:17px; border-radius:4px; padding:0 3px;
  background:linear-gradient(158deg,#f6d885 4%,#dcac52 52%,#bd8a2c 96%); border:1px solid var(--rim);
  color:#2a1e0c; font-family:var(--f-data); font-weight:700; font-size:.64rem; text-align:center; line-height:16px;
  box-shadow:inset 0 1px 0 rgba(255,246,220,.5), 0 1px 3px rgba(0,0,0,.5);}
.bcd-tag{flex:none; font-family:var(--f-data); font-size:.62rem; letter-spacing:.05em; color:var(--muted);}
.bcd-hp{height:5px; border-radius:3px; background:rgba(10,7,4,.85); overflow:hidden;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.7);}
.bcd-hp i{display:block; height:100%; border-radius:3px; background:linear-gradient(90deg,#7d2f24,#a8442f 55%,#c05a3e);
  transition:width .4s ease;}
.bcd-hp.is-high i{background:linear-gradient(90deg,#4a6b31,#628a3c 60%,#79a24a);}

/* Состояния */
.cbt-bench-card.is-stage{border-color:var(--gold);
  box-shadow:0 0 14px rgba(226,183,94,.28), 0 3px 10px rgba(0,0,0,.5);}
.cbt-bench-card.is-stage .bcd-face{border-color:var(--gold);}
.cbt-bench-card.is-stage .bcd-name{color:var(--gold);}
.cbt-bench-card.is-exhausted{opacity:.62;}
.cbt-bench-card.is-exhausted .bcd-die{background:#3a3226; color:#7a6f5c; border-color:#4a4234; box-shadow:none;}
.cbt-bench-card.is-fallen{opacity:.5; filter:saturate(.35);}
.cbt-bench-card.is-fallen .bcd-face::after{content:'\2715'; position:absolute; left:0; top:0; width:100%; height:100%;
  display:grid; place-items:center; color:rgba(192,90,62,.9); font-size:1.2rem;
  font-family:var(--f-data); background:rgba(10,6,3,.55);}
.cbt-bench-card.is-fallen .bcd-name{text-decoration:line-through; text-decoration-color:rgba(192,90,62,.6);}

/* Плашки над карточкой: свои углы, между карточками зазор 13px — не слипаются */
.bcd-me{position:absolute; top:-8px; left:10px; z-index:1;
  font-family:var(--f-data); font-size:.56rem; letter-spacing:.14em; color:#2a1e0c;
  background:linear-gradient(180deg,#e9c67a,#c2922f); border-radius:3px; padding:1px 6px;
  box-shadow:0 1px 3px rgba(0,0,0,.6);}
.bcd-next{position:absolute; top:-8px; right:10px; z-index:1;
  font-family:var(--f-data); font-size:.54rem; letter-spacing:.12em; text-transform:uppercase; color:var(--gold);
  background:rgba(20,14,8,.95); border:1px solid rgba(226,183,94,.5); border-radius:3px; padding:1px 6px;}

/* Статус ждущего: две строки с воздухом, без слипания с заголовком */
.cbt-status{display:flex; flex-direction:column; align-items:center; gap:3px;}
.cbt-status-hint{font-size:.74rem; color:var(--muted); letter-spacing:.04em;}
.cbt-status .bench-stage-name{color:var(--gold); font-weight:600;}

/* Пригашенная рука ждущего + плашка-ответ «почему» */
.cbt-hand-wrap.is-benched{opacity:.45; filter:saturate(.6); pointer-events:auto;}
.cbt-hand-wrap.is-benched .cbt-card{cursor:default;}
.cbt-bench-note{position:absolute; bottom:238px; left:50%; transform:translateX(-50%); z-index:7;
  font-family:var(--f-data); font-size:.78rem; color:var(--muted); letter-spacing:.05em; white-space:nowrap;
  background:rgba(20,14,8,.88); border:1px solid var(--edge-glass); border-radius:6px; padding:5px 14px;}

/* Узкие экраны: колонки уезжают ПОД/НАД портреты вдоль краёв — центр (кость,
   статус) свободен, наездов нет. Ещё уже — карточки худеют. Высоты строя
   (голова + 3 карточки) всегда меньше половины экрана — скролла не бывает. */
@media (max-width: 1150px){
  .cbt-bench--opp{top:332px; right:36px;}
  .cbt-bench--me{bottom:332px; left:36px;}
}
@media (max-width: 860px){
  .cbt-bench, .cbt-bench-card{width:150px;}
  .bcd-name{font-size:.74rem;}
}
@media (max-height: 700px){
  .cbt-bench{gap:9px;}
  .cbt-bench--opp{top:300px;}
  .cbt-bench--me{bottom:300px;}
}
.cbt-play-slot.is-hidden{display:none;}

/* ══════════════════════════════════════════════════════════════
   ПОЯС РАСХОДНИКОВ И ЭФФЕКТЫ БОЙЦА (1.0.0-rc12)
   Макет: mockups/combat-consumable-belt-v2.html (утверждён автором).
   ══════════════════════════════════════════════════════════════ */

/* СЛОЙ. .cbt-bottom (рука карт и «Бросок») лежит полосой на 230px по всему
   низу экрана с z-index:6, а герой стоял на 5 — пояс, оказавшись под
   портретом, попадал ВНУТРЬ этой полосы, и клики до него не доходили: их
   съедал верхний слой. Поднимаем свой столбец над полосой. Рука карт от
   этого клики не теряет: столбец узкий (210px) и стоит слева, а карты
   собраны по центру. */
.cbt-hero--me{ z-index:8; bottom:104px; }

/* ── Пояс ──────────────────────────────────────────────────── */
.cbt-belt-host{ position:relative; display:flex; flex-direction:column; align-items:center; margin-top:6px; }
.cbt-belt{ display:flex; gap:8px; align-items:flex-end; }
.cbt-belt-cap{ font-family:var(--f-data); font-size:.72rem; color:var(--muted);
  letter-spacing:.05em; text-align:center; margin-top:6px; min-height:15px; }

.cbt-vial{ position:relative; width:54px; height:72px; padding:0; border:none; background:none; cursor:pointer;
  filter:drop-shadow(0 6px 10px rgba(0,0,0,.6)); transition:transform .12s ease, filter .12s ease; }
.cbt-vial:hover{ transform:translateY(-5px);
  filter:drop-shadow(0 0 9px rgba(226,183,94,.55)) drop-shadow(0 8px 12px rgba(0,0,0,.7)); }

/* Флакон рисуем средствами стиля: арта под предметы в игре нет. */
.cbt-vial-glass{ position:absolute; inset:0;
  background:
    radial-gradient(circle at 38% 62%, rgba(192,80,63,.92) 0 34%, rgba(192,80,63,.55) 34% 46%, transparent 47%),
    linear-gradient(180deg, transparent 0 12%, rgba(18,13,7,.85) 12% 100%);
  border:1px solid rgba(226,183,94,.5); border-radius:6px 6px 22px 22px; }
.cbt-vial-glass::after{ content:''; position:absolute; left:50%; top:-6px; width:16px; height:8px;
  transform:translateX(-50%); background:#3a2c18; border:1px solid rgba(226,183,94,.5); border-radius:2px; }
.cbt-vial-qty{ position:absolute; right:-3px; bottom:5px; font-family:var(--f-data); font-size:.7rem;
  color:var(--ink); background:rgba(16,12,7,.92); border:1px solid rgba(226,183,94,.4);
  border-radius:999px; padding:0 5px; }
.cbt-vial-tip{ position:absolute; bottom:78px; left:50%; transform:translateX(-50%); white-space:nowrap;
  font-family:var(--f-data); font-size:.74rem; color:var(--ink-soft); background:rgba(12,9,5,.96);
  border:1px solid rgba(226,183,94,.3); border-radius:4px; padding:3px 8px;
  opacity:0; pointer-events:none; transition:opacity .12s; z-index:30; }
.cbt-vial:hover .cbt-vial-tip{ opacity:1; }

/* Погашенные состояния: израсходован ход / пить сейчас нельзя. */
.cbt-belt.is-spent .cbt-vial, .cbt-belt.is-spent .cbt-pouch{ filter:grayscale(1) brightness(.45); cursor:default; transform:none; }
.cbt-belt.is-blocked .cbt-vial, .cbt-belt.is-blocked .cbt-pouch{ filter:grayscale(.8) brightness(.4); cursor:not-allowed; transform:none; }
.cbt-belt.is-spent .cbt-vial:hover .cbt-vial-tip,
.cbt-belt.is-blocked .cbt-vial:hover .cbt-vial-tip{ opacity:0; }

/* ── Сумка ─────────────────────────────────────────────────── */
.cbt-pouch{ width:54px; height:72px; cursor:pointer; font-family:var(--f-data); font-size:.7rem; line-height:1.1;
  color:var(--ink-soft); background:rgba(20,14,7,.5); border:1px dashed rgba(226,183,94,.42); border-radius:8px;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; transition:background .12s; }
.cbt-pouch:hover{ background:rgba(226,183,94,.14); color:var(--gold); }
.cbt-pouch-glyph{ font-size:1.3rem; color:var(--gold); }

/* Открывается НАД столбцом героя: над поясом список накрывал портрет,
   кольцо HP и эффекты — то есть всё, по чему игрок и выбирает.
   СВОЙ СЛОЙ НА BODY, а не внутри пояса: блок героя перерисовывается целиком
   раз в POLL_MS и уносил список с собой через доли секунды (находка аудита
   rc12). Поэтому position:fixed, а left/bottom проставляет combat.js по
   координатам кнопки. Ширину держать равной POUCH_W в combat.js. */
/* z-index 85: ВЫШЕ боевой вуали (80), иначе список на body оказался бы за
   ней и не был бы виден вовсе; НИЖЕ панели исхода (90) — когда бой кончился,
   выбирать уже нечего. */
.cbt-pouch-pop{ position:fixed; z-index:85;
  width:420px; max-height:330px; overflow:auto; padding:10px 12px;
  background:rgba(12,9,5,.97); border:1px solid rgba(226,183,94,.34); border-radius:8px;
  box-shadow:0 18px 40px rgba(0,0,0,.75); }
.cbt-pouch-head{ margin:6px 0; font-family:var(--f-display); font-weight:500; font-size:.82rem;
  color:var(--gold); letter-spacing:.06em; text-transform:uppercase; }
.cbt-pouch-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:5px; }
.cbt-pouch-item{ display:flex; align-items:center; gap:8px; padding:5px 7px; border-radius:5px; cursor:pointer;
  font-family:var(--f-data); font-size:.76rem; color:var(--ink); text-align:left;
  background:rgba(226,183,94,.05); border:1px solid rgba(226,183,94,.14); }
.cbt-pouch-item:hover{ background:rgba(226,183,94,.18); border-color:rgba(226,183,94,.45); }
.cbt-pouch-name{ flex:1; line-height:1.15; }
.cbt-pouch-qty{ color:var(--muted); }

/* ── Три такта применения ──────────────────────────────────── */
@keyframes cbt-vial-drink{
  0%{ transform:rotate(0) translateY(0); }
  35%{ transform:rotate(-58deg) translateY(-8px); }
  75%{ transform:rotate(-58deg) translateY(-8px); }
  100%{ transform:rotate(0) translateY(0); } }
.cbt-vial.is-drinking{ animation:cbt-vial-drink .55s ease-in-out; }

.cbt-spark{ position:absolute; width:14px; height:14px; border-radius:50%; z-index:10050; pointer-events:none;
  background:radial-gradient(circle, #ffe8b0, rgba(226,183,94,0) 70%); box-shadow:0 0 18px 6px rgba(226,183,94,.55); }

.cbt-portrait.is-drunk{ animation:cbt-drunk-flash .7s ease-out; }
@keyframes cbt-drunk-flash{
  0%{ box-shadow:0 0 0 rgba(226,183,94,0); }
  25%{ box-shadow:0 0 30px 8px rgba(226,183,94,.6); }
  100%{ box-shadow:0 0 0 rgba(226,183,94,0); } }

.cbt-drinkpop{ position:absolute; z-index:10051; pointer-events:none; font-family:var(--f-display);
  font-size:1.8rem; text-shadow:0 2px 8px rgba(0,0,0,.8); animation:cbt-drinkpop-up 1.1s ease-out forwards; }
.cbt-drinkpop.is-heal{ color:#9fd07a; }
.cbt-drinkpop.is-buff{ color:var(--gold); font-size:1.1rem; }
@keyframes cbt-drinkpop-up{
  0%{ opacity:0; transform:translateY(6px) scale(.8); }
  18%{ opacity:1; transform:translateY(-4px) scale(1.08); }
  100%{ opacity:0; transform:translateY(-52px) scale(1); } }

/* ── Эффекты бойца квадратными иконками ────────────────────── */
.cbt-buffs{ display:flex; gap:5px; flex-wrap:wrap; justify-content:center; max-width:220px; }
/* Сама ячейка (.fx-cell) описана в game.css и общая с левой панелью игрока
   (1.0.0-rc16): значок эффекта в игре один, двух копий больше нет.
   Прежние .cbt-buff / .cbt-buff-bar / .cbt-buff-tip удалены — их разметку
   никто не выдаёт с тех пор, как combat.js перешёл на combatEffectsHtml(). */
