:root {
  --felt: #17402c;
  --felt-deep: #0d2a1c;
  --gold: #d8b45a;
  --gold-soft: rgba(216, 180, 90, 0.35);
  --cream: #f5efdf;
  --ink: #22222a;
  --red: #b3403f;
  --danger: #c96f5a;
  --glow: 0 0 0 3px rgba(216, 180, 90, 0.55), 0 10px 24px rgba(0, 0, 0, 0.45);
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* html/body/#root are capped (height, not min-height) with overflow:hidden so
   the DOCUMENT itself never scrolls on mobile — every game's live table
   screen is meant to read as one fixed screen. See the --vh/svh block below
   for how the cap is actually sized; .centre/.dom-board-wrap carry their own
   contained overflow-y:auto as a safety net for genuine edge cases instead. */
html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; }
body {
  font-family: "Outfit", system-ui, sans-serif;
  color: var(--cream);
  background:
    radial-gradient(1200px 700px at 50% -10%, #235c3f 0%, var(--felt) 45%, var(--felt-deep) 100%);
}
#root { height: 100%; overflow: hidden; display: flex; flex-direction: column; }
button { font-family: inherit; cursor: pointer; }
h1, h2, .brand { font-family: "Fraunces", serif; }

/* ---------- shared chrome ---------- */
.shell { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; max-width: 900px; width: 100%; margin: 0 auto; padding: 14px 14px calc(14px + env(safe-area-inset-bottom)); }
.brand { font-size: 26px; font-weight: 800; letter-spacing: 0.5px; color: var(--gold); text-shadow: 0 2px 12px rgba(0,0,0,.4); }
.brand small { font-family: "Outfit"; font-weight: 600; font-size: 12px; color: var(--cream); opacity: .75; letter-spacing: 2px; display: block; text-transform: uppercase; }
.btn {
  border: 0; border-radius: 14px; padding: 13px 20px; font-weight: 800; font-size: 15px;
  background: linear-gradient(180deg, #e8c979, var(--gold)); color: #3a2c10;
  box-shadow: 0 6px 16px rgba(0,0,0,.35); transition: transform .08s ease, filter .15s;
}
.btn:active { transform: translateY(1px) scale(.99); }
.btn:disabled { filter: grayscale(.7) brightness(.75); cursor: not-allowed; }
.btn.ghost { background: rgba(245,239,223,.1); color: var(--cream); border: 1.5px solid rgba(245,239,223,.35); }
.btn.small { padding: 8px 14px; font-size: 13px; border-radius: 11px; }
.btn.danger { background: linear-gradient(180deg, #d98b74, var(--danger)); color: #3a1610; }
.field {
  width: 100%; border-radius: 14px; border: 1.5px solid rgba(245,239,223,.3);
  background: rgba(0,0,0,.25); color: var(--cream); padding: 13px 16px; font-size: 16px; font-family: inherit;
}
.field:focus { outline: none; border-color: var(--gold); }

/* ---------- home ---------- */
/* One play panel + safe vertical center. Overflow scrolls from the top
   (safe center) instead of clipping the brand. */
.home {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column;
  justify-content: flex-start; /* fallback when `safe` unsupported */
  justify-content: safe center;
  gap: 16px; max-width: 420px; margin: 0 auto; width: 100%;
  padding: 8px 0 12px;
}
.home .brand { font-size: 40px; text-align: center; flex: 0 0 auto; line-height: 1.08; }
.home .brand small { font-size: 11.5px; letter-spacing: 1.6px; margin-top: 6px; }
.panel { background: rgba(0,0,0,.28); border: 1px solid rgba(216,180,90,.25); border-radius: 20px; padding: 20px; display: flex; flex-direction: column; gap: 12px; }
.home .panel { padding: 16px; gap: 11px; }
.panel h2 { margin: 0 0 2px; font-size: 19px; color: var(--gold); }
.row { display: flex; gap: 10px; }
.row > * { flex: 1; }
.code-input { text-transform: uppercase; letter-spacing: 6px; text-align: center; font-weight: 800; }
.rules-note { font-size: 12.5px; opacity: .7; line-height: 1.5; text-align: center; }

.account-row { display: flex; justify-content: center; margin-top: 8px; }
.account-row a.btn, .account-badge a.btn { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
.home-hero { display: flex; flex-direction: column; align-items: stretch; gap: 4px; flex: 0 0 auto; }
.account-guest-note { margin: 2px 10px 0; }
.home .game-pick { gap: 10px; }
.home .game-card { padding: 14px 10px; }
.privacy-note { margin: 2px 0 0; text-align: center; flex: 0 0 auto; }
.privacy-note-toggle {
  background: none; border: 0; color: var(--cream); opacity: .6; font: inherit;
  font-size: 12px; letter-spacing: .3px; text-decoration: underline; cursor: pointer; padding: 4px 8px;
}
.privacy-note-toggle:hover { opacity: .9; }
.privacy-note-body {
  margin: 8px auto 0; max-width: 34rem; padding: 12px 14px; text-align: left;
  background: rgba(0,0,0,.22); border: 1px solid rgba(245,239,223,.12); border-radius: 12px;
  font-size: 12.5px; line-height: 1.45; opacity: .9;
}
.privacy-note-body p { margin: 0 0 8px; }
.privacy-note-body p:last-child { margin-bottom: 0; }
.account-badge { display: flex; align-items: center; gap: 8px; background: rgba(0,0,0,.28); border: 1px solid rgba(216,180,90,.25); border-radius: 30px; padding: 5px 6px 5px 10px; font-size: 13px; }
.account-avatar { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; }
.account-name { font-weight: 700; max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 520px) {
  .home .brand { font-size: 36px; }
}
@media (max-height: 680px) {
  .home { gap: 12px; }
  .home .brand { font-size: 34px; }
  .home .install-nudge { display: none; }
}

/* ---------- lobby ---------- */
.lobby { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; }
.code-banner { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; background: rgba(0,0,0,.3); border: 1px dashed var(--gold-soft); border-radius: 16px; padding: 12px 16px; }
.code-banner .code { font-family: "Fraunces"; font-size: 30px; font-weight: 800; letter-spacing: 8px; color: var(--gold); }
.lobby-friends-invite { display: flex; flex-direction: column; gap: 8px; }
.lobby-friends-toggle { min-height: 28px; }
.lobby-friends-title { margin: 0; }
.lobby-friends-body { display: flex; flex-direction: column; gap: 8px; }
.friends-panel { gap: 10px; }
.friends-panel.collapsed { padding-top: 14px; padding-bottom: 14px; }
.friends-panel-toggle {
  display: flex; align-items: center; gap: 10px; width: 100%;
  margin: 0; padding: 0; border: 0; background: transparent; color: inherit;
  font: inherit; text-align: left; cursor: pointer;
}
.friends-panel-title {
  font-size: 19px; font-weight: 800; color: var(--gold); letter-spacing: .2px;
}
.friends-panel-chevron {
  margin-left: auto; opacity: .7; font-size: 14px; line-height: 1;
}
.friends-online-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 700; letter-spacing: .3px;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(0,0,0,.22); border: 1px solid rgba(245,239,223,.14);
  color: rgba(245,239,223,.75);
}
.friends-online-chip.hot {
  color: #c8f0d0; border-color: rgba(119,217,139,.45);
  background: rgba(40,100,55,.28);
}
.friends-online-chip .dot { width: 7px; height: 7px; }
.friends-panel-body { display: flex; flex-direction: column; gap: 12px; }

.emoji-btn {
  border: 0; background: rgba(245,239,223,.08); cursor: pointer;
  border-radius: 10px; padding: 2px 4px; line-height: 1;
}
.emoji-btn:hover, .emoji-btn:focus-visible {
  outline: 2px solid var(--gold); outline-offset: 1px;
}
.emoji-picker { text-align: center; }
.emoji-grid {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px; margin: 8px 0 14px;
}
.emoji-grid button {
  font-size: 28px; line-height: 1.2; padding: 10px 6px; border-radius: 12px;
  border: 1px solid rgba(245,239,223,.14); background: rgba(0,0,0,.22);
  cursor: pointer; color: inherit;
}
.emoji-grid button.on {
  border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold);
  background: rgba(216,180,90,.18);
}

.friend-invite-banner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  padding: 12px 14px; border-radius: 14px; margin-bottom: 10px;
  background: rgba(119, 217, 139, .12); border: 1px solid rgba(119, 217, 139, .4);
}
.friend-invite-float {
  position: fixed; left: 50%; top: max(12px, env(safe-area-inset-top));
  transform: translateX(-50%); z-index: 70; width: min(92vw, 440px);
  margin: 0; box-shadow: 0 10px 28px rgba(0,0,0,.45);
  background: rgba(18, 42, 30, .96);
}
.friend-invite-copy { flex: 1 1 160px; font-size: 13.5px; line-height: 1.35; min-width: 0; }
.friend-invite-copy b { display: block; color: var(--gold); font-size: 12px; letter-spacing: .5px; text-transform: uppercase; margin-bottom: 2px; }
.friend-invite-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.notify-nudge {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  padding: 12px 14px; border-radius: 14px; margin-bottom: 10px;
  background: rgba(119, 217, 139, .1); border: 1px solid rgba(119, 217, 139, .35);
}
.notify-nudge.muted { background: rgba(0,0,0,.2); border-color: rgba(245,239,223,.15); }
.notify-nudge-copy { flex: 1 1 180px; font-size: 13.5px; line-height: 1.35; min-width: 0; }
.notify-nudge-copy b { display: block; color: var(--gold); font-size: 12px; letter-spacing: .5px; text-transform: uppercase; margin-bottom: 2px; }
.notify-nudge-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.seat-list { display: flex; flex-direction: column; gap: 8px; }
.seat-list-shuffle .seat-row { animation: seatShuffle .65s ease; }
@keyframes seatShuffle {
  0% { transform: translateX(0); opacity: 1; }
  35% { transform: translateX(10px); opacity: .55; }
  70% { transform: translateX(-6px); opacity: .85; }
  100% { transform: none; opacity: 1; }
}
.seat-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.seat-row { display: flex; align-items: center; gap: 12px; background: rgba(0,0,0,.24); border-radius: 14px; padding: 10px 14px; border: 1px solid rgba(245,239,223,.12); }
.seat-row .emoji { font-size: 22px; }
.seat-row .name { font-weight: 700; flex: 1; }
.dot { width: 9px; height: 9px; border-radius: 50%; background: #77d98b; box-shadow: 0 0 8px #77d98b; }
.dot.off { background: #97a0a6; box-shadow: none; opacity: .6; }
.tag { font-size: 11px; font-weight: 800; letter-spacing: 1px; padding: 3px 8px; border-radius: 8px; background: rgba(216,180,90,.2); color: var(--gold); text-transform: uppercase; }
.settings { display: flex; flex-direction: column; gap: 10px; }
.setting { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.setting .lab { font-weight: 600; font-size: 14px; }
.seg { display: flex; background: rgba(0,0,0,.3); border-radius: 12px; padding: 3px; gap: 3px; }
.seg button { border: 0; background: transparent; color: var(--cream); font-weight: 700; font-size: 13px; padding: 7px 12px; border-radius: 9px; opacity: .65; }
.seg button.on { background: var(--gold); color: #3a2c10; opacity: 1; }
.seg button:disabled { cursor: default; }
.add-bot-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.add-bot-row .seg-compact { padding: 2px; gap: 2px; }
.add-bot-row .seg-compact button { padding: 5px 9px; font-size: 12px; }

/* ---------- table ---------- */
.table { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.roomtag { font-size: 12px; letter-spacing: 3px; font-weight: 800; color: var(--gold); opacity: .9; }
.seats-strip {
  display: flex; gap: 8px; overflow-x: auto; padding: 10px 2px 4px; scrollbar-width: none;
  /* padding-top reserves room for speech bubbles; overflow-x:auto otherwise clips them */
}
.seats-strip::-webkit-scrollbar { display: none; }
.chip {
  min-width: 92px; background: rgba(0,0,0,.28); border: 2px solid rgba(245,239,223,.14);
  border-radius: 14px; padding: 8px 10px; display: flex; flex-direction: column; gap: 3px; position: relative; transition: border-color .2s, box-shadow .2s;
}
.chip.turn {
  border-color: var(--gold); border-width: 2.5px;
  box-shadow: 0 0 0 2px rgba(216,180,90,.45), 0 0 22px rgba(216,180,90,.55);
}
.chip.you { background: rgba(216,180,90,.12); }
.chip .top { display: flex; align-items: center; gap: 6px; }
.chip .nm { font-weight: 700; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; max-width: 100%; }
.chip .cards { font-size: 12px; opacity: .85; }
.chip .hand-count-tick {
  display: inline-block; margin-left: 4px; color: var(--gold); font-weight: 900;
  animation: handTickPop .75s ease-out forwards;
}
@keyframes handTickPop {
  0% { opacity: 0; transform: translateY(4px) scale(.85); }
  25% { opacity: 1; transform: translateY(-2px) scale(1.15); }
  100% { opacity: 0; transform: translateY(-10px) scale(1); }
}
.chip .medal { position: absolute; top: -8px; right: -6px; font-size: 18px; filter: drop-shadow(0 2px 4px rgba(0,0,0,.5)); }
.chip .last { color: var(--gold); font-size: 10.5px; font-weight: 800; letter-spacing: .5px; }
.timer-wrap { position: relative; width: 100%; min-height: 7px; margin-top: 3px; }
.timerbar { height: 4px; border-radius: 4px; background: rgba(255,255,255,.14); overflow: hidden; margin-top: 0; }
.timerbar i { display: block; height: 100%; background: linear-gradient(90deg, #e8c979, var(--gold)); border-radius: 4px; transition: width .2s linear; }
.timerbar i.low { background: linear-gradient(90deg, #d98b74, var(--danger)); }
.timer-wrap.final-five { min-height: 20px; }
.timer-wrap.final-five .timerbar { margin-right: 24px; transform: translateY(6px); }
.timer-tick {
  position: absolute; right: 1px; top: -3px;
  min-width: 19px; height: 19px; display: grid; place-items: center;
  border-radius: 50%; color: #fff4ee; background: var(--danger);
  font-size: 12px; line-height: 1; font-weight: 900;
  box-shadow: 0 0 0 2px rgba(217, 107, 86, .22), 0 0 12px rgba(217, 107, 86, .5);
  animation: timerTickPop .28s ease-out;
}
.timer-wrap.afk-alert .timerbar {
  box-shadow: 0 0 9px rgba(217, 107, 86, .6);
}
.timer-wrap.afk-alert .timer-tick {
  animation: timerTickPop .28s ease-out, timerUrgent 1s ease-in-out infinite;
}
@keyframes timerTickPop {
  from { transform: scale(.65); opacity: .45; }
  to { transform: scale(1); opacity: 1; }
}
@keyframes timerUrgent {
  50% { box-shadow: 0 0 0 4px rgba(217, 107, 86, .2), 0 0 16px rgba(217, 107, 86, .75); }
}

/* justify/align "safe center" (not plain "center") matters once overflow-y:auto
   is in play: a plain centered flex container clips content that overflows
   ABOVE the centered position instead of making it reachable by scrolling —
   "safe" falls back to start-alignment only when content doesn't fit, so the
   rare overflow case stays scrollable instead of silently losing its top. */
.centre { flex: 1; min-height: 0; overflow-y: auto; display: flex; align-items: safe center; justify-content: safe center; gap: 26px; position: relative; }
.ring {
  position: absolute; width: 300px; height: 300px; border-radius: 50%;
  border: 2px dashed rgba(216,180,90,.35); animation: none; pointer-events: none;
}
.ring.cw { animation: spin 22s linear infinite; }
.ring.acw { animation: spin 22s linear infinite reverse; }
.ring::before { content: "▸"; position: absolute; top: -13px; left: 50%; transform: translateX(-50%); color: var(--gold); font-size: 18px; }
@keyframes spin { to { transform: rotate(360deg); } }

.pile { position: relative; width: 96px; height: 134px; }
.deck-btn { width: 96px; height: 134px; border-radius: 12px; border: 2px solid rgba(245,239,223,.3);
  background: repeating-linear-gradient(45deg, #274d38 0 8px, #1e412e 8px 16px); color: var(--cream);
  font-weight: 800; font-size: 13px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
  box-shadow: 0 8px 18px rgba(0,0,0,.4);
}
.deck-btn:not(:disabled):hover { border-color: var(--gold); }
.deck-btn .n { font-size: 20px; color: var(--gold); }

.card {
  width: 96px; height: 134px; border-radius: 12px; background: var(--cream); color: var(--ink);
  border: 1px solid rgba(0,0,0,.2); box-shadow: 0 8px 18px rgba(0,0,0,.4);
  display: flex; flex-direction: column; justify-content: space-between; padding: 8px 9px;
  font-weight: 800; position: relative; user-select: none;
}
.card.red { color: var(--red); }
.card .corner { font-size: 16px; line-height: 1.05; }
.card .corner.b { align-self: flex-end; transform: rotate(180deg); }
.card .mid { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 40px; }
.card .ptag {
  position: absolute; left: 50%; bottom: 7px; transform: translateX(-50%);
  font-size: 8.5px; letter-spacing: .6px; font-weight: 800; padding: 2px 6px; border-radius: 6px;
  background: rgba(34,34,42,.85); color: var(--gold); white-space: nowrap;
}
.discard-wrap { position: relative; width: 96px; height: 134px; }
.discard-wrap .under { position: absolute; inset: 0; transform: rotate(-7deg) translate(-4px, 2px); filter: brightness(.85); }
.discard-wrap .top { position: absolute; inset: 0; }
@keyframes drop { from { transform: translateY(-26px) scale(1.06); opacity: .4; } to { transform: none; opacity: 1; } }

.badges { position: absolute; top: 6px; left: 50%; transform: translateX(-50%); display: flex; flex-wrap: wrap; justify-content: center; max-width: 92vw; gap: 8px; z-index: 3; }
.badge { background: rgba(0,0,0,.55); border: 1px solid var(--gold-soft); color: var(--gold); font-weight: 800; font-size: 13px; border-radius: 999px; padding: 6px 13px; backdrop-filter: blur(4px); }
.badge.hot { animation: pulse 1s ease infinite; }
@keyframes pulse { 50% { transform: scale(1.06); } }

.msgbar { text-align: center; font-size: 14.5px; min-height: 40px; padding: 8px 12px; background: rgba(0,0,0,.25); border-radius: 12px; border: 1px solid rgba(245,239,223,.1); display: flex; align-items: center; justify-content: center; }
.msgbar-history {
  width: 100%; position: relative; color: var(--cream); font-family: inherit; cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.msgbar-history:hover, .msgbar-history:focus-visible {
  border-color: var(--gold-soft); background: rgba(0,0,0,.34);
}
.msgbar-history > span { position: absolute; right: 12px; color: var(--gold); font-size: 20px; }

.actions {
  display: flex; gap: 22px; justify-content: center; align-items: center; flex-wrap: wrap; min-height: 46px;
}
.actions .btn.pass-btn {
  min-width: 96px; margin-left: 4px; opacity: .92;
}
@media (max-width: 420px) {
  .actions { flex-direction: column; gap: 12px; }
  .actions .btn.pass-btn { margin-left: 0; width: min(100%, 200px); }
}

.hand-area { position: relative; }
/* centered when the hand fits, but never lets justify-content:center trap
   the overflow on one side unreachable by scroll — auto-margin spacers
   collapse to nothing once the hand is wider than the viewport, so every
   card stays scrollable instead of some being pushed off permanently */
.hand {
  display: flex; padding: 10px 6px 4px; min-height: 128px; flex-wrap: nowrap;
  overflow-x: auto; scrollbar-width: none; justify-content: safe center;
}
.hand::after { content: ""; margin: auto; }
.hand::-webkit-scrollbar { display: none; }
.hcard { flex: 0 0 auto; margin-left: -34px; transition: transform .15s ease, filter .2s; border: 0; padding: 0; background: none; }
.hcard:first-child { margin-left: 0; }
.hcard .card { width: 84px; height: 118px; }
.hcard.ok .card { box-shadow: var(--glow); }
.hcard.dim .card { filter: brightness(.62) saturate(.7); }
/* hover lift only on real pointers — sticky :hover on touch looks like a stuck selection */
@media (hover: hover) and (pointer: fine) {
  .hcard.ok:hover, .hcard.ok:focus-visible { transform: translateY(-14px); }
}
.hand-label { text-align: center; font-size: 11.5px; letter-spacing: 2px; text-transform: uppercase; opacity: .6; font-weight: 700; }

/* pickers + dialogs */
.sheet {
  position: fixed; inset: 0; background: rgba(6,16,11,.72); display: flex; align-items: center; justify-content: center; z-index: 40; padding: 18px; backdrop-filter: blur(3px);
}
.sheet .panel { max-width: 380px; width: 100%; text-align: center; animation: sheetIn .28s cubic-bezier(.22, 1, .36, 1); }
.suit-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.suit-grid button { font-size: 30px; padding: 16px; border-radius: 14px; border: 1.5px solid rgba(245,239,223,.25); background: rgba(0,0,0,.3); color: var(--cream); font-weight: 800; }
.suit-grid button.red { color: #ff9c8a; }
.suit-grid button:hover { border-color: var(--gold); }

/* toasts + banners */
.toast {
  position: fixed; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); z-index: 60;
  background: rgba(30, 12, 10, .93); color: #ffd9cf; border: 1px solid rgba(201,111,90,.6);
  border-radius: 12px; padding: 11px 18px; font-weight: 700; font-size: 14px; animation: toastin .2s ease;
  max-width: min(90vw, 480px); text-align: center;
}
@keyframes toastin { from { transform: translate(-50%, 12px); opacity: 0; } }

.install-nudge {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  padding: 12px 14px; border-radius: 14px;
  background: rgba(201, 164, 74, .12); border: 1px solid rgba(201, 164, 74, .35);
}
.install-nudge-copy { flex: 1 1 180px; font-size: 13.5px; line-height: 1.35; min-width: 0; }
.install-nudge-copy b { display: block; color: var(--gold); font-size: 12px; letter-spacing: .5px; text-transform: uppercase; margin-bottom: 2px; }
.install-nudge-actions { display: flex; gap: 8px; flex: 0 0 auto; }

/* quick-chat speech bubble — anchored to the sender's seat chip.
   Sits in the seats-strip padding-top so overflow-x scrolling can't clip it. */
.speech-bubble {
  position: absolute; left: 50%; bottom: calc(100% + 6px); transform: translateX(-50%);
  z-index: 8; pointer-events: none; white-space: nowrap; max-width: min(160px, 80vw);
  overflow: hidden; text-overflow: ellipsis;
  background: rgba(0,0,0,.88); border: 1.5px solid var(--gold);
  color: var(--cream);
  border-radius: 12px; padding: 7px 12px; font-size: 12.5px; font-weight: 700;
  box-shadow: 0 6px 16px rgba(0,0,0,.5); animation: speechin .18s ease;
}
.chip:first-child .speech-bubble { left: 0; transform: none; }
.chip:first-child .speech-bubble::after { left: 24px; transform: none; }
.chip:last-child .speech-bubble { left: auto; right: 0; transform: none; }
.chip:last-child .speech-bubble::after { left: auto; right: 24px; transform: none; }
.speech-bubble::after {
  content: ""; position: absolute; left: 50%; top: 100%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: rgba(0,0,0,.88);
}
@keyframes speechin {
  from { opacity: 0; margin-bottom: -4px; }
  to { opacity: 1; margin-bottom: 0; }
}

/* legacy in-flow toast (unused by table; kept for safety) */
.reaction-toast {
  display: flex; align-items: center; gap: 8px; align-self: center;
  background: rgba(0,0,0,.4); border: 1px solid var(--gold-soft); color: var(--cream);
  border-radius: 999px; padding: 8px 16px; font-size: 13.5px; font-weight: 700;
  animation: toastin .2s ease; max-width: min(92vw, 420px);
}
.reaction-toast .reaction-who, .chat-history-row .reaction-who { color: var(--gold); white-space: nowrap; }
.reaction-toast .reaction-text, .chat-history-row .reaction-text { opacity: .95; }

/* quick-chat picker */
.quick-chat { max-width: 380px; }
.quick-chat-grid { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.quick-chat-btn {
  border: 1.5px solid rgba(245,239,223,.25); background: rgba(0,0,0,.28); color: var(--cream);
  font-weight: 700; font-size: 13px; padding: 9px 13px; border-radius: 12px;
}
.quick-chat-btn:hover { border-color: var(--gold); }
.quick-chat-targets { display: flex; flex-direction: column; gap: 8px; max-height: 40vh; overflow-y: auto; }
.chat-history {
  text-align: left; max-height: 28vh; overflow-y: auto; margin: 0 0 12px;
  padding: 8px 10px; background: rgba(0,0,0,.22); border-radius: 12px;
  border: 1px solid rgba(245,239,223,.1); display: flex; flex-direction: column; gap: 6px;
}
.chat-history-label {
  font-size: 11px; letter-spacing: 2px; text-transform: uppercase; opacity: .55; font-weight: 800;
}
.chat-history-row { display: flex; gap: 8px; font-size: 13px; font-weight: 700; }

.table-menu { max-width: 320px; }
.table-menu-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.table-menu-list .btn { width: 100%; }
.table-menu-sound { display: flex; flex-direction: column; gap: 8px; padding: 4px 0 6px; }
.table-menu-sound-lab { font-size: 12px; font-weight: 800; letter-spacing: 1px; text-transform: uppercase; opacity: .7; }
.table-menu-sound .seg { width: 100%; }
.table-menu-sound .seg button { flex: 1; }
.info-banner.spectator-banner {
  display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap;
}

.conn-banner {
  background: rgba(201,111,90,.18); border: 1px solid rgba(201,111,90,.5); color: #ffd9cf;
  border-radius: 12px; padding: 9px 14px; text-align: center; font-weight: 700; font-size: 13.5px;
}
.info-banner {
  background: rgba(216,180,90,.14); border: 1px solid var(--gold-soft); color: var(--gold);
  border-radius: 12px; padding: 9px 14px; text-align: center; font-weight: 700; font-size: 13.5px;
}

/* leaderboard */
.board { display: flex; flex-direction: column; gap: 10px; max-width: 460px; margin: 0 auto; width: 100%; }
.board-row { display: flex; align-items: center; gap: 14px; background: rgba(0,0,0,.28); border: 1px solid rgba(245,239,223,.14); border-radius: 16px; padding: 14px 18px; }
.board-row.first { border-color: var(--gold); box-shadow: 0 0 18px rgba(216,180,90,.25); }
.board-row .place { font-family: "Fraunces"; font-size: 24px; font-weight: 800; color: var(--gold); width: 44px; }
.board-row .nm { font-weight: 800; font-size: 17px; flex: 1; }
.board-row .note { font-size: 12px; opacity: .7; }

@media (max-width: 520px) {
  .centre { gap: 14px; }
  .ring { width: 240px; height: 240px; }
  .pile, .deck-btn, .card, .discard-wrap { width: 82px; height: 116px; }
  .hcard .card { width: 74px; height: 104px; }
  .hcard { margin-left: -30px; }
}

/* ---------- short/landscape viewports ----------
   every breakpoint above this point keys off max-width — a landscape phone
   (e.g. 667x375) is WIDER than all of them, so it got zero special-casing
   and had to fall back on the page-scroll this whole file is trying to
   avoid. This is the first max-height query in the file; it compacts chrome
   (seat chips, hand tray, action bar) so there's more room left for the
   actual board/pile before .centre's own overflow-y:auto safety net (or,
   for Dominoes, boardMetricsFor's height-aware tile shrink) has to engage. */
@media (max-height: 480px) {
  .seats-strip { padding: 24px 2px 4px; }
  .chip { padding: 6px 8px; gap: 2px; }
  .chip .top { gap: 4px; }
  .timer-wrap { min-height: 5px; margin-top: 2px; }
  .hand { min-height: 96px; padding: 6px 6px 3px; }
  .card, .pile, .deck-btn, .discard-wrap { width: 64px; height: 90px; }
  .hcard .card { width: 60px; height: 84px; }
  .actions { min-height: 34px; gap: 14px; }
  .dom-tile-h { width: 48px; height: 24px; }
  .dom-tile-v { width: 24px; height: 48px; }
  .dom-tile-back { width: 26px; height: 50px; }
}

/* ---------- iPhone/Safari viewport fixes ---------- */
/* ---------- iPhone/Android/Arc viewport fixes ----------
   100dvh recalculates live as browser chrome shows/hides, which causes
   visible reflow on some Chromium engines (reported on Arc for Android).
   100svh (small viewport â€” chrome fully expanded) is the stable choice for
   a fixed-layout app like this. A JS-computed --vh custom property is the
   fallback for browsers that support neither. */
:root { --vh: 1vh; }
body { height: calc(var(--vh) * 100); }
@supports (height: 100svh) {
  body { height: 100svh; }
}
.shell { padding-top: max(14px, env(safe-area-inset-top)); }

/* ---------- your-turn prominence ---------- */
.your-turn-banner {
  text-align: center; font-family: "Fraunces", serif; font-weight: 800; font-size: 15px;
  letter-spacing: 3px; color: #22222a; background: linear-gradient(180deg, #f3da9a, var(--gold));
  border-radius: 12px; padding: 8px; box-shadow: 0 4px 16px rgba(216,180,90,.5);
  animation: turnpulse 1.1s ease-in-out infinite;
}

/* First-game contextual coaching: compact enough to sit between the turn
   banner and table without becoming another modal players must dismiss. */
.coach-hint {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: 12px;
  background: rgba(16, 38, 25, .94);
  border: 1px solid rgba(216, 180, 90, .5);
  box-shadow: 0 5px 18px rgba(0, 0, 0, .3);
  color: var(--cream); font-size: 12.5px;
}
.coach-icon { flex: 0 0 auto; font-size: 18px; }
.coach-copy { flex: 1; min-width: 0; line-height: 1.35; }
.coach-copy b { display: block; color: var(--gold); font-size: 12px; text-transform: uppercase; letter-spacing: .6px; }
.coach-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
.coach-actions .btn.small { padding: 6px 10px; }
.coach-skip {
  border: 0; padding: 4px 2px; background: transparent; color: var(--cream);
  opacity: .62; font: inherit; font-size: 11px; text-decoration: underline; cursor: pointer;
}
@media (max-width: 520px) {
  /* previously forced .coach-actions onto its own full-width row below the
     copy on every narrow phone (not just short ones) — costing a whole
     extra ~30px row even when the buttons would happily fit beside a
     couple of wrapped text lines. Let flex-wrap decide only when content
     genuinely doesn't fit, instead of forcing it every time. */
  .coach-hint { align-items: flex-start; flex-wrap: wrap; }
  .coach-copy { flex-basis: 140px; }
  .coach-actions { justify-content: flex-end; }
}
@keyframes turnpulse {
  0%, 100% { transform: scale(1); box-shadow: 0 4px 16px rgba(216,180,90,.5); }
  50% { transform: scale(1.025); box-shadow: 0 4px 26px rgba(216,180,90,.85); }
}
.chip.pulse { animation: chippulse 1.1s ease-in-out infinite; }
@keyframes chippulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(216,180,90,.45), 0 0 18px rgba(216,180,90,.5); }
  50% { box-shadow: 0 0 0 3px rgba(216,180,90,.75), 0 0 32px rgba(216,180,90,.95); }
}
.pulse-btn { animation: btnpulse 1s ease-in-out infinite; }
@keyframes btnpulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

/* ---------- wild (declared joker) marker on a card face ---------- */
.wildmark {
  position: absolute; top: 4px; right: 5px; font-size: 13px;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.5));
}

/* ---------- joker declare sheet — 13 ranks on 2 rows (7+6) ---------- */
.value-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.value-grid button {
  flex: 0 0 calc(14.285% - 7px); min-width: 38px;
  padding: 16px 0; border-radius: 12px; border: 1.5px solid rgba(245,239,223,.22);
  background: rgba(0,0,0,.28); color: var(--cream); font-weight: 800; font-size: 16px;
  min-height: 48px; text-align: center;
}
.value-grid button.on { border-color: var(--gold); background: rgba(216,180,90,.22); color: var(--gold); }
.value-grid button[aria-disabled="true"] { opacity: .3; }
@media (max-width: 420px) {
  .value-grid { gap: 6px; }
  .value-grid button { flex: 0 0 calc(14.285% - 5.2px); min-width: 32px; padding: 12px 0; font-size: 14px; min-height: 44px; }
}
.suit-grid.slim button { padding: 10px; font-size: 22px; }
.suit-grid.slim button.on { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(216,180,90,.4) inset; }
.suit-grid.slim button[aria-disabled="true"] { opacity: .3; }

/* ---------- rules sheet ---------- */
.panel.rules { text-align: left; max-width: 440px; max-height: 82vh; overflow-y: auto; }
.panel.rules h2 { text-align: center; }
.panel.rules ul { margin: 0 0 6px; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; font-size: 13.5px; line-height: 1.4; }
.panel.rules li::marker { color: var(--gold); }

/* ---------- hand label row (with manual Sort control) ---------- */
.hand-label-row { display: flex; align-items: center; justify-content: center; gap: 10px; position: relative; min-height: 28px; }
.hand-label-row .hand-label { margin: 0; }
.hand-label-actions { position: absolute; right: 4px; display: flex; gap: 6px; align-items: center; }
.hand-label-actions .sort-btn { position: static; }
.clear-btn { position: absolute; left: 4px; padding: 5px 12px; font-size: 11px; }
.sort-btn { position: absolute; right: 4px; padding: 5px 12px; font-size: 11px; }

/* ---------- drag-to-reorder hand ---------- */
/* the wrapper is now the flex item carrying the fan overlap */
.hand .hcard, .hand .hcard:first-child { margin-left: 0; }
.hcard-wrap { flex: 0 0 auto; margin-left: -34px; touch-action: pan-x; user-select: none; -webkit-user-select: none; }
.hcard-wrap:first-child { margin-left: 0; }
.hcard-wrap.dragging { z-index: 6; position: relative; cursor: grabbing; }
.hcard-wrap.dragging .card {
  transform: translateY(-18px) scale(1.08) rotate(1.5deg);
  box-shadow: 0 18px 34px rgba(0,0,0,.55), var(--glow);
}
.hcard[aria-disabled="true"] { cursor: default; }
.hcard[aria-disabled="false"] { cursor: pointer; }
@media (max-width: 520px) { .hcard-wrap { margin-left: -30px; } .hcard-wrap:first-child { margin-left: 0; } }

/* ---------- stale-tab update banner ---------- */
.update-banner {
  background: rgba(216,180,90,.16); border: 1px solid var(--gold-soft); color: var(--gold);
  border-radius: 12px; padding: 10px 14px; text-align: center; font-weight: 700; font-size: 13px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px;
}

/* ---------- play-by-play timeline: side drawer desktop, bottom sheet mobile ---------- */
.history-backdrop {
  position: fixed; inset: 0; z-index: 45; display: flex; justify-content: flex-end;
  background: rgba(4, 12, 8, .58); backdrop-filter: blur(2px);
}
.history-drawer {
  position: relative; width: min(460px, 92vw); height: 100%;
  display: flex; flex-direction: column; overflow: hidden;
  color: var(--cream); background: linear-gradient(180deg, #173d29, #0c2518);
  border-left: 1px solid rgba(216,180,90,.35);
  box-shadow: -14px 0 38px rgba(0,0,0,.45);
  animation: historySlideIn .24s cubic-bezier(.22, 1, .36, 1);
}
@keyframes historySlideIn { from { transform: translateX(100%); } }
.history-head {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  padding: max(16px, env(safe-area-inset-top)) 18px 12px;
  border-bottom: 1px solid rgba(245,239,223,.1);
}
.history-head h2 { margin: 0; color: var(--gold); font-size: 20px; }
.history-head span { font-size: 11px; opacity: .58; text-transform: uppercase; letter-spacing: 1px; }
.history-close {
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid rgba(245,239,223,.2);
  background: rgba(0,0,0,.22); color: var(--cream); font-size: 25px; line-height: 1; cursor: pointer;
}
.history-filters {
  flex: 0 0 auto; display: flex; gap: 6px; padding: 10px 12px;
  overflow-x: auto; border-bottom: 1px solid rgba(245,239,223,.08);
  scrollbar-width: none;
}
.history-filters::-webkit-scrollbar { display: none; }
.history-filters button {
  flex: 0 0 auto; border: 1px solid rgba(245,239,223,.18); border-radius: 999px;
  padding: 7px 11px; background: rgba(0,0,0,.2); color: var(--cream);
  font-size: 11px; font-weight: 800; cursor: pointer;
}
.history-filters button.on {
  color: #22222a; background: var(--gold); border-color: var(--gold);
}
.history-list {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  text-align: left; padding: 10px 12px max(18px, env(safe-area-inset-bottom));
  scroll-behavior: smooth;
}
.history-round { margin-bottom: 9px; }
.history-round-head {
  position: sticky; top: -10px; z-index: 2;
  width: 100%; display: flex; justify-content: space-between; align-items: center;
  border: 0; border-bottom: 1px solid rgba(216,180,90,.24);
  padding: 9px 4px 7px; background: rgba(12,37,24,.94); color: var(--gold);
  font-size: 11px; font-weight: 900; letter-spacing: 1.2px; text-transform: uppercase;
  cursor: pointer;
}
.history-events { display: flex; flex-direction: column; padding: 5px 0 4px; }
.history-row {
  position: relative; display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 9px;
  font-size: 13px; line-height: 1.4; padding: 9px 7px;
  border-bottom: 1px solid rgba(245,239,223,.07);
}
.history-row:last-child { border-bottom: 0; }
.history-marker {
  width: 27px; height: 27px; display: grid; place-items: center;
  border-radius: 50%; background: rgba(0,0,0,.28); border: 1px solid rgba(245,239,223,.12);
  font-size: 13px;
}
.history-row.kind-challenge .history-marker { background: rgba(190,93,65,.24); border-color: rgba(230,130,100,.4); }
.history-row.kind-round .history-marker { background: rgba(216,180,90,.18); border-color: var(--gold-soft); }
.history-row.busted { background: linear-gradient(90deg, rgba(180,48,36,.13), transparent); }
.history-row.true { background: linear-gradient(90deg, rgba(36,110,72,.18), transparent); }
.history-event-body { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.history-event-meta {
  display: flex; align-items: center; gap: 7px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .8px; text-transform: uppercase; opacity: .58;
}
.history-actor { color: var(--gold); opacity: 1; text-transform: none; letter-spacing: 0; font-size: 11px; }
.history-text { overflow-wrap: anywhere; }
.history-cards { display: flex; gap: 4px; flex-wrap: wrap; padding-top: 2px; }
.history-card-mini {
  width: 40px; height: 56px; overflow: visible;
}
.history-card-mini > div {
  transform: scale(0.417); transform-origin: top left; /* 96x134 base -> 40x56 */
}
.history-card-mini > div.dom-tile-h {
  transform: scale(0.625); transform-origin: top left; /* 64x32 -> 40x20 */
}
.history-card-mini > div.dom-tile-v {
  transform: scale(0.625); transform-origin: top left; /* 32x64 -> 20x40 */
}
.history-empty { text-align: center; opacity: .6; font-size: 13.5px; padding: 20px 0; }
.history-latest {
  position: absolute; right: 18px; bottom: max(18px, env(safe-area-inset-bottom));
  border: 1px solid var(--gold-soft); border-radius: 999px; padding: 9px 14px;
  background: #173d29; color: var(--gold); box-shadow: 0 6px 18px rgba(0,0,0,.4);
  font-size: 12px; font-weight: 900; cursor: pointer;
}
@media (max-width: 640px) {
  .history-backdrop { align-items: flex-end; }
  .history-drawer {
    width: 100%; height: min(88svh, 760px); border-left: 0;
    border-top: 1px solid rgba(216,180,90,.4); border-radius: 18px 18px 0 0;
    box-shadow: 0 -14px 38px rgba(0,0,0,.45);
    animation-name: historySheetIn;
  }
  @keyframes historySheetIn { from { transform: translateY(100%); } }
  .history-head { padding-top: 14px; }
}

/* ---------- decision panels (suit choice, joker declare) ----------
   These block gameplay decisions, so they read as a modal (dimmed backdrop,
   elevated card) like Rules/History — but unlike those, they're scoped to
   .centre (which already has position:relative for exactly this) instead
   of the whole viewport. .centre sits above .hand-area as a separate flex
   region, so the hand keeps rendering in normal flow, fully visible, below
   the overlay — you can still plan around what you're about to declare.
   Being absolutely positioned WITHIN .centre also means it can never push
   .table's height or force a page scroll, unlike the old push-into-flow
   layout this replaced. */
.decision-overlay {
  position: absolute; inset: 0; z-index: 6; border-radius: 14px;
  display: flex; align-items: safe center; justify-content: safe center; padding: 14px;
  background: rgba(6,16,11,.72); backdrop-filter: blur(3px);
  overflow-y: auto; animation: overlayIn .2s ease;
  transition: background .15s ease, backdrop-filter .15s ease;
}
@keyframes overlayIn { from { opacity: 0; } }
/* held via the peek button: backdrop clears so the real board/pile shows
   through; the picker card itself fades out rather than disappearing
   outright, so it doesn't lose its scroll position or re-run its entrance
   animation the instant the hold ends. pointer-events stays off it while
   peeking since there's nothing useful to tap on a fading, see-through card. */
.decision-overlay.peeking { background: transparent; backdrop-filter: none; }
.decision-overlay.peeking .inline-picker { opacity: .05; pointer-events: none; transition: opacity .15s ease; }
.peek-btn {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--gold-soft);
  background: rgba(0,0,0,.4); color: var(--cream); font-size: 15px; line-height: 1;
  display: flex; align-items: center; justify-content: center; padding: 0;
  touch-action: none; user-select: none; -webkit-user-select: none;
  transition: opacity .15s ease, background .15s ease;
}
.decision-overlay.peeking .peek-btn { background: rgba(0,0,0,.15); opacity: .5; }
.inline-picker {
  background: rgba(0,0,0,.32); border: 1.5px solid var(--gold-soft); border-radius: 16px;
  padding: 16px; display: flex; flex-direction: column; gap: 10px; align-items: center;
  text-align: center; max-width: 340px; width: 100%;
  animation: pickerIn .28s cubic-bezier(.22, 1, .36, 1);
}
.inline-picker h2 { margin: 0; color: var(--gold); font-size: 18px; }
@keyframes pickerIn { from { opacity: 0; transform: translateY(-8px) scale(.98); } }

/* ---------- "next game" section divider on the leaderboard ---------- */
.section-label {
  text-align: center; font-size: 11.5px; letter-spacing: 2px; text-transform: uppercase;
  font-weight: 800; color: var(--gold); opacity: .85; margin-top: 6px;
}

/* ================================================================
   OG CARD GAMES â€” game picker (home)
   ================================================================ */
.game-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.game-card {
  display: flex; flex-direction: column; gap: 4px; align-items: center; text-align: center;
  padding: 16px 10px; border-radius: 16px; border: 1.5px solid rgba(245,239,223,.22);
  background: rgba(0,0,0,.28); color: var(--cream); font-weight: 800; font-size: 16px;
  font-family: "Fraunces", serif; transition: border-color .15s, box-shadow .15s;
}
.game-card.on { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(216,180,90,.35) inset, 0 0 14px rgba(216,180,90,.25); color: var(--gold); }
.game-card .game-players { font-family: "Outfit"; font-size: 11.5px; font-weight: 600; opacity: .7; letter-spacing: 1px; text-transform: uppercase; }

/* ================================================================
   PRESIDENT â€” pile stage, multi-select hand, scoreboard
   ================================================================ */
.pile-stage { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.pile-stage.empty { opacity: .9; }

/* Permanent felt well for PR / BS piles — same role as BJ's discard-wrap:
   a fixed table slot that stays put when the pile burns or goes empty. */
.pile-pad {
  position: relative;
  min-width: 118px; min-height: 148px; padding: 14px 18px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 18px;
  background:
    radial-gradient(ellipse at 50% 42%, rgba(40, 72, 52, .55) 0%, rgba(8, 22, 14, .55) 70%),
    rgba(0, 0, 0, .28);
  border: 1px solid rgba(245, 239, 223, .14);
  box-shadow:
    inset 0 1px 0 rgba(245, 239, 223, .07),
    inset 0 0 32px rgba(0, 0, 0, .4),
    0 6px 16px rgba(0, 0, 0, .25);
}
.centre.pres .pile-pad { min-width: 150px; }
.pile-pad.vacant {
  background:
    radial-gradient(ellipse at 50% 42%, rgba(30, 54, 40, .4) 0%, rgba(6, 16, 11, .45) 70%),
    rgba(0, 0, 0, .2);
}
.pile-pad-ghost {
  width: 84px; height: 118px; border-radius: 12px;
  border: 2px dashed rgba(245, 239, 223, .22);
  background: rgba(0, 0, 0, .14);
  box-shadow: inset 0 0 12px rgba(0, 0, 0, .25);
}

.play-fan { display: flex; position: relative; z-index: 1; }
.fan-card { margin-left: -58px; }
.fan-card:first-child { margin-left: 0; }
.pile-under { position: absolute; left: 50%; top: 50%; transform: translate(calc(-50% - 10px), calc(-50% + 4px)) rotate(-6deg) scale(.94); filter: brightness(.6); pointer-events: none; z-index: 0; }
.pile-note {
  font-size: 12.5px; font-weight: 800; letter-spacing: 1px; text-transform: uppercase;
  color: var(--gold); background: rgba(0,0,0,.45); border-radius: 999px; padding: 5px 14px;
}
.pile-note.big { font-size: 15px; text-transform: none; letter-spacing: .3px; padding: 12px 20px; }

/* exchange card flight — face-down chip→chip (spectators / uninvolved) */
.flight-card {
  width: 28px; height: 40px; border-radius: 5px; position: relative;
  border: 1.5px solid rgba(245,239,223,.4);
  background: repeating-linear-gradient(45deg, #274d38 0 6px, #1e412e 6px 12px);
  box-shadow: 0 4px 10px rgba(0,0,0,.45);
}
.flight-tile {
  width: 28px; height: 56px; border-radius: 5px;
  border: 1.5px solid rgba(245,239,223,.35);
  background: repeating-linear-gradient(45deg, #274d38 0 8px, #1e412e 8px 16px);
  box-shadow: 0 4px 10px rgba(0,0,0,.45);
}

/* center deal stack shown briefly while cards fly to seats */
.deal-stack {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 62px; z-index: 5; pointer-events: none;
}
.deal-stack.tiles { width: 32px; height: 60px; }
.deal-stack .flight-card, .deal-stack .flight-tile {
  position: absolute; left: 0; top: 0;
}
.deal-stack .flight-card:nth-child(2), .deal-stack .flight-tile:nth-child(2) { transform: translate(2px, -2px); }
.deal-stack .flight-card:nth-child(3), .deal-stack .flight-tile:nth-child(3) { transform: translate(-2px, 2px); }

/* BJ deal ceremony — shuffle pile center, then deck slides left */
.centre.dealing .deck-btn,
.centre.dealing .discard-wrap,
.centre.dealing .pile-stage,
.centre.blind-first .discard-wrap {
  opacity: 0;
  pointer-events: none;
}
.centre.deck-slide .deck-btn {
  animation: deckSlideIn .48s ease;
}
@keyframes deckSlideIn {
  from { transform: translateX(48px) scale(.92); opacity: .25; }
  to { transform: none; opacity: 1; }
}

/* face-down discard during blind first-choice */
.card.face-down {
  background: repeating-linear-gradient(45deg, #274d38 0 10px, #1e412e 10px 20px);
  color: transparent;
  border: 1.5px solid rgba(245,239,223,.35);
}
.card.face-down .corner, .card.face-down .mid, .card.face-down .ptag, .card.face-down .wildmark { visibility: hidden; }
.card.flip-in, .discard-wrap .top.flip-in { animation: cardFlipIn .45s ease; }
@keyframes cardFlipIn {
  0% { transform: rotateY(90deg) scale(.92); opacity: .4; }
  100% { transform: none; opacity: 1; }
}

/* tribute ceremony — peasants see what they lose; recipients see what arrived */
.tribute-preview {
  position: fixed; left: 50%; top: 42%; transform: translate(-50%, -50%);
  z-index: 50; pointer-events: none; text-align: center;
  background: rgba(6, 16, 11, .92); border: 1.5px solid var(--gold-soft);
  border-radius: 18px; padding: 16px 18px 14px;
  box-shadow: 0 16px 40px rgba(0,0,0,.55);
  animation: tributeIn .25s ease;
}
.tribute-preview.out { border-color: rgba(201,111,90,.7); }
.tribute-preview.in { border-color: var(--gold); }
.tribute-preview-title {
  font-size: 13px; font-weight: 800; letter-spacing: 1px; text-transform: uppercase;
  color: var(--gold); margin-bottom: 12px;
}
.tribute-preview.out .tribute-preview-title { color: #ffb4a4; }
.tribute-preview-cards { display: flex; gap: 10px; justify-content: center; }
.tribute-preview-card { animation: tributePulse 1.1s ease-in-out infinite; }
.tribute-preview-card .card { width: 72px; height: 100px; box-shadow: var(--glow); }
@keyframes tributeIn { from { opacity: 0; transform: translate(-50%, -42%) scale(.94); } }
@keyframes tributePulse { 50% { transform: translateY(-4px); } }

/* briefly mark cards that just arrived in your hand */
.hcard-wrap.flash-new .card {
  box-shadow: 0 0 0 3px var(--gold), var(--glow);
  animation: newCardFlash 2.4s ease;
}
@keyframes newCardFlash {
  0%, 100% { filter: brightness(1); }
  20%, 50% { filter: brightness(1.18); }
  35% { filter: brightness(1.28); }
}

/* selected cards in the multi-select hand */
.hcard { transform: none; }
.hcard.sel .card { box-shadow: var(--glow); }
.hcard.sel { transform: translateY(-16px); }
/* kill sticky mobile :hover lift that mimics selection after a tap */
.hcard.ok:active { transform: none; }

/* round-over / shareable moment card */
.round-over-panel,
.moment-card {
  background:
    linear-gradient(165deg, rgba(35, 52, 40, 0.92) 0%, rgba(0, 0, 0, 0.42) 55%, rgba(0, 0, 0, 0.5) 100%);
  border: 1.5px solid var(--gold-soft);
  border-radius: 18px;
  padding: 18px 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 380px;
  width: 100%;
  text-align: center;
  animation: pickerIn .15s ease;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(245, 239, 223, 0.06);
}
.moment-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--gold);
  opacity: 0.85;
}
.moment-card .moment-title,
.round-over-panel h2,
.moment-title {
  margin: 0;
  color: var(--gold);
  font-size: 22px;
  font-family: "Fraunces", serif;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0.2px;
}
.moment-subtitle {
  font-size: 13px;
  opacity: 0.75;
  margin-top: -4px;
}
.moment-rows,
.round-roles {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.moment-row,
.round-role-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  background: rgba(0, 0, 0, 0.28);
  border-radius: 10px;
  padding: 8px 12px;
  text-align: left;
}
.moment-row.champ {
  border: 1px solid var(--gold-soft);
  background: rgba(216, 180, 90, 0.12);
}
.moment-row-left { font-weight: 700; }
.moment-row-right { color: var(--gold); font-weight: 800; white-space: nowrap; }
.moment-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 2px;
}
.moment-share { flex: 0 0 auto; }
.round-over-controls {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 380px;
  width: 100%;
  margin-top: 4px;
}
.streak-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 800;
  color: var(--gold);
  background: rgba(216, 180, 90, 0.14);
  border: 1px solid var(--gold-soft);
  border-radius: 999px;
  padding: 7px 14px;
  margin: 0 auto;
}
.recap-view {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: stretch;
  max-width: 420px;
  margin: 0 auto;
  width: 100%;
}
.recap-view .moment-card { max-width: none; }
.recap-invalid {
  text-align: center;
  font-size: 14px;
  opacity: 0.8;
  padding: 8px 4px;
}

/* running scoreboard grid */
.score-grid { display: grid; gap: 4px; font-size: 13px; }
.score-cell { padding: 6px 8px; background: rgba(0,0,0,.22); border-radius: 8px; text-align: center; }
.score-cell.head { font-weight: 800; color: var(--gold); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 520px) {
  .fan-card { margin-left: -62px; }
  .fan-card:first-child { margin-left: 0; }
}

/* ================================================================
   BULLSHIT â€” hidden pile stack, challenge button, reveal flash
   ================================================================ */
.buls-pile { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.buls-pile.loud .pile-pad { box-shadow: inset 0 1px 0 rgba(245,239,223,.07), inset 0 0 32px rgba(0,0,0,.4), 0 0 0 1px var(--gold-soft), 0 6px 16px rgba(0,0,0,.25); }
.buls-pile-stack { position: relative; width: 84px; height: 118px; }
.buls-pile-land {
  position: absolute; inset: 0; width: 84px; height: 118px;
  pointer-events: none; z-index: 2;
}
.buls-card-back {
  position: absolute; inset: 0; border-radius: 12px;
  border: 2px solid rgba(245,239,223,.35);
  background: repeating-linear-gradient(45deg, #274d38 0 8px, #1e412e 8px 16px);
  box-shadow: 0 6px 14px rgba(0,0,0,.45);
}
.buls-pile-count {
  font-size: 12.5px; font-weight: 800; letter-spacing: 1px; text-transform: uppercase;
  color: var(--gold); background: rgba(0,0,0,.45); border-radius: 999px; padding: 5px 14px;
}
.buls-pile-count.loud {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  font-size: 11px; letter-spacing: .6px; text-transform: uppercase; padding: 8px 16px;
  border: 1px solid var(--gold-soft); animation: pulse 1.2s ease infinite;
}
.buls-pile-count-num {
  font-size: 26px; font-weight: 900; letter-spacing: 0; line-height: 1; color: var(--gold);
  text-transform: none;
}
.msgbar.quiet { opacity: .55; font-size: 12px; }
.buls-challenge-btn { animation: pulse 1s ease infinite; }
.buls-ride-btn { min-width: 140px; }
.buls-challenge-timer {
  width: min(280px, 80vw); margin-top: 10px;
  display: flex; flex-direction: column; gap: 6px; align-items: stretch;
}
.buls-challenge-timer-label {
  font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-align: center;
  text-transform: uppercase; opacity: 0.85; color: var(--gold);
}
.buls-challenge-timer .timerbar { height: 8px; margin-top: 0; }
.buls-reveal { display: flex; flex-direction: column; align-items: center; gap: 10px; animation: drop .28s ease; max-width: 100%; }
.buls-reveal-cards { display: flex; justify-content: center; max-width: 100%; }
@media (max-width: 420px) {
  .buls-reveal-cards { transform: scale(0.85); transform-origin: center; }
}
.buls-verdict {
  font-size: 28px; font-weight: 900; letter-spacing: 0.18em; line-height: 1;
  padding: 8px 18px; border-radius: 10px; text-transform: uppercase;
  animation: buls-verdict-pop .35s ease;
}
.buls-verdict.busted {
  color: #fff4ee; background: rgba(180, 48, 36, .92);
  box-shadow: 0 0 0 2px rgba(255,120,90,.35), 0 8px 24px rgba(0,0,0,.45);
}
.buls-verdict.true {
  color: #eef8f0; background: rgba(36, 110, 72, .92);
  box-shadow: 0 0 0 2px rgba(120,200,150,.35), 0 8px 24px rgba(0,0,0,.45);
}
@keyframes buls-verdict-pop {
  from { transform: scale(.7); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}
.chip.buls-ate-pile {
  border-color: #e8a060; border-width: 2.5px;
  box-shadow: 0 0 0 2px rgba(232,160,96,.4), 0 0 22px rgba(232,160,96,.5);
  animation: buls-ate-pulse 1s ease-in-out infinite;
}
.chip.buls-dim { opacity: 0.42; filter: saturate(.7); }
.buls-ate-label { color: #e8a060 !important; }
.buls-gain {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  font-size: 11px; font-weight: 900; letter-spacing: 0.04em;
  color: #2a1810; background: #e8a060;
  animation: buls-gain-pop .4s ease;
}
@keyframes buls-ate-pulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(232,160,96,.35), 0 0 16px rgba(232,160,96,.4); }
  50% { box-shadow: 0 0 0 3px rgba(232,160,96,.55), 0 0 28px rgba(232,160,96,.65); }
}
@keyframes buls-gain-pop {
  from { transform: scale(1.5); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}
/* flying clone while Anime.js tweens hand/seat → board (or pool → seat) */
.anim-fly-ghost {
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.5) !important;
  filter: brightness(1.06);
  border-radius: 8px;
}
.anim-fade-swap { will-change: opacity; }

/* turn handoff — brief gold ring on the seat that just became current */
.chip.turn-handoff {
  animation: turnHandoff .65s ease;
  box-shadow: 0 0 0 2px var(--gold), var(--glow);
}
@keyframes turnHandoff {
  0% { transform: scale(1); }
  35% { transform: scale(1.06); }
  100% { transform: scale(1); }
}

/* pickup / ate-pile sting on a seat chip */
.chip.penalty-sting {
  animation: penaltySting .55s ease;
  border-color: #e08070 !important;
}
@keyframes penaltySting {
  0%, 100% { transform: scale(1); }
  30% { transform: scale(1.08); filter: brightness(1.15); }
  55% { transform: scale(0.97); }
}

/* sheet enter keyframes (applied on .sheet .panel above) */
@keyframes sheetIn {
  from { opacity: 0; transform: translateY(12px) scale(.97); }
  to { opacity: 1; transform: none; }
}

/* ================================================================
   DOMINOES — tile faces, board line, boneyard, shuffle & self-draw
   ================================================================ */
.dom-tile {
  display: flex; background: var(--cream); border-radius: 6px;
  border: 1px solid rgba(0,0,0,.25); box-shadow: 0 4px 10px rgba(0,0,0,.35);
  overflow: hidden; flex: 0 0 auto;
}
.dom-tile-h { width: 64px; height: 32px; flex-direction: row; }
.dom-tile-v { width: 32px; height: 64px; flex-direction: column; }
.dom-half { flex: 1; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); padding: 3px; }
.dom-pip { width: 5px; height: 5px; border-radius: 50%; background: var(--ink); justify-self: center; align-self: center; }
.dom-tile-h .dom-divider { width: 1.5px; background: rgba(0,0,0,.3); }
.dom-tile-v .dom-divider { height: 1.5px; background: rgba(0,0,0,.3); }
.dom-tile-back {
  width: 34px; height: 68px; border: 1.5px solid rgba(245,239,223,.35);
  background: repeating-linear-gradient(45deg, #274d38 0 8px, #1e412e 8px 16px);
  box-shadow: 0 4px 10px rgba(0,0,0,.35);
}
/* a tile that's been taken from the pool — same footprint as a live
   tile-back so the grid never reflows, but visibly an empty tray */
.dom-tile-back-ghost { background: none; box-shadow: none; border: 1.5px dashed rgba(245,239,223,.2); }

.dom-tile-btn {
  border: 0; background: none; padding: 2px; border-radius: 8px; flex: 0 0 auto;
  transition: transform .15s ease, filter .2s;
}
.dom-tile-btn.ok { box-shadow: var(--glow); }
.dom-tile-btn[aria-disabled="true"] { opacity: .5; cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .dom-tile-btn.ok:hover, .dom-tile-btn.ok:focus-visible { transform: translateY(-8px); }
}

/* the shared .centre is a row-flex designed for the card games' fixed-
   height pile stage, with .badges floating ABSOLUTELY over it — fine
   there, but a domino board can be many rows tall, so an absolutely
   positioned badge row would cover the board's own top rows instead
   of sitting above them. Dominoes stacks everything in normal flow
   instead: badges first, board below, nothing floats over anything. */
.centre.dom { flex-direction: column; align-items: stretch; gap: 10px; }
.dom-badges { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }

/* board: a real 90° turn at either end (the pivot tile) instead of
   running off the table edge. Tiles are absolutely positioned by JS
   (public/dominoes.mjs's Board component), sized to match the same
   width/height measurement that drove the grid's cell pitch — including
   shrinking tiles for a tight vertical budget (boardMetricsFor's
   height-aware clamp) — so overflow past THIS wrapper should be rare.
   overflow-y:auto is still the honest backstop for extreme edge cases
   (a very long round on the smallest supported phone) rather than a
   promise the estimate is pixel-perfect. */
.dom-board-wrap {
  position: relative; width: 100%; max-width: 100%; flex: 1; min-height: 0;
  display: flex; flex-direction: column; overflow: hidden;
}
.dom-board-viewport {
  position: relative; flex: 1; min-height: 0; width: 100%; overflow: hidden;
  display: flex; align-items: safe center; justify-content: center;
  touch-action: none; cursor: grab;
}
.dom-board-viewport:active { cursor: grabbing; }
.dom-zoom-bar {
  position: absolute; top: 6px; right: 6px; z-index: 6;
  display: flex; gap: 4px; padding: 3px;
  background: rgba(0,0,0,.45); border-radius: 10px; border: 1px solid rgba(245,239,223,.18);
}
.dom-zoom-bar .btn.small { padding: 4px 10px; font-size: 12px; min-width: 32px; }
.dom-board {
  position: relative; width: 100%; min-height: 90px; flex: 0 0 auto;
}
.dom-tile-positioned { position: absolute; transform: translate(-50%, -50%); }
.dom-end-glow {
  position: absolute; width: 52px; height: 52px; border-radius: 50%;
  transform: translate(-50%, -50%); pointer-events: none; z-index: 4;
  box-shadow: 0 0 0 2px rgba(245, 220, 120, .85), 0 0 18px 6px rgba(245, 200, 80, .45);
  background: rgba(245, 210, 90, .18); animation: domEndPulse 1.1s ease-in-out infinite;
  border: 0; padding: 0; appearance: none; -webkit-appearance: none;
}
.dom-end-glow.pickable {
  pointer-events: auto; cursor: pointer;
  /* bigger tap target without changing the visible glow size */
  min-width: 56px; min-height: 56px;
}
.dom-end-glow.pickable:active { background: rgba(245, 210, 90, .35); }
.dom-badges .badge.pickable:disabled { opacity: .55; cursor: default; }
.dom-badges button.badge {
  font: inherit; color: inherit; cursor: pointer;
}
.dom-end-actions { width: 100%; justify-content: center; flex-wrap: wrap; }
@keyframes domEndPulse {
  0%, 100% { opacity: .75; transform: translate(-50%, -50%) scale(1); }
  50% { opacity: 1; transform: translate(-50%, -50%) scale(1.08); }
}
.badge.dom-end-lit { box-shadow: 0 0 12px rgba(245, 200, 80, .55); }
.dom-team {
  flex: 0 0 auto; font-size: 10px; font-weight: 900; letter-spacing: .4px;
  border-radius: 4px; padding: 1px 5px; line-height: 1.3; border: 1px solid;
}
.dom-team.team-0 { color: #8fd0ff; border-color: rgba(143,208,255,.7); background: rgba(80,150,220,.2); }
.dom-team.team-1 { color: #ffc08a; border-color: rgba(255,192,138,.7); background: rgba(200,120,60,.2); }
.dom-tile-btn.selected { outline: 2px solid var(--gold); outline-offset: 2px; }
.dom-board-empty {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  opacity: .7; font-size: 13px; padding: 20px; text-align: center;
}

/* nowrap + horizontal scroll, same pattern as .hand (card games) — wrapping
   let a big domino hand grow the page vertically instead of scrolling
   sideways like every other game's hand tray already does. */
.dom-hand {
  display: flex; flex-wrap: nowrap; gap: 8px; padding: 10px 6px 4px;
  overflow-x: auto; scrollbar-width: none; justify-content: safe center;
}
.dom-hand::-webkit-scrollbar { display: none; }
.dom-hand::after { content: ""; margin: auto; }

/* shared draw-phase pool — everyone taps the same face-down pile */
.dom-drawphase { display: flex; flex-direction: column; align-items: center; gap: 14px; width: 100%; }
.dom-pool { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; padding: 8px 6px; max-width: 100%; }
.dom-draw-progress { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }

.dom-pool-shuffling .dom-tile-btn { animation: domShuffle .5s ease-in-out infinite; pointer-events: none; }
.dom-pool-shuffling .dom-tile-btn:nth-child(2n) { animation-delay: .08s; }
.dom-pool-shuffling .dom-tile-btn:nth-child(3n) { animation-delay: .15s; }
.dom-pool-shuffling .dom-tile-btn:nth-child(5n) { animation-delay: .05s; }
.dom-pool-shuffling .dom-tile-btn:nth-child(7n) { animation-delay: .2s; }
@keyframes domShuffle {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  25% { transform: translate(2px, -3px) rotate(-5deg); }
  50% { transform: translate(-3px, 2px) rotate(4deg); }
  75% { transform: translate(1px, 3px) rotate(-3deg); }
}

@media (max-width: 520px) {
  .dom-tile-h { width: 54px; height: 27px; }
  .dom-tile-v { width: 27px; height: 54px; }
  .dom-tile-back { width: 28px; height: 56px; }
}
