/* ============================================================
   0cards — stijl: de leegte, en licht dat breekt

   Alles speelt zich af in het donker. De achtergrond is diepe ruimte met twee
   verre nevels; panelen zijn vensters van donker glas met een koele lichtrand.
   De vier spelkleuren blijven herkenbaar rood/geel/groen/blauw, en violet en
   cyaan zijn de uiteinden van het spectrum — wat een prisma uit wit licht haalt.
   Daar komt de naam vandaan, en de nul in het logo is die prismaring.

   Contrast loopt hier andersom dan op papier: iets valt op doordat het licht
   geeft, niet doordat het een schaduw werpt.
   ============================================================ */
:root {
  /* Ruimte: van bijna zwart (de leegte) naar diep nachtblauw (de nevel). */
  --bg-0: #05060f;
  --bg-1: #0a0d1f;
  --bg-2: #101530;
  /* Panelen zijn vensters: donker glas met een koele lichtrand. */
  --panel: rgba(16, 21, 48, 0.82);
  --panel-border: rgba(120, 140, 255, 0.18);
  /* De uitklaplijst van een <select> tekent het BESTURINGSSYSTEEM, niet wij.
     Daar werkt doorzichtig glas niet: --panel is halfdoorzichtig en levert dan
     de witte systeemachtergrond op. Vandaar één effen kleur, apart van --panel. */
  --menu-bg: #0a0e20;
  /* Licht op donker; puur wit is te hard tegen zoveel zwart. */
  --text: #e8eaf6;
  --text-dim: #8a91b4;
  /* De vier spelkleuren. */
  --red: #e63946;
  --yellow: #f1c40f;
  --green: #27ae60;
  --blue: #2d6cdf;
  /* Accenten: het licht zélf — violet en cyaan, de uiteinden van het spectrum. */
  --neon: #7c5cff;
  --neon-2: #21d4fd;
  --danger: #ff4d6d;
  /* Bleven staan uit de vorige stijl omdat er opmaak aan hangt; nu in
     ruimtewaarden: goud wordt sterrenlicht, inkt wordt de leegte, papier het
     paneelvlak. */
  --gold: #ffd166;
  --ink: #05060f;
  --paper: #101530;
  --rainbow: linear-gradient(135deg, #e63946, #f1c40f, #27ae60, #2d6cdf, #7c5cff);
  --card-w: 92px;
  --card-h: 134px;
  --radius: 14px;
  /* Kop- en interfaceletter. De Content-Security-Policy laat alleen
     lettertypen van de eigen server toe en er is er nog geen meegeleverd, dus
     dit is een stapel systeemletters. De showletter is nu strak en geometrisch
     in plaats van een houtletter: dat past bij glas en licht. */
  --font: "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-show: "Futura", "Century Gothic", "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body { height: 100%; }

body {
  font-family: var(--font);
  color: var(--text);
  /* De leegte, met twee verre nevels: violet linksboven, cyaan rechtsonder.
     Allebei heel licht van contrast, zodat het achtergrond blijft en niet
     gaat concurreren met de kaarten. */
  background:
    radial-gradient(1200px 700px at 20% -10%, rgba(124, 92, 255, 0.20), transparent 60%),
    radial-gradient(1000px 600px at 90% 110%, rgba(33, 212, 253, 0.14), transparent 60%),
    linear-gradient(160deg, var(--bg-1), var(--bg-0) 70%);
  background-attachment: fixed;
  /* v3.14 — NIET zomaar 100vh. Op een telefoon is `vh` de hoogte die het scherm
     ZOU hebben als de adresbalk weg was; die balk staat er meestal wel. Een
     bladzijde van 100vh is daardoor altijd een stukje hoger dan wat je ziet, en
     dus scroll je terwijl er niets te scrollen valt. `dvh` is de hoogte die je
     ECHT hebt, en --app-h is diezelfde maat door client.js opgemeten via
     visualViewport (voor browsers zonder dvh, en voor de gevallen waarin iOS er
     naast zit). De 100vh blijft als vangnet staan voor wie geen van beide kent. */
  min-height: 100vh;
  min-height: var(--app-h, 100dvh);
  overflow-x: hidden;
}

/* v1.4: de table-asset is nu de textuur van het tafelblad (--felt-img),
   niet meer de paginabodem; de body houdt de neon-gradient. */

.hidden { display: none !important; }

.screen {
  min-height: 100vh;
  min-height: var(--app-h, 100dvh);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px;
}

/* ---------- Panels & buttons ---------- */
.panel {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  padding: 20px;
  backdrop-filter: blur(8px);
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.45);
}

.btn {
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  /* Donker glas met een koele rand: hij komt van de achtergrond af door licht,
     niet door schaduw. */
  background: var(--bg-2);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  padding: 10px 18px;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease, filter 0.12s ease;
}
.btn:hover { filter: brightness(1.03); }
.btn:active { transform: translateY(1px); box-shadow: 0 1px 0 rgba(5, 6, 15, 0.45); }
.btn:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.15); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.btn-primary {
  /* De hoofdknop draagt het violet van het spectrum en gloeit zacht na. */
  background: linear-gradient(135deg, var(--neon), #4a35c9);
  border-color: rgba(160, 140, 255, 0.5);
  color: #fff;
  box-shadow: 0 0 18px rgba(124, 92, 255, 0.45);
}
.btn-secondary {
  /* De tweede stem: dieper blauw met een cyaan rand, het andere uiteinde van
     het spectrum ten opzichte van de violette hoofdknop. */
  background: linear-gradient(135deg, #14406e, #0e2b4c);
  border-color: rgba(33, 212, 253, 0.35);
  color: var(--text);
}
.btn-danger {
  background: linear-gradient(135deg, #8c1d33, #5b0f22);
  border-color: rgba(255, 77, 109, 0.4);
}
.btn-ghost { background: transparent; }
.btn-big { font-size: 18px; padding: 14px 26px; width: 100%; }
.btn-small { font-size: 13px; padding: 6px 12px; }

.hint { color: var(--text-dim); font-size: 13px; text-align: center; }

/* ---------- Logo ---------- */
.logo { display: flex; justify-content: center; align-items: center; }
.logo img { width: min(540px, 92vw); max-width: none; height: auto; }
.logo.small img { max-width: 150px; width: auto; max-height: 44px; }
.logo-text {
  font-size: clamp(44px, 10vw, 84px);
  font-weight: 900;
  letter-spacing: 0.08em;
  background: var(--rainbow);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 18px rgba(124, 92, 255, 0.55));
}
.logo.small .logo-text { font-size: 24px; }

/* ---------- Home ---------- */
.home-inner {
  width: 100%;
  max-width: 1260px;
  margin: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 30px 0;
}
/* ============================================================
   Startscherm: 1 → 2 → 3 kolommen, afhankelijk van de schermbreedte.
     smal   : alles onder elkaar (spelen, meedoen, lobby's, ranglijst)
     middel : links spelen, rechts meedoen + lobby's + ranglijst
     breed  : links spelen, midden meedoen + lobby's, rechts ranglijst
   Mobile-first: de basis is één kolom, de media queries bouwen uit.
   ============================================================ */
.home-columns {
  display: grid;
  grid-template-columns: minmax(0, 460px);
  gap: 16px;
  justify-content: center;
  align-items: start;
}
.home-mid,
.home-side {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

/* Twee kolommen: de middenkolom en de ranglijst delen kolom 2. */
@media (min-width: 880px) {
  .home-columns { grid-template-columns: minmax(0, 440px) minmax(0, 400px); }
  .home-mid { grid-column: 2; grid-row: 1; }
  .home-side { grid-column: 2; grid-row: 2; }
}

/* Drie kolommen: de ranglijst krijgt een eigen kolom naast de rest. */
@media (min-width: 1240px) {
  .home-columns { grid-template-columns: minmax(0, 440px) minmax(0, 380px) minmax(0, 380px); }
  .home-mid { grid-column: 2; grid-row: 1; }
  .home-side { grid-column: 3; grid-row: 1; }
}
.tagline { text-align: center; color: var(--text-dim); margin-top: -6px; }
.home-panel { display: flex; flex-direction: column; gap: 12px; }

.field-label { font-size: 13px; color: var(--text-dim); font-weight: 600; }

input[type="text"], input[type="password"] {
  font-family: inherit;
  font-size: 16px;
  color: var(--text);
  /* Ingevuld formulierveld op een affiche: iets lichter dan het papier
     eromheen, met een dunne inktrand — zoals een invulstrook op een kaartje. */
  background: rgba(21, 26, 58, 0.95);
  border: 1px solid rgba(120, 140, 255, 0.35);
  border-radius: 8px;
  padding: 11px 14px;
  outline: none;
  width: 100%;
  box-shadow: inset 0 1px 2px rgba(120, 140, 255, 0.10);
}
input[type="text"]:focus, input[type="password"]:focus { border-color: var(--neon); box-shadow: 0 0 0 3px rgba(124, 92, 255, 0.22); }

.avatar-picker {
  display: grid;
  grid-template-columns: repeat(5, 1fr); /* 15 avatars = 3 rijen van 5 */
  gap: 8px;
}
.avatar-option {
  font-size: 26px;
  padding: 8px 0;
  text-align: center;
  background: rgba(120, 140, 255, 0.22);
  border: 2px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  transition: transform 0.1s ease, border-color 0.1s ease;
}
.avatar-option:hover { transform: scale(1.1); }
.avatar-option.selected {
  border-color: var(--neon);
  box-shadow: 0 0 14px rgba(124, 92, 255, 0.5);
}

.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--text-dim);
  font-size: 13px;
  margin: 4px 0;
}
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--panel-border); }

.join-row { display: flex; gap: 10px; }
.code-input {
  flex: 1;
  text-transform: uppercase;
  letter-spacing: 0.5em;
  font-weight: 800;
  font-size: 20px;
  text-align: center;
}

/* ---------- Lobby ---------- */
.lobby-inner { width: 100%; max-width: 1100px; display: flex; flex-direction: column; gap: 16px; }
.lobby-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
.lobby-code-wrap { display: flex; align-items: center; gap: 12px; }
.lobby-code-label { color: var(--text-dim); font-size: 13px; }
.lobby-code {
  font-size: 34px;
  font-weight: 900;
  letter-spacing: 0.35em;
  padding-left: 0.2em;
  background: var(--rainbow);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 10px rgba(33, 212, 253, 0.45));
}

.lobby-grid {
  display: grid;
  grid-template-columns: 1fr 1.2fr 1fr;
  gap: 16px;
  align-items: start;
}
/* v3.5: de lobbypanelen hadden helemaal geen intro-animatie, terwijl hun
   INHOUD (de lobbycode letter voor letter, de spelersrijen) wel infadet. Drie
   losse tijdlijnen die tegelijk starten lezen als "door elkaar". Nu komen de
   panelen in leesvolgorde binnen: spelers, instellingen, chat. De volgorde in
   de HTML is op elk breakpoint gelijk aan de visuele volgorde (desktop drie
   kolommen, ≤900px chat onder, ≤640px één kolom), dus vaste delays kloppen
   overal. prefers-reduced-motion zet ze verderop globaal uit. */
.lobby-players-panel  { animation: panelRise 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) both 0.10s; }
.lobby-settings-panel { animation: panelRise 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) both 0.20s; }
.lobby-chat-panel     { animation: panelRise 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) both 0.30s; }

.lobby-grid h2 { font-size: 16px; margin-bottom: 12px; letter-spacing: 0.04em; }
.lobby-grid h3 { font-size: 13px; margin: 10px 0 4px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.08em; }

.lobby-players { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.lobby-player {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(120, 140, 255, 0.20);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  padding: 8px 12px;
}
.lobby-player .avatar { font-size: 24px; }
.lobby-player .p-name { flex: 1; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lobby-player .crown { font-size: 16px; }
.conn-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: #38e07b;
  box-shadow: 0 0 8px rgba(56, 224, 123, 0.8);
  flex: none;
}
.conn-dot.off { background: #5b607e; box-shadow: none; }
.kick-btn {
  background: none; border: none; color: var(--danger);
  font-size: 15px; cursor: pointer; padding: 2px 6px; border-radius: 6px;
}
.kick-btn:hover { background: rgba(255, 77, 109, 0.15); }

/* v3.15 — ELKE uitklaplijst donker, niet alleen de twee die er toevallig aan
   dachten. De lijst die opengaat als je een <select> aanklikt wordt door het
   besturingssysteem getekend en staat standaard op wit; in een spel dat verder
   helemaal donker is springt dat er hard uit. Alleen background-color en color
   worden op een option betrouwbaar overgenomen, dus verder gaan we niet.
   Bewust op `select option` en niet per klasse: zo hoeft niemand eraan te
   denken bij het volgende keuzemenu. */
select option,
select optgroup {
  background-color: var(--menu-bg);
  color: var(--text);
}

/* Bots (v1.3): host-rij om een bot toe te voegen + badge in de spelerslijst */
.bot-row { margin-top: 12px; display: flex; align-items: center; gap: 8px; }
.bot-row select {
  flex: 1;
  min-width: 0;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: rgba(120, 140, 255, 0.24);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 6px 8px;
}
.bot-badge {
  flex: none;
  font-size: 11px;
  font-weight: 800;
  padding: 1px 7px;
  border-radius: 8px;
  background: rgba(124, 92, 255, 0.18);
  color: #c9bfff;
  border: 1px solid rgba(124, 92, 255, 0.5);
  white-space: nowrap;
}

.lobby-actions { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }

.settings-form { display: flex; flex-direction: column; gap: 8px; }
.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 14px;
}
.setting-row select {
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: rgba(120, 140, 255, 0.24);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 6px 8px;
  min-width: 150px;
}
.setting-row input[type="checkbox"] {
  appearance: none;
  width: 42px; height: 24px;
  border-radius: 12px;
  background: #2a2f52;
  position: relative;
  cursor: pointer;
  transition: background 0.15s ease;
  flex: none;
}
.setting-row input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: #cdd2f0;
  transition: transform 0.15s ease;
}
.setting-row input[type="checkbox"]:checked { background: var(--neon); box-shadow: 0 0 10px rgba(124, 92, 255, 0.5); }
.setting-row input[type="checkbox"]:checked::after { transform: translateX(18px); }
.settings-form.readonly select, .settings-form.readonly input { pointer-events: none; opacity: 0.65; }

.lobby-chat-panel { display: flex; flex-direction: column; max-height: 480px; }
.chat-log {
  flex: 1;
  min-height: 200px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px 2px;
  font-size: 14px;
}
.chat-msg .chat-from { font-weight: 700; color: var(--neon-2); margin-right: 6px; }
.chat-msg.system { color: var(--text-dim); font-style: italic; }
.chat-input-row { display: flex; gap: 8px; margin-top: 10px; }

/* ---------- Game layout: ovale 3D-speeltafel (v1.4) ---------- */
:root { --table-tilt: 54deg; --dir-r: 190px; --seat-w: 104px; }

#screen-game { padding: 8px; }
.game-inner {
  width: 100%;
  max-width: 1280px;
  min-height: calc(100vh - 16px);
  min-height: calc(var(--app-h, 100dvh) - 16px);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Tafelscene: gekanteld tafelblad + center-overlay + stoelen rondom */
.table-scene {
  position: relative;
  flex: 1;
  min-height: 320px;
  width: 100%;
}
.table-tilt {
  position: absolute;
  inset: 0;
  perspective: 1600px;
  pointer-events: none;
}
.table-felt {
  position: absolute;
  left: 50%; top: 50%;
  /* --felt-breed komt uit client.js (zie tafelBreedte) en hangt af van het
     aantal spelers. Alleen de breedte: de hoogte terugbrengen maakte er een
     klein ovaal in een leeg veld van. */
  width: calc(min(84%, 880px) * var(--felt-breed, 1));
  height: min(148%, 840px);
  transform: translate(-50%, -50%) rotateX(var(--table-tilt));
  border-radius: 50%;
  background:
    radial-gradient(ellipse at 50% 32%, rgba(124, 92, 255, 0.18), transparent 62%),
    var(--felt-img, radial-gradient(ellipse at center, #15214b 0%, #0b1230 55%, #060a1c 100%));
  background-size: cover;
  background-position: center;
  border: 12px solid #191330;
  box-shadow:
    0 0 0 3px rgba(124, 92, 255, 0.35),
    0 34px 70px rgba(0, 0, 0, 0.65),
    inset 0 0 90px rgba(0, 0, 0, 0.55);
}

/* currentColor-aura op het tafelblad */
.table-aura {
  position: absolute;
  inset: 5%;
  border-radius: 50%;
  background: radial-gradient(ellipse at center, var(--aura-color, rgba(124, 92, 255, 0.3)), transparent 68%);
  animation: glowPulse 3s ease-in-out infinite;
  pointer-events: none;
}

/* Richting-indicator: pijlenring om het tafelmidden, draait met direction mee */
.direction-ring {
  position: absolute;
  left: 50%; top: 50%;
  width: 0; height: 0;
  animation: dirSpin 16s linear infinite;
}
.direction-ring.reversed { animation-direction: reverse; }
@keyframes dirSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.dir-arrow {
  position: absolute;
  left: 0; top: 0;
  font-size: 22px;
  line-height: 1;
  color: rgba(255, 209, 102, 0.5);
  text-shadow: 0 0 12px rgba(255, 209, 102, 0.75);
  transform: translate(-50%, -50%) rotate(calc(var(--i) * 45deg)) translateX(var(--dir-r)) rotate(90deg);
  user-select: none;
}
.direction-ring.reversed .dir-arrow {
  transform: translate(-50%, -50%) rotate(calc(var(--i) * 45deg)) translateX(var(--dir-r)) rotate(-90deg);
}

/* Center-overlay: HUD, stapels, chaos, lastAction (niet gekanteld, klikbaar) */
.table-center {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  pointer-events: none;
}
.table-center > * { pointer-events: auto; }
.round-hud {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: rgba(120, 140, 255, 0.22);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  padding: 2px 12px;
  min-height: 20px;
}
.pile-area { display: flex; align-items: center; gap: clamp(14px, 4vw, 44px); }

.deck-pile { position: relative; cursor: pointer; }
.deck-pile.disabled { cursor: default; }
.deck-pile:not(.disabled):hover .card-back { transform: translateY(-4px); }
.deck-count {
  position: absolute;
  bottom: -8px; right: -8px;
  background: var(--bg-2);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  font-size: 12px;
  font-weight: 700;
  padding: 2px 8px;
}

.discard-pile { position: relative; }
.top-card-slot { position: relative; border-radius: 12px; }
.top-card-slot .card { box-shadow: 0 0 26px 6px var(--glow-color, rgba(124, 92, 255, 0.55)); }
/* 3D-plof: extra slagschaduw terwijl de topkaart landt (transform doet WAAPI) */
.top-card-slot .card.plof {
  box-shadow: 0 26px 46px rgba(0, 0, 0, 0.7), 0 0 26px 6px var(--glow-color, rgba(124, 92, 255, 0.55));
}

.pending-draw {
  font-size: 18px;
  font-weight: 800;
  color: #ffd166;
  background: rgba(90, 55, 0, 0.5);
  border: 1px solid rgba(255, 209, 102, 0.5);
  border-radius: 12px;
  padding: 6px 16px;
  animation: badgeGlow 1s ease-in-out infinite;
}

.chaos-wrap { display: flex; align-items: center; gap: 8px; width: min(360px, 80vw); }
.chaos-bolt { font-size: 18px; filter: drop-shadow(0 0 6px rgba(241, 196, 15, 0.8)); }
.chaos-bar {
  flex: 1;
  height: 12px;
  border-radius: 6px;
  background: rgba(120, 140, 255, 0.24);
  border: 1px solid var(--panel-border);
  overflow: hidden;
}
.chaos-fill {
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  border-radius: 6px;
  background: linear-gradient(90deg, #f1c40f, #ff8c42, var(--danger));
  box-shadow: 0 0 10px rgba(241, 196, 15, 0.6);
  transition: transform 0.4s cubic-bezier(0.3, 1.2, 0.4, 1);
}
.chaos-wrap.high .chaos-fill { animation: chaosFlicker 0.5s linear infinite; }
@keyframes chaosFlicker { 50% { opacity: 0.6; } }
.chaos-value { font-size: 12px; color: var(--text-dim); min-width: 36px; }

.last-action {
  min-height: 22px;
  font-size: 14px;
  color: var(--text-dim);
  text-align: center;
  padding: 0 12px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
}

/* ---------- Stoelen rondom de tafel (v1.4 §1) ---------- */
.seats { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.seat {
  position: absolute;
  left: 0; top: 0;
  will-change: transform;
  transition: transform 0.55s cubic-bezier(0.3, 1.15, 0.45, 1);
  pointer-events: none;
}
/* Eerste plaatsing: geen transitie (anders schuift de stoel vanaf (0,0) in) */
.seat.seat-new { transition: none; }
.seat-body {
  pointer-events: auto;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: var(--seat-w);
}
.seat.disconnected .seat-body { opacity: 0.55; }

.seat-avatar-wrap {
  position: relative;
  width: 66px; height: 66px;
  display: flex; align-items: center; justify-content: center;
}
.seat-avatar {
  font-size: 36px;
  width: 62px; height: 62px;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel);
  border: 2px solid var(--panel-border);
  border-radius: 50%;
  box-shadow: 0 10px 22px rgba(0, 0, 0, 0.55);
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
}
.seat.is-turn .seat-avatar {
  border-color: var(--neon-2);
  box-shadow: 0 0 22px rgba(255, 209, 102, 0.8);
}
.seat-avatar-wrap::before {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 209, 102, 0.5), transparent 70%);
  opacity: 0;
  pointer-events: none;
}
.seat.is-turn .seat-avatar-wrap::before { animation: haloPulse 1.4s ease-in-out infinite; }
@keyframes haloPulse {
  0%, 100% { opacity: 0.4; transform: scale(0.95); }
  50% { opacity: 1; transform: scale(1.12); }
}

.seat .conn-dot {
  position: absolute;
  bottom: 2px; right: 2px;
  z-index: 3;
  width: 12px; height: 12px;
  border: 2px solid #0a0d1f;
}
.seat .crown-mini { position: absolute; top: -10px; left: 0; font-size: 15px; z-index: 3; }

/* v3.22 — een flexregel, zodat de rangmeter naast de naam past. De ellipsis
   verhuisde naar de tekst-span: op de regel zelf zou een lange naam de meter
   als eerste wegduwen, en juist die moet blijven staan. */
.seat-name {
  font-size: 12px;
  font-weight: 600;
  max-width: var(--seat-w);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.85);
}
.seat-naam-tekst {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* De rangmeter. Vaste breedte, ongeacht het niveau: de naamregel verliest
   altijd precies evenveel ruimte of helemaal niets. */
.rang-merk {
  display: inline-flex;
  align-items: flex-end;
  gap: 1px;
  flex: none;
  width: 14px;
  height: 11px;
  cursor: help;
}
.rang-merk i {
  display: block;
  width: 2px;
  /* Gedoofd met een omtrek, zodat je ze ook kunt TELLEN als de kleur wegvalt. */
  background: rgba(255, 255, 255, 0.14);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22);
  border-radius: 1px;
}
.rang-merk i:nth-child(1) { height: 4px; }
.rang-merk i:nth-child(2) { height: 6px; }
.rang-merk i:nth-child(3) { height: 8px; }
.rang-merk i:nth-child(4) { height: 11px; }
.rang-merk i.aan { background: var(--rang-kleur, #d9975a); box-shadow: none; }

/* Brons, zilver, goud, prisma — dezelfde rangorde als de badges, maar plat en
   hoekig zodat het in niets op een medaille of een schildje lijkt. */
.rang-merk.rang-1 { --rang-kleur: #d9975a; }
.rang-merk.rang-2 { --rang-kleur: #9aa3b8; }
.rang-merk.rang-3 { --rang-kleur: #ffd166; }
.rang-merk.rang-4 i.aan {
  background: linear-gradient(180deg, #7c5cff, #21d4fd 60%, #ffd166);
}

@media (max-width: 640px) {
  .rang-merk { width: 12px; height: 9px; }
  .rang-merk i:nth-child(4) { height: 9px; }
}
@media (max-height: 560px) and (orientation: landscape) {
  .rang-merk { width: 11px; height: 8px; }
  .rang-merk i:nth-child(3) { height: 6px; }
  .rang-merk i:nth-child(4) { height: 8px; }
}

/* Waaier van kaartruggen (handaantal) + altijd leesbare teller */
.seat-fan {
  position: relative;
  width: 92px; height: 32px;
  display: flex; align-items: flex-start; justify-content: center;
}
.mini-back {
  position: absolute;
  left: 50%; top: 0;
  width: 17px; height: 25px;
  margin-left: -8.5px;
  border-radius: 3px;
  border: 1px solid rgba(124, 92, 255, 0.65);
  background-image: var(--back-img, linear-gradient(150deg, #171b36, #070912));
  background-size: cover;
  background-position: center;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.55);
  transform-origin: 50% 95%;
}
.seat-count {
  position: relative;
  z-index: 2;
  margin-top: 13px;
  font-size: 11px;
  font-weight: 800;
  color: var(--text);
  background: rgba(16, 21, 48, 0.88);
  border: 1px solid var(--panel-border);
  border-radius: 9px;
  padding: 0 7px;
  line-height: 16px;
}

/* Timer-ring om de beurtspeler-avatar (kleur via JS: groen→geel→rood) */
.timer-ring {
  position: absolute;
  inset: -4px;
  transform: rotate(-90deg);
  pointer-events: none;
  z-index: 2;
}
.timer-ring circle { fill: none; stroke-width: 3.5; }
.timer-ring .ring-bg { stroke: rgba(255, 255, 255, 0.1); }
.timer-ring .ring-fg { stroke: #38e07b; stroke-linecap: round; }
.timer-ring.urgent { animation: urgentPulse 0.5s ease-in-out infinite; }

/* Groot secondengetal bij de stoel van de beurtspeler */
.seat-seconds {
  position: absolute;
  top: -12px; right: -24px;
  z-index: 4;
  font-size: 22px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 10px rgba(0, 0, 0, 0.9), 0 1px 3px rgba(0, 0, 0, 0.9);
}
.seat-seconds.urgent, .my-countdown.urgent { animation: urgentPulse 0.55s ease-in-out infinite; }
@keyframes urgentPulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.2); opacity: 0.8; }
}

/* Rood pulserende "1!"-alert (1 kaart, nog niet geroepen) */
.seat-alert {
  position: absolute;
  top: -8px; left: -12px;
  z-index: 4;
  font-size: 13px;
  font-weight: 900;
  color: #fff;
  background: linear-gradient(135deg, var(--danger), #b3123a);
  border-radius: 50%;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 12px rgba(255, 45, 77, 0.9);
  animation: alertPulse 0.8s ease-in-out infinite;
}
@keyframes alertPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.25); }
}

.seat .badges { display: flex; gap: 4px; min-height: 16px; justify-content: center; flex-wrap: wrap; }
.badge {
  font-size: 10px;
  font-weight: 800;
  padding: 1px 6px;
  border-radius: 8px;
  letter-spacing: 0.03em;
}
.badge-frozen { background: rgba(255, 209, 102, 0.2); color: #9be8ff; border: 1px solid rgba(255, 209, 102, 0.5); }
.badge-bot { background: rgba(124, 92, 255, 0.18); color: #c9bfff; border: 1px solid rgba(124, 92, 255, 0.5); }
.badge-zerocards {
  background: var(--rainbow);
  color: #0a0d1f;
  animation: badgeGlow 1.2s ease-in-out infinite;
}
@keyframes badgeGlow {
  0%, 100% { opacity: 0.82; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.07); }
}
/* v3.19 — GROTER. Dit is de knop waar je haast bij hebt en die je op een
   telefoon met een duim moet raken; 11px tekst in een vakje van 3 bij 8 was
   daar te klein voor. De minimale maat is nu 34 px hoog, ruim boven wat als
   comfortabel raakdoel geldt. */
.catch-btn {
  position: absolute;
  top: -12px; right: -18px;
  min-width: 34px;
  min-height: 34px;
  font-size: 14px;
  font-weight: 900;
  letter-spacing: 0.02em;
  background: linear-gradient(135deg, var(--danger), #b3123a);
  color: #fff;
  border: 2px solid rgba(255, 255, 255, 0.28);
  border-radius: 12px;
  padding: 5px 11px;
  cursor: pointer;
  z-index: 5;
  box-shadow: 0 4px 14px rgba(230, 57, 70, 0.5);
  animation: badgeGlow 1s ease-in-out infinite;
}

/* Tijdens de bedenktijd: gedoofd, met de seconden erin. Niet verbergen — je
   moet ZIEN dat er iets aankomt en hoelang je nog moet wachten. */
.catch-btn.wacht {
  background: linear-gradient(135deg, #3a4270, #262c4d);
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow: none;
  cursor: not-allowed;
  animation: none;
  font-variant-numeric: tabular-nums;
}

/* Emote-ballon boven de stoel */
.seat-balloons {
  position: absolute;
  left: 50%; bottom: calc(100% + 2px);
  width: 0; height: 0;
  pointer-events: none;
  z-index: 7;
}
.emote-balloon {
  position: absolute;
  left: 0; bottom: 0;
  transform: translateX(-50%);
  font-size: 32px;
  line-height: 1;
  background: rgba(16, 21, 48, 0.92);
  border: 1px solid var(--panel-border);
  border-radius: 16px 16px 16px 4px;
  padding: 8px 10px;
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.5);
  animation: emotePop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  will-change: transform, opacity;
}
.emote-balloon.leaving { animation: emoteOut 0.32s ease both; }
/* Onder de stoel: voor de bovenste stoel, waar er boven geen ruimte is. Het
   staartje van de ballon zit dan aan de andere kant. */
.seat-balloons.balloons-onder { bottom: auto; top: calc(100% + 2px); }
.seat-balloons.balloons-onder .emote-balloon {
  bottom: auto;
  top: 0;
  border-radius: 4px 16px 16px 16px;
  animation-name: emotePopOnder;
}
.seat-balloons.balloons-onder .emote-balloon.leaving { animation-name: emoteOutOnder; }
@keyframes emotePopOnder {
  0% { opacity: 0; transform: translateX(-50%) translateY(-16px) scale(0.2); }
  60% { opacity: 1; transform: translateX(-50%) translateY(6px) scale(1.12); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
@keyframes emoteOutOnder {
  to { opacity: 0; transform: translateX(-50%) translateY(-10px) scale(0.7); }
}
@keyframes emotePop {
  0% { opacity: 0; transform: translateX(-50%) translateY(16px) scale(0.2); }
  60% { opacity: 1; transform: translateX(-50%) translateY(-6px) scale(1.12); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
@keyframes emoteOut { to { opacity: 0; transform: translateX(-50%) translateY(-18px) scale(0.6); } }

/* ---------- Mijn zone (hand, knoppen, emotes) ---------- */
.my-area {
  position: relative;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding-bottom: 8px;
}
/* De hoogte staat vast op die van de VOLSTE stand (klok + Pas + de roepknop).
   Anders groeit deze rij zodra je aan de beurt bent en schuift alles eronder
   — je hand, je naam en de emoji-balk — 24 pixels omlaag, precies wanneer je
   wilt klikken. */
.my-buttons {
  display: flex;
  gap: 12px;
  min-height: 68px;
  align-items: center;
  justify-content: center;
}
.my-countdown {
  font-size: 30px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 14px rgba(0, 0, 0, 0.85);
  min-width: 74px;
  text-align: center;
}
.btn-zerocards {
  font-size: 18px;
  font-weight: 900;
  letter-spacing: 0.06em;
  color: #0a0d1f;
  background: var(--rainbow);
  border: none;
  animation: zeroCardsPulse 0.9s ease-in-out infinite;
}
@keyframes zeroCardsPulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 14px rgba(255, 255, 255, 0.35); }
  50% { transform: scale(1.08); box-shadow: 0 0 30px rgba(255, 255, 255, 0.75); }
}

/* v1.7 §6: hand is een horizontale scroller (wiel/drag/touch); auto-margins op
   de randen centreren de waaier zolang hij past. */
.my-hand {
  display: flex;
  justify-content: flex-start;
  padding: 34px 10px 6px;
  max-width: 100%;
  min-height: calc(var(--card-h) + 42px);
  perspective: 900px;
  overflow-x: auto;
  /* Verticaal nooit scrollen: een kaart die oplicht of omhoog komt vergroot de
     scroll-overflow en liet anders héél kort een scrollbalk verschijnen. */
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  /* Scrollbalk verbergen (scrollen blijft werken met wiel, slepen en touch) —
     zo kan hij ook horizontaal niet in en uit beeld flitsen tijdens animaties. */
  scrollbar-width: none;
  -ms-overflow-style: none;
  cursor: grab;
}
.my-hand::-webkit-scrollbar { width: 0; height: 0; }
.my-hand.dragging { cursor: grabbing; user-select: none; }
.my-hand .card { margin-left: calc(var(--card-w) * -0.45); flex: none; }
.my-hand .card:first-child { margin-left: auto; }
.my-hand .card:last-child { margin-right: auto; }
/* Grotere hit-areas op speelbare kaarten (overflow moet daarvoor zichtbaar zijn) */
.my-hand .card { overflow: visible; }
.my-hand .card.playable::before,
.my-hand .card.jumpable::before {
  content: "";
  position: absolute;
  inset: -14px -10px -8px;
}
/* Touch: eerste tik selecteert (omhoog + gloed + naamlabel), tweede tik speelt */
.my-hand .card.tap-selected {
  transform: translateY(-24px) scale(1.04);
  z-index: 7;
  box-shadow: 0 0 22px rgba(255, 209, 102, 0.85), 0 18px 26px rgba(0, 0, 0, 0.6);
}
.card-tap-label {
  position: absolute;
  left: 50%; top: -30px;
  transform: translateX(-50%);
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
  color: var(--text);
  background: rgba(120, 140, 255, 0.30);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 2px 8px;
  pointer-events: none;
  z-index: 8;
}
/* Toetsenbordfocus op de hand (←/→ + Enter) */
.my-hand .card.kb-focus {
  outline: 3px solid var(--neon-2);
  outline-offset: 2px;
}
.my-footer {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  justify-content: center;
}
.my-info { display: flex; gap: 12px; align-items: center; font-size: 14px; }
.my-name { font-weight: 700; }
.my-turn-hint { color: var(--neon-2); font-weight: 700; min-height: 18px; }

/* Stoppen (v2.6): bewust rustig — hij staat naast de eigen naam, niet bij de
   speelknoppen, zodat je er midden in een beurt niet per ongeluk op drukt. */
.btn-quit {
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-dim);
  background: transparent;
  border: 1px solid var(--panel-border);
  opacity: 0.65;
  box-shadow: none;
  transform: none;
}
.btn-quit:hover:not(:disabled) {
  opacity: 1;
  color: #ffd9de;
  border-color: rgba(255, 90, 120, 0.65);
  background: rgba(255, 60, 90, 0.12);
  transform: none;
}

/* Emote-balk (v1.4 §3) */
.emote-bar { display: flex; gap: 4px; flex-wrap: wrap; justify-content: center; }
.emote-btn {
  font-size: 19px;
  line-height: 1;
  color: var(--text);
  background: rgba(16, 21, 48, 0.75);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  width: 36px; height: 36px;
  padding: 0;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.emote-btn:hover { transform: translateY(-3px) scale(1.12); box-shadow: 0 0 12px rgba(124, 92, 255, 0.5); }
.emote-btn:active { transform: scale(0.9); }

/* ---------- Cards ---------- */
.card {
  width: var(--card-w);
  height: var(--card-h);
  border-radius: 12px;
  position: relative;
  background: var(--card-bg, #223);
  border: 3px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
  user-select: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
  color: #fff;
  overflow: hidden;
}
.card[data-color="red"] { --card-bg: linear-gradient(150deg, #f0525f, #b31f2c); }
.card[data-color="yellow"] { --card-bg: linear-gradient(150deg, #f7d34a, #c99b06); }
.card[data-color="green"] { --card-bg: linear-gradient(150deg, #34c974, #17813f); }
.card[data-color="blue"] { --card-bg: linear-gradient(150deg, #4d86ec, #1c4bb0); }
.card[data-color="wild"] {
  --card-bg: linear-gradient(150deg, #1b1e33, #05060f);
  border-color: transparent;
  background:
    linear-gradient(150deg, #1b1e33, #05060f) padding-box,
    var(--rainbow) border-box;
}
.card .corner {
  position: absolute;
  font-size: 15px;
  font-weight: 900;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  line-height: 1;
}
.card .corner.tl { top: 6px; left: 8px; }
.card .corner.br { bottom: 6px; right: 8px; transform: rotate(180deg); }
.card .center {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.card .center .big-num {
  font-size: 52px;
  font-weight: 900;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.55);
}
/* Het cijfer als beeld. De hoogte is vast en de breedte volgt, want cijfers
   horen even hoog te zijn — een 1 is nu eenmaal smaller dan een 8. */
.card .center .big-num-img {
  height: 62px;
  width: auto;
  max-width: 86%;
  display: block;
  pointer-events: none;
}
.card .center svg { width: 58%; height: 58%; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5)); }
.card .center img { width: 62%; height: 62%; object-fit: contain; filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.6)); }

/* Kaart-artwork (v1.3): kleur-frame als achtergrond (cover), overlays leesbaar houden */
.card.has-frame {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.card.has-frame .corner {
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75), 0 0 8px rgba(0, 0, 0, 0.45);
}
.card.has-frame .center .big-num {
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.7), 0 0 12px rgba(0, 0, 0, 0.45);
}
/* "+2"/"+4"-overlay op tekstloze actie-iconen (draw2/wild4) */
.card .center .icon-overlay {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  font-size: 26px;
  font-weight: 900;
  color: #fff;
  text-shadow: 0 2px 5px rgba(0, 0, 0, 0.8), 0 0 10px rgba(0, 0, 0, 0.55);
  pointer-events: none;
}

.card-back {
  --card-bg: linear-gradient(150deg, #171b36, #070912);
  border-color: rgba(124, 92, 255, 0.6);
  display: flex; align-items: center; justify-content: center;
}
.card-back::after {
  content: "P";
  font-size: 44px;
  font-weight: 900;
  background: var(--rainbow);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.card-back.has-img::after { content: none; }
.card-back img { width: 100%; height: 100%; object-fit: cover; border-radius: 9px; }

/* Hand interactivity — speelbare kaarten liften omhoog met slagschaduw (v1.4) */
.my-hand .card.playable {
  cursor: pointer;
  filter: brightness(1.08);
  transform: translateY(-10px);
  box-shadow: 0 0 16px rgba(255, 209, 102, 0.55), 0 16px 24px rgba(0, 0, 0, 0.55);
}
.my-hand .card.playable:hover { transform: translateY(-18px) scale(1.05); z-index: 5; }
.my-hand .card:not(.playable):not(.jumpable) { filter: brightness(0.6) saturate(0.7); }
.my-hand .card.jumpable {
  cursor: pointer;
  box-shadow: 0 0 18px rgba(241, 196, 15, 0.8), 0 4px 14px rgba(0, 0, 0, 0.5);
}
.my-hand .card.jumpable:hover { transform: translateY(-18px) scale(1.05); z-index: 5; }
/* v2.4 §1: kaart die alléén door een verborgen regel geblokkeerd is (huisregel
   "laatste kaart = cijfer" of "alleen de zojuist getrokken kaart"). Kleur en
   soort kloppen wél, dus dat verdient een eigen, zichtbare markering: licht
   doorschijnend met een slotje-cursor — vóórdat je erop klikt. */
.my-hand .card.blocked-rule {
  cursor: not-allowed;
  opacity: 0.55;
}
.my-hand .card.blocked-rule::after {
  content: "🔒";
  position: absolute;
  top: 4px;
  left: 4px;
  font-size: 14px;
  line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.85));
  pointer-events: none;
  z-index: 2;
}
.jump-flash {
  position: absolute;
  top: 4px; right: 4px;
  font-size: 18px;
  filter: drop-shadow(0 0 5px rgba(241, 196, 15, 1));
  z-index: 2;
}

/* Fly animation (WAAPI stuurt transform/opacity aan) */
.fly-card {
  position: fixed;
  z-index: 90;
  margin: 0;
  pointer-events: none;
  will-change: transform, opacity;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-8px); }
  40% { transform: translateX(8px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(5px); }
}
.shake { animation: shake 0.4s ease; }

/* ---------- Overlays ---------- */
.overlay {
  position: fixed;
  inset: 0;
  /* Ruimtegrond, geen tentdoekbruin: deze laag ligt over het hele scherm. */
  background: rgba(5, 6, 15, 0.75);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 16px;
}
.overlay-box {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  padding: 26px;
  width: min(420px, 94vw);
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-items: center;
  text-align: center;
  box-shadow: 0 12px 60px rgba(0, 0, 0, 0.6);
}
.overlay-box.overlay-wide { width: min(640px, 96vw); }
.overlay-box h2 { font-size: 20px; }
.overlay-buttons { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; justify-content: center; }

.color-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  width: 100%;
}
.color-swatch {
  height: 90px;
  border: 3px solid rgba(255, 255, 255, 0.7);
  border-radius: 14px;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.color-swatch:hover { transform: scale(1.06); }
.color-swatch[data-color="red"] { background: var(--red); box-shadow: 0 0 18px rgba(230, 57, 70, 0.6); }
.color-swatch[data-color="yellow"] { background: var(--yellow); box-shadow: 0 0 18px rgba(241, 196, 15, 0.6); }
.color-swatch[data-color="green"] { background: var(--green); box-shadow: 0 0 18px rgba(39, 174, 96, 0.6); }
.color-swatch[data-color="blue"] { background: var(--blue); box-shadow: 0 0 18px rgba(45, 108, 223, 0.6); }

.target-list { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.target-option {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  background: rgba(120, 140, 255, 0.22);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  padding: 10px 16px;
  cursor: pointer;
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.target-option:hover { border-color: var(--neon-2); transform: translateX(4px); }
.target-option .avatar { font-size: 24px; }
.target-option .t-count { margin-left: auto; color: var(--text-dim); font-size: 13px; }

.extra-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  /* Bewust GÉÉN overflow: bij het kiezen van een kaart wil je alle opties in
     één oogopslag zien. In plaats van schuiven worden de kaarten kleiner — zie
     de stappen hieronder, die de client zet via data-aantal. */
}
/* Hoe meer keuzes, hoe kleiner de kaarten. De maatvariabelen doen het werk,
   dus hoeken, cijfer en kleurenblind-vormen schalen vanzelf mee. */
.extra-list[data-aantal="veel"]      { --card-w: 76px; --card-h: 111px; gap: 8px; }
.extra-list[data-aantal="heelveel"]  { --card-w: 62px; --card-h: 90px;  gap: 7px; }
.extra-list[data-aantal="enorm"]     { --card-w: 50px; --card-h: 73px;  gap: 6px; }
.extra-list .card { cursor: pointer; }
.extra-list .card:hover { transform: translateY(-8px) scale(1.05); }

/* Scores */
.scores-subtitle { color: var(--text-dim); }
.scores-table { width: 100%; border-collapse: collapse; }
.scores-table th, .scores-table td { padding: 8px 12px; text-align: left; }
.scores-table th { color: var(--text-dim); font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; }
.scores-table tbody tr { border-top: 1px solid var(--panel-border); }
.scores-table tr.winner td { color: #ffd166; font-weight: 800; }
.scores-table td.score-cell { text-align: right; font-variant-numeric: tabular-nums; }

/* Storm flash */
.storm-flash {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at center, rgba(124, 92, 255, 0.5), rgba(5, 6, 15, 0.92));
  animation: stormIn 0.25s ease;
}
@keyframes stormIn { from { opacity: 0; } to { opacity: 1; } }
.storm-flash.leaving { animation: stormOut 0.4s ease forwards; }
@keyframes stormOut { to { opacity: 0; } }
.storm-inner { text-align: center; animation: stormZoom 0.5s cubic-bezier(0.2, 1.4, 0.4, 1); }
@keyframes stormZoom { from { transform: scale(0.4); } to { transform: scale(1); } }
.storm-icon { font-size: 80px; filter: drop-shadow(0 0 30px rgba(241, 196, 15, 0.9)); }
.storm-name {
  font-size: clamp(34px, 8vw, 64px);
  font-weight: 900;
  letter-spacing: 0.12em;
  background: var(--rainbow);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.storm-desc { font-size: 18px; color: var(--text); margin-top: 8px; }

/* Toasts */
/* LINKSONDER, niet boven-midden.
   De stoelen liggen op een ellips rond de tafel; bij elk EVEN spelersaantal
   staat er precies één boven-midden, met de betrap-knop eraan. Nagerekend met
   de formule uit layoutSeats en in de browser gemeten maten botste de oude
   plek bij 7 van de 9 spelersaantallen, op alle drie de geteste formaten.
   Linksboven en rechtsboven botsen ook (6 tot 7 van de 9); linksonder valt
   buiten de ellips en raakt bij geen enkel aantal een stoel.
   De nieuwste melding hoort onderaan te staan, het dichtst bij je hand en je
   blik. De kolom is aan de ONDERKANT verankerd en groeit naar boven, dus een
   gewone `column` doet dat al: het laatst toegevoegde kind staat onderaan.
   (`column-reverse` deed precies het omgekeerde.) */
.toasts {
  position: fixed;
  bottom: 96px;
  left: 12px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
  pointer-events: none;
  width: min(320px, 78vw);
}
.toast {
  background: rgba(16, 21, 48, 0.95);
  border: 1px solid var(--panel-border);
  border-left: 4px solid var(--neon-2);
  border-radius: 10px;
  padding: 10px 18px;
  font-size: 14px;
  font-weight: 600;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
  animation: toastIn 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
  max-width: 100%;
}
.toast.error { border-left-color: var(--danger); }
/* Smalle standen: daar is geen enkele hoek écht vrij — de stoelen staan langs
   de bovenrand en je eigen kaarten vullen de onderkant. De kolom blijft
   linksonder (het minst schadelijk: daar dekt hij hooguit je eigen hand af, en
   nooit de betrap-knop van een ander), maar wordt smaller en kruipt dichter
   naar de emoji-balk zodat hij zo min mogelijk beslaat. */
@media (max-width: 640px), (max-height: 560px) {
  .toasts { bottom: 74px; width: min(260px, 70vw); gap: 6px; }
  .toast { padding: 8px 13px; font-size: 13px; border-radius: 9px; }
}
.toast.leaving { animation: toastOut 0.3s ease forwards; }
@keyframes toastIn {
  0% { opacity: 0; transform: translateY(24px) scale(0.85); }
  60% { opacity: 1; transform: translateY(-3px) scale(1.02); }
  100% { opacity: 1; transform: none; }
}
@keyframes toastOut { to { opacity: 0; transform: translateY(12px) scale(0.9); } }

.confetti-canvas { position: fixed; inset: 0; z-index: 150; pointer-events: none; width: 100vw; height: 100vh; }

.btn-mute {
  position: fixed;
  bottom: 12px;
  right: 12px;
  z-index: 210;
  font-size: 18px;
  background: rgba(16, 21, 48, 0.8);
  border: 1px solid var(--panel-border);
  border-radius: 50%;
  width: 44px; height: 44px;
  cursor: pointer;
  /* Zonder deze regel erft hij de zwarte standaardkleur van een knop, en dat
     is onleesbaar op donker glas. */
  color: var(--text);
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .lobby-grid { grid-template-columns: 1fr 1fr; }
  .lobby-chat-panel { grid-column: 1 / -1; }
}
@media (max-width: 640px) {
  /* Mobiel (v1.4): tafel minder gekanteld, stoelen compacter, alles klikbaar */
  :root {
    --card-w: 68px; --card-h: 100px;
    --table-tilt: 38deg; --dir-r: 116px; --seat-w: 78px;
  }
  .lobby-grid { grid-template-columns: 1fr; }
  .table-scene { min-height: 300px; }
  .table-felt {
    width: calc(min(97%, 560px) * var(--felt-breed, 1));
    height: min(160%, 680px);
    border-width: 8px;
  }
  .seat-avatar-wrap { width: 50px; height: 50px; }
  .seat-avatar { width: 46px; height: 46px; font-size: 26px; }
  .seat-name { font-size: 10px; }
  .seat-fan { width: 66px; height: 26px; }
  .mini-back { width: 13px; height: 19px; margin-left: -6.5px; }
  .seat-count { margin-top: 9px; font-size: 10px; }
  .seat-seconds { font-size: 17px; top: -8px; right: -15px; }
  .seat-alert { width: 22px; height: 22px; font-size: 11px; }
  .dir-arrow { font-size: 16px; }
  .round-hud { font-size: 10px; }
  .my-countdown { font-size: 24px; min-width: 60px; }
  .my-buttons { min-height: 56px; }
  .emote-btn { width: 32px; height: 32px; font-size: 16px; }
  .extra-list[data-aantal="veel"]     { --card-w: 58px; --card-h: 85px; gap: 6px; }
  .extra-list[data-aantal="heelveel"] { --card-w: 48px; --card-h: 70px; gap: 5px; }
  .extra-list[data-aantal="enorm"]    { --card-w: 40px; --card-h: 58px; gap: 4px; }
  .my-hand {
    padding: 28px 14px 10px;
    -webkit-overflow-scrolling: touch;
  }
  .my-hand .card { margin-left: calc(var(--card-w) * -0.35); }
  .card .center .big-num { font-size: 38px; }
  .card .center .big-num-img { height: 46px; }
  .lobby-code { font-size: 26px; }
}

/* ============================================================
   FX-laag (addendum v1.1) — alleen transform/opacity animaties
   ============================================================ */

/* Ambient canvas achter alles */
.ambient-canvas {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.6s ease;
}
/* Alleen .screen: .btn-mute en .toasts zijn position:fixed en moeten dat blijven. */
.screen { position: relative; z-index: 1; }

/* Vaste effectlaag boven het spel, onder toasts */
.fx-layer {
  position: fixed;
  inset: 0;
  z-index: 140;
  pointer-events: none;
  overflow: hidden;
}

/* Spotlight bij beurtwissel */
.turn-prisma {
  position: fixed;
  left: 0; top: 0;
  width: 240px; height: 240px;
  z-index: 2;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 209, 102, 0.22), rgba(124, 92, 255, 0.10) 55%, transparent 72%);
  pointer-events: none;
  will-change: transform, opacity;
}

/* Logo-prismagloed (v2.7 §3) — vervangt de oude rechthoekige ::after-sweep.
   Alleen filter: geen extra box, geen layout-shift. De vrije lichtstralen
   zelf tekent fx.js op de ambient-canvas achter het logo. */
.logo { position: relative; }
.logo-text,
.logo img { animation: logoPrismGlow 16s ease-in-out infinite; }
.logo.small .logo-text,
.logo.small img { animation-name: logoPrismGlowSmall; }
@keyframes logoPrismGlow {
  0%, 100% {
    filter: drop-shadow(0 0 14px rgba(230, 57, 70, 0.34)) drop-shadow(0 0 30px rgba(124, 92, 255, 0.46));
  }
  25% {
    filter: drop-shadow(0 0 15px rgba(241, 196, 15, 0.34)) drop-shadow(0 0 32px rgba(255, 209, 102, 0.44));
  }
  50% {
    filter: drop-shadow(0 0 14px rgba(39, 174, 96, 0.32)) drop-shadow(0 0 30px rgba(45, 108, 223, 0.46));
  }
  75% {
    filter: drop-shadow(0 0 16px rgba(255, 209, 102, 0.36)) drop-shadow(0 0 32px rgba(124, 92, 255, 0.48));
  }
}
@keyframes logoPrismGlowSmall {
  0%, 100% { filter: drop-shadow(0 0 5px rgba(230, 57, 70, 0.30)) drop-shadow(0 0 11px rgba(124, 92, 255, 0.42)); }
  25% { filter: drop-shadow(0 0 6px rgba(241, 196, 15, 0.30)) drop-shadow(0 0 12px rgba(255, 209, 102, 0.40)); }
  50% { filter: drop-shadow(0 0 5px rgba(39, 174, 96, 0.28)) drop-shadow(0 0 11px rgba(45, 108, 223, 0.42)); }
  75% { filter: drop-shadow(0 0 6px rgba(255, 209, 102, 0.32)) drop-shadow(0 0 12px rgba(124, 92, 255, 0.44)); }
}

/* Home entrance */
/* v3.5: de vier homepanelen faden in LEESVOLGORDE in — lobby maken (1),
   meedoen (2), open lobby's (3), ranglijst (4). Eerder had "meedoen" helemaal
   geen animatie (stond er dus meteen) en stonden lobby's en ranglijst
   omgedraaid, waardoor het door elkaar leek te lopen. */
.home-panel { animation: panelRise 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both 0.15s; }
.tagline { animation: fadeSlide 0.6s ease both 0.35s; }
@keyframes panelRise {
  from { opacity: 0; transform: translateY(46px) scale(0.96); }
  to { opacity: 1; transform: none; }
}
@keyframes fadeSlide {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* Avatar-selectie: bounce + gloedring */
.avatar-option { position: relative; }
.avatar-option.selected { animation: avatarBounce 0.45s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes avatarBounce {
  0% { transform: scale(0.8); }
  55% { transform: scale(1.18); }
  100% { transform: scale(1); }
}
.avatar-option.selected::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 12px;
  border: 2px solid var(--neon-2);
  opacity: 0;
  animation: ringOut 0.55s ease forwards;
  pointer-events: none;
}
@keyframes ringOut {
  0% { opacity: 0.9; transform: scale(0.85); }
  100% { opacity: 0; transform: scale(1.35); }
}

/* Press-squash op knoppen */
.btn:active:not(:disabled) { transform: translateY(1px) scale(0.96); }

/* Roomcode letter-reveal */
.lobby-code { perspective: 300px; display: inline-flex; gap: 0.08em; }
.code-letter { display: inline-block; will-change: transform, opacity; }

/* Spelers pop-in / vertrek gebeurt via WAAPI; chat schuift in */
.chat-msg { animation: chatIn 0.32s cubic-bezier(0.34, 1.4, 0.64, 1) both; }
@keyframes chatIn {
  from { opacity: 0; transform: translateX(-14px); }
  to { opacity: 1; transform: none; }
}

/* Settings-flash bij wijziging (niet-host) */
.setting-row.flash::after {
  content: "";
  position: absolute;
  inset: -3px -6px;
  border-radius: 8px;
  background: rgba(255, 209, 102, 0.18);
  animation: settingFlash 0.9s ease forwards;
  pointer-events: none;
}
.setting-row { position: relative; }
@keyframes settingFlash {
  0% { opacity: 0; transform: scale(0.98); }
  25% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1); }
}

/* Host-kroon glinstert */
.crown, .crown-mini { position: relative; display: inline-block; animation: crownGlint 4.5s ease-in-out infinite; }
@keyframes crownGlint {
  0%, 88%, 100% { transform: none; opacity: 1; }
  92% { transform: rotate(-8deg) scale(1.18); opacity: 1; }
  96% { transform: rotate(6deg) scale(1.08); opacity: 0.9; }
}
.seat .crown-mini { position: absolute; }

/* Startknop prismatische shimmer zodra klaar */
#btn-start { position: relative; overflow: hidden; }
#btn-start.ready::after {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 40%; height: 100%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.35), rgba(255, 209, 102, 0.3), transparent);
  transform: translateX(-140%) skewX(-16deg);
  animation: btnShimmer 2.4s ease-in-out infinite;
  pointer-events: none;
}
@keyframes btnShimmer {
  0% { transform: translateX(-140%) skewX(-16deg); }
  60%, 100% { transform: translateX(360%) skewX(-16deg); }
}

/* Overlays: schalen met backdrop-blur in/uit */
.overlay { animation: overlayIn 0.22s ease both; }
.overlay .overlay-box { animation: overlayBoxIn 0.34s cubic-bezier(0.34, 1.56, 0.64, 1) both; }
@keyframes overlayIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes overlayBoxIn {
  from { opacity: 0; transform: scale(0.82) translateY(14px); }
  to { opacity: 1; transform: none; }
}
.overlay.closing { animation: overlayOut 0.2s ease both; }
.overlay.closing .overlay-box { animation: overlayBoxOut 0.2s ease both; }
@keyframes overlayOut { to { opacity: 0; } }
@keyframes overlayBoxOut { to { opacity: 0; transform: scale(0.9); } }

/* Aflegstapel: laatste 3 kaarten licht geroteerd */
.top-card-slot { min-width: var(--card-w); min-height: var(--card-h); }
.top-card-slot .card { position: relative; z-index: 3; }
.top-card-slot .card.under {
  position: absolute;
  inset: 0;
  z-index: 1;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45);
}
.top-card-slot .card.under.u2 { z-index: 2; }

/* Pulserende kleur-gloed achter topkaart */
.glow-halo {
  position: absolute;
  inset: -26px;
  z-index: 0;
  border-radius: 50%;
  background: radial-gradient(circle, var(--glow-color, rgba(124, 92, 255, 0.6)), transparent 70%);
  animation: glowPulse 2.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes glowPulse {
  0%, 100% { opacity: 0.55; transform: scale(0.92); }
  50% { opacity: 1; transform: scale(1.08); }
}

/* pendingDraw-badge bonkt bij verhoging */
.pending-draw.bump { animation: pendingBump 0.45s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes pendingBump {
  0% { transform: scale(1); }
  35% { transform: scale(1.35); }
  100% { transform: scale(1); }
}

/* Stempels (⊘ skip / BETRAPT!) */
.fx-stamp {
  position: fixed;
  font-size: 54px;
  font-weight: 900;
  color: var(--neon-2);
  text-shadow: 0 0 18px rgba(255, 209, 102, 0.8);
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
  z-index: 145;
}
.fx-stamp.stamp-caught {
  font-size: 30px;
  letter-spacing: 0.1em;
  color: #ff2d4d;
  text-shadow: 0 0 14px rgba(255, 45, 77, 0.9);
  border: 4px solid #ff2d4d;
  border-radius: 8px;
  padding: 4px 12px;
  background: rgba(30, 0, 8, 0.55);
}
.fx-stamp.stamp-skip { font-size: 64px; color: #ffd166; text-shadow: 0 0 18px rgba(255, 209, 102, 0.9); }

/* Schokgolf van de prismakaart: een ring in het volle spectrum, want dat is
   precies wat de kaart doet met wit licht. */
.fx-shockwave {
  position: fixed;
  width: 120px; height: 120px;
  border-radius: 50%;
  border: 6px solid transparent;
  background:
    radial-gradient(circle, transparent 58%, rgba(255,255,255,0.25) 62%, transparent 70%) padding-box,
    conic-gradient(#e63946, #f1c40f, #27ae60, #2d6cdf, #7c5cff, #e63946) border-box;
  -webkit-mask: radial-gradient(circle, transparent 55%, #000 58%);
  mask: radial-gradient(circle, transparent 55%, #000 58%);
  will-change: transform, opacity;
}

/* Bliksemflits */
.fx-lightning {
  position: fixed;
  inset: 0;
  background:
    linear-gradient(115deg, transparent 42%, rgba(255, 255, 255, 0.9) 49%, rgba(190, 225, 255, 0.95) 51%, transparent 58%),
    rgba(200, 225, 255, 0.28);
  will-change: opacity;
}

/* IJsgroei bij freeze */
.fx-ice {
  position: fixed;
  border-radius: 14px;
  background:
    radial-gradient(circle at 20% 15%, rgba(155, 232, 255, 0.5), transparent 45%),
    radial-gradient(circle at 85% 80%, rgba(155, 232, 255, 0.45), transparent 45%),
    radial-gradient(circle at 70% 20%, rgba(255, 255, 255, 0.3), transparent 35%),
    rgba(255, 209, 102, 0.16);
  border: 2px solid rgba(155, 232, 255, 0.65);
  will-change: transform, opacity;
}
.fx-ice span { position: absolute; font-size: 20px; color: #cdf3ff; text-shadow: 0 0 8px rgba(155, 232, 255, 0.9); }
.fx-ice .i1 { top: -8px; left: -6px; }
.fx-ice .i2 { bottom: -8px; right: -4px; font-size: 26px; }
.fx-ice .i3 { top: 30%; right: -10px; font-size: 15px; }
.fx-ice .i4 { bottom: 20%; left: -10px; font-size: 17px; }

/* Bevroren spelersvak (state-gedreven blijvende look) */
.seat.frozen .seat-avatar { border-color: rgba(155, 232, 255, 0.85); box-shadow: 0 0 18px rgba(255, 209, 102, 0.6); }

/* Schermvullende roep (0cards!) */
.fx-shout {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: radial-gradient(circle at center, rgba(10, 13, 31, 0.55), rgba(5, 6, 15, 0.75));
  will-change: transform, opacity;
  z-index: 146;
}
.fx-shout-text {
  font-size: clamp(44px, 12vw, 120px);
  font-weight: 900;
  letter-spacing: 0.08em;
  background: var(--rainbow);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 30px rgba(124, 92, 255, 0.8));
  text-align: center;
  padding: 0 12px;
}
.fx-shout-sub { font-size: clamp(16px, 3vw, 26px); font-weight: 700; color: var(--text); }

/* Reverse-swoosh pijl */
.fx-reverse {
  position: fixed;
  left: 50%; top: 45%;
  font-size: clamp(80px, 18vw, 160px);
  color: var(--neon-2);
  text-shadow: 0 0 34px rgba(255, 209, 102, 0.9);
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
}

/* Scorebord: rijen tellen rij voor rij in */
.scores-table tbody tr { will-change: transform, opacity; }

/* Storm: banner zoomt binnen (bestond al) + extra schud op icoon */
.storm-icon { animation: stormIconJolt 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes stormIconJolt {
  0% { transform: scale(0.2) rotate(-20deg); }
  60% { transform: scale(1.25) rotate(8deg); }
  100% { transform: scale(1) rotate(0); }
}

/* Mijn hand: kaarten die net gerenderd zijn poppen via WAAPI (client) */
.my-hand .card { will-change: transform; }

/* ============================================================
   Addendum v1.2 — account, leaderboard, rematch, automatisch pakken
   ============================================================ */

/* Account-blok (home) */
.account-block {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--panel-border);
}
.account-logged-out { display: flex; flex-direction: column; gap: 10px; }
.account-inputs { display: flex; gap: 8px; }
.account-inputs input { flex: 1; min-width: 0; }
.account-hint, .account-stats { text-align: left; }
.account-logged-in { display: flex; flex-direction: column; gap: 6px; }
.account-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.account-buttons { display: flex; gap: 6px; flex: none; }
/* Korte aandacht-puls wanneer de 🏆-knop het paneel aanwijst */
.leaderboard-panel.attention {
  animation: lbAttention 0.9s ease;
}
@keyframes lbAttention {
  0% { transform: scale(1); box-shadow: 0 8px 40px rgba(0, 0, 0, 0.45); }
  35% { transform: scale(1.025); box-shadow: 0 0 30px rgba(255, 209, 102, 0.45); }
  100% { transform: scale(1); box-shadow: 0 8px 40px rgba(0, 0, 0, 0.45); }
}
.account-label strong {
  background: var(--rainbow);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 800;
}
.name-field { display: flex; flex-direction: column; gap: 12px; }

/* ★ bij accountspelers (lobby, game, leaderboard) */
.account-star {
  color: #ffd166;
  text-shadow: 0 0 8px rgba(255, 209, 102, 0.8);
  font-size: 0.9em;
  margin-left: 4px;
  flex: none;
}

/* Leaderboard-paneel (home) */
.leaderboard-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: panelRise 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both 0.45s; /* v3.5: 4e in de rij */
}
.leaderboard-title { font-size: 16px; letter-spacing: 0.04em; }
.leaderboard-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.leaderboard-table th, .leaderboard-table td { padding: 6px 8px; text-align: left; }
.leaderboard-table th {
  color: var(--text-dim);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.leaderboard-table tbody tr { border-top: 1px solid var(--panel-border); will-change: transform, opacity; }
.leaderboard-table tbody tr:first-child td { color: #ffd166; font-weight: 800; }
.leaderboard-table td.lb-rank { width: 36px; }
.leaderboard-table td.lb-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px; }
.leaderboard-table td.lb-num { text-align: right; font-variant-numeric: tabular-nums; }
.leaderboard-empty { padding: 2px 0; }

/* Auto-pak-hint: subtiel i.p.v. de felle beurt-tekst */
.my-turn-hint.autodraw {
  color: var(--text-dim);
  font-weight: 600;
  animation: autoDrawPulse 1.6s ease-in-out infinite;
}
@keyframes autoDrawPulse {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}

/* ============================================================
   Addendum v1.4 — 3D-tilt, audio-popover, tafel-effecten
   ============================================================ */

/* 3D-kaart-tilt: alleen op fine-pointer devices; hoeken via JS (--tiltX/--tiltY) */
@media (pointer: fine) {
  .my-hand .card:hover {
    transform: rotateX(var(--tiltX, 0deg)) rotateY(var(--tiltY, 0deg));
    z-index: 6;
  }
  .my-hand .card.playable:hover,
  .my-hand .card.jumpable:hover {
    transform: translateY(-20px) scale(1.06) rotateX(var(--tiltX, 0deg)) rotateY(var(--tiltY, 0deg));
    z-index: 6;
  }
}

/* Bliksem geclipt op het tafelblad (FX.lightning(el)) */
.fx-lightning.clipped {
  inset: auto;
  border-radius: 50%;
  overflow: hidden;
}

/* Audio-popover (mute-knop): master aan/uit + sliders Muziek/Effecten */
.audio-popover {
  position: fixed;
  right: 12px;
  bottom: 64px;
  z-index: 215;
  width: 224px;
  background: rgba(16, 21, 48, 0.97);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
  animation: overlayBoxIn 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.audio-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}
.audio-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
}
.audio-row input[type="range"] {
  width: 116px;
  accent-color: var(--neon);
}
.audio-row input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: var(--neon);
}
.audio-row input:disabled { opacity: 0.4; }
.audio-unavailable { text-align: left; }

/* ============================================================
   Addendum v1.6 — dobbel-opening, 6 nieuwe actiekaarten
   ============================================================ */

/* ---------- Dobbelstenen (3D-CSS-kubus met pips) ---------- */
.fx-dice {
  position: fixed;
  width: 46px; height: 46px;
  z-index: 148;
  perspective: 430px;
  pointer-events: none;
  will-change: transform, opacity;
  filter: drop-shadow(0 10px 14px rgba(0, 0, 0, 0.55));
}
.dice-cube {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  will-change: transform;
}
.dice-face {
  position: absolute;
  inset: 0;
  border-radius: 9px;
  background: linear-gradient(145deg, #e8eaf6, #ccd2ee);
  border: 1px solid rgba(90, 100, 160, 0.6);
  box-shadow: inset 0 0 9px rgba(30, 30, 80, 0.25);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  padding: 6px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.dice-face.f-front  { transform: translateZ(23px); }
.dice-face.f-back   { transform: rotateY(180deg) translateZ(23px); }
.dice-face.f-right  { transform: rotateY(90deg) translateZ(23px); }
.dice-face.f-left   { transform: rotateY(-90deg) translateZ(23px); }
.dice-face.f-top    { transform: rotateX(90deg) translateZ(23px); }
.dice-face.f-bottom { transform: rotateX(-90deg) translateZ(23px); }
.pip-cell { display: flex; align-items: center; justify-content: center; }
.pip {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #232848;
  box-shadow: inset 0 -1px 2px rgba(0, 0, 0, 0.55);
}
/* Gouden winnaar-flits op de winnende steen */
.fx-dice.winner { animation: diceWinner 0.8s ease-in-out infinite; }
.fx-dice.winner .dice-face {
  border-color: rgba(255, 209, 102, 0.95);
  box-shadow: inset 0 0 9px rgba(30, 30, 80, 0.25), 0 0 18px rgba(255, 209, 102, 0.9);
}
@keyframes diceWinner {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.14); }
}

/* "X mag beginnen!"-banner */
.dice-banner {
  position: fixed;
  left: 50%; top: 38%;
  transform: translate(-50%, -50%);
  z-index: 149;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 26px;
  background: rgba(16, 21, 48, 0.94);
  border: 2px solid rgba(255, 209, 102, 0.75);
  border-radius: 16px;
  box-shadow: 0 0 34px rgba(255, 209, 102, 0.45), 0 16px 50px rgba(0, 0, 0, 0.6);
  will-change: transform, opacity;
  pointer-events: none;
}
.dice-banner img { width: 44px; height: 44px; object-fit: contain; }
.dice-banner-emoji { font-size: 34px; line-height: 1; }
.dice-banner-text {
  font-size: clamp(20px, 4vw, 30px);
  font-weight: 900;
  letter-spacing: 0.03em;
  background: linear-gradient(135deg, #fff3b0, #ffd166, #f1c40f);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  white-space: nowrap;
}
.dice-banner-sub { font-size: 13px; font-weight: 700; color: var(--text-dim); white-space: nowrap; }

/* ---------- Tijdbom-indicator op de aflegstapel ---------- */
.bomb-indicator {
  position: absolute;
  top: -18px; right: -22px;
  z-index: 6;
  width: 46px; height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(20, 8, 8, 0.9);
  border: 2px solid rgba(255, 140, 66, 0.75);
  border-radius: 50%;
  box-shadow: 0 0 16px rgba(255, 140, 66, 0.55);
}
.bomb-indicator.critical {
  border-color: var(--danger);
  box-shadow: 0 0 22px rgba(255, 45, 77, 0.85);
  animation: alertPulse 0.6s ease-in-out infinite;
}
.bomb-indicator.tick { animation: bombTickPulse 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes bombTickPulse {
  0% { transform: scale(1); }
  35% { transform: scale(1.35) rotate(-6deg); }
  100% { transform: scale(1); }
}
.bomb-icon { width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; }
.bomb-icon img, .bomb-icon svg { width: 100%; height: 100%; object-fit: contain; }
.bomb-count {
  position: absolute;
  top: -8px; right: -6px;
  min-width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px;
  font-weight: 900;
  color: #fff;
  background: linear-gradient(135deg, var(--danger), #b3123a);
  border-radius: 50%;
  box-shadow: 0 0 10px rgba(255, 45, 77, 0.8);
}
.bomb-amount {
  position: absolute;
  bottom: -8px; left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  font-weight: 800;
  color: #ffd166;
  background: rgba(120, 140, 255, 0.30);
  border: 1px solid rgba(255, 209, 102, 0.5);
  border-radius: 8px;
  padding: 0 6px;
  line-height: 14px;
  white-space: nowrap;
}
/* Pulserende lont */
.bomb-fuse {
  position: absolute;
  top: -5px; left: 4px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #f1c40f;
  box-shadow: 0 0 10px rgba(241, 196, 15, 1);
  animation: fusePulse 0.7s ease-in-out infinite;
}
@keyframes fusePulse {
  0%, 100% { opacity: 0.5; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1.3); }
}

/* ---------- Röntgen-scanpaneel (alleen bij de kijker) ---------- */
.xray-panel {
  position: fixed;
  left: 12px;
  /* Boven de handzone. Die is `--card-h + 42` hoog plus de knoppenrij eronder;
     met de kaarthoogte als maat schaalt dit mee op kleine schermen. Eerder
     stond hij op 76 px en lag hij dwars over je eigen kaarten heen. */
  bottom: calc(var(--card-h) + 120px);
  z-index: 96;
  width: min(320px, calc(100vw - 24px));
  /* Nooit hoger dan dit: een tegenstander met twintig kaarten mag het paneel
     niet tot bovenin laten groeien. */
  max-height: min(42vh, 300px);
  display: flex;
  flex-direction: column;
  /* Affiche in plaats van het oude donkerblauwe kastje. */
  background: linear-gradient(180deg, #151a3a, #0d1128);
  border: 1px solid rgba(120, 140, 255, 0.45);
  border-radius: 12px;
  padding: 12px;
  overflow: hidden;
  box-shadow: 0 3px 0 rgba(120, 140, 255, 0.20), 0 14px 34px rgba(120, 140, 255, 0.22);
  animation: overlayBoxIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.xray-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.xray-title {
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--neon);
  text-shadow: none;
}
.xray-target { font-size: 12px; color: var(--text-dim); }
.xray-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
/* Mini-kaartjes in het scanpaneel */
.xray-cards .card {
  width: 52px; height: 76px;
  border-width: 2px;
  border-radius: 8px;
}
.xray-cards .card .big-num { font-size: 28px; }
.xray-cards .card .big-num-img { height: 34px; }
.xray-cards .card .corner { font-size: 9px; }
.xray-cards .card .corner.tl { top: 3px; left: 4px; }
.xray-cards .card .corner.br { bottom: 3px; right: 4px; }
.xray-cards .card .icon-overlay { font-size: 15px; }
/* Scanlijn-effect over het paneel */
.xray-scanline {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 26px;
  background: linear-gradient(180deg, transparent, rgba(255, 209, 102, 0.20), transparent);
  animation: xrayScan 1.6s linear infinite;
  pointer-events: none;
}
@keyframes xrayScan {
  from { transform: translateY(-30px); }
  to { transform: translateY(240px); }
}

/* ---------- PANIEK-modus (Pech) ---------- */
.panic-vignette {
  position: fixed;
  inset: 0;
  z-index: 95;
  pointer-events: none;
  box-shadow: inset 0 0 150px 46px rgba(255, 45, 77, 0.55);
  animation: panicPulse 0.9s ease-in-out infinite;
}
@keyframes panicPulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}
.panic-banner {
  position: fixed;
  top: 58px; left: 50%;
  transform: translateX(-50%);
  z-index: 96;
  font-size: clamp(15px, 3vw, 20px);
  font-weight: 900;
  letter-spacing: 0.06em;
  color: #fff;
  background: linear-gradient(135deg, rgba(179, 18, 58, 0.95), rgba(120, 8, 34, 0.95));
  border: 2px solid rgba(255, 77, 109, 0.85);
  border-radius: 12px;
  padding: 6px 18px;
  box-shadow: 0 0 26px rgba(255, 45, 77, 0.7);
  animation: panicBannerPulse 1s ease-in-out infinite;
  pointer-events: none;
  white-space: nowrap;
}
@keyframes panicBannerPulse {
  0%, 100% { transform: translateX(-50%) scale(1); }
  50% { transform: translateX(-50%) scale(1.06); }
}

/* ---------- Cadeau: multi-select-overlay + strik-vlucht ---------- */
.gift-list .card { cursor: pointer; }
.gift-list .card:hover { transform: translateY(-8px) scale(1.05); }
.gift-list .card.selected {
  transform: translateY(-12px) scale(1.05);
  box-shadow: 0 0 0 3px #ffd166, 0 0 22px rgba(255, 209, 102, 0.75);
}
.gift-list .card.selected::after {
  content: "🎀";
  position: absolute;
  top: -12px; left: 50%;
  transform: translateX(-50%);
  font-size: 22px;
  z-index: 3;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.7));
}
.gift-hint { min-height: 16px; }
.gift-bow {
  position: absolute;
  top: -10px; left: 50%;
  transform: translateX(-50%);
  font-size: 24px;
  z-index: 3;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.7));
}

/* ---------- Wervelwind-chips (FX.spiral) ---------- */
.fx-whirl-chip {
  position: fixed;
  width: 20px; height: 29px;
  margin: -15px 0 0 -10px;
  border-radius: 4px;
  border: 1px solid rgba(124, 92, 255, 0.7);
  background-image: var(--back-img, linear-gradient(150deg, #171b36, #070912));
  background-size: cover;
  background-position: center;
  box-shadow: 0 3px 7px rgba(0, 0, 0, 0.6);
  z-index: 147;
  will-change: transform, opacity;
  pointer-events: none;
}

@media (max-width: 640px) {
  .xray-panel { bottom: 64px; width: min(272px, calc(100vw - 24px)); }
  .bomb-indicator { width: 38px; height: 38px; top: -14px; right: -14px; }
  .bomb-icon { width: 24px; height: 24px; }
  .panic-banner { top: 50px; }
}

/* Reduced motion: alles instant */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
  .ambient-canvas { display: none; }
  .turn-prisma { display: none; }
  /* v2.7 §3: geen tintwisseling; wel een statische gloed. */
  .logo-text, .logo img { animation: none !important; }
  .logo img { filter: drop-shadow(0 0 16px rgba(124, 92, 255, 0.45)); }
}

/* ============================================================
   Addendum v1.7 — kleurenblind, avatars, ambiance, help, open lobby's
   ============================================================ */

/* ---------- §2 Kleurenblind-modus ---------- */
/* Veilig palet via CSS-variabelen (Okabe-Ito): alles wat var(--red) e.d.
   gebruikt (kleur-kiezer, SVG-fallback-kaarten) kleurt automatisch mee. */
body.colorblind {
  /* Okabe-Ito, aangepast zodat ze op papier net zo goed uit elkaar te houden
     zijn als op het oude donkere vlak: iets dieper, zodat crème eronder blijft. */
  --red: #c2570a;
  --yellow: #b08900;
  --green: #007a5c;
  --blue: #005f92;
}
/* Kaart-achtergronden (SVG/CSS-fallback; frame-jpg's schaduwen dit — daar
   zijn de vorm-symbolen het onderscheid). */
body.colorblind .card[data-color="red"]    { --card-bg: linear-gradient(150deg, #e77b3a, #a34700); }
body.colorblind .card[data-color="yellow"] { --card-bg: linear-gradient(150deg, #f5ec70, #bfb414); }
body.colorblind .card[data-color="green"]  { --card-bg: linear-gradient(150deg, #14bd90, #006c50); }
body.colorblind .card[data-color="blue"]   { --card-bg: linear-gradient(150deg, #2f8fd4, #005180); }

/* Vormen in de kaarthoeken — alleen zichtbaar in kleurenblind-modus.
   Het zijn tekeningen, geen tekens: vier vormen met hetzelfde vierkant én
   hetzelfde oppervlak, zodat ze even groot ogen en op dezelfde plek staan. */
.card .cb-shape { display: none; }
body.colorblind .card .cb-shape {
  display: block;
  width: 16px;
  height: 16px;
  margin: 2px auto 0;
  fill: #fff;
  stroke: rgba(0, 0, 0, 0.92);
  stroke-width: 2.5;
  paint-order: stroke fill;    /* eerst de contour, dan het wit erover */
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.9));
}
body.colorblind .xray-cards .card .cb-shape { width: 10px; height: 10px; margin-top: 1px; }
/* Dezelfde vorm naast de kleurnaam in de kiezer. */
.cb-shape-inline {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 2;
  paint-order: stroke fill;
}

/* v3.12: hier stond een ronde kleurbadge rechtsboven op de kaart. Die is eruit:
   in je hand overlappen de kaarten, dus hij dook pas op als je een kaart
   aanwees. Het kleuronderscheid zit in de hoekvormen hierboven — die staan er
   altijd, linksboven én rechtsonder.
   Daarmee verviel ook de reden om het centrale icoon te verschuiven en te
   verkleinen: dat gebeurde alleen om ruimte voor de badge te maken. */
/* Vorm-symbolen op de kleur-kiezer-knoppen */
.color-swatch { display: flex; align-items: center; justify-content: center; }
.cb-swatch-shape { display: none; }
body.colorblind .color-swatch .cb-swatch-shape {
  display: block;
  width: 38px;
  height: 38px;
  fill: #fff;
  stroke: rgba(0, 0, 0, 0.6);
  stroke-width: 1.6;
  paint-order: stroke fill;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.85));
}

/* Huidige-kleur-indicator als tekstlabel in de HUD (alleen kleurenblind-modus) */
.current-color-label {
  font-size: 17px;
  font-weight: 900;
  letter-spacing: 0.05em;
  color: var(--text);
  background: rgba(16, 21, 48, 0.85);
  border: 2px solid rgba(255, 255, 255, 0.5);
  border-radius: 12px;
  padding: 4px 16px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}
body:not(.colorblind) .current-color-label { display: none; }

/* Toggle in het ingelogde accountblok */
.account-pref-row { font-size: 13px; margin-top: 2px; }

/* ---------- §7 Ambiance: room-asset als in-game achtergrond ---------- */
/* Alleen actief als het room-asset bestaat (body.has-room via JS); anders
   blijft de bestaande gradient exact zoals hij was. Dim + vignette in laag 1. */
body.in-game.has-room {
  background-image:
    radial-gradient(ellipse at 50% 42%, rgba(4, 5, 14, 0.30), rgba(2, 3, 9, 0.82) 82%),
    var(--room-img);
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  background-attachment: fixed, fixed;
}

/* ---------- §8 Avatar-afbeeldingen (manifest.avatars) ---------- */
.avatar-img { display: inline-block; vertical-align: middle; }
.avatar-emoji { display: inline-block; }
.avatar .avatar-img { width: 28px; height: 28px; object-fit: contain; }
.avatar-option { height: 54px; display: flex; align-items: center; justify-content: center; padding: 4px 0; }
.avatar-option .avatar-img { width: 42px; height: 42px; object-fit: contain; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5)); }
.seat-avatar { overflow: hidden; }
.seat-avatar .avatar-img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.my-name .avatar-img { width: 24px; height: 24px; object-fit: contain; vertical-align: -6px; margin-right: 2px; }
.scores-table .avatar-img { width: 22px; height: 22px; object-fit: contain; vertical-align: -5px; margin-right: 4px; }
.scores-subtitle .avatar-img { width: 22px; height: 22px; object-fit: contain; vertical-align: -5px; margin-right: 4px; }
.target-option .avatar .avatar-img { width: 26px; height: 26px; }

/* ---------- §5 Sessiescore-tally ---------- */
.session-tally {
  flex: none;
  font-size: 11px;
  font-weight: 700;
  color: #ffd166;
  background: rgba(90, 55, 0, 0.35);
  border: 1px solid rgba(255, 209, 102, 0.4);
  border-radius: 8px;
  padding: 1px 7px;
  white-space: nowrap;
}
.scores-table td.session-cell {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  font-size: 13px;
  white-space: nowrap;
}

/* ---------- §9 Help-knop + handleiding-overlay ---------- */
.btn-help {
  position: fixed;
  bottom: 12px;
  right: 64px;
  z-index: 210;
  font-size: 17px;
  color: var(--text);
  background: rgba(16, 21, 48, 0.8);
  border: 1px solid var(--panel-border);
  border-radius: 50%;
  width: 44px; height: 44px;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.btn-help:hover { transform: translateY(-2px); box-shadow: 0 0 14px rgba(124, 92, 255, 0.5); }

.help-box { width: min(720px, 96vw); gap: 12px; text-align: left; align-items: stretch; }
.help-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.help-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.help-tab {
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-dim);
  background: rgba(120, 140, 255, 0.22);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  padding: 7px 14px;
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.help-tab:hover { color: var(--text); }
.help-tab.active {
  color: var(--text);
  background: linear-gradient(135deg, rgba(124, 92, 255, 0.35), rgba(255, 209, 102, 0.18));
  border-color: var(--neon);
}
.help-body {
  max-height: min(58vh, 560px);
  overflow-y: auto;
  padding-right: 6px;
  font-size: 14px;
  line-height: 1.5;
}
.help-pane { display: none; flex-direction: column; gap: 8px; }
.help-pane.active { display: flex; }
.help-pane h3 {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--neon-2);
  margin-top: 8px;
}
.help-pane p { color: var(--text); }
.help-pane .hint { text-align: left; }
.help-list { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.help-card-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 8px;
  border-radius: 10px;
  background: rgba(120, 140, 255, 0.18);
  border: 1px solid rgba(120, 140, 255, 0.1);
}
.help-icon {
  flex: none;
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  font-size: 24px;
}
.help-icon img, .help-icon svg { width: 100%; height: 100%; object-fit: contain; }
.help-num {
  font-size: 24px;
  font-weight: 900;
  color: #fff;
  background: linear-gradient(150deg, var(--neon), #4a35c9);
  border-radius: 8px;
  width: 32px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

/* ---------- §10 Open lobby's-paneel (home) ---------- */
.home-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.lobbies-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: panelRise 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both 0.35s; /* v3.5: 3e in de rij */
}
.lobbies-list { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.lobby-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(120, 140, 255, 0.20);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  padding: 8px 12px;
}
.lobby-row-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.lobby-row-host { font-weight: 700; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lobby-row-meta { font-size: 12px; color: var(--text-dim); }
.lobby-row-status {
  flex: none;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: 8px;
  padding: 2px 8px;
  border: 1px solid var(--panel-border);
  color: var(--text-dim);
}
.lobby-row-status.open { color: #38e07b; border-color: rgba(56, 224, 123, 0.5); }
.lobby-row-status.busy { color: #ffd166; border-color: rgba(255, 209, 102, 0.45); }
.lobbies-empty { padding: 2px 0; }

/* ---------- v1.8 Instellingen-presets (lobby, host) ---------- */
.preset-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--panel-border);
}
.preset-select {
  flex: 1;
  min-width: 130px;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: rgba(120, 140, 255, 0.24);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 6px 8px;
}
.preset-select optgroup { color: var(--text-dim); font-style: normal; }
.preset-row .btn { flex: none; }
.preset-row .btn:disabled { opacity: 0.5; cursor: default; }
.preset-delete { color: #ff6b81; padding-left: 10px; padding-right: 10px; }
.preset-hint { text-align: left; margin: -4px 0 10px; }
.preset-overlay-text { text-align: center; }
#preset-name-input { text-align: center; }

/* v1.9: sub-instelling onder een hoofdtoggle (bv. "+2 mag ook op +4") */
.setting-row.sub-row { padding-left: 10px; opacity: 0.9; }
.setting-row.sub-row span { font-size: 13px; color: var(--text-dim); }

/* Uitleg onder een instelling (speciale kaarten + spelregels in de lobby) */
.special-row,
.desc-row { align-items: flex-start; }
.special-row > span,
.desc-row > span { display: flex; flex-direction: column; gap: 2px; }
.setting-desc {
  font-style: normal;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--text-dim);
  opacity: 0.85;
  max-width: 34ch;
}

/* ============================================================
   Addendum v2.0 §4 — Uitgebreide statistieken
   (paneel "Mijn statistieken", leaderboard-popover, sessieregel)
   ============================================================ */

/* Knop in het ingelogde accountblok */
.btn-my-stats { align-self: flex-start; }

/* ---------- Persoonlijk paneel ---------- */
.stats-box { text-align: left; align-items: stretch; gap: 14px; }
.stats-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.stats-who { text-align: left; margin-top: -8px; }
.stats-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  max-height: min(60vh, 560px);
  overflow-y: auto;
}
.stats-group {
  background: rgba(120, 140, 255, 0.18);
  border: 1px solid rgba(5, 6, 15, 0.30);
  border-radius: 12px;
  padding: 10px 12px;
  will-change: transform, opacity;
}
.stats-group-title {
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--neon-2);
  margin-bottom: 8px;
}
.stats-list {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 4px 10px;
  margin: 0;
  font-size: 13px;
}
.stats-list dt { color: var(--text-dim); }
.stats-list dd {
  margin: 0;
  text-align: right;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- Leaderboard-popover (hover / focus / tik) ---------- */
.leaderboard-hint { text-align: left; font-size: 11.5px; opacity: 0.75; }
.leaderboard-table tbody tr.lb-row { cursor: help; }
.leaderboard-table tbody tr.lb-row:hover,
.leaderboard-table tbody tr.lb-row:focus,
.leaderboard-table tbody tr.lb-row:focus-visible {
  background: rgba(124, 92, 255, 0.14);
  outline: none;
}
.lb-popover {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 220;
  width: min(268px, calc(100vw - 24px));
  background: rgba(16, 21, 48, 0.97);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  padding: 10px 12px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.65);
  pointer-events: none; /* de popover vangt nooit muis/tik-events af */
  animation: overlayBoxIn 0.18s ease both;
}
.lb-pop-name {
  font-weight: 800;
  font-size: 13px;
  color: #ffd166;
  margin-bottom: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lb-popover .stats-groups {
  grid-template-columns: 1fr;
  gap: 6px;
  max-height: none;
  overflow: visible;
}
/* In de popover zijn de groepen tekstblokjes i.p.v. kaartjes: compacter. */
.lb-popover .stats-group { background: none; border: none; padding: 0; }
.lb-popover .stats-group + .stats-group {
  border-top: 1px solid var(--panel-border);
  padding-top: 6px;
}
.lb-popover .stats-group-title { font-size: 10px; margin-bottom: 3px; }
.lb-popover .stats-list { font-size: 11.5px; gap: 0 8px; line-height: 1.35; }

/* ---------- Sessieregel onder de scoretabel ---------- */
.scores-session {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: -6px;
  padding-top: 8px;
  border-top: 1px solid var(--panel-border);
  text-align: left;
  max-height: 22vh; /* veel spelers: de overlay mag niet buiten beeld groeien */
  overflow-y: auto;
}
.scores-session-title {
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-dim);
  margin-bottom: 2px;
}
.scores-session-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  color: var(--text-dim);
}
.scores-session-line .ss-name {
  font-weight: 700;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.scores-session-line .ss-nums { font-variant-numeric: tabular-nums; white-space: nowrap; }

@media (max-width: 640px) {
  .stats-groups { grid-template-columns: 1fr; }
  .btn-my-stats { align-self: stretch; }
}

/* v2.3: bevestiging dat de avatarkeuze bij het account is bewaard */
.avatar-saved-hint {
  text-align: left;
  color: #38e07b;
  font-size: 12px;
  margin-top: -4px;
  animation: fadeSlide 0.3s ease both;
}

/* ============================================================
   Addendum v2.2 §1 — Zetvergrendeling tijdens een keuze
   ============================================================ */

/* Zolang er een zet loopt (of een kiezer openstaat) doet de rest van de tafel
   even niet mee: hand, trekstapel, actieknoppen en stoelen zijn niet klikbaar.
   De overlays zelf, de emotebalk en de mute/help-knop blijven wél werken. */
body.choosing #my-hand,
body.choosing #deck-pile,
body.choosing .my-buttons,
body.choosing #seats {
  pointer-events: none;
}
body.choosing #my-hand,
body.choosing #deck-pile {
  filter: saturate(0.8) brightness(0.82);
  transition: filter 0.18s ease;
}
body.choosing #my-hand .card.playable,
body.choosing #my-hand .card.jumpable {
  animation: none; /* geen "speel mij"-puls terwijl het toch niet kan */
}
/* Uitzonderingen: deze blijven gewoon bedienbaar. */
body.choosing .overlay,
body.choosing #emote-bar,
body.choosing .btn-mute,
body.choosing .btn-help,
body.choosing .btn-lang,
body.choosing .btn-fullscreen,
body.choosing #audio-popover,
body.choosing #lang-popover,
body.choosing #log-panel,
body.choosing .btn-admin,
body.choosing #admin-panel {
  pointer-events: auto;
}

/* ============================================================
   Addendum v2.1 §3 — Live lobbylijst (pop-in van nieuwe rijen)
   ============================================================ */
.lobby-row-new {
  border-color: rgba(124, 92, 255, 0.55);
  box-shadow: 0 0 0 1px rgba(124, 92, 255, 0.2), 0 6px 20px rgba(124, 92, 255, 0.12);
}
@media (prefers-reduced-motion: reduce) {
  .lobby-row-new { box-shadow: none; }
}

/* ============================================================
   Addendum v2.2 §3 — Taalkiezer (hulpvenster)
   v2.7 §1: de balk rechtsboven op home is vervallen; de kiezer in het
   hulpvenster blijft als secundaire ingang bestaan (bewust ingetogen).
   ============================================================ */
.lang-select {
  font-family: inherit;
  font-size: 13px;
  color: var(--text);
  background: rgba(120, 140, 255, 0.24);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  padding: 5px 10px;
  cursor: pointer;
  max-width: 170px;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.lang-select:hover,
.lang-select:focus-visible {
  border-color: var(--neon);
  box-shadow: 0 0 10px rgba(124, 92, 255, 0.35);
  outline: none;
}
/* In het hulpvenster staat de kiezer naast de sluitknop — visueel secundair
   (v2.7 §1): de hoofdingang is het ronde 🌐-knopje rechtsonder. */
.help-head .lang-select {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-dim);
  opacity: 0.75;
}
.help-head .lang-select:hover,
.help-head .lang-select:focus-visible { opacity: 1; color: var(--text); }
@media (max-width: 520px) {
  .lang-select { font-size: 12px; padding: 4px 8px; max-width: 140px; }
}

/* ============================================================
   Addendum v2.7 §1 — Taalknop als derde rond knopje rechtsonder
   Zelfde vormgeving als 🔊 (right: 12px) en ❓ (right: 64px).
   ============================================================ */
.btn-lang {
  position: fixed;
  bottom: 12px;
  right: 116px;
  z-index: 210;
  font-size: 17px;
  line-height: 1;
  color: var(--text);
  background: rgba(16, 21, 48, 0.8);
  border: 1px solid var(--panel-border);
  border-radius: 50%;
  width: 44px; height: 44px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.btn-lang:hover { transform: translateY(-2px); box-shadow: 0 0 14px rgba(124, 92, 255, 0.5); }
#btn-lang-flag { font-size: 19px; line-height: 1; }

/* Popover ómhoog, zelfde patroon/positie als de audio-popover */
.lang-popover {
  position: fixed;
  right: 12px;
  bottom: 64px;
  z-index: 215;
  width: 208px;
  background: rgba(16, 21, 48, 0.97);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
  animation: overlayBoxIn 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.lang-options { display: flex; flex-direction: column; gap: 4px; }
.lang-option {
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  padding: 7px 9px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.lang-option:hover { background: rgba(124, 92, 255, 0.16); }
.lang-option.active {
  border-color: rgba(255, 209, 102, 0.55);
  background: rgba(255, 209, 102, 0.12);
  color: var(--neon-2);
}
.lang-option-flag { font-size: 18px; line-height: 1; }
.lang-option-name { flex: 1; }

/* ============================================================
   Addendum v2.7 §2 — Actielogboek (📜-knop + schuivend paneel)
   ============================================================ */
.btn-log {
  position: relative;
  padding: 5px 12px;
  font-size: 15px;
  line-height: 1.2;
  background: transparent;
  border: 1px solid var(--panel-border);
  color: var(--text-dim);
  opacity: 0.8;
  box-shadow: none;
  transform: none;
}
.btn-log:hover:not(:disabled) {
  opacity: 1;
  color: var(--text);
  border-color: rgba(124, 92, 255, 0.6);
  background: rgba(124, 92, 255, 0.12);
  transform: none;
}
.log-btn-icon { font-size: 16px; }
.log-badge {
  position: absolute;
  top: -7px;
  right: -7px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--neon), #4a35c9);
  border: 1px solid rgba(255, 209, 102, 0.65);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 10px rgba(124, 92, 255, 0.6);
}

.log-panel {
  position: fixed;
  top: 8px;
  right: 8px;
  bottom: 64px;              /* blijft boven de drie ronde knopjes */
  width: min(360px, 92vw);
  z-index: 99;               /* onder de keuze-overlays (100) en toasts (200) */
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 12px 10px;
  /* v3.12 — glas. Er stond hier al een `backdrop-filter: blur(8px)`, maar de
     achtergrond erboven was 96% dekkend: je zag er dus niets van. Nu een
     donkere, half doorzichtige laag met een stevige vervaging erachter, een
     lichtrandje langs de bovenkant (dat leest als de dikte van het glas) en wat
     extra verzadiging, zodat de kleuren van de tafel er zacht doorheen komen.

     De dekking blijft hoog (0,78): het logboek staat over de tafel, en daar
     liggen felle kaarten en de regenboogring. Doorzichtiger oogt mooier maar
     kost leesbaarheid — in de browser gemeten boven het felste stuk tafel. */
  background: linear-gradient(160deg, rgba(26, 33, 70, 0.80), rgba(9, 12, 28, 0.76));
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--radius);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 0 0 1px rgba(124, 92, 255, 0.07),
    -18px 0 60px rgba(0, 0, 0, 0.50);
  backdrop-filter: blur(22px) saturate(140%);
  -webkit-backdrop-filter: blur(22px) saturate(140%);
  /* Eigen dim-tint binnen het paneel. De gewone --text-dim (#8a91b4) haalt door
     het glas heen de norm niet meer boven een felle kaart (3,82 tegen een
     vereiste 4,5); deze wel (5,93). Zie test/kaartbeeld.test.js, die het
     narekent uit deze twee waarden. */
  --log-dim: #b0b7d2;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.2s ease;
}
/* Zonder backdrop-filter zou het paneel gewoon halfdoorzichtig worden en zou de
   tafel dwars door de tekst heen te lezen zijn. Dan liever weer dekkend. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .log-panel { background: rgba(13, 17, 40, 0.96); }
}
/* Schuiven i.p.v. verdwijnen: de globale .hidden-regel wordt hier bewust
   overschreven zodat het paneel netjes in en uit beeld glijdt. */
.log-panel.hidden {
  display: flex !important;
  transform: translateX(calc(100% + 16px));
  opacity: 0;
  pointer-events: none;
}
.log-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.log-title { font-size: 15px; letter-spacing: 0.02em; }
.log-empty { text-align: left; color: var(--log-dim, var(--text-dim)); }
.log-list {
  list-style: none;
  overflow-y: auto;
  overflow-x: hidden;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  scrollbar-gutter: stable;
}
.log-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 5px 7px;
  border-radius: 8px;
  border-left: 3px solid transparent;
  font-size: 13px;
  line-height: 1.35;
  color: var(--text);
}
.log-time {
  flex: none;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  /* Geen extra opacity meer: door het glas ging die er nog eens overheen. */
  color: var(--log-dim, var(--text-dim));
}
.log-icon { flex: none; font-size: 13px; }
.log-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* Eigen acties licht geaccentueerd */
.log-row.log-mine {
  background: rgba(255, 209, 102, 0.10);
  box-shadow: inset 0 0 0 1px rgba(255, 209, 102, 0.18);
}
.log-row.log-mine .log-text { font-weight: 700; }

/* Kleurtje per soort */
.log-play { border-left-color: rgba(255, 209, 102, 0.7); }
.log-draw { border-left-color: rgba(138, 145, 180, 0.6); }
.log-draw .log-text { color: var(--text-dim); }
.log-penalty { border-left-color: rgba(255, 77, 109, 0.8); }
.log-penalty .log-text { color: #ffc2cd; }
.log-storm { border-left-color: rgba(241, 196, 15, 0.85); }
.log-storm .log-text { color: #ffe79a; }
.log-special { border-left-color: rgba(124, 92, 255, 0.8); }
.log-call { border-left-color: rgba(39, 174, 96, 0.85); }
.log-call .log-text { font-weight: 700; }
.log-win { border-left-color: rgba(255, 215, 0, 0.9); }
.log-win .log-text { color: #ffe9a3; font-weight: 700; }
.log-info { border-left-color: rgba(138, 145, 180, 0.45); }
.log-info .log-text { color: var(--text-dim); }

/* Scheidingsregel bij een nieuwe ronde */
.log-row.log-sep {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 2px;
  padding: 0;
  border: none;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.log-row.log-sep::before,
.log-row.log-sep::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--panel-border), transparent);
}
.log-row.log-sep:first-child { margin-top: 0; }
/* Een geweigerde zet: dezelfde toon als een foutmelding, zodat je hem
   terugvindt tussen wat er verder gebeurde. */
.log-row.log-refuse .log-text { color: var(--danger); }
/* Met het paneel open ís deze regel de melding — dus even oplichten, zodat je
   oog ernaartoe gaat zonder dat er iets over de tafel schuift. */
.log-row.log-nieuw {
  animation: logNieuw 1.4s ease-out;
}
@keyframes logNieuw {
  0%   { background: rgba(230, 57, 70, 0.34); box-shadow: 0 0 0 1px rgba(230, 57, 70, 0.55); }
  70%  { background: rgba(230, 57, 70, 0.16); }
  100% { background: transparent; box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
  /* Geen puls, maar wél een blijvend randje: het signaal mag niet wegvallen. */
  .log-row.log-nieuw { animation: none; box-shadow: 0 0 0 1px rgba(230, 57, 70, 0.55); }
}

/* Desktop: het spelscherm schuift op zodat het paneel de kaarten niet dekt. */
#screen-game { transition: padding-right 0.28s cubic-bezier(0.22, 1, 0.36, 1); }
@media (min-width: 760px) {
  body.log-open #screen-game { padding-right: calc(min(360px, 92vw) + 24px); }
}

/* Mobiel: van onderaf, max 70% hoogte; onderin ruimte voor de ronde knopjes. */
@media (max-width: 759px) {
  .log-panel {
    top: auto;
    left: 8px;
    right: 8px;
    bottom: 0;
    width: auto;
    height: 70vh;
    max-height: 70%;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    padding-bottom: 62px;
    box-shadow: 0 -14px 44px rgba(0, 0, 0, 0.6);
  }
  .log-panel.hidden { transform: translateY(calc(100% + 16px)); }
}

/* Smalle schermen: drie ronde knopjes van 40×40 met 8px tussenruimte. */
@media (max-width: 520px) {
  .btn-mute { width: 40px; height: 40px; right: 12px; }
  .btn-help { width: 40px; height: 40px; right: 60px; }
  .btn-lang { width: 40px; height: 40px; right: 108px; }
  #btn-lang-flag { font-size: 17px; }
  .audio-popover, .lang-popover { bottom: 60px; }
}

@media (prefers-reduced-motion: reduce) {
  .log-panel, #screen-game { transition: none; }
  .lang-popover { animation: none; }
}

/* Geen layout-sprong wanneer een scrollbaar paneel net wel/niet hoog genoeg is:
   ruimte voor de scrollbalk blijft altijd gereserveerd. Dit voorkomt de korte
   "scroll-flits" bij o.a. de statistieken-overlay en de chat. */
.overlay-box,
.stats-groups,
.lb-popover,
.chat-log,
.lobby-settings-panel,
.help-body {
  scrollbar-gutter: stable;
}

/* ============================================================
   Addendum v3.0 — Tussenspellen (cirkel-tegels + rekenduel)
   Twee fullscreen-overlays die het spel 10 seconden lang overnemen.
   ============================================================ */
.overlay-mini { z-index: 160; padding: 12px; }
.mini-box {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  box-shadow: 0 12px 60px rgba(0, 0, 0, 0.65);
  padding: 18px clamp(14px, 3vw, 26px);
  width: min(980px, 96vw);
  max-height: 94vh;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: stretch;
  text-align: center;
  animation: miniPop 0.24s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes miniPop {
  from { transform: scale(0.92) translateY(10px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.mini-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
}
.mini-title { font-size: clamp(19px, 3vw, 26px); font-weight: 900; letter-spacing: 0.01em; }
.mini-clock {
  min-width: 56px;
  font-size: clamp(26px, 5vw, 40px);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  color: var(--neon-2);
  text-shadow: 0 0 18px rgba(255, 209, 102, 0.55);
}
.mini-clock.urgent {
  color: var(--danger);
  text-shadow: 0 0 22px rgba(255, 77, 109, 0.75);
  animation: miniClockPulse 0.5s ease-in-out infinite alternate;
}
@keyframes miniClockPulse { from { transform: scale(1); } to { transform: scale(1.14); } }
.mini-hint { margin: 0; }
.mini-foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.mini-status { margin: 0; min-height: 20px; }

/* ---------- §1: tegelraster met één tekenvak per speler ---------- */
.circle-grid {
  display: grid;
  /* v3.15 — GEEN 1fr meer. Met `1fr` deelden alle vakken de breedte, dus werd
     jouw eigen tekenvak net zo klein als dat van de negen anderen — precies
     waar je niet mee kunt tekenen. De vakken van je medespelers hebben een
     bovengrens: het zijn kijkvensters, geen tekenvellen. Jouw eigen vak staat
     hieronder apart en houdt zijn maat, hoeveel spelers er ook zijn. */
  grid-template-columns: repeat(auto-fit, minmax(88px, 124px));
  justify-content: center;
  gap: 10px;
  overflow-y: auto;
  padding: 2px;
  scrollbar-gutter: stable;
}
/* Jouw vak: over de volle breedte en bovenaan, met een eigen maat die aan
   niemand anders hangt. De drie grenzen in min() vangen elk een geval af:
   320px is genoeg om met een muis rond te tekenen, 66vw houdt hem op een
   smalle telefoon binnen beeld, en de --app-h-term zorgt dat hij liggend niet
   hoger wordt dan het scherm werkelijk is (zie addendum v3.14). */
.circle-tile.mine {
  grid-column: 1 / -1;
  order: -1;
  /* Wel de volle rij claimen, niet de volle breedte VULLEN: anders staat je
     tekenvlak midden in een omlijsting die twee keer zo breed is als hijzelf. */
  justify-self: center;
}
.circle-tile.mine .circle-stage {
  width: min(320px, 66vw, 40vh);
  width: min(320px, 66vw, calc(var(--app-h, 100dvh) * 0.4));
  margin-inline: auto;
}
.circle-tile.mine .circle-tile-head { justify-content: center; }
.circle-tile.mine .circle-tile-name { flex: 0 1 auto; }
.circle-tile {
  --ink: var(--neon);
  background: rgba(6, 9, 24, 0.72);
  border: 2px solid var(--panel-border);
  border-radius: 12px;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.circle-tile.mine { border-color: color-mix(in srgb, var(--ink) 70%, transparent); }
.circle-tile.done { opacity: 0.92; }
.circle-tile.best {
  border-color: var(--yellow);
  box-shadow: 0 0 26px rgba(241, 196, 15, 0.45);
  transform: scale(1.03);
}
.circle-tile.worst {
  border-color: var(--danger);
  box-shadow: 0 0 22px rgba(255, 77, 109, 0.4);
}
.circle-tile-head {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 24px;
  font-size: 13px;
  font-weight: 700;
}
.circle-tile-head .avatar { font-size: 17px; line-height: 1; display: inline-flex; }
.circle-tile-head .avatar-img { width: 20px; height: 20px; border-radius: 50%; }
.circle-tile-name {
  flex: 1;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.circle-tile-mark { font-size: 15px; }
.circle-tile.done .circle-tile-mark { color: var(--green); }
.circle-stage {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 9px;
  background:
    radial-gradient(circle at 50% 50%, rgba(124, 92, 255, 0.10), transparent 70%),
    rgba(255, 255, 255, 0.04);
  overflow: hidden;
}
.circle-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.circle-tile.mine .circle-canvas { cursor: crosshair; touch-action: none; }
.circle-tile-score {
  position: absolute;
  inset: auto 0 0 0;
  padding: 3px 0 4px;
  font-size: clamp(15px, 2.4vw, 21px);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  background: rgba(5, 6, 15, 0.72);
  animation: miniPop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.circle-tile.best .circle-tile-score { color: var(--yellow); }
.circle-tile.worst .circle-tile-score { color: var(--danger); }

/* ---------- §2: rekenduel ---------- */
.duel-box { width: min(560px, 96vw); }
.duel-question {
  font-size: clamp(38px, 11vw, 78px);
  font-weight: 900;
  letter-spacing: 0.04em;
  padding: 6px 0;
  background: var(--rainbow);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 22px rgba(124, 92, 255, 0.55));
}
.duel-answer-row {
  display: flex;
  gap: 10px;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}
.duel-answer {
  width: min(200px, 54vw);
  font-family: inherit;
  font-size: 26px;
  font-weight: 800;
  text-align: center;
  color: var(--text);
  background: var(--bg-2);
  border: 2px solid var(--panel-border);
  border-radius: 12px;
  padding: 8px 10px;
}
.duel-answer:focus { outline: none; border-color: var(--neon-2); box-shadow: 0 0 16px rgba(255, 209, 102, 0.35); }
.duel-answer:disabled { opacity: 0.55; }
/* Spinner-pijltjes weg: het is één getal, geen teller. */
.duel-answer::-webkit-outer-spin-button,
.duel-answer::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.duel-answer { -moz-appearance: textfield; appearance: textfield; }
.duel-outcome {
  font-size: clamp(15px, 2.6vw, 19px);
  font-weight: 700;
  min-height: 24px;
  margin: 0;
  padding: 0 8px;
}
.duel-outcome.good { color: var(--green); }
.duel-outcome.bad { color: var(--danger); }

/* ---------- v3.2: magneet — kies uit drie dichte kaarten ---------- */
.magnet-box { width: min(620px, 96vw); }
.mini-sub { margin: 0; font-size: clamp(15px, 2.6vw, 20px); font-weight: 800; }
.magnet-cards {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: clamp(10px, 3vw, 22px);
  padding: 6px 0 2px;
  perspective: 1000px;
}
.magnet-slot {
  --card-w: clamp(78px, 19vw, 116px);
  --card-h: calc(var(--card-w) * 1.45);
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  cursor: default;
}
.magnet-slot.pickable { cursor: pointer; }
.magnet-flip {
  position: relative;
  width: var(--card-w);
  height: var(--card-h);
  border-radius: 12px;
  transform-style: preserve-3d;
  transition: transform 0.5s cubic-bezier(0.4, 0.05, 0.2, 1), box-shadow 0.2s ease;
}
.magnet-slot.pickable:hover .magnet-flip,
.magnet-slot.pickable:focus-visible .magnet-flip {
  transform: translateY(-10px) scale(1.05);
  box-shadow: 0 0 26px rgba(255, 209, 102, 0.6);
}
.magnet-slot.chosen .magnet-flip { box-shadow: 0 0 30px rgba(255, 209, 102, 0.75); }
.magnet-slot.revealed .magnet-flip { transform: rotateY(180deg); }
.magnet-slot.revealed.taken .magnet-flip {
  transform: rotateY(180deg) scale(1.06);
  box-shadow: 0 0 30px rgba(39, 174, 96, 0.65);
}
.magnet-face {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.magnet-face .card { width: 100%; height: 100%; }
.magnet-back { transform: rotateY(180deg); }
.magnet-label {
  font-size: 12px;
  font-weight: 800;
  min-height: 16px;
  opacity: 0;
  transition: opacity 0.25s ease 0.3s;
}
.magnet-slot.revealed .magnet-label { opacity: 1; }
.magnet-slot.taken .magnet-label { color: var(--green); }
.magnet-slot.left { filter: grayscale(0.75); opacity: 0.7; }
.magnet-outcome {
  font-size: clamp(15px, 2.6vw, 19px);
  font-weight: 700;
  min-height: 24px;
  margin: 0;
  padding: 0 8px;
}
.magnet-outcome.good { color: var(--green); }

@media (max-width: 520px) {
  /* Ook hier zonder 1fr: op een smal scherm is de verleiding het grootst om
     jouw tekenvak mee te laten krimpen, en juist daar heb je de ruimte nodig. */
  .circle-grid { grid-template-columns: repeat(auto-fit, minmax(72px, 96px)); gap: 8px; }
  .circle-tile-head { font-size: 11px; }
  .mini-box { padding: 14px 10px; gap: 10px; }
  .magnet-slot { --card-w: clamp(66px, 24vw, 94px); }
}

@media (prefers-reduced-motion: reduce) {
  .mini-box, .circle-tile-score { animation: none; }
  .mini-clock.urgent { animation: none; }
  .magnet-flip, .magnet-label { transition: none; }
}

/* ============================================================
   v3.3 — Geen ongewenste tekstselectie in de interface
   Snel dubbelklikken of vegen selecteerde tekst en liet blauwe
   markeringen achter over de kaarten en knoppen. De hele UI is nu
   onselecteerbaar; alleen waar je écht tekst wilt kunnen pakken
   (invoervelden, chat, lobbycode, handleiding) blijft het aan.
   ============================================================ */
body {
  -webkit-user-select: none;
  user-select: none;
  /* Geen blauwe flits bij tikken en geen "kopiëren"-menu bij lang indrukken. */
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

/* Uitzonderingen: hier mág je selecteren. */
input,
textarea,
select,
.chat-log,
.chat-message,
.lobby-code,
.help-body,
#overlay-stats .stats-groups,
.lb-popover,
.log-body {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

/* Dubbelklikken op een kaart of knop mag nooit iets markeren. */
.card,
.btn,
.seat,
.avatar-option,
.color-swatch,
.emote-btn,
.my-hand,
.table-center,
#seats {
  -webkit-user-select: none;
  user-select: none;
}

/* ============================================================
   v3.3 — Volledig scherm (vierde ronde knop rechtsonder)
   Verborgen zolang de browser het niet ondersteunt (o.a. Safari op
   iPhone); client.js haalt de `hidden`-class er dan niet af.
   ============================================================ */
.btn-fullscreen {
  position: fixed;
  bottom: 12px;
  right: 168px;
  z-index: 210;
  font-size: 19px;
  line-height: 1;
  color: var(--text);
  background: rgba(16, 21, 48, 0.8);
  border: 1px solid var(--panel-border);
  border-radius: 50%;
  width: 44px; height: 44px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.btn-fullscreen:hover { transform: translateY(-2px); box-shadow: 0 0 14px rgba(124, 92, 255, 0.5); }

/* In volledig scherm blijft de knop bereikbaar om er weer uit te gaan. */
body.fullscreen .btn-fullscreen { background: rgba(124, 92, 255, 0.35); }

/* Volledig scherm haalt de browserbalken weg: dan mag de tafel de
   vrijgekomen hoogte gebruiken. */
body.fullscreen .screen { padding: 8px; }

@media (max-width: 520px) {
  .btn-fullscreen { width: 40px; height: 40px; right: 156px; font-size: 17px; }
}

/* v3.3 — "Meedoen met een code" is een eigen widget in de rechterkolom.
   Op mobiel stapelt de rechterkolom onder de linker, dus daar staat hij
   vanzelf direct onder "Lobby maken" — precies waar je hem verwacht. */
.join-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: panelRise 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both 0.25s; /* v3.5: 2e in de rij */
}
.join-panel .join-row { display: flex; gap: 10px; }
.join-hint { text-align: left; }

/* ============================================================
   Addendum v3.4 §3 — Prestaties (achievements)
   Tabbladen in het ranglijstpaneel, de badgestrook in het eigen
   statistiekvenster en de melding tijdens het spel.
   ============================================================ */

/* ---------- Tabbladen "Punten" / "Prestaties" ---------- */
.lb-tabs {
  display: flex;
  gap: 6px;
  border-bottom: 1px solid var(--panel-border);
  padding-bottom: 6px;
}
.lb-tab {
  flex: 1;
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: rgba(16, 21, 48, 0.4);
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 7px 10px;
  cursor: pointer;
  transition: color 0.14s ease, background 0.14s ease, border-color 0.14s ease;
}
.lb-tab:hover { color: var(--text); background: rgba(124, 92, 255, 0.14); }
.lb-tab.active {
  color: var(--text);
  background: rgba(124, 92, 255, 0.22);
  border-color: rgba(124, 92, 255, 0.5);
  box-shadow: 0 0 12px rgba(124, 92, 255, 0.28);
}
.lb-tab:focus-visible { outline: 2px solid var(--neon-2); outline-offset: 2px; }
.lb-pane { display: flex; flex-direction: column; gap: 10px; }

/* ---------- De badge zelf: PNG-achtergrond + categorie-icoon ervoor ---------- */
.ach-badge {
  --ach-size: 34px;
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--ach-size);
  height: var(--ach-size);
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  border-radius: 50%;
}
.ach-badge-small { --ach-size: 24px; }
.ach-badge-big { --ach-size: 60px; }
.ach-icon-img {
  width: 56%;
  height: 56%;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
}
.ach-icon-emoji {
  font-size: calc(var(--ach-size) * 0.52);
  line-height: 1;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.65);
}

/* Zonder manifest.badges tekent de CSS zelf een schijfje in de niveaukleur. */
.ach-badge.no-asset {
  border: 2px solid rgba(255, 255, 255, 0.28);
  box-shadow: inset 0 1px 4px rgba(255, 255, 255, 0.22), 0 2px 6px rgba(0, 0, 0, 0.45);
}
.ach-badge.no-asset.level-good { background: linear-gradient(150deg, #d9975a, #8c5a2b); }
.ach-badge.no-asset.level-better { background: linear-gradient(150deg, #1a2044, #9aa3b8); }
.ach-badge.no-asset.level-best { background: linear-gradient(150deg, #ffe27a, #d9a520); }
.ach-badge.no-asset.level-godlike { background: var(--rainbow); }

/* Godlike mag opvallen: een zachte regenbooggloed rondom. */
.ach-badge.level-godlike:not(.locked) {
  filter: drop-shadow(0 0 5px rgba(124, 92, 255, 0.75)) drop-shadow(0 0 9px rgba(255, 209, 102, 0.45));
}
.ach-badge.level-best:not(.locked) { filter: drop-shadow(0 0 4px rgba(255, 209, 102, 0.6)); }

/* Nog niet behaald: grijs en gedempt. */
.ach-badge.locked {
  filter: grayscale(1) brightness(0.55);
  opacity: 0.7;
}
.ach-badge.locked .ach-icon-emoji,
.ach-badge.locked .ach-icon-img { opacity: 0.8; }

/* ---------- Tabblad "Prestaties": spelers op prestatiescore ---------- */
.ach-board { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ach-row {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 8px;
  padding: 7px 4px;
  border-top: 1px solid var(--panel-border);
  cursor: help;
  will-change: transform, opacity;
}
.ach-row:first-child { border-top: none; }
.ach-row:first-child .ach-player { color: #ffd166; }
.ach-row:hover, .ach-row:focus, .ach-row:focus-visible {
  background: rgba(124, 92, 255, 0.14);
  border-radius: 8px;
  outline: none;
}
.ach-rank { font-size: 14px; font-weight: 800; }
.ach-player {
  font-size: 14px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ach-score {
  font-size: 14px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  color: var(--neon-2);
  text-align: right;
}
.ach-badges {
  grid-column: 2 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-top: 2px;
}
.ach-badges-none { font-size: 11.5px; color: var(--text-dim); font-style: italic; }
.ach-board-empty { padding: 2px 0; }

/* ---------- Badgestrook in "Mijn statistieken" ---------- */
.stats-achievements { display: flex; flex-direction: column; gap: 8px; }
.stats-ach-count { text-align: left; margin: -4px 0 0; }
.ach-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
  gap: 8px;
  max-height: min(34vh, 300px);
  overflow-y: auto;
  scrollbar-gutter: stable;
}
.ach-tile {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 9px;
  border-radius: 12px;
  background: rgba(120, 140, 255, 0.18);
  border: 1px solid rgba(5, 6, 15, 0.30);
  min-width: 0;
  will-change: transform, opacity;
}
.ach-tile.earned { border-color: rgba(255, 209, 102, 0.32); }
.ach-tile.locked { opacity: 0.72; }
.ach-tile-text { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.ach-tile-name {
  font-size: 13px;
  font-weight: 800;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ach-tile-sub { font-size: 11.5px; color: var(--text-dim); line-height: 1.25; }
.ach-tile.earned .ach-tile-sub { color: #ffd166; font-weight: 700; }

/* ---------- Melding tijdens het spel ---------- */
.ach-banner {
  position: fixed;
  left: 50%; top: 34%;
  transform: translate(-50%, -50%);
  z-index: 149;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 24px;
  max-width: min(92vw, 560px);
  background: rgba(16, 21, 48, 0.95);
  border: 2px solid rgba(255, 209, 102, 0.75);
  border-radius: 18px;
  box-shadow: 0 0 34px rgba(255, 209, 102, 0.42), 0 16px 50px rgba(0, 0, 0, 0.6);
  will-change: transform, opacity;
  pointer-events: none;
}
.ach-banner.level-godlike {
  border-color: rgba(124, 92, 255, 0.85);
  box-shadow: 0 0 40px rgba(124, 92, 255, 0.55), 0 0 70px rgba(255, 209, 102, 0.3), 0 16px 50px rgba(0, 0, 0, 0.6);
}
.ach-banner-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ach-banner-title {
  font-size: clamp(17px, 3.2vw, 24px);
  font-weight: 900;
  letter-spacing: 0.02em;
  background: linear-gradient(135deg, #fff3b0, #ffd166, #f1c40f);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.ach-banner.level-godlike .ach-banner-title { background: var(--rainbow); -webkit-background-clip: text; background-clip: text; }
.ach-banner-sub { font-size: 12.5px; font-weight: 600; color: var(--text-dim); }

@media (max-width: 520px) {
  .ach-strip { grid-template-columns: 1fr; max-height: min(38vh, 260px); }
  .ach-banner { gap: 10px; padding: 10px 16px; }
  .ach-badge-big { --ach-size: 48px; }
}

@media (prefers-reduced-motion: reduce) {
  .ach-badge.level-godlike:not(.locked), .ach-badge.level-best:not(.locked) { filter: none; }
}


/* ============================================================
   Addendum v3.5 — Beheer (rollen, live-overzicht, blokkades)
   Het paneel volgt bewust het schuifpatroon van het actielogboek en NIET het
   overlaypatroon: je moet ernaast kunnen blijven kijken terwijl je modereert.
   ============================================================ */
.btn-admin {
  position: fixed;
  bottom: 12px;
  right: 220px;              /* vijfde in de reeks 12/64/116/168 */
  z-index: 210;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(16, 21, 48, 0.8);
  border: 1px solid var(--panel-border);
  color: var(--text);
  font-size: 18px;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.btn-admin:hover { transform: translateY(-2px); box-shadow: 0 0 14px rgba(124, 92, 255, 0.5); }
.btn-admin.active { border-color: var(--neon); box-shadow: 0 0 14px rgba(124, 92, 255, 0.55); }

.admin-panel {
  position: fixed;
  top: 8px;
  right: 8px;
  bottom: 64px;
  width: min(420px, 94vw);
  z-index: 99;               /* zelfde laag als het logboek: onder de overlays */
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 12px 10px;
  background: rgba(13, 17, 40, 0.97);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  box-shadow: -14px 0 44px rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(8px);
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.2s ease;
}
.admin-panel.hidden {
  display: flex !important;
  transform: translateX(calc(100% + 16px));
  opacity: 0;
  pointer-events: none;
}
.admin-unlock { display: flex; flex-direction: column; gap: 8px; }
.admin-unlock.hidden { display: none !important; }
.admin-error { color: var(--danger); text-align: left; }
.admin-details { border-top: 1px solid var(--panel-border); padding-top: 8px; }
.admin-details summary { cursor: pointer; font-size: 13px; color: var(--text-dim); }
.admin-details > * + * { margin-top: 8px; }
.admin-body { display: flex; flex-direction: column; gap: 10px; min-height: 0; flex: 1; }
.admin-body.hidden { display: none !important; }
.admin-tabs { flex-wrap: wrap; }
.admin-tabs .lb-tab { font-size: 12px; padding: 5px 8px; }
.admin-pane { min-height: 0; flex: 1; overflow-y: auto; overflow-x: hidden; }
.admin-pane.hidden { display: none !important; }
.admin-sub {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--neon-2);
  margin: 10px 0 6px;
}
.admin-row { display: flex; gap: 8px; align-items: center; }
.admin-row input { flex: 1; min-width: 0; }
.admin-counts { display: grid; grid-template-columns: repeat(auto-fit, minmax(88px, 1fr)); gap: 8px; }
.admin-count {
  background: rgba(120, 140, 255, 0.18);
  border: 1px solid rgba(5, 6, 15, 0.30);
  border-radius: 10px;
  padding: 8px;
  text-align: center;
}
.admin-count b { display: block; font-size: 18px; font-variant-numeric: tabular-nums; }
.admin-count span { font-size: 11px; color: var(--text-dim); }
.admin-list { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.admin-item {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  background: rgba(120, 140, 255, 0.18);
  border: 1px solid rgba(5, 6, 15, 0.30);
  border-radius: 10px;
  padding: 7px 9px;
  font-size: 13px;
}
.admin-item .grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.admin-item .meta { font-size: 11px; color: var(--text-dim); }
.admin-item .btn { padding: 3px 8px; font-size: 12px; }
.admin-tag {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 6px;
  border-radius: 999px;
  border: 1px solid var(--panel-border);
  color: var(--text-dim);
}
.admin-tag.rol-admin { color: var(--neon-2); border-color: rgba(255, 209, 102, 0.4); }
.admin-tag.rol-eigenaar { color: var(--yellow); border-color: rgba(255, 210, 80, 0.45); }
.admin-tag.live { color: var(--green); border-color: rgba(80, 220, 140, 0.4); }
.lobby-code-small { font-family: monospace; letter-spacing: 0.16em; color: var(--neon-2); }
.admin-watch { border-top: 1px solid var(--panel-border); margin-top: 10px; padding-top: 8px; }
.admin-chart { display: flex; align-items: flex-end; gap: 2px; height: 90px; }
.admin-bar { flex: 1; min-width: 2px; background: linear-gradient(180deg, var(--neon-2), var(--neon)); border-radius: 2px 2px 0 0; }
.admin-bar.leeg { background: rgba(120, 140, 255, 0.15); }

/* Mobiel: bodemvel, met ruimte onderin voor de ronde knopjes. */
@media (max-width: 759px) {
  .admin-panel {
    top: auto;
    left: 8px;
    right: 8px;
    bottom: 0;
    width: auto;
    height: 76vh;
    max-height: 80%;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    padding-bottom: 62px;
    box-shadow: 0 -14px 44px rgba(0, 0, 0, 0.6);
  }
  .admin-panel.hidden { transform: translateY(calc(100% + 16px)); }
}
@media (max-width: 520px) {
  .btn-admin { width: 40px; height: 40px; right: 204px; }
}
@media (prefers-reduced-motion: reduce) {
  .admin-panel { transition: none; }
}

/* Het oogje in de lobby: spelers zien dat er meegekeken wordt. */
.lobby-watchers {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--neon-2);
  border: 1px solid rgba(255, 209, 102, 0.35);
  border-radius: 999px;
  padding: 2px 8px;
  margin-left: 8px;
}
.lobby-watchers.hidden { display: none !important; }


/* Versiemerk onderaan het hulpvenster: het hoort er te staan, maar niets
   eromheen mag ervoor wijken. */
.help-versie {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--panel-border);
  font-size: 12px;
  color: var(--text-dim);
  text-align: center;
}

/* ============================================================
   v3.6 — de meteorenregen bij de kreet
   ============================================================ */
.meteor-field {
  position: absolute;
  inset: 0;
  /* De strepen vliegen ver voorbij de rand; zonder dit zou dat de pagina
     kunnen oprekken. */
  overflow: hidden;
}
.meteor {
  position: absolute;
  top: -14%;
  /* 2px viel op een groot scherm weg tegen de sterren eronder. */
  width: 3px;
  border-radius: 3px;
  /* Fel aan de kop, uitlopend in niets aan de staart — zonder dat verloop is
     het een stokje en geen meteoor. De kop is de ONDERKANT: hij valt. */
  background: linear-gradient(to top, var(--meteor-kleur, #fff), transparent);
  box-shadow: 0 0 14px var(--meteor-kleur, #fff);
  will-change: transform, opacity;
}


/* ============================================================
   v3.6 — liggend op een telefoon (lage schermen)

   Alles hier hangt aan de HOOGTE. De bestaande mobiele regels kijken naar de
   breedte, en een telefoon in liggende stand is breed maar laag: die regels
   sloegen dus nooit aan, en de tafel duwde je eigen kaarten van het scherm.
   Doel van dit blok: het speelveld past in één beeld, zonder scrollen.
   ============================================================ */
@media (max-height: 560px) and (orientation: landscape) {
  :root {
    --card-w: 54px;
    --card-h: 79px;
    --table-tilt: 30deg;
    --dir-r: 92px;
    --seat-w: 64px;
  }
  .screen { padding: 4px 8px; }
  /* Los erbij, want `#screen-game` is een id en wint van `.screen` hierboven:
     zonder deze regel hield juist het krapste scherm de bureaubladmarge van
     8 px. Alleen boven/onder — links/rechts laat het logpaneel met rust. */
  #screen-game { padding-top: 4px; padding-bottom: 4px; }

  /* Het speelveld is hier een DOOS, geen bladzijde: precies zo hoog als het
     scherm echt is, en hij scrollt niet. Dit is de eigenlijke reparatie van
     "ik zie mijn kaarten niet, ik moet van boven naar onder scrollen". Wat er
     ook aan inhoud bijkomt, het kan het beeld niet meer uit duwen — de tafel
     hierboven geeft mee, want die is het enige dat mag rekken. */
  #screen-game {
    height: 100vh;
    height: var(--app-h, 100dvh);
    min-height: 0;
    overflow: hidden;
  }
  .game-inner { min-height: 0; height: 100%; }

  /* De tafel: breed en laag, en hij VULT wat er overblijft in plaats van een
     vaste hoogte op te eisen. Met `height: min(52vh, 260px)` vroeg hij op een
     scherm van 320 px nog 166 px op terwijl er 130 over was; nu krimpt hij
     vanzelf mee en is 260 px alleen nog een bovengrens. */
  .table-scene { min-height: 0; height: auto; flex: 1 1 auto; max-height: min(52vh, 260px); }
  .table-felt {
    width: calc(min(94%, 760px) * var(--felt-breed, 1));
    height: min(150%, 290px);
    border-width: 6px;
  }

  /* Stoelen compacter, net als in de smalle indeling. */
  .seat-avatar-wrap { width: 40px; height: 40px; }
  .seat-avatar { width: 36px; height: 36px; font-size: 20px; }
  .seat-name { font-size: 9px; }
  .seat-fan { width: 52px; height: 20px; }
  .mini-back { width: 10px; height: 15px; margin-left: -5px; }
  .seat-count { margin-top: 6px; font-size: 9px; }
  .seat-seconds { font-size: 14px; top: -6px; right: -12px; }
  .round-hud { font-size: 9px; }

  /* De hand houdt maar net genoeg lucht om een kaart te kunnen optillen. */
  .my-hand {
    padding: 16px 8px 2px;
    min-height: calc(var(--card-h) + 18px);
  }
  .my-hand .card { margin-left: calc(var(--card-w) * -0.42); }
  .card .center .big-num { font-size: 30px; }

  .my-countdown { font-size: 18px; min-width: 46px; }
  .my-buttons { min-height: 44px; gap: 8px; }
  .emote-btn { width: 26px; height: 26px; font-size: 13px; }
  .emote-bar { gap: 4px; }

  /* De ronde knopjes rechtsonder mogen niet over de kaarten vallen. */
  .btn-mute, .btn-help, .btn-lang, .btn-fullscreen, .btn-admin {
    width: 34px;
    height: 34px;
    bottom: 6px;
  }
  .btn-mute { right: 8px; }
  .btn-help { right: 48px; }
  .btn-lang { right: 88px; }
  .btn-fullscreen { right: 128px; }
  .btn-admin { right: 168px; }

  /* Het röntgenpaneel past hier niet naast de hand: leg het over de tafel,
     halfdoorzichtig, in plaats van boven de kaarten die je nodig hebt. */
  .xray-panel {
    bottom: auto;
    top: 6px;
    left: 6px;
    width: min(240px, 42vw);
    max-height: min(58vh, 200px);
    padding: 8px;
  }
  .xray-cards .card { width: 38px; height: 56px; }
  .xray-cards .card .big-num { font-size: 19px; }

  /* Overlays mogen op een laag scherm niet buiten beeld lopen. */
  .overlay-box { max-height: 92vh; overflow-y: auto; padding: 14px 16px; }

  /* v3.15 — Cirkel liggend: hoogte is hier het schaarse goed, breedte niet.
     Jouw tekenvlak krijgt daarom zoveel hoogte als er is en de kijkvensters
     van de anderen worden postzegels; die staan eronder en mogen wegscrollen.
     Zonder deze regel deelt jouw vak de hoogte met een rij medespelers en hou
     je een vakje over waarin je met een vinger geen ronde cirkel krijgt. */
  .circle-grid { grid-template-columns: repeat(auto-fit, minmax(64px, 82px)); gap: 6px; }
  /* Gemeten, niet gegokt: van 390 px scherm blijft er na kop, hint, knoppenrij
     en alle marges 205 px over voor het tegelraster. Daar moeten de kop van je
     eigen tegel (18) en zijn marges (12) nog af, dus 0,44 × de echte
     schermhoogte is precies wat er heel in past — bij 390 px is dat 171. Meer
     nemen betekent dat je onderrand wegvalt en je alsnog moet scrollen, en dat
     was nou juist de klacht. */
  .circle-tile.mine .circle-stage {
    width: min(300px, 44vh);
    width: min(300px, calc(var(--app-h, 100dvh) * 0.44));
  }
  .circle-tile { padding: 4px; gap: 4px; }
  .circle-tile-head { min-height: 18px; font-size: 10px; }
  /* Kop en klok compacter: elke pixel hier is een pixel tekenvlak. */
  .mini-title { font-size: 18px; }
  .mini-clock { font-size: 22px; }
  .mini-hint { font-size: 11px; }
  .mini-box { padding: 10px 14px; gap: 8px; }
}


/* v3.6 — de kaart die je zojuist van een ander pakte licht kort op. De hand is
   gesorteerd, dus een nieuwe kaart komt ergens in het midden terecht; zonder
   dit merk je niet eens dat je hem hebt. */
.my-hand .card.card-arrived {
  animation: kaartAangekomen 1.4s ease-out both;
  z-index: 6;
}
@keyframes kaartAangekomen {
  0%   { box-shadow: 0 0 0 3px var(--neon-2), 0 0 26px 8px rgba(33, 212, 253, 0.85); transform: translateY(-14px) scale(1.06); }
  35%  { box-shadow: 0 0 0 3px var(--neon-2), 0 0 22px 6px rgba(33, 212, 253, 0.6); transform: translateY(-8px) scale(1.03); }
  100% { box-shadow: none; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .my-hand .card.card-arrived { animation: none; box-shadow: 0 0 0 3px var(--neon-2); }
}

/* v3.6 — de meter haalde de 12 nooit in beeld: de engine laadt en laat de storm
   in dezelfde handeling los, dus je zag 11/12 en dan 0/12. Bij een storm houdt
   de balk nu even 12/12 vast, zichtbaar vol, voordat hij leegloopt. */
.chaos-wrap.chaos-vol .chaos-fill {
  animation: chaosVol 0.28s ease-out infinite alternate;
  box-shadow: 0 0 14px 3px rgba(216, 51, 47, 0.7);
}
.chaos-wrap.chaos-vol .chaos-value { color: var(--red); font-weight: 800; }
.chaos-wrap.chaos-vol .chaos-bolt { transform: scale(1.25); }
@keyframes chaosVol {
  from { filter: brightness(1); }
  to   { filter: brightness(1.5); }
}
@media (prefers-reduced-motion: reduce) {
  .chaos-wrap.chaos-vol .chaos-fill { animation: none; }
}

/* ============================================================
   Addendum v3.16 — De storm zien aankomen

   Twee vragen moesten beantwoord: HOEVER is het nog, en WAT komt er?

   Het ontwerpcriterium is "hoe leest dit als het STILSTAAT". Het globale
   reduced-motion-blok hierboven (regel ~2186) zet met !important elke animatie
   en elke overgang uit; alles wat alleen in beweging iets zegt, zegt daar dus
   niets. Vandaar dat elk kanaal hier statisch werkt: telbare vakjes, een vaste
   streep, een teken, een woord. Kleur komt als DERDE, nooit als eerste.

   En alles telt licht OP. Geen vignet, geen verduistering, geen waas over het
   speelveld: bij elke stand van de meter blijven de kaarten even leesbaar.
   ============================================================ */

/* De meter werd een barometer: balk boven, voorteken eronder. Hij groeit alleen
   in hoogte als er daadwerkelijk iets aan te kondigen is. */
.chaos-wrap { flex-direction: column; align-items: stretch; gap: 4px; }
.chaos-row { display: flex; align-items: center; gap: 8px; }

/* Telbare vakjes ÓVER de vulling heen. Dit is het enige kanaal dat het doet
   zonder kleur, zonder beweging en zonder te kunnen lezen: je telt hoeveel
   vakjes er nog leeg zijn. Het aantal komt uit --chaos-max, dat client.js uit
   de view zet — zodat 12 op één plek staat en niet op twee. */
.chaos-bar { position: relative; }
.chaos-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0,
    transparent calc(100% / var(--chaos-max, 12) - 1px),
    rgba(5, 6, 15, 0.55) calc(100% / var(--chaos-max, 12) - 1px),
    rgba(5, 6, 15, 0.55) calc(100% / var(--chaos-max, 12))
  );
}

/* De streep waar de aankondiging begint. Die staat er van meet af aan, dus je
   ziet lang van tevoren hoever het nog is tot je weet wát er komt. */
.chaos-warnmark {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--chaos-warn, 0.8333) * 100%);
  width: 2px;
  margin-left: -1px;
  background: var(--neon-2);
  opacity: 0.7;
  pointer-events: none;
}

/* Het voorteken: teken, naam en gevolg. Alle drie verschijnen op DEZELFDE
   meterstand — het verschil tussen "aangekondigd" en "zo meteen" zit alleen in
   nadruk, nooit in inhoud. Anders weet een ziende speler eerder wat er komt dan
   iemand met een schermlezer. */
.chaos-omen {
  --omen: var(--neon-2);
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--omen) 55%, transparent);
  background-color: rgba(5, 6, 15, 0.74);
  background-image: var(--omen-pat, none);
  background-size: var(--omen-size, auto);
  text-align: left;
  animation: omenKomtOp 0.8s ease-out both;
}
.chaos-omen-sign { font-size: 16px; line-height: 1; flex: none; }
.chaos-omen-woorden { display: flex; flex-direction: column; min-width: 0; }
.chaos-omen-name {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  color: var(--omen);
}
.chaos-omen-desc {
  font-size: 10px;
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@keyframes omenKomtOp { from { opacity: 0; transform: translateY(-5px); } }

/* Meer NADRUK als het bijna zover is, geen nieuwe informatie. */
.chaos-wrap.high .chaos-omen { border-width: 2px; padding: 4px 10px; }
.chaos-wrap.high .chaos-omen-name { font-size: 12px; }

/* Vier patronen die ook STILSTAAND uit elkaar te houden zijn: schuine strepen
   (regen), ringen (cycloon), vier kleurbanen (kleurenstorm), stippen
   (traktatie). --omen staat op de body zodat de tafelrand hem ook erft. */
body[data-storm="REGEN"] {
  --omen: #6ec6ff;
  --omen-pat: repeating-linear-gradient(72deg, rgba(110, 198, 255, 0.28) 0 2px, transparent 2px 8px);
}
body[data-storm="CYCLOON"] {
  --omen: #b48cff;
  --omen-pat: repeating-radial-gradient(circle at 14% 50%, rgba(180, 140, 255, 0.30) 0 2px, transparent 2px 8px);
}
body[data-storm="KLEURENSTORM"] {
  --omen: #ffd166;
  --omen-pat: repeating-linear-gradient(90deg,
    rgba(230, 57, 70, 0.26) 0 6px, rgba(241, 196, 15, 0.26) 6px 12px,
    rgba(39, 174, 96, 0.26) 12px 18px, rgba(45, 108, 223, 0.26) 18px 24px);
}
body[data-storm="TRAKTATIE"] {
  --omen: #7ce7a6;
  --omen-pat: radial-gradient(circle at 50% 50%, rgba(124, 231, 166, 0.34) 1.6px, transparent 2.2px);
  --omen-size: 9px 9px;
}

/* DE OMGEVING. Een ring in het tafelvlak die met de meter aanzwelt: bij een
   lege meter onzichtbaar, bij een volle duidelijk aanwezig — en zodra de storm
   bekend is in zijn kleur. Omdat dit pseudo-element in .table-felt zit erft hij
   de kanteling, dus de ring ligt IN de tafel en niet als plaatje erboven.
   Er wordt niets verduisterd: alleen licht erbij. */
.table-felt::after {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  pointer-events: none;
  border: 2px solid color-mix(in srgb, var(--omen, var(--neon-2)) 75%, transparent);
  opacity: calc(var(--chaos-frac, 0) * 0.8);
  box-shadow:
    0 0 calc(var(--chaos-frac, 0) * 46px) color-mix(in srgb, var(--omen, var(--neon-2)) 50%, transparent),
    inset 0 0 calc(var(--chaos-frac, 0) * 34px) color-mix(in srgb, var(--omen, var(--neon-2)) 30%, transparent);
  /* Opkomen mag je merken, wegebben hoort na te dooien: een storm wordt niet
     uitgeknipt. */
  transition: opacity 1.8s ease-out, box-shadow 1.8s ease-out, border-color 0.9s ease-out;
}

/* Kleurenblindmodus: NIET terugvallen op één kleur voor alle vier. Teken, woord
   en patroon dragen de betekenis al; de kleuren worden hier alleen naar tinten
   gebracht die ook bij rood-groenblindheid uit elkaar liggen. */
body.colorblind[data-storm="REGEN"] { --omen: #56b4e9; }
body.colorblind[data-storm="CYCLOON"] { --omen: #cc79a7; }
body.colorblind[data-storm="KLEURENSTORM"] { --omen: #f0e442; }
body.colorblind[data-storm="TRAKTATIE"] { --omen: #e69f00; }

/* Liggend is elke pixel er een: het gevolg valt weg, teken en naam blijven. */
@media (max-height: 560px) and (orientation: landscape) {
  .chaos-omen-desc { display: none; }
  .chaos-omen { padding: 2px 7px; gap: 5px; }
  .chaos-omen-sign { font-size: 13px; }
}

/* ============================================================
   Addendum v3.18 — De avatars reageren

   Vijf werkwoorden, elk één keyframe-set die in KRACHT varieert via --kr.
   Alle vijf raken UITSLUITEND transform aan (en één opacity op een pseudo bij
   zwellen): dat zijn de twee eigenschappen die de compositor zelf afhandelt,
   dus geen layout, geen paint per frame, en geen werk op de hoofddraad — waar
   het ambient-canvas van fx.js al zijn rAF-lus draait.

   HET ELEMENT IS EEN KEUZE, GEEN TOEVAL. Niet .seat (layoutSeats zet daar bij
   elke resize een transform op — dan vecht de animatie met de indeling), niet
   .seat-body (die wordt bij elke state-update leeggegooid), en vooral niet
   .seat-avatar-wrap: daar hangen de betrap-knop, het kroontje, de "1!"-alert en
   de timerring als absolute broertjes aan, en die moeten stilstaan en raakbaar
   blijven. Wél .seat-avatar: een flex-item midden in die wrap, dus transformeren
   verplaatst geen enkel broertje.

   De KLASSE staat op .seat en niet op de avatar zelf. Die overleeft namelijk de
   innerHTML-sloop van fillSeatBody; wordt de avatar midden in een reactie
   vervangen, dan start de animatie op het nieuwe element gewoon opnieuw in
   plaats van halverwege te bevriezen.
   ============================================================ */

/* 1. DEINZEN — "ik werd geraakt". Het enige werkwoord waarvan de RICHTING iets
      betekent: je deinst weg van wie je sloeg. Hard en kort in, dan terugveren. */
@keyframes avatarDeins {
  0%   { transform: translate(0, 0) scale(1); }
  14%  { transform: translate(calc(var(--rx, 0) * 9px * var(--kr, 1)), calc(var(--ry, 1) * 9px * var(--kr, 1)))
                    scale(calc(1 - 0.10 * var(--kr, 1))); }
  46%  { transform: translate(calc(var(--rx, 0) * 4px * var(--kr, 1)), calc(var(--ry, 1) * 4px * var(--kr, 1)))
                    scale(calc(1 + 0.03 * var(--kr, 1))); }
  100% { transform: translate(0, 0) scale(1); }
}

/* 2. VEREN — "dat deed ik". Squash, sprong, na-stuiter. Nooit een richting:
      een sprong is altijd omhoog. */
@keyframes avatarVeer {
  0%   { transform: translateY(0) scale(1, 1); }
  18%  { transform: translateY(0) scale(calc(1 + 0.10 * var(--kr, 1)), calc(1 - 0.12 * var(--kr, 1))); }
  48%  { transform: translateY(calc(-13px * var(--kr, 1)))
                    scale(calc(1 - 0.06 * var(--kr, 1)), calc(1 + 0.09 * var(--kr, 1))); }
  74%  { transform: translateY(0) scale(calc(1 + 0.06 * var(--kr, 1)), calc(1 - 0.07 * var(--kr, 1))); }
  100% { transform: translateY(0) scale(1, 1); }
}

/* 3. TRILLEN — "dit overkomt me en het houdt aan". Gedempt, alleen horizontaal,
      en met opzet GEEN helderheidswissel: dit verschuift een cirkel hooguit
      3 px en verandert geen enkele pixelkleur, dus het valt niet onder de
      flitsgrens waar de rest van dit project zich aan houdt. */
@keyframes avatarTril {
  0%, 100% { transform: translateX(0); }
  12% { transform: translateX(calc(-3px * var(--kr, 1))); }
  30% { transform: translateX(calc(3px * var(--kr, 1))); }
  50% { transform: translateX(calc(-2.1px * var(--kr, 1))); }
  70% { transform: translateX(calc(1.5px * var(--kr, 1))); }
  86% { transform: translateX(calc(-1.2px * var(--kr, 1))); }
}

/* 4. KNIKKEN — "ik kijk naar jou". Leunen naar iets toe met een kleine
      kanteling mee. Gebruikt dezelfde --rx/--ry, maar client.js draait het
      teken om: die twee betekenen overal "de kant waar de avatar heen gaat". */
@keyframes avatarKnik {
  0%   { transform: translate(0, 0) rotate(0deg); }
  35%  { transform: translate(calc(var(--rx, 0) * 6px * var(--kr, 1)), calc(var(--ry, 1) * 6px * var(--kr, 1)))
                    rotate(calc(var(--rx, 0) * 5deg * var(--kr, 1))); }
  70%  { transform: translate(calc(var(--rx, 0) * 5px * var(--kr, 1)), calc(var(--ry, 1) * 5px * var(--kr, 1)))
                    rotate(calc(var(--rx, 0) * 4deg * var(--kr, 1))); }
  100% { transform: translate(0, 0) rotate(0deg); }
}

/* 5. ZWELLEN — "kijk mij nou". Groot worden en blijven, met een ring eromheen.
      Het enige werkwoord dat een pseudo-element gebruikt. */
@keyframes avatarZwel {
  0%   { transform: scale(1); }
  30%  { transform: scale(calc(1 + 0.16 * var(--kr, 1))); }
  60%  { transform: scale(calc(1 + 0.10 * var(--kr, 1))); }
  100% { transform: scale(1); }
}
@keyframes avatarZwelRing {
  0%   { opacity: 0; transform: scale(0.8); }
  40%  { opacity: 0.9; transform: scale(1.15); }
  100% { opacity: 0; transform: scale(1.5); }
}

.seat.reageert-deins .seat-avatar { animation: avatarDeins 520ms cubic-bezier(0.2, 0.9, 0.3, 1) both; will-change: transform; }
.seat.reageert-veer  .seat-avatar { animation: avatarVeer 440ms cubic-bezier(0.34, 1.56, 0.64, 1) both; will-change: transform; }
.seat.reageert-tril  .seat-avatar { animation: avatarTril 480ms linear both; will-change: transform; }
.seat.reageert-knik  .seat-avatar { animation: avatarKnik 520ms ease-in-out both; will-change: transform; }
.seat.reageert-zwel  .seat-avatar { animation: avatarZwel 620ms cubic-bezier(0.34, 1.56, 0.64, 1) both; will-change: transform; }

/* will-change staat BEWUST alleen binnen deze vijf regels en niet op
   .seat-avatar zelf. Permanent zou de browser bij tien spelers het hele potje
   tien lagen levend houden; nu bestaat een laag alleen de halve seconde dat er
   echt iets beweegt. */

.seat.reageert-zwel .seat-avatar-wrap::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px solid var(--neon-2);
  pointer-events: none;
  animation: avatarZwelRing 620ms ease-out both;
}

/* ---------- Zonder beweging: een ander zintuig, niet een zwakkere versie ----------
   Het globale reduced-motion-blok zet met !important élke animatieduur op
   0,001 s, dus alle vijf werkwoorden zijn daar dood. Wat overblijft moet
   volwaardig zijn: kleur ÉN vorm (kleur alleen faalt bij kleurenblindheid, en
   dit spel heeft daar een hele modus voor), en het blijft langer staan dan de
   beweging duurt — een stilstaand teken heeft leestijd nodig. client.js rekent
   daar al mee: 900 ms in plaats van de animatieduur. */
@media (prefers-reduced-motion: reduce) {
  .seat[class*="reageert-"] .seat-avatar { position: relative; }
  .seat[class*="reageert-"] .seat-avatar::before {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    font-size: 15px;
    line-height: 1;
    padding: 2px 3px;
    text-shadow: 0 1px 3px #000;
  }
  .seat.reageert-deins .seat-avatar { border-color: var(--danger); box-shadow: 0 0 0 3px var(--danger); }
  .seat.reageert-deins .seat-avatar::before { content: "\2621"; color: var(--danger); }
  .seat.reageert-veer .seat-avatar { border-color: var(--neon-2); box-shadow: 0 0 0 3px rgba(255, 209, 102, 0.95); }
  .seat.reageert-veer .seat-avatar::before { content: "\2191"; color: var(--neon-2); }
  .seat.reageert-tril .seat-avatar { border-color: rgba(155, 232, 255, 0.95); box-shadow: 0 0 0 3px rgba(155, 232, 255, 0.85); }
  .seat.reageert-tril .seat-avatar::before { content: "\2744"; color: #9be8ff; }
  .seat.reageert-knik .seat-avatar { border-color: #7c5cff; box-shadow: 0 0 0 3px rgba(124, 92, 255, 0.9); }
  .seat.reageert-knik .seat-avatar::before { content: "\2192"; color: #c9bfff; }
  .seat.reageert-zwel .seat-avatar { box-shadow: 0 0 0 3px #ffd166, 0 0 0 6px rgba(124, 92, 255, 0.8); }
  .seat.reageert-zwel .seat-avatar::before { content: "\2605"; color: #ffd166; }
}


/* ============================================================
   Addendum v3.21 §2 — de schildjes rond de avatar

   Ze liggen IN de avatarschijf, niet eromheen. Buiten de schijf is namelijk
   geen plek: tussen de rand (straal 31) en de binnenkant van de timerring
   (32,66) zit 1,66 px, en verder naar buiten botst een ring tegelijk met de
   betrap-knop, het kroontje, de "1!"-melding en de verbindingsstip. Die
   moeten alle vier leesbaar en raakbaar blijven — de betrap-knop is in v3.19
   juist expres groter gemaakt.

   Het schildje raakt `border` en `box-shadow` van .seat-avatar nooit aan: die
   dragen "jij bent aan de beurt" en "bevroren", en dat zijn spelsignalen die
   voorgaan op sier.
   ============================================================ */
.avatar-schild {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 50%;
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
  pointer-events: none;
}
/* De avatar krimpt binnen de ring, zodat het gezicht vrij blijft. */
.seat-avatar.heeft-schild .avatar-img { width: 76%; height: 76%; }
.seat-avatar.heeft-schild { font-size: 27px; }

/* De kiezer op de startpagina. Elke tegel toont JOUW avatar met dat schildje:
   je kiest een combinatie, en een los ringetje zegt daar niets over. */
.frame-field { margin-top: 10px; }
.frame-picker {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin-top: 6px;
}
.frame-voorbeeld {
  position: relative;
  width: 46px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  margin: 0 auto;
}
.frame-voorbeeld.heeft-schild .avatar-img { width: 76%; height: 76%; }
.frame-voorbeeld.heeft-schild { font-size: 20px; }
.frame-voorbeeld .avatar-img { width: 100%; height: 100%; object-fit: contain; }
.frame-hint { font-size: 11px; margin-top: 4px; }
@media (max-width: 520px) {
  .frame-picker { grid-template-columns: repeat(3, 1fr); }
}

/* ============================================================
   Addendum v3.26 §2 — "deze pagina loopt achter"

   Bewust NIET blokkerend: je kunt gewoon doorspelen, want midden in een potje
   afgekapt worden is erger dan even met oude code spelen. Maar hij staat er
   wel, want zonder signaal weet niemand dat zijn tabblad achterloopt — en sinds
   v3.20 tekent zo iemand een cirkel terwijl de server een vierkant rekent.
   ============================================================ */
.verouderd {
  position: fixed;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  z-index: 210;               /* boven de toasts (200), onder niets anders */
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(560px, 94vw);
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(9, 12, 28, 0.94);
  border: 1px solid var(--neon-2);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.6);
  font-size: 13px;
  color: var(--text);
}
.verouderd-knop { padding: 6px 12px; font-size: 13px; flex: none; }
@media (max-height: 560px) and (orientation: landscape) {
  /* Liggend zit de onderrand vol met de hand en de knoppenbalk. */
  .verouderd { bottom: auto; top: 8px; font-size: 12px; padding: 7px 10px; }
}
