/* =============================================================
   RevisionBPEL — couche de correction et de raffinement
   Chargée EN DERNIER : surcharge sans modifier les 20 feuilles
   existantes. Réversible en retirant la ligne dans index.html.
   26.07.2026
   ============================================================= */

/* -------------------------------------------------------------
   1. BAS DE PAGE COUPÉ SUR MOBILE  (bug signalé : podium tronqué)
   Cause : 25 usages de 100vh. Sur Chrome Android, 100vh ignore la
   barre d'URL rétractable et la barre de navigation → le bas du
   contenu tombe hors écran et devient inatteignable.
   Correctif : 100dvh (hauteur dynamique réelle) + zone sûre.
   ------------------------------------------------------------- */
:root {
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-top: env(safe-area-inset-top, 0px);
}

@supports (height: 100dvh) {
  html, body,
  .container,
  .main-content,
  .app-wrapper,
  #welcomeScreen,
  #dashboardScreen,
  .quiz-interface,
  #quizInterface {
    min-height: 100dvh;
  }
  /* Ceux qui imposaient une hauteur FIXE : la borne haute doit suivre
     le viewport dynamique, sinon le contenu est rogné. */
  .quiz-interface,
  #quizInterface,
  .sidebar {
    height: 100dvh !important;
    max-height: 100dvh !important;
  }

  /* #dashboardScreen est le conteneur qui défile réellement (mesuré) et
     porte une hauteur fixe en 100vh : c'est lui qui rognait le podium
     de la hauteur de la barre système Android. Cantonné au mobile pour
     ne pas toucher la mise en page bureau.

     ⚠ NE PAS étendre cette règle à #welcomeScreen : la page d'accueil
     est PLUS HAUTE que l'écran et n'a pas de défilement interne — lui
     imposer une hauteur fixe bride sa mise en page. Elle garde donc
     seulement le min-height ci-dessus. */
  @media (max-width: 900px) {
    #dashboardScreen,
    .dashboard-screen {
      height: 100dvh !important;
      max-height: 100dvh !important;
    }
  }
}

/* La page d'accueil doit pouvoir dépasser l'écran et défiler normalement. */
#welcomeScreen {
  height: auto !important;
  max-height: none !important;
  overflow: visible !important;
}

/* -------------------------------------------------------------
   CLICS FANTÔMES DE LA PAGE D'ACCUEIL  (bug d'origine du site)
   Une fois connecté, #welcomeScreen reste en display:flex sur
   ~890 px par-dessus le tableau de bord. Le site tente de le
   neutraliser avec pointer-events:none, mais ses descendants
   repassent en pointer-events:auto et interceptent les clics :
   toucher le haut du tableau de bord déclenchait des boutons
   invisibles de l'accueil.

   `inherit` force chaque descendant à suivre l'état de son
   parent : neutre quand l'accueil est masqué, cliquable quand
   il est affiché. Vérifié avec et sans cette règle.
   ------------------------------------------------------------- */
   Mesuré : #welcomeScreen porte bien les classes `display-none
   visibility-hidden`, mais son display calculé reste `flex` — la
   classe est écrasée ailleurs. L'écran demeure donc en position
   fixed, z-index 100, 412×890 px PAR-DESSUS le tableau de bord
   (z-index 1). Et #welcomeUserMessage y remet visibility:visible
   + pointer-events:auto : un enfant visible dans un parent
   invisible redevient cliquable.

   On rend simplement la classe d'origine effective : display:none
   neutralise tout l'arbre, quels que soient les enfants. */
#welcomeScreen.display-none,
#welcomeScreen.visibility-hidden {
  display: none !important;
}

/* Ceinture et bretelles : un élément rendu invisible ne doit
   jamais rester cliquable. */
#welcomeScreen.display-none *,
#welcomeScreen.visibility-hidden * {
  pointer-events: none !important;
  visibility: hidden !important;
}

/* -------------------------------------------------------------
   FOOTER « Powered by Luiz Dias » — invisible sur mobile
   Cause : style-mobile.css le repasse en `position: relative`, mais
   il est placé APRÈS #dashboardScreen qui occupe déjà toute la
   hauteur — le footer se retrouve donc hors écran, dans une zone
   qui ne défile pas. On le rend à nouveau ancré en bas, compact,
   et on réserve sa place dans le conteneur de défilement.
   ------------------------------------------------------------- */
@media (max-width: 900px) {
  body:has(#dashboardScreen:not(.display-none)) .app-footer,
  .app-footer {
    position: fixed !important;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60 !important;
    padding: 7px 14px calc(7px + var(--safe-bottom)) !important;
    border-top: 1px solid rgba(255, 255, 255, 0.07);
    background: rgba(18, 18, 38, 0.94);
    backdrop-filter: blur(12px);
  }

  .app-footer .powered-by,
  #poweredBy {
    font-size: 11.5px !important;
    opacity: 0.72;
    justify-content: center;
  }

  /* De la place pour que le footer ne recouvre pas le dernier bloc. */
  #dashboardScreen,
  .dashboard-screen {
    padding-bottom: calc(4.25rem + var(--safe-bottom)) !important;
  }
}

/* Le dernier bloc doit rester atteignable au-dessus de la barre système.
   #dashboardScreen est le conteneur de défilement réel : sans cette marge,
   son dernier enfant affleure le bord et se retrouve sous la barre.
   Volontairement limité à ce conteneur : appliquer la marge à body ou
   .container décalerait aussi la page d'accueil. */
#dashboardScreen,
.dashboard-screen {
  padding-bottom: calc(2rem + var(--safe-bottom)) !important;
  scroll-padding-bottom: calc(2rem + var(--safe-bottom));
}

/* Défilement fluide et sans rebond parasite sur les conteneurs internes. */
#dashboardScreen,
.dashboard-screen,
.main-content {
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
}

/* Le podium est le dernier bloc du tableau de bord : on lui garantit
   sa respiration complète, socles compris. */
.top-students-section {
  overflow: visible;
  margin-bottom: calc(1.5rem + var(--safe-bottom));
}
.podium-container {
  min-height: 0;
  height: auto;
  padding-bottom: 0.75rem;
  overflow: visible;
}
.podium-place { min-width: 0; }

/* Noms d'étudiants : lisibles plutôt que coupés au caractère près. */
.student-name {
  max-width: 96px;
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.25;
}
.student-score { white-space: nowrap; }

/* -------------------------------------------------------------
   2. TITRES DE GROUPES TRONQUÉS
   Mesuré : 224 px disponibles pour 228 px de texte → « Oral 2026
   — PROJE… » coupé pour 4 px. Deux lignes autorisées : le titre
   entier passe, sans casser la grille.
   ------------------------------------------------------------- */
.recent-group-card [class*="name"],
.recent-group-card [class*="title"],
.recent-item [class*="name"],
.group-card h3,
.group-card h4,
.group-item-name,
.recent-group-name {
  white-space: normal !important;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

/* -------------------------------------------------------------
   3. BARRE FIXE QUI RECOUVRE LE CONTENU
   ------------------------------------------------------------- */
.mobile-top-bar,
.top-bar,
.quick-nav-bar {
  padding-top: var(--safe-top);
}

/* -------------------------------------------------------------
   4. DENSITÉ ET HIÉRARCHIE — tuiles de statistiques
   Elles occupaient ~300 px de haut chacune sur un écran de 915 px :
   quatre chiffres consommaient un écran entier. Passage à une
   grille compacte, chiffre mis en avant, libellé secondaire.
   ------------------------------------------------------------- */
@media (max-width: 768px) {
  .stats-grid,
  .stats-container,
  [class*="stats-grid"] {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 0.625rem !important;
  }

  .stat-card,
  .stat-item,
  [class*="stat-card"] {
    padding: 0.875rem !important;
    min-height: 0 !important;
    border-radius: 14px !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 0.25rem !important;
  }

  /* L'icône devient un accent discret, pas le sujet principal. */
  .stat-card .stat-icon,
  .stat-card [class*="icon"] {
    width: 32px !important;
    height: 32px !important;
    min-width: 32px !important;
    font-size: 0.95rem !important;
    border-radius: 9px !important;
    margin-bottom: 0.125rem !important;
  }

  .stat-card .stat-value,
  .stat-card [class*="value"],
  .stat-card [class*="number"] {
    font-size: 1.6rem !important;
    line-height: 1.1 !important;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
  }

  .stat-card .stat-label,
  .stat-card [class*="label"] {
    font-size: 0.775rem !important;
    line-height: 1.25 !important;
    opacity: 0.62;
  }
}

/* -------------------------------------------------------------
   4 bis. CARTES DE GROUPE — densité et hiérarchie
   Chaque groupe public occupait ~400 px : titre, badge, auteur,
   puis deux boutons pleine largeur empilés. Trois groupes
   remplissaient l'écran. Les actions passent côte à côte et la
   carte redevient lisible d'un coup d'œil.
   ------------------------------------------------------------- */
@media (max-width: 768px) {
  .public-group-card,
  .group-card,
  .recent-group-card {
    padding: 0.95rem !important;
    border-radius: 14px !important;
    margin-bottom: 0.625rem !important;
  }

  /* Les deux actions (« Ajouter », « Consulter ») sur une seule ligne. */
  .public-group-card .group-actions,
  .group-card .group-actions,
  .public-group-card > div:last-child:has(button + button) {
    display: flex !important;
    flex-direction: row !important;
    gap: 0.5rem !important;
    margin-top: 0.7rem !important;
  }

  .public-group-card .group-actions > *,
  .group-card .group-actions > * {
    flex: 1 1 0 !important;
    min-width: 0 !important;
    margin: 0 !important;
    font-size: 0.82rem !important;
    padding: 0.6rem 0.5rem !important;
    min-height: 42px !important;
    white-space: nowrap;
  }

  /* Titre du groupe : le sujet de la carte, mis en avant. */
  .public-group-card h3,
  .public-group-card h4,
  .group-card h3,
  .group-card h4 {
    font-size: 1.02rem !important;
    line-height: 1.3 !important;
    margin-bottom: 0.4rem !important;
  }

  /* Badge « N cartes » : information secondaire, taille réduite. */
  .public-group-card [class*="badge"],
  .public-group-card [class*="count"],
  .group-card [class*="badge"] {
    font-size: 0.76rem !important;
    padding: 0.2rem 0.55rem !important;
    border-radius: 999px !important;
  }

  /* Bloc « Groupes publics » : moins de rembourrage perdu. */
  .public-groups-section,
  [class*="public-groups"] {
    padding: 0.95rem !important;
    border-radius: 16px !important;
  }

  /* Champ de recherche et bouton Actualiser sur une ligne. */
  .public-groups-section .search-row,
  .public-groups-section > div:has(input + button) {
    display: flex !important;
    gap: 0.5rem !important;
    align-items: center;
  }
  .public-groups-section input[type="text"],
  .public-groups-section input[type="search"] {
    flex: 1 1 auto !important;
    min-height: 42px !important;
    margin: 0 !important;
  }
}

/* Titres de section : plus proches de leur contenu.
   Restreint au tableau de bord — la page d'accueil garde sa mise en
   page d'origine, qui est soignée et ne doit pas être touchée. */
#dashboardScreen .section-title,
#dashboardScreen .section-header h2 {
  font-size: 1.18rem !important;
}
#dashboardScreen .section-header {
  margin-bottom: 0.9rem !important;
}

/* =============================================================
   TABLEAU DE BORD — passe de finition (thème sombre)
   Les tuiles portaient une grosse icône violette pleine qui
   attirait l'œil avant le chiffre lui-même. On inverse : le
   chiffre devient le sujet, l'icône un repère discret.
   ============================================================= */
@media (max-width: 768px) {
  .stat-card .stat-icon,
  .stat-card [class*="icon"] {
    background: rgba(139, 122, 246, .13) !important;
    border: 1px solid rgba(139, 122, 246, .26) !important;
    color: #b9aeff !important;
    box-shadow: none !important;
  }

  .stat-card .stat-value,
  .stat-card [class*="value"],
  .stat-card [class*="number"] {
    color: #f2f0ff !important;
  }
}

/* Cartes de groupe : un liseré d'accent au lieu d'un halo diffus. */
.public-group-card,
.group-card,
.recent-group-card {
  border-left: 2px solid rgba(139, 122, 246, .40) !important;
  box-shadow: none !important;
  transition: border-color .18s ease, background .18s ease !important;
}
.public-group-card:hover,
.group-card:hover,
.recent-group-card:hover {
  border-left-color: #8b7af6 !important;
  background: rgba(255, 255, 255, .022) !important;
}

/* En-têtes de section : un filet fin plutôt qu'un bloc lourd. */
#dashboardScreen .section-header {
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  padding-bottom: .6rem !important;
}
#dashboardScreen .section-title i {
  filter: none !important;
}

/* -------------------------------------------------------------
   5. TYPOGRAPHIE — échelle cohérente et chiffres alignés
   ------------------------------------------------------------- */
/* Restreint à l'application : la page d'accueil conserve exactement
   ses métriques d'origine (ces réglages décalaient sa mise en page
   de 5 px, mesuré). */
#dashboardScreen,
#quizInterface,
.quiz-interface,
.admin-container {
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

#dashboardScreen h1,
#dashboardScreen h2,
#dashboardScreen h3,
#dashboardScreen .section-title,
#quizInterface h1,
#quizInterface h2 {
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.stat-value,
.card-counter,
.quiz-counter,
[class*="count"],
.student-score {
  font-variant-numeric: tabular-nums;
}

/* Les longs contenus de cartes ne doivent jamais déborder. */
.quiz-card-content,
.card-content,
.card-front,
.card-back {
  overflow-wrap: anywhere;
  hyphens: auto;
}

/* -------------------------------------------------------------
   6. ACCESSIBILITÉ — focus visible et cibles tactiles
   ------------------------------------------------------------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
[role="button"]:focus-visible {
  outline: 2px solid #a5b4fc;
  outline-offset: 2px;
  border-radius: 8px;
}

/* Cibles tactiles confortables — restreint à l'application : sur la page
   d'accueil, cette règle agrandissait un lien et décalait la mise en page
   de 5 px (mesuré). */
@media (pointer: coarse) {
  #dashboardScreen button,
  #dashboardScreen .btn,
  #quizInterface button,
  .quiz-interface button,
  .admin-container button,
  #adminView button {
    min-height: 44px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* -------------------------------------------------------------
   6 bis. PANNEAU D'ADMINISTRATION SUR MOBILE
   admin.css ne contient aucun @media : la liste des utilisateurs
   garde ses 5 colonnes (2fr 2fr 1fr 1fr 1.5fr) sur 412 px de large,
   soit ~50 px par colonne — d'où les cellules réduites à « Iva »,
   « da », « Th ». Sur mobile, chaque ligne devient une carte dont
   les champs occupent toute la largeur.
   ------------------------------------------------------------- */
@media (max-width: 900px) {
  /* L'en-tête de colonnes n'a plus de sens une fois les lignes empilées. */
  .admin-users-header {
    display: none !important;
  }

  .admin-user-row {
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 0.5rem !important;
    padding: 0.875rem !important;
    margin-bottom: 0.625rem !important;
    border-radius: 12px !important;
  }

  /* Chaque champ prend toute la largeur : plus de texte coupé. */
  .admin-user-row > *,
  .admin-user-row input,
  .admin-user-row select {
    width: 100% !important;
    min-width: 0 !important;
    box-sizing: border-box;
  }

  .admin-user-row input,
  .admin-user-row select,
  .admin-input-small {
    min-height: 42px !important;
    padding: 0.55rem 0.7rem !important;
    font-size: 0.9rem !important;
    border-radius: 9px !important;
  }

  /* Les actions passent en ligne, alignées à gauche, cibles confortables. */
  .admin-user-actions {
    display: flex !important;
    flex-direction: row !important;
    justify-content: flex-start !important;
    flex-wrap: wrap;
    gap: 0.5rem !important;
    padding-top: 0.25rem;
    border-top: 1px solid rgba(255, 255, 255, 0.07);
  }

  .admin-user-actions button {
    min-width: 44px !important;
    min-height: 40px !important;
  }

  /* La liste occupait 60vh : sur téléphone c'est trop court et le
     défilement interne se cumulait à celui de la page. */
  .admin-user-list {
    max-height: none !important;
    padding: 0.75rem !important;
    overflow-x: hidden !important;
  }

  .admin-container,
  .admin-hierarchy {
    overflow-x: hidden;
  }

  /* Onglets défilables plutôt que compressés. */
  .admin-tabs {
    display: flex;
    overflow-x: auto;
    gap: 0.4rem;
    scrollbar-width: none;
  }
  .admin-tabs::-webkit-scrollbar { display: none; }
  .admin-tabs button { flex: 0 0 auto; white-space: nowrap; }

  /* Grille de profil sur une colonne. */
  .admin-profile-grid {
    grid-template-columns: 1fr !important;
  }
}

/* Boutons restés à l'apparence native du navigateur (fond clair) dans
   le panneau admin : on les raccroche à la charte sombre. */
#adminView button:not([class]),
.admin-container button:not([class]),
#adminView input[type="button"]:not([class]),
#adminView input[type="submit"]:not([class]) {
  background: linear-gradient(135deg, #6d5ce7, #8b7af6);
  color: #fff;
  border: none;
  padding: 0.6rem 1rem;
  min-height: 42px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(109, 92, 231, 0.28);
}

#adminView button:not([class]):hover,
.admin-container button:not([class]):hover {
  filter: brightness(1.08);
}

/* =============================================================
   ÉCRAN DE RÉVISION — c'est là que se passe l'essentiel du temps
   d'usage. Mesuré avant correction : carte de 535 px de haut pour
   ~150 px de texte, soit ~250 px de vide en haut et autant en bas ;
   titre tronqué ; barre de progression de 6 px quasi invisible.
   ============================================================= */

/* --- Titre du groupe : lisible plutôt que coupé --- */
#quizTitle,
.quiz-title {
  white-space: normal !important;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.98rem !important;
  line-height: 1.25 !important;
  text-align: left;
  max-width: 100%;
}

/* --- La carte : le texte occupe l'espace au lieu de flotter --- */
#quizCard .quiz-card-content,
.quiz-card-front,
.quiz-card-back {
  padding: 1.5rem 1.35rem !important;
  display: flex !important;
  flex-direction: column;
  justify-content: center;
  gap: 0.75rem;
}

#quizCard .quiz-card-content {
  font-size: 1.12rem !important;
  line-height: 1.55 !important;
  letter-spacing: -0.005em;
}

/* Le verso est souvent long : il doit pouvoir défiler proprement
   et rester lisible, aligné en haut plutôt que centré. */
.quiz-card-back .quiz-card-content {
  justify-content: flex-start;
  overflow-y: auto;
  /* PAS de overscroll-behavior ici : mesure du 26.07, dans le contexte 3D de
     la carte (faces transformees), « contain » empeche le defilement lui-meme
     et pas seulement sa propagation. Verifie en A/B/A a la molette. */
  font-size: 1.02rem !important;
  line-height: 1.6 !important;
}

/* Métadonnée « Sorti 19× · Norme » : une étiquette, pas du corps de texte. */
#quizCard .quiz-card-content p[style*="opacity"],
#quizCard .quiz-card-content [style*="font-size:.85em"] {
  opacity: 1 !important;
  font-size: 0.74rem !important;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #9d8dfb !important;
  margin-top: 0.35rem !important;
}

/* --- Barre de progression réellement visible --- */
#quizProgressBar,
.quiz-progress-bar {
  height: 8px !important;
  border-radius: 999px !important;
  background: rgba(255, 255, 255, 0.09) !important;
  overflow: hidden;
}

#quizProgressFill,
.quiz-progress-fill {
  border-radius: 999px !important;
  background: linear-gradient(90deg, #6d5ce7, #a78bfa) !important;
  box-shadow: 0 0 12px rgba(139, 122, 246, 0.55);
  transition: width 0.35s cubic-bezier(0.22, 1, 0.36, 1) !important;
  min-width: 8px;
}

/* --- Compteur : chiffres alignés, lecture immédiate --- */
#quizCurrentCard,
#quizTotalCards,
.quiz-counter {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}

/* --- Hiérarchie des commandes ---
   Précédent / Suivant sont les gestes principaux : ils doivent
   dominer. Les cinq boutons ronds secondaires (lecture auto,
   mélange, réglages, son, plein écran) passent au second plan. */
#quizPrev,
#quizNext {
  width: 56px !important;
  height: 56px !important;
  background: rgba(139, 122, 246, 0.14) !important;
  border: 1px solid rgba(139, 122, 246, 0.42) !important;
  color: #cfc7ff !important;
  transition: transform 0.16s ease, background 0.2s ease;
}

#quizPrev:active,
#quizNext:active {
  transform: scale(0.94);
  background: rgba(139, 122, 246, 0.26) !important;
}

#quizPrev:disabled,
#quizNext:disabled {
  opacity: 0.3 !important;
  border-color: rgba(255, 255, 255, 0.1) !important;
  background: transparent !important;
}

.quiz-controls-secondary button,
.quiz-actions-row button {
  opacity: 0.72;
  transition: opacity 0.18s ease;
}
.quiz-controls-secondary button:hover,
.quiz-actions-row button:hover { opacity: 1; }

/* -------------------------------------------------------------
   6 ter. ÉCRAN DE CHARGEMENT
   Le fond passait en 100vh (corrigé en 100dvh dans le HTML, sinon
   une bande vide apparaît sous la barre système Android). Ici on
   soigne le reste : composition centrée, marque lisible, et une
   barre de progression indéterminée qui donne un repère au lieu
   d'un simple texte figé.
   ------------------------------------------------------------- */
.page-loader {
  background:
    radial-gradient(900px 520px at 50% 22%, rgba(99, 102, 241, .16), transparent 62%),
    linear-gradient(160deg, #0d0d18 0%, #14142a 52%, #101024 100%) !important;
}

.page-loader .loader-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  padding: 0 28px;
  max-width: 420px;
  text-align: center;
}

.page-loader .loader-brain {
  width: min(168px, 42vw);
  height: auto;
}

/* Nom du produit, sous l'animation. */
.page-loader .loader-content::before {
  content: 'RevisionBPEL';
  order: 2;
  margin-top: 4px;
  font-size: 1.42rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  background: linear-gradient(135deg, #818cf8, #a78bfa 60%, #c4b5fd);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.page-loader .loader-text {
  order: 3;
  margin-top: 10px;
  font-size: 0.82rem !important;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #8b93b8 !important;
}

/* Barre indéterminée : montre que l'application travaille. */
.page-loader .loader-content::after {
  content: '';
  order: 4;
  margin-top: 22px;
  width: min(230px, 62vw);
  height: 3px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .09);
  overflow: hidden;
  position: relative;
  background-image: linear-gradient(90deg, transparent 0%, #6366f1 32%, #a78bfa 52%, transparent 100%);
  background-size: 55% 100%;
  background-repeat: no-repeat;
  animation: chargement-glisse 1.25s cubic-bezier(.55, .1, .45, .9) infinite;
}

@keyframes chargement-glisse {
  0%   { background-position: -60% 0; }
  100% { background-position: 160% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .page-loader .loader-content::after { animation: none; background-position: 40% 0; }
}

/* =============================================================
   ÉCRAN DE RÉVISION — passe de finition (thème sombre)
   Constat mesuré : ~300 px de vide sous le texte, le bouton
   « indice » en pavé violet plein alors que c'est une action
   secondaire, et cinq boutons ronds strictement identiques en
   bas — rien ne dit lequel compte.
   ============================================================= */

/* --- La carte respire mais ne flotte plus dans le vide --- */
#quizCard .quiz-card-content,
.quiz-card-front,
.quiz-card-back {
  padding: 1.25rem 1.35rem 1.5rem !important;
  justify-content: center;
}

/* Le contenu monte : le texte n'est plus perdu au milieu d'un grand vide. */
@media (max-width: 768px) {
  #quizCard,
  .quiz-card {
    max-height: min(58vh, 460px) !important;
  }
  #quizCard .quiz-card-content {
    max-height: 100% !important;
    overflow-y: auto !important;
    /* voir ci-dessus : overscroll-behavior bloque le defilement de la carte */
  }
}

/* --- Le bouton « indice » redevient une action secondaire --- */
#quizCard .hint-btn,
#quizCard [class*="hint"],
.quiz-hint-btn {
  background: rgba(139, 122, 246, .13) !important;
  border: 1px solid rgba(139, 122, 246, .34) !important;
  color: #b9aeff !important;
  box-shadow: none !important;
  width: 38px !important;
  height: 38px !important;
  border-radius: 10px !important;
  font-size: .95rem !important;
}
#quizCard .hint-btn:hover,
.quiz-hint-btn:hover {
  background: rgba(139, 122, 246, .26) !important;
}

/* --- Titre du groupe : blanc, il identifie l'écran --- */
#quizTitle,
.quiz-title {
  color: #eceaff !important;
  font-weight: 650 !important;
}

/* --- Barre de progression : toujours lisible, même à la carte 1 --- */
#quizProgressFill,
.quiz-progress-fill {
  min-width: 10px !important;
  border-radius: 999px !important;
}

/* --- Hiérarchie de la rangée d'outils ---
   Classes réelles relevées dans le DOM : .quiz-action-btn (les cinq
   boutons du bas, parent .quiz-action-buttons) et .quiz-nav-btn
   (Précédent / Suivant). Trois niveaux clairs :
     1. Suivant — action principale, plein
     2. Précédent — contour
     3. Outils du bas — discrets, sans fond */
.quiz-action-buttons .quiz-action-btn,
button.quiz-action-btn {
  width: 40px !important;
  height: 40px !important;
  min-height: 40px !important;
  font-size: .88rem !important;
  background: transparent !important;
  border: 1px solid rgba(255, 255, 255, .09) !important;
  color: #8f94b2 !important;
  border-radius: 10px !important;
  box-shadow: none !important;
  transition: border-color .16s ease, color .16s ease, background .16s ease !important;
}
.quiz-action-buttons .quiz-action-btn:hover,
button.quiz-action-btn:hover {
  background: rgba(255, 255, 255, .045) !important;
  border-color: rgba(139, 122, 246, .42) !important;
  color: #cfc7ff !important;
}
/* L'état actif (lecture auto, son coupé…) reste identifiable. */
.quiz-action-btn.active,
.quiz-action-btn[aria-pressed="true"] {
  border-color: rgba(139, 122, 246, .6) !important;
  color: #cfc7ff !important;
  background: rgba(139, 122, 246, .14) !important;
}

/* Actions de la carte (écouter, marquer) : même langage visuel. */
.quiz-card-actions-right .quiz-audio-btn,
.quiz-card-actions-right .quiz-star-btn,
#audioBtn, #starBtn {
  width: 40px !important;
  height: 40px !important;
  border-radius: 10px !important;
  background: transparent !important;
  border: 1px solid rgba(255, 255, 255, .10) !important;
  color: #9aa0c0 !important;
  box-shadow: none !important;
}
#audioBtn:hover, #starBtn:hover {
  border-color: rgba(139, 122, 246, .45) !important;
  color: #cfc7ff !important;
}
/* Une carte marquée doit se voir : l'étoile passe en ambre. */
#starBtn.active, .quiz-star-btn.active {
  color: #fbbf24 !important;
  border-color: rgba(251, 191, 36, .45) !important;
  background: rgba(251, 191, 36, .10) !important;
}

/* En-tête du quiz : les commandes s'effacent devant le titre. */
.quiz-back-btn,
.quiz-share-btn,
.quiz-options-btn {
  background: transparent !important;
  border: 1px solid rgba(255, 255, 255, .09) !important;
  border-radius: 10px !important;
  color: #9aa0c0 !important;
  box-shadow: none !important;
}
.quiz-back-btn:hover,
.quiz-share-btn:hover,
.quiz-options-btn:hover {
  border-color: rgba(139, 122, 246, .42) !important;
  color: #cfc7ff !important;
}

/* Le compteur devient le repère central, pas une pilule parmi d'autres. */
.quiz-counter,
#quizCurrentCard,
#quizTotalCards {
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
}
.quiz-counter {
  background: transparent !important;
  border: 1px solid rgba(255, 255, 255, .12) !important;
  border-radius: 10px !important;
  font-weight: 650 !important;
}

/* --- « Suivre les progrès » : rattaché au bas de l'écran --- */
.progress-toggle-container,
[class*="progress-toggle"] {
  background: transparent !important;
  border: 0 !important;
  border-top: 1px solid rgba(255, 255, 255, .07) !important;
  border-radius: 0 !important;
  padding: .7rem .5rem calc(.4rem + var(--safe-bottom)) !important;
  margin-top: .5rem !important;
}
.progress-toggle-container label,
[class*="progress-toggle"] label {
  font-size: .82rem !important;
  color: #8b90ad !important;
  letter-spacing: .02em;
}

/* --- Pastille de présence : discrète, pas un point vert criard --- */
.quiz-viewers-container .viewer-avatar,
#quizViewersContainer [class*="avatar"] {
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .10) !important;
  border: 0 !important;
}

/* -------------------------------------------------------------
   7. BANDEAU DE REPRISE DE LECTURE
   Affiché à l'ouverture d'un groupe déjà commencé. Non bloquant :
   pas de confirm(), pas de modale — il s'efface tout seul.
   ------------------------------------------------------------- */
.reprise-bandeau {
  position: fixed;
  left: 50%;
  bottom: calc(1.25rem + var(--safe-bottom));
  transform: translateX(-50%) translateY(140%);
  z-index: 100000;
  display: flex;
  align-items: center;
  gap: 0.875rem;
  max-width: min(92vw, 460px);
  padding: 0.75rem 0.875rem 0.75rem 1.125rem;
  border-radius: 14px;
  background: rgba(30, 27, 61, 0.97);
  border: 1px solid rgba(139, 122, 246, 0.38);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(14px);
  color: #f1f0fb;
  font-size: 0.875rem;
  line-height: 1.35;
  opacity: 0;
  transition: transform 0.34s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.34s ease;
}

.reprise-bandeau.visible {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}

.reprise-bandeau__texte { flex: 1; min-width: 0; }

.reprise-bandeau__titre {
  font-weight: 650;
  display: block;
  font-variant-numeric: tabular-nums;
}

.reprise-bandeau__detail {
  opacity: 0.66;
  font-size: 0.8rem;
  display: block;
  margin-top: 0.1rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reprise-bandeau__action {
  flex-shrink: 0;
  padding: 0.5rem 0.875rem;
  min-height: 38px;
  border-radius: 10px;
  border: 1px solid rgba(139, 122, 246, 0.5);
  background: rgba(139, 122, 246, 0.16);
  color: #cfc7ff;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease;
}

.reprise-bandeau__action:hover,
.reprise-bandeau__action:focus-visible {
  background: rgba(139, 122, 246, 0.3);
  border-color: rgba(139, 122, 246, 0.75);
}

/* Pastille « reprise » sur les cartes de groupe déjà entamées. */
.reprise-pastille {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-top: 0.35rem;
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  background: rgba(139, 122, 246, 0.15);
  border: 1px solid rgba(139, 122, 246, 0.32);
  color: #b9aeff;
  font-size: 0.7rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Barre de progression fine sur la carte de groupe. */
.reprise-jauge {
  height: 3px;
  margin-top: 0.5rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}
.reprise-jauge > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #7c6cf0, #a78bfa);
  transition: width 0.4s ease;
}

/* =============================================================
   COUCHE PWA MODERNE — styles associés à pwa-plus.js
   ============================================================= */

/* Bandeau réseau : discret, au-dessus du pied de page. */
.bandeau-reseau {
  position: fixed;
  left: 50%;
  bottom: calc(3.4rem + var(--safe-bottom));
  transform: translateX(-50%);
  z-index: 100001;
  max-width: min(92vw, 420px);
  padding: 0.55rem 0.9rem;
  border-radius: 999px;
  background: rgba(120, 53, 15, 0.94);
  border: 1px solid rgba(251, 191, 36, 0.42);
  color: #fde68a;
  font-size: 0.79rem;
  font-weight: 500;
  text-align: center;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(10px);
  animation: bandeau-entre 0.32s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes bandeau-entre {
  from { opacity: 0; transform: translateX(-50%) translateY(12px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* --- Transitions de vue (View Transitions API) ---
   Le contenu de la carte glisse au lieu de sauter. Ignoré par les
   navigateurs qui ne connaissent pas l'API. */
@supports (view-transition-name: none) {
  /* Un seul element peut porter un nom de transition : .quiz-card-content
     existe en double (recto + verso), ce qui declenchait
     « Unexpected duplicate view-transition-name ». On nomme la carte
     elle-meme, qui est unique. */
  #quizCard {
    view-transition-name: carte-revision;
  }

  ::view-transition-old(carte-revision) {
    animation: carte-sort 0.16s cubic-bezier(0.4, 0, 1, 1) both;
  }
  ::view-transition-new(carte-revision) {
    animation: carte-entre 0.26s cubic-bezier(0.22, 1, 0.36, 1) both;
  }

  @keyframes carte-sort {
    to { opacity: 0; transform: translateX(-14px); }
  }
  @keyframes carte-entre {
    from { opacity: 0; transform: translateX(16px); }
  }
}

/* Les images de cartes ne bloquent plus le rendu. */
#quizCard img,
.quiz-card-content img {
  content-visibility: auto;
  contain-intrinsic-size: 300px 400px;
}

@media (prefers-reduced-motion: reduce) {
  .bandeau-reseau { animation: none; }
  ::view-transition-old(carte-revision),
  ::view-transition-new(carte-revision) { animation: none !important; }
}


/* -------------------------------------------------------------
   RESUME DE FIN DE SESSION (modale « Votre progression »)

   Deux corrections mesurees le 26.07 :
   - la regle .stat-item plus haut vise les cartes du tableau de bord ; elle
     s'appliquait aussi ici et empilait chaque ligne (141 px chacune) ;
   - l'ensemble demandait 633 px alors qu'un ecran 360x640 n'en offre que 561,
     ce qui forcait un defilement pour lire ses propres resultats.
   On met les trois chiffres cote a cote et on resserre les marges pour que
   tout tienne d'un seul coup d'oeil.
   ------------------------------------------------------------- */
.quiz-summary-modal .quiz-summary-content {
  padding: 1rem 1.1rem !important;
  max-height: min(94dvh, 94vh) !important;
  overflow-y: auto !important;
  overscroll-behavior: contain;
  padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px)) !important;
}

.quiz-summary-modal .confetti-icon {
  font-size: 1.75rem !important;
  margin-bottom: 0.2rem !important;
  animation: none !important;
}

.quiz-summary-modal .summary-title {
  font-size: 1.02rem !important;
  line-height: 1.25 !important;
  margin: 0 0 0.25rem !important;
}

.quiz-summary-modal .summary-subtitle {
  font-size: 0.82rem !important;
  line-height: 1.3 !important;
  margin-top: 0 !important;
}

.quiz-summary-modal .summary-progress-bar {
  margin-top: 0.7rem !important;
  height: 8px !important;
}

/* Les trois chiffres cote a cote : lisibles d'un seul regard. */
.quiz-summary-modal .summary-stats {
  display: grid !important;
  grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  gap: 0.45rem !important;
  margin: 0.9rem 0 0 !important;
}

.quiz-summary-modal .summary-stats h3 {
  grid-column: 1 / -1 !important;
  margin: 0 0 0.15rem !important;
  font-size: 0.68rem !important;
  letter-spacing: 0.08em !important;
}

.quiz-summary-modal .summary-stats > .stat-item {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 0.15rem !important;
  padding: 0.55rem 0.3rem !important;
  margin: 0 !important;
  min-height: 0 !important;
  border-radius: 12px !important;
  text-align: center !important;
}

.quiz-summary-modal .summary-stats > .stat-item:hover {
  transform: none !important;
}

.quiz-summary-modal .stat-icon {
  width: 24px !important;
  height: 24px !important;
  min-width: 24px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 0 !important;
  font-size: 0.72rem !important;
  order: 1;
}

.quiz-summary-modal .stat-value {
  font-size: 1.3rem !important;
  line-height: 1.1 !important;
  margin: 0 !important;
  order: 2;
  font-variant-numeric: tabular-nums;
  animation: none !important;
}

.quiz-summary-modal .stat-label {
  margin: 0 !important;
  font-size: 0.68rem !important;
  line-height: 1.15 !important;
  flex: none !important;
  order: 3;
  opacity: 0.85;
}

/* « Prochaines etapes » : le titre n'apporte rien, les boutons parlent. */
.quiz-summary-modal .summary-actions {
  margin-top: 0.9rem !important;
}

.quiz-summary-modal .summary-actions h3 {
  display: none !important;
}

.quiz-summary-modal .summary-btn {
  padding: 0.7rem 0.9rem !important;
  font-size: 0.88rem !important;
  margin-bottom: 0.45rem !important;
  border-radius: 11px !important;
}

.quiz-summary-modal .summary-back {
  margin-top: 0.5rem !important;
  padding: 0.55rem 1rem !important;
  font-size: 0.82rem !important;
}

/* -------------------------------------------------------------
   HISTORIQUE DES SESSIONS (menu « ... » de l'ecran de revision)
   Ajout du 26.07.2026 : le bouton « ... » n'ouvrait rien.
   ------------------------------------------------------------- */
.quiz-options-menu {
  position: fixed;
  z-index: 2200;
  /* En plein ecran l'hote est #quizInterface, un conteneur flex : il etirait
     le menu a toute la largeur (mesure : 393 px au lieu de 210). align-self
     annule cet etirement ; !important parce qu'une regle du theme impose
     max-width: 100% aux enfants de ce conteneur. */
  width: max-content !important;
  min-width: 210px;
  max-width: calc(100vw - 16px) !important;
  align-self: flex-start;
  flex: 0 0 auto;
  padding: 0.35rem;
  border-radius: 14px;
  background: rgba(26, 26, 46, 0.98);
  border: 1px solid rgba(99, 102, 241, 0.28);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(18px);
  animation: histoApparait 0.16s ease-out;
}

.quiz-options-menu button {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  width: 100%;
  padding: 0.7rem 0.8rem;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: #e2e8f0;
  font-size: 0.92rem;
  text-align: left;
  cursor: pointer;
}

.quiz-options-menu button:hover,
.quiz-options-menu button:active {
  background: rgba(99, 102, 241, 0.18);
}

.quiz-options-menu button i {
  width: 18px;
  color: #a5b4fc;
  font-size: 0.9rem;
}

.quiz-histo-modal {
  position: fixed;
  inset: 0;
  z-index: 2300;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, 0.72);
  backdrop-filter: blur(6px);
  animation: histoApparait 0.2s ease-out;
}

@media (min-width: 640px) {
  .quiz-histo-modal { align-items: center; }
}

.quiz-histo-content {
  width: 100%;
  max-width: 560px;
  max-height: min(86dvh, 86vh);
  display: flex;
  flex-direction: column;
  background: linear-gradient(135deg, rgba(26, 26, 46, 0.99), rgba(42, 42, 62, 0.97));
  border: 1px solid rgba(99, 102, 241, 0.22);
  border-radius: 20px 20px 0 0;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  animation: histoMonte 0.24s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@media (min-width: 640px) {
  .quiz-histo-content { border-radius: 20px; }
}

.quiz-histo-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.1rem 0.7rem;
  border-bottom: 1px solid rgba(148, 163, 184, 0.14);
}

.quiz-histo-head h2 {
  margin: 0;
  font-size: 1.02rem;
  color: #f1f5f9;
}

.quiz-histo-close {
  flex: none;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 10px;
  background: rgba(148, 163, 184, 0.14);
  color: #cbd5e1;
  cursor: pointer;
}

.quiz-histo-body {
  padding: 0.9rem 1.1rem 1.2rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.quiz-histo-vide {
  margin: 1.4rem 0;
  text-align: center;
  color: #94a3b8;
  font-size: 0.9rem;
  line-height: 1.5;
}

.histo-resume {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.45rem;
  margin-bottom: 0.9rem;
}

.histo-resume > div {
  padding: 0.6rem 0.4rem;
  border-radius: 12px;
  background: rgba(30, 30, 50, 0.55);
  text-align: center;
}

.histo-resume strong {
  display: block;
  font-size: 1.05rem;
  color: #f1f5f9;
  font-variant-numeric: tabular-nums;
}

.histo-resume span {
  font-size: 0.68rem;
  color: #94a3b8;
}

.histo-soustitre {
  margin: 0.9rem 0 0.5rem;
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #94a3b8;
}

.histo-liste,
.histo-classement {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

.histo-liste li,
.histo-classement li {
  padding: 0.6rem 0.75rem;
  border-radius: 12px;
  background: rgba(30, 30, 50, 0.5);
}

.histo-classement li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.histo-rang {
  flex: none;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 7px;
  background: rgba(99, 102, 241, 0.22);
  color: #c7d2fe;
  font-size: 0.72rem;
  font-weight: 700;
}

.histo-nom {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #e2e8f0;
  font-size: 0.88rem;
}

.histo-temps {
  flex: none;
  color: #94a3b8;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.histo-ligne1 {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

.histo-date {
  margin-left: auto;
  color: #94a3b8;
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
}

.histo-ligne2 {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin-top: 0.35rem;
  color: #94a3b8;
  font-size: 0.76rem;
}

.histo-ligne2 i {
  margin-right: 0.25rem;
  opacity: 0.75;
}

.histo-score {
  flex: none;
  padding: 0.15rem 0.45rem;
  border-radius: 7px;
  font-size: 0.74rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.histo-score.or   { background: rgba(251, 191, 36, 0.18); color: #fcd34d; }
.histo-score.vert { background: rgba(16, 185, 129, 0.18); color: #6ee7b7; }
.histo-score.bleu { background: rgba(99, 102, 241, 0.2);  color: #a5b4fc; }
.histo-score.gris { background: rgba(148, 163, 184, 0.16); color: #cbd5e1; }

.session-enregistree {
  margin: 0.7rem 0 0;
  text-align: center;
  color: #94a3b8;
  font-size: 0.76rem;
}

.session-enregistree i {
  margin-right: 0.3rem;
  opacity: 0.8;
}

@keyframes histoApparait {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes histoMonte {
  from { transform: translateY(18px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}


/* -------------------------------------------------------------
   REPRISE DE LECTURE — filet discret
   L'ancienne pastille texte « Reprise · 1/3 » s'inserait dans le
   conteneur du compteur : elle le chevauchait et tronquait le
   titre du groupe. Remplacee par un filet en bas de ligne, hors
   du flux, qui n'enleve de place a personne.
   ------------------------------------------------------------- */
.reprise-pastille { display: none !important; }

.reprise-jauge-seule {
  position: absolute !important;
  left: 10px;
  right: 10px;
  bottom: 5px;
  height: 3px;
  margin: 0 !important;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.18);
  overflow: hidden;
  pointer-events: none;
}

.reprise-jauge-seule > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #6366f1, #a78bfa);
}
