/* ===========================================================================
   LE DOSSIER DE CANDIDATURE — un DOCUMENT à sections, pas un écran de gestion.

   ── POURQUOI IL NE PREND PAS LE CADRE DE L'APP ────────────────────────────
   La règle du 2026-08-13 — fenêtre figée, zones qui défilent — décrit une app
   de GESTION : des listes qu'on parcourt, des volets qu'on ouvre. Celui-ci est
   un formulaire de quarante questions rempli une fois dans sa vie, par
   quelqu'un qui n'est pas de la coop, le plus souvent sur un téléphone. Un
   document qui défile normalement est ce qu'il attend, et c'est ce que fait
   déjà `layouts/plain`, qui le porte.

   ── MOBILE D'ABORD (Eric, 2026-08-30) ─────────────────────────────────────
   Une colonne, la navigation des sections en tête. À 900 px la navigation
   passe à GAUCHE et devient collante ; le document garde sa largeur de lecture
   au lieu de s'étirer sur toute la fenêtre.
   =========================================================================== */

/* La largeur et le rembourrage viennent de `.auth-shell-large`, dans
   `auth.css` : la coquille sait ce qu'elle porte, le document ne se mesure pas
   lui-même. Les deux fois donneraient un rembourrage double.

   ── SAUF EN HAUT (Eric, 2026-09-01 : « too tight at the top ») ────────────
   Mesuré : le bas de la barre collante et le haut du titre étaient tous deux
   à 85 px — zéro pixel entre le trait et le mot. La barre COLLE, donc ce
   n'est pas un blanc qu'on gagne en défilant : le titre lui reste collé tout
   le long. Le rembourrage va sur la grille et non sur une colonne, pour que
   les deux descendent ensemble et gardent leur alignement. */
.dossier {
  width: 100%;
  padding-top: var(--space-5);
}

/* LA HAUTEUR DE LA BARRE DU HAUT, et pourquoi elle est mesurée.

   Elle sert deux fois — la navigation se colle juste sous la barre, et les
   ancres doivent s'arrêter sous les deux — donc elle se nomme une fois.

   `candidature.js` la remplace par la valeur RÉELLE au chargement et au
   redimensionnement. Ce n'est pas « du JS qui rend » — c'est du JS qui MESURE,
   et la hauteur d'une barre dont les boutons peuvent passer à la ligne n'est
   pas une chose que le serveur peut connaître. La valeur écrite ici est donc
   un DÉFAUT SÛR : plus grand que la barre, pour que rien ne se cache dessous
   quand le script ne tourne pas.

   Le premier essai valait 4.5rem, soit 72 px, et la navigation se collait donc
   TREIZE PIXELS SOUS la barre — son premier bouton était coupé, ce qui se voit
   à l'œil et qu'aucun test n'aurait dit.

   ── ET 6rem N'ÉTAIT PAS SÛR NON PLUS (2026-08-30) ────────────────────────
   Il valait 96 px pour une barre mesurée à 93, et cette mesure-là n'avait vu
   qu'UNE des deux dispositions. Quand la marque et les boutons ne tiennent
   pas sur la même ligne — c'est le cas de tout téléphone — la barre en fait
   DEUX, et elle mesurait 145 px : le défaut cachait alors cinquante pixels de
   navigation sur exactement les appareils qui n'exécutent pas toujours le
   script. Le défaut était faux avant les pilules ; elles n'ont fait que rendre
   la deuxième disposition courante.

   Deux corrections, et la première vaut pour elle-même : `.auth-mark` porte
   une marge basse de 32 px qui sert à la PORTE D'ENTRÉE, où la marque ouvre
   une page au-dessus d'une carte. Dans une barre collante, c'est trente-deux
   pixels retirés du document en permanence pour un blanc que le `row-gap`
   dessine déjà. Elle tombe ici (voir `.doc-entete .auth-mark`), ce qui ramène
   les deux dispositions à 61 et 113 px. 8rem — 128 px — couvre la seconde. */
:root { --doc-entete-h: 8rem; }

/* OÙ UNE ANCRE S'ARRÊTE. Sans ça, sauter à une section la fait atterrir SOUS
   la barre : on clique « Vous et la coop » et on voit le deuxième champ, sans
   son titre. Au téléphone la rangée de navigation colle aussi, donc elle
   compte double. */
:root { --doc-ancre: calc(var(--doc-entete-h) + 4.5rem); }

/* ---------------------------------------------------------------
   LA BARRE DU HAUT — collante, et elle porte des liens
   ---------------------------------------------------------------
   Eric, 2026-08-30 : « the form is a dead end ». Un document qu'on remplit
   pendant vingt minutes doit dire d'où l'on vient et où l'on peut aller. Et
   il doit le dire SANS qu'on remonte : d'où le collant.
   --------------------------------------------------------------- */

.doc-entete {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) 0;
  background: var(--c-bg);
  border-bottom: 1px solid var(--c-border);
}

.doc-liens {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  font-size: var(--mil-fs-2);
}

/* Le `<form>` de la sortie ne dispose de rien : il porte un POST, pas une mise
   en page. Sans ça son bouton hérite d'une marge de bloc et sort d'un cran plus
   bas que ses voisins — c'est exactement ce qui se voyait sur la capture du
   2026-08-30, où « Sortir » flottait sous la ligne des trois liens. */
.doc-liens form { display: flex; margin: 0; }

/* LA MARGE BASSE DE LA MARQUE N'A RIEN À FAIRE DANS UNE BARRE. Elle vaut 32 px
   et elle est juste sur la porte d'entrée, où la marque ouvre la page au-dessus
   d'une carte. Ici la barre COLLE : ces 32 px sont retirés du document pour
   toute la durée du remplissage, et le `row-gap` de `.doc-entete` sépare déjà
   la marque des boutons quand ils passent à la ligne. */
.doc-entete .auth-mark { margin-bottom: 0; }

/* ---------------------------------------------------------------
   LES BOUTONS DE LA BARRE — des pilules à dessin, pas des liens soulignés
   ---------------------------------------------------------------
   Eric, 2026-08-30 : la barre était quatre liens bleus soulignés serrés dans
   le coin droit. Trois choses ne marchaient pas, et aucune n'est du goût :

   · ils se lisaient comme du TEXTE de page — même encre, même taille, même
     soulignement que les liens du document juste en dessous, alors que ce sont
     les seules commandes de l'écran ;
   · la sortie, seule à être un `<button>` dans un `<form>`, ne s'alignait pas
     sur ses voisins (voir `.doc-liens form` ci-dessus) ;
   · cinq mots à lire pour trouver le bon, là où un dessin se repère sans
     lecture — et ceci est la barre qu'on cherche du regard en panique, pas
     celle qu'on parcourt.

   D'où la pilule : bordée, sur `--c-surface`, avec son icône. C'est la forme
   déjà tranchée pour `.outil-rond` (Eric, 2026-08-19) — « le rond dit un
   geste, pas une phrase » — tenue ici avec le mot tant qu'il y a la place.

   ÉCRITE ICI ET PAS DANS `app.css` : `layouts/plain` ne charge jamais cette
   feuille-là. C'est la panne des liens de magasin du 2026-08-25, et elle se
   paie une deuxième fois à chaque composant écrit au mauvais endroit.

   `min-height` ET PAS `height` : le mot passe à la ligne à 200 % de zoom, et
   une hauteur fixe le couperait. */
.doc-lien {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;              /* cible au doigt, règle 9 */
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-pill);
  background: var(--c-surface);
  color: var(--c-text);
  font: inherit;
  font-size: var(--mil-fs-2);
  font-weight: 600;
  text-decoration: none;         /* rien ne désouligne un lien sur `plain` */
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast),
              color var(--t-fast);
}

/* 18 px et pas les 22 du gabarit : le magasin dessine à la taille du rail, où
   l'icône porte seule une colonne. Ici elle accompagne un mot. */
.doc-lien svg {
  flex: none;
  width: calc(18px * var(--mil-fs, 1));
  height: calc(18px * var(--mil-fs, 1));
}

.doc-lien:hover {
  border-color: var(--c-accent);
  background: var(--c-accent-soft);
  color: var(--c-accent-dark);
}

/* L'anneau de focus signature (§0, règle 7), redéclaré parce que celui
   d'`app.css` ne suit pas sur `layouts/plain`. */
.doc-lien:focus-visible {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-soft);
}

/* Press tactile (§2, mouvement) — le même que les primaires d'`auth.css`. */
.doc-lien:active { transform: scale(0.98); }

/* LA SORTIE GARDE LA FORME ET PERD LE RANG. Elle est la seule commande de la
   barre qui défait quelque chose : les quatre autres mènent ailleurs et se
   reviennent, celle-ci ferme la session d'un dossier rempli à moitié. Encre
   grise au repos, rouge au survol — le geste se voit venir avant de partir,
   comme la croix qui désassigne (`.outil-retrait`). */
.doc-lien-sortie { color: var(--c-text-mid); }

.doc-lien-sortie:hover {
  border-color: var(--c-danger);
  background: var(--c-danger-soft);
  color: var(--c-danger-text);
}

/* ── SOUS 820 px : LE DESSIN SEUL ─────────────────────────────────────────
   Le mot part à l'œil et reste à l'oreille — il est toujours dans le DOM,
   simplement hors du champ. C'est aussi ce qui dispense les icônes de
   l'`aria-label` qu'un dessin VRAIMENT seul imposerait (voir l'entête de
   `partials/icons`) : le nom accessible du bouton ne bouge pas.

   ── LA COUPURE EST MESURÉE, PAS CHOISIE ────────────────────────────────
   Elle ne nomme aucun appareil. C'est la largeur en dessous de laquelle les
   cinq pilules à mot cessent de tenir sur UNE rangée — elles en demandent
   761 px, et la coquille en offre la largeur de la fenêtre moins 32. Mesuré
   au banc le 2026-08-30 : elles tiennent à 830, « Sortir » tombe seule à la
   ligne à 790 ; 820 laisse la marge d'un rendu de police qui diffère.

   Et une rangée de plus n'est pas un détail ici : la barre est COLLANTE, et
   la navigation des sections se colle dessous. Chaque rangée est donc
   retirée du document pour les vingt minutes du remplissage, pas seulement
   au chargement. À 700 px, la version à mots faisait trois rangées de haut —
   la marque, puis deux de pilules — soit près du tiers d'un écran de tablette
   en portrait rendu inutilisable à demeure.

   C'est aussi pourquoi `mes_demandes` a perdu « précédentes » le même jour :
   le libellé le plus large décidait de la coupure à lui seul, et le mot était
   redondant — la demande courante est la page qu'on a sous les yeux. */
@media (max-width: 820px) {
  .doc-lien {
    position: relative;          /* l'ancre du mot caché juste en dessous */
    width: 44px;
    padding: 0;
  }

  .doc-lien-mot {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ---------------------------------------------------------------
   La navigation des sections
   ---------------------------------------------------------------
   AU TÉLÉPHONE : une rangée qui défile, collée SOUS la barre. Empilée, elle
   prendrait quatre lignes de haut à demeure — un cinquième de l'écran pour
   une navigation qu'on utilise trois fois.

   À 900 px : la colonne de gauche, collante elle aussi.
   --------------------------------------------------------------- */
.dossier-nav-zone {
  position: sticky;
  top: var(--doc-entete-h);
  z-index: 2;
  background: var(--c-bg);
}

.dossier-nav {
  /* `position: relative` PARCE QU'ELLE ÉCRÊTE. Un `overflow` ne retient que ce
     qu'il CONTIENT : un descendant en `position: absolute` — toute
     `.visually-hidden` en est une — se placerait dans le document entier,
     échapperait à l'écrêtage, et rallongerait la page d'un élément d'un pixel
     que personne ne voit. Le garde-fou du dépôt l'a attrapé à l'atterrissage. */
  position: relative;
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  margin: 0 0 var(--space-5);
  padding: var(--space-2) 0;
  list-style: none;
}

.dossier-nav li { flex: 0 0 auto; margin: 0; }

/* Le rail est un `<ol>` depuis que l'ordre est une RÈGLE et plus une mise en
   page. Ses numéros ne se dessinent pas — le rang se lit à la position, et un
   « 3. » devant chaque nom serait un mot de plus à lire pour rien. */
.dossier-nav { counter-reset: none; }

/* `center` ET PAS `baseline` : les deux boîtes de 44 px — une entrée du rail
   et le titre de l'étape — n'alignent leurs mots que si les DEUX centrent le
   leur. Avec `baseline`, le texte du rail se posait en haut de sa boîte et le
   titre au milieu de la sienne : cinq pixels d'écart, mesurés. Le compte à
   droite y gagne aussi — il fait un cran de moins que le nom, et centré il ne
   pend plus sous lui. */
.dossier-nav a,
.dossier-nav .dossier-nav-ferme {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  min-height: 44px;               /* cible au doigt, règle 9 */
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--c-text);
  text-decoration: none;
  white-space: nowrap;
}

.dossier-nav a:hover { background: var(--c-surface-2); }

/* `step` ET PAS `true` : c'est le jeton que la norme réserve à une étape
   d'assistant, et il fait annoncer « étape courante » plutôt qu'un « courant »
   nu. Le rail n'était pas un assistant avant le 2026-09-01. */
.dossier-nav a[aria-current="step"] {
  background: var(--c-surface-2);
  font-weight: 600;
}

/* UNE ÉTAPE QUE L'ON N'A PAS ENCORE OUVERTE. Elle est grise et elle ne bouge
   pas au survol — rien ne promet un clic qui n'arrivera pas. C'est un `<span>`
   dans le gabarit, donc elle n'est ni au clavier ni sous le doigt ; ceci n'est
   que ce qui le rend visible. */
.dossier-nav-ferme {
  color: var(--c-text-muted);
  cursor: default;
}

/* CE QUI MANQUE, DIT À CÔTÉ DU NOM DE LA SECTION. C'est ce qui remplace le mur
   rouge au moment du dépôt : on voit ce qui reste AVANT d'y arriver. */
.dossier-reste {
  margin-left: auto;
  font-size: var(--mil-fs-1);
  color: var(--c-text-muted);
}

.dossier-reste[data-complet] { color: var(--c-accent); }

.dossier-section {
  margin: 0 0 var(--space-6);
  padding: var(--space-4);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  background: var(--c-surface);
}

/* Une ancre s'arrête SOUS ce qui colle. */
.dossier-section { scroll-margin-top: var(--doc-ancre); }

/* LE TITRE DE SECTION SE VOIT — Eric, 2026-08-30. Dans un document de
   quarante questions, c'est le seul repère qui dit qu'on a changé de sujet :
   à la taille d'un libellé de champ, il se noyait dans la liste. */
.dossier-section > h2 {
  margin: 0 0 var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 2px solid var(--c-accent);
  font-size: var(--mil-fs-5);
  font-weight: 700;
}

.dossier-corps { min-width: 0; }

/* ── LE TITRE S'ALIGNE SUR LA PREMIÈRE ENTRÉE DU RAIL ──────────────────────
   Eric, 2026-09-01 : « not aligned with step nav ». Et la mesure dit une chose
   plus fine que le coup d'œil — les deux BOÎTES commençaient déjà au même
   pixel (85). Ce qui ne s'alignait pas, c'est le TEXTE : une entrée de rail
   fait 44 px de haut avec son texte centré dedans, le titre faisait 40 px avec
   le sien collé en haut. Deux boîtes alignées, deux mots à sept pixels d'écart.

   D'où la même boîte pour les deux : 44 px, texte centré. C'est aussi la cible
   au doigt (§0, règle 9) que les entrées portent déjà — le titre n'en a pas
   besoin, mais partager la mesure est ce qui garde l'alignement vrai le jour
   où l'une des deux change.

   `> .auth-title` et pas `.auth-title` : la feuille est chargée par TOUTE la
   coquille `plain`, donc par la connexion et la porte du candidat, où ce titre
   n'a aucun rail à qui se comparer. */
.dossier-corps > .auth-title {
  display: flex;
  align-items: center;
  min-height: 44px;
  margin: 0 0 var(--space-4);
}

/* Deux champs courts par ligne — mais seulement quand la place existe. Au
   téléphone, ils s'empilent, et c'est la règle de départ plutôt qu'un repli. */
.dossier-paire { display: block; }

.dossier-champ { margin: 0 0 var(--space-4); }

/* Une ancre `#q-<clé>` s'arrête SOUS ce qui colle, comme les sections. C'est
   là que le sommaire des refus envoie, et sans ça le champ nommé atterrit
   derrière la barre — on clique « Prénom » et on voit la question d'après. */
.dossier-champ { scroll-margin-top: var(--doc-ancre); }

/* L'enveloppe est `tabindex="-1"` pour que le navigateur y pose vraiment le
   focus quand l'ancre l'atteint (sinon le clavier reste où il était). Ce
   focus-là est PROGRAMMATIQUE : il ne doit pas dessiner d'anneau, sauf si
   quelqu'un y arrive vraiment au clavier. */
.dossier-champ:focus { outline: none; }

.dossier-champ:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-accent-soft);
}

/* ── LE LIBELLÉ SE LIT ─────────────────────────────────────────────────────
   Il était en `--c-text-mid` au cran 2, c'est-à-dire du gris à 14 px pour la
   QUESTION, au-dessus d'un champ à 16 px. Sur un document de quarante
   questions rempli au téléphone, c'est la ligne qu'on lit le plus, et c'était
   la plus pâle de l'écran.

   ── ET `> legend` NE DÉSIGNAIT RIEN ──────────────────────────────────────
   Une `<legend>` vit dans son `<fieldset>`, jamais directement sous
   `.dossier-champ` : la règle était juste à la lecture et morte à l'écran, et
   les onze questions à boutons rendaient leur intitulé au style par défaut du
   navigateur — donc plus GROS que les autres, sans marge, hors de l'échelle.

   `:not(.dossier-choix)` parce que la même enveloppe porte parfois une case à
   cocher, dont le libellé est une RANGÉE et pas un intitulé. Sans ça, le
   consentement du dépôt perdait sa disposition et sa cible de 44 px — la règle
   la plus spécifique gagnait, quel que soit l'ordre du fichier. */
.dossier-champ > label:not(.dossier-choix),
.dossier-champ legend {
  display: block;
  margin: 0 0 var(--space-1);
  padding: 0;
  font-size: var(--mil-fs-3);
  font-weight: 600;
  color: var(--c-text);
}

/* « Facultatif », à côté de la question. Le seul champ de l'écran qui ne soit
   pas exigé le dit, plutôt que d'étoiler les trente-neuf autres. */
.dossier-facultatif {
  margin-left: var(--space-2);
  font-size: var(--mil-fs-1);
  font-weight: 400;
  color: var(--c-text-muted);
}

/* LE REFUS, SOUS LE CHAMP QU'IL REFUSE. La liste du haut dit lesquels ; ceci
   dit lequel, là où on est en train de corriger. La couleur ne porte rien
   toute seule (§0, règle 8) — le message est écrit. */
.dossier-erreur {
  margin: var(--space-1) 0 0;
  font-size: var(--mil-fs-2);
  color: var(--c-danger-text);
}

.dossier-champ input[type="text"],
.dossier-champ input[type="email"],
.dossier-champ input[type="tel"],
.dossier-champ input[type="date"],
.dossier-champ input[type="number"],
.dossier-champ textarea,
.dossier-champ select {
  width: 100%;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-sm);
  background: var(--c-bg);
  color: var(--c-text);
  font: inherit;
  font-size: var(--mil-fs-3);
}

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

/* LE CHAMP REFUSÉ SE BORDE — et le sélecteur doit NOMMER son élément.
   `.dossier-champ [aria-invalid="true"]` se lit juste et ne peint rien : un
   sélecteur d'attribut pèse autant qu'une classe, donc
   `.dossier-champ input[type="tel"]` ci-dessus le bat d'un cran et repose sa
   bordure grise. Mesuré sur le rendu de brisdemo — les vingt et un champs
   refusés portaient leur message et gardaient la bordure d'un champ intact.
   À poids égal, c'est l'ordre qui trancherait : cette règle vient donc APRÈS.
   (Le `<fieldset>` d'une question à boutons n'a pas de bordure à teindre ; son
   refus est écrit sous lui, et c'est la règle 8 qui l'exige.) */
.dossier-champ input[aria-invalid="true"],
.dossier-champ textarea[aria-invalid="true"] { border-color: var(--c-danger); }

/* La règle que la question porte — l'admissibilité au PSL, l'attribution des
   chambres. Ce n'est pas de la politesse : sans elle, la réponse est donnée à
   l'aveugle. */
.dossier-aide {
  margin: var(--space-1) 0 0;
  font-size: var(--mil-fs-1);
  color: var(--c-text-muted);
}

.dossier-champ fieldset {
  margin: 0;
  padding: 0;
  border: 0;
}

.dossier-choix {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  min-height: 44px;
  padding: var(--space-1) 0;
}

.dossier-choix input { margin-top: 0.35em; }

/* L'ÉTAT DE LA SAUVEGARDE A QUITTÉ LA BARRE le 2026-09-09.

   Il était « discret et permanent, jamais un avis : un avis par champ
   enregistré ferait quarante avis ». L'objection était juste et elle est
   PAYÉE — `toasts.js` plafonne la pile à trois confirmations vivantes depuis
   le 2026-08-18. Ce qui restait était donc une phrase grise au bout d'une
   rangée de boutons, portant le seul message de cet écran qu'il ne faut pas
   rater : « votre session a expiré ». Voir `candidature.js`. */

/* LA DATE D'EMMÉNAGEMENT, SOUS SON CHOIX. Elle n'apparaît que si l'on a dit
   « à partir d'une date » — c'est un enfant de la question, pas une question de
   plus, donc son libellé est en second rang et son champ ne prend pas toute la
   largeur : une date fait dix caractères, et un champ de 800 px pour dix
   caractères se lit comme une erreur de mise en page. */
.dossier-quand { margin-top: var(--space-3); }

.dossier-quand > label {
  display: block;
  margin: 0 0 var(--space-1);
  font-size: var(--mil-fs-2);
  color: var(--c-text-mid);
}

.dossier-champ .dossier-quand > input[type="date"] { max-width: 16rem; }

/* ---------------------------------------------------------------
   LE RÉPÉTEUR DE L'IMPLICATION — une ligne, un comité
   ---------------------------------------------------------------
   Maquette du 2026-09-01 : ⊕ au-dessus, puis des lignes qui portent
   chacune leur sélecteur, leur « Retirer » et leur texte.

   Une LIGNE et pas une carte : c'est déjà un `.dossier-champ`, donc
   elle a la marge, l'ancre et le focus de tous les autres champs. Ce
   qui est écrit ici n'est que ce qu'elle a de plus — un liseré à
   gauche, qui dit « ceci se répète » sans ajouter une boîte de plus
   dans un écran qui en a déjà.
   --------------------------------------------------------------- */
.implication-invite {
  margin: 0 0 var(--space-3);
  font-size: var(--mil-fs-3);
  font-weight: 600;
  color: var(--c-text);
}

.implication-ajouter {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;              /* cible au doigt, règle 9 */
  padding: var(--space-2) var(--space-4);
  border: 1px dashed var(--c-border-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--c-text);
  font: inherit;
  font-size: var(--mil-fs-2);
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}

/* LE TIRET DIT « IL N'Y A RIEN ENCORE ». C'est la convention du dépôt pour un
   ajout — plein, il se lirait comme le bouton principal de l'écran, qui est
   « Suivant ». */
.implication-ajouter:hover {
  border-color: var(--c-accent);
  background: var(--c-accent-soft);
  color: var(--c-accent-dark);
}

.implication-ajouter:focus-visible {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-soft);
}

.implication-ajouter svg { flex: none; width: 18px; height: 18px; }

.implication-ligne {
  padding-left: var(--space-4);
  border-left: 2px solid var(--c-border);
}

/* Le comité et son retrait sur une ligne : le nom à gauche, le geste au bout.
   `flex-wrap` parce qu'à 320 px un nom de comité et « Retirer » ne tiennent
   pas ensemble. */
.implication-tete {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  align-items: center;
  margin-bottom: var(--space-3);
}

/* Le libellé du sélecteur ne prend pas toute la largeur ici — il est le
   premier mot d'une rangée, pas le titre d'un champ. Il bat
   `.dossier-champ > label:not(.dossier-choix)` par la spécificité de son
   parent, et l'ordre du fichier ne décide de rien. */
.implication-tete > label { margin: 0; }

.implication-tete > select { flex: 1 1 12rem; width: auto; }

/* « RETIRER » — un mot, pas un bouton. Il défait une ligne, donc il emprunte
   la trajectoire de la sortie (`.doc-lien-sortie`) : gris au repos, rouge au
   survol. Le geste se voit venir avant de partir. */
.implication-retirer {
  margin-left: auto;
  min-height: 44px;              /* cible au doigt, règle 9 */
  padding: 0 var(--space-2);
  border: 0;
  background: none;
  color: var(--c-text-mid);
  font: inherit;
  font-size: var(--mil-fs-2);
  text-decoration: underline;
  cursor: pointer;
}

.implication-retirer:hover { color: var(--c-danger-text); }

.implication-retirer:focus-visible {
  outline: none;
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 3px var(--c-accent-soft);
}

/* La ligne en attente n'a pas encore de texte à porter : sa tête est tout ce
   qu'elle a, et la marge du bas ferait un blanc que rien n'explique. */
.implication-vide .implication-tete { margin-bottom: 0; }

/* ---------------------------------------------------------------
   LES DEUX PAS — Précédent et Suivant
   ---------------------------------------------------------------
   Ils remplacent le bouton « Enregistrer » de chaque section, que la
   maquette du 2026-09-01 interdit. « Précédent » recule à gauche,
   « Suivant » avance à droite : c'est le seul endroit de l'écran où la
   position dit quelque chose.

   ⚠️ `justify-content: space-between` ÉTAIT FAUX, et le commentaire
   qu'il portait ici l'était aussi — il affirmait que le bouton seul
   resterait à droite. `space-between` place le premier élément au
   DÉBUT : à la première étape, où il n'y a pas de « Précédent »,
   « Suivant » partait donc à gauche. Vu par Eric le 2026-09-01, mesuré
   à 480 px, c'est-à-dire au bord gauche de la colonne.

   `margin-left: auto` sur le bouton qui AVANCE, plutôt : il mange tout
   l'espace libre à sa gauche, qu'il ait un voisin ou non. « Suivant »
   est ainsi au même endroit du pouce sur les six écrans — ce que le
   commentaire d'avant promettait sans le faire.
   --------------------------------------------------------------- */
.dossier-pas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* `[data-suivant]` est « Suivant » ; `.auth-submit` est « Déposer » et
   « Renvoyer », qui sont seuls sur leur rangée et avancent aussi. */
.dossier-pas [data-suivant],
.dossier-pas .auth-submit { margin-left: auto; }

/* `.auth-cta` prend toute la largeur — c'est juste pour une carte de connexion
   à un bouton, faux pour une rangée qui en porte deux. */
.dossier-pas .auth-cta,
.dossier-pas .auth-submit {
  width: auto;
  min-width: 8rem;
  margin-top: 0;
}

/* ── « SUIVANT », PÂLE TANT QUE L'ÉTAPE N'EST PAS FAITE ────────────────────
   La maquette : *« Next button becomes clickable when step is satisfied »*.

   ⚠️ IL RESTE CLIQUABLE, ET C'EST DÉLIBÉRÉ. Un `disabled` pour de vrai piège :
   la sauvegarde part au `change`, c'est-à-dire quand on QUITTE un champ — et
   on le quitte le plus souvent en cliquant le bouton, dont le clic serait
   alors avalé par le désarmement. La personne aurait rempli sa dernière
   réponse et se retrouverait devant un bouton mort. Sans script, ce serait
   pire : plus aucun geste ne recalculerait l'état.

   Ce qui reste est ce qui compte — on VOIT que l'étape n'est pas finie — et le
   refus, lui, vit dans `DossierController`, avec le nom de ce qui manque. Un
   bouton pâle n'a jamais été une serrure.

   `data-arme` ARME plutôt qu'il ne désarme : un bouton auquel personne n'a
   rien posé est donc net. La feuille est servie à tout le monde, le script pas
   toujours, et un attribut manquant doit tomber du bon côté. */
.dossier-pas [data-suivant]:not([data-arme]) { opacity: 0.5; }

/* ---------------------------------------------------------------
   LE SOMMAIRE DES REFUS — `.field-errors`, mais avec des liens
   ---------------------------------------------------------------
   La boîte vient d'`auth.css` ; ce qui est écrit ici, c'est ce que ses
   liens deviennent DANS un fond d'alerte. Un lien à l'encre d'accent sur
   du rouge pâle se lit mal et se voit encore plus mal en daltonien : il
   emprunte donc l'encre de la boîte et garde son soulignement, qui est
   ce qui dit « cliquable » sans la couleur (§0, règle 8).
   --------------------------------------------------------------- */
.field-errors a {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
}

/* L'anneau est `--c-danger` et NON `--c-danger-soft` : la boîte a déjà
   `--c-danger-soft` pour fond, donc l'anneau doux y serait invisible — un
   focus qu'on ne voit pas est un focus qui n'existe pas pour qui navigue au
   clavier, et c'est précisément le public de ces liens-là. */
.field-errors a:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--c-danger);
}

/* La boîte reçoit le focus au chargement (voir `candidature.js`) : elle est
   déjà bordée et colorée, un anneau de plus ne dirait rien. */
.field-errors:focus { outline: none; }

/* UN ENVOI EN VOL. Le bouton se désarme le temps de la requête — deux
   « Déposer » d'affilée sont un doigt qui doute, pas deux demandes. Il
   garde son mot : « Enregistrement… » sur le bouton irréversible dirait
   le contraire de ce qui se passe. */
.dossier [data-en-vol] {
  opacity: 0.6;
  cursor: default;
}

/* LA PROSE DU DÉPÔT — le seul endroit du formulaire qui EXPLIQUE avant de
   demander. Partout ailleurs les phrases d'aide meurent (« as little text to
   read as possible ») ; ici le texte est le contenu, donc il se lit à la taille
   du texte courant et pas à celle d'une note de bas de champ. */
.dossier-prose {
  margin: 0 0 var(--space-4);
  font-size: var(--mil-fs-3);
  color: var(--c-text-mid);
  max-width: 60ch;               /* la longueur de ligne où l'œil ne saute pas */
}

/* ---------------------------------------------------------------
   LE REÇU — l'écran d'après le dépôt
   ---------------------------------------------------------------
   Il n'a pas de rail, donc pas de grille : `.dossier` est en `grid` à
   partir de 900 px, avec une colonne de 16rem pour une navigation qui
   n'existe pas ici. Une seule colonne, alignée sur la même largeur de
   lecture que le formulaire.

   ⚠️ `.dossier.dossier-recu` ET PAS `.dossier-recu` SEUL. Les deux
   pèsent (0,1,0), et la règle de grille vit dans une `@media` plus BAS
   dans le fichier : à poids égal c'est l'ordre qui tranche, donc la
   grille gagnait. Le reçu sortait dans la colonne de 16 rem prévue pour
   un rail absent — le rang, l'identité et le bouton empilés sur cent
   quatre-vingts pixels. Une requête de média ne change RIEN au poids
   d'un sélecteur, et c'est le piège : la règle a l'air plus
   spécifique parce qu'elle est conditionnelle.
   --------------------------------------------------------------- */
.dossier.dossier-recu { display: block; }

/* CE QUI A ÉTÉ DÉPOSÉ, en trois lignes. Une liste sans puces : ce sont des
   faits, pas une énumération — et la puce ferait lire « trois choses » là où
   il n'y a qu'une identité. */
.recu-identite {
  margin: 0 0 var(--space-5);
  padding: 0;
  list-style: none;
  font-size: var(--mil-fs-3);
  color: var(--c-text);
}

.recu-identite li { margin: 0 0 var(--space-1); }

/* ── UNE LISTE DE FAITS, ET ELLE NE PEUT PAS EMPRUNTER `.rows` ────────────
   `.rows` et `.list-row` vivent dans `app.css`, que `layouts/plain` ne charge
   JAMAIS. Les employer ici rendait une liste à PUCES : la classe existe, le
   garde du dépôt la trouve — dans la mauvaise feuille — et l'écran sort brut.
   C'est la panne des liens de magasin du 2026-08-25, à l'identique.

   Une classe à nous, donc, et le minimum : ni bordure ni fond, la section les
   porte déjà. */
.dossier-liste {
  margin: 0;
  padding: 0;
  list-style: none;
}

.dossier-liste li {
  padding: var(--space-2) 0;
  font-size: var(--mil-fs-3);
  color: var(--c-text);
}

/* Un filet ENTRE les lignes, jamais sous la dernière : le bas de la liste est
   déjà celui de sa section. */
.dossier-liste li + li { border-top: 1px solid var(--c-border); }

/* ── LE RETRAIT, ET POURQUOI IL SE VOIT VENIR ──────────────────────────────
   C'est le seul geste du candidat qui FERME son dossier : l'horloge de purge
   part, et le rang ne revient pas. La section porte donc le liseré de danger,
   comme la sortie porte l'encre rouge au survol — le geste se voit venir avant
   de partir.

   Pas de fond rouge : la section n'est pas une alarme, elle est une porte. Ce
   qui alarme, c'est de l'ouvrir. */
.dossier-retrait { border-left: 3px solid var(--c-danger); }

/* Le bouton, lui, PORTE le rang du danger — c'est lui qui fait la chose. Le
   message est écrit juste au-dessus, donc la couleur ne porte rien toute seule
   (§0, règle 8). */
.auth-submit-danger {
  border-color: var(--c-danger);
  background: var(--c-danger);
}

.auth-submit-danger:hover {
  border-color: var(--c-danger-text);
  background: var(--c-danger-text);
}

/* Le rang, une fois qu'il est posé. La seule chose de cet écran qui mérite
   d'être vue avant le reste. */
.dossier-rang {
  margin: 0 0 var(--space-5);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  background: var(--c-accent-soft);
  color: var(--c-text);
  font-size: var(--mil-fs-3);
}

@media (min-width: 900px) {
  .dossier {
    display: grid;
    grid-template-columns: 16rem minmax(0, 1fr);
    gap: var(--space-6);
    align-items: start;
  }

  .dossier-nav-zone { top: calc(var(--doc-entete-h) + var(--space-2)); }

  /* À 900 px la navigation est une COLONNE : elle ne recouvre plus le
     document, donc une ancre n'a que la barre à dégager. */
  :root { --doc-ancre: calc(var(--doc-entete-h) + var(--space-4)); }

  .dossier-nav {
    display: block;
    overflow-x: visible;
    margin: 0;
    padding: 0;
  }

  .dossier-nav li { margin: 0 0 var(--space-1); }

  .dossier-corps { min-width: 0; }

  /* Deux champs courts par ligne quand la place existe. La grille et pas un
     `flex-wrap` : le repli y passe avant le rétrécissement, et une colonne qui
     ondule se lit moins bien qu'une qui rétrécit. */
  .dossier-paire {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
  }
}

/* ---------------------------------------------------------------
   L'ÂGE DES ENFANTS — une boîte par enfant, sur une ligne
   ---------------------------------------------------------------
   C'était une zone de texte de deux lignes où l'on écrivait « 4 ans,
   7 ans et demi, et le grand a 11 ». Eric, 2026-09-09 : « 1 line with
   as many small text boxes as number of children ». Le formulaire
   sait combien ils sont — on l'a demandé deux questions plus haut —
   donc la forme du champ peut le dire.

   Elles SE REPLIENT malgré la ligne : six boîtes de 3,5 rem tiennent
   partout, mais la charte interdit de parier sur une largeur, et un
   zoom texte à 200 % suffit à la démentir. Ce qui compte est qu'elles
   soient CÔTE À CÔTE, pas qu'elles tiennent sur une rangée physique.
   --------------------------------------------------------------- */

.dossier-ages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: 0;
  border: 0;
  margin: 0;
}

/* Le `<legend>` sort du flux de son `<fieldset>` : il ne se laisse pas ranger
   par le `flex` du parent. `float` le remet dans la rangée sans lui retirer son
   rôle — c'est lui qui dit à la voix que les six boîtes sont une question. */
.dossier-ages > legend {
  float: left;
  width: 100%;
  padding: 0;
  margin-bottom: var(--space-2);
}

/* `.dossier-champ input[type="text"]` (0,2,1) pose la largeur pleine des
   champs du dossier et bat une classe seule. On monte donc au même niveau
   plutôt que de poser un `!important` — la règle qu'on bat est nommée, et
   celle-ci dit pourquoi elle gagne. */
.dossier-ages > input[type="text"] {
  width: 3.5rem;
  min-width: 0;
  text-align: center;
}
