:root {
  /* Player colours (colours.py PALETTE): each person's pick, used wherever a game marks whose a thing is */
  --pc-red: #d9473f; --pc-orange: #e8892b; --pc-gold: #d4ac1e; --pc-olive: #8a8b2c;
  --pc-lime: #7cc242; --pc-green: #2f9a55; --pc-teal: #1f9c9a; --pc-cyan: #35b6dc;
  --pc-blue: #3a72d8; --pc-navy: #2b3f8c; --pc-purple: #8b5bd6; --pc-magenta: #c03dbd;
  --pc-pink: #ef86b8; --pc-coral: #f2836b; --pc-brown: #8a5a3c; --pc-slate: #66717f;
  --bg: #f4efe6;
  --fg: #2b2620;
  --muted: #7a7064;
  --panel: #fffaf2;
  --line: #d8cdbb;
  --square: #e9e1d2;
  --tw: #d9534f;
  --dw: #f2a7a0;
  --tl: #3c78b5;
  --dl: #a9cbe8;
  --tile: #f3d9a4;
  --tile-edge: #c9a96a;
  --tile-fg: #2b2620;
  --pending: #ffe58a;
  --last: #b6e3a8;
  --last-ring: #3fa95a;
  --accent: #2f7d4f;
  --bad: #b3261e;
  --bw: min(calc(100vw - 16px), 62vh, 640px);
  --cell: calc(var(--bw) / var(--n, 15));        /* --n: the board's size (set by app.js) */
  color-scheme: light dark;
}
/* Dark: when the system is dark (unless this device chose Light in settings), or chosen. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1d1b18; --fg: #ece6db; --muted: #9b9184; --panel: #27241f; --line: #3d3830;
    --square: #2e2a24; --tw: #a8403c; --dw: #7a4a46; --tl: #2f5f8f; --dl: #36506a;
    --tile: #e8cf98; --tile-edge: #b0904f; --pending: #f5d860; --last: #8fcf7c;
    --accent: #5cb27f; --bad: #ff8a80;
  }
}
:root[data-theme="dark"] {
    --bg: #1d1b18; --fg: #ece6db; --muted: #9b9184; --panel: #27241f; --line: #3d3830;
    --square: #2e2a24; --tw: #a8403c; --dw: #7a4a46; --tl: #2f5f8f; --dl: #36506a;
    --tile: #e8cf98; --tile-edge: #b0904f; --pending: #f5d860; --last: #8fcf7c;
    --accent: #5cb27f; --bad: #ff8a80;
  color-scheme: dark;
}
:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }
[hidden] { display: none !important; }   /* our display: rules would otherwise un-hide things */
html, body { margin: 0; background: var(--bg); color: var(--fg); }
body {
  font: 16px/1.4 system-ui, -apple-system, "Segoe UI", sans-serif;
  padding: max(8px, env(safe-area-inset-top)) 8px max(8px, env(safe-area-inset-bottom));
  -webkit-tap-highlight-color: transparent;
}
main { max-width: 640px; margin: 0 auto; }
h1 { font-size: 1.6rem; margin: 0.5rem 0; letter-spacing: 0.1em; }
button {
  font: inherit; padding: 0.55rem 0.9rem; border-radius: 8px; border: 1px solid var(--line);
  background: var(--panel); color: var(--fg); cursor: pointer; touch-action: manipulation;
}
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
button:disabled { opacity: 0.4; cursor: default; }
input { font: inherit; padding: 0.5rem; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--fg); }
a { color: var(--accent); }
.muted { color: var(--muted); }
.error { color: var(--bad); }

/* --- home page --- */
.home form { display: grid; gap: 0.5rem; max-width: 22rem; }
.links { margin-top: 1rem; display: grid; gap: 0.75rem; }
.links a { word-break: break-all; }

/* --- scoreboard --- */
.scores { display: flex; gap: 6px; margin-bottom: 6px; }
.score {
  flex: 1; padding: 4px 8px; border-radius: 8px; background: var(--panel);
  border: 2px solid transparent; display: flex; justify-content: space-between; align-items: baseline;
}
.score.turn { border-color: var(--accent); }
.score .pts { font-weight: 700; font-size: 1.2rem; font-variant-numeric: tabular-nums; }
.status { display: flex; justify-content: space-between; font-size: 0.9rem; margin: 4px 0; min-height: 1.4em; gap: 8px; }

/* --- board --- */
/* The board sits in a fixed window and zooms/pans inside it (app.js "board zoom"). */
.board-wrap {
  width: var(--bw); height: var(--bw); margin: 0 auto; overflow: hidden; border-radius: 4px;
  touch-action: none;   /* pinches and drags here are ours, not the page's */
}
.board {
  width: var(--bw); height: var(--bw); transform-origin: 0 0;
  display: grid; gap: 1px;
  grid-template: repeat(var(--n, 15), minmax(0, 1fr)) / repeat(var(--n, 15), minmax(0, 1fr));   /* minmax(0): the ★ glyph can't stretch its row */
  background: var(--line); border: 1px solid var(--line); border-radius: 4px; overflow: hidden;
  user-select: none; -webkit-user-select: none;
}
.sq {
  background: var(--square); display: flex; align-items: center; justify-content: center;
  font-size: calc(var(--cell) * 0.3); font-weight: 700; color: rgba(255,255,255,0.9); position: relative; line-height: 1; overflow: hidden;
}
.sq.TW { background: var(--tw); } .sq.DW { background: var(--dw); }
.sq.TL { background: var(--tl); } .sq.DL { background: var(--dl); }
.sq.star::after { content: "★"; font-size: calc(var(--cell) * 0.55); color: rgba(255,255,255,0.85); }

.tile {
  background: var(--tile); color: var(--tile-fg); border-radius: 3px;
  box-shadow: inset 0 -2px 0 var(--tile-edge);
  display: flex; align-items: center; justify-content: center; position: relative; font-weight: 700;
}
.sq .tile { position: absolute; inset: 0; font-size: calc(var(--cell) * 0.6); }
.sq .tile.pending { background: var(--pending); cursor: grab; touch-action: none; }
.sq .tile.last { background: var(--last); }
/* Whose tile: the player's colour (--owner, set by app.js) mixed into the tile, so its edges stay free for
   the word tints; the last move then shows as a ring instead of a fill */
.sq .tile.owned:not(.pending) { background: color-mix(in srgb, var(--owner) 45%, var(--tile)); }
.sq .tile.owned.last::before { content: ""; position: absolute; inset: 0; border-radius: 3px; pointer-events: none;
  box-shadow: inset 0 0 0 calc(var(--cell) * 0.07) var(--last-ring); }
/* The move's score while you build it: a disc just past the word's last tile (or on its corner) */
.score-badge { position: absolute; z-index: 3; display: grid; place-items: center; border-radius: 50%; pointer-events: none;
  width: calc(var(--cell) * 0.8); height: calc(var(--cell) * 0.8); font-size: calc(var(--cell) * 0.4); font-weight: 800;
  color: #fff; background: #2e9e4a; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); }
.score-badge.bad { background: #d03b33; } .score-badge.open { background: #d99a1e; }
.score-badge.corner { width: calc(var(--cell) * 0.55); height: calc(var(--cell) * 0.55); font-size: calc(var(--cell) * 0.3); top: 1px; right: 1px; }
.score .swatch { display: inline-block; width: 0.7em; height: 0.7em; border-radius: 50%; margin-right: 6px; background: var(--owner); vertical-align: 0.05em; }
.colour-swatch { display: block; width: 30px; height: 30px; border-radius: 50%; background: var(--owner); }
.cp-row.compact { gap: 4px; } .cp-row.compact .cp-opt { padding: 4px; } .cp-row.compact .cp-opt span:last-child { display: none; }   /* swatches only */
.settings input[type=text] { width: 100%; box-sizing: border-box; margin-bottom: 8px; }
.tile.blank { color: var(--muted); }
.tile { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }

/* word check: subtle wash + ring over every square of each word the move would make */
.sq .tile.ok::after, .sq .tile.bad::after, .sq .tile.open::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
}
.sq .tile.ok::after  { background: rgba(46, 160, 67, 0.22); box-shadow: inset 0 0 0 2px rgba(46, 160, 67, 0.75); }
.sq .tile.bad::after { background: rgba(211, 47, 47, 0.20); box-shadow: inset 0 0 0 2px rgba(211, 47, 47, 0.75); }
.sq .tile.open::after { background: rgba(240, 170, 40, 0.22); box-shadow: inset 0 0 0 2px rgba(220, 150, 20, 0.8); }   /* unfinished, for now */

/* not your turn: empty squares go grey and the board gets a dashed frame; tiles keep their colour */
.board-wrap.waiting { outline: 2px dashed var(--muted); outline-offset: 3px; }
.board.waiting .sq:not(.filled) { filter: grayscale(0.85) brightness(0.9); }

/* dragging */
.tile.ghost {
  position: fixed; z-index: 10; pointer-events: none; border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35), inset 0 -2px 0 var(--tile-edge);
}
.tile.dragging { opacity: 0.3; }
.sq.drop { outline: 3px solid var(--accent); outline-offset: -3px; z-index: 1; }
/* a played move's scoring: its tiles see-through so the squares show, the premiums that counted ringed */
.sq.explain .tile { opacity: 0.3; }
.sq.used { outline: 3px solid var(--accent); outline-offset: -3px; z-index: 1; }
.log li.explainable { cursor: pointer; } .log li.explainable.on { font-weight: 700; }
.tile sub {
  position: absolute; right: 8%; bottom: 4%; font-size: 0.4em; font-weight: 600; line-height: 1;
}

/* --- rack + controls --- */
.rack { display: flex; justify-content: center; gap: 4px; margin: 10px 0 6px; min-height: calc(var(--bw) / 8); }
.rack .tile {
  width: calc(var(--bw) / 8); height: calc(var(--bw) / 8); max-width: 56px; max-height: 56px;
  font-size: calc(min(var(--bw) / 8, 56px) * 0.55); cursor: grab; touch-action: none;
}
.rack .tile.selected { transform: translateY(-6px); outline: 3px solid var(--accent); }
.rack .tile.swap { outline: 3px dashed var(--bad); }
.controls { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.preview { text-align: center; min-height: 1.5em; margin: 4px 0; }

.log { margin-top: 12px; font-size: 0.9rem; }
.log ol { padding-left: 1.4rem; margin: 0.3rem 0; }
.over { text-align: center; font-weight: 700; padding: 8px; background: var(--panel); color: var(--fg); border-radius: 8px; }

/* --- signed-in home --- */
.home h2 { font-size: 1.1rem; margin: 1.2rem 0 0.4rem; }
.games { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; }
.games li { padding: 8px 10px; background: var(--panel); border-radius: 8px; display: flex; justify-content: space-between; gap: 8px; }
.games a { color: var(--fg); text-decoration: none; flex: 1; }
.tag { font-size: 0.8rem; color: var(--muted); white-space: nowrap; }
.tag.turn { color: var(--accent); font-weight: 700; }
.people { display: grid; gap: 6px; margin-bottom: 8px; }
.people label { display: flex; gap: 8px; align-items: center; padding: 6px 10px; background: var(--panel); border-radius: 8px; }
.back { text-decoration: none; color: var(--muted); font-weight: 700; font-size: 1.5em; line-height: 1; display: inline-block; vertical-align: -0.1em; padding: 4px 12px 4px 2px; margin: -4px 0; }   /* a big enough target to tap */
.kinds { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.kinds label { padding: 6px 12px; background: var(--panel); border-radius: 999px; border: 1px solid var(--line); }
.kinds label:has(input:checked) { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.kinds input { display: none; }
.notify { padding: 8px 10px; background: var(--panel); border-radius: 8px; }
.notify label { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.small { font-size: 0.85rem; margin: 6px 0 0; }

/* --- Four in a row (connect4) --- */
.c4 {
  /* 7 holes + 6 gaps of 4px + 16px padding + 16px page gutter = the screen width */
  --hole: min(calc((min(100vw, 640px) - 56px) / 7), 9vh, 72px);
  display: grid; grid-template-columns: repeat(7, var(--hole)); gap: 4px; justify-content: center;
  width: fit-content; margin: 8px auto; padding: 8px; border-radius: 12px; background: #2a5db0;
  user-select: none; -webkit-user-select: none; touch-action: manipulation; overflow: hidden;
}
.c4 .hole {
  width: var(--hole); height: var(--hole); border-radius: 50%; background: var(--bg);
  box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.35); position: relative; cursor: pointer;
}
.c4 .hole.aim { background: color-mix(in srgb, var(--bg) 80%, #fff); }
.c4.waiting { filter: saturate(0.5) brightness(0.92); outline: 2px dashed var(--muted); outline-offset: 3px; }
.disc { display: inline-block; width: 1.1em; height: 1.1em; border-radius: 50%; vertical-align: middle; }
.c4 .disc { position: absolute; inset: 3px; width: auto; height: auto; box-shadow: inset 0 -4px 0 rgba(0, 0, 0, 0.2); }
.disc.red { background: #d63a2f; }
.disc.yellow { background: #f2c230; }
.c4 .disc.ghost { opacity: 0.4; }
.c4 .disc.win { box-shadow: 0 0 0 4px #fff, inset 0 -4px 0 rgba(0, 0, 0, 0.2); animation: pulse 1s ease-in-out infinite alternate; }
.c4 .disc.fall { animation: fall calc(0.12s + var(--fall) * 0.05s) ease-in; }
@keyframes fall { from { transform: translateY(calc(var(--fall) * -1 * (var(--hole) + 4px))); } }
@keyframes pulse { to { transform: scale(0.88); } }

/* --- Tile rummy --- */
body.rummy { --rt: min(calc((min(100vw, 640px) - 40px) / 11), 44px); }
.rt {
  width: var(--rt); height: calc(var(--rt) * 1.35); border-radius: 5px; flex: none;
  background: #fbf6ea; box-shadow: inset 0 -3px 0 #d8ccb2, 0 1px 2px rgba(0, 0, 0, 0.25);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: calc(var(--rt) * 0.58); cursor: grab;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; touch-action: none;
}
.rt.black { color: #222; } .rt.red { color: #d32f2f; } .rt.blue { color: #1565c0; } .rt.orange { color: #ef7d00; }
.rt.joker { color: #c62828; font-size: calc(var(--rt) * 0.7); }
.rt.mine { box-shadow: inset 0 -3px 0 #d8ccb2, 0 0 0 2px var(--accent); }
.rt.last { background: #e4f3dc; }
.rt.selected { transform: translateY(-5px); outline: 3px solid var(--accent); }
.rt.ghost { position: fixed; z-index: 10; pointer-events: none; box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35); }
.rt.dragging { opacity: 0.3; }

.rtable {
  display: flex; flex-wrap: wrap; gap: 8px; align-content: flex-start; padding: 8px;
  min-height: 30vh; max-height: 52vh; overflow-y: auto; background: #2f6b4a; border-radius: 10px;
}
.rtable.waiting { filter: saturate(0.6); outline: 2px dashed var(--muted); outline-offset: 3px; }
.rtable .muted { color: #cfe3d6; margin: auto; }
.set { display: flex; gap: 2px; padding: 4px; border-radius: 7px; background: rgba(255, 255, 255, 0.12);
       min-height: calc(var(--rt) * 1.35 + 12px); border: 2px solid transparent; }
.set.ok { border-color: rgba(120, 220, 140, 0.85); }
.set.bad { border-color: rgba(255, 110, 100, 0.95); background: rgba(255, 90, 80, 0.18); }
.set.short { border: 2px dashed #f2c94c; background: rgba(242, 201, 76, 0.12); }
/* An end that could still take a tile: dotted, with a little extra room as a hint. */
.set.open-l { border-left-style: dotted; border-left-width: 3px; padding-left: 9px; }
.set.open-r { border-right-style: dotted; border-right-width: 3px; padding-right: 9px; }
.rslot { width: var(--rt); height: calc(var(--rt) * 1.35); flex: none; border: 2px dashed rgba(255, 255, 255, 0.45); border-radius: 5px; }
.set.newset { align-items: center; padding: 4px 12px; color: #e7f2ea; border: 2px dashed rgba(255, 255, 255, 0.5); box-shadow: none; font-size: 0.9rem; cursor: pointer; }
.set.droptarget, .rrack.droptarget { outline: 3px solid #ffe58a; }
.rrack { display: flex; flex-wrap: wrap; gap: 4px; justify-content: center; padding: 8px 4px; margin: 6px 0; min-height: calc(var(--rt) * 1.35 + 16px); border-radius: 8px; background: var(--panel); }
body.rummy #rematch:not([hidden]) { display: block; margin: 8px auto; }
.dots { display: inline-flex; gap: 3px; vertical-align: middle; }
.dots i { width: 9px; height: 9px; border-radius: 50%; }
.dots .black { background: #222; } .dots .red { background: #d32f2f; } .dots .blue { background: #1565c0; } .dots .orange { background: #ef7d00; }
.score .pts small { font-size: 0.7rem; font-weight: 400; }

/* --- playing cards (cards.js), shared by card games --- */
.card { width: var(--cw, 64px); aspect-ratio: 5 / 7; position: relative; flex: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.card svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25)); }
.card.slot { border: 2px dashed rgba(255, 255, 255, 0.45); border-radius: 7%/5%; }

/* --- Klondike --- */
body.klondike { --cw: min(calc((min(100vw, 640px) - 40px) / 7), 84px); --ch: calc(var(--cw) * 1.4); --step: calc(var(--ch) * 0.13); }
.kfelt { background: #2f6b4a; border-radius: 10px; padding: 8px; touch-action: pinch-zoom; }   /* drags are ours; a pinch still zooms (and un-zooms) the page */
.ktop, .ktableau { display: grid; grid-template-columns: repeat(7, var(--cw)); gap: 4px; justify-content: center; }
.ktop { margin-bottom: 10px; }
.kwaste { grid-column: span 2; position: relative; height: var(--ch); }
.kwaste .card.fan { position: absolute; left: calc(var(--k) * var(--cw) * 0.44); }   /* wide enough to show rank + suit */
.kgap { display: none; }
.kcol { position: relative; min-height: calc(var(--ch) + var(--depth, 0) * var(--step)); }
.kcol .card:not(.slot) { position: absolute; left: 0; top: calc(var(--y) * var(--step)); }
.card.slot.found::after, .card.slot.recycle::after {
  content: "A"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: rgba(255, 255, 255, 0.4); font: 700 calc(var(--cw) * 0.45) Georgia, serif;
}
.card.slot.recycle::after { content: "↻"; }
.card.lifted { opacity: 0.25; }
.kghost { position: fixed; z-index: 10; pointer-events: none; }
.kghost .card { position: absolute; left: 0; }
.kdrop { outline: 3px solid #ffe58a; outline-offset: 2px; border-radius: 6px; }
.card.shake { animation: shake 0.35s; }
@keyframes shake { 25% { translate: -4px 0; } 75% { translate: 4px 0; } }
.games li { flex-wrap: wrap; }
.lastword { flex-basis: 100%; display: flex; align-items: center; gap: 6px; font-size: 0.85rem; }
.minitiles { display: inline-flex; gap: 2px; }
.minitiles span {
  width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--tile); color: var(--tile-fg); border-radius: 3px; font-weight: 700; font-size: 0.8rem;
  box-shadow: inset 0 -2px 0 var(--tile-edge);
}
.tabs { display: flex; gap: 4px; margin: 14px 0 0; border-bottom: 1px solid var(--line); }
.tabs button { border: none; border-radius: 8px 8px 0 0; background: transparent; padding: 0.5rem 1rem; color: var(--muted); position: relative; }
.tabs button[aria-selected="true"] { background: var(--panel); color: var(--fg); font-weight: 700; box-shadow: inset 0 -3px 0 var(--accent); }
.tabs button.badge::after { content: ""; position: absolute; top: 6px; right: 4px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }

/* blank-tile letter picker (word game) */
.picker { border: none; border-radius: 12px; padding: 14px; background: var(--panel); color: var(--fg); max-width: min(92vw, 420px); }
.picker::backdrop { background: rgba(0, 0, 0, 0.45); }
.picker p { margin: 0 0 10px; }
.picker .letters { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.picker .blank-choice { aspect-ratio: 1; border: none; padding: 0; font-size: 1.3rem; cursor: pointer; color: var(--tile-fg); }
.picker .cancel { margin-top: 12px; width: 100%; }
.picker .blank-choice:focus:not(:focus-visible) { outline: none; }   /* opening focuses "A": not a pre-selection */
.optrow { align-items: center; }
.optrow > span { margin-right: 2px; }

/* --- Word guess --- */
body.wordguess { --hit: #3f8f5a; --near: #cf9f24; --miss: #7d7a74; }
.wg-grid { display: grid; gap: 6px; justify-content: center; margin: 12px auto; }
.wg-row { display: grid; grid-template-columns: repeat(5, min(15vw, 58px)); gap: 6px; }
.wg-cell {
  aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--line); border-radius: 4px; font: 800 min(8vw, 30px) system-ui, sans-serif;
  text-transform: uppercase; background: var(--panel);
}
.wg-cell.filled { border-color: var(--muted); }
.wg-cell.pop { animation: pop 0.1s; }
.wg-cell.hit, .wg-cell.near, .wg-cell.miss { color: #fff; border-color: transparent; }
.wg-cell.hit { background: var(--hit); } .wg-cell.near { background: var(--near); } .wg-cell.miss { background: var(--miss); }
.wg-cell.flip { animation: wgflip 0.32s ease-in-out both; }
@keyframes wgflip { 50% { transform: rotateX(90deg); } }
@keyframes pop { 50% { transform: scale(1.1); } }
.wg-keys { display: grid; gap: 6px; margin-top: 10px; user-select: none; -webkit-user-select: none; }
.wg-keyrow { display: flex; gap: 4px; justify-content: center; }
.wg-key {
  flex: 1; max-width: 44px; height: 54px; padding: 0; border-radius: 6px; font-weight: 700; font-size: 1rem;
  background: var(--square); border: none; touch-action: manipulation;
}
.wg-key.wide { flex: 1.6; max-width: 70px; font-size: 0.8rem; }
.wg-key.hit, .wg-key.near, .wg-key.miss { color: #fff; }
.wg-key.hit { background: var(--hit); } .wg-key.near { background: var(--near); } .wg-key.miss { background: var(--miss); }

/* --- 2048 --- */
body.g2048 { --tw: min(calc(100vw - 32px), 440px); --gap: calc(var(--tw) * 0.03); --tcell: calc((var(--tw) - 5 * var(--gap)) / 4); }
.t-scores { display: flex; gap: 8px; justify-content: center; align-items: stretch; margin: 6px 0 10px; }
.t-score { background: var(--panel); border-radius: 8px; padding: 4px 14px; text-align: center; min-width: 84px; }
.t-score small { display: block; color: var(--muted); font-size: 0.75rem; }
.t-score span { font-weight: 800; font-size: 1.3rem; font-variant-numeric: tabular-nums; }
.t-board {
  position: relative; width: var(--tw); height: var(--tw); margin: 0 auto; border-radius: 10px;
  background: #b9ad9b; touch-action: pinch-zoom; user-select: none; -webkit-user-select: none;
}
.t-cells { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(4, var(--tcell)); gap: var(--gap); padding: var(--gap); }
.t-cell { border-radius: 6px; background: rgba(255, 255, 255, 0.28); }
.t-tiles { position: absolute; inset: 0; }
.t-tile {
  position: absolute; width: var(--tcell); height: var(--tcell); border-radius: 6px;
  left: calc(var(--gap) + var(--c) * (var(--tcell) + var(--gap))); top: calc(var(--gap) + var(--r) * (var(--tcell) + var(--gap)));
  transition: left 0.11s ease-in-out, top 0.11s ease-in-out;
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: calc(var(--tcell) * 0.42);
  background: #eee3d0; color: #5c5246; font-variant-numeric: tabular-nums;
}
.t-tile[data-v="4"] { background: #ecdcb6; }
.t-tile[data-v="8"] { background: #8fcf9c; color: #fff; }
.t-tile[data-v="16"] { background: #5fb57b; color: #fff; }
.t-tile[data-v="32"] { background: #3f9a63; color: #fff; }
.t-tile[data-v="64"] { background: #2f7d4f; color: #fff; }
.t-tile[data-v="128"] { background: #e9c46a; color: #fff; font-size: calc(var(--tcell) * 0.36); }
.t-tile[data-v="256"] { background: #e2b23f; color: #fff; font-size: calc(var(--tcell) * 0.36); }
.t-tile[data-v="512"] { background: #d99a1e; color: #fff; font-size: calc(var(--tcell) * 0.36); }
.t-tile[data-v="1024"] { background: #d1691f; color: #fff; font-size: calc(var(--tcell) * 0.3); }
.t-tile[data-v="2048"] { background: #c0392b; color: #fff; font-size: calc(var(--tcell) * 0.3); box-shadow: 0 0 18px rgba(192, 57, 43, 0.6); }
.t-tile[data-v="4096"], .t-tile[data-v="8192"], .t-tile[data-v="16384"] { background: #3b2f2a; color: #fff; font-size: calc(var(--tcell) * 0.26); }
.t-tile.new { animation: t-appear 0.16s ease-out; }
.t-tile.merged { animation: t-pop 0.16s ease-out; z-index: 2; }
@keyframes t-appear { from { transform: scale(0); } }
@keyframes t-pop { 50% { transform: scale(1.15); } }
.t-banner {
  position: absolute; inset: 0; border-radius: 10px; background: rgba(255, 250, 242, 0.78);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; z-index: 5;
}
.t-banner p { font-size: 1.4rem; font-weight: 800; margin: 0; }
.t-help { text-align: center; font-size: 0.85rem; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .t-board { background: #4a4238; } :root:not([data-theme="light"]) .t-cell { background: rgba(255, 255, 255, 0.08); } }
:root[data-theme="dark"] .t-board { background: #4a4238; } :root[data-theme="dark"] .t-cell { background: rgba(255, 255, 255, 0.08); }

/* --- column solitaires (patience.js): FreeCell, Spider --- */
body.patience { --cols: 8; --cw: min(calc((min(100vw, 640px) - 32px - (var(--cols) - 1) * 4px) / var(--cols)), 80px);
                --ch: calc(var(--cw) * 1.4); --step: calc(var(--ch) * 0.24); }
.pfelt { background: #2f6b4a; border-radius: 10px; padding: 8px; touch-action: pinch-zoom; }
.prow { display: grid; grid-template-columns: repeat(var(--cols), var(--cw)); gap: 4px; justify-content: center; }
.prow + .prow { margin-top: 10px; }
.pstack { position: relative; height: var(--ch); }
.pcol { position: relative; min-height: calc(var(--ch) + var(--depth, 0) * var(--step)); }
.pcol .card:not(.slot) { position: absolute; left: 0; top: calc(var(--y) * var(--step)); }
.card.slot.cell { background: rgba(0, 0, 0, 0.12); }
.card.slot.found::after { content: "A"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
                          color: rgba(255, 255, 255, 0.4); font: 700 calc(var(--cw) * 0.45) Georgia, serif; }
.pghost { position: fixed; z-index: 10; pointer-events: none; }
.pghost .card { position: absolute; }
.pdrop { outline: 3px solid #ffe58a; outline-offset: 2px; border-radius: 6px; }

/* End game (common.js endGameButton): available everywhere, never in the way */
.endgame { display: block; margin: 18px auto 4px; background: none; border: none; color: var(--muted); font-size: 0.85rem; text-decoration: underline; }
/* The end of a game (common.js gameOverBanner): the page dims, the background pulses softly
   (accent for a result, grey once for a game ended early), and the card comes up over it */
.go { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: 16px;
      background: color-mix(in srgb, var(--bg) 60%, transparent); }
.go[hidden] { display: none; }
.go-pulse { position: absolute; inset: 0; pointer-events: none; opacity: 0.4;
            background: radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--accent) 50%, transparent), transparent 72%); }
.go.ended .go-pulse { background: radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--muted) 40%, transparent), transparent 72%); }
.go.in .go-pulse { animation: go-pulse 2.4s ease-in-out both; }
.go.in.ended .go-pulse { animation: go-pulse-once 1.4s ease-in-out both; }
@keyframes go-pulse { 0% { opacity: 0; } 22% { opacity: 1; } 48% { opacity: 0.3; } 72% { opacity: 0.85; } 100% { opacity: 0.4; } }
@keyframes go-pulse-once { 0% { opacity: 0; } 40% { opacity: 1; } 100% { opacity: 0.4; } }
.go-card { position: relative; width: min(100%, 340px); box-sizing: border-box; padding: 20px 18px 14px; text-align: center; color: var(--fg);
           background: var(--panel); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25); }
.go.in .go-card { animation: go-card 0.4s cubic-bezier(0.2, 0.7, 0.3, 1.25) both; }
@keyframes go-card { from { opacity: 0; transform: translateY(14px) scale(0.9); } }
.go-card h2 { margin: 0 0 4px; font-size: 1.7rem; font-weight: 800; line-height: 1.15; }
.go-sub { margin: 0 0 10px; color: var(--muted); }
.go-scores { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 4px; }
.go-scores li { display: flex; justify-content: space-between; gap: 12px; padding: 6px 12px; border-radius: 8px; background: var(--bg); }
.go-scores li.win { color: var(--accent); font-weight: 700; box-shadow: inset 0 0 0 2px var(--accent); }
.go-scores li.win span::before { content: "★ "; }
.go-actions { display: grid; gap: 8px; }
.go-note { margin: 8px 0 0; color: var(--muted); } .go-note:empty { display: none; }
/* Losing: the page goes greyer and darker, one slow grey swell, and the card sinks into place
   rather than bouncing up; the winner keeps a quiet outline, no star */
.go.lose { background: color-mix(in srgb, var(--bg) 72%, transparent); backdrop-filter: grayscale(0.85); -webkit-backdrop-filter: grayscale(0.85); }
.go.lose .go-pulse { background: radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--muted) 45%, transparent), transparent 75%); }
.go.in.lose .go-pulse { animation: go-pulse-sigh 3s ease-in-out both; }
@keyframes go-pulse-sigh { 0% { opacity: 0; } 45% { opacity: 0.9; } 100% { opacity: 0.35; } }
.go.in.lose .go-card { animation: go-card-sink 0.9s cubic-bezier(0.3, 0, 0.3, 1) both; }
@keyframes go-card-sink { from { opacity: 0; transform: translateY(-18px); } }
.go.lose .go-card h2 { color: var(--muted); font-weight: 700; }
.go.lose .go-scores li.win { color: inherit; font-weight: 600; box-shadow: inset 0 0 0 1px var(--muted); }
.go.lose .go-scores li.win span::before { content: ""; }
.go.lose .go-rematch { filter: saturate(0.4); }
.go-sub:empty { display: none; }
@media (prefers-reduced-motion: reduce) { .go.in .go-pulse, .go.in .go-card { animation: none; } }
.over .linkish { padding: 0 0 0 6px; font-weight: 400; text-decoration: underline; }
/* TEMPORARY: the admin's Win/Lose buttons on every game (common.js endGameButton) */
.admin-test { text-align: center; margin: 10px 0 0; }
.admin-test button { padding: 0.3rem 0.7rem; font-size: 0.85rem; border-style: dashed; }

/* --- Spider: ten columns, compact cards --- */
body.spider { --cols: 10; --step: calc(var(--ch) * 0.3); }
.sp-top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px; min-height: var(--ch); }
.sp-done, .sp-stock { display: flex; }
.sp-done .card + .card { margin-left: calc(var(--cw) * -0.6); }
.sp-stock { cursor: pointer; }
.sp-stock .card + .card { margin-left: calc(var(--cw) * -0.75); }
.optrow { margin-bottom: 6px; }
.opthelp { margin: 2px 0 0 4px; }
.optbox { background: var(--panel); border-radius: 8px; padding: 6px 10px; margin-bottom: 8px; }
.optbox summary { cursor: pointer; font-weight: 600; padding: 4px 0; }
.presets button { padding: 4px 12px; border-radius: 999px; font-size: 0.9rem; }
.presets button.on { border-color: var(--accent); color: var(--accent); font-weight: 600; }

/* --- One --- */
body.one { --ow: min(calc((min(100vw, 640px) - 40px) / 6), 76px); --oh: calc(var(--ow) * 1.5); }
.ocard { width: var(--ow); height: var(--oh); flex: none; user-select: none; -webkit-user-select: none; }
.ocard svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3)); }
.o-players { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.o-player { flex: 1 1 30%; padding: 4px 8px; border-radius: 8px; background: var(--panel); border: 2px solid transparent; font-size: 0.9rem; }
.o-player.turn { border-color: var(--accent); }
.o-player .name { display: block; font-weight: 600; }
.o-player .count { color: var(--muted); font-size: 0.8rem; }
.o-badge { margin-left: 6px; font-size: 0.75rem; font-weight: 700; color: #fff; background: var(--accent); border-radius: 999px; padding: 0 6px; }
.o-badge.warn { background: var(--bad); }
.o-felt { position: relative; display: flex; justify-content: center; align-items: center; gap: 30px; padding: 16px; border-radius: 12px; background: #2f6b4a; min-height: calc(var(--oh) * 1.25 + 32px); }
body.one { --big: 1.25; }
.o-felt .ocard { width: calc(var(--ow) * var(--big)); height: calc(var(--oh) * var(--big)); }
.o-deck { position: relative; cursor: default; }
.o-deck.live { cursor: pointer; }
.o-deck.live .ocard { box-shadow: 0 0 0 3px #ffe58a; border-radius: 10%; }
.o-decknum { position: absolute; bottom: -18px; left: 0; right: 0; text-align: center; color: #e7f2ea; font-size: 0.8rem; }
.o-pile { position: relative; width: calc(var(--ow) * var(--big)); height: calc(var(--oh) * var(--big));
          border-radius: 12%; box-shadow: 0 0 0 5px var(--ring), 0 0 18px var(--ring); }
.o-pile .ocard { position: absolute; inset: 0; transform: rotate(var(--tilt)); }
.o-pile[data-pending]::after { content: attr(data-pending); position: absolute; top: -12px; right: -14px; z-index: 50;
  background: var(--bad); color: #fff; font-weight: 800; border-radius: 999px; padding: 2px 9px; }
.o-dir { position: absolute; right: 12px; top: 8px; color: rgba(255, 255, 255, 0.55); font-size: 1.6rem; }
.o-hand { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; padding: 10px 4px; margin: 6px 0; border-radius: 10px; background: var(--panel); min-height: calc(var(--oh) + 20px); }
.o-hand .ocard { transition: transform 0.12s; }
.o-hand .ocard.can { transform: translateY(-6px); cursor: pointer; }
.o-hand .ocard.jump { outline: 3px dashed #ffe58a; border-radius: 10%; }
.o-hand .ocard.dim { opacity: 0.55; }
.o-hand.waiting { outline: 2px dashed var(--muted); outline-offset: 3px; }
.o-rules { margin: 4px 0; padding-left: 1.2rem; }
.o-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.o-choices button { padding: 0.8rem; font-weight: 700; }
.rhint { flex-basis: 100%; margin: 4px 2px 0; color: #cfe3d6; font-size: 0.85rem; }
.rt[data-as]:not(.ghost) { position: relative; }   /* never override the dragged copy's fixed position */
.rt[data-as]::after { content: attr(data-as); position: absolute; bottom: 2px; right: 3px; font-size: calc(var(--rt) * 0.26); color: var(--muted); font-weight: 700; }
.footer { margin-top: 2rem; text-align: center; }
.credits pre.licence { white-space: pre-wrap; font-size: 0.75rem; background: var(--panel); padding: 10px; border-radius: 8px; max-height: 60vh; overflow: auto; }

/* --- card games: the whole screen is the table --- */
body.klondike, body.patience {
  --felt: #2c6b40; --felt-light: #3d8a55;
  background: radial-gradient(ellipse at 50% 0%, var(--felt-light), var(--felt) 70%) fixed var(--felt);
  color: #eef5ef; min-height: 100vh;
}
body.klondike .kfelt, body.patience .pfelt { background: transparent; padding: 4px 0; }
body.klondike .muted, body.patience .muted, body.klondike .back, body.patience .back { color: rgba(238, 245, 239, 0.75); }
body.klondike .preview.error, body.patience .preview.error { color: #ffd2cc; }
body.klondike .controls button, body.patience .controls button {
  background: rgba(0, 0, 0, 0.25); color: #fff; border: 1px solid rgba(255, 255, 255, 0.18);
}
body.klondike .controls button.primary, body.patience .controls button.primary { background: #f0c24b; color: #1d1b18; border-color: #f0c24b; }
body.klondike .endgame, body.patience .endgame { color: rgba(238, 245, 239, 0.7); background: none; border: none; }
/* Bigger cards on small screens: less side margin, and fans wide enough to show the big index. */
body.klondike.cards-big { --cw: min(calc((min(100vw, 640px) - 28px) / 7), 84px); --step: calc(var(--ch) * 0.17); }
body.patience.cards-big { --step: calc(var(--ch) * 0.33); }
body.patience.cards-big { --cw: min(calc((min(100vw, 640px) - 20px - (var(--cols) - 1) * 4px) / var(--cols)), 80px); }
/* Spider: face-up cards that can't move yet (above the movable run) — grey, still readable. */
.card.blocked svg { filter: brightness(0.72) saturate(0.55) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25)); }
/* Cards… settings (cards.js) */
.cardprefs { max-width: min(94vw, 420px); }
.cardprefs .small { margin: 10px 0 4px; }
.cp-faces, .cp-backs, .cp-tables { display: flex; flex-wrap: wrap; gap: 8px; }
.cp-opt { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 6px; border-radius: 10px; border: 2px solid transparent; background: var(--bg); }
.cp-opt.on { border-color: var(--accent); }
.cp-faces .card { --cw: 64px; }
.cp-backs .card { --cw: 46px; }
/* The settings box is a light panel even on the green card tables, so undo their light text. */
dialog.cardprefs { color: var(--fg); }
dialog.cardprefs .muted { color: var(--muted); }

/* --- Stargaze --- */
body.stargaze[data-theme="stars"] { background: radial-gradient(ellipse at 50% 0%, #26315a, #10152b 75%) fixed #10152b; color: #e8ecff; min-height: 100vh; }
body.stargaze[data-theme="stars"] .muted, body.stargaze[data-theme="stars"] .back { color: #aab3d8; }
body.stargaze[data-theme="stars"] .controls button { background: rgba(255, 255, 255, 0.1); color: #fff; border-color: rgba(255, 255, 255, 0.2); }
body.stargaze[data-theme="stars"] .controls button.primary { background: #f5c542; color: #1d1b18; border-color: #f5c542; }
body.stargaze[data-theme="stars"] .endgame { color: #aab3d8; background: none; border: none; }
.sg-rule { text-align: center; margin: 2px 0 8px; }
.sg-grid {
  --size: min(calc(100vw - 24px), 60vh, 520px);
  width: var(--size); height: var(--size); margin: 0 auto; display: grid;
  grid-template-columns: repeat(var(--n), 1fr); grid-template-rows: repeat(var(--n), 1fr);
  border: 3px solid #1d1b18; border-radius: 6px; overflow: hidden; touch-action: pinch-zoom;
  user-select: none; -webkit-user-select: none;
}
.sg-cell { position: relative; display: flex; align-items: center; justify-content: center; cursor: pointer;
           border: 0.5px solid rgba(0, 0, 0, 0.25); }
.sg-cell.bt { border-top: 2.5px solid #1d1b18; } .sg-cell.bb { border-bottom: 2.5px solid #1d1b18; }
.sg-cell.bl { border-left: 2.5px solid #1d1b18; } .sg-cell.br { border-right: 2.5px solid #1d1b18; }
.sg-x { font-size: calc(var(--size) / var(--n) * 0.42); color: rgba(0, 0, 0, 0.45); font-weight: 700; }
body.stargaze[data-theme="stars"] .sg-x { color: rgba(255, 255, 255, 0.55); }
.sg-cell svg { width: 78%; height: 78%; }
.sg-cell.pop svg { animation: sg-pop 0.18s ease-out; }   /* only the star just placed */
.sg-cell.clash { background-image: repeating-linear-gradient(45deg, rgba(220, 40, 40, 0.55) 0 6px, transparent 6px 12px) !important; }
.sg-grid.won { box-shadow: 0 0 0 3px #f5c542, 0 0 26px rgba(245, 197, 66, 0.6); }
@keyframes sg-pop { from { transform: scale(0.3); } }
/* An on/off button that's on (e.g. Stargaze's Auto ✕). */
button[aria-pressed="true"] { border-color: #f5c542 !important; box-shadow: inset 0 0 0 1px #f5c542; }

/* --- home: game grid, setup, Current/Ended --- */
.gamegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.gametile {
  display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto auto; column-gap: 10px; row-gap: 2px;
  text-align: left; padding: 10px; border-radius: 12px; background: var(--panel); border: 1px solid var(--line); align-items: start;
}
.gicon { grid-row: 1 / span 3; width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center;
         color: #fff; font: 800 1.3rem Georgia, serif; }
.gname { font-weight: 700; }
.gblurb { font-size: 0.8rem; color: var(--muted); line-height: 1.25; }
.gplayers { font-size: 0.75rem; color: var(--accent); }
.tabs .count { display: inline-block; min-width: 1.3em; padding: 0 5px; margin-left: 4px; border-radius: 999px;
               background: var(--bad); color: #fff; font-size: 0.75rem; font-weight: 700; line-height: 1.4; text-align: center; }
.games li.due { border-left: 4px solid var(--accent); }
.tabpage { margin-top: 8px; }
#mine .notify { margin-top: 24px; }
#people-box h3 { font-size: 0.95rem; margin: 10px 0 6px; }
.gicon svg, .licon svg { display: block; width: 100%; height: 100%; }
.gicon { width: 46px; height: 46px; background: none !important; }
.games li { align-items: center; }
.licon { width: 26px; height: 26px; flex: none; }

/* --- Dominoes --- */
body.dominoes { --dt: min(calc((min(100vw, 640px) - 40px) / 9), 44px); }
.dtile { flex: none; user-select: none; -webkit-user-select: none; }
.dtile svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.3)); }
.dtile.v { width: var(--dt); height: calc(var(--dt) * 2); }
.dtile.h { width: calc(var(--dt) * 2); height: var(--dt); }
.d-line { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 3px; padding: 14px 8px;
          min-height: calc(var(--dt) * 3); border-radius: 12px; background: #2f6b4a; margin: 6px 0; }
.d-line .dtile.last { filter: drop-shadow(0 0 5px #ffe58a); }
.d-line.waiting { outline: 2px dashed var(--muted); outline-offset: 3px; }
.d-end { width: calc(var(--dt) * 0.9); height: calc(var(--dt) * 2); padding: 0; font-size: 1.2rem; background: #ffe58a; border: none; color: #1d1b18; }
.d-hand { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; padding: 12px 6px; margin: 6px 0; border-radius: 10px;
          background: var(--panel); min-height: calc(var(--dt) * 2 + 24px); }
.d-hand .dtile { transition: transform 0.12s; cursor: pointer; }
.d-hand .dtile.can { transform: translateY(-6px); }
.d-hand .dtile.chosen { transform: translateY(-10px); filter: drop-shadow(0 0 0 #000) drop-shadow(0 0 6px #2f7d4f); }
.d-hand .dtile.dim { opacity: 0.5; }

/* --- Backgammon --- */
body.backgammon { --pw: min(calc((min(100vw, 640px) - 46px) / 14), 40px); --ph: calc(var(--pw) * 5.2); }
.bg-board {
  display: grid; grid-template-columns: repeat(6, var(--pw)) calc(var(--pw) * 0.9) repeat(6, var(--pw)) calc(var(--pw) * 1.1);
  grid-template-rows: var(--ph) var(--ph); row-gap: calc(var(--pw) * 0.6); justify-content: center;
  background: #e9d3a8; border: 6px solid #6b3f24; border-radius: 8px; padding: 4px 0; margin: 6px auto; width: fit-content; position: relative;
}
.bg-board.waiting { outline: 2px dashed var(--muted); outline-offset: 3px; }
.bg-point { position: relative; display: flex; flex-direction: column; align-items: center; cursor: pointer; }
.bg-point.bottom { flex-direction: column-reverse; }
.bg-point::before { content: ""; position: absolute; inset: 0 2px; z-index: 0; }
.bg-point.top::before { clip-path: polygon(0 0, 100% 0, 50% 88%); }
.bg-point.bottom::before { clip-path: polygon(0 100%, 100% 100%, 50% 12%); }
.bg-point.light::before { background: #3f5f3a; } .bg-point.dark::before { background: #8a3a2a; }
.bg-checker {
  position: relative; z-index: 1; width: calc(var(--pw) * 0.92); height: calc(var(--pw) * 0.92); border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: calc(var(--pw) * 0.4);
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.35);
}
.bg-checker.white { background: radial-gradient(circle at 40% 35%, #fff, #e6dccb); color: #5b4a33; }
.bg-checker.red { background: radial-gradient(circle at 40% 35%, #e0584a, #a2281c); color: #fff; }
.bg-bar { background: #6b3f24; display: flex; flex-direction: column; align-items: center; gap: 2px; padding-top: 4px; cursor: pointer; }
.bg-bar.bottom { flex-direction: column-reverse; padding: 0 0 4px; }
.bg-tray { grid-column: 14; grid-row: 1 / span 2; background: #57331d; display: flex; flex-direction: column; justify-content: space-between; padding: 4px 3px; cursor: pointer; }
.bg-off { display: flex; flex-direction: column; gap: 1px; }
.bg-off.mine { flex-direction: column-reverse; }
.bg-slab { height: calc(var(--pw) * 0.24); border-radius: 2px; }
.bg-slab.white { background: #efe6d6; } .bg-slab.red { background: #c0392b; }
.bg-point.movable .bg-checker:last-child, .bg-point.bottom.movable .bg-checker:last-child,
.bg-bar.movable .bg-checker:last-child { box-shadow: 0 0 0 3px #ffe58a, 0 1px 2px rgba(0, 0, 0, 0.35); }
.bg-point.picked .bg-checker:last-child, .bg-bar.picked .bg-checker:last-child { transform: scale(1.12); box-shadow: 0 0 0 3px #2f7d4f; }
.bg-point.target::after, .bg-tray.target::after { content: ""; position: absolute; inset: 0 2px; background: rgba(255, 229, 138, 0.55); z-index: 0; border-radius: 4px; }
.bg-tray { position: relative; }
.bg-bottom { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; }
.bg-dice { display: flex; gap: 6px; min-height: 40px; }
.bg-die { width: 40px; height: 40px; }
.bg-die svg { width: 100%; height: 100%; }
.bg-die.used { opacity: 0.3; }
.bg-die.tumbling { animation: bg-tumble 0.14s linear infinite; }
@keyframes bg-tumble { 50% { transform: rotate(18deg) translateY(-3px); } }
.bg-dot { display: inline-block; width: 0.8em; height: 0.8em; border-radius: 50%; vertical-align: middle; }
.bg-dot.white { background: #efe6d6; border: 1px solid #8a7a60; } .bg-dot.red { background: #c0392b; }

/* --- Card-table games (gin rummy, Palace, cribbage): body class "cardtable" --- */
body.cardtable {
  --felt: #2c6b40; --felt-light: #3d8a55; --cw: min(calc((min(100vw, 640px) - 40px) / 6.4), 66px);
  background: radial-gradient(ellipse at 50% 0%, var(--felt-light), var(--felt) 70%) fixed var(--felt);
  color: #eef5ef; min-height: 100vh;
}
body.cardtable .muted, body.cardtable .back { color: rgba(238, 245, 239, 0.75); }
body.cardtable .preview.error { color: #ffd2cc; }
body.cardtable .controls button { background: rgba(0, 0, 0, 0.25); color: #fff; border: 1px solid rgba(255, 255, 255, 0.18); }
body.cardtable .controls button.primary { background: #f0c24b; color: #1d1b18; border-color: #f0c24b; }
body.cardtable .endgame { color: rgba(238, 245, 239, 0.7); background: none; border: none; }
body.cardtable .o-player { background: rgba(0, 0, 0, 0.18); }
body.cardtable .o-player .count { color: rgba(238, 245, 239, 0.75); }
body.cardtable .o-player.turn { border-color: #f0c24b; }
body.cardtable details.log summary { color: #eef5ef; }
.g-opp { display: flex; justify-content: center; margin: 4px 0 2px; }
.g-opp .card { --cw: 30px; }
.g-opp .card + .card { margin-left: -21px; }
.g-table { display: flex; justify-content: center; gap: 28px; margin: 8px 0; }
.g-pile { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.g-pile > div { min-width: var(--cw); min-height: calc(var(--cw) * 1.4); cursor: pointer; }
.g-table .card.can { box-shadow: 0 0 0 3px #f0c24b; border-radius: 8%/6%; }
.g-hand { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 12px; margin: 10px 0 2px; min-height: calc(var(--cw) * 1.4 + 12px); }
.g-hand.waiting { opacity: 0.85; }
.g-group { display: flex; flex-wrap: wrap; justify-content: center; gap: 2px; padding: 3px; border-radius: 8px; max-width: 100%; box-sizing: border-box; }
.g-hand:empty { display: none; }
.g-group.meld { background: rgba(255, 255, 255, 0.14); }
.g-group.dead { background: rgba(0, 0, 0, 0.16); }
.g-group.extra { outline: 2px dashed rgba(240, 194, 75, 0.8); }
.g-group.laid { background: rgba(240, 194, 75, 0.3); }
.g-hand .card { cursor: pointer; transition: transform 0.12s; }
.g-hand .card.picked { transform: translateY(-10px); }
.g-hand .card.new svg { filter: drop-shadow(0 0 4px #f0c24b) drop-shadow(0 0 2px #f0c24b); }
.g-dead { text-align: center; font-size: 0.9rem; min-height: 1.3em; }
.g-result .g-side { margin: 10px 0; }
.g-result .g-side-head { margin: 4px 0; font-weight: 600; text-align: center; }
.g-result .small-cards { --cw: min(calc((min(100vw, 640px) - 40px) / 9), 48px); }
.g-result .g-sum { text-align: center; font-weight: 700; font-size: 1.05rem; }
.g-result .g-totals { background: rgba(0, 0, 0, 0.2); border-radius: 10px; padding: 6px 12px; text-align: center; }
.g-result .g-totals p { margin: 4px 0; }
.g-rules li { margin: 6px 0; line-height: 1.4; }

/* --- Yot --- */
.y-dice { display: flex; justify-content: center; gap: 8px; margin: 10px 0 4px; }
.y-die { width: min(17vw, 64px); height: min(17vw, 64px); padding: 0; border: none; background: none; border-radius: 12px;
         transition: transform 0.12s; cursor: pointer; }
.y-die:disabled { cursor: default; opacity: 1; }
.y-die svg { width: 100%; height: 100%; display: block; }
.y-die.held { transform: translateY(8px); box-shadow: 0 0 0 3px var(--accent); }
.y-die.held::after { content: "held"; display: block; font-size: 0.7rem; color: var(--accent); font-weight: 700; margin-top: 4px; }
.y-die.blank svg { opacity: 0.55; }
.y-die.tumbling { animation: bg-tumble 0.14s linear infinite; }
.y-sheet { border-collapse: collapse; margin: 14px auto 4px; font-size: 0.92rem; }
.y-sheet th, .y-sheet td { padding: 5px 8px; border-bottom: 1px solid var(--line, rgba(0, 0, 0, 0.1)); }
.y-sheet tr > th:first-child { text-align: left; font-weight: 500; }
.y-sheet td, .y-sheet tr:first-child th { text-align: center; min-width: 2.6em; }
.y-sheet tr:first-child th { font-weight: 700; max-width: 5em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.y-sheet .turn { background: rgba(47, 125, 79, 0.1); }
.y-sheet td.open { color: var(--muted); font-style: italic; cursor: pointer; background: rgba(240, 194, 75, 0.18); }
.y-sheet td.open.zero { background: transparent; }
.y-sheet td.chosen { background: #f0c24b; color: #1d1b18; font-style: normal; font-weight: 700; }
.y-sheet tr.sub th, .y-sheet tr.sub td { font-size: 0.82rem; color: var(--muted); }
.y-sheet tr.total th, .y-sheet tr.total td { font-weight: 800; border-top: 2px solid currentColor; }

/* --- Sudoku --- */
.su-grid { --s: min(calc((min(100vw, 520px) - 28px) / 9), 52px);
  display: grid; grid-template-columns: repeat(9, var(--s)); width: fit-content; margin: 8px auto;
  border: 3px solid var(--fg); border-radius: 6px; overflow: hidden; background: var(--panel); }
.su-cell { width: var(--s); height: var(--s); padding: 0; margin: 0; border: none; border-radius: 0;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); background: transparent;
  font-size: calc(var(--s) * 0.58); font-family: Georgia, "Times New Roman", serif; color: var(--fg); cursor: pointer;
  display: flex; align-items: center; justify-content: center; }
.su-cell.edge-r { border-right: 2px solid var(--fg); }
.su-cell.edge-b { border-bottom: 2px solid var(--fg); }
.su-cell.given { font-weight: 700; }
.su-cell.entered { color: var(--accent); }
.su-cell.near { background: rgba(47, 125, 79, 0.08); }
.su-cell.same { background: rgba(240, 194, 75, 0.35); }
.su-cell.sel { background: rgba(240, 194, 75, 0.7); }
.su-cell.clash { color: var(--bad, #c62828); }
.su-cell.wrong { color: #fff; background: var(--bad, #c62828); }
.su-notes { display: grid; grid-template-columns: repeat(3, 1fr); width: 100%; height: 100%;
  font-size: calc(var(--s) * 0.3); font-weight: 600; font-family: system-ui, sans-serif; color: var(--fg); opacity: 0.8; line-height: 1; }
.su-cell.sel .su-notes { color: #2b2620; opacity: 1; }   /* dark on the gold, in either theme */
.su-notes span { display: flex; align-items: center; justify-content: center; }
.su-notes span.hl { color: var(--fg); font-weight: 800; }
.su-grid.solved { animation: su-glow 1.2s ease-out; }
@keyframes su-glow { 30% { box-shadow: 0 0 0 6px #f0c24b; } }
.su-pad { display: grid; grid-template-columns: repeat(9, 1fr); gap: 4px; max-width: 520px; margin: 8px auto; }
.su-key { display: flex; flex-direction: column; align-items: center; padding: 6px 0 4px; min-width: 0; }
.su-key .d { font-size: 1.4rem; font-weight: 700; font-family: Georgia, serif; }
.su-key .left { font-size: 0.7rem; color: var(--muted); }
.su-key.pencil .d { font-size: 1rem; font-weight: 400; }
.su-key.done { opacity: 0.4; }
#notes.on { background: var(--accent); color: #fff; }

/* --- Settings (gear) --- */
.home-head { display: flex; align-items: center; justify-content: space-between; }
.gear { background: none; border: none; padding: 6px; color: var(--muted); cursor: pointer; line-height: 0; }
.gear svg { width: 26px; height: 26px; }
.settings { max-width: min(94vw, 360px); color: var(--fg); background: var(--panel); }
.settings h3 { margin: 0 0 6px; }
.seg { display: flex; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; margin: 6px 0 12px; }
.seg button { flex: 1; border: none; border-radius: 0; background: transparent; color: var(--fg); padding: 8px 4px; }
.seg button[aria-pressed="true"] { background: var(--accent); color: #fff; }
.cp-table { width: 46px; height: 46px; border: 2px solid var(--line); }
.cp-table.on { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }

/* --- Palace --- */
.pa-others { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.pa-other { flex: 1 1 40%; }
.pa-other { --cw: 30px; }
.pa-stacks { display: flex; gap: 6px; margin-top: 4px; }
.pa-stack { position: relative; width: var(--cw); aspect-ratio: 5 / 7; }
.pa-stack .card { position: absolute; left: 0; top: 0; }
.pa-stack .card.up { top: calc(var(--cw) * 0.22); left: calc(var(--cw) * 0.08); }
.pa-stack:has(.card.up) { margin-bottom: calc(var(--cw) * 0.22); }
.pa-centre { display: flex; justify-content: center; gap: 34px; margin: 10px 0 0; }
.pa-pile { position: relative; width: calc(var(--cw) * 1.9); height: calc(var(--cw) * 1.4); }
.pa-pile .card { position: absolute; left: calc(var(--cw) * 0.9 + var(--k, 0) * var(--cw) * 0.3); top: 0; }
.pa-pile .card.slot { left: calc(var(--cw) * 0.45); }
.pa-needs { text-align: center; margin: 4px 0 0; font-weight: 600; min-height: 1.3em; }
.pa-table { display: flex; justify-content: center; margin: 8px 0 4px; }
.pa-table .card { cursor: pointer; transition: transform 0.12s; }
.pa-hand { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; margin: 8px 0; min-height: calc(var(--cw) * 1.4 + 10px); }
.pa-hand .card { cursor: pointer; transition: transform 0.12s; }
.pa-hand .card.can, .pa-table .card.can { transform: translateY(-6px); }
.pa-hand .card.picked, .pa-table .card.picked { transform: translateY(-14px); }
.pa-hand .card.picked svg, .pa-table .card.picked svg { filter: drop-shadow(0 0 3px #f0c24b) drop-shadow(0 0 2px #f0c24b); }
.pa-hand .card.dim, .pa-table .card.dim { opacity: 0.55; }
.pa-table .card.down.can svg { filter: drop-shadow(0 0 4px #f0c24b); }

/* --- Reversi --- */
.rv-board { --s: min(calc((min(100vw, 560px) - 52px) / 8), 64px);
  display: grid; grid-template-columns: repeat(8, var(--s)); gap: 2px; padding: 6px; width: fit-content; margin: 8px auto;
  background: #16502f; border-radius: 10px; touch-action: manipulation; }
.rv-board.waiting { outline: 2px dashed var(--muted); outline-offset: 3px; }
.rv-sq { width: var(--s); height: var(--s); padding: 0; border: none; border-radius: 3px; background: #2a8a58;
  display: flex; align-items: center; justify-content: center; cursor: default; }
.rv-sq.can { cursor: pointer; }
.rv-sq.can::after { content: ""; width: 26%; height: 26%; border-radius: 50%; background: rgba(0, 0, 0, 0.28); }
.rv-sq.last { box-shadow: inset 0 0 0 2px #f0c24b; }
.rv-disc { width: 82%; height: 82%; border-radius: 50%; box-shadow: 0 2px 2px rgba(0, 0, 0, 0.35); }
.rv-disc.black { background: radial-gradient(circle at 35% 30%, #4a4642, #141210 70%); }
.rv-disc.white { background: radial-gradient(circle at 35% 30%, #fff, #dcd6c8 70%); }
.rv-disc.flip { animation: rv-flip 0.45s ease-in-out; }
.rv-disc.drop { animation: rv-drop 0.25s ease-out; }
@keyframes rv-flip { 0% { transform: scaleX(1); filter: invert(1); } 50% { transform: scaleX(0); filter: invert(1); } 51% { filter: none; } 100% { transform: scaleX(1); } }
@keyframes rv-drop { from { transform: scale(1.4); opacity: 0.4; } }
.rv-dot { display: inline-block; width: 0.8em; height: 0.8em; border-radius: 50%; vertical-align: middle; border: 1px solid #777; }
.rv-dot.black { background: #1d1b18; } .rv-dot.white { background: #f3efe6; }

/* --- Minesweeper --- */
.ms-bar { display: flex; justify-content: space-between; align-items: center; max-width: 560px; margin: 6px auto; }
.ms-count { font-variant-numeric: tabular-nums; font-weight: 700; min-width: 4em; }
.ms-count:last-child { text-align: right; }
#mode.on { background: var(--accent); color: #fff; }
.ms-grid { --s: min(calc((min(100vw, 560px) - 24px - var(--cols) * 1px) / var(--cols)), 40px);   /* room for the 1px gaps */
  display: grid; grid-template-columns: repeat(var(--cols), var(--s)); gap: 1px; width: fit-content; margin: 0 auto;
  background: #8d969e; border: 2px solid #8d969e; border-radius: 4px; touch-action: manipulation;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.ms-sq { width: var(--s); height: var(--s); padding: 0; border: none; border-radius: 0; background: #b8c0c7;
  box-shadow: inset 2px 2px 0 #d9dee2, inset -2px -2px 0 #8d969e; font-weight: 800; font-size: calc(var(--s) * 0.58);
  font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; line-height: 1; cursor: pointer; }
.ms-sq.open { background: #e9e5dc; box-shadow: none; cursor: default; }
.ms-sq.n1 { color: #2f5d9f; } .ms-sq.n2 { color: #2f7d4f; } .ms-sq.n3 { color: #c62828; } .ms-sq.n4 { color: #283593; }
.ms-sq.n5 { color: #8e2a1e; } .ms-sq.n6 { color: #00838f; } .ms-sq.n7 { color: #1d1b18; } .ms-sq.n8 { color: #757575; }
.ms-sq.mine { color: #1d1b18; }
.ms-sq.boom { background: #d9412e; color: #fff; }
.ms-sq.wrong { background: #f2c4bd; }

/* --- Battleship --- */
.bs-title { text-align: center; margin: 8px 0 4px; font-size: 1rem; }
.bs-grid { display: grid; grid-template-columns: repeat(10, var(--s)); gap: 1px; width: fit-content; margin: 0 auto;
  background: #1a4466; border: 2px solid #1a4466; border-radius: 6px; touch-action: manipulation; }
.bs-grid.big { --s: min(calc((min(100vw, 520px) - 40px) / 10), 46px); }
.bs-grid.small { --s: min(calc((min(100vw, 520px) - 40px) / 16), 26px); }
.bs-grid.waiting { opacity: 0.8; }
.bs-sq { width: var(--s); height: var(--s); padding: 0; border: none; border-radius: 0; background: #2f6a98; position: relative; cursor: pointer; }
.bs-sq.ship { background: #2f6a98; }
.bs-sq.ship::before { content: ""; position: absolute; inset: 14%; background: #b8c0c7; }
.bs-sq.ship.across::before { inset: 16% 0; } .bs-sq.ship.down::before { inset: 0 16%; }
.bs-sq.ship.across.start::before { left: 12%; border-radius: 40% 0 0 40%; } .bs-sq.ship.across.end::before { right: 12%; border-radius: 0 40% 40% 0; }
.bs-sq.ship.down.start::before { top: 12%; border-radius: 40% 40% 0 0; } .bs-sq.ship.down.end::before { bottom: 12%; border-radius: 0 0 40% 40%; }
.bs-sq.ship.chosen::before { background: #f0c24b; }
.bs-sq.ship.sunk::before { background: #5e666d; }
.bs-sq.miss::after { content: ""; position: absolute; inset: 36%; border-radius: 50%; background: #bcd4ea; }
.bs-sq.hit::after { content: "✕"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 900; font-size: calc(var(--s) * 0.6); background: radial-gradient(circle, #e8553f 45%, transparent 47%); }
.bs-sq.aim { box-shadow: inset 0 0 0 3px #f0c24b; }
.bs-sq.last { animation: bs-flash 0.8s ease-out; }
@keyframes bs-flash { 0% { filter: brightness(2); } }
.bs-fleet { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 12px; margin: 6px 0; font-size: 0.85rem; }
.bs-ship-tag.sunk { text-decoration: line-through; color: var(--muted); }

/* --- Mahjong solitaire: on a dark jade table --- */
body.mahjong { background: radial-gradient(ellipse at 50% 0%, #2f6f5a, #173d31 75%) fixed #173d31; color: #eef5ef; min-height: 100vh; }
body.mahjong .muted, body.mahjong .back { color: rgba(238, 245, 239, 0.75); }
body.mahjong .preview.error { color: #ffd2cc; }
body.mahjong .controls button { background: rgba(0, 0, 0, 0.25); color: #fff; border: 1px solid rgba(255, 255, 255, 0.18); }
body.mahjong .controls button.primary { background: #f0c24b; color: #1d1b18; border-color: #f0c24b; }
body.mahjong .endgame { color: rgba(238, 245, 239, 0.7); background: none; border: none; }
body.mahjong details.log summary { color: #eef5ef; }
.mj-board { position: relative; margin: 10px auto; isolation: isolate; }   /* tiles' z-indexes stay inside the board */
/* Solitaire: a tile's face is a little smaller than its spot, so its side fills the gap and
   tiles on one layer sit side by side instead of overlapping their neighbours */
.mj-board .mj-tile { width: calc(var(--w) * 0.9); height: calc(var(--w) * 4 / 3 - var(--w) * 0.1);
  box-shadow: 1px 1px 0 #d8caa4, calc(var(--w) * 0.06) calc(var(--w) * 0.06) 0 #c4b083,
              calc(var(--w) * 0.08) calc(var(--w) * 0.08) 0 #2c7a55, calc(var(--w) * 0.09) calc(var(--w) * 0.09) 2px rgba(0, 0, 0, 0.4); }
.mj-board .mj-tile.same { outline: 2px solid rgba(240, 194, 75, 0.9); outline-offset: -2px; }
.mj-tile { position: absolute; width: var(--w); height: calc(var(--w) * 4 / 3); padding: calc(var(--w) * 0.04);
  border: none; border-radius: calc(var(--w) * 0.12); background: linear-gradient(160deg, #fffdf6, #f1e8d2);
  box-shadow: 1px 1px 0 #d8caa4, calc(var(--w) * 0.07) calc(var(--w) * 0.07) 0 #c4b083,
              calc(var(--w) * 0.1) calc(var(--w) * 0.1) 0 #2c7a55, calc(var(--w) * 0.11) calc(var(--w) * 0.11) 2px rgba(0, 0, 0, 0.45);
  cursor: pointer; transition: opacity 0.18s, transform 0.18s; }
.mj-tile svg { width: 100%; height: 100%; display: block; }
.mj-tile.blocked { filter: brightness(0.78) saturate(0.8); cursor: default; }
.mj-tile.picked { background: linear-gradient(160deg, #fff4b8, #f0d878); transform: translateY(-3px); }
.mj-tile.hint { animation: mj-hint 0.9s ease-in-out 2; }
@keyframes mj-hint { 50% { background: #bfe7c9; transform: translateY(-4px); } }
.mj-tile.going { opacity: 0; transform: scale(0.7); }
.mj-tile.shake { animation: shake 0.35s; }

/* --- Cribbage --- */
.cb-board svg { width: 100%; max-width: 560px; display: block; margin: 4px auto; }
.cb-peg { display: inline-block; width: 0.75em; height: 0.75em; border-radius: 50%; vertical-align: middle; border: 1px solid #fff; }
.cb-table { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin: 8px 0; }
.cb-table .card { --cw: min(15vw, 56px); }
.cb-play { flex: 1; display: flex; flex-direction: column; align-items: center; }
.cb-seq { position: relative; height: calc(min(15vw, 56px) * 1.4); width: 100%; display: flex; justify-content: center; }
.cb-seq .card { --cw: min(15vw, 56px); margin-left: calc(var(--cw) * -0.55); }
.cb-seq .card:first-child { margin-left: 0; }
.cb-count { font-weight: 800; font-size: 1.2rem; margin-top: 4px; }
.cb-show .cb-hand { margin: 10px 0; text-align: center; }
.cb-show .g-hand { --cw: min(calc((min(100vw, 640px) - 60px) / 5.5), 54px); justify-content: center; }
.cb-show .card.starter { margin-left: 10px; outline: 2px dashed rgba(240, 194, 75, 0.8); outline-offset: 2px; border-radius: 6px; }
.cb-parts { margin: 4px 0; color: rgba(238, 245, 239, 0.85); }
.pa-hand:empty { display: none; }

/* --- Solitude: any patience game, laid out from the server's pile positions --- */
.so-felt { position: relative; margin: 8px auto; touch-action: pinch-zoom; min-height: 200px; }
.so-felt .so-pile { position: absolute; width: var(--cw); height: calc(var(--cw) * 1.4); }
.so-felt .so-pile .card { position: absolute; left: 0; top: 0; }
.so-felt .so-slot { border-color: rgba(255, 255, 255, 0.35); }
.so-felt .so-slot[data-label]::after { content: attr(data-label); position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: rgba(255, 255, 255, 0.45); font-weight: 700; font-size: calc(var(--cw) * 0.28); text-align: center; }
.so-felt .so-slot.recycle::after { content: "↻"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: rgba(255, 255, 255, 0.5); font-size: calc(var(--cw) * 0.5); }
.so-felt [data-stock] { cursor: pointer; }
.so-felt .so-pile.peak .card.blocked svg { filter: brightness(0.75) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25)); }
.so-felt .card.picked svg { filter: drop-shadow(0 0 4px #f0c24b) drop-shadow(0 0 2px #f0c24b); }
.so-felt .pdrop { outline: 2px solid #f0c24b; outline-offset: 2px; border-radius: 8%; }
.so-blurb { text-align: center; max-width: 520px; margin: 8px auto; }
.so-felt .so-pile.peak .so-slot { visibility: hidden; }   /* a cleared pyramid/peak position just disappears */
.bs-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 14px; font-size: 0.8rem; color: var(--muted); margin: 6px 0; }
.bs-legend span { display: inline-flex; align-items: center; gap: 5px; }
.bs-legend .bs-sq { --s: 18px; display: inline-block; cursor: default; }

/* --- Menu trees (new game, Solitude) --- */
details.tree { margin: 6px 0; border-bottom: 1px solid var(--line); padding-bottom: 6px; }
details.tree > summary { cursor: pointer; font-size: 1.15rem; font-weight: 700; padding: 8px 2px; list-style: none; }
details.tree > summary::-webkit-details-marker { display: none; }
details.tree > summary::before { content: "▸"; display: inline-block; width: 1.1em; transition: transform 0.15s; color: var(--muted); }
details.tree[open] > summary::before { transform: rotate(90deg); }

/* --- Mastermind --- */
.mm-board { max-width: 360px; margin: 6px auto; background: #7a5230; border-radius: 10px; padding: 6px 10px; }
.mm-row { display: flex; align-items: center; gap: 10px; padding: 3px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.2); }
.mm-row.current { background: rgba(255, 255, 255, 0.12); border-radius: 6px; }
.mm-row.secret { border-bottom: 3px solid rgba(0, 0, 0, 0.35); padding-bottom: 6px; margin-bottom: 4px; }
.mm-num { width: 1.6em; color: #f3e3c6; font-size: 0.8rem; text-align: right; }
.mm-pegs { display: flex; gap: 8px; flex: 1; }
.mm-peg { width: 30px; height: 30px; border-radius: 50%; background: #4f3420; box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.5);
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px; color: rgba(0, 0, 0, 0.45); }
.mm-peg.filled { box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.4); cursor: pointer; }
.mm-peg.hidden { color: #f3e3c6; font-weight: 800; }
.mm-marks { display: grid; grid-template-columns: repeat(3, 10px); gap: 3px; width: 40px; }
.mm-marks i { width: 10px; height: 10px; border-radius: 50%; }
.mm-marks i.b { background: #1d1b18; } .mm-marks i.w { background: #fff; }
.mm-palette { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 10px auto; max-width: 360px; }
.mm-pick { padding: 4px; border-radius: 50%; }
.mm-pick .mm-peg { width: 36px; height: 36px; font-size: 16px; }

/* --- Word grid --- */
.wg-clock { font-weight: 800; font-variant-numeric: tabular-nums; font-size: 1.2rem; }
.wg-clock.low { color: var(--bad); }
.wg-current { text-align: center; font-size: 1.6rem; font-weight: 800; letter-spacing: 0.08em; min-height: 2.2rem; }
.wg-grid { --g: min(calc(100vw - 32px), 420px); display: grid; grid-template-columns: repeat(var(--n), 1fr); gap: 6px;
  width: var(--g); margin: 4px auto; padding: 8px; background: #2f5d9f; border-radius: 14px; touch-action: none;
  user-select: none; -webkit-user-select: none; }
.wg-grid.hidden .wg-die { filter: blur(7px); }
.wg-die { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; border-radius: 10px;
  background: linear-gradient(160deg, #fffdf6, #ece2c8); color: #1d1b18; font-weight: 800;
  font-size: calc(var(--g) / var(--n) * 0.42); box-shadow: 0 3px 0 #b9a978; cursor: pointer; }
.wg-die.on { background: #f0c24b; }
.wg-die.last { background: #f28c28; color: #fff; }
.wg-found, .wg-results { max-width: 520px; margin: 8px auto; text-align: center; }
.wg-words { line-height: 1.7; word-spacing: 0.3em; }
.wg-words .shared { text-decoration: line-through; color: var(--muted); }
.wg-words.missed { color: var(--muted); font-size: 0.85rem; }

/* --- Who is it? --- */
.wi-top { display: flex; justify-content: center; gap: 16px; margin: 4px 0; }
.wi-secret { display: flex; align-items: center; gap: 8px; background: var(--panel); border-radius: 10px; padding: 4px 10px 4px 4px; }
.wi-secret .wi-face { width: 54px; }
.wi-secret p { margin: 0; }
.wi-name { font-weight: 800; }
.wi-ask { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; margin: 6px 0; }
.wi-ask select { flex: 1 1 200px; max-width: 320px; font-size: 1rem; padding: 6px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--fg); }
#name-mode.on { background: var(--bad); color: #fff; }
.wi-board { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; max-width: 520px; margin: 6px auto; }
@media (min-width: 560px) { .wi-board { grid-template-columns: repeat(6, 1fr); } }
.wi-card { padding: 3px 3px 2px; border-radius: 10px; background: var(--panel); border: 2px solid transparent; font-size: 0.78rem;
  display: flex; flex-direction: column; align-items: center; gap: 1px; transition: transform 0.3s, opacity 0.3s, filter 0.3s; cursor: pointer; }
.wi-card .wi-face { width: 100%; }
.wi-face svg { display: block; width: 100%; height: auto; border-radius: 6px; }
.wi-card.down { opacity: 0.35; filter: grayscale(1); transform: scale(0.92); }
.wi-board.naming .wi-card:not(.down) { border-color: #f0c24b; }
.wi-card.answer { border-color: var(--accent); opacity: 1; filter: none; transform: none; }

/* --- Chess --- */
.ch-board { --s: min(calc((min(100vw, 560px) - 24px) / 8), 64px); display: grid; grid-template-columns: repeat(8, var(--s));
  width: fit-content; margin: 8px auto; border: 4px solid #6b4a2e; border-radius: 4px; touch-action: manipulation; }
.ch-board.waiting { outline: 2px dashed var(--muted); outline-offset: 3px; }
.ch-sq { width: var(--s); height: var(--s); padding: 0; border: none; border-radius: 0; position: relative; display: flex; align-items: center; justify-content: center; }
.ch-sq.light { background: #eedfc0; } .ch-sq.dark { background: #b5875a; }
.ch-sq.last { box-shadow: inset 0 0 0 100px rgba(240, 200, 60, 0.38); }
.ch-sq.picked { box-shadow: inset 0 0 0 100px rgba(47, 125, 79, 0.45); }
.ch-sq.check { box-shadow: inset 0 0 calc(var(--s) * 0.35) rgba(217, 65, 46, 0.95); }
.ch-sq.target::after { content: ""; width: 28%; height: 28%; border-radius: 50%; background: rgba(30, 30, 30, 0.3); }
.ch-sq.capture::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; border: 4px solid rgba(30, 30, 30, 0.3); }
.ch-sq[data-rank]::before { content: attr(data-rank); position: absolute; left: 2px; top: 1px; font-size: 9px; color: rgba(0, 0, 0, 0.45); }
.ch-sq[data-file] .ch-piece::after { content: none; }
.ch-sq[data-file]::after { }
.ch-piece { width: 88%; height: 88%; position: relative; z-index: 1; }
.ch-piece svg { width: 100%; height: 100%; display: block; }
.ch-sq.movable { cursor: pointer; }
.ch-moves { max-width: 520px; margin: 6px auto; font-size: 0.85rem; color: var(--muted); line-height: 1.6; word-spacing: 0.15em; }
.ch-choices { display: flex; gap: 8px; }
.ch-choices button { width: 60px; height: 60px; padding: 4px; }

/* --- Lines of Five --- */
.ln-board { --s: min(calc((min(100vw, 560px) - 52px) / 10), 52px); display: grid; grid-template-columns: repeat(10, var(--s)); gap: 2px;
  width: fit-content; margin: 6px auto; padding: 4px; background: #1d3f2a; border-radius: 8px; touch-action: manipulation; }
.ln-sq { width: var(--s); height: calc(var(--s) * 1.18); padding: 0; border: none; border-radius: 4px; background: #fbf7ee; color: #1f1f1f;
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1;
  font-weight: 700; font-family: Georgia, serif; font-size: calc(var(--s) * 0.34); }
.ln-sq .s { font-size: calc(var(--s) * 0.36); }
.ln-sq.red { color: #c62828; }
.ln-sq.corner { background: #f0c24b; color: #7a5a10; font-size: calc(var(--s) * 0.5); }
.ln-sq.target { box-shadow: 0 0 0 3px #f0c24b; cursor: pointer; z-index: 1; }
.ln-sq.takeable { box-shadow: 0 0 0 3px #ff8a80; cursor: pointer; z-index: 1; }
.ln-sq.last { outline: 2px solid #fff; outline-offset: -2px; }
.ln-chip { position: absolute; inset: 14%; border-radius: 50%; box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.5); opacity: 0.92; }
.ln-chip.line { box-shadow: 0 0 0 3px #fff, inset 0 -3px 0 rgba(0, 0, 0, 0.3); }
.ln-dot { display: inline-block; width: 0.8em; height: 0.8em; border-radius: 50%; vertical-align: middle; }
.lines .pa-hand .card { --cw: min(calc((min(100vw, 640px) - 40px) / 7.4), 64px); cursor: pointer; transition: transform 0.12s; }
.lines .pa-hand .card.picked { transform: translateY(-12px); }
.lines .pa-hand .card[data-jack]::after { content: attr(data-jack); position: absolute; bottom: -1.4em; left: 0; right: 0; text-align: center; font-size: 0.7rem; color: #f0c24b; font-weight: 700; }

/* --- Stacked tiles (Stack Words, on the word game's board) --- */
/* The tiles underneath peek out down and to the right, each turned a little; the top tile carries the height. */
.sq .stack { position: absolute; inset: 0; }
.sq .stack > .tile, .sq .stack > .under { inset: 0 14% 14% 0; }
.sq .stack > .under { position: absolute; background: var(--tile); border-radius: 3px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35); filter: brightness(0.8); }
.sq .stack > .under.u1 { transform: translate(14%, 14%) rotate(5deg); }
.sq .stack > .under.u2 { transform: translate(10%, 7%) rotate(-6deg); }
.sq .stack > .under.u3 { transform: translate(6%, 12%) rotate(8deg); }
.sq .stack > .under.u4 { transform: translate(13%, 4%) rotate(-4deg); }
.sq .stack > .tile { transform: rotate(-2deg); box-shadow: inset 0 -2px 0 var(--tile-edge), 1px 1px 2px rgba(0, 0, 0, 0.4); }
.tile .height { position: absolute; left: 3px; top: 1px; font-size: calc(var(--cell) * 0.24); font-weight: 800; opacity: 0.7; }

/* --- Poker --- */
.pk-seats { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin: 6px 0; }
.pk-seat { background: rgba(0, 0, 0, 0.2); border-radius: 10px; padding: 6px 8px; border: 2px solid transparent; min-width: 110px; text-align: center; }
.pk-seat.turn { border-color: #f0c24b; }
.pk-seat.won { border-color: #7fe0a0; box-shadow: 0 0 12px rgba(127, 224, 160, 0.5); }
.pk-seat.folded { opacity: 0.55; } .pk-seat.out { opacity: 0.35; }
.pk-seat p { margin: 1px 0; } .pk-seat .nm { font-weight: 700; } .pk-seat .st, .pk-seat .bt { font-size: 0.8rem; color: rgba(238, 245, 239, 0.8); }
.pk-seat .hole { display: flex; gap: 3px; justify-content: center; margin: 3px 0; }
.pk-seat .hole .card { --cw: 34px; }
.pk-seat.me { display: flex; align-items: center; gap: 12px; justify-content: center; margin: 6px auto; max-width: 360px; }
.pk-seat.me .hole .card { --cw: min(18vw, 70px); }
.pk-middle { text-align: center; margin: 8px 0; }
.pk-board { display: flex; gap: 5px; justify-content: center; }
.pk-board .card { --cw: min(calc((100vw - 60px) / 5.4), 64px); }
.pk-pot { font-weight: 800; font-size: 1.15rem; margin: 6px 0 0; }
.pk-raise { max-width: 360px; margin: 6px auto; text-align: center; }
.pk-raise input { width: 100%; }

/* --- Whist / Oh Hell --- */
.tr-score { text-align: center; font-weight: 700; margin: 4px 0; }
.tr-seats { display: flex; flex-wrap: wrap; gap: 5px; justify-content: center; margin: 6px 0; }
.tr-seat { background: rgba(0, 0, 0, 0.2); border-radius: 8px; padding: 4px 8px; border: 2px solid transparent; display: flex; flex-direction: column; align-items: center; min-width: 74px; }
.tr-seat.turn { border-color: #f0c24b; }
.tr-seat.side0 { box-shadow: inset 0 -3px 0 rgba(127, 224, 160, 0.6); } .tr-seat.side1 { box-shadow: inset 0 -3px 0 rgba(255, 138, 128, 0.6); }
.tr-seat .nm { font-weight: 700; font-size: 0.85rem; } .tr-seat .st { font-size: 0.75rem; color: rgba(238, 245, 239, 0.8); }
.tr-table { display: flex; justify-content: center; align-items: center; gap: 16px; min-height: calc(min(16vw, 60px) * 1.4 + 26px); margin: 8px 0; }
.tr-trick { display: flex; gap: 6px; }
.tr-played { display: flex; flex-direction: column; align-items: center; font-size: 0.72rem; gap: 2px; }
.tr-played .card { --cw: min(16vw, 60px); }
.tr-played.won .card { box-shadow: 0 0 0 3px #7fe0a0; border-radius: 8%; }
.tr-trump { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.tr-trump .card { --cw: 34px; }
.tr-bids { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin: 6px 0; }
.tr-bids button { min-width: 42px; font-size: 1.1rem; font-weight: 700; }
.tr-hand .card { --cw: min(calc((min(100vw, 640px) - 30px) / 7.2), 64px); margin: 0 -2px; cursor: pointer; transition: transform 0.12s; }
.tr-hand .card.can { transform: translateY(-8px); }
.tr-hand .card.dim { opacity: 0.55; }

/* --- Mahjong (four seats) --- */
.m4-tile { width: var(--tw, 22px); aspect-ratio: 3 / 4; background: linear-gradient(160deg, #fffdf6, #f1e8d2); border-radius: 3px;
  box-shadow: 1px 1px 0 #c4b083, 2px 2px 0 #2c7a55; padding: 1px; flex: none; }
.m4-tile svg { width: 100%; height: 100%; display: block; }
.m4-others { display: grid; gap: 6px; }
.m4-player { background: rgba(0, 0, 0, 0.18); border-radius: 10px; padding: 5px 8px; border: 2px solid transparent; }
.m4-player.turn { border-color: #f0c24b; }
.m4-player .nm { margin: 0 0 3px; font-size: 0.85rem; font-weight: 700; }
.m4-sets { display: flex; flex-wrap: wrap; gap: 6px; }
.m4-sets.small .m4-tile, .m4-discards .m4-tile { --tw: 18px; }
.m4-set { display: flex; gap: 1px; }
.m4-discards { display: flex; flex-wrap: wrap; gap: 2px; margin-top: 3px; }
.m4-tile.fresh { outline: 2px solid #f0c24b; }
.m4-centre { display: flex; flex-direction: column; align-items: center; min-height: 10px; margin: 6px 0; }
.m4-tile.big { --tw: 54px; box-shadow: 2px 2px 0 #c4b083, 4px 4px 0 #2c7a55; }
#mysets { justify-content: center; margin: 6px 0; } #mysets .m4-tile { --tw: 30px; }
.m4-hand { display: flex; flex-wrap: wrap; justify-content: center; gap: 3px; margin: 8px 0; }
.m4-hand .m4-tile { --tw: min(calc((100vw - 60px) / 7.5), 48px); cursor: pointer; transition: transform 0.12s; }
.m4-hand .m4-tile.drawn { margin-left: 10px; }
.m4-hand .m4-tile.picked { transform: translateY(-10px); background: linear-gradient(160deg, #fff4b8, #f0d878); }
.m4-result { text-align: center; } .m4-result .m4-sets { justify-content: center; } .m4-result .m4-tile { --tw: 26px; }
.m4-discards.mine { flex-basis: 100%; justify-content: center; opacity: 0.85; }

/* --- Cities & Roads --- */
.cr-dock { display: flex; align-items: center; gap: 12px; justify-content: center; margin: 6px 0; }
.cr-current { width: 64px; height: 64px; flex: none; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35); border-radius: 4px; overflow: hidden; }
.cr-current svg { width: 100%; height: 100%; display: block; }
.cr-scroller { overflow: auto; max-height: 62vh; border-radius: 10px; background: #2e4a2a; margin: 6px 0; touch-action: pan-x pan-y pinch-zoom; }
.cr-board { position: relative; margin: 32px; }
.cr-tile, .cr-spot { position: absolute; width: 64px; height: 64px; }
.cr-tile svg, .cr-spot svg { width: 100%; height: 100%; display: block; }
.cr-tile.placed { outline: 3px solid #f0c24b; z-index: 2; }
.cr-spot { border: 2px dashed rgba(255, 255, 255, 0.55); background: rgba(255, 255, 255, 0.06); padding: 0; border-radius: 3px; cursor: pointer; }
.cr-spot.trying { border: 3px solid #f0c24b; background: none; z-index: 3; }
.cr-opt { cursor: pointer; }

/* --- 500 --- */
.fh-grid { display: grid; grid-template-columns: 2em repeat(5, 1fr); gap: 4px; max-width: 380px; margin: 6px auto; }
.fh-grid button { padding: 6px 0; font-variant-numeric: tabular-nums; font-weight: 700; }
.fh-head { display: flex; align-items: center; justify-content: center; font-weight: 800; }
.tr-seat.out { opacity: 0.45; }
.fh .tr-hand .card.picked { transform: translateY(-14px); }

/* --- Logic puzzles (logic.js) --- */
.lg-board { display: flex; justify-content: center; margin: 8px auto; touch-action: pinch-zoom; user-select: none; -webkit-user-select: none; }
.lg-board[data-tool="digits"] { touch-action: manipulation; }
.lg-svg { display: block; max-width: 100%; height: auto; }
.lg-svg text { font-family: system-ui, sans-serif; }
.lg-svg.solved { animation: su-glow 1.2s ease-out; border-radius: 6px; }
.lg-cell { fill: var(--panel); }
.lg-cell.near { fill: color-mix(in srgb, var(--accent) 9%, var(--panel)); }
.lg-cell.same { fill: color-mix(in srgb, #f0c24b 35%, var(--panel)); }
.lg-cell.sel { fill: color-mix(in srgb, #f0c24b 70%, var(--panel)); }
.lg-cell.given { fill: color-mix(in srgb, var(--fg) 7%, var(--panel)); }
.lg-cell.filled { fill: var(--fg); }
.lg-cell.black { fill: #26221e; }
.lg-cell.lit { fill: color-mix(in srgb, #f5d24a 32%, var(--panel)); }
.lg-cell.grass { fill: color-mix(in srgb, #7cbf6a 35%, var(--panel)); }
.lg-cell.on { fill: #f5c542; } .lg-cell.off { fill: #2e3440; }
.lg-cell.wrong { fill: color-mix(in srgb, var(--bad, #c62828) 45%, var(--panel)); }
.lg-grid { stroke: var(--line); stroke-width: 1; }
.lg-grid.thick { stroke: var(--fg); stroke-width: 2; }
.lg-digit { fill: var(--fg); font-family: Georgia, "Times New Roman", serif !important; }
.lg-digit.given { font-weight: 700; } .lg-digit.entered { fill: var(--accent); }
.lg-digit.clash { fill: var(--bad, #c62828); }
.lg-note { fill: var(--fg); opacity: 0.8; font-weight: 600; }
.lg-calc { fill: none; stroke: #3c78b5; stroke-width: 3; pointer-events: none; }
.lg-sums { align-items: center; margin-top: 6px; }
.lg-sums { flex-wrap: nowrap; gap: 4px; }
.lg-sums button { padding: 0.35rem 0.6rem; flex: 1 1 auto; min-width: 0; max-width: 7rem; }
.lg-sums-out { min-height: 1.4em; }
.lg-sums-out button { padding: 0.2rem 0.9rem; margin: 4px 3px 0; }
.lg-calc.out { stroke-dasharray: 5 4; }
.lg-cell.insum { fill: color-mix(in srgb, #3c78b5 22%, var(--panel)); }
.lg-sums-log { margin: 6px auto; padding: 2px; list-style: none; max-width: 520px; font-size: 14px;
  max-height: 10em; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
.lg-sums-log:empty { display: none; }
.lg-mini { flex: none; width: 34px; height: 34px; }
.lg-mini .in { fill: color-mix(in srgb, #3c78b5 50%, transparent); }
.lg-mini .open { fill: #3c78b5; }
.lg-mini path, .lg-mini .edge { fill: none; stroke: var(--muted); stroke-width: 0.15; }
.lg-sums-log li + li { border-top: 1px solid var(--line); }
.lg-sums-log li { display: flex; text-align: left; align-items: center; gap: 6px; padding: 4px 8px; border-radius: 6px; cursor: pointer; color: var(--muted); }
.lg-sums-log li.on { background: color-mix(in srgb, #3c78b5 22%, var(--panel)); color: var(--fg); }
.lg-log-x { margin-left: auto; padding: 0 8px; border: none; background: none; color: var(--muted); font-size: 18px; }
.lg-cage { stroke: var(--fg); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.75; }
.lg-cage-wall { stroke: var(--fg); stroke-width: 2.5; stroke-linecap: square; }
.lg-cage-n { fill: var(--fg); font-weight: 700; }
.lg-cage-n.over, .lg-clue.over, .lg-black-n.over { fill: var(--bad, #c62828); }
.lg-clue { fill: var(--fg); font-weight: 700; }
.lg-clue.done { fill: var(--muted); font-weight: 400; }
.lg-cross { stroke: var(--muted); stroke-width: 2; stroke-linecap: round; }
.lg-bin.b1 { fill: #fbf6ea; stroke: var(--fg); stroke-width: 1.5; } .lg-bin.b2 { fill: #2f4a6e; }
.lg-bin.clash { stroke: var(--bad, #c62828); stroke-width: 3; }
.lg-bin-n { font-weight: 700; } .lg-bin-n.b1 { fill: #2b2620; } .lg-bin-n.b2 { fill: #fff; }
.lg-bin-n.given { text-decoration: underline; }
.lg-tree { fill: #2f7d3a; } .lg-trunk { fill: #7a4f2a; }
.lg-tent { fill: #e0782f; } .lg-tent.clash { fill: var(--bad, #c62828); } .lg-tent-door { fill: #7a3a12; }
.lg-black-n { fill: #fff; font-weight: 700; } .lg-black-n.done { fill: #8a8378; }
.lg-bulb { fill: #f5c542; stroke: #b88a12; stroke-width: 1.5; } .lg-bulb.clash { fill: var(--bad, #c62828); }
.lg-dot { fill: var(--muted); }
.lg-sea { fill: color-mix(in srgb, #4a90c2 14%, var(--panel)); }
.lg-bridge { stroke: var(--fg); stroke-width: 3; stroke-linecap: round; } .lg-bridge.wrong { stroke: var(--bad, #c62828); }
.lg-island { fill: var(--panel); stroke: var(--fg); stroke-width: 2; }
.lg-island.done { fill: var(--accent); stroke: var(--accent); } .lg-island.over { stroke: var(--bad, #c62828); stroke-width: 3; }
.lg-island.picked { stroke: #f0c24b; stroke-width: 4; }
.lg-island-n { fill: var(--fg); font-weight: 800; } .lg-island-n.done { fill: #fff; }
.lg-pipebg { fill: #1e2a33; }
.lg-pipecell { fill: none; stroke: #33444f; } .lg-pipecell.wrong { fill: rgba(198, 40, 40, 0.35); }
.lg-pipe { stroke: #8d9aa3; stroke-linecap: round; } .lg-pipe.wet { stroke: #4fb3ff; }
.lg-pipe-joint { fill: #8d9aa3; } .lg-pipe-joint.wet { fill: #4fb3ff; }
.lg-end { fill: #1e2a33; stroke: #8d9aa3; stroke-width: 3; } .lg-end.wet { stroke: #4fb3ff; fill: #cfe9ff; }
.lg-tap { fill: #f0c24b; stroke: #8a6a10; stroke-width: 2; }
.lg-tile { fill: #e9d3a6; stroke: #b49a6a; stroke-width: 1.5; } .lg-tile.home { fill: #cfe3c4; stroke: #8fb07c; }
.lg-tile-n { fill: #2b2620; font-weight: 800; }

/* --- Mahjong connect --- */
.mc-line { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 1000; opacity: 0; }
.mc-line polyline { fill: none; stroke: #f0c24b; stroke-width: 4; stroke-linejoin: round; stroke-linecap: round; filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.6)); }
.mc-line.show { animation: mc-flash 0.7s ease-out; }
@keyframes mc-flash { 0%, 50% { opacity: 1; } 100% { opacity: 0; } }
.mc-board .mj-tile { box-shadow: 1px 1px 0 #d8caa4, calc(var(--w) * 0.05) calc(var(--w) * 0.05) 0 #c4b083, calc(var(--w) * 0.06) calc(var(--w) * 0.06) 2px rgba(0, 0, 0, 0.4); }

/* --- Gem swap --- */
html:has(body.match3) { background: #1b2a44; }
body.match3 { background: linear-gradient(180deg, #2a2346, #1b2a44); min-height: 100vh; color: #f3eee6; }
.m3-combo:empty { display: none; }
body.match3 .status, body.match3 .muted, body.match3 .back, body.match3 summary, body.match3 .small { color: #e6e0f0; }
.m3-hud { display: flex; align-items: baseline; justify-content: center; gap: 12px; margin: 4px 0; }
.m3-score { font-size: 2rem; font-weight: 800; color: #ffd54f; font-variant-numeric: tabular-nums; }
.m3-combo { font-weight: 800; color: #ff80ab; opacity: 0; }
.m3-combo.show { animation: m3-combo 1s ease-out; }
@keyframes m3-combo { 0% { opacity: 1; transform: scale(1.3); } 70% { opacity: 1; } 100% { opacity: 0; transform: scale(1); } }
.m3-board { position: relative; margin: 6px auto; border-radius: 12px; overflow: hidden; touch-action: pinch-zoom; user-select: none; -webkit-user-select: none;
  background: repeating-conic-gradient(rgba(255, 255, 255, 0.07) 0 25%, rgba(255, 255, 255, 0.02) 0 50%) 0 0 / calc(var(--s) * 2) calc(var(--s) * 2); }
.m3-gem { position: absolute; left: 0; top: 0; width: var(--s); height: var(--s); padding: calc(var(--s) * 0.06); box-sizing: border-box;
  transition: transform 0.22s ease-in, opacity 0.2s, scale 0.2s; cursor: pointer; }
.m3-gem svg { width: 100%; height: 100%; display: block; pointer-events: none; }
.m3-gem.picked { scale: 1.12; filter: drop-shadow(0 0 6px #fff); }
.m3-gem.pop { opacity: 0; scale: 1.5; }
.m3-gem.hint { animation: m3-hint 0.6s ease-in-out 3; }
@keyframes m3-hint { 50% { scale: 1.2; filter: drop-shadow(0 0 6px #fff); } }
.lg-wall { stroke: #e9e2d0; stroke-width: 4; stroke-linecap: round; }
.lg-flowcell { fill: #14161c; } .lg-flowgrid { stroke: #3a3f4b; stroke-width: 1; }
.lg-flowdot { stroke: rgba(0, 0, 0, 0.35); stroke-width: 1.5; }
.mc-board .mj-tile.same { background: linear-gradient(160deg, #e6f7e9, #b9e4c2); box-shadow: 0 0 0 3px #f0c24b, calc(var(--w) * 0.05) calc(var(--w) * 0.05) 0 #c4b083; }

/* Selecting games on the home page */
.listbar { display: flex; justify-content: flex-end; gap: 8px; margin: 0 0 6px; min-height: 0; }
.listbar button { padding: 0.3rem 0.8rem; }
.linkish { background: none; border: none; color: var(--accent); }
.games li.selectable { cursor: pointer; } .games li.selectable a { pointer-events: none; }
.games li.chosen { outline: 2px solid var(--accent); }
.games li .pick { width: 20px; height: 20px; margin: 0; accent-color: var(--accent); pointer-events: none; }
.report-link { margin-top: 4px; }
dialog.report form { display: grid; gap: 10px; min-width: min(80vw, 360px); }
dialog.report h3 { margin: 0; }
dialog.report textarea { width: 100%; box-sizing: border-box; font: inherit; padding: 8px; border-radius: 8px; border: 1px solid var(--line); background: var(--bg); color: var(--fg); }
dialog.report .note { margin: 0; min-height: 1em; }

/* The settings dialog's sections (common.js Prefs) */
dialog.settings { max-height: 88vh; overflow: auto; }
dialog.settings .sections p { margin: 10px 0 4px; }
.cp-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
.cp-row .card { --cw: 46px; }
.cp-row .cp-opt span:empty { display: none; }
.cp-row .cp-table { width: 40px; height: 40px; border-radius: 8px; border: none; }
.mj-tile.mj-sample { position: static; --w: 38px; cursor: default; }
dialog.settings form.controls { align-items: center; justify-content: flex-end; margin-top: 12px; }
.status .gear { margin-left: 6px; }
dialog.settings .muted { color: color-mix(in srgb, currentColor 62%, transparent); }   /* felt pages lighten --muted; the dialog isn't on the felt */

/* Toasts: "your turn" in another game (common.js showToasts) */
#toasts { position: fixed; top: 8px; left: 50%; transform: translateX(-50%); z-index: 1000;
  width: min(calc(100vw - 32px), 420px); display: flex; flex-direction: column; gap: 6px; pointer-events: none; }
.toast { pointer-events: auto; touch-action: pan-y; user-select: none; cursor: pointer;
  background: var(--panel); color: var(--fg); border: 1px solid var(--line); border-left: 4px solid var(--accent);
  border-radius: 8px; padding: 8px 12px; box-shadow: 0 4px 14px rgb(0 0 0 / .25);
  display: flex; flex-direction: column; font-size: 14px; animation: toast-in .25s ease-out; }
.toast b { font-size: 15px; }
.toast span { color: var(--muted); }
@keyframes toast-in { from { transform: translateY(-120%); opacity: 0; } }

/* How tall a squared-up pile is (cards.js Cards.depth) */
.card.deep { box-shadow: var(--edge) var(--edge) 0 0 #ece5d3, calc(var(--edge) + 1px) calc(var(--edge) + 1px) 0 0 rgb(0 0 0 / .35); }
.stack-count { position: absolute; top: -7px; right: -7px; z-index: 5; min-width: 18px; padding: 1px 4px; border-radius: 9px;
  font: 600 11px/14px system-ui, sans-serif; text-align: center; color: #fff; background: rgb(0 0 0 / .45); pointer-events: none; }

/* Admin page (admin.js) */
.ad-showall { display: block; margin: 10px 0; }
.ad-ticket { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; margin: 8px 0; padding: 8px 12px; }
.ad-ticket.closed { opacity: 0.7; }
.ad-ticket summary { cursor: pointer; display: flex; flex-wrap: wrap; gap: 2px 8px; align-items: baseline; }
.ad-cat { font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--accent); }
.ad-text { flex: 1; min-width: 50%; font-weight: 600; overflow-wrap: anywhere; }
.ad-meta { width: 100%; font-size: 13px; }
.ad-body { white-space: pre-wrap; overflow-wrap: anywhere; }
.ad-facts { font-size: 13px; overflow-wrap: anywhere; }
.ad-errors { font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--bad); }
.ad-pics { display: flex; flex-wrap: wrap; gap: 6px; }
.ad-pics img { max-width: 140px; max-height: 240px; border-radius: 6px; border: 1px solid var(--line); }
.ad-comment { border-left: 3px solid var(--line); padding-left: 8px; white-space: pre-wrap; overflow-wrap: anywhere; }
.ad-reply { width: 100%; box-sizing: border-box; font: inherit; padding: 0.5rem; border-radius: 8px; border: 1px solid var(--line); background: var(--bg); color: var(--fg); margin: 6px 0; }
.ad-people { list-style: none; padding: 0; }
.ad-people li { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 4px 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.ad-people li > :nth-child(3) { grid-column: 2; grid-row: 1 / span 2; }
.ad-people li.off input { text-decoration: line-through; opacity: 0.6; }
.ad-people input { min-width: 0; }
.ad-email { overflow-wrap: anywhere; font-size: 14px; padding-left: 2px; }
.ad-add { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.ad-add input { flex: 1 1 10em; min-width: 0; }
.ad-h { margin: 18px 0 6px; font-size: 16px; }
.ad-person { border-bottom: 1px solid var(--line); padding: 6px 0; }
.ad-person summary { cursor: pointer; }
.ad-scroll { overflow-x: auto; }
.ad-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.ad-table th { text-align: left; font-size: 12px; color: var(--muted); font-weight: 600; }
.ad-table th, .ad-table td { padding: 5px 6px 5px 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.ad-table .num { text-align: right; padding-right: 10px; font-variant-numeric: tabular-nums; }
.ad-table tr.playing .ad-playing { color: var(--accent); font-weight: 700; }
.ad-who { font-size: 13px; overflow-wrap: anywhere; }
.ad-tag { margin-left: 6px; font-size: 11px; padding: 0 5px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); }
.ad-recent { list-style: none; padding: 0; }
.ad-recent li { display: flex; flex-wrap: wrap; gap: 2px 8px; align-items: baseline; padding: 6px 0; border-bottom: 1px solid var(--line); }
.ad-status { font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--muted); }
.ad-status.playing { color: var(--accent); }
