/* ============================================================
   Bebsolo SPA — feuille de styles principale.
   Consomme exclusivement les tokens définis dans tokens.css
   (PD1 — source unique de couleurs). Aucun hex en dur ici.
   ============================================================ */

/* LES SYMBOLES DE SECOURS (2026-08-25). Sur le téléphone de Roméo (Android,
   Chrome), Claude Code affichait « ▯▯ bypass permissions » au lieu de « ⏵⏵ »,
   et le bouton « Fichiers » un carré vide à la place de son icône : aucune
   police d'Android n'a ces glyphes, alors que Windows les a (Segoe UI Symbol,
   Cascadia). Trois polices libres, SOUS-ENSEMBLÉES aux seuls blocs de
   symboles et à plages DISJOINTES, portent une même famille « Bebsolo
   Symboles » placée en fin de pile, juste avant la famille générique : elles
   ne fournissent que ce qui manque, jamais les lettres. Sources et licences :
   assets/fonts/LICENCES.txt. Fabrication : le script est dans l'historique du
   commit qui les a posées. */
@font-face {
  font-family: "Bebsolo Symboles";
  src: url("fonts/bebsolo-symboles-mono.woff2") format("woff2");
  font-display: swap;
  /* DejaVu Sans Mono — chasse fixe : cadres, blocs, flèches, formes. */
  unicode-range: U+2190-21FF, U+2300-2306, U+2308-2315, U+2318-2319, U+231C-2321, U+2325-2328, U+232B, U+2335-237A, U+237D, U+2380-2383, U+2388-238B, U+2395, U+239B-23AE, U+23CE-23CF, U+2423, U+2500-262F, U+2638-268B, U+2690-269C, U+26A0-26A1, U+26B0-26B1, U+2701-2704, U+2706-2709, U+270C-2727, U+2729-274B, U+274D, U+274F-2752, U+2756, U+2758-275E, U+2761-2775, U+2794, U+2798-27AF, U+27B1-27BE, U+27F5-27F7, U+2B05-2B0D, U+2B12-2B1A;
}
@font-face {
  font-family: "Bebsolo Symboles";
  src: url("fonts/bebsolo-symboles-2.woff2") format("woff2");
  font-display: swap;
  /* Noto Sans Symbols 2 — ⏵ ⏺ ✳, braille des indicateurs d'attente, pictogrammes. */
  unicode-range: U+2316, U+231A-231B, U+2324, U+237B, U+237E-237F, U+2394, U+23E9-23EA, U+23ED-23EF, U+23F1-2422, U+2424-2426, U+2630-2637, U+268C-268F, U+269E-269F, U+26AA-26AC, U+26BD-26CD, U+26CF-26E1, U+2700, U+270B, U+2753, U+2757, U+275F-2760, U+2800-28FF, U+2B00-2B04, U+2B1B-2B2F, U+2B4D-2B73, U+2B76-2B95, U+2B97-2BFD, U+2BFF, U+1F5C0-1F5FA;
}
@font-face {
  font-family: "Bebsolo Symboles";
  src: url("fonts/bebsolo-symboles-1.woff2") format("woff2");
  font-display: swap;
  /* Noto Sans Symbols — ⎿ des résultats d'outils, chiffres cerclés, le reste. */
  unicode-range: U+2307, U+2317, U+2322-2323, U+2329-232A, U+232C-2334, U+237C, U+2384-2387, U+238C-2393, U+2396-239A, U+23AF, U+23BE-23CD, U+23D0-23DB, U+23E2-23E8, U+2460-24FF, U+269D, U+26A2-26A9, U+26AD-26AF, U+26B2-26BC, U+26CE, U+26E2-26FF, U+2776-2793, U+2921-2922;
}

*,
*::before,
*::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--mst-bg-app);
  color: var(--mst-text-primary);
  font-family: var(--mst-font-sans);
  font-size: var(--mst-fs-body);
  line-height: var(--mst-lh-body);
  -webkit-font-smoothing: antialiased;
}

button, input, textarea, select {
  font: inherit;
  color: inherit;
}

a {
  color: var(--mst-accent);
  text-decoration: none;
}
a:hover { color: var(--mst-accent-hover); }

/* ---------- Layout ---------- */

#app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.topbar {
  display: flex;
  align-items: center;
  /* `wrap` : sous ~700px de large (mobile), brand + onglets + langue +
     exposition + bouton « Redémarrer » ne tiennent pas sur une ligne. Sans
     retour à la ligne, la partie droite (dont le bouton « Redémarrer »)
     déborde hors du viewport et n'est atteignable qu'au prix d'un
     défilement horizontal — mesuré à 390px : bouton à x=618 pour un
     viewport de 390. */
  flex-wrap: wrap;
  gap: var(--mst-sp-4);
  padding: var(--mst-sp-3) var(--mst-sp-5);
  background: var(--mst-bg-surface);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  position: sticky;
  top: 0;
  z-index: 10;
}

/* Bannière de statut de redémarrage — premier enfant de #app sur TOUTE route
   (voir dashboard.js:mountRestartBanner). #app est le seul parent commun de
   tous les en-têtes de route (topbar, mission-header, tout en-tête futur) :
   la bannière est placée AVANT ces en-têtes dans le même flux, et sticky en
   haut du viewport pour rester visible pendant le défilement.

   Coordination des offsets sticky (règle `~ *` ci-dessous) — être sticky au
   même `top: 0` que l'en-tête de route NE SUFFIT PAS : « la bannière précède
   l'en-tête dans le flux » n'est vrai qu'à scrollY = 0. Dès que l'en-tête
   atteint son propre seuil sticky, il se fige AU MÊME `top: 0` que la
   bannière, donc exactement sous elle : navigation et bouton « Redémarrer »
   deviennent invisibles et non cliquables au moment précis où un redémarrage
   a échoué.

   `#restart-status-banner ~ *` corrige ça sans jamais coder en dur une
   hauteur ni un nom de classe d'en-tête : tout frère SUIVANT la bannière se
   fige sous elle, à `--bb-restart-banner-h` — la hauteur RÉELLEMENT rendue,
   mesurée et republiée par dashboard.js à chaque changement de taille. Aucune
   valeur de gabarit n'est écrite ici : la bannière n'a pas la même hauteur
   selon la largeur de l'écran et la longueur du motif, et un chiffre inscrit
   dans un commentaire ne serait vérifié par personne. La règle est sans effet
   sur un frère NON positionné — `top` n'est pris en compte que par un élément
   positionné — donc inoffensive pour tout le reste de la page.

   Portée délibérée : cette règle DÉCALE ce qui est déjà collant, elle ne
   rend RIEN collant. La bannière ne doit épingler aucun élément qui ne
   l'était pas de lui-même, et surtout pas « le premier frère » : ce frère
   n'est pas une abstraction, c'est l'en-tête concret de la route affichée —
   .topbar sur le dashboard, collante par conception, mais .mission-header sur
   une mission, un en-tête volontairement NON collant dont la hauteur est
   celle d'un titre, de fils d'Ariane, de pastilles et d'une barre de
   progression. L'épingler portait la pile collante d'une page mission à plus
   du tiers de l'écran, et capturait au hit-test les commandes situées
   dessous — jusqu'au bouton « Envoyer la directive », par lequel l'opérateur
   répond à un agent qui attend un arbitrage. Un élément à rendre collant se
   désigne donc par un sélecteur explicite, jamais par sa position dans la
   fratrie. Hors redémarrage en cours ou échoué, chaque route garde de toute
   façon exactement son comportement de défilement d'origine : la variable
   retombe à 0px au démontage de la bannière. */
.restart-status-banner {
  position: sticky;
  top: 0;
  z-index: 40;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 14px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .4);
}
/* Hauteur bornée du bandeau — c'est elle qui fixe la part d'écran figée.
   Un motif d'échec est long par nature (« nouveau cockpit n a jamais répondu
   … il est LAISSÉ VIVANT … ») ; laissé libre de se replier, il occupait
   plusieurs lignes en permanence sur un écran étroit, et capturait au
   hit-test autant de commandes juste dessous. Le texte est donc borné à deux
   lignes et le bouton reste sur la première.

   Ce que ce repli COÛTE, et comment il est rendu : sur un écran de téléphone,
   deux lignes ne montrent qu'une petite part du message. Le reste n'est pas
   « accessible ailleurs » de façon utilisable — l'attribut `title` n'ouvre
   d'infobulle qu'au survol, et un écran tactile n'a pas de survol
   (`hover: none`, `pointer: coarse`) ; `GET /health` et
   `cockpit-restart-echec.log` demandent un outil et un clavier, pas un doigt.
   Le motif tronqué est donc porté par un BOUTON qui le déplie sur place
   (`.restart-status-banner__reason`, cf. dashboard.js) : c'est cette
   affordance-là, et elle seule, qui rend le message lisible en entier sur
   téléphone — l'intégralité du motif est atteignable d'un appui puis d'un
   défilement dans le bandeau, quelle que soit la largeur.

   Aucune hauteur ni aucun pourcentage n'est cité ici, et c'est délibéré : un
   chiffre inscrit en commentaire est une assertion que rien n'exécute. Ceux
   de ce bandeau ont menti trois lots de suite. Les mesures vivent dans le
   journal de mission, avec leurs conditions ; le code, lui, ne porte que ce
   qu'il applique. */
.restart-status-banner > span {
  /* base 0 (et non `auto`) : avec `flex-wrap: wrap`, un texte long garde une
     taille de base égale à sa largeur naturelle et pousse le bouton sur une
     seconde rangée — le bandeau fait alors deux rangées au lieu d'une. */
  flex: 1 1 0;
  min-width: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* Affordance de révélation au toucher — le motif d'échec est un bouton.
   Un vrai `<button>` et non un `div` cliquable : focus clavier, activation à
   Entrée/Espace, rôle annoncé aux lecteurs d'écran et `aria-expanded` sans
   rien à réimplémenter.

   `min-height: 44px` porte la cible tactile au format confortable au doigt
   (WCAG 2.5.5) y compris quand le motif tient sur une seule ligne. Ce
   plancher COÛTE quelques pixels de bandeau gelé en PERMANENCE, même replié
   et même quand le texte n'en a pas besoin : c'est un choix assumé, pas un
   oubli — une cible qu'on rate au doigt sur un téléphone rend l'affordance
   inutilisable, et cette affordance est la seule voie vers le motif complet.
   La valeur `44px` est épinglée par
   `test_the_failure_reason_is_revealed_by_a_real_touch_affordance`
   (tests/test_lot4_restart.py) — c'est ce test, pas ce commentaire, qui fait
   foi si la valeur change. */
.restart-status-banner__reason {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 44px;
  padding: 2px 22px 2px 0;  /* réserve la gouttière du chevron */
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: rgba(255, 255, 255, .25);
}
.restart-status-banner__reason:focus-visible {
  outline: 0;
  box-shadow: var(--mst-focus-ring);
  border-radius: var(--mst-radius-sm);
}
.restart-status-banner__text {
  width: 100%;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
/* Déplié : le texte n'est plus tronqué, et ce qui dépasse défile DANS le
   bandeau. La borne n'est pas une fraction du viewport mais le budget
   `--bb-reason-max-h` que dashboard.js publie — ce qui reste de la part
   d'écran que la pile collante a le droit de figer, une fois retirées la
   hauteur MESURÉE de l'en-tête de route épinglé sous le bandeau et celle de
   l'habillage du bandeau lui-même. Borner le seul bloc de texte laissait ces
   deux-là hors du compte : le texte tenait sa limite pendant que la pile,
   elle, mangeait la moitié de l'écran.

   `overscroll-behavior: contain` empêche ce défilement interne de se
   propager à la page dessous une fois arrivé en bout de course. */
.restart-status-banner.is-expanded .restart-status-banner__text {
  display: block;
  -webkit-line-clamp: none;
  line-clamp: none;
  max-height: var(--bb-reason-max-h, 40vh);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Le chevron est posé DANS la gouttière réservée, en absolu : il ne prend
   aucune hauteur. C'est délibéré — une étiquette « voir le motif complet » sur
   sa propre ligne épaissit le bandeau en permanence, c'est-à-dire reprend
   d'une main le budget d'écran que le bornage à deux lignes venait de gagner.
   L'intitulé complet de l'action n'est pas perdu : il est porté par
   l'`aria-label` du bouton (lecteurs d'écran) et par son `title` (survol, là
   où le survol existe). */
.restart-status-banner__more {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  font-size: 15px;
  line-height: 1;
  opacity: .9;
}
/* Rien de plus à voir (le message tient à l'écran, cf. `data-tronque` mesuré
   après rendu par dashboard.js) : pas d'invitation à déplier. Une affordance
   qui promet un contenu inexistant cesse vite d'être crue. */
.restart-status-banner[data-tronque="non"]:not(.is-expanded) .restart-status-banner__more {
  display: none;
}
.restart-status-banner > .btn {
  flex: 0 0 auto;
}
#app > #restart-status-banner ~ * {
  top: var(--bb-restart-banner-h, 0px);
}
.restart-status-banner--failed {
  background: #5c1e1e;
  color: #fff;
}
.restart-status-banner--pending {
  background: var(--mst-bg-surface-2);
  color: var(--mst-text-primary);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}

.topbar__brand {
  font-size: var(--mst-fs-display);
  font-weight: var(--mst-fw-bold);
  letter-spacing: 0.5px;
}

/* LA BARRE D'ONGLETS DÉFILE EN ELLE-MÊME, À TOUTE LARGEUR (2026-09-19). Mesuré
   à 360 px en ajoutant l'onglet Explorateur : la barre faisait déjà ~670 px
   avant lui, 777 px après, et c'est la PAGE entière qui défilait à
   l'horizontale (817 px de large pour un écran de 360), sur tous les onglets.
   `min-width: 0` laisse la barre rétrécir à la largeur de sa ligne (sans lui,
   un élément flexible ne descend jamais sous sa largeur de contenu) ; le
   surplus défile dans la barre, jamais dans la page. dashboard.js ramène
   l'onglet actif dans le champ.
   D'abord posée sous 700 px seulement ; mesuré le même jour (vue Corbeille) :
   ENTRE 701 ET 816 px, la page faisait encore 817 px de large — la largeur
   exacte de la mise en page du téléphone de Roméo en mode « site pour
   ordinateur ». La règle vaut désormais partout (sentinelle :
   tests/test_explorateur_corbeille.py) ; au-delà de 817 px, les onglets
   tiennent et rien ne défile. */
.topbar__tabs {
  display: flex;
  gap: var(--mst-sp-1);
  min-width: 0;
  margin-left: var(--mst-sp-4);
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--mst-border-strong) transparent;
}
.topbar__tabs .tab { flex: 0 0 auto; }
@media (max-width: 700px) {
  .topbar__tabs {
    max-width: 100%;
    margin-left: 0;
  }
}

.tab {
  padding: var(--mst-sp-2) var(--mst-sp-3);
  background: transparent;
  border: 0;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-title);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color var(--mst-motion-fast) var(--mst-easing),
              border-color var(--mst-motion-fast) var(--mst-easing);
}
.tab:hover { color: var(--mst-text-primary); }
.tab.is-active {
  color: var(--mst-text-primary);
  border-bottom-color: var(--mst-accent);
}
.tab:focus-visible { outline: 0; box-shadow: var(--mst-focus-ring); border-radius: var(--mst-radius-sm); }

/* Badge de rôle de device dans le tableau Admin > Appareils. */
.device-role-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: var(--mst-fs-micro);
  font-weight: var(--mst-fw-bold);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  border: 1px solid var(--mst-border);
}
.device-role-badge[data-role="host"]  { color: #f5c542; border-color: #f5c542; }
.device-role-badge[data-role="admin"] { color: #4a90e2; border-color: #4a90e2; }
.device-role-badge[data-role="user"]  { color: var(--mst-text-secondary); }

/* Sélecteur de langue — bouton compact dans la topbar tabs.
   Cycle FR → EN → LV → FR au clic. */
.topbar__locale {
  margin-left: var(--mst-sp-3);
  padding: 4px 10px;
  background: transparent;
  border: 1px solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
  font-weight: var(--mst-fw-bold);
  cursor: pointer;
  letter-spacing: 0.5px;
  transition: all var(--mst-motion-fast) var(--mst-easing);
}
.topbar__locale:hover {
  color: var(--mst-text-primary);
  border-color: var(--mst-accent);
}
.topbar__locale:focus-visible { outline: 0; box-shadow: var(--mst-focus-ring); }

.topbar__right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--mst-sp-4);
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
}

/* Lot 4 S4b — bouton « Redémarrer » discret, à droite du header. */
.topbar__restart {
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-1);
  padding: 2px var(--mst-sp-2);
  border: 1px solid var(--mst-text-muted);
  border-radius: var(--mst-radius-sm);
  background: transparent;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
  cursor: pointer;
}
.topbar__restart:hover {
  color: var(--mst-text-primary);
  border-color: var(--mst-text-secondary);
}

.exposure {
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-1);
}
.exposure__dot {
  width: 10px; height: 10px;
  border-radius: var(--mst-radius-pill);
  background: var(--mst-net-local);
  display: inline-block;
}
.exposure[data-state="remote"] .exposure__dot { background: var(--mst-net-remote); }
.exposure[data-state="remote"] { color: var(--mst-net-remote); }

.mission-selector {
  display: flex;
  gap: var(--mst-sp-1);
  padding: var(--mst-sp-2) var(--mst-sp-5);
  background: var(--mst-bg-surface);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  overflow-x: auto;
}
.mission-selector__chip {
  padding: var(--mst-sp-1) var(--mst-sp-3);
  background: var(--mst-bg-surface-2);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-pill);
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-1);
}
.mission-selector__chip.is-active {
  border-color: var(--mst-accent);
  color: var(--mst-text-primary);
  background: var(--mst-accent-bg);
}
.mission-selector__chip[data-attention="true"]::before {
  content: "⚠";
  color: var(--mst-sem-arbitration);
}

.main {
  flex: 1;
  padding: var(--mst-sp-5);
  max-width: 1400px;
  width: 100%;
  margin: 0 auto;
}

/* ---------- Boutons ---------- */

.btn {
  height: var(--mst-row-h);
  padding: 0 var(--mst-sp-4);
  border-radius: var(--mst-radius-sm);
  border: var(--mst-border-w) solid var(--mst-border);
  background: var(--mst-bg-surface-2);
  color: var(--mst-text-primary);
  cursor: pointer;
  font-size: var(--mst-fs-body);
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-1);
  transition: background var(--mst-motion-fast) var(--mst-easing),
              border-color var(--mst-motion-fast) var(--mst-easing);
}
.btn:hover {
  background: var(--mst-bg-surface);
  border-color: var(--mst-border-strong);
}
.btn:focus-visible { outline: 0; box-shadow: var(--mst-focus-ring); }
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--mst-bg-surface-2);
  color: var(--mst-text-muted);
  cursor: not-allowed;
}

.btn--primary {
  background: var(--mst-accent);
  color: var(--mst-text-on-accent);
  border-color: var(--mst-accent);
}
.btn--primary:hover {
  background: var(--mst-accent-hover);
  border-color: var(--mst-accent-hover);
}
.btn--primary:disabled {
  background: var(--mst-bg-surface-2);
  color: var(--mst-text-muted);
  border-color: var(--mst-border);
}

.btn--danger {
  background: transparent;
  color: var(--mst-sem-escalation);
  border-color: var(--mst-sem-escalation);
}
.btn--danger:hover {
  background: var(--mst-sem-escalation-bg);
}

/* ---------- Cartes de mission ---------- */

.dashboard__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--mst-sp-3);
  margin-bottom: var(--mst-sp-5);
}
.dashboard__title { font-size: var(--mst-fs-display); margin: 0; }
.dashboard__compte { color: var(--mst-text-secondary); font-weight: normal; }
/* Recherche de missions (2026-09-12), juste avant « Lancer une mission ». */
.dashboard__actions {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  /* JAMAIS DE RETOUR À LA LIGNE (Roméo, 2026-09-12, capture à l'appui) : la
     recherche se place À GAUCHE du bouton, pas au-dessus. Elle se rétrécit
     quand la place manque — c'est le champ qui cède, pas la ligne. */
  flex-wrap: nowrap;
  flex: 1 1 auto;
  min-width: 0;                /* sans ça, le bloc déborde sur un téléphone */
  justify-content: flex-end;
}
.dashboard__recherche {
  flex: 1 1 10rem;
  min-width: 0;
  max-width: 22rem;
  padding: var(--mst-sp-2) var(--mst-sp-3);
  background: var(--mst-bg-inset);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  color: var(--mst-text-primary);
  font-size: var(--mst-fs-body);
}
.dashboard__actions .btn {
  flex: 0 0 auto;              /* le bouton garde sa taille, le champ cède */
  white-space: nowrap;
}
.dashboard__recherche:focus {
  outline: 0;
  border-color: var(--mst-accent);
  box-shadow: var(--mst-focus-ring);
}

.mission-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
  gap: var(--mst-sp-4);
}

.mission-card {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-4);
  cursor: pointer;
  transition: background var(--mst-motion-fast) var(--mst-easing),
              border-color var(--mst-motion-fast) var(--mst-easing);
}
.mission-card:hover {
  background: var(--mst-bg-surface-2);
  border-color: var(--mst-border-strong);
}
.mission-card[data-attention="true"] {
  border-left: 3px solid var(--mst-sem-arbitration);
}

.mission-card__head {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  margin-bottom: var(--mst-sp-2);
}
.mission-card__state {
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-1);
  text-transform: uppercase;
  font-weight: var(--mst-fw-medium);
  font-size: var(--mst-fs-micro);
}
.mission-card__title {
  font-size: var(--mst-fs-title);
  font-weight: var(--mst-fw-medium);
  margin: 0 0 var(--mst-sp-3) 0;
  color: var(--mst-text-primary);
}
.mission-card__progress {
  height: 6px;
  background: var(--mst-border);
  border-radius: var(--mst-radius-pill);
  overflow: hidden;
  margin-bottom: var(--mst-sp-1);
}
.mission-card__progress > span {
  display: block;
  height: 100%;
  background: var(--mst-accent);
}
.mission-card__meta {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  display: flex;
  justify-content: space-between;
  gap: var(--mst-sp-2);
}
.mission-card__alert {
  color: var(--mst-sem-arbitration);
  font-weight: var(--mst-fw-medium);
}
/* Bouton Supprimer sur la carte mission — décalé à droite dans la rangée head */
.mission-card__delete {
  margin-left: auto;
  padding: 2px 8px;
  font-size: var(--mst-fs-micro);
  opacity: 0;
  transition: opacity var(--mst-motion-fast) var(--mst-easing);
  pointer-events: none;
}
.mission-card:hover .mission-card__delete {
  opacity: 1;
  pointer-events: auto;
}

/* Étoile favori — affichée en début de tête de carte, toujours visible
   pour les favoris, atténuée pour les autres (révélée au hover). */
.mission-card__fav {
  background: transparent;
  border: 0;
  padding: 0 4px;
  margin-right: 4px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  color: var(--mst-text-muted);
  transition: color var(--mst-motion-fast) var(--mst-easing),
              opacity var(--mst-motion-fast) var(--mst-easing);
  opacity: 0.4;
}
.mission-card__fav[data-favorite="true"] {
  color: #f5c542;       /* doré */
  opacity: 1;
}
.mission-card:hover .mission-card__fav { opacity: 1; }
.mission-card__fav:hover { color: #f5c542; }

/* Liseré gauche doré pour les missions favorites (signal visuel renforcé). */
.mission-card[data-favorite="true"] {
  box-shadow: inset 3px 0 0 0 #f5c542;
}

/* Cursor pointer sur la 1ère ligne d'un message (toggle déplier/replier). */
.message__summary { cursor: pointer; }

/* Tableau de stats dans la modale de suppression */
.delete-mission-stats td {
  padding: 2px 12px 2px 0;
  vertical-align: top;
}
.delete-mission-stats td:first-child {
  color: var(--mst-text-muted);
  white-space: nowrap;
  font-weight: var(--mst-fw-medium);
}

/* ---------- Pastilles d'état ---------- */

.dot {
  width: 8px;
  height: 8px;
  display: inline-block;
  border-radius: var(--mst-radius-pill);
}
.dot[data-state="RUNNING"]        { background: var(--mst-state-session-running); }
.dot[data-state="PAUSED"]         { background: var(--mst-state-session-paused); }
.dot[data-state="AWAITING_HUMAN"] { background: var(--mst-state-session-awaiting_human); }
.dot[data-state="STOPPED"]        { background: var(--mst-state-session-stopped); }

/* ---------- Modale ---------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: var(--mst-sp-5);
}
.modal {
  background: var(--mst-bg-surface);
  border-radius: var(--mst-radius-md);
  border: var(--mst-border-w) solid var(--mst-border);
  box-shadow: var(--mst-elevation-modal);
  max-width: 640px;
  width: 100%;
  max-height: 90vh;
  overflow: auto;
  padding: var(--mst-sp-5);
}
.modal__title {
  margin: 0 0 var(--mst-sp-4) 0;
  font-size: var(--mst-fs-display);
}
.modal__close {
  float: right;
  background: transparent;
  border: 0;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-title);
  cursor: pointer;
}
.modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--mst-sp-2);
  margin-top: var(--mst-sp-5);
  padding-top: var(--mst-sp-4);
  border-top: var(--mst-border-w) solid var(--mst-border);
}

/* ---------- Formulaires ---------- */

.field { margin-bottom: var(--mst-sp-4); }
.field__label {
  display: block;
  margin-bottom: var(--mst-sp-1);
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
  font-weight: var(--mst-fw-medium);
}
.field input[type="text"],
.field textarea,
.field input[type="number"] {
  width: 100%;
  padding: var(--mst-sp-2) var(--mst-sp-3);
  background: var(--mst-bg-inset);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  color: var(--mst-text-primary);
  font-size: var(--mst-fs-body);
}
.field textarea { min-height: 96px; resize: vertical; }
.field input:focus,
.field textarea:focus {
  outline: 0;
  border-color: var(--mst-accent);
  box-shadow: var(--mst-focus-ring);
}

.mode-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--mst-sp-2);
}
.mode-card {
  padding: var(--mst-sp-3);
  background: var(--mst-bg-surface-2);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  cursor: pointer;
  transition: background var(--mst-motion-fast) var(--mst-easing),
              border-color var(--mst-motion-fast) var(--mst-easing);
}
.mode-card:hover { border-color: var(--mst-border-strong); }
.mode-card.is-selected {
  background: var(--mst-accent-bg);
  border: 2px solid var(--mst-accent);
  padding: calc(var(--mst-sp-3) - 1px);
}
.mode-card__title {
  font-weight: var(--mst-fw-medium);
  margin-bottom: var(--mst-sp-1);
  display: flex;
  align-items: center;
  gap: var(--mst-sp-1);
}
.mode-card__sub {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  line-height: var(--mst-lh-meta);
}

.casting-box {
  padding: var(--mst-sp-3);
  background: var(--mst-bg-surface-2);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
}
.casting-box label { display: flex; gap: var(--mst-sp-2); align-items: flex-start; cursor: pointer; }
.casting-box__hint {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  margin-top: var(--mst-sp-1);
  padding-left: 26px;
}

/* ---------- Page mission — en-tête ---------- */

.mission-header {
  background: var(--mst-bg-surface);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  padding: var(--mst-sp-3) var(--mst-sp-5);
}
.mission-header__crumbs {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  margin-bottom: var(--mst-sp-2);
}
.mission-header__crumbs a { color: var(--mst-accent); cursor: pointer; }
.mission-header__title-row {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-3);
  margin-bottom: var(--mst-sp-3);
}
.mission-header__title {
  font-size: var(--mst-fs-display);
  margin: 0;
}
.mission-header__chip {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  padding: var(--mst-sp-1) var(--mst-sp-2);
  background: var(--mst-bg-surface-2);
  border-radius: var(--mst-radius-pill);
  border: var(--mst-border-w) solid var(--mst-border);
}
/* Badge MODE — J4-2b. Couleur sémantique distincte selon DryRun/SDK. */
.mission-header__chip--runtime {
  font-weight: 600;
  letter-spacing: 0.03em;
}
.mission-header__chip--runtime[data-runtime="sdk"] {
  color: var(--mst-sem-go);
  border-color: var(--mst-sem-go);
  background: var(--mst-bg-surface-2);
}
/* J4-9 — runtime ``claude_cli`` (claude -p via abonnement Pro/Max).
   Couleur sémantique distincte : on emprunte le ton "phase" (bleu/violet)
   pour bien le séparer visuellement du SDK API (vert "go") et du
   DryRun (gris). Le mode est central dans la promesse "tu utilises ton
   abonnement, pas de carte bancaire" — il mérite sa propre teinte. */
.mission-header__chip--runtime[data-runtime="claude_cli"] {
  color: var(--mst-sem-phase, var(--mst-sem-go));
  border-color: var(--mst-sem-phase, var(--mst-sem-go));
  background: var(--mst-bg-surface-2);
}
.mission-header__chip--runtime[data-runtime="dry_run"] {
  color: var(--mst-text-muted);
  border-color: var(--mst-border);
  background: var(--mst-bg-surface-2);
}
.mission-header__actions {
  display: flex;
  gap: var(--mst-sp-2);
  margin-left: auto;
}
.mission-header__progress-row {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-3);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}
.mission-header__progress {
  flex: 1;
  height: 4px;
  background: var(--mst-border);
  border-radius: var(--mst-radius-pill);
  overflow: hidden;
  max-width: 320px;
}
.mission-header__progress > span {
  display: block; height: 100%;
  background: var(--mst-accent);
}

.tabs-row {
  display: flex;
  gap: var(--mst-sp-1);
  padding: 0 var(--mst-sp-5);
  background: var(--mst-bg-surface);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}

/* ---------- Onglet Messages ---------- */

.messages-toolbar {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  padding: var(--mst-sp-3) var(--mst-sp-5);
  flex-wrap: wrap;
  background: var(--mst-bg-app);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}
.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-1);
  padding: 2px var(--mst-sp-2);
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-pill);
  font-size: var(--mst-fs-micro);
  color: var(--mst-text-secondary);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
/* Correctif B — filtre actif : fond accentué + bordure épaisse + texte fort */
.filter-pill.is-active {
  color: var(--mst-accent);
  background: var(--mst-accent-bg);
  border-width: 2px;
  border-color: var(--mst-accent);
  font-weight: var(--mst-fw-bold);
}
.filter-pill--clear {
  color: var(--mst-text-muted);
  border-style: dashed;
}

/* Correctif C — bouton plier/déplier global */
.messages-toolbar__count {
  margin-left: auto;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
}
.messages-expand-all {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  font-size: var(--mst-fs-micro);
  color: var(--mst-text-secondary);
  cursor: pointer;
  padding: 2px var(--mst-sp-2);
  white-space: nowrap;
  transition: background 0.12s, color 0.12s;
}
.messages-expand-all:hover {
  background: var(--mst-accent-bg);
  color: var(--mst-accent);
  border-color: var(--mst-accent);
}

/* Correctif A — placeholder liste vide */
.messages-empty {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-muted);
  font-style: italic;
  padding: var(--mst-sp-4) var(--mst-sp-3);
  text-align: center;
}

.messages {
  display: flex;
  flex-direction: column;
  gap: 1px;
  /* Padding interne réduit pour que la zone soit plus large visuellement,
     comme demandé par Roméo (capture box verte plus généreuse). */
  padding: var(--mst-sp-2) var(--mst-sp-2);
  /* Marges externes : zone qui prend toute la largeur dispo, avec une
     petite marge horizontale pour respirer côté bordure. */
  margin: var(--mst-sp-2) var(--mst-sp-3);
  /* Scroll interne : la liste tient sur ~1 écran et défile sans pousser
     les onglets ni la bannière hors champ. */
  max-height: calc(100vh - 280px);
  overflow-y: auto;
  border: 1px solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: var(--mst-bg-deep, var(--mst-bg-surface));
}

/* Note : le scroll Monitoring est défini plus bas (ligne ~844) avec un
   layout 2 colonnes scrollant indépendamment (chef à gauche, agents à
   droite). On garde juste un wrapper compact ici. */
.monitoring-wrap {
  margin: var(--mst-sp-2) var(--mst-sp-3);
  border: 1px solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  overflow: hidden;
}

.message {
  display: grid;
  grid-template-columns: 4px max-content max-content max-content 1fr auto;
  gap: var(--mst-sp-3);
  padding: var(--mst-sp-2) var(--mst-sp-3);
  background: var(--mst-bg-surface);
  align-items: start;
  position: relative;
}
.message__body {
  text-align: left;
  word-break: break-word;
}
.message__liseré {
  width: 3px;
  height: 100%;
  background: var(--mst-sem-task);
  border-radius: var(--mst-radius-pill);
}
.message[data-actionable="true"] {
  background: var(--mst-sem-arbitration-bg);
}
.message[data-type="escalation"][data-actionable="true"] {
  background: var(--mst-sem-escalation-bg);
}
.message__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-1);
  padding: 2px var(--mst-sp-2);
  border-radius: var(--mst-radius-sm);
  font-size: var(--mst-fs-micro);
  font-weight: var(--mst-fw-bold);
  letter-spacing: 0.5px;
}
.message__time {
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
  font-family: var(--mst-font-mono);
}
.message__author {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  /* Lot 4 S4a — nom d'agent sur une ligne, modèle en dessous (cf. Monitoring). */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}
.message__author-tag {
  display: inline-block;
  border-left: 3px solid var(--mst-text-muted);
  padding: 0 var(--mst-sp-1) 0 var(--mst-sp-1);
  color: var(--mst-text-primary);
  font-weight: var(--mst-fw-medium);
}
/* Lot 3 (#27) — modèle réel sous l'auteur d'un message.
   Lot 4 S4a — passe en block sous le nom (plus inline à sa suite). */
.message__author-model {
  display: block;
  margin-left: 0;
  font-family: var(--mst-font-mono, monospace);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-muted);
}
.message__body {
  font-size: var(--mst-fs-body);
  line-height: var(--mst-lh-body);
}
.message__summary { color: var(--mst-text-primary); }
.message__detail {
  margin-top: var(--mst-sp-2);
  padding-top: var(--mst-sp-2);
  border-top: var(--mst-border-w) dashed var(--mst-border);
  font-size: var(--mst-fs-body);
  color: var(--mst-text-secondary);
  white-space: pre-wrap;
}
.message__toggle {
  background: transparent;
  border: 0;
  color: var(--mst-text-secondary);
  cursor: pointer;
  font-size: var(--mst-fs-title);
  padding: 0 var(--mst-sp-1);
}

.banner-new {
  position: sticky;
  top: 0;
  margin: var(--mst-sp-2) 0;
  text-align: center;
  background: var(--mst-accent-bg);
  color: var(--mst-accent);
  padding: var(--mst-sp-2);
  border-radius: var(--mst-radius-sm);
  cursor: pointer;
  font-size: var(--mst-fs-meta);
  font-weight: var(--mst-fw-medium);
  display: none;
}
.banner-new.is-visible { display: block; }

/* ---------- Onglet Tâches (refonte 2 colonnes) ---------- */

.tasks-2col {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: var(--mst-sp-3);
  padding: var(--mst-sp-3);
  /* Hauteur DÉFINIE (pas seulement max-height) — indispensable pour que le
     `max-height: 100%` des colonnes ci-dessous se résolve et déclenche leur
     `overflow-y: auto`. Avec un simple max-height, la hauteur du parent reste
     `auto`, le % des enfants ne se résout pas, les colonnes débordent et sont
     coupées par `overflow: hidden` → aucune barre de défilement (le contenu du
     bas devenait invisible). Même mécanique que l'onglet Monitoring. */
  height: calc(100vh - 240px);
  overflow: hidden;
}
.tasks-2col__left, .tasks-2col__right {
  background: var(--mst-bg-surface);
  border: 1px solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-3);
  overflow-y: auto;
  max-height: 100%;
}
.tasks-2col__heading {
  margin: 0 0 var(--mst-sp-2) 0;
  font-size: var(--mst-fs-body);
  color: var(--mst-text-primary);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  border-bottom: 1px solid var(--mst-border);
  padding-bottom: var(--mst-sp-2);
}
.tasks-2col__subheading {
  margin: var(--mst-sp-3) 0 var(--mst-sp-1) 0;
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.phase-card {
  background: var(--mst-bg-surface-2);
  border-left: 3px solid var(--mst-text-muted);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-2);
  margin-bottom: var(--mst-sp-2);
}
.phase-card[data-state="current"] { border-left-color: var(--mst-sem-phase); }
.phase-card[data-state="done"] { border-left-color: var(--mst-state-done); opacity: 0.7; }
.phase-card__head { display: flex; gap: var(--mst-sp-2); align-items: center; }
.phase-card__glyph { font-size: 14px; }
.phase-card__title { font-size: var(--mst-fs-body); color: var(--mst-text-primary); }
.phase-card__meta { font-size: var(--mst-fs-micro); color: var(--mst-text-muted); margin-top: 2px; font-family: var(--mst-font-mono); }
.lot-mini {
  display: flex; gap: var(--mst-sp-2); align-items: center;
  padding: var(--mst-sp-1) var(--mst-sp-2);
  background: var(--mst-bg-surface-2);
  border-radius: var(--mst-radius-sm);
  margin-bottom: var(--mst-sp-1);
  font-size: var(--mst-fs-meta);
}
.lot-mini__code { color: var(--mst-text-muted); font-family: var(--mst-font-mono); }
.lot-mini__title { flex: 1; color: var(--mst-text-primary); }
.lot-mini__progress { color: var(--mst-text-secondary); }

.task-table__head, .task-table__row {
  display: grid;
  grid-template-columns: 110px 1fr 140px 80px;
  gap: var(--mst-sp-2);
  align-items: center;
  padding: var(--mst-sp-1) var(--mst-sp-2);
}
.task-table__head {
  font-size: var(--mst-fs-micro);
  color: var(--mst-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-bottom: 1px solid var(--mst-border);
  margin-bottom: var(--mst-sp-1);
}
.task-table__row {
  border-bottom: 1px solid transparent;
  font-size: var(--mst-fs-body);
}
.task-table__row:hover { background: var(--mst-bg-surface-2); }
.task-table__col--status { font-family: var(--mst-font-mono); font-size: var(--mst-fs-meta); }
.task-table__row[data-status="done"] .task-table__col--status { color: var(--mst-state-done); }
.task-table__row[data-status="in_progress"] .task-table__col--status { color: var(--mst-state-in_progress); }
.task-table__row[data-status="open"] .task-table__col--status { color: var(--mst-state-open); }
.task-table__row[data-status="blocked"] .task-table__col--status { color: var(--mst-state-blocked); }
.task-table__col--title { color: var(--mst-text-primary); word-break: break-word; }
.task-table__col--agent { color: var(--mst-text-secondary); font-size: var(--mst-fs-meta); }
.task-table__col--time { color: var(--mst-text-muted); font-size: var(--mst-fs-meta); font-family: var(--mst-font-mono); }
.empty--inline { padding: var(--mst-sp-2); font-style: italic; }

/* Ancien style conservé pour compatibilité (encore utilisé ailleurs) */
.tasks {
  padding: var(--mst-sp-3) var(--mst-sp-5) var(--mst-sp-5) var(--mst-sp-5);
}
.lot {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  margin-bottom: var(--mst-sp-3);
  overflow: hidden;
}
.lot__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--mst-sp-2) var(--mst-sp-4);
  background: var(--mst-bg-surface-2);
  cursor: pointer;
}
.lot__title { font-weight: var(--mst-fw-medium); display: flex; align-items: center; gap: var(--mst-sp-2); }
.lot__progress { font-size: var(--mst-fs-meta); color: var(--mst-text-secondary); }
.lot__tasks { padding: var(--mst-sp-2) var(--mst-sp-3); }
.task-row {
  display: grid;
  grid-template-columns: 20px 1fr 180px 90px;
  gap: var(--mst-sp-2);
  padding: var(--mst-sp-1) var(--mst-sp-2);
  align-items: center;
  font-size: var(--mst-fs-body);
}
.task-row:hover { background: var(--mst-bg-surface-2); }
.task-row__glyph { font-size: 16px; text-align: center; }
.task-row__title { color: var(--mst-text-primary); }
.task-row__agent { color: var(--mst-text-secondary); font-size: var(--mst-fs-meta); }
.task-row__status { color: var(--mst-text-muted); font-size: var(--mst-fs-micro); text-transform: uppercase; }
.task-row__cause {
  grid-column: 2 / -1;
  color: var(--mst-text-muted);
  font-size: var(--mst-fs-meta);
  padding-left: var(--mst-sp-2);
  border-left: 3px solid var(--mst-sem-escalation);
}

/* ---------- Onglet Monitoring (bandes horizontales — J2-5 §6.5) ---------- */

.monitoring {
  display: grid;
  grid-template-columns: 340px 1fr;
  background: var(--mst-bg-app);
  /* Hauteur fixée à 1 viewport (moins l'en-tête + onglets) — les 2 zones
     scrollent indépendamment, plus besoin de descendre la page. */
  height: calc(100vh - 240px);
  overflow: hidden;
  gap: var(--mst-sp-2);
}

.monitoring__chef {
  background: var(--mst-bg-surface);
  border-right: var(--mst-border-w) solid var(--mst-border);
  padding: var(--mst-sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-2);
  border-left: 3px solid var(--mst-accent);
  /* Scroll interne propre à la colonne CHEF */
  overflow-y: auto;
  max-height: 100%;
}
.monitoring__chef-head {
  font-weight: var(--mst-fw-bold);
  font-size: var(--mst-fs-title);
  letter-spacing: 0.5px;
}
.monitoring__chef-meta {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}
.monitoring__chef-stream {
  font-family: var(--mst-font-mono);
  font-size: var(--mst-fs-mono);
  line-height: var(--mst-lh-mono);
  color: var(--mst-text-primary);
  white-space: pre-wrap;
  flex: 1;
}
.monitoring__chef-stream > div { margin: var(--mst-sp-1) 0; }
/* J5-L — entrées et séparateurs du flux chef de projet */
.monitoring__chef-entry { margin: var(--mst-sp-1) 0; }
.monitoring__chef-sep {
  border: none;
  border-top: 1px solid var(--mst-border);
  margin: var(--mst-sp-2) 0;
  opacity: 0.6;
}

.monitoring__agents {
  background: var(--mst-bg-app);
  /* PAS de cartes, PAS de cadres : juste des bandes séparées par filets. */
  /* Scroll interne propre à la colonne AGENTS — indépendant du chef. */
  overflow-y: auto;
  max-height: 100%;
  padding: var(--mst-sp-2);
}

.agent-band {
  padding: var(--mst-sp-3) var(--mst-sp-4);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  /* Régularité PD5 : toujours la même structure */
}
.agent-band:last-child { border-bottom: 0; }

.agent-band__row1 {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-3);
  font-family: var(--mst-font-mono);
  font-size: var(--mst-fs-mono);
  color: var(--mst-text-secondary);
  flex-wrap: wrap;
}
.agent-band__row1 .model { color: var(--mst-text-secondary); }
.agent-band__row1 .perm { color: var(--mst-text-muted); font-size: var(--mst-fs-meta); }
.agent-band__row1 .pulse {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: var(--mst-radius-pill);
}
.agent-band__row1 .pulse[data-state="active"]  { background: var(--mst-sem-launch); }
.agent-band__row1 .pulse[data-state="waiting"] { background: var(--mst-text-muted); }
.agent-band__row1 .pulse[data-state="blocked"] { background: var(--mst-sem-escalation); }
.agent-band__row1 .tag {
  margin-left: auto;
  /* Lot 4 S4a-bis (directive #47) — nom d'agent sur une ligne, modèle réel
     empilé en dessous dans le badge (miroir du panneau STRATEGIST). */
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  padding: 0 var(--mst-sp-2);
  font-family: var(--mst-font-sans);
  font-size: var(--mst-fs-micro);
  font-weight: var(--mst-fw-medium);
  border-left: 3px solid var(--mst-text-primary);
  color: var(--mst-text-primary);
}
.agent-band__row1 .tag__name {
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-1);
}
.agent-band__row1 .tag__model {
  font-family: var(--mst-font-mono, monospace);
  font-weight: var(--mst-fw-regular, normal);
  color: var(--mst-text-muted);
}
.agent-band__row2 {
  font-size: var(--mst-fs-body);
  line-height: var(--mst-lh-body);
  color: var(--mst-text-primary);
  margin-top: var(--mst-sp-1);
}
.agent-band__row2--waiting {
  color: var(--mst-text-muted);
  font-style: italic;
}
.agent-band__row3 {
  font-family: var(--mst-font-mono);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  margin-top: var(--mst-sp-1);
}

/* Live strip — flux des hooks Claude Code (PreToolUse, PostToolUse, …).
   3 lignes max sous chaque bande agent, façon terminal. */
.live-strip {
  margin-top: var(--mst-sp-2);
  padding: var(--mst-sp-1) var(--mst-sp-2);
  background: var(--mst-bg-subtle, #1a1a1a);
  border: 1px solid var(--mst-border);
  border-radius: 4px;
  font-family: var(--mst-font-mono);
  font-size: 11px;
  color: var(--mst-text-secondary);
  max-height: 90px;
  min-height: 72px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Bloque la compression flex quand le parent (.monitoring__chef) scrolle. */
  flex: 0 0 auto;
}
.live-strip:empty::before {
  content: "▸ en attente d'activité…";
  color: var(--mst-text-muted);
  font-style: italic;
}
.live-strip__line {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.live-strip--strategist {
  margin: var(--mst-sp-2) 0;
}

/* Boutons compacts pour barres d'action (paste/joindre/etc.). */
.btn--sm {
  padding: 4px 10px;
  font-size: var(--mst-fs-meta);
}
.btn--ghost {
  background: transparent;
  border: 1px solid var(--mst-border);
  color: var(--mst-text-primary);
}
.btn--ghost:hover {
  background: var(--mst-bg-subtle, rgba(255,255,255,0.05));
}
.field__actions {
  display: flex;
  gap: var(--mst-sp-2);
  align-items: center;
  margin-top: var(--mst-sp-1);
  flex-wrap: wrap;
}

/* Zone de dépôt (drag & drop de pièces jointes). Feedback de survol quand
   des fichiers sont glissés au-dessus — cf. makeDropzone() (components.js). */
.is-dragover {
  outline: 2px dashed var(--mst-accent, #4f8cff);
  outline-offset: 2px;
  background: var(--mst-accent-bg, rgba(79,140,255,0.08));
  border-radius: var(--mst-radius-sm, 6px);
  transition: background 0.12s ease, outline-color 0.12s ease;
}

/* Liste cumulative des pièces jointes — chips supprimables (fileChips(),
   components.js). Chaque chip = un fichier ajouté (par bouton, glisser-déposer
   ou collage) ; cliquer dessus le retire individuellement. */
.file-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mst-sp-2, 8px);
  margin-top: var(--mst-sp-2, 8px);
  width: 100%;
}
.file-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 3px 8px;
  font-size: var(--mst-fs-meta, 12px);
  line-height: 1.4;
  color: var(--mst-text-primary, #e6e6e6);
  background: var(--mst-accent-bg, rgba(79,140,255,0.10));
  border: 1px solid var(--mst-accent, #4f8cff);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.12s ease, opacity 0.12s ease;
}
.file-chip:hover {
  background: var(--mst-sem-error-bg, rgba(255,90,90,0.14));
  border-color: var(--mst-sem-error, #ff5a5a);
}
.file-chip__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 220px;
}
.file-chip__size {
  opacity: 0.6;
  font-variant-numeric: tabular-nums;
}
.file-chip__x {
  font-weight: var(--mst-fw-bold, 700);
  line-height: 1;
  opacity: 0.7;
}
.file-chip:hover .file-chip__x { opacity: 1; color: var(--mst-sem-error, #ff5a5a); }

/* TokenBar */
.tokenbar {
  display: inline-flex;
  align-items: center;
  gap: var(--mst-sp-2);
  font-family: var(--mst-font-mono);
  font-size: var(--mst-fs-mono);
}
.tokenbar__fill { letter-spacing: 0.4px; }
.tokenbar__value { font-weight: var(--mst-fw-medium); }
.tokenbar[data-threshold="calm"]   .tokenbar__fill,
.tokenbar[data-threshold="calm"]   .tokenbar__value { color: var(--mst-tokenbar-calm); }
.tokenbar[data-threshold="warn"]   .tokenbar__fill,
.tokenbar[data-threshold="warn"]   .tokenbar__value { color: var(--mst-tokenbar-warn); }
.tokenbar[data-threshold="danger"] .tokenbar__fill,
.tokenbar[data-threshold="danger"] .tokenbar__value { color: var(--mst-tokenbar-danger); }
.tokenbar[data-threshold="over"]   .tokenbar__fill,
.tokenbar[data-threshold="over"]   .tokenbar__value { color: var(--mst-tokenbar-over); }

/* ---------- Onglet Fichiers ---------- */

.files {
  padding: var(--mst-sp-4) var(--mst-sp-5);
  position: relative;
  min-height: 12rem;          /* une cible de dépôt même quand la liste est vide */
}
.files__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--mst-sp-2);
  margin-bottom: var(--mst-sp-3);
}
.files__depots {
  display: flex;
  gap: var(--mst-sp-2);
}
/* Glisser-déposer (2026-09-12) : la zone n'apparaît que pendant le survol. */
.files__zone-depot { display: none; }
.files--depot .files__zone-depot {
  display: flex;
  position: absolute;
  inset: var(--mst-sp-2);
  z-index: 5;
  align-items: center;
  justify-content: center;
  border: 2px dashed var(--mst-accent);
  border-radius: var(--mst-radius-md);
  background: var(--mst-accent-bg);
  color: var(--mst-text-primary);
  font-size: var(--mst-fs-body);
  font-weight: 600;
  opacity: 0.94;
  pointer-events: none;        /* le dépôt reste reçu par la section */
}
.files__table {
  width: 100%;
  border-collapse: collapse;
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  overflow: hidden;
}
.files__table th,
.files__table td {
  padding: var(--mst-sp-2) var(--mst-sp-3);
  text-align: left;
  font-size: var(--mst-fs-body);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}
.files__table th {
  background: var(--mst-bg-surface-2);
  color: var(--mst-text-secondary);
  font-weight: var(--mst-fw-medium);
  font-size: var(--mst-fs-meta);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.files__table tr:hover td { background: var(--mst-bg-surface-2); }
.files__table .files__actions {
  display: flex;
  gap: var(--mst-sp-1);
  justify-content: flex-end;
}
.icon-btn {
  background: transparent;
  border: var(--mst-border-w) solid var(--mst-border);
  color: var(--mst-text-primary);
  padding: 0 var(--mst-sp-2);
  height: 28px;
  border-radius: var(--mst-radius-sm);
  cursor: pointer;
  font-size: var(--mst-fs-meta);
}
.icon-btn:hover { background: var(--mst-bg-surface-2); }
.icon-btn--danger { color: var(--mst-sem-escalation); border-color: var(--mst-sem-escalation); }

/* Badges source de fichier (mission vs upload opérateur) */
.files__badge {
  display: inline-block;
  padding: 1px var(--mst-sp-1);
  border-radius: var(--mst-radius-sm);
  font-size: var(--mst-fs-meta);
  font-weight: var(--mst-fw-medium);
  letter-spacing: 0.3px;
  vertical-align: middle;
}
.files__badge--mission {
  background: var(--mst-sem-milestone-bg);
  color: var(--mst-sem-milestone);
  border: 1px solid var(--mst-sem-milestone);
}
.files__badge--upload {
  background: var(--mst-sem-task-bg);
  color: var(--mst-sem-task);
  border: 1px solid var(--mst-sem-task);
}

/* Cycle de vie d'un livrable (évolution 2 du 2026-08-07).
   Le badge est pointillé tant que le livrable peut encore bouger : c'est ce
   qui distingue, d'un coup d'œil, ce qu'on peut encore infléchir de ce qui est
   arrêté. Un livrable « final » n'a pas de badge — pas de bruit sur l'état
   normal. */
.files__badge--brouillon,
.files__badge--en_revue,
.files__badge--revise {
  border-style: dashed;
  border-width: 1px;
}
.files__badge--brouillon {
  background: var(--mst-sem-question-bg, transparent);
  color: var(--mst-sem-question, var(--mst-text-secondary));
  border-color: var(--mst-sem-question, var(--mst-border));
}
.files__badge--en_revue {
  background: var(--mst-sem-escalation-bg, transparent);
  color: var(--mst-sem-escalation, var(--mst-text-secondary));
  border-color: var(--mst-sem-escalation, var(--mst-border));
}
.files__badge--revise {
  background: var(--mst-sem-milestone-bg, transparent);
  color: var(--mst-sem-milestone, var(--mst-text-secondary));
  border-color: var(--mst-sem-milestone, var(--mst-border));
}

/* Dialogue de remarque + historique des versions */
.modal--remarque .remarque__corps,
.modal--remarque .remarque__cible {
  width: 100%;
  margin-top: var(--mst-sp-2);
  padding: var(--mst-sp-2);
  background: var(--mst-bg-surface-2);
  color: var(--mst-text-primary);
  border: 1px solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  font-family: inherit;
  font-size: var(--mst-fs-body);
}
.modal--remarque .remarque__bloquante {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-1);
  margin-top: var(--mst-sp-2);
  font-size: var(--mst-fs-meta);
}
.modal__hint {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  margin: var(--mst-sp-1) 0 0;
}
.modal__hint--warn { color: var(--mst-sem-escalation, var(--mst-text-secondary)); }

.modal--versions .versions__corps {
  max-height: 50vh;
  overflow-y: auto;
  margin-top: var(--mst-sp-2);
}
.versions__ligne {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mst-sp-2);
  align-items: baseline;
  padding: var(--mst-sp-1) 0;
  border-bottom: 1px solid var(--mst-border);
  font-size: var(--mst-fs-meta);
}
.versions__num { font-weight: var(--mst-fw-medium); min-width: 2.5em; }
.versions__jalon { color: var(--mst-text-primary); }
.versions__date, .versions__auteur { color: var(--mst-text-secondary); }
.versions__cause {
  flex-basis: 100%;
  color: var(--mst-sem-escalation, var(--mst-text-secondary));
}

/* ---------- Onglet Branches (évolutions 1 et 3 du 2026-08-07) ----------
   Ce qu'il doit rendre lisible d'un coup d'œil : ce qui avance EN MÊME TEMPS,
   ce qui attend quoi, et ce qui se passe ENTRE les agents. */
.branches__header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--mst-sp-2);
  margin-bottom: var(--mst-sp-3);
}
.branches__hint,
.branches__resume {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}
.branches__resume { margin-bottom: var(--mst-sp-2); }

.branche {
  padding: var(--mst-sp-2);
  margin-bottom: var(--mst-sp-2);
  background: var(--mst-bg-surface-1);
  border: 1px solid var(--mst-border);
  border-left: 3px solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
}
/* Seules les branches qui DEMANDENT quelque chose se signalent : une unité
   qui avance normalement n'a pas à attirer l'œil. */
.branche--en-cours   { border-left-color: var(--mst-sem-task, var(--mst-border)); }
.branche--validée    { border-left-color: var(--mst-sem-milestone, var(--mst-border)); }
.branche--suspendue,
.branche--bloquée    { border-left-color: var(--mst-sem-escalation, var(--mst-border)); }

.branche__tete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--mst-sp-2);
}
.branche__pastille { font-size: 1.1em; }
.branche__titre { flex: 1 1 auto; }
.branche__critique {
  padding: 1px var(--mst-sp-1);
  border: 1px solid var(--mst-sem-escalation, var(--mst-border));
  border-radius: var(--mst-radius-sm);
  color: var(--mst-sem-escalation, var(--mst-text-secondary));
  font-size: var(--mst-fs-meta);
}
.branche__instance,
.branche__etat,
.branche__deps,
.branche__perimetre,
.branche__livrables {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}
.branche__deps,
.branche__perimetre,
.branche__livrables { margin-top: var(--mst-sp-1); }

.branche__chaine {
  margin: var(--mst-sp-2) 0 0;
  padding-left: var(--mst-sp-3);
  border-left: 1px dashed var(--mst-border);
  list-style: none;
}
.chaine__pas {
  display: flex;
  gap: var(--mst-sp-2);
  padding: 2px 0;
  font-size: var(--mst-fs-meta);
}
.chaine__heure { color: var(--mst-text-secondary); font-variant-numeric: tabular-nums; }
.chaine__pas--error_routed .chaine__texte,
.chaine__pas--escalated .chaine__texte {
  color: var(--mst-sem-escalation, var(--mst-text-primary));
}
.chaine__pas--milestone_detected .chaine__texte,
.chaine__pas--control_assigned .chaine__texte {
  color: var(--mst-sem-milestone, var(--mst-text-primary));
}

/* Légende source */
.files__legend {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-1);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}

/* Highlight temporaire d'une ligne de fichier (naviguée depuis Messages) */
@keyframes files-row-highlight {
  0%   { background: var(--mst-sem-milestone-bg); }
  100% { background: transparent; }
}
.files__row--highlight td {
  animation: files-row-highlight 2s ease-out forwards;
}

/* Intertitre de groupe dans la liste des fichiers.
   « À lire » d'abord, le reste ensuite — cf. `lignesDeFichiers` dans
   mission.js. Discret : c'est un repère, pas un titre de section. */
.files__groupe td {
  padding-top: var(--mst-sp-3);
  color: var(--mst-text-muted);
  font-size: var(--mst-fs-meta);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}
.files__groupe:first-child td { padding-top: 0; }

/* Un document que Roméo doit ouvrir : son nom porte le poids, pas une
   couleur de fond — la ligne reste lisible quel que soit le thème. */
.files__row--livrable .files__cell--name {
  font-weight: 600;
}

/* ---------- Modale de prévisualisation de fichier ---------- */

.file-preview-overlay .modal {
  max-width: 860px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

.file-preview__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--mst-sp-3) var(--mst-sp-5);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  background: var(--mst-bg-surface-2);
  gap: var(--mst-sp-3);
  flex-shrink: 0;
}

.file-preview__name {
  font-weight: var(--mst-fw-medium);
  font-size: var(--mst-fs-body);
  color: var(--mst-text-primary);
  word-break: break-all;
  flex: 1;
}

.file-preview__header-actions {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  flex-shrink: 0;
}

.file-preview__body {
  overflow: auto;
  flex: 1;
  padding: var(--mst-sp-5);
}

.file-preview__loading {
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-body);
  text-align: center;
  padding: var(--mst-sp-5);
}

/* Rendu Markdown */
.file-preview__markdown {
  font-size: var(--mst-fs-body);
  line-height: 1.65;
  color: var(--mst-text-primary);
}
.file-preview__markdown h1,
.file-preview__markdown .file-preview__h1 { font-size: 1.5em; margin: 0.75em 0 0.4em; border-bottom: var(--mst-border-w) solid var(--mst-border); padding-bottom: 0.2em; }
.file-preview__markdown h2,
.file-preview__markdown .file-preview__h2 { font-size: 1.25em; margin: 0.75em 0 0.3em; }
.file-preview__markdown h3,
.file-preview__markdown .file-preview__h3 { font-size: 1.1em; margin: 0.6em 0 0.25em; }
.file-preview__markdown h4,
.file-preview__markdown .file-preview__h4,
.file-preview__markdown h5,
.file-preview__markdown .file-preview__h5,
.file-preview__markdown h6,
.file-preview__markdown .file-preview__h6 { font-size: 1em; margin: 0.5em 0 0.2em; }
.file-preview__markdown .file-preview__p { margin: 0 0 0.5em; }
.file-preview__markdown ul,
.file-preview__markdown ol { margin: 0.4em 0 0.4em 1.6em; }
.file-preview__markdown li { margin-bottom: 0.2em; }
.file-preview__markdown hr { border: none; border-top: var(--mst-border-w) solid var(--mst-border); margin: 1em 0; }
.file-preview__markdown a { color: var(--mst-accent); }

/* Bloc de code dans le rendu Markdown ou texte brut */
.file-preview__code {
  background: var(--mst-bg-surface-2);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-3) var(--mst-sp-4);
  overflow-x: auto;
  white-space: pre;
  font-size: var(--mst-fs-meta);
  font-family: var(--mst-font-mono, ui-monospace, "Cascadia Code", "Fira Code", monospace);
  line-height: 1.5;
  color: var(--mst-text-primary);
  margin: var(--mst-sp-2) 0;
}
.file-preview__inline-code {
  font-family: var(--mst-font-mono, ui-monospace, monospace);
  font-size: 0.88em;
  background: var(--mst-bg-surface-2);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: 0 3px;
}

/* Image */
.file-preview__image-wrap {
  display: flex;
  justify-content: center;
  padding: var(--mst-sp-2);
}
.file-preview__image {
  max-width: 100%;
  max-height: 70vh;
  border-radius: var(--mst-radius-sm);
  object-fit: contain;
}

/* Bureautique (.xlsx/.docx/.pptx/.csv) — rendu HTML backend (T7) */
.file-preview__office {
  padding: var(--mst-sp-2) var(--mst-sp-3);
  overflow-x: auto;
}
.file-preview__sheet-title {
  font-size: 1.05em;
  margin: var(--mst-sp-4) 0 var(--mst-sp-2);
  padding-bottom: 0.2em;
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}
.file-preview__sheet-title:first-child { margin-top: 0; }
.file-preview__table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--mst-sp-4);
  font-size: 0.92em;
}
.file-preview__table th,
.file-preview__table td {
  border: var(--mst-border-w) solid var(--mst-border);
  padding: var(--mst-sp-1, 4px) var(--mst-sp-2);
  text-align: left;
  vertical-align: top;
}
.file-preview__table th {
  background: var(--mst-bg-surface-2);
  font-weight: 600;
}
.file-preview__slide-lines {
  margin: 0 0 var(--mst-sp-4) 1.4em;
}
.file-preview__slide-lines li { margin-bottom: 0.2em; }
.file-preview__p--muted { color: var(--mst-text-secondary); font-style: italic; }
.file-preview__truncated { margin-top: var(--mst-sp-3); }

/* Binaire non prévisualisable */
.file-preview__unavailable {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--mst-sp-4);
  padding: var(--mst-sp-6);
  color: var(--mst-text-secondary);
  text-align: center;
}

/* ---------- Vue Rôles du dashboard ---------- */

.roles-view {
  padding: var(--mst-sp-4) var(--mst-sp-5);
}

.roles-view__header {
  margin-bottom: var(--mst-sp-4);
}

.roles-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--mst-sp-3);
  margin-top: var(--mst-sp-3);
}

.role-card {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-3) var(--mst-sp-4);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.role-card:hover {
  background: var(--mst-bg-surface-2);
  border-color: var(--mst-accent);
}
.role-card__name {
  font-weight: var(--mst-fw-medium);
  font-size: var(--mst-fs-body);
  color: var(--mst-text-primary);
  margin-bottom: var(--mst-sp-1);
}
.role-card__meta {
  display: flex;
  gap: var(--mst-sp-2);
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: var(--mst-sp-2);
}
.role-card__kind {
  font-size: var(--mst-fs-meta);
  padding: 1px var(--mst-sp-1);
  border-radius: var(--mst-radius-sm);
  font-weight: var(--mst-fw-medium);
}
.role-card__kind--core {
  background: var(--mst-sem-launch-bg);
  color: var(--mst-sem-launch);
  border: 1px solid var(--mst-sem-launch);
}
.role-card__kind--recruited {
  background: var(--mst-sem-phase-bg);
  color: var(--mst-sem-phase);
  border: 1px solid var(--mst-sem-phase);
}
.role-card__model {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  font-family: var(--mst-font-mono, monospace);
}
.role-card__summary {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Carte de rôle cliquable — onglet Rôles d'une mission. */
.role-card--clickable { cursor: pointer; transition: border-color 0.15s, transform 0.1s; }
.role-card--clickable:hover { border-color: var(--mst-accent, var(--mst-text-primary)); }
.role-card--clickable:active { transform: scale(0.995); }
.role-card--clickable:focus-visible {
  outline: 2px solid var(--mst-accent, var(--mst-text-primary));
  outline-offset: 2px;
}
/* Le nom d'un expert recruté peut rester long malgré le plafond côté moteur :
   il se replie plutôt que de pousser le bouton de fermeture hors du cadre. */
.role-detail__title {
  font-weight: 600;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Modale de carte de rôle */
.role-detail__modal {
  max-width: 720px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}
.role-detail__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--mst-sp-3) var(--mst-sp-5);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  background: var(--mst-bg-surface-2);
  gap: var(--mst-sp-3);
  flex-shrink: 0;
}
.role-detail__body {
  /* Défilement VERTICAL uniquement. Une carte de rôle est de la prose : la
     lire en zigzag (haut→bas ET gauche→droite) la rend impraticable. Le
     `white-space: pre` de `.file-preview__code` est légitime pour un aperçu de
     code source — où replier une ligne falsifierait l'indentation — mais pas
     ici, où les blocs sont des schémas JSON noyés dans du texte. On neutralise
     donc ce comportement DANS CETTE MODALE seulement. */
  overflow-x: hidden;
  overflow-y: auto;
  overflow-wrap: anywhere;
  flex: 1;
  padding: var(--mst-sp-5);
}
.role-detail__body .file-preview__code {
  white-space: pre-wrap;
  overflow-x: hidden;
  word-break: break-word;
}
.role-detail__body .file-preview__inline-code { overflow-wrap: anywhere; }

/* Lien « voir dans Fichiers » dans les messages LIVRAISON */
.message__delivery-link {
  display: inline-block;
  margin-top: var(--mst-sp-1);
  margin-left: 0;
  padding: 2px var(--mst-sp-2);
  background: var(--mst-sem-milestone-bg);
  color: var(--mst-sem-milestone);
  border: 1px solid var(--mst-sem-milestone);
  border-radius: var(--mst-radius-sm);
  font-size: var(--mst-fs-meta);
  cursor: pointer;
  transition: opacity 0.15s;
}
.message__delivery-link:hover { opacity: 0.8; }

/* ---------- Administration ---------- */

.admin {
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-4);
}
.admin__panel {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-5);
}
.admin__panel h2 { margin: 0 0 var(--mst-sp-3) 0; font-size: var(--mst-fs-title); }
.admin__row {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-3);
}
/* Inputs des panels admin — fond blanc, texte foncé pour la lisibilité.
   Sans ça l'opérateur ne voyait pas son nom (texte clair sur fond clair). */
.admin__panel input[type="text"],
.admin__panel input[type="number"],
.admin__panel input:not([type]) {
  color: #111;
  background: #fff;
  border: 1px solid var(--mst-border);
  padding: 8px 10px;
  border-radius: 4px;
  font-size: var(--mst-fs-body);
  min-width: 200px;
}
.admin__panel input::placeholder { color: #888; }

/* Compteurs tokens — mission card + header de page mission. */
.mission-card__tokens {
  font-family: var(--mst-font-mono);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  border: 1px solid var(--mst-border);
  padding: 1px 6px;
  border-radius: 8px;
  background: rgba(255,255,255,0.03);
}
.mission-header__tokens {
  margin-left: var(--mst-sp-3);
  font-family: var(--mst-font-mono);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  border: 1px solid var(--mst-border);
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(255,255,255,0.03);
}
.mission-header__cost {
  margin-left: var(--mst-sp-2);
  font-family: var(--mst-font-mono);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  border: 1px solid var(--mst-border);
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(255,255,255,0.03);
}

/* Séparateur de date dans Messages / Monitoring / Tâches —
   utile pour les missions multi-jours. */
.date-separator {
  display: flex;
  align-items: center;
  margin: var(--mst-sp-3) 0;
  text-transform: capitalize;
}
.date-separator::before,
.date-separator::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--mst-border);
}
.date-separator__label {
  padding: 0 var(--mst-sp-3);
  font-size: var(--mst-fs-meta);
  font-weight: var(--mst-fw-bold);
  color: var(--mst-text-secondary);
  letter-spacing: 0.3px;
}
.pairing-code {
  font-family: var(--mst-font-mono);
  font-size: 28px;
  letter-spacing: 6px;
  color: var(--mst-accent);
  background: var(--mst-bg-inset);
  padding: var(--mst-sp-3) var(--mst-sp-5);
  border-radius: var(--mst-radius-md);
  border: var(--mst-border-w) solid var(--mst-border);
  display: inline-block;
}
.pairing-ttl { color: var(--mst-text-secondary); margin-left: var(--mst-sp-3); font-family: var(--mst-font-mono); }
.pairing-ttl[data-warn="true"] { color: var(--mst-tokenbar-warn); }
.devices-table { width: 100%; border-collapse: collapse; }
.devices-table th, .devices-table td {
  padding: var(--mst-sp-2);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  text-align: left;
  font-size: var(--mst-fs-body);
}
.devices-table th { color: var(--mst-text-secondary); font-size: var(--mst-fs-meta); }
.devices-table__ip { font-family: var(--mst-font-mono, ui-monospace, monospace); }
.devices-table__soi { color: var(--mst-accent); font-size: var(--mst-fs-meta); }
.toggle-switch {
  position: relative;
  width: 44px; height: 24px;
  background: var(--mst-border);
  border-radius: var(--mst-radius-pill);
  cursor: pointer;
  transition: background var(--mst-motion-fast) var(--mst-easing);
}
.toggle-switch[data-state="remote"] { background: var(--mst-net-remote); }
.toggle-switch::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 18px; height: 18px;
  background: var(--mst-text-primary);
  border-radius: var(--mst-radius-pill);
  transition: left var(--mst-motion-fast) var(--mst-easing);
}
.toggle-switch[data-state="remote"]::after { left: 23px; }

/* ---------- Utilitaires ---------- */

.empty {
  padding: var(--mst-sp-6);
  text-align: center;
  color: var(--mst-text-muted);
  font-style: italic;
}

.notice {
  padding: var(--mst-sp-2) var(--mst-sp-3);
  border-radius: var(--mst-radius-sm);
  font-size: var(--mst-fs-meta);
  margin-bottom: var(--mst-sp-3);
}
.notice--info  { background: var(--mst-accent-bg); color: var(--mst-text-primary); }
.notice--warn  { background: var(--mst-sem-arbitration-bg); color: var(--mst-sem-arbitration); }
.notice--error { background: var(--mst-sem-escalation-bg); color: var(--mst-sem-escalation); }

.hidden { display: none !important; }

.toast {
  position: fixed;
  bottom: var(--mst-sp-5);
  right: var(--mst-sp-5);
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-left: 3px solid var(--mst-accent);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-3) var(--mst-sp-4);
  font-size: var(--mst-fs-body);
  box-shadow: var(--mst-elevation-modal);
  z-index: 200;
  max-width: 400px;
}
.toast[data-kind="error"] { border-left-color: var(--mst-sem-escalation); }
.toast[data-kind="success"] { border-left-color: var(--mst-state-done); }

/* ---------- J5-C — Bannière persistante "checkpoint humain" ---------- */
/*
 * Affichée quand la session est en AWAITING_HUMAN. Persiste à travers les
 * 4 onglets de la page de mission (Messages, Tâches, Monitoring, Fichiers)
 * et survit au F5 (l'état AWAITING_HUMAN est en base, pas en mémoire).
 * Couleur sémantique ambre (token arbitration) — cohérente avec la dot de
 * l'en-tête, le filtre escalation et la palette Android.
 *
 * Choix d'implementation : in-flow (pas une modale), placée juste sous
 * l'en-tête de mission. Une modale capturerait le focus et bloquerait la
 * navigation entre onglets — ce qu'on veut éviter (l'opérateur peut
 * vouloir regarder le journal ou les fichiers avant de répondre).
 */
.mission-banner {
  background: var(--mst-sem-arbitration-bg);
  border: var(--mst-border-w) solid var(--mst-sem-arbitration);
  border-left-width: 4px;
  border-radius: var(--mst-radius-sm);
  margin: var(--mst-sp-3) var(--mst-sp-5) 0;
  padding: var(--mst-sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-3);
}
.mission-banner__header {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  font-weight: 600;
  color: var(--mst-sem-arbitration);
  font-size: var(--mst-fs-title);
}
.mission-banner__icon {
  font-size: 18px;
}
.mission-banner__title { flex: 1; }
.mission-banner__waited {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  font-weight: 400;
}
.mission-banner__question {
  color: var(--mst-text-primary);
  font-size: var(--mst-fs-body);
  white-space: pre-wrap;
  line-height: 1.4;
}
/* La porte en deux étages (2026-11-10) : la tête se lit, les détails se déplient. */
.mission-banner__details {
  margin-top: 12px;
  border-top: 1px solid var(--mst-border, rgba(127, 127, 127, 0.3));
  padding-top: 8px;
}
.mission-banner__details > summary {
  cursor: pointer;
  color: var(--mst-text-secondary, inherit);
  font-size: var(--mst-fs-meta);
}
.mission-banner__details-texte {
  margin-top: 8px;
  max-height: 60vh;
  overflow: auto;
  overflow-wrap: anywhere;
}
.mission-banner__form {
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-2);
}
.mission-banner__textarea {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-2) var(--mst-sp-3);
  font-family: inherit;
  font-size: var(--mst-fs-body);
  color: var(--mst-text-primary);
  min-height: 80px;
  resize: vertical;
}
.mission-banner__textarea:focus {
  outline: none;
  border-color: var(--mst-sem-arbitration);
}
.mission-banner__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--mst-sp-2);
}
.mission-banner__submit {
  background: var(--mst-sem-arbitration);
  color: var(--mst-text-on-accent);
  border: 0;
  padding: var(--mst-sp-2) var(--mst-sp-4);
  border-radius: var(--mst-radius-sm);
  font-weight: 600;
  cursor: pointer;
}
.mission-banner__submit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.mission-banner__hint {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}

/* Bannière STOPPED contextuelle (max-turns / rate-limit / abort) avec
   bouton « Continuer ». Style proche de mission-banner mais ton neutre. */
.mission-banner-stopped {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-left: 3px solid var(--mst-accent);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-3) var(--mst-sp-4);
  margin: var(--mst-sp-3) 0;
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-2);
}
.mission-banner-stopped[data-key="abort"]      { border-left-color: var(--mst-sem-escalation, #c33); }
.mission-banner-stopped[data-key="rate-limit"] { border-left-color: var(--mst-sem-arbitration, #d99500); }
.mission-banner-stopped[data-key="max-turns"]  { border-left-color: var(--mst-accent, #4a90e2); }
.mission-banner-stopped__head {
  display: flex; align-items: center; gap: var(--mst-sp-2);
  font-weight: var(--mst-fw-bold);
  font-size: var(--mst-fs-title);
}
.mission-banner-stopped__icon { font-size: 18px; }
.mission-banner-stopped__msg {
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-body);
  line-height: 1.45;
}
.mission-banner-stopped__actions {
  display: flex; gap: var(--mst-sp-2); justify-content: flex-end;
}
.mission-banner-stopped__cta {
  background: var(--mst-accent, #4a90e2);
  color: white;
  border: 0;
  padding: 6px 14px;
  border-radius: var(--mst-radius-sm);
  font-size: var(--mst-fs-body);
  font-weight: var(--mst-fw-bold);
  cursor: pointer;
}
.mission-banner-stopped__cta:hover:not(:disabled) { filter: brightness(1.1); }
.mission-banner-stopped__cta:disabled { opacity: 0.6; cursor: wait; }

/* J5-I — Bannière permanente "mode En direct avec les agents".
 * Style discret (info) — différent de mission-banner (alerte ambre).
 * Bordure bleue/secondaire, fond léger, plus compact. */
.mission-banner-attached {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-left: 3px solid var(--mst-accent);
  border-radius: var(--mst-radius-sm);
  margin: var(--mst-sp-3) var(--mst-sp-5) 0;
  padding: var(--mst-sp-3) var(--mst-sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-2);
}
.mission-banner-attached__header {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  font-size: var(--mst-fs-body);
}
.mission-banner-attached__icon {
  color: var(--mst-accent);
  font-size: 10px;
}
.mission-banner-attached__title {
  flex: 1;
  color: var(--mst-text-primary);
}
.mission-banner-attached__toggle {
  background: transparent;
  border: var(--mst-border-w) solid var(--mst-border);
  color: var(--mst-text-primary);
  padding: 4px 10px;
  border-radius: var(--mst-radius-sm);
  cursor: pointer;
  font-size: var(--mst-fs-meta);
}
.mission-banner-attached__toggle:hover {
  background: var(--mst-bg-elev);
}
.mission-banner-attached__form {
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-2);
}
.mission-banner-attached__actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--mst-sp-2);
}
.mission-banner-attached__submit {
  background: var(--mst-accent);
  color: var(--mst-text-on-accent);
  border: 0;
  padding: var(--mst-sp-2) var(--mst-sp-4);
  border-radius: var(--mst-radius-sm);
  font-weight: 600;
  cursor: pointer;
}
.mission-banner-attached__submit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Badge sur les cartes de mission du dashboard (R1) — point ambre +
 * libellé "en attente" — réutilise la dot existante mais ajoute un
 * indicateur de priorité visuel. */
.mission-card[data-attention="awaiting_human"] {
  border-left: 3px solid var(--mst-sem-arbitration);
}
.mission-card__attention {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  background: var(--mst-sem-arbitration-bg);
  color: var(--mst-sem-arbitration);
  border-radius: var(--mst-radius-pill);
  font-size: var(--mst-fs-meta);
  font-weight: 600;
}

/* ---- Onglet Rôles (page mission) ---------------------------------------- */
.roles-tab {
  padding: 20px 24px;
}
.roles-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.role-card {
  background: var(--mst-bg-card, #1c1f24);
  border: 1px solid var(--mst-border, #2a2f36);
  border-radius: var(--mst-radius, 8px);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.role-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.role-card__title {
  font-weight: 600;
  font-size: var(--mst-fs-body, 14px);
  color: var(--mst-text, #e6e8eb);
}
.role-card__role {
  font-size: var(--mst-fs-meta, 12px);
  color: var(--mst-text-secondary, #a0a4ab);
  font-style: italic;
}
.role-card__summary {
  font-size: var(--mst-fs-meta, 12px);
  color: var(--mst-text-secondary, #a0a4ab);
  line-height: 1.4;
}
.role-card__meta {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 12px;
  font-size: var(--mst-fs-meta, 12px);
  margin: 8px 0 0 0;
}
.role-card__meta dt { color: var(--mst-text-secondary, #a0a4ab); }
.role-card__meta dd { margin: 0; color: var(--mst-text, #e6e8eb); }
.role-kind-badge {
  display: inline-block;
  padding: 2px 8px;
  border: 1px solid currentColor;
  border-radius: var(--mst-radius-pill, 999px);
  font-size: var(--mst-fs-meta, 12px);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.role-kind--decisional { color: #f5c542; }
.role-kind--routine    { color: #4a90e2; }
.role-kind--reviewer   { color: #66bb6a; }
.role-kind--expert     { color: #ab47bc; }

/* ---- T2 — Pensée vive diffusée : chevron + overlay full ---------------- */
.transcript-full__toggle {
  margin-left: 8px;
  padding: 0 6px;
  background: transparent;
  border: 1px solid var(--mst-border, #2a2f36);
  border-radius: var(--mst-radius-pill, 999px);
  color: var(--mst-text-secondary, #a0a4ab);
  font-size: var(--mst-fs-meta, 11px);
  cursor: pointer;
}
.transcript-full__toggle:hover {
  color: var(--mst-text, #e6e8eb);
  border-color: var(--mst-text-secondary, #a0a4ab);
}
.transcript-full__overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px;
  z-index: 1000;
  overflow-y: auto;
}
.transcript-full__body {
  background: var(--mst-bg-card, #1c1f24);
  border: 1px solid var(--mst-border, #2a2f36);
  border-radius: var(--mst-radius, 8px);
  width: 90%;
  max-width: 900px;
  max-height: 90vh;
  overflow-y: auto;
  padding: 0;
}
.transcript-full__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--mst-border, #2a2f36);
  position: sticky;
  top: 0;
  background: var(--mst-bg-card, #1c1f24);
  z-index: 1;
}
.transcript-full__ts {
  margin-left: auto;
  color: var(--mst-text-secondary, #a0a4ab);
  font-size: var(--mst-fs-meta, 12px);
}
.transcript-full__close {
  background: transparent;
  border: none;
  color: var(--mst-text-secondary, #a0a4ab);
  font-size: 18px;
  cursor: pointer;
  padding: 4px 8px;
}
.transcript-full__close:hover { color: var(--mst-text, #e6e8eb); }
.transcript-full__block {
  padding: 12px 20px;
  border-bottom: 1px solid var(--mst-border, #2a2f36);
}
.transcript-full__block:last-child { border-bottom: none; }
.transcript-full__block--thinking { background: rgba(245, 197, 66, 0.04); }
.transcript-full__block--text { background: rgba(74, 144, 226, 0.04); }
.transcript-full__label {
  font-size: var(--mst-fs-meta, 12px);
  color: var(--mst-text-secondary, #a0a4ab);
  margin-bottom: 6px;
  font-weight: 600;
}
.transcript-full__text {
  margin: 0;
  font-family: var(--mst-font-mono, ui-monospace, "Consolas", monospace);
  font-size: var(--mst-fs-body, 13px);
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--mst-text, #e6e8eb);
  line-height: 1.5;
}

/* ---- UX Phase 2 : D1 Pari, D2 Live view (ex-Cellule de crise), D5/D7/D8 ---- */

/* --- D1 Pari --- */
.pari-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.6);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 40px; z-index: 1000; overflow-y: auto;
}
.pari-body {
  background: var(--mst-bg-card, #1c1f24);
  border: 1px solid var(--mst-border, #2a2f36);
  border-radius: var(--mst-radius, 8px);
  width: 90%; max-width: 700px; padding: 0;
}
.pari-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 24px; border-bottom: 1px solid var(--mst-border, #2a2f36);
  position: sticky; top: 0; background: var(--mst-bg-card, #1c1f24); z-index: 1;
}
.pari-title { margin: 0; font-size: var(--mst-fs-h3, 18px); color: var(--mst-text, #e6e8eb); }
.pari-close {
  background: transparent; border: none; color: var(--mst-text-secondary, #a0a4ab);
  font-size: 18px; cursor: pointer; padding: 4px 8px;
}
.pari-section { padding: 16px 24px; border-bottom: 1px solid var(--mst-border, #2a2f36); }
.pari-section h3 { margin: 0 0 8px; font-size: var(--mst-fs-meta, 12px); color: var(--mst-text-secondary, #a0a4ab); text-transform: uppercase; letter-spacing: 0.04em; }
.pari-summary { margin: 0; color: var(--mst-text, #e6e8eb); line-height: 1.5; }
.pari-budget { margin: 0; font-family: var(--mst-font-mono, monospace); color: var(--mst-text, #e6e8eb); }
.pari-deliv { margin: 0; padding-left: 20px; }
.pari-deliv li { margin: 4px 0; }
.pari-tier {
  display: inline-block; padding: 2px 10px;
  border-radius: var(--mst-radius-pill, 999px); font-weight: 600;
  border: 1px solid currentColor;
}
.pari-tier--T0 { color: #f57c5a; }
.pari-tier--T1 { color: #4a90e2; }
.pari-tier--T2 { color: #66bb6a; }
.pari-tier--T3 { color: #f5c542; }
.pari-sign { background: rgba(74, 144, 226, 0.04); }
.pari-sign__strategist { margin: 8px 0 0; font-size: var(--mst-fs-meta, 12px); color: var(--mst-text-secondary, #a0a4ab); }
.pari-empty { padding: 24px; }
.pari-empty__hint { font-size: var(--mst-fs-meta, 12px); color: var(--mst-text-secondary, #a0a4ab); }
.pari-editor { padding: 16px 24px; }
.pari-editor summary { cursor: pointer; color: var(--mst-text-secondary, #a0a4ab); margin-bottom: 12px; }
.pari-form { display: flex; flex-direction: column; gap: 8px; }
.pari-form label { display: flex; flex-direction: column; gap: 4px; font-size: var(--mst-fs-meta, 12px); color: var(--mst-text-secondary, #a0a4ab); }
.pari-form textarea, .pari-form input, .pari-form select {
  background: var(--mst-bg, #0f1115); color: var(--mst-text, #e6e8eb);
  border: 1px solid var(--mst-border, #2a2f36); border-radius: 4px; padding: 6px 10px;
  font-family: inherit;
}
.pari-save { padding: 8px 16px; background: var(--mst-accent, #4a90e2); color: white; border: none; border-radius: 4px; cursor: pointer; align-self: flex-end; }
.pari-error { padding: 24px; color: #f5c542; }

/* --- D2 Live view (ex-« Cellule de crise ») --- */
.crisis-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.85);
  display: flex; flex-direction: column; z-index: 1100; padding: 0;
}
.crisis-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 24px; border-bottom: 1px solid var(--mst-border, #2a2f36);
  background: var(--mst-bg-card, #1c1f24);
}
.crisis-head h2 { margin: 0; color: var(--mst-text, #e6e8eb); font-size: var(--mst-fs-h3, 18px); }
.crisis-close {
  background: transparent; border: none; color: var(--mst-text-secondary, #a0a4ab);
  font-size: 20px; cursor: pointer; padding: 4px 12px;
}
.crisis-list {
  flex: 1; overflow-y: auto; padding: 16px 24px;
  display: flex; flex-direction: column; gap: 12px;
  background: var(--mst-bg, #0f1115);
}
.crisis-block {
  border: 1px solid var(--mst-border, #2a2f36);
  border-radius: var(--mst-radius, 8px);
  padding: 12px 16px;
}
.crisis-block--thinking { background: rgba(245, 197, 66, 0.06); border-color: rgba(245, 197, 66, 0.3); }
.crisis-block--text { background: rgba(74, 144, 226, 0.06); border-color: rgba(74, 144, 226, 0.3); }
.crisis-block__head { display: flex; gap: 12px; align-items: baseline; margin-bottom: 8px; font-size: var(--mst-fs-meta, 12px); }
.crisis-block__type { color: var(--mst-text-secondary, #a0a4ab); }
.crisis-block__ts { margin-left: auto; color: var(--mst-text-secondary, #a0a4ab); }
.crisis-block__text { margin: 0; font-family: var(--mst-font-mono, monospace); white-space: pre-wrap; word-break: break-word; color: var(--mst-text, #e6e8eb); line-height: 1.5; font-size: var(--mst-fs-body, 13px); }
.crisis-block__trunc { margin-top: 6px; font-size: var(--mst-fs-meta, 11px); color: var(--mst-text-secondary, #a0a4ab); font-style: italic; }
.crisis-error { padding: 16px; color: #f57c5a; text-align: center; }

/* --- D7 Sablier --- */
.sablier {
  display: flex; gap: 16px; align-items: center;
  padding: 6px 12px; background: var(--mst-bg-card, #1c1f24);
  border: 1px solid var(--mst-border, #2a2f36); border-radius: var(--mst-radius-pill, 999px);
  font-size: var(--mst-fs-meta, 12px);
}
.sablier__mission, .sablier__quota { display: flex; gap: 6px; align-items: center; }
.sablier__label { color: var(--mst-text-secondary, #a0a4ab); }
.sablier__value { color: var(--mst-text, #e6e8eb); font-family: var(--mst-font-mono, monospace); }
.sablier__quota--warn .sablier__value { color: #f5c542; }
.sablier__quota--critical .sablier__value { color: #f57c5a; font-weight: 600; }
.sablier__error { color: #f57c5a; font-style: italic; }

/* --- T11 Bouton dictée --- */
.btn--icon {
  padding: 4px 8px;
  background: transparent;
  border: 1px solid var(--mst-border, #2a2f36);
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}
.btn--icon:hover { background: var(--mst-bg, #0f1115); }
.btn--recording {
  color: #f57c5a;
  border-color: #f57c5a;
  animation: pulse-recording 1.2s ease-in-out infinite;
}
@keyframes pulse-recording {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245, 124, 90, 0.4); }
  50% { box-shadow: 0 0 0 6px rgba(245, 124, 90, 0); }
}

/* --- Onglet Live view (ex-« Cellule de crise »), T2 in-page --- */
/* --- D3 Replay narré --- */
.narrative-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.6);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 40px; z-index: 1000; overflow-y: auto;
}
.narrative-body {
  background: var(--mst-bg-card, #1c1f24);
  border: 1px solid var(--mst-border, #2a2f36); border-radius: var(--mst-radius, 8px);
  width: 90%; max-width: 800px; padding: 0;
}
.narrative-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; border-bottom: 1px solid var(--mst-border, #2a2f36); position: sticky; top: 0; background: var(--mst-bg-card, #1c1f24); z-index: 1; }
.narrative-head h2 { margin: 0; font-size: var(--mst-fs-h3, 18px); color: var(--mst-text, #e6e8eb); }
.narrative-actions { display: flex; gap: 8px; }
.narrative-actions button { background: transparent; border: 1px solid var(--mst-border, #2a2f36); border-radius: 4px; padding: 4px 12px; color: var(--mst-text, #e6e8eb); cursor: pointer; font-size: var(--mst-fs-meta, 12px); }
.narrative-actions button:hover { background: var(--mst-bg, #0f1115); }
.narrative-speak--playing { color: #f57c5a; border-color: #f57c5a; }
.narrative-loading, .narrative-prompt, .narrative-error { padding: 24px; color: var(--mst-text-secondary, #a0a4ab); }
.narrative-prompt p { margin: 0 0 12px; }
.narrative-prompt__cost { font-size: var(--mst-fs-meta, 12px); }
.narrative-go { padding: 8px 20px; background: var(--mst-accent, #4a90e2); color: white; border: none; border-radius: 4px; cursor: pointer; }
.narrative-cache-badge { padding: 8px 24px; background: rgba(102, 187, 106, 0.06); color: #66bb6a; font-size: var(--mst-fs-meta, 11px); border-bottom: 1px solid var(--mst-border, #2a2f36); }
.narrative-text { padding: 24px; color: var(--mst-text, #e6e8eb); line-height: 1.7; white-space: pre-wrap; word-break: break-word; font-size: var(--mst-fs-body, 14px); }
.narrative-text h2 { margin-top: 24px; font-size: var(--mst-fs-h3, 16px); color: var(--mst-text, #e6e8eb); }

/* --- D5 Constellation --- */
.constellation-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.6);
  display: flex; align-items: center; justify-content: center;
  padding: 40px; z-index: 1000;
}
.constellation-body {
  background: var(--mst-bg-card, #1c1f24);
  border: 1px solid var(--mst-border, #2a2f36); border-radius: var(--mst-radius, 8px);
  width: 90%; max-width: 600px;
}
.constellation-head { display: flex; justify-content: space-between; padding: 16px 24px; border-bottom: 1px solid var(--mst-border, #2a2f36); }
.constellation-head h2 { margin: 0; font-size: var(--mst-fs-h3, 18px); color: var(--mst-text, #e6e8eb); }
.constellation-close { background: transparent; border: none; color: var(--mst-text-secondary, #a0a4ab); cursor: pointer; font-size: 18px; }
.constellation-loading, .constellation-empty { padding: 24px; color: var(--mst-text-secondary, #a0a4ab); }
.constellation-empty p { margin: 0 0 12px; }
.constellation-empty__hint { font-size: var(--mst-fs-meta, 12px); }
.constellation-empty code { background: var(--mst-bg, #0f1115); padding: 2px 6px; border-radius: 3px; font-family: var(--mst-font-mono, monospace); }

/* --- D8 Plateau admin --- */

/* Respect des préférences de réduction de mouvement */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ========================================================================== */
/* Onglet Terminal (2026-08-05)                                               */
/* ========================================================================== */
/* Conçu pour de LONGUES sessions : fond sombre constant sur la zone de
   terminal (indépendant du thème clair/sombre du reste, comme un vrai
   terminal), contrastes doux, aucune animation sur la zone de texte. */

/* Le terminal occupe la PAGE — sans constante devinee.
   `calc(100vh - 104px)` reservait 104 px pour le bandeau et les marges ; la
   somme reelle en fait 111 (63 de bandeau + 24 + 24 de marges de `.main`). Sept
   pixels de trop, et les consequences n'ont rien de cosmetique : la page
   debordait, donc c'est la PAGE qui recevait la barre de defilement — celle que
   Romeo voyait a droite sans qu'elle fasse jamais defiler la console — et la
   derniere ligne du terminal passait sous le bord.
   On ne corrige donc pas la constante : on la SUPPRIME. `.main` est deja un
   element flex en colonne dans `#app` ; il suffit qu'il le soit aussi pour son
   contenu, et l'onglet prend exactement la place restante, quelle que soit la
   hauteur du bandeau demain. */
.main--terminal {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.terminal-tab {
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-2);
  flex: 1;
  min-height: 440px;
}

.term-barre {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-3);
  flex-wrap: wrap;
}
.term-colonnes { display: flex; gap: var(--mst-sp-1); margin-left: auto; }

.term-btn {
  padding: 4px var(--mst-sp-3);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: var(--mst-bg-surface);
  color: var(--mst-text-primary);
  cursor: pointer;
  font-size: var(--mst-fs-meta);
  transition: border-color 0.15s, background 0.15s;
}
.term-btn:hover { border-color: var(--mst-text-primary); }
/* L'icône d'un bouton est un SVG en ligne, pas un caractère : un pictogramme
   Unicode dépend des polices de l'appareil (le 🗀 de « Fichiers » était un
   carré vide sur Android), un tracé se dessine partout. */
.term-btn__ico { display: inline-block; width: 1em; height: 1em; vertical-align: -0.15em; margin-right: 0.35em; }
.term-btn__ico svg { display: block; width: 100%; height: 100%; }
.term-btn.is-active { background: var(--mst-bg-surface-2); font-weight: 600; }
.term-btn--primaire { background: var(--mst-bg-surface-2); font-weight: 600; }
.term-btn--danger:hover { border-color: #d9534f; color: #d9534f; }

/* ---------- Panneau « copier à la main » ----------
   Le chemin de copie des postes distants (page en http:// = contexte NON
   sécurisé, où `navigator.clipboard` n'existe pas). Le texte y est présenté
   dans un vrai champ, présélectionné, et c'est le Ctrl+C de l'utilisateur qui
   copie — aucune API n'intervient, donc rien ne peut la refuser. */
.copie-manuelle { max-width: 860px; }
.copie-manuelle__aide {
  margin: 0 0 var(--mst-sp-3) 0;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
}
.copie-manuelle__zone {
  width: 100%;
  /* Assez haut pour qu'un écran de console tienne d'un coup d'œil, et borné en
     `vh` pour qu'un long historique ne pousse pas les boutons hors de vue. */
  height: min(52vh, 420px);
  resize: vertical;
  padding: var(--mst-sp-3);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: #0d1117;              /* le fond de la console : on copie ce qu'on y voyait */
  color: #d5d9e0;
  font-family: ui-monospace, "Cascadia Code", "Fira Code", Consolas, monospace;
  font-size: var(--mst-fs-meta);
  line-height: 1.45;
  /* Pas de repli : une ligne de console coupée à l'affichage se recollerait
     mal à l'œil, et la sélection à la souris deviendrait trompeuse. */
  white-space: pre;
  overflow: auto;
}
.copie-manuelle__zone::selection { background: #2d5a9e; color: #ffffff; }
.copie-manuelle__mesure {
  margin: var(--mst-sp-2) 0 0 0;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
}

/* Grille 1 / 2 / 3 colonnes — pilotée en JS par grid-template-columns. */
.term-grille {
  display: grid;
  gap: var(--mst-sp-3);
  flex: 1;
  min-height: 0;          /* sans ça, une colonne longue déborde la grille */
}
.term-colonne {
  display: flex;
  flex-direction: column;
  min-width: 0;           /* autorise le rétrécissement sous le contenu */
  min-height: 0;
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  overflow: hidden;
}
/* Colonne REPLIÉE — une autre est agrandie.
   `display: none` et rien d'autre : la colonne reste dans le document, donc
   son terminal reste vivant, connecté, avec son historique. La retirer du DOM
   la ferait détruire, et « agrandir » deviendrait « fermer les autres ». */
.term-colonne.est-repliee { display: none; }
.term-colonne__entete {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  padding: var(--mst-sp-2);
  background: var(--mst-bg-surface-2);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}
.term-colonne__corps { flex: 1; min-height: 0; display: flex; }
.term-select {
  flex: 1;
  min-width: 0;
  padding: 3px var(--mst-sp-2);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: var(--mst-bg-surface);
  color: var(--mst-text-primary);
}

.term-panneau {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  min-width: 0;
}
.term-panneau__entete {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  padding: var(--mst-sp-2);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  flex-wrap: wrap;
}
.term-panneau__titre { font-weight: 600; }
/* Le répertoire de travail est affiché en permanence : quand trois terminaux
   sont côte à côte, « où suis-je » est la première question. */
.term-panneau__cwd {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary, #8b949e);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 40ch;
  direction: rtl;         /* tronque à GAUCHE : la fin du chemin est utile */
  text-align: left;
}
.term-panneau__actions { display: flex; gap: var(--mst-sp-1); margin-left: auto; }

/* Zone du terminal : fond sombre constant, défilement VERTICAL seulement —
   xterm gère lui-même le retour à la ligne et la barre de défilement.

   AUCUNE MARGE INTERIEURE ICI, et c'est un point de fond. L'extension `fit`
   mesure la hauteur du PARENT du terminal par `getComputedStyle().height` :
   sur un element en `border-box`, Chrome renvoie la hauteur BORDURE COMPRISE,
   marge interieure incluse. Les 8 px de marge haut + bas etaient donc comptes
   deux fois, `fit` proposait une ligne de trop, et cette ligne — la derniere,
   celle qui porte l'invite et l'etat de Claude Code — passait sous le bord,
   coupee en deux par `overflow: hidden`.
   La respiration passe donc sur `.xterm` lui-meme : `fit` retranche
   explicitement la marge interieure de CET element-la, donc le calcul redevient
   exact. Mesure au navigateur, fenetre de 1400x900 : avant, un terminal de
   660 px dans un cadre qui n'en offrait que 646 — d'ou la ligne coupee ; apres,
   646 px de terminal dans 655 px de cadre, rien ne depasse. */
.term-panneau__ecran {
  flex: 1;
  min-height: 120px;
  background: #0d1117;
  padding: 0;
  overflow: hidden;
}
.term-panneau__ecran .xterm { padding: var(--mst-sp-2); }

/* Barre de defilement VISIBLE a droite du terminal.

   xterm v6 ne se sert PAS du defilement natif du navigateur : il dessine sa
   propre glissiere (heritee de VS Code) et la fait disparaitre par opacite des
   qu'on ne la survole plus. D'ou une zone de terminal ou rien n'indiquait qu'il
   existait 5 000 lignes au-dessus. On la maintient affichee ; sa couleur, elle,
   vient du theme passe a xterm (cf. `scrollbarSlider*` dans terminal.js).

   S'y ajoute un RAIL. Sans lui, seul le curseur est peint : sur un terminal a
   peine rempli, il occupe presque toute la hauteur et se confond avec le bord,
   et sur une longue session il devient un trait de deux centimetres perdu dans
   le noir. Le rail dit ou la barre commence et ou elle finit — c'est lui qui la
   fait lire comme une barre de defilement, et non comme un reflet. */
.term-panneau__ecran .xterm .xterm-scrollable-element > .scrollbar {
  opacity: 1 !important;
  pointer-events: auto !important;
}
.term-panneau__ecran .xterm .xterm-scrollable-element > .invisible {
  opacity: 1 !important;
  pointer-events: auto !important;
}
.term-panneau__ecran .xterm .xterm-scrollable-element > .invisible.fade {
  transition: none !important;
}
.term-panneau__ecran .xterm .xterm-scrollable-element > .scrollbar.vertical {
  background: rgba(255, 255, 255, 0.07);
  border-left: 1px solid rgba(255, 255, 255, 0.08);
}

/* La SECONDE barre, blanche, derriere la bonne — on la retire.
   `.xterm-viewport` porte `overflow-y: scroll` (feuille de style de xterm) :
   c'est le conteneur qui defile REELLEMENT, et la glissiere heritee de VS Code
   n'est qu'un habillage pose par-dessus. Un navigateur qui dessine des barres
   classiques — Chrome et Edge sous Windows — en peint donc une native, blanche
   et flechee, a cote de celle qu'on voit fonctionner. Deux barres pour un seul
   defilement, dont une qu'on n'a pas dessinee.
   On la masque sans toucher au defilement : masquer une barre n'empeche ni la
   molette, ni le clavier, ni la glissiere de xterm. Et `color-scheme: dark`
   couvre ce qui resterait de chrome natif dans ce cadre : ici le fond est noir
   quel que soit le theme du reste de Bebsolo.
   (Un navigateur a barres en surimpression, comme celui des verifications
   automatiques, n'en peignait aucune : ce defaut ne se voyait que sur la
   machine de Romeo — d'ou sa capture d'ecran, qui l'a tranche.) */
.term-panneau__ecran .xterm { color-scheme: dark; }
.term-panneau__ecran .xterm .xterm-viewport { scrollbar-width: none; }
.term-panneau__ecran .xterm .xterm-viewport::-webkit-scrollbar { display: none; }

/* Ecran SECONDAIRE (Claude Code, vim, htop…) : pas de glissiere.
   Mesure sur un lancement reel de `claude` : `ESC [ ?1049h`, suivi de la prise
   de la souris. Cet ecran n'a pas d'historique — c'est sa definition — donc il
   n'y a rien a faire defiler et le defilement appartient a l'application. Une
   barre pleine hauteur et inerte promettrait le contraire ; elle disparait, et
   revient avec l'historique du shell des qu'on quitte le programme. */
.term-panneau__ecran.est-ecran-alterne .xterm .xterm-scrollable-element > .scrollbar {
  display: none !important;
}
.term-panneau__ecran .xterm .xterm-scrollable-element > .scrollbar > .slider {
  border-radius: 7px;
}

/* Bandeau d'état — la réponse visuelle à « aucune ambiguïté ». */
.term-panneau__etat {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  padding: 4px var(--mst-sp-2);
  border-top: var(--mst-border-w) solid var(--mst-border);
  background: var(--mst-bg-surface-2);
  font-size: var(--mst-fs-meta);
  min-height: 26px;
  flex-wrap: wrap;
}
.term-etat {
  padding: 1px var(--mst-sp-2);
  border-radius: var(--mst-radius-sm);
  border: 1px solid transparent;
  font-weight: 600;
}
/* Une couleur PAR ÉTAT, jamais deux états de la même teinte : c'est ce qui
   rend la distinction lisible d'un coup d'œil, sans lire le libellé. */
.etat--attente     { background: #3d3d3d; color: #d0d0d0; border-color: #555; }
.etat--cours       { background: #123b63; color: #7cc4ff; border-color: #1f6feb; }
.etat--terminee    { background: #123d24; color: #7ee787; border-color: #238636; }
.etat--interrompue { background: #4a3a10; color: #e3b341; border-color: #9e6a03; }
.etat--erreur      { background: #4d1f1f; color: #ff7b72; border-color: #da3633; }
.term-etat--file       { background: #3d3d3d; color: #d0d0d0; }
.term-etat--connexion  { color: var(--mst-text-secondary, #8b949e); font-weight: 400; }
.term-etat--coupe      { background: #4a3a10; color: #e3b341; }
/* Repli HTTP : le terminal FONCTIONNE, plus lentement. Ni vert (tout
   va bien) ni rouge (panne) — un avertissement, qui est la verite. */
.term-etat--repli      { background: #3a2f10; color: #d29922; }
/* Barre d'etat muette : elle disparait au lieu de reserver une rangee vide.
   Chaque rangee de chrome est prise sur la hauteur du terminal. */
.term-panneau__etat.est-vide { display: none; }
.term-etat--erreur     { background: #4d1f1f; color: #ff7b72; }
.term-etat--fini       { color: var(--mst-text-secondary, #8b949e); font-weight: 400; }
.term-etat__note { color: var(--mst-text-secondary, #8b949e); font-weight: 400; }

/* Sous 900 px, les colonnes s'empilent : trois terminaux côte à côte sur un
   téléphone ne seraient lisibles dans aucune. */
@media (max-width: 900px) {
  .term-grille { grid-template-columns: 1fr !important; }
  /* Sur telephone la page DOIT defiler : trois terminaux empiles ne tiennent
     pas dans une hauteur d'ecran. On rend donc a l'onglet sa hauteur naturelle,
     sinon la colonne serait comprimee et son contenu rogne. */
  .main--terminal { display: block; }
  .terminal-tab { height: auto; flex: none; }
  .term-colonne { min-height: 60vh; }
}

/* --- Onglet Terminal : fichiers, pièces jointes, gestion ------------------ */

/* Onglet Fichiers : quand il est ouvert, il PREND la place du terminal.
   En bandeau de 30 vh, une liste de fichiers ne se consulte pas, elle se
   devine — et c'est justement la consultation qui etait demandee. */
.term-fichiers {
  display: none;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  overflow-y: auto;
  padding: var(--mst-sp-2);
  background: var(--mst-bg-surface);
}
.term-fichiers__liste { display: flex; flex-direction: column; gap: 2px; }
.term-fichier {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  padding: 2px var(--mst-sp-2);
  font-size: var(--mst-fs-meta);
  border-radius: var(--mst-radius-sm);
  /* LE REPLI, ET IL VIENT D'UNE MESURE (2026-09-18). En ajoutant la date, la
     ligne à 360 px — le téléphone — ne laissait plus RIEN au nom : mesuré à
     0 px de large, avec la taille repliée sur deux lignes et 3 px de
     débordement. Un fichier sans nom n'est plus un fichier. Avec le repli et
     un plancher de 12ch sur le nom : 114 px pour le nom, aucun débordement,
     et les boutons passent sur une seconde rangée — ce qui agrandit au
     passage des cibles tactiles. À 520 et 900 px, la ligne reste unique et
     inchangée (34 px de haut dans les deux cas, avant comme après). */
  flex-wrap: wrap;
}
.term-fichier:hover { background: var(--mst-bg-surface-2); }
/* L'ORIGINE d'abord, et d'une couleur différente : Roméo doit distinguer d'un
   coup d'œil ce qu'il a envoyé de ce que le terminal a produit. */
.term-fichier__origine {
  flex: 0 0 auto;
  min-width: 7ch;
  text-align: center;
  padding: 0 4px;
  border-radius: var(--mst-radius-sm);
  background: #123d24;
  color: #7ee787;
  font-size: 11px;
}
.term-fichier__origine--entrant { background: #123b63; color: #7cc4ff; }
.term-fichier__nom {
  /* 12ch de plancher : c'est ce qui empêche la date de manger tout le nom sur
     un téléphone (cf. `flex-wrap` ci-dessus). */
  flex: 1 1 12ch;
  min-width: 12ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* C'est un bouton : il ouvre le fichier. On lui retire l'apparence de
     bouton mais pas les signes qu'on peut cliquer dessus. */
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.term-fichier__nom:hover { text-decoration: underline; }
.term-fichier__taille { color: var(--mst-text-secondary, #8b949e); }
/* La DATE de dernière modification. `nowrap` et chiffres à largeur fixe : une
   colonne de dates qui se replie ou qui danse d'une ligne à l'autre ne se lit
   plus en balayant la liste, ce qui est le seul usage qu'on en a. Le nom, lui,
   a déjà son ellipsis et son infobulle : c'est lui qui cède la place. */
.term-fichier__date {
  flex: 0 0 auto;
  color: var(--mst-text-secondary, #8b949e);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Barre de depot de l'onglet Fichiers. Le depot vit desormais la ou l'on VOIT
   les fichiers : un bouton « Joindre » sous une console laissait croire que le
   fichier accompagnait une commande, alors qu'il ne fait que se poser dans le
   dossier de la conversation. */
.term-depot {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  padding: var(--mst-sp-2);
  margin-bottom: var(--mst-sp-2);
  border: 1px dashed var(--mst-border);
  border-radius: var(--mst-radius-md);
}
.term-depot.est-survolee { border-color: #6ea8fe; background: var(--mst-bg-surface-2); }
/* La barre prend le focus a l'ouverture de l'onglet, pour que Ctrl+V y arrive.
   Elle doit donc le MONTRER : un collage qui atterrit dans un endroit qu'on
   n'avait pas designe se lit comme un collage perdu. */
.term-depot:focus,
.term-depot:focus-visible { outline: none; border-color: #6ea8fe; border-style: solid; }
.term-depot__aide { font-size: var(--mst-fs-meta); color: var(--mst-text-secondary, #8b949e); }

/* Vue « Toutes les conversations ». */
.term-gestion {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--mst-sp-2);
  overflow-y: auto;
}
.term-gestion__ligne {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  padding: var(--mst-sp-2);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: var(--mst-bg-surface);
}
.term-gestion__ligne:hover { border-color: var(--mst-text-primary); }
.term-gestion__titre {
  flex: 1;
  min-width: 0;
  text-align: left;
  border: 0;
  background: none;
  color: var(--mst-text-primary);
  font-weight: 600;
  font-size: var(--mst-fs-body, 14px);
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.term-gestion__cwd {
  color: var(--mst-text-secondary, #8b949e);
  font-size: var(--mst-fs-meta);
  max-width: 32ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  direction: rtl;
  text-align: left;
}
@media (max-width: 900px) {
  .term-gestion__cwd { display: none; }
}

/* =====================================================================
   Onglet OUTILS — cadre générique d'outils métier (outils.js).
   Aucune règle ici ne cible un outil nommé : les classes qualifient une
   FORME (card, atelier, composer…), jamais un identifiant d'outil.
   ===================================================================== */

.outils-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--mst-sp-4);
}

.outil-card {
  display: flex;
  gap: var(--mst-sp-3);
  align-items: flex-start;
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-4);
  cursor: pointer;
  transition: background var(--mst-motion-fast) var(--mst-easing),
              border-color var(--mst-motion-fast) var(--mst-easing);
}
.outil-card:hover {
  background: var(--mst-bg-surface-2);
  border-color: var(--mst-border-strong);
}
.outil-card[data-statut="en_construction"] { opacity: 0.7; }
.outil-card__icon { font-size: 28px; line-height: 1; }
.outil-card__body { flex: 1; min-width: 0; }
.outil-card__title {
  font-size: var(--mst-fs-title);
  font-weight: var(--mst-fw-medium);
  margin: 0 0 var(--mst-sp-1) 0;
  color: var(--mst-text-primary);
}
.outil-card__desc {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  margin: 0 0 var(--mst-sp-2) 0;
}
.outil-card__statut {
  display: inline-block;
  padding: 2px var(--mst-sp-2);
  border-radius: var(--mst-radius-pill);
  font-size: var(--mst-fs-micro);
  font-weight: var(--mst-fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.3px;
  border: var(--mst-border-w) solid var(--mst-border);
  color: var(--mst-text-secondary);
  white-space: nowrap;
}
.outil-card__statut[data-statut="pret"] {
  color: var(--mst-sem-go, #3fb950);
  border-color: var(--mst-sem-go, #3fb950);
}
.outil-card__statut[data-statut="connexion_requise"] {
  color: var(--mst-sem-arbitration);
  border-color: var(--mst-sem-arbitration);
}
.outil-card__statut[data-statut="en_construction"] {
  color: var(--mst-text-muted);
  border-color: var(--mst-border);
}

.outil-badge {
  display: inline-block;
  padding: 2px var(--mst-sp-2);
  border-radius: var(--mst-radius-sm);
  font-size: var(--mst-fs-micro);
  font-weight: var(--mst-fw-medium);
  margin-bottom: var(--mst-sp-2);
}
.outil-badge--readonly {
  color: var(--mst-accent);
  background: var(--mst-accent-bg);
}

/* -- En-tête de l'atelier -- */
.outil-atelier__header {
  display: flex;
  align-items: flex-start;
  gap: var(--mst-sp-3);
  margin-bottom: var(--mst-sp-4);
}
.outil-atelier__icon { font-size: 26px; line-height: 1.3; }
.outil-atelier__titles { flex: 1; min-width: 0; }
.outil-atelier__desc {
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-body);
  margin: var(--mst-sp-1) 0 0 0;
}
.outil-atelier__hint {
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
  margin: 0 0 var(--mst-sp-3) 0;
}

/* -- Parcours de configuration d'un connecteur -- */
.outil-atelier__connecteur {
  max-width: 520px;
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-4);
}
.outil-atelier__form {
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-3);
  margin-bottom: var(--mst-sp-4);
}
.outil-atelier__field {
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-1);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}
.outil-atelier__input {
  background: var(--mst-bg-app);
  color: var(--mst-text-primary);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-2) var(--mst-sp-3);
  font-family: inherit;
  font-size: var(--mst-fs-body);
}
.outil-atelier__required { color: var(--mst-sem-arbitration); }

/* La fiche d'une commande d'administration (§2.8) : les champs déclarés par
   l'outil, rendus en modale. Une fiche décrit un objet — elle porte donc
   volontiers vingt champs, là où un panneau de réglages en porte trois. Deux
   colonnes dès qu'il y a la place, et un pied qui reste visible : sans lui,
   « Enregistrer » se retrouve à trente champs de défilement du dernier champ
   rempli. */
.modal--fiche { max-width: 880px; }
.modal--fiche .outil-atelier__form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--mst-sp-3) var(--mst-sp-4);
  max-height: 62vh;
  overflow-y: auto;
  padding-right: var(--mst-sp-2);
}
.modal--fiche .outil-atelier__field textarea.outil-atelier__input { min-height: 4.5em; }
.modal--fiche .modal__footer {
  position: sticky;
  bottom: calc(-1 * var(--mst-sp-5));
  background: var(--mst-bg-surface);
  margin-bottom: calc(-1 * var(--mst-sp-5));
  padding-bottom: var(--mst-sp-4);
}
.outil-atelier__missing {
  color: var(--mst-sem-arbitration);
  font-weight: var(--mst-fw-medium);
}
.outil-atelier__actions {
  display: flex;
  gap: var(--mst-sp-2);
}

/* -- Disposition de l'espace de travail -- */
.outil-atelier__layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: var(--mst-sp-4);
  align-items: start;
}
@media (max-width: 900px) {
  .outil-atelier__layout { grid-template-columns: 1fr; }
}
.outil-atelier__side {
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-4);
}
.outil-atelier__connecteur-statut {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-3);
}
.outil-atelier__connecteur-ligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mst-sp-2);
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}
.outil-atelier__connecteur-corps { margin-top: var(--mst-sp-3); }

.outil-atelier__consignes,
.outil-atelier__sessions {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-3);
}
.outil-atelier__consignes h2,
.outil-atelier__sessions h2 {
  margin: 0 0 var(--mst-sp-2) 0;
  font-size: var(--mst-fs-title);
}
.outil-atelier__consignes-textarea {
  width: 100%;
  min-height: 90px;
  background: var(--mst-bg-app);
  color: var(--mst-text-primary);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-2);
  font-family: inherit;
  font-size: var(--mst-fs-meta);
  resize: vertical;
  margin-bottom: var(--mst-sp-2);
  box-sizing: border-box;
}
.outil-atelier__main {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-4);
  min-height: 320px;
  display: flex;
  flex-direction: column;
}

/* -- Historique des sessions -- */
.outil-sessions-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-1);
}
.outil-sessions-list__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mst-sp-2);
  padding: var(--mst-sp-2);
  border-radius: var(--mst-radius-sm);
  cursor: pointer;
  border: var(--mst-border-w) solid transparent;
}
.outil-sessions-list__item:hover { background: var(--mst-bg-surface-2); }
.outil-sessions-list__item.is-active {
  background: var(--mst-accent-bg);
  border-color: var(--mst-accent);
}
.outil-sessions-list__main { min-width: 0; overflow: hidden; }
.outil-sessions-list__title {
  display: block;
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.outil-sessions-list__meta {
  display: block;
  font-size: var(--mst-fs-micro);
  color: var(--mst-text-muted);
}
.outil-sessions-list__actions {
  display: flex;
  gap: 2px;
  opacity: 0;
  transition: opacity var(--mst-motion-fast) var(--mst-easing);
}
.outil-sessions-list__item:hover .outil-sessions-list__actions { opacity: 1; }
.outil-sessions-list__icon-btn {
  background: transparent;
  border: 0;
  color: var(--mst-text-secondary);
  cursor: pointer;
  font-size: var(--mst-fs-meta);
  padding: 2px 4px;
}
.outil-sessions-list__icon-btn:hover { color: var(--mst-text-primary); }
.outil-sessions-list__rename-input {
  width: 100%;
  background: var(--mst-bg-app);
  color: var(--mst-text-primary);
  border: var(--mst-border-w) solid var(--mst-accent);
  border-radius: var(--mst-radius-sm);
  padding: 2px var(--mst-sp-1);
  font-size: var(--mst-fs-meta);
}

/* -- Fil de conversation -- */
.outil-conversation__header {
  margin-bottom: var(--mst-sp-3);
  color: var(--mst-text-primary);
}
/* Dictée — la barre qui PROUVE que le micro écoute.
   Le témoin de niveau n'est pas décoratif : c'est la seule réponse visuelle au
   doute « est-ce que l'outil capte vraiment ce que je dis ». */
.outil-dictee {
  margin-bottom: var(--mst-sp-2);
  padding: var(--mst-sp-2) var(--mst-sp-3);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: var(--mst-bg-surface-2);
}
.outil-dictee[hidden] { display: none; }
.outil-dictee__barre {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  flex-wrap: wrap;
}
.outil-dictee__jauge {
  flex: 1;
  min-width: 80px;
  height: 6px;
  border-radius: var(--mst-radius-pill);
  background: var(--mst-bg-surface);
  overflow: hidden;
}
.outil-dictee__niveau {
  display: block;
  width: 0%;
  height: 100%;
  background: var(--mst-accent);
  transition: width 60ms linear;
}
.outil-dictee__etat {
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
}
.outil-dictee__aide {
  margin: var(--mst-sp-2) 0 0;
  color: var(--mst-text-muted);
  font-size: var(--mst-fs-meta);
}
.outil-dictee__bouton--actif {
  border-color: var(--mst-accent);
  color: var(--mst-accent);
}
/* Pendant l'enregistrement, le cadre entier respire — visible du coin de
   l'œil quand on regarde ses notes plutôt que l'écran. */
.outil-dictee--enregistre {
  border-color: var(--mst-accent);
  animation: outil-dictee-pulse 2s ease-in-out infinite;
}
@keyframes outil-dictee-pulse {
  0%, 100% { border-color: var(--mst-accent); }
  50% { border-color: var(--mst-border); }
}
@media (prefers-reduced-motion: reduce) {
  .outil-dictee--enregistre { animation: none; }
  .outil-dictee__niveau { transition: none; }
}

/* Documents de la conversation — replié par défaut, sous l'en-tête. */
.outil-documents {
  margin-bottom: var(--mst-sp-3);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-2) var(--mst-sp-3);
  background: var(--mst-bg-surface-2);
}
.outil-documents__resume {
  cursor: pointer;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
  user-select: none;
}
.outil-documents__vide {
  margin: var(--mst-sp-2) 0 0;
  color: var(--mst-text-muted);
  font-size: var(--mst-fs-meta);
}
.outil-documents__list {
  list-style: none;
  margin: var(--mst-sp-2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.outil-documents__item {
  display: flex;
  align-items: baseline;
  gap: var(--mst-sp-2);
  flex-wrap: wrap;
}
/* Le nom est un bouton : c'est lui qui déclenche la récupération, laquelle
   passe par un appel authentifié et non par une navigation. */
.outil-documents__nom {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--mst-accent);
  font: inherit;
  text-align: left;
  word-break: break-all;
}
.outil-documents__nom:hover {
  text-decoration: underline;
}
.outil-documents__meta {
  color: var(--mst-text-muted);
  font-size: var(--mst-fs-meta);
}

.outil-conversation__thread {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-3);
  margin-bottom: var(--mst-sp-4);
  overflow-y: auto;
}
.outil-msg {
  max-width: 80%;
  padding: var(--mst-sp-2) var(--mst-sp-3);
  border-radius: var(--mst-radius-md);
  background: var(--mst-bg-surface-2);
  border: var(--mst-border-w) solid var(--mst-border);
}
.outil-msg--operateur {
  align-self: flex-end;
  background: var(--mst-accent-bg);
  border-color: var(--mst-accent);
}
.outil-msg--outil { align-self: flex-start; }
.outil-msg--erreur {
  border-color: var(--mst-sem-escalation);
  background: var(--mst-sem-escalation-bg);
}
.outil-msg__meta {
  display: flex;
  justify-content: space-between;
  gap: var(--mst-sp-3);
  font-size: var(--mst-fs-micro);
  color: var(--mst-text-secondary);
  margin-bottom: var(--mst-sp-1);
}
.outil-msg__role { font-weight: var(--mst-fw-medium); }
.outil-msg__time { font-family: var(--mst-font-mono, monospace); }
.outil-msg__body {
  font-size: var(--mst-fs-body);
  line-height: var(--mst-lh-body);
  color: var(--mst-text-primary);
  white-space: pre-wrap;
  word-break: break-word;
}
/* Livrables produits par le tour, rattachés à la bulle de réponse */
.outil-msg__fichiers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mst-sp-2);
  margin-top: var(--mst-sp-2);
  padding-top: var(--mst-sp-2);
  border-top: var(--mst-border-w) solid var(--mst-border);
}
.outil-msg__fichier {
  background: var(--mst-bg-surface-2);
  border: var(--mst-border-w) solid var(--mst-accent);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-1) var(--mst-sp-2);
  cursor: pointer;
  color: var(--mst-accent);
  font: inherit;
  font-size: var(--mst-fs-meta);
  word-break: break-all;
}
.outil-msg__fichier:hover { text-decoration: underline; }

/* -- Composer : zone d'entrée dont la forme vient du manifeste -- */
.outil-composer {
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-2);
  border-top: var(--mst-border-w) solid var(--mst-border);
  padding-top: var(--mst-sp-3);
}
.outil-composer__champs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mst-sp-3);
  margin-bottom: var(--mst-sp-1);
}
.outil-composer__champ-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--mst-fs-micro);
  color: var(--mst-text-secondary);
}
.outil-composer__champ {
  background: var(--mst-bg-app);
  color: var(--mst-text-primary);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: 4px var(--mst-sp-2);
  font-family: inherit;
  font-size: var(--mst-fs-meta);
}
.outil-composer__textarea {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-2) var(--mst-sp-3);
  font-family: inherit;
  font-size: var(--mst-fs-body);
  color: var(--mst-text-primary);
  min-height: 72px;
  resize: vertical;
}
.outil-composer__textarea:focus {
  outline: none;
  border-color: var(--mst-accent);
}
.outil-composer__dropzone {
  border: 1px dashed var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-2);
}
.outil-composer__dropzone.is-dragover {
  border-color: var(--mst-accent);
  background: var(--mst-accent-bg);
}
.outil-composer__attach-row {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
  flex-wrap: wrap;
}
.outil-composer__hint {
  color: var(--mst-text-muted);
  font-size: var(--mst-fs-micro);
}
.outil-composer__actions {
  display: flex;
  justify-content: flex-end;
}

/* ---------------------------------------------------------------------------
   Onglet CHECK — état de santé de la plateforme (2026-08-16).

   Une seule règle visuelle gouverne cet écran : ce qui dit qu'un correctif a
   ÉCHOUÉ doit se voir avant ce qui dit qu'un travail reste à faire. Une
   récidive et une dette de contrôle sont donc les deux seuls éléments qui
   portent une couleur d'alerte ; tout le reste est neutre.
   --------------------------------------------------------------------------- */
.check { display: flex; flex-direction: column; gap: 1.25rem; }
.check__entete { display: flex; align-items: center; gap: .75rem; }
.check__carte {
  border: 1px solid var(--border, #2a2a35);
  border-radius: 10px; padding: 1rem 1.15rem;
  background: var(--surface, #16161d);
}
.check__carte-tete {
  display: flex; align-items: center; gap: .75rem; margin-bottom: .5rem;
}
.check__carte-tete h2 { margin: 0; font-size: 1.05rem; flex: 0 0 auto; }
.check__carte-tete .btn { margin-left: auto; }
.check__pastille {
  font-size: .78rem; font-weight: 600; padding: .12rem .55rem;
  border-radius: 999px; letter-spacing: .02em;
}
.check__pastille.is-ok { background: #14361f; color: #7ee2a8; }
.check__pastille.is-ko { background: #3a1c1c; color: #ff9d9d; }
.check__aide { color: var(--muted, #9aa0ad); font-size: .88rem; margin: .25rem 0 .75rem; }
.check__alerte { color: #ff9d9d; font-weight: 600; }
.check__dette { color: #ffcf8b; font-weight: 600; }
.check__table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.check__table th {
  text-align: left; font-weight: 600; color: var(--muted, #9aa0ad);
  border-bottom: 1px solid var(--border, #2a2a35); padding: .35rem .5rem;
}
.check__table td { padding: .35rem .5rem; border-bottom: 1px solid #1f1f27; }
.check__table tr.is-recidive td { background: #2a1414; }
.check__gravite {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .03em;
  padding: .08rem .45rem; border-radius: 4px; background: #23232c;
}
.check__gravite.is-bloquant { background: #3a1c1c; color: #ff9d9d; }
.check__gravite.is-serieux  { background: #3a2f14; color: #ffcf8b; }
.check__gravite.is-signal   { background: #1c2a3a; color: #8fc3ff; }
.check__code { color: #8fc3ff; }
.check__marques { color: #ff9d9d; font-size: .8rem; font-weight: 600; }
.check__constat { padding: .5rem 0; border-bottom: 1px solid #1f1f27; }
.check__constat-tete { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.check__resume { flex: 1 1 20rem; }
.check__detail { color: var(--muted, #9aa0ad); font-size: .86rem; }
.check__detail pre { white-space: pre-wrap; margin: .35rem 0 0; }
.check__formulaire { display: flex; flex-direction: column; margin-bottom: 1rem; }
/* Les champs reprennent la convention .field du reste de l'application —
   fond encastré, bordure et texte du thème. La première version posait une
   classe .input qui n'existait pas : les champs sortaient blancs, et le texte
   qu'on y tapait était illisible. */
.check__aide-champ {
  color: var(--mst-text-secondary); font-size: var(--mst-fs-meta);
  margin-top: .25rem;
}
.check__anomalie { padding: .6rem 0; border-bottom: 1px solid #1f1f27; }
.check__anomalie.is-dette { border-left: 3px solid #ffcf8b; padding-left: .6rem; }
.check__actions { display: flex; gap: .5rem; margin-top: .5rem; }

.check__sous-titre {
  margin: 1.25rem 0 .25rem; font-size: .95rem;
  color: var(--mst-text-secondary);
}

/* --- Check : chronométrage des missions (P5, 2026-08-18) ------------------ */
.check__tableau { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
.check__tableau th {
  text-align: left; font-weight: 600; opacity: 0.65;
  padding: 4px 10px 4px 0; border-bottom: 1px solid var(--bordure, #444);
}
.check__tableau td {
  padding: 5px 10px 5px 0; border-bottom: 1px solid var(--bordure-faible, #333);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.check__tableau td:first-child { white-space: normal; }

/* --- Outils : administration déclarée (§2.8 du contrat, 2026-08-28) ---------
   Un panneau générique — réglages, commandes, état — rendu depuis la
   déclaration d'un outil. Les statuts colorés sont des JETONS conventionnels
   du contrat (ok, attente, en_cours, erreur, ignore), pas les états d'un outil
   particulier. */
.outil-atelier__administration {
  background: var(--mst-bg-surface);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  padding: var(--mst-sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--mst-sp-2);
}
.outil-atelier__administration h2 {
  margin: 0;
  font-size: var(--mst-fs-title);
}
.outil-administration__resume {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: var(--mst-sp-2);
}
.outil-administration__tuile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--mst-sp-2);
  background: var(--mst-bg-app);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  min-width: 0;
}
.outil-administration__tuile-valeur {
  font-size: var(--mst-fs-title);
  font-weight: var(--mst-fw-medium);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.outil-administration__tuile-libelle {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}
.outil-administration__message,
.outil-administration__en-cours {
  margin: 0;
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
}
.outil-administration__en-cours { color: var(--mst-text-primary); }
.outil-administration__resultats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--mst-fs-meta);
}
.outil-administration__resultat { display: flex; flex-direction: column; }
.outil-administration__resultat.is-erreur .outil-administration__resultat-tete {
  color: var(--mst-sem-arbitration);
}
.outil-administration__resultat-message {
  color: var(--mst-text-secondary);
  white-space: pre-wrap;
}
.outil-administration__commandes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mst-sp-2);
}
.outil-administration__reglages summary { cursor: pointer; }
.outil-administration__reglage-aide {
  display: block;
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  margin-top: 2px;
}
.outil-administration__etat { display: flex; flex-direction: column; gap: var(--mst-sp-3); }
.outil-administration__barre {
  display: flex;
  align-items: center;
  gap: var(--mst-sp-2);
}
.outil-administration__filtre {
  flex: 1;
  min-width: 0;
  background: var(--mst-bg-app);
  color: var(--mst-text-primary);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  padding: var(--mst-sp-2);
  font-family: inherit;
  font-size: var(--mst-fs-meta);
}
.outil-administration__compte {
  font-size: var(--mst-fs-meta);
  color: var(--mst-text-secondary);
  font-variant-numeric: tabular-nums;
}
.outil-administration__table-wrap { overflow-x: auto; }
.outil-administration__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--mst-fs-meta);
}
.outil-administration__table th {
  text-align: left;
  font-weight: var(--mst-fw-medium);
  color: var(--mst-text-secondary);
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  padding: 4px 8px 4px 0;
  white-space: nowrap;
}
.outil-administration__table td {
  padding: 5px 8px 5px 0;
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  vertical-align: top;
}
.outil-administration__cell-libelle { max-width: 320px; overflow-wrap: anywhere; }
.outil-administration__cell-detail {
  color: var(--mst-text-secondary);
  max-width: 420px;
  overflow-wrap: anywhere;
}
.outil-administration__cell-maj {
  white-space: nowrap;
  font-family: var(--mst-font-mono, monospace);
  color: var(--mst-text-secondary);
}
.outil-administration__cell-actions { white-space: nowrap; }
.outil-administration__statut {
  display: inline-block;
  font-size: 0.74rem;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--mst-bg-surface-2);
  color: var(--mst-text-secondary);
  white-space: nowrap;
}
.outil-administration__statut[data-statut="ok"] { background: #14361f; color: #7ee2a8; }
.outil-administration__statut[data-statut="attente"] { background: #3a2f14; color: #ffcf8b; }
.outil-administration__statut[data-statut="en_cours"] { background: #1c2a3a; color: #8fc3ff; }
.outil-administration__statut[data-statut="erreur"] { background: #3a1c1c; color: #ff9d9d; }
.outil-administration__statut[data-statut="ignore"] { opacity: 0.6; }

/* ============================================================
   Onglet Explorateur (2026-09-19) — le disque du PC, à distance.

   MOBILE D'ABORD : pensé pour le téléphone de Roméo (360 px) avant l'écran
   du PC. Une ligne = case à cocher (44 px de cible), icône, nom qui cède la
   place (ellipsis) et méta-ligne dessous ; aucune colonne à aligner, donc
   rien qui déborde. Seul le fil d'Ariane défile horizontalement, EN LUI-MÊME ;
   la page, jamais. Les actions sur la sélection vivent dans une barre collée
   en bas de l'écran, à portée de pouce.
   ============================================================ */
.explo { display: flex; flex-direction: column; gap: var(--mst-sp-2); min-width: 0; }
.explo__titre { display: flex; align-items: center; justify-content: space-between; gap: var(--mst-sp-2); }
.explo__outils,
.explo__barre,
.explo__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--mst-sp-1); }
.explo__barre:empty,
.explo__avis:empty,
.explo__ops:empty { display: none; }

.explo-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 10px;
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: var(--mst-bg-surface);
  color: var(--mst-text-primary);
  font: inherit;
  font-size: var(--mst-fs-meta);
  white-space: nowrap;
  cursor: pointer;
  transition: border-color var(--mst-motion-fast) var(--mst-easing);
}
.explo-btn:hover:not(:disabled) { border-color: var(--mst-text-secondary); }
.explo-btn:focus-visible { outline: 0; box-shadow: var(--mst-focus-ring); }
.explo-btn:disabled { color: var(--mst-text-muted); cursor: not-allowed; opacity: 0.55; }
.explo-btn--primaire { background: var(--mst-accent); color: var(--mst-text-on-accent); border-color: var(--mst-accent); }
.explo-btn--primaire:disabled { background: var(--mst-bg-surface); color: var(--mst-text-muted); border-color: var(--mst-border); }
.explo-btn--danger { color: var(--mst-sem-escalation); border-color: var(--mst-sem-escalation); }
.explo-btn--danger:disabled { border-color: var(--mst-border); }
.explo-btn--discret { background: transparent; }
.explo-btn--icone .explo-btn__txt { display: none; }

.explo-ico { display: inline-block; flex: 0 0 16px; width: 16px; height: 16px; }
.explo-ico svg { display: block; width: 100%; height: 100%; }
.explo-ico--lecteur { color: var(--mst-sem-arbitration); }
.explo-ico--dossier { color: var(--explo-t-dossier); }
.explo-ico--lien { color: var(--mst-accent); }
.explo-ico--fichier { color: var(--mst-text-secondary); }

.explo-select {
  min-height: 36px;
  padding: 0 6px;
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: var(--mst-bg-surface);
  color: var(--mst-text-primary);
  font-size: var(--mst-fs-meta);
}
.explo-bascule {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 36px;
  padding: 0 6px;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
  cursor: pointer;
}

/* Le fil d'Ariane défile en lui-même et montre d'emblée sa fin (explorateur.js). */
.explo__ariane {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  overflow-x: auto;
  white-space: nowrap;
  scrollbar-width: thin;
  padding: 2px 0;
}
.explo__miette {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  max-width: 60vw;
  padding: 8px 6px;
  border: 0;
  border-radius: var(--mst-radius-sm);
  background: none;
  color: var(--mst-accent);
  font: inherit;
  font-size: var(--mst-fs-meta);
  cursor: pointer;
}
.explo__miette span { overflow: hidden; text-overflow: ellipsis; }
.explo__miette.is-courante { color: var(--mst-text-primary); font-weight: var(--mst-fw-bold); cursor: default; }
.explo__sep { flex: 0 0 auto; color: var(--mst-text-muted); }

.explo__notice { display: flex; align-items: center; gap: 6px; margin: 0; font-size: var(--mst-fs-meta); }
.explo__masques { display: flex; flex-wrap: wrap; align-items: center; gap: var(--mst-sp-2); margin: 0; color: var(--mst-text-secondary); font-size: var(--mst-fs-meta); }
.explo-lien { padding: 0; border: 0; background: none; color: var(--mst-accent); font: inherit; text-decoration: underline; cursor: pointer; }

/* Le presse-papiers : survit à la navigation, se voit tant qu'il est plein. */
.explo__presse { display: none; }
.explo__presse.is-visible {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--mst-sp-2);
  padding: var(--mst-sp-2) var(--mst-sp-3);
  border: 1px dashed var(--mst-accent);
  border-radius: var(--mst-radius-md);
  background: var(--mst-accent-bg);
  font-size: var(--mst-fs-meta);
}
.explo__presse-texte { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }

.explo__ops { display: flex; flex-direction: column; gap: var(--mst-sp-1); }
.explo-op {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--mst-sp-2) var(--mst-sp-3);
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  background: var(--mst-bg-surface);
  font-size: var(--mst-fs-meta);
}
.explo-op__texte { display: flex; justify-content: space-between; gap: var(--mst-sp-2); min-width: 0; }
.explo-op__temps { color: var(--mst-text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.explo-op__courant { overflow: hidden; color: var(--mst-text-secondary); text-overflow: ellipsis; white-space: nowrap; }
.explo-op__aide { color: var(--mst-sem-arbitration); }
.explo-jauge { display: block; height: 4px; margin-top: 4px; overflow: hidden; border-radius: 2px; background: var(--mst-bg-inset); }
.explo-jauge__plein { display: block; height: 100%; background: var(--mst-accent); transition: width var(--mst-motion-base) var(--mst-easing); }
.explo-jauge__plein.is-critique { background: var(--mst-sem-escalation); }

.explo__liste {
  display: flex;
  flex-direction: column;
  min-height: 120px;
  overflow: hidden;
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
  background: var(--mst-bg-surface);
}
.explo__liste.is-dragover { border-color: var(--mst-accent); box-shadow: inset 0 0 0 2px var(--mst-accent); }
.explo__rubrique {
  margin: 0;
  padding: var(--mst-sp-3) var(--mst-sp-3) var(--mst-sp-1);
  color: var(--mst-text-muted);
  font-size: var(--mst-fs-micro);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.explo__entete {
  display: flex;
  align-items: center;
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-meta);
}
.explo__chargement, .explo__erreur, .explo__liste > .empty-state { padding: var(--mst-sp-4); }

.explo-ligne {
  display: flex;
  align-items: center;
  min-width: 0;
  min-height: 48px;
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}
.explo-ligne:last-child { border-bottom: 0; }
.explo-ligne--lien {
  width: 100%;
  gap: var(--mst-sp-3);
  padding: 6px var(--mst-sp-3);
  border: 0;
  border-bottom: var(--mst-border-w) solid var(--mst-border);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.explo-ligne--lien:disabled { opacity: 0.55; cursor: not-allowed; }
.explo-ligne--lien:hover:not(:disabled),
.explo-ligne__ouvrir:hover { background: var(--mst-bg-surface-2); }
.explo-ligne__case {
  display: flex;
  flex: 0 0 44px;
  align-self: stretch;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.explo-ligne__case input { width: 18px; height: 18px; cursor: pointer; }
.explo-ligne__ouvrir {
  display: flex;
  flex: 1 1 auto;
  align-self: stretch;
  align-items: center;
  gap: var(--mst-sp-3);
  min-width: 0;
  padding: 6px var(--mst-sp-3) 6px 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.explo-ligne__texte { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; }
.explo-ligne__nom { overflow: hidden; font-size: var(--mst-fs-body); text-overflow: ellipsis; white-space: nowrap; }
.explo-ligne__meta {
  display: flex;
  align-items: center;
  gap: 6px;
  overflow: hidden;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-micro);
  font-variant-numeric: tabular-nums;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.explo-ligne__verrou { display: inline-flex; color: var(--mst-sem-arbitration); }
.explo-ligne__verrou .explo-ico { flex-basis: 12px; width: 12px; height: 12px; }
.explo-ligne.is-cache { opacity: 0.7; }
.explo-ligne.is-interdite .explo-ligne__nom { color: var(--mst-text-muted); }
.explo-ligne.is-selection { background: var(--mst-accent-bg); }
.explo-ligne__meta-texte { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.explo-ligne__nomligne { display: flex; align-items: center; gap: 6px; min-width: 0; }
.explo-ligne__verrou--pc { display: none; }

/* La Corbeille (2026-09-19) : sa ligne à l'accueil, et l'emplacement
   d'origine sous le nom au téléphone. Un chemin se lit par sa FIN — le
   dossier qui le distingue : l'ellipse se met au DÉBUT (bloc de droite à
   gauche), le chemin garde son ordre (<bdi> isolé, de gauche à droite). */
.explo-ico--corbeille { color: var(--mst-text-secondary); }
.explo-ligne__meta.is-erreur { color: var(--mst-sem-escalation); }
.explo-ligne__origine {
  display: block;
  direction: rtl;
  text-align: left;
}
.explo-ligne__origine bdi,
.explo-el__origine bdi,
.explo-ligne .explo-col--origine bdi { direction: ltr; unicode-bidi: isolate; }
.explo-el__origine,
.explo-ligne .explo-col--origine { direction: rtl; text-align: left; }
/* Un élément incomplet (fiche sans contenu…) se voit comme tel : estompé,
   et marqué « incomplet » à côté du nom sur grand écran. */
.explo-ligne.is-incomplet .explo-ligne__nom,
.explo-el.is-incomplet .explo-el__nom { color: var(--mst-text-muted); }
.explo-etiquette {
  flex: 0 0 auto;
  padding: 0 6px;
  border: var(--mst-border-w) solid var(--mst-border-strong);
  border-radius: 999px;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-micro);
  line-height: 1.5;
}
.explo__notice--mode { align-items: flex-start; }
.explo__notice--mode .explo-ico { margin-top: 2px; }
.explo-ligne .explo-col,
.explo__entete .explo-colonnes,
.explo__pied { display: none; }

/* ============================================================
   Les huit affichages de Windows (2026-09-19).

   Roméo : « modifier le type d'affichage dans l'explorateur de Bebsolo
   comme dans Windows ». La liste porte data-affichage (le mode) et
   data-disposition (tuiles, flux, colonnes, tableau, mosaiques, contenu) :
   TOUTE la mise en page se décide ici, le JS ne construit qu'une anatomie
   (case, visuel, textes). Chaque disposition tient à 360 px sans faire
   défiler la page en largeur.

   Teintes par famille. --explo-t-* : icône posée sur le FOND de
   l'application, donc liée au thème. --explo-m-* : « marque » d'une grande
   icône (pastille, montagnes, pellicule) posée sur sa page blanche — la même
   dans les deux thèmes, comme les icônes de Windows 11. Le cockpit n'a qu'un
   thème, sombre (tokens.css) ; le jeu clair attend :root[data-theme="light"].
   ============================================================ */
.explo {
  --explo-t-dossier: #f2bd42;
  --explo-t-image: #45bfca;
  --explo-t-pdf: #f36b5f;
  --explo-t-word: #5b9cf5;
  --explo-t-excel: #3dbd78;
  --explo-t-powerpoint: #f58152;
  --explo-t-texte: #aab5c2;
  --explo-t-archive: #deac4f;
  --explo-t-audio: #ee78b0;
  --explo-t-video: #ab8ff2;
  --explo-t-code: #93a3ff;
  --explo-t-fichier: #9aa7b4;
  --explo-m-image: #0e7c86;
  --explo-m-pdf: #c7271b;
  --explo-m-word: #185abd;
  --explo-m-excel: #107c41;
  --explo-m-powerpoint: #c43e1c;
  --explo-m-texte: #5f6b7a;
  --explo-m-archive: #a06c00;
  --explo-m-audio: #b4236b;
  --explo-m-video: #6b3fb5;
  --explo-m-code: #4052b5;
  --explo-m-fichier: #6b7785;
  --explo-dossier-face: #f7c948;
  --explo-dossier-dos: #d69a1f;
  --explo-page: #f7f9fb;
  --explo-page-coin: #dde3ea;
  --explo-page-bord: #8d98a5;
  --explo-soleil: #f2bd42;
}
:root[data-theme="light"] .explo {
  --explo-t-dossier: #b27a00;
  --explo-t-image: #0e7c86;
  --explo-t-pdf: #c7271b;
  --explo-t-word: #185abd;
  --explo-t-excel: #107c41;
  --explo-t-powerpoint: #c43e1c;
  --explo-t-texte: #5f6b7a;
  --explo-t-archive: #8a5d00;
  --explo-t-audio: #b4236b;
  --explo-t-video: #6b3fb5;
  --explo-t-code: #4052b5;
  --explo-t-fichier: #6b7785;
  --explo-page: #ffffff;
  --explo-page-coin: #e4e8ee;
  --explo-page-bord: #9aa4b0;
}
[data-famille="dossier"] { --explo-teinte: var(--explo-t-dossier); }
[data-famille="image"] { --explo-teinte: var(--explo-t-image); --explo-marque: var(--explo-m-image); }
[data-famille="pdf"] { --explo-teinte: var(--explo-t-pdf); --explo-marque: var(--explo-m-pdf); }
[data-famille="word"] { --explo-teinte: var(--explo-t-word); --explo-marque: var(--explo-m-word); }
[data-famille="excel"] { --explo-teinte: var(--explo-t-excel); --explo-marque: var(--explo-m-excel); }
[data-famille="powerpoint"] { --explo-teinte: var(--explo-t-powerpoint); --explo-marque: var(--explo-m-powerpoint); }
[data-famille="texte"] { --explo-teinte: var(--explo-t-texte); --explo-marque: var(--explo-m-texte); }
[data-famille="archive"] { --explo-teinte: var(--explo-t-archive); --explo-marque: var(--explo-m-archive); }
[data-famille="audio"] { --explo-teinte: var(--explo-t-audio); --explo-marque: var(--explo-m-audio); }
[data-famille="video"] { --explo-teinte: var(--explo-t-video); --explo-marque: var(--explo-m-video); }
[data-famille="code"] { --explo-teinte: var(--explo-t-code); --explo-marque: var(--explo-m-code); }
[data-famille="fichier"] { --explo-teinte: var(--explo-t-fichier); --explo-marque: var(--explo-m-fichier); }
.explo-ico--famille, .explo-grand { color: var(--explo-teinte, var(--explo-t-fichier)); }
.explo-ico .p-face { fill: var(--explo-dossier-face); stroke: var(--explo-dossier-dos); stroke-width: 1.1; stroke-linejoin: round; }

/* Grandes icônes : aplats, traits fins quelle que soit la taille. */
.explo-grand { display: block; width: 100%; height: 100%; overflow: visible; }
.explo-grand .g-page,
.explo-grand .g-cadre { fill: var(--explo-page); stroke: var(--explo-page-bord); stroke-width: 1.25px; vector-effect: non-scaling-stroke; }
.explo-grand .g-coin { fill: var(--explo-page-coin); stroke: var(--explo-page-bord); stroke-width: 1.25px; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.explo-grand .g-ligne { fill: none; stroke: var(--explo-marque, var(--explo-m-fichier)); stroke-opacity: 0.35; stroke-width: 2; stroke-linecap: round; }
[data-famille="texte"] .explo-grand .g-ligne { stroke-opacity: 0.7; }
.explo-grand .g-marque,
.explo-grand .g-mont { fill: var(--explo-marque, var(--explo-m-fichier)); }
.explo-grand .g-lettre { fill: #fff; font-family: var(--mst-font-sans); font-weight: var(--mst-fw-bold); }
.explo-grand .g-blanc { fill: #fff; }
.explo-grand .g-blanc-trait { fill: none; stroke: #fff; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.explo-grand .g-dos { fill: var(--explo-dossier-dos); }
.explo-grand .g-face { fill: var(--explo-dossier-face); }
.explo-grand .g-soleil { fill: var(--explo-soleil); }
.explo-grand .g-zip { fill: none; stroke: var(--explo-marque, var(--explo-m-archive)); stroke-width: 3; }

/* Le bouton « Afficher » et son menu (positionné sur l'écran, jamais hors de lui). */
.explo-btn--affichage .explo-ico--chevron { flex-basis: 12px; width: 12px; height: 12px; color: var(--mst-text-secondary); }
.explo-menu__fond { position: fixed; inset: 0; z-index: 59; }
.explo-menu {
  position: fixed;
  z-index: 60;
  display: flex;
  flex-direction: column;
  min-width: 232px;
  max-width: calc(100vw - 16px);
  padding: 4px;
  border: var(--mst-border-w) solid var(--mst-border-strong);
  border-radius: var(--mst-radius-md);
  background: var(--mst-bg-surface-2);
  box-shadow: var(--mst-elevation-modal);
}
.explo-menu__item {
  display: grid;
  grid-template-columns: 10px 16px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 42px;
  padding: 0 10px 0 6px;
  border: 0;
  border-radius: var(--mst-radius-sm);
  background: none;
  color: var(--mst-text-primary);
  font: inherit;
  font-size: var(--mst-fs-body);
  text-align: left;
  cursor: pointer;
}
.explo-menu__item:hover { background: var(--mst-bg-surface); }
.explo-menu__item:focus-visible { outline: 0; background: var(--mst-bg-surface); box-shadow: var(--mst-focus-ring); }
.explo-menu__item[aria-checked="true"] { font-weight: var(--mst-fw-medium); }
.explo-menu__puce { justify-self: center; width: 6px; height: 6px; border-radius: 50%; background: currentColor; visibility: hidden; }
.explo-menu__item[aria-checked="true"] .explo-menu__puce { visibility: visible; }
.explo-menu__libelle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.explo-menu__touche { display: none; color: var(--mst-text-muted); font-size: var(--mst-fs-micro); font-variant-numeric: tabular-nums; }

/* L'anatomie commune des sept affichages hors Détails. */
.explo__elements { min-width: 0; }
.explo-el { position: relative; min-width: 0; border-radius: var(--mst-radius-sm); }
.explo-el:hover { background: var(--mst-bg-surface-2); }
.explo-el.is-selection { background: var(--mst-accent-bg); box-shadow: inset 0 0 0 1px var(--mst-accent); }
.explo-el.is-cache { opacity: 0.7; }
.explo-el.is-interdite .explo-el__nom { color: var(--mst-text-muted); }
.explo-el__ouvrir {
  display: flex;
  align-items: center;
  width: 100%;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: inherit;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.explo-el__ouvrir:focus-visible { outline: 0; box-shadow: var(--mst-focus-ring); }
.explo-el__case { display: flex; align-items: center; justify-content: center; cursor: pointer; }
.explo-el__case input { width: 18px; height: 18px; margin: 0; cursor: pointer; accent-color: var(--mst-accent); }
.explo-el__visuel { position: relative; display: flex; flex: 0 0 auto; align-items: center; justify-content: center; }
.explo-el__icone { display: block; width: 100%; height: 100%; }
.explo-el__vignette {
  position: absolute;
  inset: 0;
  z-index: 0;
  max-width: 100%;
  max-height: 100%;
  margin: auto;
  border-radius: 2px;
  opacity: 0;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45), 0 2px 6px rgba(0, 0, 0, 0.35);
  transition: opacity var(--mst-motion-fast) var(--mst-easing);
}
.explo-el__visuel.a-vignette > .explo-el__vignette { opacity: 1; }
.explo-el__visuel.a-vignette > .explo-el__icone { visibility: hidden; }
.explo-el__texte { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; }
.explo-el__nomligne { display: flex; align-items: center; gap: 4px; min-width: 0; }
.explo-el__nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.explo-el__type,
.explo-el__taille { overflow: hidden; color: var(--mst-text-secondary); font-size: var(--mst-fs-micro); line-height: var(--mst-lh-micro); text-overflow: ellipsis; white-space: nowrap; }
.explo-el__verrou { display: inline-flex; flex: 0 0 auto; color: var(--mst-sem-arbitration); }
.explo-el__verrou .explo-ico { flex-basis: 12px; width: 12px; height: 12px; }
.explo-el__badge {
  position: absolute;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  background: var(--mst-bg-surface);
  box-shadow: 0 0 0 1px var(--mst-border-strong);
}
.explo-el__badge .explo-ico { flex-basis: 12px; width: 12px; height: 12px; }
.explo-el__badge--lien { bottom: 0; left: 0; color: var(--mst-accent); }
.explo-el__badge--verrou { right: 0; bottom: 0; color: var(--mst-sem-arbitration); }

/* Très grandes / Grandes / Icônes moyennes : la grille de tuiles. */
.explo__liste[data-affichage="tres_grandes"] { --explo-tuile: 272px; --explo-visuel: 256px; }
.explo__liste[data-affichage="grandes"] { --explo-tuile: 132px; --explo-visuel: 112px; }
.explo__liste[data-affichage="moyennes"] { --explo-tuile: 90px; --explo-visuel: 56px; }
.explo__elements--tuiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--explo-tuile), 1fr));
  gap: 4px;
  padding: var(--mst-sp-2);
}
[data-disposition="tuiles"] .explo-el__ouvrir { flex-direction: column; justify-content: flex-start; gap: 6px; padding: 8px 6px 10px; text-align: center; }
[data-disposition="tuiles"] .explo-el__visuel { width: min(100%, var(--explo-visuel)); aspect-ratio: 1 / 1; }
[data-disposition="tuiles"] .explo-el__texte { width: 100%; align-items: center; }
[data-disposition="tuiles"] .explo-el__nomligne { justify-content: center; max-width: 100%; }
[data-disposition="tuiles"] .explo-el__nom {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  font-size: var(--mst-fs-meta);
  line-height: var(--mst-lh-meta);
  white-space: normal;
  overflow-wrap: anywhere;
}
[data-disposition="tuiles"] .explo-el__case { position: absolute; top: 2px; left: 2px; z-index: 2; width: 32px; height: 32px; }

/* Petites icônes (flux de gauche à droite) et Liste (colonnes de haut en bas). */
.explo__elements--flux { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 0 4px; padding: 4px; }
.explo__elements--colonnes { padding: 4px; column-gap: 4px; columns: 240px; }
.explo__elements--colonnes > .explo-el { break-inside: avoid; }
[data-disposition="flux"] .explo-el,
[data-disposition="colonnes"] .explo-el { display: flex; align-items: stretch; min-height: 30px; }
[data-disposition="flux"] .explo-el__case,
[data-disposition="colonnes"] .explo-el__case { flex: 0 0 28px; }
[data-disposition="flux"] .explo-el__ouvrir,
[data-disposition="colonnes"] .explo-el__ouvrir { flex: 1 1 auto; gap: 8px; padding: 4px 8px 4px 0; }
[data-disposition="flux"] .explo-el__visuel,
[data-disposition="colonnes"] .explo-el__visuel { width: 16px; height: 16px; }

/* Mosaïques : icône moyenne, nom / type / taille sur trois lignes. */
.explo__elements--mosaiques {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr));
  gap: 4px;
  padding: var(--mst-sp-2);
}
/* La case vit dans sa propre gouttière : posée sur l'icône de 48 px, elle en
   mangeait le coin (vu au téléphone le 2026-09-19). */
[data-disposition="mosaiques"] .explo-el { display: flex; align-items: stretch; }
[data-disposition="mosaiques"] .explo-el__case { flex: 0 0 34px; }
[data-disposition="mosaiques"] .explo-el__ouvrir { flex: 1 1 auto; gap: 10px; min-height: 66px; padding: 8px 10px 8px 0; }
[data-disposition="mosaiques"] .explo-el__visuel { width: 48px; height: 48px; }
[data-disposition="mosaiques"] .explo-el__texte { gap: 1px; }

/* Contenu : une ligne par élément, le détail à droite. */
.explo__elements--contenu { display: flex; flex-direction: column; }
[data-disposition="contenu"] .explo-el { display: flex; align-items: stretch; border-bottom: var(--mst-border-w) solid var(--mst-border); border-radius: 0; }
[data-disposition="contenu"] .explo-el:last-child { border-bottom: 0; }
[data-disposition="contenu"] .explo-el__case { flex: 0 0 44px; }
[data-disposition="contenu"] .explo-el__ouvrir { flex: 1 1 auto; gap: var(--mst-sp-3); min-height: 60px; padding: 8px var(--mst-sp-3) 8px 0; }
[data-disposition="contenu"] .explo-el__visuel { width: 44px; height: 44px; }
[data-disposition="contenu"] .explo-el__texte { gap: 2px; }
[data-disposition="contenu"] .explo-el__nom { font-weight: var(--mst-fw-medium); }
.explo-el__droite {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  max-width: 45%;
  min-width: 0;
  color: var(--mst-text-secondary);
  font-size: var(--mst-fs-micro);
  font-variant-numeric: tabular-nums;
  line-height: var(--mst-lh-micro);
  text-align: right;
}
.explo-el__droite > span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.explo-el__etiquette { color: var(--mst-text-muted); }

/* Détails sur un écran assez large : de vraies colonnes, comme Windows. */
@media (min-width: 720px) {
  .explo-ligne { min-height: 40px; }
  .explo-ligne__ouvrir,
  .explo__entete .explo-colonnes {
    display: grid;
    grid-template-columns: 16px minmax(0, 1fr) 136px 196px 76px;
    align-items: center;
    column-gap: var(--mst-sp-3);
  }
  .explo__entete .explo-colonnes { flex: 1 1 auto; min-width: 0; padding-right: var(--mst-sp-3); }
  .explo-colonnes .explo-col--nom { grid-column: 1 / 3; }
  .explo-ligne .explo-col {
    display: block;
    min-width: 0;
    overflow: hidden;
    color: var(--mst-text-secondary);
    font-size: var(--mst-fs-meta);
    font-variant-numeric: tabular-nums;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .explo-ligne .explo-col--taille { text-align: right; }
  /* Les colonnes remplacent la méta-ligne — dans les lignes de Détails
     SEULEMENT. Posée sur toutes les .explo-ligne__meta, la règle effaçait
     aussi l'espace libre des lecteurs et le chemin des dossiers personnels
     à l'accueil (vu sur le téléphone de Roméo, 2026-09-19). */
  .explo-ligne__ouvrir .explo-ligne__meta { display: none; }
  /* La corbeille : Nom · Emplacement d'origine · Date de suppression ·
     Taille · Type, comme Windows. Les colonnes souples en minmax(0, …) :
     un emplacement d'origine long cède la place, il n'élargit rien. */
  .explo__liste[data-vue="corbeille"] .explo-ligne__ouvrir,
  .explo__liste[data-vue="corbeille"] .explo__entete .explo-colonnes {
    grid-template-columns: 16px minmax(0, 1.25fr) minmax(0, 1fr) 132px 76px minmax(0, 160px);
  }
  .explo-ligne__verrou--pc { display: inline-flex; }
  .explo__entete--tableau .explo__entete-compte { display: none; }
  .explo-colonnes .explo-col {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    min-height: 36px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--mst-text-secondary);
    font: inherit;
    font-size: var(--mst-fs-meta);
    text-align: left;
    white-space: nowrap;
  }
  .explo-colonnes button.explo-col { cursor: pointer; }
  .explo-colonnes button.explo-col:hover,
  .explo-colonnes .explo-col.is-tri { color: var(--mst-text-primary); }
  .explo-colonnes button.explo-col:focus-visible { outline: 0; box-shadow: var(--mst-focus-ring); }
  .explo-colonnes .explo-col--taille { justify-content: flex-end; }
  .explo-col__sens { flex-basis: 12px; width: 12px; height: 12px; }
  .explo__liste[data-disposition="tableau"] .explo__pied {
    display: block;
    padding: 6px var(--mst-sp-3);
    border-top: var(--mst-border-w) solid var(--mst-border);
    color: var(--mst-text-secondary);
    font-size: var(--mst-fs-meta);
  }
}

/* Souris : les raccourcis s'affichent dans le menu, et les cases des
   tuiles n'apparaissent qu'au survol ou dès qu'une sélection existe —
   comme les « cases à cocher des éléments » de Windows. Sur écran tactile,
   elles restent TOUJOURS visibles : il n'y a pas de survol. */
@media (hover: hover) and (pointer: fine) {
  .explo-menu__touche { display: inline; }
  .explo-menu__item { min-height: 34px; }
  .explo-el__case { opacity: 0; transition: opacity var(--mst-motion-fast) var(--mst-easing); }
  .explo-el:hover .explo-el__case,
  .explo-el:focus-within .explo-el__case,
  .explo-el.is-selection .explo-el__case,
  .explo__liste.a-selection .explo-el__case { opacity: 1; }
}

/* La barre de la sélection : collée en bas de l'écran, à portée de pouce. */
.explo__selection { display: none; }
.explo__selection.is-visible {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: var(--mst-sp-2);
  border: var(--mst-border-w) solid var(--mst-accent);
  border-radius: var(--mst-radius-md);
  background: var(--mst-bg-surface-2);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.35);
}
.explo__selection-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--mst-sp-2); }
.explo__compte { color: var(--mst-text-secondary); font-size: var(--mst-fs-meta); }
.explo__actions--selection {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
}
/* Un libellé long (« Supprimer définitivement ») passe à la ligne DANS son
   bouton au lieu d'en toucher le bord : une case de grille ne s'élargit pas
   pour son contenu (vu à 360 px, 2026-09-19). */
.explo__actions--selection .explo-btn {
  min-width: 0;
  padding-top: 4px;
  padding-bottom: 4px;
  line-height: 1.2;
  text-align: center;
  white-space: normal;
}
.explo__champ { display: none; }

.explo-journal__modal { display: flex; flex-direction: column; width: min(720px, 94vw); max-height: 80vh; }
.explo-journal__tete { display: flex; align-items: center; justify-content: space-between; gap: var(--mst-sp-2); }
.explo-journal { display: flex; flex-direction: column; overflow-y: auto; font-size: var(--mst-fs-meta); }
.explo-journal__ligne {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--mst-sp-2);
  padding: 6px 0;
  border-bottom: var(--mst-border-w) solid var(--mst-border);
}
.explo-journal__date { color: var(--mst-text-muted); font-variant-numeric: tabular-nums; }
.explo-journal__op { font-weight: var(--mst-fw-medium); }
.explo-journal__quoi { flex: 1 1 100%; min-width: 0; overflow: hidden; color: var(--mst-text-secondary); text-overflow: ellipsis; white-space: nowrap; }
.explo-journal__ligne.is-ok .explo-journal__issue { color: var(--mst-state-done); }
.explo-journal__ligne.is-erreur .explo-journal__issue,
.explo-journal__ligne.is-partiel .explo-journal__issue { color: var(--mst-sem-escalation); }

@media (max-width: 600px) {
  /* 24 px de marge de chaque côté sur un écran de 360 : c'est un septième de
     la largeur perdu. L'Explorateur reprend 16 px. */
  .main--explorateur { padding: var(--mst-sp-2); }
  /* Les outils gardent leurs icônes ; leurs libellés cèdent la place (le
     titre et l'aria-label les portent toujours). */
  .explo__outils .explo-btn__txt { display: none; }
  .explo__outils .explo-btn { min-width: 40px; padding: 0 8px; }

  /* Les huit affichages au téléphone : 2 / 3 / 4 colonnes de tuiles, deux
     colonnes de petites icônes, une seule colonne de Liste, des cibles de
     44 px sous le pouce. */
  .explo__liste[data-affichage="tres_grandes"] { --explo-visuel: 100%; }
  .explo__liste[data-affichage="grandes"] { --explo-visuel: 84px; }
  .explo__liste[data-affichage="moyennes"] { --explo-visuel: 52px; }
  .explo__elements--tuiles { gap: 2px; padding: 6px; }
  .explo__liste[data-affichage="tres_grandes"] .explo__elements--tuiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .explo__liste[data-affichage="grandes"] .explo__elements--tuiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .explo__liste[data-affichage="moyennes"] .explo__elements--tuiles { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  [data-disposition="tuiles"] .explo-el__ouvrir { padding: 6px 4px 8px; }
  .explo__elements--flux { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .explo__elements--colonnes { columns: 1; }
  [data-disposition="flux"] .explo-el,
  [data-disposition="colonnes"] .explo-el { min-height: 44px; }
  [data-disposition="flux"] .explo-el__case,
  [data-disposition="colonnes"] .explo-el__case { flex-basis: 36px; }
  .explo__elements--mosaiques { padding: 6px; }
  [data-disposition="contenu"] .explo-el__visuel { width: 40px; height: 40px; }
  .explo-el__etiquette,
  .explo-el__heure { display: none; }
}

/* ==========================================================================
   Onglet Remote (2026-09-20) — le bureau du PC dans un canvas.

   La scène occupe toute la hauteur restante et ne défile PAS à la main :
   `overflow: hidden` avec un `scrollLeft`/`scrollTop` piloté par les gestes à
   deux doigts (remote.js). `touch-action: none` est indispensable : sans lui
   Android intercepte le glissé pour faire défiler la PAGE, et plus aucun
   mouvement de souris n'arrive jusqu'au PC.
   ========================================================================== */
/* `flex-basis: 0px`, et PAS le `0%` de `.main` — mesure du 2026-09-20 sur
   1280 × 800 : la page faisait 912 px de haut pour un écran de 800. La barre
   de réglages (Qualité, zoom, Ctrl+Alt+Suppr) était posée à y = 900, cent
   pixels SOUS l'écran : introuvable sans faire défiler la page.

   `#app` n'a qu'un `min-height: 100vh` : sa hauteur dépend donc de son
   contenu, et contre une hauteur indéfinie un `flex-basis` en POUR CENT
   retombe sur `auto`, c'est-à-dire sur le contenu. `.main` redemandait alors
   la hauteur de la scène, la scène celle de la cible, la cible celle que
   `appliquerZoom()` venait de lui écrire en pixels : la vue FABRIQUAIT sa
   propre hauteur au lieu de prendre celle qui restait. Une longueur, elle,
   est définie : la contribution intrinsèque retombe à 0, `min-height: 100vh`
   l'emporte, et la scène reçoit exactement la place disponible. */
.main--remote {
  display: flex; flex-direction: column; min-height: 0; flex-basis: 0px;
  /* Comme l'Explorateur au téléphone, mais PARTOUT : sur cet onglet les 24 px
     de marge de `.main` sont 48 px de hauteur repris à l'image, et il n'y a
     rien à aérer — la page entière est un écran. */
  padding: var(--mst-sp-2);
}

.remote {
  display: flex;
  flex-direction: column;
  /* Quatre interlignes à 8 px, c'est 32 px d'image en moins. À 4, l'en-tête,
     les avis et la barre restent lisibles et la vue y gagne. */
  gap: var(--mst-sp-1);
  flex: 1;
  min-height: 0;
  min-width: 0;
}
/* ---- Les deux agrandissements (2026-09-20, soir) ----------------------------
   Roméo a entouré en rouge la place que prenait l'écran distant, en vert celle
   qu'il doit prendre : TOUTE la zone de la page, sous la barre d'adresse.
   Mesuré sur 1280 × 800, écran distant 1920 × 1080 : la vue normale donne
   933 × 525 à l'image (47,9 % de la page), la vue agrandie 1280 × 720 (90 %)
   — 1,88 fois la surface. Sur un téléphone en paysage (915 × 412), 11,4 %
   deviennent 80 %.

   UNE SEULE mise en page pour les deux modes. « Agrandir » est notre
   superposition (`position: fixed`, toute la zone de la page) ; « Plein
   écran » est l'API du navigateur sur la MÊME section (tout l'écran
   physique). Ce qu'ils couvrent diffère, ce qu'on y voit non — et `inset: 0`
   reste juste dans les deux cas, l'élément plein écran étant lui aussi posé
   sur son conteneur plein écran.  */
.remote--immersif {
  position: fixed;
  inset: 0;
  /* Au-dessus du bandeau collant (10), de la bannière de redémarrage (40),
     des menus de l'Explorateur (60) et des panneaux modaux (1000/1100). */
  z-index: 1200;
  margin: 0;
  padding: 0;
  gap: 0;
  background: #000;
  border-radius: 0;
}
/* La page dessous ne défile plus : un glissé qui rate la vue ne doit pas
   emmener la plateforme ailleurs pendant qu'on regarde le bureau. */
html.is-remote-immersif,
html.is-remote-immersif body { overflow: hidden; }
/* Le mobilier ordinaire s'efface : tout est passé dans la barre flottante,
   qui s'efface elle-même. Deux jeux de boutons visibles en même temps
   reprendraient la place qu'on vient de gagner. */
.remote--immersif > .remote__tete,
.remote--immersif > .remote__avis,
.remote--immersif > .remote__barre,
.remote--immersif > .remote__pied { display: none; }
.remote--immersif .remote__scene {
  flex: 1;
  min-height: 0;
  border: 0;
  border-radius: 0;
  background: #000;
}
/* Dernier recours : un navigateur qui passerait la section en plein écran
   sans que le script ait posé la classe (course à l'affichage) ne doit pas
   rendre un cadre de 260 px au milieu du noir. */
.remote:fullscreen { background: #000; padding: 0; gap: 0; }
.remote:fullscreen .remote__scene { border: 0; border-radius: 0; }

/* La barre flottante : le seul mobilier des vues agrandies. Elle s'efface
   d'elle-même après quelques secondes et revient au moindre geste — jamais
   `display: none`, sinon elle ne pourrait pas se fondre, et jamais sans
   `pointer-events: none`, sinon une barre invisible volerait le bas de
   l'écran du PC. */
.remote__flottante {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  z-index: 3;
  display: none;
  flex-direction: column;
  gap: var(--mst-sp-1);
  /* `width: max-content` est indispensable avec `left: 50%` : sans elle, la
     largeur disponible d'une boîte absolue n'est que la MOITIÉ de la scène
     (mesuré : 640 px sur 1280), et la barre se repliait sur deux lignes de
     94 px de haut pour sept boutons qui tiennent sur une. */
  width: max-content;
  max-width: calc(100% - 20px);
  padding: 8px;
  border-radius: var(--mst-radius-md);
  background: rgba(11, 14, 20, .9);
  border: var(--mst-border-w) solid var(--mst-border-strong);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .6);
  /* La scène est en `touch-action: none` pour que le glissé parte au PC ;
     la barre, elle, redevient une barre de boutons ordinaire. */
  touch-action: auto;
  transition: opacity var(--mst-motion-base) var(--mst-easing);
}
.remote--immersif .remote__flottante { display: flex; }
.remote__flottante.is-effacee { opacity: 0; pointer-events: none; }
/* Masquée EXPRÈS (2026-09-29) : elle ne se fond pas, elle disparaît. Une
   barre « effacée » se réveille au moindre geste ; une barre masquée ne
   revient que sur demande, par la poignée de rappel. Les deux états ne se
   ressemblent pas, et c'est voulu. */
.remote__flottante.is-masquee { display: none; }
.remote__rangee--flottante { flex-wrap: wrap; justify-content: center; }

/* ---- Les quatre ancrages de la barre (2026-09-29) --------------------------
   Roméo : « Est-ce que tu peux rajouter la possibilité de la déplacer pour la
   mettre à gauche, à droite, en haut ou en bas de l'écran ? »

   Un seul attribut (`data-ancrage`) commande la position ET l'orientation :
   posée en haut ou en bas, la barre est une RANGÉE ; posée à gauche ou à
   droite, une COLONNE — sinon elle déborderait des deux côtés d'un téléphone
   en portrait. Dans les deux cas elle ne dépasse jamais la scène :
   `max-height` + défilement interne, parce qu'une barre plus haute que
   l'écran n'a plus ni début ni fin. */
.remote__flottante[data-ancrage="bas"] {
  left: 50%; right: auto; top: auto; bottom: 14px;
  transform: translateX(-50%);
}
.remote__flottante[data-ancrage="haut"] {
  left: 50%; right: auto; top: 14px; bottom: auto;
  transform: translateX(-50%);
}
.remote__flottante[data-ancrage="gauche"],
.remote__flottante[data-ancrage="droite"] {
  top: 50%; bottom: auto;
  transform: translateY(-50%);
  max-height: calc(100% - 20px);
  overflow-y: auto;
  overflow-x: hidden;
}
.remote__flottante[data-ancrage="gauche"] { left: 10px; right: auto; }
.remote__flottante[data-ancrage="droite"] { right: 10px; left: auto; }
.remote__flottante[data-ancrage="gauche"] .remote__rangee--flottante,
.remote__flottante[data-ancrage="droite"] .remote__rangee--flottante {
  flex-direction: column;
  /* `center` et non `stretch` : sinon les boutons à icône prennent la largeur
     du plus bavard (« Ctrl+Alt+Suppr ») et la colonne devient un mur. */
  align-items: center;
  flex-wrap: nowrap;
}
/* En colonne, les libellés seraient trois fois plus larges que les icônes :
   la barre mangerait le tiers de l'écran pour du texte qui tient déjà dans
   l'infobulle et l'`aria-label`. La SORTIE, elle, garde le sien. */
.remote__flottante[data-ancrage="gauche"] .remote-btn:not(.is-sortie) .remote-btn__txt,
.remote__flottante[data-ancrage="droite"] .remote-btn:not(.is-sortie) .remote-btn__txt {
  display: none;
}
.remote__flottante[data-ancrage="gauche"] .remote-tch--large,
.remote__flottante[data-ancrage="droite"] .remote-tch--large { min-width: 0; }
/* Pendant le glissé : on voit où elle va, on ne devine pas. */
.remote__flottante.is-deplacee {
  outline: 2px dashed var(--mst-accent);
  outline-offset: 2px;
}

/* La poignée de déplacement. `touch-action: none` est INDISPENSABLE : sans
   elle Android prend le glissé pour un défilement de page et le `pointermove`
   n'arrive jamais. `cursor: move` dit ce qu'elle fait avant qu'on l'essaie. */
.remote__poignee {
  cursor: move;
  touch-action: none;
  padding: 0 8px;
  color: var(--mst-text-muted);
}
.remote__poignee:hover { color: var(--mst-text-primary); }

/* LA POIGNÉE DE RAPPEL : ce qui reste quand la barre est masquée.
   Un petit onglet collé au bord, au même endroit que la barre qu'il rappelle,
   assez discret pour ne rien cacher de l'image et assez grand pour un pouce
   (2026-09-29). Sans elle, masquer serait piéger. */
.remote__rappel {
  position: absolute;
  z-index: 4;
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  min-height: 34px;
  padding: 0;
  border: var(--mst-border-w) solid var(--mst-border-strong);
  border-radius: var(--mst-radius-md);
  background: rgba(11, 14, 20, .78);
  color: var(--mst-text-secondary);
  cursor: pointer;
  touch-action: auto;
}
.remote__rappel.is-visible { display: inline-flex; }
.remote__rappel:hover { color: var(--mst-text-primary); }
.remote__rappel[data-ancrage="bas"] { left: 50%; bottom: 10px; transform: translateX(-50%); }
.remote__rappel[data-ancrage="haut"] { left: 50%; top: 10px; transform: translateX(-50%); }
.remote__rappel[data-ancrage="gauche"] { left: 6px; top: 50%; transform: translateY(-50%); }
.remote__rappel[data-ancrage="droite"] { right: 6px; top: 50%; transform: translateY(-50%); }
.remote__rappel svg { width: 16px; height: 16px; display: block; }
/* « Bureau réel » : la bannière ne disparaît pas parce que l'image grandit. */
.remote__reel {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--mst-fs-meta); color: var(--mst-state-done);
}
.remote__reel::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--mst-state-done);
}
/* L'indice de sortie, quelques secondes en entrant : on ne cache jamais le
   moyen d'en sortir, on le rappelle. Dans la scène, donc visible aussi en
   plein écran — ce qu'un toast posé sur le <body> ne serait pas. */
.remote__indice {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 3; display: none; pointer-events: none;
  padding: 6px 14px; border-radius: var(--mst-radius-pill);
  background: rgba(11, 14, 20, .9); color: var(--mst-text-secondary);
  border: var(--mst-border-w) solid var(--mst-border);
  font-size: var(--mst-fs-meta);
}
.remote__indice.is-visible { display: block; }
/* Barre ancrée en HAUT : l'indice descend, sinon les deux se superposent et
   on ne lit ni l'un ni l'autre (constaté à la première mesure des ancrages,
   2026-09-29). L'ordre du DOM (barre, rappel, indice) rend le sélecteur
   frère valable. */
.remote__flottante[data-ancrage="haut"] ~ .remote__indice {
  top: auto; bottom: 14px;
}

.remote__tete { display: flex; flex-wrap: wrap; align-items: center; gap: var(--mst-sp-2); }
.remote__titre {
  display: flex; align-items: center; gap: var(--mst-sp-2);
  margin: 0; font-size: var(--mst-fs-display); color: var(--mst-text-primary);
}
.remote__ico svg, .remote-btn__ico svg { width: 16px; height: 16px; display: block; }
.remote__infos { display: flex; flex-wrap: wrap; align-items: center; gap: var(--mst-sp-2); }
.remote__meta { color: var(--mst-text-muted); font-size: var(--mst-fs-meta); font-variant-numeric: tabular-nums; }
.remote__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--mst-sp-1); margin-left: auto; }

.remote__pastille {
  padding: 2px 8px; border-radius: var(--mst-radius-pill);
  font-size: var(--mst-fs-meta); border: var(--mst-border-w) solid var(--mst-border);
  color: var(--mst-text-secondary);
}
.remote__pastille.is-ok { color: var(--mst-state-done); border-color: var(--mst-state-done); }
.remote__pastille.is-pret { color: var(--mst-accent); border-color: var(--mst-accent); }
.remote__pastille.is-ko { color: var(--mst-sem-escalation); border-color: var(--mst-sem-escalation); }

.remote__avis { display: flex; flex-direction: column; gap: var(--mst-sp-1); }
.remote__avis-ligne {
  margin: 0; padding: 8px 10px; border-radius: var(--mst-radius-sm);
  font-size: var(--mst-fs-body); border-left: 3px solid var(--mst-border);
  background: var(--mst-bg-surface); color: var(--mst-text-secondary);
}
.remote__avis-ligne.is-actif { border-left-color: var(--mst-state-done); color: var(--mst-text-primary); }
.remote__avis-ligne.is-attention { border-left-color: var(--mst-sem-directive); }
.remote__avis-ligne.is-erreur { border-left-color: var(--mst-sem-escalation); }

/* Un avis qu'on peut ranger — et qui reste rangé sur cet appareil. L'avis des
   raccourcis du navigateur est vrai une fois pour toutes, et il coûtait 52 px
   de hauteur à CHAQUE session : autant de moins pour l'image. `<details>`
   natif : le pli est au clavier et au lecteur d'écran sans une ligne de
   script. La flèche est un TRACÉ SVG — un pictogramme Unicode absent des
   polices d'Android s'affiche en carré vide (2026-08-25). */
.remote__pliable { padding: 6px 10px; }
.remote__pliable > summary {
  display: flex; align-items: center; gap: 6px;
  cursor: pointer; list-style: none;
  font-size: var(--mst-fs-meta); color: var(--mst-text-secondary);
}
.remote__pliable > summary::-webkit-details-marker { display: none; }
.remote__pliable-fleche svg { width: 12px; height: 12px; display: block; }
.remote__pliable-fleche { transition: transform var(--mst-motion-fast) var(--mst-easing); }
.remote__pliable[open] .remote__pliable-fleche { transform: rotate(90deg); }
.remote__pliable-corps { margin: 6px 0 0; }

.remote__scene {
  position: relative;
  flex: 1;
  /* Un plancher, pas une hauteur : la vue prend la place qui reste. Et le
     plancher CÈDE sur un écran bas — mesuré sur un téléphone en paysage
     (915 × 412), 260 px fixes faisaient redéfiler la page que le reste du
     chantier venait d'arrêter de faire défiler. */
  min-height: min(260px, 40vh);
  overflow: hidden;
  touch-action: none;
  background: #0b0e14;
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-md);
}
.remote__cible { width: 100%; height: 100%; }
/* Le temps d'un glissé de la barre, la vue ne reçoit RIEN : déplacer notre
   barre ne doit jamais devenir un glissé sur le vrai bureau (2026-09-29). */
.remote__cible.is-inerte { pointer-events: none; }
/* Le champ qui fait monter le clavier d'Android : présent, focusable, mais
   invisible. `display:none` ou `visibility:hidden` l'empêcheraient de prendre
   le focus, donc d'ouvrir le clavier — c'est tout l'intérêt du procédé. */
.remote__saisie {
  position: absolute; top: 0; left: 0;
  width: 1px; height: 1px; padding: 0; border: 0;
  opacity: 0; resize: none; z-index: 2;
  color: transparent; background: transparent;
}

.remote__barre { display: flex; flex-direction: column; gap: var(--mst-sp-1); }
.remote__rangee { display: flex; flex-wrap: wrap; gap: var(--mst-sp-1); align-items: center; }
.remote__rangee--fonctions { overflow-x: auto; flex-wrap: nowrap; }
.remote__zoom { color: var(--mst-text-muted); font-size: var(--mst-fs-meta); font-variant-numeric: tabular-nums; }

.remote-btn, .remote-tch {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; min-height: 36px; padding: 0 10px;
  border: var(--mst-border-w) solid var(--mst-border);
  border-radius: var(--mst-radius-sm);
  background: var(--mst-bg-surface); color: var(--mst-text-primary);
  font-size: var(--mst-fs-body); cursor: pointer;
}
.remote-btn:hover:not(:disabled), .remote-tch:hover { border-color: var(--mst-border-strong); }
.remote-btn:disabled { opacity: .5; cursor: not-allowed; }
/* Une action en cours se VOIT, mais le bouton reste cliquable : un bouton
   éteint ne dit rien, et « rien » est ce que Roméo a vu sur son téléphone
   le 2026-09-20. C'est l'action qui sait où elle en est, pas le DOM. */
.remote-btn[aria-busy="true"] { opacity: .75; }
/* Le seul reste du clavier tactile sur un ordinateur : un bouton effacé, qui
   déplie les touches spéciales pour qui en a besoin. */
.remote-btn.is-discret { color: var(--mst-text-muted); }
.remote-btn.is-discret.is-actif { color: var(--mst-accent); }
.remote-btn.is-primaire { background: var(--mst-accent); border-color: var(--mst-accent); color: #fff; }
.remote-btn.is-danger, .remote-tch.is-danger { color: var(--mst-sem-escalation); }
.remote-btn.is-actif { border-color: var(--mst-accent); color: var(--mst-accent); }
.remote-tch { min-width: 42px; font-variant-numeric: tabular-nums; }
.remote-tch--large { min-width: 92px; }
.remote-tch.is-arme { background: var(--mst-accent-bg); border-color: var(--mst-accent); color: var(--mst-accent); }

/* Ce qui a raté, écrit en toutes lettres et QUI RESTE (2026-09-29).
   Le 2026-09-29, tout ce que le téléphone de Roméo disait d'une connexion
   morte était une infobulle de QUATRE SECONDES, vingt secondes après le clic,
   dans un coin. Une erreur du client s'affiche maintenant en haut de l'onglet
   et y reste jusqu'à la connexion suivante. */
.remote__erreur { display: flex; flex-direction: column; gap: 4px; }
.remote__erreur p { margin: 0; }
.remote__erreur-titre { color: var(--mst-text-primary); font-weight: 600; }
.remote__erreur-detail {
  font-family: var(--mst-font-mono, monospace);
  font-size: var(--mst-fs-meta);
  word-break: break-word;
}
.remote__erreur-conseil { color: var(--mst-text-secondary); }
.remote__erreur-trace { color: var(--mst-text-muted); font-size: var(--mst-fs-meta); }

/* L'ERGONOMIE DU DOIGT SUIT UNE CAPACITÉ, PAS UNE LARGEUR (2026-09-29).
   Un téléphone en « Site pour ordinateur » met en page sur ~980 px : aucune
   requête de média « écran étroit » ne s'y déclenche, et il recevait donc des
   cibles de 36 px sur un écran de 412 px réels. `remote--tactile` est posée
   par `estTactile()`, la même mesure que le reste de l'onglet. */
.remote--tactile .remote-btn,
.remote--tactile .remote-tch { min-height: 44px; }
.remote--tactile .remote__actions { margin-left: 0; width: 100%; }
.remote--tactile .remote__rangee--modif,
.remote--tactile .remote__rangee--fleches { flex-wrap: nowrap; overflow-x: auto; }

@media (max-width: 600px) {
  /* Les libellés cèdent la place ; le titre et l'aria-label les portent.
     SAUF `is-sortie` : ce qui permet d'ENTRER dans la prise de contrôle, d'en
     SORTIR et de se déconnecter garde son nom. Mesure du 2026-09-29 : la
     capture de Roméo ne montrait que deux carrés sans un mot — « on ne sait
     pas lequel connecte ». On ne réduit jamais à un pictogramme à deviner ce
     dont dépend le fait d'être connecté ou non. */
  .remote__actions .remote-btn:not(.is-sortie) .remote-btn__txt,
  .remote__flottante .remote-btn:not(.is-sortie) .remote-btn__ico + .remote-btn__txt { display: none; }
  .remote__actions .remote-btn:not(.is-sortie),
  .remote__flottante .remote-btn { min-width: 44px; padding: 0 10px; }
  .remote__flottante { padding: 6px; max-width: calc(100% - 12px); }
  .remote__flottante[data-ancrage="bas"] { bottom: 10px; }
  .remote__flottante[data-ancrage="haut"] { top: 10px; }
  /* 44 px sous le pouce : la cible minimale utilisable. */
  .remote-btn, .remote-tch { min-height: 44px; }
  .remote__titre { font-size: var(--mst-fs-title); }
  .remote__actions { margin-left: 0; width: 100%; }
  .remote__rangee--modif, .remote__rangee--fleches { flex-wrap: nowrap; overflow-x: auto; }
}
