/* ═══════════════════════════════════════════════════════════
   Mivimoose Draw — complete UI redesign
   Playful-modern: paper background, chunky cards, gradient ink.
   ═══════════════════════════════════════════════════════════ */

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

/* ── Themes ──────────────────────────────────────────────────
   Midnight is the default and lives on :root; every other theme
   is a [data-theme] block that re-declares the same tokens.
   Two rules for a readable theme:
     --brand          must take white text (buttons sit on it)
     --brand-on-soft  is brand-coloured text ON --brand-soft
   ──────────────────────────────────────────────────────────── */

:root {
  /* Midnight (default) */
  --bg: #131427;
  --dot: #23244A;
  --card: #1D1F3A;
  --card-2: #24264A;
  --ink: #EDEEFC;
  --ink-dim: #9A9DBF;
  --line: #32355C;
  --brand: #6C5CE7;
  --brand-soft: #2C2A55;
  --brand-on-soft: #B9B3F5;
  --pink: #FD79A8;
  --teal: #00CEC9;
  --yellow: #FDCB6E;
  --good: #00D2A0;
  --good-soft: #143D34;
  --bad: #FF7F63;
  --bad-soft: #46271E;
  --grad: linear-gradient(120deg, #6C5CE7, #FD79A8);
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  --shadow-sm: 0 3px 12px rgba(0, 0, 0, 0.3);

  /* Shared, never themed */
  --r-lg: 22px;
  --r-md: 14px;
  --r-sm: 10px;
  --canvas-bg: #ffffff;
}

[data-theme="light"] {
  --bg: #F1F2F9;
  --dot: #DDDFF0;
  --card: #FFFFFF;
  --card-2: #F6F6FC;
  --ink: #23263B;
  --ink-dim: #7C7F99;
  --line: #E6E7F3;
  --brand: #6C5CE7;
  --brand-soft: #ECE9FF;
  --brand-on-soft: #6C5CE7;
  --pink: #FD79A8;
  --teal: #00CEC9;
  --yellow: #FDCB6E;
  --good: #00B894;
  --good-soft: #E0F7F1;
  --bad: #E17055;
  --bad-soft: #FDEEEA;
  --grad: linear-gradient(120deg, #6C5CE7, #FD79A8);
  --shadow: 0 10px 30px rgba(35, 38, 59, 0.09);
  --shadow-sm: 0 3px 12px rgba(35, 38, 59, 0.07);
}

[data-theme="sunset"] {
  --bg: #1E1024;
  --dot: #34203C;
  --card: #2A1531;
  --card-2: #351B3D;
  --ink: #FFEDF5;
  --ink-dim: #C49AB4;
  --line: #4A2551;
  --brand: #D9457C;
  --brand-soft: #45203F;
  --brand-on-soft: #FFA8C5;
  --pink: #FF6B9D;
  --teal: #4ECDC4;
  --yellow: #FFC46B;
  --good: #3ED598;
  --good-soft: #1B3F35;
  --bad: #FF7A5C;
  --bad-soft: #46261F;
  --grad: linear-gradient(120deg, #D9457C, #E8763C);
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  --shadow-sm: 0 3px 12px rgba(0, 0, 0, 0.32);
}

[data-theme="forest"] {
  --bg: #0E1A14;
  --dot: #1D3128;
  --card: #142620;
  --card-2: #1B3129;
  --ink: #E4F5EA;
  --ink-dim: #8FB3A0;
  --line: #24443A;
  --brand: #24814F;
  --brand-soft: #17352A;
  --brand-on-soft: #86EFAC;
  --pink: #F472B6;
  --teal: #22D3EE;
  --yellow: #FDE047;
  --good: #4ADE80;
  --good-soft: #17352A;
  --bad: #F87171;
  --bad-soft: #3A211F;
  --grad: linear-gradient(120deg, #24814F, #1B92A1);
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  --shadow-sm: 0 3px 12px rgba(0, 0, 0, 0.3);
}

[data-theme="ocean"] {
  --bg: #0A1A2B;
  --dot: #16304A;
  --card: #10243A;
  --card-2: #163049;
  --ink: #E2F1FF;
  --ink-dim: #8FAEC9;
  --line: #1F4468;
  --brand: #1E7FC2;
  --brand-soft: #12324D;
  --brand-on-soft: #7DD3FC;
  --pink: #F472B6;
  --teal: #2DD4BF;
  --yellow: #FCD34D;
  --good: #2DD4BF;
  --good-soft: #0F3B37;
  --bad: #FB7185;
  --bad-soft: #3D1F27;
  --grad: linear-gradient(120deg, #1E7FC2, #6366F1);
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  --shadow-sm: 0 3px 12px rgba(0, 0, 0, 0.3);
}

[data-theme="noir"] {
  --bg: #0F0F10;
  --dot: #232326;
  --card: #191A1C;
  --card-2: #202124;
  --ink: #F2F2F3;
  --ink-dim: #A0A0A6;
  --line: #303035;
  --brand: #55565E;
  --brand-soft: #2A2A2E;
  --brand-on-soft: #D8D8DE;
  --pink: #C9C9D1;
  --teal: #9AA3A8;
  --yellow: #D8CFA8;
  --good: #7FB08A;
  --good-soft: #233026;
  --bad: #C97A6A;
  --bad-soft: #33231F;
  --grad: linear-gradient(120deg, #3F3F46, #71717A);
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  --shadow-sm: 0 3px 12px rgba(0, 0, 0, 0.4);
}

[data-theme="candy"] {
  --bg: #FFF5F8;
  --dot: #FFE1EC;
  --card: #FFFFFF;
  --card-2: #FFF0F5;
  --ink: #4A2437;
  --ink-dim: #A67C90;
  --line: #FBDCE7;
  --brand: #EC4899;
  --brand-soft: #FCE7F3;
  --brand-on-soft: #DB2777;
  --pink: #F472B6;
  --teal: #2DD4BF;
  --yellow: #FBBF24;
  --good: #10B981;
  --good-soft: #D1FAE5;
  --bad: #F97316;
  --bad-soft: #FFEDD5;
  --grad: linear-gradient(120deg, #EC4899, #8B5CF6);
  --shadow: 0 10px 30px rgba(120, 40, 80, 0.12);
  --shadow-sm: 0 3px 12px rgba(120, 40, 80, 0.09);
}

[data-theme="sepia"] {
  --bg: #F5EFE3;
  --dot: #E4D9C4;
  --card: #FFFBF3;
  --card-2: #F3EADA;
  --ink: #3B3229;
  --ink-dim: #8A7A64;
  --line: #E5D9C6;
  --brand: #B45309;
  --brand-soft: #FBEBD5;
  --brand-on-soft: #92400E;
  --pink: #BE5A70;
  --teal: #0F766E;
  --yellow: #D97706;
  --good: #15803D;
  --good-soft: #DCFCE7;
  --bad: #B91C1C;
  --bad-soft: #FEE2E2;
  --grad: linear-gradient(120deg, #B45309, #D97706);
  --shadow: 0 10px 30px rgba(80, 60, 30, 0.12);
  --shadow-sm: 0 3px 12px rgba(80, 60, 30, 0.09);
}

html { font-size: 16px; }

body {
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  background-color: var(--bg);
  background-image: radial-gradient(var(--dot) 1.2px, transparent 1.2px);
  background-size: 22px 22px;
  color: var(--ink);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden; /* nothing gets to poke off the side of the page */
}

button { font-family: inherit; color: inherit; }

/* ── Top bar ─────────────────────────────────────────────── */
.topbar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 20px;
  background: color-mix(in srgb, var(--card) 82%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.brand { display: flex; align-items: center; gap: 10px; background: none; border: none; cursor: pointer; }
.brand-mark svg { width: 42px; height: 42px; display: block; filter: drop-shadow(0 3px 6px rgba(108, 92, 231, .35)); transition: transform .2s; }
.brand:hover .brand-mark svg { transform: rotate(-6deg) scale(1.05); }
.brand-text {
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 1.45rem;
  letter-spacing: -0.5px; display: flex; align-items: center; gap: 8px;
}
.brand-chip {
  font-size: 0.62rem; font-weight: 700; letter-spacing: 2.5px;
  background: var(--grad); color: #fff;
  padding: 3px 8px 2px 10px; border-radius: 99px; transform: translateY(1px);
}

.topbar-mid { flex: 1; display: flex; justify-content: center; }
.room-pill {
  display: flex; align-items: center; gap: 6px;
  background: var(--brand-soft); border: 1px solid var(--line);
  padding: 5px 6px 5px 14px; border-radius: 99px;
}
.room-pill-code { font-family: 'Fredoka', sans-serif; font-weight: 600; letter-spacing: 5px; color: var(--brand); }
.room-pill-btn { background: var(--card); border: 1px solid var(--line); border-radius: 99px; width: 30px; height: 30px; cursor: pointer; transition: transform .15s; }
.room-pill-btn:hover { transform: scale(1.12); }

.topbar-actions { display: flex; align-items: center; gap: 8px; }
.icon-btn {
  width: 38px; height: 38px; border-radius: 12px;
  background: var(--card); border: 1px solid var(--line);
  cursor: pointer; font-size: 1.05rem;
  transition: transform .15s, border-color .15s;
  display: flex; align-items: center; justify-content: center;
}
.icon-btn:hover { transform: translateY(-2px); border-color: var(--brand); }
.icon-btn.off { opacity: .45; filter: grayscale(1); }

.account-chip {
  display: flex; align-items: center; gap: 8px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 99px; padding: 5px 14px 5px 6px;
  font-weight: 700; font-size: 0.88rem; cursor: pointer;
  transition: transform .15s, border-color .15s;
}
.account-chip:hover { transform: translateY(-2px); border-color: var(--brand); }
.account-chip-avatar {
  width: 28px; height: 28px; border-radius: 99px;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand-soft); font-size: 0.95rem;
}

/* ── Layout ──────────────────────────────────────────────── */
#main { max-width: 1760px; margin: 0 auto; padding: 18px 20px 40px; }
/* In a game the layout takes the whole window — the old max-width left a
   band of empty space on wide screens and squeezed the canvas. */
body.in-game #main { max-width: none; padding: 12px 14px 12px; height: calc(100dvh - 60px); display: flex; flex-direction: column; }
body.in-game #screen-game.active { flex: 1; min-height: 0; display: flex; flex-direction: column; }
body.in-game .game-grid { flex: 1; min-height: 0; }
body.in-game .canvas-card { min-height: 0; }
body.in-game .players-card, body.in-game .chat-card { min-height: 0; }
.screen { display: none; }
.screen.active { display: block; animation: screenIn .35s ease; }
@keyframes screenIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  padding: 20px;
}
.card-title { font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 1.05rem; margin-bottom: 12px; }
.card-title-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.card-title-row .card-title { margin-bottom: 0; }
.card-hint { font-size: 0.8rem; color: var(--ink-dim); margin: -6px 0 14px; }

.pill { background: var(--card-2); border: 1px solid var(--line); border-radius: 99px; padding: 3px 12px; font-size: 0.8rem; font-weight: 700; color: var(--ink-dim); }
.mini-btn {
  background: var(--card-2); border: 1px solid var(--line); border-radius: 99px;
  padding: 5px 12px; font-size: 0.78rem; font-weight: 700; color: var(--ink-dim);
  cursor: pointer; transition: color .15s, border-color .15s;
}
.mini-btn:hover { color: var(--brand); border-color: var(--brand); }
.mini-btn-row { display: flex; gap: 6px; }

/* ── Inputs & buttons ───────────────────────────────────── */
.input {
  background: var(--card-2); border: 2px solid var(--line);
  border-radius: var(--r-md); padding: 11px 15px;
  color: var(--ink); font-family: inherit; font-size: 0.95rem; font-weight: 600;
  outline: none; transition: border-color .15s, background .15s;
  width: 100%;
}
.input:focus { border-color: var(--brand); background: var(--card); }
.input::placeholder { color: var(--ink-dim); font-weight: 500; }
.textarea { resize: vertical; min-height: 70px; line-height: 1.5; }
.select { cursor: pointer; }

.btn {
  border: none; cursor: pointer; font-weight: 800; font-family: inherit;
  border-radius: var(--r-md); color: #fff;
  background: var(--brand);
  box-shadow: 0 4px 0 color-mix(in srgb, var(--brand) 70%, #000);
  transition: transform .12s, box-shadow .12s, filter .15s;
}
.btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.btn:active { transform: translateY(3px); box-shadow: 0 1px 0 color-mix(in srgb, var(--brand) 70%, #000); }
.btn-big { padding: 13px 22px; font-size: 0.95rem; }
.btn-small { padding: 9px 16px; font-size: 0.83rem; }
.btn-alt {
  background: var(--card-2); color: var(--ink);
  border: 2px solid var(--line);
  box-shadow: 0 4px 0 var(--line);
}
.btn-alt:active { box-shadow: 0 1px 0 var(--line); }
.btn-alt:hover { border-color: var(--brand); }
.btn.used { opacity: .5; pointer-events: none; }

.btn-hero {
  display: flex; align-items: center; gap: 16px; width: 100%;
  background: var(--grad); text-align: left;
  padding: 18px 22px; border-radius: 18px;
  box-shadow: 0 6px 0 #4c3fd1, 0 14px 30px rgba(108, 92, 231, .35);
}
.btn-hero:active { transform: translateY(4px); box-shadow: 0 2px 0 #4c3fd1; }
.btn-hero-icon { font-size: 1.9rem; }
.btn-hero-label { display: block; font-size: 1.15rem; font-weight: 800; }
.btn-hero-sub { display: block; font-size: 0.78rem; font-weight: 600; opacity: .85; margin-top: 2px; }

.linklike { background: none; border: none; color: var(--brand); font-weight: 700; font-size: 0.85rem; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

.btn-discord {
  background: #5865F2;
  box-shadow: 0 4px 0 #3c45c4;
  display: flex; align-items: center; justify-content: center; gap: 10px;
}
.btn-discord:active { box-shadow: 0 1px 0 #3c45c4; }
.auth-note {
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 14px 16px; font-size: 0.87rem; font-weight: 600; color: var(--ink-dim); line-height: 1.55;
}

.btn-library { display: flex; flex-direction: column; align-items: center; gap: 2px; text-transform: none; }
.btn-library-sub { font-size: 0.72rem; font-weight: 600; color: var(--ink-dim); }

.list-odds {
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px 14px; margin-bottom: 14px;
  display: flex; flex-direction: column; gap: 8px;
}
.odds-row { display: flex; align-items: center; gap: 10px; font-size: 0.82rem; font-weight: 700; }
.odds-row .on { flex: 0 0 130px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.odds-row .opct { flex: 0 0 46px; text-align: right; color: var(--brand); font-weight: 800; }
.odds-bar { flex: 1; height: 8px; border-radius: 4px; background: var(--line); overflow: hidden; }
.odds-bar i { display: block; height: 100%; background: var(--grad); border-radius: 4px; }
.odds-note { font-size: 0.72rem; font-weight: 600; color: var(--ink-dim); }

/* Switches */
.switch {
  appearance: none; -webkit-appearance: none;
  width: 40px; height: 23px; border-radius: 99px;
  background: var(--line); cursor: pointer; position: relative; flex-shrink: 0;
  transition: background .2s; outline: none;
}
.switch::after {
  content: ''; position: absolute; top: 3px; left: 3px;
  width: 17px; height: 17px; border-radius: 99px; background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: left .2s;
}
.switch:checked { background: var(--good); }
.switch:checked::after { left: 20px; }

.toggle-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; column-gap: 12px;
  font-weight: 700; font-size: 0.88rem; cursor: pointer;
  padding: 9px 0; min-height: 46px;
}
.toggle-row > span { min-width: 0; }
.toggle-hint { display: block; font-size: 0.74rem; font-weight: 500; color: var(--ink-dim); margin-top: 1px; }

input[type="range"] {
  -webkit-appearance: none; appearance: none; height: 7px; border-radius: 4px;
  background: var(--line); outline: none; cursor: pointer; flex: 1; min-width: 60px;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 19px; height: 19px; border-radius: 50%;
  background: var(--brand); cursor: grab; border: 3px solid var(--card);
  box-shadow: 0 1px 4px rgba(0,0,0,.3);
}
input[type="color"] { width: 46px; height: 34px; border: 2px solid var(--line); border-radius: 9px; background: none; cursor: pointer; padding: 2px; }

/* ── HOME ────────────────────────────────────────────────── */
.hero { text-align: center; padding: 34px 0 26px; }
.hero-title { font-family: 'Fredoka', sans-serif; font-weight: 700; font-size: clamp(2rem, 5vw, 3.3rem); letter-spacing: -1px; }
.hero-grad { background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.hero-sub { color: var(--ink-dim); font-weight: 600; margin-top: 8px; font-size: 1rem; }

.home-grid {
  display: grid; grid-template-columns: 360px 1fr; gap: 18px;
  max-width: 1100px; margin: 0 auto;
}
.rooms-card { grid-column: 1 / -1; }

.identity-row { display: flex; gap: 12px; align-items: center; }
.avatar-bubble {
  width: 56px; height: 56px; border-radius: 18px; font-size: 1.7rem; flex-shrink: 0;
  background: var(--brand-soft); border: 2px dashed var(--brand);
  cursor: pointer; transition: transform .15s;
  display: flex; align-items: center; justify-content: center;
}
.avatar-bubble:hover { transform: scale(1.08) rotate(-4deg); }
.avatar-picker {
  margin-top: 14px; border-top: 1px solid var(--line); padding-top: 12px;
  max-height: 250px; overflow-y: auto; overflow-x: hidden; min-width: 0;
}
.avatar-emojis {
  display: grid;
  /* auto-fill so wide emoji glyphs can never blow the grid past the card */
  grid-template-columns: repeat(auto-fill, minmax(38px, 1fr));
  gap: 4px; margin-bottom: 10px; min-width: 0;
}
.avatar-emojis button {
  font-size: 1.25rem; background: none; border: 2px solid transparent; border-radius: 9px;
  padding: 4px; cursor: pointer; transition: transform .12s;
  overflow: hidden; min-width: 0; line-height: 1.3;
}
.avatar-emojis button:hover { transform: scale(1.2); }
.avatar-emojis button.sel { border-color: var(--brand); background: var(--brand-soft); }
.avatar-colors { display: flex; gap: 6px; flex-wrap: wrap; }
.avatar-colors button {
  width: 26px; height: 26px; border-radius: 99px; border: 2px solid var(--card);
  outline: 2px solid transparent; cursor: pointer; transition: transform .12s;
}
.avatar-colors button:hover { transform: scale(1.15); }
.avatar-colors button.sel { outline-color: var(--ink); }
.home-error { color: var(--bad); font-size: 0.82rem; font-weight: 700; min-height: 18px; margin-top: 8px; }

.play-card { display: flex; flex-direction: column; gap: 14px; justify-content: center; }
.play-split { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.join-combo { display: flex; gap: 8px; }
.input-code { text-transform: uppercase; letter-spacing: 4px; font-family: 'Fredoka', sans-serif; text-align: center; font-weight: 600; }

.rooms-list { display: flex; flex-direction: column; gap: 8px; }
.rooms-empty { color: var(--ink-dim); font-size: 0.85rem; font-weight: 600; text-align: center; padding: 14px; }
.room-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 10px 14px;
}
.room-row .rr-name { font-weight: 800; font-size: 0.9rem; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.room-row .rr-meta { font-size: 0.75rem; color: var(--ink-dim); font-weight: 700; white-space: nowrap; }
.room-row .rr-state { font-size: 0.7rem; font-weight: 800; padding: 3px 9px; border-radius: 99px; background: var(--good-soft); color: var(--good); }
.room-row .rr-state.playing { background: var(--brand-soft); color: var(--brand); }
.home-foot { text-align: center; color: var(--ink-dim); font-size: 0.82rem; font-weight: 600; margin-top: 22px; }

/* ── LOBBY ───────────────────────────────────────────────── */
.lobby-grid { display: grid; grid-template-columns: 360px 1fr; gap: 18px; align-items: start; }
/* Non-hosts have no settings panels, so chat takes the room instead. */
.lobby-grid.guest { grid-template-columns: 320px 1fr; }
/* Both wrappers go transparent so their cards become grid items directly. */
.lobby-grid.guest .lobby-left, .lobby-grid.guest .lobby-right { display: contents; }
.lobby-grid.guest .room-card,
.lobby-grid.guest .players-card-lobby,
.lobby-grid.guest .options-readonly,
.lobby-grid.guest .waiting-msg { grid-column: 1; }
.lobby-grid.guest .chat-card-lobby {
  grid-column: 2; grid-row: 1 / span 5;
  max-height: none; height: calc(100vh - 160px); min-height: 400px;
}
.lobby-left, .lobby-right { display: flex; flex-direction: column; gap: 18px; }

.room-code {
  width: 100%; background: var(--brand-soft); border: 2px dashed var(--brand);
  border-radius: var(--r-md); padding: 14px;
  font-family: 'Fredoka', sans-serif; font-weight: 700; font-size: 2.3rem; letter-spacing: 12px;
  color: var(--brand); text-align: center; cursor: pointer; transition: transform .15s;
}
.room-code:hover { transform: scale(1.02); }
.room-actions { display: flex; gap: 10px; margin-top: 12px; }
.room-actions .btn { flex: 1; }
.autostart-banner {
  margin-top: 12px; background: var(--good-soft); color: var(--good);
  font-weight: 800; font-size: 0.88rem; text-align: center;
  border-radius: var(--r-md); padding: 10px;
}

.lobby-players { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.p-chip {
  display: flex; align-items: center; gap: 8px;
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 8px 10px; font-weight: 700; font-size: 0.85rem;
}
.p-chip.host { border-color: var(--yellow); }
.p-chip.dc { opacity: .45; }
.p-chip .kick { margin-left: auto; background: none; border: none; color: var(--bad); font-weight: 900; cursor: pointer; padding: 0 2px; }
.p-avatar {
  width: 30px; height: 30px; border-radius: 99px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 0.95rem;
}
.p-chip { min-width: 0; }
.p-chip span.nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }

.chat-card-lobby { display: flex; flex-direction: column; max-height: 320px; }
.chat-scroll {
  flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 6px;
  min-height: 110px; padding: 4px 2px; scroll-behavior: smooth;
}
.chat-scroll::-webkit-scrollbar { width: 5px; }
.chat-scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }
.chat-input-row { display: flex; gap: 8px; margin-top: 10px; }
.send-btn {
  width: 44px; border-radius: var(--r-md); border: none; background: var(--brand);
  color: #fff; font-size: 1rem; cursor: pointer; flex-shrink: 0;
  transition: filter .15s, transform .12s;
}
.send-btn:hover { filter: brightness(1.1); transform: translateY(-1px); }

.msg { font-size: 0.85rem; padding: 6px 10px; border-radius: var(--r-sm); background: var(--card-2); line-height: 1.4; overflow-wrap: anywhere; }
.msg .au { font-weight: 800; margin-right: 5px; }
/* System notices read as small status pills rather than italic filler. */
.msg.sys {
  display: flex; align-items: center; gap: 8px; align-self: center;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 99px;
  color: var(--ink-dim); font-style: normal; font-size: 0.78rem; font-weight: 700;
  padding: 5px 12px 5px 6px; max-width: 100%; text-align: left;
}
.msg.sys .sys-icon {
  width: 20px; height: 20px; border-radius: 99px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--card); font-size: 0.78rem;
}
.msg.sys .sys-text { min-width: 0; overflow-wrap: anywhere; }
.msg.sys.sys-in { background: var(--good-soft); border-color: transparent; color: var(--good); }
.msg.sys.sys-out { background: var(--bad-soft); border-color: transparent; color: var(--bad); }
.msg.sys.sys-star { background: var(--brand-soft); border-color: transparent; color: var(--brand-on-soft); }
.msg.sys.sys-warn { background: color-mix(in srgb, var(--yellow) 22%, transparent); border-color: transparent; }
.msg.ok { background: var(--good-soft); color: var(--good); font-weight: 700; text-align: center; }
.msg.close { border-left: 3px solid var(--yellow); }
.msg.whisper { opacity: .75; border-left: 3px solid var(--brand); }

.wl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.wl-item {
  background: var(--card-2); border: 2px solid var(--line); border-radius: var(--r-md);
  padding: 12px 14px; transition: border-color .15s; min-width: 0; overflow: hidden;
}
.wl-rename { background: none; border: none; cursor: pointer; font-size: 0.78rem; opacity: .6; padding: 0 2px; }
.wl-rename:hover { opacity: 1; }
.wl-name-input {
  /* .wl-top is a flex row, so this has to flex — it used to carry a
     grid-column from the old layout and collapsed to nothing. */
  flex: 1 1 auto; width: auto; min-width: 0; box-sizing: border-box;
  background: var(--card); border: 2px solid var(--brand);
  border-radius: 8px; padding: 7px 10px; color: var(--ink); font-family: inherit;
  font-size: 0.9rem; font-weight: 700; outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent);
}
.wl-item.on { border-color: var(--brand); }
/* Three stacked rows — tick + name, then the word count and actions,
   then the weight. Nothing shares a row it has to fight for. */
.wl-top {
  display: flex; align-items: flex-start; gap: 9px;
  cursor: pointer; font-weight: 700; font-size: 0.9rem; min-width: 0;
}
.wl-top .wl-name {
  flex: 1; min-width: 0;
  overflow-wrap: anywhere; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.wl-top input { accent-color: var(--brand); width: 16px; height: 16px; cursor: pointer; flex-shrink: 0; margin-top: 2px; }
.wl-top .wl-badge { flex-shrink: 0; margin-top: 1px; }
.wl-meta {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 7px; min-height: 22px;
}
.wl-meta .cnt { color: var(--ink-dim); font-size: 0.72rem; font-weight: 700; white-space: nowrap; }
.wl-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.wl-actions button {
  background: none; border: none; cursor: pointer; font-size: 0.85rem;
  opacity: .55; padding: 3px 5px; border-radius: 7px; line-height: 1;
  transition: opacity .15s, background .15s;
}
.wl-actions button:hover { opacity: 1; background: var(--card); }
.wl-badge { font-size: 0.6rem; font-weight: 800; background: var(--grad); color: #fff; border-radius: 99px; padding: 2px 7px; letter-spacing: 1px; }
.wl-weight { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 0.72rem; color: var(--ink-dim); font-weight: 700; }
.wl-weight input[type=range] { height: 5px; }
.wl-weight .wv { color: var(--brand); font-weight: 800; min-width: 10px; }
.wl-export { background: none; border: none; cursor: pointer; font-size: 0.8rem; opacity: .6; }
.wl-export:hover { opacity: 1; }

.wl-custom { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.wl-custom-title { font-size: 0.78rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; color: var(--ink-dim); }
.wl-custom-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
/* Share the row rather than forcing a full-width line of its own. */
.wl-custom-row > .input { flex: 1 1 240px; width: auto; min-width: 0; max-width: 460px; }
.wl-mylists { display: flex; gap: 8px; align-items: center; flex: 1; min-width: 200px; }
.wl-mylists select { flex: 1; padding: 8px 12px; }

/* The lobby panels get moved into the in-game settings modal as-is. */
#gamesettings-body { display: flex; flex-direction: column; gap: 16px; }
#gamesettings-body .card { border: none; box-shadow: none; padding: 0; }

.opt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px 24px; margin-bottom: 8px; }
.opt {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px 10px;
  padding: 4px 0;
}
.opt > label {
  grid-column: 1; grid-row: 1;
  display: flex; align-items: center; gap: 6px;
  font-size: 0.78rem; font-weight: 800; color: var(--ink-dim);
  width: auto; min-width: 0;
}
.opt > .opt-val {
  grid-column: 2; grid-row: 1;
  font-weight: 800; color: var(--brand); font-size: 0.85rem;
  min-width: 42px; text-align: right;
}
.opt > input[type="range"] { grid-column: 1 / -1; grid-row: 2; width: 100%; }
.opt > .opt-help { grid-column: 1 / -1; grid-row: 3; }
.opt-toggles {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0 26px; border-top: 1px solid var(--line); margin-top: 10px; padding-top: 6px;
  align-items: start;
}

.ro-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.ro-item { background: var(--card-2); border-radius: var(--r-sm); padding: 8px 12px; font-size: 0.8rem; font-weight: 700; }
.ro-item b { display: block; color: var(--brand); font-size: 0.95rem; }

.btn-start { justify-content: center; text-align: center; display: flex; }
.waiting-msg { text-align: center; color: var(--ink-dim); font-weight: 700; }

/* ── GAME ────────────────────────────────────────────────── */
.game-top {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 20px; margin-bottom: 14px;
  flex-wrap: wrap; /* long words / small screens: wrap instead of overflowing */
}
.round-pill {
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 0.95rem;
  background: var(--brand-soft); color: var(--brand);
  padding: 7px 16px; border-radius: 99px; white-space: nowrap;
}

.word-wrap { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px; min-height: 46px; justify-content: center; min-width: 0; max-width: 100%; }
.word-meta { max-width: 100%; overflow-wrap: anywhere; text-align: center; }
.word-tiles { display: flex; gap: 4px; flex-wrap: wrap; justify-content: center; align-items: flex-end; }
.tile {
  min-width: 26px; height: 34px; border-radius: 7px;
  background: var(--card-2); border: 2px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 1.15rem;
  padding: 0 4px; text-transform: lowercase;
}
.tile.filled { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); animation: tilePop .3s ease; }
.tile.mine { background: var(--good-soft); border-color: var(--good); color: var(--good); }
@keyframes tilePop { 0% { transform: scale(.5); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
.tile-gap { width: 12px; }
.tile-plus { font-weight: 800; color: var(--ink-dim); padding: 0 2px; align-self: center; }
.word-meta { font-size: 0.72rem; font-weight: 700; color: var(--ink-dim); letter-spacing: 1px; min-height: 1em; }

.timer-wrap { position: relative; width: 54px; height: 54px; flex-shrink: 0; }
.timer-ring { width: 54px; height: 54px; transform: rotate(-90deg); }
.timer-ring-bg { fill: none; stroke: var(--line); stroke-width: 5; }
.timer-ring-fg {
  fill: none; stroke: var(--brand); stroke-width: 5; stroke-linecap: round;
  stroke-dasharray: 119.4; stroke-dashoffset: 0; transition: stroke-dashoffset 1s linear, stroke .3s;
}
.timer-wrap.urgent .timer-ring-fg { stroke: var(--bad); }
.timer-wrap.urgent .timer-num { color: var(--bad); animation: pulse .5s infinite alternate; }
@keyframes pulse { from { transform: translate(-50%,-50%) scale(1); } to { transform: translate(-50%,-50%) scale(1.18); } }
.timer-num {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
  font-family: 'Fredoka', sans-serif; font-weight: 700; font-size: 1.05rem;
}

.game-grid {
  display: grid; grid-template-columns: 240px minmax(0, 1fr) 320px; gap: 14px;
  align-items: stretch; /* side panels follow the canvas height */
}

.players-card { padding: 12px; display: flex; flex-direction: column; min-height: 0; }
.players-list { overflow-y: auto; }
.players-list { display: flex; flex-direction: column; gap: 4px; }
.p-row {
  display: flex; align-items: center; gap: 8px; padding: 7px 9px;
  border-radius: var(--r-sm); font-size: 0.84rem; position: relative;
  transition: background .2s;
}
.p-row .rk { font-size: 0.72rem; font-weight: 800; color: var(--ink-dim); width: 16px; text-align: center; }
.p-row { min-width: 0; }
.p-row .nm { font-weight: 700; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.p-row .crown { font-size: 0.8rem; flex-shrink: 0; }
.re-score-row span:first-child, .final-row span:first-child {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: 10px;
}
.podium-e .pn { max-width: 96px; }
.p-row .sc { font-weight: 800; color: var(--brand); font-size: 0.84rem; }
.p-row.drawing { background: var(--brand-soft); }
.p-row.guessed { background: var(--good-soft); }
.p-row.dc { opacity: .4; }
.p-row .flag { font-size: 0.85rem; }
.p-row .bump {
  position: absolute; right: 8px; top: -4px; font-weight: 800; font-size: 0.78rem;
  color: var(--good); animation: bumpUp 1.4s ease forwards; pointer-events: none;
}
@keyframes bumpUp { 0% { opacity: 0; transform: translateY(6px); } 25% { opacity: 1; } 100% { opacity: 0; transform: translateY(-14px); } }

/* Canvas */
.canvas-card { padding: 12px; display: flex; flex-direction: column; gap: 10px; align-items: center; }
.canvas-card .toolbar { width: 100%; justify-content: center; }
.canvas-frame {
  position: relative; width: 100%; aspect-ratio: 4/3; margin: 0 auto;
  max-height: 100%;
  -webkit-touch-callout: none; user-select: none; /* no long-press menus while drawing */
  max-width: var(--canvas-max, 100%); /* set by fitCanvas() to fill the viewport height */
  background: var(--canvas-bg); border-radius: var(--r-md);
  overflow: hidden; border: 1px solid var(--line);
}
#canvas, #canvas-preview { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; }
#canvas-preview { pointer-events: none; }

.canvas-overlay {
  position: absolute; inset: 0; z-index: 10;
  background: color-mix(in srgb, var(--card) 94%, transparent);
  backdrop-filter: blur(3px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center; padding: 20px;
}
.canvas-overlay h2 { font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 1.5rem; }
.canvas-overlay p { color: var(--ink-dim); font-weight: 600; }
.overlay-emoji { font-size: 2.6rem; }
.wiggle { animation: wig 1.2s ease-in-out infinite; }
@keyframes wig { 0%,100% { transform: rotate(-8deg); } 50% { transform: rotate(8deg); } }

.word-choice-grid {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center;
  margin-top: 6px; max-height: 62%; overflow-y: auto; padding: 4px 8px;
  align-content: flex-start;
}
/* Lots of options: shrink the buttons rather than spill off the canvas. */
.word-choice-grid.many .word-choice { padding: 8px 14px; font-size: 0.9rem; }
.word-choice-grid.lots .word-choice { padding: 6px 11px; font-size: 0.82rem; border-radius: 10px; }
.word-choice {
  background: var(--card); border: 2px solid var(--line); border-radius: var(--r-md);
  padding: 14px 24px; font-weight: 800; font-size: 1.05rem; cursor: pointer;
  transition: all .15s; box-shadow: var(--shadow-sm);
}
.word-choice:hover:not(:disabled) { border-color: var(--brand); background: var(--brand-soft); transform: translateY(-3px) scale(1.04); }
.word-choice:disabled { opacity: .5; cursor: default; }

.float-btn {
  position: relative;
  background: color-mix(in srgb, var(--card) 90%, transparent); border: 1px solid var(--line);
  border-radius: 12px; padding: 7px 11px; cursor: pointer; font-size: 0.95rem; font-weight: 800;
  box-shadow: var(--shadow-sm); transition: transform .15s;
  display: flex; align-items: center; gap: 5px;
}
.float-btn:hover { transform: scale(1.1); }
.float-btn.used { opacity: .5; pointer-events: none; }
.float-fullscreen { position: absolute; top: 10px; right: 10px; z-index: 12; }
.float-actions { position: absolute; bottom: 10px; right: 10px; z-index: 12; display: flex; gap: 8px; }

/* Toolbar */
.toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tool-group { display: flex; gap: 4px; }
.tool-btn {
  width: 38px; height: 38px; border-radius: 11px; border: 2px solid transparent;
  background: var(--card-2); cursor: pointer; font-size: 1.02rem;
  display: flex; align-items: center; justify-content: center;
  transition: all .12s; font-weight: 700;
}
.tool-btn:hover { transform: translateY(-2px); }
.tool-btn.active { border-color: var(--brand); background: var(--brand-soft); }
.tool-sep { width: 1px; height: 28px; background: var(--line); }

.size-dots { display: flex; gap: 5px; align-items: center; }
.size-dot {
  border-radius: 99px; background: var(--card-2); border: 2px solid transparent;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; transition: all .12s;
}
.size-dot:hover { transform: scale(1.1); }
.size-dot.active { border-color: var(--brand); background: var(--brand-soft); }
.size-dot i { border-radius: 99px; background: var(--ink); display: block; }

.palette { display: grid; grid-template-columns: repeat(14, 22px); gap: 4px; }
.palette .swatch { width: 22px; height: 22px; }
.swatch {
  width: 24px; height: 24px; border-radius: 8px; cursor: pointer;
  border: 2px solid rgba(0,0,0,.08); transition: transform .12s;
}
.swatch:hover { transform: scale(1.22); }
.swatch.active { outline: 3px solid var(--brand); outline-offset: 1px; }
.swatch.rainbow { background: conic-gradient(red, yellow, lime, cyan, blue, magenta, red); }

/* Chat card */
.chat-card { display: flex; flex-direction: column; height: auto; min-height: 420px; padding: 14px; }
.chat-card .chat-scroll { min-height: 0; }
.chat-head .chat-close { display: none; }
.chat-card .chat-scroll { flex: 1; }
.float-chat-toggle { display: none; position: fixed; bottom: 18px; right: 18px; z-index: 60; font-size: 1.3rem; padding: 12px 14px; }
.chat-badge {
  position: absolute; top: -5px; right: -5px; background: var(--pink); color: #fff;
  font-size: 0.65rem; font-weight: 800; border-radius: 99px; padding: 2px 6px;
}

/* ── Fullscreen / focus drawing mode ────────────────────── */
/* Fullscreen is the whole game at full size, not the canvas on its own.
   A 4:3 canvas on a 16:9 screen leaves room either side, so the players and
   the chat keep that space rather than the layout wasting it. */
body.focus-mode { overflow: hidden; }
body.focus-mode .topbar { display: none; }
body.focus-mode #screen-game {
  position: fixed; inset: 0; z-index: 200;
  background-color: var(--bg);
  background-image: radial-gradient(var(--dot) 1.2px, transparent 1.2px);
  background-size: 22px 22px;
  padding: 10px; display: flex; flex-direction: column; gap: 10px;
}
body.focus-mode #screen-game .game-top { margin: 0; flex-shrink: 0; }
body.focus-mode .game-grid { flex: 1; min-height: 0; align-items: stretch; }
body.focus-mode .players-card,
body.focus-mode .chat-card,
body.focus-mode .canvas-card { min-height: 0; }
body.focus-mode .canvas-card { display: flex; flex-direction: column; align-items: center; }
body.focus-mode .canvas-frame {
  width: auto; height: auto; flex: 1; aspect-ratio: 4/3;
  max-width: 100%; max-height: 100%; margin: 0 auto; align-self: center;
}
body.focus-mode .toolbar { justify-content: center; }
/* Chat is a normal column again, so the drawer and its toggle stand down. */
body.focus-mode .chat-card { position: static; transform: none; width: auto; height: auto; box-shadow: var(--shadow-sm); }
body.focus-mode .chat-head .chat-close { display: none; }
body.focus-mode .float-chat-toggle { display: none; }

/* The drawing surface's paper pattern sits under the strokes. */
#canvas { background-color: var(--canvas-bg); }

/* On a narrow screen there is no spare width, so chat becomes a drawer again. */
@media (max-width: 900px) {
  body.focus-mode .game-grid { display: flex; flex-direction: column; }
  body.focus-mode .chat-card {
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 220;
    width: min(340px, 90vw); height: 100%; border-radius: 0;
    transform: translateX(105%); transition: transform .25s ease;
    box-shadow: -10px 0 30px rgba(0,0,0,.2);
  }
  body.focus-mode .chat-card.open { transform: none; }
  body.focus-mode .chat-head .chat-close { display: block; }
  body.focus-mode .float-chat-toggle { display: flex; }
}

/* ── Modals ──────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(20, 21, 39, .55); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 18px;
  animation: fadeIn .2s ease;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.modal {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow);
  padding: 28px; width: 100%; max-width: 560px; position: relative;
  max-height: 92vh; overflow-y: auto;
  animation: modalIn .25s ease;
}
@keyframes modalIn { from { opacity: 0; transform: translateY(16px) scale(.97); } to { opacity: 1; transform: none; } }
.modal h2 { font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 1.4rem; margin-bottom: 4px; }
.modal-sub { color: var(--ink-dim); font-size: 0.85rem; font-weight: 600; margin-bottom: 16px; }
.modal-sm { max-width: 400px; }
.modal-lg { max-width: 680px; }
.modal-x {
  position: absolute; top: 14px; right: 14px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 99px;
  width: 32px; height: 32px; cursor: pointer; font-weight: 800; color: var(--ink-dim);
}
.modal-x:hover { color: var(--bad); }
.form { display: flex; flex-direction: column; gap: 12px; }
.form-error { color: var(--bad); font-size: 0.82rem; font-weight: 700; min-height: 18px; }

.set-row { display: flex; flex-direction: column; gap: 6px; }
.set-row > label { font-size: 0.76rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; color: var(--ink-dim); }
.set-inline { display: flex; align-items: center; gap: 12px; }
.seg { display: flex; background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md); padding: 4px; gap: 4px; }
.seg-btn { flex: 1; border: none; background: none; padding: 8px; border-radius: 10px; font-weight: 800; font-size: 0.85rem; cursor: pointer; color: var(--ink-dim); }
.seg-btn.active { background: var(--card); color: var(--ink); box-shadow: var(--shadow-sm); }

/* Account modal */
.acct-head { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; }
.acct-avatar { width: 54px; height: 54px; border-radius: 18px; background: var(--brand-soft); display: flex; align-items: center; justify-content: center; font-size: 1.7rem; }
.acct-signout { margin-left: auto; }
.tabs { display: flex; gap: 6px; border-bottom: 2px solid var(--line); margin-bottom: 18px; }
.tab {
  background: none; border: none; padding: 10px 16px; font-weight: 800; font-size: 0.9rem;
  color: var(--ink-dim); cursor: pointer; border-bottom: 3px solid transparent; margin-bottom: -2px;
}
.tab.active { color: var(--brand); border-bottom-color: var(--brand); }
.tab-pane { display: none; }
.tab-pane.active { display: block; }

.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; margin-bottom: 16px; }
.stat-tile { background: var(--card-2); border-radius: var(--r-md); padding: 12px 14px; }
.stat-tile b { display: block; font-family: 'Fredoka', sans-serif; font-size: 1.4rem; color: var(--brand); }
.stat-tile span { font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; color: var(--ink-dim); }

.lists-toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 14px; flex-wrap: wrap; }
.lists-note { font-size: 0.75rem; color: var(--ink-dim); font-weight: 700; margin-left: auto; }
.wl-remove { background: none; border: none; cursor: pointer; font-size: 0.78rem; opacity: .55; padding: 0 2px; }
.wl-remove:hover { opacity: 1; }
.lists-rows { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.list-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 10px 14px;
}
.list-row .ln { font-weight: 800; font-size: 0.9rem; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-row .lc { font-size: 0.75rem; color: var(--ink-dim); font-weight: 700; white-space: nowrap; }
.list-row button { background: none; border: none; cursor: pointer; font-size: 0.95rem; opacity: .65; transition: opacity .15s, transform .15s; }
.list-row button:hover { opacity: 1; transform: scale(1.15); }
.list-editor { border-top: 1px solid var(--line); padding-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.le-row { display: flex; align-items: center; gap: 10px; }
.le-count { font-size: 0.78rem; font-weight: 700; color: var(--ink-dim); margin-right: auto; }

.gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.g-item { background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.g-item img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; background: #fff; }
.g-info { padding: 8px 10px; }
.g-word { font-weight: 800; font-size: 0.82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-meta { font-size: 0.68rem; color: var(--ink-dim); font-weight: 700; display: flex; justify-content: space-between; margin-top: 2px; }
.g-actions { display: flex; gap: 4px; padding: 0 8px 8px; }
.g-actions button { flex: 1; background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 4px; cursor: pointer; font-size: 0.78rem; }
.g-actions button:hover { border-color: var(--brand); }
.gallery-empty { color: var(--ink-dim); font-weight: 600; font-size: 0.85rem; text-align: center; padding: 18px; }

/* Round end */
.round-end { max-width: min(1100px, 94vw); width: 100%; text-align: center; }
.re-word { font-family: 'Fredoka', sans-serif; font-size: 1.25rem; color: var(--brand); margin-bottom: 14px; }
.re-word small { color: var(--ink-dim); font-size: 0.75rem; display: block; font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 700; }
.re-body { display: flex; gap: 20px; align-items: stretch; text-align: left; }
.re-image {
  flex: 1 1 60%; min-width: 0; align-self: flex-start;
  max-height: min(62vh, 620px); object-fit: contain;
  border-radius: var(--r-md); border: 1px solid var(--line); background: #fff;
}
.re-side { flex: 1 1 34%; min-width: 240px; display: flex; flex-direction: column; gap: 10px; }
.re-stats { font-size: 0.82rem; font-weight: 700; color: var(--ink-dim); }
.re-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.re-scores { display: flex; flex-direction: column; gap: 5px; max-height: min(42vh, 380px); overflow-y: auto; }
.re-score-row {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--card-2); border-radius: var(--r-sm); padding: 7px 12px; font-size: 0.84rem;
}
.re-score-row .d { font-weight: 800; color: var(--good); }
.re-score-row .d.zero { color: var(--ink-dim); }
.re-score-row .t { font-weight: 800; color: var(--brand); }

/* Game end */
.game-end { max-width: 520px; text-align: center; }
.podium { display: flex; gap: 14px; justify-content: center; align-items: flex-end; margin: 22px 0; }
.podium-e { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.podium-e .medal { font-size: 2rem; }
.podium-e .pn { font-weight: 800; font-size: 0.85rem; max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.podium-e .pp { font-weight: 800; color: var(--brand); font-size: 0.8rem; }
.podium-e .bar { width: 66px; border-radius: 10px 10px 0 0; background: var(--grad); opacity: .85; }
.final-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.final-row { display: flex; justify-content: space-between; background: var(--card-2); border-radius: var(--r-sm); padding: 9px 14px; font-size: 0.88rem; font-weight: 700; }
.final-row .pts { color: var(--brand); font-weight: 800; }
.ge-countdown { color: var(--ink-dim); font-size: 0.82rem; font-weight: 700; margin-bottom: 10px; }

/* Toast + confetti */
.toast {
  position: fixed; bottom: 26px; left: 50%;
  transform: translateX(-50%) translateY(90px);
  background: var(--ink); color: var(--bg);
  border-radius: 99px; padding: 12px 24px;
  font-weight: 700; font-size: 0.9rem; z-index: 500;
  transition: transform .3s cubic-bezier(.2,1.4,.4,1); pointer-events: none;
  box-shadow: var(--shadow);
}
.toast.show { transform: translateX(-50%) translateY(0); }
#confetti { position: fixed; inset: 0; z-index: 400; pointer-events: none; }

/* ── Option help, text tool, friends, invite toast, format tips ── */
.opt-help-btn {
  width: 20px; height: 20px; border-radius: 99px; border: 1px solid var(--line);
  background: var(--card-2); color: var(--ink-dim); font-size: 0.7rem; font-weight: 800;
  cursor: pointer; flex-shrink: 0; margin-left: 4px; line-height: 1;
}
.opt-help-btn:hover, .opt-help-btn.on { color: var(--brand); border-color: var(--brand); }

.opt-help, .toggle-help {
  flex-basis: 100%; font-size: 0.76rem; color: var(--ink-dim); font-weight: 600;
  background: var(--card-2); border-left: 3px solid var(--brand); border-radius: 0 8px 8px 0;
  padding: 7px 10px; margin-top: 4px; line-height: 1.45;
}
.toggle-row .opt-help-btn { margin-left: 0; }
/* the help text drops onto its own full-width row underneath */
.toggle-row .toggle-help { grid-column: 1 / -1; }
.toggle-row.dim { opacity: .45; }
.toggle-row.dim .switch { cursor: not-allowed; }

.tool-text { font-family: 'Fredoka', sans-serif; font-weight: 700; font-size: 1.1rem; }
.text-tool-input {
  position: absolute; z-index: 9; transform: translateY(-50%);
  background: rgba(255,255,255,.85); border: 2px dashed var(--brand); border-radius: 6px;
  padding: 2px 6px; font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 800; outline: none;
  min-width: 120px; max-width: 60%;
}

.p-row .addf {
  background: var(--card-2); border: 1px solid var(--line); border-radius: 99px;
  width: 22px; height: 22px; font-size: 0.8rem; font-weight: 800; cursor: pointer; color: var(--ink-dim);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.p-row .addf:hover { color: var(--brand); border-color: var(--brand); }
.btn-wide { width: 100%; margin-top: 10px; }
.friend-code-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.friend-code-label { font-weight: 800; font-size: 0.9rem; }
.friend-code {
  font-family: 'Fredoka', sans-serif; font-weight: 700; font-size: 1.4rem; letter-spacing: 5px;
  background: var(--brand-soft); color: var(--brand); border: 2px dashed var(--brand); border-radius: var(--r-md);
  padding: 8px 16px; cursor: pointer;
}
.friend-row .dot { width: 10px; height: 10px; border-radius: 99px; background: var(--line); flex-shrink: 0; }
.friend-row .dot.on { background: var(--good); box-shadow: 0 0 0 3px var(--good-soft); }
.friend-req { background: var(--brand-soft); border-radius: var(--r-md); padding: 10px 14px; display: flex; align-items: center; gap: 10px; margin-bottom: 8px; font-size: 0.86rem; font-weight: 700; }
.friend-req .btn { margin-left: auto; }

.invite-toast {
  position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%);
  background: var(--card); border: 2px solid var(--brand); border-radius: 16px;
  padding: 12px 14px 12px 18px; display: flex; align-items: center; gap: 12px;
  font-weight: 700; font-size: 0.9rem; z-index: 501; box-shadow: var(--shadow);
  animation: modalIn .25s ease; max-width: 92vw;
}

.format-tip { font-size: 0.8rem; }
.format-tip summary { cursor: pointer; font-weight: 800; color: var(--brand); list-style: none; }
.format-tip summary::before { content: '▸ '; }
.format-tip[open] summary::before { content: '▾ '; }
.format-tip-body { margin-top: 8px; color: var(--ink-dim); font-weight: 600; line-height: 1.5; }
.format-tip-body pre {
  background: var(--card-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 12px; margin: 8px 0; font-size: 0.8rem; color: var(--ink);
}

.btn-leave {
  background: var(--bad); box-shadow: 0 4px 0 color-mix(in srgb, var(--bad) 70%, #000);
}
.btn-leave:active { box-shadow: 0 1px 0 color-mix(in srgb, var(--bad) 70%, #000); }
.topbar-actions .btn-leave { padding: 8px 14px; font-size: 0.8rem; }

.gif-progress {
  display: flex; align-items: center; gap: 10px;
  font-size: 0.8rem; font-weight: 700; color: var(--ink-dim);
}
.gif-bar { flex: 1; height: 7px; border-radius: 4px; background: var(--line); overflow: hidden; }
.gif-bar i { display: block; height: 100%; width: 0; background: var(--grad); transition: width .2s; }

/* Text tool: the input is styled to look exactly like the text it will draw. */
.text-tool-input {
  background: transparent; border: none; border-bottom: 2px dashed var(--brand);
  border-radius: 0; padding: 0 2px; box-shadow: 0 0 0 6px rgba(255, 255, 255, .55);
}
.text-tool-input::placeholder { color: rgba(120, 120, 140, .55); font-weight: 600; }

/* Brand-coloured text sitting on --brand-soft, per theme. */
.room-pill-code, .room-code, .round-pill, .tile.filled, .friend-code { color: var(--brand-on-soft); }

.opt-extra { display: flex; align-items: center; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
.opt-extra > label { font-size: 0.78rem; font-weight: 800; color: var(--ink-dim); width: 88px; flex-shrink: 0; }
.opt-extra select { width: auto; min-width: 150px; padding: 8px 12px; }
.opt-extra .toggle-help { flex-basis: 100%; }

.ge-actions { display: flex; flex-direction: column; gap: 10px; align-items: center; margin-bottom: 12px; }
.ge-actions .gif-progress { width: 100%; }

.scene-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; }
.scene-card {
  background: var(--card-2); border: 2px solid var(--line); border-radius: var(--r-md);
  padding: 6px; cursor: pointer; transition: transform .12s, border-color .15s;
  display: flex; flex-direction: column; gap: 6px; min-width: 0;
}
.scene-card:hover { transform: translateY(-3px); border-color: var(--brand); }
.scene-card.active { border-color: var(--brand); background: var(--brand-soft); }
.scene-card canvas { width: 100%; aspect-ratio: 4/3; border-radius: 8px; display: block; background: #fff; }
.scene-card .sn {
  font-size: 0.76rem; font-weight: 800; text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.name-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 6px; flex-wrap: wrap; }
.name-label { font-weight: 800; font-size: 0.9rem; }
.name-edit { display: flex; gap: 8px; align-items: center; }
.name-edit .input { width: 190px; }

.mod-row .badge {
  font-size: 0.62rem; font-weight: 800; letter-spacing: 1px; border-radius: 99px;
  padding: 3px 8px; flex-shrink: 0;
}
.mod-row .badge.mod { background: var(--brand-soft); color: var(--brand-on-soft); }
.mod-row .badge.boot { background: color-mix(in srgb, var(--yellow) 26%, transparent); color: var(--ink); }
.mod-row .badge.banned { background: var(--bad-soft); color: var(--bad); }
.mod-note { font-size: 0.75rem; color: var(--ink-dim); font-weight: 600; margin-top: 10px; line-height: 1.5; }

.activity-note {
  margin-top: 12px; background: var(--brand-soft); color: var(--brand-on-soft);
  font-weight: 700; font-size: 0.82rem; text-align: center;
  border-radius: var(--r-md); padding: 9px 12px;
}

.emoji-picker {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(46px, 1fr));
  gap: 4px; max-height: 46vh; overflow-y: auto; margin-top: 12px;
}
.emoji-picker button {
  font-size: 1.5rem; line-height: 1; background: none; border: 2px solid transparent;
  border-radius: 10px; padding: 6px 2px; cursor: pointer; transition: transform .1s, background .15s;
}
.emoji-picker button:hover { transform: scale(1.18); background: var(--card-2); }
.emoji-picker button.sel { border-color: var(--brand); background: var(--brand-soft); }
.emoji-group-label {
  grid-column: 1 / -1; font-size: 0.7rem; font-weight: 800; letter-spacing: 1px;
  text-transform: uppercase; color: var(--ink-dim); padding: 8px 2px 2px;
}
.tool-btn.emoji-armed { border-color: var(--brand); background: var(--brand-soft); }

/* Settings groups */
.set-group {
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 14px 16px; margin-bottom: 12px;
}
.set-group-title {
  font-size: 0.72rem; font-weight: 800; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--ink-dim); margin-bottom: 12px;
}
.set-group .set-row { margin-bottom: 12px; }
.set-group .set-row:last-child { margin-bottom: 0; }
.set-row-inline { flex-direction: row; align-items: center; justify-content: space-between; gap: 14px; }
.set-row-inline > label { margin-bottom: 0; white-space: nowrap; }
.set-row-inline .set-inline { flex: 1; max-width: 240px; }
.set-toggle { display: flex; align-items: center; gap: 12px; cursor: pointer; padding: 6px 0; font-weight: 700; font-size: 0.88rem; }
.set-toggle-text { min-width: 0; }
.set-slider-row { display: flex; align-items: center; gap: 10px; padding: 2px 0 10px 52px; }
.set-slider-icon { font-size: 0.9rem; opacity: .7; }
.set-slider-row .opt-val { min-width: 42px; }

/* "Pens down" — the big lock that lands when someone gets the word. */
.lock-flash {
  position: absolute; inset: 0; z-index: 14;
  display: none; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; pointer-events: none;
  background: color-mix(in srgb, var(--card) 40%, transparent);
  backdrop-filter: blur(1.5px);
}
.lock-flash.show { display: flex; animation: lockFade 2.4s ease forwards; }
.lock-emoji { font-size: 5.5rem; animation: lockDrop .55s cubic-bezier(.2, 1.5, .4, 1); filter: drop-shadow(0 8px 18px rgba(0,0,0,.35)); }
.lock-text {
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 1.5rem;
  color: var(--ink); background: var(--card); border: 2px solid var(--brand);
  border-radius: 99px; padding: 6px 20px; box-shadow: var(--shadow);
}
@keyframes lockDrop {
  0% { transform: translateY(-60px) scale(.4) rotate(-18deg); opacity: 0; }
  70% { transform: translateY(0) scale(1.12) rotate(4deg); opacity: 1; }
  100% { transform: translateY(0) scale(1) rotate(0); opacity: 1; }
}
@keyframes lockFade { 0%, 72% { opacity: 1; } 100% { opacity: 0; } }
/* While frozen, the canvas says so. */
.canvas-frame.locked { outline: 3px solid var(--brand); outline-offset: -3px; }
.canvas-frame.locked #canvas { cursor: not-allowed; }

.dialog-backdrop { z-index: 600; }   /* above every other modal */
.dialog-card { max-width: 380px; }
.dialog-title { margin-bottom: 6px; }
.dialog-message { color: var(--ink-dim); font-weight: 600; font-size: 0.9rem; line-height: 1.5; margin-bottom: 14px; }
.dialog-input { margin-bottom: 14px; }
.dialog-actions { display: flex; gap: 10px; justify-content: flex-end; }
.btn-danger-solid { background: var(--bad); box-shadow: 0 4px 0 color-mix(in srgb, var(--bad) 70%, #000); }
.btn-danger-solid:active { box-shadow: 0 1px 0 color-mix(in srgb, var(--bad) 70%, #000); }

/* Player count — a quiet pill with a live dot beside the round number. */
.count-pill {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 99px;
  padding: 6px 13px 6px 10px; font-weight: 800; font-size: 0.85rem;
  color: var(--ink-dim); white-space: nowrap; flex-shrink: 0;
}
.count-pill .count-dot {
  width: 8px; height: 8px; border-radius: 99px; background: var(--good);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 22%, transparent);
}
.count-pill b { color: var(--ink); }
.lobby-count-live { display: inline-flex; align-items: center; gap: 6px; }

/* Real profile pictures sit in the same circles the emoji avatars use. */
.p-avatar img, .account-chip-avatar img, .acct-avatar img, .p-chip .p-avatar img {
  width: 100%; height: 100%; border-radius: 99px; object-fit: cover; display: block;
}
.p-avatar.has-photo, .account-chip-avatar.has-photo { padding: 0; overflow: hidden; background: none; }
.acct-avatar.has-photo { padding: 0; overflow: hidden; background: none; border-radius: 18px; }
.acct-avatar.has-photo img { border-radius: 18px; }

.home-legal { text-align: center; margin-top: 10px; font-size: 0.76rem; font-weight: 700; }
.home-legal a { color: var(--ink-dim); text-decoration: none; }
.home-legal a:hover { color: var(--brand); text-decoration: underline; }
.home-legal span { color: var(--line); margin: 0 8px; }

/* ── Inside a Discord Activity ───────────────────────────────
   The frame is small and already has Discord's own chrome around
   it, so the page trims itself down to the game. */
body.in-activity .topbar { padding: 6px 12px; }
body.in-activity .brand-text { display: none; }
body.in-activity .brand-mark svg { width: 34px; height: 34px; }
body.in-activity #main { padding-top: 10px; }
body.in-activity .hero { padding: 18px 0 14px; }
body.in-activity .home-foot { display: none; }
body.in-activity #account-chip-name { display: none; }
body.in-activity .account-chip { padding: 4px 6px; }
/* Discord already gives people a way out of the activity. */
body.in-activity .btn-hero-sub { font-size: 0.74rem; }

/* A quiet line above the play buttons: how busy the game is right now. */
.online-strip {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 10px; font-size: 0.85rem; font-weight: 700; color: var(--ink-dim);
}
.online-strip b { color: var(--ink); font-weight: 800; }
.online-strip .count-dot { animation: livePulse 2.4s ease-in-out infinite; }
.online-strip.quiet { opacity: .75; }
.online-strip.quiet .count-dot { background: var(--ink-dim); box-shadow: none; animation: none; }
@keyframes livePulse {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 22%, transparent); }
  50%      { box-shadow: 0 0 0 6px color-mix(in srgb, var(--good) 6%, transparent); }
}

/* Rendered policy / terms, both in the modal and on the standalone pages. */
.legal-doc { font-size: 0.92rem; line-height: 1.65; color: var(--ink); }
.legal-doc h1 { font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 1.5rem; margin-bottom: 4px; }
.legal-doc h2 { font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 1.12rem; margin: 22px 0 8px; }
.legal-doc h3 { font-weight: 800; font-size: 0.96rem; margin: 16px 0 6px; }
.legal-doc p { margin-bottom: 12px; }
.legal-doc ul, .legal-doc ol { margin: 0 0 12px 22px; }
.legal-doc li { margin-bottom: 6px; }
.legal-doc a { color: var(--brand-on-soft); }
.legal-doc code {
  background: var(--card-2); border: 1px solid var(--line); border-radius: 6px;
  padding: 1px 5px; font-size: 0.86em;
}
.legal-doc hr { border: none; border-top: 1px solid var(--line); margin: 22px 0; }
.legal-doc blockquote {
  background: var(--card-2); border-left: 3px solid var(--yellow);
  border-radius: 0 10px 10px 0; padding: 12px 16px; margin: 0 0 16px;
  font-size: 0.88rem; color: var(--ink-dim);
}
.legal-doc blockquote p:last-child { margin-bottom: 0; }
#modal-legal .legal-doc { max-height: 68vh; overflow-y: auto; padding-right: 6px; }

.legal-page { max-width: 780px; margin: 0 auto; padding: 32px 20px 60px; }
.legal-back { display: inline-block; margin-bottom: 18px; color: var(--ink-dim); font-weight: 700; font-size: 0.85rem; text-decoration: none; }
.legal-back:hover { color: var(--brand); }
.legal-foot { margin-top: 28px; font-size: 0.85rem; font-weight: 700; }
.legal-foot a { color: var(--ink-dim); }

/* The channel-game button on the activity's home screen — prominent, but
   not competing with the main Play button. */
.btn-hero-lite {
  background: var(--grad);
  box-shadow: 0 5px 0 #4c3fd1, 0 10px 22px rgba(108, 92, 231, .28);
  font-size: 1rem; padding: 15px 22px;
}
.btn-hero-lite:active { box-shadow: 0 2px 0 #4c3fd1; }

/* Theme picker (settings) */
.theme-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; }
.theme-chip {
  display: flex; align-items: center; gap: 8px;
  background: var(--card-2); border: 2px solid var(--line); border-radius: var(--r-md);
  padding: 8px 10px; cursor: pointer; font-weight: 700; font-size: 0.82rem;
  transition: border-color .15s, transform .12s;
}
.theme-chip:hover { transform: translateY(-2px); border-color: var(--brand); }
.theme-chip.active { border-color: var(--brand); background: var(--brand-soft); color: var(--brand-on-soft); }
.theme-dot {
  width: 20px; height: 20px; border-radius: 99px; flex-shrink: 0;
  border: 1px solid rgba(128, 128, 128, .35);
}

/* ── Responsive ──────────────────────────────────────────── */
@media (max-width: 1080px) {
  .game-grid { grid-template-columns: minmax(0, 1fr) 300px; }
  .players-card { grid-column: 1 / -1; order: 3; padding: 10px; }
  .players-list { flex-direction: row; flex-wrap: wrap; gap: 6px; }
  .p-row { min-width: 150px; }
}
@media (max-width: 900px) {
  .home-grid { grid-template-columns: 1fr; }
  .lobby-grid { grid-template-columns: 1fr; }
  .play-split { grid-template-columns: 1fr; }
  .opt-grid { grid-template-columns: 1fr; }
  .opt-toggles { grid-template-columns: 1fr; }
}

/* ── Phones ──────────────────────────────────────────────── */
@media (max-width: 760px) {
  html { font-size: 15px; }
  #main { padding: 10px 8px 24px; }
  .topbar { padding: 6px 10px; gap: 8px; }
  .brand-text { display: none; }
  .brand-mark svg { width: 36px; height: 36px; }
  .icon-btn { width: 34px; height: 34px; border-radius: 10px; }
  #account-chip-name { display: none; }
  .account-chip { padding: 4px 6px; }
  .room-pill { padding: 4px 4px 4px 10px; }
  .room-pill-code { font-size: 0.9rem; letter-spacing: 3px; }

  /* Home */
  .hero { padding: 14px 0 12px; }
  .hero-title { font-size: 1.9rem; }
  .hero-sub { font-size: 0.88rem; }
  .card { padding: 14px; border-radius: 16px; }
  .btn-hero { padding: 14px 16px; }
  .home-foot { font-size: 0.75rem; }
  .avatar-emojis { grid-template-columns: repeat(auto-fill, minmax(34px, 1fr)); }

  /* Lobby */
  .room-code { font-size: 1.8rem; letter-spacing: 8px; padding: 10px; }
  .lobby-players { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  .wl-grid { grid-template-columns: 1fr 1fr; }
  .chat-card-lobby { max-height: 260px; }

  /* Game: canvas first, then a scrolling player strip, then chat */
  .game-top { padding: 8px 10px; gap: 8px; margin-bottom: 8px; }
  .round-pill { font-size: 0.78rem; padding: 5px 10px; }
  .tile { min-width: 20px; height: 28px; font-size: 0.95rem; border-radius: 6px; padding: 0 3px; }
  .word-tiles { gap: 3px; }
  .word-meta { font-size: 0.66rem; }
  .timer-wrap, .timer-ring { width: 44px; height: 44px; }
  .timer-num { font-size: 0.9rem; }

  body.in-game #main { height: auto; padding: 8px 8px 20px; }
  body.in-game #screen-game.active { display: block; }
  .game-grid { display: flex; flex-direction: column; gap: 8px; }
  .wl-grid { grid-template-columns: 1fr; }
  .set-slider-row { padding-left: 0; }
  .canvas-card { order: 1; padding: 6px; border-radius: 14px; }
  .canvas-frame { border-radius: 10px; }
  .players-card { order: 2; padding: 6px 8px; }
  .players-card .card-title-row { display: none; }
  .players-list { display: flex; flex-direction: row; flex-wrap: nowrap; overflow-x: auto; gap: 6px; padding-bottom: 2px; scrollbar-width: none; }
  .players-list::-webkit-scrollbar { display: none; }
  .p-row { flex: 0 0 auto; min-width: 0; padding: 5px 9px; gap: 5px; font-size: 0.78rem; background: var(--card-2); }
  .p-row .rk { display: none; }
  .p-row .nm { max-width: 72px; }
  .chat-card { order: 3; min-height: 0; height: 38vh; padding: 10px; }
  .chat-card .card-title-row { margin-bottom: 6px; }
  .msg { font-size: 0.82rem; padding: 5px 8px; }
  .chat-input-row input, .input { font-size: 16px; } /* keeps iOS from zooming into inputs */
  .send-btn { width: 48px; }

  /* Toolbar: chunky touch targets */
  .toolbar { gap: 8px; }
  .tool-btn { width: 40px; height: 40px; }
  .tool-group { flex-wrap: wrap; }
  .size-dot { width: 32px; height: 32px; }
  .palette { grid-template-columns: repeat(auto-fill, minmax(26px, 1fr)); width: 100%; }
  .palette .swatch { width: 100%; height: auto; aspect-ratio: 1; }
  .tool-sep { display: none; }

  .float-btn { padding: 8px 12px; font-size: 1rem; }
  .canvas-overlay h2 { font-size: 1.15rem; }
  .canvas-overlay p { font-size: 0.85rem; }
  .overlay-emoji { font-size: 2rem; }
  .word-choice { padding: 10px 14px; font-size: 0.95rem; }

  /* Focus mode on a phone */
  body.focus-mode #screen-game { padding: 6px; }
  body.focus-mode #screen-game .game-top { padding: 6px 10px; }
  body.focus-mode .chat-card { width: 100vw; height: 100dvh; }

  /* Modals become bottom sheets */
  .modal-backdrop { align-items: flex-end; padding: 0; }
  .modal { max-width: 100%; max-height: 92dvh; border-radius: 20px 20px 0 0; padding: 22px 16px 28px; }
  .modal-lg, .modal-sm { max-width: 100%; }
  .re-body { flex-direction: column; }
  .re-image { width: 100%; }
  .podium-e .bar { width: 52px; }
  .tabs { overflow-x: auto; }
  .tab { padding: 10px 12px; white-space: nowrap; }
  .stats-grid { grid-template-columns: repeat(3, 1fr); }
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
  .toast, .invite-toast { bottom: 14px; max-width: 94vw; }
  .invite-toast { flex-wrap: wrap; justify-content: center; }
}
@media (max-width: 420px) {
  .hero-title { font-size: 1.6rem; }
  .wl-grid { grid-template-columns: 1fr; }
  .lobby-players { grid-template-columns: 1fr 1fr; }
  .home-grid { gap: 10px; }
  .play-split { gap: 8px; }
}

/* ══════════ Batch 18 ══════════ */

/* ── Word lists: roomier cards, calmer weight row ── */
.wl-grid { grid-template-columns: repeat(auto-fill, minmax(228px, 1fr)); gap: 12px; }
.wl-item { padding: 13px 15px 12px; }
.wl-weight {
  margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--line);
  gap: 9px;
}
.wl-weight-label { flex-shrink: 0; text-transform: uppercase; letter-spacing: .6px; font-size: 0.66rem; }
.wl-weight input[type=range] { flex: 1; min-width: 0; }
.wl-weight .wv { min-width: 14px; text-align: right; }
.wl-item.on .wl-weight-label { color: var(--brand); }

/* ── Grouped game options ── */
.opt-section { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.opt-section:first-of-type { margin-top: 12px; padding-top: 0; border-top: none; }
.opt-section-title {
  font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1.1px;
  color: var(--ink-dim); margin-bottom: 11px;
}
.opt-section .opt-toggles { margin-top: 10px; }
.opt-section .opt-extra { margin-bottom: 10px; }
/* Settings that only apply when the one above them is on. */
.toggle-row.opt-child { margin-left: 18px; position: relative; }
.toggle-row.opt-child::before {
  content: ''; position: absolute; left: -11px; top: 12px; bottom: 12px;
  width: 2px; border-radius: 2px; background: var(--line);
}
.toggle-row.opt-child-2 { margin-left: 36px; }
.toggle-row.dim { opacity: .45; }

/* ── Relay pen ── */
.relay-bar {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 7px 12px; font-size: 0.8rem; font-weight: 800;
}
.relay-bar.mine { border-color: var(--brand); background: var(--brand-soft); color: var(--brand-on-soft); }
.relay-who { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.relay-meter { width: 84px; height: 6px; border-radius: 99px; background: var(--line); overflow: hidden; flex-shrink: 0; }
.relay-meter i { display: block; height: 100%; background: var(--brand); border-radius: 99px; transition: width .95s linear; }
.relay-secs { font-variant-numeric: tabular-nums; min-width: 22px; text-align: right; }

/* ── The clock, running out ── */
.timer-wrap.urgent .timer-num { color: var(--bad); }
.timer-wrap.urgent .timer-ring-fg { stroke: var(--bad); }
.timer-wrap.urgent { animation: timerPulse 1s ease-in-out infinite; }
@keyframes timerPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }

/* ── The AI list generator ── */
.wl-ai {
  margin-top: 16px; border-top: 1px solid var(--line); padding-top: 14px;
  display: flex; flex-direction: column; gap: 9px;
}
.wl-ai-badge {
  font-size: 0.56rem; font-weight: 800; letter-spacing: 1px; vertical-align: middle;
  background: var(--grad); color: #fff; border-radius: 99px; padding: 2px 7px; margin-left: 6px;
}
.wl-ai-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.wl-ai-row .input { flex: 1; min-width: 150px; }
.ai-remember { display: flex; align-items: center; gap: 7px; font-size: 0.74rem; font-weight: 700; color: var(--ink-dim); white-space: nowrap; }
.ai-status { font-size: 0.78rem; font-weight: 700; padding: 8px 11px; border-radius: var(--r-sm); }
.ai-status.work { background: var(--card-2); color: var(--ink-dim); }
.ai-status.good { background: var(--good-soft); color: var(--good); }
.ai-status.bad { background: var(--bad-soft); color: var(--bad); }

/* ── A bit more air where things were crammed ── */
.opt-grid { gap: 12px 16px; }
.opt-toggles { gap: 4px; }
.toggle-row { padding: 9px 10px; border-radius: var(--r-sm); }
.toggle-row:hover { background: var(--card-2); }
.card-title-row { gap: 10px; flex-wrap: wrap; }
.mini-btn-row { display: flex; gap: 6px; flex-wrap: wrap; }
.room-actions { gap: 8px; }
.wl-custom-row .input { min-width: 0; }
.rooms-list { gap: 8px; }
.final-row, .re-score-row { padding: 8px 12px; }

/* ── Canvas: give the drawing the space the panels were hoarding ── */
@media (min-width: 1081px) {
  .game-grid { grid-template-columns: 208px minmax(0, 1fr) 296px; gap: 12px; }
  body.in-game #main { padding: 8px 12px 10px; }
  .canvas-card { padding: 9px; gap: 8px; }
  .game-top { margin-bottom: 10px; }
}
@media (min-width: 1500px) {
  .game-grid { grid-template-columns: 224px minmax(0, 1fr) 312px; }
}

/* ══════════ Batch 19 ══════════ */

/* ── The list library, as a proper hub ── */
.modal-xl { max-width: 1080px; width: min(96vw, 1080px); }
.lib-search-row { display: flex; gap: 9px; align-items: center; margin-bottom: 10px; flex-wrap: wrap; }
.lib-search { position: relative; flex: 1; min-width: 220px; display: flex; align-items: center; }
.lib-search-icon { position: absolute; left: 12px; font-size: 0.9rem; opacity: .55; pointer-events: none; }
.lib-search .input { width: 100%; padding-left: 34px; padding-right: 34px; }
.lib-search-clear {
  position: absolute; right: 8px; background: none; border: none; cursor: pointer;
  font-size: 0.8rem; opacity: .55; padding: 4px;
}
.lib-search-clear:hover { opacity: 1; }
.lib-sort { max-width: 190px; }
#btn-lib-filters.on { border-color: var(--brand); color: var(--brand); }

.lib-tagbar { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.lib-tag {
  background: var(--card-2); border: 1px solid var(--line); border-radius: 99px;
  padding: 4px 11px; font-size: 0.72rem; font-weight: 700; cursor: pointer;
  color: var(--ink-dim); font-family: inherit; transition: all .14s;
}
.lib-tag:hover { border-color: var(--brand); color: var(--brand); }
.lib-tag.on { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-on-soft); }

.lib-filters {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px; align-items: end;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 14px; margin-bottom: 12px;
}
.lib-filter { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.lib-filter label { font-size: 0.7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .8px; color: var(--ink-dim); }

.lib-resultbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }

.lib-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: 12px; max-height: 54vh; overflow-y: auto; padding: 2px;
}
.lib-card {
  background: var(--card-2); border: 2px solid var(--line); border-radius: var(--r-md);
  padding: 14px; display: flex; flex-direction: column; gap: 7px; min-width: 0;
  transition: border-color .15s, transform .15s;
}
.lib-card:hover { border-color: var(--brand); transform: translateY(-2px); }
.lib-card-head { display: flex; align-items: flex-start; gap: 8px; }
.lib-card-name {
  font-weight: 800; font-size: 0.95rem; flex: 1; min-width: 0; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.lib-badge {
  font-size: 0.58rem; font-weight: 800; letter-spacing: .6px; text-transform: uppercase;
  background: var(--card); border: 1px solid var(--line); color: var(--ink-dim);
  border-radius: 99px; padding: 2px 8px; flex-shrink: 0; white-space: nowrap;
}
.lib-badge.good { background: var(--good-soft); color: var(--good); border-color: transparent; }
.lib-badge.warn { background: var(--brand-soft); color: var(--brand-on-soft); border-color: transparent; }
.lib-badge.bad { background: var(--bad-soft); color: var(--bad); border-color: transparent; }
.lib-card-by { font-size: 0.72rem; font-weight: 700; color: var(--ink-dim); }
.lib-card-desc {
  font-size: 0.78rem; line-height: 1.45; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.lib-card-desc.muted, .li-word.muted, .li-desc.muted { color: var(--ink-dim); font-style: italic; }
.lib-card-preview {
  font-size: 0.7rem; color: var(--ink-dim); background: var(--card);
  border-radius: var(--r-sm); padding: 6px 9px; line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lib-card-tags { display: flex; gap: 4px; flex-wrap: wrap; }
.lib-card-tags .lib-tag { font-size: 0.62rem; padding: 2px 8px; }
.lib-card-foot { display: flex; align-items: center; gap: 4px; margin-top: auto; padding-top: 8px; border-top: 1px solid var(--line); }
.lib-dl { font-size: 0.7rem; font-weight: 800; color: var(--ink-dim); flex: 1; }
.lib-act {
  background: none; border: 1px solid transparent; border-radius: 8px; cursor: pointer;
  font-size: 0.85rem; padding: 5px 7px; opacity: .7; transition: all .14s; line-height: 1;
}
.lib-act:hover { opacity: 1; background: var(--card); border-color: var(--line); }
.lib-act.primary { opacity: 1; }
.lib-act.danger:hover { background: var(--bad-soft); border-color: var(--bad); }

.lib-tagpick { display: flex; flex-direction: column; gap: 7px; }
.lib-tagpick-label { font-size: 0.78rem; font-weight: 800; }
.lib-tagpick-row { display: flex; gap: 5px; flex-wrap: wrap; }

/* ── One list, in detail ── */
.li-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.li-desc { font-size: 0.88rem; line-height: 1.55; margin-bottom: 10px; }
.li-stats { font-size: 0.75rem; font-weight: 700; color: var(--ink-dim); margin-bottom: 12px; }
.li-words {
  display: flex; flex-wrap: wrap; gap: 5px;
  max-height: 210px; overflow-y: auto;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px; margin-bottom: 14px;
}
.li-word {
  font-size: 0.74rem; font-weight: 600; background: var(--card);
  border: 1px solid var(--line); border-radius: 99px; padding: 3px 9px;
}
.li-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.li-edit { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 10px; }

/* ── The round's modes, over the canvas ── */
.mode-banner {
  align-self: stretch; text-align: center;
  background: var(--brand-soft); color: var(--brand-on-soft);
  border-radius: var(--r-sm); padding: 5px 12px;
  font-size: 0.76rem; font-weight: 800; letter-spacing: .3px;
}
.mode-banner.spent { background: var(--bad-soft); color: var(--bad); }
.btn-done-drawing { align-self: center; }

/* One Colour: the palette is replaced by the colour you were given. */
.palette.one-color { position: relative; }
.palette.one-color .swatch { opacity: .18; filter: grayscale(1); cursor: not-allowed; }
.palette.one-color::after {
  content: 'One colour this round';
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  gap: 8px; background: var(--card); border-radius: var(--r-sm);
  font-size: 0.74rem; font-weight: 800; color: var(--ink-dim);
  border: 2px solid var(--locked-color, var(--brand));
  box-shadow: inset 4px 0 0 var(--locked-color, var(--brand));
  padding-left: 10px;
}

/* ── Public-match voting ── */
.poll-card { border: 2px solid var(--brand); animation: pollIn .25s ease; }
@keyframes pollIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.poll-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
.poll-icon { font-size: 1.2rem; flex-shrink: 0; }
.poll-text { flex: 1; min-width: 0; }
.poll-q { font-weight: 800; font-size: 0.88rem; line-height: 1.35; }
.poll-detail { font-size: 0.74rem; color: var(--ink-dim); margin-top: 3px; line-height: 1.4; }
.poll-clock { font-size: 0.76rem; font-weight: 800; color: var(--ink-dim); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.poll-bar { height: 6px; border-radius: 99px; background: var(--line); overflow: hidden; margin-bottom: 8px; }
.poll-bar i { display: block; height: 100%; background: var(--grad); border-radius: 99px; transition: width .3s ease; }
.poll-tally { font-size: 0.73rem; font-weight: 700; color: var(--ink-dim); margin-bottom: 10px; }
.poll-actions { display: flex; gap: 8px; }
.poll-actions .btn { flex: 1; }
.p-row .votekick { background: none; border: none; cursor: pointer; font-size: 0.8rem; opacity: .45; padding: 2px 4px; }
.p-row .votekick:hover { opacity: 1; }

/* ── Dragging a list onto the room ── */
#words-panel.drop-target {
  outline: 3px dashed var(--brand); outline-offset: -6px;
  background: var(--brand-soft);
}
#words-panel.drop-target::before {
  content: '📥 Drop .txt or .zip files to add them';
  display: block; text-align: center; font-weight: 800; font-size: 0.82rem;
  color: var(--brand-on-soft); padding: 8px 0 4px;
}

/* ── "List publicly" gets some air under the buttons ── */
.room-public-row { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }

/* ── A dialog that needs room for a word list ── */
.dialog-area { width: 100%; box-sizing: border-box; margin-bottom: 4px; resize: vertical; }

@media (max-width: 760px) {
  .lib-cards { grid-template-columns: 1fr; max-height: none; }
  .lib-search-row { flex-direction: column; align-items: stretch; }
  .lib-sort { max-width: none; }
}

/* ══════════ Wet Paint & Tile Reveal ══════════ */

/* The dry line sweeps left to right; everything behind it has set. It sits
   above the canvas but ignores the pointer, so drawing still works. */
.dry-overlay {
  position: absolute; inset: 0; z-index: 6; pointer-events: none;
  --dry: 0%;
}
.dry-overlay::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: 0;
  width: var(--dry);
  background: linear-gradient(90deg,
    rgba(120, 100, 70, 0.10) 0%,
    rgba(120, 100, 70, 0.05) 70%,
    rgba(120, 100, 70, 0.14) 100%);
  transition: width 1s linear;
}
.dry-edge {
  position: absolute; top: 0; bottom: 0; left: var(--dry);
  width: 3px; margin-left: -1.5px;
  background: linear-gradient(180deg, #E4A11B, #C2410C);
  box-shadow: 0 0 12px rgba(226, 161, 27, .75);
  transition: left 1s linear;
}
.dry-edge::after {
  content: '';
  position: absolute; top: -1px; left: -4px; width: 11px; height: 11px;
  border-radius: 99px; background: #E4A11B;
  box-shadow: 0 0 10px rgba(226, 161, 27, .9);
}

/* The shutters guessers watch through. Each is a frosted panel that lifts. */
.tile-shutters { position: absolute; inset: 0; z-index: 7; pointer-events: none; }
.shutter {
  position: absolute; display: block;
  background: var(--card-2);
  border: 1px solid var(--line);
  box-shadow: inset 0 0 22px rgba(0, 0, 0, .12);
  transition: opacity .45s ease, transform .45s ease;
}
/* A subtle weave so a closed panel reads as "covered", not "broken". */
.shutter::before {
  content: ''; position: absolute; inset: 0; opacity: .5;
  background-image: repeating-linear-gradient(
    45deg, transparent 0 7px, color-mix(in srgb, var(--ink) 8%, transparent) 7px 8px);
}
.shutter.open { opacity: 0; transform: translateY(-8%); }
.shutter.lifting { animation: shutterUp .45s ease forwards; }
@keyframes shutterUp {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-14%); }
}

/* ══════════ Batch 21 ══════════ */

/* ── The palette, now three rows of fifteen ── */
.palette {
  display: grid; grid-template-columns: repeat(15, 1fr);
  gap: 4px; width: 100%; max-width: 420px;
}
.palette .swatch {
  width: 100%; aspect-ratio: 1; min-width: 0; height: auto;
  border-radius: 5px; border: 1px solid rgba(128, 128, 128, .25);
}
.palette .swatch.active {
  outline: 2px solid var(--ink); outline-offset: 1px; transform: none;
  box-shadow: 0 0 0 2px var(--card);
}
@media (max-width: 900px) {
  .palette { grid-template-columns: repeat(10, 1fr); max-width: none; }
}

/* ── Like / skip, centred under the canvas ── */
.float-actions {
  left: 50%; right: auto; transform: translateX(-50%);
  justify-content: center;
}

/* ── A lock that stays while the canvas is frozen ── */
.lock-badge {
  position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: 13; display: flex; align-items: center; gap: 6px;
  background: var(--brand); color: #fff;
  padding: 6px 14px; border-radius: 99px;
  font-size: 0.78rem; font-weight: 800; letter-spacing: .3px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .28);
  pointer-events: none;
}

/* ── Lists saved on this device ── */
.wl-saved { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 12px; }
.wl-saved-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.saved-chip {
  display: flex; align-items: stretch;
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: 99px; overflow: hidden; transition: border-color .15s;
}
.saved-chip:hover { border-color: var(--brand); }
.saved-chip.in-room { opacity: .5; }
.saved-use {
  display: flex; align-items: center; gap: 6px;
  background: none; border: none; cursor: pointer; font-family: inherit;
  padding: 5px 4px 5px 12px; color: var(--ink); font-size: 0.76rem; font-weight: 700;
}
.saved-use:disabled { cursor: default; }
.saved-name { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.saved-count {
  background: var(--card); border-radius: 99px; padding: 1px 7px;
  font-size: 0.66rem; font-weight: 800; color: var(--ink-dim);
}
.saved-drop {
  background: none; border: none; cursor: pointer; color: var(--ink-dim);
  padding: 0 10px 0 6px; font-size: 0.72rem; font-family: inherit;
}
.saved-drop:hover { color: var(--bad); }

/* ── The custom-list controls, on one tidy line ── */
.wl-custom-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wl-custom-sep { flex: 0 0 1px; align-self: stretch; background: var(--line); margin: 2px 2px; }
.wl-custom .format-tip { margin-top: 4px; }
.wl-keep { /* inherits .wl-actions button */ }

/* ── Sharing a personal list ── */
.list-share-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line);
}
.share-pill {
  display: flex; align-items: center; gap: 6px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 99px;
  padding: 4px 6px 4px 12px; font-size: 0.72rem; font-weight: 700; min-width: 0;
}
.share-pill code {
  max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 0.7rem; color: var(--ink-dim);
}
.private-tag {
  font-size: 0.6rem; font-weight: 800; letter-spacing: .8px;
  background: var(--card-2); color: var(--ink-dim);
  border: 1px solid var(--line); border-radius: 99px; padding: 2px 8px;
}
.private-tag.shared { background: var(--good-soft); color: var(--good); border-color: transparent; }

/* ── Moderator statistics ── */
.set-group-mod { border: 1px dashed var(--line); border-radius: var(--r-md); padding: 14px; }
.mod-badge {
  font-size: 0.56rem; font-weight: 800; letter-spacing: 1px; vertical-align: middle;
  background: var(--grad); color: #fff; border-radius: 99px; padding: 2px 7px; margin-left: 6px;
}
.stat-ranges { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.stat-tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(126px, 1fr));
  gap: 10px; margin-bottom: 16px;
}
.stat-tile {
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px 14px;
}
.stat-value { font-size: 1.5rem; font-weight: 800; line-height: 1.1; color: var(--brand); }
.stat-label { font-size: 0.74rem; font-weight: 700; margin-top: 3px; }
.stat-hint { font-size: 0.66rem; color: var(--ink-dim); margin-top: 2px; }

.stat-chart {
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 14px 14px 10px; margin-bottom: 10px; position: relative;
}
.bars {
  display: flex; align-items: flex-end; gap: 2px;
  height: 170px; padding-right: 34px;
}
.bar-col { flex: 1; min-width: 0; height: 100%; display: flex; align-items: flex-end; }
.bar {
  width: 100%; border-radius: 3px 3px 0 0;
  background: linear-gradient(180deg, var(--brand), color-mix(in srgb, var(--brand) 55%, transparent));
  transition: filter .12s;
}
.bar:hover { filter: brightness(1.25); }
.bar.zero { background: var(--line); }
.bar-axis {
  display: flex; justify-content: space-between; gap: 4px;
  margin-top: 6px; padding-right: 34px;
  font-size: 0.64rem; color: var(--ink-dim); font-weight: 700;
}
.bar-scale {
  position: absolute; top: 14px; right: 14px; bottom: 34px;
  display: flex; flex-direction: column; justify-content: space-between;
  font-size: 0.64rem; color: var(--ink-dim); font-weight: 700;
}

.stat-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; margin-bottom: 14px; }
.stat-col { min-width: 0; }
.stat-list {
  margin-top: 8px; max-height: 190px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 4px;
}
.stat-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--card-2); border-radius: var(--r-sm); padding: 7px 11px;
  font-size: 0.76rem;
}
.stat-row-name { font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat-row-meta { color: var(--ink-dim); font-size: 0.68rem; white-space: nowrap; flex-shrink: 0; }

/* ── Library polish ── */
.lib-card { transition: border-color .15s, transform .15s, box-shadow .15s; }
.lib-card:hover { box-shadow: var(--shadow-sm); }
.lib-cards { max-height: 58vh; }
.lib-card-name { font-size: 0.98rem; }
.lib-search .input { font-size: 0.9rem; padding-top: 10px; padding-bottom: 10px; }
.lib-resultbar { padding-bottom: 2px; border-bottom: 1px solid var(--line); margin-bottom: 12px; }

@media (max-width: 760px) {
  .stat-tiles { grid-template-columns: repeat(2, 1fr); }
  .bars { height: 130px; }
}

/* ══════════ Batch 22 — density pass + new pieces ══════════ */

/* ── Less crammed at 100% zoom: tighter chrome everywhere. The body also
      defaults to 90% zoom on desktops (see applyScale), so together the page
      finally sits comfortably on a laptop screen. ── */
.card { padding: 16px; }
.hero { padding: 22px 0 16px; }
.hero-sub { margin-top: 6px; }
.home-grid { gap: 14px; }
#main { padding: 14px 18px 32px; }
.lobby-grid { gap: 14px; }
.card-title { margin-bottom: 8px; }
.opt-grid { gap: 10px 14px; }
.opt-section { margin-top: 13px; padding-top: 11px; }
.toggle-row { padding: 7px 9px; }
.btn-hero { padding: 15px 19px; }
.btn-big { padding: 12px 16px; }
.wl-custom { margin-top: 12px; padding-top: 11px; gap: 8px; }
.modal { padding: 22px; }
.modal h2 { margin-bottom: 4px; }
.modal-sub { margin-bottom: 12px; }

/* ── the M badge ── */
.mod-chip {
  flex-shrink: 0; width: 15px; height: 15px; border-radius: 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--grad); color: #fff;
  font-size: 0.56rem; font-weight: 800; line-height: 1;
}

/* ── the close-guess bar over the chat box ── */
.close-bar {
  display: none;
  background: var(--brand-soft); color: var(--brand-on-soft);
  border: 1px solid var(--brand); border-radius: var(--r-sm);
  padding: 6px 11px; margin-bottom: 6px;
  font-size: 0.78rem; font-weight: 800; text-align: center;
}
.close-bar.show { display: block; animation: closePop .25s ease; }
@keyframes closePop { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* ── like / skip: drawn icons, tucked in the corner ── */
.float-actions { left: auto; right: 10px; transform: none; bottom: 10px; }
.icon-float { padding: 8px; border-radius: 12px; }
.icon-float svg { width: 19px; height: 19px; display: block; fill: var(--ink-dim); transition: fill .15s, transform .15s; }
#btn-like:hover svg { fill: #e0245e; transform: scale(1.12); }
#btn-like.used svg { fill: #e0245e; }
#btn-voteskip:hover svg { fill: var(--brand); }
#btn-voteskip.used svg { fill: var(--brand); }
.icon-float span:empty { display: none; }
.icon-float span { font-size: 0.72rem; font-weight: 800; }

/* ── the emoji picker at full size ── */
.emoji-search { width: 100%; margin-bottom: 8px; position: sticky; top: 0; z-index: 2; }
.emoji-picker { max-height: 320px; }

/* ── stats: the line chart ── */
.chart-line { position: relative; height: 190px; }
.chart-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.chart-area { fill: color-mix(in srgb, var(--brand) 22%, transparent); }
.chart-stroke {
  fill: none; stroke: var(--brand); stroke-width: 3;
  stroke-linejoin: round; stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.chart-dot { fill: var(--card); stroke: var(--brand); stroke-width: 2.5; }
.chart-dot:hover { fill: var(--brand); }
.chart-dots { pointer-events: auto; }

/* ── leaderboard ── */
.lb-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.lb-rows { display: flex; flex-direction: column; gap: 5px; max-height: 52vh; overflow-y: auto; }
.lb-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--card-2); border: 1px solid transparent; border-radius: var(--r-sm);
  padding: 8px 12px; font-size: 0.86rem;
}
.lb-row.me, .lb-me { border-color: var(--brand); background: var(--brand-soft); }
.lb-rank { width: 34px; text-align: center; font-weight: 800; font-size: 0.9rem; flex-shrink: 0; }
.lb-name { flex: 1; min-width: 0; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-value { font-weight: 800; color: var(--brand); font-variant-numeric: tabular-nums; }
.lb-me { display: flex; align-items: center; gap: 10px; border: 1px solid var(--brand); border-radius: var(--r-sm); padding: 8px 12px; margin-top: 8px; font-size: 0.86rem; }

/* ── words-in-a-list viewer ── */
.mw-words { max-height: 46vh; margin-top: 10px; }

/* ── footer version chip ── */
.version-chip {
  font-size: 0.68rem; font-weight: 800; letter-spacing: .4px;
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: 99px; padding: 2px 9px; color: var(--ink-dim);
}

/* ══════════ Batch 23 — the game fills the screen ══════════ */

/* Slimmer frame around the whole game screen. */
body.in-game #main { padding: 6px 8px 8px; }
@media (min-width: 1081px) {
  body.in-game .game-grid { gap: 10px; }
  body.in-game .game-top { margin-bottom: 8px; padding: 8px 14px; }
}

/* The canvas column centres its content in whatever height it has, so a
   width-limited canvas floats mid-column instead of hugging the top. */
body.in-game .canvas-card { justify-content: center; }

/* The side panels stretch the full column height and scroll inside. */
body.in-game .players-card { display: flex; flex-direction: column; }
body.in-game .players-list { flex: 1; min-height: 0; overflow-y: auto; }
body.in-game .chat-card { height: 100%; min-height: 0; }

/* ══════════ Batch 23 — the game-options panel, redesigned ══════════ */

/* Sliders become tidy little cards: name and value up top, the track under
   them, everything aligned. */
.opt {
  background: var(--card-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 9px 12px 10px;
  gap: 4px 10px;
  transition: border-color .15s;
}
.opt:hover, .opt:focus-within { border-color: var(--brand); }
.opt > label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: .5px; }
.opt > .opt-val {
  background: var(--card);
  border-radius: 99px;
  padding: 1px 9px;
  font-size: 0.78rem;
  min-width: 0;
}

/* A track and thumb that look deliberate rather than default. */
.opt > input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 6px;
  border-radius: 99px;
  background: var(--line);
  accent-color: var(--brand);
  margin-top: 4px;
  cursor: pointer;
}
.opt > input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 17px; height: 17px; border-radius: 99px;
  background: var(--grad);
  border: 2.5px solid var(--card);
  box-shadow: 0 1px 5px rgba(0, 0, 0, .3);
  cursor: grab;
}
.opt > input[type="range"]:active::-webkit-slider-thumb { cursor: grabbing; transform: scale(1.12); }

/* Sections read as grouped blocks, keyed by a brand tick on the left. */
.opt-section {
  border-top: none;
  border-left: 3px solid var(--line);
  padding: 2px 0 2px 12px;
  margin-top: 14px;
  border-radius: 2px;
}
.opt-section:first-of-type { margin-top: 12px; border-left-color: var(--line); padding-left: 12px; }
.opt-section:hover { border-left-color: var(--brand); }
.opt-section-title { margin-bottom: 9px; }

/* Toggle rows: a hair tighter, clearer hover, and the switch always at a
   consistent spot. */
.opt-toggles { border-top: none; padding-top: 2px; }
.toggle-row { border: 1px solid transparent; }
.toggle-row:hover { border-color: var(--line); }

/* The in-game settings modal: the two borrowed panels sit side by side on a
   wide screen instead of one endless scroll. */
#gamesettings-body { display: grid; gap: 16px; align-items: start; }
@media (min-width: 1150px) {
  #gamesettings-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
#gamesettings-body .card { background: var(--card-2); border: 1px solid var(--line); box-shadow: none; padding: 14px; border-radius: var(--r-md); }
#modal-gamesettings .modal { max-height: 88vh; overflow-y: auto; }

/* ══════════ Batch 24 — the canvas owns the middle of the screen ══════════ */

/* The toolbar sits at the very bottom of the screen; the canvas floats in
   the space between the word bar and it, as large as 4:3 allows. */
body.in-game .canvas-card { justify-content: flex-start; }
body.in-game .canvas-card .canvas-frame { margin: auto; }

/* A wider, flatter palette keeps the tool row shallow, so the height goes
   to the canvas (45 colours in two rows instead of four). */
@media (min-width: 1081px) {
  body.in-game .palette { grid-template-columns: repeat(23, 20px); gap: 3px; }
  body.in-game .palette .swatch { width: 20px; height: 20px; }
}

/* ══════════ Batch 25 — tighter panels, tools on the floor ══════════ */

/* The toolbar hugs the bottom edge of the screen: less padding under the
   game, less padding inside the canvas card, a slimmer gap above the bar. */
body.in-game #main { padding: 4px 8px 4px; }
body.in-game .canvas-card { gap: 6px; padding-bottom: 6px; }
@media (min-width: 1081px) {
  body.in-game .game-top { margin-bottom: 6px; }
}

/* ══════════ Batch 26 — the game IS the page ══════════ */

/* In a game the site header steps aside and the layout takes the whole
   viewport; the header's game controls live in the word bar instead. */
body.in-game .topbar { display: none; }
body.in-game #main { height: 100dvh; }

.gt-actions { display: flex; gap: 6px; align-items: center; flex-shrink: 0; }
.gt-code {
  width: auto; padding: 0 11px;
  font-family: 'Fredoka', sans-serif; font-weight: 600;
  font-size: 0.85rem; letter-spacing: 2px;
}

/* Start Game sits inside the room card now, right under the invite row. */
.room-card .btn-start { width: 100%; margin-top: 10px; }
.room-card .waiting-msg { margin-top: 10px; }

/* The public switch at the top of the in-game settings modal. */
.gs-public { border: 1px solid var(--line); margin-bottom: 12px; }

/* ══════════ Batch 27 — slim word bar, canvas low and huge, tools on the floor ══════════ */

/* The word bar goes on a diet: smaller pills, shorter tiles, a smaller
   timer. Every pixel it gives up lands in the canvas (fitCanvas measures
   the real heights, so no numbers need to agree with these). */
body.in-game .game-top { padding: 4px 12px; gap: 10px; margin-bottom: 4px; }
body.in-game .round-pill { font-size: 0.78rem; padding: 4px 12px; }
body.in-game .count-pill { font-size: 0.76rem; padding: 4px 11px 4px 9px; }
body.in-game .word-wrap { min-height: 30px; gap: 2px; }
body.in-game .tile { min-width: 21px; height: 26px; font-size: 0.95rem; border-radius: 5px; border-width: 1.5px; }
body.in-game .tile-gap { width: 8px; }
body.in-game .word-meta { font-size: 0.62rem; letter-spacing: .7px; }
body.in-game .timer-wrap, body.in-game .timer-ring { width: 42px; height: 42px; }
body.in-game .timer-num { font-size: 0.85rem; }
body.in-game .gt-actions .icon-btn { width: 30px; height: 30px; border-radius: 9px; font-size: 0.9rem; }
body.in-game .gt-code { width: auto; font-size: 0.78rem; }

/* The canvas sits DOWN on the toolbar — any spare height collects above
   it, under the word bar — and the toolbar sits on the bottom edge of the
   screen with almost nothing beneath it. */
body.in-game #main { padding: 2px 6px 2px; }
body.in-game .canvas-card { padding: 4px 6px; gap: 4px; }
body.in-game .canvas-card .canvas-frame { margin: auto auto 0; }
@media (min-width: 1081px) {
  body.in-game .game-grid { gap: 8px; }
}

/* ══════════ Batch 28 — a cleaner game screen ══════════ */

/* The word bar floats free: no card box, just the pills, the tiles and the
   timer on the page background. */
body.in-game .game-top { background: transparent; border: none; box-shadow: none; padding: 2px 4px; margin-bottom: 4px; }
body.in-game .word-meta { min-height: 0; }

/* The canvas stands on its own — the box around it is gone, and every
   pixel the card chrome used to take goes to the drawing. The toolbar
   becomes a floating pill resting on the bottom edge of the screen. */
body.in-game .canvas-card { padding: 0; background: transparent; border: none; box-shadow: none; gap: 6px; }
body.in-game .canvas-card .toolbar {
  width: auto; max-width: 100%;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 14px; padding: 6px 10px;
  box-shadow: var(--shadow-sm);
}
body.in-game .toolbar { gap: 8px; }
body.in-game .tool-btn { width: 34px; height: 34px; border-radius: 9px; font-size: 0.95rem; }
body.in-game .size-dot { width: 30px; height: 30px; }

/* Room controls live in the players column now: the code up top, the
   actions in one even row pinned at the bottom. */
.pc-actions { display: flex; gap: 6px; margin-top: 8px; flex-shrink: 0; }
.pc-actions .icon-btn { flex: 1; width: auto; height: 32px; border-radius: 10px; font-size: 0.95rem; }
.players-card .gt-code {
  width: auto; height: 30px; padding: 0 10px;
  font-family: 'Fredoka', sans-serif; font-weight: 600;
  font-size: 0.8rem; letter-spacing: 1.5px;
}

/* ══════════ Batch 29 — pinned to the bottom edge, calmer top bar ══════════ */

/* Nothing scrolls during a game. The page height is pinned from JS in real
   pixels (fitCanvas), so the canvas and both side columns land exactly on
   the bottom of the screen. */
body.in-game { overflow: hidden; }

/* The word bar sizes back up a notch — the slim pass overshot. */
body.in-game .game-top { padding: 4px 6px; gap: 12px; margin-bottom: 6px; }
body.in-game .round-pill { font-size: 0.85rem; padding: 5px 14px; }
body.in-game .count-pill { font-size: 0.82rem; padding: 5px 12px 5px 10px; }
body.in-game .word-wrap { min-height: 36px; }
body.in-game .tile { min-width: 24px; height: 30px; font-size: 1.05rem; border-radius: 6px; }
body.in-game .word-meta { font-size: 0.68rem; }
body.in-game .timer-wrap, body.in-game .timer-ring { width: 48px; height: 48px; }
body.in-game .timer-num { font-size: 0.95rem; }

/* The colours can never leave the screen again: the palette wraps to the
   width it actually has instead of demanding 23 rigid columns.

   It wraps as a GRID, not a flex row. A swatch is sized `width: 100%`, which
   in a grid means "fill your track" and in a flex row means "as wide as the
   whole palette" — so the flex version this used to be gave every one of the
   46 colours its own full-width line. On a phone that made the toolbar
   17,000 pixels tall and pushed the tools, the chat and everything else
   clean off the bottom of the screen. */
body.in-game .palette {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(22px, 1fr));
  gap: 3px;
  justify-content: center;
  max-width: 560px;
  min-width: 0;
}

/* ══════════ Batch 30 — themed scrollbars + inline list odds ══════════ */

/* Scrollbars in the site's own colours instead of the operating system's.
   This covers the list-information words box, the library, the players
   column and every other scrolling panel, and it re-colours itself with
   the theme because it is built from the same tokens. */
* { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 99px;
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--brand); background-clip: content-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* The words box in list information gets a little inset so the bar has
   somewhere to sit. */
.mw-words, .li-words { padding-right: 4px; }

/* The odds, beside the word count. */
.wl-odds {
  font-size: 0.68rem; font-weight: 800;
  color: var(--brand-on-soft); background: var(--brand-soft);
  border-radius: 99px; padding: 1px 7px;
  white-space: nowrap; flex-shrink: 0;
}
.wl-odds:empty { display: none; }

/* ══════════ Batch 31 — nothing in a dialog leaves the screen ══════════ */

/* Size dialogs against the measured viewport (set by syncViewportVars)
   rather than vw/vh, which a zoomed page reports differently browser to
   browser — that is what pushed the settings buttons off the edge. */
:root { --vvw: 100vw; --vvh: 100vh; }
.modal { max-height: calc(var(--vvh) * 0.92); }
.modal-xl { max-width: 1080px; width: min(calc(var(--vvw) * 0.96), 1080px); }
#modal-gamesettings .modal { max-height: calc(var(--vvh) * 0.88); }

/* Rows of buttons wrap onto a second line instead of running off the side.
   In the mid-game settings the panels sit in half the width they were
   designed for, so these rows were always going to be too long. */
.card-title-row { flex-wrap: wrap; gap: 8px; }
.mini-btn-row { flex-wrap: wrap; justify-content: flex-end; }
.wl-ai-row { flex-wrap: wrap; }
.wl-ai-row > .input { min-width: 0; flex: 1 1 200px; }
#gamesettings-body .card-title-row .card-title { flex: 1 1 auto; min-width: 0; }

/* Nothing inside the settings modal may push it wider than it is. */
#gamesettings-body, #gamesettings-body .card { min-width: 0; max-width: 100%; }
#gamesettings-body .wl-grid, #gamesettings-body .opt-grid { min-width: 0; }

/* ══════════ Batch 32 — one tidy toolbar line, with room to breathe ══════════ */

@media (min-width: 1081px) {
  /* One line, always. fitToolbar() picks the sizes below from the width the
     canvas actually has, so the row never wraps and never overflows. */
  body.in-game .canvas-card .toolbar {
    flex-wrap: nowrap;
    gap: var(--tb-gap, 12px);
    padding: 8px var(--tb-pad, 16px);
    /* fitToolbar() gives the bar an inline width taken from the canvas above
       it. If that is ever more than the card can actually give, the bar must
       stop at the card rather than pushing the page sideways. */
    max-width: 100%;
  }
  body.in-game .toolbar > * { flex-shrink: 0; }

  /* …except the colours, which are always the thing that gives.
     fitToolbar() picks a size from the width the bar has at that instant, but
     that width is itself downstream of the size it picks: the canvas is sized
     from the space left by the toolbar, the middle column from the canvas, and
     the toolbar from the middle column. The loop does not always settle where
     it started, and when it did not, a non-shrinkable palette walked straight
     off the right-hand edge of the screen.
     Letting the colour strip shrink and scroll makes that impossible whatever
     the arithmetic decides: the tools stay a row, the bar stays inside the
     card, and at worst the last few colours are a short swipe away. */
  body.in-game .toolbar > .palette {
    flex: 0 1 auto;
    min-width: 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  body.in-game .toolbar > .palette::-webkit-scrollbar { display: none; }

  /* Two bands instead of one cramped line: the tools on top, the colours
     across the full width below. fitToolbar() switches this on when the
     colours cannot all be shown on a single row — a Discord Activity panel on
     a desktop is the case that needs it. */
  body.in-game .canvas-card .toolbar.toolbar-stacked { flex-wrap: wrap; row-gap: 10px; }
  body.in-game .toolbar.toolbar-stacked > .palette {
    flex: 1 0 100%;
    justify-content: center;
  }

  body.in-game .tool-btn {
    width: var(--tb-btn, 38px); height: var(--tb-btn, 38px);
    border-radius: 11px; font-size: 1.02rem;
  }
  body.in-game .tool-group { gap: var(--tb-gin, 6px); }
  body.in-game .size-dots { gap: var(--tb-gin, 6px); }
  body.in-game .size-dot { width: var(--tb-dot, 34px); height: var(--tb-dot, 34px); }
  body.in-game .tool-sep { height: var(--tb-dot, 34px); }

  /* The custom-colour button spans the whole height of its own column at
     the front of the grid — fitToolbar sets the tracks — so the three colour
     families stay three clean rows instead of one button starting a fourth. */
  body.in-game .palette .swatch.rainbow {
    grid-column: 1; grid-row: 1 / -1;
    width: calc(var(--sw, 22px) * 1.3); min-height: 0;
    /* Span the full height of the three families. aspect-ratio would fight
       the row span and keep it square. */
    height: auto; align-self: stretch; aspect-ratio: auto;
  }
  /* A fixed grid, so the palette's shape is the same at every zoom. */
  body.in-game .palette {
    display: grid;
    grid-template-columns: repeat(15, var(--sw, 22px));
    gap: 4px;
    flex: 0 0 auto;
  }
  body.in-game .palette .swatch {
    width: var(--sw, 22px); height: var(--sw, 22px);
    border-radius: 6px;
  }
}

/* ══════════ Batch 33 — the round-end drawing, edge to edge ══════════ */

/* The drawing space is 4:3, but the picture sat in a box whose shape came
   from the layout — so "contain" letterboxed it, and the white filler read
   as blank canvas around the drawing. Give the box the drawing's own shape
   and the image fills it exactly. */
.re-image { aspect-ratio: 4 / 3; height: auto; width: 100%; object-fit: contain; }
@media (min-width: 861px) {
  .re-image { flex: 1 1 60%; max-height: min(62vh, 620px); }
}

/* ══════════ Batch 34 — the pregame room card, tidied ══════════ */

/* A `1fr` grid track will not shrink below its content, so a wide panel in
   the right column pushed the whole lobby sideways and took the buttons off
   the edge with it. minmax(0, 1fr) lets the track actually give. */
.lobby-grid { grid-template-columns: 360px minmax(0, 1fr); }
.lobby-grid.guest { grid-template-columns: 320px minmax(0, 1fr); }
.lobby-left, .lobby-right { min-width: 0; }
.lobby-left > *, .lobby-right > * { min-width: 0; }

/* Copy code / Invite link share a row, wrap when they must, and are allowed
   to shrink — flex items default to min-width:auto, which is what let them
   run past the edge of the card. */
.room-actions { flex-wrap: wrap; }
.room-actions .btn { flex: 1 1 132px; min-width: 0; }

/* Long labels wrap inside the button instead of overflowing it. */
.room-card .btn { white-space: normal; overflow-wrap: anywhere; }
.btn-wide { min-width: 0; }

/* The optional buttons sit together as one block with an even rhythm,
   rather than a ragged stack of margins that changes shape depending on
   which of them happen to be showing. */
.room-extra { display: grid; gap: 8px; }
.room-extra:empty { display: none; }
.room-extra .btn-wide { margin-top: 0; }

/* Breathing room around the pieces of the card, in a consistent order. */
.room-card .btn-start { margin-top: 12px; }
.room-card .waiting-msg { margin: 10px 0 2px; }
.room-card .room-public-row { margin-top: 12px; }

/* The trailing letter-space pushed the code off-centre in its box. */
.room-code { text-indent: 12px; }

/* The odds pill is a button now — short, and it opens the breakdown. */
.wl-odds { border: 1px solid transparent; cursor: pointer; font-family: inherit; }
.wl-odds:hover { border-color: var(--brand); }

/* ══════════ Batch 35 — the word-list box, and a cleaner tool bar ══════════ */

/* The odds pill made this row too long for a 240px card and the trash button
   fell off the end (the card clips its overflow). Let the row wrap instead:
   the actions drop to their own line and stay right-aligned. */
.wl-meta { flex-wrap: wrap; row-gap: 6px; }
.wl-meta .cnt { min-width: 0; }
.wl-actions { margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }

/* ── The drawing tools, rebuilt ──
   Four chips on one bar — tools, brush sizes, undo/clear, colours — spread
   across a bar exactly as wide as the drawing above it. The hairline
   separators are gone; the chips group things far more clearly. */
@media (min-width: 1081px) {
  body.in-game .canvas-card .toolbar {
    justify-content: space-between;
    align-items: center;
    margin: 0 auto;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 16px;
    box-shadow: var(--shadow-sm);
  }
  body.in-game .canvas-card .toolbar .tool-sep { display: none; }

  body.in-game .toolbar > .tool-group,
  body.in-game .toolbar > .size-dots,
  body.in-game .toolbar > .palette {
    background: var(--card-2);
    border-radius: 12px;
    padding: 6px var(--tb-chip, 12px);
  }
  body.in-game .toolbar > .palette { padding-top: 6px; padding-bottom: 6px; }

  /* The active tool reads clearly against the chip behind it. */
  body.in-game .tool-btn { background: transparent; }
  body.in-game .tool-btn:hover { background: var(--card); transform: none; }
  body.in-game .tool-btn.active { background: var(--brand-soft); border-color: var(--brand); }
  body.in-game .size-dot { background: transparent; }
  body.in-game .size-dot:hover { background: var(--card); transform: none; }
  body.in-game .size-dot.active { background: var(--brand-soft); border-color: var(--brand); }
}

/* ══════════ Batch 36 — type an exact number into a setting ══════════ */

/* The value beside a slider is a button in disguise: click it and type. */
.opt-val-typeable { cursor: text; border: 1px solid transparent; transition: border-color .15s, background .15s; }
.opt-val-typeable:hover { border-color: var(--brand); background: var(--brand-soft); }

.opt-val-input {
  width: 74px; max-width: 100%;
  background: var(--card); border: 2px solid var(--brand); border-radius: 99px;
  padding: 1px 9px; color: var(--ink);
  font-family: inherit; font-size: 0.78rem; font-weight: 800; text-align: center;
  outline: none;
}
/* No spinner arrows — they fight the pill shape. */
.opt-val-input::-webkit-outer-spin-button,
.opt-val-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ══════════ Batch 37 — the round-end frame hugs the drawing ══════════ */

/* The box was being sized from its width while its height was capped
   separately, so once the cap bit, the box grew wider than 4:3, the white
   filler showed either side and the border traced a frame larger than the
   picture. Let the image size itself instead: with both caps set and no
   forced width, an <img> keeps its own proportions and fits inside them —
   there is no leftover box to letterbox into. */
.re-image {
  /* In the stacked layout .re-body is a column, where a 60% flex-basis
     would size the HEIGHT — another way to end up off-ratio. */
  flex: 0 1 auto;
  aspect-ratio: auto;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(62vh, 620px);
  object-fit: contain;
  background: transparent;
  display: block;
}
@media (min-width: 861px) {
  .re-image { flex: 0 1 auto; max-width: 60%; }
}

/* The M badge explains itself on hover (title="Moderator"), so point at it
   with the cursor people expect for that. */
.mod-chip { cursor: help; }

/* ══════════ Batch 38 — the phone layout, rebuilt ══════════ */

/* This section is deliberately last. The phone breakpoint at the top of the
   file had been quietly overruled for a long time: every later batch declared
   the same properties unconditionally, at equal or higher specificity, so a
   390px screen was being laid out with desktop padding, desktop type and
   desktop density. Rather than unpick a thousand lines of history, the mobile
   rules now come last and say what they mean.

   Three things were actually broken, not merely cramped:

     · Every colour swatch rendered at the full width of the palette, one per
       line. Forty-six lines. The toolbar came out roughly seventeen thousand
       pixels tall and pushed the tools, the players and the chat off the
       bottom of a screen that could not scroll. That is fixed at its source
       (see the palette rule in Batch 29) and re-stated here.
     · body.in-game turns page scrolling off, so anything that did not fit was
       simply unreachable.
     · The chat sat inline and ate a third of the screen, on the screen with
       the least to spare. */

/* ── Safe areas ──
   index.html asks for viewport-fit=cover, which deliberately extends the page
   under the notch and the home indicator. Nothing compensated for that, so on
   any modern phone the top of the word bar sat under the status bar and the
   bottom of the toolbar under the home indicator. */
:root {
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
}

@media (max-width: 900px) {

  /* ── Room to breathe ──
     The whole point of the complaint. Smaller type and tighter boxes are not
     what makes a phone feel roomy — fewer things fighting for the same space
     is. Padding goes UP, not down; what comes down is how much is on screen
     at once. */
  #main { padding: 10px 12px calc(20px + var(--safe-b)); }
  .card { padding: 14px; border-radius: 16px; }
  .hero { padding: 16px 0 12px; }
  .home-grid { gap: 12px; }
  .modal { padding: 20px 16px calc(24px + var(--safe-b)); }

  /* The lobby is one column. It had been re-pinned to a fixed 360px sidebar
     plus a second column by a later batch, which alone needs more width than
     the phone has. */
  .lobby-grid,
  .lobby-grid.guest { grid-template-columns: minmax(0, 1fr); }
  .lobby-grid > *,
  .lobby-grid.guest > * { grid-column: 1; min-width: 0; }
  .players-card-lobby,
  .chat-card-lobby { grid-row: auto; min-height: 0; }
  .chat-card-lobby { max-height: 46vh; }

  /* ── The play screen ──
     One column that fits the screen exactly: word bar, canvas, tools, the
     player strip. Chat is a drawer rather than a fourth thing competing for
     the same vertical inch. */
  body.in-game #main {
    padding: calc(6px + var(--safe-t)) 8px calc(6px + var(--safe-b));
    /* A safety valve. The column is built to fit, but a very short screen, a
       large system font or an extra row of tools must never make part of the
       game unreachable — which is exactly what overflow:hidden did. */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  body.in-game #screen-game.active { display: flex; flex-direction: column; min-height: 0; }
  body.in-game .game-grid { display: flex; flex-direction: column; gap: 8px; flex: 1; min-height: 0; }

  /* Word bar: the one thing that must always be legible.
     Four things — the round, the player count, the word and the clock — do not
     fit across a phone, and the word was the one that lost: squeezed into a
     sliver and clipped mid-letter. Give it a line of its own underneath. */
  body.in-game .game-top {
    flex: 0 0 auto; padding: 8px 10px; margin-bottom: 0;
    flex-wrap: wrap; column-gap: 10px; row-gap: 6px;
  }
  body.in-game .game-top .word-wrap {
    order: 1; flex: 1 0 100%; min-height: 34px; max-width: 100%;
  }
  body.in-game .game-top .timer-wrap { margin-left: auto; }
  /* A long word used to wrap into a block of tiles three rows deep, which
     reads as a crossword rather than a word. Keep it to one line: the tiles
     are smaller, and a really long word scrolls sideways. */
  body.in-game .word-tiles {
    flex-wrap: nowrap; gap: 3px; max-width: 100%;
    overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none; padding-bottom: 2px;
  }
  body.in-game .word-tiles::-webkit-scrollbar { display: none; }
  body.in-game .tile {
    min-width: 18px; height: 30px; font-size: 0.95rem;
    padding-left: 3px; padding-right: 3px; flex: 0 0 auto;
  }
  body.in-game .timer-wrap, body.in-game .timer-ring { width: 44px; height: 44px; }
  body.in-game .round-pill { font-size: 0.8rem; padding: 5px 12px; }

  /* Canvas: as big as the width allows, and it goes first. */
  body.in-game .canvas-card {
    order: 1; flex: 0 0 auto; min-height: 0;
    padding: 0; gap: 8px; background: transparent; border: 0; box-shadow: none;
  }
  body.in-game .canvas-card .canvas-frame { margin: 0 auto; width: 100%; max-width: 100%; }

  /* Players: a single scrolling strip under the canvas. It keeps a clear
     corner on the right, because that is where the floating chat button sits
     and a button that covers a player is a button in the way. */
  body.in-game .players-card {
    order: 3; flex: 0 0 auto; padding: 6px 8px;
    padding-right: 66px;
  }
  body.in-game .players-card .card-title-row { display: none; }

  /* ── Tools ──
     Two bands: the buttons, then the colours. Everything is a real touch
     target — 44px is the size a finger actually needs, and the old 34px
     buttons are why the tools felt fiddly even when they were on screen. */
  body.in-game .canvas-card .toolbar {
    order: 2;
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    width: 100%; max-width: 100%; min-width: 0;
    gap: 10px; padding: 10px 8px;
    background: var(--card); border: 1px solid var(--line); border-radius: 16px;
  }
  body.in-game .toolbar > * { flex-shrink: 1; }
  body.in-game .toolbar .tool-sep { display: none; }

  body.in-game .toolbar .tool-group {
    display: flex; flex-wrap: wrap; justify-content: center;
    /* Tight enough that the seven drawing tools stay on one line at 390px
       (7 × 44 + 6 × 6 = 344 in 346 of usable width) instead of stranding the
       last one on a row of its own, which made the bar look accidental. */
    gap: 6px;
    padding: 0; background: none; border: 0;
  }
  body.in-game .tool-btn {
    /* 44px is the target; the shrink is what stops a 375px screen breaking the
       row for the sake of a single pixel and stranding the last tool on a line
       of its own. It never goes below 40, which is still a real target. */
    flex: 0 1 44px;
    width: 44px; height: 44px; min-width: 40px; min-height: 44px;
    border-radius: 12px; font-size: 1.15rem;
  }
  body.in-game .size-dots {
    display: flex; flex-wrap: nowrap; justify-content: center; gap: 8px;
    padding: 0; background: none; border: 0;
  }
  body.in-game .size-dot { width: 40px; height: 40px; min-width: 40px; }
  body.in-game .tool-sep { display: none; }

  /* ── The colours ──
     Forty-five colours are three designed families of fifteen — darks,
     brights, pastels — so they stay three rows, and a row stays a family.
     Fifteen touch-sized swatches are wider than a phone, so the strip
     scrolls sideways rather than either shrinking the swatches to pinheads
     or reflowing the families into a soup. */
  body.in-game .toolbar > .palette {
    flex: 1 1 100%;            /* always its own band, never beside the tools */
    display: grid;
    grid-template-columns: repeat(15, 30px);
    grid-auto-rows: 30px;
    gap: 5px;
    justify-content: start;
    max-width: 100%;
    min-width: 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    padding-bottom: 2px;
  }
  body.in-game .toolbar > .palette::-webkit-scrollbar { display: none; }
  body.in-game .toolbar > .palette .swatch {
    width: 30px; height: 30px; min-width: 30px;
    border-radius: 7px; aspect-ratio: auto;
  }
  /* The custom-colour button is the 46th swatch, so left to itself it starts
     a fourth row for one button. Pin it to its own full-height column at the
     start instead: three rows of fifteen for the three families, and a tall
     custom-colour key beside them that stays put while the rest scrolls. */
  body.in-game .toolbar > .palette {
    grid-template-columns: 34px repeat(15, 30px);
    grid-template-rows: repeat(3, 30px);
  }
  body.in-game .toolbar > .palette .swatch.rainbow {
    grid-column: 1; grid-row: 1 / -1;
    width: 34px; height: auto; min-width: 34px;
    position: sticky; left: 0; z-index: 2;
    box-shadow: 6px 0 10px -6px rgba(0, 0, 0, .4);
  }

  /* ── Chat is a drawer ──
     It used to sit in the column and take a third of the screen, on the
     screen with the least to give. The drawer, its toggle and its close
     button all already existed — they were just scoped to fullscreen only. */
  body.in-game .chat-card {
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 220;
    width: min(360px, 92vw); height: 100%; min-height: 0;
    border-radius: 18px 0 0 18px;
    padding: calc(14px + var(--safe-t)) 14px calc(14px + var(--safe-b));
    transform: translateX(105%); transition: transform .25s ease;
    box-shadow: -10px 0 30px rgba(0, 0, 0, .22);
  }
  body.in-game .chat-card.open { transform: none; }
  body.in-game .chat-head .chat-close { display: block; }
  body.in-game .float-chat-toggle {
    display: flex; align-items: center; justify-content: center;
    right: calc(14px + var(--safe-r)); bottom: calc(14px + var(--safe-b));
    width: 54px; height: 54px; padding: 0; border-radius: 50%;
  }
  /* Guessing is the game, so the box you type into is never small. */
  body.in-game .chat-input-row input { font-size: 16px; height: 46px; }
  body.in-game .send-btn { width: 54px; height: 46px; }

  /* ── The word picker ──
     It lives inside the canvas frame, so it was capped at 62% of a box that
     the toolbar bug had already squashed to 320x240 — five words in about a
     hundred pixels of scroll. It now gets the whole frame, scrolls if it
     needs to, and sits above the floating like/skip buttons instead of
     underneath them. */
  .canvas-overlay { padding: 14px 12px; z-index: 30; }
  #overlay-choice { z-index: 32; }
  #overlay-choice .word-choice-grid {
    max-height: none; width: 100%;
    display: flex; flex-direction: column; gap: 8px;
    overflow-y: auto; overscroll-behavior: contain;
  }
  #overlay-choice .word-choice-grid { gap: 6px; }
  #overlay-choice .word-choice {
    /* All five choices plus the heading have to fit inside the canvas frame
       without scrolling — a word you cannot see is a word you cannot pick. */
    width: 100%; min-height: 44px; padding: 10px 14px; font-size: 1rem;
  }
  #overlay-choice h2 { font-size: 1.05rem; margin-bottom: 8px; }
  /* The like, skip and fullscreen buttons used to paint over the picker,
     because they sit at z-index 12 and the overlay sat at 10. Raising the
     overlay is the whole fix — hiding the buttons instead would hide them for
     the entire round, since #overlay-choice is always in the DOM and only its
     inline display changes. */

  /* Floating buttons clear the home indicator. */
  .float-actions { bottom: calc(10px + var(--safe-b)); }
  .toast, .invite-toast { bottom: calc(14px + var(--safe-b)); max-width: min(94vw, 420px); }

  /* Fullscreen mode gets the same insets. */
  body.focus-mode #screen-game {
    padding: calc(6px + var(--safe-t)) calc(6px + var(--safe-r))
             calc(6px + var(--safe-b)) calc(6px + var(--safe-l));
  }
}

/* ── Landscape on a phone ──
   Height is the scarce thing, not width. The canvas is capped by height and
   the column is allowed to scroll, rather than everything being crushed into
   a few hundred pixels. */
@media (max-width: 900px) and (orientation: landscape) and (max-height: 520px) {
  /* A phone on its side is wide and very short, so stacking canvas-over-tools
     is the wrong shape entirely — it was pushing the colours off the bottom.
     Put the tools BESIDE the drawing and the height problem disappears. */
  body.in-game .game-top { padding: 4px 8px; row-gap: 2px; }
  body.in-game .game-top .word-wrap { min-height: 26px; }
  body.in-game .timer-wrap, body.in-game .timer-ring { width: 34px; height: 34px; }
  body.in-game .tile { height: 24px; min-width: 16px; font-size: 0.85rem; }

  body.in-game .canvas-card {
    flex-direction: row; align-items: center; justify-content: center;
    gap: 8px; flex: 1 1 auto; min-height: 0;
  }
  /* With aspect-ratio set, a definite HEIGHT is what derives the width.
     width:auto with only a max-height let it shrink-to-fit to nothing —
     which is how this ended up a three-pixel canvas. */
  body.in-game .canvas-card .canvas-frame {
    height: 100%; width: auto; max-width: 64%; max-height: 100%; margin: 0;
  }
  body.in-game .canvas-card .toolbar {
    flex: 0 1 auto; width: auto; max-width: 36%;
    align-content: center; gap: 8px; padding: 8px;
  }
  body.in-game .tool-btn { flex-basis: 40px; width: 40px; height: 40px; min-height: 40px; }
  body.in-game .size-dot { width: 34px; height: 34px; min-width: 34px; }
  body.in-game .toolbar > .palette {
    grid-template-columns: 28px repeat(15, 24px);
    grid-template-rows: repeat(3, 24px);
    gap: 4px;
  }
  body.in-game .toolbar > .palette .swatch { width: 24px; height: 24px; min-width: 24px; }
  body.in-game .toolbar > .palette .swatch.rainbow { width: 28px; min-width: 28px; }
  body.in-game .players-card { display: none; }   /* the strip is the first thing to go */
}

/* ── Short screens ──
   An iPhone SE is 667px tall. Word bar + a full-width 4:3 canvas + two bands
   of tools + the player strip does not fit in that, so the canvas gives up a
   little height rather than the tools disappearing under the fold. */
@media (max-width: 900px) and (max-height: 720px) and (orientation: portrait) {
  body.in-game .canvas-card .canvas-frame {
    height: 31dvh; width: auto; max-width: 100%; max-height: none;
  }
  body.in-game .canvas-card { align-items: center; }
  /* And everything else comes in a notch, so the last row of colours and the
     player strip stay above the fold rather than needing a scroll. */
  body.in-game .game-top { padding: 6px 8px; }
  body.in-game .tool-btn { flex-basis: 40px; width: 40px; height: 40px; min-height: 40px; }
  body.in-game .size-dot { width: 34px; height: 34px; min-width: 34px; }
  body.in-game .canvas-card .toolbar { gap: 8px; padding: 8px; }
  body.in-game .toolbar > .palette {
    grid-template-columns: 30px repeat(15, 26px);
    grid-template-rows: repeat(3, 26px);
    gap: 4px;
  }
  body.in-game .toolbar > .palette .swatch { width: 26px; height: 26px; min-width: 26px; }
  body.in-game .toolbar > .palette .swatch.rainbow { width: 30px; min-width: 30px; }
  body.in-game .players-card { padding: 4px 8px; }
}

/* ── Very small phones ──
   A 320px screen cannot take a 44px grid and a 30px palette at once. Give up
   a little size rather than letting anything overflow. */
@media (max-width: 360px) {
  body.in-game #main { padding-left: 6px; padding-right: 6px; }
  body.in-game .tool-btn { width: 40px; height: 40px; min-width: 40px; min-height: 40px; }
  body.in-game .size-dot { width: 36px; height: 36px; min-width: 36px; }
  body.in-game .toolbar { gap: 8px; padding: 8px; }
  body.in-game .toolbar > .palette {
    grid-template-columns: repeat(15, 28px); grid-auto-rows: 28px;
  }
  body.in-game .toolbar > .palette .swatch { width: 28px; height: 28px; min-width: 28px; }
}

/* ── Touch devices of any width ──
   Hover is not a thing a finger can do, so the swatch grow-on-hover only ever
   fired after a tap and left the wrong colour looking selected. */
@media (hover: none) {
  .swatch:hover { transform: none; }
  .tool-btn, .size-dot, .swatch, .icon-btn, .mini-btn { -webkit-tap-highlight-color: transparent; }
}

/* ══════════ Batch 39 — the gaps Batch 38 left ══════════ */

/* ── The canvas keeps its shape in fullscreen ──
   Batch 38's `body.in-game .canvas-card .canvas-frame { width: 100% }` is more
   specific than the fullscreen rule, and a definite width plus flex-sized
   height over-determines the box: aspect-ratio is ignored and the drawing
   stretches. Fullscreen sizes itself; stay out of its way. */
@media (max-width: 900px) {
  /* Fullscreen is not an edge case on a phone: a Discord Activity turns it on
     by itself, so this IS the phone layout inside Discord.
     The frame is `flex: 1` of the canvas card, but the card had no height of
     its own — it sized to its contents, which is the frame. Each waited for
     the other and the drawing collapsed to three pixels by two. Give the card
     the height and the frame can take its share of it. */
  body.in-game.focus-mode .game-grid { flex: 1 1 auto; min-height: 0; }
  body.in-game.focus-mode .canvas-card {
    flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    padding: 0; background: transparent; border: 0; box-shadow: none;
  }
  /* fitCanvas() works out how wide the drawing may be and publishes it as
     --canvas-max; aspect-ratio then gives the height. One definite dimension
     is the only way a 4:3 box keeps its shape. */
  body.in-game.focus-mode .canvas-card .canvas-frame {
    flex: 0 0 auto;
    width: 100%; height: auto; max-height: none;
    max-width: var(--canvas-max, 100%);
    margin: 0 auto; align-self: center;
  }
  body.in-game.focus-mode .canvas-card .toolbar { flex: 0 0 auto; }
  /* Fullscreen lifts the play screen out of #main with position:fixed, so
     #main's scroll safety valve never applies to it. Give it its own. */
  body.focus-mode #screen-game { overflow-y: auto; overscroll-behavior-y: contain; }
}

/* ── The 901–1080px band ──
   Too wide for the phone layout, too narrow for the desktop toolbar sizing
   (fitToolbar bails out below 1081), and pinned to one unscrollable viewport
   by the same two rules that trapped the phone. A tablet in portrait lands
   here. At minimum, nothing may be unreachable. */
@media (min-width: 901px) and (max-width: 1080px) {
  body.in-game #main { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  body.in-game .toolbar { flex-wrap: wrap; justify-content: center; gap: 10px; }
  body.in-game .toolbar > .palette { min-width: 0; max-width: 100%; }
  body.in-game .tool-btn { width: 40px; height: 40px; }
  body.in-game .size-dot { width: 36px; height: 36px; }
}

/* ── The soft keyboard ──
   The chat drawer is position:fixed, and on iOS a fixed box is anchored to the
   layout viewport, which does not shrink when the keyboard opens. The guess
   box — the thing the player is typing into — ends up underneath it. app.js
   measures the gap with visualViewport and publishes it here. */
@media (max-width: 900px) {
  body.in-game .chat-card {
    padding-bottom: calc(14px + var(--safe-b) + var(--kb, 0px));
    transition: transform .25s ease, padding-bottom .18s ease;
  }
}

/* ── Touch targets outside the toolbar ──
   Batch 38 fixed the drawing tools and stopped there. Everything else on a
   phone was still built for a mouse — including the close button on the chat
   drawer, which at 23 pixels was the only way out of it. */
@media (max-width: 900px) {
  .mini-btn { padding: 10px 14px; font-size: 0.85rem; min-height: 40px; }
  .chat-head .chat-close { min-width: 44px; min-height: 44px; padding: 0 12px; font-size: 1rem; }
  .modal-x { width: 44px; height: 44px; font-size: 1.1rem; }
  .icon-btn { width: 42px; height: 42px; }
  .tab { padding: 12px 14px; min-height: 44px; }
  .lib-tag { padding: 9px 14px; min-height: 38px; }
  .float-btn { padding: 11px 15px; min-height: 44px; }
  .p-row .addf { width: 30px; height: 30px; }
  .p-row .votekick { padding: 6px 10px; min-height: 32px; }
  .avatar-emojis button { min-width: 44px; min-height: 44px; }
  .theme-chip { min-height: 44px; }
  .word-choice { min-height: 44px; }
  .send-btn { min-height: 46px; }
}

/* ── iOS stops zooming the page when an input is focused ──
   Safari zooms whenever the focused field is under 16px, and two later, more
   specific rules were still dropping below it. */
@media (max-width: 900px) {
  input, textarea, select,
  .input, .chat-input-row input, .lib-search .input, .opt-val-input {
    font-size: 16px;
  }
}

/* ── Hover is not something a finger does ──
   A tap leaves :hover stuck on, so every hover transform stayed applied to
   whatever was touched last — the button you pressed kept floating. */
@media (hover: none) {
  .tool-btn:hover, .size-dot:hover, .float-btn:hover, .swatch:hover,
  .avatar-emojis button:hover, .avatar-bubble:hover, .scene-card:hover,
  .room-pill-btn:hover, .icon-btn:hover, .mini-btn:hover, .theme-chip:hover,
  .word-choice:hover, .btn:hover, .p-row:hover {
    transform: none;
  }
}

/* ── The player strip scrolls one way, not two ──
   The phone strip is a single horizontal row, but a later unconditional rule
   left a vertical scroll axis on it as well, so it could be dragged up and
   down over nothing. */
@media (max-width: 900px) {
  body.in-game .players-list {
    flex: 0 0 auto; overflow-y: hidden; overflow-x: auto;
    flex-direction: row; flex-wrap: nowrap;
  }
}
