﻿/* ==========================================================================
   Projector — surcharges du système de design (Hope UI).

   Volontairement mince. Elle ne touche ni `body`, ni les surfaces de travail :
   celles-ci restent celles du système de design. Ce qu'elle pose, c'est la
   couleur d'action, les marques de santé et d'état, et l'indentation de l'arbre.

   Registre : graphite et un seul accent. Les couleurs qui portent un sens —
   retard, arrêt, tension — ne sont pas décoratives et ne doivent pas se
   confondre avec l'accent, sans quoi tout l'écran semble alerter.

   Aucun style n'est écrit en attribut `style=` dans les gabarits : la CSP
   l'ignorerait, et la mise en page se déferait sans qu'aucune erreur ne le dise.
   ========================================================================== */

:root {
  --pj-encre: #1f2328;
  --pj-mute: #656d76;
  --pj-filet: #d8dee4;
  --pj-fond-doux: #f6f8fa;
  /* Un gris **plus creux** que le fond de page, pour les réceptacles.

     Les colonnes du tableau par état employaient `--pj-fond-doux`, c'est-à-dire la
     couleur exacte de la page : elles étaient donc invisibles. Rien ne disait qu'il
     s'agissait de cinq contenants entre lesquels on déplace une carte, et une colonne
     vide se lisait comme une absence plutôt que comme une place libre.

     Creux et non clair : un réceptacle se lit comme un creux, et les cartes blanches
     posées dessus s'en détachent. L'inverse — colonne blanche, cartes grises —
     contredirait le reste de l'outil, où la surface de travail est toujours blanche. */
  --pj-fond-creux: #eaedf1;

  /* Largeur de la zone utile. C'est un logiciel, pas un site : le contenu est
     centré et borné, et le bandeau s'aligne dessus. Sans cette borne, un tableau
     de sept colonnes s'étalait sur 2560 px et l'œil perdait la ligne en la
     parcourant. Généreuse — 1440 px — parce que les écrans de travail sont des
     tableaux et non des colonnes de texte. */
  --pj-largeur: 1440px;
  --pj-gouttiere: 32px;

  /* Le bandeau, foncé. Il ancre la page par le haut : blanc au-dessus d'un fond clair,
     il ne se distinguait du contenu que par son filet et la barre semblait flotter.
     Sombre, il tient l'écran et laisse toute la clarté au travail.

     **C'est l'accent de l'outil, assombri** — même teinte (202°), même saturation (65 %),
     valeur abaissée : 49 % pour l'accent, 39 % pour sa version foncée, 29 % ici. Emprunter un marine à un autre logiciel aurait mis deux
     bleus voisins mais étrangers l'un à l'autre sur le même écran : on le remarque
     immédiatement, sans savoir dire pourquoi. Ici la barre, les liens et les boutons
     principaux sont trois valeurs d'une seule couleur. */
  --pj-bandeau: #1a394a;
  --pj-bandeau-clair: rgba(255, 255, 255, .12);
  --pj-bandeau-texte: rgba(255, 255, 255, .82);

  /* Accent unique, désaturé : il désigne ce qui se clique, rien d'autre. */
  --pj-accent: #2c5f7c;
  --pj-accent-clair: #eaf1f5;
  /* Les deux extrémités du dégradé des panneaux de carte. Le foncé était écrit en
     dur pour le survol du bouton principal : deux endroits pour la même teinte
     finissent par diverger. */
  --pj-accent-vif: #35729a;
  --pj-accent-fonce: #234c63;

  /* Le thème des surfaces, posé une fois. Il vient de la maquette de carte du
     18 août 2026 : angles francs, ombre douce, **aucune bordure** — une bordure
     par-dessus une ombre donne un contour dur qui contredit le flou.

     En variables et non recopié : sept surfaces le portent — blocs, cartes,
     modales, filtres, écran de connexion — et sept valeurs à la main auraient
     divergé au premier réglage. */
  /* La surface de travail. Écrite `#fff` en dur dans `.bloc` et dans la carte : deux
     endroits pour la même teinte finissent par diverger, et trois règles du Gantt
     appelaient déjà un `--pj-surface` qui n'existait pas — leur fond tombait donc dans
     le vide, et la colonne d'intitulés collante laissait passer les barres dessous. */
  --pj-surface: #fff;

  --pj-rayon: 0;
  --pj-rayon-doux: 0;
  /* L'ombre est l'autre moitié de l'écart entre le fond et le contenu : le motif
     recule, la carte avance. Deux couches — une large et diffuse qui décolle, une
     serrée qui pose le bord. Une seule ombre large donnait un halo mou dont on ne
     voyait pas la limite. */
  --pj-ombre: 0 8px 22px rgba(26, 57, 74, .10), 0 1px 2px rgba(26, 57, 74, .10);
  --pj-ombre-haute: 0 12px 28px rgba(31, 35, 40, .14), 0 2px 6px rgba(31, 35, 40, .08);
  --pj-degrade: linear-gradient(135deg, var(--pj-accent-vif), var(--pj-accent) 55%,
                                var(--pj-accent-fonce));

  /* Sémantiques. Empruntées à Bootstrap mais assourdies : une table de
     soixante lignes dont dix clignotent en rouge vif ne se lit pas. */
  --pj-retard: #b42318;
  --pj-arret: #7a5c00;
  --pj-tension: #8a5a00;
  --pj-actif: #1a7f4b;
  --pj-repos: #8c959f;

  /* Les terres du motif de fond. Bogolan : ocre, terre de Sienne, indigo, brun,
     olive, brique — les teintes que donnent réellement la boue fermentée et les
     écorces, et c'est ce qui les accorde entre elles.

     **Variées, mais toutes dans la même valeur.** C'est la seule règle qui compte
     ici : six teintes de clarté voisine se lisent comme une palette choisie, alors
     que les mêmes six à des clartés différentes se lisent comme un accident. Une
     seule trop claire ou trop foncée, et tout le fond paraît sale.

     Elles ne portent **aucun sens** et ne doivent jamais servir ailleurs : le
     registre de l'outil reste graphite et un seul accent. Un dessin de fond qui
     emprunterait le rouge du retard ferait alerter la page entière. */
  --motif-ocre: #8a6128;
  --motif-rouille: #a2512c;
  --motif-indigo: #3d6580;
  --motif-brun: #75543d;
  --motif-olive: #5f653a;
  --motif-brique: #9a4c40;
}

/* --------------------------------------------------------------------------
   Reprises de Hope UI, prévues pour sa variante à barre latérale
   -------------------------------------------------------------------------- */
/* Trois réserves se cumulaient sur riskassessor-v2 et enfermaient les tableaux
   dans un couloir central. Elles sont reprises d'emblée ici. */
.main-content { margin-left: 0; }
.content-inner { margin-top: 0 !important; }

/* Convention anglaise de Hope UI : elle donnait « Tableau De Bord ».
   `!important` nécessaire, la règle d'origine en portant un. */
.menu__entree,
.dropdown-item { text-transform: none !important; }

/* --------------------------------------------------------------------------
   Coque
   -------------------------------------------------------------------------- */
body { background: var(--pj-fond-doux); }

/* --------------------------------------------------------------------------
   Motif de fond — bogolan, à l'encre
   --------------------------------------------------------------------------
   Ce que la version d'origine écrivait en `style=` est ici, et c'est nécessaire : la
   CSP interdit `unsafe-inline`, donc un `style="position:absolute;opacity:.13"` aurait
   été **ignoré sans aucune erreur**. Le motif se serait affiché à pleine opacité, en
   position statique, poussant tout le contenu vers le bas.

   `fixed` et non `absolute` : absolu, il s'étirerait sur la hauteur du document et se
   déformerait sur une page longue. Fixe, il est posé une seule fois dans la vue — ce
   qui est le propre d'un tissu.

   L'opacité est basse — les surfaces de travail sont des cartes blanches opaques, le
   motif ne se voit que dans les gouttières, et c'est là qu'il doit rester. Au-delà de
   .10 il commence à concurrencer le contenu. */
.motif {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  /* Sans cela, il intercepterait chaque clic de la page. */
  pointer-events: none;
  /* **Bas, et c'est le sujet.** Ce qui fait qu'un fond se lit comme un fond, ce n'est
     pas son dessin mais l'écart qu'il laisse au contenu : à 15 % les formes venaient
     au premier plan et l'œil hésitait entre elles et les cartes. Retiré à 6 %, le
     motif donne une matière au papier et le travail flotte nettement dessus.

     La couleur y survit — juste : les terres restent reconnaissables comme terres,
     alors qu'à 3 % elles ne seraient plus qu'un gris. C'est le plancher, et le test
     le borne des deux côtés. */
  opacity: .06;
  /* La teinte de repli, pour tout dessin auquel aucune terre n'est assignée. */
  color: var(--pj-encre);
}

/* Les terres, une par forme. Elles vivent dans la feuille et non dans le gabarit :
   une teinte écrite en attribut serait la seule du projet à échapper à la palette,
   et l'on ne saurait plus où la changer.

   `color` et non `fill`/`stroke` : le dessin est écrit tout entier en
   `currentColor`, donc poser la couleur sur le groupe suffit — contours et
   remplissages suivent, y compris sur les formes imbriquées. */
.motif__soleil    { color: var(--motif-ocre); }
.motif__hexagone  { color: var(--motif-indigo); }
.motif__losanges  { color: var(--motif-rouille); }
.motif__peigne    { color: var(--motif-olive); }
.motif__chevrons  { color: var(--motif-brun); }
.motif__ligne     { color: var(--motif-indigo); }
.motif__points    { color: var(--motif-brique); }
.motif__griffes   { color: var(--motif-olive); }
.motif__semis     { color: var(--motif-brun); }
.motif__brique    { color: var(--motif-brique); }
/* Un fond d'encre à l'impression noircirait la page pour rien. */
@media print {
  .motif { display: none; }
}

.contenu {
  max-width: var(--pj-largeur);
  margin: 0 auto;
  padding: 22px var(--pj-gouttiere) 56px;
  /* Au-dessus du motif : sans `position`, le contenu resterait dans le même plan et
     le motif passerait par-dessus le texte. */
  position: relative;
  z-index: 1;
}

/* --------------------------------------------------------------------------
   Le mobilier de page sur des cartes
   --------------------------------------------------------------------------
   Depuis que le motif habite le fond, **rien ne doit plus reposer directement
   dessus** : un titre ou une barre d'onglets posés à même le dessin s'y confondent,
   et l'on perd la limite entre ce qui est le fond et ce qui est l'outil.

   Titre, onglets et filtres reçoivent donc la même surface que les blocs de contenu.
   Le motif ne paraît plus qu'entre les cartes — ce qui est exactement le rôle d'un
   fond de tissu : se voir dans les intervalles, jamais sous le texte.

   Le filet inférieur du titre disparaît : sur une carte il faisait une seconde
   limite à trois pixels de la première, et l'ensemble paraissait cerné deux fois. */
.entete-page {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
  padding: 14px 18px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
}
/* Un en-tête vide — les écrans qui n'ont ni titre ni action — laisserait une carte
   blanche de trente pixels, sans rien dedans. `:has()` la retire. */
.entete-page:not(:has(.entete-page__titre:not(:empty))):not(:has(.bouton)) {
  display: none;
}
.entete-page__titre { margin: 0; font-size: 1.3rem; font-weight: 600; letter-spacing: -.01em; }
/* Le chemin **est** le titre : « Suivi / RiskAssessor v2 ». Il y avait un fil
   d'Ariane au-dessus, et le dossier s'y trouvait nommé deux fois à dix pixels d'écart.

   Le parent est en gris et de graisse normale : c'est un chemin de retour, pas la
   moitié d'un titre. Sans cet écart, la ligne se lirait comme un nom en deux mots. */
.entete-page__parent {
  color: var(--pj-mute);
  font-weight: 400;
  font-size: .95rem;
}
.entete-page__parent:hover { color: var(--pj-accent); }
.entete-page__separateur {
  margin: 0 8px;
  color: var(--pj-filet);
  font-weight: 400;
}
.entete-page__actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }

.fil {
  font-size: .82rem;
  color: var(--pj-mute);
  margin-bottom: 12px;
  padding: 8px 18px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
}
.fil a { color: var(--pj-mute); }
.fil a:hover { color: var(--pj-accent); }

/* --------------------------------------------------------------------------
   Toasts
   -------------------------------------------------------------------------- */
/* Hors du flux : un bandeau inséré en tête de contenu décalait tout l'écran d'une
   ligne à chaque enregistrement, et la table qu'on venait de modifier sautait sous
   le curseur. */
.toasts {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 120;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(380px, calc(100vw - 40px));
  /* Le conteneur ne doit pas intercepter les clics sur le contenu qu'il survole ;
     les toasts eux-mêmes les reprennent. */
  pointer-events: none;
}
.toast-pj {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 12px;
  background: var(--pj-surface);
  border: 1px solid var(--pj-filet);
  border-radius: var(--pj-rayon);
  box-shadow: 0 8px 24px rgba(31, 35, 40, .14);
  font-size: .88rem;
}
/* La couleur est portée par un filet vertical, pas par le fond : un aplat vert ou
   rouge plein écran fait plus de bruit que la confirmation qu'il annonce. */
.toast-pj__marque { flex: 0 0 3px; align-self: stretch; background: var(--pj-mute); }
.toast-pj--success .toast-pj__marque { background: var(--pj-actif); }
.toast-pj--warning .toast-pj__marque { background: var(--pj-tension); }
.toast-pj--error .toast-pj__marque   { background: var(--pj-retard); }
.toast-pj--info .toast-pj__marque    { background: var(--pj-accent); }

.toast-pj__texte { margin: 0; flex: 1; line-height: 1.4; }
.toast-pj__fermer {
  flex: 0 0 auto;
  background: none;
  border: 0;
  font-size: 1.15rem;
  line-height: 1;
  color: var(--pj-mute);
  cursor: pointer;
  padding: 0 2px;
}
.toast-pj__fermer:hover { color: var(--pj-encre); }

/* Effacement piloté par le script. `prefers-reduced-motion` est respecté : une
   translation surprise est désagréable pour qui l'a désactivée. */
.toast-pj--sortant { opacity: 0; transform: translateX(12px); }
.toast-pj { transition: opacity .2s ease, transform .2s ease; }
@media (prefers-reduced-motion: reduce) {
  .toast-pj { transition: none; }
}
@media (max-width: 760px) {
  .toasts { right: 10px; left: 10px; bottom: 10px; width: auto; }
}

/* --------------------------------------------------------------------------
   Bandeau
   -------------------------------------------------------------------------- */
.bandeau {
  background: var(--pj-bandeau);
  /* Plus de filet d'accent : sur fond marine il ne se voyait pas, et la limite du
     bandeau est déjà donnée par le contraste avec la page. */
  border-bottom: 0;
  position: sticky;
  top: 0;
  z-index: 30;
}
.bandeau__inner {
  display: flex;
  align-items: center;
  gap: 20px;
  /* La barre tient sur une ligne. Sans cette règle, le bloc de droite bascule
     sous le menu et le menu du compte se retrouve au milieu. */
  flex-wrap: nowrap;
  /* Alignée sur la zone utile : le sceau se trouve à l'aplomb du contenu, et le
     menu du compte à l'aplomb du bord droit du tableau. Un bandeau pleine largeur
     au-dessus d'un contenu centré donne deux grilles qui ne se répondent pas. */
  max-width: var(--pj-largeur);
  margin: 0 auto;
  padding: 8px var(--pj-gouttiere);
}

/* Bouton de repli du menu, visible seulement quand la barre ne tient plus. */
.bandeau__bascule {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px; height: 32px;
  margin-left: auto;
  background: none;
  border: 1px solid var(--pj-bandeau-clair);
  border-radius: var(--pj-rayon);
  color: #fff;
  cursor: pointer;
}
.bandeau__bascule:hover { border-color: rgba(255, 255, 255, .4); }
.bandeau__bascule span {
  /* Trois barres dessinées par des bordures : pas d'image à charger, pas de
     police d'icônes, et la couleur suit celle du texte. */
  display: block;
  width: 16px;
  border-top: 2px solid currentColor;
  border-bottom: 6px double currentColor;
  height: 10px;
}
.bandeau__identite {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: #fff;
  /* L'identité cède la première : le nom est de toute façon repris ailleurs. */
  min-width: 0;
  overflow: hidden;
}
.bandeau__noms { display: flex; flex-direction: column; min-width: 0; }
.bandeau__nom {
  font-weight: 600;
  font-size: .95rem;
  /* Tronqué comme l'accroche : sans `overflow`, `nowrap` empêchait le bloc de
     se réduire et poussait le menu du compte hors de l'écran. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bandeau__accroche {
  font-size: .7rem;
  color: rgba(255, 255, 255, .6);
  text-transform: uppercase;
  letter-spacing: .04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --------------------------------------------------------------------------
   Cartes et tableaux
   -------------------------------------------------------------------------- */
/* La surface de base de toute l'application. Elle porte le thème de la carte :
   c'est par elle qu'il s'applique à tous les écrans d'un coup.

   `overflow: hidden` pour que les coins d'un tableau logé dedans suivent l'arrondi.
   Aucun panneau levé ne vit dans un `.bloc` — c'est le propre des cartes de dossier,
   qui n'en sont pas. */
.bloc {
  background: var(--pj-surface);
  border: 0;
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
  overflow: hidden;
  margin-bottom: 18px;
}
.bloc__titre {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--pj-filet);
  font-size: .78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--pj-mute);
}
/* Le côté droit d'un titre de bloc porte un lien ou une précision, en casse
   normale : le laisser en petites capitales le faisait lire comme un second titre. */
.bloc__titre-droite {
  display: inline-flex; align-items: center; gap: 8px;
  text-transform: none; letter-spacing: 0; font-weight: 400;
}
.colonne-actions { width: 1%; white-space: nowrap; text-align: right; }
.actions-groupe { display: inline-flex; gap: 6px; align-items: center; }
.etat-en-ligne { display: inline-flex; gap: 4px; align-items: center; }
.etat-en-ligne select { padding: 3px 6px; font-size: .78rem; border: 1px solid var(--pj-filet);
  border-radius: var(--pj-rayon); background: var(--pj-surface); color: var(--pj-encre); }
.bloc__corps { padding: 18px; }
.bloc__corps--serre { padding: 0; }
/* Une note à l'intérieur d'un bloc. Elle remplace le bandeau bleu de Bootstrap :
   sur la carte de passation, un `alert-info` pleine largeur criait plus fort que le
   document qu'il commentait. */
.note-bloc {
  margin: 0 0 14px;
  font-size: .84rem;
  color: var(--pj-mute);
  border-left: 3px solid var(--pj-filet);
  padding-left: 10px;
}

.grille { display: grid; gap: 16px; }

/* `min(380px, 100%)` et non `380px` seul : une piste de grille dont le minimum
   dépasse la largeur disponible **ne se réduit pas**, et la carte débordait de
   19 px sur un écran de 375 px — sans erreur, la page se contentant de défiler
   horizontalement. `min()` autorise la piste à descendre sous son minimum quand il
   n'y a plus la place. */
.grille--deux { grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr)); }
/* 300 px et non 260 : en dessous, une table de propriétés à deux colonnes se casse
   en trois lignes par entrée, et les trois cartes de la synthèse deviennent
   illisibles avant de passer à deux colonnes. */
.grille--trois { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }

/* --------------------------------------------------------------------------
   Tableau des états — le travail en colonnes
   --------------------------------------------------------------------------
   Les colonnes défilent horizontalement **dans leur conteneur** : cinq colonnes ne
   tiennent pas sur un téléphone, et le corps de page ne doit jamais défiler en
   largeur. `minmax(240px, 1fr)` et non `1fr` seul — une colonne réduite à 40 px ne
   reçoit plus rien à la souris. */
.tableau-etats {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(240px, 1fr);
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 6px;
  align-items: start;
}
/* La teinte de l'étape, portée par `data-couleur` et posée sur une seule variable
   locale. Le gabarit ne nomme aucune couleur — l'écrire là l'aurait sortie de la
   palette — et chaque règle ci-dessous lit `--etape`.

   **Les teintes ne sont pas décoratives.** « Bloquée » est rouge parce que c'est un
   ennui, « Faite » verte parce que c'est réglé, « Abandonnée » éteinte parce qu'il n'y
   a plus rien à en attendre, « À faire » graphite parce que rien ne s'y passe encore.
   Peindre les cinq colonnes de cinq couleurs gaies aurait fait un tableau qui ne dit
   rien — et l'écran entier semblerait alerter. */
[data-couleur="a_faire"]    { --etape: var(--pj-mute); }
[data-couleur="en_cours"]   { --etape: var(--pj-accent); }
[data-couleur="bloquee"]    { --etape: var(--pj-retard); }
[data-couleur="faite"]      { --etape: var(--pj-actif); }
[data-couleur="abandonnee"] { --etape: var(--pj-repos); }

.colonne-etat {
  /* Voir `--pj-fond-creux` : la colonne employait la couleur de la page et n'existait
     donc pas à l'œil. */
  background: var(--pj-fond-creux);
  border-radius: var(--pj-rayon);
  padding: 0 0 10px;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
/* Le survol de dépôt se voit : sans marque, on relâche sans savoir où. */
.colonne-etat--survolee {
  background: var(--pj-accent-clair);
  box-shadow: inset 0 0 0 2px var(--pj-accent);
}

/* Le rail de progression a été **retiré** le 21 août 2026.

   C'était un trait avec un point par colonne, emprunté à la frise du cycle. Il suggérait
   une progression linéaire d'« À faire » vers « Abandonnée » — ce que les états ne sont
   pas : on ne traverse pas « Bloquée » pour atteindre « Faite », et « Abandonnée » n'est
   pas l'aboutissement de quoi que ce soit. Décoratif, donc, et trompeur.

   Ce qui répond vraiment à « où en est-on » est la barre empilée de `.avancement`, posée
   au-dessus du tableau : elle montre la part de chaque état, et le chiffre au-dessus dit
   combien de tâches sont faites sur combien. Cinq compteurs côte à côte obligeaient à
   les additionner de tête. */

/* Un **bandeau** et non une ligne de texte : c'est lui qui fait lire la colonne comme un
   contenant. Blanc sur le creux, il en marque le haut sans ajouter de couleur. */
.colonne-etat__entete {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 9px 12px;
  margin-bottom: 10px;
  background: var(--pj-surface);
  border-top: 2px solid var(--etape, var(--pj-filet));
}
.colonne-etat__titre {
  margin: 0; font-size: .82rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
  /* La couleur de l'étape sur le titre, pas sur un aplat de fond : un fond teinté par
     colonne ferait cinq bandes de couleur derrière le contenu qu'on vient lire. */
  color: var(--etape, var(--pj-mute));
}
/* Le compte en pastille : un nombre nu à côté du titre se lisait comme une partie du
   titre. Teinté de l'étape, il redit sa couleur là où l'œil arrive. */
.colonne-etat__compte {
  font-size: .74rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--etape, var(--pj-mute));
  background: var(--pj-fond-creux);
  padding: 1px 7px;
}
/* Une hauteur minimale : une colonne vide sans surface ne peut recevoir aucun dépôt. */
.colonne-etat__pile {
  display: flex; flex-direction: column; gap: 10px;
  min-height: 72px;
  padding: 0 10px;
  flex: 1;
}
/* Une **zone de dépôt** et non la phrase « Rien ici ». Le texte gris se lisait comme une
   absence — « il n'y a rien à voir » — alors qu'il faut dire l'inverse : la place est
   libre, on peut y poser une carte. Le liseré tireté est la convention de ce geste. */
.colonne-etat__vide {
  margin: 0;
  padding: 18px 8px;
  font-size: .76rem;
  text-align: center;
  color: var(--pj-mute);
  border: 1px dashed var(--pj-filet);
  background: rgba(255, 255, 255, .5);
}

/* La carte porte la teinte de son étape **sur un filet vertical**, pas en aplat.

   C'est la décision déjà prise pour les toasts : un fond rouge ou vert plein fait plus
   de bruit que ce qu'il annonce, et une colonne de six cartes rouges se lirait comme
   une avarie générale. Le filet suffit à ranger la carte d'un coup d'œil, et le texte
   reste sur blanc — donc lisible. */
.carte-tache {
  background: var(--pj-surface);
  border-radius: var(--pj-rayon-doux);
  box-shadow: var(--pj-ombre);
  border-left: 3px solid var(--etape, var(--pj-filet));
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: box-shadow .16s ease, transform .16s ease;
}
/* `grab` seulement pour qui peut déplacer : un curseur de préhension sur une carte
   qu'on ne peut pas bouger promet un geste que la vue refusera. */
.carte-tache[draggable="true"] { cursor: grab; }
.carte-tache[draggable="true"]:hover {
  box-shadow: var(--pj-ombre-haute);
  transform: translateY(-1px);
}
.carte-tache--glissee { opacity: .45; cursor: grabbing; }
@media (prefers-reduced-motion: reduce) {
  .carte-tache { transition: none; }
  .carte-tache[draggable="true"]:hover { transform: none; }
}
/* Une tâche close n'a plus à réclamer l'attention : son titre s'éteint. Barré, il
   serait illisible sur une carte qu'on ouvre encore pour la relire. */
.carte-tache[data-couleur="faite"] .carte-tache__titre,
.carte-tache[data-couleur="abandonnee"] .carte-tache__titre { color: var(--pj-mute); }
.carte-tache__titre { font-weight: 600; font-size: .86rem; overflow-wrap: anywhere; }
.carte-tache__marques {
  margin: 0; display: flex; flex-wrap: wrap; gap: 6px;
  align-items: center; font-size: .76rem;
}
.carte-tache__echeance { color: var(--pj-mute); font-variant-numeric: tabular-nums; }
.carte-tache__pied { display: flex; flex-direction: column; gap: 6px; }
.carte-tache__qui { font-size: .76rem; color: var(--pj-mute); overflow-wrap: anywhere; }
/* --------------------------------------------------------------------------
   Volet d'état — le recours au glisser-déposer, replié
   --------------------------------------------------------------------------
   Il était déployé sur chaque carte : une liste d'états et un bouton « Déplacer », soit
   la moitié de la hauteur d'une carte, répétée autant de fois qu'il y a de tâches. Sur
   un tableau de vingt cartes, une colonne entière d'écran dépensée à offrir deux fois le
   même geste.

   Replié, il ne coûte plus qu'une ligne. La forme est reprise d'un composant à panneau
   révélé au survol ; ce qui en a été gardé est le **mécanisme** — un panneau flottant,
   une flèche vers son déclencheur — et non la décoration : un dégradé violet-rose, des
   angles très arrondis et un halo flou auraient été les seuls de l'outil, dont tout le
   registre est graphite, un accent, et des angles francs.

   Ce qui a été **ajouté** au composant d'origine, en revanche, est décisif : il ne
   s'ouvrait qu'au survol. Ici c'est un `<details>`, donc il s'ouvre aussi au clic, au
   doigt et au clavier. Un panneau réservé à la souris aurait retiré à qui navigue au
   clavier — et à tout usage sur téléphone, où le glisser-déposer HTML5 ne se déclenche
   pas — le seul moyen de déplacer une tâche. */
.volet-etat { position: relative; }
.volet-etat__declencheur {
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer;
  font-size: .74rem;
  font-weight: 600;
  color: var(--pj-mute);
  /* Une puce de triangle par-dessus le libellé ferait deux marques pour une idée. */
  list-style: none;
}
.volet-etat__declencheur::-webkit-details-marker { display: none; }
.volet-etat__declencheur:hover,
.volet-etat[open] .volet-etat__declencheur { color: var(--pj-accent); }
/* L'état courant à côté du déclencheur : replié, le volet doit tout de même dire où en
   est la tâche, sans quoi il faut l'ouvrir pour le savoir. */
.volet-etat__actuel {
  font-weight: 400;
  color: var(--pj-mute);
  border-left: 2px solid var(--etape, var(--pj-filet));
  padding-left: 6px;
}

/* Le panneau **flotte** : dans le flux, il aurait repoussé les cartes suivantes à
   chaque ouverture, et la colonne aurait sauté sous la main. */
.volet-etat__panneau {
  position: absolute;
  z-index: 5;
  bottom: calc(100% + 8px);
  left: 0;
  /* `min()` : sur un téléphone, 210 px de panneau dans une colonne de 180 px
     débordaient de l'écran, sans erreur — la page défilait latéralement. */
  width: min(210px, 78vw);
  /* **`none`, et c'est le point.** Un `display` posé ici écrase le masquage natif du
     `<details>` fermé : les panneaux restaient tous ouverts en permanence, flottants
     au-dessus des cartes voisines. Rien n'était donc regagné — et surtout, avec
     `z-index: 5`, ils interceptaient le curseur : on croyait saisir une carte, on
     saisissait un panneau, et le dépôt se résolvait sur la colonne du panneau au lieu de
     celle qu'on visait. Le glisser-déposer paraissait mort, sans une seule erreur.

     Le `display: flex` vit désormais dans la règle d'ouverture, plus bas. */
  display: none;
  flex-direction: column; gap: 2px;
  padding: 8px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre-haute);
}
.volet-etat__titre {
  margin: 0 0 4px;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--pj-mute);
}
/* Un bouton par état : un clic au lieu de deux — la liste, puis « Déplacer ». Le liseré
   reprend la couleur de l'état, la même que sur les colonnes et les étiquettes. */
.volet-etat__choix {
  display: block;
  width: 100%;
  text-align: left;
  padding: 5px 8px;
  font-size: .8rem;
  color: var(--pj-encre);
  background: none;
  border: 0;
  border-left: 3px solid var(--etape, var(--pj-filet));
  cursor: pointer;
}
.volet-etat__choix:hover { background: var(--pj-fond-doux); color: var(--pj-accent); }
/* L'état courant : montré mais inerte. Le retirer aurait fait quatre boutons ici et
   cinq ailleurs, et l'on chercherait lequel manque. */
.volet-etat__choix:disabled {
  color: var(--pj-mute);
  cursor: default;
  background: var(--pj-fond-doux);
}

/* La flèche vers le déclencheur, reprise du composant d'origine : sans elle, un panneau
   flottant au-dessus d'une pile de cartes ne dit pas de laquelle il parle. */
.volet-etat__panneau::after {
  content: "";
  position: absolute;
  bottom: -5px; left: 16px;
  width: 10px; height: 10px;
  background: var(--pj-surface);
  transform: rotate(45deg);
  /* Sous le panneau dans l'ordre de peinture, sinon son coin recouvre le bord. */
  z-index: -1;
}

/* Les trois façons de l'ouvrir. Le clic sur le `<summary>` est la seule qui existe sans
   feuille de style — les deux autres sont des raccourcis.

   **Le survol est réservé à la souris** : `[data-glisser="oui"]` n'est posé par le script
   que si le pointeur est fin, et au doigt un survol ouvrirait le panneau au premier
   effleurement du défilement.

   **Et il est suspendu pendant un glissement.** Sans cela, passer au-dessus d'une carte
   en glissant y ouvrait son panneau, lequel se retrouvait sous le curseur : le dépôt se
   résolvait alors sur la colonne de ce panneau et non sur celle qu'on visait. Un panneau
   flottant qui s'ouvre au survol et une surface de dépôt ne peuvent pas se partager le
   même pixel. */
.volet-etat[open] .volet-etat__panneau,
.volet-etat:focus-within .volet-etat__panneau,
[data-glisser="oui"]:not([data-en-glissement]) .volet-etat:hover .volet-etat__panneau {
  display: flex;
}

/* Bascule d'arrangement, sous la barre d'onglets : plus discrète qu'elle, sans quoi on
   ne saurait plus laquelle porte la position dans l'application. */
.onglets--secondaires { border-bottom: 0; margin-bottom: 14px; gap: 4px; }
.onglets--secondaires .onglet { font-size: .82rem; padding: 5px 10px; }

/* --------------------------------------------------------------------------
   Volet des filtres
   --------------------------------------------------------------------------
   Les filtres occupaient un bandeau plein sur des écrans dont ils ne sont pas le
   sujet — sur le tableau des états, la première carte commençait sous la ligne de
   flottaison. Repliés, ils rendent la place au contenu.

   `<details>` et non un panneau piloté par script : replié par défaut, il n'encombre
   pas, et il s'ouvre sans JavaScript. */
.volet-filtres {
  margin-bottom: 14px;
  padding: 10px 18px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
}
.volet-filtres__declencheur {
  display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer;
  font-size: .82rem; font-weight: 600; color: var(--pj-mute);
  /* Une puce de triangle par-dessus le libellé ferait deux marques pour une idée. */
  list-style: none;
}
.volet-filtres__declencheur::-webkit-details-marker { display: none; }
.volet-filtres__declencheur:hover { color: var(--pj-accent); }
.volet-filtres[open] .volet-filtres__declencheur { color: var(--pj-accent); }
/* « filtre actif » en mots et non par la seule couleur : la couleur ne se transmet pas
   à qui ne la voit pas, et c'est précisément l'information qu'il ne faut pas manquer. */
.volet-filtres__marque {
  font-weight: 500;
  color: var(--pj-accent);
  background: var(--pj-accent-clair);
  padding: 1px 7px;
  font-size: .74rem;
}
/* La rangée reprend l'aspect qu'elle avait, une fois dépliée. */
.volet-filtres .filtres { margin-top: 10px; margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Cheminement d'une tâche
   -------------------------------------------------------------------------- */
/* Trois colonnes à pas fixe : la date, le passage, l'auteur. Alignées d'une ligne à
   l'autre, sans quoi l'œil qui descend la colonne des dates la perdrait. */
.chemin { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.chemin__etape {
  display: grid;
  grid-template-columns: minmax(0, 11ch) 1fr minmax(0, 14ch);
  align-items: center;
  gap: 12px;
  font-size: .82rem;
}
.chemin__date { color: var(--pj-mute); font-variant-numeric: tabular-nums; }
.chemin__passage { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chemin__fleche { color: var(--pj-mute); }
.chemin__acteur {
  color: var(--pj-mute); text-align: right;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Graphiques du tableau de bord
   --------------------------------------------------------------------------
   Rendus par le serveur, sans JavaScript : la CSP interdit `unsafe-inline` et tout
   hôte externe. Les couleurs sont **ici** et non dans le SVG — une teinte écrite en
   attribut serait la seule du projet à échapper à la palette. */
.graphe { display: flex; flex-direction: column; gap: 4px; }
/* `preserveAspectRatio="none"` étire la toile : la hauteur est donc fixée ici, et la
   largeur suit le bloc. Sans cela, huit semaines laissaient deux tiers du bloc vides. */
.graphe__toile { width: 100%; height: 96px; display: block; }
.graphe__barre { fill: var(--pj-accent); }

/* La légende est du texte HTML, pas des `<text>` SVG : étirés par la toile, ils
   auraient été déformés en largeur. Une piste de grille par barre, donc alignée. */
.graphe__legende {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 0;
}
.graphe__pas { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.graphe__valeur { font-size: .8rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.graphe__libelle { font-size: .66rem; color: var(--pj-mute); white-space: nowrap; }
.graphe__note { margin: 10px 0 0; display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  font-size: .78rem; color: var(--pj-mute); }

/* Classement en barres horizontales. La jauge fournit la largeur — vingt et un
   paliers en classes, la CSP ignorant une largeur en attribut de style. */
.rangs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.rangs__ligne {
  display: grid;
  /* Libellé, piste, valeur. Le libellé est borné pour que les pistes s'alignent d'une
     ligne à l'autre : sans cela, « Correctifs et évolutions » décalait sa barre et le
     classement ne se comparait plus. */
  grid-template-columns: minmax(0, 11ch) 1fr auto;
  align-items: center;
  gap: 10px;
  font-size: .8rem;
}
.rangs__libelle { color: var(--pj-mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rangs__valeur { font-variant-numeric: tabular-nums; font-weight: 600; }

/* --------------------------------------------------------------------------
   Cartes de dossier — l'écran de suivi
   --------------------------------------------------------------------------
   Dessin repris d'une maquette du 18 août 2026 : panneau à dégradé débordant au-
   dessus de la carte, angles très arrondis, ombre portée douce, bouton en capitales.

   `auto-fill` et non `auto-fit`, et ce n'est pas indifférent : `auto-fit` effondre
   les pistes vides, et un dossier seul s'étirait alors sur les 1440 px de la zone
   utile. `auto-fill` garde les pistes, donc la carte garde sa taille.

   `min(340px, 100%)` pour la même raison que les autres grilles : une piste dont le
   minimum dépasse la largeur disponible **ne se réduit pas**, et la carte débordait
   de la page sur un téléphone — sans erreur, l'écran se contentant de défiler
   horizontalement.

   L'écart vertical doit rester **supérieur à la levée du panneau** (22 px), sans quoi
   le panneau d'une rangée mordrait sur la carte de la rangée précédente. */
.cartes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
  gap: 36px 18px;
  /* La première rangée doit laisser la place à la levée : sans cela le panneau passe
     sous le filet de l'en-tête de page. */
  padding-top: 22px;
}

.carte-dossier {
  display: flex;
  flex-direction: column;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
  transition: box-shadow .18s ease, transform .18s ease;
  /* **Jamais `overflow: hidden`** : il rognerait le panneau, qui déborde exprès.
     C'est la seule surface de l'application dans ce cas. */
}
.carte-dossier:hover {
  box-shadow: var(--pj-ombre-haute);
  transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
  .carte-dossier { transition: none; }
  .carte-dossier:hover { transform: none; }
}

/* Le panneau. Il monte de 22 px au-dessus de la carte et se resserre de 16 px de
   chaque côté : c'est ce décalage qui donne l'impression d'une vignette posée sur la
   carte plutôt que d'un bandeau collé dedans. */
.carte-dossier__panneau {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: -22px 16px 0;
  padding: 16px 18px;
  border-radius: var(--pj-rayon-doux);
  background: var(--pj-degrade);
  box-shadow: 0 6px 16px rgba(44, 95, 124, .32);
  color: #fff;
  text-decoration: none;
  /* Un nom long en un seul mot élargirait la carte au-delà de sa piste de grille. */
  min-width: 0;
}
.carte-dossier__panneau:hover { color: #fff; }
.carte-dossier__titre {
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
/* Blanc atténué, et non gris : un gris sur le dégradé perd son contraste dans le
   coin foncé. */
.carte-dossier__code { font-size: .76rem; color: rgba(255, 255, 255, .82); }
.carte-dossier__code code { color: inherit; }
/* La pastille de santé garde son fond clair : c'est ce qui la rend lisible sur le
   dégradé, et sa couleur continue de signifier. */
.carte-dossier__panneau .sante { align-self: flex-start; margin-top: 8px; background: var(--pj-surface); }

.carte-dossier__corps {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 18px 18px;
  flex: 1;
}

.carte-dossier__marques { margin: 0; display: flex; flex-wrap: wrap; gap: 6px; }

/* Phase et avancement sur une ligne, la barre en dessous, sur toute la largeur : deux
   colonnes de grille, la barre occupant les deux. */
.carte-dossier__cycle {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 6px 10px;
}
.carte-dossier__part {
  font-size: .8rem;
  color: var(--pj-mute);
  font-variant-numeric: tabular-nums;
}
.carte-dossier__cycle .jauge__piste { grid-column: 1 / -1; }

/* Une ligne de séparation avant les mesures, plutôt qu'un fond : elle marque le
   passage de la description à la mesure sans ajouter de couleur. */
.carte-dossier__mesures {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--pj-filet);
}
.carte-dossier__mesures .mesure { min-width: 0; }
.mesure__libelle {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--pj-mute);
  font-weight: 600;
}
.mesure__valeur {
  margin: 2px 0 0;
  font-size: .84rem;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.carte-dossier__pied {
  display: flex;
  align-items: center;
  gap: 10px;
  /* `margin-top: auto` colle le pied en bas : les cartes d'une même rangée ont la
     hauteur de la plus haute, et sans cela le bouton flottait à mi-hauteur. */
  margin-top: auto;
  padding-top: 4px;
}
/* Le master pousse les actions au bord droit, et cède la place avant elles. */
.carte-dossier__master {
  font-size: .8rem;
  color: var(--pj-mute);
  margin-left: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Un tableau large défile dans son propre conteneur : le corps de page ne doit
   jamais défiler horizontalement. */
.table-enveloppe { overflow-x: auto; }
.table { margin: 0; font-size: .87rem; }
.table > thead th {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--pj-mute); font-weight: 600; border-bottom: 1px solid var(--pj-filet);
  white-space: nowrap;
}
.table > tbody td { vertical-align: middle; }
.table code { font-size: .82rem; color: var(--pj-mute); }

.vide { padding: 22px 14px; color: var(--pj-mute); font-size: .88rem; }
/* Dans un bloc ou une cellule, `.vide` est déjà sur une surface. Employé seul comme
   note de bas d'écran, il flottait sur le motif — un texte gris sur un dessin gris,
   qui ne se rattachait à rien. Le sélecteur d'enfant direct de `main` cible ce seul
   cas et laisse les autres intacts. */
.contenu > .vide {
  margin-bottom: 14px;
  padding: 14px 18px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
}

/* Les colonnes de nombres s'alignent à droite et en chiffres de largeur fixe :
   des décomptes ferrés à gauche ne se comparent pas d'une ligne à l'autre. */
.table .nombre { text-align: right; font-variant-numeric: tabular-nums; }


/* Table de fiche : deux colonnes, l'intitulé en gris, sans filets horizontaux —
   c'est une liste de propriétés, pas un tableau de données à comparer. */
.table--fiche th {
  width: 40%;
  font-weight: 500;
  color: var(--pj-mute);
  font-size: .82rem;
}
.table--fiche > tbody > tr > * { border-bottom-width: 0; padding: 5px 14px; }

/* --------------------------------------------------------------------------
   Chapeau de fiche
   -------------------------------------------------------------------------- */
/* Le chapeau reprend le panneau des cartes : même dégradé, mêmes angles. C'est la
   même chose vue de plus près, et deux traitements pour un même objet feraient douter
   qu'on soit au bon endroit.

   Il **regroupe** ce qui traînait en deux rangées libres sur le fond de page — les
   marques d'un côté, la frise de l'autre. Un écran de détail chargé se calme d'abord
   en réunissant, pas en retirant. */
.chapeau {
  display: flex;
  /* **En colonne depuis la fusion des deux en-têtes** : ligne du titre, puis ligne de
     l'identité et de la frise. En ligne, le titre se serait glissé à côté du résumé. */
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  margin-bottom: 16px;
  padding: 18px 22px;
  border-radius: var(--pj-rayon);
  background: var(--pj-degrade);
  box-shadow: var(--pj-ombre);
  color: #fff;
}
.chapeau__resume { min-width: 260px; flex: 1 1 300px; }
.chapeau__marques { margin: 0; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.chapeau__mesure { font-size: .78rem; color: rgba(255, 255, 255, .82); }
/* Blanc atténué, et non gris : un gris sur le dégradé perd son contraste dans le coin
   foncé. Même traitement que sur la carte de l'écran de suivi. */
.chapeau__code {
  margin: 0 0 8px;
  font-size: .78rem;
  color: rgba(255, 255, 255, .82);
}
.chapeau__code code { color: inherit; }

/* Les marques sur le dégradé. `.origine` et `.etat` sont gris sur fond transparent :
   posées là sans reprise, elles étaient illisibles. La pastille de santé, elle, garde
   son fond clair — c'est ce qui la rend lisible, et sa couleur signifie. */
.chapeau .origine,
.chapeau .etat {
  color: #fff;
  border-color: rgba(255, 255, 255, .45);
  background: rgba(255, 255, 255, .12);
}
.chapeau .sante { background: var(--pj-surface); }

/* La frise dans le chapeau : ses jalons franchis sont à la couleur d'accent, donc
   invisibles sur le dégradé. Elle passe en blanc, l'étape courante cerclée. */
.chapeau .frise__etape::before { background: rgba(255, 255, 255, .3); }
.chapeau .frise__etape--atteinte::before { background: rgba(255, 255, 255, .85); }
.chapeau .frise__jalon { background: transparent; border-color: rgba(255, 255, 255, .55); }
.chapeau .frise__etape--atteinte .frise__jalon { background: var(--pj-surface); border-color: #fff; }
.chapeau .frise__etape--courante .frise__jalon {
  background: var(--pj-accent-fonce);
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, .3);
}
.chapeau .frise__libelle { color: rgba(255, 255, 255, .78); }
.chapeau .frise__etape--courante .frise__libelle { color: #fff; font-weight: 600; }

.sous-titre { font-size: 1.05rem; font-weight: 600; margin: 0 0 14px; }
.ligne-action { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.ligne-action .champ { margin-bottom: 0; min-width: 220px; }

/* --------------------------------------------------------------------------
   Frise du cycle de vie
   -------------------------------------------------------------------------- */
/* Neuf cellules de grille égales : la largeur ne vient d'aucun calcul en
   `style=""`, que la CSP ignorerait — la frise s'effondrerait alors en une pile de
   points, sans erreur. */
/* 640 px et non 520 : à dix phases, une cellule de 52 px est plus étroite que
   « Développement », et les libellés se chevauchaient deux à deux. Le chapeau est un
   `flex` — s'il n'y a pas la place, la frise passe à la ligne sous les marques plutôt
   que de les écraser. */
.frise { flex: 1 1 640px; min-width: 300px; }
.frise__etapes {
  display: grid;
  /* Le nombre d'étapes suit la table des phases, il n'est **pas** écrit ici. Il l'a
     été — `repeat(9, 1fr)` — et la dixième phase ajoutée par l'utilisateur passait à
     la ligne suivante : la frise se cassait en deux, sans aucune erreur. Les colonnes
     implicites en portent autant qu'il y a de `<li>`. */
  grid-auto-flow: column;
  /* `minmax(0, 1fr)` et non `1fr` : `1fr` vaut `minmax(auto, 1fr)`, dont le minimum
     est la largeur du contenu. Les colonnes refusaient donc de descendre sous
     « Développement », la frise dépassait ses 520 px, et la dernière étape sortait du
     panneau où elle était coupée net. Même piège que les grilles de cartes, qui
     débordaient de 19 px sur un téléphone — un test lit cette feuille pour lui. */
  grid-auto-columns: minmax(0, 1fr);
  list-style: none;
  margin: 0;
  padding: 0;
}
.frise__etape { position: relative; text-align: center; padding-top: 14px; }

/* Le trait de liaison est un pseudo-élément, pas une bordure de cellule : une
   bordure aurait laissé un dépassement à chaque extrémité de la frise. */
.frise__etape::before {
  content: "";
  position: absolute;
  top: 4px;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--pj-filet);
}
.frise__etape:first-child::before { left: 50%; }
.frise__etape:last-child::before { right: 50%; }
.frise__etape--atteinte::before { background: var(--pj-accent); }

.frise__jalon {
  position: absolute;
  top: 0;
  left: 50%;
  margin-left: -5px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--pj-surface);
  border: 2px solid var(--pj-filet);
}
.frise__etape--atteinte .frise__jalon { background: var(--pj-accent); border-color: var(--pj-accent); }
/* L'étape courante est cerclée plutôt que grossie : un point plus gros décalerait
   la ligne de jalons d'un pixel et toute la frise semblerait de guingois. */
.frise__etape--courante .frise__jalon {
  background: var(--pj-surface);
  border-color: var(--pj-accent);
  box-shadow: 0 0 0 3px var(--pj-accent-clair);
}

.frise__libelle {
  display: block;
  font-size: .62rem;
  line-height: 1.25;
  color: var(--pj-mute);
  padding: 0 2px;
  /* **Le pli se fait sur les espaces, jamais dans un mot.** `overflow-wrap:
     break-word` a été essayé : il rendait « Développ / ement » et « Correctif / s et /
     évolution / s », illisibles. Un mot un peu plus large que sa cellule la dépasse de
     deux ou trois pixels de chaque côté, ce qui ne gêne personne — la frise, elle, ne
     dépasse plus, et c'est ce que `minmax(0, 1fr)` garantit au-dessus. */
  overflow-wrap: normal;
}
.frise__etape--courante .frise__libelle { color: var(--pj-accent); font-weight: 600; }

/* En cellule de tableau : les jalons seuls, sur une hauteur qui n'écarte pas les
   lignes. Les libellés passent en infobulle. */
.frise--compacte { min-width: 0; flex: none; }
.frise--compacte .frise__etapes { grid-auto-columns: 10px; }
.frise--compacte .frise__etape { padding-top: 10px; }
.frise--compacte .frise__jalon { width: 7px; height: 7px; margin-left: -3.5px; border-width: 1px; }
.frise--compacte .frise__etape::before { top: 3px; }
.frise--compacte .frise__etape--courante .frise__jalon { box-shadow: 0 0 0 2px var(--pj-accent-clair); }

.phase {
  display: inline-block;
  font-size: .78rem;
  font-weight: 600;
  color: var(--pj-encre);
  margin-bottom: 3px;
}

/* --------------------------------------------------------------------------
   Onglets d'un dossier
   -------------------------------------------------------------------------- */
/* Ce sont des liens vers de vraies routes. Le filet inférieur porte l'état actif :
   sur une barre horizontale il se lit mieux qu'un aplat, et il reste visible au
   clavier. */
.onglets {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  border-bottom: 1px solid var(--pj-filet);
  margin-bottom: 14px;
  padding: 0 8px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
}
.onglet {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  font-size: .87rem;
  color: var(--pj-mute);
  text-decoration: none;
  /* Filet transparent au repos : sans lui l'onglet se décalerait d'un pixel en
     devenant actif, et toute la barre sauterait. */
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
}
.onglet:hover { color: var(--pj-encre); border-bottom-color: var(--pj-filet); }
.onglet--actif {
  color: var(--pj-accent);
  font-weight: 600;
  border-bottom-color: var(--pj-accent);
}
.onglet__compteur {
  display: inline-block;
  min-width: 18px;
  padding: 0 5px;
  border-radius: var(--pj-rayon);
  background: var(--pj-fond-doux);
  border: 1px solid var(--pj-filet);
  font-size: .7rem;
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.onglet--actif .onglet__compteur {
  background: var(--pj-accent-clair);
  border-color: var(--pj-accent-clair);
  color: var(--pj-accent);
}

/* --------------------------------------------------------------------------
   Modale
   -------------------------------------------------------------------------- */
/* `<dialog>` natif. Sans JavaScript, l'attribut `open` posé par le serveur affiche
   la boîte en flux — sans fond grisé, mais utilisable : la création reste possible. */
.modale {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: min(720px, 94vw);
  width: 100%;
}
.modale--large { max-width: min(980px, 96vw); }
.modale--confirmation { max-width: min(460px, 94vw); }
.modale__erreurs {
  margin: 14px 18px 0;
  padding: 9px 12px;
  border: 1px solid #f3c9c5;
  border-radius: var(--pj-rayon);
  background: #fdf3f2;
  color: var(--pj-retard);
  font-size: .85rem;
}

.confirmation__cible { font-weight: 600; margin: 0 0 10px; }
.confirmation__intro { margin: 0 0 4px; font-size: .86rem; color: var(--pj-mute); }
.confirmation__consequences {
  margin: 0 0 12px 1.1rem;
  padding: 0;
  font-size: .86rem;
  color: var(--pj-encre);
}
.confirmation__avertissement { margin: 0; font-size: .84rem; color: var(--pj-retard); }

/* --------------------------------------------------------------------------
   Actions de fin de ligne
   -------------------------------------------------------------------------- */
.actions-ligne { display: inline-flex; gap: 2px; white-space: nowrap; }
.action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border-radius: var(--pj-rayon);
  color: var(--pj-mute);
  border: 1px solid transparent;
  /* **Déclaré, et il le faut.** Un `<a>` est en `content-box`, un `<button>` en
     `border-box` par défaut du navigateur : la même règle de 26 px avec une bordure d'un
     pixel rendait 28 px pour les liens et 26 px pour le bouton de réinitialisation, un
     pixel plus bas que ses voisins. Trois icônes de deux tailles sur une même ligne, et
     rien dans la feuille ne l'expliquait.

     Posé sur `.action` plutôt que sur le bouton seul : la prochaine action écrite avec un
     autre élément aura la bonne taille sans qu'on y pense. */
  box-sizing: content-box;
  /* Les boîtes `inline-flex` s'alignent sur leur ligne de base, qui dépend de leur
     contenu. `middle` les cale sur leur milieu — ce qu'on veut d'une rangée d'icônes de
     même hauteur, et ce qui résiste à un contenu qui changerait. */
  vertical-align: middle;
}
.action:hover { color: var(--pj-accent); border-color: var(--pj-filet); background: var(--pj-surface); }
/* Un `<button>` employé comme icône d'action : il faut le dépouiller de son apparence
   propre, sinon il arrive avec son fond, sa bordure et sa police, et détonne à côté des
   liens qui l'entourent. Il reste un bouton parce que son action est un POST — la
   réinitialisation d'un mot de passe met quelqu'un dehors de sa session, et un lien en GET
   serait déclenchable depuis une page tierce. */
.action-en-ligne { display: inline-flex; margin: 0; }
.action-en-ligne .action {
  background: none;
  font: inherit;
  cursor: pointer;
  padding: 0;
}
/* Grise au repos : la teinter d'emblée ferait de chaque ligne un avertissement. */
.action--risque:hover { color: var(--pj-retard); border-color: #f3c9c5; background: #fdf3f2; }
.modale::backdrop { background: rgba(31, 35, 40, .45); }
.modale__carte {
  background: var(--pj-surface);
  border: 0;
  border-radius: var(--pj-rayon);
  /* Plus portée que les autres surfaces : la boîte flotte au-dessus d'un fond grisé,
     et l'ombre commune ne l'en détacherait pas. */
  box-shadow: 0 18px 48px rgba(31, 35, 40, .22);
  overflow: hidden;
}
.modale__entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--pj-filet);
}
.modale__titre { margin: 0; font-size: 1rem; font-weight: 600; }
.modale__fermer {
  background: none;
  border: 0;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--pj-mute);
  cursor: pointer;
  padding: 0 4px;
}
.modale__fermer:hover { color: var(--pj-encre); }
/* La hauteur est bornée : un formulaire plus haut que l'écran doit défiler dans la
   carte, jamais emporter la page derrière lui. */
.modale__corps { padding: 18px; max-height: min(66vh, 620px); overflow-y: auto; }
.modale__pied {
  display: flex;
  gap: 10px;
  padding: 14px 18px;
  border-top: 1px solid var(--pj-filet);
  background: var(--pj-fond-doux);
}

/* --------------------------------------------------------------------------
   Santé, états, priorités
   -------------------------------------------------------------------------- */
.sante, .etat, .priorite, .retard, .origine {
  display: inline-block;
  padding: 1px 8px;
  border-radius: var(--pj-rayon);
  font-size: .72rem;
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid;
}
.sante--retard  { color: var(--pj-retard); border-color: #f3c9c5; background: #fdf3f2; }
.sante--arret   { color: var(--pj-arret);  border-color: #e8dca8; background: #fdf9ec; }
.sante--tension { color: var(--pj-tension); border-color: #ecd9b0; background: #fdf8ef; }
.sante--actif   { color: var(--pj-actif);  border-color: #bfe0cd; background: #f2faf5; }
.sante--repos   { color: var(--pj-repos);  border-color: var(--pj-filet); background: var(--pj-fond-doux); }

.etat { font-weight: 500; color: var(--pj-mute); border-color: var(--pj-filet);
  background: var(--pj-fond-doux); }
.etat--en_cours { color: var(--pj-accent); border-color: #c6d9e3; background: var(--pj-accent-clair); }
.etat--bloquee  { color: var(--pj-retard); border-color: #f3c9c5; background: #fdf3f2; }
.etat--faite    { color: var(--pj-actif);  border-color: #bfe0cd; background: #f2faf5; }

/* Seules les priorités hautes portent une couleur : teinter les quatre ferait
   de chaque ligne un avertissement. */
.priorite--3 { color: var(--pj-tension); border-color: #ecd9b0; background: #fdf8ef; }
.priorite--4 { color: var(--pj-retard); border-color: #f3c9c5; background: #fdf3f2; }

.retard { color: #fff; background: var(--pj-retard); border-color: var(--pj-retard); }
.origine { color: var(--pj-mute); border-color: var(--pj-filet); background: transparent;
  font-weight: 500; }

/* --------------------------------------------------------------------------
   Avancement
   -------------------------------------------------------------------------- */
.jauge {
  display: flex; align-items: center; gap: 8px;
  min-width: 110px;
}
.jauge__piste {
  flex: 1; height: 5px;
  background: var(--pj-filet); overflow: hidden;
}
.jauge__part { height: 100%; background: var(--pj-accent); display: block; }
.jauge__valeur { font-size: .76rem; color: var(--pj-mute); font-variant-numeric: tabular-nums; }

/* La largeur d'une jauge vient des données : elle ne peut pas être écrite en
   `style=""`, que la CSP ignore. Vingt et un paliers de 5 % suffisent — une
   jauge n'a pas besoin d'être au pourcentage près. */
.jauge__part--p0   { width: 0; }
.jauge__part--p5   { width: 5%; }
.jauge__part--p10  { width: 10%; }
.jauge__part--p15  { width: 15%; }
.jauge__part--p20  { width: 20%; }
.jauge__part--p25  { width: 25%; }
.jauge__part--p30  { width: 30%; }
.jauge__part--p35  { width: 35%; }
.jauge__part--p40  { width: 40%; }
.jauge__part--p45  { width: 45%; }
.jauge__part--p50  { width: 50%; }
.jauge__part--p55  { width: 55%; }
.jauge__part--p60  { width: 60%; }
.jauge__part--p65  { width: 65%; }
.jauge__part--p70  { width: 70%; }
.jauge__part--p75  { width: 75%; }
.jauge__part--p80  { width: 80%; }
.jauge__part--p85  { width: 85%; }
.jauge__part--p90  { width: 90%; }
.jauge__part--p95  { width: 95%; }
.jauge__part--p100 { width: 100%; }

/* --------------------------------------------------------------------------
   Arbre des fonctionnalités
   -------------------------------------------------------------------------- */
/* Indentation par classes, jamais par `style=""`. La profondeur est bornée à
   trois par les règles d'emboîtement, ce qui rend des classes fixes suffisantes. */
.arbre__decalage--n0 { padding-left: 0; font-weight: 600; }
.arbre__decalage--n1 { padding-left: 22px; }
.arbre__decalage--n2 { padding-left: 44px; color: var(--pj-mute); }

.arbre__incoherence { color: var(--pj-tension); font-size: .78rem; }

/* --------------------------------------------------------------------------
   Mode d'emploi
   -------------------------------------------------------------------------- */
.mode-emploi__accroche { margin: 0; font-size: .95rem; max-width: 90ch; }

/* Numérotation par compteur CSS : les chiffres suivent l'ordre du gabarit, et
   insérer une étape en milieu de liste ne demande pas de renuméroter à la main —
   ce qui aurait fini par donner deux étapes « 5 ». */
.etapes { list-style: none; counter-reset: etape; margin: 0; padding: 0; }
.etape {
  counter-increment: etape;
  position: relative;
  padding-left: 34px;
  margin-bottom: 18px;
}
.etape::before {
  content: counter(etape);
  position: absolute;
  left: 0;
  top: 1px;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 1px solid var(--pj-filet);
  background: var(--pj-fond-doux);
  color: var(--pj-mute);
  font-size: .74rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* L'étape charnière — figer le périmètre — est la seule marquée : c'est celle qu'on
   saute, et la sauter vide l'outil de son intérêt. Un accent, pas une alerte. */
.etape--pivot::before {
  border-color: var(--pj-accent);
  background: var(--pj-accent-clair);
  color: var(--pj-accent);
}

.etape__titre { margin: 0 0 3px; font-size: .92rem; font-weight: 600; }
.etape__texte { margin: 0 0 14px; font-size: .88rem; line-height: 1.55; max-width: 78ch; }
.etape__texte em { color: var(--pj-mute); font-style: normal; }
.etape .etape__texte { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Précision secondaire
   -------------------------------------------------------------------------- */
/* Petit texte gris sous une ligne : le rang d'un élément, la fonction d'un membre,
   la date d'une référence. La classe s'appelait `arbre__niveau`, du nom de son
   premier usage — elle servait en réalité partout, et ce nom faisait apparaître le
   mot « niveau » dans le rendu de dix écrans qui n'en parlaient pas. */
.meta {
  font-size: .72rem;
  color: var(--pj-mute);
  text-transform: uppercase;
  letter-spacing: .04em;
}

/* --------------------------------------------------------------------------
   Formulaires
   -------------------------------------------------------------------------- */
.formulaire { max-width: 860px; }
.formulaire--large { max-width: 1060px; }

/* Groupes déclarés par le formulaire (`core/forms.FormulaireStructure`). Le
   `fieldset` est dépouillé de sa bordure native : le regroupement se lit au
   titre et à l'espace, un cadre par section ferait cinq boîtes dans une boîte. */
.groupe { border: 0; margin: 0; padding: 0; }
.groupe + .groupe { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--pj-filet); }
.groupe__titre {
  float: none;             /* `legend` est flottant par défaut dans certains agents */
  width: auto;
  padding: 0;
  margin-bottom: 12px;
  font-size: .74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--pj-mute);
}

/* Deux colonnes : un champ de date ou un code étirés sur toute la largeur
   laissent croire qu'on y attend un texte long. */
.groupe__champs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 20px;
}
.champ--pleine { grid-column: 1 / -1; }

/* Sous 720 px, la seconde colonne ne tient plus : une colonne unique vaut mieux
   que deux champs écrasés. */
@media (max-width: 720px) {
  .groupe__champs { grid-template-columns: 1fr; }
}

.champ { margin-bottom: 14px; }
.champ label { display: block; font-size: .82rem; font-weight: 600; margin-bottom: 4px; }
.champ input, .champ select, .champ textarea {
  width: 100%; padding: 7px 10px;
  border: 1px solid var(--pj-filet); border-radius: var(--pj-rayon);
  font-size: .9rem; background: var(--pj-surface); color: var(--pj-encre);
}
.champ input:focus, .champ select:focus, .champ textarea:focus {
  outline: none; border-color: var(--pj-accent);
  box-shadow: 0 0 0 3px var(--pj-accent-clair);
}
.champ input:disabled, .champ select:disabled { background: var(--pj-fond-doux); color: var(--pj-mute); }
.champ__aide { font-size: .78rem; color: var(--pj-mute); margin-top: 3px; }
.champ__erreur { font-size: .8rem; color: var(--pj-retard); margin-top: 3px; }
.champ--erreur input, .champ--erreur select, .champ--erreur textarea { border-color: var(--pj-retard); }

/* Une liste de classement qui bascule en zone de texte, pour ranger le dossier dans
   une valeur qui n'existe pas encore.

   Tout se joue en CSS, sur une case à cocher véritable : rien ne se recharge, l'état
   est posté avec le formulaire — donc conservé si la modale revient pour une erreur —
   et cela fonctionne sans script.

   L'interrupteur précède ses frères dans le document : `~` ne regarde qu'en avant.
   Le déplacer casserait la bascule sans produire aucune erreur. */
.champ--liste .liste__interrupteur {
  /* Masqué à l'œil, atteignable au clavier : c'est lui qui porte l'état, et le
     supprimer du flux avec `display: none` le retirerait de la tabulation.
     Sélecteur préfixé par `.champ--liste` : `.champ input { width: 100% }` gagnerait
     sinon sur la largeur. */
  position: absolute;
  width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); border: 0;
}
.liste__saisie { display: none; }
.liste__interrupteur:checked ~ .liste__choix { display: none; }
.liste__interrupteur:checked ~ .liste__saisie { display: block; }

/* Discret : c'est une issue, pas l'action courante. S'il attirait l'œil autant que
   la liste, on inventerait une valeur là où il fallait choisir, et le classement se
   disperserait entre des variantes du même mot. */
.champ--liste .liste__bascule {
  display: inline-block;
  margin-top: 5px; margin-bottom: 0;
  font-size: .76rem; font-weight: 500; color: var(--pj-mute);
  cursor: pointer;
}
.champ--liste .liste__bascule:hover { color: var(--pj-accent); }
.liste__vers-choix { display: none; }
.liste__interrupteur:checked ~ .liste__bascule .liste__vers-saisie { display: none; }
.liste__interrupteur:checked ~ .liste__bascule .liste__vers-choix { display: inline; }
.liste__interrupteur:checked ~ .liste__bascule { color: var(--pj-accent); }

/* La case étant invisible, son anneau de focus doit se reporter sur l'étiquette :
   sans cela, l'utilisateur au clavier perd le curseur en traversant le formulaire. */
.liste__interrupteur:focus-visible ~ .liste__bascule {
  outline: 2px solid var(--pj-accent); outline-offset: 2px;
}

.actions-formulaire { display: flex; gap: 10px; align-items: center; margin-top: 20px;
  padding-top: 16px; border-top: 1px solid var(--pj-filet); }

.bouton, .bouton:visited {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border-radius: var(--pj-rayon); font-size: .87rem; font-weight: 500;
  border: 1px solid var(--pj-filet); background: var(--pj-surface); color: var(--pj-encre);
  text-decoration: none; cursor: pointer;
}
.bouton:hover { border-color: var(--pj-accent); color: var(--pj-accent); }
.bouton--principal { background: var(--pj-accent); border-color: var(--pj-accent); color: #fff; }
.bouton--principal:hover { background: var(--pj-accent-fonce);
  border-color: var(--pj-accent-fonce); color: #fff; }

/* L'action principale prend le traitement de la maquette : capitales, gras, coins
   plus arrondis. **Une seule par écran**, ce qui est la règle du dessin d'origine —
   la mettre sur tous les boutons ferait crier tout l'écran.

   **Déclaré après `.bouton--principal`** : à spécificité égale, c'est la dernière
   règle qui gagne, et placé avant il reprenait la graisse et les angles de la base,
   sans qu'aucune erreur ne le signale. Même piège que les blocs `@media`. */
.bouton--principal {
  text-transform: uppercase;
  font-weight: 700;
  font-size: .76rem;
  letter-spacing: .06em;
  padding: 9px 16px;
}
/* L'action destructrice reste grise au repos : la teinter d'emblée ferait de
   chaque ligne un avertissement. */
/* Pleine largeur, pour l'action unique d'un écran — la connexion. Ailleurs, un bouton
   étiré sur toute la carte donnerait à un geste ordinaire le poids d'une décision. */
.bouton--pleine { width: 100%; justify-content: center; }
.bouton--risque { color: var(--pj-mute); }
.bouton--risque:hover { color: var(--pj-retard); border-color: var(--pj-retard); }
/* Plein rouge : réservé au bouton qui **exécute** la suppression, dans la boîte de
   confirmation. C'est le seul endroit où l'utilisateur a déjà lu les conséquences. */
.bouton--danger, .bouton--danger:visited {
  background: var(--pj-retard); border-color: var(--pj-retard); color: #fff;
}
.bouton--danger:hover { background: #96170f; border-color: #96170f; color: #fff; }
.bouton--menu { padding: 3px 8px; font-size: .78rem; }

/* Les filtres étaient une rangée nue posée sur le fond de page : entre le titre et
   une grille de cartes blanches, ils flottaient sans appartenir à l'écran. */
.filtres {
  display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap;
  margin-bottom: 18px;
  padding: 14px 18px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
}
/* Dépliés dans le volet, ils sont **déjà** sur la carte de celui-ci : garder leur
   propre fond et leur ombre faisait une carte dans une carte, et le double liseré se
   voyait à l'ouverture. */
.volet-filtres .filtres {
  margin-bottom: 0;
  padding: 12px 0 2px;
  background: none;
  box-shadow: none;
}
.filtres .champ { margin-bottom: 0; min-width: 170px; }

/* --------------------------------------------------------------------------
   Fil de discussion
   -------------------------------------------------------------------------- */
.fil-discussion { display: flex; flex-direction: column; gap: 12px; }
.message { display: flex; gap: 10px; }
.message__corps { flex: 1; }
.message__entete { font-size: .8rem; color: var(--pj-mute); margin-bottom: 2px; }
.message__auteur { font-weight: 600; color: var(--pj-encre); }
.message__texte { font-size: .9rem; white-space: pre-wrap; margin: 0; }

/* --------------------------------------------------------------------------
   Documents et Markdown
   -------------------------------------------------------------------------- */
/* Ici, et seulement ici, une largeur de lecture : c'est du texte suivi. */
.prose { max-width: 78ch; font-size: .95rem; line-height: 1.65; }
.prose h2 { font-size: 1.1rem; margin: 1.6em 0 .5em; }
.prose h3 { font-size: .98rem; margin: 1.4em 0 .4em; }
.prose p { margin: 0 0 .8em; }
.prose ul { margin: 0 0 .8em 1.2em; }
.prose code { background: var(--pj-fond-doux); padding: 1px 5px;
  font-size: .88em; }

.source-markdown {
  background: var(--pj-fond-doux);
  border: 1px solid var(--pj-filet);
  border-radius: var(--pj-rayon);
  padding: 16px;
  font-size: .82rem;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-x: auto;
  margin: 0;
}

/* --------------------------------------------------------------------------
   Écran de connexion
   -------------------------------------------------------------------------- */
.page-auth { background: var(--pj-fond-doux); }
.auth {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  /* Au-dessus du motif, comme `.contenu`. Sans `position`, cet écran reste dans le flux
     non positionné — que le navigateur peint **sous** les éléments positionnés — et le
     motif passait par-dessus le formulaire de connexion. */
  position: relative;
  z-index: 1;
}
.auth__carte {
  width: 100%; max-width: 400px;
  background: var(--pj-surface); border: 0;
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre-haute);
  padding: 30px;
}
/* **Centré, et seulement lui.** L'identité se regarde d'un seul coup — sceau, nom,
   vocation — alors qu'un formulaire se remplit : l'œil descend le long du bord gauche des
   champs, et une étiquette centrée au-dessus d'un champ pleine largeur casse cette
   colonne de lecture. Tout ce qui se regarde est centré, tout ce qui se remplit reste
   aligné à gauche. */
.auth__entete {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin-bottom: 24px;
}
.auth__titre { font-size: 1.15rem; font-weight: 600; margin: 14px 0 2px; }
.auth__accroche { font-size: .82rem; color: var(--pj-mute); margin: 0; }
/* La note ferme la carte : centrée, elle équilibre l'en-tête et ne se lit pas comme une
   quatrième étiquette de champ — ce qu'elle faisait, alignée à gauche sous le bouton. */
.auth__note {
  font-size: .78rem;
  color: var(--pj-mute);
  margin-top: 18px;
  text-align: center;
}

/* --------------------------------------------------------------------------
   Menu horizontal
   -------------------------------------------------------------------------- */
/* Jamais dans un conteneur qui défile : `overflow-x: auto` rognerait les
   panneaux déroulants dès la première entrée, et `overflow-y: visible` n'est
   pas honoré quand `overflow-x` vaut `auto`. Piège rencontré trois fois sur
   riskassessor-v2. */
/* Le menu **suit l'identité**, il n'est plus poussé à droite. Collé au bord droit, il
   se lisait comme un groupe d'outils secondaires ; à côté du nom de l'outil, c'est la
   navigation principale, ce qu'elle est. Le bloc de droite — cloche et compte — prend
   le `margin-left: auto`. */
.menu { display: flex; align-items: center; gap: 4px; margin-left: 22px; }
.menu__entree {
  /* `inline-flex` et non `inline` : c'est ce qui centre l'icône avec son libellé.
     Sans lui, l'icône s'aligne sur la ligne de base du texte et pend de deux pixels —
     un défaut qu'on voit sans savoir le nommer. */
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  border-radius: var(--pj-rayon);
  font-size: .87rem;
  color: var(--pj-bandeau-texte);
  text-decoration: none;
  /* Filet transparent au repos : sans lui, l'entrée se décalerait d'un pixel
     au survol et toute la barre sauterait. */
  border: 1px solid transparent;
  background: none;
  white-space: nowrap;
}
.menu__entree:hover { background: var(--pj-bandeau-clair); color: #fff; }
/* L'entrée active en clair sur le foncé : c'est l'inverse du reste de l'outil, où
   l'accent désigne ce qui se clique. Sur une barre sombre, un fond d'accent aurait
   été presque invisible — deux valeurs voisines de la même teinte. */
.menu__entree--active {
  color: var(--pj-bandeau);
  background: var(--pj-surface);
  border-color: #fff;
  font-weight: 600;
}
/* L'icône. Sa taille est fixée pour que les entrées gardent la même hauteur quel que
   soit son dessin, et `flex: 0 0` l'empêche de se comprimer quand la barre se serre. */
.menu__icone {
  width: 16px; height: 16px;
  flex: 0 0 16px;
  /* `currentColor` dans le dessin : l'icône suit le libellé au survol et à l'état
     actif, sans une seule règle de couleur de plus. */
  display: block;
}
.menu__panneau { border: 1px solid var(--pj-filet); border-radius: var(--pj-rayon); padding: 4px; }
.menu__panneau .dropdown-item { font-size: .87rem; }

/* Le coin « moi » : la cloche et le menu du compte, côte à côte, plaqués à droite.

   C'est **le groupe** qui porte le `margin-left: auto`, pas ses membres. Quand la cloche
   et le compte le portaient chacun, le premier des deux poussait le second : la cloche
   restait collée à la dernière rubrique du menu, seule au milieu de la barre, à deux
   cents pixels du portrait qu'elle accompagne. */
.bandeau__moi {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
  flex-shrink: 0;
}
.menu-compte { flex-shrink: 0; }
.menu-compte__declencheur {
  display: flex; align-items: center; gap: 8px;
  background: none; border: 1px solid transparent; border-radius: var(--pj-rayon);
  padding: 4px 8px 4px 4px;
}
.menu-compte__declencheur { color: #fff; }
.menu-compte__declencheur:hover { background: var(--pj-bandeau-clair); }
.menu-compte__nom { font-size: .85rem; max-width: 160px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.menu-compte__panneau { min-width: 240px; border: 1px solid var(--pj-filet); }
.menu-compte__identite { padding: 10px 14px; display: flex; flex-direction: column; }
.menu-compte__identite-nom { font-weight: 600; font-size: .88rem; }
.menu-compte__identite-role { font-size: .76rem; color: var(--pj-mute); }
.menu-compte__sortie { color: var(--pj-retard); }

/* Le survol seul serait inatteignable au clavier et sur écran tactile : la
   classe `show` que Bootstrap ajoute au clic doit suffire à révéler le panneau. */
.dropdown-menu.show { display: block; }
/* Sceau : monogramme du bandeau et des fils de discussion. */
.sceau {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  flex: 0 0 32px;
  border-radius: 50%;
  border: 1px solid var(--pj-accent);
  color: var(--pj-accent);
  background: var(--pj-accent-clair);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .02em;
}

/* --------------------------------------------------------------------------
   Diagramme de Gantt
   --------------------------------------------------------------------------
   Le dessin n'est **pas étiré** : la toile garde sa largeur de 1000 px, donc une
   unité de `viewBox` vaut un pixel. C'est ce qui permet d'écrire les dates de l'axe
   en `<text>` SVG sans qu'elles se déforment, et c'est ce qui fait correspondre les
   hauteurs de ligne du SVG à celles de la colonne d'intitulés en HTML.

   Le cadre défile donc en largeur sur un écran étroit. Comprimer trois mois dans
   360 px rendrait toutes les barres indiscernables ; le défilement est le geste
   attendu sur ce dessin-là. */
.gantt { display: flex; flex-direction: column; }

.gantt__cadre {
  display: flex;
  overflow-x: auto;
  /* Le fond derrière la colonne collante : sans lui, les barres défileraient en
     transparence sous les intitulés. */
  background: var(--pj-surface);
}

.gantt__intitules {
  flex: 0 0 auto;
  /* `min()` et non une largeur nue : sur un écran de 320 px, 240 px d'intitulés ne
     laissaient que 80 px de dessin. */
  width: min(240px, 42vw);
  /* Reste en vue quand le dessin défile — un Gantt dont les intitulés partent à
     gauche ne se lit plus du tout. */
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--pj-surface);
  border-right: 1px solid var(--pj-filet);
}

/* La hauteur du cran doit valoir celle de `.gantt__axe`, sinon toutes les lignes
   sont décalées d'un cran — ce qui se lit comme « la tâche a une autre date ». */
.gantt__cran {
  margin: 0;
  height: 26px;
  display: flex; align-items: center;
  padding: 0 10px;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--pj-mute);
  border-bottom: 1px solid var(--pj-filet);
}

/* 28 px : la valeur de `HAUTEUR_LIGNE` dans `core/graphiques.py`. Les deux doivent
   rester d'accord — c'est le seul point où le dessin et le texte se rejoignent. */
.gantt__intitule {
  margin: 0;
  height: 28px;
  display: flex; align-items: center;
  gap: 6px;
  padding: 0 10px;
  font-size: .82rem;
  /* La pastille de couleur de l'état, reprise de `--etape` : la même teinte que la
     barre en face, et que le tableau par état. */
  border-left: 3px solid var(--etape, transparent);
}
.gantt__intitule a {
  color: var(--pj-encre);
  text-decoration: none;
  /* Un intitulé long pousserait la colonne et désalignerait tout le dessin. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gantt__intitule a:hover { color: var(--pj-accent); text-decoration: underline; }
.gantt__intitule[data-couleur="faite"] a,
.gantt__intitule[data-couleur="abandonnee"] a { color: var(--pj-mute); }

.gantt__toiles { flex: 0 0 auto; }
/* Largeur fixe, égale au `viewBox` : c'est elle qui empêche l'étirement. */
.gantt__axe   { display: block; width: 1000px; height: 26px; }
.gantt__toile { display: block; width: 1000px; }

.gantt__date { fill: var(--pj-mute); font-size: 9px; }
.gantt__cran-trait { stroke: var(--pj-filet); stroke-width: 1; }
.gantt__guide { stroke: var(--pj-filet); stroke-width: 1; }

.gantt__barre { fill: var(--etape, var(--pj-mute)); }
/* Le jalon se distingue de la barre : un carré plein de six unités se confondrait
   avec une barre courte, et l'on croirait à une tâche d'un jour planifiée. */
.gantt__jalon {
  fill: var(--pj-surface);
  stroke: var(--etape, var(--pj-mute));
  stroke-width: 2;
}

/* Aujourd'hui : tirets, pour ne pas se confondre avec une graduation. */
.gantt__aujourdhui {
  stroke: var(--pj-retard);
  stroke-width: 1.5;
  stroke-dasharray: 3 3;
}

/* Le relevé écrit sous le dessin. Un diagramme ne se lit pas au lecteur d'écran, et
   sur trois mois personne ne devine le jour exact d'une barre. */
.gantt__releve {
  list-style: none;
  margin: 0;
  padding: 10px 12px 4px;
  border-top: 1px solid var(--pj-filet);
  display: flex; flex-direction: column; gap: 5px;
  font-size: .82rem;
}
.gantt__ligne-relevee { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.gantt__puce {
  flex: 0 0 auto;
  width: 9px; height: 9px;
  background: var(--etape, var(--pj-mute));
}
.gantt__ligne-relevee a { color: var(--pj-encre); text-decoration: none; font-weight: 500; }
.gantt__ligne-relevee a:hover { color: var(--pj-accent); text-decoration: underline; }
.gantt__dates { color: var(--pj-mute); font-variant-numeric: tabular-nums; }

/* Le bloc ne rembourre pas : le cadre défilant doit toucher ses bords, sinon la
   colonne collante s'arrête avant le bord et laisse voir les barres passer. */
.bloc--gantt { padding: 0; overflow: hidden; }

/* --------------------------------------------------------------------------
   Notifications — la cloche et la boîte
   -------------------------------------------------------------------------- */

/* Un lien, pas un panneau déroulant : celui-ci aurait demandé du JavaScript pour se
   remplir, donc une requête de plus par ouverture, et n'aurait rien montré de mieux
   que la page. Le compteur suffit à savoir s'il faut y aller. */
.cloche {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  color: var(--pj-bandeau-texte);
  text-decoration: none;
  border-radius: var(--pj-rayon);
}
.cloche:hover { color: #fff; background: var(--pj-bandeau-clair); }
.cloche__dessin { width: 19px; height: 19px; display: block; }
/* Pleine, elle prend la couleur d'action : la cloche est alors la seule chose de
   l'écran sur laquelle il y a quelque chose à faire. */
/* Pleine : blanc franc. L'accent sur la barre foncée aurait été deux valeurs
   voisines de la même teinte, donc invisible. La pastille rouge, elle, suffit à
   attirer l'œil. */
.cloche--pleine { color: #fff; }

.cloche__compte {
  position: absolute;
  top: 1px; right: 0;
  min-width: 15px;
  padding: 0 3px;
  /* Le rouge du retard, et c'est voulu : un compteur de messages non lus est un
     signal d'attente, pas une invitation à cliquer. L'accent, lui, ne désigne que ce
     qui se clique — et toute la cloche est déjà cliquable. */
  background: var(--pj-retard);
  color: #fff;
  font-size: .62rem;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
  /* **Carrée**, comme toutes les surfaces de l'outil (`--pj-rayon: 0`). Une pastille
     en gélule aurait été le seul angle rond de l'écran, et un test l'interdit — à
     raison : un thème à angles francs percé d'une exception se lit comme un oubli.
     Le carré a en outre l'avantage de tenir « 99+ » sans se déformer. */
  /* Un liseré de la couleur du bandeau : sans lui, la pastille collée au dessin de la
     cloche se lisait comme une partie du dessin. Il suit le bandeau, pas la surface
     de travail — un liseré blanc sur le foncé aurait fait un anneau lumineux. */
  box-shadow: 0 0 0 2px var(--pj-bandeau);
}

.boite { list-style: none; margin: 0; padding: 0; }
.boite__ligne + .boite__ligne { border-top: 1px solid var(--pj-filet); }

.boite__lien {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 18px;
  text-decoration: none;
  color: inherit;
}
.boite__lien:hover { background: var(--pj-fond-doux); }

/* La marque de non-lu. Ronde et pleine à gauche du texte, elle se voit d'un coup
   d'œil sur une liste de trente lignes — ce qu'une graisse plus forte ne fait pas. */
.boite__marque {
  flex: 0 0 auto;
  width: 7px; height: 7px;
  margin-top: 6px;
  border-radius: 50%;
  background: var(--pj-accent);
}
/* Lue : la place de la marque est **conservée**, seule sa couleur disparaît. La
   retirer aurait décalé le texte de dix-sept pixels d'une ligne à l'autre, et la
   liste aurait paru en désordre. */
.boite__ligne[data-lue="oui"] .boite__marque { background: transparent; }
.boite__ligne[data-lue="oui"] .boite__titre { font-weight: 400; color: var(--pj-mute); }

.boite__texte { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.boite__titre { font-size: .9rem; font-weight: 600; }
.boite__corps { font-size: .82rem; color: var(--pj-mute); }

.boite__cote {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
  font-size: .76rem;
  color: var(--pj-mute);
}
.boite__code { font-size: .72rem; color: var(--pj-mute); }
.boite__date { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* --------------------------------------------------------------------------
   Mon compte — portrait et identité
   -------------------------------------------------------------------------- */

/* La photo occupe exactement la place du sceau à initiales : les deux se relaient dans
   `partials/portrait.html`, et une taille différente aurait fait sauter le bandeau selon
   que l'on a déposé une photo ou non. */
.portrait {
  display: inline-block;
  width: 32px; height: 32px;
  flex: 0 0 32px;
  border-radius: 50%;
  /* `cover` : l'image est déjà carrée — recadrée au serveur — mais un fichier plus
     ancien, d'avant le recadrage, se serait déformé sans cela. */
  object-fit: cover;
  border: 1px solid var(--pj-filet);
  background: var(--pj-fond-doux);
}

/* La vignette de la page « Mon compte ». Assez grande pour juger du cadrage : à
   32 px on ne voit pas si le visage est coupé. */
.portrait--grand, .sceau--grand {
  width: 96px; height: 96px;
  flex: 0 0 96px;
}
.sceau--grand { font-size: 1.7rem; }

.identite { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
.identite__texte { flex: 1 1 min(320px, 100%); min-width: 0; }
.identite__nom { margin: 0 0 2px; font-size: 1.05rem; font-weight: 600; }
.identite__detail { margin: 0 0 12px; font-size: .84rem; color: var(--pj-mute); }
.identite__detail code { font-size: .82rem; color: var(--pj-encre); }

/* Le retrait de la photo, détaché du formulaire de dépôt : collé dessous, son bouton
   se lisait comme la seconde action du même formulaire. */
.formulaire--a-part {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--pj-filet);
}

/* Les erreurs hors champ, au-dessus des champs : sous le bouton d'envoi, elles ne sont
   pas vues et l'on recommence la saisie à l'identique. */
.formulaire__erreurs {
  margin-bottom: 14px;
  padding: 10px 12px;
  border-left: 3px solid var(--pj-retard);
  background: #fdf3f2;
  color: var(--pj-retard);
  font-size: .84rem;
}

/* --------------------------------------------------------------------------
   Tuiles — les quatre chiffres du tableau de bord
   --------------------------------------------------------------------------
   **`.tuile` et non `.mesure`.** `.mesure`, `.mesure__libelle` et `.mesure__valeur`
   appartiennent déjà aux trois chiffres de la carte de dossier. Réemployer le nom a
   écrasé leurs règles — la feuille est un seul fichier, et ce qui est écrit plus bas
   gagne : les trois chiffres de chaque carte sont devenus des boîtes blanches à ombre,
   posées côte à côte, si étroites que « aujourd'hui » se lisait une lettre par ligne.

   Aucune erreur n'a été levée. Un nom de classe réemployé ne se signale jamais : il
   déforme un écran qu'on ne regardait pas au moment où on l'a écrit. */
/* Quatre cartes de front, une par question qu'on se pose en arrivant. `auto-fit` et non
   `repeat(4, 1fr)` : sur un écran de tablette, quatre colonnes donnaient des nombres
   collés à leur pastille, et sur téléphone une colonne de 70 px. Elles se replient
   d'elles-mêmes en deux puis en une.

   `min(230px, 100%)` : sans le `min()`, la grille ne descend pas sous 230 px et la
   rangée débordait de l'écran sur un téléphone de 375 px — sans erreur, la page
   défilait latéralement. */
.tuiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: 16px;
  margin-bottom: 18px;
}

.tuile {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
}

/* La pastille carrée, comme tout le thème. Elle porte l'icône, et sa couleur dit de
   quoi parle le chiffre. */
.tuile__pastille {
  flex: 0 0 42px;
  width: 42px; height: 42px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--pj-rayon);
  color: #fff;
}
/* L'icône du menu reprise ici, en plus grand : un second jeu de dessins pour les mêmes
   idées aurait fait deux vocabulaires à tenir d'accord. */
.tuile__pastille .menu__icone { width: 21px; height: 21px; flex: 0 0 21px; }

/* Quatre teintes, et chacune a un sens. Les quatre en accent auraient fait un mur bleu
   où rien ne ressort — ce qu'un bandeau de mesures doit précisément éviter. */
.tuile__pastille--neutre  { background: var(--pj-bandeau); }
.tuile__pastille--retard  { background: var(--pj-retard); }
.tuile__pastille--accent  { background: var(--pj-accent); }
.tuile__pastille--attente { background: var(--pj-tension); }

.tuile__texte { display: flex; flex-direction: column; min-width: 0; }
.tuile__nombre {
  font-size: 1.55rem;
  font-weight: 650;
  line-height: 1.1;
  letter-spacing: -.02em;
  /* Chiffres de largeur fixe : sans cela, passer de 9 à 10 décale le libellé en
     dessous, et la rangée paraît bouger d'un rechargement à l'autre. */
  font-variant-numeric: tabular-nums;
}
.tuile__libelle {
  font-size: .82rem;
  color: var(--pj-mute);
  /* Deux lignes autorisées : « Tâches qui me sont confiées » tronqué en « Tâches qui
     me… » ne dit plus de quoi il s'agit. */
  line-height: 1.3;
}

/* --------------------------------------------------------------------------
   Aperçu d'une pièce — la regarder sans la télécharger
   --------------------------------------------------------------------------
   Un PDF ou une image se vérifient d'un coup d'œil : on veut savoir si le devis est le
   bon, pas encombrer son répertoire de téléchargements d'un fichier qu'on ouvrira une
   fois. Pour tout le reste — un tableur, une archive — le téléchargement reste le seul
   geste qui ait un sens.

   L'affichage en ligne rouvre la porte que la remise en pièce jointe fermait : trois
   protections la referment, et deux ne sont pas ici mais dans `dossiers.views` — le type
   constaté dans les octets, et `Content-Security-Policy: sandbox`. La troisième est le
   `sandbox` de l'`<iframe>`, dans le gabarit. */
.modale__carte--large { width: min(1000px, 94vw); }

/* Bornée à la vue : sans cette hauteur, un PDF de quarante pages faisait une boîte de
   trente mètres et le pied — donc le bouton de téléchargement — sortait de l'écran. */
.modale__corps--apercu {
  padding: 0;
  background: var(--pj-fond-doux);
  max-height: 72vh;
  overflow: auto;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* `contain` et non `cover` : une capture d'écran recadrée n'est plus une preuve. On veut
   la pièce entière, quitte à laisser du vide autour. */
.apercu__image {
  display: block;
  max-width: 100%;
  max-height: 72vh;
  object-fit: contain;
}

.apercu__cadre {
  display: block;
  width: 100%;
  /* Hauteur fixe et non `100%` : dans un conteneur dont la hauteur dépend du contenu,
     `100%` se résout à zéro et le cadre disparaissait — sans erreur. */
  height: 72vh;
  border: 0;
  background: var(--pj-surface);
}

/* Le téléchargement, à côté du nom, en second rôle : c'est le nom qu'on clique pour
   regarder, et ce lien reste pour emporter. */
.lien-discret {
  margin-left: 8px;
  font-size: .74rem;
  color: var(--pj-mute);
}
.lien-discret:hover { color: var(--pj-accent); }

/* --------------------------------------------------------------------------
   Chapeau fusionné — le titre, l'identité et la frise sur une seule surface
   --------------------------------------------------------------------------
   Il y avait deux cartes empilées : celle du titre — « Suivi / Risque Assessor » et ses
   boutons — puis le chapeau foncé. Deux surfaces, deux ombres et une gouttière entre
   elles pour une seule idée : de quel dossier parle-t-on, et où en est-il.

   Le chapeau passe donc en colonne : ligne du titre, puis ligne de l'identité et de la
   frise. C'est le seul endroit de l'outil où l'en-tête de page est absorbé — ailleurs il
   reste, parce qu'ailleurs il n'y a pas de chapeau pour le recevoir. */
.chapeau__ligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  padding-bottom: 14px;
  margin-bottom: 14px;
  /* Un filet clair plutôt qu'un espace : sur le dégradé, un simple écart laissait les
     deux lignes flotter sans qu'on sache si elles appartenaient au même bloc. */
  border-bottom: 1px solid rgba(255, 255, 255, .18);
}
.chapeau__corps {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  width: 100%;
}

.chapeau__titre {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -.01em;
  color: #fff;
  min-width: 0;
}
/* Le parent en blanc atténué et de graisse normale : c'est un chemin de retour, pas la
   moitié d'un titre. Sans cet écart, la ligne se lirait comme un nom en deux mots. */
.chapeau__parent {
  color: rgba(255, 255, 255, .72);
  font-weight: 400;
  font-size: 1rem;
  text-decoration: none;
}
.chapeau__parent:hover { color: #fff; text-decoration: underline; }
.chapeau__separateur { margin: 0 8px; color: rgba(255, 255, 255, .4); font-weight: 400; }

.chapeau__actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }
/* Les boutons sur le dégradé. Le principal y perdrait tout contraste — accent sur
   accent — donc il s'inverse : blanc plein, texte foncé. Le secondaire devient un
   contour clair. */
.chapeau__actions .bouton {
  background: none;
  border-color: rgba(255, 255, 255, .45);
  color: #fff;
}
.chapeau__actions .bouton:hover {
  background: rgba(255, 255, 255, .14);
  border-color: #fff;
  color: #fff;
}
.chapeau__actions .bouton--principal {
  background: var(--pj-surface);
  border-color: var(--pj-surface);
  color: var(--pj-bandeau);
}
.chapeau__actions .bouton--principal:hover {
  background: rgba(255, 255, 255, .88);
  border-color: rgba(255, 255, 255, .88);
  color: var(--pj-bandeau);
}

/* --------------------------------------------------------------------------
   Frise pilotable — la frise est le contrôle de phase
   --------------------------------------------------------------------------
   Elle remplace le bloc « Faire avancer le cycle » : une liste déroulante et un bouton,
   occupant une carte entière pour un geste d'un clic. Ici l'espace est nul — la frise est
   déjà à l'écran — et l'on désigne l'étape au lieu de la chercher dans une liste. */
.frise--pilotable { margin: 0; }
.frise__bouton {
  display: block;
  width: 100%;
  padding: 14px 0 0;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  /* Le jalon est positionné contre `.frise__etape` : ce bouton ne doit surtout pas
     créer de contexte de positionnement, sinon chaque point se recale sur son propre
     bouton et la ligne de jalons se désaligne. */
  position: static;
}
.frise__bouton:disabled { cursor: default; }
/* L'invitation ne paraît qu'au survol d'une étape atteignable : un liseré permanent sur
   dix étapes aurait fait dix boutons là où l'on veut lire une progression. */
.frise__bouton:not(:disabled):hover .frise__libelle,
.frise__bouton:not(:disabled):focus-visible .frise__libelle {
  color: #fff;
  text-decoration: underline;
}
.frise__bouton:not(:disabled):hover .frise__jalon,
.frise__bouton:not(:disabled):focus-visible .frise__jalon {
  border-color: #fff;
  background: rgba(255, 255, 255, .4);
}
/* Compacte, le libellé reste **lu** sans être vu : un bouton sans nom accessible n est
   pas atteignable au clavier. */
.frise__libelle--lu {
  position: absolute;
  width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); border: 0;
}

/* --------------------------------------------------------------------------
   Captures d'un regroupement
   --------------------------------------------------------------------------
   Elles disent à quoi ressemble ce qu'on décrit. Placées **sous le titre et avant les
   tâches** : reléguées après la liste, elles ne seraient jamais vues.

   Des vignettes et non les images en pleine taille — douze captures déployées auraient
   repoussé les tâches, sujet de l'écran, hors de la vue. Le clic ouvre la boîte
   d'aperçu, la même que dans Livraisons. */
.captures {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--pj-filet);
  background: var(--pj-fond-doux);
}
.captures__vignette {
  display: block;
  width: 104px; height: 68px;
  overflow: hidden;
  border: 1px solid var(--pj-filet);
  background: var(--pj-surface);
}
.captures__vignette img {
  width: 100%; height: 100%;
  /* `cover` sur une vignette : on veut un aperçu de même gabarit pour toutes, et le clic
     ouvre l'image entière. `contain` aurait donné douze rectangles de tailles inégales. */
  object-fit: cover;
  display: block;
}
.captures__vignette:hover { border-color: var(--pj-accent); }
/* Une pièce rattachée qui n'est pas une image — un PDF de maquette, un tableur. Elle
   garde sa place : la cacher aurait fait disparaître un fichier délibérément rattaché. */
.captures__fichier {
  display: inline-flex; align-items: center;
  height: 68px;
  padding: 0 12px;
  font-size: .78rem;
  color: var(--pj-mute);
  text-decoration: none;
  border: 1px dashed var(--pj-filet);
  background: var(--pj-surface);
}
.captures__fichier:hover { color: var(--pj-accent); border-color: var(--pj-accent); }

/* --------------------------------------------------------------------------
   Avancement — la barre empilée au-dessus du tableau des états
   --------------------------------------------------------------------------
   Ce qui était là ne répondait pas à la question. Cinq compteurs côte à côte et, au
   dessus, un rail avec un point par colonne : un dessin emprunté à la frise du cycle,
   qui suggérait une progression linéaire d'À faire vers Abandonnée — ce que les états ne
   sont pas. Décoratif, donc, et trompeur. Pour savoir où l'on en était, il fallait
   additionner cinq nombres de tête.

   La barre le dit d'un coup, et le chiffre au-dessus dit ce qu'on vient chercher. */
.avancement {
  margin-bottom: 16px;
  padding: 14px 18px 12px;
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
}
.avancement__tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.avancement__chiffre { margin: 0; font-size: .9rem; color: var(--pj-mute); }
.avancement__chiffre strong { font-size: 1.15rem; color: var(--pj-encre); }
.avancement__part {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 650;
  letter-spacing: -.02em;
  color: var(--pj-actif);
  font-variant-numeric: tabular-nums;
}

/* `preserveAspectRatio="none"` : la barre s'étire sur la largeur du bloc, la hauteur
   restant celle que la feuille lui donne. C'est le même choix que l'histogramme du
   tableau de bord — deux mécaniques pour un même dessin en auraient fait une de trop. */
.avancement__barre {
  display: block;
  width: 100%;
  height: 10px;
  /* Le fond derrière les segments : sur un total nul aucun segment n'est rendu, et sans
     ce fond la barre disparaîtrait au lieu de se montrer vide. */
  background: var(--pj-fond-doux);
}
/* La teinte vient de `--etape`, comme les colonnes, les cartes et les étiquettes. Une
   sixième palette pour cette barre aurait fait douter qu'il s'agisse des mêmes états. */
.avancement__part-barre { fill: var(--etape, var(--pj-mute)); }

.avancement__legende {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  font-size: .78rem;
  color: var(--pj-mute);
}
.avancement__entree { display: inline-flex; align-items: center; gap: 6px; }
.avancement__entree strong { color: var(--pj-encre); }
.avancement__puce {
  width: 9px; height: 9px;
  flex: 0 0 9px;
  background: var(--etape, var(--pj-mute));
}
.avancement__pourcent { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   LE DESCRIPTIF, ET LES POINTS À FAIRE
   ==========================================================================
   Ajoutés le 21 août 2026, quand la fonctionnalité et la tâche ont cessé d'être le
   seul inventaire du travail pour décrire d'abord ce que le logiciel fait.

   Deux registres à distinguer d'un coup d'œil sur la même fiche : le descriptif est
   au présent et se lit, les points sont au futur et se cochent. Sans distinction
   visuelle, l'œil les prend pour un même bloc de texte. */

.descriptif { margin: 16px 0; }
.descriptif__titre {
  font-size: .78rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; color: var(--pj-mute);
  margin: 0 0 6px;
}
/* **La couleur et la taille sont posées explicitement**, et c'est la correction d'un
   défaut mesuré le 21 août 2026 : sans elles, ce texte héritait du gris clair de Hope UI
   (#8a92a6) et de son corps à 16 px. Deux conséquences, dont la seconde est absurde —
   le descriptif était plus gros que tout ce qui l'entourait, et surtout **plus pâle que
   le texte atténué** posé juste en dessous, `--pj-mute` étant plus sombre que le gris du
   fournisseur. Le principal paraissait secondaire.

   La leçon est générale : dans un bloc, un texte sans couleur déclarée n'hérite pas de
   notre encre mais de celle du thème tiers. */
.descriptif p { margin: 0 0 8px; color: var(--pj-encre); font-size: .9rem; }

/* « Ce qui était prévu » est en retrait, sur un filet : c'est un texte gelé, du passé.
   Le présenter comme le descriptif aurait laissé croire qu'il se met à jour. */
.descriptif--prevu {
  padding-left: 12px;
  border-left: 2px solid var(--pj-filet);
}
.descriptif--prevu p { color: var(--pj-mute); }

.points { list-style: none; margin: 0; padding: 0; }
.point {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--pj-filet);
}
.point:last-child { border-bottom: none; }

/* La case. Un `<button>` et non une case à cocher : le geste est une écriture en POST,
   consignée dans la piste d'audit. Une vraie case aurait demandé du JavaScript pour
   soumettre, donc n'aurait rien fait sans lui. */
.point__case {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  flex: 0 0 18px;
  padding: 0;
  border: 1px solid var(--pj-filet);
  border-radius: var(--pj-rayon);
  background: var(--pj-surface);
  color: var(--pj-surface);
  cursor: pointer;
}
.point__case:hover { border-color: var(--pj-accent); }
.point__case:focus-visible {
  outline: none; border-color: var(--pj-accent);
  box-shadow: 0 0 0 3px var(--pj-accent-clair);
}
.point--fait .point__case { background: var(--pj-accent); border-color: var(--pj-accent); }

/* Même correction que pour le descriptif : sans couleur déclarée, un point **non
   coché** héritait du gris clair du thème tiers, donc s'affichait plus pâle qu'un point
   coché — l'inverse exact de ce qu'on veut dire. */
.point__libelle { flex: 1; font-size: .9rem; color: var(--pj-encre); }
/* Barré **et** grisé. Le barré seul reste lisible et l'œil continue de le compter
   parmi ce qui reste ; le gris seul se confond avec une ligne désactivée. */
.point--fait .point__libelle { text-decoration: line-through; color: var(--pj-mute); }

.point__signature { font-size: .76rem; color: var(--pj-mute); white-space: nowrap; }

/* Le retrait ne se montre qu'au survol de la ligne — et **reste visible au clavier**,
   sans quoi il serait inatteignable sans souris. */
.point__retrait { opacity: 0; }
.point:hover .point__retrait,
.point__retrait:focus-within { opacity: 1; }

/* Le champ d'ajout occupe la largeur restante dans `.actions-formulaire`, qui est une
   rangée. `flex: 1` et non `flex: 1 1 300px` : en colonne, la base aurait été lue
   comme une hauteur — le défaut du chapeau à 700 px, le 21 août 2026. */
.champ--extensible { flex: 1; margin-bottom: 0; }

/* Le chapeau d'un groupe de l'écran Travail : la finalité de la fonctionnalité, ou le
   rappel qu'elle n'est pas décrite. Sur le fond creux et non sur la surface du bloc :
   c'est du texte de présentation, pas une ligne de travail, et l'œil doit pouvoir le
   sauter quand il vient chercher une tâche. */
/* Couleur déclarée, **troisième occurrence du même piège dans la même journée** : sans
   elle, ce texte hérite du gris clair de Hope UI (#8a92a6), qui est plus pâle que notre
   `--pj-mute` (#656d76). La finalité paraissait donc secondaire par rapport à la ligne
   « Qui y a droit » posée juste dessous, alors que c'est l'inverse. */
.bloc__finalite { margin: 0; font-size: .88rem; color: var(--pj-encre); }
.bloc__acces { margin: 6px 0 0; font-size: .8rem; color: var(--pj-mute); }
.bloc__a-decrire { margin: 0; font-size: .82rem; color: var(--pj-mute); }

/* ==========================================================================
   ESSAYER UNE VERSION
   ==========================================================================
   Adresse, dépôt et comptes d'essai, sur une seconde ligne dépliable du tableau des
   versions. Le tableau vit dans une grille à deux colonnes : trois colonnes de plus
   l'auraient rendu illisible.

   La couleur est déclarée partout ici. Dans un bloc, un texte sans `color` hérite du gris
   clair du thème tiers — plus pâle que notre couleur atténuée — et le texte principal
   paraît alors secondaire. Le piège s'est refermé trois fois le 21 août 2026. */

.ligne-essai > td { padding: 0; border-top: none; }

.essai { border-top: 1px dashed var(--pj-filet); }
.essai__titre {
  padding: 7px 14px;
  font-size: .8rem;
  color: var(--pj-mute);
  cursor: pointer;
}
.essai__titre:hover { color: var(--pj-accent); }
.essai__compte { color: var(--pj-encre); }
.essai__corps { padding: 4px 14px 14px; background: var(--pj-fond-creux); }

.essai__ligne {
  display: flex; align-items: baseline; gap: 8px;
  margin: 0 0 6px; font-size: .84rem;
  color: var(--pj-encre);
}
/* Largeur fixe sur l'étiquette : « Adresse » et « Dépôt » alignent leurs valeurs, et
   l'œil descend la colonne au lieu de chercher où commence chaque valeur. */
.essai__etiquette {
  flex: 0 0 62px;
  font-size: .74rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--pj-mute);
}
/* Une adresse de dépôt ne se coupe pas aux espaces — elle n'en a pas. Sans cette règle,
   elle élargit le tableau et fait déborder la page horizontalement. */
.essai__depot { word-break: break-all; }
.essai__actions { margin: 10px 0 0; font-size: .82rem; }

.compte-essai {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--pj-filet);
}
.compte-essai__entete {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: .86rem; color: var(--pj-encre);
}
.compte-essai__secret { margin-top: 4px; font-size: .82rem; }
.compte-essai__secret summary { color: var(--pj-mute); cursor: pointer; }
.compte-essai__secret summary:hover { color: var(--pj-accent); }
.compte-essai__valeur {
  display: inline-block; margin-top: 4px;
  color: var(--pj-encre);
  /* Sélectionnable d'un coup : ce mot de passe est fait pour être copié. */
  user-select: all;
}
.compte-essai__note { margin: 4px 0 0; font-size: .8rem; color: var(--pj-mute); }

/* ==========================================================================
   L'ACCORDÉON DES FONCTIONNALITÉS, ET SES ONGLETS
   ==========================================================================
   Refonte du 1er septembre 2026. Chaque fonctionnalité déroulait d'un bloc son titre, sa
   finalité, ses captures et son tableau de tâches : à six fonctionnalités l'écran faisait
   quatre hauteurs de fenêtre. Tout était visible, donc rien ne ressortait.

   `<details>` pour l'accordéon, boutons radio et CSS pour les onglets. **Pas une ligne de
   script** — il n'y a donc rien à dégrader, et le clavier vient du navigateur. */

.fct {
  background: var(--pj-surface);
  border-radius: var(--pj-rayon);
  box-shadow: var(--pj-ombre);
  margin-bottom: 12px;
  overflow: hidden;
}

/* Le résumé porte le nom, l'avancement, et la flèche du navigateur. `cursor: pointer`
   parce que le marqueur natif ne suffit pas à dire que toute la ligne est cliquable. */
.fct__entete {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 18px;
  cursor: pointer;
  color: var(--pj-encre);
}

/* **Le chevron est dessiné, parce que le marqueur natif disparaît.** `display: flex` sur
   un `<summary>` retire le triangle que le navigateur affiche d une liste : constaté au
   navigateur le 1er septembre 2026, la ligne ne portait plus aucun repère de dépliement.
   Rien ne disait qu elle s ouvrait, et un accordéon dont on ne voit pas les poignées est
   une liste morte.

   Les deux suppressions explicites couvrent les navigateurs qui, eux, l afficheraient
   encore : deux repères valent moins qu un seul. */
.fct__entete { list-style: none; }
.fct__entete::-webkit-details-marker { display: none; }
.fct__entete::before {
  content: "";
  flex: 0 0 7px;
  width: 7px; height: 7px;
  margin-right: 2px;
  border-right: 2px solid var(--pj-mute);
  border-bottom: 2px solid var(--pj-mute);
  transform: rotate(-45deg);
}
.fct[open] > .fct__entete::before {
  transform: rotate(45deg);
  border-color: var(--pj-accent);
}
.fct__entete:hover { background: var(--pj-fond-doux); }
/* Le focus clavier doit se voir : sans cela, on tabule à l'aveugle dans une liste de
   dépliants. */
.fct__entete:focus-visible {
  outline: 2px solid var(--pj-accent);
  outline-offset: -2px;
}
.fct__nom {
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-weight: 600; font-size: .95rem;
  min-width: 0;
  /* **Collé au chevron.** L en-tête a trois éléments — chevron, nom, mesures — et
     `space-between` centrait celui du milieu : constaté au navigateur, l intitulé
     flottait au milieu de la ligne, loin de sa poignée. La marge automatique pousse les
     mesures à droite et laisse le nom là où l œil le cherche. */
  margin-right: auto;
}
.fct__mesures {
  display: inline-flex; align-items: center; gap: 10px;
  flex: 0 0 auto;
}
/* Un filet sous l'en-tête **seulement quand c'est ouvert** : fermé, il ferait une ligne
   sous chaque carte, et la liste ressemblerait à un tableau sans colonnes. */
.fct[open] > .fct__entete { border-bottom: 1px solid var(--pj-filet); }

/* --- les onglets ------------------------------------------------------- */
/* Les entrées restent dans le flux et **focalisables au clavier** : `display: none` les
   aurait rendues inatteignables sans souris, ce qui est le défaut habituel de cette
   technique. Réduites à un pixel et transparentes, elles ne se voient pas ; le label
   sert de cible au pointeur. */
.onglets-f__choix {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

.onglets-f__barre {
  display: flex; align-items: center; gap: 4px;
  padding: 0 18px;
  border-bottom: 1px solid var(--pj-filet);
  background: var(--pj-fond-doux);
}
.onglets-f__onglet {
  padding: 9px 12px;
  font-size: .82rem; font-weight: 600;
  color: var(--pj-mute);
  border-bottom: 2px solid transparent;
  cursor: pointer;
  user-select: none;
}
.onglets-f__onglet:hover { color: var(--pj-encre); }
.onglets-f__nombre {
  font-weight: 400;
  color: var(--pj-mute);
}
/* Poussées à droite : ce sont des gestes sur la fonctionnalité, pas des onglets. */
.onglets-f__actions {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 6px;
}

/* **Le focus clavier porte sur la barre entière et non sur l'onglet visé.** Un bouton
   radio masqué ne peut pas montrer son propre anneau ; cerner la barre dit au moins
   « le focus est ici, employez les flèches ». C'est une limite assumée de la technique
   sans script, et mieux vaut l'écrire que la laisser croire résolue. */
.onglets-f__choix:focus-visible ~ .onglets-f__barre {
  outline: 2px solid var(--pj-accent);
  outline-offset: -2px;
}

.onglets-f__panneau { display: none; }
/* `:checked ~` ne regarde que les frères **qui suivent** : c'est pourquoi les deux
   entrées précèdent la barre et les panneaux dans le balisage. `nth-of-type` compte parmi
   les éléments de même nom, donc parmi les `input` d'un côté et les `label` de l'autre —
   les commentaires de gabarit ne produisant aucun nœud, le compte reste juste. */
/* Trois paires depuis le 9 septembre 2026, avec les sous-fonctionnalités. Le troisième
   onglet n'existe que sur un parent ; la règle ne trouve alors simplement rien à viser,
   et il n'y a rien à conditionner. */
.onglets-f__choix:nth-of-type(1):checked ~ .onglets-f__panneaux > .onglets-f__panneau:nth-child(1),
.onglets-f__choix:nth-of-type(2):checked ~ .onglets-f__panneaux > .onglets-f__panneau:nth-child(2),
.onglets-f__choix:nth-of-type(3):checked ~ .onglets-f__panneaux > .onglets-f__panneau:nth-child(3) {
  display: block;
}
.onglets-f__choix:nth-of-type(1):checked ~ .onglets-f__barre > label:nth-of-type(1),
.onglets-f__choix:nth-of-type(2):checked ~ .onglets-f__barre > label:nth-of-type(2),
.onglets-f__choix:nth-of-type(3):checked ~ .onglets-f__barre > label:nth-of-type(3) {
  color: var(--pj-encre);
  border-bottom-color: var(--pj-accent);
}

/* --- l'emboîtement à un cran ------------------------------------------- */
/* Une sous-fonctionnalité vit dans le troisième panneau de sa parente. Elle garde la
   forme d'un dépliant — même chevron, même barre d'onglets — parce que c'est une
   fonctionnalité à part entière : lui donner une apparence de sous-liste aurait laissé
   croire qu'elle ne porte pas de travail.

   Ce qui la distingue est mesuré, pas décoratif : un liseré à gauche, qui dit la
   filiation sans ajouter d'indentation. Une indentation aurait rétréci le tableau des
   tâches à chaque cran, et c'est le tableau qui compte. */
.fct__sous { padding: 12px 14px; background: var(--pj-fond-creux); }

.fct--enfant {
  margin-bottom: 8px;
  border-left: 3px solid var(--pj-accent-clair);
  box-shadow: none;
  border-top: 1px solid var(--pj-filet);
  border-right: 1px solid var(--pj-filet);
  border-bottom: 1px solid var(--pj-filet);
}
.fct--enfant:last-child { margin-bottom: 0; }
/* Le nom d'un enfant est un cran moins fort que celui de sa parente : la hiérarchie se
   lit alors sans compter les liserés. */
.fct--enfant > .fct__entete > .fct__nom { font-weight: 600; font-size: .88rem; }

.fct__infos { padding: 16px 18px; }
.fct__infos .captures { margin-top: 14px; }

/* ==========================================================================
   ADAPTATION AUX ÉCRANS — DOIT RESTER EN FIN DE FEUILLE
   ==========================================================================
   Une `@media` de même spécificité qu'une règle de base ne gagne que si elle est
   écrite **après** elle. Ces blocs se trouvaient au milieu du fichier, avant la
   section « Menu horizontal » : `.menu { display: flex }` écrasait donc le
   `display: none` du régime compact, et le panneau restait déplié sur téléphone —
   sans qu'aucune erreur ne le signale, la media query étant bien appliquée par
   ailleurs. Ne rien ajouter après ce commentaire qui ne soit pas une adaptation.
   ========================================================================== */
/* --------------------------------------------------------------------------
   Adaptation du bandeau
   --------------------------------------------------------------------------
   Trois régimes, et non une suite de rustines :

   1. **Bureau** (> 1040 px) — tout sur une ligne : identité, rubriques, compte.
   2. **Intermédiaire** (760–1040 px) — l'accroche puis le nom du compte cèdent,
      les entrées se resserrent. La barre tient toujours sur une ligne.
   3. **Compact** (≤ 760 px) — les rubriques passent derrière un bouton de repli.
      Le panneau s'ouvre **sous** la barre, en pleine largeur : il n'est jamais mis
      dans un conteneur qui défile, ce qui rognerait ses sous-menus. */
@media (max-width: 1240px) {
  :root { --pj-gouttiere: 24px; }
  .bandeau__accroche { display: none; }
  .menu__entree { padding: 6px 9px; }
}

@media (max-width: 1040px) {
  .menu-compte__nom { display: none; }
}

@media (max-width: 760px) {
  :root { --pj-gouttiere: 14px; }

  .bandeau__bascule { display: flex; }
  .bandeau__noms { display: none; }

  /* Le menu quitte le flux de la barre et devient un panneau sous elle. `order`
     le place après le menu du compte, `width: 100%` lui donne toute la largeur. */
  .bandeau__inner { flex-wrap: wrap; gap: 10px; }
  .menu {
    display: none;
    order: 4;
    width: 100%;
    margin-left: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 6px 0 10px;
    border-top: 1px solid var(--pj-filet);
  }
  /* Ouvert par le script, qui pose la classe. Sans script, le bouton n'apparaît
     pas non plus : `:target` et compagnie auraient demandé de changer l'URL. */
  .menu--ouvert { display: flex; }
  .menu__entree {
    padding: 10px 4px;
    border-radius: 0;
    border-left: 2px solid transparent;
    border-bottom: 0;
    white-space: normal;
  }
  .menu__entree--active {
    background: none;
    border-left-color: var(--pj-accent);
    padding-left: 10px;
  }
  .menu__groupe { width: 100%; }
  .menu__groupe .menu__entree { width: 100%; text-align: left; }
  .menu__panneau { position: static !important; transform: none !important; border: 0;
    padding-left: 12px; box-shadow: none; }

  .menu-compte { margin-left: 0; }
  .entete-page { flex-direction: column; align-items: stretch; gap: 10px; }

  /* Une colonne de cartes : la levée du panneau se resserre, sinon l'écart entre
     deux cartes mange un tiers de l'écran. */
  .cartes { gap: 30px 0; }
  .carte-dossier__panneau { margin-left: 12px; margin-right: 12px; }
  .onglets { gap: 0; }
  .onglet { padding: 8px 10px; font-size: .84rem; }
}


