/* ---------------------------------------------------------------
   L'IMPLICATION — le formulaire trimestriel, dans SES DEUX COQUILLES
   ---------------------------------------------------------------

   ── POURQUOI CETTE FEUILLE EXISTE (2026-09-05) ──────────────────────────────
   Ces règles vivaient dans `auth.css`, et l'argument écrit ici disait qu'elles
   ne pouvaient pas vivre ailleurs : « la coquille nue n'a pas de pile de
   feuilles à empiler — elle en charge quatre, fixées dans son `<head>` — donc
   tout écran qui s'y accroche s'habille ici ou ne s'habille pas ».

   La prémisse a cessé d'être vraie le jour où cet écran-ci a eu DEUX coquilles.
   Eric, 2026-09-05 : *« if the user is connected the main shared menu should be
   there »*. Une session ouvre le formulaire dans `layouts/app` — le rail, la
   barre d'écran, la fenêtre figée ; un lien de courriel l'ouvre toujours dans
   `layouts/plain`. Un écran servi par deux coquilles ne peut pas s'habiller
   dans la feuille de l'une d'elles, et c'est exactement la panne des liens de
   magasin du 2026-08-25, prise à l'envers : là, une règle vivait dans `app.css`
   pour un écran qui ne la chargeait jamais.

   Les DEUX coquilles chargent celle-ci, comme elles chargent `magasins.css` et
   pour la même raison.

   ── CE QUI EST VENU AVEC, ET CE QUI EST RESTÉ ───────────────────────────────
   `.field`, `.check`, `.field-help` et `.visually-hidden` existent dans
   `app.css` COMME dans `auth.css` : les champs se dessinent donc des deux
   côtés sans que rien ne bouge. `.auth-panel` et `.auth-submit`, non — ils sont
   propres à la coquille nue. Le panneau et le bouton d'envoi ont donc pris
   leurs classes à eux (`.impl-part`, `.impl-envoi`), écrites ici, identiques
   dans les deux coquilles. Ce n'est pas un jeu de champs parallèle : ce sont
   les deux seules pièces que les deux feuilles ne nommaient pas pareil.

   ── LE CADRE VIENT TOUJOURS DU DOSSIER DE CANDIDATURE ───────────────────────
   Eric, 2026-09-02 : « Match Candidature layout with comités as the sidebar. »
   `.dossier`, `.dossier-nav-zone`, `.dossier-nav`, `.dossier-corps` et
   `.dossier-reste` sont écrits, mesurés et commentés dans `candidature.css`.
   `layouts/plain` la charge pour tous ses écrans ; `layouts/app` la pousse par
   `@push('styles')` pour celui-ci seulement. L'emprunt tient — deux cadres
   jumeaux divergent au premier ajustement, et personne ne renomme jamais celui
   qu'on a dupliqué.

   Ce qui vit ici est ce que ce cadre-là ne connaît pas : un rail facultatif,
   une coche d'état, une promesse en tête de document, et le décalage du
   collant quand il n'y a pas de barre de document au-dessus.
   --------------------------------------------------------------- */

/* PAS DE RAIL POUR UN SEUL COMITÉ — seize rem pour redire le titre du panneau
   d'à côté.

   ⚠️ DEUX CLASSES, ET ON LES GARDE. `.dossier` passe en grille dans une
   `@media` de `candidature.css`, et une requête de média ne change rien au
   poids d'un sélecteur : `.impl-seul` seul pèserait autant que `.dossier`,
   donc c'est l'ORDRE qui trancherait. Il joue en notre faveur depuis que ces
   règles ont leur feuille — les deux coquilles chargent `candidature.css`
   d'abord, celle-ci ensuite — mais un ordre de chargement est ce qui change le
   jour où quelqu'un range un `<head>`, et le poids ne change pas. C'est la
   leçon déjà payée par `.dossier.dossier-recu`. */
.dossier.impl-seul { display: block; }

/* ── DANS LA COQUILLE DE L'APP — ET DANS LE CARNET — RIEN NE COLLE AU-DESSUS
   DU RAIL. Le carnet ouvre la page sans aucune en-tête (2026-10-11), même
   raison, même remise à zéro. ─────────────────────────────────────────────
   `candidature.css` cale le rail du document sous la barre de marque
   (`top: var(--doc-entete-h)`, 8 rem) et arrête les ancres au même endroit.
   Dans `layouts/app` cette barre n'existe pas : la barre d'écran est HORS de
   la zone qui défile, donc huit rem de vide s'ajouteraient au-dessus du rail
   et une ancre atterrirait huit rem trop bas.

   Les deux variables sont donc remises à zéro sur le cadre, et pas sur
   `:root` : c'est le même document, servi par deux coquilles, et la valeur de
   `candidature.css` reste la bonne pour l'autre. */
.dossier.impl-dans-app {
  --doc-entete-h: 0px;
  --doc-ancre: var(--space-4);
}

/* LA PROMESSE EN TÊTE DE DOCUMENT — qui verra quoi, en entier, une fois.

   Un liseré et pas une carte : elle n'est ni un avertissement ni une
   confirmation, et lui donner un fond la mettrait au même rang que les
   panneaux de comité, qu'elle surplombe. Le trait suffit à dire « ceci vaut
   pour tout ce qui suit ». */
.impl-promesse {
  margin: 0 0 var(--space-5);
  padding: var(--space-2) 0 var(--space-2) var(--space-4);
  border-left: 3px solid var(--c-border);
}

/* La première ligne colle au haut du liseré : `.impl-vu` porte une marge
   haute qui la sépare du champ qui la précède SUR un bloc, et il n'y a rien
   au-dessus d'elle ici. */
.impl-promesse > .impl-vu:first-child { margin-top: 0; }

/* LA COCHE DU RAIL — « ce comité porte déjà quelque chose ».

   Elle est TOUJOURS rendue et c'est la visibilité qui la montre, jamais
   `display` : la place du signe reste prise, donc la ligne du rail ne saute
   pas de deux pixels quand il apparaît sous les doigts. Le script n'a qu'un
   attribut à poser — il n'écrit aucun texte, et la couleur vient déjà de
   `.dossier-reste[data-complet]`. */
.impl-fait { visibility: hidden; }

.impl-fait[data-complet] { visibility: visible; }

/* UN VOLET = UN DOMAINE (T1, 2026-09-03), ou les heures d'un comité
   (2026-10-06). Le volet ne dessine rien, il groupe : le nom, le panneau, le
   repli des indicateurs. La marge est sur lui et non sur le
   formulaire — c'est lui qui se répète, et les volets s'empilent quand le
   script ne tourne pas. */
.impl-volet {
  margin-bottom: var(--space-4);
  /* UNE ANCRE S'ARRÊTE SOUS CE QUI COLLE, et c'est le chemin SANS script que
     ça sert : là, le rail est une liste d'ancres pour de vrai, et le panneau
     visé atterrirait sous la barre — on cliquerait « Entretien » pour voir le
     deuxième champ d'Entretien, sans son titre. Avec le script, le geste ne
     passe plus par l'ancre : il remonte la page en entier, pour que la
     promesse de visibilité reste à l'écran. */
  scroll-margin-top: var(--doc-ancre);
}

/* LA GARDE DE `hidden`, écrite alors que rien ne l'exige encore. `.impl-part`
   ne pose aucun `display` aujourd'hui ; le jour où elle en posera un, l'attribut
   que le script met sur les volets fermés cesserait de cacher — la feuille de
   l'agent le pose sans classe, donc avec une spécificité de 0. Le défaut serait
   muet partout ailleurs et ouvrirait les seize volets d'un coup ici. */
.impl-volet[hidden] { display: none; }

/* OÙ ON EST — « Toute la coop », ou le nom du comité, au-dessus du domaine.

   Petit et sourd, comme un fil d'Ariane : la question qui compte est le NOM du
   domaine juste en dessous, et un membre de trois comités a besoin de savoir
   duquel on parle sans que ça vienne se disputer la première lecture. */
.impl-ou {
  margin: 0;
  font-size: var(--mil-fs-1);
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

/* LE TITRE D'UN GROUPE DU RAIL. Un `<p>` et pas un `<li>` : une entrée de liste
   se ferait annoncer comme une destination, et « Toute la coop » n'en est pas
   une — c'est ce qui explique pourquoi ces quatre questions-là ne se répètent
   pas sous chaque comité. */
.impl-groupe {
  margin: var(--space-4) 0 var(--space-1);
  font-size: var(--mil-fs-1);
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.impl-groupe:first-child { margin-top: 0; }

/* LE CRITÈRE — la question, en gros, tout de suite (charte, règle 2).

   Il est plus grand que le corps et pas en gras : c'est ce qu'on lit avant de
   choisir, donc il doit se lire en un coup d'œil, mais il n'est pas un titre —
   le titre est le nom du domaine, au-dessus. */
.impl-critere {
  margin: var(--space-3) 0 0;
  font-size: var(--mil-fs-3);
  line-height: 1.45;
}

/* ── LES QUATRE GROS BOUTONS, À LA PREMIÈRE PERSONNE ───────────────────────
   Eric, PLAN-PARTICIPATION §4.3 : « quatre gros boutons ». Des boutons radio
   dans UN groupe — les cinq réponses sont exclusives, et deux champs séparés
   auraient laissé un navigateur envoyer les deux.

   Ils s'empilent au téléphone et s'alignent au-delà : la cible tactile est de
   44 px de haut dans les deux cas (système de design, règle 9), et une rangée
   de quatre à 375 px donnerait quatre cases de 80 px où le mot ne tient pas. */
.impl-crans-moi {
  border: 0;
  padding: 0;
  margin: var(--space-4) 0 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Le bouton est le LABEL, et le radio vit dedans : c'est ce qui rend toute la
   surface cliquable au doigt sans une ligne de script, et ce qui garde le
   clavier et le lecteur d'écran d'accord avec l'œil. */
.impl-cran-moi {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius);
  background: var(--c-surface);
  cursor: pointer;
  transition: border-color var(--t-base), background var(--t-base);
}

.impl-cran-moi:hover { border-color: var(--c-accent); }

/* L'ÉTAT CHOISI SE VOIT PAR LA BORDURE ET LE FOND, et le point du radio reste
   là : la couleur ne porte jamais l'état toute seule (règle 8 du système de
   design). Quelqu'un en niveaux de gris voit le rond plein ; quelqu'un qui lit
   à voix haute entend « sélectionné ». */
.impl-cran-moi:has(input:checked) {
  border-color: var(--c-accent);
  background: var(--c-accent-soft);
}

/* L'anneau de focus signature, sur le bouton entier plutôt que sur le rond :
   c'est la boîte qu'on voit, donc c'est elle qui doit s'allumer. */
.impl-cran-moi:has(input:focus-visible) {
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-soft);
}

.impl-cran-mot {
  font-size: var(--mil-fs-3);
  font-weight: 500;
}

/* « SANS OBJET » EST DERRIÈRE LES QUATRE. Pas de cadre, pas de fond : c'est la
   sortie, pas un cinquième cran. Elle reste une cible de 44 px — être rare ne
   veut pas dire être difficile à viser. */
.impl-sans-objet {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  margin-top: var(--space-1);
  font-size: var(--mil-fs-2);
  color: var(--c-text-mid);
  cursor: pointer;
}

/* ── LA VERSION FINE, DERRIÈRE UN REPLI (charte, règle 2) ──────────────────
   Les indicateurs et la source de vérification de §5.2. Un `<details>` nu :
   il s'ouvre sans script, il se lit sans souris, et ce qu'il cache n'est jamais
   nécessaire pour répondre — le critère au-dessus suffit. */
.impl-fin {
  margin-top: var(--space-3);
  font-size: var(--mil-fs-2);
  color: var(--c-text-mid);
}

.impl-fin summary {
  cursor: pointer;
  padding: var(--space-2) 0;
  color: var(--c-text-mid);
}

.impl-fin-titre {
  margin: var(--space-2) 0 var(--space-1);
  font-weight: 600;
  color: var(--c-text);
}

.impl-fin-liste {
  margin: 0;
  padding-left: var(--space-4);
}

.impl-nom {
  font-size: var(--mil-fs-4);
  font-weight: 700;
  margin: 0;
}

/* LA DERNIÈRE DÉCLARATION, sous le nom du comité. Sourde et petite : c'est un
   repère, pas une consigne — la seule chose qu'elle doit faire est de répondre
   « oui, tu l'as déjà fait, il y a un an » avant qu'on relise les champs pour
   le deviner. */
.impl-derniere {
  margin: var(--space-1) 0 0;
  font-size: var(--mil-fs-1);
  color: var(--c-text-muted);
}

/* ── UN COMITÉ, UN PANNEAU ─────────────────────────────────────────────────
   Eric, 2026-09-05 : « The forms don't need to be split in sections. »

   Il y en a eu deux du 2026-09-02 au 2026-09-05 : une carte nominative, une
   carte anonyme avec son propre fond, pour que la frontière se voie de loin.
   Ce que ça donnait, le rail compris, c'est un document coupé deux fois — une
   par comité, une par régime — pour six champs. Le rail coupe déjà ; ce qui
   est dedans se lit d'un trait.

   Le nom du comité et sa date restent DEHORS, au-dessus : ils valent pour tout
   ce qui suit, et les poser dans le panneau les rattacherait au premier champ.

   ⚠️ CE QUI NE DOIT PAS PARTIR AVEC LES BOÎTES : la frontière. Elle vit
   maintenant dans `.impl-anonyme` — du blanc, et l'étiquette `.impl-vu` juste
   avant les champs qu'elle décrit. C'est la règle 6 de la charte appliquée à
   la lettre : le mot porte l'information, le fond ne la portait qu'en plus.

   ── LE DESSIN DU PANNEAU EST ÉCRIT ICI DEPUIS LE 2026-09-05 ────────────────
   Il était emprunté à `.auth-panel`, qui n'existe que dans `auth.css` : dans
   la coquille de l'app, le panneau serait sorti sans bord, sans fond et sans
   marge intérieure. `app.css` a bien un `.panel`, mais s'en servir demanderait
   une classe qui change avec la coquille — c'est-à-dire deux formes du même
   écran, et la garantie qu'elles divergent. Les quatre déclarations sont donc
   ici, une fois, pour les deux. */
.impl-part {
  margin-top: var(--space-4);
  padding: var(--space-5);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  background: var(--c-surface);
}

/* LE CHANGEMENT DE RÉGIME, DANS LE MÊME PANNEAU.

   Le blanc est plus large que celui qui sépare deux champs (`--space-6` contre
   `--space-4`), et c'est tout ce qu'il a à faire : on descend en tapant, donc
   la frontière doit se sentir sous les doigts avant de se lire. Pas de filet,
   pas de fond — l'un et l'autre rendraient la coupe que la demande retire. */
.impl-anonyme { margin-top: var(--space-6); }

/* ── LE BLOC CONFIDENTIEL SE VOIT (Eric, 2026-10-11) ───────────────────────
   « Confidential sections must be clearly identified. » Le blanc seul ne
   suffisait pas : dans un écran où chaque comité empile cinq blocs, le
   commentaire anonyme passait pour un champ de plus des heures. Il prend un
   fond à lui et un liseré d'accent — le MOT « Confidentiel » porte toujours
   l'information (règle 6), le fond aide à trouver le bloc en défilant. */
.impl-part.impl-anonyme {
  background: var(--c-accent-soft);
  border-color: var(--c-accent);
  border-left-width: 4px;
}

.impl-vu-anonyme .impl-vu-mot { color: var(--c-accent-dark); }

/* LE NOM D'UN BLOC dans la section de son comité : sous le titre du comité,
   au-dessus de l'étiquette de visibilité. */
.impl-bloc-nom {
  margin: 0;
  font-size: var(--mil-fs-3);
  font-weight: 700;
}

/* Qui lit ce bloc-ci, à côté du mot. */
.impl-vu-qui { color: var(--c-text-mid); }

/* « Toute la coop » vient APRÈS les comités, et s'en détache d'un blanc :
   ce n'est pas un comité de plus. */
.impl-nav-coop {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--c-border);
}

/* L'ÉTIQUETTE DE VISIBILITÉ.

   Elle se pose SOUS le titre du bloc et AU-DESSUS des champs qu'elle décrit —
   la seule place où elle est lue avant qu'on écrive. Posée en bas, elle serait
   une mention légale ; posée là, elle est une consigne.

   Aucun fond, aucune couleur d'état : ce n'est ni un avertissement ni une
   confirmation, et l'habiller en `warning` ferait lire « attention » là où on
   dit simplement « voici qui verra ». La règle 6 de la charte vaut ici comme
   ailleurs — le mot porte l'information, pas la couleur. */
.impl-vu {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
  margin: var(--space-2) 0 0;
  font-size: var(--mil-fs-2);
  color: var(--c-text-mid);
}

/* Le dessin est décoratif et se tient à la hauteur du mot, pas à la sienne. */
.impl-vu svg {
  width: 16px;
  height: 16px;
  flex: none;
  align-self: center;
}

/* Deux mots, en gras : c'est ce qui se lit en balayant, et c'est la partie de
   la promesse qui doit survivre à quelqu'un qui ne lit pas la phrase. */
.impl-vu-mot {
  font-weight: 600;
  color: var(--c-text);
}

/* La phrase prend toute la largeur restante, ou passe à la ligne — elle est la
   promesse en entier, et une promesse tronquée par un `ellipsis` serait pire
   que pas de promesse du tout. */
.impl-vu-dit { flex: 1 1 100%; }

/* LE BOUTON D'ENVOI — même raison que `.impl-part` juste au-dessus : il était
   `.auth-submit`, qui n'existe que dans la coquille nue. Il garde le dessin de
   son modèle au pixel, parce que c'est le même geste au bas du même genre de
   document, et que les deux se regardent l'un après l'autre le jour où on
   ajuste la porte d'entrée. */
.impl-envoi {
  display: block;
  width: 100%;
  min-height: 44px;
  margin-top: var(--space-5);
  padding: var(--space-3) var(--space-4);
  font: inherit;
  font-size: var(--mil-fs-3);
  font-weight: 600;
  text-align: center;
  border: 1px solid var(--c-accent);
  border-radius: var(--radius-sm);
  background: var(--c-accent);
  color: var(--c-on-accent);
  cursor: pointer;
  transition: background var(--t-fast);
}

.impl-envoi:hover { background: var(--c-accent-dark); border-color: var(--c-accent-dark); }

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

.impl-envoi:active { transform: scale(0.98); }

/* ── LA PÉRIODE ET L'AVANCEMENT, DANS LA BARRE D'ÉCRAN ─────────────────────
   Eric, 2026-09-05, sur la maquette C1 : la cérémonie ne descend pas dans le
   document, elle tient dans la zone d'états de la barre — « ce qui est vrai de
   la section maintenant », ce que cette zone est faite pour porter.

   Deux choses seulement : de quel trimestre on parle, et combien de comités
   sont déjà remplis. La seconde n'existait NULLE PART avant aujourd'hui — le
   rail dit lesquels, il ne dit pas combien il en reste, et il faut le compter
   du regard.

   Rien de tout ça n'est rendu dans la coquille nue : là, le titre et la
   période sont le `<h1>` et son chapô, et il n'y a pas de barre. */
.impl-etat {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  white-space: nowrap;
}

.impl-etat svg {
  width: 16px;
  height: 16px;
  flex: none;
}

/* LA JAUGE — `.board-meter` fait tout le dessin (`app.css`, la même jauge que
   `/profil` et les appréciations) ; il ne reste ici que la largeur, parce
   qu'une barre d'écran n'est pas une ligne de tableau : la sienne fait 4 rem
   au lieu de la pleine largeur d'une cellule.

   ⚠️ ÉCRITE ICI ET PAS DANS `app.css` avec sa base : cette feuille-là est
   chargée par UNE des deux coquilles. La jauge, elle, ne se rend que dans
   celle qui a une barre — donc `.board-meter` est toujours là quand
   `.impl-jauge` sert, et jamais l'inverse. */
.impl-jauge { width: 4rem; }

/* ── ET ELLE DISPARAÎT SUR UN TÉLÉPHONE ────────────────────────────────────
   La rangée d'états a une hauteur FIXE : ce qui n'y tient pas ne descend pas,
   il se fait défiler (voir `<x-app-header>`). À 390 px, mesuré, la rangée
   demande 384 px pour 358 disponibles — et ce qui sort par la droite est la
   fin de « 2 comités sur 6 », c'est-à-dire la seule moitié qui porte.

   La jauge vaut 4 rem plus sa gouttière, donc la retirer rend soixante-huit
   pixels et fait tenir la phrase. C'est le bon sacrifice et pas un pis-aller :
   elle est `aria-hidden`, elle ne dit rien que la phrase ne dise, et elle
   existe pour l'œil qui balaie une barre large. C'est le même arbitrage que
   les pilules du dossier de candidature à 820 px, pris dans l'autre sens —
   là c'est le mot qui sort et le dessin qui reste, parce que là le dessin
   porte un geste et pas une mesure. */
@media (max-width: 700px) {
  .impl-jauge { display: none; }
}

/* ── T3 : LE DOSSIER REÇU, SA RÉPONSE EN FACE DE LA LEUR ──────────────────
   Un domaine = un bloc, deux lignes : ce que la personne a dit, ce que ses
   évaluateurs ont écrit. L'une AU-DESSUS de l'autre et non côte à côte : à
   375 px, deux colonnes donnent deux mots par ligne, et c'est l'écran qu'on
   tient à la main qui décide (charte, §2 — le téléphone est le design). */
.impl-face {
  padding: var(--space-3) 0;
  border-top: 1px solid var(--c-border);
}

.impl-face:first-child { border-top: 0; padding-top: 0; }

.impl-face-nom {
  margin: 0 0 var(--space-2);
  font-size: var(--mil-fs-3);
  font-weight: 700;
}

.impl-face-mienne,
.impl-face-leur {
  margin: 0 0 var(--space-1);
}

/* QUI PARLE, en petites capitales sourdes. C'est la seule chose qui distingue
   les deux lignes, et elle ne peut pas être une couleur : la règle 6 vaut ici
   plus qu'ailleurs — on lit ce qu'on a dit soi contre ce qu'on a écrit de
   nous, et confondre les deux serait le pire malentendu de l'écran. */
.impl-face-qui {
  display: inline-block;
  min-width: 9rem;
  font-size: var(--mil-fs-1);
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

/* Les faits que les évaluateurs ont écrits : en retrait, comme une citation.
   §5.4 les exige datés et factuels — ce sont eux qui rendent un cran
   défendable, donc ils se lisent, ils ne se survolent pas. */
.impl-face-faits {
  margin: var(--space-1) 0 0 9rem;
  font-size: var(--mil-fs-2);
  color: var(--c-text-mid);
