/* ============================================================================
   QZR vNext — Écran Résultat solo « light HD » (Feature 1.5)
   ----------------------------------------------------------------------------
   Le résultat solo réutilise la modale temps réel partagée #scoreModal. Pour ne
   PAS toucher au classement multi-joueur (fond sombre), le skin clair est scopé
   sous #scoreModal.qzr-result-hd — classe posée uniquement pour le récap final
   solo par showRankings() (isSoloFinalStats).

   La carte .qzr-res est bâtie par rt.renderFinalStatsFigures() (mascotte, anneau
   de précision, 3 KPI, slots XP/XP-groupe/extras) puis complétée par
   rt.renderEnrichedResultOverlay() (XP gagné, XP groupe, niveau, quêtes, badges,
   coffre) une fois la finalisation des objectifs revenue.

   Chargé APRÈS style-realtime.css + vnext-tokens.css + vnext-mascot.css.
   Les anciennes règles .solo-xp-* / .solo-level-* (fond translucide) sont
   conservées en fin de fichier comme repli (overlay legacy multi / sans skeleton).
   ============================================================================ */

/* ── Modale : passage en carte claire (solo final uniquement) ──────────────── */
#scoreModal.qzr-result-hd {
  background: rgba(6, 52, 42, .34);
}
#scoreModal.qzr-result-hd .modal-content {
  background: var(--qz-screen, #F1FAF6);
  color: var(--qz-text, #06342A);
  border: 1px solid var(--qz-line, #DCEFE8);
  border-radius: 26px;
  max-width: 460px;
  box-shadow: 0 24px 60px rgba(6, 52, 42, .22);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* Bottom-sheet sizing : min 61vh / max 92vh sur grand écran, hauteur fixe 92vh en mobile. */
@media (min-width: 768px) {
  #scoreModal.qzr-result-hd .modal-content {
    min-height: 61vh;
    max-height: 92vh;
  }
}
@media (max-width: 767.98px) {
  #scoreModal.qzr-result-hd .modal-content {
    height: 92vh;
    max-height: 92vh;
  }
}
#scoreModal.qzr-result-hd .modal-body-scroll {
  padding: var(--qz-5) var(--qz-5) var(--qz-2);
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
  scrollbar-color: var(--qz-600) rgb(247, 225, 132, 0.05) !important;
  scrollbar-width: thin;
}
/* La carte porte son propre titre « Quiz terminé » : on masque le legacy. */
#scoreModal.qzr-result-hd #modalTitle,
#scoreModal.qzr-result-hd #modalSubtitle {
  display: none !important;
}

/* Croix en haut de la sheet (récap final solo uniquement) — reprend le rôle du
   bouton secondaire « Retour au parcours » / « Quitter » (retiré du footer). */
#scoreModal #btnScoreModalTopClose { display: none; }
#scoreModal.qzr-result-hd .modal-content { position: relative; }
#scoreModal.qzr-result-hd #btnScoreModalTopClose {
  display: flex;
  position: absolute;
  top: 12px; right: 14px;
  z-index: 6;
  width: 32px; height: 32px;
  padding: 0;
  border-radius: var(--qz-r-pill);
  background: var(--qz-screen, #F1FAF6);
  border: 1px solid var(--qz-line, #DCEFE8);
  color: var(--qz-muted, #5E8A7C);
  align-items: center;
  justify-content: center;
  font-size: 14px;
  cursor: pointer;
  transition: background var(--qz-dur-ui) ease, color var(--qz-dur-ui) ease;
}
#scoreModal.qzr-result-hd #btnScoreModalTopClose:hover {
  background: var(--qz-accent-soft, #E1F5EE);
  color: var(--qz-accent-ink, #0F6E56);
}

/* Récap final MULTI-JOUEUR : la même croix reprend le rôle du bouton
   « Rejouer / Quitter » (retiré du footer, cf. P4). */
#scoreModal.qzr-result-mp .modal-content { position: relative; }
#scoreModal.qzr-result-mp #btnScoreModalTopClose {
  display: flex;
  position: absolute;
  top: 12px; right: 14px;
  z-index: 6;
  width: 32px; height: 32px;
  padding: 0;
  border-radius: var(--qz-r-pill);
  background: var(--qz-screen, #F1FAF6);
  border: 1px solid var(--qz-line, #DCEFE8);
  color: var(--qz-muted, #5E8A7C);
  align-items: center;
  justify-content: center;
  font-size: 14px;
  cursor: pointer;
  transition: background var(--qz-dur-ui) ease, color var(--qz-dur-ui) ease;
}
#scoreModal.qzr-result-mp #btnScoreModalTopClose:hover {
  background: var(--qz-accent-soft, #E1F5EE);
  color: var(--qz-accent-ink, #0F6E56);
}

/* ── Carte résultat ────────────────────────────────────────────────────────── */
#finalStatsFigures .qzr-res {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2px;
}

/* Bulle mascotte + mascotte */
#finalStatsFigures .qzr-res-bubble {
  position: relative;
  display: inline-block;
  max-width: 84%;
  margin: 2px auto 0;
  padding: var(--qz-2) var(--qz-4);
  background: var(--qz-accent-soft, #E6F5EF);
  color: var(--qz-accent-ink, #0F6E56);
  border-radius: 14px;
  font-size: .88rem;
  font-weight: var(--qz-fw-strong, 500);
  line-height: 1.3;
}
#finalStatsFigures .qzr-res-bubble::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -6px;
  width: 12px;
  height: 12px;
  background: var(--qz-accent-soft, #E6F5EF);
  transform: translateX(-50%) rotate(45deg);
  border-radius: 2px;
}
#finalStatsFigures .qzr-res-mascot {
  width: 88px;
  margin: 2px auto 0;
}

/* F7 — pop the result bubble when the mascot reacts to a gamification reveal */
#finalStatsFigures .qzr-res-bubble--pop { animation: qzrResBubblePop .6s cubic-bezier(.22, .61, .36, 1); }
@keyframes qzrResBubblePop {
  0%   { transform: scale(.92); }
  45%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  #finalStatsFigures .qzr-res-bubble--pop { animation: none; }
}
#finalStatsFigures .qzr-res-mascot .qzr-mascot-svg {
  width: 88px;
  height: auto;
  display: block;
}

#finalStatsFigures .qzr-res-title {
  margin: 6px 0 1px;
  font-size: 1.4rem;
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-text, #06342A);
  letter-spacing: -.01em;
}
#finalStatsFigures .qzr-res-sub {
  margin: 0 0 4px;
  font-size: .86rem;
  color: var(--qz-muted, #5E8A7C);
}

/* Anneau de précision */
#finalStatsFigures .qzr-res-ring {
  position: relative;
  width: 158px;
  height: 158px;
  margin: var(--qz-2) auto 2px;
}
#finalStatsFigures .qzr-res-ring-svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}
#finalStatsFigures .qzr-res-ring-track {
  fill: none;
  stroke: var(--qz-line-strong, #CDE7DC);
  stroke-width: 12;
}
#finalStatsFigures .qzr-res-ring-fill {
  fill: none;
  stroke: var(--qz-accent, #16A87A);
  stroke-width: 12;
  stroke-linecap: round;
  /* Target offset is set inline; sweep from empty via keyframe (rAF-independent). */
  animation: qzrResRingFill 1.05s var(--qz-ease) both;
}
@keyframes qzrResRingFill { from { stroke-dashoffset: 326.726; } }
#finalStatsFigures .qzr-res-ring-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
#finalStatsFigures .qzr-res-ring-score {
  font-size: 2.15rem;
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-text, #06342A);
  line-height: 1;
}
#finalStatsFigures .qzr-res-ring-pct {
  margin-top: var(--qz-1);
  font-size: .72rem;
  color: var(--qz-muted, #5E8A7C);
}

/* KPI (XP gagné / Combo max / XP groupe) */
#finalStatsFigures .qzr-res-kpis {
  display: grid;
  /* auto-fit so the row is 3 tiles normally and cleanly becomes 4 when the coins
     KPI (hidden until earned) appears — collapsed empty tracks keep items stretched. */
  grid-template-columns: repeat(auto-fit, minmax(64px, 1fr));
  gap: 10px;
  width: 100%;
  margin-top: var(--qz-4);
}
#finalStatsFigures .qzr-res-kpi {
  background: var(--qz-surface, #FFFFFF);
  border: 1px solid var(--qz-line, #DCEFE8);
  border-radius: var(--qz-r-card, 16px);
  padding: var(--qz-3) var(--qz-2) var(--qz-3);
  text-align: center;
}
#finalStatsFigures .qzr-res-kpi-ico {
  font-size: 1.05rem;
  line-height: 1;
}
#finalStatsFigures .qzr-res-kpi--xp .qzr-res-kpi-ico { color: var(--qz-energy, #F5C542); }
#finalStatsFigures .qzr-res-kpi--combo .qzr-res-kpi-ico { color: var(--qz-error, #E24B4A); }
#finalStatsFigures .qzr-res-kpi--group .qzr-res-kpi-ico { color: var(--qz-accent, #16A87A); }
#finalStatsFigures .qzr-res-kpi--coins .qzr-res-kpi-ico { color: var(--qz-accent, #16A87A); }
#finalStatsFigures .qzr-res-kpi-val {
  margin-top: var(--qz-1);
  font-size: 1.3rem;
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-text, #06342A);
  line-height: 1;
}
#finalStatsFigures .qzr-res-kpi-lbl {
  margin-top: 3px;
  font-size: .72rem;
  color: var(--qz-muted, #5E8A7C);
}

/* Extras (niveau, quêtes, badges, coffre) — remplis en 2ᵉ passe */
#finalStatsFigures .qzr-res-extras {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  margin-top: var(--qz-4);
  text-align: left;
}
#finalStatsFigures .qzr-res-extras:empty { margin-top: 0; }

#finalStatsFigures .qzr-res-level,
#finalStatsFigures .qzr-res-block {
  background: var(--qz-surface, #FFFFFF);
  border: 1px solid var(--qz-line, #DCEFE8);
  border-radius: var(--qz-r-card, 16px);
  padding: var(--qz-3) var(--qz-4);
}
#finalStatsFigures .qzr-res-level-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: var(--qz-2);
}
#finalStatsFigures .qzr-res-level-badge {
  font-size: .9rem;
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-accent-ink, #0F6E56);
}
#finalStatsFigures .qzr-res-level-pct {
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-accent-ink, #0F6E56);
}
#finalStatsFigures .qzr-res-bar {
  height: 12px;
  border-radius: var(--qz-r-pill);
  background: var(--qz-accent-soft, #E6F5EF);
  overflow: hidden;
}
#finalStatsFigures .qzr-res-bar-fill {
  height: 100%;
  border-radius: var(--qz-r-pill);
  background: var(--qz-accent, #16A87A);
  transition: width .9s var(--qz-ease);
}
#finalStatsFigures .qzr-res-level-next {
  margin-top: var(--qz-2);
  font-size: .75rem;
  color: var(--qz-muted, #5E8A7C);
}

#finalStatsFigures .qzr-res-block-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: var(--qz-2);
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-text, #06342A);
}
#finalStatsFigures .qzr-res-block-head i { color: var(--qz-accent, #16A87A); }
#finalStatsFigures .qzr-res-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: var(--qz-2) 0;
  font-size: .86rem;
  color: var(--qz-text, #06342A);
}
#finalStatsFigures .qzr-res-line + .qzr-res-line { border-top: 1px solid var(--qz-line, #DCEFE8); }
#finalStatsFigures .qzr-res-line i.fa-check-circle { color: var(--qz-accent, #16A87A); }
#finalStatsFigures .qzr-res-line i.fa-award { color: var(--qz-energy, #F5C542); }
#finalStatsFigures .qzr-res-line span:last-child {
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-energy, #F5C542);
  white-space: nowrap;
}

#finalStatsFigures .qzr-res-chest {
  display: flex;
  align-items: center;
  gap: 10px;
  border-radius: var(--qz-r-card, 16px);
  padding: var(--qz-3) var(--qz-4);
  background: rgba(245, 197, 66, .14);
  border: 1px solid rgba(245, 197, 66, .40);
  color: var(--qz-text, #06342A);
  font-size: .9rem;
}
#finalStatsFigures .qzr-res-chest i { color: var(--qz-energy, #F5C542); font-size: 1.2rem; }

/* Objectif de session — même gabarit que le bloc niveau (tête + barre + légende),
   avec une teinte qui bascule selon l'issue : accent si atteint, neutre sinon —
   un objectif raté ne doit pas avoir l'air d'une célébration. */
#finalStatsFigures .qzr-res-goal:not(.qzr-res-goal--done) .qzr-res-level-badge,
#finalStatsFigures .qzr-res-goal:not(.qzr-res-goal--done) .qzr-res-level-pct {
  color: var(--qz-muted, #5E8A7C);
}
#finalStatsFigures .qzr-res-goal:not(.qzr-res-goal--done) .qzr-res-bar-fill {
  background: var(--qz-muted, #5E8A7C);
}

/* Notice de rejeu — même carte informative que le coffre, mais teinte neutre
   (pas d'or) : ce n'est pas une récompense, c'est une explication de pourquoi
   il n'y en a pas. Posée dans le squelette, cachée par défaut, révélée sans
   dépendre de l'ordre d'arrivée entre goals.finalize() et path.progress.save
   (voir rt.setResultReplayNotice). */
#finalStatsFigures .qzr-res-replay-note {
  display: flex;
  align-items: center;
  gap: 10px;
  border-radius: var(--qz-r-card, 16px);
  padding: var(--qz-3) var(--qz-4);
  margin-top: var(--qz-4);
  background: var(--qz-accent-soft, #E6F5EF);
  border: 1px solid var(--qz-line, #DCEFE8);
  color: var(--qz-muted, #5E8A7C);
  font-size: .84rem;
  text-align: left;
}
#finalStatsFigures .qzr-res-replay-note i { color: var(--qz-accent, #16A87A); font-size: 1.05rem; flex: 0 0 auto; }

/* Bouton Partager retire le 01/09 : redondant avec les blocs de partage et de
   defi que qzr-duel.js et qzr-quiz-du-jour.js posent dans ce meme
   #finalStatsFigures. Il portait en outre `location.origin`, inutilisable
   dans l'enveloppe native. Les regles .qzr-res-share partent avec lui. */

/* ── Boutons d'action (footer partagé) ─────────────────────────────────────── */
#scoreModal.qzr-result-hd .modal-footer-fixed {
  position: static;
  background: transparent;
  border-top: none;
  box-shadow: none;
  padding: 2px var(--qz-5) var(--qz-5);
}
#scoreModal.qzr-result-hd #btnReadyNext {
  background: var(--qz-accent, #16A87A) !important;
  color: #FFFFFF !important;
  border: none !important;
  border-radius: var(--qz-r-pill, var(--qz-r-pill));
  box-shadow: inset 0 -4px 0 rgba(0, 0, 0, .14);
  font-weight: var(--qz-fw-strong, 500);
  padding: var(--qz-3) var(--qz-4);
  transition: background var(--qz-dur-ui) ease;
}
#scoreModal.qzr-result-hd #btnReadyNext:hover { background: var(--qz-accent-deep, #0F6E56) !important; }
#scoreModal.qzr-result-hd #btnReadyNext:disabled { opacity: .65; }
#scoreModal.qzr-result-hd #btnQuitSoloAfterFinal,
#scoreModal.qzr-result-hd .qzr-path-final-return {
  margin: var(--qz-3) var(--qz-5) var(--qz-1) !important;
  width: calc(100% - 40px);
  background: var(--qz-surface, #FFFFFF) !important;
  color: var(--qz-accent-ink, #0F6E56) !important;
  border: 1.5px solid var(--qz-line-strong, #CDE7DC) !important;
  border-radius: var(--qz-r-pill, var(--qz-r-pill)) !important;
  font-weight: var(--qz-fw-strong, 500);
}
#scoreModal.qzr-result-hd #btnQuitSoloAfterFinal:hover,
#scoreModal.qzr-result-hd .qzr-path-final-return:hover {
  background: var(--qz-accent-soft, #E6F5EF) !important;
}

/* ============================================================================
   QZR vNext — Score inter-question solo (« qzr-solo-interim-hd »)
   ----------------------------------------------------------------------------
   Même châssis clair que le récap final, mais réduit au strict minimum : score
   courant + mascotte (message XP → objectif) + « Je suis prêt(e) ». Hauteur AUTO
   — la sheet épouse son contenu (fini le 92vh figé et le scroll interne).
   Posé par showRankings() quand isSoloInterim.
   ============================================================================ */
#scoreModal.qzr-solo-interim-hd {
  background: rgba(6, 52, 42, .34);
}
#scoreModal.qzr-solo-interim-hd .modal-content {
  background: var(--qz-surface, #FFFFFF);
  color: var(--qz-text, #06342A);
  border: 1px solid var(--qz-line, #DCEFE8);
  border-radius: 30px 30px 24px 24px;
  width: 100%;
  max-width: 460px;
  height: auto;              /* hauteur auto : la sheet épouse son contenu */
  max-height: 88vh;
  box-shadow: 0 -18px 60px rgba(6, 52, 42, .22);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#scoreModal.qzr-solo-interim-hd .modal-body-scroll {
  flex: 0 1 auto;            /* ne s'étire pas → la hauteur suit le contenu */
  min-height: 0;
  overflow-y: auto;
  padding: var(--qz-6) var(--qz-6) var(--qz-2);
}
#scoreModal.qzr-solo-interim-hd #modalTitle,
#scoreModal.qzr-solo-interim-hd #modalSubtitle,
#scoreModal.qzr-solo-interim-hd #rankingList {
  display: none !important;
}
#scoreModal.qzr-solo-interim-hd .modal-footer-fixed {
  position: static;
  background: transparent;
  border-top: none;
  box-shadow: none;
  padding: var(--qz-2) var(--qz-6) max(20px, var(--qzr-safe-bottom, 20px));
}
#scoreModal.qzr-solo-interim-hd #btnReadyNext {
  background: var(--qz-accent, #16A87A) !important;
  color: #FFFFFF !important;
  border: none !important;
  border-radius: 16px;
  box-shadow: inset 0 -4px 0 rgba(6, 52, 42, .30);   /* liseré bas 4px */
  font-weight: var(--qz-fw-strong, 500);
  font-size: 16px;
  padding: var(--qz-4) var(--qz-5);
  transition: background var(--qz-dur-ui) ease, transform .08s ease, box-shadow .08s ease;
}
#scoreModal.qzr-solo-interim-hd #btnReadyNext:hover { background: var(--qz-accent-deep, #0F6E56) !important; }
#scoreModal.qzr-solo-interim-hd #btnReadyNext:active {
  transform: scale(var(--qz-press-scale));
  box-shadow: inset 0 -2px 0 rgba(6, 52, 42, .30);
}
#scoreModal.qzr-solo-interim-hd #btnReadyNext:disabled { opacity: .65; }

/* ── Carte score simplifiée ─────────────────────────────────────────────────── */
#finalStatsFigures .qzr-si {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 4px;
  padding: var(--qz-2) 2px 2px;
}
#finalStatsFigures .qzr-si-mascot-row {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 12px;
  margin-bottom: var(--qz-1);
}
#finalStatsFigures .qzr-si-mascot {
  width: 92px;
  height: 110px;
  flex: 0 0 auto;
}
#finalStatsFigures .qzr-si-mascot .qzr-mascot-svg { width: 100%; height: 100%; }
#finalStatsFigures .qzr-si-bubble {
  position: relative;
  max-width: 60%;
  margin-bottom: var(--qz-4);
  padding: var(--qz-2) var(--qz-3);
  background: var(--qz-accent-soft, #E1F5EE);
  border: 1px solid var(--qz-line-strong, #CDE7DC);
  border-radius: 16px 16px 16px 6px;
  font-size: 13.5px;
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-text, #06342A);
  line-height: 1.35;
}
#finalStatsFigures .qzr-si-bubble b { color: var(--qz-accent-ink, #0F6E56); font-weight: var(--qz-fw-strong, 500); }
#finalStatsFigures .qzr-si-score {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 4px;
  line-height: 1;
}
#finalStatsFigures .qzr-si-num {
  font-size: 46px;
  font-weight: var(--qz-fw-strong, 500);
  letter-spacing: -.02em;
  color: var(--qz-accent-ink, #0F6E56);
}
#finalStatsFigures .qzr-si-unit {
  font-size: 19px;
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-accent, #16A87A);
}
#finalStatsFigures .qzr-si-label {
  font-size: 12px;
  font-weight: var(--qz-fw-strong, 500);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--qz-muted, #5E8A7C);
  margin-top: 2px;
}
#finalStatsFigures .qzr-si-progress {
  width: min(78%, 280px);
  height: 9px;
  border-radius: var(--qz-r-pill);
  background: var(--qz-accent-soft, #E1F5EE);
  overflow: hidden;
  margin: var(--qz-4) auto var(--qz-2);
}
#finalStatsFigures .qzr-si-progress > i {
  display: block;
  height: 100%;
  background: var(--qz-accent, #16A87A);
  border-radius: var(--qz-r-pill);
  transition: width .8s var(--qz-ease);
}
#finalStatsFigures .qzr-si-progress-cap {
  display: flex;
  justify-content: space-between;
  width: min(78%, 280px);
  margin: 0 auto;
  font-size: 11px;
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-muted, #5E8A7C);
}
@media (prefers-reduced-motion: reduce) {
  #finalStatsFigures .qzr-si-progress > i { transition: none; }
}

/* ============================================================================
   REPLI legacy — overlay XP translucide (multi / rendu sans skeleton .qzr-res).
   Conservé tel quel : injecté dans #finalStatsFigures quand la carte HD est
   absente (rt.renderEnrichedResultOverlay, chemin de repli).
   ============================================================================ */
#finalStatsFigures .solo-xp-breakdown {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 14px;
  text-align: left;
  /* Base text color must be mode-adaptive: the realtime shell forces a light
     text colour (body.realtime-active { color: var(--text) }) that is invisible
     on the light-HD result's cream surface. --qz-text is dark on light / light
     on dark, so the labels read in BOTH modes. Accent/energy bits below set
     their own colours and are unaffected. */
  color: var(--qz-text, #06342A);
}
/* Secondary lines (next-level hint, badge descriptions) read as muted but stay
   legible in both modes. */
#finalStatsFigures .solo-level-next,
#finalStatsFigures .solo-badge-item { color: var(--qz-text, #06342A); }
#finalStatsFigures .solo-xp-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1rem;
  font-weight: var(--qz-fw-strong, 500);
  /* Adaptive — overrides the dark-only #ffa040 base so "XP gagné :" reads on
     the light-HD surface too (the star icon + total keep the energy colour). */
  color: var(--qz-text, #06342A);
}
#finalStatsFigures .solo-xp-header i { color: var(--qz-energy, #F5C542); }
#finalStatsFigures .solo-xp-header strong { color: var(--qz-energy, #F5C542); font-size: 1.25rem; }
#finalStatsFigures .solo-xp-items {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-radius: 14px;
  background: rgba(127, 199, 178, .08);
  padding: 6px 12px;
}
#finalStatsFigures .solo-xp-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  font-size: .9rem;
  /* Override the base .solo-xp-item white color (dark-only) so the "XP de base"
     / "Quiz terminé" labels read on the light result surface too. Adaptive, so
     dark mode still gets light text. The +value span keeps its own accent. */
  color: var(--qz-text, #06342A);
}
#finalStatsFigures .solo-xp-item + .solo-xp-item { border-top: 1px solid rgba(127, 199, 178, .14); }
#finalStatsFigures .solo-xp-item span:last-child { font-weight: var(--qz-fw-strong, 500); }
#finalStatsFigures .solo-xp-perfect span:last-child,
#finalStatsFigures .solo-xp-perfect i { color: var(--qz-energy, #F5C542); }
#finalStatsFigures .solo-xp-speed span:last-child,
#finalStatsFigures .solo-xp-speed i { color: var(--qz-accent, #16A87A); }
#finalStatsFigures .solo-level-progress {
  display: flex;
  flex-direction: column;
  gap: 7px;
  border-radius: 14px;
  background: rgba(127, 199, 178, .08);
  padding: 12px;
}
#finalStatsFigures .solo-level-badge { font-weight: var(--qz-fw-strong, 500); color: var(--qz-accent, #16A87A); }
#finalStatsFigures .solo-level-bar-wrap {
  height: 12px;
  border-radius: var(--qz-r-pill);
  background: rgba(127, 199, 178, .18);
  overflow: hidden;
}
#finalStatsFigures .solo-level-bar-fill {
  height: 100%;
  border-radius: var(--qz-r-pill);
  background: var(--qz-accent, #16A87A);
  transition: width .9s var(--qz-ease);
}
#finalStatsFigures .solo-level-next { font-size: .8rem; opacity: .75; }
#finalStatsFigures .solo-group-xp {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}
#finalStatsFigures .solo-group-xp-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: .82rem;
  font-weight: var(--qz-fw-strong, 500);
  color: var(--qz-accent, #16A87A);
  background: rgba(127, 199, 178, .12);
  border-radius: var(--qz-r-pill);
  padding: 5px 11px;
}
#finalStatsFigures .solo-quests-done {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border-radius: 14px;
  background: rgba(127, 199, 178, .08);
  padding: 10px 12px;
}
#finalStatsFigures .solo-quests-header {
  display: flex;
  align-items: center;
  gap: 7px;
  font-weight: var(--qz-fw-strong, 500);
}
#finalStatsFigures .solo-quests-header i { color: var(--qz-accent, #16A87A); }
#finalStatsFigures .solo-quest-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 5px 0;
  font-size: .88rem;
}
#finalStatsFigures .solo-quest-item i { color: var(--qz-accent, #16A87A); }
#finalStatsFigures .solo-quest-item span:last-child { font-weight: var(--qz-fw-strong, 500); color: var(--qz-energy, #F5C542); }
#finalStatsFigures .solo-badges-earned {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
#finalStatsFigures .solo-badge-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: .86rem;
}
#finalStatsFigures .solo-badge-item i { color: var(--qz-energy, #F5C542); }
#finalStatsFigures .solo-chest-earned {
  display: flex;
  align-items: center;
  gap: 9px;
  border-radius: 14px;
  padding: 11px 13px;
  background: rgba(245, 197, 66, .12);
  border: 1px solid rgba(245, 197, 66, .35);
}
#finalStatsFigures .solo-chest-earned i { color: var(--qz-energy, #F5C542); font-size: 1.2rem; }

/* --- Offline practice: "not scored" treatment -----------------------------
   Set by the gameFinished handler in quizz.online.realtime-solo.js when the run
   came from the local engine (payload.unranked). An offline score is computed
   client-side, so it must never LOOK like a ranked result — the banner is the
   only thing standing between a practice run and a user who thinks they earned
   XP. See docs/architecture/offline-practice-mode.md §4.                     */
/* ONE target only: the modal CARD. `.qzr-result-hd` is #scoreModal itself — the
   full-screen overlay — so including it here painted a second copy of the
   banner across the whole viewport, which surfaced as a stray box stranded in a
   corner. The card is the only element the banner belongs to.

   No icon glyph either: the previous `content` opened with "\f6ff" and relied on
   `font-family: "Font Awesome 5 Free", inherit`, which is invalid — `inherit`
   cannot appear inside a font list, so the whole declaration was dropped, the
   icon font never applied and the glyph rendered as a tofu box. Text alone
   cannot regress that way. */
body.qzr-offline-run #scoreModal .modal-content::before {
  content: "Entraînement hors ligne · non comptabilisé";
  font-weight: 600;
  display: block;
  margin: 0 0 12px;
  padding: 10px 14px;
  border-radius: var(--qz-r-control, 12px);
  background: var(--qz-warning-bg);
  color: var(--qz-warning-ink);
  font-size: var(--qz-fs-xs, .78rem);
  text-align: center;
  line-height: 1.35;
}

/* XP figures are meaningless for an unranked run — hide rather than show a
   zero, which reads like a bug. */
body.qzr-offline-run .qzr-result-hd [data-xp-block],
body.qzr-offline-run .qzr-result-hd .qzr-xp-breakdown {
  display: none !important;
}
