/* =========================================================
   THOMATHS — CARTE EXERCICE (refonte)
   En-tête (kind/ID/titre + difficulté + icônes pédago +
   variantes + filières + options), méta (chapitre/tags).
   Chargé après theme.css : surcharge l'ancien layout de carte.
   Consomme uniquement les tokens (tokens.css).
   ========================================================= */

/* ---------- Structure : poignée à gauche + corps ---------- */
.exercise-card { position: relative; }

/* Même agencement que .doc-block-drag-handle (poignée de feuille/cours) :
   bande sur tout le bord droit de la carte, icône 6 points centrée. */
.exo-drag-handle {
    position: absolute;
    right: -16px;
    top: 0;
    bottom: 0;
    width: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius);
    background: var(--surface-2);
    color: var(--text-faint);
    cursor: grab;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s, color 0.12s, background 0.12s;
}
.exercise-card:hover .exo-drag-handle {
    opacity: 1;
    pointer-events: auto;
}
.exo-drag-handle:hover { background: var(--surface-3); color: var(--text-muted); }
.exo-drag-handle:active { cursor: grabbing; }

/* Le corps laisse la place à la poignée quand elle existe */
.exo-body { padding: 12px 16px 14px; }
.exercise-card:has(.exo-drag-handle) { margin-right: 16px; }

/* Liseré gauche coloré — même principe que .doc-env (doc.css) : uniformisé
   ici pour TOUS les exercices (avant, réservé aux cartes avec variantes,
   neutralisé ensuite quand la barre de variantes est passée dans
   l'en-tête ; ça ne concerne plus les variantes du tout maintenant).
   --kind-border sert de couleur commune à la sélection (cf. theme.css
   .exercise-card.selected et doc.css .sheet-block.selected), pour que le
   même mécanisme "la sélection prolonge le liseré existant" s'applique
   aux exercices comme aux environnements. */
.exercise-card {
    border-left: 3px solid var(--content-exercise-doc);
    --kind-border: var(--content-exercise-doc);
}
.exo-main-head .variant-bar {
    margin-top: 0;
    padding: 3px;
    border-top: none;
    border: 1.5px solid var(--violet-soft);
    border-radius: 9px;
    background: var(--violet-dim);
    gap: 0;
}
.exo-main-head .vbar-btn {
    background: transparent;
    border: none;
    color: var(--text-muted);
    height: 30px;
    min-width: 28px;
    font-size: 0.95rem;
    border-radius: 6px;
}
.exo-main-head .vbar-btn:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.exo-main-head .vbar-select-btn {
    color: var(--violet);
    font-weight: 700;
    padding: 0 10px;
    font-size: 0.85rem;
}
.exo-main-head .vbar-all { color: var(--violet); }

/* ---------- En-tête ---------- */
.exo-main-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.exo-main-head-right {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}
/* Réserve la place du bouton options ancré dans le coin (position absolute) */
.exercise-card:has(.exo-options-btn) .exo-main-head-right { padding-right: 30px; }

/* Badge type d'exercice — repère net mais discipliné : un seul poids
   fort par carte (avec le titre), tout le reste de l'en-tête reste bas. */
.exo-kind-badge {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 5px 11px;
    border-radius: 6px;
    background: var(--accent);
    color: #fff;
    white-space: nowrap;
}
.exo-kind-probleme       { background: var(--content-definition); color: #fff; }
.exo-kind-question_cours { background: var(--content-proof);      color: #fff; }

/* Badge ID — discret, même famille que le badge type sans lui faire concurrence */
.exo-id-badge {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-faint);
    background: var(--surface-3);
    padding: 5px 8px;
    border-radius: 6px;
    min-width: 1.4em;
    text-align: center;
}

/* Titre */
.exo-title {
    font-family: var(--font-head);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--text);
}

/* Étoile favori */
.exo-fav {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--text-faint);
    cursor: pointer;
    padding: 2px;
    border-radius: var(--radius-sm);
}
.exo-fav svg { width: 18px; height: 18px; }
.exo-fav:hover { color: var(--content-definition); }
.exo-fav.active { color: var(--content-definition); }
.exo-fav.active svg { fill: var(--content-definition); }

/* Coeur "question de cours" (blocs de cours) : même bouton/position que le
   favori étoile des exercices, juste une couleur rouge/rose dédiée au lieu
   du bleu, pour rester visuellement distinct du favori. La couleur "actif"
   elle-même vient de `.icon-question-cours.active` (doc.css, posée sur ce
   bouton en plus de `.exo-fav-heart`) — règle UNIQUE, partagée avec les
   autres endroits où ce cœur apparaît (barre de survol, panneau info). Seul
   le survol, propre à ce bouton précis, reste ici. */
.exo-fav-heart:hover { color: #e0455f; }

/* Difficulté (compacte, discrète dans l'en-tête — ne rivalise pas avec le titre) */
.exo-main-head .difficulty { font-size: 0.72rem; letter-spacing: 1px; line-height: 1; opacity: 0.75; }
.exo-main-head .difficulty:hover { opacity: 1; }

/* ---------- Filières — flottent comme du texte, pas des boîtes ---------- */
.exo-tracks {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
    max-width: 180px;
    background: transparent;
    border: none;
    padding: 0;
}
.exo-track-pill {
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0;
    background: none;
    border: none;
}
.exo-track-sup { color: var(--track-sup); }
.exo-track-spe { color: var(--track-spe); }
.exo-track-none { color: var(--text-faint); }

/* ---------- Bouton options ⋮ — inline, aligné avec le reste de la ligne ---------- */
.exo-options-btn {
    position: static;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--text-faint);
    font-size: 0.95rem;
    line-height: 1;
    width: 16px;
    height: 16px;
    min-width: 16px;
    padding: 0;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.exo-options-btn:hover { background: var(--surface-2); color: var(--text); }
.exercise-card:has(.exo-options-btn) .exo-main-head-right { padding-right: 0; }

/* ---------- Réglages footer hérités ---------- */
.exo-timestamps {
    padding: 0 1rem;
    font-size: 0.72rem;
    color: var(--text-muted, #666);
    opacity: 0.6;
    display: flex;
    align-items: center;
    display: none;
}

/* ---------- Énoncé + panneaux Indication/Corrigé ---------- */
.exo-statement { margin: 10px 0 4px; }
.exo-statement .content { min-height: 1.2em; }

/* Panneaux affichés SOUS la barre d'actions */
.exo-panel {
    margin: 12px 0 2px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    overflow: hidden;
}
.exo-panel-hint     { border-left: 3px solid var(--hint); }
.exo-panel-solution { border-left: 3px solid var(--content-proof); }
.exo-panel-label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 6px 10px 0;
}
.exo-panel-hint .exo-panel-label     { color: var(--hint); }
.exo-panel-solution .exo-panel-label { color: var(--content-proof); }
.exo-panel .content { padding: 4px 10px 8px; }

/* ---------- Barre d'actions (séparateur + boutons + méta) ---------- */
.exo-actionbar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--border-soft);
}
.exo-actions-left {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.exo-act-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;   /* annule le min-width global de form.css */
    padding: 5px 12px;
    font-size: 0.82rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.exo-act-btn svg { width: 15px; height: 15px; }
.exo-act-btn:hover { background: var(--surface-2); color: var(--text); }
.exo-act-hint.open     { color: var(--hint); border-color: var(--hint); background: var(--hint-bg); }
.exo-act-solution.open { color: var(--content-proof);    border-color: var(--content-proof);    background: var(--content-proof-bg); }

.exo-actions-right {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-left: auto;
    font-size: 0.75rem;
    color: var(--text-faint);
}
.exo-dates { white-space: nowrap; }
.exo-est-time { white-space: nowrap; }

.exo-source-row {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 2px 1rem;
    font-size: 0.78rem;
    color: var(--text-faint);
}
.exo-source-row .exo-source-sep { display: none; }
.exo-source-label { color: var(--text-faint);     font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    flex-shrink: 0;
}
.exo-source-link {
    color: var(--text-faint);
    text-decoration: none;
    font-size: 0.78rem;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
}
.exo-source-link:hover { text-decoration: underline; }
.exo-source-link-empty { color: var(--text-faint); font-style: italic;     opacity: 0.5;
}

/* ---------- Popup Notes ---------- */
/* [hidden] doit primer sur display:flex (même spécificité) */
.exo-notes-modal[hidden],
.exo-tex-modal[hidden] { display: none !important; }
.exo-notes-modal {
    position: fixed;
    inset: 0;
    z-index: 400;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.55);
}
.exo-notes-box {
    width: min(760px, 92vw);
    min-height: 420px;
    max-height: 84vh;
    display: flex;
    flex-direction: column;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
.exo-notes-head,
.exo-tex-head {
    position: relative;
    display: flex;
    align-items: center;
    height: 44px;
    box-sizing: border-box;
    padding: 0 40px 0 16px;
    border-bottom: 1px solid var(--border);
    font-weight: 600;
    color: var(--text);
}
/* Titre centré sur toute la largeur de l'en-tête (position absolue, hors
   flux) : reste centré quel que soit l'espace pris par le statut à gauche
   ou le bouton fermer à droite. */
.exo-notes-head > span:first-child {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    pointer-events: none;
}
.exo-notes-status {
    position: relative;
    z-index: 1;
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--text-faint);
    transition: color 0.2s;
}
.exo-notes-status.saved { color: var(--success); }
.exo-notes-close {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    min-width: 0;
    width: auto;
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1;
    padding: 4px 8px;
    cursor: pointer;
}
.exo-notes-close:hover { color: var(--text); }

/* Une seule zone visible à la fois : aperçu KaTeX par défaut (double-clic
   pour éditer), CodeMirror pendant l'édition (Ctrl+Entrée pour revenir à
   l'aperçu) — cf. .is-editing sur .exo-notes-box, posé par notes_ui.js. */
.exo-notes-box:not(.is-editing) .exo-notes-editor { display: none; }
.exo-notes-box.is-editing .exo-notes-preview-label,
.exo-notes-box.is-editing .exo-notes-preview { display: none; }

/* Éditeur LaTeX — pas collé aux bords de la modale, contrairement à
   l'aperçu (qui, lui, doit se fondre visuellement avec le rendu réel). */
.exo-notes-editor {
    flex: 1;
    padding: 12px;
    overflow-y: auto;
}
.exo-notes-editor .CodeMirror {
    height: auto;
    min-height: 170px;
    max-height: 38vh;
    font-size: 13.5px;
    background: var(--inset);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px 10px;
}
.exo-notes-editor .CodeMirror-scroll { min-height: 170px; }

/* Aperçu — même police que le rendu d'un bloc (définition, etc.), cf.
   .doc-prose dans doc.css : pas de font-family dédiée, donc var(--font-body)
   (system-ui, cf. tokens.css) hérité du body. Le stack Charter/Bitstream
   Charter/Sitka Text tenté ici avant retombait sur Cambria (aucune des
   trois n'est installée sur Windows) — nettement plus dense que le reste
   du site, perçu à tort comme du gras. */
.exo-notes-preview-label {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-faint);
    padding: 10px 16px 0;
}
.exo-notes-preview {
    flex: 1;
    padding: 8px 16px 16px;
    overflow-y: auto;
    min-height: 110px;
    font-family: var(--font-body);
    font-size: 14px;
    line-height: 1.65;
    cursor: text;
}
/* Mode "aperçu KaTeX seul" (cf. notes_ui.js, katexOnly) : le texte est posé
   tel quel via textContent, sans passer par le moteur LaTeX→HTML qui aurait
   sinon traduit les retours à la ligne en paragraphes. */
.exo-notes-preview-plain { white-space: pre-wrap; }
.exo-notes-preview:empty::before {
    content: "Double-clique pour écrire une note.";
    color: var(--text-faint);
    font-style: italic;
    font-family: var(--font-body);
    font-size: 0.85rem;
}

/* ---------- Popup TeX (code non éditable) ---------- */
.exo-tex-modal {
    position: fixed;
    inset: 0;
    z-index: 400;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.55);
}
.exo-tex-box {
    width: min(760px, 92vw);
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
/* Titre centré, comme la popup Notes. */
.exo-tex-head > span:first-child {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    pointer-events: none;
}
.exo-tex-actions {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;
}
.exo-tex-actions button,
.exo-tex-actions a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    width: auto;
    background: transparent;
    border: none;
    color: var(--text-muted);
    padding: 6px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    text-decoration: none;
}
.exo-tex-actions button:hover,
.exo-tex-actions a:hover { background: var(--surface-2); color: var(--text); }
.exo-tex-actions svg { width: 16px; height: 16px; display: block; }
/* Feedback de copie : icône coche verte pendant quelques secondes */
.exo-tex-copy .exo-tex-check-icon { display: none; }
.exo-tex-copy.copied { color: var(--success); }
.exo-tex-copy.copied .exo-tex-copy-icon { display: none; }
.exo-tex-copy.copied .exo-tex-check-icon { display: block; }
/* Croix "fermer" : identique à la popup Notes (coin haut-droit, collée) */
.exo-tex-close {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    min-width: 0;
    width: auto;
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1;
    padding: 4px 8px;
    cursor: pointer;
}
.exo-tex-close:hover { color: var(--text); }
.exo-tex-cm { flex: 1; overflow: auto; }
.exo-tex-cm .CodeMirror { height: auto; min-height: 200px; }

/* =========================================================
   MODE ÉLÈVE — l'édition n'est ni visible ni possible
   (.admin-only est déjà masqué par theme.css ; ici on
   neutralise en plus les interactions d'édition résiduelles)
   ========================================================= */
body.mode-eleve .content-editable,
body.mode-eleve .inline-edit,
body.mode-eleve .difficulty,
body.mode-eleve .tags-edit,
body.mode-eleve .exo-tracks,
body.mode-eleve .exo-fav { pointer-events: none; }

/* Rangée Tags : masquée si vide en vue élève */
body.mode-eleve .meta-chip-tags:not(:has(.tag-pill)) { display: none; }

/* Indication masquée pour CET exercice (bouton ampoule barrée, SheetItem.
   hide_hint) : contrairement au corrigé (déjà admin-only), l'indication est
   visible aux élèves par défaut — ce toggle par item la retire pour eux
   seulement, sans toucher à l'énoncé/corrigé du même bloc. */
body.mode-eleve .sheet-item-hint-hidden .exo-act-hint,
body.mode-eleve .sheet-item-hint-hidden .exo-panel-hint { display: none; }

/* =========================================================
   POLISH VISUEL — se rapprocher de la maquette
   (cartes plus aérées, énoncé en serif, méta plus légère)
   ========================================================= */

/* Carte : coins plus doux, respiration */
.exercise-card { border-radius: 12px; }
.exo-body { padding: 16px 20px 12px; }
.exercise-card:has(.exo-drag-handle) .exo-body { padding-left: 42px; }

/* En-tête : titre net, très peu d'espace avant la méta (même groupe visuel) */
.exo-main-head { margin-bottom: 1px; }
.exo-title { font-size: 1.22rem; }

/* Énoncé + panneaux : police serif « maths » (perdue avec .editable-block) */
.exo-statement .content,
.exo-panel .content {
    font-family: Charter, 'Bitstream Charter', 'Sitka Text', Cambria, Georgia, serif;
    font-size: 13px;
    line-height: 1.6;
    color: var(--text);
}
/* Rupture nette avant l'énoncé : 2e chose qu'on regarde après le titre,
   elle ne doit pas se confondre avec la méta juste au-dessus. */
.exo-statement { margin: var(--space-4) 0 var(--space-2); }
.exo-statement .content { padding: 2px 0; }

/* ---------- Méta : ligne discrète type « fil d'Ariane » ----------
   Chapitre › sous-chapitre + tags affichés comme du texte simple,
   pas comme un formulaire. Les affordances d'édition (fond, bordure,
   croix de suppression, champ d'ajout) n'apparaissent qu'au survol
   ou au clic (focus) en mode admin — jamais en mode élève. */
.exercise-meta-bar {
    align-items: center;
    gap: 4px 10px;
    margin: 4px 0 2px;
    font-size: 0.82rem;
    color: var(--text-faint);
}
.meta-chip-tags {
    flex-basis: 100%;
    align-items: center;
}
.meta-label {
    font-size: 0.64rem;
    color: var(--text-faint);
    opacity: 0.9;
}

/* Pastilles de tags : texte plat séparé par un point, pas de pilule */
.tags-edit {
    gap: 5px;
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
}
.tag-pill {
    background: var(--surface-3);
    color: var(--text);
    border: none;
    padding: 1px 3px 1px 9px;
    font-size: 0.8rem;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    border-radius: 12px;
}
.tag-pill:not(:last-child)::after { content: ","; color: var(--text-faint); }
.tag-remove { display: none;     min-width: 0;
    padding: 0 4px;
    background: transparent;
    border: none;
    color: var(--text-faint);
    cursor: pointer;
    font-size: 0.7rem;
    line-height: 1;
}
.tag-add-input {
    background: var(--inset);
    border: 1px solid var(--border);
    color: var(--text);
    width: 70px;
    min-width: 70px;
    padding: 2px 8px;
    border-radius: 12px;
    font-size: 0.8rem;
}

/* Mode admin : au survol/clic sur la zone, on révèle les affordances
   d'édition (fond, bordure pointillée, croix de suppression). */
body.mode-admin .tags-edit:hover .tag-remove,
body.mode-admin .tags-edit:focus-within .tag-remove { display: inline-flex; }
body.mode-admin .tags-edit:hover .tag-pill,
body.mode-admin .tags-edit:focus-within .tag-pill {
    background: var(--surface-2);
    border: 1px solid var(--border-soft);
    padding: 1px 4px 1px 8px;
    border-radius: 999px;
}
body.mode-admin .tags-edit:hover .tag-pill::after,
body.mode-admin .tags-edit:focus-within .tag-pill::after { content: none; }
body.mode-admin .tag-add-input:hover,
body.mode-admin .tag-add-input:focus {
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    padding: 0 4px;
}

/* Barre d'actions : séparation franche du reste, boutons sobres */
.exo-actionbar { gap: 10px; margin-top: var(--space-4); padding-top: var(--space-3); }
.exo-actions-left { gap: 8px; }
.exo-act-btn {
    padding: 7px 14px;
    font-size: 0.86rem;
    border-radius: 7px;
    border-color: var(--border-soft);
    gap: 7px;
    color: var(--text-muted);
}
.exo-act-btn:hover { color: var(--text); }
.exo-act-btn svg { width: 18px; height: 18px; }
/* Icône colorée selon le rôle (le libellé reste clair) */
.exo-act-hint svg     { color: var(--hint); }
.exo-act-solution svg { color: var(--content-proof); }
.exo-act-ai-solution svg { color: var(--accent); }
.notes-icon svg       { color: var(--content-exercise); }
/* Génération IA en cours : bouton grisé, non cliquable, icône figée (pas
   d'animation coûteuse pour un aller-retour réseau généralement bref) */
.exo-act-ai-solution.is-loading,
.exo-act-ai-solution:disabled {
    opacity: 0.55;
    cursor: default;
    pointer-events: none;
}
/* Panneau vide (pas de contenu saisi) : icône et libellé grisés, même au survol */
.exo-act-btn.is-empty:not(.open),
.exo-act-btn.is-empty:not(.open) svg { color: var(--text-faint); }
.exo-act-hint:hover     { border-color: var(--hint);             background: var(--hint-bg); }
.exo-act-solution:hover { border-color: var(--content-proof);   background: var(--content-proof-bg); }
.exo-act-btn.is-empty:not(.open):hover { border-color: var(--border-soft); background: transparent; color: var(--text-faint); }
.notes-icon:hover       { border-color: var(--content-exercise); background: var(--content-exercise-bg); }
/* Notes vides : grisées au repos (règle générique ci-dessus), mais au survol
   on retrouve quand même l'icône orange (indication d'action possible) —
   juste la bordure reste bleue (accent) plutôt que orange, pour ne pas se
   confondre visuellement avec l'état "notes déjà remplies". */
.notes-icon.is-empty:not(.open):hover,
.notes-icon.is-empty:not(.open):hover svg { color: var(--content-exercise); }
.notes-icon.is-empty:not(.open):hover { border-color: var(--accent); background: transparent; }

/* Logo TeX — bouton plus imposant que les autres actions (crénage
   classique : E abaissé et resserré) */
.latex-btn {
    padding: 9px 20px;
    border-width: 1.5px;
}
.latex-btn:hover { border-color: var(--text-muted); }
.tex-logo {
    font-family: 'Spectral', Georgia, 'Times New Roman', serif;
    font-weight: 700;
    font-size: 15px;
    line-height: 1;
    letter-spacing: 0.01em;
    color: var(--text);
}
.tex-e {
    display: inline-block;
    font-size: 0.8em;
    transform: translateY(0.22em);
    margin: 0 -0.12em;
}
.exo-actions-right { gap: 14px; font-size: 0.78rem; }
.exo-actions-right > * + *::before {
    content: "•";
    margin-right: 14px;
    color: var(--text-faint);
    opacity: 0.6;
}

/* ---------- Bandeau haut de page ---------- */
.exercises-header-title {
    display: flex;
    align-items: baseline;
    gap: 14px;
    flex: 1;
}
.exercises-header-title h1 {
    margin: 0;
    text-align: left;
    font-size: 1.85rem;
}
.exercises-count {
    font-size: 0.78rem;
    color: var(--text-muted);
    background: var(--surface-2);
    border: 1px solid var(--border);
    padding: 3px 12px;
    border-radius: 999px;
    white-space: nowrap;
}

/* =========================================================
   RESPONSIVE — carte plus compacte sur petits écrans
   ========================================================= */
@media (max-width: 720px) {
    .exo-body { padding: 14px 16px 12px; }
    .exercise-card:has(.exo-drag-handle) .exo-body { padding-left: 32px; }

    .exo-main-head { gap: 6px; }
    .exo-kind-badge { font-size: 0.66rem; padding: 4px 9px; }
    .exo-id-badge { font-size: 0.7rem; padding: 4px 7px; }
    .exo-title { font-size: 1.05rem; }
    .exo-fav svg { width: 16px; height: 16px; }

    /* Les filières et la barre de variantes passent sous le titre */
    .exo-main-head-right {
        flex-basis: 100%;
        margin-left: 0;
        justify-content: flex-start;
        padding-right: 0 !important;
    }
    .exo-options-btn { top: 6px; right: 4px; }

    .exo-statement .content { font-size: 14.5px; }

    /* Actions : icônes seules, libellés masqués pour gagner de la place */
    .exo-actionbar { gap: 8px; }
    .exo-act-btn { padding: 7px 10px; font-size: 0; gap: 0; }
    .exo-act-btn svg { width: 17px; height: 17px; }
    .exo-act-btn .tex-logo { font-size: 15px; }
    .latex-btn { padding: 7px 14px; }

    /* Reste sur la même ligne que .exo-actions-left (TeX/carnet toujours
       en bas à droite), pas de retour à la ligne : seuls les libellés
       masqués (règle .exo-act-btn ci-dessus) laissent la place. */
    .exo-actions-right { font-size: 0.7rem; }

    .exercise-meta-bar { font-size: 0.76rem; }
}

/* =========================================================
   REFONTE LAYOUT — hiérarchie, alignements, rythme vertical
   (aucune couleur modifiée ici, uniquement structure/espacement)

   5 zones empilées sur le même axe gauche : HEADER › META ›
   CONTENU › ACTIONS/FOOTER. Rythme vertical basé sur l'échelle
   de tokens.css (--space-*), jamais de valeur arbitraire.
   ========================================================= */

.exo-body {
    padding: var(--space-4) var(--space-4) var(--space-3);
    display: flex;
    flex-direction: column;
}
.exercise-card:has(.exo-drag-handle) .exo-body { padding-left: 42px; }

/* ---------- HEADER : titre dominant, tout aligné verticalement ---------- */
.exo-main-head {
    align-items: center;
    gap: var(--space-2);
    margin-bottom: 0;
}
/* Titre : élément dominant du header */
.exo-title { font-size: 1.28rem; line-height: 1.25; font-weight: 650; }

/* Difficulté juste après le titre */
.exo-main-head .difficulty { order: 1; margin-left: 2px; }

/* ID discret, en toute fin du groupe gauche */
.exo-id-badge { order: 2; }

/* Favori / menu entièrement à droite */
.exo-main-head-right { gap: var(--space-3); align-items: center; }

/* ---------- META : regroupée, labels discrets, valeurs mises en avant ---------- */
.exercise-meta-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;gap: 14px;margin: 2px 0 6px;
    padding-top: 2px;
    font-size: 0.85rem;
}
.meta-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-right: 3px;
    color: var(--text-faint);
}
/* ---------- CONTENU : bloc dominant, respire largement ---------- */
.exo-statement {
    margin: var(--space-5) 0 var(--space-2);
}
.exo-statement .content {
    font-size: 13px;
    line-height: 1.7;
}

/* ---------- ACTIONS / FOOTER : même axe, groupes bien alignés ---------- */
.exo-actionbar {
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    gap: var(--space-3);
    align-items: center;
}
.exo-actions-left { gap: var(--space-2); }
.exo-actions-right { gap: var(--space-3); font-size: 0.76rem; }

/* Tous les blocs partagent le même axe gauche que le titre */
.exercise-meta-bar,
.exo-statement,
.exo-actionbar { margin-left: 0; }

/* =========================================================
   SIMPLIFICATION — ordre strict header, séparateurs, épuration
   (id, icônes pédago, filières, méta chapitre/tags, date/source
   masqués ; signet à droite ; TeX élargi et aligné en hauteur)
   ========================================================= */

.exo-main-head-right { gap: var(--space-2); }

/* Signet (favori), désormais tout à droite */
.exo-fav svg { width: 19px; height: 19px; }

/* Contenu resserré : plus de séparateurs (<hr>), rythme vertical réduit
   pour ne pas créer de vide autour d'un énoncé court. Plus de liseré
   gauche ici : la carte entière en porte déjà un (exercise_card.css/
   theme.css, .exercise-card { border-left }), un second sur l'énoncé
   faisait doublon. */
.exo-statement { margin: var(--space-3) 0; }
.exo-statement .content { padding: 0; }

/* Barre d'actions : un seul groupe compact, aligné à gauche (pas de
   colonne droite avec un couloir vide au milieu de la carte). */
/* nowrap : Indication/Corrigé (gauche) et TeX/carnet (droite) doivent
   toujours rester sur la même ligne, jamais le groupe de droite qui
   passe en dessous à l'étroit. */
.exo-actionbar {
    display: flex;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: 1px solid var(--border-soft);
}
.exo-actions-left, .exo-actions-right { flex-wrap: nowrap; min-width: 0; }
.exo-actions-right { margin-left: auto; }

/* TeX : même hauteur que les autres boutons, largeur raisonnable
   (plus besoin d'être très large : il n'est plus isolé à droite) */
.exo-act-btn.latex-btn {
    padding: 7px 22px;
    justify-content: center;
}
.exo-act-btn.latex-btn .tex-logo { font-size: 15px; }

/* ---------- Grille 2 colonnes : les cartes sont courtes (souvent une
   ligne d'énoncé), une seule colonne pleine largeur laisse trop de
   marge morte à droite du texte. ---------- */
#exercises-container {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* [hidden] doit primer sur tout style de composant qui fixe `display`
   (règle générale : ces classes redéfinissent display ailleurs dans le
   fichier, ce qui fait perdre l'effet de l'attribut hidden) */
.exo-id-badge[hidden],
.exo-tracks[hidden],
.exo-est-time[hidden],
.exo-dates[hidden],
.exo-source-row[hidden] { display: none !important; }

/* ---------- Bouton info (ⓘ) — entre les options et le signet ---------- */
.exo-info-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    min-width: 24px;
    padding: 0;
    background: transparent;
    border: none;
    color: var(--text-faint);
    cursor: pointer;
    border-radius: var(--radius-sm);
}
.exo-info-btn svg { width: 18px; height: 18px; }
.exo-info-btn:hover { color: var(--accent); background: var(--surface-2); }
.trash-purge-btn:hover { color: var(--danger); border-color: var(--danger); background: var(--surface-2); }

/* ---------- Métadonnées : colonne droite permanente, état vide illustré
   quand rien n'est sélectionné (un seul exercice affiché à la fois). ---------- */
.exo-info-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: var(--space-5) var(--space-2) var(--space-3);
}
.exo-info-empty[hidden] { display: none; }
.exo-info-empty-icon {
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius);
    background: var(--surface-2);
    color: var(--text-faint);
    margin-bottom: var(--space-3);
}
.exo-info-empty-icon svg { width: 26px; height: 26px; }
.exo-info-empty-title {
    font-family: var(--font-head);
    font-weight: 600;
    color: var(--text);
    margin-bottom: 6px;
}
.exo-info-empty-text {
    font-size: 0.84rem;
    color: var(--text-faint);
    line-height: 1.5;
    margin: 0 0 var(--space-4);
}
.exo-info-empty-preview {
    width: 100%;
    text-align: left;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border-soft);
}
.exo-info-empty-preview-label {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-faint);
    margin-bottom: var(--space-2);
}
.exo-info-empty-preview-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.exo-info-empty-preview-list li {
    font-size: 0.84rem;
    color: var(--text-muted);
    padding-left: var(--space-3);
    position: relative;
}
.exo-info-empty-preview-list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--accent);
}
.exo-info-empty-tip {
    width: 100%;
    text-align: left;
    margin-top: var(--space-4);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    background: var(--accent-dim);
    color: var(--text-muted);
    font-size: 0.8rem;
    line-height: 1.5;
}
.exo-meta-fields[hidden] { display: none !important; }
.exo-meta-fields { display: flex; flex-direction: column; gap: var(--space-2); }

/* Texte sélectionnable (copier-coller de l'ID) — le bouton-logo juste avant
   ne l'affiche que dans son title, non sélectionnable. */
.exo-meta-id-text {
    font-size: 0.78rem;
    color: var(--text-muted);
    user-select: text;
    cursor: text;
    white-space: nowrap;
}

/* ---------- Résumé (lecture seule) : même chip que sur la carte + id ---------- */
.exo-meta-summary {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--border-soft);
}
.exo-meta-id-badge {
    font-size: 0.72rem;
    font-weight: 700;
    padding: 4px 9px;
    border-radius: 6px;
    background: var(--surface-2);
    color: var(--text-faint);
}

/* ---------- Tableau compact : une ligne = un champ (label | valeur) ---------- */
.exo-meta-table { display: flex; flex-direction: column; }
.exo-meta-row {
    display: grid;
    grid-template-columns: 84px 1fr;
    column-gap: var(--space-3);
    align-items: center;
    padding: 6px 0;
    border-bottom: 1px solid var(--border-soft);
    font-size: 0.86rem;
}
.exo-meta-row:last-child { border-bottom: none; }
.exo-meta-row-label {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-faint);
}
.exo-meta-row-value { font-size: 0.86rem; color: var(--text); }


/* ---------- Groupes repliables du panneau info (Informations générales /
   Chapitres / Assignations...) — cf. exo_meta_groups.js. Chaque groupe est
   une CARTE à part entière (fond + bordure + coins arrondis), pas juste un
   séparateur de texte — demande explicite ("belle disposition"), cf.
   mockup fourni. Ouverts par défaut, pas d'état persisté. ---------- */
.exo-meta-group {
    background: var(--surface-2);
    border: 1px solid var(--border-soft);
    border-radius: 12px;
    padding: 10px 14px;
}
.exo-meta-group + .exo-meta-group { margin-top: 8px; }
.exo-meta-group-header {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    text-align: left;
    color: var(--text);
}
.exo-meta-group.collapsed .exo-meta-group-header { padding-bottom: 0; }
.exo-meta-group-icon {
    width: 30px;
    height: 30px;
    padding: 7px;
    box-sizing: border-box;
    flex: none;
    border-radius: 9px;
    background: var(--accent-soft, color-mix(in srgb, var(--accent) 16%, transparent));
    color: var(--accent);
}
.exo-meta-group-title {
    flex: 1;
    font-size: 0.94rem;
    font-weight: 700;
    color: var(--text);
}
.exo-meta-group-count {
    font-size: 0.7rem;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--surface-3);
    color: var(--text-faint);
}
.exo-meta-group-chevron { width: 16px; height: 16px; flex: none; color: var(--text-faint); transition: transform 0.15s ease, color 0.12s; }
.exo-meta-group.collapsed .exo-meta-group-chevron { transform: rotate(180deg); }
.exo-meta-group-clamp.expanded .exo-meta-group-chevron { transform: rotate(180deg); }
.exo-meta-group-body { overflow: hidden; margin-top: 8px; }
.exo-meta-group.collapsed .exo-meta-group-body { display: none; margin-top: 0; }

/* ---------- Bloc Chapitres : cliquable/repliable sur toute sa surface (pas
   seulement l'en-tête), mais SEULEMENT s'il y a vraiment une 3ᵉ ligne de
   chapitres à déplier — cf. .has-more posée par updateChapterClamp
   (core/exo_meta_groups.js) et le listener de clic délégué (même fichier).
   Rien à déplier : visibility: hidden (pas display: none) sur le chevron
   pour que l'en-tête garde la même largeur de titre — demande 2026-08-24,
   "pas de chevron ni d'effet au clic si il n'y a pas assez de chapitres".
   ---------- */
.exo-meta-group-chapters .exo-meta-group-chevron { visibility: hidden; }
.exo-meta-group-chapters.has-more .exo-meta-group-chevron { visibility: visible; }
.exo-meta-group-chapters.has-more { cursor: pointer; }
.exo-meta-group-chapters:not(.has-more) .exo-meta-group-header { cursor: default; }
/* Chevron coloré (orange, la couleur d'accent de la page) au survol de TOUT
   le bloc, pas seulement de l'en-tête — reflète la zone de clic élargie.
   Rouge DS dédié (cf. devoirs.css --devoirs-ds, même teinte que
   .devoirs-card-ds .devoirs-card-chevron:hover) quand la feuille est un DS ;
   fallback sur --accent si --devoirs-ds n'est pas défini (hors page
   Devoirs). */
.exo-meta-group-chapters.has-more:hover .exo-meta-group-chevron { color: var(--accent); }
[data-sheet-kind="ds"] .exo-meta-group-chapters.has-more:hover .exo-meta-group-chevron { color: var(--devoirs-ds, var(--accent)); }

/* ---------- En-tête épuré du panneau (logo + titre éditable + croix) ----------
   .exo-meta-summary générique (exercise_card.css, partagé avec les cartes
   exercice/devoir) reste centré ; ce modifier n'affecte QUE sheet_detail.html
   (cf. demande "logo puis titre inline, croix discrète à droite"). */
.exo-meta-summary.exo-meta-summary-header {
    justify-content: flex-start;
    gap: 12px;
    padding-right: 34px; /* laisse la place à la croix, posée en absolute */
    border-bottom: none;
    padding-bottom: 0;
}
.exo-meta-kind-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    min-width: 0;
    flex: none;
    padding: 0;
    border: none;
    border-radius: 10px;
    background: var(--surface-3);
    cursor: pointer;
    position: relative;
}
.exo-meta-kind-logo .sh-kind-icon { width: 26px; height: 26px; object-fit: contain; }
/* Logo d'environnement/preuve/bloc texte (cf. _sheet_block_toolbar.html) :
   même boîte que le logo de feuille, mais avec l'icône SVG .doc-env-icon
   (18px par défaut, cf. doc.css) plutôt qu'un <img> — agrandie ici pour
   remplir la boîte 38px de la même façon. */
.exo-meta-kind-logo .doc-env-icon { width: 22px; height: 22px; color: var(--text-muted); }
.exo-meta-kind-logo.copied::after {
    content: "Copié !";
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--surface-3);
    color: var(--text);
    font-size: 0.68rem;
    font-weight: 600;
    padding: 3px 8px;
    border-radius: 6px;
    white-space: nowrap;
    box-shadow: 0 4px 12px rgba(0,0,0,0.3);
    z-index: 1;
}
.exo-meta-header-title {
    flex: 1;
    min-width: 0;
    /* Aligné sur la hauteur du logo (38px, cf. .exo-meta-kind-logo) : sans
       ça, un titre générique (volontairement affiché vide, cf.
       Sheet.has_custom_title) s'effondrait à la hauteur d'une ligne de
       texte quasi nulle — cliquable seulement sur 3-4px, quasi impossible
       à toucher pour ouvrir l'édition. */
    min-height: 38px;
    display: flex;
    align-items: center;
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* En édition (remplacé par un <input class="inline-edit-input">, cf.
   core/inline_edit.js) : overflow:hidden ci-dessus rognait la bordure
   droite du champ — on la laisse dépasser normalement pendant l'édition. */
.exo-meta-header-title:has(.inline-edit-input) { overflow: visible; }
.exo-meta-header-title .inline-edit-input { width: 100%; box-sizing: border-box; font-size: 1.1rem; font-weight: 700; }

/* ---------- Bloc Publication/Dernière modification : ni carte, ni titre,
   jamais repliable (cf. demande) ---------- */
.exo-meta-block { margin-top: 10px; }
.exo-meta-publish-row { display: flex; align-items: center; gap: 10px; }
/* Statut : "Publié"/point vert (seul le mot, pas la date, cf. demande) ou
   "Non publié"/point rouge en italique — le reste (date) reste en couleur
   de texte neutre. */
/* Boîte bleutée autour de l'icône globe (cf. demande, mockup fourni) */
.sheet-publish-status { display: inline-flex; align-items: center; flex: 1; gap: 6px; min-width: 0; }
.sheet-publish-value {
    display: inline-flex;
    align-items: center;
    /* Espace point -> texte réduit (cf. demande) : plus petit que le gap
       général de la ligne (icône/statut/actions). */
    gap: 4px;
    font-size: 0.86rem;
    color: var(--text-muted);
}
.sheet-publish-value.sheet-publish-none { color: var(--danger, #e5555b); font-style: italic; }
.sheet-publish-value.sheet-publish-stale .sheet-publish-word { color: var(--star); }
.sheet-publish-word { color: var(--positive, #4ade80); font-weight: 700; }
.sheet-publish-sep { margin: 0 6px; color: var(--border); }
.sheet-publish-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--positive, #4ade80); flex: none; }
.sheet-publish-dot.sheet-publish-dot-none { background: var(--danger, #e5555b); }

/* Actions : deux boutons carrés à icône seule, bordure colorée (rouge =
   dépublier, vert = publier/republier) — remplace l'ancien bouton texte +
   menu déroulant, cf. mockup fourni. */
.sheet-publish-actions { display: flex; gap: 8px; }
.sheet-publish-icon-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    min-width: 0;
    padding: 0;
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
}
.sheet-publish-icon-btn svg { width: 17px; height: 17px; }
.sheet-publish-icon-unpublish { border: 1px solid var(--danger, #e5555b); color: var(--danger, #e5555b); }
.sheet-publish-icon-unpublish:hover { background: color-mix(in srgb, var(--danger, #e5555b) 12%, transparent); }
.sheet-publish-icon-publish { border: 1px solid var(--positive, #4ade80); color: var(--positive, #4ade80); }
.sheet-publish-icon-publish:hover { background: color-mix(in srgb, var(--positive, #4ade80) 12%, transparent); }
/* Même DA que la ligne Publication juste au-dessus : icône encadrée
   (.exo-meta-group-icon, réutilisée telle quelle), libellé/valeur alignés
   sur la même grille horizontale. */
.exo-meta-icon-row { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.exo-meta-icon-row-label { flex: 1; font-size: 0.86rem; color: var(--text); }
.exo-meta-icon-row-value { font-size: 0.86rem; color: var(--text-faint); font-weight: 600; }

/* ---------- Détails supplémentaires : grille simple 2 colonnes, sans icône
   ni fond de carte propre à chaque cellule (contrairement à l'ancienne
   .exo-meta-icon-grid) ---------- */
.exo-meta-simple-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; }
.exo-meta-simple-cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* Cellule "fusionnée" (comme un colspan) : réservée aux valeurs dont le
   contenu est de longueur variable (ex. pastilles de filières) — sur la
   seule colonne de gauche, ce contenu se serait retrouvé à retomber à la
   ligne bien plus tôt qu'avec toute la largeur du panneau disponible. */
.exo-meta-simple-cell-full { grid-column: 1 / -1; }
.exo-meta-simple-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-faint); }
.exo-meta-simple-value { font-size: 0.88rem; color: var(--text); }

/* ---------- Chapitres : pastilles + champ texte (même pattern que
   .tags-edit/.tag-add-input des tags/usages d'exercice, cf.
   exercise_meta.js) — pas de menu qui s'ouvre/se ferme. 2 lignes visibles
   par défaut, le reste derrière un badge "+N" posé dynamiquement par
   updateChapterClamp (cf. core/exo_meta_groups.js) — jamais un scroll
   interne, déplié via le chevron de l'en-tête du groupe
   (.exo-meta-group-clamp.expanded) ou un clic sur le badge lui-même
   (devenu bouton "−" une fois déplié, pour re-réduire). ---------- */
.chapter-tags { display: block; }
.chapter-tags-list {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    gap: 8px;
    /* 3 lignes : 2 de pastilles (+ le badge "+N" qui partage la 2ᵉ, cf.
       updateChapterClamp) et une 3ᵉ toujours réservée au champ d'ajout
       (.chapter-tag-add-input), visible même replié — demande 2026-08-24
       ("l'inline-edit toujours visible même si c'est pas déroulé"). Sans
       overflow, le contenu reste plus court que ce plafond : aucun
       changement visuel quand tout tient déjà. */
    max-height: calc(3 * (1.2em + 11px) + 16px);
    overflow: hidden;
}
.exo-meta-group-clamp.expanded .chapter-tags-list { max-height: none; overflow: visible; }
.chapter-tag-more {
    /* <button> plutôt qu'un <span> : reset des styles UA par-dessus le
       look pilule, cf. .devoirs-card-chapter-more (même principe, devoirs.css).
       Volontairement étroit (padding réduit, pas de min-width) — demande
       explicite 2026-08-23 ("largeur beaucoup plus petite") : c'est un
       compteur, pas un chip de contenu comme les pastilles de chapitre. */
    font: inherit;
    appearance: none;
    display: inline-flex;
    align-items: center;
    width: fit-content;
    /* min-width: 0 : form.css pose `button { min-width: 120px }` en global,
       qui l'emporte sur width: fit-content (min-width prime toujours sur
       width) — sans ce reset le badge "+N" restait forcé à 120px de large
       quel que soit son contenu (même bug que .devoirs-card-chapter-more,
       cf. devoirs.css, "le +2 doit être petit" 2026-08-24). */
    min-width: 0;
    white-space: nowrap;
    padding: 5px 9px;
    border-radius: 999px;
    background: var(--surface-3);
    border: 1px solid var(--border-soft);
    color: var(--text-faint);
    font-size: 0.74rem;
    font-weight: 700;
    line-height: 1.2;
    flex: 0 0 auto;
    cursor: pointer;
}
/* Pas de hover dédié sur le badge : le bloc entier est cliquable (cf.
   .exo-meta-group-chapters.has-more:hover ci-dessus), un hover propre au
   badge ferait doublon. */
.chapter-tag-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 6px 5px 12px;
    border-radius: 999px;
    background: var(--surface-3);
    border: 1px solid var(--border-soft);
    color: var(--text);
    font-size: 0.82rem;
    line-height: 1.2;
    flex: none;
}
.chapter-tag-pill-main { border-color: var(--accent); background: var(--accent-soft, color-mix(in srgb, var(--accent) 14%, transparent)); color: var(--accent); cursor: pointer; font-weight: 600; }
.chapter-tag-pill-empty { color: var(--text-faint); font-style: italic; font-weight: 400; }
/* Croix discrète : pas de zone cliquable large façon bouton, juste le
   symbole — demande explicite ("pas aussi large"). */
.chapter-tag-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text-faint);
    cursor: pointer;
    font-size: 0.68rem;
    opacity: 0.6;
    line-height: 1;
}
.chapter-tag-remove:hover { opacity: 1; color: var(--text); }
.chapter-tag-add-input {
    flex: 1;
    min-width: 110px;
    border: none;
    border-bottom: 1px dashed var(--border);
    background: transparent;
    color: var(--text);
    font-size: 0.82rem;
    padding: 5px 2px;
}
.chapter-tag-add-input::placeholder { color: var(--text-faint); }
.chapter-tag-add-input:focus { outline: none; border-bottom-color: var(--accent); }

/* ---------- Assignations : historique trié, récentes mises en avant ---------- */
.assignation-list { display: flex; flex-direction: column; gap: 6px; }
.assignation-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 9px;
    border: 1px solid var(--border-soft);
    background: var(--surface-3);
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s, background 0.15s;
}
.assignation-row:hover { background: var(--accent-soft, color-mix(in srgb, var(--accent) 12%, transparent)); }
.assignation-row-recent .assignation-classe::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--accent);
    vertical-align: middle;
}
.assignation-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex: none;
    border-radius: 7px;
    background: var(--bg-elev);
    color: var(--text-faint);
}
.assignation-avatar svg { width: 13px; height: 13px; }
.assignation-info { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; }
.assignation-classe { font-size: 0.84rem; font-weight: 700; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.assignation-classe-annee { font-weight: 400; color: inherit; }
.assignation-row-recent .assignation-classe { color: var(--text); }
.assignation-date { display: flex; align-items: center; gap: 4px; font-size: 0.74rem; color: var(--text-faint); flex: none; margin-left: auto; }
.assignation-date svg { width: 12px; height: 12px; }
/* ---------- Sources : liens du chapitre (ChapterSourceLink) ---------- */
.source-link-list { display: flex; flex-direction: column; gap: 6px; }
.source-link-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 9px;
    border: 1px solid var(--border-soft);
    background: var(--surface-3);
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s, background 0.15s;
}
.source-link-row:hover { background: var(--accent-soft, color-mix(in srgb, var(--accent) 12%, transparent)); border-color: var(--accent); }
.source-link-icon { width: 18px; height: 18px; flex: none; border-radius: 5px; object-fit: cover; }
.source-link-icon-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-elev);
    color: var(--text-faint);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
}
.source-link-name { flex: 1; min-width: 0; font-size: 0.82rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.source-link-pages { font-size: 0.74rem; color: var(--text-faint); flex: none; }

/* Masquées par défaut, révélées par le chevron de l'en-tête OU le lien
   "Voir toutes les assignations" — les deux pilotent le même état
   (.exo-meta-group.expanded), cf. demande ("pas vraiment rétractable"). */
.assignation-list-more { display: none; flex-direction: column; gap: 8px; margin-top: 8px; }
.exo-meta-group.expanded .assignation-list-more { display: flex; }
.assignation-toggle-more {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    min-width: 0;
    margin-top: 10px;
    padding: 7px;
    border: none;
    background: transparent;
    color: var(--text-faint);
    font-size: 0.8rem;
    cursor: pointer;
}
.assignation-toggle-more:hover { color: var(--text); }
.assignation-toggle-more svg { width: 13px; height: 13px; transition: transform 0.15s ease; }
.exo-meta-group.expanded .assignation-toggle-more svg { transform: rotate(180deg); }

/* ---------- Boutons de bascule bas de panneau (preuves/todos/notes/notions)
   : icônes rondes plus grandes, distinctes, façon mockup. ---------- */
.exo-meta-toggles { display: flex; gap: 8px; margin-top: 8px; }
.exo-meta-toggles .doc-header-icon-btn {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    border: 1px solid var(--border-soft);
    background: var(--bg-elev);
}
.exo-meta-toggles .doc-header-icon-btn.active:not(.doc-header-icon-proof):not(.doc-header-icon-todo):not(.doc-header-icon-hint):not(.doc-header-icon-toc) {
    background: var(--star-soft, color-mix(in srgb, var(--star) 18%, transparent));
    border-color: var(--star);
    color: var(--star);
}
.exo-meta-toggles .doc-header-icon-btn.has-notes { border-color: var(--accent); color: var(--accent); }
/* Notes/Notions groupés à droite de la rangée, Preuves/Todos/Modifier à
   gauche (demande 2026-08-23) : un seul margin-left:auto sur le premier
   des deux suffit à pousser tout le groupe qui le suit. Notions précède
   Notes dans le HTML (cf. _sheet_info_panel.html) : c'est donc LUI qui
   porte le margin-left:auto quand il est présent (sinon le gap se
   formait entre Notions et Notes au lieu de devant Notions, cf. capture
   2026-08-26 — bug corrigé). */
.exo-meta-toggles .notes-icon { margin-left: auto; }
.exo-meta-toggles .sheet-notions-btn { margin-left: auto; }
.exo-meta-toggles .sheet-notions-btn + .notes-icon { margin-left: 0; }
/* "Modifier" (liste /devoirs/ uniquement, remplace Preuves/Todos, cf.
   _sheet_info_panel.html) : bouton large icône+texte plutôt qu'une icône
   carrée isolée — demande explicite ("assez large"), prend toute la place
   laissée par les deux toggles qu'il remplace. */
/* Même style que .exo-meta-import-btn (pilule contour accent), demande
   explicite — hauteur/largeur adaptées pour s'insérer dans la rangée
   d'icônes 32px plutôt qu'en pleine largeur sur sa propre ligne. */
/* "Assigner" (2026-09-19) : même pilule que Modifier, juste à sa gauche —
   deux actions de même poids sur un devoir, elles doivent se ressembler. */
.exo-meta-toggles .sheet-edit-btn,
.exo-meta-toggles .sheet-assign-btn {
    width: fit-content;
    height: 32px;
    flex: 0 0 auto;
    justify-content: center;
    gap: 8px;
    padding: 0 14px;
    border: 1px solid var(--accent);
    border-radius: 10px;
    background: transparent;
    color: var(--accent);
    font-weight: 600;
    font-size: 0.88rem;
    text-decoration: none;
}
/* transform: none pour annuler le scale(1.03) de .doc-header-icon-btn:hover
   (cf. doc.css) : sur ce bouton icône+texte, l'agrandissement fait "monter"
   visuellement le texte, effet non désiré ici. */
.exo-meta-toggles .sheet-edit-btn:hover,
.exo-meta-toggles .sheet-assign-btn:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: var(--accent); color: var(--accent); transform: none; }
/* Le SVG de base (.doc-header-icon-btn svg) est en position:absolute + inset:0
   pour se centrer dans un bouton carré icône-seule (cf. doc.css) — ici le
   bouton contient icône+texte côte à côte, donc on repasse le logo en flux
   normal plutôt que superposé au centre du bouton. */
/* Rangée d'un devoir : Assigner + Modifier + Notes + Sujet + Corrigé, soit
   12px de trop pour la largeur du panneau — les deux pilules se resserrent
   (14px -> 8px de padding) plutôt que de laisser "Corrigé" tomber seul sur
   une 2e ligne. Ciblé par la présence d'Assigner : une feuille sans lui
   (colle) garde des pilules larges, la rangée y tient sans problème. */
.exo-meta-toggles .sheet-assign-btn,
.exo-meta-toggles .sheet-assign-btn ~ .sheet-edit-btn { padding: 0 8px; }
.exo-meta-toggles .sheet-edit-btn svg,
.exo-meta-toggles .sheet-assign-btn svg { position: static; margin: 0; inset: auto; width: 15px; height: 15px; flex: none; }

/* Champs pouvant devenir longs (chapitres, feuilles, tags, usages,
   positions) : hauteur clampée à ~3 lignes plutôt que de pousser tout le
   reste du panneau vers le bas. Le petit chevron (enfant du conteneur, pas
   un sibling — certaines de ces valeurs vivent dans une grille 2 colonnes
   .exo-meta-row, où un 3e sibling irait se placer dans une ligne implicite
   sous le label) n'est ajouté/affiché par core/meta_field_collapse.js QUE
   si le contenu déborde réellement (`.has-overflow`), donc invisible pour
   un champ court. */
.exo-meta-collapsible {
    max-height: 4.4em;
    overflow: hidden;
    position: relative;
}
.exo-meta-collapsible.has-overflow { padding-bottom: 16px; }
.exo-meta-collapsible.expanded { max-height: none; }
.exo-meta-collapse-toggle {
    display: none;
    position: absolute;
    right: 0;
    bottom: 0;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 16px;
    padding: 0;
    border: none;
    border-radius: 4px;
    background: var(--surface-2);
    color: var(--text-faint);
    cursor: pointer;
    font-size: 0.65rem;
    line-height: 1;
}
.exo-meta-collapsible.has-overflow .exo-meta-collapse-toggle { display: flex; }
.exo-meta-collapse-toggle:hover { background: var(--surface-3); color: var(--text); }

.exo-meta-positions { display: flex; flex-wrap: wrap; gap: 4px 10px; font-variant-numeric: tabular-nums; }

/* ---------- Panneau "Variantes" (visibilité par feuille, drag reorder) ---------- */
.exo-meta-row-variants { grid-template-columns: 1fr; row-gap: 4px; }
/* max-height + overflow-y propres : sans ça, une famille avec beaucoup de
   variantes peut dépasser le bas de .exo-info-panel (lui-même scrollable,
   mais ancré à la fenêtre) au point de rendre certaines lignes inatteignables
   au scroll. */
.variant-panel { display: flex; flex-direction: column; gap: 2px; width: 100%; max-height: 21vh; overflow-y: auto; }
.variant-panel-row {
    display: grid;
    grid-template-columns: auto 1fr auto auto auto;
    align-items: center;
    gap: 8px;
    padding: 4px 6px;
    border-radius: 6px;
    cursor: pointer;
}
.variant-panel-row:hover { background: var(--surface-2); }
.variant-panel-row.dragging { opacity: 0.85; }
/* Variante actuellement affichée sur la carte (comparée à `exo.id` côté
   template, cf. `variant-panel-row-current`) — même code couleur que
   .vbar-menu-current (theme.css) pour rester cohérent avec le menu
   déroulant de la barre de variantes. */
.variant-panel-row-current { background: var(--surface-2); }
.variant-panel-row-current .variant-panel-title { color: var(--violet); font-weight: 600; }
/* min-width:0 nécessaire : le `button { min-width: 120px }` générique de
   form.css n'est pas surchargé par une règle de padding/taille plus
   spécifique, donc sans ça ces icônes deviennent des gros boutons
   rectangulaires (cf. commentaire identique sur .vlink-close, theme.css). */
.variant-panel-eye,
.variant-panel-unlink {
    background: none;
    border: none;
    min-width: 0;
    cursor: pointer;
    line-height: 1;
}
.variant-panel-eye {
    padding: 2px;
    color: var(--accent);
    display: inline-flex;
    align-items: center;
}
.variant-panel-eye:hover { background: var(--surface-3); border-radius: 4px; }
.variant-panel-eye svg { width: 16px; height: 16px; display: block; }
/* Même pattern que .context-banner-hide-toggle (exercises/index.html) : un
   seul SVG, le trait `.eye-slash` bascule en opacité plutôt que d'échanger
   deux emoji 👁/🙈 en JS. */
.variant-panel-eye .eye-slash { opacity: 0; transition: opacity 0.1s; }
.variant-panel-eye.variant-panel-eye-off .eye-slash { opacity: 1; }
.variant-panel-eye.variant-panel-eye-off { color: var(--text-faint); }
.variant-panel-title {
    font-size: 0.82rem;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Masquée dans cette feuille (œil barré) : même code couleur que le menu
   déroulant de la barre de variantes (vbar-menu-item-hidden, theme.css) —
   texte grisé plutôt que blanc, pour repérer d'un coup d'œil ce qui est
   visible dans la feuille sans avoir à lire l'icône œil. */
.variant-panel-row-hidden .variant-panel-title { color: var(--text-faint); font-style: italic; }
.variant-panel-unlink {
    color: var(--text-faint);
    font-size: 0.78rem;
    padding: 2px 4px;
}
.variant-panel-unlink:hover { color: var(--danger, #f85149); }
.variant-panel-handle {
    cursor: grab;
    color: var(--text-faint);
    font-size: 0.9rem;
    touch-action: none;
}
.exo-meta-row .tags-edit { flex-wrap: wrap; }

/* Réglages de la feuille (sommaire/preuves/todos/notes) déportés dans le
   panneau info — mêmes boutons .doc-header-icon-btn que l'ancienne barre
   d'outils de la sidebar, juste regroupés ici sous le tableau. */
.exo-meta-toggles {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px solid var(--border-soft);
}

/* ---------- Feuilles contenant l'exercice ---------- */
.exo-meta-sheets { display: flex; flex-direction: column; gap: 4px; }
.exo-meta-sheet-link {
    font-size: 0.86rem;
    color: var(--accent);
    text-decoration: none;
}
.exo-meta-sheet-link:hover { text-decoration: underline; }

/* ---------- TeX / Notes : bas du panneau info, cohérent entre tous les
   types de carte (cf. sheet_detail.html) ---------- */
.exo-meta-footer-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    border-top: 1px solid var(--border-soft);
}
/* Bouton Notes toujours collé à droite de la rangée (exercice, item de
   feuille...), quel que soit ce qui précède (latex-btn ou rien) — demande
   2026-08-26. */
.exo-meta-footer-actions .notes-icon { margin-left: auto; }
.exo-meta-variants-link {
    font-size: 0.88rem;
    color: var(--accent);
    text-decoration: none;
}
.exo-meta-variants-link:hover { text-decoration: underline; }

/* =========================================================
   PANNEAU INFO (ⓘ) — masqué par défaut, ouvert par exo_info.js qui
   y déplace le .exo-meta-fields de la carte cliquée (pas de copie).
   ========================================================= */
.exo-info-panel[hidden] { display: none !important; }
.exo-info-panel {
    position: fixed;
    top: var(--nav-height);
    right: 0;
    bottom: 0;
    width: min(400px, 100vw);
    box-sizing: border-box;
    /* Padding uniforme : le bouton fermer n'est plus posé au-dessus du
       contenu (ce qui réservait une bande morte en haut du panneau) mais
       aligné sur la même ligne que .exo-meta-summary (EXERCICE N / id),
       cf. .exo-info-panel-close ci-dessous. */
    padding: 20px;
    overflow-y: auto;
    background: var(--bg-elev);
    border-left: 1px solid var(--border);
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.35);
    z-index: 300;
}
/* Plus discrète (cf. demande) : pas de boîte/bordure, juste l'icône, un
   fond léger n'apparaît qu'au survol. */
.exo-info-panel-close {
    position: absolute;
    /* Même ligne que .exo-meta-summary (logo + titre), qui démarre juste
       après le padding du panneau — plus de bande vide au-dessus. */
    top: 22px;
    right: 18px;
    box-sizing: border-box;
    width: 30px;
    height: 30px;
    min-width: 0;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-faint);
    font-size: 1.3rem;
    cursor: pointer;
}
.exo-info-panel-close:hover { background: var(--surface-2); color: var(--text); }
/* Le bouton fermer est au-dessus du contenu (padding-top du panneau), plus
   besoin de réserver 40px sur toute la hauteur du panneau — ça laissait de
   l'espace mort à droite de chaque ligne. */
.exo-info-panel-body { padding-right: 0; }
.exo-info-btn.active { color: var(--accent); background: var(--surface-2); border-color: var(--accent); }

/* Bouton "Importer des exercices" du panneau info (_sheet_info_panel.html) :
   déplacé depuis sheet_detail.css, qui n'est pas chargé sur toutes les pages
   utilisant ce panneau (ex. /devoirs/) — sans ces règles le svg s'affichait
   à sa taille naturelle (viewBox 24x24 mais sans contrainte de largeur du
   lien flex), énorme. Contour, pas rempli (cf. demande, mockup fourni) :
   distingue "Importer" d'une action primaire comme Publier — fond neutre,
   bordure/texte/icône en accent. */
.exo-meta-import-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    box-sizing: border-box;
    margin-top: var(--space-3);
    padding: 10px;
    border: 1px solid var(--accent);
    border-radius: 10px;
    background: transparent;
    color: var(--accent);
    font-weight: 600;
    font-size: 0.88rem;
    text-decoration: none;
    cursor: pointer;
}
.exo-meta-import-btn svg { width: 15px; height: 15px; flex: none; }
.exo-meta-import-btn:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }

/* Variante rouge (danger) — suppression de la feuille, cf. sheet-delete-btn */
.exo-meta-delete-btn { border-color: var(--danger); color: var(--danger); }
.exo-meta-delete-btn:hover { background: color-mix(in srgb, var(--danger) 10%, transparent); }

/* =========================================================
   COMPOSITION EN L — rail (type + difficulté) + bloc de contenu,
   au lieu d'empiler des bandes pleine largeur. Casse la monotonie
   horizontale répétée à chaque carte.
   ========================================================= */
.exo-layout {
    display: flex;
    align-items: stretch;
    gap: var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--border-soft);
}

/* Rail : colonne étroite, repère visuel constant à gauche de chaque carte */
.exo-rail {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    padding-top: 2px;
}
.exo-kind-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 4px 10px;
    border-radius: 7px;
    background: var(--accent);
    color: #fff;
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    white-space: nowrap;
}
.exo-kind-chip.exo-kind-question_cours { background: var(--content-proof); }

/* Types "Exercice" et "Problème" : pas de pavé de couleur, juste icône +
   libellé en violet (carte + panneau d'infos). */
.exo-kind-chip.exo-kind-exercice,
.exo-kind-chip.exo-kind-probleme {
    padding: 4px 8px;
    gap: 5px;
    background: none;
    color: var(--content-exercise-doc);
}
.exo-kind-chip.exo-kind-exercice .doc-env-icon,
.exo-kind-chip.exo-kind-probleme .doc-env-icon { width: 16px; height: 16px; color: var(--content-exercise-doc); }
.exo-kind-chip.exo-kind-exercice .doc-env-label,
.exo-kind-chip.exo-kind-probleme .doc-env-label { font-family: var(--font-head); letter-spacing: 0.03em; }

.difficulty-rail {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 1px;
    font-size: 0.8rem;
    letter-spacing: 1px;
    opacity: 0.85;
}
.difficulty-rail:hover { opacity: 1; }

/* Bloc principal : titre → énoncé → actions, jamais étiré pleine largeur */
.exo-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.exo-main-head { margin-bottom: 0; }

/* =========================================================
   COLONNE DE LECTURE — largeur capée pour le confort de lecture.
   Le vide résiduel à droite reste un simple repère de marge
   (filet vertical discret), pas une zone à combler.
   ========================================================= */
.exo-reading-col {
    max-width: 1200px;
    position: relative;
}
.exo-reading-col::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(100% + 48px);
    width: 1px;
    background: var(--border-soft);
}
@media (max-width: 1100px) {
    .exo-reading-col::after { display: none; }
}

/* =========================================================
   RESSERREMENT TYPO + UNIFORMISATION DES BOUTONS
   (police plus petite, actions alignées sur la taille des
   boutons de la page feuille : doc-tool-btn / doc-header-icon-btn)
   ========================================================= */

.exo-title { font-size: 1rem; font-weight: 600; }
.exo-statement .content,
.exo-panel .content {
    font-size: 13px;
    line-height: 1.55;
}
.exo-meta-summary-title { font-size: 0.92rem; }

/* Barre d'actions : boutons tous à la même hauteur/police, même style
   sobre (bordure + fond) que les icônes de la page feuille */
.exo-act-btn {
    height: 30px;
    padding: 0 12px;
    font-size: 0.78rem;
    border-color: var(--border);
    background: var(--surface-2);
}
.exo-act-btn svg { width: 14px; height: 14px; }
.exo-act-btn.latex-btn { padding: 0 16px; }
.exo-act-btn.latex-btn .tex-logo { font-size: 15px; }

/* Points d'options (⋮) et info (ⓘ) : collés dans le coin haut-droit de la
   carte, même carré que .doc-tool-btn (feuille) — bordure + fond, 24x24 */
.exercise-card { padding-top: 0; }
/* .editable-card (editable.css, chargé après) impose padding: 10px 20px sur la
   carte elle-même, en plus du padding de .exo-body : neutralisé ici pour ne
   garder qu'un seul padding (celui de .exo-body). */
.exercise-card.editable-card { padding: 0; }
/* Corps de carte : même gabarit que .doc-env (blocs des autres pages) */
.exo-body { padding: 14px 18px 14px !important; }
/* La poignée de drag flotte désormais à droite, hors du cadre (cf. plus haut) :
   plus besoin de réserver de la place à gauche pour elle (neutralise les
   anciennes réservations `padding-left` plus haut dans ce fichier). */
.exercise-card:has(.exo-drag-handle) .exo-body { padding-left: 18px !important; }
.exo-info-btn,
.exo-fav,
.trash-restore-btn,
.trash-purge-btn {
    position: absolute;
    top: 6px;
    width: 24px;
    height: 24px;
    min-width: 24px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    border-radius: var(--radius-sm);
    color: var(--text-faint);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    cursor: pointer;
}
.exo-info-btn { right: 34px; }
.exo-info-btn svg { width: 18px; height: 18px; }

/* ---------- Petits boutons toggle (favori/coeur, info…) ----------
   Même mécanique que .doc-toggle-icon-btn (doc.css : sommaire/preuves/
   todos de la page feuille), déclinée pour des boutons plus petits (24px,
   contre 32px) — survol avec léger scale/ombre, animation press/pop au
   clic (classes posées par nav.js, cf. "PETITS BOUTONS TOGGLE"). Couleur
   active/inactive gérée séparément par chaque bouton (.exo-fav.active,
   .exo-info-btn.active…), pas par cette classe. */
.doc-toggle-icon-btn-sm {
    transition: background 0.12s, border-color 0.12s, color 0.18s ease, transform 0.08s ease, box-shadow 0.12s;
}
.doc-toggle-icon-btn-sm:hover {
    transform: scale(1.06);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
}
.doc-toggle-icon-btn-sm.icon-btn-press { transform: scale(0.92); }
.doc-toggle-icon-btn-sm.icon-btn-pop { animation: docIconBtnPop 0.2s ease; }
/* Favori : juste à gauche du bouton info quand les deux sont visibles */
.exo-fav { right: 62px; padding: 0; }
.exo-main-head-right { padding-right: 92px; }
/* Le 3e emplacement (right: 6px) est occupé par .exo-delete-btn /
   .add-to-sheet-btn — un seul à la fois selon le contexte (voir
   editable.css, "SLOT D'ACTION ADAPTATIF"), jamais l'ancien ⋮ (supprimé :
   le clic droit fait déjà doublon pour dupliquer/éditer). */

/* Carte d'exercice dans une feuille (.no-action-slot, cf. _exercise_card.html) :
   pas de 3e bouton (retirer/supprimer passe par le clic droit du bloc,
   cf. doc-block-ctx-menu) — en mode prof, favori et info se décalent d'un
   cran vers la droite pour combler l'emplacement vide. Sans effet en mode
   élève : l'info et le 3e emplacement y sont déjà masqués (.admin-only) et
   le favori déjà repositionné en right:6px (cf. body.mode-eleve .exo-fav). */
body.mode-admin .exercise-card.no-action-slot .exo-fav { right: 34px; }
body.mode-admin .exercise-card.no-action-slot .exo-info-btn { right: 6px; }

/* Cacher / Cacher l'indication (in_sheet uniquement, cf. _exercise_card.html) :
   deux crans de plus à gauche du favori — même mécanique (absolu, 24px,
   masqué hors survol sauf actif) que .exo-info-btn/.exo-fav ci-dessus. */
.doc-hide-item-btn,
.exo-hide-hint-btn {
    position: absolute;
    top: 6px;
    width: 24px;
    height: 24px;
    min-width: 24px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    border-radius: var(--radius-sm);
    color: var(--text-faint);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s, background 0.12s, border-color 0.12s, color 0.18s ease, transform 0.08s ease, box-shadow 0.12s;
}
.doc-hide-item-btn svg,
.exo-hide-hint-btn svg { width: 18px; height: 18px; }
.exo-hide-hint-btn { right: 90px; }
.doc-hide-item-btn { right: 118px; }
.doc-hide-item-btn.active,
.exo-hide-hint-btn.active { opacity: 1; pointer-events: auto; color: var(--star); }
:is(.exercise-card, .doc-block):hover .doc-hide-item-btn,
:is(.exercise-card, .doc-block):focus-within .doc-hide-item-btn,
:is(.exercise-card, .doc-block):hover .exo-hide-hint-btn,
:is(.exercise-card, .doc-block):focus-within .exo-hide-hint-btn {
    opacity: 1;
    pointer-events: auto;
}
/* Réserve la place des deux boutons en plus (148 = 118 + 24 + 6 de marge) */
.exo-main-head-right:has(.doc-hide-item-btn) { padding-right: 148px; }
/* .doc-block (environnement/preuve, cf. _sheet_block_toolbar.html) n'a
   jamais de 3e bouton (pas de add-to-sheet/delete dans ce slot) : même
   décalage que .no-action-slot ci-dessus, mais permanent. */
body.mode-admin .doc-block .exo-fav-heart { right: 34px; }
body.mode-admin .doc-block .exo-info-btn { right: 6px; }

/* Info + 3e emplacement : masqués tant que la souris n'est pas sur la
   carte (ou qu'un élément de la carte n'a pas le focus). Le favori suit
   la même règle SAUF quand il est actif, où il reste visible en
   permanence — voir plus bas. */
.exo-info-btn,
.exo-delete-btn,
.add-to-sheet-btn,
.trash-restore-btn,
.trash-purge-btn {
    opacity: 0;
    pointer-events: none;
    /* .doc-toggle-icon-btn-sm (exercise_card.css, plus haut) ajoute son
       propre transform/box-shadow au survol/press/pop : listés ici aussi
       pour ne pas les écraser (une seule déclaration `transition` gagne
       par sélecteur, elle ne fusionne pas avec les autres règles). */
    transition: opacity 0.12s, background 0.12s, border-color 0.12s, color 0.18s ease, transform 0.08s ease, box-shadow 0.12s;
}
/* Info : reste visible en permanence tant que le panneau lui est ouvert
   (classe .active posée/retirée par exo_info.js), même règle que .exo-fav
   ci-dessous. */
.exo-info-btn.active { opacity: 1; pointer-events: auto; }
:is(.exercise-card, .doc-block):hover .exo-info-btn,
:is(.exercise-card, .doc-block):focus-within .exo-info-btn,
:is(.exercise-card, .doc-block):hover .exo-delete-btn,
:is(.exercise-card, .doc-block):focus-within .exo-delete-btn,
:is(.exercise-card, .doc-block):hover .add-to-sheet-btn,
:is(.exercise-card, .doc-block):focus-within .add-to-sheet-btn,
:is(.exercise-card, .doc-block):hover .trash-restore-btn,
:is(.exercise-card, .doc-block):focus-within .trash-restore-btn,
:is(.exercise-card, .doc-block):hover .trash-purge-btn,
:is(.exercise-card, .doc-block):focus-within .trash-purge-btn {
    opacity: 1;
    pointer-events: auto;
}

/* Favori : emplacement fixe (2e slot, à gauche du bouton info) — ne
   bouge plus jamais au survol, seule son opacité change. Visible en
   permanence si actif ; sinon masqué hors survol/focus. En mode élève,
   info/supprimer sont masqués (admin-only) donc le favori devient le
   seul bouton et se déplace tout à droite (voir plus bas). */
.exo-fav {
    right: 62px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s, background 0.12s, border-color 0.12s, color 0.18s ease, transform 0.08s ease, box-shadow 0.12s;
}
.exo-fav.active { opacity: 1; pointer-events: auto; }
:is(.exercise-card, .doc-block):hover .exo-fav,
:is(.exercise-card, .doc-block):focus-within .exo-fav {
    opacity: 1;
    pointer-events: auto;
}
body.mode-eleve .exo-fav.active { opacity: 1; }
body.mode-eleve .exo-fav { right: 6px; }

/* Corbeille : réutilise les mêmes emplacements (info à 34px déjà pris par
   le bouton métadonnées) — restaurer prend la place de favori, purger celle
   des options, pour ne pas superposer les boutons. */
.trash-restore-btn { right: 62px; }
.trash-purge-btn { right: 6px; }
.trash-restore-btn svg,
.trash-purge-btn svg { width: 18px; height: 18px; }
.trash-restore-btn:hover { color: var(--accent); background: var(--surface-2); border-color: var(--accent); }

/* Les étoiles de difficulté suivent l'ordre du DOM (entre le badge type
   et le titre), pas l'ordre flex hérité de l'ancien rail vertical */
.exo-main-head > .difficulty-rail { order: 0; margin-left: 0; margin-right: 6px; }


/* ---- Mode sélection (Cours & TD utilisé comme sélecteur chapitre/feuille) ---- */
.doc-chapter-select-current > summary { background: var(--surface-2); }
.doc-chapter-select-badge {
    display: flex;
    align-items: center;
    color: var(--accent, #4a9eff);
    flex-shrink: 0;
}
.doc-chapter-select-badge svg { width: 18px; height: 18px; display: block; }
.doc-chapter-select-all-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-left: auto;
    flex-shrink: 0;
    padding: 4px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
}
.doc-chapter-select-all-btn:hover { background: var(--surface-2); color: var(--accent, #4a9eff); }

#exercises-container.hide-already-in-sheet .already-in-sheet { display: none; }

/* Bandeau "Exercice non vérifié" (import automatique pas encore relu) */
.exo-unverified-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding: 6px 10px;
    border-radius: var(--radius-sm, 6px);
    background: color-mix(in srgb, var(--danger, #d9534f) 12%, transparent);
    border: 1px solid var(--danger, #d9534f);
    color: var(--danger, #d9534f);
    font-size: 0.85em;
    font-weight: 600;
}
.exo-unverified-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--danger, #d9534f);
    color: #fff;
    font-size: 0.7em;
    flex-shrink: 0;
}
.exo-unverified-label { flex: 1; }
.exo-unverified-verify-btn,
.exo-generation-retry-btn {
    border: 1px solid var(--danger, #d9534f);
    background: transparent;
    color: var(--danger, #d9534f);
    border-radius: var(--radius-sm, 6px);
    padding: 3px 10px;
    font-size: 0.9em;
    font-weight: 600;
    cursor: pointer;
}
.exo-unverified-verify-btn:hover,
.exo-generation-retry-btn:hover { background: var(--danger, #d9534f); color: #fff; }
.exo-unverified-verify-btn:disabled,
.exo-generation-retry-btn:disabled { opacity: 0.5; cursor: default; }

/* Bandeau warnings LaTeX heuristiques (cf. importer/warnings.py), même
   détecteur que la review d'import — couleur --hint (jaune) pour se
   distinguer du rouge "non vérifié"/"échec génération" au-dessus. */
.exo-warning-banner {
    align-items: flex-start;
    background: color-mix(in srgb, var(--hint) 12%, transparent);
    border-color: var(--hint);
    color: var(--hint);
}
.exo-warning-banner .exo-unverified-icon { background: var(--hint); }
.exo-warning-list {
    margin: 0;
    padding-left: 1.1em;
    flex: 1;
    font-weight: 400;
}
.exo-warning-list li { line-height: 1.4; }

/* ---------- Carte minimaliste de session de colle (demande 2026-09-15) ----
   Pas de "boîte dans la boîte" : la carte elle-même disparaît (ni fond, ni
   bordure, ni liseré, ni padding), seul l'énoncé est encadré, au plus large
   et avec un padding minimal. Le commentaire reste dessous. Tout le reste
   (barre d'actions Indication / Corrigé / Info / Retirer) n'apparaît qu'au
   clic sur la carte (.is-open, posé par session_exercise_card.js).

   !important ici : le fond/la bordure des cartes viennent de theme.css
   (`.editable-card, .exercise-card`), chargé APRÈS ce fichier, et le padding
   du corps est lui-même déclaré `!important` plus haut (ligne ~1922) — sans
   ça, aucune de ces trois annulations ne passe. */
.colle-session-card {
    background: transparent !important;
    border: none !important;
    border-radius: 0;
    box-shadow: none !important;
    cursor: pointer;
}
.colle-session-card .exo-body { padding: 0 !important; }
.colle-session-card .exo-statement { margin: 0; }

/* Barre d'options : pilule flottante d'icônes, calquée sur .fpdf-actions
   (sheet_fake_pdf.css, barre de survol d'un bloc du faux PDF) — même gabarit,
   même langage visuel, mais posée en absolu sur le coin haut droit de la
   carte plutôt qu'en flux. Masquée tant que la carte n'est pas ouverte.
   Elle chevauche volontairement le bord du cadre de l'énoncé : elle est
   transitoire, et ne doit pas décaler le texte en apparaissant. */
.colle-session-card .exo-colle-bar { display: none; }
.colle-session-card.is-open .exo-colle-bar {
    position: absolute;
    top: 0;
    right: 6px;
    transform: translateY(-50%);
    z-index: 7;
    display: flex;
    align-items: center;
    gap: 2px;
    margin: 0;
    padding: 3px 4px;
    border: 1px solid var(--border);
    border-top: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2, #12161d);
    box-shadow: 0 6px 18px -8px rgba(0, 0, 0, 0.7);
}
.exo-colle-bar-label {
    max-width: 190px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 6px 0 3px;
    font-size: 0.72rem;
    color: var(--text-faint);
}
.exo-colle-bar-sep {
    width: 1px;
    height: 16px;
    margin: 0 2px;
    background: var(--border);
    flex: none;
}
/* Boutons icône seule : on écrase le gabarit "pilule à libellé"
   d'.exo-act-btn (padding/bordure/fond), le même bouton servant ailleurs
   avec son texte. */
.colle-session-card .exo-colle-bar .exo-act-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
}
.colle-session-card .exo-colle-bar .exo-act-btn svg { width: 15px; height: 15px; }
.colle-session-card .exo-colle-bar .exo-act-btn:hover { background: var(--surface-3); color: var(--text); }
/* is-empty : champ vide côté exercice — grisé, comme ailleurs sur la carte. */
.colle-session-card .exo-colle-bar .exo-act-btn.is-empty { opacity: 0.45; }
.colle-session-card .exo-colle-solution-btn.is-active { color: var(--accent); }
.colle-session-card .exo-colle-remove-btn { color: var(--danger, #d4735c); }
.colle-session-card .exo-colle-remove-btn:hover {
    background: var(--surface-3);
    color: var(--danger, #d4735c);
}
/* Avertissements LaTeX : outil de relecture, hors sujet pendant l'oral —
   visibles seulement quand la carte est ouverte. */
.colle-session-card .exo-warning-banner { display: none; }
.colle-session-card.is-open .exo-warning-banner { display: flex; }

/* Énoncé en image exacte du PDF (session de colle, cf. .exo-colle-shot dans
   _exercise_card.html, session_exercise_shots.js). Tranches PNG à fond
   transparent et encre noire : fond blanc obligatoire en thème sombre. */
.exo-colle-shot {
    background: #fff;
    border: 1px solid var(--border-soft);
    border-radius: 4px;
    padding: 2px 4px;
    min-height: 24px;
}
.exo-colle-shot-img {
    display: block;
    max-width: 100%;
    height: auto;
    user-select: none;
}
.exo-colle-shot-status {
    display: block;
    font-size: 0.8rem;
    color: #57606a;
}
.exo-colle-shot-status.is-error { color: #cf222e; }
.exo-colle-solution-btn.is-active { color: var(--accent); }

/* Plus de filet de séparation : l'énoncé a maintenant son propre cadre, le
   commentaire se lit juste en dessous sans second trait (cf. carte
   minimaliste ci-dessus). */
.exo-colle-comment { margin-top: var(--space-2); }
.exo-colle-comment-input {
    width: 100%;
    min-height: 52px;
    resize: vertical;
    font: inherit;
    font-size: 0.85rem;
    line-height: 1.4;
    color: var(--text);
    background: var(--surface-1, transparent);
    border: 1px solid var(--border-soft);
    border-radius: 6px;
    padding: var(--space-2);
}
.exo-colle-comment-input:focus {
    outline: none;
    border-color: var(--accent, var(--border-soft));
}
.exo-colle-comment-status {
    display: block;
    margin-top: 2px;
    font-size: 0.72rem;
    color: var(--text-faint);
    transition: color 0.2s;
}
.exo-colle-comment-status.saved { color: var(--success); }
