﻿/* ════════════════════════════════════════════════════════════
   SHADOW SALOON - Main Stylesheet
   Western-Noir Theme
════════════════════════════════════════════════════════════ */

:root {
  /* ── Raw palette: theme-INDEPENDENT constants. Never switch with the theme.
     Used by the deliberately fixed-dark artwork surfaces (spotlight banner,
     intro windows, dice/action cinemas, card backs, chat paper) and by fixed
     gold gradients (buttons, avatars). ── */
  --raw-ink:        #0d0a07;
  --raw-gold:       #c8922a;
  --raw-gold-light: #e8b84b;
  --raw-amber:      #d4620a;
  --raw-parchment:  #e8d5b0;
  --raw-smoke:      #a89784;
  --raw-old-paper:  #c9b48a;
  --raw-border:     rgba(200, 146, 42, .22);
  --raw-surface-1:        rgba(8, 5, 2, .65);
  /* Currently unreferenced since SS-0336 (the dark --surface-1-strong is now a
     literal "raised" value, not this alias). Kept as a raw-palette reference. */
  --raw-surface-1-strong: rgba(8, 5, 2, .88);
  --raw-surface-2:        rgba(200, 146, 42, .08);
  --raw-scrim:            rgba(8, 5, 2, .85);

  /* ── Semantic, theme-aware tokens (dark = default; light overrides below).
     Components reference ONLY these (or the raw ones on dark islands). ── */
  --surface-0-a: #241708;                     /* page gradient start */
  --surface-0-b: #160f07;
  --surface-0-c: #0d0a07;
  --surface-1:        var(--raw-surface-1);          /* card/panel */
  /* V2 (2026-07-05): lifted from the near-black raw value to a real "raised" step
     above --surface-1 (dropdowns/toasts/footer bar sit clearly above the panel). */
  --surface-1-strong: rgba(30, 20, 10, .90);
  --surface-2:        var(--raw-surface-2);          /* subtle inset chip */
  --surface-hover:    rgba(200, 146, 42, .14);
  --heading:     #e8b84b;                     /* readable heading/emphasis text */
  --text-main:   #e8d5b0;
  --text-dim:    #a89784;
  --text-invert: #241708;                     /* text on accent-filled surfaces */
  --accent-strong: #e8b84b;                   /* theme accent, strong variant */
  --accent-amber:  #d4620a;
  --border-soft:   rgba(200, 146, 42, .22);
  --border-strong: rgba(200, 146, 42, .45);
  /* V2: opaque edge for cards nested on the lighter --pf-board panel — 3.2:1 vs
     the panel, 3.8:1 vs .db-section (WCAG 1.4.11). Deliberately NOT a --border-soft
     bump: that would relight the game-frame/stage borders (--board-border /
     --border-soft outside .pf-board), which must stay dark. */
  --card-edge:     #7d6a52;
  --shadow-color:  rgba(0, 0, 0, .5);
  --scrim:         rgba(8, 5, 2, .85);
  /* V2: sticky app chrome (header/footer) one visible step above the page.
     --scrim stays the darker veil for overlays/backdrops — do not conflate. */
  --chrome:        rgba(33, 22, 9, .92);
  --danger:        #e88;
  --danger-strong: #c85a6a;
  --success:       #88d088;
  /* Near-opaque card/panel gradient + form-input surface (the translucent
     --surface-1 is too see-through for text-heavy panels over the saloon bg). */
  /* V2: panel elevation — lifted so cards/panels read as a step above the page. */
  --card-grad-a: rgba(34, 24, 13, .97);
  --card-grad-b: rgba(22, 15, 8, .98);
  --input-bg:    rgba(8, 5, 2, .85);
  --modal-grad-a: #2e1f0e;
  --modal-grad-b: #0d0a07;
  /* SS-0312: theme-aware game-surface tokens (dark = the former hardcoded
     island values). Light values live in the [data-theme="light"] block. */
  /* V2: game-frame FILL lifted to match the panel elevation. --board-border stays
     .28 (unchanged) — the game-frame/stage EDGE must not get lighter. */
  --board-grad-a: rgba(34, 24, 13, .97);
  --board-grad-b: rgba(22, 15, 8, .98);
  --board-border: rgba(200, 146, 42, .28);
  --board-shadow: 0 18px 55px rgba(0, 0, 0, .55), inset 0 1px 0 rgba(200, 146, 42, .09);
  --felt-base-a: #1d3b2a;
  --felt-base-b: #122418;
  --felt-base-c: #0b160e;
  --felt-rim:    #3a2410;
  --felt-shadow: inset 0 0 60px rgba(0, 0, 0, .6), 0 14px 34px rgba(0, 0, 0, .45);
  --stage-back-a: #16100a;
  --stage-back-b: #0e0905;
  --stage-floor-a: #3a2412;
  --stage-floor-b: #311d0d;
  --spot-accent-mix: 55%;   /* Akzent-Anteil im Rampenlicht-Verlauf */
  --art-glow: 46%;   /* Poster-Kacheln: Akzent-Glow (Betreiber: Dark darf kraeftiger) */
  --art-tint: 20%;
  /* SS-0312 stage 2: small-scale game-surface tokens (wells/chips inset on
     boards, neutral hairlines). Dark = the former hardcoded values. */
  --well:        rgba(8, 5, 2, .45);
  --well-strong: rgba(8, 5, 2, .62);
  --edge:        rgba(255, 255, 255, .07);
  --edge-strong: rgba(255, 255, 255, .14);
  --border-faint: rgba(200, 146, 42, .10);

  /* ── Legacy palette names: kept as aliases of the semantic tokens so the
     existing rules follow the theme. Fixed gradients keep using --gold/
     --gold-light (raw constants, see below) on purpose. ── */
  --ink:        #0d0a07;
  --dark-wood:  #1a1208;
  --mid-wood:   #2e1f0e;
  --warm-wood:  #4a2f14;
  --gold:       #c8922a;
  --gold-light: #e8b84b;
  --amber:      #d4620a;
  /* --smoke: warm sandy beige for secondary text (labels, hints, counters).
     Lightened from #8a7a6a to #a89784 so the contrast on the dark
     saloon background is comfortably AA-compliant (~6:1 instead of 4.5:1).
     Atmosphere stays warm/muted. */
  --smoke:      var(--text-dim);
  --parchment:  var(--text-main);
  --old-paper:  #c9b48a;
  --blood-red:  #8b1a1a;
  --red-light:  #c0352a;
  --green-felt: #1a3d2b;
  --green-ok:   #2d7a4a;
  --shadow:     #0a0806;
  /* Generic border tone (muted gold). WAS UNDEFINED EVERYWHERE - every
     `border: 1px solid var(--border)` (admin shell, toolbar dividers, filter
     fields, pager, podium/report box) was an invalid declaration and rendered
     NO border at all - that is why the outer frame of the variant-B shell was missing. */
  --border:     var(--border-soft);
  --btn-radius: 6px;            /* Button standard: uniform corner radius (soft) for all real action buttons */

  /* Per-mode accent: defaults to gold, overridden in .mode-* classes. */
  --accent:       var(--gold);
  --accent-light: var(--gold-light);

  /* Body font: Inter for UI readability + tabular numbers, loaded
     via Google Fonts in App.razor. System stack as fallback. Headings use
     Rye (see h1/h2/h3 + .card-title/.lobby-code/etc. with explicit
     font-family: 'Rye'). Special Elite was removed entirely. */
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
               'Helvetica Neue', Arial, sans-serif;
}

/* ── Light theme ("Wanted Poster bei Tageslicht"): same color family, inverted
   lightness. Values match the approved mockup (sitewide-layout-final.html).
   Toggled via html[data-theme="light"], persisted in localStorage (ssTheme).
   (Der frühere Zusatz-Selektor für .modal-overlay-v2 stammte aus der
   §8-Insel-Zeit und ist mit dem Insel-Abbau (SS-0312 Etappe 2) überflüssig;
   er bleibt harmlos stehen, falls ein Overlay je wieder eigene Token-Pins
   bekommt.) ── */
[data-theme="light"],
[data-theme="light"] .modal-overlay-v2 {
  --surface-0-a: #fbf3e0;
  --surface-0-b: #f2e3c4;
  --surface-0-c: #e9d7ae;
  --surface-1:        rgba(255, 252, 245, .86);
  --surface-1-strong: rgba(255, 255, 250, .96);
  --surface-2:        rgba(156, 106, 26, .08);
  --surface-hover:    rgba(156, 106, 26, .13);
  --heading:     #7a4a12;
  --text-main:   #3a2a16;
  /* SS-0312 E2: von #6b5c48 abgedunkelt — auf den dunkelsten Sand-Stops der
     Spielflächen (≈#ccb181) fiel Dim-Text sonst auf 3,4–3,8:1. */
  --text-dim:    #4f4335;
  --text-invert: #fff8ec;
  --accent-strong: #7a4a12;
  /* SS-0312 E2: von #b5540a abgedunkelt — fiel auf Sand-Karten unter 3:1. */
  --accent-amber:  #7d3b07;
  --border-soft:   rgba(120, 80, 20, .28);
  --border-strong: rgba(120, 80, 20, .5);
  /* V2 light counterparts: light panel/card already contrast well, so card-edge
     reuses the stronger brown border; chrome mirrors the light scrim. */
  --card-edge:     rgba(120, 80, 20, .5);
  --shadow-color:  rgba(80, 60, 30, .18);
  --scrim:         rgba(255, 250, 240, .9);
  --chrome:        rgba(255, 250, 240, .9);
  --danger:        #a3324a;
  --danger-strong: #7a2338;
  --success:       #17663a;   /* dark enough for 4.5:1 even on the darker modal-gradient end (#f2e3c4) */
  --card-grad-a: rgba(255, 252, 245, .94);
  --card-grad-b: rgba(249, 240, 222, .97);
  --input-bg:    rgba(255, 255, 250, .9);
  --modal-grad-a: #fffdf7;
  --modal-grad-b: #f2e3c4;
  /* SS-0312: light variants of the game-surface tokens — "Wanted Poster bei
     Tageslicht": cream boards, daylight felt, bright stage backdrop. */
  --board-grad-a: rgba(247, 236, 212, .92);
  --board-grad-b: rgba(230, 209, 168, .96);
  --board-border: rgba(120, 80, 20, .35);
  --board-shadow: 0 18px 45px rgba(80, 60, 30, .22), inset 0 1px 0 rgba(255, 255, 255, .6);
  --felt-base-a: #446e55;
  --felt-base-b: #3a6049;
  --felt-base-c: #30523e;
  --felt-mix-a: 7%;
  --felt-mix-b: 12%;
  --felt-mix-c: 15%;
  --felt-rim:    #8a6a3c;
  --felt-shadow: inset 0 0 60px rgba(40, 70, 52, .35), 0 14px 34px rgba(80, 60, 30, .28);
  --stage-back-a: #e9d4a9;
  --stage-back-b: #d8bc88;
  --stage-floor-a: #b8934f;
  --stage-floor-b: #aa8441;
  --spot-accent-mix: 26%;   /* Light: Pastell statt Vollton, sonst faellt der Text unter 4.5:1 */
  --art-glow: 58%;   /* Poster-Kacheln: Akzent im Light kraeftiger, sonst blass */
  --art-tint: 30%;
  --well:        rgba(156, 106, 26, .10);
  --well-strong: rgba(156, 106, 26, .16);
  --edge:        rgba(120, 80, 20, .16);
  --edge-strong: rgba(120, 80, 20, .30);
  --border-faint: rgba(120, 80, 20, .16);
  /* Legacy names that were used directly as colors (not via the aliases above). */
  /* SS-0312 E2: von #6a5642 abgedunkelt (s. --text-dim). */
  --old-paper: #4a3b28;
  --accent:    #9c6a1a;   /* gold-mode accent readable on light; .mode-* still override */
}

/* ── §8 "Always dark islands" — ABGEBAUT (SS-0312 Etappe 2). Der frühere
   Dark-Re-Pin-Block für .screen-game/.screen-break/.screen-voting/
   .screen-result/.card-board ist ersatzlos entfernt: alle Spielflächen laufen
   jetzt auf den theme-fähigen Tokens (Dark-Werte = die alten Insel-Werte).
   Bewusst FEST DUNKEL bleiben nur eigenständige Artwork-/Kino-Flächen
   (Intro-Fenster .gintro-*, Würfel-/Aktions-Kinos, Roll-/Shuffle-Prompts,
   Kick-Toasts, Karten-Rücken, Seeschlacht-Wasser, Chat-Telegrammpapier,
   Kopf-Hero .lobby-hero) — deren Text-Inks hängen an der Raw-Palette
   (--raw-*), nie an Theme-Tokens. ── */

/* Per-game accent colors: applied via mode-* classes on the game screen
   root, the lobby wrapper, and mode pills in profile/statistics. */
.mode-schattenspiel { --accent: #5a2f4a; --accent-light: #9a5a8a; }
.mode-hangman       { --accent: #7a3a1a; --accent-light: #b8693a; }
.mode-tabu          { --accent: #a8553a; --accent-light: #d68a72; }
.mode-musikquiz     { --accent: #a3324a; --accent-light: #d65c78; }
/* Wissensquiz: teal/blue-green - intentionally the only COOL accent, clearly distinct
   from the four warm tones. */
.mode-wissensquiz   { --accent: #1f6f6a; --accent-light: #3fa89f; }
/* Memory: jade/card-table green */
.mode-memory        { --accent: #1f8a6d; --accent-light: #37b894; }
/* Durak: tsarist purple */
.mode-durak         { --accent: #4a2f6e; --accent-light: #7d5bc0; }
/* Skat: oak-leaf green (card table mode) */
.mode-skat          { --accent: #3f6b32; --accent-light: #7faa55; }
/* Doppelkopf: cognac/amber (card table mode) */
.mode-doppelkopf    { --accent: #9a5a1e; --accent-light: #d18a3e; }
/* Poker: garnet red (card table mode) */
.mode-poker         { --accent: #8e2c3b; --accent-light: #c85a6a; }
/* Seeschlacht: navy/steel blue */
.mode-seeschlacht   { --accent: #2b4f74; --accent-light: #4d7eab; }
/* Schnellschuss: cactus teal (Stammtisch shedding game) */
.mode-schnellschuss { --accent: #1f9aae; --accent-light: #4fc4d6; }
/* Rausschmeisser: colt steel / gunmetal (dice race game) */
.mode-rausschmeisser { --accent: #4a5d6b; --accent-light: #7d97a8; }
/* Mahjong: bone-white taupe (stone/porcelain, layered pair puzzle) */
.mode-mahjong       { --accent: #8a7a63; --accent-light: #b8a888; }
/* Boomtown: prairie/denim blue (frontier build-and-trade board game) */
.mode-boomtown      { --accent: #2f6aa6; --accent-light: #5fa0da; }
/* Ultimate TicTacToe: rosewood/mauve (meta tic-tac-toe board game). --x-color/--o-color
   are the readable X/O glyph tints (per theme, ≥7:1) — --accent-light must never be text. */
.mode-uttt          { --accent: #82355c; --accent-light: #c76194; --x-color: #d98cb2; --o-color: #9db2c7; }
[data-theme="light"] .mode-uttt { --x-color: #7a2a4e; --o-color: #3f5468; }

/* SS-0312 stage 2: accent-tinted TEXT ink. Dark keeps the vivid --accent-light
   look (pixel-identical), light switches to a readable accent/text mix —
   --accent-light must never be used as a text color directly. --gold-ink is
   the same idea for the fixed gold accent (--gold as text). The per-mode rule
   re-declares the ink ON the mode root so it picks up the mode accent (custom
   properties resolve where they are declared, not where they are used). */
:root { --accent-ink: var(--accent-light); --gold-ink: #c8922a; }
[data-theme="light"] { --gold-ink: #7a4a12; }
.mode-schattenspiel, .mode-hangman, .mode-tabu, .mode-musikquiz, .mode-wissensquiz,
.mode-memory, .mode-durak, .mode-skat, .mode-doppelkopf, .mode-poker,
.mode-seeschlacht, .mode-schnellschuss, .mode-rausschmeisser, .mode-mahjong,
.mode-boomtown, .mode-uttt {
  --accent-ink: var(--accent-light);
}
[data-theme="light"],
[data-theme="light"] :is(.mode-schattenspiel, .mode-hangman, .mode-tabu,
  .mode-musikquiz, .mode-wissensquiz, .mode-memory, .mode-durak, .mode-skat,
  .mode-doppelkopf, .mode-poker, .mode-seeschlacht, .mode-schnellschuss,
  .mode-rausschmeisser, .mode-mahjong, .mode-boomtown, .mode-uttt) {
  --accent-ink: color-mix(in srgb, var(--accent) 30%, var(--text-main));
}

/* ═══════════════════════════════════════════════════════════════════
   Ultimate TicTacToe — nine local 3×3 boards in a 3×3 meta grid.
   Accent/ink + --x-color/--o-color defined above with the mode accents.
   ═══════════════════════════════════════════════════════════════════ */
.uttt-screen { display: flex; flex-direction: column; align-items: center; gap: 12px; width: 100%; }
.uttt-board-area { width: 100%; display: flex; align-items: center; justify-content: center; }
/* Head (legend + status) sits above the board in the SAME width; the board is a square below.
   The desktop height-fill scaling lives in the @media (min-width:761px) maximized block. */
.uttt-frame { width: 100%; max-width: 560px; margin: 0 auto; display: flex; flex-direction: column; gap: 8px; }
.uttt-head { display: flex; align-items: center; justify-content: space-between; gap: 8px 16px; flex-wrap: wrap; font-size: 13px; min-height: 22px; }
.uttt-legend { display: flex; gap: 8px; align-items: center; color: var(--text-dim); }
.uttt-legend .lg-x { color: var(--x-color); font-weight: 700; }
.uttt-legend .lg-o { color: var(--o-color); font-weight: 700; }
.uttt-status { color: var(--text-dim); }
.uttt-oppname { background: none; border: none; padding: 0; font: inherit; color: inherit; font-weight: 700; cursor: pointer; text-decoration: underline dotted; text-underline-offset: 2px; }
.uttt-oppname:hover { opacity: .8; }
.uttt-board-wrap { position: relative; width: 100%; }
.uttt-board { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; aspect-ratio: 1 / 1; }

.uttt-local {
  position: relative; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
  gap: 3px; padding: 5px; border-radius: 6px; background: var(--surface-2); border: 1px solid var(--border-soft);
  transition: box-shadow .18s ease, transform .18s ease, border-color .12s ease, opacity .18s ease;
}
.uttt-local.legal {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-light), 0 0 20px 2px color-mix(in srgb, var(--accent-light) 45%, transparent);
  transform: scale(1.025); z-index: 2;
}
.uttt-local.illegal-dim { opacity: .4; filter: saturate(.6); }
.uttt-local.won-x { background: color-mix(in srgb, var(--x-color) 16%, var(--surface-2)); border-color: color-mix(in srgb, var(--x-color) 55%, transparent); }
.uttt-local.won-o { background: color-mix(in srgb, var(--o-color) 16%, var(--surface-2)); border-color: color-mix(in srgb, var(--o-color) 55%, transparent); }
.uttt-local.drawn { border-color: var(--border-strong); }
.uttt-local.won-x::after, .uttt-local.won-o::after, .uttt-local.drawn::after {
  content: ''; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: 'Rye', cursive; pointer-events: none; font-size: clamp(26px, 7vw, 52px);
}
.uttt-local.won-x::after { content: '✕'; color: var(--x-color); opacity: .92; }
.uttt-local.won-o::after { content: '○'; color: var(--o-color); opacity: .92; }
.uttt-local.drawn::after { content: '—'; color: var(--text-dim); font-family: var(--font-body); font-weight: 700; font-size: clamp(20px, 5vw, 36px); }

.uttt-cell {
  aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center;
  font-family: 'Rye', cursive; font-size: clamp(13px, 3.2vw, 22px); background: transparent;
  border: 1px solid var(--border-soft); border-radius: 3px; color: var(--text-main); padding: 0; cursor: pointer;
}
.uttt-cell.is-x { color: var(--x-color); }
.uttt-cell.is-o { color: var(--o-color); }
.uttt-cell:disabled { cursor: default; }
.uttt-local.legal .uttt-cell:not(:disabled):hover { background: color-mix(in srgb, var(--accent-light) 20%, transparent); }
.uttt-local:not(.legal) .uttt-cell { cursor: default; }

.uttt-winline { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .35s ease; }
.uttt-winline.show { opacity: 1; }

.uttt-overlay {
  position: absolute; inset: -20px -16px; background: var(--scrim); display: flex;
  align-items: center; justify-content: center; border-radius: 8px; z-index: 5; padding: 20px;
}
.uttt-overlay-card {
  background: linear-gradient(160deg, var(--modal-grad-a), var(--modal-grad-b));
  border: 1px solid var(--board-border); border-radius: 10px; padding: 24px 26px; max-width: 340px; width: 100%;
  text-align: center; box-shadow: 0 20px 50px rgba(0, 0, 0, .4);
}
.uttt-overlay-card h3 { font-family: 'Rye', cursive; font-weight: 400; color: var(--heading); margin: 0 0 10px; font-size: 20px; }
.uttt-overlay-card p { font-size: 13.5px; line-height: 1.6; color: var(--text-main); margin: 0; }

/* Intro scene: three marks popping in like the opening moves */
.utti-scene { display: flex; gap: 18px; align-items: center; justify-content: center; }
.utti-mark { font-family: 'Rye', cursive; font-size: clamp(38px, 9vw, 68px); line-height: 1; text-shadow: 0 3px 14px rgba(0, 0, 0, .5); animation: utti-pop .5s ease both; }
.utti-mark.utti-x { color: var(--x-color); }
.utti-mark.utti-o { color: var(--o-color); }
.utti-mark:nth-child(2) { animation-delay: .12s; }
.utti-mark:nth-child(3) { animation-delay: .24s; }
@keyframes utti-pop { from { opacity: 0; transform: scale(.4) rotate(-8deg); } to { opacity: 1; transform: none; } }

@media (max-width: 700px) {
  .uttt-board { gap: 6px; }
  .uttt-local { gap: 2px; padding: 3px; }
}

/* Skat: bidding ladder chips + result rows */
.skat-rung { font-size: 12px; padding: 3px 9px; border-radius: 5px; background: var(--well); border: 1px solid var(--border); color: var(--smoke); }
.skat-rung.done { opacity: .5; text-decoration: line-through; }
.skat-rung.now { background: color-mix(in srgb, var(--accent) 28%, transparent); border-color: var(--accent-ink); color: var(--accent-ink); font-weight: 700; }
.skat-resrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 7px 0; border-bottom: 1px solid var(--edge); font-size: 13px; color: var(--old-paper); }
.skat-resrow:last-child { border-bottom: none; }
.skat-resrow b { color: var(--parchment); }

/* Offiziersskat (2-player Skat, same mode/accent): table layout of 8 stacks per player.
   Card size hangs on --osk-w/--osk-h ONLY — the measured maximize fit (shadowSaloon.fitOsk)
   bumps these two variables, the 2×4 grid itself never changes. */
.osk-board { --osk-w: 58px; --osk-h: 81px; }
/* Repariert (SS-0312 Nebenbefund): hier stand ein verwaister Selektor mit
   Komma direkt vor dem @media-Block — der Parser verwarf damit BEIDE Regeln
   (Basis-Kartengröße UND Maximize-Bump). */
.osk-board .durak-card { --card-w: var(--osk-w); --card-h: var(--osk-h); }
@media (min-width: 761px) {
  body.ss-maximized .osk-board .durak-card { --card-w: var(--osk-w); --card-h: var(--osk-h); }
}
.osk-auslage { display: grid; grid-template-columns: repeat(4, var(--osk-w)); gap: 16px 13px; justify-content: center; padding: 4px 0; }
.osk-stack { position: relative; width: var(--osk-w); height: calc(var(--osk-h) + 14px); }
.osk-stack .durak-card.osk-under { position: absolute; top: 0; left: 0; }
.osk-stack .durak-card.osk-over { position: absolute; top: 14px; left: 0; }
.osk-stack.single .durak-card.osk-over { top: 7px; }
.osk-stack.empty::after { content: ""; position: absolute; top: 14px; left: 0; width: var(--osk-w); height: var(--osk-h);
  border-radius: 7px; border: 1px dashed color-mix(in srgb, var(--accent-light) 30%, transparent); opacity: .5; }
.osk-zone-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-size: 12px; color: var(--old-paper); padding: 2px 4px; border-radius: 10px; }
.osk-zone-head .who { font-weight: 600; font-size: 13px; color: var(--parchment); }
.osk-zone-head .grow { flex: 1; }
.osk-zone-head .tag { font-size: 12px; color: var(--smoke); }
.osk-zone-head.turn { background: color-mix(in srgb, var(--accent) 16%, transparent); box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 30%, transparent); }
.osk-table { flex-direction: row; gap: 22px; min-height: 128px; }
.osk-panel { display: flex; flex-direction: column; align-items: center; gap: 11px; text-align: center; width: 100%; }
.osk-lbl { font-size: 13px; color: var(--old-paper); }
.osk-hint { font-size: 12px; color: var(--smoke); line-height: 1.5; max-width: 420px; }
.osk-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.osk-actions .btn { display: inline-flex; width: auto; flex: 0 0 auto; }
.osk-kontra-big { font-family: 'Rye', serif; font-size: 34px; color: var(--red-light); line-height: 1; text-shadow: 0 2px 6px #000; }
.durak-chip.osk-kontra { background: rgba(192, 53, 42, .16); border-color: color-mix(in srgb, var(--blood-red) 55%, transparent); color: var(--red-light); font-weight: 700; }
.osk-trick-slot { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.osk-trick-slot .lbl { font-size: 12px; color: var(--old-paper); letter-spacing: .04em; }
.osk-slot-empty { width: var(--osk-w); height: var(--osk-h); border-radius: 7px; border: 2px dashed var(--edge-strong);
  display: grid; place-items: center; font-size: 12px; text-align: center; padding: 5px; }
.osk-slot-empty.active { border-color: var(--accent-ink); color: var(--accent-ink); }

/* Doppelkopf: Re/Kontra party boxes in result */
.doko-party { flex: 1 1 200px; border-radius: 12px; padding: 11px 13px; background: var(--well); border: 1px solid var(--border); }
.doko-party.re { border-color: #7faa55; }
.doko-party.kontra { border-color: #c85a6a; }
.doko-party-h { font-family: 'Rye', serif; font-size: 15px; margin-bottom: 7px; }
.doko-party.re .doko-party-h { color: #7faa55; }
.doko-party.kontra .doko-party-h { color: #c85a6a; }
/* Light: Hellgruen/Hellrot als Ueberschrift faellt auf Pergament unter 4.5:1 */
[data-theme="light"] .doko-party.re .doko-party-h { color: #4a7028; }
[data-theme="light"] .doko-party.kontra .doko-party-h { color: var(--danger-strong); }
.doko-pmember { display: flex; align-items: center; justify-content: space-between; font-size: 13px; color: var(--old-paper); padding: 3px 0; }
.doko-pmember .pts { color: var(--parchment); font-weight: 600; }

/* Poker: stack chip, action bar, raise slider */
/* Community-card row: empty slots are .durak-card variants so they inherit
   every size rule (default/mobile/maximized) and always match dealt cards. */
.pk-community { display: flex; gap: 9px; align-items: center; }
.pk-community .pk-slot { background: none; box-shadow: none; border: 2px dashed var(--edge-strong); }
/* 5 cards must fit a 375px viewport: tighten gap + shrink the row's cards. */
@media (max-width: 480px) {
  .pk-community { gap: 5px; }
  .pk-community .durak-card { --card-w: 54px; --card-h: 76px; }
}
.pk-stack { display: inline-flex; align-items: center; gap: 4px; color: var(--heading); font-weight: 700; }
/* Live hand strength next to "Your Hand" (e.g. "Pair of Jacks"). */
.pk-handlabel {
  margin-left: 10px; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 700;
  color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); white-space: nowrap;
}
.pk-stack::before { content: ""; width: 10px; height: 10px; border-radius: 50%; display: inline-block;
  background: radial-gradient(circle at 35% 30%, var(--gold-light), var(--gold)); box-shadow: 0 0 0 1.5px #6b4a14; }
.pk-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; justify-content: center; margin-top: 6px;
  padding: 12px; border-radius: 12px; background: var(--well); border: 1px solid var(--border); }
/* Base .btn is display:block + width:100%. In card action bars the
   buttons should be inline + content-width + compact (otherwise full-width "slabs"). */
.card-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; align-items: center; }
.card-actions .btn,
.pk-actions .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: auto; flex: 0 0 auto; min-width: 104px; padding: 9px 18px;
  font-size: 13px; letter-spacing: .06em; border-radius: var(--btn-radius, 6px);
}

/* Card tables more compact - sections denser, smaller center, more compact "End game"
   (scoped to .card-board so Durak/Seeschlacht remain untouched). */
/* The entire game sits in ONE framed panel (like the header "card"): accent-colored
   border + dark gradient, so nothing floats loosely on the background. */
.card-board {
  gap: 8px; position: relative;
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid var(--board-border);
  border-radius: 0 0 4px 4px; padding: 16px 18px;
  box-shadow: var(--board-shadow);
}
/* Docked directly below the header card (like .lobby-actions): header open at bottom,
   board square at top, shared 1px divider, no gap. */
.lobby-redesign .lobby-header + .card-board { border-radius: 0 0 4px 4px; }
.card-board .durak-seats { gap: 8px; }
.card-board .durak-table { padding: 12px 16px; }
.card-board .durak-hand-head { margin-bottom: 4px; }
.card-board .durak-hand { padding-top: 6px; }
.card-board .host-section { border-top: none; padding-top: 0; margin-top: 4px; }
.card-board .abort-btn { width: auto; max-width: 220px; margin: 0 auto; padding: 6px 16px; font-size: 12px; }
/* Shared anchored footer (lobby = game): strip at the bottom edge of the board panel,
   status info on the left (cab-status), context action on the right (start button or game actions).
   Nothing floats freely; the inner .card-actions/.pk-actions row keeps its compact dimensions. */
.card-board .card-actions-bar {
  margin: 10px -18px -16px; display: flex; align-items: center; justify-content: space-between;
  gap: 8px 14px; flex-wrap: wrap; padding: 12px 18px;
  /* Saloon gold like the panel border (.card-board), not the mode accent - the footer
     visually belongs to the panel border. */
  border-top: 1px solid var(--board-border);
  background: var(--surface-2); border-radius: 0 0 4px 4px;
}
.card-board .card-actions-bar:empty { display: none; }
.card-board .card-actions-bar .cab-status {
  display: flex; align-items: center; gap: 8px; flex: 1 1 220px; min-width: 0;
  font-size: 12.5px; color: var(--old-paper); line-height: 1.3;
}
.card-board .card-actions-bar .cab-status b { color: var(--parchment); font-weight: 600; }
.card-board .card-actions-bar .card-actions { margin: 0; flex: 0 0 auto; }
/* Poker actions in the footer: NO inner border (the board panel already frames) and full
   footer width - the buttons spread across the entire strip instead of a box. */
.card-board .card-actions-bar .pk-actions {
  margin: 0; flex: 1 1 100%; width: 100%;
  padding: 0; border: none; background: none; border-radius: 0;
  justify-content: space-between;
}

/* ════ Unified shell - mock-only rules made real. Applies to ALL games in the
   shared GameShell (Lobby + Game). ════ */
/* Width cap: board flush with the 880px header (.lobby-header) - width:100%,
   otherwise the panel shrinks to content width in the centered screen-game flex (grid collapses). */
.card-board { width: 100%; max-width: 1000px; margin-left: auto; margin-right: auto; }
/* Nested (unframed) card panel fills the shell without its own cap. */
.card-board .card-board { max-width: none; }
/* No double border: remove frame from inner .card / profile inside the accent panel. */
.card-board .card { background: none; border-color: transparent; box-shadow: none; }
.card-board .card::before, .card-board .card::after { display: none; }
.card-board .stat-box.wanted-poster { background: none; border-color: transparent; box-shadow: none; }
/* Fit inner game containers into the shell. */
.card-board .screen-voting { background: none; min-height: 0; padding: 0; }
.card-board .hangman-layout, .card-board .see-wrap, .card-board .mq-card,
.card-board .hangman-word-card, .card-board .memory-board-card { margin: 0; }
/* Seeschlacht: "Your Fleet" + "Target Waters" side by side (otherwise they wrap in the narrower panel). */
.card-board .see-main { flex-wrap: nowrap; justify-content: center; gap: 14px; padding: 12px; align-self: stretch; }
.card-board .see-main > div { min-width: 0; }
.card-board .see-targets { justify-content: center; }
/* Break/podium/result screens: height/centering + deframing (own borders/ornaments removed). */
.card-board .screen-result { min-height: 0; padding: 4px 0; }
.card-board .break-stage, .card-board .podium-wrapper { min-height: 0; margin: 0 auto; }
.card-board .break-stage, .card-board .podium-wrapper, .card-board .card-break { background: none; border: none; box-shadow: none; }
.card-board .break-stage::before, .card-board .break-stage::after { display: none; }
/* Podium stats: slim accent scrollbar + sticky heading for many rounds. */
.card-board .podium-stats {
  max-height: 460px; overflow-y: auto; padding-right: 8px;
  /* padding-top 0 - no strip above the sticky header (otherwise scrolling
     text shows through); the header itself provides the top spacing via padding-top. */
  padding-top: 0;
  /* No own well/border inside the board panel — matches the final-score column
     (card-break is unframed here too); the off-tone box read badly on light. */
  background: none; border: none;
  scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--accent) 60%, transparent) transparent;
}
.card-board .podium-stats::-webkit-scrollbar { width: 7px; }
.card-board .podium-stats::-webkit-scrollbar-track { background: transparent; }
.card-board .podium-stats::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--accent) 52%, transparent); border-radius: 999px; }
.card-board .podium-stats::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--accent) 80%, transparent); }
/* Sticky header sits flush at the top (container padding-top:0) and provides its own
   top spacing; opaque, fully covering background + high z-index - scrolling text is
   cleanly covered instead of showing through. */
.card-board .podium-stats .section-label { position: sticky; top: 0; z-index: 5; margin: 0 0 8px; padding: 16px 0 10px; background: #130d06; }
/* In-game: game components render their own screen-game/screen-break wrapper INSIDE
   the shared GameShell card-board - neutralize (no second saloon background/panel). */
.card-board .screen-game, .card-board .screen-break { background: none; min-height: 0; padding: 0; }
/* Card games bring their own "durak-board card-board" - unfame the nested panel
   so only the outer GameShell draws the accent border (no double border). */
.card-board .card-board { border: none; background: none; box-shadow: none; padding: 0; margin: 0; }
/* In-game abort now runs centrally via the header X - hide the component-specific
   "End game" buttons (host-section/abort-btn) inside the shell. */
.card-board .host-section, .card-board .abort-btn { display: none; }
/* Poker bet bar: no inner border inside the accent panel (no double border). */
.card-board .pk-actions { background: none; border: none; padding: 0; }

.pk-raise { display: flex; flex-direction: column; gap: 6px; min-width: 220px; }
.pk-raise-top { display: flex; align-items: center; justify-content: space-between; font-size: 12px; color: var(--old-paper); }
.pk-raise-top b { font-family: 'Rye', serif; font-size: 16px; color: var(--heading); }
.pk-raise input[type=range] { width: 100%; accent-color: var(--accent); }
.pk-quick { display: flex; gap: 6px; }
.pk-quick .qbet { cursor: pointer; font-size: 12px; padding: 3px 10px; border-radius: 999px; background: var(--well);
  border: 1px solid var(--border); color: var(--old-paper); }
.pk-quick .qbet:hover { border-color: var(--accent-ink); color: var(--accent-ink); }

/* Deck skin selector (face card letters) at the card table */
.deck-skin-select { display: inline-flex; gap: 0; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; }
.deck-skin-select .dss { background: var(--well); border: none; border-right: 1px solid var(--border); color: var(--smoke);
  font-family: var(--font-body); font-size: 12px; padding: 4px 9px; cursor: pointer; line-height: 1; }
.deck-skin-select .dss:last-child { border-right: none; }
.deck-skin-select .dss.on { background: color-mix(in srgb, var(--accent) 30%, transparent); color: var(--accent-ink); font-weight: 600; }
.deck-skin-select .dss:hover:not(.on) { color: var(--old-paper); }

/* ════════════════════════════════════════════════════════════
   Modal v2 - unified base component
   Used via the <Modal> component in Components/Shared/Modal.razor.
   The old modal wrapper classes (.modal-overlay, .modal-backdrop,
   .modal-content*, .modal-header/body/footer/close, .tdm-modal/-head/-close/-body,
   .history-modal*, .player-profile-modal, .mode-info-modal, .rules-modal,
   .matchmaking-modal, .help-modal/-body, .mini-dialog, .create-lobby-modal)
   were removed in May 2026 (~308 lines). Body/content classes like
   .tdm-hero, .player-profile-info, .join-dialog-* etc. remain and
   are used directly in the <Modal> BodyContent slot.
═══════════════════════════════════════════════════════════════ */
.modal-overlay-v2 {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.72);
  /* backdrop-filter removed: caused GPU repaint on every animation frame
     (perf measurement: presentation delay dominates, blur is unnecessarily expensive) */
  z-index: 1000;
  /* align-items:flex-start + overflow-y:auto + margin:auto on child instead of
     align-items:center. Fixes the iOS Safari portrait problem (fixed + backdrop-
     filter + flex-centering caused the modal to jump to the bottom right) and scrolls
     cleanly for very tall modals without clipping the top. On desktop unchanged,
     centered (margin:auto). */
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  padding: 20px;
  animation: modalV2FadeIn .05s ease-out;
}
@keyframes modalV2FadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.modal-v2 {
  /* Theme-aware modal surface: outside game pages it follows light/dark;
     inside the always-dark islands the token re-pin keeps it dark. */
  background: linear-gradient(to bottom, var(--modal-grad-a) 0%, var(--modal-grad-b) 100%);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  box-shadow: 0 12px 40px var(--shadow-color);
  display: flex;
  flex-direction: column;
  /* overflow:visible (was hidden): the game-switch dropdown in the modal
     header must be able to extend BELOW short modals (few settings).
     Corner clipping is handled by radii on the first/last child instead. */
  overflow: visible;
  width: 100%;
  max-height: calc(100vh - 40px);
  margin: auto;   /* centers vertically when there is space, otherwise the overlay scrolls */
}
.modal-v2 > :first-child { border-top-left-radius: 6px; border-top-right-radius: 6px; }
.modal-v2 > :last-child { border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; }
.modal-v2-sm { max-width: 440px; }
.modal-v2-md { max-width: 580px; }
.modal-v2-lg { max-width: 760px; }
.modal-v2-xl { max-width: 920px; }   /* Lobby settings: room for the filter pill row + chips */

.modal-v2-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border-soft);
  background: var(--surface-2);
  flex-shrink: 0;
  /* Wrap on mobile: when the header content (e.g. title + HeaderContent + close)
     does not fit on one line, elements may wrap to the next line
     instead of overflowing or overlapping. No effect on desktop since
     the content fits comfortably. */
  flex-wrap: wrap;
}
.modal-v2-title {
  font-family: 'Rye', cursive;
  font-size: 17px;
  color: var(--heading);
  letter-spacing: .5px;
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.modal-v2-title-icon {
  font-size: 22px;
  flex-shrink: 0;
  line-height: 1;
  /* Emoji/glyph vertical alignment: emoji glyphs sit visually high in their
     line box (more space below than above), while the Rye title caps
     sit low in the line box (cap height near baseline). flex align-items:center
     aligns the line-box centers, not the visual glyph centers - so without
     correction the icon appears about 2px above the title. translateY corrects
     this. line-height:1 additionally tightens the icon box so the
     nudge remains consistent. */
  transform: translateY(2px);
}
.modal-v2-title-text-wrap {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.modal-v2-title-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.modal-v2-subtitle {
  font-size: 12px;
  color: var(--smoke);
  font-style: italic;
  letter-spacing: 0;
  margin-top: 2px;
}

.modal-v2-close {
  background: transparent;
  border: 1px solid var(--border-soft);
  color: var(--text-dim);
  width: 28px;
  height: 28px;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  font-family: inherit;
  flex-shrink: 0;
  transition: all .15s;
  padding: 0;
}
.modal-v2-close:hover {
  color: var(--heading);
  border-color: var(--gold);
  background: var(--surface-hover);
}

.modal-v2-body {
  padding: 18px 20px;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.modal-v2-footer {
  display: flex;
  gap: 10px;
  padding: 12px 18px;
  border-top: 1px solid var(--border-soft);
  background: var(--surface-2);
  justify-content: flex-end;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.modal-v2-footer-vertical {
  flex-direction: column;
  align-items: stretch;
}
.modal-v2-footer-vertical .btn {
  width: 100%;
}

/* ── Confirm-Switch - info card for the existing lobby ────────── */
.switch-lobby-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  margin: 4px 0 14px;
}
.switch-lobby-code {
  font-family: 'Rye', cursive;
  font-size: 18px;
  letter-spacing: .22em;
  color: var(--heading);
  background: var(--surface-1-strong);
  border: 1px solid var(--gold);
  padding: 5px 12px;
  border-radius: 3px;
  white-space: nowrap;
}
.switch-lobby-meta { min-width: 0; }
.switch-lobby-game { color: var(--parchment); font-weight: 600; }
.switch-lobby-sub  { color: var(--smoke); font-size: 12px; margin-top: 2px; }
.switch-role-chip {
  display: inline-block;
  font-size: 12px;
  letter-spacing: .04em;
  padding: 1px 7px;
  border-radius: 10px;
  margin-left: 2px;
  border: 1px solid rgba(200,146,42,.4);
  color: var(--gold-light);
}
.switch-host-note {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-size: 12.5px;
  color: var(--old-paper);
  background: rgba(139,26,26,.12);
  border-left: 2px solid var(--amber);
  padding: 8px 11px;
  border-radius: 0 3px 3px 0;
}
.switch-host-note span:first-child { flex-shrink: 0; }

/* ─── Hero stage: central game element gets a stage ─────────────────
   Applied to the hero cards of the four games:
   .secret-word-card (Schattenspiel crew, Tabu role reveal),
   .hangman-word-card (Hangman playing),
   .tabu-word-display (Tabu explainer playing).
   Spotlight glow in accent color + corner ornaments (via .stage-corner spans)
   + larger, more dramatic hero typography. */

.secret-word-card,
.hangman-word-card,
.tabu-word-display,
.tabu-reveal-word-card,
.mq-card {
  position: relative;
  container-type: inline-size;
}
.secret-word-card::before,
.hangman-word-card::before,
.tabu-word-display::before,
.tabu-reveal-word-card::before,
.mq-card::before {
  content: '';
  position: absolute;
  inset: -14px;
  background: radial-gradient(ellipse at center 45%, var(--accent) 0%, transparent 60%);
  opacity: .22;
  filter: blur(10px);
  pointer-events: none;
  z-index: 0;
  border-radius: inherit;
}
.secret-word-card > *,
.hangman-word-card > *,
.tabu-word-display > *,
.tabu-reveal-word-card > *,
.mq-card > * { position: relative; z-index: 1; }

.stage-corner {
  position: absolute;
  font-size: 14px;
  color: var(--accent-ink);
  font-family: 'Times New Roman', serif;
  line-height: 1;
  opacity: .8;
  pointer-events: none;
  z-index: 2;
}
.stage-corner-tl { top: 6px; left: 8px; }
.stage-corner-tr { top: 6px; right: 8px; }
.stage-corner-bl { bottom: 6px; left: 8px; }
.stage-corner-br { bottom: 6px; right: 8px; }

/* ─── Western avatar (procedural, deterministic from name hash) ──────
   Used by the Avatar.razor component. Three hat variants, three
   mustache variants, two eye styles - 18 combinations.
   Four sizes Sm/Md/Lg/Xl. */

.avatar {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
  --av-size: 28px;
  --hat-color: #1a0f06;
  width: var(--av-size);
  height: var(--av-size);
  /* Clip to circle - procedural portrait is a clean circle like the
     photo; the hat corners of the square box no longer stick out of the ring. */
  border-radius: 50%;
  overflow: hidden;
}
.avatar-sm { --av-size: 20px; }
.avatar-md { --av-size: 28px; }
.avatar-lg { --av-size: 44px; }
.avatar-xl { --av-size: 60px; }
.avatar-xxl { --av-size: 104px; }

/* Uploaded portrait - sits above the procedural one (same size),
   round & opaque. onerror removes the <img> on 404 - procedural remains. */
.avatar-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid rgba(0,0,0,.5);
  background: #2a1a0c;
  /* Hidden until onload confirms the file exists; on 404
     onerror keeps it hidden - procedural portrait remains visible. */
  visibility: hidden;
}

/* Team logo (rounded square; placeholder shield + optional image on top). */
.team-logo {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  border-radius: 10px;
  overflow: hidden;
  background: linear-gradient(135deg, #5a3a1f, #241608);
  border: 1px solid rgba(200,146,42,.4);
}
.team-logo-sm { width: 40px; height: 40px; font-size: 20px; border-radius: 8px; }
.team-logo-md { width: 64px; height: 64px; font-size: 30px; }
.team-logo-lg { width: 88px; height: 88px; font-size: 44px; }
/* Sits on the fixed dark .team-logo gradient — must stay raw/light in both themes. */
.team-logo-ph  { color: var(--raw-smoke); line-height: 1; }
.team-logo-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; visibility: hidden; }

/* Teams overview (/Teams) */
.teams-toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
.teams-search  { flex: 1; min-width: 180px; max-width: 320px; }
.teams-create-btn { margin-left: auto; }
/* Base .btn is display:block + width:100% + no background. In the
   team UI the buttons should be inline + content-width + more compact. */
.teams-toolbar .btn,
.team-row .btn,
.team-hero-actions .btn,
.team-admin-actions .btn,
.team-back {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: auto; flex: 0 0 auto; padding: 9px 16px; font-size: 13px; letter-spacing: .06em;
}
/* Buttons WITHOUT a color modifier (search, view, change logo, promote, back)
   would otherwise inherit the backgroundless base .btn - white <button> default or purple
   <a> link. Style them explicitly as ghost here; gold/red buttons are excluded. */
.teams-toolbar .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]),
.team-row .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]),
.team-hero-actions .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]),
.team-admin-actions .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]),
.team-member-actions .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]),
.team-back {
  background: transparent;
  border: 1px solid rgba(200,146,42,.32);
  color: var(--old-paper);
  text-decoration: none;
}
.teams-toolbar .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]):hover,
.team-row .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]):hover,
.team-hero-actions .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]):hover,
.team-admin-actions .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]):hover,
.team-member-actions .btn:not([class*="btn-gold"]):not([class*="btn-ghost-red"]):not([class*="btn-red"]):hover,
.team-back:hover {
  border-color: var(--gold); color: var(--gold-light); background: rgba(200,146,42,.05);
}
.teams-list { display: flex; flex-direction: column; }
.team-row { display: flex; align-items: center; gap: 12px; padding: 10px 4px; border-bottom: 1px solid rgba(200,146,42,.1); }
.team-row:last-child { border-bottom: none; }

/* Whole-row click affordance: hover background, focus ring and a chevron that
   nudges right on hover. Shared by team rows, "my team" and friend rows. */
.row-clickable { cursor: pointer; border-radius: 6px; padding-left: 10px; padding-right: 8px; transition: background .12s ease; }
.row-clickable:hover, .row-clickable:focus-visible { background: rgba(200,146,42,.08); outline: none; }
.row-clickable:focus-visible { box-shadow: 0 0 0 1px rgba(200,146,42,.5) inset; }
.row-chevron { margin-left: auto; flex: 0 0 auto; color: var(--smoke); font-size: 18px; line-height: 1; opacity: .45; transition: opacity .12s ease, transform .12s ease, color .12s ease; }
.row-clickable:hover .row-chevron, .row-clickable:focus-visible .row-chevron { opacity: .95; transform: translateX(2px); color: var(--gold-light); }
/* When the row already has an action cluster (which carries margin-left:auto),
   the chevron only needs a small gap, not its own auto-push. */
.row-clickable .friend-row-acts ~ .row-chevron { margin-left: 6px; }
.team-row-main { flex: 1; min-width: 0; }
.team-row-name { color: var(--parchment); font-size: 14px; }
.team-row-desc { color: var(--smoke); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Team page (/Team/{id}) */
.team-hero { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
.team-hero-main { flex: 1; min-width: 200px; }
.team-hero-name { font-size: 22px; margin: 0; text-align: left; }
.team-hero-desc { margin: 4px 0; }
.team-hero-meta { font-size: 12px; }
.team-hero-actions { display: flex; align-items: center; }
.team-hero-note { font-size: 12px; }
.team-sub { color: var(--heading); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; margin: 16px 0 6px; }
.team-sub-first { margin-top: 0; }
.team-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
@media (max-width: 540px) { .team-stats-grid { grid-template-columns: repeat(2, 1fr); } }
.team-stat { background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: 5px; padding: 12px 10px; text-align: center; }
.team-stat-val { display: block; font-family: 'Rye', cursive; color: var(--heading); font-size: 20px; }
.team-stat-mode { font-size: 15px; }
.team-stat-lbl { display: block; color: var(--smoke); font-size: 12px; margin-top: 3px; }
.team-members { display: flex; flex-direction: column; }
.team-member-row { display: flex; align-items: center; gap: 11px; padding: 8px 4px; border-bottom: 1px solid rgba(200,146,42,.08); }
.team-member-row:last-child { border-bottom: none; }
/* Avatar + name as a profile link (the row keeps its own action buttons on the
   right, so the link deliberately covers only the identity part). */
.team-member-link { display: flex; align-items: center; gap: 11px; flex: 1; min-width: 0; color: inherit; text-decoration: none; border-radius: 6px; }
.team-member-link:hover .team-member-name { color: var(--heading); text-decoration: underline; text-underline-offset: 2px; }
.team-member-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.team-member-name { color: var(--parchment); font-size: 13.5px; }
.team-req-meta { font-size: 12px; }
.team-member-actions { display: flex; gap: 7px; flex-shrink: 0; }
.team-role-badge { font-size: 12px; letter-spacing: .03em; padding: 1px 8px; border-radius: 10px; border: 1px solid rgba(200,146,42,.22); color: var(--smoke); }
.team-role-admin { background: rgba(200,146,42,.16); border-color: rgba(200,146,42,.6); color: var(--heading); }
.team-admin-box { border-color: rgba(200,146,42,.5); margin-top: 16px; background: rgba(200,146,42,.05); }
.team-admin-title { font-size: 14px; }
.team-admin-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* Team description inline editor (team admins). */
.team-desc-current { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.team-desc-current .btn { width: auto; flex: 0 0 auto; }
.team-desc-edit { display: flex; flex-direction: column; gap: 8px; }
.team-desc-textarea { width: 100%; resize: vertical; min-height: 60px; }
.team-desc-edit-actions { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
.team-desc-count { margin-right: auto; font-size: 12px; }

.team-back { margin-top: 10px; }
.team-mine { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.team-mine-main { flex: 1; min-width: 0; }
.team-mine-name { color: var(--parchment); font-size: 14px; }

/* Avatar section in the profile (preview + upload/remove) */
.avatar-edit         { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.avatar-ring         { border: 2px solid rgba(200,146,42,.35); border-radius: 50%; padding: 3px; display: inline-flex; flex-shrink: 0; }
.avatar-edit-body    { flex: 1; min-width: 220px; }
.avatar-edit-actions { display: flex; flex-direction: row; flex-wrap: wrap; gap: 8px; margin: 8px 0 6px; }
/* Compact inline buttons (overrides .btn base: full-width/Rye/large). */
.avatar-edit-actions .btn {
  width: auto; padding: 8px 16px; font-size: 12px; letter-spacing: .06em;
  text-align: center; box-sizing: border-box; cursor: pointer;
}
.avatar-file-input   { display: none; }
.avatar-locked-note  {
  display: flex; gap: 8px; align-items: flex-start;
  color: var(--smoke); font-size: 12.5px;
  background: rgba(200,146,42,.07); border: 1px solid rgba(200,146,42,.18);
  border-radius: 4px; padding: 10px 12px; max-width: 460px;
}

/* Crop editor (modal). The stage shows the image (inserted via JS as an
   absolutely positioned <img> + panned/zoomed); ::before darkens everything
   outside the circle, ::after draws the dashed circle border.
   Both pointer-events:none so dragging works. */
.crop-stage {
  position: relative;
  width: 300px; height: 300px;
  margin: 0 auto;
  background: #241608;
  border-radius: 4px;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.crop-stage:active { cursor: grabbing; }
.crop-stage::before {
  content: ''; position: absolute; inset: 0;
  box-shadow: 0 0 0 999px rgba(8,5,2,.62);
  border-radius: 50%;
  pointer-events: none; z-index: 2;
}
.crop-stage::after {
  content: ''; position: absolute; inset: 0;
  border: 1.5px dashed rgba(232,184,75,.7);
  border-radius: 50%;
  pointer-events: none; z-index: 3;
}
.zoom-row { display: flex; align-items: center; gap: 10px; margin: 14px 2px 2px; color: var(--smoke); font-size: 13px; }
.zoom-row input[type=range] { flex: 1; accent-color: var(--gold); }
.crop-hint { display: block; text-align: center; margin-top: 6px; }

/* Avatar at the top of the player profile modal (centered). */
.player-profile-avatar { display: flex; justify-content: center; margin-bottom: 14px; }

/* Face: warm skin tone, slight gradient */
.avatar-face {
  position: absolute;
  left: calc(var(--av-size) * .14);
  top: calc(var(--av-size) * .28);
  width: calc(var(--av-size) * .72);
  height: calc(var(--av-size) * .72);
  border-radius: 50%;
  background: linear-gradient(180deg, #c9a880 0%, #a08560 100%);
  border: 1px solid rgba(0,0,0,.5);
}

/* Hat: rectangular with brim (::before) */
.avatar-hat {
  position: absolute;
  left: calc(var(--av-size) * .04);
  top: 0;
  width: calc(var(--av-size) * .92);
  height: calc(var(--av-size) * .42);
  background: var(--hat-color);
  border: 1px solid rgba(0,0,0,.6);
  border-radius: 2px 2px 50% 50% / 2px 2px 30% 30%;
}
.avatar-hat::before {
  content: '';
  position: absolute;
  left: calc(var(--av-size) * .14);
  bottom: -1px;
  width: calc(var(--av-size) * .64);
  height: calc(var(--av-size) * .11);
  background: inherit;
  border-radius: 2px;
}

/* Hat variants: color */
.avatar-hat-cowboy   { --hat-color: #1f140a; }
.avatar-hat-sheriff  { --hat-color: linear-gradient(180deg, #c9a070, #8a6840); }
.avatar-hat-stranger { --hat-color: #3a2614; }

/* Eyes */
.avatar-eyes {
  position: absolute;
  left: calc(var(--av-size) * .32);
  top: calc(var(--av-size) * .54);
  width: calc(var(--av-size) * .36);
  height: calc(var(--av-size) * .07);
  display: flex;
  justify-content: space-between;
}
.avatar-eyes::before, .avatar-eyes::after {
  content: '';
  background: var(--ink);
  border-radius: 50%;
  width: calc(var(--av-size) * .07);
  height: calc(var(--av-size) * .07);
}
.avatar-eyes-slits::before, .avatar-eyes-slits::after {
  width: calc(var(--av-size) * .11);
  height: calc(var(--av-size) * .04);
  border-radius: 1px;
}

/* Mustache */
.avatar-mustache {
  position: absolute;
  background: var(--ink);
  border-radius: 50%;
}
.avatar-mustache-thick .avatar-mustache {
  left: calc(var(--av-size) * .28);
  top: calc(var(--av-size) * .74);
  width: calc(var(--av-size) * .44);
  height: calc(var(--av-size) * .11);
}
.avatar-mustache-thin .avatar-mustache {
  left: calc(var(--av-size) * .32);
  top: calc(var(--av-size) * .74);
  width: calc(var(--av-size) * .36);
  height: calc(var(--av-size) * .07);
  opacity: .85;
}

/* ─── Wanted poster: sidebar in western profile style ──────────────
   Applied via .stat-box.wanted-poster - score sidebar during Hangman/Tabu/
   Music quiz. Atmospheric swap of the plain box for a
   profile layout (parchment header, double divider, avatar per row). */
.wanted-poster {
  background:
    radial-gradient(ellipse at center top, rgba(201,180,138,.06) 0%, transparent 70%),
    rgba(74,47,20,.32);
  border: 1px solid rgba(201,180,138,.22);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.4);
  padding: 12px 12px 10px;
}
.wanted-poster .wanted-header {
  text-align: center;
  font-family: 'Rye', cursive;
  font-size: 13px;
  color: var(--old-paper);
  letter-spacing: .22em;
  padding-bottom: 4px;
  border-bottom: 2px double rgba(201,180,138,.3);
  margin-bottom: 4px;
}
.wanted-poster .wanted-sub {
  text-align: center;
  font-size: 12px;
  color: var(--smoke);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin-bottom: 10px;
}
.wanted-poster .wanted-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 2px;
  border-bottom: 1px dotted rgba(201,180,138,.18);
}
.wanted-poster .wanted-row:last-child { border-bottom: none; }
.wanted-poster .wanted-row.answered {
  background: rgba(45,122,74,.06);
}
.wanted-poster .wanted-row.active {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-bottom-color: var(--accent-light);
}
.wanted-poster .sidebar-player-name,
.wanted-poster .sidebar-player-name-me {
  flex: 1;
  font-size: 13px;
}
.wanted-poster .sidebar-player-status {
  font-family: 'Rye', cursive;
  color: var(--accent-ink);
  font-size: 14px;
}

/* ─── Animations for transitions and highlights ─────────────
   Stick to CSS-only patterns (no JS) to work cleanly with Blazor
   Server + SignalR. Triggered as soon as classes change on the DOM
   (via re-render). */

/* Active player in turn-list: subtle pulsing */
.turn-row.active {
  animation: activePulse 2.2s ease-in-out infinite;
}
@keyframes activePulse {
  0%, 100% { box-shadow: 0 0 0 rgba(0,0,0,0); border-color: rgba(200,146,42,.28); }
  50%      { box-shadow: 0 0 16px color-mix(in srgb, var(--accent-light) 35%, transparent);
             border-color: var(--accent-light); }
}

/* Wanted-row "answered" pulses once on status change */
.wanted-poster .wanted-row.answered {
  animation: answeredFlash 1.2s ease-out;
}
@keyframes answeredFlash {
  0%   { background: color-mix(in srgb, var(--accent) 25%, transparent); }
  100% { background: rgba(45,122,74,.06); }
}

/* Incoming clue: subtle fade-in + slide */
.turn-row.done .t-clue {
  animation: clueFadeIn .55s ease-out;
}
@keyframes clueFadeIn {
  0%   { opacity: 0; transform: translateX(-6px); }
  60%  { opacity: 1; transform: translateX(0); }
  100% { opacity: 1; transform: translateX(0); }
}

/* Screen transitions: smooth fade when switching between Playing/Break/Voting */
.screen-game,
.screen-break,
.screen-voting,
.screen-result {
  animation: screenFadeIn .35s ease-out;
}
@keyframes screenFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Hero element (secret word/placeholder) glowing entrance */
.stage-corner {
  animation: cornerTwinkle 3.5s ease-in-out infinite;
}
.stage-corner-tr { animation-delay: .4s; }
.stage-corner-bl { animation-delay: .8s; }
.stage-corner-br { animation-delay: 1.2s; }
@keyframes cornerTwinkle {
  0%, 100% { opacity: .8; text-shadow: 0 0 0 transparent; }
  50%      { opacity: 1;
             text-shadow: 0 0 8px color-mix(in srgb, var(--accent-light) 70%, transparent); }
}

/* Voting: selected card gets a subtle "snapped in" effect */
.vote-card.selected {
  animation: votePopIn .3s ease-out;
}
@keyframes votePopIn {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.04); }
  100% { transform: scale(1); }
}

/* Reduced motion: respects the user preference for less animation */
@media (prefers-reduced-motion: reduce) {
  .turn-row.active,
  .turn-row.done .t-clue,
  .wanted-poster .wanted-row.answered,
  .screen-game, .screen-break, .screen-voting, .screen-result,
  .stage-corner, .vote-card.selected,
  .wq-card-enter, .wq-resolving, .wq-commentary, .wq-break-explanation,
  .mq-option.wq-reveal-correct, .wq-cat-curtain {
    animation: none;
  }
}
*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }
html,
body { height: 100%; }

/* Background is on html so body can remain transparent.
   This is necessary because .saloon-bg with z-index: -1 would disappear
   behind the body background if the body had its own background. */
html {
  /* Theme-aware page canvas: subtle vertical depth like the approved mockup.
     Sits on html (not body) so the fixed .saloon-bg (z-index:-1) stays visible. */
  background: radial-gradient(120% 90% at 50% -10%,
    var(--surface-0-a) 0%, var(--surface-0-b) 45%, var(--surface-0-c) 100%);
  background-color: var(--surface-0-c);
  /* The gradient tile is exactly one viewport high (html { height:100% }) — with
     the default repeat it restarts on longer pages as a hard bright band. The
     tile's bottom edge already reaches --surface-0-c, so no-repeat hands over
     seamlessly to the background-color below. */
  background-repeat: no-repeat;
}

body {
  color: var(--parchment);
  /* Inter as body font. 14px is optimal for Inter - previously 15px
     due to Special Elite, which appears visually larger; Inter does not need
     the compensation. Variable definition see :root above. */
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  overflow-x: hidden;
}

/* Form controls inherit body font instead of browser default (otherwise
   platform-specific Arial/Helvetica/system-sans). Makes individual
   font-family declarations on .btn/.inp/etc. unnecessary. */
input, button, select, textarea {
  font-family: inherit;
}

/* <small> keeps its relative sizing but never drops below the app-wide
   12px text minimum (browser default 0.8333em on the 14px body = ~11.7px). */
small { font-size: max(12px, 0.8333em); }

/* Grain overlay */
body::before {
  content: '';
  position: fixed; inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.07'/%3E%3C/svg%3E");
  pointer-events: none; z-index: 998; opacity: .35; mix-blend-mode: overlay;
}

/* ── Saloon background silhouette ──────────────────────────────────────────
   Shadowy saloon scene (bar counter, swing doors, hanging lamps, shelves with
   bottles). Fixed-positioned, behind all app content. Very low
   opacity so the text stays easily readable - the scene feels more like a
   memory or a shadow than a concrete image. */
.saloon-bg {
  position: fixed;
  inset: 0;
  background-image: url("/img/saloon-bg.svg");
  background-size: cover;
  background-position: center bottom;
  background-repeat: no-repeat;
  pointer-events: none;
  /* Negative z-index places the element behind the normal document flow.
     body has no background-color that could cover it (only the
     wood gradient from the html background), so the saloon remains visible. */
  z-index: -1;
  opacity: 0.22;
  /* Gentle fade toward the top so the background is not equally
     present everywhere but atmospherically "clings" toward the bottom. */
  mask-image: linear-gradient(to bottom, transparent 0%, black 35%, black 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 35%, black 100%);
}
/* Light theme: keep the silhouette as a faint sepia print instead of a glow. */
[data-theme="light"] .saloon-bg { opacity: 0.10; mix-blend-mode: multiply; }
[data-theme="light"] .bg-saloon {
  background: radial-gradient(ellipse 90% 55% at 50% 100%, rgba(156, 106, 26, .12) 0%, transparent 65%);
}
/* §8 Teil 2 (dunkler Seiten-Canvas hinter Spiel-Screens) — ABGEBAUT
   (SS-0312 Etappe 2): Spiel-Seiten laufen im Light Theme jetzt auf demselben
   hellen Canvas wie alle anderen Seiten. */

/* ── Screens ── */
.screen-lobby,
.screen-game,
.screen-break,
.screen-voting,
.screen-result {
  flex: 1 0 auto; /* fill the available space in app-main */
  padding: 40px 20px 48px;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  position: relative;
}

.btn-copy {
    font-size: 13px;
    color: var(--gold);
    background: transparent;
    border: 1px solid rgba(200,146,42,.4);
    padding: 6px 14px;
    border-radius: 1px;
    cursor: pointer;
    transition: all .2s;
}

.btn-copy:hover {
    border-color: var(--gold);
    background: rgba(200,146,42,.08);
}

.btn-copy.copied {
    color: var(--green-ok);
    border-color: rgba(45,122,74,.5);
}

.bg-saloon {
  /* Only a gentle glow at the bottom - NO linear-gradient, so the global
     saloon silhouette from .saloon-bg shows through. Used on screens like
     Home, Admin, Game-Break, Lobby-Break - wherever the atmosphere
     should remain visible. When a screen wants to recolor the mood
     (Impostor mode etc.) it uses bg-red/bg-amber/bg-green - those
     still set a full background. */
  background:
    radial-gradient(ellipse 90% 55% at 50% 100%, rgba(74,47,20,.35) 0%, transparent 65%);
}
.bg-red {
  background:
    radial-gradient(ellipse 80% 45% at 50% 55%, rgba(100,14,14,.18) 0%, transparent 70%),
    linear-gradient(to bottom, #060302, #0e0705);
}
.bg-green {
  background:
    radial-gradient(ellipse 80% 45% at 50% 100%, rgba(26,61,43,.28) 0%, transparent 60%),
    linear-gradient(to bottom, #0a0806, #111a0f);
}
.bg-amber {
  background:
    radial-gradient(ellipse 80% 45% at 50% 55%, rgba(100,60,5,.2) 0%, transparent 70%),
    linear-gradient(to bottom, #060402, #0e0905);
}

/* ── Typography ── */
.rye { font-family: 'Rye', cursive; }
.pf { font-family: 'Playfair Display', serif; }
.gold { color: var(--gold-ink); }

.eyebrow {
  font-size: 14px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--smoke); text-align: center; margin-bottom: 14px;
}
.section-label {
  font-size: 14px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--smoke); margin-bottom: 10px;
}
.inline-note {
  font-size: 14px; color: var(--smoke); text-align: center;
  margin-top: 8px; letter-spacing: .08em;
}

/* ── Cards ── */
.card {
  background: linear-gradient(135deg, var(--card-grad-a), var(--card-grad-b));
  border: 1px solid var(--border-soft); border-radius: 2px;
  padding: 24px 28px; position: relative;
  box-shadow: 0 18px 55px var(--shadow-color), inset 0 1px 0 rgba(200,146,42,.09);
}
.card::before,
.card::after {
  content: '✦'; position: absolute; top: 13px;
  color: rgba(200,146,42,.25); font-size: 12px;
}
.card::before { left: 18px; }
.card::after { right: 18px; }

.card-red { border-color: rgba(139,26,26,.35); box-shadow: 0 18px 55px rgba(0,0,0,.65), 0 0 40px rgba(100,14,14,.08); }
.card-red::before,
.card-red::after { color: rgba(139,26,26,.35); }

.card-title {
  font-family: 'Rye', cursive; font-size: 17px; color: var(--heading);
  text-align: center; margin-bottom: 20px; letter-spacing: .09em;
}

/* ── Forms ── */
.lbl {
  font-size: 14px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--smoke); display: block; margin-bottom: 7px;
}
.inp {
  width: 100%; background: var(--input-bg);
  border: 1px solid var(--border-soft); border-radius: 1px;
  color: var(--text-main);
  font-size: 15px; padding: 11px 13px; outline: none; transition: border-color .2s;
}
.inp:focus { border-color: var(--gold); box-shadow: 0 0 14px rgba(200,146,42,.14); }
.inp::placeholder { color: color-mix(in srgb, var(--text-dim) 55%, transparent); }
.inp-lg { font-family: 'Playfair Display', serif; font-size: 22px; font-style: italic; padding: 13px 15px; }
.inp-red { border-color: rgba(139,26,26,.4) !important; }
.fgrp { margin-bottom: 16px; }
select.inp {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' stroke='%23c8922a' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; padding-right: 30px;
}
textarea.inp { resize: vertical; min-height: 100px; font-size: 14px; line-height: 1.6; }

.char-count {
  position: absolute; bottom: 10px; right: 12px;
  font-size: 12px; color: var(--smoke); pointer-events: none;
}
.char-count.warn { color: var(--accent-amber); }
.char-count.over { color: var(--blood-red); }

/* ── Slider ── */

.slider {
  -webkit-appearance: none; appearance: none; width: 100%; height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right,
    var(--gold) 0%,
    var(--gold) var(--val, 50%),
    rgba(200,146,42,.15) var(--val, 50%),
    rgba(200,146,42,.15) 100%);
  outline: none; cursor: pointer;
}
.slider::-webkit-slider-thumb {
  -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%;
  background: var(--gold-light); border: 2px solid var(--amber);
  box-shadow: 0 0 10px rgba(200,146,42,.4); cursor: pointer;
}
.slider::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--gold-light); border: 2px solid var(--amber);
  box-shadow: 0 0 10px rgba(200,146,42,.4); cursor: pointer;
}

/* ── Buttons ── */
.btn {
  display: block; width: 100%; padding: 12px; border-radius: 1px;
  font-family: 'Rye', cursive; font-size: 15px; letter-spacing: .12em;
  text-transform: uppercase; cursor: pointer; transition: all .2s;
  border: none; position: relative; overflow: hidden;
  text-decoration: none;
}
a.btn { text-align: center; }
.btn::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent 30%, rgba(255,255,255,.09) 50%, transparent 70%);
  transform: translateX(-100%); transition: transform .45s;
  pointer-events: none;  /* decorative shimmer must not intercept clicks */
}
.btn:hover::after { transform: translateX(100%); }
.btn:disabled { opacity: .35; cursor: not-allowed; transform: none !important; }

.btn-gold { background: linear-gradient(135deg, var(--amber), var(--gold)); color: var(--shadow); box-shadow: 0 4px 22px rgba(212,98,10,.38); }
.btn-gold:not(:disabled):hover { transform: translateY(-1px); box-shadow: 0 7px 30px rgba(212,98,10,.55); }

/* Amber variant for "cautious action" (activate maintenance, destructive confirms). */
/* Gradient end darkened (75% amber): plain --amber pushed white text to 3.8:1. */
.btn-amber { background: linear-gradient(135deg, var(--blood-red), color-mix(in srgb, var(--amber) 75%, #000)); color: #fff; font-weight: bold; box-shadow: 0 4px 22px rgba(139,26,26,.32); }
.btn-amber:not(:disabled):hover { transform: translateY(-1px); filter: brightness(1.08); }
.btn-amber:disabled { opacity: .55; cursor: not-allowed; }
/* Merged single definition (was duplicated; cascade computed state preserved:
   later definition won background/color, box-shadow comes from the earlier one). */
.btn-red { background: linear-gradient(135deg, #8b1a1a, #5a0e0e); color: #fff; box-shadow: 0 4px 22px rgba(139,26,26,.38); border: 1px solid rgba(220,100,100,.5); padding: 10px 18px; border-radius: 3px; cursor: pointer; font-family: 'Rye', cursive; letter-spacing: .05em; transition: all .15s; }
.btn-red:not(:disabled):hover { transform: translateY(-1px); }
.btn-green { background: linear-gradient(135deg, var(--green-felt), var(--green-ok)); color: var(--parchment); }
.btn-green:not(:disabled):hover { transform: translateY(-1px); }
.btn-ghost { background: transparent; border: 1px solid rgba(200,146,42,.32); color: var(--old-paper); font-size: 15px; letter-spacing: .08em; }
.btn-ghost:hover { border-color: var(--gold); color: var(--heading); background: var(--surface-hover); }
/* Merged single definition (was duplicated; cascade computed state preserved:
   later definition won background/color/box metrics, font-size comes from the earlier one). */
.btn-ghost-red { background: rgba(139,26,26,.08); border: 1px solid rgba(139,26,26,.4); color: var(--danger); font-size: 15px; padding: 10px 18px; border-radius: 3px; cursor: pointer; transition: all .15s; }
.btn-ghost-red:hover { background: rgba(139,26,26,.18); border-color: rgba(220,100,100,.6); color: var(--red-light); }
.abort-btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; padding: 9px; background: transparent;
  border: 1px solid rgba(139,26,26,.3); border-radius: 1px;
  color: rgba(192,53,42,.55);
  font-size: 15px; letter-spacing: .06em; cursor: pointer; transition: all .25s;
}
.abort-btn:hover { border-color: var(--blood-red); color: var(--red-light); background: rgba(139,26,26,.07); }

/* ── Dividers ── */
.div-line { display: flex; align-items: center; gap: 10px; margin: 16px 0; }
.div-line::before,
.div-line::after { content: ''; flex: 1; height: 1px; background: rgba(200,146,42,.18); }
.div-line span { font-size: 12px; letter-spacing: .22em; color: var(--smoke); }
.h-line { height: 1px; background: linear-gradient(to right, transparent, rgba(200,146,42,.35), transparent); margin: 10px 0 18px; }

/* ── Badges ── */
.badge { display: inline-block; padding: 2px 10px; border: 1px solid var(--border-soft); font-size: 12px; letter-spacing: .18em; text-transform: uppercase; color: var(--heading); }

/* ── Lobby code ── */
.lobby-code { font-family: 'Rye', cursive; font-size: 28px; letter-spacing: .35em; color: var(--gold-light); display: inline-block; background: rgba(8,5,2,.9); border: 1px solid var(--gold); padding: 8px 24px; box-shadow: 0 0 26px rgba(200,146,42,.18); }
.code-hint { font-size: 13px; letter-spacing: .2em; color: var(--smoke); text-transform: uppercase; display: block; margin-top: 5px; }

/* ── Streamer mode toggle (eye icon next to lobby code) ─────────────────────────
   Small, subtle, sits directly to the right of the code. When active (code is
   masked), the button gets a gold-filled background + the
   eye-strike effect indicates "hidden". */
.streamer-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin-left: 6px;
  padding: 0;
  background: transparent;
  border: 1px solid rgba(200,146,42,.35);
  border-radius: 50%;
  color: var(--gold);
  font-size: 14px;
  cursor: pointer;
  vertical-align: middle;
  transition: background .15s, border-color .15s;
  position: relative;
}
.streamer-toggle:hover {
  background: rgba(200,146,42,.12);
  border-color: var(--gold);
}
.streamer-toggle.is-on {
  background: rgba(200,146,42,.18);
  border-color: var(--gold);
}
/* Diagonal strike through the eye when active (code hidden).
   Pseudo-element so the emoji itself does not need to be changed. */
.streamer-toggle.is-on::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-top: 2px solid var(--gold);
  transform: rotate(-45deg);
  transform-origin: center;
  pointer-events: none;
}

.btn-eye.visible {
    border-color: rgba(200,146,42,.5);
}

/* ── Player slots ── */

.player-slot.filled { border-color: color-mix(in srgb, var(--border-strong) 71%, transparent); }
.player-slot.empty { opacity: .35; }
.player-slot.disconnected { opacity: .45; border-color: rgba(139,26,26,.25); background: rgba(30,5,5,.4); }

/* (Removed) Here was a second, unused `.avatar` rule
   (32px letter avatar from the dead "Player slots"). It collided with
   the procedural avatar (above) and forced its box to 32px while
   child elements scaled via --av-size - overflow (huge head at Xxl size).
   No `class="avatar"` letter markup in use anymore - removed instead of renamed. */

.p-name { font-size: 17px; color: var(--parchment); }

/* ── Player progress bar ── */
.player-progress { width: 100%; margin: 10px 0 14px; }
.pp-bar { width: 100%; height: 5px; background: var(--surface-2); border-radius: 2px; overflow: hidden; }
.pp-fill { height: 100%; border-radius: 2px; transition: width .4s; }
.pp-fill.ok { background: linear-gradient(to right, var(--green-felt), var(--green-ok)); }
.pp-fill.warn { background: linear-gradient(to right, var(--blood-red), var(--amber)); }
.pp-labels { display: flex; justify-content: space-between; margin-top: 5px; font-size: 14px; color: var(--smoke); }

/* ── Turn list ── */
.turn-list { display: flex; flex-direction: column; gap: 7px; }
.turn-row { display: flex; align-items: center; gap: 10px; padding: 9px 11px; border-radius: 1px; border: 1px solid transparent; }
/* Do NOT dim done rows - the clues in Schattenspiel are the central
   evidence (who said what - who is the impostor). Visual done indication
   runs via clue color (parchment, semi-bold)
   and the disappearance of the "typing..." hint, NOT via opacity. */
.turn-row.done { opacity: 1; }
.turn-row.active { background: var(--surface-2); border-color: color-mix(in srgb, var(--border-strong) 62%, transparent); }
.turn-row.pending { opacity: .35; }
.t-num { width: 22px; height: 22px; border-radius: 50%; border: 1px solid color-mix(in srgb, var(--border-strong) 62%, transparent); display: flex; align-items: center; justify-content: center; font-size: 12px; color: var(--smoke); flex-shrink: 0; }
.turn-row.active .t-num { border-color: var(--accent); color: var(--accent-ink); }
.turn-row.done .t-num { border-color: color-mix(in srgb, var(--accent-light) 50%, transparent); color: var(--accent-ink); }
.t-name { font-size: 16px; color: var(--old-paper); flex: 1; }
.t-clue { font-size: 15px; color: var(--smoke); font-style: italic; }
/* Clue text as the central Schattenspiel evidence: parchment cream (high
   contrast on dark bg), size +1px above default, semi-bold. No
   italics - italics signal "transient" like "typing...", which does not fit
   for entered clues. */
.turn-row.done .t-clue {
  color: var(--parchment);
  font-style: normal;
  font-weight: 600;
  font-size: 16px;
}

/* Uniform clue chip (circled round number + word) - identical throughout Schattenspiel:
   running move list, round break, showdown, scoreboard. */
.clue-chip-row { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.t-clue.clue-chip-row { justify-content: flex-end; font-style: normal; }
.clue-chip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-style: normal; font-weight: 500;
  background: color-mix(in srgb, var(--accent) 22%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent);
  border-radius: 999px; padding: 2px 11px 2px 3px; color: var(--parchment); white-space: nowrap;
}
.clue-chip .cn {
  display: inline-grid; place-items: center; width: 17px; height: 17px; border-radius: 50%; flex: 0 0 auto;
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent); background: var(--well);
  color: var(--accent-ink); font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.clue-chip.placeholder { background: none; border-style: dashed; color: var(--smoke); }

/* ── Timer bars ── */
.timer-bar { width: 100%; height: 4px; background: var(--surface-2); border-radius: 2px; overflow: hidden; }
.timer-fill { height: 100%; background: linear-gradient(to right, var(--green-felt), var(--accent), var(--accent-light)); border-radius: 2px; }
.timer-fill-red { background: linear-gradient(to right, #7a0f0f, var(--blood-red)); }

/* ── Countdown ring ── */
.countdown-ring { position: relative; width: 88px; height: 88px; }
.countdown-ring svg { transform: rotate(-90deg); }
.ring-bg { fill: none; stroke: color-mix(in srgb, var(--border-strong) 27%, transparent); stroke-width: 6; }
.ring-prog { fill: none; stroke: var(--accent-ink); stroke-width: 6; stroke-linecap: round; stroke-dasharray: 213.6; transition: stroke-dashoffset 1s linear; }
.ring-prog.danger { stroke: var(--blood-red); }
.ring-num { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.ring-num span:first-child { font-family: 'Rye', cursive; font-size: 21px; color: var(--accent-ink); line-height: 1; }
.ring-num span:last-child { font-size: 12px; letter-spacing: .12em; color: var(--smoke); }

/* ── Voting cards ── */
.vote-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(155px, 1fr)); gap: 11px; width: 100%; max-width: 660px; }
.vote-card { background: var(--surface-1-strong); border: 1px solid var(--border-soft); border-radius: 2px; padding: 16px 12px; text-align: center; cursor: pointer; transition: all .25s; position: relative; }
.vote-card:hover { border-color: var(--accent-ink); transform: translateY(-2px); }
.vote-card.selected { border-color: var(--blood-red); background: rgba(100,14,14,.12); }
.vote-card.selected::after { content: '✓'; position: absolute; top: 8px; right: 10px; color: var(--blood-red); font-size: 14px; }
.vote-avatar-wrap { display: flex; justify-content: center; margin: 0 auto 9px; }
.vote-name { font-size: 15px; color: var(--parchment); margin-bottom: 3px; }
.vote-hints { font-size: 14px; color: var(--smoke); font-style: italic; line-height: 1.5; }
.vpip { width: 9px; height: 9px; border-radius: 50%; background: color-mix(in srgb, var(--border-strong) 40%, transparent); border: 1px solid color-mix(in srgb, var(--border-strong) 62%, transparent); transition: all .3s; }
.vpip.done { background: var(--accent-ink); box-shadow: 0 0 7px var(--accent); }

/* ── Result ── */
.r-title { font-family: 'Rye', cursive; font-size: clamp(24px, 5vw, 40px); text-align: center; margin-bottom: 6px; }
.r-gold { color: var(--gold-ink); text-shadow: 0 0 38px rgba(200,146,42,.45); }
.r-red { color: var(--blood-red); text-shadow: 0 0 38px rgba(139,26,26,.45); }
.r-amber { color: var(--accent-amber); text-shadow: 0 0 38px rgba(212,98,10,.45); }
.reveal-box { background: var(--surface-1-strong); border: 1px solid color-mix(in srgb, var(--border-strong) 62%, transparent); padding: 16px 24px; width: 100%; text-align: center; border-radius: 2px; }
.reveal-box.red { border-color: rgba(139,26,26,.35); }
.rl { font-size: 12px; letter-spacing: .28em; text-transform: uppercase; color: var(--smoke); margin-bottom: 7px; }
.rv { font-family: 'Rye', cursive; font-size: 24px; color: var(--heading); }
.rv.red { color: var(--blood-red); }
.rsub { font-size: 15px; color: var(--smoke); margin-top: 4px; }

.sb-rank.first { color: var(--heading); }

/* ── Toasts / Alerts ── */
.toast { padding: 10px 14px; border-radius: 1px; font-size: 15px; border-left: 3px solid; display: flex; align-items: center; gap: 8px; margin-bottom: 8px; animation: toastIn .32s ease both; }
@keyframes toastIn { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: none; } }
.toast-info { background: color-mix(in srgb, var(--success) 12%, var(--surface-1-strong)); border-color: var(--success); color: var(--success); }

.toast-abort { background: color-mix(in srgb, var(--danger-strong) 14%, var(--surface-1-strong)); border-color: var(--danger-strong); color: var(--danger); }
[data-theme="light"] .toast-abort { color: var(--danger-strong); }   /* wie .alert-error: --danger faellt auf dem Rosa-Wash unter 4.5 */

/* Achievement unlock toast (finished screen) */
.toast-achievement { background: color-mix(in srgb, var(--gold) 14%, var(--surface-1-strong)); border-color: var(--gold); color: var(--heading); }

.notifications-overlay { position: fixed; top: 16px; right: 16px; z-index: 999; display: flex; flex-direction: column; gap: 8px; max-width: 320px; }
.alert-error { background: color-mix(in srgb, var(--danger-strong) 16%, var(--surface-1)); border: 1px solid color-mix(in srgb, var(--danger-strong) 45%, transparent); border-left: 3px solid var(--danger-strong); color: var(--danger); padding: 9px 12px; border-radius: 1px; font-size: 15px; margin-bottom: 10px; }
/* Light: --danger on the pink-tinted alert bg lands at ~2.5:1 — take the strong tone for text. */
[data-theme="light"] .alert-error { color: var(--danger-strong); }
/* .alert-success duplicate entry removed - was completely overridden by the later
   definition (profile section) including border-left via border shorthand. */

/* OAuth-only note in the delete modal (no password - type-to-confirm instead of re-auth). */
.oauth-delete-note { display: flex; gap: 8px; align-items: flex-start; background: rgba(70,110,160,.1); border: 1px solid rgba(120,150,200,.3); border-radius: 4px; padding: 10px 12px; margin-bottom: 14px; font-size: 12.5px; color: #bcc8e0; line-height: 1.45; }

/* ── Banners ── */
.waiting-banner { font-size: 16px; letter-spacing: .07em; color: var(--smoke); text-align: center; padding: 12px; border: 1px dashed var(--border-soft); border-radius: 1px; margin-bottom: 14px; animation: waitBlink 2s ease-in-out infinite; }
@keyframes waitBlink { 0%,100% { opacity: .5; } 50% { opacity: 1; } }

/* ── Dots ── */
.dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.dot-idle { background: var(--smoke); }
.dot-active { background: var(--gold-ink); box-shadow: 0 0 8px rgba(200,146,42,.6); animation: dotPulse 1.4s ease-in-out infinite; }
.dot-done { background: var(--green-ok); }

.dot-reconnect { background: var(--amber); animation: dotPulse 1s ease-in-out infinite; }
@keyframes dotPulse { 0%,80%,100% { transform: scale(1); opacity: .5; } 40% { transform: scale(1.4); opacity: 1; } }

/* ── Reconnect indicator (top header area) ───────────────────
   Custom #components-reconnect-modal instead of the blocking default modal.
   Online = invisible (user choice: only shown on problems). Blazor switches the
   -show/-failed/-rejected classes; the appearance comes from here. */
#components-reconnect-modal.conn-indicator {
  /* Centered at top IN the sticky header bar (~50px high). top:10px
     centers the 30px pill vertically in the bar; z-index 1200 > header (900),
     so it sits above the (center-clear) header middle. The header actions
     (streamer/volume/profile) are on the right and remain untouched. */
  position: fixed; top: 10px; left: 50%; transform: translateX(-50%); z-index: 1200;
  display: none;                       /* default + components-reconnect-hide: nichts */
  align-items: center; gap: 8px;
  height: 30px; padding: 0 8px 0 11px;
  border-radius: 16px; font-size: 12px; letter-spacing: .02em;
  background: var(--surface-1-strong);
  border: 1px solid color-mix(in srgb, var(--border-strong) 67%, transparent);
  box-shadow: 0 4px 16px rgba(0,0,0,.45);
}
#components-reconnect-modal .conn-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; }
#components-reconnect-modal .conn-label { white-space: nowrap; }
#components-reconnect-modal .conn-label-reconnect,
#components-reconnect-modal .conn-label-lost { display: none; }
#components-reconnect-modal .conn-reload {
  display: none; margin-left: 2px; font-size: 12px; padding: 3px 9px;
  border-radius: 12px; border: 1px solid rgba(200,146,42,.4);
  background: rgba(200,146,42,.16); color: var(--gold-light);
  cursor: pointer; white-space: nowrap; font-family: inherit;
}
#components-reconnect-modal .conn-reload:hover { background: rgba(200,146,42,.28); }

/* Reconnecting (blip) - dot becomes a spinning amber ring, non-blocking */
#components-reconnect-modal.components-reconnect-show { display: inline-flex; }
#components-reconnect-modal.components-reconnect-show .conn-dot {
  background: transparent;
  border: 2px solid rgba(212,98,10,.35); border-top-color: var(--amber);
  animation: spin .7s linear infinite;
}
#components-reconnect-modal.components-reconnect-show .conn-label-reconnect { display: inline; color: var(--amber); }
/* Shared 360-degree rotation (was connspin = mqSpin, exact duplicate). */
@keyframes spin { to { transform: rotate(360deg); } }

/* Loading band for the create-lobby filter data — shown only on a cold cache; the
   matchmaking-dialog prefetch usually warms the bundle before the dialog opens. */
.settings-loading {
  display: flex; align-items: center; gap: 10px; padding: 11px 13px; margin: 8px 0 4px;
  background: rgba(200,146,42,.08); border: 1px solid rgba(200,146,42,.28);
  border-radius: 6px; color: var(--text-dim); font-size: 13px;
}
.settings-loading::before {
  content: ""; flex: none; width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid var(--border-soft); border-top-color: var(--accent);
  animation: spin .7s linear infinite;
}

/* Connection lost / reload required (failed = server gone, rejected = circuit gone) */
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected { display: inline-flex; }
#components-reconnect-modal.components-reconnect-failed .conn-dot,
#components-reconnect-modal.components-reconnect-rejected .conn-dot {
  background: var(--red-light); box-shadow: 0 0 7px rgba(192,53,42,.6);
}
#components-reconnect-modal.components-reconnect-failed .conn-label-lost,
#components-reconnect-modal.components-reconnect-rejected .conn-label-lost { display: inline; color: #e8a59b; }
#components-reconnect-modal.components-reconnect-failed .conn-reload,
#components-reconnect-modal.components-reconnect-rejected .conn-reload { display: inline-block; }

/* ── Shadow figure (Impostor) ── */
.impostor-figure { position: relative; width: 110px; height: 170px; margin: 0 auto; }
.f-hat-crown { position: absolute; top: -14px; left: 50%; transform: translateX(-50%); width: 36px; height: 28px; background: #050202; border-radius: 3px 3px 0 0; }
.f-hat-brim { position: absolute; top: 12px; left: 50%; transform: translateX(-50%); width: 62px; height: 9px; background: #050202; border-radius: 2px; }
.f-head { position: absolute; top: 19px; left: 50%; transform: translateX(-50%); width: 38px; height: 38px; border-radius: 50%; background: #060302; }
.f-head::before,
.f-head::after { content: ''; position: absolute; width: 6px; height: 6px; border-radius: 50%; background: var(--blood-red); top: 36%; box-shadow: 0 0 10px var(--blood-red), 0 0 22px rgba(139,26,26,.7); animation: eyeGlow 2.4s ease-in-out infinite; }
.f-head::before { left: 22%; }
.f-head::after { right: 22%; }
@keyframes eyeGlow { 0%,100% { opacity: 1; } 50% { opacity: .3; } }
.f-body { position: absolute; bottom: 28px; left: 50%; transform: translateX(-50%); width: 52px; height: 86px; background: #060302; border-radius: 26px 26px 8px 8px; }
.f-arm-l { position: absolute; width: 13px; height: 55px; background: #060302; border-radius: 7px; bottom: 36px; left: 13px; transform: rotate(14deg); }
.f-arm-r { position: absolute; width: 13px; height: 55px; background: #060302; border-radius: 7px; bottom: 36px; right: 13px; transform: rotate(-14deg); }
.f-glow { position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); width: 68px; height: 16px; border-radius: 50%; background: radial-gradient(ellipse, rgba(139,26,26,.35) 0%, transparent 70%); }
.fig-pulse { animation: figPulse 3s ease-in-out infinite; }
@keyframes figPulse { 0%,100% { filter: drop-shadow(0 0 8px rgba(139,26,26,.3)); } 50% { filter: drop-shadow(0 0 22px rgba(139,26,26,.6)); } }

/* ── Crewmate figure: sheriff in cowboy outfit, counterpart to the impostor ──
   Same layout format as .impostor-figure (110x170), but lighter colored,
   with a sheriff star on the chest and gold glow instead of blood-red glow.
   Animation `fig-crew-pulse` analogous to `fig-pulse`. */
.crewmate-figure { position: relative; width: 110px; height: 170px; margin: 0 auto; }

/* Hat: warm brown cowboy hat */
.c-hat-crown {
  position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
  width: 38px; height: 26px;
  background: linear-gradient(180deg, #6a4828 0%, #4a3018 100%);
  border: 1px solid #2a1d0e;
  border-radius: 6px 6px 3px 3px;
}
.c-hat-brim {
  position: absolute; top: 11px; left: 50%; transform: translateX(-50%);
  width: 66px; height: 10px;
  background: linear-gradient(180deg, #5a3f1a 0%, #3a2614 100%);
  border: 1px solid #2a1d0e;
  border-radius: 3px;
}
/* Hat band (small bright line below the crown) */
.c-hat-crown::after {
  content: '';
  position: absolute; bottom: -1px; left: 4px; right: 4px;
  height: 3px;
  background: var(--gold);
  opacity: .7;
}

/* Head: warm skin tone (analogous to the avatar) */
.c-head {
  position: absolute; top: 18px; left: 50%; transform: translateX(-50%);
  width: 38px; height: 38px;
  border-radius: 50%;
  background: linear-gradient(180deg, #c9a880 0%, #a08560 100%);
  border: 1px solid #6a4828;
}
.c-head::before,
.c-head::after {
  content: '';
  position: absolute;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--ink);
  top: 42%;
}
.c-head::before { left: 26%; }
.c-head::after  { right: 26%; }

/* Classic western mustache */
.c-mustache {
  position: absolute; top: 46px; left: 50%; transform: translateX(-50%);
  width: 22px; height: 4px;
  background: var(--ink);
  border-radius: 50%;
  z-index: 1;
}

/* Body: vest, slightly lighter than the impostor */
.c-body {
  position: absolute; bottom: 28px; left: 50%; transform: translateX(-50%);
  width: 54px; height: 88px;
  background: linear-gradient(180deg, #5a3f1a 0%, #3a2614 100%);
  border: 1px solid #2a1d0e;
  border-radius: 22px 22px 6px 6px;
}

/* Sheriff star on the chest - the central accent */
.c-star {
  position: absolute; bottom: 64px; left: 50%; transform: translateX(-50%);
  font-size: 22px;
  color: var(--gold-light);
  text-shadow:
    0 0 8px var(--gold-light),
    0 0 16px var(--gold);
  line-height: 1;
  z-index: 2;
  user-select: none;
}

/* Arms */
.c-arm-l, .c-arm-r {
  position: absolute;
  width: 13px; height: 55px;
  background: linear-gradient(180deg, #5a3f1a 0%, #3a2614 100%);
  border: 1px solid #2a1d0e;
  border-radius: 7px;
  bottom: 36px;
}
.c-arm-l { left: 11px;  transform: rotate(8deg); }
.c-arm-r { right: 11px; transform: rotate(-8deg); }

/* Ground glow - gold instead of blood red */
.c-glow {
  position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%);
  width: 72px; height: 16px;
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(232,184,75,.4) 0%, transparent 70%);
}

.fig-crew-pulse { animation: figCrewPulse 3s ease-in-out infinite; }
@keyframes figCrewPulse {
  0%, 100% { filter: drop-shadow(0 0 6px rgba(200,146,42,.25)); }
  50%      { filter: drop-shadow(0 0 18px rgba(232,184,75,.5)); }
}

/* ── Secret word card ── */
.secret-word-card { border-color: var(--border-strong); text-align: center; padding: 20px 24px; }
.secret-word-label { position: absolute; top: -10px; left: 50%; transform: translateX(-50%); background: var(--dark-wood); padding: 0 12px; font-size: 12px; letter-spacing: .25em; color: var(--smoke); white-space: nowrap; }
[data-theme="light"] .secret-word-label { background: #f6ecd6; }   /* Plakette deckt die Kartenkante — im Light heller Grund */

/* ── Layouts ── */
.lobby-header {
  text-align: center;
  margin-bottom: 14px;
  width: 100%;
  max-width: 1000px;
}
.lobby-header-card {
  padding: 14px 22px;
  background: rgba(8,5,2,.55);
  border: 1px solid rgba(200,146,42,.18);
  border-radius: 4px;
}
.lobby-header-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 10px;
  flex-wrap: wrap;
}
/* In the header row .code-hint has more space left/right and
   loses block display so it sits inline next to the code and button. */
.lobby-header-row .code-hint {
  display: inline;
  margin-top: 0;
  max-width: 260px;
  text-align: left;
}
/* Lobby layout: vertically stacked.
   Top (full width): player chips bar
   Below: lobby-main-row with chat large on the left + narrow sidebar on the right */
.lobby-layout { display: flex; flex-direction: column; gap: 16px;
                    width: 100%; max-width: 1000px; }

/* Main area below the player chips: chat large on the left, narrow sidebar on the right.
   DOM order is 'chat-col to sidebar-col', so each gets its column
   automatically via grid - no explicit grid-column needed. */
.lobby-main-row {
  display: grid;
  grid-template-columns: 1fr 270px;
  gap: 16px;
  align-items: start;
}
.lobby-chat-col {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0; /* allows the column to shrink, otherwise chat content pushes the grid */
}
.lobby-sidebar-col {
  display: flex;
  flex-direction: column;
  gap: 13px;
}

/* Kept for any places that still reference .lobby-sidebar
   (e.g. the old responsive rule). No longer actively used. */
.lobby-sidebar { display: flex; flex-direction: column; gap: 13px; }
.lobby-players-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }

.game-layout { display: grid; grid-template-columns: 1fr 240px; gap: 20px; width: 100%; max-width: 820px; align-items: start; }
.game-sidebar { display: flex; flex-direction: column; gap: 12px; }

/* ── Loading & misc ── */
.loading-screen { flex: 1 0 auto; display: flex; align-items: center; justify-content: center; }
.not-found { text-align: center; padding: 60px 20px; }
.not-found h2 { font-size: 28px; color: var(--gold); margin-bottom: 16px; }
.not-found a { color: var(--old-paper); text-decoration: underline; }

/* ── Responsive ── */
@media (max-width: 700px) {
  .lobby-main-row,
.game-layout { grid-template-columns: 1fr; }
  .lobby-sidebar,
.game-sidebar { display: contents; }
}

/* ── Lobby Page ─────────────────────────────────────────────────────────── */
.lobby-loading-text { font-size: 22px; }
.lobby-title { font-family: 'Rye', cursive; font-size: 22px; color: var(--accent); }

.card-players { padding: 20px 22px; }
.card-sidebar { padding: 16px 18px; }

.lobby-section-title { font-family: 'Rye', cursive; font-size: 15px; color: color-mix(in srgb, var(--accent) 30%, var(--text-main)); }
.lobby-player-count { font-size: 15px; color: var(--smoke); }
.card-title-sm { font-family: 'Rye', cursive; font-size: 15px; color: var(--accent-light);
                        letter-spacing: .09em; margin-bottom: 10px; }

.text-danger { color: var(--danger); }
.text-success { color: var(--success); }   /* theme-aware + island re-pin; --green-ok was ~3.6:1 on the dark lobby island */

.settings-info { font-size: 15px; color: var(--smoke); line-height: 2.2; }
.settings-row { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.settings-value { color: var(--accent-ink); text-align: right;
                        min-width: 0; overflow-wrap: anywhere; }
.settings-fixed-note { font-size: 14px; color: rgba(168, 151, 132,.5);
                        margin-top: 8px; font-style: italic; }
.btn-edit { margin-top: 10px; padding: 7px; font-size: 14px; width: 100%; }

/* ── Player chips (lobby) ───────────────────────────────────────────────── */
/* Player overview at the top as a compact chip row instead of a large slot list.
   Avatar + name + badges (host star, admin crown, mod sword, guest diamond,
   own "you" marker). Click opens the profile modal. */
.player-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.player-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(8,5,2,.5);
  border: 1px solid rgba(200,146,42,.18);
  color: var(--parchment);
  padding: 5px 12px 5px 5px;
  border-radius: 22px;
  font-size: 13px;
  cursor: pointer;
  transition: border-color .15s, background .15s, transform .12s;
}
.player-chip:hover {
  border-color: var(--gold);
  background: rgba(8,5,2,.7);
}
.player-chip:active {
  transform: scale(.98);
}
.player-chip.is-host {
  border-color: rgba(200,146,42,.55);
  background: rgba(200,146,42,.08);
}
.player-chip.is-me {
  outline: 1px solid var(--gold-light);
  outline-offset: -1px;
}
.player-chip.is-guest .player-chip-name {
  color: var(--smoke);
  font-style: italic;
}
.player-chip-avatar {
  display: inline-flex;
  flex-shrink: 0;
}
/* The avatar component now provides the round portrait/photo (instead of
   a name initial); the container is just a flex slot now. */
.player-chip-avatar .avatar { --av-size: 26px; }
.player-chip-name {
  font-size: 13px;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.player-chip-badge {
  font-size: 14px;
  line-height: 1;
  margin-left: -2px;
}
/* Verified profile - blue checkmark (Twitter style), next to the name. */
.verified-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #1d9bf0;
  color: #fff;
  font-weight: bold;
  line-height: 1;
  flex-shrink: 0;
  vertical-align: middle;
  box-shadow: 0 0 0 1px rgba(0,0,0,.25);
}
.verified-check.vc-sm { width: 15px; height: 15px; font-size: 9px; }
.verified-check.vc-md { width: 17px; height: 17px; font-size: 10px; }
.verified-check.vc-lg { width: 21px; height: 21px; font-size: 12px; }
.player-chip-you {
  background: rgba(45,122,74,.2);
  color: var(--green-ok);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .1em;
  padding: 1px 6px;
  border-radius: 10px;
  margin-left: 2px;
}
.player-chip-empty {
  display: inline-flex;
  align-items: center;
  padding: 5px 14px;
  border: 1px dashed rgba(168, 151, 132,.3);
  color: var(--smoke);
  font-size: 12px;
  border-radius: 22px;
  font-style: italic;
}

/* Away player - chip grayed out, strikethrough background,
   but remains clickable (profile modal can still be opened). */
.player-chip.is-away {
  opacity: 0.5;
  filter: grayscale(0.6);
}
.player-chip.is-away .player-chip-name {
  text-decoration: line-through;
  text-decoration-color: rgba(168, 151, 132,.4);
  text-decoration-thickness: 1px;
}

/* ── Home Page ───────────────────────────────────────────────────────────── */
.card-home { width: 100%; max-width: 440px; }
.inp-code { letter-spacing: .2em; text-transform: uppercase; }

/* ── Game Page – Playing ─────────────────────────────────────────────────── */
.impostor-title { font-family: 'Rye', cursive; font-size: 28px; color: var(--blood-red); margin-bottom: 6px; }
.impostor-subtitle { font-size: 15px; color: var(--smoke); margin-bottom: 20px; }
.secret-word-card-wrap { margin-bottom: 14px; text-align: center; }
.secret-word-text {
  font-family: 'Rye', cursive;
  /* Scales with the actual card width (cqi = container query inline).
     7cqi instead of 9cqi - Rye has wide glyphs, long compound words
     like "VORHÄNGESCHLOSS" (15 chars) would otherwise overflow the card and break
     mid-word. Plus dynamic letter-spacing adjustment in the Razor code. */
  font-size: clamp(20px, 7cqi, 44px);
  color: var(--parchment);
  letter-spacing: .03em;
  line-height: 1.05;
  /* break-word only as a last resort if the word still does not fit through ALL these
     measures. Does not apply in normal cases. */
  word-break: break-word;
  text-shadow:
    0 0 24px var(--accent-light),
    0 0 48px var(--accent),
    0 2px 0 var(--shadow);
}
.secret-word-hint { font-size: 15px; color: var(--smoke); margin-top: 5px; }
.progress-wrap { margin-bottom: 14px; }
.progress-header { display: flex; justify-content: space-between; font-size: 15px; color: var(--smoke); margin-bottom: 5px; }
/* SS-0312: the secret-word glow is a dark-canvas effect — light gets crisp ink
   without the halo (see the light-overrides section at the end of the file). */
.card-turn-list { padding: 18px 20px; margin-bottom: 12px; }
.turn-list-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.turn-list-title { font-family: 'Rye', cursive; font-size: 15px; color: var(--gold-ink); }
.text-amber { color: var(--accent-amber); }
.text-smoke { color: var(--smoke); }
.text-gold { color: var(--gold-ink); }
.text-gold-light { color: var(--heading); }
.text-blood-red { color: var(--blood-red); }

.typing-anim { animation: waitBlink 1s ease-in-out infinite; }
.card-clue-input { padding: 22px 24px; border-color: var(--border-strong); }
.clue-title { font-family: 'Rye', cursive; font-size: 16px; color: var(--gold-ink); margin-bottom: 5px; }
.clue-title-red { font-family: 'Rye', cursive; font-size: 16px; color: var(--blood-red); margin-bottom: 5px; }
.clue-hint { font-size: 15px; color: var(--smoke); margin-bottom: 12px; }
.clue-input-wrap { position: relative; margin-bottom: 12px; }

.sidebar-player-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; }
.sidebar-player-name { font-size: 15px; color: var(--old-paper); flex: 1; }
.sidebar-player-name-me { font-size: 15px; color: var(--accent-ink); flex: 1; }
.sidebar-player-status { font-size: 15px; color: var(--smoke); }
.round-label { font-size: 15px; color: var(--smoke); margin-bottom: 2px; }
.round-number { font-family: 'Rye', cursive; font-size: 30px; color: var(--heading); }
.round-total { font-size: 16px; color: var(--smoke); }
.host-section { border-top: 1px solid var(--border-faint); padding-top: 10px; }
.host-only-label { font-size: 13px; color: rgba(200,146,42,.25); text-align: center;
                      text-transform: uppercase; margin-bottom: 7px; }

/* ── Game Page – Break ───────────────────────────────────────────────────── */
.screen-break-center { text-align: center; }
.impostor-figure-sm { width: 90px; height: 138px; margin-bottom: 16px; }
.showdown-title { font-family: 'Rye', cursive; font-size: 30px; color: var(--blood-red);
                        text-shadow: 0 0 28px rgba(139,26,26,.5); margin-bottom: 8px; }
.break-subtitle { font-size: 15px; color: var(--smoke); margin-bottom: 20px; }
.break-emoji { font-size: 46px; margin-bottom: 14px; }
.break-title { font-family: 'Rye', cursive; font-size: 26px; color: var(--accent-ink); margin-bottom: 8px; }
.card-break { max-width: 400px; width: 100%; margin: 0 auto; }
.section-label-mb { margin-bottom: 8px; }
.break-clue-row { display: flex; justify-content: space-between; padding: 6px 0;
                        border-bottom: 1px solid var(--border-faint); font-size: 15px; }
.countdown-label { text-align: center; font-size: 15px; color: var(--smoke); margin-top: 14px; }
.countdown-number { font-family: 'Rye', cursive; font-size: 36px; color: var(--accent-ink);
                        text-align: center; margin-top: 4px; }
.countdown-number-red { font-family: 'Rye', cursive; font-size: 36px; color: var(--red-light);
                        text-align: center; margin-top: 4px; }
.timer-bar-mt10 { margin-top: 10px; }

/* ── Game Page – Voting ──────────────────────────────────────────────────── */
.voting-header { text-align: center; margin-bottom: 18px; }
.voting-title { font-family: 'Rye', cursive; font-size: 24px; color: var(--blood-red); }
.voting-subtitle { font-size: 15px; color: var(--smoke); margin-top: 5px; }
.timer-ring-wrap { display: flex; align-items: center; justify-content: center;
                          gap: 28px; margin-bottom: 18px; flex-wrap: wrap; }
.vpip-row { display: flex; gap: 7px; align-items: center; margin-bottom: 8px; }
.impostor-guess-panel { display: flex; align-items: flex-start; justify-content: center;
                          gap: 20px; width: 100%; max-width: 700px; flex-wrap: wrap; }
.card-clues-sidebar { padding: 14px 18px; max-width: 220px; }
.clue-item { font-size: 15px; margin-bottom: 5px; }
.guess-panel-right { flex: 1; max-width: 370px; }
.card-guess { padding: 22px 26px; }
.guess-title { font-family: 'Rye', cursive; font-size: 16px; color: var(--blood-red); margin-bottom: 5px; }
.guess-hint { font-size: 15px; color: var(--smoke); margin-bottom: 14px; }
.btn-vote { max-width: 260px; margin-top: 14px; }
.host-abort-section { margin-top: 20px; border-top: 1px solid rgba(139,26,26,.15);
                          padding-top: 12px; text-align: center; }
.abort-btn-centered { max-width: 260px; margin: 0 auto; }

/* ── Game Page – Result ──────────────────────────────────────────────────── */
.impostor-figure-result { width: 110px; height: 168px; position: relative; margin-bottom: 14px; }
.result-header { text-align: center; margin-bottom: 8px; }
.h-line-result { width: 100%; max-width: 480px; margin: 12px auto; }
.reveal-stack { display: flex; flex-direction: column; gap: 10px; align-items: center;
                          width: 100%; max-width: 460px; margin-bottom: 14px; }

/* ── Schattenspiel result unified card ──────────────────────────────
   A central card with two sections: reveal pair (secret word | impostor)
   above + history grid (clues | votes) below. Previously there were 4
   standalone bordered boxes vertically - looked stacked with unequal
   content heights. Mobile (< 720px): both rows collapse to a column. */
.ss-result-card {
  width: 100%;
  max-width: 720px;
  margin: 0 auto 14px;
  padding: 22px 28px;
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid var(--board-border);
  border-radius: 6px;
  box-shadow: var(--board-shadow);
  position: relative;
}
.ss-result-card::before,
.ss-result-card::after {
  content: '✦'; position: absolute; top: 10px;
  color: var(--border-strong); font-size: 12px;
}
.ss-result-card::before { left: 16px; }
.ss-result-card::after  { right: 16px; }

/* Reveal row: word | vertical line | impostor */
.ss-result-reveal {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 18px;
  align-items: center;
  text-align: center;
}
.ss-result-reveal-col {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.ss-result-reveal-label {
  font-size: 12px;
  color: var(--smoke);
  text-transform: uppercase;
  letter-spacing: .12em;
}
.ss-result-reveal-value {
  font-family: 'Rye', cursive;
  font-size: 24px;
  color: var(--heading);
  line-height: 1.1;
  word-break: break-word;
}
.ss-result-reveal-value.red { color: var(--blood-red); }
.ss-result-reveal-sub {
  font-size: 12px;
  color: var(--smoke);
  margin-top: 2px;
}
.ss-result-reveal-divider {
  width: 1px;
  align-self: stretch;
  background: var(--border-soft);
}

/* Horizontal section divider between reveal and history */
.ss-result-section-divider {
  height: 1px;
  background: var(--border-faint);
  margin: 18px 0 16px;
}

/* History: clues | votes */
.ss-result-history {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
}
.ss-result-history-col { min-width: 0; }
.ss-result-section-title {
  font-family: 'Rye', cursive;
  font-size: 13px;
  color: var(--gold-ink);
  letter-spacing: .1em;
  margin-bottom: 10px;
  text-align: center;
  font-weight: normal;
}

.ss-result-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border-faint);
  font-size: 13px;
}
.ss-result-row:last-child { border-bottom: none; }
.ss-result-name {
  color: var(--old-paper);
  flex: 0 0 auto;
  min-width: 0;
}
.ss-result-name.imp {
  color: var(--blood-red);
  font-weight: 600;
}
.ss-result-arrow { color: var(--smoke); flex-shrink: 0; }
.ss-result-val {
  flex: 1;
  text-align: right;
  color: var(--gold-ink);
  min-width: 0;
  word-break: break-word;
}
.ss-result-val.hit { color: var(--green-ok); }

/* Mobile: both grids collapse to a column */
@media (max-width: 640px) {
  .ss-result-card { padding: 18px 16px; }
  .ss-result-reveal {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .ss-result-reveal-divider {
    width: 60%;
    height: 1px;
    justify-self: center;
  }
  .ss-result-history {
    grid-template-columns: 1fr;
    gap: 20px;
  }
}

.result-actions { display: flex; gap: 10px; max-width: 460px; width: 100%; }
.btn-flex1 { flex: 1; }
.btn-flex2 { flex: 2; }

/* ── Draw / Unentschieden ────────────────────────────────────────────────── */

/* ── Voting: own card ────────────────────────────────────────────────── */
.vote-card-self {
  opacity: .55;
  cursor: not-allowed;
  border-style: dashed;
}
.vote-card-self:hover {
  border-color: var(--border-soft);
  transform: none;
}

/* ── Impostor Mission Box ────────────────────────────────────────────────── */
.impostor-mission {
  width: 100%;
  max-width: 460px;
  padding: 18px 22px;
  margin-bottom: 18px;
}
.impostor-mission-title {
  font-family: 'Rye', cursive;
  font-size: 15px;
  color: var(--blood-red);
  text-align: center;
  margin-bottom: 10px;
  letter-spacing: .08em;
}
.impostor-mission-text {
  font-size: 14px;
  color: var(--smoke);
  line-height: 1.7;
  border-left: 2px solid rgba(139,26,26,.4);
  padding-left: 13px;
}
.impostor-mission-text strong { color: var(--parchment); }

/* Impostor game view (screen-game bg-red) more compact - previously did not fit without
   scrolling on one screen: figure scaled down (layout height compensated via negative margin),
   title/subtitle/mission box tighter. */
.screen-game.bg-red .impostor-figure { transform: scale(.6); transform-origin: top center; margin: 0 auto -62px; }
.screen-game.bg-red .impostor-title { font-size: 21px; margin-bottom: 2px; }
.screen-game.bg-red .impostor-subtitle { font-size: 13px; margin-bottom: 10px; }
.screen-game.bg-red .impostor-mission { padding: 11px 16px; margin-bottom: 10px; max-width: 560px; }
.screen-game.bg-red .impostor-mission-title { font-size: 13px; margin-bottom: 5px; }
.screen-game.bg-red .impostor-mission-text { font-size: 13px; line-height: 1.45; }
.screen-game.bg-red .impostor-category { padding: 8px 16px; margin-bottom: 10px; }

/* ── End screen game history ─────────────────────────────────────────────── */
.history-card {
  width: 100%;
  max-width: 480px;
  padding: 16px 20px;
  margin-bottom: 14px;
}
.history-title {
  font-family: 'Rye', cursive;
  font-size: 14px;
  color: var(--gold-ink);
  letter-spacing: .08em;
  margin-bottom: 12px;
  text-align: center;
}
.history-clue-row,
.history-vote-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--border-faint);
  font-size: 14px;
}
.history-clue-row:last-child,
.history-vote-row:last-child {
  border-bottom: none;
}
.history-name { color: var(--old-paper); flex: 0 0 130px; }
.history-name-impostor { color: var(--blood-red); flex: 0 0 130px; font-weight: bold; }
.history-clues { color: var(--gold-ink); flex: 1; text-align: right; }
.history-arrow { color: var(--smoke); }
.history-vote-hit { color: var(--green-ok); flex: 1; text-align: right; }
.history-vote-miss { color: var(--smoke);   flex: 1; text-align: right; }

/* ── Too Few Players Screen ──────────────────────────────────────────────── */
.toofew-card { max-width: 420px; width: 100%; text-align: center; padding: 28px 32px; }
.toofew-text { font-size: 14px; color: var(--smoke); }

/* ── Clue-Timer in Input Field ───────────────────────────────────────────── */
.clue-timer-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 14px; margin-bottom: 6px;
  font-size: 13px;
}
.clue-timer-label { color: var(--smoke); letter-spacing: .08em; text-transform: uppercase; }
.clue-timer-num { color: var(--accent-ink); font-family: 'Rye', cursive; font-size: 16px; }
.clue-timer-num.danger { color: var(--blood-red); }

/* ── Home Page ───────────────────────────────────────────────────────────── */
/* The former hero/mode-cards/segmented styles are gone — Home now uses the
   sitewide poster grid (.pg-poster-grid) + spotlight banner (.pg-spotlight)
   inside the PageFrame shell. Only the pieces still referenced remain. */
.home-alert {
  max-width: 540px;
  width: 100%;
  margin: 0 auto 24px;
}
/* "Off" badge for disabled modes (admins only) — used on the poster tiles. */
.home-mode-off-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--danger);
  background: rgba(163,50,74,.18);
  border: 1px solid rgba(163,50,74,.5);
  border-radius: 3px;
  padding: 1px 6px;
}
.mode-switch-off {
  margin-left: auto;
  font-size: 12px;
  color: #e88;
  border: 1px solid rgba(163,50,74,.5);
  border-radius: 3px;
  padding: 0 5px;
}

/* ── JoinLobbyDialog (Modal Specifics) ───────────────────────────────────── */
.join-dialog {
  max-width: 540px;
}
.join-dialog-loading {
  text-align: center;
  padding: 30px;
  color: var(--smoke);
  font-style: italic;
}
.join-dialog-info {
  margin-bottom: 18px;
}
.join-dialog-mode {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 14px;
  background: rgba(200,146,42,.06);
  border: 1px solid rgba(200,146,42,.22);
  border-radius: 4px;
  margin-bottom: 12px;
}
.join-dialog-mode-icon {
  font-size: 32px;
  line-height: 1;
  flex-shrink: 0;
}
.join-dialog-mode-name {
  font-family: 'Rye', cursive;
  font-size: 17px;
  color: var(--gold);
  margin: 0 0 6px 0;
}
.join-dialog-mode-desc {
  color: var(--parchment);
  font-size: 13px;
  margin: 0;
  line-height: 1.5;
}
.join-dialog-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  font-size: 14px;
  color: var(--smoke);
  margin-bottom: 12px;
}
.join-dialog-meta strong {
  color: var(--gold-light);
}
/* "You are joining the lobby as X." – a little breathing room below,
   so the join button does not stick directly to the text. */
.join-dialog-as-user {
  color: var(--smoke);
  font-size: 14px;
  margin: 0 0 14px 0;
}
.join-dialog-as-user strong {
  color: var(--gold-light);
}
.join-dialog-section {
  padding: 14px 0;
}
.join-dialog-section-title {
  font-size: 14px;
  color: var(--gold-light);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0 0 10px 0;
}
.join-dialog-auth-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.join-dialog-account-required {
  margin-bottom: 14px;
}

/* compact OAuth button list in the join dialog (variant B from
   `docs/mockups/join-lobby-dialog-refactor.html`). Buttons stack vertically
   with a small gap; below them two subtle footer text links for email login
   or register, instead of the previously dominant wide buttons. */
.join-dialog-oauth {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.join-dialog-footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px 18px;
  margin-top: 10px;
  font-size: 12px;
}
.join-dialog-footer-links a {
  color: var(--gold);
  text-decoration: none;
}
.join-dialog-footer-links a:hover {
  color: var(--gold-light);
}

/* ── Join page (/Join/{code}) — auto-join interstitial + waiting room ─────── */
.join-switch-note { font-size: 12.5px; color: var(--smoke); margin: 6px 0 2px; }

.ji-auto, .ji-wait {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 9px; padding: 22px 14px; margin-top: 4px;
  background: rgba(8,5,2,.4);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.ji-h {
  font-family: 'Rye', cursive; font-size: 18px; color: var(--accent-light);
  display: flex; align-items: center; gap: 10px;
}
.ji-s { font-size: 13px; color: var(--parchment); max-width: 460px; line-height: 1.55; }
.ji-f { font-size: 12.5px; color: var(--smoke); margin-top: 2px; }

.ji-spin {
  width: 34px; height: 34px;
  border: 3px solid var(--border); border-top-color: var(--accent-light);
  border-radius: 50%; animation: jiSpin .9s linear infinite;
}
@keyframes jiSpin { to { transform: rotate(360deg); } }

.ji-pulse {
  width: 11px; height: 11px; border-radius: 50%; flex: none;
  background: var(--accent-light); animation: jiPulse 1.6s infinite;
}
.ji-pulse-sm { width: 9px; height: 9px; }
@keyframes jiPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-light) 65%, transparent); }
  70%  { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ── App Shell: Header + Main + Footer Layout ───────────────────────────── */
.app-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.app-main {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  /* NO padding-bottom here! Otherwise a strip without screen background appears.
     Footer spacing is handled inside each .screen-* itself (see above). */
}

/* In-app maximize: the BOX fills the area between top-nav and bottom-nav
   (no zoom — real space). Height is passed down via flex: screen → frame →
   lobby-layout → player-/stage-card → stage; same for the game via card-board. */
/* Mobile strategy: maximize is a DESKTOP feature. The button is hidden at ≤760px
   AND the maximized CSS only kicks in from 761px up — so mobile always keeps
   the responsive normal layout, even when the state (localStorage) is set. */
@media (min-width: 761px) {
  /* Outer screens (carrying .lobby-redesign) fill app-main. IMPORTANT: only these, NOT
     the nested Playing-.screen-game (HangmanPlaying/SeeschlachtPlacement render
     their own .screen-game WITHOUT .lobby-redesign) — otherwise their content loses
     centering (→ left-aligned). */
  /* Frame scroll lock (game/lobby pages): app height = exactly viewport, app-main shrinkable.
     This prevents the page/frame from growing in maximized mode → no page scroll.
     Tall game content scrolls INSIDE the nested screen instead (see below).
     Scoped via :has() deliberately to game/lobby pages only — otherwise the remembered
     maximize state (localStorage) would also height-lock admin/account pages (sticky header
     would scroll away). Other pages keep the normal scrollable app-shell (min-height:100vh). */
  body.ss-maximized:has(.screen-game.lobby-redesign, .screen-lobby) .app-shell { height: 100vh; min-height: 0; }
  body.ss-maximized:has(.screen-game.lobby-redesign, .screen-lobby) .app-main { flex: 1 1 auto; min-height: 0; }

  body.ss-maximized .screen-lobby,
  body.ss-maximized .screen-game.lobby-redesign {
    flex: 1 1 auto; min-height: 0; align-items: stretch; justify-content: flex-start;
    padding: 6px 8px;
  }
  /* Lobby shows the FIXED app footer (imprint bar) → reserve space at the bottom,
     otherwise the action bar (START GAME) disappears behind it. In the game the
     footer is hidden, so no reserve needed there.
     Reserve = footer height (~49px on desktop) + the same 6px gap the top edge has
     (padding: 6px 8px above) → the frame sits symmetrically between header and footer.
     Was 50px, which left only ~1px below the frame after the footer grew. */
  body.ss-maximized .screen-lobby { padding-bottom: 55px; }
  body.ss-maximized .lobby-frame {
    max-width: none; width: 100%; flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column;
  }
  body.ss-maximized .lobby-header { max-width: none; width: 100%; }
  /* Lobby: pass height through to the stage/arena. */
  body.ss-maximized .lobby-layout {
    max-width: none; width: 100%; flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column;
  }
  body.ss-maximized .lobby-arena { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  /* Stage AND table fill the arena height equally (seats are %-positioned → scale with it). */
  body.ss-maximized .lobby-stage-theatre,
  body.ss-maximized .lobby-table .felt { flex: 1 1 auto; height: auto; min-height: 0; }
  /* Game: the card-board fills width + height. */
  body.ss-maximized .screen-game.lobby-redesign > .card-board {
    max-width: none; width: 100%; flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column;
  }
  /* The nested game screen (Playing/Break/Voting/Result) fills the card-board
     and CENTERS its content itself (its own align/justify:center is kept). */
  /* Inner scroll as a general catch-all: if a game screen does not fill the height,
     it stays centered; if its content is too tall (long final scores/recaps/lists), IT
     scrolls INTERNALLY — the card-board frame + the docked footer stay fixed. `safe center`
     keeps the overflow reachable at the top (otherwise centered flex content clips at the top). */
  body.ss-maximized .card-board > .screen-game,
  body.ss-maximized .card-board > .screen-break,
  body.ss-maximized .card-board > .screen-voting,
  body.ss-maximized .card-board > .screen-result {
    flex: 1 1 auto; min-height: 0; overflow-y: auto; justify-content: safe center;
  }

  /* ── Content uses the maximized area (no zoom) ──────────────────────────────
     Inner width caps are raised; flexible content (memory grid with
     1fr, quiz answers) grows along with them. Fixed sizes (cards, naval battle board)
     are selectively enlarged. */
  /* Word/Quiz/Memory + Shadow Game: layout cap (820px) raised → main column (1fr) grows. */
  body.ss-maximized .card-board .hangman-layout,
  body.ss-maximized .card-board .game-layout { max-width: 1280px; }

  /* Memory: height is passed down via flex to the board, so the fit area has a
     REAL bounded height (no more guessed vh constants). shadowSaloon.fitMemory
     measures .memory-fit and sets --mem-cell = min(width-fit, height-fit). SAME grid
     as normal (fixed 6 columns) — just scaled larger, square, centered, no scrolling. */
  body.ss-maximized .card-board > .screen-game.mode-memory { display: flex; flex-direction: column; }
  body.ss-maximized .mode-memory > .hangman-layout {
    flex: 1 1 auto; min-height: 0; max-width: none;
    /* minmax(0, 1fr) (not the default 1fr, whose implicit min-width:auto lets the board push
       the column wider than the viewport → horizontal scrollbar + a resize-direction feedback
       loop, because fitMemory then measures the inflated width). Now the column always reports
       the TRUE available width, so fitMemory sizes the board to fit — no overflow, no hysteresis. */
    grid-template-columns: minmax(0, 1fr) 220px;
    grid-template-rows: minmax(0, 1fr); align-items: stretch;
  }
  body.ss-maximized .mode-memory .hangman-main { min-height: 0; min-width: 0; }
  body.ss-maximized .mode-memory .memory-board-card { flex: 1 1 auto; min-height: 0; }
  /* Felt HUGS the board (width/height = content) and centers itself in the card's free
     space via margin:auto — instead of spanning the full width and leaving the small board
     stranded in a sea of green. shadowSaloon.fitMemory no longer measures this (shrinking)
     box; it measures the stable card and sizes --mem-cell to fit, so there's no circular
     width dependency. max-*: 100% + the fit-to-height cell keep it inside the card. */
  body.ss-maximized .mode-memory .memory-felt {
    margin: auto; width: fit-content; max-width: 100%; max-height: 100%;
    min-height: 0; display: flex; flex-direction: column;
  }
  body.ss-maximized .mode-memory .memory-fit {
    display: block; min-height: 0;
  }
  body.ss-maximized .mode-memory .memory-board {
    gap: 14px;
    grid-template-columns: repeat(var(--mem-cols, 6), var(--mem-cell, 92px));
    grid-auto-rows: var(--mem-cell, 92px);
    justify-content: center; align-content: center;
  }
  body.ss-maximized .mode-memory .mem-card { width: var(--mem-cell, 92px); height: var(--mem-cell, 92px); aspect-ratio: auto; }
  /* Music quiz/knowledge quiz: let the question card grow + scale question/answers.
     Layout stays the same (no wrapping of the 2x2 answers) — just larger/more readable via clamp,
     answer buttons also get taller (vh) and use the maximized height. */
  body.ss-maximized .card-board .mq-card { max-width: none; }
  body.ss-maximized .wq-question { font-size: clamp(21px, 2.2vw, 34px); }
  body.ss-maximized .mq-question-mark { font-size: clamp(62px, 8vh, 110px); }
  body.ss-maximized .mq-option {
    font-size: clamp(14px, 1.25vw, 19px);
    padding: clamp(14px, 1.3vw, 20px) clamp(16px, 1.5vw, 26px);
    min-height: clamp(56px, 7vh, 92px);
  }
  body.ss-maximized .mq-option-letter {
    width: clamp(30px, 2.2vw, 40px); height: clamp(30px, 2.2vw, 40px);
    font-size: clamp(13px, 1vw, 17px);
  }
  /* Word games: hangman placeholder + secret word (Tabu) already scale via cqi with the
     card width — in maximized mode just raise the cap. The dynamic letter-spacing
     from Razor code further slows down long compound words (no wrapping). */
  body.ss-maximized .hangman-placeholder { font-size: clamp(24px, 8cqi, 60px); }
  body.ss-maximized .secret-word-text { font-size: clamp(20px, 7cqi, 56px); }
  /* Card games: override cap (inline 880/1080) + larger cards. */
  body.ss-maximized .card-board .durak-board { max-width: 1280px !important; }
  body.ss-maximized .durak-card { --card-w: 108px; --card-h: 152px; }

  /* Ultimate TicTacToe: the square board fills the maximized height; the head (legend +
     status) sits above it in the SAME width. Both are sized to the smaller of the area's
     width / (height − head) via container-query units → no page scroll (overflow hidden). */
  body.ss-maximized .card-board > .screen-game.mode-uttt { overflow: hidden; }
  body.ss-maximized .mode-uttt > .uttt-board-area { flex: 1 1 auto; min-height: 0; container-type: size; }
  body.ss-maximized .mode-uttt .uttt-frame { width: min(100cqw, calc(100cqh - 44px)); max-width: none; }
  body.ss-maximized .mode-uttt .uttt-head { min-height: 0; height: 26px; flex-wrap: nowrap; }
  body.ss-maximized .mode-uttt .uttt-status { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Schnellschuss reuses the durak-board shell with its own .ssk-card — bump it (a bit larger
     than Durak, the table is sparser). The cinema card stays pinned via !important. */
  body.ss-maximized .ssk-card { --card-w: 124px; --card-h: 174px; }
  /* Height chain so the felt oval fills the maximized area (board → felt-wrap → felt grow). */
  body.ss-maximized .card-board > .screen-game.mode-schnellschuss { display: flex; flex-direction: column; }
  body.ss-maximized .mode-schnellschuss > .durak-board { flex: 1 1 auto; min-height: 0; }
  /* Offiziersskat (2-player Skat): height chain so the layout board has a REAL bounded
     height — shadowSaloon.fitOsk measures it and bumps ONLY --osk-w/--osk-h (the 2×4
     stack grid never changes). The classic 3-player Skat table is untouched (:has). */
  body.ss-maximized .card-board > .screen-game.mode-skat:has(.osk-board) { display: flex; flex-direction: column; overflow-y: hidden; }
  body.ss-maximized .screen-game.mode-skat > .osk-board { flex: 1 1 auto; min-height: 0; }
  /* Naval battle: raise see-wrap cap. The exact cell size is set by ss.fitSeeBoard via measurement
     (inline --see-cell-max) — so the board NEVER overflows on any resolution. */
  body.ss-maximized .card-board .see-wrap { max-width: 1280px; }
  /* Height chain: limit the board host to the available height (min-height:0 + flex:1),
     otherwise the container grows with the board content and the measurement would be useless. */
  body.ss-maximized .card-board > .screen-game.mode-seeschlacht { display: flex; flex-direction: column; }
  body.ss-maximized .screen-game.mode-seeschlacht > .see-wrap { flex: 1 1 auto; min-height: 0; }
  body.ss-maximized .see-wrap .see-main { flex: 1 1 auto; min-height: 0; }
  /* In the fleet duel BOTH board columns need the treatment (own fleet + target
     waters) — with only :first-child the right column stayed top-aligned with
     auto height and got a different fitted cell size. */
  body.ss-maximized .see-main > div:first-child,
  body.ss-maximized .see-duel .see-main > div:not(.see-panel) {
    min-height: 0; min-width: 0; align-self: stretch; overflow: hidden;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
  }
  /* Equal column widths in the duel — with auto-width flex columns the measured
     fit becomes order-dependent and the two boards end up with different cells. */
  body.ss-maximized .see-duel .see-main > div:not(.see-panel) { flex: 1 1 0; }
  /* Duel boards must line up flush at the TOP: the target column also carries the
     "fire salvo" actions below its board, so vertical centering pushed the (action-less)
     own-fleet board lower than the target board. Top-align keeps both headers + boards even. */
  body.ss-maximized .see-duel .see-main > div:not(.see-panel) { justify-content: flex-start; }
  /* Placement (WERFT) keeps its panel vertically centered next to the board. */
  body.ss-maximized .see-main > .see-panel { align-self: center; }
  /* Shared-sea PLAY only: the fleets panel docks at the TOP (see-shared marker keeps the
     placement WERFT untouched — both otherwise share the plain .see-wrap). */
  body.ss-maximized .see-shared .see-main > .see-panel { align-self: flex-start; }
  /* CSS fallback for cell size (applies only until ss.fitSeeBoard calculates, or without JS). */
  body.ss-maximized .see-duel .see-board-wrap { --see-cell-max: clamp(20px, 5vh, 60px); }
  body.ss-maximized .see-wrap:not(.see-duel) .see-board-wrap {
    --see-cell-max: min(44px, calc((100vh - 240px) / var(--see-rows, 20)));
  }
  /* The naval battle status footer (Game.razor, card-board level) is flex:0 → stays docked at the bottom;
     the nested game screen above fills the rest and centers the boards. */

  /* Podium "game over": the GAME-FRAME (card-board) stays fixed and NEVER scrolls. The inner
     stats box fills the available height via the flex chain and scrolls INTERNALLY when needed
     (overflow-y:auto comes from the base). No zoom, no column tricks. The class
     .podium-has-stats is set by Game.razor only when there is a stats column — Memory
     (without stats) stays normally centered. */
  body.ss-maximized .podium-wrapper { max-width: 1280px; }
  body.ss-maximized .podium-wrapper.podium-has-stats { flex: 1 1 auto; min-height: 0; }
  body.ss-maximized .podium-wrapper.podium-has-stats .podium-layout {
    flex: 1 1 auto; min-height: 0; grid-template-rows: minmax(0, 1fr); align-items: stretch;
  }
  body.ss-maximized .podium-wrapper.podium-has-stats .podium-main { align-self: start; }
  body.ss-maximized .podium-wrapper.podium-has-stats .podium-stats { max-height: none; min-height: 0; }
}

/* ── Low-height compact mode: quiz games on flat landscape viewports ──────
   Landscape tablets (e.g. Galaxy Tab A9+: 1280×800 CSS px, minus ~60px browser
   chrome → ~740px usable) fall into the maximized desktop layout above, but the
   quiz cards' DOM-flow stack (Musikquiz ~660px, Wissensquiz ~617px measured)
   exceeds the available ~573px card-board height and triggers the inner
   overflow-y scroll. Below 850px viewport height the fixed paddings and the
   Musikquiz cover block shrink so both quizzes fit without scrolling; taller
   desktops are pixel-identical. Scoped to the two quiz modes — Hangman/Tabu/
   Memory share .hangman-layout but their stacks fit as-is. */
@media (min-width: 761px) and (max-height: 850px) {
  body.ss-maximized .mode-musikquiz .hangman-layout,
  body.ss-maximized .mode-wissensquiz .hangman-layout { padding-top: 8px; padding-bottom: 8px; }
  body.ss-maximized .card-board .card.mq-card { padding: 14px 26px; gap: 10px; }
  body.ss-maximized .mq-card .hangman-word-header { margin-bottom: 6px; }
  body.ss-maximized .mode-musikquiz .mq-option,
  body.ss-maximized .mode-wissensquiz .mq-option { padding: 10px 16px; min-height: 48px; }

  /* Musikquiz: the cover block is the biggest fixed-height consumer (~280px) —
     scale the cover with the viewport height, tighten slot/volume/gaps. */
  body.ss-maximized .mq-cover-block { margin: 0; gap: 6px; }
  body.ss-maximized .mq-mystery-cover,
  body.ss-maximized .mq-reveal-cover {
    width: clamp(110px, 17vh, 160px);
    height: clamp(110px, 17vh, 160px);
  }
  body.ss-maximized .mq-reveal-slot { min-height: 40px; }
  body.ss-maximized .mq-volume-control { padding: 4px 12px; margin-top: 0; }
}

/* ── App Header (fixed at top) ──────────────────────────────────────────── */
.app-header {
  position: sticky;
  top: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px;
  background: var(--chrome);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border-soft);
}
/* Left group: brand + (when present) the lobby pill / code-join form. Grouping
   them frees the header's horizontal center for the centered announcement banner. */
.app-header-left {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

/* Global announcement banner, centered IN the header row (admin-configurable;
   renders nothing when empty). Absolutely centered so it stays page-centered
   regardless of the differing left/right widths; single-line with ellipsis so it
   never grows the header height. pointer-events:none so it never blocks the
   header controls even if it visually approaches them on narrow widths. */
.announce-strip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: max-content;
  max-width: min(52vw, 600px);
  pointer-events: none;
}
/* Wide: full inline banner (single line, ellipsized if it gets tight). */
.announce-strip .ann-inline {
  margin-bottom: 0;
  width: 100%;
  align-items: center;
  padding: 5px 14px;
  font-size: 13px;
}
.announce-strip .ann-inline .announce-body {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}
.announce-strip .ann-collapsed { display: none; }
/* Hidden measuring copy: JS reads its width to decide whether the full text fits. */
.announce-strip .ann-measure {
  position: absolute;
  left: -9999px;
  top: 0;
  visibility: hidden;
  white-space: nowrap;
  font-size: 13px;
}

/* Collapsed (measured: full text doesn't fit the header center) → show only the
   level icon; a click opens the full text as a popover. Driven by JS measurement
   (shadowSaloon.fitAnnounce), not a fixed breakpoint, so it adapts to text length
   AND window width. */
/* Collapsed: leave the absolute centering and join the header's normal flow as a
   real flex item (between the left group and the actions). That way the icon can
   never overlap the code box — flexbox lays it out instead of stacking it on top. */
.announce-strip.is-collapsed {
  position: static;
  transform: none;
  max-width: none;
  width: auto;
  flex: 0 0 auto;
  pointer-events: auto;
}
.announce-strip.is-collapsed .ann-inline { display: none; }
.announce-strip.is-collapsed .ann-collapsed { display: block; position: relative; pointer-events: auto; }
.announce-strip .ann-toggle {
  margin: 0;
  padding: 0;
  width: 32px;
  height: 32px;
  border: 1px solid currentColor;   /* full ring in the level color (overrides the inline left accent) */
  border-radius: 50%;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.announce-strip .ann-toggle .announce-icon { font-size: 15px; }
.announce-strip .ann-pop {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 86vw;
  /* Opaque base + high z-index so the popover sits clearly ON TOP of the page (game-frame
     header/code box below) instead of showing it through the translucent level tint. The inner
     .announce keeps its per-level tint, now layered over this opaque box. */
  background: var(--surface-1-strong);
  border-radius: 6px;
  box-shadow: 0 12px 30px var(--shadow-color);
  z-index: 1300;
}
.announce-strip .ann-collapsed.is-open .ann-pop { display: block; }
.announce-strip .ann-pop .announce {
  margin-bottom: 0;
  padding: 8px 14px;
  font-size: 12.5px;
  align-items: flex-start;
  box-shadow: none;
}
.announce-strip .ann-pop .announce-body { text-align: left; line-height: 1.4; }
.app-header-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--heading);
  font-family: 'Rye', cursive;
  font-size: 16px;
  letter-spacing: 0.06em;
  transition: opacity 0.15s;
}
.app-header-brand:hover { opacity: 0.85; }
.app-header-logo {
  width: 28px;
  height: 28px;
  filter: drop-shadow(0 0 6px rgba(200, 146, 42, 0.4));
}
/* Theme-Logo-Umschaltung: dunkle Kachel im Dark, Pergament-Stempel im Light. */
.logo-for-light { display: none; }
[data-theme="light"] .logo-for-light { display: inline-block; }
[data-theme="light"] .logo-for-dark { display: none; }
[data-theme="light"] .app-header-logo { filter: none; }
.app-header-title {
  display: inline-block;
}
.app-header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Streamer mode indicator in the header (only visible when active).
   Matched to the 38px height + pill shape of the other header controls
   (language dropdown, mute, avatar), so the chip does not stand out as smaller.
   Red tint remains as a "privacy active" signal. */
.streamer-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 38px;
  padding: 0 14px;
  background: rgba(139, 26, 26, .22);
  border: 1px solid var(--border-strong);
  color: var(--heading);
  border-radius: 19px;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s, border-color .15s;
}
.streamer-chip:hover {
  background: rgba(139, 26, 26, .34);
  border-color: var(--gold);
}
[data-theme="light"] .streamer-chip { background: rgba(139, 26, 26, .10); }
[data-theme="light"] .streamer-chip:hover { background: rgba(139, 26, 26, .18); }
@media (max-width: 540px) {
  /* On narrow screens show only the camera icon, hide text to save space.
     Height stays at 34px like the other header buttons in the mobile layout. */
  .streamer-chip { font-size: 0; height: 34px; padding: 0 11px; }
  .streamer-chip::before { content: '🎥'; font-size: 14px; }
}

/* ── Header Auth Buttons (Guests) ────────────────────────
   Replace the previous hamburger menu for unauthenticated visitors. "Sign in"
   and "Register" are directly visible instead of hidden in a dropdown. */
.header-auth-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.auth-btn {
  display: inline-flex;
  align-items: center;
  height: 38px;
  padding: 0 16px;
  border-radius: 6px;
  font-size: 13px;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .15s, background .15s;
}
.auth-btn-ghost {
  background: transparent;
  border: 1px solid rgba(200, 146, 42, 0.4);
  color: var(--parchment);
}
.auth-btn-ghost:hover { border-color: var(--gold); }
.auth-btn-solid {
  background: linear-gradient(180deg, #3a2710, #26190a);
  border: 1px solid var(--gold);
  color: var(--gold-light);
}
.auth-btn-solid:hover { background: linear-gradient(180deg, #4a3214, #2e1f0c); }

/* ── Nav Lobby Pill ──────────────────────────────────────────────────────
   Shown in the header next to the logo when the user is in a lobby
   but not currently on the lobby/game page. Click navigates back. */
.nav-lobby-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: 14px;
  margin-right: auto;     /* pushes the header-actions block further to the right */
  padding: 5px 12px 5px 8px;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  color: var(--heading);
  font-size: 13px;
  text-decoration: none;
  transition: background .15s, border-color .15s;
  /* gentle pulsing so the user notices the pill */
  animation: navLobbyPulse 2.4s ease-in-out infinite;
}
.nav-lobby-pill:hover {
  background: rgba(200,146,42,.18);
  border-color: var(--gold);
  animation-play-state: paused;
}
.nav-lobby-pill-icon {
  font-size: 16px;
  line-height: 1;
}
.nav-lobby-pill-text {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.nav-lobby-pill-count {
  color: var(--smoke);
  font-size: 12px;
}
@keyframes navLobbyPulse {
  0%, 100% { box-shadow: 0 0 0 rgba(200,146,42,0); }
  50%      { box-shadow: 0 0 14px rgba(200,146,42,.18); }
}

/* Inside the lobby: no pulsing (user is already there),
   slightly more subtle and with a default cursor instead of pointer. */
.nav-lobby-pill.is-current {
  animation: none;
  cursor: default;
  background: rgba(200,146,42,.04);
  border-color: rgba(200,146,42,.25);
}
.nav-lobby-pill.is-current:hover {
  background: rgba(200,146,42,.04);
  border-color: rgba(200,146,42,.25);
}

/* ── Kick Toast (shown by MainLayout when the user was removed from
   the lobby while not on the lobby page) ─────────────────────────────────────── */
.kick-toast-wrap {
  /* Centered directly below the header, but does not push anything.
     Container is just a placeholder for the toast element, which stays sticky. */
  position: sticky;
  top: 60px;
  z-index: 850;
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.kick-toast {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px 10px 16px;
  margin: 14px 16px 0 16px;
  background: rgba(30,10,5,.92);
  border: 1px solid rgba(192,53,42,.7);
  border-left: 3px solid var(--blood-red);
  border-radius: 3px;
  box-shadow: 0 6px 24px rgba(0,0,0,.5);
  color: var(--old-paper);
  font-size: 14px;
  max-width: 480px;
  pointer-events: auto;
  animation: kickToastSlideIn .25s ease-out;
}
.kick-toast-icon {
  font-size: 18px;
  color: var(--red-light);
  flex-shrink: 0;
}
.kick-toast-text {
  flex: 1;
}
.kick-toast-close {
  background: transparent;
  border: none;
  color: var(--smoke);
  font-size: 14px;
  cursor: pointer;
  padding: 2px 6px;
  margin: -2px -4px -2px 0;
  border-radius: 2px;
  transition: color .15s, background .15s;
}
.kick-toast-close:hover {
  color: var(--old-paper);
  background: rgba(255,255,255,.08);
}
@keyframes kickToastSlideIn {
  from { transform: translateY(-12px); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}
/* Mobile: more compact, without mode name */
@media (max-width: 600px) {
  .nav-lobby-pill-text { gap: 4px; }
  .nav-lobby-pill { font-size: 12px; padding: 4px 10px 4px 6px; }
}

/* ── Volume (vertical slider pop-up BELOW the button, hover/focus) ──────── */
.volume-control {
  display: flex;
  align-items: center;
  position: relative;
}
.mute-btn {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  color: var(--heading);
  font-size: 16px;
  cursor: pointer;
  transition: all .2s;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mute-btn:hover {
  border-color: var(--gold);
  background: var(--surface-hover);
  transform: scale(1.05);
}
.mute-btn.muted {
  color: color-mix(in srgb, var(--text-dim) 60%, transparent);
  border-color: color-mix(in srgb, var(--text-dim) 30%, transparent);
}
.mute-btn.muted:hover {
  color: var(--text-dim);
  border-color: var(--border-strong);
}

/* Anchored pop-up panel below the button; the ::before strip bridges the
   hover gap between button and panel so it doesn't close mid-way. */
.volume-pop {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: 34px;
  height: 118px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-1-strong);
  border: 1px solid var(--border-soft);
  border-radius: 17px;
  box-shadow: 0 10px 26px var(--shadow-color);
  z-index: 1000;
  /* opacity instead of display:none — a display:none slider could never
     receive keyboard focus, so :focus-within would be unreachable via Tab. */
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}
.volume-pop::before {
  content: '';
  position: absolute;
  top: -10px;
  left: 0;
  right: 0;
  height: 10px;
}
.volume-control:hover .volume-pop,
.volume-control:focus-within .volume-pop {
  opacity: 1;
  pointer-events: auto;
}
/* Horizontal range rotated 270° → max points UP (push up = louder). The
   layout box stays horizontal; hit-testing follows the transformed geometry.
   The input box is 24px thick (WCAG 2.5.8 minimum target size) — the visible
   4px track is drawn by the track pseudo-elements, not the element itself. */
.volume-slider {
  -webkit-appearance: none;
  appearance: none;
  flex: none;
  width: 94px;
  height: 24px;
  background: transparent;
  outline: none;
  cursor: pointer;
  transform: rotate(270deg);
}
.volume-slider::-webkit-slider-runnable-track {
  height: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 2px;
}
.volume-slider::-moz-range-track {
  height: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 2px;
}
.volume-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  margin-top: -5px;   /* center the 14px thumb on the 4px(+2px border) track */
  border-radius: 50%;
  background: var(--gold);
  border: 1px solid rgba(8, 5, 2, 0.8);
  cursor: pointer;
}
.volume-slider::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--gold);
  border: 1px solid rgba(8, 5, 2, 0.8);
  cursor: pointer;
}

/* Header help button (game rules) — sits in the header-actions, no longer fixed */
.header-help-btn {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  color: var(--heading);
  font-family: 'Rye', cursive;
  font-size: 16px;
  cursor: pointer;
  transition: all .2s;
  display: flex;
  align-items: center;
  justify-content: center;
}
.header-help-btn:hover {
  border-color: var(--gold);
  background: var(--surface-hover);
  transform: scale(1.05);
}

@media (max-width: 540px) {
  .app-header { padding: 8px 12px; }
  .app-header-title { display: none; } /* logo only on mobile */
  .mute-btn,
.header-help-btn { width: 34px; height: 34px; font-size: 14px; }
  .volume-control:hover .volume-slider { width: 60px; max-width: 60px; }
  /* Narrow header: show only "Sign in", "Register" is accessible from
     the login page. Saves width next to logo + volume. */
  .auth-btn-solid { display: none; }
  .auth-btn { height: 34px; padding: 0 12px; }
}

/* ── Game Start: Sidebar Button + Fullscreen Countdown Overlay ─────────── */

/* Slimmer start button below the settings (instead of wide below the chat) */
.btn-start-sidebar {
  width: 100%;
  margin-top: 14px;
  padding: 10px 18px;
  font-size: 14px;
  letter-spacing: .08em;
}
.waiting-banner-sidebar {
  margin-top: 14px;
  text-align: center;
  font-size: 13px;
}

/* Overlay for start countdown — lives in .lobby-frame, covers only the lobby card */
.lobby-frame {
  position: relative;
  width: 100%;
  max-width: 1000px;
  border-radius: 4px;
  overflow: hidden;
}
.start-overlay {
  position: absolute;
  inset: 0;
  background: var(--scrim);
  backdrop-filter: blur(6px);
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: startOverlayFadeIn .25s ease-out;
}
@keyframes startOverlayFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.start-overlay-content {
  text-align: center;
  max-width: 480px;
  width: 100%;
}
.start-overlay-label {
  font-size: 15px;
  color: var(--smoke);
  letter-spacing: .25em;
  text-transform: uppercase;
  margin-bottom: 14px;
}
.start-overlay-num {
  font-family: 'Rye', cursive;
  font-size: clamp(96px, 18vw, 168px);
  color: var(--accent-strong);
  line-height: 1;
  text-shadow:
    0 0 32px var(--accent-light),
    0 0 64px var(--accent),
    0 4px 0 var(--shadow);
  margin-bottom: 18px;
  animation: startOverlayPulse 1s ease-in-out infinite;
}
@keyframes startOverlayPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}
.start-overlay-bar {
  width: 100%;
  height: 6px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 20px;
}
.start-overlay-bar-fill {
  height: 100%;
  background: linear-gradient(to right, var(--accent), var(--accent-light));
  box-shadow: 0 0 14px var(--accent-light);
}
.start-overlay-cancel {
  margin-top: 4px;
}

/* Kept: timer-fill-gold is still used by CountdownScreen.razor */
.timer-fill-gold {
  background: var(--gold) !important;
  box-shadow: 0 0 10px rgba(200,146,42,.5);
}

/* ── Chat ────────────────────────────────────────────────────────────────── */
.chat-card {
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.chat-title {
  font-family: 'Rye', cursive;
  font-size: 14px;
  color: var(--gold);
  letter-spacing: .08em;
}
.chat-messages {
  /* Was 180px before – with the new lobby layout (player list compact at top)
     we have more height available, so we use the space for the chat. */
  height: 380px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 3px;
  scrollbar-width: thin;
  scrollbar-color: rgba(200,146,42,.2) transparent;
}
.chat-messages::-webkit-scrollbar { width: 4px; }
.chat-messages::-webkit-scrollbar-thumb { background: rgba(200,146,42,.2); border-radius: 2px; }

/* Status line */
.chat-status {
  display: flex;
  gap: 6px;
  align-items: baseline;
  padding: 1px 0;
}
.chat-status-text {
  font-size: 13px;
  color: var(--tg-sub, #6b5838);   /* fixed paper ink — the drawer is light in BOTH themes */
  font-style: italic;
}

/* Chat message */
.chat-msg {
  display: flex;
  gap: 6px;
  align-items: baseline;
  padding: 2px 0;
  flex-wrap: wrap;
}
.chat-msg-own .chat-sender { color: var(--tg-ink, #3a2c16); }
.chat-time {
  font-size: 12px;
  color: var(--tg-sub, #6b5838);   /* fixed paper ink — the drawer is light in BOTH themes */
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.chat-sender {
  font-size: 13px;
  color: var(--tg-wood, #6b4a23);
  font-weight: bold;
  flex-shrink: 0;
}
.chat-sender::after { content: ':'; }
.chat-text {
  font-size: 14px;
  color: var(--old-paper);
  word-break: break-word;
  flex: 1;
}

/* Input line */
.chat-input-row {
  display: flex;
  gap: 6px;
  /* stretch instead of center: button adapts to the input height (input has
     padding-based height ~36 px, button had fixed 32 px → 4 px offset). */
  align-items: stretch;
}
.chat-inp {
  flex: 1;
  min-width: 0;
  font-size: 14px;
}

.chat-send-btn {
  flex-shrink: 0;
  width: 32px;
  background: rgba(8,5,2,.6);
  border: 1px solid rgba(200,146,42,.35);
  border-radius: 1px;
  font-size: 20px;
  color: var(--gold);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all .2s;
  line-height: 1;
  padding: 0;
}
.chat-send-btn:hover:not(:disabled) { background: rgba(200,146,42,.12); border-color: var(--gold); }
.chat-send-btn:disabled { opacity: .35; cursor: default; }

/* Emoji picker removed */

/* ── Game History Modal — Body Classes (all wrappers migrated to <Modal> component) ──── */

.history-loading,
.history-empty {
  padding: 32px;
  text-align: center;
  color: var(--smoke);
  font-size: 14px;
}
.history-list {
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ── Game Card ── */
.history-game-card {
  background: rgba(200,146,42,.04);
  border: 1px solid rgba(200,146,42,.12);
  border-radius: 2px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.history-game-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.history-game-meta {
  display: flex;
  gap: 10px;
  align-items: center;
}
.history-game-date {
  font-size: 13px;
  color: var(--smoke);
}
.history-game-duration {
  font-size: 12px;
  color: rgba(168, 151, 132,.55);
  background: rgba(200,146,42,.07);
  padding: 1px 7px;
  border-radius: 10px;
}
.history-winner-badge {
  font-size: 13px;
  padding: 3px 10px;
  border-radius: 2px;
  letter-spacing: .05em;
}
.history-winner-crewmates { background: rgba(34,139,34,.2);   color: #5c5; }
.history-winner-impostor { background: rgba(139,26,26,.25);  color: #e66; }
.history-winner-draw { background: rgba(168, 151, 132,.2); color: var(--smoke); }

.history-label {
  font-size: 12px;
  color: var(--smoke);
  letter-spacing: .1em;
  text-transform: uppercase;
  flex-shrink: 0;
  min-width: 68px;
}
.history-word-row,
.history-impostor-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.history-word {
  font-family: 'Rye', cursive;
  font-size: 16px;
  color: var(--gold-light);
  letter-spacing: .08em;
}
.history-impostor { font-size: 14px; color: var(--blood-red); }
.history-guess {
  font-size: 12px;
  margin-left: 4px;
}
.history-guess.correct { color: var(--green-ok); }
.history-guess.wrong { color: rgba(200,60,60,.7); }

.history-clues-section { display: flex; flex-direction: column; gap: 6px; }
.history-clues-grid { display: flex; flex-direction: column; gap: 4px; padding-left: 4px; }
.history-player-row {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-size: 13px;
  padding: 3px 0;
  border-bottom: 1px solid rgba(200,146,42,.05);
}
.history-player-row:last-child { border-bottom: none; }
.history-player-row.is-impostor .history-pname { color: var(--blood-red); }
.history-pname { flex: 0 0 110px; color: var(--old-paper); }
.history-pclues { flex: 1; color: var(--gold); }
.history-pvotes { flex: 0 0 80px; text-align: right; color: rgba(168, 151, 132,.6); font-size: 12px; }

/* ── Impostor: Category Display ─────────────────────────────────────────── */
.impostor-category {
  width: 100%;
  max-width: 320px;
  padding: 14px 22px;
  text-align: center;
  margin-top: 4px;
}
.impostor-category-value {
  font-family: 'Rye', cursive;
  font-size: 22px;
  color: var(--heading);
  letter-spacing: .08em;
  margin-top: 6px;
}

/* ── Settings: Toggle Row ─────────────────────────────────────────────── */
.settings-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 0;
}
/* .lbl brings display:block + margin-bottom — reset in the flex row
   so the label sits vertically centered, and match the
   compact 13px size of the other config rows. Applies to the
   direct label and the inline-label-with-help variant. */
.settings-toggle-row > .lbl,
.settings-toggle-row > .lbl-with-help-inline {
  display: flex;
  align-items: center;
  margin-bottom: 0;
}
.settings-toggle-row > .lbl,
.settings-toggle-row .lbl-with-help-inline .lbl {
  font-size: 13px;
  margin-bottom: 0;
}
/* Inline hint under a setting label (e.g. "not available in rapid fire"): own line,
   normal sentence case (not the uppercase/letter-spacing of the .lbl it sits in). */
.settings-lbl-hint {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  line-height: 1.35;
  color: var(--smoke);
}

/* ── Settings Toggle Button ──────────────────────────────────────────────── */
/* Bool slider (red/green) with ✓/✕ in the knob. Base = OFF (red),
   .on = ON (green). Used centrally: admin settings + lobby config.
   Markup: <button class="settings-toggle-btn [on]"><span class="toggle-knob">✓/✕</span></button> */
.settings-toggle-btn {
  width: 46px;
  height: 24px;
  border-radius: 12px;
  position: relative;
  padding: 0;
  border: none;
  cursor: pointer;
  background: rgba(139, 26, 26,.6);   /* off = red */
  transition: background .18s;
  flex-shrink: 0;
}
.settings-toggle-btn.on { background: var(--green-ok); }   /* on = green */
.settings-toggle-btn .toggle-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #e8d5b0;
  color: #1a1208;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: bold;
  transition: left .18s;
  box-shadow: 0 1px 3px rgba(0,0,0,.5);
}
.settings-toggle-btn.on .toggle-knob { left: 24px; }
.settings-toggle-btn:hover { filter: brightness(1.12); }

/* ── Settings Section Label ──────────────────────────────────────────────
   Subtle separator heading between lobby and game settings in the
   new-lobby dialog. Two horizontal lines (pseudo-elements) flank
   the label text. .first = no top margin (first section directly at the
   start of the modal body). Applies to all game modes. */
.settings-section-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0 4px;
  color: var(--smoke);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .8px;
  text-transform: uppercase;
}
.settings-section-label::before,
.settings-section-label::after {
  content: '';
  flex: 1;
  height: 1px;
  background: rgba(200,146,42,.15);
}
.settings-section-label.first { margin-top: 0; }

/* ── Game Variant Block ───────────────────────────────────────────────────
   Visually highlighted block for the rapid-fire mode in the music-quiz
   lobby dialog — replaces the previous settings-toggle-row.
   Shows mode name, short description text and the toggle button.
   .active = rapid-fire enabled (golden border + light background). */
.spielvariante-block {
  border: 1px solid rgba(200,146,42,.2);
  border-radius: 5px;
  background: var(--surface-2);
  margin: 2px 0 6px;
  transition: border-color .18s, background .18s;
}
.spielvariante-block.active {
  border-color: rgba(200,146,42,.45);
  background: rgba(200,146,42,.07);
}
.spielvariante-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
}
.spielvariante-info { flex: 1; min-width: 0; }
.spielvariante-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--parchment);
  display: flex;
  align-items: center;
  gap: 6px;
  transition: color .18s;
}
.spielvariante-block.active .spielvariante-name { color: var(--gold-light); }
.spielvariante-desc {
  font-size: 12px;
  color: var(--smoke);
  margin-top: 3px;
  line-height: 1.5;
}

/* ── Advanced Settings Collapsible ─────────────────────────────────────────
   Collapses fine-tuning options (answer delay, stop-on-first).
   Uses native <details> — no JS state needed.
   Deliberately mirrors the filter-collapsible look (bordered box, rotating
   ▸ triangle) so it stands as an equal block next to the filters and
   has a clear click target — instead of floating centered text. */
.settings-advanced-collapsible {
  border: 1px solid rgba(255,255,255,.06);
  border-radius: 4px;
  background: var(--surface-2);
  margin-top: 6px;
}
.settings-advanced-collapsible > .settings-advanced-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  user-select: none;
  border-radius: 4px;
  transition: background .15s ease;
}
.settings-advanced-collapsible > .settings-advanced-summary::-webkit-details-marker {
  display: none;
}
.settings-advanced-collapsible > .settings-advanced-summary:hover {
  background: rgba(255,255,255,.03);
}
.settings-advanced-collapsible > .settings-advanced-summary::before {
  content: '▸';
  font-size: 18px;
  font-weight: 700;
  color: var(--gold, #c8922a);
  transition: transform .2s ease;
  display: inline-block;
  margin-right: 8px;
}
.settings-advanced-collapsible[open] > .settings-advanced-summary::before {
  transform: rotate(90deg);
}
/* ── Lobby Sidebar: Quick-Access Buttons at Top ──────────────────────────── */
.lobby-sidebar-top-btns {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}
.btn-sm-action {
  flex: 1;
  font-size: 12px !important;
  padding: 6px 10px !important;
  white-space: nowrap;
}

/* ── Stat Box (Game Sidebar) ─────────────────────────────────────────────── */
.stat-box { background: var(--surface-1-strong); border: 1px solid var(--border-soft); padding: 14px 16px; border-radius: 1px; }
.stat-box h4 { font-family: 'Rye', cursive; font-size: 16px; color: var(--accent); margin-bottom: 10px; letter-spacing: .08em; }
[data-theme="light"] .stat-box h4 { color: var(--accent-ink); }   /* Gold-Akzent faellt auf Pergament unter 4.5:1 */
.stat-box-center { text-align: center; }

/* ── Hangman ─────────────────────────────────────────────────────────────── */

.hangman-placeholder {
  font-family: 'Rye', cursive;
  /* Scales with the card width — the inline-style letter-spacing from
     HangmanPlaying.razor adjusts letter spacing dynamically by word length,
     but the font size itself should also adapt to the card. */
  font-size: clamp(24px, 8cqi, 46px);
  color: var(--parchment);
  letter-spacing: .22em;
  margin: 12px 0 16px;
  word-break: break-all;
  text-shadow:
    0 0 20px var(--accent-light),
    0 0 40px var(--accent),
    0 2px 0 var(--shadow);
}
/* In-place reveal (SS-0327): the word solves in green, like a correct quiz answer,
   with a matching glow instead of the accent shadow. */
.hangman-placeholder.solved {
  color: var(--success);
  text-shadow:
    0 0 22px color-mix(in srgb, var(--success) 55%, transparent),
    0 0 44px color-mix(in srgb, var(--success) 30%, transparent),
    0 2px 0 var(--shadow);
}
/* Reveal countdown line ("Nächstes Wort in X s" / "Auswertung in X s") — sits in the
   timer row's place, centered. */
.hangman-next-row { justify-content: center; color: var(--smoke); font-size: 14px; }
.hangman-next-num {
  font-family: 'Rye', cursive;
  color: var(--accent-ink);
  font-size: 22px;
  font-variant-numeric: tabular-nums;
}
.hangman-letter-count {
  font-size: 12px;
  color: color-mix(in srgb, var(--text-dim) 50%, transparent);
  letter-spacing: .08em;
}

/* ── Tabu ────────────────────────────────────────────────────────────────── */
.tabu-clues-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.tabu-clue-item {
  font-size: 14px;
  color: var(--old-paper);
  padding: 6px 10px;
  background: var(--surface-2);
  border-left: 2px solid color-mix(in srgb, var(--border-strong) 55%, transparent);
  border-radius: 1px;
}

/* Gold background for Explainer role reveal */
.bg-gold {
  background: radial-gradient(ellipse at 50% 30%, rgba(200,146,42,.12) 0%, transparent 70%),
              var(--dark);
}

/* ── History: Session Header as Collapsible Button ───────────────────── */
.history-session-header {
  /* button reset because we use <button> instead of <div> */
  background: color-mix(in srgb, var(--well) 33%, transparent);
  border: 1px solid var(--border-faint);
  color: var(--gold-ink);
  font-family: 'Rye', cursive;
  font-size: 13px;
  letter-spacing: .08em;
  padding: 10px 14px;
  margin-top: 10px;
  width: 100%;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  border-radius: 2px;
  transition: background .15s ease, border-color .15s ease;
}
.history-session-header:hover {
  background: var(--surface-2);
  border-color: color-mix(in srgb, var(--border-strong) 67%, transparent);
}
.history-session-header:first-of-type {
  margin-top: 0;
}
.history-session-header.expanded {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  border-bottom-color: transparent;
}
.history-session-toggle {
  color: var(--smoke, #a89784);
  font-size: 12px;
  width: 12px;
  flex-shrink: 0;
}
.history-session-title {
  flex-shrink: 0;
}
.history-session-summary {
  font-size: 12px;
  color: var(--smoke, #a89784);
  letter-spacing: .03em;
  margin-left: auto;
  text-transform: none;
  text-align: right;
}
.history-session-my-result strong {
  color: var(--accent-amber);
}

/* ── Hangman: Compact Layout ───────────────────────────────────────────── */
.hangman-layout {
  display: grid;
  grid-template-columns: 1fr 220px;
  gap: 20px;
  width: 100%;
  max-width: 820px;
  padding: 24px 20px;
  align-items: start;
}
.hangman-main { display: flex; flex-direction: column; gap: 14px; }
.hangman-word-card {
  padding: 20px 24px 18px;
  text-align: center;
}
.hangman-word-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
  font-size: 12px;
  letter-spacing: .07em;
}
.hangman-word-progress {
  color: var(--smoke);
}
.hangman-word-category {
  color: var(--accent-amber);
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.hangman-letter-count { color: color-mix(in srgb, var(--text-dim) 50%, transparent); }
.hangman-input-area { margin-top: 18px; }
.hangman-correct-msg {
  color: var(--success);
  font-size: 14px;
  padding: 12px 0;
}

/* ── Podium Layout ───────────────────────────────────────────────────────── */
.podium-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 900px;
  padding: 28px 24px;
  gap: 16px;
}
.podium-title-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.podium-layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 24px;
  width: 100%;
  align-items: start;
}
/* Modes without round statistics (e.g. Memory): only the final standings, single-column and
   centered instead of left-aligned in the 280px column. */
.podium-layout.no-stats {
  grid-template-columns: 280px;
  justify-content: center;
}
.podium-main {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.podium-scores { width: 100%; padding: 16px 20px; }
.podium-score-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--border-faint);
}
.podium-score-row:last-child { border-bottom: none; }
.podium-medal { font-size: 20px; width: 30px; flex-shrink: 0; }

/* Clickable player name on the end podium — opens the PlayerProfileModal.
   Hover highlights brighter + underlined; the underline is deliberately
   a clearer signal than on track rows, because a name
   row is less obviously interactive. */
.podium-name-clickable { cursor: pointer; transition: color .12s; }
.podium-name-clickable:hover { color: var(--heading); text-decoration: underline; }

/* Hint pill for players who left the lobby before the game ended —
   their name stays in the final standings but is not clickable. */
.podium-name-left-tag {
  display: inline-block;
  font-size: 12px;
  letter-spacing: .08em;
  padding: 1px 7px;
  margin-left: 6px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--text-dim) 20%, transparent);
  color: var(--smoke);
  vertical-align: middle;
}

.podium-pts { color: var(--accent-ink); font-family: 'Rye', cursive; font-size: 20px; }
.podium-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}
.podium-btn { width: 100% !important; }

/* ── Podium Statistics ───────────────────────────────────────────────────── */
.podium-stats {
  background: var(--well);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 16px 18px;
  max-height: 70vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border-soft) transparent;
}
.podium-word-block {
  padding: 10px 0;
  border-bottom: 1px solid var(--border-faint);
}
.podium-word-block:last-child { border-bottom: none; }
.podium-word-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}
.podium-word-num { color: var(--smoke); font-size: 12px; flex-shrink: 0; }
.podium-word-text { font-family: 'Rye', cursive; font-size: 15px; color: var(--accent-ink); }
.podium-word-cat { font-size: 12px; color: var(--smoke); padding: 1px 6px; background: var(--surface-2); border-radius: 2px; }
.podium-word-erklaerer { font-size: 12px; color: var(--accent-amber); }
.podium-stat-row {
  display: grid;
  grid-template-columns: 1fr 50px 55px;
  gap: 8px;
  font-size: 13px;
  padding: 3px 0;
  color: var(--old-paper);
}
.podium-stat-time { color: var(--smoke); text-align: right; }
.podium-stat-pts { color: var(--accent-ink); text-align: right; }

@media (max-width: 700px) {
  .hangman-layout { grid-template-columns: 1fr; }
  .podium-layout { grid-template-columns: 1fr; }
}

/* ── Hangman Role Reveal ─────────────────────────────────────────────────── */
.hangman-reveal-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  max-width: 400px;
}
.hangman-reveal-letters {
  font-family: 'Rye', cursive;
  font-size: clamp(28px, 6vw, 48px);
  color: var(--heading);
  letter-spacing: .35em;
  text-shadow: 0 0 30px rgba(200,146,42,.3);
}
.hangman-reveal-rules {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 8px;
}
.hangman-rule-item {
  font-size: 14px;
  color: var(--old-paper);
  background: var(--surface-2);
  border: 1px solid var(--border-faint);
  border-radius: 2px;
  padding: 8px 16px;
  text-align: center;
}

/* ── Hangman Timer ───────────────────────────────────────────────────────── */
.hangman-timer-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0 4px;
}
.hangman-timer-num {
  font-size: 13px;
  color: var(--smoke);
  flex-shrink: 0;
  min-width: 34px;
  text-align: right;
}
.hangman-timer-num.danger { color: var(--blood-red); }

/* ── Tabu Role Reveal ─────────────────────────────────────────────────────── */
.tabu-reveal-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  max-width: 400px;
}
.tabu-reveal-badge {
  font-family: 'Rye', cursive;
  font-size: 22px;
  color: var(--heading);
  letter-spacing: .2em;
  padding: 8px 24px;
  border: 1px solid color-mix(in srgb, var(--border-strong) 67%, transparent);
  border-radius: 2px;
  background: var(--surface-2);
}
.tabu-reveal-word-card { width: 100%; text-align: center; }
.tabu-reveal-erklaerer {
  font-size: 16px;
  color: var(--old-paper);
}
.tabu-reveal-erklaerer strong { color: var(--heading); }

/* ── Tabu Game Screen ───────────────────────────────────────────────────── */
.tabu-word-display {
  text-align: center;
  padding: 8px 0 12px;
  border-bottom: 1px solid var(--border-faint);
  margin-bottom: 12px;
}
.tabu-clues-area {
  min-height: 60px;
  margin-bottom: 10px;
}
.tabu-waiting {
  font-size: 14px;
  color: var(--smoke);
  text-align: center;
  padding: 12px 0;
  font-style: italic;
}
.tabu-sent-clues {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.tabu-sent-clue {
  font-size: 12px;
  color: var(--smoke);
  background: var(--surface-2);
  border: 1px solid var(--border-faint);
  border-radius: 2px;
  padding: 2px 8px;
}

/* ── Tabu Role Reveal: Compact Rules ─────────────────────────────────────── */
.tabu-reveal-compact-rules {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}
.tabu-reveal-compact-rules span {
  font-size: 13px;
  color: var(--old-paper);
  background: var(--surface-2);
  border: 1px solid var(--border-faint);
  border-radius: 2px;
  padding: 5px 12px;
  text-align: center;
}

/* ── Tabu Explainer Skip ──────────────────────────────────────────────────── */
.tabu-erklaerer-actions {
  margin-top: 8px;
}
.tabu-skip-btn {
  font-size: 12px !important;
  padding: 5px 14px !important;
  color: var(--smoke) !important;
  border-color: color-mix(in srgb, var(--text-dim) 30%, transparent) !important;
}
.tabu-skip-btn:hover { color: var(--old-paper) !important; }

/* ── Tabu Flash Message ──────────────────────────────────────────────────── */
.tabu-flash {
  font-size: 13px;
  text-align: center;
  padding: 7px 14px;
  border-radius: 2px;
  margin-bottom: 10px;
  letter-spacing: .04em;
  animation: tabu-flash-in .2s ease;
}
.tabu-flash-ok { background: rgba(80,180,80,.12);  color: var(--success);  border: 1px solid rgba(80,180,80,.25); }
.tabu-flash-skip { background: var(--surface-2); color: var(--smoke);     border: 1px solid var(--border-faint); }
@keyframes tabu-flash-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* ── Tabu Break Screen ───────────────────────────────────────────────────── */
.tabu-break-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  width: 100%;
  max-width: 600px;
  margin: 12px 0;
}
.tabu-break-card { padding: 14px 16px; }
.tabu-break-word-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
  border-bottom: 1px solid var(--border-faint);
  gap: 8px;
}
.tabu-break-word-row:last-child { border-bottom: none; }
.tabu-break-word {
  color: var(--heading);
  font-size: 13px;
}
.tabu-break-guesser {
  font-size: 12px;
  color: var(--smoke);
  flex-shrink: 0;
}
@media (max-width: 500px) {
  .tabu-break-layout { grid-template-columns: 1fr; }
}

/* ── Game Rules Modal — Body Classes (wrapper migrated to <Modal> component) ─────── */
.rules-content {
  text-align: left;
  font-size: 14px;
  line-height: 1.6;
  color: var(--old-paper);
}
.rules-content p { margin: 0 0 10px 0; }
.rules-content ul { margin: 4px 0 10px 24px; padding: 0; }
.rules-content li { margin: 4px 0; }
.rules-content strong { color: var(--heading); }

/* ── Auth Pages (Setup, Login, Register, Profile) ─────────────────────── */
.auth-screen,
.setup-screen {
  flex: 1 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.card-auth,
.card-setup {
  background: var(--surface-1-strong);
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  padding: 32px;
  max-width: 420px;
  width: 100%;
  box-shadow: 0 4px 32px rgba(0,0,0,.6);
}
.card-setup { max-width: 480px; }

.auth-emoji,
.setup-emoji {
  text-align: center;
  font-size: 48px;
  margin-bottom: 12px;
}
.auth-title,
.setup-title {
  text-align: center;
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 26px;
  margin: 0 0 6px 0;
}
.setup-subtitle {
  text-align: center;
  color: var(--smoke);
  font-size: 14px;
  margin-bottom: 24px;
}

.auth-form,
.setup-form { display: flex; flex-direction: column; gap: 16px; }
.form-group { display: flex; flex-direction: column; gap: 6px; }
/* var(--heading), NOT --gold-light: identical gold in dark mode, but readable
   dark brown in the light theme (gold-light on light modal bg is ~1.5:1). */
.form-group label {
  font-size: 13px;
  color: var(--heading);
}
.form-group small { color: var(--smoke); font-size: 12px; }

/* Spacing between consecutive form-groups inside a modal body.
   `.auth-form` already handles this via its `gap: 16px`, but the modal lacks
   such a wrapper — the form-groups would otherwise stick together (label "Current
   Password" would look like the label of the input above it). Adjacent-sibling selector
   so no top spacing appears on the first form-group. */
.modal-v2-body .form-group + .form-group { margin-top: 14px; }
.form-row { flex-direction: row; align-items: center; justify-content: space-between; gap: 10px; }
.check-row { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; color: var(--smoke); }
.check-row input[type="checkbox"] { cursor: pointer; }

.text-warning { color: #d97706; }

.btn-block { width: 100%; }

.auth-link {
  color: var(--heading);   /* not --gold: 2.7:1 on the light auth card */
  text-decoration: none;
  font-size: 13px;
}
.auth-link:hover { color: var(--heading); text-decoration: underline; }
/* Inactive variant (e.g. "Forgot password?" when SMTP is not configured) –
   stays visible but visually greyed out and not clickable. */
.auth-link-disabled {
  color: var(--smoke, #a89784);
  opacity: 0.55;
  cursor: not-allowed;
  text-decoration: line-through;
}
.auth-link-disabled:hover {
  color: var(--smoke, #a89784);
  text-decoration: line-through;
}

.auth-divider {
  text-align: center;
  margin: 24px 0 18px 0;
  position: relative;
  color: var(--smoke);
  font-size: 12px;
}
.auth-divider::before,
.auth-divider::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 40%;
  height: 1px;
  background: rgba(200,146,42,.2);
}
.auth-divider::before { left: 0; }
.auth-divider::after { right: 0; }
.auth-divider span { background: var(--card-grad-b); padding: 0 12px; position: relative; }

.oauth-buttons { display: flex; flex-direction: column; gap: 8px; }
.btn-oauth {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 10px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  color: var(--old-paper);
  border-radius: 6px;
  text-decoration: none;
  font-size: 14px;
  transition: all .2s;
}
.btn-oauth:hover { border-color: var(--gold); background: var(--surface-hover); }
.oauth-icon { font-weight: bold; width: 20px; text-align: center; }

/* Brand icons from ProviderIcon.razor — same dimensions as the .oauth-icon container,
   so login + profile linked-accounts lists sit on the same visual line. */
.provider-icon {
  width: 18px;
  height: 18px;
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
}

/* Toggle button for password/email form on login + register.
   OAuth is the default path, the classic form path expands on click.
   Kept subtle, only highlights on hover. */
.pw-toggle {
  background: transparent;
  border: 1px solid rgba(200,146,42,.25);
  color: var(--smoke);
  width: 100%;
  padding: 10px 14px;
  cursor: pointer;
  font-size: 14px;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: all .15s;
}
.pw-toggle:hover { color: var(--heading); border-color: var(--gold); }
.pw-toggle .chevron { font-size: 12px; transition: transform .2s; }
.pw-toggle.expanded .chevron { transform: rotate(180deg); }

/* Collapsed form below the toggle. Toggled via JS
   (login: localStorage memory, register: always initially collapsed). */
.pw-form-collapsible { display: none; margin-top: 14px; padding-top: 14px;
  border-top: 1px dashed rgba(200,146,42,.15); }
.pw-form-collapsible.expanded { display: block; }

.auth-footer {
  margin-top: 20px;
  text-align: center;
  font-size: 13px;
  color: var(--smoke);
}

/* ── Profile Info ─────────────────────────────────────────────────────── */
.profile-info { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.profile-info-row { display: flex; align-items: center; gap: 10px; font-size: 14px; }
/* Label fixed on the left, value takes the middle space (`flex:1`), edit button sticks to the right.
   Before the edit-pencil extension, Profile-Info-Rows used `space-between`
   with only two children — now there can be up to three. With `flex:1` on the value
   the layout stays consistent regardless of whether a pencil is attached or not. */
/* min-width:0 lets the flex item shrink below its content width,
   overflow-wrap wraps long values (e.g. long email addresses) instead of
   overflowing the box. */
.profile-info-row > strong,
.profile-info-row > code { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.profile-label { color: var(--smoke); min-width: 90px; }
.profile-section-title { color: var(--heading); font-size: 15px; margin: 0 0 10px 0; }
/* masked values in streamer mode. */
.streamer-masked { color: var(--smoke); letter-spacing: 2px; font-style: italic; }
/* Streamer toggle as a clean single line: right-aligned like a value/edit pencil, no
   wrapping hint anymore (explanation is in the tooltip). */
.profile-streamer-row .settings-toggle-btn { margin-left: auto; }
/* Language dropdown right-aligned like the privacy toggle (same row appearance). */
.profile-divider { border: none; border-top: 1px solid rgba(200,146,42,.15); margin: 22px 0; }

/* Edit pencil behind editable values in the account card (display name, email).
   Subtle, in the saloon gold style, hover brightens. */
.edit-btn {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--heading);
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  border-radius: 1px;
  font-size: 13px;
  font-family: inherit;
  padding: 0;
  flex-shrink: 0;
  transition: all .15s;
}
.edit-btn:hover {
  border-color: var(--gold);
  color: var(--heading);
  background: rgba(200,146,42,.08);
}

/* Action row below the info rows (e.g. "change password" button).
   Dashed separator visually separates it from the info rows above. */
.profile-action-row {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed rgba(200,146,42,.1);
  display: flex;
  gap: 8px;
}
/* Buttons in an action row should only be as wide as their content —
   `.btn` has `width:100%` as default, which leads to wall-wide buttons here. */
.profile-action-row .btn-sm-action {
  flex: 0 0 auto;
  width: auto;
}

/* Modal body form label: smaller grey labels above the inputs. */
.form-label {
  display: block;
  font-size: 13px;
  color: var(--smoke);
  margin-bottom: 4px;
}

/* Role badges in the account card: compact symbol display (crown/scale/pencil)
   instead of comma-separated role names, with a title tooltip for the plain-text role.
   Keeps the account card slim when more account data is added later. */
.profile-roles {
  display: inline-flex;
  gap: 6px;
  flex: 1;
}
.profile-role-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  color: var(--heading);
  font-size: 14px;
  border-radius: 3px;
  cursor: help;
}

/* ── Profile Page Layout (responsive 2-column) ──────────────────────────── */
/* Own screen container instead of .auth-screen, because the profile should not
   sit in a narrow auth card but may use the full width. */
.profile-screen {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 24px 16px 60px;
}
.profile-page {
  width: 100%;
  max-width: 1100px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.profile-page-header {
  text-align: center;
  margin-bottom: 6px;
}

/* Two-column layout: left (380px, account management) and right (1fr, statistics
   + history). Each column is its own flex container, so the left sections stay
   stacked tightly — regardless of how tall the right column gets.
   With the old grid layout (grid-auto-flow: dense + explicitly assigned
   grid-column) very tall right sections dragged the whole grid row along and made
   the left cards look visually "torn apart". */
.profile-grid {
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: 18px;
  align-items: start;
}
.profile-column-left,
.profile-column-right {
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-width: 0;  /* so long content (e.g. long email address) does not break the column */
}
.profile-section {
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  padding: 18px 20px 22px;
}
/* Buttons and button links inside a profile section get spacing
   from the preceding content (typically explanatory text). Standard p-margin
   alone is not enough; the "too close" impression comes mainly from
   .btn-block buttons that take up full width and therefore look visually
   very heavy. */
.profile-section > .btn,
.profile-section > a.btn {
  margin-top: 10px;
}
.profile-section > p + .btn,
.profile-section > p + a.btn {
  margin-top: 14px;
}
/* Legacy modifier: profile-section-left / profile-section-right were previously
   used for CSS grid column assignment. With the flex-column layout they are
   no longer semantically needed, but stay on the Razor sections so
   the logical purpose is visible in the markup. No additional styling here. */
.profile-section-danger {
  border-color: rgba(139,26,26,.35);
}
.profile-section .profile-section-title {
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 16px;
  letter-spacing: .04em;
  margin: 0 0 14px 0;
}
.profile-section .profile-danger-title { color: var(--danger); }

/* Collapse to a single column on tablet / smartphone, sections follow
   DOM order: all left sections first (account, display name,
   linked accounts, data, danger zone), then the right ones (statistics, recent games).
   Both flex columns remain active, the grid just switches its column mode
   — stack layout works automatically. */
@media (max-width: 860px) {
  .profile-grid {
    grid-template-columns: 1fr;
  }
}

/* ── Profile Dropdown in MainLayout ───────────────────────────────────── */
/* Closing on outside click now runs via ssClickOutside
   (document listener) instead of a fixed backdrop — which would be trapped
   inside the header box because of backdrop-filter. */
.profile-menu { position: relative; }
.profile-btn {
  position: relative;
  z-index: 1001;      /* must stay above the backdrop */
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  color: var(--heading);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all .2s;
}
/* Avatar fills the profile button (round photo/portrait instead of a letter). */
.profile-btn .avatar { --av-size: 32px; }
.profile-btn:hover {
  border-color: var(--gold);
  background: var(--surface-hover);
  transform: scale(1.05);
}
.profile-initial {
  font-size: 16px;
  /* line-height: 1 suppresses the default line spacing of the font, which would
     otherwise shift the character upward. Special Elite (typewriter font) has
     additional whitespace at the top of the glyph – a slight translateY
     compensates this visually inside the circle. */
  line-height: 1;
  display: inline-block;
  transform: translateY(1px);
}
.profile-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--surface-1-strong);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  min-width: 180px;
  z-index: 1000;
  box-shadow: 0 4px 16px rgba(0,0,0,.6);
  backdrop-filter: blur(4px);
}
.profile-dropdown-header { padding: 10px 14px; border-bottom: 1px solid var(--border-soft); font-size: 13px; color: var(--heading); }
.profile-dropdown-item {
  display: block; padding: 8px 14px;
  color: var(--old-paper);
  text-decoration: none;
  font-size: 13px;
  background: none;
  border: none;
  width: 100%;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
}
.profile-dropdown-item:hover { background: rgba(200,146,42,.1); color: var(--gold); }
.profile-dropdown-divider { height: 1px; background: rgba(200,146,42,.15); margin: 4px 0; }
/* Prevents double borders when the divider comes directly after the header or
   in-game banner (e.g. in the guest menu without profile/admin items before it) -
   both predecessors already have a border-bottom. */
.profile-dropdown-header + .profile-dropdown-divider,
.profile-dropdown-ingame + .profile-dropdown-divider {
  display: none;
}
/* Icons in dropdown items have different glyph widths (👤 vs ⚙).
   A fixed column keeps the text left-aligned. */
.dropdown-icon {
  display: inline-block;
  width: 20px;
  text-align: center;
  margin-right: 6px;
  font-size: 13px;
}

/* Warning banner in the profile menu when the player is in an active game */
.profile-dropdown-ingame {
  padding: 9px 14px;
  background: rgba(212, 98, 10, 0.14);
  border-bottom: 1px solid rgba(212, 146, 42, 0.3);
  border-left: 3px solid var(--gold);
  font-size: 12px;
  color: var(--bone, #ddd);
  line-height: 1.4;
}
.profile-dropdown-logout { color: #b85a4a; }

.alert-success {
  background: rgba(30,100,30,.2);
  border: 1px solid #4ade80;
  color: #4ade80;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  margin-bottom: 8px;
}

.toofew-text { color: var(--smoke); font-size: 14px; text-align: center; }

/* ── Guest indicator ────────────────────────────────────────────────────── */

.guest-mini {
  display: inline-block;
  color: #9ca3af;
  font-size: 12px;
  margin-left: 4px;
  opacity: 0.85;
}

/* ── Label + ?-Help-Button layout ──────────────────────────────────────────
   Form label with a small ? button beside it. Clicking ? opens a modal
   with brief descriptions (e.g. the game mode overview). Keeps the form
   lean while still allowing contextual lookup. */
.lbl-with-help {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.lbl-with-help .lbl {
  margin: 0;
}
.help-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;    /* WCAG 2.5.8 minimum target size */
  min-width: 24px;   /* flex containers must not shrink it below the target size */
  height: 24px;
  padding: 0;
  background: transparent;
  border: 1px solid rgba(200,146,42,.4);
  border-radius: 50%;
  color: var(--heading);
  font-size: 12px;
  font-weight: bold;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.help-icon-btn:hover {
  background: var(--surface-hover);
  border-color: var(--gold);
  color: var(--heading);
}

/* ── Mode-info modal — body classes (wrapper migrated to <Modal> component) ──── */
.mode-info-intro {
  font-size: 13px;
  margin: 0 0 18px 0;
}
/* Game rules page (/Rules): the former accordion was replaced by the
   sitewide split view (.rules-split, see the Saloon-Rahmen section). */

/* Single-game instructions (GameModeInfoModal): hero header above the GameRulesContent. */
.single-mode-hero { display: flex; align-items: center; gap: 14px; padding: 2px 0 14px;
  border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.single-mode-hero .smh-ic { font-size: 38px; line-height: 1; flex: 0 0 auto; }
.single-mode-hero .smh-name { font-family: 'Rye', serif; color: var(--heading); font-size: 21px; }
.single-mode-hero .smh-meta { font-size: 12px; color: var(--smoke); margin-top: 3px; }
.mode-info-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.mode-info-card {
  display: flex;
  gap: 14px;
  padding: 14px;
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
}
.mode-info-card.is-highlighted {
  border-color: var(--gold);
  background: rgba(200,146,42,.06);
}
.mode-info-icon {
  font-size: 32px;
  line-height: 1;
  flex-shrink: 0;
}
.mode-info-text {
  flex: 1;
}
.mode-info-name {
  font-family: 'Rye', cursive;
  font-size: 16px;
  color: var(--gold);
  margin: 0 0 6px 0;
  display: flex;
  align-items: center;
  gap: 10px;
}
.mode-info-current {
  font-size: 12px;
  color: var(--heading);
  background: rgba(200,146,42,.18);
  padding: 2px 8px;
  border-radius: 10px;
  font-weight: normal;
  letter-spacing: 0.02em;
}
.mode-info-desc {
  font-size: 13px;
  color: var(--parchment);
  margin: 0 0 6px 0;
  line-height: 1.5;
}
.mode-info-meta {
  font-size: 12px;
  color: var(--smoke);
}

/* ── Quiz mode pills (only visible when music quiz is selected) ──────────────── */
.quiz-mode-pills {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.quiz-pill {
  padding: 8px 16px;
  /* Semantic tokens: --mid-wood is a raw dark constant and stayed pitch dark in
     the light theme (found on Admin → Einrichtung); the island re-pin keeps the
     pill dark inside game surfaces. */
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  color: var(--text-main);
  border-radius: 20px;
  font-size: 13px;
  cursor: pointer;
  transition: all .15s;
  white-space: nowrap;
}
.quiz-pill:not(:disabled):hover {
  border-color: var(--accent);
  color: var(--heading);
}
.quiz-pill.selected {
  background: rgba(200,146,42,.15);
  border-color: var(--accent-strong);
  color: var(--heading);
}
/* Invalid option (e.g. answer delay >= time per track) - not selectable. */
.quiz-pill:disabled {
  opacity: .3;
  cursor: not-allowed;
  filter: grayscale(.6);
}

/* ── Profile: statistics display ────────────────────────────────────────── */
.stats-summary {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 18px;
}
.stats-summary-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 5px;
  padding: 10px 8px;
  text-align: center;
}
.stats-summary-value {
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 18px;
  margin-bottom: 2px;
}
.stats-summary-label {
  color: var(--smoke);
  font-size: 12px;
  letter-spacing: 0.05em;
}

/* Mode cards in a 2-column grid, single column on narrow screens. */
.stats-mode-grid-2col {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
@media (max-width: 560px) {
  .stats-mode-grid-2col { grid-template-columns: 1fr; }
}
.stats-mode-card {
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 12px 14px;
  margin-bottom: 0;
}
.stats-mode-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-soft);
}
.stats-mode-name {
  /* --heading instead of the raw mode accent as TEXT (mockup a11y decision +
     convention_accent_light_never_as_text — unreadable on light surfaces). */
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 15px;
}
.stats-mode-played {
  font-size: 12px;
  color: var(--smoke);
}
.stats-mode-grid {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.stats-row {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
}
.stats-row-label {
  color: var(--smoke);
}
.stats-row-value {
  color: var(--old-paper);
  font-variant-numeric: tabular-nums;
}
.stats-pct {
  color: var(--smoke);
  font-size: 12px;
  margin-left: 4px;
}

@media (max-width: 540px) {
  .stats-summary { grid-template-columns: repeat(2, 1fr); }
}

/* ── Achievement gallery (profile tab "Achievements") ────────────────── */
/* 2-column badge grid mirroring .stats-mode-grid-2col; fixed icon column. */
.ach-subheading {
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 15px;
  margin: 16px 0 8px;
}
.ach-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
@media (max-width: 560px) {
  .ach-grid { grid-template-columns: 1fr; }
}
.ach-card {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 12px 14px;
}
.ach-card.unlocked {
  border-color: var(--border-strong);
  background: var(--surface-2);
}
.ach-icon {
  font-size: 26px;
  line-height: 1.2;
  width: 34px;
  text-align: center;
  flex: 0 0 auto;
}
.ach-card.locked .ach-icon { filter: grayscale(1); opacity: 0.55; }
.ach-body { flex: 1 1 auto; min-width: 0; }
.ach-title {
  font-family: 'Rye', cursive;
  font-size: 14px;
  color: var(--heading);
}
.ach-card.locked .ach-title { color: var(--old-paper); }
.ach-desc {
  font-size: 12px;
  color: var(--smoke);
  margin-top: 2px;
  line-height: 1.35;
}
.ach-date {
  font-size: 12px;
  color: var(--smoke);
  margin-top: 6px;
}
.ach-progress {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.ach-bar {
  flex: 1 1 auto;
  height: 5px;
  background: var(--surface-2);
  border-radius: 3px;
  overflow: hidden;
}
.ach-bar-fill {
  height: 100%;
  background: var(--gold);
  border-radius: 3px;
}
.ach-progress-text {
  font-size: 12px;
  color: var(--smoke);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ── Footer (privacy policy / imprint links) ───────────────────────────────── */
.app-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 900;
  text-align: center;
  padding: 12px 16px;
  font-size: 12px;
  color: var(--text-dim);
  border-top: 1px solid var(--border-soft);
  background: var(--chrome);
  backdrop-filter: blur(6px);
}
.footer-link {
  color: var(--smoke);
  text-decoration: none;
  transition: color 0.15s;
}
.footer-link:hover {
  color: var(--gold);
}
.footer-sep {
  margin: 0 8px;
  opacity: 0.4;
}

/* ── Language dropdown (header + profile) ─────────────────────────────
   Replaces the former segmented footer switcher. Trigger = pill with the
   current flag + chevron (styled like .header-help-btn/.profile-btn);
   expanded it shows a list (flag + native name), backdrop to close. */
.lang-dd { position: relative; display: inline-flex; }
.lang-dd-trigger {
  position: relative;
  z-index: 1001;      /* above the backdrop */
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 38px;
  padding: 0 9px;
  border-radius: 19px;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  color: var(--heading);
  cursor: pointer;
  transition: all .2s;
}
.lang-dd-trigger:hover {
  border-color: var(--gold);
  background: var(--surface-hover);
}
.lang-dd-flag {
  display: block;
  height: 15px;
  width: auto;
  border-radius: 2px;
  /* Theme-aware contour ring: flag stripes that match the surface (black stripe
     of the DE flag on the dark menu, white UK areas on light surfaces) would
     otherwise melt into the background and make the flag look smaller/misaligned. */
  box-shadow: 0 0 0 1px var(--border-strong);
}
/* In the expanded list use a FIXED UNIFORM FLAG BOX (24x15 + cover) instead of a
   height-based width - otherwise names start at different x positions and the
   flags render at different heights depending on the flag's aspect ratio
   (DE 5:3 vs. UK 2:1), which reads as "not aligned". Cover crops the wider
   ratios slightly (centered), which keeps every flag recognizable. */
.lang-dd-opt .lang-dd-flag {
  width: 24px;
  height: 15px;
  object-fit: cover;
}
.lang-dd-chev {
  font-size: 12px;
  line-height: 1;
  color: var(--heading);
  transition: transform .2s;
}
.lang-dd.open .lang-dd-chev { transform: rotate(180deg); }

.lang-dd-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 170px;
  /* The footer dropup inherits .app-footer's text-align:center — the names
     would center within different leftover widths (the active row also holds
     the ✓) and end up visually staggered. */
  text-align: left;
  background: var(--surface-1-strong);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  z-index: 1000;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
  overflow: hidden;
}
.lang-dd-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  color: var(--old-paper);
  text-decoration: none;
  font-size: 13px;
}
.lang-dd-opt:hover { background: var(--surface-hover); color: var(--heading); }
.lang-dd-opt.active {
  background: rgba(200, 146, 42, 0.14);
  color: var(--heading);
}
.lang-dd-name { flex: 1; }
.lang-dd-check { color: var(--heading); font-size: 12px; }

/* Footer variant (MainLayout footer): trigger looks like a plain footer link
   (globe + native name), the menu opens UPWARD since the footer sits at the
   page bottom. Used via <LanguageDropdown Footer="true" />. */
.lang-dd-footer .lang-dd-trigger {
  height: auto;
  min-height: 24px;   /* WCAG 2.5.8 minimum target size */
  padding: 2px 4px;
  gap: 6px;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--text-dim);
  font-size: 12.5px;
}
.lang-dd-footer .lang-dd-trigger:hover { color: var(--heading); background: none; border: none; }
.lang-dd-footer .lang-dd-current { line-height: 1; }
.lang-dd-footer .lang-dd-menu {
  top: auto;
  bottom: calc(100% + 8px);
  right: auto;
  left: 50%;
  transform: translateX(-50%);
  box-shadow: 0 -6px 24px var(--shadow-color);
}

/* Profile variant: the 🌐 label sits on the left, the dropdown opens below.
   To prevent the menu from overflowing the right card edge it stays
   right-aligned to the trigger (default above). */

/* ── Legal pages (privacy policy, imprint) ───────────────────────────────── */
/* Legal pages now live inside the PageFrame board (narrow width) — the class
   only provides typography, no own container/frame anymore. */
.legal-page {
  color: var(--old-paper);
  line-height: 1.6;
}
.legal-page h2 {
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 18px;
  margin-top: 26px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-soft);
}
.legal-page h2:first-child { margin-top: 0; }
.legal-page h3 {
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 14px;
  margin-top: 18px;
}
.legal-page p { font-size: 14px; }
.legal-page ul { padding-left: 22px; font-size: 14px; }
.legal-page li { margin-bottom: 5px; }
.legal-page a {
  color: var(--heading);
  text-decoration: underline;
}
.legal-block {
  background: var(--surface-2);
  border-left: 2px solid var(--gold);
  padding: 12px 16px;
  margin: 12px 0;
}
.legal-footer {
  margin-top: 30px;
  color: var(--smoke);
  font-size: 12px;
  text-align: right;
}
/* Notice of precedence on the EN version of the legal texts. */
.legal-translation-notice {
  background: var(--surface-2);
  border-left: 2px solid var(--smoke);
  padding: 10px 14px;
  margin: 0 0 18px;
  color: var(--smoke);
  font-size: 13px;
}

/* ── Home page announcement banner ───────────────────────────────── */
.announce {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  border-radius: 5px;
  padding: 12px 16px;
  margin-bottom: 16px;
  font-size: 14px;
  line-height: 1.5;
  border-left: 4px solid;
}
.announce-icon { font-size: 18px; line-height: 1.3; flex-shrink: 0; }
.announce-body { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.announce.announce-info  { background: rgba(60,120,180,.12);  border-left-color: #5a9bd4; color: #cfe3f5; }
.announce.announce-warn  { background: rgba(212,160,30,.12);  border-left-color: var(--gold); color: #f0dca0; }
.announce.announce-error { background: rgba(139,26,26,.16);   border-left-color: #c0392a; color: #f0c0b8; }
/* Light theme: the banner texts above are LIGHT tints — unreadable on the
   light scrim. Swap to dark variants of the same level colors. */
[data-theme="light"] .announce.announce-info  { color: #1e4e78; }
[data-theme="light"] .announce.announce-warn  { color: #6a4a08; background: rgba(181, 84, 10, .12); }
[data-theme="light"] .announce.announce-error { color: #7a2338; }

/* ── Error page /Error ───────────────────────────────────────────── */
.error-page-text {
  color: var(--old-paper);
  font-size: 14px;
  line-height: 1.6;
  text-align: center;
  margin: 8px 0;
}
.error-page-hint { color: var(--smoke); font-size: 13px; }
.error-page-actions {
  display: flex;
  justify-content: center;
  margin-top: 18px;
}

/* ── Changelog / What's new ──────────────────────────────────────────────── */
/* Lives inside the PageFrame board (narrow width) — no own container anymore. */
.changelog-sub {
  color: var(--smoke);
  font-size: 13px;
  margin: 0 0 26px;
}
.changelog-empty {
  color: var(--smoke);
  font-style: italic;
  padding: 12px 0;
}
.changelog-timeline {
  margin-top: 4px;
}
.cl-entry {
  position: relative;
  padding: 0 0 22px 22px;
  border-left: 2px solid rgba(200, 146, 42, 0.25);
  margin-left: 6px;
}
.cl-entry:last-child {
  border-left-color: transparent;
  padding-bottom: 0;
}
.cl-entry::before {
  content: '';
  position: absolute;
  left: -7px;
  top: 4px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 3px #14100c;
}
.cl-entry.latest::before {
  background: var(--amber);
  box-shadow: 0 0 0 3px #14100c, 0 0 10px rgba(212, 98, 10, 0.6);
}
.cl-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.cl-version {
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 16px;
}
.cl-badge-new {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #f0a060;
  border: 1px solid rgba(212, 98, 10, 0.5);
  background: rgba(212, 98, 10, 0.12);
  border-radius: 10px;
  padding: 1px 8px;
}
.cl-date {
  color: var(--smoke);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  margin-left: auto;
}
.cl-entry-title {
  color: var(--parchment);
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 8px;
}
.cl-body {
  color: var(--old-paper);
  font-size: 13.5px;
  line-height: 1.6;
}
.cl-body strong { color: var(--heading); font-weight: 600; }
.cl-body ul { margin: 4px 0 12px; padding-left: 20px; }
.cl-body li { margin: 3px 0; }
.cl-body p { margin: 6px 0; }
.cl-body a { color: var(--gold); text-decoration: underline; }
/* Headings tamed - a changelog entry already has its own title,
   a markdown H1 should not blow up the card. */
.cl-body h1, .cl-body h2, .cl-body h3, .cl-body h4 {
  font-family: 'Rye', cursive;
  color: var(--gold-light);
  margin: 10px 0 4px;
  line-height: 1.3;
}
.cl-body h1 { font-size: 16px; }
.cl-body h2 { font-size: 15px; }
.cl-body h3, .cl-body h4 { font-size: 13.5px; }
.cl-body h1:first-child, .cl-body h2:first-child, .cl-body h3:first-child { margin-top: 0; }
.cl-body code {
  font-family: 'Courier New', monospace;
  font-size: 12px;
  color: var(--gold-light);
  background: rgba(200, 146, 42, 0.08);
  padding: 1px 4px;
  border-radius: 2px;
}

/* ── Profile: danger zone ─────────────────────────────────────────────── */
.profile-danger-title {
  color: var(--danger) !important;
}
.btn-flex1 { flex: 1; }

/* ── Player name clickable ───────────────────────────────────────────────── */
.p-name-clickable {
  cursor: pointer;
  transition: color 0.15s;
  text-decoration: underline;
  text-decoration-color: rgba(200, 146, 42, 0.25);
  text-underline-offset: 3px;
}
.p-name-clickable:hover {
  color: var(--gold-ink);
  text-decoration-color: var(--gold-ink);
}

/* ── Player profile modal — body classes (wrapper migrated to <Modal> component) ──── */
.player-profile-info {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.player-profile-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  font-size: 13px;
  border-bottom: 1px solid rgba(200, 146, 42, 0.08);
}
.player-profile-row:last-child { border-bottom: none; }
.player-profile-label {
  color: var(--smoke);
}
.player-profile-value {
  color: var(--old-paper);
  text-align: right;
}
.player-profile-banned { color: var(--danger); }
.player-profile-banned small { color: var(--text-dim); margin-left: 4px; }
.player-profile-role {
  display: inline-block;
  background: rgba(200, 146, 42, 0.12);
  border: 1px solid rgba(200, 146, 42, 0.3);
  border-radius: 3px;
  padding: 1px 6px;
  margin-left: 4px;
  font-size: 12px;
  color: var(--heading);
}
.player-profile-divider {
  border: none;
  border-top: 1px solid rgba(200, 146, 42, 0.15);
  margin: 16px 0 12px;
}
.player-profile-mod {
  background: rgba(139, 26, 26, 0.08);
  border: 1px solid rgba(139, 26, 26, 0.25);
  border-radius: 4px;
  padding: 12px;
}
.player-profile-mod .lbl {
  display: block;
  margin-bottom: 4px;
  font-size: 12px;
  color: var(--smoke);
}
.player-profile-mod .inp { margin-bottom: 10px; }
.player-profile-mod-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

/* Base of .btn-ghost-red/.btn-red was merged upward into the leading
   .btn-* definitions preserving computed values - only states not yet
   duplicated there remain here (disabled + hover background). */
.btn-ghost-red:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-red:hover { background: linear-gradient(135deg, #a02020, #6a1010); }
.btn-red:disabled { opacity: 0.5; cursor: not-allowed; }

/* ── Recent-games history in the profile (cards in .lg-games) ──────── */
.history-card-compact {
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-left-width: 4px;
  border-radius: 3px;
  padding: 10px 14px;
  font-size: 13px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.history-card-compact.history-outcome-won { border-left-color: rgba(80, 180, 80, 0.7); }
.history-card-compact.history-outcome-lost { border-left-color: rgba(180, 60, 60, 0.7); }
.history-card-compact.history-outcome-draw { border-left-color: rgba(180, 160, 80, 0.55); }

.history-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
}
.history-card-mode {
  font-family: 'Rye', cursive;
  color: var(--accent-light);
  font-size: 14px;
  letter-spacing: 0.04em;
}
.history-card-outcome {
  font-size: 13px;
  padding: 2px 8px;
  border-radius: 2px;
}
.history-outcome-won  .history-card-outcome { background: rgba(80,180,80,.12);  color: #88d088; }
.history-outcome-lost .history-card-outcome { background: rgba(180,60,60,.12);  color: #e88080; }
.history-outcome-draw .history-card-outcome { background: rgba(180,160,80,.12); color: #d8c878; }

.history-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  color: var(--smoke);
  font-size: 12px;
}
.history-card-meta > span { white-space: nowrap; }
.history-role-impostor { color: #e88080; }
.history-role-crewmate { color: #88d088; }
.history-word-inline {
  font-family: 'Rye', cursive;
  color: var(--gold);
  letter-spacing: 0.06em;
}

.history-card-coplayers {
  font-size: 12px;
  color: rgba(220, 200, 170, 0.65);
}
.history-card-label {
  color: var(--smoke);
  margin-right: 4px;
}

/* Light: the history outcome badges (won / lost / „geteilt"), the ✓/✗ result marks and the
   Schattenspiel roles use bright colors tuned for the dark card; on the pale history/modal
   they wash out. Switch to the theme's readable inks; the solo/co-player line likewise moves
   off its hardcoded pale beige. Dark keeps its calibrated tones. */
[data-theme="light"] .history-outcome-won  .history-card-outcome,
[data-theme="light"] .track-history-res.res-ok,
[data-theme="light"] .history-role-crewmate,
[data-theme="light"] .lg-wins { color: var(--success); }
[data-theme="light"] .history-outcome-lost .history-card-outcome,
[data-theme="light"] .track-history-res.res-no,
[data-theme="light"] .history-role-impostor { color: var(--danger); }
[data-theme="light"] .history-outcome-draw .history-card-outcome { color: var(--gold-ink); }
[data-theme="light"] .history-card-coplayers { color: var(--text-dim); }

/* ── Lobby grouping in profile history ──────────────────────────
   "Recent games" grouped per lobby session: collapsed headers, click lazily
   loads the games (history-card-compact, defined above) into .lg-games. */
.lobby-group-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.lobby-group {
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  overflow: hidden;
}
.lobby-group-header {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; cursor: pointer; transition: background .12s;
}
.lobby-group-header:hover { background: rgba(200, 146, 42, 0.06); }
.lg-chevron {
  color: var(--smoke); font-size: 16px; flex-shrink: 0;
  width: 14px; text-align: center; transition: transform .15s;
}
.lobby-group.open .lg-chevron { transform: rotate(90deg); color: var(--accent-light); }
/* Fixed icon zone (like .lg-chevron) so the title always starts at the same x, no matter
   whether the mode glyph is narrow (♠) or wide (⚓/🧠). */
.lg-icons { font-size: 16px; flex-shrink: 0; width: 22px; text-align: center; }
.lg-main { flex: 1; min-width: 0; }
.lg-title {
  font-family: 'Rye', cursive; color: var(--accent-ink);
  font-size: 14px; letter-spacing: .03em;
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
}
.lg-code { color: var(--smoke); font-size: 12px; letter-spacing: .04em; }
.lg-meta { display: flex; flex-wrap: wrap; gap: 6px; color: var(--smoke); font-size: 12px; margin-top: 3px; }
.lg-meta .sep { opacity: .5; }
.lg-wins { color: #88d088; }
.lg-when { flex-shrink: 0; color: var(--smoke); font-size: 12px; white-space: nowrap; }
.lg-games {
  border-top: 1px dashed rgba(200, 146, 42, 0.15);
  padding: 10px 14px 12px 32px;
  display: flex; flex-direction: column; gap: 7px;
  background: var(--surface-2);
}
.lg-loading { color: var(--smoke); font-size: 12px; font-style: italic; padding: 4px 0; }

/* ── Game detail in the profile (clickable co-players + track history) ── */
/* List cards become clickable (open the detail view). */
.history-card-clickable {
  cursor: pointer;
  position: relative;
  padding-right: 30px;
  transition: border-color .15s, transform .05s;
}
.history-card-clickable:hover { border-color: rgba(200, 146, 42, 0.4); }
.history-card-clickable:active { transform: scale(.998); }
.history-card-chevron {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--smoke);
  font-size: 18px;
  opacity: .5;
}
.history-card-clickable:hover .history-card-chevron { opacity: 1; color: var(--accent-light); }

/* Detail view (variant B: pane swap within the same modal) */
.btn-back-history {
  background: none;
  border: none;
  color: var(--accent-light);
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
  padding: 2px 0;
  margin-bottom: 12px;
}
.btn-back-history:hover { color: var(--parchment); }

.partie-detail { display: flex; flex-direction: column; }
.partie-detail-hero {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 6px;
}
.partie-detail-hero .history-card-mode { font-size: 17px; }
.partie-detail-meta { margin-bottom: 4px; }
.partie-detail-section {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed rgba(200, 146, 42, 0.18);
}
.partie-detail-sub {
  font-family: 'Rye', cursive;
  color: var(--gold);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.partie-detail-coplayers { font-size: 13px; line-height: 1.9; }
.coplayer-link {
  color: var(--gold-light);
  cursor: pointer;
  border-bottom: 1px dotted rgba(232, 184, 75, 0.45);
}
.coplayer-link:hover { color: var(--parchment); border-bottom-color: var(--parchment); }
.coplayer-guest { color: rgba(220, 200, 170, 0.55); }
.coplayer-guest-mark { font-size: 12px; opacity: .7; margin-left: 2px; }
.coplayer-sep { color: var(--smoke); }

.track-history-list { display: flex; flex-direction: column; gap: 3px; }
.track-history-row {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 9px;
  border-radius: 3px;
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  font-size: 12.5px;
}
.track-history-clickable { cursor: pointer; transition: border-color .15s, background .15s; }
.track-history-clickable:hover { border-color: rgba(200, 146, 42, 0.4); background: var(--surface-hover); }
.track-history-ord {
  color: var(--smoke);
  width: 20px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  flex: none;
}
.track-history-main { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.track-history-artist { color: var(--parchment); }
.track-history-title { color: var(--smoke); }
.track-history-genre {
  font-size: 12px;
  color: var(--smoke);
  background: rgba(200, 146, 42, 0.08);
  padding: 1px 8px;
  border-radius: 10px;
  white-space: nowrap;
  flex: none;
}
.track-history-res { width: 18px; text-align: center; font-size: 13px; flex: none; }
.track-history-res.res-ok { color: #88d088; }
.track-history-res.res-no { color: #e88080; }

/* ── Card hands in history (Durak/Skat/Doppelkopf/Poker) ── */
.hand-history-list { display: flex; flex-direction: column; gap: 6px; }
.hand-history-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 5px 2px; border-bottom: 1px solid rgba(200, 146, 42, 0.08); }
.hand-history-row:last-child { border-bottom: none; }
.hand-history-who { width: 120px; flex: 0 0 auto; font-size: 13px; color: var(--parchment); }
.hand-history-cards { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.hand-extra { display: flex; align-items: center; gap: 4px; margin-left: 6px; padding-left: 10px; border-left: 1px solid rgba(200, 146, 42, 0.18); }
.extra-lbl { font-size: 12px; color: var(--smoke); text-transform: uppercase; letter-spacing: 0.04em; }
.deal-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.deal-chip { font-size: 12px; color: var(--smoke); background: var(--surface-2); border: 1px solid var(--border); padding: 3px 11px; border-radius: 999px; cursor: pointer; transition: 0.15s; }
.deal-chip:hover { border-color: color-mix(in srgb, var(--accent) 50%, transparent); color: var(--parchment); }
.deal-chip.active { background: color-mix(in srgb, var(--accent) 24%, transparent); color: var(--heading); border-color: color-mix(in srgb, var(--accent) 55%, transparent); }

/* ── Battleship boards in history ── */
.board-history-gallery { display: flex; gap: 16px; flex-wrap: wrap; }
.board-history-item { display: flex; flex-direction: column; gap: 6px; }
.board-history-cap { font-size: 13px; color: var(--parchment); }

/* ── Memory board in history (symbol + revealer color) ── */
.mem-history-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 5px; max-width: 360px; }
.mem-history-card { aspect-ratio: 3 / 4; border-radius: 5px; display: grid; place-items: center;
  background: radial-gradient(ellipse at 30% 20%, rgba(120, 80, 35, 0.12) 0 30%, transparent 55%), linear-gradient(155deg, #f6ead0, #dec79c);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4), inset 0 0 0 2px var(--pc, #999); }
.mem-history-ic { width: 64%; height: 64%; color: #5a3a1a; }
.mem-history-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 10px; font-size: 12px; }
.mem-history-legend span { display: inline-flex; align-items: center; gap: 6px; color: var(--parchment); }
.mem-history-legend i { width: 13px; height: 13px; border-radius: 3px; display: inline-block; }

/* Discord brand accent for the OAuth button */
.btn-discord:hover {
  border-color: #5865f2;
  background: rgba(88, 101, 242, 0.12);
}
.btn-discord .oauth-icon { color: #5865f2; }

/* ── Linked accounts in the profile ──────────────────────────────────────── */
.linked-accounts {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.linked-account-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: 3px;
}
.linked-account-info {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.linked-account-name {
  color: var(--old-paper);
  font-size: 14px;
}
.linked-account-status {
  font-size: 12px;
  color: var(--success);   /* theme-aware — the old hardcoded #88d088 was unreadable in light */
}
.linked-account-status-off {
  color: var(--smoke);
}
/* Link/unlink button in the linked-account row: more compact than the
   default saloon button. Default `.btn` has width:100%, text-transform:uppercase,
   font-size:15px, letter-spacing:.12em - everything adds up to a wide
   button that wraps the info column. Trim everything to content width here. */
.linked-account-row .btn-sm-action {
  flex: 0 0 auto;
  width: auto !important;
  display: inline-block;
  padding: 5px 12px !important;
  font-size: 12px !important;

  letter-spacing: .04em !important;
  text-transform: none !important;
}
.linked-account-username {
  color: var(--smoke);   /* theme-aware secondary — no alpha, the old rgba(...,.6) washed out in both themes */
  font-style: italic;
  margin-left: 4px;
  font-size: 12px;
}

/* Steam brand accent for the OAuth button (Steam blue) */
.btn-steam:hover {
  border-color: #66c0f4;
  background: rgba(102, 192, 244, 0.12);
}
.btn-steam .oauth-icon { color: #66c0f4; }

/* ── Email verification: banner in the profile ─────────────────────────────── */
.verify-banner {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: stretch;
}
.verify-banner-text { line-height: 1.5; }
.verify-banner code {
  background: var(--surface-2);
  padding: 1px 6px;
  border-radius: 2px;
  font-size: 0.9em;
}
.alert-warning {
  background: rgba(180, 140, 30, 0.12);
  border: 1px solid rgba(220, 180, 80, 0.4);
  color: #e8c878;
  padding: 12px 14px;
  border-radius: 4px;
  margin-bottom: 14px;
  font-size: 13px;
}
.email-verified {
  color: var(--success);   /* theme-aware — hardcoded #88d088 was 4.2:1 in light */
  margin-left: 6px;
  font-weight: bold;
}
.email-unverified {
  color: var(--amber);
  margin-left: 6px;
  font-size: 12px;
}
.btn-sm {
  padding: 5px 12px;
  font-size: 12px;
  border-radius: 3px;
}

/* Genre chips (lobby music quiz settings) */
/* ── Filter bar (trigger pills) + shared panel ──
   Replaces the stacked filter-collapsible boxes. Works on desktop + mobile. */
.filterbar { display: flex; gap: 10px; flex-wrap: wrap; margin: 4px 0 2px; }
.filter-trigger {
  display: flex; align-items: center; gap: 8px; min-width: 150px; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 9px 14px; color: var(--parchment); font: inherit; text-align: left;
}
.filter-trigger:hover { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.filter-trigger.active { border-color: color-mix(in srgb, var(--accent) 60%, transparent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.filter-trigger .ft-ic { font-size: 15px; flex: 0 0 auto; }
.filter-trigger .ft-name { font-size: 13px; color: var(--parchment); }
.filter-trigger .ft-val { margin-left: auto; font-size: 12px; color: var(--smoke); }
.filter-trigger.has-sel .ft-val { color: var(--accent-light); font-weight: 600; }
.filter-trigger .ft-chev { color: var(--smoke); font-size: 12px; transition: transform .15s; flex: 0 0 auto; }
.filter-trigger.active .ft-chev { transform: rotate(180deg); }
.filter-panel {
  background: var(--surface-1); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 12px; padding: 14px; margin: 10px 0 4px;
}
.filter-panel .filter-pop-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.filter-panel .fp-title { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--gold); }
.filter-panel .fp-clear { font-size: 12px; color: var(--smoke); cursor: pointer; background: none; border: none; padding: 2px 4px; }
.filter-panel .fp-clear:hover { color: var(--accent-light); }
.filter-panel .fp-done {
  margin-top: 12px; width: 100%; padding: 8px; border-radius: var(--btn-radius); cursor: pointer; font: inherit;
  border: 1px solid var(--border); background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--parchment);
}
.filter-panel .fp-done:hover { background: color-mix(in srgb, var(--accent) 28%, transparent); }

.genre-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px;
  background: var(--surface-2);
  border-radius: 4px;
  border: 1px solid var(--border-soft);
  max-height: 140px;
  overflow-y: auto;
}
.genre-chip {
  padding: 5px 11px;
  font-size: 12px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--text-main) 55%, transparent);
  color: var(--text-main);
  cursor: pointer;
  transition: all 0.12s ease;
  font-family: inherit;
}
.genre-chip:hover {
  background: var(--surface-hover);
  border-color: var(--accent);
}
.genre-chip.selected {
  background: linear-gradient(135deg, #d4620a, #f0a020);
  border-color: #f0a020;
  color: #1a0e05;
  font-weight: 600;
}
.genre-chip-count {
  margin-left: 4px;
  padding: 1px 6px;
  font-size: 12px;
  font-weight: 400;
  background: var(--surface-2);
  border-radius: 999px;
  vertical-align: middle;
}
.genre-chip.selected .genre-chip-count {
  background: rgba(0,0,0,0.18);
}

/* Music quiz difficulty chips use their traffic-light color when active
   (A green / B gold / C red) instead of the default orange. */
.genre-chip.tier-chip-A.selected {
  background: linear-gradient(135deg, #3f8f59, #5fb87e);
  border-color: #5fb87e;
  color: #08140c;
}
.genre-chip.tier-chip-B.selected {
  background: linear-gradient(135deg, #d4880a, #f0bd20);
  border-color: #f0bd20;
  color: #1a1205;
}
.genre-chip.tier-chip-C.selected {
  background: linear-gradient(135deg, #b04535, #d4685a);
  border-color: #d4685a;
  color: #1a0a08;
}

/* ════════════════════════════════════════════════════════════════════
   MUSIKQUIZ – Spielbildschirm
   ════════════════════════════════════════════════════════════════════ */

.mq-card {
  position: relative;   /* anchor for the in-place category overlay (SS-0317) */
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Framed quiz panel: the question + answers sit in a defined card instead of floating
   on the (visually near-invisible) card-board. Both quiz games share .mq-card, so
   Musikquiz + Wissensquiz stay consistent. Saloon-gold border — never the game accent
   (panel borders rule). Overrides the generic ".card-board .card" frame-strip; the width
   still fills the main column (maximized keeps max-width:none) so the frame hugs the real
   quiz area without shrinking it. */
.card-board .card.mq-card {
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid var(--board-border);
  border-radius: 6px;
  box-shadow: var(--board-shadow);
  padding: 22px 26px;
}

/* Same Saloon-gold frame for the remaining floating game surfaces: Hangman AND
   Tabu share .hangman-word-card, Memory uses .memory-board-card. Extends the
   SS-0320 quiz treatment so nothing floats loosely on the near-invisible
   card-board. Border is Saloon gold (--board-border), never the mode accent
   (panel-borders rule); each card keeps its own padding. */
.card-board .card.hangman-word-card,
.card-board .card.memory-board-card {
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid var(--board-border);
  border-radius: 6px;
  box-shadow: var(--board-shadow);
}

.mq-question {
  color: var(--gold-ink);
  font-weight: 600;
  letter-spacing: 0.03em;
  font-size: 14px;
}

/* Music-quiz-specific header override: three-column grid instead of flex-space-between
   so the question is truly centered in the middle - even when the genre on the right is long
   (e.g. "Contemporary Blues"). Standard flex-space-between only distributes the gaps
   equally, not the center position. For Hangman/Tabu the header stays in flex mode
   (Hangman has 4 items including the report-flag button - a generic grid switch would
   break the layout there). */
.mq-card .hangman-word-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 12px;
}
.mq-card .hangman-word-progress { justify-self: start; min-width: 0; }
.mq-card .mq-question { justify-self: center; text-align: center; min-width: 0; }
.mq-card .hangman-letter-count {
  justify-self: end;
  min-width: 0;
  /* If the genre is extremely long (>30 chars), truncate elegantly with ellipsis
     instead of shifting the center. No effect in the normal case (Pop / Rock / Jazz / Blues). */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Mystery cover (large question-mark square) */
.mq-cover-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin: 8px 0;
}

.mq-mystery-cover {
  position: relative;
  width: 160px;
  height: 160px;
  background: linear-gradient(135deg, #2a1d0e 0%, #3a2614 50%, #2a1d0e 100%);
  border: 2px solid var(--accent-light);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5),
              inset 0 0 30px rgba(0,0,0,0.4),
              0 0 32px color-mix(in srgb, var(--accent) 35%, transparent);
}

.mq-mystery-cover.playing {
  animation: mq-cover-pulse 2.4s ease-in-out infinite;
}

@keyframes mq-cover-pulse {
  0%, 100% { box-shadow: 0 8px 24px rgba(0,0,0,0.5), inset 0 0 30px rgba(0,0,0,0.4), 0 0 24px color-mix(in srgb, var(--accent) 30%, transparent); }
  50%      { box-shadow: 0 8px 24px rgba(0,0,0,0.5), inset 0 0 30px rgba(0,0,0,0.4), 0 0 40px 8px color-mix(in srgb, var(--accent-light) 45%, transparent); }
}

/* Sits on the fixed dark mystery-cover artwork — pin to the raw palette. */
.mq-question-mark {
  font-size: 96px;
  font-weight: 900;
  color: var(--raw-parchment);
  text-shadow:
    0 0 24px var(--accent-light),
    0 0 48px var(--accent),
    0 2px 12px rgba(0,0,0,0.7);
  font-family: Georgia, serif;
  user-select: none;
}

/* Equalizer bars: 5 vertical bars pulsing up and down */
.mq-equalizer {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 3px;
  align-items: flex-end;
  height: 22px;
}
.mq-equalizer span {
  display: block;
  width: 4px;
  background: linear-gradient(180deg, #f0a020 0%, #d4620a 100%);
  border-radius: 2px;
  animation: mq-eq 0.9s ease-in-out infinite;
}
.mq-equalizer span:nth-child(1) { animation-delay: 0.0s;  height: 8px; }
.mq-equalizer span:nth-child(2) { animation-delay: 0.15s; height: 14px; }
.mq-equalizer span:nth-child(3) { animation-delay: 0.3s;  height: 18px; }
.mq-equalizer span:nth-child(4) { animation-delay: 0.45s; height: 14px; }
.mq-equalizer span:nth-child(5) { animation-delay: 0.6s;  height: 8px; }

@keyframes mq-eq {
  0%, 100% { transform: scaleY(0.4); }
  50%      { transform: scaleY(1.0); }
}

.mq-play-btn {
  font-size: 14px;
  padding: 10px 22px;
}
.mq-blocked-hint {
  font-size: 12px;
  color: var(--smoke);
  text-align: center;
}

/* 4 answer options in a 2x2 grid */
.mq-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 4px;
}
.mq-option {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--well);
  border: 2px solid var(--edge);
  border-radius: 8px;
  color: var(--text-main);
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  text-align: left;
  transition: all 0.15s ease;
  min-height: 56px;
}
.mq-option:hover:not(:disabled) {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  transform: translateY(-1px);
}
.mq-option:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}
.mq-option.selected {
  background: linear-gradient(135deg, rgba(212, 98, 10, 0.25), rgba(240, 160, 32, 0.18));
  border-color: var(--gold-ink);
  box-shadow: 0 0 18px rgba(212, 146, 42, 0.25);
}
.mq-option-letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(212, 146, 42, 0.25);
  border: 1px solid rgba(212, 146, 42, 0.5);
  color: var(--gold-ink);
  font-weight: 700;
  font-size: 13px;
  flex-shrink: 0;
}
.mq-option.selected .mq-option-letter {
  background: var(--gold);
  color: #1a0e05;
}
.mq-option-text {
  flex: 1;
  word-break: break-word;
  /* Max 3 lines, then ellipsis. Guards against iTunes featuring lists
     with 15+ artists (rare, but then the block is 12 lines long
     and tears the grid apart). */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.mq-answered-msg {
  margin-top: 6px;
  padding: 8px 12px;
  background: rgba(76, 175, 80, 0.12);
  border-left: 3px solid #4caf50;
  border-radius: 4px;
  color: var(--success);
  font-size: 13px;
  text-align: center;
}

/* Mobile: stack answer options in a single column */
@media (max-width: 540px) {
  .mq-options { grid-template-columns: 1fr; }
  .mq-mystery-cover { width: 130px; height: 130px; }
  .mq-question-mark { font-size: 62px; }
}

/* Music quiz volume control (in the game interface) */
.mq-volume-control {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: color-mix(in srgb, var(--well) 55%, transparent);
  border: 1px solid var(--edge);
  border-radius: 999px;
  margin-top: 4px;
}
.mq-volume-icon {
  font-size: 14px;
  user-select: none;
  width: 18px;
  text-align: center;
}
/* Input box is 24px tall (WCAG 2.5.8 minimum target size) — the visible 4px
   track is drawn by the track pseudo-elements, not the element itself. */
.mq-volume-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 140px;
  height: 24px;
  background: transparent;
  outline: none;
  cursor: pointer;
}
.mq-volume-slider::-webkit-slider-runnable-track {
  height: 4px;
  background: var(--edge-strong);
  border-radius: 2px;
}
.mq-volume-slider::-moz-range-track {
  height: 4px;
  background: var(--edge-strong);
  border-radius: 2px;
}
.mq-volume-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  margin-top: -5px;   /* center the 14px thumb on the 4px track */
  border-radius: 50%;
  background: var(--gold-ink);
  border: 1px solid rgba(8, 5, 2, 0.8);
  cursor: pointer;
}
.mq-volume-slider::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--gold-ink);
  border: 1px solid rgba(8, 5, 2, 0.8);
  cursor: pointer;
  border: 0;
}
.mq-volume-value {
  font-size: 12px;
  color: var(--smoke);
  font-variant-numeric: tabular-nums;
  min-width: 30px;
  text-align: right;
}

/* ════════════════════════════════════════════════════════════════════
   MUSIKQUIZ – in-place answer reveal + category overlay (SS-0317).
   Fully theme-based (Dark + Light); the only fixed-dark bit is the mystery
   cover artwork (see .mq-mystery-cover above, on --raw-*).
   ════════════════════════════════════════════════════════════════════ */

/* Reveal: real album cover replaces the mystery square (music keeps playing). */
.mq-reveal-cover {
  position: relative;
  width: 160px; height: 160px;
  border-radius: 12px;
  overflow: hidden;
  border: 2px solid color-mix(in srgb, var(--green-ok) 70%, transparent);
  box-shadow: 0 8px 24px rgba(0,0,0,.5),
              0 0 32px color-mix(in srgb, var(--green-ok) 35%, transparent);
  display: flex; align-items: center; justify-content: center;
}
.mq-reveal-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mq-reveal-cover-fallback {
  font-size: 60px;
  color: var(--accent-light);
  background: linear-gradient(135deg, #2a1d0e 0%, #3a2614 50%, #2a1d0e 100%);
}

/* Fixed-height slot so the options never shift between guessing and reveal. */
.mq-reveal-slot {
  min-height: 54px; width: 100%; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.mq-slot-placeholder {
  font-family: 'Rye', cursive; font-size: 20px; color: var(--smoke);
  opacity: .4; letter-spacing: .35em; user-select: none;
}
.mq-reveal-info { text-align: center; width: 100%; min-width: 0; }
/* Artist + title strictly single-line with ellipsis (some titles are very long);
   the full text stays in the DOM + the title attribute. */
.mq-reveal-artist {
  font-family: 'Rye', cursive; color: var(--heading); font-size: 24px; line-height: 1.1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.mq-reveal-title {
  font-size: 15px; color: var(--parchment); font-weight: 500; margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}

/* Reveal countdown row — same fixed height as the timer row (no shift). */
.mq-card .hangman-timer-row, .mq-card .mq-next-row { min-height: 30px; }
.mq-next-row {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 14px; color: var(--smoke);
}
.mq-next-num {
  font-family: 'Rye', cursive; font-size: 22px; color: var(--heading);
  font-variant-numeric: tabular-nums;
}

/* Option reveal states: correct = green, wrong = faded, own wrong pick keeps its gold rim. */
.mq-card.reveal .mq-option { transition: opacity .25s ease, background .25s ease, border-color .25s ease; }
.mq-card.reveal .mq-option.correct {
  background: color-mix(in srgb, var(--green-ok) 16%, transparent);
  border-color: color-mix(in srgb, var(--green-ok) 75%, transparent);
  box-shadow: 0 0 22px color-mix(in srgb, var(--green-ok) 30%, transparent);
  opacity: 1;
}
.mq-card.reveal .mq-option.correct .mq-option-letter {
  background: var(--green-ok); border-color: var(--green-ok); color: #eafff0;
}
.mq-card.reveal .mq-option:not(.correct) { opacity: .35; filter: saturate(.4); }
.mq-card.reveal .mq-option.selected:not(.correct) { opacity: .55; border-color: var(--gold-ink); }
.mq-correct-check { margin-left: auto; color: var(--success); font-size: 18px; font-weight: 700; }

/* Category overlay — sits INSIDE the card (not a full-screen overlay, so the
   z-index ≥ 1000 rule does not apply). Saloon-gold panel border; the mode accent
   appears only as a veil behind the panel. */
.mq-cat-overlay {
  position: absolute; inset: 0; z-index: 5;
  background: var(--scrim); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  border-radius: inherit;
  opacity: 0; pointer-events: none; transition: opacity .35s ease;
}
.mq-cat-overlay.show { opacity: 1; pointer-events: auto; }
.mq-cat-panel {
  position: relative; text-align: center; padding: 28px 42px 24px;
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid var(--board-border); border-radius: 6px; box-shadow: var(--board-shadow);
  max-width: 85%;
  transform: translateY(10px) scale(.96); transition: transform .35s ease;
}
.mq-cat-overlay.show .mq-cat-panel { transform: translateY(0) scale(1); }
.mq-cat-panel::before {
  content: ''; position: absolute; inset: -12px;
  background: radial-gradient(ellipse at center 40%, var(--accent) 0%, transparent 65%);
  opacity: .28; filter: blur(12px); pointer-events: none; z-index: 0; border-radius: inherit;
}
.mq-cat-panel > * { position: relative; z-index: 1; }
.mq-cat-eyebrow {
  font-size: 14px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--smoke); margin-bottom: 10px;
}
.mq-cat-icon { font-size: 44px; line-height: 1; margin-bottom: 8px; display: block; }
.mq-cat-name { font-family: 'Rye', cursive; color: var(--heading); font-size: 40px; line-height: 1.1; }
.mq-cat-sub { margin-top: 10px; font-size: 14px; color: var(--parchment); }
.mq-cat-count {
  font-family: 'Rye', cursive; color: var(--heading); font-size: 26px;
  font-variant-numeric: tabular-nums; display: inline-block; min-width: 1.2em;
}
.mq-cat-gate { margin-top: 14px; font-size: 12px; color: var(--smoke); }
/* Countdown reached 0 but the server is still preparing the next track — pulse so
   it reads as an intentional "starting" beat, not a frozen "0 s". */
.mq-cat-starting { animation: mq-cat-pulse 1.1s ease-in-out infinite; }
@keyframes mq-cat-pulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

/* Still-loading stragglers in the overlay (compact chips; capped in markup, like the
   old break/intro ready list). */
.mq-cat-loading { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border-faint); }
.mq-cat-loading-label { display: block; font-size: 12px; color: var(--smoke); margin-bottom: 7px; }
.mq-cat-loading-list { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; max-width: 340px; }
.mq-cat-loading-chip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--parchment);
  background: var(--well); border: 1px solid var(--border-faint); border-radius: 999px; padding: 3px 10px;
}
.mq-cat-loading-more { display: inline-flex; align-items: center; font-size: 12px; color: var(--smoke); padding: 3px 4px; }

/* Intro (Song 1): first-category badge under the title. */
.mqi-category {
  display: inline-flex; align-items: center; gap: 10px; padding: 10px 22px;
  border-radius: 6px; background: var(--well); border: 1px solid var(--board-border);
  position: relative;
}
.mqi-category::before {
  content: ''; position: absolute; inset: -8px;
  background: radial-gradient(ellipse at center, var(--accent) 0%, transparent 70%);
  opacity: .25; filter: blur(10px); pointer-events: none; border-radius: inherit;
}
.mqi-category > * { position: relative; }
.mqi-category-label { font-size: 13px; color: var(--smoke); text-transform: uppercase; letter-spacing: .18em; }
.mqi-category-name { font-family: 'Rye', cursive; font-size: 24px; color: var(--heading); }
.mqi-category-icon { font-size: 24px; }

/* Sidebar per-round point-gain chip (reveal). */
.sidebar-player-delta {
  font-size: 12px; font-weight: 700; color: var(--success);
  background: color-mix(in srgb, var(--green-ok) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--green-ok) 50%, transparent);
  border-radius: 10px; padding: 1px 8px; font-variant-numeric: tabular-nums;
}

/* Apple Music deep link in the music quiz break + podium */
.apple-music-link {
  display: inline-block;
  margin-top: 10px;
  padding: 5px 12px;
  font-size: 12px;
  color: var(--smoke);
  text-decoration: none;
  border: 1px solid var(--edge-strong);
  border-radius: 999px;
  transition: all 0.15s ease;
}
.apple-music-link:hover {
  color: var(--gold-ink);
  border-color: var(--gold-ink);
  background: rgba(212,98,10,0.08);
}
.apple-music-link-inline {
  margin-left: 6px;
  font-size: 12px;
  text-decoration: none;
  opacity: 0.55;
  transition: opacity 0.12s ease;
}
.apple-music-link-inline:hover {
  opacity: 1;
}

/* Clickable settings values (e.g. "13 categories ›") */
.settings-value-link {
  color: var(--heading);
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  cursor: pointer;
  text-align: right;
  text-decoration: underline dotted rgba(212,98,10,0.4);
  text-underline-offset: 3px;
  transition: color 0.12s ease;
}
.settings-value-link:hover {
  color: var(--gold-ink);
  text-decoration-color: var(--gold-ink);
}

/* Modal for category filter overview (small popup) */
.category-filter-modal {
  max-width: 420px;
  width: 90%;
  margin: 0 auto;
  padding: 0;
}
.category-filter-modal-body {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 16px 18px 20px;
}

/* ── Dual-range slider ─────────────────────────────────────────
   Year filter "from-to" as a single bar with two thumbs instead of two rows.
   Technique: two congruent <input type=range> stacked on top of each other, both
   pointer-events:none - only the thumbs are clickable (pointer-events:auto).
   The colored fill (.dr-fill) between the thumbs is positioned via inline style
   from the current values. */
.dual-range-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.dual-range-row .dr-rowlabel {
  width: 60px;
  flex-shrink: 0;
  font-size: 13px;
  color: var(--parchment);
}
.dual-range-wrap { flex: 1; min-width: 0; }
.dual-range {
  position: relative;
  height: 22px;
  display: flex;
  align-items: center;
}
.dual-range .dr-track {
  position: absolute;
  left: 0; right: 0;
  height: 4px;
  border-radius: 2px;
  background: var(--edge-strong);
}
.dual-range .dr-fill {
  position: absolute;
  height: 4px;
  border-radius: 2px;
  background: var(--gold-ink);
}
.dual-range input[type="range"] {
  position: absolute;
  left: 0; right: 0;
  width: 100%;
  margin: 0;
  height: 22px;
  appearance: none;
  -webkit-appearance: none;
  background: none;
  pointer-events: none;   /* track inert - only the thumbs receive input */
}
.dual-range input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--heading);
  border: 2px solid var(--ink);
  cursor: pointer;
  pointer-events: auto;
}
.dual-range input[type="range"]::-moz-range-thumb {
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--heading);
  border: 2px solid var(--ink);
  cursor: pointer;
  pointer-events: auto;
}
.dual-range input[type="range"]::-moz-range-track { background: none; }
/* z-index layering: "to" sits on top of "from" by default. When "from" is in the
   upper half (thumbs close together near the right edge), "from" comes on top,
   otherwise it would remain unreachable under the "to" thumb. */
.dual-range .dr-from { z-index: 3; }
.dual-range .dr-to   { z-index: 4; }
.dual-range .dr-from.dr-from-top { z-index: 5; }
.dual-range-vals {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--smoke);
  font-variant-numeric: tabular-nums;
  margin-top: 1px;
}

/* ── Music quiz: voting delay ───────────────────────────────────────────── */
/* Answer buttons are disabled for the first N seconds (see MusicQuizPlaying).
   We show the usual "disabled" appearance plus a subtle hint below. */
.mq-options-locked {
  position: relative;
}
.mq-options-locked .mq-option {
  filter: blur(0.3px);
}
.mq-lock-hint {
  margin-top: 8px;
  text-align: center;
  font-size: 13px;
  color: var(--smoke, #a89784);
  letter-spacing: .04em;
  padding: 6px;
  background: color-mix(in srgb, var(--well) 44%, transparent);
  border-radius: 2px;
}
.mq-lock-hint strong {
  color: var(--gold-ink);
}

/* ── Break-screen stage (shared: music quiz, Hangman, Tabu) ────────────────
   Hero stage card with mode glow + score strip + countdown badge top-right.
   Introduced for music quiz, generalised for Hangman + Tabu.
   Free of the old `.break-title/-subtitle/.card-break/.countdown-*` classes
   (those remain for CountdownScreen/TooFewPlayersScreen). Mode-specific
   content (word, explainer pill) via `.break-stage-hero-*`. */
.break-stage {
  position: relative;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  /* Top padding 48 px instead of 28 px: makes room for the absolutely positioned
     countdown badge top-right (top:14 + ~26 px height = ends at y:40),
     so long hero content (e.g. "STEUERBERATER" at full width) does not
     run underneath the badge. */
  padding: 48px 32px 22px;
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid var(--board-border);
  border-radius: 6px;
  box-shadow: var(--board-shadow);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
}
.break-stage::before {
  content: '';
  position: absolute;
  inset: -14px;
  background: radial-gradient(ellipse at center 45%, var(--accent) 0%, transparent 60%);
  opacity: .22;
  filter: blur(10px);
  pointer-events: none;
  z-index: 0;
  border-radius: inherit;
}
.break-stage > * { position: relative; z-index: 1; }

/* Countdown badge: compact top-right, instead of a lonely large number at the bottom of the screen */
.break-stage-countdown {
  position: absolute;
  top: 14px;
  right: 18px;
  color: var(--smoke);
  font-size: 13px;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  z-index: 2;
}
.break-stage-countdown-num {
  font-family: 'Rye', cursive;
  color: var(--accent-ink);
  font-size: 22px;
  font-variant-numeric: tabular-nums;
}

/* Score strip: all players as horizontal pills, visually separated at the top */
.break-stage-scores {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 4px;
  padding-top: 14px;
  border-top: 1px solid var(--border-faint);
  width: 100%;
}
.break-stage-score {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  background: var(--well);
  border: 1px solid var(--border-soft);
  border-radius: 22px;
  font-size: 13px;
  color: var(--parchment);
}
.break-stage-score.correct {
  border-color: rgba(45,122,74,.5);
  background: rgba(45,122,74,.1);
}
.break-stage-score.wrong { opacity: .65; }
.break-stage-score-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--smoke);
  flex-shrink: 0;
}
.break-stage-score.correct .break-stage-score-dot { background: var(--green-ok); }
.break-stage-score-name { font-weight: 500; }
.break-stage-score-pts {
  color: var(--heading);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.break-stage-score.wrong .break-stage-score-pts {
  color: var(--smoke);
  font-weight: 400;
}
.break-stage-empty {
  color: var(--smoke);
  font-style: italic;
  font-size: 14px;
  padding: 10px 0;
}

/* ── Track-ready display (preparation screen + break gate) ──────── */
.mq-ready {
  margin-top: 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.mq-ready-title { font-size: 14px; color: var(--smoke); }
.mq-ready-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: min(320px, 80vw);
}
.mq-ready-row {
  display: grid;
  grid-template-columns: 18px 1fr auto;
  gap: 10px;
  align-items: center;
  font-size: 14px;
  padding: 7px 12px;
  border-radius: 4px;
  background: var(--well);
  border: 1px solid transparent;
}
.mq-ready-row.ready { border-color: rgba(45, 122, 74, .4); background: rgba(45, 122, 74, .10); }
.mq-ready-name {
  text-align: left;
  color: var(--parchment);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mq-ready-state { font-size: 12px; }
.mq-ready-state.ok { color: var(--success); font-weight: 600; }
.mq-ready-state.wait { color: var(--smoke); }
/* Dot: green checkmark when ready, spinning ring when loading */
.mq-ready-dot { width: 16px; height: 16px; border-radius: 50%; display: inline-block; }
.mq-ready-dot.ok { background: var(--green-ok); position: relative; }
.mq-ready-dot.ok::after {
  content: '✓';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: #fff;
  font-weight: bold;
}
.mq-ready-dot.wait {
  border: 2px solid color-mix(in srgb, var(--border-strong) 67%, transparent);
  border-top-color: var(--heading);
  animation: spin .8s linear infinite;
}

/* ── RoleReveal indicator - subtle loading dots instead of a countdown number ───────────
   The role screen no longer has a ticking timer; it starts automatically after a short
   display (or in the music quiz, once everyone is ready). These three
   pulsing dots signal "starting soon" without a hard number. */
.rr-dots { display: flex; gap: 8px; justify-content: center; margin-top: 18px; }
.rr-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent-ink);
  box-shadow: 0 0 8px var(--accent-light);
  animation: dotPulse 1.4s ease-in-out infinite;
}
.rr-dot:nth-child(2) { animation-delay: .2s; }
.rr-dot:nth-child(3) { animation-delay: .4s; }

/* ── Shared intro frame (game-start 3D intros) ───────────────────────────
   Shared "stage": a framed window in which the saloon swing doors open in 3D
   and reveal the game-specific scene (ChildContent). Used by
   <Game>Intro.razor via <GameIntroFrame>. Pure CSS 3D, no 3D lib; in a
   fixed frame (not over the full viewport) so the app header/layout stays calm.
   Each scene hooks into --accent/--accent-light via the mode-* class. */
.gintro-frame {
  position: relative;
  width: min(440px, 90vw);
  height: 300px;
  margin: 0 auto 6px;
  perspective: 1100px;
  border-radius: 10px;
  overflow: hidden;
  background: #140e07;
  border: 2px solid #3a2a14;
  box-shadow: inset 0 0 90px rgba(0, 0, 0, .85);
}
.gintro-scene {
  position: absolute; inset: 0; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px;
}
.gintro-title {
  font-family: 'Rye', cursive; font-size: 26px; letter-spacing: 1px;
  color: var(--accent-light); text-shadow: 0 0 20px currentColor;
  opacity: 0; animation: gintroTtl .5s ease-out 1.4s forwards;
}
@keyframes gintroTtl { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
/* Shared soft fade-in (opacity only - does not conflict with baseline transforms). */
@keyframes gintroFade { from { opacity: 0; } to { opacity: 1; } }
.gintro-door {
  position: absolute; top: 0; height: 100%; width: 50%; z-index: 4;
  background: #4a3018;
  background-image: repeating-linear-gradient(180deg, #4a3018 0, #4a3018 22px, #33210f 23px, #4a3018 24px);
  box-shadow: inset 0 0 40px rgba(0, 0, 0, .55);
}
.gintro-door::after {
  content: ""; position: absolute; top: 30%; left: 16%; right: 16%; height: 38%;
  border: 3px solid #251708; border-radius: 3px; opacity: .5;
}
.gintro-door-l {
  left: 0; transform-origin: 0% 50%; border-right: 2px solid #1c1208;
  animation: gintroDoorL 1.15s cubic-bezier(.5, 0, .25, 1) .25s forwards;
}
.gintro-door-r {
  right: 0; transform-origin: 100% 50%; border-left: 2px solid #1c1208;
  animation: gintroDoorR 1.15s cubic-bezier(.5, 0, .25, 1) .25s forwards;
}
@keyframes gintroDoorL { from { transform: rotateY(0); } to { transform: rotateY(-115deg); } }
@keyframes gintroDoorR { from { transform: rotateY(0); } to { transform: rotateY(115deg); } }
/* Reduced-motion: doors statically OPEN (otherwise they would stay closed and
   cover the scene); title visible. Per-game scene stops further below. */
@media (prefers-reduced-motion: reduce) {
  .gintro-door-l { transform: rotateY(-115deg); animation: none; }
  .gintro-door-r { transform: rotateY(115deg); animation: none; }
  .gintro-title { opacity: 1; animation: none; }
}

/* ── Music quiz scene - spinning vinyl record + music notes ──────────────────────────── */
.mqi-disc-wrap {
  position: relative; width: 140px; height: 140px;
  opacity: 0; animation: mqiUp .6s ease-out .7s forwards;
}
@keyframes mqiUp { from { opacity: 0; transform: translateY(60px); } to { opacity: 1; transform: none; } }
.mqi-disc {
  position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle, #1a130b 0 30%, #241a0d 30% 100%);
  border: 3px solid #0c0a07;
  transform: rotateX(56deg);
  animation: mqiSpin 1.6s linear 1.3s infinite;
  box-shadow: 0 14px 30px rgba(0, 0, 0, .5);
}
.mqi-disc-label {
  position: absolute; inset: 38%; border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 3px #0c0a07, 0 0 14px var(--accent-light);
}
.mqi-disc-shine {
  position: absolute; inset: 0; border-radius: 50%;
  border-top: 2px solid rgba(232, 184, 75, .25);
}
@keyframes mqiSpin {
  from { transform: rotateX(56deg) rotateZ(0); }
  to   { transform: rotateX(56deg) rotateZ(360deg); }
}
.mqi-note {
  position: absolute; font-size: 22px; color: var(--accent-light); opacity: 0;
  text-shadow: 0 0 12px rgba(214, 92, 120, .6); pointer-events: none;
}
.mqi-note1 { left: 58%; top: 42%; animation: mqiNote 1.8s ease-out 1.6s infinite; }
.mqi-note2 { left: 62%; top: 50%; animation: mqiNote 1.8s ease-out 2.2s infinite; }
.mqi-note3 { left: 54%; top: 46%; animation: mqiNote 1.8s ease-out 2.8s infinite; }
@keyframes mqiNote {
  0%   { opacity: 0; transform: translate(0, 0) scale(.5); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(60px, -80px) scale(1.1); }
}
@media (prefers-reduced-motion: reduce) {
  .mqi-disc-wrap { opacity: 1; animation: none; }
  .mqi-disc { animation: none; }
  .mqi-note1, .mqi-note2, .mqi-note3 { opacity: 0; animation: none; }
}

/* ── Battleship scene - ship on a tilted water grid + crosshair ───────── */
.ssi-sky {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 38%, #16324d 0, #0c1420 70%);
}
.ssi-water {
  position: absolute; left: -30%; right: -30%; bottom: -20px; height: 150px;
  background:
    repeating-linear-gradient(90deg, transparent 0 32px, rgba(77, 126, 171, .45) 32px 33px),
    repeating-linear-gradient(0deg,  transparent 0 24px, rgba(77, 126, 171, .35) 24px 25px);
  transform: perspective(280px) rotateX(62deg); transform-origin: bottom center;
  opacity: 0; animation: ssiWater .8s ease-out .9s forwards;
}
@keyframes ssiWater { from { opacity: 0; } to { opacity: .85; } }
.ssi-ship {
  position: absolute; left: 50%; top: 42%; width: 120px; height: 64px; margin-left: -60px;
  color: #9cc3e8; filter: drop-shadow(0 0 14px rgba(77, 126, 171, .6));
  opacity: 0; transform-origin: 50% 80%;
  animation: ssiShipIn .5s ease-out 1.4s forwards, ssiRock 2.4s ease-in-out 1.9s infinite;
}
@keyframes ssiShipIn { from { opacity: 0; transform: translateY(16px) rotate(-6deg); } to { opacity: 1; transform: none; } }
@keyframes ssiRock { 0%, 100% { transform: rotate(-6deg) translateY(0); } 50% { transform: rotate(6deg) translateY(-4px); } }
.ssi-cross {
  position: absolute; left: 60%; top: 26%; width: 58px; height: 58px;
  color: var(--gold-light);
  opacity: 0; animation: ssiCross .6s ease-out 1.7s forwards, ssiSweep 3.4s ease-in-out 2.3s infinite;
}
@keyframes ssiCross { from { opacity: 0; transform: scale(1.6) rotate(-40deg); } to { opacity: .9; transform: none; } }
@keyframes ssiSweep { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(-90px, 30px); } }
.ssi-title-pos { position: absolute; left: 0; right: 0; bottom: 16px; text-align: center; }
@media (prefers-reduced-motion: reduce) {
  .ssi-water { opacity: .85; animation: none; }
  .ssi-ship { opacity: 1; animation: none; }
  .ssi-cross { opacity: .9; animation: none; }
}

/* ── Shadow Play scene — spotlight + role figure (Reveal integrated) ─────── */
.schi-spot {
  position: absolute; top: -40px; left: 50%; width: 210px; height: 300px; margin-left: -105px;
  background: radial-gradient(ellipse at top, rgba(154, 90, 138, .30), transparent 70%);
  opacity: 0; transform-origin: top center;
  animation: schiSpot 2.6s ease-in-out 1.1s forwards;
}
@keyframes schiSpot {
  0%   { opacity: 0; transform: rotate(-20deg); }
  35%  { opacity: .6; }
  100% { opacity: .45; transform: rotate(12deg); }
}
.schi-figwrap { transform: scale(.72); opacity: 0; animation: gintroFade .5s ease-out 1.4s forwards; }
.schi-title-imp { color: var(--red-light); }
.schi-cat { margin-top: 14px; }
@media (prefers-reduced-motion: reduce) {
  .schi-spot { opacity: .45; animation: none; }
  .schi-figwrap { opacity: 1; animation: none; }
}

/* ── Hangman scene — gallows builds up + letter slots ───────────────────── */
.hmi-gallows { position: relative; width: 150px; height: 140px; }
.hmi-plank { position: absolute; background: var(--accent-light); border-radius: 2px; }
.hmi-base { bottom: 0; left: 14px; width: 92px; height: 8px; transform-origin: left center; animation: hmiGrow .35s ease-out 1.3s backwards; }
.hmi-post { bottom: 0; left: 28px; width: 8px; height: 132px; transform-origin: bottom center; animation: hmiGrow .35s ease-out 1.65s backwards; }
.hmi-beam { top: 8px; left: 28px; width: 80px; height: 8px; transform-origin: left center; animation: hmiGrow .35s ease-out 2.0s backwards; }
.hmi-rope { top: 14px; left: 100px; width: 3px; height: 30px; background: #cdb98f; transform-origin: top center; animation: hmiGrow .35s ease-out 2.3s backwards; }
@keyframes hmiGrow { from { transform: scale(0); } to { transform: scale(1); } }
.hmi-slots { display: flex; gap: 7px; }
.hmi-slots span { width: 24px; height: 30px; border-bottom: 3px solid var(--accent-light); opacity: 0; animation: gintroFade .3s ease-out forwards; }
.hmi-slots span:nth-child(1) { animation-delay: 2.5s; }
.hmi-slots span:nth-child(2) { animation-delay: 2.62s; }
.hmi-slots span:nth-child(3) { animation-delay: 2.74s; }
.hmi-slots span:nth-child(4) { animation-delay: 2.86s; }
.hmi-slots span:nth-child(5) { animation-delay: 2.98s; }
@media (prefers-reduced-motion: reduce) {
  .hmi-plank { animation: none; }
  .hmi-slots span { opacity: 1; animation: none; }
}

/* ── Taboo scene — red "TABU" stamp slams down ─────────────────────────────── */
.tbi-stamp {
  font-family: 'Rye', cursive; font-size: 46px; letter-spacing: 3px;
  color: var(--red-light); border: 4px solid var(--red-light); border-radius: 8px;
  padding: 10px 26px; box-shadow: 0 0 26px rgba(192, 53, 42, .35);
  opacity: 0; transform: rotate(-8deg) scale(2.4);
  animation: tbiStamp .45s cubic-bezier(.2, 1.5, .4, 1) 1.5s forwards;
}
@keyframes tbiStamp {
  from { opacity: 0; transform: rotate(-8deg) scale(2.4); }
  to   { opacity: 1; transform: rotate(-8deg) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .tbi-stamp { opacity: 1; transform: rotate(-8deg) scale(1); animation: none; }
}

/* ── Knowledge Quiz scene — rotating question mark ─────────────────────────────── */
.wqi-qmark {
  font-family: 'Rye', cursive; font-size: 104px; line-height: 1;
  color: var(--accent-light); filter: drop-shadow(0 0 10px currentColor);
  opacity: 0;
  animation: wqiSpin .9s cubic-bezier(.2, 1, .3, 1) 1.3s forwards, wqiGlow 1.8s ease-in-out 2.3s infinite;
}
@keyframes wqiSpin { from { opacity: 0; transform: rotateY(540deg) scale(.2); } to { opacity: 1; transform: rotateY(0) scale(1); } }
@keyframes wqiGlow { 0%, 100% { filter: drop-shadow(0 0 8px currentColor); } 50% { filter: drop-shadow(0 0 22px currentColor); } }
@media (prefers-reduced-motion: reduce) {
  .wqi-qmark { opacity: 1; transform: none; animation: none; }
}

/* ── Memory scene — card grid flips in staggered sequence ─────────────────────────── */
.mmi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; perspective: 700px; }
.mmi-card {
  width: 46px; height: 60px; border-radius: 6px; position: relative;
  background: var(--accent); border: 1px solid var(--accent-light);
  transform: rotateY(180deg); backface-visibility: hidden;
  box-shadow: 0 4px 10px rgba(0, 0, 0, .4);
  animation: mmiFlip .5s ease-out forwards;
}
.mmi-card::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 14px; height: 14px;
  margin: -7px 0 0 -7px; border-radius: 50%; background: rgba(255, 255, 255, .14);
}
.mmi-card:nth-child(1) { animation-delay: 1.4s; }
.mmi-card:nth-child(2) { animation-delay: 1.55s; }
.mmi-card:nth-child(3) { animation-delay: 1.7s; }
.mmi-card:nth-child(4) { animation-delay: 1.85s; }
.mmi-card:nth-child(5) { animation-delay: 2.0s; }
.mmi-card:nth-child(6) { animation-delay: 2.15s; }
@keyframes mmiFlip { from { transform: rotateY(180deg); } to { transform: rotateY(0); } }
@media (prefers-reduced-motion: reduce) { .mmi-card { transform: rotateY(0); animation: none; } }

/* ── Durak scene — card deck fans out ─────────────────────────────────────── */
.dki-fan { position: relative; width: 170px; height: 130px; }
.dki-card {
  position: absolute; bottom: 6px; left: 63px; width: 44px; height: 64px;
  border-radius: 6px; background: #f4eedd; border: 1px solid #b8a98a;
  box-shadow: 0 5px 14px rgba(0, 0, 0, .5); transform-origin: bottom center;
  opacity: 0; animation: dkiFan .55s cubic-bezier(.2, 1.1, .4, 1) forwards;
}
.dki-card::after { content: "♠"; position: absolute; top: 4px; left: 6px; font-size: 13px; color: var(--accent); }
.dki-card:nth-child(1) { --r: -44deg; animation-delay: 1.4s; }
.dki-card:nth-child(2) { --r: -22deg; animation-delay: 1.55s; }
.dki-card:nth-child(3) { --r: 0deg;   animation-delay: 1.7s; }
.dki-card:nth-child(4) { --r: 22deg;  animation-delay: 1.85s; }
.dki-card:nth-child(5) { --r: 44deg;  animation-delay: 2.0s; }
@keyframes dkiFan {
  from { opacity: 0; transform: rotate(0) translateY(40px); }
  to   { opacity: 1; transform: rotate(var(--r)) translateY(-6px); }
}
@media (prefers-reduced-motion: reduce) { .dki-card { opacity: 1; animation: none; } }

/* Meta-Caption (shared, small smoke color beneath the hero element) */
.break-stage-meta {
  font-size: 13px;
  color: var(--smoke);
  margin-top: -4px;
}

/* ── Hangman break: large word as stage hero ────────────────────────── */
.break-stage-hero-word {
  font-family: 'Rye', cursive;
  color: var(--accent-ink);
  font-size: 40px;
  letter-spacing: .12em;
  margin: 8px 0 0;
  line-height: 1.1;
  text-shadow: 0 0 24px color-mix(in srgb, var(--accent-light) 35%, transparent);
  word-break: break-word;
}

/* ── Taboo break: explainer pill + words list ───────────────────────────── */
.break-stage-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 14px;
  background: var(--surface-2);
  border: 1px solid color-mix(in srgb, var(--border-strong) 89%, transparent);
  border-radius: 20px;
  color: var(--heading);
  font-size: 13px;
}
.break-stage-pill strong { font-weight: 600; }

.break-stage-words {
  width: 100%;
  background: var(--well);
  border: 1px solid var(--border-faint);
  border-radius: 5px;
  padding: 10px 16px;
}
.break-stage-words-head {
  font-size: 12px;
  color: var(--smoke);
  margin-bottom: 6px;
  text-align: center;
}
.break-stage-words-head strong { color: var(--heading); font-weight: 600; }
.break-stage-word-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 7px 0;
  border-bottom: 1px solid var(--border-faint);
  font-size: 14px;
}
.break-stage-word-row:last-child { border-bottom: none; }
.break-stage-word-row.skipped { opacity: .55; }
.break-stage-word-row.skipped .break-stage-word-text { color: var(--smoke); }
.break-stage-word-text {
  font-family: 'Rye', cursive;
  color: var(--accent-ink);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.break-stage-word-arrow { color: var(--smoke); margin: 0 6px; }
.break-stage-word-guesser { color: var(--parchment); font-weight: 500; }
.break-stage-skip-tag {
  font-size: 12px;
  color: var(--smoke);
  background: color-mix(in srgb, var(--text-dim) 10%, transparent);
  padding: 1px 8px;
  border-radius: 10px;
  text-transform: uppercase;
  letter-spacing: .04em;
}

/* Mobile portrait: cover/hero smaller, padding more compact, countdown closer to edge */
@media (max-width: 540px) {
  .break-stage { padding: 38px 18px 18px; max-width: 100%; }
  .break-stage-countdown { top: 10px; right: 12px; font-size: 12px; }
  .break-stage-countdown-num { font-size: 18px; }
  .break-stage-hero-word { font-size: 32px; letter-spacing: .08em; }
  .break-stage-words { padding: 8px 12px; }
  .break-stage-word-row { font-size: 13px; }
}

/* ── Filter chips: stale state for cross-filter counts ─────────────────── */
/* When a category/language is currently reduced to 0 tracks by the other axis
   (e.g. 'Schlager' + 'English'), the chip remains visible — greyed out and
   disabled so the user understands the combination rather than being confused
   about where the option went. */
.genre-chip.stale {
  opacity: 0.55;
  color: var(--smoke);
  border-color: var(--border-soft);
  pointer-events: auto;  /* click allowed so the selection can be undone */
}
.genre-chip.stale .genre-chip-count {
  color: var(--smoke);
}
/* Stale AND selected: struck-through text — the selected filter currently contributes nothing */
.genre-chip.stale.selected {
  text-decoration: line-through;
  text-decoration-color: rgba(212,98,10,.5);
  text-decoration-thickness: 1px;
}

/* Total count hint below the filter sections */
.filter-total-hint {
  margin: 12px 0 4px;
  padding: 8px 12px;
  font-size: 13px;
  text-align: center;
  letter-spacing: .04em;
  color: var(--smoke, #a89784);
  background: var(--surface-2);
  border-radius: 2px;
  border: 1px solid var(--border-soft);
}
.filter-total-hint strong {
  color: var(--gold, #d4920a);
}
.filter-total-hint-empty {
  color: #d97a5a;
  background: rgba(217,122,90,.08);
  border-color: rgba(217,122,90,.25);
}

/* ── Read-only Yes/No icons in the lobby settings box ─────────────────── */
/* Previously shown as text "Yes"/"No" - wraps when space is tight. Now compact
   icons that fit on any line. */
.settings-value-icon-yes {
  color: #5c5;
  font-weight: bold;
  font-size: 16px;
  line-height: 1;
}
.settings-value-icon-no {
  color: #d97a5a;
  font-weight: bold;
  font-size: 16px;
  line-height: 1;
}

/* Filter total hint: third level for "filter yields > 0 tracks but fewer
   than the WordCount setting requires". Orange as a warning between "all ok"
   (smoke) and "0 tracks" (red). */
.filter-total-hint-warn {
  color: var(--amber, #e8a040);
  background: rgba(232,160,64,.08);
  border-color: rgba(232,160,64,.25);
}

/* Clickable game mode text in the read-only settings box: opens the
   game rules modal with GameRulesContent. Looks like a regular settings-value
   but has button reset + subtle info icon to make it clear it is clickable. */
.settings-value-link-mode {
  color: var(--accent-ink);
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  cursor: pointer;
  text-align: right;
  transition: color 0.12s ease;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.settings-value-link-mode:hover {
  color: var(--gold-ink);
}
.settings-value-info-icon {
  font-size: 12px;
  color: var(--smoke, #a89784);
  opacity: 0.7;
  transition: opacity 0.12s ease;
}
.settings-value-link-mode:hover .settings-value-info-icon {
  opacity: 1;
  color: var(--gold);
}

/* Game mode pill in the game history session header */
.history-session-mode-pill {
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--accent-light);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border: 1px solid var(--accent-light);
  padding: 2px 8px;
  border-radius: 2px;
  text-transform: uppercase;
  flex-shrink: 0;
}

/* Apple Music link inline in the track row (game history, music quiz) */
.history-apple-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-left: 6px;
  font-size: 13px;
  text-decoration: none;
  color: var(--gold, #d4920a);
  background: rgba(200,146,42,.10);
  border: 1px solid rgba(200,146,42,.25);
  border-radius: 2px;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
  vertical-align: middle;
}
.history-apple-link:hover {
  background: rgba(200,146,42,.25);
  border-color: rgba(200,146,42,.55);
  color: var(--gold-light);
  text-decoration: none;
}

/* ── History: session scoreboard (above the track/word list) ────────── */
/* Shown in the history modal when a session is expanded — displays the
   final score as at game end, more compact and in history style. */
.history-scoreboard {
  margin: 8px 0 14px;
  padding: 10px 14px;
  background: rgba(0,0,0,.2);
  border: 1px solid rgba(200,146,42,.18);
  border-radius: 2px;
}
.history-scoreboard-label {
  font-family: 'Rye', cursive;
  font-size: 12px;
  letter-spacing: .08em;
  color: var(--gold, #d4920a);
  margin-bottom: 8px;
}
.history-scoreboard-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
  font-size: 13px;
  border-bottom: 1px dotted rgba(200,146,42,.08);
}
.history-scoreboard-row:last-child {
  border-bottom: none;
}
.history-scoreboard-medal {
  width: 24px;
  text-align: center;
  flex-shrink: 0;
  color: var(--smoke, #a89784);
}
.history-scoreboard-name {
  flex: 1;
  color: var(--old-paper, #d6c6a8);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.history-scoreboard-pts {
  font-weight: bold;
  color: var(--gold, #d4920a);
  flex-shrink: 0;
}
.history-scoreboard-row.is-me {
  background: rgba(200,146,42,.06);
  margin: 0 -6px;
  padding-left: 6px;
  padding-right: 6px;
  border-radius: 2px;
}
.history-scoreboard-row.is-me .history-scoreboard-name {
  color: var(--gold-light, #f0a020);
}

/* ══ Inhalts-Meldungen (Mod-Sprint Schritt 1) ═════════════════════════════
   Styles für ReportContentModal (Shared/ReportContentModal.razor) und den
   🚩-Button in den Spielmodi. Wiederverwendete generische Modal-Klassen
   (modal-backdrop, modal-content, fgrp, lbl, inp). */

/* Flag button in the game — icon only, very small and subtle.
   Deliberately no label so the button does not wrap in tight headers.
   Hover shows a faint red tint to make the purpose clear. */
.report-flag-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  color: rgba(168, 151, 132, 0.35);
  font-size: 13px;
  padding: 2px 4px;
  border-radius: 3px;
  cursor: pointer;
  transition: all .15s;
  line-height: 1;
  flex-shrink: 0;
}
.report-flag-btn:hover {
  border-color: rgba(192, 53, 42, 0.35);
  color: rgba(192, 53, 42, 0.7);
  background: rgba(139, 26, 26, 0.08);
}
.report-flag-btn.reported {
  color: var(--green-ok);
  border-color: transparent;
  cursor: default;
  background: transparent;
}
.report-flag-btn:disabled {
  cursor: default;
}

/* Target display at the top of the report modal — compact info box showing what is being reported */
.report-target-box {
  background: var(--surface-1);
  border: 1px solid var(--border);
  padding: 8px 12px;
  border-radius: 2px;
  margin-bottom: 14px;
}
.report-target-label {
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--smoke);
  margin-bottom: 4px;
}
.report-target-name {
  font-family: 'Rye', cursive;
  font-size: 16px;
  color: var(--heading);
}
.report-target-meta {
  font-size: 12px;
  color: var(--smoke);
  margin-top: 3px;
}

/* Reason selection as a list instead of classic radio buttons.
   Clicking the entire row selects it — larger hit area, better on touch. */
.report-reason-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.report-reason-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: 2px;
  cursor: pointer;
  font-size: 14px;
  color: var(--old-paper);
  transition: all .12s;
}
.report-reason-row:hover {
  border-color: rgba(200, 146, 42, 0.4);
  background: rgba(200, 146, 42, 0.04);
}
.report-reason-row.checked {
  border-color: rgba(200, 146, 42, 0.55);
  background: rgba(200, 146, 42, 0.1);
  color: var(--gold-light);
}
.report-reason-row input[type="radio"] {
  accent-color: var(--gold);
  cursor: pointer;
}

/* ══════════════════════════════════════════════════════════════════════════
   MATCHMAKING — Startseiten-Aktions-Buttons + „Lobby beitreten"-Modal
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Matchmaking modal: code field in header ─────────────────────────────── */
/* (Wrapper .matchmaking-modal migrated to <Modal> component — body classes remain) */
.mm-header-code {
  display: flex;
  align-items: center;
  gap: 6px;
}
.mm-header-code .inp-code {
  width: 108px;
  background: var(--input-bg);
  border: 1px solid var(--border-strong);
  color: var(--heading);
  font-family: 'Rye', cursive;
  letter-spacing: .18em;
  text-align: center;
  font-size: 14px;
  padding: 6px 8px;
  border-radius: 3px;
  text-transform: uppercase;
}
.mm-header-code .inp-code::placeholder {
  color: var(--smoke);
  letter-spacing: .1em;
  font-size: 12px;
}
.mm-header-code .mm-code-go {
  font-family: 'Rye', cursive;
  font-size: 12px;
  cursor: pointer;
  background: linear-gradient(135deg, var(--amber), var(--gold));
  color: var(--shadow);
  border: none;
  padding: 7px 12px;
  border-radius: 3px;
}
.mm-header-code .mm-code-go:disabled { opacity: .4; cursor: not-allowed; }
/* On narrow screens the code field wraps below the title.
   - flex-basis: 100% forces it to full width (instead of squeezing next to the title)
   - order: 99 moves it to the end of the header flex container so the close button
     (x) still stays in the first row to the right of the title
   - Works together with flex-wrap: wrap on .modal-v2-header */
@media (max-width: 520px) {
  .mm-header-code {
    flex-basis: 100%;
    order: 99;
  }
  .mm-header-code .inp-code { flex: 1; width: auto; }
}

.mm-subhead {
  font-size: 12px;
  color: var(--smoke);
  letter-spacing: .08em;
  text-transform: uppercase;
  margin: 0 0 12px;
}

/* ── Lobby entry (flat list) ───────────────────────────────────────── */
.mm-lobby {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  padding: 10px 12px;
  margin-bottom: 8px;
}
.mm-lobby:last-child { margin-bottom: 0; }
.mm-lobby-icon { font-size: 26px; line-height: 1; flex-shrink: 0; }
.mm-lobby-main { flex: 1; min-width: 0; }
.mm-lobby-host { color: var(--parchment); font-size: 14px; }
.mm-lobby-host .mm-host-name { color: var(--heading); }
.mm-lobby-meta {
  font-size: 12px;
  color: var(--smoke);
  margin-top: 2px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.mm-mode-tag { color: var(--gold-light); letter-spacing: .04em; }
.mm-players { color: var(--old-paper); }
.mm-join-btn {
  font-family: 'Rye', cursive;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--amber), var(--gold));
  color: var(--shadow);
  border: none;
  padding: 8px 16px;
  border-radius: 3px;
}
.mm-join-btn:hover { transform: translateY(-1px); }

/* ── Empty state ────────────────────────────────────────────────────────── */
.mm-empty {
  text-align: center;
  color: var(--smoke);
  font-size: 13px;
  padding: 34px 12px;
  line-height: 1.6;
}
.mm-empty .mm-empty-icon {
  font-size: 34px;
  display: block;
  margin-bottom: 8px;
  opacity: .6;
}

/* ── Paging ─────────────────────────────────────────────────────────────── */
.mm-paging {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(200, 146, 42, .14);
}
.mm-page-btn {
  font-size: 13px;
  cursor: pointer;
  padding: 5px 12px;
  border-radius: 2px;
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--old-paper);
}
.mm-page-btn:hover:not(:disabled) { border-color: var(--gold); color: var(--gold-light); }
.mm-page-btn:disabled { opacity: .3; cursor: not-allowed; }
.mm-page-info { font-size: 12px; color: var(--smoke); }

/* ══════════════════════════════════════════════════════════════════════════
   MODUS-PILL MIT DROPDOWN — im Header von MatchmakingDialog und Create-Modal
   ══════════════════════════════════════════════════════════════════════════ */
.mode-pill-header {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: 14px;
  font-size: 13px;
  color: var(--heading);
  position: relative;
  cursor: pointer;
  transition: background .15s, border-color .15s;
  user-select: none;
  margin-left: 8px;
}
.mode-pill-header:hover {
  background: rgba(200, 146, 42, .25);
  border-color: var(--gold);
}
.mode-pill-header.open {
  background: rgba(200, 146, 42, .3);
  border-color: var(--gold);
}
.mode-pill-header .caret {
  color: var(--smoke);
  font-size: 12px;
  margin-left: 2px;
}
.mode-switch-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  background: var(--surface-1-strong);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  padding: 4px;
  box-shadow: 0 8px 24px var(--shadow-color);
  z-index: 100;
  min-width: 180px;
  max-height: 260px;   /* long game list scrolls inside (mockup behavior) */
  overflow-y: auto;
  text-transform: none;
  letter-spacing: 0;
}
.mode-switch-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  color: var(--parchment);
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
}
.mode-switch-item:hover {
  background: var(--surface-hover);
  color: var(--heading);
}
.mode-switch-item.cur { background: var(--surface-2); color: var(--heading); font-weight: 600; }
.mode-switch-icon { font-size: 18px; line-height: 1; width: 22px; text-align: center; flex-shrink: 0; }
/* Game locked in the switch dropdown because too many players are connected. */
.mode-switch-item.disabled {
  opacity: .5;
  cursor: not-allowed;
  pointer-events: none;
}
.mode-switch-off.cap {
  color: var(--amber, #e8a060);
  border-color: rgba(232, 160, 96, .5);
}

/* ══════════════════════════════════════════════════════════════════════════
   MATCHMAKING — ACTION-CARDS (Schnellstart + Neue Lobby) und Live-Liste
   ══════════════════════════════════════════════════════════════════════════ */
.mm-action-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 18px;
}
.mm-action-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  cursor: pointer;
  text-align: left;
  color: var(--parchment);
  transition: all .15s;
}
.mm-action-card:not(:disabled):hover {
  border-color: var(--gold);
  background: rgba(200, 146, 42, .08);
  transform: translateY(-1px);
}
.mm-action-card:disabled { opacity: .5; cursor: not-allowed; }
.mm-action-quickstart {
  background: linear-gradient(135deg, rgba(212, 98, 10, .22), rgba(212, 98, 10, .05));
  border-color: rgba(212, 98, 10, .55);
}
.mm-action-quickstart:not(:disabled):hover {
  background: linear-gradient(135deg, rgba(212, 98, 10, .32), rgba(212, 98, 10, .1));
  border-color: var(--amber);
}
.mm-action-create {
  background: linear-gradient(135deg, rgba(200, 146, 42, .18), rgba(200, 146, 42, .05));
  border-color: rgba(200, 146, 42, .5);
}
.mm-action-create:not(:disabled):hover {
  background: linear-gradient(135deg, rgba(200, 146, 42, .28), rgba(200, 146, 42, .1));
  border-color: var(--gold);
}
.mm-action-icon { font-size: 28px; flex-shrink: 0; line-height: 1; }
.mm-action-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mm-action-title {
  color: var(--heading);
  font-family: 'Rye', cursive;
  font-size: 15px;
}
.mm-action-sub { color: var(--smoke); font-size: 12px; }
@media (max-width: 540px) {
  .mm-action-cards { grid-template-columns: 1fr; }
}

.mm-list-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 10px;
}
.mm-subhead {
  font-family: 'Rye', cursive;
  color: var(--heading);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .12em;
  margin: 0;
}
.mm-live-hint {
  font-size: 12px;
  color: var(--smoke);
  font-style: italic;
}

/* ══════════════════════════════════════════════════════════════════════════
   MATCHMAKING — INLINE-HUB (Variante A). Ersetzt im Home-Board das Poster-Grid
   statt als Overlay aufzugehen. Wiederverwendet .mm-action-cards / .mm-lobby /
   .mm-empty / .mode-pill-header / .mm-header-code; neu sind nur Leiste + Hero.
   ══════════════════════════════════════════════════════════════════════════ */
.mm-inline-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.mm-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Rye', cursive;
  font-size: 13px;
  letter-spacing: .04em;
  cursor: pointer;
  min-height: 40px;                 /* WCAG 2.5.8: Zielgröße */
  padding: 8px 16px;
  border-radius: var(--btn-radius);
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--old-paper);
  transition: border-color .15s, color .15s, background .15s;
}
.mm-back:hover { border-color: var(--gold); color: var(--gold-light); background: var(--surface-hover); }
.mm-back-arrow { font-size: 16px; line-height: 1; }
.mm-inline-tools {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  flex-wrap: wrap;
}
/* Die Modus-Pill bringt margin-left:8px mit — im Tools-Flex regelt der gap. */
.mm-inline-tools .mode-pill-header { margin-left: 0; }

.mm-inline-hero {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 18px 20px;
  margin-bottom: 20px;
  border-radius: 12px;
  border: 1px solid var(--board-border);
  /* Dezenter Akzent-Tint des gewählten Spiels (mode-* setzt --accent); Text
     bleibt auf dem Board-Verlauf → --text-main behält AA-Kontrast. */
  background:
    radial-gradient(circle at 12% 25%,
      color-mix(in srgb, var(--accent) var(--spot-accent-mix, 40%), transparent), transparent 62%),
    linear-gradient(180deg, var(--board-grad-a), var(--board-grad-b));
}
.mm-inline-hero-ic { font-size: 54px; line-height: 1; flex: none; filter: drop-shadow(0 3px 8px var(--shadow-color)); }
.mm-inline-hero-txt { min-width: 0; }
.mm-inline-hero-txt h2 {
  font-family: 'Rye', cursive;
  font-weight: 400;
  color: var(--heading);
  font-size: clamp(20px, 3.5vw, 26px);
  margin: 0 0 5px;
  line-height: 1.1;
}
.mm-inline-hero-txt p { margin: 0 0 8px; color: var(--text-main); font-size: 14px; max-width: 60ch; line-height: 1.5; }
.mm-inline-hero-meta { color: var(--heading); font-size: 13px; font-weight: 600; }

@media (max-width: 560px) {
  .mm-inline-tools { margin-left: 0; width: 100%; }
  .mm-inline-hero { gap: 12px; padding: 14px 16px; }
  .mm-inline-hero-ic { font-size: 40px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   HEADER — Code-Direktbeitritt im Slot rechts vom Brand
   (sichtbar wenn nicht in Lobby + nicht im Spiel; sonst steht dort die
   .nav-lobby-pill bzw. nichts). Visuell als kompakte Pill gestaltet —
   gleiche Höhe und Stil-Sprache wie .nav-lobby-pill, damit der Slot
   konsistent wirkt egal welcher Inhalt drin steht.
   ══════════════════════════════════════════════════════════════════════════ */
.header-code-form {
  display: inline-flex;
  align-items: stretch;            /* icon/input/button all the same height */
  gap: 0;
  margin-left: 14px;               /* mirrors .nav-lobby-pill */
  margin-right: auto;              /* pushes .app-header-actions to the right edge */
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  overflow: hidden;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.header-code-form:hover { border-color: var(--gold); }
.header-code-form:focus-within {
  border-color: var(--gold);
  box-shadow: 0 0 0 2px rgba(200, 146, 42, .18);
}
/* Focus ring on the WHOLE pill instead of the inner input (the global
   :focus-visible rule would otherwise draw it inside the rounded shape). */
.header-code-form:has(.header-code-input:focus-visible) {
  outline: 3px solid var(--accent-strong);
  outline-offset: 2px;
}
.header-code-form .header-code-input:focus-visible { outline: none !important; }
.header-code-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 6px 0 10px;
  font-size: 14px;
  line-height: 1;
  color: var(--text-dim);
  user-select: none;
}
.header-code-input {
  background: transparent;
  border: none;
  color: var(--text-main);
  padding: 6px 10px 6px 4px;
  width: 92px;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 2px;
  font-size: 13px;
  line-height: 1;
}
.header-code-input::placeholder {
  color: color-mix(in srgb, var(--text-dim) 65%, transparent);
  letter-spacing: 1px;
  text-transform: none;
}
.header-code-input:focus { outline: none; }
.header-code-go {
  background: linear-gradient(135deg, var(--amber), var(--gold));
  color: var(--ink);
  border: none;
  padding: 0 12px;
  cursor: pointer;
  font-size: 14px;
  font-weight: bold;
  line-height: 1;
  transition: filter .15s;
}
.header-code-go:hover:not(:disabled) { filter: brightness(1.12); }
.header-code-go:disabled {
  background: var(--surface-2);
  color: color-mix(in srgb, var(--text-dim) 60%, transparent);
  cursor: not-allowed;
}

/* Mobile: icon padding more compact, input narrower. Brand title is
   already hidden via the .app-header-title media query. */
@media (max-width: 540px) {
  .header-code-form { margin-left: 10px; }
  .header-code-icon { padding: 0 4px 0 8px; font-size: 13px; }
  .header-code-input { width: 78px; padding: 6px 8px 6px 4px; }
  .header-code-go { padding: 0 10px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   KONFIG-MODAL KOMPAKT — einzeilige Slider-Zeilen
   ══════════════════════════════════════════════════════════════════════════ */

/* Replaces the two-line .fgrp for slider settings: label fixed on the left,
   slider fills the center, current value on the right — all in one line. */
.slider-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 7px 0;
}
.slider-row .sr-label {
  flex: 0 0 128px;
  color: var(--smoke);
  font-size: 13px;
  /* same typography as .lbl in the other config rows */
  letter-spacing: .16em;
  text-transform: uppercase;
}
.slider-row .slider { flex: 1; }
.slider-row .sr-value {
  flex: 0 0 auto;
  min-width: 48px;
  text-align: right;
  color: var(--heading);
  font-size: 14px;
  font-weight: bold;
}
/* Hint below the max-players slider when the account cap (unconfirmed
   email) limits the slider below the account maximum. */
.slider-cap-note {
  margin: -2px 0 6px;
  padding-left: 140px;
  color: var(--smoke);
  font-size: 12px;
}
/* Two adjacent 420px blocks combined.
   On very narrow screens the slider row wraps: label on top, slider+value below. */
@media (max-width: 420px) {
  .slider-cap-note { padding-left: 0; }
  .slider-row {
    flex-wrap: wrap;
    gap: 4px 12px;
  }
  .slider-row .sr-label { flex-basis: 100%; }
  .slider-row .sr-value { min-width: 40px; }
}

/* ── Help modal (lobby visibility) — wrapper migrated to <Modal> component ── */
/* Body styles are not needed since <Modal> BodyContent works directly with <p> tags
   and global typography rules. Help modal content is short enough that no
   separate body wrapper is required. */

/* Variant for a toggle row: label + help icon side by side, without the
   margin-bottom of the block variant .lbl-with-help. */
.lbl-with-help-inline {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
/* line-height:1 ensures the '?' glyph sits centered in its own box;
   align-items:center on the container aligns the box to the text line.
   No padding hack needed once the label is properly normalized. */
.lbl-with-help-inline .help-icon-btn {
  line-height: 1;
  min-width: 24px;   /* WCAG 2.5.8 — without this the inline variant shrinks to ~17px */
}

/* ── Visibility badge in the lobby header ─────────────────────────── */
.visibility-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  line-height: 1;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--border-soft);
  background: var(--surface-2);
  color: var(--text-dim);
  cursor: default;
  flex-shrink: 0;
}
.visibility-badge.is-public {
  color: var(--green-ok);
  border-color: rgba(45, 122, 74, .45);
}

/* ── Visibility icon in the nav lobby pill ───────────────────────────── */
.nav-lobby-pill-vis {
  font-size: 12px;
  opacity: .85;
  flex-shrink: 0;
}

/* ── Settings row with pill group (label on left, pills on right) ──────────
   Similar to .settings-toggle-row, but instead of a single toggle button
   there is a pill group on the right (e.g. answer delay: Off / 2 s / 3 s).
   On narrow screens the pill group wraps below the label. */
.settings-pills-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
}
.settings-pills-row > .lbl {
  flex: 1;
  min-width: 0;
  /* .lbl brings display:block + margin-bottom:7px — both would push the
     label out of vertical center in the flex row. Reset here
     and align to the compact 13px size of the slider rows. */
  display: flex;
  align-items: center;
  margin-bottom: 0;
  font-size: 13px;
}
.settings-pills-row .quiz-mode-pills {
  flex-shrink: 0;
  margin: 0;
  /* Pills remain single-line — wrapping on narrow screens happens
     at row level (.settings-pills-row), not within the pill group. */
  flex-wrap: nowrap;
}
@media (max-width: 460px) {
  .settings-pills-row {
    flex-wrap: wrap;
    align-items: flex-start;
  }
  .settings-pills-row > .lbl { flex-basis: 100%; }
}

/* ── TrackDetailModal (Shared, readonly) — body classes ─────────────────────
   Wrapper/header (.tdm-modal/-head/-close/-body) migrated to <Modal> component.
   The body layout classes below remain — <Modal> BodyContent renders them
   directly. Own tdm-* content classes instead of track-detail-* from admin.css,
   because admin.css is not loaded outside the admin area (Game/Lobby/Profile). */
.tdm-hero {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(200, 146, 42, .15);
}
.tdm-cover {
  width: 104px; height: 104px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
  border: 1px solid rgba(200, 146, 42, .25);
  box-shadow: 0 4px 18px rgba(0, 0, 0, .5);
}
.tdm-cover-empty {
  display: flex; align-items: center; justify-content: center;
  font-size: 36px;
  background: radial-gradient(circle at 35% 30%, var(--warm-wood), var(--ink));
}
.tdm-hero-text { flex: 1; min-width: 0; }
.tdm-artist {
  font-size: 18px; color: var(--heading);
  overflow-wrap: anywhere;
}
.tdm-title {
  font-size: 15px; color: var(--parchment);
  margin-top: 2px; overflow-wrap: anywhere;
}
.tdm-album {
  font-size: 12px; color: var(--smoke); font-style: italic;
  margin-top: 6px; overflow-wrap: anywhere;
}
.tdm-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 16px;
  font-size: 13px;
}
.tdm-label {
  color: var(--smoke);
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: 12px;
  align-self: center;
}
.tdm-value { color: var(--parchment); }
.tdm-pill {
  display: inline-block;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 12px;
  color: var(--heading);
}
.tdm-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}
.tdm-btn {
  flex: 1;
  min-width: 150px;
  text-align: center;
  text-decoration: none;
}
.tdm-btn-star-on {
  background: rgba(200, 146, 42, .16);
  border-color: var(--gold);
  color: var(--heading);
}
.tdm-btn-flag { border-color: rgba(192, 53, 42, .5); color: #e0998f; }

/* 'Already reported' state — applies to track and player report buttons.
   The button is already disabled (.btn:disabled dims it); this class
   additionally gives it a calm green done accent so it looks
   'confirmed done' rather than 'broken/disabled'.
   !important because .btn:disabled dimming would otherwise swallow the border color. */
.tdm-btn-reported,
.btn-reported {
  border-color: rgba(45, 122, 74, .55) !important;
  color: var(--green-ok) !important;
}

/* Clickable track rows (podium, lobby history, profile) — open the TrackDetailModal. */
.track-clickable { cursor: pointer; }
.track-clickable:hover { color: var(--heading); }

/* ── Profile: favorites section ───────────────────────────────────────────── */
.profile-fav-count { font-size: 12px; color: var(--smoke); font-weight: normal; }
.profile-fav-list { display: flex; flex-direction: column; }
.profile-fav-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(200, 146, 42, .12);
}
.profile-fav-row:last-child { border-bottom: none; }
.profile-fav-main {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
}
.profile-fav-cover {
  width: 38px; height: 38px;
  border-radius: 5px;
  object-fit: cover;
  flex-shrink: 0;
}
.profile-fav-cover-empty {
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  background: radial-gradient(circle at 35% 30%, var(--warm-wood), var(--ink));
}
.profile-fav-text { flex: 1; min-width: 0; }
.profile-fav-artist {
  font-size: 13px; color: var(--heading);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.profile-fav-title {
  font-size: 12px; color: var(--smoke);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Action column per favorites row (preview · remove/inline confirm). */
.profile-fav-acts {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
/* Both action buttons compact + consistent. Overrides .btn base
   (full-width, Rye, uppercase) AND gives the play button an explicit background —
   otherwise the <button> shows browser default chrome. */
.profile-fav-acts .btn {
  width: auto; min-width: 32px; height: 30px; padding: 0 10px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: inherit; font-size: 13px; letter-spacing: 0; text-transform: none;
  border-radius: 4px; line-height: 1;
}
.profile-fav-play {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--heading);
}
.profile-fav-play:hover { background: rgba(200, 146, 42, .15); border-color: var(--gold); }

/* Make AdminPager styles available outside admin — the pager is now used on
   saloon pages (profile history/favorites, teams overview) that only load
   saloon.css. The button/container styles otherwise live only in admin.css.
   On admin/mod pages admin.css is loaded AFTER saloon.css and overrides these
   rules so the pager table-shell layout remains unchanged there. */
.admin-pager {
  display: flex; align-items: center; justify-content: center;
  gap: 4px; flex-wrap: wrap; padding: 14px 0 2px;
}
.admin-pager-info { font-size: 12px; color: var(--smoke); margin-left: 6px; }
.lot-page-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 32px; height: 32px; padding: 0 8px;
  background: var(--surface-1); border: 1px solid var(--border-soft);
  color: var(--text-dim); font-size: 13px; border-radius: 3px;
  cursor: pointer; transition: all .2s;
}
.lot-page-btn:hover:not(:disabled) { color: var(--gold); border-color: rgba(200, 146, 42, .5); }
.lot-page-btn:disabled { opacity: .3; cursor: default; }
.lot-page-btn.lot-page-active {
  background: rgba(200, 146, 42, .15); border-color: var(--gold); color: var(--gold-light);
}

.profile-fav-remove {
  width: 30px; height: 30px;
  flex-shrink: 0;
  border-radius: 5px;
  border: 1px solid rgba(192, 53, 42, .4);
  background: var(--surface-2);
  color: var(--parchment);
  cursor: pointer;
  font-size: 13px;
}
.profile-fav-paging {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid rgba(200, 146, 42, .12);
}
.profile-fav-page-info { font-size: 12px; color: var(--smoke); letter-spacing: .04em; }

/* ── Profile: 'recent games' button (opens the history modal) ───────────── */
.profile-history-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
.profile-history-btn-count { font-size: 12px; color: var(--smoke); }

/* ════════════════════════════════════════════════════════════════════
   Friends feature
   ════════════════════════════════════════════════════════════════════ */

/* Counter badge (open incoming requests) — on the section title and in the dropdown. */
.badge-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  font-family: Georgia, serif;
  font-size: 12px;
  font-weight: bold;
  color: #1a0f06;
  background: var(--gold-light);
  border-radius: 9px;
  vertical-align: middle;
}
.profile-section-subtle {
  font-size: 12px;
  color: var(--smoke);
  font-weight: normal;
  margin-left: 4px;
}

/* Nav badge: small dot counter at the top right of the profile avatar button. */
.nav-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: Georgia, serif;
  font-size: 12px;
  font-weight: bold;
  color: #1a0f06;
  background: var(--gold-light);
  border: 1px solid rgba(13, 10, 7, 0.7);
  border-radius: 9px;
  pointer-events: none;
}
.profile-btn { position: relative; }
.nav-badge-inline { margin-left: auto; }

/* Group heading within the friends section (incoming/outgoing/list). */
.friend-group-label {
  color: var(--heading);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 16px 0 4px;
}
.friend-group-label:first-of-type { margin-top: 6px; }

.friend-list { display: flex; flex-direction: column; }
/* Row wraps: avatar + name/meta on line 1, action buttons slide right-aligned
   onto a second line when space is tight (narrow profile column),
   instead of squeezing the text. */
.friend-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 11px;
  padding: 10px 2px;
  border-bottom: 1px solid rgba(200, 146, 42, 0.08);
}
.friend-row:last-child { border-bottom: none; }
/* min-width forces the wrap: if the text column cannot shrink below 60%,
   buttons must go to the next line (instead of squeezing the text). */
.friend-row-main { flex: 1 1 auto; min-width: 60%; }
.friend-row-name {
  font-size: 13.5px;
  color: var(--parchment);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.friend-row-meta { color: var(--smoke); font-size: 12px; margin-top: 2px; line-height: 1.35; }
.friend-row-acts {
  display: flex;
  gap: 7px;
  flex: 0 0 auto;
  margin-left: auto;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.friend-inline-q { color: var(--smoke); font-size: 12px; }

/* ── Friend/team presence (online dot, game badge, join) ── */
.friend-avatar-wrap { position: relative; flex: 0 0 auto; line-height: 0; }
.presence-dot {
  position: absolute; right: -2px; bottom: -2px;
  width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid #20180f;            /* ring in saloon dark, separates dot from avatar */
}
.presence-dot.online  { background: #5fb96b; box-shadow: 0 0 6px rgba(95, 185, 107, .7); }
.presence-dot.offline { background: #6b5d50; }
.presence-online      { color: var(--success); }
.presence-offline     { color: var(--smoke); }
.presence-sub         { color: var(--smoke); }
.game-badge           { display: inline-flex; align-items: center; gap: 5px; color: var(--gold); }
.team-member-presence { display: block; font-size: 12px; margin-top: 2px; color: var(--smoke); }

/* Compact button for list actions (accept/decline/remove ...). */
.btn-xs {
  display: inline-block;
  width: auto;
  font-size: 12px;
  padding: 4px 10px;
  border-radius: 3px;
  white-space: nowrap;
  cursor: pointer;
}

/* Friendship block in PlayerProfileModal. */
.player-profile-friend { margin-top: 4px; }
.player-profile-friend .alert-error { margin-bottom: 8px; }
.player-profile-friend-state {
  color: var(--success);
  font-size: 13px;
  margin-bottom: 8px;
}
.player-profile-friend-q {
  color: var(--smoke);
  font-size: 12.5px;
  align-self: center;
  margin-right: 2px;
}
.player-profile-team-link {
  color: var(--heading);
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}
.player-profile-team-link:hover { color: var(--gold); }

/* Visually hidden but present for screen readers and search engines
   (e.g. the landing page H1 whose brand title would otherwise only appear in the header). */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ════════════════════════════════════════════════════════════════════
   Profile page with tabs
   ════════════════════════════════════════════════════════════════════ */

/* Identity bar: remains visible above all tabs (portrait + name + team/matches).
   flex-wrap + min-width:0 so a long name + actions never blow up narrow screens. */
.profile-id-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  padding: 14px 18px;
  margin-bottom: 14px;
}
.profile-id-avatar { flex-shrink: 0; }
.profile-id-main { min-width: 0; }
.profile-id-name { font-family: 'Rye', cursive; color: var(--heading); font-size: 20px; line-height: 1.1; display: flex; align-items: center; gap: 6px; }
.profile-id-meta { color: var(--text-dim); font-size: 12.5px; margin-top: 5px; }
.profile-id-team { color: var(--heading); text-decoration: underline dotted; text-underline-offset: 2px; }
.profile-id-team:hover { color: var(--gold); }

/* The former .profile-tabs/.profile-tab bar was replaced by the shared subnav
   (SubnavTabs / .pg-tab) in the PageFrame header row. */

/* Tab content: flex grid. Default = full width; .col-half = two side by side
   (on narrow screens they collapse back to one column via min-width). */
.profile-tab-body {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: flex-start;
}
/* Tab contents are ALWAYS in the DOM (one .tab-region per tab) and toggled via
   CSS only — tab switching is a pure visibility toggle without
   re-render/remount. Each region is its own flex container for its sections/pairs;
   only the active one is visible. */
.profile-tab-body > .tab-region { flex: 1 1 100%; }
.tab-region {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: flex-start;
}
.tab-region.tab-hidden { display: none; }
.tab-region > section { flex: 1 1 100%; margin: 0; }
/* Explicit 50/50 pair row — keeps data+danger-zone or account+linked side by side
   robustly, even if one card is missing (e.g. 'Linked accounts' without OAuth).
   A single col-half grows to full width via flex-grow. */
.tab-region > .profile-pair {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: flex-start;
}
.profile-pair > .col-half { flex: 1 1 calc(50% - 9px); min-width: 280px; margin: 0; }
/* Favorites renders (due to DOM order) before the stats — pushed to the end of the tab via order. */
.profile-tab-body > .profile-fav-last { order: 5; }

/* ════════════════════════════════════════════════════════════
   Knowledge Quiz — question/timer/break (uses --accent from .mode-wissensquiz)
   Layout intentionally mirrors the music quiz classes (.mq-*, .break-stage-*).
   ════════════════════════════════════════════════════════════ */
.wq-card { /* inherits from .mq-card; placeholder for future quiz-specific tweaks */ }

/* Question displayed prominently above the answer buttons */
.wq-question {
  font-family: 'Rye', cursive;
  font-size: 21px;
  line-height: 1.4;
  color: var(--parchment);
  text-align: center;
  margin: 8px 4px 16px;
}

/* Hint shown while the timer (= answer window) is not yet running */
.wq-timer-idle {
  flex: 1;
  font-size: 13px;
  color: var(--smoke);
  font-style: italic;
}

/* Difficulty badge in the header */
.wq-difficulty {
  padding: 2px 9px;
  border-radius: 11px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .3px;
  border: 1px solid var(--accent);
  color: var(--accent-ink);
  background: color-mix(in srgb, var(--accent) 26%, transparent);
}
.wq-diff-leicht { --accent: #4f7a3a; --accent-light: #8bbf6a; }   /* green = easy   */
.wq-diff-mittel { --accent: #b88a2a; --accent-light: #e3b85a; }   /* gold  = medium  */
.wq-diff-schwer { --accent: #a3324a; --accent-light: #d65c78; }   /* carmine = hard  */

/* ── Break screen ───────────────────────────────────────────────
   The break re-renders the SAME question card as the playing screen
   (continuous card, no separate stage). The .wq-break-answer* block below
   is only the fallback when the option list is broken (≠ 4 entries). */
.wq-break-answer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  margin-bottom: 12px;
}
.wq-break-answer-label {
  font-size: 12px;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--smoke);
}
.wq-break-answer-text {
  font-size: 24px;
  font-weight: 800;
  color: var(--accent-ink);
  text-align: center;
}
.wq-break-explanation {
  max-width: 520px;
  margin: 0 auto 14px;
  padding: 10px 14px;
  border-radius: 6px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-main);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
}

/* ── Show staging: reveal inside the SAME question card ──────────
   Break choreography: drumroll (~1.3 s, .wq-resolving pulses) → options flip
   to revealed states (correct = --success green, wrong = faded) → the reserved
   reveal area shows commentary + optional explanation (per-player points go to
   the sidebar as +N chips). The reveal area has a FIXED height that is also
   reserved in the playing screen, so the centered card never changes height and
   the options never jump. */

/* Question-card entrance per new question (keyed on the round id so the animation
   re-runs for every question; unchanged across the Playing → RoundBreak reveal since
   the same component instance persists — SS-0324). */
.wq-card-enter { animation: wqCardIn .45s ease-out; }
@keyframes wqCardIn {
  from { opacity: 0; transform: perspective(900px) rotateX(-10deg) scale(.97); }
  to   { opacity: 1; transform: none; }
}

/* Reserved reveal area at the card bottom. Fixed min-height for the whole break
   AND matched in the playing screen (same .has-expl modifier) → the centered card
   keeps a constant height across playing → drumroll → results, so nothing shifts.
   Holds: the answer-saved msg (playing), the drumroll hint (resolving), or the
   commentary + explanation (results). */
.wq-reveal-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: 100%;
  margin-top: 14px;
  min-height: 44px;
}
.wq-reveal-area.has-expl { min-height: 120px; }

/* Hint line while the drumroll runs (before the reveal) */
.wq-resolving {
  text-align: center;
  font-size: 13px;
  color: var(--heading);
  letter-spacing: .08em;
  animation: wqResolvingPulse 1s ease-in-out infinite;
}
@keyframes wqResolvingPulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }

/* Revealed option states. --success (not gold) so "correct" stays semantically
   distinct from the gold "selected" state and is contrast-safe in both themes;
   --text-invert flips with the theme like the --success surface does.
   Both rules intentionally sit AFTER .mq-option:disabled (opacity .55) so the
   later position wins the equal-specificity fight. */
.mq-option.wq-reveal-wrong { opacity: .38; filter: grayscale(.4); }
.mq-option.wq-reveal-correct {
  opacity: 1;
  border-color: var(--success);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--success) 28%, transparent),
    color-mix(in srgb, var(--success) 14%, transparent));
  box-shadow: 0 0 26px color-mix(in srgb, var(--success) 45%, transparent),
              inset 0 0 0 1px var(--success);
  transform: scale(1.02);
  animation: wqCorrectPop .45s cubic-bezier(.34, 1.56, .64, 1);
}
.mq-option.wq-reveal-correct .mq-option-letter {
  background: var(--success);
  border-color: var(--success);
  color: var(--text-invert);
}
@keyframes wqCorrectPop { from { transform: scale(.96); } to { transform: scale(1.02); } }

/* Commentary + explanation fade in WITHOUT moving — the reveal area's height is
   already reserved, so a translate would read as a shift. Opacity only. */
.wq-reveal-area .wq-commentary,
.wq-reveal-area .wq-break-explanation { animation: wqRevealFade .35s ease-out; }
@keyframes wqRevealFade { from { opacity: 0; } to { opacity: 1; } }

/* Explanation stays within the reserved area (scrolls if unusually long) so it can
   never grow the card past the reserved height. */
.wq-reveal-area .wq-break-explanation { margin: 0; max-height: 82px; overflow-y: auto; }

/* Host commentary line (computed from the round's answers, no server data) */
.wq-commentary {
  font-size: 14px;
  color: var(--heading);
  background: color-mix(in srgb, var(--gold) 10%, transparent);
  border: 1px solid var(--border-soft);
  border-radius: 16px;
  padding: 5px 16px;
  text-align: center;
  flex-shrink: 0;
}

/* Category curtain: opaque board-toned cover announcing the category before
   each question (flips away after ~1.2 s; DOM removal is timed in code, so
   reduced-motion users see it statically and it still disappears). */
.wq-cat-curtain {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  /* Opaque base under the translucent board gradient — the question must NOT
     shimmer through the curtain (that is the whole point of the reveal). */
  background-color: var(--surface-0-c);
  background-image: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border-radius: inherit;
  transform-origin: 50% 0;
  /* Stay fully visible ~3.15 s, then flip out over .35 s (gone at ~3.5 s). Must match
     WissensquizPlaying.CategoryIntroMs (3500), which removes the element from the DOM
     right when the flip completes. Bump both together to change how long the category shows. */
  animation: wqCurtainOut .35s ease-in 3.15s forwards;
}
.wq-cat-curtain-icon { font-size: 60px; line-height: 1; }
.wq-cat-curtain-name {
  font-family: 'Rye', cursive;
  font-size: clamp(40px, 6vw, 72px);
  color: var(--accent-ink);
  text-align: center;
  padding: 0 20px;
}
@keyframes wqCurtainOut {
  to { opacity: 0; transform: perspective(900px) rotateX(14deg) scale(.97); }
}

/* Break countdown in the timer row's slot (same place the ticking timer sits
   during play — no absolute badge, so it can never overlap the header). */
.wq-next-row { justify-content: center; gap: 6px; color: var(--smoke); font-size: 13px; }
.wq-next-num {
  font-family: 'Rye', cursive;
  font-size: 18px;
  line-height: 1;
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
}


/* ══════════════════════════════════════════════════════════════════════════
   MEMORY — board, cards, states, animations
   Own .mem-card classes (does NOT override global .card). Accent color via
   .mode-memory on the screen root.
   ══════════════════════════════════════════════════════════════════════════ */
.memory-board-card { display: flex; flex-direction: column; gap: 14px; }

/* Centered, content-hugging pill that wraps gracefully on narrow widths instead of the
   old full-width bar whose margin-left:auto shoved the hint to a far edge (looked
   left-broken once the felt hugged the board). */
.memory-turn {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 6px 12px;
  padding: 12px 16px; border-radius: 12px; text-align: center;
  width: fit-content; max-width: 100%; margin-inline: auto;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 28%, var(--stage-back-a)), var(--stage-back-a));
  border: 1px solid color-mix(in srgb, var(--accent) 50%, transparent);
}
.memory-turn .mt-dot {
  width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto; background: var(--accent-ink);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-light) 35%, transparent);
}
.memory-turn .mt-who  { font-family: 'Rye', serif; font-size: 16px; color: var(--parchment); }
.memory-turn .mt-hint { font-size: 12.5px; color: var(--smoke); }

/* Fit wrapper: normally transparent (board keeps its responsive 6-column layout).
   When maximized it becomes the height-bounded centering area measured by shadowSaloon.fitMemory. */
.memory-fit { display: contents; }
.memory-board { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; justify-content: center; }
@media (max-width: 760px) { .memory-board { grid-template-columns: repeat(4, 1fr); gap: 8px; } }

.mem-card {
  position: relative; aspect-ratio: 1; border-radius: 10px; display: grid; place-items: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .45);
  transition: transform .25s ease, box-shadow .2s ease, opacity .3s ease;
}
/* Square tiles (width from grid, height = width). Icon fills most of the tile (little
   border) so the woodcut motifs read clearly, even at small cell sizes. Stays clear of the
   fixed 13px owner dot in the bottom-right corner. */
.mem-card .ic { width: 80%; height: 80%; }
.mem-card.back {
  background: radial-gradient(120% 120% at 50% 34%, #3a2812 0%, #1b1106 72%);
  border: 1px solid var(--gold); color: var(--gold-light);
}
.mem-card.back::before {
  content: ""; position: absolute; inset: 6px; border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
}
.mem-card.back::after {
  content: ""; position: absolute; width: 27%; height: 27%; transform: rotate(45deg);
  border: 1px solid color-mix(in srgb, var(--gold) 55%, transparent);
}
.mem-card.back .emblem { position: relative; width: 22%; height: 22%; color: var(--gold-light); }
.mem-card.is-clickable { cursor: pointer; }
.mem-card.is-clickable:hover { transform: translateY(-2px); box-shadow: 0 7px 18px rgba(0, 0, 0, .5); }
.mem-card.face {
  background: linear-gradient(160deg, #efdcb4, #d6bd92); border: 1px solid #b89a63; color: #2e1f0e;
  animation: memFlip .28s ease;
}
.mem-card.sel {
  box-shadow: 0 0 0 3px var(--accent-ink), 0 6px 18px rgba(0, 0, 0, .55); transform: translateY(-2px);
}
.mem-card.match {
  opacity: .55; box-shadow: 0 0 0 2px var(--gold-ink), 0 0 16px color-mix(in srgb, var(--gold) 45%, transparent);
  animation: memMatch .5s ease;
}
.mem-card.miss { box-shadow: 0 0 0 3px var(--red-light); animation: memMiss .4s ease; }
.mem-card .owner {
  position: absolute; bottom: 6px; right: 6px; width: 13px; height: 13px; border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, .45);
}

.memory-progress { margin: 0; font-size: 12px; color: var(--smoke); }
/* Personal miss counter — a touch brighter than the rest of the progress line so it reads as
   the number to beat, without shouting. */
.memory-miss-count { color: var(--old-paper); font-weight: 600; white-space: nowrap; }

/* Solo end-screen summary (under the final score in the podium): misses + time tiles and a
   personal-best line (gold when beaten). Only rendered for single-player Memory games. */
.mem-solo { margin-top: 12px; }
.mem-solo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mem-solo-tile { display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 12px 8px; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); }
.mem-solo-val { font-family: 'Rye', serif; font-size: 26px; line-height: 1; color: var(--accent-ink); }
.mem-solo-lbl { font-size: 11px; color: var(--old-paper); letter-spacing: .03em; }
.mem-solo-record { margin-top: 12px; text-align: center; font-size: 13px; padding: 9px 12px; border-radius: 9px; }
.mem-solo-record.best { color: var(--gold-ink); font-weight: 700;
  background: color-mix(in srgb, var(--gold) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--gold) 50%, transparent); }
.mem-solo-record.par { color: var(--old-paper);
  background: rgba(255,255,255,.03); border: 1px solid var(--border); }

/* Felt table under the board: Memory is a table game, so the cards sit on a felt
   surface instead of the empty dark panel. Reuses the card-game --felt-* tokens
   (theme-aware, Light + Dark), tinted with the memory accent. The felt WRAPS
   .memory-fit — fitMemory still measures the padding-free .memory-fit box, so the
   maximize scaling (--mem-cell) is unaffected. */
.memory-felt {
  border-radius: 14px;
  border: 8px solid var(--felt-rim);
  background: radial-gradient(ellipse at 50% 40%,
    color-mix(in srgb, var(--accent) var(--felt-mix-a, 14%), var(--felt-base-a)) 0%,
    color-mix(in srgb, var(--accent) var(--felt-mix-b, 26%), var(--felt-base-b)) 60%,
    color-mix(in srgb, var(--accent) var(--felt-mix-c, 32%), var(--felt-base-c)) 100%);
  box-shadow: var(--felt-shadow);
  padding: 16px;
}

@keyframes memFlip  { from { transform: rotateY(90deg); } to { transform: rotateY(0); } }
@keyframes memMatch { 0% { box-shadow: 0 0 0 3px var(--gold), 0 0 26px var(--gold); opacity: 1; } 100% { opacity: .55; } }
@keyframes memMiss  { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }

/* ══════════════════════════════════════════════════════════════════════════
   DURAK — playing cards, table, hand. Own .durak-* / .durak-card classes
   (does NOT override global .card). Accent via .mode-durak.
   ══════════════════════════════════════════════════════════════════════════ */
.durak-board { --card-w: 60px; --card-h: 84px; display: flex; flex-direction: column; gap: 14px; }
.durak-topbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.durak-chip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px; padding: 5px 11px; border-radius: 999px;
  background: var(--edge); border: 1px solid var(--border); color: var(--old-paper);
}
/* Phase chip keeps its filled accent gradient in both themes — the fill stays
   mid-dark (accent + black), so the label ink is pinned to the raw palette. */
.durak-chip.phase { background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 80%, #000), var(--accent)); border-color: var(--accent-light); color: var(--raw-parchment); font-weight: 600; }
.durak-chip b { color: var(--heading); }

/* ── Card ── */
.durak-card {
  --card-w: 88px; --card-h: 124px;   /* significantly larger cards (mini overrides) */
  position: relative; width: var(--card-w, 60px); height: var(--card-h, 84px); flex: 0 0 auto; border-radius: 7px;
  color: #3a2a1a; font-family: 'Rye', serif; line-height: 1;
  background:
    radial-gradient(ellipse at 24% 16%, rgba(120, 80, 35, .13) 0 22%, transparent 47%),
    radial-gradient(ellipse at 82% 86%, rgba(120, 80, 35, .14) 0 20%, transparent 45%),
    linear-gradient(155deg, #f6ead0 0%, #ecd9af 55%, #dec79c 100%);
  box-shadow: 0 3px 7px rgba(0, 0, 0, .5), inset 0 0 16px rgba(90, 58, 22, .30), inset 0 0 0 1px rgba(255, 250, 235, .5);
  transition: transform .12s ease, box-shadow .12s ease;
}
.durak-card::before {
  content: ""; position: absolute; inset: 3px; border-radius: 5px; pointer-events: none;
  border: 1px solid color-mix(in srgb, #3a2a1a 42%, transparent);
  box-shadow: inset 0 0 0 1.5px rgba(246, 238, 214, .55), inset 0 0 0 2.5px color-mix(in srgb, #3a2a1a 16%, transparent);
}
.durak-card.red { color: #9a2b2b; }
.durak-card .corner { position: absolute; display: flex; flex-direction: column; align-items: center; gap: 1px; z-index: 1; }
.durak-card .corner.tl { top: 5px; left: 6px; }
.durak-card .corner.br { bottom: 5px; right: 6px; transform: rotate(180deg); }
.durak-card .corner .r { font-size: 18px; font-variant-numeric: tabular-nums; text-shadow: 0 1px 0 rgba(255, 250, 235, .4); }
.durak-card .corner .s { font-size: 12px; font-family: var(--font-body); }
.durak-card .pip { position: absolute; inset: 0; display: grid; place-items: center; font-size: 40px; font-family: var(--font-body); z-index: 1; }
.durak-card .pip::before {
  content: ""; position: absolute; width: 54px; height: 54px; transform: rotate(45deg); border-radius: 9px; opacity: .5;
  border: 1px solid color-mix(in srgb, #3a2a1a 32%, transparent); box-shadow: inset 0 0 0 3px rgba(246, 238, 214, .35);
}
/* Face cards now show the suit symbol centered (like number cards) — no separate court pip anymore. */
/* Narrow screens: cards more compact again, otherwise the hand exceeds the width. */
@media (max-width: 640px) {
  .durak-card { --card-w: 62px; --card-h: 87px; }
  .durak-card .pip { font-size: 30px; } .durak-card .pip::before { width: 40px; height: 40px; }
  .durak-card .corner .r { font-size: 14px; } .durak-card .corner .s { font-size: 10px; }
}

/* Back face */
.durak-card.back {
  color: var(--gold-light); font-family: var(--font-body);
  background:
    repeating-linear-gradient(45deg, rgba(0, 0, 0, .15) 0 5px, transparent 5px 10px),
    repeating-linear-gradient(-45deg, rgba(0, 0, 0, .15) 0 5px, transparent 5px 10px),
    radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--accent-light) 42%, transparent) 0 30%, transparent 60%),
    linear-gradient(155deg, var(--accent), color-mix(in srgb, var(--accent) 46%, #000));
  box-shadow: 0 3px 7px rgba(0, 0, 0, .55), inset 0 0 0 2px var(--gold), inset 0 0 0 4px #f1e4c4, inset 0 0 0 6px var(--gold);
}
.durak-card.back::before { content: none; }
.durak-card.back::after { content: "★"; position: absolute; inset: 0; display: grid; place-items: center; font-size: 24px; color: var(--gold-light); text-shadow: 0 0 8px rgba(0, 0, 0, .5); }

.durak-card.trump { box-shadow: 0 0 0 2px var(--heading), 0 4px 14px color-mix(in srgb, var(--gold-light) 55%, transparent), inset 0 0 16px rgba(90, 58, 22, .30), inset 0 0 0 1px rgba(255, 250, 235, .5); }
.durak-card.playable { cursor: pointer; box-shadow: 0 0 0 2px var(--accent-ink), 0 5px 14px rgba(0, 0, 0, .5), inset 0 0 16px rgba(90, 58, 22, .28), inset 0 0 0 1px rgba(255, 250, 235, .5); }
.durak-card.playable:hover { transform: translateY(-14px); }
.durak-card.sel { transform: translateY(-18px); box-shadow: 0 0 0 3px var(--heading), 0 10px 18px rgba(0, 0, 0, .55), inset 0 0 16px rgba(90, 58, 22, .28); }
.durak-card.dim { filter: grayscale(.5) brightness(.7) sepia(.2); opacity: .82; }
/* Skat "drücken": not-yet-picked cards read as choosable (pointer + small hover lift);
   the picked ones use .sel (raised + gold ring) so the selection is unmistakable. */
.durak-card.pickable { cursor: pointer; }
.durak-card.pickable:hover { transform: translateY(-8px); }

/* Mini (opponent fan / deck) */
.durak-card.mini { --card-w: 34px; --card-h: 48px; border-radius: 5px; }
.durak-card.mini::before { inset: 2px; border-radius: 3px; box-shadow: none; }
.durak-card.mini .pip::before { display: none; }
.durak-card.mini.back::after { font-size: 15px; }
.durak-card.mini .corner .r { font-size: 9px; } .durak-card.mini .corner .s { font-size: 7px; } .durak-card.mini .pip { font-size: 16px; }
.durak-card.mini .corner.tl { top: 3px; left: 4px; } .durak-card.mini .corner.br { bottom: 3px; right: 4px; }

/* ── Opponent seats ── */
.durak-seats { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
.durak-seat { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 9px 11px; border-radius: 14px; background: color-mix(in srgb, var(--edge) 45%, transparent); border: 1px solid var(--border); min-width: 116px; }
.durak-seat.turn { border-color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 18%, transparent); box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 35%, transparent); }
.durak-seat.out { opacity: .5; }
.durak-seat .who { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--parchment); font-weight: 600; }
.durak-seat .fan { display: flex; }
.durak-seat .fan .durak-card { margin-left: -22px; } .durak-seat .fan .durak-card:first-child { margin-left: 0; }
/* Showdown: opponent hole cards revealed full-size, side by side (like community/own cards). */
.durak-seat .fan.reveal { gap: 6px; }
.durak-seat .fan.reveal .durak-card { margin-left: 0; }
.durak-seat .cnt { font-size: 12px; color: var(--smoke); }
.durak-role { font-size: 12px; font-weight: 700; padding: 2px 7px; border-radius: 999px; letter-spacing: .3px; }
.durak-role.att { background: rgba(192, 53, 42, .18); color: var(--red-light); border: 1px solid color-mix(in srgb, var(--blood-red) 60%, transparent); }
.durak-role.def { background: color-mix(in srgb, var(--accent) 30%, transparent); color: var(--accent-ink); border: 1px solid var(--accent-ink); }

/* ── Table ── */
.durak-table { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; justify-content: center; padding: 20px; border-radius: 18px;
  background: radial-gradient(420px 200px at 50% 40%, color-mix(in srgb, var(--accent) 24%, transparent) 0%, transparent 70%), color-mix(in srgb, var(--well) 50%, transparent); border: 1px solid var(--border); }
.durak-deck { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.durak-deck-stack { position: relative; width: calc(var(--card-h) + 8px); height: calc(var(--card-h) + 6px); }
.durak-deck-stack .laid { position: absolute; left: 0; top: 19px; transform: rotate(90deg); transform-origin: center; }
.durak-deck-stack .pile { position: absolute; right: 0; top: 0; width: var(--card-w); height: var(--card-h); }
/* Anchored to the right so the back-face stack stays within the deck box and does not
   intrude into the battle area (hint text 'No cards in play yet.'). Offsets fan out to the left. */
.durak-deck-stack .pile .durak-card { position: absolute; top: 0; right: 0; }
.durak-deck-stack .pile .durak-card:nth-child(2) { right: 3px; top: 2px; }
.durak-deck-stack .pile .durak-card:nth-child(3) { right: 6px; top: 4px; }
.durak-deck-info { font-size: 12px; color: var(--old-paper); text-align: center; }
.durak-deck-info b { color: var(--parchment); font-variant-numeric: tabular-nums; }
.durak-battle { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; min-height: 110px; align-items: flex-start; }
.durak-pair { position: relative; width: var(--card-w); height: calc(var(--card-h) + 26px); }
.durak-pair .att { position: absolute; top: 0; left: 0; }
.durak-pair .def { position: absolute; top: 24px; left: 18px; transform: rotate(8deg); z-index: 2; }
.durak-pair.open.sel-target { cursor: pointer; }

/* ── Own hand ── */
.durak-hand-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.durak-hand-head .grow { flex: 1; }
.durak-hand { display: flex; padding-top: 18px; justify-content: center; flex-wrap: wrap; }
.durak-hand .durak-card { margin-left: -20px; } .durak-hand .durak-card:first-child { margin-left: 0; }
.durak-hint { font-size: 12px; color: var(--smoke); }

/* ── Game end (Durak reveal) ── */
.durak-spotlight { text-align: center; padding: 22px; border-radius: 16px; margin-bottom: 16px;
  background: radial-gradient(520px 240px at 50% 30%, color-mix(in srgb, var(--blood-red) 28%, transparent) 0%, transparent 70%), color-mix(in srgb, var(--well) 62%, transparent); border: 1px solid var(--border); }
.durak-stamp { font-family: 'Rye', serif; font-size: 46px; color: var(--red-light); border: 5px double var(--red-light); border-radius: 12px; padding: 4px 26px; transform: rotate(-7deg); display: inline-block; margin: 6px 0 16px; letter-spacing: 6px; text-shadow: 0 2px 7px rgba(0, 0, 0, .5); }
.durak-stamp.shared { color: var(--heading); border-color: var(--heading); }
.durak-who { font-family: 'Rye', serif; font-size: 20px; color: var(--parchment); margin-bottom: 4px; }
.durak-sub { font-size: 13px; color: var(--smoke); margin-bottom: 14px; }
.durak-reveal-hand { display: flex; gap: 9px; justify-content: center; flex-wrap: wrap; }
.durak-ranks { display: flex; flex-direction: column; gap: 9px; }
.durak-rank { display: flex; align-items: center; gap: 13px; padding: 11px 15px; border-radius: 11px; background: color-mix(in srgb, var(--edge) 50%, transparent); border: 1px solid var(--border); }
.durak-rank .medal { font-size: 21px; flex: 0 0 28px; text-align: center; }
.durak-rank .nm { font-size: 15px; color: var(--parchment); font-weight: 600; }
.durak-rank .stat { flex: 1; text-align: right; font-size: 12px; color: var(--smoke); }
.durak-rank.win { border-color: color-mix(in srgb, var(--gold) 50%, transparent); background: var(--surface-2); }
.durak-rank.durak { border-color: color-mix(in srgb, var(--blood-red) 60%, transparent); background: rgba(139, 26, 26, .14); }
.durak-rank.durak .nm { color: var(--red-light); }

/* ══════════════════════════════════════════════════════════════════════════
   BATTLESHIP — grid, cell states, shipyard, standings. Own .see-* classes.
   Accent via .mode-seeschlacht.
   ══════════════════════════════════════════════════════════════════════════ */
.see-wrap { max-width: 1080px; margin: 0 auto; width: 100%; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.see-topbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* .see-chip is identical to .durak-chip — intentionally NOT merged.
   Both belong to the four new deliberately namespaced/isolated game modules
   (Battleship/Durak); a shared class would couple two independent modules. */
.see-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; padding: 5px 11px; border-radius: 999px;
  background: var(--edge); border: 1px solid var(--border); color: var(--old-paper); }
/* Filled accent chip stays mid-dark in both themes — raw ink (see .durak-chip.phase). */
.see-chip.phase { background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 80%, #000), var(--accent)); border-color: var(--accent-light); color: var(--raw-parchment); font-weight: 600; }
.see-chip.see-timer { color: var(--heading); border-color: var(--border-strong); font-variant-numeric: tabular-nums; }
.see-chip.see-timer.danger { color: var(--red-light); border-color: var(--red-light); animation: seeTimerPulse 1s ease-in-out infinite; }
@keyframes seeTimerPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(192,53,42,.0); } 50% { box-shadow: 0 0 10px 1px rgba(192,53,42,.5); } }

/* Shared 'stage': board + shipyard/fleet bar sit in ONE bordered box that shrinks to content
   width (centered horizontally as a group with the topbar) — no more free drifting apart.
   Applies to placement phase, shared sea, and fleet duel (all use .see-main). */
.see-main {
    display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap;
    align-self: center;
    padding: 16px; border-radius: 16px;
    background: color-mix(in srgb, var(--well) 53%, transparent); border: 1px solid var(--border);
}
/* Shipyard/fleet bar blends into the stage: no separate box, just a fine separator. */
.see-main > .see-panel { flex: 0 0 230px; background: transparent; border: none; border-radius: 0; padding: 0 0 0 16px; border-left: 1px solid var(--edge); }
@media (max-width: 760px) {
    .see-main { align-self: stretch; }
    /* The desktop measure-fit pins one row (.card-board .see-main nowrap, see the
       card-board block) — below the maximize breakpoint boards + shipyard must
       stack again, otherwise the duel boards overflow narrow viewports. */
    .card-board .see-main { flex-wrap: wrap; }
    .see-main > .see-panel { flex: 1 1 100%; border-left: none; border-top: 1px solid var(--edge); padding: 14px 0 0; }
}

/* ── Board ── */
/* Subtle navy border so the board looks 'anchored' rather than floating without a frame. */
.see-board-wrap { display: inline-grid; gap: 4px; padding: 9px; border-radius: 12px;
    background: color-mix(in srgb, var(--accent) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); }
.see-board-wrap .corner { width: 18px; }
.see-collabels, .see-rowlabel { color: var(--smoke); font-size: 12px; text-align: center; }
.see-board { display: grid; gap: 2px; }
.see-cell {
  aspect-ratio: 1; min-width: 16px; border-radius: 3px; border: none; padding: 0; cursor: default;
  display: grid; place-items: center; font-size: 12px; line-height: 1; color: #fff;
  background: repeating-linear-gradient(45deg, rgba(43, 79, 116, .10) 0 6px, rgba(43, 79, 116, .04) 6px 12px), #142a40;
}
.see-cell.fog { background: repeating-linear-gradient(45deg, rgba(255, 255, 255, .035) 0 6px, transparent 6px 12px), #0f2235; }
.see-cell.ship { background: linear-gradient(135deg, var(--accent-light), var(--accent)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18); }
.see-cell.shiphit { background: linear-gradient(135deg, var(--accent), #2a1620); box-shadow: inset 0 0 0 2px var(--red-light); color: #fff; }
.see-cell.shiphit::after { content: "✕"; color: var(--red-light); font-weight: 700; }
.see-cell.miss { background: #112335; }
.see-cell.miss::after { content: "•"; color: var(--smoke); font-size: 14px; }
.see-cell.unk { background: radial-gradient(circle, #b5602a, #7a3a12); }
.see-cell.unk::after { content: "?"; font-weight: 700; }
.see-cell.sunk { background: repeating-linear-gradient(45deg, #2b4f74 0 4px, #10243a 4px 8px); color: var(--parchment); }
.see-cell.sunk::after { content: "☠"; font-size: 12px; }
.see-cell.hit { background: radial-gradient(circle, #c0352a, #8b1a1a); }
.see-cell.hit::after { content: "✕"; color: #fff; font-weight: 700; }
.see-cell.pending { background: rgba(232, 184, 75, .16); box-shadow: inset 0 0 0 1px var(--gold-light); }
.see-cell.pending::after { content: "✛"; color: var(--gold-light); font-weight: 700; }
.see-cell.pok { background: rgba(45, 122, 74, .30); box-shadow: inset 0 0 0 1px #5fcf8a; }
.see-cell.pbad { background: rgba(192, 53, 42, .28); box-shadow: inset 0 0 0 1px var(--red-light); }
.see-cell.clickable { cursor: pointer; }
.see-cell.clickable:hover { outline: 2px solid var(--accent-light); outline-offset: -2px; }
.see-cell.ownx { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent-light) 60%, transparent); } /* opponent ship (spectator) */
/* Shared sea: empty tiles (odd player count) darkened/hatched — never shootable. */
.see-cell.empty-tile { background: repeating-linear-gradient(45deg, rgba(0,0,0,.35) 0 5px, rgba(0,0,0,.18) 5px 10px), #0a141f; opacity: .55; cursor: default; }
/* Fine separator at tile borders (right/bottom edge of each tile). */
.see-cell.sep-r { box-shadow: inset -2px 0 0 color-mix(in srgb, var(--accent-light) 55%, transparent); }
.see-cell.sep-b { box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--accent-light) 55%, transparent); }
.see-cell.sep-r.sep-b { box-shadow: inset -2px 0 0 color-mix(in srgb, var(--accent-light) 55%, transparent), inset 0 -2px 0 color-mix(in srgb, var(--accent-light) 55%, transparent); }
/* Hidden ship count (lobby option). */
.see-stand .pships.hidden-cnt { color: var(--smoke); font-size: 14px; }

/* ── Shipyard (placement phase) ── */
.see-werft { display: flex; flex-direction: column; gap: 7px; }
.see-ship-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 9px; cursor: pointer;
  background: color-mix(in srgb, var(--edge) 45%, transparent); border: 1px solid var(--border); }
.see-ship-item.sel { border-color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 18%, transparent); }
.see-ship-item.done { opacity: .5; }
.see-ship-item .ship-vis { display: flex; gap: 2px; }
.see-ship-item .ship-vis i { width: 12px; height: 12px; border-radius: 2px; background: linear-gradient(135deg, var(--accent-light), var(--accent)); }
.see-ship-item .nm { font-size: 13px; color: var(--parchment); }
.see-ship-item .sz { margin-left: auto; font-size: 12px; color: var(--smoke); }

/* ── Standings (sidebar) ── */
.see-panel { background: color-mix(in srgb, var(--well) 53%, transparent); border: 1px solid var(--border); border-radius: 14px; padding: 14px; }
.see-panel h3 { font-size: 13px; color: var(--gold-ink); margin: 0 0 12px; letter-spacing: .4px; }
.see-stand { display: flex; align-items: center; gap: 9px; padding: 8px 9px; border-radius: 9px; margin-bottom: 5px; background: color-mix(in srgb, var(--edge) 30%, transparent); }
.see-stand.turn { background: color-mix(in srgb, var(--accent) 18%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent); }
.see-stand.out { opacity: .5; }
.see-stand .pname { font-size: 13px; color: var(--parchment); font-weight: 600; }
.see-stand .pships { margin-left: auto; font-size: 12px; color: var(--old-paper); font-variant-numeric: tabular-nums; }
.see-stand .pships.gone { color: var(--red-light); }

.see-banner { align-self: flex-start; max-width: 100%; padding: 10px 14px; border-radius: 10px; background: rgba(139, 26, 26, .14); border: 1px solid color-mix(in srgb, var(--blood-red) 50%, transparent); color: var(--parchment); font-size: 13px; }
.see-status { font-size: 12.5px; color: var(--smoke); }
/* Battleship footer (shot status) uses the shared card-actions-bar; in the
   flex column .see-wrap it must be stretched to full width so it docks at the
   bottom panel edge like in lobby/card games. */
/* Split Battleship status footer: incoming fire on the left, own shot on the right. */
.see-footer .see-st-in  { justify-content: flex-start; }
.see-footer .see-st-out { justify-content: flex-end; text-align: right;
  border-left: 1px solid var(--border-soft); padding-left: 14px; margin-left: 8px; }
.see-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; justify-content: center; }
/* Compact, side-by-side action buttons (fire + clear). Without this the block-level .btn
   (width:100%) forced each button onto its own row, so selecting a target added a row of
   height → the height-fitted board shrank on every click. */
.see-actions .btn { display: inline-flex; width: auto; flex: 0 0 auto; }

/* ── Fleet duel (variant A): board heading + opponent tabs above the target board ── */
.see-board-h { font-size: 13px; color: var(--gold-ink); margin: 0 0 8px; letter-spacing: .3px; }
.see-targets { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 8px; }
.see-target-tab { padding: 5px 11px; border-radius: 999px; border: 1px solid var(--border); background: color-mix(in srgb, var(--edge) 45%, transparent); color: var(--old-paper); font-size: 12.5px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.see-target-tab:hover:not(.out) { border-color: var(--accent-ink); color: var(--parchment); }
.see-target-tab.active { background: color-mix(in srgb, var(--accent) 24%, transparent); border-color: var(--accent-ink); color: var(--parchment); box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 35%, transparent); }
.see-target-tab.out { opacity: .45; cursor: default; text-decoration: line-through; }
.see-target-tab .t-ships { font-size: 12px; color: var(--smoke); font-variant-numeric: tabular-nums; }
.see-target-tab.active .t-ships { color: var(--heading); }

/* ── Animations (nautical). Play once on class change (fog/ship -> hit/sunk/miss). ── */
.see-cell.hit, .see-cell.shiphit { animation: seeHit .5s ease-out; }
.see-cell.unk { animation: seeHit .5s ease-out; }
.see-cell.miss { animation: seeSplash .6s ease-out; }
.see-cell.sunk { animation: seeSink .9s ease-in; }

@keyframes seeHit {
  0%   { transform: scale(.35); filter: brightness(2.6); box-shadow: 0 0 0 0 rgba(232, 184, 75, .8); }
  45%  { transform: scale(1.18); filter: brightness(1.6); box-shadow: 0 0 10px 4px rgba(192, 53, 42, .65); }
  100% { transform: scale(1);    filter: brightness(1);   box-shadow: 0 0 0 0 rgba(192, 53, 42, 0); }
}
@keyframes seeSplash {
  0%   { box-shadow: 0 0 0 0 rgba(122, 162, 200, .55); }
  70%  { box-shadow: 0 0 0 7px rgba(122, 162, 200, .12); }
  100% { box-shadow: 0 0 0 9px rgba(122, 162, 200, 0); }
}
@keyframes seeSink {
  0%   { transform: translateY(-3px) scale(1.15) rotate(-6deg); filter: brightness(1.8); }
  35%  { transform: translateY(1px)  scale(1.05) rotate(5deg);  filter: brightness(1.3); }
  70%  { transform: translateY(3px)  scale(.96)  rotate(-3deg); filter: brightness(.95); }
  100% { transform: translateY(0)    scale(1)    rotate(0);     filter: brightness(.78); }
}

/* ── Start overlay after the placement phase ('You go first!' / 'Battle opened!') ──
   Absolute child over the card-board; Game.razor hides it again after ~2 s.
   Accent from .mode-seeschlacht. */
.see-start-ov {
  position: absolute; inset: 0; z-index: 40; border-radius: inherit;
  display: grid; place-items: center; padding: 18px; overflow: hidden;
  background:
    repeating-linear-gradient(45deg, rgba(43, 79, 116, .05) 0 14px, transparent 14px 28px),
    radial-gradient(120% 90% at 50% 120%, rgba(43, 79, 116, .42), rgba(8, 12, 18, .93) 72%);
  animation: seeStartFade .3s ease both;
}
@keyframes seeStartFade { from { opacity: 0; } to { opacity: 1; } }
.see-start-card { position: relative; text-align: center; max-width: 560px;
  animation: seeStartRise .5s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes seeStartRise { from { opacity: 0; transform: translateY(18px) scale(.96); } to { opacity: 1; transform: none; } }

/* The start overlay keeps its fixed dark nautical backdrop in both themes —
   all inks below are pinned to raw/theme-independent palette values. */
.see-start-vs { display: flex; align-items: center; justify-content: center; gap: 26px; margin-bottom: 18px; }
.see-start-mid { font-family: 'Rye', serif; color: var(--raw-gold); font-size: 22px; opacity: .8; }
.see-start-fleet { display: flex; align-items: flex-start; justify-content: center; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }

.see-start-pl { display: flex; flex-direction: column; align-items: center; gap: 7px; opacity: .5; transition: opacity .3s; }
.see-start-pl.active, .see-start-fleet .see-start-pl { opacity: 1; }
.see-start-crown { font-size: 18px; height: 20px; line-height: 1; }
.see-start-nm { font-size: 13px; color: var(--raw-smoke); max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.see-start-pl.active .see-start-nm { color: var(--raw-parchment); font-weight: 600; }

/* Spotlight for the first shooter (duel) — glow ring + pulse on the round avatar. */
.see-start-pl.active .avatar { box-shadow: 0 0 0 4px rgba(77, 126, 171, .28), 0 0 34px rgba(77, 126, 171, .6);
  animation: seeStartPulse 1.6s ease-in-out infinite; }
@keyframes seeStartPulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(77, 126, 171, .25), 0 0 30px rgba(77, 126, 171, .5); }
  50%      { box-shadow: 0 0 0 6px rgba(77, 126, 171, .35), 0 0 46px rgba(77, 126, 171, .85); }
}
/* Salvo: you yourself gold-bordered (there is no first shooter). */
.see-start-fleet .see-start-pl.me .avatar { box-shadow: 0 0 0 3px rgba(232, 184, 75, .28), 0 0 24px rgba(232, 184, 75, .55); }

.see-start-anchor { font-size: 26px; filter: drop-shadow(0 2px 6px #000); margin-bottom: 4px; }
.see-start-eyebrow { font-size: 12px; letter-spacing: .26em; text-transform: uppercase; color: var(--accent-light); margin-bottom: 7px; }
.see-start-title { font-family: 'Rye', serif; font-size: clamp(30px, 5vw, 44px); line-height: 1.05; margin: 0 0 8px;
  background: linear-gradient(180deg, #eaf2fb, var(--accent-light)); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 10px rgba(43, 79, 116, .6)); }
.see-start-title.enemy { background: linear-gradient(180deg, #f0e3c6, var(--gold)); -webkit-background-clip: text; background-clip: text; }
.see-start-sub { font-size: 14px; color: var(--raw-old-paper); margin: 0 0 14px; }
.see-start-hint { font-size: 12px; color: var(--raw-smoke); }

.see-start-wait { display: inline-flex; align-items: center; gap: 9px; font-size: 13px; color: var(--raw-smoke); }
.see-start-dots { display: inline-flex; gap: 4px; }
.see-start-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--raw-smoke); animation: seeStartBlink 1.2s infinite; }
.see-start-dots i:nth-child(2) { animation-delay: .2s; }
.see-start-dots i:nth-child(3) { animation-delay: .4s; }
@keyframes seeStartBlink { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

/* ════════════════════════════
   LOBBY REDESIGN (mode-specific) — 'At the Table' / 'The Stage'
   Accent comes from .mode-* (--accent / --accent-light), applied
   at the .screen-lobby root. Used consistently here.
════════════════════════════ */
.lobby-redesign .lobby-title,
.lobby-redesign .lobby-section-title { color: color-mix(in srgb, var(--accent) 30%, var(--text-main)); }
.lobby-arena { padding: 18px 20px; }

/* ── At the table: elliptical felt surface with seats around it ── */
.lobby-table .felt {
  position: relative;
  height: 420px;   /* same default height as the stage (.lobby-stage-theatre) */
  margin-top: 12px;
  border-radius: 50% / 44%;
  border: 10px solid var(--felt-rim);
  background:
    radial-gradient(ellipse at 50% 42%,
      color-mix(in srgb, var(--accent) var(--felt-mix-a, 14%), var(--felt-base-a)) 0%,
      color-mix(in srgb, var(--accent) var(--felt-mix-b, 26%), var(--felt-base-b)) 60%,
      color-mix(in srgb, var(--accent) var(--felt-mix-c, 32%), var(--felt-base-c)) 100%);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent),
              var(--felt-shadow);
}
.lobby-table .seat {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 104px;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  text-align: center;
}
.seat-filled {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--parchment); font: inherit;
  transition: transform .12s;
}
.seat-filled:hover { transform: translate(-50%, -50%) scale(1.06); }
.seat-name {
  font-size: 14px; color: var(--parchment);
  max-width: 108px; overflow: hidden; white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center; gap: 3px;
}
.seat-filled.is-host .seat-name { color: var(--text-main); font-weight: 600; }
.seat-filled.is-away { opacity: .55; }
.seat-badge.badge-host { color: color-mix(in srgb, var(--accent) 30%, var(--text-main)); }
.seat-you {
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--text-main);
}
.seat-ghost .seat-avatar-empty {
  width: 44px; height: 44px; border-radius: 50%; margin: 0 auto; font-size: 18px;
  border: 1px dashed color-mix(in srgb, var(--accent) 45%, rgba(200,146,42,.3));
  display: flex; align-items: center; justify-content: center; color: var(--text-main);
  background: var(--surface-2);
}
.seat-ghost .seat-name { color: var(--text-main); opacity: .75; }

/* ── The Stage: audience (comfortable up to 10, dense crowd beyond that) ── */
.aud-cluster {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px;
  max-height: 160px; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: rgba(200,146,42,.2) transparent;
}
.aud-dot {
  position: relative; width: 32px; height: 32px; border-radius: 50%; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid color-mix(in srgb, var(--accent) 35%, rgba(200,146,42,.25));
  background: rgba(8,5,2,.4); cursor: pointer; overflow: visible;
}
.aud-dot.is-host { border-color: var(--accent-light); box-shadow: 0 0 8px color-mix(in srgb, var(--accent-light) 45%, transparent); }
.aud-dot.is-me { border-color: var(--accent-light); border-width: 2px; }
.aud-dot .dot-star { position: absolute; top: -6px; right: -4px; font-size: 12px; color: var(--accent-light); }
.aud-more {
  width: 32px; height: 32px; border-radius: 50%;
  border: 1.5px dashed var(--accent); background: rgba(8,5,2,.4);
  color: var(--accent-light); font-size: 12px; cursor: pointer;
}
.aud-more:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); }

/* All players modal */
.all-players-grid { display: flex; flex-direction: column; gap: 4px; max-height: 60vh; overflow-y: auto; }
.all-player-row {
  display: flex; align-items: center; gap: 10px;
  background: rgba(8,5,2,.3); border: 1px solid rgba(200,146,42,.14);
  border-radius: 4px; padding: 6px 10px; cursor: pointer; color: var(--parchment); font: inherit;
}
.all-player-row:hover { border-color: var(--accent); }
.all-player-name { font-size: 14px; }

/* ── Chat: collapsible + privacy veil ── */
.chat-title-row { display: flex; align-items: center; justify-content: space-between; }
.chat-collapse-btn, .chat-reopen {
  background: rgba(8,5,2,.4); border: 1px solid rgba(200,146,42,.24);
  color: var(--smoke); cursor: pointer; transition: all .15s; font-family: var(--font-body);
}
.chat-collapse-btn { border-radius: 3px; padding: 3px 9px; font-size: 13px; }
.chat-collapse-btn:hover, .chat-reopen:hover { border-color: var(--accent); color: var(--accent-light); }
.chat-reopen { width: 100%; text-align: center; padding: 12px; border-style: dashed; border-radius: 4px; font-size: 14px; }
.chat-messages-wrap { position: relative; }

/* ── Lobby header as hero/shield: code prominent, spotlight, accent ── */
.lobby-redesign .lobby-hero {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 22%, #160f08) 0%, #120c07 100%);
  border: 1px solid var(--accent);
}
.lobby-redesign .lobby-hero::before {
  content: ""; position: absolute; top: -60%; left: 50%; transform: translateX(-50%);
  width: 55%; height: 180%; pointer-events: none; z-index: 0;
  background: radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--accent-light) 22%, transparent) 0%, transparent 60%);
}
.lobby-redesign .lobby-hero .lobby-title,
.lobby-redesign .lobby-hero .lobby-header-row { position: relative; z-index: 1; }
.lobby-redesign .lobby-hero .lobby-code {
  border-color: var(--accent);
  box-shadow: 0 0 26px color-mix(in srgb, var(--accent) 34%, transparent), inset 0 0 16px rgba(0,0,0,.6);
}
.lobby-redesign .lobby-hero .streamer-toggle.is-on { border-color: var(--accent); color: var(--accent-light); }
.lobby-redesign .lobby-hero .btn-copy:hover { border-color: var(--accent); color: var(--accent-light); }
/* Stage hero: prop + 'On stage today' + game name as marquee */
.lobby-redesign .lobby-hero { padding: 12px 22px; }
.lobby-redesign .lobby-hero .buhne-eyebrow { font-size: 12px; letter-spacing: .26em; text-transform: uppercase; color: var(--smoke); position: relative; z-index: 1; }
.lobby-redesign .lobby-hero .buhne-game { display: flex; align-items: center; justify-content: center; gap: 7px; font-family: 'Rye', cursive; font-size: 28px; color: var(--accent-light); position: relative; z-index: 1; margin: 2px 0 10px; }
.lobby-redesign .lobby-hero .buhne-prop { font-size: 24px; line-height: 1; filter: drop-shadow(0 2px 4px #000); }

/* ── Unified code box: code centered, visibility on left + eye on right integrated, copy below ── */
.code-box-wrap { display: flex; flex-direction: column; align-items: center; gap: 7px; position: relative; z-index: 1; }
.code-box {
  position: relative; display: flex; align-items: center; justify-content: center;
  background: var(--surface-1-strong); border: 1px solid var(--accent); border-radius: 3px; padding: 6px 44px;
  box-shadow: 0 0 22px color-mix(in srgb, var(--accent) 30%, transparent), inset 0 0 14px var(--shadow-color);
}
.code-box-text { font-family: 'Rye', cursive; letter-spacing: .2em; color: var(--heading); font-size: 23px; }
.code-box-vis { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); font-size: 13px; line-height: 1; opacity: .85; }
.code-box-eye {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: transparent; border: none; cursor: pointer;
  color: var(--smoke); font-size: 15px; line-height: 1; padding: 4px;
  min-width: 24px; min-height: 24px;   /* WCAG 2.5.8 */
}
.code-box-eye:hover, .code-box-eye.is-on { color: var(--accent-strong); }
.code-box-wrap .btn-copy { color: color-mix(in srgb, var(--accent) 30%, var(--text-main)); border-color: var(--accent); }
.lobby-hero .code-box-text { font-size: 25px; }
.lobby-hero .code-box { padding: 6px 46px; }

/* ── Mobile (≤700px): felt ellipse → compact felt card, seats wrap, boxes tighter ── */
@media (max-width: 700px) {
  .screen-lobby.lobby-redesign { padding: 16px 10px 34px; }
  .lobby-arena { padding: 14px 12px; }
  .lobby-redesign .lobby-stage-theatre { min-height: 300px; }
  .lobby-table .felt {
    height: auto; border-radius: 12px; border-width: 5px;
    display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
    gap: 14px 8px; padding: 16px 10px 18px;
  }
  .lobby-table .radar { display: none; }
  .lobby-table .felt-center { position: static; transform: none; width: 100%; flex-basis: 100%; margin-bottom: 2px; }
  .lobby-table .seat { position: static; transform: none; width: 72px; }
  .lobby-table .seat-filled:hover { transform: scale(1.04); }
  .code-box { padding: 6px 36px; }
  .code-box-text, .lobby-hero .code-box-text { font-size: 21px; }
  .lobby-hero .code-box { padding: 6px 38px; }
  .lobby-redesign .lobby-hero .buhne-game { font-size: 24px; }
  .lobby-redesign .lobby-hero .buhne-prop { font-size: 21px; }
  .aud-cluster { max-height: 132px; }
}

/* ── Code coaster in the felt center (table) + slim table header ── */
.lobby-table .felt-center {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 9px; text-align: center; z-index: 1;
}
.lobby-table .felt-code {
  font-size: 22px; letter-spacing: .28em; padding: 6px 18px; border-color: var(--accent);
  box-shadow: 0 0 22px color-mix(in srgb, var(--accent) 30%, transparent), inset 0 0 14px rgba(0,0,0,.6);
}
.felt-code-actions { display: flex; align-items: center; gap: 8px; }
.lobby-redesign .lobby-head-slim { padding: 9px 22px; background: var(--surface-2); }
.lobby-redesign .lobby-head-slim .lobby-title { font-size: 18px; }

/* ── Unified lobby header (3 zones) — game pill on left, code centered,
   seats/copy/chat bubble/settings on right. Replaces lobby-head-slim & lobby-hero. ── */
.lobby-redesign .lobby-uh {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 16%, var(--surface-1)), var(--surface-1));
  border: 1px solid var(--accent);
  border-bottom: 3px solid var(--accent);
  border-radius: 4px;
  text-align: left;
}
.lobby-uh .uh-left   { display: flex; align-items: center; gap: 9px; min-width: 0; }
.lobby-uh .uh-center { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
.lobby-uh .uh-right  { display: flex; align-items: center; gap: 8px; }
.lobby-uh .uh-pill   { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.lobby-uh .uh-ico {
  width: 30px; height: 30px; flex: none; border-radius: 6px;
  display: flex; align-items: center; justify-content: center; font-size: 16px;
  background: color-mix(in srgb, var(--accent) 45%, #1a1208);
  color: #f0e6d2; border: 1px solid var(--accent);
}
.lobby-uh .uh-name {
  /* --heading instead of the raw mode accent as TEXT (documented contrast bug
     the moment a light theme exists — see convention_accent_light_never_as_text). */
  font-family: 'Rye', cursive; font-size: 18px; color: var(--heading);
  line-height: 1.1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 240px;
}
/* Copy icon docks to the right of the centered code box without pushing it off center. */
.lobby-uh .uh-center .uh-copy { position: absolute; left: 100%; top: 50%; transform: translateY(-50%); margin-left: 8px; }
.lobby-uh .uh-icon-btn {
  position: relative; background: transparent; border: 1px solid var(--accent); border-radius: 4px;
  cursor: pointer; color: color-mix(in srgb, var(--accent) 30%, var(--text-main)); width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center; font-size: 15px; line-height: 1; transition: background .15s;
}
.lobby-uh .uh-icon-btn:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); }
.lobby-uh .uh-help { font-weight: 700; }
.lobby-uh .uh-leave {
  color: var(--danger);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  border-color: color-mix(in srgb, var(--danger) 55%, transparent);
}
.lobby-uh .uh-leave:hover { background: color-mix(in srgb, var(--danger) 22%, transparent); }
.lobby-uh .uh-copy.copied { border-color: var(--green-ok); color: var(--green-ok); }
.lobby-uh .uh-bubble.unread { border-color: var(--accent-light); animation: uhBubblePulse 1.4s ease-in-out infinite; }
.lobby-uh .uh-unread-dot {
  position: absolute; top: -4px; right: -4px; width: 11px; height: 11px;
  border-radius: 50%; background: var(--blood-red); border: 2px solid #140d07;
}
@keyframes uhBubblePulse {
  0%, 100% { box-shadow: 0 0 7px color-mix(in srgb, var(--accent-light) 45%, transparent); }
  50%      { box-shadow: 0 0 16px color-mix(in srgb, var(--accent-light) 85%, transparent); }
}
.lobby-uh .uh-gear {
  display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-body); font-size: 13px;
  background: color-mix(in srgb, var(--accent) 10%, transparent); border: 1px solid var(--accent);
  border-radius: 4px; color: color-mix(in srgb, var(--accent) 30%, var(--text-main)); cursor: pointer; padding: 7px 11px; white-space: nowrap; transition: background .15s;
}
.lobby-uh .uh-gear:hover { background: color-mix(in srgb, var(--accent) 22%, transparent); }
/* Icon-only fallback below ~480px: the settings label is the only visible
   header-button text — on very narrow screens it collapses to the gear icon
   (accessible name preserved via aria-label on the button). */
@media (max-width: 480px) {
  .uh-gear-label { display: none; }
  .lobby-uh .uh-gear { width: 32px; height: 32px; padding: 7px; justify-content: center; }
}
/* Leave/end as a red icon in the header (to the right of settings). */
.lobby-uh .uh-leave { border-color: color-mix(in srgb, var(--blood-red) 55%, transparent); color: var(--red-light); }
.lobby-uh .uh-leave:hover { background: rgba(139, 26, 26, .14); border-color: var(--blood-red); }

/* Light: the same faint glyph outline as the poster icons, so the color emojis in the
   header's transparent toolbar buttons (history/chat/link, globe/lock/eye, gear) don't
   wash out on the pale header. The mode icon (.uh-ico) sits on its own dark tile and needs
   none; the symbol glyphs that already carry a color (? and ✕) and the gear's text label
   stay crisp. */
[data-theme="light"] .lobby-uh .uh-icon-btn:not(.uh-help):not(.uh-leave),
[data-theme="light"] .lobby-uh .uh-gear span[aria-hidden="true"],
[data-theme="light"] .lobby-uh .code-box-vis,
[data-theme="light"] .lobby-uh .code-box-eye {
  text-shadow: 0 0 1px rgba(58, 42, 22, .5), 0 1px 1px rgba(58, 42, 22, .32);
}

/* Action row below the player area (replaces chat column + sidebar) */
.lobby-actions { display: flex; flex-direction: column; gap: 10px; }
.lobby-actions-row { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
/* Start button (or wait banner) on the right: same height as history/leave
   (btn-sm-action = 6px/12px). Horizontally a bit wider for prominence. */
.lobby-actions-row .lobby-actions-start { margin-left: auto; margin-top: 0; margin-bottom: 0; width: auto; padding: 6px 18px; font-size: 12px; }
/* History/leave: text-width & left-aligned instead of stretched (btn-sm-action is flex:1 from the old sidebar context). */
.lobby-actions-row .btn-sm-action { flex: 0 0 auto; width: auto; }

/* Lobby header, player box and action row as ONE continuous panel —
   flush-stacked (no gap), 4px rounded top+bottom, touching edges square
   (one clean separator each). The button bar docks at the bottom instead of floating. */
.lobby-redesign .lobby-header { margin-bottom: 0; }
.lobby-redesign .lobby-header-card { border-bottom: none; border-radius: 4px 4px 0 0; border-color: rgba(200,146,42,.28); }
.lobby-redesign .lobby-layout { gap: 0; }
.lobby-redesign .lobby-layout > .card:first-child { border-radius: 0; }
.lobby-redesign .lobby-actions {
  border: 1px solid var(--border-soft); border-top: none; border-radius: 0 0 4px 4px;
  background: var(--surface-2); padding: 12px 16px;
}

/* Chat as a sliding-in sidebar (overlay), triggered via the header bubble */
.chat-drawer-back {
  position: fixed; inset: 0; background: rgba(0,0,0,.45);
  opacity: 0; pointer-events: none; transition: opacity .2s; z-index: 900;
}
.chat-drawer-back.open { opacity: 1; pointer-events: auto; }
/* "Telegram board": light parchment instead of a black gradient. Everything scoped under
   .chat-drawer so the global .chat-* rules (e.g. report snapshot in admin) stay untouched. */
.chat-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: 340px; max-width: 86vw; z-index: 901;
  --tg-ink: #3a2c16; --tg-sub: #574730; --tg-slip: #fbf3e0; --tg-slip-own: #efe7cf;
  --tg-line: #c2a86f; --tg-wood: #6b4a23;
  background: radial-gradient(140% 120% at 50% -10%, #f3e9d2, #e3d4b4 70%, #d8c6a0);
  border-left: 3px solid var(--tg-wood); box-shadow: -12px 0 30px rgba(0,0,0,.5);
  transform: translateX(100%); transition: transform .24s ease;
  display: flex; flex-direction: column;
}
.chat-drawer.open { transform: translateX(0); }

/* Head: dark wooden bar with a parchment title */
.chat-drawer-head { display: flex; align-items: center; gap: 8px; padding: 12px 15px;
  background: linear-gradient(180deg, #3a2913, #2c1e10); border-bottom: 2px solid var(--tg-wood); }
.chat-drawer-head .chat-title { flex: 1; color: var(--gold-light); }
.chat-drawer-close { background: transparent; border: none; color: #d9c39a; cursor: pointer; font-size: 16px; line-height: 1; padding: 4px; min-width: 24px; min-height: 24px; }
.chat-drawer-close:hover { color: #fff; }

.chat-drawer .chat-messages-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.chat-drawer .chat-messages { flex: 1; height: auto; min-height: 0; padding: 12px; gap: 6px;
  scrollbar-color: rgba(107,74,35,.4) transparent; }
.chat-drawer .chat-messages::-webkit-scrollbar-thumb { background: rgba(107,74,35,.4); }

/* Status bar centered, muted */
.chat-drawer .chat-status { justify-content: center; }
.chat-drawer .chat-status-text { color: var(--tg-sub); }
.chat-drawer .chat-status .chat-time { color: var(--tg-sub); opacity: .8; }

/* Nachricht als Telegramm-Zettel */
.chat-drawer .chat-msg { background: var(--tg-slip); border: 1px solid #cdb98c; border-radius: 6px;
  padding: 5px 9px; box-shadow: 0 1px 2px rgba(80,55,20,.12); }
.chat-drawer .chat-msg-own { background: var(--tg-slip-own); border-color: var(--tg-line); }
/* SS-0312-E2-Nebenbefund: #9a865f fiel auf dem hellsten Papier-Stop auf 3,2:1. */
.chat-drawer .chat-msg .chat-time { color: var(--tg-sub); }
.chat-drawer .chat-msg .chat-sender { color: #7a4a16; }
.chat-drawer .chat-msg-own .chat-sender { color: #8a5a10; }
.chat-drawer .chat-msg .chat-text { color: var(--tg-ink); }

/* Eingabe + Senden auf Pergament */
.chat-drawer .chat-input-row { padding: 11px 12px; border-top: 1px solid var(--tg-line); background: #e7d7b6; }
.chat-drawer .chat-inp { background: var(--tg-slip); border: 1px solid var(--tg-line); color: var(--tg-ink); }
.chat-drawer .chat-inp::placeholder { color: #9a865f; }
.chat-drawer .chat-inp:focus { border-color: #8a5a10; box-shadow: 0 0 10px rgba(138,90,16,.18); }
.chat-drawer .chat-send-btn { background: var(--tg-wood); border: 1px solid #4f3415; color: #f3e2bf; border-radius: 5px; }
.chat-drawer .chat-send-btn:hover:not(:disabled) { background: #7d5828; border-color: #4f3415; }

/* Empty state instead of black emptiness */
.chat-drawer .chat-empty { margin: auto; text-align: center; padding: 20px;
  display: flex; flex-direction: column; align-items: center; gap: 8px; }
.chat-drawer .chat-empty-glyph { font-size: 34px; line-height: 1; opacity: .85; }
.chat-drawer .chat-empty-title { font-size: 14px; font-style: italic; color: #5a4321; }
.chat-drawer .chat-empty-hint { font-size: 12px; color: var(--tg-sub); }

/* ── "The Stage" as a theatre: min-height + curtain, spotlight, footlights, stage floor;
   players stand as performers on the floor (≤10) or as a dense ensemble (>10). ── */
.lobby-redesign .lobby-stage-theatre {
  position: relative; min-height: 420px; overflow: hidden; border-radius: 8px; margin-top: 4px;
  display: flex; flex-direction: column; justify-content: flex-end;
  background: radial-gradient(120% 95% at 50% 130%, color-mix(in srgb, var(--accent) 18%, var(--stage-back-a)), var(--stage-back-b) 72%);
  border: 1px solid var(--border-soft);
}
.stage-valance { position: absolute; top: 0; left: 0; right: 0; height: 28px; z-index: 4; background: linear-gradient(180deg, #6e2326, #4a1416); box-shadow: 0 3px 8px rgba(0,0,0,.5); }
.stage-valance::after { content: ""; position: absolute; left: 0; right: 0; bottom: -9px; height: 9px; background: repeating-linear-gradient(90deg, #7a2a2d 0 7px, #5a1c1f 7px 14px); clip-path: polygon(0 0,5% 100%,10% 0,15% 100%,20% 0,25% 100%,30% 0,35% 100%,40% 0,45% 100%,50% 0,55% 100%,60% 0,65% 100%,70% 0,75% 100%,80% 0,85% 100%,90% 0,95% 100%,100% 0); }
.stage-drape { position: absolute; top: 0; bottom: 0; width: 46px; z-index: 3; background: repeating-linear-gradient(90deg, #5a1a1c, #6e2326 9px, #491315 18px); box-shadow: inset -12px 0 18px rgba(0,0,0,.5); }
.stage-drape-l { left: 0; }
.stage-drape-r { right: 0; transform: scaleX(-1); }
.stage-spot { position: absolute; top: -6%; left: 50%; transform: translateX(-50%); width: 58%; height: 118%; z-index: 1; pointer-events: none; background: radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--accent-light) 24%, transparent) 0%, transparent 62%); }
.stage-hint { position: absolute; top: 76px; left: 0; right: 0; text-align: center; z-index: 3; font-family: 'Rye', cursive; font-size: 13px; letter-spacing: .08em; color: var(--text-main); }
.stage-floor { position: absolute; left: 0; right: 0; bottom: 0; height: 76px; z-index: 1; border-top: 3px solid var(--accent); background: repeating-linear-gradient(90deg, var(--stage-floor-a) 0 28px, var(--stage-floor-b) 28px 56px); box-shadow: inset 0 10px 20px var(--shadow-color); }
.stage-footlights { position: absolute; left: 46px; right: 46px; bottom: 72px; display: flex; justify-content: center; gap: 16px; z-index: 5; pointer-events: none; }
.stage-footlights span { width: 8px; height: 8px; border-radius: 50%; background: var(--accent-light); box-shadow: 0 0 8px var(--accent-light), 0 0 18px color-mix(in srgb, var(--accent-light) 60%, transparent); }
.stage-troupe { position: relative; z-index: 6; display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-end; gap: 10px 18px; padding: 0 58px 24px; }
.stage-perf { background: transparent; border: none; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 0; width: 72px; transition: transform .12s; }
.stage-perf:hover { transform: translateY(-3px); }
.stage-perf-av { position: relative; display: inline-flex; border-radius: 50%; }
.stage-perf.is-host .stage-perf-av { box-shadow: 0 0 12px color-mix(in srgb, var(--accent-light) 55%, transparent); }
.stage-perf.is-me .stage-perf-av { outline: 2px solid var(--gold-light); outline-offset: 2px; }
.stage-perf.is-away { opacity: .5; }
.stage-perf-star { position: absolute; top: -7px; right: -5px; font-size: 13px; color: color-mix(in srgb, var(--accent) 30%, var(--text-main)); text-shadow: 0 1px 2px var(--shadow-color); }
.stage-perf-nm { font-size: 12px; color: var(--parchment); white-space: nowrap; max-width: 108px; overflow: hidden; text-overflow: ellipsis; display: inline-flex; align-items: center; justify-content: center; gap: 3px; }
.stage-perf-you { color: var(--text-main); font-weight: 600; }
.stage-perf-free { align-self: flex-end; margin-bottom: 8px; font-size: 12px; color: var(--text-main); opacity: .8; font-style: italic; border: 1px dashed rgba(200,146,42,.25); border-radius: 20px; padding: 6px 12px; }
.stage-aud { position: relative; z-index: 6; margin: 0; padding: 14px 54px 24px; justify-content: center; }

/* ════════════════════════════════════════════════════════════════════════════
   SS — Projektweiter Button-Standard: einheitlicher Eckenradius (Weich, --btn-radius).
   EINE Stelle für ALLE echten Aktions-Buttons. .btn deckt alle .btn-Kompositionen ab
   (btn-gold/-ghost/-amber/-green/-oauth/-sm/-xs/-edit/-sm-action/-start-sidebar/-vote/
   -block/podium-btn/tdm-btn/mq-play-btn/tabu-skip-btn/profile-history-btn …); die übrigen
   Selektoren sind eigenständige Buttons ohne .btn-Basis.
   BEWUSST AUSGENOMMEN (bleiben wie sie sind): runde Icon-/Avatar-Buttons
   (.mute-btn/.header-help-btn/.profile-btn/.help-icon-btn = 50%), Schalter
   (.settings-toggle-btn), rahmenlose Textlinks (.btn-back-history) und Chips/Tags/Pillen.
   ════════════════════════════════════════════════════════════════════════════ */
.btn,
.btn-red, .btn-ghost-red, .abort-btn, .btn-copy, .chat-send-btn, .chat-collapse-btn,
.report-flag-btn, .auth-btn, .edit-btn, .mm-join-btn, .mm-page-btn, .lot-page-btn,
.lobby-uh .uh-icon-btn, .lobby-uh .uh-gear {
  border-radius: var(--btn-radius);
}

/* Mobile: head stacked, code no longer absolutely centered */
@media (max-width: 700px) {
  .lobby-redesign .lobby-uh { flex-direction: column; gap: 9px; }
  .lobby-uh .uh-center { position: static; transform: none; display: inline-flex; align-items: center; gap: 8px; }
  .lobby-uh .uh-center .uh-copy { position: static; transform: none; margin-left: 0; }
  .lobby-uh .uh-right { flex-wrap: wrap; justify-content: center; }
}

/* ── Schub 2: Signatur-Requisit im Filz-Zentrum je Tisch-Spiel ── */
.lobby-table .tprop {
  display: flex; align-items: flex-end; justify-content: center; gap: 6px;
  min-height: 44px; margin-bottom: 2px; position: relative; z-index: 1;
}
.tprop-ship { width: 58px; height: 30px; filter: drop-shadow(0 2px 4px #000); }
.tprop-cross { width: 28px; height: 28px; }
.tprop-card {
  width: 28px; height: 40px; border-radius: 3px;
  background: linear-gradient(160deg, #f4ecd8, #dcc9a0); border: 1px solid #8a6a3a;
  color: #7a1f1f; font-weight: 700; font-size: 12px;
  display: flex; align-items: center; justify-content: center; box-shadow: 0 3px 7px rgba(0,0,0,.5);
}
.tprop-card.l { transform: rotate(-9deg) translateY(-3px); }
.tprop-card.r { transform: rotate(9deg) translateY(-3px); }
.tprop-back {
  width: 28px; height: 40px; border-radius: 3px; border: 1px solid var(--accent-light);
  background: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--accent) 70%, #1a1208) 0 5px,
    color-mix(in srgb, var(--accent) 45%, #1a1208) 5px 10px);
}
.tprop-mask { font-size: 32px; filter: drop-shadow(0 2px 4px #000); line-height: 1; }
/* Schnellschuss: mini shedding cards (own brand colors, not the ivory playing cards) */
.tprop-ssk { width: 28px; height: 40px; border-radius: 4px; display: flex; align-items: center; justify-content: center;
  font-family: 'Rye', cursive; font-size: 13px; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.6);
  border: 1.5px solid rgba(255,255,255,.55); box-shadow: 0 3px 7px rgba(0,0,0,.5); }
.tprop-ssk.c-red { background: #b5392f; }
.tprop-ssk.c-blue { background: #2f74a6; }
.tprop-ssk.wild { background: radial-gradient(120% 120% at 50% 34%, #2c1e10, #160f08 72%);
  border-color: var(--accent-light); color: var(--accent-light); font-size: 15px; }
.tprop-ssk.l { transform: rotate(-9deg) translateY(-3px); }
.tprop-ssk.r { transform: rotate(9deg) translateY(-3px); }
/* Rausschmeisser: pawn trio (classic player colors) + die */
.tprop-pawn { width: 22px; height: 28px; filter: drop-shadow(0 2px 4px #000); }
.tprop-pawn.l { transform: rotate(-8deg) translateY(1px); }
.tprop-pawn.r { transform: rotate(8deg) translateY(1px); }
.tprop-die { font-size: 24px; line-height: 1; color: #f1e7d0; filter: drop-shadow(0 2px 4px #000);
  align-self: center; margin-left: 2px; }
/* Mahjong: ivory tile trio with the real CC0 faces */
.tprop-tile { width: 26px; height: 34px; border-radius: 4px; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(160deg, #efdcb4, #d6bd92); border: 1px solid #b89a63;
  box-shadow: 0 3px 0 0 #8a7047, 0 3px 7px rgba(0,0,0,.5); }
.tprop-tile img { width: 18px; height: 24px; object-fit: contain; }
.tprop-tile.l { transform: rotate(-9deg) translateY(-2px); }
.tprop-tile.r { transform: rotate(9deg) translateY(-2px); }
/* Boomtown: terrain hex trio (forest / pasture camp / wheat) */
.tprop-hex { width: 30px; height: 34px; display: grid; place-items: center; font-size: 15px; line-height: 1;
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  filter: drop-shadow(0 2px 4px #000); }
.tprop-hex.mid { width: 36px; height: 41px; font-size: 18px; margin-top: -4px; }

/* Battleship war council: sonar rings + slow radar sweep over the felt */
.lobby-table .radar {
  position: absolute; inset: 6%; border-radius: 50% / 44%; overflow: hidden;
  pointer-events: none; opacity: .5; z-index: 0;
  background: repeating-radial-gradient(circle at 50% 50%,
    transparent 0 28px, color-mix(in srgb, var(--accent-light) 16%, transparent) 28px 29px);
}
.lobby-table .radar::after {
  content: ""; position: absolute; inset: -20%; transform-origin: 50% 50%;
  background: conic-gradient(from 0deg, color-mix(in srgb, var(--accent-light) 24%, transparent) 0deg, transparent 55deg);
  animation: lobbyRadarSweep 6s linear infinite;
}
@keyframes lobbyRadarSweep { to { transform: rotate(360deg); } }

/* ════════════════════════════════════════════════════════════
   „Runde beendet"-Signal — Overlay über dem eingefrorenen Brett im
   RoundBreak-State (Memory / Durak / Seeschlacht; rollout-fähig).
   position:fixed über dem Spiel, pointer-events:none (blockiert nichts),
   z-index unter Header/Toast/Modal. Komponente: Components/Shared/
   RoundOverCue.razor · Mockup: docs/mockups/round-over-signal.html
   ════════════════════════════════════════════════════════════ */
.round-over {
  position: fixed; inset: 0; z-index: 50;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(0,0,0,.32) 30%, rgba(0,0,0,.62) 100%);
  animation: roDim .45s ease-out both;
}
@keyframes roDim { from { opacity: 0; } to { opacity: 1; } }

/* Wax/Wanted stamp: slams in with a slight rotation */
.round-over-stamp {
  font-family: 'Rye', cursive; text-transform: uppercase; letter-spacing: .04em;
  color: var(--accent-light); text-align: center;
  padding: 14px 34px; border: 4px double var(--accent-light); border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 18%, rgba(13,10,7,.72));
  transform: rotate(-7deg);
  text-shadow: 0 2px 0 rgba(0,0,0,.5), 0 0 22px color-mix(in srgb, var(--accent-light) 45%, transparent);
  box-shadow: 0 0 0 1px rgba(0,0,0,.4), 0 14px 40px rgba(0,0,0,.55);
  animation: roStamp .5s cubic-bezier(.2,1.4,.35,1) both;
}
.round-over-stamp .ro-title { display: block; font-size: clamp(30px, 6vw, 52px); }
.round-over-stamp .ro-sub {
  display: block; font-family: var(--font-body); font-weight: 700; letter-spacing: .18em;
  font-size: 13px; color: var(--gold-light); margin-top: 6px; opacity: .85;
}
@keyframes roStamp {
  0%   { opacity: 0; transform: rotate(-7deg) scale(2.6); }
  60%  { opacity: 1; transform: rotate(-7deg) scale(.92); }
  80%  { transform: rotate(-7deg) scale(1.04); }
  100% { transform: rotate(-7deg) scale(1); }
}

/* Static "result incoming..." hint (intentionally does NOT count visibly) */
.round-over-badge {
  font-family: var(--font-body); font-weight: 600; font-size: 15px; color: var(--parchment);
  background: rgba(0,0,0,.5); border: 1px solid var(--accent-light); border-radius: 999px;
  padding: 7px 18px; opacity: 0; animation: roBadge .4s ease-out .35s forwards;
}
@keyframes roBadge { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ── Situative Flourishes ── */
.ro-flourish { position: absolute; inset: 0; pointer-events: none; }

/* Memory: aufsteigende Funken (Paare setzen sich) */
.ro-sparks span {
  position: absolute; bottom: 38%; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent-light); box-shadow: 0 0 12px var(--accent-light);
  opacity: 0; animation: roRise 1.2s ease-out forwards;
}
@keyframes roRise {
  0%   { opacity: 0; transform: translateY(40px) scale(.4); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-120px) scale(1); }
}

/* Durak: taunt banner for the loser */
.ro-durak {
  display: flex; align-items: flex-end; justify-content: center; padding-bottom: 14%;
  font-family: 'Rye', cursive; color: var(--red-light); font-size: 26px; letter-spacing: .3em;
  text-shadow: 0 2px 10px rgba(0,0,0,.6);
  opacity: 0; animation: roBadge .45s ease-out .6s forwards;
}

/* Schnellschuss: "shot empty" banner */
.ro-schnellschuss {
  display: flex; align-items: flex-end; justify-content: center; padding-bottom: 14%;
  font-family: 'Rye', cursive; color: var(--accent-light); font-size: 24px; letter-spacing: .26em;
  text-shadow: 0 2px 10px rgba(0,0,0,.6);
  opacity: 0; animation: roBadge .45s ease-out .6s forwards;
}

/* Battleship: rising smoke over the hit fleet */
.ro-smoke span {
  position: absolute; bottom: 30%; width: 60px; height: 60px; border-radius: 50%;
  background: radial-gradient(circle, rgba(180,170,160,.5), transparent 70%);
  opacity: 0; animation: roSmoke 1.8s ease-out forwards;
}
@keyframes roSmoke {
  0%   { opacity: 0; transform: translateY(0) scale(.3); }
  30%  { opacity: .7; }
  100% { opacity: 0; transform: translateY(-90px) scale(2.2); }
}

@media (prefers-reduced-motion: reduce) {
  .round-over, .round-over-stamp, .round-over-badge,
  .ro-sparks span, .ro-durak, .ro-schnellschuss, .ro-smoke span { animation-duration: .01ms; }
}

/* ── IconSelect: custom dropdown with a fixed icon column + right-aligned counter ──
   GLOBAL (was previously only in admin.css → unstyled in the lobby/game = white box).
   Moved here so the control appears everywhere in the same Saloon look; uses the global
   :root vars (--border/--old-paper/--amber/--smoke). The open list is positioned via
   ssIconSelect (helpers.js, global). */
.icon-select { position: relative; display: inline-block; min-width: 150px; }
.icon-select.block { display: block; width: 100%; }
.icon-select:focus { outline: none; }
.icon-select:focus-visible .icon-select-btn { border-color: var(--amber); }
.icon-select-btn {
  width: 100%;
  display: grid;
  grid-template-columns: 1.7em 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--old-paper);
  font-size: 12px;
  cursor: pointer;
  text-align: left;
}
.icon-select.open .icon-select-btn,
.icon-select-btn:hover { border-color: var(--amber); }
.icon-select-btn:disabled { opacity: .5; cursor: not-allowed; }
.icon-select-ico  { display: inline-flex; justify-content: center; width: 1.7em; }
.icon-select-lbl  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.icon-select-lbl.ph { color: var(--smoke); }
.icon-select-chev { color: var(--smoke); font-size: 12px; }
.icon-select-backdrop { position: fixed; inset: 0; z-index: 40; }
.icon-select-list {
  position: fixed; z-index: 41; left: 0; top: 0;
  width: max-content; max-width: min(360px, 90vw);
  max-height: 320px; overflow-y: auto;
  background: var(--surface-1-strong);
  border: 1px solid var(--border);
  border-radius: 2px;
  box-shadow: 0 14px 36px rgba(0,0,0,.6);
}
.icon-select-opt {
  display: grid;
  grid-template-columns: 1.7em 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  cursor: pointer;
  color: var(--old-paper);
  border-bottom: 1px solid rgba(200,146,42,.08);
  font-size: 12px;
}
.icon-select-opt:last-child { border-bottom: none; }
.icon-select-opt:hover,
.icon-select-opt.hl  { background: rgba(200,146,42,.12); }
.icon-select-opt.sel { background: rgba(200,146,42,.20); }
.icon-select-opt.all { font-weight: 600; }
.icon-select-name  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.icon-select-count { color: var(--smoke); font-size: 12px; font-variant-numeric: tabular-nums; }

/* ═══════════════════════════════════════════════════════════════════════════
   Schattenspiel · Variante „Undercover"  (verdeckte Rollen + Eliminierungs-Loop)
   Akzent = mode-schattenspiel (Pflaume). Geist-Palette: fahles Blaugrau.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Geist-Figur (Reveal-Intro), analog zur Crewmate-Figur ── */
.ghost-figure { position: relative; width: 110px; height: 170px; margin: 0 auto; opacity: .94; }
.g-hat-crown { position: absolute; top: -14px; left: 50%; transform: translateX(-50%); width: 38px; height: 26px;
  background: linear-gradient(180deg,#54636e,#39454e); border: 1px solid #28323a; border-radius: 6px 6px 3px 3px; }
.g-hat-brim { position: absolute; top: 11px; left: 50%; transform: translateX(-50%); width: 66px; height: 10px;
  background: linear-gradient(180deg,#46555f,#2e3940); border: 1px solid #28323a; border-radius: 3px; }
.g-head { position: absolute; top: 18px; left: 50%; transform: translateX(-50%); width: 38px; height: 38px; border-radius: 50%;
  background: radial-gradient(circle at 50% 38%, #d6e2ec, #8ea3b3); border: 1px solid #5b6b78; }
.g-eyes { position: absolute; top: 32px; left: 50%; transform: translateX(-50%); color: #28333c; letter-spacing: 6px; font-size: 12px; z-index: 2; }
.g-body { position: absolute; bottom: 28px; left: 50%; transform: translateX(-50%); width: 54px; height: 88px;
  background: linear-gradient(180deg, rgba(174,191,204,.85), rgba(111,132,148,.5)); border: 1px solid #46555f; border-radius: 22px 22px 16px 16px; }
.g-glow { position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); width: 72px; height: 16px; border-radius: 50%;
  background: radial-gradient(ellipse, rgba(174,191,204,.4) 0%, transparent 70%); }
.fig-ghost-pulse { animation: figGhostPulse 3s ease-in-out infinite; }
@keyframes figGhostPulse { 0%,100% { filter: drop-shadow(0 0 6px rgba(174,191,204,.3)); } 50% { filter: drop-shadow(0 0 16px rgba(174,191,204,.55)); } }
.uc-title-ghost { color: #aebfcc !important; text-shadow: 0 0 14px rgba(174,191,204,.5); }

/* Reveal-Intro Wort-/Kategorie-Karte */
.uc-word-card, .uc-ghost-card { text-align: center; padding: 12px 18px; }
.uc-word-card .secret-word-text { font-size: 28px; }
.uc-ghost-card { border-color: rgba(174,191,204,.4) !important; }
.uc-ghost-card .impostor-category-value { color: #aebfcc; }

/* ── Schattenspiel left column framed as ONE panel (SS-0328, Option B) ──────────
   Both the classic Schattenspiel (Game.razor RenderPlaying) and the Undercover
   variant (UndercoverPlaying) put their left column in `.ss-panel`. Instead of
   stacked floating cards it sits in a single Saloon-gold frame; the inner cards
   become sections (hero wash for the secret word, subtle wells for the turn list
   + clue input). Only inside the card-board shell — outside it the classic stacked
   look is unaffected. */
.card-board .ss-panel {
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid var(--board-border);
  border-radius: 6px;
  box-shadow: var(--board-shadow);
  padding: 16px 18px;
  display: flex; flex-direction: column; gap: 12px;
}
/* Flex gap owns the spacing — drop the cards' own margins to avoid double gaps. */
.card-board .ss-panel > * { margin: 0; }
/* Secret word = hero section: accent wash + accent-tinted border (civilian). */
.card-board .ss-panel .secret-word-card {
  background:
    radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--accent) 24%, transparent) 0%, transparent 62%),
    var(--well);
  border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--board-border));
  border-radius: 8px;
}
/* Impostor keeps red; overrides the accent wash with a red wash + red border. */
.card-board .ss-panel .secret-word-card.card-red {
  background:
    radial-gradient(ellipse at 50% 0%, rgba(139,26,26,.28) 0%, transparent 62%),
    var(--well);
  border-color: rgba(139,26,26,.5);
}
/* Ghost keeps its cool border (the !important rule already survives); add a well. */
.card-board .ss-panel .secret-word-card.uc-ghost-word { background: var(--well); }
/* Turn list + clue input = subtle well sections. */
.card-board .ss-panel .card-turn-list,
.card-board .ss-panel .card-clue-input {
  background: var(--well);
  border: 1px solid var(--board-border);
  border-radius: 8px;
}
/* Impostor clue input keeps its red section border. */
.card-board .ss-panel .card-clue-input.card-red { border-color: rgba(139,26,26,.5); }

/* Spectator god-view is a single card → frame it like the other single game cards. */
.card-board .uc-spectator .card-turn-list {
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid var(--board-border);
  border-radius: 6px;
  box-shadow: var(--board-shadow);
}

/* Impostor mission + category cards (classic Schattenspiel, above the game layout)
   are also stripped in the card-board shell → floating. Frame them as red-tinted
   panels (they carry the .card-red role signal) so they no longer hang in the air. */
.card-board .impostor-mission,
.card-board .impostor-category {
  background: linear-gradient(135deg, var(--board-grad-a), var(--board-grad-b));
  border: 1px solid rgba(139, 26, 26, .5);
  border-radius: 8px;
  box-shadow: var(--board-shadow);
  margin-left: auto; margin-right: auto;
}

/* ── Game view: ghost word card (category) ── */
.uc-ghost-word { border-color: rgba(174,191,204,.45) !important; }
.uc-ghost-text { color: #aebfcc !important; font-size: 22px !important; }

/* Impostor knows their role -- consistently highlighted in red (reveal + game) */
.uc-imp-label { color: var(--red-light); font-family: 'Rye', cursive; font-size: 12px; letter-spacing: .08em; }
.uc-imp-hint { font-size: 12px; color: var(--smoke); margin-top: 4px; }
.uc-word-card-imp .secret-word-text { color: #e6736b; }

/* Diskussions-Banner */
.disc-banner { background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); border-radius: 8px;
  padding: 12px 16px; text-align: center; color: var(--accent-ink); font-size: 14px; margin-top: 12px; }

/* Rollen-Tags (Zuschauer-God-View / Ergebnis) */
.uc-role-tag { font-size: 12px; letter-spacing: .04em; text-transform: uppercase; font-family: 'Rye', cursive; white-space: nowrap; }
.uc-role-tag.civ   { color: var(--heading); }
.uc-role-tag.imp   { color: var(--red-light); }
.uc-role-tag.ghost { color: #aebfcc; }
.turn-row .uc-role-tag, .uc-role-row .uc-role-tag { margin-left: auto; }

/* Zuschauer-Banner + God-View */
.uc-spectator { width: 100%; max-width: 560px; margin: 0 auto; }
.spectator-banner { display: flex; align-items: center; gap: 10px; justify-content: center; max-width: 560px; margin: 0 auto 14px;
  background: color-mix(in srgb, var(--well) 67%, transparent); border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; color: var(--old-paper); font-size: 13px; }
.spectator-banner .eye { font-size: 16px; }
.uc-godview { max-width: 460px; margin: 0 auto; display: flex; flex-direction: column; gap: 4px; }
.uc-gv-row { display: flex; align-items: center; gap: 10px; padding: 7px 12px; background: color-mix(in srgb, var(--well) 62%, transparent);
  border: 1px solid var(--border); border-radius: 8px; }
.uc-gv-row.out { opacity: .5; }
.uc-gv-row .nm { color: var(--parchment); flex: 1; }

/* ── Abstimmung (anonym) ── */
.uc-vote-screen { width: 100%; max-width: 720px; margin: 0 auto; text-align: center; }
.uc-vote-head { margin-bottom: 16px; }
.uc-vote-head .r-title { font-family: 'Rye', cursive; font-size: 26px; color: var(--accent-ink); }
.uc-vote-timer { font-family: 'Special Elite', cursive; color: var(--heading); font-size: 15px; margin-top: 4px; }
.uc-vote-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; max-width: 540px; margin: 0 auto; }
.uc-vote-opt { display: flex; align-items: center; gap: 10px; padding: 10px 14px; cursor: pointer; text-align: left;
  background: color-mix(in srgb, var(--well) 67%, transparent); border: 1px solid var(--border); border-radius: 10px; color: var(--parchment); font-size: 15px; }
.uc-vote-opt:hover:not(:disabled) { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.uc-vote-opt.sel { border-color: color-mix(in srgb, var(--accent) 65%, transparent); background: color-mix(in srgb, var(--accent) 14%, transparent); }
.uc-vote-opt:disabled { cursor: default; }
.uc-vote-opt .nm { flex: 1; }
.uc-vote-opt .tally { color: var(--accent-ink); font-size: 12px; }
.uc-vote-progress { margin-top: 14px; color: var(--smoke); font-size: 13px; }

/* Geist-Tipp-Eingabe */
.uc-ghost-guess { max-width: 460px; margin: 16px auto 0; background: color-mix(in srgb, var(--well) 58%, transparent);
  border: 1px solid rgba(174,191,204,.4); border-radius: 12px; padding: 14px; text-align: left; }
.uc-ghost-guess-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.uc-ghost-guess-head .hint { font-size: 12px; color: var(--smoke); }
.role-pill { background: color-mix(in srgb, var(--accent) 25%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 999px; padding: 4px 12px; font-size: 12px; color: var(--accent-ink); font-weight: 600; }
.role-pill.ghost { background: rgba(111,132,148,.22); border-color: rgba(174,191,204,.45); color: #aebfcc; }
.uc-ghost-btn { background: linear-gradient(135deg,#aebfcc,#6f8494) !important; color: #10181f !important; }
.uc-ghost-saved { margin-top: 8px; font-size: 12px; color: #aebfcc; font-style: italic; }

/* ── Stimmen-Aufdeckung (👉) ── */
.uc-reveal { width: 100%; max-width: 560px; margin: 0 auto; text-align: center; }
.uc-reveal .r-title { font-family: 'Rye', cursive; font-size: 24px; color: var(--accent-ink); }
.tally-reveal { max-width: 480px; margin: 12px auto 0; display: flex; flex-direction: column; gap: 8px; }
.tally-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; background: color-mix(in srgb, var(--well) 67%, transparent);
  border: 1px solid var(--border); border-radius: 8px; }
.tally-row.top { border-color: color-mix(in srgb, var(--accent) 60%, transparent); background: color-mix(in srgb, var(--accent) 13%, transparent); }
.tally-row .nm { color: var(--parchment); font-weight: 600; min-width: 84px; text-align: left; }
.tally-row .tokens { display: flex; gap: 5px; align-items: center; justify-content: flex-start; min-height: 19px; }
.vtoken { display: inline-grid; place-items: center; font-size: 18px; line-height: 1; transform: scale(0); opacity: 0;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.55)); animation: ucPop .4s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes ucPop { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.uc-reveal-caption { margin-top: 12px; color: var(--parchment); font-size: 14px; }
.uc-reveal-tie { margin-top: 16px; color: var(--heading); font-size: 16px; font-family: 'Rye', cursive; opacity: 0; animation: ucFadeIn .5s ease both; }
@keyframes ucFadeIn { to { opacity: 1; } }

/* ── Elimination cinema (swing doors + avatar flies out) ── */
.uc-kino { position: relative; max-width: 520px; height: 248px; margin: 14px auto 0; border-radius: 12px; overflow: hidden;
  background: radial-gradient(ellipse at 40% 52%, rgba(90,47,74,.35), transparent 62%), linear-gradient(180deg,#160f08,#0a0603);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); box-shadow: inset 0 0 60px rgba(0,0,0,.6); }
.uc-kino .floor { position: absolute; left: 0; right: 0; bottom: 0; height: 46px;
  background: linear-gradient(180deg, rgba(74,47,20,.5), rgba(0,0,0,.45)); border-top: 1px solid rgba(120,80,35,.4); }
.uc-kino .doorway { position: absolute; left: 42px; top: 40px; bottom: 50px; width: 120px; perspective: 620px; }
.uc-kino .door { position: absolute; top: 0; bottom: 0; width: 52px; border: 1px solid #2a1a0a; border-radius: 3px;
  background: repeating-linear-gradient(90deg,#5a3a18 0 10px,#4a2f14 10px 20px); box-shadow: inset 0 0 14px rgba(0,0,0,.55); }
.uc-kino .door .slat { position: absolute; left: 6px; right: 6px; height: 7px; background: rgba(0,0,0,.28); border-radius: 2px; }
.uc-kino .door.l { left: 0; transform-origin: left center; transform: rotateY(50deg); }
.uc-kino .door.r { right: 0; transform-origin: right center; transform: rotateY(-50deg); }
.uc-kino .flyfig { position: absolute; left: 150px; top: 96px; width: 72px; height: 72px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent-light), var(--accent)); border: 2px solid rgba(255,255,255,.18);
  display: grid; place-items: center; font-family: 'Rye', cursive; font-size: 30px; color: #1a1208; font-weight: 700;
  box-shadow: 0 8px 24px rgba(0,0,0,.6); opacity: 0; animation: ucKickout 2.6s cubic-bezier(.5,0,.7,.4) var(--kino-delay,3s) both; }
@keyframes ucKickout {
  0% { left: 150px; top: 96px; transform: rotate(0) scale(.85); opacity: .15; }
  30% { opacity: 1; }
  100% { left: 392px; top: 64px; transform: rotate(230deg) scale(1.05); opacity: 1; } }
.uc-kino .lines { position: absolute; top: 104px; left: 158px; display: flex; flex-direction: column; gap: 8px; opacity: 0;
  animation: ucFadeIn .3s ease var(--kino-delay,3s) both; }
.uc-kino .lines i { display: block; height: 3px; border-radius: 2px; background: var(--accent-light); }
.uc-kino .lines i:nth-child(1) { width: 38px; } .uc-kino .lines i:nth-child(2) { width: 62px; } .uc-kino .lines i:nth-child(3) { width: 28px; }
.uc-kino .stamp { position: absolute; right: 24px; top: 28px; font-family: 'Rye', cursive; color: var(--red-light); font-size: 22px;
  border: 3px solid var(--red-light); border-radius: 8px; padding: 5px 13px; transform: rotate(-11deg) scale(.4); opacity: 0;
  box-shadow: 0 0 18px rgba(192,53,42,.3); animation: ucStamp .5s ease-out calc(var(--kino-delay,3s) + .3s) forwards; }
@keyframes ucStamp { 0% { transform: rotate(-11deg) scale(.4); opacity: 0; } 60% { transform: rotate(-11deg) scale(1.15); opacity: 1; } 100% { transform: rotate(-11deg) scale(1); opacity: .95; } }

/* ── Ergebnis ── */
.uc-result-title { font-family: 'Rye', cursive; font-size: 28px; }
.uc-result-title.civ   { color: #6ed496; text-shadow: 0 0 22px rgba(45,122,74,.4); }
.uc-result-title.inf   { color: var(--red-light); text-shadow: 0 0 22px rgba(139,26,26,.4); }
.uc-result-title.ghost { color: #aebfcc; text-shadow: 0 0 22px rgba(174,191,204,.45); }
.uc-words-reveal { display: flex; justify-content: center; gap: 30px; margin: 10px 0 4px; }
.uc-words-reveal .wr { text-align: center; }
.uc-words-reveal .wr .l { font-size: 12px; color: var(--smoke); text-transform: uppercase; letter-spacing: .1em; }
.uc-words-reveal .wr .v { font-family: 'Rye', cursive; font-size: 22px; color: var(--accent-ink); }
.uc-words-reveal .wr .v.imp { color: var(--red-light); }
.uc-ghost-solo { margin: 6px 0 2px; color: #aebfcc; font-size: 14px; }
.uc-roles-card { max-width: 440px; }
.uc-role-row { display: flex; align-items: center; gap: 10px; }
.uc-role-row.out { opacity: .55; }

/* ═══════════════════════════════════════════════════════════════════════════
   Schnellschuss (Stammtisch shedding game). Reuses the shared card-table shell
   (.durak-board / .durak-topbar / .durak-seats); only the cards, center piles,
   hand fan, auto-call banner and color overlay are mode-specific. Card colors
   are intrinsic (red/yellow/green/blue), independent of the cactus-teal accent.
   Mockup: docs/mockups/ss0279-schnellschuss-tisch.html
   ═══════════════════════════════════════════════════════════════════════════ */
.ssk-color-dot { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: middle; border: 1px solid rgba(0,0,0,.4); }
.ssk-timer { font-variant-numeric: tabular-nums; }
.ssk-timer.danger { color: #e0594d; border-color: #e0594d; font-weight: 700; }

/* Base card size for Schnellschuss — a touch larger than Durak's 60x84 (sparser table, no pips). */
.mode-schnellschuss .durak-board { --card-w: 72px; --card-h: 100px; }
/* Topbar badges sit centered above the felt (no trailing widget to balance the row otherwise). */
.mode-schnellschuss .durak-topbar { justify-content: center; }
/* "Deine Hand · N Karten" header centered over the hand fan (mode-scoped so Durak/Poker/Skat
   keep their left-aligned shared header); .grow spacer neutralized so it doesn't push left. */
.mode-schnellschuss .durak-hand-head { justify-content: center; }
.mode-schnellschuss .durak-hand-head .grow { display: none; }

/* Direction chip glyph (↻/↺) — bumped well past the chip's 12px base text so the two
   arrowheads are actually distinguishable at a glance. */
.ssk-dir-glyph { font-size: 19px; font-weight: 700; line-height: 1; }

/* Felt table — green oval play surface with opponents around the upper arc, piles in the middle.
   Mockup: docs/mockups/ss0279-schnellschuss-tisch.html */
.ssk-felt-wrap { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.ssk-felt { position: relative; flex: 1 1 auto; min-height: clamp(330px, 46vh, 620px); border-radius: 50% / 46%;
    background: radial-gradient(ellipse at 50% 40%, #1f5138 0%, #173c2a 60%, #0f2a1d 100%);
    border: 11px solid var(--felt-rim); box-shadow: inset 0 0 70px rgba(0,0,0,.6), 0 10px 30px rgba(0,0,0,.5); }
/* Light: daylight felt like the lobby (tokens), teal keeps only the rim accent. */
[data-theme="light"] .ssk-felt {
    background: radial-gradient(ellipse at 50% 40%, var(--felt-base-a) 0%, var(--felt-base-b) 60%, var(--felt-base-c) 100%);
    box-shadow: var(--felt-shadow); }
.ssk-felt-rim { position: absolute; inset: 5px; border-radius: inherit; border: 2px solid rgba(79,196,214,.3); pointer-events: none; }
.ssk-dir-wm { position: absolute; left: 50%; top: 46%; transform: translate(-50%,-50%);
    font-size: clamp(120px, 22vh, 240px); font-weight: 700; line-height: 1; color: #fff; opacity: .07; pointer-events: none; }

.ssk-seat { position: absolute; transform: translate(-50%,-50%); width: 120px; display: flex; flex-direction: column;
    align-items: center; gap: 4px; font-size: 12px; cursor: pointer; z-index: 2; }
.ssk-seat-head { display: flex; align-items: center; gap: 6px; padding: 3px 10px 3px 3px; border-radius: 999px;
    border: 1px solid transparent; transition: box-shadow .15s, background .15s; }
.ssk-seat.active .ssk-seat-head { background: color-mix(in srgb, var(--accent) 24%, transparent);
    box-shadow: 0 0 0 1px var(--accent-light), 0 0 16px rgba(79,196,214,.5); }
/* Up-next hint — a plain red ring, distinct from the filled teal glow of the active seat.
   #ff6b57 (not the usual #e0594d danger red) — picked for >=3:1 against the felt itself
   (WCAG 1.4.11 non-text contrast); the brand red only clears that on chip/paper backgrounds. */
.ssk-seat.next .ssk-seat-head { border-color: #ff6b57; box-shadow: 0 0 0 1px #ff6b57, 0 0 10px rgba(255,107,87,.45); }
.ssk-seat-nm { font-size: 15px; font-weight: 700; color: var(--parchment); max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ssk-seat-mini { display: flex; align-items: center; gap: 5px; }
.ssk-seat-cnt { font-size: 12px; color: var(--old-paper); font-variant-numeric: tabular-nums; }

.ssk-center { position: absolute; left: 50%; top: 56%; transform: translate(-50%,-50%);
    display: flex; align-items: center; gap: clamp(20px, 4vw, 42px); z-index: 1; }

/* Spectator note when the action hits someone else — a compact pill floating in the free
   band above the piles (the felt watermark sits behind it). Capped at 88% of the felt / 340px
   and wraps on narrow screens so it fits every resolution. Fixed dark pill background carries
   the text contrast in BOTH themes (felt stays dark either way). */
/* Anchored by its BOTTOM edge just above the pile band (top:43% + translateY(-100%)) so a
   multi-line note on narrow screens grows UP into the empty watermark band and never covers
   the draw/discard piles. width:max-content lets it use the full available width (capped at
   88%/340px) before wrapping — otherwise inline-flex shrinks to min-content and over-wraps. */
.ssk-note { position: absolute; left: 50%; top: 35%; transform: translate(-50%,-100%);
    display: inline-flex; align-items: center; gap: 7px; text-align: center;
    width: max-content; max-width: min(88%, 340px);
    font-size: clamp(12px, 3vw, 14px); font-weight: 700; line-height: 1.25;
    padding: 6px clamp(11px, 3vw, 16px); border-radius: 16px;
    background: rgba(12,18,20,.92); border: 1px solid; box-shadow: 0 4px 18px rgba(0,0,0,.5);
    animation: ssk-note-in .3s ease; z-index: 3; pointer-events: none; }
@keyframes ssk-note-in { from { opacity: 0; transform: translate(-50%, calc(-100% + 8px)); }
    to { opacity: 1; transform: translate(-50%, -100%); } }
.ssk-note-ic { font-size: 17px; flex: 0 0 auto; }
.ssk-note.draw2 { color: #ff8a7d; border-color: #ff6b57; }
.ssk-note.draw4 { color: #f0c95f; border-color: #e8b84b; }
.ssk-note.skip  { color: #a9bccb; border-color: #8fa4b3; }
@media (prefers-reduced-motion: reduce) { .ssk-note { animation: none; } }

/* Card — size driven by --card-w/--card-h (inherited from .durak-board; bumped on maximize,
   exactly like .durak-card). Inner elements are proportional so they scale with the card. */
.ssk-card { position: relative; width: var(--card-w, 60px); height: var(--card-h, 84px);
    border-radius: calc(var(--card-h, 84px) * .1); border: 2px solid rgba(0,0,0,.4);
    box-shadow: 0 3px 8px rgba(0,0,0,.45); color: #fff; flex: 0 0 auto; display: inline-block; }
.ssk-card .ssk-oval { position: absolute; left: 50%; top: 50%; width: 66%; height: 76%;
    transform: translate(-50%,-50%) rotate(26deg); background: rgba(255,255,255,.92); border-radius: 50%; }
.ssk-card .ssk-big { position: absolute; inset: 0; display: grid; place-items: center; z-index: 1;
    font-size: calc(var(--card-h, 84px) * .34); font-family: 'Rye', cursive; }
.ssk-card .ssk-corner { position: absolute; font-size: calc(var(--card-h, 84px) * .155); font-weight: 700; color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.7); z-index: 2; }
.ssk-card .ssk-corner.tl { top: 5%; left: 8%; }
.ssk-card .ssk-corner.br { bottom: 5%; right: 8%; transform: rotate(180deg); }
/* Mini size for the game-history hands (matches DurakCard mini). */
.ssk-card.ssk-mini { --card-w: 30px; --card-h: 42px; border-width: 1.5px; }
.ssk-card.c-red    { background: #b5392f; } .ssk-card.c-red    .ssk-big { color: #b5392f; }
.ssk-card.c-yellow { background: #d9a527; } .ssk-card.c-yellow .ssk-big { color: #9c6e10; }
.ssk-card.c-green  { background: #3f8a52; } .ssk-card.c-green  .ssk-big { color: #3f8a52; }
.ssk-card.c-blue   { background: #2f74a6; } .ssk-card.c-blue   .ssk-big { color: #2f74a6; }
.ssk-card.ssk-wild { background: linear-gradient(135deg,#2a2320,#150f0c); }
.ssk-card.ssk-wild .ssk-oval { background: conic-gradient(#b5392f 0 90deg,#d9a527 90deg 180deg,#3f8a52 180deg 270deg,#2f74a6 270deg 360deg); }
.ssk-card.ssk-wild .ssk-big { color: #fff; text-shadow: 0 2px 4px rgba(0,0,0,.7); }

/* Face-down back (opponents + draw pile) */
.ssk-back { display: inline-block; width: 13px; height: 18px; border-radius: 2px; margin-left: -6px;
    background: linear-gradient(135deg,#16414a,#0e2a30); border: 1px solid #0a1f24; }
.ssk-back:first-child { margin-left: 0; }
.ssk-back.lg { width: var(--card-w, 60px); height: var(--card-h, 84px); border-radius: calc(var(--card-h, 84px) * .1); margin: 0; position: relative; }
.ssk-back.lg::after { content: '✦'; position: absolute; inset: 0; display: grid; place-items: center;
    color: var(--accent-light); font-size: calc(var(--card-h, 84px) * .3); opacity: .85; }
.ssk-call-badge { font-size: 13px; }

/* Center: draw pile + discard top (positioned inside .ssk-center on the felt) */
.ssk-draw { position: relative; background: none; border: none; padding: 0; cursor: default; }
.ssk-draw.live { cursor: pointer; }
.ssk-draw.live:hover .ssk-back.lg { box-shadow: 0 0 0 2px var(--accent-light); }
.ssk-draw[disabled] { opacity: .85; }
.ssk-pile-cap { position: absolute; left: 50%; bottom: -20px; transform: translateX(-50%); font-size: 12px;
    color: var(--smoke); white-space: nowrap; }
.ssk-discard { transform: rotate(-5deg); }

/* Drawn-card decision bar (play the highlighted drawn card, or carry on) */
.ssk-decide { display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap;
    margin: 8px auto 2px; width: max-content; max-width: 92%; padding: 8px 16px; border-radius: 999px;
    font-size: 13px; color: var(--parchment); background: color-mix(in srgb, var(--well-strong) 65%, transparent); border: 1px solid var(--accent-ink); }
.ssk-decide-go { font-family: 'Rye', cursive; font-size: 14px; border: none; border-radius: 8px; padding: 7px 16px;
    cursor: pointer; color: #0b1116; background: linear-gradient(135deg,var(--accent),var(--accent-light)); }

/* Auto-Schnellschuss banner */
.ssk-banner { display: block; width: max-content; max-width: 90%; margin: 8px auto 2px; font-size: 13px;
    color: #0b1116; background: linear-gradient(135deg,var(--accent),var(--accent-light));
    border-radius: 999px; padding: 5px 16px; font-weight: 700; box-shadow: 0 0 14px rgba(79,196,214,.5); }

/* Own hand fan */
.ssk-hand { display: flex; justify-content: center; align-items: flex-end; flex-wrap: wrap;
    gap: 0; padding: 16px 8px 6px; min-height: 100px; }
.ssk-hand .ssk-card { margin-left: -12px; transition: transform .12s ease, box-shadow .12s ease; }
.ssk-hand .ssk-card:first-child { margin-left: 0; }
.ssk-hand .ssk-card.playable { cursor: pointer; box-shadow: 0 0 0 2px var(--accent-light), 0 8px 16px rgba(0,0,0,.55);
    transform: translateY(-16px); }
.ssk-hand .ssk-card.dim { opacity: .5; filter: saturate(.65); }

/* Result spotlight stamp */
.ssk-win-stamp { font-size: 64px; line-height: 1; filter: drop-shadow(0 0 14px rgba(79,196,214,.6)); }

/* Color picker overlay (after playing a wild) */
.ssk-ovl { position: absolute; inset: 0; background: rgba(6,10,11,.82); display: flex; align-items: center;
    justify-content: center; z-index: 1000; padding: 18px; }
.ssk-dlg { background: linear-gradient(135deg,#13191b,#0a0d0e); border: 1px solid var(--accent-light);
    border-radius: 10px; max-width: 440px; width: 100%; overflow: hidden; box-shadow: 0 18px 60px rgba(0,0,0,.6); }
.ssk-dlg-hd { padding: 12px 16px; background: color-mix(in srgb, var(--accent) 22%, transparent);
    border-bottom: 1px solid var(--border); font-family: 'Rye', cursive; font-size: 17px; color: var(--accent-light); }
.ssk-colorpick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 16px; }
.ssk-cbtn { font-family: 'Rye', cursive; font-size: 16px; color: #fff; border: 2px solid rgba(0,0,0,.4);
    border-radius: 8px; padding: 14px; cursor: pointer; text-shadow: 0 1px 3px rgba(0,0,0,.6); }
.ssk-cbtn.c-red { background: #b5392f; } .ssk-cbtn.c-yellow { background: #d9a527; }
.ssk-cbtn.c-green { background: #3f8a52; } .ssk-cbtn.c-blue { background: #2f74a6; }

/* Action cinema — short celebrated overlay when a player gets +2/+4 or is skipped.
   Mockup: docs/mockups/ss0279-schnellschuss-aktionskino.html */
.ssk-cine { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    z-index: 1000; pointer-events: none; }
.ssk-cine::before { content: ''; position: absolute; inset: 0;
    background: radial-gradient(ellipse 60% 50% at 50% 50%, rgba(0,0,0,.55), rgba(0,0,0,.78)); animation: ssk-cine-fade .25s ease; }
@keyframes ssk-cine-fade { from { opacity: 0; } to { opacity: 1; } }
.ssk-cine-burst { position: relative; display: flex; flex-direction: column; align-items: center; gap: 16px;
    animation: ssk-cine-pop .4s cubic-bezier(.2,1.5,.4,1); }
@keyframes ssk-cine-pop { 0% { transform: scale(.5); opacity: 0; } 60% { transform: scale(1.06); } 100% { transform: scale(1); opacity: 1; } }
.ssk-cine-stamp { font-family: 'Rye', cursive; font-size: 46px; line-height: 1; padding: 6px 24px; border-radius: 13px;
    border: 3px solid; text-transform: uppercase; text-shadow: 0 3px 10px rgba(0,0,0,.7); }
.ssk-cine-ic { font-size: 40px; margin-right: 8px; vertical-align: -3px; }
/* Pin the cinema card to the base size (ignore the maximize bump) so the overlay stays
   consistent. scale(2) is visual only — reserve the grown footprint via margin so the card
   doesn't overlap the stamp above / the subtitle below (60x84 → 120x168). */
.ssk-cine-card { --card-w: 60px !important; --card-h: 84px !important;
    margin: 46px 30px; animation: ssk-cine-flip .5s cubic-bezier(.2,1.3,.4,1) both; }
@keyframes ssk-cine-flip { 0% { transform: rotateY(90deg) scale(1.2); opacity: 0; } 60% { transform: rotateY(-10deg) scale(2.1); } 100% { transform: rotateY(0) scale(2); opacity: 1; } }
.ssk-cine-sub { font-size: 18px; font-weight: 700; color: var(--raw-parchment); text-shadow: 0 2px 6px rgba(0,0,0,.8); text-align: center; }
.ssk-v-draw2 .ssk-cine-stamp { color: #e0594d; border-color: #e0594d; background: rgba(40,12,10,.7); box-shadow: 0 0 34px rgba(224,89,77,.5); }
.ssk-v-draw4 .ssk-cine-stamp { color: #e8b84b; border-color: #e8b84b; background: rgba(40,28,6,.7); box-shadow: 0 0 40px rgba(232,184,75,.55); }
.ssk-v-skip  .ssk-cine-stamp { color: #8fa4b3; border-color: #8fa4b3; background: rgba(16,22,28,.78); box-shadow: 0 0 30px rgba(143,164,179,.45); }
.durak-seat.ssk-cine-target { animation: ssk-cine-shake .5s ease; }
.durak-seat.ssk-cine-target .who { filter: drop-shadow(0 0 8px rgba(224,89,77,.7)); }
@keyframes ssk-cine-shake { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-4px); } 40% { transform: translateX(4px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(3px); } }

/* Forced-draw overlay (replaces the bottom-right draw button). Mockup: ss0279-schnellschuss-ziehoverlay.html */
.ssk-draw-dlg { position: relative; background: linear-gradient(135deg,#13191b,#0a0d0e); border: 1px solid var(--accent-light);
    border-radius: 14px; max-width: 380px; width: 100%; text-align: center; padding: 24px 22px 22px;
    box-shadow: 0 18px 60px rgba(0,0,0,.6); animation: ssk-draw-pop .35s cubic-bezier(.2,1.4,.4,1); }
@keyframes ssk-draw-pop { 0% { transform: scale(.8); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
.ssk-draw-dlg.danger { border-color: #e0594d; }
.ssk-draw-ic { font-size: 46px; line-height: 1; margin-bottom: 6px; }
.ssk-draw-dlg h2 { font-family: 'Rye', cursive; font-size: 24px; margin: 0 0 6px; color: var(--accent-light); }
.ssk-draw-dlg.danger h2 { color: #e0594d; }
.ssk-draw-dlg p { margin: 0 0 18px; font-size: 14px; color: var(--old-paper); }
.ssk-draw-go { font-family: 'Rye', cursive; letter-spacing: .04em; font-size: 18px; border: none; border-radius: 10px;
    padding: 13px 26px; cursor: pointer; color: #0b1116; background: linear-gradient(135deg,var(--accent),var(--accent-light));
    box-shadow: 0 6px 18px rgba(79,196,214,.4); animation: ssk-draw-bob 1.4s ease-in-out infinite; }
.ssk-draw-dlg.danger .ssk-draw-go { background: linear-gradient(135deg,#b5392f,#e0594d); color: #fff; box-shadow: 0 6px 18px rgba(224,89,77,.4); }
@keyframes ssk-draw-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }

/* ════════════════════════════════════════════════════════════
   BOARD GAMES — shared chrome for Rausschmeisser (.rsm-*),
   Mahjong Solitaire (.mjg-*) and Boomtown (.bt-*): turn timer +
   player pill strip. Only the glow color differs per mode.
════════════════════════════════════════════════════════════ */

.rsm-timer, .mjg-timer, .bt-timer { font-variant-numeric: tabular-nums; }
.rsm-timer.danger, .mjg-timer.danger, .bt-timer.danger { color: #e0594d; border-color: #e0594d; font-weight: 700; }

.rsm-players, .mjg-players, .bt-players { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
/* Mahjong: Spielerleiste zentriert wie die Topbar darüber (Betreiber-Wunsch). */
.mjg-players { justify-content: center; }
.rsm-pl, .mjg-pl, .bt-pl { display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; cursor: pointer;
    font: inherit; font-size: 13px; color: var(--old-paper);
    background: var(--well); border: 1px solid var(--border); border-radius: 999px; }
.mjg-pl { gap: 10px; }
.rsm-pl.turnow, .mjg-pl.turnow, .bt-pl.turnow { background: color-mix(in srgb, var(--accent) 30%, transparent);
    border-color: var(--accent-ink); }
.rsm-pl.turnow { box-shadow: 0 0 14px rgba(125,151,168,.35); }
.mjg-pl.turnow { box-shadow: 0 0 14px rgba(184,168,136,.35); }
.bt-pl.turnow  { box-shadow: 0 0 14px rgba(95,160,218,.35); }
.rsm-sw, .bt-sw { width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto; border: 1.5px solid rgba(0,0,0,.5); }
.rsm-nm, .mjg-nm, .bt-nm { font-weight: 600; color: var(--parchment); }
.rsm-nm.me, .mjg-nm.me, .bt-nm.me { color: var(--accent-ink); }

/* ════════════════════════════════════════════════════════════
   RAUSSCHMEISSER — dice race game on the SVG cross board.
   Namespaced .rsm-*; geometry lives in the SVG viewBox (uniform
   scaling, no reflow). Mockup: docs/mockups/ss0275-rausschmeisser-board.html
════════════════════════════════════════════════════════════ */

.rsm-board { display: flex; flex-direction: column; }
.rsm-prog { font-size: 12px; color: var(--old-paper); font-variant-numeric: tabular-nums; letter-spacing: .02em; }

/* Board host: SVG scales uniformly via viewBox ("meet"); overlays anchor to this wrapper. */
.rsm-svg-wrap { position: relative; display: flex; align-items: center; justify-content: center;
    flex: 1 1 auto; min-height: 0; }
.rsm-svg { width: 100%; height: auto; max-height: min(74vh, 640px); display: block; }
@media (min-width: 761px) {
  body.ss-maximized .rsm-svg { max-height: none; height: 100%; }
  body.ss-maximized .card-board > .screen-game.mode-rausschmeisser { display: flex; flex-direction: column; }
  body.ss-maximized .mode-rausschmeisser > .rsm-board { flex: 1 1 auto; min-height: 0; }
}

.rsm-pulse { animation: rsm-vpulse 1.4s ease-in-out infinite; }
@keyframes rsm-vpulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* Central "🎲 Würfeln" prompt (platform standard for dice games — no footer button) */
.rsm-roll-prompt { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    z-index: 28; pointer-events: none; }
.rsm-rp-card { pointer-events: auto; cursor: pointer; text-align: center; display: flex; flex-direction: column;
    align-items: center; gap: 10px; font: inherit; color: inherit;
    background: linear-gradient(135deg,#161b20,#0b0d10); border: 1px solid var(--raw-gold-light); border-radius: 16px;
    padding: 20px 34px; box-shadow: 0 18px 50px rgba(0,0,0,.55); animation: rsm-rp-glow 1.9s ease-in-out infinite;
    transition: transform .12s; }   /* Prompt-Karte bleibt dunkel (Kino-Muster) → --raw-* statt --accent-light/mode-getönt, gilt für alle Würfelspiele (Rausschmeisser+Boomtown teilen diese Klasse) */
.rsm-rp-card:hover { transform: translateY(-2px); }
.rsm-rp-card:active { transform: scale(.97); }
.rsm-rp-die { font-size: 52px; line-height: 1; color: #f1e7d0; text-shadow: 0 4px 12px rgba(0,0,0,.5); }
.rsm-rp-label { font-family: 'Rye', cursive; font-size: 22px; color: var(--raw-gold-light); }
.rsm-rp-hint { font-size: 12px; color: var(--raw-old-paper); }   /* Prompt-Karte bleibt dunkel (Kino-Muster) */
@keyframes rsm-rp-glow { 0%, 100% { box-shadow: 0 18px 50px rgba(0,0,0,.55), 0 0 0 rgba(125,151,168,0); }
    50% { box-shadow: 0 18px 50px rgba(0,0,0,.55), 0 0 30px rgba(125,151,168,.55); } }

/* ── Disconnect overlay + majority vote (all modes, last child of .card-board) ──
   Same visual family as the dice-roll prompts above: centered glowing card, accent
   from the mode. Deliberately NO board dim — the game stays playable underneath,
   so the wrapper passes clicks through and only the card itself is interactive.
   Theme-aware since SS-0312 stage 2 (modal tokens + ink tokens). */
.dcv-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    z-index: 40; pointer-events: none; }
.dcv-card { pointer-events: auto; width: min(84%, 340px); text-align: center; padding: 18px 20px 20px;
    background: linear-gradient(to bottom, var(--modal-grad-a) 0%, var(--modal-grad-b) 100%);
    border: 1px solid var(--accent); border-radius: 10px;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent), 0 16px 44px rgba(0,0,0,.6),
                0 0 30px color-mix(in srgb, var(--accent) 45%, transparent); }
.dcv-avatar { display: flex; justify-content: center; margin-bottom: 8px;
    animation: dcvPulse 1.6s ease-in-out infinite; border-radius: 50%; width: fit-content; margin-inline: auto; }
@keyframes dcvPulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(192,53,42,.5); } 50% { box-shadow: 0 0 0 8px rgba(192,53,42,0); } }
.dcv-name { font-weight: 600; color: var(--parchment); font-size: 15px; margin-bottom: 2px; }
.dcv-status { color: var(--red-light); font-size: 12px; margin-bottom: 14px; }
.dcv-timer { position: relative; width: 76px; height: 76px; margin: 0 auto 12px; }
.dcv-timer svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.dcv-timer-track { fill: none; stroke: var(--edge); stroke-width: 6; }
.dcv-timer-prog { fill: none; stroke: var(--accent-ink); stroke-width: 6; stroke-linecap: round;
    transition: stroke-dashoffset 1s linear; }
.dcv-timer-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-size: 20px; font-weight: 700; color: var(--accent-ink); font-variant-numeric: tabular-nums; }
.dcv-hint { font-size: 12px; color: var(--smoke); line-height: 1.5; }
.dcv-divider { height: 1px; background: var(--border); margin: 14px 0 12px; }
.dcv-vote-label { font-size: 12.5px; color: var(--parchment); margin-bottom: 10px; }
.dcv-vote-label b { color: var(--accent-ink); }
.dcv-vote-btns { display: flex; gap: 8px; margin-bottom: 10px; }
.dcv-btn { flex: 1; padding: 9px 4px; border-radius: var(--btn-radius); font-family: 'Rye', cursive;
    font-size: 13px; text-transform: uppercase; letter-spacing: .06em;
    border: 1px solid transparent; cursor: pointer; transition: filter .12s, outline-color .12s; }
.dcv-btn:hover { filter: brightness(1.15); }
.dcv-btn.on { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.dcv-btn-yes { background: linear-gradient(135deg, var(--blood-red), #5a0e0e); color: #fff; }
.dcv-btn-no { background: var(--edge); border-color: var(--edge-strong); color: var(--parchment); }
.dcv-tally { font-size: 12px; color: var(--smoke); }
.dcv-tally-bar { height: 5px; border-radius: 3px; background: var(--edge); margin-top: 5px; overflow: hidden; }
.dcv-tally-fill { height: 100%; background: var(--red-light); transition: width .25s ease; }

/* Dice roll cinema over the board (one die) */
.rsm-dice-cine { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    z-index: 1000; pointer-events: none;
    background: radial-gradient(ellipse 70% 60% at 50% 45%, rgba(6,4,2,.45), rgba(6,4,2,.82)); border-radius: 8px; }
.rsm-cine-inner { display: flex; align-items: center; gap: 24px; }
.rsm-cdie { font-size: 110px; line-height: 1; color: #f1e7d0;
    filter: drop-shadow(0 10px 26px rgba(0,0,0,.6)); }
.rsm-cdie.tumble { animation: rsm-tumble .5s linear infinite; }
@keyframes rsm-tumble { 0% { transform: rotate(0deg) translateY(0); } 25% { transform: rotate(95deg) translateY(-12px); }
    50% { transform: rotate(185deg) translateY(0); } 75% { transform: rotate(280deg) translateY(-9px); } 100% { transform: rotate(360deg) translateY(0); } }
.rsm-cine-sum { font-family: 'Rye', cursive; font-size: 54px; color: var(--gold-light); min-width: 60px;
    animation: rsm-sum-pop .3s cubic-bezier(.2,1.5,.4,1); }
@keyframes rsm-sum-pop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* Kick toast (board stays visible behind it) */
.rsm-toast { position: absolute; left: 0; right: 0; bottom: 0; display: flex; justify-content: center;
    z-index: 1000; padding: 16px; pointer-events: none; }
.rsm-toast-dlg { display: flex; align-items: center; gap: 12px; max-width: 460px;
    background: linear-gradient(135deg,#161b20,#0b0d10); border: 1px solid var(--accent-light); border-radius: 10px;
    padding: 12px 18px; box-shadow: 0 18px 60px rgba(0,0,0,.6); animation: rsm-toast-in .3s cubic-bezier(.2,1.4,.4,1); }
@keyframes rsm-toast-in { from { transform: translateY(16px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.rsm-toast-ic { font-size: 30px; line-height: 1; }
.rsm-toast-hd { font-family: 'Rye', cursive; font-size: 16px; color: var(--accent-light); }
/* The kick toast keeps its fixed dark card in both themes — pin the body ink
   to the raw palette so the light theme cannot darken it. */
.rsm-toast-bd { font-size: 13px; color: var(--raw-old-paper); }

/* Result spotlight stamp + round-over flourish */
.rsm-win-stamp { font-size: 64px; line-height: 1; filter: drop-shadow(0 0 14px rgba(125,151,168,.6)); }
.ro-flourish.ro-rausschmeisser { font-family: 'Rye', cursive; font-size: 30px; color: var(--accent-ink);
    text-shadow: 0 3px 10px rgba(0,0,0,.7); }

/* Intro scene: pawn trio + die behind the swing doors */
.rsmi-scene { display: flex; align-items: flex-end; gap: 10px; font-size: 44px; line-height: 1;
    filter: drop-shadow(0 6px 14px rgba(0,0,0,.55)); }
.rsmi-scene .rsmi-pawn.mid { font-size: 56px; }
.rsmi-scene .rsmi-die { font-size: 40px; color: #f1e7d0; margin-left: 6px; align-self: center; }

/* ════════════════════════════════════════════════════════════
   MAHJONG SOLITAIRE — layered pair puzzle. Namespaced
   .mjg-*; 2.5D depth purely from CSS (per-layer offset + staggered
   shadows) via a shared --scale variable (no transform:scale blur).
   Mockup: docs/mockups/ss0273-mahjong-solitaire.html
════════════════════════════════════════════════════════════ */

.mjg-board { display: flex; flex-direction: column; }
/* Topbar info (layout/tiles/status/hint) sits CENTERED above the board (owner preference) —
   neutralize the .grow spacer that would push the tools to the right edge. */
.mode-mahjong .durak-topbar { justify-content: center; }
.mode-mahjong .durak-topbar .grow { display: none; }

.mjg-tool { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font: inherit; font-size: 12.5px;
    font-weight: 600; color: var(--accent-ink); background: transparent; padding: 5px 12px;
    border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent); border-radius: var(--btn-radius); }
.mjg-tool:disabled { opacity: .45; cursor: default; }
/* No permanent glow: the toolbar shuffle is an always-available tool, not an alert.
   A real dead end is signalled by the central .mjg-shuffle-prompt (its own glow). */
.mjg-tool.mjg-shuffle { color: var(--heading); border-color: var(--gold-ink); }

/* Player strip (multiplayer): pair count on the shared pill chrome */
.mjg-pairs { font-weight: 700; color: var(--heading); font-variant-numeric: tabular-nums; }
.mjg-pairs small { color: var(--smoke); font-weight: 500; font-size: 12px; }

/* Board stage: layered tiles over a warm wood well. --scale drives ALL dimensions. */
.mjg-stage-wrap { position: relative; display: flex; align-items: center; justify-content: center;
    flex: 1 1 auto; min-height: 0; overflow: auto; padding: 24px 10px; --scale: 1.25; }
.mjg-stage { position: relative; margin: 0 auto; }
.mjg-stage::before { content: ""; position: absolute;
    left: calc(-26px * var(--scale)); right: calc(-26px * var(--scale));
    top: calc(-14px * var(--scale)); bottom: calc(-14px * var(--scale)); z-index: 0;
    background: radial-gradient(140% 120% at 50% 18%, #3a2a16 0%, #241a0e 45%, #160f08 82%);
    border: 2px solid color-mix(in srgb, var(--accent) 42%, #4a2f14); border-radius: calc(22px * var(--scale));
    box-shadow: inset 0 0 3px rgba(255,255,255,.05), inset 0 0 44px rgba(0,0,0,.6), 0 8px 24px rgba(0,0,0,.5); }
.mjg-stage-wrap .mjg-lay-dragon { --scale-hint: 1; }
@media (max-width: 900px) { .mjg-stage-wrap { --scale: 0.95; } }
@media (max-width: 560px) { .mjg-stage-wrap { --scale: 0.72; } }
/* Maximized: shadowSaloon.fitMahjong measures the host and sets --scale inline (measured
   fit); --scale:1.6 is only the no-JS fallback. overflow:hidden — the fit guarantees the
   board fits, and auto-scrollbars would shrink the measured area and feed back into the
   next fit (bars appear ↔ disappear). max-width:none overrides the inline 1100px cap
   (same pattern as the maximized durak-board) so wide layouts can use the full width. */
@media (min-width: 761px) {
  body.ss-maximized .mjg-stage-wrap { --scale: 1.6; overflow: hidden; }
  body.ss-maximized .card-board > .screen-game.mode-mahjong { display: flex; flex-direction: column; }
  body.ss-maximized .mode-mahjong > .mjg-board { flex: 1 1 auto; min-height: 0; max-width: none !important; }
  /* Height chain continued through the new .mjg-layout grid (same pattern as
     mode-memory > .hangman-layout): the maximized fit reads .mjg-stage-wrap's
     clientHeight as its budget, so the wrap MUST be height-locked by the layout.
     Without this the wrap is content-sized and feeds the fit its own output —
     a shrink loop down to the 0.72 floor. */
  body.ss-maximized .mode-mahjong .mjg-layout {
      flex: 1 1 auto; min-height: 0;
      grid-template-rows: minmax(0, 1fr); align-items: stretch;
  }
  body.ss-maximized .mode-mahjong .mjg-sidebar { align-self: start; }
}

/* Layers are board-sized transparent divs stacked by z-index — without pointer-events:none
   they swallow clicks on lower-layer tiles anywhere the upper layer has no tile of its own. */
.mjg-layer { position: absolute; inset: 0; pointer-events: none; }
/* Top-down view: layers draw with ZERO offset (a stone only covers what it sits on → free
   stones are ALWAYS fully visible/clickable). "There is a stone underneath" reads via a
   bright ivory tile edge peeking out below stones on layer ≥ 1 (every such stone sits on
   at least one stone by construction, and coverers block their base until removed) plus a
   per-layer brightness lift. All edge offsets scale with --scale and stay inside the 6px
   grid gap, so they never cover a neighbor. The look is fed through layer-level CSS
   variables so .sel/.hinted/.blocked overrides keep working untouched. */
.mjg-stone { position: absolute; display: grid; place-items: center; cursor: default; pointer-events: auto;
    width: calc(26px * var(--scale)); height: calc(34px * var(--scale)); border-radius: calc(5px * var(--scale));
    left: calc(var(--x) * 30px * var(--scale)); top: calc(var(--y) * 40px * var(--scale));
    background: linear-gradient(160deg, #efdcb4, #d6bd92); border: 1px solid #b89a63; color: #2e1f0e;
    box-shadow: var(--mjg-sh, 0 calc(2px * var(--scale)) 0 0 #8a7047, 0 4px 7px rgba(0,0,0,.42));
    filter: var(--mjg-br, none); }
.mjg-stone img { width: calc(20px * var(--scale)); height: calc(26px * var(--scale)); object-fit: contain;
    pointer-events: none; user-select: none; }
.mjg-layer:nth-child(2) { --mjg-br: brightness(1.05);
    --mjg-sh: 0 calc(2px * var(--scale)) 0 0 #8a7047,
              0 calc(4.5px * var(--scale)) 0 0 #e8d7b0,
              0 calc(5.5px * var(--scale)) 0 0 #6b532f,
              0 7px 12px rgba(0,0,0,.5); }
.mjg-layer:nth-child(3) { --mjg-br: brightness(1.1);
    --mjg-sh: 0 calc(2px * var(--scale)) 0 0 #8a7047,
              0 calc(4.5px * var(--scale)) 0 0 #e8d7b0,
              0 calc(5.5px * var(--scale)) 0 0 #6b532f,
              0 9px 15px rgba(0,0,0,.55); }
.mjg-layer:nth-child(4) { --mjg-br: brightness(1.15);
    --mjg-sh: 0 calc(2px * var(--scale)) 0 0 #8a7047,
              0 calc(4.5px * var(--scale)) 0 0 #e8d7b0,
              0 calc(5.5px * var(--scale)) 0 0 #6b532f,
              0 11px 18px rgba(0,0,0,.6); }
.mjg-stone.blocked { filter: brightness(.68) saturate(.75); }
.mjg-stone.free { cursor: pointer; }
/* Free dot scales with the board — at maximize scale it is THE clickability signal. */
.mjg-stone.free::after { content: ""; position: absolute;
    top: calc(-3px * var(--scale)); right: calc(-3px * var(--scale));
    width: max(6px, calc(7px * var(--scale))); height: max(6px, calc(7px * var(--scale)));
    border-radius: 50%; background: #2d7a4a; box-shadow: 0 0 0 1px rgba(0,0,0,.4); }
/* Selection ring keeps the layer's stack edge (--mjg-sh) so "something underneath" stays visible. */
.mjg-stone.sel { cursor: pointer;
    box-shadow: 0 0 0 3px var(--accent-ink), var(--mjg-sh, 0 calc(2px * var(--scale)) 0 0 #8a7047, 0 4px 7px rgba(0,0,0,.42));
    transform: translateY(-2px); z-index: 5; }
.mjg-stone.hinted { cursor: pointer; animation: mjg-hint-pulse 1.1s ease-in-out infinite; z-index: 5; }
@keyframes mjg-hint-pulse { 0%, 100% { box-shadow: 0 0 0 2px var(--gold), var(--mjg-sh, 0 calc(2px * var(--scale)) 0 0 #8a7047, 0 4px 7px rgba(0,0,0,.42)); }
    50% { box-shadow: 0 0 0 4px var(--gold-light), 0 0 18px rgba(232,184,75,.65), var(--mjg-sh, 0 calc(2px * var(--scale)) 0 0 #8a7047, 0 4px 7px rgba(0,0,0,.42)); } }
/* Placeholders are decor — never let them eat clicks meant for uncovered tiles. */
.mjg-stone.gone { background: var(--surface-2); border: 1.5px dashed color-mix(in srgb, var(--border-strong) 62%, transparent);
    box-shadow: none; filter: none; pointer-events: none; }

/* Pair toast / shuffle notice */
.mjg-toast { position: absolute; left: 0; right: 0; bottom: 6px; display: flex; justify-content: center;
    z-index: 1000; padding: 10px; pointer-events: none; }
.mjg-toast-dlg { display: inline-flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 600;
    color: var(--gold-light); background: color-mix(in srgb, var(--gold) 22%, #160f08);
    border: 1px solid var(--gold); border-radius: 10px; padding: 8px 14px;
    box-shadow: 0 10px 30px rgba(0,0,0,.5); animation: mjg-toast-in .25s cubic-bezier(.2,1.4,.4,1); }
@keyframes mjg-toast-in { from { transform: translateY(12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.mjg-toast-tile { width: 22px; height: 29px; object-fit: contain; background: linear-gradient(160deg,#efdcb4,#d6bd92);
    border: 1px solid #b89a63; border-radius: 4px; padding: 1px; }

/* Central "↻ Mischen" prompt at a solo dead end (platform standard: prompt on the
   board, mirrors .rsm-roll-prompt — the former topbar button was too easy to miss) */
.mjg-shuffle-prompt { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    z-index: 80; pointer-events: none; }
.mjg-sp-card { pointer-events: auto; cursor: pointer; text-align: center; display: flex; flex-direction: column;
    align-items: center; gap: 10px; font: inherit; color: inherit;
    background: linear-gradient(135deg,#1d1913,#0f0c08); border: 1px solid var(--raw-gold-light); border-radius: 16px;
    padding: 20px 34px; box-shadow: 0 18px 50px rgba(0,0,0,.55); animation: mjg-sp-glow 1.9s ease-in-out infinite;
    transition: transform .12s; }   /* Prompt-Karte bleibt dunkel (Kino-Muster) → --raw-* statt --accent-light/mode-getönt */
.mjg-sp-card:hover { transform: translateY(-2px); }
.mjg-sp-card:active { transform: scale(.97); }
.mjg-sp-icon { font-size: 46px; line-height: 1; filter: drop-shadow(0 4px 12px rgba(0,0,0,.5)); }
.mjg-sp-label { font-family: 'Rye', cursive; font-size: 22px; color: var(--raw-gold-light); }
.mjg-sp-hint { font-size: 12px; color: var(--raw-old-paper); max-width: 280px; }   /* Prompt-Karte bleibt dunkel (Kino-Muster) */
@keyframes mjg-sp-glow { 0%, 100% { box-shadow: 0 18px 50px rgba(0,0,0,.55), 0 0 0 rgba(184,168,136,0); }
    50% { box-shadow: 0 18px 50px rgba(0,0,0,.55), 0 0 30px rgba(184,168,136,.5); } }

/* Result spotlight stamp + round-over flourish */
.mjg-win-stamp { font-size: 64px; line-height: 1; filter: drop-shadow(0 0 14px rgba(184,168,136,.6)); }
.ro-flourish.ro-mahjong { font-family: 'Rye', cursive; font-size: 30px; color: var(--accent-ink);
    text-shadow: 0 3px 10px rgba(0,0,0,.7); }

/* Race format: everyone's board sits next to a live leaderboard rail instead of a turn-order strip. */
.mjg-layout { display: grid; grid-template-columns: 1fr 250px; gap: 16px; align-items: start; }
.mjg-layout.solo { grid-template-columns: 1fr; }
@media (max-width: 860px) { .mjg-layout { grid-template-columns: 1fr; } }

/* Spectate selector (SS-0340): a finished player watches a still-racing board read-only and
   switches between racers via chips, centered above the board (owner preference). */
.mjg-spectate-bar { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 2px auto 12px; }
.mjg-spec-cap { font-size: 12.5px; color: var(--smoke); }
.mjg-spec-cap strong { color: var(--gold-ink); font-weight: 600; }
.mjg-spec-chips { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.mjg-spec-chip { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; font: inherit; font-size: 13px;
    font-weight: 600; color: var(--old-paper); background: var(--edge); padding: 7px 14px; border-radius: 999px;
    border: 1px solid var(--border); }
.mjg-spec-chip:hover { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.mjg-spec-cnt { color: var(--smoke); font-weight: 500; font-size: 12px; font-variant-numeric: tabular-nums; }
.mjg-spec-chip.active { background: color-mix(in srgb, var(--accent) 24%, var(--edge)); border-color: var(--accent-light);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent); color: var(--accent-ink); }
.mjg-spec-chip.active .mjg-spec-cnt { color: var(--accent-ink); }
/* Read-only spectated board: hide the green free-dot + the clickable cursor (owner: dots off). */
.mjg-stage.spectate .mjg-stone.free::after { display: none; }
.mjg-stage.spectate .mjg-stone.free { cursor: default; }

.mjg-reshuffle.low { border-color: var(--danger-strong); color: var(--danger-strong); }

.durak-chip.mjg-timer { font-variant-numeric: tabular-nums; }
.durak-chip.mjg-timer.low { border-color: var(--danger-strong); color: var(--danger-strong); animation: seeTimerPulse 1s ease-in-out infinite; }

.mjg-stage.done .mjg-stone { filter: brightness(.45) saturate(.6); }
.mjg-stage-banner { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 6px; text-align: center; background: rgba(10,7,4,.72); border-radius: 12px;
    z-index: 90; padding: 0 24px; }
.mjg-sb-icon { font-size: 40px; filter: drop-shadow(0 4px 10px rgba(0,0,0,.5)); }
.mjg-sb-msg { font-family: 'Rye', cursive; font-size: 20px; color: var(--gold-light); }
.mjg-sb-sub { font-size: 12.5px; color: var(--smoke); max-width: 280px; }

/* Theme-aware panel surface — the old fixed rgba(0,0,0,.24) stayed a dark island in the light
   theme (SS-0312). --well is a subtle sunken surface in BOTH themes. */
.mjg-sidebar { background: var(--well); border: 1px solid var(--border); border-radius: 14px; padding: 12px; }
.mjg-sidebar-title { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--old-paper);
    font-weight: 700; margin: 2px 0 10px; }
.mjg-racer { display: flex; align-items: center; gap: 8px; width: 100%; font: inherit; text-align: left;
    padding: 8px 9px; border-radius: 9px; margin-bottom: 6px; cursor: pointer;
    /* --edge is theme-aware (the old fixed rgba(255,255,255,.03) was invisible on the light
       panel) so the rows read as distinct list items in both themes. */
    background: var(--edge); border: 1px solid transparent; color: inherit; }
.mjg-racer:last-child { margin-bottom: 0; }
.mjg-racer.me { border-color: var(--border-strong); background: color-mix(in srgb, var(--gold) 10%, transparent); }
.mjg-r-info { flex: 1 1 auto; min-width: 0; }
.mjg-r-nm { display: block; font-size: 12.5px; font-weight: 600; color: var(--parchment);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mjg-r-nm.me { color: var(--accent-ink); }
.mjg-r-st { display: block; font-size: 11px; color: var(--smoke); font-variant-numeric: tabular-nums; }
.mjg-racer.won .mjg-r-st { color: var(--success); }
.mjg-racer.lost .mjg-r-st { color: var(--danger-strong); }
.mjg-r-badge { font-size: 15px; flex: 0 0 auto; }
.mjg-racer.playing .mjg-r-badge { animation: mjg-badge-pulse 1.7s ease-in-out infinite; }
@keyframes mjg-badge-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }

/* End-of-game ranking panel — theme-aware surface (replaces the old fixed rgba(0,0,0,.24)
   dark island so it stays right in the light theme). Shared by the single-layout ranking and
   the aggregated "all variants" standings. */
.mjg-rank-panel { background: color-mix(in srgb, var(--accent) 12%, transparent);
    border: 1px solid var(--border); border-radius: 16px; padding: 18px; }
.mjg-rank-head { font-size: 13px; font-weight: 600; color: var(--old-paper); margin: 0 0 12px;
    text-transform: uppercase; letter-spacing: .08em; }

/* Aggregated standings (all variants): total row + per-variant breakdown chips. */
.mjg-agg-row { display: grid; grid-template-columns: 28px 1fr auto; align-items: center; gap: 10px;
    padding: 10px; border-radius: 10px; background: var(--edge); border: 1px solid transparent; margin-bottom: 8px; }
.mjg-agg-row:last-child { margin-bottom: 0; }
.mjg-agg-row.win { border-color: var(--gold); background: color-mix(in srgb, var(--gold) 12%, transparent); }
.mjg-agg-medal { font-size: 17px; text-align: center; }
.mjg-agg-nm { font-weight: 600; color: var(--parchment); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mjg-agg-tot { display: flex; gap: 14px; font-size: 12px; color: var(--old-paper); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mjg-agg-tot b { color: var(--parchment); }
.mjg-agg-variants { grid-column: 1 / -1; display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.mjg-agg-vchip { display: flex; align-items: center; gap: 5px; font-size: 11.5px; padding: 4px 9px; border-radius: 8px;
    background: var(--edge); border: 1px solid var(--border); color: var(--smoke); font-variant-numeric: tabular-nums; }
.mjg-agg-vchip .vn { color: var(--old-paper); }
.mjg-agg-vchip.cleared { color: var(--success); border-color: color-mix(in srgb, var(--success) 40%, transparent); }
.mjg-agg-vchip.cleared .vn { color: var(--success); }
.mjg-agg-vchip.stuck { color: var(--danger-strong); }

.mjg-rank-time { font-size: 12px; color: var(--smoke); font-variant-numeric: tabular-nums; min-width: 56px; text-align: right; }
.durak-rank.out { opacity: .72; }

/* Intro scene: small tile fan behind the swing doors */
.mjgi-fan { display: flex; align-items: flex-end; gap: 8px; }
.mjgi-tile { display: grid; place-items: center; width: 44px; height: 58px; border-radius: 7px;
    background: linear-gradient(160deg,#efdcb4,#d6bd92); border: 1px solid #b89a63;
    box-shadow: 0 4px 0 0 #8a7047, 0 8px 18px rgba(0,0,0,.5); transform: rotate(-8deg); }
.mjgi-tile.mid { width: 52px; height: 68px; transform: none; z-index: 2; }
.mjgi-tile:last-child { transform: rotate(8deg); }
.mjgi-tile img { width: 32px; height: 42px; object-fit: contain; }

/* ════════════════════════════════════════════════════════════
   BOOMTOWN — frontier build-and-trade hex board game.
   Namespaced .bt-*; the board scales uniformly via the SVG viewBox
   ("meet"). Reuses the rsm-* roll prompt/cinema/toast shells.
   Mockup: docs/mockups/ss0186-boomtown-board.html
════════════════════════════════════════════════════════════ */

.bt-board { display: flex; flex-direction: column; }
.bt-pulse { animation: rsm-vpulse 1.4s ease-in-out infinite; }

/* Setup phase (colour pick + roll for first founder) — centered panel over the board. */
.bt-setup-ovl { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    background: rgba(6, 4, 2, .55); z-index: 4; padding: 16px; }
.bt-setup-panel { width: min(460px, 92%); background: color-mix(in srgb, var(--accent) 14%, var(--chrome));
    border: 1px solid var(--border); border-radius: 16px; padding: 20px; text-align: center;
    box-shadow: 0 12px 34px rgba(0,0,0,.5); }
.bt-setup-title { font-family: 'Rye', cursive; font-size: 21px; color: var(--accent-ink); margin: 0 0 4px; }
.bt-setup-sub { font-size: 12.5px; color: var(--old-paper); margin: 0 0 16px; line-height: 1.45; }
.bt-setup-pal { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin: 0 0 16px; }
.bt-sw-pick { width: 40px; height: 40px; border-radius: 10px; border: 2px solid transparent; cursor: pointer; padding: 0; }
.bt-sw-pick.mine { border-color: #fff; box-shadow: 0 0 0 2px var(--gold); }
.bt-sw-pick.taken { cursor: not-allowed; opacity: .5; }
.bt-setup-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.bt-setup-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px;
    padding: 9px 12px; border-radius: 10px; background: var(--edge); border: 1px solid transparent; }
.bt-setup-row.lead { border-color: var(--gold); background: color-mix(in srgb, var(--gold) 12%, transparent); }
.bt-setup-row.out { opacity: .5; }
.bt-setup-sw { width: 16px; height: 16px; border-radius: 4px; flex: 0 0 auto; }
.bt-setup-sw.none { background: repeating-linear-gradient(45deg, #3a2a16, #3a2a16 3px, #241708 3px, #241708 6px); }
.bt-setup-nm { font-weight: 600; text-align: left; color: var(--parchment); min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bt-setup-die { font-size: 26px; line-height: 1; min-width: 30px; color: var(--parchment); }
.bt-setup-die.pending { color: var(--smoke); font-size: 13px; }
.bt-setup-roll { font-family: 'Rye', cursive; font-size: 16px; letter-spacing: .08em; text-transform: uppercase;
    padding: 12px 26px; border: none; border-radius: 2px; cursor: pointer;
    background: linear-gradient(135deg, var(--amber), var(--gold)); color: var(--shadow); }
.bt-setup-wait { font-size: 12.5px; color: var(--smoke); }

/* Dev-card explanation: small info glyph on the card + a description line in the play dialog. */
.bt-dev-info { font-size: 11px; color: var(--accent-ink); margin-left: 3px; cursor: help; }
.bt-dlg-desc { padding: 10px 16px 0; font-size: 12.5px; color: var(--old-paper); line-height: 1.45; }
/* Center the chrome rows (topbar, dev-card hand) to match the centered hex board —
   they otherwise inherited the shared left-aligned flex defaults and hung to the left. */
.mode-boomtown .durak-topbar { justify-content: center; }
.mode-boomtown .bt-hand { justify-content: center; }

/* ── Board + HUD sidebar (SS-0342) ────────────────────────────────
   Board (left, flexes) + fixed ~280px sidebar with the info cards from
   the ss0186 mockup. Theme-aware: cards on the recessed --well surface,
   accents via --accent-ink (no dark islands in light — the coloured
   resource tiles mirror the board terrain, which also stays coloured). */
.bt-main { display: flex; gap: 14px; align-items: flex-start; }
.bt-svg-wrap { min-width: 0; }
.bt-hud { flex: 0 0 280px; width: 280px; display: flex; flex-direction: column; gap: 10px; }
.bt-hud-card { background: var(--well); border: 1px solid var(--border); border-radius: 12px; padding: 11px 13px; }
.bt-hud-h { font-family: 'Rye', cursive; font-size: 15px; font-weight: 400; color: var(--accent-ink); margin: 0 0 9px; }

/* Card 1 — am Zug + Würfel */
.bt-hud-turn { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.bt-hud-who { font-family: 'Rye', cursive; font-size: 17px; color: var(--heading); line-height: 1.15; }
.bt-hud-phase { font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--smoke); margin-top: 3px; }
.bt-hud-dice { display: flex; gap: 6px; flex: 0 0 auto; }
.bt-hud-die { width: 32px; height: 32px; border-radius: 7px; display: grid; place-items: center;
    font-family: 'Rye', cursive; font-size: 17px; font-variant-numeric: tabular-nums; }
/* White digit on red = 5.6:1; dark-red digit on yellow = 4.7:1 (both ≥ WCAG AA 4.5:1). */
.bt-hud-die.red { background: #c62828; color: #fff; }
.bt-hud-die.yellow { background: #f2c200; color: #9c1b1a; }

/* Card 2 — Rohstoff-Kacheln (Terrain-Farbe; wheat abgedunkelt für Weiß-Kontrast ≥4.5:1).
   Icon + Zahl (kein Wort-Label, wie die bisherigen Chips) → Name im title-Tooltip. */
.bt-hud-res { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.bt-restile { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 7px 2px;
    border-radius: 7px; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.6); border: 1px solid rgba(0,0,0,.28); }
.bt-restile .ic { font-size: 18px; line-height: 1; }
.bt-restile .n { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.bt-restile.r-wood   { background: #2c4a2a; }
.bt-restile.r-cattle { background: #5d7a33; }
.bt-restile.r-wheat  { background: #7a5c14; }
.bt-restile.r-gold   { background: #55575f; }
.bt-restile.r-clay   { background: #8a5a30; }

/* Card 3 — Baukosten-Referenz */
.bt-hud-costs { display: flex; flex-direction: column; gap: 5px; font-size: 13px; }
.bt-hud-costs > div { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.bt-hud-costs span { color: var(--old-paper); }
.bt-hud-costs b { color: var(--parchment); font-weight: 500; letter-spacing: 1px; white-space: nowrap; }

/* Card 4 — Spieler & Punkte */
.bt-hud-players { display: flex; flex-direction: column; }
.bt-hud-pl { display: flex; align-items: center; gap: 7px; width: 100%; padding: 6px 5px; cursor: pointer;
    background: none; border: none; border-bottom: 1px solid var(--edge); color: var(--parchment);
    font: inherit; text-align: left; border-radius: 7px; }
.bt-hud-pl:last-child { border-bottom: none; }
.bt-hud-pl.turnow { background: color-mix(in srgb, var(--accent) 16%, transparent);
    box-shadow: 0 0 12px rgba(95,160,218,.28); }
.bt-hud-pl .bt-sw { width: 13px; height: 13px; border-radius: 3px; flex: 0 0 auto; }
.bt-hud-pl-nm { flex: 1; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bt-hud-pl-nm.me { color: var(--accent-ink); font-weight: 700; }
.bt-hud-pl-aw { font-size: 14px; flex: 0 0 auto; }
.bt-hud-pl-cards { font-size: 12px; color: var(--smoke); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.bt-hud-pl-vp { font-size: 15px; font-weight: 700; color: var(--heading); font-variant-numeric: tabular-nums;
    min-width: 18px; text-align: right; flex: 0 0 auto; }
.bt-hud-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 9px; }
.bt-hud-chip { font-size: 12px; border-radius: 999px; padding: 3px 9px; border: 1px solid var(--border);
    color: var(--old-paper); }
.bt-hud-chip.have { background: color-mix(in srgb, var(--accent) 22%, transparent);
    border-color: var(--accent-ink); color: var(--accent-ink); }

/* Card 5 — Legende */
.bt-hud-leg { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 8px; }
.bt-hud-leg-item { font-size: 12px; color: var(--old-paper); }

/* Narrow / mobile: sidebar wraps below the board full-width */
@media (max-width: 760px) {
  .bt-main { flex-direction: column; }
  .bt-hud { flex: 0 0 auto; width: auto; }
}

/* Player strip: VP/card counts on the shared pill chrome */
.bt-vp { font-weight: 700; color: var(--heading); font-variant-numeric: tabular-nums; }
.bt-cards { font-size: 12px; color: var(--smoke); font-variant-numeric: tabular-nums; }
.bt-award { font-size: 14px; }

/* Board host */
.bt-svg-wrap { position: relative; display: flex; align-items: center; justify-content: center;
    flex: 1 1 auto; min-height: 0; border-radius: 8px; overflow: hidden;
    /* Frontier-dusk backdrop so the board doesn't float (from the SS-0186 mockup). Theme-aware:
       a warm daylight sky in light mode keeps the "no dark islands" rule. */
    background:
      radial-gradient(ellipse 72% 55% at 50% 58%, rgba(200,146,42,.14), transparent 60%),
      linear-gradient(180deg, #141621 0%, #241a12 46%, #43260f 66%, #1a110a 74%, #0b0805 100%); }
[data-theme="light"] .bt-svg-wrap {
    background:
      radial-gradient(ellipse 72% 55% at 50% 58%, rgba(200,146,42,.20), transparent 62%),
      linear-gradient(180deg, #d7e2eb 0%, #ecdcbe 52%, #e0cb9e 72%, #d2b886 100%); }
.bt-svg { width: 100%; height: auto; max-height: min(70vh, 660px); display: block; }
@media (min-width: 761px) {
  body.ss-maximized .bt-svg { max-height: none; height: 100%; }
  body.ss-maximized .card-board > .screen-game.mode-boomtown { display: flex; flex-direction: column; }
  body.ss-maximized .mode-boomtown > .bt-board { flex: 1 1 auto; min-height: 0; }
  /* The board row flexes to fill the height; the sidebar matches board height and scrolls
     internally if its cards exceed it, so the fitted board never overflows. */
  body.ss-maximized .mode-boomtown .bt-main { flex: 1 1 auto; min-height: 0; align-items: stretch; }
  body.ss-maximized .mode-boomtown .bt-hud { min-height: 0; overflow-y: auto; }
}

/* Roll prompt dice preview + cinema dice (red/yellow pair, mockup) */
.bt-rp-dice { display: flex; gap: 8px; }
.bt-rp-die { font-size: 44px; line-height: 1; }
.bt-rp-die.red { color: #e0594d; } .bt-rp-die.yellow { color: #e8b84b; }
.bt-cdie { font-size: 100px; line-height: 1; filter: drop-shadow(0 10px 26px rgba(0,0,0,.6)); }
.bt-cdie.red { color: #e0594d; } .bt-cdie.yellow { color: #e8b84b; }
.bt-cdie.tumble { animation: rsm-tumble .5s linear infinite; }

/* Own hand: resource chips + dev cards */
.bt-hand { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0 0;
    padding: 8px 12px; background: var(--well); border: 1px solid var(--border); border-radius: 10px; }
.bt-res { display: inline-flex; align-items: center; gap: 5px; font-size: 14px; color: var(--parchment);
    padding: 4px 10px; border-radius: 8px; background: var(--edge); border: 1px solid var(--border);
    font-variant-numeric: tabular-nums; }
.bt-res.empty { opacity: .45; }
.bt-dev { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--old-paper);
    padding: 4px 10px; border-radius: 8px; background: color-mix(in srgb, var(--accent) 18%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 50%, transparent); }
.bt-dev.vp { border-color: var(--gold-ink); color: var(--heading); }
.bt-dev.fresh { opacity: .55; border-style: dashed; }
.bt-dev-play { font: inherit; font-size: 12px; font-weight: 700; cursor: pointer; color: #0b1116;
    background: linear-gradient(135deg, var(--accent), var(--accent-light)); border: none;
    border-radius: var(--btn-radius); padding: 2px 9px; }

/* Action footer + trade banner — centered compact row, same idiom as Seeschlacht's
   .see-actions (NOT the full-bleed .card-actions-bar strip, which forced space-between
   and a negative-margin overhang). Primary action = .btn-gold, rest = .btn-ghost. */
.bt-foot { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.bt-foot .btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; width: auto; flex: 0 0 auto; }
.bt-foot-hint { font-size: 13px; color: var(--old-paper); }
.bt-trade-in { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 10px;
    padding: 10px 14px; font-size: 13px; color: var(--parchment);
    background: color-mix(in srgb, var(--gold) 16%, transparent); border: 1px solid var(--gold-ink); border-radius: 10px; }
.bt-trade-in .btn { display: inline-flex; width: auto; flex: 0 0 auto; padding: 6px 12px; }
.bt-resp { font-size: 12.5px; color: var(--smoke); }
.bt-resp.ok { color: var(--success); font-weight: 700; }

/* Dialog shell (build/trade/discard/steal/dev pickers) */
.bt-dlg { background: linear-gradient(135deg,#141a22,#0a0d12); border: 1px solid var(--accent-light);
    border-radius: 10px; max-width: 560px; width: 100%; overflow: hidden; box-shadow: 0 18px 60px rgba(0,0,0,.6);
    max-height: 86vh; display: flex; flex-direction: column; }
.bt-dlg-hd { padding: 12px 16px; background: color-mix(in srgb, var(--accent) 22%, transparent);
    border-bottom: 1px solid var(--border); font-family: 'Rye', cursive; font-size: 17px; color: var(--accent-light); }
.bt-dlg-bd { padding: 14px 16px; font-size: 13.5px; color: var(--old-paper); overflow-y: auto; }
.bt-dlg-ft { padding: 12px 16px; border-top: 1px solid var(--border); display: flex; gap: 10px; justify-content: flex-end; }
.bt-dlg .btn { display: inline-flex; width: auto; flex: 0 0 auto; }

/* Build menu rows */
.bt-build-opt { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--edge); }
.bt-build-opt:last-child { border-bottom: none; }
.bt-bo-ic { font-size: 26px; width: 34px; text-align: center; }
.bt-bo-main { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.bt-bo-name { font-size: 14px; font-weight: 600; color: var(--parchment); }
.bt-bo-name small { font-weight: 500; color: var(--smoke); font-size: 12px; }
.bt-bo-cost { font-size: 15px; letter-spacing: 2px; }

/* Discard hand */
.bt-discard-hand { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }
.bt-dc { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 56px; padding: 8px 4px;
    font: inherit; cursor: pointer; color: var(--parchment); background: var(--edge);
    border: 1.5px solid var(--border); border-radius: 8px; }
.bt-dc span { font-size: 20px; }
.bt-dc small { font-size: 12px; color: var(--smoke); }
.bt-dc.sel { border-color: #e0594d; background: rgba(224,89,77,.14); transform: translateY(-3px); }

/* Steal + dev pickers */
.bt-victims { display: flex; flex-wrap: wrap; gap: 10px; }
.bt-victims .btn { display: inline-flex; align-items: center; gap: 8px; width: auto; flex: 0 0 auto; }

/* Trade editor */
.bt-trade-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.bt-cap { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--smoke); width: 72px; }
.bt-bag { display: flex; flex-wrap: wrap; gap: 6px; }
.bt-tok { display: inline-flex; align-items: center; gap: 5px; font-size: 13.5px; color: var(--parchment);
    padding: 3px 6px; border-radius: 8px; background: var(--edge); border: 1px solid var(--border);
    font-variant-numeric: tabular-nums; }
.bt-step { font: inherit; font-size: 13px; font-weight: 700; width: 24px; height: 24px; cursor: pointer;
    color: var(--accent-ink); background: var(--edge); border: 1px solid var(--border); border-radius: 6px; }
.bt-partner { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--edge); flex-wrap: wrap; }
.bt-partner:last-child { border-bottom: none; }
.bt-hr { border: none; border-top: 1px solid var(--border); margin: 14px 0; }
.bt-bank-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; font-size: 12.5px; flex-wrap: wrap; }
.bt-bank-row .btn { padding: 5px 12px; }
.bt-bank-sel { font: inherit; font-size: 12.5px; color: var(--parchment); background: var(--input-bg);
    border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; }

/* Result spotlight stamp + round-over flourish + intro */
.bt-win-stamp { font-size: 64px; line-height: 1; filter: drop-shadow(0 0 14px rgba(95,160,218,.6)); }
.ro-flourish.ro-boomtown { font-family: 'Rye', cursive; font-size: 30px; color: var(--accent-ink);
    text-shadow: 0 3px 10px rgba(0,0,0,.7); }
.bti-scene { display: flex; align-items: center; gap: 10px; font-size: 40px; line-height: 1;
    filter: drop-shadow(0 6px 14px rgba(0,0,0,.55)); }
.bti-scene .bti-hex { display: grid; place-items: center; width: 58px; height: 64px;
    background: color-mix(in srgb, var(--accent) 30%, #17202b);
    clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); }
.bti-scene .bti-hex.mid { width: 70px; height: 78px; font-size: 46px; }
.bti-scene .bti-dice { font-size: 26px; margin-left: 4px; }

/* ════════════════════════════════════════════════════════════
   SITEWIDE "SALOON-RAHMEN" — unified page shell for all
   non-stage pages (Home, Profil, Teams, Admin, Mod, Regeln,
   Neuigkeiten, Legal). Source of truth: the approved mockup
   docs/mockups/sitewide-layout-final.html.
════════════════════════════════════════════════════════════ */

/* ── WCAG 2.2 AA: visible focus (2.4.7) + focus not obscured by the sticky
   header/footer bars (2.4.11). The global !important guards against any
   component-level outline:none silently killing the ring. Components that
   deliberately move the ring onto a surrounding container (search pills)
   must pair `outline:none !important` on the input with a `:has()` ring
   on the container — see .pf-search below for the pattern. ── */
:focus-visible { outline: 3px solid var(--accent-strong) !important; outline-offset: 2px; }
button, a, input, select, textarea, [tabindex] { scroll-margin-top: 96px; scroll-margin-bottom: 84px; }

/* ── Page frame (PageFrame.razor): header card → tabs row → board → footer ── */
.pf-main {
  flex: 1 0 auto;
  width: 100%;
  padding: 26px 22px 70px;   /* bottom clears the fixed .app-footer */
  display: flex; flex-direction: column; align-items: center;
}
.pf-col {
  width: 100%;
  --pf-border: color-mix(in srgb, var(--accent) 42%, transparent);
  animation: pfFade .22s ease;
}
.pf-col.w-narrow   { max-width: 720px; }
.pf-col.w-standard { max-width: 1000px; }
.pf-col.w-wide     { max-width: 1280px; }
@keyframes pfFade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }

.pf-pageuh {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  border-radius: 4px 4px 0 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 14%, var(--scrim)), var(--scrim));
  border: 1px solid var(--pf-border); border-bottom: none;
}
.pf-pageuh-top {
  position: relative; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; width: 100%; padding: 9px 16px; flex-wrap: wrap;
}
.pf-title { display: flex; align-items: center; gap: 9px; font-family: 'Rye', cursive; color: var(--heading); font-size: 16px; margin: 0; }
.pf-title h1 { font: inherit; color: inherit; margin: 0; letter-spacing: inherit; }
.pf-ico {
  width: 30px; height: 30px; border-radius: 6px; display: grid; place-items: center; font-size: 16px;
  background: color-mix(in srgb, var(--accent) 28%, transparent);
  border: 1px solid var(--pf-border); color: var(--heading);
}
.pf-acts { display: flex; align-items: center; gap: 6px; }
.pf-tabs {
  display: flex; gap: 2px; width: 100%; min-width: 0; padding: 0 12px;
  border-top: 1px solid var(--pf-border); overflow-x: auto;
}
/* Pages pass the Tabs fragment conditionally (loading states) — hide the row
   entirely while it has no real tab buttons, so no empty border strip shows. */
.pf-tabs:not(:has(*)) { display: none; }
.pf-board {
  /* V2: own gradient tier (was --surface-1) so nested cards that also use
     --surface-1 (status-card, db-section, stats-mode-card, pg-poster, …) read as
     a distinct raised layer instead of doubling the identical panel tone. Cards on
     it get --card-edge borders (rule below) to stay ≥3:1. */
  border: 1px solid var(--pf-border);
  background: linear-gradient(160deg, var(--card-grad-a), var(--card-grad-b));
  padding: 20px 22px;
}
/* V2: AA edge for cards nested directly on the (now lighter) .pf-board panel.
   Scoped under .pf-board so the game-frame/stage borders (.card-board,
   .lobby-stage-theatre — outside PageFrame) are NOT touched and stay dark.
   Higher specificity than the cards' own .xxx { border: … } → no !important. */
.pf-board .status-card, .pf-board .db-section, .pf-board .maintenance-card,
.pf-board .mailoauth-card, .pf-board .backup-card, .pf-board .users-row,
.pf-board .report-block, .pf-board .chat-snapshot, .pf-board .importjobs-card,
.pf-board .stats-mode-card, .pf-board .stat-box, .pf-board .card,
.pf-board .pg-poster, .pf-board [class$="-card"], .pf-board [class$="-section"] {
  border-color: var(--card-edge);
}
.pf-board .erow { background: var(--surface-2); border-left-color: var(--card-edge); }
.pf-board.pad-none { padding: 0; }
/* Card-bottom rule: round the bottom ONLY when no footer bar follows
   (docked pages keep it square so the footer joins seamlessly). */
.pf-board.cap-bottom { border-radius: 0 0 4px 4px; }
.pf-footer-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 16px; border: 1px solid var(--pf-border); border-top: none;
  border-radius: 0 0 4px 4px; background: var(--surface-1-strong);
}
@media (max-width: 640px) { .pf-main { padding-left: 12px; padding-right: 12px; } }

/* ── Shared pill-tab idiom (SubnavTabs.razor) — the ONE navigational pattern
   replacing Admin sidebar tabs, Profil tabs and Mod tabs. ── */
.pg-tab {
  font: inherit; font-size: 12.5px; color: var(--text-dim); background: transparent;
  border: none; border-bottom: 2px solid transparent; padding: 9px 13px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
}
.pg-tab:hover { color: var(--text-main); }
.pg-tab.on { color: var(--heading); border-bottom-color: var(--accent-light); }
.pg-tab .cnt { font-size: 12px; background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: 999px; padding: 0 6px; }
.pg-tab .tab-sub { font-size: 12px; color: var(--text-dim); font-weight: 400; opacity: .8; }
.pg-tab .tab-caret { opacity: .6; font-size: 12px; }
/* Second (smaller) tab row for Admin's real sub-level (Content/Diagnose/
   Einstellungen) — rendered inside the board, clearly a 2nd hierarchy level. */
.pf-sub-tabs {
  display: flex; gap: 2px; flex-wrap: wrap; margin: -6px 0 16px; padding-left: 6px;
  border-bottom: 1px solid var(--border-soft);
}
.pf-sub-tabs .pg-tab { font-size: 12px; padding: 6px 12px; }
.pf-sub-tabs .pg-tab.on { font-weight: 600; }

/* ── Generic in-board building blocks (from the approved mockup) ── */
.pg-title { font-family: 'Rye', cursive; color: var(--heading); font-size: 22px; margin: 0 0 4px; }
.pg-sub { color: var(--text-dim); font-size: 13px; margin: 0 0 18px; max-width: 640px; }
.pg-section { margin-bottom: 22px; }
.pg-section-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.pg-section-head h3 { font-family: 'Rye', cursive; color: var(--heading); font-size: 15px; margin: 0; }
.pf-search {
  flex: 1; min-width: 160px; display: flex; align-items: center; gap: 7px; padding: 8px 12px;
  border-radius: 7px; background: var(--surface-1); border: 1px solid var(--border-soft);
  color: var(--text-dim); font-size: 12.5px;
}
/* Search box above the statistics card grids (profile + admin). */
.stats-search { flex: none; max-width: 320px; margin: 14px 0 12px; }
.pf-search input {
  flex: 1; min-width: 0; border: none; background: transparent; color: var(--text-main);
  font: inherit; padding: 0;
}
.pf-search:has(input:focus-visible) { outline: 3px solid var(--accent-strong); outline-offset: 2px; border-color: var(--accent); }
.pf-search input:focus-visible { outline: none !important; }

/* ── Home: flat poster grid (alphabetical, all games equal) ── */
.pg-poster-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.pg-poster {
  position: relative; border-radius: 9px; overflow: hidden; border: 1px solid var(--border-soft);
  background: var(--surface-1); cursor: pointer; transition: .15s;
  text-align: left; font: inherit; color: inherit; padding: 0; margin: 0;
  /* Flex column instead of block: Blazor leaves whitespace text nodes inside
     the button (around the conditional spotlight/off badges). In block layout
     they form an anonymous line box (~8px pale bar ABOVE the art area, came
     and went with the spotlight rotation); as whitespace-only flex items they
     are guaranteed not to render. */
  display: flex; flex-direction: column;
}
.pg-poster .art { flex: none; }
.pg-poster .bd { flex: 1; }
.pg-poster:hover { transform: translateY(-2px); border-color: var(--border-strong); }
.pg-poster.spotlight-active {
  border: 2px solid var(--accent-strong);
  box-shadow: 0 0 0 1px var(--accent-strong), 0 4px 14px color-mix(in srgb, var(--accent-strong) 35%, transparent);
}
.pg-poster-tag {
  position: absolute; top: 8px; right: 8px; z-index: 1; background: var(--accent-strong);
  color: var(--text-invert); font-size: 12px; font-weight: 700; padding: 3px 8px;
  border-radius: 20px; letter-spacing: .02em;
}
.pg-poster .art {
  height: 76px; display: grid; place-items: center; font-size: 34px; color: var(--heading);
  /* Top glow PLUS an even base tint. Deliberately a LINEAR gradient: the
     mockup's oversized radial ellipse (120% 140%) rasterizes
     non-deterministically in Chromium (some tiles paint the falloff
     inverted → reads as a white bar at the top). The linear falloff is
     visually equivalent and paints reliably. */
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent) var(--art-glow, 34%), transparent) 0%, transparent 85%),
    color-mix(in srgb, var(--accent) var(--art-tint, 14%), transparent);
}
/* Color emojis carry their own hues and ignore `color`. In light mode the pale
   accent wash behind them is low-contrast against cool glyphs (the anchor, the
   blue theatre mask). A thin dark outline lifts every icon off the wash; it is
   imperceptible on warm/dark emojis that already contrast, so the rule is
   systemic rather than per-mode. Light mode only — the dark theme sits the icons
   on a dark wash where the issue does not occur. text-shadow, not filter, so the
   outline traces the glyph and not the tinted box (both share this element). */
[data-theme="light"] .pg-poster .art { text-shadow: 0 0 1px rgba(58, 42, 22, .6), 0 1px 1px rgba(58, 42, 22, .38); }
.pg-poster .bd { padding: 9px 11px 11px; }
.pg-poster .nm { font-family: 'Rye', cursive; color: var(--heading); font-size: 13.5px; margin: 0 0 3px; }
.pg-poster .ds { color: var(--text-dim); font-size: 12px; line-height: 1.4; margin: 0; min-height: 34px; }
.pg-poster .pl { color: var(--heading); font-size: 12px; margin: 6px 0 0; font-weight: 600; }
.pg-poster-off { opacity: .55; }
/* right:auto — the base badge rule anchors right:8px; with BOTH set the badge
   would stretch across the full tile width (left+right resolved together). */
.pg-poster .home-mode-off-badge { position: absolute; top: 8px; left: 8px; right: auto; z-index: 1; }
@media (max-width: 960px) { .pg-poster-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .pg-poster-grid { grid-template-columns: 1fr 1fr; } }

/* ── Home: "Im Rampenlicht" spotlight banner. Seit SS-0312 theme-fähig:
   Flächen über --spot-accent-mix/--surface-0-c (Light mischt gegen Weiß,
   s. Light-Override weiter unten), Texte über --heading/--text-main.
   Mode accent comes from the .mode-* class on the banner. ── */
.pg-spotlight {
  position: relative; overflow: hidden; margin-bottom: 18px; display: flex; align-items: center;
  gap: 22px; flex-wrap: wrap; padding: 22px 26px; border-radius: 10px;
  border: 1px solid var(--accent);
  background: linear-gradient(110deg, color-mix(in srgb, var(--accent) var(--spot-accent-mix), var(--surface-0-c)) 0%, var(--surface-0-c) 62%);
  transition: background .3s ease, border-color .3s ease;
}
.pg-spotlight-glow {
  position: absolute; right: -50px; top: -60px; width: 280px; height: 280px; border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent-light) 45%, transparent), transparent 65%);
}
/* Fixed icon zone: the glyph is centered inside a constant-width box so the
   banner geometry never shifts between wide emojis (brain, masks) and narrow
   symbol glyphs (♦/♣/♠) — the text column always starts at the same x. */
.pg-spotlight-ic { font-size: 76px; line-height: 1; color: var(--text-main); filter: drop-shadow(0 8px 20px rgba(0,0,0,.5)); flex: none; position: relative; z-index: 1; width: 96px; display: grid; place-items: center; }
.pg-spotlight-txt { flex: 1; min-width: 220px; position: relative; z-index: 1; }
.pg-spotlight-tag { font-size: 12px; letter-spacing: .18em; text-transform: uppercase; color: var(--heading); margin-bottom: 6px; font-weight: 600; }
.pg-spotlight-txt h2 { font-family: 'Rye', cursive; font-size: 22px; color: var(--heading); margin: 0 0 6px; }
.pg-spotlight-txt p { color: var(--text-main); font-size: 13px; margin: 0; max-width: 520px; opacity: .9; }
.pg-spotlight-btns { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.pg-spotlight-btns .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: auto; flex: 0 0 auto; padding: 9px 18px; font-size: 13px; border-radius: var(--btn-radius);
}
.pg-spotlight-btns .btn-ghost { border-color: var(--heading); color: var(--text-main); }
.pg-spotlight-meta { margin-top: 10px; font-size: 12px; color: var(--smoke); }
/* Light: Glow, Ring + Fortschrittsleiste nutzen den GRUND-Akzent statt
   --accent-light — sonst wirkt der Banner wie eine andere Spielfarbe als
   die Poster-Kacheln (Betreiber-Fund: "andere Akzentfarbe?"). */
/* Light: gegen WEISS mischen statt gegen den warmen Sand — dunkle Akzente
   (Aubergine, Sienna) vermatschen sonst zu Beige und der Banner wirkt farblos. */
[data-theme="light"] .pg-spotlight {
  background: linear-gradient(110deg, color-mix(in srgb, var(--accent) 36%, #fffdf7) 0%, var(--surface-0-c) 62%);
}
[data-theme="light"] .pg-spotlight-glow { background: radial-gradient(circle, color-mix(in srgb, var(--accent) 30%, rgba(255,253,247,.0)), transparent 65%); }
[data-theme="light"] .pg-spotlight-ring .rprog { stroke: var(--accent); }
[data-theme="light"] .pg-spotlight-bar .fill { background: var(--accent); }
/* Light: Titel/Tag auf dem Akzent-Pastell brauchen den dunkelsten Textton —
   --heading (#7a4a12) schafft dort nur ~4:1. Dark bleibt Gold. */
[data-theme="light"] .pg-spotlight-tag,
[data-theme="light"] .pg-spotlight-txt h2 { color: var(--text-main); }

/* Auto-rotation controls (WCAG 2.2.2 pause/stop/hide): pause button top-right
   with an SVG progress ring + slim progress bar along the bottom edge. Both are
   pure CSS animations over --spotlight-cycle (MUST match the C# rotation
   interval in Home.razor); .is-paused (server truth: hover/focus/button)
   freezes them via animation-play-state, a fresh @key per rotation restarts
   them. Raw tokens only — the banner stays an always-dark island. */
.pg-spotlight { --spotlight-cycle: 30s; }
.pg-spotlight:hover, .pg-spotlight:focus-within {
  border-color: var(--accent-light);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-light) 30%, transparent);
}
.pg-spotlight-ctrl { position: absolute; top: 10px; right: 10px; display: flex; align-items: center; gap: 8px; z-index: 1; }
.pg-spotlight-paused-lbl { font-size: 12px; color: var(--smoke); }
.pg-spotlight-pause {
  position: relative; width: 36px; height: 36px; border-radius: 50%; border: none; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  background: color-mix(in srgb, var(--text-main) 12%, transparent);
  color: var(--text-main); font-size: 14px; line-height: 1;
}
.pg-spotlight-pause:hover { background: color-mix(in srgb, var(--text-main) 22%, transparent); }
.pg-spotlight-ring { position: absolute; inset: 0; width: 36px; height: 36px; transform: rotate(-90deg); pointer-events: none; }
.pg-spotlight-ring circle { fill: none; stroke-width: 2.5; }
.pg-spotlight-ring .rtrack { stroke: color-mix(in srgb, var(--text-main) 18%, transparent); }
/* dasharray/-offset = circumference of r=16 (2·π·16 ≈ 100.53) */
.pg-spotlight-ring .rprog {
  stroke: var(--accent-light); stroke-linecap: round;
  stroke-dasharray: 100.53; stroke-dashoffset: 100.53;
  animation: spotlight-ring var(--spotlight-cycle) linear forwards;
}
@keyframes spotlight-ring { to { stroke-dashoffset: 0; } }
.pg-spotlight-bar {
  position: absolute; left: 0; right: 0; bottom: 0; height: 4px; pointer-events: none;
  background: color-mix(in srgb, var(--text-main) 15%, transparent);
}
.pg-spotlight-bar .fill {
  display: block; height: 100%; background: var(--accent-light);
  transform: scaleX(0); transform-origin: left;
  animation: spotlight-bar var(--spotlight-cycle) linear forwards;
}
@keyframes spotlight-bar { to { transform: scaleX(1); } }
.pg-spotlight.is-paused .rprog, .pg-spotlight.is-paused .fill { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .pg-spotlight-ring .rprog, .pg-spotlight-bar .fill { animation: none; }
}

@media (max-width: 640px) {
  .pg-spotlight { flex-direction: column; text-align: center; padding: 20px; }
  .pg-spotlight-btns, .pg-spotlight-meta { justify-content: center; }
}

/* Link row "view full profile" in the player quick-view modal. */
.player-profile-fulllink { margin-top: 12px; text-align: center; font-size: 13px; }
.player-profile-fulllink a { color: var(--heading); text-decoration: none; }
.player-profile-fulllink a:hover { text-decoration: underline; }

/* ── Hero row (public profile head) + generic list rows (friends/favorites) ── */
.pg-hero {
  display: flex; align-items: center; gap: 18px; padding: 18px 20px; border-radius: 10px;
  background: var(--surface-1); border: 1px solid var(--border-soft); margin-bottom: 18px; flex-wrap: wrap;
}
.pg-hero-info { flex: 1; min-width: 140px; }
.pg-hero h2 { font-family: 'Rye', cursive; color: var(--heading); font-size: 22px; margin: 0 0 4px; }
.pg-hero p { color: var(--text-dim); font-size: 12.5px; margin: 0; }
.pg-hero-team-link { color: var(--heading); text-decoration: none; }
.pg-hero-team-link:hover { text-decoration: underline; }
.pg-team-row {
  display: flex; align-items: center; gap: 12px; padding: 11px 13px; border-radius: 8px;
  background: var(--surface-1); border: 1px solid var(--border-soft); margin-bottom: 8px;
}
.pg-row-main { flex: 1; min-width: 0; }
.pg-row-title { color: var(--text-main); font-size: 13px; font-weight: 600; }
.pg-row-meta { color: var(--text-dim); font-size: 12px; }

/* ── Rules page: split view (game list left, detail right) ── */
.rules-split { display: grid; grid-template-columns: 220px 1fr; gap: 16px; align-items: start; }
.rules-split-list { display: flex; flex-direction: column; gap: 3px; }
/* .pf-search is flex:1 for toolbar use — inside the vertical list column that
   would make it GROW with the detail pane's height. Pin it to its own height. */
.rules-split-list .pf-search { flex: 0 0 auto; margin-bottom: 10px; }
.rsplit-item {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 9px 12px; border-radius: 7px;
  border: 1px solid transparent; background: transparent; color: var(--text-main);
  font: inherit; font-size: 12.5px; cursor: pointer; text-align: left;
}
.rsplit-item:hover { background: var(--surface-hover); }
.rsplit-item.on { background: var(--surface-2); border-color: var(--border-strong); color: var(--heading); font-weight: 600; }
.rsplit-item .ic { font-size: 16px; width: 20px; flex: none; display: inline-flex; align-items: center; justify-content: center; }
.rsplit-empty { font-size: 12.5px; color: var(--text-dim); padding: 8px 12px; }
.rules-split-detail { background: var(--surface-1); border: 1px solid var(--border-soft); border-radius: 8px; padding: 18px 20px; min-width: 0; }
.rsd-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.rsd-head .ic { font-size: 28px; }
.rsd-head h2 { font-family: 'Rye', cursive; color: var(--heading); font-size: 17px; margin: 0; }
.rsd-meta { font-size: 12px; color: var(--text-dim); margin-bottom: 12px; }
@media (max-width: 640px) { .rules-split { grid-template-columns: 1fr; } }

/* ── Header theme toggle (light/dark) — same pill sizing as the other
   header controls. ── */
.theme-btn {
  width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center;
  justify-content: center; cursor: pointer; padding: 0; font-size: 15px;
  background: var(--surface-1); border: 1px solid var(--border-strong); color: var(--heading);
  transition: border-color .15s, background .15s;
}
.theme-btn:hover { border-color: var(--gold); background: var(--surface-hover); }

/* ── Light theme: targeted surface fixes for legacy hull pieces that keep
   their hardcoded dark tints otherwise. Kept as an explicit, bounded list. ── */
[data-theme="light"] body::before { opacity: .18; }   /* grain: much softer on paper */
[data-theme="light"] .profile-dropdown,
[data-theme="light"] .lang-dd-list { background: var(--surface-1-strong); border-color: var(--border-soft); color: var(--text-main); }
[data-theme="light"] .auth-btn-solid { background: linear-gradient(180deg, #f4e6c6, #ecd9ac); color: var(--heading); }
[data-theme="light"] .auth-btn-solid:hover { background: linear-gradient(180deg, #f8ecd2, #f0e0b8); }

[data-theme="light"] .oauth-delete-note { color: #3a4a6a; }

[data-theme="light"] .email-verified { color: var(--success); }
[data-theme="light"] .cl-badge-new { color: #8a4108; }
[data-theme="light"] .presence-online { color: var(--success); }
[data-theme="light"] .btn-ghost-red { color: #a32a2a; border-color: rgba(139, 26, 26, .45); }
[data-theme="light"] .btn-ghost-red:hover { color: #8b1a1a; }
[data-theme="light"] .help-icon-btn { color: #7a4a12; }

/* ── SS-0312 stage 2 — light overrides for GAME surfaces. Everything the
   token swap alone cannot express: glow effects that only work on a dark
   canvas, opaque sticky covers, decorative alpha tints. Dark stays untouched
   (base rules keep the old values); this list is the light-side counterpart
   and intentionally bounded — new game CSS should use the theme tokens
   directly instead of growing this section. ── */
[data-theme="light"] .secret-word-text { text-shadow: none; }
[data-theme="light"] .host-only-label { color: var(--text-dim); }
[data-theme="light"] .card-board .podium-stats .section-label { background: #f3e6c8; }
[data-theme="light"] .player-slot.disconnected { background: rgba(163, 50, 74, .08); }
[data-theme="light"] .r-gold, [data-theme="light"] .r-red,
[data-theme="light"] .r-amber { text-shadow: none; }   /* Titel-Glow vermatscht auf Pergament */
[data-theme="light"] .abort-btn { color: var(--danger-strong); border-color: rgba(139, 26, 26, .45); }
[data-theme="light"] .start-overlay-num { text-shadow: none; }
[data-theme="light"] .dcv-status { color: var(--danger-strong); }
[data-theme="light"] .durak-role.att { color: var(--danger-strong); }
/* Schattenspiel: Geist-Stahlblau + Hellgruen/-rot sind Dunkel-Inks — Light braucht dunkle Toene. */
[data-theme="light"] .uc-title-ghost { color: #47596a !important; text-shadow: none; }
[data-theme="light"] .uc-ghost-card .impostor-category-value,
[data-theme="light"] .uc-ghost-text { color: #47596a !important; }
[data-theme="light"] .uc-role-tag.ghost,
[data-theme="light"] .role-pill.ghost,
[data-theme="light"] .uc-ghost-saved { color: #47596a; }
[data-theme="light"] .uc-result-title.ghost { color: #47596a; text-shadow: none; }
[data-theme="light"] .uc-result-title.civ { color: var(--success); text-shadow: none; }
[data-theme="light"] .uc-result-title.inf { text-shadow: none; }
[data-theme="light"] .uc-word-card-imp .secret-word-text { color: var(--danger-strong); }
[data-theme="light"] .uc-role-tag.imp,
[data-theme="light"] .uc-imp-label { color: var(--danger-strong); }
/* Schnellschuss/Würfelspiele: Texte AUF dem Filz + Danger-Ink im Light */
[data-theme="light"] .ssk-seat-nm,
[data-theme="light"] .ssk-seat-cnt,
[data-theme="light"] .ssk-pile-cap { color: var(--text-invert); }
/* Seat-ring markers sit on the felt too, which stays dark in both themes — the raw
   --accent-light/next-red only clear 3:1 (WCAG 1.4.11) against the darker felt gradient
   used in dark mode; brightened variants for the lighter light-theme felt stops. */
[data-theme="light"] .ssk-seat.active .ssk-seat-head {
    box-shadow: 0 0 0 1px #79d2e0, 0 0 16px rgba(79,196,214,.5); }
[data-theme="light"] .ssk-seat.next .ssk-seat-head {
    border-color: #ffb09c; box-shadow: 0 0 0 1px #ffb09c, 0 0 10px rgba(255,176,156,.5); }
[data-theme="light"] .rsm-timer.danger,
[data-theme="light"] .mjg-timer.danger,
[data-theme="light"] .bt-timer.danger,
[data-theme="light"] .ssk-timer.danger { color: var(--danger-strong); }
[data-theme="light"] .ssk-dlg,
[data-theme="light"] .ssk-draw-dlg { background: linear-gradient(135deg, var(--modal-grad-a), var(--modal-grad-b)); border-color: var(--accent-ink); }
[data-theme="light"] .ssk-dlg-hd,
[data-theme="light"] .ssk-draw-dlg h2 { color: var(--accent-ink); }
[data-theme="light"] .ssk-draw-dlg.danger { border-color: var(--danger-strong); }
[data-theme="light"] .ssk-draw-dlg.danger h2 { color: var(--danger-strong); }
[data-theme="light"] .bt-dlg { background: linear-gradient(135deg, var(--modal-grad-a), var(--modal-grad-b)); border-color: var(--accent-ink); }
/* Der Header-Hintergrund ist ein halbtransparenter Blau-Akzent — über dem hellen
   Dialog-Diagonalverlauf wird das ein kalter blau-grauer Streifen, der sich mit dem
   warmen Pergament-Body beißt. Im Light stattdessen ein DECKENDER warmer Gold-Ton. */
[data-theme="light"] .bt-dlg-hd { color: var(--accent-ink);
    background: color-mix(in srgb, var(--gold) 14%, var(--modal-grad-a));
    border-bottom-color: color-mix(in srgb, var(--gold) 32%, transparent); }
/* Gefüllte Phasen-Chips: der helle Gradient-Endpunkt (purer Akzent) trug die
   Raw-Parchment-Schrift im Light nur mit ~2,9-3,9:1 — beide Stops abdunkeln. */
[data-theme="light"] .durak-chip.phase,
[data-theme="light"] .see-chip.phase {
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 60%, #000), color-mix(in srgb, var(--accent) 70%, #000));
}
/* Antwort-Buchstaben (A/B/C/D): helle Plakette statt Gold-Alpha-Kreis. */
[data-theme="light"] .mq-option-letter {
  background: color-mix(in srgb, var(--gold) 18%, #fffdf7);
  border-color: color-mix(in srgb, var(--gold) 65%, #3a2a16);
}
[data-theme="light"] .break-stage-score-pts { color: #6b3f0a; }   /* Gold-Heading fiel auf der Grün-Pill auf 4,0 */
/* Mahjong-Brettmulde: warmes Sand statt dunkles Holz */
[data-theme="light"] .mjg-stage::before {
    background: radial-gradient(140% 120% at 50% 18%, #e9d6ab 0%, #ddc490 45%, #cfae74 82%);
    box-shadow: inset 0 0 3px rgba(255,255,255,.4), inset 0 0 44px rgba(120,80,20,.25), 0 8px 24px rgba(80,60,30,.25); }
[data-theme="light"] .ro-flourish { text-shadow: none; }
[data-theme="light"] .hangman-placeholder { text-shadow: none; }
[data-theme="light"] .hangman-placeholder.solved { text-shadow: none; }
[data-theme="light"] .break-stage-hero-word { text-shadow: none; }
[data-theme="light"] .mq-question-mark { text-shadow: 0 0 24px var(--accent-light), 0 0 48px var(--accent), 0 2px 12px rgba(0,0,0,0.7); }

/* ── WCAG 2.5.8: 24px-Mindestzielgrößen für kompakte Controls (app-weit).
   min-height wirkt nur auf die zu kleinen Instanzen; normal große Inputs
   (30px+) bleiben unverändert. ── */
input[type="text"], input[type="search"], input[type="email"],
input[type="password"], input[type="number"], select { min-height: 24px; }
.icon-select-btn { min-height: 24px; }

/* ── Bühnen-Lobby: Scheinwerfer-Rigg + Requisiten (SS-0312-Deko) ──────────
   Rigg/Lampen aus festen Holz-Tönen (Artwork, beide Themes), Lichtkegel in
   der Mode-Akzentfarbe. Die "Lichtprobe" schwenkt die Kegel EINMAL beim Laden
   ein (< 5 s → kein WCAG-2.2.2-Pausensteuerelement nötig); bei
   prefers-reduced-motion stehen sie sofort. Requisite liegt HINTER der
   Truppe (z-Index) und tritt auf vollen Bühnen zurück (.stage-prop-crowded). */
.stage-rig {
  position: absolute; top: 34px; left: 62px; right: 62px; height: 8px; z-index: 4;
  background: linear-gradient(180deg, #4a3620, #2e2214); border-radius: 3px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .35);
}
.stage-lamp { position: absolute; top: 38px; width: 22px; height: 27px; z-index: 4; transform: translateX(-50%) rotate(var(--lamp-tilt, 0deg)); }
.stage-lamp::before { content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 5px; height: 8px; background: #2e2214; }
.stage-lamp::after {
  content: ""; position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
  width: 20px; height: 19px; border-radius: 5px 5px 8px 8px;
  background: linear-gradient(180deg, #4a3620, #241708);
  box-shadow: inset 0 -4px 6px color-mix(in srgb, var(--accent) 70%, transparent);
}
.stage-lamp-l { left: 24%; --lamp-tilt: 14deg; }
.stage-lamp-c { left: 50%; }
.stage-lamp-r { left: 76%; --lamp-tilt: -14deg; }
.stage-beam {
  position: absolute; top: 58px; width: 160px; height: 72%; z-index: 1;
  margin-left: -80px; pointer-events: none; transform-origin: 50% 0;
  clip-path: polygon(45% 0, 55% 0, 100% 100%, 0 100%);
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 22%, transparent), transparent 78%);
}
.stage-beam-l { left: 24%; transform: rotate(14deg);  animation: stage-beam-l 3.8s ease-in-out 1; }
.stage-beam-c { left: 50%; transform: rotate(0deg);   animation: stage-beam-c 3.8s ease-in-out .25s 1 backwards; }
.stage-beam-r { left: 76%; transform: rotate(-14deg); animation: stage-beam-r 3.8s ease-in-out .5s 1 backwards; }
@keyframes stage-beam-l { 0% { transform: rotate(-14deg); opacity: 0; } 18% { opacity: 1; } 62% { transform: rotate(19deg); } 100% { transform: rotate(14deg); } }
@keyframes stage-beam-c { 0% { transform: rotate(-9deg); opacity: 0; } 18% { opacity: 1; } 62% { transform: rotate(7deg); } 100% { transform: rotate(0deg); } }
@keyframes stage-beam-r { 0% { transform: rotate(14deg); opacity: 0; } 18% { opacity: 1; } 62% { transform: rotate(-19deg); } 100% { transform: rotate(-14deg); } }
@media (prefers-reduced-motion: reduce) {
  .stage-beam-l, .stage-beam-c, .stage-beam-r { animation: none; }
}
.stage-prop { position: absolute; bottom: 72px; left: 21%; transform: translateX(-50%); z-index: 2; text-align: center; transition: opacity .3s; }
.stage-prop-crowded { opacity: .35; }
.sprop-base { width: 120px; height: 10px; margin: 6px auto 0; border-radius: 4px; background: linear-gradient(180deg, #8a6a3c, #6b4a23); box-shadow: 0 4px 8px rgba(0, 0, 0, .25); }
.sprop-gallows { position: relative; width: 110px; height: 96px; margin: 0 auto; }
.sprop-gallows .post { position: absolute; left: 14px; bottom: 0; width: 9px; height: 96px; background: #6b4a23; border-radius: 2px; }
.sprop-gallows .arm  { position: absolute; left: 14px; top: 0; width: 72px; height: 8px; background: #6b4a23; border-radius: 2px; }
.sprop-gallows .rope { position: absolute; left: 76px; top: 8px; width: 3px; height: 22px; background: #8a6a3c; }
.sprop-gallows .tile { position: absolute; left: 60px; top: 30px; width: 34px; height: 34px; background: #f7ecd4; border: 2px solid #8a6a3c; border-radius: 4px; font-family: 'Rye', cursive; font-size: 20px; display: flex; align-items: center; justify-content: center; color: #3a2a16; }
.sprop-mic { position: relative; width: 80px; height: 110px; margin: 0 auto; }
.sprop-mic .head { position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 30px; height: 30px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #6b5838, #2e2214); }
.sprop-mic .pole { position: absolute; top: 28px; left: 50%; transform: translateX(-50%); width: 5px; height: 70px; background: #4a3620; }
.sprop-mic .foot { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 56px; height: 8px; border-radius: 50%; background: #2e2214; }
.sprop-mic .note { position: absolute; font-size: 22px; color: #3a2a16; opacity: .8; }
.lobby-stage-theatre .sprop-mic .note { color: color-mix(in srgb, var(--accent) 40%, #3a2a16); }
.sprop-mic .note-l { left: -26px; top: 8px; }
.sprop-mic .note-r { right: -24px; top: -8px; }
.sprop-podium { position: relative; width: 96px; height: 104px; margin: 0 auto; }
.sprop-podium .top  { position: absolute; top: 0; left: 0; right: 0; height: 14px; background: #6b4a23; border-radius: 4px; }
.sprop-podium .body { position: absolute; top: 12px; left: 8px; right: 8px; bottom: 0; border-radius: 0 0 6px 6px; background: linear-gradient(180deg, #8a6a3c, #6b4a23); display: flex; align-items: center; justify-content: center; font-family: 'Rye', cursive; font-size: 40px; color: #f7ecd4; }
.sprop-tabu { position: relative; width: 92px; height: 96px; margin: 0 auto; background: #f7ecd4; border: 2px solid #8a6a3c; border-radius: 6px; padding-top: 10px; transform: rotate(-3deg); }
.sprop-tabu .word   { display: block; font-family: 'Rye', cursive; font-size: 15px; letter-spacing: .06em; color: #3a2a16; }
.sprop-tabu .strike { display: block; width: 70%; height: 3px; margin: 4px auto 6px; background: #a3324a; transform: rotate(-4deg); }
.sprop-tabu .shh    { font-size: 26px; }
@media (max-width: 640px) {
  .stage-prop { transform: translateX(-50%) scale(.75); transform-origin: bottom center; }
  .stage-rig { left: 50px; right: 50px; }
}

/* Memory: status pill + progress line center themselves (fit-content pill above,
   text-align:center progress) — no longer pinned to a computed board width. */
.memory-progress { text-align: center; }

/* Light: Lobby-Panels (Header-Karte, Spieler-Panel, Fusszeile) waren mit dem
   globalen Karten-Verlauf fast reinweiss ("blendet") — im Lobby-Kontext auf
   warmes Pergament abgesenkt. Aussenseiten behalten den Standard-Verlauf. */
[data-theme="light"] .screen-lobby .card,
[data-theme="light"] .screen-game .card {
  --card-grad-a: rgba(246, 235, 210, .95);
  --card-grad-b: rgba(236, 220, 184, .97);
}

/* Light: sattes Filzgrün -> Texte AUF dem Filz hell (wie im Dark), sonst kein AA. */
[data-theme="light"] .lobby-table .seat-name,
[data-theme="light"] .lobby-table .seat-you,
[data-theme="light"] .lobby-table .seat-avatar-empty,
[data-theme="light"] .lobby-table .seat-ghost .seat-name { color: var(--text-invert); }

/* Light: Kopfzeilen-Karte der Lobby als dunkleres Sand-Band — hebt die
   Kopfzeile vom Pergament-Rest ab (Betreiber-Feedback: zu wenig Hierarchie). */
/* §3-Ausweichregel: Schnellschuss-Türkis ist der hellste Akzent und fällt im
   Light unter die Kanten-Schwelle (Ring 2,7:1) — abgedunkeltes Light-Paar.
   Erster und bisher einziger Modus mit explizitem Light-Override. */
[data-theme="light"] .mode-schnellschuss {
  --accent: #157585;
  --accent-light: #3b9fb2;
}
[data-theme="light"] .screen-lobby .lobby-header-card,
[data-theme="light"] .screen-game .lobby-header-card {
  /* Band traegt den Spiel-Akzent als Schleier (wie im Dark der dunkle Grund
     die Akzente traegt) — Basis bleibt das Sand-Band. Seit SS-0312 Etappe 2
     gilt dasselbe Band auch auf den Spiel-Seiten (gleiche Header-Komponente). */
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 14%, #e3cda0),
    color-mix(in srgb, var(--accent) 20%, #d9bf8c));
  /* Rahmen bleibt Saloon-Gold-Braun — Panel-Raender tragen NIE den Mode-Akzent
     (etablierte Regel, s. .card-actions-bar). Gleiches Token wie die Panels
     darunter, damit Ober- und Unterrahmen exakt denselben Ton haben. */
  border-color: var(--border-soft);
}
[data-theme="light"] :is(.screen-lobby, .screen-game) .lobby-header-card .uh-name,
[data-theme="light"] :is(.screen-lobby, .screen-game) .lobby-header-card .help-icon-btn,
[data-theme="light"] :is(.screen-lobby, .screen-game) .lobby-header-card .uh-help { color: var(--text-main); }
/* Light: Icon-Chip als HELLE Akzent-Marke (Pastell-Grund + tiefer Akzent-Glyph)
   statt des importierten Dunkel-Chips — jedes Spiel behält seinen Akzent. */
/* Light: Verlauf/Chat/Copy-Buttons tragen Emoji-Glyphen (eigenfarbig, beige!)
   — auf dem Sand-Band unsichtbar. Gleiche Plakette wie der Icon-Chip. */
[data-theme="light"] :is(.screen-lobby, .screen-game) .lobby-uh .uh-icon-btn {
  background: color-mix(in srgb, var(--accent) 12%, #fffdf7);
  border-color: color-mix(in srgb, var(--accent) 65%, #3a2a16);
}
[data-theme="light"] :is(.screen-lobby, .screen-game) .lobby-uh .uh-gear {
  background: color-mix(in srgb, var(--accent) 12%, #fffdf7);
  border-color: color-mix(in srgb, var(--accent) 65%, #3a2a16);
}
[data-theme="light"] :is(.screen-lobby, .screen-game) .lobby-uh .uh-ico {
  /* Heller als das Sand-Band (Plakette) + dunkle Akzent-Kontur — dunkle
     Akzente (Aubergine, Sienna) verschwimmen sonst mit dem Band-Ton. */
  background: color-mix(in srgb, var(--accent) 20%, #fffdf7);
  color: color-mix(in srgb, var(--accent) 55%, #3a2a16);
  border-color: color-mix(in srgb, var(--accent) 65%, #3a2a16);
}
