/*
 * Cezalı 101 — css/style.css (UI agent)
 * Layout, table, rack (ıstaka), HUD, modals, toasts and animations.
 * Tile / avatar / logo artwork lives in css/art.css + js/ui/art.js.
 *
 * Everything inside #stage is laid out on a fixed 1600×900 virtual canvas that
 * js/ui/ui.js scales uniformly to the window (letterboxed).
 */

/* ======================================================================================
   1. Tokens & base
   ====================================================================================== */
:root {
  --gold: #f4c95d;
  --gold-2: #e0a43a;
  --gold-3: #b9791a;
  --gold-hair: rgba(244, 201, 93, 0.34);
  --gold-hair-strong: rgba(244, 201, 93, 0.62);
  --ink: #f6f1e6;
  --ink-dim: #c3cfcb;
  --ink-mute: #85999a;
  --glass: rgba(8, 20, 25, 0.66);
  --glass-strong: rgba(9, 22, 27, 0.86);
  --glass-hi: rgba(255, 255, 255, 0.07);
  --red: #ef5350;
  --red-2: #c62f35;
  --green: #3ddc97;
  --green-2: #14a06c;
  --blue: #5aaeff;
  --amber: #ffb547;
  --felt: #0d6044;
  --font-display: 'Baloo 2', 'Nunito', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body: 'Nunito', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-num: 'Rubik', 'Nunito', system-ui, sans-serif;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.55), 0 8px 20px rgba(0, 0, 0, 0.35);
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none; /* no pull-to-refresh / scroll chaining */
}
/* No Android font boosting / iOS text inflation: the stage is laid out in fixed virtual px. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
img, svg { -webkit-user-drag: none; }
/* Safe-area probe read by Stage.safeInsets() (ui.js) */
.sa-probe {
  position: fixed;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  visibility: hidden;
  pointer-events: none;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}

body {
  background-color: #061013;
  background-image:
    radial-gradient(120% 95% at 50% 42%, #153a41 0%, #0b2127 46%, #050d10 100%),
    repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.012) 0 2px, transparent 2px 14px);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
  touch-action: none;
}

button { font: inherit; color: inherit; }
button:focus { outline: none; }
button:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* absolute, not fixed: html / body are the viewport and never scroll, so the box is the same — and a
   fixed full-screen box was a second full-screen compositor layer (12 MB on a phone) under the page */
.app { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; }

.stage {
  position: absolute;
  left: 0;
  top: 0;
  width: 1600px;
  height: 900px;
  transform-origin: 0 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.45s ease;
}
.stage.is-ready { opacity: 1; }
/* Android app, until js/main.js reveals the page (index.html .c101-boot, under the native splash): no
   pixel is painted — the WebView's first frames have almost no tile memory — while the page is built
   and laid out as usual; its animations wait at their start, the stage fades in after the reveal. */
html.c101-boot body { background: transparent; }
html.c101-boot body,
html.c101-boot body * { visibility: hidden !important; }
html.c101-boot body *,
html.c101-boot body *::before,
html.c101-boot body *::after { animation-play-state: paused !important; }

.stage svg { display: block; }

/* Boot splash & helpers outside the stage ------------------------------------------- */
.boot {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  z-index: 5;
  transition: opacity 0.4s ease, visibility 0.4s;
}
.boot.is-hidden { opacity: 0; visibility: hidden; pointer-events: none; }
/* The logo's 1 · 0 · 1 tiles in their rail (inline SVG in index.html): they hop one after the other.
   Lengths inside the SVG are its own units (the mark is ~283 units wide). */
.boot-mark {
  display: block;
  width: 136px;
  height: auto;
  overflow: visible;
  filter: drop-shadow(0 10px 12px rgba(0, 0, 0, 0.45));
}
.boot-mark .bm-t { animation: bootHop 1.6s var(--ease-out) infinite; }
.boot-mark .bm-t2 { animation-delay: 0.14s; }
.boot-mark .bm-t3 { animation-delay: 0.28s; }
.boot-text { font: 700 18px var(--font-body); color: var(--ink-dim); letter-spacing: 0.02em; }
@keyframes bootHop {
  0%, 52%, 100% { transform: translateY(0); }
  20% { transform: translateY(-20px); }
}

.boot-error {
  max-width: 560px;
  padding: 22px 26px;
  border-radius: 18px;
  background: var(--glass-strong);
  border: 1px solid rgba(239, 83, 80, 0.5);
  font: 600 17px/1.5 var(--font-body);
  color: var(--ink);
  text-align: center;
}
.boot-error b { color: #ff8f8c; }

.noscript {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font: 700 20px var(--font-body);
  color: var(--ink);
  z-index: 10;
}

.rotate-hint {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  background: rgba(4, 12, 14, 0.94);
  text-align: center;
  padding: 24px;
}
.rotate-hint-phone {
  width: 54px;
  height: 92px;
  border-radius: 12px;
  border: 4px solid var(--gold);
  box-shadow: 0 0 24px rgba(244, 201, 93, 0.4);
  animation: rotateHint 2.2s var(--ease-out) infinite;
}
.rotate-hint-text { font: 700 18px/1.4 var(--font-body); color: var(--ink); max-width: 280px; }
@keyframes rotateHint {
  0%, 20% { transform: rotate(0deg); }
  55%, 100% { transform: rotate(-90deg); }
}
@media (orientation: portrait) and (max-width: 820px) {
  .rotate-hint { display: flex; }
}

/* ======================================================================================
   2. Screens
   ====================================================================================== */
.screen {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s ease, visibility 0.35s;
}
.screen.is-active { opacity: 1; visibility: visible; }
/* A hidden screen (the menu during a game, the table behind the menu) never animates: its infinite
   animations would keep producing frames — and main-thread work — for the whole game. They resume
   where they stopped when the screen is shown again (SMIL: UI.showScreen() pauses the menu logo). */
.screen:not(.is-active) *,
.screen:not(.is-active) *::before,
.screen:not(.is-active) *::after { animation-play-state: paused !important; }

.fx-layer { position: absolute; inset: 0; pointer-events: none; z-index: 60; }
.modal-layer { position: absolute; inset: 0; pointer-events: none; z-index: 80; }
.toast-layer {
  position: absolute;
  left: 50%;
  top: 166px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  z-index: 95;
  pointer-events: none;
  width: 900px;
}

/* ======================================================================================
   3. Buttons
   ====================================================================================== */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 48px;
  padding: 0 20px;
  border: 0;
  border-radius: 14px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 20px;
  line-height: 1;
  letter-spacing: 0.01em;
  color: #fff;
  cursor: pointer;
  white-space: nowrap;
  background: linear-gradient(180deg, #4a5f66, #2c3c42);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -3px 0 rgba(0, 0, 0, 0.22),
    0 6px 14px rgba(0, 0, 0, 0.35);
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
  transition: transform 0.14s var(--ease-out), filter 0.18s, box-shadow 0.18s, opacity 0.25s;
}
.btn > span { position: relative; z-index: 1; }
.btn::after {
  content: '';
  position: absolute;
  inset: 1px 1px 50% 1px;
  border-radius: 13px 13px 40% 40% / 13px 13px 12px 12px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0));
  pointer-events: none;
}
.btn:hover { filter: brightness(1.08) saturate(1.05); transform: translateY(-1px); }
.btn:active {
  transform: translateY(2px) scale(0.985);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.22), 0 2px 6px rgba(0, 0, 0, 0.35);
}
.btn-ic { display: inline-flex; width: 22px; height: 22px; flex: none; }
.btn-ic svg { width: 100%; height: 100%; }
.btn-ic:empty { display: none; }

.btn-gold {
  background: linear-gradient(180deg, #ffe596 0%, #f6be45 46%, #d98c16 100%);
  color: #3d2400;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.45);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    inset 0 -3px 0 rgba(120, 60, 0, 0.35),
    0 6px 16px rgba(0, 0, 0, 0.38),
    0 0 0 1px rgba(120, 70, 0, 0.35);
}
.btn-emerald {
  background: linear-gradient(180deg, #4de3a8 0%, #19a974 52%, #0d7d55 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45), inset 0 -3px 0 rgba(0, 60, 35, 0.4), 0 6px 14px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(0, 70, 40, 0.4);
}
.btn-sapphire {
  background: linear-gradient(180deg, #7cc0ff 0%, #2f7fe6 52%, #1c58b8 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45), inset 0 -3px 0 rgba(10, 30, 90, 0.4), 0 6px 14px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(10, 40, 100, 0.45);
}
.btn-danger {
  background: linear-gradient(180deg, #ff9384 0%, #e5484d 52%, #b32731 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45), inset 0 -3px 0 rgba(90, 10, 15, 0.4), 0 6px 14px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(100, 10, 20, 0.45);
}
.btn-glass {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.04));
  border: 1px solid var(--gold-hair);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 6px 14px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.btn-glass::after { opacity: 0.35; }
.btn-lg { height: 58px; font-size: 24px; border-radius: 17px; padding: 0 28px; }
.btn-xl { height: 70px; font-size: 30px; border-radius: 20px; padding: 0 36px; }
.btn-lg .btn-ic, .btn-xl .btn-ic { width: 28px; height: 28px; }

.btn.is-disabled,
.btn:disabled {
  filter: grayscale(0.9) brightness(0.62);
  opacity: 0.62;
  cursor: not-allowed;
}
.btn.is-disabled:hover,
.btn:disabled:hover { transform: none; }
.btn.is-hidden { display: none; }

.icon-btn {
  position: relative;
  width: 42px;
  height: 42px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  border: 1px solid var(--gold-hair);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.03));
  color: var(--ink);
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 4px 10px rgba(0, 0, 0, 0.3);
  transition: transform 0.14s var(--ease-out), background 0.2s, color 0.2s, border-color 0.2s;
}
.icon-btn svg { width: 22px; height: 22px; }
.icon-btn:hover { background: linear-gradient(180deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.06)); color: #fff6d8; border-color: var(--gold-hair-strong); transform: translateY(-1px); }
.icon-btn:active { transform: translateY(1px) scale(0.96); }
.icon-btn.is-on { color: var(--gold); border-color: var(--gold-hair-strong); }
.icon-btn.is-off { color: var(--ink-mute); }
.icon-btn .ib-fallback { font: 800 13px var(--font-display); }

/* Tooltips for icon buttons */
.icon-btn[data-tip]::before {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translate(-50%, -4px);
  padding: 5px 10px;
  border-radius: 8px;
  background: rgba(5, 14, 17, 0.95);
  border: 1px solid var(--gold-hair);
  font: 700 13px var(--font-body);
  color: var(--ink);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s, transform 0.15s;
  z-index: 5;
}
.icon-btn[data-tip]:hover::before { opacity: 1; transform: translate(-50%, 0); }

/* ======================================================================================
   4. Menu screen
   ====================================================================================== */
.screen-menu { overflow: hidden; overflow: clip; }
.menu-bg { position: absolute; inset: 0; overflow: hidden; }
.menu-glow {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(38% 46% at 50% 40%, rgba(40, 170, 120, 0.34), transparent 70%),
    radial-gradient(60% 60% at 50% 110%, rgba(244, 201, 93, 0.14), transparent 70%),
    radial-gradient(90% 80% at 50% 50%, transparent 55%, rgba(0, 0, 0, 0.5) 100%);
}
/* Soft lamp light over the felt behind the logo (a plain radial glow: no rays / sunburst, see the
   motif rule in js/ui/art.js), breathing very slowly, over a faint felt grain. */
.menu-bg::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--c101-tex-felt-noise, none);
  opacity: 0.55;
  -webkit-mask: radial-gradient(75% 80% at 50% 40%, #000 30%, transparent 100%);
  mask: radial-gradient(75% 80% at 50% 40%, #000 30%, transparent 100%);
  pointer-events: none;
}
.menu-halo {
  position: absolute;
  left: 50%;
  top: 34%;
  width: 1400px;
  height: 860px;
  margin: -430px 0 0 -700px;
  background:
    radial-gradient(closest-side, rgba(255, 234, 178, 0.13), rgba(255, 234, 178, 0.05) 42%, transparent 100%),
    radial-gradient(closest-side, rgba(52, 196, 136, 0.2), rgba(52, 196, 136, 0.06) 55%, transparent 100%);
  animation: haloBreath 10s ease-in-out infinite;
}
@keyframes haloBreath {
  0%, 100% { opacity: 0.78; transform: scale(0.97); }
  50% { opacity: 1; transform: scale(1.03); }
}
.menu-tiles { position: absolute; inset: 0; }
.float-tile {
  position: absolute;
  width: 70px;
  height: 98px;
  transform: translate(-50%, -50%) rotate(var(--r, 0deg)) scale(var(--s, 1));
  animation: floatTile var(--d, 9s) ease-in-out var(--dl, 0s) infinite alternate;
  opacity: var(--o, 0.9);
  filter: drop-shadow(0 14px 18px rgba(0, 0, 0, 0.45));
}
.float-tile > svg { width: 100%; height: 100%; }
@keyframes floatTile {
  from { transform: translate(-50%, -50%) translateY(-14px) rotate(var(--r, 0deg)) scale(var(--s, 1)); }
  to { transform: translate(-50%, -50%) translateY(16px) rotate(calc(var(--r, 0deg) + 7deg)) scale(var(--s, 1)); }
}

.menu-main {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 760px;
  transform: translate(-50%, -52%);
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* the horizontal lockup (Art.logo, viewBox 1569 × 447) */
.menu-logo {
  width: 744px;
  height: 212px;
  animation: logoIn 0.9s var(--ease-spring) backwards;
}
/* (the endless float on an inner box: two transform animations on one element — logoIn, logoFloat —
   are animated on the main thread, one per element on the compositor) */
.menu-logo-in {
  position: relative; /* (the sheen overlay) */
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: logoFloat 6s ease-in-out 1s infinite;
}
.menu-logo-in > svg { width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 16px 26px rgba(0, 0, 0, 0.5)); }
/* The light sweeping over "Cezalı" (Art.logoSheen): a band of light in an SVG of its own, moved by the
   compositor and seen through a mask of the word — the logo is painted once, never per frame (it was
   a SMIL gradient animation that repainted the whole logo on every frame, also between two passes).
   Same band, same 7 s rhythm: 2.1 s across from 1.2 s, then outside the word. */
.c101-logo-sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
.c101-logo-band {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  animation: c101LogoSheen 7s linear 1.2s infinite;
}
.c101-logo-band > svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* one sweep = the word's width + 2 bands = (892 + 2 × 143) / 1569 of the logo's width (Art.logoSheen) */
@keyframes c101LogoSheen {
  0% { transform: translateX(0); }
  30%, 100% { transform: translateX(75.0797%); }
}
.logo-fallback {
  font: 800 110px/1 var(--font-display);
  color: var(--gold);
  text-shadow: 0 6px 0 #7a4b00, 0 18px 30px rgba(0, 0, 0, 0.5);
}
.logo-fallback b { color: #ff6b5b; }
@keyframes logoIn { from { opacity: 0; transform: scale(0.7) translateY(30px); } to { opacity: 1; transform: none; } }
@keyframes logoFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }

.menu-tag {
  margin-top: 10px;
  font: 700 22px var(--font-display);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 236, 190, 0.78);
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
  animation: fadeUp 0.7s var(--ease-out) 0.3s backwards;
}
.menu-btns {
  position: relative; /* (the gold button's glow, ::before) */
  margin-top: 34px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 14px;
  width: 360px;
}
.menu-btns .btn { width: 100%; animation: fadeUp 0.6s var(--ease-out) backwards; }
.menu-btns .btn:nth-child(1) { animation-delay: 0.35s; }
.menu-btns .btn:nth-child(2) { animation-delay: 0.43s; }
.menu-btns .btn:nth-child(3) { animation-delay: 0.51s; }
.menu-btns .btn:nth-child(4) { animation-delay: 0.59s; }
.menu-btns .btn-xl.btn-gold { animation: fadeUp 0.6s var(--ease-out) 0.35s backwards; }
/* Its slow golden pulse: a pre-painted glow whose opacity breathes (compositor only, see glowPulse).
   It was the gold button's outermost shadow, under the button's own drop shadow — so it is painted
   just before the buttons (the column's ::before, on the first button: Oyna, or Devam Et during a
   match — whichever is the gold one), not over the button's shadow from inside it. */
.menu-btns::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 70px; /* .btn-xl */
  border-radius: 20px;
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 34px 6px rgba(255, 210, 100, 0.45);
  animation: glowPulse 2.6s ease-in-out 1.4s infinite;
}
.is-phone .menu-btns::before { height: 58px; border-radius: 16px; } /* (.is-phone .btn-xl) */
.menu-row { display: flex; gap: 14px; }
.menu-row .btn { flex: 1; }

.menu-profile {
  position: absolute;
  left: 28px;
  top: 26px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 20px 8px 8px;
  border-radius: 999px;
  background: var(--glass);
  border: 1px solid var(--gold-hair);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);
  cursor: pointer;
  transition: transform 0.15s var(--ease-out), border-color 0.2s;
  animation: fadeIn 0.6s ease 0.4s backwards;
}
.menu-profile:hover { transform: translateY(-1px); border-color: var(--gold-hair-strong); }
.mp-av { width: 58px; height: 58px; border-radius: 50%; overflow: hidden; box-shadow: 0 0 0 3px var(--gold), 0 4px 10px rgba(0, 0, 0, 0.4); background: #173338; }
.mp-av svg { width: 100%; height: 100%; }
.mp-name { font: 800 22px/1.1 var(--font-display); color: #fff; }
.mp-sub { font: 700 14px var(--font-body); color: var(--ink-dim); }

.menu-foot {
  position: absolute;
  right: 28px;
  bottom: 22px;
  font: 700 14px var(--font-body);
  color: var(--ink-mute);
  letter-spacing: 0.05em;
}
.menu-foot b { color: var(--gold); font-weight: 800; }
.menu-hint {
  position: absolute;
  left: 28px;
  bottom: 22px;
  font: 600 14px var(--font-body);
  color: var(--ink-mute);
}
.menu-hint .mh-touch { display: none; }

/* ======================================================================================
   5. Game screen: room, top bar
   ====================================================================================== */
/* clip (not just hidden): the closed log panel sits off-stage, and a hidden-overflow box can still be
   scrolled by script / focus / scroll-to-text, which would shift the whole table sideways. */
.screen-game { overflow: hidden; overflow: clip; }
.room {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(55% 60% at 50% 48%, rgba(255, 230, 170, 0.09), transparent 70%),
    radial-gradient(100% 90% at 50% 50%, transparent 60%, rgba(0, 0, 0, 0.45) 100%);
  pointer-events: none;
}

.topbar {
  position: absolute;
  left: 0;
  top: 0;
  width: 1600px;
  height: 56px;
  display: flex;
  align-items: center;
  padding: 0 16px 0 14px;
  gap: 14px;
  z-index: 30;
  background: linear-gradient(180deg, rgba(5, 14, 17, 0.92), rgba(6, 17, 21, 0.72));
  border-bottom: 1px solid var(--gold-hair);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.35);
}
.topbar .tb-menu { display: none; } /* phone layout only */
/* compact lockup (Art.logo({ compact: true }), viewBox 1305 × 352): 40px high */
.tb-logo { width: 148px; height: 40px; display: flex; align-items: center; flex: none; }
.tb-logo > svg { width: 100%; height: 100%; overflow: visible; }
.tb-logo .logo-fallback { font-size: 30px; text-shadow: 0 2px 0 #7a4b00; }
.tb-pill {
  height: 38px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--gold-hair);
  font: 700 15px var(--font-body);
  color: var(--ink-dim);
  white-space: nowrap;
}
.tb-pill b { font: 800 19px var(--font-num); color: #fff; }
.tb-round b { color: var(--gold); }
.tb-center { flex: 1; display: flex; justify-content: center; align-items: center; gap: 10px; }
/* "Gösterge [tile]": the okey is not shown, as at a real 101 table (the next number of the same colour) */
.tb-gosterge { gap: 10px; padding: 0 12px 0 16px; height: 44px; }
/* Barrier HUD: "Baraj 107 · Çift 6" (raising barriers) */
.tb-barrier { height: 44px; gap: 8px; padding: 0 16px; color: var(--ink-dim); cursor: help; }
.tb-barrier b { color: var(--gold); min-width: 22px; text-align: center; }
.tb-barrier.no-pairs .tb-sep, .tb-barrier.no-pairs .tb-bp { display: none; }
.tb-barrier.is-bump { animation: barrierBump 0.9s var(--ease-out); }
.tb-mini { width: 26px; height: 36px; flex: none; }
.tb-mini > svg { width: 100%; height: 100%; }
.tb-sep { width: 1px; height: 22px; background: var(--gold-hair); }
.tb-right { display: flex; gap: 8px; align-items: center; }
/* Android app (js/platform/native.js sets .is-native): the activity is already immersive full screen. */
.is-native .tb-right [data-act="fullscreen"] { display: none; }
.tb-deck b { color: #fff; }

/* ======================================================================================
   6. Table
   ====================================================================================== */
.table {
  position: absolute;
  left: 128px;
  top: 60px;
  width: 1344px;
  height: 640px;
  border-radius: 210px;
  z-index: 1;
}
.table-rim {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--tex-wood, linear-gradient(180deg, #7b4a26 0%, #5a3218 45%, #3c2010 100%));
  box-shadow:
    0 34px 70px rgba(0, 0, 0, 0.6),
    0 10px 22px rgba(0, 0, 0, 0.45),
    inset 0 2px 1px rgba(255, 225, 170, 0.35),
    inset 0 -6px 12px rgba(0, 0, 0, 0.55);
}
.table-rim::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background:
    linear-gradient(180deg, rgba(255, 220, 160, 0.22) 0%, transparent 22%, transparent 70%, rgba(0, 0, 0, 0.35) 100%),
    radial-gradient(70% 40% at 50% 0%, rgba(255, 235, 190, 0.18), transparent 70%);
  pointer-events: none;
}
.table-rim::after {
  /* thin brass inlay */
  content: '';
  position: absolute;
  inset: 12px;
  border-radius: 198px;
  border: 2px solid rgba(233, 190, 102, 0.55);
  box-shadow: 0 0 0 1px rgba(60, 30, 5, 0.6), inset 0 0 0 1px rgba(60, 30, 5, 0.5);
  pointer-events: none;
}
/* The procedural textures baked into bitmaps (ui.js TexBake, ≈ 1 bitmap px per device px): sampled
   nearest like the browser samples its own raster of the SVG tile, so the pixels are the same. */
.tex-baked .table-rim,
.tex-baked .felt-tex,
.tex-baked .rack-body,
.tex-baked .rack-ledge,
.tex-baked .rack-cap,
.tex-baked .menu-bg::before { image-rendering: pixelated; }
.table-felt {
  position: absolute;
  inset: 18px;
  border-radius: 192px;
  overflow: hidden;
  background-color: var(--felt);
  box-shadow:
    inset 0 0 0 2px rgba(0, 0, 0, 0.4),
    inset 0 14px 30px rgba(0, 0, 0, 0.55),
    inset 0 -10px 30px rgba(0, 0, 0, 0.35);
}
.felt-tex {
  position: absolute;
  inset: 0;
  background: var(--tex-felt, radial-gradient(90% 85% at 50% 45%, #178a5f 0%, #0f6a48 50%, #0a4a33 100%));
}
.felt-light {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(48% 52% at 50% 44%, rgba(255, 250, 225, 0.17), transparent 72%),
    radial-gradient(120% 110% at 50% 50%, transparent 52%, rgba(0, 0, 0, 0.5) 100%);
  pointer-events: none;
}
.felt-lines {
  position: absolute;
  inset: 16px;
  border-radius: 178px;
  border: 2px dashed rgba(255, 255, 255, 0.075);
  pointer-events: none;
}
/* The logo printed into the felt blends (soft-light) with the felt under it. A blend makes its whole
   stacking context an offscreen group — that was the whole table, on every raster of any part of it.
   So it blends inside a box of its own: a copy of the felt's layers (same classes, same place: the
   very same pixels), isolated and clipped to the logo's box (+ 2px), so the group is only that big.
   The clip follows .felt-emblem's geometry below (desktop 540 × 154 at 50% / 46%, phone 330 × 94 at
   50% / --ph-mid-c, section 18). */
.felt-emblem-box {
  position: absolute;
  inset: 0;
  isolation: isolate;
  pointer-events: none;
  clip-path: inset(calc(46% - 79px) calc(50% - 272px) calc(54% - 79px) calc(50% - 272px));
}
/* the logo printed into the felt (Art.logo({ flat: true }), 1569 × 447) */
.felt-emblem {
  position: absolute;
  left: 50%;
  top: 46%;
  width: 540px;
  height: 154px;
  transform: translate(-50%, -50%);
  opacity: 0.1;
  filter: grayscale(1) brightness(1.8);
  mix-blend-mode: soft-light;
  pointer-events: none;
  transition: opacity 0.6s ease;
}
.felt-emblem > svg { width: 100%; height: 100%; }
/* baked into a bitmap at its device size with this filter already applied (ui.js EmblemBake) */
.felt-emblem.is-baked { filter: none; }
.felt-emblem > img { display: block; width: 100%; height: 100%; }
.screen-game.has-melds .felt-emblem { opacity: 0.045; }

/* ======================================================================================
   7. Seats
   ====================================================================================== */
.seat {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 10px;
  z-index: 12;
  --seat-c: var(--gold);
}
.seat-0 { left: 12px; top: 674px; width: 256px; height: 110px; }
.seat-1 { left: 1480px; top: 196px; width: 112px; flex-direction: column; gap: 6px; }
.seat-3 { left: 8px; top: 196px; width: 112px; flex-direction: column; gap: 6px; }
.seat-2 { left: 540px; top: 60px; width: 520px; height: 96px; justify-content: center; }
.seat-2 .seat-hand { order: 0; }
.seat-2 .seat-av { order: 1; }
.seat-2 .seat-info { order: 2; }

.seat-av { position: relative; width: 86px; height: 86px; flex: none; }
.seat-0 .seat-av { width: 96px; height: 96px; }
.seat-2 .seat-av { width: 82px; height: 82px; }
.seat-av-img {
  position: absolute;
  inset: 7px;
  border-radius: 50%;
  overflow: hidden;
  background: radial-gradient(circle at 50% 35%, #2b525a, #0f2429);
  box-shadow: 0 0 0 3px rgba(244, 201, 93, 0.85), 0 8px 18px rgba(0, 0, 0, 0.55);
  transition: box-shadow 0.3s ease, transform 0.3s var(--ease-out);
}
.seat-av-img > svg { width: 100%; height: 100%; }
.seat-av-fallback {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font: 800 34px var(--font-display);
  color: #fff;
}
.seat-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.3s ease;
  background: conic-gradient(var(--ring-c, #3ddc97) calc(var(--p, 1) * 360deg), rgba(255, 255, 255, 0.12) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 5px));
}
.seat.is-active .seat-ring { opacity: 1; }
.seat-bot.is-active .seat-ring {
  background: conic-gradient(from 0deg, rgba(244, 201, 93, 0) 0deg, rgba(244, 201, 93, 0.15) 120deg, var(--gold) 330deg, #fff6d6 360deg);
  animation: spin 1.15s linear infinite;
}
.seat.is-active .seat-av-img {
  box-shadow: 0 0 0 3px #fff1bd, 0 0 26px 6px rgba(244, 201, 93, 0.55), 0 8px 18px rgba(0, 0, 0, 0.55);
  transform: scale(1.04);
}
/* The last 5 s of the human's turn: the avatar's shadow turns red (the static low point of the pulse)
   and .seat-glow — a sibling right after the avatar (the avatar clips its own children) carrying the
   brighter red ring and halo — breathes over it by opacity only (glowPulse: compositor, no repaint). */
.seat-glow {
  position: absolute;
  inset: 7px;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 0 3px #ff5a50, 0 0 30px 8px rgba(239, 83, 80, 0.62);
  transition: transform 0.3s var(--ease-out);
}
.seat.is-active .seat-glow { transform: scale(1.04); }
.seat.seat-0.is-urgent .seat-av-img,
.is-phone .seat.seat-0.is-urgent .seat-av-img {
  box-shadow: 0 0 0 3px #ff8a80, 0 0 16px 4px rgba(239, 83, 80, 0.45), 0 8px 18px rgba(0, 0, 0, 0.55);
  transition: transform 0.3s var(--ease-out);
}
.seat-0.is-urgent .seat-glow { animation: glowPulse 0.8s ease-in-out infinite; }

.seat-timer {
  position: absolute;
  left: 50%;
  bottom: -6px;
  transform: translateX(-50%);
  min-width: 40px;
  height: 22px;
  padding: 0 7px;
  border-radius: 11px;
  background: #0a1b1f;
  border: 1px solid var(--gold-hair);
  font: 800 13px/20px var(--font-num);
  text-align: center;
  color: #fff;
  opacity: 0;
  transition: opacity 0.2s, color 0.2s, border-color 0.2s;
  z-index: 2;
}
.seat-timer.is-on { opacity: 1; }
.seat-timer.is-low { color: #ff8f8c; border-color: rgba(239, 83, 80, 0.7); }

.seat-info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
  padding: 7px 12px 8px;
  border-radius: 14px;
  background: var(--glass);
  border: 1px solid var(--gold-hair);
  box-shadow: inset 0 1px 0 var(--glass-hi), 0 8px 18px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.seat-1 .seat-info, .seat-3 .seat-info { align-items: center; width: 112px; padding: 6px 6px 7px; }
.seat-0 .seat-info { flex: 1; }
.seat-name {
  max-width: 140px;
  font: 700 18px/1.1 var(--font-display);
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.seat-1 .seat-name, .seat-3 .seat-name { max-width: 100px; font-size: 16px; }
.seat-score {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  font: 700 12px var(--font-body);
  color: var(--ink-mute);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.seat-score b { font: 800 18px var(--font-num); color: var(--gold); letter-spacing: 0; text-transform: none; }
.seat-score b.is-neg { color: var(--green); }
.seat-badges { display: flex; gap: 4px; flex-wrap: wrap; justify-content: center; }
.seat-badge {
  display: none;
  height: 20px;
  padding: 0 8px;
  border-radius: 10px;
  font: 800 12px/20px var(--font-body);
  white-space: nowrap;
}
.seat-badge.is-on { display: inline-block; animation: badgePop 0.45s var(--ease-spring) backwards; }
.seat-badge.b-open { background: linear-gradient(180deg, #58e8ad, #16a36f); color: #03281a; }
.seat-badge.b-pairs { background: linear-gradient(180deg, #8ac6ff, #2c78e0); color: #04203f; }
.seat-badge.b-pen { background: linear-gradient(180deg, #ff8a80, #d8343b); color: #fff; }
.seat-badge.b-pen.b-bonus { background: linear-gradient(180deg, #7dffc4, #16a36f); color: #03281a; }
.seat-badge.b-dive { background: linear-gradient(180deg, #ffc27a, #e06a1c); color: #3a1400; box-shadow: 0 0 10px rgba(255, 150, 60, 0.45); }
/* Provisional opening (this turn, not committed yet) */
.seat-badge.is-prov {
  background: rgba(255, 215, 102, 0.12) !important;
  color: #ffe7a6 !important;
  border: 1px dashed rgba(255, 215, 102, 0.85);
  line-height: 18px;
}
.seat-diff { font: 700 11px var(--font-body); color: var(--ink-mute); text-transform: uppercase; letter-spacing: 0.08em; }

.seat-hand { position: relative; width: 108px; height: 50px; flex: none; }
.seat-2 .seat-hand { width: 124px; height: 56px; margin-right: 6px; }
.seat-fan { position: absolute; left: 50%; bottom: 4px; width: 0; height: 0; }
.fan-tile {
  position: absolute;
  left: -12px;
  bottom: 0;
  width: 24px;
  height: 34px;
  transform-origin: 50% 140%;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.35));
}
.fan-tile > svg { width: 100%; height: 100%; }
.seat-count {
  position: absolute;
  right: -2px;
  top: -8px;
  min-width: 28px;
  height: 22px;
  padding: 0 6px;
  border-radius: 11px;
  background: #0a1b1f;
  border: 1px solid var(--gold-hair-strong);
  font: 800 13px/20px var(--font-num);
  text-align: center;
  color: #fff;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4);
}

.seat-fx { position: absolute; left: 50%; top: 18px; width: 0; height: 0; pointer-events: none; z-index: 20; }
.seat-0 .seat-fx { left: 60px; top: -10px; }
.seat-2 .seat-fx { top: 112px; }
.flash {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, 0);
  text-align: center;
  white-space: nowrap;
  animation: flashUp 1.9s var(--ease-out) forwards;
}
.flash-num { display: block; font: 800 40px/1 var(--font-display); }
.flash-sub { display: block; font: 800 14px var(--font-body); letter-spacing: 0.08em; text-transform: uppercase; margin-top: 2px; }
.flash-bad .flash-num { color: #ff6b66; text-shadow: 0 3px 0 #5b0c0c, 0 0 22px rgba(255, 70, 70, 0.7); }
.flash-bad .flash-sub { color: #ffd0cc; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8); }
.flash-good .flash-num { color: #74ffc0; text-shadow: 0 3px 0 #064a2c, 0 0 22px rgba(60, 255, 170, 0.6); }
.flash-good .flash-sub { color: #d5ffe9; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8); }
.flash-info .flash-num { color: var(--gold); text-shadow: 0 3px 0 #5a3a00, 0 0 22px rgba(244, 201, 93, 0.6); }

.seat-bubble {
  position: absolute;
  z-index: 25;
  padding: 7px 13px;
  border-radius: 14px;
  background: linear-gradient(180deg, #fffdf5, #f3e7c8);
  color: #33240a;
  font: 800 15px/1.1 var(--font-display);
  white-space: nowrap;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.45);
  pointer-events: none;
  animation: bubble 2.3s var(--ease-out) forwards;
}
.seat-bubble::after {
  content: '';
  position: absolute;
  width: 12px;
  height: 12px;
  background: #f8efd8;
  transform: rotate(45deg);
}
.seat-bubble.b-good { background: linear-gradient(180deg, #e9fff4, #bff5da); color: #073a24; }
.seat-bubble.b-good::after { background: #d2f9e6; }
.seat-bubble.b-bad { background: linear-gradient(180deg, #fff0ee, #ffd1cc); color: #5a0e0e; }
.seat-bubble.b-bad::after { background: #ffe0dc; }
.seat-1 .seat-bubble { right: calc(100% + 10px); top: 26px; }
.seat-1 .seat-bubble::after { right: -5px; top: 12px; }
.seat-3 .seat-bubble { left: calc(100% + 10px); top: 26px; }
.seat-3 .seat-bubble::after { left: -5px; top: 12px; }
.seat-2 .seat-bubble { left: 50%; top: calc(100% + 6px); transform: translateX(-50%); }
.seat-2 .seat-bubble::after { left: calc(50% - 6px); top: -5px; }
.seat-0 .seat-bubble { left: 20px; bottom: calc(100% + 8px); }
.seat-0 .seat-bubble::after { left: 34px; bottom: -5px; }

/* ======================================================================================
   8. Discard piles & centre hub
   ====================================================================================== */
.pile {
  position: absolute;
  width: 76px;
  height: 104px;
  z-index: 6;
}
.pile-0 { left: 1236px; top: 546px; }
.pile-1 { left: 1236px; top: 96px; }
.pile-2 { left: 288px; top: 96px; }
.pile-3 { left: 288px; top: 546px; }
.pile-slot,
.pile-anchor {
  position: absolute;
  left: 10px;
  top: 10px;
  width: 56px;
  height: 78px;
}
.pile-slot {
  border-radius: 10px;
  border: 2px dashed rgba(255, 255, 255, 0.2);
  background: rgba(0, 0, 0, 0.14);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.2s, background 0.2s;
}
.pile-tile {
  position: absolute;
  left: 0;
  top: 0;
  width: 56px;
  height: 78px;
  border-radius: 8px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);
}
.pile-tile > svg { width: 100%; height: 100%; }
.pile-tile.is-hidden { visibility: hidden; }
.pile-cap {
  position: absolute;
  left: -20px;
  right: -20px;
  top: 92px;
  text-align: center;
  font: 800 12px var(--font-display);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.pile-count {
  position: absolute;
  right: -8px;
  top: 0;
  min-width: 26px;
  height: 22px;
  padding: 0 6px;
  border-radius: 11px;
  border: 1px solid var(--gold-hair);
  background: rgba(6, 18, 21, 0.9);
  font: 800 12px/20px var(--font-num);
  color: var(--ink-dim);
  cursor: pointer;
  z-index: 3;
  transition: transform 0.15s var(--ease-out), color 0.15s;
}
.pile-count:hover { color: #fff; transform: scale(1.08); }
.pile.is-empty .pile-count { display: none; }
/* Touch screens: Chromium's touch adjustment moves a finger tap (pointer events and click) to the best
   clickable element within ±16 CSS px of the finger, and a small button near the finger beats the
   tile under it — the count badge (discard history) opened instead of the side tile being taken
   (Xiaomi 17 Pro). So the badges of the two piles you act on (yandan: take, taş at: discard) keep
   ≥ 20 virtual px from their tile; the history stays tappable in every phase. Phones: section 18. */
@media (pointer: coarse) {
  .pile-3 .pile-count,
  .pile-0 .pile-count { top: -34px; right: 6px; }
}

.pile.can-take .pile-tile.is-top { cursor: grab; }
/* the side tile you may take: a gold ring (the static low point of the pulse) and a brighter ring +
   halo on ::before (under the tiles) breathing by opacity only — never a per-frame repaint.
   (::after is the finger-sized take area) */
.pile.can-take .pile-anchor { border-radius: 9px; box-shadow: 0 0 0 2px rgba(244, 201, 93, 0.6), 0 0 10px rgba(244, 201, 93, 0.35); }
.pile.can-take .pile-anchor::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 0 3px rgba(244, 201, 93, 0.88), 0 0 24px rgba(244, 201, 93, 0.6);
  animation: glowPulse 1.6s ease-in-out infinite;
}
/* a finger-friendly take area around the (slightly rotated) top tile */
.pile.can-take .pile-anchor::after { content: ''; position: absolute; left: -6px; top: -6px; right: -6px; bottom: -6px; }
.pile.can-take .pile-cap { color: var(--gold); }
.pile.can-drop .pile-slot { border-color: rgba(61, 220, 151, 0.55); background: rgba(61, 220, 151, 0.07); }
.pile.can-drop .pile-cap { color: #9ff3cc; }
.pile.can-drop { cursor: pointer; }
/* While a rack tile is dragged the discard slot lights up (green, or red for a penalised discard).
   Both looks are pre-painted on pseudo-elements and switched by opacity only (no box-shadow
   transition: that repainted the table under the slot on every frame of the lift and the drop):
   ::before — the bright dashed border, ring and halo over the slot's own border;
   ::after  — the slot's inner shade, which the highlight hides (as before). */
.pile-slot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 8px;
  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.3);
  pointer-events: none;
  transition: opacity 0.2s;
}
.pile-slot::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  border: 2px dashed #3ddc97;
  box-shadow: 0 0 0 3px rgba(61, 220, 151, 0.35), 0 0 26px rgba(61, 220, 151, 0.6);
  pointer-events: none;
  opacity: 0;
  /* (leaving a state: the colours change back only after the fade-out) */
  transition: opacity 0.2s, border-color 0s 0.2s, box-shadow 0s 0.2s;
}
.pile.is-drop-ok .pile-slot::before,
.pile.is-drop-warn .pile-slot::before { opacity: 1; transition: opacity 0.2s; }
.pile.is-drop-warn .pile-slot::before { border-color: #ff6b66; box-shadow: 0 0 0 3px rgba(239, 83, 80, 0.35), 0 0 26px rgba(239, 83, 80, 0.6); }
.pile.is-drop-ok .pile-slot::after,
.pile.is-drop-warn .pile-slot::after { opacity: 0; }
.pile.is-drop-hover .pile-slot { transform: scale(1.06); background: rgba(255, 255, 255, 0.08); }
.pile-warn {
  position: absolute;
  left: 50%;
  top: -22px;
  transform: translateX(-50%);
  padding: 2px 8px;
  border-radius: 8px;
  background: #d8343b;
  color: #fff;
  font: 800 12px/16px var(--font-num);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
  z-index: 4;
}
.pile.is-drop-warn .pile-warn { opacity: 1; }

.hub {
  position: absolute;
  left: 628px;
  top: 546px;
  width: 344px;
  height: 118px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 30px;
  z-index: 6;
}
.hub-item { position: relative; display: flex; flex-direction: column; align-items: center; }
.hub-cap {
  margin-top: 8px;
  font: 800 12px var(--font-display);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  white-space: nowrap;
}
.hub-n { display: none; } /* the deck count in its caption: phones only (section 18) */
.deck { position: relative; width: 64px; height: 88px; touch-action: none; }
.deck-back {
  position: absolute;
  left: 0;
  top: 0;
  width: 58px;
  height: 81px;
  border-radius: 8px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.35);
}
.deck-back > svg { width: 100%; height: 100%; }
.deck-back:nth-child(1) { transform: translate(6px, 7px); }
.deck-back:nth-child(2) { transform: translate(4px, 4.5px); }
.deck-back:nth-child(3) { transform: translate(2px, 2px); }
.deck-top { transition: transform 0.2s var(--ease-out), box-shadow 0.2s; }
/* (the deck you may draw from: a gold ring — the static low point of the pulse — and a brighter ring +
   halo on ::after breathing by opacity only, never a per-frame repaint of the table) */
.deck.can-draw .deck-top {
  box-shadow: 0 0 0 2px rgba(244, 201, 93, 0.55), 0 0 10px rgba(244, 201, 93, 0.3), 0 2px 3px rgba(0, 0, 0, 0.35);
  transition: transform 0.2s var(--ease-out);
}
.deck.can-draw .deck-top::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 0 3px rgba(244, 201, 93, 0.89), 0 0 26px rgba(244, 201, 93, 0.6);
  animation: glowPulse 1.6s ease-in-out infinite;
}
.deck.is-low .deck-back:nth-child(1), .deck.is-low .deck-back:nth-child(2) { display: none; }
.deck.is-empty .deck-back { display: none; }
.deck.is-empty::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 58px;
  height: 81px;
  border-radius: 9px;
  border: 2px dashed rgba(255, 255, 255, 0.2);
}
.deck-count {
  position: absolute;
  right: -14px;
  top: -10px;
  min-width: 30px;
  height: 24px;
  padding: 0 7px;
  border-radius: 12px;
  background: linear-gradient(180deg, #ffe596, #e3a53a);
  color: #3d2400;
  font: 800 14px/24px var(--font-num);
  text-align: center;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.45);
  z-index: 5;
}
.deck.is-low .deck-count { background: linear-gradient(180deg, #ff9d94, #d8343b); color: #fff; }
.deck.can-draw { cursor: grab; }
.deck.can-draw:hover .deck-top { transform: translateY(-5px); }
.deck.is-lifted .deck-top { visibility: hidden; }

/* the gösterge alone (no okey preview); the bottom margin (= the deck's stacked backs, 88 − 81)
   puts its caption on the "DESTE" line */
.ind-tile {
  width: 58px;
  height: 81px;
  margin-bottom: 7px;
  border-radius: 8px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);
}
.ind-tile > svg { width: 100%; height: 100%; }
.ind-tile.is-hidden { visibility: hidden; }
/* (backwards, not both: a finished entry animation must not keep the tile composited — ui.js also
   removes the class when it ends) */
.ind-tile.flip-in { animation: flipIn 0.7s var(--ease-out) backwards; }

/* ======================================================================================
   9. Table melds
   ====================================================================================== */
.melds-area {
  position: absolute;
  left: 184px;
  top: 204px;
  width: 1232px;
  height: 334px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  z-index: 5;
  --ms: 1;
}
.melds-inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  align-items: flex-start;
  gap: calc(10px * var(--ms)) calc(16px * var(--ms));
  max-width: 100%;
  padding: 4px;
}
.meld-group {
  display: flex;
  flex-direction: column;
  gap: calc(5px * var(--ms));
  max-width: 100%;
  padding: calc(7px * var(--ms)) calc(10px * var(--ms)) calc(9px * var(--ms));
  border-radius: calc(14px * var(--ms));
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.12));
  border: 1px solid rgba(255, 255, 255, 0.07);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  animation: groupIn 0.45s var(--ease-out) backwards;
}
.mg-head {
  display: flex;
  align-items: center;
  gap: 6px;
  height: calc(22px * var(--ms));
  font: 700 calc(14px * var(--ms)) / 1 var(--font-display);
  color: rgba(255, 255, 255, 0.86);
  white-space: nowrap;
}
.mg-av {
  width: calc(22px * var(--ms));
  height: calc(22px * var(--ms));
  border-radius: 50%;
  overflow: hidden;
  flex: none;
  box-shadow: 0 0 0 1.5px var(--seat-c, var(--gold));
  background: #16343a;
}
.mg-av > svg { width: 100%; height: 100%; }
.mg-tag {
  padding: 0 calc(7px * var(--ms));
  height: calc(18px * var(--ms));
  line-height: calc(18px * var(--ms));
  border-radius: 9px;
  font: 800 calc(11px * var(--ms)) / calc(18px * var(--ms)) var(--font-body);
  background: rgba(61, 220, 151, 0.2);
  color: #9ff3cc;
}
.mg-tag.t-pairs { background: rgba(90, 174, 255, 0.2); color: #b8dcff; }
.mg-melds {
  display: flex;
  flex-wrap: wrap;
  gap: calc(8px * var(--ms)) calc(12px * var(--ms));
}
.meld {
  position: relative;
  display: flex;
  gap: calc(2px * var(--ms));
  padding: calc(3px * var(--ms));
  border-radius: calc(9px * var(--ms));
  transition: box-shadow 0.18s ease, background 0.18s ease, transform 0.18s var(--ease-out);
}
.meld-pair { background: rgba(90, 174, 255, 0.06); }
.meld-tile {
  position: relative;
  width: calc(34px * var(--ms));
  height: calc(48px * var(--ms));
  border-radius: calc(5px * var(--ms));
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.35);
}
.meld-tile > svg { width: 100%; height: 100%; }
.meld-tile.is-hidden { visibility: hidden; }
.meld.can-accept { box-shadow: 0 0 0 2px rgba(61, 220, 151, 0.55); background: rgba(61, 220, 151, 0.08); cursor: pointer; }
.meld.can-swap .meld-tile.is-wild { box-shadow: 0 0 0 2px #ffd766, 0 0 12px rgba(255, 215, 102, 0.7); }
.meld.is-target { box-shadow: 0 0 0 3px #3ddc97, 0 0 24px rgba(61, 220, 151, 0.75); background: rgba(61, 220, 151, 0.16); transform: scale(1.04); }
.meld.is-reject { box-shadow: 0 0 0 2px rgba(239, 83, 80, 0.75); background: rgba(239, 83, 80, 0.08); }
.meld.is-bump { animation: meldBump 0.5s var(--ease-spring); }
/* Face-down okeys can be long-pressed to peek */
.meld-tile.is-wild { cursor: help; touch-action: none; }
.meld-tile.is-flip, .rack-tile.is-flip .rack-tile-face { animation: tileFlip 0.3s ease-in-out; }
/* Provisional table moves (until the discard commits the turn): dashed + lighter */
.meld.is-prov { outline: 1.5px dashed rgba(255, 223, 130, 0.9); outline-offset: 1px; background: rgba(255, 215, 102, 0.07); }
.meld.is-prov .meld-tile, .meld-tile.is-prov { opacity: 0.84; filter: saturate(0.85) brightness(1.04); }
.meld-tile.is-prov { outline: 1.5px dashed rgba(255, 223, 130, 0.95); outline-offset: 1px; }
.meld-group.is-prov { border: 1px dashed rgba(255, 215, 102, 0.7); background: linear-gradient(180deg, rgba(255, 215, 102, 0.08), rgba(0, 0, 0, 0.12)); }
.mg-tag.t-prov { background: rgba(255, 215, 102, 0.16); color: #ffe7a6; box-shadow: inset 0 0 0 1px rgba(255, 215, 102, 0.55); }
.mg-tag.t-prov.t-bad { background: rgba(239, 83, 80, 0.22); color: #ffc7c2; box-shadow: inset 0 0 0 1px rgba(255, 120, 110, 0.7); }
/* Pair rows accepting a dragged rack pair ("Çift İşle") */
.meld-group { transition: box-shadow 0.18s ease, background 0.18s ease; }
.meld-group.can-accept-pair { box-shadow: 0 0 0 2px rgba(90, 174, 255, 0.6), 0 0 16px rgba(90, 174, 255, 0.3); }
.meld-group.is-row-target { box-shadow: 0 0 0 3px #5aaeff, 0 0 26px rgba(90, 174, 255, 0.75); background: rgba(90, 174, 255, 0.14); }
.meld-group.is-row-reject { box-shadow: 0 0 0 2px rgba(239, 83, 80, 0.75); }

/* ======================================================================================
   10. Rack (ıstaka)
   ====================================================================================== */
.rack-host {
  position: absolute;
  left: 278px;
  top: 668px;
  width: 1045px;
  height: 228px;
  /* above .ctl / .ph-hub / .topbar: the rack's tiles are compositor layers, and anything painted
     after them that overlaps them would be pulled into extra (big) layers */
  z-index: 30;
}
.rack { position: relative; width: 100%; height: 100%; }
.rack-shadow {
  position: absolute;
  left: 30px;
  right: 30px;
  bottom: -10px;
  height: 46px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  filter: blur(16px);
}
.rack-body {
  position: absolute;
  inset: 0;
  border-radius: 20px 20px 16px 16px;
  overflow: hidden;
  background: var(--tex-wood, linear-gradient(180deg, #8a5630 0%, #6a3d1f 50%, #4a2812 100%));
  box-shadow:
    inset 0 2px 1px rgba(255, 230, 180, 0.35),
    inset 0 -2px 2px rgba(0, 0, 0, 0.45),
    inset 0 0 0 1px rgba(30, 14, 4, 0.7),
    0 18px 30px rgba(0, 0, 0, 0.5);
}
.rack-body::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(255, 225, 170, 0.2) 0%, rgba(255, 225, 170, 0) 12%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.22) 100%),
    linear-gradient(90deg, rgba(0, 0, 0, 0.25) 0%, transparent 5%, transparent 95%, rgba(0, 0, 0, 0.25) 100%);
}
.rack-ledge {
  position: absolute;
  left: 8px;
  right: 8px;
  height: 24px;
  border-radius: 3px 3px 9px 9px;
  background: var(--tex-wood-dark, linear-gradient(180deg, #5b3419 0%, #3e2210 60%, #2b170a 100%));
  box-shadow:
    inset 0 5px 0 rgba(255, 228, 180, 0.16),
    inset 0 -2px 3px rgba(0, 0, 0, 0.5),
    0 5px 8px rgba(0, 0, 0, 0.45);
}
.rack-ledge::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 4px;
  border-radius: 3px 3px 0 0;
  background: var(--tex-brass, linear-gradient(90deg, #7d5a1c, #f1d17c 30%, #a57a2a 55%, #f6dc93 80%, #7d5a1c));
  opacity: 0.95;
}
.rack-ledge::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 40%;
  border-radius: 0 0 9px 9px;
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.35));
}
.rack-ledge-front { left: 0; right: 0; height: 26px; border-radius: 3px 3px 16px 16px; }
.rack-cap {
  position: absolute;
  top: 10px;
  bottom: 10px;
  width: 8px;
  border-radius: 4px;
  background: var(--tex-brass, linear-gradient(180deg, #f6dc93, #a57a2a 50%, #7d5a1c));
  box-shadow: 0 0 0 1px rgba(40, 20, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  opacity: 0.9;
}
.rack-cap-l { left: 5px; }
.rack-cap-r { right: 5px; }
.rack-slots, .rack-glows, .rack-tiles, .rack-badges { position: absolute; inset: 0; }
/* the group frames and the drop marker change by opacity only: their own layers */
.rack-glows, .rack-drop { will-change: opacity; }
/* Tile size: --rk-tw / --rk-th come from the rack geometry in ui.js (desktop 60×84, phone smaller) */
.rack-slot {
  position: absolute;
  width: var(--rk-tw, 60px);
  height: var(--rk-th, 84px);
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.16), rgba(0, 0, 0, 0.06));
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.28), inset 0 -1px 0 rgba(255, 220, 170, 0.06);
}
.rack-slot.is-hint { background: rgba(255, 215, 102, 0.12); box-shadow: inset 0 0 0 2px rgba(255, 215, 102, 0.5); }
.rack-glow {
  position: absolute;
  border-radius: 12px;
  pointer-events: none;
  transition: opacity 0.2s ease;
  animation: glowIn 0.35s var(--ease-out) backwards;
}
.glow-meld { background: rgba(80, 240, 170, 0.14); box-shadow: 0 0 0 2px rgba(90, 245, 175, 0.95), 0 0 18px 3px rgba(80, 240, 170, 0.5); }
.glow-pair { background: rgba(120, 190, 255, 0.13); box-shadow: 0 0 0 2px rgba(130, 195, 255, 0.95), 0 0 18px 3px rgba(110, 180, 255, 0.45); }
.rack-badge {
  position: absolute;
  transform: translateX(-50%);
  height: 18px;
  padding: 0 9px;
  border-radius: 9px;
  font: 800 12px/18px var(--font-num);
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.45);
  animation: badgePop 0.35s var(--ease-spring) backwards;
  z-index: 3;
}
.badge-meld { background: linear-gradient(180deg, #a6ffd6, #34d693); color: #04301d; }
.badge-pair { background: linear-gradient(180deg, #c6e3ff, #5aaeff); color: #042242; }
/* (the frames and badges stay visible while a tile is dragged, as they always looked: the old
   "hide while dragging" rule never applied — the filled entry animation pinned their opacity) */
.rack-drop {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--rk-tw, 60px);
  height: var(--rk-th, 84px);
  border-radius: 9px;
  box-shadow: 0 0 0 3px #ffd766, 0 0 20px rgba(255, 215, 102, 0.7);
  background: rgba(255, 215, 102, 0.1);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.rack-drop.is-on { opacity: 1; }

.rack-tile {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--rk-tw, 60px);
  height: var(--rk-th, 84px);
  cursor: grab;
  touch-action: none;
  transition: transform 0.26s var(--ease-out);
  z-index: 1;
  /* every tile is its own compositor layer (22 × ≈ 0.1 MB): sliding tiles never re-raster the table.
     (opacity, not transform: a will-change: transform layer keeps the raster scale it was first drawn
     at and is drawn at whole device pixels — a tile that arrived during a move stayed slightly soft;
     the slide itself still runs on the compositor) */
  will-change: opacity;
}
.rack-tiles.no-anim .rack-tile { transition: none; }
.rack-tile-in {
  position: absolute;
  inset: 0;
  transition: transform 0.16s var(--ease-out);
}
.rack-tile-face {
  position: absolute;
  inset: 0;
  border-radius: 8px;
  box-shadow: 0 3px 4px rgba(0, 0, 0, 0.38), 0 1px 1px rgba(0, 0, 0, 0.3);
  transition: box-shadow 0.18s ease;
}
.rack-tile-face > svg { width: 100%; height: 100%; }
.rack-tile:hover .rack-tile-in { transform: translateY(-5px); }
/* (a mouse only: on a touch screen the tapped tile stayed :hover and kept this shadow) */
@media (hover: hover) {
  .rack-tile:hover .rack-tile-face { box-shadow: 0 8px 12px rgba(0, 0, 0, 0.42); }
}
.rack-tile.is-sel { z-index: 3; }
.rack-tile.is-sel .rack-tile-in { transform: translateY(-15px); }
.rack-tile.is-sel .rack-tile-face { box-shadow: 0 0 0 3px #ffd766, 0 0 18px rgba(255, 215, 102, 0.65), 0 12px 16px rgba(0, 0, 0, 0.45); }
/* the side tile taken this turn: an amber ring (the static low point of the pulse) and a brighter
   ring + halo on ::after breathing by opacity only */
.rack-tiles .rack-tile.is-taken .rack-tile-face {
  box-shadow: 0 0 0 3px rgba(255, 181, 71, 0.8), 0 0 10px rgba(255, 181, 71, 0.4), 0 3px 4px rgba(0, 0, 0, 0.38);
  transition: none;
}
.rack-tiles .rack-tile.is-taken .rack-tile-face::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 0 3px #ffd766, 0 0 24px rgba(255, 181, 71, 0.75);
  animation: glowPulse 1.3s ease-in-out infinite;
}
.rack-tile.is-fresh .rack-tile-face { box-shadow: 0 0 0 2px #8fe6ff, 0 0 16px rgba(143, 230, 255, 0.75), 0 3px 4px rgba(0, 0, 0, 0.38); }
.rack-tile.is-dragging { visibility: hidden; }
.rack-tile.is-incoming { visibility: hidden; }
.rack-tile.is-dealing .rack-tile-in { opacity: 0; }
.rack-tile.deal-in .rack-tile-in { animation: dealIn 0.42s var(--ease-spring) both; }
.rack-tile-mark {
  position: absolute;
  right: -4px;
  top: -5px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  display: none;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, #7dffc4, #1db679);
  color: #03301c;
  font: 900 14px/1 var(--font-num);
  box-shadow: 0 0 0 2px #0b2d22, 0 2px 4px rgba(0, 0, 0, 0.45);
  pointer-events: none;
  z-index: 2;
}
.rack-tile-mark::before { content: '+'; }
.rack-tile.is-islek .rack-tile-mark { display: flex; }
/* This tile can take a table okey (assist): gold marker with the okey gem's lozenge (drawn, not a
   font glyph; motif rule in js/ui/art.js: no stars) */
.rack-tile.is-swap .rack-tile-mark {
  display: flex;
  background: linear-gradient(180deg, #fff1b0, #e0a02a);
  color: #4a2a00;
  font-size: 11px;
  box-shadow: 0 0 0 2px #4a2a00, 0 0 8px rgba(255, 215, 102, 0.7), 0 2px 4px rgba(0, 0, 0, 0.45);
}
.rack-tile.is-swap .rack-tile-mark::before {
  content: '';
  width: 7px;
  height: 10px;
  background: currentColor;
  -webkit-clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
/* A diver's kept side tile (rulebook §6.3): "alındı" tag, must go down as a pair */
.rack-tile-tag {
  position: absolute;
  left: -5px;
  top: -7px;
  display: none;
  height: 15px;
  padding: 0 5px;
  border-radius: 8px;
  background: linear-gradient(180deg, #9dd0ff, #2f7fd6);
  color: #fff;
  font: 800 10px/15px var(--font-body);
  letter-spacing: 0.02em;
  white-space: nowrap;
  text-shadow: 0 1px 0 rgba(0, 30, 80, 0.5);
  box-shadow: 0 0 0 1.5px #0b2440, 0 2px 4px rgba(0, 0, 0, 0.45);
  pointer-events: none;
  z-index: 2;
}
.rack-tile.is-kept .rack-tile-tag { display: block; }
.rack-tile.is-kept .rack-tile-face { box-shadow: 0 0 0 2px rgba(138, 198, 255, 0.9), 0 0 12px rgba(110, 180, 255, 0.5), 0 3px 4px rgba(0, 0, 0, 0.38); }
/* Partner of a dragged pair ("Çift İşle" by drag) */
.rack-tile.is-partner .rack-tile-in { transform: translateY(-8px); }
.rack-tile.is-partner .rack-tile-face { box-shadow: 0 0 0 3px #8ac6ff, 0 0 18px rgba(110, 180, 255, 0.75), 0 8px 12px rgba(0, 0, 0, 0.42); }

/* ======================================================================================
   11. Controls around the rack
   ====================================================================================== */
.ctl { position: absolute; z-index: 15; display: flex; flex-direction: column; }
.ctl-left { left: 12px; top: 788px; width: 256px; gap: 5px; }
.ctl-sort { display: flex; gap: 8px; }
.ctl-sort .btn { flex: 1; height: 42px; font-size: 18px; padding: 0 10px; }
/* Info box (up to three lines): açış vs barrier (assist: red below the barrier), çift / hand value
   or a diver's kept tiles, and the status line (hatalı açılış · baraj ödülü hint). */
.ctl-info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
  height: 62px;
  padding: 0 10px;
  border-radius: 12px;
  background: var(--glass);
  border: 1px solid var(--gold-hair);
  font: 700 13.5px/1.2 var(--font-body);
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
}
.ci-row { display: flex; align-items: center; justify-content: center; gap: 5px; min-height: 18px; overflow: hidden; }
.ci-row.is-hidden { display: none; }
.ci-lbl { color: var(--ink-mute); }
.ctl-info b { font: 800 15px var(--font-num); color: #fff; }
/* Status line: hatalı açılış (D5) in red, "düzeldi" in green, baraj ödülü hint in gold */
.ci-status {
  display: block;
  max-width: 100%;
  height: 18px;
  /* 7px padding and no extra tracking: the longest default lines ("150+ puan / 7+ çift açarsan
     ödül −101", "Hatalı açılış · geçerli açmazsan +101") fit the 234px info box without an ellipsis. */
  padding: 0 7px;
  border-radius: 9px;
  font: 800 12px/18px var(--font-body);
  letter-spacing: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ci-status.is-bad { background: rgba(239, 83, 80, 0.32); color: #ffe0dc; box-shadow: inset 0 0 0 1px rgba(255, 120, 110, 0.6); }
.ci-status.is-ok { background: rgba(61, 220, 151, 0.18); color: #9ff3cc; }
.ci-status.is-bonus { background: rgba(244, 201, 93, 0.13); color: #f6e3b0; }
.ci-status.is-earned { background: rgba(61, 220, 151, 0.2); color: #9ff3cc; }
.ci-row-3.is-alert .ci-status { animation: statusPulse 1.8s ease-in-out infinite; }
/* Çifte dalma (D2): kept side tiles that must go down as pairs */
.ci-kept { font: 800 12px/18px var(--font-body); color: #ffc7c2; white-space: nowrap; }
.ci-mini { display: inline-block; flex: none; width: 13px; height: 18px; border-radius: 2px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.45); }
.ci-mini > svg { display: block; width: 100%; height: 100%; }
.ci-mini + .ci-mini { margin-left: -3px; }
.ci-tag.is-kept { background: rgba(90, 174, 255, 0.22); color: #cfe6ff; }
.ctl-info b.ci-ok { color: var(--green); }
.ctl-info b.ci-bad { color: #ff7d77; }
.ci-tag { height: 17px; padding: 0 7px; border-radius: 9px; font: 800 11px/17px var(--font-body); letter-spacing: 0.02em; white-space: nowrap; flex: none; }
.ci-tag.is-bad { background: rgba(239, 83, 80, 0.26); color: #ffc7c2; }
.ci-tag.is-ok { background: rgba(61, 220, 151, 0.2); color: #9ff3cc; }
.ci-sep { width: 1px; height: 14px; margin: 0 5px; background: var(--gold-hair); }

/* Right column: hint · Aç · Çift Aç/İşle · 2-column grid (İşle, Geri Topla, Geri Bırak, Çifte Dal).
   Fits 664 → 892 with every button visible. */
.ctl-right { left: 1336px; top: 664px; width: 252px; gap: 7px; }
.ctl-hint {
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 12px;
  border-radius: 12px;
  background: var(--glass);
  border: 1px solid var(--gold-hair);
  font: 700 14px var(--font-body);
  color: var(--ink-dim);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.ctl-right .ctl-hint { font-size: 13.5px; }
.ctl-hint.is-mine { color: #fff3c8; border-color: var(--gold-hair-strong); background: linear-gradient(180deg, rgba(244, 201, 93, 0.16), rgba(244, 201, 93, 0.06)); }
.ctl-hint.is-warn { color: #ffd1cc; border-color: rgba(239, 83, 80, 0.6); background: rgba(239, 83, 80, 0.14); }
.ctl-right .btn { width: 100%; }
.btn-open { height: 52px; font-size: 23px; }
.btn-pairs { height: 42px; font-size: 19px; }
.ctl-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.ctl-grid.is-empty { display: none; }
.btn-sm { height: 38px; font-size: 16px; padding: 0 8px; gap: 5px; border-radius: 12px; }
.btn-sm .btn-ic { width: 17px; height: 17px; }
.btn-sm .btn-num { min-width: 24px; height: 20px; padding: 0 6px; border-radius: 10px; font-size: 13px; line-height: 20px; }
.btn-sm.is-wide { grid-column: 1 / -1; }
.btn-sm::after { border-radius: 11px 11px 40% 40% / 11px 11px 10px 10px; }
/* "Aç" below the barrier (assist): allowed, but the number turns red */
.btn.is-below .btn-num { background: linear-gradient(180deg, #ff8a80, #d8343b); color: #fff; box-shadow: 0 0 10px rgba(239, 83, 80, 0.6); }
.btn-dive { animation: diveGlow 2.2s ease-in-out infinite; }
.btn-num {
  min-width: 34px;
  height: 26px;
  padding: 0 8px;
  border-radius: 13px;
  font: 800 16px/26px var(--font-num);
  background: rgba(0, 0, 0, 0.22);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
}
.btn-gold .btn-num { background: rgba(80, 40, 0, 0.18); }
/* Aç / Çift Aç when an opening is ready: the gold button's own shadows (as before, also on a blue
   button) and a warm halo on ::before (.btn::after is the gloss) breathing by opacity only */
.btn.is-ready {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), inset 0 -3px 0 rgba(120, 60, 0, 0.35), 0 6px 16px rgba(0, 0, 0, 0.38), 0 0 0 1px rgba(120, 70, 0, 0.35);
  transition: transform 0.14s var(--ease-out), filter 0.18s, opacity 0.25s;
}
.btn.is-ready::before {
  content: '';
  position: absolute;
  inset: 0;
  /* under the button and its own drop shadow (the halo was the outermost shadow of the button):
     painted at the bottom of the controls column (.ctl is the stacking context) */
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 26px 4px rgba(255, 210, 100, 0.65);
  animation: glowPulse 1.5s ease-in-out infinite;
}
/* Attention pulse (e.g. "Geri Bırak" after a side-tile discard refusal, D5) */
.btn.is-pulse { z-index: 2; animation: btnPulse 0.95s ease-in-out 6; }

/* ======================================================================================
   12. Banner, log panel
   ====================================================================================== */
.banner-host { position: absolute; left: 0; top: 0; width: 1600px; height: 900px; pointer-events: none; z-index: 40; }
.banner {
  position: absolute;
  left: 50%;
  top: 372px;
  transform: translate(-50%, -50%);
  text-align: center;
  white-space: nowrap;
  animation: bannerIn 1.8s var(--ease-out) forwards;
}
.banner::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 760px;
  height: 150px;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(5, 16, 19, 0.75), rgba(5, 16, 19, 0));
  z-index: -1;
}
.banner-main {
  font: 800 70px/1 var(--font-display);
  background: linear-gradient(180deg, #fff8dc 0%, #ffd46b 50%, #d3901f 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 4px 0 rgba(70, 40, 0, 0.8)) drop-shadow(0 12px 22px rgba(0, 0, 0, 0.55));
}
.banner-sub {
  margin-top: 8px;
  font: 800 22px var(--font-body);
  color: #fff;
  letter-spacing: 0.02em;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.8);
}
.banner.is-compact { top: 506px; animation-duration: 1.25s; }
.banner.is-compact::before { width: 420px; height: 90px; }
.banner.is-compact .banner-main { font-size: 42px; }
.banner.is-bad .banner-main { background: linear-gradient(180deg, #ffe4e0 0%, #ff7b73 50%, #c7262e 100%); -webkit-background-clip: text; background-clip: text; }
.banner.is-good .banner-main { background: linear-gradient(180deg, #eafff5 0%, #6ff0b5 50%, #13a06b 100%); -webkit-background-clip: text; background-clip: text; }

.log-panel {
  position: absolute;
  left: 1226px;
  top: 66px;
  width: 362px;
  height: 480px;
  z-index: 64; /* above the fx layer (60): a flying tile never draws over the open drawer */
  display: flex;
  flex-direction: column;
  border-radius: 18px;
  background: var(--glass-strong);
  border: 1px solid var(--gold-hair);
  box-shadow: var(--shadow-lg);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transform: translateX(400px);
  opacity: 0;
  visibility: hidden;
  transition: transform 0.35s var(--ease-out), opacity 0.3s, visibility 0.35s;
}
.log-panel.is-open { transform: none; opacity: 1; visibility: visible; }
.log-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 12px 10px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  font: 800 20px var(--font-display);
  color: var(--gold);
}
.log-head .icon-btn { margin-left: auto; width: 34px; height: 34px; }
.log-head .icon-btn svg { width: 18px; height: 18px; }
.log-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px 10px 12px;
  touch-action: pan-y;
  scrollbar-width: thin;
  scrollbar-color: rgba(244, 201, 93, 0.4) transparent;
}
.log-item {
  position: relative;
  padding: 5px 8px 5px 12px;
  margin: 2px 0;
  border-left: 3px solid var(--c, rgba(255, 255, 255, 0.2));
  border-radius: 3px 8px 8px 3px;
  font: 600 14px/1.35 var(--font-body);
  color: var(--ink-dim);
  background: rgba(255, 255, 255, 0.025);
  animation: fadeIn 0.3s ease backwards;
}
/* (added while the log panel is closed: nobody sees it arrive) */
.log-item.is-quiet { animation: none; }
.log-item.k-penalty { color: #ffc7c2; background: rgba(239, 83, 80, 0.1); }
.log-item.k-open, .log-item.k-lay { color: #c5f7df; }
.log-item.k-finish, .log-item.k-round, .log-item.k-roundEnd { color: #fff0c2; background: rgba(244, 201, 93, 0.08); }
.log-item.k-bonus, .log-item.k-openBonus, .log-item.k-openConfirm, .log-item.k-confirm { color: #b5f5d6; background: rgba(61, 220, 151, 0.08); }
.log-item.k-dive { color: #ffd7ae; background: rgba(255, 150, 60, 0.1); }
.log-item.k-undo, .log-item.k-return { color: #d9e6ff; }
.log-item.k-wrongOpen, .log-item.k-wrong, .log-item.k-feed, .log-item.k-feedFinish, .log-item.k-okeyTaken { color: #ffc7c2; background: rgba(239, 83, 80, 0.1); }
.log-sep {
  margin: 10px 0 6px;
  text-align: center;
  font: 800 13px var(--font-display);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
}
.log-empty { padding: 30px 10px; text-align: center; color: var(--ink-mute); font: 600 14px var(--font-body); }

/* ======================================================================================
   13. Drag ghost & flying tiles
   ====================================================================================== */
.drag-ghost {
  position: absolute;
  left: 0;
  top: 0;
  width: 60px;
  height: 84px;
  pointer-events: none;
  transform-origin: 50% 50%;
  will-change: transform;
  z-index: 5;
}
.drag-ghost .g-face {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  box-shadow: 0 20px 30px rgba(0, 0, 0, 0.5), 0 6px 10px rgba(0, 0, 0, 0.35);
}
.drag-ghost .g-face > svg { width: 100%; height: 100%; }
.drag-ghost.is-warn .g-face { box-shadow: 0 0 0 3px rgba(239, 83, 80, 0.9), 0 20px 30px rgba(0, 0, 0, 0.5); }
.drag-ghost.is-ok .g-face { box-shadow: 0 0 0 3px rgba(61, 220, 151, 0.9), 0 20px 30px rgba(0, 0, 0, 0.5); }

.fly {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
  pointer-events: none;
  will-change: transform, opacity;
  z-index: 3;
}
.fly > svg { width: 100%; height: 100%; }
.fly-tile { border-radius: 8px; box-shadow: 0 12px 20px rgba(0, 0, 0, 0.45); }
.fly-back { border-radius: 6px; box-shadow: 0 8px 14px rgba(0, 0, 0, 0.4); }

/* ======================================================================================
   14. Modals
   ====================================================================================== */
.modal-wrap {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(80% 80% at 50% 50%, rgba(3, 10, 12, 0.55), rgba(3, 10, 12, 0.78));
  pointer-events: auto;
  animation: fadeIn 0.2s ease backwards;
}
.modal-wrap.is-closing { animation: fadeOut 0.2s ease forwards; pointer-events: none; }
.modal-wrap.is-closing .modal { animation: modalOut 0.2s ease forwards; }
.modal {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 620px;
  max-width: 1480px;
  max-height: 840px;
  border-radius: 24px;
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(244, 201, 93, 0.09), transparent 60%),
    linear-gradient(180deg, rgba(20, 42, 48, 0.98), rgba(9, 22, 27, 0.98));
  border: 1px solid var(--gold-hair);
  box-shadow: 0 34px 90px rgba(0, 0, 0, 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  animation: modalIn 0.34s var(--ease-spring) backwards;
  /* one compositor layer while open, as it always was (its filled entry animation kept it one): the
     same whole-pixel placement of its content, and what changes inside it never re-rasters the table */
  will-change: transform;
}
.stage.rs .modal { will-change: auto; } /* (a scale change: re-rastered sharp, ui.js refreshArt) */
.modal::before {
  /* gold hairline highlight along the top */
  content: '';
  position: absolute;
  left: 40px;
  right: 40px;
  top: -1px;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(255, 220, 140, 0.9), transparent);
  pointer-events: none;
}
.modal-sm { width: 540px; }
.modal-md { width: 800px; }
.modal-lg { width: 1040px; }
.modal-xl { width: 1260px; }
.modal-head { display: flex; align-items: center; gap: 12px; padding: 22px 24px 10px 28px; }
.modal-ic { width: 32px; height: 32px; color: var(--gold); flex: none; }
.modal-ic svg { width: 100%; height: 100%; }
.modal-ic:empty { display: none; }
.modal-title { margin: 0; font: 800 32px/1.1 var(--font-display); color: #ffe8a8; text-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); }
.modal-x { margin-left: auto; }
.modal-body {
  padding: 8px 28px 18px;
  overflow-y: auto;
  font: 600 17px/1.55 var(--font-body);
  color: var(--ink);
  touch-action: pan-y;
  user-select: text;
  -webkit-user-select: text;
  scrollbar-width: thin;
  scrollbar-color: rgba(244, 201, 93, 0.45) transparent;
}
.modal-body::-webkit-scrollbar, .log-list::-webkit-scrollbar { width: 8px; }
.modal-body::-webkit-scrollbar-thumb, .log-list::-webkit-scrollbar-thumb { background: rgba(244, 201, 93, 0.35); border-radius: 4px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 12px; padding: 12px 28px 24px; }
.modal-foot .btn { min-width: 150px; }
.modal-foot.is-center { justify-content: center; }
.modal-msg { font: 600 19px/1.55 var(--font-body); color: var(--ink); }
.modal-msg b { color: var(--gold); }
.modal-msg .em-bad { color: #ff8f8c; }

.confirm-tile { display: flex; justify-content: center; margin: 4px 0 16px; }
.confirm-tile .ct-tile { width: 70px; height: 98px; border-radius: 9px; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.45); }
.confirm-tile .ct-tile > svg { width: 100%; height: 100%; }
.confirm-reasons { margin: 10px 0 0; padding: 0; list-style: none; }
.confirm-reasons li { position: relative; padding-left: 22px; margin: 4px 0; color: #ffcdc8; font-weight: 700; }
.confirm-reasons li::before { content: ''; position: absolute; left: 4px; top: 10px; width: 8px; height: 8px; border-radius: 50%; background: var(--red); }
.modal-danger .modal-title { color: #ffb4ad; }
.modal-danger .modal-ic { color: #ff8078; }
.confirm-tip { margin-top: 12px; padding: 8px 12px; border-radius: 10px; background: rgba(244, 201, 93, 0.08); border: 1px solid var(--gold-hair); font: 700 15px/1.45 var(--font-body); color: #f6e3b0; }
.confirm-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; }
.confirm-list li { position: relative; padding-left: 22px; font: 600 17px/1.45 var(--font-body); }
.confirm-list li::before { content: ''; position: absolute; left: 5px; top: 10px; width: 8px; height: 8px; border-radius: 50%; background: var(--gold); }

/* Settings ---------------------------------------------------------------------------- */
.set-grid { display: grid; grid-template-columns: 300px 1fr; gap: 26px; }
.set-col { display: flex; flex-direction: column; gap: 14px; }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 44px; }
.set-row-col { flex-direction: column; align-items: stretch; gap: 8px; }
.set-lbl { font: 800 17px/1.2 var(--font-display); color: #fff; }
.set-lbl small { display: block; font: 600 13px/1.3 var(--font-body); color: var(--ink-mute); margin-top: 2px; }
.set-input {
  height: 46px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid var(--gold-hair);
  background: rgba(0, 0, 0, 0.3);
  color: #fff;
  font: 700 19px var(--font-body);
  outline: none;
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.set-input:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(244, 201, 93, 0.2); }
.av-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.av-opt {
  position: relative;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 0;
  padding: 0;
  overflow: hidden;
  cursor: pointer;
  background: #16343a;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.12), 0 4px 10px rgba(0, 0, 0, 0.35);
  transition: transform 0.15s var(--ease-out), box-shadow 0.2s;
}
.av-opt > svg { width: 100%; height: 100%; }
.av-opt:hover { transform: translateY(-2px) scale(1.04); }
.av-opt.is-on { box-shadow: 0 0 0 3px var(--gold), 0 0 18px rgba(244, 201, 93, 0.55); }
.seg {
  display: inline-flex;
  padding: 4px;
  gap: 4px;
  border-radius: 13px;
  background: rgba(0, 0, 0, 0.32);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.seg-btn {
  min-width: 48px;
  height: 36px;
  padding: 0 12px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  font: 700 16px var(--font-display);
  color: var(--ink-dim);
  cursor: pointer;
  transition: background 0.18s, color 0.18s, box-shadow 0.18s;
}
.seg-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.06); }
.seg-btn.is-on {
  background: linear-gradient(180deg, #ffe596, #e3a53a);
  color: #3d2400;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.switch {
  position: relative;
  width: 62px;
  height: 34px;
  flex: none;
  border: 0;
  border-radius: 17px;
  background: rgba(255, 255, 255, 0.14);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.4);
  cursor: pointer;
  transition: background 0.2s;
}
.switch-knob {
  position: absolute;
  left: 4px;
  top: 4px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: linear-gradient(180deg, #fff, #d9d9d9);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.4);
  transition: transform 0.22s var(--ease-spring);
}
.switch.is-on { background: linear-gradient(180deg, #3ddc97, #14a06c); }
.switch.is-on .switch-knob { transform: translateX(28px); }
.set-note {
  margin-top: 18px;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(244, 201, 93, 0.08);
  border: 1px solid var(--gold-hair);
  font: 600 14px/1.4 var(--font-body);
  color: #f6e3b0;
}

/* Rules --------------------------------------------------------------------------------- */
.tabs { display: flex; gap: 6px; padding: 4px; border-radius: 14px; background: rgba(0, 0, 0, 0.3); margin-bottom: 16px; width: max-content; }
.tab {
  height: 40px;
  padding: 0 18px;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: var(--ink-dim);
  font: 700 17px var(--font-display);
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
}
.tab:hover { color: #fff; }
.tab.is-on { background: linear-gradient(180deg, #ffe596, #e3a53a); color: #3d2400; box-shadow: 0 3px 8px rgba(0, 0, 0, 0.3); }
.tab-page { display: none; }
.tab-page.is-on { display: block; animation: fadeIn 0.25s ease backwards; }
.rules-group-title {
  margin: 18px 0 10px;
  font: 800 20px var(--font-display);
  color: var(--gold);
  display: flex;
  align-items: center;
  gap: 12px;
}
.rules-group-title::after { content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, var(--gold-hair), transparent); }
.rules-group-title:first-child { margin-top: 0; }
.rules-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.rule-card {
  padding: 14px 16px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.07);
}
.rule-card h4 { margin: 0 0 6px; font: 800 17px/1.2 var(--font-display); color: #fff; }
.rule-card p { margin: 0; font: 600 15px/1.5 var(--font-body); color: var(--ink-dim); }
.data-table { width: 100%; border-collapse: separate; border-spacing: 0; font: 600 15px var(--font-body); }
.data-table th {
  padding: 10px 12px;
  text-align: left;
  font: 800 13px var(--font-display);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold);
  background: rgba(0, 0, 0, 0.25);
  border-bottom: 1px solid var(--gold-hair);
  white-space: nowrap;
}
.data-table th .sb-player { text-transform: none; letter-spacing: 0; font: 800 15px var(--font-display); color: #fff; }
.data-table th:first-child { border-radius: 10px 0 0 0; }
.data-table th:last-child { border-radius: 0 10px 0 0; }
.data-table td { padding: 10px 12px; border-bottom: 1px solid rgba(255, 255, 255, 0.06); color: var(--ink); vertical-align: middle; }
.data-table tr:nth-child(even) td { background: rgba(255, 255, 255, 0.02); }
.data-table td.num, .data-table th.num { text-align: right; font-family: var(--font-num); font-weight: 700; }
.data-table td small { display: block; color: var(--ink-mute); font-weight: 600; font-size: 13px; }
.v-good { color: var(--green) !important; }
.v-bad { color: #ff8f8c !important; }
.v-dim { color: var(--ink-mute) !important; }
.help-list { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.help-list li { padding: 14px 16px 14px 56px; position: relative; border-radius: 14px; background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.07); font: 600 15px/1.5 var(--font-body); color: var(--ink-dim); }
.help-list li b { color: #fff; display: block; font: 800 17px var(--font-display); margin-bottom: 2px; }
.help-list li .hl-ic { position: absolute; left: 16px; top: 16px; width: 26px; height: 26px; color: var(--gold); }
.help-list li .hl-ic svg { width: 100%; height: 100%; }

/* Rulebook tab (docs/CEZALI_KURALLAR.md rendered) */
.rulebook { max-width: 1080px; font: 600 15.5px/1.6 var(--font-body); color: var(--ink-dim); }
.rulebook .rb-title { margin: 0 0 8px; font: 800 26px/1.2 var(--font-display); color: #ffe8a8; }
.rulebook .rb-h {
  margin: 20px 0 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--gold-hair);
  font: 800 20px/1.2 var(--font-display);
  color: var(--gold);
}
.rulebook p { margin: 6px 0 10px; }
.rulebook b { color: #fff; font-weight: 800; }
.rulebook code { padding: 1px 6px; border-radius: 6px; background: rgba(0, 0, 0, 0.3); font: 700 13px var(--font-num); color: #f6e3b0; }
.rulebook .rb-list { margin: 4px 0 10px; padding-left: 24px; }
.rulebook .rb-list > li { margin: 5px 0; padding-left: 4px; }
.rulebook ol.rb-list > li::marker { color: var(--gold); font-weight: 800; }
.rulebook ul.rb-list > li::marker { color: var(--gold); }
.rulebook .rb-sub { margin: 4px 0 2px; padding-left: 20px; list-style: circle; }
.rulebook .rb-sub li { margin: 3px 0; }
.rulebook .rb-h4 { margin: 12px 0 6px; font: 800 16px/1.3 var(--font-display); color: #ffe8a8; }
.rulebook .rb-toc { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0 4px; }
.rulebook .rb-toc-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border-radius: 15px;
  border: 1px solid var(--gold-hair);
  background: rgba(255, 255, 255, 0.04);
  color: var(--ink-dim);
  font: 700 13.5px var(--font-body);
  cursor: pointer;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.rulebook .rb-toc-btn b { color: var(--gold); font: 800 13.5px var(--font-num); }
.rulebook .rb-toc-btn:hover { color: #fff; border-color: var(--gold-hair-strong); background: rgba(244, 201, 93, 0.1); }
.rulebook .rb-src { margin-top: 18px; font: 700 12.5px var(--font-body); color: var(--ink-mute); }
.rulebook .rb-note {
  display: inline-block;
  height: 19px;
  padding: 0 7px;
  border-radius: 6px;
  background: rgba(90, 174, 255, 0.2);
  color: #b8dcff;
  font: 800 11px/19px var(--font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: 1px;
}

/* Scoreboard & results ----------------------------------------------------------------- */
.sb-player { display: flex; align-items: center; gap: 8px; }
.sb-av { width: 30px; height: 30px; border-radius: 50%; overflow: hidden; flex: none; box-shadow: 0 0 0 2px var(--gold-hair-strong); background: #16343a; }
.sb-av svg { width: 100%; height: 100%; }
.sb-me td { background: rgba(244, 201, 93, 0.07) !important; }
.sb-total td { font-weight: 800; background: rgba(0, 0, 0, 0.25) !important; border-bottom: 0; }
.sb-total td.num { color: var(--gold); font-size: 18px; }
.sb-live td { color: var(--ink-mute); font-style: italic; }
.sb-rank td { font-weight: 800; background: rgba(0, 0, 0, 0.18) !important; border-bottom: 0; }
.sb-rank td.num b { color: #ffe8a8; font: 800 17px var(--font-num); }

.rr-banner { display: flex; align-items: center; gap: 20px; margin-bottom: 16px; padding: 16px 20px; border-radius: 18px; background: linear-gradient(90deg, rgba(244, 201, 93, 0.16), rgba(244, 201, 93, 0.02)); border: 1px solid var(--gold-hair); }
.rr-banner.is-none { background: linear-gradient(90deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.01)); }
.rr-av { width: 84px; height: 84px; border-radius: 50%; overflow: hidden; flex: none; box-shadow: 0 0 0 4px var(--gold), 0 0 26px rgba(244, 201, 93, 0.5); background: #16343a; animation: badgePop 0.6s var(--ease-spring) backwards; }
.rr-av svg { width: 100%; height: 100%; }
.rr-ic { width: 70px; height: 70px; color: var(--gold); flex: none; }
.rr-ic svg { width: 100%; height: 100%; }
.rr-title { font: 800 34px/1.1 var(--font-display); color: #fff; }
.rr-chips { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.chip { display: inline-flex; align-items: center; height: 28px; padding: 0 12px; border-radius: 14px; font: 800 14px var(--font-body); background: rgba(255, 255, 255, 0.1); color: #fff; }
.chip-gold { background: linear-gradient(180deg, #ffe596, #e3a53a); color: #3d2400; }
.chip-green { background: rgba(61, 220, 151, 0.2); color: #9ff3cc; }
.chip-blue { background: rgba(90, 174, 255, 0.2); color: #b8dcff; }
.chip-red { background: rgba(239, 83, 80, 0.22); color: #ffc7c2; }
.rr-hand { display: flex; flex-wrap: wrap; gap: 2px; max-width: 330px; }
.rr-table td { vertical-align: top; }
.rr-table td.num small { white-space: nowrap; }
.rr-pen { min-width: 190px; }
.rr-ledger { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; }
.rr-ledger li { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font: 700 13.5px/1.25 var(--font-body); color: var(--ink-dim); white-space: nowrap; }
.rr-ledger li i { font-style: normal; color: var(--ink-mute); font-size: 12px; }
.rr-ledger li b { font: 800 14px var(--font-num); }
.rr-pen-sum { margin-top: 4px; padding-top: 3px; border-top: 1px solid rgba(255, 255, 255, 0.08); text-align: right; font: 800 15px var(--font-num); }
.rr-note { margin-top: 12px; }
.rr-mini { width: 22px; height: 31px; border-radius: 3px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); }
.rr-mini > svg { width: 100%; height: 100%; }
.rr-winner td { background: rgba(61, 220, 151, 0.07) !important; }
.rr-trophy { width: 20px; height: 20px; color: var(--gold); display: inline-block; vertical-align: -4px; }
.rr-trophy svg { width: 100%; height: 100%; }

.podium { display: flex; align-items: flex-end; justify-content: center; gap: 18px; margin: 4px 0 22px; min-height: 300px; }
.pod { display: flex; flex-direction: column; align-items: center; width: 200px; animation: fadeUp 0.6s var(--ease-out) backwards; }
.pod-1 { animation-delay: 0.25s; }
.pod-2 { animation-delay: 0.1s; }
.pod-3 { animation-delay: 0.4s; }
.pod-av { width: 88px; height: 88px; border-radius: 50%; overflow: hidden; background: #16343a; box-shadow: 0 0 0 4px var(--pc), 0 10px 20px rgba(0, 0, 0, 0.45); }
.pod-1 .pod-av { width: 112px; height: 112px; box-shadow: 0 0 0 5px var(--pc), 0 0 34px rgba(244, 201, 93, 0.6), 0 10px 20px rgba(0, 0, 0, 0.45); }
.pod-av svg { width: 100%; height: 100%; }
.pod-crown { width: 40px; height: 40px; color: var(--gold); margin-bottom: 2px; animation: logoFloat 2.4s ease-in-out infinite; }
.pod-crown svg { width: 100%; height: 100%; }
.pod-name { margin-top: 10px; font: 800 20px var(--font-display); color: #fff; max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pod-score { font: 800 18px var(--font-num); color: var(--pc); }
.pod-step {
  margin-top: 10px;
  width: 100%;
  border-radius: 14px 14px 4px 4px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 10px;
  font: 800 44px var(--font-display);
  color: rgba(0, 0, 0, 0.35);
  background: linear-gradient(180deg, var(--pc), rgba(0, 0, 0, 0.25));
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.4), 0 10px 22px rgba(0, 0, 0, 0.4);
}
.pod-1 { --pc: #f4c95d; }
.pod-2 { --pc: #cfd8dc; }
.pod-3 { --pc: #d8925a; }
.pod-1 .pod-step { height: 110px; }
.pod-2 .pod-step { height: 76px; }
.pod-3 .pod-step { height: 54px; }
/* Shared ranks: colour and height follow the rank, not the podium position */
.pod.pod-r1 { --pc: #f4c95d; }
.pod.pod-r2 { --pc: #cfd8dc; }
.pod.pod-r3 { --pc: #d8925a; }
.pod.pod-r1 .pod-step { height: 110px; }
.pod.pod-r2 .pod-step { height: 76px; }
.pod.pod-r3 .pod-step { height: 54px; }
.pod.pod-r1 .pod-av { width: 112px; height: 112px; box-shadow: 0 0 0 5px var(--pc), 0 0 34px rgba(244, 201, 93, 0.6), 0 10px 20px rgba(0, 0, 0, 0.45); }
.mr-sub { text-align: center; font: 700 18px var(--font-body); color: var(--ink-dim); margin: -6px 0 14px; }
.confetti { position: absolute; inset: 0; overflow: hidden; pointer-events: none; border-radius: inherit; }
.confetti i {
  position: absolute;
  top: -20px;
  width: 10px;
  height: 16px;
  border-radius: 2px;
  opacity: 0.9;
  animation: confetti var(--d, 3s) linear var(--dl, 0s) infinite;
}

.pile-hist { display: flex; flex-wrap: wrap; gap: 6px; }
.pile-hist .ph-tile { width: 40px; height: 56px; border-radius: 5px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); }
.pile-hist .ph-tile > svg { width: 100%; height: 100%; }
.pile-hist .ph-tile.is-last { box-shadow: 0 0 0 2px var(--gold), 0 2px 4px rgba(0, 0, 0, 0.4); }

/* ======================================================================================
   15. Toasts
   ====================================================================================== */
.toast {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 880px;
  padding: 11px 20px 11px 14px;
  border-radius: 15px;
  background: rgba(7, 19, 23, 0.94);
  border: 1px solid var(--gold-hair);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.5);
  font: 700 17px/1.35 var(--font-body);
  color: var(--ink);
  animation: toastIn 0.34s var(--ease-spring) backwards;
}
.toast.is-out { animation: toastOut 0.32s ease forwards; }
.toast-ic { width: 22px; height: 22px; flex: none; color: var(--gold); }
.toast-ic svg { width: 100%; height: 100%; }
.toast-error { border-color: rgba(239, 83, 80, 0.65); background: linear-gradient(90deg, rgba(80, 12, 14, 0.95), rgba(10, 20, 24, 0.95)); }
.toast-error .toast-ic { color: #ff8078; }
.toast-warn { border-color: rgba(255, 181, 71, 0.6); }
.toast-warn .toast-ic { color: var(--amber); }
.toast-success { border-color: rgba(61, 220, 151, 0.6); background: linear-gradient(90deg, rgba(8, 60, 40, 0.95), rgba(10, 20, 24, 0.95)); }
.toast-success .toast-ic { color: var(--green); }

/* ======================================================================================
   16. Keyframes
   ====================================================================================== */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeOut { to { opacity: 0; } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes modalIn { from { opacity: 0; transform: translateY(24px) scale(0.94); } to { opacity: 1; transform: none; } }
@keyframes modalOut { to { opacity: 0; transform: translateY(10px) scale(0.97); } }
@keyframes toastIn { from { opacity: 0; transform: translateY(-16px) scale(0.92); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateY(-10px) scale(0.96); } }
@keyframes badgePop { from { opacity: 0; transform: translateX(var(--bx, 0)) scale(0.4); } to { opacity: 1; transform: translateX(var(--bx, 0)) scale(1); } }
.rack-badge { --bx: -50%; }
@keyframes glowIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes groupIn { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: none; } }
@keyframes meldBump { 0% { transform: scale(1); } 40% { transform: scale(1.07); } 100% { transform: scale(1); } }
@keyframes dealIn {
  from { opacity: 0; transform: translateY(-46px) scale(0.72) rotate(-10deg); }
  to { opacity: 1; transform: none; }
}
@keyframes flipIn {
  0% { transform: perspective(400px) rotateY(90deg) scale(0.9); opacity: 0.2; }
  60% { transform: perspective(400px) rotateY(-12deg) scale(1.06); opacity: 1; }
  100% { transform: none; opacity: 1; }
}
@keyframes flashUp {
  0% { opacity: 0; transform: translate(-50%, 12px) scale(0.5); }
  14% { opacity: 1; transform: translate(-50%, -8px) scale(1.18); }
  28% { transform: translate(-50%, -12px) scale(1); }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -64px) scale(1); }
}
/* phones: a shorter rise, so a flash never floats over the top strip's buttons */
@keyframes flashUpPh {
  0% { opacity: 0; transform: translate(-50%, 8px) scale(0.5); }
  14% { opacity: 1; transform: translate(-50%, -6px) scale(1.18); }
  28% { transform: translate(-50%, -8px) scale(1); }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -30px) scale(1); }
}
/* phones, the top opponent's flash beside its card in the top strip: it pops up in place */
@keyframes flashPopPh {
  0% { opacity: 0; transform: translate(-50%, 0) scale(0.5); }
  14% { opacity: 1; transform: translate(-50%, 0) scale(1.14); }
  28% { transform: translate(-50%, 0) scale(1); }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -4px) scale(1); }
}
@keyframes bubble {
  0% { opacity: 0; transform: var(--bt, translateX(0)) scale(0.6); }
  10% { opacity: 1; transform: var(--bt, translateX(0)) scale(1.06); }
  18% { transform: var(--bt, translateX(0)) scale(1); }
  82% { opacity: 1; }
  100% { opacity: 0; transform: var(--bt, translateX(0)) scale(0.96); }
}
.seat-2 .seat-bubble { --bt: translateX(-50%); }
@keyframes bannerIn {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  14% { opacity: 1; transform: translate(-50%, -50%) scale(1.08); }
  24% { transform: translate(-50%, -50%) scale(1); }
  76% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -58%) scale(0.98); }
}
/* Every pulsing glow (deck, side pile, taken tile, Aç, the urgent avatar, the menu's Oyna): the element
   keeps the glow's low point as a static shadow and a pre-painted brighter glow on top breathes by
   opacity only. An infinite box-shadow / filter animation repaints — and re-rasters the table
   under it — on every frame (tests/ui.test.js guards this). */
@keyframes glowPulse {
  0%, 100% { opacity: 0; }
  50% { opacity: 1; }
}
@keyframes confetti {
  0% { transform: translate3d(0, 0, 0) rotate(0deg); }
  100% { transform: translate3d(var(--dx, 30px), 900px, 0) rotate(720deg); }
}
@keyframes tileFlip {
  0% { transform: perspective(320px) rotateY(0deg); }
  50% { transform: perspective(320px) rotateY(90deg) scale(1.04); }
  100% { transform: perspective(320px) rotateY(0deg); }
}
@keyframes barrierBump {
  0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(244, 201, 93, 0); }
  30% { transform: scale(1.08); box-shadow: 0 0 0 3px rgba(244, 201, 93, 0.6), 0 0 24px rgba(244, 201, 93, 0.5); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(244, 201, 93, 0); }
}
@keyframes diveGlow {
  0%, 100% { filter: none; }
  50% { filter: brightness(1.12) drop-shadow(0 0 6px rgba(255, 120, 90, 0.55)); }
}
@keyframes btnPulse {
  0%, 100% { transform: scale(1); filter: none; }
  50% { transform: scale(1.07); filter: brightness(1.25) drop-shadow(0 0 10px rgba(255, 205, 90, 0.95)); }
}
@keyframes statusPulse {
  0%, 100% { box-shadow: inset 0 0 0 1px rgba(255, 120, 110, 0.6); }
  50% { box-shadow: inset 0 0 0 1px rgba(255, 150, 140, 0.95), 0 0 10px rgba(239, 83, 80, 0.55); }
}

/* ======================================================================================
   17. Pause menu (phone ≡ button, Android back button)
   ====================================================================================== */
.pm-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pm-grid .btn { width: 100%; justify-content: flex-start; padding: 0 16px; }
.pm-grid .pm-wide { grid-column: 1 / -1; justify-content: center; }

/* ======================================================================================
   18. Phone layout (html/.stage "is-phone", set by Stage.fit() in ui.js)
   The stage covers the whole screen (--sw × --sh; the table is full-bleed on every edge, also
   behind a camera hole): its content box — the stage minus the safe-area insets --sa-l/t/r/b —
   is at least PHONE.baseH (390) × PHONE.minW (760) virtual px, scaled ≈ 0.92–1.1 on 740×360 …
   924×425 screens, so 12–13px text stays ≥ 11 CSS px and 44px targets ≥ 40 CSS px.
   Laid out like the desktop table (phoneBoxes() in ui.js does the same arithmetic):

     top strip   ≡ · El · Baraj/Çift ······· seat 2 (one compact card) ······· Skor · Günlük
     middle      seat 3 | pile 2 ·········· the table melds (big board) ·········· pile 1 | seat 1
     hub row     seat 0 ····· hint + info chip · DESTE [deck] [gösterge] GÖSTERGE ····· action pills
     rack row    Seri/Çift Diz | pile 3 (yandan) | ıstaka 16×2 | pile 0 (attığın) | Aç/Çift Aç

   Every row has its own side offsets from phoneLayout() (ui.js), so a camera cutout only pushes
   the rows it touches and the rounded display corners only the corner buttons:
     --ph-t / --ph-b             top / bottom content offset (margin, or a top / bottom inset + gap)
     --ph-tl / --ph-tr, --ph-tcx top strip (corner-aware) and its centre
     --ph-ml / --ph-mr, --ph-mcx middle band        --ph-hl / --ph-hr  hub row
     --ph-rl / --ph-rr, --ph-rcx rack row (corner-aware: its button columns sit in the bottom corners)
     --ph-bl / --ph-br           bottom corners (menu)
     --ph-rad…                   table corner radius (= the display's corner radius when known)
   The fallbacks below are the values without any inset. --rk-w/--rk-h/--rk-tw/--rk-th: rack
   geometry (rackGeometry); --ph-m, --ph-t, --ph-b, --ph-top, --ph-hub-h, --ph-pile-w, --ph-col-l,
   --ph-col-r and --ph-seat-w must match PHONE.m / mt / mb / top / hub / pileW / colL / colR / seatW,
   the board's gap above the hub row PHONE.boardGap, and PHONE.rackReserve = both columns +
   2 × (6px gap + pile + 4px gap to the ıstaka).
   The table's rim is 5px on phones (felt inset): the top strip sits 5px, the side controls 9px and
   the ıstaka 3px inside the felt — nothing overlaps the rim.
   ====================================================================================== */
.stage.is-phone {
  --ph-m: 14px;
  --ph-top: 44px;
  --ph-pile-w: 40px;
  --ph-t: 10px;
  --ph-b: 8px;
  --ph-tl: var(--ph-m);
  --ph-tr: var(--ph-m);
  --ph-tcx: 50%;
  --ph-ml: var(--ph-m);
  --ph-mr: var(--ph-m);
  --ph-mcx: 50%;
  --ph-hl: var(--ph-m);
  --ph-hr: var(--ph-m);
  --ph-rl: var(--ph-m);
  --ph-rr: var(--ph-m);
  --ph-rcx: 50%;
  --ph-bl: var(--ph-m);
  --ph-br: var(--ph-m);
  --sa-l: 0px;
  --sa-t: 0px;
  --sa-r: 0px;
  --sa-b: 0px;
  --ph-rack-b: var(--ph-b);
  /* hub row (deck + gösterge) 4px above the ıstaka, the meld board 4px under the top strip and 6px
     above the hub row (PHONE.boardGap) */
  --ph-hub-h: 50px;
  --ph-hub-b: calc(var(--ph-rack-b) + var(--rk-h, 120px) + 4px);
  --ph-mid-t: calc(var(--ph-t) + var(--ph-top) + 4px);
  --ph-mid-b: calc(var(--ph-hub-b) + var(--ph-hub-h) + 6px);
  --ph-mid-c: calc((var(--ph-mid-t) + var(--sh, 390px) - var(--ph-mid-b)) / 2);
  /* the middle band's bottom edge, 2px above the hub row (the side cards stay above it) */
  --ph-band-b: calc(var(--sh, 390px) - var(--ph-hub-b) - var(--ph-hub-h) - 2px);
  /* side cards on the screen edges, the top piles 6px inside them, the meld board 8px after those */
  --ph-seat-w: 72px;
  --ph-pile-l: calc(var(--ph-ml) + var(--ph-seat-w) + 6px);
  --ph-pile-r: calc(var(--ph-mr) + var(--ph-seat-w) + 6px);
  --ph-board-l: calc(var(--ph-pile-l) + var(--ph-pile-w) + 8px);
  --ph-board-r: calc(var(--ph-pile-r) + var(--ph-pile-w) + 8px);
  /* the button columns at the ends of the rack row */
  --ph-col-l: 50px;
  --ph-col-r: 50px;
  /* behind the table's rounded corners (a browser, or a screen with unknown corners): dark rim wood */
  background: #26140a;
}

/* --- generic controls ------------------------------------------------------------------ */
.is-phone .btn { height: 44px; padding: 0 12px; gap: 6px; font-size: 16px; border-radius: 12px; }
.is-phone .btn::after { border-radius: 11px 11px 40% 40% / 11px 11px 10px 10px; }
.is-phone .btn .btn-ic { width: 18px; height: 18px; }
.is-phone .btn-num { min-width: 26px; height: 22px; padding: 0 6px; border-radius: 11px; font-size: 14px; line-height: 22px; }
.is-phone .icon-btn { width: 44px; height: 44px; border-radius: 12px; }
.is-phone .icon-btn svg { width: 22px; height: 22px; }
.is-phone .icon-btn[data-tip]::before { display: none; }

/* --- top strip ------------------------------------------------------------------------- */
.is-phone .topbar {
  left: 0;
  top: var(--ph-t);
  width: 100%;
  height: var(--ph-top);
  padding: 0 var(--ph-tr) 0 var(--ph-tl);
  gap: 6px;
  background: none;
  border: 0;
  box-shadow: none;
  pointer-events: none;
}
.is-phone .topbar > * { pointer-events: auto; }
.is-phone .topbar .tb-menu { display: inline-flex; }
.is-phone .tb-logo, .is-phone .tb-gosterge { display: none; } /* the gösterge is on the table */
.is-phone .tb-center { flex: none; gap: 6px; }
.is-phone .tb-right { margin-left: auto; gap: 6px; }
.is-phone .tb-right [data-act="rules"],
.is-phone .tb-right [data-act="sound"],
.is-phone .tb-right [data-act="fullscreen"],
.is-phone .tb-right [data-act="settings"],
.is-phone .tb-right [data-act="menu"] { display: none; }
.is-phone .tb-pill { height: 34px; padding: 0 11px; gap: 6px; font-size: 13px; background: rgba(5, 14, 17, 0.62); }
.is-phone .tb-pill b { font-size: 16px; }
.is-phone .tb-barrier { height: 34px; padding: 0 11px; }
.is-phone .tb-barrier b { min-width: 0; }
.is-phone .tb-sep { height: 16px; }

/* --- table ------------------------------------------------------------------------------- */
/* full bleed: the rim runs along the screen edges, its corners follow the display's rounded corners */
.is-phone .table { left: 0; top: 0; width: 100%; height: 100%; border-radius: var(--ph-rad, 22px); }
.is-phone .table-rim::after { inset: 2px; border-radius: var(--ph-rad-rim, 20px); border-width: 1px; box-shadow: none; }
.is-phone .table-felt { inset: 5px; border-radius: var(--ph-rad-felt, 17px); }
.is-phone .felt-lines { inset: 6px; border-radius: var(--ph-rad-lines, 11px); }
.is-phone .felt-emblem { top: var(--ph-mid-c); width: 330px; height: 94px; }
.is-phone .felt-emblem-box { clip-path: inset(calc(var(--ph-mid-c) - 49px) calc(50% - 167px) calc(100% - var(--ph-mid-c) - 49px) calc(50% - 167px)); }

/* --- seats: one compact card per opponent ------------------------------------------------ */
.is-phone .seat-av { width: 44px; height: 44px; }
.is-phone .seat-av-img { inset: 3px; box-shadow: 0 0 0 2px rgba(244, 201, 93, 0.85), 0 3px 8px rgba(0, 0, 0, 0.45); }
.is-phone .seat-glow { inset: 3px; } /* (the avatar's geometry) */
.is-phone .seat.is-active .seat-av-img { box-shadow: 0 0 0 2px #fff1bd, 0 0 14px 3px rgba(244, 201, 93, 0.55), 0 3px 8px rgba(0, 0, 0, 0.45); }
.is-phone .seat-ring {
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3.5px), #000 calc(100% - 3px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3.5px), #000 calc(100% - 3px));
}
/* the human's clock is the frame on the ıstaka (.rk-turn): the avatar ring would only repeat it (the
   "0:57" pill stays, the exact reading) */
.is-phone .seat-0 .seat-ring { display: none; }
/* an opponent's ring (the bot spinner, the server's countdown online) paints over the avatar's own
   outline; the tile-count chip, the presence mark and the "BOT" tag (z-index 3) stay above it */
.is-phone .seat-ring { z-index: 1; }
.is-phone .seat-count { z-index: 2; }
.is-phone .seat-av-fallback { font-size: 18px; }
/* the name / score / badges sit on the card itself (no box in the box) */
.is-phone .seat-info {
  gap: 1px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.is-phone .seat-name { max-width: 96px; font-size: 14px; }
.is-phone .seat-score { font-size: 0; gap: 0; } /* the "Puan" label is dropped, the number stays */
.is-phone .seat-score b { font-size: 14px; }
.is-phone .seat-badges { gap: 2px; }
.is-phone .seat-badge { height: 17px; padding: 0 5px; border-radius: 9px; font-size: 12px; line-height: 17px; }
.is-phone .seat-badge.is-prov { line-height: 15px; }
/* an opened player's "Açtı · 139" / "Daldı" badges: the board row's tag says it (ui.js renderSeats) */
.is-phone .seat.has-row .seat-badge.b-open,
.is-phone .seat.has-row .seat-badge.b-pairs,
.is-phone .seat.has-row .seat-badge.b-dive { display: none; }
.is-phone .seat-fan { display: none; }
/* the tile count: a chip on the avatar's lower right, with a small tile in it (the score is the gold
   number without a chip — the human's is the chip on the avatar's upper right) */
.is-phone .seat-count {
  right: -9px;
  top: auto;
  bottom: 1px;
  min-width: 24px;
  height: 20px;
  padding: 0 5px 0 4px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 18px;
  white-space: nowrap;
}
.is-phone .seat-count::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 10px;
  margin-right: 3px;
  border-radius: 2px;
  background: linear-gradient(180deg, #fffdf5, #e6d6b4);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.45);
  vertical-align: -1px;
}
.is-phone .seat-bot {
  background: rgba(5, 14, 17, 0.56);
  border: 1px solid var(--gold-hair);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.28);
}
.is-phone .seat-bot.is-active { border-color: var(--gold-hair-strong); background: rgba(5, 14, 17, 0.7); }

/* side opponents: slim vertical cards on the screen edges, centred in the middle band by their
   badge-less height (≈ 94px): a new badge (Ceza, Daldı) grows the card downward — the avatar and
   the name never jump — and a card that would reach the hub row moves up just enough (--card-h:
   its height, set by ui.js fitSideCards) */
.is-phone .seat-1,
.is-phone .seat-3 {
  top: max(calc(var(--ph-mid-t) - 2px), min(calc(var(--ph-mid-c) - 47px), calc(var(--ph-band-b) - var(--card-h, 94px))));
  width: var(--ph-seat-w);
  height: auto;
  padding: 6px 0 7px;
  gap: 2px;
  border-radius: 14px;
  transform: none;
}
.is-phone .seat-3 { left: var(--ph-ml); }
.is-phone .seat-1 { left: auto; right: var(--ph-mr); }
.is-phone .seat-bot .seat-av { order: 0; }
.is-phone .seat-bot .seat-hand { order: 1; position: relative; flex: none; width: 48px; height: 0; margin: -2px 0 0; }
.is-phone .seat-bot .seat-info { order: 2; }
.is-phone .seat-1 .seat-info,
.is-phone .seat-3 .seat-info { width: 100%; align-items: center; }
.is-phone .seat-1 .seat-name,
.is-phone .seat-3 .seat-name { max-width: calc(100% - 8px); font-size: 13px; } /* first name only (ui.js) */
.is-phone .seat-1 .seat-badge,
.is-phone .seat-3 .seat-badge { max-width: calc(var(--ph-seat-w) - 4px); padding: 0 4px; letter-spacing: -0.02em; overflow: hidden; text-overflow: ellipsis; } /* "Ödül −101", "Ceza 1010" fit */
.is-phone .seat-1 .seat-badges,
.is-phone .seat-3 .seat-badges { flex-direction: column; align-items: center; margin-top: 2px; }
.is-phone .seat-bot:not(.has-badges) .seat-badges { display: none; } /* .has-badges: set by renderSeats() */

/* top opponent: one compact card in the middle of the top strip */
.is-phone .seat-2 {
  left: var(--ph-tcx);
  top: var(--ph-t);
  width: auto;
  height: var(--ph-top);
  padding: 0 12px 0 3px;
  gap: 12px;
  border-radius: 22px;
  transform: translateX(-50%);
  justify-content: flex-start;
}
.is-phone .seat-2 .seat-av { order: 0; width: 38px; height: 38px; }
.is-phone .seat-2 .seat-hand { order: 1; width: 0; height: 38px; margin: 0 0 0 -12px; }
.is-phone .seat-2 .seat-count { left: -26px; right: auto; bottom: -2px; }
.is-phone .seat-2 .seat-info {
  order: 2;
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  column-gap: 8px;
  row-gap: 0;
}
.is-phone .seat-2 .seat-name { grid-column: 1; grid-row: 1; line-height: 1.15; }
.is-phone .seat-2 .seat-score { grid-column: 1; grid-row: 2; }
.is-phone .seat-2 .seat-badges { grid-column: 2; grid-row: 1 / span 2; flex-direction: column; align-items: flex-start; }

/* the human: the first item of the hub row — avatar with its timer ring (on the axis of the Seri /
   Çift Diz column below it), the score as a chip on it; no name, and only the badge nothing else
   says: Ceza / Ödül as a compact chip ("+130", "−101"; "Açtı · 115" is the board row's tag,
   "Çifte daldın" the info line). ui.js fitHubRow reserves the score chip's overhang (margin-right). */
.is-phone .ph-hub .seat-0 {
  position: relative;
  left: auto;
  top: auto;
  width: auto;
  height: var(--ph-hub-h);
  flex: none;
  gap: 6px;
  margin-left: max(0px, calc(var(--ph-rl) - var(--ph-hl) + (var(--ph-col-l) - 44px) / 2));
  z-index: 16;
}
.is-phone .seat-0 .seat-info { display: contents; }
.is-phone .seat-0 .seat-name { display: none; }
.is-phone .seat-0 .seat-score {
  position: absolute;
  left: 26px;
  top: -3px;
  z-index: 3;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: #0a1b1f;
  border: 1px solid var(--gold-hair-strong);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4);
}
.is-phone .seat-0 .seat-score b { font-size: 13px; line-height: 18px; }
/* (display: contents: the hidden badges take no room, not even a flex gap) */
.is-phone .seat-0 .seat-badges { display: contents; }
.is-phone .seat-0 .seat-badge:first-child,
.is-phone .seat-0 .seat-badge.b-dive { display: none; }
/* (at the avatar's bottom: clear of the score chip at its top) */
.is-phone .seat-0 .seat-badge.b-pen { align-self: flex-end; margin-bottom: 4px; height: 20px; padding: 0 7px; border-radius: 10px; font-size: 13px; line-height: 20px; }
.is-phone .seat-timer { bottom: -2px; min-width: 36px; height: 18px; padding: 0 5px; border-radius: 9px; font-size: 12px; line-height: 16px; }

/* flashes & bubbles (keepFlashInside() in ui.js keeps each flash on screen, out of the top strip and
   off the other players' cards); the side cards' bubbles point at the board below the top piles.
   A side card's flash starts on its name (it rises over the avatar), the human's beside the avatar
   (over the info chip, clear of the left card above), the top card's pops up beside the card in the
   top strip (no rise: the board and the toasts stay free) */
/* a soft dark plate behind each flash: legible over an avatar, a name or the felt */
.is-phone .flash {
  padding: 2px 10px 3px;
  border-radius: 14px;
  background: radial-gradient(closest-side, rgba(3, 10, 12, 0.62), rgba(3, 10, 12, 0.34) 70%, rgba(3, 10, 12, 0));
  animation-name: flashUpPh;
}
.is-phone .flash-num { font-size: 28px; }
.is-phone .flash-sub { font-size: 12px; letter-spacing: 0.03em; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.95), 0 0 8px rgba(0, 0, 0, 0.75); }
.is-phone .seat-fx { top: 10px; }
.is-phone .seat-1 .seat-fx,
.is-phone .seat-3 .seat-fx { top: 40px; }
.is-phone .seat-2 .seat-fx { left: calc(100% + 58px); top: -2px; }
.is-phone .seat-2 .flash { animation-name: flashPopPh; }
.is-phone .seat-2 .flash-num { font-size: 24px; }
.is-phone .seat-0 .seat-fx { left: 96px; top: -12px; }
.is-phone .seat-bubble { padding: 5px 10px; border-radius: 12px; font-size: 14px; }
.is-phone .seat-1 .seat-bubble { right: calc(100% + 8px); top: calc(50% - 6px); }
.is-phone .seat-3 .seat-bubble { left: calc(100% + 8px); top: calc(50% - 6px); }
.is-phone .seat-2 .seat-bubble { top: calc(100% + 6px); }
.is-phone .seat-0 .seat-bubble { left: 74px; bottom: calc(100% + 2px); }
.is-phone .seat-0 .seat-bubble::after { left: 10px; }

/* --- discard piles ------------------------------------------------------------------------ */
.is-phone .pile { width: var(--ph-pile-w); height: 70px; }
/* a 34×47 tile, like the gösterge */
.is-phone .pile-slot,
.is-phone .pile-anchor { left: 3px; top: 3px; width: 34px; height: 47px; }
.is-phone .pile-slot { border-radius: 6px; border-width: 1.5px; }
.is-phone .pile-slot::before { inset: -1.5px; border-width: 1.5px; }
.is-phone .pile-slot::after { border-radius: 4.5px; }
.is-phone .pile-tile { width: 34px; height: 47px; border-radius: 5px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); }
/* caption ("YANDAN" / "ATTIĞIN" ≈ 46px on a 40px pile): it may reach 6px past the pile's outer side,
   into the gap to the button column — never toward the ıstaka */
.is-phone .pile-cap { top: 53px; left: 0; right: 0; font-size: 12px; letter-spacing: 0; color: rgba(255, 255, 255, 0.64); }
.is-phone .pile-3 .pile-cap { left: -6px; }
.is-phone .pile-0 .pile-cap { right: -6px; }
/* the top piles sit right next to their owners: no name caption */
.is-phone .pile-1 .pile-cap,
.is-phone .pile-2 .pile-cap { display: none; }
.is-phone .pile-count { right: -9px; top: -5px; min-width: 24px; height: 20px; padding: 0 5px; border-radius: 10px; font-size: 12px; line-height: 18px; }
.is-phone .pile-count::after { content: ''; position: absolute; inset: -12px -10px; }
/* The two piles beside the rack are tap targets themselves (yandan: take, taş at: discard). Their
   count badge (history) sits under the caption, 24px below the tile — out of the reach of Chromium's
   touch adjustment from anywhere on the tile (section 8) — with a finger-sized hit area of its own
   (44px high) that grows downward, never over the caption (a tap on "TAŞ AT" discards). */
.is-phone .pile-3 .pile-count,
.is-phone .pile-0 .pile-count { right: 8px; top: 74px; }
.is-phone .pile-3 .pile-count::after,
.is-phone .pile-0 .pile-count::after { inset: -2px -10px -22px; }
.is-phone .pile-warn { top: -20px; font-size: 12px; }
/* finger-sized targets (≥ 44 virtual px wide, ≥ 40 CSS px on a 360px-high phone) around the 40px
   piles: the take area of the side tile, the discard area of "TAŞ AT" (tile + caption) */
.is-phone .pile.can-take .pile-anchor::after { content: ''; position: absolute; inset: -4px -5px -3px; }
.is-phone .pile-0::before { content: ''; position: absolute; left: -2px; right: -2px; top: 0; height: 70px; }
/* yandan (take) left of the ıstaka, attığın (discard) right of it: tile, caption and badge (96px,
   PHONE.pileH) centred on the rack's height */
.is-phone .pile-3,
.is-phone .pile-0 { top: auto; height: 96px; bottom: calc(var(--ph-rack-b) + (var(--rk-h, 120px) - 96px) / 2); }
.is-phone .pile-3 { left: calc(var(--ph-rcx) - var(--rk-w, 588px) / 2 - 4px - var(--ph-pile-w)); }
.is-phone .pile-0 { left: calc(var(--ph-rcx) + var(--rk-w, 588px) / 2 + 4px); }
/* the top piles in the top corners of the board, just inside the side cards; count on the outer side,
   overhanging only 5px (the gap to the card is 6px: the card never covers it) */
.is-phone .pile-2,
.is-phone .pile-1 { top: calc(var(--ph-mid-t) - 2px); height: 58px; }
.is-phone .pile-2 .pile-count,
.is-phone .pile-1 .pile-count { top: 1px; }
.is-phone .pile-1 .pile-count { right: -5px; }
.is-phone .pile-2 .pile-count { left: -5px; right: auto; } /* outer side, the mirror of pile 1 */
.is-phone .pile-2 { left: var(--ph-pile-l); }
.is-phone .pile-1 { left: auto; right: var(--ph-pile-r); }

/* --- hub row: [seat 0] ··· [hint + info] DESTE [deck] [gösterge] GÖSTERGE ··· [action pills] ----
   The deck and the gösterge are centred; the pills' column never shrinks below the pills (then the
   centre moves left), the info chip takes what is left beside the avatar (sizeInfoBlock in ui.js). */
.is-phone .ph-hub {
  position: absolute;
  left: var(--ph-hl);
  right: var(--ph-hr);
  bottom: var(--ph-hub-b);
  height: var(--ph-hub-h);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(max-content, 1fr);
  align-items: center;
  column-gap: 8px;
  z-index: 15;
}
/* Compositor layers that stay for the whole game (a phone rasters the table in full-width strips, so
   any small change painted into it re-rasters a wide band of the screen): the hub row, the ıstaka and
   the two piles beside it are layers of their own. The timer ring, the info chip, the discard
   highlight and a tile landing on a pile re-raster only their own small layer, and the deck / side
   tile glows find the content above them already layered. (transform for the hub row — opacity would
   cut the glass pills' backdrop blur off from the felt; ui.js refreshArt() drops it for one frame
   after a scale change (.stage.rs), so it re-rasters sharp at the new scale.) */
.is-phone .ph-hub { will-change: transform; }
.is-phone .rack-host,
.is-phone .pile-0,
.is-phone .pile-3 { will-change: opacity; }
.stage.rs .ph-hub { will-change: auto; }
.is-phone .ph-hub-l { display: flex; align-items: center; gap: 6px; min-width: 0; height: 100%; }
.is-phone .ph-hub-r { display: flex; align-items: center; justify-content: flex-end; height: 100%; }

/* the deck and the gösterge side by side, their captions outside ("DESTE" left, "GÖSTERGE" right);
   centred over the ıstaka also when a cutout pushes only one end of the hub row (a punch-hole at
   mid-height): the margin moves it back by the difference of the two rows' asymmetries */
.is-phone .ph-hub .hub {
  position: relative;
  left: auto;
  top: auto;
  width: auto;
  height: var(--ph-hub-h);
  margin-left: max(0px, calc(var(--ph-hr) - var(--ph-hl) + var(--ph-rl) - var(--ph-rr)));
  margin-right: max(0px, calc(var(--ph-hl) - var(--ph-hr) - var(--ph-rl) + var(--ph-rr)));
  align-items: center;
  gap: 8px;
  z-index: 6;
}
.is-phone .hub-item { flex-direction: row; align-items: center; gap: 7px; }
.is-phone .hub-item:first-child { flex-direction: row-reverse; }
/* both captions as wide as "GÖSTERGE": the two tiles stay centred over the ıstaka; the deck's count
   is in its caption ("DESTE 17", red when low) instead of a badge sticking out of the row */
.is-phone .hub-cap { min-width: 60px; margin: 0; font-size: 12px; letter-spacing: 0.02em; color: rgba(255, 255, 255, 0.64); }
.is-phone .hub-item:first-child .hub-cap { text-align: right; }
.is-phone .hub-n { display: inline; margin-left: 5px; font: 800 13px var(--font-num); letter-spacing: 0; color: var(--gold); }
.is-phone .hub-n.is-low { color: #ff8f8c; }
.is-phone .deck-count { display: none; }
.is-phone .deck { width: 37px; height: 50px; }
.is-phone .deck::after { content: ''; position: absolute; inset: -6px -8px -6px -6px; }
.is-phone .deck-back { width: 34px; height: 47px; border-radius: 5px; }
.is-phone .deck-back:nth-child(1) { transform: translate(3px, 3px); }
.is-phone .deck-back:nth-child(2) { transform: translate(2px, 2px); }
.is-phone .deck-back:nth-child(3) { transform: translate(1px, 1px); }
.is-phone .deck.can-draw:hover .deck-top { transform: translateY(-3px); }
.is-phone .deck.is-empty::before { width: 34px; height: 47px; border-radius: 6px; }
/* 3px under it (= the deck's stacked backs, 50 − 47): the tile tops line up with the deck */
.is-phone .ind-tile { width: 34px; height: 47px; margin-bottom: 3px; border-radius: 5px; }

/* hint + info chip: two quiet lines on dark glass, no border ("Taş çek: …" / "Açış 0/101 · Çift 0/5 · El 142"),
   next to the deck; one width (250px, or the room beside the avatar) whatever the hint says */
.is-phone .ctl-mid {
  flex: 0 1 250px;
  min-width: 0;
  margin-left: auto;
  height: 44px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 1px;
  padding: 3px 8px;
  border-radius: 12px;
  background: rgba(5, 14, 17, 0.5);
  overflow: hidden;
}
/* my turn (ui.js renderControls): a gold outline — it stays all turn, whatever the hint says */
.is-phone .ctl-mid.is-turn { box-shadow: inset 0 0 0 1.5px rgba(244, 201, 93, 0.85); background: linear-gradient(180deg, rgba(244, 201, 93, 0.18), rgba(244, 201, 93, 0.06)), rgba(5, 14, 17, 0.55); }
.is-phone .ctl-mid .ctl-hint {
  display: block;
  flex: none;
  max-width: 100%;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: 13px;
  line-height: 18px;
}
/* a hint longer than the room (a long name on a narrow phone, a Ceza chip beside the avatar): the
   hint wraps onto two 12.5px lines, the info line below */
.is-phone .ctl-mid.is-tight { padding-top: 1px; padding-bottom: 1px; gap: 0; }
.is-phone .ctl-mid.is-tight .ctl-hint {
  display: -webkit-box;
  height: auto;
  max-height: 28px;
  font-size: 12.5px;
  line-height: 14px;
  white-space: normal;
  text-align: center;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.is-phone .ctl-mid.is-tight .ctl-info { height: 14px; font-size: 12px; line-height: 14px; }
.is-phone .ctl-mid.is-tight .ctl-info b { font-size: 12.5px; }
.is-phone .ctl-mid.is-tight .ci-row { min-height: 14px; }
.is-phone .ctl-mid.is-tight .ci-status,
.is-phone .ctl-mid.is-tight .ci-tag { height: 14px; font-size: 12px; line-height: 14px; }
.is-phone .ctl-mid .ctl-hint.is-mine { color: #ffe6a3; background: none; }
.is-phone .ctl-mid .ctl-hint.is-warn { color: #ffb0a8; background: none; }
/* "Sıra sende!" for 1.5 s at the start of a turn (after .is-mine / .is-tight: it wins) */
.is-phone .ctl-mid .ctl-hint.is-head { font: 800 15px/18px var(--font-display); color: #ffd766; }
.is-phone .ctl-mid .ctl-hint:empty { display: none; }
.is-phone .ctl-mid .ctl-info {
  flex: none;
  flex-direction: row;
  justify-content: center;
  justify-content: safe center; /* overflowing: keep the start (status first) visible */
  gap: 7px;
  max-width: 100%;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: 12.5px;
  line-height: 18px;
}
.is-phone .ctl-info b { font-size: 13.5px; }
/* A narrow chip drops the least important parts first. The width classes come from sizeInfoBlock()
   in ui.js (no container queries / :has(): older WebViews). */
.is-phone .ctl-mid.is-lt330 .ci-tag.is-bad,
.is-phone .ctl-mid.is-lt330 .ci-tag.is-ok { display: none; }
.is-phone .ctl-mid.is-lt240 .ci-row-2,
.is-phone .ci-row-2.is-barrier { display: none; } /* "Baraj · Çift" is in the top strip */
/* "0/101": the denominator quieter; a narrow chip drops it (the top strip shows the baraj) */
.is-phone .ci-den { margin-left: -3px; font-weight: 700; color: rgba(255, 255, 255, 0.62); }
.is-phone .ctl-mid.is-nod .ci-den { display: none; }
.is-phone .ci-row { flex: none; min-height: 18px; gap: 4px; }
/* Priorities of the one info line: a hatalı açılış status comes first (and replaces the çift / el
   part); the baraj ödülü hint comes last and only when there is room. */
.is-phone .ci-row-3 { order: 5; }
.is-phone .ci-row-3.is-alert,
.is-phone .ci-row-3.is-ok { order: -1; }
.is-phone .ctl-info.has-alert .ci-row-2,
.is-phone .ctl-info.has-ok .ci-row-2 { display: none; }
.is-phone .ctl-mid.is-lt520 .ci-row-3.is-bonus { display: none; }
.is-phone .ci-status { height: 18px; padding: 0 6px; font-size: 12.5px; line-height: 18px; }
.is-phone .ci-tag { height: 17px; padding: 0 5px; font-size: 12px; line-height: 17px; }
.is-phone .ci-kept { font-size: 12.5px; }
.is-phone .ci-sep { margin: 0 3px; }

/* contextual actions (İşle, Geri Topla, Geri Bırak, Çifte Dal): pills, shown only while available */
.is-phone .ph-hub-r .ctl-grid { display: flex; gap: 6px; }
.is-phone .ctl-grid.is-empty { display: none; }
.is-phone .btn-sm { height: 44px; padding: 0 14px; gap: 5px; font-size: 15px; border-radius: 22px; }
.is-phone .btn-sm::after { border-radius: 21px 21px 40% 40% / 21px 21px 10px 10px; }
.is-phone .btn-sm.is-wide { grid-column: auto; }
.is-phone .btn-sm .btn-ic { width: 16px; height: 16px; }
.is-phone .btn-sm .btn-num { min-width: 22px; height: 20px; padding: 0 5px; font-size: 13px; line-height: 20px; }
/* pills wider than their half of the row (fitHubRow() in ui.js): no icons */
.is-phone .ph-hub.is-dense .btn-sm { padding: 0 12px; }
.is-phone .ph-hub.is-dense .btn-sm .btn-ic { display: none; }
/* Çifte Dal is a rare, risky choice (it asks for confirmation): a quiet danger outline, not the
   loudest fill on the table — saturated fills are for actions that are ready (Aç, İşle) */
.is-phone .ph-hub-r .btn-dive {
  background: rgba(5, 14, 17, 0.55);
  box-shadow: inset 0 0 0 1px rgba(255, 120, 110, 0.55), 0 4px 10px rgba(0, 0, 0, 0.3);
  color: #ffb0a8;
  text-shadow: none;
  animation: none;
}
.is-phone .ph-hub-r .btn-dive::after { opacity: 0; }
.is-phone .ph-hub-r .btn-dive .btn-ic { color: #ff7a70; }

/* --- rack row: [Seri / Çift Diz] [yandan] ıstaka [attığın] [Aç / Çift Aç] ------------------------
   The two columns sit at the row's ends (bottom corners), each button half the rack high, 50px wide
   with 13px labels on up to two lines ("Seri / Diz", "Per / İndir", "Çift / İşle") and no icons —
   the ıstaka gets the width. A lone Aç / Çift Aç button takes the lower slot (thumb reach, in line
   with Çift Diz). */
.is-phone .ctl-left,
.is-phone .ctl-right {
  top: auto;
  bottom: var(--ph-rack-b);
  height: var(--rk-h, 120px);
  justify-content: center;
  gap: 8px;
}
.is-phone .ctl-left { left: var(--ph-rl); width: var(--ph-col-l); }
.is-phone .ctl-right { left: auto; right: var(--ph-rr); width: var(--ph-col-r); justify-content: flex-end; }
.is-phone .ctl-sort { flex-direction: column; gap: 8px; }
.is-phone .ctl-sort .btn,
.is-phone .ctl-right .btn {
  flex: none;
  width: 100%;
  height: calc((var(--rk-h, 120px) - 8px) / 2);
  min-height: 44px;
  max-height: 58px;
  flex-direction: column;
  gap: 3px;
  padding: 0 2px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.05;
}
.is-phone .ctl-sort .btn::after,
.is-phone .ctl-right .btn::after { border-radius: 13px 13px 40% 40% / 13px 13px 10px 10px; }
.is-phone .ctl-sort .btn .btn-ic { display: none; }
.is-phone .ctl-sort .btn .lbl-x { display: block; } /* "Seri" / "Diz" */
.is-phone .ctl-right .btn-lbl { max-width: 42px; white-space: normal; text-align: center; }
.is-phone .ctl-right .btn-num { min-width: 30px; height: 20px; padding: 0 6px; border-radius: 10px; font-size: 14px; line-height: 20px; }
.is-phone .ctl-right .btn.is-disabled .btn-num { display: none; } /* no meaningless "0" */
.is-phone .btn-pairs > .btn-ic,
.is-phone .btn-open > .btn-ic { display: none; } /* the number chip identifies them */
/* not possible yet: quiet glass in the corner instead of a grey block; they light up (gold / blue)
   as soon as the rack holds a valid opening */
.is-phone .ctl-right .btn.is-disabled {
  filter: none;
  opacity: 1;
  background: rgba(5, 14, 17, 0.4);
  box-shadow: inset 0 0 0 1px rgba(244, 201, 93, 0.2);
  color: rgba(255, 255, 255, 0.46);
  text-shadow: none;
}
.is-phone .ctl-right .btn.is-disabled::after { opacity: 0; }
.is-phone .ctl-right .btn.is-disabled .btn-num { background: rgba(255, 255, 255, 0.07); box-shadow: none; }

/* --- table melds: the big board between the top piles, top strip → hub row ------------------- */
.is-phone .melds-area {
  left: var(--ph-board-l);
  right: var(--ph-board-r);
  top: var(--ph-mid-t);
  bottom: var(--ph-mid-b);
  width: auto;
  height: auto;
  align-items: center;
  align-items: safe center; /* a table fuller than the smallest scale scrolls, never clips */
  overflow-y: auto;
  touch-action: pan-y;
  scrollbar-width: none;
}
.is-phone .melds-area::-webkit-scrollbar { display: none; }
/* a board fuller than the smallest tiles scrolls: the edge with more melds beyond it fades out
   (ui.js updateMeldFade; the newest meld is scrolled into view) */
.is-phone .melds-area.fade-b { -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 16px), transparent); mask-image: linear-gradient(180deg, #000 calc(100% - 16px), transparent); }
.is-phone .melds-area.fade-t { -webkit-mask-image: linear-gradient(180deg, transparent, #000 16px); mask-image: linear-gradient(180deg, transparent, #000 16px); }
.is-phone .melds-area.fade-t.fade-b {
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 16px, #000 calc(100% - 16px), transparent);
  mask-image: linear-gradient(180deg, transparent, #000 16px, #000 calc(100% - 16px), transparent);
}
.is-phone .melds-inner { gap: calc(6px * var(--ms)) calc(10px * var(--ms)); padding: 2px; }
/* one flowing line per owner: [avatar name Açış · 103] meld meld meld … — calm: a faint shade, no border */
.is-phone .meld-group {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(5px * var(--ms)) calc(8px * var(--ms));
  padding: calc(4px * var(--ms)) calc(8px * var(--ms));
  border-color: transparent;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.13);
}
.is-phone .meld-group.is-prov { border-color: rgba(255, 215, 102, 0.7); }
/* a provisional row has one dashed outline: its melds get none of their own (no double dashes) */
.is-phone .meld-group.is-prov .meld.is-prov { outline-color: transparent; }
.is-phone .mg-melds { display: contents; }
/* the owner label keeps a readable size while the tiles shrink to fit: avatar + tag only (the cards
   show the names), so each owner's melds stay on one line */
.is-phone .mg-head { flex: none; height: 18px; gap: 4px; font-size: 13px; }
.is-phone .mg-name { display: none; }
.is-phone .mg-av { width: 18px; height: 18px; }
.is-phone .mg-tag { height: 17px; padding: 0 6px; font-size: 12px; line-height: 17px; }
.is-phone .meld { padding: calc(2px * var(--ms)); border-radius: calc(6px * var(--ms)); }
.is-phone .meld-tile { width: calc(30px * var(--ms)); height: calc(42px * var(--ms)); border-radius: calc(4px * var(--ms)); }

/* --- rack ------------------------------------------------------------------------------------ */
.is-phone .rack-host {
  left: calc(var(--ph-rcx) - var(--rk-w, 588px) / 2);
  top: auto;
  bottom: var(--ph-rack-b);
  width: var(--rk-w, 588px);
  height: var(--rk-h, 120px);
}
.is-phone .rack-shadow { left: 20px; right: 20px; bottom: -6px; height: 24px; filter: blur(10px); }
.is-phone .rack-body { border-radius: 12px 12px 10px 10px; }
/* My turn: a gold frame on the ıstaka's rim (ui.js RackView), also the turn clock — a fuse that burns
   from the bottom centre outward, up the sides and along the top toward its centre (under the deck).
   A layer of its own above the slots, under the tiles; it changes by opacity (on / flashes / the last
   5 s breathing) and its pieces by transform (scaleX / scaleY, written by the clock's own steps —
   no transition: a running transform animation makes Chrome assume it overlaps everything painted
   after the rack and composite that too, and keeps the page drawing every frame all turn); the
   corners are quarter arcs of the body's radii that fade out. The burnt part (the track) is dim so
   what is left stands out; at ≤ 5 s the track and its halo turn brighter and red. The stage colours
   stay while an ended turn's frame fades out; only an "on" frame breathes (rkPulse would override
   the fade). Desktop: the avatar ring is the clock. */
.rk-turn { display: none; }
.is-phone .rk-turn { display: block; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 0.25s ease; will-change: opacity; --rk-c: #ffd766; }
.is-phone .rk-turn.is-on { opacity: 1; }
.is-phone .rk-turn.is-start { animation: rkTurnIn 0.9s ease-out; }
.is-phone .rk-turn.is-soon { --rk-c: #ff9f43; }
.is-phone .rk-turn.is-urgent { --rk-c: #ff5a50; }
.is-phone .rk-turn.is-on.is-urgent { animation: rkPulse 0.8s ease-in-out infinite; }
.rk-trk { position: absolute; inset: 0; border: 3px solid rgba(255, 226, 150, 0.26); border-radius: 12px 12px 10px 10px; box-shadow: 0 0 0 1px rgba(255, 215, 102, 0.32), 0 0 10px 2px rgba(255, 215, 102, 0.4); }
.is-phone .rk-turn.is-urgent .rk-trk { border-color: rgba(255, 140, 130, 0.5); box-shadow: 0 0 0 1px rgba(255, 110, 100, 0.85), 0 0 14px 4px rgba(239, 83, 80, 0.6); }
.rk-f { position: absolute; background: var(--rk-c); will-change: transform; }
.rk-tl { left: 12px; right: 50%; top: 0; height: 3px; transform-origin: 100% 50%; }
.rk-tr { left: 50%; right: 12px; top: 0; height: 3px; transform-origin: 0 50%; }
.rk-l { left: 0; top: 12px; bottom: 10px; width: 3px; transform-origin: 50% 0; }
.rk-r { right: 0; top: 12px; bottom: 10px; width: 3px; transform-origin: 50% 0; }
.rk-bl { left: 10px; right: 50%; bottom: 0; height: 3px; transform-origin: 0 50%; }
.rk-br { left: 50%; right: 10px; bottom: 0; height: 3px; transform-origin: 100% 50%; }
.rk-c { position: absolute; border: 0 solid var(--rk-c); will-change: opacity; transition: opacity 0.15s linear; }
.rk-c.is-off { opacity: 0; }
.rk-ctl { left: 0; top: 0; width: 12px; height: 12px; border-width: 3px 0 0 3px; border-top-left-radius: 12px; }
.rk-ctr { right: 0; top: 0; width: 12px; height: 12px; border-width: 3px 3px 0 0; border-top-right-radius: 12px; }
.rk-cbl { left: 0; bottom: 0; width: 10px; height: 10px; border-width: 0 0 3px 3px; border-bottom-left-radius: 10px; }
.rk-cbr { right: 0; bottom: 0; width: 10px; height: 10px; border-width: 0 3px 3px 0; border-bottom-right-radius: 10px; }
@keyframes rkTurnIn { 0%, 45%, 100% { opacity: 1; } 22%, 68% { opacity: 0.25; } }
@keyframes rkPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
.is-phone .rack-ledge { left: 4px; right: 4px; height: 10px; border-radius: 2px 2px 6px 6px; box-shadow: inset 0 3px 0 rgba(255, 228, 180, 0.14), inset 0 -2px 2px rgba(0, 0, 0, 0.5), 0 3px 5px rgba(0, 0, 0, 0.4); }
.is-phone .rack-ledge::before { height: 2px; }
.is-phone .rack-ledge-front { left: 0; right: 0; border-radius: 2px 2px 10px 10px; }
.is-phone .rack-cap { top: 6px; bottom: 6px; width: 3px; }
.is-phone .rack-cap-l { left: 1px; }
.is-phone .rack-cap-r { right: 1px; }
.is-phone .rack-slot { border-radius: 5px; }
.is-phone .rack-tile-face { border-radius: 5px; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.38), 0 1px 1px rgba(0, 0, 0, 0.3); }
.is-phone .rack-tile:hover .rack-tile-in { transform: translateY(-3px); }
.is-phone .rack-tile.is-sel .rack-tile-in { transform: translateY(-9px); }
.is-phone .rack-tile.is-partner .rack-tile-in { transform: translateY(-5px); }
.is-phone .rack-glow { border-radius: 8px; }
.is-phone .rack-badge { height: 16px; padding: 0 6px; border-radius: 8px; font-size: 12px; line-height: 16px; }
.is-phone .rack-drop { border-radius: 6px; box-shadow: 0 0 0 2px #ffd766, 0 0 14px rgba(255, 215, 102, 0.7); }
.is-phone .rack-tile-mark { right: -3px; top: -4px; width: 16px; height: 16px; font-size: 13px; }
.is-phone .rack-tile.is-swap .rack-tile-mark { font-size: 12px; }
.is-phone .rack-tile-tag { left: -3px; top: -6px; height: 16px; padding: 0 4px; font-size: 12px; line-height: 16px; }
.is-phone .drag-ghost .g-face { border-radius: 5px; }
.is-phone .fly-tile { border-radius: 5px; }

/* --- banner, log drawer, toasts --------------------------------------------------------------- */
/* banners: centred on the meld board */
.is-phone .banner-host { width: 100%; height: 100%; }
.is-phone .banner { left: var(--ph-mcx); top: var(--ph-mid-c); }
.is-phone .banner::before { width: 480px; height: 100px; }
.is-phone .banner-main { font-size: 44px; }
.is-phone .banner-sub { margin-top: 4px; font-size: 16px; }
.is-phone .banner.is-compact { top: calc(var(--ph-mid-c) + 16px); }
.is-phone .banner.is-compact::before { width: 280px; height: 64px; }
.is-phone .banner.is-compact .banner-main { font-size: 30px; }

/* the drawer reaches the screen edge; its content stays out of a cutout / bar on that side */
.is-phone .log-panel {
  left: auto;
  right: 0;
  top: 0;
  width: calc(min(380px, 58%) + var(--sa-r));
  height: 100%;
  padding: var(--sa-t) var(--sa-r) var(--sa-b) 0;
  border-radius: 16px 0 0 16px;
  transform: translateX(105%);
}
.is-phone .log-panel.is-open { transform: none; }
.is-phone .log-head { padding: 4px 4px 4px 14px; font-size: 18px; }
.is-phone .log-head .icon-btn { width: 44px; height: 44px; }
.is-phone .log-list { padding: 6px 8px 10px; }
.is-phone .log-item { padding: 4px 8px 4px 10px; font-size: 14px; line-height: 1.3; }
.is-phone .log-sep { margin: 8px 0 4px; font-size: 13px; }
.is-phone .log-empty { font-size: 14px; }

/* toasts: compact, at the bottom edge of the meld board (the newest lowest; the rows at its top — the
   first openings, the top player's flash — stay readable), never over the rack or the buttons, and
   under an open dialog (the modal layer is z-index 80). At most two (ui.js Toasts), the older dimmed. */
.is-phone .toast-layer {
  z-index: 79;
  left: var(--ph-mcx);
  top: auto;
  bottom: calc(var(--ph-mid-b) + 2px);
  width: calc(100% - var(--ph-board-l) - var(--ph-board-r));
  max-height: calc(var(--sh, 390px) - var(--ph-mid-t) - var(--ph-mid-b) - 2px);
  justify-content: flex-end;
  overflow: hidden;
  padding: 4px 0 6px;
  gap: 4px;
}
.is-phone .toast {
  max-width: min(100%, 480px);
  gap: 7px;
  padding: 5px 12px 5px 9px;
  border-radius: 11px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
  font-size: 13px;
  line-height: 1.3;
  animation-fill-mode: backwards; /* (the older one's dimming below is not overridden) */
}
.is-phone .toast.is-out { animation-fill-mode: forwards; }
.is-phone .toast:not(:last-child):not(.is-out) { opacity: 0.6; }
.is-phone .toast-txt { display: -webkit-box; overflow: hidden; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }
.is-phone .toast-ic { width: 16px; height: 16px; }

/* --- dialogs ------------------------------------------------------------------------------------ */
/* the backdrop covers the whole screen, the dialog is centred in the safe area */
.is-phone .modal-wrap { padding: var(--sa-t) var(--sa-r) var(--sa-b) var(--sa-l); }
.is-phone .modal { max-width: calc(100% - 16px); max-height: calc(100% - 12px); border-radius: 16px; }
.is-phone .modal::before { left: 24px; right: 24px; }
.is-phone .modal-sm { width: 470px; }
.is-phone .modal-md { width: 620px; }
.is-phone .modal-lg,
.is-phone .modal-xl { width: calc(100% - 16px); }
.is-phone .modal-head { gap: 8px; padding: 6px 6px 2px 16px; }
.is-phone .modal-ic { width: 22px; height: 22px; }
.is-phone .modal-title { font-size: 21px; }
.is-phone .modal-body { padding: 4px 16px 8px; font-size: 15px; line-height: 1.45; }
/* more content below (ui.js Modals): the body fades out at its bottom edge — it reads as "scroll" */
.is-phone .modal-body.fade-b {
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(180deg, #000 calc(100% - 24px), transparent);
}
.is-phone .modal-foot { gap: 8px; padding: 6px 16px 10px; }
.is-phone .modal-foot .btn { min-width: 110px; height: 44px; padding: 0 16px; font-size: 17px; }
/* one plain Tamam / Kapat / Anladım button: the header's × does the same, the content gets the room */
.is-phone .modal.has-plain-close .modal-foot { display: none; }
.is-phone .modal.has-plain-close .modal-body { padding-bottom: 14px; }
.is-phone .modal-msg { font-size: 16px; line-height: 1.45; }
.is-phone .confirm-tile { margin: 0 0 8px; }
.is-phone .confirm-tile .ct-tile { width: 44px; height: 62px; border-radius: 6px; }
.is-phone .confirm-reasons li { margin: 2px 0; }
.is-phone .confirm-tip { margin-top: 8px; padding: 6px 10px; font-size: 14px; }
.is-phone .confirm-list { gap: 4px; }
.is-phone .confirm-list li { font-size: 15px; }
.is-phone .pm-grid { gap: 8px; }
.is-phone .pm-grid .btn { height: 46px; font-size: 17px; }

.is-phone .set-grid { grid-template-columns: 210px 1fr; gap: 16px; }
.is-phone .set-col { gap: 6px; }
.is-phone .set-row { min-height: 46px; gap: 10px; }
.is-phone .set-row-col { gap: 5px; }
.is-phone .set-lbl { font-size: 15px; }
.is-phone .set-lbl small { font-size: 12px; }
.is-phone .set-input { height: 44px; font-size: 16px; }
.is-phone .av-grid { gap: 8px; }
.is-phone .seg { padding: 2px; gap: 2px; border-radius: 12px; }
.is-phone .seg-btn { min-width: 44px; height: 44px; padding: 0 9px; font-size: 15px; }
.is-phone .switch { width: 56px; height: 32px; border-radius: 16px; }
.is-phone .switch::after { content: ''; position: absolute; inset: -7px -4px; }
.is-phone .switch-knob { width: 24px; height: 24px; }
.is-phone .switch.is-on .switch-knob { transform: translateX(24px); }
.is-phone .set-note { margin-top: 10px; padding: 7px 10px; font-size: 13px; }
.is-phone .set-note.set-note-top { margin: 0 0 8px; padding: 5px 10px; }

.is-phone .tabs { gap: 4px; padding: 3px; margin-bottom: 10px; }
.is-phone .tab { height: 44px; padding: 0 14px; font-size: 15px; }
.is-phone .rules-group-title { margin: 12px 0 8px; font-size: 17px; }
.is-phone .rules-grid { gap: 8px; }
.is-phone .rule-card { padding: 10px 12px; border-radius: 12px; }
.is-phone .rule-card h4 { font-size: 15px; }
.is-phone .rule-card p { font-size: 14px; line-height: 1.45; }
.is-phone .data-table { font-size: 14px; }
.is-phone .data-table th { padding: 7px 8px; font-size: 12px; }
.is-phone .data-table th .sb-player { font-size: 14px; }
.is-phone .data-table td { padding: 6px 8px; }
.is-phone .data-table td small { font-size: 12px; }
.is-phone .help-list { gap: 8px; }
.is-phone .help-list li { padding: 10px 12px 10px 44px; font-size: 14px; line-height: 1.45; }
.is-phone .help-list li b { font-size: 15px; }
.is-phone .help-list li .hl-ic { left: 12px; top: 12px; width: 22px; height: 22px; }
.is-phone .rulebook { font-size: 14.5px; line-height: 1.55; }
.is-phone .rulebook .rb-title { font-size: 21px; }
.is-phone .rulebook .rb-h { margin: 16px 0 6px; font-size: 17px; }
.is-phone .rulebook .rb-h4 { font-size: 15px; }
.is-phone .rulebook .rb-toc-btn { height: 40px; padding: 0 12px; border-radius: 20px; font-size: 13.5px; }
.is-phone .rulebook .rb-note { font-size: 12px; }
.is-phone .rulebook code { font-size: 13px; }

.is-phone .sb-av { width: 24px; height: 24px; }
.is-phone .sb-total td.num { font-size: 16px; }
/* round result: a one-line banner, the remaining tiles as small minis (12 a line: an unopened
   21-tile hand takes 2 lines; a short hand's "El değeri" note on the same line), the numeric
   columns stay narrow, the header row sticks — four rows fit a 360px-high phone */
.is-phone .rr-banner { gap: 10px; margin-bottom: 6px; padding: 5px 10px; border-radius: 12px; }
.is-phone .rr-banner > div:last-child { display: flex; flex-wrap: wrap; align-items: center; column-gap: 10px; }
.is-phone .rr-av { width: 36px; height: 36px; box-shadow: 0 0 0 2px var(--gold), 0 0 12px rgba(244, 201, 93, 0.5); }
.is-phone .rr-ic { width: 32px; height: 32px; }
.is-phone .rr-title { font-size: 19px; }
.is-phone .rr-chips { gap: 5px; margin-top: 0; }
.is-phone .chip { height: 22px; padding: 0 8px; border-radius: 11px; font-size: 12.5px; }
.is-phone .rr-table th { padding: 6px; white-space: normal; line-height: 1.15; position: sticky; top: -4px; z-index: 2; background: #10252b; }
.is-phone .rr-table td { padding: 5px 6px; }
.is-phone .rr-table td small { line-height: 1.25; }
.is-phone .rr-table .chip { white-space: nowrap; }
.is-phone .rr-handcell { display: flex; flex-wrap: wrap; align-items: center; column-gap: 7px; row-gap: 1px; max-width: 196px; }
.is-phone .rr-hand { gap: 1px; max-width: 180px; }
.is-phone .rr-mini { width: 14px; height: 20px; border-radius: 2px; }
.is-phone .rr-pen { min-width: 92px; }
.is-phone .rr-ledger li { gap: 6px; font-size: 12.5px; white-space: normal; }
.is-phone .rr-ledger li b { font-size: 13px; white-space: nowrap; }
.is-phone .rr-pen-sum { font-size: 13.5px; }
.is-phone .rr-trophy { width: 16px; height: 16px; }
.is-phone .rr-note { margin-top: 8px; }

.is-phone .podium { gap: 10px; min-height: 0; margin: 0 0 10px; }
.is-phone .pod { width: 130px; }
.is-phone .pod-av,
.is-phone .pod-2 .pod-av,
.is-phone .pod-3 .pod-av { width: 52px; height: 52px; }
.is-phone .pod-1 .pod-av,
.is-phone .pod.pod-r1 .pod-av { width: 64px; height: 64px; }
.is-phone .pod-crown { width: 26px; height: 26px; }
.is-phone .pod-name { max-width: 124px; margin-top: 4px; font-size: 15px; }
.is-phone .pod-score { font-size: 14px; }
.is-phone .pod-step { margin-top: 4px; padding-top: 4px; font-size: 26px; }
.is-phone .pod-1 .pod-step, .is-phone .pod.pod-r1 .pod-step { height: 56px; }
.is-phone .pod-2 .pod-step, .is-phone .pod.pod-r2 .pod-step { height: 40px; }
.is-phone .pod-3 .pod-step, .is-phone .pod.pod-r3 .pod-step { height: 28px; }
.is-phone .mr-sub { margin: 0 0 8px; font-size: 15px; }
.is-phone .pile-hist .ph-tile { width: 32px; height: 45px; }

/* --- main menu ------------------------------------------------------------------------------------ */
.is-phone .menu-main {
  z-index: 1;
  left: var(--sa-l);
  right: var(--sa-r);
  top: var(--sa-t);
  bottom: var(--sa-b);
  width: auto;
  height: auto;
  transform: none;
  display: grid;
  grid-template-columns: auto 300px;
  grid-template-rows: auto auto;
  column-gap: 36px;
  align-content: center;
  justify-content: center;
  align-items: center;
  justify-items: center;
  pointer-events: none; /* the full-size grid must not cover the profile pill and the version label */
}
.is-phone .menu-main > * { pointer-events: auto; }
/* logo 392 + gap 36 + buttons 300 = 728: fits the narrowest content box (PHONE.minW 760) */
.is-phone .menu-logo { grid-column: 1; grid-row: 1; width: 392px; height: 112px; }
.is-phone .menu-logo-in > svg { filter: drop-shadow(0 10px 16px rgba(0, 0, 0, 0.5)); }
.is-phone .menu-tag { grid-column: 1; grid-row: 2; align-self: start; margin-top: 8px; font-size: 15px; letter-spacing: 0.14em; }
.is-phone .menu-btns { grid-column: 2; grid-row: 1 / span 2; width: 300px; margin-top: 0; gap: 10px; }
.is-phone .btn-xl { height: 58px; padding: 0 22px; border-radius: 16px; font-size: 24px; }
.is-phone .btn-lg { height: 48px; padding: 0 16px; border-radius: 14px; font-size: 18px; }
.is-phone .btn-lg .btn-ic,
.is-phone .btn-xl .btn-ic { width: 22px; height: 22px; }
.is-phone .menu-row { gap: 10px; }
.is-phone .menu-profile { left: var(--ph-tl); top: calc(var(--ph-t) + 4px); gap: 10px; padding: 4px 16px 4px 4px; }
.is-phone .mp-av { width: 42px; height: 42px; box-shadow: 0 0 0 2px var(--gold), 0 3px 8px rgba(0, 0, 0, 0.4); }
.is-phone .mp-name { font-size: 17px; }
.is-phone .mp-sub { font-size: 13px; }
.is-phone .menu-foot { z-index: 2; right: calc(var(--ph-br) + 4px); bottom: calc(var(--ph-b) + 6px); font-size: 12.5px; }
.is-phone .menu-hint { z-index: 2; left: calc(var(--ph-bl) + 4px); bottom: calc(var(--ph-b) + 6px); font-size: 12.5px; }
.is-phone .menu-profile { z-index: 2; }
.is-phone .menu-hint .mh-desk { display: none; }
.is-phone .menu-hint .mh-touch { display: inline; }
.is-phone .float-tile { width: 42px; height: 59px; opacity: calc(var(--o, 0.9) * 0.65); }
/* no floating tile under the hint / version text or behind the translucent menu buttons */
.is-phone .float-tile.ft-busy { display: none; }
/* the phone stage's own background is rim wood (for the table's corners); the menu keeps the
   desktop's teal felt so the logo's walnut rack stands out */
.is-phone .menu-bg { background: radial-gradient(120% 95% at 40% 42%, #153a41 0%, #0b2127 46%, #050d10 100%); }
.is-phone .menu-halo { top: 45%; left: 32%; width: 820px; height: 540px; margin: -270px 0 0 -410px; }

/* --- touch: no text selection / callouts, no sticky hover lifts -------------------------------------- */
.is-phone .modal-body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.is-phone .modal-body .set-input { -webkit-user-select: text; user-select: text; }
@media (hover: none) and (pointer: coarse) {
  .modal-body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
  .modal-body .set-input { -webkit-user-select: text; user-select: text; }
  .rack-tile:hover:not(.is-sel):not(.is-partner) .rack-tile-in { transform: none; }
  .deck.can-draw:hover .deck-top { transform: none; }
}

/* --- diagnostics overlay (ui.js Diag: 5 taps on the menu's version label, or ?debug=1) ----------------
   Outside the stage, in CSS px: a text panel + guides over the whole screen. */
.menu-foot { padding: 6px 0 6px 10px; margin: -6px 0; } /* a finger-sized target for the 5 taps */
.dbg-guides { position: fixed; left: 0; top: 0; right: 0; bottom: 0; z-index: 2147482000; pointer-events: none; }
.dbg-guides > div { position: absolute; box-sizing: border-box; }
.dbg-safe { border: 2px dashed rgba(0, 229, 255, 0.9); }
.dbg-cut { background: rgba(255, 40, 40, 0.45); border: 1px solid #ff3b3b; }
.dbg-row { border-left: 2px solid rgba(255, 200, 60, 0.95); border-right: 2px solid rgba(255, 200, 60, 0.95); background: rgba(255, 200, 60, 0.07); }
.dbg-panel {
  position: fixed;
  left: 50%;
  top: 6px;
  z-index: 2147482001;
  width: 640px;
  max-width: calc(100% - 140px);
  max-height: calc(100% - 12px);
  overflow: auto;
  transform: translateX(-50%);
  border-radius: 10px;
  background: rgba(3, 10, 12, 0.86);
  border: 1px solid rgba(0, 229, 255, 0.6);
  color: #e8fbff;
  font: 11px/1.35 ui-monospace, 'Roboto Mono', 'Droid Sans Mono', monospace;
  -webkit-user-select: text;
  user-select: text;
  touch-action: pan-y;
}
.dbg-bar { display: flex; align-items: center; gap: 6px; padding: 5px 6px 5px 10px; border-bottom: 1px solid rgba(0, 229, 255, 0.3); }
.dbg-bar b { margin-right: auto; color: #7fefff; font-weight: 700; }
.dbg-bar button { min-width: 44px; height: 30px; padding: 0 10px; border-radius: 8px; border: 1px solid rgba(0, 229, 255, 0.5); background: rgba(0, 229, 255, 0.12); color: #e8fbff; font: 700 12px/1 system-ui, sans-serif; }
.dbg-text { margin: 0; padding: 6px 10px 8px; white-space: pre-wrap; word-break: break-word; font: inherit; }
.dbg-panel.is-folded .dbg-text { display: none; }

/* ======================================================================================
   20. Online (v2.5.0, docs/SPEC_ONLINE.md §5.5 / §5.6) — dialogs and drawers only: nothing here
   takes room on the table while playing offline. js/ui/online.js builds the dialogs, the chat
   drawer and the reconnect overlay; js/ui/ui.js the chat button, seat marks and bubbles.
   ====================================================================================== */
/* --- top bar: the chat button (phone: next to ≡; desktop: after the icons, css order) --- */
.tb-chat { order: 1; }
.tb-chat .tb-dot {
  position: absolute;
  right: 5px;
  top: 5px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 0 2px #0a1b1f, 0 0 10px rgba(239, 83, 80, 0.8);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 0.2s, transform 0.25s var(--ease-spring);
  pointer-events: none;
}
.tb-chat.has-unread .tb-dot { opacity: 1; transform: none; }
.is-phone .tb-chat { order: 0; }

/* --- seats: presence mark and the "BOT" tag on the avatar (no new rows) --- */
.seat-presence {
  position: absolute;
  right: 6px;
  top: 6px;
  z-index: 3;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 2px #0a1b1f;
  display: none;
}
.seat-presence.is-on { display: block; }
.seat-presence.is-off { background: #7f8c8d; box-shadow: 0 0 0 2px #0a1b1f, 0 0 0 4px rgba(239, 83, 80, 0.8); }
.seat-bottag {
  position: absolute;
  left: 50%;
  bottom: -4px;
  z-index: 3;
  transform: translateX(-50%);
  padding: 1px 7px;
  border-radius: 8px;
  background: #1c3036;
  border: 1px solid var(--gold-hair);
  font: 800 11px/1.3 var(--font-num);
  letter-spacing: 0.08em;
  color: var(--gold);
  display: none;
}
.seat-bottag.is-on { display: block; }
.seat-0 .seat-bottag { bottom: 16px; }
.seat.is-away .seat-av-img { filter: grayscale(0.85) brightness(0.8); }
/* phone: the tile-count chip sits on the avatar's top-right and the name under it — the mark goes to
   the bottom-left, the tag to the top-left corner */
.is-phone .seat-presence { left: 0; bottom: 0; right: auto; top: auto; width: 11px; height: 11px; }
.is-phone .seat-bottag { left: -9px; top: -6px; bottom: auto; transform: none; padding: 0 4px; font-size: 12px; line-height: 1.15; border-radius: 7px; }
.is-phone .seat-0 .seat-bottag { left: -9px; top: -6px; bottom: auto; }
/* the server's turn clock: every seat on turn shows a countdown ring (no spinner for bots) */
.screen-game.is-net .seat-bot.is-active .seat-ring {
  background: conic-gradient(var(--ring-c, #3ddc97) calc(var(--p, 1) * 360deg), rgba(255, 255, 255, 0.12) 0);
  animation: none;
}
/* phone: the small ring's spent part on a dark track (a light one read as "full" over the avatar) */
.is-phone .screen-game.is-net .seat-bot.is-active .seat-ring { background: conic-gradient(var(--ring-c, #3ddc97) calc(var(--p, 1) * 360deg), rgba(3, 10, 12, 0.62) 0); }

/* --- chat bubbles: longer text wraps, the bubble stays as long as the message needs --- */
.seat-bubble.b-chat {
  white-space: normal;
  width: max-content;
  max-width: 250px;
  line-height: 1.2;
  background: linear-gradient(180deg, #f2f8ff, #d7e8fb);
  color: #0f2a45;
  animation: bubbleChat var(--bd, 5s) var(--ease-out) forwards;
}
.seat-bubble.b-chat::after { background: #e2eefc; }
@keyframes bubbleChat {
  0% { opacity: 0; transform: var(--bt, translateX(0)) scale(0.6); }
  5% { opacity: 1; transform: var(--bt, translateX(0)) scale(1.04); }
  9% { transform: var(--bt, translateX(0)) scale(1); }
  93% { opacity: 1; }
  100% { opacity: 0; transform: var(--bt, translateX(0)) scale(0.97); }
}
.is-phone .seat-bubble.b-chat { max-width: 200px; font-size: 13px; }

/* --- settings: rows the online table decides --- */
.set-row.is-locked { opacity: 0.45; cursor: not-allowed; }
.set-row.is-locked .seg { pointer-events: none; }

/* --- round result: "Sonraki el N sn sonra" --- */
.rr-break { margin-top: 8px; text-align: center; font: 700 15px var(--font-body); color: var(--ink-dim); }
.rr-break:empty { display: none; }

/* --- dialogs: chooser, nickname, lobby flow --- */
.oc-grid { display: flex; flex-direction: column; gap: 10px; }
.oc-opt {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 76px;
  padding: 10px 18px;
  border-radius: 16px;
  border: 1px solid var(--gold-hair);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.03));
  text-align: left;
  cursor: pointer;
  transition: transform 0.14s var(--ease-out), border-color 0.2s, background 0.2s;
}
.oc-opt:hover { transform: translateY(-1px); border-color: var(--gold-hair-strong); background: linear-gradient(180deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.05)); }
.oc-opt:active { transform: translateY(1px) scale(0.99); }
.oc-ic {
  width: 48px;
  height: 48px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 14px;
  background: linear-gradient(180deg, #ffe596, #d98c16);
  color: #3d2400;
}
.oc-ic svg { width: 28px; height: 28px; }
.oc-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.oc-txt b { font: 800 22px/1.15 var(--font-display); color: #fff; }
.oc-txt small { font: 600 14px/1.3 var(--font-body); color: var(--ink-dim); }
.oc-test { display: flex; align-items: center; gap: 8px; margin-top: 12px; font: 700 13px var(--font-body); color: #8fe8ff; }
.oc-test svg { width: 16px; height: 16px; flex: none; }
.oc-server { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--gold-hair); }
.oc-server-row { display: flex; gap: 6px; margin-top: 6px; }
.oc-server-row .set-input { flex: 1; min-width: 0; height: 38px; font-size: 14px; }

.og-lead { font: 700 18px/1.4 var(--font-body); margin-bottom: 10px; }
.og-name { width: 100%; }
.og-err { min-height: 20px; margin: 4px 2px 6px; font: 700 14px/1.35 var(--font-body); color: #ff8f8c; }
.og-av { grid-template-columns: repeat(8, 1fr); gap: 8px; }

.of-body { display: flex; flex-direction: column; gap: 10px; }
.of-wait { display: flex; align-items: center; justify-content: center; gap: 14px; min-height: 90px; font: 700 18px var(--font-body); color: var(--ink); }
.of-spin {
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  border: 3px solid rgba(244, 201, 93, 0.22);
  border-top-color: var(--gold);
  animation: spin 0.9s linear infinite;
}
.of-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }
.of-foot .btn { min-width: 130px; }
.of-foot .btn:disabled { filter: grayscale(0.9) brightness(0.62); opacity: 0.62; cursor: not-allowed; }

.op-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.op-col { display: flex; flex-direction: column; gap: 10px; padding: 12px; border-radius: 14px; background: rgba(0, 0, 0, 0.22); border: 1px solid rgba(255, 255, 255, 0.06); }
.op-h { font: 800 19px var(--font-display); color: var(--gold); }
.op-row { display: flex; flex-direction: column; gap: 5px; }
.op-row .seg { flex-wrap: wrap; width: max-content; max-width: 100%; }
.op-row .seg-btn { min-width: 40px; padding: 0 8px; }
.op-code { width: 100%; text-align: center; letter-spacing: 0.3em; text-transform: uppercase; font: 800 24px var(--font-num); }
.op-err { min-height: 18px; margin: 0; }
.op-go { width: 100%; margin-top: auto; }
.op-go:disabled { filter: grayscale(0.9) brightness(0.62); opacity: 0.62; }

.wr-code-box { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 10px 14px; border-radius: 14px; background: rgba(244, 201, 93, 0.08); border: 1px solid var(--gold-hair); }
.wr-code-lbl { font: 700 14px var(--font-body); color: var(--ink-dim); }
.wr-code {
  font: 800 38px/1 var(--font-num);
  letter-spacing: 0.22em;
  color: #fff3c9;
  -webkit-user-select: all;
  user-select: all;
  cursor: text;
}
.wr-code-btns { display: flex; gap: 8px; margin-left: auto; }
.wr-seats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.wr-seat { display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 0; --seat-c: var(--gold); }
.wr-av {
  width: 74px;
  height: 74px;
  border-radius: 50%;
  overflow: hidden;
  background: radial-gradient(circle at 50% 35%, #2b525a, #0f2429);
  box-shadow: 0 0 0 3px var(--seat-c), 0 6px 14px rgba(0, 0, 0, 0.45);
  animation: modalIn 0.34s var(--ease-spring) backwards;
}
.wr-av > svg { width: 100%; height: 100%; }
.wr-seat.is-empty .wr-av { background: rgba(255, 255, 255, 0.04); box-shadow: none; border: 2px dashed rgba(255, 255, 255, 0.22); animation: none; }
.wr-seat.is-off .wr-av { filter: grayscale(0.9) brightness(0.7); }
.wr-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 800 15px var(--font-display); color: #fff; }
.wr-seat.is-empty .wr-name { color: var(--ink-mute); font-weight: 700; }
.wr-seat.is-me .wr-name { color: var(--gold); }
.wr-host { font: 700 12px var(--font-body); color: var(--gold); }
.wr-host.is-off { color: #ff8f8c; }
.wr-note { min-height: 22px; text-align: center; font: 700 15px/1.4 var(--font-body); color: var(--ink-dim); }

/* --- the chat drawer (like the log drawer) --- */
.chat-panel {
  position: absolute;
  left: 1190px;
  top: 66px;
  width: 398px;
  height: 560px;
  z-index: 65; /* above the fx layer (60) and the log drawer; under the reconnect overlay (70) */
  display: flex;
  flex-direction: column;
  border-radius: 18px;
  background: var(--glass-strong);
  border: 1px solid var(--gold-hair);
  box-shadow: var(--shadow-lg);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transform: translateX(440px);
  opacity: 0;
  visibility: hidden;
  transition: transform 0.35s var(--ease-out), opacity 0.3s, visibility 0.35s;
}
.chat-panel.is-open { transform: none; opacity: 1; visibility: visible; }
.chat-head { gap: 8px; }
.chat-tabs { margin-left: auto; padding: 3px; }
.chat-tabs .seg-btn { height: 32px; min-width: 0; padding: 0 10px; font-size: 14px; }
.chat-head .icon-btn { margin-left: 0; }
.chat-page { display: none; flex: 1; min-height: 0; flex-direction: column; }
.chat-page.is-on { display: flex; }
.chat-list { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 10px; touch-action: pan-y; display: flex; flex-direction: column; gap: 4px; scrollbar-width: thin; scrollbar-color: rgba(244, 201, 93, 0.4) transparent; }
.chat-msg {
  align-self: flex-start;
  max-width: 88%;
  padding: 5px 10px 6px;
  border-radius: 4px 12px 12px 12px;
  background: rgba(255, 255, 255, 0.06);
  border-left: 3px solid var(--c, var(--gold));
  font: 600 14px/1.35 var(--font-body);
  color: var(--ink);
  overflow-wrap: anywhere;
  -webkit-user-select: text;
  user-select: text;
}
.chat-msg b { display: block; font: 800 12px var(--font-display); color: var(--c, var(--gold)); letter-spacing: 0.02em; }
.chat-msg.is-me { align-self: flex-end; border-left: 0; border-right: 3px solid var(--c, var(--gold)); border-radius: 12px 4px 12px 12px; background: rgba(244, 201, 93, 0.1); }
.chat-empty { padding: 24px 10px; text-align: center; color: var(--ink-mute); font: 600 14px var(--font-body); }
.chat-phrases { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 10px 4px; border-top: 1px solid rgba(255, 255, 255, 0.07); }
.chat-phrase {
  height: 32px;
  padding: 0 11px;
  border-radius: 16px;
  border: 1px solid var(--gold-hair);
  background: rgba(255, 255, 255, 0.07);
  font: 700 13px var(--font-body);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
}
.chat-phrase:hover { background: rgba(255, 255, 255, 0.14); }
.chat-phrase:active { transform: scale(0.97); }
.chat-form { display: flex; align-items: center; gap: 6px; padding: 6px 10px 10px; }
.chat-input { flex: 1; min-width: 0; height: 42px; font-size: 16px; }
.chat-count { flex: none; font: 700 12px var(--font-num); color: var(--ink-mute); min-width: 44px; text-align: right; }
.chat-send { width: 42px; height: 42px; color: var(--gold); }
.chat-people { overflow-y: auto; padding: 8px 14px 12px; gap: 6px; }
.cp-h { font: 800 15px var(--font-display); color: var(--gold); margin: 4px 0 2px; }
.cp-row { min-height: 44px; }
.cp-hide { margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--gold-hair); }

/* --- reconnect overlay (over the game screen while the connection is down) --- */
.net-overlay {
  position: absolute;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(3, 10, 12, 0.62);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s, visibility 0.25s;
}
.net-overlay.is-on { opacity: 1; visibility: visible; }
.no-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 24px 30px;
  border-radius: 20px;
  background: var(--glass-strong);
  border: 1px solid var(--gold-hair);
  box-shadow: var(--shadow-lg);
  text-align: center;
}
.no-box .of-spin { width: 40px; height: 40px; }
.no-text { font: 800 20px/1.35 var(--font-display); color: #fff; max-width: 420px; }
.no-sub { min-height: 18px; font: 700 14px var(--font-body); color: var(--ink-dim); }

/* --- phone --- */
.is-phone .oc-grid { gap: 8px; }
.is-phone .oc-opt { min-height: 60px; gap: 12px; padding: 6px 12px; border-radius: 14px; }
.is-phone .oc-ic { width: 40px; height: 40px; border-radius: 12px; }
.is-phone .oc-ic svg { width: 22px; height: 22px; }
.is-phone .oc-txt b { font-size: 18px; }
.is-phone .oc-txt small { font-size: 12.5px; }
.is-phone .og-lead { font-size: 15px; margin-bottom: 6px; }
.is-phone .og-av { gap: 6px; }
.is-phone .og-err { min-height: 16px; font-size: 13px; }
.is-phone .of-wait { min-height: 64px; font-size: 16px; }
.is-phone .of-foot .btn { min-width: 110px; }
.is-phone .op-cols { gap: 10px; }
.is-phone .op-col { padding: 8px 10px; gap: 6px; }
.is-phone .op-h { font-size: 16px; }
.is-phone .op-code { height: 44px; font-size: 20px; }
.is-phone .wr-code-box { padding: 6px 10px; gap: 10px; }
.is-phone .wr-code { font-size: 28px; }
.is-phone .wr-av { width: 54px; height: 54px; }
.is-phone .wr-name { font-size: 13px; }
.is-phone .wr-note { font-size: 13px; min-height: 18px; }
.is-phone .chat-panel {
  left: auto;
  right: 0;
  top: 0;
  width: calc(min(400px, 60%) + var(--sa-r));
  height: 100%;
  padding: var(--sa-t) var(--sa-r) var(--sa-b) 0;
  border-radius: 16px 0 0 16px;
  transform: translateX(105%);
}
.is-phone .chat-panel.is-open { transform: none; }
.is-phone .chat-head { padding: 4px 4px 4px 14px; font-size: 18px; }
.is-phone .chat-head .icon-btn { width: 44px; height: 44px; }
.is-phone .chat-tabs .seg-btn { height: 44px; font-size: 13px; }
.is-phone .chat-phrases { gap: 5px; padding: 6px 8px 2px; max-height: 97px; overflow-y: auto; touch-action: pan-y; }
.is-phone .chat-phrase { height: 42px; padding: 0 12px; border-radius: 21px; font-size: 13px; }
.is-phone .chat-form { padding: 4px 8px 8px; }
.is-phone .chat-input { height: 44px; }
.is-phone .chat-send { width: 44px; height: 44px; }
.is-phone .no-box { padding: 16px 20px; gap: 8px; }
.is-phone .no-text { font-size: 17px; }

/* ======================================================================================
   19. Reduced motion
   ====================================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: 0.001ms !important;
  }
  .menu-halo, .float-tile, .confetti, .boot-mark .bm-t { animation: none !important; }
  .c101-logo-sheen { display: none; }
}
