/* Games inside a group (game.md Phase G3): the Chat · Games · Online tabs, the Select game and
   Settings sheets, the game screen and Tic-Tac-Toe. Laid out after the owner's Plato
   screenshots. Uses the classes of groups.css (.group-bar, .group-round, .group-card,
   .group-person…) and the theme variables (--p-*). Loaded after groups.css. */

/* ── Tabs under the header of an open group ───────────────────────────────────────── */
.group-tabs{display:none}
body.group-chat-open .chat-header{flex-wrap:wrap}
body.group-chat-open .group-tabs{display:flex;flex:0 0 100%;order:99;margin:10px -4px -6px;gap:0}
.group-tabs button{flex:1;padding:12px 4px 13px;border:0;border-bottom:3px solid transparent;background:none;color:var(--p-muted,var(--muted));font:inherit;font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;cursor:pointer}
.group-tabs button[aria-selected="true"]{color:var(--p-brand,var(--accent));border-bottom-color:var(--p-brand,var(--accent));font-weight:800}
.group-tabs button:focus-visible{outline:2px solid var(--p-brand,var(--accent));outline-offset:-2px}

.group-tab-panel{position:absolute;left:0;right:0;bottom:0;top:120px;z-index:6;display:flex;flex-direction:column;padding:6px 12px calc(16px + env(safe-area-inset-bottom));overflow-y:auto;background:var(--p-soft,var(--p-bg,var(--bg)));color:var(--p-text,var(--text))}
.group-tab-panel.hidden,body:not(.group-chat-open):not(.chat-games-open) .group-tab-panel{display:none}
.games-empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:24px;color:var(--p-muted,var(--muted))}
.games-empty svg{width:170px;height:auto;fill:none;stroke:currentColor;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;opacity:.55;margin-bottom:18px}
.games-empty h3{margin:0 0 8px;font-size:22px;font-weight:700;color:var(--p-muted,var(--muted))}
.games-empty p{margin:0;max-width:280px;font-size:16px;line-height:1.4}

.game-primary{width:100%;min-height:50px;border:0;border-radius:14px;background:var(--p-brand,var(--accent));color:var(--p-on-brand,#fff);font:inherit;font-size:15px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;cursor:pointer}
.game-primary:active{transform:scale(.985)}
.game-secondary{width:100%;min-height:46px;margin-top:10px;border:1px solid var(--p-hair-strong,var(--border));border-radius:14px;background:none;color:inherit;font:inherit;font-weight:600;cursor:pointer}

/* ── Bottom sheets (Select game, Settings) ────────────────────────────────────────── */
.game-sheet-wrap{position:fixed;inset:0;z-index:1250;display:flex;align-items:flex-end;justify-content:center;background:rgba(0,0,0,.55);animation:game-fade .16s ease-out}
.game-sheet{width:100%;max-width:560px;max-height:82vh;max-height:82dvh;display:flex;flex-direction:column;border-radius:22px 22px 0 0;background:var(--p-panel,var(--panel));color:var(--p-text,var(--text));font-family:var(--p-font,inherit);box-shadow:0 -18px 50px rgba(0,0,0,.4);animation:game-up .22s cubic-bezier(.2,.9,.3,1)}
.game-sheet>header{position:relative;display:flex;align-items:center;justify-content:center;min-height:56px;border-bottom:1px solid var(--p-hair,var(--border))}
.game-sheet>header h3{margin:0;font-size:15px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}
.game-sheet-close{position:absolute;left:8px;top:6px;width:44px;height:44px;border:0;background:none;color:inherit;display:grid;place-items:center;cursor:pointer}
.game-sheet-close .ico,.game-sheet-close .ico svg{width:22px;height:22px}
.game-sheet-body{overflow-y:auto;padding:14px 12px calc(16px + env(safe-area-inset-bottom))}
.game-sheet-note{margin:12px 6px 0;font-size:13px;color:var(--p-muted,var(--muted));text-align:center}
/* Select game: a grid, icon above the name, all games without scrolling (owner, 2026-10-04: 2 × 4 for
   eight; from nine games on, three to a row). */
.game-list{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:0;border:0;border-radius:0;background:none}
.game-row{width:100%;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:8px;padding:14px 8px;border:1px solid var(--p-hair,var(--border));border-radius:18px;background:var(--p-soft,rgba(127,127,127,.08));color:inherit;font:inherit;font-size:16px;line-height:1.2;text-align:center;cursor:pointer}
.game-row .game-icon{flex-basis:52px;width:52px;height:52px}
.game-row>span:last-child{min-height:2.4em}   /* names of one or two lines: the icons in a row stay level */
@media (hover:hover){.game-row:hover{background:var(--p-lift,rgba(127,127,127,.06))}}
.game-icon{flex:0 0 46px;width:46px;height:46px;border-radius:50%;overflow:hidden;display:block;box-shadow:0 3px 8px rgba(0,0,0,.3),inset 0 2px 3px rgba(255,255,255,.28)}
.game-icon svg{width:100%;height:100%;display:block}
.game-icon.small{flex-basis:34px;width:34px;height:34px}
.game-setting{padding:6px 10px 16px;border-bottom:1px solid var(--p-hair,var(--border));margin-bottom:12px}
.game-setting h4{margin:0 0 10px;font-size:18px;font-weight:500}
.game-options{display:flex;flex-wrap:wrap;gap:6px 22px}
.game-options button{padding:6px 2px;border:0;background:none;color:var(--p-muted,var(--muted));font:inherit;font-size:14px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;cursor:pointer}
.game-options button[aria-pressed="true"]{color:var(--p-brand,var(--accent));font-weight:800}
@keyframes game-fade{from{opacity:0}to{opacity:1}}
@keyframes game-up{from{transform:translateY(40px);opacity:.4}to{transform:none;opacity:1}}

/* ── The game screen ──────────────────────────────────────────────────────────────── */
.game-layer{position:fixed;inset:0;z-index:1220;display:flex;justify-content:center;background:radial-gradient(120% 80% at 50% 0%,color-mix(in srgb,var(--p-brand,#5b6cff) 22%,var(--p-bg,#0b0f1a)) 0%,var(--p-bg,#0b0f1a) 62%);color:var(--p-text,var(--text));font-family:var(--p-font,inherit);animation:game-fade .18s ease-out}
/* Jet Black / Matte Black (theme-init.js sets data-app-shade="black"): a plain black game screen, no coloured glow (owner, 2026-10-04). */
html[data-app-shade="black"] .game-layer{background:var(--p-bg,#000)}
.game-layer-inner{position:relative;width:100%;max-width:560px;display:flex;flex-direction:column;min-height:0;padding:env(safe-area-inset-top) 0 calc(16px + env(safe-area-inset-bottom))}
.game-sound svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.game-sound[aria-pressed="false"]{color:var(--p-muted,var(--muted))}

.game-players{display:flex;align-items:center;justify-content:center;gap:6px;padding:8px 12px 0}
.game-player{flex:1;min-width:0;display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:999px;border:2px solid transparent;background:var(--p-lift-strong,rgba(127,127,127,.12));transition:border-color .2s,box-shadow .2s,opacity .2s;opacity:.7}
.game-player[data-player="1"]{justify-content:flex-end}
.game-player.turn{opacity:1;border-color:var(--p-brand,var(--accent));box-shadow:0 0 0 4px color-mix(in srgb,var(--p-brand,var(--accent)) 22%,transparent)}
.game-player .avatar{flex:0 0 36px;width:36px;height:36px;font-size:12px;overflow:hidden}
.game-bot{display:grid;place-items:center;background:color-mix(in srgb,#f43f5e 22%,transparent)!important;color:#fb7185!important}
.game-bot svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.game-player-name{min-width:0;font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.game-player-mark{flex:0 0 18px;width:18px;height:18px}
.game-player-mark .ttt-mark{animation:none;stroke-dashoffset:0}
.game-vs{font-size:12px;font-weight:800;letter-spacing:.08em;color:var(--p-muted,var(--muted))}
.game-stage{flex:1;min-height:0;display:grid;place-items:center;padding:18px}
.game-board{width:min(100%,400px);width:min(100%,400px,62dvh)}
.game-status{min-height:24px;margin:0;text-align:center;font-size:16px;font-weight:600;color:var(--p-muted,var(--muted))}

/* Tic-Tac-Toe: raised glossy tiles, marks that draw themselves, a glowing winning line. */
.ttt-board{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;padding:12px;border-radius:28px;background:linear-gradient(160deg,color-mix(in srgb,var(--p-text,#fff) 10%,var(--p-panel,#141a2a)),var(--p-panel,#141a2a));box-shadow:0 22px 50px -18px rgba(0,0,0,.7),inset 0 1px 0 rgba(255,255,255,.12),0 0 0 1px var(--p-hair-strong,rgba(255,255,255,.14))}
.ttt-cell{aspect-ratio:1;padding:0;border:0;border-radius:18px;display:grid;place-items:center;background:linear-gradient(160deg,color-mix(in srgb,var(--p-text,#fff) 9%,var(--p-bg,#0b0f1a)),var(--p-bg,#0b0f1a));box-shadow:inset 0 2px 0 rgba(255,255,255,.07),inset 0 -6px 12px rgba(0,0,0,.35),0 2px 4px rgba(0,0,0,.35);cursor:pointer;transition:transform .12s,filter .2s,opacity .3s}
@media (hover:hover){.ttt-cell:not(:disabled):hover{filter:brightness(1.25)}}
.ttt-cell:not(:disabled):active{transform:scale(.95)}
.ttt-cell:disabled{cursor:default}
.ttt-mark{width:74%;height:74%;fill:none;stroke-width:13;stroke-linecap:round}
.ttt-x{stroke:#38bdf8;filter:drop-shadow(0 3px 0 #0369a1) drop-shadow(0 0 10px rgba(56,189,248,.45))}
.ttt-o{stroke:#fb7185;filter:drop-shadow(0 3px 0 #9f1239) drop-shadow(0 0 10px rgba(251,113,133,.45))}
.ttt-cell.fresh .ttt-mark{animation:ttt-pop .32s cubic-bezier(.3,1.6,.5,1)}
.ttt-cell.fresh .ttt-x path{stroke-dasharray:70;stroke-dashoffset:70;animation:ttt-draw .22s ease-out forwards}
.ttt-cell.fresh .ttt-x path+path{animation-delay:.14s}
.ttt-cell.fresh .ttt-o circle{stroke-dasharray:170;stroke-dashoffset:170;animation:ttt-draw .34s ease-out forwards}
.ttt-board.over .ttt-cell:not(.win){opacity:.38}
.ttt-cell.win{animation:ttt-win .9s ease-in-out infinite alternate;box-shadow:inset 0 2px 0 rgba(255,255,255,.18),0 0 0 2px #fbbf24,0 0 26px rgba(251,191,36,.55)}
@keyframes ttt-pop{from{transform:scale(.4)}to{transform:scale(1)}}
@keyframes ttt-draw{to{stroke-dashoffset:0}}
@keyframes ttt-win{from{transform:scale(1)}to{transform:scale(1.06)}}

/* Result card and confetti */
.game-result{position:absolute;inset:0;z-index:3;display:grid;place-items:end center;padding:20px 16px calc(20px + env(safe-area-inset-bottom));background:linear-gradient(transparent 45%,rgba(0,0,0,.72));animation:game-fade .2s ease-out;overflow:hidden}
.game-result-card{position:relative;width:100%;max-width:400px;padding:20px 18px 16px;border-radius:26px;text-align:center;background:var(--p-panel,var(--panel));box-shadow:0 30px 70px -20px rgba(0,0,0,.8),0 0 0 1px var(--p-hair-strong,rgba(255,255,255,.14));animation:ttt-pop .35s cubic-bezier(.3,1.5,.5,1)}
.game-result-card h3{margin:0 0 6px;font-size:28px;font-weight:800}
.game-result.won h3{color:#fbbf24}.game-result.lost h3{color:#fb7185}
.game-result-card p{margin:0 0 20px;color:var(--p-muted,var(--muted))}
.game-confetti{position:absolute;inset:0;pointer-events:none}
.game-confetti i{position:absolute;top:-16px;left:var(--x);width:9px;height:15px;border-radius:2px;background:hsl(var(--h) 90% 62%);animation:game-confetti 1.9s var(--d) cubic-bezier(.2,.6,.4,1) both}
@keyframes game-confetti{from{transform:translateY(0) rotate(0);opacity:1}to{transform:translateY(105vh) rotate(700deg);transform:translateY(105dvh) rotate(700deg);opacity:.9}}

@media (prefers-reduced-motion:reduce){
  .game-sheet-wrap,.game-sheet,.game-layer,.game-result,.game-result-card,.ttt-cell.fresh .ttt-mark,.ttt-cell.win{animation:none}
  .ttt-cell.fresh .ttt-x path,.ttt-cell.fresh .ttt-o circle{animation:none;stroke-dashoffset:0}
  .game-confetti{display:none}
}

/* ── Live play (Phase G4) ─────────────────────────────────────────────────────────── */
/* The "started · Tap to play · Table n" card in the chat */
.game-card{display:flex;align-items:center;gap:14px;width:100%;min-width:220px;padding:6px 8px 6px 2px;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}
.game-card .game-icon{flex-basis:54px;width:54px;height:54px;display:grid;place-items:center;font-size:30px}
.game-card-copy{display:flex;flex-direction:column;line-height:1.25}
.game-card-copy strong{font-size:17px;font-weight:600}
.game-card-copy span{font-size:15px;opacity:.92}
.game-card-copy small{font-size:12px;opacity:.75;margin-top:2px}
.game-card:focus-visible{outline:2px solid currentColor;outline-offset:3px;border-radius:12px}

/* My games / Other tables in the Games tab */
.games-list{flex:1}
.game-table{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;gap:4px 14px;align-items:center;padding:16px 16px 14px;margin-bottom:10px}
.game-table>.game-icon{grid-row:1/3;align-self:start;flex-basis:56px;width:56px;height:56px}
.game-table-copy{min-width:0;display:flex;flex-direction:column;gap:2px}
.game-table-copy strong{font-size:17px;font-weight:600}
.game-table-copy small{font-size:14px;color:var(--p-muted,var(--muted))}
.game-table-no{align-self:start;font-size:14px;color:var(--p-muted,var(--muted));white-space:nowrap}
.game-seats{display:flex;gap:6px;margin-top:10px}
.game-seat{position:relative;display:block}
.game-seat .avatar{width:30px;height:30px;flex:none;font-size:10px;overflow:hidden}
.game-seat>svg{position:absolute;left:50%;top:-11px;width:16px;height:16px;transform:translateX(-50%)}
.game-seat-empty{display:grid!important;place-items:center;background:color-mix(in srgb,var(--p-text,#fff) 22%,transparent)!important;color:var(--p-panel,#111)!important}
.game-seat-empty svg{width:62%;height:62%;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.game-go{grid-column:2/4;justify-self:end;margin-top:-34px;min-height:36px;padding:0 18px;border:0;border-radius:999px;background:color-mix(in srgb,var(--p-text,#fff) 26%,transparent);color:var(--p-text,#fff);font:inherit;font-size:14px;font-weight:600;cursor:pointer}
@media (hover:hover){.game-go:hover{background:var(--p-brand,var(--accent));color:var(--p-on-brand,#fff)}}
/* Close table / Give up, under Go to game, on my own tables (owner, 2026-10-03) */
.game-end{grid-column:2/4;justify-self:end;margin-top:8px;min-height:32px;padding:0 14px;border:1px solid color-mix(in srgb,#f87171 55%,transparent);border-radius:999px;background:none;color:#f87171;font:inherit;font-size:13px;font-weight:600;cursor:pointer}
@media (hover:hover){.game-end:hover{background:color-mix(in srgb,#f87171 16%,transparent)}}
@media (pointer:coarse){.game-end{min-height:44px}}
.game-setting.hidden{display:none}
.game-leave{align-self:center;margin-top:10px;padding:8px 16px;border:0;background:none;color:var(--danger,#f87171);font:inherit;font-size:14px;font-weight:600;cursor:pointer}
.game-leave.hidden{display:none}

/* ── Phase G5: Connect Four and Ludo ──────────────────────────────────────────────── */
.game-player-mark svg{width:100%;height:100%;display:block}

/* Connect Four: a glossy blue rack with round holes; discs fall in from the top. */
.c4-board{display:grid;grid-template-columns:repeat(7,1fr);gap:0;padding:10px;border-radius:26px;background:linear-gradient(165deg,#3b82f6,#1e3a8a);box-shadow:0 22px 50px -18px rgba(0,0,0,.75),inset 0 2px 0 rgba(255,255,255,.35),inset 0 -8px 14px rgba(0,0,0,.3);overflow:hidden}
.c4-col{display:grid;grid-template-rows:repeat(6,1fr);gap:0;padding:0;border:0;border-radius:999px;background:none;cursor:pointer}
.c4-col:disabled{cursor:default}
@media (hover:hover){.c4-col:not(:disabled):hover{background:rgba(255,255,255,.14)}}
.c4-hole{position:relative;aspect-ratio:1;margin:8%;border-radius:50%;background:#0b1533;box-shadow:inset 0 4px 7px rgba(0,0,0,.65),0 1px 0 rgba(255,255,255,.25)}
.c4-hole .c4-mark{position:absolute;inset:0;width:100%;height:100%}
.c4-mark circle{stroke:none}
.c4-p0>circle:first-child{fill:#38bdf8}.c4-p1>circle:first-child{fill:#fb7185}
.c4-p0 .c4-ring{fill:#0ea5e9}.c4-p1 .c4-ring{fill:#f43f5e}
.c4-shine{fill:#fff;opacity:.38}
.c4-hole.fresh .c4-mark{animation:c4-drop calc(.16s + var(--row) * .07s) cubic-bezier(.45,0,.9,.55),c4-bounce .22s calc(.16s + var(--row) * .07s) ease-out}
.c4-board.over .c4-hole:not(.win) .c4-mark{opacity:.4}
.c4-hole.win{box-shadow:0 0 0 3px #fbbf24,0 0 22px rgba(251,191,36,.7)}
.c4-hole.win .c4-mark{animation:ttt-win .8s ease-in-out infinite alternate}
@keyframes c4-drop{from{transform:translateY(calc((var(--row) + 1.2) * -125%))}to{transform:none}}
/* How to play: the ? in the game screen's header opens a card of simple numbered rules (with a picture for
   some games); it also opens by itself the first time a game is played on this device. */
.game-qmark{position:relative;flex:0 0 24px;width:24px;height:24px;margin:0 -6px 0 auto;padding:0;border-radius:50%;border:1px solid var(--p-hair-strong,var(--border));background:rgba(255,255,255,.06);color:var(--p-muted,var(--muted));display:grid;place-items:center;font:inherit;font-size:13px;font-weight:800;line-height:1;cursor:pointer}
.game-qmark::after{content:"";position:absolute;inset:-10px}   /* a thumb-sized tap area around the small ? */
/* Voice chat from the game: the chat header's button (voice.css .voice-chat-btn: green icon when people are in
   it, green tint when I am, the count badge); here it can also mute, shown red with a slash. */
.game-voice{position:relative}
.game-voice svg{width:22px;height:22px}
.game-voice.voice-chat-btn.muted{background:rgba(239,68,68,.16)!important;border-color:rgba(239,68,68,.55);color:#fca5a5}
/* Phones (owner, 2026-10-04: "optimise for mobile"): four things in the game screen's top bar, so on a narrow
   screen the round buttons are a little smaller and closer, and the title keeps more room. Still 42 px to tap. */
@media (max-width:400px){
  .game-layer .group-bar{gap:8px;padding:10px 10px}
  .game-layer .group-round{flex-basis:42px;width:42px;height:42px}
  .game-layer .group-title-pill{padding-right:12px;gap:8px}
}
.game-layer .group-title-copy{min-width:0}
.game-layer .group-title-copy strong,.game-layer .group-title-copy small{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}   /* one line each, beside the ? and sound buttons */
.game-help{position:fixed;inset:0;z-index:1240;display:grid;place-items:center;padding:18px;background:rgba(0,0,0,.66);animation:game-fade .16s ease-out}
.game-help-card{width:min(100%,400px);max-height:88vh;max-height:88dvh;overflow-y:auto;padding:20px 20px 16px;border-radius:24px;border:1px solid var(--p-hair,var(--border));background:var(--p-panel,var(--panel));color:var(--p-text,var(--text));box-shadow:0 30px 70px rgba(0,0,0,.6);text-align:center}
.game-help-card>.game-icon{width:52px;height:52px;margin:0 auto 10px}
.game-help-card h3{margin:0 0 14px;font-size:19px;font-weight:800}
.game-help-card ol{margin:0 0 14px;padding:0;list-style:none;counter-reset:rule;display:grid;gap:11px;text-align:left}
.game-help-card li{counter-increment:rule;position:relative;padding-left:36px;font-size:15px;line-height:1.45}
.game-help-card li::before{content:counter(rule);position:absolute;left:0;top:0;width:25px;height:25px;border-radius:50%;display:grid;place-items:center;font-size:13px;font-weight:800;background:var(--p-brand,var(--accent));color:var(--p-on-brand,#fff)}
.game-help-card li b{font-weight:800;color:var(--p-text,var(--text))}
.game-help-fig{margin:2px 0 16px;padding:12px 10px 10px;border-radius:16px;background:rgba(255,255,255,.04);border:1px solid var(--p-hair,var(--border))}
.game-help-fig svg{display:block;width:100%;max-width:300px;height:auto;margin:0 auto}
.game-help-fig figcaption{margin-top:8px;font-size:13px;line-height:1.4;color:var(--p-muted,var(--muted))}
@media (prefers-reduced-motion:reduce){.game-help{animation:none}}
/* ── Dots and Boxes ── glowing dots on a jet-black card (owner, 2026-10-04); a line draws itself in, a box pops in with
   its owner's colour (blue / rose, as in Connect Four). Every line has a diamond-shaped tap area
   that reaches the middle of the boxes beside it, so a thumb cannot miss. */
.db{width:100%;max-width:min(100%,60dvh);margin-inline:auto;display:flex;flex-direction:column;gap:12px}
.db-score{display:flex;align-items:center;justify-content:space-between;gap:10px}
.db-num{display:inline-flex;align-items:center;gap:9px;min-width:70px;padding:7px 14px;border-radius:999px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);font-size:22px;font-weight:800;font-variant-numeric:tabular-nums;transition:box-shadow .25s,border-color .25s,background .25s}
.db-num.p1{flex-direction:row-reverse}
.db-num i{width:13px;height:13px;border-radius:4px}
.db-num.p0 i{background:#38bdf8;box-shadow:0 0 10px rgba(56,189,248,.8)}
.db-num.p1 i{background:#fb7185;box-shadow:0 0 10px rgba(251,113,133,.8)}
.db-num.turn.p0{border-color:#38bdf8;background:rgba(56,189,248,.14);box-shadow:0 0 18px rgba(56,189,248,.35)}
.db-num.turn.p1{border-color:#fb7185;background:rgba(251,113,133,.14);box-shadow:0 0 18px rgba(251,113,133,.35)}
.db-mid{flex:1;min-width:0;font-size:13px;font-weight:600;text-align:center;opacity:.7;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.db-mid.go{opacity:1;color:#fbbf24;font-weight:800;animation:db-pop .4s cubic-bezier(.3,1.6,.5,1)}
.db-board{display:block;width:100%;height:auto;border-radius:26px;background:radial-gradient(120% 90% at 25% 0%,#161616 0%,#070707 55%,#000 100%);border:1px solid #1c1c1c;box-shadow:0 22px 50px -18px rgba(0,0,0,.9),inset 0 1px 0 rgba(255,255,255,.06);touch-action:manipulation;-webkit-user-select:none;user-select:none}
.db-line{stroke:rgba(203,213,225,.13);stroke-width:4;stroke-linecap:round;stroke-dasharray:.06 .07;transition:stroke .15s,stroke-width .15s}
.db-edge.on .db-line{stroke-width:11;stroke-dasharray:none}
.db-edge.on.p0 .db-line{stroke:#38bdf8;filter:drop-shadow(0 0 5px rgba(56,189,248,.6))}
.db-edge.on.p1 .db-line{stroke:#fb7185;filter:drop-shadow(0 0 5px rgba(251,113,133,.6))}
.db-edge.fresh .db-line{stroke-dasharray:1;stroke-dashoffset:1;animation:db-draw .3s cubic-bezier(.3,.7,.4,1) forwards}
.db-hit{fill:transparent;cursor:pointer;-webkit-tap-highlight-color:transparent}
.db-edge.can:active .db-line{stroke-width:9;stroke-dasharray:none}
.db.me-p0 .db-edge.can:active .db-line{stroke:rgba(56,189,248,.75)}
.db.me-p1 .db-edge.can:active .db-line{stroke:rgba(251,113,133,.75)}
@media (hover:hover){
  .db-edge.can:hover .db-line{stroke-width:9;stroke-dasharray:none}
  .db.me-p0 .db-edge.can:hover .db-line{stroke:rgba(56,189,248,.55)}
  .db.me-p1 .db-edge.can:hover .db-line{stroke:rgba(251,113,133,.55)}
}
.db-box rect{stroke-width:2}
.db-box.p0 rect{fill:rgba(56,189,248,.36);stroke:rgba(56,189,248,.6)}
.db-box.p1 rect{fill:rgba(251,113,133,.36);stroke:rgba(251,113,133,.6)}
.db-star{fill:#fff;opacity:.9}
.db-box.p0 .db-star{fill:#e0f2fe}.db-box.p1 .db-star{fill:#ffe4e6}
.db-box.fresh{transform-box:fill-box;transform-origin:center;animation:db-box .45s .12s cubic-bezier(.2,1.5,.4,1) backwards}
.db-dot{fill:#f1f5f9;filter:drop-shadow(0 0 4px rgba(226,232,240,.55))}
.db.over .db-box:not(.fresh){opacity:.85}
.db-mark rect{stroke-width:0}.db-mark circle{fill:#fff;opacity:.85}
.db-mark.p0 rect{fill:#38bdf8}.db-mark.p1 rect{fill:#fb7185}
@keyframes db-draw{to{stroke-dashoffset:0}}
@keyframes db-box{from{transform:scale(.25);opacity:0}to{transform:none;opacity:1}}
@keyframes db-pop{from{transform:scale(.8)}to{transform:none}}
@media (prefers-reduced-motion:reduce){.db-edge.fresh .db-line{animation:none;stroke-dashoffset:0}.db-box.fresh,.db-mid.go{animation:none}}
/* ── Reversi ── a green felt board on the black screen, glossy black and white discs. A captured disc
   flips in 3D (two faces, back-face hidden), the flips ripple out from the new disc (--d), the new disc
   drops in, the last move has a gold dot, and my legal squares glow softly. */
.rv{width:100%;max-width:min(100%,58dvh);margin-inline:auto;display:flex;flex-direction:column;gap:12px}
.rv-score{display:flex;align-items:center;justify-content:space-between;gap:10px}
.rv-num{display:inline-flex;align-items:center;gap:9px;min-width:74px;padding:7px 14px;border-radius:999px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);font-size:22px;font-weight:800;font-variant-numeric:tabular-nums;transition:box-shadow .25s,border-color .25s,background .25s}
.rv-num.p1{flex-direction:row-reverse}
.rv-num.turn{border-color:#fbbf24;background:rgba(251,191,36,.12);box-shadow:0 0 18px rgba(251,191,36,.3)}
.rv-chip{width:16px;height:16px;border-radius:50%}
.rv-chip.b{background:radial-gradient(circle at 35% 30%,#6b6b6b,#0a0a0a 70%);box-shadow:0 0 0 1px #4a4a4a}
.rv-chip.w{background:radial-gradient(circle at 35% 30%,#fff,#c4c4c4 85%)}
.rv-mid{flex:1;min-width:0;font-size:13px;font-weight:600;text-align:center;opacity:.7;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rv-mid.go{opacity:1;color:#fbbf24;font-weight:800;animation:db-pop .4s cubic-bezier(.3,1.6,.5,1)}
.rv-mid.pass{opacity:1;color:#fda4af;font-weight:700}
.rv-board{display:grid;grid-template-columns:repeat(8,1fr);gap:3px;padding:9px;border-radius:20px;background:linear-gradient(160deg,#0c5434,#052a19);box-shadow:0 22px 50px -18px rgba(0,0,0,.9),inset 0 1px 0 rgba(255,255,255,.12),0 0 0 1px #0a3a24;touch-action:manipulation;-webkit-user-select:none;user-select:none}
.rv-cell{position:relative;aspect-ratio:1;display:grid;place-items:center;padding:0;border:0;border-radius:5px;background:radial-gradient(circle at 50% 38%,#178a54,#0e6b40 75%);box-shadow:inset 0 1px 0 rgba(255,255,255,.07),inset 0 -2px 4px rgba(0,0,0,.25);perspective:420px;cursor:default;-webkit-tap-highlight-color:transparent}
.rv-cell:disabled{opacity:1}
.rv-cell.can{cursor:pointer}
.rv-cell.can:active{background:radial-gradient(circle at 50% 38%,#1fa566,#13804d 75%)}
@media (hover:hover){.rv-cell.can:hover{background:radial-gradient(circle at 50% 38%,#1fa566,#13804d 75%)}}
.rv-hint{width:30%;height:30%;border-radius:50%;animation:rv-hint 1.4s ease-in-out infinite alternate}
.rv.me-b .rv-hint{background:rgba(0,0,0,.45);box-shadow:0 0 0 2px rgba(255,255,255,.16)}
.rv.me-w .rv-hint{background:rgba(255,255,255,.5);box-shadow:0 0 10px rgba(255,255,255,.45)}
.rv-disc{position:relative;width:84%;height:84%;transform-style:preserve-3d;transition:transform .4s}
.rv-disc.w{transform:rotateY(180deg)}
.rv-face{position:absolute;inset:0;border-radius:50%;-webkit-backface-visibility:hidden;backface-visibility:hidden}
.rv-b{background:radial-gradient(circle at 34% 28%,#707070 0%,#262626 34%,#060606 72%);box-shadow:0 3px 5px rgba(0,0,0,.55),inset 0 -3px 5px rgba(0,0,0,.6),inset 0 2px 2px rgba(255,255,255,.16)}
.rv-w{transform:rotateY(180deg);background:radial-gradient(circle at 34% 28%,#fff 0%,#f2f2f2 38%,#c8c8c8 88%);box-shadow:0 3px 5px rgba(0,0,0,.45),inset 0 -3px 5px rgba(0,0,0,.16)}
.rv-disc.flip.w{animation:rv-to-w .55s var(--d,0ms) cubic-bezier(.45,.05,.3,1) backwards}
.rv-disc.flip.b{animation:rv-to-b .55s var(--d,0ms) cubic-bezier(.45,.05,.3,1) backwards}
.rv-disc.new{animation:rv-drop .34s cubic-bezier(.3,1.5,.5,1)}
.rv-cell.last::after{content:"";position:absolute;width:13%;height:13%;border-radius:50%;background:#fbbf24;box-shadow:0 0 6px #fbbf24;pointer-events:none}
.rv.over .rv-cell.last::after{display:none}
.rv-mark{display:block}
@keyframes rv-to-w{0%{transform:rotateY(0)}50%{transform:rotateY(90deg) scale(1.14)}100%{transform:rotateY(180deg)}}
@keyframes rv-to-b{0%{transform:rotateY(180deg)}50%{transform:rotateY(270deg) scale(1.14)}100%{transform:rotateY(360deg)}}
@keyframes rv-drop{from{scale:1.7;opacity:0}to{scale:1;opacity:1}}
@keyframes rv-hint{from{opacity:.55;scale:.85}to{opacity:1;scale:1}}
@media (prefers-reduced-motion:reduce){.rv-disc.flip.w,.rv-disc.flip.b,.rv-disc.new,.rv-hint,.rv-mid.go{animation:none}.rv-disc{transition:none}}
@keyframes c4-bounce{0%{transform:none}45%{transform:translateY(-14%)}100%{transform:none}}

/* Ludo: the classic board, drawn in SVG. Player 0 is blue (top left), player 1 rose (bottom right). */
.ludo{display:flex;flex-direction:column;gap:14px}
.ludo-board{width:100%;height:auto;display:block;border-radius:22px;box-shadow:0 22px 50px -18px rgba(0,0,0,.75),0 0 0 1px rgba(255,255,255,.14);overflow:visible}
.ludo-base{fill:#f8fafc}
.ludo-cell{fill:#fff;stroke:#cbd5e1;stroke-width:.5}
.ludo-cell.p0{fill:#38bdf8}.ludo-cell.p1{fill:#fb7185}.ludo-cell.off{fill:#e2e8f0}
.ludo-yard.p0{fill:#0ea5e9}.ludo-yard.p1{fill:#f43f5e}.ludo-yard.off{fill:#94a3b8}
.ludo-yard-in{fill:#fff}
.ludo-nest{fill:#e2e8f0}.ludo-nest.p0{fill:#bae6fd}.ludo-nest.p1{fill:#fecdd3}
.ludo-star{fill:#94a3b8}
.ludo-goal.p0{fill:#0ea5e9}.ludo-goal.p1{fill:#f43f5e}.ludo-goal.off{fill:#cbd5e1}
.ludo-token{transition:transform .38s cubic-bezier(.3,1.3,.5,1)}
.ludo-hit{fill:transparent}
.ludo-shadow{fill:rgba(15,23,42,.35)}
.ludo-body{stroke:#fff;stroke-width:1.1}
.ludo-p0 .ludo-body{fill:#0284c7}.ludo-p1 .ludo-body{fill:#e11d48}
.ludo-token .ludo-dot{fill:#fff;opacity:.9}
.ludo-ring{fill:none;stroke:#fbbf24;stroke-width:1.2;opacity:0;transform-box:fill-box;transform-origin:center}
.ludo-token.can{cursor:pointer}
.ludo-token.can .ludo-ring{opacity:1;animation:ludo-pulse .8s ease-in-out infinite alternate}
.ludo-token.moved .ludo-body{stroke:#fbbf24}
@keyframes ludo-pulse{from{transform:scale(.86);opacity:.55}to{transform:scale(1.12);opacity:1}}
.ludo-mark circle:first-child{stroke:#fff;stroke-width:9}
.ludo-mark.ludo-p0 circle:first-child{fill:#0284c7}.ludo-mark.ludo-p1 circle:first-child{fill:#e11d48}
.ludo-mark .ludo-dot{fill:#fff}
.ludo-tray{display:flex;align-items:center;justify-content:center;gap:14px;min-height:60px}
.ludo-dice{width:58px;height:58px;padding:9px;border:0;border-radius:15px;display:grid;grid-template-columns:repeat(3,1fr);gap:3px;background:linear-gradient(160deg,#fff,#dbe4f0);box-shadow:0 6px 0 #94a3b8,0 12px 20px -8px rgba(0,0,0,.6);cursor:pointer;transition:transform .12s,box-shadow .12s}
.ludo-dice i{border-radius:50%;align-self:center;justify-self:center;width:78%;aspect-ratio:1}
.ludo-dice i.on{background:#0f172a}
.ludo-dice.ludo-p0 i.on{background:#0284c7}.ludo-dice.ludo-p1 i.on{background:#e11d48}
.ludo-dice:disabled{cursor:default;opacity:.85}
.ludo-dice.ready{animation:ludo-ready 1s ease-in-out infinite alternate;box-shadow:0 6px 0 #94a3b8,0 0 0 5px rgba(251,191,36,.45)}
.ludo-dice.ready:active{transform:translateY(4px);box-shadow:0 2px 0 #94a3b8}
.ludo-dice.rolling{animation:ludo-roll .45s ease-out}
.ludo-tray-note{font-size:14px;font-weight:600;color:var(--p-muted,var(--muted));min-width:140px}
@keyframes ludo-ready{from{transform:scale(1)}to{transform:scale(1.07)}}
@keyframes ludo-roll{0%{transform:rotate(-200deg) scale(.6)}60%{transform:rotate(20deg) scale(1.12)}100%{transform:none}}
@media (prefers-reduced-motion:reduce){
  .c4-hole.fresh .c4-mark,.c4-hole.win .c4-mark,.ludo-dice.ready,.ludo-dice.rolling,.ludo-token.can .ludo-ring{animation:none}
  .ludo-token{transition:none}
}

/* ── Phones: iPhone Safari and Chrome on Android/iPhone ────────────────────────────── */
/* A second tap on a board must be a move, not a double-tap zoom; a long press must not raise
   the copy/look-up bubble; a drag inside a sheet or a game must not scroll or refresh the
   page behind it. */
.game-layer,.game-sheet-wrap,.group-tab-panel{touch-action:manipulation;overscroll-behavior:contain}
.game-layer{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.game-layer button,.game-sheet button,.group-tabs button,.game-card{-webkit-tap-highlight-color:transparent}
.game-sheet-body{overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
/* On a short screen (iPhone SE, or a phone held sideways) the game scrolls instead of being cut off. */
.game-layer-inner{overflow-y:auto;-webkit-overflow-scrolling:touch}
.ludo{width:100%;width:min(100%,56dvh);margin-inline:auto}
@media (pointer:coarse){
  /* Thumb-sized targets (Apple 44pt, Android 48dp) for the things a thumb goes for. */
  .game-options button{min-height:44px;padding:10px 6px}
  .game-go,.game-leave{min-height:44px}
  .game-row{min-height:60px}
}
@media (max-height:640px){
  .game-stage{padding:8px 14px}
  .game-players{padding-top:2px}
  .ludo{gap:8px}.ludo-tray{min-height:52px}
  .game-status{font-size:14px}
}

/* A game that fills the screen and draws its own players and status (Bowling). */
.game-full .game-players,.game-full .game-status{display:none}
.game-full .game-layer-inner{padding-bottom:0;overflow:hidden}
.game-full .game-stage{display:block;padding:0}
.game-full .game-board{width:100%;height:100%}
.game-loading{margin:0;height:100%;display:grid;place-items:center;padding:24px;text-align:center;color:var(--p-muted,var(--muted))}
.game-full .game-leave{display:none}   /* its place is the game's own menu */
.game-tally{margin:-4px 0 14px;font-size:14px;font-weight:600;color:var(--p-muted,var(--muted))}

/* ── Snakes & Ladders ──────────────────────────────────────────────────────────────── */
/* The board is one SVG drawn once; the pawns are a second SVG on top that only moves by
   transform, so a move never repaints the board. Gradients are inside the SVG (fill="url(#…)"
   in a stylesheet resolves against the CSS file in Firefox). */
.snl-stage{position:relative;width:100%;aspect-ratio:1;contain:layout paint}
.snl-board,.snl-pieces{position:absolute;inset:0;width:100%;height:100%;display:block}
.snl-board{border-radius:20px;box-shadow:0 22px 50px -18px rgba(0,0,0,.75),0 0 0 1px rgba(255,255,255,.14)}
.snl-pieces{pointer-events:none;overflow:visible}
.snl-tl{fill:#fffaf0}
.snl-t0{fill:#ffe08a}.snl-t1{fill:#ffc2cf}.snl-t2{fill:#b9f3d6}.snl-t3{fill:#bfe0ff}.snl-t4{fill:#e2ccff}
.snl-num{font:700 2.5px/1 ui-sans-serif,system-ui,-apple-system,sans-serif;fill:rgba(30,27,75,.55)}
.snl-start{font:800 1.7px/1 ui-sans-serif,system-ui,-apple-system,sans-serif;letter-spacing:.08px;fill:#4338ca}
.snl-crown{fill:#b45309;opacity:.9}
.snl-shade{fill:rgba(15,23,42,.28)}
.snl-scales{fill:none;stroke:rgba(0,0,0,.26);stroke-width:1.15;stroke-dasharray:.7 1.25;stroke-linecap:round}
.snl-sheen{fill:none;stroke:rgba(255,255,255,.45);stroke-width:.45;stroke-linecap:round}
.snl-eye{fill:#fff}.snl-pupil{fill:#0f172a}
.snl-tongue{fill:none;stroke:#e11d48;stroke-width:.35;stroke-linecap:round}
.snl-route{fill:none;stroke:none}
.snl-rail{fill:none;stroke:#92400e;stroke-width:1.3;stroke-linecap:round}
.snl-rail-hi{fill:none;stroke:#fcd34d;stroke-width:.4;stroke-linecap:round;opacity:.8}
.snl-rung{fill:none;stroke:#d97706;stroke-width:.9;stroke-linecap:round}
.snl-ladder-shade{fill:none;stroke:rgba(15,23,42,.3);stroke-width:1.5;stroke-linecap:round}
.snl-pawn{transition:transform .16s ease-out;will-change:transform}
.snl-pawn.sliding{transition:none}
.snl-pawn.waiting .snl-hop{transform:scale(.82)}
.snl-pawn-shadow{fill:rgba(15,23,42,.35)}
.snl-pawn-rim{fill:none;stroke:rgba(255,255,255,.75);stroke-width:.45}
.snl-pawn-shine{fill:rgba(255,255,255,.75)}
.snl-hop.hop{animation:snl-hop .17s ease-out}
@keyframes snl-hop{50%{transform:translateY(-2.4px) scale(1.08)}}
@media (prefers-reduced-motion:reduce){.snl-pawn{transition:none}.snl-hop.hop{animation:none}}

/* ── Chat at the bottom of a live game: a short window, the last 10 lines ─────────────── */
.game-chat{position:absolute;z-index:6;top:calc(env(safe-area-inset-top) + 74px);left:10px;right:10px;max-width:520px;margin:0 auto;display:flex;flex-direction:column;gap:6px;padding:8px;border-radius:18px;background:var(--p-panel,#141a2a);border:1px solid var(--p-hair,rgba(255,255,255,.1));box-shadow:0 -10px 30px -16px rgba(0,0,0,.6)}
.game-chat-log{max-height:78px;overflow-y:auto;display:flex;flex-direction:column;gap:3px;font-size:14px;overscroll-behavior:contain}
.game-chat-log:empty{display:none}
.game-chat-line{display:flex;align-items:center;gap:6px;min-width:0;animation:game-chat-in .18s ease-out}
.game-chat-line b{flex:none;font-size:12px;font-weight:800;color:var(--p-brand,var(--accent))}
.game-chat-line.mine b{color:var(--p-muted,var(--muted))}
.game-chat-line .t{min-width:0;overflow-wrap:anywhere}
.game-chat-line .e{font-size:22px;line-height:1}
.game-chat-line .s{width:36px;height:36px;object-fit:contain}
.game-chat-bar{display:flex;align-items:center;gap:6px;margin:0}
.game-chat-bar input{flex:1;min-width:0;height:38px;padding:0 12px;border-radius:999px;border:1px solid var(--p-hair-strong,var(--border));background:var(--p-bg,#0b0f1a);color:inherit;font:inherit;font-size:16px}
.game-chat-btn{flex:none;width:38px;height:38px;padding:0;border:0;border-radius:50%;background:var(--p-lift-strong,rgba(127,127,127,.15));color:inherit;font-size:17px;cursor:pointer}
.game-chat-btn.send{background:var(--p-brand,var(--accent));color:var(--p-on-brand,#fff)}
.game-chat-tray{display:flex;flex-direction:column;gap:6px}
.game-chat-tray.hidden{display:none}
.game-chat-emotes{display:flex;gap:4px;overflow-x:auto;overscroll-behavior:contain}
.game-chat-emotes button{flex:none;min-width:40px;height:36px;border:0;border-radius:10px;background:var(--p-lift,rgba(127,127,127,.1));color:inherit;font-size:20px;font-weight:800;cursor:pointer}
.game-chat-stickers{display:flex;gap:4px;overflow-x:auto;overscroll-behavior:contain}
.game-chat-stickers button{flex:none;width:44px;height:44px;padding:2px;border:0;border-radius:10px;background:none;cursor:pointer}
.game-chat-stickers img{width:100%;height:100%;object-fit:contain}
.game-chat-none{grid-column:1/-1;margin:4px;font-size:13px;color:var(--p-muted,var(--muted))}
.game-chat-open{position:relative;padding:0;font-size:20px;line-height:1}
.game-chat-open[aria-expanded="true"]{border-color:var(--p-brand,var(--accent));background:color-mix(in srgb,var(--p-brand,var(--accent)) 22%,transparent)}
.game-chat-open i{position:absolute;top:6px;right:6px;width:9px;height:9px;border-radius:50%;background:#ef4444}
.game-chat.min{background:none;border-color:transparent;box-shadow:none;padding:0}
.game-chat.min>*{display:none}
@keyframes game-chat-in{from{opacity:0;transform:translateY(6px)}}
@media (prefers-reduced-motion:reduce){.game-chat-line{animation:none}}

/* Two-person chats: the Games button in the header, beside the voice chat button. display is
   set here because premium.css styles header buttons with a rule that out-ranks [hidden]. */
#chatGamesBtn{position:relative;display:inline-grid;place-items:center}
#chatGamesBtn[hidden]{display:none!important}
.chat-games-btn svg{fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.chat-games-btn[aria-pressed="true"]{color:var(--p-brand,var(--accent));background:color-mix(in srgb,var(--p-brand,var(--accent)) 20%,transparent)!important}
.chat-games-count{position:absolute;top:-4px;right:-4px;min-width:18px;height:18px;padding:0 4px;border-radius:999px;background:var(--p-brand,var(--accent));color:#fff;font-size:11px;font-weight:800;line-height:18px;text-align:center}
.chat-games-count.hidden{display:none}
/* …and the Games list as a popup under it, the size and look of the sticker window, with
   the chat still visible behind. Select game and Settings open inside the popup. */
.group-tab-panel.pop{left:auto;right:10px;bottom:auto;margin-top:8px;width:min(360px,calc(100% - 20px));max-height:min(440px,calc(100% - 90px));padding:0 12px 12px;border:1px solid var(--p-hair,var(--border));border-radius:22px;background:var(--p-panel,var(--panel));box-shadow:0 18px 50px rgba(0,0,0,.45);animation:game-fade .14s ease-out}
.games-pop-head{position:sticky;top:0;z-index:1;display:flex;align-items:center;justify-content:space-between;min-height:46px;margin:0 -12px 8px;padding:0 6px 0 16px;border-bottom:1px solid var(--p-hair,var(--border));background:inherit;border-radius:22px 22px 0 0}
.games-pop-head strong{font-size:15px;font-weight:700}
.games-pop-head button{width:40px;height:40px;border:0;background:none;color:inherit;display:grid;place-items:center;cursor:pointer}
.games-pop-head .ico,.games-pop-head .ico svg{width:20px;height:20px}
.group-tab-panel.pop .games-empty{flex:none;padding:14px 12px 18px}
.group-tab-panel.pop .games-empty svg{width:96px;margin-bottom:8px}
.group-tab-panel.pop .games-empty h3{font-size:17px}
.group-tab-panel.pop .games-empty p{font-size:14px}
.group-tab-panel.pop .games-list{flex:none}
.group-tab-panel.pop .group-label{margin:6px 6px 8px}
.group-tab-panel.pop .game-table{padding:12px;border-radius:18px;gap:4px 10px}
.group-tab-panel.pop .game-table>.game-icon{flex-basis:44px;width:44px;height:44px}
.group-tab-panel.pop .game-primary{min-height:46px;flex:none}
.group-tab-panel.pop .game-sheet-wrap{position:absolute;inset:0;z-index:2;align-items:stretch;background:var(--p-panel,var(--panel));border-radius:22px;animation:none}
.group-tab-panel.pop .game-sheet{max-width:none;max-height:none;height:100%;border-radius:22px;box-shadow:none;animation:none}
.group-tab-panel.pop .game-sheet>header{min-height:46px}
.group-tab-panel.pop .game-sheet-close{top:1px}
.group-tab-panel.pop .game-sheet-body{padding:10px 10px 12px}
.group-tab-panel.pop .game-row{padding:10px 4px;font-size:13px;gap:6px}
.group-tab-panel.pop .game-row .game-icon{flex-basis:46px;width:46px;height:46px}
.group-tab-panel.pop .game-setting{padding:2px 8px 10px;margin-bottom:8px}
.group-tab-panel.pop .game-setting h4{margin-bottom:6px;font-size:15px}
.group-tab-panel.pop:has(.game-sheet-wrap){min-height:min(440px,calc(100% - 90px));overflow:hidden}
/* Taller while choosing a game, so four rows of three fit without scrolling. */
.group-tab-panel.pop:has(.game-list){min-height:min(550px,calc(100% - 90px));max-height:min(550px,calc(100% - 90px))}

/* ── Phone browsers (owner, 2026-10-03) ──────────────────────────────────────────────
   Found by measuring every game at 360×640, 320×568 and sideways:
   1. The board's area used to shrink below the board on a short screen, so the dice tray
      slid under the status line. It no longer shrinks: the screen scrolls a little instead.
      (A full-screen game sizes itself to the space, so it keeps shrinking.) */
.game-stage{flex:1 0 auto}
.game-full .game-stage{flex:1 1 0;min-height:0}
/* 2. The chat is a button in the header and drops down under it, so it never pushes the board up
      or covers the buttons at the bottom of a game (see "The table chat" below). */
/* 3. Boards sized by the height that is really left under the header, players and status. */
.ludo{width:min(100%,56dvh,max(220px,calc(100dvh - 300px)))}   /* never tiny: sideways it scrolls instead */
@media (pointer:coarse){
  /* 4. Thumb-sized targets for the chat bar and the settings' short options. */
  .game-chat-btn{width:44px;height:44px}
  .game-chat-bar input{height:44px}
  .game-chat-emotes button{min-width:44px;height:44px}
  .game-options button{min-width:44px}
}

/* The table chat (owner, 2026-10-03: "this chatting disturbs while playing"): it starts folded in
   every game, and opened it sits below the game instead of floating over the dice and status line.
   While folded, the other player's newest line shows for four seconds beside the button. */
.game-chat.min{left:auto;flex-direction:row;align-items:center;gap:8px;pointer-events:none}
.game-chat.min>.game-chat-peek{pointer-events:auto}
.game-chat.min>.game-chat-peek:not([hidden]){display:flex}
.game-chat-peek{order:2;align-items:center;gap:6px;max-width:min(70vw,320px);min-height:36px;padding:6px 12px;border:0;border-radius:18px 4px 18px 18px;background:var(--p-panel,#141a2a);color:inherit;font:inherit;font-size:14px;text-align:left;box-shadow:0 8px 24px -10px rgba(0,0,0,.8),0 0 0 1px var(--p-hair,rgba(255,255,255,.1));cursor:pointer;animation:game-chat-in .18s ease-out}
.game-chat-peek b{flex:none;font-size:12px;font-weight:800;color:var(--p-brand,var(--accent))}
.game-chat-peek .t{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.game-chat-peek .e{font-size:20px;line-height:1}
.game-chat-peek .s{width:30px;height:30px;object-fit:contain}
.game-chat-peek[hidden]{display:none}

/* ── Map Quiz (mapquiz.js): the place's name, a blank map of India, the scores and Lock in ── */
.mq{display:flex;flex-direction:column;gap:10px;width:100%;width:min(100%,48dvh);margin-inline:auto}
.mq-ask{display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center}
.mq-ask small{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--p-muted,var(--muted))}
.mq-ask strong{font-size:22px;line-height:1.15}
.mq-map{position:relative;border-radius:20px;overflow:hidden;box-shadow:0 22px 50px -18px rgba(0,0,0,.75),0 0 0 1px rgba(255,255,255,.14)}
.mq-map svg{display:block;width:100%;height:auto;outline:none}
.mq-map.can svg{cursor:crosshair}
.mq-map svg:focus-visible{outline:3px solid #fbbf24;outline-offset:-3px}
.mq-sea{fill:#0b3b5c}
.mq-grid line{stroke:rgba(255,255,255,.08);stroke-width:.5}
.mq-land{fill:#f3ead7;stroke:#8a7a5c;stroke-width:.7;stroke-linejoin:round}
.mq-pin path{stroke:#fff;stroke-width:1.1}
.mq-pin circle{fill:#fff}
.mq-pin.p0 path{fill:#0284c7}.mq-pin.p1 path{fill:#e11d48}
.mq-pin.pending{opacity:.8}
.mq-miss{stroke-width:1.3;stroke-dasharray:3 2;stroke-linecap:round}
.mq-miss.p0{stroke:#0284c7}.mq-miss.p1{stroke:#e11d48}
.mq-star circle{fill:#fbbf24;stroke:#fff;stroke-width:1.3}
.mq-star path{fill:#78350f}
.mq-star{animation:mq-pop .35s cubic-bezier(.3,1.5,.5,1)}
@keyframes mq-pop{from{opacity:0;transform-box:fill-box;scale:.2}}
.mq-card{position:absolute;left:10px;right:10px;bottom:10px;display:grid;gap:6px;padding:12px;border-radius:16px;background:rgba(15,23,42,.93);color:#fff;animation:mq-up .25s ease-out}
@keyframes mq-up{from{opacity:0;transform:translateY(12px)}}
.mq-card p{display:flex;align-items:baseline;gap:10px;margin:0;font-size:15px}
.mq-card b{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mq-card span{opacity:.8}
.mq-card strong{min-width:44px;text-align:right;font-size:17px}
.mq-card .p0 strong{color:#7dd3fc}.mq-card .p1 strong{color:#fda4af}
.mq-card .game-primary{min-height:44px;margin-top:4px}
/* The answer's explanation (AI places, FR-23): what the place is and where. */
.mq-card p.mq-why{display:block;margin:2px 0 0;font-size:14px;line-height:1.4;opacity:.9}
.mq-swing{margin:0 0 2px;font-size:15px;font-weight:800;text-align:center}
.mq-swing.up{color:#4ade80}.mq-swing.down{color:#f87171}
.mq-card em{font-style:normal;font-size:13px;font-weight:800}
.mq-card em.up{color:#4ade80}.mq-card em.down{color:#f87171}
.mq-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:50px}
.mq-score{flex:0 1 auto;min-width:0;max-width:30%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600}
.mq-score b{font-size:20px}
.mq-score.p0 b{color:#38bdf8}.mq-score.p1 b{color:#fb7185}
.mq-wait{flex:1;text-align:center;font-size:13px;color:var(--p-muted,var(--muted))}
.mq-foot .game-primary{flex:1;max-width:210px;min-height:46px}
.mq-foot .game-primary:disabled{opacity:.55;cursor:default}
.mq-mark{width:20px;height:26px}
.mq-mark path{stroke:#fff;stroke-width:1.6}.mq-mark circle{fill:#fff}
.mq-mark.p0 path{fill:#0284c7}.mq-mark.p1 path{fill:#e11d48}
@media (max-height:640px){.mq{gap:6px;width:min(100%,42dvh)}.mq-ask strong{font-size:19px}}
@media (prefers-reduced-motion:reduce){.mq-star,.mq-card{animation:none}}

/* ── Quiz Duel (quizduel.js): the question, four options, a 15-second bar; the foot is Map Quiz's ── */
.qd{display:flex;flex-direction:column;gap:12px;width:100%;max-width:440px;margin-inline:auto}
.qd-top{display:flex;flex-direction:column;align-items:center;gap:8px}
.qd-top small{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--p-muted,var(--muted))}
.qd-time{width:100%;height:6px;border-radius:99px;background:rgba(148,163,184,.25);overflow:hidden}
.qd-time i{display:block;height:100%;width:100%;border-radius:inherit;background:linear-gradient(90deg,#22c55e,#a3e635);transition:width .1s linear}
.qd-time i.low{background:linear-gradient(90deg,#ef4444,#f97316)}
.qd-q{margin:0;padding:16px;border-radius:18px;background:var(--p-surface-2,rgba(255,255,255,.06));font-size:18px;font-weight:700;line-height:1.35;text-align:center}
/* A statement question (PYQ style: "1. … 2. … Which … is/are correct?") keeps its lines, reads left to right, a little smaller. */
.qd-q{white-space:pre-line}
.qd-q.long{font-size:15.5px;font-weight:600;line-height:1.45;text-align:left}
.qd-q.xl{font-size:14.5px;padding:12px 14px}   /* the longest real PYQs (400+ characters) still fit a phone */
.qd-opts{display:grid;gap:8px}
.qd-opt{display:flex;align-items:center;gap:12px;width:100%;min-height:52px;padding:10px 12px;border:1.5px solid var(--p-hair-strong,rgba(255,255,255,.16));border-radius:14px;background:none;color:inherit;font:inherit;font-size:15px;text-align:left;cursor:pointer;transition:background .15s,border-color .15s,transform .1s}
.qd-opt b{flex:0 0 30px;height:30px;display:grid;place-items:center;border-radius:9px;background:rgba(148,163,184,.2);font-size:13px}
.qd-opt span{flex:1;min-width:0}
.qd-opt:not(:disabled):active{transform:scale(.985)}
@media (hover:hover){.qd-opt:not(:disabled):hover{border-color:var(--p-brand,var(--accent))}}
.qd-opt:disabled{cursor:default;opacity:1}
.qd-opt.chosen{border-color:var(--p-brand,var(--accent));background:color-mix(in srgb,var(--p-brand,#6366f1) 18%,transparent)}
.qd-opt.right{border-color:#22c55e;background:rgba(34,197,94,.16)}.qd-opt.right b{background:#22c55e;color:#04210f}
.qd-opt.wrong{border-color:#ef4444;background:rgba(239,68,68,.14)}.qd-opt.wrong b{background:#ef4444;color:#fff}
.qd-opt.dim{opacity:.5}
.qd-opt em{flex:0 0 auto;max-width:28%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:3px 8px;border-radius:99px;font-size:11px;font-style:normal;font-weight:700;color:#fff}
.qd-opt em.p0{background:#0284c7}.qd-opt em.p1{background:#e11d48}
.qd-hold{display:grid;place-items:center;gap:6px;min-height:260px;padding:20px;border-radius:18px;background:var(--p-surface-2,rgba(255,255,255,.06));text-align:center}
.qd-hold p{margin:0;font-size:17px;font-weight:700}
.qd-hold small{color:var(--p-muted,var(--muted))}
.qd-why{display:grid;gap:8px;padding:12px;border-radius:16px;background:rgba(15,23,42,.6);animation:mq-up .25s ease-out}
.qd-why p{margin:0;font-size:14px;line-height:1.45}
.qd-pts{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:13px}
.qd-pts .p0 b{color:#7dd3fc}.qd-pts .p1 b{color:#fda4af}
.qd-why .game-primary{min-height:44px}
.qd-mark{display:grid;place-items:center;width:22px;height:22px;border-radius:7px;font-size:12px;font-style:normal;font-weight:800;color:#fff}
.qd-mark.p0{background:#0284c7}.qd-mark.p1{background:#e11d48}
@media (max-height:640px){.qd{gap:8px}.qd-q{padding:12px;font-size:16px}.qd-opt{min-height:46px;padding:8px 10px}.qd-hold{min-height:200px}}
@media (prefers-reduced-motion:reduce){.qd-why{animation:none}.qd-time i{transition:none}}

/* ── Map Quiz fills the screen (owner, 2026-10-03: "make the map bigger … no scroll bar") ──────
   A game with fit: true drops the players row (its foot shows both names and scores) and sizes
   itself to the height that is left, so the map is as big as the screen allows and nothing scrolls.
   The map keeps its shape; the sea colour fills the box around it. */
.game-fit .game-players{display:none}
.game-fit .game-status:empty{display:none}
.game-fit .game-layer-inner{overflow:hidden}
.game-fit .game-stage{flex:1 1 0;min-height:0;padding:4px 10px 0}
.game-fit .game-board{width:100%;height:100%}
.game-fit .game-leave{margin-top:4px}
.game-fit .mq{width:100%;max-width:none;height:100%;gap:8px}
.game-fit .mq-map{flex:1 1 0;min-height:0;background:#0b3b5c}
.game-fit .mq-map svg{height:100%}
.mq-time{max-width:320px;margin-top:6px}

/* AI questions (FR-23): the "type any topic" box in a game's Settings. 16 px so iPhone does not zoom. */
.game-ask{display:block;width:100%;height:44px;margin-top:12px;padding:0 14px;border-radius:12px;border:1px solid var(--p-hair-strong,var(--border));background:var(--p-bg,#0b0f1a);color:inherit;font:inherit;font-size:16px}
.game-ask:focus{outline:2px solid var(--p-brand,var(--accent));outline-offset:1px}


/* ── Jackaroo (jackaroo.md §2b, after the owner's Jackaroo King screenshots) ─────────────────
   Green table with a faint gold pattern, the wooden board in a gold frame, the four players in
   the corners with a fan of card backs, team badge and the turn timer, the hand at the bottom.
   Sizes follow the board's own width (--t), so it looks the same on every phone. */
html .game-layer.jk-layer{background:radial-gradient(90% 60% at 50% 16%,#3f8f6e 0%,#1f5e47 48%,#113a2c 100%);color:#fff}
.jk-layer::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.09;background:radial-gradient(circle at 50% 50%,transparent 37%,#f5d77a 38.5%,transparent 40%) 0 0/120px 120px,radial-gradient(circle at 0 0,transparent 37%,#f5d77a 38.5%,transparent 40%) 0 0/120px 120px}
.jk-layer .game-status{display:none}
.jk{height:100%;display:flex;flex-direction:column;gap:6px;font-family:system-ui,-apple-system,"Segoe UI",sans-serif}
.jk-box{flex:1 1 0;min-height:0;container-type:size;display:grid;place-items:center}
.jk-table{--t:min(100cqw,100cqh);position:relative;width:var(--t);height:var(--t)}
.jk-board{display:block;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 10px 16px rgba(0,0,0,.45))}
.jk-band{fill:#1d6b4c}
.jk-grain path{fill:none;stroke:#9a6430;stroke-opacity:.11;stroke-width:.07}
.jk-hole{stroke:#fff3d6;stroke-opacity:.4;stroke-width:.05}
.jk-pad{fill:#dcae6c;stroke:#a8743a;stroke-width:.08}
.jk-start{fill:none;stroke:var(--c);stroke-width:.14}
.jk-ring{fill:none;stroke:var(--c);stroke-width:.1}
.jk-hit{fill:transparent;stroke:none}
.jk-m{transition:transform 80ms linear;pointer-events:none}
.jk-m-shade{fill:rgba(60,30,5,.35)}
.jk-m-glow{fill:rgba(253,230,138,.35);stroke:#fde68a;stroke-width:.14;opacity:0}
.jk-m.can{pointer-events:auto;cursor:pointer}
.jk-m.can .jk-m-glow{opacity:1;animation:jk-blink 1s ease-in-out infinite}
.jk-target{fill:rgba(251,191,36,.6);stroke:#fff;stroke-width:.12;animation:jk-blink 1s ease-in-out infinite;pointer-events:none}
[data-targets] .jk-hit{cursor:pointer}
@keyframes jk-blink{50%{opacity:.35}}

.jk-seat{position:absolute;z-index:2;width:calc(var(--t)*.25);display:flex;flex-direction:column;align-items:center;pointer-events:none}
.jk-seat.tl{left:0;top:0}.jk-seat.tr{right:0;top:0}.jk-seat.bl{left:0;bottom:0}.jk-seat.br{right:0;bottom:0}
.jk-fan{position:relative;width:calc(var(--t)*.12);height:calc(var(--t)*.065)}
.jk-fan i{position:absolute;left:50%;bottom:0;width:calc(var(--t)*.042);height:calc(var(--t)*.062);margin-left:calc(var(--t)*-.021);border-radius:3px;background:linear-gradient(135deg,#efbd75,#b7712c);border:1.5px solid #fff1d6;box-shadow:0 1px 2px rgba(0,0,0,.35);transform:rotate(var(--r));transform-origin:50% 130%}
.jk-ava{position:relative;width:calc(var(--t)*.165);height:calc(var(--t)*.165);margin-top:calc(var(--t)*-.03)}
.jk-seat .jk-photo{width:100%;height:100%;min-width:0;border-radius:50%;border:3px solid var(--c);box-shadow:0 4px 10px rgba(0,0,0,.45);display:grid;place-items:center;background-color:#1e293b;background-size:cover;background-position:center;color:#fff;font-weight:800;font-size:calc(var(--t)*.05)}
.jk-photo.jk-bot svg{width:58%;height:58%;fill:none;stroke:#e2e8f0;stroke-width:1.6;stroke-linecap:round}
.jk-clock{position:absolute;left:-7%;top:-7%;width:114%;height:114%;transform:rotate(-90deg);opacity:0}
.jk-clock circle{fill:none;stroke:#fbbf24;stroke-width:7;stroke-linecap:round;stroke-dasharray:289;transition:stroke-dashoffset .2s linear}
.jk-seat.turn .jk-clock{opacity:1}
.jk-seat.low .jk-clock circle{stroke:#ef4444}
.jk-secs{position:absolute;inset:0;display:none;place-items:center;border-radius:50%;background:rgba(0,0,0,.45);color:#fcd34d;font-size:calc(var(--t)*.075);font-weight:900;text-shadow:0 2px 0 #92400e,0 0 8px rgba(0,0,0,.6)}
.jk-seat.turn .jk-secs{display:grid}
.jk-seat.low .jk-secs{color:#fee2e2;text-shadow:0 2px 0 #7f1d1d}
.jk-team{position:absolute;right:-6%;bottom:-4%;width:36%;height:36%;border-radius:50%;display:grid;place-items:center;border:2px solid #fff;font-size:calc(var(--t)*.03);font-style:normal;font-weight:900;color:#fff;background:#dc2626}
.jk-team.t1{background:#2563eb}
.jk-name{max-width:100%;margin-top:4px;padding:2px 10px;border-radius:999px;background:rgba(0,0,0,.45);font-size:12px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.jk-pile{position:absolute;left:50%;top:50%;width:calc(var(--t)*.14);transform:translate(-50%,-50%);pointer-events:none}
.jk-pilecard{animation:jk-fly .38s cubic-bezier(.2,.8,.3,1)}
.jk-pilecard.still{animation:none}
.jk-pilecard.burnt .jk-face{opacity:.45}
.jk-pilecard em{position:absolute;left:50%;bottom:8%;transform:translateX(-50%) rotate(-12deg);padding:1px 6px;border-radius:6px;background:#b91c1c;color:#fff;font-size:15cqw;font-style:normal;font-weight:800}
@keyframes jk-fly{from{transform:translate(calc(var(--fx)*var(--t)*.36),calc(var(--fy)*var(--t)*.36)) scale(.55) rotate(-25deg);opacity:.3}}

.jk-card{position:relative;display:block;width:100%;aspect-ratio:.7;padding:0;border:0;border-radius:10%/7%;background:#fff;color:#1b2340;box-shadow:0 3px 8px rgba(0,0,0,.35);container-type:inline-size;font:inherit}
.jk-face{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;padding-top:26%}
.jk-face.red{color:#d21f2b}
.jk-corner{position:absolute;left:7%;top:5%;display:flex;flex-direction:column;align-items:center;line-height:1}
.jk-corner b{font-size:24cqw;font-weight:800;letter-spacing:-.04em}
.jk-corner i{font-size:19cqw;font-style:normal}
.jk-big{font-size:46cqw;font-weight:800;line-height:.95}
.jk-ico{width:50%;line-height:0}
.jk-ico svg{width:100%;height:auto;fill:currentColor}
.jk-face small{margin-top:4%;font-size:12cqw;font-weight:800;line-height:1;white-space:nowrap}
.jk-hand{display:flex;justify-content:center;gap:2.4%;padding:0 12px 4px}
.jk-hand .jk-card{flex:0 0 auto;width:min(20%,92px);cursor:pointer;transition:transform .15s ease-out}
.jk-hand .jk-card.off{background:#cdd0d6}
.jk-hand .jk-card.sel{transform:translateY(-14%);box-shadow:0 0 0 3px #fbbf24,0 8px 16px rgba(0,0,0,.4)}
.jk-hand:not(.mine) .jk-card{cursor:default}
.jk-card.deal{animation:jk-deal .36s cubic-bezier(.2,.8,.3,1) both;animation-delay:var(--d)}
@keyframes jk-deal{from{transform:translateY(-120%) scale(.5);opacity:0}}
.jk-note{display:flex;flex-direction:column;align-items:center;gap:2px;min-height:40px;margin:0;padding:0 12px;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.5)}
.jk-note span{color:#d1fae5;font-size:13px;font-weight:600}
.jk-note b{color:#fef3c7;font-size:15px;font-weight:800}
.jk-note :empty{display:none}
.jk-acts{display:flex;justify-content:center;gap:8px;padding:0 12px 10px}
.jk-acts:empty{display:none}
.jk-act{min-height:40px;padding:0 16px;border:0;border-radius:999px;background:#fbbf24;color:#3b2506;font:inherit;font-size:14px;font-weight:800;cursor:pointer}
.jk-act.quiet{background:rgba(0,0,0,.35);color:#fff}
@media (prefers-reduced-motion:reduce){.jk-m,.jk-clock circle,.jk-hand .jk-card{transition:none}.jk-pilecard,.jk-card.deal,.jk-m.can .jk-m-glow,.jk-target{animation:none}}
