/*
 * Feuille du site. Le système (palette, typographie, espacements) est décrit
 * dans docs/DESIGN.md : un changement ici se reporte là-bas, et inversement.
 *
 * Aucune couleur de teinte dans l'identité : encre et papier seulement.
 * Toute couleur évoque un camp en politique (docs/DESIGN.md, « Color »).
 */

/* Polices auto-hébergées, aucun CDN. Fichiers variables (graisses 300 à
   800), découpés en latin et latin étendu : le second n'est téléchargé que
   si la page contient un de ses caractères. Licences dans resources/fonts/. */

@font-face {
    font-family: 'Fraunces';
    font-style: normal;
    font-weight: 300 800;
    font-display: swap;
    src: url("../fonts/fraunces-latin-ext-lB3xlu4.woff2") format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Fraunces';
    font-style: normal;
    font-weight: 300 800;
    font-display: swap;
    src: url("../fonts/fraunces-latin-SfWU466.woff2") format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Source Sans 3';
    font-style: normal;
    font-weight: 300 800;
    font-display: swap;
    src: url("../fonts/source-sans-3-latin-ext-eCU7jd1.woff2") format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Source Sans 3';
    font-style: normal;
    font-weight: 300 800;
    font-display: swap;
    src: url("../fonts/source-sans-3-latin-u4wvMPu.woff2") format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Polices de repli ajustées. Tant que Fraunces et Source Sans 3 ne sont pas
   arrivées, le texte s'affiche dans une police du système agrandie ou
   réduite (size-adjust) pour prendre la même largeur : la vraie police la
   remplace sans renvoyer de mot à la ligne, donc sans décaler la page (CLS).
   Times New Roman et Arial existent sous Windows, macOS et iOS, leurs
   équivalents métriques (Liberation, Tinos, Arimo) sous Linux ; Android n'a
   que Noto Serif et Roboto. Valeurs mesurées et méthode dans docs/DESIGN.md,
   « Typography » : à recalculer si une police ou une graisse change. */

@font-face {
    font-family: 'Fraunces repli';
    font-weight: 300 500;
    src: local('Times New Roman'), local('TimesNewRomanPSMT'), local('Liberation Serif'), local('LiberationSerif'), local('Tinos'), local('Tinos-Regular');
    size-adjust: 114.2%;
    ascent-override: 85.64%;
    descent-override: 22.33%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Fraunces repli';
    font-weight: 600 800;
    src: local('Times New Roman Bold'), local('TimesNewRomanPS-BoldMT'), local('Liberation Serif Bold'), local('LiberationSerif-Bold'), local('Tinos Bold'), local('Tinos-Bold');
    size-adjust: 110.26%;
    ascent-override: 88.7%;
    descent-override: 23.13%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Fraunces repli Android';
    font-weight: 300 800;
    src: local('Noto Serif'), local('Noto Serif Regular'), local('NotoSerif-Regular');
    size-adjust: 97.34%;
    ascent-override: 100.47%;
    descent-override: 26.2%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Source Sans 3 repli';
    font-weight: 300 500;
    src: local('Arial'), local('ArialMT'), local('Liberation Sans'), local('LiberationSans'), local('Arimo'), local('Arimo-Regular');
    size-adjust: 93.14%;
    ascent-override: 109.94%;
    descent-override: 42.94%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Source Sans 3 repli';
    font-weight: 600 800;
    src: local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'), local('LiberationSans-Bold'), local('Arimo Bold'), local('Arimo-Bold');
    size-adjust: 89.01%;
    ascent-override: 115.04%;
    descent-override: 44.94%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Source Sans 3 repli Android';
    font-weight: 300 800;
    src: local('Roboto'), local('Roboto Regular'), local('Roboto-Regular');
    size-adjust: 93.5%;
    ascent-override: 109.52%;
    descent-override: 42.78%;
    line-gap-override: 0%;
}

/* Jetons. Contrastes mesurés dans docs/DESIGN.md. */

:root {
    color-scheme: light dark;

    --fond: #f6f4ef;
    --surface: #fffefb;
    --surligne: #ebe7de;
    --encre: #1d1c1a;
    --encre-douce: #57534c;
    --filet: #d6d1c6;
    --filet-fort: #8a8478;
    --erreur: #a1281c;
    --succes: #2c6a3c;

    --police-titre: 'Fraunces', 'Fraunces repli', 'Fraunces repli Android', Georgia, serif;
    --police-texte: 'Source Sans 3', 'Source Sans 3 repli', 'Source Sans 3 repli Android', 'Segoe UI', 'Helvetica Neue', sans-serif;

    --largeur: 72rem;
    --largeur-texte: 42rem;
    --gouttiere: 1rem;
    --rayon: 4px;
    --duree: 150ms;
}

/* Mode sombre : celui de l'appareil par défaut, ou celui choisi par le
   bouton de l'en-tête (assets/mode.js), qui pose data-mode sur <html> avant
   l'affichage. Les deux blocs portent les mêmes valeurs. */
@media (prefers-color-scheme: dark) {
    :root:not([data-mode='clair']) {
        --fond: #161513;
        --surface: #201f1c;
        --surligne: #2c2a26;
        --encre: #ece9e2;
        --encre-douce: #aba69c;
        --filet: #3b3934;
        --filet-fort: #7a756c;
        --erreur: #f2a395;
        --succes: #8fcf9f;
    }
}

:root[data-mode='sombre'] {
    color-scheme: dark;

    --fond: #161513;
    --surface: #201f1c;
    --surligne: #2c2a26;
    --encre: #ece9e2;
    --encre-douce: #aba69c;
    --filet: #3b3934;
    --filet-fort: #7a756c;
    --erreur: #f2a395;
    --succes: #8fcf9f;
}

:root[data-mode='clair'] {
    color-scheme: light;
}

@media (min-width: 40rem) {
    :root { --gouttiere: 1.5rem; }
}

@media (min-width: 64rem) {
    :root { --gouttiere: 2rem; }
}

/* Base */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--fond);
    color: var(--encre);
    font-family: var(--police-texte);
    font-size: 1.125rem;
    line-height: 1.6;
}

main {
    flex: 1;
}

h1,
h2,
h3 {
    margin: 0 0 1rem;
    font-family: var(--police-titre);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.01em;
    text-wrap: balance;
    /* Un mot plus long que la ligne se coupe plutôt que de faire défiler la
       page : « Confidentialité » à 320 px, espacement du texte élargi
       (WCAG 1.4.12). Sans effet sur un mot qui tient. */
    overflow-wrap: break-word;
}

h1 {
    font-size: clamp(2.25rem, 1.5rem + 3vw, 3.5rem);
    font-weight: 500;
    line-height: 1.08;
    letter-spacing: -0.015em;
}

h2 {
    font-size: clamp(1.75rem, 1.5rem + 1vw, 2.25rem);
}

h3 {
    font-size: 1.375rem;
}

p {
    margin: 0 0 1rem;
    text-wrap: pretty;
}

/* Liens soulignés partout (aucune couleur ne les distingue du texte), d'un
   trait en filet fort pour alléger les pages qui en comptent des dizaines ;
   le trait passe à l'encre et s'épaissit au survol. Filet fort sur fond :
   3,4:1 en clair, 4,0:1 en sombre (docs/DESIGN.md, « Color »). */
a {
    color: inherit;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--filet-fort);
    text-underline-offset: 0.18em;
    transition: text-decoration-color var(--duree) ease-out;
}

a:hover {
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
}

:focus-visible {
    outline: 3px solid var(--encre);
    outline-offset: 3px;
    border-radius: 2px;
}

::selection {
    background: var(--encre);
    color: var(--fond);
}

/* L'attribut hidden l'emporte sur l'affichage d'une classe (.bouton est en
   inline-flex) : le quiz masque ainsi ses étapes et ses boutons. */
[hidden] {
    display: none !important;
}

/* Lu par les lecteurs d'écran, masqué à l'écran. */
.visuellement-masque {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.contenance {
    width: 100%;
    max-width: var(--largeur);
    margin-inline: auto;
    padding-inline: var(--gouttiere);
}

.evitement {
    position: absolute;
    left: var(--gouttiere);
    top: -10rem;
    z-index: 10;
    padding: 0.75rem 1rem;
    background: var(--encre);
    color: var(--fond);
    font-weight: 600;
}

.evitement:focus {
    top: 1rem;
}

/* Boutons : encre pleine, inversés au survol. */

.bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0.625rem 1.25rem;
    border: 2px solid var(--encre);
    border-radius: var(--rayon);
    background: var(--encre);
    color: var(--fond);
    font: 600 1rem/1.2 var(--police-texte);
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--duree) ease-out, color var(--duree) ease-out, transform var(--duree) ease-out;
}

.bouton:hover {
    background: transparent;
    color: var(--encre);
}

/* Retour au toucher : le bouton s'enfonce d'un pixel. */
.bouton:active {
    transform: translateY(1px);
}

/* Bouton qui fait avancer (commencer le quiz, voir le résultat) : un chevron
   dessiné en bordures, sans caractère que liraient les lecteurs d'écran. */
.bouton--suite::after {
    content: '';
    flex: none;
    width: 0.45em;
    height: 0.45em;
    margin-left: 0.75em;
    border-top: 2px solid currentColor;
    border-right: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform var(--duree) ease-out;
}

.bouton--suite:hover::after {
    transform: translateX(3px) rotate(45deg);
}

.bouton--secondaire {
    background: transparent;
    color: var(--encre);
}

.bouton--secondaire:hover {
    background: var(--surligne);
}

.bouton--petit {
    min-height: 2.25rem;
    padding: 0.375rem 0.875rem;
    font-size: 0.9375rem;
}

.bouton--grand {
    min-height: 3.25rem;
    padding: 0.875rem 1.75rem;
    font-size: 1.125rem;
}

/* Pastilles d'accord (docs/DESIGN.md, « Identité ») */

.pastille {
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
}

/* En-tête */

.entete {
    border-bottom: 1px solid var(--filet);
}

/* En mobile, la marque et le bouton du mode sur la première ligne, la
   navigation sur la seconde ; dès 52rem, tout sur une ligne, le bouton du
   mode au bout. Le bouton suit la navigation dans le code : au clavier, il
   vient en dernier. */
.entete__barre {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        'marque mode'
        'navigation navigation';
    align-items: center;
    gap: 0.5rem 1rem;
    padding-block: 0.875rem;
}

.entete__barre .marque {
    grid-area: marque;
    justify-self: start;
}

.navigation {
    grid-area: navigation;
}

@media (min-width: 52rem) {
    .entete__barre {
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas: 'marque navigation mode';
        column-gap: 1.5rem;
    }

    .navigation {
        justify-self: end;
    }
}

/* Bouton du mode sombre (assets/mode.js) : une lune en mode clair, un
   soleil en mode sombre, l'icône du mode vers lequel il bascule. Son nom,
   « Mode sombre », ne change pas : aria-pressed dit s'il est actif. Masqué
   sans JavaScript, le site suit alors le réglage de l'appareil. */
.bouton-mode {
    position: relative;
    grid-area: mode;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border: 1px solid var(--filet-fort);
    border-radius: var(--rayon);
    background: transparent;
    color: var(--encre);
    cursor: pointer;
    transition: background-color var(--duree) ease-out, border-color var(--duree) ease-out;
}

.bouton-mode:hover {
    border-color: var(--encre);
    background: var(--surligne);
}

.bouton-mode svg {
    width: 1.25rem;
    height: 1.25rem;
}

.bouton-mode[aria-pressed='true'] .bouton-mode__lune,
.bouton-mode[aria-pressed='false'] .bouton-mode__soleil {
    display: none;
}

.marque {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    font-family: var(--police-titre);
    font-size: 1.375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    text-decoration: none;
}

.marque__signe {
    flex: none;
    width: 1.625rem;
    height: 1.625rem;
}

.navigation ul {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 1.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.navigation a:not(.bouton) {
    display: inline-block;
    padding-block: 0.5rem;
    font-size: 1rem;
    font-weight: 600;
    text-decoration: none;
}

.navigation a:not(.bouton):hover,
.navigation a[aria-current='page'] {
    text-decoration: underline;
}

/* Pied de page */

.pied {
    margin-top: 4rem;
    padding-block: 2.5rem 3rem;
    border-top: 2px solid var(--encre);
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

.pied__grille {
    display: grid;
    gap: 1.5rem;
}

.pied__presentation p:last-child {
    max-width: 32rem;
}

.pied__nom {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
    color: var(--encre);
    font-family: var(--police-titre);
    font-size: 1.125rem;
    font-weight: 600;
}

.pied__signe {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
}

.pied__liens ul {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.pied__liens a {
    display: inline-block;
    padding-block: 0.375rem;
    color: var(--encre);
}

.pied__editeur {
    margin: 0;
}

@media (min-width: 56rem) {
    .pied__grille {
        grid-template-columns: 2fr 1fr;
    }

    .pied__editeur {
        grid-column: 1 / -1;
    }
}

/* Sections */

/* Date de mise à jour d'une page (_mise_a_jour.html.twig) */

.mise-a-jour {
    margin: 0;
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

/* Fil d'Ariane (_fil_ariane.html.twig) */

.fil-ariane {
    padding-top: 1.5rem;
    margin-bottom: 1.5rem;
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

.fil-ariane ol {
    display: flex;
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    list-style: none;
}

.fil-ariane li + li::before {
    content: '›' / '';
    margin-inline: 0.5rem;
}

.fil-ariane a {
    display: inline-block;
    padding-block: 0.25rem;
}

.titre-section {
    padding-top: 1rem;
    border-top: 2px solid var(--encre);
}

.intro {
    max-width: var(--largeur-texte);
    margin-bottom: 2rem;
    color: var(--encre-douce);
}

/* Accueil : la une */

.une {
    padding-block: clamp(3rem, 8vw, 6rem) clamp(2.5rem, 6vw, 4.5rem);
}

.surtitre {
    margin-bottom: 1.25rem;
    color: var(--encre-douce);
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.une h1 {
    max-width: 15em;
    margin-bottom: 1.5rem;
}

.chapeau {
    max-width: var(--largeur-texte);
    font-size: 1.25rem;
    line-height: 1.5;
}

.une__action {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 1.5rem;
    margin-block: 2rem 1.75rem;
}

.une__duree {
    margin: 0;
    color: var(--encre-douce);
    font-weight: 600;
}

/* La une en deux colonnes dès 56rem : la promesse à gauche, la mosaïque des
   candidats à droite ; en mobile, la mosaïque suit la date de vérification. */
.une__grille {
    display: grid;
    gap: 2.5rem;
}

/* Mosaïque des candidats en lice : tous à la même taille, dans l'ordre du
   site. Sept par ligne en mobile, six dès 56rem ; la dernière ligne, quand
   elle est incomplète, est centrée plutôt que calée à gauche. */
.mosaique {
    margin: 0;
}

.mosaique__grille {
    --par-ligne: 7;
    --espace: 4px;

    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--espace);
    margin: 0;
    padding: 0;
    list-style: none;
}

.mosaique__grille li {
    flex: 0 0 calc((100% - (var(--par-ligne) - 1) * var(--espace)) / var(--par-ligne));
}

.mosaique .photo {
    border-radius: 2px;
}

/* Dans la mosaïque, décorative, la silhouette s'efface derrière les photos :
   en filet fort, neuf bustes faisaient tache au premier écran. */
.mosaique .photo--silhouette {
    color: var(--filet);
}

.mosaique__legende {
    margin-top: 0.875rem;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    text-align: center;
}

.mosaique__legende a {
    display: inline-block;
    padding-block: 0.125rem;
    color: var(--encre);
    font-weight: 600;
}

@media (min-width: 56rem) {
    .une__grille {
        grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
        align-items: center;
        column-gap: clamp(3rem, 6vw, 5rem);
    }

    /* Sur une demi-largeur, le titre plafonne à 3,25rem : à 3,5rem, il
       tenait sur cinq lignes. */
    .une h1 {
        font-size: clamp(2.25rem, 1.25rem + 2.5vw, 3.25rem);
    }

    .mosaique__grille {
        --par-ligne: 6;
        --espace: 6px;
    }
}


/* Accueil : les règles du site */

.regles {
    padding-block: clamp(3rem, 7vw, 4.5rem);
    border-block: 1px solid var(--filet);
    background: var(--surface);
}

.regles__liste {
    display: grid;
    gap: 2.5rem;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
    counter-reset: regle;
}

.regle {
    counter-increment: regle;
}

.regle h3::before {
    content: counter(regle);
    display: block;
    margin-bottom: 0.75rem;
    font-size: 2.5rem;
    font-weight: 400;
    line-height: 1;
}

.regle p:last-child {
    margin-bottom: 0;
}

/* Barème de l'accueil, décompte d'un duel : une pastille, puis le texte. */
.bareme,
.decompte {
    display: grid;
    gap: 0.375rem;
    margin: 0 0 0.75rem;
    padding: 0;
    list-style: none;
}

.bareme li,
.decompte li {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-weight: 600;
}

.regle__note {
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

@media (min-width: 56rem) {
    .regles__liste {
        grid-template-columns: repeat(3, 1fr);
        gap: 0;
    }

    .regle {
        padding-inline: 2rem;
        border-left: 1px solid var(--filet);
    }

    .regle:first-child {
        padding-left: 0;
        border-left: 0;
    }

    .regle:last-child {
        padding-right: 0;
    }
}

/* Accueil : thèmes et candidats */

.themes,
.candidats {
    padding-top: clamp(3rem, 7vw, 5rem);
}

.themes__liste {
    display: grid;
    gap: 0 3rem;
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: theme;
}

.theme {
    counter-increment: theme;
    display: grid;
    grid-template-columns: 2.25rem 1fr;
    align-content: start;
    column-gap: 0.75rem;
    padding-block: 1.25rem 1.5rem;
    border-top: 1px solid var(--filet);
}

.theme::before {
    content: counter(theme, decimal-leading-zero);
    grid-row: span 2;
    color: var(--encre-douce);
    font-family: var(--police-titre);
    font-size: 1.375rem;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

.theme__titre {
    margin-bottom: 0.625rem;
}

.theme__questions {
    display: grid;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
    line-height: 1.45;
}

.theme__questions li {
    position: relative;
    padding-left: 1rem;
}

.theme__questions li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.62em;
    width: 0.3rem;
    height: 0.3rem;
    background: var(--filet-fort);
}

.candidats__liste {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0 1.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.candidat {
    display: flex;
    flex-direction: column;
    padding-block: 0.75rem 0.875rem;
    border-top: 1px solid var(--filet);
}

.candidat__nom {
    font-weight: 600;
}

.candidat__etiquette {
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

/* Photo d'un candidat, ou sa silhouette s'il n'en a pas (docs/DESIGN.md,
   « Identité ») : carrée, en noir et blanc, même cadre pour tous. Dans une
   liste, la vignette précède le nom et l'étiquette. */

.photo {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 1;
    border-radius: var(--rayon);
    background: var(--surligne);
    object-fit: cover;
}

.photo--silhouette {
    overflow: hidden;
    color: var(--filet-fort);
}

.silhouette {
    display: block;
    width: 100%;
    height: 100%;
}

/* En mobile, deux colonnes de 150 px : la vignette passe au-dessus du nom,
   sinon « Glucksmann » ou « Mikolajczak » déborderaient. */
.candidat--photo {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    row-gap: 0.5rem;
}

.candidat--photo .photo {
    width: 3.5rem;
}

.candidat__texte {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

@media (min-width: 30rem) {
    .candidat--photo {
        grid-template-columns: 3.5rem minmax(0, 1fr);
        align-items: center;
        column-gap: 0.875rem;
    }

    .candidat--photo .photo {
        width: 100%;
    }
}

@media (min-width: 48rem) {
    .themes__liste {
        grid-template-columns: repeat(2, 1fr);
    }

    .candidats__liste {
        grid-template-columns: repeat(3, 1fr);
        column-gap: 2rem;
    }
}

@media (min-width: 64rem) {
    .candidats__liste {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* Trombinoscope de l'accueil : la photo en grand au-dessus du nom, de trois
   à six colonnes (deux en mobile faisaient dix-sept rangées). La photo et le
   nom forment un seul lien vers la page du candidat ; son contour de focus
   les entoure, et au survol un filet d'encre encadre la photo. */

.candidats__liste--trombinoscope {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.5rem 0.75rem;
}

.candidat--portrait {
    gap: 0.25rem;
    padding: 0;
    border-top: 0;
    overflow-wrap: break-word;
}

/* Les candidatures retirées, sous le trombinoscope : une ligne de liens. */
.candidats__hors-course {
    max-width: var(--largeur-texte);
    margin-top: 2.5rem;
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

.candidats__hors-course a {
    color: var(--encre);
}

.candidat__lien {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    border-radius: var(--rayon);
    text-decoration: none;
}

.candidat__lien:focus-visible {
    outline-offset: 4px;
}

.candidat--portrait .photo {
    outline: 2px solid transparent;
    outline-offset: 2px;
    transition: outline-color var(--duree) ease-out;
}

.candidat__lien:hover .photo {
    outline-color: var(--encre);
}

/* « Mikolajczak » tient dans une colonne de 88 px à 320 px ; un mot plus
   long (« NPA-Révolutionnaires ») se coupe plutôt que de déborder. */
.candidat--portrait .candidat__nom {
    font-family: var(--police-titre);
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
}

.candidat--portrait .candidat__etiquette {
    font-size: 0.875rem;
    line-height: 1.35;
}

/* Le lien est un bloc : le souligné ne porte que sur le nom. */
.candidat__lien .candidat__nom {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--filet-fort);
    text-underline-offset: 0.18em;
    transition: text-decoration-color var(--duree) ease-out;
}

.candidat__lien:hover .candidat__nom {
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
}

@media (min-width: 40rem) {
    .candidats__liste--trombinoscope {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 1.75rem 1.25rem;
    }

    .candidat--portrait .candidat__nom {
        font-size: 1.125rem;
    }

    .candidat--portrait .candidat__etiquette {
        font-size: 0.9375rem;
    }
}

@media (min-width: 56rem) {
    .candidats__liste--trombinoscope {
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }
}

@media (min-width: 64rem) {
    .candidats__liste--trombinoscope {
        grid-template-columns: repeat(6, minmax(0, 1fr));
        gap: 2rem 1.25rem;
    }
}

/* Pages de texte : pages légales, contact */

.page-texte {
    max-width: var(--largeur-texte);
    padding-bottom: 1rem;
}

.page-texte h1 {
    margin-bottom: 1rem;
}

.page-texte > .mise-a-jour {
    margin-bottom: 2rem;
}

.page-texte h2 {
    margin-top: 2.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--filet);
    font-size: 1.75rem;
}

.page-texte ul {
    margin: 0 0 1rem;
    padding-left: 1.25rem;
}

.page-texte li + li {
    margin-top: 0.5rem;
}

.page-texte__note {
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

/* Page Méthode (EL-232) : une page de texte, avec son sommaire, ses
   tableaux et le journal des corrections. Les listes du site (barème, liens
   en colonnes) y gardent leur propre mise en page. */

.page-texte h3 {
    margin-top: 2rem;
}

.page-texte .bareme,
.page-texte .journal {
    padding-left: 0;
}

.page-texte .bareme li + li,
.page-texte .liens-suite--colonnes li + li {
    margin-top: 0;
}

.sommaire {
    margin-block: 2rem;
    padding: 1.25rem 1.5rem;
    border-left: 2px solid var(--encre);
    background: var(--surface);
}

.page-texte .sommaire__titre {
    margin: 0 0 0.5rem;
    padding: 0;
    border: 0;
    font-size: 1.25rem;
}

.sommaire ol {
    margin: 0;
    padding-left: 1.25rem;
}

.sommaire li + li {
    margin-top: 0.25rem;
}

.journal {
    list-style: none;
}

.page-texte .journal li {
    margin: 0;
    padding-block: 0.75rem;
    border-top: 1px solid var(--filet);
}

.journal__date {
    color: var(--encre-douce);
    font-size: 0.9375rem;
    font-weight: 700;
}

/* Page Journal (EL-233) : une correction se distingue d'une modification
   par un mot, sans couleur (docs/DESIGN.md). */
.journal__nature {
    margin-left: 0.5rem;
    padding: 0 0.375rem;
    border: 1px solid var(--encre);
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.journal p {
    margin: 0.25rem 0 0;
}

/* Fiche : couples intitulé et valeur (éditeur, hébergeur) */

.fiche {
    display: grid;
    gap: 0.125rem 1.5rem;
    margin: 0 0 1rem;
}

.fiche dt {
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

.fiche dd {
    margin: 0 0 0.625rem;
}

@media (min-width: 40rem) {
    .fiche {
        grid-template-columns: 14rem 1fr;
    }

    .fiche dt {
        padding-top: 0.1rem;
    }

    .fiche dd {
        margin-bottom: 0.375rem;
    }
}

/* Page d'un candidat : présentation, puis ses positions thème par thème.
   Même gabarit pour tous : la photo, ou la silhouette, au-dessus du nom en
   mobile, à sa gauche dès 40rem (docs/DESIGN.md, « Identité »). */

.presentation {
    max-width: var(--largeur-texte);
}

.presentation__identite {
    display: grid;
    gap: 1.25rem;
    margin-bottom: 1.25rem;
}

.presentation__identite .photo {
    width: 7.5rem;
}

.presentation__identite h1 {
    margin-bottom: 0;
}

@media (min-width: 40rem) {
    .presentation__identite {
        grid-template-columns: 10rem minmax(0, 1fr);
        align-items: end;
        gap: 1.5rem;
    }

    .presentation__identite .photo {
        width: 100%;
    }
}

.presentation .fiche {
    margin-top: 2rem;
}

.presentation > .mise-a-jour {
    margin-bottom: 2.5rem;
}

/* Dès 64rem, les pages candidat, thème, question et duel passent sur deux
   colonnes (.contenance--encart) : le titre, le chapô et les sections de
   lecture (parcours, enjeux, contexte) sur la largeur de lecture, la fiche
   (ou le face-à-face d'un duel) en encart à droite, comme l'encadré d'un
   article de presse. L'en-tête s'efface (display: contents) pour que ses
   enfants et les sections qui le suivent partagent la même grille : les
   sections étroites remontent à côté de l'encart au lieu d'attendre sa fin.
   Les sections larges (.positions : tableaux, listes de positions) passent
   sous l'encart, sur toute la largeur. L'encart couvre les douze premières
   rangées et une dernière, flexible, qui prend seule ce qui dépasse : les
   éléments de gauche restent serrés. */
@media (min-width: 64rem) {
    .contenance--encart {
        display: grid;
        grid-template-columns: minmax(0, var(--largeur-texte)) minmax(0, 1fr);
        grid-template-rows: repeat(12, auto) 1fr;
        column-gap: clamp(3rem, 5vw, 4.5rem);
    }

    .contenance--encart > *,
    .contenance--encart > .presentation > * {
        grid-column: 1;
        min-width: 0;
    }

    .contenance--encart > .fil-ariane {
        grid-row: 1;
        grid-column: 1 / -1;
    }

    .contenance--encart > .presentation {
        display: contents;
    }

    .contenance--encart > .positions {
        grid-column: 1 / -1;
    }

    .contenance--encart > .presentation > .fiche,
    .contenance--encart > .presentation > .presentation__encart {
        grid-column: 2;
        grid-row: 2 / -1;
        align-self: start;
        margin: 0 0 2.5rem;
        padding: 1.25rem 1.5rem 0.5rem;
        border-top: 2px solid var(--encre);
        background: var(--surface);
    }

    .contenance--encart > .presentation > .fiche {
        display: block;
    }

    .contenance--encart > .presentation > .fiche dt {
        padding-top: 0;
        font-size: 0.8125rem;
        font-weight: 700;
        letter-spacing: 0.06em;
        text-transform: uppercase;
    }

    .contenance--encart > .presentation > .fiche dd {
        margin: 0.125rem 0 1rem;
    }

    .presentation__encart .candidats__liste--duo {
        margin-top: 0.25rem;
    }

    /* Le filet d'encre de l'encart suffit : pas de filet au-dessus de chaque candidat. */
    .presentation__encart .candidat {
        padding-top: 0;
        border-top: 0;
    }
}

/* Présentation d'un candidat : parcours, démarche, vision
   (docs/presentations.md). Le parcours renvoie à ses sources par numéro,
   listées une fois sous lui. */

.portrait {
    max-width: var(--largeur-texte);
    padding-top: clamp(1.5rem, 4vw, 2.5rem);
}

.parcours {
    margin: 0;
    padding: 0;
    list-style: none;
}

.parcours__etape {
    display: grid;
    gap: 0.125rem 1.5rem;
    padding-block: 0.625rem;
    border-top: 1px solid var(--filet);
}

.parcours__periode {
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

.renvois {
    margin-left: 0.2em;
    font-size: 0.75em;
    line-height: 0;
    vertical-align: super;
}

.parcours__sources-titre {
    margin: 1.25rem 0 0.25rem;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    font-weight: 700;
}

.parcours__sources {
    margin: 0;
    padding-left: 1.5rem;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    line-height: 1.45;
}

.parcours__sources li:target {
    background: var(--surligne);
}

.portrait__texte {
    margin: 0 0 0.5rem;
    font-size: 1.125rem;
}

.portrait__texte p {
    margin: 0;
}

.portrait__verification {
    max-width: var(--largeur-texte);
    margin-block: 2rem 0;
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

@media (min-width: 40rem) {
    .parcours__etape {
        grid-template-columns: 11rem 1fr;
    }
}

/* Source d'un fait, sous lui : titre lié et date de publication. */
.source {
    display: block;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    line-height: 1.45;
}

.positions {
    padding-top: clamp(2.5rem, 6vw, 4rem);
}

.positions__lien {
    margin-top: -0.25rem;
    font-size: 0.9375rem;
}

.positions__liste {
    margin: 0;
    padding: 0;
    list-style: none;
}

.position {
    display: grid;
    gap: 0.5rem 3rem;
    padding-block: 1.25rem 1.5rem;
    border-top: 1px solid var(--filet);
}

.position__question {
    margin: 0;
    font-size: 1.25rem;
}

.position__reponse {
    margin-bottom: 0.375rem;
    font-weight: 700;
}

.position__reponse--absente {
    color: var(--encre-douce);
    font-weight: 600;
}

.position__texte {
    margin: 0 0 0.5rem;
}

.position__texte p {
    margin: 0;
}

.position__source {
    margin: 0;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    line-height: 1.45;
}

.liens-suite {
    margin: 0;
    padding-left: 1.25rem;
}

.liens-suite li + li {
    margin-top: 0.5rem;
}

@media (min-width: 48rem) {
    .position {
        grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    }
}

/* Duel entre deux candidats : les deux candidats et le décompte en tête,
   puis chaque question avec ses deux positions, côte à côte dès 48rem,
   empilées en mobile. Même relevé que la page candidat (_position.html.twig). */

.candidats__liste--duo {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-block: 2rem 1.5rem;
}

/* Les deux photos au-dessus des noms, à toutes les largeurs. */
.candidats__liste--duo .candidat--photo {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    row-gap: 0.75rem;
}

.candidats__liste--duo .candidat--photo .photo {
    width: clamp(4.5rem, 20vw, 7rem);
}

.decompte {
    margin-bottom: 1.5rem;
}

.decompte li {
    font-weight: 400;
}

.comparaison {
    padding-block: 1.25rem 1.5rem;
    border-top: 1px solid var(--filet);
}

.comparaison__theme {
    margin-bottom: 0.25rem;
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

.comparaison .position__question {
    margin-bottom: 1rem;
}

.comparaison__positions {
    display: grid;
    gap: 1rem 3rem;
}

.comparaison__position + .comparaison__position {
    padding-top: 1rem;
    border-top: 1px dashed var(--filet);
}

.comparaison__nom {
    margin-bottom: 0.25rem;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    font-weight: 600;
}

@media (min-width: 48rem) {
    .comparaison__positions {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .comparaison__position + .comparaison__position {
        padding-top: 0;
        border-top: 0;
    }
}

/* Page d'une question : le contexte sourcé, la répartition des réponses en
   bref, puis chaque position sous le titre de sa réponse, le candidat à
   gauche et son relevé à droite dès 48rem (même grille que .position). */

.contexte {
    max-width: var(--largeur-texte);
    margin-bottom: 1rem;
    padding: 1.25rem 1.5rem;
    border-left: 2px solid var(--encre);
    background: var(--surface);
}

.contexte__titre {
    margin-bottom: 0.5rem;
    font-size: 1.25rem;
}

.contexte .source {
    margin: 0;
}

.repartition {
    margin: 0;
    padding: 0;
    list-style: none;
}

.repartition li {
    display: grid;
    gap: 0.25rem 3rem;
    padding-block: 0.875rem 1rem;
    border-top: 1px solid var(--filet);
}

.repartition__reponse {
    font-weight: 700;
}

.repartition__candidats {
    color: var(--encre-douce);
}

.position__candidat {
    margin: 0;
    font-size: 1.25rem;
}

.position__candidat + .candidat__etiquette {
    margin: 0.125rem 0 0;
}

@media (min-width: 48rem) {
    .repartition li {
        grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    }
}

/* Page d'un thème : l'introduction sourcée, le tableau comparatif (un
   candidat par ligne, une question par colonne), puis chaque question et son
   contexte, sur la grille de .position. */

.enjeux {
    max-width: var(--largeur-texte);
}

.enjeux .source {
    margin: 0;
}

.question-theme__enonce,
.question-theme__decompte {
    margin: 0.375rem 0 0;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    line-height: 1.45;
}

.question-theme__decompte {
    margin-top: 0.75rem;
}

.liens-suite--colonnes li + li {
    margin-top: 0;
}

.liens-suite--colonnes {
    display: grid;
    gap: 0.5rem 2rem;
}

@media (min-width: 48rem) {
    .liens-suite--colonnes {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Tableau comparatif (pages par thème, résultat du quiz). Sur téléphone, il
   défile à l'horizontale dans sa zone, la colonne des intitulés de ligne
   restant à l'écran ; la page, elle, ne défile jamais de côté. */

/* position: relative retient dans la zone les textes masqués des liens
   (.visuellement-masque, en position absolue) : sans elle, ils feraient
   défiler la page entière de côté. */
.tableau {
    position: relative;
    overflow-x: auto;
    margin-top: 1rem;
    border-top: 2px solid var(--encre);
    /* Focus non masqué (WCAG 2.4.11) : au clavier, le navigateur fait défiler
       la zone jusqu'à l'élément qui reçoit le focus, mais sans tenir compte
       de la colonne collée, qui le recouvrait alors en entier. La marge de
       gauche couvre cette colonne (12rem au plus, contour de focus compris) ;
       celle de droite fait défiler un lien à peine entamé au bord droit, que
       Chrome laissait sinon presque entièrement hors de la zone. */
    scroll-padding-inline: 12.5rem 3rem;
}

/* Consigne visuelle seulement : au clavier et au lecteur d'écran, le tableau
   se parcourt cellule par cellule. */
.tableau__consigne {
    margin: 0 0 0.5rem;
    color: var(--encre-douce);
    font-size: 0.875rem;
}

@media (min-width: 48rem) {
    .tableau__consigne {
        display: none;
    }
}

.tableau table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9375rem;
    line-height: 1.45;
}

.tableau th,
.tableau td {
    min-width: 11rem;
    padding: 0.75rem 1rem 0.875rem 0;
    border-bottom: 1px solid var(--filet);
    text-align: left;
    vertical-align: top;
}

.tableau thead th {
    padding-block: 0.75rem;
    border-bottom: 2px solid var(--encre);
    font-family: var(--police-titre);
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.25;
}

.tableau tbody th {
    position: sticky;
    left: 0;
    z-index: 1;
    min-width: 9rem;
    max-width: 12rem;
    background: var(--fond);
    font-weight: 600;
}

.tableau thead th:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--fond);
}

.tableau tbody th .candidat__etiquette {
    display: block;
    font-weight: 400;
}

/* Tableaux de la page Méthode : peu de texte par case. */
.tableau--compact th,
.tableau--compact td {
    min-width: 7rem;
}

.tableau--compact tbody th {
    min-width: 8rem;
}

.page-texte .tableau {
    margin-bottom: 1.5rem;
}

.case__reponse {
    display: block;
    font-weight: 700;
}

.case__reponse--absente {
    color: var(--encre-douce);
    font-weight: 600;
}

.case__source {
    display: block;
    margin-top: 0.25rem;
    color: var(--encre-douce);
    font-size: 0.875rem;
}

/* Formulaires (thème templates/_formulaire.html.twig). Le rouge et le vert
   ne servent qu'ici, toujours doublés d'un texte (docs/DESIGN.md). */

.formulaire {
    display: grid;
    gap: 1.5rem;
    justify-items: start;
    margin-block: 2rem;
}

.champ {
    display: grid;
    gap: 0.375rem;
    width: 100%;
    margin: 0;
}

.champ label,
.champ legend {
    font-weight: 600;
}

.champ input:not([type='radio']):not([type='checkbox']),
.champ textarea {
    width: 100%;
    min-height: 2.75rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--filet-fort);
    border-radius: var(--rayon);
    background: var(--surface);
    color: var(--encre);
    font: inherit;
}

.champ textarea {
    min-height: 12rem;
    resize: vertical;
}

.champ__aide {
    margin: 0;
    color: var(--encre-douce);
    font-size: 0.9375rem;
}

.champ__erreur {
    margin: 0;
    color: var(--erreur);
    font-weight: 600;
}

.champ--erreur input,
.champ--erreur textarea {
    border: 2px solid var(--erreur);
}

.champ--choix {
    padding: 0;
    border: 0;
}

.champ--choix legend {
    margin-bottom: 0.375rem;
    padding: 0;
}

.choix {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
}

.choix input {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    margin: 0.2rem 0 0;
    accent-color: var(--encre);
}

.choix label {
    padding-block: 0.125rem;
    font-weight: 400;
}

/* Piège à robots : hors de l'écran plutôt que masqué, pour que les robots
   qui ignorent les champs cachés le remplissent quand même. */
.champ-piege {
    position: absolute;
    left: -100vw;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.message {
    margin-block: 1.5rem;
    padding: 0.75rem 1rem;
    border-left: 4px solid currentColor;
    background: var(--surface);
    font-weight: 600;
}

.message--succes {
    color: var(--succes);
}

.message--erreur {
    color: var(--erreur);
}

.message a {
    color: var(--encre);
}

/* Quiz (EL-226) : une étape à la fois sur la largeur de lecture, pensé
   d'abord pour le téléphone. Une réponse est un bouton pleine largeur, plein
   d'encre quand elle est choisie ; « sans avis » a le contour en pointillés
   de la pastille « sans objet ». */

.quiz {
    max-width: var(--largeur-texte);
}

/* Dès 48rem, le quiz est centré, fil d'Ariane compris : une seule tâche à
   l'écran. Le résultat reprend toute la largeur pour son tableau. Sans
   :has (Safari avant 15.4), le fil d'Ariane reste calé à gauche. */
@media (min-width: 48rem) {
    .quiz {
        margin-inline: auto;
    }

    .contenance:has(> .quiz:not([data-etape-courante='resultat'])) > .fil-ariane {
        max-width: var(--largeur-texte);
        margin-inline: auto;
    }
}

/* Le titre de la page ne reste à l'écran que sur la présentation : pendant
   les questions, l'écran est à la question. */
.quiz:not([data-etape-courante='accueil']) .quiz__entete {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Focus donné par le script au titre de chaque étape, pour les lecteurs
   d'écran : pas de contour sur un titre qu'on ne peut pas activer. */
.quiz [tabindex='-1']:focus {
    outline: none;
}

.quiz__regles {
    display: grid;
    gap: 0.75rem;
    max-width: var(--largeur-texte);
    margin: 1.5rem 0 0;
    padding: 0;
    list-style: none;
}

.quiz__regles li {
    padding-top: 0.75rem;
    border-top: 1px solid var(--filet);
}

.quiz__reprise p {
    margin-bottom: 1rem;
}

.quiz__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    margin-block: 2rem 1.5rem;
}

.quiz__reprise .quiz__actions {
    margin: 0;
}

.quiz__etape[data-etape='question'] {
    padding-top: 0.5rem;
}

.quiz__barre {
    height: 4px;
    margin-bottom: 1.5rem;
    background: var(--filet);
}

/* La barre avance d'un cran à chaque réponse : le mouvement dit le progrès. */
.quiz__barre span {
    display: block;
    width: 0;
    height: 100%;
    background: var(--encre);
    transition: width 300ms ease-out;
}

.quiz__enonce {
    margin-bottom: 1.5rem;
    font-size: clamp(1.5rem, 1.3rem + 1vw, 2rem);
}

.quiz__numero {
    display: block;
    margin-bottom: 0.75rem;
    color: var(--encre-douce);
    font-family: var(--police-texte);
    font-size: 0.875rem;
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.quiz__reponses {
    display: grid;
    gap: 0.625rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Le chevron à droite dit qu'un appui répond et passe à la suite ; il
   avance au survol. Dessiné en bordures : rien à lire pour un lecteur
   d'écran. */
.quiz__reponse {
    position: relative;
    display: block;
    width: 100%;
    min-height: 3.5rem;
    padding: 0.875rem 3rem 0.875rem 1.125rem;
    border: 1px solid var(--filet-fort);
    border-radius: var(--rayon);
    background: var(--surface);
    color: var(--encre);
    font: 600 1.0625rem/1.35 var(--police-texte);
    text-align: left;
    cursor: pointer;
    transition: background-color var(--duree) ease-out, color var(--duree) ease-out, border-color var(--duree) ease-out, transform var(--duree) ease-out;
}

.quiz__reponse::after {
    content: '';
    position: absolute;
    top: 50%;
    right: 1.25rem;
    width: 0.5rem;
    height: 0.5rem;
    border-top: 2px solid var(--filet-fort);
    border-right: 2px solid var(--filet-fort);
    transform: translateY(-50%) rotate(45deg);
    transition: border-color var(--duree) ease-out, transform var(--duree) ease-out;
}

.quiz__reponse:hover {
    border-color: var(--encre);
    background: var(--surligne);
}

.quiz__reponse:hover::after {
    border-color: var(--encre);
    transform: translate(3px, -50%) rotate(45deg);
}

.quiz__reponse:active {
    transform: scale(0.99);
}

.quiz__reponse--sans-avis {
    margin-top: 0.5rem;
    border-style: dashed;
    background: transparent;
    color: var(--encre-douce);
}

.quiz__reponse[aria-pressed='true'] {
    border: 1px solid var(--encre);
    background: var(--encre);
    color: var(--fond);
}

.quiz__reponse[aria-pressed='true']::after {
    border-color: var(--fond);
}

/* Contraste élevé de Windows : le système efface les fonds, et la réponse
   déjà donnée devenait identique aux autres (repris de Histoires). */
@media (forced-colors: active) {
    .quiz__reponse[aria-pressed='true'] {
        forced-color-adjust: none;
        border-color: Highlight;
        background: Highlight;
        color: HighlightText;
    }

    .quiz__reponse[aria-pressed='true']::after {
        border-color: HighlightText;
    }
}

.quiz__navigation {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 2rem;
}

.quiz__navigation [data-action='suivante'] {
    margin-left: auto;
}

.quiz__themes {
    display: grid;
    gap: 1rem 2rem;
}

.choix__detail {
    display: block;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    line-height: 1.4;
}

@media (min-width: 40rem) {
    .quiz__themes {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Résultat du quiz (EL-227) : le rappel, le classement (rang, candidat,
   pourcentage et nombre de questions comparées, jauge d'encre, bilan par
   thème), les non classés, puis le tableau récapitulatif sur toute la
   largeur. Pas de couleur par candidat (docs/DESIGN.md, « Identité »). */

.quiz[data-etape-courante='resultat'] {
    max-width: none;
}

.quiz__etape--resultat > :not(.recapitulatif) {
    max-width: var(--largeur-texte);
}

.resultat__rappel {
    padding: 1rem 1.25rem;
    border-left: 2px solid var(--encre);
    background: var(--surface);
}

.resultat {
    margin: 1.5rem 0 0;
    padding: 0;
    list-style: none;
}

.resultat__ligne {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr) auto;
    grid-template-areas:
        'rang candidat score'
        'rang jauge jauge'
        'rang detail detail';
    gap: 0.5rem 0.75rem;
    padding-block: 1rem 0.75rem;
    border-top: 1px solid var(--filet);
}

/* La vignette n'a pas la place sous 360 px : le nom passerait à la ligne
   au milieu d'un mot. Masquée pour tous, elle ne change rien au classement. */
.resultat__photo {
    display: none;
}

@media (min-width: 22.5rem) {
    .resultat__ligne {
        grid-template-columns: 2rem 2.5rem minmax(0, 1fr) auto;
        grid-template-areas:
            'rang photo candidat score'
            'rang jauge jauge jauge'
            'rang detail detail detail';
    }

    .resultat__photo {
        display: block;
        grid-area: photo;
    }
}

@media (min-width: 40rem) {
    .resultat__ligne {
        grid-template-columns: 2rem 3.5rem minmax(0, 1fr) auto;
    }
}

.resultat__detail {
    grid-area: detail;
}

/* Le repli a son chevron, qui pivote à l'ouverture : sans lui, rien ne
   disait que « Détail par thème » s'ouvre. */
.resultat__detail summary {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    padding-block: 0.5rem;
    color: var(--encre-douce);
    font-size: 0.9375rem;
    font-weight: 600;
    list-style: none;
    cursor: pointer;
}

.resultat__detail summary::-webkit-details-marker {
    display: none;
}

.resultat__detail summary::before {
    content: '';
    flex: none;
    width: 0.4rem;
    height: 0.4rem;
    margin-top: -0.2rem;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform var(--duree) ease-out;
}

.resultat__detail[open] summary::before {
    margin-top: 0.2rem;
    transform: rotate(-135deg);
}

.resultat__detail summary:hover {
    color: var(--encre);
}

.bilan {
    margin: 0.25rem 0 0.5rem;
    padding: 0;
    list-style: none;
    font-size: 0.9375rem;
    line-height: 1.4;
}

.bilan__theme {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.125rem 0.75rem;
    padding-block: 0.5rem;
    border-top: 1px dashed var(--filet);
}

.bilan__nom {
    font-weight: 600;
}

.bilan__pastilles {
    display: inline-flex;
    gap: 0.25rem;
    align-items: center;
}

.bilan__texte {
    grid-column: 1 / -1;
    color: var(--encre-douce);
}

@media (min-width: 40rem) {
    .bilan__theme {
        grid-template-columns: 12rem auto minmax(0, 1fr);
        align-items: center;
    }

    .bilan__texte {
        grid-column: auto;
    }
}

.resultat__rang {
    grid-area: rang;
    color: var(--encre-douce);
    font-family: var(--police-titre);
    font-size: 1.375rem;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

.resultat__candidat {
    grid-area: candidat;
    display: flex;
    flex-direction: column;
}

.resultat__score {
    grid-area: score;
    text-align: right;
}

.resultat__pourcentage {
    display: block;
    font-family: var(--police-titre);
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.resultat__questions {
    display: block;
    margin-top: 0.25rem;
    color: var(--encre-douce);
    font-size: 0.875rem;
}

.resultat__jauge {
    grid-area: jauge;
    height: 6px;
    background: var(--filet);
}

.resultat__jauge span {
    display: block;
    height: 100%;
    background: var(--encre);
}

.resultat__non-classes {
    margin-top: 2.5rem;
}

.resultat__non-classes h3 {
    padding-top: 1rem;
    border-top: 2px solid var(--encre);
}

/* Quatre colonnes sur la largeur de lecture : la vignette reste au-dessus
   du nom, comme en mobile, sinon les noms se coupent mot à mot. */
.resultat__non-classes .candidat--photo {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

.resultat__non-classes .candidat--photo .photo {
    width: 3rem;
}

.recapitulatif,
.resultat__partage {
    margin-top: 3rem;
}

.resultat__partage p {
    overflow-wrap: anywhere;
}

/* Le don (EL-250), discret : après le partage, bouton secondaire. */
.resultat__don {
    margin-top: 3rem;
}

/* Tableau récapitulatif : la colonne des questions reste à l'écran quand le
   tableau défile. Sur téléphone, votre réponse s'y écrit sous la question
   (« Vous : … ») ; dès 48rem, elle a sa colonne, elle aussi fixe, sur fond
   d'encart pour se distinguer des candidats. */

.tableau--resultat {
    scroll-padding-inline-start: 9rem;
}

.tableau--resultat thead th:first-child,
.tableau--resultat tbody th {
    width: 8.5rem;
    min-width: 8.5rem;
    max-width: 8.5rem;
}

.tableau--resultat td {
    min-width: 9.5rem;
}

.tableau--resultat .tableau__visiteur {
    display: none;
    background: var(--surface);
    padding-left: 0.75rem;
}

.tableau__vous {
    display: block;
    margin-top: 0.375rem;
    font-weight: 400;
}

.tableau__vous [data-votre-reponse] {
    font-weight: 700;
}

.tableau__theme {
    display: block;
    margin-top: 0.125rem;
    color: var(--encre-douce);
    font-size: 0.875rem;
    font-weight: 400;
}

/* Taille des cibles (WCAG 2.5.8) : 24 px de haut au moins, le lien du thème
   étant collé à celui de la question. */
.tableau__theme a {
    display: inline-block;
    padding-block: 0.125rem;
}

.case__accord {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin-bottom: 0.25rem;
    color: var(--encre-douce);
    font-size: 0.875rem;
    font-weight: 600;
}

.case__accord:empty {
    display: none;
}

@media (min-width: 48rem) {
    /* Deux colonnes collées : les questions (10rem), puis vos réponses (11rem). */
    .tableau--resultat {
        scroll-padding-inline-start: 21.5rem;
    }

    .tableau--resultat thead th:first-child,
    .tableau--resultat tbody th {
        width: 10rem;
        min-width: 10rem;
        max-width: 10rem;
    }

    .tableau--resultat td {
        min-width: 11rem;
    }

    .tableau__vous {
        display: none;
    }

    .tableau--resultat .tableau__visiteur {
        display: table-cell;
        position: sticky;
        left: 10rem;
        z-index: 1;
    }

    .tableau--resultat thead .tableau__visiteur {
        z-index: 2;
    }
}

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