/* ═══════════════════════════════════════════════════════════════════════════
   Design tokens
   Every color comes from these variables. A theme (body[data-theme]) sets them
   for light mode and again inside the dark-mode media query; a color vision
   setting (body[data-vision]) then overrides the colors that carry meaning.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Classic, light: Nord "Snow Storm" surfaces, Polar Night text, Frost accents. */
body {
  --bg: #eceff4;            --bg-rgb: 236, 239, 244;
  --surface: #ffffff;       --surface-2: #e5e9f0;
  --ink: #2e3440;           --muted: #4c566a;
  --border: #d8dee9;
  --link: #3b5f8a;          --link-rgb: 59, 95, 138;
  --accent: #4c6a92;        --accent-rgb: 76, 106, 146;   --accent-ink: #ffffff; --accent-hover: #3f5a7d;
  --accent2: #5e7f45;       --accent2-ink: #ffffff;        --accent2-hover: #4f6b3a;
  --danger: #a5414a;        --danger-rgb: 165, 65, 74;
  --success-rgb: 79, 115, 56;
  --warning-rgb: 235, 203, 139;
  --secondary-rgb: 76, 86, 106;
  --mark: #4c6f9c;          --mark-ink: #ffffff;
  --won: #4f7338;           --won-ink: #ffffff;
  --free: #ebcb8b;          --free-ink: #2e3440;
  --cell: #ffffff;          --cell-border: #d8dee9;
  --pip-off: #c3cad6;       --pip-on: #5e81ac;
  --b: #bf616a; --i: #d08770; --n: #a3be8c; --g: #81a1c1; --o: #b48ead;
  --reward-bg: #fff6df;     --reward-border: #ebcb8b;
  --danger-emphasis: #7d2a31; --danger-subtle: #f6e1e3; --danger-border: #e3b2b7;
  --info-emphasis: #2e4a6b;   --info-subtle: #e1ebf5;   --info-border: #b5cbe3;
  --veil: 0.72;
  --stripe: rgba(0, 0, 0, .18);
  --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%232e3440' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  --btn-radius: .5rem;
}

/* Classic, dark: Nord. */
@media (prefers-color-scheme: dark) {
  body:where(:not([data-mode="light"])) {
    --bg: #2e3440;          --bg-rgb: 46, 52, 64;
    --surface: #3b4252;     --surface-2: #434c5e;
    --ink: #eceff4;         --muted: #b8c0ce;
    --border: #4c566a;
    --link: #88c0d0;        --link-rgb: 136, 192, 208;
    --accent: #88c0d0;      --accent-rgb: 136, 192, 208;  --accent-ink: #2e3440; --accent-hover: #9fcfdc;
    --accent2: #a3be8c;     --accent2-ink: #2e3440;       --accent2-hover: #b4cc9f;
    --danger: #bf616a;      --danger-rgb: 191, 97, 106;
    --success-rgb: 163, 190, 140;
    --warning-rgb: 235, 203, 139;
    --secondary-rgb: 76, 86, 106;
    --mark: #4c6f9c;        --mark-ink: #ffffff;
    --won: #a3be8c;         --won-ink: #2e3440;
    --free: #ebcb8b;        --free-ink: #2e3440;
    --cell: #3b4252;        --cell-border: #4c566a;
    --pip-off: #7b88a1;     --pip-on: #88c0d0;
    --reward-bg: #434c5e;   --reward-border: #ebcb8b;
    --danger-emphasis: #f0c4c8; --danger-subtle: #4a3439; --danger-border: #7a4a50;
    --info-emphasis: #cfe6ee;   --info-subtle: #364559;   --info-border: #4f6b86;
    --veil: 0.6;
    --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23eceff4' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  }
}
/* Same as above when the viewer picked dark mode. */
body:where([data-mode="dark"]) {
    --bg: #2e3440;          --bg-rgb: 46, 52, 64;
    --surface: #3b4252;     --surface-2: #434c5e;
    --ink: #eceff4;         --muted: #b8c0ce;
    --border: #4c566a;
    --link: #88c0d0;        --link-rgb: 136, 192, 208;
    --accent: #88c0d0;      --accent-rgb: 136, 192, 208;  --accent-ink: #2e3440; --accent-hover: #9fcfdc;
    --accent2: #a3be8c;     --accent2-ink: #2e3440;       --accent2-hover: #b4cc9f;
    --danger: #bf616a;      --danger-rgb: 191, 97, 106;
    --success-rgb: 163, 190, 140;
    --warning-rgb: 235, 203, 139;
    --secondary-rgb: 76, 86, 106;
    --mark: #4c6f9c;        --mark-ink: #ffffff;
    --won: #a3be8c;         --won-ink: #2e3440;
    --free: #ebcb8b;        --free-ink: #2e3440;
    --cell: #3b4252;        --cell-border: #4c566a;
    --pip-off: #7b88a1;     --pip-on: #88c0d0;
    --reward-bg: #434c5e;   --reward-border: #ebcb8b;
    --danger-emphasis: #f0c4c8; --danger-subtle: #4a3439; --danger-border: #7a4a50;
    --info-emphasis: #cfe6ee;   --info-subtle: #364559;   --info-border: #4f6b86;
    --veil: 0.6;
    --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23eceff4' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  }


/* Halloween, light: parchment with pumpkin orange and witchy purple. */
body[data-theme="halloween"] {
  --bg: #f8efe3;            --bg-rgb: 248, 239, 227;
  --surface: #fffaf3;       --surface-2: #f1e3d1;
  --ink: #2a1c33;           --muted: #65537a;
  --border: #e0c9ad;
  --link: #8a3f00;          --link-rgb: 138, 63, 0;
  --accent: #c14c00;        --accent-rgb: 193, 76, 0;     --accent-ink: #ffffff; --accent-hover: #a34000;
  --accent2: #6a3d8a;       --accent2-ink: #ffffff;        --accent2-hover: #583173;
  --danger: #a3222e;        --danger-rgb: 163, 34, 46;
  --success-rgb: 46, 125, 80;
  --warning-rgb: 255, 166, 77;
  --secondary-rgb: 101, 83, 122;
  --mark: #c25200;          --mark-ink: #ffffff;
  --won: #2e7d50;           --won-ink: #ffffff;
  --free: #2a1c33;          --free-ink: #ffb35c;
  --cell: #fffaf3;          --cell-border: #e0c9ad;
  --pip-off: #dccab4;       --pip-on: #e0620d;
  --b: #e0620d; --i: #6a3d8a; --n: #4f8a3c; --g: #f08c2e; --o: #3b2a52;
  --reward-bg: #fde6cc;     --reward-border: #f08c2e;
  --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%232a1c33' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  --btn-radius: .35rem;
}
@media (prefers-color-scheme: dark) {
  body:where(:not([data-mode="light"]))[data-theme="halloween"] {
    --bg: #15101d;          --bg-rgb: 21, 16, 29;
    --surface: #221a2e;     --surface-2: #2d2240;
    --ink: #f4ead9;         --muted: #c3b2d4;
    --border: #46345e;
    --link: #ffa24d;        --link-rgb: 255, 162, 77;
    --accent: #ff7a1a;      --accent-rgb: 255, 122, 26;   --accent-ink: #1c0d00; --accent-hover: #ff8f3d;
    --accent2: #9b59c6;     --accent2-ink: #ffffff;       --accent2-hover: #a96bd1;
    --danger: #ff5c6c;      --danger-rgb: 255, 92, 108;
    --success-rgb: 126, 217, 87;
    --warning-rgb: 255, 166, 77;
    --secondary-rgb: 70, 52, 94;
    --mark: #ff7a1a;        --mark-ink: #1c0d00;
    --won: #7ed957;         --won-ink: #10200a;
    --free: #9b59c6;        --free-ink: #ffffff;
    --cell: #221a2e;        --cell-border: #46345e;
    --pip-off: #7d679a;     --pip-on: #ff7a1a;
    --i: #a970d6; --o: #8a6bb8;
    --stripe: rgba(255, 255, 255, .25);
    --reward-bg: #2d2240;   --reward-border: #ff7a1a;
    --danger-emphasis: #ffc9cf; --danger-subtle: #3d1a24; --danger-border: #7a2e3c;
    --info-emphasis: #f4ead9;   --info-subtle: #2d2240;   --info-border: #46345e;
    --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23f4ead9' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  }
}
/* Same as above when the viewer picked dark mode. */
body:where([data-mode="dark"])[data-theme="halloween"] {
    --bg: #15101d;          --bg-rgb: 21, 16, 29;
    --surface: #221a2e;     --surface-2: #2d2240;
    --ink: #f4ead9;         --muted: #c3b2d4;
    --border: #46345e;
    --link: #ffa24d;        --link-rgb: 255, 162, 77;
    --accent: #ff7a1a;      --accent-rgb: 255, 122, 26;   --accent-ink: #1c0d00; --accent-hover: #ff8f3d;
    --accent2: #9b59c6;     --accent2-ink: #ffffff;       --accent2-hover: #a96bd1;
    --danger: #ff5c6c;      --danger-rgb: 255, 92, 108;
    --success-rgb: 126, 217, 87;
    --warning-rgb: 255, 166, 77;
    --secondary-rgb: 70, 52, 94;
    --mark: #ff7a1a;        --mark-ink: #1c0d00;
    --won: #7ed957;         --won-ink: #10200a;
    --free: #9b59c6;        --free-ink: #ffffff;
    --cell: #221a2e;        --cell-border: #46345e;
    --pip-off: #7d679a;     --pip-on: #ff7a1a;
    --i: #a970d6; --o: #8a6bb8;
    --stripe: rgba(255, 255, 255, .25);
    --reward-bg: #2d2240;   --reward-border: #ff7a1a;
    --danger-emphasis: #ffc9cf; --danger-subtle: #3d1a24; --danger-border: #7a2e3c;
    --info-emphasis: #f4ead9;   --info-subtle: #2d2240;   --info-border: #46345e;
    --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23f4ead9' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  }


/* Christmas, light: fresh snow with holly red, pine green and gold. */
body[data-theme="christmas"] {
  --bg: #f7f4ee;            --bg-rgb: 247, 244, 238;
  --surface: #ffffff;       --surface-2: #efe9df;
  --ink: #1f2a24;           --muted: #56645b;
  --border: #e2d8c8;
  --link: #a3101b;          --link-rgb: 163, 16, 27;
  --accent: #b3121e;        --accent-rgb: 179, 18, 30;    --accent-ink: #ffffff; --accent-hover: #950f19;
  --accent2: #1d6b3e;       --accent2-ink: #ffffff;        --accent2-hover: #175832;
  --danger: #a3101b;        --danger-rgb: 163, 16, 27;
  --success-rgb: 29, 107, 62;
  --warning-rgb: 212, 167, 44;
  --secondary-rgb: 86, 100, 91;
  --mark: #b3121e;          --mark-ink: #ffffff;
  --won: #1d6b3e;           --won-ink: #ffffff;
  --free: #d4a72c;          --free-ink: #1f2a24;
  --cell: #ffffff;          --cell-border: #e2d8c8;
  --pip-off: #ddd3c4;       --pip-on: #b3121e;
  --b: #b3121e; --i: #1d6b3e; --n: #d4a72c; --g: #b3121e; --o: #1d6b3e;
  --reward-bg: #fbf1d6;     --reward-border: #d4a72c;
  --veil: 0.78;
  --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%231f2a24' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  --btn-radius: 999px;
}
@media (prefers-color-scheme: dark) {
  body:where(:not([data-mode="light"]))[data-theme="christmas"] {
    --bg: #0e1c16;          --bg-rgb: 14, 28, 22;
    --surface: #16291f;     --surface-2: #1f3629;
    --ink: #f3eee4;         --muted: #b7c6bb;
    --border: #2f4d3c;
    --link: #f0c75e;        --link-rgb: 240, 199, 94;
    --accent: #e03a45;      --accent-rgb: 224, 58, 69;    --accent-ink: #ffffff; --accent-hover: #e8545e;
    --accent2: #2f9e5b;     --accent2-ink: #ffffff;       --accent2-hover: #38b067;
    --danger: #ff6b74;      --danger-rgb: 255, 107, 116;
    --success-rgb: 47, 158, 91;
    --warning-rgb: 240, 199, 94;
    --secondary-rgb: 47, 77, 60;
    --mark: #e03a45;        --mark-ink: #ffffff;
    --won: #f0c75e;         --won-ink: #1a1405;
    --free: #2f9e5b;        --free-ink: #ffffff;
    --cell: #16291f;        --cell-border: #2f4d3c;
    --pip-off: #5d8a70;     --pip-on: #f0c75e;
    --b: #ef4f5a; --i: #3fbf73; --n: #f0c75e; --g: #ef4f5a; --o: #3fbf73;
    --reward-bg: #1f3629;   --reward-border: #f0c75e;
    --danger-emphasis: #ffd0d3; --danger-subtle: #3a1a1d; --danger-border: #7a2e34;
    --info-emphasis: #f3eee4;   --info-subtle: #1f3629;   --info-border: #2f4d3c;
    --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23f3eee4' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  }
}
/* Same as above when the viewer picked dark mode. */
body:where([data-mode="dark"])[data-theme="christmas"] {
    --bg: #0e1c16;          --bg-rgb: 14, 28, 22;
    --surface: #16291f;     --surface-2: #1f3629;
    --ink: #f3eee4;         --muted: #b7c6bb;
    --border: #2f4d3c;
    --link: #f0c75e;        --link-rgb: 240, 199, 94;
    --accent: #e03a45;      --accent-rgb: 224, 58, 69;    --accent-ink: #ffffff; --accent-hover: #e8545e;
    --accent2: #2f9e5b;     --accent2-ink: #ffffff;       --accent2-hover: #38b067;
    --danger: #ff6b74;      --danger-rgb: 255, 107, 116;
    --success-rgb: 47, 158, 91;
    --warning-rgb: 240, 199, 94;
    --secondary-rgb: 47, 77, 60;
    --mark: #e03a45;        --mark-ink: #ffffff;
    --won: #f0c75e;         --won-ink: #1a1405;
    --free: #2f9e5b;        --free-ink: #ffffff;
    --cell: #16291f;        --cell-border: #2f4d3c;
    --pip-off: #5d8a70;     --pip-on: #f0c75e;
    --b: #ef4f5a; --i: #3fbf73; --n: #f0c75e; --g: #ef4f5a; --o: #3fbf73;
    --reward-bg: #1f3629;   --reward-border: #f0c75e;
    --danger-emphasis: #ffd0d3; --danger-subtle: #3a1a1d; --danger-border: #7a2e34;
    --info-emphasis: #f3eee4;   --info-subtle: #1f3629;   --info-border: #2f4d3c;
    --select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23f3eee4' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  }


/* ── Color vision ─────────────────────────────────────────────────────────────
   Swap the colors that carry meaning for pairs that stay apart. Shapes (the
   stamp on marked cells, stripes on the winning line, hollow vs filled dots)
   back up color everywhere, so nothing depends on color alone. */

/* Protanopia / deuteranopia: blue vs orange (Okabe-Ito). */
body[data-vision="redgreen"] {
  --mark: #0072b2; --mark-ink: #ffffff;
  --won: #e69f00;  --won-ink: #1a1a1a;
  --free: #9aa3ad; --free-ink: #111111;
  --pip-on: #0072b2;
  --accent2: #0072b2; --accent2-ink: #ffffff; --accent2-hover: #005f94;
  --success-rgb: 0, 114, 178;
  --danger: #d55e00; --danger-rgb: 213, 94, 0;
}
/* Tritanopia: vermillion vs bluish green. */
body[data-vision="blueyellow"] {
  --mark: #d55e00; --mark-ink: #ffffff;
  --won: #009e73;  --won-ink: #ffffff;
  --free: #9aa3ad; --free-ink: #111111;
  --pip-on: #d55e00;
  --accent2: #009e73; --accent2-ink: #ffffff; --accent2-hover: #008561;
  --success-rgb: 0, 158, 115;
  --warning-rgb: 204, 121, 167;
}
/* High contrast: black, white and one strong highlight. */
body[data-vision="contrast"] {
  --bg: #ffffff; --bg-rgb: 255, 255, 255; --surface: #ffffff; --surface-2: #f0f0f0;
  --ink: #000000; --muted: #222222; --border: #000000;
  --link: #0000c0; --link-rgb: 0, 0, 192;
  --accent: #000000; --accent-rgb: 0, 0, 0; --accent-ink: #ffffff; --accent-hover: #333333;
  --accent2: #000000; --accent2-ink: #ffffff; --accent2-hover: #333333;
  --mark: #000000; --mark-ink: #ffffff;
  --won: #ffd400;  --won-ink: #000000;
  --free: #ffffff; --free-ink: #000000;
  --cell: #ffffff; --cell-border: #000000;
  --pip-off: #000000; --pip-on: #000000;
  --reward-bg: #ffffff; --reward-border: #000000;
  --success-rgb: 0, 0, 0; --secondary-rgb: 0, 0, 0; --warning-rgb: 255, 212, 0;
  --b: #000000; --i: #000000; --n: #000000; --g: #000000; --o: #000000;
  --stripe: rgba(255, 255, 255, .4);
  --veil: 0.85;
}
@media (prefers-color-scheme: dark) {
  body:where(:not([data-mode="light"]))[data-vision="contrast"] {
    --bg: #000000; --bg-rgb: 0, 0, 0; --surface: #000000; --surface-2: #1a1a1a;
    --ink: #ffffff; --muted: #e6e6e6; --border: #ffffff;
    --link: #8ab4ff; --link-rgb: 138, 180, 255;
    --accent: #ffffff; --accent-rgb: 255, 255, 255; --accent-ink: #000000; --accent-hover: #dddddd;
    --accent2: #ffffff; --accent2-ink: #000000; --accent2-hover: #dddddd;
    --mark: #ffffff; --mark-ink: #000000;
    --free: #000000; --free-ink: #ffffff;
    --cell: #000000; --cell-border: #ffffff;
    --pip-off: #ffffff; --pip-on: #ffffff;
    --reward-bg: #000000; --reward-border: #ffffff;
    --success-rgb: 255, 255, 255; --secondary-rgb: 60, 60, 60;
    --b: #ffffff; --i: #ffffff; --n: #ffffff; --g: #ffffff; --o: #ffffff;
    --stripe: rgba(0, 0, 0, .22);
  }
  body:where(:not([data-mode="light"]))[data-vision="contrast"] .cell.free.line { --stripe: rgba(255, 255, 255, .35); }
}
/* Same as above when the viewer picked dark mode. */
body:where([data-mode="dark"])[data-vision="contrast"] {
    --bg: #000000; --bg-rgb: 0, 0, 0; --surface: #000000; --surface-2: #1a1a1a;
    --ink: #ffffff; --muted: #e6e6e6; --border: #ffffff;
    --link: #8ab4ff; --link-rgb: 138, 180, 255;
    --accent: #ffffff; --accent-rgb: 255, 255, 255; --accent-ink: #000000; --accent-hover: #dddddd;
    --accent2: #ffffff; --accent2-ink: #000000; --accent2-hover: #dddddd;
    --mark: #ffffff; --mark-ink: #000000;
    --free: #000000; --free-ink: #ffffff;
    --cell: #000000; --cell-border: #ffffff;
    --pip-off: #ffffff; --pip-on: #ffffff;
    --reward-bg: #000000; --reward-border: #ffffff;
    --success-rgb: 255, 255, 255; --secondary-rgb: 60, 60, 60;
    --b: #ffffff; --i: #ffffff; --n: #ffffff; --g: #ffffff; --o: #ffffff;
    --stripe: rgba(0, 0, 0, .22);
  }
  body:where([data-mode="dark"])[data-vision="contrast"] .cell.free.line { --stripe: rgba(255, 255, 255, .35); }

body[data-vision="contrast"] .cell, body[data-vision="contrast"] .card, body[data-vision="contrast"] .mark-tile { border-width: 2px; }
body[data-vision="contrast"] .ball { color: var(--bg); text-shadow: none; }
body[data-vision="contrast"] .cell.free { border-color: var(--cell-border); }
body[data-vision="contrast"] .cell.free.line { --stripe: rgba(0, 0, 0, .35); }
@media (prefers-color-scheme: light) {
  body:where(:not([data-mode="dark"]))[data-vision="contrast"] .cell.line,
  body:where(:not([data-mode="dark"]))[data-vision="contrast"] .board-wrap.won .board,
  body:where(:not([data-mode="dark"]))[data-vision="contrast"] .mini.won { box-shadow: 0 0 0 2px #000; }
}
/* Same as above when the viewer picked light mode. */
body:where([data-mode="light"])[data-vision="contrast"] .cell.line,
  body:where([data-mode="light"])[data-vision="contrast"] .board-wrap.won .board,
  body:where([data-mode="light"])[data-vision="contrast"] .mini.won { box-shadow: 0 0 0 2px #000; }


/* ── Bootstrap, driven by the tokens ─────────────────────────────────────── */
body {
  --bs-body-bg: var(--bg);              --bs-body-color: var(--ink);
  --bs-emphasis-color: var(--ink);      --bs-heading-color: var(--ink);
  --bs-secondary-color: var(--muted);   --bs-tertiary-color: var(--muted);
  --bs-border-color: var(--border);     --bs-secondary-bg: var(--surface-2); --bs-tertiary-bg: var(--surface-2);
  --bs-link-color: var(--link);         --bs-link-hover-color: var(--link);
  --bs-link-color-rgb: var(--link-rgb); --bs-link-hover-color-rgb: var(--link-rgb);
  --bs-primary-rgb: var(--accent-rgb);  --bs-success-rgb: var(--success-rgb);
  --bs-danger-rgb: var(--danger-rgb);   --bs-warning-rgb: var(--warning-rgb);
  --bs-secondary-rgb: var(--secondary-rgb);
  --bs-danger-text-emphasis: var(--danger-emphasis); --bs-danger-bg-subtle: var(--danger-subtle); --bs-danger-border-subtle: var(--danger-border);
  --bs-info-text-emphasis: var(--info-emphasis);     --bs-info-bg-subtle: var(--info-subtle);     --bs-info-border-subtle: var(--info-border);
  background: var(--bg); color: var(--ink);
}
.card { --bs-card-bg: var(--surface); --bs-card-cap-bg: var(--surface-2); --bs-card-border-color: var(--border); --bs-card-color: var(--ink); }
.form-control, .form-select { background-color: var(--surface); color: var(--ink); border-color: var(--border); }
.form-control::placeholder { color: var(--muted); opacity: .75; }
.form-select { --bs-form-select-bg-img: var(--select-arrow); }
.form-control:focus, .form-select:focus, .form-check-input:focus {
  border-color: var(--accent); box-shadow: 0 0 0 .2rem rgba(var(--accent-rgb), .3); background-color: var(--surface); color: var(--ink);
}
.form-check-input { background-color: var(--surface); border-color: var(--muted); }
.form-check-input:checked { background-color: var(--accent); border-color: var(--accent); }
.text-body-secondary { color: var(--muted) !important; }
.badge.text-bg-success { background-color: var(--won) !important; color: var(--won-ink) !important; }
::selection { background: rgba(var(--accent-rgb), .35); color: var(--ink); }
.text-success { color: rgb(var(--success-rgb)) !important; }
.text-danger { color: var(--danger) !important; }

/* Buttons */
.btn { --bs-btn-border-radius: var(--btn-radius); --bs-btn-font-weight: 600; transition: background-color .15s, border-color .15s, box-shadow .15s, transform .1s; }
.btn:active { transform: translateY(1px); }
.btn-sm { --bs-btn-border-radius: var(--btn-radius); }
.btn-lg { --bs-btn-border-radius: var(--btn-radius); }
.btn-primary {
  --bs-btn-bg: var(--accent); --bs-btn-border-color: var(--accent); --bs-btn-color: var(--accent-ink);
  --bs-btn-hover-bg: var(--accent-hover); --bs-btn-hover-border-color: var(--accent-hover); --bs-btn-hover-color: var(--accent-ink);
  --bs-btn-active-bg: var(--accent-hover); --bs-btn-active-border-color: var(--accent-hover); --bs-btn-active-color: var(--accent-ink);
  --bs-btn-disabled-bg: var(--accent); --bs-btn-disabled-border-color: var(--accent); --bs-btn-disabled-color: var(--accent-ink);
  --bs-btn-focus-shadow-rgb: var(--accent-rgb);
}
.btn-success {
  --bs-btn-bg: var(--accent2); --bs-btn-border-color: var(--accent2); --bs-btn-color: var(--accent2-ink);
  --bs-btn-hover-bg: var(--accent2-hover); --bs-btn-hover-border-color: var(--accent2-hover); --bs-btn-hover-color: var(--accent2-ink);
  --bs-btn-active-bg: var(--accent2-hover); --bs-btn-active-border-color: var(--accent2-hover); --bs-btn-active-color: var(--accent2-ink);
}
.btn-outline-primary {
  --bs-btn-color: var(--link); --bs-btn-border-color: var(--accent);
  --bs-btn-hover-bg: var(--accent); --bs-btn-hover-border-color: var(--accent); --bs-btn-hover-color: var(--accent-ink);
  --bs-btn-active-bg: var(--accent); --bs-btn-active-border-color: var(--accent); --bs-btn-active-color: var(--accent-ink);
}
.btn-outline-secondary {
  --bs-btn-color: var(--ink); --bs-btn-border-color: var(--border);
  --bs-btn-hover-bg: var(--surface-2); --bs-btn-hover-border-color: var(--muted); --bs-btn-hover-color: var(--ink);
  --bs-btn-active-bg: var(--surface-2); --bs-btn-active-border-color: var(--muted); --bs-btn-active-color: var(--ink);
}
.btn-outline-danger {
  --bs-btn-color: var(--danger); --bs-btn-border-color: var(--danger);
  --bs-btn-hover-bg: var(--danger); --bs-btn-hover-border-color: var(--danger); --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: var(--danger); --bs-btn-active-border-color: var(--danger); --bs-btn-active-color: #fff;
}

/* Halloween buttons: squarer, bolder, with an eerie glow. */
body[data-theme="halloween"] .btn { letter-spacing: .02em; }
body[data-theme="halloween"] .btn-primary:hover,
body[data-theme="halloween"] .btn-success:hover { box-shadow: 0 0 0 2px rgba(var(--accent-rgb), .25), 0 0 18px rgba(var(--accent-rgb), .55); }
body[data-theme="halloween"] .btn-primary { background-image: linear-gradient(180deg, rgba(255,255,255,.12), rgba(0,0,0,.12)); }

/* Christmas buttons: rounded, with a candy cane stripe on the main button. */
body[data-theme="christmas"] .btn-primary {
  background-image: repeating-linear-gradient(135deg, rgba(255,255,255,.16) 0 8px, transparent 8px 16px);
}
body[data-theme="christmas"] .btn-success { box-shadow: inset 0 0 0 2px rgba(var(--warning-rgb), .55); }
body[data-theme="christmas"] .btn { padding-left: 1.1em; padding-right: 1.1em; }
/* Keep red for the main button and danger; secondary actions are pine green. */
body[data-theme="christmas"] .btn-outline-primary {
  --bs-btn-color: var(--accent2); --bs-btn-border-color: var(--accent2);
  --bs-btn-hover-bg: var(--accent2); --bs-btn-hover-border-color: var(--accent2); --bs-btn-hover-color: var(--accent2-ink);
  --bs-btn-active-bg: var(--accent2); --bs-btn-active-border-color: var(--accent2); --bs-btn-active-color: var(--accent2-ink);
}
@media (prefers-color-scheme: dark) {
  body:where(:not([data-mode="light"]))[data-theme="christmas"] .btn-outline-primary { --bs-btn-color: #6fd39a; }
}
/* Same as above when the viewer picked dark mode. */
body:where([data-mode="dark"])[data-theme="christmas"] .btn-outline-primary { --bs-btn-color: #6fd39a; }

/* A red focus ring looks like an error, so Christmas focus is green and gold. */
body[data-theme="christmas"] .form-control:focus, body[data-theme="christmas"] .form-select:focus,
body[data-theme="christmas"] .form-check-input:focus, body[data-theme="christmas"] .tile-editor:focus-within {
  border-color: var(--accent2); box-shadow: 0 0 0 .2rem rgba(var(--warning-rgb), .35);
}

/* Show/hide by JS support */
.js-only { display: none !important; }
.js .js-only { display: revert !important; }
.js .nojs-only { display: none !important; }

/* ── Background image and decorations ───────────────────────────────────── */
body.has-bg::before {
  content: ""; position: fixed; inset: 0; z-index: -2;
  background: linear-gradient(rgba(var(--bg-rgb), var(--veil)), rgba(var(--bg-rgb), var(--veil))), var(--bg-full) center / cover no-repeat;
}
@media (max-width: 1280px) {
  body.has-bg::before { background-image: linear-gradient(rgba(var(--bg-rgb), var(--veil)), rgba(var(--bg-rgb), var(--veil))), var(--bg-small); }
}
.decor { position: fixed; inset: 0; z-index: -1; pointer-events: none; }
/* Christmas: gentle snowfall. */
body[data-theme="christmas"] .decor {
  background-image:
    radial-gradient(2px 2px at 20px 30px, rgba(255,255,255,.9), transparent),
    radial-gradient(3px 3px at 120px 80px, rgba(255,255,255,.8), transparent),
    radial-gradient(2px 2px at 200px 150px, rgba(255,255,255,.9), transparent),
    radial-gradient(3px 3px at 60px 190px, rgba(255,255,255,.7), transparent),
    radial-gradient(2px 2px at 160px 230px, rgba(255,255,255,.85), transparent);
  background-size: 240px 260px;
  animation: snow 18s linear infinite;
  opacity: .9;
}
@media (prefers-color-scheme: light) {
  body:where(:not([data-mode="dark"]))[data-theme="christmas"] .decor { filter: drop-shadow(0 0 1px rgba(80, 100, 120, .6)); opacity: .7; }
}
/* Same as above when the viewer picked light mode. */
body:where([data-mode="light"])[data-theme="christmas"] .decor { filter: drop-shadow(0 0 1px rgba(80, 100, 120, .6)); opacity: .7; }

@keyframes snow { from { background-position: 0 0; } to { background-position: 40px 260px; } }
/* Halloween: a low orange glow, like jack-o'-lanterns in the dark. */
body[data-theme="halloween"] .decor {
  background: radial-gradient(ellipse 80% 40% at 50% 105%, rgba(var(--accent-rgb), .22), transparent 70%);
}

/* ── Header ─────────────────────────────────────────────────────────────── */
.topbar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: .5rem; padding: .9rem 1rem .4rem; }
.topbar .brand { grid-column: 2; }

/* Viewer display settings (top right). */
body { color-scheme: light dark; }
body[data-mode="light"] { color-scheme: light; }
body[data-mode="dark"] { color-scheme: dark; }
.prefs { justify-self: end; display: flex; gap: .4rem; align-items: center; }
.prefs form { margin: 0; }
.icon-btn {
  display: grid; place-items: center; width: 2.25rem; height: 2.25rem; padding: 0;
  border: 1px solid var(--border); border-radius: 50%; background: var(--surface); color: var(--ink);
  cursor: pointer; list-style: none; transition: border-color .15s, background-color .15s;
}
.icon-btn::-webkit-details-marker { display: none; }
.icon-btn:hover, .vision-menu[open] > .icon-btn { border-color: var(--accent); }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.icon-btn svg { width: 1.2rem; height: 1.2rem; }
.mode-icon { display: none; }
body[data-mode="auto"] .mode-icon.auto, body[data-mode="light"] .mode-icon.light, body[data-mode="dark"] .mode-icon.dark { display: block; }
.vision-menu { position: relative; }
.vision-menu .menu {
  position: absolute; right: 0; top: calc(100% + .45rem); z-index: 1100; min-width: 13rem;
  padding: .4rem; border: 1px solid var(--border); border-radius: .6rem;
  background: var(--surface); box-shadow: 0 8px 24px rgba(0,0,0,.18);
}
.menu-title { font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); padding: .25rem .6rem .4rem; }
.vision-menu .menu button {
  display: flex; align-items: center; gap: .5rem; width: 100%; padding: .45rem .6rem;
  border: 0; border-radius: .4rem; background: none; color: var(--ink); text-align: left; font-size: .9rem;
}
.vision-menu .menu button::before { content: ""; width: 1rem; flex: none; font-weight: 900; color: var(--link); }
.vision-menu .menu button[aria-checked="true"] { font-weight: 700; }
.vision-menu .menu button[aria-checked="true"]::before { content: "✓"; }
.vision-menu .menu button:hover, .vision-menu .menu button:focus-visible { background: var(--surface-2); outline: none; }
@media (max-width: 420px) {
  .topbar { padding-inline: .6rem; }
  .icon-btn { width: 2rem; height: 2rem; }
  .ball { width: 1.9rem; height: 1.9rem; font-size: 1rem; }
}
.brand { text-decoration: none; display: inline-flex; gap: .35rem; }
.ball {
  position: relative;
  display: inline-grid; place-items: center;
  width: 2.2rem; height: 2.2rem; border-radius: 50%;
  color: #fff; font-weight: 900; font-size: 1.1rem;
  text-shadow: 0 1px 2px rgba(0,0,0,.55);
  box-shadow: inset -3px -4px 0 rgba(0,0,0,.18), 0 2px 4px rgba(0,0,0,.15);
}
.ball.b { background: var(--b); } .ball.i { background: var(--i); } .ball.n { background: var(--n); }
.ball.g { background: var(--g); } .ball.o { background: var(--o); }
/* Christmas: the balls become ornaments with a gold cap. */
body[data-theme="christmas"] .ball::before {
  content: ""; position: absolute; top: -5px; left: 50%; transform: translateX(-50%);
  width: 10px; height: 6px; border-radius: 2px 2px 0 0; background: #d4a72c;
}
/* Halloween: the balls become pumpkins with a stem. */
body[data-theme="halloween"] .ball { border-radius: 46% 46% 50% 50% / 52% 52% 48% 48%; }
body[data-theme="halloween"] .ball::before {
  content: ""; position: absolute; top: -5px; left: 50%; transform: translateX(-30%) rotate(12deg);
  width: 5px; height: 8px; border-radius: 2px; background: #4f6b2a;
}

.narrow { max-width: 760px; }
.join-card { max-width: 440px; }
.join-prize { padding: .5rem .75rem; border-radius: .5rem; background: var(--reward-bg); border: 1px solid var(--reward-border); }
.code-input, .room-code { text-transform: uppercase; letter-spacing: .2em; font-weight: 700; font-family: ui-monospace, monospace; }
.room-code { background: var(--ink); color: var(--bg); padding: .1rem .5rem .1rem .6rem; border-radius: .4rem; }

/* Room header: room code and invite link on the left, identity on the right. */
.room-head {
  display: flex; flex-wrap: wrap; gap: .75rem 1.5rem; justify-content: space-between; align-items: center;
  margin-bottom: 1rem; padding: .4rem 0; border-radius: .75rem;
}
body.has-bg .room-head { background: var(--surface); border: 1px solid var(--border); padding: .6rem .9rem; }
.room-id { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.25rem; min-width: 0; }
.invite { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; min-width: 0; }
.invite-label { font-size: .8rem; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.invite-link {
  font-family: ui-monospace, monospace; font-size: .85rem; color: var(--ink); text-decoration: none;
  padding: .3rem .65rem; border: 1px dashed var(--muted); border-radius: .45rem; background: var(--surface-2);
  overflow-wrap: anywhere;
}
.invite-link:hover { border-style: solid; border-color: var(--accent); }
.js .invite-link { cursor: copy; }
.invite-status { font-size: .78rem; color: var(--muted); padding-left: .1rem; }
.invite-status.copied { color: rgb(var(--success-rgb)); font-weight: 700; }
.me-id { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.live { font-size: .75rem; color: var(--muted); margin-left: .25rem; }
.live::before { content: "●"; margin-right: .3rem; color: #d08770; }
.live.ok::before { color: rgb(var(--success-rgb)); }

.toast-msg {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translateX(-50%); z-index: 1050;
  background: var(--danger); color: #fff; padding: .6rem 1rem; border-radius: .5rem; box-shadow: 0 4px 16px rgba(0,0,0,.25);
  max-width: calc(100% - 2rem);
}

/* ── Prize ──────────────────────────────────────────────────────────────── */
.reward {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .35rem .7rem;
  margin-bottom: 1rem; padding: .65rem 1.1rem; border-radius: .8rem;
  background: var(--reward-bg); border: 1px solid var(--reward-border); color: var(--ink); text-align: center;
}
.reward-icon { font-size: 1.3rem; }
.reward-label { font-size: .75rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.reward-text { font-size: 1.1rem; overflow-wrap: anywhere; }

/* ── Players ────────────────────────────────────────────────────────────── */
.card-title-sm { font-size: .8rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: .9rem; }
.players { list-style: none; padding: 0; margin: 0 0 .5rem; display: flex; flex-direction: column; gap: .3rem; }
.players li { display: flex; align-items: center; gap: .5rem; padding: .35rem .55rem; border-radius: .45rem; }
.players li.me { background: rgba(var(--accent-rgb), .12); }
.players li.won { background: rgba(var(--success-rgb), .16); }
.pname { font-weight: 600; overflow-wrap: anywhere; }
.pname a { color: inherit; }
.players li.me .pname::after, strong.me::after {
  content: "you"; margin-left: .4rem; padding: .1em .45em; border-radius: .375rem;
  background: var(--ink); color: var(--bg); font-size: .72rem; font-weight: 700; vertical-align: .1em;
}
/* Progress dots: hollow rings for missing, filled for marked (shape and color). */
.pips {
  --ring: radial-gradient(circle, transparent .17rem, var(--pip-off) .18rem .27rem, transparent .29rem) 0 0 / .75rem 100% repeat-x;
  --dot: radial-gradient(circle, var(--pip-on) .27rem, transparent .29rem) 0 0 / .75rem 100% repeat-x;
  margin-left: auto; position: relative; flex: none; height: .6rem; width: calc(var(--n) * .75rem);
  background: var(--ring);
}
.pips::before { content: ""; position: absolute; inset: 0; width: calc(var(--b) * .75rem); background: var(--dot); }

/* ── Player board ───────────────────────────────────────────────────────── */
.board-wrap { max-width: min(640px, 100%); margin: 0 auto; width: 100%; }
.board-note { text-align: center; font-size: .875rem; color: var(--muted); margin-bottom: .75rem; }
.board-note.strong { color: var(--ink); font-weight: 600; }
body.has-bg .board-note { background: var(--surface); border-radius: .5rem; padding: .4rem .75rem; }
.board-letters, .board { display: grid; grid-template-columns: repeat(var(--n), 1fr); gap: .4rem; }
.board-letters span {
  text-align: center; font-weight: 900; font-size: clamp(1.4rem, 5vw, 2.4rem); line-height: 1.3; color: var(--b);
}
.board-letters span:nth-child(2) { color: var(--i); } .board-letters span:nth-child(3) { color: var(--n); }
.board-letters span:nth-child(4) { color: var(--g); } .board-letters span:nth-child(5) { color: var(--o); }
body.has-bg .board-letters span { text-shadow: 0 0 2px var(--surface), 0 0 6px var(--surface), 0 0 12px var(--surface); }
.cell {
  aspect-ratio: 1; display: grid; place-items: center; text-align: center;
  background: var(--cell); color: var(--ink); border: 2px solid var(--cell-border); border-radius: .6rem;
  padding: .35rem; overflow: hidden; position: relative;
  font-size: clamp(.6rem, 1.9vw, .95rem); line-height: 1.15; font-weight: 600;
  overflow-wrap: break-word; hyphens: auto; hyphenate-limit-chars: 7 3 3;
  transition: background .25s, color .25s, transform .25s;
}
.cell.marked { background: var(--mark); border-color: var(--mark); color: var(--mark-ink); }
/* A stamp on every marked cell, so marks don't rely on color. */
.cell.marked:not(.free)::after {
  content: "✓"; position: absolute; top: .15rem; right: .3rem;
  font-size: clamp(.6rem, 1.6vw, .95rem); font-weight: 900; line-height: 1; opacity: .9;
}
.cell.marked:not(.free) { animation: pop .35s ease-out; }
.cell.free { background: var(--free); border-color: var(--free); color: var(--free-ink); font-weight: 900; letter-spacing: .1em; }
/* Winning line: outline plus stripes. */
.cell.line {
  outline: 4px solid var(--won); outline-offset: -2px; z-index: 1;
  background-image: repeating-linear-gradient(45deg, var(--stripe) 0 6px, transparent 6px 12px);
}
.board-wrap.won .board { outline: 4px solid var(--won); outline-offset: 6px; border-radius: .6rem; }
@media (max-width: 576px) { .board-wrap.won .board { outline-width: 3px; outline-offset: 3px; } }
@keyframes pop { 0% { transform: scale(.85); } 60% { transform: scale(1.06); } 100% { transform: scale(1); } }

/* ── Host: marking ──────────────────────────────────────────────────────── */
.mark-filter { max-width: 14rem; }
.mark-grid { display: flex; flex-wrap: wrap; gap: .45rem; }
.mark-tile {
  border: 2px solid var(--cell-border); background: var(--cell); color: var(--ink);
  border-radius: 2rem; padding: .3rem .85rem; font-size: .9rem; font-weight: 600; cursor: pointer;
  transition: background .15s, border-color .15s;
}
.mark-tile:hover { border-color: var(--accent); }
.mark-tile.marked { background: var(--mark); border-color: var(--mark); color: var(--mark-ink); }
.mark-tile.marked::before { content: "✓ "; }

/* ── Revealed boards ────────────────────────────────────────────────────── */
.mini-boards { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 1rem; }
.mini {
  display: block; color: inherit; text-decoration: none;
  background: var(--surface); border: 1px solid var(--border); border-radius: .6rem; padding: .6rem;
  transition: transform .15s, box-shadow .15s;
}
a.mini:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,.15); color: inherit; }
.mini.won { outline: 3px solid var(--won); }
.mini-name { font-weight: 700; font-size: .875rem; margin-bottom: .4rem; overflow-wrap: anywhere; }
.mini-board { display: grid; grid-template-columns: repeat(var(--n), 1fr); gap: 2px; }
.mini-board div {
  aspect-ratio: 1; background: var(--surface-2); border-radius: 3px; font-size: .55rem; line-height: 1.1;
  overflow: hidden; padding: 1px; color: var(--muted); overflow-wrap: normal; word-break: normal;
}
/* On phones the mini boards are too small for text: the pattern shows who was close,
   and the card links to the full board. */
@media (max-width: 576px) {
  .mini-boards { grid-template-columns: repeat(2, 1fr); gap: .6rem; }
  .mini-board div { font-size: 0; }
}
.mini-board div.marked { background: var(--mark); color: var(--mark-ink); }
.mini-board div.free { background: var(--free); color: var(--free-ink); }
.mini-board div.line {
  background-color: var(--won); color: var(--won-ink);
  background-image: repeating-linear-gradient(45deg, var(--stripe) 0 3px, transparent 3px 6px);
}

/* ── Foldable host cards ────────────────────────────────────────────────── */
.fold summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: .5rem; }
.fold summary::-webkit-details-marker { display: none; }
.fold summary::before { content: "▸"; transition: transform .15s; color: var(--muted); }
.fold[open] summary::before { transform: rotate(90deg); }
.fold:not([open]) summary { border-bottom: 0; border-radius: var(--bs-card-inner-border-radius); }

/* Room settings */
.settings-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 1.4rem 1.75rem; }
.setting-wide { grid-column: 1 / -1; }
.input-row { display: flex; gap: .5rem; align-items: center; }
.input-row > .form-control, .input-row > .form-select { flex: 1; min-width: 0; }
.form-hint { font-size: .8rem; color: var(--muted); margin: .4rem 0 0; }
.bg-row { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; }
.bg-preview { width: 9rem; aspect-ratio: 16 / 9; object-fit: cover; border-radius: .45rem; border: 1px solid var(--border); }

/* Tiles: a no-wrap editor with line numbers. */
.tile-editor {
  display: flex; align-items: stretch;
  border: 1px solid var(--border); border-radius: .45rem; background: var(--surface); overflow: hidden;
}
.tile-editor:focus-within { border-color: var(--accent); box-shadow: 0 0 0 .2rem rgba(var(--accent-rgb), .3); }
.tile-editor textarea {
  border: 0; border-radius: 0; box-shadow: none !important; background: transparent;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .875rem; line-height: 1.6;
  white-space: pre; overflow-wrap: normal; overflow-x: auto; resize: vertical; min-height: 9rem;
  padding: .5rem .75rem;
}
.line-gutter {
  flex: none; min-width: 3.2ch; padding: .5rem .55rem .5rem .6rem; text-align: right;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .875rem; line-height: 1.6;
  color: var(--muted); background: var(--surface-2); border-right: 1px solid var(--border);
  white-space: pre; overflow: hidden; user-select: none;
}
.line-gutter .warn { color: var(--danger); font-weight: 700; }

.tile-list {
  padding-left: 2.4rem; margin: 0; max-height: 28rem; overflow-y: auto; padding-bottom: 1.5rem;
  mask-image: linear-gradient(#000 calc(100% - 2rem), transparent);
}
.tile-list li { margin-bottom: .35rem; }
.tile-list li::marker { color: var(--muted); font-size: .8rem; font-family: ui-monospace, monospace; }
.tile-row { display: flex; gap: .35rem; }
.tile-row input.changed { border-color: var(--accent); background-color: rgba(var(--accent-rgb), .08); }
.tiles-bar { display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: center; justify-content: space-between; margin-bottom: .6rem; }
.tiles-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.tiles-dirty { font-size: .8rem; color: var(--muted); }
.tiles-dirty.has-changes { color: var(--link); font-weight: 600; }

/* Saved tile sets */
.saved-sets { display: flex; flex-direction: column; gap: .45rem; }
.saved-set {
  display: flex; align-items: center; gap: .6rem;
  border: 1px dashed var(--border); border-radius: .5rem; padding: .5rem .7rem; background: var(--surface-2);
}
.saved-info { flex: 1; min-width: 0; }
.saved-preview { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Waiting screen ─────────────────────────────────────────────────────── */
.waiting-balls { display: inline-flex; gap: .45rem; padding-top: .3rem; }
.waiting-balls .ball { animation: bounce 1.4s ease-in-out infinite; }
.waiting-balls .ball:nth-child(2) { animation-delay: .1s; } .waiting-balls .ball:nth-child(3) { animation-delay: .2s; }
.waiting-balls .ball:nth-child(4) { animation-delay: .3s; } .waiting-balls .ball:nth-child(5) { animation-delay: .4s; }
@keyframes bounce { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-10px); } }

/* ── Winners ────────────────────────────────────────────────────────────── */
.winners {
  position: relative; overflow: hidden; text-align: center; margin-bottom: 1.25rem;
  padding: 1rem; border-radius: 1rem; color: #fff;
  background: linear-gradient(rgba(0,0,0,.22), rgba(0,0,0,.22)), linear-gradient(120deg, var(--b), var(--o), var(--g));
  box-shadow: 0 6px 24px rgba(0,0,0,.2);
  animation: pop .5s ease-out;
}
.winners-title { font-size: clamp(2rem, 7vw, 3.5rem); font-weight: 900; letter-spacing: .12em; line-height: 1; text-shadow: 0 3px 0 rgba(0,0,0,.25); }
.winners-names { margin-top: .4rem; font-size: 1.1rem; position: relative; text-shadow: 0 1px 2px rgba(0,0,0,.35); }
body[data-theme="christmas"] .winners { background: linear-gradient(120deg, #8e0e18, #b3121e 45%, #1d6b3e); }
.winners-names { font-weight: 600; }
body[data-vision="contrast"] .winners { background: #000; border: 3px solid var(--won); }

/* CSS-only confetti for visitors without JS; JS users get the canvas version. */
.confetti-css { position: absolute; inset: 0; pointer-events: none; }
.js .confetti-css { display: none; }
.confetti-css i {
  position: absolute; top: -12px; left: calc(var(--i) * 2.05%);
  width: 8px; height: 12px; opacity: 0;
  background: hsl(calc(var(--i) * 47deg) 90% 60%);
  animation: fall 2.6s linear calc(var(--i) * .045s) 2;
}
.confetti-css i:nth-child(3n) { width: 6px; height: 6px; border-radius: 50%; }
@keyframes fall {
  0% { opacity: 1; transform: translateY(0) rotate(0); }
  100% { opacity: .9; transform: translateY(160px) rotate(540deg); }
}
.confetti-canvas { position: fixed; inset: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 2000; }

.all-players { columns: 2 14rem; }

/* ── Footer ─────────────────────────────────────────────────────────────── */
.site-footer {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: .75rem 1.5rem;
  padding: 2.5rem 1rem 1.25rem; font-size: .8rem; color: var(--muted);
}
.site-footer .version { color: var(--muted); text-decoration: none; font-family: ui-monospace, monospace; }
.site-footer .version:hover { text-decoration: underline; }
body.has-bg .site-footer > * { background: var(--surface); padding: .25rem .6rem; border-radius: .4rem; }

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

/* Empty regions (e.g. "Mark tiles" before the game) shouldn't leave gaps. */
[data-region]:empty { display: none; }
.js #saved-sets:empty { display: none !important; }

/* Sub pages (player board, all players) over a background image. */
body.has-bg main.narrow > p, body.has-bg main.narrow > h1, body.has-bg main.narrow > ol {
  background: var(--surface); border-radius: .6rem; padding: .5rem .8rem;
}
body.has-bg main.narrow > p, body.has-bg main.narrow > h1 { display: inline-block; }
