/* =============================================================================
   atelier.css : la feuille du pré-alpha de FAA (train PA-0).
   Copie de socle.css (kit/briques/design, brique « système de design ») dont SEULE la section MARQUE change : les jetons de la
   maquette (tete.html, l. 11-24 : accent vert #006850 (A23, PA-6), neutres verdâtres, clair et sombre) posés sur les 32 jetons du kit.
   Aucune ressource externe : polices hébergées par le logiciel (public/fonts, AJ-10), aucune police distante. Les règles de la dernière partie (PA-0) sont
   propres à ce logiciel ; elles ne portent aucune couleur en dur, seulement des jetons.
   ========================================================================== */

/* =============================================================================
   AJ-10 (D-a, 4 nov. 2026) : les polices de la maquette, HÉBERGÉES par le logiciel (public/fonts, woff2 sous-ensemble latin, licence OFL à côté).
   Neuf faces : Noto Serif 600, 600 italique, 700 ; Open Sans 400 à 700 ; IBM Plex Mono 400 et 500. `font-display: swap` : le texte s'affiche tout de suite
   dans la pile du système, puis passe à la police. Open Sans 400 et Noto Serif 700 sont préchargées (layouts). Aucun lien vers un tiers : la politique
   de contenu garde `font-src 'self'`. Les chemins sont relatifs à cette feuille. PolicesTest garde la liste, les fichiers et l'absence d'URL externe.
   ========================================================================== */

@font-face { font-family: "Noto Serif"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/noto-serif-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Noto Serif"; font-style: italic; font-weight: 600; font-display: swap; src: url("../fonts/noto-serif-latin-600-italic.woff2") format("woff2"); }
@font-face { font-family: "Noto Serif"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/noto-serif-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/open-sans-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/open-sans-latin-500-normal.woff2") format("woff2"); }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/open-sans-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/open-sans-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2"); }


/* =============================================================================
   socle.css : la feuille neutre du kit (brique « système de design », versée le 18 oct. 2026).

   Copie réduite de la feuille de production de la plateforme (v.105, Design-1), SANS ses sections propres.
   Ce qui est retiré, section par section, et pourquoi :
     - B3, « écrans d'un logiciel » (.ecrans-logiciel) : la barre d'écrans des prototypes de la plateforme ;
     - B3, « espace du mandat » (.espace-mandat et ses onglets) : l'en-tête d'un écran de la plateforme, branché sur
       sa navigation ; B3, « retour » (.retour) : le repli déclaré de son contrôleur ;
     - B4, « administration » (.etage-administration, .cartes-administration) : l'index d'un écran de la plateforme ;
     - B8, quatre icônes de couches (data-couche="clients", "mandats", "finance", "administration") : les couches de
       la plateforme ; la couche par défaut (la grille) reste, un hôte dessine les siennes ;
     - B9, « document rendu » (.document, mark.trou) : le texte d'une offre ; B13 « offre côté client » ;
     - B12, « qui invite » (.page-seule .qui) : la page d'invitation de la plateforme ;
     - B14, « tableau de suivi » (.tableau-colonnes) : l'espace de suivi du client ;
     - B15, « plan et avancement » (.banniere-plan, .grille-plan, .plan-client, .trait-*, .gantt-jour, .indicateurs-jour) :
       le Gantt et la bannière du plan.
   Chaque section retirée est un écran, un objet ou une navigation que seul cet hôte possède : elle ne passerait
   pas le test du switch (kit/design-systeme.md, section 3). Les lignes qui les nommaient dans les blocs
   d'impression, de pointeur grossier, de téléphone et de mouvement réduit sont retirées avec elles.

   AUCUNE POLICE EXTERNE, AUCUN SCRIPT, AUCUNE IMAGE EXTERNE : polices hébergées par le logiciel (AJ-10, plus bas), icônes en SVG `data:` posées en masque
   sur `currentColor`. Charger une police chez un tiers lui enverrait l'adresse IP de chaque visiteur à chaque page.

   DEUX PARTIES :
     A. LA MARQUE : ce qui change d'un client à l'autre (32 jetons par thème) ; le gabarit commenté, jeton par jeton,
        est `marque-gabarit.css`, prêt à être recopié et recoloré ;
     B. LE SOCLE : les couleurs d'état, les échelles, la structure et les composants (36 jetons par thème).
   Chaque bloc :root porte deux marqueurs, MARQUE puis SOCLE, que lit Socle\Design\Theme::frontiere() : un
   rebranding ne touche que la section MARQUE, et aucune règle de composant n'écrit une couleur en dur
   (l'impression et le contraste forcé exceptés). Les tests de thème lisent le PREMIER `:root` et le bloc sombre :
   mêmes 68 noms des deux côtés, échelles recopiées à l'identique.

   NUMÉROTATION de la feuille de production, conservée : B9, B13, B14 et B15 sont absentes.

   ORDRE DU FICHIER : A. jetons · contrastes promis ; B. base · structure · barre · onglets · contenu · tableaux ·
   formulaires · états · icônes · téléphone (B10) · impression (B11) · pages autonomes (B12, connexion).
   ========================================================================== */


/* ═════════════════════════════════════════════════════════════════════════
   PARTIE A : LA MARQUE (jetons de la maquette du logiciel, recolorés sur les 32 jetons du kit)
   ═════════════════════════════════════════════════════════════════════════ */

:root {
    color-scheme: light dark;

    /* MARQUE */
    --marque: #006850;
    --accent: var(--marque);
    --accent-texte: #ffffff;
    --accent-survol: #00573f;
    --accent-doux: #e1efe9;
    --focus: var(--marque);
    --selection: #c5e0d5;
    --logo: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.5 2.5 8.5l9.5 5 9.5-5-9.5-5Z'/%3E%3Cpath d='m2.5 12.5 9.5 5 9.5-5M2.5 16.5l9.5 5 9.5-5'/%3E%3C/svg%3E");
    --barre-haut: #0f1311;
    --barre-bas: #161c19;
    --barre-texte: #eef2ef;
    --barre-lien: #eef2ef;
    --barre-doux: #a7b1ab;
    --barre-survol: #1f2824;
    --barre-courant: #1b2320;
    --barre-repere: #5ccaa6;
    --barre-point: #f0b44c;
    --barre-trait: #2a322e;
    --barre-bord: #46514b;
    --fond: #f3f5f1;
    --carte: #ffffff;
    --creux: #eef1ec;
    --survol: #e8ede6;
    --bord: #dadfd8;
    --bord-fort: #b5bdb3;
    --bord-champ: #737d79; /* AV1 point 1 : filet des champs à 3:1 (WCAG 1.4.11), gardé. Maquette (--line-strong) : #b5bdb3. Un seul jeton à changer pour basculer. */
    --bord-bouton: var(--bord-fort); /* AJ-17 lot 2, H5 : filet du bouton secondaire = celui de la maquette (--line-strong, 1,8:1). Basculer vers var(--bord-champ) pour 3:1. */
    --texte: #1a201d;
    --doux: #586159;
    --info: var(--marque);
    --info-fond: #e1efe9;
    --info-bord: #a9cfc1;
    --ombre-repos: 0 1px 2px #0000000f;
    --ombre-flottant: 0 8px 30px #00000030;
    --ombre-enfonce: inset 0 2px 4px rgb(10 20 16 / .45);
    /* AJ-17 lot 3 (L3-R) : les huit couleurs des barres du Gantt (maquette v17, --gxb0 à --gxb7 : fond de la barre ; --gxf0 à --gxf7 : encre du numéro sur ce fond). À la MARQUE : la teinte de la 1re et de la 7e est voisine de la sarcelle, que le SOCLE n'a pas le droit de porter. */
    --gxb0: #006850; --gxf0: #ffffff; --gxb1: #8a5a00; --gxf1: #ffffff; --gxb2: #1d4f91; --gxf2: #ffffff; --gxb3: #a1302b; --gxf3: #ffffff;
    --gxb4: #5b3a8c; --gxf4: #ffffff; --gxb5: #456b0f; --gxf5: #ffffff; --gxb6: #0b6a7a; --gxf6: #ffffff; --gxb7: #7a3b5e; --gxf7: #ffffff;
    --postit: #fbe38a; --postit-bord: #e7c955; --postit-encre: #3a3000;   /* AJ-25 : le papier du post-it (jetons de la maquette, --postit*) */


    /* SOCLE */
    /* Les états : constants d'un client à l'autre, chacun avec sa variante sombre. */
    --succes: #456b0f;
    --succes-fond: #eaf1d8;
    --succes-bord: #c9dba0;
    --attention: #8a5a00;
    --attention-fond: #f9eed6;
    --attention-bord: #e6c77a;
    --alerte: #a1302b;
    --alerte-fond: #f8e3e1;
    --alerte-bord: #f3c6c6;
    /* Les échelles, non chromatiques, recopiées à l'identique dans les deux thèmes (A68). */
    --police: "Open Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --police-titre: "Noto Serif", "Droid Serif", Georgia, "Times New Roman", serif;
    --police-mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;
    --taille-legende: .75rem; --taille-petite: .8125rem; --taille-texte: .875rem; --taille-corps: .9375rem; --taille-titre-carte: 1rem; --taille-section: 1.125rem; --taille-chiffre: 1.75rem; --taille-ecran: 1.625rem;
    --interligne: 1.5; --interligne-titre: 1.25; --suivi-surtitre: .06em;
    --espace-1: .25rem; --espace-2: .5rem; --espace-3: .75rem; --espace-4: 1rem; --espace-5: 1.25rem; --espace-6: 1.5rem; --espace-8: 2rem;
    --rayon-controle: .375rem; --rayon-carte: .625rem; --rayon-grand: .5rem; --rayon-pilule: 999px;
    --largeur-contenu: 80rem; --largeur-mesure: 46rem; --largeur-barre: 16.25rem; --largeur-barre-reduite: 4rem; --hauteur-barre: 3.5rem;
    --duree: .12s;
    --espace-carte-v: var(--espace-4); --espace-carte-h: calc(var(--espace-4) + var(--espace-1) / 2); /* AJ-17 lot 2 : marge interne d'une carte, 16 × 18 px de la maquette (.ecran) en densité normale ; alias d'espacement : la densité compacte ou aérée les suit (L2-R) */
    --cible-tactile: 2.75rem; /* AV1 point 1 : cible tactile de 44 px (AJ-8), gardée. Maquette : 38 px (2.375rem). Un seul jeton à changer pour basculer. */
    --icone: none;
}

@media (prefers-color-scheme: dark) {
    :root {
        /* MARQUE */
        --marque: #4fc3a1;
        --accent: #4fc3a1;
        --accent-texte: #04201a;
        --accent-survol: #66d1b2;
        --accent-doux: #12302a;
        --focus: var(--marque);
        --selection: #1d4a3e;
        --logo: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.5 2.5 8.5l9.5 5 9.5-5-9.5-5Z'/%3E%3Cpath d='m2.5 12.5 9.5 5 9.5-5M2.5 16.5l9.5 5 9.5-5'/%3E%3C/svg%3E");
        --barre-haut: #050706;
        --barre-bas: #0b0f0d;
        --barre-texte: #eef2ef;
        --barre-lien: #eef2ef;
        --barre-doux: #a7b1ab;
        --barre-survol: #151a18;
        --barre-courant: #151a18;
        --barre-repere: #5ccaa6;
        --barre-point: #f0b44c;
        --barre-trait: #232b27;
        --barre-bord: #46514b;
        --fond: #0c0f0e;
        --carte: #151a18;
        --creux: #101412;
        --survol: #1c2320;
        --bord: #262e2b;
        --bord-fort: #3a4540;
        --bord-champ: #707c78; /* AV1 point 1 : gardé à 3:1. Maquette (--line-strong) : #3a4540. */
        --bord-bouton: var(--bord-fort);
        --texte: #e7ece9;
        --doux: #9ba69f;
        --info: var(--marque);
        --info-fond: #12302a;
        --info-bord: #25574a;
        --ombre-repos: 0 1px 2px #0000000f;
        --ombre-flottant: 0 8px 30px #00000080;
        --ombre-enfonce: inset 0 2px 4px rgb(0 0 0 / .55);
        /* AJ-17 lot 3 (L3-R) : les huit couleurs des barres du Gantt (maquette v17, --gxb0 à --gxb7 : fond de la barre ; --gxf0 à --gxf7 : encre du numéro sur ce fond). À la MARQUE : la teinte de la 1re et de la 7e est voisine de la sarcelle, que le SOCLE n'a pas le droit de porter. */
        --gxb0: #4fc3a1; --gxf0: #04201a; --gxb1: #e9b864; --gxf1: #2b1d00; --gxb2: #8db8f0; --gxf2: #0a1c33; --gxb3: #f0928b; --gxf3: #3b0f0c;
        --gxb4: #bfa5ea; --gxf4: #1d1033; --gxb5: #b4d66b; --gxf5: #1c2a05; --gxb6: #6dd0e0; --gxf6: #04242b; --gxb7: #e7a0c4; --gxf7: #35101f;
        --postit: #d9c25a; --postit-bord: #b39c3c; --postit-encre: #241e00;   /* AJ-25 : le papier du post-it (jetons de la maquette, --postit*) */


        /* SOCLE */
        /* Les états : constants d'un client à l'autre, chacun avec sa variante sombre. */
        --succes: #b4d66b;
        --succes-fond: #232d10;
        --succes-bord: #4a5e22;
        --attention: #e9b864;
        --attention-fond: #382a10;
        --attention-bord: #5c4a12;
        --alerte: #f0928b;
        --alerte-fond: #3b1c1a;
        --alerte-bord: #5c2626;
        /* Les échelles, non chromatiques, recopiées à l'identique dans les deux thèmes (A68). */
        --police: "Open Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
        --police-titre: "Noto Serif", "Droid Serif", Georgia, "Times New Roman", serif;
        --police-mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;
        --taille-legende: .75rem; --taille-petite: .8125rem; --taille-texte: .875rem; --taille-corps: .9375rem; --taille-titre-carte: 1rem; --taille-section: 1.125rem; --taille-chiffre: 1.75rem; --taille-ecran: 1.625rem;
        --interligne: 1.5; --interligne-titre: 1.25; --suivi-surtitre: .06em;
        --espace-1: .25rem; --espace-2: .5rem; --espace-3: .75rem; --espace-4: 1rem; --espace-5: 1.25rem; --espace-6: 1.5rem; --espace-8: 2rem;
        --rayon-controle: .375rem; --rayon-carte: .625rem; --rayon-grand: .5rem; --rayon-pilule: 999px;
        --largeur-contenu: 80rem; --largeur-mesure: 46rem; --largeur-barre: 16.25rem; --largeur-barre-reduite: 4rem; --hauteur-barre: 3.5rem;
        --duree: .12s;
        --espace-carte-v: var(--espace-4); --espace-carte-h: calc(var(--espace-4) + var(--espace-1) / 2);
        --cible-tactile: 2.75rem; /* AV1 point 1 : cible tactile de 44 px (AJ-8), gardée. Maquette : 38 px (2.375rem). Un seul jeton à changer pour basculer. */
        --icone: none;
    }
}

/*
 * Les 34 paires texte sur fond que la feuille PROMET, recalculées par ThemeTest dans les deux thèmes
 * (Socle\Design\Theme) : un ratio écrit à la main en commentaire ne prouve rien le jour où un jeton
 * change. 4,5 = texte courant (WCAG 1.4.3, AA) ; 3 = trait d'un élément d'interface (1.4.11).
 *
 * Le contenu :
 *   @contraste --texte sur --fond
 *   @contraste --texte sur --carte
 *   @contraste --doux sur --fond
 *   @contraste --doux sur --carte
 *   @contraste --texte sur --survol
 *   @contraste --doux sur --survol
 *   @contraste --texte sur --creux
 *   @contraste --doux sur --creux
 *   @contraste --texte sur --selection
 * La marque et l'action :
 *   @contraste --accent-texte sur --accent
 *   @contraste --accent-texte sur --accent-survol
 *   @contraste --marque sur --fond
 *   @contraste --marque sur --carte
 *   @contraste --marque sur --accent-doux
 *   @contraste --texte sur --accent-doux
 *   @contraste --marque sur --survol
 *   @contraste --accent sur --carte : 3
 *   @contraste --focus sur --fond : 3
 *   @contraste --focus sur --carte : 3
 * Les états, et leurs pastilles (même trio) :
 *   @contraste --succes sur --succes-fond
 *   @contraste --attention sur --attention-fond
 *   @contraste --alerte sur --alerte-fond
 *   @contraste --texte sur --info-fond
 *   @contraste --info sur --info-fond : 3
 *   @contraste --succes sur --carte
 *   @contraste --succes sur --fond
 *   @contraste --attention sur --carte
 *   @contraste --alerte sur --carte
 * Les traits d'interface :
 *   @contraste --bord-champ sur --carte : 3
 *   @contraste --bord-champ sur --fond : 3
 * La barre du haut et la barre basse du téléphone (le menu latéral n'en fait plus partie : il suit le thème, AJ-2 ; ses paires sont au bloc suivant) :
 *   @contraste --barre-texte sur --barre-haut
 *   @contraste --barre-texte sur --barre-bas
 *   @contraste --barre-lien sur --barre-bas
 *   @contraste --barre-lien sur --barre-survol
 *   @contraste --barre-doux sur --barre-bas
 *   @contraste --barre-doux sur --barre-haut
 *   @contraste --barre-texte sur --barre-courant
 *   @contraste --barre-repere sur --barre-courant : 3
 *   @contraste --barre-repere sur --barre-bas : 3
 *   @contraste --barre-repere sur --barre-haut : 3
 *   @contraste --barre-repere sur --barre-haut
 *   @contraste --barre-point sur --barre-haut : 3
 * Le menu latéral (texte, doux, marque et survol sont déjà déclarés plus haut ; il reste le repère de la page courante) :
 *   @contraste --accent sur --accent-doux : 4.5
 *   @contraste --succes sur --creux : 3
 *   @contraste --attention sur --creux : 3
 *   @contraste --alerte sur --creux : 3
 * Les couleurs des barres du Gantt (AJ-17 lot 3, L3-R) : chaque couleur tranche sur le cadre du dessin (--creux) et sur la carte à 3:1 ; l'encre du numéro est lisible sur sa barre :
 *   @contraste --gxb0 sur --creux : 3
 *   @contraste --gxb0 sur --carte : 3
 *   @contraste --gxf0 sur --gxb0
 *   @contraste --gxb1 sur --creux : 3
 *   @contraste --gxb1 sur --carte : 3
 *   @contraste --gxf1 sur --gxb1
 *   @contraste --gxb2 sur --creux : 3
 *   @contraste --gxb2 sur --carte : 3
 *   @contraste --gxf2 sur --gxb2
 *   @contraste --gxb3 sur --creux : 3
 *   @contraste --gxb3 sur --carte : 3
 *   @contraste --gxf3 sur --gxb3
 *   @contraste --gxb4 sur --creux : 3
 *   @contraste --gxb4 sur --carte : 3
 *   @contraste --gxf4 sur --gxb4
 *   @contraste --gxb5 sur --creux : 3
 *   @contraste --gxb5 sur --carte : 3
 *   @contraste --gxf5 sur --gxb5
 *   @contraste --gxb6 sur --creux : 3
 *   @contraste --gxb6 sur --carte : 3
 *   @contraste --gxf6 sur --gxb6
 *   @contraste --gxb7 sur --creux : 3
 *   @contraste --gxb7 sur --carte : 3
 *   @contraste --gxf7 sur --gxb7
 * Le papier du post-it (AJ-25) : l'encre est lisible sur le papier (le filet --postit-bord est décoratif, le papier se reconnaît à sa forme et à son texte). AJ-25-R : le lien et l'anneau de focus du formulaire de la note prennent aussi cette encre (4,5:1, au-delà des 3:1 de l'anneau) :
 *   @contraste --postit-encre sur --postit
 */


/* ═════════════════════════════════════════════════════════════════════════
   PARTIE B : LE SOCLE
   Rien ci-dessous ne porte une couleur en dur, sauf l'impression et le contraste forcé : tout passe
   par les jetons (Theme::frontiere le prouve à chaque test).
   ═════════════════════════════════════════════════════════════════════════ */

/* ─── B1. La base ──────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

body {
    margin: 0;
    font: var(--taille-corps)/var(--interligne) var(--police);
    background: var(--fond);
    color: var(--texte);
    /* Les chiffres du produit sont des montants et des heures : ils s'alignent toujours. */
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
}

::selection { background: var(--selection); color: var(--texte); }

/*
 * ⭐ UNE SEULE RÈGLE DE FOCUS, POUR TOUT CE QUI SE FOCALISE.
 * Le focus n'était déclaré que sur les champs : liens de menu, boutons et liens de tableau
 * retombaient sur l'anneau par défaut du navigateur, qui disparaît sur certains fonds.
 * Naviguer au clavier sans savoir où on est, ce n'est pas naviguer. L'anneau prend la couleur
 * de la marque (3:1 au moins, promis plus haut) ; dans la barre sombre, il passe au blanc.
 */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
    border-radius: .2rem;
}

/* Le lien d'évitement : hors écran jusqu'à ce qu'on le focalise au clavier. */
.evitement {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 50;   /* au-dessus de la barre du haut, collante (z-index 30) */
    padding: .6rem 1rem;
    background: var(--carte);
    border: 1px solid var(--bord-champ);
    border-radius: 0 0 var(--rayon-controle) 0;
    box-shadow: var(--ombre-flottant);
    color: var(--texte);
    text-decoration: none;
    font-weight: 600;
}
.evitement:focus-visible { left: 0; }

/* Visible d'un lecteur d'écran, invisible à l'œil. */
.pour-lecteur {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ─── B2. La structure ─────────────────────────────────────────────────── */

.cadre {
    display: grid;
    grid-template-columns: var(--largeur-barre) minmax(0, 1fr);
    min-height: 100vh;
}

/* Le contenu est centré dans sa colonne et plafonné : à 1440 px, plus de 168 px vides d'un seul côté. */
/*
 * AJ-17, lot 1 : la zone de contenu de la maquette (v17) : 1 280 px au plus, collée au menu (jamais centrée), marges de 28 / 36 / 72 px dès 900 px
 * et de 20 / 16 / 64 px en dessous. Écrites en rem et non en espace-N : la densité ne les déplace pas, comme la maquette (trame de 8 px écrite en dur).
 */
main {
    width: 100%;
    max-width: var(--largeur-contenu);
    margin: 0;
    padding: 1.25rem 1rem 4rem;
    min-width: 0;   /* sans quoi une grille refuse de laisser rétrécir son contenu */
}
@media (min-width: 56.25rem) {
    main { padding: 1.75rem 2.25rem 4.5rem; }
}

/*
 * Trois rangs de titres qui se voient : la page (24 px, 700), la section hors carte (18 px, 650), la carte
 * (16 px, 600). Le titre de page est écrit en rem, pas en jeton : un test d'hôte peut lire l'écart entre les rangs.
 */
h1, h2 {
    font-family: var(--police-titre);
    font-weight: 700;
}

h1 {
    margin: 0 0 .35rem;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: var(--interligne-titre);
    letter-spacing: -.015em;
    text-wrap: balance;
}

/* AJ-17, lot 1 : le titre d'écran de la coquille est celui de la maquette (v17, .cart h2) : 26 px, Noto Serif 700, -0,005 em, un filet dessous. */
body.coquille main > h1 {
    margin: 0 0 1.125rem;
    padding: 0 0 .875rem;
    font-size: var(--taille-ecran);
    letter-spacing: -.005em;
    border-bottom: 1px solid var(--bord);
}

/* Un h2 posé directement dans la page, hors carte (signalements, listes groupées) : un vrai titre de section. */
main > h2 {
    margin: var(--espace-8) 0 var(--espace-3);
    font-size: var(--taille-section);
    font-weight: 650;
    line-height: var(--interligne-titre);
    letter-spacing: -.01em;
}

.sous {
    margin: 0 0 1.75rem;
    color: var(--doux);
    font-size: var(--taille-petite);   /* AJ-17 lot 2 : .cart .meta de la maquette, 13 px */
    max-width: var(--largeur-mesure);
}
/* AJ-17 lot 2 : dans une carte, le texte discret est .sb de la maquette, 12 px. */
.carte .sous, .petite { font-size: var(--taille-legende); }

/* ─── B3. La barre latérale ────────────────────────────────────────────── */

/*
 * AJ-2 (D-b, 4 nov. 2026) : le menu SUIT LE THÈME. Clair en thème clair, sombre en thème sombre ; seule la barre du haut reste sombre dans les deux.
 * Il ne lit aucun jeton « barre-* » : il lit les jetons de surface (carte, texte, survol, accent-doux, marque), qui changent avec le thème de l'appareil
 * (réglage « auto », sans sélecteur de plus) ou avec le choix de la personne (theme-clair.css, theme-sombre.css), sans règle de plus. La page courante :
 * fond vert pâle (accent-doux), texte de marque, repère à gauche. Collante à l'écran large : le menu ne défile plus avec une longue page. Les paires de
 * contraste du menu (texte, doux et marque sur leurs fonds, dans les quatre feuilles) sont calculées par MenuThemeTest.
 * Un seul jeu de règles (UXG-36) : l'ancien `.menu-lateral` de la coquille et ce `nav.menu-lateral` décrivaient le même menu ; les sélecteurs de l'ancienne
 * barre qu'aucun gabarit n'émet (marque, profil, groupe, couche, trait, pied, bouton) sont retirés.
 */
nav.menu-lateral {
    flex: 0 0 var(--largeur-barre);
    position: sticky;
    top: calc(var(--hauteur-barre) + 1px);   /* sous la barre du haut, collante (AJ-17, lot 1) */
    align-self: start;
    z-index: 20;   /* AV1-R2-4 : au-dessus du contenu positionné (≤ 5), sous la barre du haut (30) : l'infobulle du menu réduit y est prise et ne passe plus sous la page */
    height: calc(100vh - var(--hauteur-barre) - 1px);
    overflow-y: auto;
    background: var(--carte);
    color: var(--texte);
    border-right: 1px solid var(--bord);
    padding: .75rem .75rem 1rem;
    display: flex;
    flex-direction: column;
}
.menu-lateral ul { margin: 0; padding: 0; list-style: none; }

nav.menu-lateral a {
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .5rem .75rem;
    border-radius: .4375rem;
    color: var(--texte);
    text-decoration: none;
    font-size: var(--taille-texte);
    font-weight: 400;
    border-left: 3px solid transparent;
    transition: background-color var(--duree), color var(--duree);
}
nav.menu-lateral a:hover { background: var(--creux); color: var(--texte); }

/* La page courante : un fond vert pâle, le texte de marque et le repère à gauche. */
nav.menu-lateral a[aria-current="page"] {
    background: var(--accent-doux);
    border-left-color: var(--accent);
    color: var(--marque);
    font-weight: 600;
}

/* La version affichée (« Pré-alpha v.017 »), discrète. Dans la barre du haut : voir `.barre-haut .version`. */
.version {
    display: block;
    margin-top: .6rem;
    font-size: var(--taille-legende);
    color: var(--doux);
    font-variant-numeric: tabular-nums;
}
/* AJ-27-R : sur une page d'erreur, la version suit la phrase (« … · erreur 404 · Pré-alpha v.017 ») : en ligne, sans marge. */
p.sous .version { display: inline; margin: 0; }

/*
 * La sous-navigation de la couche, dans la page, sous le titre. Ce n'est pas un élément <nav> (rôle
 * « navigation » sur un bloc) : toutes les règles « nav » ci-dessus visent la barre latérale, et la
 * colonneraient. Les onglets REVIENNENT À LA LIGNE, à toutes les largeurs : huit onglets ne doivent jamais
 * élargir la page, ni se cacher hors champ dans une bande qui défile. Un sélecteur segmenté qui épouse ses
 * onglets ; l'onglet choisi est une pastille blanche en relief. « page » porte la couleur de marque ; « true »
 * (un écran satellite) le fond seulement.
 */
.sous-navigation {
    margin: .75rem 0 1.5rem;
    min-width: 0;
}
.sous-navigation .onglets {
    display: flex;
    flex-wrap: wrap;
    gap: .2rem;
    width: fit-content;
    max-width: 100%;
    padding: var(--espace-1);
    background: var(--creux);
    border-radius: calc(var(--rayon-controle) + var(--espace-1));
}
.sous-navigation .onglets a {
    display: inline-block;
    padding: .4rem .8rem;
    border-radius: var(--rayon-controle);
    color: var(--doux);
    text-decoration: none;
    font-size: var(--taille-texte);
    font-weight: 500;
    overflow-wrap: anywhere;
    transition: background-color var(--duree), color var(--duree);
}
.sous-navigation .onglets a:hover { background: var(--carte); color: var(--texte); }
.sous-navigation .onglets a[aria-current] { background: var(--carte); color: var(--texte); font-weight: 600; }
.sous-navigation .onglets a[aria-current="page"] { color: var(--marque); box-shadow: var(--ombre-repos); }
.sous-navigation .selecteur {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .15rem .45rem;
    margin-top: .65rem;
    font-size: var(--taille-petite);
    color: var(--doux);
}
.sous-navigation .selecteur a { color: var(--marque); overflow-wrap: anywhere; }
.sous-navigation .selecteur a[aria-current="page"] { color: var(--texte); font-weight: 600; text-decoration: none; }

/* ─── B4. Le contenu ───────────────────────────────────────────────────── */

/*
 * La recette unique, répétée partout : fond blanc, bordure fine teintée, coins de 12 px, ombre de repos.
 * Fond contre carte tient à 1,08:1 : sans l'ombre, la page ne se lit qu'en aplats.
 */
.carte {
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: var(--rayon-carte);
    padding: var(--espace-carte-v) var(--espace-carte-h);   /* AJ-17 lot 2 : 16 × 18 px, comme .ecran de la maquette */
    margin-bottom: var(--espace-5);
    box-shadow: var(--ombre-repos);
    min-width: 0;
}

/*
 * AJ-17 lot 2 : LE TITRE DE CARTE est celui de la maquette (v17, .ecran h3) : police du corps, 14 px, 600, sans bandeau ni filet, 10 px dessous.
 * Il reste un h2 (ordre des titres). Retiré : la bande filetée d'un bord à l'autre et le Noto Serif de `h1, h2` (la maquette réserve le serif au titre d'écran).
 */
.carte h2 {
    margin: var(--espace-6) 0 .625rem;
    font-family: var(--police);
    font-size: var(--taille-texte);
    font-weight: 600;
    line-height: var(--interligne);   /* 21 px, comme le corps de la maquette */
    letter-spacing: 0;
    color: var(--texte);
    text-wrap: balance;
}
.carte > h2:first-child { margin: 0 0 .625rem; }
/*
 * L2-R : un h3 de carte est le sous-titre (h4 de la maquette v17 : 13 px, 500, 10 px dessus, 4 px dessous), jamais plus gros ni plus gras que le titre de la carte.
 * Un h3 en tête de carte (validation, analyse des étiquettes, paiements reçus) en est le titre : il prend le dessin du h2.
 */
.carte h3 {
    margin: .625rem 0 .25rem;
    font-size: var(--taille-petite);
    font-weight: 500;
}
.carte > h3:first-child {
    margin: 0 0 .625rem;
    font-size: var(--taille-texte);
    font-weight: 600;
    line-height: var(--interligne);
    letter-spacing: 0;
    color: var(--texte);
    font-family: var(--police);
    text-wrap: balance;
}

/*
 * AV1 notes (tableau de bord) : un lien sans classe prend la couleur de la marque, dans les deux thèmes
 * (le bleu par défaut du navigateur ne se lisait pas sur le fond sombre). Spécificité la plus basse :
 * tout composant qui fixe sa propre couleur (bouton, tuile, menu, barre) garde la sienne.
 * Contraste : la paire --marque sur --carte est déjà déclarée et calculée en tête de feuille (ThemeTest).
 */
a { color: var(--marque); }
a.lien { color: var(--marque); text-underline-offset: .15em; }
a.lien:hover { text-decoration-thickness: 2px; }

/*
 * ⭐ LES NOMBRES SONT LA CHARGE UTILE DE CE PRODUIT.
 * Un total d'heures, un montant, un taux de rattachement : ils pesaient exactement autant
 * qu'une étiquette de colonne. Une page où rien ne ressort est une page qu'on relit deux fois.
 */
.chiffre {
    font-family: var(--police-titre);   /* AJ-17 lot 2 : .mv de la maquette, Noto Serif 20 px 700, chiffres tabulaires */
    font-size: 1.25rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
}
/* Intouchés au lot 2 (lot 3) : ils gardent la police d'avant. À retirer avec le lot 3. */
.chiffre.grand, .tuile .chiffre { font-family: var(--police); }
.chiffre.grand { font-size: var(--taille-chiffre); font-weight: 700; line-height: 1.15; }
.chiffre.doux { color: var(--doux); font-weight: 500; }

/* L'aide sous un champ, et la légende sous un chiffre. */
.aide {
    display: block;
    font-size: var(--taille-legende);   /* AJ-17 lot 2 : .sb de la maquette, 12 px ; posé ici, la règle du texte discret de carte (plus haut) perdait contre celle-ci à spécificité égale */
    color: var(--doux);
    margin-top: .2rem;
}

/*
 * Les tuiles de chiffres : un nombre lisible en une seconde, sa légende dessous, un rail de 4 px à gauche qui dit
 * l'état. Elles se rangent seules (auto-fit), sans point de rupture. Une tuile « calme » s'éteint (le zéro ne crie
 * pas) ; une tuile lien se soulève au survol. Balisage : `.tuiles > .tuile` ou `a.tuile`.
 */
.tuiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
    gap: var(--espace-4);
    margin: 0 0 var(--espace-5);
}
.tuile {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    padding: var(--espace-4) 1.15rem;
    background: var(--carte);
    border: 1px solid var(--bord);
    border-left: 4px solid var(--accent);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-repos);
    color: inherit;
    text-decoration: none;
    min-width: 0;
}
.tuile .chiffre { font-size: var(--taille-chiffre); font-weight: 700; line-height: 1.15; }
.tuile .aide { margin: 0; }
.tuile.calme { border-left-color: var(--bord-fort); }
.tuile.calme .chiffre { color: var(--doux); }
.tuile.actif { border-left-color: var(--succes); }
.tuile.attention { border-left-color: var(--attention); }
.tuile.alerte { border-left-color: var(--alerte); }
a.tuile { transition: box-shadow var(--duree), border-color var(--duree); }
a.tuile:hover { box-shadow: var(--ombre-flottant); border-top-color: var(--bord-fort); border-right-color: var(--bord-fort); border-bottom-color: var(--bord-fort); }
/*
 * AJ-20b : l'accueil du module Administration range ses cartes en `ul.tuiles > li > a.tuile` : la liste perd ses puces, la tuile remplit son li (hauteurs égales par rangée), son titre
 * porte l'icône (décorative) et l'aide d'une phrase suit en texte doux (paire « doux sur carte », déjà déclarée). Une colonne étroite au téléphone ; cible d'au moins 44 px.
 */
ul.tuiles { list-style: none; padding: 0; }
.tuiles > li { display: flex; min-width: 0; }
.tuiles > li > a.tuile { flex: 1; min-height: var(--cible-tactile); }
a.tuile .tuile-titre { display: flex; align-items: center; gap: .5rem; font-weight: 600; color: var(--texte); }
a.tuile .tuile-titre .icone { flex: none; width: 1.125rem; height: 1.125rem; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
/* AJ-20b : « Fixé pour toute la firme », en lecture seule : un nom, sa valeur, en une colonne étroite au téléphone ; deux au bureau. Texte du nom en doux (paire « doux sur fond », déjà déclarée). */
dl.fixees { margin: 0 0 1.75rem; max-width: var(--largeur-mesure); }
dl.fixees > div { padding: .625rem 0; border-top: 1px solid var(--bord); }
dl.fixees dt { color: var(--doux); font-size: var(--taille-petite); }
dl.fixees dd { margin: .125rem 0 0; }
@media (min-width: 48rem) { dl.fixees > div { display: grid; grid-template-columns: 14rem 1fr; gap: 1rem; } dl.fixees dd { margin: 0; } }

/*
 * La rangée d'actions d'une page : une seule action pleine, le tout qui revient à la ligne. À poser APRÈS le
 * paragraphe `p.sous`, sans envelopper le h1 : une enveloppe autour du titre recevrait la sous-navigation si l'hôte
 * la pose après le premier </h1>.
 */
.entete-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-2); margin: 0 0 var(--espace-6); }

/* ─── B5. Les tableaux ─────────────────────────────────────────────────── */

table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--taille-petite);   /* AJ-17 lot 2 : .tb de la maquette, 13 px */
}

th, td {
    text-align: left;
    vertical-align: top;   /* L2-R : .tb td de la maquette ; l'en-tête collant garde son vertical-align: bottom (thead th) */
    padding: .375rem;   /* 6 px */
    border-bottom: 1px solid var(--bord);
}

/* AJ-17 lot 2 : l'en-tête de colonne est celui de la maquette (.tb th) : 12 px, 500, casse normale, doux, filet fort, 4 × 6 px. Les capitales sont retirées. */
th {
    padding: .25rem .375rem;
    font-size: var(--taille-legende);
    letter-spacing: 0;
    color: var(--doux);
    font-weight: 500;
    border-bottom-color: var(--bord-fort);
}
/* L'en-tête reste à l'écran sur une longue liste : il porte le fond de la carte, pour qu'on ne lise pas à travers. */
thead th {
    position: sticky;
    top: calc(var(--hauteur-barre) + 1px);   /* sous la barre du haut, collante (AV1-R2-1) ; dans un conteneur qui défile lui-même, voir plus bas */
    z-index: 1;
    vertical-align: bottom;
    background: var(--carte);
}

th[scope="row"] {
    padding: .375rem;
    font-size: var(--taille-petite);
    font-weight: 600;
    color: var(--texte);
    border-bottom-color: var(--bord);
}

td.nombre, th.nombre { text-align: right; font-variant-numeric: tabular-nums; }
/* AJ-17 lot 3 : `.num` et `.mono` de la maquette. Montants, heures, taux et nombres (td.nombre) et identifiants ou dates (.mono) : IBM Plex Mono 12 px, chiffres tabulaires. L'en-tête d'une colonne de nombres garde la police du corps (.tb th.num). */
td.nombre, td.mono, th[scope="row"].mono, .mono { font-family: var(--police-mono); font-size: var(--taille-legende); font-variant-numeric: tabular-nums; }
.mono { white-space: nowrap; }
/* Un nombre ne se coupe jamais : « 35 / h » sur deux lignes ne se lit plus. */
td.nombre, .chiffre { white-space: nowrap; }
tr:last-child td { border-bottom: 0; }
/* La ligne de total : un filet de champ au-dessus, le chiffre appuyé. */
tfoot td, tfoot th { border-top: 1px solid var(--bord-champ); font-weight: 650; }
tfoot th { padding: .375rem; font-size: var(--taille-petite); color: var(--texte); }

/* Le tableau d'une carte va d'un bord à l'autre : sa première colonne s'aligne sur le titre de la carte. */
.carte > table { width: calc(100% + 2 * var(--espace-carte-h)); margin: 0 calc(-1 * var(--espace-carte-h)); }
.carte > table > * > tr > :first-child { padding-left: var(--espace-carte-h); }
.carte > table > * > tr > :last-child { padding-right: var(--espace-carte-h); }

/* La ligne survolée se teinte : l'œil suit la ligne jusqu'au montant. */
table > tbody > tr:hover > * { background: var(--survol); }

caption {
    text-align: left;
    font-size: var(--taille-legende);
    color: var(--doux);
    padding-bottom: .5rem;
}

/*
 * Un état vide qui ne dit pas quoi faire est un défaut, pas un détail.
 * Dire POURQUOI c'est vide. Reconnu par sa PLACE :
 * seul dans sa carte, ou seul sous son titre, le vide devient une zone en pointillés, l'icône au-dessus
 * de la phrase centrée. Ailleurs (une liste compacte, une colonne), il reste une ligne, l'icône devant.
 */
.vide {
    margin: var(--espace-1) 0;
    padding: var(--espace-2) 0;
    color: var(--doux);
    font-size: var(--taille-texte);
}
.carte > h2:first-child + .vide:last-child,
.carte > .vide:only-child {
    margin: 0;
    padding: 1.75rem 1rem;
    border: 1px dashed var(--bord-fort);
    border-radius: var(--rayon-controle);
    text-align: center;
}

/* ─── B6. Les formulaires ──────────────────────────────────────────────── */

/*
 * ⚠ DÉQUALIFIÉE. La règle s'écrivait `form.ligne`, donc six `<div class="ligne">`, dans
 * trois écrans de l'hôte, ne recevaient AUCUNE mise en page : les champs
 * s'empilaient verticalement au lieu de se ranger en ligne. Une classe qui ne s'applique que
 * sur un élément précis est un piège : celui qui la réutilise ailleurs ne voit rien se passer
 * et cherche l'erreur dans son balisage.
 */
.ligne {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem 1rem;
    align-items: flex-end;
}
.ligne > div {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    min-width: 0;
}

label {
    font-size: var(--taille-petite);
    font-weight: 600;
    color: var(--doux);
}

input, select, textarea {
    padding: var(--remplissage-champ, .5rem) .375rem;   /* AJ-17 lot 2 : 13 px et 6 px de côté, comme la maquette */
    font: inherit;
    font-size: var(--taille-petite);
    color: inherit;
    background: var(--carte);
    border: 1px solid var(--bord-champ);   /* 3:1 au moins, promis plus haut ; l'ancien --bord était à 1,29:1 */
    border-radius: var(--rayon-controle);
    max-width: 100%;
    transition: border-color var(--duree);
}
/* AJ-8 : la hauteur des contrôles vient du jeton de la densité « bureau » ; sans lui, `auto` (la valeur initiale) : rien ne change. */
input:not([type="checkbox"]):not([type="radio"]), select, button.action, a.action { min-height: var(--hauteur-controle, auto); }
input:hover, select:hover, textarea:hover { border-color: var(--doux); }
input:focus-visible, select:focus-visible, textarea:focus-visible { border-color: var(--focus); }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }
/* Dans une colonne de `.ligne`, une case garde sa taille au lieu de s'étirer ; son libellé est une phrase, en romain. */
.ligne > div > input[type="checkbox"],
.ligne > div > input[type="radio"] { align-self: flex-start; }
input[type="checkbox"] + label,
input[type="radio"] + label { font-weight: 400; }

input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
    border-color: var(--alerte);
    border-width: 2px;
}
/* 26 messages d'erreur sous un champ n'avaient aucune règle : un texte noir sous un champ marqué invalide. */
span.erreur {
    display: block;
    margin-top: .2rem;
    font-size: var(--taille-petite);
    font-weight: 600;
    color: var(--alerte);
}

/*
 * Le champ de montant. Le symbole est DANS le champ, pas dans l'étiquette.
 * L'écran disait « Montant ferme ($) » au-dessus d'un champ qui attendait des cents :
 * taper 12000 en pensant 12 000 $ écrivait 120,00 $ sur un document contractuel.
 * L'unité doit être là où l'œil se pose au moment de taper.
 */
.champ-montant {
    display: flex;
    align-items: stretch;
    border: 1px solid var(--bord-champ);
    border-radius: var(--rayon-controle);
    background: var(--carte);
    max-width: 12rem;
}
.champ-montant:focus-within { outline: 2px solid var(--focus); outline-offset: 2px; border-color: var(--focus); }
.champ-montant > span {
    display: flex;
    align-items: center;
    padding: 0 .55rem;
    color: var(--doux);
    font-size: var(--taille-texte);
    border-right: 1px solid var(--bord);
    background: var(--survol);
    border-radius: calc(var(--rayon-controle) - 1px) 0 0 calc(var(--rayon-controle) - 1px);
}
.champ-montant > input {
    border: 0;
    background: transparent;
    border-radius: 0 calc(var(--rayon-controle) - 1px) calc(var(--rayon-controle) - 1px) 0;
    width: 100%;
    text-align: right;
}
.champ-montant > input:focus-visible { outline: none; }

/*
 * Le bouton principal : fond de marque, texte blanc (7,5:1 en clair). `a.action` n'avait aucune règle :
 * six liens « action » s'affichaient en liens ; ils prennent enfin le dessin du bouton. Un enfoncement
 * (`:active`) par une ombre intérieure, sans mouvement.
 */
button.action,
a.action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    padding: var(--remplissage-bouton, .55rem) .75rem;   /* AJ-17 lot 2 : 13 px, 500, 12 px de côté, comme `button` de la maquette ; la hauteur reste à la densité (AJ-8) */
    font: inherit;
    font-size: var(--taille-petite);
    font-weight: 500;
    line-height: var(--interligne);   /* AJ-17 lot 2 : `font: inherit` de la maquette, 19,5 px à 13 px */
    cursor: pointer;
    border: 1px solid var(--accent);
    border-radius: var(--rayon-controle);
    background: var(--accent);
    color: var(--accent-texte);
    text-decoration: none;
    transition: background-color var(--duree), border-color var(--duree), color var(--duree);
}
button.action:hover,
a.action:hover { background: var(--accent-survol); border-color: var(--accent-survol); }
button.action:active,
a.action:active { box-shadow: var(--ombre-enfonce); }

/*
 * ⭐ DEUX NIVEAUX DE NATURE, PLUS UN DISCRET.
 * « Enregistrer le brouillon » (réversible) et « Figer et envoyer » (irréversible, visible
 * du destinataire, non annulable) ne doivent pas porter exactement le même bouton. La différence doit se lire
 * comme une différence de NATURE, pas d'urgence : donc un contour plein plutôt qu'une
 * couleur d'alarme. On ne crie pas, on distingue. Le contour est celui de la marque ; au survol,
 * il se teinte sans se remplir : il ne devient jamais le bouton principal.
 */
button.action.engage,
a.action.engage {
    background: var(--carte);
    color: var(--marque);
    border: 1px solid var(--accent);
}
button.action.engage:hover,
a.action.engage:hover { background: var(--accent-doux); color: var(--marque); border-color: var(--accent); }

/*
 * AJ-17 lot 2 : le bouton SECONDAIRE de la maquette (`button` sans .prim) : fond de carte, filet --bord-bouton (la valeur de la maquette, H5), encre du texte,
 * survol --creux. La hauteur reste à la densité. `.engage` le précède dans le fichier : un bouton qui porte les deux classes garde le contour de la marque.
 */
button.action.discrete,
a.action.discrete {
    background: var(--carte);
    border: 1px solid var(--bord-bouton);
    color: var(--texte);
}
button.action.discrete:hover,
a.action.discrete:hover { background: var(--creux); border-color: var(--bord-bouton); }
button.action.engage.discrete,
a.action.engage.discrete { border-color: var(--accent); color: var(--marque); }
button.action.engage.discrete:hover,
a.action.engage.discrete:hover { background: var(--accent-doux); border-color: var(--accent); }

button.action[disabled],
button.action[aria-disabled="true"] {
    opacity: .45;
    cursor: not-allowed;
}

/*
 * Une action qui ne se corrige pas (clôturer un dossier, verrouiller une prise) ne se met
 * pas dans une phrase grise à côté de trois liens de navigation. Elle vit dans son propre
 * bloc, avec sa conséquence écrite juste à côté d'elle. Et surtout : PAS DE ROUGE. Le rouge
 * dit « attention, danger » ; ici il s'agit d'une décision normale et assumée, qu'il faut
 * simplement prendre en sachant qu'on ne reviendra pas dessus.
 */
.irreversible {
    border-top: 1px solid var(--bord);
    margin-top: 1.5rem;
    padding-top: 1.1rem;
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    align-items: center;
}
.irreversible .aide { margin: 0; max-width: 32rem; }

/*
 * Le troisième niveau : sans bord, à la couleur de la marque, teinté au survol. Il vit dans les rangées de tableau
 * (« corriger », « retirer ») : dix boutons bordés par écran faisaient plus de bruit que les données. « corriger » dans
 * une ligne de temps est un résumé, pas un bouton : même dessin. Le bord transparent garde la taille et l'anneau de focus.
 */
button.discret,
summary.discret {
    display: inline-flex;
    align-items: center;
    padding: .25rem .5rem;
    font: inherit;
    font-size: var(--taille-petite);
    font-weight: 500;
    line-height: 1.25;
    cursor: pointer;
    border: 1px solid transparent;
    border-radius: var(--rayon-controle);
    background: transparent;
    color: var(--marque);
    list-style: none;
    transition: background-color var(--duree);
}
button.discret:hover,
summary.discret:hover { background: var(--accent-doux); }
summary.discret::-webkit-details-marker { display: none; }
summary.discret::marker { content: ""; }

/*
 * Le repli : un formulaire de nouvelle entrée, replié jusqu'au besoin (`<details class="repli">`).
 * Replié, il ne prend qu'une ligne, « + Nouvelle entrée », dessinée comme un bouton discret : le <summary> natif,
 * atteignable au clavier (la règle de focus unique, plus haut, le vise déjà), annoncé « réduit » ou « développé » par les
 * lecteurs d'écran. Le « + » est un dessin tu (aria-hidden) ; il pivote en « × » quand le repli est ouvert. Le marqueur
 * natif (le triangle) disparaît : un seul signe. Le libellé revient à la ligne plutôt que d'élargir la page (375 px) ;
 * aucune couleur nouvelle : les jetons existants, le mode sombre suit de lui-même.
 * « position: relative » (vu au navigateur, 375 px) : le résumé est le bloc contenant de ce que seul un lecteur d'écran
 * entend (.pour-lecteur, en position absolue : « dans À faire ») ; sans lui, dans les colonnes du tableau qui défilent, ces
 * textes s'en échappaient et élargissaient toute la page (906 px pour 375).
 * La règle du résumé reste mot pour mot (le test de formulaires de l'hôte l'ancre) ; le rayon et l'ombre du socle
 * viennent de la seconde règle, juste dessous.
 */
.repli { margin: 0 0 1.35rem; min-width: 0; }
.repli > summary {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    max-width: 100%;
    padding: .5rem .95rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--texte);
    background: var(--carte);
    border: 1px solid var(--bord-champ);
    border-radius: .35rem;
    cursor: pointer;
    list-style: none;
    overflow-wrap: anywhere;
}
.repli > summary::-webkit-details-marker { display: none; }
.repli > summary::marker { content: ""; }
details.repli > summary { border-radius: var(--rayon-controle); box-shadow: var(--ombre-repos); transition: background-color var(--duree); }
.repli > summary:hover { background: var(--survol); }
.repli-signe { display: inline-block; font-weight: 700; line-height: 1; color: var(--marque); transition: transform .15s ease; }
.repli[open] > summary { margin-bottom: .75rem; }
.repli[open] > summary .repli-signe { transform: rotate(45deg); }
.repli > .carte:last-child { margin-bottom: 0; }
/* Dans une colonne du tableau, sous une liste d'une carte : la même ligne, plus petite. */
.repli.repli-compact { margin: .6rem 0 0; }
.repli.repli-compact > summary { padding: .3rem .65rem; font-size: .8125rem; }
@media (prefers-reduced-motion: reduce) {
    .repli-signe { transition: none; }
}
@media (hover: none) and (pointer: coarse) {
    .repli > summary { min-height: var(--cible-tactile); }
}
/* Les formulaires ne s'impriment pas (section 11) ; leur repli non plus, ouvert ou fermé : rien d'autre ne change. */
@media print {
    .repli { display: none !important; }
}

/* ─── B7. Les états : avis et étiquettes ───────────────────────────────── */

/*
 * L'avis (bandeau) : la triade fond, bord, texte de son état, une icône devant, un titre
 * en gras avant la phrase. Sans état, c'est une information : la voix de la marque.
 */
.avis {
    position: relative;
    padding: .8rem 1rem .8rem 2.75rem;
    border-radius: var(--rayon-controle);
    font-size: var(--taille-texte);
    line-height: 1.5;
    border: 1px solid var(--info-bord);
    background: var(--info-fond);
    color: var(--texte);
    margin-bottom: var(--espace-5);
}
.avis strong { font-weight: 650; }

.avis.succes    { border-color: var(--succes-bord);    background: var(--succes-fond);    color: var(--succes); }
.avis.attention { border-color: var(--attention-bord); background: var(--attention-fond); color: var(--attention); }
.avis.erreur    { border-color: var(--alerte-bord);    background: var(--alerte-fond);    color: var(--alerte); }

.avis a { color: inherit; }

/*
 * L'étiquette est l'indicateur d'état universel du produit : une pastille, fond pâle et
 * texte foncé de la même famille, 12 px au moins (le plancher), un point devant quand elle porte un état.
 *
 * ⚠ AUCUN ÉTAT N'EST SIGNALÉ PAR LA COULEUR SEULE. Le mot reste dans l'étiquette : « en
 * retard », « envoyée », « brouillon ». La couleur confirme, elle n'informe jamais toute
 * seule : environ 8 % des hommes ne la distinguent pas. Le point est une forme, pas un code.
 */
.etiquette {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .125rem .5rem;   /* AJ-17 lot 2 : .pl de la maquette, 2 × 8 px, 500 ; 12 px (plancher, H4 : la maquette a 11) */
    border-radius: var(--rayon-pilule);
    font-size: var(--taille-legende);
    font-weight: 500;
    line-height: 1.5;
    letter-spacing: 0;
    border: 1px solid transparent;   /* transparent : il reste visible en contraste forcé */
    color: var(--doux);
    background: var(--creux);
    white-space: nowrap;
    vertical-align: middle;
}
.etiquette.calme     { border-color: var(--bord); background: var(--creux); color: var(--doux); }
.etiquette.actif     { background: var(--succes-fond);    color: var(--succes); }
.etiquette.attention { background: var(--attention-fond); color: var(--attention); }
.etiquette.alerte    { background: var(--alerte-fond);    color: var(--alerte); }
/* AJ-17 lot 3 : « acc » de la maquette (envoyée, relancée, soumise) : fond d'accent doux, texte d'accent. 4,5:1 promis aux deux thèmes (@contraste --accent sur --accent-doux). */
.etiquette.accent    { background: var(--accent-doux);    color: var(--accent); }
/* Dans une colonne de `.ligne` (tableau de bord, sauvegarde), la pastille garde sa largeur au lieu de s'étirer. */
.ligne > div > .etiquette { align-self: flex-start; }
.etiquette.actif::before,
.etiquette.attention::before,
.etiquette.alerte::before {
    content: "";
    flex: none;
    width: .45rem;
    height: .45rem;
    border-radius: 50%;
    background: currentColor;
}

/* Un écart favorable et un écart défavorable, distingués autrement que par la couleur. */
.ecart::before { font-weight: 700; margin-right: .2rem; }
.ecart.favorable   { color: var(--succes); }
.ecart.favorable::before   { content: "▲"; }
.ecart.defavorable { color: var(--alerte); }
.ecart.defavorable::before { content: "▼"; }

/* ─── B8. Les icônes ───────────────────────────────────────────────────── */

/*
 * Icône plus mot, sans police tierce ni sprite : des dessins SVG en `data:`,
 * appliqués en masque sur un pseudo-élément dont le fond est `currentColor`. L'icône prend donc la
 * couleur du texte, dans les deux thèmes et sur le champ sombre. Chaque élément choisit son dessin par
 * --icone ; le pseudo-élément ne porte jamais de texte : rien n'est lu à voix haute. Le lien de couche
 * garde son texte seul : l'icône n'est pas un enfant, c'est un ::before.
 */
.page-seule h1::before,
.avis::before,
.vide::before {
    content: "";
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
    background-color: currentColor;
    -webkit-mask: var(--icone) center / contain no-repeat;
    mask: var(--icone) center / contain no-repeat;
}

/* La marque : le jeton --logo de la section MARQUE ; un autre client y pose son dessin. */
.page-seule h1 { --icone: var(--logo); }

/* Les quatre avis : information, succès, attention, erreur. L'icône est dans l'avis, à gauche du texte. */
.avis { --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 11v5.5M12 7.5h.01'/%3E%3C/svg%3E"); }
.avis.succes { --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m8 12.3 2.8 2.8 5.4-5.5'/%3E%3C/svg%3E"); }
.avis.attention { --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.3 4.2 2.6 17.5a2 2 0 0 0 1.7 3h15.4a2 2 0 0 0 1.7-3L13.7 4.2a2 2 0 0 0-3.4 0Z'/%3E%3Cpath d='M12 9.5v4M12 17h.01'/%3E%3C/svg%3E"); }
.avis.erreur { --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m15 9-6 6M9 9l6 6'/%3E%3C/svg%3E"); }
.avis::before { position: absolute; left: .95rem; top: .85rem; color: var(--info); }
.avis.succes::before,
.avis.attention::before,
.avis.erreur::before { color: inherit; }

/* L'état vide : un plateau, discret, devant la phrase ; au-dessus d'elle quand le vide est seul dans sa carte. */
.vide { --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 13.5 5.4 5.6a2 2 0 0 1 1.9-1.4h9.4a2 2 0 0 1 1.9 1.4L21 13.5V18a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4.5Z'/%3E%3Cpath d='M3 13.5h5.2l1.3 2.5h5l1.3-2.5H21'/%3E%3C/svg%3E"); }
.vide::before { display: inline-block; width: 1.1em; height: 1.1em; margin: 0 .45rem 0 0; vertical-align: -.2em; background-color: var(--bord-champ); }
.carte > h2:first-child + .vide:last-child::before,
.carte > .vide:only-child::before { display: block; width: 1.75rem; height: 1.75rem; margin: 0 auto .5rem; }

/* La connexion : le dessin de la marque au-dessus du nom. */
.page-seule h1::before { display: block; width: 2.25rem; height: 2.25rem; margin: 0 0 .9rem; background-color: var(--marque); }

/* Contraste forcé (Windows) : le fond d'un pseudo-élément serait remplacé, l'icône disparaîtrait. */
@media (forced-colors: active) {
    .page-seule h1::before,
    .avis::before,
    .vide::before { forced-color-adjust: none; background-color: CanvasText; }
}

/* ─── B10. Le téléphone ────────────────────────────────────────────────── */

@media (max-width: 48rem) {
    /* Le menu latéral est caché sous 48 rem (voir plus bas) ; la navigation du téléphone est la barre basse. */
    .cadre {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto 1fr;   /* sinon la nav se partage la hauteur à parts égales */
    }

    main { padding: 1.25rem 1rem 4rem; }

    /*
     * Un tableau plus large que l'écran faisait défiler la PAGE entière, nav comprise.
     * Le défilement redevient contenu dans la carte. (AJ-17 lot 2 : plus de bande de titre.)
     */
    .carte { overflow-x: auto; padding: var(--espace-carte-v) var(--espace-carte-h); }
    /* L'encadré de l'en-tête du dossier ne défile pas : sa liste ⋮ flottante (position absolue) y serait rognée. Rien dedans n'a besoin du défilement (titre et repères se replient). */
    .carte.entete-dossier { overflow: visible; }
    .carte > table { width: calc(100% + 2 * var(--espace-carte-h)); margin: 0 calc(-1 * var(--espace-carte-h)); }
    .carte > table > * > tr > :first-child { padding-left: var(--espace-carte-h); }
    .carte > table > * > tr > :last-child { padding-right: var(--espace-carte-h); }

    /*
     * Un tableau à beaucoup de colonnes (le journal du dossier : six) cachait ses dernières colonnes derrière le défilement de la carte.
     * Sous 48 rem, chaque ligne s'empile : la cellule dit sa colonne (data-label). L'en-tête reste lisible par les lecteurs d'écran.
     */
    .carte > table.empilable { width: 100%; margin: 0; }
    table.empilable > thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
    table.empilable > tbody > tr { display: block; padding: .625rem 0; border-bottom: 1px solid var(--bord); }
    .carte > table.empilable > tbody > tr > td { display: flex; gap: .75rem; padding: .125rem 0; border: 0; }
    table.empilable > tbody > tr > td::before { content: attr(data-label); flex: 0 0 4.5rem; color: var(--doux); font-family: var(--police); font-size: var(--taille-legende); }

    /* Les min-width posés en style en ligne débordent la largeur d'un téléphone. */
    form.ligne > div, .ligne > div { min-width: 0 !important; width: 100%; }
    .champ-montant { max-width: 100%; }
}

/*
 * ⭐ LE ZOOM AUTOMATIQUE D'iOS.
 * Un champ sous 16 px déclenche un zoom à la mise au point, et iOS ne dézoome pas ensuite.
 * Un visiteur le rencontre à la seconde exacte où il choisit son mot de passe.
 * La requête porte sur le POINTEUR, pas sur la largeur : un ordinateur en fenêtre étroite
 * garde ses champs à leur taille.
 */
@media (hover: none) and (pointer: coarse) {
    input, select, textarea { font-size: 16px; }
    nav a, button { min-height: var(--cible-tactile); display: flex; align-items: center; }
    /* AJ-18 : une case à cocher et son étiquette (fiche d'une personne, réglages) tiennent la cible tactile. */
    label.case { min-height: var(--cible-tactile); }
    nav a { display: inline-flex; }
    /* Un onglet est une cible tactile comme un lien de la barre. */
    .sous-navigation .onglets a { min-height: var(--cible-tactile); display: inline-flex; align-items: center; }
    /* Le résumé « corriger » est une cible, comme le bouton « retirer ». */
    summary.discret { min-height: var(--cible-tactile); }
}

/* Le mouvement réduit coupe toutes les transitions de la feuille, pas seulement celle du repli. */
@media (prefers-reduced-motion: reduce) {
    nav.menu-lateral a, .sous-navigation .onglets a,
    a.tuile, input, select, textarea, button.action, a.action, button.discret, summary.discret, details.repli > summary, .repli-signe { transition: none; }
}
@media (prefers-reduced-motion: reduce) {
    .boite:modal { animation: none; }
}

/* ─── B11. L'impression ────────────────────────────────────────────────── */

@media print {
    nav, .sous-navigation, .action, form, .avis, .evitement { display: none !important; }
    body { background: #fff; color: #000; }
    main { padding: 0; max-width: none; }
    .cadre { display: block; }
    .carte { border: 0; padding: 0; background: transparent; overflow: visible; box-shadow: none; }
    .carte > h2:first-child { margin: 0 0 .75rem; }
    .tuile { box-shadow: none; }
    .carte > table { width: 100%; margin: 0; }
    thead th { position: static; }
    /* La couleur disparaît à l'impression : l'étiquette garde un contour. */
    .etiquette { border-color: #000; color: #000; background: transparent; }
    a { color: #000; }
}

/* ─── B12. Les pages autonomes (connexion, invitation) ─────────────────── */

/*
 * Connexion et invitation vivent hors du gabarit : elles n'ont pas de menu, et la seconde est
 * vue par quelqu'un qui n'a pas encore de compte. Deux pages jumelles partagent la même feuille,
 * sinon l'une vieillit sans que personne ne la regarde.
 * Le champ de marque sombre en plein écran, une carte blanche flottante, le dessin de la marque au-dessus du nom.
 */
body.page-seule {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 1.25rem;
    background: linear-gradient(135deg, var(--barre-haut) 0%, var(--barre-bas) 100%);
}

.page-seule .carte {
    width: min(100%, 26rem);
    padding: 2.25rem 2rem 2rem;
    margin: 0;
    border-radius: var(--rayon-grand);
    border-color: transparent;
    box-shadow: var(--ombre-flottant);
}

/*
 * AJ-17 lot 4 : la page seule prend les composants de la maquette (v17), les mêmes que les écrans de la coquille : le titre d'écran (Noto Serif 700, 26 px), le champ (13 px, 6 px de côté,
 * filet --bord-champ), le bouton principal et le secondaire (13 px, 500), le texte discret (12 px dans la carte). Il ne lui reste en propre que la MISE EN PAGE : pleine largeur et marges.
 * Le banc navigateur (étape `seules`) compare chaque composant à celui de « / », au même thème et à la même largeur ; PagesSeulesTest lit cette règle.
 */
.page-seule h1 { font-size: var(--taille-ecran); letter-spacing: -.005em; margin: 0 0 .3rem; }
.page-seule .sous { margin: 0 0 1.5rem; }

.page-seule label { display: block; margin-bottom: .35rem; }
.page-seule input[type=email],
.page-seule input[type=password],
.page-seule input[type=text] {
    width: 100%;
    margin-bottom: .75rem;
}
.page-seule .aide { margin: 0 0 1rem; }
.page-seule .memoire {
    display: flex; align-items: center; gap: .5rem;
    margin: .5rem 0 1.25rem; font-size: var(--taille-texte);
}
.page-seule .memoire input { margin: 0; width: auto; }
.page-seule .memoire label { margin: 0; font-weight: 400; font-size: var(--taille-texte); color: var(--texte); }
.page-seule button.action { width: 100%; }
/*
 * L4-R : la cible tactile de 44 px (AJ-8) tient aussi sur les pages seules. `button.action` et les champs lisent `--hauteur-controle`, posé par la seule densité « bureau » (valeur initiale : auto) ;
 * quand le lot a retiré la marge interne redite par `.page-seule`, rien ne tenait plus la hauteur au pointeur grossier (champ de 42 px, bouton de 39 px). Spécificité (0,2,1), après les règles générales.
 */
@media (hover: none) and (pointer: coarse) {
    .page-seule :is(input[type=email], input[type=password], input[type=text], button.action, a.action) { min-height: var(--cible-tactile); }
}

/* ═════════════════════════════════════════════════════════════════════════
   PARTIE C : LES PAGES DU TRAIN PA-0 (connexion, second facteur, Mon compte, accueil)
   Portées de la feuille de la plateforme (commit 2b80567), réécrites sur les jetons. Aucun style en ligne dans les vues : la
   politique de contenu refuse `style=` (style-src 'self').
   ═════════════════════════════════════════════════════════════════════════ */

/* Le ruban « Pré-alpha · données fictives » : visible sur chaque page, jamais caché (cahier §5). */
.ruban {
    display: block;
    padding: var(--espace-1) var(--espace-4);
    background: var(--attention-fond);
    color: var(--attention);
    border-bottom: 1px solid var(--attention-bord);
    font-size: var(--taille-petite);
    text-align: center;
}

.page-seule .ruban { position: fixed; top: 0; left: 0; right: 0; }

.page-seule .etapes-inscription { margin: 0 0 1.25rem; padding-left: 1.25rem; font-size: var(--taille-petite); }
.page-seule .etapes-inscription li { margin-bottom: .6rem; }
.page-seule .cle-secrete { display: block; margin-top: .35rem; font-size: 1rem; letter-spacing: .04em; word-spacing: .3em; overflow-wrap: anywhere; }
.page-seule .codes-secours { list-style: none; margin: 0 0 1.5rem; padding: 0; display: grid; gap: .35rem; }
.page-seule .codes-secours code { font-size: 1rem; letter-spacing: .04em; white-space: nowrap; }
.page-seule .pied-de-carte { text-align: center; margin: 1.1rem 0 0; }
.page-seule .pied-de-carte.version { margin-top: 1.2rem; }
.page-seule .action.pleine { display: block; text-align: center; }
.page-seule .petite { margin-top: .5rem; }
.page-seule h2 { font-size: var(--taille-section); margin: 1.5rem 0 .5rem; }
.page-seule .sessions { list-style: none; margin: 0 0 .8rem; padding: 0; display: grid; gap: .5rem; font-size: var(--taille-petite); }
.page-seule .sessions li { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; justify-content: space-between; }
.page-seule .sessions form { margin: 0; }
.page-seule .sessions button.action { width: auto; }
.page-seule .lien-centre { text-align: center; margin: .8rem 0 0; }

/* L'accueil minimal (la coquille de navigation complète est au train PA-1). */
.accueil { max-width: var(--largeur-mesure); margin: 0 auto; padding: var(--espace-6) var(--espace-4); }
.accueil h1 { font-size: var(--taille-section); margin: 0 0 var(--espace-2); }
.accueil .carte { padding: var(--espace-6); }


/* =============================================================================
   PA-1 : la coquille de navigation, les préférences (thème, densité, menu réduit), l'administration.
   Aucune couleur en dur : seulement des jetons. Le thème explicite de la personne vient de theme-clair.css ou theme-sombre.css (mêmes jetons, chargés après
   cette feuille) ; « auto » suit l'appareil.
   La densité ne réécrit aucune classe : elle redéfinit les variables d'espacement (data-densite).
   ========================================================================== */

:root[data-densite="compacte"] { --espace-1: .2rem; --espace-2: .375rem; --espace-3: .5rem; --espace-4: .75rem; --espace-5: .9rem; --espace-6: 1.1rem; --espace-8: 1.5rem; }
:root[data-densite="aeree"] { --espace-1: .3rem; --espace-2: .65rem; --espace-3: .95rem; --espace-4: 1.25rem; --espace-5: 1.6rem; --espace-6: 1.9rem; --espace-8: 2.5rem; }
/*
 * AJ-8 (D-c, 4 nov. 2026) : la densité « bureau », une préférence de COMPTE (Mon compte > Préférences) ; le défaut reste « normale ». Corps de 14 px et contrôles
 * (champs, listes, boutons d'action) de 32 px de haut. Des variables seulement, comme les deux autres : sans cette densité, ni --hauteur-controle ni les
 * remplissages ne sont posés, et les règles des contrôles retombent sur la taille d'aujourd'hui. Une cible tactile garde 44 px : la préférence suit la
 * personne sur le téléphone, la cible ne rapetisse pas.
 */
:root[data-densite="bureau"] { --taille-corps: .875rem; --hauteur-controle: 2rem; --remplissage-champ: .25rem; --remplissage-bouton: .3rem; }
@media (hover: none) and (pointer: coarse) {
    :root[data-densite="bureau"] { --hauteur-controle: var(--cible-tactile); }
}

body.coquille { display: flex; flex-direction: column; min-height: 100vh; }
.evitement { position: absolute; left: -100vw; }
.evitement:focus { left: var(--espace-2); top: var(--espace-2); z-index: 50; padding: var(--espace-2) var(--espace-3); background: var(--carte); color: var(--texte); border-radius: var(--rayon-controle); }

/*
 * AJ-17, lot 1 : la barre du haut de la maquette (v17) : collante, 56 px et un filet, marque en Noto Serif 17 px, champ de recherche de 34 px (fond et filet de la barre).
 * AJ-21 : la cloche est à gauche, juste après la marque. Une seule rangée, à toutes les largeurs : la marque rétrécit au téléphone.
 */
.barre-haut {
    position: sticky; top: 0; z-index: 30;
    display: flex; align-items: center; gap: .75rem;
    min-width: 0; min-height: calc(var(--hauteur-barre) + 1px);
    padding: .375rem 1rem;
    background: var(--barre-haut); color: var(--barre-texte);
    border-bottom: 1px solid var(--barre-trait);
}
/* AV1-R2-1 : la barre du haut est collante ; une ancre (#preferences, #bloc-formulaire) et le focus clavier qui font défiler la page ne se posent plus dessous (WCAG 2.4.11). */
html { scroll-padding-top: calc(var(--hauteur-barre) + 1px + var(--espace-2)); }
/* Dans un conteneur qui défile lui-même, l'en-tête colle au bord de ce conteneur, pas à la barre de la page. */
.tableau-defilant thead th, .semaine-defile thead th, .ceq-cadre thead th { top: 0; }
.barre-haut a, .barre-haut summary { color: var(--barre-texte); }
.barre-haut :focus-visible { outline-color: var(--barre-repere); }
.marque-produit { display: block; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--police-titre); font-weight: 700; font-size: 1.0625rem; letter-spacing: .005em; text-decoration: none; }
.barre-haut .version { flex: none; margin: 0; font-family: var(--police-mono); font-size: var(--taille-legende); color: var(--barre-doux); white-space: nowrap; }
.recherche-globale { flex: 1 1 12rem; min-width: 0; max-width: 28rem; margin: 0; }
.barre-haut .recherche-globale input[type="search"] { width: 100%; height: 2.125rem; min-height: 2.125rem; margin: 0; padding: 0 var(--espace-3); font-size: var(--taille-petite); background: var(--barre-courant); color: var(--barre-texte); border: 1px solid var(--barre-bord); border-radius: var(--rayon-controle); }
.recherche-globale input::placeholder { color: var(--barre-doux); }
.cloche { position: relative; display: inline-flex; flex: none; align-items: center; gap: .375rem; min-height: calc(var(--interligne) * var(--taille-petite) + .5rem); padding: .25rem .5rem; border-radius: var(--rayon-controle); font-size: var(--taille-petite); font-weight: 500; text-decoration: none; }
.cloche:hover, .menu-personne summary:hover { background: var(--barre-courant); }
.cloche .icone { width: 1.125rem; height: 1.125rem; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.cloche .compteur { display: inline-flex; align-items: center; justify-content: center; min-width: 1.125rem; height: 1.125rem; padding: 0 .3125rem; background: var(--alerte); color: var(--carte); border-radius: .5625rem; font-family: var(--police-mono); font-size: var(--taille-legende); font-weight: 400; font-variant-numeric: tabular-nums; }

.menu-personne { position: relative; margin-left: auto; flex: none; }
.menu-personne summary { display: flex; align-items: center; gap: var(--espace-2); cursor: pointer; list-style: none; padding: var(--espace-1) var(--espace-2); border-radius: var(--rayon-controle); }
.menu-personne summary::-webkit-details-marker { display: none; }
.menu-personne ul { position: absolute; right: 0; z-index: 5; max-height: calc(100vh - var(--hauteur-barre) - var(--espace-4)); max-height: calc(100dvh - var(--hauteur-barre) - var(--espace-4)); overflow-y: auto; min-width: 13rem; margin: var(--espace-1) 0 0; padding: var(--espace-2); list-style: none; background: var(--carte); color: var(--texte); border: 1px solid var(--bord); border-radius: var(--rayon-carte); box-shadow: var(--ombre-flottant); }
.menu-personne ul a { display: block; padding: var(--espace-2) var(--espace-3); color: var(--texte); text-decoration: none; border-radius: var(--rayon-controle); }
.menu-personne ul a:hover { background: var(--survol); }
.avatar { display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; border-radius: var(--rayon-pilule); object-fit: cover; background: var(--accent-doux); color: var(--texte); font-weight: 650; }

/* Téléphone (≤ 640 px) : la marque rétrécit sur deux lignes (11,5 px) et les écarts aussi ; la barre reste sur un seul rang (153, partie 1, de la maquette). La cloche n'est plus
   que son icône et sa pastille : sa hauteur est celle de la pastille plus ses marges (26 px, comme la maquette). */
@media (max-width: 40rem) {
    .barre-haut { gap: .375rem; }
    .cloche { min-height: 0; }
    .marque-produit { flex: 0 1 7.5rem; font-size: var(--taille-legende); line-height: 1.15; white-space: normal; }   /* maquette : 11,5 px ; le plancher de 12 px tient (écart de 0,5 px, sous la tolérance du banc) */
    .recherche-globale { flex: 1 1 0; }
    /* AJ-27 : au téléphone, « v.017 » seul ; le stade reste dans le nom lu (masquage visuel comme .pour-lecteur, jamais display: none). */
    .barre-haut .version-stade { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

/* AJ-21 : au pointeur grossier, la cloche atteint la cible tactile (AJ-8, jeton --cible-tactile), même au téléphone. */
@media (hover: none) and (pointer: coarse) {
    .cloche { min-width: var(--cible-tactile); min-height: var(--cible-tactile); justify-content: center; }
    /* AV1-R2-2 : le champ de recherche de la barre atteint la cible tactile et passe à 16 px (sous 16 px, iOS zoome la page au focus). La barre fait 56 px : 44 + 2 × 6. */
    .barre-haut .recherche-globale input[type="search"] { height: var(--cible-tactile); min-height: var(--cible-tactile); font-size: 1rem; }
}
/* AJ-25-R2 : au téléphone tactile (375 px), la cloche à pastille (72 px) et « Quoi de neuf ? » (48 px) ne laissaient que 15 px à la marque, que le banc veut à 16 au moins (une lettre lisible, pas une rognure). La cible
   de 44 px vient de min-width et de min-height (règle ci-dessus), pas du remplissage : la cloche rend 4 px de marge de côté sur 8 (72 → 64 px, le lien 48 → 44 px) et la marque passe à 27 px. Les deux conditions sont
   jointes : au bureau et au pointeur fin, la forme de la maquette (padding 4 px 8 px) ne change pas ; placé après la règle de base de .cloche (même spécificité : l'ordre décide). */
@media (max-width: 40rem) and (hover: none) and (pointer: coarse) {
    .cloche { padding-inline: .25rem; }
}

/* AJ-17, lot 1 : le titre de groupe de la maquette (14 px au-dessus, 4 px dessous, capitales à 0,07 em). Maquette : 11 px ; le plancher de 12 px de la feuille (ThemeTest) tient : écart connu, à trancher. */
.corps { display: flex; flex: 1; min-width: 0; }
.menu-titre { margin: .875rem .625rem .25rem; color: var(--doux); font-size: var(--taille-legende); font-weight: 600; text-transform: uppercase; letter-spacing: .07em; }
.menu-titre:first-child { margin-top: .125rem; }

/*
 * AJ-20 : l'icône de chaque entrée (SVG en ligne, trait sur currentColor) et le bouton qui réduit la barre à ses icônes. Réduite, la barre ne garde que l'icône ;
 * le libellé reste dans l'arbre d'accessibilité (nom du lien) et paraît en infobulle au survol ET au focus clavier. L'infobulle est en `position: fixed` à
 * `top: auto` : elle reste à la hauteur du lien et échappe au défilement de la barre (qui la rognerait). Sous 48 rem la barre est cachée : le téléphone ne change pas.
 */
.menu-lateral .icone, .menu-bascule .icone { flex: none; width: 1.125rem; height: 1.125rem; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.menu-bascule-form { margin: 0 0 var(--espace-2); }
.menu-bascule { display: flex; align-items: center; gap: .625rem; width: 100%; padding: .5rem .75rem; border: 0; border-left: 3px solid transparent; border-radius: .4375rem; background: transparent; color: var(--doux); font: inherit; font-size: var(--taille-texte); cursor: pointer; text-align: left; }
.menu-bascule:hover { background: var(--creux); color: var(--texte); }

body.menu-reduit nav.menu-lateral { flex-basis: var(--largeur-barre-reduite); padding-left: var(--espace-2); padding-right: var(--espace-2); }
body.menu-reduit .menu-lateral a, body.menu-reduit .menu-bascule { justify-content: center; padding-left: 0; padding-right: 0; }
body.menu-reduit .menu-bascule .icone { transform: scaleX(-1); }
body.menu-reduit .menu-lateral .menu-titre { height: 1px; margin: var(--espace-2) var(--espace-1); padding: 0; overflow: hidden; background: var(--bord); color: transparent; line-height: 0; }
body.menu-reduit .menu-lateral .libelle { position: fixed; left: calc(var(--largeur-barre-reduite) + var(--espace-2)); z-index: 40; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
body.menu-reduit .menu-lateral a:hover .libelle, body.menu-reduit .menu-lateral a:focus-visible .libelle,
body.menu-reduit .menu-bascule:hover .libelle, body.menu-reduit .menu-bascule:focus-visible .libelle {
    width: auto; height: auto; overflow: visible; clip-path: none;
    padding: var(--espace-1) var(--espace-3); border-radius: var(--rayon-controle);
    background: var(--texte); color: var(--carte); font-size: var(--taille-petite); font-weight: 500; box-shadow: var(--ombre-flottant);
}
/* AV1-R2-5 (WCAG 1.4.13) : survolable (un pont transparent couvre l'écart entre l'entrée et l'infobulle : le pointeur la rejoint sans la perdre) et rejetable (Échap,
   menu-reduit.js pose .sans-infobulle sur le menu jusqu'à ce que le pointeur ou le focus passe à une autre entrée). */
body.menu-reduit .menu-lateral .libelle::before { content: ""; position: absolute; top: 0; bottom: 0; right: 100%; width: calc(var(--espace-2) * 2 + 2px); }
body.menu-reduit nav.menu-lateral.sans-infobulle a .libelle, body.menu-reduit nav.menu-lateral.sans-infobulle .menu-bascule .libelle {
    width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); box-shadow: none; background: transparent;
}

.fil ol { display: flex; flex-wrap: wrap; gap: var(--espace-2); margin: 0 0 var(--espace-3); padding: 0; list-style: none; font-size: var(--taille-petite); color: var(--doux); }
.fil li + li::before { content: "\203A"; margin-right: var(--espace-2); }
.fil [aria-current] { color: var(--texte); }

/* AV1 notes (tableau de bord) : UNE colonne au téléphone (375 px) et jusqu'à 60 rem ; DEUX au bureau, 1 280 et 1 470 px compris (l'ancienne grille `auto-fit` en posait trois ou quatre,
   étroites, dès que l'écran s'élargissait). `align-items: start` : une carte courte garde sa hauteur, elle n'est plus étirée à vide à la hauteur de sa voisine.
   `minmax(0, 1fr)` : une colonne ne s'élargit pas sous une ligne longue (le défilement horizontal du téléphone ne revient pas). Classe employée par le seul tableau de bord. */
.zones { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; gap: var(--espace-4); margin: 0 0 var(--espace-5); }
@media (min-width: 60rem) { .zones { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.zones .carte { margin: 0; }
.formulaire label { display: block; margin: var(--espace-3) 0 var(--espace-1); }
.formulaire label.case, label.case { display: flex; align-items: center; gap: var(--espace-2); margin: var(--espace-2) 0; }
.formulaire input[type=text], .formulaire input[type=email], .formulaire input[type=number], .formulaire select { max-width: 24rem; width: 100%; }
fieldset { border: 0; margin: 0; padding: 0; }
.fiche { display: grid; grid-template-columns: max-content 1fr; gap: var(--espace-2) var(--espace-5); margin: 0; }
.fiche dt { color: var(--doux); }
.fiche dd { margin: 0; overflow-wrap: anywhere; }
.lien-unique { overflow-wrap: anywhere; user-select: all; }
input.lien-unique { width: 100%; max-width: 40rem; font-family: var(--police-mono); }   /* COURRIEL-AJ-19-R (D6) : le lien est un champ en lecture seule ; mêmes couleurs que tout champ (texte sur --carte, déjà contrôlées) */

.barre-basse { display: none; }
.menu-personne .entrees-admin { display: none; }

@media (max-width: 48rem) {
    .menu-lateral, nav.menu-lateral { display: none; }
    .menu-personne .entrees-admin { display: block; }
    .barre-haut .nom { display: none; }
    body.coquille { padding-bottom: 4rem; }
    .barre-basse { display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 4; background: var(--barre-bas); border-top: 1px solid var(--barre-trait); }
    .barre-basse ul { display: flex; margin: 0; padding: 0; list-style: none; }
    .barre-basse li { flex: 1 1 0; min-width: 0; }
    .barre-basse a { display: block; padding: var(--espace-3) var(--espace-1); text-align: center; color: var(--barre-lien); text-decoration: none; font-size: var(--taille-petite); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    /* AV1-R2-6 : le fond de la page courante (--barre-courant) ne se distingue plus du fond de la barre (1,08:1) : un filet de 3 px en haut de l'entrée, dans le vert de repère
       (--barre-repere, 3:1 au moins sur --barre-bas), et la graisse. Ni couleur seule (WCAG 1.4.1) ni changement de structure : le filet est une ombre intérieure. */
    .barre-basse a[aria-current] { background: var(--barre-courant); color: var(--barre-texte); font-weight: 650; box-shadow: inset 0 3px 0 var(--barre-repere); }
    /* AJ-31-R : une ancre ou le focus clavier qui font défiler la page ne se posent plus sous la barre basse fixe (WCAG 2.4.11), comme scroll-padding-top le fait pour la barre du haut. */
    html { scroll-padding-bottom: calc(4rem + var(--espace-1)); }
}

/* ── PA-2 : listes, onglets avec nombre, fiches, formulaires de dossier et de bottin ───────────────────────────────────────────────
   Jetons seulement (aucune couleur en dur) ; aucun sélecteur « nav » nu ; rien ne dépend d'un attribut style. */
.recherche-liste { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-2); flex: 1 1 18rem; min-width: 0; }
.recherche-liste input[type="search"] { flex: 1 1 12rem; min-width: 0; }
.compteur-onglet { display: inline-block; min-width: 1.4em; padding: 0 .35em; border-radius: var(--rayon-controle); background: var(--creux); color: var(--doux); font-size: var(--taille-legende); text-align: center; }
.pagination { display: flex; flex-wrap: wrap; gap: var(--espace-2); align-items: center; margin: var(--espace-2) 0 0; }
.donnees { display: grid; grid-template-columns: minmax(8rem, 14rem) 1fr; gap: var(--espace-1) var(--espace-2); margin: 0; }
.donnees dt { color: var(--doux); }
.donnees dd { margin: 0; overflow-wrap: anywhere; }
.groupe-cases { border: 1px solid var(--bord); border-radius: var(--rayon-controle); padding: var(--espace-2); margin: var(--espace-2) 0; }
.groupe-cases legend { padding: 0 var(--espace-1); }
.case { display: flex; align-items: center; gap: var(--espace-2); margin: var(--espace-1) 0; }
.personne { border-top: 1px solid var(--bord); padding: var(--espace-2) 0; }
.formulaire-en-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-1); margin: 0; }
.sous-etape { color: var(--doux); }
@media (max-width: 48rem) {
    .donnees { grid-template-columns: 1fr; }
}
.liste-simple { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--espace-1); }
/* AV1 notes (tableau de bord) : une ligne de statut de dossier suit la maquette : titre en gras, barre du budget, texte du budget, pastilles, montants, bouton. Chaque ligne est un bloc séparé
   de la suivante par un filet ; les textes discrets perdent la marge basse de `.sous` (ils sont empilés ici par `gap`). Aucun attribut `style` : la barre est un <progress> (`barre-conso`). */
.statuts-dossiers { gap: 0; }
.statut-dossier { display: grid; gap: var(--espace-2); justify-items: start; padding: var(--espace-3) 0; border-top: 1px solid var(--bord); }
.statut-dossier:first-child { padding-top: 0; border-top: 0; }
.statut-dossier:last-child { padding-bottom: 0; }
.statut-dossier > p { margin: 0; }
.statut-dossier .sous { margin: 0; }
.statut-titre { font-weight: 700; overflow-wrap: anywhere; }
.statut-seuil { font-weight: 600; }   /* le mot du seuil (« seuil de 70 % atteint », « budget dépassé ») : le sens ne tient jamais à la couleur de la barre seule */
.statut-dossier .barre-conso { max-width: none; }
.statut-pastilles { display: flex; flex-wrap: wrap; gap: var(--espace-1); }
@media (hover: none) and (pointer: coarse) {
    .statut-action a.action { min-height: var(--cible-tactile); }   /* AV1 notes (R1-D3) : « Voir les étapes » faisait 39 px au pointeur grossier ; la norme maison (AJ-8) est de 44 px, comme AJ-23 et AJ-24-R */
}
/* PA-3 : « Ma semaine ». Jetons seulement (aucune couleur en dur) ; les blocs se positionnent par le script. Plancher de texte : 12 px. */
.semaine-entete { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--espace-3); }
.semaine-entete h2 { margin: 0; }
.semaine-actions { display: flex; flex-wrap: wrap; gap: var(--espace-2); }
.semaine-jour-nav { display: none; gap: var(--espace-2); margin-bottom: var(--espace-3); }
.annonce-ecran { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; }
.semaine-defile { max-height: 70vh; overflow: auto; border: 1px solid var(--bord); border-radius: var(--espace-1); background: var(--carte); }
.sans-cadre { border: 0; margin: 0; padding: 0; min-width: 0; display: contents; }
.semaine { --hauteur-heure: 3rem; }
.semaine-grille { display: grid; grid-template-columns: 3.5rem repeat(7, minmax(6.5rem, 1fr)); min-width: 48rem; }
.semaine-coin, .semaine-jour { position: sticky; top: 0; z-index: 3; background: var(--creux); border-bottom: 1px solid var(--bord); padding: var(--espace-1) var(--espace-2); font-size: var(--taille-petite); text-align: center; color: var(--texte); }
.semaine-heures > div { height: var(--hauteur-heure); box-sizing: border-box; border-top: 1px solid var(--bord); padding-right: var(--espace-1); text-align: right; font-size: var(--taille-legende); color: var(--doux); }
.semaine-colonne { position: relative; height: calc(var(--hauteur-heure) * 24); border-left: 1px solid var(--bord); background-image: linear-gradient(var(--bord) 1px, transparent 1px); background-size: 100% var(--hauteur-heure); user-select: none; touch-action: pan-x pan-y pinch-zoom; }
/* Le contenu d'un bloc court est rogné, jamais défilable : `overflow: hidden` laisse scrollIntoView() faire défiler le bloc (un titre long poussait la poignée d'étirement, `.rz`, au-dessus du bas du bloc) ; `clip` ne crée pas de conteneur défilable. */
.semaine .bloc { position: absolute; left: 2px; right: 2px; box-sizing: border-box; overflow: hidden; overflow: clip; z-index: 1; padding: 2px var(--espace-1); border: 1px solid var(--accent); border-radius: var(--espace-1); background: var(--accent-doux); color: var(--texte); font-size: var(--taille-petite); line-height: 1.25; text-decoration: none; cursor: grab; }
.semaine .bloc.non-facturable { background: var(--creux); border-color: var(--bord-fort); }
.semaine .bloc.absence { background: var(--attention-fond); border-color: var(--attention-bord); color: var(--attention); }
.semaine .bloc:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; z-index: 2; }
.semaine .bloc.fantome { background: var(--info-fond); border: 1px dashed var(--info); pointer-events: none; z-index: 2; }
.semaine .bloc .bloc-heure { font-weight: 600; margin-right: var(--espace-1); }
.semaine .bloc .rz { position: absolute; left: 0; right: 0; bottom: 0; height: 6px; cursor: ns-resize; }
@media (pointer: coarse) { .semaine .bloc .rz { height: 16px; } }
.semaine:not(.avec-js) .semaine-colonne { height: auto; min-height: 4rem; background-image: none; }
.semaine:not(.avec-js) .bloc { position: static; display: block; margin: 2px; }
@media (max-width: 48rem) {
    .semaine-jour-nav { display: flex; }
    .semaine.avec-js .semaine-grille { grid-template-columns: 3.5rem 1fr; min-width: 0; }
    .semaine.avec-js .semaine-jour:not(.actif), .semaine.avec-js .semaine-colonne:not(.actif) { display: none; }
}

/* ── PA-4 : le fil du dossier et le centre d'avis ─────────────────────────────────────────────────────────────────────────
   Jetons seulement (aucune couleur en dur) ; le texte d'une personne garde ses retours à la ligne et se coupe où il faut. */
.fil-messages { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--espace-3); }
.fil-message { padding: var(--espace-3) var(--espace-4); border: 1px solid var(--bord); border-radius: var(--rayon-carte); background: var(--carte); }
.fil-message-mien { border-color: var(--bord-fort); background: var(--creux); }
.fil-entete { margin: 0 0 var(--espace-1); font-size: var(--taille-texte); }
.fil-texte { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.fil-mention { margin: var(--espace-2) 0 0; font-size: var(--taille-texte); }
.fil-saisie { position: relative; }
.fil-saisie textarea { width: 100%; }
.fil-propositions { position: absolute; left: 0; right: 0; z-index: 5; margin: var(--espace-1) 0 0; padding: var(--espace-1); list-style: none; border: 1px solid var(--bord-fort); border-radius: var(--rayon-controle); background: var(--carte); box-shadow: var(--ombre-flottant); }
.fil-propositions[hidden] { display: none; }
.fil-propositions li { padding: var(--espace-2) var(--espace-3); border-radius: var(--rayon-controle); cursor: pointer; }
.fil-propositions li[aria-selected="true"], .fil-propositions li:hover { background: var(--accent-doux); }
.avis-outils { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-4); margin-bottom: var(--espace-4); }
.avis-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--espace-3); }
.avis-ligne { padding: var(--espace-3) var(--espace-4); border: 1px solid var(--bord); border-radius: var(--rayon-carte); background: var(--carte); }
.avis-non-lu { border-color: var(--bord-fort); border-left-width: 4px; }
.avis-texte { margin: 0 0 var(--espace-1); overflow-wrap: anywhere; }
.avis-gestes { display: flex; flex-wrap: wrap; gap: var(--espace-2); margin-top: var(--espace-2); }
.avis-gestes form { margin: 0; }

/* PA-6 (A15, A22, A27, A13, A26) : nom de code, étiquettes, panneau de choix, jalons, repères du temps. Jetons seulement : aucune couleur en dur. */
.nom-code { font-family: var(--police-titre); font-style: italic; font-weight: 600; color: var(--texte); }
/* AJ-10 : les heures, les compteurs et la version en mono (chiffres de même chasse, comme la maquette). */
.semaine-heures, .ceq-heure, .bloc-heure, .cb-heure, .compteur, .compteur-onglet, .version { font-family: var(--police-mono); }
/* AJ-32 / AJ-33 : l'en-tête du dossier est un encadré ; code et intitulé en titre, puis état, client, étiquettes et actions sur une ligne qui se replie (375 px). */
.entete-dossier { position: relative; display: grid; gap: var(--espace-2); }
.entete-dossier .titre-dossier { margin: 0; font-family: var(--police-titre); font-size: var(--taille-section); line-height: var(--interligne-titre); overflow-wrap: anywhere; }
.entete-dossier .reperes-dossier { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-2) var(--espace-3); min-width: 0; }
.entete-dossier .reperes-dossier .pastilles-etiquettes { margin: 0; }
.entete-dossier .nom-code { font-weight: 600; }
/* Le menu ⋮ : sans script, la liste des actions est une ligne visible dans l'encadré ; avec script (.menu-actions-js), un bouton de 2,75 rem en haut à droite et une liste flottante. */
.menu-actions { min-width: 0; }
.menu-actions-liste { margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: var(--espace-2) var(--espace-3); }
.menu-actions-bouton { display: inline-flex; align-items: center; justify-content: center; min-width: var(--cible-tactile); min-height: var(--cible-tactile); border: 1px solid transparent; border-radius: var(--rayon-controle); background: transparent; color: var(--texte); font: inherit; font-size: 1.25rem; line-height: 1; cursor: pointer; }
.menu-actions-bouton[hidden] { display: none; }   /* sans script le bouton reste caché : la règle ci-dessus ne doit pas annuler l'attribut hidden (WCAG 4.1.2) */
.menu-actions-bouton:hover, .menu-actions-bouton[aria-expanded="true"] { background: var(--creux); border-color: var(--bord); }
.menu-actions-js { position: absolute; top: var(--espace-2); right: var(--espace-2); }
.menu-actions-js .menu-actions-liste { position: absolute; right: 0; z-index: 5; min-width: 13rem; margin-top: var(--espace-1); padding: var(--espace-2); flex-direction: column; flex-wrap: nowrap; background: var(--carte); color: var(--texte); border: 1px solid var(--bord); border-radius: var(--rayon-carte); box-shadow: var(--ombre-flottant); }
.menu-actions-js .menu-actions-liste[hidden] { display: none; }
.menu-actions-js .menu-actions-liste a { display: block; padding: var(--espace-2); min-height: var(--cible-tactile); box-sizing: border-box; }
.entete-dossier:has(.menu-actions-js) .titre-dossier { padding-right: 3rem; }
.pastilles-etiquettes { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-1); margin: var(--espace-2) 0; padding: 0; list-style: none; }
/* AJ-17 lot 2 : l'étiquette de dossier est la pastille « acc » de la maquette (E-07, .pl.acc) : fond et encre d'accent, 2 × 8 px, 500, filet transparent ; archivée = « neu » (creux, doux, filet) + trait barré de la maquette (L2-R : l'état ne tient jamais à la teinte seule, consigne §7). L'opacity .6 de la maquette reste retirée (contraste 4,5:1). */
.pastille-etiquette { display: inline-flex; align-items: center; gap: var(--espace-1); padding: .125rem .5rem; border: 1px solid transparent; border-radius: var(--rayon-pilule); background: var(--accent-doux); color: var(--marque); font-size: var(--taille-legende); font-weight: 500; line-height: var(--interligne-titre); text-decoration: none; }
.pastille-etiquette.archivee { border-color: var(--bord); background: var(--creux); color: var(--doux); text-decoration: line-through; }
a.pastille-etiquette.retirable { min-height: 2rem; }
.retrait-pastille { min-width: 1.75rem; min-height: 1.75rem; border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; }
.choix-etiquettes { position: relative; display: inline-block; }
.choix-etiquettes > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: var(--espace-1); }
.choix-etiquettes > summary::-webkit-details-marker { display: none; }
.panneau-etiquettes { position: absolute; z-index: 20; top: 100%; left: 0; width: min(24rem, calc(100vw - 2rem)); max-height: 70vh; overflow: auto; margin-top: var(--espace-1); padding: var(--espace-3); background: var(--carte); border: 1px solid var(--bord-fort); border-radius: var(--rayon-carte); box-shadow: var(--ombre-flottant); }
.panneau-etiquettes.a-droite { left: auto; right: 0; }
@media (max-width: 40rem) {
    .choix-etiquettes { display: block; width: 100%; }
    .panneau-etiquettes { position: static; width: auto; max-height: none; box-shadow: none; }
}
.etiquette-archivee th, .etiquette-archivee td { color: var(--doux); }
.liste-jalons { margin: var(--espace-1) 0 0; padding: 0 0 0 var(--espace-3); list-style: none; }
.liste-jalons li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-2); padding: var(--espace-1) 0; }
.formulaire-jalon { margin: var(--espace-2) 0; }
.semaine-jour .pastille-jour { display: inline-block; min-width: 1.75em; padding: 0 .4em; border-radius: var(--rayon-pilule); background: var(--accent); color: var(--accent-texte); font-weight: 600; }
.semaine-jour.aujourdhui { color: var(--texte); font-weight: 600; }
.semaine-colonne.aujourdhui::before { content: ""; position: absolute; inset: 0; background: var(--accent-doux); opacity: .5; pointer-events: none; }
.semaine-maintenant { position: absolute; left: 0; right: 0; z-index: 2; height: 0; border-top: 2px solid var(--alerte); pointer-events: none; }
.semaine-maintenant::before { content: ""; position: absolute; left: -.3125rem; top: -.4375rem; width: .625rem; height: .625rem; border-radius: var(--rayon-pilule); background: var(--alerte); }
/* PA-7 (A5, A16, A26, A28) : heures de mes dossiers, calendrier de l'équipe en lecture. Jetons seulement : aucune couleur en dur. La couleur ET le motif disent l'état, jamais le volume. */
.ceq-bascule { display: flex; flex-wrap: wrap; gap: var(--espace-2); margin: var(--espace-2) 0; }
.ceq-bascule a[aria-current="true"] { border-color: var(--accent); font-weight: 600; }
/* L2-R : a.action.discrete:hover (0,3,1) battait la règle ci-dessus (0,2,1) : au survol, le filet de la vue courante devenait gris. Le filet d'accent tient aussi au survol. */
.ceq-bascule a.action.discrete[aria-current="true"],
.ceq-bascule a.action.discrete[aria-current="true"]:hover { border-color: var(--accent); }
.ceq-legende { display: flex; flex-wrap: wrap; gap: var(--espace-1) var(--espace-3); margin: var(--espace-2) 0 var(--espace-1); padding: 0; list-style: none; }
.ceq-legende li { display: inline-flex; align-items: center; gap: var(--espace-1); }
.cb-echantillon { display: inline-block; width: 1.5rem; height: 1rem; border: 1px solid var(--bord-fort); border-radius: .25rem; }
.ceq-cadre { max-width: 100%; overflow: auto; border: 1px solid var(--bord); border-radius: var(--rayon-carte); background: var(--carte); }
/* AJ-17 lot 3 : `.ceq-t` de la maquette (v17, l. 315-323) : bordures bas et gauche séparées (border-spacing 0), marge de 3 px, 12 px au plus petit (le plancher du logiciel ; la maquette descend à 9-11 px, écart listé), en-tête de surface en mono 500 et en `--doux`, colonne des personnes en police du corps. */
.ceq-t { border-collapse: separate; border-spacing: 0; width: 100%; min-width: 44rem; font-size: var(--taille-legende); }
.ceq-heures { min-width: 28rem; }
.ceq-t th, .ceq-t td { padding: .1875rem; border: 0; border-bottom: 1px solid var(--bord); border-left: 1px solid var(--bord); text-align: left; vertical-align: top; }
.ceq-t thead th { background: var(--carte); color: var(--doux); font-family: var(--police-mono); font-size: var(--taille-legende); font-weight: 500; position: sticky; top: 0; z-index: 1; }
.ceq-t thead th.aujourdhui { color: var(--marque); }
.ceq-t tbody th { background: var(--carte); color: var(--texte); font-family: var(--police); font-size: var(--taille-legende); font-weight: 500; min-width: 8rem; }
.ceq-t td.aujourdhui { background: var(--accent-doux); }
.ceq-t th.aujourdhui .pastille-jour { display: inline-block; padding: 0 .5em; border-radius: var(--rayon-pilule); background: var(--accent); color: var(--accent-texte); font-weight: 600; }
.cb { display: block; width: 100%; margin: 0 0 .25rem; padding: .125rem .375rem; border: 1px solid var(--bord-fort); border-radius: .25rem; background: var(--carte); color: var(--texte); font: inherit; font-size: .8125rem; line-height: 1.25; text-align: left; cursor: pointer; }
.cb:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cb.choisi { box-shadow: 0 0 0 2px var(--accent); }
.cb-heure, .cb-duree { white-space: nowrap; }
.cb-code { font-weight: 600; }
.cb-signal { font-style: italic; }
.cb.etat-nonsoumis, .cb-echantillon.etat-nonsoumis { border-style: dashed; background: var(--carte); }
.cb.etat-soumis, .cb-echantillon.etat-soumis { border-style: solid; border-left-width: .3125rem; background: var(--accent-doux); }
.rappel-form { display: inline; margin: 0; }
.lien-bouton { padding: 0; border: 0; background: none; color: var(--accent); font: inherit; text-align: left; text-decoration: underline; cursor: pointer; }
.lien-bouton:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bloc.verrouille { opacity: .85; border-left-style: double; }
.cb.etat-valide, .cb-echantillon.etat-valide { border-style: solid; border-color: var(--succes); border-left-width: .3125rem; background-color: var(--succes-fond); background-image: radial-gradient(var(--succes-bord) 1px, transparent 1.5px); background-size: .5rem .5rem; }
.cb.etat-retenu, .cb-echantillon.etat-retenu { border-style: solid; border-color: var(--accent); border-left-width: .3125rem; border-right-width: .3125rem; background-color: var(--succes-fond); background-image: repeating-linear-gradient(135deg, var(--succes-bord) 0 1px, transparent 1px .5rem); }
.cb.etat-renvoye, .cb-echantillon.etat-renvoye { border-style: double; border-color: var(--attention); border-width: .25rem; background: var(--attention-fond); }
.cb.choisi::after { content: " ✓ choisi"; font-weight: 600; }
.petit { font-size: .75rem; padding: .0625rem .375rem; margin-left: var(--espace-1); }
.vb { position: sticky; bottom: 0; z-index: 5; margin-top: var(--espace-3); padding: var(--espace-3); border: 1px solid var(--accent); border-radius: var(--rayon-carte); background: var(--carte); box-shadow: var(--ombre-flottant); }
.vb[hidden], .vb [hidden] { display: none; }
.vb-resume { margin: 0 0 var(--espace-2); font-weight: 600; }
.vb textarea, .val-groupe textarea, #val-commentaire { width: 100%; }
.val-boutons { display: flex; flex-wrap: wrap; gap: var(--espace-2); margin-top: var(--espace-2); }
.val-choix { display: inline-flex; gap: var(--espace-2); align-items: center; font-weight: 600; }
.val-hors { display: block; margin-top: var(--espace-1); }
.cb.etat-absence, .cb-echantillon.etat-absence { border-style: solid; background-color: var(--creux); background-image: repeating-linear-gradient(135deg, transparent 0, transparent .3rem, var(--bord) .3rem, var(--bord) .4rem); }
.ceq-en-ce-moment ul { margin: 0 0 var(--espace-3); padding: 0 0 0 var(--espace-3); }
.ceq-defile { max-height: 36rem; position: relative; }
.ceq-grille { --hauteur-heure: 2.5rem; display: grid; grid-template-rows: auto auto; grid-template-columns: 3.5rem; grid-auto-columns: minmax(9rem, 1fr); grid-auto-flow: column; min-width: min-content; }
.ceq-coin { position: sticky; top: 0; left: 0; z-index: 3; background: var(--creux); }
.ceq-axe { position: sticky; left: 0; z-index: 2; background: var(--carte); border-right: 1px solid var(--bord); }
.ceq-heure { display: block; height: var(--hauteur-heure); padding: 0 .25rem; border-top: 1px solid var(--bord); font-size: .75rem; color: var(--doux); }
.ceq-nom { position: sticky; top: 0; z-index: 2; margin: 0; padding: var(--espace-1); background: var(--creux); border-left: 1px solid var(--bord); border-bottom: 1px solid var(--bord); font-size: .875rem; }
.ceq-col { position: relative; height: calc(var(--hauteur-heure) * 24); border-left: 1px solid var(--bord); background-image: linear-gradient(var(--bord) 1px, transparent 1px); background-size: 100% var(--hauteur-heure); }
.ceq-col .cb { position: absolute; left: .125rem; right: .125rem; width: auto; min-height: 1.25rem; margin: 0; overflow: hidden; }
.ceq-maintenant { position: absolute; left: 0; right: 0; z-index: 4; height: 0; border-top: 2px solid var(--alerte); pointer-events: none; }
.ceq-maintenant.premiere::before { content: ""; position: absolute; left: -.3125rem; top: -.4375rem; width: .625rem; height: .625rem; border-radius: 50%; background: var(--alerte); }
.ceq-panneau { margin-top: var(--espace-3); padding: var(--espace-3); border: 1px solid var(--bord); border-radius: var(--rayon-carte); background: var(--carte); }
.ceq-panneau h3 { margin: 0 0 var(--espace-2); font-size: 1rem; }
.ceq-faits { display: grid; grid-template-columns: max-content 1fr; gap: .125rem var(--espace-3); margin: 0; }
.ceq-faits dt { font-weight: 600; }
.ceq-faits dd { margin: 0; overflow-wrap: anywhere; }
.ceq-survol, .reseau-survol { position: fixed; z-index: 60; max-width: min(24rem, calc(100vw - 1rem)); padding: var(--espace-2) var(--espace-3); border: 1px solid var(--bord-fort); border-radius: var(--rayon-carte); background: var(--carte); color: var(--texte); box-shadow: var(--ombre-flottant); font-size: .8125rem; }
.ceq-survol[hidden], .reseau-survol[hidden], .reseau-source[hidden] { display: none; }
@media (hover: none) { .ceq-survol, .reseau-survol { display: none; } }
/* AJ-34 : la carte du réseau du dossier (le client, les organisations rattachées, leurs contacts) ; l'encadré des coordonnées est la règle .ceq-survol ci-dessus. Cibles de 44 px, jetons seulement. */
.reseau, .reseau-contacts { list-style: none; margin: 0; padding: 0; }
.reseau-membre + .reseau-membre { margin-top: var(--espace-3); padding-top: var(--espace-3); border-top: 1px solid var(--bord); }
.reseau-nom { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-2); margin: 0; font-weight: 600; }
.reseau-contacts { margin-top: var(--espace-1); padding-left: var(--espace-4); }
.reseau-lien { display: inline-flex; align-items: center; min-height: var(--cible-tactile); }
/* WCAG 1.4.11 : le bord de l'encadré du réseau est le filet à 3:1 (--bord-champ sur --carte), pas --bord-fort de la règle partagée (1,8:1 ; mesuré au banc navigateur). */
.reseau-survol { border-color: var(--bord-champ); }
.reseau-survol-liste { display: grid; grid-template-columns: auto 1fr; gap: var(--espace-1) var(--espace-3); margin: 0; }
.reseau-survol-liste dt { color: var(--doux); }
.reseau-survol-liste dd { margin: 0; overflow-wrap: anywhere; }

/*
 * PA-10, AJ-17 lot 3 : barre de consommation du budget (élément progress, sans style en ligne, aucune couleur en dur). Dessin de `.bar` de la maquette :
 * 8 px, rayon 4 px, piste `--creux` avec un filet de 1 px `--bord`, remplissage `--succes`, `.attention` (seuil du dossier) en `--attention`, `.alerte`
 * (dépassement) en `--alerte`. L'état ne passe jamais par la couleur seule : le pourcentage et « Dépasse le budget » restent en texte. En contraste
 * forcé, la barre redevient native.
 */
progress.barre-conso {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    box-sizing: border-box;
    width: 100%;
    max-width: 24rem;
    min-width: 4.375rem;
    height: .5rem;
    margin: 0;
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--bord);
    border-radius: .25rem;
    background: var(--creux);
    color: var(--succes);
}
progress.barre-conso::-webkit-progress-bar { background: var(--creux); }
progress.barre-conso::-webkit-progress-value { background: var(--succes); }
progress.barre-conso::-moz-progress-bar { background: var(--succes); }
progress.barre-conso.attention { color: var(--attention); }
progress.barre-conso.attention::-webkit-progress-value { background: var(--attention); }
progress.barre-conso.attention::-moz-progress-bar { background: var(--attention); }
progress.barre-conso.alerte { color: var(--alerte); }
progress.barre-conso.alerte::-webkit-progress-value { background: var(--alerte); }
progress.barre-conso.alerte::-moz-progress-bar { background: var(--alerte); }
@media (forced-colors: active) {
    progress.barre-conso { -webkit-appearance: auto; appearance: auto; border: 0; background: Canvas; }
}
/*
 * Le tableau des étapes défile dans sa carte à 375 px. Les libellés .pour-lecteur des formulaires des colonnes de droite sont en position
 * absolue : sans carte positionnée, leur bloc conteneur est la page, le défilement de la carte ne les retient pas et ils élargissent
 * toute la page (506 px pour 375, vu par le banc navigateur chez la direction et l'administration, qui seules portent ces formulaires).
 */
.carte:has(.budget-etape) { overflow-x: auto; position: relative; }

/* PA-11 : un onglet de la facturation qui n'existe pas encore paraît, inactif, sans lien. */
.onglets .onglet-inactif { padding: 0.4rem 0.75rem; color: var(--doux); cursor: not-allowed; }   /* AJ-17 lot 3 : `--texte-discret` n'existait pas ; `--doux` sur le fond, sans opacité (4,5:1 promis) */

/* PA-12 : la facture se lit et s'imprime depuis le navigateur ; la page entière tient à 375 px, et à l'impression seuls le papier et ses totaux restent. */
.facture-entete, .facture-totaux { display: grid; gap: var(--espace-2) var(--espace-6); margin: var(--espace-4) 0; }   /* AJ-17 lot 3 : espacements en jetons */
.facture-entete { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.facture-entete div, .facture-totaux div { display: flex; flex-direction: column; gap: var(--espace-1); }
.facture-entete dt, .facture-totaux dt { font-weight: 600; color: var(--doux); }
.facture-entete dd, .facture-totaux dd { margin: 0; overflow-wrap: anywhere; }
.facture-totaux dd { font-variant-numeric: tabular-nums; }
.facture-totaux { max-width: 24rem; margin-left: auto; }
.facture-totaux div { flex-direction: row; justify-content: space-between; border-bottom: 1px solid var(--bord); padding-bottom: var(--espace-1); }
.facture-totaux .total dt, .facture-totaux .total dd { font-weight: 700; }
.facture code { overflow-wrap: anywhere; word-break: break-all; }
.actions-facture { display: flex; flex-wrap: wrap; gap: var(--espace-3); align-items: flex-end; margin-top: var(--espace-4); }
@media (max-width: 30rem) { .facture-totaux { max-width: none; } .actions-facture { flex-direction: column; align-items: stretch; } }
/*
 * AJ-17 lot 4 (point 4) : l'impression de la facture reprend celle de la maquette (v17, `@media print` et `.feuille-facture`) : papier blanc quel que soit le thème, encre #16191a (et non #000),
 * un filet de 2 px sous l'en-tête des lignes, un filet de 2 px au-dessus du total, ni cadre ni marge. Le ruban « données fictives » reste imprimé (cahier §5). Les couleurs en dur ne sont permises
 * que sous @media print (ThemeTest) : le papier ne suit pas le thème. Le banc de conformité (paire P25i, média `print`) compare ces règles à la maquette ; ImpressionFactureTest les lit.
 */
@media print {
    .barre-haut, .menu-lateral, .barre-basse, .fil, .sans-impression, .onglets, .actions-facture { display: none !important; }
    body, main, #contenu { background: #fff !important; color: #16191a !important; }
    .carte.facture { box-shadow: none !important; border: 0 !important; padding: 0 !important; margin: 0 !important; background: #fff !important; color: #16191a !important; }
    .carte.facture :is(h2, h3, p, dl, dt, dd, th, td, li, code, a, s) { color: #16191a !important; }
    .carte.facture :is(table, thead, tbody, tr, th, td) { background: transparent !important; }
    .facture a { text-decoration: none; }
    .carte.facture h2 { font-family: var(--police-titre); }
    .facture .tableau thead th { border-bottom: 2px solid #16191a !important; }
    .facture-totaux .total { border-top: 2px solid #16191a; padding-top: 4px; }
    /* L4-R : la pastille de statut, le texte discret en ligne (« span.sous » d'un paiement renversé) et le ruban portent leur propre couleur de thème : sans cette règle, un compte au thème sombre imprime la
       pastille en #b4d66b et le ruban en #e9b864 (environ 4,3:1 une fois assombris par Chrome, sous 4,5:1 à 12 px), ou en pavés sombres avec « Graphiques d'arrière-plan ». Le ruban reste imprimé (cahier §5). */
    .carte.facture :is(.etiquette, .sous), .ruban { color: #16191a !important; background: transparent !important; border-color: #16191a !important; }
}

/* PA-13 : un paiement ou une affectation renversé reste affiché, biffé. */
.biffe { color: var(--doux); }   /* AJ-17 lot 3 : la couleur douce remplace l'opacité (le contraste de 4,5:1 tient) ; le trait barré dit l'état */
.biffe s { text-decoration: line-through; }

/* PA-13 : le tableau de la répartition d'un paiement vit dans un formulaire, pas à la racine de la carte : il s'empile aussi sous 48 rem. */
@media (max-width: 48rem) {
    .carte form table.empilable { width: 100%; margin: 0; }
    .carte form table.empilable > tbody > tr > td { display: flex; gap: .75rem; padding: .125rem 0; border: 0; }
    .carte form table.empilable > tbody > tr > th { display: block; padding: .125rem 0; border: 0; }
    .carte form table.empilable input { max-width: 100%; }
}

/*
 * AJ-10 : le tableau des lignes d'une facture vit dans un conteneur défilant, pas à la racine de la carte. Avec Open Sans, plus large que la police
 * système, il dépassait l'écran de 375 px (393 px) : il s'empile lui aussi sous 48 rem, comme les autres.
 */
@media (max-width: 48rem) {
    .facture > .tableau-defilant > table.empilable { width: 100%; margin: 0; }
    .facture > .tableau-defilant > table.empilable > tbody > tr > td { display: flex; gap: .75rem; padding: .125rem 0; border: 0; }
    .facture > .tableau-defilant > table.empilable > tbody > tr > th { display: block; padding: .125rem 0; border: 0; }
}

/* Un tableau large défile dans son cadre : la page, elle, ne défile jamais de côté. */
.tableau-defilant { max-width: 100%; overflow-x: auto; }

/* ════════════════════════════════════════════════════════════════════════════
   PA-15 : Réglages (les trois interrupteurs avec leur effet en clair), listes des versions et des derniers changements. Jetons seulement.
   ════════════════════════════════════════════════════════════════════════════ */
.interrupteur { border: 1px solid var(--bord); border-radius: var(--rayon-carte); padding: var(--espace-3) var(--espace-4); margin: 0 0 var(--espace-4); min-width: 0; }
.interrupteur legend { font-weight: 600; padding: 0 var(--espace-2); }
.option-effet { display: flex; gap: var(--espace-3); align-items: flex-start; padding: var(--espace-2) 0; }
.option-effet input { margin-top: .3rem; flex: none; }
.option-effet .effet { display: block; color: var(--doux); }
.liste-changements, .liste-versions { list-style: none; margin: 0 0 var(--espace-4); padding: 0; }
.liste-changements li, .liste-versions li { padding: var(--espace-2) 0; border-bottom: 1px solid var(--bord); overflow-wrap: anywhere; }

/* ─── AJ-1. Ma semaine : la boîte de détails du bloc et le choix du dossier à la frappe ──────────────────────────────────────────────
   <dialog> natif, modal à toutes les largeurs (D-d « a », 4 nov. 2026) ; au téléphone, une feuille qui monte du bas. Sans script, la boîte reste
   OUVERTE dans la page : `position: static` la remet en flux (le navigateur la superposerait sinon). */
.carte.boite-js { border: 0; padding: 0; margin: 0; background: transparent; box-shadow: none; min-height: 0; }
.boite { box-sizing: border-box; padding: 0; border: 1px solid var(--bord); border-radius: var(--rayon-carte); background: var(--carte); color: var(--texte); box-shadow: var(--ombre-flottant); width: min(36rem, calc(100vw - 2rem)); max-height: calc(100dvh - 2rem); overflow: auto; }
.boite[open]:not(:modal) { position: static; width: auto; max-height: none; box-shadow: none; border: 0; }
.boite::backdrop { background: color-mix(in srgb, var(--texte) 55%, transparent); }
.boite-entete { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--espace-3); padding: var(--espace-4) var(--espace-4) var(--espace-2); }
.boite-entete h2 { margin: 0; }
.boite-sous { margin: var(--espace-1) 0 0; font-size: var(--taille-petite); color: var(--doux); min-height: 1.25em; }
.boite-fermer { min-width: var(--cible-tactile); min-height: var(--cible-tactile); font-size: 1.25rem; line-height: 1; justify-content: center; }
.boite > .avis, .boite .formulaire { margin-left: var(--espace-4); margin-right: var(--espace-4); }
.boite .formulaire { padding-bottom: var(--espace-3); }
.boite .formulaire input[type=text], .boite .formulaire select { max-width: none; }
.boite-heures { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: var(--espace-3); }
.boite-heures input { width: 100%; box-sizing: border-box; }
.boite-pied { position: sticky; bottom: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--espace-2); margin-top: var(--espace-4); padding: var(--espace-3) 0; background: var(--carte); border-top: 1px solid var(--bord); }
.boite-pied .action:not(.discrete) { order: 2; }
#bloc-retirer { margin: 0; }
.boite-pied .retirer-bloc { margin-right: auto; }
.combo { position: relative; }
.combo ul[role=listbox] { margin: var(--espace-1) 0 0; padding: 0; list-style: none; max-height: 14rem; overflow-y: auto; border: 1px solid var(--bord-champ); border-radius: var(--rayon-controle); background: var(--carte); }
.combo li[role=option] { padding: var(--espace-2) var(--espace-3); min-height: var(--cible-tactile); box-sizing: border-box; display: flex; align-items: center; cursor: pointer; border-bottom: 1px solid var(--bord); }
.combo li[role=option]:last-child { border-bottom: 0; }
.combo li[role=option]:hover { background: var(--survol); }
.combo li[role=option][aria-selected=true] { background: var(--accent-doux); outline: 2px solid var(--focus); outline-offset: -2px; }
.semaine .bloc.sel { outline: 2px solid var(--focus); outline-offset: 1px; z-index: 2; }
@media (max-width: 40rem) {
    .boite:modal { width: 100%; max-width: 100%; margin: auto 0 0; border-radius: var(--rayon-grand) var(--rayon-grand) 0 0; max-height: 92dvh; }
    .boite-heures { grid-template-columns: 1fr 1fr; }
    .boite-heures > div:first-child { grid-column: 1 / -1; }
    .boite-pied .action { min-height: var(--cible-tactile); }
}
@media (prefers-reduced-motion: no-preference) {
    .boite:modal { animation: boite-entree 160ms ease-out; }
    @keyframes boite-entree { from { opacity: 0; transform: translateY(.5rem); } }
}

/* ─── AJ-17 lot 3. Le Gantt du dossier (SVG produit par le serveur, dossiers/_gantt.blade.php) ──────────────────────────────────────────────
   Jetons seulement : aucune couleur en dur, aucun style en ligne. L'état ne passe jamais par la couleur seule : une barre sans avancement est pleine, une barre avec avancement est un contour
   hachuré (partie restante) dont la partie réalisée est pleine, chaque barre porte son numéro, et le tableau des étapes dit tout ce que le dessin dit (WCAG 1.4.1). Chaque barre a sa couleur
   (8 jetons --gxb, rang de l'étape modulo 8, maquette v17) ; elle tranche à 3:1 sur le cadre (`--creux`) et sur la carte (1.4.11), l'encre du numéro à 4,5:1 sur elle. À 375 px, seul le cadre défile (role="region", tabindex="0") ; la page ne défile pas de côté. */
.gantt-cadre { max-width: 100%; overflow-x: auto; border: 1px solid var(--bord); border-radius: var(--rayon-controle); background: var(--creux); }
.gantt-svg { display: block; min-width: 40rem; font-family: var(--police-mono); font-size: var(--taille-legende); }
.gantt-mois-trait { stroke: var(--bord); stroke-width: 1; }
.gantt-mois-texte { fill: var(--doux); font-size: var(--taille-legende); }
.gantt-filet-entete { stroke: var(--bord-fort); stroke-width: 1; }
.gantt-filet-couloir { stroke: var(--bord); stroke-width: 1; }
/* Chaque barre porte sa couleur (classe gx0 à gx7, rang de l'étape modulo 8) : --gxb (fond) et --gxf (encre du numéro) ; la hachure, dans <defs>, porte la sienne par la même classe. */
.gantt-barre.gx0 { --gxb: var(--gxb0); --gxf: var(--gxf0); }
.gantt-barre.gx1 { --gxb: var(--gxb1); --gxf: var(--gxf1); }
.gantt-barre.gx2 { --gxb: var(--gxb2); --gxf: var(--gxf2); }
.gantt-barre.gx3 { --gxb: var(--gxb3); --gxf: var(--gxf3); }
.gantt-barre.gx4 { --gxb: var(--gxb4); --gxf: var(--gxf4); }
.gantt-barre.gx5 { --gxb: var(--gxb5); --gxf: var(--gxf5); }
.gantt-barre.gx6 { --gxb: var(--gxb6); --gxf: var(--gxf6); }
.gantt-barre.gx7 { --gxb: var(--gxb7); --gxf: var(--gxf7); }
.gantt-hachure-trait.gx0 { stroke: var(--gxb0); }
.gantt-hachure-trait.gx1 { stroke: var(--gxb1); }
.gantt-hachure-trait.gx2 { stroke: var(--gxb2); }
.gantt-hachure-trait.gx3 { stroke: var(--gxb3); }
.gantt-hachure-trait.gx4 { stroke: var(--gxb4); }
.gantt-hachure-trait.gx5 { stroke: var(--gxb5); }
.gantt-hachure-trait.gx6 { stroke: var(--gxb6); }
.gantt-hachure-trait.gx7 { stroke: var(--gxb7); }
.gantt-plein { fill: var(--gxb); stroke: var(--gxb); }
.gantt-fond { fill: var(--carte); }
.gantt-fait { fill: var(--gxb); }
.gantt-contour { stroke: var(--gxb); }
.gantt-no-fond { fill: var(--carte); }
.gantt-no { fill: var(--texte); font-size: var(--taille-legende); font-weight: 600; }
.gantt-no.gantt-no-plein { fill: var(--gxf); }
.gantt-auj { stroke: var(--alerte); }
.gantt-legende { display: flex; flex-wrap: wrap; gap: var(--espace-1) var(--espace-3); margin: var(--espace-2) 0; padding: 0; list-style: none; font-size: var(--taille-legende); }
.gantt-echantillon { display: inline-block; width: 1.5rem; height: .75rem; border: 1.5px solid var(--accent); border-radius: .25rem; vertical-align: middle; }
.gantt-echantillon.realise { background: var(--accent); }
.gantt-echantillon.restant { background: repeating-linear-gradient(135deg, var(--accent) 0 1.5px, transparent 1.5px 6px) var(--carte); }
.gantt-dossier .tableau-defilant { margin-top: var(--espace-3); }
.dates-etape { margin: var(--espace-1) 0 0; }
.dates-etape-saisie input[type="date"] { width: auto; min-width: 9.5rem; }

/* AJ-23 : la Centrale des notifications. Le formulaire « Me rappeler » (date, dossier, note), la note d'un rappel (lue par son auteur seul) et la ligne « Reporter » ; jetons seulement. */
.formulaire input[type=date], .formulaire textarea, #me-rappeler select { max-width: 24rem; width: 100%; }
.avis-note { margin: 0 0 var(--espace-1); overflow-wrap: anywhere; }
.avis-gestes .formulaire-en-ligne label { margin: 0; }
/* AJ-23 : au pointeur grossier, les gestes de la Centrale (Ouvrir, Fait, Marquer lu, Répondu, Reporter, Retirer) et le formulaire « Me rappeler » tiennent la cible tactile (le jeton --hauteur-controle ne la porte qu'en densité « bureau »). */
@media (hover: none) and (pointer: coarse) {
    .avis-gestes button.action, .avis-gestes a.action, #me-rappeler select, #me-rappeler button.action { min-height: var(--cible-tactile); }
}

/* AJ-31 (Alpha v1) : la note d'un bloc de temps au journal du dossier. Retours à la ligne gardés, mot trop long coupé (500 caractères lisibles à 375 px), aucun défilement horizontal. */
.note-temps { white-space: pre-line; overflow-wrap: anywhere; min-width: 0; }

/* ── D-α5 (Alpha v1) : le curseur de case de Ma semaine au clavier ───────────────────────────────────────────────────────────
   Le calendrier est un seul arrêt de tabulation (la colonne qui porte tabindex="0") ; le curseur est un div .curseur-case posé par le script (CSSOM, jamais un attribut de style),
   montré quand la colonne a le focus CLAVIER (:focus-visible : un clic à la souris ne le montre pas). Jetons seulement. Le cadre de focus de la colonne entière (72 rem de haut)
   cède la place au curseur, qui est le repère du focus (2.4.7) ; le script le garde visible, sous l'en-tête collant des jours (2.4.11). */
.semaine-colonne .curseur-case { display: none; position: absolute; left: 0; right: 0; box-sizing: border-box; border: 2px solid var(--focus); background: var(--info-fond); pointer-events: none; z-index: 2; }
.semaine-colonne:focus-visible { outline: none; }
.semaine-colonne:focus-visible .curseur-case { display: block; }

/* AJ-24 : signaler (le bouton de la barre du haut, le texte d'un signalement). Jetons seulement ; la cloche donne déjà la forme, la cible tactile et le focus.
   AJ-24-R : sous 40 rem la barre n'a plus la place d'un quatrième contrôle (le champ de recherche tombait à 26 px, la cloche était recouverte : WCAG 2.5.8) ; le bouton de la barre se cache et
   « Signaler » se montre au menu de la personne, à côté de « Mes signalements » (même destination, même nom). L'endroit définitif reste à trancher. */
.cloche.signaler .libelle-signaler { white-space: nowrap; }
/* AJ-24-R puis AV1 notes (10 nov.) : l'ordre à droite est Signaler → Post-it → menu de la personne (dernier élément). Au bureau, Signaler prend la marge automatique de la barre et le groupe d'outils (le Post-it)
   qui le suit la rend ; sans Signaler (compte inactif) ou sous 40 rem (Signaler caché, au menu de la personne), c'est le groupe d'outils qui prend la marge automatique, jamais le menu (`.outils-haut + .menu-personne`). */
.barre-haut .cloche.signaler { margin-left: auto; }
.cloche.signaler + .outils-haut { margin-left: 0; }
.outils-haut + .menu-personne { margin-left: 0; }
.menu-personne .signaler-menu { display: none; }
@media (max-width: 40rem) {
    .cloche.signaler { display: none; }
    .cloche.signaler + .outils-haut { margin-left: auto; }
    .menu-personne .signaler-menu { display: list-item; }
}
.signalement-texte, .signalement-extrait { margin: 0 0 var(--espace-2); overflow-wrap: anywhere; }
.signalement-texte { white-space: pre-wrap; }
@media (hover: none) and (pointer: coarse) {
    .avis-outils a.action, .formulaire select, .formulaire input[type="text"], .formulaire button.action { min-height: var(--cible-tactile); }   /* AJ-24-R : le banc, joué au pointeur grossier, a mesuré 39 px aux boutons */
    .avis-outils a.action { display: inline-flex; align-items: center; }
}

/* ─── PI-31. Les liens fin-à-début et le chemin critique, en texte (dossiers/_liens-etape.blade.php) ─────────────────────────────────────────
   Jetons seulement. Sur l'écran des étapes, chaque ligne dit « Après : 1, 3 », sa marge en jours et, au besoin, la mention « Chemin critique » (une étiquette avec son texte : jamais la couleur seule, WCAG 1.4.1).
   Le champ de lien est un select natif et un bouton, au clavier comme à la souris ; à 375 px il passe à la ligne et ne dépasse pas la carte (qui défile seule, voir .carte:has(.budget-etape)). */
.liens-etape { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-1) var(--espace-3); margin: var(--espace-1) 0 0; }
.liens-etape-saisie, .liens-etape-retrait { margin: var(--espace-1) 0 0; }
.liens-etape-saisie select { flex: 1 1 10rem; width: auto; min-width: 0; max-width: 100%; }
.liens-etape-retrait .action { white-space: normal; text-align: left; }
.liens-etape-erreur { display: block; margin-top: var(--espace-1); }

/* PI-31, au Gantt du dossier. Une barre du chemin critique porte la classe `critique` : son contour est épais, en tirets, dans l'encre du texte (--texte, déclarée à 4,5:1 sur le cadre --creux et sur la carte), et déborde
   de la barre pour se voir aussi sur le cadre, quelle que soit la couleur de la barre : un motif et une épaisseur, jamais la couleur seule (WCAG 1.4.1) ; le mot « critique » est dans le nom accessible de la barre et
   le tableau écrit « Chemin critique » (le dessin est décoratif). Les liens sont des traits : --doux (4,5:1 sur --creux), et --texte pour un lien dont les deux bouts sont critiques. Aucune couleur nouvelle : aucune paire à déclarer. */
.gantt-barre.critique { overflow: visible; }
.gantt-barre.critique .gantt-plein,
.gantt-barre.critique .gantt-contour { stroke: var(--texte); stroke-width: 5; stroke-dasharray: 7 3; }
.gantt-lien-trait { stroke: var(--doux); stroke-width: 1.5; fill: none; }
.gantt-fleche { fill: var(--doux); }
.gantt-lien.critique .gantt-lien-trait { stroke: var(--texte); stroke-width: 2; }
.gantt-fleche.critique { fill: var(--texte); }
.gantt-echantillon.critique { background: transparent; border: 3px dashed var(--texte); }

/* ═════════════════════════════════════════════════════════════════
   AJ-25 (post-it n° 8) : le bouton Post-it de la barre du haut, les notes collées sur l'écran, le formulaire de la note, la liste.
   Jetons seulement : le papier (--postit, --postit-bord, --postit-encre, deux thèmes), la barre (--barre-*), l'accent et l'attention. Aucune couleur en dur.
   ═════════════════════════════════════════════════════════════════ */

/* Le groupe d'outils de la barre, juste avant le menu de la personne (le bouton Post-it ; l'horloge de saisie du temps, PI-34, viendrait à sa gauche). Il prend la marge automatique de la barre,
   que `.cloche.signaler + .outils-haut` lui retire quand « Signaler » la porte déjà (voir AJ-24). */
.outils-haut { display: flex; flex: none; align-items: center; gap: .375rem; margin-left: auto; }
/* Rond, 38 px, même filet et même opacité au repos que l'horloge de la maquette (tete.html:224) ; plein au survol, au focus et quand le mode « coller » est actif. */
.postit-bouton { display: inline-flex; flex: none; align-items: center; justify-content: center; box-sizing: border-box; width: 2.375rem; height: 2.375rem; min-height: 0; padding: 0; gap: .375rem; border-radius: 50%; border: 1px solid var(--barre-bord); background: var(--barre-courant); color: var(--barre-texte); opacity: .6; font-size: var(--taille-petite); font-weight: 500; text-decoration: none; cursor: grab; touch-action: none; user-select: none; }
.postit-bouton .icone { width: 1.125rem; height: 1.125rem; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.postit-bouton .libelle-postit { display: none; white-space: nowrap; }
.postit-bouton:hover, .postit-bouton:focus-visible { opacity: 1; background: var(--barre-survol); }
.postit-bouton[aria-pressed="true"] { opacity: 1; background: var(--accent); color: var(--accent-texte); border-color: var(--accent); }
.barre-haut a.postit-bouton[aria-pressed="true"] { color: var(--accent-texte); }
/* Dès 40 rem : le libellé « Post-it » paraît (la barre a la place) ; en dessous, l'icône seule. */
@media (min-width: 40rem) {
    .postit-bouton { width: auto; padding: 0 .75rem; border-radius: var(--rayon-pilule); }
    .postit-bouton .libelle-postit { display: inline; }
}
/* Au pointeur grossier : la cible tactile de 44 px (AJ-8, jeton --cible-tactile), même au téléphone. */
@media (hover: none) and (pointer: coarse) {
    .postit-bouton { min-height: var(--cible-tactile); min-width: var(--cible-tactile); }
}

/* Les notes de l'écran. Sans script : une liste dans un <details>, en flux. Avec postits.js : les notes qui ont une position montent dans la couche, posée sur le contenu (`#contenu`), et se placent par le CSSOM. */
#contenu { position: relative; }
.postits-ecran { margin-top: var(--espace-4); }
.postits-liste > summary { cursor: pointer; font-weight: 600; padding: var(--espace-1) 0; }
.postits-calque { display: flex; flex-wrap: wrap; gap: var(--espace-4); padding: var(--espace-4) var(--espace-2) var(--espace-2); }
.postit, .postit-note { box-sizing: border-box; background: var(--postit); color: var(--postit-encre); border: 1px solid var(--postit-bord); border-radius: 2px; }
.postit { position: relative; width: 11rem; max-width: 100%; padding: var(--espace-2) var(--espace-2) var(--espace-1); font-size: var(--taille-legende); line-height: 1.4; box-shadow: var(--ombre-repos); transform: rotate(-.6deg); }
.postit .postit-n { position: absolute; top: -.5625rem; left: -.5625rem; display: flex; align-items: center; justify-content: center; min-width: 1.25rem; height: 1.25rem; margin: 0; padding: 0 .375rem; border-radius: var(--rayon-pilule); background: var(--postit-encre); color: var(--postit); font-family: var(--police-mono); font-size: var(--taille-legende); }
.postit .postit-texte { margin: 0 0 var(--espace-2); white-space: pre-wrap; overflow-wrap: anywhere; }
.postit .postit-meta { margin: var(--espace-1) 0 0; font-family: var(--police-mono); font-size: var(--taille-legende); }
.postits-couche { position: absolute; inset: 0; z-index: 20; overflow-x: clip; pointer-events: none; }
.postits-couche .postit { position: absolute; margin: 0; pointer-events: auto; }
.postits-couche .postit-note { pointer-events: auto; }   /* la couche laisse passer le pointeur : le formulaire de la note, lui, reçoit les clics (Coller, Annuler, le champ) */
/* Une note qui chevauche l'élément qui a le focus s'atténue et laisse passer le pointeur (WCAG 2.4.11) ; elle revient dès que le focus la quitte. */
.postit.postit-estompe { opacity: .25; pointer-events: none; }
/* « Masquer » ne cache que les notes : le formulaire de la note vit dans la même couche, et « Post-it » doit pouvoir s'ouvrir même quand les notes sont masquées (AJ-25-R). */
body.postits-masques .postits-couche .postit { display: none; }
.postit-masquer { margin: var(--espace-2) 0 0; }
.postit-masquer[hidden] { display: none; }

/* Le formulaire de la note : sur place (positionné par le script) ou, par la voie du clavier, en haut à droite, sous la barre. */
.postit-note { position: absolute; z-index: 30; width: 15rem; max-width: calc(100vw - 2rem); padding: var(--espace-3); box-shadow: var(--ombre-flottant); }
.postit-note[hidden] { display: none; }
.postit-note.postit-note-libre { position: fixed; top: calc(var(--hauteur-barre) + 1px + var(--espace-3)); right: var(--espace-4); }
.postit-note label { display: block; font-size: var(--taille-petite); font-weight: 600; }
.postit-note textarea { width: 100%; min-height: 5rem; margin: var(--espace-1) 0; padding: var(--espace-1) var(--espace-2); background: var(--carte); color: var(--texte); border: 1px solid var(--bord-champ); border-radius: var(--rayon-controle); }
.postit-note .sous, .postit-note .erreur { margin: 0 0 var(--espace-2); color: var(--postit-encre); font-size: var(--taille-legende); }
/* AJ-25-R : le lien et l'anneau de focus sont sur le papier, pas sur la page : l'encre du papier (paire `--postit-encre sur --postit`, déclarée en tête, 4,5:1 aux deux thèmes) remplace le bleu du navigateur et le vert de --focus (1,2:1 sur le papier sombre). */
.postit-note a { color: var(--postit-encre); }
.postit-note :focus-visible { outline-color: var(--postit-encre); }
.postit-gestes { display: flex; flex-wrap: wrap; gap: var(--espace-2); }
.postit-gestes .action { min-height: 2rem; }
/* Le bandeau du mode « coller » (role="status") : fixe, sous la barre ; vide, il ne paraît pas. Le contenu est entouré d'un trait pointillé tant que le mode est actif (maquette). */
.postit-bandeau { position: fixed; z-index: 35; top: calc(var(--hauteur-barre) + 1px + var(--espace-2)); left: 50%; transform: translateX(-50%); max-width: calc(100vw - 2rem); margin: 0; padding: var(--espace-2) var(--espace-3); background: var(--attention-fond); color: var(--attention); border: 1px solid var(--attention-bord); border-radius: var(--rayon-controle); font-size: var(--taille-petite); box-shadow: var(--ombre-flottant); }
/* Vide, le bandeau ne se voit pas, mais il reste dans l'arbre d'accessibilité (jamais display: none) : une zone role="status" qui naît avec son texte n'est souvent pas lue (AV1 notes-2, revue 2 M5). */
.postit-bandeau:empty { padding: 0; border-width: 0; box-shadow: none; }
body.postit-coller #contenu { cursor: copy; outline: 2px dashed var(--attention); outline-offset: -2px; }
/* AV1 notes : le glisser du bouton « Post-it » (geste repris d'un outil antérieur du consultant). Le fantôme suit le pointeur (posé par le script, par le CSSOM) et ne le reçoit jamais ; il porte le papier et son encre (paire déclarée,
   4,5:1) et un trait d'attention. Le contenu reprend le trait pointillé du mode « coller » : le même signal, jamais la couleur seule (le fantôme dit « Déposer ici… » et le bandeau le répète). */
.postit-fantome { position: fixed; z-index: 45; box-sizing: border-box; width: 11rem; max-width: calc(100vw - 1rem); padding: var(--espace-2); background: var(--postit); color: var(--postit-encre); border: 1px solid var(--postit-bord); border-radius: 2px; box-shadow: var(--ombre-flottant); font-size: var(--taille-legende); line-height: 1.4; pointer-events: none; transform: rotate(-.6deg); opacity: .92; }
body.postit-glisse, body.postit-glisse * { cursor: grabbing; user-select: none; }
body.postit-glisse #contenu { outline: 2px dashed var(--attention); outline-offset: -2px; }
/* AV1 notes-2 : déplacer une note déjà posée. On la tient et on la glisse (le fantôme montre où elle se posera) ; ou, sans glisser (WCAG 2.5.7), le bouton « Déplacer » de la note, puis un clic à la nouvelle place, ou les flèches puis Entrée.
   Jetons seulement. Le bouton est à l'encre du papier (paire `--postit-encre sur --postit` déclarée plus haut, 4,5:1, et son inverse à l'état enfoncé) ; l'état se dit aussi par le trait pointillé de la note et par le bandeau, jamais par la couleur seule.
   Pendant le glisser et le déplacement au clic, les notes laissent passer le pointeur : la zone visée est celle du contenu sous elles (sauf le bouton de la note en cours, qui sert à l'abandonner). */
.postits-couche .postit { cursor: grab; user-select: none; }
/* Au doigt, seule la ligne du numéro (la poignée) saisit la note : elle seule retient le défilement ; le reste de la note laisse défiler la page et se sélectionner. */
.postit .postit-n { touch-action: none; }
.postit .postit-deplacer { display: block; box-sizing: border-box; min-height: 1.75rem; margin: var(--espace-1) 0 0; padding: 0 var(--espace-2); background: transparent; color: var(--postit-encre); border: 1px solid var(--postit-encre); border-radius: var(--rayon-controle); font: inherit; font-size: var(--taille-legende); cursor: pointer; touch-action: manipulation; }
.postit .postit-deplacer[hidden] { display: none; }
.postit .postit-deplacer:hover { text-decoration: underline; }
.postit.postit-en-deplacement [data-postit-deplacer] { background: var(--postit-encre); color: var(--postit); }
.postit .postit-deplacer:focus-visible { outline: 2px solid var(--postit-encre); outline-offset: 2px; }
.postit.postit-en-deplacement { outline: 2px dashed var(--postit-encre); outline-offset: -3px; }
body.postit-glisse .postit.postit-en-deplacement { opacity: .55; }
body.postit-glisse .postits-couche .postit, body.postit-deplace .postits-couche .postit { pointer-events: none; }
body.postit-deplace .postits-couche .postit.postit-en-deplacement .postit-deplacer { pointer-events: auto; }
body.postit-deplace #contenu { cursor: copy; outline: 2px dashed var(--attention); outline-offset: -2px; }
/* L'échec d'un déplacement (role="alert") : même place que le bandeau, au rouge de l'alerte (paire `--alerte sur --alerte-fond` déclarée plus haut) ; vide, il ne paraît pas. */
.postit-alerte { position: fixed; z-index: 36; top: calc(var(--hauteur-barre) + 1px + var(--espace-2)); left: 50%; transform: translateX(-50%); max-width: calc(100vw - 2rem); margin: 0; padding: var(--espace-2) var(--espace-3); background: var(--alerte-fond); color: var(--alerte); border: 1px solid var(--alerte-bord); border-radius: var(--rayon-controle); font-size: var(--taille-petite); box-shadow: var(--ombre-flottant); }
.postit-alerte:empty { padding: 0; border-width: 0; box-shadow: none; }

/* La liste /postits. */
.postit-texte-liste { margin: 0 0 var(--espace-2); white-space: pre-wrap; overflow-wrap: anywhere; }
.postit-ligne h2 .statut { margin-left: var(--espace-2); font-size: var(--taille-petite); font-weight: 400; }
@media (hover: none) and (pointer: coarse) {
    .postit-note textarea, .postit-gestes .action, .postit-masquer, .postit .postit-deplacer { min-height: var(--cible-tactile); }
    /* La poignée au doigt : la ligne du numéro tient la cible tactile (44 px) ; le texte de la note se sélectionne. */
    .postits-couche .postit { user-select: text; }
    .postit .postit-n { position: static; box-sizing: border-box; width: auto; min-height: var(--cible-tactile); height: auto; margin: 0 0 var(--espace-1); justify-content: flex-start; border-radius: var(--rayon-controle); }
}
@media print {
    .postits-ecran, .postits-couche, .postit-bandeau, .postit-alerte { display: none !important; }
}

/* ═════════════════════════════════════════════════════════════════
   AJ-26 (post-it n° 9) : « Quoi de neuf » : le lien de la barre du haut (un point tant qu'une note publiée n'est pas vue), l'écran de lecture, l'outil du sys_admin.
   Jetons seulement. Le point prend --barre-point (ambre, comme --pt de la maquette, tete.html:459 ; 3:1 au moins sur --barre-haut, paire déclarée plus haut, deux thèmes) ; le sens ne tient pas au point seul (texte caché « n notes non lues »).
   ═════════════════════════════════════════════════════════════════ */
.quoi-de-neuf { gap: .375rem; }
/* AJ-26-R : la forme de `.ev-lien` de la maquette (tete.html:516) : police mono, 12 px, la couleur d'accent de la barre (--barre-repere : 4,5:1 sur la barre, paire déclarée), souligné. Le sélecteur porte `.barre-haut` pour passer devant `.barre-haut a`. */
.barre-haut .quoi-de-neuf { font-family: var(--police-mono); font-size: var(--taille-legende); font-weight: 400; color: var(--barre-repere); text-decoration: underline; }
.quoi-de-neuf .icone { display: none; }
.quoi-de-neuf .libelle-qdn { white-space: nowrap; }
/* AJ-25-R : sous 48 rem (là où le menu latéral cède la place à la barre basse ; le correctif a d'abord visé 40 rem, mais à 667 px, un téléphone en paysage, la recherche tombait à 33 px avec la forme mono), « Quoi de neuf ? » (119 px sans retour à la ligne) et le bouton Post-it prenaient la place de la recherche (0 px) et de la marque (0 px), et le menu de la personne recouvrait le champ. Le libellé se
   masque à l'œil (même masquage que .pour-lecteur, jamais display: none : le nom lu reste « Quoi de neuf ? »), l'icône paraît à sa place avec le point ; la recherche garde 44 px de large (la marque cède, elle retrécit déjà). */
@media (max-width: 48rem) {
    .quoi-de-neuf .icone { display: block; }
    .quoi-de-neuf .libelle-qdn { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); }
    .recherche-globale { min-width: 2.75rem; }
}
.ev-point { flex: none; width: .5rem; height: .5rem; border-radius: 50%; background: var(--barre-point); }
.nouveautes-outils { margin-bottom: var(--espace-4); }
.nouveaute .nouveaute-texte { margin: 0 0 var(--espace-2); white-space: pre-line; overflow-wrap: anywhere; }
.nouveaute h2, .nouveaute h3, .nouveaute h4 { margin-top: 0; }
.nouveaute-etiquette { margin-left: var(--espace-2); font-size: var(--taille-petite); font-weight: 600; }
.nouveaute-ligne { margin-bottom: var(--espace-4); }
@media print {
    .quoi-de-neuf { display: none !important; }
}
