/* Portail des assistants — feuille unique, mobile d'abord.
   Aucune dépendance, aucune police distante : rien ne sort vers un tiers. */

:root {
  --fond: #0f1115;
  --fond-2: #161a21;
  --fond-3: #1d2229;
  --bord: #272d36;
  --texte: #e7eaef;
  --texte-2: #9aa4b2;
  --accent: #5ad1a0;
  /* Couleur de TEXTE posée SUR l'accent. Déclarée ici avec sa valeur par
     défaut, et recalculée par la marque blanche quand une organisation
     change l'accent. Un repli `var(--accent-texte, …)` disséminé dans les
     règles serait faux dès que l'accent change : chaque usage garderait
     son propre défaut. */
  --accent-texte: #07140f;
  --accent-sombre: #0d2a20;
  --alerte: #f0a37a;
  --rayon: 10px;
  --police: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--fond); color: var(--texte);
  font: 16px/1.55 var(--police);
  -webkit-text-size-adjust: 100%;
}

.invisible {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------------------------------------------------- connexion ----------- */
.accueil { min-height: 100%; display: grid; place-items: center; padding: 1.25rem; }

.carte-connexion {
  width: 100%; max-width: 27rem; background: var(--fond-2);
  border: 1px solid var(--bord); border-radius: 14px; padding: 2rem 1.6rem;
}
.marque { margin: 0 0 .35rem; color: var(--accent); font-size: .78rem;
          letter-spacing: .08em; text-transform: uppercase; }
.carte-connexion h1 { margin: 0 0 .6rem; font-size: 1.5rem; letter-spacing: -.02em; }
.intro { margin: 0 0 1.5rem; color: var(--texte-2); }
.mention { margin: 1.25rem 0 0; color: var(--texte-2); font-size: .85rem; }

.bouton-principal {
  display: block; width: 100%; padding: .85rem 1rem; border: 0;
  border-radius: var(--rayon); background: var(--accent); color: var(--accent-texte);
  font: 600 1rem/1 var(--police); text-align: center; text-decoration: none;
  cursor: pointer;
}
.bouton-principal:hover { filter: brightness(1.08); }
.bouton-principal:focus-visible { outline: 2px solid var(--texte); outline-offset: 2px; }

.alerte {
  margin: 0 0 1rem; padding: .7rem .85rem; border-radius: var(--rayon);
  background: #2a1d16; border: 1px solid #4a3020; color: var(--alerte);
  font-size: .9rem;
}

/* ---------------------------------------------------- barre --------------- */
.barre {
  display: flex; align-items: center; gap: .5rem;
  /* .25rem vertical : le CDC plafonne la barre à 48 px sur téléphone.
     Mesurée à 67 px avec l'ancien réglage — 20 px payés à chaque écran. */
  padding: .25rem .6rem; background: var(--fond-2);
  border-bottom: 1px solid var(--bord); min-height: 47px;
}
.titre-barre { margin: 0; font-weight: 600; font-size: .98rem; flex: 1;
               white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Sur la page de chat en étroit, le titre se réduisait à « Assis… » entre le
   bouton Conversations et le menu : trois éléments pour la largeur de deux.
   Un titre tronqué n'informe de rien, les deux boutons situent déjà. */
/* `display: none` retirerait le titre de l'ARBRE D'ACCESSIBILITÉ : plus
   de h1 sur l'écran de chat en mobile, donc plus rien à annoncer ni à
   parcourir pour un lecteur d'écran. On le masque visuellement tout en le
   laissant lisible aux outils. */
.barre:has(.bouton-colonne) .titre-barre {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.identite { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2; }

/* --- navigation ---------------------------------------------------------
   Une seule définition de liens, rendue deux fois : en ligne sur très grand
   écran, en tiroir en dessous. Les cinq écrans portaient chacun leur propre
   liste, qui divergeait à chaque ajout.

   Seuil à 104rem et non 52rem, et c'est une MESURE : à quinze destinations,
   la navigation en ligne occupe 1 442 px et l'en-tête entier 1 572 px —
   1600 px ne suffisait donc pas, marges comprises. À
   52rem (832 px) elle débordait donc de la page sur tout écran d'ordinateur
   portable — la page partait sur la droite, sans la moindre erreur. Le
   défaut existait avant d'ajouter « Démarrage » : à quatorze entrées la
   barre faisait déjà 1 338 px.

   Choix assumé : un tiroir qui marche plutôt qu'une barre qui déborde. Le
   tiroir est replié par groupes et tient sur un écran de 667 px, vérifié. */
.nav-large, .barre .nav-large-seul { display: none; }
.barre .nom-lien { display: none; }
@media (min-width: 64rem) {
  .barre .nom-lien { display: inline-flex; white-space: nowrap; overflow: hidden;
                     text-overflow: ellipsis; max-width: 12rem; }
}

.nav-liens { display: flex; flex-direction: column; gap: .15rem; }
.nav-liens a {
  display: flex; align-items: center; min-height: 44px;
  padding: .5rem .7rem; border-radius: 8px; border-left: 3px solid transparent;
  color: var(--texte-2); text-decoration: none; font-size: .92rem;
}
.nav-liens a:hover { background: var(--fond-3); color: var(--texte); }
/* La page courante se signale par une barre, pas par une couleur seule :
   lisible aussi sans distinguer les teintes. */
.nav-liens a[aria-current="page"] {
  background: var(--fond-3); color: var(--texte); border-left-color: var(--accent);
  font-weight: 600;
}
.nav-groupe {
  margin: .35rem .7rem .05rem; color: var(--texte-2); font-size: .78rem;
  border-top: 1px solid var(--bord); padding-top: .35rem;
}

/* Le tiroir doit tenir dans l'écran, cibles tactiles comprises.
   Mesuré : 14 entrées faisaient 917 px de contenu pour 844 px visibles — il
   fallait faire défiler un MENU. La place est reprise sur les marges et les
   séparateurs, jamais sur la hauteur des liens : 44 px est le minimum pour
   viser au pouce, et un menu compact qu'on rate n'est pas un gain. */
@media (max-height: 56rem) {
  .tiroir { padding: .6rem .8rem; gap: .15rem; }
  .tiroir-tete { margin-bottom: .25rem; }
  .tiroir .nav-groupe { margin: .2rem .7rem .02rem; padding-top: .25rem; }
  .tiroir .nav-liens { gap: .05rem; }
  .tiroir .nav-liens a { min-height: 42px; padding: .35rem .7rem; }
  .tiroir .lien-discret { padding: .4rem .7rem; min-height: 42px; }
}

.voile {
  position: fixed; inset: 0; background: rgba(5, 7, 10, .6);
  z-index: 20; border: 0;
}
.tiroir {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 21;
  width: min(18rem, 85vw); padding: 1rem .8rem;
  background: var(--fond-2); border-left: 1px solid var(--bord);
  display: flex; flex-direction: column; gap: .3rem;
  overflow-y: auto;
}
.tiroir-tete { display: flex; align-items: center; justify-content: space-between;
               margin-bottom: .6rem; }
/* Cible tactile : 44 px, comme tout ce qui se touche au pouce. */
#fermer-tiroir { min-width: 44px; min-height: 44px; font-size: 1.4rem; }

/* `display: flex` écrase l'attribut `hidden` du navigateur : le tiroir restait
   présent, invisible, et interceptait les clics sur le bouton censé l'ouvrir.
   Défaut invisible à la relecture, évident à la première capture d'écran. */
.tiroir[hidden], .voile[hidden] { display: none; }
.tiroir .lien-discret { margin-top: auto; padding: .6rem .7rem; min-height: 44px;
                        display: flex; align-items: center; }
.nom { font-size: .85rem; }
.lien-discret { color: var(--texte-2); font-size: .78rem; text-decoration: none; }
.lien-discret:hover { color: var(--texte); text-decoration: underline; }

/* Deux ouvertures coexistent sur la page de chat : les conversations (à
   gauche, nommée) et la navigation (à droite, en icône). Les distinguer par la
   forme évite d'avoir à se souvenir laquelle fait quoi. */
.bouton-colonne {
  min-height: 38px; padding: .35rem .7rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: 8px; color: var(--texte);
  font: inherit; font-size: .84rem; cursor: pointer; white-space: nowrap;
}
.bouton-colonne:hover { border-color: var(--accent); }

.bouton-nav {
  display: grid; gap: 4px; align-content: center;
  width: 38px; height: 38px; padding: .5rem;
  background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: 8px; cursor: pointer; flex: 0 0 auto;
}
.bouton-nav span { display: block; height: 2px; background: var(--texte); border-radius: 2px; }
.bouton-nav:hover { border-color: var(--accent); }

/* Ancien bouton du menu latéral : conservé comme alias le temps que les
   anciennes pages en cache disparaissent. */
.bouton-menu { display: none; }

/* `hidden` l'emporte sur tout `display` d'auteur : sans cette règle, tout
   élément à la fois masqué par l'attribut et stylé en flex/grid s'affiche
   quand même — le formulaire de renommage en était le troisième cas. */
[hidden] { display: none !important; }

/* ------------------------------------------------- avertissement IA ------ */
/* Plus de bandeau permanent : mesuré à 90 px sur 844, payé à chaque écran
   pour une phrase lue une fois. La mention courte vit sous la saisie, la
   version entière sur l'écran d'accueil d'une conversation vide — là où il
   y a la place de la lire. */
.mention-ia {
  margin: .25rem 0 0; text-align: center;
  color: var(--texte-2); font-size: .72rem;
}
.avertissement-complet {
  margin-top: 1rem; padding: .7rem .85rem;
  background: var(--accent-sombre); border: 1px solid #1d4034;
  border-radius: var(--rayon); color: #a9e4cb; font-size: .85rem;
}

/* ---------------------------------------------------- disposition -------- */
/* La page de conversation ne défile jamais en entier : seul le fil défile.
   Avant, `min-height` laissait le document grandir, et la zone de saisie
   partait sous la ligne de flottaison dès que la conversation s'allongeait.
   `dvh` et non `vh` : sur téléphone, `vh` ignore la barre du navigateur et
   la saisie se retrouvait sous elle. Le sélecteur `:has` limite la règle à
   l'écran de conversation — les autres écrans défilent normalement. */
/* Le gabarit enveloppe le contenu dans `#contenu` (cible du lien
   d'évitement) : la chaîne de hauteur doit traverser CE maillon aussi.
   Première version en `body:has(> .pageur)` : enfant direct, jamais
   vrai, règle morte — et le fil mesurait 40 px au lieu de l'écran. */
body:has(.pageur) { display: flex; flex-direction: column;
                    height: 100dvh; overflow: hidden; }
body:has(.pageur) > #contenu { flex: 1; min-height: 0;
                               display: flex; flex-direction: column; }
.pageur { display: flex; flex: 1; min-height: 0; }

/* La colonne est un TIROIR sous 64 rem : elle glisse par-dessus le fil,
   et un voile ferme d'un clic au-dehors. Avant, elle était cachée jusqu'à
   104 rem — un seuil mesuré pour la barre de navigation à quinze entrées,
   recopié ici par erreur : la liste des conversations était invisible sur
   la quasi-totalité des écrans d'ordinateur. */
.colonne {
  position: fixed; inset: 0 auto 0 0; z-index: 30;
  display: flex; flex-direction: column; gap: .5rem;
  width: min(20rem, 88vw); padding: 1rem .9rem;
  background: var(--fond-2); border-right: 1px solid var(--bord);
  overflow-y: auto;
  transform: translateX(-102%); transition: transform .18s ease-out;
}
.colonne.ouverte { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) { .colonne { transition: none; } }
.voile-colonne { position: fixed; inset: 0; z-index: 29;
                 background: rgba(0, 0, 0, .45); }

.etiquette { margin: 0 0 .35rem; color: var(--texte-2); font-size: .74rem;
             letter-spacing: .08em; text-transform: uppercase; }
.vide { color: var(--texte-2); font-size: .9rem; }

.liste-assistants { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.assistant {
  display: grid; gap: .15rem; width: 100%; padding: .7rem .8rem; text-align: left;
  background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: var(--rayon); color: var(--texte); cursor: pointer; font: inherit;
}
.assistant:hover { border-color: #3a4450; }
.assistant[aria-selected="true"] { border-color: var(--accent); background: var(--accent-sombre); }
.assistant-nom { font-weight: 600; font-size: .94rem; }
.assistant-desc { color: var(--texte-2); font-size: .82rem; }

/* ---------------------------------------------------- échange ------------ */
.echange { flex: 1; display: flex; flex-direction: column; min-width: 0;
           min-height: 0; position: relative; }

.fil { flex: 1; min-height: 0; overflow-y: auto; padding: 1rem .9rem 1.5rem; }

/* Colonne de lecture bornée à 56 rem et centrée : au-delà, l'œil perd la
   ligne. C'est la seule des quatre convergences des interfaces de
   référence qui soit purement typographique. */
.colonne-lecture { max-width: 56rem; margin: 0 auto; width: 100%;
                   display: grid; gap: 1rem; align-content: start; }

.accueil-fil { color: var(--texte-2); max-width: 34rem; margin: 2rem auto 0; }
.accueil-fil h2 { margin: 0 0 .4rem; color: var(--texte); font-size: 1.15rem; }
.accueil-fil p { margin: 0 0 .5rem; font-size: .92rem; }

/* La QUESTION est une bulle, la RÉPONSE est du texte pleine largeur, sans
   fond : c'est la distinction sur laquelle Claude, ChatGPT, Copilot et
   Open WebUI sont unanimes, et son absence était le défaut le plus cher
   de l'ancien écran — on ne savait pas qui parlait. */
.bulle { border-radius: 14px; }
.bulle.question { background: var(--fond-3); border: 1px solid var(--bord);
                  justify-self: end; max-width: 85%; padding: .7rem .95rem; }
.bulle.reponse { background: transparent; border: 0; padding: 0;
                 max-width: none; }
.signature-reponse { margin: 0 0 .3rem; color: var(--texte-2);
                     font-size: .76rem; font-weight: 600; }
.bulle.incident { background: #2a1d16; border: 1px solid #4a3020;
                  color: var(--alerte); padding: .8rem .95rem; }
.bulle p { margin: 0 0 .5rem; white-space: pre-wrap; }
.bulle p:last-child { margin-bottom: 0; }

/* « Descendre » : visible dès que la vue n'est plus en bas. Sans lui, on
   remonte lire une source et on ne retrouve plus la réponse en cours
   d'écriture — huit minutes plus bas. */
.descendre {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: 7.5rem; z-index: 5;
  width: 2.25rem; height: 2.25rem; border-radius: 50%;
  background: var(--fond-3); border: 1px solid var(--bord);
  color: var(--texte); font-size: 1rem; cursor: pointer;
}
.descendre:hover { border-color: var(--accent); color: var(--accent); }

.attente { display: flex; align-items: center; gap: .55rem;
           color: var(--texte-2); font-size: .88rem; }
.point { width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
         animation: battement 1.2s ease-in-out infinite; }
@keyframes battement { 0%,100% { opacity: .25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .point { animation: none; opacity: .8; } }

.sources-repli { margin: .75rem 0 0; }
.sources-repli summary { cursor: pointer; color: var(--texte-2);
                         font-size: .8rem; min-height: 24px;
                         display: inline-flex; align-items: center; }
.sources-repli summary:hover { color: var(--accent); }
.sources { margin: .75rem 0 0; padding: .7rem .8rem; background: var(--fond-3);
           border: 1px solid var(--bord); border-radius: var(--rayon); }
.sources p { margin: 0 0 .4rem; color: var(--texte-2); font-size: .75rem;
             letter-spacing: .06em; text-transform: uppercase; }
.sources ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .25rem; }
.sources li { font-size: .88rem; }
.page { display: inline-block; margin-left: .35rem; padding: .05rem .4rem;
        background: var(--accent-sombre); border: 1px solid #1d4034;
        border-radius: 5px; color: #a9e4cb; font-size: .78rem; }

/* ---------------------------------------------------- saisie ------------- */
/* UNE boîte arrondie qui contient le texte ET les commandes — joindre et
   dicter à gauche, envoyer à droite. Avant : un champ puis quatre boutons
   posés à côté en ligne souple, qui débordaient de la colonne dès qu'on en
   ajoutait un — c'est le défaut `min-width: auto` déjà payé une fois. */
.zone-saisie {
  padding: .45rem .6rem; background: var(--fond-2);
  border-top: 1px solid var(--bord);
  /* Clavier mobile : la zone de saisie reste au-dessus de la barre système. */
  padding-bottom: max(.5rem, env(safe-area-inset-bottom));
}
.saisie {
  display: flex; flex-direction: column; gap: .25rem;
  max-width: 56rem; margin: 0 auto;
  padding: .4rem .5rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: 16px;
}
.saisie:focus-within { border-color: var(--accent); }
.saisie textarea {
  width: 100%; min-height: 1.5rem;
  /* 12.5 rem = 200 px, puis défilement interne : jamais plus du quart d'un
     écran de téléphone. Le plafond vit AUSSI dans app.js (auto-grandi). */
  max-height: 12.5rem; padding: .35rem .3rem;
  background: transparent; border: 0;
  color: var(--texte); font: inherit; resize: none;
}
.saisie textarea:focus-visible { outline: none; }
.saisie-commandes { display: flex; align-items: center; gap: .15rem; }
.saisie-espace { flex: 1; }
.saisie button[type="submit"] {
  padding: .5rem .95rem; border: 0; border-radius: 999px;
  background: var(--accent); color: #07140f; font: 600 .9rem/1 var(--police);
  cursor: pointer;
}
.saisie button[disabled] { opacity: .5; cursor: progress; }
.saisie .liste-pieces { margin: 0 0 .15rem; }

/* ---------------------------------------------------- écran large -------- */
@media (min-width: 104rem) {
  .bouton-nav, .bouton-colonne { display: none; }
  .barre:has(.bouton-colonne) .titre-barre { display: block; }
  .nav-large { display: block; }
  .barre .nav-large-seul { display: inline-flex; }
  .nav-large .nav-liens { flex-direction: row; align-items: center; gap: .1rem; }
  .nav-large .nav-liens a { min-height: 36px; padding: .35rem .6rem;
                            border-left: 0; border-bottom: 2px solid transparent; }
  .nav-large .nav-liens a[aria-current="page"] {
    border-left: 0; border-bottom-color: var(--accent); background: transparent;
  }
  /* Le séparateur de groupe n'a de sens qu'empilé ; en ligne, un trait
     vertical suffit. */
  .nav-large .nav-groupe {
    margin: 0 .4rem; padding: 0 0 0 .6rem; border-top: 0;
    border-left: 1px solid var(--bord); font-size: 0; width: 1px;
  }
}

@media (min-width: 64rem) {
  .bouton-colonne { display: none; }
  .colonne { position: static; transform: none; transition: none;
             width: 17.5rem; flex: 0 0 17.5rem; }
  .voile-colonne { display: none; }
  .fil { padding: 1.5rem 1.5rem 2rem; }
  .zone-saisie { padding: .75rem 1.5rem; }
  .zone-saisie { padding-bottom: max(1rem, env(safe-area-inset-bottom)); }
}

/* ---------------------------------------------------- administration ----- */
.lien-retour {
  display: grid; place-items: center; width: 2.1rem; height: 2.1rem;
  background: var(--fond-3); border: 1px solid var(--bord); border-radius: 8px;
  color: var(--texte); text-decoration: none; font-size: 1.1rem;
}
.lien-retour:hover { border-color: #3a4450; }

.admin { padding: 1rem .9rem 2.5rem; display: grid; gap: 1.1rem;
         max-width: 56rem; margin: 0 auto; }
.bloc { background: var(--fond-2); border: 1px solid var(--bord);
        border-radius: 12px; padding: 1rem .9rem; }

.onglets { display: flex; flex-wrap: wrap; gap: .4rem; }
.onglet {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .5rem .75rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: 999px;
  color: var(--texte); text-decoration: none; font-size: .9rem;
}
.onglet.actif { border-color: var(--accent); background: var(--accent-sombre); }
.compteur { padding: .05rem .4rem; background: var(--fond); border-radius: 999px;
            font-size: .75rem; color: var(--texte-2); }

.formulaire-depot { display: grid; gap: .9rem; }
.champ { display: grid; gap: .3rem; }
.champ label { font-size: .88rem; font-weight: 600; }
.facultatif { font-weight: 400; color: var(--texte-2); }
.champ input, .champ select {
  padding: .6rem .7rem; background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: var(--rayon); color: var(--texte); font: inherit; width: 100%;
  /* `width: 100%` ne suffit pas pour un `select` : sa largeur MINIMALE est
     celle de son option la plus longue, et elle l'emporte. Mesuré sur
     /cles : 363 px de champ dans un écran de 360. Trois pixels, et toute la
     page part sur la droite. */
  min-width: 0; max-width: 100%; box-sizing: border-box;
}
.champ input[type="file"] { padding: .5rem; }
.champ input:focus-visible, .champ select:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.aide { margin: 0; color: var(--texte-2); font-size: .8rem; }
.deux-colonnes { display: grid; gap: .9rem; }

#bouton-depot {
  padding: .75rem 1.1rem; border: 0; border-radius: var(--rayon);
  background: var(--accent); color: #07140f; font: 600 .95rem/1 var(--police);
  cursor: pointer; justify-self: start;
}
#bouton-depot[disabled] { opacity: .5; cursor: progress; }

.retour-depot { margin: 0; font-size: .88rem; color: var(--texte-2); }
.retour-depot.ok { color: var(--accent); }
.retour-depot.erreur { color: var(--alerte); }

.documents { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
.document { padding: .75rem .8rem; background: var(--fond-3);
            border: 1px solid var(--bord); border-radius: var(--rayon); }
.document-tete { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; }
.document-titre { font-weight: 600; font-size: .95rem; }
.pastille { padding: .05rem .45rem; border-radius: 999px; font-size: .72rem;
            border: 1px solid var(--bord); color: var(--texte-2); }
.pastille.restreint { background: #2a1d16; border-color: #4a3020; color: var(--alerte); }
.pastille.retire { background: var(--fond); }

.versions { list-style: none; margin: .45rem 0 0; padding: 0; display: grid;
            gap: .2rem; color: var(--texte-2); font-size: .84rem; }
.statut { margin-left: .35rem; padding: .05rem .45rem; border-radius: 5px;
          font-size: .76rem; }
.statut-indexe { background: var(--accent-sombre); color: #a9e4cb; }
.statut-en_cours, .statut-en_attente { background: #1f2a3a; color: #a8c4e8; }
.statut-en_erreur { background: #2a1d16; color: var(--alerte); }
.statut-desindexe { background: var(--fond); color: var(--texte-2); }
.expire { margin-left: .35rem; color: var(--texte-2); font-size: .78rem; }

.retirer {
  margin-top: .55rem; padding: .4rem .7rem; background: transparent;
  border: 1px solid #4a3020; border-radius: 8px; color: var(--alerte);
  font: inherit; font-size: .84rem; cursor: pointer;
}
.retirer:hover { background: #2a1d16; }
.retirer[disabled] { opacity: .5; cursor: progress; }

.lien-admin {
  padding: .35rem .7rem; border: 1px solid var(--accent); border-radius: 8px;
  color: var(--accent); text-decoration: none; font-size: .85rem; white-space: nowrap;
}
.lien-admin:hover { background: var(--accent-sombre); }

/* Ligne de documentation : le lien respire au-dessus et en dessous.
   `white-space: nowrap` du lien l'empêcherait de se couper sur un
   téléphone — ici le libellé tient, mais la ligne doit pouvoir passer
   sous le lien plutôt que déborder. */
.lien-doc { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
            margin: -.2rem 0 .3rem; }

.lien-gerer {
  display: block; margin-top: .9rem; padding: .55rem .7rem; text-align: center;
  background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: var(--rayon); color: var(--texte); text-decoration: none;
  font-size: .88rem;
}
.lien-gerer:hover { border-color: var(--accent); }

@media (min-width: 52rem) {
  .admin { padding: 1.5rem 1.5rem 3rem; }
  .deux-colonnes { grid-template-columns: 1fr 1fr; }
}

/* ---------------------------------------------------- plateforme -------- */
.valeur-tech { margin-left: auto; color: var(--texte-2); font-size: .84rem;
               font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.detail-tech { margin: .3rem 0 0; color: var(--texte-2); font-size: .84rem; }
.detail-tech strong { color: var(--texte); font-family: ui-monospace, SFMono-Regular,
                      Menlo, monospace; font-weight: 600; }

/* ---------------------------------------------------- segments --------- */
.segments { list-style: none; margin: .6rem 0 0; padding: 0; display: grid; gap: .5rem; }
.segment { padding: .6rem .7rem; background: var(--fond-3);
           border: 1px solid var(--bord); border-radius: var(--rayon); }
.segment-tete { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
                margin-bottom: .35rem; }
.segment-texte { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere;
                 font-size: .88rem; line-height: 1.5; color: var(--texte-2); }
/* Écrit pour un `<a>`, réutilisé sur un `<button>` : sans remise à zéro,
   le bouton garde le FOND GRIS du navigateur, et ce gris clair sous un
   texte gris clair donnait 2,19:1 — sous le seuil de 4,5. Le défaut n'a
   été vu qu'en mesurant l'écran Comptes, qu'aucun script n'atteignait
   (second facteur). `background: transparent` et `font: inherit` rendent
   la classe valable pour les deux balises. */
.lien-voir { margin-left: auto; padding: .25rem .55rem; border: 1px solid var(--bord);
             border-radius: 8px; background: transparent;
             color: var(--texte-2); text-decoration: none;
             font: inherit; font-size: .8rem; white-space: nowrap;
             cursor: pointer; min-height: 24px;
             display: inline-flex; align-items: center; }
.lien-voir:hover { border-color: var(--accent); color: var(--accent); }

/* Bloc d'alerte : une seule occasion de copier la clé, la page doit le crier. */
.bloc-alerte { border-color: var(--alerte); background: #1d1512; }

/* Le secret s'affiche en entier et se coupe plutôt que de déborder : sur un
   téléphone, une chaîne de 60 caractères sortirait de l'écran sans retour. */
.secret {
  margin: .5rem 0; padding: .65rem .75rem; background: var(--fond);
  border: 1px dashed var(--alerte); border-radius: var(--rayon);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .82rem;
  overflow-wrap: anywhere; user-select: all;
}

/* Les deux exports restent groupés et passent à la ligne ensemble plutôt que
   de se séparer de part et d'autre de l'écran sur un téléphone. */

/* Annonce d'arrivée : en bas de l'écran, au-dessus du contenu mais sous la
   saisie sur mobile — un bandeau qui recouvre le champ de question ferait
   manquer le geste suivant. */
.annonce {
  position: fixed; left: .7rem; right: .7rem; bottom: .7rem; z-index: 40;
  display: flex; align-items: center; gap: .6rem; padding: .7rem .8rem;
  background: var(--accent-sombre); border: 1px solid var(--accent);
  border-radius: var(--rayon); box-shadow: 0 6px 24px rgba(0, 0, 0, .45);
}
.annonce a { color: var(--accent); font-size: .9rem; flex: 1; }
@media (min-width: 52rem) {
  .annonce { left: auto; right: 1.2rem; bottom: 1.2rem; max-width: 26rem; }
}

/* Recherche dans l'historique, au-dessus de la liste des fils. */
.recherche-fils { display: flex; gap: .3rem; margin: .4rem 0 .6rem; }
.recherche-fils input {
  flex: 1; min-width: 0; padding: .4rem .55rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: 8px; color: var(--texte);
  font: inherit; font-size: .85rem;
}
/* L'extrait situe le résultat : sans lui, il faut ouvrir chaque fil pour
   savoir lequel contenait le terme cherché. */
.extrait { display: block; margin-top: .15rem; color: var(--texte-2);
           font-size: .76rem; line-height: 1.3; }

/* Zone de saisie d'une consigne : large, et qui grandit avec le texte sans
   repousser le bouton hors de l'écran sur téléphone. */
textarea {
  width: 100%; box-sizing: border-box; margin: .3rem 0 .5rem;
  padding: .55rem .65rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: var(--rayon);
  color: var(--texte); font: inherit; font-size: .88rem; line-height: 1.45;
  resize: vertical; min-height: 4rem;
}

/* L'échelle des niveaux : on lit l'ordre, c'est la propriété de sécurité. */
.echelle { margin: .5rem 0 0; padding-left: 1.2rem; color: var(--texte-2);
           font-size: .84rem; line-height: 1.6; }
.echelle strong { color: var(--texte); }

/* Aperçu du message système : du texte brut, qui se coupe plutôt que de
   déborder — sur téléphone, une ligne de 200 caractères sortirait de l'écran. */
.apercu-consigne {
  margin: .4rem 0 0; padding: .7rem .8rem; background: var(--fond);
  border: 1px solid var(--bord); border-radius: var(--rayon);
  color: var(--texte-2); font-size: .78rem; line-height: 1.5;
  white-space: pre-wrap; overflow-wrap: anywhere; max-height: 22rem;
  overflow-y: auto;
}

/* Groupe repliable du tiroir. Le chevron dit l'état ; le groupe de la page
   courante est ouvert, pour qu'on voie toujours où l'on est. */
.nav-repli > summary.nav-groupe {
  cursor: pointer; list-style: none; display: flex; align-items: center;
  gap: .3rem; min-height: 32px;
}
.nav-repli > summary::-webkit-details-marker { display: none; }
.nav-repli > summary::before { content: "▸"; color: var(--accent); font-size: .7rem; }
.nav-repli[open] > summary::before { content: "▾"; }

/* --------------------------------------------- inventaire ------------- */
/* Les quatre états, lisibles d'un coup d'œil. Couleurs distinctes en vision
   déficiente : bleu et orange se séparent, vert et orange non. */
.compteurs { display: flex; flex-wrap: wrap; gap: .4rem; margin: .4rem 0 .6rem; }
.compteur-etat { padding: .2rem .55rem; border-radius: 999px; font-size: .78rem;
                 border: 1px solid var(--bord); color: var(--texte-2); }
.compteur-etat strong { color: var(--texte); }
.etat-fait          { border-color: var(--accent); }
.etat-developpement { border-color: #5b8db8; }
.etat-question      { border-color: var(--bord); }
.etat-ecarte        { border-color: #6b4a3a; }

/* Une ligne porte sa couleur à gauche : on balaie la liste sans lire. */
.ligne-fonction { border-left: 3px solid var(--bord); }
.ligne-fonction.etat-fait          { border-left-color: var(--accent); }
.ligne-fonction.etat-developpement { border-left-color: #5b8db8; }
.ligne-fonction.etat-ecarte        { border-left-color: #6b4a3a; }

/* Les quatre choix : des pastilles cliquables, pas une liste déroulante —
   sur téléphone, un menu déroulant demande deux gestes au lieu d'un. */
.choix-etat { display: flex; flex-wrap: wrap; gap: .3rem; margin: .45rem 0 .35rem; }
.puce { display: inline-flex; align-items: center; }
/* Masquage ACCESSIBLE : l'entrée garde une surface de 1 px et reste dans le
   flux de tabulation. En 0×0 elle disparaît du test de survol — un outil de
   recette ne peut plus la cliquer, et certains lecteurs d'écran la sautent.
   Le motif ci-dessous est celui qui préserve les deux. */
.puce input {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}
.puce span {
  display: inline-block; padding: .3rem .6rem; border-radius: 999px;
  border: 1px solid var(--bord); background: var(--fond-3);
  color: var(--texte-2); font-size: .78rem; cursor: pointer;
}
.puce input:checked + span { color: #07140f; font-weight: 600; }
.puce-fait input:checked + span          { background: var(--accent); border-color: var(--accent); }
.puce-developpement input:checked + span { background: #5b8db8; border-color: #5b8db8; }
.puce-question input:checked + span      { background: var(--texte-2); border-color: var(--texte-2); }
.puce-ecarte input:checked + span        { background: #b5774f; border-color: #b5774f; }
/* Le focus clavier doit rester visible : sans cela, la navigation au clavier
   se fait à l'aveugle sur soixante lignes. */
.puce input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.note-fonction {
  width: 100%; box-sizing: border-box; padding: .35rem .55rem;
  background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: 8px; color: var(--texte); font: inherit; font-size: .8rem;
}

/* Avec soixante lignes, un bouton en bas de page obligerait à tout remonter. */
.barre-action {
  position: sticky; bottom: 0; z-index: 30; padding: .7rem .9rem;
  background: linear-gradient(to top, var(--fond) 70%, transparent);
}
.barre-action .bouton-principal { width: 100%; }

/* ------------------------------------------- architecture ------------- */
/* Couches empilées, pas un schéma SVG : un dessin ne se lit pas sur 390 px,
   et celui-ci se plie à la largeur disponible. */
.couche { margin: .6rem 0; padding-left: .7rem; border-left: 2px solid var(--bord); }
.couche-titre { display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem;
                margin: 0 0 .3rem; }
.couche-nom { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
              color: var(--accent); font-weight: 600; }
.briques { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.brique { display: grid; gap: .12rem; padding: .5rem .6rem; border-radius: var(--rayon);
          background: var(--fond-2); border: 1px solid var(--bord);
          border-left: 3px solid var(--texte-2); font-size: .84rem; }
.brique.etat-actif { border-left-color: var(--accent); }
.brique.etat-sans-réponse, .brique.etat-sans-reponse { border-left-color: var(--alerte); }
.brique-tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem; }
.brique-etat { font-size: .72rem; color: var(--texte-2); }
.brique-role { color: var(--texte-2); font-size: .8rem; }
/* La flèche porte le sens de l'appel : on lit la chaîne sans légende. */
.brique-flux { color: var(--accent); font-size: .78rem; }
.brique-stock { color: var(--texte-2); font-size: .76rem;
                font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.brique-note { color: var(--texte-2); font-size: .76rem; line-height: 1.45;
               margin-top: .15rem; }
/* Un écart entre la carte et la réalité doit sauter aux yeux : c'est tout
   l'intérêt de confronter l'une à l'autre. */
.ecart-carte { border-left: 3px solid var(--alerte); padding-left: .6rem; }

/* ------------------------------------------- topologie ----------------- */
/* Arbre du découpage. Des filets et des retraits plutôt qu'un dessin : un
   schéma SVG ne se lit pas sur un téléphone de 390 px, et celui-ci se plie
   tout seul à la largeur disponible. */
.organisation { margin: .6rem 0 1rem; padding-left: .2rem; }
.branches, .feuilles { list-style: none; margin: .25rem 0 0 .55rem; padding: 0 0 0 .7rem;
                       border-left: 1px solid var(--bord); }
.noeud { margin: .3rem 0; }
.noeud-tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem;
              margin: 0; font-size: .88rem; }
/* Le TYPE du nœud est écrit, pas suggéré par une icône : « unité » et
   « assistant » ne se devinent pas, et c'est tout l'objet de cet écran. */
.noeud-type { padding: .05rem .4rem; border-radius: 999px; font-size: .68rem;
              text-transform: uppercase; letter-spacing: .04em;
              background: var(--fond-3); color: var(--texte-2); }
.feuille { display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem;
           margin: .25rem 0; font-size: .86rem; }
.feuille-inactive { opacity: .55; }
.chiffres { display: flex; gap: .5rem; margin-left: auto;
            color: var(--texte-2); font-size: .76rem;
            font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
@media (max-width: 52rem) {
  /* Sous 52 rem, les compteurs passent à la ligne plutôt que de pousser le
     nom de l'assistant hors de l'écran. */
  .chiffres { margin-left: 0; flex-basis: 100%; }
}

/* --------------------------------------------- modules ---------------- */
/* Un module éteint doit se voir sans lire : le filet de gauche suffit. */
.ligne-module { border-left: 3px solid var(--accent); }
.ligne-module.module-eteint { border-left-color: var(--texte-2); opacity: .75; }
.ligne-module.module-garde-fou { border-left-color: #b5774f; }
.actions-module { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .5rem;
                  align-items: center; }
.actions-module form { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; }
.actions-module input[type=text] {
  flex: 1 1 14rem; min-width: 0; padding: .35rem .55rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: 8px; color: var(--texte);
  font: inherit; font-size: .8rem;
}

/* ---------------------------------------------------- filtres ---------- */
.filtres { display: flex; flex-wrap: wrap; gap: .5rem; margin: .7rem 0; }
.filtres input, .filtres select {
  flex: 1 1 11rem; padding: .5rem .6rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: var(--rayon);
  color: var(--texte); font: inherit; font-size: .88rem;
}
.filtres button {
  padding: .5rem 1rem; border: 0; border-radius: var(--rayon);
  background: var(--accent); color: #07140f; font: 600 .88rem/1 var(--police);
  cursor: pointer;
}
/* Un bouton secondaire placé dans un bloc de filtres héritait de l'allure de
   l'action principale : deux boutons verts pleins sur le même écran, dont un
   seul compte. La règle de `.filtres button` est reprise ici explicitement —
   sans cela, elle gagne par ordre d'apparition. */
.filtres button.fil-action {
  background: var(--fond-3); color: var(--texte); border: 1px solid var(--bord);
  font-weight: 500;
}
.filtres button.fil-action:hover { background: var(--fond); color: var(--accent); }

/* Le réglage d'une clé est une action occasionnelle : replié par défaut, il
   laisse la liste lisible. Déplié partout, trois clés remplissaient l'écran. */
.reglage > summary {
  cursor: pointer; color: var(--texte-2); font-size: .84rem; padding: .3rem 0;
  list-style: none;
}
.reglage > summary::-webkit-details-marker { display: none; }
.reglage > summary::before { content: "▸ "; color: var(--accent); }
.reglage[open] > summary::before { content: "▾ "; }

/* Étiquette d'un champ de filtre : sur téléphone, un champ sans mot au-dessus
   se devine mal, et le placeholder disparaît dès la première frappe. */
.filtres label { display: flex; flex: 1 1 11rem; align-items: center; gap: .4rem;
                 color: var(--texte-2); font-size: .82rem; }
.filtres label input { flex: 1 1 auto; min-width: 0; }

/* Jauge : une barre proportionnelle, pas un graphique. Elle répond à « quel
   jour a été chargé », ce qui ne demande ni axes ni bibliothèque. */
.jauge { margin-top: .4rem; height: 6px; border-radius: 999px;
         background: var(--fond-3); overflow: hidden; }
.jauge span { display: block; height: 100%; background: var(--accent);
              border-radius: 999px; }

/* ---------------------------------------------------- courbes ---------- */
.courbe { display: block; width: 100%; height: 40px; margin-top: .4rem;
          color: var(--accent); opacity: .85; }

/* ---------------------------------------------------- fils ------------- */
.nouveau-fil { margin: .2rem 0 .5rem; }
.bouton-nouveau {
  width: 100%; padding: .5rem .7rem; background: var(--accent-sombre);
  border: 1px solid var(--accent); border-radius: var(--rayon);
  color: var(--accent); font: 600 .86rem/1 var(--police); cursor: pointer;
}
.bouton-nouveau:hover { background: var(--accent); color: var(--accent-texte); }

.liste-fils { list-style: none; margin: 0; padding: 0; display: grid; gap: .2rem; }
/* `min-width: 0` sur l'élément de grille, et c'est indispensable : par défaut
   un enfant de grille vaut `min-width: auto`, c'est-à-dire la largeur de son
   contenu. En ajoutant deux boutons à cette ligne, elle est passée de 250 à
   346 px dans une colonne de 280 : les boutons se retrouvaient SOUS le
   panneau de conversation, visibles mais impossibles à cliquer. Mesuré au
   navigateur (elementFromPoint rendait `div.fil`), invisible à la lecture. */
.fil-titre { display: block; white-space: nowrap; overflow: hidden;
             text-overflow: ellipsis; }
.fil-entree { display: flex; flex-wrap: nowrap; align-items: center;
              gap: .3rem; min-width: 0; }
.fil-entree a {
  flex: 1; min-width: 0; padding: .4rem .5rem; border-radius: 8px;
  color: var(--texte-2); text-decoration: none; font-size: .86rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fil-entree a:hover { background: var(--fond-3); color: var(--texte); }
.fil-entree.actif a { background: var(--fond-3); color: var(--texte); font-weight: 600; }
.fil-action {
  background: transparent; border: 0; color: var(--texte-2); cursor: pointer;
  font-size: .9rem; padding: .2rem .35rem; border-radius: 6px;
}
.fil-action:hover { color: var(--alerte); background: var(--fond-3); }

/* `min-width: 0` sur chaque maillon, sinon le titre refuse de rétrécir
   sous la largeur de son texte et pousse le menu hors de l'écran — le
   piège qui avait déjà rendu deux boutons inatteignables. */
.barre-centre { flex: 1; min-width: 0; display: flex; align-items: center;
                gap: .5rem; }
.titre-conversation { flex: 1; min-width: 0; margin: 0;
                      font-size: .98rem; font-weight: 600; }
.titre-bouton {
  display: block; max-width: 100%; min-width: 24px; min-height: 24px;
  padding: .2rem .4rem;
  background: none; border: 0; border-radius: 6px;
  color: var(--texte); font: inherit; text-align: left; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.titre-bouton:hover { background: var(--fond-3); }
.renommer { display: flex; gap: .3rem; min-width: 0; flex: 1; }
.renommer input { min-width: 0; flex: 1; }

/* Menus en `details` : natifs, au clavier, sans script obligatoire. */
.menu-fil, .menu-ligne-fil { position: relative; }
.menu-fil summary, .menu-ligne-fil summary {
  list-style: none; cursor: pointer; user-select: none;
}
.menu-fil summary::-webkit-details-marker,
.menu-ligne-fil summary::-webkit-details-marker { display: none; }
.menu-contenu {
  position: absolute; right: 0; top: calc(100% + .25rem); z-index: 40;
  min-width: 13rem; padding: .3rem;
  background: var(--fond-2); border: 1px solid var(--bord);
  border-radius: var(--rayon); box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
  display: grid; gap: .1rem;
}
.menu-contenu form { display: contents; }
.menu-ligne {
  display: flex; align-items: center; gap: .4rem;
  width: 100%; min-height: 36px; padding: .4rem .6rem;
  background: none; border: 0; border-radius: 6px;
  color: var(--texte); font: inherit; font-size: .9rem;
  text-align: left; text-decoration: none; cursor: pointer;
}
.menu-ligne:hover { background: var(--fond-3); }
.menu-danger { color: var(--alerte); }
.menu-bascule input { accent-color: var(--accent); width: 24px; height: 24px; }
@media (min-width: 52rem) {
  .renommer { flex: 1; min-width: 12rem; }
}
.renommer input {
  flex: 1; padding: .35rem .5rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: 8px; color: var(--texte);
  font: inherit; font-size: .88rem;
}

.actions-reponse { display: flex; gap: .4rem; margin-top: .5rem; }
.actions-reponse button {
  background: transparent; border: 1px solid var(--bord); border-radius: 8px;
  color: var(--texte-2); font: inherit; font-size: .8rem; padding: .2rem .5rem;
  cursor: pointer;
}
.actions-reponse button:hover { border-color: var(--accent); color: var(--accent); }
.actions-reponse .avis[aria-pressed="true"] {
  border-color: var(--accent); background: var(--accent-sombre); color: #a9e4cb;
}

/* ---------------------------------------------------- simulateur -------- */
/* Deux séries seulement, et leurs couleurs sont vérifiées : vert + orange,
   le réflexe, échouent le test de distinction en vision des couleurs
   déficiente (ΔE 6,0 en deutéranopie). Bleu + orange passent (ΔE 26,8), et
   chaque courbe porte en plus son étiquette : la couleur ne porte jamais
   l'identité à elle seule. */
.simu { --serie-ca: #3987e5; --serie-cout: #d95926; }

.simu-indics { display: grid; gap: .5rem; grid-template-columns: repeat(2, 1fr); }
.indic { background: var(--fond-3); border: 1px solid var(--bord);
         border-radius: var(--rayon); padding: .6rem .7rem; }
.indic-nom { margin: 0; font-size: .72rem; text-transform: uppercase;
             letter-spacing: .06em; color: var(--texte-2); }
.indic-valeur { margin: .15rem 0 0; font-size: 1.35rem; font-weight: 650;
                letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.indic-detail { margin: .1rem 0 0; font-size: .78rem; color: var(--texte-2); }

.feu { display: inline-flex; align-items: center; gap: .35rem; font-size: .78rem; }
.feu::before { content: ""; width: .55rem; height: .55rem; border-radius: 50%;
               background: currentColor; }
.feu-vert { color: #199e70; }
.feu-orange { color: #c98500; }
.feu-rouge { color: #e66767; }
.feu-gris { color: var(--texte-2); }

.simu-grille { display: grid; gap: .5rem; grid-template-columns: repeat(2, 1fr); }
.simu-champ { display: flex; flex-direction: column; gap: .2rem; }
.simu-champ label { font-size: .75rem; color: var(--texte-2); }
.simu-champ input[type="number"] {
  width: 100%; padding: .4rem .5rem; background: var(--fond);
  color: var(--texte); border: 1px solid var(--bord); border-radius: 8px;
  font: inherit; font-size: .9rem; font-variant-numeric: tabular-nums;
}
.simu-champ input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.simu-bascule { display: flex; align-items: center; gap: .45rem; font-size: .85rem;
                color: var(--texte-2); margin: .5rem 0 0; }

.simu-profil { border: 1px solid var(--bord); border-radius: var(--rayon);
               padding: .6rem; margin-bottom: .5rem; background: var(--fond-2); }
.simu-profil-nom { margin: 0 0 .45rem; font-weight: 650; }

.simu-graphe { width: 100%; height: auto; display: block; touch-action: pan-y; }
.simu-legende { display: flex; flex-wrap: wrap; gap: .9rem; margin: .4rem 0 0;
                font-size: .8rem; color: var(--texte-2); }
.simu-legende span { display: inline-flex; align-items: center; gap: .35rem; }
.simu-legende i { width: 1rem; height: 2px; border-radius: 1px; background: currentColor; }
.simu-infobulle { font-size: .78rem; color: var(--texte-2); min-height: 1.4em;
                  margin: .3rem 0 0; font-variant-numeric: tabular-nums; }

.simu-lignes { list-style: none; margin: 0; padding: 0; }
.simu-ligne { display: grid; gap: .1rem .6rem; padding: .5rem 0;
              border-top: 1px solid var(--bord); }
.simu-ligne:first-child { border-top: 0; }
.simu-ligne dt { font-weight: 650; }
.simu-ligne dd { margin: 0; font-size: .85rem; color: var(--texte-2);
                 font-variant-numeric: tabular-nums; }

@media (min-width: 52rem) {
  .simu-indics { grid-template-columns: repeat(3, 1fr); }
  .simu-grille { grid-template-columns: repeat(4, 1fr); }
  .simu-profil { display: grid; gap: .5rem; grid-template-columns: 7rem repeat(4, 1fr);
                 align-items: end; }
  .simu-profil-nom { margin: 0 0 .25rem; }
}

/* Choix d'une offre d'hébergement relevée (écran Simulateur). Le sélecteur
   est posé AVANT la grille de champs qu'il remplit : l'ordre de lecture
   annonce la conséquence. */
.simu-offre {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  margin-bottom: .9rem;
}
.simu-offre > span {
  font-size: .82rem;
  color: var(--texte-2);
}
.simu-offre select {
  width: 100%;
  min-height: 2.6rem;
  padding: .45rem .6rem;
  border: 1px solid var(--bord);
  border-radius: var(--rayon);
  background: var(--fond-3);
  color: var(--texte);
  font: inherit;
}
#offre-detail {
  margin-top: -.4rem;
  margin-bottom: .9rem;
}

/* ------------------------------------------------- mon profil ------------ */
/* Fiche d'identité : en lecture. Pas de champ de saisie, volontairement —
   Keycloak est maître des comptes, et un champ modifiable ici créerait un
   second jeu de vérité. La forme doit le dire avant le texte. */
.fiche { display: grid; grid-template-columns: auto 1fr; gap: .35rem .9rem;
         margin: 0 0 .8rem; font-size: .9rem; }
.fiche dt { color: var(--texte-2); }
.fiche dd { margin: 0; }
.fiche dd.mono { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
                 font-size: .85rem; overflow-wrap: anywhere; }

.bouton-secondaire {
  display: inline-block; padding: .6rem .9rem; border: 1px solid var(--bord);
  border-radius: var(--rayon); background: var(--fond-3); color: var(--texte);
  font: 600 .9rem/1.2 var(--police); text-decoration: none; cursor: pointer;
  min-height: 2.6rem; box-sizing: border-box;
}
.bouton-secondaire:hover { border-color: var(--accent); }
.bouton-secondaire:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Zone destructrice, repliée par défaut : ce qu'on ne peut pas défaire ne
   s'offre pas au premier regard, mais ne se cache pas non plus. */
.danger { margin-top: 1rem; border: 1px solid #4a3020; border-radius: var(--rayon);
          background: #1b1411; padding: .7rem .85rem; }
.danger > summary { cursor: pointer; color: var(--alerte); font-weight: 600;
                    font-size: .9rem; min-height: 42px; display: flex;
                    align-items: center; }
.danger[open] > summary { margin-bottom: .6rem; }
.bouton-danger {
  padding: .7rem 1rem; border: 1px solid #6b3a22; border-radius: var(--rayon);
  background: #3a2016; color: var(--alerte); font: 600 .95rem/1 var(--police);
  cursor: pointer; justify-self: start; min-height: 2.6rem;
}
.bouton-danger:hover { background: #4a2a1c; }
.bouton-danger:focus-visible { outline: 2px solid var(--alerte); outline-offset: 2px; }

/* Le champ de consigne personnelle : même traitement que les autres champs,
   que `.champ input` ne couvrait pas (textarea est un autre élément). */
.champ textarea {
  padding: .6rem .7rem; background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: var(--rayon); color: var(--texte); font: inherit; width: 100%;
  resize: vertical; box-sizing: border-box;
}
.champ textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Le nom de la personne devient un lien vers son profil. Il doit se voir
   comme cliquable sans crier : un soulignement au survol, pas une couleur
   d'accent qui le ferait passer pour une action. */
.nom-lien { text-decoration: none; color: inherit; }
.nom-lien:hover { text-decoration: underline; }
.nom-lien:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px;
                          border-radius: 4px; }
.nom-lien[aria-current="page"] { text-decoration: underline; color: var(--accent); }

/* Compteurs d'activité : deux colonnes, le nombre d'abord. En ligne simple,
   « 0 conversation(s) 0 question(s) posée(s) » se lit comme une phrase
   cassée — mesuré à 390 px. */
.compteurs-profil { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem;
                    margin: .2rem 0 .8rem; }
.compteurs-profil p { margin: 0; display: flex; flex-direction: column; }
.compteurs-profil b { font-size: 1.5rem; line-height: 1.1; }
.compteurs-profil span { font-size: .8rem; color: var(--texte-2); }

/* ------------------------------------------------- démarrage ------------- */
/* Le piège d'un poste : encadré parce qu'il doit interrompre la lecture.
   C'est la ligne qu'on regrette de ne pas avoir lue, pas la description. */
.piege {
  margin: .5rem 0 0; padding: .55rem .7rem;
  border-left: 3px solid var(--alerte); border-radius: 0 var(--rayon) var(--rayon) 0;
  background: #1b1411; color: var(--texte-2); font-size: .82rem;
}
.piege strong { color: var(--alerte); }

/* Une commande se copie : police à chasse fixe, et elle peut déborder d'un
   téléphone sans pousser la page — on la fait défiler elle, pas l'écran. */
.commande {
  margin: .5rem 0 .35rem; padding: .5rem .6rem;
  background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: var(--rayon); overflow-x: auto;
  /* `min-width: 0` : sans lui, `overflow-x: auto` ne contient rien. Un
     élément de grille a une largeur minimale égale à son contenu, donc la
     commande la plus longue élargissait la carte, la section, et toute la
     page — 533 px de contenu sur un écran de 390. Mesuré, pas supposé. */
  min-width: 0;
}
.documents > .document { min-width: 0; }
/* Le `white-space` n'est PLUS posé ici : cette règle (`.commande code`) est
   plus spécifique que `.ligne-commande`, et elle gagnait contre le repli
   mobile sans qu'on voie pourquoi — la page repartait sur la droite. Le
   retour à la ligne est décidé par la ligne elle-même, plus bas. */
.commande code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: .8rem; color: var(--texte);
}

.total-ligne { margin: .8rem 0 0; font-size: .95rem; }
.valeur-tendue { color: var(--alerte); }

/* Le verdict d'une ligne de comparaison. Pas de vert/rouge : aucune des deux
   options n'est un défaut, et un rouge ferait lire « mauvais » là où il faut
   lire « l'autre est meilleur sur CE point ». */
.verdict-api     { border-color: var(--accent); color: var(--accent); }
.verdict-gpu     { border-color: #7aa7d4; color: #7aa7d4; }
.verdict-egalite { border-color: var(--bord); color: var(--texte-2); }

/* Un `select` a pour largeur MINIMALE celle de son option la plus longue, et
   cette largeur l'emporte sur `width: 100%`. Mesuré sur /cles : 363 px dans
   un écran de 360, et toute la page part sur la droite. La règle vise tout
   l'espace d'administration plutôt que la seule classe `.champ`, parce que
   les formulaires n'emploient pas tous la même enveloppe — et que le défaut
   ne se voit qu'à 360 px, largeur qu'on ne teste jamais spontanément. */
.admin select, .admin input, .admin textarea {
  max-width: 100%; min-width: 0; box-sizing: border-box;
}

/* La conclusion d'une comparaison : un paragraphe dans le flux, et surtout
   PAS `.annonce` — celle-ci est une bulle `position: fixed`, faite pour un
   message passager. Employée pour un texte permanent, elle se posait par
   dessus le contenu et masquait deux postes de la liste. Vu à la capture,
   invisible à la relecture du gabarit. */
.conclusion {
  margin: 1rem 0 0; padding: .8rem .9rem;
  background: var(--accent-sombre); border: 1px solid var(--accent);
  border-radius: var(--rayon); font-size: .9rem; line-height: 1.5;
}

/* « Mon profil » au pied du tiroir. Traité comme une destination et non
   comme un lien discret : c'est la seule entrée qui porte le mot cherché
   par qui veut changer son mot de passe ou sa préférence de réponse. */
.lien-compte {
  display: block; padding: .6rem .7rem; margin-top: .4rem;
  min-height: 42px; box-sizing: border-box;
  border-top: 1px solid var(--bord);
  color: var(--texte); text-decoration: none; font-size: .95rem;
}
.lien-compte:hover { color: var(--accent); }
.lien-compte-actif { color: var(--accent); }

/* Un poste de la liste de démarrage. Le nom de l'offre est du TEXTE, pas une
   valeur technique : `.detail-tech strong` l'affichait en chasse fixe, ce
   qui le faisait lire comme une commande et cassait la colonne sur
   téléphone. Vu à la capture, invisible dans le gabarit. */
.poste-choix { margin: .35rem 0 .25rem; font-size: .9rem; color: var(--texte); }
.poste-ou { color: var(--texte-2); }
/* Le prix ne doit pas être en chasse fixe non plus : à côté d'un titre gras
   il déséquilibre la ligne, et il passe à la ligne au mauvais endroit. */
.prix { margin-left: auto; color: var(--accent); font-size: .88rem;
        font-weight: 600; white-space: nowrap; }

/* Deux scénarios dans le même écran : ils doivent se distinguer d'un coup
   d'œil, sinon on lit une seule liste de douze postes et on additionne des
   prix qui ne s'additionnent pas. */
.scenario { margin-top: 1.1rem; padding-top: .9rem; border-top: 1px solid var(--bord); }
.scenario:first-of-type { border-top: 0; padding-top: .2rem; }
.scenario-tete { display: flex; flex-wrap: wrap; align-items: baseline;
                 gap: .5rem; margin-bottom: .5rem; }
.scenario-nom { font-size: 1rem; font-weight: 600; color: var(--texte); }

/* Le total d'un scénario est une PHRASE (« 35 à 85 €/mois hors jetons et
   hors temps humain »), pas un montant court : il doit pouvoir se couper.
   Avec le `white-space: nowrap` de `.prix`, il imposait 389 px de largeur
   minimale sur un écran de 390. */
.total-scenario { color: var(--accent); font-size: .88rem; font-weight: 600; }

/* Mode opératoire : des étapes numérotées, parce que l'ordre est la moitié
   de l'information. Un rang visible permet aussi de dire « j'en suis à 7 ». */
.etapes { list-style: none; margin: .6rem 0 0; padding: 0; display: grid; gap: .7rem; }
.etape { padding: .75rem .8rem; background: var(--fond-3);
         border: 1px solid var(--bord); border-radius: var(--rayon);
         min-width: 0; }
.etape-rang {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; flex: none;
  border-radius: 999px; background: var(--accent-sombre);
  border: 1px solid var(--accent); color: var(--accent);
  font-size: .78rem; font-weight: 700;
}
.etape-liste { margin: .45rem 0 .2rem; padding-left: 1.1rem; color: var(--texte-2);
               font-size: .84rem; display: grid; gap: .25rem; }
/* `pre` et non `p` : un bloc de commandes garde ses retours à la ligne, et
   `min-width: 0` l'empêche d'élargir la carte jusqu'à pousser la page. */
pre.commande { margin: .5rem 0 .35rem; white-space: pre; }
.regle-sauvegarde {
  margin: .4rem 0 .6rem; padding: .7rem .8rem;
  background: var(--accent-sombre); border: 1px solid var(--accent);
  border-radius: var(--rayon); font-weight: 600; font-size: .92rem;
}

/* Commandes : repli plutôt que défilement latéral. Mesuré — quinze blocs à
   faire défiler un par un sur un téléphone, personne ne les lit. `pre-wrap`
   n'INSÈRE aucun caractère : le texte copié reste exactement la commande,
   seul l'affichage est replié. Un retrait marque la continuation pour qu'on
   voie qu'il s'agit d'une seule ligne. */
.ligne-commande {
  display: block; white-space: pre; overflow-wrap: normal;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: .8rem; line-height: 1.6; color: var(--texte);
}
@media (max-width: 64rem) {
  /* Repli par commande, avec un retrait pendu qui montre la continuation. */
  .ligne-commande { white-space: pre-wrap; overflow-wrap: anywhere;
                    padding-left: 1.3rem; text-indent: -1.3rem; }
}

/* Un réglage : le champ et son bouton sur la même ligne, pour qu'on voie
   que l'un applique l'autre. Le champ se replie sous le bouton si la place
   manque, plutôt que de pousser la page. */
.ligne-reglage { display: flex; flex-wrap: wrap; align-items: center;
                 gap: .5rem; margin: .6rem 0 .2rem; min-width: 0; }
.ligne-reglage .champ,
.ligne-reglage .champ-controle { flex: 1 1 10rem; min-width: 0; }
/* La liste déroulante prend la largeur de son conteneur et PAS celle de
   sa plus longue option : « Maintenance — tout le monde dehors » faisait
   343 px dans un écran de 360. */
.ligne-reglage select { width: 100%; max-width: 100%; min-height: 44px;
                        padding: .4rem .5rem; background: var(--fond-3);
                        border: 1px solid var(--bord);
                        border-radius: var(--rayon); color: var(--texte);
                        font: inherit; font-size: .9rem; }
.ligne-reglage button { flex: none; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* Confirmation d'un formulaire : DANS le flux, en haut de la page, là où
   l'œil revient après l'envoi. Pas `.annonce` : celle-ci est une bulle
   `position: fixed` faite pour un événement asynchrone (« votre réponse est
   prête »), et elle porte un bouton de fermeture créé par le script. Posée
   par le serveur, elle n'en a pas et resterait indéfiniment à couvrir le
   bas de l'écran. */
.confirmation {
  margin: 0 0 1rem; padding: .7rem .85rem; border-radius: var(--rayon);
  background: var(--accent-sombre); border: 1px solid var(--accent);
  color: var(--texte); font-size: .9rem;
}

/* Secret révélé : affiché une fois, en évidence, et jamais pré-rempli dans
   un champ — un masque recopié dans le formulaire deviendrait la nouvelle
   valeur au premier « Appliquer » distrait. */
.secret-revele {
  margin: 0 0 1rem; padding: .8rem .9rem; border-radius: var(--rayon);
  background: #2a1d16; border: 1px solid #4a3020;
}
.valeur-revelee {
  margin: .3rem 0 .5rem; padding: .5rem .6rem;
  background: var(--fond); border: 1px solid var(--bord);
  border-radius: var(--rayon); overflow-x: auto;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: .85rem; color: var(--texte); word-break: break-all;
}

/* ------------------------------------------------------------------ */
/* Rendu Markdown des réponses                                        */
/* ------------------------------------------------------------------ */
/* `white-space: pre-wrap` est retiré des corps rendus : il vient de
   l'époque du texte brut, où il seul conservait les retours à la ligne.
   Maintenant que le rendu produit de vrais blocs, il ajouterait une ligne
   vide sous chaque titre et chaque liste. */
.corps-reponse { white-space: normal; min-width: 0; max-width: 100%; }
/* Un tableau ou un bloc de code plus large que l'écran défile DANS son
   cadre : sans cela, c'est toute la colonne de lecture qui s'élargit
   (min-width:auto des enfants de grille — le même piège qui avait poussé
   deux boutons hors écran, côté lecture cette fois), et les paragraphes
   se font rogner à droite, sans erreur. Vu sur téléphone à la recette :
   « trente-cinq he » coupé net. */
.bulle { min-width: 0; max-width: 100%; }
.corps-reponse pre { overflow-x: auto; max-width: 100%; }
.corps-reponse .table-reponse { display: block; max-width: 100%;
                                overflow-x: auto; width: fit-content; }
.corps-reponse > :first-child { margin-top: 0; }
.corps-reponse > :last-child { margin-bottom: 0; }
.corps-reponse p { margin: 0 0 .6rem; white-space: pre-wrap; }

.titre-reponse { margin: 1rem 0 .4rem; font-size: 1rem; line-height: 1.3;
  color: var(--texte); font-weight: 600; }
.corps-reponse h5.titre-reponse, .corps-reponse h6.titre-reponse { font-size: .92rem; }

.liste-reponse { margin: .2rem 0 .7rem; padding-left: 1.3rem; }
.liste-reponse li { margin: .2rem 0; }

.corps-reponse blockquote { margin: .5rem 0; padding: .1rem 0 .1rem .8rem;
  border-left: 3px solid var(--bord); color: var(--texte-2); }
.corps-reponse hr { border: 0; border-top: 1px solid var(--bord); margin: .9rem 0; }

.code-ligne { background: var(--fond); border: 1px solid var(--bord);
  border-radius: 5px; padding: .05rem .3rem; font-size: .86em;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; }

.bloc-code { position: relative; margin: .6rem 0; background: var(--fond);
  border: 1px solid var(--bord); border-radius: var(--rayon); }
.bloc-code pre { margin: 0; padding: .7rem .8rem; overflow-x: auto;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: .84rem; line-height: 1.5; }
.langage-code { position: absolute; top: .35rem; right: .5rem; font-size: .68rem;
  letter-spacing: .06em; text-transform: uppercase; color: var(--texte-2); }

/* Coloration. Quatre teintes, pas douze : au-delà, le code est plus difficile
   à lire, pas plus. Contrastes vérifiés sur le fond #0f1115 (AA, texte normal). */
.jeton-mot { color: #7cb7ff; }
.jeton-chaine { color: #8ddfa8; }
.jeton-commentaire { color: #8b94a3; font-style: italic; }
.jeton-nombre { color: #e0b267; }

/* Le repère d'extrait n'est pas une décoration : il dit d'où vient la phrase
   qui précède, et c'est la promesse centrale du produit. */
.repere-extrait { color: var(--accent); font-size: .82em; white-space: nowrap; }

.table-reponse { border-collapse: collapse; margin: .6rem 0; font-size: .88rem;
  display: block; overflow-x: auto; max-width: 100%; }
.table-reponse th, .table-reponse td { border: 1px solid var(--bord);
  padding: .3rem .55rem; text-align: left; vertical-align: top; }
.table-reponse th { background: var(--fond-3); font-weight: 600; }

/* Édition d'une question posée --------------------------------------- */
/* Toujours visibles. La révélation au survol a été ESSAYÉE puis retirée :
   une action qui n'apparaît qu'au survol n'existe pas sur un écran tactile,
   et la moitié de l'usage visé est sur téléphone (CDC, règle 4). */
.actions-question { margin-top: .35rem; display: flex; gap: .4rem; }

.actions-question .modifier { background: none; border: 0; padding: 0;
  color: var(--texte-2); font-size: .74rem; cursor: pointer; }
.actions-question .modifier:hover { color: var(--accent); }

.edition-question textarea { width: 100%; min-height: 3.2rem; resize: vertical;
  background: var(--fond); color: var(--texte); border: 1px solid var(--bord);
  border-radius: 8px; padding: .5rem .6rem; font: inherit; font-size: .92rem; }
.edition-question .actions-question { opacity: 1; margin-top: .4rem; }
.fil-action.discret { color: var(--texte-2); }

/* Rangement des conversations ---------------------------------------- */
/* Les filtres sont des liens : partageables, rechargeables, et ils marchent
   sans JavaScript. Un filtre qui n'existe que dans l'état du script
   disparaît au premier rechargement, et on croit avoir perdu ses fils. */
.rangement { margin: .3rem 0 .5rem; display: flex; flex-direction: column; gap: .3rem; }
.filtres-dossiers, .filtres-etiquettes { display: flex; flex-wrap: wrap; gap: .25rem; }
.puce { font-size: .72rem; padding: .12rem .45rem; border-radius: 999px;
  border: 1px solid var(--bord); color: var(--texte-2); text-decoration: none; }
.puce:hover { color: var(--texte); border-color: var(--texte-2); }
.puce.active { color: var(--accent); border-color: var(--accent);
  background: var(--accent-sombre); }
.puce .compte { opacity: .6; margin-left: .2rem; }
.etiquette-puce { font-family: ui-monospace, Menlo, monospace; }

.nouveau-dossier { display: flex; gap: .3rem; margin-bottom: .5rem; }
.nouveau-dossier input { flex: 1; min-width: 0; background: var(--fond);
  border: 1px solid var(--bord); border-radius: 7px; color: var(--texte);
  padding: .3rem .45rem; font-size: .78rem; }

.epingle-marque { font-size: .7rem; margin-right: .15rem; }
.etiquettes-fil { display: block; font-size: .68rem; color: var(--texte-2);
  font-family: ui-monospace, Menlo, monospace; }
.actions-fil { display: flex; gap: .15rem; align-items: center; }
.fil-entree .epingler[aria-pressed="true"] { filter: none; opacity: 1; }
.fil-entree .epingler[aria-pressed="false"] { opacity: .35; }
.fil-entree .epingler:hover { opacity: 1; }

/* `flex: 1 0 100%` : le menu prend sa propre ligne sous le fil. Posé en
   ligne, il se retrouvait écrasé entre le titre et les boutons — lisible
   dans le test, illisible à l'œil. */
.menu-classement { flex: 1 0 100%; display: flex; flex-direction: column; gap: .3rem;
  padding: .4rem; margin-top: .3rem; background: var(--fond);
  border: 1px solid var(--bord); border-radius: 8px; }
.menu-classement select, .menu-classement input { background: var(--fond-2);
  color: var(--texte); border: 1px solid var(--bord); border-radius: 6px;
  padding: .25rem .35rem; font-size: .78rem; }

/* Provenance d'un fil dérivé ------------------------------------------ */
.origine-fil { font-size: .74rem; color: var(--texte-2); }
.origine-fil a { color: var(--accent); text-decoration: none; }
.origine-fil a:hover { text-decoration: underline; }

/* Partage par lien ---------------------------------------------------- */
.panneau-partage { margin: 0 0 1rem; padding: .8rem; background: var(--fond-2);
  border: 1px solid var(--bord); border-radius: var(--rayon); }
.ligne-partage { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin: .5rem 0; }
.ligne-partage select { background: var(--fond); color: var(--texte);
  border: 1px solid var(--bord); border-radius: 6px; padding: .25rem .4rem; }
#lien-partage { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
#adresse-partage { flex: 1; min-width: 14rem; background: var(--fond);
  color: var(--accent); border: 1px solid var(--bord); border-radius: 6px;
  padding: .35rem .5rem; font-family: ui-monospace, Menlo, monospace;
  font-size: .78rem; }
.liste-partages { list-style: none; margin: .6rem 0 0; padding: 0;
  display: grid; gap: .25rem; }
.ligne-lien { display: flex; align-items: center; gap: .5rem; font-size: .78rem;
  color: var(--texte-2); }
.etat-lien { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em;
  padding: .05rem .35rem; border-radius: 999px; border: 1px solid var(--bord); }
.etat-lien.actif { color: var(--accent); border-color: var(--accent); }

/* Page publique d'un partage ------------------------------------------ */
.page-partage { padding: 1.5rem 1rem 3rem; }
.page-partage .echange { max-width: 48rem; margin: 0 auto; }
.entete-partage h1 { margin: .2rem 0 .4rem; font-size: 1.3rem; }
.entete-partage { margin-bottom: 1.2rem; padding-bottom: .8rem;
  border-bottom: 1px solid var(--bord); }
.page-partage .fil { display: flex; flex-direction: column; gap: .8rem; }
.carte-centrale { max-width: 27rem; margin: 15vh auto 0; text-align: center;
  background: var(--fond-2); border: 1px solid var(--bord);
  border-radius: 14px; padding: 2rem 1.6rem; }

/* Conversation temporaire --------------------------------------------- */
.bascule-temporaire { display: flex; align-items: center; gap: .35rem;
  font-size: .76rem; color: var(--texte-2); cursor: pointer; }
.bascule-temporaire input { accent-color: var(--accent); }
.avis-temporaire { margin: 0 1.5rem 1rem; padding: .6rem .8rem;
  background: var(--fond-2); border: 1px solid var(--bord);
  border-left: 3px solid var(--accent); border-radius: 8px;
  font-size: .8rem; color: var(--texte-2); }

/* Pièces jointes à une conversation ----------------------------------- */
.joindre { display: inline-flex; align-items: center; cursor: pointer;
  font-size: 1.1rem; padding: .2rem .3rem; border-radius: 6px;
  color: var(--texte-2); }
.joindre:hover { color: var(--accent); background: var(--fond-3); }
.liste-pieces { list-style: none; margin: 0 1.5rem .6rem; padding: 0;
  display: grid; gap: .25rem; }
.ligne-piece { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  font-size: .78rem; color: var(--texte-2); padding: .3rem .5rem;
  background: var(--fond-2); border: 1px solid var(--bord); border-radius: 8px; }
.ligne-piece .nom-piece { color: var(--texte); font-weight: 500; }
.ligne-piece.prete .etat-piece { color: var(--accent); }
.ligne-piece.en_erreur { border-color: #4a3020; }
.ligne-piece.en_erreur .etat-piece { color: var(--alerte); }

/* Bannière système ---------------------------------------------------- */
/* Rendue par le serveur, en haut du document : une bannière qui n'apparaît
   qu'une fois le JavaScript chargé est une bannière qu'on rate — et elle
   sert précisément aux moments où quelque chose ne va pas. */
.banniere { padding: .55rem 1rem; font-size: .85rem; text-align: center;
  border-bottom: 1px solid var(--bord); }
.banniere-information { background: var(--fond-3); color: var(--texte); }
.banniere-avertissement { background: #2a2416; color: #e8c97a;
  border-bottom-color: #4a3f20; }
.banniere-incident { background: #2a1d16; color: var(--alerte);
  border-bottom-color: #4a3020; }

/* Marque blanche : l'accent est redéfini par l'organisation, et sa couleur
   de TEXTE l'accompagne. Les boutons pleins l'utilisent ; sans elle, un
   accent clair donne du texte blanc sur fond clair. */
.bouton-principal { color: var(--accent-texte); }
/* `.bouton-nouveau` a un fond SOMBRE et un texte d'accent : lui imposer la
   couleur « sur accent » l'a rendu illisible — contraste 1,00:1, texte de
   la couleur exacte du fond. Trouvé par le contrôle d'accessibilité, pas à
   la relecture. Seul son état survolé, où le fond devient l'accent, prend
   la couleur calculée. */
.bouton-nouveau:hover { color: var(--accent-texte); }

/* Dictée et lecture --------------------------------------------------- */
.dicter { background: none; border: 0; font-size: 1.1rem; cursor: pointer;
  color: var(--texte-2); padding: .2rem .3rem; border-radius: 6px; }
.dicter:hover { color: var(--accent); background: var(--fond-3); }
.dicter.ecoute { color: var(--alerte); animation: battement 1.2s infinite; }
@keyframes battement { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .dicter.ecoute { animation: none; } }
.actions-reponse .lire { font-size: .74rem; }

/* `.ligne-reglage` était défini DEUX FOIS, et la seconde — `inline-flex`
   sans `flex-wrap` — écrasait la première en silence. Les deux sont
   fondues plus haut ; ce qui reste ici est ce que la seconde apportait
   vraiment : l'alignement vertical au centre, pour les lignes qui ne
   portent qu'un interrupteur. */
.avertissement-reglage { border-left: 3px solid var(--alerte);
  padding-left: .6rem; color: var(--texte-2); }


/* ------------------------------------------------------------------ */
/* Accessibilité : cibles d'au moins 24 px (WCAG 2.5.8)               */
/* ------------------------------------------------------------------ */
/* Mesuré au contrôleur, pas estimé : les petites commandes du portail
   faisaient 19 à 22 px de haut. Sur un écran tactile, un bouton qu'on
   rate deux fois sur trois n'est pas une fonction, c'est une épreuve —
   et la règle vaut aussi à la souris pour qui tremble.

   `inline-flex` et non `display: block` : ces éléments vivent dans des
   lignes de texte, et un bloc casserait la mise en page partout. */
.fil-action, .lien-discret, .nom-lien, .actions-question .modifier,
.actions-reponse button {
  min-height: 24px;
  /* La LARGEUR compte autant : le bouton « × » de suppression faisait
     20 px de large pour 24 de haut, et c'est lui qu'on vise le plus mal. */
  min-width: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Les cases à cocher ne se redimensionnent pas de façon fiable : on
   agrandit leur ZONE en passant par l'étiquette qui les contient. */
.bascule-temporaire { min-height: 24px; }
.bascule-temporaire input { width: 18px; height: 18px; }
/* La case fait 18 px, mais la CIBLE est l'étiquette entière — on
   coche en cliquant le mot. C'est ce que mesure WCAG 2.5.8. */
.bascule-temporaire { padding: .15rem .25rem; }

/* Lien d'évitement ---------------------------------------------------- */
/* Hors écran tant qu'il n'a pas le focus : visible pour qui navigue au
   clavier, invisible pour les autres. `clip-path` et non `display:none` —
   un élément retiré de l'affichage ne peut pas recevoir le focus, et le
   lien ne servirait à personne. */
.evitement {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  padding: .6rem 1rem; background: var(--accent); color: var(--accent-texte);
  border-radius: 0 0 var(--rayon) 0; font-weight: 600; text-decoration: none;
}
.evitement:focus { left: 0; }
/* Le conteneur reçoit le focus après le saut, sans contour permanent. */
#contenu:focus { outline: none; }

/* Arène : deux réponses côte à côte ----------------------------------- */
/* Empilées sous 64 rem : deux colonnes de texte sur un téléphone donnent
   deux colonnes illisibles, et c'est le texte qu'on vient comparer. */
.duel { display: grid; gap: .8rem; }
@media (min-width: 64rem) { .duel { grid-template-columns: 1fr 1fr; } }
.duel-cote { min-width: 0; }
.choix-verdict { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }

/* ------------------------------------------------- abonnement ------------ */
/* L'écran dit QUATRE choses dans l'ordre où on les cherche : où j'en suis,
   ce que je peux prendre, comment dépanner, ce que j'ai payé. */
.page-abonnement { max-width: 64rem; margin: 0 auto; padding: 1rem .9rem 2rem;
                   display: grid; gap: 1.5rem; }
.carte-etat { padding: 1rem; background: var(--fond-2);
              border: 1px solid var(--bord); border-radius: var(--rayon); }
.carte-etat h2 { margin: 0 0 .4rem; }
.offre-courante { margin: 0 0 .4rem; }
.compteurs { display: flex; flex-wrap: wrap; gap: 1.2rem; margin: .8rem 0; }
.compteurs dt { color: var(--texte-2); font-size: .78rem; }
.compteurs dd { margin: 0; font-size: 1.3rem; font-weight: 600; }
.en-ligne { display: inline-block; margin-right: .6rem; }

.grille-offres { display: grid; gap: .8rem;
                 grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.offre { padding: 1rem; background: var(--fond-2); border: 1px solid var(--bord);
         border-radius: var(--rayon); display: flex; flex-direction: column;
         gap: .5rem; }
/* L'offre courante se distingue par un LISERÉ, pas par la couleur seule :
   lisible aussi sans distinguer les teintes. */
.offre.courante { border-color: var(--accent); }
.offre h3 { margin: 0; }
.prix { margin: 0; font-size: 1.5rem; font-weight: 700; }
.prix .par { font-size: .78rem; font-weight: 400; color: var(--texte-2); }
.traits { margin: 0; padding-left: 1.1rem; font-size: .88rem;
          display: grid; gap: .25rem; }
.etiquette-courante { margin: auto 0 0; color: var(--accent); font-weight: 600; }
.offre form { margin-top: auto; display: grid; gap: .4rem; }

.grille-packs { display: flex; flex-wrap: wrap; gap: .8rem; }
.pack { display: flex; align-items: center; gap: .8rem; padding: .7rem .9rem;
        background: var(--fond-2); border: 1px solid var(--bord);
        border-radius: var(--rayon); }
.pack-questions { font-weight: 600; }
.pack-prix { color: var(--texte-2); }

.journal-abonnement { list-style: none; margin: 0; padding: 0;
                      display: grid; gap: .3rem; font-size: .9rem; }
.journal-abonnement .date { color: var(--texte-2); margin-right: .5rem;
                            font-variant-numeric: tabular-nums; }
.lignes-factures { list-style: none; margin: 0; padding: 0;
                   display: grid; gap: .3rem; }
.lignes-factures li { display: flex; flex-wrap: wrap; gap: .8rem;
                      align-items: center; padding: .5rem .7rem;
                      background: var(--fond-2); border: 1px solid var(--bord);
                      border-radius: 8px; font-size: .9rem; }
.lignes-factures .numero { font-weight: 600; }
.lignes-factures .montant { margin-left: auto;
                            font-variant-numeric: tabular-nums; }
.etat-facture.payee { color: var(--accent); }
.note-interrompue { margin: .4rem 0 0; color: var(--texte-2);
                    font-size: .82rem; font-style: italic; }

/* ------------------------------------------------- mode de service ------- */
.carte-maintenance .marque { font-size: 2rem; }
.bloc-infolettre { margin-top: 1.2rem; padding-top: 1rem;
                   border-top: 1px solid var(--bord); }
.infolettre-titre { margin: 0 0 .5rem; font-weight: 600; }
.formulaire-infolettre { display: flex; gap: .4rem; flex-wrap: wrap; }
.formulaire-infolettre input[type="email"] {
  flex: 1; min-width: 12rem; padding: .6rem .7rem;
  background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: var(--rayon); color: var(--texte); font: inherit;
}
.formulaire-infolettre .bouton-principal { width: auto; padding: .6rem 1rem; }

/* ------------------------------------------------- contrôles de saisie --- */
/* Interrupteur : une VRAIE case à cocher, stylée. Jamais un div avec
   role=switch — le clavier, le lecteur d'écran et la saisie vocale
   fonctionnent alors sans une ligne de script. */
/* `position: relative` sur le label : sans lui, la case réelle (en
   position absolue pour rester invisible mais cliquable) se place par
   rapport au BLOC CONTENEUR INITIAL — c'est-à-dire au coin haut-gauche de
   la page. Elle y recouvrait le titre de l'écran : cliquer le titre
   basculait un réglage. */
.interrupteur { position: relative; display: inline-flex; align-items: center;
                gap: .6rem; cursor: pointer; min-height: 44px; }
.interrupteur input { position: absolute; top: 0; left: 0; opacity: 0;
                      width: 44px; height: 24px; margin: 0; cursor: pointer; }
/* Noms PROPRES à l'interrupteur, et règles scopées sous `.interrupteur`.
   Le premier jet s'appelait `.piste` / `.pastille` : or `.pastille`
   désigne depuis toujours les badges de rôle et de statut sur huit
   écrans, que ces règles ont envoyés dans le coin de la page. Un nom
   générique dans une feuille partagée finit toujours par en écraser un
   autre, sans aucune erreur. */
.interrupteur .interrupteur-piste {
  position: relative; flex: 0 0 auto; width: 44px; height: 24px;
  background: var(--fond-3); border: 1px solid var(--bord);
  border-radius: 999px; transition: background .15s, border-color .15s;
}
.interrupteur .interrupteur-curseur {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  background: var(--texte-2); border-radius: 50%;
  transition: transform .15s, background .15s;
}
.interrupteur input:checked + .interrupteur-piste {
  background: var(--accent-sombre); border-color: var(--accent);
}
.interrupteur input:checked + .interrupteur-piste .interrupteur-curseur {
  transform: translateX(20px); background: var(--accent);
}
/* Le focus se voit SUR LA PISTE : la case réelle est transparente, et sans
   cette règle la navigation au clavier n'affiche aucun repère. */
.interrupteur input:focus-visible + .interrupteur-piste {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.interrupteur input:disabled + .interrupteur-piste { opacity: .45;
                                                     cursor: not-allowed; }
.interrupteur .interrupteur-texte { display: flex; flex-direction: column; }
.interrupteur .interrupteur-texte .aide { font-size: .8rem; }

/* Champ avec étiquette au-dessus : la lire après avoir rempli ne sert à rien. */
.champ-controle { display: flex; flex-direction: column; gap: .25rem;
                  min-width: 0; }
.etiquette-controle { font-size: .85rem; color: var(--texte-2); }
.champ-controle select, .champ-controle input {
  min-height: 44px; padding: .5rem .6rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: var(--rayon);
  color: var(--texte); font: inherit; max-width: 100%;
}

.groupe-controle { margin: 0 0 .8rem; padding: .7rem .9rem; border: 1px solid var(--bord);
                   border-radius: var(--rayon); background: var(--fond-2); }
.groupe-controle legend { padding: 0 .4rem; font-weight: 600; font-size: .9rem; }
.options-controle { display: grid; gap: .3rem; }
/* Plusieurs cases : en colonnes dès qu'il y a la place, pour voir la liste
   entière sans défiler — c'est tout l'intérêt des cases sur une liste. */
.options-cases { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.option-controle { display: flex; align-items: flex-start; gap: .55rem;
                   min-height: 44px; padding: .25rem .3rem; border-radius: 8px;
                   cursor: pointer; }
.option-controle:hover { background: var(--fond-3); }
.option-controle input { width: 20px; height: 20px; margin-top: .55rem;
                         accent-color: var(--accent); flex: 0 0 auto; }
.option-controle > span { display: flex; flex-direction: column;
                          padding-top: .4rem; }
.option-controle .aide { font-size: .8rem; }

/* Le bouton de repli : visible tant que le script n'a pas pris la main,
   masqué ensuite. Un portail qui EXIGE le script pour changer un réglage
   est un portail qu'on ne peut pas réparer quand le script casse. */
.js-actif .sans-js { display: none; }
/* Documentation d'un réglage : repliée. Elle est précieuse quand on
   découvre l'écran, encombrante quand on vient tourner un bouton. */
.detail-reglage { margin: .4rem 0 0; }
.detail-reglage summary { cursor: pointer; color: var(--texte-2);
                          font-size: .85rem; min-height: 44px;
                          display: inline-flex; align-items: center; }
.detail-reglage summary:hover { color: var(--accent); }

/* ------------------------------------------------- images déposées ------ */
.bloc-photo, .bloc-logo { margin: 1rem 0; padding-top: .8rem;
                          border-top: 1px solid var(--bord); }
.apercu-photo, .apercu-logo { display: flex; align-items: center; gap: .9rem;
                              margin-bottom: .6rem; flex-wrap: wrap; }
/* `object-fit: cover` : une photo rectangulaire rentrée de force dans un
   carré est écrasée, pas recadrée — et personne ne se reconnaît. */
.apercu-photo img, .apercu-logo img {
  width: 96px; height: 96px; object-fit: cover;
  background: var(--fond-3); border: 1px solid var(--bord);
}
.apercu-photo img { border-radius: 50%; }
.apercu-logo img { border-radius: 12px; object-fit: contain; padding: .3rem; }
/* Le champ de fichier natif : cible de 44 px et couleurs du thème — sans
   quoi il garde le gris du navigateur, illisible sur fond sombre.

   `width: 100%` et PAS seulement `max-width` : un champ de fichier a une
   largeur intrinsèque (bouton + « Aucun fichier sélectionné ») de plus de
   330 px, et `max-width` plafonne la largeur UTILISÉE sans réduire la
   contribution minimale de l'élément à son conteneur. Le bloc refusait
   donc de rétrécir et poussait la page de 18 px à 360. */
.champ-controle input[type="file"] {
  min-height: 44px; padding: .5rem .6rem; background: var(--fond-3);
  border: 1px solid var(--bord); border-radius: var(--rayon);
  color: var(--texte); font: inherit; font-size: .9rem;
  width: 100%; min-width: 0; max-width: 100%;
}
.champ-controle input[type="file"]::file-selector-button {
  margin-right: .6rem; padding: .35rem .7rem; border: 1px solid var(--bord);
  border-radius: 8px; background: var(--fond-2); color: var(--texte);
  font: inherit; font-size: .85rem; cursor: pointer;
}
.champ-controle input[type="file"]::file-selector-button:hover {
  border-color: var(--accent); color: var(--accent);
}

/* ------------------------------------------------- options vendues ------ */
.grille-options { display: grid; gap: .8rem;
                  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.option-vendue { display: flex; flex-direction: column; gap: .4rem;
                 padding: .9rem; background: var(--fond-2);
                 border: 1px solid var(--bord); border-radius: var(--rayon); }
/* Une option active se distingue par un LISERÉ, pas par la couleur seule :
   lisible aussi sans distinguer les teintes. */
.option-vendue.active { border-color: var(--accent); }
.option-vendue h3 { margin: 0; font-size: 1rem; }
.prix-option { margin: 0; font-size: 1.15rem; font-weight: 600; }
.prix-option .par { font-size: .75rem; font-weight: 400; color: var(--texte-2); }
.option-vendue form { margin-top: auto; }

/* ------------------------------------------------- verdicts de contrôle -- */
.verdicts { list-style: none; margin: 0 0 .6rem; padding: 0;
            display: grid; gap: .3rem; }
.verdict { padding: .45rem .7rem; border-radius: 8px; font-size: .88rem;
           border-left: 3px solid var(--bord); background: var(--fond-2); }
/* Trois états et non deux : « indisponible » n'est ni un succès ni un
   échec, et il se distingue À L'ŒIL — sinon on le lit comme l'un des
   deux. Liseré ET mot : jamais la couleur seule. */
.verdict-valide { border-left-color: var(--accent); }
.verdict-invalide { border-left-color: var(--alerte); }
.verdict-indisponible, .verdict-approximative { border-left-color: #b08b4f; }
.verdict-absent { opacity: .7; }

/* ------------------------------------------------- alertes du bord ------ */
.alertes { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: .4rem; }
.alerte-ligne { padding: .6rem .8rem; border-radius: 8px;
                border-left: 3px solid var(--bord); background: var(--fond-2);
                font-size: .92rem; }
/* Deux niveaux, distingués par le LISERÉ et par la place : jamais par la
   couleur seule. */
.alerte-grave { border-left-color: var(--alerte); }
.alerte-attention { border-left-color: #b08b4f; }
.etat-facture.echec { color: #e0a04a; }

/* Lien vers la fiche d'un client, dans une liste.
   Mesuré AVANT correction : 16 px de haut (sous la cible tactile de
   24 px) et contraste 1,86:1 — le lien héritait de la couleur d'accent,
   pensée pour un fond sombre, pas pour ce fond-ci. Un nom de client
   illisible dans la liste des clients, c'est l'écran entier qui rate.
   Le soulignement reste : la couleur seule ne signale pas un lien. */
.lignes-factures .numero a {
  color: var(--texte); text-decoration: underline;
  text-underline-offset: 2px;
  display: inline-block; padding: .25rem 0; min-height: 24px;
}
.lignes-factures .numero a:hover { color: var(--accent); }

/* ---------------------------------------------------------------- *
 * Recherche dans les documents
 * ---------------------------------------------------------------- */
.formulaire-recherche { display: grid; gap: .9rem; }
.formulaire-recherche input[type="search"] { width: 100%; min-height: 2.75rem; }
.formulaire-recherche .bouton-principal { justify-self: start; width: auto; }
.resultats-recherche { list-style: none; margin: .5rem 0 0; padding: 0;
  display: grid; gap: .75rem; }
.resultat-recherche { padding: .75rem .9rem; border: 1px solid var(--bord, #2a313b);
  border-radius: .5rem; background: var(--fond-3); min-width: 0; }
.resultat-titre { margin: 0 0 .35rem; overflow-wrap: anywhere; }
.resultat-extrait { margin: 0; line-height: 1.5; overflow-wrap: anywhere; }
/* Surlignage : couleur d'accent sur fond sombre de l'accent. Jamais le
   jaune par défaut du navigateur, illisible sur ce thème. */
.resultat-extrait mark { background: var(--accent-sombre); color: var(--accent);
  padding: 0 .15em; border-radius: .2em; font-weight: 600; }
.pagination { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap;
  margin-top: 1rem; }

/* Questions d'amorce sur une conversation vide */
.amorces { list-style: none; margin: 1rem 0 .75rem; padding: 0; display: grid; gap: .5rem; }
.amorce { width: 100%; text-align: left; min-height: 2.75rem; padding: .6rem .8rem;
  border: 1px solid var(--bord); border-radius: var(--rayon); background: var(--fond-2);
  color: var(--texte); font: inherit; font-size: .92rem; cursor: pointer;
  overflow-wrap: anywhere; }
.amorce:hover, .amorce:focus-visible { border-color: var(--accent); }
/* [hidden] perd contre un `display` d'auteur : sans cette règle, toutes
   les listes d'amorces s'affichent ensemble (piège déjà rencontré ici). */
.amorces[hidden] { display: none; }

/* ---------------------------------------------------------------- *
 * Vue d'ensemble du corpus — activité des sept derniers jours
 * Couleurs validées (dataviz, mode sombre, fond #161a21) : bleu réussis
 * / orange échec, écart en vision déficiente ≥ 8. Le vert d'accent et
 * l'orange d'alerte, eux, échouaient (ΔE 6,0).
 * ---------------------------------------------------------------- */
.page-espace section { margin-bottom: 1.2rem; }
.legende-activite { display: flex; gap: .4rem 1rem; align-items: center; flex-wrap: wrap;
  margin: .2rem 0 .6rem; font-size: .85rem; color: var(--texte-2); }
.pastille { display: inline-block; width: .75rem; height: .75rem; border-radius: 2px;
  margin-right: .3rem; vertical-align: -1px; }
.pastille-reussi, .barre-reussi { background: #5b8def; }
.pastille-erreur, .barre-erreur { background: #d9733f; }
.activite { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .4rem;
  align-items: end; height: 9rem; }
.activite-jour { display: flex; flex-direction: column; align-items: center; height: 100%;
  min-width: 0; }
.activite-total { font-size: .78rem; color: var(--texte); min-height: 1.1rem; }
/* La pile part de la ligne de base ; un espace de 2 px sépare les deux
   segments, et seul le haut de la pile est arrondi. */
.activite-pile { flex: 1; width: 60%; max-width: 2.2rem; display: flex;
  flex-direction: column; justify-content: flex-end; gap: 2px;
  border-bottom: 1px solid var(--bord); }
.activite-pile > span:first-child { border-radius: 4px 4px 0 0; }
.activite-date { font-size: .72rem; color: var(--texte-2); margin-top: .25rem; }
.detail-activite { margin-top: .6rem; font-size: .85rem; }
.detail-activite table { border-collapse: collapse; margin-top: .4rem; }
.detail-activite th, .detail-activite td { padding: .2rem .7rem .2rem 0; text-align: left; }
.message-echec { display: block; overflow-wrap: anywhere; font-family: ui-monospace, monospace;
  font-size: .78rem; }
/* Liens de la vue d'ensemble : la couleur par défaut du navigateur
   (bleu foncé) est illisible sur ce fond — constaté à la capture. */
.page-espace a:not(.bouton-secondaire) { color: var(--accent); }

/* Sources externes : l'état d'un coup d'œil */
.compteurs-source { gap: .4rem 1.4rem; }
.compteurs-source dd { font-size: 1rem; }
.reglage-source { margin: .4rem 0 .6rem; }

/* Durée écoulée pendant une génération : discrète, chiffres fixes. */
.attente-duree { color: var(--texte-2); font-variant-numeric: tabular-nums; }

/* « Voir comme un groupe » */
.vue-simulee { margin: .4rem 0 .8rem; font-size: .88rem; }
.vue-simulee summary { cursor: pointer; color: var(--texte-2); min-height: 24px; }
.formulaire-vue { display: grid; gap: .4rem; margin: .5rem 0; }
.formulaire-vue select { max-width: 100%; }
.vue-marque { display: block; font-size: .75rem; color: var(--alerte); }
.bandeau-vue { margin: 0 0 1rem; padding: .6rem .8rem; border-radius: var(--rayon);
  border: 1px solid var(--alerte); background: #2a1d16; color: var(--texte); font-size: .9rem; }

/* « Qui peut lire » sous chaque document */
.lisible-par { margin: .2rem 0 .3rem; font-size: .82rem; color: var(--texte-2);
  overflow-wrap: anywhere; }
.lisible-personne { color: var(--alerte); }

/* Extraits des sources, sous chaque réponse */
.sources-repli ol.sources { padding-left: 1.4rem; margin: .4rem 0 0; }
.sources-repli ol.sources li { margin-bottom: .35rem; overflow-wrap: anywhere; }
.source-extrait summary { font-size: .8rem; color: var(--texte-2); cursor: pointer;
  min-height: 24px; }
.source-extrait p { margin: .3rem 0 .2rem; padding: .5rem .7rem; font-size: .85rem;
  border-left: 3px solid var(--bord); background: var(--fond-2); white-space: pre-wrap; }
.source-masquee { display: block; font-size: .8rem; color: var(--alerte); }

/* « Choisir pour moi » restreint à plusieurs assistants */
.perimetre-auto { border: 1px solid var(--bord); border-radius: var(--rayon);
  margin: .3rem 0 .8rem; padding: .4rem .7rem .5rem; font-size: .88rem; }
.perimetre-auto legend { color: var(--texte-2); font-size: .8rem; padding: 0 .3rem; }
.perimetre-auto[hidden] { display: none; }
.perimetre-auto .option-controle { display: flex; gap: .5rem; align-items: center;
  min-height: 32px; }

/* ------------------------------------------------------------------ *
 * Barre sur grand écran : groupes en menus déroulants
 * ------------------------------------------------------------------ */
@media (min-width: 104rem) {
  .nav-large .nav-deroulant { position: relative; }
  .nav-large .nav-deroulant > summary.nav-groupe {
    font-size: .9rem; width: auto; border-left: 0; margin: 0; padding: .35rem .6rem;
    min-height: 36px; display: inline-flex; align-items: center; gap: .3rem;
    color: var(--texte-2); cursor: pointer; list-style: none;
    border-bottom: 2px solid transparent; }
  .nav-large .nav-deroulant.nav-courant > summary { color: var(--texte);
    border-bottom-color: var(--accent); }
  .nav-large .nav-deroulant > summary::before { content: none; }
  .nav-large .nav-deroulant > summary::after { content: "▾"; font-size: .7rem; }
  .nav-large .nav-panneau { position: absolute; top: 100%; left: 0; z-index: 40;
    min-width: 13rem; display: flex; flex-direction: column; gap: .1rem;
    padding: .35rem; background: var(--fond-2); border: 1px solid var(--bord);
    border-radius: var(--rayon); box-shadow: 0 8px 24px rgb(0 0 0 / .35); }
  .nav-large .nav-panneau a { border-bottom: 0; border-left: 2px solid transparent;
    min-height: 36px; }
  .nav-large .nav-panneau a[aria-current="page"] { border-left-color: var(--accent);
    background: var(--fond-3); }
}

/* Écran Droits */
.profils { display: grid; gap: .5rem; margin: .3rem 0 .6rem; }
.profils dt { font-weight: 600; }
.profils dd { margin: 0; color: var(--texte-2); font-size: .9rem; }
.page-droits a:not(.onglet):not(.bouton-secondaire) { color: var(--accent); }

/* Légifrance : bascule dans la saisie, lien sous la source */
.bascule-officielle { display: inline-flex; align-items: center; gap: .3rem;
  font-size: .82rem; min-height: 32px; cursor: pointer; }
.source-lien { display: inline-block; margin-left: .4rem; font-size: .8rem;
  color: var(--accent); }
