/* Kartenspiel — Tisch in Stadionform (gerade Seiten, runde Enden).
   Quer- und Hochformat sind dieselbe Anordnung: die Sitze liegen parametrisch
   auf einer Ellipse in Prozent des Tischkastens. Kippt der Kasten, wandert die
   Ellipse mit — nichts wird gedreht, also steht keine Zahl auf dem Kopf. */

/* Cinzel — elegante, gravierte Versalien (OFL), lokal gebuendelt (laeuft auch im
   NUI/offline). Variable-Font: eine Datei je Subset deckt alle Gewichte ab. */
@font-face {
  font-family: 'Cinzel'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('assets/fonts/cinzel-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cinzel'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('assets/fonts/cinzel-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --room: #0B0B0E;
  --panel: #15151A;
  --edge: #26262F;
  --ink: #E8E8EE;
  --ink-2: #9A9AA8;
  --ink-3: #62626F;

  --felt-hi: #2E7D5E;
  --felt-a: #1D5A44;
  --felt-b: #0F3227;

  --ok: #5CC48D;
  --danger: #FF5A3C;

  /* Akzentfarbe des UI (aktiver Spieler, Board-Timer, Chips, Buttons, Highlights).
     Standard = Gruen; pro Biom (body[data-biome=...]) auf die Crew-Farbe umgestellt,
     damit sich das UI an das Tischdesign anpasst. Alpha-Varianten vorgebacken
     (kein color-mix -> laeuft auch im aelteren NUI-CEF). */
  --accent:         #7FE0AC;   /* Vollton */
  --accent-strong:  #7FE0AC88; /* kraeftige Raender */
  --accent-glow:    #7FE0AC66; /* Schein/Glow */
  --accent-ring:    #7FE0AC44; /* feine Ringe */
  --accent-wash:    #7FE0AC1A; /* sehr dezente Fuellung */
  --accent-btn:     #1E6E4E;   /* satter Akzent-Knopf (Passen, Legen, Banner) */
  --accent-btn-hi:  #268A61;   /* dessen Hover */

  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  --sans: ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* Elegant-antike Display-Schrift fuer Titel/Banner/Feld-Hinweise. */
  --display: 'Cinzel', "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;

  /* min(...vmin, ...vh) deckelt die Groesse zusaetzlich an der Fensterhoehe.
     So passt alles auch in ein flaches Browserfenster (ohne F11-Vollbild). */
  --card-table: clamp(30px, min(6.2vmin, 8.5vh), 62px);
  --card-mine: clamp(44px, min(8.8vmin, 15vh), 88px);
  --card-trick: clamp(38px, min(7.6vmin, 12vh), 78px);
  --card-back: clamp(32px, min(5.8vmin, 9vh), 58px);
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }

body {
  background: var(--room); color: var(--ink);
  font-family: var(--sans); font-size: 15px;
  -webkit-font-smoothing: antialiased;
  overflow: hidden; overscroll-behavior: none;
  touch-action: manipulation;
}
/* Vollbild-Tisch: das Biom-Bild (unten, body[data-biome]) fuellt den Schirm.
   Ohne Biom bleibt eine dunkle Flaeche — die alte table.jpg gibt es nicht mehr. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2;
  background: #0a1a12 center / cover no-repeat;
}
/* Kanten leicht abdunkeln, damit die UI darueber lesbar bleibt. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(125% 95% at 50% 42%, transparent 40%, #000000a6 100%);
}
/* Biom-Tische: der Vollbild-Hintergrund wechselt mit dem gewaehlten Biom
   (data-biome am body). Ohne data-biome bleibt es beim Standard-Tisch (oben). */
body[data-biome="lion"]::before  { background-image: url('assets/table/lion.webp'); }
body[data-biome="shark"]::before { background-image: url('assets/table/shark.webp'); }
body[data-biome="snake"]::before { background-image: url('assets/table/snake.webp'); }
body[data-biome="hawk"]::before  { background-image: url('assets/table/hawk.webp'); }
body[data-biome="vulcano"]::before { background-image: url('assets/table/vulcano.webp'); }
body[data-biome="casino"]::before { background-image: url('assets/table/casino.webp'); }

/* UI-Akzent je Biom = Crew-Farbe (an das Tischdesign angepasst). */
body[data-biome="lion"] {   /* Savanne — warmes Loewen-Orange */
  --accent: #F5852B; --accent-strong: #F5852B88; --accent-glow: #F5852B66;
  --accent-ring: #F5852B44; --accent-wash: #F5852B1A;
  --accent-btn: #8A4A12; --accent-btn-hi: #A5591A;
}
body[data-biome="shark"] {  /* Korallenriff — Hai-Cyan */
  --accent: #34C6E0; --accent-strong: #34C6E088; --accent-glow: #34C6E066;
  --accent-ring: #34C6E044; --accent-wash: #34C6E01A;
  --accent-btn: #14606E; --accent-btn-hi: #1C7C8E;
}
body[data-biome="snake"] {  /* Dschungel — Schlangen-Gruen */
  --accent: #46D173; --accent-strong: #46D17388; --accent-glow: #46D17366;
  --accent-ring: #46D17344; --accent-wash: #46D1731A;
  --accent-btn: #1E6E3E; --accent-btn-hi: #268A52;
}
body[data-biome="hawk"] {   /* Berggipfel — Falken-Gold */
  --accent: #F4C64A; --accent-strong: #F4C64A88; --accent-glow: #F4C64A66;
  --accent-ring: #F4C64A44; --accent-wash: #F4C64A1A;
  --accent-btn: #7C6516; --accent-btn-hi: #98801E;
}
body[data-biome="vulcano"] {  /* Vulkan (alle Crews) — gluehendes Lava-Rot */
  --accent: #E5381F; --accent-strong: #E5381F88; --accent-glow: #E5381F66;
  --accent-ring: #E5381F44; --accent-wash: #E5381F1A;
  --accent-btn: #7A1E10; --accent-btn-hi: #952518;
}
body[data-biome="casino"] {  /* Casino (alle Crews) — Schwarz/Weiß, edles Silber */
  --accent: #E9E9EE; --accent-strong: #E9E9EE88; --accent-glow: #E9E9EE66;
  --accent-ring: #E9E9EE44; --accent-wash: #E9E9EE14;
  --accent-btn: #26262B; --accent-btn-hi: #37373E;
}
body.is-dragging { cursor: grabbing; user-select: none; }

/* Lokales PvP: Host/Beitreten-Knoepfe unter dem Startknopf. */
.hub-pvp { display: flex; gap: 10px; justify-content: center; margin-top: 12px; }
.hub-pvp .chip { min-width: 140px; }

/* PvP-Statusfenster (Warte auf Gegner / Verbinde …). */
.pvp-status {
  position: fixed; inset: 0; z-index: 120; pointer-events: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center;
  background: radial-gradient(60% 60% at 50% 45%, rgba(0, 0, 0, .72), rgba(0, 0, 0, .88));
  backdrop-filter: none;
}
.pvp-status[hidden] { display: none; }
.pvp-status-title { font-size: 26px; font-weight: 800; color: var(--accent); letter-spacing: .01em; }
.pvp-status-sub { font-size: 15px; color: #cfe9df; max-width: 34ch; }
/* Warteraum-Liste: eine Zeile je Sitz. */
.lobby-list { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 2px; min-width: 260px; }
.lobby-row {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 8px 14px; border-radius: 10px; font-size: 15px;
  border: 1px solid #ffffff1a; background: #ffffff0d; color: #dfeee8;
}
.lobby-row.on { border-color: var(--accent-ring); background: var(--accent-wash); }
.lobby-row.off { opacity: .5; }
.lobby-row.me b { color: var(--accent); }
.lobby-row.team-a { border-left: 3px solid #34C6E0; }   /* Team A = Cyan */
.lobby-row.team-b { border-left: 3px solid #EF4A2A; }   /* Team B = Rot */
.lobby-row b { font-weight: 700; }
.lobby-row span { font-size: 13px; color: #b9d2c8; }
.pvp-status .banner-btn { margin-top: 6px; pointer-events: auto; }   /* klickbar trotz overlay pointer-events:none */

/* In den Voreinstellungen "Standard"/"Zufall" sind Modus & Feld nicht frei waehlbar -> die Kacheln
   bleiben SICHTBAR, werden aber gedimmt + gesperrt und tragen ein Badge (Standard/Zufall). Nur
   "Custom" gibt sie frei. (Frueher display:none; jetzt als 4-Kachel-Layout immer sichtbar.) */
body.preset-standard .cfg-tile.custom-only,
body.preset-random .cfg-tile.custom-only { opacity: .4; pointer-events: none; filter: grayscale(.35); }
body.preset-standard .cfg-tile.custom-only .cfg-lock,
body.preset-random .cfg-tile.custom-only .cfg-lock { display: block; }
body.preset-standard .cfg-tile.custom-only .cfg-lock::after { content: 'Standard'; }
body.preset-random .cfg-tile.custom-only .cfg-lock::after { content: 'Zufall'; }

#app { height: 100%; position: relative; }

/* Spotlight fuer den aktiven Spieler: ein weicher Lichtfleck, der von der Mitte
   in Richtung des Spielers wandert. z-index 0 -> liegt UNTER dem Spielfeld und
   ALLEN Karten (die stecken in .room, z 1) und hellt per screen-Blend nur den
   Filz darunter auf. Radial-Verlauf + Blur = maximal weiche Raender, keine
   harten Kanten. Bewusst sehr dezent. */
/* Registrierter Winkel — nur so laesst sich die Drehung der Sektor-Maske weich
   per transition interpolieren (unregistrierte Custom Properties koennen das nicht). */
@property --dir {
  syntax: '<angle>';
  inherits: false;
  initial-value: 180deg;
}
.spotlight {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  mix-blend-mode: screen; opacity: 0;
  --sa: 31deg;   /* voll ausgeleuchteter Kern (halbe Breite) — per JS je Spielerzahl */
  --fa: 67deg;   /* bis hierhin weich auf 0 (breiter Falloff federt die Kante -> wenig Blur noetig) */
  /* Hell in der Bildmitte, faellt nach aussen ab. */
  background: radial-gradient(circle at 50% 50%,
    rgba(198, 240, 216, 0.20) 0%,
    rgba(190, 234, 210, 0.10) 40%,
    transparent 80%);
  /* Sektor-Keil per conic-gradient; der Winkel --dir wird animiert. */
  -webkit-mask-image: conic-gradient(from var(--dir),
    #000 0deg, #000 var(--sa), transparent var(--fa),
    transparent calc(360deg - var(--fa)), #000 calc(360deg - var(--sa)), #000 360deg);
  mask-image: conic-gradient(from var(--dir),
    #000 0deg, #000 var(--sa), transparent var(--fa),
    transparent calc(360deg - var(--fa)), #000 calc(360deg - var(--sa)), #000 360deg);
  /* Kleiner Blur = massiv weniger GPU-Last: ein blur() re-rasterisiert pro Frame ueber einen
     viewport-grossen Puffer; die Kosten skalieren ~quadratisch mit dem Radius (12px ≈ 1/6 von 30px).
     Das war die #1-Dauerlast auf Firefox' gemeinsamem Compositor. Die weiche Kante liefert jetzt
     der breite Masken-Falloff (--sa..--fa), nicht der Blur. */
  filter: blur(12px);
  transition: --dir .55s cubic-bezier(.4, 0, .2, 1), opacity .4s ease;
}
/* Beim Austeilen aus (display:none nimmt die geblurrte Ebene ganz aus dem Compositing). */
body.dealing:not(.rolling) .spotlight { display: none; }

/* Spotlight-Helligkeit je Biom feinjustiert (Kern-Deckkraft; mittlerer Ring = halb). */
body[data-biome="lion"] .spotlight {
  background: radial-gradient(circle at 50% 50%,
    rgba(198, 240, 216, 0.30) 0%, rgba(190, 234, 210, 0.15) 40%, transparent 80%);
}
body[data-biome="hawk"] .spotlight {
  background: radial-gradient(circle at 50% 50%,
    rgba(198, 240, 216, 0.25) 0%, rgba(190, 234, 210, 0.125) 40%, transparent 80%);
}
/* Casino: neutrales Weiss statt des gruenlichen Standards, passend zum Schwarz/Weiss-Look. */
body[data-biome="casino"] .spotlight {
  background: radial-gradient(circle at 50% 50%,
    rgba(240, 240, 244, 0.24) 0%, rgba(230, 230, 236, 0.12) 40%, transparent 80%);
}

/* ---------- Menue links / Stats rechts ---------- */

/* Beide sind schmale Overlays an den Bildschirmraendern; der Spielbereich
   bleibt das ganze Fenster. Leicht durchscheinend, damit der Dschungel-Tisch
   an den Raendern nicht komplett verdeckt wird. */
.menu, .stats {
  position: fixed; top: 14px; z-index: 30;
  display: flex; flex-direction: column; gap: 12px;
  padding: 15px 14px; width: 188px;
  background: linear-gradient(165deg, #14241cF4, #0a130dF8);
  border: 1px solid #ffffff1a;
  box-shadow: 0 20px 44px -20px #000D, inset 0 1px 0 #ffffff12, 0 0 0 1px #00000055;
  backdrop-filter: none;
}
.menu { left: 0; border-left: 0; border-radius: 0 16px 16px 0; }
.stats { right: 0; border-right: 0; border-radius: 16px 0 0 16px; }

/* Spieltitel 4CREWS — goldene 4 als Blickfang, CREWS in Cinzel. */
.game-title {
  display: flex; align-items: baseline; gap: 3px;
  font-family: var(--display); font-weight: 700; letter-spacing: .05em;
  line-height: 1;
}
.game-title .four {
  font-size: 34px; color: #FFD24B;
  text-shadow: 0 2px 6px #000, 0 0 18px #FFD24B55;
}
.game-title .word {
  font-size: 25px; color: #EAF7EF; text-shadow: 0 1px 4px #000;
}
/* 4CREWS-Logo (ersetzt den Text-Titel). Menue = klein/links, Hub = gross/zentriert (s. .hub-brand).
   Weisses Leuchten hinter dem Logo: mehrere drop-shadows folgen der transparenten Logo-Form (Bloom);
   ein dezenter dunkler Schatten grundet es auf hellen Hintergruenden. */
.brand-logo {
  display: block; width: 148px; height: auto; margin-bottom: 3px;
  user-select: none; -webkit-user-drag: none;
  filter: drop-shadow(0 0 5px rgba(255, 255, 255, .3)) drop-shadow(0 0 13px rgba(255, 255, 255, .16)) drop-shadow(0 2px 5px #0009);
}
/* Studio-Vermerk „by maxedPLAY" — Sans, damit die maxed/PLAY-Schreibweise bleibt.
   „by" gedaempft, „maxedPLAY" komplett weiss. */
.menu-brand {
  font-family: var(--sans); font-weight: 500; font-size: 10.5px;
  letter-spacing: .02em; color: var(--ink-3); margin: 2px 0 4px;
}
.menu-brand span { color: #fff; font-weight: 600; }
.menu-group { display: flex; flex-direction: column; gap: 5px; }
.menu-row { display: flex; gap: 6px; }
.menu-row .chip { flex: 1; text-align: center; }
.menu .chip.wide { margin-left: 0; }

.label {
  font-family: var(--display); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: #9db8a8;
}

/* --- Spieler-Stats (rechts, per JS gefuellt) --- */
.stats-title { margin-bottom: 2px; }
/* Modus- und Spielfeld-Panel (oben im Stats-Panel) — je eine eigene Karte im gleichen Look wie
   die Spielerzeilen: neutrale Flaeche/Rahmen, Wert in Cinzel (wie der Spielername), Eyebrow-Label. */
.stats-info {
  display: flex; flex-direction: column; gap: 3px;
  padding: 9px 11px 9px 13px; border-radius: 10px;
  border: 1px solid #ffffff10; background: #ffffff0a;
}
.stats-info-eyebrow { font-size: 9.5px; }
.stats-info-value {
  font-family: var(--display); font-size: 14px; font-weight: 600; letter-spacing: .04em; color: var(--ink);
}
.stat-row {
  display: grid; grid-template-columns: 1fr auto; gap: 3px 8px;
  align-items: center;
  padding: 9px 11px 9px 13px; border-radius: 10px;
  border: 1px solid #ffffff10;
  background: #ffffff0a;
  transition: background .2s, box-shadow .2s;
}
.stat-row.active {
  border-color: var(--accent-strong);
  background: var(--accent-wash);
  /* linker Akzent-Balken + Glow, damit sofort klar ist, wer dran ist */
  box-shadow: inset 3px 0 0 var(--accent), 0 0 0 1px var(--accent-ring), 0 0 16px -4px var(--accent);
}
.stat-row.passed { opacity: .55; }
.stat-row.done { opacity: .4; }
.stat-name {
  grid-column: 1 / 2; font-family: var(--display); font-size: 14px; font-weight: 600;
  letter-spacing: .04em; color: var(--ink);
}
.stat-badge {
  grid-column: 2 / 3; justify-self: end;
  font-family: var(--mono); font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-3);
}
.stat-row.active .stat-badge { color: var(--accent); }
.stat-nums {
  grid-column: 1 / 3;
  display: flex; gap: 12px;
  font-family: var(--mono); font-size: 10.5px; color: var(--ink-2);
}
.stat-nums b { color: var(--ink); font-weight: 600; }

button {
  font-family: var(--mono); font-size: 12px; letter-spacing: .04em;
  color: var(--ink-2); background: #ffffff08;
  border: 1px solid #ffffff1f; border-radius: 8px;
  padding: 8px 12px; cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .12s, box-shadow .15s;
}
/* Neutraler, sauberer Hover (kein Akzent-Wash — der wirkte auf manchen Biomen matschig).
   Niedrige Spezifitaet (0,2,1), damit Akzent-Buttons ihn mit :not(:disabled) schlagen. */
button:hover:not(:disabled) {
  color: var(--ink); background: #ffffff16; border-color: #ffffff4a;
}
button:disabled { opacity: .4; cursor: default; }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Menue-Chips: elegante Versalien, groesser. */
.chip {
  font-family: var(--display); font-size: 13px; font-weight: 600; letter-spacing: .05em;
  color: #cfe6da;
}
.chip[aria-pressed="true"] {
  color: #06120c; background: var(--accent); border-color: var(--accent); font-weight: 700;
  box-shadow: 0 0 16px -4px var(--accent-glow), inset 0 1px 0 #ffffff44;
}
/* "Neues Match" — prominenter gruener Knopf. */
.chip.wide {
  margin-left: 0; color: #EAFFF4; background: var(--accent-btn); border-color: var(--accent);
  font-weight: 700; padding: 10px 12px;
  box-shadow: 0 8px 20px -10px #000, inset 0 1px 0 #ffffff22;
}
.chip.wide:hover:not(:disabled) { background: var(--accent-btn-hi); border-color: var(--accent); color: #fff; }
/* Chip-Hover: dezenter Lift statt Farbwechsel — nicht bei gedrueckten oder wide-Chips. */
.chip:not(.wide):hover:not(:disabled):not([aria-pressed="true"]) {
  transform: translateY(-1px);
  background: #ffffff1e; border-color: #ffffff5e;
  box-shadow: 0 7px 16px -9px #000c;
}
/* Gedrueckter Chip behaelt beim Hovern seine Akzentfarbe (kein Neutral-Wash). */
.chip[aria-pressed="true"]:hover:not(:disabled) {
  background: var(--accent); border-color: var(--accent); color: #06120c; filter: brightness(1.06);
}

/* ---------- Raum ---------- */

/* Der Raum fuellt das ganze Fenster. Dadurch liegt die Filzmitte exakt auf der
   Bildschirmmitte — und die Sitze (±% um die Mitte) werden symmetrisch, genau
   wie das mittig fixierte Kartenfeld. */
.room {
  position: fixed; inset: 0; z-index: 1;
}

/* Der Wrapper ist der Container — der Filz misst sich an ihm.
   Ein Element kann seine eigenen Container-Einheiten nicht benutzen. */
.table-wrap {
  width: 100%; height: 100%;
  display: grid; place-items: center; position: relative;
  container-type: size;
}

/* Der Filz ist jetzt nur noch der (transparente) Koordinatenraum, auf dem die
   Sitze auf ihrer Ellipse liegen — das Tischbild kommt vom Vollbild-Hintergrund.
   Etwas schmaler als die volle Breite, damit die Sitze zum Bild-Oval passen. */
.felt {
  position: relative;
  width: min(100%, 100cqh * 1.9);
  height: 100%;
}
.felt.shake { animation: shake .34s cubic-bezier(.36,.07,.19,.97); }
@keyframes shake {
  0%, 100% { transform: translate(0, 0); }
  15% { transform: translate(-7px, 3px); }
  32% { transform: translate(6px, -4px); }
  50% { transform: translate(-5px, -2px); }
  68% { transform: translate(4px, 3px); }
  85% { transform: translate(-2px, -1px); }
}

/* ---------- Mitte ---------- */

/* Das Kartenfeld sitzt fest in der Bildschirmmitte — deckungsgleich mit dem
   Mandala des Hintergrundbilds, nicht nur mittig im Filzbereich. */
.center {
  position: fixed; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  z-index: 5;
}
/* Die Ablage: ein eigener Rahmen mit vier festen Feldern, damit die Karten
   sichtbar in Fächern landen statt frei im Filz zu schweben. */
.board {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 11px 13px 13px; border-radius: 16px;
  /* Neutrales Dunkel + Biom-Toenung von oben (orientiert sich am Tisch, bleibt aber
     dunkel genug fuer lesbare Karten). Weicher Einzel-Verlauf mit Zentrum ueber dem
     Feld -> die Toenung laeuft sanft nach unten aus, kein harter Uebergang. */
  background:
    radial-gradient(150% 135% at 50% -30%, var(--accent-glow), transparent 72%),
    radial-gradient(120% 120% at 50% 0%, #0f0f11ec, #050507F0);
  /* Rahmenlinie kommt jetzt als SVG (#board-frame), damit sie deckungsgleich mit
     der Timer-Linie ist und ueberall gleich dick. */
  box-shadow:
    inset 0 1px 0 #ffffff1f,
    inset 0 0 24px -6px #000,
    0 18px 40px -18px #000E,
    0 0 0 1px #00000055;
}
/* Glow in der Groesse des Kartenfelds x1,5 — deckt das ganze Feld ab, nicht nur
   einen kreisrunden Ausschnitt. inset:-25% = 1,5-fache Kantenlaenge in beide
   Richtungen; die Ellipse passt sich der breiten Feldform an. */
.board::before {
  content: ""; position: absolute; inset: -25%;
  border-radius: 40px; z-index: -1; pointer-events: none;
  mix-blend-mode: screen;
  /* Glow in der Tischfarbe (Biom-Akzent) statt festem Gruen. */
  background: radial-gradient(ellipse 60% 60% at 50% 50%, var(--accent), var(--accent-glow) 46%, transparent 76%);
}
/* Beschriftung sitzt absolut ueber dem Feld — so verschiebt sie die vertikale
   Mitte des Feldes nicht. */
.trick-label {
  position: absolute; bottom: calc(100% + 10px); left: 0; right: 0;
  font-family: var(--display); font-size: 14px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: #EAF7EF; text-align: center; pointer-events: none;
  padding: 5px 14px; border-radius: 10px;
  background: #0a1712c0; border: 1px solid #ffffff1a;
  text-shadow: 0 1px 4px #000, 0 0 12px #0007;
  box-shadow: 0 6px 18px -10px #000, inset 0 1px 0 #ffffff12;
}
.slots { display: flex; gap: 6px; align-items: center; pointer-events: none; }
.slot {
  position: relative;
  width: var(--card-trick); aspect-ratio: 5 / 7;
  border-radius: 7px; display: grid; place-items: center;
}
.slot.free { border: 1px dashed #ffffff26; background: #ffffff08; }
.slot .card-slot { width: 100%; }

/* Bereitgelegte (noch nicht bestaetigte) Karte: sieht aus wie eine normal
   gelegte Karte — volle Groesse, kein Sonderrahmen —, liegt nur ueber der
   darunterliegenden. Klick nimmt sie zurueck. */
.slot .staged-overlay {
  position: absolute; inset: 0; z-index: 2;
  cursor: pointer; transition: transform .12s;
}
.slot .staged-overlay:hover { transform: scale(1.04); }

/* Ablagefeld — hierher werden Karten gezogen. */
/* Nie klickbar — die Zone wird nur geometrisch abgefragt. Sonst deckt sie
   die Stapel zu, die von unten in die Tischmitte ragen. */
.dropzone {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 46%; height: 62%; border-radius: 16px;
  border: 2px dashed transparent; z-index: 3; pointer-events: none;
  transition: border-color .15s, background .15s;
}
body.is-dragging .dropzone { border-color: #ffffff33; background: #ffffff0A; }
body.is-dragging .dropzone.hot { border-color: var(--accent); background: var(--accent-wash); }

/* Aktionsleiste unter dem Legefeld: immer alle drei Knoepfe (Legen · Zurück · Passen)
   gleich breit nebeneinander. Gesamtbreite = Feldbreite (100 % von .center-controls,
   das genauso breit ist wie das Feld) -> die drei Buttons ragen nie ueber das Feld hinaus. */
.staging-actions { display: flex; gap: 8px; width: 100%; }
/* Basis = "Zurück": neutraler, dunkler Sekundaerknopf, auf jedem Biom gut sichtbar. */
.staging-actions button {
  flex: 1;
  background: #0e1016e0; border-color: #ffffff52; color: var(--ink);
  font-size: 12px; letter-spacing: .06em; padding: 8px 10px; border-radius: 7px;
}
.staging-actions button:hover:not(:disabled) { background: #1a1e26ec; border-color: #ffffff7a; }
/* "Legen" + "Passen" = satte Akzent-Knoepfe (faerben sich mit dem Tisch). */
.staging-actions button.go, .staging-actions button.pass {
  background: var(--accent-btn); border-color: var(--accent); color: #EAFFF4; font-weight: 700;
}
.staging-actions button.go:hover:not(:disabled),
.staging-actions button.pass:hover:not(:disabled) {
  background: var(--accent-btn-hi); border-color: var(--accent); color: #EAFFF4;
}
/* Nicht moeglich = klar ausgegraut (volle Deckkraft, damit lesbar). */
.staging-actions button:disabled {
  background: #23252c; border-color: #3a3d47; color: var(--ink-3); opacity: 1; cursor: default;
}

/* Passen-Schloss: liegen Karten bereit, ist Passen zweistufig gesichert.
   locked = neutral/gesperrt (1. Klick entriegelt), armed = akzent + Puls (2. Klick passt). */
.staging-actions button.pass.locked {
  background: #23252c; border-color: #4a4d57; color: var(--ink-2); font-weight: 600;
}
.staging-actions button.pass.locked:hover:not(:disabled) {
  background: #2c2f38; border-color: #6b6e79; color: var(--ink);
}
.staging-actions button.pass.armed {
  background: var(--accent-btn); border-color: var(--accent); color: #fff;
  animation: pass-armed-pulse 1s ease-in-out infinite;
}
@keyframes pass-armed-pulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--accent-ring), 0 0 12px -4px var(--accent); }
  50%      { box-shadow: 0 0 0 3px var(--accent-strong), 0 0 20px -2px var(--accent); }
}

/* Gezeitenwechsel: gegnerische Oberkarten sind Zieh-Quellen (Akzentring), eigene
   Oberkarten leuchten beim Ziehen als Ablageziel. */
.card-slot.swap-source { cursor: grab; pointer-events: auto; }
.card-slot.swap-source .card { box-shadow: 0 0 0 2px var(--accent-ring), 0 5px 11px -4px #000c; }
.card-slot.swap-source:hover .card { box-shadow: 0 0 0 2px var(--accent), 0 0 16px -2px var(--accent-glow); }
.card-slot.swap-drop .card { box-shadow: 0 0 0 3px var(--accent), 0 0 22px -2px var(--accent), 0 5px 11px -4px #000c !important; }

.swap-hint {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .03em; color: var(--accent);
  text-align: center; text-shadow: 0 1px 3px #000; opacity: .85;
}

/* Tausch-Flug: Akzent-Funkenschweif + Gezeiten-Welle. */
.swap-spark {
  position: fixed; z-index: 90; pointer-events: none; border-radius: 50%;
  background: radial-gradient(circle, #fff, var(--accent) 55%, transparent 75%);
  box-shadow: 0 0 8px 2px var(--accent-glow);
  mix-blend-mode: screen; will-change: transform, opacity;
}
.swap-ripple {
  position: fixed; z-index: 89; pointer-events: none; border-radius: 50%;
  border: 2px solid var(--accent);
  box-shadow: 0 0 20px -4px var(--accent-glow), inset 0 0 16px -4px var(--accent-glow);
  mix-blend-mode: screen; will-change: transform, opacity;
}
.staging-why {
  font-family: var(--mono); font-size: 10px; color: #FFB4A2;
  text-shadow: 0 1px 3px #000A; max-width: 30ch; text-align: center;
}

/* Kontext + Passen-Knopf sitzen absolut unter dem Feld — halten die vertikale
   Mitte des Feldes frei, damit Feld und Stapel wirklich auf 50/25/75 % liegen. */
.center-controls {
  position: absolute; top: calc(100% + 10px); left: 0; right: 0;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  gap: 6px; min-height: 30px;
}
.center-controls .hint {
  align-self: stretch; text-align: center;
  font-family: var(--display); font-size: 15px; font-weight: 600;
  color: #EAF7EF; letter-spacing: .07em;
  text-shadow: 0 1px 4px #000, 0 0 12px #0007;
  padding: 6px 14px; border-radius: 10px;
  background: #0a1712c0; border: 1px solid #ffffff1a;
  box-shadow: 0 6px 18px -10px #000, inset 0 1px 0 #ffffff12;
}

/* Taeuschung: 3-Knopf-Leiste (Bluffen · Höher · Niedriger) an der Stelle der
   Werte-Anzeige, gebaut wie die untere Legen/Zurück/Passen-Leiste. */
/* Sitzt absolut GENAU an der Stelle der Werte-Leiste (ueber dem Feld, nicht drin).
   z-index hoch, damit die Knoepfe ueber Sitzen/Feld liegen und klickbar sind. */
.bluff-bar { position: absolute; bottom: calc(100% + 10px); left: 0; right: 0; z-index: 20; pointer-events: auto; }
.bluff-bar[hidden] { display: none; }
.bluff-actions { margin: 0; }
/* Plus/Minus schmal (nur Symbol), damit alle vier Knoepfe nebeneinander passen. */
.bluff-actions .step { flex: 0 0 40px; padding: 8px 0; font-size: 16px; }
/* "Bluffen" als aktiver Umschalter: gedrueckt wirkende Akzent-Taste. */
.staging-actions button.go.on {
  filter: brightness(1.12);
  box-shadow: inset 0 2px 7px #0007, 0 0 15px -4px var(--accent-glow);
}
.staging-actions button.go.challenge { letter-spacing: .06em; }
/* Ist die Leiste durch die Bluff-Knoepfe ersetzt, verschwindet die Werte-Zeile. */
.trick-label.replaced { display: none; }

/* Eine gebluffte Karte: die Zahl ist nur behauptet -> Fragezeichen direkt dahinter,
   gleiche Schriftgroesse wie die Zahl (sitzt perfekt hinter ihr). */
.card.bluffed .idx.tl::after {
  content: '?'; font-size: 1em; margin-left: .22em; letter-spacing: normal;
}
/* Behaupteter Wert (weiss) auf der Rueckseite lesbar halten. */
.card.back .idx { text-shadow: 0 1px 2px #000a, 0 0 3px #0009; }

/* Aufdecken beim Anzweifeln: echte Karten ueber dem Feld + Verdikt-Banner. */
.reveal-card { position: fixed; z-index: 60; aspect-ratio: 5 / 7; pointer-events: none; }
.reveal-card .card-slot { width: 100%; }
.reveal-card.lie .card { box-shadow: 0 0 0 3px #EF4A2A, 0 0 22px -3px #EF4A2A, 0 8px 22px -6px #000; }
.reveal-card.honest .card { box-shadow: 0 0 0 3px #46D173, 0 0 22px -3px #46D173, 0 8px 22px -6px #000; }
.reveal-verdict {
  position: fixed; left: 50%; top: 40%; transform: translate(-50%, -50%); z-index: 61; pointer-events: none;
  font-family: var(--display); font-weight: 800; font-size: 30px; letter-spacing: .04em; white-space: nowrap;
  padding: 12px 26px; border-radius: 14px; color: #fff;
  background: #0a1712ee; border: 1px solid #ffffff2a;
  text-shadow: 0 2px 8px #000; box-shadow: 0 14px 40px -14px #000;
}
.reveal-verdict.lie { color: #FFD9CE; border-color: #EF4A2A; box-shadow: 0 0 34px -6px #EF4A2A, 0 14px 40px -14px #000; }
.reveal-verdict.honest { color: #DFF7EA; border-color: #46D173; box-shadow: 0 0 34px -6px #46D173, 0 14px 40px -14px #000; }
.pass-btn {
  font-family: var(--mono); font-size: 12px; letter-spacing: .06em;
  color: #EAFFF4; background: var(--accent-btn); border: 1px solid var(--accent);
  border-radius: 7px; padding: 8px 20px; cursor: pointer;
  width: 146px;   /* gleich gross wie ein einzelner Legen/Zurueck-Button */
  box-shadow: 0 6px 18px -8px #000, inset 0 1px 0 #ffffff22;
}
/* button.pass-btn — mit Element-Selektor, damit der Akzent-Hover den generischen
   Neutral-Hover schlaegt (gleiche Spezifitaet, spaeter in der Quelle -> gewinnt). */
button.pass-btn:hover:not(:disabled) { background: var(--accent-btn-hi); border-color: var(--accent); color: #EAFFF4; }
.pass-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- Sitze ---------- */

/* Die STAPEL sind am Ankerpunkt zentriert (25 % / 75 %), damit beide Seiten
   symmetrisch zur Mitte liegen. Der Faecher haengt absolut nach AUSSEN und
   verschiebt die Stapel dadurch nicht mehr. */
.seat {
  position: absolute; z-index: 3; transform: translate(-50%, -50%);
}
/* Sitz-Panels: flankieren die Handkarten JEDES Sitzes — links Avatar UEBER Name, rechts Kartenanzahl UEBER
   Symbolen (vertikal gestapelt). Look wie die Balken ueber/unter dem Plazierfeld: halbtransparent dunkel.
   Bei Gegnern sitzen sie am opp-hand, bei mir im .my-hand-row (siehe unten). */
.seat-panel {
  display: inline-flex; flex-direction: column; align-items: center; gap: 3px; flex: none;
  padding: 6px 8px; border-radius: 10px; white-space: nowrap; pointer-events: none;
  font-family: var(--display); font-weight: 700; letter-spacing: .06em; color: #EAF7EF;
  background: #0a1712c0; border: 1px solid #ffffff1a; border-radius: 10px;
  box-shadow: 0 6px 18px -10px #000, inset 0 1px 0 #ffffff12;
  text-shadow: 0 0 3px rgba(255, 255, 255, .22), 0 1px 2px rgba(255, 255, 255, .14);
}
.seat-panel .sp-name { font-size: clamp(11px, 1.7vmin, 15px); max-width: 24vmin; overflow: hidden; text-overflow: ellipsis; }
/* Am Desktop zeigt das rechte Panel die Kartenzahl -> die Namens-Kopie dort ausblenden. */
.seat-panel.right .sp-name { display: none; }
.seat-panel .hand-num { font-family: var(--mono); font-size: clamp(19px, 3.1vmin, 28px); font-weight: 800; line-height: 1; color: #EAF6F0; padding: 0; text-shadow: 0 1px 3px #000C; }
.seat-panel .hand-label { font-family: var(--display); font-size: clamp(10px, 1.5vmin, 13px); font-weight: 600; letter-spacing: .06em; color: #cfe6da; }
.seat-panel.active .hand-label { color: #eafff4; }
.seat-icons { font-size: 13px; }
.seat-panel .seat-icons { filter: drop-shadow(0 0 2px rgba(255, 255, 255, .3)); }
/* Am Zug: das aktive Sitz-Panel wechselt in die (gedaempfte) Tischfarbe, dezenter Glow. */
.seat-panel.active {
  background: var(--accent-btn); border-color: var(--accent); color: #fff;
  box-shadow: 0 0 12px -6px var(--accent-glow), 0 6px 16px -10px #000, inset 0 1px 0 #ffffff22;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .75), 0 0 4px rgba(0, 0, 0, .5);
}
.seat-panel.active .hand-num { color: #fff; }
.seat-panel.active .seat-icons { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .75)); }
.seat-panel.dim { opacity: .5; }
/* display:inline-flex (oben) wuerde sonst das [hidden]-Attribut aushebeln -> leeres Panel sichtbar. */
.seat-panel[hidden] { display: none; }
/* Verdeckte Gegnerhand — eigenes Element, entkoppelt vom Stapel, auf ganze
   Pixel gesetzt (Faecher in JS). */
/* opp-hand: der Faecher (.fan, strukturell unveraendert -> Animationen haengen an .opp-hand .fan .card-slot)
   bleibt das einzige IN-FLOW-Kind und damit exakt bei sx zentriert = direkt ueber dem Stapel. Die beiden
   Panels flankieren ihn ABSOLUT (links/rechts), ohne seine Mitte zu verschieben. */
.opp-hand {
  position: absolute; z-index: 3; transform: translate(-50%, -50%);
  display: flex; align-items: center;
}
.opp-hand .seat-panel { position: absolute; top: 50%; transform: translateY(-50%); }
.opp-hand .seat-panel.left  { right: 100%; margin-right: clamp(6px, 1.4vmin, 12px); }
.opp-hand .seat-panel.right { left: 100%;  margin-left: clamp(6px, 1.4vmin, 12px); }
/* Partner-Hand (2v2) liegt offen — dezenter freundlicher Schein, damit klar ist,
   dass diese Karten fuer dich lesbar sind. */
.opp-hand.teammate .fan { filter: drop-shadow(0 0 7px rgba(127, 224, 172, .4)); }
.opp-hand.teammate .hand-num { color: #BFF5D2; }
/* Gegner-Handkarten werfen denselben Schatten wie die eigenen — sie liegen ja auch
   gefaechert uebereinander und sehen damit raeumlicher/schoener aus. */
.opp-hand .card { box-shadow: -5px 4px 11px -4px rgba(0, 0, 0, 0.85), -2px 2px 4px -2px rgba(0, 0, 0, 0.7); }

/* Avatar-Scheibe = Sitz-Token (Tier-Emoji) in der Sitzfarbe. --seat-col/--seat-bg werden in JS gesetzt. */
/* Zentrierung EXAKT wie der funktionierende Avatar-Picker (.avatar-opt): feste Hoehe (keine aspect-ratio),
   flex-Zentrierung, line-height:1, Emoji als reiner Text (kein Span/Transform). */
.avatar {
  width: clamp(26px, 4vmin, 40px); height: clamp(26px, 4vmin, 40px); border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center; line-height: 1;
  font-size: clamp(15px, 2.3vmin, 22px);
  background: var(--seat-bg, #22222b);
  border: 2px solid var(--seat-col, #50505F);
  box-shadow: 0 4px 10px -4px #000C, inset 0 1px 0 #ffffff20;
}
.seat-panel.active .avatar { box-shadow: 0 0 0 3px var(--accent-ring), 0 4px 10px -4px #000C, inset 0 1px 0 #ffffff20; }
/* Emoji als GRAFIK (Noto-SVG): fest anteilig zur Slot-Groesse, vom Flex-Container exakt zentriert.
   Quadratische SVG mit zentriertem Motiv -> in JEDEM Panel identisch mittig, keine Font-Metrik. */
.av-img { width: 76%; height: 76%; object-fit: contain; display: block; pointer-events: none; }
/* Text-Fallback, falls eine Grafik (noch) fehlt. */
.av-emoji { display: block; line-height: 1; }

/* Eigene Hand mit flankierenden Panels: [Panel links] [my-hand] [Panel rechts]. */
.my-hand-row {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(8px, 2vmin, 22px);
}

/* Handkarten: bei allen Spielern ALLE Karten als Rueckseite, plus Anzahl. */
.hand-backs { display: flex; align-items: center; gap: 5px; }
/* Der Faecher wird in JS auf ganze Pixel gesetzt (absolute Positionen). */
.fan { flex: none; }
.hand-num {
  font-family: var(--mono); font-size: clamp(9px, 1.5vmin, 12px); font-weight: 700;
  color: #EAF6F0; text-shadow: 0 1px 3px #000C; padding-left: 3px;
}

/* Immer eine Reihe quer, an jedem Platz gleich — kein 2x2 an den Seiten.
   Ein einziges Feld für alle vier Stapel statt vier Einzelmulden. */
/* Kein Feld mehr um die Stapel — nur ein schlichter Container fuer die vier
   Zellen. Die Karten werfen ihren eigenen Schatten (siehe .stack-cell .card). */
.seat-stacks {
  display: flex; gap: 8px;
}

/* Fertiger Sitz: Medaille + dimmes Name-Panel untereinander zentriert. */
.seat.done { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.seat-panel.finished-tag { padding: 3px 8px; }
.seat-panel.finished-tag .sp-name { font-size: clamp(10px, 1.5vmin, 13px); }

/* Platzierungs-Medaille fuer fertige Spieler an ihrer Kartenposition. */
.seat-medal {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  animation: medal-pop .42s cubic-bezier(.2,.9,.3,1.35);
}
.medal-disc {
  display: grid; place-items: center;
  font-size: clamp(30px, 5vmin, 46px); line-height: 1;
  filter: drop-shadow(0 3px 6px #000B) drop-shadow(0 0 10px var(--mglow, #0000));
}
.medal-label {
  font-family: var(--mono); font-size: clamp(9px, 1.5vmin, 12px); font-weight: 600;
  letter-spacing: .06em; color: var(--mcol, #cfe6da); text-shadow: 0 1px 3px #000A; white-space: nowrap;
}
.place-1 { --mcol: #FFE29A; --mglow: #FFD24B99; }
.place-2 { --mcol: #E7EDF4; --mglow: #C7D0DA66; }
.place-3 { --mcol: #EFC094; --mglow: #CD7F3277; }
/* KEINE medal-shine-Pulsanimation mehr: sie animierte `filter: drop-shadow` endlos (Per-Frame-Repaint)
   und lief genau waehrend der runden-beendenden Flug-Animation mit auf dem Feld -> zusammen auf
   Firefox' geteiltem Compositor der Freeze-Kandidat. Der statische Glow (.medal-disc, drop-shadow)
   bleibt; die 1.-Platz-Medaille bekommt nur einen kraeftigeren, STATISCHEN Gold-Schein. */
.place-1 .medal-disc { filter: drop-shadow(0 3px 6px #000B) drop-shadow(0 0 14px #FFD24Bcc); }
@keyframes medal-pop { from { opacity: 0; transform: scale(.35); } to { opacity: 1; transform: scale(1); } }

/* Ein Stapel ist ein Stapel: die verdeckten Karten liegen sichtbar darunter
   und schauen an der Kante hervor.
   Die Zelle ist absichtlich groesser als eine Karte — die versetzten Lagen
   brauchen Platz, sonst ragen sie in die Handkarten hinein. */
.stack-cell {
  position: relative;
  width: calc(var(--card-table) * 1.18);
  height: calc(var(--card-table) * 1.4 * 1.16);
}
/* Statt eines Feldes werfen die Stapelkarten einen weichen Schatten auf den
   Filz — das wirkt raeumlicher/realistischer. Leere Stapel zeigen dadurch
   nichts an (kein Feld mehr). */
.stack-cell .card-slot .card {
  box-shadow: 0 5px 11px -4px rgba(0, 0, 0, 0.8), 0 2px 4px -2px rgba(0, 0, 0, 0.8);
}

.stack-cell .layer {
  position: absolute; left: 0; top: 0; width: var(--card-table); z-index: 1;
  transform: translate(calc(var(--i) * 7%), calc(var(--i) * 8%));
  filter: brightness(calc(1 - var(--i) * 0.16));
  transition: filter .3s ease;   /* Abdunklung weich ein-/ausblenden (s. body.dealing) */
}
/* Die Lagen-Abdunklung simuliert den Schatten der DRUEBERLIEGENDEN Karte. Waehrend des Austeilens
   soll sie NICHT schon gelten, solange die Karte gerade erst gelandet und noch nicht abgedeckt ist —
   sonst wirkt eine frisch ausgeteilte Stapelkarte dunkler als der (helle) Flug-Klon. Erst wenn das
   Austeilen fertig ist (body.dealing weg), blendet die Abdunklung weich ein. */
body.dealing .stack-cell .layer { filter: brightness(1); }
.stack-cell .top {
  position: absolute; left: 0; top: 0; width: var(--card-table); z-index: 2;
  /* Nur bei MEINEM Stapel ist --i gesetzt (Oberkarte am fixen Platz); Gegner
     ohne --i -> 0 -> keine Verschiebung, bleibt wie bisher. */
  transform: translate(calc(var(--i, 0) * 7%), calc(var(--i, 0) * 8%));
}
.stack-cell .card-slot { width: 100%; }

/* Erdbeben — heftiges, laengeres Rumpeln des ganzen Tisches. */
.felt.quaking-hard { animation: quake-hard .9s cubic-bezier(.36, .07, .19, .97); }
@keyframes quake-hard {
  0%, 100% { transform: translate(0, 0) rotate(0); }
  8%  { transform: translate(-9px, 4px) rotate(-.5deg); }
  18% { transform: translate(8px, -5px) rotate(.4deg); }
  30% { transform: translate(-10px, 3px) rotate(-.3deg); }
  44% { transform: translate(7px, 5px) rotate(.35deg); }
  58% { transform: translate(-6px, -4px) rotate(-.25deg); }
  72% { transform: translate(5px, 3px) rotate(.25deg); }
  86% { transform: translate(-3px, -2px); }
}

/* Waehrend die Ghost-Ruecken in die Mitte wirbeln und neu verteilt werden, sind die
   echten Stapelkarten unsichtbar — sonst laege der neue Zustand schon starr darunter. */
body.quake-mixing .stack-cell .card { opacity: 0; }

/* Erd-/Lava-Broeckchen, die aus der Tischmitte spritzen. */
.quake-dust {
  position: absolute; border-radius: 2px; pointer-events: none; z-index: 30;
  box-shadow: 0 0 6px -1px rgba(0, 0, 0, .5);
}

/* Nach dem Neu-Verteilen flammen die (jetzt neuen) Oberkarten kurz auf. Es werden nur
   Opacity und Filter animiert — die --i-Verschiebung der Stapel bleibt unberuehrt. */
@keyframes quake-emerge {
  0%   { opacity: .12; filter: brightness(2.6) sepia(.7) hue-rotate(-20deg) saturate(2.2); }
  55%  { opacity: 1; }
  100% { opacity: 1; filter: none; }
}
body.quaking .stack-cell .card { animation: quake-emerge .55s ease-out; }
@media (prefers-reduced-motion: reduce) {
  body.quaking .stack-cell .card,
  .felt.quaking-hard { animation: none; }
}

/* ---------- Eigene Hand ---------- */

/* Eigene Hand auf 92 % Hoehe: das ergibt zu den eigenen Stapeln (~76 %) denselben
   Abstand (~16 %, HAND_GAP) wie bei den Gegnern zwischen Hand und Stapel — so sitzt
   auch das "Du"-Banner (Mittelpunkt-Messung) symmetrisch. */
/* NUR die Handkarten-Sektion (<section class="me">). Als BLANKER `.me`-Selektor hat er
   frueher auch andere Elemente mit Klasse „me" getroffen (Sieger-Panel `.champ-panel.me`,
   Runden-Score-Zeile `.banner-score.me`) und ihnen position:fixed + translateY(-50%)
   aufgezwungen -> Panel-Versatz. Deshalb streng auf das <section>-Element gescoped. */
section.me {
  position: fixed; left: 0; right: 0; top: 92%; transform: translateY(-50%); z-index: 12;
  display: flex; flex-direction: column; gap: 7px;
}
.my-hand {
  display: flex; justify-content: center; align-items: flex-end;
  min-height: calc(var(--card-mine) * 1.42); padding: 0 4px;
}
.my-hand .card-slot {
  width: var(--card-mine); margin-right: calc(var(--card-mine) / -3);
}
.my-hand .card-slot:last-child { margin-right: 0; }

/* Anfassbare Karten bewegen sich smooth — Hand UND Stapel gleich. */
.my-hand .card-slot,
.seat.mine .stack-cell .card-slot {
  transition: transform .14s ease;
}

.card-slot.grab { cursor: grab; }
.card-slot.preview { transform: translateY(-12px); }

/* Schlagschatten der Handkarten mit Versatz nach LINKS: die Karten ueberlappen
   (rechte liegt oben), also wirft jede obere Karte ihren Schatten nach unten-links
   auf die dahinterliegende -> sichtbarer 3D-Faecher an JEDER Karte, nicht nur aussen. */
.my-hand .card {
  box-shadow: -5px 4px 11px -4px rgba(0, 0, 0, 0.85), -2px 2px 4px -2px rgba(0, 0, 0, 0.7);
}

/* Blosses Drueberfahren hebt eine spielbare Karte an und holt sie nach vorn.
   Nicht waehrend eines Ziehvorgangs.
   z-index wirkt hier, weil die Handkarten Flex-Items sind (kein position noetig).
   Bei den Stapeln sitzt er auf .top mit position:absolute. */
body:not(.is-dragging) .my-hand .card-slot.grab:hover {
  transform: translateY(-12px);
  z-index: 20;
}
body:not(.is-dragging) .seat.mine .stack-cell .card-slot.grab:hover {
  transform: translateY(-12px);
}

/* In diesem Zug gar nicht legbar: eigene GRAUE Kartengrafik (Bild-Tausch in
   styleOwnCard) statt grayscale()-Filter -> gleichmaessiges Grau ueber alle Crews,
   kein luminanz-bedingtes Abdunkeln von Rot. */
.card-slot.locked { cursor: default; }
/* Passt zur angefangenen Kombination — positiver Hinweis statt Ausgrauen. */
.card-slot.joinable .card { box-shadow: 0 0 0 2px var(--accent-glow), 0 6px 16px -8px #000 !important; }

/* Shift: alle Karten desselben Werts. Gleiche Hoehe wie beim Hover (-12px),
   damit die Karte unter der Maus nicht hoeher steht als ihre Partner. */
.card-slot.same-value { transform: translateY(-12px); z-index: 20; }
.card-slot.same-value .card {
  border-color: #FFFFFF !important;
  box-shadow: 0 0 4cqw -1cqw #FFFFFFAA !important;
}

/* Kopfschütteln: geht nicht. */
.card-slot.nope { animation: nope .46s cubic-bezier(.36,.07,.19,.97); z-index: 20; }
.card-slot.nope .card {
  border-color: #FF5A3C !important;
  box-shadow: 0 0 0 2px #FF5A3C99, 0 0 18px -2px #FF5A3C77 !important;
}
@keyframes nope {
  0%, 100% { transform: translateX(0) rotate(0deg); }
  14% { transform: translateX(-7px) rotate(-4deg); }
  30% { transform: translateX(7px) rotate(4deg); }
  46% { transform: translateX(-6px) rotate(-3deg); }
  62% { transform: translateX(5px) rotate(2deg); }
  80% { transform: translateX(-2px) rotate(-1deg); }
}

/* Mit Shift oder Strg vorgemerkt — wird beim Ziehen mitgenommen. */
.card-slot.marked { transform: translateY(-14px); }
.card-slot.marked .card { box-shadow: 0 0 0 2px var(--accent), 0 10px 22px -8px #000 !important; }


/* ---------- Karten ---------- */

.card-slot { container-type: inline-size; flex: none; }
.card {
  width: 100%; aspect-ratio: 5 / 7; position: relative;
  background: #08080A; display: grid; place-items: center;
  box-sizing: border-box;   /* Rand zaehlt in die Kartenbreite -> pro Seite exakt gleich */
  border-style: solid; border-width: max(1.1px, 2cqw); border-radius: max(5px, 9cqw);
  /* Jede Karte ist ihr eigener Stapelkontext: der z-index des Rahmens gilt nur
     INNERHALB der Karte. Sonst zeichnet der Browser erst alle Bilder und dann
     alle Raender — der Rand von Karte 1 landet dann ueber Karte 2, obwohl die
     obenauf liegt. */
  isolation: isolate;
}
/* Komplettes Kartendesign: das Bild fuellt die innere Flaeche, das PADDING gibt
   ringsum die farbige Kartenflaeche (crew-Farbe bzw. Regenbogen, inline) als
   Rand frei. Zoom-sicher: eine gefuellte Flaeche kann nie wegrunden wie eine
   1px-Linie oder eine Maske. */
.card.full {
  overflow: hidden; padding: 0;
  border-width: 0;   /* kein reservierter Rand -> das Bild fuellt die GANZE Karte */
}
/* Kartenflaeche: Vorderseite als <canvas> (aus ImageBitmap -> nie schwarz), Rueckseite
   als <img>. Beide fuellen die 5:7-Karte randlos. */
.card.full canvas.card-art,
.card.full img {
  width: 100%; height: 100%;
  display: block; pointer-events: none; user-select: none;
  border-radius: inherit;   /* rundet wie die Karte, randlos (Bild geht bis an die Kante) */
}
.card.full img { object-fit: fill; }   /* <img> aufs 5:7-Zielmaß (Quellen sind 5:7) */
/* Farbrand als 2px-Ring OBEN DRAUF auf dem Bild -> er ueberdeckt die aeussersten 2px
   des Motivs (Farbe = border-color der Karte, inline gesetzt). box-sizing: border-box
   -> der Ring sitzt innen an der Kante, auf jeder Seite exakt 2px (symmetrisch). */
.card.full::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-sizing: border-box;
  border: 2px solid; border-color: inherit; border-radius: inherit;
}
/* Rueckseite wird wie eine normale Vollkarte gerendert (gleicher Rand-Mechanismus,
   Gold-Rand, gleiche Ecken-Rundung) — nur ohne Zahlen-Overlay. */
/* Zahl auf gemustertem Grund: kein Kasten, sondern ein satter schwarzer Schein
   dahinter — mehrfach gestapelt, damit die Zahl auf jedem Motiv lesbar bleibt. */
.card .idx.plate {
  text-shadow:
    0 0 1.5cqw #000, 0 0 1.5cqw #000, 0 0 3cqw #000, 0 0 3cqw #000,
    0 0 5cqw #000, 0 0 5cqw #000, 0 0 8cqw #000, 0 0 8cqw #000,
    0 0 12cqw #000, 0 0 12cqw #000, 0 0 18cqw #000, 0 0 24cqw #000;
}
.card .idx.plate.tl { top: 5%; left: 6%; }
.card .idx.plate.br { bottom: 5%; right: 6%; }
/* Roemische Ziffer als geprägtes Emblem — aufrecht, nicht gedreht.
   translateZ(0) legt sie auf eine eigene Compositor-Ebene: waehrend die Karte
   beim Hover hochfaehrt, wird der Text nicht Frame fuer Frame neu gerastert und
   zittert dadurch nicht. */
.card .idx.plate.roman {
  transform: translateZ(0);
  white-space: nowrap;
  font-family: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  font-weight: 600; letter-spacing: .03em;
}
.card .idx {
  position: absolute; font-weight: 700; line-height: .9;
  letter-spacing: -.04em; font-variant-numeric: tabular-nums; user-select: none;
}
.card.empty { background: #ffffff0A; border-color: #ffffff1F; }

/* ---------- Flug, Splitter, Blitz ---------- */

.fly-layer { position: fixed; inset: 0; pointer-events: none; z-index: 90; }
.fly, .shard, .ghost { position: fixed; will-change: transform, opacity; }

/* Erdbeben-Flip: zweiseitige fliegende Karte. Der aeussere .flip3d fliegt, das innere
   Element dreht sich (rotateY). Vorder- und Rueckseite liegen deckungsgleich uebereinander;
   backface-visibility blendet die jeweils abgewandte Seite aus. */
.flip3d { perspective: 900px; z-index: 95; }
.flip3d-inner { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; will-change: transform; }
.flip3d-inner > .flip-face {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  transform-style: flat;   /* die Karte selbst bleibt flach; nur das innere Element dreht in 3D */
}
.flip3d-inner > .flip-face .card { width: 100%; height: 100%; }
.flip3d-inner > .flip-back { transform: rotateY(180deg); }
.ghost { z-index: 95; filter: drop-shadow(0 12px 18px #000A); }
.shard { transform-origin: 50% 50%; }

.flash {
  position: fixed; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, #FFFFFF 0%, #FFD7C2 30%, #FF5A3Cbb 55%, transparent 72%);
  mix-blend-mode: screen;
}

/* Schockwelle beim 12-Sieg: expandierender Ring in der Crew-Farbe. Groesse und
   Position werden in app.js gesetzt; hier nur Aussehen. transform-origin ist die
   Box-Mitte (Default), es wird nur skaliert. */
.shockwave {
  position: fixed; z-index: 88; pointer-events: none;
  border-radius: 50%;
  border: 3px solid var(--wcolor, #fff);
  box-shadow: 0 0 26px 5px var(--wcolor, #fff), inset 0 0 26px 5px var(--wcolor, #fff);
  mix-blend-mode: screen;
  will-change: transform, opacity;
}

/* Stich gewonnen (nicht geschlagen): Karten blitzen golden auf und verpuffen an
   Ort und Stelle in aufsteigende Funken. */
.won-card {
  z-index: 89;
  filter: drop-shadow(0 0 12px #FFD24Bdd) drop-shadow(0 7px 12px #000A);
}
.gold-spark {
  position: fixed; z-index: 89; pointer-events: none; border-radius: 50%;
  background: radial-gradient(circle, #FFF6C0, #FFD24B 60%, #FFB02E00);
  box-shadow: 0 0 8px 2px #FFD24Baa;
  mix-blend-mode: screen; will-change: transform, opacity;
}

/* Stroemung: Funken ziehen einmal um den Tisch, in der neuen Spielrichtung, in
   der Tischfarbe (Akzent). Zeigt sichtbar an, dass die Richtung gekippt ist. */
.flow-streak {
  position: fixed; left: 0; top: 0; z-index: 88; pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(circle, #ffffff, var(--accent) 55%, transparent 75%);
  box-shadow: 0 0 10px 2px var(--accent-glow);
  mix-blend-mode: screen; will-change: transform, opacity;
}

/* ---------- Austeilen ---------- */

.deal-stage { position: fixed; inset: 0; z-index: 92; pointer-events: none; }
.deal-deck { position: fixed; z-index: 1; filter: drop-shadow(0 16px 24px #000B); }
.deal-fly { position: fixed; z-index: 2; will-change: transform, opacity; }
/* KEIN Schlagschatten auf den Austeil-Karten: sonst summieren sich die am Mittelpunkt gestapelten
   „Deck"-Klone zu einem dunklen Schatten-Fleck in der Feldmitte waehrend des Austeilens. */
.deal-fly .card { box-shadow: none; }

/* Austeil-Transform: das ECHTE Board wird beim Austeilen zusammengeklappt und
   faehrt danach wieder auf. box-sizing border-box, damit die per JS gesetzte Breite
   die Aussenbreite ist; KEIN overflow:hidden (sonst wuerde der ::before-Glow
   abgeschnitten) — die zu breiten leeren Slots sind stattdessen per visibility aus. */
.board.deal-collapse { box-sizing: border-box; }
.board.deal-expand { transition: width .5s cubic-bezier(.3, .9, .3, 1); }

/* Kometen-Schweif hinter einer fliegenden Karte: heisser weisser Kern + Glow. */
.deal-trail {
  position: fixed; z-index: 1; pointer-events: none; border-radius: 50%;
  background: radial-gradient(circle, #FFFFFF, #FFE9A8 42%, #FFB02E77 68%, transparent 80%);
  box-shadow: 0 0 8px 2px #FFD24B99;
  mix-blend-mode: screen; will-change: transform, opacity;
}
/* Beim Austeilen bleibt das Board sichtbar (es IST das transformierende Feld) —
   nur Bedienknoepfe und Label werden ausgeblendet, und Klicks gehen nicht ans Feld. */
.center { transition: opacity .25s ease; }
body.dealing .center { pointer-events: none; }
body.dealing .center-controls, body.dealing .trick-label { opacity: 0; }

/* ---------- Protokoll ---------- */

.log {
  position: fixed; right: 0; top: 0; bottom: 0; width: 300px; z-index: 60;
  border-left: 1px solid var(--edge); background: #101014F5;
  padding: 56px 14px 14px; overflow-y: auto;
  font-family: var(--mono); font-size: 11.5px; line-height: 1.65;
  display: flex; flex-direction: column; gap: 2px;
}
.log[hidden] { display: none; }
.log-line { color: var(--ink-2); }
.log-line.me { color: var(--ink); }
.log-line.trick { color: var(--ink-3); border-top: 1px solid var(--edge); margin-top: 5px; padding-top: 5px; }
.log-line.big { color: var(--ok); font-weight: 600; }
.log-line.kill { color: var(--danger); }

/* ---------- Zug-Timer ---------- */

/* Umlaufende Linie im Rand des Plazierfelds — fuellt sich in 30 s einmal rundum
   (pathLength=100 macht die Fuellung groessenunabhaengig). */
/* Rahmen und Timer sind zwei deckungsgleiche SVGs (gleiche Geometrie in JS).
   Der Rahmen ist immer da, der Timer liegt darueber und faerbt ihn beim Fuellen. */
.board-frame, .board-timer {
  position: absolute; top: 0; left: 0;
  pointer-events: none; z-index: 0;
}
.board-frame-path { fill: none; stroke: #ffffff2b; stroke-width: 2; }
.board-timer-path {
  fill: none;
  stroke: var(--accent); stroke-width: 2; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: 100;   /* voll versteckt bis der Timer laeuft */
  filter: drop-shadow(0 0 3px var(--accent-strong));
}
/* Fuellt sich in 30 s einmal rundum und faerbt dabei von Gruen ueber Gelb nach Rot. */
.board.timing .board-timer-path { animation: board-timer-fill 30s linear forwards; }
@keyframes board-timer-fill {
  0%   { stroke-dashoffset: 100; stroke: var(--accent); filter: drop-shadow(0 0 3px var(--accent-strong)); }
  55%  {                         stroke: #F2C94C; filter: drop-shadow(0 0 3px #F2C94C88); }
  100% { stroke-dashoffset: 0;   stroke: #FF5A3C; filter: drop-shadow(0 0 4px #FF5A3Cbb); }
}
/* Austeil-Ring: laeuft in genau 10 s (= Dauer des Kartenausteilens) einmal rundum und wirkt so wie eine
   Austeil-Fortschrittsanzeige — bewusst durchgehend Akzentfarbe (kein Rot-Verlauf, es ist KEIN Zug-Countdown).
   Wird direkt danach vom echten 30-s-Zug-Ring (.timing) abgeloest. */
.board.dealing-ring .board-timer-path { animation: board-timer-deal 10.75s linear forwards; }
@keyframes board-timer-deal {
  0%   { stroke-dashoffset: 100; opacity: 1; }
  93%  { stroke-dashoffset: 0;   opacity: 1; }   /* voll nach ~10 s (= Ende des Austeilens) */
  100% { stroke-dashoffset: 0;   opacity: 0; }   /* danach sanft ausblenden (~0,75 s) */
}
/* Letzte 5 s: die Linie pulsiert. */
.board.timing.urgent .board-timer { animation: board-timer-pulse .7s ease-in-out infinite; }
@keyframes board-timer-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* Countdown im Badge des aktiven Spielers (ich). */
.stat-badge.stat-timer {
  font-size: 13px; font-weight: 700; text-transform: none; letter-spacing: .02em;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.stat-badge.stat-timer.urgent { color: #FF7A5C; animation: stat-timer-pulse .9s ease-in-out infinite; }
@keyframes stat-timer-pulse { 0%,100% { opacity: 1; } 50% { opacity: .55; } }
.stat-afk {
  grid-column: 1 / 3; justify-self: stretch; margin-top: 4px;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .05em;
  color: #EAFFF4; background: var(--accent-btn); border: 1px solid var(--accent);
  border-radius: 7px; padding: 5px 10px; cursor: pointer;
}
.stat-afk:hover:not(:disabled) { background: var(--accent-btn-hi); border-color: var(--accent); }
.stat-afk:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- Match-Banner ---------- */

/* z-index unter Menue/Stats (30), damit man am Match-Ende direkt Spieler/Modus
   umstellen kann; das zentrierte Banner ueberschneidet die Seitenpanels nicht. */
.banner {
  position: fixed; inset: 0; z-index: 25;
  display: grid; place-items: center; padding: 20px;
  background: #05060899;
}
.banner[hidden] { display: none; }
.banner-card {
  min-width: 260px; max-width: 90vw;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: 22px 26px; border-radius: 16px; text-align: center;
  background: radial-gradient(120% 120% at 50% 0%, #12261d, #0a120d);
  border: 1px solid #ffffff26;
  box-shadow: 0 30px 70px -20px #000, inset 0 1px 0 #ffffff1f;
  animation: banner-in .28s cubic-bezier(.2,.8,.3,1);
}
@keyframes banner-in {
  from { opacity: 0; transform: translateY(10px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
.banner-card.champion {
  border-color: var(--accent-strong);
  box-shadow: 0 30px 70px -20px #000, 0 0 46px -10px var(--accent-glow), inset 0 1px 0 #ffffff1f;
}
.banner-title {
  font-family: var(--display); font-size: 21px; font-weight: 700; letter-spacing: .06em; color: var(--ink);
}
.banner-card.champion .banner-title { color: #9dffd6; }
.banner-sub {
  font-family: var(--display); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.banner-scores { display: flex; flex-direction: column; gap: 4px; width: 100%; margin: 4px 0; }
.banner-score {
  display: flex; justify-content: space-between; gap: 20px;
  padding: 6px 12px; border-radius: 7px;
  background: #ffffff08; border: 1px solid transparent;
  font-family: var(--mono); font-size: 13px; color: var(--ink-2);
}
.banner-score.me { color: var(--ink); }
.banner-score b { color: var(--ink); font-size: 15px; }
.banner-score.win { border-color: var(--accent-strong); background: var(--accent-wash); color: #DFF7EA; }
.banner-btn {
  margin-top: 4px;
  font-family: var(--mono); font-size: 13px; letter-spacing: .05em;
  color: #EAFFF4; background: var(--accent-btn); border: 1px solid var(--accent);
  border-radius: 8px; padding: 9px 22px; cursor: pointer;
  box-shadow: 0 6px 18px -8px #000, inset 0 1px 0 #ffffff22;
}
.banner-btn:hover:not(:disabled) { background: var(--accent-btn-hi); border-color: var(--accent); color: #EAFFF4; }
.banner-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Match-Ende-Buttons (Nochmal / Revanche / Zum Menü) nebeneinander in einer Reihe (statt gestapelt). */
.banner-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; align-items: center; margin-top: 4px; }
.banner-actions .banner-btn { margin-top: 0; }

/* „Uebernehmen"-Knopf: ein Bot spielt meinen Sitz (ich war >30 s weg). Klick loest ihn ab. */
.reclaim-btn {
  position: fixed; left: 50%; bottom: 92px; transform: translateX(-50%); z-index: 130;
  font-family: var(--mono); font-size: 14px; letter-spacing: .04em; color: #FFE7C2;
  background: #7a3a1cdd; border: 1px solid #E5842f; border-radius: 10px;
  padding: 11px 20px; cursor: pointer; box-shadow: 0 8px 22px -8px #000;
  animation: reclaim-pulse 1.4s ease-in-out infinite;
}
.reclaim-btn:hover { background: #9c4a20; border-color: #ff9a3c; color: #fff; }
.reclaim-btn[hidden] { display: none; }
@keyframes reclaim-pulse { 0%, 100% { box-shadow: 0 8px 22px -8px #000, 0 0 0 0 #ff9a3c66; } 50% { box-shadow: 0 8px 22px -8px #000, 0 0 0 6px #ff9a3c00; } }

/* Rundenwechsel-Countdown (ersetzt den „Naechste Runde"-Button): Zahl + schrumpfender Balken. */
.banner-countdown {
  margin-top: 8px; display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.bc-label {
  font-family: var(--mono); font-size: 13px; letter-spacing: .05em; color: #cfe9df;
}
.bc-label b { color: var(--accent); font-variant-numeric: tabular-nums; }
.bc-bar {
  width: 220px; max-width: 60vw; height: 5px; border-radius: 999px;
  background: #ffffff1a; overflow: hidden;
}
.bc-bar i {
  display: block; height: 100%; width: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-strong));
}

/* Revanche-Button (1v1-Herausforderung). „hot" = der/die Gleichstand-Gegner, hervorgehoben. */
.banner-btn.revanche { color: #FFE7C2; background: #7a3a1c66; border-color: #E5842f; }
.banner-btn.revanche:hover:not(:disabled) { background: #9c4a20; border-color: #ff9a3c; color: #fff; }
.banner-btn.revanche.hot {
  color: #fff; background: linear-gradient(180deg, #E5842f, #c85a12);
  border-color: #ffb266; box-shadow: 0 0 16px -2px #E5842faa, inset 0 1px 0 #ffffff33;
  animation: revanche-pulse 1.4s ease-in-out infinite;
}
@keyframes revanche-pulse { 0%,100% { box-shadow: 0 0 12px -2px #E5842f88, inset 0 1px 0 #ffffff33; } 50% { box-shadow: 0 0 22px 1px #E5842fcc, inset 0 1px 0 #ffffff44; } }
@media (prefers-reduced-motion: reduce) { .banner-btn.revanche.hot { animation: none; } }

/* ---------- Runden-/Match-Effekte ---------- */

/* Konfetti-Teilchen: liegen in der fly-layer (z 90) ueber allem. */
.confetti {
  position: fixed; top: 0; left: 0;
  pointer-events: none; will-change: transform, opacity;
  box-shadow: 0 0 6px currentColor;
}

.banner-card { position: relative; z-index: 2; }

/* Match gewonnen: goldener Rahmen, pulsierendes Leuchten, schimmernder Titel. */
.banner-card.champ-win {
  border-color: #FFE81Faa;
  box-shadow: 0 30px 70px -20px #000, 0 0 60px -6px #FFE81F70, inset 0 1px 0 #ffffff2a;
  animation: banner-in .28s cubic-bezier(.2,.8,.3,1), champ-glow 1.8s ease-in-out .3s infinite;
}
.banner-card.champ-win .banner-title {
  font-size: 20px;
  color: #FFF3B0;
  background: linear-gradient(90deg, #FFE81F, #FFFFFF, #FFC24B, #FFE81F);
  background-size: 250% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: champ-shimmer 2.4s linear infinite;
}
@keyframes champ-glow {
  0%,100% { box-shadow: 0 30px 70px -20px #000, 0 0 50px -8px #FFE81F60, inset 0 1px 0 #ffffff2a; }
  50%     { box-shadow: 0 30px 70px -20px #000, 0 0 82px -4px #FFE81F95, inset 0 1px 0 #ffffff2a; }
}
@keyframes champ-shimmer { to { background-position: 250% 0; } }

/* Match verloren: dunkelroter Rahmen und Karte. */
.banner-card.champ-lose {
  border-color: #FF5A3C88;
  box-shadow: 0 30px 70px -20px #000, 0 0 46px -10px #FF5A3C55, inset 0 1px 0 #ffffff14;
  background: radial-gradient(120% 120% at 50% 0%, #26120f, #120a09);
}
.banner-card.champ-lose .banner-title { color: #ffb3a3; }

/* Runde gewonnen/verloren: dezente Faerbung des Rahmens. */
.banner-card.round-win { border-color: var(--accent-glow); }
.banner-card.round-win .banner-title { color: #b6ffe0; }
.banner-card.round-lose { border-color: #ffffff1a; }
.banner-card.round-lose .banner-title { color: var(--ink-2); }

/* ---------- Sieger-/Zwischenscreen (Panel-Bühne) ---------- */
/* Beim Panel-Screen ist das Spielfeld + Seiten-Panel + SPOTLIGHT ausgeblendet — der Biom-
   Hintergrund (body::before) bleibt gedimmt als Kulisse, davor nur die Buehne.
   WICHTIG: `display:none` statt `visibility:hidden` — sonst bleiben Tisch, alle Karten-Layer UND
   die `.spotlight` (filter:blur(30px), sehr GPU-schwer) WEITER komposited und liegen zusammen mit
   den einfahrenden Panels auf Firefox' GEMEINSAMEM Compositor -> Grau-Screen-Freeze ueber alle Tabs.
   `display:none` nimmt diese Layer komplett raus. */
body.champ-screen .room,
body.champ-screen .stats,
body.champ-screen .spotlight { display: none; }

/* Sieger: KEIN grosses umschliessendes Panel — die Karte wird unsichtbar, damit die
   einzelnen Spieler-Panels frei nebeneinander stehen. (Titel/Belohnung/Buttons bringen
   ihren eigenen Hintergrund mit.) */
.banner-card.champion,
.banner-card.champion.champ-win,
.banner-card.champion.champ-lose {
  min-width: 0; max-width: 96vw; gap: 16px;
  background: none; border: none; box-shadow: none; padding: 6px;
  animation: banner-in .28s cubic-bezier(.2,.8,.3,1);
}
.champ-title {
  font-family: var(--display); font-weight: 800; font-size: 30px; letter-spacing: .1em;
  color: #FFE81F; text-shadow: 0 2px 10px #000, 0 0 22px #FFD24B55;
}
.banner-card.champ-lose .champ-title { color: #d3d8d5; text-shadow: 0 2px 10px #000; }

/* EINE flache Reihe gleich grosser, KOMPLETTER Panels (ein Panel je Spieler, auch Bots):
   erst alle Gewinner (Gold + Krone), ein VS-Trenner, dann alle Verlierer (neutral).
   align-items: stretch -> alle Panels exakt gleich hoch; Inhalt oben (justify-content:
   flex-start) -> Avatare/Zeilen liegen auf einer Linie. Skaliert 1v1..4er und 2v2 gleich. */
/* GRID: align-items:start richtet ALLE Panel-Oberkanten exakt aus — unabhaengig von Inhalts-Hoehe
   (Flex align-start hatte in Firefox einen Versatz erzeugt). `repeat(auto-fit, minmax(...))` legt
   auf breiten Schirmen alle Panels in EINE Zeile und BRICHT auf schmalen Schirmen echt UM (statt sie
   off-screen zu clippen wie das alte grid-auto-flow:column). Die Karte ist auf max-width:96vw gedeckelt
   -> gibt dem auto-fit die noetige definite Breite zum Umbrechen. */
.champ-panels {
  --panel-w: 186px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, var(--panel-w)));
  justify-content: center; align-items: start;
  gap: 14px; width: 100%; max-width: 96vw;
}

/* Jedes Panel ist eine eigene, freistehende Kachel — ALLE identisch (Breite + feste Hoehe),
   Inhalt oben -> alle Avatare/Zeilen liegen exakt auf einer Linie. Der Gewinner unterscheidet
   sich NUR durch goldenen Tag/Punkte + (falls es ich bin) den Cyan-Rahmen. */
.champ-panel {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 6px;
  width: 100%; min-height: 224px; padding: 20px 16px 18px; border-radius: 18px;   /* fuellt die Grid-Spalte (minmax 150..186) */
  background: radial-gradient(120% 120% at 50% 0%, #12261d, #0a120d);
  border: 1px solid #ffffff20;
  box-shadow: 0 18px 40px -22px #000, inset 0 1px 0 #ffffff14;
  animation: champ-pop .4s ease-out backwards;   /* nur Opacity -> kein Transform, der haengenbleibt */
}
@keyframes champ-pop { from { opacity: 0; } to { opacity: 1; } }
/* Dein Panel wird nur ueber den Namen („Du" + Akzent-Punkt) markiert — kein Rahmen. */

.pc-ava {
  width: 86px; height: 86px; border-radius: 20px; display: grid; place-items: center;
  background: radial-gradient(120% 120% at 50% 0%, #1b2822, #0b120e);
  border: 2px solid var(--pc);
  box-shadow: 0 0 22px -8px var(--pc), 0 10px 22px -12px #000, inset 0 1px 0 #ffffff22;
}
.pc-ava span { font-size: 46px; line-height: 1; }

.pc-name { font-family: var(--display); font-size: 17px; letter-spacing: .04em; color: var(--ink); }
.champ-panel.winner .pc-name,
.champ-panel.leader .pc-name { color: #FFF3B0; }
.champ-panel.me .pc-name::after { content: ' •'; color: var(--accent); }

.cp-tag {
  font-family: var(--display); font-size: 10px; font-weight: 700; letter-spacing: .1em;
  color: var(--ink-3); min-height: 13px;
}
.champ-panel.winner .cp-tag,
.champ-panel.leader .cp-tag { color: #FFD24B; }

/* Runden-Zwischenscreen-Titel: neutral „ZWISCHENSTAND", kleiner als das grosse „SIEGER". */
.interstitial-title { font-size: 18px !important; letter-spacing: .12em; }

.cp-div { width: 64%; height: 1px; background: #ffffff1e; margin: 5px 0 4px; }

.cp-pts { display: flex; align-items: baseline; gap: 5px; font-variant-numeric: tabular-nums; }
.cp-pts b { font-family: var(--mono); font-size: 31px; line-height: 1; color: var(--ink); }
.champ-panel.winner .cp-pts b,
.champ-panel.leader .cp-pts b { color: #FFE81F; }
.cp-pts span { font-family: var(--display); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }

/* Match-Stats: untereinander als Liste — Symbol · Name · Zahl (Zahl rechtsbuendig). */
.cp-stats {
  display: flex; flex-direction: column; gap: 5px; width: 100%;
  margin-top: 12px;
}
.cp-stat {
  display: grid; grid-template-columns: 16px 1fr auto; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 12.5px;
}
.cp-stat-ico { text-align: center; font-size: 12px; }
.cp-stat-lbl { color: var(--ink-3); letter-spacing: .01em; }
.cp-stat-num { color: var(--ink); font-variant-numeric: tabular-nums; }
.champ-panel.winner .cp-stat-num,
.champ-panel.leader .cp-stat-num { color: #FFE8B0; }

/* Comeback-Badge: nur wenn verdient. „episch" (>=5 Karten Rueckstand) in Orange. */
.cp-comeback {
  margin-top: 6px;
  font-family: var(--display); font-size: 9px; font-weight: 700; letter-spacing: .08em;
  color: #FFD24B; background: #FFD24B1a; border: 1px solid #FFD24B55;
  border-radius: 6px; padding: 3px 8px;
}
.cp-comeback.epic { color: #FF9A4C; background: #FF8A3C1f; border-color: #FF8A3C99; }

/* Revanche haengt am Panel-BODEN (margin-top:auto), damit die oberen Zeilen ausgerichtet bleiben. */
.cp-revanche {
  margin-top: auto; width: 100%;
  font-family: var(--mono); font-size: 11px; letter-spacing: .03em;
  color: #FFE7C2; background: #7a3a1c66; border: 1px solid #E5842f;
  border-radius: 8px; padding: 6px 8px; cursor: pointer;
}
.cp-revanche:hover { background: #9c4a20; border-color: #ff9a3c; color: #fff; }
.cp-revanche:focus-visible { outline: 2px solid #ff9a3c; outline-offset: 2px; }
.cp-revanche.hot {
  color: #fff; background: linear-gradient(180deg, #E5842f, #c85a12); border-color: #ffb266;
  box-shadow: 0 0 14px -3px #E5842faa, inset 0 1px 0 #ffffff33;
  animation: revanche-pulse 1.4s ease-in-out infinite;
}

/* Kleiner „Bump", wenn eine Muenze beim Gewinner ankommt. */
.pc-ava.coin-hit { animation: coin-bump .3s ease-out; }
@keyframes coin-bump { 0% { transform: scale(1); } 40% { transform: scale(1.11); } 100% { transform: scale(1); } }

.champ-rewards {
  display: flex; flex-direction: column; gap: 5px; width: 100%; max-width: 340px;
  padding: 12px 16px 14px; border-radius: 14px;
  background: radial-gradient(120% 120% at 50% 0%, #12261d, #0a120d);
  border: 1px solid #ffffff1c; box-shadow: 0 18px 40px -22px #000;
}
.champ-rewards-head { font-family: var(--display); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 3px; }
.reward-row {
  display: grid; grid-template-columns: 22px 1fr auto; align-items: center; gap: 8px;
  padding: 6px 12px; border-radius: 9px;
  background: #ffffff0c; border: 1px solid #ffffff14;
  animation: reward-in .32s ease-out backwards;
}
@keyframes reward-in { from { opacity: 0; transform: translateX(-10px); } to { opacity: 1; transform: none; } }
.rw-ico { font-size: 15px; text-align: center; }
.rw-lbl { font-family: var(--display); font-size: 11px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-2); }
.rw-val { font-family: var(--mono); font-size: 15px; color: #7FE0AC; font-variant-numeric: tabular-nums; }
.reward-row.bad .rw-val { color: #FF7A5C; }

@media (prefers-reduced-motion: reduce) {
  .champ-panel, .reward-row, .cp-revanche.hot { animation: none; }
}
/* AFK/verdeckt: der ganze Sieger-Screen statisch (kein Panel-Pop, kein glow-Puls, keine Muenzen)
   -> im gedrosselten Zustand entsteht kein Render-Burst, der Firefoxx GPU-Prozess haengen liesse. */
.banner-card.champ-static,
.banner-card.champ-static .champ-panel,
.banner-card.champ-static .cp-revanche,
.banner-card.champ-static .reward-row { animation: none !important; }

/* ---------- Hochformat ---------- */

@media (orientation: portrait) {
  .felt { aspect-ratio: 10 / 16; width: min(100cqw, 100cqh * 0.625, 560px); }
  .dropzone { width: 62%; height: 34%; }
}

/* ---------- Hauptmenue / Hub ---------- */

/* Vollbild-Startscreen. Liegt ueber allem, solange body.hub-open gesetzt ist —
   ist es nicht gesetzt (im Match), wird der Hub ausgeblendet. */
.hub {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column;
  overflow: auto;
  background:
    radial-gradient(1100px 520px at 50% -6%, #1c3a2a 0%, transparent 62%),
    radial-gradient(760px 420px at 84% 6%, #FFD24B14 0%, transparent 55%),
    linear-gradient(180deg, #0c1912 0%, #0a130d 100%);
}
body:not(.hub-open) .hub { display: none; }

/* Gewaehltes Biom dezent hinter dem Hub — so ist die Tisch-Wahl schon hier
   sichtbar. Bild wird per JS gesetzt (setBiome). Niedrige Deckkraft, damit die
   dunkle Hub-Basis durchscheint und der Text lesbar bleibt. */
.hub-bg {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-position: center; background-size: cover; background-repeat: no-repeat;
  opacity: .18;
}
.hub-hud, .hub-main { position: relative; z-index: 1; }

/* Top-HUD: Avatar, Rang+XP, Chips, Kronen — der Klebstoff aus dem Konzept. */
.hub-hud {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid #ffffff14;
  background: linear-gradient(180deg, #00000055, #00000018);
}
.hud-user { display: flex; align-items: center; gap: 11px; }
.hud-avatar {
  width: 42px; height: 42px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center; line-height: 1;
  font-size: 21px;
  background: radial-gradient(circle at 40% 30%, #2a4234, #14241c);
  border: 1px solid #ffffff1f;
}
.hud-who { display: flex; flex-direction: column; line-height: 1.15; }
.hud-who b { font-family: var(--display); font-size: 15px; color: var(--ink); letter-spacing: .03em; }
.hud-who span { font-family: var(--mono); font-size: 10.5px; color: var(--ink-2); }
.hud-xp { width: 96px; height: 5px; border-radius: 3px; background: #ffffff14; overflow: hidden; margin-top: 4px; }
.hud-xp i { display: block; height: 100%; background: linear-gradient(90deg, #FFD24B, #ffe9a6); }
.hud-spacer { flex: 1; }
.hud-pill {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border-radius: 999px;
  background: #00000038; border: 1px solid #ffffff1f;
  font-family: var(--mono); font-size: 13px; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.hud-pill b { color: #FFE9A6; font-weight: 600; }
.hud-icon {
  width: 38px; height: 38px; border-radius: 10px; padding: 0;
  display: grid; place-items: center; font-size: 16px;
}

/* Mitte: Wortmarke, Start-Panel, Kacheln — vertikal zentriert. */
.hub-main {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 30px; padding: 30px 20px 44px; text-align: center;
}
.hub-brand { display: flex; flex-direction: column; align-items: center; }
.hub-brand .brand-logo {
  width: 300px; margin-bottom: 0;
  filter: drop-shadow(0 0 8px rgba(255, 255, 255, .34)) drop-shadow(0 0 22px rgba(255, 255, 255, .18)) drop-shadow(0 3px 8px #0009);
}
.hub-brand .menu-brand { margin: 14px 0 0; font-size: 12px; letter-spacing: .04em; }

/* Start-Panel: Optionen + grosser Startknopf. */
.hub-start {
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  padding: 22px 26px 20px;
  background: linear-gradient(165deg, #14241cF0, #0a130dF6);
  border: 1px solid #ffffff1f; border-radius: 18px;
  box-shadow: 0 26px 60px -26px #000E, inset 0 1px 0 #ffffff12;
  width: min(920px, 94vw);
}

/* --- Neues Hauptmenue: Voreinstellung-Feld + 4 Config-Kacheln (Chips direkt drin) --- */
.cfg-preset { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.cfg-preset .menu-row { gap: 7px; }
.cfg-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; width: 100%; align-items: stretch; }
.cfg-tile {
  position: relative;
  display: flex; flex-direction: column; gap: 9px;
  padding: 13px 11px 14px; border-radius: 14px;
  background: linear-gradient(160deg, #18291f, #0e1712);
  border: 1px solid #ffffff14;
  box-shadow: inset 0 1px 0 #ffffff10, 0 10px 24px -16px #000B;
}
.cfg-title {
  font-family: var(--display); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase;
  color: #9db8a8; text-align: center;
}
.cfg-chips { display: flex; flex-direction: column; gap: 6px; }
.cfg-chips .chip { width: 100%; text-align: center; white-space: nowrap; min-width: 0; }
.cfg-chips .combine-chip { margin-top: 4px; font-size: 10.5px; }
/* Sperr-Badge (Standard/Zufall) oben rechts, nur in den gedimmten Modus-/Feld-Kacheln sichtbar. */
.cfg-lock {
  display: none; position: absolute; top: 8px; right: 8px;
  font: 700 8.5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); background: #000A; border: 1px solid #ffffff1f;
  padding: 3px 6px; border-radius: 6px;
}

/* --- Hub-Views: home (Wahl) / multi (Aktions-Kacheln) / browse (Match-Browser) / solo + host (Config) --- */
.hub-home, .hub-multi, .hub-browse, .hub-config, .hub-profile, .hub-pname, .hub-pavatar { display: none; }
/* Bezug fuer den absolut liegenden Zurueck-Knopf. KEINE feste Breite: die View schrumpft auf ihren
   Inhalt (Config-Panel bzw. die Kachelreihe), damit left:0 buendig an der Inhaltskante liegt
   (Config-Panel links bzw. Hosten-Kachel links) statt an einer breiteren Wrapper-Kante. */
.hub-multi, .hub-browse, .hub-config, .hub-profile, .hub-pname, .hub-pavatar { position: relative; }
.hub[data-view="home"] .hub-home { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; }
.hub[data-view="multi"] .hub-multi { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.hub[data-view="browse"] .hub-browse { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.hub[data-view="profile"] .hub-profile { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.hub[data-view="pname"] .hub-pname { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.hub[data-view="pavatar"] .hub-pavatar { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.hub[data-view="solo"] .hub-config,
.hub[data-view="host"] .hub-config { display: flex; flex-direction: column; align-items: center; gap: 14px; }

/* --- Profil: Anzeigename-Panel + Avatar-Auswahl --- */
.profile-panel {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  width: min(460px, 92vw); padding: 22px 20px;
  background: #0e1a15cc; border: 1px solid #ffffff1a; border-radius: 16px;
  box-shadow: 0 18px 44px -22px #000, inset 0 1px 0 #ffffff10;
}
.profile-panel.wide { width: min(560px, 94vw); }
.pp-avatar {
  width: 76px; height: 76px; border-radius: 50%; display: grid; place-items: center;
  font-size: 42px; line-height: 1; background: #ffffff10; border: 2px solid var(--accent);
  box-shadow: 0 0 0 4px var(--accent-ring), 0 6px 16px -8px #000;
}
.pp-title { font-family: var(--display); font-size: 18px; font-weight: 800; letter-spacing: .06em; color: var(--ink); }
.pp-input {
  width: 100%; box-sizing: border-box; text-align: center;
  font-family: var(--display); font-size: 20px; font-weight: 700; letter-spacing: .04em;
  color: var(--ink); background: #05100b; border: 1.5px solid #ffffff26; border-radius: 12px;
  padding: 12px 14px; outline: none;
}
.pp-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.pp-hint { font-family: var(--mono); font-size: 12px; color: var(--ink-2); text-align: center; max-width: 34ch; line-height: 1.5; }
/* „Bestätigen": uebernimmt Name/Avatar. */
.pp-confirm {
  margin-top: 4px; padding: 11px 30px; cursor: pointer;
  font-family: var(--display); font-size: 15px; font-weight: 800; letter-spacing: .06em;
  color: #fff; background: var(--accent-btn); border: 1.5px solid var(--accent); border-radius: 12px;
  box-shadow: 0 0 14px -6px var(--accent-glow), 0 8px 18px -12px #000, inset 0 1px 0 #ffffff22;
  transition: filter .12s ease, transform .08s ease;
}
.pp-confirm:hover { filter: brightness(1.12); }
.pp-confirm:active { transform: translateY(1px); }
.avatar-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); grid-auto-rows: 54px; gap: 8px;
  width: 100%; padding: 4px; overflow-y: auto;
  max-height: min(60vh, 372px);          /* genau ~6 Reihen (6*54 + 5*8 + Padding), Rest scrollt */
  scrollbar-width: none;                 /* Firefox: Scrollbalken unsichtbar */
  -ms-overflow-style: none;              /* alte Edge */
}
.avatar-grid::-webkit-scrollbar { width: 0; height: 0; display: none; }   /* Chromium/WebKit */
.avatar-opt {
  width: 100%; height: 100%; padding: 0; margin: 0; cursor: pointer;   /* feste Zellenhoehe (grid-auto-rows) */
  display: flex; align-items: center; justify-content: center;   /* Emoji exakt mittig im Slot */
  font-size: 30px; line-height: 1; border-radius: 12px;
  background: #ffffff0d; border: 1.5px solid transparent; transition: transform .1s ease, background .12s ease, border-color .12s ease;
}
.avatar-opt:hover { background: #ffffff1a; transform: translateY(-2px); }
.avatar-opt.sel { border-color: var(--accent); background: var(--accent-btn); box-shadow: 0 0 0 3px var(--accent-ring); }

/* Match-Browser (Beitreten): Liste offener Matches. */
.browse-panel {
  width: min(680px, 94vw);
  display: flex; flex-direction: column; gap: 12px; padding: 20px 22px;
  background: linear-gradient(165deg, #14241cF0, #0a130dF6);
  border: 1px solid #ffffff1f; border-radius: 18px;
  box-shadow: 0 26px 60px -26px #000E, inset 0 1px 0 #ffffff12;
}
.browse-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.browse-title { font-family: var(--display); font-size: 17px; letter-spacing: .04em; color: var(--ink); }
.browse-refresh { font-size: 12px; }
/* Suche + Filter */
.browse-search {
  width: 100%; padding: 9px 12px; border-radius: 10px;
  background: #ffffff0c; border: 1px solid #ffffff1f; color: var(--ink);
  font-family: var(--sans); font-size: 13px;
}
.browse-search::placeholder { color: var(--ink-3); }
.browse-search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-ring); }
.browse-filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.browse-filter {
  font-family: var(--sans); font-size: 12px; color: var(--ink-2);
  background: #ffffff0c; border: 1px solid #ffffff1f; border-radius: 8px; padding: 6px 9px; cursor: pointer;
}
.browse-filter:focus { outline: none; border-color: var(--accent); }
.browse-filter option { background: #14241c; color: var(--ink); }
#filter-open { font-size: 12px; }
.browse-empty { font-family: var(--mono); font-size: 11px; color: var(--ink-3); text-align: center; padding: 12px; }
.browse-list { display: flex; flex-direction: column; gap: 8px; max-height: 46vh; overflow-y: auto; }
.browse-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 10px 12px; border-radius: 12px;
  background: #ffffff08; border: 1px solid #ffffff12;
}
.browse-row.browse-local { background: var(--accent-wash); border-color: var(--accent-ring); cursor: pointer; transition: background .15s, border-color .15s; }
.browse-row.browse-local:hover { background: var(--accent-btn-hi); border-color: var(--accent); }
.browse-row.soon { opacity: .62; }
.browse-av { font-size: 26px; line-height: 1; width: 34px; text-align: center; flex: none; }
.browse-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.browse-main b { font-family: var(--display); font-weight: 700; font-size: 15px; letter-spacing: .03em; color: var(--ink); }
.browse-meta { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }
.browse-tags { display: flex; flex-wrap: wrap; gap: 5px; justify-content: flex-end; flex: none; max-width: 300px; }
.browse-tag {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .02em; color: var(--ink-2);
  background: #ffffff10; border: 1px solid #ffffff18; border-radius: 6px; padding: 2px 6px; white-space: nowrap;
}
.browse-join { font-family: var(--display); font-size: 12px; letter-spacing: .04em; color: var(--accent); flex: none; }
.browse-join.disabled { color: var(--ink-3); }
.browse-note { font-family: var(--mono); font-size: 10px; color: var(--ink-3); text-align: center; line-height: 1.5; }
/* Solo: kein Einsatz + kein Host-Button; Host: kein Solo-Startknopf. */
.hub[data-view="solo"] .host-only { display: none; }
.hub[data-view="host"] .solo-only { display: none; }
/* Solo: 3 Config-Kacheln (Modus/Feld/Spieler). Host: 5 (+ Einsatz + Sichtbarkeit). Das Solo-Panel
   wird schmaler, damit die 3 Spalten dieselbe Breite wie die 5 im Host haben (statt gestreckt/leer). */
.hub[data-view="solo"] .hub-start { width: min(570px, 94vw); }
.hub[data-view="solo"] .cfg-tiles { grid-template-columns: repeat(3, 1fr); }
.hub[data-view="host"] .cfg-tiles { grid-template-columns: repeat(5, 1fr); }
/* Reihe der grossen Wahl-Kacheln (Home: Singleplayer/Multiplayer, Multi: Hosten/Beitreten). */
.mode-row { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; }

/* Grosse Wahl-Kacheln auf dem Home-Screen. */
.mode-tile {
  position: relative; width: 300px; min-height: 152px; padding: 26px 24px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  border-radius: 18px; text-align: center; cursor: pointer;
  background: linear-gradient(160deg, #1a2c22, #0d1712);
  border: 1px solid #ffffff1c;
  box-shadow: 0 22px 50px -24px #000E, inset 0 1px 0 #ffffff12;
  transition: transform .12s, border-color .15s, box-shadow .15s;
}
.mode-tile:hover { transform: translateY(-2px); border-color: var(--accent); box-shadow: 0 26px 56px -22px #000E, 0 0 0 1px var(--accent-ring), inset 0 1px 0 #ffffff12; }
.mode-tile:active { transform: translateY(0); }
.mode-ico { font-size: 46px; line-height: 1; filter: drop-shadow(0 3px 8px #000A); }
.mode-name { font-family: var(--display); font-weight: 700; font-size: 24px; letter-spacing: .05em; color: var(--ink); }
.mode-sub { font-family: var(--mono); font-size: 11px; letter-spacing: .04em; color: var(--ink-3); }

/* Zurueck-Knopf: ABSOLUT direkt UEBER dem Config-/Multi-Block (an seiner urspruenglichen Stelle,
   links in der Luecke unter dem Logo) -> nimmt keinen Platz im Fluss ein und schiebt die Kategorien
   darunter nicht mehr nach unten. */
.hub-back {
  position: absolute; left: 0; bottom: 100%; margin-bottom: 8px; z-index: 3;
  font-family: var(--display); font-size: 13px; letter-spacing: .04em;
  color: var(--ink-2); background: #ffffff0e; border: 1px solid #ffffff1f; border-radius: 10px;
  padding: 8px 14px; cursor: pointer; transition: background .15s, border-color .15s;
}
.hub-back:hover { background: #ffffff18; border-color: #ffffff33; color: var(--ink); }
.hub-opts { display: flex; flex-direction: column; gap: 15px; align-items: center; width: 100%; }
.hub-opt-group { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.hub-opt-group .menu-row { gap: 7px; }
.hub-opt-group .chip { min-width: 44px; }
/* Haken-Chip „Modi kombinieren": Kaestchen fuellt sich, wenn aktiv. */
.combine-row { margin-top: 1px; }
.toggle-check::before { content: '\2610'; margin-right: 6px; line-height: 1; }
.toggle-check[aria-pressed="true"]::before { content: '\2611'; }
/* Breite Kategorien (Spielfeld/Spielmodus/Wetteinsatz): Chips passen sich ihrem Text
   an (statt gleicher Breite) und duerfen umbrechen — so ragt kein Wort ueber den Rand. */
.hub-wide-group .menu-row { flex-wrap: wrap; justify-content: center; }
.hub-wide-group .chip { flex: 0 1 auto; white-space: nowrap; min-width: 0; }

.hub-play {
  font-family: var(--display); font-weight: 700; font-size: 21px; letter-spacing: .06em;
  color: #06120c; padding: 15px 46px; border-radius: 13px;
  /* Faerbt sich mit dem gewaehlten Tisch (Akzent-Tokens). */
  background: linear-gradient(180deg, var(--accent), var(--accent-btn-hi));
  border: 1px solid var(--accent);
  box-shadow: 0 14px 30px -12px var(--accent-strong), inset 0 1px 0 #ffffff66;
  display: inline-flex; align-items: center; gap: 12px;
}
.hub-play:hover:not(:disabled) {
  /* Gradient explizit wiederholen, sonst schlaegt der generische Neutral-Hover durch. */
  background: linear-gradient(180deg, var(--accent), var(--accent-btn-hi));
  color: #06120c; border-color: var(--accent);
  filter: brightness(1.08);
}
.hub-play .play-arrow { font-size: 15px; }
.hub-play-sub {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em;
  color: var(--ink-3); margin-top: -6px; text-transform: uppercase;
}

/* Vorschau-Kacheln der naechsten Bausteine (noch gesperrt). */
.hub-tiles { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; }
.hub-tile {
  position: relative; width: 172px; min-height: 92px; padding: 16px 16px 14px;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-end; gap: 3px;
  border-radius: 14px; text-align: left;
  background: linear-gradient(160deg, #16261d, #101a13);
  border: 1px solid #ffffff14;
}
.hub-tile .tile-name { font-family: var(--display); font-weight: 700; font-size: 16px; letter-spacing: .03em; color: var(--ink); }
.hub-tile .tile-sub { font-family: var(--mono); font-size: 10px; color: var(--ink-3); }
.hub-tile .tile-badge {
  position: absolute; top: 9px; right: 9px;
  font-family: var(--mono); font-size: 9px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3); background: #00000040; border: 1px solid #ffffff14; border-radius: 6px; padding: 2px 7px;
}
.hub-tile.soon { opacity: .5; cursor: default; }
/* Aktive PvP-Kacheln (Hosten/Beitreten): anfassbar mit Hover/Press. */
.hub-tile:not(.soon) { cursor: pointer; transition: background .15s, border-color .15s, transform .1s; }
.hub-tile:not(.soon):hover { background: linear-gradient(160deg, #1d3327, #12211a); border-color: var(--accent-ring); }
.hub-tile:not(.soon):active { transform: translateY(1px); }

/* Sekundaerer Banner-Knopf ("Zum Menue") — dezenter als der Primaerknopf. */
.banner-btn.secondary {
  margin-top: 8px; background: #ffffff0c; border-color: #ffffff26;
  color: var(--ink-2); font-family: var(--mono); font-size: 12px; letter-spacing: .04em;
}
.banner-btn.secondary:hover:not(:disabled) { color: var(--ink); background: #ffffff16; border-color: #ffffff4a; }

/* ---------- Audio-Regler (Musik / Sounds) ---------- */
.audio-ctrl { display: flex; flex-direction: column; gap: 5px; }
.audio-row { display: flex; align-items: center; gap: 8px; }
.audio-mute {
  flex: none; width: 34px; height: 30px; padding: 0;
  display: grid; place-items: center; font-size: 14px; border-radius: 8px;
}
.audio-mute[aria-pressed="true"] { color: var(--ink-3); background: #ffffff08; border-color: #ffffff1f; }
.audio-slider {
  flex: 1; min-width: 88px; height: 5px; padding: 0; margin: 0;
  -webkit-appearance: none; appearance: none;
  background: #ffffff1f; border: none; border-radius: 3px; cursor: pointer;
}
.audio-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent); border: 1px solid #00000066;
  box-shadow: 0 0 8px -2px var(--accent-glow);
}
.audio-slider::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent); border: 1px solid #00000066;
}
.audio-slider:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.audio-slider.muted { opacity: .4; }
.audio-slider.muted::-webkit-slider-thumb { background: var(--ink-3); box-shadow: none; }
.audio-slider.muted::-moz-range-thumb { background: var(--ink-3); }

/* Audio-Regler im Hub: nebeneinander, dezent unter den Kacheln. */
.hub-audio { display: flex; gap: 26px; justify-content: center; flex-wrap: wrap; margin-top: 6px; }
.hub-audio .audio-ctrl { min-width: 176px; }
.hub-audio .label { text-align: left; }

@media (max-width: 560px) {
  .hub-brand .brand-logo { width: 220px; }
  .hub-main { gap: 22px; }
}

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

/* ==================== Mobile / Querformat (vorerst nur Landscape) ==================== */

/* Touch-Paritaet: ziehbare Karten duerfen die Seite NICHT scrollen/gesten — sonst bricht der
   Browser das Ziehen mit pointercancel ab. Nur die Greifflaechen, nicht global (Rest bleibt
   touch-action: manipulation, damit Buttons/Scrollen normal funktionieren). */
.card-slot.grab, .card-slot.swap-source, .dropzone { touch-action: none; }

/* Dreh-Hinweis DEAKTIVIERT: 4CREWS soll jetzt Quer- UND Hochformat unterstuetzen (Both-Orientation-
   Umbau). Das alte „Bitte ins Querformat drehen"-Overlay wird daher nie mehr angezeigt. (Das echte
   Hochformat-Layout kommt mit dem Fliess-Layout-Umbau.) */
.rotate-hint { display: none !important; }
@keyframes rotate-nudge { 0%, 62%, 100% { transform: rotate(0); } 30% { transform: rotate(-90deg); } }

/* ---- 16:9-STAGE (nur Touch-Geraete): das ganze Spiel als feste 1920x1080-Buehne, die per
   transform:scale auf den Screen skaliert wird (Letterbox — der Biom-Hintergrund fuellt die
   Raender). So sieht auf dem Handy alles EXAKT wie am PC aus, statt jedes Element einzeln
   umzubrechen. Der Biom-BG liegt auf body::before (Viewport) -> fuellt die Balken. --stage-scale
   kommt aus app.js (min(vw/1920, vh/1080)). Desktop bleibt komplett unberuehrt (kein stage-mode). */
body.stage-mode #app {
  position: fixed; left: 50%; top: 50%;
  width: 1920px; height: 1080px;
  transform: translate(-50%, -50%) scale(var(--stage-scale, 1));
  transform-origin: center center;
}
/* In der Buehne feste Design-Groessen statt vh/vmin (die wuerden den echten Viewport messen und
   nicht die Buehne). Es sind die Werte, auf die die Desktop-Clamps bei 1080p ohnehin deckeln. */
body.stage-mode {
  --card-table: 62px; --card-mine: 88px; --card-trick: 78px; --card-back: 58px;
}
body.stage-mode .avatar { width: 46px; font-size: 17px; }
body.stage-mode .who-name,
body.stage-mode .hand-num,
body.stage-mode .medal-label { font-size: 12px; }
body.stage-mode .medal-disc { font-size: 46px; }

/* ===== Echtes Handy-Layout (body.is-mobile): FLIESS-LAYOUT mit Flexbox-Zonen statt radialer %-Positionen.
   Jede Zone misst sich selbst -> nichts ueberlappt/schneidet ab, egal Aufloesung/Ausrichtung. ===== */
/* #app als Groessen-Container -> cqh misst die SPIELFLAECHE (bei ?res der feste Kasten, sonst der Viewport).
   So richten sich die Kartengroessen nach dem Kasten statt nach dem Desktop (kein Hochstrecken). */
body.is-mobile #app { container-type: size; }
body.is-mobile {
  /* Segment-relative Groessen (1 Segment = 25% Hoehe = 25cqh). Karten 5:7 -> Breite = Hoehe / 1.4.
     Die Variablen sind BREITEN; die Hoehe ergibt sich per aspect-ratio (5/7). */
  --card-mine:  calc(20cqh / 1.4);   /* Hand:   Hoehe = 80% Segment (20cqh). Gegnerhand nutzt via buildFan denselben Wert. */
  --card-back:  calc(20cqh / 1.4);
  --card-table: calc(10cqh / 1.4);   /* Stapel: Hoehe = 40% Segment (10cqh). */
  --card-trick: calc(16cqh / 1.4);   /* Tisch:  Hoehe ~64% Segment (Kompromiss; nicht spezifiziert). */
}
/* --- 2-Spieler-Handy-Layout: FESTES 4x4-RASTER (proportional -> aufloesungsunabhaengig, immer 16 Segmente).
   Elemente per grid-area exakt in ihre Segmente. Spec: project_4crews_mobile_grid. --- */
body.is-mobile .room { position: absolute; inset: 0; display: block; }
body.is-mobile .table-wrap { position: absolute; inset: 0; display: block; }
body.is-mobile .felt {
  display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 1fr);
  width: 100%; height: 100%; padding: 0;
}
/* Rasterelemente aus der absoluten %-Positionierung loesen (JS setzt inline left/top/transform). */
body.is-mobile .felt > .seat,
body.is-mobile .felt > .opp-hand,
body.is-mobile .felt > .center,
body.is-mobile .felt > .m-group,
body.is-mobile .felt > .m-hint {
  position: relative !important; left: auto !important; top: auto !important; transform: none !important; margin: 0 !important;
}
body.is-mobile .felt .dropzone { position: absolute !important; }

/* Platzierung nach Segment-Spec (2 Spieler): */
body.is-mobile .opp-hand        { grid-column: 2 / 4; grid-row: 1;     place-self: center; }        /* Seg 2,3 */
body.is-mobile .seat:not(.mine) { grid-column: 2 / 4; grid-row: 2;     place-self: start center; }  /* Seg 6,7 oben anliegend */
body.is-mobile .center          { grid-column: 2 / 4; grid-row: 2 / 4; place-self: center; }         /* Kreuz 6/7/10/11 = Mitte */
body.is-mobile .seat.mine       { grid-column: 2 / 4; grid-row: 3;     place-self: end center; }     /* Seg 10,11 unten anliegend */
body.is-mobile #hint-left       { grid-column: 1 / 3; grid-row: 2 / 4; place-self: center; }         /* Kreuz 5,6,9,10 */
body.is-mobile #hint-right      { grid-column: 3 / 5; grid-row: 2 / 4; place-self: center; }         /* Kreuz 7,8,11,12 */
body.is-mobile #mg-bluff        { grid-column: 1;     grid-row: 3;     place-self: center; }         /* Seg 9  Bluff+Fake */
body.is-mobile #mg-legen        { grid-column: 1;     grid-row: 4;     place-self: center; }         /* Seg 13 Legen+Shift */
body.is-mobile #mg-show         { grid-column: 4;     grid-row: 3;     place-self: center; }         /* Seg 12 Zeigen+Emotes */
body.is-mobile #mg-back         { grid-column: 4;     grid-row: 4;     place-self: center; }         /* Seg 16 Zurueck+Passen */

/* Meine Hand (liegt in .me, AUSSERHALB .felt) absolut auf Seg 14,15 (Sp2-3, Reihe4).
   WICHTIG: transform:none — sonst erbt sie das Desktop-translateY(-50%) und haengt am Kreuz 10/11/14/15. */
body.is-mobile section.me {
  position: absolute; left: 25%; right: 25%; top: 75%; bottom: 0; z-index: 4;
  transform: none; flex-direction: row;
  display: flex; align-items: center; justify-content: center; padding: 2px 4px;
}

/* MEINE Panels bleiben aus (Name/Bild kenne ich selbst). Gegner-Panels aber wieder ANzeigen:
   links neben dem Faecher nur das Profilbild, rechts nur der Name (keine Kartenzahl — schnell erfassbar). */
body.is-mobile .seat-panel { display: none; }
body.is-mobile .opp-hand .seat-panel { display: inline-flex; }
body.is-mobile .opp-hand .seat-panel.left .sp-name { display: none; }                   /* links: nur Profilbild */
body.is-mobile .opp-hand .seat-panel.right .hand-num,
body.is-mobile .opp-hand .seat-panel.right .hand-label { display: none; }               /* rechts: keine Kartenzahl */
body.is-mobile .opp-hand .seat-panel.right .sp-name {
  display: block; max-width: 24cqw; font-size: clamp(9px, 2.4cqh, 14px);                /* rechts: der Name */
}
body.is-mobile .opp-hand .avatar { width: clamp(22px, 6.5cqh, 40px); height: clamp(22px, 6.5cqh, 40px); }
body.is-mobile .trick-label { display: none; }
body.is-mobile .center-controls { display: none; }
body.is-mobile .board { padding: 4px 6px 6px; border-radius: 7px; gap: 3px; }
body.is-mobile .board::before { border-radius: 14px; }
body.is-mobile .slots { gap: 4px; }
body.is-mobile .slot { border-radius: 3px; }
body.is-mobile .stack-cell .card-slot .card,
body.is-mobile .my-hand .card,
body.is-mobile .opp-hand .card { box-shadow: 0 2px 5px -2px rgba(0,0,0,.8); }
/* Handy: farbiger Kartenrahmen je Groesse abgestimmt. Basis (Stapel) = 1px; Handkarten +0,5px,
   gelegte Karten in der Mitte (#trick) +0,25px — sonst wirken die groesseren Karten zu duenn gerandet. */
body.is-mobile .card.full::after { border-width: 1px; }
body.is-mobile .my-hand .card.full::after,
body.is-mobile .opp-hand .card.full::after { border-width: 1.5px; }
body.is-mobile #trick .card.full::after { border-width: 1.25px; }

/* Hinweis-Boxen (links/rechts vom Feld). */
.m-hint { display: none; }
body.is-mobile .m-hint {
  display: block; width: min(86%, 150px); text-align: center;   /* feste, GLEICHE Breite links wie rechts */
  font-family: var(--display); font-weight: 700; font-size: clamp(9px, 2.4cqh, 13px);
  letter-spacing: .03em; color: #EAF7EF; line-height: 1.18;
  padding: 4px 8px; border-radius: 8px; background: #0a1712dd; border: 1px solid #ffffff1a; text-shadow: 0 1px 3px #000;
}
body.is-mobile .m-hint:empty { visibility: hidden; }

/* Button-Gruppe = 2 runde Buttons nebeneinander. */
.m-group { display: none; }
body.is-mobile .m-group { display: flex; flex-direction: row; gap: 5px; align-items: center; }
.m-btn {
  width: clamp(40px, 9.5cqh, 60px); height: clamp(40px, 9.5cqh, 60px); border-radius: 50%; padding: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  font-family: var(--display); font-weight: 700; line-height: 1; cursor: pointer;
  background: #0e1a15ee; border: 1.5px solid #ffffff2a; color: var(--ink);
  box-shadow: 0 6px 16px -8px #000, inset 0 1px 0 #ffffff14;
  /* iOS: 300ms-Tap-Delay + Doppeltipp-Zoom raus -> der Toggle reagiert beim ERSTEN Tippen
     (auf iPhone brauchte „Mehr" sonst mehrere Taps). tap-highlight-Blitz aus. */
  touch-action: manipulation; -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none;
}
.m-btn .m-ico { font-size: clamp(15px, 3.2cqh, 21px); }
.m-btn .m-lbl { font-size: clamp(7px, 1.5cqh, 9px); letter-spacing: .02em; }
.m-btn.go   { background: var(--accent-btn); border-color: var(--accent); color: #EAFFF4; }
.m-btn.pass { background: var(--accent-btn); border-color: var(--accent); color: #EAFFF4; }
.m-btn.pass.armed { animation: pass-armed-pulse 1s ease-in-out infinite; }
.m-btn.on { background: var(--accent-btn); border-color: var(--accent); color: #EAFFF4; }
.m-btn:disabled { opacity: .4; background: #23252c; border-color: #3a3d47; color: var(--ink-3); cursor: default; }
.m-btn:active:not(:disabled) { transform: translateY(1px); }
/* Handy: Button-Durchmesser = 75% Segmenthoehe (Segment = 25cqh -> 18.75cqh). Zwei Buttons je Gruppe,
   die Gruppe sitzt per place-self:center mittig in ihrem Segment -> ringsum symmetrische Abstaende. */
body.is-mobile .m-btn { width: 18.75cqh; height: 18.75cqh; }

/* --- Start-Gate (Handy): verdeckt das Menue, bis 1x getippt UND quer. Wird nur auf dem Handy erzeugt. --- */
#start-gate {
  position: fixed; inset: 0; z-index: 9999; cursor: pointer;
  display: flex; align-items: center; justify-content: center; text-align: center;
  background: radial-gradient(circle at 50% 38%, #12241a, #0a130d 72%);
  transition: opacity .38s ease;
}
#start-gate.gone { opacity: 0; pointer-events: none; }
#start-gate .sg-inner { display: flex; flex-direction: column; align-items: center; gap: 18px; padding: 24px; }
#start-gate .sg-logo { width: min(46vmax, 60vmin); max-width: 320px; filter: drop-shadow(0 10px 26px #000a); }
#start-gate .sg-title {
  font-family: var(--display); font-weight: 700; letter-spacing: .04em;
  font-size: clamp(20px, 5.5vmin, 34px); color: var(--ink);
  animation: sg-pulse 1.4s ease-in-out infinite;
}
#start-gate .sg-hint {
  display: flex; align-items: center; gap: 9px;
  color: var(--ink-2); font-size: clamp(12px, 3vmin, 16px);
}
#start-gate .sg-rot { display: inline-block; font-size: 1.35em; animation: sg-spin 2.6s linear infinite; }
#start-gate .sg-install-slot { display: flex; justify-content: center; }
#start-gate .sg-install {
  margin-top: 4px; padding: 7px 12px; border-radius: 9px;
  background: #0e1a15; border: 1px solid #ffffff22; color: var(--ink-2); font-size: clamp(11px, 2.6vmin, 14px);
}
#start-gate .sg-install b { color: var(--accent); font-weight: 700; }
#start-gate .sg-install-btn {
  margin-top: 4px; padding: 9px 20px; border-radius: 10px; cursor: pointer;
  font-family: var(--display); font-weight: 700; font-size: clamp(12px, 3vmin, 15px); letter-spacing: .03em;
  color: #06120c; background: linear-gradient(180deg, var(--accent), var(--accent-btn-hi));
  border: 1px solid var(--accent); box-shadow: 0 8px 20px -8px var(--accent-strong);
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
#start-gate .sg-install-btn:active { filter: brightness(1.08); transform: translateY(1px); }
@keyframes sg-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@keyframes sg-spin { to { transform: rotate(360deg); } }

/* ===== Hauptmenue / Hub — HANDY-Layout (Querformat) =========================================
   Der Hub ist am Desktop gross (300px-Logo, 300x152-Kacheln) -> auf dem kurzen Querformat viel zu
   gross. Hier alles kompakt und an die kurze Achse gekoppelt: cqh/cqw beziehen sich auf #app
   (container-type:size am Handy) -> funktioniert am echten Handy UND im ?res-Testkasten.
   `safe center` zentriert wenn es passt, rutscht bei Ueberlaenge nach oben (kein Abschneiden). */
/* NICHT der ganze .hub scrollt (sonst wandert das absolute .hub-bg mit) — nur der Inhalt (.hub-main)
   scrollt intern. So bleibt das Biom-Hintergrundbild fix hinter allem stehen. */
body.is-mobile .hub { overflow: hidden; }
body.is-mobile .hub-main {
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  justify-content: safe center;
  gap: clamp(8px, 2.6cqh, 22px);
  padding: clamp(8px, 2cqh, 16px) 16px clamp(12px, 3cqh, 24px);
}
body.is-mobile .hub-brand .brand-logo { width: clamp(110px, 30cqh, 220px); }

/* Top-HUD kompakter. */
body.is-mobile .hub-hud { padding: 5px 12px; gap: 8px; }
body.is-mobile .hud-avatar { width: 30px; height: 30px; font-size: 15px; border-radius: 8px; }
body.is-mobile .hud-who b { font-size: 12px; }
body.is-mobile .hud-who span { font-size: 8.5px; }
body.is-mobile .hud-xp { width: 66px; height: 4px; }
body.is-mobile .hud-pill { padding: 4px 9px; font-size: 11px; gap: 5px; }

/* Wahl-Kacheln (Home/Profil/Multi) — in einer Reihe, an die Hoehe gekoppelt. */
body.is-mobile .hub[data-view="home"] .hub-home,
body.is-mobile .mode-row { gap: clamp(8px, 2cqw, 18px); flex-wrap: nowrap; }
body.is-mobile .mode-tile {
  width: clamp(120px, 27cqw, 240px); min-height: 0;
  padding: clamp(10px, 2.6cqh, 24px) clamp(8px, 2cqw, 20px);
  gap: clamp(3px, 1cqh, 8px); border-radius: 14px;
}
body.is-mobile .mode-ico  { font-size: clamp(24px, 7.5cqh, 46px); }
body.is-mobile .mode-name { font-size: clamp(13px, 3.8cqh, 24px); }
body.is-mobile .mode-sub  { font-size: clamp(8px, 1.9cqh, 11px); }

/* Config-/Start-Panel (Solo/Host) — schmaler, Kacheln 2-spaltig, Chips fliessen in Reihen
   (statt hoher Einzel-Spalten) -> passt in der Hoehe. */
body.is-mobile .hub-start {
  width: min(96cqw, 860px); gap: clamp(8px, 2cqh, 16px);
  padding: clamp(8px, 2cqh, 18px) clamp(10px, 2.5cqw, 22px); border-radius: 14px;
}
/* Solo-Einstellungen genauso breit wie beim Hosten (Desktop macht Solo absichtlich schmaler —
   am Handy nicht gewuenscht). Hoehere Spezifitaet als die Desktop-Solo-Regel. */
body.is-mobile .hub[data-view="solo"] .hub-start { width: min(96cqw, 860px); }
/* Jede Kategorie = eine ZEILE (Titel links, Chips fliessen nach rechts ueber die Breite). Die
   Kategorien liegen untereinander. Bei 3-5 Kategorien passt das in die Hoehe und nutzt die Breite. */
body.is-mobile .hub-config .cfg-tiles { grid-template-columns: 1fr; gap: 6px; }
body.is-mobile .cfg-tile { flex-direction: row; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 10px; }
body.is-mobile .cfg-title { flex: none; min-width: 72px; text-align: left; font-size: 10px; letter-spacing: .08em; }
body.is-mobile .cfg-chips { flex: 1; flex-direction: row; flex-wrap: wrap; justify-content: flex-start; gap: 5px; }
body.is-mobile .cfg-chips .chip { width: auto; padding: 5px 9px; font-size: 11px; }
/* „Kombinieren"-Schalter am Handy vorerst raus. */
body.is-mobile #btn-combine { display: none; }
body.is-mobile .cfg-chips .combine-chip { margin-top: 0; font-size: 10px; }

/* Grosser Start-/Host-Knopf. */
body.is-mobile .hub-play {
  font-size: clamp(14px, 3.4cqh, 21px);
  padding: clamp(9px, 2cqh, 15px) clamp(22px, 6cqw, 46px); border-radius: 11px;
}

/* Profil-/Browse-Panels an die Box koppeln (nicht an die Desktop-vw). */
body.is-mobile .profile-panel { width: min(92cqw, 480px); }
body.is-mobile .profile-panel.wide { width: min(94cqw, 560px); }
body.is-mobile .browse-panel { width: min(94cqw, 620px); }
body.is-mobile .avatar-grid { max-height: 44cqh; }
body.is-mobile .browse-list { max-height: 40cqh; }

/* Audio-Regler kompakt (Musik/Sounds nebeneinander). */
body.is-mobile .hub-audio { gap: 14px; margin-top: 2px; }
body.is-mobile .hub-audio .audio-ctrl { min-width: clamp(120px, 30cqw, 176px); }

/* ===== Zwischenstand / Sieger-Screen — HANDY (Querformat) ===================================
   Am Desktop gross (30px-Titel, 186px-Panels, 86px-Avatare) -> auf dem kurzen Querformat zu hoch.
   Hier alles an die Box gekoppelt (cqh/cqw), Panels in EINER Reihe. `safe center` + overflow:auto
   am .banner faengt Ueberlaenge ab (oben buendig statt abgeschnitten). */
body.is-mobile .banner { padding: 8px; place-items: safe center; overflow: auto; }
body.is-mobile .banner-card { max-width: 98cqw; gap: 8px; padding: 10px 12px; }
body.is-mobile .banner-card.champion { max-width: 98cqw; gap: clamp(6px, 1.6cqh, 16px); padding: 4px; }

/* Titel */
body.is-mobile .champ-title { font-size: clamp(18px, 4.8cqh, 30px); }
body.is-mobile .interstitial-title { font-size: clamp(13px, 3.2cqh, 18px) !important; }
body.is-mobile .banner-title { font-size: clamp(15px, 3.6cqh, 21px); }
body.is-mobile .banner-sub { font-size: 10px; }

/* Spieler-Panels: alle in EINER Reihe, kompakt. */
body.is-mobile .champ-panels {
  --panel-w: clamp(94px, 22cqw, 186px);
  grid-template-columns: repeat(auto-fit, minmax(88px, var(--panel-w)));
  gap: clamp(6px, 1.4cqw, 14px); max-width: 98cqw;
}
body.is-mobile .champ-panel {
  min-height: 0; gap: 4px; border-radius: 14px;
  padding: clamp(8px, 2cqh, 20px) clamp(7px, 1.6cqw, 16px) clamp(8px, 1.8cqh, 18px);
}
body.is-mobile .pc-ava { width: clamp(42px, 12cqh, 86px); height: clamp(42px, 12cqh, 86px); border-radius: 14px; }
body.is-mobile .pc-ava span { font-size: clamp(22px, 6.5cqh, 46px); }
body.is-mobile .pc-name { font-size: clamp(12px, 2.6cqh, 17px); }
body.is-mobile .cp-tag { font-size: 9px; }
body.is-mobile .cp-pts b { font-size: clamp(19px, 4.8cqh, 31px); }
body.is-mobile .cp-pts span { font-size: clamp(8px, 1.8cqh, 11px); }
body.is-mobile .cp-stats { margin-top: clamp(5px, 1.4cqh, 12px); gap: 3px; }
body.is-mobile .cp-stat { font-size: clamp(9.5px, 2.1cqh, 12.5px); }

/* Belohnungen + Countdown kompakt. */
body.is-mobile .champ-rewards { max-width: min(92cqw, 340px); padding: 8px 12px 10px; gap: 4px; }
body.is-mobile .champ-rewards-head { font-size: 9px; }
body.is-mobile .reward-row { padding: 4px 10px; }
body.is-mobile .rw-val { font-size: 13px; }
body.is-mobile .banner-countdown { margin-top: 5px; gap: 5px; }
body.is-mobile .bc-bar { max-width: 60cqw; }
body.is-mobile .banner-btn { font-size: 12px; padding: 8px 18px; }

/* --- 16-Segment-Raster-Overlay (Menue „Raster"): immer 16 gleiche Zellen, proportional. --- */
.grid-overlay { display: none; }
body.grid-debug .grid-overlay {
  display: grid; position: absolute; inset: 0; z-index: 200; pointer-events: none;
  grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 1fr);
}
.grid-overlay > span {
  border: 1px solid rgba(255, 60, 60, .5);
  display: flex; align-items: flex-start; justify-content: flex-start; padding: 2px 4px;
  font: 700 13px/1 var(--mono, monospace); color: rgba(255, 90, 90, .95); text-shadow: 0 1px 2px #000;
}

/* Drawer-Umschalter: nur auf dem Handy sichtbar, feste Ecken. */
.drawer-toggle { display: none; }
body.is-mobile .drawer-toggle {
  display: flex; align-items: center; justify-content: center;
  position: fixed; top: 8px; z-index: 42;
  width: 46px; height: 46px; border-radius: 12px; cursor: pointer;
  font-size: 22px; line-height: 1; color: var(--ink);
  background: #0e1a15ee; border: 1px solid #ffffff26;
  box-shadow: 0 8px 20px -10px #000, inset 0 1px 0 #ffffff12;
}
body.is-mobile .menu-toggle { left: 8px; }
body.is-mobile .stats-toggle { right: 8px; }
body.is-mobile.menu-open .menu-toggle,
body.is-mobile.stats-open .stats-toggle { background: var(--accent-btn); border-color: var(--accent); }

/* Seitenmenues als Drawer: standardmaessig ausgeblendet, bei ...-open eingeblendet. Volle Hoehe, scrollbar. */
body.is-mobile .menu, body.is-mobile .stats {
  top: 0; height: 100dvh; max-height: 100dvh; overflow-y: auto;
  border-radius: 0; transition: transform .25s ease; z-index: 41;
  scrollbar-width: none;
}
body.is-mobile .menu::-webkit-scrollbar, body.is-mobile .stats::-webkit-scrollbar { display: none; }
body.is-mobile .menu  { transform: translateX(-108%); }
body.is-mobile .stats { transform: translateX(108%); }
body.is-mobile.menu-open  .menu  { transform: none; }
body.is-mobile.stats-open .stats { transform: none; }

/* --- „Feste Aufloesung" am PC (?res=900x420): das Spiel in einen exakten Kasten zwingen, Rest schwarz.
   Die Groessen richten sich per cqh (oben) nach dem Kasten -> nichts wird auf den Desktop hochgestreckt. --- */
body.forced-res { background: #000; overflow: hidden; }
body.forced-res #app {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: var(--res-w, 900px); height: var(--res-h, 420px);
  overflow: hidden; box-shadow: 0 0 0 1px #ffffff2e, 0 0 40px -6px #000;
}
/* Viewport-fixe Elemente in den #app-Kasten holen (sonst kleben sie am Desktop-Rand statt am Kasten). */
body.forced-res .room,
body.forced-res .spotlight,
body.forced-res .drawer-toggle,
body.forced-res .menu,
body.forced-res .stats,
body.forced-res .banner,
body.forced-res .pvp-status,
body.forced-res .hub,
body.forced-res .log { position: absolute; }
/* Drawer im Kasten: volle KASTEN-Hoehe (nicht 100dvh = Desktop-Hoehe). */
body.forced-res .menu, body.forced-res .stats { height: 100%; max-height: 100%; }
