/* Les règles du portail Efm — la disposition, pas l'apparence.
 *
 * **Ce fichier ne contient aucune valeur d'apparence**, et c'est ce qui rend le produit
 * re-thémable : ni couleur, ni police, ni rayon, ni ombre n'y sont écrits — il ne lit que
 * des jetons, définis dans `theme.css`. Une nouvelle identité se fait donc dans ce fichier-
 * là, sans relire celui-ci. Des témoins refusent toute valeur littérale ici
 * (`TestLesDeuxThemes`) : sans eux, la règle tiendrait jusqu'au premier correctif pressé.
 *
 * **Il vit hors des gabarits parce qu'un style en ligne ne s'applique pas.** La politique
 * de contenu est `default-src 'self'` sans `'unsafe-inline'` : un bloc `<style>` ou un
 * attribut `style="…"` est refusé par le navigateur, sans erreur visible. Le portail a vécu
 * six phases ainsi. Un témoin tient les gabarits.
 *
 * Servi depuis `/statique/efm.css`, **après** `theme.css`, avec l'empreinte du dossier en
 * paramètre : le cache est d'un an, et c'est l'empreinte qui le périme.
 *
 * ── L'ordre du fichier, et il ne se réarrange pas ──────────────────────────────────
 *   1. remise à zéro   2. éléments   3. coquille   4. composants
 *   5. le tableau de bord   6. utilitaires   7. impression
 * Les requêtes média restent **collées à leur composant** : la cascade se lit là où on la
 * modifie. Le point de bascule vaut 60 rem partout (`--bascule`, documentaire).
 */

/* ═══ 1. REMISE À ZÉRO ════════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0; background: var(--fond); color: var(--encre);
  font: var(--t-base)/1.5 var(--police);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; transition-duration: 1ms !important; }
}

/* ═══ 2. ÉLÉMENTS ═════════════════════════════════════════════════════════════════════
 * Le style du portail porte d'abord sur des éléments : les restyler ici remonte les seize
 * écrans d'un coup, sans toucher à un gabarit.
 */
a { color: var(--lien); text-decoration: none; }
a:hover { color: var(--accent-fonce); text-decoration: underline; }
h1 { font-size: var(--t-xl); font-weight: var(--gras-titre); letter-spacing: var(--chasse-titre);
     margin: 0 0 var(--pas-4); }
h2 { font-size: var(--t-m); font-weight: var(--gras-fort); margin: var(--pas-6) 0 var(--pas-3); }
h3 { font-size: var(--t-base); font-weight: var(--gras-fort); margin: var(--pas-5) 0 var(--pas-2); }
p { margin: 0 0 var(--pas-3); }

/* Les chiffres d'une colonne doivent s'aligner. */
table, time, code, .num { font-variant-numeric: var(--chiffres); }
code, kbd, samp { font-family: var(--police-mono); font-size: var(--t-mono); }

label { display: block; margin: var(--pas-4) 0 var(--pas-1);
        font-weight: var(--gras-fort); font-size: var(--t-s); color: var(--encre-2); }
input, select, textarea {
  font: inherit; padding: var(--pas-2) var(--pas-3); border: 1px solid var(--trait-champ);
  border-radius: var(--rayon-s); width: 100%; max-width: 26rem; background: var(--papier);
  color: var(--encre);
}
/* **iOS zoome au focus sous 16 px.** C'est la faute qui rend « utilisable au doigt »
   faux sans qu'on comprenne pourquoi. */
input, select, textarea, button { font-size: max(var(--t-champ), var(--t-base)); }
input:focus, select:focus, textarea:focus {
  outline: 0; border-color: var(--accent); box-shadow: var(--anneau);
}
/* Une case à cocher n'est pas un champ de saisie : sans cette règle, le `width: 100%` du
   dessus l'étire sur toute la ligne. */
input[type="checkbox"], input[type="radio"] { width: auto; max-width: none; }
/* **La flèche vient d'un fichier, et non d'une URI `data:`**, que la politique de contenu
   refuse. Le fichier change avec le thème : c'est le jeton qui le désigne. */
select {
  appearance: none; padding-right: var(--pas-6);
  background-image: var(--chevron);
  background-repeat: no-repeat; background-position: right var(--pas-3) center;
}
/* **Deux sélecteurs pour une seule apparence.** « Déposer un fichier » est une
   navigation, donc un `<a>` : en faire un `<button>` casserait le clic du milieu et
   l'annonce du lecteur d'écran. La classe lui donne la forme sans lui retirer sa nature. */
button, .bouton {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--pas-2);
  font: inherit; font-weight: var(--gras-fort); padding: 0 var(--pas-4);
  border: 1px solid var(--action); border-radius: var(--rayon-s);
  background: var(--action); color: var(--sur-action); cursor: pointer; box-shadow: var(--ombre-1);
  min-height: var(--cible-doigt);
  transition: background-color .12s ease-out, border-color .12s ease-out;
}
button:hover, .bouton:hover {
  background: var(--action-survol); border-color: var(--action-survol);
  color: var(--sur-action); text-decoration: none;
}
/* **Le trait plein porte l'information, le halo l'adoucit.** Le halo seul est l'accent à
   15 % : sous les 3:1 que la règle 1.4.11 exige d'un indicateur de focus. */
button:focus-visible, .bouton:focus-visible, a:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; box-shadow: var(--anneau);
}
button:disabled { opacity: .55; cursor: not-allowed; }
/* Le bouton secondaire : papier bordé. Deux boutons pleins côte à côte ne disent plus
   lequel est l'action principale. */
.bouton--doux, button.doux {
  background: var(--papier); color: var(--encre); border-color: var(--trait-champ);
  font-weight: var(--gras-moyen);
}
.bouton--doux:hover, button.doux:hover { background: var(--ligne-survol); color: var(--encre);
                                         border-color: var(--trait-champ); }
button .signe, .bouton .signe { width: 15px; height: 15px; flex: none; }

/* **Les tables sont le cœur du produit, et elles se filettent au lieu de s'encadrer.**
   L'en-tête est un aplat crème en casse normale : les petites capitales grises espacées
   se lisaient « tableau de bord de démonstration », pas « registre ». */
table { border-collapse: collapse; width: 100%; background: var(--papier); font-size: var(--t-s); }
th, td { text-align: left; padding: var(--pas-2) var(--pas-3); height: 2.5rem;
         border-bottom: 1px solid var(--trait-doux); vertical-align: middle; }
th { font-size: var(--t-xs); font-weight: var(--gras-fort); color: var(--encre);
     background: var(--tete-table); border-bottom: 0; white-space: nowrap; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--ligne-survol); }
/* Une table clé/valeur n'est pas une table de liste : ses en-têtes sont des libellés. */
th[scope="row"] { width: 38%; font-size: var(--t-s); font-weight: var(--gras-moyen);
                  color: var(--encre-2); background: transparent;
                  border-bottom: 1px solid var(--trait-doux); white-space: normal; }

/* ═══ 3. LA COQUILLE ══════════════════════════════════════════════════════════════════
 * **Une barre en haut, et non plus un rail à gauche** (phase D5). Le rail prenait
 * 15,5 rem sur chaque écran pour une navigation qu'on consulte une fois par écran ; la
 * barre les rend aux tables. Elle porte trois choses : la marque, les gestes du travail
 * (traiter, gérer), et le menu du compte — ce qu'on ouvre rarement se replie.
 *
 * **Le menu du compte est un `<details>`, et c'est voulu** : il s'ouvre sans une ligne de
 * JavaScript, au clavier comme à la souris, et la politique de contenu n'a rien à
 * autoriser. Ce qu'il ne fait pas : se refermer d'un clic ailleurs dans la page — on le
 * referme en cliquant à nouveau dessus, ou en changeant d'écran.
 */
.app { min-height: 100vh; display: flex; flex-direction: column; }

.barre {
  display: flex; align-items: center; gap: var(--pas-5);
  min-height: var(--hauteur-barre); padding: 0 var(--pas-6);
  background: var(--papier); border-bottom: 1px solid var(--trait);
  position: sticky; top: 0; z-index: 10;
}
.barre .marque {
  display: flex; align-items: center; gap: var(--pas-2); flex: none;
  color: var(--encre); font-size: var(--t-m); font-weight: var(--gras-titre); letter-spacing: var(--chasse-titre);
}
.barre .marque:hover { text-decoration: none; color: var(--encre); }
.barre .marque img { width: 22px; height: 22px; flex: none; }

.barre__nav { display: flex; align-items: stretch; align-self: stretch; min-width: 0; }
.barre__groupe { display: flex; align-items: stretch; }
/* Deux groupes se séparent d'un filet court, pas d'un titre : le titre existe pour le
   lecteur d'écran, qui en a besoin pour savoir où il est. */
.barre__groupe + .barre__groupe::before {
  content: ""; width: 1px; background: var(--trait); margin: var(--pas-4) var(--pas-2);
}
.barre__nav a {
  display: flex; align-items: center; gap: var(--pas-2); padding: 0 var(--pas-3);
  color: var(--encre-2); font-size: var(--t-s); font-weight: var(--gras-moyen);
  white-space: nowrap; border-block: 2px solid transparent;
}
.barre__nav a:hover { color: var(--encre); text-decoration: none; background: var(--ligne-survol); }
/* L'écran courant : un filet carmin sous l'onglet, et l'encre pleine. Le filet est ce qui
   se voit ; le poids est ce qui se lit quand la couleur ne se distingue pas. */
.barre__nav a[aria-current="page"] {
  color: var(--encre); font-weight: var(--gras-fort); border-bottom-color: var(--accent);
}
.barre__nav .signe { display: none; }

.barre__compte { margin-left: auto; position: relative; flex: none; }
.barre__compte > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--pas-2);
  min-height: var(--cible-dense); padding: 0 var(--pas-3);
  border: 1px solid var(--trait-champ); border-radius: var(--rayon-s);
  font-size: var(--t-s); font-weight: var(--gras-moyen); color: var(--encre);
}
.barre__compte > summary::-webkit-details-marker { display: none; }
/* La flèche est le même fichier que celle des menus déroulants, pour la même raison. */
.barre__compte > summary::after {
  content: ""; width: 12px; height: 12px; background: var(--chevron) no-repeat center / contain;
}
.barre__compte[open] > summary { background: var(--tete-table); }
/* **Sur un écran du menu, la barre dit encore où l'on est** : l'entrée courante est
   cachée dans le `<details>` fermé, et sans cette règle aucun onglet n'était marqué. */
.barre__compte--courant > summary { border-color: var(--accent); font-weight: var(--gras-fort); }
.menu {
  position: absolute; right: 0; top: calc(100% + var(--pas-1)); min-width: 15rem;
  display: flex; flex-direction: column; padding: var(--pas-1) 0;
  background: var(--papier); border: 1px solid var(--trait); border-radius: var(--rayon-m);
  box-shadow: var(--ombre-2);
}
.menu a, .menu .lien {
  display: flex; align-items: center; gap: var(--pas-2); padding: var(--pas-2) var(--pas-4);
  color: var(--encre); font-size: var(--t-s); font-weight: var(--gras-moyen);
  min-height: var(--cible-dense); text-decoration: none; width: 100%; justify-content: flex-start;
}
.menu a:hover, .menu .lien:hover { background: var(--ligne-survol); color: var(--encre); text-decoration: none; }
.menu a[aria-current="page"] { background: var(--tete-table); font-weight: var(--gras-fort); }
.menu .signe { width: 15px; height: 15px; flex: none; color: var(--attenue); }
.menu form { margin: var(--pas-1) 0 0; padding-top: var(--pas-1); border-top: 1px solid var(--trait-doux); }

.zone { display: flex; flex-direction: column; min-width: 0; flex: 1; }
main { padding: var(--pas-5) var(--pas-6) var(--pas-7);
       max-width: var(--largeur-contenu); width: 100%; margin: 0; }

/* **Le lien d'évitement.** Visible au clavier seulement, et il vise un `<div>` : `<main>`
   doit rester sans attribut, un témoin découpe le HTML dessus. La même classe cache aussi
   ce qui n'existe que pour le lecteur d'écran — les titres des groupes de la barre. */
.evitement { position: absolute; left: -9999px; }
.evitement:focus { left: var(--pas-4); top: var(--pas-4); z-index: 20; position: fixed;
                   background: var(--papier); color: var(--encre); padding: var(--pas-3) var(--pas-4);
                   border-radius: var(--rayon-s); box-shadow: var(--ombre-2); }

@media (max-width: 60rem) {
  /* **Deux rangs, et aucun tiroir.** La marque et le compte en haut ; les gestes du
     travail dessous, en une rangée qui défile. Un tiroir demanderait un mécanisme que
     rien ne justifie, et cacherait ce qu'on cherche. */
  .barre { flex-wrap: wrap; padding: 0 0 0 var(--pas-4); gap: 0; row-gap: 0; }
  .barre .marque { min-height: var(--hauteur-barre); }
  .barre__compte { margin-right: var(--pas-3); }
  .barre__compte > summary { min-height: var(--cible-doigt); }
  .barre__nav { order: 3; flex-basis: 100%; overflow-x: auto; overscroll-behavior-x: contain;
                border-top: 1px solid var(--trait-doux); margin-left: calc(-1 * var(--pas-4)); }
  .barre__nav a { min-height: var(--cible-doigt); }
  .barre__groupe + .barre__groupe::before { margin: var(--pas-3) var(--pas-1); }
  main { padding: var(--pas-4) var(--pas-4) var(--pas-6); }
}

/* ═══ 4. COMPOSANTS ═══════════════════════════════════════════════════════════════════ */

/* **La bande de titre.** Le titre de l'écran, sa ligne de contexte, et les gestes
   principaux à droite. Plus de bande blanche détachée : la page entière est blanche, et
   c'est l'alignement qui fait l'assise. */
.entete-page { padding: var(--pas-5) var(--pas-6) 0; display: flex; align-items: flex-end;
               gap: var(--pas-4); flex-wrap: wrap; max-width: var(--largeur-contenu); }
.entete-page h1 { margin: 0; font-size: var(--t-xl); }
.entete-page .sous { color: var(--attenue); font-size: var(--t-s); margin: var(--pas-1) 0 0; }
.entete-page .actions { margin-left: auto; display: flex; gap: var(--pas-2);
                        flex-wrap: wrap; align-items: center; }
.entete-page .actions .bouton, .entete-page .actions button { min-height: var(--cible-dense); }
.entete-page .actions label, .entete-page .actions select { margin: 0; }
.entete-page .actions select { max-width: 14rem; }
/* Le menu d'un filtre a la hauteur du bouton qui l'envoie : son corps reste à 16 px — iOS
   zoome en dessous —, c'est la marge intérieure qui cède. */
.entete-page .actions select { min-height: var(--cible-dense); padding-block: 0; }
/* **Collée à sa règle, et après elle** : placée dans la requête de la coquille, plus
   haut, elle perdait contre la règle générale écrite plus bas, et le titre d'un écran de
   téléphone restait décalé de seize pixels par rapport à son contenu. */
@media (max-width: 60rem) {
  .entete-page { padding: var(--pas-4) var(--pas-4) 0; align-items: flex-start; }
  .entete-page .actions { margin-left: 0; }
}

/* **La carte est un cadre, plus une carte.** Un filet d'un pixel, des coins de 4 px, et
   aucune ombre : les jetons `--ombre-1` et `--rayon-l` le disent, cette règle ne fait que
   les lire. Le nom de classe reste, parce que la plupart des écrans l'emploient et qu'il
   dit encore le rôle : un bloc de contenu qui a un titre. */
.carte { background: var(--papier); border: 1px solid var(--trait);
         border-radius: var(--rayon-l); box-shadow: var(--ombre-1);
         margin-bottom: var(--pas-5); padding: var(--pas-5); }
.carte--table { padding: 0; overflow: hidden; }
.carte > h2:first-child, .carte > h3:first-child {
  margin: calc(-1 * var(--pas-5)) calc(-1 * var(--pas-5)) var(--pas-5);
  padding: var(--pas-3) var(--pas-4);
  border-bottom: 1px solid var(--trait-doux);
  font-size: var(--t-m);
}
.carte--table > h2:first-child, .carte--table > h3:first-child {
  margin: 0; padding: var(--pas-3) var(--pas-4);
}
.carte__entete { display: flex; align-items: center; gap: var(--pas-3);
                 padding: var(--pas-3) var(--pas-4); border-bottom: 1px solid var(--trait-doux); }
.carte__entete h2, .carte__entete h3 { margin: 0; font-size: var(--t-m); }
.carte__entete .actions { margin-left: auto; display: flex; gap: var(--pas-3);
                          align-items: center; }
/* Le compte, en chiffre sobre à côté du titre. Le nombre n'est pas un état. */
.carte__compte { color: var(--attenue); font-size: var(--t-s); font-weight: var(--gras-moyen); }
.carte__corps { padding: var(--pas-5); }
.carte__corps h2, .carte__corps h3 {
  margin: var(--pas-6) 0 var(--pas-3); padding-top: var(--pas-4);
  border-top: 1px solid var(--trait-doux); font-size: var(--t-m);
}
.carte__corps > :first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.carte__corps > :last-child { margin-bottom: 0; }

/* **La jauge en dix marches, et elles se voient.** La part consommée se calcule en
   dixièmes (`_dixiemes`) parce qu'une largeur ne peut pas s'écrire en ligne — la politique
   de contenu refuse `style="…"`. Au lieu de le cacher derrière une barre continue qui
   avancerait par sauts de 10 %, la jauge le montre : dix segments, et on les compte. */
.jauge { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 2px;
         margin-top: var(--pas-3); }
.jauge span { height: 4px; background: var(--jauge-fond); }
.jauge .plein { background: var(--jauge); }
.jauge--chaud .plein { background: var(--jauge-chaud); }

/* Les pastilles d'état. **Fond, trait et texte** — jamais la couleur seule. */
.pastille { display: inline-flex; align-items: center; gap: var(--pas-1);
            font-size: var(--t-xs); font-weight: var(--gras-fort); line-height: 1.4;
            padding: 1px var(--pas-2); border-radius: var(--rayon-pastille);
            border: 1px solid var(--trait); background: var(--pastille-fond); color: var(--encre-2);
            white-space: nowrap; }
.pastille .signe { width: 12px; height: 12px; flex: none; }
/* **Une pastille qui porte une phrase, et non une étiquette** : sous `nowrap`, l'objet
   d'une alerte devenait une gélule de soixante caractères et la table défilait. */
.pastille--libre { white-space: normal; text-align: left; align-items: flex-start; }
.pastille--libre .signe { margin-top: 2px; }
.pastille--a-verifier, .pastille--avis {
  color: var(--avis); background: var(--avis-fond); border-color: var(--avis-trait); }
.pastille--valide, .pastille--actif, .pastille--soldee {
  color: var(--succes); background: var(--succes-fond); border-color: var(--succes-trait); }
.pastille--exporte, .pastille--depose, .pastille--essai, .pastille--info {
  color: var(--info); background: var(--info-fond); border-color: var(--info-trait); }
/* **`resilie` est le pire état du produit** : il annonce la purge à trente jours et la
   fin de la fenêtre d'export (décision 53). Sans règle, il retomberait sur la pastille
   neutre — la couleur du « rien à signaler ». */
.pastille--echec, .pastille--refuse, .pastille--en-defaut, .pastille--suspendu,
.pastille--echue, .pastille--resilie, .pastille--alerte {
  color: var(--alerte); background: var(--alerte-fond); border-color: var(--alerte-trait); }

/* **Une commande écartée n'est ni un succès ni un incident** : pastille neutre, barrée —
   elle a été retirée de la file, pas effacée (décision 167). */
.pastille--ecarte { color: var(--attenue); text-decoration: line-through; }

/* Le repli « ce n'est pas une commande », sous le formulaire de correction. */
.ecart { margin-top: var(--pas-6); padding-top: var(--pas-4); border-top: 1px solid var(--trait-doux); }
.ecart > summary { cursor: pointer; color: var(--encre-2); font-size: var(--t-s);
                   font-weight: var(--gras-moyen); }
.ecart > summary:hover { color: var(--encre); }
.ecart p { margin: var(--pas-3) 0; max-width: 42rem; font-size: var(--t-s); }
.avis form { margin: var(--pas-3) 0 0; }

/* Messages. **Les trois noms de classe sont figés** : trois témoins cherchent
   `<p class="erreur">` et `<p class="message">` littéralement dans le HTML rendu.
   Le signe est dessiné par `::before` : la phrase reste un `<p>` d'un seul tenant. */
.message, .erreur, .avis {
  display: flex; align-items: flex-start; gap: var(--pas-3);
  padding: var(--pas-3) var(--pas-4); border-radius: var(--rayon-m);
  border: 1px solid; font-size: var(--t-s); margin-bottom: var(--pas-4);
}
/* **Le signe n'existe que si le masque existe** : sans ce `@supports`, un navigateur qui
   ignore `mask-image` peindrait un carré plein devant chaque message. */
@supports (mask-image: url("signe-avis.svg")) or (-webkit-mask-image: url("signe-avis.svg")) {
  .message::before, .erreur::before, .avis::before {
    content: ""; flex: none; width: 17px; height: 17px; margin-top: 1px;
    background: currentColor;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    -webkit-mask-size: contain; mask-size: contain;
    -webkit-mask-image: url("signe-avis.svg");
    mask-image: url("signe-avis.svg");
  }
  .message::before {
    -webkit-mask-image: url("signe-succes.svg");
    mask-image: url("signe-succes.svg");
  }
}
.message { background: var(--succes-fond); border-color: var(--succes-trait); color: var(--succes); }
.erreur { background: var(--alerte-fond); border-color: var(--alerte-trait); color: var(--alerte); }
.avis { background: var(--avis-fond); border-color: var(--avis-trait); color: var(--avis); }

/* **L'avis de lecture seule vit au-dessus de la barre**, parce qu'il vaut pour l'écran
   entier : il prend la forme d'un bandeau pleine largeur. */
body > .avis { margin: 0; border-radius: 0; border-width: 0 0 1px; }

/* Le bandeau d'usurpation : pleine largeur, au-dessus de tout, impossible à manquer. */
.bandeau {
  background: var(--alerte); color: var(--sur-alerte); padding: var(--pas-3) var(--pas-4);
  display: flex; gap: var(--pas-4); align-items: center; justify-content: space-between;
  flex-wrap: wrap; font-weight: var(--gras-fort); font-size: var(--t-s);
}
.bandeau form { margin: 0; }
.bandeau button { background: var(--sur-alerte); color: var(--alerte);
                  border-color: var(--sur-alerte); box-shadow: none; }
.bandeau button:hover { background: var(--sur-alerte-survol); color: var(--alerte); }
/* **L'anneau de focus ordinaire est carmin, et le bandeau aussi** : posé dessus, il
   mesurait 1:1 et le seul bouton du bandeau n'avait plus d'indicateur de focus. Il prend
   ici la couleur de ce qu'on écrit sur le bandeau, dont le contraste est mesuré. */
.bandeau button:focus-visible { outline-color: var(--sur-alerte); box-shadow: none; }

/* **Un état vide dit quoi faire ensuite**, à gauche, en texte : un rond coloré au milieu
   du blanc était la signature du gabarit générique. Le signe reste, petit, en encre. */
.etat-vide { padding: var(--pas-6) var(--pas-4); display: grid;
             grid-template-columns: auto minmax(0, 1fr); column-gap: var(--pas-3);
             align-items: start; }
.etat-vide__signe { width: 22px; height: 22px; color: var(--attenue); grid-row: span 2; }
.etat-vide__signe svg { width: 18px; height: 18px; }
.etat-vide strong { display: block; font-size: var(--t-base); font-weight: var(--gras-fort); }
.etat-vide p { margin: var(--pas-1) 0 0; color: var(--attenue); font-size: var(--t-s); }

/* Un tableau dense ne se coupe pas sur petit écran : il défile. `role` et `tabindex` le
   rendent atteignable au clavier. */
.tableau-defilant { overflow-x: auto; overscroll-behavior-x: contain; }
.tableau-defilant:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* **Sans barre, pas de coquille.** Un écran hors session — second facteur, refus — se
   centre et se borne, sinon il traverse un écran de vingt-quatre pouces. La page de refus
   en fait partie même en session : `rendre_le_refus` passe `acces=None` à dessein. */
.app--nue main { max-width: 34rem; margin: var(--pas-7) auto; }
/* L'accueil, lui, prend l'écran entier : deux colonnes pleine hauteur. */
.app--pleine main { max-width: none; margin: 0; padding: 0;
                     min-height: 100vh; display: flex; flex-direction: column; }
/* **Le message vit avant le contenu, et la connexion prend toute la hauteur** : l'erreur
   et le champ à corriger restent visibles ensemble. */
.app--pleine #contenu { display: flex; flex-direction: column; flex: 1; }
.app--pleine #contenu > .message,
.app--pleine #contenu > .erreur,
.app--pleine #contenu > .avis { margin: var(--pas-4) var(--pas-4) 0; }
.app--pleine .accueil { flex: 1; min-height: 0; }

/* **Un formulaire hors session n'est pas dans une carte.** */
.accueil__boite, .boite-seule { width: 100%; max-width: 23rem; }
.boite-seule { margin: 0 auto; }
.accueil__boite h1, .boite-seule h1 { margin-bottom: var(--pas-1); }
.accueil__boite form > p:last-child,
.boite-seule form > p:last-child { margin: var(--pas-5) 0 0; }
.accueil__boite button, .boite-seule button { width: 100%; }
.aide { color: var(--attenue); font-size: var(--t-s); margin: var(--pas-1) 0 0; }

/* L'écran de connexion : la promesse à gauche, sur l'encadré sombre ; le formulaire à
   droite. **Aplat, sans dégradé** — le voile d'accent de D1 et D2 est parti avec la
   sarcelle. */
.accueil { display: grid; grid-template-columns: 1fr 1fr; min-height: 100vh; }
.accueil__promesse {
  background: var(--encadre); color: var(--encadre-vif); padding: var(--pas-7);
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--pas-6);
}
.accueil__promesse .marque { display: flex; align-items: center; gap: var(--pas-3);
                             font-size: var(--t-m); font-weight: var(--gras-fort); margin: 0; }
.accueil__promesse h2 { font-size: var(--t-accroche); font-weight: var(--gras-titre);
                        letter-spacing: var(--chasse-chiffre); line-height: 1.24; max-width: 13em;
                        margin: 0 0 var(--pas-4); color: var(--encadre-vif); }
.accueil__promesse > div > p { color: var(--encadre-texte); font-size: var(--t-m);
                               line-height: 1.6; max-width: 28em; margin: 0; }
.accueil__points { list-style: none; padding: 0; margin: var(--pas-5) 0 0;
                   color: var(--encadre-texte); font-size: var(--t-base); }
.accueil__points li { position: relative; padding: var(--pas-1) 0 var(--pas-1) var(--pas-5); }
/* La coche est **décorative** : la phrase se suffit. */
.accueil__points li::before {
  content: ""; position: absolute; left: 0; top: .72em; width: 11px; height: 6px;
  border-left: 2px solid var(--encadre-accent); border-bottom: 2px solid var(--encadre-accent);
  transform: rotate(-45deg);
}
.accueil__pied { color: var(--encadre-titre); font-size: var(--t-s); margin: 0; max-width: 34em;
                 padding-top: var(--pas-4); border-top: 1px solid var(--encadre-trait); }
.accueil__formulaire { display: grid; place-items: center; padding: var(--pas-6); background: var(--papier); }
.accueil__formulaire .sous { color: var(--attenue); font-size: var(--t-s);
                             margin: 0 0 var(--pas-6); }

@media (max-width: 60rem) {
  /* On vient se connecter, pas lire : la colonne de promesse disparaît. */
  .accueil { grid-template-columns: 1fr; min-height: auto; }
  .accueil__promesse { display: none; }
  .accueil__formulaire { padding: var(--pas-5) var(--pas-4); min-height: 100vh; }
}

/* Un lien qui se présente comme un bouton discret : même boîte, même hauteur de cible. */
a.discret { display: inline-flex; align-items: center; padding: 0 var(--pas-4);
            border: 1px solid var(--trait-champ); border-radius: var(--rayon-s);
            color: var(--encre); font-weight: var(--gras-moyen);
            font-size: var(--t-base); min-height: var(--cible-doigt); }
a.discret:hover { background: var(--ligne-survol); color: var(--encre); text-decoration: none; }

/* ═══ 5. LE TABLEAU DE BORD ═══════════════════════════════════════════════════════════
 * **Une bande de chiffres, puis le travail lui-même.** L'écran d'avant montrait quatre
 * cartes de consommation et reléguait « à relire » au rang de chiffre parmi d'autres ;
 * celui-ci pose la file devant les yeux, parce que c'est elle qui décide de la journée.
 */
.bande { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
         border: 1px solid var(--trait); border-radius: var(--rayon-m);
         margin-bottom: var(--pas-6); background: var(--papier); }
.bande__case { padding: var(--pas-4) var(--pas-5); border-left: 1px solid var(--trait); min-width: 0; }
.bande__case:first-child { border-left: 0; }
/* La case qui demande un geste se détache par son fond, pas par une couleur criarde. */
.bande__case--vive { background: var(--ligne-survol); }
.bande__libelle { color: var(--attenue); font-size: var(--t-s); display: flex; align-items: center;
                  gap: var(--pas-2); }
.bande__libelle .signe { width: 14px; height: 14px; flex: none; }
.bande__valeur { display: flex; align-items: baseline; gap: var(--pas-2); margin-top: var(--pas-1);
                 flex-wrap: wrap; }
.bande__valeur strong { font-size: var(--t-xxl); font-weight: var(--gras-titre);
                        letter-spacing: var(--chasse-chiffre); line-height: 1.15; }
.bande__case--vive .bande__valeur strong { color: var(--accent); }
.bande__detail { font-size: var(--t-s); color: var(--encre-2); margin: var(--pas-1) 0 0; }
.bande__detail--attenue { color: var(--attenue); }

@media (max-width: 60rem) {
  /* Deux par rang, et les filets se redistribuent : celui de gauche disparaît en tête de
     rang, et un filet haut sépare les rangs. */
  .bande { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bande__case { padding: var(--pas-3) var(--pas-4); }
  .bande__case:nth-child(odd) { border-left: 0; }
  .bande__case:nth-child(n + 3) { border-top: 1px solid var(--trait); }
}

/* Deux colonnes : la file à gauche, ce qui s'est passé à droite. */
.colonnes { display: grid; grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr);
            gap: var(--pas-6); align-items: start; }
@media (max-width: 60rem) {
  .colonnes { grid-template-columns: minmax(0, 1fr); }
}

/* **Une section se titre d'un filet d'encre**, c'est la seule « boîte » du registre. */
.section__entete { display: flex; align-items: baseline; gap: var(--pas-3);
                   padding-bottom: var(--pas-2); border-bottom: 1px solid var(--encre);
                   margin-bottom: 0; }
.section__entete h2 { margin: 0; font-size: var(--t-m); }
.section__entete .compte { color: var(--attenue); font-size: var(--t-s); }
.section__entete .suite { margin-left: auto; font-size: var(--t-s); font-weight: var(--gras-moyen); }
.section__pied { display: flex; flex-wrap: wrap; gap: var(--pas-3); align-items: baseline;
                 padding: var(--pas-3) 0; color: var(--attenue); font-size: var(--t-s); }
.section__pied a { margin-left: auto; font-weight: var(--gras-moyen); }
/* La table d'une section touche le filet : son en-tête crème fait la transition. */
.section table { border-top: 0; }

/* Le repère d'une ligne qui porte des signalements : un carré plein, avant le nombre. La
   forme dit « quelque chose », le nombre dit combien. */
.repere { display: inline-flex; align-items: center; gap: var(--pas-2); color: var(--alerte);
          font-weight: var(--gras-fort); }
.repere::before { content: ""; width: 8px; height: 8px; background: currentColor; flex: none; }
.repere--calme { color: var(--attenue); font-weight: var(--gras-moyen); }
.repere--calme::before { background: transparent; }

/* **Le fil des alertes.** Une alerte est une phrase : elle se lit en liste, pas en table
   à trois colonnes dont la première se coupait en cinq lignes. Le rang se dit trois fois
   — la forme du repère, sa couleur, et le mot. */
.fil { list-style: none; margin: 0; padding: 0; }
.fil li { display: grid; grid-template-columns: 10px minmax(0, 1fr); gap: var(--pas-3);
          padding: var(--pas-3) 0; border-bottom: 1px solid var(--trait-doux); }
.fil li::before { content: ""; width: 8px; height: 8px; margin-top: .45em;
                  border: 1.5px solid currentColor; }
.fil .fil--alerte { color: var(--alerte); }
.fil .fil--alerte::before { background: currentColor; }
.fil .fil--avis { color: var(--avis); }
.fil .fil--info { color: var(--info); }
.fil__objet { color: var(--encre); font-size: var(--t-s); }
.fil__meta { color: var(--attenue); font-size: var(--t-xs); margin-top: var(--pas-1); }
.fil .etat-vide { padding: var(--pas-4) 0; }

/* ═══ 6. UTILITAIRES ══════════════════════════════════════════════════════════════════ */
.attenue { color: var(--attenue); }
/* Le second niveau d'une cellule : d'où vient un code, quand une chose a été faite. */
td > .attenue, td > .secondaire { font-size: var(--t-xs); }
.secondaire { display: block; color: var(--attenue); font-size: var(--t-xs); }
/* Une référence est ce qu'on cherche des yeux dans une file : chasse fixe, encre pleine. */
.ref { font-family: var(--police-mono); font-weight: var(--gras-moyen); color: var(--encre); }
a.ref:hover { color: var(--accent); }
.mono { font-family: var(--police-mono); font-size: var(--t-mono); }
.discret { background: var(--papier); color: var(--encre); border-color: var(--trait-champ);
           font-weight: var(--gras-moyen); }
.discret:hover { background: var(--ligne-survol); color: var(--encre); border-color: var(--trait-champ); }
.lien { background: none; border: 0; color: var(--lien); text-decoration: underline;
        cursor: pointer; padding: 0; box-shadow: none; min-height: 0; font-weight: var(--gras-moyen); }
.lien:hover { background: none; color: var(--accent-fonce); border: 0; }
.enligne { display: inline; }
.liste { width: 100%; }
.alerte { color: var(--alerte); }
code.secret { display: block; background: var(--tete-table); border: 1px solid var(--trait);
              border-radius: var(--rayon-s); padding: var(--pas-3); font-family: var(--police-mono);
              font-size: var(--t-s); word-break: break-all; max-width: 26rem; }

/* ═══ 7. IMPRESSION ═══════════════════════════════════════════════════════════════════ */
@media print {
  .barre, .entete-page .actions, .evitement { display: none; }
  .app { display: block; }
  body { background: var(--papier); }
  .carte { box-shadow: none; border-color: var(--trait); break-inside: avoid; }
  /* **Un navigateur n'imprime pas les fonds par défaut** : le bandeau d'usurpation
     deviendrait blanc sur blanc et perdrait « vous regardez le compte de X ». */
  .bandeau { background: var(--papier); color: var(--alerte);
             border: 2px solid var(--alerte); }
  .bandeau button { display: none; }
}

/* ═══ 8. LE DÉTAIL D'UNE COMMANDE ═════════════════════════════════════════════════════
 * **Une bande d'entête, puis un tableau des lignes** (phase D11). La page empilait chaque
 * champ dans une colonne unique — quatre-vingt-six champs pour une commande de huit lignes,
 * une vingtaine d'écrans de haut, et deux lignes qu'on ne pouvait pas comparer. Le
 * commanditaire l'a trouvée « moche », et il avait raison.
 */

/* La bande : trois rangées d'une grille, qui se replient seules sur un écran étroit. */
.bande-commande__rangee { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
                          gap: var(--pas-3) var(--pas-4); margin-bottom: var(--pas-4); }
.bande-commande__rangee:last-child { margin-bottom: 0; }
.rubrique label, .rubrique__titre { display: block; margin: 0 0 var(--pas-1); font-size: var(--t-xs);
                                    font-weight: var(--gras-fort); color: var(--encre-2); }
.rubrique--large { grid-column: span 2; }
.rubrique__valeur { margin: 0; padding: var(--pas-2) 0; }

/* Une case : le champ, et ce que le document écrivait quand la valeur en diffère. */
.case { display: block; }
.case input { max-width: none; }
.case__brute { display: block; margin-top: var(--pas-1); font-size: var(--t-xs); color: var(--avis); }
/* L'origine, sous la case et non dans une infobulle. Discrète pour une valeur lue — c'est
   le cas ordinaire —, marquée pour une valeur qu'un opérateur a posée : un filet à gauche
   dans une couleur de texte, assez contrastée pour être vue sans survol. */
.case__origine { display: block; margin-top: var(--pas-1); font-size: var(--t-xs); color: var(--attenue); }
.case--saisie input { border-left: 3px solid var(--info); }
.case--saisie .case__origine { color: var(--info); font-weight: var(--gras-moyen); }
/* Dans le tableau, l'origine d'une valeur lue se tait : huit fois « lu dans le PDF » par
   ligne noyaient les valeurs. Le lecteur d'écran la lit toujours. */
.lignes-commande .case:not(.case--saisie) .case__origine { position: absolute; left: -9999px; }

/* Le tableau des lignes : une rangée par ligne, une case par champ. Il défile seul en
   largeur, la page non. */
.lignes-commande th, .lignes-commande td { height: auto; }
.lignes-commande td.cellule { padding: var(--pas-1) var(--pas-2); vertical-align: top; }
.lignes-commande td.cellule input { padding: var(--pas-1) var(--pas-2); min-width: 6rem; }
/* **La désignation prend la place, les nombres la cèdent.** Sans largeur déclarée, le
   tableau partageait l'espace à parts égales : des quantités de trois chiffres dans des
   cases de quinze, et une désignation tronquée. Un `width: 1%` réduit une colonne à son
   contenu minimal ; la désignation récupère le reste. */
.lignes-commande td.num, .lignes-commande th.num { width: 1%; }
.lignes-commande td.num input { text-align: right; min-width: 5.5rem; width: 5.5rem; }
.lignes-commande td.cellule--designation { width: 40%; }
.lignes-commande td.cellule--designation input { min-width: 14rem; }
.lignes-commande td.cellule--code-barres input,
.lignes-commande td.cellule--reference-emetteur input { min-width: 11rem; }
.lignes-commande td.code-article { white-space: nowrap; vertical-align: top; }
.lignes-commande td.code-article .attenue { display: block; font-size: var(--t-xs); }

/* Les colonnes vides partout : repliées, et dépliées par la case à cocher qui les précède. */
.colonne-vide { display: none; }
.bascule-colonnes:checked ~ .tableau-defilant .colonne-vide { display: table-cell; }
.bascule-colonnes { margin: var(--pas-3) var(--pas-2) var(--pas-3) var(--pas-4); vertical-align: middle; }
.bascule-colonnes__libelle { display: inline; margin: 0; font-weight: var(--gras-moyen);
                             font-size: var(--t-s); color: var(--encre-2); }
.bascule-colonnes__nom { margin-left: var(--pas-2); color: var(--attenue); }

.somme-des-lignes { margin: 0; padding: var(--pas-3) var(--pas-4); text-align: right;
                    border-top: 1px solid var(--trait-doux); font-size: var(--t-s); }

/* Les gestes, collés en bas de l'écran : « Valider » ne doit jamais être à vingt écrans. */
.barre-gestes { position: sticky; bottom: 0; z-index: 5; display: flex; align-items: center;
                gap: var(--pas-4); flex-wrap: wrap; padding: var(--pas-3) var(--pas-4);
                background: var(--papier); border-top: 1px solid var(--trait); }
.barre-gestes > p { margin: 0 auto 0 0; }
.barre-gestes .ecart { margin: 0; padding: 0; border: 0; }
/* La case qui a le focus ne doit pas finir sous la barre collée. */
:root:has(.barre-gestes) { scroll-padding-bottom: 6rem; }

@media (max-width: 60rem) {
  .rubrique--large { grid-column: auto; }
  /* Sur un téléphone, la barre collée mangeait près de la moitié de l'écran : la phrase
     d'explication part, les deux gestes tiennent sur une ligne. */
  .barre-gestes { flex-wrap: nowrap; gap: var(--pas-3); padding: var(--pas-2) var(--pas-3); }
  .barre-gestes > p { display: none; }
  .barre-gestes .ecart { margin-right: auto; }
}
