/*
 * Cockpit — feuille de style unique.
 *
 * Coque en tableau de bord : barre latérale à gauche, contenu à droite. Sous
 * 1000 px, la barre devient un tiroir et le contenu occupe toute la largeur —
 * le portail client se consulte au téléphone.
 *
 * Aucune police distante, aucun CDN, aucune icône en police : tout est local,
 * la page s'affiche à l'identique même si le réseau du client filtre les
 * domaines tiers.
 *
 * C'est un outil de travail : la réussite se mesure à la vitesse de lecture,
 * pas à la décoration. Cinq principes tiennent toute la feuille —
 *
 *   1. Une strate = une taille ET une graisse ET une couleur. Deux niveaux qui
 *      ne diffèrent que par la teinte se lisent comme un seul.
 *   2. Une action primaire par écran, impossible à confondre avec le reste.
 *   3. Les surfaces sont hiérarchisées : une carte de saisie, une carte de
 *      contenu et un bloc d'appoint ne peuvent pas avoir le même aspect.
 *   4. La navigation est en encre bleue profonde, le travail sur fond clair.
 *      Le regard sait toujours de quel côté il est.
 *   5. Ce qui annonce quelque chose (message, bandeau) est un aplat saturé à
 *      texte blanc — pas un cadre pâle de plus au milieu des cadres pâles.
 */

/* ================================================================== */
/* Police de titrage                                                   */
/* ================================================================== */

/*
 * Nunito — SIL Open Font License 1.1, texte de licence dans public/fonts/OFL.txt.
 * Sous-ensemble latin, fichier variable unique (39 ko) qui porte toutes les
 * graisses de 400 à 1000 : une requête, aucune graisse synthétisée.
 *
 * Auto-hébergée dans public/fonts/, servie en `'self'` : la CSP interdit tout
 * domaine tiers, et le réseau d'un client peut filtrer n'importe quoi. Aucun
 * @import, aucune URL distante — l'URL est relative à cette feuille, donc
 * l'application reste déplaçable sous un préfixe.
 *
 * Elle ne sert QU'AU TITRAGE : géométrique, terminaisons arrondies, très
 * grasse — c'est le caractère de la marque. Le corps de texte reste sur la pile
 * système, celle que le système d'exploitation a réglée pour la lecture longue,
 * qui est ce que l'on fait toute la journée dans un outil de travail.
 *
 * `font-display: swap` : le titre s'affiche immédiatement dans la police
 * système puis bascule. Une page qui attend sa police est une page blanche.
 */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 400 1000;
  font-display: swap;
  src: url('../fonts/nunito-latin-variable.woff2') format('woff2');
  /* Latin de base, plus ce dont le français et les montants ont besoin : Œ/œ,
     l'euro, et le vrai signe moins U+2212 (« −50 % », pas un trait d'union). */
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ================================================================== */
/* Jetons                                                              */
/* ================================================================== */

:root {
  /*
   * Accent de marque, et seul accent de l'application. Le réglage d'agence
   * « couleur_accent » n'a qu'une variable à poser (`--accent` sur <html>) :
   * toutes les dérivées se recalculent par `color-mix`. Chaque dérivée porte
   * d'abord sa valeur bleue littérale — c'est elle que reçoivent les
   * navigateurs sans `color-mix`, et c'est aussi ce qui garantit qu'un accent
   * changé ne laisse jamais un halo bleu sur un bouton vert.
   */
  --accent: #0000ff;

  --accent-sombre: #0000cc;
  --accent-sombre: color-mix(in oklab, var(--accent) 84%, #05050f);

  --accent-clair: #ececff;
  --accent-clair: color-mix(in oklab, var(--accent) 9%, #ffffff);

  --accent-bord: #b9b9ff;
  --accent-bord: color-mix(in oklab, var(--accent) 30%, #ffffff);

  /* Encre lisible sur `--accent-clair` : titres de carte de saisie, bandeau
     d'information, libellé de navigation actif. */
  --accent-encre: #00006b;
  --accent-encre: color-mix(in oklab, var(--accent) 62%, #000000);

  /* Voile : fond d'un état actif. Anneau : halo de focus — il doit se VOIR,
     l'ancien voile à 7 % ne se voyait pas. */
  --accent-voile: rgba(0, 0, 255, 0.09);
  --accent-voile: color-mix(in srgb, var(--accent) 9%, transparent);
  --accent-anneau: rgba(0, 0, 255, 0.3);
  --accent-anneau: color-mix(in srgb, var(--accent) 32%, transparent);
  --accent-ombre: rgba(0, 0, 255, 0.24);
  --accent-ombre: color-mix(in srgb, var(--accent) 26%, transparent);

  /*
   * Accent PROFOND : l'accent ramené à une encre, pour les aplats saturés qui
   * portent du texte blanc (bandeau d'information, en-tête de carte pleine).
   * Toujours plus sombre que `--accent` lui-même — donc un accent clair choisi
   * dans les réglages n'y sera jamais moins lisible qu'il ne l'est déjà sur un
   * bouton primaire, qui pose depuis toujours du blanc sur `--accent` pur.
   * Bleu par défaut : #031e96, soit 12,9:1 sur blanc.
   */
  --accent-profond: #031e96;
  --accent-profond: color-mix(in oklab, var(--accent) 56%, #0c1122);

  /*
   * Encre de NUIT : le fond de la navigation. Dérivée de l'accent pour que le
   * réglage de couleur pilote toute la coque, mais tirée vers un bleu-gris très
   * sombre pour rester une encre et non un aplat de marque — 30 % d'accent
   * suffisent à en donner la teinte. Bleu par défaut : #0e2771, soit 13,6:1
   * avec du blanc ; le pire accent imaginable (un jaune pur) reste à 6,9:1.
   *
   * Les états ne sont pas d'autres bleus mais des voiles blancs : ils se
   * composent correctement au-dessus de N'IMPORTE QUELLE nuit, quelle que soit
   * la couleur réglée par l'agence.
   */
  --nuit: #0e2771;
  --nuit: color-mix(in oklab, var(--accent) 30%, #16203a);
  --nuit-appui: rgba(255, 255, 255, 0.09);
  --nuit-actif: rgba(255, 255, 255, 0.15);
  --nuit-bord: rgba(255, 255, 255, 0.13);
  --nuit-encre: #ffffff;
  --nuit-encre-douce: rgba(255, 255, 255, 0.84);
  --nuit-encre-legere: rgba(255, 255, 255, 0.72);

  /* Une seule famille de gris, très légèrement bleutée pour s'accorder à
     l'accent. Trois niveaux d'encre, franchement écartés : deux gris voisins
     ne font pas une hiérarchie. */
  --encre: #12121b;
  --encre-douce: #3b3b4d;
  --encre-legere: #64647a;

  --fond: #ffffff;
  --fond-tete: #f7f7fb;
  --fond-zebre: #fafafd;
  --fond-doux: #f4f4f8;
  --fond-appuye: #eaeaf1;

  --bord: #e4e4ed;
  --bord-appuye: #d3d3e0;
  /* Bord des champs et des boutons de second rang : 3:1 sur blanc, seuil
     WCAG 1.4.11 pour la limite d'un composant. En dessous, un champ vide sur
     une carte blanche n'existe visuellement pas. */
  --bord-fort: #8e8ea6;

  --succes: #0a7d4b;
  --succes-fond: #e7f6ef;
  --succes-bord: #bce3d0;
  --alerte: #8a5b06;
  --alerte-fond: #fdf4dc;
  --alerte-bord: #ecd7a0;
  --danger: #b3261e;
  --danger-fond: #fdeceb;
  --danger-bord: #f2c6c3;

  /*
   * Trois rayons, et la hiérarchie est celle du contenant : une carte est plus
   * douce que ce qu'elle contient, sinon les arrondis se marchent dessus dans
   * les angles. Généreux — c'est le trait le plus reconnaissable de l'identité
   * — mais pas au point de manger la place utile d'un tableau dense.
   */
  --rayon: 18px;
  --rayon-sm: 11px;
  --rayon-xs: 8px;

  /*
   * Interlettrage des micro-capitales. Un sur-titre en capitales serré se lit
   * comme un mot ; espacé, il se lit comme une étiquette et cesse de concurrencer
   * le titre qu'il annonce.
   */
  --caps: 0.14em;

  /*
   * Quatre niveaux d'élévation, et l'élévation se mérite : plat pour les blocs
   * d'appoint, `--ombre-1` pour le courant, `--ombre-2` pour ce qui appelle un
   * geste, `--ombre-3` pour ce qui flotte au-dessus de la page. Les ombres sont
   * teintées de l'encre, jamais du noir pur, sinon elles grisent le fond bleuté.
   */
  --ombre-1: 0 1px 2px rgba(18, 18, 45, 0.05);
  --ombre-2: 0 1px 2px rgba(18, 18, 45, 0.05), 0 4px 12px rgba(18, 18, 45, 0.07);
  --ombre-3: 0 2px 6px rgba(18, 18, 45, 0.07), 0 16px 40px rgba(18, 18, 45, 0.14);

  /*
   * Corps de texte : pile système, avec ses variantes optiques quand la
   * plateforme en a une. Aucune police distante : la CSP l'interdit, et le
   * réseau d'un client peut filtrer n'importe quoi.
   *
   * Titrage : Nunito, auto-hébergée (voir le @font-face plus haut), avec la
   * pile système derrière — si le fichier manque, la page reste juste, elle
   * perd seulement son caractère.
   */
  --police: system-ui, -apple-system, 'Segoe UI Variable Text', 'Segoe UI',
    Inter, Roboto, 'Helvetica Neue', Arial, sans-serif;
  --police-titre: 'Nunito', 'Segoe UI Variable Display', system-ui,
    -apple-system, 'Segoe UI', Inter, Roboto, 'Helvetica Neue', Arial,
    sans-serif;
  --police-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas,
    monospace;

  /*
   * Échelle typographique. Les graisses sont limitées à 400 / 500 / 600 / 700 :
   * les valeurs intermédiaires (520, 560, 620, 640) que portait l'ancienne
   * feuille n'existent dans aucune police système non variable — le navigateur
   * les arrondissait, et il ne restait en pratique que deux graisses.
   */
  --t-etiquette: 0.6875rem; /* 11 px — micro-étiquettes en capitales */
  --t-meta: 0.75rem; /* 12 px — horodatages, mentions */
  --t-aide: 0.8125rem; /* 13 px — aides de champ */
  --t-libelle: 0.875rem; /* 14 px — étiquettes de champ, boutons */
  --t-corps: 0.9375rem; /* 15 px — texte courant */
  --t-appui: 1rem; /* 16 px */
  --t-section: 1.0625rem; /* 17 px — titres de carte */
  --t-sous: 1.375rem; /* 22 px — h2 de page */
  --t-page: 1.875rem; /* 30 px — h1 */
  --t-nombre: 2.25rem; /* 36 px — indicateurs */

  --espace-1: 4px;
  --espace-2: 8px;
  --espace-3: 12px;
  --espace-4: 16px;
  --espace-5: 20px;
  --espace-6: 24px;
  --espace-8: 32px;
  --espace-10: 40px;

  /* Au-delà, l'œil perd la ligne suivante. */
  --mesure: 68ch;

  --barre-largeur: 268px;
  --largeur-max: 1120px;
}

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

body {
  margin: 0;
  font-family: var(--police);
  font-size: var(--t-corps);
  line-height: 1.55;
  color: var(--encre);
  background: var(--fond-doux);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ================================================================== */
/* Hiérarchie du texte                                                 */
/* ================================================================== */

h1,
h2,
h3,
h4 {
  margin: 0 0 0.5em;
  font-family: var(--police-titre);
  line-height: 1.2;
  color: var(--encre);
  /* Un titre coupé sur un mot orphelin se relit deux fois. */
  text-wrap: balance;
}

/*
 * Les titres sont franchement gras : c'est le trait du visuel de marque, et
 * c'est aussi ce qui les détache d'un corps de texte système à 400. La graisse
 * remplace la taille — un h1 de 30 px en 800 domine une page sans avoir à
 * prendre la moitié de l'écran, ce qu'un outil de travail ne peut pas offrir.
 */
h1 {
  font-size: var(--t-page);
  font-weight: 800;
  letter-spacing: -0.025em;
}

h2 {
  font-size: var(--t-sous);
  font-weight: 700;
  letter-spacing: -0.018em;
}

h3 {
  font-size: var(--t-section);
  font-weight: 700;
  letter-spacing: -0.012em;
}

h4 {
  font-size: var(--t-libelle);
  font-weight: 700;
  letter-spacing: -0.005em;
}

/*
 * Sur-titre : la ligne de petites capitales très espacées qui annonce un titre,
 * comme le « PARTICULIERS · REPASSAGE & LINGE » du visuel de marque. Utilitaire
 * plutôt que composant : elle se pose sur n'importe quoi, au-dessus de
 * n'importe quel titre.
 */
.sur-titre {
  display: block;
  margin: 0 0 6px;
  font-size: var(--t-etiquette);
  font-weight: 700;
  letter-spacing: var(--caps);
  text-transform: uppercase;
  color: var(--encre-legere);
}

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

strong,
b {
  font-weight: 600;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
a:hover {
  color: var(--accent-sombre);
  text-decoration-thickness: 2px;
}

/*
 * Un seul anneau de focus dans toute l'application, et il suit le rayon du
 * composant : `outline` respecte `border-radius`. L'ancienne règle imposait un
 * rayon de 3 px, qui coupait les coins des boutons et des cartes.
 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.icone {
  flex: none;
  vertical-align: middle;
}

/* Premier élément focusable : évite de traverser toute la navigation au
   clavier avant d'atteindre le contenu. */
.saut-contenu {
  position: absolute;
  left: -9999px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--fond);
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-sm);
  box-shadow: var(--ombre-3);
  font-weight: 600;
  text-decoration: none;
}
.saut-contenu:focus {
  left: 12px;
  top: 12px;
}

/* ================================================================== */
/* Marque                                                              */
/* ================================================================== */

.marque {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--encre);
  text-decoration: none;
  font-weight: 400;
}

.marque__fusee {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 9px;
  color: var(--accent);
  background: var(--accent-clair);
  box-shadow: inset 0 0 0 1px var(--accent-bord);
}

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

.marque__nom {
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: var(--t-appui);
  letter-spacing: -0.028em;
  line-height: 1.15;
}

/* Signature discrète : présente, jamais concurrente du nom du produit. */
.marque__signature {
  font-size: var(--t-meta);
  line-height: 1.3;
  color: var(--encre-legere);
  letter-spacing: 0.005em;
}

.marque--centre {
  justify-content: center;
}

.marque--grand .marque__fusee {
  width: 44px;
  height: 44px;
  border-radius: 12px;
}
.marque--grand .marque__nom {
  font-size: 1.35rem;
}
.marque--grand .marque__signature {
  font-size: var(--t-aide);
}

/*
 * La marque posée sur une nuit — barre latérale, tiroir, barre du téléphone,
 * page de connexion. Écrite une seule fois pour les quatre : `partials/logo.ejs`
 * est le même bloc partout, il n'a pas à connaître son fond.
 *
 * Le médaillon devient un voile blanc plutôt qu'un aplat d'accent : sur une
 * nuit dérivée de l'accent, un médaillon à l'accent disparaîtrait dans le fond.
 */
.barre .marque,
.barre-mobile .marque,
.page-centree__marque .marque {
  color: var(--nuit-encre);
}
.barre .marque__fusee,
.barre-mobile .marque__fusee,
.page-centree__marque .marque__fusee {
  background: var(--nuit-actif);
  color: var(--nuit-encre);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.24);
}
.barre .marque__signature,
.barre-mobile .marque__signature,
.page-centree__marque .marque__signature {
  color: var(--nuit-encre-legere);
}

/*
 * Sur une nuit dérivée de l'accent, un anneau de focus À l'accent ne se voit
 * pas : il est de la même famille que son fond. Toute zone sombre reprend donc
 * le blanc. Sans cette règle, la navigation au clavier devient invisible dès
 * qu'on entre dans la barre.
 */
.barre :focus-visible,
.barre-mobile :focus-visible,
.page-centree__marque :focus-visible {
  outline-color: var(--nuit-encre);
}

/* ================================================================== */
/* Coque de l'application                                              */
/* ================================================================== */

.appli {
  min-height: 100vh;
}

.appli__contenu {
  padding: var(--espace-5) 0 72px;
}

.enveloppe {
  width: 100%;
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: 0 var(--espace-4);
}

/* Pages atteintes par jeton (questionnaire, synthèse) : pas de navigation. */
.public__entete {
  background: var(--fond);
  border-bottom: 1px solid var(--bord);
  padding: 14px 0;
}
.page {
  padding: var(--espace-6) 0 72px;
}

/* Ligne de contact du pied de page, posée par `partials/pied.ejs` : présente
   partout, y compris sur les pages à jeton où c'est le seul recours. */
.pied-contact {
  margin: var(--espace-10) 0 0;
  padding-top: var(--espace-4);
  border-top: 1px solid var(--bord);
  font-size: var(--t-aide);
  color: var(--encre-legere);
}
.pied-contact a {
  color: var(--encre-legere);
}
.pied-contact a:hover {
  color: var(--accent);
}

/*
 * Les liens légaux, sous le contact et plus discrets que lui : ils doivent être
 * atteignables partout, pas attirer l'œil. Pas de second filet au-dessus — le
 * bloc de pied n'en a qu'un, sur le contact.
 */
.pied-legal {
  margin: var(--espace-2) 0 0;
  font-size: var(--t-aide);
  color: var(--encre-legere);
  display: flex;
  flex-wrap: wrap;
  gap: var(--espace-2);
}
.pied-legal a {
  color: var(--encre-legere);
}
.pied-legal a:hover {
  color: var(--accent);
}
/* Sur les écrans d'authentification, tout est centré : ces liens aussi. La
   teinte, elle, vient de `.page-centree > * > p`, qui l'emporte en
   spécificité — sur le champ de nuit, un gris de page serait illisible. */
.page-centree .pied-legal {
  justify-content: center;
}

/* ---------- Barre supérieure, petit écran uniquement ---------- */

/*
 * Au téléphone, cette barre EST la navigation : elle prend donc la nuit, comme
 * le tiroir qu'elle ouvre. Une barre claire au-dessus d'un tiroir sombre
 * donnerait deux navigations pour une.
 */
.barre-mobile {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px var(--espace-4);
  background: var(--nuit);
  border-bottom: 1px solid var(--nuit-bord);
}

.barre-mobile__bouton {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: var(--rayon-sm);
  background: transparent;
  color: var(--nuit-encre);
  cursor: pointer;
  transition: background-color 0.16s ease, color 0.16s ease;
}
.barre-mobile__bouton:hover {
  background: var(--nuit-actif);
  color: var(--nuit-encre);
}
.barre-mobile__bouton:active {
  transform: translateY(1px);
}

.voile {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(18, 18, 45, 0.45);
}
body.barre-ouverte {
  overflow: hidden;
}

/* ================================================================== */
/* Barre latérale                                                      */
/* ================================================================== */

/*
 * La barre est en encre de nuit, le contenu reste clair. C'est la séparation la
 * plus utile de toute la feuille : à n'importe quel moment, sans lire un mot,
 * on sait si l'on regarde là où l'on va ou là où l'on travaille.
 */
.barre {
  display: flex;
  flex-direction: column;
  background: var(--nuit);
  color: var(--nuit-encre-douce);

  /* Petit écran : tiroir hors champ, à gauche. */
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 60;
  width: min(304px, 86vw);
  box-shadow: var(--ombre-3);
  transform: translateX(-101%);
  transition: transform 0.22s ease;
}
.barre.est-ouverte {
  transform: none;
}

.barre__entete {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: var(--espace-4) 18px;
  border-bottom: 1px solid var(--nuit-bord);
}

.barre__fermer {
  margin-left: auto;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: none;
  border-radius: var(--rayon-xs);
  background: transparent;
  color: var(--nuit-encre-legere);
  cursor: pointer;
}
.barre__fermer:hover {
  background: var(--nuit-actif);
  color: var(--nuit-encre);
}

.barre__nav {
  flex: 1;
  overflow-y: auto;
  padding: var(--espace-4) 12px var(--espace-5);
  overscroll-behavior: contain;
}

/* Un trait entre les groupes : sans lui, un titre de groupe se lit comme un
   item de plus, en plus petit. */
.barre__groupe + .barre__groupe {
  margin-top: var(--espace-5);
  padding-top: 18px;
  border-top: 1px solid var(--nuit-bord);
}

.barre__titre {
  margin: 0 0 var(--espace-2);
  padding: 0 10px;
  font-size: var(--t-etiquette);
  font-weight: 700;
  letter-spacing: var(--caps);
  text-transform: uppercase;
  color: var(--nuit-encre-legere);
}

.barre__liste,
.barre__sous-liste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.barre__ligne {
  display: flex;
  align-items: center;
  gap: 2px;
}

.barre__lien {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--rayon-sm);
  color: var(--nuit-encre-douce);
  text-decoration: none;
  font-size: var(--t-libelle);
  font-weight: 500;
  transition: background-color 0.16s ease, color 0.16s ease;
}
.barre__lien > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.barre__lien:hover {
  background: var(--nuit-appui);
  color: var(--nuit-encre);
}
.barre__lien .icone {
  color: rgba(255, 255, 255, 0.66);
}
.barre__lien:hover .icone {
  color: var(--nuit-encre);
}

/*
 * L'item actif est marqué trois fois : un repère de forme collé au bord du
 * panneau, un fond, une graisse. Le repère et le texte passent au blanc plein —
 * sur une nuit dérivée de l'accent, un marquage À l'accent serait de la même
 * famille que son fond, donc invisible.
 */
.barre__lien.est-actif {
  background: var(--nuit-actif);
  color: var(--nuit-encre);
  font-weight: 700;
}
.barre__lien.est-actif::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 5px;
  bottom: 5px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--nuit-encre);
}
.barre__lien.est-actif .icone {
  color: var(--nuit-encre);
}

.barre__chevron {
  display: grid;
  place-items: center;
  width: 28px;
  height: 32px;
  flex: none;
  border: none;
  border-radius: var(--rayon-xs);
  background: transparent;
  color: var(--nuit-encre-legere);
  cursor: pointer;
  transition: transform 0.16s ease, background-color 0.16s ease;
}
.barre__chevron:hover {
  background: var(--nuit-appui);
  color: var(--nuit-encre);
}

.barre__item.est-ouvert > .barre__ligne > .barre__chevron,
.barre__item.est-ouverte-manuel > .barre__ligne > .barre__chevron {
  transform: rotate(90deg);
}

/* Replié par défaut : la branche de la page courante est dépliée par le
   serveur, les autres s'ouvrent au chevron. */
.barre__sous-liste {
  display: none;
  margin: 2px 0 var(--espace-1);
}
.barre__item.est-ouvert > .barre__sous-liste,
.barre__item.est-ouverte-manuel > .barre__sous-liste {
  display: block;
}

.barre__sous-lien {
  position: relative;
  display: block;
  /* Aligné sous le libellé du parent, pas sous son icône. */
  padding: 6px 10px 6px 40px;
  border-radius: var(--rayon-xs);
  color: var(--nuit-encre-legere);
  text-decoration: none;
  font-size: var(--t-aide);
  font-weight: 400;
  transition: background-color 0.16s ease, color 0.16s ease;
}
.barre__sous-lien:hover {
  background: var(--nuit-appui);
  color: var(--nuit-encre);
}
.barre__sous-lien.est-actif {
  color: var(--nuit-encre);
  font-weight: 700;
  background: var(--nuit-actif);
}
.barre__sous-lien.est-actif::before {
  content: '';
  position: absolute;
  left: 26px;
  top: 8px;
  bottom: 8px;
  width: 2px;
  border-radius: 2px;
  background: var(--nuit-encre);
}

/*
 * Le pied empile trois choses — libellé, bloc compte, lien d'aide. Le bloc
 * compte est encadré : sans cela, il se lisait comme un quatrième groupe de
 * navigation, et son titre comme un titre de groupe de plus.
 */
/* Un cran plus sombre que le panneau : le pied s'assoit, il ne flotte pas. */
.barre__pied {
  display: flex;
  flex-direction: column;
  gap: var(--espace-2);
  padding: var(--espace-3) 14px;
  border-top: 1px solid var(--nuit-bord);
  background: rgba(0, 0, 0, 0.18);
}

.barre__pied-titre {
  margin: 0;
  font-size: var(--t-etiquette);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--caps);
  color: var(--nuit-encre-legere);
}

.barre__pied-ligne {
  display: flex;
  align-items: center;
  gap: var(--espace-2);
  padding: 6px;
  background: var(--nuit-appui);
  border: 1px solid var(--nuit-bord);
  border-radius: var(--rayon-sm);
}

.barre__aide {
  font-size: var(--t-aide);
  font-weight: 500;
  color: var(--nuit-encre-legere);
  text-decoration: none;
}
.barre__aide:hover {
  color: var(--nuit-encre);
  text-decoration: underline;
}
/* La page d'aide passe avant l'e-mail : elle répond tout de suite, et sans
   déranger personne. Elle est donc la plus lisible des deux. */
.barre__aide--page {
  font-weight: 600;
  color: var(--nuit-encre);
}

.barre__compte {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px;
  margin: -4px;
  border-radius: var(--rayon-xs);
  text-decoration: none;
  color: inherit;
  font-weight: 400;
  transition: background-color 0.16s ease;
}
.barre__compte:hover {
  background: var(--nuit-appui);
}

/* Pastille blanche, initiale à la couleur de la nuit : le seul aplat clair de
   toute la barre, donc le point que l'œil trouve sans le chercher. */
.barre__avatar {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 50%;
  background: var(--nuit-encre);
  color: var(--nuit);
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: var(--t-libelle);
}

.barre__identite {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.barre__identite-nom {
  font-size: var(--t-libelle);
  font-weight: 600;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.barre__identite-role {
  font-size: var(--t-meta);
  color: var(--nuit-encre-legere);
}

.barre__sortie {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: none;
  border: 1px solid transparent;
  border-radius: var(--rayon-xs);
  background: transparent;
  color: var(--nuit-encre-legere);
  cursor: pointer;
  transition: background-color 0.16s ease, color 0.16s ease;
}
/* Rempli de sa propre teinte au survol : sur une nuit, un fond rouge PÂLE
   ferait une tache claire là où il faut un avertissement. */
.barre__sortie:hover {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

/* ================================================================== */
/* En-tête de page                                                     */
/* ================================================================== */

/* Le titre de page est séparé du contenu par un trait : il cesse d'être la
   première ligne d'une liste de blocs, il devient l'en-tête de l'écran. */
.titre-page {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--espace-3);
  margin-bottom: var(--espace-6);
  padding-bottom: 18px;
  border-bottom: 1px solid var(--bord);
}
/* Le bloc titre est élastique : sans cela, sa largeur maximale poussait les
   boutons d'action sur une deuxième ligne alors que la place existait. */
.titre-page > :first-child {
  flex: 1 1 260px;
  min-width: 0;
}
.titre-page h1 {
  margin: 0;
}
.titre-page__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espace-2);
  margin-left: auto;
  align-items: center;
}
.titre-page__sous {
  width: 100%;
  max-width: var(--mesure);
  margin: 6px 0 0;
  color: var(--encre-legere);
  font-size: var(--t-libelle);
  font-variant-numeric: tabular-nums;
}
.titre-page__sous strong {
  color: var(--encre-douce);
}

/*
 * Le fil d'ariane occupe exactement la place du sur-titre du visuel de marque —
 * la ligne de petites capitales très espacées posée au-dessus du grand titre.
 * Il en prend donc la forme : il dit d'où l'on vient, et il annonce le titre au
 * lieu de faire une ligne de texte gris de plus.
 */
.fil-ariane {
  margin-bottom: var(--espace-2);
  font-size: var(--t-etiquette);
  font-weight: 700;
  /* Un cran sous les micro-capitales : un fil d'ariane porte des noms propres
     entiers, qui à 0,14em passeraient sur trois lignes au téléphone. */
  letter-spacing: 0.1em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--encre-legere);
}
.fil-ariane a {
  color: var(--encre-legere);
  font-weight: 700;
  text-decoration: none;
}
.fil-ariane a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* ================================================================== */
/* Cartes et surfaces                                                  */
/* ================================================================== */

/*
 * Trois rangs de surface, et le rang se lit avant d'avoir lu le titre :
 *
 *   .carte                  — contenu courant : blanche, bord fin, ombre basse
 *   .carte--formulaire      — on y saisit : élévation + en-tête à l'accent
 *   .carte--discret         — appoint (colonne latérale, aide) : plat, teinté
 *
 * L'ancienne feuille n'en avait qu'un : bord + ombre + blanc pour tout, ce qui
 * laissait l'œil sans point d'entrée sur une page dense.
 */
.carte {
  background: var(--fond);
  border: 1px solid var(--bord);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-1);
  /* Avec 18 px de rayon, un tableau posé à même la carte dépasserait des
     angles : `clip` les lui fait suivre. `clip` et non `hidden` — il n'ouvre
     pas de contexte de défilement, donc rien ne se met à défiler tout seul. */
  overflow: clip;
}

.carte__entete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 13px 18px;
  background: var(--fond-tete);
  border-bottom: 1px solid var(--bord);
  border-radius: var(--rayon) var(--rayon) 0 0;
}
.carte__entete h2,
.carte__entete h3 {
  margin: 0;
  font-size: var(--t-section);
  font-weight: 700;
  letter-spacing: -0.012em;
  font-variant-numeric: tabular-nums;
}
.carte__entete .btn {
  margin-left: auto;
}

.carte__corps {
  padding: 18px;
}
/* La mesure ne s'applique qu'au texte courant d'une carte : ni aux tableaux,
   ni aux lignes de formulaire, qui ont leur propre largeur utile. */
.carte__corps > p {
  max-width: var(--mesure);
}
.carte__corps > *:last-child {
  margin-bottom: 0;
}

.carte__pied {
  padding: var(--espace-3) 18px;
  border-top: 1px solid var(--bord);
  background: var(--fond-doux);
  border-radius: 0 0 var(--rayon) var(--rayon);
}

/* Carte de saisie : l'en-tête prend l'accent, le bloc prend de l'élévation.
   On voit du premier coup d'œil où l'on agit et où l'on lit. */
.carte--formulaire {
  border-color: var(--bord-appuye);
  box-shadow: var(--ombre-2);
}
.carte--formulaire > .carte__entete {
  background: var(--accent-clair);
  border-bottom-color: var(--accent-bord);
}
.carte--formulaire > .carte__entete h2,
.carte--formulaire > .carte__entete h3 {
  color: var(--accent-encre);
}

/* Bloc d'appoint : posé sur la page, pas au-dessus. Aucune ombre — l'élévation
   se mérite. */
.carte--discret {
  background: var(--fond-doux);
  border-color: var(--bord);
  box-shadow: none;
}
.carte--discret > .carte__entete {
  background: transparent;
  border-bottom-color: var(--bord-appuye);
}
.carte--discret > .carte__entete h2,
.carte--discret > .carte__entete h3 {
  font-size: var(--t-libelle);
  font-weight: 700;
  letter-spacing: var(--caps);
  text-transform: uppercase;
  color: var(--encre-legere);
}
.carte--discret > .carte__pied {
  background: transparent;
}

/* Carte principale d'un écran : un cran d'élévation de plus. */
.carte--principal {
  box-shadow: var(--ombre-2);
  border-color: var(--bord-appuye);
}

/* Une carte qui est un lien doit se comporter comme un lien : sans état de
   survol, son immobilité se lit comme une panne. */
a.carte {
  display: block;
  color: inherit;
  text-decoration: none;
  font-weight: 400;
  transition: border-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease;
}
a.carte:hover {
  border-color: var(--accent-bord);
  box-shadow: var(--ombre-2);
  transform: translateY(-1px);
}
a.carte:active {
  transform: none;
  box-shadow: var(--ombre-1);
}

/* ---------- Sections repliables ---------- */

/*
 * Le bouton est ajouté par `interface.js` sur toute carte qui porte un
 * en-tête : sans JavaScript, les sections restent simplement ouvertes.
 * Il se place AVANT le titre, ce qui laisse intacte la règle qui pousse les
 * boutons d'action de l'en-tête vers la droite.
 */
.carte__repli {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: none;
  margin-left: -4px;
  border: none;
  border-radius: var(--rayon-xs);
  background: transparent;
  color: var(--encre-legere);
  cursor: pointer;
  transition: background-color 0.16s ease, color 0.16s ease;
}
.carte__repli:hover {
  background: var(--fond-appuye);
  color: var(--encre);
}

/* Chevron vers le bas quand la section est ouverte, vers la droite repliée. */
.carte__repli .icone {
  transform: rotate(90deg);
  transition: transform 0.18s ease;
}
.carte.est-repliee .carte__repli .icone {
  transform: none;
}

/* Le repli est mémorisé d'une visite à l'autre : sans cette mention, une carte
   repliée se lit comme une carte vide, et l'on cherche ailleurs son contenu. */
.carte__etat-repli {
  display: none;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--fond-appuye);
  color: var(--encre-legere);
  font-size: var(--t-meta);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.carte.est-repliee .carte__etat-repli {
  display: inline-block;
}

/* Tout sauf l'en-tête disparaît : robuste quel que soit le contenu de la
   carte — corps, pied, ou tableau posé directement dessous. */
.carte.est-repliee > *:not(.carte__entete) {
  display: none;
}
.carte.est-repliee > .carte__entete {
  border-bottom: none;
  border-radius: var(--rayon);
}

/* ---------- Grilles ---------- */

.grille {
  display: grid;
  gap: var(--espace-4);
  grid-template-columns: 1fr;
}
/*
 * Un élément de grille vaut `min-width: auto` par défaut : il refuse de
 * descendre sous la largeur minimale de son contenu, et c'est la piste qui
 * s'élargit. Sur la fiche projet au téléphone, une ligne d'étape (champ +
 * menu + date + case + bouton) suffisait à pousser toute la page à 598 px de
 * large dans un écran de 375. Mesuré, pas supposé.
 */
.grille > * {
  min-width: 0;
}
.grille--2 {
  grid-template-columns: 1fr;
}
.grille--3 {
  grid-template-columns: 1fr;
}
.grille--auto {
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}

/* ================================================================== */
/* Boutons                                                             */
/* ================================================================== */

/*
 * Trois rangs, séparés par la taille ET le remplissage ET la graisse — jamais
 * par la seule teinte :
 *
 *   .btn--primaire   fond accent plein, plus grand, ombre teintée
 *   .btn             contour net sur fond gris clair — second rang
 *   .btn--discret    texte seul — action mineure
 *   .btn--danger     rempli de sa propre teinte, reconnaissable sans hurler
 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-sm);
  background: var(--fond-doux);
  color: var(--encre-douce);
  font: inherit;
  font-size: var(--t-libelle);
  font-weight: 600;
  line-height: 1.3;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.16s ease, border-color 0.16s ease,
    color 0.16s ease, box-shadow 0.16s ease, transform 0.08s ease;
}
.btn:hover {
  background: var(--fond-appuye);
  border-color: var(--encre-legere);
  color: var(--encre);
}
.btn:active {
  transform: translateY(1px);
}
.btn[disabled],
.btn[aria-disabled='true'] {
  opacity: 0.5;
  pointer-events: none;
}

.btn--primaire {
  /* Plus grand et plus gras que le second rang : la hiérarchie tient même
     quand le lecteur ne distingue pas les couleurs. */
  padding: 10px 18px;
  font-size: var(--t-corps);
  font-weight: 600;
  letter-spacing: 0.005em;
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  box-shadow: 0 1px 2px var(--accent-ombre), 0 4px 10px var(--accent-ombre);
}
.btn--primaire:hover {
  background: var(--accent-sombre);
  border-color: var(--accent-sombre);
  color: #fff;
  box-shadow: 0 2px 4px var(--accent-ombre), 0 8px 18px var(--accent-ombre);
}
.btn--primaire:active {
  transform: translateY(1px);
  box-shadow: 0 1px 2px var(--accent-ombre);
}
/* Un anneau accent sur un fond accent ne se voit pas. */
.btn--primaire:focus-visible {
  outline-color: var(--encre);
}

.btn--danger {
  background: var(--danger-fond);
  border-color: var(--danger-bord);
  color: var(--danger);
}
.btn--danger:hover {
  background: #f9dcda;
  background: color-mix(in oklab, var(--danger) 13%, #ffffff);
  border-color: var(--danger);
  color: var(--danger);
}
.btn--danger:focus-visible {
  outline-color: var(--danger);
}

/* Troisième rang : une action mineure ne prend pas la forme d'un bouton. */
.btn--discret {
  padding-left: 8px;
  padding-right: 8px;
  border-color: transparent;
  background: transparent;
  color: var(--encre-legere);
  font-weight: 500;
}
.btn--discret:hover {
  background: var(--fond-appuye);
  border-color: transparent;
  color: var(--encre);
}

/* Après les variantes : `btn--petit` doit pouvoir recomprimer un primaire. */
.btn--petit {
  padding: 5px 10px;
  font-size: var(--t-aide);
  font-weight: 600;
  letter-spacing: 0;
}
.btn--large {
  width: 100%;
}

/* ================================================================== */
/* Formulaires                                                         */
/* ================================================================== */

/*
 * Un formulaire long se lit par blocs. `.groupe-champs` est ce bloc : un titre
 * en micro-capitales, un trait au-dessus, et une respiration franche entre
 * deux groupes. Sans lui, neuf champs d'affilée sont espacés exactement de la
 * même façon qu'ils appartiennent ou non au même sujet.
 */
.groupe-champs {
  display: grid;
  gap: var(--espace-4);
}
.groupe-champs + .groupe-champs {
  margin-top: var(--espace-6);
  padding-top: var(--espace-5);
  border-top: 1px solid var(--bord);
}
.groupe-champs__titre {
  margin: 0;
  font-size: var(--t-etiquette);
  font-weight: 700;
  letter-spacing: var(--caps);
  text-transform: uppercase;
  color: var(--encre-legere);
}

/* Zone de saisie posée à l'intérieur d'une carte de contenu : ce que l'on
   ajoute se distingue de ce que l'on relit. */
.bloc-saisie {
  padding: var(--espace-4);
  margin-bottom: var(--espace-5);
  background: var(--fond-doux);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-sm);
}
.bloc-saisie > *:last-child {
  margin-bottom: 0;
}
.bloc-saisie .formulaire-actions {
  margin-top: var(--espace-4);
  padding-top: 0;
  border-top: none;
}

.champ {
  margin-bottom: var(--espace-5);
}
/* Dans un conteneur qui gère déjà l'espacement par `gap`, la marge du champ
   doublerait l'écart et casserait le rythme vertical. */
.grille > .champ,
.groupe-champs > .champ,
.rangee > .champ {
  margin-bottom: 0;
}

/* Étiquette : plus petite que le corps, nettement plus grasse et plus sombre
   que l'aide. Trois écarts, pas un seul. */
.champ label,
.etiquette {
  display: block;
  margin-bottom: 5px;
  font-size: var(--t-libelle);
  font-weight: 600;
  letter-spacing: 0.008em;
  color: var(--encre);
}

/* L'aide vient SOUS le champ, plus petite et plus claire que l'étiquette. */
.champ__aide {
  max-width: 62ch;
  margin: 6px 0 0;
  font-size: var(--t-aide);
  line-height: 1.45;
  color: var(--encre-legere);
}

input[type='text'],
input[type='email'],
input[type='password'],
input[type='url'],
input[type='number'],
input[type='date'],
input[type='search'],
input[type='tel'],
input[type='file'],
select,
textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-sm);
  background: var(--fond);
  color: var(--encre);
  font: inherit;
  font-size: var(--t-corps);
  font-variant-numeric: tabular-nums;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}

input:hover:not([disabled]),
select:hover:not([disabled]),
textarea:hover:not([disabled]) {
  border-color: var(--encre-legere);
}

/*
 * Largeurs adaptées au contenu : un champ de trois caractères qui occupe
 * 500 px empêche de lire un formulaire en diagonale. Les types le disent
 * déjà, inutile d'ajouter une classe à chaque vue.
 */
input[type='number'] {
  max-width: 9rem;
}
input[type='date'] {
  max-width: 12rem;
}
input[type='color'] {
  width: 64px;
  height: 40px;
  padding: 3px;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-sm);
  background: var(--fond);
  cursor: pointer;
}

/* Modificateurs pour les champs texte dont la longueur utile est connue
   (code postal, SIRET, montant). */
.champ--court input,
.champ--court select {
  max-width: 11rem;
}
.champ--moyen input,
.champ--moyen select {
  max-width: 20rem;
}

input[type='file'] {
  padding: 6px 8px;
  font-size: var(--t-aide);
  cursor: pointer;
}
input[type='file']::file-selector-button {
  margin-right: 10px;
  padding: 5px 11px;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-xs);
  background: var(--fond-doux);
  color: var(--encre-douce);
  font: inherit;
  font-size: var(--t-aide);
  font-weight: 600;
  cursor: pointer;
}
input[type='file']::file-selector-button:hover {
  background: var(--fond-appuye);
  color: var(--encre);
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-anneau);
}
/* Au clavier, l'anneau seul ne suffit pas : on ajoute le trait plein, qui
   reste visible en contraste élevé et en mode forcé. */
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

textarea {
  min-height: 110px;
  line-height: 1.5;
  resize: vertical;
}

input[type='checkbox'],
input[type='radio'] {
  width: 17px;
  height: 17px;
  accent-color: var(--accent);
  cursor: pointer;
}

.champ--case {
  display: flex;
  align-items: flex-start;
  gap: 9px;
}
.champ--case input {
  width: auto;
  margin-top: 3px;
  flex: none;
}
.champ--case label {
  margin: 0;
  font-size: var(--t-corps);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--encre);
  cursor: pointer;
}

/* ------------------------------------------------------------------ */
/* Aide : déroulé numéroté et glossaire                                */
/* ------------------------------------------------------------------ */

/* Le numéro est l'information : il porte l'ordre, que le texte ne dit pas. */
.deroule {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: deroule;
}
.deroule > li {
  position: relative;
  counter-increment: deroule;
  padding: 0 0 var(--espace-5) 38px;
  font-size: var(--t-corps);
  color: var(--encre-douce);
}
.deroule > li:last-child {
  padding-bottom: 0;
}
.deroule > li::before {
  content: counter(deroule);
  position: absolute;
  top: 1px;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent-voile);
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.deroule__titre {
  display: block;
  margin-bottom: 2px;
  font-weight: 650;
  color: var(--encre);
}

.glossaire + .glossaire {
  margin-top: var(--espace-6);
  padding-top: var(--espace-6);
  border-top: 1px solid var(--bord);
}
.glossaire__titre {
  margin: 0;
  font-size: var(--t-section);
}
.glossaire__intro {
  margin: 2px 0 var(--espace-4);
}

/* Deux colonnes sur large écran, l'étiquette gardant une largeur fixe pour que
   les définitions s'alignent : une pastille par ligne se lit en balayant. */
.glossaire__liste {
  margin: 0;
}
.glossaire__liste > div {
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: 4px var(--espace-4);
  padding: 9px 0;
  border-top: 1px solid var(--bord);
}
.glossaire__liste > div:first-child {
  border-top: 0;
}
.glossaire__liste dt {
  margin: 0;
}
.glossaire__liste dd {
  margin: 0;
  font-size: var(--t-corps);
  color: var(--encre-douce);
}

@media (max-width: 720px) {
  .glossaire__liste > div {
    grid-template-columns: 1fr;
  }
}

/* Champ à deux modes exclusifs : chaque choix est une ligne cliquable entière,
   et non un point de 16 px à viser. Le mode retenu se voit à sa bordure, pas
   seulement au rond coché — un rond seul se repère mal en balayant la page. */
.champ--modes {
  margin: 0;
  padding: 0;
  border: 0;
}
.champ__legende {
  padding: 0;
  margin-bottom: 5px;
  font-size: var(--t-libelle);
  font-weight: 600;
  letter-spacing: 0.008em;
  color: var(--encre);
}

.mode {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0 0 6px;
  padding: 9px 11px;
  border: 1px solid var(--bord);
  border-radius: var(--rayon-sm);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--encre);
  cursor: pointer;
}
.mode:hover {
  border-color: var(--bord-fort);
}
.mode:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-voile);
}
.mode input[type='radio'] {
  width: auto;
  margin-top: 2px;
  flex: none;
}

.mode__corps {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  min-width: 0;
}
.mode__titre {
  font-size: var(--t-corps);
}
.mode__detail {
  display: flex;
  align-items: baseline;
  gap: 5px;
  font-size: var(--t-aide);
  color: var(--encre-legere);
}
/* Le champ chiffré vit dans une ligne de texte : il se dimensionne sur son
   contenu au lieu d'occuper toute la largeur comme les autres saisies. */
.mode__detail input[type='number'] {
  width: 5.5rem;
  padding: 4px 8px;
}

/* Barre d'action : détachée du dernier champ par un trait, sinon elle flotte
   au milieu du formulaire. */
.formulaire-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espace-3);
  align-items: center;
  margin-top: var(--espace-6);
  padding-top: var(--espace-4);
  border-top: 1px solid var(--bord);
}

/* ================================================================== */
/* Messages et pastilles                                               */
/* ================================================================== */

/*
 * CARTE PLEINE. Un message n'est pas un cadre pâle de plus au milieu des cadres
 * pâles : c'est un aplat saturé à texte blanc, arrondi comme une carte. Sur un
 * écran de console dense, c'est la seule chose qui passe devant le reste sans
 * discussion — et c'est le geste que l'on reconnaît du visuel de marque.
 *
 * La sémantique ne bouge pas, seule sa forme change : chaque variante garde
 * exactement la teinte qu'elle avait, portée à l'aplat au lieu du fond pâle.
 * Toutes tiennent le 4,5:1 en blanc — danger 6,5:1, alerte 5,9:1, succès 5,2:1,
 * information 12,9:1 avec le bleu par défaut.
 */
.message {
  padding: 14px 18px;
  border: none;
  border-radius: var(--rayon);
  margin: 0 0 var(--espace-5);
  font-size: var(--t-corps);
  font-weight: 500;
  line-height: 1.5;
  color: #fff;
  box-shadow: var(--ombre-1);
}
.message > *:last-child {
  margin-bottom: 0;
}
.message strong {
  font-weight: 700;
}
/* Les utilitaires de gris ne peuvent pas s'appliquer sur un aplat : ils y
   deviendraient illisibles. Le retrait se fait en opacité, pas en gris. */
.message .muet,
.message .petit.muet {
  /* 0,92 et pas moins : mesuré, 0,86 tombait à 4,3:1 sur l'aplat de succès,
     qui est le plus clair des quatre. */
  color: rgba(255, 255, 255, 0.92);
}
.message a {
  color: currentColor;
  font-weight: 700;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.message a:hover {
  color: currentColor;
}
/* Un anneau à l'accent sur un aplat saturé ne se voit pas. */
.message :focus-visible {
  outline-color: #fff;
}
/* Un bouton posé dans une carte pleine se dessine en creux : un bouton gris
   clair y ferait une tache, un bouton à l'accent s'y noierait. */
.message .btn {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.55);
  color: #fff;
}
.message .btn:hover {
  background: rgba(255, 255, 255, 0.26);
  border-color: #fff;
  color: #fff;
}

/*
 * Sur-titre de carte pleine : les petites capitales très espacées du visuel de
 * marque (« CRÉDIT D'IMPÔT · −50 % »), suivies du corps en graisse normale.
 * Une carte pleine sans sur-titre reste valable — c'est le cas des messages
 * d'une seule phrase.
 */
.message__titre {
  display: block;
  margin-bottom: 2px;
  font-family: var(--police-titre);
  font-size: var(--t-libelle);
  font-weight: 800;
  letter-spacing: var(--caps);
  text-transform: uppercase;
  line-height: 1.3;
}

.message--erreur {
  background: var(--danger);
}
.message--succes {
  background: var(--succes);
}
.message--alerte {
  background: var(--alerte);
}
/* L'information prend l'accent, ramené à son encre : le bleu reste le bleu,
   et il reste lisible quelle que soit la couleur réglée par l'agence. */
.message--info {
  background: var(--accent-profond);
}

/*
 * Pastilles : la teinte ne suffit pas — imprimée en noir et blanc, ou lue par
 * un œil deutéranope, « validé » et « refusé » seraient identiques. Chaque état
 * porte donc aussi une forme (puce pleine ou creuse) et un bord.
 */
.pastille {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 9px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: var(--t-meta);
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  /* La puce est le premier élément flex : sans cela, c'est elle qui donnerait
     sa ligne de base à la pastille posée au fil du texte. */
  vertical-align: middle;
  background: var(--fond-appuye);
  color: var(--encre-douce);
}
.pastille::before {
  content: '';
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: currentColor;
}

.pastille--succes {
  background: var(--succes-fond);
  border-color: var(--succes-bord);
  color: var(--succes);
}
.pastille--alerte {
  background: var(--alerte-fond);
  border-color: var(--alerte-bord);
  color: var(--alerte);
}
/* L'état le plus engageant est le seul en graisse forte, avec un bord plein. */
.pastille--danger {
  background: var(--danger-fond);
  border-color: var(--danger);
  color: var(--danger);
  font-weight: 700;
}
.pastille--accent {
  background: var(--accent-clair);
  border-color: var(--accent-bord);
  color: var(--accent-encre);
}
/* Puce creuse : « rien ne se passe ici », lisible sans la couleur. */
.pastille--neutre {
  background: var(--fond);
  border-color: var(--bord-appuye);
  color: var(--encre-legere);
  font-weight: 500;
}
.pastille--neutre::before {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px currentColor;
}

/*
 * SIGNAL. Une pastille dit un état (« En validation », « Payée ») ; un signal
 * dit qu'un travail attend quelqu'un (« 3 livrables à valider », « sans
 * réponse depuis 12 jours »). Ce sont deux choses différentes, et une liste où
 * elles portent la même forme oblige à lire chaque ligne pour trier.
 *
 * Le signal reprend donc la règle des cartes pleines, en miniature : aplat
 * saturé, texte blanc, aucune puce. C'est le seul aplat saturé d'une liste, et
 * l'œil le trouve avant d'avoir lu un mot. Les trois teintes tiennent le
 * 4,5:1 en blanc — alerte 5,9:1, danger 6,5:1, information 12,9:1 en bleu.
 */
.signal {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--alerte);
  color: #fff;
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.35;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  vertical-align: middle;
}
.signal--danger {
  background: var(--danger);
}
.signal--info {
  background: var(--accent-profond);
}

/* ================================================================== */
/* Filtres visibles                                                    */
/* ================================================================== */

/*
 * Un `<select>` sans étiquette ne s'annonce pas comme un filtre : il faut le
 * déplier pour découvrir qu'il existe, et rien ne dit ce qui est sélectionné.
 * Les statuts deviennent donc des liens GET posés à plat — on voit d'un coup
 * les choix possibles, celui qui est actif, et combien il y en a derrière.
 *
 * Le `<select>` ne subsiste que là où la liste est longue et ouverte (les
 * projets d'une agence), et il porte alors une étiquette visible.
 */
.filtres {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espace-2);
  padding: var(--espace-3) 18px;
  background: var(--fond-tete);
  border-bottom: 1px solid var(--bord);
}
.filtres + .filtres {
  border-top: none;
}

.filtres__titre {
  margin: 0 var(--espace-1) 0 0;
  font-size: var(--t-etiquette);
  font-weight: 700;
  letter-spacing: var(--caps);
  text-transform: uppercase;
  color: var(--encre-legere);
}

/* Le formulaire résiduel (recherche, filtre par projet) vit dans la même
   bande : deux barres de filtres superposées se liraient comme deux outils. */
.filtres__forme {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espace-2);
  min-width: 0;
}
.filtres__forme label {
  display: inline-block;
  margin: 0;
  font-size: var(--t-etiquette);
  font-weight: 700;
  letter-spacing: var(--caps);
  text-transform: uppercase;
  color: var(--encre-legere);
}
/*
 * `width: auto` sur un `<select>` le dimensionne sur sa plus longue option :
 * un nom de projet un peu long suffisait à pousser la page à 500 px de large
 * dans un écran de 375. `min-width: 0` sur un élément flex l'y autorise enfin.
 */
.filtres__forme select,
.filtres__forme input[type='search'] {
  flex: 1 1 160px;
  min-width: 0;
  width: auto;
  max-width: 260px;
  padding: 6px 10px;
  font-size: var(--t-aide);
}

.pilule {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border: 1px solid var(--bord-appuye);
  border-radius: 999px;
  background: var(--fond);
  color: var(--encre-douce);
  font-size: var(--t-aide);
  font-weight: 600;
  line-height: 1.35;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.16s ease, border-color 0.16s ease,
    color 0.16s ease;
}
.pilule:hover {
  background: var(--fond-appuye);
  border-color: var(--encre-legere);
  color: var(--encre);
  text-decoration: none;
}

/*
 * Active : l'aplat de nuit, celui de l'item courant de la barre latérale. Une
 * pilule de filtre EST une navigation, et elle en prend le marquage. L'aplat
 * d'accent reste réservé à l'action primaire de l'écran — deux aplats
 * d'accent sur une même page, et l'œil ne sait plus lequel est le geste
 * attendu.
 */
.pilule.est-active {
  background: var(--nuit);
  border-color: var(--nuit);
  color: var(--nuit-encre);
  font-weight: 700;
}
.pilule.est-active:hover {
  background: var(--nuit);
  border-color: var(--nuit);
  color: var(--nuit-encre);
}

.pilule__compte {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--encre-legere);
}
.pilule.est-active .pilule__compte {
  color: var(--nuit-encre-douce);
}

/* ================================================================== */
/* Tableaux                                                            */
/* ================================================================== */

/* Enveloppe obligatoire : sur mobile, c'est elle qui défile, jamais la page. */
.tableau-enveloppe {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

table.tableau {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-libelle);
  /* Les chiffres d'une colonne doivent s'aligner verticalement : c'est ce qui
     permet de comparer deux montants sans les lire. */
  font-variant-numeric: tabular-nums;
}

table.tableau th {
  padding: 9px 14px;
  text-align: left;
  font-size: var(--t-etiquette);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--caps);
  color: var(--encre-legere);
  background: var(--fond-tete);
  border-bottom: 1px solid var(--bord-appuye);
  white-space: nowrap;
}

table.tableau td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--bord);
  vertical-align: middle;
}

/* Alternance très basse : elle guide l'œil sur une ligne longue sans devenir
   une texture. */
table.tableau tbody tr:nth-child(even) {
  background: var(--fond-zebre);
}
table.tableau tbody tr:last-child td {
  border-bottom: none;
}
table.tableau tbody tr:hover {
  background: var(--fond-appuye);
}
table.tableau .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/*
 * MODE CARTE. Réservé au seul tableau qui reste un tableau : celui que l'on
 * lit en colonne pour comparer des montants d'un client à l'autre. Partout
 * ailleurs, une liste d'objets (voir plus bas) remplace la grille.
 *
 * Sous 700 px, cinq colonnes ne tiennent pas : chaque ligne devient une carte
 * de paires étiquetées. Ni scroll horizontal, ni colonnes de quarante pixels.
 *
 * Changer `display` sur un tableau lui retire ses rôles ARIA implicites — la
 * ligne cesse d'être une ligne, la cellule cesse d'être liée à son en-tête.
 * Les gabarits qui portent cette classe écrivent donc les rôles à la main
 * (`role="table"`, `row`, `cell`, `columnheader`), et l'en-tête est masqué à
 * l'œil sans l'être aux lecteurs d'écran, qui continuent d'y lire le nom de
 * chaque colonne. L'étiquette visible vient de `data-libelle`.
 */
@media (max-width: 699px) {
  table.tableau--cartes,
  .tableau--cartes tbody,
  .tableau--cartes tr,
  .tableau--cartes td {
    display: block;
  }

  table.tableau--cartes {
    padding: var(--espace-3);
  }

  .tableau--cartes thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }

  .tableau--cartes tbody tr {
    padding: var(--espace-3) 14px;
    border: 1px solid var(--bord);
    border-radius: var(--rayon-sm);
  }
  /* Les fonds de zébrure et de survol n'ont plus de sens sur des cartes
     séparées : une carte sur deux en gris se lirait comme un état. */
  .tableau--cartes tbody tr,
  .tableau--cartes tbody tr:nth-child(even),
  .tableau--cartes tbody tr:hover {
    background: var(--fond);
  }
  .tableau--cartes tbody tr + tr {
    margin-top: 10px;
  }

  /*
   * Étiquette AU-DESSUS de la valeur, comme le composant `.paires` du reste de
   * la feuille. Côte à côte en deux colonnes, une cellule qui porte deux
   * enfants (« 1 490,00 € » puis « par an ») renvoyait le second dans la
   * colonne des étiquettes : « par an » se lisait alors comme le nom du champ
   * suivant. Empilé, n'importe quel contenu de cellule tombe juste.
   */
  .tableau--cartes tbody td {
    padding: 5px 0;
    border-bottom: none;
    text-align: left;
  }
  .tableau--cartes tbody td::before {
    content: attr(data-libelle);
    display: block;
    margin-bottom: 1px;
    font-size: var(--t-etiquette);
    font-weight: 700;
    letter-spacing: var(--caps);
    text-transform: uppercase;
    color: var(--encre-legere);
  }
  /* L'alignement à droite sert à comparer une colonne : sans colonne, il ne
     fait plus que décrocher le montant de son étiquette. */
  .tableau--cartes tbody td.num {
    text-align: left;
  }
}

/* ================================================================== */
/* Listes d'objets                                                     */
/* ================================================================== */

/*
 * LA LIGNE-OBJET. Le motif le plus répété de l'application : une liste de
 * choses que l'on parcourt pour en ouvrir une.
 *
 * Écrite en tableau, cette liste donnait à chaque colonne le même poids —
 * la référence, le nom, l'échéance et le chef de projet arrivaient à l'œil
 * dans le désordre, et rien n'accrochait. Il fallait ensuite viser un lien
 * « Ouvrir » de quarante pixels pour entrer dans la fiche.
 *
 * Une ligne-objet a une hiérarchie interne, toujours la même :
 *
 *   identité   — ce qui nomme l'objet, en gras, à la taille du corps
 *   méta       — le contexte (client, référence, date), un cran plus bas
 *   côté       — l'état à droite : pastille, signal, chiffre
 *   actions    — hors du lien, quand il y en a
 *
 * Et la ligne ENTIÈRE est le lien. Un seul lien par ligne : les liens
 * imbriqués sont ingérables au clavier, et deux cibles concentriques ne
 * disent pas laquelle mène où.
 */
.liste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.liste__item {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  /* Le liseré est toujours là, transparent : sans lui, une ligne signalée
     serait décalée de trois pixels par rapport à ses voisines. */
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--bord);
}
.liste__item:last-child {
  border-bottom: none;
}

/*
 * `.liste__lien` quand la ligne mène quelque part, `.liste__bloc` quand elle
 * ne mène nulle part (un compte, une facture dont le document est la seule
 * destination). Même dessin, pour que la liste reste une liste.
 */
.liste__lien,
.liste__bloc {
  flex: 1 1 260px;
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espace-2);
  padding: 13px 18px;
}

.liste__lien {
  color: inherit;
  text-decoration: none;
  font-weight: 400;
  transition: background-color 0.16s ease;
}

/*
 * Le lien s'étire à toute la ligne, y compris sous la zone d'actions.
 *
 * Sans ce voile, la ligne qui porte un bouton avait une zone morte : au
 * téléphone les actions passent à la ligne, et les deux cent soixante pixels
 * restés vides à leur droite ne faisaient rien — mesuré, 17 % de la surface
 * de la ligne. On y tape en croyant ouvrir la fiche.
 *
 * Le bouton, lui, reste au-dessus (`z-index`) et garde son propre geste : le
 * voile ne l'avale pas. C'est ce qui permet d'avoir UNE ligne entièrement
 * cliquable sans jamais imbriquer un lien dans un autre.
 */
.liste__lien::after {
  content: '';
  position: absolute;
  inset: 0;
}
.liste__actions {
  position: relative;
  z-index: 1;
}
.liste__lien:hover {
  background: var(--fond-appuye);
  color: inherit;
}
.liste__lien:hover .liste__titre {
  color: var(--accent-sombre);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}
/*
 * L'anneau se dessine à l'INTÉRIEUR de la ligne. Posé dehors (le décalage de
 * 2 px par défaut), il passait sous la ligne voisine et se faisait rogner par
 * le `overflow: clip` de la carte : au clavier, on ne voyait qu'un fragment de
 * cadre. Ici il souligne la ligne entière — ce qui est précisément ce que le
 * doigt et la souris atteignent.
 */
.liste__lien:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  background: var(--accent-voile);
}

.liste__principal {
  min-width: 0;
  display: grid;
  gap: 3px;
}

/* L'identité est la seule chose en gras de la ligne : c'est elle qui accroche
   l'œil quand on parcourt trente lignes à la recherche d'une. */
.liste__titre {
  min-width: 0;
  font-size: var(--t-corps);
  font-weight: 700;
  line-height: 1.35;
  color: var(--encre);
  overflow-wrap: anywhere;
}

/* Un extrait de retour se lit sur deux lignes au plus : au-delà, la liste
   cesse d'être parcourable et devient un fil de lecture. */
.liste__titre--extrait {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-weight: 600;
}

/*
 * Les séparateurs sont posés par la feuille, pas par le gabarit : une vue qui
 * intercale ses « · » à la main en laisse toujours un qui pend en fin de ligne
 * le jour où la donnée d'après est vide.
 *
 * Le point suit la donnée qu'il termine (`::after`), collé par une espace
 * insécable, et l'écart avant la suivante vient du `column-gap` du flex. Posé
 * en `::before` sur la donnée SUIVANTE, il partait à la ligne avec elle : au
 * téléphone, une ligne de méta sur deux commençait par un point orphelin.
 */
.liste__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  min-width: 0;
  column-gap: 7px;
  row-gap: 2px;
  font-size: var(--t-aide);
  line-height: 1.45;
  color: var(--encre-legere);
  font-variant-numeric: tabular-nums;
}
.liste__meta > *:not(:last-child)::after {
  content: '\00a0·';
  color: var(--bord-appuye);
}
.liste__meta strong {
  font-weight: 600;
  color: var(--encre-douce);
}

.liste__cote {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  min-width: 0;
}

/* Le montant est un chiffre que l'on compare : il monte d'une graisse et
   garde des chasses fixes, colonne ou pas colonne. */
.liste__chiffre {
  font-size: var(--t-appui);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.25;
  white-space: nowrap;
  color: var(--encre);
}
.liste__chiffre small {
  display: block;
  font-size: var(--t-meta);
  font-weight: 500;
  color: var(--encre-legere);
}

/* Avancement d'un projet, remplissage d'un questionnaire : une barre courte
   et son chiffre. Largeur fixe — une jauge élastique ne se compare plus d'une
   ligne à l'autre, ce qui est la seule chose qu'on lui demande. */
.liste__jauge {
  flex: none;
  display: grid;
  gap: 3px;
  width: 92px;
}
/* La jauge est écrite en `<span>` : posée dans un lien de ligne, elle ne peut
   pas être un bloc. La grille et cette règle lui rendent sa hauteur. */
.liste__jauge .jauge {
  height: 6px;
}
.liste__jauge .jauge__barre {
  display: block;
}
.liste__jauge span {
  font-size: var(--t-meta);
  color: var(--encre-legere);
  font-variant-numeric: tabular-nums;
}

/*
 * Les actions vivent HORS du lien de ligne — c'est la seule façon d'avoir une
 * ligne entièrement cliquable sans imbriquer deux liens l'un dans l'autre.
 * Elles sont un frère du lien dans le même conteneur flex, donc jamais
 * recouvertes par lui.
 */
.liste__actions {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espace-2);
  padding: 0 18px 13px;
}

/*
 * Liseré de bord : ce qui attend quelqu'un se repère avant la lecture, à la
 * périphérie de l'œil, pendant que l'on parcourt la colonne des titres.
 */
.liste__item--attention {
  border-left-color: var(--alerte);
}
.liste__item--urgence {
  border-left-color: var(--danger);
}

@media (min-width: 560px) {
  .liste__lien,
  .liste__bloc {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--espace-2) var(--espace-5);
  }
  .liste__cote {
    justify-content: flex-end;
    text-align: right;
  }
  .liste__actions {
    padding: 13px 18px 13px 0;
  }
}

/* ================================================================== */
/* Progression, frise, fil, indicateurs                                */
/* ================================================================== */

.jauge {
  height: 8px;
  border-radius: 999px;
  background: var(--fond-appuye);
  box-shadow: inset 0 0 0 1px var(--bord-appuye);
  overflow: hidden;
}
.jauge__barre {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.3s ease;
}

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

.frise__etape {
  position: relative;
  padding: 0 0 22px 30px;
}
/* Le trait relie les jalons ; le dernier ne le porte pas. */
.frise__etape::before {
  content: '';
  position: absolute;
  left: 6px;
  top: 18px;
  bottom: 0;
  width: 2px;
  background: var(--bord-appuye);
}
.frise__etape:last-child {
  padding-bottom: 0;
}
.frise__etape:last-child::before {
  display: none;
}

.frise__puce {
  position: absolute;
  left: 0;
  top: 4px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid var(--bord-fort);
  background: var(--fond);
}
.frise__etape--termine .frise__puce {
  background: var(--succes);
  border-color: var(--succes);
}
.frise__etape--en_cours .frise__puce {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-voile);
}
.frise__etape--bloque .frise__puce {
  background: var(--danger);
  border-color: var(--danger);
}

.frise__titre {
  font-weight: 600;
  margin: 0 0 2px;
}
.frise__etape--en_cours .frise__titre {
  color: var(--accent-encre);
}
.frise__meta {
  font-size: var(--t-aide);
  color: var(--encre-legere);
  font-variant-numeric: tabular-nums;
}

.fil {
  list-style: none;
  margin: 0;
  padding: 0;
}
.fil__item {
  padding: 13px 0;
  border-bottom: 1px solid var(--bord);
}
.fil__item:first-child {
  padding-top: 0;
}
.fil__item:last-child {
  padding-bottom: 0;
  border-bottom: none;
}
.fil__meta {
  font-size: var(--t-meta);
  color: var(--encre-legere);
  font-variant-numeric: tabular-nums;
  margin-bottom: 3px;
}

/*
 * Liste clé / valeur (fiche de repères, récapitulatifs). Écrite en `<br>`, la
 * clé et la valeur avaient le même poids et se lisaient comme une seule
 * phrase. Ici la clé descend d'une strate et la valeur monte d'une graisse.
 */
.paires {
  margin: 0;
  display: grid;
  gap: var(--espace-3);
}
.paires > div {
  display: grid;
  gap: 1px;
}
.paire__cle {
  font-size: var(--t-etiquette);
  font-weight: 700;
  letter-spacing: var(--caps);
  text-transform: uppercase;
  color: var(--encre-legere);
}
.paire__valeur {
  margin: 0;
  font-size: var(--t-libelle);
  font-weight: 600;
  color: var(--encre);
  font-variant-numeric: tabular-nums;
}

.indicateur {
  padding: var(--espace-4) 18px;
}
.indicateur__valeur {
  font-family: var(--police-titre);
  font-size: var(--t-nombre);
  font-weight: 800;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
  color: var(--encre);
}
/* L'étiquette d'un compteur se lit autant que le compteur : elle sort du gris
   le plus clair. */
.indicateur__libelle {
  margin-top: 2px;
  font-size: var(--t-etiquette);
  color: var(--encre-douce);
  text-transform: uppercase;
  letter-spacing: var(--caps);
  font-weight: 700;
}

/*
 * État vide : ce n'est pas une absence, c'est un écran à part entière. Cadre
 * pointillé (rien n'est encore posé ici), titre au rang d'un titre de section,
 * texte à la mesure, et la place d'une action. Aucun médaillon décoratif :
 * un carré vide se lit comme une image qui n'a pas chargé.
 */
.vide {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--espace-2);
  padding: var(--espace-8) var(--espace-6);
  text-align: center;
  color: var(--encre-legere);
  background: var(--fond-doux);
  border: 1px dashed var(--bord-appuye);
  border-radius: var(--rayon-sm);
}
.carte > .vide {
  margin: 18px;
}
.vide__titre {
  margin: 0;
  font-family: var(--police-titre);
  font-size: var(--t-section);
  font-weight: 700;
  letter-spacing: -0.012em;
  color: var(--encre);
}
.vide p {
  max-width: 52ch;
  margin: 0;
  font-size: var(--t-libelle);
  line-height: 1.5;
}
.vide .btn {
  margin-top: var(--espace-2);
}

/* ================================================================== */
/* Listes de définitions (pages légales)                               */
/* ================================================================== */

/*
 * « Raison sociale : … », « SIRET : … ». Un `<dl>` et non un tableau : ce sont
 * des paires terme/valeur, pas des lignes comparables entre elles — et sur un
 * téléphone, une grille à deux colonnes se replie en une seule sans que rien
 * ne défile.
 */
.definitions {
  display: grid;
  grid-template-columns: minmax(160px, 12rem) 1fr;
  gap: var(--espace-2) var(--espace-4);
  margin: 0;
}
.definitions dt {
  color: var(--encre-legere);
  font-size: var(--t-aide);
  /* Aligné sur la première ligne de sa valeur, pas centré : une adresse sur
     trois lignes ferait sinon flotter son intitulé au milieu. */
  align-self: start;
  padding-top: 2px;
}
.definitions dd {
  margin: 0;
}

@media (max-width: 560px) {
  .definitions {
    grid-template-columns: 1fr;
    gap: 2px var(--espace-4);
  }
  /* Chaque paire redevient un bloc : un peu d'air avant l'intitulé suivant. */
  .definitions dd + dt {
    margin-top: var(--espace-3);
  }
}

/* ================================================================== */
/* Page centrée (connexion, invitation)                                */
/* ================================================================== */

/*
 * Seul écran de l'application qui n'est pas un plan de travail : c'est la
 * première image que le client reçoit de l'agence. Il prend donc le parti du
 * visuel de marque en entier — champ de nuit, marque en blanc au centre, une
 * seule carte claire posée dessus.
 */
.page-centree {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--espace-8) var(--espace-4);
  background: radial-gradient(
      900px 520px at 50% -8%,
      rgba(255, 255, 255, 0.12),
      transparent 64%
    ),
    var(--nuit);
}
.page-centree .carte {
  width: 100%;
  max-width: 404px;
  box-shadow: var(--ombre-3);
  border-color: transparent;
}
.page-centree .carte__corps {
  padding: var(--espace-6);
}
.page-centree h1 {
  font-size: var(--t-sous);
  margin-bottom: var(--espace-1);
}
.page-centree__marque {
  display: flex;
  justify-content: center;
  margin-bottom: 22px;
}
/* Sur la page d'accueil de l'agence, le médaillon est plein et blanc, comme un
   logo posé sur une affiche : c'est le seul écran où la marque est le sujet. */
.page-centree__marque .marque__fusee {
  background: var(--nuit-encre);
  color: var(--nuit);
  box-shadow: none;
}
/* Les mentions posées hors de la carte sont sur la nuit, pas sur du gris
   clair : les utilitaires `.muet` qu'elles portent y seraient illisibles. */
.page-centree > * > p {
  color: var(--nuit-encre-legere);
}
.page-centree > * > p a {
  color: var(--nuit-encre);
}
.page-centree > * > p a:focus-visible {
  outline-color: var(--nuit-encre);
}

/* ================================================================== */
/* Utilitaires                                                         */
/* ================================================================== */

.muet {
  color: var(--encre-legere);
}
.petit {
  font-size: var(--t-aide);
}
.mono {
  font-family: var(--police-mono);
  font-size: 0.9em;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.gras {
  font-weight: 600;
}
.centre {
  text-align: center;
}
.mesure {
  max-width: var(--mesure);
}
.chiffres {
  font-variant-numeric: tabular-nums;
}
.pile {
  display: flex;
  flex-direction: column;
  gap: var(--espace-1);
}
.rangee {
  display: flex;
  align-items: center;
  gap: var(--espace-2);
  flex-wrap: wrap;
}
.pousse {
  margin-left: auto;
}
.mt-0 {
  margin-top: 0;
}
.mb-0 {
  margin-bottom: 0;
}
.mt-16 {
  margin-top: var(--espace-4);
}
.mb-16 {
  margin-bottom: var(--espace-4);
}
.mb-24 {
  margin-bottom: var(--espace-6);
}

.lecteur-ecran-seul {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ================================================================== */
/* Écrans moyens                                                       */
/* ================================================================== */

@media (min-width: 720px) {
  :root {
    --t-page: 2.125rem; /* 34 px — le titre de page domine enfin le corps */
  }
  .enveloppe {
    padding: 0 28px;
  }
  /* Respiration en haut : c'est ce qui distingue un écran soigné d'un écran
     qui commence au ras du bord. */
  .appli__contenu {
    padding: var(--espace-8) 0 88px;
  }
  .barre__entete {
    padding: var(--espace-5) 18px;
  }
  .carte__corps {
    padding: var(--espace-5);
  }
  .grille--2 {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ================================================================== */
/* Grand écran : la barre latérale se fixe à gauche                    */
/* ================================================================== */

@media (min-width: 1000px) {
  .appli {
    display: grid;
    grid-template-columns: var(--barre-largeur) minmax(0, 1fr);
    align-items: start;
  }

  .barre {
    grid-column: 1;
    grid-row: 1;
    position: sticky;
    top: 0;
    height: 100vh;
    width: auto;
    transform: none;
    box-shadow: none;
    transition: none;
  }

  .appli__contenu {
    grid-column: 2;
    grid-row: 1;
  }

  /* Le tiroir et ses commandes n'ont plus de raison d'être. */
  .barre-mobile,
  .voile,
  .barre__fermer {
    display: none;
  }

  .grille--3 {
    grid-template-columns: repeat(3, 1fr);
  }
  /* Deux tiers / un tiers : contenu principal et colonne d'appui. */
  .grille--principal-lateral {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  }
}

@media (min-width: 1360px) {
  :root {
    --barre-largeur: 288px;
  }
}

/* ================================================================== */
/* Mouvement réduit                                                    */
/* ================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .btn:active,
  a.carte:hover {
    transform: none;
  }
}

/* ================================================================== */
/* Impression (fiche de synthèse du questionnaire)                     */
/* ================================================================== */

@media print {
  body {
    background: #fff;
    font-size: 11pt;
  }
  .barre,
  .barre-mobile,
  .voile,
  .saut-contenu,
  .btn,
  .titre-page__actions,
  .filtres,
  .liste__actions,
  .public__entete,
  .sans-impression {
    display: none !important;
  }
  /* Une ligne coupée en deux par un saut de page se relit deux fois. */
  .liste__item {
    break-inside: avoid;
  }
  .appli {
    display: block;
  }
  .appli__contenu,
  .page {
    padding: 0;
  }
  .enveloppe {
    max-width: none;
    padding: 0;
  }
  .carte {
    border: none;
    box-shadow: none;
    break-inside: avoid;
  }
  .carte__entete,
  .carte__pied,
  .vide,
  .bloc-saisie {
    background: transparent;
    border: none;
  }
  /*
   * Les fonds ne s'impriment pas par défaut : une carte pleine sortirait en
   * blanc sur blanc, c'est-à-dire vide. À l'impression elle redevient un
   * encadré à l'encre — le message est conservé, l'aplat non.
   */
  .message,
  .signal {
    background: transparent !important;
    color: var(--encre);
    border: 1px solid #9a9aae;
    box-shadow: none;
  }
  .message .muet,
  .message .petit.muet {
    color: var(--encre-douce);
  }
  table.tableau tbody tr:nth-child(even) {
    background: transparent;
  }
  a {
    text-decoration: none;
    color: inherit;
  }
}
