/* =========================================================
   THÈME DE PAGE — VIOLET-ORCHIDÉE "CORRECTION"
   =========================================================
   Même mécanisme que le rose des imports, l'orange des Devoirs ou le vert du
   planning : on redéfinit --accent* sur les conteneurs, tout ce qui le
   consomme suit sans une règle de plus. Le n-uplet Σ / onglet nav / fil
   d'Ariane passe lui par --page-accent, déclaré une seule fois dans nav.css.
   La page Élèves est incluse : elle vit sous Correction dans le fil d'Ariane.
   ========================================================= */
body.correction-ctx-active .doc-page,
body.correction-ctx-active .ctx-bar {
    --accent:        var(--kind-correction);
    --accent-strong: color-mix(in srgb, var(--kind-correction) 82%, black);
    --accent-soft:   color-mix(in srgb, var(--kind-correction) 14%, transparent);
    --accent-dim:    color-mix(in srgb, var(--kind-correction) 8%, transparent);
    --shadow-glow:   0 4px 20px color-mix(in srgb, var(--kind-correction) 22%, transparent);
}

/* Pages Correction DS/DM (ds_correction/*.html, students/index.html) —
   socle _leftmenu_base + context bar manuelle dans doc_topbar, même
   patron que sheets/cours_et_td.html (cf. .courstd-ctx-bar) : ce fichier
   ne redéfinit QUE ce qui est propre à ces pages, les boutons/badges/
   stats réutilisent .button*/.sh-kind/.doc-stat-chip génériques. */

.cor-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

/* Titres de carte ("Élève", "Questions", "Notation", "Statistiques de la
   classe", "Notes de la classe") : .filters-title est gris discret par
   défaut (pensé pour un simple en-tête de filtre) mais sur cette page
   dense, en pleine correction, ça les rend trop effacés — blanc, pas
   seulement --text, pour qu'ils tranchent nettement sur le fond sombre.
   Scopé à cette page (pas de règle globale sur .filters-title, qui sert
   ailleurs pour des en-têtes volontairement discrets). */
.doc-sidebar-card .filters-title,
.cor-questions-head .filters-title,
.cor-class-section .filters-title {
    color: #fff;
}

/* Sidebar plus large que le défaut du site (248px) : le formulaire
   "Ajouter un élève" (gauche) et le détail élève (droite) sont plus à
   l'aise sur cette page. La même règle vise LES DEUX panneaux — gauche
   ET .student-detail-sidebar (plus bas) — puisqu'ils partagent tous deux
   la classe .doc-page-sidebar : c'est ce qui les garde symétriques. */
body.correction-ctx-active .doc-page-sidebar {
    flex: 0 0 320px;
}

.cor-card {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 14px;
    border-radius: var(--radius);
    background: var(--surface);
    border: 1px solid var(--border-soft);
    padding: 14px 18px;
    transition: border-color 0.15s;
}

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

.cor-card-info {
    grid-column: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    justify-self: start;
}

.cor-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
}

.cor-card-title {
    font-family: var(--font-head);
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text);
}

.cor-card-actions {
    grid-column: 3;
    flex-shrink: 0;
    display: flex;
    gap: 8px;
    justify-self: end;
}

.cor-card-meta {
    display: flex;
    align-items: center;
    gap: 14px;
    font-size: 0.82rem;
    color: var(--text-faint);
}

.cor-card-not-assigned {
    font-style: italic;
}

.cor-progress {
    grid-column: 2;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    justify-self: center;
}

.cor-progress-label {
    font-size: 0.95rem;
    color: var(--text-faint);
    white-space: nowrap;
}

.cor-progress-count {
    font-weight: 600;
}

.cor-progress-bar {
    width: 100px;
    height: 6px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
    flex-shrink: 0;
}

.cor-progress-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--accent);
}

.cor-progress-fill-low {
    background: #e5484d;
}

.cor-progress-fill-mid {
    background: #f5a524;
}

.cor-progress-count-low {
    color: #e5484d;
}

.cor-progress-count-mid {
    color: #f5a524;
}

.cor-progress-done {
    grid-column: 2;
    justify-self: center;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border-radius: 999px;
    background: color-mix(in srgb, #46a758 16%, transparent);
    border: 1px solid color-mix(in srgb, #46a758 45%, transparent);
    color: var(--text);
    font-weight: 600;
    font-size: 0.95rem;
    white-space: nowrap;
}

.cor-progress-done-icon {
    width: 18px;
    height: 18px;
    color: #46a758;
    flex-shrink: 0;
}


/* Titre du DS/DM dans le fil d'Ariane : plus de badge icône à gauche,
   la couleur du texte lui-même porte l'info DM (orange) / DS (rouge) —
   mêmes tokens que .sh-kind-dm/.sh-kind-ds (sheet_card.css,
   context_bar.css) pour rester cohérent avec le reste du site. */
/* Spécificité alignée sur `.ctx-breadcrumb:has(.ctx-breadcrumb-link-accent)
   .ctx-breadcrumb-current { color: #fff }` (context_bar.css) qui, sinon,
   l'emporte et repasse le titre en blanc : même préfixe de sélecteur, plus
   la classe de kind en plus. */
.ctx-breadcrumb:has(.ctx-breadcrumb-link-accent) .ctx-breadcrumb-current.ctx-breadcrumb-kind-dm { color: var(--content-exercise); }
.ctx-breadcrumb:has(.ctx-breadcrumb-link-accent) .ctx-breadcrumb-current.ctx-breadcrumb-kind-ds { color: var(--danger); }

/* Police à chasse fixe : le nom (padé à largeur constante côté template)
   et le prénom démarrent alors chacun à une position fixe, colonnes
   alignées entre toutes les options. */
#student-select { font-family: var(--font-mono, monospace); }

/* ---------- Formulaires (assigner / élèves) ----------
   .inline-form (form.css) est un habillage de MODALE (bordure bleue en
   dur, fond #2a2a2a hors tokens) — pas adapté à un formulaire de page
   normale. Grille label/champ propre, sur tokens, dans le même esprit
   que .devoirs-filter-group (devoirs.css) pour select/input. */

.cor-form {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: var(--space-3);
    align-items: center;
    max-width: 480px;
    background: var(--surface);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    padding: var(--space-4);
}

.cor-form label {
    font-size: 0.78rem;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.cor-form input {
    width: 100%;
    box-sizing: border-box;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    padding: 7px 10px;
    font-size: 0.88rem;
}

.cor-form input:focus {
    outline: none;
    border-color: var(--accent);
}

.cor-form-hint {
    grid-column: 1 / -1;
    font-size: 0.8rem;
    color: var(--text-faint);
    margin: 4px 0 0;
}

.cor-form-actions {
    grid-column: 1 / -1;
    display: flex;
    justify-content: flex-end;
}


/* ---------- Table élèves ---------- */

.student-table {
    width: 100%;
    /* fixed : sans ça, `width` sur les colonnes μ n'est qu'une suggestion
       — le layout auto les redimensionne quand même selon leur contenu
       ("13.11" vs "—"), d'où des largeurs qui ne matchaient jamais. */
    table-layout: fixed;
    border-collapse: collapse;
    margin-top: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    overflow: hidden;
}

.student-table-col-rank { width: 40px; }
.student-table-col-name { width: 130px; }
.student-table-col-mu { width: 60px; }
.student-table-col-genre { width: 56px; }
.student-table-col-tel { width: 110px; }

/* Colonne Mail : seule sans largeur fixe, elle prend tout ce qui reste
   (Nom/Prénom/Genre/Tel/DS/Colles/Moy. sont, elles, dimensionnées) — mais
   les adresses longues doivent tout de même être tronquées, sinon elles
   débordent visuellement sur la colonne Tel voisine (table-layout: fixed
   ne les contraint pas tout seul). */
.student-table td:nth-child(5) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 0;
}

/* Table plus large que le plafond par défaut du site (1180px, doc.css) :
   ce tableau a besoin de toute la place possible pour Nom/Prénom/Mail/DS/
   Colles/Moy. sans se tasser. */
main:has(.student-table),
main:has(.colle-groups-view) {
    max-width: none;
}

.student-table th {
    text-align: left;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-faint);
    font-weight: 600;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-soft);
}

/* text-transform:uppercase ci-dessus mettrait "μ" en majuscule grecque
   (Μ), visuellement un simple "M" — imperceptible de "Moyenne" sans ce
   contournement. Sélecteur composé (pas juste .student-table-th-mu) pour
   gagner en spécificité sur .student-table th sans !important. */
.student-table th.student-table-th-mu {
    text-transform: none;
}

.student-table-th-mu,
.student-table td.student-table-td-mu {
    text-align: center;
    white-space: nowrap;
}

.student-table-th-mu .student-table-sort {
    justify-content: center;
}

.student-table-th-rank {
    width: 1%;
    color: var(--text-faint);
    text-align: right;
}

/* Zone cliquable = toute la cellule d'en-tête (pas juste le texte) : le
   lien reprend le padding du th, qui lui passe à 0. Le survol change le
   fond de la cellule, pas seulement la couleur du texte. */
.student-table th.student-table-th-sortable {
    padding: 0;
}

.student-table-sort {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 10px 14px;
    box-sizing: border-box;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

.student-table-sort:hover {
    background: var(--surface-2);
    color: var(--text);
}

.student-table-sort.is-active {
    color: var(--accent);
}

.student-table-sort-arrow {
    font-size: 0.6rem;
}

/* visibility (pas display:none) : la flèche garde sa place réservée même
   masquée, pour que les colonnes ne changent pas de largeur au clic. */
.student-table-sort-arrow-hidden {
    visibility: hidden;
}

.student-table td {
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-soft);
    color: var(--text-muted);
    font-size: 0.92rem;
}

.student-table tr:last-child td {
    border-bottom: none;
}

.student-table tr:hover td {
    background: var(--surface-2);
}

/* Un seul bouton qui bascule Garçon/Fille au clic (pas deux boutons côte à
   côte) : data-genre posé côté serveur (student.genre vide → "m"/Garçon par
   défaut) pour éviter un flash au chargement, cf. le template. Les deux
   icônes sont toujours dans le DOM, seule celle qui correspond à
   data-genre est affichée (cf. règles [data-genre=...] .icon-* ci-dessous). */
.student-genre-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    min-width: 0;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: none;
    cursor: pointer;
}

.student-genre-toggle svg {
    width: 20px;
    height: 20px;
}

.student-genre-toggle .icon-f {
    display: none;
}

.student-genre-toggle[data-genre="f"] .icon-m {
    display: none;
}

.student-genre-toggle[data-genre="f"] .icon-f {
    display: block;
}

.student-genre-toggle:hover {
    background: var(--surface-2);
    border-color: var(--border-soft);
}

.student-genre-toggle[data-genre="m"] {
    color: #1c7ed6;
}

.student-genre-toggle[data-genre="f"] {
    color: #d6336c;
}

/* ---------- Formulaire "Ajouter un élève" (sidebar gauche) ----------
   Empilé (label au-dessus du champ) plutôt que la grille 140px/1fr de
   .cor-form : la colonne fait 248px (.doc-page-sidebar), trop étroite
   pour un label à côté d'un champ. */
.student-form {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.student-form label {
    font-size: 0.78rem;
    color: var(--text-faint);
    margin-top: 6px;
}

/* Ligne Genre : label + bouton toggle sur la même ligne (pas de retour à la
   ligne comme les autres champs empilés), cf. demande 2026-08-22. */
.student-form-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 6px;
}

.student-form-row label {
    margin-top: 0;
}

.student-form input {
    width: 100%;
    box-sizing: border-box;
    padding: 7px 10px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-size: 0.88rem;
}

.student-form input:focus {
    outline: none;
    border-color: var(--accent);
}

.student-form-submit {
    margin-top: 12px;
    width: 100%;
}


/* =========================================================
   PAGE DE CORRECTION (correct.html) : un seul panneau PDF (viewer maison,
   cf. core/pdf_canvas_viewer.js) basculant entre l'énoncé et le corrigé,
   deux compilations distinctes du même devoir (cf. cours_fs.PDF_VARIANT_*).
   Colonne de gauche : élève, sommaire « Questions », puis le panneau de
   notation de la question sélectionnée (toujours ouvert, pas de modale).
   ========================================================= */

/* Pleine largeur : le PDF n'a aucune raison d'être bridé à 1180px
   (`main:has(.doc-page-scroll)`, doc.css) alors qu'on lit dessus. */
main:has(.cor-pdf-panel) {
    max-width: none;
}

/* Bascule Énoncé / Corrigé, au centre de la context bar. */
.cor-variant-switch {
    display: flex;
    gap: 2px;
    padding: 2px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.cor-variant-btn {
    padding: 3px 14px;
    border: none;
    border-radius: calc(var(--radius-sm) - 1px);
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.cor-variant-btn:hover { color: var(--text); }

/* Le même bouton sert aussi de lien (bascule Classe/Correction, deux pages
   distinctes plutôt qu'un JS toggle) — annule les styles par défaut de <a>. */
a.cor-variant-btn {
    display: inline-block;
    text-decoration: none;
}

.cor-variant-btn.is-active {
    background: var(--accent);
    color: var(--on-accent);
}

/* Panneau plein écran (pas de scroll de la page elle-même) : le viewer
   commun (core/pdf_canvas_viewer.js, même comportement scrollable multi-
   pages que partout ailleurs sur le site) gère lui-même son scroll interne
   via .pdfcv-pages — seule la HAUTEUR du panneau est propre à cette page. */
/* scrollbar-gutter:stable (nav.css, global) réserve 10px à droite pour
   compenser l'apparition d'une scrollbar — ici #app-body ne scrolle
   jamais, donc ces 10px ne servent à rien et cassent la symétrie avec la
   marge gauche (colonne Questions). */
body:has(.cor-pdf-panel) #app-body { overflow: hidden; scrollbar-gutter: auto; }

body:has(.cor-pdf-panel) .doc-page-main {
    max-height: calc(100vh - var(--nav-height) - var(--doc-topbar-h, 45px));
}

/* Aucune marge : le panneau est collé sous la context bar. La marge haute
   de doc.css gagnerait sinon — son `:not(#doc-chapters-root)` lui donne une
   spécificité d'ID, qu'aucun empilement de classes ne rattrape — d'où la
   reprise de son sélecteur exact, affiné d'un cran. */
.doc-page:has(.ctx-bar) .doc-chapters-scroll:not(#doc-chapters-root):has(.cor-pdf-panel) {
    margin-top: 0;
}

.doc-chapters-scroll:has(.cor-pdf-panel) {
    padding-bottom: 0;
}

/* Les 6px sous la context bar elle-même : le dernier interstice entre elle
   et le panneau, et le seul qui ne vienne pas de .doc-chapters-scroll. */
.doc-page:has(.cor-pdf-panel) .ctx-bar {
    margin-bottom: 0;
}

/* Colonne de gauche 25% plus large que le défaut du site (248px, cf.
   .doc-page-sidebar dans doc.css) : elle porte ici l'élève, le sommaire des
   questions ET le panneau de notation toujours ouvert, plus chargée que sur
   une page document ordinaire. Scopé à cette page — pas touche au 248px
   commun. Le PDF suit tout seul : .doc-page-main est en flex:1 1 auto, il
   perd donc exactement les 62px que la colonne gagne. */
.doc-page-scroll:has(.cor-pdf-panel) .doc-page-sidebar {
    /* 330px plutôt que 310 (cf. demande "gagner de la place avec les
       menus") : le PDF est en flex:1 dans .cor-work-area, il cède donc
       automatiquement exactement ce que les deux colonnes latérales
       gagnent — pas besoin d'y toucher séparément. */
    flex: 0 0 330px;
    /* Hauteur réelle (pas juste un plafond) : indispensable pour que la
       carte Questions puisse s'étirer en flex:1 et pousser la carte
       Notation jusqu'au bas de la colonne — sans ça, la colonne ne fait
       que la hauteur de son contenu et Notation suit immédiatement après
       Questions au lieu de rester collée en bas. */
    height: calc(100vh - var(--nav-height) - var(--doc-topbar-h, 45px));
    max-height: calc(100vh - var(--nav-height) - var(--doc-topbar-h, 45px));
}

/* Carte Questions : seule à rétrécir/scroller dans la colonne (même
   patron que .doc-sidebar-toc-card, doc.css) — la carte Élève/Note garde
   sa taille naturelle en haut, la carte Notation reste collée en bas. */
.cor-questions-card {
    flex: 1 1 auto;
    min-height: 0;
}

.cor-questions-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.cor-shortcuts-group + .cor-shortcuts-group { margin-top: 18px; }
.cor-shortcuts-group-title {
    display: block;
    margin-bottom: 8px;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-faint);
}
.cor-shortcuts-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.cor-shortcuts-list > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
}
.cor-shortcuts-list dt { flex-shrink: 0; text-align: right; }
.cor-shortcuts-list dd { color: var(--text); margin: 0; }
.cor-shortcuts-list kbd {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 4px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    font-size: 0.78rem;
    font-family: inherit;
    color: var(--text-faint);
}
.cor-shortcuts-note {
    margin: 18px 0 0;
    font-size: 0.82rem;
    color: var(--text-faint);
}

.cor-questions-wrap {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    margin-right: -16px;
    padding-right: 8px;
}

/* Toujours sa taille naturelle, jamais rétrécie : c'est elle qui doit
   rester collée en bas, pas s'écraser pour laisser de la place. */
.cor-grade-panel {
    flex-shrink: 0;
}

/* Hôte de la zone PDF commune (_pdf_viewer.html) : toute la hauteur
   restante sous la context bar. SEULE la taille est définie ici — le
   panneau lui-même, sa barre d'outils et son comportement viennent du
   composant partagé, exactement comme sur la page Feuille et la page
   Colles. Même patron que .colles-pdf-panel (colles.css). */
/* Zone de travail : le PDF, et à sa droite tout ce qui parle de la CLASSE
   (statistiques, normalisation, tableau des notes) — la colonne de gauche
   restant, elle, dédiée à la copie courante. */
.cor-work-area {
    display: flex;
    align-items: stretch;
    /* 40px : même écart que .doc-page-scroll entre la sidebar gauche et le
       corps de page, pour que les deux menus latéraux de cette page (gauche
       questions, droite classe) soient à équidistance visuelle du PDF. */
    gap: 40px;
    height: calc(100vh - var(--nav-height) - var(--doc-topbar-h, 45px));
}

.cor-pdf-panel {
    position: relative;
    box-sizing: border-box;
    /* Prend ce que le panneau de droite laisse. min-width: 0 est
       indispensable : sans lui, un item flex refuse de passer sous la
       largeur de son contenu et le PDF déborderait au lieu de se réduire. */
    flex: 1;
    min-width: 0;
    height: 100%;
    border: 1px solid var(--border);
    background: var(--surface);
    overflow: hidden;
}

.cor-class-panel {
    /* Même largeur que la colonne de gauche (.doc-page-sidebar, 330px
       ci-dessus) : les deux menus latéraux du panneau de correction.
       Le panneau lui-même ne scroll pas (hauteur fixe) : seule la liste
       des élèves, plus bas, a son propre scroll interne. */
    flex: 0 0 330px;
    height: 100%;
    box-sizing: border-box;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.cor-class-section {
    background: var(--surface);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ---- Statistiques ----
   Une icône + une couleur par indicateur (moyenne, corrigées, écart-type,
   min, max) pour les distinguer d'un coup d'œil plutôt que de les aligner
   en simple liste dt/dd — la barre de progression sur "Copies corrigées"
   est le seul indicateur qui appelle un visuel en plus du chiffre. */

/* Bouton discret : ouvre la modale "Statistiques détaillées". Reset des
   styles <button> par défaut (min-width:120px de form.css compris, cf. le
   piège déjà documenté ailleurs dans ce fichier) pour qu'il se comporte
   comme le simple en-tête de carte qu'il remplace. */
.cor-stats-head {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-width: 0;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    text-align: left;
    color: inherit;
    font: inherit;
}

.cor-stats-head:hover .filters-title { color: var(--text); }

.cor-stats-head-icon {
    width: 16px;
    height: 16px;
    color: var(--accent);
    flex-shrink: 0;
}

.cor-stats-head-arrow {
    width: 14px;
    height: 14px;
    margin-left: auto;
    flex-shrink: 0;
    color: var(--text-faint);
    transition: transform 0.15s, color 0.15s;
}

.cor-stats-head:hover .cor-stats-head-arrow {
    color: var(--accent);
    transform: translateX(2px);
}

.cor-stat-item {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: 8px;
    padding: 5px 0;
    font-size: 0.86rem;
}

.cor-stat-icon {
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    background: color-mix(in srgb, var(--cor-stat-color, var(--accent)) 16%, transparent);
    color: var(--cor-stat-color, var(--accent));
}

.cor-stat-icon svg {
    width: 14px;
    height: 14px;
}

.cor-stat-icon-mean { --cor-stat-color: var(--accent); }
.cor-stat-icon-corrected { --cor-stat-color: var(--accent); }
.cor-stat-icon-sd { --cor-stat-color: #2f81f7; }
.cor-stat-icon-min { --cor-stat-color: #f5a524; }
.cor-stat-icon-max { --cor-stat-color: #46a758; }

.cor-stat-item-label {
    color: var(--text-muted);
    min-width: 0;
}

.cor-stat-item-value {
    font-weight: 700;
    color: var(--cor-stat-color, var(--text));
    white-space: nowrap;
}

.cor-stat-item-value-mean { --cor-stat-color: var(--accent); }
.cor-stat-item-value-corrected { --cor-stat-color: var(--accent); }
.cor-stat-item-value-sd { --cor-stat-color: #2f81f7; }
.cor-stat-item-value-min { --cor-stat-color: #f5a524; }
.cor-stat-item-value-max { --cor-stat-color: #46a758; }

.cor-stat-item-unit {
    color: var(--text-faint);
    font-size: 0.76rem;
}

/* Barre de progression "Copies corrigées" : tout sur UNE seule ligne
   (icône, libellé, jauge, quantité) — la jauge prend la colonne flexible
   du milieu, comme le libellé sur les autres lignes. */
.cor-stat-item-progress {
    grid-template-columns: auto auto 1fr auto;
}

.cor-stat-item-progress .cor-stat-item-label {
    flex-shrink: 0;
    white-space: nowrap;
}

.cor-stat-progress-bar {
    min-width: 30px;
    height: 6px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
}

.cor-stat-progress-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--cor-stat-color, var(--accent));
    transition: width 0.2s;
}

.cor-class-note {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--success, #3fb950);
}

.cor-class-note-icon {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    margin-top: 1px;
    color: var(--text-faint);
}

/* ---- Statistiques, variante "option 4" (comparaison temporaire) ----
   Deux grandes tuiles (Moyenne / Copies corrigées) au-dessus de trois
   tuiles compactes (Écart-type / Min / Max), chacune centrée avec son
   icône en médaillon rond au-dessus du libellé plutôt qu'à côté. */
.cor-stats-v2-top {
    display: flex;
    gap: 14px;
}

.cor-stats-v2-tile {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.cor-stats-v2-tile + .cor-stats-v2-tile {
    padding-left: 14px;
    border-left: 1px solid var(--border-soft);
}

/* Moyenne = LE chiffre qui compte le plus dans ce panneau : centrée dans
   sa tuile plutôt qu'alignée à gauche comme les autres, pour attirer
   l'œil en premier. */
.cor-stats-v2-tile-mean {
    align-items: center;
    justify-content: center;
    text-align: center;
}

.cor-stats-v2-tile-mean .cor-stats-v2-tile-value,
.cor-stats-v2-tile-mean .cor-stat-item-unit {
    font-size: 1.7rem;
}

.cor-stats-v2-tile-mean .cor-stat-item-unit {
    font-size: 0.9rem;
}

.cor-stats-v2-tile-label {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-faint);
}

.cor-stats-v2-tile-value {
    font-family: var(--font-head);
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--cor-stat-color, var(--text));
    line-height: 1.2;
}

.cor-stats-v2-top .cor-stat-progress-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 2px;
}

.cor-stats-v2-top .cor-stat-progress-bar {
    flex: 1;
    height: 6px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
}

.cor-stats-v2-top .cor-stat-progress-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--cor-stat-color, var(--accent));
}

.cor-stats-v2-top .cor-stat-progress-pct {
    flex-shrink: 0;
    font-size: 0.72rem;
    color: var(--text-faint);
}

.cor-stats-v2-bottom {
    display: flex;
    gap: 10px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border-soft);
}

.cor-stats-v2-mini {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    text-align: center;
}

.cor-stat-icon-round {
    width: 30px;
    height: 30px;
    border-radius: 50%;
}

.cor-stats-v2-mini .cor-stats-v2-tile-value {
    font-size: 1rem;
}

/* ---- Normalisation ---- */

.cor-norm-methods {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.cor-norm-method {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.84rem;
    color: var(--text-muted);
    cursor: pointer;
    padding: 3px 4px;
    border-radius: var(--radius-sm);
}

.cor-norm-method:hover {
    background: var(--surface-2);
    color: var(--text);
}

.cor-norm-method input {
    accent-color: var(--accent);
    flex-shrink: 0;
}

.cor-norm-params {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border-soft);
}

.cor-norm-param {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    font-size: 0.82rem;
    color: var(--text-muted);
}

.cor-norm-param input {
    width: 72px;
    padding: 4px 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    text-align: right;
    /* Pas de flèches haut/bas : ce sont des cibles réglées une fois, pas
       des compteurs qu'on incrémente au clic. */
    -moz-appearance: textfield;
}

.cor-norm-param input::-webkit-outer-spin-button,
.cor-norm-param input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.cor-norm-param input:focus {
    outline: none;
    border-color: var(--accent);
}

.cor-norm-formula {
    margin: 0;
    font-size: 0.76rem;
    color: var(--text-faint);
}

.cor-norm-formula em {
    font-style: normal;
    font-weight: 600;
    color: var(--accent);
}

.cor-norm-warning {
    margin: 0;
    font-size: 0.76rem;
    line-height: 1.4;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    background: color-mix(in srgb, #f5a524 14%, transparent);
    border: 1px solid color-mix(in srgb, #f5a524 40%, transparent);
    color: var(--text);
}

/* ---- Tableau des notes de la classe ---- */

.cor-class-section-table {
    min-height: 0;
    flex: 1 1 auto;
    overflow: hidden;
}

.cor-class-table-scroll {
    overflow-y: auto;
    min-height: 0;
    flex: 1 1 auto;
    /* La scrollbar mange sinon dans la largeur du tableau, juste contre la
       colonne "/20" : on étend le conteneur jusqu'au bord droit de la
       carte (annule son padding) et on ré-injecte un peu de padding pour
       que la scrollbar colle au bord plutôt que de gêner le texte — 12px
       plutôt que 8, pour un vrai espace visible avant la scrollbar. */
    margin-right: -14px;
    padding-right: 12px;
    /* Miroir à gauche, mais en SENS INVERSE : on grignote le padding de la
       carte au lieu d'en ajouter, pour réduire le vide entre le bord de la
       carte et la colonne flèche/nom (cf. demande "espace pas bien
       utilisé à gauche") — le colgroup fixe déjà les largeurs de colonnes
       donc aucun risque de re-tremblement en réduisant ce padding. */
    margin-left: -8px;
    padding-left: 2px;
}

.cor-class-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
    /* Largeurs de colonnes figées par le colgroup, jamais recalculées
       depuis le contenu (cf. commentaire du template) : sans ça, la flèche
       qui apparaît/disparaît ou un nombre plus large faisait sauter les
       colonnes d'une ligne à l'autre en changeant d'élève. */
    table-layout: fixed;
}

.cor-class-col-arrow { width: 12px; }
.cor-class-col-nom { width: 40%; }
.cor-class-col-prenom { width: 30%; }
.cor-class-col-mu { width: 15%; }

.cor-class-table th {
    text-align: left;
    font-weight: 600;
    color: var(--text-faint);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border-soft);
}

.cor-class-table th:not(.cor-class-th-nom):not(.cor-class-th-prenom),
.cor-class-table td:not(.cor-class-td-nom):not(.cor-class-td-prenom) {
    text-align: right;
    white-space: nowrap;
}

/* Notes trop collées au bord droit sinon : un peu d'air avant le bord de
   la zone de survol/cadre, symétrique au padding-left du nom à gauche. */
.cor-class-table th:last-child,
.cor-class-table td:last-child {
    padding-right: 6px;
}

.cor-class-table td {
    padding: 3px 0;
    color: var(--text-muted);
}

/* Une ligne = un élève cliquable (change de copie, cf. switchStudent) —
   sauf la ligne déjà courante, qui n'a nulle part où aller. */
.cor-class-table tbody tr:not(.is-current) {
    cursor: pointer;
}

/* Colonne flèche exclue, comme le cadre de .is-current juste plus bas :
   sinon le survol débordait plus à gauche que la bordure de la ligne
   active, les deux zones ne couvrant pas le même espace. */
.cor-class-table tbody tr:not(.is-current):hover td:not(.cor-class-td-arrow) {
    color: var(--text);
    background: var(--surface-2);
}

.cor-class-table td.cor-class-td-nom,
.cor-class-table td.cor-class-td-prenom {
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 130px;
    white-space: nowrap;
}

/* Nom/prénom rapprochés l'un de l'autre, colonnes notes éloignées d'eux.
   padding-left : un peu d'air entre le bord gauche de la zone de survol/
   cadre (qui commence à cette colonne, cf. plus haut) et le texte. */
.cor-class-table td.cor-class-td-nom,
.cor-class-table th.cor-class-th-nom {
    padding-right: 4px;
    padding-left: 6px;
}

.cor-class-table td.cor-class-td-prenom,
.cor-class-table th.cor-class-th-prenom {
    padding-right: 20px;
    color: var(--text-faint);
}

/* Cadre discret haut/bas de la ligne courante, en box-shadow plutôt qu'en
   border : une bordure ajoute à la hauteur de la ligne (même 1-2px), ce qui
   décale très légèrement les lignes voisines et peut faire "sauter" le
   tableau au changement d'élève. Le box-shadow, lui, se pose par-dessus
   sans jamais toucher au box model — colonnes et hauteurs de ligne restent
   identiques à l'état normal.
   La colonne flèche est explicitement EXCLUE du cadre (:not) : la flèche
   doit ressortir DEVANT/EN DEHORS du cadre, pas y être enfermée avec le
   reste de la ligne. */
.cor-class-table tr.is-current td:not(.cor-class-td-arrow) {
    font-weight: 600;
    box-shadow: inset 0 1px 0 0 currentColor, inset 0 -1px 0 0 currentColor;
    /* Fond très léger dans la même couleur que le texte (currentColor) :
       c'est CE lavis qui doit lire comme "actif", pas un texte plus clair
       — éclaircir le texte lui-même (blanc pur, vert/rouge pastel) rendait
       la ligne délavée plutôt qu'active. */
    background: color-mix(in srgb, currentColor 10%, transparent);
}

/* Petite flèche devant le nom de l'élève affiché, pour repérer d'un coup
   d'œil sa position dans la liste. Une vraie colonne dédiée, très étroite,
   plutôt qu'un enfant en position absolute à l'intérieur de .cor-class-td-nom
   (rogné par le scroll du tableau dans la plupart des moteurs, testé pas
   fiable) : elle ne mange donc rien sur la largeur du nom et n'est jamais
   coupée. Largeur figée par le colgroup (cf. plus haut), pas par le
   contenu — aucun tremblement en changeant d'élève. */
.cor-class-table th.cor-class-th-arrow,
.cor-class-table td.cor-class-td-arrow {
    padding: 0;
    text-align: center;
}

/* Chevron SVG (traits arrondis, même famille que les flèches précédent/
   suivant de la carte Élève) plutôt qu'un glyphe texte "▸" — rendu net à
   toute taille, animable, et sa couleur suit celle de la ligne (currentColor,
   cf. les états plus bas) au lieu d'être fixée à part.
   Toujours présent dans le DOM, caché par défaut : SEULE .is-current le
   révèle, avec un petit pop-in (scale + translate) plutôt qu'une apparition
   sèche — la colonne, elle, garde sa largeur (cf. colgroup) que la flèche
   soit visible ou non, donc aucun tremblement. */
.cor-class-arrow-icon {
    width: 11px;
    height: 11px;
    vertical-align: middle;
    opacity: 0;
    transform: translateX(-6px) scale(0.6);
    transition: opacity 0.15s ease, transform 0.15s ease;
    filter: drop-shadow(0 0 3px color-mix(in srgb, currentColor 70%, transparent));
}

.cor-class-table tr.is-current .cor-class-arrow-icon {
    opacity: 1;
    /* Décalée hors de la cellule (donc hors du cadre du is-current
       ci-dessus) plutôt que centrée dedans : elle doit clairement
       dépasser, pas juste occuper sa colonne. */
    transform: translateX(-4px) scale(1);
}

/* ---------- États de ligne : rouge = absent, vert = corrigé, gris = en
   attente. Posé sur TOUTES les cellules (pas seulement nom/prénom) pour
   que la couleur lise comme un état de LIGNE.
   Sur la ligne courante, le texte reste dans la MÊME famille de couleur —
   à peine plus clair, mélangé à --text (le blanc cassé du thème, pas du
   blanc pur) plutôt qu'à du blanc franc ou une version pastel qui
   détonnait. Le "plus actif" vient surtout du fond + cadre ci-dessus. */
.cor-class-table tr.is-pending td {
    color: var(--text-faint);
    font-style: italic;
}

.cor-class-table tr.is-graded td {
    color: var(--row-graded, #46a758);
}

.cor-class-table tr.is-current.is-pending td {
    color: color-mix(in srgb, var(--text-faint) 55%, var(--text) 45%);
    font-style: normal;
}

.cor-class-table tr.is-current.is-graded td {
    color: color-mix(in srgb, var(--row-graded, #46a758) 80%, var(--text) 20%);
}

/* .doc-page-pdf est normalement un panneau LATÉRAL fixe
   (width: var(--pdf-panel-width), sheet_detail.css) — ici il doit remplir
   .cor-pdf-panel, comme côté Colles. */
.cor-pdf-panel .doc-page-pdf {
    position: static;
    width: 100%;
    height: 100%;
}

/* Poignée de redimensionnement latéral : pertinente pour une 3e colonne
   (sheet_detail.html), sans objet pour ce panneau pleine largeur. */
.cor-pdf-panel .doc-pdf-resize-handle {
    display: none;
}

/* ---------- Absent ----------
   Aligné sur le libellé "Élève" (même ligne, poussé à droite) : un simple
   lien discret, pas un bouton encadré en pleine largeur — l'action reste
   secondaire tant qu'elle n'est pas active. */
.cor-student-label-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.cor-absent-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0;
    background: none;
    border: none;
    color: var(--text-faint);
    font-size: 0.72rem;
    cursor: pointer;
}

.cor-absent-toggle:hover {
    color: var(--danger);
}

.cor-absent-toggle.is-active {
    color: var(--danger);
    font-weight: 600;
}

.cor-absent-toggle svg { flex: 0 0 auto; width: 12px; height: 12px; }

/* Absent : rouge, y compris sur la ligne courante (juste éclairci, comme
   les deux autres états ci-dessus) — cf. is-pending/is-graded plus haut,
   même logique. */
.cor-class-table tr.is-absent td {
    color: var(--danger);
    font-style: normal;
}

.cor-class-table tr.is-current.is-absent td {
    color: color-mix(in srgb, var(--danger) 80%, var(--text) 20%);
}

/* ---------- Note de l'élève (haut de la colonne de gauche) ----------
   Brute et finale côte à côte : la brute est le constat de correction
   (points obtenus), la finale est ce qui sera rendu à l'élève. */

.cor-note-pair {
    display: flex;
    gap: 10px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--border-soft);
}

.cor-note-block {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 3px;
    text-align: center;
}

.cor-note-value {
    font-family: var(--font-head);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text);
    line-height: 1.1;
}

.cor-note-block-final .cor-note-value {
    color: var(--accent);
}

.cor-note-unit {
    font-size: 0.8rem;
    color: var(--text-faint);
}

.cor-note-label {
    flex-basis: 100%;
    font-size: 0.72rem;
    color: var(--text-faint);
}

/* ---------- Navigation élève (flèches de part et d'autre du select) ----------
   Violette quand il y a un élève dans ce sens (même liste que le select,
   triée nom/prénom), grisée et non cliquable en bout de liste — pas de
   bouclage silencieux d'un bout à l'autre de la classe. */
.cor-student-nav {
    display: flex;
    align-items: center;
    gap: 6px;
}

.cor-student-nav select {
    flex: 1;
    min-width: 0;
}

.cor-student-nav-btn {
    flex-shrink: 0;
    /* min-width:0 — écrase `button { min-width: 120px }` générique
       (form.css, piège déjà documenté ailleurs dans le CSS du site). */
    min-width: 0;
    width: 22px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--accent);
    cursor: pointer;
    transition: opacity 0.15s;
}

.cor-student-nav-btn svg {
    width: 18px;
    height: 18px;
}

.cor-student-nav-btn:hover:not(:disabled) {
    opacity: 0.7;
}

.cor-student-nav-btn:disabled {
    color: var(--text-faint);
    cursor: default;
}


/* ---------- Panneau de notation (bas de la colonne de gauche) ---------- */

/* Hauteur FIXE (4 lignes ≈ 0.86rem × 1.45 × 4) plutôt que suivant le
   contenu : une indication à rallonge décalait tout le bas de la colonne
   (boutons de notation, sommaire) selon la question sélectionnée. Au-delà,
   ça scrolle dans le panneau plutôt que de pousser la mise en page. */
.cor-grade-indications {
    max-height: calc(0.86rem * 1.45 * 4.3);
    overflow-y: auto;
    font-size: 0.86rem;
    line-height: 1.45;
    color: var(--text-muted);
    margin-bottom: var(--space-3);
}

/* Une indication par ligne (cf. eval_blocks._indications_to_html) : chaque
   ligne du bloc eval est un critère distinct du barème (« Bonne majoration :
   1 point »), les enchaîner en un seul paragraphe les rendait illisibles
   pendant la correction. Puces discrètes, pas la liste HTML par défaut. */
.cor-indic-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.cor-indic-list li {
    position: relative;
    padding-left: 12px;
}

.cor-indic-list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--text-faint);
}

.cor-grade-indications-empty {
    font-style: italic;
    color: var(--text-faint);
}

.ds-question-grade-buttons {
    display: flex;
    gap: 6px;
}

.ds-grade-btn {
    flex: 1;
    min-width: 0;
    padding: 6px 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text-muted);
    cursor: pointer;
    font-weight: 500;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.ds-grade-btn:hover {
    border-color: var(--accent);
    color: var(--text);
}

.ds-grade-btn.is-active {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent);
}


/* Sommaire « Questions » (sidebar) — une ligne = Q1 … [?]/4 … /2 :
   l'étiquette à gauche, la case de note cliquable (ouvre la modale) au
   milieu, et le barème de la question tout à droite. */

.ds-question-summary {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ds-question-summary li {
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    padding: 5px 8px;
    border-radius: var(--radius-sm);
    font-size: 0.88rem;
    color: var(--text-muted);
}

.ds-question-summary li:hover {
    background: var(--surface-2);
}

.ds-question-summary li.is-selected {
    background: var(--accent-soft);
    color: var(--text);
}

.ds-question-label {
    font-weight: 600;
    color: var(--text);
}

/* Pastille de note : "?" tant que la question n'est pas notée, la valeur
   0..4 ensuite. Purement indicative — la saisie se fait dans le panneau de
   notation en bas de colonne, alimenté par la ligne sélectionnée. */
.ds-question-score {
    margin-left: auto;
    width: 26px;
    flex-shrink: 0;
    box-sizing: border-box;
    padding: 1px 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text-faint);
    font-weight: 600;
    font-size: 0.78rem;
    line-height: 1.3;
    text-align: center;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.ds-question-score.is-noted {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent);
}

/* NT : traité (donc plus « à faire »), mais rapporte 0 — ni le vide du
   « ? », ni l'accent d'une note. */
.ds-question-score.is-nt {
    background: color-mix(in srgb, var(--text-faint) 25%, transparent);
    border-color: var(--text-faint);
    color: var(--text);
}

.ds-question-scale {
    font-size: 0.78rem;
    color: var(--text-faint);
    margin-left: -3px;
}

/* Barème de la question, calé à droite et séparé de la note sur 4.
   C'est un <button> : cliquer dessus modifie le nombre de points de la
   question. Il ne doit pas pour autant RESSEMBLER à un bouton au repos
   (le sommaire serait constellé de cadres) — d'où l'habillage neutre,
   révélé au survol seulement. */
.ds-question-summary .ds-question-points {
    min-width: 30px;
    padding: 1px 4px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    text-align: right;
    font: inherit;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.ds-question-summary .ds-question-points:hover {
    border-color: var(--accent);
    background: var(--surface);
    color: var(--text);
}

/* ---------- Groupes d'exercices dans le sommaire ----------
   Les questions repartent à Q1 à chaque exercice : sans séparation nette,
   deux « Q1 » à la suite seraient illisibles. L'en-tête porte le numéro
   d'exercice (et son titre), les lignes ne portent plus que Q1/Q2. */

.ds-question-group + .ds-question-group {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border-soft);
}

.ds-question-group-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 6px;
    padding: 0 8px;
}

.ds-question-group-ident {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

/* Total de l'exercice, calé à droite de son en-tête : points obtenus
   (somme des valeur/4 × barème) sur total du barème. */
.ds-question-group-total {
    margin-left: auto;
    flex-shrink: 0;
    font-weight: 600;
    white-space: nowrap;
}

.ds-question-group-total-value {
    color: var(--text);
}

.ds-question-group-total-max {
    font-size: 0.78rem;
    color: var(--text-faint);
}

.ds-question-group-num {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--accent);
}

.ds-question-group-title {
    font-size: 0.76rem;
    color: var(--text-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ds-question-empty {
    font-size: 0.84rem;
    color: var(--text-faint);
    font-style: italic;
}

/* =========================================================
   MODALE "Statistiques détaillées" — histogramme, quartiles, répartition
   par intervalles, donut. Couleurs alignées sur celles déjà utilisées dans
   la carte compacte (--accent violet, --danger, --content-exercise,
   #2f81f7, #46a758) plutôt que sur une palette ad hoc.
   ========================================================= */

#stats-detail-modal .modal-box {
    width: 640px;
    max-width: 95vw;
    max-height: 88vh;
}

#stats-detail-modal .modal-header {
    align-items: flex-start;
}

.stats-detail-subtitle {
    margin: 2px 0 0;
    font-size: 0.78rem;
    font-weight: 400;
    color: var(--text-faint);
}

.stats-detail-body {
    overflow-y: auto;
    gap: 16px;
}

.stats-detail-toggle {
    align-self: flex-start;
}

.stats-detail-tiles {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 8px;
}

.stats-detail-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 10px 6px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    background: var(--surface-2);
    text-align: center;
}

.stats-detail-tile-value {
    font-family: var(--font-head);
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1.1;
}

.stats-detail-tile-unit {
    margin-left: 2px;
    font-size: 0.7rem;
    font-weight: 400;
    color: var(--text-faint);
}

.stats-detail-tile-chip {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--content-exercise);
}

.stats-detail-tile-label {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-faint);
}

.stats-detail-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.stats-detail-panel {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    background: var(--surface-2);
}

.stats-detail-panel-title {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-faint);
}

/* ---- Histogramme (distribution des notes, tranches de 2) ---- */

.stats-detail-hist {
    display: flex;
    align-items: flex-end;
    gap: 4px;
    height: 120px;
}

.stats-detail-hist-col {
    flex: 1;
    min-width: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 2px;
}

.stats-detail-hist-count {
    font-size: 0.66rem;
    color: var(--text-faint);
    min-height: 1em;
}

.stats-detail-hist-bar {
    width: 100%;
    min-height: 0;
    border-radius: 3px 3px 0 0;
    background: var(--accent);
}

.stats-detail-hist-label {
    font-size: 0.58rem;
    color: var(--text-faint);
    white-space: nowrap;
    transform: rotate(0deg);
}

/* ---- Résumé (min/Q1/médiane/Q3/max/IQR) ---- */

.stats-detail-summary {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.stats-detail-summary-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    font-size: 0.82rem;
}

.stats-detail-summary-row dt {
    color: var(--text-muted);
}

.stats-detail-summary-row dd {
    margin: 0;
    font-weight: 600;
    color: var(--text);
}

/* ---- Table de répartition par intervalles ---- */

.stats-detail-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
}

.stats-detail-table th {
    text-align: left;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-faint);
    font-weight: 600;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border-soft);
}

.stats-detail-table td {
    padding: 4px 0;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border-soft);
}

.stats-detail-table tr:last-child td {
    border-bottom: none;
}

.stats-detail-table th:not(:first-child),
.stats-detail-table td:not(:first-child) {
    text-align: right;
}

.stats-detail-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 6px;
}

/* ---- Donut de répartition (%) ---- */

.stats-detail-panel-donut {
    flex-direction: row;
    align-items: center;
    justify-content: center;
}

.stats-detail-donut-row {
    display: flex;
    align-items: center;
    gap: 16px;
}

.stats-detail-donut {
    width: 90px;
    height: 90px;
    flex-shrink: 0;
}

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

.stats-detail-legend-row {
    display: flex;
    align-items: center;
    font-size: 0.78rem;
    color: var(--text-muted);
    white-space: nowrap;
}

.stats-detail-legend-pct {
    margin-left: 6px;
    font-weight: 600;
    color: var(--text);
}

/* ---------- Panneau droit "détail élève" (students/index.html) ----------
   3e colonne du layout doc-page-scroll (block doc_info_panel, prévu à cet
   effet dans _leftmenu_base.html) : toujours visible, comme le panneau
   gauche — pas une popup/drawer qui apparaît par-dessus le contenu.
   Réutilise .doc-page-sidebar (sticky, largeur, scroll interne) : la
   règle body.correction-ctx-active .doc-page-sidebar (plus haut dans ce
   fichier) élargit donc les DEUX panneaux latéraux de cette page à la
   même largeur, gauche et droite. */
/* Symétrique au panneau gauche : .doc-page-sidebar donne déjà padding-top:20px
   + sticky + max-height (doc.css) — on n'y touche pas ici, on l'utilise tel
   quel. Le "carton" bordé (fond/bordure/radius, comme .doc-sidebar-card à
   gauche) vit sur .student-detail-body, pas sur l'aside : display:flex +
   min-height:0 lui permet de rétrécir/scroller DANS la max-height de l'aside
   au lieu de la pousser (même technique que .doc-sidebar-toc-card à gauche)
   — sans ça, le panneau grandissait/rétrécissait selon le nombre de notes
   de l'élève sélectionné au lieu de garder une taille fixe. */
.student-detail-sidebar {
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    min-height: 0;
    /* min-width:0 indispensable : par défaut un flex-item a min-width:auto,
       qui vaut la largeur minimale de son CONTENU (ici un texte non
       coupable, ex. une adresse mail longue dans le résumé) — cette
       largeur "automatique" prime sur flex-basis/flex-shrink:0 et peut
       donc élargir le panneau au-delà de 320px malgré tout, cassant la
       symétrie avec le panneau gauche. */
    min-width: 0;
}

.student-detail-body {
    box-sizing: border-box;
    padding: 16px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    background: #121826;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.student-detail-empty-msg {
    color: var(--text-faint);
    font-size: 0.88rem;
    margin: 0 0 20px 0;
}

.student-detail-photo {
    display: block;
    width: 100%;
    max-width: 187px;
    aspect-ratio: 187 / 249;
    object-fit: cover;
    border-radius: var(--radius);
    border: 1px solid var(--border-soft);
    margin: 0 0 12px 0;
}

.student-detail-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 16px;
}

.student-detail-close-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    min-width: 0;
    padding: 0;
    flex-shrink: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-faint);
    cursor: pointer;
}

.student-detail-close-btn:hover {
    background: var(--surface-2);
    color: var(--text);
}

.student-detail-close-btn svg {
    width: 16px;
    height: 16px;
}

.student-detail-name {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--text);
}

/* Ligne surlignée dans le tableau tant que son détail est affiché à
   droite — repère visuel de la sélection courante. */
.student-table tr.student-row.is-selected td {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
}

/* Les trois grosses moyennes, en violet (--accent), tel que demandé. */
.student-detail-summary {
    display: flex;
    gap: 8px;
    margin-bottom: 24px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--border-soft);
}

.student-detail-summary-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

.student-detail-summary-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-faint);
}

.student-detail-summary-value {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--accent);
}

.student-detail-block {
    margin-bottom: 20px;
}

.student-detail-block-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 8px;
}

.student-detail-block-label {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text);
}

/* La moyenne du bloc, en tête de bloc (demandé explicitement) : même
   couleur violette que le résumé du haut, mais plus petite. */
.student-detail-block-mu {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--accent);
}

.student-detail-block-empty {
    margin: 0;
    font-size: 0.82rem;
}

.student-detail-note-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.student-detail-note {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 6px 0;
    border-bottom: 1px solid var(--border-soft);
    font-size: 0.85rem;
}

.student-detail-note:last-child {
    border-bottom: none;
}

.student-detail-note-titre {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-muted);
}

.student-detail-note-date {
    color: var(--text-faint);
    font-size: 0.75rem;
    white-space: nowrap;
}

.student-detail-note-value {
    min-width: 3ch;
    text-align: right;
    font-weight: 600;
    color: var(--text);
}

.student-detail-note-pending .student-detail-note-value {
    color: var(--text-faint);
    font-style: italic;
}

.student-row {
    cursor: pointer;
}

/* =========================================================
   VUE "PAR GROUPE" (colle-groups-*, students/index.html)
   =========================================================
   Toggle Élèves/Groupes dans la context bar (demande 2026-08-27) : cartes
   de groupes en grille + liste des élèves non groupés en dessous, même
   esprit que .colle-session-panel-title (teinte --kind-colle). */
/* Meme geometrie que la vue "Eleves" : meme largeur de page (cf. le
   `main:has(...)` plus haut) et meme decalage haut que .student-table
   (margin-top: var(--space-4)) — les deux vues doivent se superposer
   pixel pour pixel quand on bascule de l'une a l'autre. */
.colle-groups-view {
    margin-top: var(--space-4);
}

.colle-groups-toolbar {
    display: flex;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
}
.colle-groups-toolbar form { margin: 0; }

/* Trois colonnes au maximum (cf. demande 2026-08-27), moins si la place
   manque. Le `max(...)` plafonne la grille a 3 colonnes en imposant a
   chaque piste au moins un tiers de la largeur, tout en gardant le repli
   automatique a 2 puis 1 colonne sous --colle-group-col-min. */
.colle-groups-grid {
    --colle-group-col-min: 260px;
    display: grid;
    grid-template-columns: repeat(
        auto-fill,
        minmax(max(var(--colle-group-col-min), (100% - 2 * var(--space-3)) / 3), 1fr)
    );
    gap: var(--space-3);
}

.colle-group-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    background: var(--surface-1);
}
.colle-group-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-2);
}
.colle-group-card-title {
    font-weight: 700;
    color: var(--kind-colle);
    font-size: 0.9rem;
}
input.colle-group-label-input {
    border: 1px solid transparent;
    background: transparent;
    border-radius: var(--radius-sm);
    padding: 2px 4px;
    min-width: 0;
    flex: 1;
}
input.colle-group-label-input:hover,
input.colle-group-label-input:focus {
    border-color: var(--border);
    background: var(--surface-2);
}
.colle-group-delete-form { margin: 0; }
/* Croix (suppression de groupe / retrait d'un eleve) : invisibles au
   repos, revelees au survol de la carte ou de la ligne concernee — elles
   encombraient l'affichage en permanence. `visibility` plutot que
   `display` pour que la place reste reservee (pas de saut de mise en
   page au survol) ; :focus-visible les revele aussi, sinon elles seraient
   inatteignables au clavier. */
.colle-group-delete-btn,
.colle-group-member-remove {
    visibility: hidden;
}
.colle-group-card:hover .colle-group-delete-btn,
.colle-group-delete-btn:focus-visible,
.colle-group-member:hover .colle-group-member-remove,
.colle-group-member-remove:focus-visible {
    visibility: visible;
}

/* min-width/padding serres : form.css pose `button { min-width: 120px }`
   en global, sans quoi cette croix occupe une zone de 120px de large. */
.colle-group-delete-btn {
    background: none;
    border: none;
    color: var(--text-faint);
    cursor: pointer;
    font-size: 0.85rem;
    min-width: 0;
    width: 22px;
    height: 22px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
}
.colle-group-delete-btn:hover { color: var(--danger, #d33); background: var(--surface-2); }

.colle-group-members {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
/* Lignes eleve : meme trio de moyennes que la vue "Par eleve"
   (DS / Colles / Moy.), en colonnes alignees d'une ligne a l'autre — d'ou
   la grille partagee avec .colle-group-members-head, qui porte les
   libelles une seule fois par carte. */
.colle-group-members-head,
.colle-group-member {
    display: grid;
    /* Derniere piste = la croix, separee des moyennes par une gouttiere
       plus large (var(--space-2)) : collee a "Moy." elle se lisait comme
       une quatrieme colonne de notes. */
    grid-template-columns: minmax(0, 1fr) 38px 38px 38px var(--space-2) 20px;
    align-items: center;
    gap: 4px;
    font-size: 0.88rem;
    padding: 3px 4px;
}

.colle-group-members-head {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-faint);
    padding-bottom: 2px;
    border-bottom: 1px solid var(--border);
}
.colle-group-members-head span { text-align: right; }

.colle-group-member {
    cursor: pointer;
    border-radius: var(--radius-sm);
}
.colle-group-member:hover { background: var(--surface-2); }
/* Meme fond uni que la ligne selectionnee du tableau "Par eleve"
   (.student-table tr.student-row.is-selected td) — un seul repere visuel
   pour la selection courante, quelle que soit la vue. */
.colle-group-member.is-selected {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.colle-group-member-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.colle-group-member-mu {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}
/* Idem : min-width: 0 contre le `button { min-width: 120px }` global.
   grid-column explicite : la ligne n'a que 5 enfants pour 6 pistes, sans
   ca la croix se poserait dans la gouttiere et resterait collee a
   "Moy.". */
.colle-group-member-remove {
    grid-column: -2 / -1;
    background: none;
    border: none;
    color: var(--text-faint);
    cursor: pointer;
    font-size: 0.78rem;
    min-width: 0;
    width: 20px;
    height: 20px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}
.colle-group-member-remove:hover { color: var(--danger, #d33); }

.colle-group-warning {
    margin: var(--space-2) 0 0;
    font-size: 0.78rem;
    color: var(--warning, #c78a1e);
}

.colle-groups-ungrouped {
    margin-top: var(--space-5);
}
.colle-groups-ungrouped-list {
    list-style: none;
    margin: var(--space-2) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-width: 420px;
}
.colle-groups-ungrouped-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    font-size: 0.88rem;
    padding: 4px 0;
    border-bottom: 1px solid var(--border);
}
