/* Extrait de student_dashboard.html. Ordre historique : 1. */
/* ========== RESET & VARIABLES ========== */
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    /* ═══════════════════════════════════════════════════════════════════
        CORRECTION MATHJAX - Masquer le doublon d'accessibilité
       ═══════════════════════════════════════════════════════════════════ */
    mjx-assistive-mml {
        display: none !important;
        visibility: hidden !important;
        position: absolute !important;
        top: -9999px !important;
        left: -9999px !important;
    }

    /* ═══════════════════════════════════════════════════════════════════
        CORRECTION PDF - Sauts de page et pagination (ISO 80000-1)
       ═══════════════════════════════════════════════════════════════════ */
    
    /* Empêche de couper un bloc en deux */
    .no-break {
        page-break-inside: avoid !important;
        break-inside: avoid !important;
        display: block;
    }
    
    /* Force un saut de page APRÈS cet élément */
    .page-break {
        page-break-after: always;  /* Navigateurs anciens */
        break-after: page;         /* Standard moderne */
        height: 0;
        display: block;
        clear: both;
    }

    /* Éviter que les sections soient coupées */
    .fiche-section {
        break-inside: avoid;
        page-break-inside: avoid;
        margin-bottom: 20px;
    }
    
    /* ═══════════════════════════════════════════════════════════════════
        FIX CRITIQUE: FORCER FOND BLANC ET TEXTE NOIR POUR EXPORT PDF
       Gemini Diagnostic: Variables CSS du thème (--text-primary blanc) 
       causent texte invisible sur fond blanc
       ═══════════════════════════════════════════════════════════════════ */
    @media print {
        body, 
        #fiche-synthese-temp,
        .fiche-synthese-temp, 
        .fiche-section,
        .formule-bloc,
        .notion-block {
            background: white !important;
            background-color: white !important;
            color: black !important;
            -webkit-print-color-adjust: exact !important;
            print-color-adjust: exact !important;
        }
        
        /* Forcer TOUS les éléments en noir sur blanc */
        #fiche-synthese-temp *,
        .fiche-synthese-temp * {
            color: black !important;
            background-color: transparent !important;
            -webkit-print-color-adjust: exact !important;
        }
        
        /* Formules MathJax en noir */
        mjx-container,
        mjx-container *,
        .mjx-chtml,
        .mjx-math {
            color: black !important;
            background-color: transparent !important;
        }
        
        /* Titres et headers en noir */
        h1, h2, h3, h4, h5, h6 {
            color: black !important;
        }
        
        /* Tableaux et cellules */
        table, td, th {
            background-color: white !important;
            color: black !important;
        }
    }

    /* Éviter que les formules soient coupées */
    .formule-bloc {
        break-inside: avoid !important;
        page-break-inside: avoid !important;
        display: block !important;
    }
    
    /* Titre de chapitre ne doit pas être séparé du contenu */
    .chapitre-title {
        page-break-after: avoid;
        break-after: avoid;
    }

    :root {
      --primary: #7c3aed;
      /* 02/10/2026 — #06b6d4 portait le sous-titre blanc du bandeau à 2,4:1 ;
         #0e7490 le porte à 5,4:1 (règle ① de themes-eleve.css). */
      --secondary: #0e7490;
      /* Grands chiffres et mises en évidence : un accent CLAIR, lisible sur
         les cartes sombres, distinct de --primary qui porte du texte blanc. */
      --accent-texte: #a78bfa;
      --success: #10b981;
      --danger: #ef4444;
      --warning: #f59e0b;
      --info: #3b82f6;
      
      --bg-main: linear-gradient(135deg, #0f0e17 0%, #1a0033 100%);
      --bg-card: rgba(26, 24, 37, 0.9);
      --bg-card-hover: rgba(37, 35, 54, 0.9);
      
      --text-primary: #fffffe;
      --text-secondary: #a7a9be;
      --border: #2e2b41;
      --shadow: rgba(124, 58, 237, 0.3);
      
      --transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
      --border-radius: 16px;
      
      /* Rarity colors */
      --common: #9ca3af;
      --rare: #3b82f6;
      --epic: #a855f7;
      --legendary: #f59e0b;
      --mythic: #ef4444;
    }

    /* ========== PANNEAU STATS COMPACT + DRAGGABLE ========== */
    /* (panneau supprimé — CSS nettoyé) */

    /* Responsive mobile : padding simple */
    @media (max-width: 768px) {
      .phase-main-container {
        padding: 1rem;
        padding-right: 1rem;
      }
    }

    /* Cards phases */
    .phase-card {
      transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .phase-card:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 16px rgba(0,0,0,0.15);
    }

    /* ========== STYLES NAVIGATION DÉPLAÇABLE ========== */
    .nav-item {
      transition: all 0.3s ease;
      user-select: none;
    }

    .nav-item.dragging {
      box-shadow: 0 10px 30px rgba(124, 58, 237, 0.5) !important;
      transform: scale(1.05) !important;
      z-index: 1000;
    }

    .nav-item:hover {
      transform: translateX(5px);
    }

    @keyframes slideInRight {
      from {
        opacity: 0;
        transform: translateX(100px);
      }
      to {
        opacity: 1;
        transform: translateX(0);
      }
    }

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

    /* Bouton de réinitialisation - Version discrète */
    .reset-nav-btn {
      position: fixed;
      bottom: 10px;
      left: 10px;
      background: rgba(255, 255, 255, 0.05);
      color: rgba(255, 255, 255, 0.4);
      border: 1px solid rgba(255, 255, 255, 0.1);
      padding: 0.4rem 0.7rem;
      border-radius: 8px;
      font-weight: 500;
      cursor: pointer;
      box-shadow: none;
      transition: all 0.3s;
      z-index: 9998;
      display: flex;
      align-items: center;
      gap: 0.4rem;
      font-size: 0.75rem;
      opacity: 0.3;
    }

    .reset-nav-btn:hover {
      opacity: 1;
      background: rgba(239, 68, 68, 0.15);
      color: #ef4444;
      border-color: rgba(239, 68, 68, 0.3);
      transform: translateY(-1px);
      box-shadow: 0 2px 8px rgba(239, 68, 68, 0.2);
    }

    /* ========== STYLES NAVIGATION TAB-BASED ========== */
    .app-view {
      width: 100%;
      min-height: 500px;
      animation: fadeIn 0.3s ease-in-out;
    }
    
    #view-formations {
      width: 100%;
      min-height: 500px;
    }
    
    @keyframes fadeIn {
      from { opacity: 0; transform: translateY(10px); }
      to { opacity: 1; transform: translateY(0); }
    }
    
    @keyframes slideInRight {
      from { opacity: 0; transform: translateX(30px); }
      to { opacity: 1; transform: translateX(0); }
    }

    /* ========== THÈMES ==========
       02/10/2026 — les palettes des thèmes vivent dans themes-eleve.css,
       chargée juste après cette feuille. Une seule liste : apps/shared/habillages.js. */

	
/* ========== ULTIMATE STUDIO V3 (PRO) ========== */
/* Forcer le centrage du modal Studio Arrière-plan */
#bgSettingsModal {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    width: 100% !important;
    height: 100% !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    z-index: 20000 !important;
}

#bgSettingsModal.hidden,
#bgSettingsModal[style*="display: none"] {
    display: none !important;
}

#bgSettingsModal .modal-content {
    background: #131321; /* Plus sombre */
    color: white;
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 50px 100px -20px rgba(0, 0, 0, 0.8);
    max-width: 950px !important;
    width: 95%;
    display: flex;
    flex-direction: column;
    border-radius: 16px;
    overflow: hidden;
    height: 600px; /* Plus grand */
    max-height: 90vh; /* Eviter le débordement sur petits écrans */
}

.bg-studio-grid {
    display: grid;
    grid-template-columns: 1fr 350px; /* Apercu large + Panneau fixe */
    gap: 0;
    flex: 1; /* ✅ Prend toute la hauteur disponible dans le flex container */
    min-height: 0; /* ✅ Permet au grid de se réduire si nécessaire */
    overflow: hidden;
}

/* Zone Apercu */
.preview-area {
    background-color: #0f0e17;
    /* Motif de damier pour voir la transparence */
    background-image: linear-gradient(45deg, #1a1a2e 25%, transparent 25%), linear-gradient(-45deg, #1a1a2e 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #1a1a2e 75%), linear-gradient(-45deg, transparent 75%, #1a1a2e 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    position: relative;
    overflow: hidden;
    cursor: grab;
    display: flex;
    align-items: center;
    justify-content: center;
}
.preview-area:active { cursor: grabbing; }

/* L'image dans le studio */
#interactivePreview {
    width: 100%; height: 100%;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    /* IMPORTANT : scroll ici pour que l'image reste DANS le cadre du popup */
    background-attachment: scroll !important; 
    transition: filter 0.1s ease, background-position 0.1s ease;
    box-shadow: 0 0 50px rgba(0,0,0,0.5);
    position: relative; /* Pour que l'overlay soit positionné par rapport à lui */
}

/* L'overlay (effet sombre) par-dessus l'image */
#interactiveOverlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none; /* Pour que le drag fonctionne à travers l'overlay */
    z-index: 1;
}

/* Panneau de controle */
.controls-panel {
    padding: 20px;
    background: #1a1a2e;
    border-left: 1px solid rgba(255,255,255,0.1);
    overflow-y: auto;
    display: flex; flex-direction: column; gap: 15px;
}

.control-group {
    background: rgba(0, 0, 0, 0.2);
    padding: 15px;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.05);
}

.control-header {
    display: flex; justify-content: space-between;
    font-size: 0.75rem; color: #a7a9be; margin-bottom: 10px;
    font-weight: 700; text-transform: uppercase; letter-spacing: 1px;
}

/* Grille de positionnement */
.pos-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;
    width: 100px;
    margin: 0 auto;
}
.pos-btn {
    aspect-ratio: 1;
    background: #2d2d44;
    border: 1px solid #4a4a6a;
    border-radius: 4px;
    cursor: pointer;
    color: white;
    display: flex; align-items: center; justify-content: center;
    font-size: 10px;
}
.pos-btn:hover { background: var(--primary); border-color: white; }

/* Boutons de mode (Cover/Contain) */
.mode-buttons {
    display: flex; gap: 5px;
}
.mode-btn {
    flex: 1;
    padding: 8px;
    font-size: 0.8rem;
    background: #2d2d44;
    border: 1px solid transparent;
    border-radius: 6px;
    color: #a7a9be;
    cursor: pointer;
}
.mode-btn.active {
    background: var(--primary);
    color: white;
    border-color: white;
}

input[type="range"] {
    width: 100%; height: 6px; background: #2d2d44;
    border-radius: 3px; accent-color: var(--primary); outline: none;
}

@media (max-width: 768px) {
    .bg-studio-grid { grid-template-columns: 1fr; height: auto; }
    .preview-area { height: 300px; }
}
	/* ========== STYLE CONTROLES JEUX & CLASSEMENT ========== */
.game-controls-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  width: 100%;
  max-width: 320px;
  margin-top: 20px;
}

.game-btn {
  background: var(--primary); /* S'adapte au theme choisi */
  color: white;
  border: 2px solid var(--border);
  border-radius: 12px;
  height: 60px;
  font-size: 24px;
  font-weight: bold;
  cursor: pointer;
  box-shadow: 0 4px 15px var(--shadow);
  transition: transform 0.1s, background 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
}

.game-btn:active {
  transform: scale(0.95);
  filter: brightness(1.2);
}

/* ══════════════════════════════════════════════════════════════════════════
   Classement récréatif — 03/09/2026

   La ligne était en flex sans « gap » : le nom de l'élève, en flex:1,
   poussait le nom du jeu contre le score, qui se chevauchaient à l'écran
   (« CyberRunner2007 pts »). Les colonnes sont maintenant nommées et
   dimensionnées ; le nom du jeu a quitté la ligne pour devenir le titre de
   son bloc, puisqu'on classe désormais jeu par jeu.

   Les règles :nth-child(1..3) qui doraient les trois premières lignes ont
   disparu : avec un tableau par jeu, la première ligne d'un bloc est son
   titre. Le rang porte sa couleur en ligne, décidée par le code.
   ══════════════════════════════════════════════════════════════════════════ */
.arcade-game-block { margin-bottom: 18px; }
.arcade-game-title {
  margin: 0 0 6px;
  font-size: 0.95em;
  font-weight: 800;
  letter-spacing: .02em;
  color: var(--text-secondary);
  text-transform: uppercase;
}
.arcade-rank-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
  font-size: 0.9em;
}
.arcade-rank-place { width: 1.6em; flex: none; font-weight: 800; }
.arcade-rank-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.arcade-rank-score { flex: none; font-weight: bold; font-variant-numeric: tabular-nums; }
/* Se trouver dans le classement doit être immédiat. */
.arcade-rank-row--moi {
  background: rgba(99,102,241,.18);
  border-radius: 8px;
}

















    /* ========== MODES ACCESSIBILITE ========== */
    body.accessibility-dyslexia {
      font-family: 'OpenDyslexic', Arial, sans-serif !important;
      letter-spacing: 0.12em;
      word-spacing: 0.16em;
      line-height: 2 !important;
    }

    body.accessibility-contrast {
      --text-primary: #ffffff !important;
      --text-secondary: #ffff00 !important;
      --bg-card: #000000 !important;
      --bg-card-hover: #1a1a1a !important;
      --border: #ffffff !important;
    }

    body.accessibility-large-text {
      font-size: 120% !important;
    }

    body.accessibility-reduced-motion * {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
    }

    /* ========== BASE STYLES ========== */
    body {
      font-family: Arial, sans-serif; font-size: 12pt;
      color: var(--text-primary);
      min-height: 100vh;
      overflow-x: hidden;
    }

    /* ========== LOADING SCREEN ========== */
    .loading-screen {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      /* 02/10/2026 — le texte du chargement est clair ; certains fonds de thème
         (Glace, Printemps, Rouge ciel) le sont aussi. Un voile sombre garantit
         la lecture quel que soit le thème. */
      background: linear-gradient(rgba(10, 9, 18, 0.6), rgba(10, 9, 18, 0.6)), var(--bg-main);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      z-index: 9999;
      transition: opacity 0.5s ease, visibility 0s linear 0.5s;
    }

    /* 03/10/2026 — l'écran d'accueil, une fois effacé, restait un calque plein écran
       invisible AU-DESSUS de la page, avec un cercle qui tournait pour toujours :
       le navigateur continuait de produire des images pour rien (batterie, fluidité
       des tablettes). visibility:hidden le retire du rendu après le fondu, et le
       cercle s'arrête. */
    .loading-screen.hidden {
      opacity: 0;
      pointer-events: none;
      visibility: hidden;
    }
    .loading-screen.hidden .spinner {
      animation: none;
    }

    .spinner {
      width: 60px;
      height: 60px;
      border: 5px solid var(--border);
      border-top-color: var(--primary);
      border-radius: 50%;
      animation: spin 1s linear infinite;
    }

    @keyframes spin {
      to { transform: rotate(360deg); }
    }

    .loading-text {
      margin-top: 20px;
      font-size: 1.2em;
      font-weight: 600;
      color: var(--text-primary);
    }

    /* ========== HEADER ========== */
    .header {
      background: var(--bg-card);
      border-bottom: 2px solid var(--border);
      padding: 20px 0;
      position: sticky;
      top: 0;
      z-index: 100;
      backdrop-filter: blur(20px);
    }

    /* 📱 MOBILE : Header auto-hide au scroll + compact */
    @media (max-width: 768px) {
      .header {
        position: fixed !important;
        top: 0;
        left: 0;
        right: 0;
        padding: 10px 0 !important;
        transition: transform 0.3s ease-in-out, opacity 0.3s;
        will-change: transform;
        background: rgba(26, 24, 37, 0.98) !important;
      }
      
      .header.header-hidden {
        transform: translateY(-100%);
        opacity: 0;
      }
      
      .header-content {
        padding: 0 10px !important;
        gap: 8px !important;
        flex-wrap: nowrap;
      }
      
      .logo {
        font-size: 1.1em !important;
        gap: 4px !important;
      }
      
      .stat-badge {
        padding: 5px 10px !important;
        font-size: 0.8em !important;
        border-radius: 8px !important;
      }
      
      .stat-icon {
        font-size: 1em !important;
      }
      
      .user-avatar {
        width: 36px !important;
        height: 36px !important;
        font-size: 1.3em !important;
        border-width: 2px !important;
      }
      
      .header-center {
        gap: 6px !important;
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
      }
      
      .header-center::-webkit-scrollbar {
        display: none;
      }
      
      .user-stats {
        display: none !important;
      }
    }

    .header-content {
      max-width: 1400px;
      margin: 0 auto;
      padding: 0 20px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 20px;
    }

    .logo {
      font-size: 2em;
      font-weight: 900;
      display: flex;
      align-items: center;
      gap: 10px;
      color: var(--text-primary);
    }

    .header-center {
      display: flex;
      gap: 20px;
      flex-wrap: wrap;
    }

    .stat-badge {
      background: var(--bg-card-hover);
      padding: 10px 20px;
      border-radius: 12px;
      display: flex;
      align-items: center;
      gap: 8px;
      border: 2px solid var(--border);
      font-weight: 600;
      transition: var(--transition);
    }

    .stat-badge:hover {
      border-color: var(--primary);
      transform: translateY(-2px);
    }

    .stat-icon {
      font-size: 1.3em;
    }

    .user-info {
      display: flex;
      align-items: center;
      gap: 15px;
    }

    /* Sélecteur d'ambiance toujours accessible près de l'avatar. */
    .student-mood-control {
      --mood-accent: #94a3b8;
      min-height: 48px;
      display: grid;
      grid-template-columns: auto minmax(76px, auto);
      align-items: center;
      gap: 7px;
      padding: 5px 7px 5px 11px;
      border: 2px solid #64748b;
      border-color: color-mix(in srgb, var(--mood-accent) 72%, transparent);
      border-radius: 14px;
      background: rgba(15, 23, 42, .88);
      box-shadow: 0 5px 18px rgba(0, 0, 0, .22);
      color: #fff;
      font-weight: 800;
      line-height: 1;
      white-space: nowrap;
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
    }

    .student-mood-control[data-mood="sun"] { --mood-accent: #fbbf24; }
    .student-mood-control[data-mood="rain"] { --mood-accent: #38bdf8; }
    .student-mood-control[data-mood="snow"] { --mood-accent: #e0f2fe; }

    .student-mood-label {
      display: inline-flex;
      align-items: center;
      gap: 5px;
      font-size: .84rem;
      color: #f8fafc;
    }

    .student-mood-control select {
      min-width: 86px;
      min-height: 36px;
      padding: 5px 26px 5px 9px;
      border: 1px solid rgba(255, 255, 255, .24);
      border-radius: 9px;
      background: #fff;
      color: #111827;
      font: inherit;
      font-size: .84rem;
      font-weight: 750;
      cursor: pointer;
      color-scheme: light;
    }

    .student-mood-control:focus-within {
      border-color: var(--mood-accent);
      box-shadow: 0 0 0 3px color-mix(in srgb, var(--mood-accent) 28%, transparent), 0 5px 18px rgba(0, 0, 0, .22);
    }

    .user-avatar {
      font-size: 2.5em;
      background: var(--bg-card-hover);
      width: 60px;
      height: 60px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 3px solid var(--primary);
      cursor: pointer;
      transition: var(--transition);
    }

    .user-avatar:hover {
      transform: scale(1.1) rotate(5deg);
      box-shadow: 0 8px 20px var(--shadow);
    }

    .user-stats {
      display: flex;
      flex-direction: column;
      gap: 5px;
    }

    .user-name {
      font-weight: 700;
      font-size: 1.1em;
    }

    .user-level {
      color: var(--text-secondary);
      font-size: 0.9em;
    }

    .btn-logout {
      padding: 12px 24px;
      background: var(--danger);
      color: white;
      border: none;
      border-radius: var(--border-radius);
      font-weight: 600;
      cursor: pointer;
      transition: var(--transition);
    }

    .btn-logout:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 20px rgba(239, 68, 68, 0.4);
    }

    /* ========== LAYOUT ========== */
    .app-layout {
      display: flex;
      max-width: 1400px;
      margin: 0 auto;
      padding: 20px;
      gap: 20px;
    }

    .sidebar {
      width: 280px;
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 20px;
      height: fit-content;
      position: sticky;
      top: 120px;
      border: 2px solid var(--border);
    }

    .nav-item {
      padding: 15px 20px;
      margin-bottom: 10px;
      background: var(--bg-card-hover);
      border-radius: 12px;
      cursor: pointer;
      transition: var(--transition);
      display: flex;
      align-items: center;
      gap: 12px;
      font-weight: 600;
      border: 2px solid transparent;
      color: var(--text-primary);
    }

    .nav-item:hover {
      border-color: var(--primary);
      transform: translateX(5px);
    }

    .nav-item.active {
      background: var(--primary);
      border-color: var(--primary);
      color: white;
    }

    .nav-icon {
      font-size: 1.5em;
    }

    .badge-notif {
      margin-left: auto;
      background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
      color: white;
      font-size: 0.75em;
      font-weight: 700;
      padding: 2px 8px;
      border-radius: 12px;
      min-width: 20px;
      text-align: center;
      box-shadow: 0 2px 6px rgba(239, 68, 68, 0.4);
      /* calme visuel : badge fixe, plus de pulsation en boucle */
    }
    
    @keyframes pulse-badge {
      0%, 100% {
        opacity: 1;
        transform: scale(1);
      }
      50% {
        opacity: 0.7;
        transform: scale(1.1);
      }
    }

    .content {
      flex: 1;
    }
	/* ========== STYLE DU POPUP BACKGROUND ========== */
#bgSettingsModal .modal-body {
  text-align: center;
}
#previewBgImage {
  box-shadow: 0 10px 30px rgba(0,0,0,0.5);
  transition: all 0.3s ease;
}
#bgOverlayInput {
  width: 100%;
  height: 10px;
  border-radius: 5px;
  background: #d3d3d3;
  outline: none;
  margin: 10px 0 20px;
}
#bgSizeInput {
  padding: 10px;
  border-radius: 8px;
  border: 2px solid var(--primary);
  width: 100%;
  background: var(--bg-card);
  color: var(--text-primary);
}
/* ========== FIX BACKGROUND ULTIME (FILTRES) ========== */
body {
    /* L'image est geree via le pseudo-element ::before pour pouvoir la flouter independamment */
    background-color: #0f0e17;
    min-height: 100vh;
    position: relative;
}

/* Le calque de l'image de fond */
body::before {
    content: '';
    position: fixed;
    top: 0; left: 0; width: 100%; height: 100%;
    z-index: -2;
    
    /* Image pilotee par JS */
    background-image: var(--user-background, none);
    
    /* CORRECTION ICI : On utilise des variables pour la position et la taille */
    background-position: var(--bg-position, center); 
    background-size: var(--bg-size, cover);
    background-attachment: fixed;
    background-repeat: no-repeat;
    
    /* Filtres */
    filter: var(--bg-filter, none);
    transition: filter 0.3s ease, background-position 0.3s ease, background-size 0.3s ease;
}

/* Le calque de couleur (Overlay) */
body::after {
    content: '';
    position: fixed;
    top: 0; left: 0; width: 100%; height: 100%;
    z-index: -1;
    
    background-color: var(--bg-overlay-color, #000000);
    opacity: var(--bg-overlay-opacity, 0.3);
    pointer-events: none;
    transition: background-color 0.3s ease, opacity 0.3s ease;
}

/* Atmospheric Mood : canvas 2D à la demande, sans contexte WebGL.
   Les teintes statiques restent disponibles si le moteur ne charge pas. */
body[data-climate="clear"]::after { background-image:none; }
body[data-climate="sun"]::after { background:linear-gradient(140deg,rgba(250,199,105,.10),transparent 65%); }
body[data-climate="rain"]::after { background:linear-gradient(180deg,rgba(14,31,48,.3),rgba(8,21,32,.16)); }
body[data-climate="snow"]::after { background:linear-gradient(180deg,rgba(186,215,234,.1),rgba(38,63,83,.1)); }
body[data-climate="wind"]::after { background:linear-gradient(135deg,rgba(108,133,113,.1),transparent); }
#studentWeatherCanvas { position:fixed!important; inset:0!important; width:100vw!important; height:100dvh!important; max-width:none!important; max-height:none!important; z-index:-1!important; pointer-events:none!important; border:0!important; margin:0!important; opacity:.88; }
.student-mood-control[data-mood="wind"] { --mood-accent:#a3cfa5; }
.student-weather-pause { min-width:44px; min-height:44px; border:1px solid var(--border-color,#667085); border-radius:12px; background:var(--bg-card,#182231); color:var(--text-primary,#fff); cursor:pointer; }
.student-weather-pause:focus-visible { outline:3px solid #7dd3fc; outline-offset:3px; }
@media (prefers-reduced-motion: reduce) { #studentWeatherCanvas { opacity:.5; } }
    /* ========== PAGES ========== */
    .page {
      display: none;
    }

    .page.active {
      display: block;
      animation: fadeIn 0.3s ease-out;
    }

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

    .page-header {
      background: var(--degrade-bandeau, linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%));
      border-radius: var(--border-radius);
      padding: 40px;
      margin-bottom: 30px;
      text-align: center;
      box-shadow: 0 10px 30px var(--shadow);
    }

    .page-title {
      font-size: 2.5em;
      font-weight: 900;
      margin-bottom: 10px;
      color: white;
    }

    .page-subtitle {
      font-size: 1.2em;
      opacity: 0.9;
      color: white;
    }

    /* ========== CARDS ========== */
    .card {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 25px;
      border: 2px solid var(--border);
      transition: var(--transition);
    }

    .card:hover {
      border-color: var(--primary);
      box-shadow: 0 8px 20px var(--shadow);
    }

    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
    }

    .card-title {
      font-size: 1.5em;
      font-weight: 700;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .card-body {
      color: var(--text-secondary);
    }

    /* ========== GRID ========== */
    .grid {
      display: grid;
      gap: 20px;
    }

    .grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
    .grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
    .grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

    /* ========== BUTTONS ========== */
    /* ========== 🎨 SYSTEME DE BOUTONS ULTRA-PROFESSIONNEL ========== */
    
    .btn {
      padding: 12px 24px;
      border-radius: 12px;
      border: none;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 8px;
      position: relative;
      overflow: hidden;
    }
    
    /* Effet de brillance qui glisse au survol */
    .btn::before {
      content: '';
      position: absolute;
      top: 0;
      left: -100%;
      width: 100%;
      height: 100%;
      background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
      transition: left 0.5s;
    }
    
    .btn:hover::before {
      left: 100%;
    }
    
    /* Effet ondulation au clic */
    .btn::after {
      content: '';
      position: absolute;
      top: 50%;
      left: 50%;
      width: 0;
      height: 0;
      border-radius: 50%;
      background: rgba(255, 255, 255, 0.5);
      transform: translate(-50%, -50%);
      transition: width 0.6s, height 0.6s;
    }
    
    .btn:active::after {
      width: 300px;
      height: 300px;
    }

    .btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
      transform: none !important;
      box-shadow: none !important;
    }

    .btn-primary {
      background: var(--primary);
      color: white;
      box-shadow: 0 4px 15px rgba(124, 58, 237, 0.3);
    }

    .btn-primary:hover:not(:disabled) {
      transform: translateY(-3px) scale(1.02);
      box-shadow: 0 12px 30px rgba(124, 58, 237, 0.5);
      background: #6d28d9;
    }
    
    .btn-primary:active:not(:disabled) {
      transform: translateY(-1px) scale(0.98);
    }

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

    .btn-success:hover:not(:disabled) {
      transform: translateY(-3px) scale(1.02);
      box-shadow: 0 12px 30px rgba(16, 185, 129, 0.5);
      background: #059669;
    }
    
    .btn-success:active:not(:disabled) {
      transform: translateY(-1px) scale(0.98);
    }

    .btn-danger {
      background: var(--danger);
      color: white;
      box-shadow: 0 4px 15px rgba(239, 68, 68, 0.3);
    }
    
    .btn-danger:hover:not(:disabled) {
      transform: translateY(-3px) scale(1.02);
      box-shadow: 0 12px 30px rgba(239, 68, 68, 0.5);
      background: #dc2626;
    }
    
    .btn-danger:active:not(:disabled) {
      transform: translateY(-1px) scale(0.98);
    }

    .btn-warning {
      background: var(--warning);
      color: white;
      box-shadow: 0 4px 15px rgba(245, 158, 11, 0.3);
    }
    
    .btn-warning:hover:not(:disabled) {
      transform: translateY(-3px) scale(1.02);
      box-shadow: 0 12px 30px rgba(245, 158, 11, 0.5);
      background: #d97706;
    }
    
    .btn-warning:active:not(:disabled) {
      transform: translateY(-1px) scale(0.98);
    }

    .btn-secondary {
      background: var(--bg-card-hover);
      color: var(--text-primary);
      border: 2px solid var(--border);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
    }
    
    .btn-secondary:hover:not(:disabled) {
      transform: translateY(-2px);
      border-color: var(--primary);
      box-shadow: 0 8px 20px rgba(124, 58, 237, 0.3);
    }
    
    /* Boutons generiques (non classes)

       21/09/2026 — .pe-bascule et .pe-sortie (mode plein écran) sont exclus au
       même titre que .btn et .mode-button. Sans cela, « position: relative »
       l'emportait sur leur « position: fixed » — ce sélecteur pèse quatre
       classes, une simple classe ne peut pas le battre — et la pastille de
       sortie se retrouvait au bas du document, hors de l'écran. Le « transform »
       et le « filter » des règles :hover/:active posaient le même problème.

       ⚠ .tuto-reopen (« Revoir la visite guidée ») subit encore exactement cela :
       apps/student/onboarding/onboarding.css la veut fixe en bas à gauche, elle
       se retrouve en fin de flux. Non corrigé ici : déplacer un bouton existant
       est un changement visible, à décider. */
    button:not(.btn):not(.mode-button):not(.reaction-bar button):not(.pe-bascule):not(.pe-sortie) {
      transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
      position: relative;
      overflow: hidden;
      cursor: pointer;
    }
    
    button:not(.btn):not(.mode-button):not(.pe-bascule):not(.pe-sortie):hover {
      transform: translateY(-2px);
      filter: brightness(1.1);
      box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
    }
    
    button:not(.btn):not(.mode-button):not(.pe-bascule):not(.pe-sortie):active {
      transform: translateY(0);
    }
    
    /* Boutons avec background inline (couleurs specifiques) */
    button[style*="background:#10b981"]:hover,
    button[style*="background: #10b981"]:hover {
      background: #059669 !important;
      box-shadow: 0 8px 24px rgba(16, 185, 129, 0.5) !important;
      transform: translateY(-3px) scale(1.03);
    }
    
    button[style*="background:#ef4444"]:hover,
    button[style*="background: #ef4444"]:hover {
      background: #dc2626 !important;
      box-shadow: 0 8px 24px rgba(239, 68, 68, 0.5) !important;
      transform: translateY(-3px) scale(1.03);
    }
    
    button[style*="background:#3b82f6"]:hover,
    button[style*="background: #3b82f6"]:hover {
      background: #2563eb !important;
      box-shadow: 0 8px 24px rgba(59, 130, 246, 0.5) !important;
      transform: translateY(-3px) scale(1.03);
    }
    
    button[style*="background:#8b5cf6"]:hover,
    button[style*="background: #8b5cf6"]:hover {
      background: #7c3aed !important;
      box-shadow: 0 8px 24px rgba(139, 92, 246, 0.5) !important;
      transform: translateY(-3px) scale(1.03);
    }
    
    /* Boutons avec gradient */
    button[style*="background:linear-gradient"]:hover,
    button[style*="background: linear-gradient"]:hover {
      transform: translateY(-3px) scale(1.02);
      box-shadow: 0 12px 30px rgba(124, 58, 237, 0.5);
      filter: brightness(1.15);
    }
    
    /* Boutons desactives */
    button:disabled,
    button[disabled] {
      opacity: 0.5;
      cursor: not-allowed !important;
      transform: none !important;
      box-shadow: none !important;
      filter: none !important;
    }

    /* ========== DASHBOARD ========== */
    .stats-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 20px;
      margin-bottom: 30px;
    }

    .stat-card {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 25px;
      border: 2px solid var(--border);
      text-align: center;
      transition: var(--transition);
    }

    .stat-card:hover {
      border-color: var(--primary);
      transform: translateY(-5px);
      box-shadow: 0 8px 20px var(--shadow);
    }

    .stat-icon-large {
      font-size: 3em;
      margin-bottom: 10px;
    }

    .stat-value {
      font-size: 2.5em;
      font-weight: 900;
      color: var(--accent-texte, var(--primary));
      margin-bottom: 5px;
    }

    .stat-label {
      color: var(--text-secondary);
      font-weight: 600;
    }

    /* ========== PROGRESS BAR ========== */
    .progress-container {
      background: var(--bg-card-hover);
      border-radius: 999px;
      height: 20px;
      overflow: hidden;
      position: relative;
      margin: 15px 0;
    }

    .progress-bar {
      background: linear-gradient(90deg, var(--primary), var(--secondary));
      height: 100%;
      border-radius: 999px;
      transition: width 0.5s ease;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: 600;
      font-size: 0.85em;
    }

    /* ========== SHOP ========== */
    .shop-filters {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 25px;
      margin-bottom: 30px;
      border: 2px solid var(--border);
    }

    .filter-section {
      margin-bottom: 20px;
    }

    .filter-section:last-child {
      margin-bottom: 0;
    }

    .filter-label {
      font-weight: 700;
      font-size: 1.1em;
      margin-bottom: 15px;
      display: block;
    }

    .filter-buttons {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
    }

    .filter-btn {
      padding: 10px 20px;
      background: var(--bg-card-hover);
      border: 2px solid var(--border);
      border-radius: 12px;
      cursor: pointer;
      font-weight: 600;
      transition: var(--transition);
      color: var(--text-secondary);
    }

    .filter-btn:hover {
      border-color: var(--primary);
      color: var(--text-primary);
      transform: translateY(-2px);
    }

    .filter-btn.active {
      background: var(--primary);
      border-color: var(--primary);
      color: white;
    }

    .filter-btn.common { border-color: var(--common); }
    .filter-btn.common.active { background: var(--common); }
    .filter-btn.rare { border-color: var(--rare); }
    .filter-btn.rare.active { background: var(--rare); }
    .filter-btn.epic { border-color: var(--epic); }
    .filter-btn.epic.active { background: var(--epic); }
    .filter-btn.legendary { border-color: var(--legendary); }
    .filter-btn.legendary.active { background: var(--legendary); }

    .search-bar {
      width: 100%;
      padding: 15px 20px;
      background: var(--bg-card-hover);
      border: 2px solid var(--border);
      border-radius: 12px;
      font-size: 1em;
      color: var(--text-primary);
      transition: var(--transition);
    }

    .search-bar:focus {
      outline: none;
      border-color: var(--primary);
    }

    .search-bar::placeholder {
      color: var(--text-secondary);
    }

    .shop-item {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 0;
      border: 2px solid var(--border);
      transition: var(--transition);
      text-align: center;
      cursor: pointer;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }

    .shop-item:hover {
      transform: translateY(-5px);
      box-shadow: 0 10px 30px var(--shadow);
    }

    .shop-item.common { border-color: var(--common); }
    .shop-item.rare { border-color: var(--rare); }
    .shop-item.epic { border-color: var(--epic); }
    .shop-item.legendary { border-color: var(--legendary); }

    .shop-item.owned { position: relative; }

    .shop-item.owned::after {
      content: '✓ Possédé';
      position: absolute;
      top: 10px;
      right: 10px;
      background: var(--success);
      color: white;
      padding: 4px 10px;
      border-radius: 8px;
      font-size: 0.78em;
      font-weight: 700;
      letter-spacing: .3px;
      box-shadow: 0 2px 8px rgba(0,0,0,.35);
      z-index: 2;
    }

    /* Conteneur image ratio 16/9 fixe */
    .item-image-wrap {
      width: 100%;
      aspect-ratio: 16 / 9;
      overflow: hidden;
      background: var(--bg-secondary);
      flex-shrink: 0;
      position: relative;
    }
    .item-image-wrap img.item-image {
      width: 100% !important;
      height: 100% !important;
      object-fit: cover !important;
      object-position: center top;
      display: block;
      transition: transform .35s ease;
      border-radius: 0 !important;
      margin-bottom: 0 !important;
    }
    .shop-item:hover .item-image-wrap img.item-image {
      transform: scale(1.06);
    }
    .item-image-wrap .item-emoji-fallback {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 3.5em;
    }

    /* Corps texte sous l'image */
    .shop-item-body {
      padding: 14px 16px 16px;
      display: flex;
      flex-direction: column;
      flex: 1;
    }

    .item-emoji {
      font-size: 4em;
      margin-bottom: 15px;
    }

    .item-name {
      font-weight: 700;
      font-size: 1.05em;
      margin-bottom: 6px;
    }

    .item-description {
      color: var(--text-secondary);
      font-size: 0.88em;
      margin-bottom: 10px;
      min-height: 36px;
      flex: 1;           /* pousse le prix + bouton en bas */
    }

    .item-price {
      font-size: 1.4em;
      font-weight: 900;
      color: var(--warning);
      margin-bottom: 10px;
    }

    .item-rarity {
      display: inline-block;
      padding: 5px 15px;
      border-radius: 999px;
      font-size: 0.85em;
      font-weight: 700;
      margin-bottom: 15px;
      text-transform: uppercase;
    }

    .item-rarity.common { background: var(--common); color: white; }
    .item-rarity.rare { background: var(--rare); color: white; }
    .item-rarity.epic { background: var(--epic); color: white; }
    .item-rarity.legendary { background: var(--legendary); color: white; }

    /* ========== GAMES ========== */
	/* Amelioration des cartes de jeux */
    .game-card {
      position: relative;
      overflow: hidden; /* Empeche l'image de depasser */
      /* ... vos autres styles existants ... */
    }

    /* Ajout d'un fond sombre semi-transparent derriere le texte pour la lisibilite */
    .game-description {
      background: rgba(0, 0, 0, 0.6); /* Fond noir transparent */
      color: white;
      padding: 5px 10px;
      border-radius: 8px;
      margin-bottom: 10px;
      display: inline-block; /* Pour coller au texte */
    }

    /* Ameliorer les stats en bas de carte */
    .game-stats {
      background: rgba(255, 255, 255, 0.9); /* Fond blanc presque opaque */
      border-radius: 12px;
      padding: 10px;
      margin-top: 10px;
      color: #333; /* Texte sombre pour contraste sur fond blanc */
    }
    
    /* Si le texte est rouge comme sur l'image, on force une couleur lisible */
    .game-stat-label {
        color: #666 !important;
        font-weight: 600;
    }
    .game-stat-value {
        color: #d32f2f !important; /* Rouge fonce plus lisible */
    }
    .game-card {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 25px;
      border: 2px solid var(--border);
      transition: var(--transition);
      cursor: pointer;
      text-align: center;
    }

    .game-card:hover {
      border-color: var(--primary);
      transform: translateY(-5px);
      box-shadow: 0 10px 30px var(--shadow);
    }

    .game-icon {
      font-size: 5em;
      margin-bottom: 15px;
    }

    .game-title {
      font-size: 1.5em;
      font-weight: 700;
      margin-bottom: 10px;
    }

    .game-description {
      color: var(--text-secondary);
      margin-bottom: 20px;
    }

    .game-stats {
      display: flex;
      justify-content: space-around;
      margin-top: 20px;
      padding-top: 20px;
      border-top: 2px solid var(--border);
    }

    .game-stat {
      text-align: center;
    }

    .game-stat-value {
      font-size: 1.5em;
      font-weight: 700;
      color: var(--accent-texte, var(--primary));
    }

    .game-stat-label {
      color: var(--text-secondary);
      font-size: 0.9em;
    }

    /* ========== GAME CANVAS ========== */
    .game-container {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 30px;
      border: 2px solid var(--border);
      text-align: center;
    }

    .game-canvas {
      max-width: 100%;
      border: 3px solid var(--border);
      border-radius: 12px;
      background: #000;
      margin: 20px auto;
      display: block;
    }

    .game-controls {
      display: flex;
      gap: 15px;
      justify-content: center;
      margin-top: 20px;
      flex-wrap: wrap;
    }

    /* ========== BADGES ========== */
    .badge-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
      gap: 20px;
    }

    .badge-item {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 20px;
      border: 2px solid var(--border);
      text-align: center;
      transition: var(--transition);
    }

    .badge-item:hover {
      border-color: var(--primary);
      transform: scale(1.05);
    }

    .badge-item.locked {
      opacity: 0.4;
      filter: grayscale(1);
    }

    .badge-icon {
      font-size: 3em;
      margin-bottom: 10px;
    }

    .badge-name {
      font-weight: 700;
      font-size: 0.9em;
      margin-bottom: 5px;
    }

    .badge-description {
      color: var(--text-secondary);
      font-size: 0.75em;
    }

    /* ========== LEADERBOARD ========== */
    .leaderboard-table {
      width: 100%;
      border-collapse: collapse;
    }

    .leaderboard-table th,
    .leaderboard-table td {
      padding: 15px;
      text-align: left;
      border-bottom: 2px solid var(--border);
    }

    .leaderboard-table th {
      background: var(--bg-card-hover);
      font-weight: 700;
      position: sticky;
      top: 0;
    }

    .leaderboard-table tr {
      transition: var(--transition);
    }

    .leaderboard-table tr:hover {
      background: var(--bg-card-hover);
    }

    .rank-badge {
      display: inline-block;
      width: 40px;
      height: 40px;
      background: var(--primary);
      border-radius: 50%;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      font-weight: 900;
      font-size: 1.2em;
    }

    .rank-badge.gold { background: #f59e0b; }
    .rank-badge.silver { background: #94a3b8; }
    .rank-badge.bronze { background: #ea580c; }

    /* ========== QUESTS ========== */
    .quest-card {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      padding: 20px;
      border: 2px solid var(--border);
      transition: var(--transition);
      margin-bottom: 15px;
    }

    .quest-card:hover {
      border-color: var(--primary);
    }

    .quest-card.completed {
      border-color: var(--success);
      opacity: 0.7;
    }

    .quest-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
    }

    .quest-title {
      font-weight: 700;
      font-size: 1.1em;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .quest-reward {
      background: var(--warning);
      color: white;
      padding: 5px 15px;
      border-radius: 999px;
      font-weight: 700;
      font-size: 0.9em;
    }

    .quest-progress {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-top: 10px;
    }

    .quest-progress-text {
      color: var(--text-secondary);
      font-size: 0.9em;
    }

    /* ========== MODAL ========== */
    .modal-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.8);
      display: none;
      align-items: center;
      justify-content: center;
      z-index: 1000;
      backdrop-filter: blur(5px);
    }

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

    /* Game modal specific styles for fullscreen */
    #gameModal.modal-overlay {
      z-index: 9999;
    }

    #gameModal .modal-content {
      width: 100vw !important;
      height: 100vh !important;
      max-width: 100vw !important;
      max-height: 100vh !important;
      margin: 0 !important;
      border-radius: 0 !important;
      overflow: hidden;
    }

    #gameContainer {
      width: 100%;
      height: 100%;
    }

    #gameContainer canvas {
      display: block;
      margin: 0 auto;
    }

    /* ══════════ CADRE DE JEU COMMUN — 23/09/2026 ══════════
       « Il y a un décalage en écran ordinateur, smartphone et tablette. »
       Trois causes, une règle chacune :
       ① un conteneur centré (justify-content: center) qui déborde coupe son
         HAUT, hors d'atteinte du défilement : le jeu glissait sous l'en-tête.
         Les marges automatiques centrent sans jamais rien couper ;
       ② chaque canvas gardait sa petite taille native (400 × 300, 240 × 400…)
         au milieu d'un grand écran, ou était étiré sur la hauteur d'un
         téléphone. Il prend maintenant la plus grande taille qui tienne en
         LARGEUR comme en HAUTEUR, sans jamais se déformer. Chaque jeu donne
         ses proportions (--jeu-ratio) et la place de ses commandes
         (--jeu-reserve) dans arcade-manager.js ;
       ③ en-tête compact : titre sur une ligne, FERMER toujours visible. */
    #gameContainer {
      justify-content: flex-start !important;
      padding: clamp(10px, 2.5vw, 24px) !important;
    }
    #gameContainer > :first-child { margin-top: auto; }
    #gameContainer > :last-child { margin-bottom: auto; }
    #gameContainer > canvas {
      width: min(100%, var(--jeu-max, 760px), calc((100vh - var(--jeu-reserve, 280px)) * var(--jeu-ratio, 1))) !important;
      width: min(100%, var(--jeu-max, 760px), calc((100dvh - var(--jeu-reserve, 280px)) * var(--jeu-ratio, 1))) !important;
      height: auto !important;
      max-width: 100% !important;
      max-height: none !important;
      flex-shrink: 0;
    }
    /* Téléphone tenu en paysage : les commandes passent à côté du jeu. */
    @media (max-height: 520px) and (orientation: landscape) {
      #gameContainer {
        flex-direction: row !important;
        flex-wrap: wrap;
        align-content: center;
        justify-content: center !important;
        gap: 16px;
      }
      /* La réserve de chaque jeu (inline, pour les commandes SOUS le jeu)
         ne vaut plus : les commandes sont à côté. Seul l'en-tête compte. */
      #gameContainer > canvas {
        width: min(62%, calc((100vh - 110px) * var(--jeu-ratio, 1))) !important;
        width: min(62%, calc((100dvh - 110px) * var(--jeu-ratio, 1))) !important;
      }
      #gameContainer > canvas + div, #gameContainer > canvas + button { margin-top: 0 !important; max-width: 260px !important; }
    }
    #gameModal .modal-content > div:first-child {
      gap: 12px;
      padding-top: max(10px, env(safe-area-inset-top)) !important;
    }
    #gameTitle {
      flex: 1;
      min-width: 0;
      text-align: left;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    #gameScoreDisplay { white-space: nowrap; }
    #gameModal .modal-content > div:first-child button {
      white-space: nowrap;
      min-height: 44px;
      flex-shrink: 0;
    }

    /* Responsive adjustments */
    @media (max-width: 768px) {
      #gameModal .modal-content > div:first-child {
        padding: 10px 15px;
      }
      
      #gameModal .modal-content > div:first-child h3 {
        font-size: 1.2rem;
      }
      
      #gameModal .modal-content > div:first-child button {
        padding: 8px 15px;
        font-size: 0.9rem;
      }
      
      #gameContainer {
        padding: 10px;
      }
    }

    @media (max-width: 480px) {
      #gameModal .modal-content > div:first-child h3 {
        font-size: 1rem;
      }
      
      #gameModal .modal-content > div:first-child span {
        font-size: 1rem;
      }
    }

    .modal-content {
      background: var(--bg-card);
      border-radius: var(--border-radius);
      border: 2px solid var(--border);
      max-width: 600px;
      width: 90%;
      max-height: 90vh;
      overflow-y: auto;
      animation: modalSlideIn 0.3s ease-out;
    }

    @keyframes modalSlideIn {
      from {
        opacity: 0;
        transform: translateY(-50px) scale(0.9);
      }
      to {
        opacity: 1;
        transform: translateY(0) scale(1);
      }
    }

    .modal-header {
      padding: 25px;
      border-bottom: 2px solid var(--border);
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .modal-title {
      font-size: 1.8em;
      font-weight: 800;
    }

    .modal-close-btn {
      background: var(--danger);
      color: white;
      border: none;
      width: 40px;
      height: 40px;
      border-radius: 50%;
      font-size: 1.5em;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: var(--transition);
    }

    .modal-close-btn:hover {
      transform: rotate(90deg);
    }

    .modal-body {
      padding: 25px;
    }

    /* ========== TOAST ========== */
    .toast {
      position: fixed;
      bottom: 30px;
      right: 30px;
      background: var(--bg-card);
      border: 2px solid var(--border);
      border-radius: var(--border-radius);
      padding: 20px 25px;
      box-shadow: 0 10px 30px var(--shadow);
      z-index: 2000;
      animation: slideInRight 0.3s ease-out;
      max-width: 400px;
    }

    @keyframes slideInRight {
      from {
        opacity: 0;
        transform: translateX(100px);
      }
      to {
        opacity: 1;
        transform: translateX(0);
      }
    }

    .toast.success { border-color: var(--success); }
    .toast.error { border-color: var(--danger); }
    .toast.warning { border-color: var(--warning); }
    .toast.info { border-color: var(--info); }

    /* ========== EXERCISE OPTIONS ========== */
    .exercise-option {
      display: block;
      padding: 15px 20px;
      background: var(--bg-card-hover);
      border: 2px solid var(--border);
      border-radius: 12px;
      margin-bottom: 10px;
      cursor: pointer;
      transition: var(--transition);
      display: flex;
      align-items: center;
      gap: 15px;
    }

    .exercise-option:hover {
      border-color: var(--primary);
      transform: translateX(5px);
    }

    .exercise-option input[type="radio"] {
      width: 20px;
      height: 20px;
      cursor: pointer;
    }

    .exercise-result {
      margin-top: 20px;
      padding: 15px;
      border-radius: 12px;
      font-weight: 600;
      text-align: center;
      display: none;
    }

    .exercise-result.success {
      background: var(--success);
      color: white;
      display: block;
    }

    .exercise-result.error {
      background: var(--danger);
      color: white;
      display: block;
    }

    /* ========== RESPONSIVE ========== */
    @media (max-width: 768px) {
      .app-layout {
        flex-direction: column;
      }
      
      .sidebar {
        width: 100%;
        position: static;
      }
      
      .header-content {
        flex-direction: column;
        text-align: center;
      }
      
      .header-center {
        width: 100%;
        justify-content: center;
      }
      
      .grid-2, .grid-3, .grid-4 {
        grid-template-columns: 1fr;
      }
      
      .page-title {
        font-size: 2em;
      }
    }

    /* ========== CHAT PAGE ========== */
    .chat-container {
      display: flex;
      flex-direction: column;
      height: 600px;
      background: var(--chat-bg, linear-gradient(135deg, #667eea 0%, #764ba2 100%));
      border-radius: var(--border-radius);
      overflow: hidden;
    }

    .chat-messages {
      flex: 1;
      overflow-y: auto;
      padding: 20px;
      display: flex;
      flex-direction: column;
      gap: 15px;
      background: var(--chat-messages-bg, rgba(0,0,0,0.2));
    }

    .chat-message {
      font-size: var(--chat-font-size, 14px);
      color: var(--chat-text-color, inherit);
      display: flex;
      gap: 12px;
      align-items: flex-start;
      padding: 12px;
      background: rgba(255,255,255,0.1);
      border-radius: 12px;
      animation: slideUp 0.3s ease-out;
      backdrop-filter: blur(10px);
      position: relative;
    }
    
    /* 🎆 ANIMATIONS EFFETS */
    .chat-message-student {
      animation: slideInLeft 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
    }
    
    .chat-message-teacher {
      animation: slideInRight 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
    }
    
    .new-message-glow {
      animation: glowPulse 2s ease-in-out;
      box-shadow: 0 0 20px rgba(124,58,237,0.8);
    }
    
    @keyframes slideInLeft {
      from {
        opacity: 0;
        transform: translateX(-100px) scale(0.8);
      }
      to {
        opacity: 1;
        transform: translateX(0) scale(1);
      }
    }
    
    @keyframes slideInRight {
      from {
        opacity: 0;
        transform: translateX(100px) scale(0.8);
      }
      to {
        opacity: 1;
        transform: translateX(0) scale(1);
      }
    }
    
    @keyframes glowPulse {
      0%, 100% {
        box-shadow: 0 0 5px rgba(124,58,237,0.5);
      }
      50% {
        box-shadow: 0 0 25px rgba(124,58,237,1), 0 0 35px rgba(124,58,237,0.8);
      }
    }
    
    @keyframes bounceIn {
      0% {
        opacity: 0;
        transform: scale(0.3) translateY(-20px);
      }
      50% {
        opacity: 1;
        transform: scale(1.1);
      }
      70% {
        transform: scale(0.9);
      }
      100% {
        transform: scale(1);
      }
    }
    
    .typing-dots {
      display: inline-flex;
      gap: 4px;
      align-items: center;
    }
    
    .typing-dots span {
      display: inline-block;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background: #7c3aed;
      animation: typingBounce 1.4s infinite;
    }
    
    .typing-dots span:nth-child(2) {
      animation-delay: 0.2s;
    }
    
    .typing-dots span:nth-child(3) {
      animation-delay: 0.4s;
    }
    
    @keyframes typingBounce {
      0%, 60%, 100% {
        transform: translateY(0);
      }
      30% {
        transform: translateY(-6px);
      }
    }
    
    .reaction-bar button {
      transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
    }
    
    .reaction-bar button:active {
      animation: bounceIn 0.3s;
    }

    .chat-message.own {
      background: var(--chat-own-bg, rgba(124, 58, 237, 0.8));
      color: var(--chat-text-color, white);
      margin-left: auto;
      max-width: 70%;
    }

    .chat-avatar {
      font-size: 2em;
      min-width: 40px;
    }

    .chat-content {
      flex: 1;
    }

    .chat-author {
      font-weight: 700;
      margin-bottom: 5px;
      color: var(--chat-author-color, #ffd700);
    }

    .chat-message.own .chat-author {
      color: var(--chat-text-color, white);
    }

    .chat-text {
      word-wrap: break-word;
      font-family: var(--chat-font, 'Inter');
      font-size: var(--chat-font-size, 1em);
      color: var(--chat-text-color, white);
    }

    .chat-time {
      font-size: 0.8em;
      opacity: 0.7;
      margin-top: 5px;
    }

    .chat-input-container {
      padding: 20px;
      background: var(--bg-card-hover);
      display: flex;
      gap: 12px;
    }

    .chat-input {
      flex: 1;
      padding: 12px 20px;
      background: var(--bg-card);
      border: 2px solid var(--border);
      border-radius: 24px;
      color: var(--text-primary);
      font-size: 1em;
      outline: none;
      transition: var(--transition);
    }

    .chat-input:focus {
      border-color: var(--primary);
    }

    .chat-send-btn {
      padding: 12px 24px;
      background: var(--primary);
      color: white;
      border: none;
      border-radius: 24px;
      cursor: pointer;
      font-weight: 700;
      transition: var(--transition);
    }

    .chat-send-btn:hover {
      transform: scale(1.05);
    }

    .online-players {
      display: flex;
      gap: 12px;
      flex-wrap: wrap;
      margin-bottom: 20px;
    }

    .online-player {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 8px 16px;
      background: var(--bg-card-hover);
      border-radius: 20px;
      cursor: pointer;
      transition: var(--transition);
    }

    .online-player:hover {
      background: var(--primary);
      color: white;
      transform: translateY(-2px);
    }

    .online-indicator {
      width: 8px;
      height: 8px;
      background: var(--success);
      border-radius: 50%;
      /* calme visuel : pastille de présence fixe, ne clignote plus */
    }

    /* ========== CHALLENGES PAGE ========== */
    .challenge-card {
      background: var(--bg-card);
      border: 2px solid var(--border);
      border-radius: var(--border-radius);
      padding: 20px;
      transition: var(--transition);
      cursor: pointer;
    }

    .challenge-card:hover {
      border-color: var(--primary);
      transform: translateY(-3px);
      box-shadow: 0 10px 30px var(--shadow);
    }

    .challenge-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
    }

    .challenge-type {
      display: flex;
      align-items: center;
      gap: 10px;
      font-size: 1.2em;
      font-weight: 700;
    }

    .challenge-status {
      padding: 6px 12px;
      border-radius: 20px;
      font-size: 0.85em;
      font-weight: 700;
    }

    .challenge-status.pending {
      background: var(--warning);
      color: white;
    }

    .challenge-status.active {
      background: var(--success);
      color: white;
    }

    .challenge-status.completed {
      background: var(--info);
      color: white;
    }

    .challenge-players {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
      margin: 15px 0;
    }

    .challenge-player {
      padding: 6px 12px;
      background: var(--bg-card-hover);
      border-radius: 12px;
      font-size: 0.9em;
      font-weight: 600;
    }

    .challenge-bet {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-top: 15px;
      padding-top: 15px;
      border-top: 1px solid var(--border);
    }

    .challenge-actions {
      display: flex;
      gap: 10px;
      margin-top: 15px;
    }

    .btn-challenge {
      flex: 1;
      padding: 12px;
      border: none;
      border-radius: 12px;
      font-weight: 700;
      cursor: pointer;
      transition: var(--transition);
    }

    .btn-challenge.accept {
      background: var(--success);
      color: white;
    }

    .btn-challenge.decline {
      background: var(--danger);
      color: white;
    }

    .btn-challenge:hover {
      transform: translateY(-2px);
    }

    .create-challenge-btn {
      position: fixed;
      bottom: 30px;
      right: 30px;
      width: 60px;
      height: 60px;
      border-radius: 50%;
      background: var(--primary);
      color: white;
      font-size: 2em;
      border: none;
      cursor: pointer;
      box-shadow: 0 10px 30px var(--shadow);
      transition: var(--transition);
      z-index: 100;
    }

    .create-challenge-btn:hover {
      transform: scale(1.1) rotate(90deg);
    }

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

    @keyframes pulse {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.5; }
    }
	/* ========== CLASSEMENT (LEADERBOARD) ========== */
    .leaderboard-table {
        width: 100%;
        border-collapse: collapse;
        color: white;
    }
    .leaderboard-table th, .leaderboard-table td {
        padding: 12px 8px;
        text-align: left;
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }
    .leaderboard-table th {
        color: var(--warning);
        font-weight: 600;
        text-transform: uppercase;
        font-size: 0.85em;
    }
    /* Styles pour le podium */
    .leaderboard-table tr:nth-child(1) td {
        font-weight: bold;
        background-color: rgba(255, 215, 0, 0.1); /* Gold for 1st */
    }
    .leaderboard-table tr:nth-child(2) td {
        background-color: rgba(192, 192, 192, 0.1); /* Silver for 2nd */
    }
    .leaderboard-table tr:nth-child(3) td {
        background-color: rgba(205, 127, 50, 0.1); /* Bronze for 3rd */
    }
    .leaderboard-table .rank-1, .leaderboard-table .rank-2, .leaderboard-table .rank-3 {
        font-size: 1.2em;
        font-weight: 900;
    }
    .leaderboard-tabs {
        display: flex;
        gap: 10px;
        margin-bottom: 15px;
        overflow-x: auto;
        padding-bottom: 5px; /* Espace pour le scrollbar mobile */
    }
    .leaderboard-tabs .tab-btn {
        flex-shrink: 0;
        padding: 8px 15px;
        border: none;
        border-radius: 6px;
        background: rgba(255, 255, 255, 0.1);
        color: white;
        cursor: pointer;
        transition: all 0.2s;
    }
    .leaderboard-tabs .tab-btn.active {
        background: var(--primary);
        font-weight: bold;
    }
	/* === STYLE TETRIS NEON & JEUX === */
    .game-modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #050505; z-index: 9999; flex-direction: column; }
    .game-modal.active { display: flex; }
    .gm-header { padding: 15px; background: #111; border-bottom: 2px solid #333; display: flex; justify-content: space-between; align-items: center; }
    .gm-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; overflow: hidden; position: relative; }
    
    /* Le Canvas Tetris avec effet Neon */
    canvas.game-canvas {
        background: #000; 
        border: 2px solid #0ff; 
        box-shadow: 0 0 20px rgba(0, 255, 255, 0.2), inset 0 0 20px rgba(0, 255, 255, 0.1);
        border-radius: 4px;
        max-width: 95%; 
        max-height: 70vh;
    }

    /* Controles Mobiles */
    .mobile-controls { display: none; gap: 10px; margin-top: 20px; }
    .m-btn {
        width: 60px; height: 60px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.3);
        background: rgba(255,255,255,0.1); color: white; font-size: 24px; cursor: pointer;
        display: flex; align-items: center; justify-content: center; touch-action: manipulation;
    }
    .m-btn:active { background: var(--primary); border-color: white; transform: scale(0.95); }
    
    /* Affichage mobile uniquement */
    @media (hover: none) and (pointer: coarse) { .mobile-controls { display: flex; } }
    
    /* ========== 🆕 TABLEAUX EDITABLES ========== */
    .editable-table {
      width: 100%;
      border-collapse: collapse;
      margin: 1rem 0;
      background: white;
      border-radius: 8px;
      overflow: hidden;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }
    
    .editable-table th,
    .editable-table td {
      border: 1px solid #d1d5db;
      padding: 0.75rem;
      text-align: left;
    }
    
    .editable-table th {
      background: #e0f2fe;
      font-weight: bold;
      color: #1e293b;
      font-size: 0.95rem;
    }
    
    .editable-table input[type="text"],
    .editable-table input[type="number"] {
      width: 100%;
      padding: 0.5rem;
      border: 1px solid #cbd5e1;
      border-radius: 4px;
      font-size: 0.95rem;
      font-family: inherit;
      transition: all 0.2s;
    }
    
    .editable-table input:focus {
      outline: none;
      border-color: #667eea;
      box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
      background: #f8f9ff;
    }
    
    .auto-save-indicator {
      position: fixed;
      bottom: 20px;
      right: 20px;
      background: rgba(16, 185, 129, 0.95);
      color: white;
      padding: 0.75rem 1.5rem;
      border-radius: 8px;
      font-weight: 600;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
      z-index: 10001;
      opacity: 0;
      transition: opacity 0.3s;
      font-size: 0.95rem;
    }
    
    .auto-save-indicator.show {
      opacity: 1;
    }

/* ═══════════════════════════════════════════════════════════════════════
    STYLES ACADÉMIQUES POUR FICHES SYNTHÈSES (FORMAT BAC)
   ═══════════════════════════════════════════════════════════════════════ */

.formule-academique {
    background-color: #f8f9fa;
    border-left: 5px solid #2c3e50;
    padding: 15px 20px;
    margin: 15px 0;
    font-family: 'Times New Roman', serif;
    font-size: 1.1rem;
    box-shadow: 2px 2px 5px rgba(0,0,0,0.1);
}

.formule-academique h4 {
    margin: 0 0 10px 0;
    color: #2c3e50;
    font-size: 1rem;
    font-weight: bold;
}

.formule-academique p {
    margin: 8px 0;
    line-height: 1.6;
}

.formule-academique .variables {
    font-size: 0.9rem;
    font-style: italic;
    color: #666;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid #ddd;
}

.formule-academique ul {
    margin: 10px 0;
    padding-left: 20px;
}

.formule-academique li {
    margin: 5px 0;
}

/* Amélioration rendu MathJax */
.MathJax {
    font-size: 1.1em !important;
}

mjx-container {
    margin: 5px 0 !important;
}

/* ========================================= */
/* 🧮 SIMULATEURS ÉTUDIANTS - CARTES HUB */
/* ========================================= */

#simulateurs-hub > div > div {
  transition: all 0.3s ease;
}

#simulateurs-hub > div > div:hover {
  transform: translateY(-8px) scale(1.02);
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2) !important;
}

#simulateurs-hub > div > div:active {
  transform: translateY(-4px) scale(1.01);
}

/* ========== ANIMATIONS NOTIFICATIONS COMBAT ========== */
@keyframes slideInRight {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slideOutRight {
  from {
    transform: translateX(0);
    opacity: 1;
  }
  to {
    transform: translateX(100%);
    opacity: 0;
  }
}

@keyframes slideDown {
  from {
    transform: translate(-50%, -100%);
    opacity: 0;
  }
  to {
    transform: translateX(-50%);
    opacity: 1;
  }
}

@keyframes slideUp {
  from {
    transform: translateX(-50%);
    opacity: 1;
  }
  to {
    transform: translate(-50%, -100%);
    opacity: 0;
  }
}

@keyframes damageFlash {
  0% { opacity: 0; }
  50% { opacity: 1; }
  100% { opacity: 0; }
}

/* ═══════════════════════════════════════════════════════════════════
    RESPONSIVE MOBILE - Adaptation smartphone
   ═══════════════════════════════════════════════════════════════════ */
@media screen and (max-width: 768px) {
  /* Canvas plein écran — pour le monde 3D de MineProjet seulement.
     23/09/2026 : ce sélecteur nu « canvas » visait AUSSI les jeux d'arcade
     (#gameContainer > canvas) : sur téléphone, leur canvas passait en
     position fixe en haut à gauche, par-dessus l'en-tête et le bouton
     FERMER, ses commandes posées au milieu du jeu. Et les graphiques
     « Mes résultats » recouvraient tout l'écran. On les exclut. */
  canvas:not(#gameContainer > canvas):not(#evolutionChart):not(#competencesRadar):not(#pp-scene) {
    width: 100vw !important;
    height: 100vh !important;
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
  }
  
  /* Joystick plus grand sur petit écran */
  #missionJoystick {
    width: 130px !important;
    height: 130px !important;
  }
  
  #missionJoystickKnob {
    width: 60px !important;
    height: 60px !important;
  }
  
  /* Boutons plus gros */
  #jumpBtn, #actionBtn, #buildBtn {
    width: 70px !important;
    height: 70px !important;
    font-size: 28px !important;
  }
  
  /* Bouton aide plus gros */
  #helpBtn {
    width: 50px !important;
    height: 50px !important;
    font-size: 26px !important;
  }
  
  /* Tracker objectifs plus petit */
  #objectivesTracker {
    font-size: 10px !important;
    max-width: 140px !important;
  }
}

/* Très petits écrans (iPhone SE, etc) */
@media screen and (max-width: 375px) {
  #missionJoystick {
    width: 100px !important;
    height: 100px !important;
  }
  
  #jumpBtn, #actionBtn, #buildBtn {
    width: 55px !important;
    height: 55px !important;
    font-size: 22px !important;
  }
  
  #objectivesTracker {
    font-size: 9px !important;
    max-width: 120px !important;
  }
}

/* ========== LISIBILITE DE L'INTERFACE ELEVE ========== */
html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  line-height: 1.55;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

.header,
.app-layout,
.modal-content {
  letter-spacing: 0.005em;
}

.nav-item,
.stat-badge,
.btn-logout,
.content button,
.content input,
.content select,
.content textarea {
  font-size: 1rem;
  line-height: 1.4;
}

.user-level,
.badge-notif,
.content small,
.content .text-small,
.content .text-xs {
  font-size: 0.875rem !important;
  line-height: 1.45 !important;
}

.content p,
.content li,
.content label,
.content td,
.content th {
  line-height: 1.55;
}

.nav-item:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
a:focus-visible {
  outline: 3px solid #22d3ee !important;
  outline-offset: 3px !important;
}

@media (max-width: 768px) {
  .nav-item,
  .content button,
  .content input,
  .content select,
  .content textarea {
    font-size: 1rem !important;
  }
}

/* ========== BOUTIQUE MOBILE / GALAXY Z FOLD ========== */
/* Les fonds d'écran doivent être identifiables avant achat : la vignette est
   prioritaire, non déformée, et dispose d'un repli local si Storage tarde. */
#shopItems {
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  align-items: stretch;
}

#shopItems .item-image-wrap {
  aspect-ratio: 16 / 10;
  min-height: 150px;
  background: linear-gradient(110deg, var(--bg-card-hover), var(--bg-secondary), var(--bg-card-hover));
  background-size: 220% 100%;
}

#shopItems .item-image-wrap.is-loading {
  animation: shop-image-loading 3s linear infinite;
}

#shopItems .item-image-wrap img.item-image {
  object-position: center center;
}

#shopItems .item-image-status {
  position: absolute;
  left: 8px;
  bottom: 8px;
  z-index: 2;
  padding: 4px 8px;
  border-radius: 999px;
  background: rgba(3, 7, 18, .78);
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
  backdrop-filter: blur(6px);
}

@keyframes shop-image-loading {
  to { background-position: -220% 0; }
}

@media (pointer: coarse) {
  /* 02/10/2026 — le fond de l'élève est peint par body::before (couche fixe,
     --user-background) : c'est elle qui ne doit pas rester « attachée » sur
     écran tactile. Sur une couche déjà fixe, « scroll » ne la fait pas bouger
     et évite le coût de « fixed » dans les navigateurs mobiles. */
  body, body::before { background-attachment: scroll !important; }
  #shopItems .shop-item:hover { transform: none; }
  #shopItems .shop-item .btn { min-height: 48px; }
}

/* Écran extérieur étroit du Z Fold : une grande carte par ligne. */
@media (max-width: 420px) {
  #shopItems { grid-template-columns: minmax(0, 1fr) !important; gap: 14px; }
  #shopItems .item-image-wrap { min-height: 180px; }
  #shopItems .shop-item-body { padding: 13px 14px 15px; }
  #shopItems .item-name { font-size: 1.1rem; }
  #shopItems .item-description { min-height: 0; font-size: .95rem; }
  #shopItems .item-price { font-size: 1.25rem; }
}

/* Smartphones larges et petit écran intérieur en portrait. */
@media (min-width: 421px) and (max-width: 699px) {
  #shopItems { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 12px; }
  #shopItems .item-image-wrap { min-height: 120px; }
  #shopItems .shop-item-body { padding: 11px; }
  #shopItems .item-description { min-height: 0; }
}

/* Fold déplié et tablettes : trois aperçus confortables. */
@media (min-width: 700px) and (max-width: 1100px) {
  #shopItems { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; gap: 16px; }
  #shopItems .item-image-wrap { min-height: 135px; }
}

/* ========== BARRE MOBILE / TABLETTE — EN-TÊTE ET OUTILS ========== */
/*
   Ce bloc est volontairement placé en dernier. Une ancienne règle responsive
   plus haut dans le fichier repassait l’en-tête en colonne et transformait la
   barre d’outils en longue liste verticale. Sur un écran Fold, cela repoussait
   le contenu utile de plusieurs centaines de pixels. Les classes dédiées
   permettent de conserver la navigation existante tout en la rendant
   compacte, tactile et défilable horizontalement.
*/
@media screen and (max-width: 900px) {
  html {
    scroll-padding-top: 8px;
  }

  .student-mobile-header {
    position: sticky !important;
    top: 0 !important;
    left: auto !important;
    right: auto !important;
    width: 100% !important;
    padding: 8px 0 !important;
    z-index: 110 !important;
    background: rgba(15, 14, 23, .97) !important;
    box-shadow: 0 4px 18px rgba(0, 0, 0, .28);
  }

  /* Une rangée qui se replie toute seule : les indicateurs demandent
     300 points, le bloc élève environ 250. En dessous de 550 points de
     large ils passent sur deux lignes, au-dessus ils partagent la même —
     une tablette debout n'a aucune raison de payer deux lignes d'en-tête. */
  .student-mobile-header .header-content {
    width: 100%;
    max-width: none;
    padding: 0 10px !important;
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 7px 10px !important;
    text-align: left !important;
  }

  .student-mobile-header .header-center {
    order: 1;
    flex: 1 1 300px;
    width: auto !important;
    min-width: 0;
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    justify-content: flex-start !important;
    align-items: stretch;
    gap: 6px !important;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 1px 1px 3px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }

  .student-mobile-header .header-center::-webkit-scrollbar {
    display: none;
  }

  .student-mobile-header .stat-badge {
    flex: 0 0 auto;
    min-height: 40px;
    padding: 6px 9px !important;
    gap: 4px !important;
    border-width: 1px !important;
    border-radius: 9px !important;
    font-size: .76rem !important;
    line-height: 1.2 !important;
    white-space: nowrap;
  }

  .student-mobile-header .stat-icon {
    flex: 0 0 auto;
    font-size: 1rem !important;
  }

  .student-mobile-header .user-info {
    order: 2;
    flex: 0 1 auto;
    width: auto;
    min-width: 0;
    margin-left: auto;
    display: flex !important;
    justify-content: flex-end;
    align-items: center;
    gap: 8px !important;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
  }

  .student-mobile-header .user-info::-webkit-scrollbar {
    display: none;
  }

  .student-mobile-header .student-mood-control {
    flex: 0 0 auto;
    min-height: 44px;
    grid-template-columns: auto minmax(72px, auto);
    padding: 4px 5px 4px 8px;
    gap: 5px;
    border-radius: 11px;
  }

  .student-mobile-header .student-mood-control select {
    min-width: 80px;
    min-height: 34px;
    padding-left: 7px;
    font-size: .78rem;
  }

  .student-mobile-header .student-mood-label {
    font-size: .78rem;
  }

  .student-mobile-header .user-stats {
    display: none !important;
  }

  .student-mobile-header .user-avatar {
    flex: 0 0 auto;
    width: 44px !important;
    height: 44px !important;
    font-size: 1.45em !important;
    border-width: 2px !important;
  }

  .student-mobile-header #prm-hote-bandeau {
    flex: 0 0 auto;
    min-width: 44px;
    min-height: 44px;
    display: flex !important;
    align-items: center;
    justify-content: center;
  }

  .student-mobile-header #prm-hote-bandeau button,
  .student-mobile-header #prm-hote-bandeau [role="button"] {
    min-width: 44px !important;
    min-height: 44px !important;
  }

  .student-mobile-header .btn-logout {
    flex: 0 0 auto;
    min-height: 44px !important;
    padding: 9px 14px !important;
    font-size: .9rem !important;
    line-height: 1.2 !important;
    white-space: nowrap;
  }

  .app-layout {
    width: 100%;
    max-width: none;
    padding: 10px !important;
    gap: 10px !important;
    flex-direction: column !important;
    align-items: stretch;
  }

  /* ════════════════════════════════════════════════════════════════════
     LA BARRE D'OUTILS — UNE GRILLE, PLUS UN RUBAN QUI DÉFILE · 06/09/2026

     CE QUI N'ALLAIT PAS. La barre était une rangée horizontale que l'on
     faisait défiler (« flex-nowrap » + « overflow-x: auto »). Mesuré dans
     Chromium sur un téléphone DEBOUT (390 × 780) :

         largeur nécessaire  1257 points
         largeur disponible   366 points

     Deux destinations sur huit étaient visibles. Les six autres se
     trouvaient derrière un défilement latéral que rien n'annonce. Couché,
     820 points en montraient cinq — d'où le réflexe de tourner l'appareil.
     L'élève ne tournait pas son téléphone par confort : il le tournait
     parce que le menu était inatteignable autrement.

     Et « align-items: stretch » faisait le reste : quand un groupe
     s'ouvrait, son contenu grandissait la rangée, donc TOUS ses frères
     s'étiraient avec elle. Mesuré : 48 → 397 points. « Tableau de bord »
     et « Mon Profil » devenaient deux colonnes vides de 40 centimètres.

     CE QU'ON FAIT. La rangée devient une grille de puces qui s'ajuste
     seule : « repeat(auto-fit, minmax(78px, 1fr)) » donne quatre colonnes
     sur un téléphone debout, huit sur une tablette, une seule rangée dès
     que la place existe. Rien ne défile, rien n'est caché, et la même
     règle sert les trois formats — c'est la largeur disponible qui décide,
     pas une liste d'appareils à tenir à jour.

     Le panneau d'un groupe, lui, sort du flux : « position: absolute »
     sous la barre entière. Il ne peut donc plus déformer quoi que ce soit,
     et il s'ouvre sur toute la largeur au lieu d'une colonne de 80 points.
     C'est pour cela que « overflow » repasse à « visible » : un panneau
     absolu dans un conteneur qui défile serait rogné.
     ════════════════════════════════════════════════════════════════════ */
  .student-mobile-tools {
    width: 100% !important;
    max-width: 100%;
    min-height: 0;
    height: auto;
    position: relative !important;   /* ancre des panneaux déroulants */
    /* ⚠️ « .sidebar » de base est collante avec « top: 120px ». Passer en
       « relative » sans neutraliser « top » décale la barre de 120 points
       vers le bas et ouvre un trou noir entre l'en-tête et le menu — vu à
       la capture, invisible à la mesure de hauteur. */
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));
    /* Toutes les lignes à la hauteur de la plus haute : sans cela, une
       deuxième ligne aux libellés plus courts est visiblement plus basse
       que la première. */
    grid-auto-rows: 1fr;
    align-items: stretch;
    gap: 6px !important;
    padding: 8px !important;
    overflow: visible !important;    /* sinon le panneau serait rogné */
  }

  /* La puce : icône au-dessus, libellé dessous, centré. Une puce = une
     cellule de la grille, donc toutes ont la même taille sur une ligne. */
  .student-mobile-tools > .nav-item:not(.nav-group),
  .student-mobile-tools > .nav-group > .nav-group-head {
    position: relative;
    box-sizing: border-box;
    min-height: 52px;
    height: 100%;
    margin: 0 !important;
    padding: 6px 3px !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 2px !important;
    border-width: 1px !important;
    border-radius: 12px !important;
    font-size: .68rem !important;
    font-weight: 600;
    line-height: 1.15 !important;
    text-align: center;
    white-space: normal;
    /* « break-word » et non « anywhere » : un mot n'est coupé que s'il ne
       tient vraiment pas, sinon on obtenait « Récompens / es ». */
    overflow-wrap: break-word;
    hyphens: auto;
    transform: none !important;
  }

  .student-mobile-tools > .nav-item:hover,
  .student-mobile-tools > .nav-item:focus-visible,
  .student-mobile-tools > .nav-group > .nav-group-head:hover {
    transform: none !important;
  }

  /* Le groupe n'est qu'un porteur : c'est sa tête qui est la puce. Il doit
     occuper toute la cellule, sinon sa puce est plus courte que celles de
     ses voisines sur la même ligne — c'est ce que montrait la capture. */
  .student-mobile-tools > .nav-group {
    display: block;
    min-width: 0;
    align-self: stretch;
    height: 100%;
  }

  .student-mobile-tools > .nav-group > .nav-group-head {
    background: var(--bg-card-hover) !important;
    border: 1px solid transparent !important;
    cursor: pointer;
  }

  .student-mobile-tools > .nav-group > .nav-group-head[aria-expanded="true"] {
    background: var(--primary) !important;
    border-color: var(--primary) !important;
    color: #fff !important;
  }

  .student-mobile-tools .nav-icon {
    flex: 0 0 auto;
    font-size: 1.32em;
    line-height: 1;
  }

  /* Le chevron et la pastille de notification quittent le flux du texte :
     dans une puce en colonne, « margin-left: auto » les enverrait à la
     ligne. Coin supérieur droit pour l'un, supérieur gauche pour l'autre. */
  .student-mobile-tools > .nav-group > .nav-group-head .nav-chev {
    position: absolute;
    top: 3px;
    right: 5px;
    margin: 0 !important;
    font-size: 9px;
    opacity: .7;
  }

  .student-mobile-tools > .nav-item .badge-notif {
    position: absolute;
    top: 2px;
    right: 3px;
    margin: 0 !important;
    /* Ronde à un chiffre, allongée seulement quand le nombre l'exige :
       une hauteur et une largeur minimales égales, et un rayon complet. */
    min-width: 18px;
    height: 18px;
    padding: 0 5px !important;
    display: grid;
    place-items: center;
    border-radius: 999px !important;
    font-size: .62rem !important;
    line-height: 1;
  }

  .student-mobile-tools > .nav-item:not(.nav-group) {
    position: relative;
  }

  /* ── LE PANNEAU D'UN GROUPE ────────────────────────────────────────────
     Hors du flux, sur toute la largeur de la barre, au-dessus du contenu.
     Deux colonnes dès que la place existe : un groupe de six entrées tient
     alors en trois lignes au lieu de six. */
  .student-mobile-tools .nav-group-body {
    position: absolute;
    top: calc(100% - 2px);
    left: 6px;
    right: 6px;
    z-index: 320;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
    gap: 6px;
    margin: 0;
    padding: 8px !important;
    max-height: 56vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* ⚠️ « --bg-card » est TRANSLUCIDE dans les vingt thèmes (alpha 0,08 à
       0,95) : un panneau flottant peint avec lui laisse lire le titre de la
       page à travers. On pose donc le fond opaque de la page (« --bg-main »,
       présent et opaque dans tous les thèmes, clairs compris) sous la teinte
       de carte. Deux couches, aucun thème sacrifié. */
    background-color: #14131c;
    background-image: linear-gradient(var(--bg-card), var(--bg-card)), var(--bg-main);
    border: 1px solid var(--border, rgba(255, 255, 255, .16));
    border-radius: 14px;
    box-shadow: 0 20px 44px rgba(0, 0, 0, .55);
  }

  .student-mobile-tools .nav-group-body[hidden] {
    display: none !important;
  }

  .student-mobile-tools .nav-group-body .nav-item {
    min-height: 46px;
    margin: 0 !important;
    padding: 10px 12px !important;
    gap: 9px !important;
    border-width: 1px !important;
    border-radius: 11px !important;
    font-size: .88rem !important;
    line-height: 1.2 !important;
    opacity: 1;
    transform: none !important;
  }

  .student-mobile-tools .nav-group-body .nav-item:hover {
    transform: none !important;
  }

  .student-mobile-tools .nav-group-body .nav-icon {
    font-size: 1.15em;
  }

  /* L'échappatoire « Tout afficher (n) » n'est pas une destination : elle
     prend la ligne entière plutôt qu'une cellule de 78 points. */
  .student-mobile-tools > .nav-tout {
    grid-column: 1 / -1;
    margin: 2px 0 0 !important;
  }

  .student-mobile-tools .nav-group-body .badge-notif {
    position: static;
    margin-left: auto !important;
  }

  .content {
    width: 100%;
    min-width: 0;
  }

  /* ══════════════════════════════════════════════════════════════════════
     LES RONDS RESTENT RONDS — 06/09/2026

     Signalé sur téléphone et tablette : « des bulles déformées, des ovales
     plutôt que des cercles ».

     La cause est toujours la même, et elle est invisible sur un grand écran.
     Ces éléments sont carrés (width = height) avec « border-radius: 50% » —
     donc ronds — mais ils vivent dans des rangées flex, et un élément flex
     est RÉTRÉCISSABLE par défaut (flex-shrink vaut 1). Dès que la ligne
     manque de place, le navigateur reprend la largeur sur eux, jamais la
     hauteur : le cercle s'écrase en ovale. Sur un écran large la place ne
     manque pas, alors le défaut ne se voit jamais en développement.

     « flex-shrink: 0 » est la réponse exacte : un élément dont la taille est
     fixée n'a aucune raison d'être rétréci. « aspect-ratio: 1 » double la
     garantie là où la hauteur, elle aussi, pourrait être discutée.

     Liste explicite plutôt que sélecteur large : on ne fige que ce qui est
     censé être rond, et rien d'autre.
     ══════════════════════════════════════════════════════════════════════ */
  .user-avatar,
  .rank-badge,
  .modal-close-btn,
  .online-indicator,
  .create-challenge-btn,
  .spinner,
  .typing-dots span,
  .badge-icon,
  .stat-icon,
  .nav-icon {
    flex: 0 0 auto;
  }

  .user-avatar,
  .rank-badge,
  .modal-close-btn,
  .online-indicator,
  .create-challenge-btn,
  .spinner {
    aspect-ratio: 1;
  }
}

@media screen and (max-width: 375px) {
  .student-mobile-header .header-content {
    padding-inline: 7px !important;
  }

  .student-mobile-header .stat-badge {
    padding-inline: 7px !important;
    font-size: .7rem !important;
  }

  .student-mobile-header .btn-logout {
    padding-inline: 11px !important;
    font-size: .84rem !important;
  }

  .student-mobile-header .student-mood-label {
    font-size: 0;
    gap: 0;
  }

  .student-mobile-header .student-mood-label > span {
    font-size: 1.15rem;
  }

  .student-mobile-header .student-mood-control {
    grid-template-columns: auto 76px;
  }

  .app-layout {
    padding: 7px !important;
  }

  /* 66 points : sur un écran de 320 (iPhone SE), c'est la borne qui donne
     encore QUATRE colonnes — donc deux lignes et non trois. Mesuré : la
     barre passe de 202 à ~140 points sur un écran qui n'en compte que 568. */
  .student-mobile-tools {
    grid-template-columns: repeat(auto-fit, minmax(66px, 1fr));
    padding: 6px !important;
    gap: 5px !important;
  }

  .student-mobile-tools > .nav-item:not(.nav-group),
  .student-mobile-tools > .nav-group > .nav-group-head {
    padding-inline: 3px !important;
    font-size: .68rem !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   ORIENTATION — TÉLÉPHONE ET TABLETTE COUCHÉS · 05/09/2026

   CE QUI MANQUAIT : ce fichier compte seize requêtes média, toutes fondées
   sur la LARGEUR. Aucune ne parlait d'orientation. Or c'est la hauteur qui
   manque quand on couche un appareil, pas la largeur.

   Un téléphone couché mesure environ 844 × 390. Il passe donc sous les
   règles « max-width: 900px » — l'en-tête compact et la barre d'outils
   tactile s'appliquent bien, et c'est heureux. Mais leurs hauteurs ont été
   choisies pour un écran DEBOUT :

       en-tête collant   ~54 points
       barre d'outils     58 points  (min-height)
       ────────────────────────────
       112 points sur 390, soit 29 % de l'écran occupés avant le premier mot.

   Debout, ces 112 points valent 13 % — c'est raisonnable. Couché, non.

   Ce bloc ne touche donc QUE la hauteur, et seulement en paysage sur écran
   tactile. Rien n'est déplacé, rien n'est masqué : ce qui existe maigrit.
   Placé en fin de fichier pour la même raison que le bloc précédent —
   l'ordre de cascade est ici la seule chose qui garantisse qu'il s'applique.

   Le « pointer: coarse » est essentiel : sans lui, une fenêtre de navigateur
   réduite en hauteur sur un ordinateur recevrait ce traitement, alors qu'elle
   n'en a aucun besoin et que l'élève y travaille à la souris.
   ══════════════════════════════════════════════════════════════════════════ */
/* 20/09/2026 — LE MENU ÉLÈVE EST ATTEIGNABLE AU CLAVIER.
   Les 21 entrées étaient des <div class="nav-item"> : aucun role, aucun
   tabindex, câblées par un seul addEventListener('click') dans
   apps/student/core/platform/learning.js. Un élève sans souris — motricité
   réduite, lecteur d'écran, ou simplement une souris morte en salle info —
   n'atteignait ni Mes TP, ni Mes Résultats, ni la Boutique : sa séance
   s'arrêtait sur l'écran d'accueil. Seule « Matières » avait été corrigée.

   Elles sont désormais des <button type="button" class="nav-item">. Le
   listener les retrouve par la classe, le glisser-déposer par la classe
   aussi (navigation-dnd.js pose draggable lui-même), et `.nav-item:focus-
   visible` — déjà écrit plus haut, jamais visible faute d'élément focusable
   — dessine enfin son anneau.

   Ce bloc neutralise le style natif du bouton. Il est écrit en :where()
   pour avoir une spécificité NULLE : toute règle .nav-item existante, et
   tout thème parmi les 24, continue de gagner. Ne sont donc posées ici que
   les propriétés que .nav-item ne fixait pas, et que le <div> tenait de son
   statut d'élément de bloc. */
:where(button.nav-item) {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  margin-left: 0;
  margin-right: 0;
  font-family: inherit;
  text-align: left;
}

/* 20/09/2026 — LE BANDEAU DE SAUVEGARDE DU PLAN DE TRAVAIL, SORTI DE LA PAGE.
   Ses 367 octets de style « inline » vivaient dans student_dashboard.html, qui
   pesait 149 167 octets pour un plafond de 150 000 : la marge de 1 000 octets
   exigee par test-parcours-python.js etait tombee a 833. C'est exactement la
   lecon du 14/09/2026, quand la carte du parcours Python avait fait passer
   cette page de 146 886 a 151 616 octets en portant ses styles dans le HTML,
   et arrete le deploiement au portique.

   Le `box-shadow` y figurait DEUX FOIS — 0 2px 4px puis 0 4px 12px. Seule la
   seconde s'appliquait ; la premiere etait du code mort depuis le debut. Elle
   n'est pas reprise ici.

   workspace.js ne pose que `style.transform` et la couleur de fond : un style
   « inline » pose par le script l'emporte toujours sur cette regle. */
#wsSaveToast {
  position: fixed;
  top: 80px;
  right: 20px;
  background: #10b981;
  color: white;
  font-weight: 700;
  border: 2px solid #059669;
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
  padding: 12px 20px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  transform: translateX(400px);
  transition: transform 0.3s ease;
  z-index: 10001;
}

@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {

  /* ── L'en-tête : une seule ligne, et il cesse d'être collant ────────────
     Un en-tête collant de 54 points sur 390 reste à l'écran pendant qu'on
     lit : il coûte sa hauteur en permanence. Couché, on préfère le laisser
     défiler et récupérer la place. */
  .student-mobile-header {
    position: static !important;
    padding: 4px 0 !important;
  }
  .student-mobile-header h1,
  .student-mobile-header .header-title { font-size: 1rem !important; }

  /* Couché, la largeur ne manque pas : les indicateurs et le bloc élève
     tiennent sur UNE ligne. Empilés, ils coûtaient 105 points sur 390 —
     plus du quart de l'écran avant le premier mot de contenu. */
  .student-mobile-header .header-content {
    flex-direction: row !important;
    align-items: center !important;
    gap: 10px !important;
  }
  .student-mobile-header .header-center {
    flex: 1 1 auto;
    min-width: 0;
  }
  .student-mobile-header .user-info {
    flex: 0 0 auto;
    width: auto;
  }
  /* Le sous-titre répète ce que l'élève sait déjà : sa classe. */
  .student-mobile-header .header-subtitle,
  .student-mobile-header p { display: none !important; }

  /* ── La barre d'outils : 58 → 44 points ────────────────────────────────
     Elle reste défilable horizontalement, et la place horizontale ne manque
     pas en paysage : les libellés restent lisibles. */
  /* Couché, la place horizontale ne manque pas : les huit puces tiennent sur
     une seule ligne. C'est la HAUTEUR qu'on récupère — la puce repasse donc
     en ligne (icône puis libellé) au lieu de la colonne du portrait. */
  .student-mobile-tools {
    padding-block: 4px !important;
  }
  .student-mobile-tools > .nav-item:not(.nav-group),
  .student-mobile-tools > .nav-group > .nav-group-head {
    /* 44 px : le plancher tactile, même couché. 42 aurait suffi à l'œil et
       manqué au doigt. */
    min-height: 44px !important;
    flex-direction: row !important;
    gap: 6px !important;
    padding-block: 5px !important;
    font-size: .74rem !important;
  }
  .student-mobile-tools .nav-icon {
    font-size: 1.1em;
  }
  .student-mobile-tools > .nav-group > .nav-group-head .nav-chev {
    top: 2px;
    right: 3px;
  }
  .student-mobile-tools .nav-group-body {
    max-height: 62vh;
  }

  /* ── Les indicateurs (étincelles, niveau, série) ───────────────────────
     Ils restent sur une ligne défilable — c'est déjà la règle — mais leur
     hauteur descend d'un cran. */
  .student-mobile-header .stats-row,
  .student-mobile-header .indicateurs { padding-block: 2px !important; }

  /* ── Le contenu récupère la place ──────────────────────────────────────
     La zone utile passe d'environ 278 à 330 points : un cinquième de plus,
     sans rien supprimer. */
  .main-content, .content-area { padding-top: 8px !important; }

  /* ── Les fenêtres modales ne doivent pas dépasser l'écran ──────────────
     C'est le défaut classique du paysage : une boîte de dialogue calculée
     pour un écran debout sort par le haut et par le bas, et son bouton de
     validation devient inatteignable. */
  .modal-content, .modal-box, dialog {
    max-height: 92vh !important;
    overflow-y: auto !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   PLIABLE DÉPLIÉ — 691 à 839 points, presque carré

   La bande est déjà couverte pour l'en-tête et les outils par le bloc
   « max-width: 900px » ci-dessus. Ce qui manquait : les grilles de contenu,
   qui restaient à une colonne parce que la dernière règle de largeur
   au-dessous d'elles s'arrête à 699. Sur un écran presque carré, une seule
   colonne laisse la moitié de la surface vide.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 700px) and (max-width: 839px) {
  .student-grid, .cards-grid, .courses-grid, .tp-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   LA CHARNIÈRE — même règle que côté professeur.
   Aucun appareil non pliable ne lit ce bloc : il ne coûte rien aux autres.
   ══════════════════════════════════════════════════════════════════════════ */
@media (horizontal-viewport-segments: 2) {
  .student-grid, .cards-grid, .courses-grid, .tp-grid {
    grid-template-columns:
      calc(env(viewport-segment-width 0 0) - 24px)
      calc(env(viewport-segment-width 1 0) - 24px) !important;
    column-gap: calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0)) !important;
  }
}

/* 10/09/2026 — bloc .agenda-du-jour-* retiré : la carte « 📅 Agenda du jour »
   (apps/student/agenda/agenda-du-jour.js) a été fusionnée dans le panneau
   « Ce que j'ai à faire » (apps/student/today/index.js, classes
   .student-today__session), voir today.css. Ces règles n'étaient plus
   utilisées par aucune page. */





/* Styles sortis de student_dashboard.html (plafond de taille de la page, 24/09/2026). */
.sd-lbl { display: block; font-size: 13px; font-weight: 600; margin-bottom: 4px; }
.sd-ligne { display: flex; justify-content: space-between; padding: 10px; background: var(--bg-card-hover); border-radius: 8px; }

/* Refuge : toute la fenêtre disponible, sans plafond 760 px ni centrage arcade. */
#gameModal:is([data-game="catient"],[data-game="ile2050"]) { padding:0!important; inset:0!important; width:100vw!important; height:100dvh!important; }
#gameModal:is([data-game="catient"],[data-game="ile2050"]) .modal-content { padding:0!important; height:100dvh!important; max-height:100dvh!important; }
#gameModal:is([data-game="catient"],[data-game="ile2050"]) #gameContainer { padding:0!important; height:auto!important; min-height:0!important; flex:1 1 0!important; display:flex!important; flex-direction:column!important; flex-wrap:nowrap!important; align-items:stretch!important; overflow:hidden!important; }
#gameModal:is([data-game="catient"],[data-game="ile2050"]) #gameContainer > iframe { width:100%!important; height:100%!important; max-width:none!important; max-height:none!important; margin:0!important; flex:1 1 0!important; border-radius:0!important; }
#launchCaTient { display:block; width:100%; min-width:0; font:inherit; color:inherit; appearance:none; transform:none!important; border-radius:0!important; isolation:isolate; }
#launchCaTient > span { display:block; pointer-events:none; }
#launchCaTient:focus-visible { outline:3px solid #c6f578; outline-offset:3px; }

#gameModal:is([data-game="catient"],[data-game="ile2050"]) .modal-content { transform:none!important; animation:none!important; transition:none!important; border:0!important; box-shadow:none!important; }

#launchCaTient { transition:none!important; }

/* Mission Île 2050 : carte entière activable, sans déplacement au survol. */
#launchIle2050 {display:block;width:100%;padding:24px;text-align:left;border:2px solid #a3c67e66;border-radius:0!important;background:linear-gradient(140deg,#163741,#172921);color:#e5edda;font:inherit;appearance:none;position:relative;cursor:pointer;transform:none!important;transition:none!important;}
#launchIle2050 > span {display:block;pointer-events:none;}
#launchIle2050 .island-badge{font-size:10px;letter-spacing:1.4px;color:#d4ed91;}
#launchIle2050 .island-card-art svg{width:100%;height:130px;}
#launchIle2050 .island-card-title{font-size:23px;font-weight:850;letter-spacing:-.5px;}
#launchIle2050 .island-card-description{margin-top:12px;color:#b7cbc0;font-size:13px;}
#launchIle2050:focus-visible{outline:3px solid #d4ed91;outline-offset:4px;}

/* Arcade (02/10/2026) : les sept jeux en iframe (games/arcade/…) occupent toute la
   zone sous l'en-tête commun (titre + FERMER restent visibles). Le défilement
   éventuel est géré DANS le jeu, jamais par le conteneur. */
#gameModal:is([data-game="motdujour"],[data-game="fusion"],[data-game="paires"],[data-game="familles"],[data-game="gonogo"],[data-game="simon"],[data-game="dodu"]) #gameContainer { padding:0!important; display:flex!important; flex-direction:column!important; justify-content:flex-start!important; align-items:stretch!important; overflow:hidden!important; }
#gameModal:is([data-game="motdujour"],[data-game="fusion"],[data-game="paires"],[data-game="familles"],[data-game="gonogo"],[data-game="simon"],[data-game="dodu"]) #gameContainer > iframe { flex:1 1 0!important; width:100%!important; height:100%!important; min-height:0!important; max-width:none!important; max-height:none!important; margin:0!important; border-radius:0!important; }

    /* Cartes des jeux d'arcade cognitifs : une classe, une couleur (--c). */
    .jeu-arcade{cursor:pointer;text-align:center;padding:30px;background:linear-gradient(135deg,color-mix(in srgb,var(--c) 20%,transparent),rgba(15,14,23,.05));border:3px solid color-mix(in srgb,var(--c) 50%,transparent);transition:all .3s;position:relative;border-radius:15px;box-shadow:0 0 20px color-mix(in srgb,var(--c) 30%,transparent)}
    .jeu-arcade .ja-badge{position:absolute;top:12px;right:12px;background:var(--c);color:#04210f;padding:6px 12px;border-radius:20px;font-size:.75em;font-weight:800}
    .jeu-arcade .ja-ico{font-size:5em;margin-bottom:15px;filter:drop-shadow(0 0 12px var(--c))}
    .jeu-arcade h3{color:var(--c);margin:12px 0;font-size:1.4em;font-weight:800}
    .jeu-arcade p{color:#b9bdd8;font-size:.95em}

/* Calme visuel — respect du réglage système « réduire les animations » :
   aucune animation ni transition ne se répète, et les animations infinies
   sont suspendues quand l'onglet est masqué (cf. calme-visuel.js). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ========== ÉCRANS TACTILES : PAS DE FLOU D'ARRIÈRE-PLAN SUR L'EN-TÊTE ET LES FENÊTRES ==========
   03/10/2026 — « Sur tablette, le fonctionnement est lent. » Un backdrop-filter oblige le
   processeur graphique à recalculer le flou de TOUT ce qui défile derrière, à chaque image :
   l'en-tête (blur 20 px, collant, pleine largeur) le payait en permanence, et chaque fenêtre
   modale en plein écran à l'ouverture. Or l'en-tête est déjà opaque à 90-97 % (le flou ne se
   voit pas) et les fenêtres reposent sur un voile sombre. Seuls les écrans sans survol ni
   pointeur fin (tablettes, téléphones) perdent ce flou ; sur ordinateur, rien ne change. */
@media (hover: none), (pointer: coarse) {
  .header,
  .student-mobile-header,
  .student-mood-control,
  .modal-overlay {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}
