/* La feuille de style de CopiWave : le style « Registre » (tâche 1.33, spec § 4 et § 7).

   Aucun style en ligne n'est permis par la CSP : tout passe par ce fichier, servi par notre domaine,
   avec ses polices (aucune origine extérieure, aucun CDN, aucun framework).

   Le site est aussi écrit de droite à gauche (arabe) : uniquement des propriétés LOGIQUES
   (inline = le sens de l'écriture, block = l'autre axe, start/end), jamais de gauche ni de droite.

   Cinq couches, déclarées ci-dessous dans cet ordre, la dernière l'emportant sur les autres quelle
   que soit la spécificité des sélecteurs :
     reinitialisation  le strict minimum (boîtes, marges, champs qui héritent de la police) ;
     jetons            toutes les valeurs, en trois niveaux, sur `:root` et nulle part ailleurs ;
     composition       le corps, la page, les titres, les liens, les tableaux, les formulaires ;
     composants        les pièces nommées (messages, sélecteur de langue…) ;
     utilitaires       les classes à un seul effet.

   Les jetons, en trois niveaux :
     1. les primitives : les couleurs en OKLCH (L en pourcentage), l'échelle des espacements ;
     2. les rôles : `--couleur-fond`, `--police-texte`, `--marge-page`… Ils nomment des primitives
        par `var()`. Un thème sombre, plus tard, ne changera que ce niveau (décision du 27/10 :
        `color-scheme: light` d'ici là, la page est claire même sur un appareil réglé en sombre) ;
     3. les composants : `--champ-contour`, `--bouton-fond`… Ils nomment des rôles.
   Aucune valeur en dur hors des jetons (longueur, couleur, trait, police) : un essai le vérifie
   (tests/noyau/test_feuille_de_style.py), comme il vérifie que chaque jeton sert, que chaque `var()`
   vise un jeton défini, et qu'aucune propriété n'est physique. Un autre vérifie les contrastes
   (tests/noyau/test_contrastes.py). */

@layer reinitialisation, jetons, composition, composants, utilitaires;

/* Les polices : trois fichiers WOFF2 sous licence OFL, servis par notre domaine (plateforme/statique/
   polices/, leur manifeste polices.json fait foi : un essai compare les deux). Les `url()` sont
   relatives à ce fichier, car le stockage à empreinte les réécrit. Les plages `unicode-range` sont
   celles de Google Fonts : le navigateur ne télécharge le sous-ensemble arabe que pour une page qui
   contient des lettres arabes. Le sous-ensemble arabe n'a ni espace, ni chiffre, ni ponctuation
   latine : en arabe, c'est la police latine, en tête de `font-family`, qui les fournit. */
@font-face {
    font-family: "Newsreader";
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url("polices/newsreader/newsreader-latin.1ab178ccdf0e.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: "Schibsted Grotesk";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("polices/schibsted-grotesk/schibsted-grotesk-latin.feba89d402e1.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: "Alexandria";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("polices/alexandria/alexandria-arabe.317d41003c54.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}

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

    * {
        margin: 0;
    }

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

    /* Les champs et les boutons prennent la police du texte, pas celle du système. */
    input,
    select,
    textarea,
    button {
        font: inherit;
        color: inherit;
    }
}

@layer jetons {
    :root {
        color-scheme: light;

        /* Niveau 1 : les primitives. Les couleurs sont du canevas validé (spec § 4), converties en
           OKLCH ; le nombre du nom est la clarté L en millièmes (ardoise-951 : L = 95,1 %). Les
           quatre familles : l'ardoise (les gris, teintés de bleu), la marine, l'ambre, la rouille. */
        --blanc: oklch(100% 0 0);
        --ardoise-979: oklch(97.9% 0.003 265); /* #F7F8FA */
        --ardoise-972: oklch(97.2% 0.005 258); /* #F4F6F9 */
        --ardoise-966: oklch(96.6% 0.006 255); /* #F1F4F8 */
        --ardoise-951: oklch(95.1% 0.005 258); /* #EDEFF2 */
        --ardoise-929: oklch(92.9% 0.011 257); /* #E3E8EF */
        --ardoise-905: oklch(90.5% 0.009 258); /* #DCE0E6 */
        --ardoise-622: oklch(62.2% 0.016 257); /* #818791, le #B9C0CA du canevas foncé à 3,1:1 */
        --ardoise-486: oklch(48.6% 0.029 260); /* #566070 */
        --ardoise-396: oklch(39.6% 0.030 262); /* #3E4757 */
        --ardoise-242: oklch(24.2% 0.026 258); /* #18202C */
        --marine-344: oklch(34.4% 0.070 254); /* #1D3A5C */
        --ambre-980: oklch(98.0% 0.010 87); /* #FBF8F1 */
        --ambre-489: oklch(48.9% 0.1063 69.3); /* #865300 */
        --rouille-492: oklch(49.2% 0.135 39.6); /* #9E3F1B */

        /* Les espacements : une échelle, de 4 px (0,25 rem) à 56 px (3,5 rem). */
        --espace-1: 0.25rem;
        --espace-2: 0.5rem;
        --espace-3: 0.75rem;
        --espace-4: 1rem;
        --espace-5: 1.25rem;
        --espace-6: 1.5rem;
        --espace-7: 2rem;
        --espace-8: 3.5rem;
    }

    :root {
        /* Niveau 2 : les rôles. Les couleurs : jamais de vert ni de rouge pour les gains et les
           pertes (marine et rouille se distinguent aussi par la clarté) ; un nombre porte son signe. */
        --couleur-fond: var(--ardoise-951);
        --couleur-surface: var(--blanc);
        --couleur-surface-attenuee: var(--ardoise-979);
        --couleur-encre: var(--ardoise-242);
        --couleur-encre-secondaire: var(--ardoise-486);
        --couleur-note: var(--ardoise-396);
        --couleur-fond-note: var(--ardoise-972);
        --couleur-trait: var(--ardoise-905);
        --couleur-trait-fort: var(--ardoise-622);
        --couleur-accent: var(--marine-344);
        --couleur-sur-accent: var(--blanc);
        --couleur-survol: var(--ardoise-966);
        --couleur-pastille: var(--ardoise-929);
        --couleur-attention: var(--ambre-489);
        --couleur-fond-attention: var(--ambre-980);
        --couleur-gain: var(--couleur-accent);
        --couleur-perte: var(--rouille-492);
        --couleur-focus: var(--couleur-accent);

        /* Les polices : la latine toujours en tête. */
        --police-titre: "Newsreader", Georgia, serif;
        --police-texte: "Schibsted Grotesk", system-ui, sans-serif;

        /* La typographie : le texte à 14 px, interligne 1,45 ; les titres de page à 40 px
           (30 px sur téléphone), resserrés de 0,015 em et à 1,05 ; en-têtes de colonnes à 12 px. */
        --taille-texte: 0.875rem;
        --taille-titre-page: 2.5rem;
        --taille-section: 0.9375rem;
        --taille-colonne: 0.75rem;
        --interligne: 1.45;
        --interligne-titre: 1.05;
        --interlettrage-titre: -0.015em;

        /* Les petits textes à 13 px (aides, fil d'Ariane, notes), les badges à 11 px, le titre d'une
           section à 16 px. */
        --taille-petit: 0.8125rem;
        --taille-badge: 0.6875rem;
        --taille-titre-section: 1rem;

        /* La marque « CopiWave » de l'en-tête : en serif, à 24 px (22 px sur téléphone), à peine
           resserrée. */
        --taille-marque: 1.5rem;
        --interlettrage-marque: -0.01em;

        /* Les mesures : le contenu à 1 216 px au plus, la page d'entrée plus étroite ; l'en-tête
           de 64 px (56 px sur téléphone) ; des cibles d'au moins 44 px ; des coins de 4 px. */
        --largeur-contenu: 76rem;
        --largeur-entree: 28rem;
        --hauteur-entete: 4rem;
        --hauteur-cible: 2.75rem;
        --rayon: 0.25rem;
        --rayon-pastille: 0.5rem;
        --rayon-puce: 1.125rem;

        /* La page : 32 px de marge (16 px sur téléphone), 24 px en haut, 56 px en bas, 20 px entre
           les blocs. */
        --marge-page: var(--espace-7);
        --marge-haut: var(--espace-6);
        --marge-bas: var(--espace-8);
        --espace-blocs: var(--espace-5);

        /* Les traits : le filet clair, et l'anneau du focus (2 px, décalé du contrôle). */
        --trait: 1px solid var(--couleur-trait);
        --trait-focus: 2px solid var(--couleur-focus);
        --decalage-focus: 0.125rem;

        /* L'ombre des menus déroulants (l'encre à 16 %, spec § 4) : la seule de cette tâche. */
        --ombre-menu: 0 12px 32px rgba(24, 32, 44, 0.16);

        /* Le séparateur du fil d'Ariane : un chevron qui suit le sens d'écriture. */
        --fil-separateur: "›";
    }

    :root {
        /* Niveau 3 : les composants. Un champ a son fond et un contour qui se voit (3,1:1 au
           moins contre la surface et contre le fond de page : WCAG 1.4.11 en demande 3) ; le
           bouton principal est marine sous un texte blanc ; le tableau « registre » pose son
           en-tête sur un filet d'encre. */
        --champ-fond: var(--couleur-surface);
        --champ-contour: 1px solid var(--couleur-trait-fort);
        --champ-hauteur: var(--hauteur-cible);
        --bouton-fond: var(--couleur-accent);
        --bouton-texte: var(--couleur-sur-accent);
        --bouton-hauteur: var(--hauteur-cible);
        --tableau-filet-entete: 1px solid var(--couleur-encre);
        --tableau-hauteur-ligne: var(--hauteur-cible);

        /* Le tableau : le total est sous un double filet d'encre de 3 px. */
        --tableau-filet-total: 3px double var(--couleur-encre);

        /* Les champs : un champ en erreur change de contour (le message écrit reste l'essentiel), une
           carte choisie prend le contour marine, la case et le bouton radio font 18 px, une carte
           au moins 170 px. */
        --champ-contour-erreur: 1px solid var(--couleur-perte);
        --champ-carte-choisie: 1px solid var(--couleur-accent);
        --champ-case-taille: 1.125rem;
        --champ-carte-largeur: 10.625rem;

        /* Les sections, et leurs lignes « libellé | réglage » (deux colonnes, la seconde un peu plus
           large ; une seule sur un téléphone, où le libellé et le réglage s'empilent et n'ont plus à
           se tenir chacun à la hauteur d'un contrôle : une valeur à lire, « Offre | Essai 3 », ne
           prend pas 100 px). */
        --section-marge-bloc: 1.125rem;
        --ligne-colonnes: minmax(0, 1fr) minmax(0, 1.3fr);
        --ligne-ecart: var(--espace-2) var(--espace-6);
        --ligne-hauteur: var(--hauteur-cible);

        /* Les onglets-filtres : soulignés sur un écran large (un trait de 2 px posé sur le filet de
           la liste), des pastilles à coins arrondis de 18 px sur un téléphone. Le téléphone redéfinit
           ces jetons-ci, et eux seuls. */
        --onglet-rayon: 0;
        --onglet-contour: 0;
        --onglet-souligne: 2px solid transparent;
        --onglet-recouvrement: -0.0625rem;
        --onglet-liste-trait: var(--trait);
        --onglet-ecart: var(--espace-1);
        --onglet-fond: transparent;
        --onglet-fond-actif: transparent;
        --onglet-texte-actif: var(--couleur-accent);

        /* Les badges : 1 px sur 6 px de marge intérieure. */
        --badge-bloc: 0.0625rem;
        --badge-inline: 0.375rem;

        /* Un état vide : un filet en tirets, qui dit « rien ici » sans poser de carte pleine. */
        --etat-vide-contour: 1px dashed var(--couleur-trait-fort);

        /* Les menus déroulants : la liste fait 300 px au moins, avec 6 px de marge ; un lien a 10 px
           de marge en haut et en bas (et 44 px de haut au moins) ; l'onglet du menu de navigation
           repose sur un trait de 2 px ; le chevron fait 14 px, tracé de 2. */
        --menu-largeur: 18.75rem;
        --menu-remplissage: 0.375rem;
        --menu-lien-bloc: 0.625rem;
        --menu-souligne: 2px solid transparent;
        --chevron-taille: 0.875rem;
        --chevron-trait: 2;

        /* Le code QR du second facteur (allauth/elements/img.html) : 224 px, la taille d'un code qu'on
           scanne à l'écran avec un téléphone. */
        --image-qr-taille: 14rem;

        /* Un tableau plus large que l'écran le dit : une bande estompée de 24 px, couleur du filet,
           au bord où il reste du tableau à voir (voir `.tableau-boite`). */
        --defilement-bord: 1.5rem;
        --defilement-estompe: var(--couleur-trait);

        /* Le texte réservé aux lecteurs d'écran (`.visuellement-cache`) tient dans une boîte d'un
           pixel. */
        --cache-taille: 1px;

        /* Le kit (/kit) : la largeur des colonnes de champs, et la hauteur qui garde la place d'un
           menu montré ouvert. */
        --kit-colonne: 22rem;
        --kit-menus-hauteur: 14rem;

        /* L'en-tête : sur un écran large, la navigation reste en ligne et le lien à trois traits (que
           le serveur rend, et que `menu.js` change en bouton) n'est pas montré. Sur un téléphone, la
           navigation est repliée PAR DÉFAUT, sans script : elle devient un panneau en colonne, posé
           sous l'en-tête et aussi large que lui, que ce lien déplie (`:target`) ou, avec le script, ce
           bouton. Le téléphone redéfinit ces jetons, et eux seuls. */
        --navigation-affichage: flex;
        --navigation-panneau: static;
        --navigation-marge: 0;
        --navigation-sens: row;
        --bascule-affichage: none;

        /* L'empilement, du plus bas au plus haut : la navigation de l'en-tête (le panneau du
           téléphone), les listes des menus déroulants, le lien d'évitement, qui passe devant tout. */
        --pile-navigation: 10;
        --pile-menu: 20;
        --pile-evitement: 30;

        /* L'espace entre la marque, la navigation et les outils de l'en-tête : 24 px, et 8 px sur
           un téléphone, où la ligne est étroite. Le mot « Organisation » qui précède le nom de
           l'organisation courante n'y est pas montré (le nom est tronqué au besoin). */
        --entete-ecart: var(--espace-6);
        --prefixe-affichage: inline;
    }

    /* L'arabe : Alexandria derrière la police latine (qui fournit l'espace, les chiffres et la
       ponctuation latine, absents du sous-ensemble arabe), un interligne plus large pour les
       lettres liées et leurs points, et jamais d'interlettrage, qui détache les lettres. */
    :root:lang(ar) {
        --police-titre: "Newsreader", "Alexandria", Georgia, serif;
        --police-texte: "Schibsted Grotesk", "Alexandria", system-ui, sans-serif;
        --interligne: 1.7;
        --interligne-titre: 1.4;
        --interlettrage-titre: 0;
        --interlettrage-marque: 0;
        --fil-separateur: "‹";
    }

    /* Sur un téléphone, les mesures se resserrent : les règles n'en savent rien, elles citent les
       mêmes jetons. Les lignes « libellé | réglage » passent sur une colonne, et les onglets-filtres
       deviennent des pastilles. */
    @media (max-width: 40rem) {
        :root {
            --marge-page: var(--espace-4);
            --hauteur-entete: 3.5rem;
            --taille-marque: 1.375rem;
            --taille-titre-page: 1.875rem;
            --navigation-affichage: none;
            --navigation-panneau: absolute;
            --navigation-marge: var(--marge-page);
            --navigation-sens: column;
            --bascule-affichage: inline-flex;
            --entete-ecart: var(--espace-2);
            --prefixe-affichage: none;
            --ligne-colonnes: minmax(0, 1fr);
            --ligne-hauteur: 0;
            --onglet-rayon: var(--rayon-puce);
            --onglet-contour: var(--trait);
            --onglet-souligne: var(--trait);
            --onglet-recouvrement: 0;
            --onglet-liste-trait: 0;
            --onglet-ecart: var(--espace-2);
            --onglet-fond: var(--couleur-surface);
            --onglet-fond-actif: var(--couleur-accent);
            --onglet-texte-actif: var(--couleur-sur-accent);
        }
    }
}

@layer composition {
    /* Le corps est une colonne qui remplit l'écran : l'en-tête, la page (qui prend ce qui reste), le
       pied de page, en bas même quand la page est courte. */
    body {
        display: flex;
        flex-direction: column;
        min-block-size: 100%;
        background-color: var(--couleur-fond);
        color: var(--couleur-encre);
        font-family: var(--police-texte);
        font-size: var(--taille-texte);
        line-height: var(--interligne);
    }

    /* La page prend la place que l'en-tête et le pied laissent, pour que le pied reste en bas. */
    main {
        flex: 1 0 auto;
    }

    /* La page : centrée, au plus 1 216 px (marges comprises) ; la page d'entrée est plus étroite.
       La largeur est un plafond, jamais une largeur : une page étroite se lit sans défilement. Les
       blocs de la page, espacés de 20 px, sont ses enfants. */
    .page,
    .page-entree {
        inline-size: 100%;
        margin-inline: auto;
        padding-block: var(--marge-haut) var(--marge-bas);
        padding-inline: var(--marge-page);
        display: flex;
        flex-direction: column;
        gap: var(--espace-blocs);
    }

    .page {
        max-inline-size: var(--largeur-contenu);
    }

    .page-entree {
        max-inline-size: var(--largeur-entree);
    }

    /* Le titre d'une page. `.titre-page__titre` (composants/titre.html) lui donne le même aspect à un
       autre niveau de titre : une page n'a qu'un `<h1>`, et la démonstration du composant dans le
       kit, sous le titre d'une section, est un `<h3>`. */
    h1,
    .titre-page__titre {
        font-family: var(--police-titre);
        font-size: var(--taille-titre-page);
        font-weight: 500;
        line-height: var(--interligne-titre);
        letter-spacing: var(--interlettrage-titre);
    }

    h2 {
        font-size: var(--taille-section);
        font-weight: 600;
    }

    a {
        color: var(--couleur-accent);
    }

    hr {
        inline-size: 100%;
        border: 0;
        border-block-start: var(--trait);
    }

    /* Le résumé d'un bloc qui se déplie (allauth/elements/details.html) se clique. */
    summary {
        cursor: pointer;
    }

    /* Le tableau « registre », en version de base : les nombres en chiffres tabulaires, l'en-tête en
       petit gris sur un filet d'encre, des lignes de 44 px séparées d'un filet clair. */
    table {
        inline-size: 100%;
        border-collapse: collapse;
        background-color: var(--couleur-surface);
        font-variant-numeric: tabular-nums;
    }

    th,
    td {
        block-size: var(--tableau-hauteur-ligne);
        padding-block: var(--espace-1);
        padding-inline: var(--espace-3);
        text-align: start;
        border-block-end: var(--trait);
    }

    th {
        color: var(--couleur-encre-secondaire);
        font-size: var(--taille-colonne);
        font-weight: 500;
    }

    thead th {
        border-block-end: var(--tableau-filet-entete);
    }

    tbody tr:hover {
        background-color: var(--couleur-survol);
    }

    /* Les formulaires, en version de base : des champs de 44 px au contour qui se voit. Le groupe de
       champs des éléments d'allauth (`.champs`, allauth/elements/fields.html) espace les siens de
       même. */
    form,
    .champs {
        display: flex;
        flex-direction: column;
        gap: var(--espace-4);
    }

    form p {
        display: flex;
        flex-direction: column;
        gap: var(--espace-1);
    }

    label {
        font-weight: 500;
    }

    input:not([type="checkbox"], [type="radio"], [type="hidden"], [type="submit"]),
    select,
    textarea {
        min-block-size: var(--champ-hauteur);
        padding-block: var(--espace-1);
        padding-inline: var(--espace-3);
        border: var(--champ-contour);
        border-radius: var(--rayon);
        background-color: var(--champ-fond);
    }

    /* Une valeur que le serveur écrit en lettres latines (une adresse e-mail, un numéro de téléphone,
       une adresse web, un code à usage unique) reste de gauche à droite, même dans une page en
       arabe. Les champs que allauth/elements/field.html écrit lui-même (le secret de l'application,
       les codes de récupération) portent `dir="ltr"` pour la même raison. */
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[autocomplete="one-time-code"] {
        direction: ltr;
    }

    input[type="checkbox"],
    input[type="radio"] {
        accent-color: var(--couleur-accent);
    }

    input:disabled,
    select:disabled,
    textarea:disabled {
        background-color: var(--couleur-surface-attenuee);
        color: var(--couleur-encre-secondaire);
    }

    button,
    input[type="submit"] {
        min-block-size: var(--bouton-hauteur);
        padding-block: var(--espace-1);
        padding-inline: var(--espace-4);
        border: 0;
        border-radius: var(--rayon);
        background-color: var(--bouton-fond);
        color: var(--bouton-texte);
        font-weight: 600;
        cursor: pointer;
    }

    button:disabled,
    input[type="submit"]:disabled {
        background-color: var(--couleur-pastille);
        color: var(--couleur-encre-secondaire);
        cursor: not-allowed;
    }

    /* Le focus se voit toujours (WCAG 2.4.7, 1.4.11), au clavier surtout. */
    :focus-visible {
        outline: var(--trait-focus);
        outline-offset: var(--decalage-focus);
    }
}

@layer composants {
    /* ===== La mise en page de base (allauth/layouts/, mise_en_page/, tâche 1.33) =====
       L'en-tête, le pied de page et le lien d'évitement ne sont pas des composants du kit : ils
       habillent toute page, et le kit les porte comme les autres. */

    /* Le lien d'évitement : le premier élément que le clavier atteint, caché au-dessus de l'écran
       jusqu'à ce qu'il prenne le focus. */
    .lien-evitement {
        position: absolute;
        inset-block-start: 0;
        inset-inline-start: var(--espace-4);
        z-index: var(--pile-evitement);
        padding-block: var(--espace-3);
        padding-inline: var(--espace-4);
        border: var(--trait);
        border-radius: var(--rayon);
        background-color: var(--couleur-surface);
        color: var(--couleur-accent);
        font-weight: 600;
        text-decoration: none;
        transform: translateY(-100%);
    }

    .lien-evitement:focus {
        transform: none;
    }

    /* L'en-tête : blanc, sur un filet, 64 px de haut (56 px sur téléphone). Son contenu suit la page :
       1 216 px au plus, centré, avec les marges de la page. La page d'entrée n'y met que la marque. */
    .entete {
        position: relative;
        background-color: var(--couleur-surface);
        border-block-end: var(--trait);
    }

    .entete__contenu {
        display: flex;
        align-items: center;
        gap: 0 var(--entete-ecart);
        min-block-size: var(--hauteur-entete);
        max-inline-size: var(--largeur-contenu);
        margin-inline: auto;
        padding-inline: var(--marge-page);
    }

    .entete__marque {
        display: inline-flex;
        flex: none;
        align-items: center;
        min-block-size: var(--hauteur-cible);
        color: var(--couleur-encre);
        font-family: var(--police-titre);
        font-size: var(--taille-marque);
        font-weight: 500;
        letter-spacing: var(--interlettrage-marque);
        text-decoration: none;
    }

    /* La navigation principale : en ligne dans l'en-tête, et elle prend la place que la marque et les
       outils laissent. Sur un téléphone, elle est repliée par défaut (voir `--navigation-*`) : un
       panneau sous l'en-tête, que le lien à trois traits déplie. `scroll-margin` : le lien mène au
       panneau, et le navigateur laisse la hauteur de l'en-tête au-dessus de lui, au lieu de faire
       sauter la page. */
    header nav {
        display: var(--navigation-affichage);
        position: var(--navigation-panneau);
        inset-block-start: 100%;
        inset-inline: 0;
        z-index: var(--pile-navigation);
        flex: 1 1 auto;
        align-items: stretch;
        padding-inline: var(--navigation-marge);
        background-color: var(--couleur-surface);
        scroll-margin-block-start: var(--hauteur-entete);
    }

    /* Sans script, `:target` déplie le panneau (le lien à trois traits mène à lui). Une fois
       `menu.js` au travail (la classe `js` est posée à la fin de son démarrage), `:target` n'agit
       plus : c'est la classe `entete--ouvert` que le bouton bascule, avec `aria-expanded`, et les
       deux ne se contredisent jamais. Si le script échoue avant la fin, la classe n'est pas posée et
       le lien marche encore. */
    :root:not(.js) header nav:target {
        display: flex;
    }

    .entete--ouvert nav {
        display: flex;
    }

    .entete__liste {
        display: flex;
        flex-direction: var(--navigation-sens);
        flex-wrap: wrap;
        gap: 0 var(--espace-1);
        margin: 0;
        padding: 0;
        list-style: none;
    }

    /* Le sélecteur d'organisation et le menu du compte, au bout de l'en-tête. */
    .entete__outils {
        display: flex;
        align-items: center;
        gap: var(--espace-2);
        min-inline-size: 0;
        margin-inline-start: auto;
    }

    /* Le lien à trois traits, que le serveur rend, et le bouton dont `menu.js` le remplace : la
       même taille (44 px), rien ne bouge. La feuille ne le montre que sur téléphone. */
    .entete__bascule {
        display: var(--bascule-affichage);
        flex: none;
        align-items: center;
        justify-content: center;
        inline-size: var(--hauteur-cible);
        min-block-size: var(--hauteur-cible);
        padding: 0;
        background-color: transparent;
        color: var(--couleur-encre);
        text-decoration: none;
        cursor: pointer;
    }

    .entete__bascule svg {
        inline-size: calc(var(--hauteur-cible) / 2);
        block-size: calc(var(--hauteur-cible) / 2);
        fill: none;
        stroke: currentColor;
        stroke-width: var(--chevron-trait);
    }

    /* Le pied de page : sur un filet, les liens du compte au début et le sélecteur de langue à la
       fin. */
    .pied {
        border-block-start: var(--trait);
    }

    .pied__contenu {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--espace-2) var(--espace-6);
        max-inline-size: var(--largeur-contenu);
        margin-inline: auto;
        padding-block: var(--espace-3);
        padding-inline: var(--marge-page);
        color: var(--couleur-encre-secondaire);
        font-size: var(--taille-petit);
    }

    /* Sur une page d'entrée, le pied a la largeur de la carte qu'il suit. */
    .page-entree ~ .pied .pied__contenu {
        max-inline-size: var(--largeur-entree);
    }

    .pied__liens {
        display: flex;
        flex-wrap: wrap;
        gap: 0 var(--espace-5);
        margin: 0;
        padding: 0;
        list-style: none;
    }

    .pied__lien {
        display: inline-flex;
        align-items: center;
        min-block-size: var(--hauteur-cible);
        color: var(--couleur-encre-secondaire);
    }

    .pied__lien[aria-current="page"] {
        color: var(--couleur-accent);
        font-weight: 600;
    }

    /* Le sélecteur de langue, au bout du pied (« bout » suit le sens d'écriture) : le mot « Langue »
       en petit gris, la liste, et le bouton « discret » (composants/bouton.html) qui valide le choix
       sans script. Il ne rivalise pas avec les actions de la page. */
    .selecteur-langue {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        gap: var(--espace-2);
        align-items: center;
        margin-inline-start: auto;
    }

    .selecteur-langue label {
        font-weight: 400;
    }

    /* Un formulaire d'une ligne (un rôle et son bouton, ou un bouton seul) dans une cellule d'actions. */
    .en-ligne {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        gap: var(--espace-1);
        align-items: center;
    }

    /* Un lien à copier : sur toute la largeur, pour qu'il se lise en entier. */
    .lien-a-copier {
        inline-size: 100%;
    }

    /* ===== Les composants Registre (gabarits/composants/, tâche 1.33) =====
       Chacun a sa page de démonstration, /kit. Le nom de la classe est celui du composant, ses
       modificateurs s'écrivent `--genre`, ses parties `__partie`. Rien ici ne cite une valeur : tout
       passe par les jetons. */

    /* --- Les boutons (composants/bouton.html) : quatre genres, 44 px de haut au moins. Le principal
       et le danger passent à l'encre au survol (le lien du canevas fait de même). */
    .bouton {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--espace-2);
        min-block-size: var(--bouton-hauteur);
        padding-block: var(--espace-1);
        padding-inline: var(--espace-4);
        border: 0;
        border-radius: var(--rayon);
        font-weight: 600;
        text-decoration: none;
        cursor: pointer;
    }

    .bouton--principal {
        background-color: var(--bouton-fond);
        color: var(--bouton-texte);
    }

    .bouton--principal:hover,
    .bouton--danger:hover {
        background-color: var(--couleur-encre);
    }

    .bouton--secondaire {
        border: var(--trait);
        background-color: var(--couleur-surface);
        color: var(--couleur-encre);
    }

    .bouton--discret {
        background-color: transparent;
        color: var(--couleur-accent);
    }

    .bouton--secondaire:hover,
    .bouton--discret:hover {
        background-color: var(--couleur-survol);
    }

    .bouton--danger {
        background-color: var(--couleur-perte);
        color: var(--couleur-sur-accent);
    }

    /* Désactivé : le même gris pour tous les genres, après les survols pour qu'il les écrase. */
    .bouton:disabled,
    .bouton[aria-disabled="true"] {
        border: 0;
        background-color: var(--couleur-pastille);
        color: var(--couleur-encre-secondaire);
        cursor: not-allowed;
    }

    /* Un bouton posé seul dans la page (« Ajouter » sous un tableau) garde sa largeur : la page est une
       colonne, qui étire ses enfants. Dans un groupe en colonne, au contraire, il s'étire. */
    .page > .bouton,
    .page-entree > .bouton {
        align-self: start;
    }

    /* Le code QR (allauth/elements/img.html) : d'une taille qu'on scanne, jamais étiré à la largeur de
       la carte qui le porte. */
    .image-qr {
        inline-size: var(--image-qr-taille);
        max-inline-size: 100%;
        block-size: auto;
    }

    /* --- Les champs (composants/champ.html) : le libellé, l'aide en petit gris dessous, le contrôle,
       l'erreur écrite. Les contrôles eux-mêmes sont stylés par la couche `composition`. */
    .champ,
    .champ__entete,
    .champ__controle {
        display: flex;
        flex-direction: column;
        gap: var(--espace-1);
    }

    .champ__controle {
        min-inline-size: 0;
    }

    .champ__libelle {
        font-weight: 500;
    }

    .champ__aide {
        color: var(--couleur-encre-secondaire);
        font-size: var(--taille-petit);
    }

    /* L'aide d'un mot de passe est la liste des règles de Django. */
    .champ__aide ul {
        padding-inline-start: var(--espace-5);
    }

    .champ__erreur {
        color: var(--couleur-perte);
        font-weight: 600;
    }

    /* Les erreurs d'un formulaire d'allauth qui ne sont celles d'aucun champ visible (celles du
       formulaire, celles d'un champ caché) : en tête, des messages l'un sous l'autre. */
    .champs__erreurs {
        display: flex;
        flex-direction: column;
        gap: var(--espace-2);
    }

    .champ--erreur input[aria-invalid="true"]:not([type="checkbox"], [type="radio"]),
    .champ--erreur select[aria-invalid="true"],
    .champ--erreur textarea[aria-invalid="true"] {
        border: var(--champ-contour-erreur);
    }

    /* Une case, un bouton radio : leur libellé les suit, sur une cible de 44 px. */
    .champ__case,
    .champ__options label {
        display: flex;
        align-items: center;
        gap: var(--espace-3);
        min-block-size: var(--hauteur-cible);
        font-weight: 400;
        cursor: pointer;
    }

    .champ input[type="checkbox"],
    .champ input[type="radio"] {
        flex: none;
        inline-size: var(--champ-case-taille);
        block-size: var(--champ-case-taille);
        margin: 0;
    }

    /* Le choix en segments : les options côte à côte dans un même cadre, un seul choix. */
    .champ--segmente .champ__options > div {
        display: inline-flex;
        flex-wrap: wrap;
        border: var(--champ-contour);
        border-radius: var(--rayon);
        background-color: var(--champ-fond);
        overflow: hidden;
    }

    .champ--segmente .champ__options > div > div + div {
        border-inline-start: var(--champ-contour);
    }

    .champ--segmente .champ__options label {
        padding-inline: var(--espace-3);
    }

    .champ--segmente .champ__options label:has(input:checked) {
        background-color: var(--couleur-pastille);
        font-weight: 600;
    }

    /* Le cadre coupe tout ce qui dépasse, l'anneau du focus compris : il se dessine en dedans. */
    .champ--segmente .champ__options label:has(input:focus-visible) {
        outline: var(--trait-focus);
        outline-offset: calc(var(--decalage-focus) * -1);
    }

    /* Le choix en cartes : une carte par option, plusieurs possibles ; la carte choisie a le contour
       marine. */
    .champ--cartes .champ__options > div {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(var(--champ-carte-largeur), 1fr));
        gap: var(--espace-2);
    }

    .champ--cartes .champ__options label {
        padding-inline: var(--espace-3);
        border: var(--trait);
        border-radius: var(--rayon);
        background-color: var(--couleur-surface);
    }

    .champ--cartes .champ__options label:has(input:checked) {
        border: var(--champ-carte-choisie);
    }

    /* --- Les sections (composants/section.html) : une carte blanche, son titre, son aide, ses lignes. */
    .section {
        min-inline-size: 0;
        margin: 0;
        padding-block: var(--section-marge-bloc);
        padding-inline: var(--espace-5);
        border: var(--trait);
        border-radius: var(--rayon);
        background-color: var(--couleur-surface);
    }

    /* Un formulaire d'allauth (allauth/elements/form.html) posé dans la page large (le mot de passe,
       l'activation du code) se lit à la largeur d'une page d'entrée : des champs de 1 150 px ne se
       lisent pas. Les autres sections de la page gardent toute la largeur. */
    .page > form.section {
        max-inline-size: var(--largeur-entree);
    }

    .section__titre {
        margin-block-end: var(--espace-1);
        padding: 0;
        font-size: var(--taille-titre-section);
        font-weight: 600;
    }

    .section__aide {
        margin-block-end: var(--espace-3);
        color: var(--couleur-encre-secondaire);
        font-size: var(--taille-petit);
    }

    /* Une ligne « libellé | réglage », séparée de la précédente par un filet clair. Après `.champ`,
       dont elle reprend la place quand un champ s'écrit en ligne. */
    .ligne {
        display: grid;
        grid-template-columns: var(--ligne-colonnes);
        gap: var(--ligne-ecart);
        align-items: start;
        padding-block: var(--espace-3);
        border-block-start: var(--trait);
    }

    .ligne__nom {
        display: flex;
        flex-direction: column;
        justify-content: center;
        min-block-size: var(--ligne-hauteur);
    }

    .ligne .champ__libelle {
        font-weight: 600;
    }

    .ligne__valeur {
        display: flex;
        flex-direction: column;
        justify-content: center;
        min-block-size: var(--ligne-hauteur);
        min-inline-size: 0;
    }

    /* Deux champs l'un sous l'autre dans une section : 16 px entre eux (les lignes, elles, se
       séparent par leur filet). */
    .section > .champ:not(.ligne) + .champ:not(.ligne) {
        margin-block-start: var(--espace-4);
    }

    /* --- Le tableau registre (composants/tableau.html) : une boîte qui défile à l'horizontale, une
       carte blanche sauf dans une section. Il complète le tableau de base de la couche `composition`. */
    /* Rien ne dit qu'une boîte défile quand son tableau est plus large que l'écran (la colonne des
       actions, hors de vue, sur un téléphone). Deux bandes estompées, une à chaque bord de la boîte
       (attachement `scroll` : elles restent au bord), et par-dessus elles deux caches de la couleur
       de la surface, qui défilent avec le contenu (attachement `local`) : au départ du défilement,
       le cache du bord où l'on est cache sa bande ; il reste la bande du bord où il reste du
       tableau, et elle disparaît quand on y arrive. En CSS seul, sans script. Les bandes sont
       symétriques : elles suivent le défilement dans les deux sens d'écriture, sans qu'aucune règle
       ne nomme la gauche ou la droite (les dégradés sont des angles, les positions des
       pourcentages).
       La boîte est positionnée : un texte réservé aux lecteurs d'écran (`.visuellement-cache`,
       `position: absolute`) posé dans une cellule hors de vue y reste contenu, au lieu de pousser
       la largeur de la page (le titre « Actions » de la liste des clés d'accès, à 390 px). */
    .tableau-boite {
        position: relative;
        max-inline-size: 100%;
        overflow-x: auto;
        background-image:
            linear-gradient(90deg, var(--couleur-surface), var(--couleur-surface)),
            linear-gradient(270deg, var(--couleur-surface), var(--couleur-surface)),
            linear-gradient(90deg, var(--defilement-estompe), transparent),
            linear-gradient(270deg, var(--defilement-estompe), transparent);
        background-position:
            0 0,
            100% 0,
            0 0,
            100% 0;
        background-size:
            var(--defilement-bord) 100%,
            var(--defilement-bord) 100%,
            var(--defilement-bord) 100%,
            var(--defilement-bord) 100%;
        background-repeat: no-repeat;
        background-attachment: local, local, scroll, scroll;
    }

    .tableau-boite--cadre {
        padding-block: var(--espace-4) var(--espace-3);
        padding-inline: var(--espace-5);
        border: var(--trait);
        border-radius: var(--rayon);
        background-color: var(--couleur-surface);
    }

    /* Les chiffres tabulaires pour les nombres seulement : sur un nom ou une liste (« PAPA, JEJE »),
       ils élargissent la virgule et les espaces. */
    .tableau {
        background-color: transparent;
        font-variant-numeric: normal;
    }

    /* Une ligne fait 44 px : les cellules ne passent pas à la ligne, et c'est la boîte qui défile
       quand le tableau est plus large que l'écran. */
    .tableau th,
    .tableau td {
        padding-inline: 0 var(--espace-4);
        white-space: nowrap;
    }

    .tableau__nombre {
        font-variant-numeric: tabular-nums;
        text-align: end;
    }

    .tableau__nom {
        font-weight: 600;
    }

    .tableau__actions {
        text-align: end;
        white-space: nowrap;
    }

    /* Les formulaires d'une cellule d'actions (un rôle et son bouton, « Retirer ») se rangent à la fin
       de la cellule, sous leur titre de colonne : la colonne est plus large que ce qu'elle porte. Ils
       restent sur une ligne : c'est la boîte du tableau qui défile quand l'écran est étroit, plutôt
       que des lignes de tableau de 100 px. */
    .tableau__actions .groupe-boutons,
    .tableau__actions .en-ligne {
        flex-wrap: nowrap;
        justify-content: end;
    }

    .tableau__total th,
    .tableau__total td {
        border-block-start: var(--tableau-filet-total);
        border-block-end: 0;
        font-weight: 600;
    }

    /* --- Les onglets-filtres (composants/onglets.html) : soulignés ; des pastilles sur un téléphone
       (les jetons `--onglet-*` changent, ces règles non). */
    .onglets__liste {
        display: flex;
        flex-wrap: wrap;
        gap: var(--onglet-ecart);
        margin: 0;
        padding: 0;
        border-block-end: var(--onglet-liste-trait);
        list-style: none;
    }

    .onglets__lien {
        display: inline-flex;
        align-items: center;
        gap: var(--espace-2);
        min-block-size: var(--hauteur-cible);
        margin-block-end: var(--onglet-recouvrement);
        padding-inline: var(--espace-3);
        border: var(--onglet-contour);
        border-block-end: var(--onglet-souligne);
        border-radius: var(--onglet-rayon);
        background-color: var(--onglet-fond);
        color: var(--couleur-encre);
        text-decoration: none;
    }

    .onglets__lien:hover {
        background-color: var(--couleur-survol);
    }

    .onglets__lien[aria-current="true"] {
        border-color: var(--couleur-accent);
        background-color: var(--onglet-fond-actif);
        color: var(--onglet-texte-actif);
        font-weight: 600;
    }

    .onglets__compteur {
        color: var(--couleur-encre-secondaire);
        font-weight: 400;
    }

    .onglets__lien[aria-current="true"] .onglets__compteur {
        color: inherit;
    }

    /* --- Les messages (composants/message.html) : le niveau est écrit en tête, en couleur, et le
       fond le soutient (note pour l'information, ambre clair pour l'attention). Le filet est le
       même des quatre côtés : jamais une bordure colorée d'un seul côté (spec § 2, anti-buts). */
    .message {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: var(--espace-1) var(--espace-3);
        padding-block: var(--espace-3);
        padding-inline: var(--espace-4);
        border: var(--trait);
        border-radius: var(--rayon);
        background-color: var(--couleur-surface);
        color: var(--couleur-encre);
    }

    .message__etiquette {
        font-weight: 700;
    }

    .message__texte {
        flex: 1 1 0;
        min-inline-size: 0;
    }

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

    .message--information {
        background-color: var(--couleur-fond-note);
        color: var(--couleur-note);
    }

    .message--attention {
        background-color: var(--couleur-fond-attention);
    }

    .message--attention .message__etiquette {
        color: var(--couleur-attention);
    }

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

    /* --- Les badges (composants/badge.html) : un mot court, sur 11 px. */
    .badge {
        display: inline-block;
        padding-block: var(--badge-bloc);
        padding-inline: var(--badge-inline);
        border-radius: var(--rayon-pastille);
        font-size: var(--taille-badge);
        font-weight: 600;
    }

    .badge--accent {
        background-color: var(--couleur-accent);
        color: var(--couleur-sur-accent);
    }

    .badge--neutre {
        background-color: var(--couleur-pastille);
        color: var(--couleur-encre);
    }

    .badge--attention {
        background-color: var(--couleur-fond-attention);
        color: var(--couleur-attention);
    }

    /* --- L'état vide (composants/etat_vide.html) : « rien ici », et la suite. */
    .etat-vide {
        display: flex;
        flex-direction: column;
        align-items: start;
        gap: var(--espace-2);
        padding-block: var(--espace-7);
        padding-inline: var(--espace-6);
        border: var(--etat-vide-contour);
        border-radius: var(--rayon);
        background-color: var(--couleur-surface);
    }

    .etat-vide__titre {
        font-size: var(--taille-section);
    }

    .etat-vide__texte {
        color: var(--couleur-encre-secondaire);
        font-size: var(--taille-petit);
    }

    /* --- Le titre d'une page (composants/titre.html) : le fil d'Ariane, le titre, la note, et les
       actions à l'autre bout de la ligne. */
    .titre-page {
        display: flex;
        flex-wrap: wrap;
        align-items: end;
        justify-content: space-between;
        gap: var(--espace-4);
    }

    .titre-page__texte {
        min-inline-size: 0;
    }

    .titre-page__note {
        margin-block-start: var(--espace-2);
        color: var(--couleur-encre-secondaire);
        font-size: var(--taille-petit);
    }

    /* Les actions d'une page, et le groupe de boutons des éléments d'allauth (`.groupe-boutons`,
       allauth/elements/button_group.html, panel.html, provider_list.html) : côte à côte, qui passent à
       la ligne quand la place manque. */
    .titre-page__actions,
    .groupe-boutons {
        display: flex;
        flex-wrap: wrap;
        gap: var(--espace-2);
    }

    /* Un groupe de boutons peut être une liste : sans puces ni retrait. Il peut être en colonne (les
       boutons prennent alors toute la largeur), ou suivre un texte (le corps d'un panneau). */
    .groupe-boutons {
        padding: 0;
        list-style: none;
    }

    .groupe-boutons--colonne {
        flex-direction: column;
    }

    .groupe-boutons--suite {
        margin-block-start: var(--espace-3);
    }

    .fil {
        margin-block-end: var(--espace-1);
        color: var(--couleur-encre-secondaire);
        font-size: var(--taille-petit);
    }

    .fil__liste {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        margin: 0;
        padding: 0;
        list-style: none;
    }

    /* Le chevron est décoratif : son texte de remplacement est vide (`/ ""`), pour que les lecteurs
       d'écran ne lisent pas « supérieur à » entre deux étapes. */
    .fil__etape + .fil__etape::before {
        content: var(--fil-separateur) / "";
        margin-inline: var(--espace-2);
    }

    .fil a {
        color: var(--couleur-encre-secondaire);
    }

    /* --- Le menu déroulant (composants/menu_deroulant.html) : un bouton, et sous lui sa liste. Sans
       script, le bouton est un lien et la liste est cachée (`hidden`) ; `menu.js` les anime. Trois variantes : un onglet de la barre, un bouton à filet, un rond aux initiales. */
    .menu-deroulant {
        position: relative;
        display: flex;
        min-inline-size: 0;
    }

    /* Le lien simple de la barre (`.entete__lien`, « Tableau de bord ») est un onglet comme le bouton
       d'un groupe : il partage ses règles, au lieu de les recopier. Le bouton, que `menu.js` met à la
       place du lien d'entrée, y est remis à plat (coins, graisse) : sans cela la feuille de base le
       montrerait en bouton marine, et le lien et le bouton ne se ressembleraient pas. */
    .menu-deroulant__bouton,
    .entete__lien {
        display: inline-flex;
        align-items: center;
        gap: var(--espace-2);
        min-block-size: var(--hauteur-cible);
        min-inline-size: 0;
        padding-inline: var(--espace-3);
        border: 0;
        border-block-end: var(--menu-souligne);
        border-radius: 0;
        background-color: transparent;
        color: var(--couleur-encre);
        font-weight: 400;
        text-decoration: none;
        cursor: pointer;
    }

    .menu-deroulant__bouton:hover,
    .menu-deroulant__bouton[aria-expanded="true"],
    .entete__lien:hover {
        background-color: var(--couleur-survol);
    }

    .menu-deroulant--navigation .menu-deroulant__bouton,
    .entete__lien {
        block-size: var(--hauteur-entete);
    }

    /* Un onglet de la barre touche le haut de la fenêtre : son anneau de focus se dessine en dedans,
       un anneau extérieur y serait coupé. */
    .menu-deroulant--navigation .menu-deroulant__bouton:focus-visible,
    .entete__lien:focus-visible {
        outline-offset: calc(var(--decalage-focus) * -1);
    }

    .menu-deroulant--actif .menu-deroulant__bouton,
    .entete__lien[aria-current="page"] {
        border-block-end-color: var(--couleur-accent);
        color: var(--couleur-accent);
        font-weight: 600;
    }

    .menu-deroulant--bouton .menu-deroulant__bouton {
        border: var(--trait);
        border-radius: var(--rayon);
        background-color: var(--couleur-surface);
        font-weight: 600;
    }

    .menu-deroulant--bouton .menu-deroulant__bouton:hover,
    .menu-deroulant--bouton .menu-deroulant__bouton[aria-expanded="true"] {
        background-color: var(--couleur-survol);
    }

    .menu-deroulant--rond .menu-deroulant__bouton {
        justify-content: center;
        inline-size: var(--hauteur-cible);
        padding: 0;
        border: var(--trait);
        border-radius: 50%;
        background-color: var(--couleur-pastille);
        color: var(--couleur-accent);
        font-size: var(--taille-petit);
        font-weight: 700;
    }

    /* Le nom d'un bouton se tronque (« … ») plutôt que de pousser le reste hors de la barre. */
    .menu-deroulant__bouton > span {
        min-inline-size: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .menu-deroulant__prefixe {
        display: var(--prefixe-affichage);
        color: var(--couleur-encre-secondaire);
        font-weight: 400;
    }

    .menu-deroulant__chevron {
        flex: none;
        inline-size: var(--chevron-taille);
        block-size: var(--chevron-taille);
        fill: none;
        stroke: currentColor;
        stroke-width: var(--chevron-trait);
    }

    .menu-deroulant__liste {
        position: absolute;
        inset-block-start: 100%;
        inset-inline-start: 0;
        z-index: var(--pile-menu);
        min-inline-size: var(--menu-largeur);
        margin: 0;
        padding: var(--menu-remplissage);
        border: var(--trait);
        border-radius: var(--rayon);
        background-color: var(--couleur-surface);
        box-shadow: var(--ombre-menu);
        list-style: none;
    }

    /* Le bouton d'organisation et le rond du compte sont au bout de la barre : leur liste s'aligne
       sur la fin, pour ne pas sortir de l'écran. */
    .menu-deroulant--bouton .menu-deroulant__liste,
    .menu-deroulant--rond .menu-deroulant__liste {
        inset-inline: auto 0;
    }

    .menu-deroulant__lien {
        display: flex;
        flex-direction: column;
        justify-content: center;
        min-block-size: var(--hauteur-cible);
        padding-block: var(--menu-lien-bloc);
        padding-inline: var(--espace-3);
        border-radius: var(--rayon);
        color: var(--couleur-encre);
        font-weight: 600;
        text-decoration: none;
    }

    .menu-deroulant__lien:hover,
    .menu-deroulant__lien[aria-current="page"] {
        background-color: var(--couleur-survol);
        color: var(--couleur-accent);
    }

    .menu-deroulant__aide {
        color: var(--couleur-encre-secondaire);
        font-size: var(--taille-colonne);
        font-weight: 400;
    }

    .menu-deroulant__element--separe {
        margin-block-start: var(--espace-1);
        padding-block-start: var(--espace-1);
        border-block-start: var(--trait);
    }

    /* --- Le kit (/kit, noyau/kit.py) : la mise en page de la planche, rien de plus. */
    .kit__bloc {
        display: flex;
        flex-direction: column;
        gap: var(--espace-4);
    }

    .kit__echantillons {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--espace-3);
    }

    .kit__colonnes {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--kit-colonne)), 1fr));
        gap: var(--espace-blocs);
        align-items: start;
    }

    /* Une barre qui garde la place des menus montrés ouverts. */
    .kit__menus {
        display: flex;
        flex-wrap: wrap;
        align-items: start;
        gap: var(--espace-2);
        min-block-size: var(--kit-menus-hauteur);
        padding-inline: var(--espace-4);
        border: var(--trait);
        background-color: var(--couleur-surface);
    }

    /* La barre du bouton d'organisation et du rond du compte : au bout de la ligne, comme dans
       l'en-tête. */
    .kit__menus--fin {
        justify-content: end;
    }
}

@layer utilitaires {
    /* Ce qui est caché l'est : sans cette règle, un `display: flex` posé plus bas (un champ de
       formulaire, une page) montre quand même l'élément `hidden`, que le navigateur ne cache que
       par sa propre feuille, la plus faible de toutes. */
    [hidden] {
        display: none;
    }

    /* Un texte pour les lecteurs d'écran seulement : il ne se voit pas et ne prend aucune place,
       mais il se lit (le titre d'une colonne qui ne montre qu'un bouton, « Actions »). Pas
       `display: none` ni `hidden`, que les lecteurs d'écran ignorent. */
    .visuellement-cache {
        position: absolute;
        inline-size: var(--cache-taille);
        block-size: var(--cache-taille);
        margin: calc(var(--cache-taille) * -1);
        padding: 0;
        border: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    /* Une cellule alignée en fin de ligne (les actions d'un tableau) : à droite en français, à
       gauche en arabe. `align="right"` d'allauth est physique, il n'y a pas de style en ligne (CSP). */
    .cellule-fin {
        text-align: end;
    }

    /* Le sens d'un montant (le filtre `sens` de noyau/templatetags/nombres.py) : marine pour un gain,
       rouille pour une perte, jamais vert ni rouge. Le signe écrit reste ce qui dit la vérité. */
    .gain {
        color: var(--couleur-gain);
    }

    .perte {
        color: var(--couleur-perte);
    }
}
