/* ==========================================================================
   Telegram Card Games — Mini App stylesheet
   Rewritten as a small design system: every value below comes from the token
   block, so spacing and colour stay consistent instead of being re-invented per
   component. Layout is mobile-first with a fixed bottom nav.
   ========================================================================== */

:root {
  /* Surfaces, from deepest to highest */
  --bg: #0a0f1c;
  --bg-2: #0e1526;
  --surface: #141d33;
  --surface-2: #1b2542;
  --surface-3: #24305180;
  --line: #ffffff14;
  --line-strong: #ffffff26;

  /* Text */
  --text: #eef2fb;
  --text-2: #a8b4cf;
  --text-3: #6f7d9b;

  /* Accents */
  --gold: #f5c518;
  --gold-soft: #f5c5182e;
  --green: #34d399;
  --green-soft: #34d3992e;
  --red: #f87171;
  --red-soft: #f871712e;
  --blue: #60a5fa;
  --blue-soft: #60a5fa2e;
  --violet: #a78bfa;
  --violet-soft: #a78bfa2e;

  /* Felt */
  --felt: #0f5132;
  --felt-2: #16704a;

  /* Radii */
  --r-sm: 9px;
  --r-md: 13px;
  --r-lg: 18px;
  --r-full: 999px;

  /* Elevation */
  --shadow-1: 0 2px 8px #00000047;
  --shadow-2: 0 8px 24px #0000005c;
  --shadow-glow: 0 0 16px #f5c5184d;

  /* Rhythm */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 22px;

  /* Chrome heights */
  --topbar-h: 54px;
  --nav-h: 60px;

  /* Kept as aliases so any older rule or injected markup still resolves. */
  --accent-gold: var(--gold);
  --glass-border: var(--line-strong);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html, body {
  height: 100%;
  overflow: hidden;
}

body {
  font-family: "Vazirmatn", system-ui, -apple-system, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

button, input, textarea {
  font-family: inherit;
  color: inherit;
}

button { cursor: pointer; border: none; background: none; }

/* Latin glyphs and digits read better in Outfit. */
.coin-balance, .score-val, .bid-value, .stat-value,
.turn-timer-badge, .xp-label { font-family: "Outfit", "Vazirmatn", sans-serif; }

::-webkit-scrollbar { width: 0; height: 0; }

/* ==========================================================================
   SHELL
   ========================================================================== */

.app-shell {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  max-width: 520px;
  margin: 0 auto;
  background:
    radial-gradient(1000px 520px at 50% -12%, #1b2a4d 0%, transparent 62%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%);
  overflow: hidden;
}

.screen { display: none; flex: 1; min-height: 0; flex-direction: column; }
.screen.active { display: flex; }

.scroll-area {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--s3) var(--s3) calc(var(--nav-h) + var(--s4));
  -webkit-overflow-scrolling: touch;
}

.panel { display: none; flex-direction: column; gap: var(--s3); }
.panel.active { display: flex; }

.panel-title {
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -0.2px;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
}

.panel-head-actions { display: flex; gap: var(--s2); }

.card-title {
  font-size: 13.5px;
  font-weight: 800;
  margin-bottom: var(--s3);
}

.subhead {
  font-size: 12.5px;
  font-weight: 800;
  color: var(--text-2);
  margin: var(--s3) 0 var(--s2);
}

/* ==========================================================================
   TOP BAR
   ========================================================================== */

.topbar {
  flex: 0 0 auto;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  padding: 0 var(--s3);
  background: #0c122199;
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.identity { display: flex; align-items: center; gap: var(--s2); min-width: 0; }

.identity-avatar {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  border-radius: var(--r-full);
  display: grid;
  place-items: center;
  font-size: 16px;
  overflow: hidden;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  border: 1.5px solid var(--line-strong);
}

.identity-avatar img { width: 100%; height: 100%; object-fit: cover; }

.identity-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }

.identity-name {
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 130px;
}

.identity-status { font-size: 9.5px; color: var(--text-3); }

.topbar-actions { display: flex; align-items: center; gap: var(--s2); }

.coin-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border-radius: var(--r-full);
  background: var(--gold-soft);
  border: 1px solid #f5c5185c;
  color: var(--gold);
  font-size: 12.5px;
  font-weight: 800;
}

.coin-icon { font-size: 12px; }

.icon-btn {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: var(--r-md);
  background: #ffffff0f;
  border: 1px solid var(--line);
  font-size: 15px;
  transition: background 0.15s, transform 0.15s;
}

.icon-btn:active { transform: scale(0.94); background: #ffffff1f; }

.icon-btn-danger {
  background: var(--red-soft);
  border-color: #f8717159;
  color: var(--red);
}

/* ==========================================================================
   BOTTOM NAV
   ========================================================================== */

.bottom-nav {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 40;
  height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: #0b1120e6;
  backdrop-filter: blur(16px);
  border-top: 1px solid var(--line);
}

.nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  position: relative;
  color: var(--text-3);
  transition: color 0.16s;
}

.nav-item .nav-icon { font-size: 18px; filter: grayscale(0.55); transition: filter 0.16s, transform 0.16s; }
.nav-item .nav-label { font-size: 9.5px; font-weight: 700; }

.nav-item.active { color: var(--gold); }
.nav-item.active .nav-icon { filter: none; transform: translateY(-1px); }

.nav-item.active::before {
  content: "";
  position: absolute;
  top: 0;
  width: 26px;
  height: 2.5px;
  border-radius: var(--r-full);
  background: var(--gold);
}

/* ==========================================================================
   BUTTONS
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 11px 16px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 700;
  border: 1px solid transparent;
  transition: transform 0.14s, filter 0.14s, background 0.14s;
  white-space: nowrap;
}

.btn:active { transform: scale(0.975); }
.btn:disabled { opacity: 0.5; pointer-events: none; }

.btn-primary {
  background: linear-gradient(135deg, #2563eb, #1e40af);
  color: #fff;
  box-shadow: var(--shadow-1);
}

.btn-primary:active { filter: brightness(1.12); }

.btn-secondary {
  background: #ffffff12;
  border-color: var(--line-strong);
  color: var(--text);
}

.btn-secondary:active { background: #ffffff1f; }

.btn-gold {
  background: linear-gradient(135deg, #fbd24e, #e0a800);
  color: #2a1f00;
  font-weight: 800;
}

.btn-sm { padding: 7px 12px; font-size: 11.5px; }
.btn-block { width: 100%; }
.btn-icon { font-size: 12px; }

.btn-hero {
  padding: 15px 18px;
  font-size: 15px;
  font-weight: 800;
  border-radius: var(--r-lg);
  box-shadow: 0 6px 20px #1d4ed866;
}

.btn-duo { display: flex; gap: var(--s2); }
.btn-duo > .btn { flex: 1; }

/* Small pill button used inside dense rows (hand tools, list actions). */
.chip-btn {
  padding: 5px 10px;
  border-radius: var(--r-full);
  background: #ffffff12;
  border: 1px solid var(--line);
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-2);
}

.chip-btn:active { background: #ffffff24; }

/* ==========================================================================
   CARDS & GENERIC BLOCKS
   ========================================================================== */

.card,
.glass-card {
  background: linear-gradient(180deg, var(--surface) 0%, #121a2e 100%);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s4);
  box-shadow: var(--shadow-1);
}

.empty-state,
.empty-rooms,
.tx-empty,
.mh-empty {
  padding: 26px var(--s3);
  text-align: center;
  font-size: 12.5px;
  color: var(--text-3);
}

.stack-list { display: flex; flex-direction: column; gap: var(--s2); }

/* ==========================================================================
   TOASTS & BANNERS
   ========================================================================== */

.toast-stack,
.toast-container {
  position: fixed;
  top: calc(var(--topbar-h) + 8px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 300;
  width: min(94%, 460px);
  display: flex;
  flex-direction: column;
  gap: 6px;
  pointer-events: none;
}

/* showToast() builds `.toast-item`; `.toast` is kept as an alias so either name
   renders identically. */
.toast-item,
.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
  padding: 11px 14px;
  border-radius: var(--r-md);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.65;
  color: #fff;
  background: #1f2937f5;
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-2);
  backdrop-filter: blur(10px);
  /* Toasts sit in a container that ignores pointer events; re-enable it here so
     a long message can still be dismissed by tapping it. */
  pointer-events: auto;
  animation: toast-in 0.24s cubic-bezier(0.2, 1.1, 0.4, 1);
}

.toast-item > span:first-child,
.toast > span:first-child { flex: 0 0 auto; font-size: 14px; line-height: 1.4; }

.toast-item > span:last-child,
.toast > span:last-child { flex: 1; min-width: 0; word-break: break-word; }

.toast-item.success, .toast.success { background: #065f46f5; border-color: #34d39980; }
.toast-item.error,   .toast.error   { background: #7f1d1df5; border-color: #f8717180; }
.toast-item.warning, .toast.warning { background: #78350ff5; border-color: #f5c51880; }
.toast-item.info,    .toast.info    { background: #1e3a8af5; border-color: #60a5fa80; }

.toast-item.fade-out,
.toast.fade-out { animation: toast-out 0.3s ease forwards; }

@keyframes toast-in { from { opacity: 0; transform: translateY(-12px); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-12px); } }

.connection-banner {
  display: none;
  padding: 7px var(--s3);
  text-align: center;
  font-size: 11.5px;
  font-weight: 700;
  color: #fde68a;
  background: #78350fe6;
  border-bottom: 1px solid #f5c51859;
}

.connection-banner.active { display: block; }

.resume-banner {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s3);
  padding: var(--s3);
  border-radius: var(--r-md);
  background: var(--blue-soft);
  border: 1px solid #60a5fa59;
  font-size: 12.5px;
  font-weight: 600;
}

.resume-banner.active { display: flex; }

/* ==========================================================================
   TICKER
   ========================================================================== */

.ticker {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 7px var(--s2);
  border-radius: var(--r-md);
  background: var(--surface-3);
  border: 1px solid var(--line);
  overflow: hidden;
}

.ticker-tag { flex: 0 0 auto; font-size: 12px; }

.ticker-viewport { flex: 1; min-width: 0; overflow: hidden; }

.ticker-text {
  display: inline-block;
  white-space: nowrap;
  font-size: 11px;
  color: var(--text-2);
  animation: ticker 34s linear infinite;
}

@keyframes ticker {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}

/* ==========================================================================
   GAME PICKER
   ========================================================================== */

.game-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s2);
}

.game-mode-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: var(--s3);
  padding-top: 26px;
  border-radius: var(--r-md);
  background: linear-gradient(160deg, var(--surface-2) 0%, #141d33 100%);
  border: 1px solid var(--line);
  text-align: right;
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.game-mode-card:active { transform: scale(0.98); }

.game-mode-card.active {
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold), var(--shadow-glow);
}

.game-suit { font-size: 22px; line-height: 1; }
.game-name { font-size: 14px; font-weight: 800; }
.game-note { font-size: 10px; color: var(--text-3); }

.game-tag {
  position: absolute;
  top: var(--s2);
  right: var(--s2);
  padding: 2px 7px;
  border-radius: var(--r-full);
  font-size: 8.5px;
  font-weight: 800;
}

.tag-gold   { background: var(--gold-soft);   color: var(--gold); }
.tag-violet { background: var(--violet-soft); color: var(--violet); }
.tag-sky    { background: var(--blue-soft);   color: var(--blue); }
.tag-rose   { background: var(--red-soft);    color: var(--red); }

/* Join by code */
.join-card { padding: var(--s3); }
.join-label { display: block; font-size: 11.5px; color: var(--text-2); margin-bottom: var(--s2); }
.join-row { display: flex; gap: var(--s2); }

.join-row input {
  flex: 1;
  min-width: 0;
  padding: 10px var(--s3);
  border-radius: var(--r-md);
  background: #00000038;
  border: 1px solid var(--line-strong);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 3px;
  text-align: center;
  text-transform: uppercase;
  direction: ltr;
}

.join-row input::placeholder { letter-spacing: 1px; font-weight: 500; color: var(--text-3); }
.join-row input:focus { outline: none; border-color: var(--gold); }

/* ==========================================================================
   PROFILE PANEL
   ========================================================================== */

.profile-card { display: flex; flex-direction: column; gap: var(--s3); }

.profile-top { display: flex; align-items: center; gap: var(--s3); }

.profile-avatar-wrap { position: relative; flex: 0 0 auto; }

.profile-avatar {
  width: 52px;
  height: 52px;
  border-radius: var(--r-full);
  display: grid;
  place-items: center;
  font-size: 22px;
  overflow: hidden;
  background: linear-gradient(135deg, #f59e0b, #b45309);
  border: 2px solid var(--gold);
}

.profile-avatar img { width: 100%; height: 100%; object-fit: cover; }

.presence-dot {
  position: absolute;
  bottom: 1px;
  left: 1px;
  width: 12px;
  height: 12px;
  border-radius: var(--r-full);
  background: var(--green);
  border: 2px solid var(--surface);
}

.profile-ident { flex: 1; min-width: 0; }

.profile-name {
  font-size: 15px;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.level-chip {
  display: inline-block;
  margin-top: 2px;
  padding: 2px 9px;
  border-radius: var(--r-full);
  background: var(--gold-soft);
  border: 1px solid #f5c5183d;
  color: var(--gold);
  font-size: 9.5px;
  font-weight: 800;
}

.coin-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  padding: 6px 11px;
  border-radius: var(--r-full);
  background: var(--gold-soft);
  border: 1px solid #f5c5183d;
  color: var(--gold);
  font-size: 12.5px;
  font-weight: 800;
}

.xp-track {
  position: relative;
  height: 20px;
  border-radius: var(--r-full);
  background: #00000047;
  border: 1px solid var(--line);
  overflow: hidden;
}

.xp-fill {
  height: 100%;
  width: 0;
  border-radius: var(--r-full);
  background: linear-gradient(90deg, #f59e0b, var(--gold));
  transition: width 0.5s ease;
}

.xp-label {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 9.5px;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 3px #000000a8;
}

.stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); }

.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: var(--s2) 4px;
  border-radius: var(--r-md);
  background: #ffffff0a;
  border: 1px solid var(--line);
}

.stat-value { font-size: 16px; font-weight: 800; }
.stat-label { font-size: 9.5px; color: var(--text-3); }

.quick-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s2); }

.quick-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: var(--s3) 4px;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--line);
  transition: transform 0.14s, background 0.14s;
}

.quick-tile:active { transform: scale(0.96); background: var(--surface-2); }
.quick-icon { font-size: 19px; }
.quick-text { font-size: 10px; font-weight: 700; color: var(--text-2); }

.notif-dot,
.friend-req-count {
  position: absolute;
  top: 5px;
  right: 6px;
  min-width: 16px;
  padding: 0 4px;
  border-radius: var(--r-full);
  background: var(--red);
  color: #fff;
  font-size: 9px;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
}

/* The same badge inside a tab label sits inline rather than pinned. */
.history-tab-btn .notif-dot { position: static; margin-right: 3px; }

.reward-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s3);
}

.reward-left { display: flex; align-items: center; gap: var(--s3); min-width: 0; }
.reward-icon { font-size: 24px; }
.reward-title { display: block; font-size: 12.5px; font-weight: 800; }
.reward-note { font-size: 10px; color: var(--text-3); }

/* ==========================================================================
   MISSIONS
   ========================================================================== */

.mission-row {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--line);
}

.mission-row:last-child { border-bottom: none; }
.mission-icon { flex: 0 0 auto; font-size: 17px; }
.mission-main { flex: 1; min-width: 0; }
.mission-title { font-size: 12px; font-weight: 700; }
.mission-sub { font-size: 9.5px; color: var(--text-3); margin-top: 1px; }

.mission-bar {
  height: 5px;
  margin-top: 5px;
  border-radius: var(--r-full);
  background: #ffffff14;
  overflow: hidden;
}

.mission-bar-fill {
  height: 100%;
  border-radius: var(--r-full);
  background: linear-gradient(90deg, var(--blue), var(--green));
  transition: width 0.35s ease;
}

.mission-action { flex: 0 0 auto; }
.mission-done { font-size: 10px; font-weight: 700; color: var(--green); }
.mission-pending { font-size: 11px; font-weight: 800; color: var(--text-3); direction: ltr; }

/* ==========================================================================
   ROOMS LIST
   ========================================================================== */

.rooms-list,
.rooms-grid { display: flex; flex-direction: column; gap: var(--s2); }

.room-card {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3);
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--line);
  transition: border-color 0.15s, transform 0.15s;
}

.room-card:active { transform: scale(0.99); border-color: var(--line-strong); }

.room-card { align-items: flex-start; }
.room-card .room-icon { font-size: 22px; flex: 0 0 auto; margin-top: 1px; }
.room-card .room-body { flex: 1; min-width: 0; }
.room-card .room-title { font-size: 13px; font-weight: 800; }

.room-card .room-host {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text-2);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.room-card .room-meta { font-size: 9.5px; color: var(--text-3); margin-top: 2px; }

/* Occupancy as pips: how full a room is reads at a glance, which a bare
   fraction does not give you. */
.room-seats { display: flex; align-items: center; gap: 4px; margin-top: 6px; }

.room-seats-count {
  font-family: "Outfit", sans-serif;
  font-size: 10px;
  font-weight: 800;
  color: var(--text-2);
  margin-inline-end: 2px;
  direction: ltr;
}

.seat-pip {
  width: 7px;
  height: 7px;
  border-radius: var(--r-full);
  background: #ffffff1f;
  border: 1px solid var(--line-strong);
}

.seat-pip.filled { background: var(--green); border-color: var(--green); }

.room-card .btn { flex: 0 0 auto; align-self: center; }

/* ==========================================================================
   LEADERBOARD
   ========================================================================== */

.leaderboard-periods { display: flex; gap: 6px; margin-bottom: var(--s3); }

.lb-period-btn {
  flex: 1;
  padding: 7px 5px;
  border-radius: var(--r-sm);
  background: #ffffff0f;
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 700;
  color: var(--text-2);
  transition: all 0.15s;
}

.lb-period-btn.active {
  background: var(--gold-soft);
  border-color: var(--gold);
  color: var(--gold);
}

.leaderboard-table { width: 100%; border-collapse: collapse; font-size: 12px; }

.leaderboard-table th {
  padding: var(--s2) 4px;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-3);
  border-bottom: 1px solid var(--line);
  text-align: center;
}

.leaderboard-table td {
  padding: 9px 4px;
  border-bottom: 1px solid #ffffff0a;
  text-align: center;
}

.rank-badge {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: var(--r-full);
  font-size: 11px;
  font-weight: 800;
}

.rank-1 { background: var(--gold); color: #2a1f00; }
.rank-2 { background: #cbd5e1; color: #1f2937; }
.rank-3 { background: #d97706; color: #fff; }
.rank-other { background: #ffffff14; color: var(--text-2); }

/* ==========================================================================
   GAME SCREEN — header & scoreboard
   ========================================================================== */

.game-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--line);
}

.game-header-tools { display: flex; gap: 6px; margin-right: auto; }

.trump-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px var(--s3);
  border-radius: var(--r-full);
  background: #ffffff0f;
  border: 1px solid var(--line);
  font-size: 11.5px;
}

.trump-badge.trump-set {
  background: var(--gold-soft);
  border-color: var(--gold);
  box-shadow: var(--shadow-glow);
}

.trump-label { color: var(--text-3); font-size: 10px; }
.trump-icon { font-weight: 800; font-size: 14px; }

.scoreboard {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
}

.score-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px var(--s3);
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--line);
}

.score-pill.team1 { border-right: 3px solid var(--green); }
.score-pill.team2 { border-right: 3px solid var(--red); }

.team-label { font-size: 10px; color: var(--text-3); }
.score-val { font-size: 17px; font-weight: 800; }
.tricks-val { font-size: 9.5px; color: var(--text-2); margin-right: auto; }

/* ==========================================================================
   GAME SCREEN — table
   ========================================================================== */

.card-table {
  position: relative;
  flex: 1;
  min-height: 210px;
  margin: var(--s2) var(--s3);
  border-radius: var(--r-lg);
  overflow: hidden;
}

/* --own-felt-* come from the equipped felt; the original variables remain the
   fallback so a player who owns nothing still gets the classic green. */
.table-felt {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 50% 45%,
      var(--own-felt-1, var(--felt-2)) 0%,
      var(--own-felt-2, var(--felt)) 70%,
      #05140d 100%);
  border: 1px solid #ffffff1a;
  border-radius: var(--r-lg);
  box-shadow: inset 0 0 40px #00000073;
}

.trump-watermark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 96px;
  opacity: 0;
  color: #ffffff1f;
  pointer-events: none;
  transition: opacity 0.4s;
}

.trump-watermark.active { opacity: 1; }

/* --- seats --- */

.player-seat {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 74px;
  z-index: 6;
}

.seat-top    { top: 6px;    left: 50%; transform: translateX(-50%); }
.seat-bottom { bottom: 6px; left: 50%; transform: translateX(-50%); }
.seat-left   { left: 6px;   top: 50%;  transform: translateY(-50%); }
.seat-right  { right: 6px;  top: 50%;  transform: translateY(-50%); }

.avatar-wrap { position: relative; width: 42px; height: 42px; }

.avatar-circle {
  position: absolute;
  inset: 0;
  border-radius: var(--r-full);
  display: grid;
  place-items: center;
  font-size: 17px;
  font-weight: 800;
  overflow: hidden;
  background: linear-gradient(135deg, #475569, #334155);
  border: 2px solid #ffffff2e;
}

.avatar-circle img { width: 100%; height: 100%; object-fit: cover; }
.avatar-circle.avatar-clickable { cursor: pointer; }

.avatar-timer-ring {
  position: absolute;
  inset: -4px;
  border-radius: var(--r-full);
  border: 2.5px solid transparent;
  opacity: 0;
  transition: opacity 0.2s;
}

.avatar-timer-ring.active {
  opacity: 1;
  border-color: var(--gold);
  animation: ring-pulse 1s ease-in-out infinite;
}

@keyframes ring-pulse {
  50% { box-shadow: 0 0 12px 3px #f5c51873; }
}

.player-name {
  font-size: 10px;
  font-weight: 700;
  max-width: 74px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-shadow: 0 1px 3px #000000a8;
}

.card-count-badge {
  padding: 1px 7px;
  border-radius: var(--r-full);
  background: #00000073;
  font-size: 9px;
  font-weight: 700;
  color: #e2e8f0;
}

.player-seat.active-turn .avatar-circle {
  border-color: var(--gold);
  box-shadow: 0 0 14px #f5c518a6;
}

.player-seat.seat-empty { opacity: 0.42; }

.player-seat.seat-offline .avatar-circle { filter: grayscale(1); border-color: var(--red); }

/* Hidden unless the seat is actually offline. The badge element is created for
   every seat and always carries its text, so leaving it visible by default made
   every healthy player look disconnected. Only the `seat-offline` class tells
   the truth, so the badge is bound to it. */
.seat-offline-badge {
  display: none;
  position: absolute;
  bottom: -7px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  padding: 1px 7px;
  border-radius: var(--r-full);
  font-size: 8.5px;
  font-weight: 800;
  white-space: nowrap;
  color: #fff;
  background: var(--red);
  border: 1px solid #00000059;
  box-shadow: var(--shadow-1);
}

.player-seat.seat-offline .seat-offline-badge { display: block; }

/* --- chat bubbles --- */

.chat-bubble {
  position: absolute;
  z-index: 20;
  max-width: 130px;
  padding: 5px 9px;
  border-radius: var(--r-md);
  background: #f8fafcf5;
  color: #0f172a;
  font-size: 11px;
  font-weight: 600;
  box-shadow: var(--shadow-2);
  opacity: 0;
  pointer-events: none;
  transform: scale(0.85);
  transition: opacity 0.2s, transform 0.2s;
}

.chat-bubble.active { opacity: 1; transform: scale(1); }

.seat-top .chat-bubble    { top: 100%; margin-top: 4px; }
.seat-bottom .chat-bubble { bottom: 100%; margin-bottom: 4px; }
.seat-left .chat-bubble   { left: 100%; margin-left: 4px; top: 0; }
.seat-right .chat-bubble  { right: 100%; margin-right: 4px; top: 0; }

/* --- trick arena --- */

.trick-arena {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 152px;
  height: 132px;
  z-index: 4;
}

.played-card-slot {
  position: absolute;
  width: 42px;
  height: 60px;
}

.slot-top    { top: 0;    left: 50%; transform: translateX(-50%); }
.slot-bottom { bottom: 0; left: 50%; transform: translateX(-50%); }
.slot-left   { left: 0;   top: 50%;  transform: translateY(-50%); }
.slot-right  { right: 0;  top: 50%;  transform: translateY(-50%); }

/* ==========================================================================
   PLAYING CARDS
   ========================================================================== */

.playing-card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 40px;
  height: 57px;
  flex: 0 0 auto;
  padding: 3px 4px;
  border-radius: 7px;
  background: linear-gradient(160deg, #ffffff, #e8ecf4);
  color: #0f172a;
  border: 1px solid #00000026;
  box-shadow: 0 2px 5px #00000059;
  font-weight: 800;
  transition: transform 0.16s, box-shadow 0.16s;
  user-select: none;
  overflow: hidden;
}

/* Rank stacked over a small suit glyph in the top-left corner. Stacked rather
   than side by side because in a fanned hand only a narrow strip of each card is
   visible, and a vertical label fits that strip where a horizontal one does not. */
.playing-card .card-top {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 16px;
  line-height: 1;
  direction: ltr;
}

.playing-card .card-top > span:first-child {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: -0.5px;
}

.playing-card .card-top > span:last-child { font-size: 10px; margin-top: 1px; }

/* Decorative watermark on the part of the card that overlapping hides anyway. */
.playing-card .card-suit-big {
  align-self: flex-end;
  font-size: 18px;
  line-height: 1;
  opacity: 0.85;
}

/* createCardElement() tags cards `red` / `black`; the trick-history mini cards
   use `suit-red`. Both spellings are honoured so hearts and diamonds are never
   rendered in the default black. */
.playing-card.red,
.playing-card.suit-red { color: #dc2626; }
.playing-card.black { color: #0f172a; }

.playing-card.playable { cursor: pointer; }
.playing-card.playable:active { transform: translateY(-6px) scale(1.04); }

.playing-card.disabled { filter: grayscale(0.75) brightness(0.72); cursor: not-allowed; }

.playing-card.selected {
  transform: translateY(-9px);
  box-shadow: 0 0 0 2px var(--gold), 0 6px 14px #00000073;
}

/* The owner's purchased back, when they have one. --own-card-back is set from
   the shop catalogue by applyMyCosmetics(); the repeating gradient stays as the
   fallback for anyone who has not equipped anything. */
.playing-card.card-back {
  background: var(--own-card-back, repeating-linear-gradient(45deg, #1e3a8a 0 5px, #172554 5px 10px));
  border-color: var(--own-card-back-accent, #ffffff2e);
  color: transparent;
}

/* Card slid straight into a capture pile, briefly revealed on the felt. */
.card-played-reveal { animation: card-drop 0.28s ease; }

@keyframes card-drop {
  from { opacity: 0; transform: translateY(-16px) scale(0.9); }
}

.played-card-reveal-overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 12;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: var(--s2);
  border-radius: var(--r-md);
  background: #000000a6;
  backdrop-filter: blur(3px);
  animation: toast-in 0.2s ease;
}

.played-card-reveal-label { font-size: 10px; font-weight: 700; color: #fde68a; }
.reveal-fade-out { animation: toast-out 0.3s ease forwards; }

/* Card animating from the arena to the winner's seat. */
.trick-collect-floating-card {
  position: fixed;
  z-index: 200;
  pointer-events: none;
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.6, 1), opacity 0.5s;
}

.trick-winner-pulse { animation: winner-pulse 0.55s ease; }

@keyframes winner-pulse {
  50% { transform: scale(1.16); filter: brightness(1.3); }
}

/* ==========================================================================
   GAME NOTICE, HAND, CHAT
   ========================================================================== */

.game-notice {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  margin: 0 var(--s3);
  padding: 7px var(--s3);
  border-radius: var(--r-md);
  background: var(--surface-3);
  border: 1px solid var(--line);
  font-size: 11.5px;
  font-weight: 600;
}

.turn-timer-badge,
.timer-badge {
  display: none;
  flex: 0 0 auto;
  padding: 3px 9px;
  border-radius: var(--r-full);
  background: #00000059;
  border: 1px solid var(--line-strong);
  font-size: 11px;
  font-weight: 800;
  direction: ltr;
}

.turn-timer-badge.active { display: inline-block; color: var(--gold); border-color: #f5c5185c; }

.turn-timer-badge.using-time-bank {
  border-color: var(--blue);
  box-shadow: 0 0 12px #3b82f68c;
}

.time-bank-badge {
  display: inline-block;
  margin-right: 5px;
  padding: 1px 6px;
  border-radius: var(--r-sm);
  background: var(--blue-soft);
  border: 1px solid #60a5fa80;
  color: #93c5fd;
  font-size: 9px;
  font-weight: 800;
}

.hand-panel {
  flex: 0 0 auto;
  margin: var(--s2) var(--s3) 0;
  padding: var(--s2) var(--s3) var(--s3);
  border-radius: var(--r-lg);
  background: var(--surface-3);
  border: 1px solid var(--line);
}

.hand-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  margin-bottom: var(--s2);
}

.hand-tools { display: flex; gap: 6px; }

.turn-indicator {
  padding: 3px 10px;
  border-radius: var(--r-full);
  background: #ffffff0f;
  border: 1px solid var(--line);
  font-size: 10px;
  font-weight: 700;
  color: var(--text-3);
}

.turn-indicator.my-turn {
  background: var(--green-soft);
  border-color: var(--green);
  color: #6ee7b7;
  animation: turn-blink 1.4s ease-in-out infinite;
}

@keyframes turn-blink { 50% { opacity: 0.6; } }

/* The hand is laid out as an overlapping fan so a full 13-card hand fits without
   sideways scrolling. layoutHand() in game_ui.js measures the container and sets
   --card-overlap; the rank and suit sit in the top corner of each card precisely
   so they stay readable when only a sliver shows. */
.cards-fan {
  --card-overlap: 0px;
  /* Painted left-to-right on purpose, even though the app is RTL. In RTL each
     new card would cover the previous card's left edge - which is exactly where
     the rank sits - so the numbers disappeared. Left-to-right leaves every
     card's left corner exposed, and the corner carries the rank.
     This is a painting direction only: sortHandForDisplay() reverses the cards
     before rendering, so the hand still reads right-to-left and the trump group
     sits at the right-hand end. */
  direction: ltr;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  min-height: 76px;
  padding: 8px 0 6px;
  /* Bleed past the panel padding. Those 24px are the difference between a
     13-card hand fitting on a 320px phone and not. */
  margin-inline: calc(var(--s3) * -1);
  overflow: visible;
}

.cards-fan .playing-card { margin-inline-start: calc(var(--card-overlap) * -1); }
.cards-fan .playing-card:first-child { margin-inline-start: 0; }

/* Later cards stack over earlier ones, so the exposed sliver is always the
   corner that carries the rank. */
.cards-fan .playing-card { z-index: 1; }
.cards-fan .playing-card:hover { z-index: 5; }

/* A lifted card must clear its neighbours to be fully visible. */
.cards-fan .playing-card.selected,
.cards-fan .playing-card.playable:active { z-index: 20; }

/* With no overlap the cards need a little breathing room instead. */
.cards-fan.no-overlap { gap: 3px; }

/* Last resort on very narrow screens: scroll rather than clip. */
.cards-fan.scroll-fallback {
  justify-content: flex-start;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  padding-inline: var(--s3);
}

.chat-bar {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  margin: var(--s2) var(--s3);
  margin-bottom: calc(var(--s2) + env(safe-area-inset-bottom, 0px));
  padding: var(--s2) var(--s3);
  border-radius: var(--r-lg);
  background: var(--surface-3);
  border: 1px solid var(--line);
}

.quick-emotes { display: flex; justify-content: space-between; gap: 4px; }

.emote-btn {
  flex: 1;
  padding: 5px 0;
  border-radius: var(--r-sm);
  background: #ffffff0f;
  border: 1px solid var(--line);
  font-size: 16px;
  transition: transform 0.12s, background 0.12s;
}

.emote-btn:active { transform: scale(1.22); background: #ffffff26; }

.chat-input-wrapper { display: flex; gap: 6px; }

.chat-input-wrapper input {
  flex: 1;
  min-width: 0;
  padding: 8px var(--s3);
  border-radius: var(--r-md);
  background: #00000038;
  border: 1px solid var(--line);
  font-size: 12px;
}

.chat-input-wrapper input:focus { outline: none; border-color: var(--blue); }

.btn-send {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, #2563eb, #1e40af);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
}

/* ==========================================================================
   WAITING CARD (injected into the arena while seats fill)
   ========================================================================== */

/* Full-felt scrim. It also blocks taps reaching the seats underneath, which is
   what previously let an "add bot" tap land on the player's own avatar. */
.table-overlay {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--s3);
  border-radius: var(--r-lg);
  background: #06101ce0;
  backdrop-filter: blur(2px);
  overflow-y: auto;
}

.table-overlay.active { display: flex; }

.waiting-radar-card {
  width: 100%;
  max-width: 290px;
  padding: var(--s4);
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, var(--surface-2) 0%, #101830 100%);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-2);
  text-align: center;
}

.radar-pulse-ring {
  width: 54px;
  height: 54px;
  margin: 0 auto var(--s2);
  border-radius: var(--r-full);
  display: grid;
  place-items: center;
  border: 2px solid #f5c5184d;
  animation: radar 1.9s ease-out infinite;
}

@keyframes radar {
  0%   { box-shadow: 0 0 0 0 #f5c51859; }
  100% { box-shadow: 0 0 0 18px #f5c51800; }
}

.radar-center-icon { font-size: 22px; }

.waiting-title { font-size: 13.5px; font-weight: 800; }
.waiting-subtitle { font-size: 11px; color: var(--text-2); margin-top: 2px; }

.waiting-invite-block {
  margin-top: var(--s3);
  padding: var(--s2) var(--s3);
  border-radius: var(--r-md);
  border: 1px dashed #f5c51890;
  background: var(--gold-soft);
}

.waiting-invite-label { font-size: 9.5px; font-weight: 700; color: var(--text-2); }

.waiting-invite-code {
  display: block;
  width: 100%;
  padding: 2px 0;
  background: none;
  border: none;
  color: var(--gold);
  font-family: "Outfit", monospace;
  font-size: 25px;
  font-weight: 800;
  letter-spacing: 7px;
  text-align: center;
  direction: ltr;
}

.waiting-invite-hint { font-size: 9px; color: var(--text-3); }

/* Each action gets its own full-width row with real separation. They used to sit
   flush against one another and against the seat below, so a miss-tap was easy. */
.btn-invite-friend,
.btn-invite-share,
.btn-add-bot,
.btn-leave-waiting {
  display: block;
  width: 100%;
  margin-top: var(--s2);
  padding: 12px 10px;
  border-radius: var(--r-md);
  font-size: 12.5px;
  font-weight: 700;
  border: 1px solid;
  transition: transform 0.14s, filter 0.14s;
}

.btn-invite-friend:active,
.btn-invite-share:active,
.btn-add-bot:active,
.btn-leave-waiting:active { transform: scale(0.98); filter: brightness(1.15); }

/* The one-tap path leads, so it carries the accent colour and the manual share
   below it is visibly the fallback. */
.btn-invite-friend { background: var(--green-soft); border-color: #34d39980; color: #6ee7b7; }
.btn-invite-share { background: var(--blue-soft); border-color: #60a5fa80; color: #93c5fd; }
.btn-add-bot { background: var(--violet-soft); border-color: #a78bfa80; color: #c4b5fd; }

/* Leaving is the destructive option, so it is pushed away from the two it could
   be confused with. */
.btn-leave-waiting {
  margin-top: var(--s4);
  background: var(--red-soft);
  border-color: #f8717180;
  color: #fca5a5;
}

/* ==========================================================================
   MODALS
   ========================================================================== */

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--s4);
  background: #050912cc;
  backdrop-filter: blur(5px);
}

.modal-overlay.active { display: flex; animation: overlay-in 0.18s ease; }

/* Some decisions depend on the cards in hand: choosing the trump suit, or
   bidding in Shelem. A full blurred scrim hid exactly the information needed to
   decide, so these dialogs sit at the top and the scrim fades out over the hand.
   Taps are still absorbed, so nothing is played by accident. */
.modal-overlay.modal-keep-hand {
  align-items: flex-start;
  padding-top: var(--s4);
  background: linear-gradient(
    to bottom,
    #050912f7 0%,
    #050912f0 42%,
    #05091299 66%,
    #05091200 84%
  );
  backdrop-filter: none;
}

.modal-overlay.modal-keep-hand .modal-card { max-width: 340px; }

/* Lift the hand above the scrim so the cards read at full contrast while the
   dialog is open. Look-don't-touch: pointer events stay off, so a card cannot be
   played out of turn. Where :has() is unsupported the gradient above still lets
   the hand show through, so this only ever improves things. */
body:has(.modal-keep-hand.active) #gameScreen .hand-panel {
  position: relative;
  z-index: 210;
  pointer-events: none;
  border-color: #f5c51880;
  box-shadow: 0 -12px 34px #000000b3;
}

@keyframes overlay-in { from { opacity: 0; } }

.modal-card {
  width: 100%;
  max-width: 380px;
  max-height: 86vh;
  overflow-y: auto;
  padding: var(--s4);
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, var(--surface-2) 0%, #121a2e 100%);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-2);
  animation: modal-in 0.22s cubic-bezier(0.2, 1.1, 0.4, 1);
}

@keyframes modal-in { from { opacity: 0; transform: translateY(16px) scale(0.97); } }

.modal-card h3 { font-size: 15px; font-weight: 800; margin-bottom: var(--s2); }
.modal-card h4 { font-size: 13px; font-weight: 800; margin-bottom: var(--s2); }
.modal-card > .btn-block { margin-top: var(--s3); }

.modal-sub { font-size: 12px; color: var(--text-2); margin-bottom: var(--s3); }
.modal-sub.accent { color: var(--gold); font-weight: 700; }
.modal-tall .mh-pane { max-height: 46vh; }

.field { margin-bottom: var(--s3); }
.field-label { font-size: 12px; font-weight: 700; color: var(--text-2); margin-bottom: 6px; }
.field-hint { display: block; margin-top: 6px; font-size: 9.5px; color: var(--text-3); line-height: 1.7; }

.option-row { display: flex; gap: var(--s2); }

.btn-room-option,
.btn-capacity {
  flex: 1;
  padding: 9px 6px;
  border-radius: var(--r-sm);
  background: #ffffff0d;
  border: 1px solid var(--line);
  font-size: 11.5px;
  font-weight: 800;
  color: var(--text-2);
  transition: all 0.15s;
}

.btn-room-option.active,
.btn-capacity.active {
  background: var(--gold-soft);
  border-color: var(--gold);
  color: var(--gold);
}

/* --- trump picker --- */

.trump-options { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); }

.trump-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--s3);
  border-radius: var(--r-md);
  background: #ffffff0d;
  border: 1px solid var(--line-strong);
  transition: transform 0.14s, border-color 0.14s;
}

.trump-btn:active { transform: scale(0.96); border-color: var(--gold); }
.trump-btn .suit-sym { font-size: 26px; line-height: 1; }
.trump-btn .suit-name { font-size: 11px; font-weight: 700; color: var(--text-2); }
.trump-btn.hearts .suit-sym,
.trump-btn.diamonds .suit-sym { color: #ef4444; }
.trump-btn.spades .suit-sym,
.trump-btn.clubs .suit-sym { color: #e2e8f0; }

/* --- bidding --- */

.bid-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s4);
  margin-bottom: var(--s3);
}

.bid-step {
  width: 44px;
  height: 40px;
  border-radius: var(--r-md);
  background: #ffffff12;
  border: 1px solid var(--line-strong);
  font-size: 15px;
  font-weight: 800;
}

.bid-value { font-size: 27px; font-weight: 800; color: var(--gold); min-width: 68px; text-align: center; }

/* --- settings --- */

.settings-list { display: flex; flex-direction: column; gap: 2px; }

.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: 11px 2px;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
  cursor: pointer;
}

.setting-row:last-child { border-bottom: none; }
.setting-row input[type="checkbox"] { width: 19px; height: 19px; accent-color: var(--gold); }

/* --- confirm play --- */

.confirm-card-preview {
  display: flex;
  justify-content: center;
  gap: 6px;
  min-height: 66px;
  margin-top: var(--s2);
}

/* --- rules / history bodies --- */

.rules-body { max-height: 52vh; overflow-y: auto; font-size: 12px; line-height: 1.9; }
.rules-body h4 { margin: var(--s3) 0 4px; font-size: 12.5px; color: var(--gold); }
.rules-body ul { padding-right: var(--s4); }
.rules-body li { margin-bottom: 3px; color: var(--text-2); }
.rules-body b { color: var(--text); }

.history-tabs { display: flex; gap: 6px; margin-bottom: var(--s3); }

.history-tab-btn {
  flex: 1;
  padding: 8px 6px;
  border-radius: var(--r-sm);
  background: #ffffff0d;
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 700;
  color: var(--text-2);
  transition: all 0.15s;
}

.history-tab-btn.active { background: var(--gold-soft); border-color: var(--gold); color: var(--gold); }

/* --- trick history rows --- */

.trick-row {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 7px 2px;
  border-bottom: 1px solid var(--line);
}

.trick-row-number { flex: 0 0 auto; font-size: 10px; font-weight: 800; color: var(--text-3); }
.trick-row-cards { flex: 1; display: flex; gap: 3px; flex-wrap: wrap; }

.trick-mini-card {
  padding: 2px 5px;
  border-radius: 5px;
  background: #ffffff14;
  font-size: 10.5px;
  font-weight: 800;
  direction: ltr;
}

.trick-mini-card.suit-red { color: #fca5a5; }
.trick-winner-card { background: var(--green-soft); box-shadow: 0 0 0 1px #34d39980; }
.trick-row-winner { flex: 0 0 auto; font-size: 9.5px; color: var(--green); font-weight: 700; }

/* --- score breakdown table --- */

.score-table { width: 100%; border-collapse: collapse; font-size: 11.5px; }

.score-table th,
.score-table td {
  padding: 7px 5px;
  border-bottom: 1px solid var(--line);
  text-align: center;
}

.score-table th { font-size: 10px; color: var(--text-3); font-weight: 700; }
.score-table .total-row td { font-weight: 800; color: var(--gold); border-bottom: none; }

/* --- winner celebration --- */

.winner-celebration-card { text-align: center; }

.trophy-badge-wrap { position: relative; display: inline-grid; place-items: center; margin-bottom: var(--s2); }
.trophy-icon { font-size: 46px; animation: trophy-pop 0.6s ease; }

@keyframes trophy-pop { from { transform: scale(0.4) rotate(-16deg); opacity: 0; } }

.starburst-fx {
  position: absolute;
  width: 84px;
  height: 84px;
  border-radius: var(--r-full);
  background: radial-gradient(circle, #f5c51859 0%, transparent 68%);
  animation: ring-pulse 2s ease-in-out infinite;
}

.winner-title { font-size: 19px; font-weight: 800; color: var(--gold); }
.winner-subtitle { font-size: 12px; color: var(--text-2); margin-top: 3px; }

.rewards-summary-box { display: flex; justify-content: center; gap: var(--s2); margin: var(--s3) 0; }

.reward-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 7px var(--s3);
  border-radius: var(--r-full);
  background: var(--gold-soft);
  border: 1px solid #f5c5183d;
  font-size: 12px;
  font-weight: 800;
  color: var(--gold);
}

.pill-icon { font-size: 13px; }

.score-summary-grid { display: flex; flex-direction: column; gap: 6px; font-size: 12px; }

/* ==========================================================================
   LIST ROWS shared by stats, transactions, friends, tournaments
   ========================================================================== */

.mh-pane,
.tx-list { max-height: 320px; overflow-y: auto; margin-top: var(--s1); }

.mh-row,
.tx-row {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 9px 3px;
  border-bottom: 1px solid var(--line);
}

.mh-row:last-child,
.tx-row:last-child { border-bottom: none; }

.mh-row-icon,
.tx-row-icon { flex: 0 0 auto; font-size: 16px; }

.mh-row-main,
.tx-row-main { flex: 1; min-width: 0; }

.mh-row-title,
.tx-row-label { font-size: 12px; font-weight: 700; }

.mh-row-sub,
.tx-row-date { font-size: 9.5px; color: var(--text-3); margin-top: 2px; }

.mh-row-tag {
  flex: 0 0 auto;
  padding: 3px 9px;
  border-radius: var(--r-sm);
  font-size: 10.5px;
  font-weight: 800;
}

.mh-row-tag.win  { color: #6ee7b7; background: var(--green-soft); }
.mh-row-tag.loss { color: #fca5a5; background: var(--red-soft); }
.mh-row-tag.draw { color: var(--text-2); background: #94a3b829; }

.mh-rate-bar {
  height: 5px;
  margin-top: 5px;
  border-radius: var(--r-full);
  background: #ffffff14;
  overflow: hidden;
}

.mh-rate-fill { height: 100%; border-radius: var(--r-full); background: linear-gradient(90deg, var(--gold), var(--green)); }

.tx-balance-row {
  padding: var(--s2) 2px var(--s3);
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-2);
}

.tx-balance-row b { color: var(--gold); }

.tx-row-amount { flex: 0 0 auto; font-size: 12.5px; font-weight: 800; direction: ltr; }
.tx-row-amount.credit { color: var(--green); }
.tx-row-amount.debit { color: var(--red); }

/* ==========================================================================
   FRIENDS
   ========================================================================== */

.friend-actions { display: flex; flex: 0 0 auto; gap: 5px; }

.friend-btn {
  padding: 5px 9px;
  border-radius: var(--r-sm);
  background: #ffffff12;
  border: 1px solid var(--line);
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-2);
  white-space: nowrap;
}

.friend-btn.accept { border-color: var(--green); background: var(--green-soft); color: #6ee7b7; }
.friend-btn.join { border-color: var(--gold); background: var(--gold-soft); color: var(--gold); }
.friend-btn.invite { border-color: #60a5fa80; background: var(--blue-soft); color: #93c5fd; }
.friend-btn.danger { border-color: var(--red); color: #fca5a5; }

.friend-btn:disabled { opacity: 0.55; }

.friend-online-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-left: 5px;
  border-radius: var(--r-full);
  background: var(--green);
  vertical-align: middle;
}

/* ==========================================================================
   BADGES
   ========================================================================== */

.badge-summary {
  padding: 6px 2px var(--s3);
  border-bottom: 1px solid var(--line);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--gold);
}

.badges-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s2);
  max-height: 46vh;
  overflow-y: auto;
  margin-top: var(--s3);
}

.badge-cell {
  padding: var(--s3) var(--s2);
  border-radius: var(--r-md);
  text-align: center;
  background: #ffffff0d;
  border: 1px solid var(--line);
}

.badge-cell.earned { background: var(--gold-soft); border-color: #f5c51890; }
.badge-cell.locked { opacity: 0.5; }
.badge-cell-icon { font-size: 23px; }
.badge-cell-title { font-size: 11.5px; font-weight: 800; margin-top: 4px; }
.badge-cell-desc { font-size: 9px; color: var(--text-3); margin-top: 3px; line-height: 1.6; }

/* ==========================================================================
   TOURNAMENTS
   ========================================================================== */

.tournament-tag {
  padding: 4px 9px;
  border-radius: var(--r-sm);
  font-size: 10px;
  font-weight: 800;
  white-space: nowrap;
}

.tournament-tag.open { color: #6ee7b7; background: var(--green-soft); }
.tournament-tag.running { color: var(--gold); background: var(--gold-soft); }
.tournament-tag.done { color: var(--text-2); background: #94a3b829; }

.bracket-meta {
  padding: 6px 2px var(--s3);
  border-bottom: 1px solid var(--line);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--text-2);
}

.bracket-round-title { margin: var(--s3) 0 6px; font-size: 11px; font-weight: 800; color: var(--gold); }

.bracket-match {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 8px var(--s3);
  margin-bottom: 6px;
  border-radius: var(--r-md);
  background: #ffffff0d;
  border: 1px solid var(--line);
}

.bracket-match.mine { background: var(--blue-soft); border-color: #60a5fa99; }

.bracket-player {
  flex: 1;
  min-width: 0;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bracket-player.winner { color: #6ee7b7; font-weight: 800; }
.bracket-vs { flex: 0 0 auto; font-size: 9px; color: var(--text-3); direction: ltr; }

/* ==========================================================================
   OPPONENT PROFILE & REPORT
   ========================================================================== */

.opponent-profile-card { text-align: center; }

.opponent-profile-avatar {
  width: 68px;
  height: 68px;
  margin: 0 auto var(--s2);
  border-radius: var(--r-full);
  display: grid;
  place-items: center;
  font-size: 25px;
  font-weight: 800;
  overflow: hidden;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
}

.opponent-profile-avatar img { width: 100%; height: 100%; object-fit: cover; }

.opponent-profile-level { font-size: 11px; font-weight: 700; color: var(--gold); margin-bottom: var(--s3); }

.opponent-profile-stats { display: flex; gap: var(--s2); }

.opponent-stat-box {
  flex: 1;
  padding: 10px 4px;
  border-radius: var(--r-md);
  background: #ffffff0d;
  border: 1px solid var(--line);
}

.opponent-stat-value { font-size: 16px; font-weight: 800; }
.opponent-stat-label { font-size: 9.5px; color: var(--text-3); margin-top: 2px; }

.opponent-profile-actions { display: flex; gap: 6px; margin-top: var(--s3); }
.opponent-profile-actions .btn { flex: 1; }

.report-target { font-size: 12.5px; font-weight: 700; color: var(--gold); margin-bottom: var(--s3); }
.report-reasons { display: flex; flex-direction: column; gap: 6px; }

.report-reason-btn {
  width: 100%;
  padding: 10px;
  border-radius: var(--r-md);
  background: #ffffff0f;
  border: 1px solid var(--line);
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  text-align: right;
  transition: all 0.15s;
}

.report-reason-btn.active { border-color: var(--red); background: var(--red-soft); color: #fca5a5; }

.report-note {
  width: 100%;
  margin-top: var(--s2);
  padding: 9px 10px;
  border-radius: var(--r-md);
  background: #00000038;
  border: 1px solid var(--line);
  font-size: 12px;
  resize: none;
}

.report-note:focus { outline: none; border-color: var(--gold); }
.report-hint { display: block; margin-top: var(--s2); font-size: 9.5px; color: var(--text-3); text-align: center; }

/* ==========================================================================
   LARGER SCREENS
   Telegram Desktop and tablets get a roomier table instead of a phone-width
   column stranded in the middle of the window.
   ========================================================================== */

@media (min-width: 700px) and (min-height: 620px) {
  .app-shell { max-width: 660px; }
  .card-table { min-height: 300px; }
  .playing-card { width: 50px; height: 71px; }
  .playing-card .card-top { font-size: 14px; }
  .playing-card .card-suit-big { font-size: 22px; }
  .trick-arena { width: 190px; height: 160px; }
  .played-card-slot { width: 50px; height: 71px; }
  .avatar-wrap { width: 50px; height: 50px; }
  .player-seat { width: 88px; }
}

@media (min-width: 1000px) and (min-height: 720px) {
  .app-shell { max-width: 800px; }
  .card-table { min-height: 360px; }
  .playing-card { width: 56px; height: 80px; }
  .playing-card .card-top { font-size: 15px; }
  .playing-card .card-suit-big { font-size: 25px; }
  .game-grid { grid-template-columns: repeat(4, 1fr); }
}

/* Very short viewports: keep the table usable by trimming chrome. */
@media (max-height: 620px) {
  .card-table { min-height: 170px; }
  .quick-emotes { display: none; }
  .playing-card { width: 40px; height: 57px; }
  .playing-card .card-top { font-size: 11.5px; }
  .playing-card .card-suit-big { font-size: 16px; }
  .trick-arena { width: 136px; height: 118px; }
  .played-card-slot { width: 38px; height: 54px; }
}

/* ==========================================================================
   SHOP
   Item appearance is never defined here. The catalogue in economy/shop.py ships
   the colours and the JavaScript applies them inline, so adding an item is a
   catalogue entry plus a version bump. These rules only lay out the container.
   ========================================================================== */

.shop-banner {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  margin-bottom: var(--s3);
  padding: var(--s3) var(--s4);
  border: 1px solid #f5c51840;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, #f5c5181f, #a78bfa1f);
  color: var(--text-1);
  font-family: inherit;
  text-align: right;
  cursor: pointer;
}

.shop-banner:active { transform: scale(0.99); }
.shop-banner-icon { font-size: 22px; }
.shop-banner-text { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.shop-banner-text strong { font-size: 13.5px; color: var(--gold); }
.shop-banner-text small { font-size: 10.5px; color: var(--text-3); }
.shop-banner-go { font-size: 20px; color: var(--text-3); transform: rotate(180deg); }

.shop-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
}

.shop-head h3 { margin: 0; }

.shop-wallet {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--r-full);
  background: var(--gold-soft);
  border: 1px solid #f5c51840;
  font-size: 12px;
  font-weight: 800;
  color: var(--gold);
}

.shop-progress {
  display: flex;
  justify-content: space-between;
  padding: var(--s2) 2px 0;
  font-size: 10.5px;
  color: var(--text-3);
}

.shop-pane {
  max-height: 52vh;
  overflow-y: auto;
  margin: var(--s2) 0 var(--s3);
}

.shop-hint {
  padding: 0 2px var(--s2);
  font-size: 10.5px;
  color: var(--text-3);
}

.shop-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s2);
}

.shop-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: var(--s3) var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: #ffffff0a;
  text-align: center;
}

.shop-cell.is-equipped { border-color: var(--green); background: var(--green-soft); }
.shop-cell.is-locked { opacity: 0.72; }

.shop-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 52px;
  border: 1px solid #ffffff26;
  border-radius: var(--r-sm);
  font-size: 12px;
  font-weight: 700;
  overflow: hidden;
}

.shop-preview.preview-card_back { font-size: 20px; }
.shop-preview.preview-title { border-style: dashed; font-size: 13px; font-weight: 800; }

/* A frame swatch is drawn as a ring: the coloured plate with a dark disc on top. */
.shop-preview.preview-frame { position: relative; }
.preview-frame-hole {
  width: 30px;
  height: 30px;
  border-radius: var(--r-full);
  background: var(--bg-2, #0f172a);
}

.shop-preview.preview-animated { animation: frame-spin 6s linear infinite; }

@keyframes frame-spin {
  from { filter: hue-rotate(0deg); }
  to { filter: hue-rotate(360deg); }
}

.shop-item-name { font-size: 11.5px; font-weight: 700; color: var(--text-1); }
.shop-item-tier { font-size: 9.5px; font-weight: 800; }
.shop-item-desc { font-size: 9.5px; color: var(--text-3); line-height: 1.5; }

.shop-btn {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: #ffffff0d;
  color: var(--text-2);
  font-family: inherit;
  font-size: 11px;
  font-weight: 800;
  cursor: pointer;
}

.shop-btn:active { transform: scale(0.98); }
.shop-btn.buy { border-color: var(--gold); background: var(--gold-soft); color: var(--gold); }
.shop-btn.equip { border-color: var(--blue); background: var(--blue-soft); color: #93c5fd; }
.shop-btn.equipped { border-color: var(--green); background: var(--green-soft); color: #6ee7b7; }
.shop-btn.unequip { border-color: rgba(244, 63, 94, 0.4); background: rgba(244, 63, 94, 0.12); color: #fda4af; }
.shop-btn.unequip:hover { border-color: rgba(244, 63, 94, 0.6); background: rgba(244, 63, 94, 0.2); }
.shop-btn.unaffordable { border-color: #f8717155; color: #fca5a5; }
.shop-btn.locked { color: var(--text-3); }
.shop-btn:disabled { cursor: default; opacity: 0.85; }

/* ==========================================================================
   QUICK CHAT
   ========================================================================== */

.quick-chat-sheet {
  position: absolute;
  left: var(--s3);
  right: var(--s3);
  bottom: var(--s3);
  z-index: 60;
  display: none;
  flex-direction: column;
  gap: var(--s2);
  padding: var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: #0b1120f2;
  box-shadow: 0 -8px 28px #00000073;
  backdrop-filter: blur(8px);
}

.quick-chat-sheet.active { display: flex; }

.quick-chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  font-weight: 800;
  color: var(--text-2);
}

.quick-chat-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  max-height: 38vh;
  overflow-y: auto;
}

.quick-chat-item {
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: #ffffff0d;
  color: var(--text-1);
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 700;
  text-align: right;
  cursor: pointer;
}

.quick-chat-item:active { transform: scale(0.98); filter: brightness(1.2); }

.quick-chat-note {
  font-size: 10px;
  line-height: 1.6;
  color: var(--text-3);
}

.quick-chat-note:empty { display: none; }

/* ==========================================================================
   WORN ITEMS ON A SEAT
   ========================================================================== */

/* The ring is drawn behind the avatar wrapper rather than on the avatar itself.
   The avatar sets its own background for the initial-letter fallback and clips
   its photo with overflow:hidden, so a ring painted there is either overwritten
   or hidden. Behind the wrapper it always shows. */
.avatar-wrap.has-frame::before,
.profile-avatar-wrap.has-frame::before {
  content: "";
  position: absolute;
  inset: -3px;
  z-index: 0;
  border-radius: var(--r-full);
  background: var(--frame-ring, transparent);
}

.avatar-wrap.has-frame .avatar-circle,
.profile-avatar-wrap.has-frame .profile-avatar { position: relative; z-index: 1; }

.avatar-wrap.frame-animated::before,
.profile-avatar-wrap.frame-animated::before {
  animation: frame-spin 8s linear infinite;
}

/* The profile avatar wrapper needs a positioning context for the ring; the seat
   wrapper already has one. */
.profile-avatar-wrap { position: relative; }

.seat-title {
  margin-top: 1px;
  font-size: 9px;
  font-weight: 800;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--text-3);
}

.profile-title {
  display: inline-block;
  margin-top: 3px;
  font-size: 10.5px;
  font-weight: 800;
  color: var(--text-3);
}

/* The card count doubles as the place a player's card back is on show. */
.card-count-badge .count-number { font-variant-numeric: tabular-nums; }

.count-card-back {
  display: inline-block;
  width: 11px;
  height: 15px;
  margin-inline-start: 4px;
  vertical-align: -3px;
  border: 1px solid #ffffff40;
  border-radius: 2px;
  background: repeating-linear-gradient(45deg, #1e3a8a 0 3px, #172554 3px 6px);
  font-size: 7px;
  line-height: 13px;
  text-align: center;
}
