/* ═══════════════════════════════════════════════════════════════════════
   MoneyMove — midnight felt
   The iOS app's identity, ported: a deep green card-table with brass
   accents at night, warm ivory linen by day.
   ═══════════════════════════════════════════════════════════════════════ */
:root {
  /* Daylight table: warm ivory linen, white cards, forest-and-brass accents. */
  --page:       #efe9dc;
  --page-2:     #e2dac9;
  --card:       #ffffff;
  --paper-2:    #efe9de;   /* sunken areas inside a card */
  --ink:        #201f1a;
  --ink-2:      #5c5b50;
  --ink-3:      #92917f;
  --rule:       #e4dece;
  --rule-2:     #d2cab6;

  /* --red is the brand accent slot; on the felt table it wears brass. */
  --red:        #b58223;
  --red-deep:   #93690f;
  --red-soft:   #f7edd8;
  --red-ink:    #7a5a10;

  --good:       #177c4d;
  --good-soft:  #e4f3ea;
  --bad:        #bf3a4e;
  --gold:       #a97b1d;
  --gold-soft:  #f7edd8;

  /* Ink for words printed straight onto the page instead of onto a card — the
     landing hero and the in-game wordmark. Same as --ink on every table except
     the crimson daytime one, whose page is a deep red. */
  --page-ink:    var(--ink);
  --page-ink-2:  var(--ink-2);
  --page-ink-3:  var(--ink-3);
  --page-accent: var(--red);

  /* board */
  --board-bg:      #fdfbf4;
  --tile-face:     #ffffff;
  --tile-corner:   #fffef9;
  --tile-treasure: var(--gold-soft);
  --tile-surprise: #f3e4f1;
  --tile-tax:      #f6e3e5;
  --tile-refund:   var(--good-soft);
  --tile-start:    #e2f2e8;
  --tile-goto:     #f6e3e7;
  --tile-vacation: #e0f0ee;
  --tile-jail:     #e8ebf4;
  --ink-start:     #147445;
  --ink-treasure:  #8a5f10;
  --ink-surprise:  #9c4a86;
  --art-lift:      none;

  --shadow:    0 16px 40px rgba(30, 28, 14, .20);
  --shadow-sm: 0 3px 10px rgba(30, 28, 14, .11);
  --shadow-in: inset 0 1px 0 rgba(255, 255, 255, .8);
  --overlay:   rgba(26, 24, 12, .5);

  --r-sm: 8px;
  --r:    13px;
  --r-lg: 20px;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --pop:  cubic-bezier(.34, 1.56, .64, 1);
}

/* Midnight felt: a deep green card-table, warm ivory ink, brass accents. */
:root[data-theme="dark"] {
  --page:       #0c1310;
  --page-2:     #070b09;
  --card:       #16211c;
  --paper-2:    #1d2b25;
  --ink:        #efede2;
  --ink-2:      #adb6ac;
  --ink-3:      #78827a;
  --rule:       #24332c;
  --rule-2:     #31453c;

  --red:        #e3a93c;
  --red-deep:   #c08a25;
  --red-soft:   #2e2718;
  --red-ink:    #f2cd8b;

  --good:       #4fd98b;
  --good-soft:  #14291e;
  --bad:        #e25a6d;
  --gold:       #d9a13a;
  --gold-soft:  #2c2413;

  --board-bg:      #121d18;
  --tile-face:     #1b2721;
  --tile-corner:   #223129;
  --tile-treasure: #2c2413;
  --tile-surprise: #2a1d2c;
  --tile-tax:      #2e1b1f;
  --tile-refund:   #14291e;
  --tile-start:    #153125;
  --tile-goto:     #331b21;
  --tile-vacation: #122c2a;
  --tile-jail:     #1c2433;
  --ink-start:     #6ee7a0;
  --ink-treasure:  #e9be6b;
  --ink-surprise:  #e39ad1;
  --art-lift:      brightness(1.35) saturate(1.05);

  --shadow:    0 16px 40px rgba(0, 0, 0, .6);
  --shadow-sm: 0 3px 10px rgba(0, 0, 0, .45);
  --shadow-in: inset 0 1px 0 rgba(255, 255, 255, .06);
  --overlay:   rgba(3, 8, 5, .68);
}


/* ── table styles: six more palettes, each with its own light and dark ──
   felt (default, above) · crimson · royale · blush · marine · sands · noir */

:root[data-palette="crimson"] {
  --page: #b31527; --page-2: #8e0f1e; --card: #ffffff; --paper-2: #f4eeea;
  --ink: #1e1a1c; --ink-2: #5f5359; --ink-3: #948890; --rule: #e9e0db; --rule-2: #d8cac3;
  --red: #d92037; --red-deep: #a4142a; --red-soft: #fdecee; --red-ink: #7d0f20;
  --gold: #b7791f; --gold-soft: #fdf3e0;
  --board-bg: #fffaf7; --tile-face: #ffffff; --tile-corner: #fffdfb;
  /* The only light table with a dark page: dark ink would vanish into it. */
  --page-ink: #fff6f7; --page-ink-2: rgba(255, 246, 247, .84);
  --page-ink-3: rgba(255, 246, 247, .62); --page-accent: #ffd0d6;
}
:root[data-palette="crimson"][data-theme="dark"] {
  --page: #150a0e; --page-2: #0d0508; --card: #211319; --paper-2: #2b1a21;
  --ink: #f4eaed; --ink-2: #bda8b0; --ink-3: #8d757e; --rule: #382330; --rule-2: #4a2f3c;
  --red: #f04156; --red-deep: #c4243a; --red-soft: #3a1620; --red-ink: #ffb8c2;
  --gold: #fbbf24; --gold-soft: #35240d;
  --board-bg: #1a0e13; --tile-face: #2a1a22; --tile-corner: #33202a;
}

:root[data-palette="royale"] {
  --page: #eae6f4; --page-2: #dcd5ec; --card: #ffffff; --paper-2: #efecf7;
  --ink: #1d1a26; --ink-2: #575168; --ink-3: #8f89a3; --rule: #e2ddef; --rule-2: #cec6e3;
  --red: #6d3fd6; --red-deep: #5530ab; --red-soft: #efe8fd; --red-ink: #4a278f;
  --gold: #a97b1d; --gold-soft: #f4edd8;
  --board-bg: #fcfbff; --tile-face: #ffffff; --tile-corner: #fdfcff;
}
:root[data-palette="royale"][data-theme="dark"] {
  --page: #14101f; --page-2: #0b0814; --card: #201a33; --paper-2: #2a2342;
  --ink: #efecf7; --ink-2: #b3accc; --ink-3: #7d7699; --rule: #322a4d; --rule-2: #453a66;
  --red: #8b5cf6; --red-deep: #6d3fd6; --red-soft: #251b3e; --red-ink: #cdb8ff;
  --gold: #d9a13a; --gold-soft: #2c2413;
  --board-bg: #191430; --tile-face: #251e3b; --tile-corner: #2e2647;
}

:root[data-palette="blush"] {
  --page: #f7e8ee; --page-2: #efd8e2; --card: #ffffff; --paper-2: #f7edf2;
  --ink: #241a20; --ink-2: #67535d; --ink-3: #a08892; --rule: #f0dde6; --rule-2: #e2c7d4;
  --red: #d6479a; --red-deep: #b02c7a; --red-soft: #fbe7f2; --red-ink: #8f1f61;
  --gold: #b7791f; --gold-soft: #fdf3e0;
  --board-bg: #fffbfd; --tile-face: #ffffff; --tile-corner: #fffdfe;
}
:root[data-palette="blush"][data-theme="dark"] {
  --page: #1d1016; --page-2: #120a0e; --card: #2b1a23; --paper-2: #37222d;
  --ink: #f7ecf1; --ink-2: #cfacbd; --ink-3: #97768a; --rule: #43293a; --rule-2: #58374b;
  --red: #f472b6; --red-deep: #d6479a; --red-soft: #3a1e2f; --red-ink: #ffc0e0;
  --gold: #e3a93c; --gold-soft: #2e2718;
  --board-bg: #241419; --tile-face: #301d27; --tile-corner: #3a2430;
}

:root[data-palette="marine"] {
  --page: #e2ebf2; --page-2: #d2dfe9; --card: #ffffff; --paper-2: #ebf1f6;
  --ink: #16202a; --ink-2: #4e5f6e; --ink-3: #84939f; --rule: #dde7ee; --rule-2: #c6d6e2;
  --red: #1d94cf; --red-deep: #14719f; --red-soft: #e2f3fc; --red-ink: #0d567b;
  --gold: #a97b1d; --gold-soft: #f4edd8;
  --board-bg: #fbfdff; --tile-face: #ffffff; --tile-corner: #fcfeff;
}
:root[data-palette="marine"][data-theme="dark"] {
  --page: #0b1220; --page-2: #070b15; --card: #14202f; --paper-2: #1c2b3f;
  --ink: #e9eef6; --ink-2: #a9b8cc; --ink-3: #74839a; --rule: #24354b; --rule-2: #314763;
  --red: #38bdf8; --red-deep: #1d94cf; --red-soft: #14293a; --red-ink: #a5e0ff;
  --gold: #d9a13a; --gold-soft: #2c2413;
  --board-bg: #101b2b; --tile-face: #182535; --tile-corner: #1f2e40;
}

:root[data-palette="sands"] {
  --page: #f2e9d8; --page-2: #e7dac2; --card: #fffdf8; --paper-2: #f4edde;
  --ink: #241e12; --ink-2: #665c46; --ink-3: #998c70; --rule: #eadfc9; --rule-2: #d9c9a9;
  --red: #b97509; --red-deep: #935c05; --red-soft: #faeed6; --red-ink: #7a4c06;
  --gold: #b97509; --gold-soft: #faeed6;
  --board-bg: #fffcf3; --tile-face: #fffdf8; --tile-corner: #fffef9;
}
:root[data-palette="sands"][data-theme="dark"] {
  --page: #191307; --page-2: #100c04; --card: #272013; --paper-2: #33291a;
  --ink: #f5efe2; --ink-2: #c8bba0; --ink-3: #93876e; --rule: #3d321f; --rule-2: #52432a;
  --red: #f59e0b; --red-deep: #cc7f06; --red-soft: #332508; --red-ink: #ffd591;
  --gold: #f59e0b; --gold-soft: #332508;
  --board-bg: #201a0e; --tile-face: #2c2415; --tile-corner: #362c1c;
}

:root[data-palette="noir"] {
  --page: #e8e8e6; --page-2: #d9d9d6; --card: #ffffff; --paper-2: #f0f0ee;
  --ink: #1b1b1a; --ink-2: #56565a; --ink-3: #8e8e91; --rule: #e2e2df; --rule-2: #ccccc8;
  --red: #8a6a2f; --red-deep: #6d5325; --red-soft: #f2ead9; --red-ink: #5d4419;
  --gold: #8a6a2f; --gold-soft: #f2ead9;
  --board-bg: #fcfcfb; --tile-face: #ffffff; --tile-corner: #fdfdfc;
}
:root[data-palette="noir"][data-theme="dark"] {
  --page: #101113; --page-2: #0a0b0c; --card: #1b1d20; --paper-2: #25282c;
  --ink: #f0f1f2; --ink-2: #b3b8bd; --ink-3: #7d8288; --rule: #2e3237; --rule-2: #414750;
  --red: #c9a86a; --red-deep: #a8874a; --red-soft: #2a2519; --red-ink: #ecd7ae;
  --gold: #c9a86a; --gold-soft: #2a2519;
  --board-bg: #17181b; --tile-face: #202226; --tile-corner: #292c30;
}

.map-section { margin: 18px 0 2px; font-size: 16px; font-weight: 850; }
.auth-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }

.continue-btn {
  margin-bottom: 12px; font-weight: 800;
  border-color: var(--gold); color: var(--red-deep);
  background: var(--gold-soft);
}

/* ── store ── */
.store-btn { margin-top: 12px; display: flex; align-items: center; justify-content: center; gap: 8px; }
.coin-chip {
  font-size: 12.5px; font-weight: 850; color: var(--gold);
  background: var(--gold-soft); border: 1px solid var(--gold);
  border-radius: 99px; padding: 2px 9px;
}
.store-head { display: flex; align-items: center; gap: 10px; }
.store-head h2 { flex: 1; min-width: 0; }
.store-head .coin-chip { font-size: 15px; padding: 4px 13px; }
.sheet-x { flex: none; font-size: 15px; line-height: 1; }
.store-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 10px; }
.store-card {
  font: inherit; cursor: pointer; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 14px 8px 11px; border-radius: var(--r);
  background: var(--paper-2); border: 1.5px solid var(--rule-2);
  transition: transform .15s var(--pop), border-color .15s;
}
.store-card:hover { transform: translateY(-2px); border-color: var(--gold); }
.store-card.owned { border-color: var(--rule-2); }
.store-card.equipped { border-color: var(--gold); background: var(--gold-soft); }
/* Priced out of reach: still tappable (the toast says why), but it shouldn't
   look identical to something you can actually walk out with. */
.store-card.locked { opacity: .5; border-style: dashed; }
.store-card.locked:hover { transform: none; border-color: var(--rule-2); }
.sc-emoji { font-size: 34px; line-height: 1.1; }
.sc-name { font-size: 12.5px; font-weight: 800; color: var(--ink); }
.sc-price { font-size: 11px; font-weight: 750; color: var(--gold); }
.store-card.owned .sc-price { color: var(--ink-3); }

/* ── friend DMs ── */
.dm-list {
  max-height: 300px; min-height: 140px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 6px; padding: 6px 2px;
}
.dm-msg {
  align-self: flex-start; max-width: 78%;
  background: var(--paper-2); color: var(--ink);
  font-size: 13.5px; line-height: 1.35; font-weight: 550;
  padding: 8px 12px; border-radius: 14px 14px 14px 4px;
  animation: logIn .25s var(--ease);
  overflow-wrap: anywhere;
}
.dm-msg.mine {
  align-self: flex-end;
  background: var(--red); color: #fff;
  border-radius: 14px 14px 4px 14px;
}
.token-face.skin { font-size: clamp(11px, 1.3vw, 19px); }
.avatar.has-skin { font-size: 17px; }

/* the picker itself */
.palette-bar {
  position: fixed; z-index: 90; display: flex; gap: 8px;
  padding: 10px 12px; background: var(--card); border: 1px solid var(--rule-2);
  border-radius: 99px; box-shadow: var(--shadow);
  animation: popIn .25s var(--pop);
}
.pswatch {
  width: 26px; height: 26px; border-radius: 50%; cursor: pointer;
  background: var(--dot); border: 2px solid transparent;
  transition: transform .15s var(--pop), border-color .15s;
}
.pswatch:hover { transform: scale(1.18); }
.pswatch.on { border-color: var(--ink); transform: scale(1.12); }

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  background: var(--page);
  transition: background-color .28s var(--ease), color .28s var(--ease);
  color: var(--ink);
  font-family: 'Outfit', 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-feature-settings: 'tnum' 1;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

body::before {
  content: '';
  position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(1100px 780px at 50% 42%, rgba(255, 255, 255, .13), transparent 68%),
    radial-gradient(900px 700px at 8% -10%, rgba(255, 255, 255, .10), transparent 60%),
    radial-gradient(1000px 800px at 100% 108%, rgba(0, 0, 0, .30), transparent 62%),
    linear-gradient(155deg, var(--page), var(--page-2));
}

.hidden { display: none !important; }
.dim { color: var(--ink-3); }
.small { font-size: 12.5px; }
.mt { margin-top: 8px; }
.empty { color: var(--ink-3); font-size: 13px; text-align: center; padding: 14px 6px; }
.empty.small { padding: 8px; font-size: 12px; }
.row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; width: 100%; }
.stack { display: flex; flex-direction: column; gap: 8px; }

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

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--rule-2); border-radius: 99px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--ink-3); }

/* ─────────────────────────────────────────────────────── drawn glyphs ── */
/* js/icons.js returns inline SVG on a 32×32 grid. Most glyphs paint with
   currentColor, so a button, chip or badge lends them its own ink and every
   palette follows for free; the ones with an inherent colour (coin, medals,
   flame) ignore it on purpose. Sizing to 1.15em keeps a glyph the optical
   weight of the capital beside it, and the baseline nudge stops it making the
   line taller — pass a size to icon() to override both. */
.ico { display: inline-block; flex: none; width: 1.15em; height: 1.15em; vertical-align: -.19em; }
.ico.solo { vertical-align: middle; }   /* the only thing inside a button or badge */
/* Chips and tags set their own type size and print the glyph hard against the
   number beside it — the emoji carried that gap inside its own box. */
.chip .ico, .tag .ico { margin-right: 2px; }

/* ───────────────────────────────────────────────────────────── buttons ── */
.btn {
  position: relative;
  background: var(--card);
  border: 1px solid var(--rule-2);
  border-radius: var(--r-sm);
  padding: 10px 15px;
  cursor: pointer;
  font-weight: 650;
  color: var(--ink);
  box-shadow: var(--shadow-sm);
  transition: transform .12s var(--pop), box-shadow .16s, background .16s, border-color .16s;
  white-space: nowrap;
}
.btn:hover:not(:disabled) { border-color: var(--red); color: var(--red-deep); transform: translateY(-1px); }
.btn:active:not(:disabled) { transform: translateY(1px) scale(.99); }
.btn:disabled { opacity: .42; cursor: not-allowed; box-shadow: none; }

.btn.primary {
  /* the highlight follows whatever accent the table style wears */
  background: linear-gradient(180deg, color-mix(in srgb, var(--red) 72%, white), var(--red));
  border-color: var(--red-deep);
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .25);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--red) 35%, transparent), var(--shadow-in);
}
.btn.primary:hover:not(:disabled) { color: #fff; border-color: var(--red-deep); filter: brightness(1.06); }
.btn.good { background: linear-gradient(180deg, #1c9a59, var(--good)); border-color: #0f6339; color: #fff; box-shadow: 0 6px 16px rgba(21, 127, 74, .28); }
.btn.good:hover:not(:disabled) { color: #fff; border-color: #0f6339; }
.btn.bad  { background: linear-gradient(180deg, #d8394d, var(--bad)); border-color: #8f1b2b; color: #fff; }
.btn.bad:hover:not(:disabled) { color: #fff; border-color: #8f1b2b; }
.btn.gold { background: linear-gradient(180deg, #d9932c, var(--gold)); border-color: #8a5a13; color: #fff; }
.btn.gold:hover:not(:disabled) { color: #fff; border-color: #8a5a13; }
.btn.ghost { background: transparent; box-shadow: none; }

.btn.small { padding: 7px 11px; font-size: 12.5px; }
.btn.tiny  { padding: 3px 8px; font-size: 12px; border-radius: 6px; line-height: 1.35; box-shadow: none; }
.btn.big   { padding: 15px 22px; font-size: 16.5px; width: 100%; border-radius: var(--r); font-weight: 750; }
.btn.wide  { width: 100%; }
.btn-ico { margin-right: 6px; }

.icon-btn {
  background: transparent; border: none; cursor: pointer;
  font-size: 17px; color: var(--ink-2); padding: 5px 7px; border-radius: 8px;
  transition: color .15s, background .15s;
}
.icon-btn:hover { color: var(--red); background: var(--red-soft); }

input, select {
  width: 100%;
  background: var(--card);
  border: 1px solid var(--rule-2);
  border-radius: var(--r-sm);
  padding: 11px 13px;
  color: var(--ink);
  outline: none;
  transition: border-color .16s, box-shadow .16s;
}
input:focus, select:focus { border-color: var(--red); box-shadow: 0 0 0 3px rgba(191, 141, 40, .18); }
input::placeholder { color: var(--ink-3); }
select { cursor: pointer; }

/* ───────────────────────────────────────────────────────────── landing ── */
/* minmax(0, 1fr) pins the column to the screen. Left as an auto track it grew
   to the widest line the card could produce — the tagline on one line — and
   dragged the whole landing sideways on a phone. */
.landing {
  position: fixed; inset: 0; z-index: 40; padding: 22px; overflow: auto;
  display: grid; grid-template-columns: minmax(0, 1fr); place-items: center;
}
/* The mood blobs are decoration: clipped to the screen, or they widen the
   landing and drag the whole card sideways on a phone. */
.landing-bg { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.landing-bg span {
  position: absolute; border-radius: 50%; filter: blur(80px); opacity: .35;
  animation: float 15s ease-in-out infinite;
}
.landing-bg span:nth-child(1) { width: 340px; height: 340px; background: #3f8a63; top: 8%; left: 10%; }
.landing-bg span:nth-child(2) { width: 280px; height: 280px; background: #d9a13a; bottom: 12%; right: 12%; animation-delay: -5s; }
.landing-bg span:nth-child(3) { width: 240px; height: 240px; background: #f7b7c0; top: 52%; left: 58%; animation-delay: -9s; }
@keyframes float {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(26px, -32px) scale(1.12); }
}

/* 100% of the padded grid area, not 94vw: viewport units ignore the scrollbar,
   so the card used to hang past the right edge once the page grew tall enough
   to scroll. The top gap keeps the wordmark clear of the two float buttons. */
.landing-inner { width: min(430px, 100%); padding-top: 38px; text-align: center; position: relative; }
.logo { font-size: 25px; font-weight: 900; letter-spacing: -.8px; color: var(--page-ink); }
.logo span { color: var(--page-accent); }
.logo.xl { font-size: clamp(42px, 9vw, 64px); line-height: 1.02; }
.tagline { color: var(--page-ink-2); margin: 12px 0 28px; font-size: 15.5px; }

.landing-card {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  padding: 24px;
  box-shadow: var(--shadow);
}
.field { display: block; text-align: left; margin-bottom: 15px; }
.field span { display: block; font-size: 12.5px; color: var(--ink-2); margin-bottom: 7px; font-weight: 600; }
.field.tight { margin-bottom: 9px; }
.field.tight input { padding: 8px 10px; font-size: 13px; }

.or { position: relative; margin: 20px 0; color: var(--ink-3); font-size: 12px; }
.or::before, .or::after { content: ''; position: absolute; top: 50%; width: 30%; height: 1px; background: var(--rule); }
.or::before { left: 0; } .or::after { right: 0; }
.join-row { display: flex; gap: 8px; }
.join-row input { text-transform: lowercase; letter-spacing: 2px; text-align: center; font-weight: 700; }
/* Friend codes are handed out in capitals, so they must be typed back in
   capitals — the shared lowercase rule made the field disagree with the chip. */
.join-row input.code-input { text-transform: uppercase; }

.public-rooms { margin-top: 18px; display: grid; gap: 6px; }
.pr-title { font-size: 11.5px; color: var(--ink-3); text-align: left; text-transform: uppercase; letter-spacing: .8px; font-weight: 700; }
.public-room {
  display: flex; justify-content: space-between; align-items: center; gap: 10px; width: 100%;
  background: var(--paper-2); border: 1px solid var(--rule);
  border-radius: var(--r-sm); padding: 9px 13px; font-size: 13px; cursor: pointer;
  color: var(--ink); transition: border-color .15s, background .15s;
}
.public-room:hover { border-color: var(--red); background: var(--red-soft); }
.pr-name {
  display: flex; align-items: center; gap: 6px; font-weight: 650;
  /* "The Great White North" on a narrow phone must not shove the room code and
     its tag off the row. */
  min-width: 0; overflow: hidden; white-space: nowrap;
}
.pr-meta { display: flex; align-items: center; gap: 8px; flex: none; }
.pr-tag {
  font-style: normal; font-size: 9.5px; font-weight: 800; letter-spacing: .7px;
  text-transform: uppercase; border-radius: 99px; padding: 2px 7px;
  border: 1px solid currentColor;
}
.pr-tag.open { color: var(--good); }
.pr-tag.busy { color: var(--ink-3); }
/* A game already under way is still worth seeing — it is the difference between
   "nobody plays this" and "there is a table on right now" — so it is listed and
   labelled rather than hidden. It reads as a room to watch, not a seat to take. */
.public-room.busy { background: transparent; border-style: dashed; color: var(--ink-2); }
.public-room.busy:hover { border-color: var(--rule-2); background: var(--paper-2); }

/* ---- unfinished games ---- */
.resume-list { display: grid; gap: 6px; margin: -6px 0 14px; text-align: left; }
.resume-row { display: flex; gap: 6px; align-items: stretch; }
.resume-go {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; text-align: left;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-sm);
  padding: 8px 12px; cursor: pointer; color: var(--ink);
  transition: border-color .15s, background .15s;
}
.resume-go:hover { border-color: var(--gold); background: var(--gold-soft); }
.rr-main { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rr-sub { font-size: 11px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rr-x {
  flex: none; width: 30px; background: none; border: 1px solid var(--rule);
  border-radius: var(--r-sm); color: var(--ink-3); font-size: 15px; cursor: pointer;
}
.rr-x:hover { color: var(--bad); border-color: var(--bad); }

/* ---- recent games: endings kept for their report cards ---- */
.recent-games { margin-top: 18px; display: grid; gap: 6px; text-align: left; }
.recent-games:empty { display: none; }
.recent-game {
  display: flex; flex-direction: column; gap: 2px; text-align: left; width: 100%;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-sm);
  padding: 8px 12px; cursor: pointer; color: var(--ink);
  transition: border-color .15s, background .15s;
}
.recent-game:hover { border-color: var(--gold); background: var(--gold-soft); }
.rg-main { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; min-width: 0; }
.rg-tag {
  margin-left: auto; flex: none; font-style: normal; font-size: 9.5px; font-weight: 800;
  letter-spacing: .7px; text-transform: uppercase; border-radius: 99px; padding: 2px 7px;
  border: 1px solid currentColor; color: var(--ink-3);
}
.rg-tag.won { color: var(--gold); }
.rg-sub { font-size: 11px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.landing-feats { display: flex; justify-content: center; gap: 30px; margin-top: 24px; }
.landing-feats div { display: flex; flex-direction: column; }
.landing-feats b { font-size: 22px; font-weight: 800; color: var(--page-accent); }
.landing-feats span { font-size: 11.5px; color: var(--page-ink-3); text-transform: uppercase; letter-spacing: .8px; font-weight: 600; }
.fineprint { margin-top: 22px; font-size: 11px; color: var(--page-ink-3); line-height: 1.6; }
/* Support and the privacy policy existed but nothing on the web ever linked
   to them; they belong with the small print, not louder than it. */
.fineprint a { color: var(--page-ink-3); text-decoration: underline; }
.fineprint a:hover { color: var(--page-ink-2); }

/* A warning panel painted in fixed pinks was unreadable on every dark table —
   dark maroon body text on a dark card. It wears the palette now. */
.server-down {
  display: flex; flex-direction: column; gap: 7px; text-align: left;
  background: var(--paper-2); border: 1px solid var(--bad);
  border-radius: var(--r-sm); padding: 12px 14px;
}
.server-down b { font-size: 13px; color: var(--bad); }
.server-down span { font-size: 11.5px; color: var(--ink-2); line-height: 1.5; }
.server-down code { background: var(--card); padding: 1px 5px; border-radius: 4px; font-size: 11px; word-break: break-all; }
.server-form { display: flex; gap: 6px; margin-top: 4px; }
.server-form input { padding: 8px 10px; font-size: 12px; }
.link-btn { background: none; border: none; color: var(--red-deep); font-size: 11px; text-decoration: underline; cursor: pointer; padding: 0; text-align: left; }

/* ---- friends ---- */
.friends-card { margin-top: 14px; padding: 18px; }
.fc-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.code-chip {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 13px; font-weight: 700; letter-spacing: 2px;
  background: var(--red-soft); border: 1px solid var(--red); color: var(--red-ink);
  padding: 5px 11px; border-radius: 8px; cursor: pointer;
  transition: background .15s, transform .12s var(--pop);
}
/* Hover used to wash the chip near-white, which hid its own light-on-dark text. */
.code-chip:hover { background: color-mix(in srgb, var(--red) 20%, var(--card)); transform: translateY(-1px); }

.friend-list { display: flex; flex-direction: column; gap: 5px; margin-top: 10px; max-height: 230px; overflow-y: auto; }
.friend {
  display: flex; align-items: center; gap: 9px;
  background: var(--paper-2); border: 1px solid var(--rule);
  border-radius: var(--r-sm); padding: 8px 10px; font-size: 13px;
}
.friend-flag { font-size: 16px; line-height: 1; }
.friend-name { flex: 1; font-weight: 650; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.friend-status { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-3); }
.friend-status.lobby { color: var(--gold); }
.friend-status.playing { color: var(--good); }
.icon-btn.tiny-x { font-size: 12px; padding: 2px 5px; }

/* ─────────────────────────────────────────────────────────── app shell ── */
.app {
  height: 100vh; display: grid;
  grid-template-columns: clamp(186px, 15.5vw, 244px) minmax(0, 1fr) clamp(242px, 18vw, 290px);
  gap: 10px; padding: 10px;
  transition: grid-template-columns .28s var(--ease);
}
.col { min-height: 0; display: flex; flex-direction: column; gap: 10px; }
.col.left, .col.right { overflow: hidden; }
.col.center { align-items: center; justify-content: center; }

.panel {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 13px;
  box-shadow: var(--shadow-sm);
}
.panel-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: 1px;
  color: var(--ink-3); margin-bottom: 9px; font-weight: 750;
}

/* On a phone the row is wider than the screen, and the last icon out — the way
   off the table — was the one that fell off it. Let it wrap instead. */
.brand { display: flex; align-items: center; justify-content: space-between; gap: 4px 8px; flex-wrap: wrap; padding: 2px 5px; }
.brand-actions { display: flex; gap: 2px; flex-wrap: wrap; justify-content: flex-end; }
/* Seven equal squares fit the side column; left to size themselves the emoji
   ones ran wide and pushed Leave, Sound and Help off the panel entirely. */
.brand-actions .icon-btn {
  flex: none; width: 28px; height: 28px; padding: 0;
  display: grid; place-items: center; font-size: 15px; line-height: 1;
}

.share-row { display: flex; gap: 7px; }
.share-row input { font-size: 12px; padding: 8px 11px; }

/* An empty log used to be a tall blank box; it now grows with its content
   and only starts scrolling once it has earned the height. */
.log-panel { flex: 0 1 auto; display: flex; flex-direction: column; max-height: 46%; }
.log-list { overflow-y: auto; font-size: 12.5px; display: flex; flex-direction: column; gap: 2px; padding-right: 3px; }
.log-line {
  display: flex; gap: 7px; align-items: baseline; line-height: 1.4;
  color: var(--ink-2); padding: 3px 6px; border-radius: 6px;
  animation: logIn .3s var(--ease);
}
@keyframes logIn { from { opacity: 0; transform: translateX(-6px); } }
.log-ico { flex: none; font-size: 11px; width: 14px; text-align: center; }
.log-line.dice     { color: #4b3d8f; }
.log-line.money    { color: var(--good); }
.log-line.rent     { color: var(--bad); }
.log-line.buy      { color: #1668a8; }
.log-line.turn     { color: var(--ink); font-weight: 750; background: var(--gold-soft); }
.log-line.jail, .log-line.warn { color: #a63f12; }
.log-line.bankrupt { color: var(--red-ink); font-weight: 750; background: var(--red-soft); }
.log-line.auction, .log-line.trade { color: var(--gold); }
.log-line.system   { color: var(--red-deep); font-weight: 750; background: var(--red-soft); }
.log-line.treasure { color: #9a6112; }
.log-line.surprise { color: #a3246c; }
.log-line.build    { color: #3a5bb5; }

/* Those six hues are mixed for pale paper. On the dark tables they sat at
   1.9–3.2 against the panel, which made "rolled 3 + 2 = 5" and "bought Rome
   for $160" — the two lines people actually read — almost invisible. Same
   colours, lifted until they carry on a dark card, in every palette. */
:root[data-theme="dark"] .log-line.dice     { color: #a99bf0; }
:root[data-theme="dark"] .log-line.buy      { color: #6ab6ee; }
:root[data-theme="dark"] .log-line.jail,
:root[data-theme="dark"] .log-line.warn     { color: #f0894f; }
:root[data-theme="dark"] .log-line.treasure { color: #e0aa4e; }
:root[data-theme="dark"] .log-line.surprise { color: #f07ab5; }
:root[data-theme="dark"] .log-line.build    { color: #8aa8f0; }

.chat-panel { flex: 0 1 auto; display: flex; flex-direction: column; max-height: 40%; }
.chat-list { flex: 0 1 auto; overflow-y: auto; font-size: 13px; display: flex; flex-direction: column; gap: 5px; min-height: 34px; }
.chat-msg { line-height: 1.4; animation: logIn .3s var(--ease); color: var(--ink-2); }
.chat-msg b { font-weight: 750; margin-right: 4px; }
.chat-flag { margin-right: 3px; }
.chat-team-badge {
  font-size: 8px; font-weight: 900; letter-spacing: .6px;
  border: 1px solid currentColor; border-radius: 99px;
  padding: 0 5px; margin-right: 3px; opacity: .9; vertical-align: 1px;
}
.chat-channels { display: flex; gap: 6px; margin-bottom: 8px; }
.chat-channels button {
  font: inherit; font-size: 11px; font-weight: 750; letter-spacing: .2px;
  color: var(--ink-3); background: var(--paper-2);
  border: 1px solid transparent; border-radius: 99px;
  padding: 4px 11px; cursor: pointer; transition: all .15s var(--ease);
}
.chat-channels button.on { color: var(--gold); background: var(--gold-soft); border-color: var(--gold); }
.chat-channels button:hover:not(.on) { color: var(--ink-2); }
.chat-form { display: flex; gap: 7px; margin-top: 9px; }
.chat-form input { padding: 9px 11px; font-size: 13px; }
.icon-btn.send { background: var(--red); color: #fff; border-radius: var(--r-sm); padding: 6px 13px; }
.icon-btn.send:hover { background: var(--red-deep); color: #fff; }

.emote-row { display: flex; gap: 3px; flex-wrap: wrap; margin-top: 8px; }
.emote {
  background: var(--paper-2); border: 1px solid var(--rule);
  border-radius: 7px; font-size: 14px; line-height: 1; padding: 4px 6px;
  cursor: pointer; transition: transform .12s var(--pop), background .12s;
}
.emote:hover { background: var(--red-soft); transform: translateY(-2px) scale(1.1); }

/* ─────────────────────────────────────────────────────────────── board ── */
.board-wrap { position: relative; width: min(100%, calc(100vh - 22px)); aspect-ratio: 1 / 1; }
.board {
  position: absolute; inset: 0;
  display: grid; gap: 3px;
  background: var(--board-bg);
  border: 1px solid var(--rule-2);
  border-radius: 18px;
  padding: 5px;
  box-shadow: var(--shadow);
}

/* A tile is a white card with a solid country band on the edge facing the
   middle of the board — the way a printed board actually reads. */
.tile {
  position: relative;
  background: var(--tile-face);
  border: 1px solid var(--rule);
  border-radius: 7px;
  overflow: hidden;
  display: flex;
  min-width: 0; min-height: 0;
  transition: box-shadow .18s, transform .18s var(--pop);
}
.t-top    { flex-direction: column; }
.t-bottom { flex-direction: column-reverse; }
.t-left   { flex-direction: row; }
.t-right  { flex-direction: row-reverse; }

.tile-wash { position: absolute; background: var(--g, transparent); }
.t-top .tile-wash    { left: 0; right: 0; bottom: 0; height: 21%; }
.t-bottom .tile-wash { left: 0; right: 0; top: 0;    height: 21%; }
.t-left .tile-wash   { top: 0; bottom: 0; right: 0;  width: 21%; }
.t-right .tile-wash  { top: 0; bottom: 0; left: 0;   width: 21%; }
.tile-wash::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, .28), transparent 60%);
}

.tile.type-treasure { background: var(--tile-treasure); }
.tile.type-surprise { background: var(--tile-surprise); }
.tile.type-tax      { background: var(--tile-tax); }
.tile.type-refund   { background: var(--tile-refund); }
.tile.corner        { background: var(--tile-corner); }
.tile.type-start      { background: var(--tile-start); }
.tile.type-gotoprison { background: var(--tile-goto); }
.tile.type-vacation   { background: var(--tile-vacation); }
.tile.type-prison     { background: var(--tile-jail); }

.tile.ownable { cursor: pointer; }
.tile.ownable:hover { box-shadow: 0 0 0 2px var(--red) inset, var(--shadow-sm); z-index: 5; }
.tile.active-tile { box-shadow: 0 0 0 2px var(--gold) inset, 0 0 18px rgba(183, 121, 31, .35); z-index: 4; }

.tile-body {
  position: relative; z-index: 2;
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 4%; padding: 5% 3%; min-width: 0; min-height: 0; text-align: center;
}
.t-left, .t-right { container-type: size; }
.t-left .tile-body, .t-right .tile-body {
  position: absolute; top: 50%; left: 50%;
  width: 100cqh; height: 100cqw;
}
.t-right .tile-body { transform: translate(-50%, -50%) rotate(90deg); }
.t-left .tile-body  { transform: translate(-50%, -50%) rotate(-90deg); }
.t-right .medal, .t-right .tile-art { transform: rotate(-90deg); }
.t-left .medal,  .t-left .tile-art  { transform: rotate(90deg); }

.tile-name {
  font-size: clamp(6.5px, .84vw, 13px); font-weight: 750; line-height: 1.08;
  color: var(--ink); letter-spacing: -.3px; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow-wrap: anywhere;
}
.tile-price {
  font-size: clamp(6px, .74vw, 11.5px); font-weight: 750; letter-spacing: -.2px;
  color: var(--ink-2); background: var(--paper-2);
  padding: 1px 5px; border-radius: 5px;
}
.tile-price.solo { background: none; }
.tile-sub { font-size: clamp(5.5px, .55vw, 8.5px); color: var(--ink-3); text-transform: uppercase; letter-spacing: .5px; font-weight: 650; }

.medal {
  flex: none; writing-mode: horizontal-tb;
  width: clamp(14px, 1.95vw, 30px); height: clamp(14px, 1.95vw, 30px);
  border-radius: 50%; overflow: hidden;
  display: grid; place-items: center;
  background: var(--card);
  box-shadow: 0 0 0 1.5px var(--rule-2), 0 2px 5px rgba(0, 0, 0, .25);
}
/* A country flies its own pennant here, tinted with the group's colour — the
   one mark on the board that has to survive Windows, where flag emoji simply
   do not draw. It fills the disc the way the emoji did. */
.medal svg { width: 78%; height: 78%; display: block; }

.tile-art {
  writing-mode: horizontal-tb; flex: none; display: block;
  width: clamp(14px, 1.9vw, 29px); height: clamp(14px, 1.9vw, 29px);
  filter: var(--art-lift) drop-shadow(0 1px 2px rgba(0, 0, 0, .25));
}
.tile-art.big  { width: clamp(19px, 2.6vw, 40px); height: clamp(19px, 2.6vw, 40px); }
.tile-art.huge { width: clamp(28px, 3.8vw, 64px); height: clamp(28px, 3.8vw, 64px); }
.tile-art svg { width: 100%; height: 100%; display: block; }

.accent-treasure { color: var(--ink-treasure); }
.accent-surprise { color: var(--ink-surprise); }
.start-word { color: var(--ink-start); letter-spacing: 1px; }
.corner .tile-body { writing-mode: horizontal-tb; transform: none; gap: 4%; }

.tile.owned::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .2; z-index: 1;
  background: var(--own-color);
}
/* Set-completed celebration: the whole section floods with the owner's
   colour and breathes back, three deep pulses. */
.tile.owned.set-flash::after { animation: setPulse 3.2s ease-in-out; }
@keyframes setPulse {
  0%, 100% { opacity: .2; }
  12%, 44%, 76% { opacity: .85; }
  28%, 60% { opacity: .3; }
}

/* A whole country in one hand: thicker owner band + a quiet ring. */
.t-top.full-set .tile-wash,
.t-bottom.full-set .tile-wash { height: 30%; }
.t-left.full-set .tile-wash,
.t-right.full-set .tile-wash { width: 30%; }
.tile.full-set { box-shadow: 0 0 0 1.5px var(--own-color) inset; }
.tile.full-set.owned::after { opacity: .3; }
.tile.mortgaged .tile-body { opacity: .34; }
/* The mortgage stamp is drawn art now, so it comes from the markup rather than
   a `content:` string the stylesheet would have to spell in emoji. It rides
   above the dimmed body on its own layer, at full strength. */
.tile-stamp { display: none; }
.tile.mortgaged .tile-stamp {
  position: absolute; inset: 0; z-index: 3;
  display: grid; place-items: center; color: var(--ink);
}
.tile-stamp svg { width: clamp(11px, 1.3vw, 19px); height: clamp(11px, 1.3vw, 19px); }

.tile-owner { position: absolute; top: 3px; left: 3px; z-index: 6; }
.t-bottom .tile-owner { top: auto; bottom: 3px; }
.t-right .tile-owner { left: auto; right: 3px; }
.owner-dot {
  display: grid; place-items: center;
  width: clamp(9px, 1vw, 15px); height: clamp(9px, 1vw, 15px);
  border-radius: 50%; font-size: clamp(5.5px, .58vw, 9px); font-weight: 900; color: #fff;
  box-shadow: 0 0 0 1.5px var(--card), 0 1px 3px rgba(0, 0, 0, .35);
}

.tile-houses {
  position: absolute; z-index: 5; display: flex; gap: 1px;
  align-items: center; justify-content: center;
}
.t-top .tile-houses    { bottom: 1px; left: 0; right: 0; height: 21%; }
.t-bottom .tile-houses { top: 1px; left: 0; right: 0; height: 21%; }
.t-left .tile-houses   { right: 1px; top: 0; bottom: 0; width: 21%; flex-direction: column; }
.t-right .tile-houses  { left: 1px; top: 0; bottom: 0; width: 21%; flex-direction: column; }
.tile.has-buildings .medal { display: none; }
.tile-houses .house, .tile-houses .hotel {
  display: block; animation: popIn .35s var(--pop);
  width: clamp(7px, .82vw, 13px); height: clamp(7px, .82vw, 13px);
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .35));
}
.tile-houses .hotel { width: clamp(9px, 1.05vw, 17px); height: clamp(9px, 1.05vw, 17px); }
.tile-houses svg { width: 100%; height: 100%; display: block; }
@keyframes popIn { from { transform: scale(0); } }

/* tokens ride on their own layer so they can animate between tiles */
/* The layer fades rather than cuts: tokens appear only after the deal-in
   has put the tiles down for them to stand on. */
.token-layer { position: absolute; inset: 0; pointer-events: none; z-index: 8; transition: opacity .45s ease; }
.token {
  position: absolute; top: 0; left: 0;
  width: clamp(13px, 1.7vw, 24px); height: clamp(13px, 1.7vw, 24px);
  border-radius: 50%;
  display: grid; place-items: center;
  border: 2px solid var(--card);
  box-shadow: 0 3px 8px rgba(0, 0, 0, .4);
  transition: transform .11s linear;
  will-change: transform;
}
.token-face { font-size: clamp(6.5px, .8vw, 11px); font-weight: 900; color: rgba(255, 255, 255, .95); }
.token.is-turn { box-shadow: 0 0 0 2px var(--ink), 0 0 14px var(--tc), 0 3px 8px rgba(60, 30, 35, .4); z-index: 2; }
.token.is-turn::after {
  content: ''; position: absolute; inset: -5px; border-radius: 50%;
  border: 2px solid var(--tc); opacity: .6; animation: ping 1.5s ease-out infinite;
}
@keyframes ping { 0% { transform: scale(.85); opacity: .6; } 100% { transform: scale(1.5); opacity: 0; } }

/* ─────────────────────────────────────────────────────── board centre ── */
.board-center {
  position: absolute; inset: 13.5%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  pointer-events: none; text-align: center;
}
.board-center > * { pointer-events: auto; }
.center-felt {
  position: absolute; inset: -3%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 50% 45%, rgba(217, 161, 58, .06), transparent 62%);
}
.center-logo {
  position: absolute; top: 2%; font-size: clamp(13px, 1.8vw, 24px); font-weight: 900;
  letter-spacing: 1.5px; color: var(--ink); opacity: .045; pointer-events: none;
}
.center-logo span { color: var(--red); }

/* No panel chrome in the middle — the dice float straight on the board,
   with the actions and status hanging below them. */
.center-panel {
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  padding: 0; background: none; border: none; box-shadow: none;
  max-width: 94%;
}
body.my-turn .board { box-shadow: var(--shadow), 0 0 0 2px rgba(227, 169, 60, .35); }

.dice-row { display: flex; gap: 18px; height: 86px; align-items: center; }
.dice-row:not(:has(.die.show)) { display: none; }
.die {
  width: 78px; height: 78px; border-radius: 18px;
  /* Real dice are ivory in any light — never theme-tinted. */
  background: linear-gradient(155deg, #ffffff, #efe7e2);
  border: 1px solid rgba(0, 0, 0, .14);
  display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
  padding: 12px; box-shadow: 0 10px 26px rgba(0, 0, 0, .3), inset 0 -4px 0 rgba(0, 0, 0, .06);
  opacity: 0; transform: scale(.5); transition: opacity .2s, transform .3s var(--pop);
}
.die.show { opacity: 1; transform: scale(1); }
.die.rolling { animation: tumble .55s var(--ease); }
@keyframes tumble {
  0%   { transform: rotate(0) scale(.7); }
  45%  { transform: rotate(220deg) scale(1.2); }
  100% { transform: rotate(360deg) scale(1); }
}
.pip { width: 13px; height: 13px; border-radius: 50%; background: #1b5e3f; align-self: center; justify-self: center; }

.center-card { display: flex; justify-content: center; }
.center-action { display: flex; flex-direction: column; gap: 9px; align-items: center; width: min(280px, 80%); }
.center-status { font-size: 13.5px; color: var(--ink-2); max-width: 320px; line-height: 1.5; }
.room-code { font-size: 15px; }
.room-code b { letter-spacing: 3px; color: var(--ink); font-size: 19px; }
.turn-block { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.avatar.lg { width: 46px; height: 46px; font-size: 20px; animation: breathe 2.4s ease-in-out infinite; }
@keyframes breathe { 50% { transform: scale(1.07); } }
.turn-line { font-size: 17px; font-weight: 800; }
.win-line { font-size: 24px; font-weight: 900; }
.alert {
  background: var(--red-soft); border: 1px solid #f3c3ca;
  border-radius: var(--r-sm); padding: 9px 13px; color: var(--red-ink); margin-bottom: 7px; font-size: 13.5px;
}

.auction-box { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 100%; }
.auction-label { font-size: 12px; text-transform: uppercase; letter-spacing: 1.4px; color: var(--gold); font-weight: 750; }
.auction-bid { font-size: 38px; font-weight: 900; color: var(--red); line-height: 1.1; }
.auction-timer { height: 5px; width: 100%; background: var(--paper-2); border-radius: 4px; overflow: hidden; margin: 9px 0 4px; }
.auction-timer i { display: block; height: 100%; width: 100%; background: linear-gradient(90deg, var(--red), #f2748a); }
.bid-row { display: flex; gap: 7px; justify-content: center; flex-wrap: wrap; }

.turn-banner-fly {
  position: absolute; top: 17%; left: 0; right: 0; z-index: 20;
  display: flex; justify-content: center; pointer-events: none; opacity: 0;
}
.turn-banner-fly.show { animation: bannerIn 1.6s var(--ease); }
@keyframes bannerIn {
  0%   { opacity: 0; transform: translateY(16px) scale(.9); }
  14%  { opacity: 1; transform: translateY(0) scale(1); }
  78%  { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-14px) scale(.97); }
}
.tb-inner {
  display: flex; align-items: center; gap: 11px;
  background: var(--card); border: 2px solid var(--c);
  border-radius: 99px; padding: 9px 22px 9px 9px;
  box-shadow: var(--shadow);
}
.tb-avatar { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; font-weight: 900; color: #fff; font-size: 15px; }
.tb-text { font-size: 17px; font-weight: 800; color: var(--ink); }

/* ─────────────────────────────────────────────────────────── player list ── */
.player-list { display: flex; flex-direction: column; gap: 8px; }
/* The clock and the Trade button only appear on some cards, and on a narrow
   column they used to squeeze the name, the cash and the set chips into a
   sliver. They wrap onto their own line instead of crushing the seat. */
.player-card {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; row-gap: 6px;
  background: var(--card); border: 1px solid var(--rule);
  border-radius: var(--r); padding: 10px 11px;
  box-shadow: var(--shadow-sm);
  transition: border-color .2s, box-shadow .2s, transform .2s var(--ease);
}
.player-card.turn { border-color: var(--red); box-shadow: 0 0 0 2px rgba(191, 141, 40, .18), var(--shadow-sm); transform: translateX(-3px); }
.player-card.turn .avatar-ring { opacity: 1; animation: ping 1.6s ease-out infinite; }
.player-card.dead { opacity: .5; filter: grayscale(.8); }
.player-card.empty-seat { border-style: dashed; background: transparent; box-shadow: none; }
.avatar.ghost-seat { background: var(--paper-2); color: var(--ink-3); }

.avatar {
  position: relative; width: 34px; height: 34px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 14.5px; font-weight: 900; color: #fff;
  box-shadow: 0 2px 6px rgba(60, 30, 35, .25);
}
.avatar.sm { width: 24px; height: 24px; font-size: 11.5px; }
.avatar-ring { position: absolute; inset: -4px; border-radius: 50%; border: 2px solid var(--red); opacity: 0; }
.avatar-flag { position: absolute; bottom: -3px; right: -5px; font-size: 13px; line-height: 1; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .3)); }
.avatar.sm .avatar-flag { font-size: 10px; bottom: -2px; right: -4px; }

.pinfo { flex: 1 1 108px; min-width: 108px; display: flex; flex-direction: column; gap: 2px; }
.pn-text { overflow: hidden; text-overflow: ellipsis; }
.pname { font-size: 13.5px; font-weight: 750; display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.pmeta { font-size: 11.5px; color: var(--ink-3); }
.tags { display: inline-flex; gap: 3px; flex-wrap: wrap; }
.tag {
  font-size: 8.5px; font-style: normal; font-weight: 800; letter-spacing: .5px;
  padding: 2px 5px; border-radius: 5px; background: var(--paper-2); color: var(--ink-2);
}
.tag.host { background: var(--gold-soft); color: var(--gold); }
.tag.you  { background: var(--red-soft); color: var(--red-deep); }
.tag.off, .tag.jail { background: #fdeaec; color: var(--bad); }
.tag.vac  { background: #e6f6f6; color: #0f6d6d; }
.tag.card { background: var(--gold-soft); color: var(--gold); }
.tag.team { font-weight: 800; }

.pmoney { font-size: 14px; color: var(--good); font-weight: 800; white-space: nowrap; }
.pmoney.bump { animation: bump .45s var(--pop); }
@keyframes bump { 40% { transform: scale(1.16); } }

.chips { display: flex; gap: 3px; flex-wrap: wrap; align-items: center; }
.chip {
  font-style: normal; font-size: 9.5px; font-weight: 800; line-height: 1;
  padding: 3px 5px; border-radius: 5px;
  background: color-mix(in srgb, var(--c) 18%, var(--card));
  border: 1px solid color-mix(in srgb, var(--c) 55%, var(--card));
  color: color-mix(in srgb, var(--c) 72%, var(--ink));
}
.chip small { opacity: .6; font-size: 8.5px; }
.chip.full { background: var(--c); color: var(--card); border-color: var(--c); }
.chip.plain { background: var(--paper-2); border-color: var(--rule); color: var(--ink-2); }
.chips .dim { font-size: 11px; }

.player-actions { display: flex; gap: 3px; align-items: center; }
.player-card.teamed { border-left: 3px solid var(--team-color); }
.player-card.teamed .avatar { box-shadow: 0 0 0 2px var(--team-color), 0 2px 6px rgba(60, 30, 35, .25); }

.delta-slot { position: absolute; right: 12px; top: 4px; pointer-events: none; }
.delta { font-size: 13px; font-weight: 900; animation: deltaFly 1.5s var(--ease) forwards; }
.delta.up { color: var(--good); }
.delta.down { color: var(--bad); }
@keyframes deltaFly {
  0%   { opacity: 0; transform: translateY(6px); }
  18%  { opacity: 1; transform: translateY(0); }
  70%  { opacity: 1; transform: translateY(-14px); }
  100% { opacity: 0; transform: translateY(-26px); }
}

/* ─────────────────────────────────────────────────────────── right panel ── */
.right-panel { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; padding-right: 3px; }

.setting { display: flex; align-items: center; gap: 10px; padding: 9px 2px; border-bottom: 1px solid var(--rule); }
.setting:last-child { border-bottom: none; }
.s-icon { font-size: 16px; width: 22px; text-align: center; flex: none; }
.s-body { flex: 1; min-width: 0; }
.s-name { font-size: 13px; font-weight: 750; }
.s-desc { font-size: 11px; color: var(--ink-3); line-height: 1.35; margin-top: 1px; }
.setting select { width: auto; padding: 6px 9px; font-size: 12.5px; }

.switch { position: relative; width: 42px; height: 23px; flex: none; }
.switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; z-index: 2; width: 100%; height: 100%; }
.switch .track { position: absolute; inset: 0; background: var(--rule-2); border-radius: 99px; transition: background .2s; }
.switch .thumb {
  position: absolute; top: 3px; left: 3px; width: 17px; height: 17px;
  background: var(--card); border-radius: 50%; box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
  transition: transform .22s var(--pop);
}
.switch input:checked ~ .track { background: var(--red); }
.switch input:checked ~ .thumb { transform: translateX(19px); }
.switch input:disabled ~ .track { opacity: .5; }

.name-field { margin-bottom: 10px; }
.swatches { display: flex; gap: 7px; flex-wrap: wrap; }
.swatch {
  width: 27px; height: 27px; border-radius: 50%; cursor: pointer;
  background: var(--c); border: 2px solid transparent;
  transition: transform .15s var(--pop), box-shadow .15s;
}
.swatch:hover:not(:disabled) { transform: scale(1.13); }
.swatch.sel { border-color: var(--card); box-shadow: 0 0 0 2px var(--c); }
.swatch:disabled { opacity: .25; cursor: not-allowed; }

.flag-picker {
  display: grid; grid-template-columns: repeat(10, 1fr); gap: 3px;
  margin-top: 10px; max-height: 116px; overflow-y: auto;
  padding: 6px; background: var(--paper-2);
  border: 1px solid var(--rule); border-radius: var(--r-sm);
}
.flag-opt {
  background: none; border: 1px solid transparent; border-radius: 6px;
  font-size: 15px; line-height: 1; padding: 3px 0; cursor: pointer;
  transition: transform .12s var(--pop), background .12s;
}
.flag-opt:hover { background: var(--card); transform: scale(1.2); }
.flag-opt.sel { background: var(--red-soft); border-color: var(--red); }

.waiting { display: flex; align-items: center; gap: 9px; color: var(--ink-2); font-size: 13px; justify-content: center; }
.pulse-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--red); animation: blink 1.2s infinite; }
@keyframes blink { 50% { opacity: .25; } }

.group-head {
  font-size: 10.5px; color: var(--ink-3); font-weight: 800; text-transform: uppercase;
  letter-spacing: .7px; margin: 9px 0 4px; display: flex; align-items: center; gap: 6px;
}
.group-head:first-child { margin-top: 0; }
.group-head.complete { color: var(--gold); }
.group-head i { font-style: normal; font-size: 8.5px; background: var(--gold-soft); color: var(--gold); padding: 2px 5px; border-radius: 4px; }

.prop-row {
  display: flex; align-items: center; gap: 8px; padding: 7px 9px; margin-bottom: 4px;
  background: var(--paper-2); border: 1px solid var(--rule);
  border-radius: var(--r-sm); font-size: 12.5px; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.prop-row:hover { border-color: var(--red); background: var(--red-soft); }
.prop-swatch { width: 4px; align-self: stretch; border-radius: 3px; flex: none; }
.prop-name { flex: 1; font-weight: 650; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prop-houses { font-size: 10px; letter-spacing: -1px; }
.prop-houses svg { width: 11px; height: 11px; vertical-align: -1px; }
.prop-actions { display: flex; gap: 3px; }
.prop-row.mortgaged .prop-name { text-decoration: line-through; color: var(--ink-3); }

.pot { text-align: center; }
.pot-amount { font-size: 23px; font-weight: 900; color: var(--gold); }

.trade-offer { border-color: var(--gold); }
.trade-line { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; padding: 4px 0; }
.trade-line span { color: var(--ink-3); flex: none; }
.trade-line b { text-align: right; font-weight: 750; }
.trade-line.good b { color: var(--good); }
.trade-line.bad b { color: var(--bad); }
.trade-offer .row-2 { margin-top: 9px; }
.trade-offer.ignored { border-color: var(--rule); opacity: 0.8; }
.trade-viewing {
  font-size: 11.5px; font-weight: 650; color: var(--gold);
  padding: 3px 0 1px; animation: viewingPulse 1.6s ease-in-out infinite;
}
@keyframes viewingPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

/* ────────────────────────────────────────────────────────────── modals ── */
.modal-root {
  position: fixed; inset: 0; background: var(--overlay);
  display: grid; place-items: center; z-index: 60; padding: 22px;
  backdrop-filter: blur(4px); animation: fadeIn .18s ease;
}
@keyframes fadeIn { from { opacity: 0; } }
.modal {
  background: var(--card);
  border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: 24px; width: min(480px, 96vw); max-height: 88vh; overflow-y: auto;
  box-shadow: var(--shadow); animation: modalIn .26s var(--pop);
}
@keyframes modalIn { from { transform: scale(.92) translateY(10px); opacity: 0; } }
.modal.small { width: min(380px, 94vw); }
.modal.wide { width: min(740px, 96vw); }
.modal.deed-modal { width: min(340px, 94vw); }
.modal h2 { font-size: 21px; font-weight: 800; }
.modal .sub { color: var(--ink-2); font-size: 13px; margin: 5px 0 18px; }
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 18px; flex-wrap: wrap; }

.deed {
  background: var(--card);
  border: 1px solid var(--rule-2); border-radius: var(--r); overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.deed.compact { width: min(228px, 90%); font-size: 11.5px; }
.deed-head { display: flex; align-items: center; gap: 7px; padding: 10px 13px; color: #fff; }
.deed.compact .deed-head { padding: 7px 10px; }
.deed-flag { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; }
.deed-flag svg { width: 100%; height: 100%; }
.deed.compact .deed-flag { width: 15px; height: 15px; }
.deed-title { font-weight: 900; font-size: 15px; letter-spacing: -.2px; }
.deed.compact .deed-title { font-size: 12.5px; }
.deed-price { text-align: center; font-size: 22px; font-weight: 900; padding: 9px 0 3px; color: var(--ink); }
.deed.compact .deed-price { font-size: 16px; padding: 6px 0 1px; }
.deed-rows { padding: 9px 13px 13px; }
.deed-row {
  display: flex; justify-content: space-between; gap: 12px; padding: 3.5px 0;
  color: var(--ink-2); border-bottom: 1px dashed var(--rule);
}
.deed.compact .deed-row { padding: 2px 0; }
.deed-row:last-child { border-bottom: none; }
.deed-row b { color: var(--ink); font-weight: 750; }
.deed-row b.dim { color: var(--ink-3); }
.deed-row.hl, .deed-row.hl b { color: var(--red); }
.deed-row.sep { margin-top: 4px; border-top: 1px solid var(--rule); padding-top: 6px; }

.map-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.map-card {
  display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center;
  background: var(--paper-2); border: 1px solid var(--rule);
  border-radius: var(--r); padding: 14px 12px; cursor: pointer; color: var(--ink);
  transition: border-color .16s, transform .16s var(--pop), background .16s;
}
.map-card:hover { border-color: var(--red); transform: translateY(-3px); background: var(--red-soft); }
.map-card.sel { border-color: var(--red); box-shadow: 0 0 0 2px rgba(191, 141, 40, .22); }
.map-card .mi { font-size: 26px; }
.map-card .mn { font-weight: 800; font-size: 14.5px; }
.map-card .md { font-size: 11px; color: var(--ink-3); line-height: 1.35; }
.map-card .mt { font-size: 10px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .6px; }

.trade-grid { display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; align-items: start; }
.trade-arrow { align-self: center; font-size: 22px; color: var(--ink-3); }
.trade-side { background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r); padding: 12px; }
.trade-who { display: flex; align-items: center; gap: 7px; font-weight: 750; font-size: 13.5px; margin-bottom: 9px; }
.trade-list { display: flex; flex-direction: column; gap: 2px; max-height: 210px; overflow-y: auto; margin-bottom: 10px; }
.check-row {
  display: flex; align-items: center; gap: 7px; font-size: 12.5px;
  padding: 5px 7px; border-radius: 6px; cursor: pointer; transition: background .13s;
}
.check-row:hover { background: var(--card); }
.check-row.blocked { opacity: .45; cursor: not-allowed; }
.check-row input { width: auto; margin: 0; accent-color: var(--red); }
.dotc { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.cr-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cr-name i { font-style: normal; color: var(--ink-3); font-size: 10.5px; }

.go-crown { font-size: 52px; text-align: center; animation: popIn .5s var(--pop); }
.go-title { text-align: center; font-size: 27px; font-weight: 900; }
.go-chart { margin: 6px 0 2px; }
.go-chart svg { width: 100%; height: auto; display: block; }
.gc-grid { stroke: var(--rule); stroke-width: 1; }
.gc-label { font-size: 9px; font-weight: 650; fill: var(--ink-3); }
.gc-flip { stroke: var(--gold); stroke-width: 1; stroke-dasharray: 4 3; opacity: .8; }
.gc-flip-label { font-size: 9px; font-weight: 800; fill: var(--gold); }
.gc-legend { display: flex; flex-wrap: wrap; gap: 5px 13px; justify-content: center; margin-top: 6px; }
.gc-key { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 750; color: var(--ink-2); }
.gc-key i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.rank-row {
  display: flex; align-items: center; gap: 10px; padding: 9px 11px; margin-bottom: 6px;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-sm);
}
.rank-row.me { border-color: var(--red); }
.rank-pos { font-size: 15px; width: 22px; text-align: center; font-weight: 800; }
.rank-name { flex: 1; font-weight: 750; font-size: 13.5px; }
.rank-worth { font-weight: 800; color: var(--good); font-size: 13.5px; }

/* Standings grew a second line: the badge a title-holder gets to wear. */
.rank-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.rank-main .rank-name { flex: none; }
.rank-title {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  line-height: 1.35; color: var(--gold);
}
.rank-title b { font-variant: small-caps; letter-spacing: .5px; font-size: 12.5px; font-weight: 850; }
.rank-title i { font-style: normal; font-size: 11px; color: var(--ink-3); }

/* The report card. Eleven columns will never fit a phone, so the table rides
   inside its own scroller while the sheet itself stays put. */
.stats-scroll { overflow-x: auto; border: 1px solid var(--rule); border-radius: var(--r-sm); }
.stats-table { border-collapse: collapse; min-width: 100%; font-size: 11.5px; font-variant-numeric: tabular-nums; }
.stats-table th, .stats-table td {
  padding: 6px 9px; white-space: nowrap; text-align: right;
  border-bottom: 1px solid var(--rule); color: var(--ink);
}
.stats-table thead th {
  font-size: 10px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--ink-3); background: var(--paper-2);
}
.stats-table tbody tr:last-child th, .stats-table tbody tr:last-child td { border-bottom: none; }
/* The name column stays put while the numbers slide beneath it. */
.stats-table th:first-child {
  position: sticky; left: 0; text-align: left; background: var(--card); font-weight: 750;
}
.stats-table thead th:first-child { background: var(--paper-2); }
.stats-table .dotc { display: inline-block; margin-right: 6px; }
.stats-table td i { display: block; font-style: normal; font-size: 9.5px; color: var(--ink-3); }
.stats-table tr.out th, .stats-table tr.out td { color: var(--ink-3); }

/* ────────────────────────────────────────────────────────── card popup ── */
.card-popup {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 70; width: min(340px, 90vw); padding: 24px; border-radius: var(--r-lg);
  text-align: center; box-shadow: var(--shadow); border: 2px solid;
  background: var(--card); animation: cardIn .4s var(--pop);
}
/* Both cards paint themselves out of the same tokens the matching tiles use, so
   they follow the theme instead of fighting it. The Surprise card used to pin a
   light pink background while its text stayed var(--ink) — near-white on the
   dark palettes — which is how it ended up a blank white box. */
.card-popup.treasure {
  border-color: var(--ink-treasure); background: var(--tile-treasure);
}
.card-popup.treasure .cp-kind { color: var(--ink-treasure); }
.card-popup.surprise {
  border-color: var(--ink-surprise); background: var(--tile-surprise);
}
.card-popup.surprise .cp-kind { color: var(--ink-surprise); }
/* Not a card drawn off a deck — the house explaining one of its own rules. It
   wears the brass accent every table has rather than a deck's colours. */
.card-popup.rule { border-color: var(--gold); background: var(--gold-soft); }
.card-popup.rule .cp-kind { color: var(--gold); }
.card-popup.rule .cp-text { font-size: 14px; font-weight: 600; }
.cp-ico { font-size: 40px; }
.cp-kind { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--ink-3); margin: 7px 0 9px; font-weight: 750; }
.cp-text { font-size: 15.5px; line-height: 1.5; font-weight: 650; color: var(--ink); }
.card-popup { cursor: pointer; }
.cp-hint { margin-top: 10px; font-size: 10.5px; letter-spacing: 1px; text-transform: uppercase; color: var(--ink-3); opacity: .75; }
@keyframes cardIn { from { transform: translate(-50%, -50%) scale(.72) rotate(-6deg); opacity: 0; } }

/* ────────────────────────────────────────────────────────────── toasts ── */
/* Full width so a wrapping message gets the whole screen to wrap in — anchored
   at left:50% it only ever had half of it. It must not swallow taps either. */
.toast-root {
  position: fixed; bottom: 20px; left: 0; right: 0;
  z-index: 80; display: flex; flex-direction: column; gap: 8px; align-items: center;
  pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 8px;
  background: var(--ink); color: var(--card);
  padding: 11px 17px; border-radius: 99px; font-size: 13.5px; font-weight: 550;
  box-shadow: var(--shadow); animation: toastIn .28s var(--pop);
  /* Long messages have to wrap: unbounded they ran off both edges of a phone. */
  max-width: min(92vw, 420px); text-align: center; line-height: 1.35;
}
.toast.error { background: var(--red-deep); }
.toast.out { animation: toastOut .3s ease forwards; }
.toast-n:not(:empty) { font-size: 11px; font-weight: 800; background: rgba(255, 255, 255, .22); padding: 2px 7px; border-radius: 99px; }
@keyframes toastIn { from { transform: translateY(14px); opacity: 0; } }
@keyframes toastOut { to { transform: translateY(10px); opacity: 0; } }

.tile-tip { position: fixed; z-index: 90; pointer-events: none; animation: fadeIn .12s ease; }
.tile-tip .deed.compact { width: 215px; }
.confetti { position: fixed; inset: 0; z-index: 75; pointer-events: none; }

/* ────────────────────────────────────────────────────────── responsive ── */
@media (max-width: 1240px) {
  .app { grid-template-columns: 230px minmax(0, 1fr) 268px; gap: 9px; padding: 9px; }
  .die { width: 64px; height: 64px; border-radius: 15px; }
  .pip { width: 11px; height: 11px; }
}
@media (max-width: 1024px) {
  html, body { overflow: auto; }
  .app { grid-template-columns: 1fr; height: auto; }
  .col.center { order: 1; }
  .col.right  { order: 2; }
  .col.left   { order: 3; }
  .board-wrap { width: min(96vw, 640px); margin: 0 auto; }
  .log-panel, .chat-panel { max-height: 250px; }
  .right-panel { overflow: visible; }
}
@media (max-width: 700px) {
  .tile-name { font-size: 6.6px; -webkit-line-clamp: 3; line-height: 1.06; overflow-wrap: anywhere; }
  .tile-sub { display: none; }
  .corner .tile-name { font-size: 7.5px; }
  .board { gap: 2px; padding: 3px; border-radius: 12px; }
  .tile { border-radius: 5px; }
  .board-center { inset: 15%; }
  .center-logo { display: none; }
  .deed.compact { width: min(180px, 94%); font-size: 10px; }
  /* The middle of the board is barely 250px tall on a phone. A full rent
     table there pushed the very Buy button it belongs to down over the tiles,
     and clipped the name of the street off the top — so the well keeps the
     name and the price, and the table stays one tap away on the tile. */
  .center-panel { gap: 10px; }
  .center-card .deed-rows { display: none; }
  .turn-banner-fly { top: 8%; }
  .tb-avatar { width: 25px; height: 25px; font-size: 12px; }
  .tb-text { font-size: 14px; }
  .flag-picker { grid-template-columns: repeat(8, 1fr); }
}
@media (max-width: 560px) {
  .app { padding: 8px; gap: 8px; }
  .board-wrap { width: 97vw; }
  .dice-row { height: 56px; gap: 12px; }
  .die { width: 48px; height: 48px; border-radius: 12px; padding: 7px; }
  .pip { width: 8px; height: 8px; }
  .center-action { width: 90%; }
  .btn.big { padding: 12px 16px; font-size: 14.5px; }
  .trade-grid { grid-template-columns: 1fr; }
  .trade-arrow { transform: rotate(90deg); }
  .landing-feats { gap: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* Names measured as overflowing their tile: the side columns lay text out along
   the short axis, so two-word streets need a smaller size to fit their lines,
   and corner labels needed the clamp loosened rather than tightened. */

.corner .tile-name { -webkit-line-clamp: 2; line-height: 1.22; }
/* The corner art was crowding out the label underneath it. */
.tile-art.huge { width: clamp(24px, 3.1vw, 52px); height: clamp(24px, 3.1vw, 52px); }
.corner .tile-body { gap: 2%; padding: 4% 3%; }

/* lobby centre */
.lobby-head { margin-bottom: 10px; }
.lobby-map { font-size: 12.5px; color: var(--ink-2); margin-top: 2px; font-weight: 600; }
/* The seats a table is still waiting on. Faces rather than dots, so a player
   sitting through the countdown can watch the table assemble. */
/* The regional boards mark their groups with a pictograph rather than a flag;
   it sits on the same optical line as the drawn ones. */
.group-mark { font-size: 1.05em; line-height: 1; vertical-align: -.1em; }

.seat-row { display: flex; gap: 10px; justify-content: center; margin: 8px 0 8px; flex-wrap: wrap; }
.seat-slot { display: flex; flex-direction: column; align-items: center; gap: 4px; width: 62px; }
.seat-face {
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 15px; font-weight: 850; color: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .28);
  animation: seatIn .32s var(--pop);
}
.seat-slot.open .seat-face {
  background: transparent; border: 2px dashed var(--rule-2); box-shadow: none; animation: none;
}
.seat-name {
  font-size: 10.5px; font-weight: 700; color: var(--ink-2);
  max-width: 62px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.seat-slot.open .seat-name { color: var(--ink-3); font-weight: 600; }
@keyframes seatIn { from { transform: scale(.5); opacity: 0; } }

.seat-dots { display: flex; gap: 6px; justify-content: center; margin: 4px 0 8px; }
.seat-dot {
  width: 11px; height: 11px; border-radius: 50%;
  background: transparent; border: 2px dashed var(--rule-2);
}
.seat-dot.filled { border: none; box-shadow: 0 1px 3px rgba(60, 30, 35, .3); }

/* Theme toggle sits with the other brand actions in game, and pairs up with the
   table-style button on the landing. Both sit in a row above the logo: parked
   on top of it they printed over the wordmark at every width. */
/* Signed-in presence: the chip is the proof that the Google button did
   something, and the menu behind it holds the details. */
.profile-chip {
  position: absolute; top: 0; right: 84px; z-index: 5;
  width: 34px; height: 34px; border-radius: 50%; padding: 0;
  border: 2px solid var(--gold); background: var(--card);
  overflow: hidden; cursor: pointer;
  display: grid; place-items: center;
  font-weight: 850; font-size: 14px; color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.profile-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profile-menu {
  position: absolute; top: 42px; right: 0; z-index: 30;
  width: min(280px, 86vw); padding: 14px;
  background: var(--card); border: 1px solid var(--rule);
  border-radius: var(--r); box-shadow: var(--shadow);
  text-align: left;
}
.pm-head { display: flex; gap: 11px; align-items: center; margin-bottom: 10px; }
.pm-photo {
  width: 44px; height: 44px; border-radius: 50%; overflow: hidden; flex: none;
  border: 2px solid var(--gold); background: var(--paper-2);
  display: grid; place-items: center; font-weight: 850; font-size: 18px; color: var(--ink);
}
.pm-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pm-name { font-weight: 800; font-size: 14.5px; color: var(--ink); line-height: 1.25; }
.pm-mail { font-size: 11.5px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 190px; }
.pm-row {
  display: flex; justify-content: space-between; gap: 8px;
  font-size: 12.5px; color: var(--ink-2); padding: 5px 0;
  border-top: 1px solid var(--rule);
}
.pm-row b { color: var(--ink); font-weight: 750; }
.pm-actions { margin-top: 10px; display: flex; gap: 8px; }

.theme-float, .palette-float {
  position: absolute; top: 0; font-size: 17px;
  background: var(--paper-2); border: 1px solid var(--rule);
  border-radius: 50%; line-height: 1; padding: 6px 8px;
}
.theme-float { right: 0; }
.palette-float { right: 42px; }
/* The landing wore hard-coded white text for a dark hero it never had: on a
   light table the wordmark, tagline and stats vanished into the page. */

/* Theme changes ease instead of snapping. */
.panel, .player-card, .landing-card, .tile, .board, .center-panel, .modal, .btn, input, select {
  transition-property: background-color, border-color, color, box-shadow, transform, filter;
  transition-duration: .24s;
  transition-timing-function: var(--ease);
}
.tile.ownable:hover { transform: translateY(-1px); }

/* Empty seats read as an invitation, not a broken box. */
.player-card.empty-seat {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--rule-2) 70%, transparent);
  background: color-mix(in srgb, var(--card) 22%, transparent);
}
.player-card.empty-seat:hover { border-color: var(--red); }

/* The left column packs to the top rather than stretching to fill. */
.col.left { justify-content: flex-start; }

/* Focus mode: fold the log and chat away and the board takes the width back. */
body.focus-board .app { grid-template-columns: 0 minmax(0, 1fr) clamp(242px, 18vw, 290px); }
body.focus-board .col.left { opacity: 0; pointer-events: none; overflow: hidden; }
.col.left { transition: opacity .2s var(--ease); }
#focusBtn.on { color: var(--red); background: var(--red-soft); }
/* Parked on the screen while the panel it belongs to is hidden, so there is
   always a way back to the side panel. */
#focusBtn.floating {
  position: fixed; top: 12px; left: 12px; z-index: 60;
  width: 34px; height: 34px; display: grid; place-items: center; padding: 0;
  border: 1px solid var(--rule); border-radius: 10px;
  background: var(--card); box-shadow: var(--shadow-sm);
}

@media (max-width: 1024px) {
  body.focus-board .app { grid-template-columns: 1fr; }
  body.focus-board .col.left { display: none; }
}

/* ── landing: wallet row, karma and the name dice ── */
.wallet-row { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.wallet-row .store-btn { flex: 1; margin-top: 0; }
.karma-chip {
  flex: none; font-size: 12.5px; font-weight: 850; white-space: nowrap;
  color: var(--good); background: var(--good-soft);
  border: 1px solid var(--good); border-radius: 99px; padding: 8px 12px;
}
.karma-chip.low { color: var(--bad); border-color: var(--bad); background: color-mix(in srgb, var(--bad) 12%, var(--card)); }

.name-row { display: flex; gap: 8px; align-items: stretch; }
.name-row input { flex: 1; min-width: 0; }
/* `.field span` dresses every caption inside a label and would stack this row
   vertically, so the row has to out-specify it — hence `.field .name-row`
   carrying the layout rather than `.name-row` alone. Outside a label (the
   invite modal) the plain rule above is what keeps the dice beside the field. */
.field .name-row {
  display: flex; gap: 8px; align-items: stretch;
  margin-bottom: 0; font-size: 16px; font-weight: 400; color: var(--ink);
}
.dice-btn { flex: none; padding: 0 14px; font-size: 18px; }

/* ── store: coin packs (bought in the iOS app, shown here) ── */
/* 96px so all three packs still sit on one row on a phone — at 118 the third
   one dropped to a line of its own. */
.pack-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 10px; }
.pack-card {
  position: relative; text-align: center; text-decoration: none; color: var(--ink);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 14px 8px 12px; border-radius: var(--r);
  background: var(--paper-2); border: 1.5px solid var(--rule-2);
  transition: transform .15s var(--pop), border-color .15s;
}
.pack-card:hover { transform: translateY(-2px); border-color: var(--gold); }
.pk-emoji { font-size: 32px; line-height: 1.1; }
.pk-coins { font-size: 14.5px; font-weight: 900; color: var(--gold); }
.pk-name { font-size: 12px; font-weight: 750; color: var(--ink-2); }
.pk-price {
  margin-top: 5px; font-size: 12.5px; font-weight: 850;
  background: var(--card); border: 1px solid var(--rule-2); border-radius: 99px; padding: 2px 11px;
}
.pk-bonus {
  position: absolute; top: 6px; right: 6px;
  font-size: 9.5px; font-weight: 850; color: #fff;
  background: var(--good); border-radius: 99px; padding: 2px 6px;
}
.pack-link { color: var(--gold); font-weight: 750; text-decoration: none; white-space: nowrap; }
.pack-link:hover { text-decoration: underline; }

/* ── trade: cash slider ── */
.cash-slider { margin-top: 10px; }
.cs-label { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.cs-track { position: relative; height: 46px; }
.cs-track input[type="range"] {
  position: absolute; top: 6px; left: 0; width: 100%; height: 18px;
  -webkit-appearance: none; appearance: none;
  background: transparent; border: none; box-shadow: none; padding: 0; cursor: pointer;
}
.cs-track input[type="range"]:focus { box-shadow: none; }
.cs-track input[type="range"]:focus-visible { outline: 2px solid var(--red); outline-offset: 4px; border-radius: 99px; }
.cs-track input[type="range"]:disabled { opacity: .45; cursor: not-allowed; }
.cs-track input[type="range"]::-webkit-slider-runnable-track {
  height: 6px; border-radius: 99px;
  background: linear-gradient(90deg, var(--red) 0 calc(var(--pct) * 100%), var(--rule-2) calc(var(--pct) * 100%) 100%);
}
.cs-track input[type="range"]::-moz-range-track {
  height: 6px; border-radius: 99px;
  background: linear-gradient(90deg, var(--red) 0 calc(var(--pct) * 100%), var(--rule-2) calc(var(--pct) * 100%) 100%);
}
.cs-track input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; margin-top: -6px; border-radius: 50%;
  background: var(--card); border: 2px solid var(--red); box-shadow: var(--shadow-sm);
}
.cs-track input[type="range"]::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%; box-sizing: border-box;
  background: var(--card); border: 2px solid var(--red); box-shadow: var(--shadow-sm);
}
/* The pill rides the thumb: half a thumb in, then across the track it can reach. */
.cs-bubble {
  position: absolute; top: 27px; left: calc(9px + var(--pct) * (100% - 18px));
  transform: translateX(-50%); pointer-events: none; white-space: nowrap;
  font-size: 12px; font-weight: 850; color: var(--red-ink);
  background: var(--red-soft); border: 1px solid var(--red);
  border-radius: 99px; padding: 1px 9px;
}
.cs-max { display: block; font-size: 11px; color: var(--ink-3); font-weight: 650; }

/* ── deed sheet: quick build bar ── */
/* It lives inside the deed now, between the price and the rent table, so it is
   inset from the card edge rather than stacked under it. */
.quick-build {
  margin: 10px 13px 4px; padding: 11px 12px; border-radius: var(--r);
  background: var(--paper-2); border: 1px solid var(--rule);
}
.qb-status { display: flex; flex-direction: column; gap: 2px; margin-bottom: 9px; text-align: center; }
.qb-level { font-size: 15px; font-weight: 850; letter-spacing: 1px; }
.qb-next { font-size: 11.5px; color: var(--ink-3); line-height: 1.35; }
.qb-row { display: flex; align-items: center; gap: 6px; }
.qb-btn {
  font: inherit; flex: none; cursor: pointer;
  min-width: 40px; padding: 9px 11px; border-radius: var(--r-sm);
  background: var(--card); border: 1px solid var(--rule-2); color: var(--ink);
  font-size: 15px; font-weight: 850; line-height: 1;
  transition: transform .12s var(--pop), border-color .16s, color .16s;
}
.qb-btn:hover:not(:disabled) { border-color: var(--red); color: var(--red-deep); }
.qb-btn:active:not(:disabled) { transform: scale(.94); }
.qb-btn:disabled { opacity: .38; cursor: not-allowed; }
.qb-btn.mort { flex: 1; font-size: 12.5px; font-weight: 750; }
.qb-btn.gold { border-color: var(--gold); color: var(--gold); }
.qb-count { flex: 1; text-align: center; font-size: 17px; font-weight: 900; }
.qb-count small { font-size: 11px; font-weight: 700; color: var(--ink-3); }

/* ── turn clock ── */
.turn-clock {
  flex: none; font-size: 11.5px; font-weight: 850; font-variant-numeric: tabular-nums;
  color: var(--ink-2); background: var(--paper-2);
  border: 1px solid var(--rule-2); border-radius: 99px; padding: 3px 8px;
}
.turn-clock.urgent { color: #fff; background: var(--bad); border-color: var(--bad); animation: clockPulse .9s ease-in-out infinite; }
.turn-clock-well { font-size: 13px; font-weight: 800; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.turn-clock-well.urgent { color: var(--bad); animation: clockPulse .9s ease-in-out infinite; }
@keyframes clockPulse { 50% { opacity: .5; transform: scale(1.06); } }

/* ── holding a dropped player's chair ── */
/* It sits above the roster in brass so it reads as a decision the table owes
   somebody, not as another status line about them. */
.awaiting-well { flex: none; display: flex; flex-direction: column; gap: 8px; }
.await-card {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--card); border: 1px solid var(--gold); border-radius: var(--r);
  padding: 11px 12px; box-shadow: var(--shadow-sm);
}
.aw-head { display: flex; align-items: center; gap: 9px; }
.aw-who { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-size: 12.5px; color: var(--ink-2); }
.aw-who b { color: var(--ink); font-weight: 850; }
.aw-left { font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.aw-left.urgent { color: var(--bad); font-weight: 800; }
.aw-votes { display: flex; gap: 4px; }
.aw-votes i { flex: 1; height: 4px; border-radius: 99px; background: var(--rule-2); transition: background .2s var(--ease); }
.aw-votes i.on { background: var(--gold); }
.aw-note { font-size: 11px; color: var(--ink-3); line-height: 1.35; }

/* ── leaving for good, and the removed-from-play overlay ── */
.leave-choices { display: flex; flex-direction: column; gap: 8px; }
.leave-choice {
  font: inherit; width: 100%; text-align: left; cursor: pointer;
  display: flex; flex-direction: column; gap: 3px;
  padding: 12px 14px; border-radius: var(--r);
  background: var(--paper-2); border: 1px solid var(--rule-2); color: var(--ink);
  transition: transform .12s var(--pop), border-color .16s, background .16s;
}
.leave-choice:hover { transform: translateY(-1px); border-color: var(--red); background: var(--red-soft); }
.leave-choice.bad:hover { border-color: var(--bad); background: color-mix(in srgb, var(--bad) 10%, var(--card)); }
.leave-choice b { font-size: 14px; font-weight: 850; }
.leave-choice span { font-size: 11.5px; color: var(--ink-3); line-height: 1.4; }
.karma-note { margin-top: 12px; text-align: center; font-size: 12px; font-weight: 750; color: var(--gold); }
.removed-mark { font-size: 44px; text-align: center; line-height: 1.1; }
.removed-title { text-align: center; }
.removed-modal .sub { text-align: center; }
.removed-modal .modal-actions { justify-content: center; }

/* ═══════════════════════════════════════════════════════════════════════
   Quick Play, live standings and the helpers that read the board for you
   ═══════════════════════════════════════════════════════════════════════ */

/* ── landing: "Play now" sits above the private-game controls ── */
.quick-note {
  margin: 8px 0 16px; font-size: 11.5px; line-height: 1.45;
  color: var(--ink-3); text-align: center;
}

/* ── board centre: the searching state a Quick Play table shows itself ── */
.quick-search {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  font-size: 15.5px; font-weight: 800; color: var(--ink);
}
.quick-count { font-size: 12.5px; color: var(--ink-3); font-weight: 650; text-align: center; }
.quick-count b { color: var(--gold); font-weight: 850; font-variant-numeric: tabular-nums; }

/* ── the line everyone reads while waiting: a tip or a city fact ── */
.table-talk {
  min-height: 18px; max-width: 460px; margin: 0 auto;
  font-size: 12px; line-height: 1.5; color: var(--ink-2); text-align: center;
}
.table-talk b { color: var(--ink); font-weight: 750; }
.table-talk .talk-in { display: block; animation: talkIn .7s ease; }
@keyframes talkIn { from { opacity: 0; } }
.modal .table-talk { margin-top: 16px; }

/* ── the undealt table, and the deal at kick-off ── */
/* While a quick match hunts for players the tiles wait in the deck: bare
   felt, a riffling deck, the lobby info alongside. A private lobby keeps the
   full preview — the host picked that map to look at it. */
.board-wrap.undealt .tile { opacity: 0; pointer-events: none; transition: none; }
.board-wrap.undealt .token-layer,
.board-wrap.dealing .token-layer { opacity: 0; }

/* The drawn deck: stacked card backs in the game's red wearing the MM
   monogram — the same back the iOS deck deals from. */
.deal-deck {
  position: relative; margin: 0 auto 12px;
  width: clamp(48px, 5.2vw, 64px); height: clamp(70px, 7.4vw, 92px);
  pointer-events: none;
}
.deal-card {
  position: absolute; left: 50%; top: 50%;
  width: 100%; height: 100%;
  display: grid; place-items: center;
  border-radius: 9px;
  background: linear-gradient(150deg, var(--red), var(--red-deep));
  box-shadow: 0 4px 10px rgba(0, 0, 0, .3);
  transform: translate(-50%, -50%) translateY(calc(var(--i) * -2.4px))
             rotate(calc(var(--i) * 1.4deg - 4deg));
}
.deal-card::before {
  content: ''; position: absolute; inset: 5px;
  border: 1.5px solid rgba(255, 255, 255, .38); border-radius: 6px;
}
.deal-card::after {
  content: 'MM';
  font-size: clamp(11px, 1.3vw, 16px); font-weight: 900; letter-spacing: .5px;
  color: rgba(255, 255, 255, .82);
}

/* The idle riffle: the halves ease apart, hang a beat, and merge again —
   once every four-and-a-half seconds while the table waits. */
.deal-deck.idle .deal-card { animation: deckRiffle 4.6s ease-in-out infinite; }
@keyframes deckRiffle {
  0%, 74%, 96%, 100% {
    transform: translate(-50%, -50%) translateY(calc(var(--i) * -2.4px))
               rotate(calc(var(--i) * 1.4deg - 4deg));
  }
  80%, 85% {
    transform: translate(-50%, -50%)
               translate(calc(var(--h) * 42%), calc(var(--i) * -2.4px + var(--h) * 2px))
               rotate(calc(var(--h) * 9deg));
  }
  90% {
    transform: translate(-50%, -50%) translateY(calc(var(--i) * -1.2px))
               rotate(calc(var(--h) * -2deg));
  }
}

/* The deal: pinned to the middle of the table for one sharp riffle, then the
   deck sinks away as the tiles fly out of it (board.js flies them). */
.deal-deck.deal-out {
  position: absolute; left: 50%; top: 50%; z-index: 9; margin: 0;
  transform: translate(-50%, -50%);
  animation: deckSink .5s ease-in .55s forwards;
}
.deal-deck.deal-out .deal-card { animation: deckRiffleOnce .58s ease-in-out; }
@keyframes deckRiffleOnce {
  0%, 100% {
    transform: translate(-50%, -50%) translateY(calc(var(--i) * -2.4px))
               rotate(calc(var(--i) * 1.4deg - 4deg));
  }
  38% {
    transform: translate(-50%, -50%)
               translate(calc(var(--h) * 42%), calc(var(--i) * -2.4px + var(--h) * 2px))
               rotate(calc(var(--h) * 9deg));
  }
  72% {
    transform: translate(-50%, -50%) translateY(calc(var(--i) * -1.2px))
               rotate(calc(var(--h) * -2deg));
  }
}
@keyframes deckSink {
  to { transform: translate(-50%, -50%) scale(.35); opacity: 0; }
}

/* ── right panel: who has turned up at a Quick Play table ── */
.quick-blurb { font-size: 12px; color: var(--ink-3); line-height: 1.45; margin-bottom: 10px; }
.quick-seats { display: flex; flex-direction: column; gap: 5px; margin-bottom: 9px; }
.quick-seat {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 7px; border-radius: var(--r-sm);
  background: var(--paper-2); border: 1px solid var(--rule);
}
.quick-seat.open { background: transparent; border-style: dashed; }
.qs-name { flex: 1; min-width: 0; font-size: 12.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── player chips: live position, and a nudge for whoever plays next ── */
.prank {
  flex: none; min-width: 21px; line-height: 1.15;
  display: flex; flex-direction: column; align-items: center;
  font-size: 10.5px; font-weight: 850; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.prank b { font-size: 12.5px; }
.prank.lead { color: var(--gold); }
.tag.next { background: var(--gold-soft); color: var(--gold); }
.player-card.next-up { border-color: color-mix(in srgb, var(--gold) 45%, var(--rule)); }

/* ── one street short of a whole set ── */
.one-away {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 3px 0 2px; padding: 7px 9px; border-radius: var(--r-sm);
  background: var(--gold-soft); border: 1px dashed var(--gold);
  font-size: 11.5px; line-height: 1.4; color: var(--ink-2);
}
.one-away span { flex: 1; min-width: 120px; }
.one-away b { color: var(--ink); font-weight: 800; }

/* ── the deadlock rule counting laps in the background ── */
/* Calm on purpose: this is a rule ticking over several turns, not an alarm. */
.panel.deadlock { border-color: color-mix(in srgb, var(--gold) 45%, var(--rule)); }
.dl-laps { display: flex; align-items: center; gap: 9px; margin: 2px 0 8px; }
.lap-pips { display: flex; gap: 5px; }
.lap-pips i {
  width: 13px; height: 6px; border-radius: 99px;
  background: var(--rule-2); transition: background .3s;
}
.lap-pips i.on { background: var(--gold); }
.dl-count { font-size: 11px; font-weight: 800; letter-spacing: .4px; color: var(--gold); }

/* ── owing money: the shortfall, then the biggest levers ── */
.raise-panel { border-color: var(--bad); }
.raise-line { font-size: 12.5px; line-height: 1.45; margin-bottom: 8px; color: var(--ink-2); }
.raise-line b { font-weight: 900; font-size: 15px; }
.raise-row {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 0; border-bottom: 1px solid var(--rule);
}
.raise-row:last-child { border-bottom: none; }
/* "Sell a building on Frankfurt" is longer than the column: clipped to
   "…on Frankf…" it hid the one word that says which deed you are spending. */
.raise-what { flex: 1; min-width: 0; font-size: 12px; font-weight: 650; line-height: 1.35; }
.good-text { color: var(--good); font-weight: 750; }
.bad-text  { color: var(--bad); font-weight: 750; }

/* ── trade composer: totals, verdict and the fairness helper ── */
.trade-totals {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; margin-top: 14px; padding: 10px 12px;
  border-radius: var(--r); background: var(--paper-2); border: 1px solid var(--rule);
  font-size: 12.5px; color: var(--ink-2);
}
.trade-totals b { color: var(--ink); font-weight: 850; }
.trade-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.trade-tools .dim { flex: 1; min-width: 150px; line-height: 1.4; }

/* ── game over: the rematch is the next step, not a footnote ── */
.btn.wrap { white-space: normal; line-height: 1.3; }
.go-actions { flex-direction: column; align-items: stretch; }
.go-wait { text-align: center; }

/* ═══════════════════════════════════════════════════════════════════════
   Drawn glyphs in the chrome around the table
   The icons themselves come from js/icons.js; these rules only give them a
   place to stand next to the words they belong to.
   ═══════════════════════════════════════════════════════════════════════ */

/* Waiting on the server. The replay arrow doubles as the spinner, so a busy
   button still shows a drawing of ours rather than a borrowed hourglass. */
.ico.spin { animation: ico-spin 1.1s linear infinite; transform-origin: 50% 50%; }
@keyframes ico-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ico.spin { animation: none; } }

/* Chips read as one badge, not a picture with a number beside it. */
.coin-chip, .karma-chip, .sc-price, .pk-coins {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
}
.friend-flag { display: flex; align-items: center; }
.chat-channels button { display: inline-flex; align-items: center; gap: 5px; }
.map-card .mn { display: flex; align-items: center; justify-content: center; gap: 6px; }

/* How to play: the list never had a layout of its own — an emoji simply sat in
   the text flow. A drawn glyph wants a column of its own to line up in. */
.help-list { display: flex; flex-direction: column; gap: 13px; }
.help-row { display: flex; align-items: flex-start; gap: 12px; }
.help-ico { flex: none; margin-top: 1px; color: var(--red-ink); }
.help-row > div b { display: block; font-size: 13.5px; font-weight: 850; margin-bottom: 2px; }
.help-row > div span { font-size: 12px; color: var(--ink-2); line-height: 1.5; }
