/* ============================================================
   БАЗА (мобильный макет): ресет, оболочка #shell/#scr, глобальный сканлайн,
   экраны-страницы, шапка лобби, нижняя навигация, сам покерный стол,
   празднование выигрыша, своё место, док ставок и тосты.

   Перенесено из прототипа (arena-web/styles/base.css) с сохранением порядка
   правил: каскад зависит от последовательности файлов, см. index.html.

   Что удалено при переносе относительно прототипа:
   · палитра и размеры карт — теперь из /shared/styles/tokens.css (один файл
     на все приложения);
   · мёртвые блоки старого лобби (.hero/.play/.modes/.pills/.rankc/.lang/.dots)
     и фейковый хром телефона (.island/.sbar) — разметки под них больше нет;
   · «сундук сезона» с выдуманным лутом (.chest/.loot) — сервер такого не
     отдаёт, значит на экране этого нет.
   ============================================================ */
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;height:100%}
body{min-height:100dvh;margin:0;
  font-family:'Manrope',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;color:var(--text);
  background:#050410;
  background-image:radial-gradient(900px 600px at 20% -5%,rgba(108,75,255,.25),transparent 60%),
                   radial-gradient(800px 600px at 95% 10%,rgba(45,226,197,.13),transparent 55%),
                   radial-gradient(900px 700px at 50% 110%,rgba(177,75,255,.18),transparent 60%);}
button{font-family:inherit;cursor:pointer}
.num{font-family:'Rajdhani','Manrope',sans-serif;font-weight:700;letter-spacing:.3px}
.muted{color:var(--muted)}.dim{color:var(--dim)}

/* ===== adaptive shell ===== */
/* Narrow (phone): #scr fills the viewport = the original mobile UX.
   Wide (desktop): the sidebar (repositioned #nav) sits left, #scr is the
   centered app stage, and #rail (chat/stats) sits right. The stage keeps the
   exact same markup + ids, so app.js and every animation are untouched. */
#shell{min-height:100dvh;display:flex}
#scr{flex:1;min-width:0;position:relative;overflow:hidden;background:#0A0718;
  background-image:radial-gradient(600px 380px at 50% -8%,rgba(124,92,255,.22),transparent 60%),
                   radial-gradient(500px 400px at 100% 100%,rgba(45,226,197,.08),transparent 55%);
  /* Верх страниц (--pgtop) складывается из двух слагаемых и только из них:
     · --safetop — системная строка телефона (часы, батарея). В браузере это
       ноль, поэтому 4px — чтобы аватар не лип к самой кромке экрана;
     · --netbar-h — полоса состояния соединения. Она лежит НАД страницами и,
       пока связь есть, места не занимает (0px). Её высоту в переменную пишет
       setConnBar (src/shell.js): текст бывает в две строки на узком экране,
       и «на глаз» такую константу не угадать.
     До этого здесь стояло сплошное 54px — бронь под фейковый хром телефона из
     прототипа (.island/.sbar). Разметку хрома удалили ещё при переносе, а
     бронь осталась, и каждый экран начинался с полосы пустоты в 54px. */
  --safetop:env(safe-area-inset-top,0px);
  --netbar-h:0px;
  --pgtop:calc(max(var(--safetop),4px) + var(--netbar-h));}
/* warm sheen over the centre stage (the ribbed scanline is global — body::after) */
#scr::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:46;
  background:linear-gradient(120deg,rgba(255,194,75,.05),transparent 30%)}
/* GLOBAL ribbed scanline — every screen and every zone (nav, rails, centre, …).
   Fixed to the viewport so fixed sidebars get it too; pointer-events:none. */
body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:9990;
  background:repeating-linear-gradient(0deg,rgba(180,200,255,.022) 0 1px,transparent 1px 3px)}
/* right rail hidden until there's room for it (≥1280) */
#rail{display:none}

/* ===== экраны-страницы =====
   `.screen` — тот же лейаут для контейнера эко-слоя (#s-clubs): вкладка
   «Клубы» рисуется другой половиной приложения и не должна знать, как
   позиционируются покерные страницы (см. README, контракт монтирования). */
.page,.screen{position:absolute;inset:var(--pgtop) 0 0 0;overflow-y:auto;overflow-x:hidden;display:none;padding-bottom:104px;scrollbar-width:none}
.page::-webkit-scrollbar,.screen::-webkit-scrollbar{display:none}
.page.on{display:block;animation:fade .35s ease}
/* Эко-слой держит внутреннюю прокрутку сам (.eco-view), поэтому у контейнера
   её нет — иначе прокруток было бы две — и он тянется во всю высоту сцены,
   оставляя место нижней навигации. */
#s-clubs{overflow:hidden;padding-bottom:0;bottom:88px}
#s-clubs.on{display:flex;animation:fade .35s ease}
@keyframes fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ===== состояние соединения =====
   Полоса поверх экрана, пока сокета нет. Появляется только в этом случае —
   «наверное, подключено» не показывается никогда. */
.netbar{position:absolute;top:var(--safetop);left:0;right:0;z-index:120;display:none;
  padding:7px 14px;text-align:center;font-size:12px;font-weight:700;cursor:pointer;
  color:#2a1900;background:linear-gradient(90deg,var(--gold2),var(--gold))}
.netbar.on{display:block}
/* Вытеснение другим окном — не обрыв: связь есть, занято место. Другой цвет,
   чтобы состояния не путались, и подсказка, что полоса кликабельна. */
.netbar.taken{color:#fff;background:linear-gradient(90deg,#6C4BFF,#B14BFF)}

/* ===== шапка лобби ===== */
.lvl{position:relative;width:46px;height:46px;flex:none;cursor:pointer}
.lvl .ring{position:absolute;inset:0;border-radius:50%;background:conic-gradient(var(--teal) 78%,rgba(255,255,255,.1) 0)}
.lvl .ph{position:absolute;inset:3px;border-radius:50%;background:linear-gradient(135deg,#7C5CFF,#B14BFF);display:flex;align-items:center;justify-content:center;font-weight:900;font-size:17px;color:#fff;overflow:hidden}
.lvl .tag{position:absolute;bottom:-4px;left:50%;transform:translateX(-50%);background:var(--gold);color:#2a1900;font-size:9px;font-weight:900;padding:1px 5px;border-radius:6px;font-family:'Rajdhani'}
.logo{font-family:'Orbitron','Rajdhani',sans-serif;font-weight:900;font-size:15px;line-height:1;letter-spacing:1px}
.logo .a{color:#fff}.logo .b{background:linear-gradient(90deg,#9A8BFF,#2DE2C5);-webkit-background-clip:text;background-clip:text;color:transparent}
.curr{margin-left:auto;display:flex;gap:7px;align-items:center}
.cpill{display:flex;align-items:center;gap:5px;background:var(--glass);border:1px solid var(--bord);border-radius:999px;padding:5px 7px 5px 9px;font-family:'Rajdhani';font-weight:700;font-size:14px}
.cpill i{font-size:15px}.cpill .gold{color:var(--gold)}.cpill .gem{color:var(--teal)}
.cpill .add{width:18px;height:18px;border-radius:50%;background:linear-gradient(135deg,#7C5CFF,#B14BFF);display:flex;align-items:center;justify-content:center;font-size:12px;color:#fff;cursor:pointer}

/* ===== секция ===== */
.sec{display:flex;align-items:center;justify-content:space-between;margin:18px 18px 11px}
.sec h3{margin:0;font-size:16px;font-weight:700}
.sec a{color:var(--muted);font-size:12px;text-decoration:none;cursor:pointer}
.prog{height:8px;border-radius:999px;background:rgba(0,0,0,.3);overflow:hidden;margin:8px 0 5px}
.prog>i{display:block;height:100%;border-radius:999px;background:linear-gradient(90deg,#FFC24B,#FF9D2B);transition:width .8s ease}
.hint{color:var(--dim);font-size:11px;text-align:center;padding:14px 26px 6px;line-height:1.5}

/* ===== bottom nav ===== */
/* Подложка непрозрачна ровно до верхней кромки, а не до середины панели.
   Раньше градиент становился плотным только к 60% высоты (53px от низа), тогда
   как иконки и подписи стоят выше — 38..77px от низа. Прокручиваемый список
   просвечивал СКВОЗЬ ряд иконок: строка «Gold Highroller» читалась наполовину
   поверх «Клубы»/«Магазин». Теперь под иконками — сплошной фон, и остаётся
   только тонкая матовая кромка в 10px, ради которой градиент и был. */
.nav{position:absolute;left:0;right:0;bottom:0;height:88px;display:flex;align-items:flex-start;justify-content:space-around;padding:11px 18px 0;z-index:50;
  background:linear-gradient(0deg,#0A0718 0 88%,rgba(10,7,24,.88) 100%);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border-top:1px solid rgba(255,255,255,.06)}
.nav button{background:0;border:0;color:var(--dim);font-size:10px;display:flex;flex-direction:column;align-items:center;gap:4px;width:54px}
.nav button i{font-size:23px}.nav button.on{color:var(--p1)}.nav button.on i{filter:drop-shadow(0 0 8px rgba(139,123,255,.8))}
.fab{width:60px;height:60px;border-radius:22px;margin-top:-20px;border:0;background:linear-gradient(135deg,#7C5CFF,#B14BFF);display:flex;align-items:center;justify-content:center;color:#fff;box-shadow:0 10px 26px rgba(124,92,255,.6);animation:pulse 2.6s infinite}
.fab i{font-size:28px}
.nav .lp{position:absolute;top:-22px;left:50%;transform:translateX(-50%);font-size:10px;color:var(--muted);white-space:nowrap;font-family:'Rajdhani';font-weight:700}

/* ===== POKER TABLE ===== */
#g{position:absolute;inset:0;display:none;background:radial-gradient(120% 90% at 50% 35%,#1a1340,#0A0718 70%)}
#g.on{display:block}
/* Шапка стола считает верх от того же --pgtop, что и страницы: у стола своя
   разметка (#g — не `.page`), но бронь под удалённый хром прототипа была той
   же. Шапка поднялась в освободившееся место целиком (было 62px).
   Сукно за ней НЕ идёт — см. .table ниже. */
.ghud{position:absolute;top:calc(var(--pgtop) + 4px);left:0;right:0;display:flex;align-items:center;justify-content:space-between;padding:0 18px;z-index:20}
.ghud .pill{display:flex;align-items:center;gap:5px;background:rgba(0,0,0,.4);border:1px solid var(--bord);border-radius:999px;padding:6px 11px;font-family:'Rajdhani';font-weight:700;font-size:13px;backdrop-filter:blur(8px)}
.gbtn-r{width:36px;height:36px;border-radius:50%;background:rgba(0,0,0,.4);border:1px solid var(--bord);display:flex;align-items:center;justify-content:center;color:var(--text)}
.gbtn-r.muted{opacity:.55}
/* Полоса над сукном — НЕ пустая, и поднимать сукно в неё нельзя. В неё свисает
   верхний ряд мест: карты лежат ВЫШЕ аватара, а плашка ставки и итог руки
   (`.bet`, `.res`) — ещё на 20px выше карт, то есть блок места торчит над своей
   точкой посадки примерно на 77px. Место `[50,2]` из SLOTS (шесть за столом,
   src/table/render.js) стоит в 2% от верха сукна — именно его карты и «фолд»
   уезжали под пилюли, когда сукно поднялось вместе с шапкой.
   Поэтому освободившиеся 50px забрала шапка (она встала к самой кромке), а
   сукно осталось там, где было: 118px до правки, 122px сейчас — четыре пикселя
   вниз, чтобы между плашкой верхнего места и шапкой остался зазор, а не стык. */
.table{position:absolute;top:calc(var(--pgtop) + 118px);left:14px;right:14px;bottom:182px;border-radius:50%/46%;
  background:radial-gradient(120% 120% at 50% 40%,#1f7a5c,#0c4733 75%);
  border:8px solid #2a1d4d;box-shadow:inset 0 0 60px rgba(0,0,0,.55),0 0 0 2px rgba(45,226,197,.25),0 0 50px rgba(45,226,197,.18)}
.table:before{content:"";position:absolute;inset:14px;border-radius:50%/46%;border:1.5px solid rgba(45,226,197,.22)}
.felt-logo{position:absolute;top:30%;left:50%;transform:translate(-50%,-50%);font-family:'Orbitron','Rajdhani';font-weight:900;font-size:13px;letter-spacing:2px;color:rgba(255,255,255,.1)}
.center{position:absolute;top:48%;left:50%;transform:translate(-50%,-50%);text-align:center;width:100%}
.pot{display:inline-flex;align-items:center;gap:6px;background:rgba(0,0,0,.4);border:1px solid rgba(255,194,75,.4);border-radius:999px;padding:4px 12px;font-family:'Rajdhani';font-weight:700;color:var(--gold);font-size:14px;margin-bottom:11px;transition:transform .2s}
.pot.pop{transform:scale(1.18)}
.board{display:flex;gap:6px;justify-content:center;min-height:60px}
.winline{margin-top:9px;font-size:12px;font-weight:700;color:var(--teal);min-height:16px;text-shadow:0 0 12px rgba(45,226,197,.6)}

/* cards */
.pc{width:var(--pc-w);height:var(--pc-h);border-radius:7px;position:relative;background:linear-gradient(160deg,#fff,#e9e6f7);box-shadow:0 4px 10px rgba(0,0,0,.4);flex:none}
.pc .c{position:absolute;top:4px;left:5px;font-family:'Rajdhani';font-weight:700;line-height:.85;text-align:center}
.pc .c .rk{font-size:var(--pc-rk)}.pc .c .su{font-size:var(--pc-su)}
.pc .big{position:absolute;bottom:3px;right:4px;font-size:var(--pc-big);line-height:1}
.pc.red{color:#E23B5C}.pc.blk{color:#1b1340}
/* Рубашка: здесь ТОЛЬКО геометрия. Красит её вложенный `.cbk` — гравюра,
   отделка, кайма и герб из каталога косметики (styles/cosmetics.css). Раньше
   заливка и пунктирная рамка стояли прямо здесь, из-за чего все рубашки
   отличались только оттенком, а `::after` карты был занят. */
.pc.back{border:1px solid rgba(255,255,255,.15);overflow:hidden}
.pc.deal{animation:deal .42s ease both}
@keyframes deal{from{opacity:0;transform:translateY(-40px) rotate(-12deg)}to{opacity:1;transform:none}}

/* seats (positioned in JS as % of .table) */
#seats{position:absolute;inset:0}
.seat{position:absolute;text-align:center;width:74px;z-index:10;transform:translate(-50%,-50%)}
.seat .av{width:46px;height:46px;border-radius:50%;margin:0 auto;display:flex;align-items:center;justify-content:center;font-weight:900;color:#fff;font-size:16px;border:2px solid rgba(255,255,255,.15);position:relative;background:linear-gradient(135deg,#7C5CFF,#B14BFF);overflow:hidden}
.seat .av img,.lvl .ph img{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;object-fit:cover}
.seat .av:has(img),.lvl .ph:has(img){color:transparent}
.seat.bot .av{background:linear-gradient(135deg,#2DE2C5,#1f7a5c)}
.seat.act .av{border-color:var(--teal);box-shadow:0 0 18px rgba(45,226,197,.7)}
.seat.fold{opacity:.4}
.seat.win .av{border-color:var(--gold);box-shadow:0 0 26px rgba(255,194,75,.9);animation:winpulse .5s ease 3}
@keyframes winpulse{0%,100%{transform:scale(1)}50%{transform:scale(1.12)}}
.seat .info{margin-top:5px;background:rgba(0,0,0,.55);border:1px solid var(--bord);border-radius:9px;padding:3px 6px;backdrop-filter:blur(6px)}
.seat .info .nm{font-size:10px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.seat .info .ch{font-family:'Rajdhani';font-weight:700;font-size:12px;color:var(--gold)}
.seat.empty .av{background:rgba(255,255,255,.05);border-style:dashed;color:var(--dim);font-size:11px}
.seat .timer{position:absolute;inset:-3px;border-radius:50%;background:conic-gradient(var(--teal) var(--deg,0deg),transparent 0);-webkit-mask:radial-gradient(transparent 19px,#000 20px);mask:radial-gradient(transparent 19px,#000 20px)}
.seat .dlr{position:absolute;bottom:34px;right:-2px;width:18px;height:18px;border-radius:50%;background:#fff;color:#3a1d6e;font-family:'Rajdhani';font-weight:700;font-size:11px;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px rgba(0,0,0,.5)}
.seat .res{position:absolute;top:-20px;left:50%;transform:translateX(-50%);font-size:11px;font-weight:800;padding:2px 8px;border-radius:999px;white-space:nowrap;z-index:12}
.seat .res.w{background:var(--teal);color:#04241c}
.seat .res.l{background:rgba(255,59,92,.85);color:#fff}
.seat .cards{display:flex;gap:2px;justify-content:center;margin-bottom:3px}
.seat .cards .pc{width:22px;height:31px}.seat .cards .pc .c .rk{font-size:9px}.seat .cards .pc .c .su{font-size:7px}.seat .cards .pc .big{font-size:12px}

/* bet chip near a seat */
.bet{position:absolute;left:50%;transform:translateX(-50%);top:-20px;font-family:'Rajdhani';font-weight:700;font-size:11px;color:var(--gold);background:rgba(0,0,0,.5);border-radius:999px;padding:2px 7px 2px 5px;display:inline-flex;align-items:center;gap:4px;white-space:nowrap;z-index:11}
.bet:before{content:"";width:10px;height:10px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#FFD98A,#FF9D2B);border:1.5px solid #b86a00;flex:none}

/* flying chips */
#fly{position:absolute;inset:0;pointer-events:none;z-index:40}
.chipfly{position:absolute;width:18px;height:18px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#FFD98A,#FF9D2B);border:2px solid #b86a00;box-shadow:0 2px 5px rgba(0,0,0,.5);transition:transform .5s cubic-bezier(.4,.7,.3,1),opacity .5s}
.chipfly.big{width:26px;height:26px;border-width:3px;transition:transform .9s cubic-bezier(.35,.75,.3,1),opacity .9s;box-shadow:0 3px 9px rgba(0,0,0,.55),0 0 14px rgba(255,194,75,.7)}

/* ===== WIN CELEBRATION ===== */
/* my cards glow + pulse when I take the pot */
.hero-cards.youwin{animation:youwin .55s ease 3}
@keyframes youwin{0%,100%{transform:scale(1)}50%{transform:scale(1.09)}}
.hero-cards.youwin .pc{box-shadow:0 0 26px rgba(255,194,75,.95),0 0 8px rgba(255,255,255,.8),0 4px 10px rgba(0,0,0,.4)}

/* centered win banner */
.winbanner{position:absolute;top:40%;left:50%;z-index:52;pointer-events:none;text-align:center;
  transform:translate(-50%,-50%) scale(.55);opacity:0;transition:transform .42s cubic-bezier(.2,1.5,.4,1),opacity .3s}
/* dark scrim so the text stays readable over the bright felt */
.winbanner:before{content:"";position:absolute;inset:-46px -80px;z-index:-1;border-radius:50%;
  background:radial-gradient(closest-side,rgba(6,4,16,.82),rgba(6,4,16,.5) 55%,transparent 80%)}
.winbanner.show{opacity:1;transform:translate(-50%,-50%) scale(1)}
.winbanner .wb-main{font-family:'Orbitron','Rajdhani';font-weight:900;font-size:34px;letter-spacing:1px;line-height:1;
  background:linear-gradient(90deg,#2DE2C5,#9A8BFF);-webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 2px 10px rgba(45,226,197,.5))}
.winbanner .wb-amt{font-family:'Rajdhani';font-weight:700;font-size:26px;color:var(--gold);margin-top:4px;text-shadow:0 2px 12px rgba(255,194,75,.7)}
/* all-in: bigger, gold, with a shake */
.winbanner.allin{animation:none}
.winbanner.allin.show{animation:wbshake .5s ease .1s}
.winbanner.allin .wb-top{font-family:'Orbitron','Rajdhani';font-weight:900;font-size:18px;letter-spacing:6px;color:var(--gold);text-shadow:0 0 16px rgba(255,194,75,.9)}
.winbanner.allin .wb-main{font-size:48px;background:linear-gradient(90deg,#FFC24B,#FF9D2B,#FF4D8D);-webkit-background-clip:text;background-clip:text;filter:drop-shadow(0 3px 18px rgba(255,157,43,.8))}
.winbanner.allin .wb-amt{font-size:32px}
@keyframes wbshake{0%,100%{transform:translate(-50%,-50%) scale(1) rotate(0)}20%{transform:translate(-52%,-50%) scale(1.04) rotate(-2deg)}60%{transform:translate(-48%,-50%) scale(1.04) rotate(2deg)}}

/* full-table gold flash (all-in only) */
.winflash{position:absolute;inset:0;z-index:48;pointer-events:none;opacity:0;transition:opacity .12s ease;
  background:radial-gradient(circle at 50% 42%,rgba(255,221,150,.85),rgba(255,157,43,.35) 45%,transparent 70%)}
.winflash.on{opacity:1}

/* confetti particles */
.confetti{position:absolute;width:8px;height:11px;border-radius:2px;z-index:46;opacity:1;
  transition:transform 1.1s cubic-bezier(.2,.6,.4,1),opacity 1.1s ease}

/* dealt card flying from dealer to each player at hand start */
.dealcard{position:absolute;width:30px;height:42px;border-radius:5px;z-index:42;opacity:0;
  background:linear-gradient(150deg,#6C4BFF,#3a1d6e);border:1px solid rgba(255,255,255,.18);
  box-shadow:0 5px 12px rgba(0,0,0,.55);transition:transform .38s cubic-bezier(.33,.7,.32,1),opacity .16s ease;will-change:transform,opacity}
.dealcard:after{content:"";position:absolute;inset:4px;border-radius:3px;border:1px dashed rgba(255,255,255,.3);
  background:radial-gradient(circle at 50% 50%,rgba(45,226,197,.4),transparent 60%)}
/* seat card backs fade in as the deal lands */
.seat .cards{transition:opacity .25s ease}

/* showdown: flip the face-down backs into faces */
.pc.reveal{animation:cardflip .42s ease both;transform-style:preserve-3d;backface-visibility:hidden}
@keyframes cardflip{0%{transform:rotateY(90deg) scale(.92);opacity:.2}60%{opacity:1}100%{transform:rotateY(0) scale(1);opacity:1}}

/* all-in suspense: the last board card lands face-down and flips back→front */
.flipcard{width:var(--pc-w);height:var(--pc-h);flex:none;position:relative;perspective:780px}
.flipcard.deal{animation:deal .42s ease both}
.flipcard .fi{position:absolute;inset:0;transform-style:preserve-3d;transition:transform .68s cubic-bezier(.5,.05,.2,1)}
.flipcard.flipped .fi{transform:rotateY(180deg)}
.flipcard .ff{position:absolute;inset:0;border-radius:7px;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.flipcard .fr{transform:rotateY(180deg)}
.flipcard.waiting .bk{animation:cardwait .9s ease-in-out infinite}
.flipcard.flipped{filter:drop-shadow(0 0 11px rgba(255,194,75,.6))}
@keyframes cardwait{0%,100%{box-shadow:0 4px 10px rgba(0,0,0,.4)}50%{box-shadow:0 0 16px 3px rgba(45,226,197,.7),0 4px 10px rgba(0,0,0,.45)}}

/* floating action label (CALL / RAISE / FOLD / ALL-IN) above a seat */
.actlabel{position:absolute;transform:translate(-50%,6px) scale(.8);z-index:45;pointer-events:none;
  font-family:'Rajdhani';font-weight:700;font-size:12px;letter-spacing:.4px;white-space:nowrap;
  padding:3px 10px;border-radius:999px;opacity:0;transition:transform .22s cubic-bezier(.3,1.4,.5,1),opacity .22s;
  background:rgba(20,14,40,.92);border:1px solid var(--bord);color:var(--text);box-shadow:0 4px 12px rgba(0,0,0,.5)}
.actlabel.show{opacity:1;transform:translate(-50%,-6px) scale(1)}
.actlabel.fold{color:#FFB3C0;border-color:rgba(255,59,92,.5)}
.actlabel.chk{color:#9af5e5;border-color:rgba(45,226,197,.45)}
.actlabel.call{color:#9af5e5;border-color:rgba(45,226,197,.55)}
.actlabel.bet{color:#fff;border-color:rgba(124,92,255,.7);background:linear-gradient(135deg,rgba(124,92,255,.92),rgba(177,75,255,.92))}
.actlabel.allin{color:#2a1900;font-weight:900;border-color:var(--gold2);background:linear-gradient(135deg,#FFD98A,#FF9D2B);box-shadow:0 4px 16px rgba(255,157,43,.6)}

/* ===== my seat: cards + stack, anchored to the felt's lower edge ===== */
.myseat{position:absolute;left:50%;bottom:138px;transform:translateX(-50%);z-index:15;
  display:flex;flex-direction:column;align-items:center;gap:6px}
/* Место под свои карты ЗАБРОНИРОВАНО — ровно две карты и зазор между ними, то
   есть натуральный размер этого блока с картами. Пока карт нет, коробка пустая
   и невидимая, но геометрия плашки личности не меняется весь стол.

   Это не косметика, а якорь для двух потребителей, которые считают координаты
   по рамке этого блока и пересчитать их позже им нечем:
     · компаньон (table/companions.js) парковался сбоку от карт и ПРОПАДАЛ на
       каждой новой раздаче: renderHole() чистит блок на время анимации сдачи,
       свёрнутая рамка (0×0) означала «ставить некуда», а следующий пересчёт
       приходит только со следующим снимком стола — то есть после моего
       действия. В окне посадки за стол (§5.7) карт нет вообще, и мой дрон
       оставался единственным за столом, кто не отыгрывал влёт;
     · анимация сдачи (dealAnimation) целилась в центр той же свёрнутой рамки —
       карты летели ниже того места, где потом появлялись.
   Оба лечатся одной строкой: рамка блока перестаёт зависеть от того, лежат ли
   в нём карты ПРЯМО СЕЙЧАС. Размеры совпадают с натуральными — ни один кадр с
   картами на экране не сдвинулся. */
.hero-cards{display:flex;gap:7px;z-index:15;
  min-width:calc(var(--hero-w) * 2 + 7px);min-height:var(--hero-h)}
.hero-cards .pc{width:var(--hero-w);height:var(--hero-h)}
.hero-cards .pc .c .rk{font-size:var(--hero-rk)}.hero-cards .pc .c .su{font-size:var(--hero-su)}.hero-cards .pc .big{font-size:var(--hero-big)}
/* Подсказка «Сила руки» на телефоне: одна строка над своими картами —
   «Две пары · уязвима · 9 аутов». До этого хиро с силой руки жил только в
   левом рельсе (десктоп ≥1280px), то есть в мобильном приложении подсказки не
   было вовсе. Цвет — по уровню, тот же язык, что у хиро. */
.handname{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translateX(-50%);
  background:rgba(45,226,197,.16);border:1px solid var(--teal);color:#9af5e5;font-size:11px;font-weight:700;
  padding:3px 12px;border-radius:999px;white-space:nowrap;z-index:16;opacity:0;transition:.2s;
  max-width:min(86vw,320px);overflow:hidden;text-overflow:ellipsis}
.handname.on{opacity:1}
.handname.lv-weak{background:rgba(255,255,255,.09);border-color:var(--bord);color:#cfc9e6}
.handname.lv-risky{background:rgba(255,194,75,.16);border-color:var(--gold);color:#ffe3ab}
.handname.lv-nuts{box-shadow:0 0 14px rgba(45,226,197,.45)}
.meinfo{display:inline-flex;align-items:center;gap:7px;font-family:'Rajdhani';font-weight:700;font-size:12px;
  color:var(--text);background:rgba(0,0,0,.55);border:1px solid var(--bord);border-radius:999px;
  padding:3px 12px;white-space:nowrap;backdrop-filter:blur(6px)}
.meinfo .nm{color:var(--muted);font-weight:500}
.meinfo b{color:var(--gold)}
.meinfo .mbet{color:var(--gold);display:inline-flex;align-items:center;gap:4px}
.meinfo .mbet:before{content:"";width:9px;height:9px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#FFD98A,#FF9D2B);border:1.5px solid #b86a00}

/* ===== bottom dock: bet controls + action buttons ===== */
.dock{position:absolute;left:0;right:0;bottom:0;z-index:25;
  padding:8px 16px calc(12px + env(safe-area-inset-bottom));
  background:linear-gradient(180deg,transparent,#0A0718 42%);
  display:flex;flex-direction:column;gap:8px}

.betzone{min-width:0}
.betzone:empty{display:none}
.quickbets{display:flex;gap:7px;margin-bottom:8px}
.qb{flex:1;min-width:0;background:var(--glass);border:1px solid var(--bord);border-radius:10px;padding:8px 2px;text-align:center;font-family:'Rajdhani';font-weight:700;font-size:13px;color:var(--text)}
.qb.on{border-color:var(--teal);color:var(--teal);background:rgba(45,226,197,.1)}
.qb.allin{border-color:var(--red);color:var(--red);background:rgba(255,77,79,.1)}
.slider{display:flex;align-items:center;gap:10px}
.slider i{color:var(--gold);font-size:15px}
.slider input{flex:1;min-width:0;-webkit-appearance:none;height:6px;border-radius:999px;background:linear-gradient(90deg,#7C5CFF var(--v,45%),rgba(255,255,255,.12) 0);outline:0}
.slider input::-webkit-slider-thumb{-webkit-appearance:none;width:20px;height:20px;border-radius:50%;background:linear-gradient(135deg,#fff,#cfc6ff);box-shadow:0 0 0 4px rgba(124,92,255,.4),0 2px 6px rgba(0,0,0,.5)}
.slider .amt{font-family:'Rajdhani';font-weight:700;color:var(--gold);font-size:15px;min-width:46px;text-align:right}

.waiting{text-align:center;color:var(--muted);font-size:13px;padding:10px 14px}
.abtns{display:flex;gap:8px}
.ab{flex:1;border:0;border-radius:13px;padding:13px 0;font-family:'Rajdhani';font-weight:700;font-size:16px;color:#fff}
.ab.fold{background:rgba(255,255,255,.08);border:1px solid var(--bord)}
.ab.check{background:rgba(45,226,197,.16);border:1px solid var(--teal);color:#9af5e5}
.ab.call{background:rgba(45,226,197,.16);border:1px solid var(--teal);color:#9af5e5}
.ab.raise{flex:1.4;background:linear-gradient(135deg,#7C5CFF,#B14BFF);box-shadow:0 8px 22px rgba(124,92,255,.5)}
.emo-btn{width:50px;flex:none;border-radius:13px;background:rgba(255,255,255,.08);border:1px solid var(--bord);color:#fff;font-size:20px}
.rebuy-btn{width:100%;border:0;border-radius:13px;padding:13px;font-family:'Rajdhani';font-weight:700;font-size:16px;color:#3a2400;background:linear-gradient(135deg,#FFC24B,#FF9D2B)}

/* ===== отчёт о матче: общая часть ===== */
#p-result{top:0;padding:0!important}

/* ===== toast ===== */
.toast{position:absolute;left:50%;bottom:120px;transform:translateX(-50%) translateY(20px);background:rgba(20,14,40,.96);border:1px solid var(--bord);color:var(--text);padding:11px 18px;border-radius:12px;font-size:13px;opacity:0;pointer-events:none;transition:.25s;z-index:100;max-width:84%;text-align:center}
.toast.on{opacity:1;transform:translateX(-50%) translateY(0)}

