/**
 * BOUTONS - Système centralisé CFM77
 * Source unique pour tous les boutons de l'application
 *
 * SOMMAIRE :
 * 1. Boutons rectangulaires (.button)
 * 2. Boutons icônes carrés (.button_icon)
 * 3. Boutons spéciaux (toggle, logout, back)
 * 4. Inputs stylisés (checkbox, radio)
 * 5. États et modificateurs
 * 6. Responsive
 */

/* ============================================
   1. BOUTONS RECTANGULAIRES
   Base : .button
   Taille par défaut : height 36px
   ============================================ */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 36px;
    padding: 0 16px;
    border: 1px solid transparent;
    border-radius: 6px;
    font-weight: 500;
    font-size: var(--text-small);
    font-family: inherit;
    text-decoration: none;
    cursor: pointer;
    transition: all 150ms ease;
    white-space: nowrap;
}

/* L'attribut HTML `hidden` doit toujours gagner sur le display du .button.
   Sans cette règle, `display: inline-flex` écrase la règle UA `[hidden]`. */
.button[hidden],
.button_icon[hidden] {
    display: none;
}

/* --- Variantes de couleur --- */

.button_primary {
    background-color: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}

/* UN BOUTON GRISÉ NE RÉAGIT PAS AU SURVOL – seuls le curseur interdit et l'info-bulle restent :
   un survol laisserait croire qu'il se clique. D'où le `:where(:not(...))` sur chaque `:hover`
   ici – `:where` ne pèse rien, une page qui retouche un survol garde la main. */
.button_primary:where(:not(:disabled, [aria-disabled="true"], .button_disabled)):hover {
    background-color: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
    color: var(--color-white);
}

/* LE BOUTON D'UNE ÉPREUVE – « + Créer une évaluation » sur sa carte : la couleur de sa pastille,
   posée en ligne sur la carte (`--epreuve-couleur`). Grisé, il reprend le gris du primaire. */
.button_epreuve {
    background-color: var(--epreuve-couleur, var(--color-primary));
    color: var(--color-white);
    border-color: var(--epreuve-couleur, var(--color-primary));
}

.button_epreuve:where(:not(:disabled, [aria-disabled="true"], .button_disabled)):hover {
    background-color: color-mix(in srgb, var(--epreuve-couleur, var(--color-primary)) 85%, black);
    border-color: color-mix(in srgb, var(--epreuve-couleur, var(--color-primary)) 85%, black);
    color: var(--color-white);
}

.button_epreuve[aria-disabled="true"] {
    background-color: var(--color-gray-400);
    border-color: var(--color-gray-400);
}

.button_secondary {
    background-color: var(--color-white);
    color: var(--color-gray-700);
    border-color: var(--color-gray-300);
}

.button_secondary:where(:not(:disabled, [aria-disabled="true"], .button_disabled)):hover {
    background-color: var(--color-gray-50);
    border-color: var(--color-gray-400);
}

/* Marqué : il y a quelque chose derrière ce bouton – bordure verte et pastille du compte. */
.button_marque {
    position: relative;
    border-color: var(--color-success);
    color: var(--color-success);
}

/* Marqué par quelqu'un d'autre : il y a du contenu, mais pas de celui qu'on regarde. */
.button_marque_autre {
    position: relative;
    border-color: var(--color-warning);
    color: var(--color-warning);
}

.button_marque_autre .button_compte {
    background-color: var(--color-warning);
}

/* La pastille tient le bord droit : le libellé garde le centre du bouton. */
.button_compte {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    padding: 1px 7px;
    border-radius: 9999px;
    background-color: var(--color-success);
    color: var(--color-white);
    font-size: var(--text-meta);
    font-weight: 700;
}

.button_success {
    background-color: var(--color-success);
    color: var(--color-white);
    border-color: var(--color-success);
}

.button_success:where(:not(:disabled, [aria-disabled="true"], .button_disabled)):hover {
    background-color: var(--color-success-dark, #16a34a);
    border-color: var(--color-success-dark, #16a34a);
}

.button_warning {
    background-color: var(--color-warning);
    color: var(--color-white);
    border-color: var(--color-warning);
}

.button_warning:where(:not(:disabled, [aria-disabled="true"], .button_disabled)):hover {
    background-color: var(--color-warning-dark);
    border-color: var(--color-warning-dark);
}

.button_danger {
    background-color: var(--color-white);
    color: var(--color-error);
    border-color: var(--color-error);
}

.button_danger:where(:not(:disabled, [aria-disabled="true"], .button_disabled)):hover {
    background-color: var(--color-error);
    color: var(--color-white);
}

/* --- Modificateurs de taille --- */

.button_small {
    height: 32px;
    padding: 0 12px;
    font-size: var(--text-tiny);
}

/* Un bouton posé dans une case de tableau : il prend la largeur de la case sans la dépasser,
   et rétrécit avec elle quand les colonnes se resserrent. */
.button_dans_case {
    width: 100%;
    max-width: 88px;
    min-width: 0;
    padding: 0 4px;
}

.button_tiny {
    height: 28px;
    padding: 0 10px;
    font-size: var(--text-tiny);
}

.button_full {
    width: 100%;
}

.button_fixed_width {
    min-width: 100px;
    text-align: center;
    justify-content: center;
}

.button_form {
    height: 44px;
}

/* ============================================
   2. BOUTONS ICÔNES CARRÉS
   Taille par défaut : 32x32
   Icônes : &#10005; (suppr), &#9998; (modif), &#8593; &#8595; (flèches), &#8942; (menu)
   ============================================ */

/* Base commune - IDENTIQUE pour tous */
.button_icon,
.button_icon_danger,
.button_icon_menu,
.button_icon_nu {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    margin: 0;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    background-color: var(--color-white);
    font-size: var(--text-label);
    font-family: Arial, sans-serif;
    font-weight: normal;
    line-height: 32px;
    text-align: center;
    vertical-align: middle;
    cursor: pointer;
    transition: all 150ms ease;
    box-sizing: border-box;
    color: var(--color-gray-600);
    flex-shrink: 0;
}

/* Neutre : hover en double contraste (fond gris foncé + icône blanche) pour
   rester cohérent avec le pattern danger (fond rouge + icône blanche).
   Encapsulé dans (hover: hover) pour ne pas rester collé en tactile. */
@media (hover: hover) {
    .button_icon:where(:not(:disabled, [aria-disabled="true"])):hover,
    .button_icon_menu:where(:not(:disabled, [aria-disabled="true"])):hover {
        background-color: var(--color-gray-600);
        border-color: var(--color-gray-600);
        color: var(--color-white);
    }
}

/* Marqué : il y a quelque chose derrière ce bouton – bordure verte, l'info-bulle dit quoi. */
.button_icon_marque {
    border-color: var(--color-success);
    color: var(--color-success);
}

@media (hover: hover) {
    .button_icon_marque:where(:not(:disabled, [aria-disabled="true"])):hover {
        background-color: var(--color-success);
        border-color: var(--color-success);
        color: var(--color-white);
    }
}

/* Marqué par quelqu'un d'autre : il y a du contenu, mais pas de celui qu'on regarde. */
.button_icon_marque_autre {
    border-color: var(--color-warning);
    color: var(--color-warning);
}

@media (hover: hover) {
    .button_icon_marque_autre:where(:not(:disabled, [aria-disabled="true"])):hover {
        background-color: var(--color-warning);
        border-color: var(--color-warning);
        color: var(--color-white);
    }
}

/* Danger (suppression) - bordure rouge */
.button_icon_danger {
    border-color: var(--color-error);
    color: var(--color-error);
}

@media (hover: hover) {
    .button_icon_danger:where(:not(:disabled, [aria-disabled="true"])):hover {
        background-color: var(--color-error);
        border-color: var(--color-error);
        color: var(--color-white);
    }
}

/* Nu - sans cadre ni fond : un geste discret posé à côté d'un champ (la gomme).
   Neutre au repos, rouge au survol seulement – la couleur arrive au moment où l'on
   va effacer, pas avant. Trois cadres rouges dans une même fenêtre pesaient trop. */
.button_icon_nu {
    border-color: transparent;
    background-color: transparent;
    color: var(--color-gray-500);
}

@media (hover: hover) {
    .button_icon_nu:where(:not(:disabled, [aria-disabled="true"])):hover {
        border-color: transparent;
        background-color: transparent;
        color: var(--color-error);
    }
}

/* L'ICÔNE SEULE, À LA HAUTEUR DE SA LIGNE – une corbeille au bout d'une case à cocher.
   Ni cadre, ni fond, ni carré de 32 px : posé dans une liste dont les lignes en font 20, un
   bouton d'icône ordinaire rallonge chaque ligne, et la liste double de hauteur. Il ne porte
   donc PAS `.button_icon` – c'est sa base qui impose les 32 px. */
.button_icon_ligne {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: auto;
    height: auto;
    /* Les 3 px calent l'icône sur la première ligne du texte qu'elle accompagne. */
    margin-top: 3px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-gray-400);
    cursor: pointer;
}

@media (hover: hover) {
    .button_icon_ligne:where(:not(:disabled, [aria-disabled="true"])):hover {
        color: var(--color-error);
    }
}

.button_icon_ligne svg {
    display: block;
    width: 16px;
    height: 16px;
}

/* Copie (mode copier/coller planning) - hover rose
   Encapsulé dans (hover: hover) pour ne pas rester collé en tactile. */
@media (hover: hover) {
    .button_icon_copy:where(:not(:disabled, [aria-disabled="true"])):hover {
        background-color: var(--color-copy-bg);
        border-color: var(--color-copy-border);
    }
}

/* Inline - petit bouton rond pour usage à côté d'un titre ou dans une
   cellule de tableau (ex : ouvrir une image en lightbox). Variant plus
   compact et rond que .button_icon (32px carré). */
.button_icon_inline {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    margin-left: 8px;
    padding: 0;
    background: var(--color-bg-secondary, #f1f5f9);
    color: var(--color-primary, #0891b2);
    border: 1px solid var(--color-border, #e2e8f0);
    border-radius: 50%;
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
    vertical-align: middle;
    transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}

@media (hover: hover) {
    .button_icon_inline:where(:not(:disabled, [aria-disabled="true"])):hover {
        background: var(--color-primary, #0891b2);
        color: var(--color-white);
        border-color: var(--color-primary, #0891b2);
    }
}

.button_icon_inline svg {
    display: block;
}

/* Info (rond bleu, "i" blanc) */
.button_icon_info {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    margin-left: 6px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background-color: var(--color-info);
    color: var(--color-white);
    font-family: Georgia, 'Times New Roman', serif;
    font-style: italic;
    font-weight: 700;
    font-size: 10px;
    line-height: 1;
    cursor: pointer;
    transition: all 150ms ease;
    flex-shrink: 0;
    vertical-align: middle;
}

.button_icon_info:where(:not(:disabled, [aria-disabled="true"])):hover {
    background-color: var(--color-info-dark, #1d4ed8);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.button_icon_info_small {
    width: 16px;
    height: 16px;
    font-size: 9px;
}

/* Variante petite (28x28) */
.button_icon.button_icon_small,
.button_icon_danger.button_icon_small,
.button_icon_menu.button_icon_small {
    width: 28px;
    height: 28px;
    font-size: var(--text-meta);
    line-height: 28px;
}

/* ============================================
   3. BOUTONS SPÉCIAUX
   ============================================ */

/* --- Bouton retour --- */
.button_back {
    gap: 6px;
}

/* Bouton qui fait passer d'une page à sa jumelle (gestion des séries ↔ suivi des séries,
   ↔ liste des diffusions). Les libellés n'ont pas la même longueur : sans largeur commune,
   le bouton change de taille à chaque aller-retour et l'en-tête « saute ». */
.button_bascule {
    min-width: 190px;
}

/* Posée dans la barre d'actions d'une fiche, la bascule voisine des boutons courts : la
   largeur commune n'a plus d'objet, l'en-tête de la page ne bouge pas. */
.button_bascule.button_small {
    min-width: 0;
}

/* Le geste s'annonce avant son libellé : la même flèche double que dans les barres de
   navigation, où ce bouton n'a que son icône pour se dire. */
.button_bascule::before {
    content: "⇄";
    margin-right: 8px;
    font-size: var(--text-subtitle);
    line-height: 1;
}

.button_back_arrow {
    font-size: var(--text-h3);
    line-height: 1;
}

/* --- Chevron de navigation (précédent / suivant) --- */
/* Carré encadré, toujours affiché. Grisé quand désactivé, coloré et cliquable sinon.
   À utiliser avec .button (ex. class="button button_chevron"). */
.button_chevron {
    width: 34px;
    height: 34px;
    padding: 0;
    border-color: var(--color-gray-300);
    background-color: var(--color-white);
    color: var(--color-gray-400);
    font-size: var(--text-h3);
    line-height: 1;
}

.button_chevron:not(:disabled) {
    color: var(--color-primary);
    border-color: var(--color-primary);
}

.button_chevron:not(:disabled):hover {
    background-color: var(--color-gray-100);
}

.button_chevron:disabled {
    cursor: default;
}

/* --- Bouton retour en haut --- */
.button_scroll_top {
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background-color: var(--color-white);
    color: var(--color-gray-600);
    font-size: var(--text-h2);
    font-family: Arial, sans-serif;
    line-height: 44px;
    text-align: center;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    transition: all 200ms ease;
    z-index: 900;
    opacity: 0;
    transform: translateY(12px);
    pointer-events: none;
}

.button_scroll_top.visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.button_scroll_top:hover {
    background-color: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-white);
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
}

.page_eleve .button_scroll_top {
    border-color: var(--color-role-eleve);
    color: var(--color-role-eleve);
}

.page_eleve .button_scroll_top:hover {
    background-color: var(--color-role-eleve);
    border-color: var(--color-role-eleve);
    color: var(--color-white);
}

.page_formateur .button_scroll_top {
    border-color: var(--color-role-formateur);
    color: var(--color-role-formateur);
}

.page_formateur .button_scroll_top:hover {
    background-color: var(--color-role-formateur);
    border-color: var(--color-role-formateur);
    color: var(--color-white);
}

.page_admin .button_scroll_top {
    border-color: var(--color-role-admin);
    color: var(--color-role-admin);
}

.page_admin .button_scroll_top:hover {
    background-color: var(--color-role-admin);
    border-color: var(--color-role-admin);
    color: var(--color-white);
}

/* --- Navigation flottante bas-droite --- */
.floating_nav {
    position: fixed;
    bottom: 80px;
    right: 17px;
    z-index: 900;
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
    opacity: 0;
    transform: translateX(calc(100% + 40px));
    transition: transform 300ms ease, opacity 300ms ease;
    pointer-events: none; /* invisible mais présent : ne doit pas capter les clics */
}

/* Un objet FIXÉ à l'écran se répète sur chaque page imprimée et peut en ouvrir une de
   plus, vide, à la fin du document. Ce pavé est un outil d'écran : il ne s'imprime pas. */
@media print {
    .floating_nav {
        display: none;
    }
}

.floating_nav.visible {
    opacity: 1;
    transform: translateX(0);
    pointer-events: auto;
}

.floating_nav_btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 5px;
    border: 1px solid var(--color-border);
    background: var(--color-white);
    color: var(--color-gray-600);
    font-size: var(--text-h3);
    cursor: pointer;
    text-decoration: none;
    transition: all 200ms ease;
}

.floating_nav_btn:hover {
    background-color: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}

.floating_nav_btn_disabled {
    opacity: 0.3;
    pointer-events: none;
}

.floating_nav_separator {
    height: 1px;
    background: var(--color-border);
    margin: 2px 0;
}

/* Wrapper dropdown dans le pavé flottant */
.floating_nav_selector {
    position: relative;
}

/* Dropdown cloné : surcharge le positionnement d'origine */
.floating_nav_dropdown.dropdown_menu {
    top: auto;
    left: auto;
    right: calc(100% + 12px);
    bottom: 0;
    transform: none;
    min-width: 280px;
    max-height: 60vh;
    overflow-y: auto;
    z-index: 910;
}

.page_eleve .floating_nav_btn:hover {
    background-color: var(--color-role-eleve);
    border-color: var(--color-role-eleve);
}

.page_formateur .floating_nav_btn:hover {
    background-color: var(--color-role-formateur);
    border-color: var(--color-role-formateur);
}

.page_admin .floating_nav_btn:hover {
    background-color: var(--color-role-admin);
    border-color: var(--color-role-admin);
}

/* Rien de flottant sur le papier : ces éléments sont en `position: fixed`, ils se
   posaient donc sur la page imprimée – par-dessus le pied de page de la feuille d'évaluation.
   La règle vit ici, avec le composant : le défaut vaut pour toute page imprimée. */
@media print {
    .button_scroll_top,
    .floating_nav {
        display: none !important;
    }
}

@media (max-width: 1350px) {
    .floating_nav {
        bottom: 72px;
        right: 16px;
    }
}

@media (max-width: 950px) {
    /* En mobile, la barre mobile_nav (PHP) prend le relais */
    .floating_nav {
        display: none !important;
    }

    .button_scroll_top {
        width: 40px;
        height: 40px;
        font-size: var(--text-subtitle);
        line-height: 40px;
    }
}

/* --- Barre navigation mobile (rendue côté serveur) --- */
.mobile_nav {
    display: none;
}

/* `screen and` et non la largeur seule : une feuille A4 mesure moins de 950 px, si bien
   que sans cette précision la barre s'imprimait en bas de chaque page. Une navigation
   n'a rien à faire sur du papier. */
@media screen and (max-width: 950px) {
    .mobile_nav {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 900;
        justify-content: center;
        gap: 8px;
        background: var(--color-white);
        border-top: 1px solid var(--color-border);
        box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
        padding: 8px 12px;
    }
    .mobile_nav_btn {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 34px;
        height: 34px;
        border-radius: 5px;
        border: 1px solid var(--color-border);
        background: var(--color-white);
        color: var(--color-gray-600);
        font-size: var(--text-body);
        cursor: pointer;
        text-decoration: none;
        transition: all 200ms ease;
    }
    .mobile_nav_btn:hover {
        background-color: var(--color-primary);
        color: var(--color-white);
        border-color: var(--color-primary);
    }
    /* Le composant rend un `<span>` pour un lien mort, mais un vrai `<button>` pour un
       geste : celui-là s'éteint par son attribut, pas par une classe. */
    .mobile_nav_btn_disabled,
    .mobile_nav_btn:disabled {
        opacity: 0.3;
        pointer-events: none;
    }
    .mobile_nav_separator {
        width: 1px;
        height: 24px;
        background: var(--color-border);
        align-self: center;
    }
    .mobile_nav_selector {
        position: relative;
    }
    /* Le menu se centre sur L'ÉCRAN, pas sur son bouton : ancré au bouton, il partait d'un
       côté ou de l'autre selon la place de celui-ci dans la barre – et un menu « large »
       réclame 320 px de fond. Fixé et centré, il est toujours à égale distance des deux
       bords, quel que soit le bouton qui l'ouvre. */
    .mobile_nav_dropdown.dropdown_menu {
        position: fixed;
        top: auto;
        bottom: 62px;
        left: 50%;
        right: auto;
        transform: translateX(-50%);
        min-width: min(280px, calc(100vw - 24px));
        max-width: calc(100vw - 24px);
        max-height: 60vh;
        overflow-y: auto;
        z-index: 910;
    }

    /* `dropdown_menu_large` vaut pour un écran large ; ici il imposerait 320 px. */
    .mobile_nav_dropdown.dropdown_menu_large {
        min-width: min(320px, calc(100vw - 24px));
    }
    .page_eleve .mobile_nav_btn:hover {
        background-color: var(--color-role-eleve);
        border-color: var(--color-role-eleve);
    }
    .page_formateur .mobile_nav_btn:hover {
        background-color: var(--color-role-formateur);
        border-color: var(--color-role-formateur);
    }
    .page_admin .mobile_nav_btn:hover {
        background-color: var(--color-role-admin);
        border-color: var(--color-role-admin);
    }
}

/* --- Bouton toggle avec flèche --- */
.button_toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.toggle_text {
    display: inline-block;
    min-width: 70px;
    text-align: left;
}

/* --- Switch toggle (ON/OFF) --- */
.switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    min-width: 30px;
    height: 16px;
    min-height: 16px;
    flex-shrink: 0;
    vertical-align: text-bottom;
}

.switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.switch_slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    width: 30px;
    height: 16px;
    background-color: var(--color-gray-300);
    border-radius: 16px;
    transition: all 0.2s ease;
}

.switch_slider::before {
    position: absolute;
    content: "";
    height: 12px;
    width: 12px;
    left: 2px;
    bottom: 2px;
    background-color: var(--color-white);
    border-radius: 50%;
    transition: all 0.2s ease;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.switch input:checked + .switch_slider {
    background-color: var(--color-success);
}

.switch input:checked + .switch_slider::before {
    transform: translateX(14px);
}

.switch input:focus + .switch_slider {
    box-shadow: 0 0 0 2px var(--color-primary-light-alpha);
}

.switch input:disabled + .switch_slider {
    opacity: 0.5;
    cursor: not-allowed;
}

/* L'interrupteur descend d'un cran avec tout le reste – voir « UN SEUL CRAN, À 950 » plus
   bas, où le seuil et sa réserve tactile sont expliqués une fois pour toutes. */
@media (max-width: 950px) and (pointer: fine) {
    .switch {
        width: 26px;
        min-width: 26px;
        height: 14px;
        min-height: 14px;
    }

    .switch_slider {
        width: 26px;
        height: 14px;
        border-radius: 14px;
    }

    .switch_slider::before {
        height: 10px;
        width: 10px;
    }

    .switch input:checked + .switch_slider::before {
        transform: translateX(12px);
    }
}

/* Switch avec label */
.switch_label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}

.switch_label_text {
    font-size: var(--text-small);
    color: var(--color-text-secondary);
}

/* ============================================
   4. INPUTS STYLISÉS (checkbox, radio)
   ============================================ */

/* --- Groupe de radios --- */
.radio_group {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.radio_group_horizontal {
    flex-direction: row;
    flex-wrap: wrap;
}

.radio_group_horizontal .radio_label {
    flex: 1;
}

.radio_label {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    padding: 10px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    transition: border-color 0.2s, background-color 0.2s;
}

/* DEUX NIVEAUX DANS L'ÉTIQUETTE – un titre et son explication (`radio_text`) : le bouton se
   pose en regard du TITRE, pas au milieu des deux lignes. Les 2 px le calent optiquement sur
   la ligne, comme pour les cases des permissions (`permissions_features_label`). */
.radio_label:has(.radio_text) {
    align-items: flex-start;
}

.radio_label:has(.radio_text) .radio_input {
    margin-top: 2px;
}

.radio_label:hover {
    border-color: var(--color-primary);
    background-color: var(--color-bg-hover);
}

.radio_label:has(.radio_input:checked) {
    border-color: var(--color-primary);
    background-color: var(--color-primary-light-alpha);
}

.radio_input {
    flex-shrink: 0;
}

.radio_text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
}

.radio_text strong {
    color: var(--color-text-primary);
}

/* Modificateur : pilule à largeur naturelle au lieu d'une part égale de la ligne – pour des
   choix courts alignés côte à côte (« −1 point », « 3 ans », « 4ᵉ classe »).
   Le sélecteur porte le groupe : sans lui, le `flex: 1` de `.radio_group_horizontal
   .radio_label` pèse plus lourd et le modificateur reste sans effet – c'est-à-dire
   précisément dans la rangée où il a un sens. */
.radio_group_horizontal .radio_label_compact,
.radio_label_compact {
    flex: 0 0 auto;
    padding: 6px 10px;
    gap: 6px;
    white-space: nowrap; /* « −2 points » ne se coupe pas en deux lignes */
}

/* --- Checkbox et radio basiques --- */
.checkbox_label {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-size: var(--text-small);
    font-weight: 500;
    color: var(--color-gray-700);
    cursor: pointer;
}

.checkbox_input,
.radio_input {
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: var(--color-primary);
}

/* Plusieurs cases à cocher les unes sous les autres, pour des choix qui ne s'excluent
   pas – là où .radio_group obligerait à inventer une option « ne rien faire ». */
.checkbox_group {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* `hidden` DOIT L'EMPORTER SUR `display: flex`, qui gagne sinon sur la règle du navigateur.
   Un écran qui pose deux groupes et n'en dévoile qu'un – les compétences de l'activité-type
   ouverte, dans le livret d'évaluation – les montrerait sinon tous les deux, l'un collé à l'autre. */
.radio_group[hidden],
.checkbox_group[hidden] {
    display: none;
}

/* CASE PRÉSENTÉE EN OPTION ENCADRÉE – la jumelle de `.radio_label`, pour des choix qui ne
   s'excluent pas. La case se pose en regard de la PREMIÈRE ligne : un libellé de deux lignes
   la laisserait flotter au milieu. Le bloc prend toute la hauteur de sa cellule de grille,
   pour que deux colonnes d'étiquettes inégales gardent le même cadre. */
.checkbox_label_carte {
    display: flex;
    align-items: flex-start;
    padding: 10px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    transition: border-color 0.2s, background-color 0.2s;
}

.checkbox_label_carte .checkbox_input {
    flex-shrink: 0;
    margin-top: 1px;
}

.checkbox_label_carte:hover {
    border-color: var(--color-primary);
    background-color: var(--color-bg-hover);
}

.checkbox_label_carte:has(.checkbox_input:checked) {
    border-color: var(--color-primary);
    background-color: var(--color-primary-light-alpha);
}

/* Précision sous le libellé d'une case : la plage de numéros, un effectif. */
.checkbox_note {
    display: block;
    margin-top: 2px;
    font-size: var(--text-meta);
    font-weight: 400;
    color: var(--color-text-secondary);
}

/* --- Checkbox success (vert) --- */
.checkbox_input_success,
.answer_correct_toggle {
    width: 18px;
    height: 18px;
    min-width: 18px;
    min-height: 18px;
    box-sizing: border-box;
    flex-shrink: 0;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    border: 2px solid var(--color-gray-300);
    border-radius: 3px;
    background-color: white;
    position: relative;
    transition: all 0.15s ease;
}

.checkbox_input_success:hover,
.answer_correct_toggle:hover {
    border-color: var(--color-success);
}

.checkbox_input_success:checked,
.answer_correct_toggle:checked {
    border-color: var(--color-success);
    background-color: white;
}

.checkbox_input_success:checked::after,
.answer_correct_toggle:checked::after {
    content: '';
    position: absolute;
    left: 5px;
    top: 1px;
    width: 5px;
    height: 10px;
    border: solid var(--color-success);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* Checkbox bloquée (QCM : au moins 1 mauvaise réponse requise) */
.checkbox_blocked {
    border-color: var(--color-error) !important;
    background-color: #fee2e2 !important;
    cursor: not-allowed !important;
}

/* ============================================
   5. ÉTATS ET MODIFICATEURS
   ============================================ */

/* --- État désactivé ---
   `aria-disabled` plutôt que `disabled` quand le bouton doit encore expliquer pourquoi :
   un bouton vraiment désactivé n'émet aucun événement, donc aucune info-bulle. */
.button:disabled,
.button_disabled,
.button[aria-disabled="true"],
.button_icon:disabled,
.button_icon_danger:disabled,
.button_icon_menu:disabled,
.button_icon_nu:disabled,
.button_icon[aria-disabled="true"],
.button_icon_danger[aria-disabled="true"],
.button_icon_menu[aria-disabled="true"],
.button_icon_nu[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

.button_primary:disabled,
.button_primary.button_disabled {
    background-color: var(--color-gray-400);
    border-color: var(--color-gray-400);
}

.button_secondary:disabled,
.button_secondary.button_disabled {
    background-color: var(--color-gray-100);
    border-color: var(--color-gray-200);
    color: var(--color-gray-400);
}


/* ============================================
   6. RESPONSIVE
   ============================================ */


/* UN SEUL CRAN, À 950 – LE MÊME QUE LES TEXTES.

   À 950 px, `base/styles.css` redéfinit tous les jetons `--text-*` : le site entier descend
   d'un cran. Les boutons suivent le même rythme, sinon leur texte maigrit dans une boîte
   restée grande, et un bouton-icône sans texte ne bouge plus du tout – d'où des gestes de
   tailles différentes sur une même ligne.

   MAIS PAS AU DOIGT (`pointer: fine`). Une cible tactile de 28 px se rate ; les
   recommandations parlent de 44. Sur un appareil tactile, tout ce qui se touche garde donc
   sa taille pleine, quelle que soit la largeur de l'écran. Un bouton n'est pas un texte :
   on le lit de loin, mais on le vise de près. */
@media (max-width: 950px) and (pointer: fine) {
    .button {
        height: 32px;
    }

    .button_small {
        height: 28px;
    }

    .button_icon,
    .button_icon_danger,
    .button_icon_menu,
    .button_icon_nu {
        width: 28px;
        height: 28px;
        line-height: 28px;
    }
}

@media (max-width: 500px) {
    .button {
        padding: 0 12px;
    }

    .button_small {
        padding: 0 10px;
    }
}
