:root {
  --bg-dark: #0f172a;
  --bg-gradient: radial-gradient(circle at 50% -20%, #1e1b4b 0%, #0f172a 70%);
  --glass-bg: rgba(255, 255, 255, 0.03);
  --glass-border: rgba(255, 255, 255, 0.08);
  --glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3);
  --primary: #3b82f6;
  --primary-hover: #2563eb;
  --success: #10b981;
  --warning: #f59e0b;
  --danger: #ef4444;
  --text: #f8fafc;
  --muted: #94a3b8;
  --radius: 20px;
  --font: 'Outfit', sans-serif;
  --qzr-safe-top: env(safe-area-inset-top, 0px);
  --qzr-safe-right: env(safe-area-inset-right, 0px);
  --qzr-safe-bottom: env(safe-area-inset-bottom, 0px);
  --qzr-safe-left: env(safe-area-inset-left, 0px);
}

/* Base resets specifically for realtime panels */
#quizRealTimeContainer * {
  box-sizing: border-box;
}

/* In the simulator, this was body. Providing a modifier class for the app container */
body.realtime-active {
  font-family: var(--font) !important;
  background: var(--bg-gradient) !important;
  background-color: var(--bg-dark) !important;
  color: var(--text) !important;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
}

/* The app-shell topbar must never show while a realtime session (lobby or game)
   is active, at ANY viewport width. The mobile shell already hides it via a
   max-width media query; this guarantees the same on tablet/desktop regardless
   of the router's fade timing (the topbar is a <div>, so the realtime header
   fade-out doesn't cover it). */
body.realtime-active #app-shell-topbar,
body.realtime-active .qzr-shell-topbar {
  display: none !important;
}

body.theme-1.realtime-active {
  background: var(--qz-screen, #f5f8fc) !important;
  background-color: var(--qz-screen, #f5f8fc) !important;
  color: var(--qz-text, #12263f) !important;
}

body.theme-1 #quizRealTimeContainer {
  --bg-dark: var(--qz-screen, #f5f8fc);
  --bg-gradient: linear-gradient(180deg, var(--qz-screen, #f5f8fc) 0%, color-mix(in srgb, var(--qz-surface, #fff) 82%, #eef4fa) 100%);
  --glass-bg: color-mix(in srgb, var(--qz-surface, #fff) 92%, transparent);
  --glass-border: color-mix(in srgb, var(--qz-line, #dfe7f1) 82%, transparent);
  --glass-shadow: var(--qz-shadow-sm);
  --primary: var(--qz-accent);
  --primary-hover: color-mix(in srgb, var(--qz-accent) 82%, #111827);
  --text: var(--qz-text, #12263f);
  --muted: var(--qz-muted, #5b6f87);
  background: var(--bg-gradient);
  color: var(--text);
}

body.theme-1 #quizRealTimeContainer > * {
  color: var(--text);
}

body.theme-1 #quizRealTimeContainer .glass-panel {
  background: var(--glass-bg);
  border-color: var(--glass-border);
  box-shadow: var(--glass-shadow);
}

body.theme-1 #quizRealTimeContainer h1 {
  background: linear-gradient(135deg, var(--qz-accent), var(--qz-accent-deep));
  -webkit-background-clip: text;
  background-clip: text;
}

body.theme-1 #quizRealTimeContainer input,
body.theme-1 #quizRealTimeContainer select,
body.theme-1 #quizRealTimeContainer textarea {
  background: color-mix(in srgb, var(--qz-surface, #fff) 86%, #eef4fa);
  border-color: var(--glass-border);
  color: var(--text);
}

body.theme-1 #quizRealTimeContainer input:focus,
body.theme-1 #quizRealTimeContainer select:focus,
body.theme-1 #quizRealTimeContainer textarea:focus {
  border-color: var(--primary);
  box-shadow: var(--qz-focus-ring, 0 0 0 4px rgba(255, 122, 69, 0.18));
}

body.theme-1 #quizRealTimeContainer .btn-secondary {
  background: color-mix(in srgb, var(--qz-surface, #fff) 86%, #eef4fa);
  color: var(--text);
  border-color: var(--glass-border);
}

body.theme-1 #quizRealTimeContainer .badge:not(.connected):not(.host) {
  background: color-mix(in srgb, var(--qz-surface, #fff) 78%, #eef4fa);
  color: var(--text);
  border: 1px solid var(--glass-border);
}

body.theme-1 #quizRealTimeContainer .text-white,
body.theme-1 #quizRealTimeContainer .text-light {
  color: var(--text) !important;
}

body.theme-1 #quizRealTimeContainer .text-muted {
  color: var(--muted) !important;
}

body.theme-1 #quizRealTimeContainer .bg-dark-subtle {
  background-color: color-mix(in srgb, var(--qz-accent) 12%, var(--qz-surface, #fff)) !important;
}

/* Explicit exception to restore FontAwesome visibility against the !important font override */
body.realtime-active i[class*="fa-"],
body.realtime-active [class*="fa-solid"],
body.realtime-active [class*="fas"],
body.realtime-active [class*="fab"],
body.realtime-active [class*="far"] {
  font-family: "Font Awesome 6 Free", "Font Awesome 5 Free", "FontAwesome" !important;
}

/* Goal badge selection for showcase */
.goals-badges-track .goal-badge {
  cursor: pointer;
  transition: transform var(--qz-dur-ui), box-shadow var(--qz-dur-ui);
}

.goals-badges-track .goal-badge.goal-badge--selected {
  /* outline: 2px solid var(--bs-warning, #ffc107); */
  outline-offset: 2px;
  /* transform: scale(1.05); */
  /* box-shadow: 0 0 0 4px rgba(255,193,7,.25); */
}

#quizRealTimeContainer h1,
#quizRealTimeContainer h2,
#quizRealTimeContainer h3 {
  font-weight: 900;
  letter-spacing: 0;
}

#quizRealTimeContainer h1 {
  font-size: 2rem;
  background: linear-gradient(135deg, #60a5fa, #3b82f6);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.subtitle {
  color: var(--muted);
  font-size: 0.95rem;
  font-weight: 500;
}

/* Layout Components */
.app-container {
  max-width: 1200px;
  margin: 0 auto;
  /* padding: 24px; */
  width: 100%;
  flex-grow: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 350px;
  gap: 24px;
}

#quizRealTimeContainer.app-container {
  min-height: calc(100dvh - var(--qzr-safe-top) - var(--qzr-safe-bottom));
  padding-top: max(24px, var(--qzr-safe-top));
  padding-right: max(24px, var(--qzr-safe-right));
  padding-bottom: max(24px, var(--qzr-safe-bottom));
  padding-left: max(24px, var(--qzr-safe-left));
}

@media (max-width: 900px) {
  .app-container {
    grid-template-columns: 1fr;
  }

  #quizRealTimeContainer.app-container {
    padding-top: max(16px, var(--qzr-safe-top));
    padding-right: max(16px, var(--qzr-safe-right));
    padding-bottom: max(16px, var(--qzr-safe-bottom));
    padding-left: max(16px, var(--qzr-safe-left));
  }
}

/* Glassmorphism Panel */
.glass-panel {
  background: var(--glass-bg);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius);
  box-shadow: var(--glass-shadow);
  padding: 24px;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

/* View Management */
.view {
  display: none;
  animation: fadeIn 0.4s ease forwards;
}

.view.active {
  display: block;
}

#viewWaiting.active {
  display: flex;
  flex-direction: column;
  min-height: 65vh;
  justify-content: center;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

#quizRealTimeContainer label {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

#quizRealTimeContainer input,
#quizRealTimeContainer select,
#quizRealTimeContainer textarea {
  font-family: var(--font);
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid var(--glass-border);
  color: white;
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 1rem;
  transition: all var(--qz-dur-ui) ease;
}

#quizRealTimeContainer input:focus,
#quizRealTimeContainer select:focus,
#quizRealTimeContainer textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
}

#quizRealTimeContainer textarea {
  min-height: 100px;
  resize: vertical;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

/* Buttons */
#quizRealTimeContainer .btn {
  font-family: var(--font);
  font-weight: 700;
  border: none;
  border-radius: 12px;
  padding: 14px 24px;
  font-size: 1rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: all var(--qz-dur-ui) ease;
  position: relative;
  overflow: hidden;
}

#quizRealTimeContainer .btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(rgba(255, 255, 255, 0.1), transparent);
  opacity: 0;
  transition: opacity var(--qz-dur-ui) ease;
}

#quizRealTimeContainer .btn:hover::after {
  opacity: 1;
}

#quizRealTimeContainer .btn:active {
  transform: scale(var(--qz-press-scale));
}

#quizRealTimeContainer .btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

#quizRealTimeContainer .btn-primary {
  background: var(--primary);
  color: white;
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
}

#quizRealTimeContainer .btn-success {
  background: var(--success);
  color: white;
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
}

#quizRealTimeContainer .btn-secondary {
  background: rgba(255, 255, 255, 0.1);
  color: white;
  border: 1px solid var(--glass-border);
}

#quizRealTimeContainer .btn-block {
  width: 100%;
}

/* Badges & Tags */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 30px;
  font-size: 0.8rem;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.1);
  color: var(--text);
}

.badge.connected {
  background: rgba(16, 185, 129, 0.2);
  color: #34d399;
  border: 1px solid rgba(16, 185, 129, 0.3);
}

.badge.host {
  background: rgba(245, 158, 11, 0.2);
  color: #fbbf24;
  border: 1px solid rgba(245, 158, 11, 0.3);
}

/* Header */
.realtime-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 32px;
  border-bottom: 1px solid var(--glass-border);
  background: rgba(15, 23, 42, 0.5);
  backdrop-filter: blur(8px);
}

.logo-area {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo-icon {
  width: 36px;
  height: 36px;
  background: var(--primary);
  border-radius: 10px;
  display: grid;
  place-items: center;
  font-size: 1.2rem;
}

/* Players Grid */
.players-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
  margin-top: 24px;
}

.player-card {
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid var(--glass-border);
  border-radius: 16px;
  padding: 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  transition: transform var(--qz-dur-ui);
  color: var(--text);
}

.player-card:hover {
  transform: translateY(-2px);
  background: rgba(255, 255, 255, 0.05);
}

.avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--primary), #8b5cf6);
  display: grid;
  place-items: center;
  font-weight: 900;
  font-size: 1.2rem;
  color: white;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}

.player-info {
  display: flex;
  flex-direction: column;
}

.player-name {
  font-weight: 700;
  font-size: 1rem;
}

.player-status {
  font-size: 0.75rem;
  color: var(--muted);
}

/* Playground */
.playground-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.realtime-goal-hud-list {
  display: grid;
  gap: 10px;
  /* margin-bottom: 18px; */
  flex: 0 0 100%;
}

.realtime-goal-hud-card {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  padding: 10px 12px;
}

/* Slim solo HUD: progress bar + target value on one row (title/badge/left removed). */
.realtime-goal-hud-track {
  display: flex;
  align-items: center;
  gap: 10px;
}
.realtime-goal-hud-track .progress {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}
.realtime-goal-hud-track > span {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Circular Countdown Timer */
.timer-circle-wrap {
  position: relative;
  width: 80px;
  height: 80px;
  flex-shrink: 0;
}

.timer-circle-svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
  filter: drop-shadow(0 0 8px rgba(59, 130, 246, 0.35));
  transition: filter 0.4s ease;
}

.timer-circle-track {
  fill: none;
  stroke: rgba(255, 255, 255, 0.06);
  stroke-width: 5;
}

.timer-circle-progress {
  fill: none;
  stroke: url(#timerGradient);
  stroke-width: 5;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.25s ease;
}

.timer-circle-wrap .timer-text {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 1.6rem;
  font-weight: 900;
  color: var(--primary);
  text-shadow: 0 0 12px rgba(59, 130, 246, 0.35);
  font-variant-numeric: tabular-nums;
  transition: color 0.4s, text-shadow 0.4s;
  line-height: 1;
}

/* Urgent state (last 3 seconds) */
.timer-circle-wrap.urgent .timer-circle-svg {
  filter: drop-shadow(0 0 14px rgba(239, 68, 68, 0.6));
}

.timer-circle-wrap.urgent .timer-circle-progress {
  stroke: var(--danger);
}

.timer-circle-wrap.urgent .timer-text {
  color: var(--danger);
  text-shadow: 0 0 14px rgba(239, 68, 68, 0.5);
  animation: timerPulseText 0.8s infinite alternate;
}

@keyframes timerPulseText {
  from {
    transform: scale(1);
  }

  to {
    transform: scale(1.12);
  }
}

.question-box {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 20px;
  padding: 32px;
  text-align: center;
  margin-bottom: 32px;
  border: 1px solid var(--glass-border);
}

.question-title {
  font-size: 1.8rem;
  font-weight: 900;
  margin-bottom: 12px;
  line-height: 1.3;
  color: var(--text);
}

.answers-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.answers-grid--typed {
  grid-template-columns: 1fr;
}

.answer-btn {
  background: rgba(255, 255, 255, 0.05);
  border: 2px solid var(--glass-border);
  border-radius: 16px;
  padding: 24px;
  font-size: 1.2rem;
  font-weight: 700;
  color: white;
  cursor: pointer;
  transition: all var(--qz-dur-ui) cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  gap: 16px;
  text-align: left;
}

.answer-key {
  min-width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  display: grid;
  place-items: center;
  font-size: 0.9rem;
  font-weight: 900;
  color: var(--muted);
}

/* Hover is gated on a device that can actually hover. On touch, :hover STICKS
   to whatever was last tapped until something else is tapped — and because the
   answers are re-rendered for each question, the stale hover lands on whichever
   NEW option sits under the last tap point. Since the hover treatment is the
   same tint as .selected, the next question opened with an option looking
   already chosen. That is the reported bug, and it is why it happened
   "sometimes": it depends where the previous answer sat on screen. */
@media (hover: hover) {
  .answer-btn:hover:not(.disabled) {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.2);
    transform: translateY(-2px);
  }
}

.answer-btn.selected {
  background: rgba(59, 130, 246, 0.2);
  border-color: var(--primary);
}

.answer-btn.selected .answer-key {
  background: var(--primary);
  color: white;
}

@keyframes correctPulse {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
  }

  50% {
    transform: scale(1.05);
    box-shadow: 0 0 25px 10px rgba(16, 185, 129, 0);
  }

  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
  }
}

@keyframes wrongShake {

  0%,
  100% {
    transform: translateX(0);
  }

  20%,
  60% {
    transform: translateX(-8px);
  }

  40%,
  80% {
    transform: translateX(8px);
  }
}

.answer-btn.correct {
  background: rgba(16, 185, 129, 0.3) !important;
  border-color: var(--success) !important;
  animation: correctPulse 1.5s ease-out infinite;
  z-index: 10;
}

.answer-btn.correct .answer-key {
  background: var(--success);
  color: white;
}

.answer-btn.wrong {
  background: rgba(239, 68, 68, 0.2) !important;
  border-color: #ef4444 !important;
  animation: wrongShake 0.4s ease-in-out;
  opacity: 0.8 !important;
}

.answer-btn.wrong .answer-key {
  background: #ef4444;
  color: white;
}

.answer-btn.disabled {
  cursor: not-allowed;
  opacity: 0.6;
  transform: none;
}

#quizRealTimeContainer .realtime-text-blank {
  display: inline-block;
  /* La largeur suit le contenu : une reponse longue etait tronquee a 132px
     (« un courant p » pour « un courant politique et intellectuel »).
     L'ancien clamp devient le MINIMUM, pas la largeur : un trou vide garde
     exactement l'allure qu'il avait, et il reste etroit sur mobile — un
     plancher fixe de 64px empilait deux trous l'un sous l'autre dans une
     colonne de 320px au lieu de les laisser dans la phrase. */
  width: auto;
  min-width: clamp(52px, 18vw, 132px);
  max-width: 100%;
  min-height: 1.25em;
  margin: 0;
  padding: 0;
  color: inherit;
  background: transparent;
  border: 0;
  border-bottom: 2px solid currentColor;
  border-radius: 0;
  box-shadow: none;
  text-align: center;
  font: inherit;
  font-weight: inherit;
  line-height: inherit;
  vertical-align: baseline;
}

/* Le soulignement ne sert qu'a MONTRER LE TROU tant qu'il est vide. Des que le
   joueur s'en occupe — focus — ou qu'il est corrige, l'etat se lit au fond
   teinte : garder en plus un cadre encerclait le mot au milieu de la phrase et
   alourdissait la lecture. Le trait et les anneaux sont donc retires ensemble,
   sinon il reste un demi-cadre, ce qui est pire que les deux. */
#quizRealTimeContainer .realtime-text-blank:focus {
  outline: none;
  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
}

/* A4 — the blank the player is filling (used with the word bank).
   Sans cadre : c'est le fond accent, la legere elevation et l'ombre douce
   coloree qui signalent le trou actif. */
#quizRealTimeContainer .realtime-text-blank.is-active {
  border-bottom-color: transparent;
  background: var(--qz-accent-soft);
  box-shadow: 0 8px 18px -8px var(--qz-accent);
  transform: translateY(-1px);
}

/* Correction states — set by renderTypedSolution alongside the drawn trails.
   Le fond porte le verdict ; la reponse fausse reste barree. */
#quizRealTimeContainer .realtime-text-blank.is-miss {
  border-bottom-color: transparent;
  background: var(--qz-error-bg);
  color: var(--qz-error-ink);
  text-decoration: line-through;
  text-decoration-color: var(--qz-error);
  box-shadow: none;
}
#quizRealTimeContainer .realtime-text-blank.is-hit {
  border-bottom-color: transparent;
  background: var(--qz-success-bg);
  color: var(--qz-success-ink);
  box-shadow: none;
}
#quizRealTimeContainer .realtime-text-blank.is-due {
  border-bottom-color: transparent;
  background: var(--qz-warning-bg);
  box-shadow: none;
}

/* A4 — word bank: clickable proposition chips for opted-in TEXT questions. */
#quizRealTimeContainer .realtime-wordbank {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 6px;
  animation: qzrWordBankIn .22s ease;
}
@keyframes qzrWordBankIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
#quizRealTimeContainer .realtime-wordbank[hidden] { display: none; }
#quizRealTimeContainer .realtime-wordbank__hint {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin: 0;
  font-size: .82rem;
  opacity: .72;
}
#quizRealTimeContainer .realtime-wordbank__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}
#quizRealTimeContainer .realtime-wordbank__chip {
  padding: 9px 15px;
  border-radius: var(--qz-r-pill);
  border: 1.5px solid rgba(29, 158, 117, .5);
  background: rgba(29, 158, 117, .14);
  color: inherit;
  font-size: .92rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform var(--qz-dur-ui) ease, background var(--qz-dur-ui) ease, border-color var(--qz-dur-ui) ease;
}
#quizRealTimeContainer .realtime-wordbank__chip:hover,
#quizRealTimeContainer .realtime-wordbank__chip:focus-visible {
  transform: translateY(-2px);
  background: rgba(29, 158, 117, .26);
  border-color: rgba(29, 158, 117, .95);
  outline: none;
}
#quizRealTimeContainer .realtime-wordbank__chip:active {
  transform: scale(var(--qz-press-scale));
}
/* Amplified pick — the chip answers the blank's own double ring, so the pair
   "blank + proposition" reads as one gesture. */
#quizRealTimeContainer .realtime-wordbank__chip.is-picked {
  border-color: var(--qz-accent);
  background: var(--qz-accent-soft);
  box-shadow:
    0 0 0 3px var(--qz-accent-soft),
    0 0 0 4.5px var(--qz-accent),
    0 10px 20px -10px var(--qz-accent);
  transform: translateY(-2px) scale(1.03);
}
/* Correction — the chips that were the right answers. */
#quizRealTimeContainer .realtime-wordbank__chip.is-answer {
  border-color: var(--qz-warning);
  background: var(--qz-warning-bg);
  color: var(--qz-warning-ink);
  box-shadow: 0 0 0 3px var(--qz-warning-bg), 0 0 0 4.5px var(--qz-warning);
}
#quizRealTimeContainer .realtime-wordbank__chip.is-dim {
  opacity: .34;
  pointer-events: none;
}
/* Un mot deja place dans un trou : reste visible (le joueur retrouve ou il
   est parti) et cerne d'un trait net plutot que de disparaitre de la banque
   et faire sauter la mise en page des autres chips. Reste cliquable — pas
   `disabled` — pour permettre le toggle : re-taper dessus vide le trou qu'il
   occupe (voir le handler de clic). Le survol vire vers la teinte "erreur"
   pour suggerer l'action de retrait, plutot que l'accent habituel qui
   suggererait au contraire une selection. */
#quizRealTimeContainer .realtime-wordbank__chip.is-placed {
  border: 2px solid var(--qz-line, rgba(29, 158, 117, .35));
  background: transparent;
  color: var(--qz-muted, inherit);
  opacity: .55;
  cursor: pointer;
  box-shadow: none;
  transform: none;
}
#quizRealTimeContainer .realtime-wordbank__chip.is-placed:hover,
#quizRealTimeContainer .realtime-wordbank__chip.is-placed:focus-visible {
  opacity: .9;
  background: color-mix(in srgb, var(--qz-error, #E24B4A) 10%, transparent);
  border-color: var(--qz-error, #E24B4A);
  color: var(--qz-error, #E24B4A);
  transform: none;
  outline: none;
}

/* ------------------------------------------------------------------ *
 * Correction tracee — TEXT et MATCH.
 *
 * Remplace « Solution : a / b » et « gauche -> droite | gauche -> droite »,
 * illisibles des deux trous ou quatre paires. Deux poids, deux roles :
 *   - ce que le joueur a fait  -> 2px, estompe. C'est un constat.
 *   - ce qu'il fallait faire   -> 4.5px gaine du fond, anime. C'est une consigne.
 * La gaine (--case) passe SOUS le trait et par-dessus les autres, pour que la
 * bonne reponse reste lisible quand les traits se croisent.
 * ------------------------------------------------------------------ */
#quizRealTimeContainer .realtime-trails {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
  z-index: 3;
}
#quizRealTimeContainer .realtime-trails path { fill: none; stroke-linecap: round; }
#quizRealTimeContainer .realtime-trails path.is-mine {
  stroke: var(--qz-success);
  stroke-width: 2;
  opacity: .5;
}
#quizRealTimeContainer .realtime-trails path.is-wrong {
  stroke: var(--qz-error);
  stroke-width: 2;
  opacity: .65;
  stroke-dasharray: 3 5;
}
#quizRealTimeContainer .realtime-trails path.is-case {
  stroke: var(--qz-surface);
  stroke-width: 9;
  opacity: .95;
}
#quizRealTimeContainer .realtime-trails path.is-due {
  stroke: var(--qz-warning);
  stroke-width: 4.5;
  stroke-dasharray: 9 8;
  animation: qzrTrailFlow 1.1s linear infinite;
}
#quizRealTimeContainer .realtime-trails circle.is-duedot {
  fill: var(--qz-warning);
  stroke: var(--qz-surface);
  stroke-width: 3;
}
@keyframes qzrTrailFlow { to { stroke-dashoffset: -34; } }
@media (prefers-reduced-motion: reduce) {
  #quizRealTimeContainer .realtime-trails path.is-due { animation: none; }
}
/* A4 refinement 2 — the available set fades in each time it changes (a word placed
   drops out, the rest re-appear), so moving between blanks reads clearly. */
#quizRealTimeContainer .realtime-wordbank__chips.is-fresh .realtime-wordbank__chip {
  animation: qzrChipIn .26s ease both;
}
@keyframes qzrChipIn {
  from { opacity: 0; transform: translateY(5px) scale(.9); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  #quizRealTimeContainer .realtime-wordbank { animation: none; }
  #quizRealTimeContainer .realtime-wordbank__chip { transition: none; }
  #quizRealTimeContainer .realtime-wordbank__chips.is-fresh .realtime-wordbank__chip { animation: none; }
}

.realtime-order-board,
.realtime-match-board {
  display: grid;
  gap: 14px;
  width: 100%;
}

.realtime-order-board--anagram {
  justify-items: center;
}

.realtime-sortable-list {
  display: grid;
  gap: 10px;
}

/* `transform` est volontairement EXCLU : le FLIP le pose puis le relache dans
   la meme frame, une transition ici animerait aussi l'aller et produirait un
   double mouvement. Le retour est anime par .is-gliding, et par lui seul. */
.realtime-sortable-list.is-sorting .realtime-sortable-item {
  transition: border-color var(--qz-dur-ui) ease, background var(--qz-dur-ui) ease, box-shadow var(--qz-dur-ui) ease;
}

.realtime-sortable-list--anagram {
  display: flex;
  flex-flow: row nowrap;
  justify-content: center;
  align-items: center;
  width: 100%;
  max-width: 100%;
  gap: 10px;
  padding: 4px 2px 10px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.realtime-sortable-item {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 58px;
  padding: 14px 16px;
  color: var(--text);
  text-align: left;
  background: rgba(255, 255, 255, 0.06);
  border: 2px solid var(--glass-border);
  border-radius: 16px;
  cursor: grab;
  user-select: none;
  touch-action: none;
  transition: border-color var(--qz-dur-ui) ease, transform var(--qz-dur-ui) ease, background var(--qz-dur-ui) ease;
}

/* Same split as the answer buttons, and the same reason: this rule gave :hover
   and .is-selected an identical treatment, so on touch a stale hover was
   indistinguishable from a picked item. ORDER questions are answered by
   selecting these, so it is the same bug wearing a different question type. */
.realtime-sortable-item.is-selected {
  background: rgba(59, 130, 246, 0.16);
  border-color: var(--primary);
}

@media (hover: hover) {
  .realtime-sortable-item:hover {
    background: rgba(59, 130, 246, 0.16);
    border-color: var(--primary);
  }
}

/* ------------------------------------------------------------------ *
 * Tri ORDER / ANAG — modele "emplacement fantome".
 *
 * L'element saisi RESTE en place et devient l'emplacement : il ne se cree ni
 * ne se detruit rien pendant le geste, donc plus de saut. Un clone flottant
 * suit le doigt, et les voisins sont replaces par FLIP (.is-gliding).
 * L'ancien modele decalait les voisins de 4px et recreait un placeholder a
 * chaque survol, d'ou l'a-coup.
 * ------------------------------------------------------------------ */
.realtime-sortable-item.is-slot {
  background: transparent;
  border-style: dashed;
  border-color: var(--qz-accent);
  box-shadow: inset 0 0 0 4px var(--qz-accent-soft);
  color: transparent;
}
.realtime-sortable-item.is-slot * { visibility: hidden; }

.realtime-sortable-item.is-carried {
  position: fixed;
  z-index: 60;
  margin: 0;
  cursor: grabbing;
  pointer-events: none;
  box-sizing: border-box;
  border-color: var(--qz-accent);
  box-shadow: 0 18px 38px -12px rgba(15, 23, 42, .34), 0 2px 6px rgba(15, 23, 42, .10);
  transform-origin: center;
}
/* La tuile portee sort de .realtime-sortable-list--anagram : sans ce rappel
   elle perdrait sa taille de police et son centrage, et le padding de base la
   gonflerait (content-box). Elle doit rester identique, un quart plus grande. */
.realtime-sortable-item.is-carried.is-letter {
  flex: none;
  padding: 0;
  gap: 0;
  justify-content: center;
  text-align: center;
}

.realtime-sortable-item.is-gliding {
  transition: transform .26s cubic-bezier(.2, .9, .25, 1);
}

@media (prefers-reduced-motion: reduce) {
  .realtime-sortable-item.is-gliding { transition: none; }
}

.realtime-sortable-item--letter {
  flex: 0 0 48px;
  width: 48px;
  min-height: 52px;
  justify-content: center;
  gap: 0;
  padding: 0;
  color: #101828;
  text-align: center;
  background: rgba(255, 255, 255, 0.96);
  border-color: rgba(124, 108, 255, 0.28);
  border-radius: 15px;
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.16);
}

.realtime-sortable-item--letter .answer-key {
  display: none;
}

.realtime-sortable-item--letter span:last-child {
  font-size: 1.3rem;
  font-weight: 900;
  line-height: 1;
  text-transform: uppercase;
}

.realtime-sortable-item--letter:hover,
.realtime-sortable-item--letter.is-selected {
  background: #fff;
  border-color: var(--primary);
  transform: translateY(-2px);
}

.realtime-match-board--interactive {
  position: relative;
  gap: 18px;
  width: min(100%, 560px);
  margin: 0 auto;
}

.realtime-match-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(28px, 10vw, 76px);
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-align: center;
}

.realtime-match-stage {
  position: relative;
}

.realtime-match-lines {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.realtime-match-columns {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(28px, 10vw, 76px);
  align-items: stretch;
}

.realtime-match-column {
  display: grid;
  gap: 14px;
  align-content: start;
}

.realtime-match-card {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 86px;
  padding: 12px;
  color: #101828;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 800;
  line-height: 1.35;
  text-align: left;
  background: rgba(255, 255, 255, 0.96);
  border: 1px solid rgba(148, 163, 184, 0.2);
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.13);
  cursor: pointer;
  touch-action: manipulation;
  transition: transform var(--qz-dur-ui) ease, border-color var(--qz-dur-ui) ease, box-shadow var(--qz-dur-ui) ease, background var(--qz-dur-ui) ease;
}

.realtime-match-card--left {
  gap: 12px;
  touch-action: pan-y;
}

.realtime-match-card--right {
  justify-content: center;
  min-height: 86px;
  text-align: center;
  background: rgba(255, 255, 255, 0.86);
  border-style: dashed;
  border-color: rgba(148, 163, 184, 0.45);
}

.realtime-match-card--right[data-match-count]:not([data-match-count="0"]):not([data-match-count="1"])::after {
  content: attr(data-match-count);
  position: absolute;
  top: -8px;
  right: -8px;
  display: grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 900;
  line-height: 1;
  background: var(--match-color, var(--primary));
  border: 2px solid #fff;
  border-radius: var(--qz-r-pill);
  box-shadow: 0 8px 18px rgba(15, 23, 42, 0.18);
}

.realtime-match-card:hover:not(.disabled),
.realtime-match-card.is-selected,
.realtime-match-card.is-drop-target {
  transform: translateY(-2px);
  border-color: var(--match-color, var(--primary));
  box-shadow: 0 16px 34px rgba(15, 23, 42, 0.18);
}

.realtime-match-card.is-matched {
  border-color: var(--match-color, var(--primary));
}

.realtime-match-card.is-dragging {
  opacity: .7;
  transform: scale(.98);
}

/* Selection amplifiee — meme double anneau que le trou TEXT actif, pour que le
   geste « je choisis » se lise pareil dans les deux moteurs. Un liseré de 2px
   SEUL se perdait sur une colonne chargee — mais un vrai border de 2px EN PLUS
   de l'anneau donne un contour net à l'element choisi sans perdre l'anneau qui
   porte l'essentiel du relief. */
.realtime-match-card.is-selected {
  background: var(--qz-accent-soft);
  border-width: 2px;
  border-color: var(--qz-accent);
  color: var(--qz-accent-ink);
  box-shadow:
    0 0 0 3px var(--qz-accent-soft),
    0 0 0 4.5px var(--qz-accent),
    0 14px 30px -10px var(--qz-accent);
  transform: translateY(-2px) scale(1.02);
}
.realtime-match-card.is-selected .realtime-match-dot {
  background: var(--qz-accent);
  box-shadow: 0 0 0 4px var(--qz-accent-soft);
}

/* Correction — posee par renderTypedSolution, en regard des traits traces. */
.realtime-match-card.is-wrong {
  background: var(--qz-error-bg);
  border-color: var(--qz-error);
  color: var(--qz-error-ink);
  box-shadow: 0 0 0 3px var(--qz-error-bg), 0 0 0 4.5px var(--qz-error);
}
.realtime-match-card.is-wrong .realtime-match-dot { background: var(--qz-error); }
.realtime-match-card.is-due {
  background: var(--qz-warning-bg);
  border-color: var(--qz-warning);
  color: var(--qz-warning-ink);
  box-shadow: 0 0 0 3px var(--qz-warning-bg), 0 0 0 4.5px var(--qz-warning);
}
.realtime-match-card.is-due .realtime-match-dot { background: var(--qz-warning); }

.realtime-match-card.is-just-matched {
  animation: qzrMatchPop .42s cubic-bezier(.2, 1.6, .4, 1);
}
@keyframes qzrMatchPop {
  0%   { transform: scale(1); }
  38%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .realtime-match-card.is-just-matched { animation: none; }
}

.realtime-match-card.disabled,
.realtime-match-card:disabled {
  cursor: not-allowed;
  opacity: .72;
  transform: none;
}

.realtime-match-thumb {
  flex: 0 0 44px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  color: var(--match-color, var(--primary));
  background: rgba(124, 108, 255, 0.12);
  border-radius: 12px;
  overflow: hidden;
}

.realtime-match-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.realtime-match-thumb i {
  font-size: 1.25rem;
}

.realtime-match-card__text {
  min-width: 0;
  overflow-wrap: anywhere;
}

.realtime-match-dot {
  position: absolute;
  top: 50%;
  z-index: 3;
  width: 12px;
  height: 12px;
  background: var(--match-color, var(--primary));
  border: 2px solid #fff;
  border-radius: var(--qz-r-pill);
  box-shadow: 0 0 0 2px rgba(15, 23, 42, 0.08);
  transform: translateY(-50%);
}

.realtime-match-dot--left {
  right: -7px;
}

.realtime-match-dot--right {
  left: -7px;
}

.realtime-match-submit {
  justify-content: center;
  min-height: 54px;
  margin-top: 8px;
  color: #fff;
  text-align: center;
  background: linear-gradient(135deg, #6d5dfc 0%, #7c3aed 100%);
  border-color: rgba(255, 255, 255, 0.12);
  border-radius: var(--qz-r-pill);
  box-shadow: 0 14px 30px rgba(109, 93, 252, 0.38);
}

.realtime-match-submit .answer-key {
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
}

.realtime-match-submit:hover:not(.disabled) {
  background: linear-gradient(135deg, #7c6cff 0%, #8b5cf6 100%);
  border-color: rgba(255, 255, 255, 0.22);
}

.realtime-match-help {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  margin: 0;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 700;
}

.realtime-match-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(180px, 1fr);
  gap: 12px;
  align-items: center;
  padding: 14px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--glass-border);
  border-radius: 16px;
}

.realtime-match-row span {
  color: var(--text);
  font-weight: 900;
  text-transform: none;
}

#quizRealTimeContainer .realtime-match-row select {
  min-width: 0;
}

.realtime-solution-box {
  display: grid;
  gap: 6px;
  padding: 16px;
  color: var(--text);
  background: rgba(16, 185, 129, 0.16);
  border: 1px solid rgba(16, 185, 129, 0.35);
  border-radius: 16px;
}

.realtime-solution-box strong {
  color: #34d399;
}

/* Side Panel / Logs */
.side-panel {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.status-matrix {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 16px;
  padding: 16px;
}

.status-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.status-label {
  font-size: 0.7rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 700;
}

.status-value {
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--text);
}

.console-log {
  background: #020617;
  border-radius: 16px;
  padding: 16px;
  flex-grow: 1;
  height: 400px;
  overflow-y: auto;
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 0.8rem;
  color: #a5b4fc;
  border: 1px solid var(--glass-border);
}

.log-entry {
  margin-bottom: 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  padding-bottom: 8px;
}

.log-time {
  color: #64748b;
  margin-right: 8px;
  font-size: 0.7rem;
}

.log-event {
  color: #38bdf8;
  font-weight: 700;
}

.log-data {
  color: #94a3b8;
  margin-top: 4px;
  display: block;
  white-space: pre-wrap;
  word-break: break-all;
}

/* Advanced Settings Toggle */
.advanced-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--muted);
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
  margin-top: 16px;
  transition: color var(--qz-dur-ui);
}

.advanced-toggle:hover {
  color: white;
}

.advanced-settings {
  display: none;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--glass-border);
  animation: fadeIn 0.3s;
}

.advanced-settings.open {
  display: block;
}

/* Modal Styles */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: transparent;
  z-index: 100;
  display: none;
  align-items: flex-end;
  justify-content: center;
}

.modal-overlay.open {
  display: flex;
}

body.realtime-active .modal-content {
  background: var(--bg-dark);
  border: 1px solid var(--glass-border);
  border-bottom: none;
  border-radius: 24px 24px 0 0;
  width: 100%;
  max-width: 600px;
  height: 55vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.4);
  transform: translateY(100%);
  animation: bottomSheetUp .35s cubic-bezier(.22, .61, .36, 1) forwards;
}

.modal-body-scroll {
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  padding: 28px 32px 8px;
}

.modal-footer-fixed {
  flex-shrink: 0;
  padding: 12px 32px max(20px, var(--qzr-safe-bottom));
  border-top: 1px solid var(--glass-border);
}

@keyframes bottomSheetUp {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

.ranking-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 24px 0;
}

.final-stats-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 16px 0 8px;
}

.final-stat {
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  padding: 10px 12px;
  text-align: center;
}

.final-stat-label {
  font-size: 0.78rem;
  color: var(--muted);
}

.final-stat-value {
  margin-top: 4px;
  font-size: 1.2rem;
  font-weight: 800;
  color: var(--primary);
}

.solo-performance-card {
  margin: 16px 0 8px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 18px;
  /* background: linear-gradient(140deg, rgba(87, 45, 13, 0.95), rgba(163, 88, 44, 0.9)); */
  overflow: hidden;
}

.solo-performance-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  font-weight: 800;
  font-size: 1.05rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.solo-performance-main {
  margin: 14px 16px 10px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.07);
  text-align: center;
  padding: 14px 12px;
}

.solo-performance-score-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: rgba(255, 255, 255, 0.78);
  font-weight: 700;
}

.solo-performance-score-value {
  margin-top: 4px;
  font-size: 2.75rem;
  line-height: 1;
  font-weight: 900;
  color: #ffa57c;
}

.solo-performance-kpi-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  padding: 8px 16px 16px;
}

.solo-performance-kpi {
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.06);
  padding: 10px 12px;
  text-align: center;
}

.solo-performance-kpi-label {
  font-size: 2.5rem;
  color: rgba(255, 255, 255, 0.9);
}

.solo-performance-kpi-value {
  margin-top: 4px;
  font-size: 1.7rem;
  font-weight: 900;
  line-height: 1.1;
  color: #ff6b1a;
}

.solo-xp-breakdown {
  margin-top: 12px;
  border-radius: 14px;
  background: linear-gradient(135deg, rgba(255, 170, 50, 0.12) 0%, rgba(255, 100, 20, 0.10) 100%);
  border: 1px solid rgba(255, 170, 50, 0.18);
  padding: 14px 16px;
  animation: soloXpFadeIn 0.5s ease-out;
}
@keyframes soloXpFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
.solo-xp-header {
  font-size: 1.1rem;
  font-weight: 700;
  color: #ffa040;
  margin-bottom: 8px;
}
.solo-xp-header i { margin-right: 6px; }
.solo-xp-items {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.solo-xp-item {
  display: flex;
  justify-content: space-between;
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.85);
  padding: 3px 0;
}
.solo-xp-item span:last-child {
  font-weight: 700;
  color: #ffa57c;
}
.solo-xp-perfect span:first-child {
  color: #4ade80;
}
.solo-xp-perfect span:last-child {
  color: #4ade80;
}
.solo-xp-speed span:first-child {
  color: #facc15;
}
.solo-xp-speed span:last-child {
  color: #facc15;
}
.solo-level-progress {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.solo-level-badge {
  font-size: 0.9rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.92);
  margin-bottom: 6px;
}
.solo-level-bar-wrap {
  height: 6px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
  overflow: hidden;
}
.solo-level-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, #ff8c00, #ffa040);
  border-radius: 3px;
  transition: width 1s ease-out;
}
.solo-level-next {
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.55);
  margin-top: 4px;
}
.solo-group-xp {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.solo-group-xp-item {
  font-size: 0.88rem;
  color: rgba(100, 200, 255, 0.9);
  font-weight: 600;
}
.solo-group-xp-item i { margin-right: 6px; }

/* === Phase 3: Quests, Chests, Badges in result overlay === */
.solo-quests-done {
  margin-top: 12px;
  padding: 10px 14px;
  background: rgba(34, 197, 94, 0.08);
  border-radius: 10px;
  border: 1px solid rgba(34, 197, 94, 0.2);
  animation: fadeIn 0.5s ease;
}
.solo-quests-header {
  font-size: 0.92rem;
  font-weight: 700;
  color: rgba(34, 197, 94, 0.95);
  margin-bottom: 6px;
}
.solo-quests-header i { margin-right: 6px; }
.solo-quest-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.85);
  padding: 4px 0;
}
.solo-quest-item i { margin-right: 4px; color: rgba(34, 197, 94, 0.9); }

.solo-badges-earned {
  margin-top: 10px;
  padding: 10px 14px;
  background: rgba(234, 179, 8, 0.08);
  border-radius: 10px;
  border: 1px solid rgba(234, 179, 8, 0.2);
  animation: fadeIn 0.6s ease;
}
.solo-badge-item {
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.9);
  padding: 4px 0;
}
.solo-badge-item i { color: rgba(234, 179, 8, 0.95); margin-right: 6px; }

.solo-chest-earned {
  margin-top: 10px;
  padding: 10px 14px;
  background: rgba(168, 85, 247, 0.08);
  border-radius: 10px;
  border: 1px solid rgba(168, 85, 247, 0.25);
  text-align: center;
  font-size: 0.92rem;
  color: rgba(168, 85, 247, 0.95);
  animation: fadeIn 0.7s ease;
}
.solo-chest-earned i { margin-right: 6px; }

/* === Quest widget (dashboard) === */
.qzr-quests-widget {
  padding: 12px;
  background: var(--qz-surface);
  border-radius: 14px;
  border: 1px solid var(--qz-line);
}
.qzr-quests-title {
  font-size: 1rem;
  font-weight: 700;
  color: rgba(255,255,255,0.95);
  margin-bottom: 10px;
}
.qzr-quests-title i { margin-right: 6px; color: rgba(234, 179, 8, 0.9); }
.qzr-quest-card {
  padding: 10px 12px;
  margin-bottom: 8px;
  background: rgba(255,255,255,0.04);
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.06);
  transition: transform var(--qz-dur-ui) ease, border-color var(--qz-dur-ui) ease;
}
.qzr-quest-card:hover { transform: translateY(-1px); border-color: rgba(255,255,255,0.12); }
.qzr-quest-done {
  border-color: rgba(34, 197, 94, 0.3);
  background: rgba(34, 197, 94, 0.06);
}
.qzr-quest-done .qzr-quest-label { color: rgba(34, 197, 94, 0.9); }
.qzr-quest-label {
  font-size: 0.88rem;
  font-weight: 600;
  color: rgba(255,255,255,0.9);
  margin-bottom: 6px;
}
.qzr-quest-label i { color: rgba(34, 197, 94, 0.9); margin-right: 4px; }
.qzr-quest-bar-wrap {
  height: 6px;
  background: rgba(255,255,255,0.08);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 4px;
}
.qzr-quest-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, #f59e0b, #f97316);
  border-radius: 3px;
  transition: width 0.3s ease;
}
.qzr-quest-done .qzr-quest-bar-fill {
  background: linear-gradient(90deg, #22c55e, #16a34a);
}
.qzr-quest-meta {
  display: flex;
  justify-content: space-between;
  font-size: 0.78rem;
  color: rgba(255,255,255,0.5);
}
.qzr-quest-reward { color: rgba(234, 179, 8, 0.85); font-weight: 600; }

/* === Chest widget (dashboard) === */
.qzr-chests-widget {
  padding: 12px;
  background: var(--glass-bg, rgba(255,255,255,0.03));
  border-radius: 14px;
  border: 1px solid var(--glass-border, rgba(255,255,255,0.08));
  margin-top: 12px;
}
.qzr-chests-title {
  font-size: 1rem;
  font-weight: 700;
  color: rgba(255,255,255,0.95);
  margin-bottom: 10px;
}
.qzr-chests-title i { margin-right: 6px; color: rgba(168, 85, 247, 0.9); }
.qzr-chest-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  margin-bottom: 8px;
  background: rgba(168, 85, 247, 0.06);
  border-radius: 10px;
  border: 1px solid rgba(168, 85, 247, 0.15);
}
.qzr-chest-icon { font-size: 1.4rem; color: rgba(168, 85, 247, 0.9); }
.qzr-chest-label { flex: 1; font-size: 0.88rem; font-weight: 600; color: rgba(255,255,255,0.9); }
.qzr-chest-open-btn { font-size: 0.78rem; font-weight: 700; }
.qzr-chest-opened {
  text-align: center;
  padding: 14px 8px;
}
.qzr-chest-reward-reveal {
  font-size: 1.1rem;
  font-weight: 700;
  color: rgba(234, 179, 8, 0.95);
  animation: fadeIn 0.5s ease;
}
.qzr-chest-opened-animation {
  animation: chestPop 0.4s ease;
}
@keyframes chestPop {
  0% { transform: scale(1); }
  50% { transform: scale(1.08); }
  100% { transform: scale(1); }
}

/* === Badge widget (profile/dashboard) === */
.qzr-badges-widget {
  padding: 12px;
  background: var(--glass-bg, rgba(255,255,255,0.03));
  border-radius: 14px;
  border: 1px solid var(--glass-border, rgba(255,255,255,0.08));
  margin-top: 12px;
}
.qzr-badges-title {
  font-size: 1rem;
  font-weight: 700;
  color: rgba(255,255,255,0.95);
  margin-bottom: 10px;
}
.qzr-badges-title i { margin-right: 6px; color: rgba(234, 179, 8, 0.9); }
.qzr-badges-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  gap: 10px;
}
.qzr-badge-item {
  text-align: center;
  padding: 10px 6px;
  background: rgba(255,255,255,0.04);
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.06);
  transition: transform var(--qz-dur-ui) ease;
}
.qzr-badge-item:hover { transform: translateY(-2px); }
.qzr-badge-icon { font-size: 1.6rem; color: rgba(234, 179, 8, 0.85); margin-bottom: 4px; }
.qzr-badge-label { font-size: 0.74rem; font-weight: 600; color: rgba(255,255,255,0.8); }

.ranking-item {
  display: flex;
  align-items: center;
  gap: 16px;
  background: rgba(255, 255, 255, 0.05);
  padding: 12px 20px;
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.02);
}

.rank-number {
  font-size: 1.5rem;
  font-weight: 900;
  color: var(--muted);
  min-width: 40px;
  text-align: center;
}

.ranking-item:nth-child(1) .rank-number {
  color: #fbbf24;
}

/* Gold */
.ranking-item:nth-child(2) .rank-number {
  color: #94a3b8;
}

/* Silver */
.ranking-item:nth-child(3) .rank-number {
  color: #b45309;
}

/* Bronze */

.rank-score {
  font-weight: 900;
  font-size: 1.2rem;
  margin-left: auto;
  color: var(--primary);
}

.host-controls {
  display: none;
  margin-top: 24px;
  padding: 24px;
  background: rgba(59, 130, 246, 0.1);
  border-radius: 16px;
  border: 1px solid rgba(59, 130, 246, 0.2);
}

.host-controls.active {
  display: block;
  animation: fadeIn 0.4s;
}

.realtime-session-info-btn,
.realtime-session-sound-btn {
  position: fixed !important;
  left: max(16px, var(--qzr-safe-left));
  z-index: 1012;
  width: 44px;
  height: 44px;
  border-radius: 50% !important;
  padding: 0 !important;
  opacity: 0.84;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
}

.realtime-session-info-btn {
  bottom: calc(88px + var(--qzr-safe-bottom));
}

.realtime-session-sound-btn {
  bottom: calc(142px + var(--qzr-safe-bottom));
  display: none;
}

.realtime-session-sound-btn.is-muted {
  opacity: 0.58;
}

.realtime-session-info-btn i,
.realtime-session-sound-btn i {
  font-size: 0.95rem;
}

.session-info-modal-content {
  width: min(680px, 94vw);
}

.session-info-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 16px 0 20px;
}

.session-info-item {
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.session-info-label {
  color: var(--muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
}

.session-info-value {
  color: var(--text);
  font-size: 1rem;
  font-weight: 700;
  word-break: break-word;
}

.session-info-grid.is-solo-mode .session-info-multi-only {
  display: none;
}
.session-info-grid.is-solo-mode {
  grid-template-columns: 1fr;
}

.session-info-sound-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  margin: 0 0 16px;
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
}
.session-info-sound-label {
  color: var(--text);
  font-size: .9rem;
  font-weight: 700;
}
.session-info-sound-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--text);
}
.session-info-sound-toggle__track {
  position: relative;
  width: 44px;
  height: 24px;
  border-radius: 12px;
  background: var(--primary, #3b82f6);
  transition: background var(--qz-dur-ui) ease;
}
.session-info-sound-toggle.is-muted .session-info-sound-toggle__track {
  background: rgba(255, 255, 255, .15);
}
.session-info-sound-toggle__thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  transition: transform var(--qz-dur-ui) ease;
}
.session-info-sound-toggle.is-muted .session-info-sound-toggle__thumb {
  transform: translateX(0);
}
.session-info-sound-toggle:not(.is-muted) .session-info-sound-toggle__thumb {
  transform: translateX(20px);
}
.session-info-sound-toggle__text {
  font-size: .8rem;
  font-weight: 600;
  color: var(--muted);
  min-width: 52px;
}

body.theme-1 #quizRealTimeContainer .realtime-goal-hud-card,
body.theme-1 #quizRealTimeContainer .question-box,
body.theme-1 #quizRealTimeContainer .player-card,
body.theme-1 #quizRealTimeContainer .status-matrix,
body.theme-1 #quizRealTimeContainer .realtime-match-row,
body.theme-1 #quizRealTimeContainer .ranking-item,
body.theme-1 #quizRealTimeContainer .final-stat,
body.theme-1 #quizRealTimeContainer .session-info-item,
body.theme-1 #quizRealTimeContainer .session-info-sound-row,
body.theme-1 #quizRealTimeContainer .host-controls {
  background: color-mix(in srgb, var(--qz-surface, #fff) 90%, #eef4fa);
  border-color: var(--glass-border);
  color: var(--text);
}

body.theme-1 #quizRealTimeContainer .player-card:hover,
/* SPLIT deliberately: .is-selected is a real state and must keep working on
   touch, so it stays outside the hover query. Only the two :hover selectors are
   gated — see the note above on sticky hover after a tap. */
body.theme-1 #quizRealTimeContainer .realtime-sortable-item.is-selected {
  background: color-mix(in srgb, var(--primary) 12%, var(--qz-surface, #fff));
  border-color: color-mix(in srgb, var(--primary) 45%, var(--glass-border));
}

@media (hover: hover) {
  body.theme-1 #quizRealTimeContainer .answer-btn:hover:not(.disabled),
  body.theme-1 #quizRealTimeContainer .realtime-sortable-item:hover {
    background: color-mix(in srgb, var(--primary) 12%, var(--qz-surface, #fff));
    border-color: color-mix(in srgb, var(--primary) 45%, var(--glass-border));
  }
}

body.theme-1 #quizRealTimeContainer .answer-btn,
body.theme-1 #quizRealTimeContainer .realtime-sortable-item {
  background: color-mix(in srgb, var(--qz-surface, #fff) 92%, #eef4fa);
  border-color: var(--glass-border);
  color: var(--text);
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.06);
}

body.theme-1 #quizRealTimeContainer .answer-key {
  background: color-mix(in srgb, var(--primary) 13%, var(--qz-surface, #fff));
  color: var(--primary);
}

body.theme-1 #quizRealTimeContainer .timer-circle-track {
  stroke: color-mix(in srgb, var(--qz-line, #dfe7f1) 72%, transparent);
}

body.theme-1 #quizRealTimeContainer .timer-circle-wrap .timer-text {
  text-shadow: 0 0 12px color-mix(in srgb, var(--primary) 22%, transparent);
}

body.theme-1 #quizRealTimeContainer .answer-btn.selected {
  background: color-mix(in srgb, var(--primary) 16%, var(--qz-surface, #fff));
  border-color: var(--primary);
}

body.theme-1 #quizRealTimeContainer .answer-btn.correct {
  background: color-mix(in srgb, var(--success) 18%, var(--qz-surface, #fff)) !important;
  color: #064e3b;
}

body.theme-1 #quizRealTimeContainer .answer-btn.wrong {
  background: color-mix(in srgb, var(--danger) 14%, var(--qz-surface, #fff)) !important;
  color: #7f1d1d;
}

body.theme-1 #quizRealTimeContainer .realtime-text-blank:focus {
  box-shadow: 0 2px 0 color-mix(in srgb, var(--primary) 30%, transparent);
}

body.theme-1 #quizRealTimeContainer .realtime-sortable-item--letter,
body.theme-1 #quizRealTimeContainer .realtime-match-card {
  background: var(--qz-surface, #fff);
  border-color: color-mix(in srgb, var(--qz-line, #dfe7f1) 86%, #fff);
  color: var(--text);
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.08);
}

/* Sans ce doublon scope theme-1, la regle ci-dessus (ID + classe = plus
   specifique que .realtime-match-card.is-selected seul) ecrasait purement et
   simplement la selection : ni l'anneau ni la bordure de 2px ne
   s'affichaient, sur le theme par defaut. Meme motif que
   .realtime-sortable-item.is-selected juste au-dessus. */
body.theme-1 #quizRealTimeContainer .realtime-match-card.is-selected {
  background: var(--qz-accent-soft);
  border-width: 2px;
  border-color: var(--qz-accent);
  color: var(--qz-accent-ink);
  box-shadow:
    0 0 0 3px var(--qz-accent-soft),
    0 0 0 4.5px var(--qz-accent),
    0 14px 30px -10px var(--qz-accent);
}

body.theme-1 #quizRealTimeContainer .realtime-match-card--right {
  background: color-mix(in srgb, var(--qz-surface, #fff) 88%, #eef4fa);
  border-color: color-mix(in srgb, var(--qz-line, #dfe7f1) 70%, var(--muted));
}

body.theme-1 #quizRealTimeContainer .realtime-match-thumb {
  background: color-mix(in srgb, var(--match-color, var(--primary)) 14%, var(--qz-surface, #fff));
}

body.theme-1 #quizRealTimeContainer .realtime-match-dot {
  border-color: var(--qz-surface, #fff);
}

body.theme-1 #quizRealTimeContainer .realtime-solution-box {
  background: color-mix(in srgb, var(--success) 14%, var(--qz-surface, #fff));
  border-color: color-mix(in srgb, var(--success) 35%, var(--glass-border));
  color: var(--text);
}

body.theme-1 #quizRealTimeContainer .console-log {
  background: color-mix(in srgb, var(--qz-surface, #fff) 88%, #e6eef7);
  color: var(--text);
  border-color: var(--glass-border);
}

body.theme-1 #quizRealTimeContainer .log-entry {
  border-bottom-color: var(--glass-border);
}

body.theme-1 #quizRealTimeContainer .log-event,
body.theme-1 #quizRealTimeContainer .log-data {
  color: var(--muted);
}

body.theme-1 #quizRealTimeContainer .advanced-toggle:hover {
  color: var(--primary);
}

body.theme-1.realtime-active .modal-content {
  background: var(--qz-surface, #fff);
  border-color: var(--qz-line, #dfe7f1);
  color: var(--qz-text, #12263f);
  box-shadow: 0 -8px 32px rgba(15, 23, 42, 0.12);
}

body.theme-1.realtime-active .modal-footer-fixed {
  border-top-color: var(--qz-line, #dfe7f1);
}

body.theme-1 #quizRealTimeContainer .solo-performance-card {
  border-color: color-mix(in srgb, #f59e0b 28%, var(--glass-border));
  /* background: linear-gradient(140deg, #fff7ed, #ffedd5); */
  color: #7c2d12;
}

body.theme-1 #quizRealTimeContainer .solo-performance-main,
body.theme-1 #quizRealTimeContainer .solo-performance-kpi {
  background: rgba(255, 255, 255, 0.58);
}

body.theme-1 #quizRealTimeContainer .solo-performance-score-label,
body.theme-1 #quizRealTimeContainer .solo-performance-kpi-label {
  color: #9a3412;
}

body.theme-1 #quizRealTimeContainer .realtime-question-image-container,
body.theme-1 #quizRealTimeContainer .realtime-quiz-image-container {
  background-color: color-mix(in srgb, var(--qz-surface, #fff) 88%, #eef4fa);
  border-color: var(--glass-border);
}

@media (max-width: 640px) {
  .realtime-session-info-btn,
  .realtime-session-sound-btn {
    bottom: calc(86px + var(--qzr-safe-bottom));
    left: max(12px, var(--qzr-safe-left));
  }

  .realtime-session-sound-btn {
    bottom: calc(138px + var(--qzr-safe-bottom));
  }

  .players-grid {
    grid-template-columns: 1fr;
    gap: 10px;
    margin-top: 16px;
  }

  .player-card {
    min-height: 64px;
    padding: 12px;
  }

  .playground-header {
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 18px;
  }

  .timer-circle-wrap {
    width: 64px;
    height: 64px;
  }

  .timer-circle-wrap .timer-text {
    font-size: 1.25rem;
  }

  .realtime-goal-hud-card {
    padding: 9px 10px;
  }

  .question-box {
    padding: 18px;
    margin-bottom: 18px;
  }

  .question-title {
    font-size: 1.35rem;
  }

  .answers-grid {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .realtime-sortable-list--anagram {
    justify-content: flex-start;
    gap: 8px;
  }

  .realtime-sortable-item--letter {
    flex-basis: 42px;
    width: 42px;
    min-height: 46px;
    border-radius: 13px;
  }

    .realtime-sortable-item--letter span:last-child {
    font-size: 1.12rem;
  }

  .realtime-match-board--interactive {
    gap: 14px;
  }

  .realtime-match-head,
  .realtime-match-columns {
    column-gap: clamp(24px, 8vw, 38px);
  }

  .realtime-match-column {
    gap: 12px;
  }

  .realtime-match-card {
    min-height: 74px;
    padding: 10px 8px;
    border-radius: 11px;
    font-size: 0.86rem;
  }

  .realtime-match-card--left {
    gap: 8px;
  }

  .realtime-match-card--right {
    min-height: 74px;
  }

  .realtime-match-thumb {
    flex-basis: 38px;
    width: 38px;
    height: 38px;
    border-radius: 10px;
  }

  .realtime-match-dot {
    width: 11px;
    height: 11px;
  }

  .realtime-match-submit {
    min-height: 52px;
    margin-top: 4px;
  }

  .realtime-match-row {
    grid-template-columns: 1fr;
  }

  .answer-btn {
    min-height: 52px;
    padding: 14px;
    font-size: 1rem;
  }

  .status-matrix {
    grid-template-columns: 1fr;
  }

  .console-log {
    height: 220px;
  }

  .feedback-toast {
    width: calc(100vw - 2rem - var(--qzr-safe-left) - var(--qzr-safe-right));
    max-width: 420px;
    padding: 12px 16px;
    border-radius: 18px;
    font-size: 1rem;
    letter-spacing: 0;
  }

  .session-info-grid {
    grid-template-columns: 1fr;
  }
}

/* Brutal Elimination Toast */
.elimination-toast {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.5);
  background: rgba(220, 38, 38, 0.95);
  color: white;
  padding: 40px 60px;
  border-radius: 24px;
  text-align: center;
  box-shadow: 0 0 100px rgba(220, 38, 38, 0.8), inset 0 0 20px rgba(0, 0, 0, 0.5);
  z-index: 9999;
  opacity: 0;
  pointer-events: none;
  transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  border: 2px solid #f87171;
  backdrop-filter: blur(10px);
}

.elimination-toast.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.elimination-toast i {
  font-size: 5rem;
  margin-bottom: 20px;
  text-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
  animation: pulseSkull 1s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes pulseSkull {

  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }

  50% {
    opacity: .7;
    transform: scale(1.1);
  }
}

.elimination-toast .elimination-title {
  font-size: 2.5rem;
  font-weight: 900;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 10px;
}

.elimination-toast .elimination-name {
  font-size: 1.5rem;
  font-weight: 500;
}

.competition-winner-toast {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.5);
  background: radial-gradient(circle at top, rgba(251, 191, 36, 0.98), rgba(180, 83, 9, 0.96));
  color: #fff8eb;
  padding: 40px 60px;
  border-radius: 24px;
  text-align: center;
  box-shadow: 0 0 100px rgba(251, 191, 36, 0.55), inset 0 0 22px rgba(120, 53, 15, 0.45);
  z-index: 10001;
  opacity: 0;
  pointer-events: none;
  transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  border: 2px solid rgba(255, 251, 235, 0.78);
  backdrop-filter: blur(10px);
}

.competition-winner-toast.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.competition-winner-toast i {
  font-size: 5rem;
  margin-bottom: 20px;
  color: #fff7cc;
  text-shadow: 0 4px 20px rgba(120, 53, 15, 0.45);
  animation: pulseWinnerTrophy 1.2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes pulseWinnerTrophy {

  0%,
  100% {
    opacity: 1;
    transform: scale(1) rotate(0deg);
  }

  50% {
    opacity: 0.88;
    transform: scale(1.08) rotate(-2deg);
  }
}

.competition-winner-toast .winner-title {
  font-size: 2.5rem;
  font-weight: 900;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 10px;
}

.competition-winner-toast .winner-name {
  font-size: 1.5rem;
  font-weight: 800;
  margin-bottom: 8px;
}

.competition-winner-toast .winner-subtitle {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  opacity: 0.96;
}

.competition-winner-fireworks {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 10000;
}

/* Feedback Toast */
.feedback-toast {
  position: fixed;
  top: calc(20px + var(--qzr-safe-top));
  left: 50%;
  transform: translateX(-50%) translateY(-50px);
  padding: 16px 32px;
  border-radius: 50px;
  font-weight: 800;
  font-size: 1.2rem;
  color: white;
  z-index: 10000;
  opacity: 0;
  pointer-events: none;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  letter-spacing: 1px;
}

.feedback-toast.show {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}

.feedback-toast.success {
  background: linear-gradient(135deg, #10b981, #047857);
  border: 2px solid #34d399;
}

.feedback-toast.error {
  background: linear-gradient(135deg, #ef4444, #b91c1c);
  border: 2px solid #f87171;
}

.solo-contextual-message {
  position: fixed;
  top: 22%;
  left: 50%;
  z-index: 10010;
  pointer-events: none;
  border-radius: 16px;
  padding: 12px 20px;
  font-weight: 900;
  letter-spacing: 0.3px;
  text-align: center;
  color: #fff;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
  max-width: min(88vw, 720px);
  border: none;
  background: rgba(15, 23, 42, 0.1);
  backdrop-filter: blur(12px) saturate(150%);
  -webkit-backdrop-filter: blur(12px) saturate(150%);
}

.solo-contextual-message--flying {
  opacity: 0;
  transform: translate(-140vw, -50%);
  transition:
    transform 750ms cubic-bezier(0.08, 0.82, 0.2, 1),
    opacity 220ms ease-out;
}

.solo-contextual-message--flying.is-entering {
  opacity: 1;
  transform: translate(-50%, -50%);
}

.solo-contextual-message--flying.is-leaving {
  opacity: 0;
  transform: translate(120vw, -50%);
  transition:
    transform 350ms ease-in,
    opacity 350ms ease-in;
}

.solo-contextual-message--flying.tone-success {
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.13), rgba(59, 130, 246, 0.09));
  color: #d1fae5;
  text-shadow: 0 0 10px rgba(16, 185, 129, 0.5), 0 0 18px rgba(59, 130, 246, 0.35);
}

.solo-contextual-message--flying.tone-error {
  background: linear-gradient(135deg, rgba(245, 158, 11, 0.13), rgba(236, 72, 153, 0.09));
  color: #fef3c7;
  text-shadow: 0 0 10px rgba(245, 158, 11, 0.55), 0 0 18px rgba(236, 72, 153, 0.35);
}

.solo-contextual-message--attempts {
  top: 26%;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.72);
  background: linear-gradient(135deg, rgba(56, 189, 248, 0.13), rgba(20, 184, 166, 0.09));
  color: #dbeafe;
  text-shadow: 0 0 10px rgba(56, 189, 248, 0.55), 0 0 16px rgba(20, 184, 166, 0.4);
}

.solo-contextual-message--attempts.is-visible {
  animation: soloContextPuffIn 220ms ease-out forwards;
}

.solo-contextual-message--attempts.is-leaving {
  animation: soloContextPuffOut 320ms ease-in forwards;
}

@keyframes soloContextPuffIn {
  from {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.72);
  }
  to {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes soloContextPuffOut {
  from {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  to {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1.18);
  }
}

/* ===================================================================
   Goal-achieved celebration  ·  Centered banner + localised fireworks
   =================================================================== */
.solo-goal-celebrate {
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: 10020;
  pointer-events: none;
  width: 0;
  height: 0;
  transform: translate(-50%, -50%);
}

.solo-goal-celebrate__banner {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(-50%, -50%) scale(0.6);
  opacity: 0;
  padding: 14px 26px;
  border-radius: 18px;
  text-align: center;
  white-space: nowrap;
  background: linear-gradient(135deg, rgba(255, 215, 0, 0.22), rgba(236, 72, 153, 0.18));
  border: 1px solid rgba(255, 255, 255, 0.35);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  box-shadow:
    0 12px 40px rgba(0, 0, 0, 0.35),
    0 0 24px rgba(255, 215, 0, 0.45),
    0 0 48px rgba(236, 72, 153, 0.35);
  color: #fff;
  text-shadow: 0 0 12px rgba(255, 215, 0, 0.7), 0 0 18px rgba(236, 72, 153, 0.55);
  transition: transform 380ms cubic-bezier(0.18, 1.4, 0.4, 1), opacity 220ms ease-out;
}

.solo-goal-celebrate__title {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  opacity: 0.95;
}

.solo-goal-celebrate__label {
  margin-top: 4px;
  font-size: 22px;
  font-weight: 900;
  letter-spacing: 0.3px;
}

.solo-goal-celebrate.is-on .solo-goal-celebrate__banner {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.solo-goal-celebrate.is-off .solo-goal-celebrate__banner {
  opacity: 0;
  transform: translate(-50%, -50%) scale(1.12);
  transition: transform 350ms ease-in, opacity 320ms ease-in;
}

.solo-goal-celebrate__fireworks {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
}

.solo-goal-celebrate__spark {
  position: absolute;
  top: 0;
  left: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin: -5px 0 0 -5px;
  opacity: 0;
  background: radial-gradient(circle, #fff 0%, #ffd700 45%, rgba(255, 215, 0, 0) 70%);
  box-shadow: 0 0 12px rgba(255, 215, 0, 0.9), 0 0 22px rgba(236, 72, 153, 0.55);
  transform: translate(0, 0) scale(0.4);
}

.solo-goal-celebrate__spark.spark--0 { background: radial-gradient(circle, #fff 0%, #ffd700 45%, rgba(255, 215, 0, 0) 70%); }
.solo-goal-celebrate__spark.spark--1 { background: radial-gradient(circle, #fff 0%, #f472b6 45%, rgba(244, 114, 182, 0) 70%); }
.solo-goal-celebrate__spark.spark--2 { background: radial-gradient(circle, #fff 0%, #38bdf8 45%, rgba(56, 189, 248, 0) 70%); }
.solo-goal-celebrate__spark.spark--3 { background: radial-gradient(circle, #fff 0%, #34d399 45%, rgba(52, 211, 153, 0) 70%); }
.solo-goal-celebrate__spark.spark--4 { background: radial-gradient(circle, #fff 0%, #f97316 45%, rgba(249, 115, 22, 0) 70%); }
.solo-goal-celebrate__spark.spark--5 { background: radial-gradient(circle, #fff 0%, #a78bfa 45%, rgba(167, 139, 250, 0) 70%); }

.solo-goal-celebrate.is-on .solo-goal-celebrate__spark {
  animation: soloGoalSpark 1100ms cubic-bezier(0.15, 0.7, 0.2, 1) forwards;
  animation-delay: var(--delay, 0ms);
}

@keyframes soloGoalSpark {
  0% {
    opacity: 0;
    transform: rotate(var(--angle)) translateX(0) scale(0.3);
  }
  20% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: rotate(var(--angle)) translateX(var(--distance)) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .solo-goal-celebrate__banner,
  .solo-goal-celebrate.is-on .solo-goal-celebrate__spark {
    transition: opacity var(--qz-dur-ui) linear;
    animation: none;
  }
  .solo-goal-celebrate.is-on .solo-goal-celebrate__banner {
    transform: translate(-50%, -50%) scale(1);
  }
}

/* Join-Session inline alert — vNext version moved to
   style/players/vnext-search-opponent.css (.modal-join-session .join-alert-*,
   token-based + dark-adaptive). The old frosted-glass block was removed so the
   modal has a single, theme-aware source of truth. */

/* Showcase Goals Badges - Modern Horizontal Scrollable */
.goals-showcase-section {
  width: 100%;
}

.goals-section-header {
  /* display: flex; */
  align-items: center;
}

.goals-section-title {
  color: #374151;
  letter-spacing: 0.02em;
}

.goals-swiper-container {
  position: relative;
}

.goals-swiper-container::-webkit-scrollbar {
  display: none;
}

/* .goals-badges-track {
  padding: 0px;
} */

.goal-badge {
  transition: transform var(--qz-dur-ui) ease, box-shadow var(--qz-dur-ui) ease;
  cursor: default;
}

.goal-badge:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}

/* Empty state badges */
.goals-placeholder-badge {
  border: 1px dashed #d1d5db;
}

/* Goal badge internal elements */
.goal-badge-icon {
  margin-right: 4px;
}

.goal-badge-value {
  margin-left: 4px;
}

.goal-badge--disabled {
  opacity: 0.4;
  pointer-events: none;
  cursor: not-allowed;
}

.goal-path-lock-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.12), rgba(139, 92, 246, 0.10));
  border: 1px solid rgba(99, 102, 241, 0.3);
  color: #818cf8;
  font-size: 0.82rem;
  font-weight: 600;
}

/* Locked primary path-target badge in the showcase objectifs tab */
.goal-badge--path-primary {
  position: relative;
  /* border: 2px solid rgba(99, 102, 241, 0.55) !important; */
  /* background: linear-gradient(135deg, rgba(59, 130, 246, 0.12), rgba(139, 92, 246, 0.10)) !important; */
  /* box-shadow: 0 4px 14px rgba(99, 102, 241, 0.22); */
}

.goal-badge--path-primary .goal-badge-lock {
  color: #6366f1;
  font-size: 0.9rem;
}

body.theme-1 .goal-badge--path-primary {
  /* border-color: rgba(99, 102, 241, 0.4) !important; */
  /* background: linear-gradient(135deg, rgba(59, 130, 246, 0.06), rgba(139, 92, 246, 0.05)) !important; */
}

body.theme-1 .goal-path-lock-banner {
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.08), rgba(139, 92, 246, 0.06));
  border-color: rgba(99, 102, 241, 0.25);
  color: #6366f1;
}

/* Goals section title default styles (override inline) */
.goals-section-title {
  font-size: 4rem;
  font-weight: 100;
  color: #3e5984;
  letter-spacing: 0.02em;
  text-align: center;
  /* width: 100%; */
}

/* Goals swiper container styles (override inline) */
.goals-swiper-container {
  overflow-x: auto;
  white-space: nowrap;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: 16px 8px;
}

.goals-showcase-potential {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 10px;
}

.goals-potential-metric {
  min-width: 0;
  padding: 25px 10px;
  border: 1px solid rgba(62, 89, 132, 0.18);
  border-radius: 8px;
  /* background: #f8fafc; */
}

.goals-potential-label,
.goals-potential-detail {
  display: block;
  color: #64748b;
  font-family: Roboto, Verdana, sans-serif;
  font-size: 9px;
  line-height: 1.25;
  white-space: normal;
}

.goals-potential-label {
  font-weight: 600;
}

.goals-potential-value {
  display: block;
  margin: 3px 0 2px;
  color: #223c80;
  font-family: "Alfa Slab One", Roboto, Verdana, sans-serif;
  font-size:2.2rem;
  font-weight: 100;
  line-height: 1.15;
}

@media (max-width: 420px) {
  /* Add responsive styles here if needed */
  .goals-showcase-potential {
    /* grid-template-columns: 1fr; */
  }
}

/* Placeholder badge for loading state */
.goals-placeholder-badge {
  font-size: 10px;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px dashed #d1d5db;
}

/* ── Solo Quiz Live Mascot (uses unified qzr-m-* expression system) ── */
.solo-mascot {
  position: relative;
  width: 100px;
  height: 120px;
  flex-shrink: 0;
  z-index: 9990;
  pointer-events: auto;
  opacity: .9;
  transition: transform .3s ease, opacity .3s ease;
}
.solo-mascot--react {
  opacity: 1;
}
.solo-mascot svg { width: 100%; height: 100%; }

.solo-mascot--react[data-qzr-expr="happy"] {
  animation: qzrBounce .4s ease 1;
}
.solo-mascot--react[data-qzr-expr="wow"] {
  animation: qzrBounce .5s ease 2;
}
.solo-mascot--react[data-qzr-expr="victory"] {
  animation: qzrVictoryBounce .6s ease 3;
}
.solo-mascot--react[data-qzr-expr="sad"] {
  transform: scale(.92);
}
.solo-mascot--react[data-qzr-expr="dance"] {
  animation: qzrDanceBody .6s ease-in-out infinite alternate;
}
.solo-mascot--react[data-qzr-expr="celebrate"] {
  animation: qzrVictoryBounce .4s ease infinite;
}
.solo-mascot--react[data-qzr-expr="excited"] {
  animation: qzrBounce .25s ease infinite;
}
.solo-mascot--react[data-qzr-expr="love"] {
  animation: qzrLovePulse 1s ease-in-out infinite;
}

/* ── Mascot speech bubble (matches .answer-btn theme) ── */
.qzr-m-bubble {
  position: absolute;
  top: 4px;
  left: calc(100% + 10px);
  transform: scale(.7) translateX(-8px);
  transform-origin: left center;
  white-space: nowrap;
  padding: 7px 14px;
  border-radius: 16px;
  font-size: 13px;
  font-weight: 700;
  pointer-events: none;
  opacity: 0;
  z-index: 9991;
  background: rgba(255, 255, 255, 0.05);
  border: 2px solid var(--glass-border);
  color: white;
  transition: opacity .3s ease, transform .3s ease;
}
.qzr-m-bubble::after {
  content: '';
  position: absolute;
  top: 12px;
  left: -6px;
  width: 10px;
  height: 10px;
  transform: rotate(45deg);
  border-radius: 0 0 0 3px;
  background: rgba(255, 255, 255, 0.05);
  border-left: 2px solid var(--glass-border);
  border-bottom: 2px solid var(--glass-border);
}
.qzr-m-bubble.is-visible {
  opacity: 1;
  transform: scale(1) translateX(0);
}
.qzr-m-bubble.is-leaving {
  opacity: 0;
  transform: scale(.85) translateX(8px);
  transition: opacity .35s ease, transform .35s ease;
}
.qzr-m-bubble--success {
  background: rgba(16, 185, 129, 0.3);
  border-color: var(--success);
  color: #6ee7b7;
}
.qzr-m-bubble--success::after {
  background: rgba(16, 185, 129, 0.3);
  border-left-color: var(--success);
  border-bottom-color: var(--success);
}
.qzr-m-bubble--error {
  background: rgba(239, 68, 68, 0.2);
  border-color: #ef4444;
  color: #fca5a5;
}
.qzr-m-bubble--error::after {
  background: rgba(239, 68, 68, 0.2);
  border-left-color: #ef4444;
  border-bottom-color: #ef4444;
}

/* Light theme bubble — mirrors body.theme-1 .answer-btn */
body.theme-1 .qzr-m-bubble {
  background: color-mix(in srgb, var(--qz-surface, #fff) 92%, #eef4fa);
  border-color: var(--glass-border);
  color: var(--text);
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.06);
}
body.theme-1 .qzr-m-bubble::after {
  background: color-mix(in srgb, var(--qz-surface, #fff) 92%, #eef4fa);
  border-left-color: var(--glass-border);
  border-bottom-color: var(--glass-border);
}
body.theme-1 .qzr-m-bubble--success {
  background: color-mix(in srgb, var(--success) 18%, var(--qz-surface, #fff));
  border-color: var(--success);
  color: #064e3b;
}
body.theme-1 .qzr-m-bubble--success::after {
  background: color-mix(in srgb, var(--success) 18%, var(--qz-surface, #fff));
  border-left-color: var(--success);
  border-bottom-color: var(--success);
}
body.theme-1 .qzr-m-bubble--error {
  background: color-mix(in srgb, var(--danger) 14%, var(--qz-surface, #fff));
  border-color: var(--danger);
  color: #7f1d1d;
}
body.theme-1 .qzr-m-bubble--error::after {
  background: color-mix(in srgb, var(--danger) 14%, var(--qz-surface, #fff));
  border-left-color: var(--danger);
  border-bottom-color: var(--danger);
}

@media (max-width: 480px) {
  .solo-mascot { width: 75px; height: 90px; }
  .qzr-m-bubble { font-size: 11px; padding: 5px 10px; border-radius: 10px; }
}

/* ===========================================================================
   Playground scroll containment
   ---------------------------------------------------------------------------
   One scroller, and it is the question+answers block.

   The page used to scroll as a whole during a session, which meant the timer,
   the question counter and the goal HUD could all be scrolled off-screen at the
   exact moment they matter, and on a long question the answers sat below the
   fold with nothing to indicate they were there.

   Now the body cannot scroll while a session is active and
   .questions-answers-container owns the overflow. `dvh` is preferred
   (declared after `vh` so it overrides when supported) because `100vh` on
   mobile is the tallest-possible viewport, which hides the bottom of the
   block behind the browser UI; `vh` stays as the fallback for browsers without `dvh`.

   Scoped to body.realtime-active — the class page-router.js adds when a session
   opens and removes when it ends, so the lobby, the results sheet and every
   other view keep their normal page scroll.
   ======================================================================== */
/* Both, and both are needed. The scrollport is the root element, so hiding
   overflow on the body alone leaves the document scrollable and the "page does
   not scroll" rule quietly does nothing — measured: body hidden, page still
   scrolled. page-router.js puts .qzr-no-page-scroll on <html> for the life of
   the session. */
html.qzr-no-page-scroll,
body.realtime-active {
  overflow: hidden !important;
}

html.qzr-no-page-scroll {
  height: 100%;
}

/* La respiration haute mobile posee sur `body` (crs__front.css, <=767.98px) ne
   doit PAS s'appliquer pendant une session : #quizRealTimeContainer fait
   100dvh, donc une marge le decale vers le bas et sa base sort du cadre —
   mesure : 16 px inatteignables, puisque body/html sont en overflow:hidden.
   Ici la page ne defile pas, il n'y a donc aucune respiration a menager. */
body.realtime-active {
  margin-top: 0 !important;
}

/* CAREFUL: the `display: flex` below is NOT what the container actually gets.
   Every show-site in the session code sets `display` as an INLINE style, and
   inline beats any stylesheet declaration that is not !important — so at runtime
   this box is `display: block` (quizz.online.realtime.js:1473,
   quizz.online.realtime-solo.js:3188/3191/3453 all write 'block').

   It stays that way ON PURPOSE. Forcing flex here with !important would also
   override the `display = 'none'` that quizz.online.realtime.js:2505/5431 use to
   HIDE the container — both can run while body.realtime-active is still set, so
   the container would be pinned visible, exactly the bug #viewPlayground had
   under the lobby. An earlier attempt to make the JS write 'flex' instead laid
   every realtime view out sideways and was reverted.

   So `height: 100dvh` is the load-bearing declaration, not the flex properties:
   it gives the box a DEFINITE height, which is what lets #viewPlayground resolve
   a percentage height against it. The `flex: 1 1 auto; min-height: 0` on the
   children are inert while display is block — do not rely on them. */
body.realtime-active #quizRealTimeContainer {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  min-height: 0;
}

/* Every ACTIVE view fills the container and owns its own scrolling, because the
   page no longer has any. Without this the lobby — which can run past the
   viewport once a few players are in — would be clipped with no way to reach
   the bottom. */
/* :not(#viewPlayground) is load-bearing, not decoration. With the id in the
   selector this rule scores (1,3,1) against the playground's own (1,2,1), so it
   would WIN and hand the playground an overflow-y:auto it must not have — it
   delegates scrolling to .questions-answers-container. Excluding it explicitly
   beats raising specificity in an arms race nobody can read later. */
body.realtime-active #quizRealTimeContainer > .view.active:not(#viewPlayground) {
  flex: 1 1 auto;
  /* Without min-height:0 a flex item refuses to shrink below its content, the
     container never becomes smaller than what it holds, and overflow-y:auto has
     nothing to overflow — the classic silent no-op. */
  min-height: 0;
  overflow-y: auto;
}

/* The playground is the exception: it does not scroll itself, it delegates to
   .questions-answers-container so the question and its answers move together
   while the timer and HUD stay put.
   `.active` is REQUIRED here and its absence was a real bug: `.view{display:none}`
   is (0,1,0) and `.view.active{display:block}` is (0,2,0), so an id selector
   qualified only by body.realtime-active out-specified BOTH and forced the
   playground visible for the whole session — it showed up under the lobby,
   "Chargement de la question…" and all. */
body.realtime-active #viewPlayground.active {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  /* `height: 100%`, not `flex: 1 1 auto` alone, and this is the whole fix.
     The parent #quizRealTimeContainer gets a definite height (100dvh) from the
     rule above, but the session code sets its `display` INLINE to 'block', and
     an inline declaration beats the stylesheet — so it is not a flex container
     and never stretches this child. `flex: 1 1 auto` was therefore inert, the
     playground sized to its content, and .questions-answers-container ended up
     exactly as tall as what it held: measured in a real local session,
     clientHeight 2831 == scrollHeight 2831, playground 2970px against a 1305px
     viewport, no scroll.

     A percentage height does not care whether the parent is flex or block — only
     that its height is definite, which it is. So this bounds the playground
     without touching any `display`, which is what makes it safe: forcing the
     container to flex (or !important-ing its display) changes the formatting
     context for EVERY realtime view and lays the lobby out sideways.

     SOLO ONLY — see the two rules below. */
}

/* The height is the one thing solo and multiplayer must NOT share.
   `.qzr-play-hd` is put on the container by toggleView() only when soloPlay is
   true (quizz.online.realtime.js), so it is the existing, authoritative seam
   between the two modes — the same one vnext-play.css already scopes to.

   SOLO: bounded to the viewport, so .questions-answers-container has something
   to overflow and the question+answers scroll under a fixed HUD. That is the
   fix described at length above and it must stay.

   MULTIPLAYER: auto. Its playground carries content solo does not — the
   opponents strip and the inter-question ranking — and a hard 100% clips it
   against a container whose height it does not control. Letting it size to its
   content is what the mode needs. */
#quizRealTimeContainer.qzr-play-hd #viewPlayground.active {
  height: 100%;
}

body.realtime-active #quizRealTimeContainer:not(.qzr-play-hd) #viewPlayground.active {
  height: auto;
  /* AJOUT 29.AOU.2026 — le `height: auto` ci-dessus laissait le multi SANS
     defilement possible. Symptome signale : au-dela de ~4 reponses sur petit
     ecran, impossible de scroller.

     Mecanique, mesuree en reproduisant la session : `auto` fait grandir le
     playground avec son contenu (2201 px pour une vue de 846 px), donc
     .questions-answers-container, qui vaut `flex:1; min-height:0`, n'a aucune
     hauteur definie contre laquelle retrecir. Il adopte celle de son contenu —
     clientHeight 2120 == scrollHeight 2120 — et son `overflow-y: auto` devient
     un NO-OP SILENCIEUX. C'est exactement le defaut decrit plus haut pour le
     solo, resté present en multi.

     `max-height` et NON `height: 100%` : le commentaire ci-dessus met en garde
     contre un 100% dur, qui rognerait la bande d'adversaires et le classement
     inter-questions. Un maximum ne borne QUE lorsque le contenu depasse —
     verifie : contenu court, le playground reste a sa taille naturelle
     (201 px, aucun changement) ; contenu long, il se borne a 813 px et le
     scroller retrouve clientHeight 732 vs scrollHeight 2120, donc un vrai
     defilement. La mise en garde est donc respectee, pas contournee. */
  max-height: 100%;
}

.questions-answers-container {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  /* Room for the last answer tile to clear the bottom edge / home indicator. */
  padding-bottom: 8px;
  overscroll-behavior: contain;
}

/* The question card already carries its own bottom margin; keeping it inside
   the scroller means the gap scrolls with the content instead of pinning. */
.questions-answers-container > .answers-grid:last-child {
  margin-bottom: 0;
}
