@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

/* Palette TendersPage : navy / indigo / cobalt / ambre, fond gris clair, cartes
 * blanches. Les noms de variables historiques (creme/encre/laiton…) sont
 * conservés pour ne pas casser les ~400 références dans le reste du fichier ;
 * seules leurs VALEURS changent. Les noms sémantiques ont été ajoutés en alias
 * (--bg-page, --accent, --text…) pour les nouveaux composants. */
:root {
  /* Nouveaux noms sémantiques (à privilégier dans le code futur) */
  --bg-page:         #f4f5f8;     /* fond général de la page */
  --bg-page-strong:  #e9ecf1;     /* fond accentué (creme-fonce) */
  --card:            #ffffff;     /* fond des cartes */
  --text:            #23272f;     /* texte principal */
  --text-soft:       #4a5060;     /* texte secondaire */
  --text-muted:      #737b86;     /* texte mute */
  --border:          #dde1e8;     /* bordures fines */
  --border-strong:   #c5cbd4;     /* bordures appuyées */
  --accent:          #3865c8;     /* bleu cobalt (liens, accents) */
  --accent-strong:   #2e5bba;     /* bleu cobalt foncé (hover) */
  --accent-soft:     #dce7fb;     /* bleu cobalt clair (chips, halos) */
  --primary:         #4f4e91;     /* indigo violet (headers, primary) */
  --primary-strong:  #3f3e7a;     /* indigo violet foncé (hover) */
  --navy:            #1f2a4f;     /* navy de la sidebar TendersPage */
  --amber:           #f0a030;     /* badge / notification orange */
  --amber-soft:      #fde9c8;     /* tint clair de l'amber */
  /* Sous-brique ④ — token violet (conseil_type = 'redactionnel'). Miroir
   * docx-common COLOR.violet + COLOR.violetSoft. Contraste 5.9:1 sur blanc. */
  --color-conseil-redactionnel:      #6b4fa0;
  --color-conseil-redactionnel-soft: #e8dff3;

  /* Alias historiques (mêmes noms qu'avant, nouvelles valeurs) */
  --creme:           var(--bg-page);
  --creme-fonce:     var(--bg-page-strong);
  --encre:           var(--text);
  --encre-doux:      var(--text-soft);
  --encre-tres-doux: var(--text-muted);
  --trait:           var(--border);
  --trait-fort:      var(--border-strong);
  --laiton:          var(--accent);
  --laiton-fonce:    var(--accent-strong);
  --laiton-clair:    var(--accent-soft);
  --blanc:           var(--card);

  /* Statuts (inchangés sémantiquement) */
  --go:              #2f6b3a;     /* vert (recommandation GO) */
  --nogo:            #9b2c2c;     /* rouge (NO_GO) */
  --arbitrer:        #d97706;     /* ambre (A_ARBITRER) */

  /* Lifting agenda §1.4 — palette source (couleur fixe par SOURCE, jamais par
     item). Trois teintes du produit : bleu cobalt (marché), violet (jalon —
     dérivé du token conseil-rédactionnel), vert (coffre — teinte GO). Les
     variantes -soft servent au fond doux des chips, la teinte pleine à la
     barre gauche de 3 px et à la puce de légende. */
  --agenda-src-marche:      var(--accent);              /* #3865c8 bleu   */
  --agenda-src-marche-soft: var(--accent-soft);         /* #dce7fb        */
  --agenda-src-jalon:       var(--color-conseil-redactionnel);      /* #6b4fa0 violet */
  --agenda-src-jalon-soft:  var(--color-conseil-redactionnel-soft); /* #e8dff3        */
  --agenda-src-coffre:      var(--go);                  /* #2f6b3a vert   */
  --agenda-src-coffre-soft: #e3efe4;                    /* miroir .state-pill-go */
  /* J-C — 4e source `company_event` : orange brûlé, chaud, distinct des
     bleu/violet/vert et des points d'urgence rouge/ambre. */
  --agenda-src-event:       #c65f1c;                    /* orange brûlé  */
  --agenda-src-event-soft:  #fbe5d4;                    /* soft assorti  */
  /* Points d'urgence (mois) — le canal URGENCE se dit désormais par un point
     coloré `•`, pas par un fond qui recouvrirait la couleur de source. */
  --agenda-urg-urgente-dot: #a32a2a;                    /* rouge */
  --agenda-urg-proche-dot:  #8a5a07;                    /* ambre */

  /* Lifting passe 2 décision 1 — fond des cases par TEMPORALITÉ.
     Passée = blanc (défaut de la carte). Courante+future = bleu ciel doux
     (dérivé léger du bleu produit --accent #3865c8 — mêmes règles pour
     grille Mois, colonnes Semaine, mini-cases du mini-calendrier dashboard).
     Aujourd'hui GARDE son liseré is-today (règle indépendante). Contraste
     des chips sur ce fond vérifié — les .agenda-chip[data-source] posent
     leur propre fond -soft qui reste discriminant sur bleu ciel. */
  --agenda-jour-futur: #eef4fd;

  /* Typo : Inter pour tout, plus de serif (Fraunces retiré). --serif et
   * --sans coexistent par compat ; les deux pointent vers Inter. */
  --serif: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --sans:  'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --radius:   10px;
  --radius-s: 7px;
  /* Ombres relevées d'un cran pour ancrer les cartes sur le fond gris clair. */
  --shadow-s: 0 1px 2px rgba(35,39,47,0.06);
  --shadow:   0 2px 4px rgba(35,39,47,0.05), 0 14px 28px -10px rgba(35,39,47,0.14);
  --shadow-l: 0 4px 8px rgba(35,39,47,0.07), 0 28px 56px -16px rgba(35,39,47,0.20);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--sans);
  background: var(--bg-page);
  color: var(--text);
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--sans);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.18;
  margin: 0 0 12px;
  color: var(--text);
}
h1 { font-size: clamp(26px, 3.2vw, 36px); font-weight: 600; }
h2 { font-size: clamp(19px, 1.8vw, 23px); font-weight: 600; }
h3 { font-size: 16px; font-weight: 600; }
h4 { font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-soft); }

p { margin: 0 0 12px; }
a  { color: var(--laiton); text-decoration: none; transition: color .15s ease; }
a:hover { color: var(--encre); }

.muted       { color: var(--encre-doux); }
.subdued     { color: var(--encre-tres-doux); font-size: 14px; }
.eyebrow     { font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--encre-tres-doux); font-weight: 500; }

/* ─────────────── Topbar / navigation ─────────────── */
.topbar {
  background: var(--navy);
  position: sticky; top: 0; z-index: 50;
  /* Halo diffus sous la topbar pour ancrer la barre sur le fond gris clair.
   * Le bandeau gradient fin (::after) ajoute l'accent de couleur, en rappel
   * de la bannière (navy → indigo → cobalt). */
  box-shadow: 0 6px 20px -6px rgba(31,42,79,0.30);
}
.topbar::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -3px;
  height: 3px;
  background: linear-gradient(90deg, var(--navy) 0%, var(--primary) 50%, var(--accent) 100%);
  pointer-events: none;
}
.topbar-inner {
  max-width: 1180px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
  padding: 12px 28px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: #ffffff;
  text-decoration: none;
}
.brand:hover { color: #ffffff; opacity: 0.92; }
.brand strong { font-weight: 700; color: var(--amber); }
/* Le repère graphique : l'icône TendersPage (globe + nœuds) sur fond navy.
 * Conservé sous le même nom .brand-mark pour rétro-compat HTML existant. */
.brand-mark {
  display: inline-block;
  width: 60px; height: 60px;
  background: url('/logo-tp-ia.png') center/cover no-repeat;
  border-radius: 10px;
  transform: none;
  vertical-align: middle;
  flex-shrink: 0;
}

/* 5 liens sur UNE SEULE ligne (jamais wrap). Compact pour rentrer dans 1180px
 * avec brand + user-chip. white-space:nowrap au cas où un libellé i18n s'allonge. */
.main-nav {
  display: flex;
  gap: 2px;
  justify-self: center;
  flex-wrap: nowrap;
  white-space: nowrap;
}
.main-nav a {
  font: 500 13.5px var(--sans);
  color: rgba(255,255,255,0.72);
  padding: 7px 12px;
  border-radius: 6px;
  white-space: nowrap;
  transition: all .15s ease;
}
.main-nav a:hover { color: #ffffff; background: rgba(255,255,255,0.08); }
.main-nav a.active {
  color: #ffffff;
  background: var(--accent);
  font-weight: 600;
  box-shadow: 0 2px 8px -2px rgba(46,91,186,0.55);
}

/* Tous les éléments du user-chip sont posés sur la topbar navy : textes clairs,
 * pills avec une lueur blanche très douce pour ressortir sans agresser. */
.user-chip {
  display: flex; align-items: center; gap: 10px;
  font-size: 14px;
  color: rgba(255,255,255,0.85);
}
.credits-pill {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 6px 13px;
  border: 1px solid rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.08);
  border-radius: 999px;
  font-size: 13px;
}
.credits-pill strong { font-family: var(--sans); font-weight: 700; font-size: 14px; color: #ffffff; }
.credits-pill .credits-label { color: rgba(255,255,255,0.65); font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; }
.user-name { font-weight: 500; color: #ffffff; }
.user-role { color: rgba(255,255,255,0.6); font-size: 12px; }
.user-chip .ghost.small { color: rgba(255,255,255,0.8); }
.user-chip .ghost.small:hover { color: #ffffff; background: rgba(255,255,255,0.10); }

/* ─────────────── Sélecteur de langue (topbar) ─────────────── */
.lang-switcher {
  width: auto;
  margin: 0;
  padding: 5px 24px 5px 10px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: rgba(255,255,255,0.95);
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.20);
  border-radius: 999px;
  cursor: pointer;
}
.lang-switcher:hover { color: #ffffff; background: rgba(255,255,255,0.14); border-color: rgba(255,255,255,0.30); }
.lang-switcher:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Les options du select natif s'affichent sur fond du système (clair) : forcer
 * un fond clair lisible pour ne pas hériter du navy. */
.lang-switcher option { color: var(--text); background: var(--card); }

/* Pages publiques (index, rejoindre, admin) : la topbar est en navy, donc tout
 * lien .muted inline doit basculer en clair pour rester lisible. */
.topbar a.muted, .topbar .muted { color: rgba(255,255,255,0.72); }
.topbar a.muted:hover { color: #ffffff; }
.topbar .brand .muted { color: rgba(255,255,255,0.72); }

/* ─────────────── Shell : sidebar + main (espace entreprise) ───────────────
 * Inspiration TendersPage (sidebar persistante d'environnements) dans la
 * charte TPIA — navy dominant, indigo/cobalt en accent, Inter. La sidebar
 * apparaît UNIQUEMENT après `renderTopbar(activeKey, me)` (cf. common.js
 * → ensureShellLayout) ; les pages publiques (login, admin) gardent la
 * topbar pleine largeur sans shell. */
body.has-shell {
  display: grid;
  grid-template-columns: 268px 1fr;
  min-height: 100vh;
}
body.has-shell .shell-main { min-width: 0; }
/* Topbar du shell : fond CLAIR (la sidebar porte le navy à elle seule).
 * Séparation discrète par une fine bordure inférieure + ombre subtile à
 * la sticky pour détacher du contenu sans alourdir. Le bandeau gradient
 * historique (::after) est désactivé — il alourdissait la transition
 * sidebar navy → topbar blanche. */
body.has-shell .topbar {
  background: var(--card);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 0 var(--border), 0 4px 12px -8px rgba(31, 42, 79, 0.10);
}
body.has-shell .topbar::after { display: none; }
body.has-shell .wrap { max-width: 1100px; padding: 32px 32px 96px; }
body.has-shell .shell-drawer-overlay { display: none; }

.shell-sidebar {
  position: sticky; top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
  background: linear-gradient(180deg, var(--navy) 0%, #182240 100%);
  color: rgba(255,255,255,0.9);
  border-right: 1px solid rgba(255,255,255,0.06);
  padding: 18px 14px 24px;
  display: flex; flex-direction: column;
  z-index: 60;
}

.sidebar-brand {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px 18px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  margin-bottom: 16px;
}
.sidebar-brand-link {
  display: inline-flex; align-items: center; gap: 10px;
  color: #fff; text-decoration: none;
  font-size: 15px; font-weight: 600;
}
.sidebar-brand-link strong { color: var(--amber); font-weight: 700; }
.sidebar-brand-name { display: inline; }
.sidebar-brand .brand-mark { width: 36px; height: 36px; border-radius: 8px; }
.sidebar-drawer-close {
  display: none;
  background: transparent; border: none; color: rgba(255,255,255,0.7);
  width: 36px; height: 36px; border-radius: 8px; cursor: pointer;
  align-items: center; justify-content: center;
}
.sidebar-drawer-close:hover { background: rgba(255,255,255,0.08); color: #fff; }

.sidebar-eyebrow {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.12em;
  color: rgba(255,255,255,0.45);
  padding: 0 10px 8px;
}
.sidebar-nav { display: flex; flex-direction: column; gap: 6px; }

.sidebar-env {
  padding: 12px 12px 10px;
  border-radius: 10px;
  transition: background 0.15s ease;
}
.sidebar-env.is-active.is-current {
  background: rgba(255,255,255,0.04);
  box-shadow: inset 3px 0 0 var(--accent);
}
.sidebar-env-head {
  display: flex; align-items: center; gap: 10px;
  color: #fff;
  font-size: 14px; font-weight: 600;
  letter-spacing: -0.005em;
  text-decoration: none;
  padding: 2px 0 2px;
}
.sidebar-env-head-link:hover { opacity: 0.92; }
/* Étape 6.1 — l'en-tête d'environnement EST le lien Accueil ; il prend
 * un fond surbrillance quand activeKey='home' (homeKey de l'env). Comme
 * pour .sidebar-item.is-active, fond cobalt + texte blanc. */
.sidebar-env-head-link.is-head-active {
  background: var(--accent);
  border-radius: 8px;
  padding: 8px 10px;
  margin: -2px -10px;
  box-shadow: 0 2px 6px -2px rgba(46, 91, 186, 0.55);
}
.sidebar-env-head-link.is-head-active:hover { opacity: 1; background: var(--accent-strong); }
.sidebar-env-icon {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 7px;
  background: rgba(255,255,255,0.08);
  color: rgba(255,255,255,0.92);
  flex-shrink: 0;
}
.sidebar-env.is-current .sidebar-env-icon {
  background: var(--primary);
  color: #fff;
}
.sidebar-env-label { flex: 1 1 auto; }
.sidebar-coming-badge {
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 3px 8px;
  background: var(--amber-soft);
  color: #8a5a07;
  border-radius: 999px;
}
/* Chantier « Discussions » geste ÉCRAN — badge chiffré `total_unread` sur
 * l'entrée Discussion. Palette accent (cobalt) : signal actif, pas d'alerte.
 * Se lit à côté du libellé, ne pousse pas la description. */
.sidebar-env-unread-badge {
  font-size: 11px; font-weight: 700;
  min-width: 18px; height: 18px;
  padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent);
  color: #fff;
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  margin-left: auto;
}
.sidebar-env-head-link.is-head-active .sidebar-env-unread-badge {
  /* En état actif (surbrillance cobalt) le badge doit se distinguer : on
   * l'inverse — fond blanc, texte cobalt — pour rester visible sur le cobalt. */
  background: #fff;
  color: var(--accent);
}
.sidebar-env-desc {
  font-size: 12px;
  /* Gris très clair, bien contrasté sur le navy. 75 % de blanc → ratio
   * AA atteint pour du texte ≥ 12 px sur le fond navy de la sidebar. */
  color: rgba(255,255,255,0.78);
  margin: 4px 0 0 38px;
  line-height: 1.35;
}
/* État « Bientôt » : on garde les libellés en BLANC (lisibles) et la
 * description en gris clair, comme l'état actif. Le signal « non cliquable »
 * passe par cursor:not-allowed + le badge « Bientôt » + un icône légèrement
 * estompé — pas par une chute d'opacité globale qui rendait tout illisible. */
.sidebar-env.is-coming { cursor: not-allowed; }
.sidebar-env.is-coming .sidebar-env-head { color: #fff; }
.sidebar-env.is-coming .sidebar-env-desc { color: rgba(255,255,255,0.72); }
.sidebar-env.is-coming .sidebar-env-icon {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.78);
}

.sidebar-items {
  display: flex; flex-direction: column; gap: 2px;
  margin: 10px 0 0 0;
}
.sidebar-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px 8px 14px;
  border-radius: 7px;
  font-size: 13.5px;
  color: rgba(255,255,255,0.72);
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}
.sidebar-item:hover { background: rgba(255,255,255,0.06); color: #fff; }
.sidebar-item.is-active {
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 2px 6px -2px rgba(46, 91, 186, 0.55);
}
.sidebar-item.is-active:hover { background: var(--accent-strong); }
.sidebar-item-icon {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; color: inherit; opacity: 0.85;
}
.sidebar-item.is-active .sidebar-item-icon { opacity: 1; }

/* --- Topbar slim (avec shell, fond clair) -------------------------- */
.topbar-slim {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 28px;
  max-width: none;
}
.topbar-spacer { flex: 1 1 auto; }
.topbar-hamburger {
  display: none;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-soft);
  width: 38px; height: 38px;
  border-radius: 8px;
  cursor: pointer;
  align-items: center; justify-content: center;
  transition: background 0.15s ease, color 0.15s ease;
}
.topbar-hamburger:hover {
  background: var(--bg-page);
  color: var(--navy);
  border-color: var(--border-strong);
}

/* Crédits pill, sur fond CLAIR (mode shell) — bordure cobalt fin, fond
 * accent-soft pour signaler la cliquabilité, texte navy pour la lisibilité.
 * Les styles globaux (.credits-pill) restent pour la topbar navy des pages
 * publiques/admin ; on surcharge UNIQUEMENT dans le shell. */
body.has-shell .credits-pill {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-strong);
}
body.has-shell .credits-pill strong { color: var(--navy); }
body.has-shell .credits-pill .credits-label {
  color: var(--accent-strong);
  opacity: 0.8;
}
body.has-shell .credits-pill .icon { color: var(--accent); }
body.has-shell .credits-pill-link { text-decoration: none; cursor: pointer; transition: background 0.15s ease, border-color 0.15s ease, transform 0.12s ease; }
body.has-shell .credits-pill-link:hover {
  background: var(--accent);
  border-color: var(--accent-strong);
  transform: translateY(-1px);
}
body.has-shell .credits-pill-link:hover strong,
body.has-shell .credits-pill-link:hover .credits-label,
body.has-shell .credits-pill-link:hover .icon { color: #fff; opacity: 1; }

/* Anneau de complétude du profil dans la topbar (shell). Ton sobre : ambre
 * tant que <100 %, vert discret à 100 % — jamais rouge (encouragement, pas
 * alerte). Visible partout via renderTopbar(). */
body.has-shell .profile-pill {
  display: inline-flex; align-items: center; gap: 8px;
  height: 32px; padding: 0 12px;
  border: 1px solid var(--border);
  background: var(--card);
  border-radius: 999px;
  text-decoration: none;
  font: 600 13px/1 var(--sans);
  color: var(--text-soft);
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
}
body.has-shell .profile-pill:hover {
  background: var(--bg-page);
  border-color: var(--border-strong);
  color: var(--text);
  transform: translateY(-1px);
}
body.has-shell .profile-pill-progress { border-color: var(--amber); background: var(--amber-soft); color: #8a5a07; }
body.has-shell .profile-pill-progress:hover { background: var(--amber); color: #fff; }
body.has-shell .profile-pill-progress:hover .profile-ring circle:last-child { stroke: #fff; }
body.has-shell .profile-pill-complete { border-color: rgba(47,107,58,0.4); color: var(--go); background: rgba(47,107,58,0.08); }
body.has-shell .profile-pill-complete:hover { background: var(--go); color: #fff; }
body.has-shell .profile-ring { display: block; flex-shrink: 0; }

/* Mobile : on garde l'anneau seul, le texte est masqué (les hover labels
 * apparaissent dans l'attribut title). */
@media (max-width: 720px) {
  body.has-shell .profile-pill { padding: 0 8px; }
  body.has-shell .profile-pill .profile-pill-label { display: none; }
}

/* Sélecteur de langue sur fond clair */
body.has-shell .topbar-slim .lang-switcher {
  color: var(--text-soft);
  background: var(--card);
  border-color: var(--border);
}
body.has-shell .topbar-slim .lang-switcher:hover {
  color: var(--navy);
  background: var(--bg-page);
  border-color: var(--border-strong);
}

/* Bouton compte sur fond clair — sobre, le dropdown apporte la couleur */
.account-trigger {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 10px 6px 14px;
  border-radius: 999px;
  font: 500 13.5px var(--sans);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.account-trigger:hover { background: var(--bg-page); border-color: var(--border-strong); }
.account-trigger-name { color: var(--navy); font-weight: 500; }
.account-trigger .user-role { color: var(--text-muted); font-size: 12px; }
.account-trigger .icon { color: var(--text-muted); }
body.account-menu-open .account-trigger {
  background: var(--bg-page);
  border-color: var(--accent);
}
body.account-menu-open .account-trigger .icon { color: var(--accent); }

/* Menu compte (dropdown) */
.account-menu {
  position: absolute; top: calc(100% + 6px); right: 16px;
  min-width: 220px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  box-shadow: 0 12px 32px -10px rgba(31, 42, 79, 0.30);
  padding: 6px;
  z-index: 70;
  display: none;
}
body.account-menu-open .account-menu { display: block; }
.account-menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  font-size: 14px;
  color: var(--text);
  text-decoration: none;
  border-radius: 6px;
  cursor: pointer;
  background: transparent;
  border: none;
  width: 100%;
  text-align: left;
}
.account-menu-item:hover { background: var(--bg-page); }
.account-menu-icon { color: var(--text-muted); display: inline-flex; flex-shrink: 0; }
.account-menu-logout {
  margin-top: 4px;
  border-top: 1px solid var(--border);
  border-radius: 0 0 6px 6px;
  padding-top: 10px;
  color: var(--nogo);
}
.account-menu-logout .account-menu-icon { color: var(--nogo); }

/* --- Responsive : sidebar repliée en drawer overlay ---------------- */
@media (max-width: 1024px) {
  body.has-shell { grid-template-columns: 1fr; }
  body.has-shell .shell-sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 280px;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    z-index: 90;
  }
  body.has-shell.shell-open .shell-sidebar { transform: translateX(0); }
  body.has-shell .shell-drawer-overlay {
    display: block;
    position: fixed; inset: 0;
    background: rgba(15, 22, 44, 0.45);
    z-index: 80;
    opacity: 0; pointer-events: none;
    transition: opacity 0.22s ease;
  }
  body.has-shell.shell-open .shell-drawer-overlay {
    opacity: 1; pointer-events: auto;
  }
  body.has-shell .sidebar-drawer-close { display: inline-flex; }
  body.has-shell .topbar-hamburger { display: inline-flex; }
  body.has-shell .wrap { padding: 24px 18px 80px; }
}

@media (max-width: 560px) {
  .topbar-slim { padding: 10px 16px; gap: 10px; }
  .account-trigger-name { max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .credits-pill .credits-label { display: none; }
  .topbar-slim .lang-switcher { padding: 5px 22px 5px 10px; }
}

/* ─────────────── Layout ─────────────── */
.wrap         { max-width: 1180px; margin: 0 auto; padding: 36px 28px 96px; }
.wrap.narrow  { max-width: 720px; }
.page-header  { margin-bottom: 28px; padding-bottom: 24px; border-bottom: 1px solid var(--trait); }
.page-header h1 { margin-bottom: 6px; }
.page-header .lead { color: var(--encre-doux); margin: 0; font-size: 16px; }

/* ─────────────── Cards ─────────────── */
.card {
  background: var(--blanc);
  border: 1px solid var(--trait);
  border-radius: var(--radius);
  padding: 28px;
  margin: 18px 0;
  box-shadow: var(--shadow);
}
.card.flat { box-shadow: var(--shadow-s); }
.card h2:first-child, .card h3:first-child, .card h4:first-child { margin-top: 0; }
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.card-head h2, .card-head h3 { margin-bottom: 0; }

/* ─────────────── Hero stats (Accueil) ─────────────── */
.hello {
  display: grid;
  grid-template-columns: minmax(0,1fr) auto;
  gap: 24px;
  align-items: end;
  margin-bottom: 28px;
}
.hello h1 { font-size: clamp(28px, 4vw, 40px); font-weight: 600; }
.hello h1 em { font-style: normal; font-weight: 700; color: var(--primary); }
.hello .sub { color: var(--text-soft); margin-top: 6px; }
.hero-cta button {
  font-size: 15px;
  padding: 12px 22px;
}

.stats {
  display: grid;
  /* Grille adaptative — s'ajuste au nombre de tuiles rendues. Le J4 a
     retiré la tuile Complétude ; auto-fit garantit que les 2 tuiles
     restantes prennent toute la largeur sans laisser de trou, et que
     le prochain ajout/retrait n'a pas besoin de toucher au nombre de
     colonnes. min=240px : cohérent avec les autres grilles KPI du repo
     (220-260px), et le pied « Un Go/No-Go consomme 1 crédit... » tient
     sur une ligne au-delà de ce seuil. */
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin-bottom: 32px;
}
.stat {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 24px;
  position: relative;
  overflow: hidden;
  box-shadow: var(--shadow);
}
.stat::after {
  content: '';
  position: absolute; right: -40px; top: -40px;
  width: 140px; height: 140px;
  background: radial-gradient(circle, rgba(79,78,145,0.10), transparent 70%);
  pointer-events: none;
}
.stat .eyebrow { margin-bottom: 12px; }
.stat .value {
  font-family: var(--sans);
  font-weight: 700;
  font-size: clamp(30px, 4.2vw, 42px);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--primary);
}
.stat .value-sub {
  display: inline-block;
  margin-left: 6px;
  font-family: var(--sans);
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 500;
}
.stat .footnote { color: var(--encre-doux); font-size: 13px; margin-top: 10px; }

/* ─────────────── Forms ─────────────── */
label {
  display: block;
  font-size: 13px;
  margin: 14px 0 6px;
  color: var(--encre-doux);
  font-weight: 500;
}
label .req { color: var(--laiton); margin-left: 2px; }
input, select, textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--trait);
  border-radius: var(--radius-s);
  background: var(--blanc);
  font: 15px/1.5 var(--sans);
  color: var(--encre);
  transition: border-color .12s ease, box-shadow .12s ease;
}
input::placeholder, textarea::placeholder { color: var(--encre-tres-doux); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--laiton);
  box-shadow: 0 0 0 3px rgba(56,101,200,0.18);
}
textarea { min-height: 90px; resize: vertical; }
.field-help { font-size: 12px; color: var(--encre-tres-doux); margin-top: 4px; }
.row { display: flex; gap: 14px; flex-wrap: wrap; }
.row > * { flex: 1 1 220px; }

/* ─────────────── Buttons ─────────────── */
/* Tous les boutons d'action primaires sont indigo (var(--primary)). On
 * applique le style indigo À LA RACINE pour que les <button> sans classe
 * (submit d'inscription/connexion, page rejoindre, admin login…) héritent
 * automatiquement de la charte — plus aucun bouton primaire ne reste noir.
 * .secondary et .ghost gardent leur traitement neutre. */
button {
  font: 500 14px var(--sans);
  cursor: pointer;
  border: none;
  border-radius: var(--radius-s);
  padding: 10px 18px;
  background: var(--primary);
  color: #ffffff;
  box-shadow: 0 2px 6px -1px rgba(79,78,145,0.35), 0 1px 0 rgba(255,255,255,0.06) inset;
  transition: background .15s ease, box-shadow .15s ease, transform .05s ease;
}
button:hover {
  background: var(--primary-strong);
  box-shadow: 0 4px 12px -2px rgba(79,78,145,0.45);
}
button:active { transform: translateY(1px); }
/* .primary devient un alias explicite — utile pour la lisibilité du HTML. */
button.primary {
  background: var(--primary);
  color: #ffffff;
  box-shadow: 0 2px 6px -1px rgba(79,78,145,0.35), 0 1px 0 rgba(255,255,255,0.06) inset;
}
button.primary:hover {
  background: var(--primary-strong);
  box-shadow: 0 4px 12px -2px rgba(79,78,145,0.45);
}
/* .secondary : neutre, encadrée. Annule l'ombre indigo de la racine. */
button.secondary {
  background: transparent;
  color: var(--encre);
  border: 1px solid var(--trait);
  box-shadow: none;
}
button.secondary:hover {
  background: var(--creme-fonce);
  border-color: var(--trait-fort);
  box-shadow: none;
}
/* .ghost : texte/lien, sans fond. Annule aussi l'ombre indigo. */
button.ghost {
  background: transparent;
  color: var(--encre-doux);
  padding: 6px 10px;
  box-shadow: none;
}
button.ghost:hover {
  color: var(--encre);
  background: var(--creme-fonce);
  box-shadow: none;
}
button.small { padding: 6px 12px; font-size: 13px; }
button:disabled { opacity: .4; cursor: not-allowed; transform: none; }

.action-bar { display: flex; gap: 10px; align-items: center; margin-top: 18px; flex-wrap: wrap; }
.action-bar .grow { flex: 1; }

/* ─────────────── Completion gauge ─────────────── */
.gauge {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px; align-items: center;
}
.gauge-bar {
  height: 6px;
  background: var(--creme-fonce);
  border-radius: 999px;
  overflow: hidden;
}
.gauge-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--primary));
  transition: width .5s cubic-bezier(.2,.7,.3,1);
}
.gauge-label {
  font: 600 13px var(--sans);
  color: var(--encre);
  white-space: nowrap;
}

/* ─────────────── Profile tabs layout ─────────────── */
.tabs-layout {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 36px;
  align-items: start;
}
.tabs-list {
  position: sticky;
  top: 88px;
  background: var(--blanc);
  border: 1px solid var(--trait);
  border-radius: var(--radius);
  padding: 14px;
  box-shadow: var(--shadow-s);
}
/* Neutralisation scopée du margin .card pour aligner le panneau actif sur la sidebar. */
.tabs-layout article.card.tab-panel { margin-top: 0; }
.tabs-list .eyebrow { padding: 4px 10px 8px; }
.tab-item {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-s);
  font: 500 14px var(--sans);
  color: var(--encre-doux);
  background: transparent;
  border: none;
  text-align: left;
  cursor: pointer;
  margin: 0;
  transition: all .12s ease;
}
.tab-item:hover { background: var(--creme-fonce); color: var(--encre); }
.tab-item.active {
  background: var(--creme);
  color: var(--encre);
  box-shadow: inset 0 0 0 1px var(--trait);
}
.tab-item .tab-pct {
  font: 600 12px var(--serif);
  color: var(--encre-tres-doux);
  font-variant-numeric: tabular-nums;
}
.tab-item.active .tab-pct { color: var(--laiton); }

.tab-panel { display: none; }
.tab-panel.active { display: block; }
.tab-panel .panel-head { margin-bottom: 18px; }
.tab-panel .panel-head h2 { margin-bottom: 6px; }
.tab-panel .panel-head .panel-desc { color: var(--encre-doux); font-size: 15px; margin: 0; }

.tabs-mobile { display: none; margin-bottom: 18px; }

/* ─────────────── Pills, banners ─────────────── */
.pill {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.pill.GO { background: #e3efe4; color: var(--go); }
.pill.NO_GO { background: #f4e1e1; color: var(--nogo); }
.pill.A_ARBITRER { background: var(--amber-soft); color: var(--arbitrer); }
.pill.pill-available { background: var(--laiton-clair); color: var(--laiton-fonce); }
.pill.pill-soon { background: var(--creme-fonce); color: var(--encre-tres-doux); }

/* ─────────────── Profil incomplet — CTA d'accueil ─────────────── */
.profile-cta {
  border-left: 4px solid var(--amber);
  background: linear-gradient(180deg, var(--amber-soft), var(--card) 70%);
  margin-bottom: 22px;
}
.profile-cta-head .eyebrow { color: var(--arbitrer); margin-bottom: 6px; }
.profile-cta-head h2 { margin: 0 0 6px; }
.profile-cta-list {
  margin: 14px 0 18px;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px 22px;
}
.profile-cta-list li {
  display: flex; align-items: center; gap: 10px;
  font-size: 14px;
  color: var(--text);
}
.profile-cta-dot {
  display: inline-block;
  width: 8px; height: 8px;
  background: var(--amber);
  border-radius: 999px;
  flex-shrink: 0;
}
.profile-cta-actions {
  display: flex; align-items: center; gap: 16px;
  flex-wrap: wrap;
}

/* ─────────────── Types d'analyse (Accueil) ─────────────── */
.analysis-types-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}
.analysis-type {
  border: 1px solid var(--trait);
  border-radius: var(--radius-s);
  padding: 18px 20px;
  background: var(--creme);
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: border-color .12s ease, background .12s ease;
}
.analysis-type.is-available { background: var(--blanc); border-color: var(--trait-fort); }
.analysis-type.is-soon { opacity: 0.72; }
.analysis-type-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
}
.analysis-type-head h3 { margin: 0; font-size: 16px; font-weight: 500; }
.analysis-type-desc { margin: 0; color: var(--encre-doux); font-size: 14px; line-height: 1.5; }
.analysis-type-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: auto; padding-top: 4px;
}
.analysis-type-cost {
  font-size: 13px;
  color: var(--encre-doux);
  font-variant-numeric: tabular-nums;
}
/* CTA des cartes « Les analyses de la plateforme » (anchor stylé, ex. « Lancer »
 * du Go/No-Go). Aligné sur le traitement indigo des boutons d'action primaires
 * — même couleur, même ombre, même hover, pour la cohérence visuelle. */
.btn-small {
  display: inline-flex; align-items: center;
  padding: 8px 16px;
  background: var(--primary);
  color: #ffffff;
  border: none;
  border-radius: var(--radius-s);
  font-size: 13px; font-weight: 500;
  font-family: var(--sans);
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 2px 6px -1px rgba(79,78,145,0.35), 0 1px 0 rgba(255,255,255,0.06) inset;
  transition: background .15s ease, box-shadow .15s ease;
}
.btn-small:hover {
  background: var(--primary-strong);
  color: #ffffff;
  box-shadow: 0 4px 12px -2px rgba(79,78,145,0.45);
}

.banner {
  border-left: 3px solid var(--arbitrer);
  background: #f6eed6;
  padding: 14px 18px;
  border-radius: var(--radius-s);
  margin: 12px 0;
  font-size: 14px;
}
.banner.ok { border-color: var(--go); background: #e8f1e9; }
.banner strong { font-weight: 600; }

.error { color: var(--nogo); font-size: 13px; margin: 8px 0; min-height: 18px; }
.success { color: var(--go); font-size: 13px; margin: 8px 0; }

/* ─────────────── Tables ─────────────── */
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 12px 10px; border-bottom: 1px solid var(--trait); }
tr:last-child td { border-bottom: 0; }
th {
  font-weight: 500;
  font-size: 11px;
  color: var(--encre-tres-doux);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ─────────────── Password toggle (œil) ─────────────── */
.password-wrap { position: relative; }
.password-wrap > input { padding-right: 42px; }
.password-toggle {
  position: absolute;
  top: 50%;
  right: 8px;
  width: 30px; height: 30px;
  transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  padding: 0;
  color: var(--encre-tres-doux);
  box-shadow: none;
  transition: color .12s ease, background .12s ease;
}
.password-toggle:hover { color: var(--text); background: rgba(35,39,47,0.05); box-shadow: none; }
.password-toggle::before {
  /* Œil "ouvert" — état par défaut (mot de passe masqué). */
  content: '';
  width: 20px; height: 20px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z'/><circle cx='12' cy='12' r='3'/></svg>") center/contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z'/><circle cx='12' cy='12' r='3'/></svg>") center/contain no-repeat;
}
.password-toggle.is-showing::before {
  /* Œil "barré" — mot de passe affiché. */
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M3 3l18 18'/><path d='M10.6 6.2A10.7 10.7 0 0112 6c6.5 0 10 6 10 6a17.7 17.7 0 01-3.2 4.2'/><path d='M6.3 7.5C3.7 9.2 2 12 2 12s3.5 7 10 7c1.7 0 3.2-.4 4.5-1'/><path d='M9.9 9.9a3 3 0 104.2 4.2'/></svg>") center/contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M3 3l18 18'/><path d='M10.6 6.2A10.7 10.7 0 0112 6c6.5 0 10 6 10 6a17.7 17.7 0 01-3.2 4.2'/><path d='M6.3 7.5C3.7 9.2 2 12 2 12s3.5 7 10 7c1.7 0 3.2-.4 4.5-1'/><path d='M9.9 9.9a3 3 0 104.2 4.2'/></svg>") center/contain no-repeat;
}

/* ─────────────── Combo multi-select avec recherche ─────────────── */
.combo-multi { position: relative; margin: 6px 0 12px; }
.combo-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.combo-chips:empty { display: none; }
.combo-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--laiton-clair); border: 1px solid var(--laiton);
  color: var(--encre);
  padding: 4px 4px 4px 12px; border-radius: 999px;
  font-size: 13px; font-weight: 500; line-height: 1.2;
}
.combo-chip > span { white-space: nowrap; }
.combo-chip button {
  width: 22px; height: 22px;
  border: none; background: transparent;
  border-radius: 999px; cursor: pointer;
  color: var(--laiton-fonce); font-size: 16px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  box-shadow: none;
}
.combo-chip button:hover { background: rgba(35,39,47,0.10); color: var(--text); box-shadow: none; }
.combo-search { width: 100%; }
.combo-list {
  position: absolute;
  top: 100%; left: 0; right: 0;
  background: var(--blanc);
  border: 1px solid var(--trait);
  border-radius: var(--radius-s);
  margin: 4px 0 0;
  padding: 4px;
  list-style: none;
  max-height: 280px;
  overflow-y: auto;
  z-index: 30;
  box-shadow: var(--shadow);
}
.combo-list li {
  padding: 8px 10px;
  border-radius: var(--radius-s);
  cursor: pointer;
  display: flex; align-items: baseline; gap: 10px;
  font-size: 14px;
  color: var(--encre);
}
.combo-list li.is-active, .combo-list li:hover { background: var(--creme-fonce); }
.combo-list li.combo-empty {
  cursor: default; color: var(--encre-tres-doux);
  justify-content: center; padding: 14px;
  font-style: italic;
}
.combo-list li.combo-empty:hover { background: transparent; }
.combo-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  color: var(--encre-tres-doux);
  min-width: 24px;
}

/* ─────────────── Liste d'emails (chips + input) ─────────────── */
.emails-list { margin: 6px 0 12px; }
.emails-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.emails-add { display: flex; gap: 8px; align-items: center; }
.emails-add .emails-input { flex: 1; margin: 0; }
.emails-add .emails-add-btn { white-space: nowrap; }
.emails-error { margin-top: 6px; font-size: 13px; }

/* ─────────────── Multicheck ─────────────── */
.multicheck { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0; }
.multicheck label {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px;
  border: 1px solid var(--trait);
  border-radius: 999px;
  background: var(--blanc);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  margin: 0;
  color: var(--encre-doux);
  transition: all .12s ease;
}
.multicheck label:hover { color: var(--encre); border-color: var(--trait-fort); }
.multicheck label:has(input:checked) {
  background: var(--laiton-clair);
  border-color: var(--laiton);
  color: var(--encre);
}
.multicheck input { width: auto; margin: 0; accent-color: var(--laiton); }

/* ─────────────── Recent analyses (Accueil) ─────────────── */
.analyses-list { display: flex; flex-direction: column; gap: 0; }
.analyse-line {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 14px;
  padding: 14px 0;
  border-top: 1px solid var(--trait);
  /* Lignes désormais rendues en <a> pour être cliquables vers le dossier
   * marché — on remet la couleur et la décoration neutres. */
  text-decoration: none;
  color: inherit;
}
.analyse-line:first-child { border-top: 0; }
.analyse-line .title { font-weight: 500; }
.analyse-line .meta { color: var(--encre-doux); font-size: 13px; margin-top: 2px; }

/* ─────────────── Score block (gonogo result) ─────────────── */
.score-block {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 22px;
  padding: 8px 0 20px;
  border-bottom: 1px solid var(--trait);
  margin-bottom: 20px;
}
.score-block .score {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 56px;
  line-height: 1;
  letter-spacing: -0.02em;
}
.score-block .score-sub { color: var(--encre-doux); font-size: 13px; }

/* ─────────────── Login / Signup ─────────────── */
.auth-wrap { max-width: 480px; margin: 48px auto; padding: 0 24px; }
.auth-banner {
  display: block;
  width: 100%;
  max-width: 480px;
  height: auto;
  border-radius: 12px;
  margin: 0 auto 24px;
  box-shadow: var(--shadow);
}
.auth-hero { text-align: center; margin-bottom: 24px; }
.auth-hero h1 { font-size: clamp(24px, 4.5vw, 30px); margin-bottom: 8px; font-weight: 600; }
.auth-hero p { color: var(--text-soft); margin: 0; }
.auth-card { background: var(--blanc); border: 1px solid var(--trait); border-radius: 14px; padding: 30px; box-shadow: var(--shadow-l); }
.tabs-auth {
  display: flex; gap: 4px;
  border-bottom: 1px solid var(--trait);
  margin: -10px -10px 18px;
}
.tabs-auth button {
  flex: 1; background: transparent; color: var(--encre-tres-doux);
  border: none; border-bottom: 2px solid transparent;
  border-radius: 0; padding: 12px 6px;
  font-weight: 500;
  box-shadow: none;
}
.tabs-auth button.active { color: var(--encre); border-bottom-color: var(--laiton); }
.tabs-auth button:hover { background: transparent; color: var(--encre); box-shadow: none; }
.signin-link { text-align: center; margin-top: 18px; color: var(--encre-doux); font-size: 14px; }

ul { margin: 8px 0; padding-left: 20px; }
li { margin: 4px 0; }
code { font-family: 'SF Mono', Consolas, monospace; font-size: 13px; background: var(--creme-fonce); padding: 2px 6px; border-radius: 4px; }

.hide { display: none !important; }

/* ─────────────── Composer d'ingestion unifié (T2 dossier marché) ─────────── */
/* Zone unique : textarea + drag/drop + bouton parcourir. Texte ET fichier
 * passent par le même submit. Conçu pour accueillir plus tard d'autres
 * formats (Word/Excel/ZIP) et l'URL sans changer la mise en page. */
.composer {
  display: flex; flex-direction: column; gap: 12px;
}
.composer-drop {
  position: relative;
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius-s);
  background: var(--bg-page);
  transition: border-color .12s ease, background .12s ease;
  min-height: 140px;
}
.composer-drop:hover,
.composer-drop:focus-within {
  border-color: var(--primary);
}
.composer.is-dragover .composer-drop {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.composer-text {
  width: 100%;
  border: none;
  background: transparent;
  resize: vertical;
  padding: 14px 16px;
  font: 15px/1.55 var(--sans);
  color: var(--text);
  min-height: 140px;
  border-radius: var(--radius-s);
}
.composer-text:focus { outline: none; box-shadow: none; }
.composer-file-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
}
.composer-file-icon { font-size: 22px; }
.composer-file-name {
  font-weight: 600; color: var(--text);
  word-break: break-word;
  flex: 1;
}
.composer-file-meta { white-space: nowrap; }
.composer-file-remove {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  font-size: 16px;
  border-radius: 999px;
}
/* Overlay drop : apparaît au-dessus de la zone pendant un drag actif */
.composer-drop-overlay {
  position: absolute; inset: 6px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-s);
  background: rgba(56,101,200,0.10);
  color: var(--primary);
  font-weight: 600;
  pointer-events: none;
  opacity: 0;
  transition: opacity .12s ease;
}
.composer-drop-overlay.is-visible { opacity: 1; }

.composer-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.composer-hint { font-size: 13px; flex: 1; min-width: 200px; }
.composer-error.grow { flex: 1; }

/* Insertion inline sur la page dossier marché : zone « Ajouter une pièce »
 * basculant entre un bouton et le composer entier. */
.marche-add-piece { margin: 14px 0; }
.marche-add-piece.is-open { padding: 14px; background: var(--bg-page); border-radius: var(--radius-s); border: 1px solid var(--border); }
.marche-add-piece .primary { display: inline-flex; align-items: center; gap: 8px; }

@media (max-width: 720px) {
  .composer-bar { flex-direction: column; align-items: stretch; }
  .composer-hint { flex: none; }
}

/* ─────────────── Dossier marché (brique « Dossier marché ») ─────────────── */
/* Badge de statut — palette alignée sur la charte (vert/ambre/rouge/indigo/neutre). */
.marche-badge {
  display: inline-flex; align-items: center;
  /* Étape 6.2 — padding horizontal resserré pour tenir dans une colonne
   * STATUT compacte (cf. .tenders-table). Le visuel reste un pill cohérent
   * avec les autres badges, juste un peu moins large. */
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px; font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.marche-badge-a_evaluer    { background: var(--bg-page-strong); color: var(--text-soft); }
.marche-badge-no_go        { background: rgba(200,50,50,0.14); color: #a32a2a; }
.marche-badge-a_arbitrer   { background: var(--amber-soft);    color: #8a5a07; }
.marche-badge-go           { background: rgba(46,139,87,0.16); color: #1f7a4d; }
.marche-badge-en_preparation { background: var(--accent-soft); color: var(--primary); }

/* Liste « Mes marchés » : chaque ligne est un lien complet vers le dossier. */
.marches-list {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: 12px;
}
.marche-row { margin: 0; }
.marche-row-link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 18px;
  align-items: center;
  padding: 16px 18px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  color: var(--text);
  text-decoration: none;
  transition: background .12s ease, border-color .12s ease, transform .05s ease;
}
.marche-row-link:hover {
  background: var(--card);
  border-color: var(--primary);
  color: var(--text);
}
.marche-row-link:active { transform: translateY(1px); }
.marche-row-objet {
  font-weight: 600; font-size: 15px; color: var(--text);
  word-break: break-word;
}
.marche-row-meta { font-size: 13px; margin-top: 4px; }
.marche-row-side {
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
  text-align: right;
  white-space: nowrap;
}
.marche-row-activity, .marche-row-last { font-size: 12px; }

/* Page dossier marché : en-tête + meta grid */
.marche-header-back { margin-bottom: 12px; }
.marche-header { background: linear-gradient(135deg, var(--navy) 0%, var(--primary) 100%); color: #fff; border: none; }
.marche-header h1 {
  color: #fff;
  font-size: clamp(22px, 3vw, 30px);
  font-weight: 700;
  margin: 4px 0 12px;
}
.marche-header .eyebrow { color: rgba(255,255,255,0.75); }
.marche-header .small { font-size: 13px; }
.marche-header .muted { color: rgba(255,255,255,0.7); }
.marche-header-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 18px;
  align-items: flex-start;
  margin-bottom: 14px;
}
.marche-header-side {
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
  white-space: nowrap;
}
/* Override des badges sur fond navy/indigo pour rester lisibles */
.marche-header .marche-badge-a_evaluer { background: rgba(255,255,255,0.18); color: #ffffff; }
.marche-header .marche-badge-no_go     { background: rgba(255,255,255,0.92); color: #a32a2a; }
.marche-header .marche-badge-a_arbitrer{ background: var(--amber); color: var(--navy); }
.marche-header .marche-badge-go        { background: rgba(255,255,255,0.92); color: #1f7a4d; }
.marche-header .marche-badge-en_preparation { background: rgba(255,255,255,0.92); color: var(--primary); }
.marche-meta-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,0.16);
}
.marche-meta-item { display: flex; flex-direction: column; gap: 2px; }
.marche-meta-label {
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: rgba(255,255,255,0.65);
}
.cpv-chip {
  display: inline-block;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px;
  padding: 2px 8px;
  margin-right: 4px;
  background: rgba(255,255,255,0.14);
  border-radius: 999px;
}

/* Cartes Go/No-Go résumées du dossier */
.gonogo-cards { display: grid; gap: 14px; }
.gonogo-card {
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  padding: 16px 18px;
}
.gonogo-card-head { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.score-wrap {
  display: inline-flex; align-items: baseline; gap: 2px;
  color: var(--primary);
}
.score-num { font-size: 30px; font-weight: 700; font-variant-numeric: tabular-nums; }
.score-unit { color: var(--text-muted); font-size: 14px; }
.gonogo-card-rec { display: flex; flex-direction: column; gap: 4px; }
/* Pousse le bouton d'export à droite de la ligne d'en-tête. Sur les écrans
 * étroits, la flex-wrap parente le bascule sous le score sans effort. */
.gonogo-card-actions { margin-left: auto; }
.gonogo-card-rationale { margin: 10px 0 0; color: var(--text); }

/* Bandeau d'actions au sommet d'un bloc résultat Go/No-Go autonome
 * (analyses.html après lancement). Aligne le bouton à droite avec une marge
 * pour ne pas écraser l'eyebrow. */
.result-actions { display: flex; justify-content: flex-end; margin: 0 0 6px; }

/* ─────────────── Rendu Go/No-Go partagé (GonogoRender) ───────────────
 * Hérite du look de .dce-hero (fond navy gradient + bouton export ambre en
 * haut à droite) et ajoute son propre bloc score + recommandation +
 * justification, sans dépendre de .dce-layout ni du menu d'ancrage latéral
 * (un Go/No-Go tient sur 3 sections, pas besoin de sommaire). */
.gonogo-hero { /* hérite de .dce-hero ; rien à surcharger côté fond */ }

/* Brique « Cascade de sources Go/No-Go » — badge sobre dans le hero
 * indiquant la source d'ancrage (avis_ao / RC / métadonnées seules) +
 * un chip plus compact dans la ligne d'analyse de la liste sur la fiche
 * marché. Sur le hero (fond navy), texte clair sur fond translucide pour
 * rester lisible ; sur la liste (fond clair), chip neutre type pill. */
.gonogo-source-badge {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 10px;
  padding: 4px 10px;
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.92);
  letter-spacing: 0.01em;
}
.gonogo-source-badge .gonogo-source-label {
  font-weight: 600;
  color: rgba(255, 255, 255, 0.72);
}
.gonogo-source-badge .gonogo-source-value {
  font-weight: 600;
}
.gonogo-source-trunc {
  color: rgba(255, 255, 255, 0.55);
  font-style: italic;
}
.gonogo-source-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 1px 8px;
  background: var(--bg-page-strong, var(--bg-page));
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--text-muted);
  letter-spacing: 0.01em;
}
.gonogo-source-chip[data-input-source="aapc"] { color: var(--accent-strong); border-color: var(--accent); }
.gonogo-source-chip[data-input-source="rc"]   { color: var(--accent-strong); border-color: var(--accent); }
.gonogo-source-chip[data-input-source="metadata"] { color: var(--text-muted); }
.gonogo-hero-block {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 24px;
  margin-top: 18px;
}
.gonogo-hero-score {
  display: flex;
  align-items: baseline;
  gap: 4px;
  color: #ffffff;
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: 12px;
  padding: 14px 22px;
  min-width: 130px;
  justify-content: center;
}
.gonogo-hero-score-num { font-size: 48px; font-weight: 700; letter-spacing: -0.01em; line-height: 1; }
.gonogo-hero-score-unit { font-size: 16px; color: rgba(255,255,255,0.7); }
.gonogo-hero-reco { display: flex; flex-direction: column; gap: 10px; }
.gonogo-hero-pill {
  /* Pill plus grosse que la pill "résultat" historique, et alignée à gauche */
  align-self: flex-start;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 6px 14px;
}
.gonogo-hero-rationale {
  margin: 0;
  color: rgba(255,255,255,0.92);
  font-size: 15px;
  line-height: 1.55;
}
.gonogo-hero-rationale.muted { color: rgba(255,255,255,0.55); font-style: italic; }
.gonogo-list { margin: 6px 0 0; padding-left: 20px; }
.gonogo-list li { margin-bottom: 6px; color: var(--text); }
.gonogo-strengths h2 { color: var(--go); }
.gonogo-risks h2 { color: var(--nogo); }

/* Lignes cliquables d'historique / accueil — feedback visuel discret. */
.clickable-row { cursor: pointer; transition: background 0.12s ease; }
.clickable-row:hover { background: var(--bg-page); }
.analyse-line.clickable-row { border-radius: var(--radius-s); }
.analyse-line.clickable-row:hover { background: var(--bg-page); }

/* ─────────────── Table « Vos appels d'offres » (T2 dashboard) ───────────────
 * Table marché-centrée sur l'accueil. Lignes entières cliquables vers le
 * dossier, en-têtes triables (clavier-accessibles), pastilles d'échéance
 * colorées par bucket (urgent/soon/ok/past), icônes d'export Word par type.
 * Limité à ~8 lignes ; le détail vit sur marches.html. */
/* Étape 6.2 — confinement du tableau « Vos appels d'offres » dans sa carte :
 * wrapper avec overflow-x:auto (scroll interne sur largeurs étroites plutôt
 * que débordement à droite). */
.tenders-table-wrap {
  width: 100%;
  overflow-x: auto;
}

.tenders-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
  /* Largeurs de colonnes explicites — sommant à 100 % — pour éviter
   * que le contenu (ex. acheteurs et objets longs) ne fasse déborder le
   * tableau au-delà du conteneur. table-layout: fixed force le respect
   * des largeurs déclarées via :nth-child ci-dessous. */
  table-layout: fixed;
  min-width: 720px; /* en deçà, le wrapper passe en scroll horizontal */
}
/* Brique « Dashboard AO tri » — 8 colonnes : OBJET 22 + ACHETEUR 15 +
 * STATUT 11 + ÉCHÉANCE 11 + CRÉÉ LE 9 + PROCHAINE 15 + ANALYSES 7 +
 * ACTIONS 10 = 100. La colonne CRÉÉ LE reste compacte (date courte type
 * « 10/06/26 ») ; OBJET et ACHETEUR restent ellipsis. En deçà de 720 px,
 * le wrapper passe en scroll horizontal. */
.tenders-table thead th:nth-child(1), .tenders-table tbody td:nth-child(1) { width: 22%; }
.tenders-table thead th:nth-child(2), .tenders-table tbody td:nth-child(2) { width: 15%; }
.tenders-table thead th:nth-child(3), .tenders-table tbody td:nth-child(3) { width: 11%; }
.tenders-table thead th:nth-child(4), .tenders-table tbody td:nth-child(4) { width: 11%; }
.tenders-table thead th:nth-child(5), .tenders-table tbody td:nth-child(5) { width: 9%; }
.tenders-table thead th:nth-child(6), .tenders-table tbody td:nth-child(6) { width: 15%; }
.tenders-table thead th:nth-child(7), .tenders-table tbody td:nth-child(7) { width: 7%; }
.tenders-table thead th:nth-child(8), .tenders-table tbody td:nth-child(8) { width: 10%; }
/* Clip tout débordement de contenu (pill plus large que la cellule) — on
 * préfère un ellipsis ou un soft-clip au bleed dans la colonne suivante. */
.tenders-table tbody td { overflow: hidden; }
.tenders-table thead th {
  text-align: left;
  font-weight: 600;
  font-size: 12px;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 8px 8px;
  border-bottom: 1px solid var(--trait);
  white-space: nowrap;
  /* En-têtes ne peuvent plus pousser la colonne au-delà de leur largeur
   * déclarée — on tronque proprement si le libellé est trop long. */
  overflow: hidden;
  text-overflow: ellipsis;
}
.tenders-table thead th.sortable { cursor: pointer; user-select: none; }
.tenders-table thead th.sortable:hover { color: var(--primary); }
.tenders-table thead th.sortable:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.tenders-table thead th .sort-arrow { color: var(--primary); font-size: 11px; }
.tenders-table tbody td {
  padding: 12px 8px;
  border-bottom: 1px solid var(--trait);
  vertical-align: middle;
}
.tenders-table tbody tr:last-child td { border-bottom: 0; }
.tenders-table tbody tr.clickable-row:hover { background: var(--bg-page); }
.tenders-table .tender-objet {
  max-width: 320px;
  font-weight: 500;
  color: var(--text);
  /* Étape 6.1 — troncature : objet sur 1 ligne, ellipsis, texte complet
   * disponible via title="…" sur la cellule. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tenders-table .tender-objet em { color: var(--text-muted); }
.tenders-table .tender-acheteur {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
}
.tenders-table .tender-next {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 6px;
  white-space: nowrap;
}
.tenders-table .tender-next.next-analyze { background: var(--accent-soft); color: var(--primary); }
.tenders-table .tender-next.next-gonogo  { background: var(--amber-soft); color: #8a5a07; }
.tenders-table .tender-next.next-ok      { background: rgba(46,139,87,0.12); color: #1f7a4d; }
.tenders-table .tender-actions { white-space: nowrap; }
.tenders-table .tender-created {
  /* Date courte (« 10/06/26 ») compacte ; pas d'ellipsis nécessaire grâce
   * à la largeur fixe (9 %) calibrée pour le format `dateStyle: short`. */
  font-size: 13px;
  white-space: nowrap;
}

/* Brique « Dashboard AO tri » — sélecteur de mode au-dessus du tableau.
 * Sobre, aligné à droite (proche du « Voir tous mes marchés → »), même
 * traitement visuel que les autres `<select>` du produit. */
.tenders-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin: 0 0 12px;
}
.tenders-sort-label {
  font-size: 13px;
  color: var(--text-soft);
}
.tenders-sort-select {
  font: inherit;
  font-size: 13px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fff;
  color: var(--text);
  cursor: pointer;
}
.tenders-sort-select:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.tenders-sort-select:disabled { opacity: 0.6; cursor: progress; }

/* Étape 6.1 — onboarding (Accueil vide) : bouton unique centré sous la
 * grille de capacités. */
.onboarding-cta {
  display: flex;
  justify-content: center;
  padding-top: 18px;
  margin-top: 18px;
  border-top: 1px solid var(--border);
}
.onboarding-cta .primary { padding: 12px 22px; font-size: 15px; }

/* Pastille d'échéance — vert/ambre/rouge selon proximité, gris si passée. */
.deadline-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.deadline-ok     { background: rgba(46,139,87,0.14); color: #1f7a4d; }
.deadline-soon   { background: var(--amber-soft); color: #8a5a07; }
.deadline-urgent { background: rgba(200,50,50,0.14); color: #a32a2a; }
.deadline-past   { background: var(--bg-page-strong); color: var(--text-muted); text-decoration: line-through; }

/* Icônes d'export Word — compactes, ton SOBRE gris neutre (cohérent avec
 * .tag). L'ambre est réservé à l'urgence d'échéance et le vert aux recos
 * Go ; ici on est sur une action neutre (« télécharger »). */
.tender-export-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 24px;
  padding: 0 8px;
  margin-right: 4px;
  font: 700 11px var(--sans);
  letter-spacing: 0.04em;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-page-strong);
  color: var(--text-soft);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.tender-export-btn:hover {
  background: var(--text-soft);
  border-color: var(--text-soft);
  color: #fff;
}
.tender-export-btn:disabled { opacity: 0.6; cursor: progress; }

.tenders-overflow { margin: 14px 0 0; font-size: 13px; }
.tenders-overflow a { color: var(--primary); }

@media (max-width: 720px) {
  .tenders-table { font-size: 13px; }
  .tenders-table thead th, .tenders-table tbody td { padding: 8px 6px; }
  /* On masque les colonnes secondaires sur mobile pour rester lisible :
   * acheteur (2), créé le (5), prochaine étape (6), analyses (7) — on
   * garde objet + statut + échéance + actions, qui composent l'info
   * vitale d'une ligne marché. */
  .tenders-table thead th:nth-child(2),
  .tenders-table tbody td:nth-child(2),
  .tenders-table thead th:nth-child(5),
  .tenders-table tbody td:nth-child(5),
  .tenders-table thead th:nth-child(6),
  .tenders-table tbody td:nth-child(6),
  .tenders-table thead th:nth-child(7),
  .tenders-table tbody td:nth-child(7) { display: none; }
  .tenders-table .tender-objet { max-width: 200px; }
}

@media (max-width: 720px) {
  .gonogo-hero-block { grid-template-columns: 1fr; gap: 14px; }
  .gonogo-hero-score { min-width: 0; padding: 12px 18px; }
  .gonogo-hero-score-num { font-size: 40px; }
}
.gonogo-card .row > div { flex: 1 1 240px; }
.gonogo-card .small { font-size: 12px; }

/* Bloc « prochaine étape » (T3) — un guide sobre, pas un harcèlement.
 * Liseré indigo à gauche pour signaler l'action suggérée sans crier.
 * Variante neutre (sans liseré coloré) pour le cas « rien à faire ici ». */
.marche-next {
  border-left: 4px solid var(--primary);
  margin-top: 18px;
}
.marche-next h2 {
  font-size: 18px;
  margin: 6px 0 8px;
  color: var(--text);
}
.marche-next p { margin: 0 0 12px; color: var(--text-soft); }
.marche-next .eyebrow {
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.08em;
}
.marche-next-action {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  margin-top: 8px;
}
.marche-next-list {
  margin: 4px 0 14px 18px;
  padding: 0;
  color: var(--text);
}
.marche-next-list li { margin: 4px 0; }
/* Variante « rien à pousser » : on retire le liseré coloré pour signaler
 * que ce n'est pas une action urgente, juste une porte ouverte. */
.marche-next-other { border-left-color: var(--border-strong); }
.marche-next-other p { color: var(--text-soft); }
.ghost-link {
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
  font-size: 14px;
}
.ghost-link:hover { color: var(--primary-strong); text-decoration: underline; }

/* Lignes DCE du dossier (document + action) */
.dce-lines { display: grid; gap: 10px; }
.dce-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 12px 14px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
}
.dce-line-name { font-weight: 600; color: var(--text); word-break: break-word; }
.dce-line .small { font-size: 12px; }

@media (max-width: 720px) {
  .marche-row-link { grid-template-columns: 1fr; }
  .marche-row-side { align-items: flex-start; text-align: left; }
  .marche-header-top { grid-template-columns: 1fr; }
  .marche-header-side { align-items: flex-start; }
  .dce-line { grid-template-columns: 1fr; }
}

/* ─────────────── Rendu Analyse de DCE (tranche 3) ─────────────── */
/* Layout 2 colonnes sur grand écran : menu d'ancrage sticky à gauche +
 * contenu à droite. Sur mobile, le menu se replie en chips horizontales en
 * haut du contenu (cf. media query plus bas). */
.dce-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 28px;
  align-items: start;
  margin-top: 16px;
}
.dce-content { min-width: 0; display: grid; gap: 18px; }
.dce-content > * { margin: 0; }

/* Menu d'ancrage sticky — la topbar fait ~64 px de haut, on prend 88 px pour
 * un peu d'air visuel + s'aligner sur le haut du hero. */
.dce-anchor-nav {
  position: sticky;
  top: 88px;
  align-self: start;
}
.dce-anchor-nav-title {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  padding: 0 12px 8px;
}
.dce-anchor-nav nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.dce-anchor-nav a {
  display: block;
  padding: 9px 12px;
  color: var(--text-soft);
  text-decoration: none;
  border-radius: var(--radius-s);
  font-size: 14px;
  font-weight: 500;
  transition: background .12s ease, color .12s ease;
}
.dce-anchor-nav a:hover {
  background: var(--accent-soft);
  color: var(--primary);
}

/* Sections : décale la cible des ancres pour ne pas être masquée par la
 * topbar sticky. Tient compte du même 88 px que .dce-anchor-nav top. */
.dce-hero, .dce-section { scroll-margin-top: 88px; }

/* Défilement fluide quand un lien d'ancrage est cliqué — scoped à la page
 * via la présence de .dce-layout pour ne pas affecter le reste de l'app. */
html:has(.dce-layout) { scroll-behavior: smooth; }


/* Chargeur étapé : messages temporisés défilant pendant l'appel IA (~20 s) */
.dce-stepper {
  display: flex; flex-direction: column; align-items: center; gap: 18px;
  padding: 40px 24px; text-align: center;
}
.dce-stepper-ring {
  width: 56px; height: 56px;
  border-radius: 50%;
  border: 4px solid var(--accent-soft);
  border-top-color: var(--primary);
  animation: dce-spin 1.1s linear infinite;
}
@keyframes dce-spin { to { transform: rotate(360deg); } }
.dce-stepper-msg {
  font-size: 16px; font-weight: 500; color: var(--primary);
  transition: opacity .35s ease, transform .35s ease;
}
.dce-stepper-msg.is-leaving { opacity: 0; transform: translateY(-6px); }
.dce-stepper-msg.is-entering { opacity: 0; transform: translateY(6px); }
.dce-stepper-sub { font-size: 13px; color: var(--text-muted); }

/* Hero : en-tête de l'analyse avec synthèse mise en avant */
.dce-hero {
  background: linear-gradient(135deg, var(--navy) 0%, var(--primary) 100%);
  color: #ffffff;
  border: none;
  position: relative; /* permet l'ancrage du bouton d'export en haut à droite */
}
/* Bouton « Exporter en Word » en haut à droite du hero. Sur mobile, repli
 * en pleine largeur sous la synthèse plutôt que d'écraser le titre. */
.dce-hero-actions {
  position: absolute;
  top: 22px;
  right: 24px;
  z-index: 1;
}
/* Style ambre commun à tous les boutons « Exporter en Word » de l'appli :
 * hero DCE (fond navy) + cartes Go/No-Go (fond clair) + résultat autonome.
 * Le ton ambre, déjà l'accent du wordmark, signale visuellement l'action
 * « export Word » indépendamment du fond. */
.export-word-btn,
.dce-hero-actions .primary {
  background: var(--amber);
  color: var(--navy);
  font-weight: 600;
  padding: 11px 20px;
  border: none;
  border-radius: var(--radius-s);
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  box-shadow: 0 4px 14px -2px rgba(0,0,0,0.25),
              0 0 0 1px rgba(0,0,0,0.06) inset;
}
.export-word-btn:hover,
.dce-hero-actions .primary:hover {
  background: #D78A1C;
  color: var(--navy);
  box-shadow: 0 6px 18px -3px rgba(0,0,0,0.35),
              0 0 0 1px rgba(0,0,0,0.08) inset;
}
.dce-hero-actions .primary {
  /* Le hero est sur fond navy : on durcit l'ombre + on ajoute un liseré clair
   * inset pour décoller le bouton du fond foncé. */
  box-shadow: 0 4px 14px -2px rgba(0,0,0,0.45),
              0 0 0 1px rgba(255,255,255,0.18) inset;
}
.dce-hero-actions .primary:hover {
  box-shadow: 0 6px 18px -3px rgba(0,0,0,0.55),
              0 0 0 1px rgba(255,255,255,0.22) inset;
}
.export-word-btn:disabled {
  opacity: 0.7;
  cursor: progress;
}
@media (max-width: 720px) {
  .dce-hero-actions {
    position: static;
    margin-top: 14px;
    text-align: right;
  }
}
.dce-hero .eyebrow {
  color: rgba(255,255,255,0.75);
  letter-spacing: 0.08em;
}
.dce-hero-h1 {
  font-size: clamp(22px, 3vw, 30px);
  font-weight: 700;
  margin: 4px 0 6px;
  letter-spacing: -0.01em;
  /* La règle globale `h1 { color: var(--text) }` plus spécifique que `.dce-hero`
   * laissait le titre en encre foncée, illisible sur le fond navy/indigo. */
  color: #ffffff;
}
.dce-hero .dce-meta {
  color: rgba(255,255,255,0.7);
  font-size: 13px;
  margin-bottom: 14px;
}
.dce-synthese {
  font-size: 16px;
  line-height: 1.55;
  margin: 0;
  color: rgba(255,255,255,0.95);
  background: rgba(255,255,255,0.06);
  border-left: 3px solid var(--amber);
  padding: 14px 18px;
  border-radius: 0 8px 8px 0;
}
.dce-sim {
  margin-bottom: 14px;
  background: var(--amber-soft);
  border-left-color: var(--amber);
}

/* Chip de référence (RC §5.2, déduit, …) — visible partout, traçabilité */
.dce-ref {
  display: inline-block;
  font-size: 12px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  color: var(--text-soft);
  background: var(--bg-page-strong);
  border: 1px solid var(--border);
  padding: 2px 8px;
  border-radius: 999px;
  vertical-align: middle;
}
.dce-hero .dce-ref {
  background: rgba(255,255,255,0.12);
  border-color: rgba(255,255,255,0.25);
  color: rgba(255,255,255,0.9);
}

/* Sections génériques */
.dce-section h2 {
  font-size: 17px;
  font-weight: 600;
  margin: 0 0 14px;
  color: var(--text);
}
.dce-section-empty p { margin: 4px 0 0; }

/* Brique « Analyse DCE multi-pièces » — bloc « Composition du dossier ».
 * Visible quand l'analyse vient d'un dossier agrégé. Style sobre, info
 * neutre (pas d'alerte rouge sur les non-lues / non-extraites — ce n'est
 * pas une erreur, c'est de la traçabilité).
 */
.dce-dossier-composition { }
.dce-dossier-block { margin-top: 14px; }
.dce-dossier-block-title { font-weight: 600; font-size: 14px; margin-bottom: 6px; }
.dce-dossier-list { list-style: none; padding: 0; margin: 6px 0 0; display: grid; gap: 4px; }
.dce-dossier-item {
  display: grid;
  grid-template-columns: 90px 1fr auto;
  align-items: baseline;
  gap: 10px;
  font-size: 13px;
  padding: 4px 8px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.dce-dossier-kind {
  font-size: 11.5px; font-weight: 600;
  color: var(--text-muted);
  padding: 1px 6px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  text-align: center;
}
.dce-dossier-name {
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.dce-dossier-extra { white-space: nowrap; }
/* Discrète distinction par bloc — point cobalt sur l'entête uniquement. */
.dce-dossier-lues       .dce-dossier-block-title::before,
.dce-dossier-partielles .dce-dossier-block-title::before,
.dce-dossier-non-lues   .dce-dossier-block-title::before,
.dce-dossier-non-extraites .dce-dossier-block-title::before {
  content: ''; display: inline-block;
  width: 7px; height: 7px; border-radius: 50%;
  margin-right: 6px;
  background: var(--text-muted);
  vertical-align: middle;
}
.dce-dossier-lues       .dce-dossier-block-title::before { background: var(--accent); }
.dce-dossier-partielles .dce-dossier-block-title::before { background: var(--amber); }

/* =========================================================================
 * Brique « Badge d'obsolescence d'analyse DCE » — badge ambre + bouton
 * « Relancer ». Style SOBRE (pas d'alerte rouge), c'est de la traçabilité.
 * Apparaît sur :
 *   - la carte d'analyse dans la liste « Analyses de DCE »
 *   - l'étape rail « Analyse de DCE » du suivi
 *   - le hero de l'analyse ouverte (via dce-render.js)
 * ========================================================================= */
.dce-obs-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 8px;
  font-size: 12px; font-weight: 600;
  background: rgba(245, 158, 11, 0.12);
  color: var(--amber-strong, #92400e);
  border: 1px solid rgba(245, 158, 11, 0.5);
  border-radius: 999px;
  line-height: 1.4;
}
.dce-obs-badge-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  background: var(--amber, #f59e0b);
  color: white;
  border-radius: 50%;
  font-size: 10px; font-weight: 700;
}
button.amber.small,
button.amber {
  background: var(--amber, #f59e0b);
  color: white;
  border: 1px solid var(--amber, #f59e0b);
  border-radius: 6px;
  font-weight: 600;
  cursor: pointer;
  padding: 4px 10px;
  font-size: 12.5px;
}
button.amber:hover { filter: brightness(0.95); }
button.amber:disabled { opacity: 0.6; cursor: not-allowed; }

.analysis-row-stale {
  border-left: 3px solid var(--amber, #f59e0b);
  padding-left: 10px;
}
.step-done-stale .step-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.step-actions { display: inline-flex; gap: 6px; align-items: center; }

/* Hero de l'analyse ouverte — bloc d'obsolescence inline avec badge,
 * bouton relancer et détail listé (added / removed / replaced). */
.dce-obs-hero {
  margin: 10px 0 6px;
  padding: 10px 12px;
  background: rgba(245, 158, 11, 0.06);
  border: 1px solid rgba(245, 158, 11, 0.3);
  border-radius: 8px;
}
.dce-obs-hero-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 6px;
}
.dce-obs-detail {
  display: flex; flex-direction: column; gap: 8px;
  font-size: 13px;
}
.dce-obs-block { padding: 4px 0; }
.dce-obs-block-title { font-weight: 600; font-size: 12.5px; margin-bottom: 3px; }
.dce-obs-list { list-style: disc; padding-left: 20px; margin: 2px 0 0; color: var(--text); }
.dce-obs-list li { padding: 1px 0; }

/* Critères d'attribution */
.dce-criteria-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 14px; }
.dce-criterion {
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  padding: 14px 16px;
}
.dce-criterion-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin-bottom: 8px;
}
.dce-criterion-label { font-weight: 600; color: var(--text); }
.dce-criterion-weight {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--primary);
  font-size: 15px;
}
.dce-criterion-weight.muted { color: var(--text-muted); font-weight: 500; font-size: 13px; }
.dce-bar {
  height: 6px;
  background: var(--accent-soft);
  border-radius: 999px;
  overflow: hidden;
}
.dce-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--primary));
  border-radius: 999px;
}
.dce-subcriteria {
  margin: 10px 0 0 18px;
  padding: 0;
  color: var(--text-soft);
  font-size: 14px;
}
.dce-subcriteria li { margin: 2px 0; }
.dce-criterion-ref { margin-top: 10px; }

/* Pièces à fournir — checklist */
.dce-checklist { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.dce-check-item {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  padding: 10px 14px;
}
.dce-check-box {
  width: 18px; height: 18px; flex-shrink: 0;
  border: 2px solid var(--border-strong);
  border-radius: 4px;
  background: var(--card);
}
.dce-check-label { flex: 1; min-width: 200px; color: var(--text); }

/* Badges génériques */
.dce-badge {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.dce-badge-required { background: var(--primary); color: #ffffff; }
.dce-badge-optional { background: var(--bg-page-strong); color: var(--text-soft); }

/* Dates clés */
.dce-dates { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.dce-date {
  display: grid;
  grid-template-columns: minmax(160px, auto) 1fr auto;
  align-items: baseline;
  gap: 14px;
  padding: 10px 14px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
}
.dce-date-when {
  font-weight: 600;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.dce-date-what { color: var(--text); }

/* Contraintes & exigences regroupées par type */
.dce-constraints { display: grid; gap: 18px; }
.dce-constraint-group h3 {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin: 0 0 8px;
}
.dce-constraint-group ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; }
.dce-constraint-group li {
  background: var(--bg-page);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  padding: 10px 14px;
}
.dce-constraint-label { font-weight: 600; color: var(--text); }
.dce-constraint-detail { font-size: 14px; color: var(--text-soft); margin-top: 2px; }

/* Clauses à risque — code couleur par gravité */
.dce-risks { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.dce-risk {
  background: var(--bg-page);
  border-left: 4px solid var(--border-strong);
  border-radius: 4px;
  padding: 12px 14px;
}
.dce-risk-faible { border-left-color: var(--go); }
.dce-risk-moyenne { border-left-color: var(--amber); }
.dce-risk-elevee { border-left-color: var(--nogo); }
.dce-risk-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.dce-risk-label { font-weight: 600; color: var(--text); }
.dce-risk-reason { font-size: 14px; color: var(--text-soft); margin-top: 4px; }
.dce-badge-grav-faible { background: rgba(46, 139, 87, 0.14); color: #1f7a4d; }
.dce-badge-grav-moyenne { background: var(--amber-soft); color: #8a5a07; }
.dce-badge-grav-elevee { background: rgba(200, 50, 50, 0.14); color: #a32a2a; }

/* Encart positif « pour compléter » — prépare l'ingestion ZIP T4.
 * Couleurs explicites au lieu d'hériter de body : sur fond bleu cobalt
 * clair, la classe utilitaire `.muted` (gris ~#737b86) tombait à un
 * contraste trop pâle et le titre héritait des règles globales h2.
 * On utilise navy partout pour rester lisible et cohérent avec la
 * charte (encre foncée, jamais noir pur). Les liens éventuels dans le
 * bloc forcent l'accent cobalt soutenu (vs accent-soft du fond).
 */
.dce-missing {
  background: var(--accent-soft);
  border: 1px solid #c9d8f8;
  color: var(--navy);
}
.dce-missing-head {
  display: flex; align-items: flex-start; gap: 14px;
  margin-bottom: 10px;
}
.dce-missing-icon {
  flex-shrink: 0;
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary); color: #fff;
  border-radius: 8px;
  font-size: 20px; font-weight: 700;
}
.dce-missing h2 {
  margin: 0 0 2px; font-size: 16px;
  color: var(--navy);  /* force la couleur sur fond bleu clair */
}
.dce-missing-head p {
  margin: 0; font-size: 14px;
  color: var(--navy);  /* la classe .muted héritée tombait trop pâle ici */
}
.dce-missing-list {
  margin: 6px 0 8px 50px; padding: 0; list-style: disc;
  color: var(--navy);
}
.dce-missing-list li {
  margin: 3px 0;
  color: var(--navy);
}
.dce-missing-hint {
  font-size: 13px; margin-left: 50px;
  color: var(--navy);  /* idem : .muted trop pâle sur ce fond */
  opacity: 0.78;       /* léger atténuement, mais reste lisible (~4.5:1) */
}
/* Liens à l'intérieur du bloc : on force l'accent cobalt FONCÉ et un
 * soulignement discret (le fond accent-soft décolorerait un lien bleu
 * standard). */
.dce-missing a {
  color: var(--accent-strong, var(--accent));
  text-decoration: underline;
  text-underline-offset: 2px;
}
.dce-missing a:hover { color: var(--primary); }
/* Badges/chips éventuels (cf. .tag, .pill) : assombrir le texte pour
 * rester lisible sur le fond bleu clair sans changer leur couleur de
 * fond — les bandes colorées des verdicts Go/No-Go restent intactes
 * par leur classe spécifique, ceci ne touche QUE les tags neutres. */
.dce-missing .tag,
.dce-missing .chip {
  color: var(--navy);
}

/* Debug : JSON brut repliable */
.dce-debug summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--text-muted);
  font-weight: 500;
}
.dce-debug-json {
  margin-top: 10px;
  white-space: pre-wrap;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px;
  background: var(--bg-page-strong);
  padding: 14px;
  border-radius: 8px;
  max-height: 50vh;
  overflow: auto;
}

/* ─────────────── Responsive ─────────────── */
/* Menu d'ancrage DCE : sticky en colonne sur grand écran (cf. ci-dessus),
 * replié en chips horizontales scrollables en haut sur écran moyen/mobile. */
@media (max-width: 960px) {
  .dce-layout { grid-template-columns: 1fr; gap: 0; }
  .dce-anchor-nav {
    position: static;
    margin-bottom: 16px;
  }
  .dce-anchor-nav-title { display: none; }
  .dce-anchor-nav nav {
    flex-direction: row;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding: 6px;
  }
  .dce-anchor-nav a {
    white-space: nowrap;
    flex-shrink: 0;
    padding: 8px 14px;
  }
}
@media (max-width: 900px) {
  .tabs-layout { grid-template-columns: 1fr; gap: 0; }
  .tabs-list { display: none; }
  .tabs-mobile { display: block; }
  .stats { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 720px) {
  .topbar-inner {
    grid-template-columns: 1fr auto;
    grid-template-areas: 'brand chip' 'nav nav';
    gap: 12px; padding: 12px 16px;
  }
  .brand { grid-area: brand; }
  .user-chip { grid-area: chip; gap: 8px; }
  .user-chip .user-name, .user-chip .user-role { display: none; }
  .main-nav {
    grid-area: nav;
    justify-self: stretch;
    overflow-x: auto;
    flex-wrap: nowrap;
    margin: 0 -16px;
    padding: 0 16px 4px;
    -webkit-overflow-scrolling: touch;
  }
  .main-nav a { white-space: nowrap; }
  .hello { grid-template-columns: 1fr; gap: 16px; }
  .stats { grid-template-columns: 1fr; }
  .analysis-types-grid { grid-template-columns: 1fr; }
  .profile-cta-list { grid-template-columns: 1fr; }
  .wrap { padding: 24px 16px 64px; }
  .card { padding: 22px; }
  .score-block { grid-template-columns: 1fr; gap: 8px; }
  .dce-date { grid-template-columns: 1fr; gap: 4px; }
  .dce-criterion-head { flex-direction: column; align-items: flex-start; gap: 4px; }
  .dce-missing-list, .dce-missing-hint { margin-left: 0; }
  .packs-grid { grid-template-columns: 1fr; }
}

/* ─────────────── Tableau de bord opérateur (back-office tranche a) ─────────
 * Cartes KPI compactes + graphiques SVG sobres (bar + line).
 * Pas de dépendance externe — tout est codé à la main. */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin-top: 8px;
}
.kpi-card {
  padding: 16px 18px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
}
.kpi-card .eyebrow {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
.kpi-card .kpi-value {
  font-family: var(--serif, inherit);
  font-size: 30px;
  font-weight: 600;
  color: var(--navy);
  line-height: 1.1;
  margin-bottom: 4px;
}
.kpi-card .small { font-size: 12px; }

/* Chart.js : maintainAspectRatio=false demande que le conteneur définisse
 * la hauteur. .chart-wrap définit cette boîte ; les variantes -line / -bar
 * ajustent la hauteur selon le type de graphique. */
.chart-wrap {
  position: relative;
  width: 100%;
  height: 280px;
  margin-top: 6px;
}
.chart-wrap-line { /* hérite de .chart-wrap, hauteur plus généreuse en ligne */ }
.chart-wrap-line > canvas, .chart-wrap > canvas {
  display: block;
  max-width: 100%;
}
/* Bar chart pays : la hauteur est proportionnelle au nombre de barres pour
 * ne pas écraser visuellement quand il n'y a qu'1 ou 2 pays. Plafond géré
 * par maxBarThickness côté JS ; le conteneur réserve simplement assez de
 * place. */
.chart-wrap-bar .chart-wrap { height: 260px; }

.overview-bar-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-top: 6px;
}
.chart-subtitle {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Sélecteur de période — barre de boutons en haut du dashboard. Les boutons
 * forment un groupe segmenté (style admin e-commerce). État actif en navy
 * plein, inactifs en outline léger qui hover vers le primary. */
.period-card { padding: 18px 22px; }
.period-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}
.period-label { display: flex; flex-direction: column; gap: 2px; }
.period-label .eyebrow {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.period-buttons {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.period-btn {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--text-soft);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 6px 14px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.period-btn:hover { color: var(--navy); }
.period-btn.is-active {
  background: var(--navy);
  color: #ffffff;
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
.period-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

/* Badge « +N » sur les KPI quand un flux complète un stock (ex. clients). */
.kpi-delta {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 600;
  color: #1f7a4d;
  background: rgba(46,139,87,0.14);
  border-radius: 999px;
  vertical-align: middle;
}

@media (max-width: 720px) {
  .period-bar { flex-direction: column; align-items: stretch; }
  .period-buttons { flex-wrap: wrap; justify-content: center; }
}

@media (max-width: 720px) {
  .overview-bar-grid { grid-template-columns: 1fr; }
  .chart-wrap { height: 260px; }
}

/* Coût & marge — cartes par type d'analyse. Deux colonnes par carte : coût
 * moyen à gauche, multiple de marge à droite (pour visualiser d'un coup
 * d'œil l'économie unitaire). */
.cost-type-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
  margin-top: 6px;
}
.cost-type-card {
  padding: 14px 16px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
}
.cost-type-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.cost-type-name {
  font-family: var(--serif, inherit);
  font-size: 16px;
  font-weight: 600;
  color: var(--navy);
}
.cost-type-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.cost-type-row .eyebrow {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 4px;
}
.cost-type-value {
  font-family: var(--serif, inherit);
  font-size: 22px;
  font-weight: 600;
  color: var(--navy);
  line-height: 1.1;
  margin-bottom: 2px;
}
.cost-type-multiple .cost-type-value { color: var(--primary); }

@media (max-width: 720px) {
  .cost-type-row { grid-template-columns: 1fr; gap: 10px; }
}

/* ─────────────── Page Tarifs & Crédits (brique Paiement T-A) ─────────────── */
/* Bandeau « Mode simulation » — couleur ambre claire, présent uniquement
 * tant que Stripe n'est pas branché. Rappel : aucun moyen de paiement saisi. */
.banner.billing-sim {
  border-left-color: var(--amber);
  background: var(--amber-soft);
}

.billing-perks { margin: 14px 0; padding-left: 22px; color: var(--text-soft); }
.billing-perks li { margin-bottom: 6px; }

.billing-sub-active { display: flex; flex-direction: column; gap: 14px; }
.billing-sub-active .pill { display: inline-block; }
.billing-meta { margin: 0; padding-left: 18px; color: var(--text-soft); font-size: 14px; }
.billing-meta li { margin-bottom: 4px; }

/* Grille des packs — 4 colonnes en desktop, repli auto, single-col mobile. */
.packs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin-top: 6px;
}
.pack-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  background: var(--bg-page);
}
.pack-card .pack-price {
  font-family: var(--serif, inherit);
  font-size: 28px;
  font-weight: 600;
  color: var(--navy);
  line-height: 1.1;
}
.pack-card .pack-credits {
  font-size: 15px;
  font-weight: 600;
  color: var(--primary);
}
.pack-card .pack-detail { font-size: 12px; }
.pack-card .primary { margin-top: 10px; }

/* ─── Refonte Tarifs « clarté & conversion » ──────────────────────────────
 * Hero contraste (5 € vs 1 €), packs crédits-d'abord avec deux grilles,
 * coûts des analyses, parcours bout-en-bout. */

/* --- Hero contraste -------------------------------------------------- */
.hero-contrast {
  padding: 22px 24px 18px;
  background: linear-gradient(180deg, var(--bg-page) 0%, var(--card) 100%);
}
.hero-contrast .eyebrow { text-align: center; margin-bottom: 14px; }
.hero-rates {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 22px;
}
.hero-rate {
  text-align: center;
  padding: 14px 12px;
  border-radius: var(--radius-s);
  border: 1px solid transparent;
  transition: opacity 0.18s ease, border-color 0.18s ease;
}
.hero-rate.is-active {
  background: var(--bg-page);
  border-color: var(--border);
}
.hero-rate.is-faded { opacity: 0.55; }
.hero-rate-label {
  font-size: 12px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
.hero-rate-price {
  font-family: var(--serif, inherit);
  font-size: 42px;
  font-weight: 700;
  color: var(--navy);
  line-height: 1;
}
.hero-rate.is-active .hero-rate-price { color: var(--primary); }
.hero-rate-suffix { font-size: 13px; color: var(--text-soft); margin-top: 6px; }
.hero-rate-divider-wrap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-muted);
}
.hero-savings-pill {
  font-family: var(--serif, inherit);
  font-size: 22px;
  font-weight: 700;
  color: var(--card);
  background: linear-gradient(135deg, var(--accent) 0%, var(--primary) 100%);
  padding: 8px 16px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  box-shadow: 0 4px 14px rgba(63, 62, 122, 0.25);
  white-space: nowrap;
}
@media (max-width: 640px) {
  .hero-rates { grid-template-columns: 1fr; gap: 12px; }
  .hero-rate-divider-wrap { justify-self: center; flex-direction: row; }
  .hero-rate-price { font-size: 36px; }
  .hero-savings-pill { font-size: 18px; padding: 6px 12px; }
}

/* --- Carte abonnement non-abonné : « Recommandé » ------------------- */
.sub-offer-card {
  position: relative;
  padding: 22px 22px 16px;
  border: 1px solid var(--primary);
  border-radius: var(--radius);
  background:
    linear-gradient(180deg, var(--accent-soft) 0%, rgba(255,255,255,0) 70%),
    var(--card);
  box-shadow: 0 8px 24px -16px rgba(79, 78, 145, 0.35);
}
.sub-offer-badge {
  position: absolute;
  top: -12px;
  right: 18px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 12px;
  background: linear-gradient(135deg, var(--primary) 0%, var(--accent-strong) 100%);
  color: var(--card);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-radius: 999px;
  box-shadow: 0 4px 12px rgba(79, 78, 145, 0.35);
}
.sub-offer-list { list-style: none; padding: 0; margin: 0 0 14px; }
.sub-offer-list li {
  padding: 10px 0;
  font-size: 15px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: flex-start;
  gap: 12px;
  line-height: 1.45;
}
.sub-offer-list li:last-child { border-bottom: none; }
.sub-offer-list li .bullet-icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--go);
  margin-top: 1px;
}
.sub-offer-list li.muted .bullet-icon { color: var(--text-muted); }
.sub-offer-list li.sub-offer-breakeven {
  background: var(--accent-soft);
  border-radius: 8px;
  border-bottom: none;
  margin-top: 6px;
  padding: 12px 14px;
  font-weight: 600;
  color: var(--accent-strong);
}
.sub-offer-list li.sub-offer-breakeven .bullet-icon { color: var(--accent); }
.value-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: linear-gradient(135deg, var(--amber-soft) 0%, rgba(240, 160, 48, 0.18) 100%);
  color: #8a5a07;
  font-size: 12px;
  font-weight: 600;
  border-radius: 999px;
  border: 1px solid rgba(240, 160, 48, 0.4);
}
.value-pill .icon { stroke: #8a5a07; }
.primary-large {
  padding: 12px 22px;
  font-size: 15px;
  font-weight: 600;
}

/* --- Packs : 2 grilles superposées, crédits-d'abord ------------------- */
.packs-block { margin-top: 6px; }
.packs-block + .packs-block { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.packs-block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 10px;
}
.packs-block-locked .packs-grid { opacity: 0.45; pointer-events: none; filter: grayscale(0.3); }
.packs-block-locked .packs-block-head h3 { color: var(--text-muted); }
.pack-card.is-locked {
  background: var(--bg-page-strong);
  border-style: dashed;
}

/* Nouvelle hiérarchie : crédits dominants, prix discret, taux tertiaire. */
.pack-credits-big {
  font-family: var(--serif, inherit);
  font-size: 44px;
  font-weight: 700;
  color: var(--primary);
  line-height: 1;
}
.pack-credits-unit {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 8px;
}
.pack-price-small {
  font-size: 15px;
  font-weight: 600;
  color: var(--navy);
}
.pack-unit-rate { font-size: 11px; margin-bottom: 4px; }

/* --- Coûts des analyses ---------------------------------------------- */
.analysis-cost-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
.analysis-cost-card {
  padding: 16px 18px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  position: relative;
}
.analysis-cost-icon {
  width: 38px;
  height: 38px;
  border-radius: 9px;
  background: var(--accent-soft);
  color: var(--accent-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
}
.analysis-cost-card.is-soon .analysis-cost-icon {
  background: var(--bg-page-strong);
  color: var(--text-muted);
}
.analysis-cost-card.is-soon { opacity: 0.7; }
.analysis-cost-head { display: flex; align-items: center; flex-wrap: wrap; margin-bottom: 6px; }
.analysis-cost-credits {
  font-family: var(--serif, inherit);
  font-size: 26px;
  font-weight: 700;
  color: var(--primary);
  line-height: 1.1;
  margin-bottom: 4px;
}
.analysis-cost-equiv { font-size: 12px; }

/* --- Parcours bout-en-bout ------------------------------------------ */
.parcours-flow {
  display: flex;
  align-items: stretch;
  gap: 12px;
  margin: 6px 0 16px;
  overflow-x: auto;
}
.parcours-step {
  flex: 1 1 0;
  min-width: 110px;
  padding: 16px 14px;
  text-align: center;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
}
.parcours-step.is-soon { opacity: 0.7; border-style: dashed; }
.parcours-step-credit {
  font-family: var(--serif, inherit);
  font-size: 32px;
  font-weight: 700;
  color: var(--primary);
  line-height: 1;
  margin-bottom: 4px;
}
.parcours-step-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 4px;
}
.parcours-step-icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 10px;
}
.parcours-step.is-soon .parcours-step-icon {
  background: var(--bg-page-strong);
  color: var(--text-muted);
}
.parcours-arrow {
  align-self: center;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.parcours-total {
  padding: 14px 16px;
  background: var(--accent-soft);
  border-radius: var(--radius-s);
  font-size: 15px;
  color: var(--accent-strong);
}
@media (max-width: 640px) {
  .parcours-flow { flex-direction: column; }
  .parcours-arrow { transform: rotate(90deg); }
}

/* --- Estimateur interactif ------------------------------------------ */
.estimator-card {
  background:
    radial-gradient(circle at 100% 0%, var(--accent-soft) 0%, rgba(255,255,255,0) 40%),
    var(--card);
}
.estimator-grid {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) 2fr;
  gap: 24px;
  align-items: start;
}
.estimator-inputs { display: flex; flex-direction: column; gap: 14px; }
.estimator-input label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-soft);
  font-weight: 600;
  margin-bottom: 6px;
}
.estimator-input-icon { display: inline-flex; color: var(--accent); }
.estimator-input input[type="number"] {
  width: 100%;
  padding: 10px 14px;
  font-size: 18px;
  font-weight: 600;
  color: var(--navy);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  background: var(--card);
  text-align: left;
  font-variant-numeric: tabular-nums;
}
.estimator-input input[type="number"]:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
.estimator-result {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.estimator-col {
  padding: 16px 18px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  transition: all 0.18s ease;
}
.estimator-col.is-winner {
  background: linear-gradient(180deg, var(--accent-soft) 0%, var(--card) 100%);
  border-color: var(--primary);
  box-shadow: 0 6px 18px -12px rgba(79, 78, 145, 0.4);
}
.estimator-col-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.estimator-col-amount {
  font-family: var(--serif, inherit);
  font-size: 28px;
  font-weight: 700;
  color: var(--navy);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.estimator-col.is-winner .estimator-col-amount { color: var(--primary); }
.estimator-col-detail { margin-top: 6px; }

.estimator-verdict {
  margin-top: 18px;
  padding: 14px 18px;
  border-radius: var(--radius-s);
  font-size: 15px;
  line-height: 1.45;
  display: flex;
  align-items: center;
  gap: 12px;
}
.estimator-verdict .bullet-icon {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.estimator-verdict.is-sub {
  background: linear-gradient(135deg, var(--accent-soft) 0%, rgba(79, 78, 145, 0.08) 100%);
  color: var(--primary-strong);
  border: 1px solid var(--primary);
  font-weight: 600;
}
.estimator-verdict.is-sub .bullet-icon { color: var(--primary); }
.estimator-verdict.is-pack {
  background: var(--amber-soft);
  color: #8a5a07;
  border: 1px solid rgba(240, 160, 48, 0.4);
}
.estimator-verdict.is-pack .bullet-icon { color: var(--amber); }
.estimator-verdict.is-zero, .estimator-verdict.is-tie {
  background: var(--bg-page);
  color: var(--text-soft);
  border: 1px solid var(--border);
}
.estimator-verdict.is-zero .bullet-icon,
.estimator-verdict.is-tie  .bullet-icon { color: var(--text-muted); }

@media (max-width: 800px) {
  .estimator-grid { grid-template-columns: 1fr; }
  .estimator-result { grid-template-columns: 1fr; }
}

/* --- Réassurance pied de page --------------------------------------- */
.reassurance {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px 32px;
  margin: 24px 0 8px;
  padding: 16px 22px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
}
.reassurance-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--text-soft);
  font-size: 13px;
}
.reassurance-item .icon { color: var(--accent); flex: 0 0 auto; }
@media (max-width: 640px) {
  .reassurance { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* --- Icônes SVG inline (lucide-style) ------------------------------- */
.icon { display: inline-block; vertical-align: middle; flex-shrink: 0; }

/* =====================================================================
 * Écran « Mes marchés » — Socle marché étape 3 (refonte v2).
 * Un SEUL menu vertical : la sidebar latérale existante, dans laquelle
 * on injecte les dossiers via setShellSubnav (mécanisme générique de
 * common.js). La page n'a plus qu'une colonne : barre d'outils + table.
 * ===================================================================== */

/* Wrap normal — l'écran tient désormais sur ~1180 px sans le rail */
.wrap.wrap-wide { max-width: 1180px; }

/* Layout en colonne unique (le rail vit dans la sidebar du shell) */
.marche-page-layout { display: block; }

/* ─── Sous-navigation contextuelle dans la sidebar (fond navy) ────── */
/* Injectée sous l'item « Marchés » actif via setShellSubnav. Style aligné
 * avec .sidebar-item (rgba blanc sur navy) + indentation. */
.sidebar-subnav {
  margin: 6px 0 4px 0;
  padding: 4px 0 4px 8px;
  border-left: 1px solid rgba(255,255,255,0.08);
  margin-left: 18px;
  display: flex; flex-direction: column; gap: 10px;
}
.sidebar-subnav-zone { display: flex; flex-direction: column; }
.sidebar-subnav-zone-head {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 8px 2px;
  color: rgba(255,255,255,0.46);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}
.sidebar-subnav-zone-icon { display: inline-flex; align-items: center; }
.sidebar-subnav-zone-label { flex: 1; }
.sidebar-subnav-add {
  background: transparent;
  color: rgba(255,255,255,0.55);
  padding: 0 6px;
  border: none;
  border-radius: 4px;
  font-size: 16px;
  line-height: 1;
  height: 18px;
  cursor: pointer;
  box-shadow: none;
}
.sidebar-subnav-add:hover { background: rgba(255,255,255,0.10); color: #fff; box-shadow: none; }

.sidebar-subnav-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.sidebar-subnav-list li { margin: 0; padding: 0; }

.sidebar-subnav-item {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 6px;
  padding: 5px 8px 5px 12px;
  border-radius: 6px;
  cursor: pointer;
  color: rgba(255,255,255,0.72);
  font-size: 13px;
  transition: background .12s ease, color .12s ease;
  min-height: 26px;
}
.sidebar-subnav-item.is-sub { padding-left: 26px; }
.sidebar-subnav-item:hover { background: rgba(255,255,255,0.06); color: #fff; }
.sidebar-subnav-item.is-active {
  background: rgba(56,101,200,0.30);
  color: #fff;
  font-weight: 600;
}
.sidebar-subnav-item-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar-subnav-item-count {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: rgba(255,255,255,0.55);
  background: rgba(255,255,255,0.08);
  padding: 1px 7px;
  border-radius: 999px;
  font-weight: 500;
}
.sidebar-subnav-item.is-active .sidebar-subnav-item-count {
  background: rgba(255,255,255,0.18); color: #fff;
}
.sidebar-subnav-item-actions {
  display: inline-flex; gap: 1px;
  opacity: 0; transition: opacity .15s ease;
}
.sidebar-subnav-item:hover .sidebar-subnav-item-actions { opacity: 1; }
.sidebar-subnav-item-actions button {
  background: transparent;
  color: rgba(255,255,255,0.60);
  padding: 3px 4px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  box-shadow: none;
  line-height: 0;
}
.sidebar-subnav-item-actions button:hover { background: rgba(255,255,255,0.12); color: #fff; box-shadow: none; }

/* Feedback drop : pulsation cobalt sur l'item ciblé */
.sidebar-subnav-item.is-dnd-over {
  background: var(--accent);
  color: #fff;
  outline: 2px dashed rgba(255,255,255,0.55);
  outline-offset: -2px;
}
/* Quand on drag une ligne, halo subtil sur la sidebar pour indiquer la zone
 * cible — discret, juste un cue visuel sans agressivité. */
body.is-dragging-marche .shell-sidebar {
  outline: 2px solid rgba(56,101,200,0.35);
  outline-offset: -2px;
}

/* ─── Pane unique : pleine largeur ─────────────────────────────────── */
.marche-pane {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-s);
  padding: 18px 20px 12px;
}

/* Breadcrumb du dossier courant, au-dessus de la toolbar */
.pane-current-folder {
  display: flex; align-items: center; gap: 8px;
  padding: 0 0 12px;
  font-size: 14px;
  flex-wrap: wrap;
}
.pane-current-folder-icon { color: var(--primary); display: inline-flex; }
.pane-current-folder-zone { font-weight: 500; color: var(--text-soft); }
.pane-current-folder-sep { color: var(--text-muted); }
.pane-current-folder-name { font-weight: 600; color: var(--text); }
.pane-current-folder-count { margin-left: auto; font-size: 13px; }

.pane-toolbar {
  display: flex;
  gap: 14px;
  align-items: center;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 10px;
}

.pane-toolbar-actions { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; width: 100%; }
.pane-toolbar-actions-wide .pane-search { flex: 1; }
.pane-toolbar-actions-wide .pane-search-input { width: 100%; }
.pane-search { position: relative; }
.pane-search-input {
  width: 240px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  font: 400 14px var(--sans);
  color: var(--text);
  background: var(--bg-page);
}
.pane-search-input:focus { outline: none; border-color: var(--accent); background: var(--card); }
.pane-pageSize {
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  font: 400 14px var(--sans);
  background: var(--bg-page);
  color: var(--text);
}

/* Étape 7.2 — Panneau « Filtres avancés » (multi-critères, combinables) */
.pane-filters-panel {
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  padding: 14px 16px;
  margin: 0 0 12px;
}
.filters-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px 16px;
}
.filter-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.filter-cell-wide { grid-column: span 2; }
.filter-label {
  font: 600 12px var(--sans);
  color: var(--muted);
  letter-spacing: 0.01em;
}
.filter-input {
  width: 100%;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  font: 400 14px var(--sans);
  color: var(--text);
  background: var(--card);
  box-sizing: border-box;
}
.filter-input:focus { outline: none; border-color: var(--accent); }
.filter-range { display: flex; align-items: center; gap: 6px; }
.filter-range .filter-input { flex: 1; min-width: 0; }
.filter-range-sep { color: var(--muted); font-size: 13px; }
.filters-actions {
  display: flex; justify-content: flex-end;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}
.filters-count-pill {
  display: inline-block;
  margin-left: 8px;
  min-width: 18px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font: 600 11px var(--sans);
  text-align: center;
  line-height: 16px;
}

@media (max-width: 900px) {
  .filters-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .filter-cell-wide { grid-column: span 2; }
}
@media (max-width: 560px) {
  .filters-grid { grid-template-columns: 1fr; }
  .filter-cell-wide { grid-column: span 1; }
  .pane-filters-panel { padding: 12px; }
}

/* Barre de sélection multiple */
.pane-selection-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; margin: 0 0 10px;
  background: var(--accent-soft);
  border-radius: var(--radius-s);
  color: var(--primary);
}
.pane-selection-count { font-weight: 600; flex: 1; }
.ghost-clear { margin-left: auto; }

/* ─── Tableau ─────────────────────────────────────────────────────── */
.marche-table-wrap {
  overflow-x: auto;
  min-height: 200px;
}
.marche-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  table-layout: auto;
}
.marche-table thead th {
  text-align: left;
  font-weight: 600;
  color: var(--text-soft);
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  background: var(--card);
  position: sticky; top: 0;
}
.marche-table thead th.sortable { cursor: pointer; user-select: none; }
.marche-table thead th.sortable:hover { color: var(--primary); }
.marche-table thead th.is-sorted { color: var(--primary); }
.marche-table thead th .sort-arrow {
  display: inline-block; margin-left: 4px; font-size: 11px;
  color: var(--primary);
  font-weight: 700;
  min-width: 10px;
}
.marche-table .col-sel { width: 36px; text-align: center; }
.marche-table .col-team { width: 130px; }
.marche-table .col-act  { width: 90px; text-align: right; }
.marche-table .col-date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.marche-table .col-objet { max-width: 320px; }

.marche-table tbody td {
  padding: 11px 12px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}
.marche-table tbody tr.marche-row:hover { background: var(--bg-page); }
.marche-table tbody tr.is-selected { background: var(--accent-soft); }
.marche-table tbody tr.is-dragging { opacity: 0.4; }
.marche-table tbody tr:last-child td { border-bottom: 0; }

.marche-table .row-link { color: var(--text); font-weight: 500; }
.marche-table .row-link:hover { color: var(--accent); text-decoration: underline; }

.row-act {
  background: transparent;
  color: var(--text-soft);
  padding: 5px 7px;
  border-radius: 5px;
  box-shadow: none;
  opacity: 0;
  transition: opacity .15s ease, background .12s ease, color .12s ease;
}
.marche-table tbody tr.marche-row:hover .row-act { opacity: 1; }
.row-act:hover { background: var(--accent-soft); color: var(--primary); box-shadow: none; }
.row-act-danger:hover { background: rgba(155,44,44,0.12); color: var(--nogo); }

/* Pastilles équipe */
.team-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  border-radius: 50%;
  font-size: 11px;
  font-weight: 600;
  color: #fff;
  margin-right: -6px;
  border: 2px solid var(--card);
  letter-spacing: 0;
}
.team-chip-more {
  background: var(--bg-page-strong);
  color: var(--text-soft);
}

/* État vide */
.empty-state {
  text-align: center;
  padding: 48px 24px;
  color: var(--text-soft);
}
.empty-state-icon { color: var(--text-muted); margin-bottom: 12px; display: inline-flex; }
.empty-state-title { font-size: 16px; color: var(--text); margin-bottom: 6px; font-weight: 500; }
.empty-state-hint { font-size: 13px; color: var(--text-muted); }

/* Pagination */
.marche-pagination {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 4px 6px;
  border-top: 1px solid var(--border);
  margin-top: 10px;
  flex-wrap: wrap; gap: 10px;
}
.pagination-summary { font-size: 13px; }
.pagination-buttons { display: inline-flex; align-items: center; gap: 8px; }
.pagination-page { font-variant-numeric: tabular-nums; font-size: 13px; color: var(--text-soft); }

/* ─── Modale générique ────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(31,42,79,0.36);
  display: flex; align-items: center; justify-content: center;
  z-index: 200;
  padding: 20px;
  backdrop-filter: blur(2px);
}
.modal-backdrop.hide { display: none; }
.modal {
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow-l);
  width: 100%; max-width: 480px;
  max-height: 90vh; overflow: auto;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px 12px;
  border-bottom: 1px solid var(--border);
}
.modal-head h3 { margin: 0; font-size: 16px; }
.modal-close {
  background: transparent; color: var(--text-soft);
  border: none; padding: 4px 8px; cursor: pointer; box-shadow: none;
  font-size: 22px; line-height: 1;
}
.modal-close::before { content: '×'; }
.modal-body { padding: 16px 20px 4px; }
.modal-actions {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 20px 18px;
}

.modal-label {
  display: block;
  font: 500 13px var(--sans);
  color: var(--text-soft);
  margin: 10px 0 5px;
}
/* Astérisque « champ requis » dans un label de modale. La règle
 * `[hidden]` doit gagner sur la couleur ; on l'isole en sélecteur
 * avec spécificité égale pour que `el.hidden = true` masque
 * réellement (cf. bug récurrent `[hidden]` vs class flex). */
.required-mark { color: var(--danger, #b43232); font-weight: 700; }
.required-mark[hidden] { display: none; }

/* Brique `fix/objet-optionnel-creation` — placeholder affiché en
 * italique gris quand un champ texte d'une ligne de marché vit avec
 * une valeur absente (utilisé en `<em class="value-empty">…</em>` à
 * la place de la valeur, comme c'est déjà le cas pour acheteur). */
.value-empty {
  color: var(--text-muted);
  font-style: italic;
  font-weight: normal;
}
.modal-input {
  width: 100%;
  padding: 8px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  font: 400 14px var(--sans);
  background: var(--bg-page);
  color: var(--text);
}
.modal-input:focus { outline: none; border-color: var(--accent); background: var(--card); }
.modal-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}

/* J-D §1.A — modale event : toggle « Journée entière » + inputs time. En
   all_day (défaut) : 2 cellules date_start | date_end sur 1 ligne. En
   horaire (toggle décoché) : la grille REPLIE en 2 lignes de 2 colonnes —
   Début + Heure début sur la 1re, Fin + Heure fin sur la 2e. AUCUN
   débordement horizontal en FR ni DE (libellés plus longs), quel que soit
   l'état du toggle — retouche Laurent avant merge J-D (viewport desktop).
   Le toggle est sémantique — le CSS ne pilote que l'affichage. */
.agenda-modal-all-day-line {
  display: flex; align-items: center; gap: 8px;
  margin: 8px 0 4px;
  font: 400 14px var(--sans);
  cursor: pointer;
}
.agenda-modal-all-day-line input[type="checkbox"] { margin: 0; cursor: pointer; }
.agenda-modal-dates-grid .agenda-modal-time-cell { display: none; }
.agenda-modal-dates-grid.is-horaire {
  /* 2 colonnes date | heure, auto-flow row => 4 items = 2 lignes de 2. */
  grid-template-columns: 1.4fr 0.8fr;
}
.agenda-modal-dates-grid.is-horaire .agenda-modal-time-cell { display: block; }

/* J-D §1.E-G — ligne « Télécharger le fichier calendrier (.ics) » : bouton
   stylé comme un lien pour cohérence visuelle avec les 2 liens jumeaux
   Google/Outlook. `button.link` n'existe pas dans les styles de base, on
   normalise ici pour la modale event. */
.agenda-modal-ics-btn {
  background: transparent; border: 0; padding: 0;
  color: var(--accent, #1a76d2);
  font: inherit; text-decoration: underline;
  cursor: pointer;
}
.agenda-modal-ics-btn:hover { text-decoration: none; }

/* Bouton .danger (action de suppression destructive) */
button.danger {
  background: var(--nogo);
  color: #fff;
  box-shadow: 0 2px 6px -1px rgba(155,44,44,0.35);
}
button.danger:hover { background: #7e2424; box-shadow: 0 4px 12px -2px rgba(155,44,44,0.45); }

.hide { display: none !important; }

/* ─── Responsive : ≤ 720 px ───────────────────────────────────────── */
/* Sous 1024 px : la sidebar du shell se replie elle-même en drawer
 * (mécanisme common.js). Les dossiers vivent dedans — rien de spécifique
 * à ajouter ici à part le breadcrumb au-dessus du tableau qui reste
 * toujours visible (indicateur du dossier courant). */
@media (max-width: 720px) {
  .pane-search-input { width: 100%; }
  .pane-search { flex: 1 1 100%; }
  .marche-table .col-objet { max-width: 200px; }
  .marche-table thead th, .marche-table tbody td { padding: 8px 10px; font-size: 13px; }
  .marche-pagination { flex-direction: column; align-items: flex-start; }
  .pane-current-folder-count { margin-left: 0; width: 100%; }
}

/* =====================================================================
 * Fiche marché — Socle marché étape 4 (marche.html?id=...).
 * 4 zones : en-tête éditable + suivi + équipe + analyses.
 * ===================================================================== */

.page-back { margin-bottom: 14px; }
.page-back a { font-size: 14px; color: var(--text-soft); }
.page-back a:hover { color: var(--accent); }

/* ─── (1) EN-TÊTE ─────────────────────────────────────────────────── */
.fiche-header { padding: 22px 26px; }
.fiche-header-top {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 18px;
  align-items: start;
  margin-bottom: 18px;
}
.fiche-header-main { min-width: 0; }
.fiche-objet {
  font-size: clamp(20px, 2.2vw, 26px);
  font-weight: 600;
  margin: 4px 0 0;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--text);
}
.fiche-header-side {
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
}
.fiche-location {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 13px;
  color: var(--text-soft);
}
.fiche-location-icon { color: var(--primary); display: inline-flex; }
.fiche-location-text { font-weight: 500; }
.fiche-header-quick-actions {
  display: inline-flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end;
}

/* Variant ghost danger : pour la mise à la corbeille depuis la fiche */
button.ghost.ghost-danger {
  color: var(--nogo);
}
button.ghost.ghost-danger:hover {
  background: rgba(155,44,44,0.08);
  color: var(--nogo);
}

/* Grille de métadonnées éditables */
.fiche-meta-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px 22px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.fiche-meta-item { display: flex; flex-direction: column; gap: 4px; }
.fiche-meta-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  font-weight: 500;
}
.fiche-meta-value {
  font-size: 14px;
  color: var(--text);
  min-height: 26px;
}
.fiche-meta-value-static { padding: 3px 0; }

/* ─── Édition inline ──────────────────────────────────────────────── */
.editable-field {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 8px 2px 6px;
  margin: -2px -8px -2px -6px; /* compense le padding pour aligner avec le static */
  border-radius: 6px;
  cursor: text;
  min-height: 26px;
  transition: background .12s ease;
  max-width: 100%;
}
.fiche-objet.editable-field {
  display: flex; align-items: flex-start;
  margin-left: -6px;
}
.editable-field:hover {
  background: var(--bg-page);
}
.editable-display {
  overflow-wrap: anywhere;
  word-break: break-word;
  flex: 1;
}
.editable-pencil {
  background: transparent;
  color: var(--text-muted);
  padding: 2px;
  border: none;
  border-radius: 4px;
  opacity: 0;
  transition: opacity .12s ease, color .12s ease, background .12s ease;
  box-shadow: none;
  display: inline-flex;
}
.editable-field:hover .editable-pencil { opacity: 1; color: var(--accent); }
.editable-pencil:hover { background: var(--card); box-shadow: none; }

.editable-field.is-editing {
  background: var(--bg-page);
  cursor: text;
}
.editable-input {
  flex: 1;
  width: 100%;
  border: 1px solid var(--accent);
  border-radius: var(--radius-s);
  padding: 5px 8px;
  font: inherit;
  background: var(--card);
  color: var(--text);
  outline: none;
  resize: vertical;
}
.fiche-objet .editable-input {
  font-size: clamp(20px, 2.2vw, 26px);
  font-weight: 600;
  line-height: 1.25;
  padding: 4px 8px;
}

/* ─── (4) SUIVI : rail d'étapes ──────────────────────────────────── */
.fiche-suivi { padding: 22px 26px; }
.steps-rail {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex; flex-direction: column;
  gap: 4px;
}
.step-item {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 12px 12px 12px 8px;
  border-radius: 8px;
  position: relative;
}
.step-item:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 25px; top: 100%;
  width: 2px; height: 4px;
  background: var(--border);
}
.step-item.is-active:not(:last-child)::after { background: var(--accent); }

.step-num {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  font-weight: 600;
  font-size: 13px;
  background: var(--bg-page);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.step-item.is-active .step-num {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.step-item.is-empty .step-num {
  background: var(--card);
  color: var(--accent);
  border-color: var(--accent);
  border-style: dashed;
}
.step-body { min-width: 0; }
.step-label {
  font-size: 14px; font-weight: 600;
  color: var(--text);
}
.step-item.is-coming .step-label { color: var(--text-muted); }
.step-info { font-size: 12px; margin-top: 2px; }

.step-coming-badge {
  background: var(--bg-page-strong);
  color: var(--text-muted);
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ─── (2) ÉQUIPE ──────────────────────────────────────────────────── */
.fiche-team .card-head { margin-bottom: 14px; }
.team-members {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
}
.team-member-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--bg-page);
  border-radius: 8px;
  border: 1px solid var(--border);
}
.team-member-row .team-chip {
  margin: 0;
  width: 32px; height: 32px;
  font-size: 13px;
  border: none;
}
.team-member-info { min-width: 0; }
.team-member-name {
  font-size: 14px; font-weight: 500; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.team-member-role { font-size: 12px; margin-top: 1px; }
.team-member-remove {
  background: transparent;
  color: var(--text-muted);
  padding: 4px 6px;
  border-radius: 4px;
  box-shadow: none;
}
.team-member-remove:hover {
  background: rgba(155,44,44,0.10);
  color: var(--nogo);
  box-shadow: none;
}

/* ─── (3) ANALYSES ────────────────────────────────────────────────── */
.fiche-analyses .card-head { margin-bottom: 12px; }
.analysis-list {
  display: flex; flex-direction: column; gap: 8px;
}
.analysis-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 12px 14px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color .12s ease;
}
.analysis-row:hover { border-color: var(--accent); }
.analysis-left {
  display: flex; align-items: center; gap: 16px;
  flex-wrap: wrap;
  min-width: 0;
}
.analysis-meta {
  display: inline-flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.analysis-date {
  font-weight: 500;
  color: var(--text);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.analysis-right {
  display: inline-flex; align-items: center; gap: 10px;
}
.analysis-actions {
  display: inline-flex; align-items: center; gap: 8px;
}

/* card-head local : pour les sections de fiche analyses & équipe.
 * Le projet a déjà .card-head défini ailleurs ; cet override ajoute
 * juste l'alignement vertical baseline + petit séparateur invisible. */
.fiche-analyses .card-head,
.fiche-team .card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* ─── Responsive ──────────────────────────────────────────────────── */
@media (max-width: 768px) {
  .fiche-header-top {
    grid-template-columns: 1fr;
  }
  .fiche-header-side {
    align-items: flex-start;
  }
  .fiche-header-quick-actions {
    justify-content: flex-start;
  }
  .fiche-meta-grid {
    grid-template-columns: 1fr 1fr;
  }
  .analysis-row {
    grid-template-columns: 1fr;
  }
  .analysis-actions { justify-content: flex-start; }
  .step-item {
    grid-template-columns: 32px 1fr auto;
    gap: 10px;
  }
  .step-num { width: 28px; height: 28px; }
}
@media (max-width: 480px) {
  .fiche-meta-grid { grid-template-columns: 1fr; }
  .team-members { grid-template-columns: 1fr; }
}

/* =====================================================================
 * Socle marché — étape 5 : habillage visuel (Marchés + Fiche).
 * AUCUN changement fonctionnel. Réutilise la charte existante (navy /
 * cobalt / Inter) et les classes pills (.pill.GO / .NO_GO / …).
 * ===================================================================== */

/* ─── Lignes workflow (écran Marchés) ────────────────────────────── */
.marches-flow-head {
  display: flex; align-items: center;
  padding: 4px 6px 8px 10px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
}
.marches-flow-selall {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--text-muted);
  cursor: pointer;
}
.marches-flow-selall input { cursor: pointer; }

.marches-flow {
  display: flex; flex-direction: column;
  gap: 4px;
}
.marche-row.workflow-row {
  display: grid;
  grid-template-columns: 28px 1fr auto auto 120px 70px;
  gap: 14px;
  align-items: center;
  padding: 12px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  transition: border-color .12s ease, box-shadow .12s ease, transform .05s ease;
  cursor: grab;
}
.marche-row.workflow-row:hover {
  border-color: var(--accent);
  box-shadow: 0 2px 8px -2px rgba(56,101,200,0.20);
}
.marche-row.workflow-row.is-selected {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.marche-row.workflow-row.is-dragging {
  opacity: 0.45;
  cursor: grabbing;
}
.workflow-row-select { display: flex; align-items: center; justify-content: center; }
.workflow-row-select input { cursor: pointer; }

.workflow-row-main { min-width: 0; }
.workflow-row-title {
  font-size: 15px; font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
}
.workflow-row-title .row-link {
  color: var(--text);
  text-decoration: none;
}
.workflow-row-title .row-link:hover { color: var(--accent); }
.workflow-row-title .row-link.faded { color: var(--text-muted); font-weight: 500; font-style: italic; }

.workflow-row-subline {
  display: flex; align-items: center; gap: 8px;
  margin-top: 3px;
  font-size: 13px;
  color: var(--text-soft);
  flex-wrap: wrap;
}
.row-fact { display: inline-block; white-space: nowrap; }
.row-fact.faded { color: var(--text-muted); font-style: italic; opacity: 0.7; }
.row-dot { color: var(--text-muted); }
/* Dernière activité : discret (gris muted, taille un poil plus petite). */
.row-activity { color: var(--text-muted); font-size: 0.95em; }

/* Colonne « Dernière activité » : slot dédié dans la grille de la ligne
   (piste fixe 120 px en desktop), aligné à droite pour rester scannable
   entre lignes homonymes. Typo HÉRITÉE À L'IDENTIQUE de .row-activity —
   même color muted, même font-size 0.95em ; font-family et font-weight
   hérités de l'ancêtre. Override mobile en 4e rangée dans le bloc
   @media (max-width: 900px) plus bas. */
.workflow-row-activity {
  color: var(--text-muted);
  font-size: 0.95em;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.workflow-row-state {
  display: inline-flex; gap: 6px; align-items: center;
  flex-wrap: wrap; justify-content: flex-end;
}
.workflow-row-team {
  display: inline-flex; justify-content: flex-end;
  min-width: 60px;
}
.workflow-row-actions {
  display: inline-flex; gap: 4px; justify-content: flex-end;
  align-items: center;
  opacity: 0; transition: opacity .15s ease;
}
.marche-row.workflow-row:hover .workflow-row-actions { opacity: 1; }
/* Mobile : actions toujours visibles pour ne pas dépendre du hover. */
@media (hover: none) {
  .workflow-row-actions { opacity: 1; }
}

/* ─── Pastilles d'état (Go/No-Go reco, DCE analysé) ─────────────── */
.state-pill {
  display: inline-flex; align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  border: 1px solid transparent;
}
.state-pill-go        { background: #e3efe4; color: var(--go); border-color: rgba(47,107,58,0.20); }
.state-pill-nogo      { background: #f4e1e1; color: var(--nogo); border-color: rgba(155,44,44,0.20); }
.state-pill-arbitrer  { background: var(--amber-soft); color: var(--arbitrer); border-color: rgba(217,119,6,0.22); }
.state-pill-dce       { background: var(--accent-soft); color: var(--primary); border-color: rgba(79,78,145,0.18); }
.state-pill-lg {
  font-size: 13px;
  padding: 5px 12px;
}

/* ─── FICHE MARCHÉ — étape 5 ──────────────────────────────────── */

/* Titre + pastille d'état alignés */
.fiche-objet-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 4px;
}
.fiche-objet-row .fiche-objet { margin: 0; }

/* Bande de faits horizontale (remplace fiche-meta-grid) */
.fiche-facts-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px 24px;
  padding: 18px 4px 4px;
  border-top: 1px solid var(--border);
  margin-top: 16px;
}
.fiche-fact { min-width: 0; }
.fiche-fact-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  font-weight: 600;
  margin-bottom: 3px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* Étape 7.1 — petit repère « issu du DCE » dans le label de la cellule */
.fact-from-dce {
  display: inline-flex;
  align-items: center;
  background: var(--accent-soft);
  color: var(--primary);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border-radius: 999px;
  text-transform: uppercase;
}
/* Étape 7.1bis — repère « issu de l'avis d'AO » (couleur amber pour
 * distinguer visuellement de la provenance DCE, même format pill). */
.fact-from-avis {
  display: inline-flex;
  align-items: center;
  background: var(--amber-soft);
  color: #8a5a07;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border-radius: 999px;
  text-transform: uppercase;
}
/* Sous-brique ② — badge « SIRET vérifié » + bouton discret « Résoudre ».
 * Vert doux pour signaler une donnée liée à un identifiant stable annuaire.
 * Règles scopées `.acheteur-*` — aucun global touché.                        */
.acheteur-resolved-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(22, 163, 74, 0.10);
  color: #166534;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border-radius: 999px;
  margin-left: 6px;
  /* Le SIRET numérique dans le badge est un seul « mot » avec espaces
   * insécables potentiels — nowrap force le badge à rester sur UNE ligne
   * (il pourra passer sous « Acheteur » si le label est étroit, mais ne
   * s'empilera jamais en 3 lignes syllabiques). */
  white-space: nowrap;
}
.acheteur-resolved-siret {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
}
.acheteur-resolve-btn {
  padding: 2px 8px;
  font-size: 11px;
  /* Passe le bouton en ligne 2 de la cellule via flex-basis 100% — la règle
   * `.fiche-fact:has(.acheteur-resolve-btn) .editable-field { flex-wrap: wrap }`
   * ci-dessous rend ce flex-basis effectif. Le pencil reste en ligne 1
   * à côté de la valeur (comportement existant préservé). */
  flex-basis: 100%;
  margin-left: 0;
  justify-content: flex-start;
  align-self: flex-start;
}

/* Sous-brique ② — correctifs cosmétiques cellule acheteur uniquement.
 * :has() (Chrome 105+, Safari 15.4+, Firefox 121+) cible EXCLUSIVEMENT la
 * cellule contenant `.acheteur-resolve-btn`. AUCUN autre champ impacté :
 * pays / ville / dates / source restent byte-identiques. Aucun global touché. */
.fiche-fact:has(.acheteur-resolve-btn) {
  /* Le grid parent .fiche-facts-strip a min-width:0 sur les items — ce qui
   * autorise le shrink sous le contenu. Sur la seule cellule acheteur on
   * force un plancher raisonnable pour éviter que « Ville de Nantes » ne
   * casse en syllabes via .editable-display{ overflow-wrap:anywhere }. */
  min-width: 240px;
}
.fiche-fact:has(.acheteur-resolve-btn) .editable-field {
  /* Autorise le bouton Résoudre à passer en ligne 2 (flex-basis:100%). */
  flex-wrap: wrap;
  row-gap: 6px;
}
.fiche-fact:has(.acheteur-resolve-btn) .editable-display {
  /* Override du break-word / overflow-wrap:anywhere de .editable-display :
   * la valeur acheteur reste sur UNE ligne avec ellipsis si trop long. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: normal;
  overflow-wrap: normal;
}
@media (max-width: 768px) {
  /* Tablette/mobile : la cellule acheteur prend toute la largeur du grid
   * (spanne les 2 colonnes) — évite le débordement horizontal quand
   * min-width:240px ne rentre pas dans 1fr 1fr. */
  .fiche-facts-strip .fiche-fact:has(.acheteur-resolve-btn) {
    grid-column: 1 / -1;
  }
}
/* Sous-brique ② — le badge « ✓ SIRET vérifié XXX XXX XXX XXXXX » est
 * `white-space:nowrap` par construction (le numéro SIRET est un bloc
 * insécable voulu). Sans flex-wrap sur le label parent, il étend la
 * line-box du .fiche-fact-label et déborde horizontalement sur la
 * cellule voisine (« Pays »). Le fix passe le label en flex+wrap
 * UNIQUEMENT sur la cellule acheteur : le badge retombe SOUS le libellé
 * « Acheteur » quand il ne tient plus à côté, sans jamais déborder.
 * Rendu badge absent (non résolu) préservé : un seul flex item = même
 * disposition qu'un div block. */
.fiche-fact:has(.acheteur-resolve-btn) .fiche-fact-label {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 6px;
  row-gap: 2px;
}
.fiche-fact:has(.acheteur-resolve-btn) .acheteur-resolved-badge {
  /* column-gap du parent flex remplace le margin-left dans ce contexte. */
  margin-left: 0;
}
.acheteur-search-inputs {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  margin: 12px 0;
  flex-wrap: wrap;
}
.acheteur-search-input {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
  min-width: 180px;
}
.acheteur-search-input input {
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
}
/* Sous-brique ③bis — total-line encadrée discrètement pour émerger du bruit
   (Piste A aération). Classe existante restylée en place — pas de rename. */
.acheteur-total-line {
  margin: 8px 0 8px 0;
  padding: 6px 10px;
  background: rgba(0, 0, 0, 0.03);
  border-radius: 6px;
  font-size: 13px;
}
.acheteur-candidate-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 320px;
  overflow-y: auto;
}
/* Sous-brique ③bis — Piste B « cartes ». Chaque item porte sa propre
   bordure arrondie, pas de bordure wrapper. Sélection = classe .is-selected
   ajoutée conditionnellement par _renderAcheteurCandidate (JS). */
.acheteur-candidate-item {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 8px;
  transition: border-color 120ms, background 120ms;
}
.acheteur-candidate-item:last-child {
  margin-bottom: 0;
}
.acheteur-candidate-item:hover {
  border-color: var(--primary);
  background: rgba(0, 0, 0, 0.02);
}
.acheteur-candidate-item.is-selected {
  border-color: var(--primary);
  background: var(--accent-soft, #DCE7FB);
}
.acheteur-candidate-item label {
  display: flex;
  gap: 12px;
  cursor: pointer;
  align-items: center;
}
.acheteur-candidate-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}
.acheteur-candidate-name {
  font-weight: 600;
  color: var(--text);
}
.acheteur-candidate-error {
  color: var(--nogo);
  padding: 8px 12px;
  background: rgba(155, 44, 44, 0.06);
  border-radius: 6px;
}
/* Sous-brique ③bis — Piste A « aération » de la modale ②.
   - Description avec marge basse claire.
   - Bouton Rechercher sur sa propre ligne, aligné à droite.
   - Total-line encadrée discrètement pour émerger du bruit. */
.acheteur-modal-desc {
  margin: 0 0 12px 0;
}
.acheteur-search-actions {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 16px 0;
}
.fiche-fact-value {
  font-size: 14px;
  color: var(--text);
  min-height: 24px;
}
.fiche-fact-value-static { padding: 2px 0; }
.fiche-fact.is-empty .fiche-fact-value { color: var(--text-muted); }
.fact-empty {
  color: var(--text-muted);
  font-style: italic;
  font-size: 13px;
  opacity: 0.7;
}

/* Ligne équipe sous l'en-tête */
.fiche-team-line {
  display: flex; align-items: center; gap: 12px;
  padding-top: 16px;
  margin-top: 14px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
.fiche-team-empty { font-style: italic; }
.fiche-team-line-add { margin-left: auto; }
.fiche-team-line .team-cluster { display: inline-flex; }
.fiche-team-line .team-chip {
  width: 30px; height: 30px;
  font-size: 12px;
}

/* ─── Progress rail (Suivi) — pastilles done/available/coming ────── */
.progress-rail {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex; flex-direction: column;
  gap: 6px;
}
.progress-step {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 10px 12px 10px 8px;
  border-radius: 8px;
  position: relative;
  transition: background .12s ease;
}
.progress-step:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 25px; top: calc(100% - 2px);
  width: 2px; height: 8px;
  background: var(--border);
}
.progress-step.step-done:not(:last-child)::after { background: var(--accent); }

.step-bullet {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  font-weight: 600;
  font-size: 13px;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
  flex-shrink: 0;
}
.step-done .step-bullet {
  background: var(--accent);
  color: #fff;
  border: 2px solid var(--accent);
}
.step-available .step-bullet {
  background: var(--card);
  color: var(--accent);
  border: 2px solid var(--accent);
}
.step-coming .step-bullet {
  background: var(--bg-page-strong);
  color: var(--text-muted);
  border: 2px solid var(--border);
}
.step-body { min-width: 0; }
.step-label { font-size: 14px; font-weight: 600; color: var(--text); }
.step-coming .step-label { color: var(--text-muted); font-weight: 500; }
.step-meta { font-size: 12px; margin-top: 2px; color: var(--text-soft); }
.step-cta { white-space: nowrap; }

/* Coming-badge déjà défini avant — variante compacte ici */
.progress-step .step-coming-badge {
  background: var(--bg-page-strong);
  color: var(--text-muted);
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ─── Rail-cockpit : pill coût + prochaine étape + actions groupées ─────
 * Convention : le coût en crédits affiché à côté de chaque action lançable
 * vient TOUJOURS du catalogue serveur (/api/catalog/analysis-types), jamais
 * codé en dur dans le front. La pill reste discrète (chip neutre, pas une
 * pill de verdict — couleur pleine réservée aux recos Go/No-Go).
 * Le solde global reste dans la topbar (pas de duplication).
 */
.progress-step .step-actions {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}
.step-cost-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* « À venir » : bouton désactivé visiblement, pas de pill coût */
.progress-step.step-coming .step-cta[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* Mise en évidence sobre de la prochaine action recommandée :
 * tint ambre (encouragement, pas alerte), bord gauche coloré comme un
 * highlight discret. La step reste cliquable et son CTA primary inchangé. */
.progress-step.step-next {
  background: var(--amber-soft);
  box-shadow: inset 3px 0 0 var(--amber);
}
.step-next-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  background: var(--amber);
  color: #1a1407;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  vertical-align: middle;
}

/* ─── Empty states chaleureux (sections analyses) ──────────────── */
.empty-state-warm {
  text-align: center;
  padding: 36px 24px;
  background: var(--bg-page);
  border: 1px dashed var(--border-strong);
  border-radius: 10px;
  color: var(--text-soft);
}
.empty-state-warm .empty-state-icon {
  color: var(--accent);
  margin-bottom: 10px;
  display: inline-flex;
}
.empty-state-warm .empty-state-title {
  font-size: 15px;
  color: var(--text);
  font-weight: 600;
  margin-bottom: 6px;
}
.empty-state-warm .empty-state-hint {
  font-size: 13px;
  color: var(--text-muted);
  max-width: 460px;
  margin: 0 auto 16px;
  line-height: 1.5;
}
.empty-state-warm .primary {
  display: inline-block;
  text-decoration: none;
}

/* ─── Responsive ───────────────────────────────────────────────── */
@media (max-width: 900px) {
  .marche-row.workflow-row {
    grid-template-columns: 24px 1fr auto;
    gap: 10px;
    padding: 12px;
  }
  .workflow-row-state {
    grid-column: 2 / 4;
    grid-row: 2;
    justify-content: flex-start;
    gap: 5px;
  }
  .workflow-row-team {
    grid-column: 2 / 4;
    grid-row: 3;
    justify-content: flex-start;
  }
  .workflow-row-actions {
    grid-column: 3;
    grid-row: 1;
    opacity: 1;
  }
  /* Colonne « Dernière activité » : en desktop c'est un slot dédié aligné
     à droite (piste fixe 120 px) ; en mobile la ligne s'empile en rangées
     (state row 2, team row 3), le fact activité prend row 4 sous l'équipe,
     aligné à gauche pour cohérence avec state/team. Source unique préservée
     à tous les viewports (pas de perte d'info : dédup sous-ligne exigée). */
  .workflow-row-activity {
    grid-column: 2 / 4;
    grid-row: 4;
    text-align: left;
  }
}
@media (max-width: 768px) {
  .fiche-facts-strip { grid-template-columns: 1fr 1fr; }
  .fiche-objet-row { gap: 8px; }
  .progress-step { grid-template-columns: 32px 1fr auto; gap: 10px; }
  .step-bullet { width: 28px; height: 28px; }
}
@media (max-width: 480px) {
  .fiche-facts-strip { grid-template-columns: 1fr; }
  .fiche-team-line { gap: 8px; }
  .fiche-team-line-add { margin-left: 0; width: 100%; justify-content: center; }
}

/* =====================================================================
 * Étape 6 — entrée unique : modales de lancement depuis la fiche +
 * bloc Dernières analyses sur l'Accueil.
 * ===================================================================== */

/* Aperçu des métadonnées du marché dans les modales de lancement */
.launch-meta-preview {
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  padding: 10px 12px;
  margin: 8px 0 14px;
  display: grid;
  gap: 4px;
  grid-template-columns: 1fr;
}
.launch-meta-row {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 12px;
  align-items: baseline;
  font-size: 13px;
}
.launch-meta-label {
  color: var(--text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}
.launch-meta-value {
  color: var(--text);
  word-break: break-word;
}

/* Brique « fiche-actions-in-context » — récap sobre des pièces déjà déposées
 * sur le marché, visible dans les modales Go/No-Go et DCE. Informationnel :
 * aide l'utilisateur à se repérer sans rien auto-importer (les pipelines
 * d'analyse restent autonomes). Palette neutre, pas de couleur pleine — la
 * couleur reste réservée aux verdicts (Go/No-Go) et à l'urgence d'échéance. */
.launch-existing-docs {
  background: var(--accent-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  padding: 10px 12px;
  margin: 6px 0 12px;
}
.launch-existing-docs-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 6px;
}
.launch-existing-docs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.launch-existing-doc {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text);
}
.launch-existing-doc-icon {
  display: inline-flex;
  color: var(--text-soft);
  flex: 0 0 auto;
}
.launch-existing-doc-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.launch-existing-docs-hint {
  margin: 8px 0 0;
  font-size: 11px;
}

/* Tabs pour la modale DCE (upload / paste) */
.launch-dce-tabs {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  padding: 3px;
  background: var(--bg-page);
  margin: 4px 0 12px;
}
.launch-tab {
  background: transparent;
  color: var(--text-soft);
  padding: 5px 12px;
  border-radius: 5px;
  border: none;
  font: 500 13px var(--sans);
  cursor: pointer;
  box-shadow: none;
}
.launch-tab.is-active {
  background: var(--card);
  color: var(--text);
  box-shadow: var(--shadow-s);
}
.launch-tab:hover { color: var(--text); box-shadow: none; }

.launch-dce-panel { margin-top: 6px; }
.launch-dce-panel.hide { display: none !important; }

/* Brique « Analyser un DCE déjà déposé » — onglet « existing » :
 * liste des pièces du marché sous forme de radios cliquables.
 * Les pièces non extractibles (ODT, ZIP, autres) ont .is-unsupported,
 * radio désactivé et libellé honnête « bientôt pris en charge ».
 * Palette neutre cohérente avec la palette des tags sobres : aucune
 * couleur pleine, la couleur reste réservée aux verdicts Go/No-Go.
 *
 * Ajustements v2 : fond grisé clair (var(--bg-page)) pour bien détacher
 * les rows du fond blanc de la modale, état :has(:checked) qui surligne
 * la pièce présélectionnée en cobalt soft — supprime l'effet « radio vide
 * flottant au milieu de la modale » qu'on avait quand aucune row n'était
 * cochée à l'ouverture. */
.launch-piece-list {
  list-style: none;
  margin: 4px 0 8px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.launch-piece-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  background: var(--bg-page);
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease, box-shadow 0.12s ease;
}
.launch-piece-row:hover { border-color: var(--primary); background: #fff; }
.launch-piece-row:has(input[type="radio"]:checked) {
  border-color: var(--primary);
  background: var(--accent-soft);
  box-shadow: 0 0 0 1px var(--primary) inset;
}
.launch-piece-row > input[type="radio"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--primary);
}
.launch-piece-row.is-unsupported {
  cursor: not-allowed;
  background: #fff;
  opacity: 0.62;
}
.launch-piece-row.is-unsupported:hover { border-color: var(--border); background: #fff; }
.launch-piece-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.launch-piece-name {
  font-weight: 500;
  font-size: 14px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.launch-piece-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--text-soft);
}
.launch-piece-meta .tag { font-size: 11px; padding: 2px 8px; }
.launch-piece-size { white-space: nowrap; }
.launch-piece-unsupported {
  margin-top: 2px;
  font-size: 11px;
  font-style: italic;
  color: var(--text-soft);
}
.launch-piece-foot { margin: 4px 0 0; font-size: 11px; }

/* Etat « en cours » dans la modale pendant l'IA */
.launch-running {
  text-align: center;
  padding: 32px 16px;
}
.launch-running-spinner {
  display: inline-block;
  width: 36px; height: 36px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
  margin-bottom: 14px;
}
@keyframes spin { to { transform: rotate(360deg); } }
.launch-running-msg {
  font-size: 14px;
  color: var(--text);
  font-weight: 500;
}

/* Brique « analyse-progress-ui » — barre de progression honnête pour
 * les analyses IA en cours. Remplace le spinner qui tournait dans la
 * modale. Palette sobre : cobalt sur la barre, vert sur le check final
 * (seul moment où une couleur pleine est utilisée — le succès EST un
 * verdict, exception assumée à la règle « couleur réservée aux
 * recommandations Go/No-Go »). */
.ap-wrap {
  padding: 28px 6px 22px;
  text-align: center;
}
.ap-step {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  margin-bottom: 14px;
  min-height: 20px;
  transition: color 0.2s ease;
}
.ap-bar {
  position: relative;
  width: 100%;
  max-width: 360px;
  margin: 0 auto;
  height: 8px;
  border-radius: 999px;
  background: var(--bg-page-strong, #eef0f3);
  overflow: hidden;
}
.ap-fill {
  height: 100%;
  width: 0%;
  background: var(--primary);
  border-radius: 999px;
  transition: width 0.3s ease-out;
}
.ap-hint {
  margin-top: 12px;
  font-size: 11px;
  color: var(--text-soft);
}
/* État « ETA dépassée » : la barre reste au plafond et le wrap pulse
 * discrètement (1.6 s, opacité 1 → 0.6 → 1) pour signaler « toujours
 * en cours », sans prétendre une fausse progression. */
.ap-wrap.is-pulsing .ap-fill {
  animation: ap-pulse 1.6s ease-in-out infinite;
}
@keyframes ap-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}
/* État final « done » : barre cobalt → vert (verdict succès), check
 * dans le libellé d'étape. */
.ap-wrap.is-done .ap-fill {
  background: #2f6b3a;
  animation: none;
}
.ap-wrap.is-done .ap-step {
  color: #1f7a4d;
  font-weight: 600;
}
.ap-check {
  display: inline-block;
  font-weight: 700;
  margin-right: 2px;
}
/* État final « erreur » : croix rouge, message d'erreur tel quel. */
.ap-wrap.is-error .ap-step {
  color: #a32a2a;
  font-weight: 500;
}
.ap-cross {
  display: inline-block;
  font-weight: 700;
  margin-right: 2px;
  color: #a32a2a;
}

/* === Bloc « Dernières analyses » (Accueil) ============================ */
.recent-analyses-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column;
  gap: 6px;
}
.recent-analysis-row { margin: 0; padding: 0; }
.recent-analysis-link {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 12px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  text-decoration: none;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.recent-analysis-link:hover {
  border-color: var(--accent);
  box-shadow: 0 2px 8px -2px rgba(56,101,200,0.20);
  color: var(--text);
}
.recent-analysis-main { min-width: 0; }
.recent-analysis-title {
  font-size: 14px; font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.recent-analysis-sub {
  margin-top: 3px;
  display: flex; gap: 8px; flex-wrap: wrap;
  align-items: center;
}
.recent-analysis-side {
  display: inline-flex; align-items: center; gap: 8px;
  justify-content: flex-end;
}

@media (max-width: 600px) {
  .launch-meta-row { grid-template-columns: 1fr; gap: 2px; }
  .launch-meta-label { font-size: 10.5px; }
  .recent-analysis-link { padding: 10px 12px; }
}

/* =============================================================================
 * Accueil « effet waow » + palette de tags SOBRE et RÉUTILISABLE
 *
 * Convention (à appliquer partout où on ajoute un tag) :
 *   .tag                          tag de base, gris neutre (font 11.5/16, padding 2x8)
 *   .tag.tag-status               statut : petit point coloré devant + texte neutre
 *   .tag.tag-reco-go              recommandation Go    → couleur pleine mate verte
 *   .tag.tag-reco-no-go           recommandation No-Go → couleur pleine mate rouge
 *   .tag.tag-reco-arbitrer        recommandation à arbitrer → couleur pleine mate ambre
 *   .tag.tag-urgent               urgence d'échéance < 3j → ambre/rouge plein
 *   .tag.tag-soon                 urgence d'échéance 3-14j → ambre clair
 *
 * Couleur pleine = fond coloré opaque + texte blanc, RÉSERVÉE aux recos finales
 * (sortie irréversible d'un Go/No-Go) et à l'urgence d'échéance. Tout le reste
 * est neutre — pour éviter l'effet « sapin de Noël » qui sature l'œil.
 * =========================================================================== */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--bg-page-strong);
  color: var(--text-soft);
  font: 600 11.5px/16px var(--sans);
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.tag-status::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--text-muted);
  flex-shrink: 0;
}
.tag-status.dot-success::before  { background: var(--go); }
.tag-status.dot-warning::before  { background: var(--arbitrer); }
.tag-status.dot-danger::before   { background: var(--nogo); }
.tag-status.dot-info::before     { background: var(--accent); }
.tag-reco-go,
.tag-reco-no-go,
.tag-reco-arbitrer,
.tag-urgent,
.tag-soon {
  color: #fff;
}
.tag-reco-go        { background: var(--go); }
.tag-reco-no-go     { background: var(--nogo); }
.tag-reco-arbitrer  { background: var(--arbitrer); }
.tag-urgent         { background: var(--nogo); }
.tag-soon           { background: var(--arbitrer); color: #fff; }

/* Dashboard Accueil — grille cards (KPIs + donut + activity).
 * Point 1 alignement layout (Jalons & rappels V1) : `#dashboard-zone` reste
 * SANS padding latéral, ses enfants directs (.dashboard-kpis grid, .dashboard-row
 * grid) touchent les bords de `.wrap`. Le CONTENU (h3, texte, valeurs) est
 * aligné sur celui des `.card` frères en portant leur padding aux tuiles
 * elles-mêmes : `.kpi-card` et `.panel` passent à padding 28px (== padding
 * `.card`). Bordures et contenus se retrouvent à la même abscisse que ceux
 * de tenders-section / map-section / agenda-panel. L'agenda est rendu hors
 * `#dashboard-zone` (cf. dashboard.html) au même niveau que tenders/map. */
.dashboard-zone { display: grid; grid-template-columns: 1fr; gap: 16px; margin: 18px 0 8px; }
.dashboard-kpis {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}
.kpi-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 18px 16px;
  box-shadow: var(--shadow-s);
  display: flex; flex-direction: column; gap: 4px;
}
/* Point 1 alignement layout dashboard (Jalons & rappels V1) : dans le
 * `#dashboard-zone` du dashboard user, les tuiles KPI passent à padding
 * 28px pour que leur CONTENU (eyebrow, valeur, hint) s'aligne latéralement
 * sur le contenu des `.card` frères (tenders-section, map-section, agenda).
 * Scoping strict `.dashboard-kpis .kpi-card` — les KPIs admin restent en
 * padding 18px (cf. admin-client.js / admin-overview.js). */
.dashboard-kpis .kpi-card { padding: 28px 28px 24px; }
.kpi-card .kpi-eyebrow {
  font: 600 11px var(--sans); color: var(--text-muted);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.kpi-card .kpi-value {
  font: 700 32px/1.05 var(--sans); color: var(--text);
  margin-top: 4px;
}
.kpi-card .kpi-suffix { font-size: 18px; color: var(--text-muted); margin-left: 2px; }
.kpi-card .kpi-hint { font-size: 12.5px; color: var(--text-muted); margin-top: 4px; }
.kpi-card .kpi-na { color: var(--text-muted); font: 500 18px var(--sans); }

/* Donut pipeline + légende — la grille du donut est 2 colonnes (graphe + légende)
 * en desktop, empilées en mobile. Quand sufficiency.pipeline est false on
 * affiche un état vide léger à la place. */
.dashboard-row {
  display: grid;
  /* Post-ajustement layout Jalons & rappels V1 : la rangée héberge désormais
   * Pipeline (donut) + Activité (barres) — deux graphes à hauteurs
   * comparables. L'agenda a été sorti en pleine largeur (`.agenda-panel`
   * autonome). Colonnes égales (1fr 1fr) pour laisser aux deux graphes la
   * même surface (le donut a un aspect ratio 1:1 borné, les barres
   * s'adaptent). */
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  /* align-items:start conservé — pas d'étirement forcé même si un des
   * panneaux se remplit avec une légende plus longue. */
  align-items: start;
}
/* Mode solo : quand Activité est masqué (sufficiency.activity false), la
 * rangée passe en 1 colonne — Pipeline occupe seul la largeur, aucune
 * colonne fantôme. Miroir du même sélecteur `.dashboard-row.dashboard-row-solo`
 * appliqué par home.js selon la valeur de `s.activity`. */
.dashboard-row.dashboard-row-solo {
  grid-template-columns: 1fr;
}
.dashboard-row > .panel { min-width: 0; }
.panel {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* Point 1 alignement layout dashboard (Jalons & rappels V1) : `.panel`
   * n'est utilisé que par Pipeline et Activity dans `.dashboard-row`. On
   * aligne son padding sur celui de `.card` (28px) pour que les h3/légendes
   * internes tombent à la même abscisse que le h2 des cards frères. */
  padding: 28px;
  box-shadow: var(--shadow-s);
}
.panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 12px; gap: 12px;
}
.panel-head h3 { margin: 0; font: 700 16px var(--sans); color: var(--text); }
.panel-head .panel-sub { font-size: 12.5px; color: var(--text-muted); }

.donut-wrap { display: grid; grid-template-columns: 160px 1fr; gap: 18px; align-items: center; }
.donut-canvas-zone { width: 160px; height: 160px; position: relative; }
.donut-center {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  pointer-events: none;
}
.donut-center .donut-center-value { font: 700 22px var(--sans); color: var(--text); }
.donut-center .donut-center-label { font: 500 11px var(--sans); color: var(--text-muted); }
.donut-legend { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.donut-legend li {
  display: flex; align-items: center; gap: 8px;
  font: 500 13px var(--sans); color: var(--text);
}
.donut-legend .legend-swatch {
  width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0;
}
.donut-legend .legend-count { margin-left: auto; color: var(--text-muted); font-weight: 600; }

/* Liste des prochaines échéances */
.deadlines-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; }
.deadline-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 14px;
  padding: 10px 0;
  border-bottom: 1px dashed var(--border);
  text-decoration: none;
  color: inherit;
}
.deadline-row:last-child { border-bottom: 0; }
.deadline-row:hover { background: var(--bg-page); }
.deadline-row .deadline-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.deadline-row .deadline-objet {
  font: 600 14px var(--sans); color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.deadline-row .deadline-sub {
  font: 500 12.5px var(--sans); color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.deadline-row .deadline-side {
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
}

/* Activity chart — un canvas plein largeur, dans une panel dédiée.
 * Hauteur canvas calée sur la hauteur naturelle du frère Pipeline dans
 * `.dashboard-row` (align-items:start, cf. supra). Bilan mesuré (FR,
 * 1440×900) : Pipeline offsetHeight 251 (head 21.38+12 + donut 160 +
 * padding 28+28 + border 1+1) ; côté Activity, head+foot+padding+border
 * = 118, donc canvas cible = 133 pour atterrir à panel 252 → delta 1 px,
 * dans la tolérance ±1 px de C-DB-1. Mini-passe dashboard G1 (27/08/2026).
 * Chart.js responsive+!aspect suit la hauteur du parent. */
.activity-canvas-zone { width: 100%; height: 133px; position: relative; }
.activity-foot { font-size: 12.5px; color: var(--text-muted); margin-top: 8px; }

/* États vides légers (data-aware) */
.dashboard-empty {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 24px 8px; text-align: center;
  color: var(--text-muted);
}
.dashboard-empty .empty-title { font: 600 14px var(--sans); color: var(--text-soft); }
.dashboard-empty .empty-hint { font-size: 12.5px; max-width: 360px; }

@media (max-width: 900px) {
  .dashboard-row { grid-template-columns: 1fr; }
  .dashboard-kpis { grid-template-columns: 1fr; }
  .donut-wrap { grid-template-columns: 1fr; justify-items: center; }
  .donut-canvas-zone { width: 180px; height: 180px; }
  .donut-legend { width: 100%; max-width: 320px; }
}

/* =========================================================================
 * Brique « Éléments externes » étape 2 — section fiche marché.
 *
 * Palette sobre :
 *   - Pas de couleur PLEINE en dehors des pills de recommandation
 *     (.pill.GO / .NO_GO / .A_ARBITRER — déjà définies plus haut).
 *   - La carte ajustée mise en évidence quand differs=true utilise une
 *     bordure cobalt + fond accent-soft TRÈS clair, pas un plein agressif.
 *   - Les points signés du breakdown : vert sobre pour positif, navy pour
 *     zéro, rouge sobre pour négatif. Couleur de TEXTE seule (pas de fond
 *     plein), pour préserver la convention « plein = verdict seulement ».
 * ========================================================================= */
.fiche-elements-externes { /* hérite de .card */ }

.ee-cards {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
  margin: 14px 0 4px;
}
.ee-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  background: #fff;
  display: flex; flex-direction: column; gap: 6px;
  position: relative;
}
.ee-card-eyebrow {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-muted);
}
.ee-card-score {
  font: 700 28px var(--sans); color: var(--navy);
  display: flex; align-items: baseline; gap: 8px;
}
.ee-card-score-unit { font: 500 13px var(--sans); color: var(--text-muted); }
.ee-card-delta {
  font: 600 13px var(--sans); color: var(--primary);
  padding: 2px 8px; border-radius: 999px;
  background: var(--accent-soft);
}
.ee-card-reco { display: flex; }
.ee-card-flag {
  font-size: 12px; color: var(--primary);
  border-top: 1px dashed rgba(56,101,200,0.25);
  padding-top: 6px; margin-top: 4px;
}

/* Surlignage SOBRE de la carte ajustée quand differs=true : bordure cobalt
 * un peu plus épaisse + halo accent-soft à gauche. Pas de couleur pleine,
 * pas d'animation : on souligne juste « c'est le moment qui compte ». */
.ee-card-highlighted {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), -3px 0 0 var(--accent-soft);
}

.ee-notice {
  margin: 14px 0 4px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 12px 14px;
  background: #fbfbfd;
}
.ee-notice-info .ee-notice-title { font: 600 13px var(--sans); color: var(--text); margin-bottom: 4px; }
.ee-notice-info .ee-notice-body { font-size: 12.5px; color: var(--text-muted); }

.ee-breakdown {
  margin: 14px 0 6px;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  background: #fbfbfd;
}
.ee-breakdown-title {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-muted);
  margin-bottom: 8px;
}
.ee-breakdown-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.ee-breakdown-row {
  display: grid; grid-template-columns: 1fr auto 1.4fr auto; align-items: center; gap: 10px;
  font-size: 13.5px;
}
.ee-breakdown-factor { color: var(--text); font-weight: 500; }
.ee-breakdown-arrow { color: var(--text-muted); }
.ee-breakdown-level { color: var(--text-muted); }
.ee-breakdown-points {
  font: 600 13.5px var(--sans);
  font-variant-numeric: tabular-nums;
  min-width: 38px; text-align: right;
}
.ee-breakdown-points.is-pos  { color: var(--go); }
.ee-breakdown-points.is-zero { color: var(--text-muted); }
.ee-breakdown-points.is-neg  { color: var(--nogo); }

.ee-synthese {
  margin: 6px 0 10px;
  padding: 10px 14px;
  border-left: 3px solid var(--primary);
  background: #fbfafd;
  border-radius: 0 6px 6px 0;
  color: var(--text); font-size: 13.5px; line-height: 1.5;
}

.ee-form {
  margin-top: 12px;
  border-top: 1px solid var(--border);
  padding-top: 14px;
}
.ee-form-head { margin-bottom: 12px; display: flex; flex-direction: column; gap: 2px; }
.ee-form-title { font: 600 14px var(--sans); color: var(--text); }
/* Lien discret vers la page Réglages — découvrabilité de l'écran d'édition
 * du barème et des seuils sans surcharger l'interface (texte muted + flèche). */
.ee-form-settings-link {
  margin-top: 2px;
  color: var(--accent);
  text-decoration: none;
}
.ee-form-settings-link:hover { color: var(--accent-strong); text-decoration: underline; }

.ee-factors {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
}
.ee-factor {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  background: #fff;
  display: flex; flex-direction: column; gap: 8px;
}
.ee-factor-head { display: flex; flex-direction: column; gap: 2px; }
.ee-factor-label { font: 600 13px var(--sans); color: var(--text); }
.ee-factor-desc { margin: 0; font-size: 12px; line-height: 1.4; }
.ee-factor-select {
  width: 100%;
  font-size: 13px;
}

/* Zone de note : apparaît uniquement quand un niveau est sélectionné (cf.
 * renderEeFactor). Apparence de champ réel — label visible, fond clair,
 * bordure définie, état de focus cobalt. Le hint en-dessous est rattaché
 * au champ comme une aide discrète, pas comme un bloc autonome. */
.ee-factor-note-wrap {
  display: flex; flex-direction: column; gap: 4px;
  margin-top: 2px;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
}
.ee-factor-note-label {
  font: 500 12px var(--sans);
  color: var(--text-soft);
}
.ee-factor-note {
  width: 100%;
  font: 400 13px var(--sans); line-height: 1.45;
  color: var(--text);
  background: #fcfcfe;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  resize: vertical;
  min-height: 52px;
  transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
}
.ee-factor-note::placeholder { color: var(--text-muted); }
.ee-factor-note:hover { background: #fff; border-color: rgba(56,101,200,0.30); }
.ee-factor-note:focus {
  outline: none;
  background: #fff;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(56,101,200,0.15);
}
.ee-factor-note-hint { font-size: 11px; line-height: 1.35; }

@media (max-width: 900px) {
  .ee-cards { grid-template-columns: 1fr; }
  .ee-factors { grid-template-columns: 1fr; }
  .ee-breakdown-row { grid-template-columns: 1fr auto; row-gap: 2px; }
  .ee-breakdown-arrow, .ee-breakdown-level { grid-column: 1 / -1; padding-left: 0; }
}

/* =========================================================================
 * Brique « Réglages d'entreprise » étape 2 — page autonome reglages.html.
 *
 * Palette sobre, miroir des conventions :
 *   - 3 bandes de la visualisation utilisent les couleurs des verdicts
 *     (cf. .pill.GO / NO_GO / A_ARBITRER) — couleur PLEINE matte sur ce
 *     composant car la barre représente LA frontière entre les recos,
 *     donc le verdict est intrinsèque à la chose visualisée.
 *   - Le reste reste neutre (gris/cobalt) pour ne pas surcharger.
 * ========================================================================= */
.reglages-section { margin-bottom: 20px; }
.reglages-bound-hint { margin-bottom: 14px; }

.rg-factors { display: flex; flex-direction: column; gap: 18px; }
.rg-factor {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 16px;
  background: #fff;
}
.rg-factor-head { margin-bottom: 12px; }
.rg-factor-label { font: 600 14px var(--sans); color: var(--text); }
.rg-factor-desc { margin: 4px 0 0; line-height: 1.4; }

.rg-levels {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
}
.rg-level { display: flex; flex-direction: column; gap: 4px; }
.rg-level-label { font: 500 12px var(--sans); color: var(--text-soft); }
.rg-points-input {
  width: 100%;
  font: 600 14px var(--sans);
  font-variant-numeric: tabular-nums;
  text-align: center;
  background: #fcfcfe;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
}
.rg-points-input:hover { background: #fff; border-color: rgba(56,101,200,0.30); }
.rg-points-input:focus {
  outline: none; background: #fff; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(56,101,200,0.15);
}

.reglages-seuils-explainer {
  font-size: 13.5px; color: var(--text); line-height: 1.5;
  border-left: 3px solid var(--primary);
  background: #fbfafd;
  padding: 10px 14px; border-radius: 0 6px 6px 0;
  margin: 4px 0 14px;
}

.rg-seuils {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  margin-bottom: 16px;
}
.rg-seuil-field {
  display: flex; flex-direction: column; gap: 4px;
  position: relative;
}
.rg-seuil-field label { font: 500 12px var(--sans); color: var(--text-soft); }
.rg-threshold-input {
  width: 100%;
  font: 600 16px var(--sans);
  font-variant-numeric: tabular-nums;
  background: #fcfcfe;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 36px 10px 12px;
  transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
}
.rg-threshold-input:hover { background: #fff; border-color: rgba(56,101,200,0.30); }
.rg-threshold-input:focus {
  outline: none; background: #fff; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(56,101,200,0.15);
}
.rg-seuil-unit {
  position: absolute; right: 12px; bottom: 11px;
  font: 500 13px var(--sans); color: var(--text-muted);
  pointer-events: none;
}

/* Visualisation des bandes : barre horizontale 100% avec 3 zones. */
.rg-bands { margin-top: 8px; }
.rg-bands-bar {
  display: flex; width: 100%; height: 48px;
  border-radius: 8px; overflow: hidden;
  border: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}
.rg-bands-warn { outline: 2px dashed var(--nogo); outline-offset: 2px; }
.rg-band {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: #fff; font: 600 12px var(--sans);
  padding: 4px 8px; overflow: hidden; white-space: nowrap;
  transition: width 0.2s ease-out;
  min-width: 0;
}
.rg-band-label { font-size: 12px; letter-spacing: 0.02em; }
.rg-band-range { font-size: 11px; opacity: 0.92; margin-top: 1px; }
.rg-band-nogo     { background: var(--nogo); }
.rg-band-arbitrer { background: var(--arbitrer); }
.rg-band-go       { background: var(--go); }
.rg-bands-warn-msg {
  margin-top: 8px; font: 500 12px var(--sans); color: var(--nogo);
}

.reglages-actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.reglages-actions-right { display: flex; align-items: center; gap: 12px; }
.reglages-feedback {
  font: 500 13px var(--sans);
  padding: 4px 0;
  transition: opacity 0.2s;
}
.reglages-feedback-ok { color: var(--go); }
.reglages-error {
  margin-top: 12px;
  padding: 10px 14px;
  border-left: 3px solid var(--nogo);
  background: #fff5f5;
  color: var(--nogo);
  font: 500 13px var(--sans);
  border-radius: 0 6px 6px 0;
}

/* =========================================================================
 * Section « Calendrier externe » (J-A-bis, dette n° 1 verdict J-A) — le
 * markup portait déjà les classes `rg-ics-*` sans règles CSS consommées ;
 * conséquence : Copier tombait sous le champ, l'état n'était pas une
 * pastille, le lien `webcal://` s'étalait sur toute la largeur. Ces règles
 * consomment les classes existantes du DOM (aucun changement de markup).
 * ========================================================================= */
.rg-ics-state {
  display: inline-flex; align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font: 600 11.5px var(--sans);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.rg-ics-state-on  { background: rgba(46,139,87,0.14); color: #1f7a4d; }
.rg-ics-state-off { background: var(--bg-page-strong); color: var(--text-soft); }

.rg-ics-field {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 12px;
}
.rg-ics-field label {
  font: 500 12px var(--sans); color: var(--text-soft);
}

/* Champ URL + bouton Copier alignés horizontalement (F2.c : même ligne). */
.rg-ics-url-row {
  display: flex; align-items: center; gap: 8px;
}
.rg-ics-url {
  flex: 1; min-width: 0;
  font: 500 12.5px var(--mono, ui-monospace, SFMono-Regular, Consolas, monospace);
  background: #fcfcfe;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  color: var(--text);
}
.rg-ics-url:focus {
  outline: none; background: #fff; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(56,101,200,0.15);
}
.rg-ics-copy { flex: 0 0 auto; }

/* Lien webcal — un secret ne doit pas déborder, word-break pour tenir dans
 * la largeur de la section sans casser l'affordance. */
.rg-ics-webcal {
  font: 500 12.5px var(--mono, ui-monospace, SFMono-Regular, Consolas, monospace);
  color: var(--primary);
  word-break: break-all;
  overflow-wrap: anywhere;
}

.rg-ics-actions {
  display: flex; align-items: center; gap: 10px;
  margin-top: 14px; flex-wrap: wrap;
}

.rg-ics-help {
  margin-top: 18px;
  padding: 12px 14px;
  border-left: 3px solid var(--border);
  background: #fbfafd;
  border-radius: 0 6px 6px 0;
}
.rg-ics-help h3 {
  margin: 0 0 6px; font: 600 13px var(--sans); color: var(--text);
}
.rg-ics-help ul { margin: 0 0 6px; padding-left: 18px; }
.rg-ics-help li { font: 400 13px var(--sans); color: var(--text); line-height: 1.5; }
.rg-ics-help p { margin: 6px 0 0; font: 400 12.5px var(--sans); color: var(--text-muted); }

/* =========================================================================
 * Page « Agenda » — grille calendaire (J-B). Trois vues Mois/Semaine/Liste.
 * Aucun drag/drop, aucune poignée (C-JB-7). Le passé se rend grisé via
 * `.is-passe { opacity: 0.55 }` — propriété nommée pour l'assertion
 * `getComputedStyle` (C-JB-6). Convention gravée : « une classe qu'aucune
 * CSS ne consomme est une garde que rien ne traverse » — is-passe est
 * consommée ci-dessous, `.agenda-chip-*` aussi.
 * ========================================================================= */
.agenda-page-card { padding: 22px 24px; }
.agenda-grid-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 16px;
}
.agenda-grid-head h1 { margin: 0; font: 700 22px var(--sans); }
.agenda-grid-controls {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.agenda-grid-title {
  font: 600 14px var(--sans); color: var(--text-soft);
  padding: 0 6px; min-width: 120px;
}
.agenda-view-switcher {
  display: inline-flex; gap: 4px; margin-left: 12px;
  padding: 2px; background: var(--bg-page-strong); border-radius: 8px;
}
.agenda-view-btn.is-active {
  background: var(--primary); color: #fff; border-color: var(--primary);
}

.agenda-grid-zone { margin-top: 16px; }

/* ─── Vue Mois ────────────────────────────────────────────────────────── */
/* Correctif Laurent 31/08 (capture DURATONT août 2026) : les 7 colonnes
 * étaient inégales — jours vides écrasés à ~29 px, jours à chips étalés
 * à ~290 px. Cause : `repeat(7, 1fr)` = `repeat(7, minmax(auto, 1fr))`,
 * où `auto` = `min-content` par défaut ; le texte des chips (`white-space:
 * nowrap`) impose son min-content à la colonne, ce que la CSS honore avant
 * la fraction. Fix : `minmax(0, 1fr)` — chaque colonne peut se rétracter à
 * 0 avant que le `1fr` s'applique, ce qui rend les 7 colonnes strictement
 * égales et rend enfin le `text-overflow: ellipsis` des chips effectif.
 * Idem sur `.agenda-month-cell` : `min-width: 0` explicite pour absorber
 * l'ellipsis. Assertion F1.c le mesure (± 2 px). */
.agenda-month-head {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px; padding: 0 4px 4px;
}
.agenda-month-dowhead {
  font: 600 11px var(--sans); color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.03em;
  text-align: center; padding: 4px 0;
  min-width: 0;
}
.agenda-month-grid {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px; padding: 0 4px;
}
.agenda-month-cell {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fff;
  padding: 6px;
  min-height: 72px;
  min-width: 0;
  display: flex; flex-direction: column;
  cursor: default;
}
/* Passe 2 décision 1 — fond temporel : passée = blanc (défaut), courante+future =
   bleu ciel doux. is-out-month reste atténué mais suit la règle (blanc/bleu ciel
   plus mate). is-today conserve son liseré indépendamment du fond. */
.agenda-month-cell.is-jour-passe  { background: #fff; }
.agenda-month-cell.is-jour-futur  { background: var(--agenda-jour-futur); }
.agenda-month-cell.is-out-month.is-jour-passe  { background: #fafafb; color: var(--text-muted); }
.agenda-month-cell.is-out-month.is-jour-futur  { background: #f2f5fa; color: var(--text-muted); }
.agenda-month-cell.is-out-month .agenda-month-cell-daynum {
  color: var(--text-muted);
}
.agenda-month-cell.is-today {
  border-color: var(--primary);
  box-shadow: inset 0 0 0 1px var(--primary);
}
.agenda-month-cell-daynum {
  font: 500 12px var(--sans); color: var(--text);
  margin-bottom: 4px;
}
.agenda-month-chips {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
}
.agenda-chip {
  display: block;
  padding: 3px 6px 3px 5px;
  border-radius: 4px;
  border-left: 3px solid transparent;
  font: 500 11px var(--sans);
  background: var(--accent-soft, rgba(56,101,200,0.10));
  color: var(--primary);
  text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  cursor: pointer;
}
.agenda-chip:hover { text-decoration: underline; }
/* Lifting §1.4 — SOURCE : barre gauche 3 px + fond doux. Trois sources, trois
   couleurs distinctes fixes par attribut data-source. */
.agenda-chip[data-source="marche_deadline"] {
  background: var(--agenda-src-marche-soft);
  color: var(--agenda-src-marche);
  border-left-color: var(--agenda-src-marche);
}
.agenda-chip[data-source="marche_jalon"] {
  background: var(--agenda-src-jalon-soft);
  color: var(--agenda-src-jalon);
  border-left-color: var(--agenda-src-jalon);
}
.agenda-chip[data-source="coffre_piece"] {
  background: var(--agenda-src-coffre-soft);
  color: var(--agenda-src-coffre);
  border-left-color: var(--agenda-src-coffre);
}
.agenda-chip[data-source="company_event"] {
  background: var(--agenda-src-event-soft);
  color: var(--agenda-src-event);
  border-left-color: var(--agenda-src-event);
  /* J-C §3.3 — poignée de déplacement UNIQUEMENT sur company_event.
     Curseur `move` = affordance de drag ; ::before affiche l'icône
     grippée (≡). Les 3 sources dérivées gardent leur curseur par
     défaut (pointer) — mesuré discriminant au front-smoke via
     getComputedStyle + ::before. */
  cursor: move;
  padding-left: 16px; /* place pour la poignée ≡ */
}
.agenda-chip[data-source="company_event"]::before {
  content: "≡";
  position: absolute;
  left: 4px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 10px;
  color: var(--agenda-src-event);
  opacity: 0.7;
}
.agenda-chip[data-source="company_event"] { position: relative; }
.agenda-chip[data-source="company_event"].is-dragging {
  opacity: 0.5;
  outline: 1px dashed var(--agenda-src-event);
}
/* J-C — cellule cible pendant le drag : liseré discret pour indiquer
   la cible potentielle. Applique aussi aux colonnes Semaine. */
.agenda-month-cell.is-drop-target,
.agenda-week-col.is-drop-target {
  outline: 2px dashed var(--agenda-src-event);
  outline-offset: -2px;
}
/* Item Semaine/Liste : même curseur `move` + poignée ≡ sur company_event
   (via ::before sur le badge date). Absent des 3 dérivés. */
.agenda-item[data-source="company_event"] {
  cursor: move;
}
.agenda-item[data-source="company_event"] .agenda-item-date-badge::before {
  content: "≡";
  margin-right: 4px;
  opacity: 0.7;
}
/* URGENCE (mois) — point coloré `•` avant le libellé, remplace le fond
   d'urgence historique (qui recouvrait la couleur de source). */
.agenda-chip-dot { display: none; margin-right: 3px; font-size: 12px; line-height: 1; }
.agenda-chip[data-urgence="urgente"] .agenda-chip-dot { display: inline; color: var(--agenda-urg-urgente-dot); }
.agenda-chip[data-urgence="proche"]  .agenda-chip-dot { display: inline; color: var(--agenda-urg-proche-dot); }
/* PASSÉ écrase tout (opacity + gris, pas de point). */
.agenda-chip.is-passe {
  opacity: 0.55; background: var(--bg-page-strong); color: var(--text-soft);
  border-left-color: transparent;
}
.agenda-chip.is-passe .agenda-chip-dot { display: none; }

/* J-D §1.E-F — Poignée de resize sur bord DROIT, company_event ALL_DAY seul.
   Zone cliquable 6 px, curseur col-resize discriminant. Aucun visuel « ≡ »
   sur le bord droit — la poignée gauche (déplacement) et la droite (resize)
   sont distinguées par leur COTÉ et leur CURSEUR ; pas d'ambiguïté visuelle.
   ABSENTE des dérivés (aucun span posé côté DOM) et des horaires (idem). */
.agenda-chip { position: relative; }
.agenda-chip-resize {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: 6px;
  cursor: col-resize;
  z-index: 2;
}
.agenda-chip.is-resizing { opacity: 0.7; outline: 1px dashed var(--agenda-src-event, #c65f1c); }
.agenda-item { position: relative; }
.agenda-item-resize {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: 8px;
  cursor: col-resize;
  z-index: 2;
}
.agenda-item.is-resizing { opacity: 0.7; outline: 1px dashed var(--agenda-src-event, #c65f1c); }

/* J-D §1.B — heure locale (Intl) préfixée sur chips Mois pour events HORAIRES.
   Chiffres tabulaires pour un alignement propre quand plusieurs chips
   partagent une cellule. */
.agenda-chip-heure {
  font-weight: 600;
  margin-right: 4px;
  font-variant-numeric: tabular-nums;
  opacity: 0.9;
}
.agenda-item-heure {
  font-weight: 600;
  margin-right: 6px;
  font-variant-numeric: tabular-nums;
  opacity: 0.9;
}

.agenda-month-more {
  font: 500 11px var(--sans); color: var(--primary);
  background: transparent; border: 0; padding: 2px 0;
  cursor: pointer; text-align: left;
}
.agenda-month-more:hover { text-decoration: underline; }

/* ─── Vue Jour — J-D §1.C ─────────────────────────────────────────────── */
.agenda-day { display: flex; flex-direction: column; gap: 12px; }
.agenda-day-header {
  font: 600 15px var(--sans); color: var(--text);
  padding: 4px 6px; border-bottom: 1px solid var(--border);
}
.agenda-day.is-today .agenda-day-header {
  border-bottom-color: var(--agenda-today-line, var(--accent));
}
.agenda-day-allday-band {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 6px 8px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg-page);
  min-height: 32px;
}
.agenda-day-allday-label {
  font: 600 12px var(--sans); color: var(--text-soft);
  min-width: 100px; padding-top: 3px;
  text-transform: uppercase; letter-spacing: 0.5px;
}
.agenda-day-allday-list {
  display: flex; flex-wrap: wrap; gap: 6px;
  flex: 1 1 auto;
}
.agenda-day-allday-chip {
  padding: 3px 8px; border-radius: 999px;
  background: var(--card); border: 1px solid var(--border);
  font: 500 12px var(--sans);
  border-left-width: 3px;
  cursor: pointer;
}
.agenda-day-allday-chip[data-source="marche_deadline"] { border-left-color: var(--agenda-src-marche); background: var(--agenda-src-marche-soft); }
.agenda-day-allday-chip[data-source="marche_jalon"]    { border-left-color: var(--agenda-src-jalon);  background: var(--agenda-src-jalon-soft); }
.agenda-day-allday-chip[data-source="coffre_piece"]    { border-left-color: var(--agenda-src-coffre); background: var(--agenda-src-coffre-soft); }
.agenda-day-allday-chip[data-source="company_event"]   { border-left-color: var(--agenda-src-event);  background: var(--agenda-src-event-soft); }
.agenda-day-allday-chip.is-passe { opacity: 0.55; }
.agenda-day-timeline {
  position: relative;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg-page);
  overflow: hidden;
}
.agenda-day-slots, .agenda-day-items {
  position: absolute; top: 0; left: 0; right: 0; bottom: 0;
}
.agenda-day-slot {
  position: absolute; left: 0; right: 0;
  border-top: 1px solid var(--border);
  padding-left: 62px;
  box-sizing: border-box;
  cursor: pointer;
}
.agenda-day-slot:first-child { border-top: 0; }
.agenda-day-slot:hover { background: var(--bg-page-strong, rgba(0,0,0,0.02)); }
.agenda-day-slot-label {
  position: absolute; left: 8px; top: 4px;
  font: 500 11px var(--sans); color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.agenda-day-items { pointer-events: none; padding-left: 62px; }
.agenda-day-item {
  position: absolute; left: 62px; right: 8px;
  pointer-events: auto;
  padding: 4px 8px;
  border-radius: 4px;
  background: var(--agenda-src-event-soft, #fbe5d4);
  border-left: 3px solid var(--agenda-src-event, #c65f1c);
  font: 500 12px var(--sans);
  overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.agenda-day-item:hover { filter: brightness(0.98); }
.agenda-day-item-label { display: inline-block; }
.agenda-day-hint { margin: 4px 0 0; color: var(--text-soft); }

/* J-D §1.D — mention discrète du fuseau au-dessus de la légende. */
.agenda-timezone-mention {
  margin: 8px 0 0;
  font: 400 12px var(--sans);
  color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}

/* ─── Vue Semaine ─────────────────────────────────────────────────────── */
.agenda-week-grid {
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: 8px;
}
.agenda-week-col {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fff;
  padding: 8px;
  min-height: 200px;
}
/* Passe 2 décision 1 — même règle temporelle sur les colonnes Semaine. */
.agenda-week-col.is-jour-passe { background: #fff; }
.agenda-week-col.is-jour-futur { background: var(--agenda-jour-futur); }
.agenda-week-col.is-today {
  border-color: var(--primary);
  box-shadow: inset 0 0 0 1px var(--primary);
}
.agenda-week-colhead {
  font: 600 12px var(--sans); color: var(--text);
  margin-bottom: 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.agenda-week-list { list-style: none; padding: 0; margin: 0; }
.agenda-week-list .agenda-item { padding: 6px 0; border-bottom: 1px solid var(--border); }
.agenda-week-list .agenda-item:last-child { border-bottom: 0; }
.agenda-week-empty { list-style: none; }

/* ─── Éléments partagés : items passés (Semaine et Liste) ─────────────── */
.agenda-item.is-passe { opacity: 0.55; }
.agenda-item.is-passe .agenda-pill { display: none; }

/* Lifting §1.4 — SOURCE sur `.agenda-item` (Semaine/Liste + dashboard). Barre
   gauche 3 px de la couleur de source, alignée sur la grammaire des chips.
   Le PASSÉ escamote la barre (déjà atténué par opacity — pas la peine de
   colorer un item que l'utilisateur ne lit plus). */
.agenda-item {
  border-left: 3px solid transparent;
  padding-left: 8px;
}
.agenda-item[data-source="marche_deadline"] { border-left-color: var(--agenda-src-marche); }
.agenda-item[data-source="marche_jalon"]    { border-left-color: var(--agenda-src-jalon); }
.agenda-item[data-source="coffre_piece"]    { border-left-color: var(--agenda-src-coffre); }
.agenda-item[data-source="company_event"]   { border-left-color: var(--agenda-src-event); }
.agenda-item.is-passe { border-left-color: transparent; }

/* Lifting §1.4 — légende sous la grille (page agenda seule, jamais dashboard).
   Rangée horizontale (wrap si besoin), séparée de la grille par une fine
   ligne. 6 entrées : 3 sources (carré coloré) + 2 urgences (point rond) +
   1 passé (carré atténué). Les libellés viennent de agenda.legend.* × 7 locales. */
.agenda-legend {
  display: flex; flex-wrap: wrap; gap: 12px 16px;
  padding: 12px 8px 4px; margin-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 12px; color: var(--text-soft);
}
.agenda-legend-entry { display: inline-flex; align-items: center; gap: 6px; }
.agenda-legend-mark {
  display: inline-block; width: 10px; height: 10px; border-radius: 2px;
  background: transparent;
}
.agenda-legend-src-marche .agenda-legend-mark { background: var(--agenda-src-marche); }
.agenda-legend-src-jalon  .agenda-legend-mark { background: var(--agenda-src-jalon); }
.agenda-legend-src-coffre .agenda-legend-mark { background: var(--agenda-src-coffre); }
.agenda-legend-src-event  .agenda-legend-mark { background: var(--agenda-src-event); }
.agenda-legend-urg-urgente .agenda-legend-mark {
  background: var(--agenda-urg-urgente-dot); border-radius: 50%;
}
.agenda-legend-urg-proche .agenda-legend-mark {
  background: var(--agenda-urg-proche-dot); border-radius: 50%;
}
.agenda-legend-passee .agenda-legend-mark {
  background: var(--bg-page-strong); border: 1px solid var(--border);
}

.agenda-empty { padding: 24px 12px 4px; }

/* Lifting §1.3 — état vide 2 lignes : hint atténué en seconde ligne sous
   `.agenda-empty` (message principal). Le bloc `.agenda-empty-block` regroupe
   les deux <p> et s'affiche sous la grille (Mois/Semaine) ou seul (Liste). */
.agenda-empty-block { text-align: center; }
.agenda-empty-block .agenda-empty { padding-bottom: 2px; }
.agenda-empty-hint {
  padding: 0 12px 24px;
  font-size: 13px;
  opacity: 0.75;
}

/* Lifting passe 2 décision 2 — mini-calendrier dashboard : 2 lignes × 7 cases
   (semaine courante + suivante), fond blanc/bleu ciel (règle temporelle
   passe 2), aujourd'hui liseré, chips par source ellipsées. Ancre visuelle
   en tête du bloc agenda du dashboard — jamais masquée. */
.dashboard-agenda-minical {
  padding: 12px 0 16px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 12px;
}
.dashboard-agenda-minical-dowheads,
.dashboard-agenda-minical-grid {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}
.dashboard-agenda-minical-grid { grid-auto-rows: minmax(56px, auto); }
.dashboard-agenda-minical-dowhead {
  font: 600 10px var(--sans); color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.03em;
  text-align: center; padding: 3px 0;
  min-width: 0;
}
.dashboard-agenda-minical-cell {
  border: 1px solid var(--border);
  border-radius: 5px;
  background: #fff;
  padding: 4px;
  min-height: 56px;
  min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
  text-decoration: none;
  color: var(--text);
  overflow: hidden;
}
.dashboard-agenda-minical-cell:hover { background: var(--bg-page-strong); }
.dashboard-agenda-minical-cell.is-jour-passe  { background: #fff; }
.dashboard-agenda-minical-cell.is-jour-futur  { background: var(--agenda-jour-futur); }
.dashboard-agenda-minical-cell.is-today {
  border-color: var(--primary);
  box-shadow: inset 0 0 0 1px var(--primary);
}
.dashboard-agenda-minical-daynum {
  font: 500 11px var(--sans); color: var(--text);
}
.dashboard-agenda-minical-chips {
  display: flex; flex-direction: column; gap: 1px;
  min-width: 0;
}
.dashboard-agenda-minical-chip {
  display: block;
  padding: 1px 4px;
  border-radius: 3px;
  border-left: 2px solid transparent;
  font: 500 9px var(--sans);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: var(--bg-page-strong);
  color: var(--text-soft);
}
.dashboard-agenda-minical-chip[data-source="marche_deadline"] {
  background: var(--agenda-src-marche-soft);
  color: var(--agenda-src-marche);
  border-left-color: var(--agenda-src-marche);
}
.dashboard-agenda-minical-chip[data-source="marche_jalon"] {
  background: var(--agenda-src-jalon-soft);
  color: var(--agenda-src-jalon);
  border-left-color: var(--agenda-src-jalon);
}
.dashboard-agenda-minical-chip[data-source="coffre_piece"] {
  background: var(--agenda-src-coffre-soft);
  color: var(--agenda-src-coffre);
  border-left-color: var(--agenda-src-coffre);
}
.dashboard-agenda-minical-chip[data-source="company_event"] {
  background: var(--agenda-src-event-soft);
  color: var(--agenda-src-event);
  border-left-color: var(--agenda-src-event);
}
.dashboard-agenda-minical-overflow {
  font: 500 9px var(--sans); color: var(--text-muted);
  padding: 1px 4px;
}

/* Lifting §1.6 — bloc « Calendrier externe » migré de Réglages vers la page
   agenda, REPLIÉ par défaut via <details> natif. Le summary porte le titre
   + la pastille d'état ; le contenu est la section ICS complète (mêmes
   classes .rg-ics-* que reglages historique — la CSS existante s'y applique
   telle quelle). Décision Laurent : « les utilisateurs ne vont pas le
   trouver dans Réglages ». */
.agenda-ics-details-card { margin-top: 20px; padding: 0; }
.agenda-ics-details > summary {
  list-style: none;
  cursor: pointer;
  padding: 14px 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  font: 600 15px var(--sans);
  color: var(--text);
  user-select: none;
}
.agenda-ics-details > summary::-webkit-details-marker { display: none; }
.agenda-ics-details > summary::before {
  content: '▸';
  display: inline-block;
  margin-right: 8px;
  color: var(--text-soft);
  font-size: 12px;
  transition: transform 120ms ease;
}
.agenda-ics-details[open] > summary::before { transform: rotate(90deg); }
.agenda-ics-summary-title { flex: 1; }
.agenda-ics-summary .rg-ics-state {
  font: 500 11px var(--sans);
  padding: 2px 8px;
  border-radius: 4px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.agenda-ics-panel-root {
  padding: 8px 16px 16px;
  border-top: 1px solid var(--border);
}

/* Lifting §1.1 — séparateur visuel de groupes dans la barre de navigation
   agenda. Rendu discret, aria-hidden côté DOM, aligné aux boutons. */
.agenda-nav-sep {
  color: var(--text-soft);
  opacity: 0.45;
  padding: 0 2px;
  user-select: none;
}

@media (max-width: 900px) {
  .rg-levels { grid-template-columns: repeat(2, 1fr); }
  .rg-seuils { grid-template-columns: 1fr; }
  .reglages-actions { flex-direction: column; align-items: stretch; }
  .reglages-actions-right { justify-content: space-between; }
}
@media (max-width: 560px) {
  .rg-levels { grid-template-columns: 1fr; }
  .rg-band-range { display: none; }
}

/* =========================================================================
 * Brique « Carte des marchés » étape 2 — composant Leaflet réutilisable.
 *
 * Conteneur de carte sur le dashboard, marqueurs HTML/CSS (divIcon), popup
 * sobre alignée sur le reste de l'app. Le composant reste agnostique au
 * dashboard — ce CSS s'applique partout où MapMarches.render() est appelé.
 * ========================================================================= */
.map-marches-section { margin: 24px 0; }
.map-marches-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.map-marches-head h2 { margin: 0; }
.map-marches-summary { font: 500 13px var(--sans); color: var(--text-muted); }
.map-marches-container {
  height: 420px;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: #eef2f7;
}
.map-marches-empty {
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fbfbfd;
  color: var(--text-muted);
  font-size: 13.5px;
}

/* Marqueurs en divIcon : un petit cercle plein + halo blanc pour la
 * lisibilité sur n'importe quelle tuile. Couleur reprise du verdict. */
.map-marker-icon { display: block; }
.map-marker-pin {
  display: block;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.35);
}

/* Popup : libellés sobres, lien cobalt vers la fiche. Réutilise les
 * classes .pill.* du verdict pour les recos GO / NO_GO / A_ARBITRER. */
.map-popup { min-width: 220px; font-family: var(--sans); }
.map-popup-title { font-weight: 600; color: var(--text); margin-bottom: 4px; line-height: 1.3; }
.map-popup-acheteur { font-size: 13px; color: var(--text-muted); margin-bottom: 6px; }
.map-popup-meta { margin-bottom: 6px; }
.map-popup-rec { font: 600 12px var(--sans); padding: 2px 8px; border-radius: 999px; }
.map-popup-rec.muted { background: #f0f1f4; color: var(--text-muted); border: 1px solid var(--border); }
.map-popup-deadline { font-size: 12.5px; color: var(--text-muted); margin-bottom: 8px; }
.map-popup-link {
  display: inline-block; margin-top: 4px;
  font-weight: 600; font-size: 13px;
  color: var(--accent); text-decoration: none;
}
.map-popup-link:hover { color: var(--accent-strong); text-decoration: underline; }

/* Leaflet — surcharges sobres alignées sur la charte. On laisse le reste
 * tel quel (les contrôles ± sont déjà discrets dans le défaut Leaflet). */
.leaflet-container { font-family: var(--sans); }
.leaflet-popup-content-wrapper { border-radius: 8px; }
.leaflet-popup-content { margin: 12px 14px; }

@media (max-width: 720px) {
  .map-marches-container { height: 320px; }
}

/* =========================================================================
 * Brique « Documents du marché » — stockage pur (ZÉRO coût IA).
 * Section placée entre l'en-tête de la fiche et le rail-cockpit. Couleurs
 * sobres : la palette pleine reste pour les verdicts Go/No-Go. Le badge
 * de type combine un point coloré + texte neutre (convention partagée
 * `.tag-status + dot-*` revisitée localement pour rester dans le contexte
 * documentaire).
 * ========================================================================= */
.fiche-documents { margin-top: 14px; }
.fiche-documents .card-head { margin-bottom: 14px; }

.doc-uploader {
  display: flex; flex-direction: column;
  gap: 12px;
  margin-bottom: 18px;
}
.doc-type-row {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.doc-type-label {
  font-size: 13px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.doc-type-radios {
  display: inline-flex; gap: 8px; flex-wrap: wrap;
}
.doc-type-radio {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  font-size: 13px;
  cursor: pointer;
  background: var(--card);
  transition: border-color .12s ease, background .12s ease, color .12s ease;
  user-select: none;
}
.doc-type-radio input { position: absolute; opacity: 0; pointer-events: none; }
.doc-type-radio.is-checked {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-weight: 600;
}

.doc-drop-zone {
  position: relative;
  display: flex; align-items: center; gap: 14px;
  padding: 18px 18px;
  border: 2px dashed var(--border-strong);
  border-radius: 10px;
  background: var(--bg-page);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
  outline: none;
}
.doc-drop-zone:hover,
.doc-drop-zone:focus-visible { border-color: var(--accent); background: var(--accent-soft); }
.doc-drop-zone.is-dragover { border-color: var(--accent); background: var(--accent-soft); }
.doc-drop-icon { color: var(--accent); flex-shrink: 0; }
.doc-drop-text { display: flex; flex-direction: column; gap: 2px; }
.doc-drop-text strong { font-weight: 600; color: var(--text); font-size: 14px; }
.doc-drop-hint { font-size: 12px; }
.doc-file-input { display: none; }

/* =========================================================================
 * Brique « Dépôt intelligent » — modale de confirmation du dépôt.
 *
 * La sélection ou le drop de fichiers ouvre une modale (helper showModal
 * partagé) dont le body contient la liste de slots ci-dessous. La dropzone
 * elle-même reste persistante sur la page (pas masquée).
 *
 * Conserve l'override `[hidden]` sur `.doc-piece-kind-row` et
 * `.doc-detected-badge` : ces éléments existent à l'intérieur des slots
 * dans la modale et sont basculés via `el.hidden = true/false`. La règle
 * UA `[hidden] { display: none }` perd autrement sa guerre de
 * spécificité face aux classes flex parentes.
 * ========================================================================= */
.doc-piece-kind-row[hidden],
.doc-detected-badge[hidden],
.doc-upload-slot-remove[hidden] {
  display: none;
}
.doc-piece-kind-row {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.doc-piece-kind-select {
  padding: 6px 10px; border-radius: 6px;
  border: 1px solid var(--border-strong); background: var(--card);
  font-size: 13px; color: var(--text);
  min-width: 220px;
}

/* Liste des slots de dépôt — 1 ligne par fichier choisi.
 *
 * En mono-fichier, l'unique <li> rend l'aperçu d'un seul fichier (nom +
 * radios + select en bloc) ; en multi, les <li> s'empilent verticalement
 * séparés par 12px. Le bouton « Retirer » (✕) est toujours visible. Le
 * conteneur vit dans le body de la modale partagée. */
.doc-upload-slot-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 12px;
}
.doc-upload-slot {
  padding: 12px 14px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 8px;
  display: flex; flex-direction: column; gap: 10px;
}
.doc-upload-slot-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.doc-upload-slot-file {
  display: inline-flex; align-items: center; gap: 10px; min-width: 0;
}
.doc-upload-slot-icon { color: var(--accent); flex-shrink: 0; }
.doc-upload-slot-name {
  font-size: 14px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 480px;
}
.doc-upload-slot-fields {
  display: flex; flex-direction: column; gap: 8px;
}
.doc-upload-slot-remove {
  flex-shrink: 0;
}
.doc-detected-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px;
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.01em;
}
.doc-detected-badge svg { color: var(--accent-strong); }

.doc-upload-feedback {
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  border: 1px solid transparent;
}
.doc-feedback-success {
  background: rgba(46, 130, 73, 0.08);
  color: #2e8249;
  border-color: rgba(46, 130, 73, 0.25);
}
.doc-feedback-error {
  background: rgba(180, 50, 50, 0.07);
  color: #9b2c2c;
  border-color: rgba(180, 50, 50, 0.25);
}
.doc-feedback-progress {
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-color: var(--accent);
}

.doc-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.doc-row {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 12px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.doc-row-icon { color: var(--text-muted); display: inline-flex; }
.doc-row-body { min-width: 0; }
.doc-row-name {
  font-size: 14px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.doc-row-meta {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 4px; flex-wrap: wrap;
}
.doc-row-meta-sep { color: var(--text-muted); }
.doc-row-actions { display: inline-flex; gap: 6px; white-space: nowrap; }
.doc-row-actions .ghost { display: inline-flex; align-items: center; gap: 6px; }

.doc-type-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 8px;
  background: var(--bg-page-strong);
  border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  color: var(--text);
  letter-spacing: 0.01em;
}
.doc-type-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-muted);
}
/* Couleurs sobres par type (point coloré + texte neutre).
 * Cohérent avec la palette de tags sobre (cf. CLAUDE.md §11) :
 *   avis_ao → ambre  (information de marché entrant)
 *   dce     → cobalt (pièce technique)
 *   autre   → gris   (neutre)
 */
.doc-type-avis_ao .doc-type-dot { background: var(--amber); }
.doc-type-dce     .doc-type-dot { background: var(--accent); }
.doc-type-autre   .doc-type-dot { background: var(--text-muted); }

/* =========================================================================
 * Brique « DCE ZIP » — pièces extraites d'un ZIP DCE.
 *
 * Sous-liste indentée sous le parent ZIP : visuellement subordonnée, mais
 * chaque ligne reste interactive (download/delete propres). Le badge
 * « DCE / <kind> » reprend le point cobalt du badge DCE standard pour
 * suggérer la filiation.
 * ========================================================================= */
.doc-row-has-children { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.doc-list-children {
  list-style: none;
  margin: -1px 0 0 24px;
  padding: 0 0 0 14px;
  display: flex; flex-direction: column; gap: 6px;
  border-left: 2px solid var(--border-strong);
}
.doc-row-child {
  padding: 8px 12px;
  background: var(--bg-page);
  font-size: 13px;
}
.doc-row-children-count {
  display: inline-flex; align-items: center;
  padding: 0 6px; border-radius: 4px;
  background: var(--accent-soft); color: var(--accent-strong);
  font-weight: 600; font-size: 11.5px;
}
.doc-type-dce-piece .doc-type-dot { background: var(--accent); }

.doc-uploader-note {
  margin-top: 8px;
  padding: 8px 12px;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: 6px;
  color: var(--accent-strong);
}

/* Bloc « Fichiers non extraits » — rendu sous la sous-liste des pièces
 * d'un ZIP DCE parent quand `ignored_entries` est non vide. Sobre (gris
 * neutre, pas d'alerte rouge) car les entrées ignorées ne sont pas une
 * erreur — juste de l'info transparente pour l'utilisateur (« voici ce
 * qui n'a pas été pris en compte dans ton DCE »).
 */
.doc-ignored-block {
  margin: 4px 0 0 24px;
  padding: 8px 12px;
  background: var(--bg-page);
  border: 1px dashed var(--border);
  border-radius: 0 0 6px 6px;
  border-top-color: transparent;
}
.doc-ignored-heading {
  display: flex; align-items: baseline; gap: 6px;
  font-size: 12.5px; font-weight: 600; color: var(--text);
}
.doc-ignored-count { font-weight: 500; }
.doc-ignored-hint { margin-top: 2px; font-size: 12px; }
.doc-ignored-list {
  list-style: none; margin: 6px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.doc-ignored-row {
  display: grid;
  grid-template-columns: 16px 1fr auto;
  gap: 8px;
  align-items: baseline;
  font-size: 12.5px;
  padding: 2px 0;
}
.doc-ignored-icon { color: var(--text-muted); display: inline-flex; }
.doc-ignored-name {
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.doc-ignored-reason { white-space: nowrap; }

.doc-empty {
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  padding: 28px 18px;
  border: 1px dashed var(--border-strong);
  border-radius: 10px;
  background: var(--bg-page);
  color: var(--text-muted);
}
.doc-empty-icon { color: var(--accent); margin-bottom: 8px; display: inline-flex; }
.doc-empty-title { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.doc-empty-hint { font-size: 12.5px; }

@media (max-width: 720px) {
  .doc-row { grid-template-columns: 24px 1fr; }
  .doc-row-actions { grid-column: 2; justify-content: flex-start; }
  .doc-drop-zone { flex-direction: column; align-items: stretch; text-align: center; }
}

/* =========================================================================
 * Brique « Pré-remplissage depuis l'AO déposé » — modale de revue.
 * ZÉRO IA, déclenchée par le bouton sur un document de type avis_ao.
 * La discipline est imposée côté serveur (seuls les champs vides sont
 * proposés). La modale n'écrit rien — l'utilisateur confirme champ par
 * champ avec édition inline possible.
 * ========================================================================= */
.prefill-list {
  list-style: none;
  margin: 12px 0 6px;
  padding: 0;
  display: flex; flex-direction: column;
  gap: 10px;
}
.prefill-row {
  display: grid;
  grid-template-columns: minmax(180px, 30%) 1fr;
  gap: 12px; align-items: center;
}
.prefill-check {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 500; font-size: 13.5px;
  color: var(--text);
  cursor: pointer; user-select: none;
}
.prefill-field-label {
  font-size: 12px; font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.prefill-value-input { width: 100%; }
.prefill-foot { margin-top: 8px; }

/* Bouton « Pré-remplir » plus présent que les autres ghost de la ligne
 * (l'action est l'intention principale d'un avis_ao). */
.doc-row-prefill {
  background: var(--accent-soft);
  color: var(--accent-strong);
  border: 1px solid var(--accent);
}
.doc-row-prefill:hover {
  background: var(--accent);
  color: #fff;
}
.doc-row-prefill[disabled] { opacity: 0.6; cursor: progress; }

@media (max-width: 720px) {
  .prefill-row { grid-template-columns: 1fr; gap: 4px; }
}

/* =========================================================================
 * Brique « Extraire seul — pré-remplissage fiche marché » — geste
 * transverse en tête de la section Documents. Miroir visuel strict de
 * .creation-prefill-zone de la modale Nouveau marché ; portée à
 * .fiche-documents pour éviter tout leak transverse. ZÉRO modif de
 * .creation-prefill-*, .prefill-list, .doc-drop-zone, .doc-row-prefill.
 * ========================================================================= */
.fiche-documents .extraire-seul-zone {
  margin-bottom: 12px;
  padding: 10px 12px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.fiche-documents .extraire-seul-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--accent-soft);
  color: var(--accent-strong);
  border: 1px solid var(--accent);
}
.fiche-documents .extraire-seul-toggle:hover {
  background: var(--accent);
  color: #fff;
}
.fiche-documents .extraire-seul-toggle[aria-expanded="true"] {
  background: var(--accent);
  color: #fff;
}
.fiche-documents .extraire-seul-body {
  margin-top: 12px;
}
.fiche-documents .extraire-seul-lead {
  margin-bottom: 10px;
}
.fiche-documents .extraire-seul-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  align-items: start;
}
.fiche-documents .extraire-seul-drop {
  /* Réutilise .creation-drop-zone (bordure dashed, hover accent) */
  min-height: 80px;
}
.fiche-documents .extraire-seul-paste-run {
  margin-top: 6px;
  align-self: flex-start;
}
.fiche-documents .extraire-seul-feedback {
  margin-top: 10px;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 12.5px;
  border: 1px solid transparent;
}

@media (max-width: 720px) {
  .fiche-documents .extraire-seul-row { grid-template-columns: 1fr; }
}

/* =========================================================================
 * Brique « Création de marché par dépôt/collage » — zone de pré-remplissage
 * en haut de la modale Nouveau marché. Dépôt OU collage texte → appel
 * /api/company/extract-preview → champs du formulaire pré-remplis (éditables).
 * La création reste 100 % manuelle si l'utilisateur ne dépose rien.
 * ========================================================================= */
.creation-prefill-zone {
  margin-bottom: 16px;
  padding: 12px 14px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.creation-prefill-lead {
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.creation-prefill-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  align-items: start;
}
.creation-drop-zone {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 6px;
  min-height: 80px;
  padding: 12px;
  border: 2px dashed var(--border-strong);
  border-radius: 8px;
  background: var(--card);
  cursor: pointer;
  outline: none;
  transition: border-color .15s ease, background .15s ease;
  text-align: center;
}
.creation-drop-zone:hover,
.creation-drop-zone:focus-visible,
.creation-drop-zone.is-dragover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.creation-drop-input { display: none; }
.creation-drop-text strong { font-size: 13px; color: var(--text); display: block; }
.creation-drop-text .muted { font-size: 11.5px; }
.creation-drop-filename {
  margin-top: 6px;
  font-size: 12px; font-weight: 600;
  color: var(--accent-strong);
  word-break: break-all;
}
.creation-paste-zone { display: flex; flex-direction: column; }
.creation-paste-zone .modal-label { margin-bottom: 6px; }
.creation-paste-textarea {
  resize: vertical;
  min-height: 80px;
  font-size: 13px;
}
.creation-prefill-feedback {
  margin-top: 10px;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 12.5px;
  border: 1px solid transparent;
}
.creation-prefill-success {
  background: rgba(46, 130, 73, 0.08);
  color: #2e8249;
  border-color: rgba(46, 130, 73, 0.25);
}
.creation-prefill-error {
  background: rgba(180, 50, 50, 0.07);
  color: #9b2c2c;
  border-color: rgba(180, 50, 50, 0.25);
}
.creation-prefill-progress {
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-color: var(--accent);
}
.creation-prefill-info {
  background: var(--amber-soft);
  color: #7a5a14;
  border-color: var(--amber);
}

@media (max-width: 720px) {
  .creation-prefill-row { grid-template-columns: 1fr; }
}

/* ──────────────────────────────────────────────────────────────────────────
 * Brique « Dossier de réponse » phase 1 — section dédiée sur la fiche marché.
 * Visuel sobre, aligné sur fiche-documents / fiche-analyses. ZÉRO appel IA.
 * ──────────────────────────────────────────────────────────────────────── */
.fiche-dossier { margin-top: 14px; }
.fiche-dossier .card-head { margin-bottom: 14px; }

.dossier-empty {
  padding: 18px 8px 4px 8px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: flex-start;
}
.dossier-empty-text { margin: 0; }

.dossier-list {
  list-style: none;
  padding: 0;
  margin: 0 0 12px 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.dossier-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 10px;
  border-radius: 6px;
  background: var(--surface-2, #fafafa);
}
.dossier-row:hover { background: var(--surface-3, #f4f4f4); }
.dossier-row-main {
  display: flex;
  align-items: center;
  gap: 10px;
}

.dossier-statut {
  border: none;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  min-width: 84px;
  text-align: center;
}
.dossier-statut-a_obtenir {
  background: #fef3c7;
  color: #92400e;
}
.dossier-statut-a_obtenir:hover { background: #fde68a; }
.dossier-statut-deposee {
  background: #d1fae5;
  color: #065f46;
}
.dossier-statut-deposee:hover { background: #a7f3d0; }

.dossier-label {
  flex: 1;
  font-size: 14px;
}
.dossier-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted, #6b7280);
  text-decoration: none;
  padding: 4px;
  border-radius: 4px;
}
.dossier-link:hover {
  color: var(--text, #111);
  background: rgba(0, 0, 0, 0.04);
}
.dossier-delete {
  background: none;
  border: none;
  color: var(--muted, #6b7280);
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
}
.dossier-delete:hover {
  color: #b91c1c;
  background: rgba(185, 28, 28, 0.06);
}

.dossier-add {
  margin-top: 4px;
}
.dossier-add-form {
  display: flex;
  gap: 8px;
  align-items: center;
}
.dossier-add-input {
  flex: 1;
  min-width: 0;
}

/* v2b — pièces attachées et menu d'attachement */
.dossier-pieces {
  list-style: none;
  padding: 0;
  margin: 0 0 0 24px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.dossier-piece-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 13px;
  padding: 4px 0;
}
.dossier-piece-filename {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Brique « Pièces du dossier — auteur, date & modification » — ligne méta
 * muted small sous le rang (source + actions). Miroir strict de .doc-row-meta
 * (style.css:5329-5333). flex-basis: 100% force le retour à la ligne
 * (flex-wrap: wrap sur le parent). Aucune règle globale touchée. */
.dossier-piece-meta {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 2px; flex-wrap: wrap;
  flex-basis: 100%;
}
.dossier-piece-meta-sep { color: var(--text-muted); }
.dossier-piece-source {
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.06);
  color: var(--muted, #6b7280);
}
/* Brique « Pré-remplissage déterministe DC1+DC2 » — badge « généré » pour
 * les pièces produites par la plateforme (source='genere'). Teinte accent
 * (bleu doux), distincte de coffre/upload/dce. Cohérence WCAG : accent
 * navy sur fond accentSoft (miroir docx COLOR.accentSoft) — ratio > 4.5:1.
 */
.dossier-piece-source.tag-source-genere {
  background: rgba(56, 101, 200, 0.14);  /* --accent 3865C8 à 14 % */
  color: #1F2A4F;                          /* --navy */
}
/* Brique « Pré-remplissage déterministe DC1+DC2 » — mini-bloc en tête de
 * #dossier-section. Boutons ghost sober, séparés par un petit espace, un
 * discret sous-titre à gauche. Aucune règle globale touchée (spec 0-0-2-0).
 */
.fiche-dossier .formulaires-admin-block {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  padding: 8px 0 12px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  margin-bottom: 8px;
}
.fiche-dossier .formulaires-admin-title {
  flex: 0 0 auto;
}
.fiche-dossier .formulaires-admin-actions {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
}
/* Brique « Bibliothèque de formulaires officiels vierges » — bloc distinct
 * sous « Formulaires administratifs ». Liste verticale (6 entrées, dume
 * dernier en linkonly) pour rester lisible même sur mobile. Aucune règle
 * globale touchée (spec 0-0-2-0, patron miroir des règles admin ci-dessus).
 */
.fiche-dossier .formulaires-vierges-block {
  padding: 8px 0 12px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  margin-bottom: 8px;
}
.fiche-dossier .formulaires-vierges-title {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 8px;
}
.fiche-dossier .formulaires-vierges-description {
  color: var(--text-muted);
}
.fiche-dossier .formulaires-vierges-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.fiche-dossier .formulaires-vierges-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  padding: 4px 0;
}
.fiche-dossier .formulaires-vierges-label {
  flex: 1 1 auto;
  min-width: 0;
}
.fiche-dossier .formulaires-vierges-millesime {
  flex: 0 0 auto;
  font-size: 0.85em;
  color: var(--text-muted);
  padding: 1px 8px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.04);
}
.fiche-dossier .formulaires-vierges-download {
  flex: 0 0 auto;
}
.fiche-dossier .formulaires-vierges-link {
  flex: 0 0 auto;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
}
.fiche-dossier .formulaires-vierges-link:hover {
  color: var(--navy);
}
.fiche-dossier .formulaires-vierges-hint {
  flex: 0 0 auto;
  font-style: italic;
}
.dossier-piece-actions {
  display: flex;
  gap: 4px;
  align-items: center;
}
.dossier-attach {
  margin-left: 24px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-start;
}
.dossier-attach-menu {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.dossier-attach-panel {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.03);
  width: 100%;
  max-width: 520px;
}
.dossier-attach-panel-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted, #6b7280);
  margin-bottom: 2px;
}
.coffre-suggestion-btn,
.dce-pick-btn {
  text-align: left;
  display: flex;
  align-items: center;
  gap: 8px;
}
.tag-validity { font-size: 11px; padding: 1px 6px; border-radius: 999px; }
.tag-validity.validity-valide  { background: #d1fae5; color: #065f46; }
.tag-validity.validity-bientot { background: #fef3c7; color: #92400e; }
.tag-validity.validity-perime  { background: #fecaca; color: #991b1b; }
.tag-validity.validity-indefini { background: rgba(0,0,0,0.06); color: var(--muted, #6b7280); }
.hide { display: none !important; }

/* =========================================================================
 * Coffre de pièces entreprise — v2a
 * Réutilise la palette de tags existante (.tag.tag-status.dot-*).
 * ========================================================================= */
.coffre-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 16px;
}
.coffre-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.coffre-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.coffre-row-main { flex: 1; min-width: 0; }
.coffre-row-title { font-weight: 600; margin-bottom: 4px; }
.coffre-row-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 0.92em;
}
.coffre-row-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.coffre-expiring-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.coffre-expiring-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
}
.coffre-expiring-row:first-child { border-top: none; }
.coffre-expiring-main { flex: 1; min-width: 0; }
.coffre-expiring-label { font-weight: 600; }
.coffre-expiring-sub { font-size: 0.9em; margin-top: 2px; }
.coffre-expiring-side {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
/* Modale Modifier — bloc « Pièce actuelle » (nom + bouton Télécharger). */
.coffre-edit-current {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* =========================================================================
 * Brique « Jalons & rappels » V1 — CSS.
 *
 * Section Jalons sur la fiche marché (.fiche-jalons) + agenda unifié sur le
 * dashboard (.agenda-panel). Pastilles d'urgence partagées entre les deux
 * surfaces via 3 classes .{jalon,agenda}-pill-{depassee,urgente,proche}.
 * ========================================================================= */

/* --- Section Jalons sur la fiche marché --- */
.fiche-jalons .jalons-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 12px;
}
.fiche-jalons .jalons-list {
  display: flex;
  flex-direction: column;
}
.fiche-jalons .jalons-empty {
  padding: 12px 0;
  color: var(--text-muted);
  font-style: italic;
}
.jalon-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 0;
  border-top: 1px solid var(--border);
}
.jalon-row:first-child { border-top: 0; }
.jalon-main { flex: 1; min-width: 0; }
.jalon-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.jalon-type { font: 600 14px var(--sans); color: var(--text); }
/* Pastille lecture seule — champ Type en édition d'une date clé (spec 0-0-1-0,
 * portée locale au form modal jalons). Miroir de patron gravé « .jalon-actions
 * .danger » de la micro-passe UI pré-γ. Ne touche PAS .pill global ni
 * .jalon-pill d'urgence. Contraste WCAG : #23272f sur #e9ecf1 = 12.64:1 (AAA). */
.jalon-form-type-readonly {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--creme-fonce);
  color: var(--text);
  font: 500 13px var(--sans);
  line-height: 1.4;
}
.jalon-date { font: 500 13px var(--sans); color: var(--text-muted); margin-top: 2px; }
.jalon-note { margin-top: 4px; white-space: pre-wrap; }
.jalon-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}
/* Neutralisation scopée du background hérité de button.danger — miroir du fix entités :7643-7673 (ratio WCAG >= 4.5:1 sur fond .card blanc). */
.jalon-actions .danger {
  background: transparent;
  color: var(--reject, #b91c1c);
  box-shadow: none;
}

/* --- Pastilles d'urgence (partagées jalon + agenda) --- */
.jalon-pill,
.agenda-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font: 600 11px var(--sans);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1.4;
}
.jalon-pill-depassee,
.agenda-pill-depassee {
  background: #fee2e2;
  color: #b91c1c;
}
.jalon-pill-urgente,
.agenda-pill-urgente {
  background: #fef3c7;
  color: #b45309;
}
.jalon-pill-proche,
.agenda-pill-proche {
  background: #e0e7ff;
  color: #3730a3;
}

/* --- Agenda panel sur le dashboard --- */
/* Ajustement 3 : hauteur maximale de sécurité même agenda déplié.
 * `max-height` calé sur ~70 % de la fenêtre laisse le donut visible en haut
 * quand l'agenda déborde. Scrollbar discrète alignée sur le style existant
 * (souris pointue seulement, cohérent avec la charte navy/border). Le
 * .panel-head reste HORS du conteneur scrollable (titre toujours visible). */
.agenda-panel .agenda-body {
  max-height: 70vh;
  overflow-y: auto;
  /* Point 3 (Jalons V1) : padding-top laissant respirer le premier
   * .agenda-group-title. Sans lui, le titre du premier groupe (« CETTE
   * SEMAINE ») se colle au haut du body scrollable et paraît rogné entre
   * le `.card-head` margin-bottom et le début du contenu. Symétrisé sur
   * les 4 côtés du body. */
  padding: 4px 4px 0 0;
}
/* Layout dashboard (Jalons & rappels V1) : l'agenda vit en pleine largeur
 * sous la rangée Pipeline+Activité, TOUJOURS en colonne unique. La tentative
 * de répartition sur 2 colonnes en desktop a été retirée : des groupes de
 * tailles très inégales se répartissent mal (un groupe à 1 item laisse un
 * vide massif d'un côté pendant que l'autre déborde) — la lisibilité
 * verticale prime. */
.agenda-panel .agenda-body::-webkit-scrollbar { width: 6px; }
.agenda-panel .agenda-body::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 3px;
}
.agenda-panel .agenda-body::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
.agenda-panel .agenda-group {
  margin-top: 12px;
}
.agenda-panel .agenda-group:first-of-type { margin-top: 0; }
/* Ajustement 2 : bouton local « Afficher les {n} autres » (client pur, aucun
 * fetch supplémentaire — les items cachés sont déjà dans le DOM avec [hidden]). */
.agenda-panel .agenda-show-more {
  margin-top: 6px;
  background: transparent;
  border: 0;
  padding: 4px 0;
  color: var(--navy, #3865c8);
  cursor: pointer;
  font: 500 12.5px var(--sans);
  text-decoration: underline;
}
.agenda-panel .agenda-show-more:hover { text-decoration: none; }
.agenda-panel .agenda-show-more[hidden] { display: none; }
/* Point 2 typographie (Jalons & rappels V1) — MÉTHODE par styles calculés :
 * les en-têtes de groupe jouent le même rôle que les <th> de `.tenders-table`
 * (têtes de liste UPPERCASE muted au-dessus de rangées). On applique donc les
 * MÊMES tokens que `.tenders-table thead th` (style.css:1504-1512) — pas la
 * classe `.eyebrow` (qui a font-weight:500 et letter-spacing:0.08em, divergent
 * des <th> à font-weight:600 et 0.04em, cf. mesures getComputedStyle).
 * `line-height` explicite : le sélecteur global `h1,h2,h3,h4` (style.css:71-75)
 * hérite 1.18 sur ce <h4>, alors que <th> hérite 1.55 du body — on force 1.55
 * pour égaliser. */
.agenda-group-title {
  font-weight: 600;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 6px 0;
}
/* État vide sous l'en-tête du groupe : styles italiques discrets alignés sur
 * les rangées de tableau (font-size 14px comme .tender-objet, couleur muted,
 * italique pour discriminer d'une donnée réelle). */
.agenda-group-empty {
  font-size: 14px;
  color: var(--text-muted);
  font-style: italic;
  padding: 6px 0 4px 0;
}
.agenda-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.agenda-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-top: 1px dashed var(--border);
}
.agenda-item:first-child { border-top: 0; }
/* Lifting §1.5 — refonte : `.agenda-item-body` remplace `.agenda-item-main`,
   la date sort du corps pour devenir un badge autonome (`.agenda-item-date-badge`)
   au premier plan de l'item. Motivation : le langage de la grille arrive dans
   le dashboard + Semaine/Liste (barre gauche source posée à (b), badge date
   coloré par source posé ici). Un SEUL rendu — les deux surfaces changent
   ensemble via `agendaItemHtml`. */
.agenda-item-body { flex: 1; min-width: 0; }
/* Point 2 typographie (Jalons & rappels V1) — MÉTHODE par styles calculés :
 * le libellé d'item d'agenda mirroite EXACTEMENT `.tender-objet` du tableau
 * « Vos appels d'offres » (style.css:1533-1542) — font-size:14px, weight:500,
 * couleur texte principale. Le font-size 14px doit être POSÉ explicitement :
 * sans lui, `.agenda-libelle` hérite du 16px du body, alors que `.tender-objet`
 * hérite du 14px de la cellule table. */
.agenda-libelle {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Lifting §1.5 — badge date au premier plan de l'item. Format court « J mois »
   (l'année vit dans le titre agenda et les groupes de la vue Liste). Fond
   coloré par source, largeur minimale pour rester alignée en colonne. */
.agenda-item-date-badge {
  display: inline-block;
  padding: 3px 8px;
  font: 600 12px var(--sans);
  color: var(--text-soft);
  background: var(--bg-page-strong);
  border-radius: 4px;
  white-space: nowrap;
  min-width: 62px;
  text-align: center;
  flex-shrink: 0;
}
.agenda-item[data-source="marche_deadline"] .agenda-item-date-badge {
  color: var(--agenda-src-marche);
  background: var(--agenda-src-marche-soft);
}
.agenda-item[data-source="marche_jalon"] .agenda-item-date-badge {
  color: var(--agenda-src-jalon);
  background: var(--agenda-src-jalon-soft);
}
.agenda-item[data-source="coffre_piece"] .agenda-item-date-badge {
  color: var(--agenda-src-coffre);
  background: var(--agenda-src-coffre-soft);
}
.agenda-item[data-source="company_event"] .agenda-item-date-badge {
  color: var(--agenda-src-event);
  background: var(--agenda-src-event-soft);
}
.agenda-item.is-passe .agenda-item-date-badge {
  background: var(--bg-page-strong);
  color: var(--text-muted);
}
.agenda-item-side {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

/* --- Modale de confirmation locale (miroir identity-media) --- */
.jalons-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.jalons-modal {
  background: #fff;
  border-radius: 8px;
  padding: 24px;
  max-width: 420px;
  width: 92%;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2);
}
.jalons-modal h2 { margin: 0 0 8px 0; font: 700 18px var(--sans); }
.jalons-confirm-body { margin: 0 0 16px 0; color: var(--text-muted); }
.jalons-modal .modal-actions {
  display: flex; justify-content: flex-end; gap: 10px; margin-top: 12px;
}
.jalons-modal .modal-actions .danger {
  background: #b91c1c;
  color: #fff;
  border: none;
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
}
.jalons-modal .modal-actions .link {
  background: transparent; border: none; cursor: pointer; color: var(--text-muted);
}

/* =========================================================================
 * v2c — Modal d'export ZIP du dossier de réponse
 * ========================================================================= */
/* La card-head du Dossier de réponse passe en flex : titres à gauche,
   bouton « Télécharger (ZIP) » à droite. Le wrap .card-head-titles permet
   au sous-titre de rester sous le h2 quand la place manque. */
.fiche-dossier .card-head {
  align-items: center;
  flex-wrap: wrap;
}
.card-head-titles { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }

.dossier-export-items {
  list-style: none;
  padding: 0;
  margin: 12px 0 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 50vh;
  overflow-y: auto;
}
.dossier-export-line {
  padding: 10px 12px;
  border-radius: 6px;
  background: var(--surface-2, #fafafa);
}
.dossier-export-line-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.dossier-export-line-label { flex: 1; font-weight: 500; }
.badge {
  font-size: 11px;
  padding: 1px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.badge-obligatoire { background: #fee2e2; color: #991b1b; }
.badge-optionnel { background: rgba(0,0,0,0.06); color: var(--muted, #6b7280); }

/* Rédaction SP2-2b — badges generation_mode (un seul badge par section,
   reflète l'état COURANT : ia | deterministic_repeat | stub | edited). */
.badge-ia    { background: #e0e7ff; color: #3730a3; font-weight: 600; }
.badge-rep   { background: rgba(0,0,0,0.06); color: #4a5060; font-weight: 600; }
.badge-stub  { background: #fde9c8; color: #92400e; font-weight: 600; }
.badge-edit  { background: #d7edde; color: #166534; font-weight: 600; }
.dossier-export-pieces {
  list-style: none;
  padding: 0;
  margin: 0 0 0 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Rangée standard d'une pièce dans le panneau d'export :
   case à cocher (gauche, taille naturelle) + nom de fichier (flex 1) +
   badge source (à droite, taille naturelle). justify-content explicite à
   flex-start pour garantir l'ancrage gauche de la case quel que soit le
   contexte parent. */
.dossier-export-piece label,
.dossier-export-piece-row {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  cursor: pointer;
  padding: 2px 0;
}
.dossier-export-piece-row > input[type="checkbox"] {
  flex: 0 0 auto;
  margin: 0;
}
.dossier-export-piece-filename {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dossier-export-piece-row > .dossier-piece-source { flex: 0 0 auto; }
.dossier-export-summary {
  border-top: 1px solid var(--border, rgba(0,0,0,0.1));
  padding-top: 10px;
  margin-top: 4px;
}
.dossier-export-count { font-weight: 500; margin-bottom: 6px; }
.dossier-export-warnings { display: flex; flex-direction: column; gap: 4px; }
.dossier-export-warning {
  font-size: 13px;
  padding: 6px 10px;
  border-radius: 6px;
}
.dossier-export-warning.warning-obligatoire { background: #fef3c7; color: #92400e; }
.dossier-export-warning.warning-manuel { background: rgba(0,0,0,0.05); color: var(--muted, #6b7280); }

/* =========================================================================
 * Passe UX démo fiche marché — feature/marche-ux-demo
 * Tokens utilisés UNIQUEMENT : --card, --navy, --accent, --accent-soft,
 * --muted, --border, --bg-page-strong, --go, .tag-status .dot-* existant.
 * Zéro nouvelle couleur ad hoc.
 * ========================================================================= */

/* --- Bande de chips d'état (résumé du marché) ---------------------------- */
.marche-status-band {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  padding: 12px 16px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 16px;
}
.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--bg-page-strong);
  font-size: 13px;
  line-height: 1;
  color: var(--navy);
}
/* Pastille dédiée à la bande de résumé : pose la couleur directement sur le
   span (pas via ::before), pour ne pas dépendre du contexte flex de `.tag`.
   Réutilise les MÊMES variables CSS et le MÊME nommage `.dot-*` que la
   palette existante (cf. .tag-status.dot-* ligne 4569+). Zéro nouvelle
   couleur, zéro nouveau token. Default gris = état neutre (à faire). */
.status-chip-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-muted);
  flex-shrink: 0;
}
.status-chip-dot.dot-success { background: var(--go); }
.status-chip-dot.dot-info    { background: var(--accent); }
.status-chip-dot.dot-warning { background: var(--arbitrer); }
.status-chip-dot.dot-danger  { background: var(--nogo); }

.status-chip-label { font-weight: 600; }
.status-chip-sep { color: var(--muted); margin: 0 1px; }
.status-chip-value { color: var(--muted); }

/* --- Section repliable réutilisable -------------------------------------- */
/* Default : DÉPLIÉ. Toggle .is-collapsed sur la <section> → cache .collapsible-body.
   Le chevron pivote (▾ déplié → ▸ replié). Les front-smokes ciblent des
   éléments DANS le body : par défaut, tout est visible → smokes verts. */
.collapsible .card-head-collapsible {
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.collapsible .card-head-collapsible:hover {
  background: rgba(0, 0, 0, 0.02);
  border-radius: 8px;
}
.collapsible .card-head-collapsible:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 8px;
}
.collapsible .card-head-titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.collapsible .collapsible-chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  transition: transform 0.18s ease;
  flex-shrink: 0;
}
.collapsible.is-collapsed .collapsible-chevron {
  transform: rotate(-90deg);
}
.collapsible .collapsible-body {
  /* Animation discrète : on coupe via display:none plutôt qu'une hauteur
     animée (trop fragile sur des contenus variables). Le toggle est
     instantané — sobre, pas de saccade. */
}
.collapsible.is-collapsed .collapsible-body {
  display: none;
}
/* Quand replié, le padding-bottom de la card devient inutile (le head
   touche le bord). On compacte. */
.collapsible.is-collapsed.card {
  padding-bottom: 14px;
}

/* =========================================================================
 * Lot 7 J1 R-REPLI + L2b-3 preservation — Documents a une sémantique
 * .is-collapsed SCOPÉE : le body reste rendu (display:block) mais la
 * LISTE + le reveal-wrap sont masqués. La DROP-ZONE et le toggle
 * Extraire seul restent VISIBLES (L2b-3 cardinale 2a-bis : le chemin
 * de dépôt survit à la compaction, y compris au collapse).
 * Un choix utilisateur EXPLICITE de collapse via clic sur le head
 * suit ce comportement — le geste principal (dépôt) reste toujours
 * atteignable.
 * ========================================================================= */
.fiche-documents.collapsible.is-collapsed > .collapsible-body {
  display: block;
}
/* R-REPLI : la LISTE est masquée par défaut (compact class + is-collapsed).
   Le REVEAL-WRAP (bouton lot 2a-bis « Voir les N fichiers déposés »)
   reste VISIBLE — offre au user une vue partielle sans devoir déplier
   toute la section. Cohérent avec le patron 2a-bis « la liste ne devient
   jamais inatteignable par tout chemin client ». */
.fiche-documents.collapsible.is-collapsed .doc-list-wrap {
  display: none;
}
/* Exception : quand le user CLIQUE le reveal-wrap (patron 2a-bis
   L2b-3), la classe .fiche-documents-dce-revealed est posée et la
   liste devient visible même si .is-collapsed. Spécificité supérieure
   (3 classes vs 2). */
.fiche-documents.collapsible.is-collapsed.fiche-documents-dce-revealed .doc-list-wrap {
  display: block;
}
.fiche-documents.collapsible.is-collapsed .extraire-seul-body {
  display: none;
}
/* Le padding-bottom compacté du .card ne s'applique plus si le body est
   effectivement rendu (drop-zone visible sur ligne). */
.fiche-documents.collapsible.is-collapsed.card {
  padding-bottom: initial;
}

/* =========================================================================
 * Polish démo — passe feature/polish-demo
 * Topbar account trigger riche : avatar + greeting + raison sociale.
 * Tokens existants uniquement (--navy, --accent, --text, --muted, --card,
 * --border, --border-strong, --bg-page). Aucune nouvelle couleur ad hoc.
 * ========================================================================= */

/* Variante riche du bouton compte. On garde .account-trigger comme base
   (pill + hover) et on ajoute la version multi-ligne via .account-trigger-rich. */
.account-trigger-rich {
  padding: 4px 10px 4px 4px;
  gap: 10px;
  align-items: center;
}
.account-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  color: #fff;
  font: 600 12.5px/1 var(--sans);
  letter-spacing: 0.02em;
  flex-shrink: 0;
  /* background posé inline (couleur déterministe par user). */
}
.account-trigger-stack {
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
  text-align: left;
  line-height: 1.15;
  min-width: 0;
  max-width: 200px;
}
.account-name {
  color: var(--navy);
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.account-name .user-role {
  font-weight: 500;
  color: var(--text-muted);
  font-size: 11.5px;
  margin-left: 2px;
}
.account-company {
  color: var(--text-muted);
  font-size: 11.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Responsive : sur étroit, on cache la stack (avatar + chevron seuls). */
@media (max-width: 720px) {
  .account-trigger-rich .account-trigger-stack { display: none; }
  .account-trigger-rich { padding: 4px; }
}

/* ============================================================================
 * Brique « Analyse d'écarts / matrice de conformité » v1.
 * Pattern visuel cohérent avec les autres sections fiche marché (fiche-dossier,
 * fiche-documents). Palette réutilisée des variables existantes (--go,
 * --arbitrer, --nogo, --text-muted) — ZÉRO nouvelle couleur.
 * ============================================================================ */

.fiche-ecarts .ecarts-summary {
  display: flex; flex-wrap: wrap; gap: 12px;
  padding: 12px 16px;
  margin-bottom: 12px;
  background: #f6f7f9;
  border-radius: 8px;
}
.ec-summary-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  background: #fff;
  border-radius: 999px;
  font-size: 13px;
  border: 1px solid #e2e4e8;
}
.ec-summary-chip strong { color: var(--text); }
.ec-summary-chip span { color: var(--text-muted); }

/* Dots colorés (réutilisent --go/--arbitrer/--nogo/--text-muted). */
.ec-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; }
.ec-dot-couvert     { background: var(--go); }
.ec-dot-partiel     { background: var(--arbitrer); }
.ec-dot-non-couvert { background: var(--nogo); }
.ec-dot-a-produire  { background: var(--text-muted); }

.ecarts-table-wrap { overflow-x: auto; }
.ecarts-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.ecarts-table th, .ecarts-table td {
  text-align: left; padding: 10px 12px;
  border-bottom: 1px solid #e2e4e8;
  vertical-align: top;
}
.ecarts-table th {
  font-weight: 600; font-size: 12px; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.04em;
  background: #fafbfc;
}
.ecarts-table tbody tr:hover { background: #fafbfc; }

.ec-col-exigence  { width: 32%; }
.ec-col-categorie { width: 14%; }
.ec-col-statut    { width: 14%; }
.ec-col-justif    { width: 20%; }
.ec-col-note      { width: 16%; cursor: pointer; }
.ec-col-actions   { width: 4%; white-space: nowrap; }

.ec-exigence-main { font-weight: 500; }
.ec-exigence-meta { margin-top: 4px; display: flex; gap: 6px; flex-wrap: wrap; }
.ec-ref-badge, .ec-oblig-badge, .ec-override-badge {
  display: inline-block; padding: 1px 6px;
  font-size: 11px; border-radius: 3px;
  background: #eef0f3; color: var(--text-muted);
}
.ec-oblig-badge { background: #fef3e8; color: #92400e; }
.ec-override-badge { background: #eef2ff; color: #4338ca; }
/* v1.x — drapeau conditionnel post-attribution (« si retenu »). Couleur
   neutre, ne se confond pas avec l'ambre obligatoire ni l'indigo override. */
.ec-conditionnel-badge {
  display: inline-block; padding: 1px 6px;
  font-size: 11px; border-radius: 3px;
  background: #ecfeff; color: #155e75;
  border: 1px solid #cffafe;
}
/* v1.x — chip secondaire (a_fournir_si_retenu, clauses_contractuelles).
   Pas de pastille colorée — l'information est neutre. */
.ec-summary-chip-info {
  background: #fafbfc;
  border-style: dashed;
}

.ec-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 13px; font-weight: 500;
  background: #fff; border: 1px solid #e2e4e8;
}
.ec-chip-couvert     { background: rgba(47, 107, 58, 0.08); color: var(--go); border-color: rgba(47, 107, 58, 0.2); }
.ec-chip-partiel     { background: rgba(217, 119, 6, 0.08); color: var(--arbitrer); border-color: rgba(217, 119, 6, 0.2); }
.ec-chip-non_couvert { background: rgba(155, 44, 44, 0.08); color: var(--nogo); border-color: rgba(155, 44, 44, 0.2); }
.ec-chip-a_produire  { background: #f3f4f6; color: var(--text-muted); border-color: #e2e4e8; }
/* v1.x option C correctif — chip « Contexte » sur les lignes narrative
   non comptées (visible dans la matrice mais hors compteur non_couvert).
   Couleur neutre cyan pâle, distincte du nogo (rouge non_couvert) et
   de l'a_produire (gris). */
.ec-chip-info        { background: #ecfeff; color: #155e75; border-color: #cffafe; }

.ec-justif {
  display: inline-flex; flex-direction: column; gap: 2px;
  font-size: 13px;
}
.ec-justif-source { color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
.ec-justif-link { color: var(--accent); text-decoration: none; }
.ec-justif-link:hover { text-decoration: underline; }

.ec-non-couvert-cta { display: flex; flex-direction: column; gap: 2px; }
.ec-cta-link { color: var(--accent); font-size: 13px; text-decoration: none; }
.ec-cta-link:hover { text-decoration: underline; }

.ec-note-text { font-size: 13px; color: var(--text); }
.ec-cell-note:hover { background: #fafbfc; }

.ec-cell-actions { white-space: nowrap; text-align: right; }
.ec-row-action { padding: 4px 6px; }

.ecarts-empty {
  padding: 24px; text-align: center;
}
.ecarts-empty-text { margin-bottom: 12px; }

/* v1.x — section repliable « Clauses contractuelles ». Mini-table sous le
   tableau principal, marges et fond légèrement séparés pour appuyer le
   statut « informatif ». */
.ec-clause-section {
  margin-top: 20px;
  border-top: 1px solid #e2e4e8;
  padding-top: 8px;
}
.ec-clause-title {
  font-size: 14px; font-weight: 600; margin: 0;
  display: flex; align-items: center; gap: 8px;
}
.ec-clause-count { color: var(--text-muted); font-weight: 400; font-size: 13px; }
.ec-clause-table-wrap { overflow-x: auto; padding-top: 8px; }
.ec-clause-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.ec-clause-table th, .ec-clause-table td {
  text-align: left; padding: 8px 12px;
  border-bottom: 1px solid #eef0f3;
  vertical-align: top;
}
.ec-clause-table th {
  font-weight: 600; font-size: 12px; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.ec-clause-col-exigence { width: 78%; }
.ec-clause-col-ref { width: 22%; }
.ec-clause-info-badge {
  display: inline-block; margin-left: 8px;
  padding: 1px 6px;
  font-size: 11px; border-radius: 3px;
  background: #f3f4f6; color: var(--text-muted);
}

@media (max-width: 720px) {
  .ecarts-table { font-size: 13px; }
  .ec-col-categorie { display: none; }
  .ec-col-justif { width: 26%; }
  .ec-col-note { width: 20%; }
  .ec-clause-table { font-size: 13px; }
}

/* ─── Sous-brique « Zone profil enrichie » — Mémoire technique ─────────── */
.memoire-blocs-root { display: flex; flex-direction: column; gap: 18px; }
.memoire-blocs-root .theme-card {
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  padding: 14px 16px;
  background: #fff;
}
.memoire-blocs-root .theme-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 4px;
}
.memoire-blocs-root .theme-head h3 {
  margin: 0; font-size: 16px;
}
.memoire-blocs-root .badge-count {
  font-size: 12px; color: var(--text-muted, #7f8c8d);
  background: #f3f4f6; padding: 2px 8px; border-radius: 999px;
}
.memoire-blocs-root .theme-help {
  margin: 0 0 12px; color: var(--text-muted, #7f8c8d); font-size: 13px;
}
.memoire-blocs-root .bloc-list {
  list-style: none; padding: 0; margin: 0 0 10px;
  display: flex; flex-direction: column; gap: 8px;
}
.memoire-blocs-root .bloc-item {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 12px; align-items: start;
  padding: 10px; border: 1px solid var(--border, #e5e7eb); border-radius: 4px;
  background: #fbfcfc;
}
.memoire-blocs-root .bloc-item:not(:has(.bloc-thumb)) {
  grid-template-columns: 1fr auto;
}
.memoire-blocs-root .bloc-thumb {
  width: 64px; height: 64px; overflow: hidden; border-radius: 3px;
  background: #f3f4f6;
}
.memoire-blocs-root .bloc-thumb img {
  width: 100%; height: 100%; object-fit: cover;
}
.memoire-blocs-root .bloc-label {
  font-weight: 600; font-size: 14px; margin-bottom: 2px;
}
.memoire-blocs-root .bloc-texte {
  font-size: 13px; color: var(--text, #2c3e50); line-height: 1.45;
  white-space: pre-wrap;
}
.memoire-blocs-root .bloc-actions {
  display: flex; gap: 4px; flex-wrap: wrap; align-items: center;
}
.memoire-blocs-root .bloc-actions button {
  background: none; border: 1px solid transparent;
  color: var(--accent, #2980b9); font-size: 12px;
  padding: 2px 6px; cursor: pointer; border-radius: 3px;
}
.memoire-blocs-root .bloc-actions button:hover {
  background: #ecf0f1; border-color: var(--border, #e5e7eb);
}
.memoire-blocs-root .bloc-empty {
  margin: 0 0 10px; font-style: italic;
}
.memoire-blocs-root .theme-actions { text-align: right; }
.memoire-blocs-root .theme-actions .primary.small {
  font-size: 13px; padding: 6px 12px;
}

/* ─── SP5 incrément 1 — UX du réservoir ───────────────────────────────────── */
/* Conteneur global de la zone Mémoire, groupé sous le panneau de complétude. */
.memoire-blocs-root .memoire-zone-head {
  display: flex; align-items: center; justify-content: flex-end;
  margin-bottom: 8px;
}
.memoire-blocs-root .memoire-view-tabs {
  display: inline-flex; border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px; overflow: hidden; background: #fff;
}
.memoire-blocs-root .memoire-view-tabs button {
  background: #fff; border: 0; padding: 6px 14px; font-size: 13px;
  color: var(--text, #2c3e50); cursor: pointer; line-height: 1.3;
}
.memoire-blocs-root .memoire-view-tabs button + button {
  border-left: 1px solid var(--border, #e5e7eb);
}
.memoire-blocs-root .memoire-view-tabs button[aria-pressed="true"] {
  background: var(--accent-soft, #DCE7FB); color: var(--accent, #2980b9);
  font-weight: 600;
}
.memoire-blocs-root .memoire-view-tabs button:focus-visible {
  outline: 2px solid var(--accent, #2980b9); outline-offset: -2px;
}

/* Panneau de complétude en tête. */
.memoire-blocs-root .memoire-completion-panel {
  border: 1px solid var(--border, #e5e7eb); border-radius: 6px;
  background: #fbfcfc; padding: 14px 16px; margin-bottom: 4px;
}
.memoire-blocs-root .memoire-completion-title {
  margin: 0 0 6px; font-size: 14px; color: var(--text-soft, #4A5060);
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
}
.memoire-blocs-root .memoire-completion-summary {
  margin: 0 0 10px; font-size: 15px; color: var(--text, #2c3e50);
}
.memoire-blocs-root .memoire-completion-missing-head {
  font-size: 13px; color: var(--text-muted, #7f8c8d); margin: 0 0 4px;
}
.memoire-blocs-root .memoire-completion-missing-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.memoire-blocs-root .memoire-completion-missing-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px; border: 1px solid #fde9c8;
  background: #fffaf2; border-radius: 4px; font-size: 13px;
}
.memoire-blocs-root .memoire-completion-missing-link {
  background: none; border: 0; cursor: pointer; font-size: 13px;
  color: #92400e; font-weight: 600; padding: 2px 8px;
}
.memoire-blocs-root .memoire-completion-missing-link:hover {
  text-decoration: underline;
}

/* Bandeau d'erreur explicite (RÉSERVE A — fetch base-memoire échoué). */
/* Affiché À LA PLACE de l'accordéon, pas en superposition. Pas de fallback
   silencieux sur THEMES_ORDER : si la source serveur de structure
   régime-aware échoue, on ne maquille pas l'erreur derrière un ordre figé
   côté client. */
.memoire-blocs-root .memoire-error-banner {
  border: 1px solid #fde9c8; background: #fffaf2;
  border-left: 4px solid #f0a030; border-radius: 4px;
  padding: 14px 16px; color: #92400e; font-size: 14px;
}
.memoire-blocs-root .memoire-error-banner-title {
  margin: 0 0 4px; font-weight: 600; font-size: 14px;
}
.memoire-blocs-root .memoire-error-banner-body {
  margin: 0; color: var(--text-soft, #4A5060);
}

/* Accordéon — un thème ouvert à la fois. État par défaut : tous fermés. */
.memoire-blocs-root .theme-card.is-collapsed .theme-body { display: none; }
.memoire-blocs-root .theme-card .theme-head {
  cursor: pointer; user-select: none;
}
.memoire-blocs-root .theme-card .theme-head:focus-visible {
  outline: 2px solid var(--accent, #2980b9); outline-offset: -2px;
  border-radius: 4px;
}
.memoire-blocs-root .theme-card .theme-chevron {
  display: inline-block; transition: transform 0.18s ease;
  color: var(--text-muted, #7f8c8d); font-size: 12px; line-height: 1;
  margin-right: 6px;
}
.memoire-blocs-root .theme-card.is-open .theme-chevron {
  transform: rotate(90deg);
}
/* Pastille de statut couleur ET texte (accessibilité — pas la couleur seule). */
.memoire-blocs-root .theme-statut-badge {
  font-size: 11px; padding: 2px 8px; border-radius: 999px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em;
}
.memoire-blocs-root .theme-statut-badge.statut-redigee {
  background: #d7edde; color: #166534;
}
.memoire-blocs-root .theme-statut-badge.statut-stub_a_completer {
  background: #fde9c8; color: #92400e;
}

/* Mode aperçu vs édition — toggle global au niveau de la zone. */
.memoire-blocs-root .memoire-content[data-view-mode="preview"] .memoire-accordion { display: none; }
.memoire-blocs-root .memoire-content[data-view-mode="edit"]    .memoire-preview   { display: none; }

/* Aperçu in-app : vue lecture seule, H2 par thème, blocs inline avec images. */
.memoire-blocs-root .memoire-preview {
  display: flex; flex-direction: column; gap: 24px;
}
.memoire-blocs-root .preview-section {
  border-top: 1px solid var(--border, #e5e7eb); padding-top: 16px;
}
.memoire-blocs-root .preview-section h2 {
  margin: 0 0 12px; font-size: 18px; color: var(--navy, #1F2A4F);
  font-weight: 600;
}
.memoire-blocs-root .preview-bloc {
  margin-bottom: 16px;
}
.memoire-blocs-root .preview-bloc-label {
  font-weight: 600; font-size: 14px; margin: 0 0 4px;
  color: var(--text, #2c3e50);
}
.memoire-blocs-root .preview-bloc-text {
  font-size: 14px; line-height: 1.55; color: var(--text, #2c3e50);
  white-space: pre-wrap;
}
.memoire-blocs-root .preview-bloc-image {
  margin-top: 8px; max-width: 320px; max-height: 240px;
  border: 1px solid var(--border, #e5e7eb); border-radius: 3px;
  background: #f6f7f9; display: block;
}
.memoire-blocs-root .preview-stub {
  background: #fde9c8; border-left: 4px solid #f0a030;
  padding: 12px 14px; color: #92400e; font-style: italic;
  border-radius: 3px;
}
/* Segment amber inline « à compléter : X » — partagé édition + aperçu. */
.memoire-blocs-root .preview-todo {
  color: #f0a030; font-style: italic; font-weight: 600;
}

/* Brique « rendu texte enrichi » — ligne d'aide markdown sous les textareas.
   Discrète, sous le champ, ne casse pas la mise en page existante. */
.markdown-hint {
  display: block; margin-top: 4px;
  font-size: 12px; color: var(--text-muted, #737b86);
  font-style: italic;
}
.markdown-hint code {
  font-family: monospace; font-style: normal;
  background: #f6f7f9; padding: 0 4px; border-radius: 2px;
  color: var(--text, #23272f);
}

/* Brique « toolbar markdown cliquable » — la ligne d'aide statique devient
   une rangée de boutons-tokens cliquables. Style dérivé de .markdown-hint
   (mêmes tailles, même couleur mute), plus les affordances de clic
   (border, hover, focus-visible). Variables de thème réutilisées ; aucune
   nouvelle couleur. */
.md-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
}
.md-toolbar-btn {
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
  font-size: 12px;
  font-style: normal;
  color: var(--text-muted, #737b86);
  background: transparent;
  border: 1px solid var(--border, #dde1e8);
  border-radius: 3px;
  padding: 2px 8px;
  cursor: pointer;
  line-height: 1.4;
  transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.md-toolbar-btn:hover {
  color: var(--text, #23272f);
  border-color: var(--border-strong, #c5cbd4);
  background: #f6f7f9;
}
.md-toolbar-btn:focus-visible {
  outline: 2px solid var(--accent, #3865c8);
  outline-offset: 1px;
}
.md-toolbar-btn:active {
  background: #eef1f5;
}

/* Aperçu live — UNIQUEMENT dans la modale mémoire (input label + textarea
   texte). Conteneur discret, séparé du champ par une bordure supérieure
   fine. Le renderer HTML (renderProseHtml / renderInlineOnlyHtml) fournit
   son propre HTML sûr — on ne fait que le styliser. */
.md-preview {
  margin-top: 6px;
  padding: 8px 10px;
  border: 1px solid var(--border, #dde1e8);
  border-radius: 3px;
  background: #fbfcfd;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text, #23272f);
}
.md-preview:empty { display: none; }
.md-preview-inline {
  min-height: 1.6em;
}
.md-preview-block {
  min-height: 3em;
  max-height: 260px;
  overflow-y: auto;
}
.md-preview p { margin: 4px 0; }
.md-preview h2 {
  margin: 8px 0 4px;
  font-size: 15px;
  color: var(--navy, #1f2a4f);
  font-weight: 600;
}
.md-preview h3 {
  margin: 6px 0 3px;
  font-size: 14px;
  color: var(--text-soft, #4a5060);
  font-weight: 600;
}
.md-preview ul, .md-preview ol {
  margin: 4px 0;
  padding-left: 1.4em;
}
.md-preview li { margin: 2px 0; }
.md-preview em.preview-todo {
  color: #f0a030;
  font-style: italic;
  font-weight: 600;
}
.md-preview strong { color: var(--text, #23272f); }

/* Modal blocs profil */
.memoire-modal-backdrop {
  position: fixed; inset: 0; background: rgba(44,62,80,0.45);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000; padding: 16px;
}
.memoire-modal {
  background: #fff; border-radius: 6px; padding: 20px 22px;
  width: min(560px, 100%); max-height: calc(100vh - 32px); overflow: auto;
  box-shadow: 0 12px 32px rgba(0,0,0,0.2);
}
.memoire-modal h2 { margin: 0 0 12px; font-size: 18px; }
.memoire-modal .memoire-form {
  display: flex; flex-direction: column; gap: 12px;
}
.memoire-modal label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.memoire-modal label span { font-weight: 600; color: var(--text, #2c3e50); }
.memoire-modal input[type=text], .memoire-modal textarea {
  width: 100%; padding: 8px 10px; border: 1px solid var(--border, #e5e7eb);
  border-radius: 3px; font-family: inherit; font-size: 14px;
}
.memoire-modal textarea { min-height: 160px; resize: vertical; }
.memoire-modal .modal-actions {
  display: flex; justify-content: flex-end; gap: 12px; margin-top: 8px;
}

/* Modale de confirmation simplifiée (suppression — SP5 réserve « modale custom »). */
.memoire-modal-confirm .memoire-confirm-body {
  margin: 0 0 16px; color: var(--text, #2c3e50); font-size: 14px;
  line-height: 1.5;
}
.memoire-modal .danger {
  background: #c0392b; color: #fff; border: 0; padding: 8px 16px;
  border-radius: 4px; font-weight: 600; cursor: pointer;
}
.memoire-modal .danger:hover { background: #a8312a; }
.memoire-modal .danger:focus-visible {
  outline: 2px solid #c0392b; outline-offset: 2px;
}

/* ─── Brique « Pré-remplissage bloc Mémoire depuis le profil » ─────────────
 * Règles SCOPÉES à la modale mémoire (0-0-2-0) : aucun global touché.
 * Badge amber (WCAG 6.9:1 sur #fff7ed → #7c2d12) affiché en tête de modale
 * quand on ouvre un brouillon pré-rempli. La couleur amber matérialise
 * « brouillon non validé » — miroir sémantique du `.preview-todo` amber déjà
 * utilisé pour les segments « à compléter » dans le rendu prose. */
.memoire-modal-prefill-badge {
  background: #fff7ed;
  color: #7c2d12;
  border-left: 3px solid #d97706;
  padding: 8px 12px;
  margin: 0 0 12px;
  border-radius: 3px;
  font-size: 13px;
  line-height: 1.4;
}
.memoire-modal-prefill-description {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.5;
}
.theme-actions .theme-prefill {
  margin-left: 8px;
}
.memoire-modal-prefill-gate .memoire-modal-prefill-gate-link {
  display: inline-block;
  background: var(--primary, #2c5aa0);
  color: #fff;
  border: 0;
  padding: 8px 16px;
  border-radius: 4px;
  font-weight: 600;
  text-decoration: none;
}
.memoire-modal-prefill-gate .memoire-modal-prefill-gate-link:hover {
  filter: brightness(0.95);
}

/* Rédaction Phase 2 — prose des sections rédigées.
 * Le markup utilise <pre> pour préserver les sauts de ligne natifs de la
 * sortie Sonnet ; sans cette règle, le default user-agent applique
 * font-family:monospace + white-space:pre → chasse fixe + lignes coupées
 * débordant horizontalement. pre-wrap = newlines préservés + wrap autorisé. */
.redaction-section-prose {
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 8px 0 0;
  max-width: 100%;
}

/* ─── SP2-2a : table de correspondance critère → section ────────────────── */

.redaction-correspondance-table {
  margin: 12px 0 16px;
  padding: 14px 16px;
  background: var(--bg-page-strong, #F4F6FA);
  border: 1px solid var(--border, #DDE1E8);
  border-radius: 8px;
}
.redaction-correspondance-title {
  margin: 0 0 10px;
  font: 600 14px/1.3 var(--sans);
  color: var(--navy, #1F2A4F);
}
.redaction-correspondance-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  background: var(--card, #ffffff);
  border: 1px solid var(--border, #dde1e8);
  border-radius: 4px;
  overflow: hidden;
}
.redaction-correspondance-table th {
  padding: 8px 10px;
  text-align: left;
  background: var(--bg-page-strong, #ecf0f1);
  border-bottom: 1px solid var(--border, #dde1e8);
  font-weight: 600;
  color: var(--text-soft, #4a5060);
}
.redaction-correspondance-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border, #ecf0f1);
  vertical-align: top;
}
.redaction-correspondance-table tr:last-child td {
  border-bottom: none;
}
.redaction-correspondance-table .rc-parent {
  color: var(--text-muted, #7f8c8d);
  font-size: 0.92em;
}
.redaction-correspondance-table .rc-pond {
  text-align: right;
  white-space: nowrap;
  color: var(--text-soft, #4a5060);
  font-variant-numeric: tabular-nums;
}
.redaction-correspondance-table .rc-section {
  color: var(--text-soft, #4a5060);
}
.redaction-correspondance-table .rc-section-hors {
  font-style: italic;
  color: var(--text-muted, #7f8c8d);
}
.redaction-correspondance-table .rc-marqueurs {
  white-space: normal;
}
.redaction-correspondance-table .rc-marqueur {
  display: inline-block;
  padding: 2px 8px;
  margin: 1px 2px;
  background: var(--amber-soft, #FFEBC4);
  color: #7f6500;
  border: 1px solid var(--amber, #F0A030);
  border-radius: 10px;
  font-size: 0.85em;
  font-weight: 600;
  font-style: italic;
}

/* ─── Brique « Note de transparence du mémoire » ──────────────────────────
 * Encart introspectif rendu entre <hr.redaction-sep> et .redaction-snapshot,
 * à l'intérieur de la garde E1.
 *
 * DÉCOUPLAGE TOTAL du mécanisme collapsible global (fix post-validation
 * visuelle Laurent) : l'encart vit à l'intérieur de la section parente
 * « Rédaction du mémoire technique » qui est elle-même un .collapsible. La
 * règle générique `.collapsible.is-collapsed .collapsible-body { display: none }`
 * (cf. style.css:5989) est un sélecteur DESCENDANT non borné — si l'encart
 * portait .collapsible et .collapsible-body, le clic sur le head du parent
 * propagerait la cascade au corps de l'encart. SOLUTION : retirer .collapsible
 * et .collapsible-body du markup de l'encart (cf. renderTransparenceNote dans
 * marche-redaction.js), et utiliser des règles DÉDIÉES ci-dessous, scopées
 * via le préfixe `.redaction-note` (sélecteur ENFANT direct, pas descendant
 * non borné). Le toggle est bindé localement par bindRedactionNoteCollapsible
 * — pas de couplage au mécanisme global. La classe .collapsible-chevron est
 * conservée uniquement pour hériter du style visuel de l'icône (sans la
 * règle de rotation générique qui ne matche plus).
 */
.redaction-note {
  margin: 12px 0 16px;
  padding: 0;
  background: var(--bg-page-strong, #F4F6FA);
  border: 1px solid var(--border, #DDE1E8);
  border-radius: 8px;
  overflow: hidden;
}
.redaction-note-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  user-select: none;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border, #DDE1E8);
}
.redaction-note-head-titles {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 2px;
  min-width: 0;
}
.redaction-note-head h4 {
  margin: 0;
  font: 600 14px/1.3 var(--sans);
  color: var(--navy, #1F2A4F);
}
.redaction-note-counter {
  font: 500 12px/1.3 var(--sans);
  color: var(--text-soft, #4a5060);
  font-variant-numeric: tabular-nums;
}
.redaction-note-body {
  padding: 14px 16px 16px;
  background: var(--card, #ffffff);
}
.redaction-note-subtitle {
  margin: 0 0 12px;
  color: var(--text-muted, #7f8c8d);
}
.redaction-note-sections {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.redaction-note-section {
  padding: 10px 12px;
  background: var(--bg-page-strong, #F4F6FA);
  border: 1px solid var(--border, #DDE1E8);
  border-radius: 6px;
}
.redaction-note-section-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.redaction-note-section-head strong {
  font: 600 13px/1.3 var(--sans);
  color: var(--navy, #1F2A4F);
}
.redaction-note-section-body {
  font-size: 13px;
  line-height: 1.5;
}
.redaction-note-criteres-label,
.redaction-note-trous-label {
  margin: 8px 0 4px;
  font: 600 12px/1.3 var(--sans);
  color: var(--text-soft, #4a5060);
}
.redaction-note-criteres,
.redaction-note-trous {
  list-style: disc;
  padding-left: 22px;
  margin: 0;
}
.redaction-note-criteres li,
.redaction-note-trous li {
  margin: 2px 0;
  color: var(--text, #1F2A4F);
}
.redaction-note-criteres .rc-parent {
  color: var(--text-muted, #7f8c8d);
  font-size: 0.92em;
}
.redaction-note-criteres .rc-marqueur {
  display: inline-block;
  padding: 1px 6px;
  margin-left: 4px;
  background: var(--amber-soft, #FFEBC4);
  color: #7f6500;
  border: 1px solid var(--amber, #F0A030);
  border-radius: 10px;
  font-size: 0.85em;
  font-weight: 600;
  font-style: italic;
}
.redaction-note-no-criteres {
  margin: 6px 0 0;
}
/* État replié — sélecteur ENFANT DIRECT `.redaction-note > .redaction-note-body`
 * pour borner la profondeur (anti-cascade). Aucune autre règle générique ne
 * peut atteindre .redaction-note-body via descendant non borné. */
.redaction-note.is-collapsed > .redaction-note-body {
  display: none;
}
.redaction-note.is-collapsed > .redaction-note-head {
  border-bottom: none;
}
/* Rotation du chevron — règle dédiée (la règle générique
 * `.collapsible.is-collapsed .collapsible-chevron` du fichier ne s'applique
 * plus puisque la note n'a plus la classe .collapsible). */
.redaction-note.is-collapsed .collapsible-chevron {
  transform: rotate(-90deg);
}
.redaction-note .collapsible-chevron {
  display: inline-block;
  transition: transform 0.15s ease;
}

/* ─── Brique « assistant de complétude pré-génération » (commit 4) ──────── */

.redaction-completion-panel {
  margin: 12px 0 16px;
  padding: 14px 16px;
  background: var(--bg-page-strong, #F4F6FA);
  border: 1px solid var(--border, #DDE1E8);
  border-radius: 8px;
}
.redaction-completion-title {
  margin: 0 0 8px;
  font: 600 14px/1.3 var(--sans);
  color: var(--navy, #1F2A4F);
}
.redaction-completion-summary {
  margin: 0 0 12px;
  font-size: 13.5px;
  color: var(--text-soft, #4A5060);
}
.redaction-completion-list {
  list-style: none;
  padding: 0;
  margin: 0 0 10px;
}
.completion-section-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border-light, #ECEEF3);
  font-size: 13px;
}
.completion-section-row:last-child { border-bottom: 0; }
.completion-section-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font: 600 11px var(--sans);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  flex-shrink: 0;
}
.completion-badge-ready {
  background: rgba(46,139,87,0.14);
  color: #1F7A4D;
}
.completion-badge-missing {
  background: var(--amber-soft, #FFEBC4);
  color: #8A5A07;
}
.completion-section-label {
  flex: 1;
  color: var(--text, #23272F);
  overflow: hidden;
  text-overflow: ellipsis;
}
.completion-section-link {
  flex-shrink: 0;
  color: var(--accent, #3865C8);
  text-decoration: none;
  font-weight: 500;
  font-size: 12.5px;
}
.completion-section-link:hover { text-decoration: underline; }
.redaction-completion-presentation-info {
  margin: 8px 0 0;
  padding: 8px 10px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-soft, #4A5060);
  background: rgba(63,99,200,0.05);
  border-left: 3px solid var(--accent-soft, #DCE7FB);
  border-radius: 0 4px 4px 0;
}

/* Banner de divergence — encart amber voyant rendu quand le snapshot
   persisté est désaligné du plan vivant (signature !=) OU quand le snapshot
   a moins de sections que le plan courant (compteur affichées/disponibles).
   Brique « Ergonomie post-génération du mémoire ». */
.redaction-divergence-banner {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin: 14px 0;
  padding: 12px 14px;
  background: var(--amber-soft, #fde9c8);
  border: 1px solid var(--arbitrer, #d97706);
  border-left: 4px solid var(--arbitrer, #d97706);
  border-radius: 6px;
  color: #6b3a03;
}
.redaction-divergence-icon {
  font-size: 20px;
  line-height: 1;
  flex-shrink: 0;
  color: var(--arbitrer, #d97706);
}
.redaction-divergence-body { flex: 1; }
.redaction-divergence-title {
  margin: 0 0 4px;
  font: 600 14px var(--sans);
  color: #6b3a03;
}
.redaction-divergence-text {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: #6b3a03;
}
.redaction-divergence-text strong { color: var(--arbitrer, #d97706); }
/* Ligne d'avertissement conditionnelle — rendue uniquement si le snapshot
   contient au moins une section éditée manuellement (editedCount ≥ 1).
   Brique « snapshot — divergence de contenu ». */
.redaction-divergence-warning {
  margin: 6px 0 0;
  font: italic 12px var(--sans);
  color: #7a4a10;
}

/* Boutons d'action — version 2 boutons côte à côte en mode brouillon. */
.redaction-actions-completion {
  display: flex;
  gap: 12px;
  align-items: stretch;
  flex-wrap: wrap;
  margin-top: 12px;
}
.redaction-actions-completion button {
  flex: 1 1 220px;
  min-width: 220px;
  padding: 10px 16px;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.redaction-actions-completion .btn-main {
  font: 600 14px var(--sans);
}
.redaction-actions-completion .btn-subtitle {
  font: 400 11.5px var(--sans);
  opacity: 0.78;
}

/* Modale « Sections à compléter ». */
.redaction-completion-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(31,42,79,0.55);
  backdrop-filter: blur(2px);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 2000;
}
.redaction-completion-modal-backdrop.is-open { display: flex; }
.redaction-completion-modal {
  position: relative;
  background: var(--card, #FFFFFF);
  border-radius: 10px;
  padding: 24px 28px;
  max-width: 560px;
  width: calc(100% - 32px);
  max-height: 80vh;
  overflow: auto;
  box-shadow: 0 12px 40px rgba(31,42,79,0.25);
}
.redaction-completion-modal h3 {
  margin: 0 0 8px;
  color: var(--navy, #1F2A4F);
  font: 600 17px var(--sans);
}
.redaction-completion-modal p {
  margin: 0 0 14px;
}
.redaction-completion-modal-close {
  position: absolute;
  top: 12px;
  right: 14px;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--text-muted, #737B86);
  font: 600 22px var(--sans);
  line-height: 1;
  padding: 4px 8px;
}
.redaction-completion-modal-close:hover { color: var(--text, #23272F); }
.redaction-completion-modal-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.redaction-completion-modal-list li {
  margin: 4px 0;
}
.redaction-completion-modal-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--border, #DDE1E8);
  border-radius: 6px;
  text-decoration: none;
  color: var(--text, #23272F);
  transition: border-color 0.12s ease, background 0.12s ease;
}
.redaction-completion-modal-item:hover {
  border-color: var(--accent, #3865C8);
  background: var(--accent-soft, #DCE7FB);
}
.completion-section-arrow {
  color: var(--accent, #3865C8);
  font-weight: 600;
  flex-shrink: 0;
}

/* Bannière de provenance dans profil-entreprise.html — affichée quand le
 * deep-link transporte `section=` et/ou `return_to=`. */
/* Le banner sticky reste DANS le DOM même quand caché (au retour en mode
 * édition, il réapparaît à l'identique sans re-fetch). L'attribut HTML
 * `hidden` est par défaut écrasé par `display: flex` ci-dessous, on le
 * réaffirme ici en `display: none !important`. SP5 incrément 1 — retouche
 * cosmétique : masquage en mode aperçu via `syncBannerVisibility()`. */
.memoire-banner-context[hidden] { display: none !important; }
.memoire-banner-context {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin: 0 0 14px;
  padding: 12px 16px;
  background: var(--accent-soft, #DCE7FB);
  border-left: 4px solid var(--accent, #3865C8);
  border-radius: 6px;
  font-size: 13.5px;
}
.memoire-banner-title {
  font-weight: 600;
  color: var(--navy, #1F2A4F);
  flex: 1;
}
.memoire-banner-return {
  flex-shrink: 0;
  color: var(--accent, #3865C8);
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap;
}
.memoire-banner-return:hover { text-decoration: underline; }

/* Surlignage transitoire du theme-card ciblé par le deep-link. */
.theme-card-deeplinked {
  outline: 2px solid var(--accent, #3865C8);
  outline-offset: 4px;
  transition: outline-color 0.3s ease;
}

/* ====================================================================
   Brique « Identité entreprise : logo + bannière dans le profil »
   ====================================================================
   Îlot média rendu DANS le panneau identite, hors data-field et hors
   complétude (sœur visuelle de l'accordéon MemoireBlocs).
   ==================================================================== */

.identity-media-section {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border, #e5e7eb);
}
.identity-media-section-head { margin-bottom: 16px; }
.identity-media-section-head h2 {
  margin: 0 0 4px;
  font-size: 16px;
  color: var(--navy, #1F2A4F);
}
.identity-media-section-head p {
  margin: 0;
  font-size: 13px;
}

.identity-media-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 720px) {
  .identity-media-grid { grid-template-columns: 1fr; }
}

.identity-media-slot {
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  padding: 14px;
  background: var(--card, #fff);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.identity-media-slot h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--navy, #1F2A4F);
}

.identity-media-dropzone {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100px;
  border: 2px dashed var(--border-strong, #cbd5e0);
  border-radius: 4px;
  background: var(--bg-page, #f8f9fa);
  cursor: pointer;
  font-size: 13px;
  color: var(--text-muted, #6c7480);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.identity-media-dropzone:hover {
  border-color: var(--accent, #3865C8);
  background: var(--accent-soft, #eef2fc);
}
.identity-media-dropzone input[type=file] { display: none; }
.identity-media-dropzone-cta { text-align: center; padding: 8px 12px; }

.identity-media-helper {
  font-size: 12px;
  line-height: 1.45;
}

.identity-media-preview {
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 4px;
  background: var(--bg-page, #f8f9fa);
  padding: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
}
.identity-media-preview img {
  max-width: 100%;
  max-height: 200px;
  object-fit: contain;
  display: block;
}

.identity-media-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}
.identity-media-replace {
  cursor: pointer;
  color: var(--accent, #3865C8);
  font-weight: 600;
  font-size: 13px;
}
.identity-media-replace:hover { text-decoration: underline; }
.identity-media-actions .danger { background: none; color: #c0392b; padding: 0; font-weight: 600; font-size: 13px; border: 0; cursor: pointer; }
.identity-media-actions .danger:hover { text-decoration: underline; box-shadow: none; }

.identity-media-status {
  font-size: 12px;
  margin: 0;
  min-height: 16px;
}
.identity-media-status.error {
  color: #c0392b;
}

/* ─── Modale partagée (recadreur + confirmation) ─── */
.identity-media-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(44, 62, 80, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 16px;
}
.identity-media-modal {
  background: #fff;
  border-radius: 6px;
  padding: 20px 22px;
  width: min(720px, 100%);
  max-height: calc(100vh - 32px);
  overflow: auto;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2);
}
.identity-media-modal h2 { margin: 0 0 12px; font-size: 18px; color: var(--navy, #1F2A4F); }
.identity-media-modal .modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 14px;
}
.identity-media-modal .danger {
  background: #c0392b;
  color: #fff;
  border: 0;
  padding: 8px 16px;
  border-radius: 4px;
  font-weight: 600;
  cursor: pointer;
}
.identity-media-modal .danger:hover { background: #7e2424; }
.identity-media-modal-confirm .identity-media-confirm-body {
  margin: 0 0 16px;
  color: var(--text, #2c3e50);
  font-size: 14px;
  line-height: 1.5;
}

/* ─── Recadreur canvas ─── */
.identity-media-cropper { width: min(720px, 100%); }
.identity-cropper-stage {
  position: relative;
  background: #1a1a1a;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 12px;
}
.identity-cropper-canvas {
  display: block;
  width: 100%;
  height: auto;
  cursor: crosshair;
}
.identity-cropper-controls { margin-bottom: 12px; }
.identity-cropper-controls label {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
  margin-bottom: 6px;
}
.identity-cropper-zoom { flex: 1; }
.identity-cropper-hint {
  margin: 0;
  font-size: 12px;
}

/* =========================================================================
 * Brique « Profil enrichi » α — CSS module profil-entites.js.
 *
 * GABARITS DE RÉFÉRENCE (mesures E8 profil-entreprise.html) :
 *   .wrap                       : max-width 1100px, padding 32px 32px 96px,
 *                                 background transparent, body font 16px/400/1.55.
 *   .tab-panel .panel-head      : margin-bottom 18px (style.css:815).
 *   .tab-panel .panel-head h2   : hérite h1..h4 (font-weight 600, line-height 1.18)
 *                                 + font-size clamp(19px,1.8vw,23px) (style.css:80).
 *   .tab-panel .panel-head p    : .panel-desc — color var(--encre-doux) 15px (style.css:817).
 * Le module vit dans une `.card` (via profil.js render), donc le padding 28px
 * de .card (style.css:585) s'applique. On garde ici uniquement les styles
 * spécifiques au CRUD entités (toolbar + cards internes + modales + galerie).
 * ========================================================================= */

.profil-entites-root { display: flex; flex-direction: column; gap: 16px; }
.profil-entites-wrap { display: flex; flex-direction: column; gap: 18px; }

.entite-toolbar {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  flex-wrap: wrap;
}
.entite-toolbar .btn { padding: 8px 14px; font-size: 14px; }

.entite-empty {
  padding: 20px 0;
  color: var(--text-muted);
  font-style: italic;
}

/* Point 4 (bis) : espacement clair entre groupes sur onglets Références et
 * Actualités (vue plate) — gap plus large que les cartes intra-groupe pour
 * marquer visuellement la séparation.  */
.entite-body { display: flex; flex-direction: column; gap: 20px; }

/* Cartes entités — sœur visuelle de .theme-card (memoire-blocs). */
.entite-group { display: flex; flex-direction: column; gap: 8px; }
.entite-group-title {
  font-weight: 600;
  font-size: 12px;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 8px 0 4px 0;
}
.entite-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  box-shadow: var(--shadow-s);
}
/* Point 4 : arborescence gamme→produits perceptible. Les produits rattachés
 * vivent DANS la carte de leur gamme (.entite-card-gamme .entite-produits-nested)
 * avec :
 *   - fond légèrement teinté (--bg-page) pour distinguer la « zone enfants »
 *     de la carte gamme ;
 *   - indentation latérale (padding-left 20px) ;
 *   - filet connecteur vertical (border-left 3px sur .entite-produits-nested)
 *     en couleur accent-soft pour renforcer la relation parent-enfant ;
 *   - séparation supérieure par un fin trait horizontal (border-top).
 * Les produits ORPHELINS (groupe « Sans rattachement à une gamme ») restent
 * dans une .entite-list au niveau du .entite-body — pas d'imbrication. */
.entite-card-gamme .entite-produits-nested {
  margin-top: 12px;
  padding: 10px 0 4px 20px;
  border-top: 1px solid var(--border);
  border-left: 3px solid var(--accent-soft);
  background: var(--bg-page);
  border-radius: 0 0 6px 6px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-left: -12px;
  margin-right: -12px;
  margin-bottom: -10px;
}
.entite-card-gamme .entite-produits-nested .entite-card {
  background: var(--card);
  border: 1px solid var(--border);
}
.entite-list { display: flex; flex-direction: column; gap: 10px; }

.entite-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.entite-head-main {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  min-width: 0; flex: 1;
}
.entite-type-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font: 600 11px var(--sans);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  background: var(--accent-soft);
  color: var(--primary);
}
.entite-label {
  margin: 0;
  font-weight: 500;
  font-size: 15px;
  color: var(--text);
  line-height: 1.35;
}
.entite-date {
  font-size: 13px;
  color: var(--text-soft);
}
.entite-head-actions { display: flex; gap: 6px; flex-shrink: 0; flex-wrap: wrap; }
/* Point 1 (bug bouton Supprimer illisible) : la règle globale button.danger
 * pose background:var(--nogo) + color:#fff. Un simple color:red sur .danger
 * ne suffisait pas — le fond rouge restait, texte rouge sur rouge illisible.
 * Fix : les boutons .link dans .entite-head-actions ET .entite-manage-photo-actions
 * sont TRANSPARENTS (fond clair de la carte), le .danger ne change QUE la
 * couleur du texte (rouge sur fond blanc). Miroir du pattern .link de
 * memoire-blocs (aucun style .link ne redéfinit de background). */
.entite-head-actions button.link,
.entite-manage-photo-actions button.link,
.entite-manage-caract td button.link {
  background: transparent;
  border: 0;
  padding: 4px 8px;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 13px;
  border-radius: 4px;
  box-shadow: none;
}
.entite-head-actions button.link:hover,
.entite-manage-photo-actions button.link:hover,
.entite-manage-caract td button.link:hover {
  background: var(--bg-page);
  color: var(--text);
}
.entite-head-actions button.link.danger,
.entite-manage-photo-actions button.link.danger,
.entite-manage-caract td button.link.danger {
  background: transparent;
  color: #b91c1c;
  box-shadow: none;
}
.entite-head-actions button.link.danger:hover,
.entite-manage-photo-actions button.link.danger:hover,
.entite-manage-caract td button.link.danger:hover {
  background: #fee2e2;
  color: #7e2424;
}

.entite-content { display: flex; flex-direction: column; gap: 12px; }
.entite-texte.prose-preview {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
}
.entite-texte.prose-preview p:last-child { margin-bottom: 0; }

.entite-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
}
.entite-photo {
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg-page);
}
.entite-photo img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  aspect-ratio: 4 / 3;
}

.entite-caracts { margin-top: 8px; }
.entite-caract-title {
  font-weight: 600;
  font-size: 12px;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 6px 0;
}
.entite-caract-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.entite-caract-table td {
  padding: 4px 10px 4px 0;
  border-bottom: 1px dashed var(--border);
}
.entite-caract-table tr:last-child td { border-bottom: 0; }
.entite-caract-cle { font-weight: 500; color: var(--text); }
.entite-caract-valeur { color: var(--text); }
.entite-caract-unite { color: var(--text-soft); }

/* Modale locale (miroir identity-media / marche-jalons — JAMAIS
 * window.confirm). Backdrop caché par défaut, ouvert en display:flex. */
.entite-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.entite-modal {
  background: #fff;
  border-radius: 8px;
  padding: 24px;
  max-width: 640px;
  width: 92%;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2);
}
.entite-modal h3 { margin: 0 0 12px 0; font: 700 18px var(--sans); }
.entite-modal-body { margin-bottom: 12px; }
.entite-modal-actions {
  display: flex; justify-content: flex-end; gap: 10px; margin-top: 12px;
}
.entite-modal-actions .btn.primary { background: var(--primary); color: #fff; border: none; padding: 8px 14px; border-radius: 6px; cursor: pointer; }
.entite-modal-actions .btn.secondary { background: transparent; border: 1px solid var(--border); padding: 8px 14px; border-radius: 6px; cursor: pointer; }
.entite-modal-actions .btn.danger { background: #b91c1c; color: #fff; border: none; }

.entite-field {
  display: flex; flex-direction: column; gap: 4px;
  margin-bottom: 12px;
}
.entite-field > span { font-size: 13px; color: var(--text-soft); font-weight: 500; }
.entite-field input[type=text], .entite-field input[type=date], .entite-field select, .entite-field textarea {
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: var(--sans);
  font-size: 14px;
}

.entite-error {
  background: #fee2e2;
  color: #b91c1c;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 13px;
  margin-top: 8px;
}

/* Modale de gestion photos + caract */
.entite-manage-section { margin-bottom: 20px; }
.entite-manage-section > h4 {
  font-size: 13px;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 4px 0;
}
/* Point 5 : phrase d'aide sous le titre PHOTOS / CARACTÉRISTIQUES avec
 * exemple concret. Style discret, italique muted — n'alourdit pas la modale. */
.entite-manage-help {
  margin: 0 0 10px 0;
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.4;
  font-style: italic;
}
.entite-manage-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 8px;
  margin-bottom: 10px;
}
.entite-manage-photo {
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  position: relative;
}
.entite-manage-photo img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block;
}
.entite-manage-photo-actions {
  display: flex; justify-content: space-between; padding: 4px 6px;
  background: var(--bg-page);
  font-size: 12px;
}
.entite-manage-photo-actions .danger { color: #b91c1c; }
.entite-photo-upload { display: flex; gap: 8px; align-items: center; }

.entite-manage-caract {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-bottom: 8px;
}
.entite-manage-caract th {
  text-align: left;
  padding: 6px 8px 6px 0;
  font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
}
.entite-manage-caract td {
  padding: 6px 8px 6px 0;
  border-bottom: 1px dashed var(--border);
}
.entite-manage-caract input[type=text] {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 13px;
}
.entite-caract-add {
  display: grid;
  grid-template-columns: 1fr 1fr 100px auto;
  gap: 6px;
  margin-top: 6px;
}
.entite-caract-add input[type=text] {
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 13px;
}

/* Cases activites-types (onglet identité, purement indicatives). */
.activites-types {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  padding: 6px 0;
}
.activites-types-opt {
  display: flex; align-items: center; gap: 6px;
  cursor: pointer;
  font-size: 14px;
}
.activites-types-opt input[type=checkbox] { margin: 0; }

/* ─── Brique β « Profil enrichi » — surface de sélection par marché ───────
 * Miroir strict des tokens capturés à C-2 (docs/gabarits/beta-selection-
 * references.json) : panel identique à .redaction-correspondance-table +
 * .redaction-note, head identique à .redaction-note-head, h4 identique
 * navy 14/600, counter 12/500 text-soft.
 *
 * DÉCOUPLAGE STRICT du mécanisme collapsible global de marche.js — le
 * markup n'utilise PAS .collapsible / .collapsible-body / .card-head-
 * collapsible (précédent gravé note de transparence). Le toggle est
 * local, self-contained (module marche-profil-entites-selection.js).
 */
.marche-selection-section {
  margin: 12px 0 16px;
  padding: 0;
  background: var(--bg-page-strong, #F4F6FA);
  border: 1px solid var(--border, #DDE1E8);
  border-radius: 8px;
  overflow: hidden;
}
.marche-selection-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  user-select: none;
  background: transparent;
  border: none;
  border-bottom: 1px solid transparent;
}
.marche-selection-section[data-collapsible-selection]:not([hidden]) > .marche-selection-body:not([hidden]) {
  /* Filet lisibilité : quand le body est ouvert, la séparation head/body */
  /* est visible via un liseré (ci-dessous), sinon head reste plein. */
}
.marche-selection-section > .marche-selection-body:not([hidden]) {
  border-top: 1px solid var(--border, #DDE1E8);
}
.marche-selection-head-titles {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 2px;
  min-width: 0;
}
.marche-selection-head h4 {
  margin: 0;
  font: 600 14px/1.3 var(--sans);
  color: var(--navy, #1F2A4F);
}
.marche-selection-counter {
  font: 500 12px/1.3 var(--sans);
  color: var(--text-soft, #4a5060);
  font-variant-numeric: tabular-nums;
}
.marche-selection-chevron {
  font-size: 12px;
  color: var(--text-muted, #7f8c8d);
  transition: transform 0.15s ease-in-out;
}
.marche-selection-section[data-collapsible-selection] .marche-selection-head[aria-expanded="true"] .marche-selection-chevron {
  transform: rotate(180deg);
}
.marche-selection-body {
  padding: 14px 16px 16px;
  background: var(--card, #ffffff);
}
/* CORRECTIF de rendu (préfixage .marche-selection-body — spécificité renforcée).
 *
 * Les règles globales suivantes du même fichier écrasaient les enfants du
 * composant sans que le préfixe de classe suffise :
 *   - style.css:660-667  input, select, textarea { width:100%; padding:10px 12px;
 *                        border:1px solid ...; background:...; font:15px/1.5 ... }
 *                        → checkboxes étirés à 100% du parent, écrasent le libellé
 *   - style.css:652-658  label { display:block; margin:14px 0 6px;
 *                        font-size:13px; color:...; font-weight:500 }
 *                        → items trop hauts + héritage de font/color parasite
 *
 * Correctif : chaque règle enfant est préfixée par `.marche-selection-body`
 * pour atteindre une spécificité 0-3-1+ qui bat 0-0-1 des règles globales,
 * ET re-déclare EXPLICITEMENT les propriétés que le global impose
 * (width/padding/border/background/font/margin). Aucune règle globale n'est
 * modifiée — le composant se défend, il ne touche pas au monde.
 */
.marche-selection-body .selection-group {
  list-style: none;
  padding: 0;
  margin: 0 0 12px;
}
.marche-selection-body .selection-group:last-child { margin-bottom: 0; }
.marche-selection-body .selection-group-title {
  font: 600 12px/1.3 var(--sans);
  color: var(--text-muted, #7f8c8d);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin: 0 0 6px;
  padding: 0;
}
.marche-selection-body .selection-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 14px;
  margin: 0;
}
.marche-selection-body .selection-item label {
  display: flex;
  align-items: flex-start;      /* checkbox baseline avec la 1re ligne du body */
  gap: 8px;
  cursor: pointer;
  width: 100%;
  /* Défaire l'héritage global `label { ... }` — cf. style.css:652-658 */
  margin: 0;
  padding: 0;
  font-size: 14px;
  font-weight: 400;
  color: var(--text, #23272F);
}
.marche-selection-body .selection-item-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.marche-selection-body .selection-item-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}
.marche-selection-body .selection-item-photos-count {
  font-size: 12px;
  color: var(--text-soft, #4a5060);
  white-space: nowrap;
  flex: 0 0 auto;
}
.marche-selection-body .selection-item-excerpt {
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-muted, #7f8c8d);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
/* Checkbox alignée verticalement sur la 1re ligne (~14×1.3 = 18px) */
.marche-selection-body .selection-item input[type="checkbox"] {
  margin-top: 3px;
}
.marche-selection-body .selection-item input[type="checkbox"] {
  /* Défaire l'héritage global `input, select, textarea { ... }` — cf. style.css:660-667.
   * SANS ces re-déclarations, la checkbox devient 100% de large et écrase
   * le libellé à ~12px de large → wrap lettre par lettre → illusion verticale. */
  width: auto;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  font: inherit;
  color: inherit;
  margin: 0;
  flex: 0 0 auto;
}
.marche-selection-body .selection-item-label {
  flex: 1 1 auto;
  min-width: 0;
  word-break: break-word;
}
.marche-selection-body .selection-nested {
  list-style: none;
  padding: 0 0 0 24px;
  margin: 4px 0 0;
  border-left: 2px solid var(--accent-soft, #DDE1E8);
}
.marche-selection-empty {
  padding: 8px 0;
  font-size: 14px;
  color: var(--text-soft, #4a5060);
}
.marche-selection-empty a { display: inline-block; margin-top: 6px; }

/* Ligne additive du banner divergence quand la sélection a évolué. */
.redaction-divergence-selection {
  margin: 6px 0 0;
  font-size: 13px;
  color: var(--text-soft, #4a5060);
  line-height: 1.5;
}
.redaction-divergence-selection strong { color: var(--text, #23272F); }


/* ============================================================================
 * Sous-brique ③ « Ingestion + cache notices ».
 * Card compacte placée entre renderStatusBand et renderSuivi. Spécificité
 * 0-0-2-0 (parent .fiche-acheteur-notices + classe fille), AUCUN global touché.
 * ============================================================================ */
/* T-TYPO — ancre héritage à l'échelle de référence in-product (13.5px, patron
 * .acheteur-sales-block du J1 et .dce-sales-block du 2a-bis). Sans cette
 * règle, le corps des rangs .acheteur-notice-* héritait du body à 16px —
 * plainte Laurent 17/08 « titres et objets des marchés sont plus grands que
 * dans les autres onglets ». Les sélecteurs internes à font-size explicite
 * (count 14px, progress/error 13px) restent gagnants par spécificité. */
.fiche-acheteur-notices {
  font-size: 13.5px;
}
.fiche-acheteur-notices .acheteur-notices-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}
.fiche-acheteur-notices .acheteur-notices-count {
  font-size: 14px;
}
.fiche-acheteur-notices .acheteur-notices-actions {
  display: flex;
  gap: 8px;
}
.fiche-acheteur-notices .acheteur-notices-progress {
  font-size: 13px;
  color: var(--text-soft, #4a5060);
}
.fiche-acheteur-notices .acheteur-notices-error {
  font-size: 13px;
  color: var(--danger, #9b2c2c);
}


/* ============================================================================
 * Sous-brique ③bis — liste des notices (rangs sous le bloc collapsible).
 * Miroir strict des patrons .doc-row-* : flex row avec icône | body | actions.
 * Spec 0-0-1-0, aucun global touché.
 * ============================================================================ */
.acheteur-notices-list {
  max-height: 320px;
  overflow-y: auto;
  margin-top: 4px;
}
.acheteur-notices-ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.acheteur-notice-row {
  display: flex;
  gap: 10px;
  padding: 8px 12px;
  border-top: 1px solid var(--border);
  align-items: flex-start;
}
.acheteur-notice-row:first-child {
  border-top: none;
}
.acheteur-notice-icon {
  flex: 0 0 auto;
  color: var(--text-muted);
  padding-top: 2px;
}
.acheteur-notice-body {
  flex: 1;
  min-width: 0;
}
.acheteur-notice-title {
  font-weight: 600;
  font-size: 14px;                       /* T-TYPO — patron .dce-sales-extract-t=14px */
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.acheteur-notice-meta {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 2px;
}
.acheteur-notice-meta-sep {
  color: var(--text-muted);
}
.acheteur-notice-holder {
  margin-top: 4px;
}
.acheteur-notice-actions {
  flex: 0 0 auto;
}
.acheteur-notice-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* ==========================================================================
 * Sous-brique ④ « Analyse acheteur + compétiteurs »
 *
 * Toutes les règles sont scopées `.fiche-acheteur-analysis .*` (spec ≤ 0-0-2-0)
 * pour ne toucher AUCUN global. Le token --color-conseil-redactionnel est
 * défini dans :root pour cohérence avec la palette (miroir COLOR.violet).
 * ========================================================================== */
/* T-TYPO — ancre héritage à 13.5px (patron .acheteur-sales-block J1 et
 * .dce-sales-block 2a-bis). Corrige la plainte Laurent 17/08 « textes de
 * synthèse plus grands que dans les autres onglets » : synthese li /
 * conseil.text / chapitre.markdown / disclaimer héritaient de 16px du body.
 * Sélecteurs internes à font-size explicite (h3=16, h4=14, legend=13,
 * badges=11/12) restent gagnants par spécificité. */
.fiche-acheteur-analysis {
  font-size: 13.5px;
}
.fiche-acheteur-analysis .acheteur-analyse-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.fiche-acheteur-analysis .acheteur-analyse-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.fiche-acheteur-analysis .acheteur-analyse-error {
  padding: 8px 12px;
  border-left: 3px solid var(--nogo);
  background: #f4e1e1;
  color: var(--nogo);
  border-radius: 6px;
}
.fiche-acheteur-analysis .acheteur-analyse-disclaimer {
  padding: 6px 0;
  border-top: 1px dashed var(--border);
  margin-top: 8px;
  font-style: italic;
}
.fiche-acheteur-analysis .acheteur-analyse-synthese {
  list-style: none;
  padding-left: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.fiche-acheteur-analysis .acheteur-analyse-synthese li {
  padding-left: 20px;
  position: relative;
}
.fiche-acheteur-analysis .acheteur-analyse-synthese li::before {
  content: '▸';
  color: var(--accent);
  position: absolute;
  left: 4px;
  font-weight: bold;
}
.fiche-acheteur-analysis .acheteur-analyse-legend {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  background: var(--bg-page);
}
.fiche-acheteur-analysis .acheteur-analyse-legend summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 13px;
  color: var(--text-soft);
}
.fiche-acheteur-analysis .acheteur-analyse-legend ul {
  list-style: none;
  padding: 8px 0 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.fiche-acheteur-analysis .acheteur-analyse-legend li {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-size: 13px;
}
.fiche-acheteur-analysis .acheteur-conseil-badge {
  padding: 2px 8px;
  border-radius: 3px;
  font-weight: 600;
  font-size: 12px;
  white-space: nowrap;
}
.fiche-acheteur-analysis .acheteur-conseil-block,
.fiche-acheteur-analysis .acheteur-chapitre-block {
  padding: 10px 12px;
  border-radius: 6px;
  margin: 8px 0;
}
.fiche-acheteur-analysis .acheteur-conseil-header,
.fiche-acheteur-analysis .acheteur-chapitre-header {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.fiche-acheteur-analysis .acheteur-conseil-type-badge {
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.fiche-acheteur-analysis .acheteur-conseil-priorite-badge {
  padding: 1px 6px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.08);
  font-size: 11px;
  color: var(--text-soft);
  text-transform: lowercase;
}
.fiche-acheteur-analysis .acheteur-conseil-source {
  margin-left: auto;
  font-size: 11px;
}
.fiche-acheteur-analysis .acheteur-conseil-text {
  color: var(--text);
  line-height: 1.5;
}
.fiche-acheteur-analysis .acheteur-chapitre-header h4 {
  margin: 0;
  flex: 1 1 auto;
  font-size: 14px;                       /* T-TYPO — aligné sur .fiche-acheteur-analysis h4=14px (était 15px, discret dépassement) */
}
.fiche-acheteur-analysis .acheteur-chapitre-markdown {
  color: var(--text);
  white-space: pre-wrap;
  line-height: 1.5;
}
.fiche-acheteur-analysis .acheteur-chapitre-disclaimer {
  margin-top: 6px;
  font-style: italic;
}
.fiche-acheteur-analysis h4 {
  margin: 8px 0 4px;
  font-size: 14px;
  color: var(--navy);
}
.fiche-acheteur-analysis h3 {
  margin: 12px 0 4px;
  font-size: 16px;
  color: var(--navy);
}
.fiche-acheteur-analysis ul {
  margin: 4px 0 8px;
  padding-left: 20px;
}
/* Amendement #11c — badge « marché similaire » (cpv_overlap avec marché courant). */
.fiche-acheteur-analysis .acheteur-analyse-similar-badge {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
  margin-left: 6px;
}
.fiche-acheteur-analysis .acheteur-analyse-similar-count {
  color: var(--accent);
  font-weight: 600;
  margin: 4px 0 8px;
}

/* ============================================================================
 * Sous-brique ⑤ « Recherche de partenaires » — CSS scopé .fiche-partenaires.
 * Spec 0-0-2-0 max, aucun sélecteur global touché (patron miroir ④).
 * ============================================================================ */
.fiche-partenaires .partenaires-body {
  padding-top: 8px;
}
.fiche-partenaires .partenaires-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.fiche-partenaires .partenaires-empty {
  padding: 8px 0;
}
.fiche-partenaires .partenaires-pending {
  padding: 8px 0;
}
.fiche-partenaires .partenaires-error {
  color: var(--nogo);
  padding: 8px 0;
}
.fiche-partenaires .partenaires-resume {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: 12px 0;
}
.fiche-partenaires .partenaires-synthese ul {
  margin: 4px 0 12px 20px;
  padding: 0;
}
.fiche-partenaires .partenaires-lentille {
  margin: 16px 0;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
}
.fiche-partenaires .partenaires-lentille h3 {
  margin: 0 0 4px 0;
  color: var(--primary, #1F2A4F);
}
.fiche-partenaires .partenaires-candidates {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 12px;
}
.fiche-partenaires .partenaires-candidate {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fff;
}
.fiche-partenaires .partenaires-candidate-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.fiche-partenaires .partenaires-candidate-subcats {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin: 6px 0;
}
.fiche-partenaires .partenaires-contacts,
.fiche-partenaires .partenaires-marches {
  margin-top: 8px;
}
.fiche-partenaires .partenaires-contacts ul,
.fiche-partenaires .partenaires-marches ul {
  margin: 4px 0 0 20px;
  padding: 0;
}
.fiche-partenaires .pill-subcat {
  background: #f0f4f8;
  color: #23272f;
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 12px;
}
.fiche-partenaires .badge-laureat {
  background: var(--accent-soft, #DCE7FB);
  color: var(--accent, #1F2A4F);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
}
.fiche-partenaires .partenaires-conseils {
  margin-top: 16px;
}
.fiche-partenaires .partenaires-conseil {
  padding: 8px 12px;
  border-left: 3px solid var(--accent, #1F2A4F);
  background: #fafbfc;
  margin: 8px 0;
}
.fiche-partenaires .partenaires-conseil-head {
  display: flex;
  gap: 6px;
  margin-bottom: 4px;
}
.fiche-partenaires .pill-priorite-haute {
  background: #fdecec;
  color: #9b2c2c;
}
.fiche-partenaires .pill-priorite-moyenne {
  background: #fff7ed;
  color: #7c2d12;
}
.fiche-partenaires .pill-priorite-basse {
  background: #f0f4f8;
  color: #4a5060;
}

/* Modale portée — F1 stratège 23/07 : scoping par CLASSE des tuiles/picker
 * (patron miroir strict acheteur-modal-desc de _renderAcheteurModal). La
 * modale utilise le patron canonique showModal (#modal-backdrop → #modal-body),
 * aucun wrapper personnalisé. Les classes ci-dessous sont scopées AU BODY
 * de la modale globale par leur préfixe unique `.partenaires-scope-*` et
 * `.partenaires-intl-*` — spec 0-0-1-0, aucun global touché. */
.partenaires-scope-tiles {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 12px 0;
}
.partenaires-scope-tile {
  display: flex;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 120ms, background 120ms;
}
.partenaires-scope-tile:hover {
  border-color: var(--accent, #1F2A4F);
}
.partenaires-scope-tile.is-selected {
  border-color: var(--accent, #1F2A4F);
  background: var(--accent-soft, #DCE7FB);
}
.partenaires-scope-tile input[type="radio"] {
  /* F4 bonus 23/07 : neutralise `input, select, textarea { width:100%;
   * padding:10px 12px; border:...}` (style.css:664) qui rend les radios
   * en cercles géants ~70 px dans la modale. Miroir strict
   * `.launch-piece-row > input[type="radio"]` (style.css:4558-4564). */
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  padding: 0;
  border: none;
  margin: 2px 0 0 0;
  accent-color: var(--primary);
}
.partenaires-scope-tile-body {
  flex: 1;
}
.partenaires-scope-tile-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.partenaires-scope-tile-price {
  font-weight: 600;
  color: var(--accent, #1F2A4F);
}
.partenaires-intl-picker {
  margin-top: 12px;
  padding: 8px;
  background: rgba(0, 0, 0, 0.02);
  border-radius: 6px;
}
.partenaires-intl-picker select {
  margin-left: 6px;
}
.partenaires-modal-desc {
  margin: 0 0 12px 0;
}

/* ============================================================================
 * ⑤ 7c async (jalon 5, 27/07) — modale de progression.
 *
 * Rendue via `showModal` canonique (le body est injecté dans #modal-body).
 * Aucun sélecteur global touché (spec 0-0-1-0 max) — même patron gravé que
 * .partenaires-scope-*. La modale mesure une largeur naturelle contrainte
 * par la modale globale ; on gère surtout l'espacement vertical + la barre
 * de progression + la liste teaser.
 * ============================================================================ */
.partenaires-progress {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.partenaires-progress-step {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  font-size: 15px;
}
.partenaires-progress-step .step-label {
  font-weight: 600;
}
.partenaires-progress-counter {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.partenaires-progress-bar {
  width: 100%;
  height: 6px;
  background: rgba(0, 0, 0, 0.06);
  border-radius: 3px;
  overflow: hidden;
}
.partenaires-progress-fill {
  height: 100%;
  background: var(--accent, #2f5bea);
  transition: width 300ms ease-out;
}
.partenaires-progress-teaser {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 240px;
  overflow-y: auto;
}
.partenaires-progress-teaser-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.02);
}
.partenaires-progress-teaser-row .teaser-line-1 {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
}
.partenaires-progress-teaser-row .teaser-name {
  font-weight: 600;
}
.partenaires-progress-teaser-row .teaser-city {
  font-style: italic;
}
.partenaires-progress-teaser-row .teaser-line-2 a {
  color: var(--accent, #2f5bea);
  text-decoration: underline;
}
.partenaires-progress-note {
  margin: 0;
  padding-top: 4px;
  border-top: 1px dashed rgba(0, 0, 0, 0.1);
}

/* ============================================================================
 * Lot 1 refonte page marché — barre d'onglets + panneaux.
 * Spécificité 0-0-1-0 max ; aucun sélecteur global touché. Style volontairement
 * minimal — le raffinement visuel arrive dans les lots ultérieurs. Le seul
 * objectif au lot 1 est : (a) rendre les onglets distinguables, (b) masquer
 * les panneaux inactifs, (c) marquer visiblement l'onglet actif.
 * ============================================================================ */
.marche-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 16px 0;
  padding: 0;
  border-bottom: 1px solid var(--border, #d8dbe0);
}
.marche-tab-btn {
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  padding: 8px 14px;
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  color: var(--text, #23272f);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: -1px;
  transition: background 120ms ease, border-color 120ms ease;
}
.marche-tab-btn:hover {
  background: rgba(0, 0, 0, 0.04);
}
.marche-tab-btn.is-active {
  background: #fff;
  border-color: var(--border, #d8dbe0);
  font-weight: 600;
}
.marche-tab-num {
  opacity: 0.65;
  font-variant-numeric: tabular-nums;
}
/* Filet de sécurité : force display:none pour un panneau `[hidden]` même si
 * un descendant a un `display` explicite qui pourrait « fuir » (`.card` de
 * niveau supérieur est `display: block` par défaut, mais un futur reset
 * pourrait passer par une règle plus spécifique). */
.marche-tab-panel[hidden] {
  display: none !important;
}

/* =============================================================================
   Lot 2a — refonte du rendu DCE en page selon docs/maquette-page-marche-v10.html.
   Trois blocs :
     (a) `.dce-dossier-compteur` — la carte 8 « Les 24 pièces, toutes lues »
         devient un COMPTEUR compact (1 ligne, 4 chiffres). Remplace la liste
         verticale des 24 pièces (`.dce-dossier-composition` — CSS conservée
         pour rétrocompat, plus rendue par dce-render.js post-lot 2a).
     (b) `.dce-constraints-compact` — variante compacte de la grille contraintes.
         Un préfixe A/F/T posé en pseudo-élément ::before sur le libellé, plus
         de h3 par groupe (tout dans une seule grille dense).
     (c) `.dce-hero-actions .primary` — le bouton export garde son style
         primaire, aucune modification.
   ============================================================================= */

/* (a) Compteur des pièces analysées — remplace la liste 1 629 px par ~200 px. */
.dce-dossier-compteur h2 {
  font-size: 17px;
  margin: 0 0 12px;
}
.dce-dossier-compteur-line {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 20px;
  align-items: baseline;
  margin-bottom: 8px;
}
.dce-dossier-compteur-item {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-size: 15px;
  color: var(--text);
}
.dce-dossier-compteur-item[data-count]::first-line { font-weight: 700; }
.dce-dossier-compteur-item.dce-dossier-compteur-ok {
  color: var(--go);
  font-weight: 600;
}
.dce-dossier-compteur-item.dce-dossier-compteur-warn {
  color: var(--amber);
  font-weight: 600;
}
.dce-dossier-compteur-item.muted {
  color: var(--text-muted);
}
.dce-dossier-compteur .muted.small {
  font-size: 13px;
  color: var(--text-muted);
  margin: 6px 0 0;
}

/* Lot 2a — compaction globale des sections DCE quand rendues EN PAGE
   (conteneur `#dce-en-page`, cf. marche.js:renderAnalyseDceSection). La
   sélectivité 0-1-0 sur `#dce-en-page` cible strictement les sections rendues
   en page — le rendu historique via `#action-zone` (chemin openAnalysis
   depuis l'onglet mémoire) reste inchangé. */
#dce-en-page .card { margin: 12px 0; padding: 16px 18px; }
#dce-en-page .dce-section h2 { font-size: 17px; margin: 0 0 12px; }
#dce-en-page .dce-section h3 { font-size: 13px; margin: 8px 0 6px; }
#dce-en-page .dce-hero-h1 { font-size: 22px; margin: 6px 0; }
#dce-en-page .dce-synthese { margin: 8px 0 0; line-height: 1.55; font-size: 14px; }
#dce-en-page .dce-meta { margin: 4px 0 8px; font-size: 12px; }

/* Compaction des critères : grille 2 colonnes, pondération en tête, pas
   d'espacement entre items. */
#dce-en-page .dce-criteria-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 8px;
  padding: 0;
  margin: 0;
  list-style: none;
}
#dce-en-page .dce-criterion {
  background: var(--bg-page);
  border-radius: 6px;
  padding: 10px 12px;
}
#dce-en-page .dce-criterion-head { margin-bottom: 4px; }
#dce-en-page .dce-criterion-label { font-size: 14px; font-weight: 600; }
#dce-en-page .dce-criterion-weight { font-size: 13px; }
#dce-en-page .dce-bar { height: 6px; margin: 4px 0 2px; }
#dce-en-page .dce-subcriteria { font-size: 12.5px; margin: 4px 0 0; padding-left: 16px; }
#dce-en-page .dce-subcriteria li { line-height: 1.4; }
#dce-en-page .dce-criterion-ref { font-size: 12px; margin-top: 2px; }

/* Dates : grille 3 colonnes compacte. */
#dce-en-page .dce-dates {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 6px;
  padding: 0;
  margin: 0;
  list-style: none;
}
#dce-en-page .dce-date {
  background: var(--bg-page);
  border-radius: 6px;
  padding: 8px 10px;
  display: flex;
  gap: 8px;
  align-items: baseline;
  flex-wrap: wrap;
}
#dce-en-page .dce-date-when { font-size: 13px; font-weight: 600; }
#dce-en-page .dce-date-what { font-size: 12.5px; }

/* Clauses à risque : compact 2 colonnes, gravité en badge inline. */
#dce-en-page .dce-risks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 4px;
  padding: 0;
  margin: 0;
  list-style: none;
}
#dce-en-page .dce-risk {
  padding: 6px 8px;
}
#dce-en-page .dce-risk-label { font-size: 13px; }
#dce-en-page .dce-risk-reason { font-size: 12.5px; margin-top: 2px; line-height: 1.35; }
#dce-en-page .dce-badge-grav-faible,
#dce-en-page .dce-badge-grav-moyenne,
#dce-en-page .dce-badge-grav-elevee { font-size: 11px; padding: 1px 6px; }

/* Contraintes en page — encore plus dense qu'en variante générique compact. */
#dce-en-page .dce-constraints-compact {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 4px;
}
#dce-en-page .dce-constraints-compact .dce-constraint-group li {
  padding: 6px 8px 6px 26px;
}
#dce-en-page .dce-constraints-compact .dce-constraint-group li::before {
  left: 6px;
  top: 6px;
}
#dce-en-page .dce-constraints-compact .dce-constraint-label { font-size: 13px; }
#dce-en-page .dce-constraints-compact .dce-constraint-detail { font-size: 12px; line-height: 1.3; }

/* Manquants (« Ce que l'acheteur n'a pas écrit »). */
#dce-en-page .dce-missing-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}
#dce-en-page .dce-missing-list li {
  background: var(--bg-page);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 13px;
  line-height: 1.4;
}
#dce-en-page .dce-missing-head { margin-bottom: 10px; }
#dce-en-page .dce-missing-hint { display: none; }  /* hint « multi-fichiers » obsolète */

/* (b) Contraintes — variante compacte (grille dense 2/3 colonnes, préfixe A/F/T
   sur chaque item, plus de h3 par groupe). Utilisée quand dce-render.js pose
   la classe supplémentaire `.dce-constraints-compact`. La règle historique
   `.dce-constraints { display: grid; gap: 18px; }` reste en place — la variante
   override juste ce qui doit l'être. */
.dce-constraints-compact {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 10px;
}
.dce-constraints-compact .dce-constraint-group h3 { display: none; }
.dce-constraints-compact .dce-constraint-group ul {
  display: contents;  /* fusionne les groupes dans la grille parente */
}
.dce-constraints-compact .dce-constraint-group li {
  padding: 8px 10px 8px 30px;
  position: relative;
}
.dce-constraints-compact .dce-constraint-group li::before {
  content: '·';
  position: absolute;
  left: 10px;
  top: 8px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent-soft, #DCE7FB);
  color: var(--primary);
  text-align: center;
  line-height: 16px;
  font-weight: 700;
  font-size: 11px;
}
/* Préfixe par type : A (administratives), T (techniques), F (financières) */
.dce-constraints-compact .dce-constraint-group[data-type="administrative"] li::before { content: 'A'; }
.dce-constraints-compact .dce-constraint-group[data-type="technique"] li::before { content: 'T'; }
.dce-constraints-compact .dce-constraint-group[data-type="financiere"] li::before { content: 'F'; }
.dce-constraints-compact .dce-constraint-group[data-type="autre"] li::before { content: '·'; }
.dce-constraints-compact .dce-constraint-label { font-weight: 600; font-size: 14px; }
.dce-constraints-compact .dce-constraint-detail { font-size: 13px; margin-top: 1px; }

/* ============================================================================
 * Lot 2a-bis — Bloc de vente de l'onglet DCE (état « avant l'analyse »).
 *
 * Cardinales L2b-1/2/6 :
 *   - Visible UNIQUEMENT quand DCE déposé sans analyse `success` (contrôlé
 *     côté JS ; ici on ne masque rien par CSS — la cardinale L2b-1 discrimine
 *     par ABSENCE du bloc, pas par masquage).
 *   - Prix « — » remplacés au mount asynchrone par PricingCatalog. Aucune
 *     valeur numérique en dur dans le CSS.
 * ========================================================================= */
.dce-sales-block {
  padding: 28px 32px;
  background: linear-gradient(180deg, rgba(79,78,145,0.06) 0%, rgba(79,78,145,0.02) 100%);
  border: 1px solid rgba(79,78,145,0.14);
  margin-bottom: 18px;
}
.dce-sales-hero-context {
  margin: 0 0 12px;
  font-size: 12px;
  color: var(--ink2);
  letter-spacing: 0.02em;
}
.dce-sales-hero-title {
  margin: 0 0 12px;
  font-size: 26px;
  line-height: 1.24;
  font-weight: 700;
  color: var(--ink);
}
.dce-sales-hero-lead {
  margin: 0 0 18px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink2);
  max-width: 62ch;
}
.dce-sales-hero-cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.dce-sales-hero-cta .btn { padding: 10px 16px; font-size: 14.5px; }
.dce-sales-cta-price {
  margin-left: 6px;
  font-weight: 600;
  opacity: 0.92;
}
.dce-sales-hero-trust {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  padding: 0;
  margin: 0;
  list-style: none;
  font-size: 13px;
  color: var(--ink2);
}
.dce-sales-hero-trust li {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}

/* Cartes intra-bloc de vente : Go/No-Go pré-diagnostic + « ce que l'analyse
   extrait ». Structure de card légère, cohérente avec .dce-sales-block. */
.dce-sales-gonogo, .dce-sales-extract { padding: 20px 24px; margin-bottom: 14px; }
.dce-sales-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}
.dce-sales-card-head h3 { margin: 0; font-size: 17px; font-weight: 600; }
.dce-sales-card-head-right { color: var(--ink2); }
.dce-sales-gonogo-lead { margin: 0 0 14px; color: var(--ink2); line-height: 1.55; max-width: 62ch; }
.dce-sales-gonogo-actions {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.dce-sales-extract-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}
.dce-sales-extract-list li {
  display: flex;
  gap: 12px;
  padding: 10px 12px;
  background: var(--bg-page);
  border-radius: 8px;
  line-height: 1.45;
}
.dce-sales-extract-idx {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-weight: 700;
  font-size: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.dce-sales-extract-t { font-weight: 600; font-size: 14px; }
.dce-sales-extract-d { font-size: 13px; color: var(--ink2); margin-top: 3px; }

/* Lot 2a-ter — zone échantillon D-NUM. Fond vert clair (positif «offert»),
   bordure verte, labelet capitalisé. Cf. .sample de la maquette v10 (lignes
   396-398) — palette vert positif adaptée aux vars TPIA. Deux cas d'affichage
   par construction : 0 finding → slot [hidden] (rien à rendre) ; 1 finding
   → contenu rendu. Le cas ≥ 2 findings est INATTEIGNABLE (D-NUM seul livré,
   arbitrage E5). Marge sup 11 px cohérente avec la maquette (§396). */
.dce-sales-sample {
  border: 1px solid #7dd3a5;
  background: linear-gradient(160deg, #f2fbf7, #e9f7f1);
  border-radius: 8px;
  padding: 14px 16px;
  margin-top: 11px;
}
.dce-sales-sample-label {
  font-size: 10px;
  letter-spacing: .09em;
  text-transform: uppercase;
  font-weight: 780;
  color: #276749;
  margin-bottom: 7px;
}
.dce-sales-sample-finding {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text, #1a1a1a);
}
.dce-sales-sample-note {
  margin: 8px 0 0;
  font-size: 11px;
  line-height: 1.5;
  color: var(--ink2);
}

/* =========================================================================
 * Lot 7 J1 — bloc de vente onglet Acheteur (« avant l'analyse »).
 * Miroir architectural du .dce-sales-* du 2a-bis : hero + card what
 * (tuiles + histogramme + insight) + card extract (5 points + slot).
 * L7J1-1 : visible ssi acheteur résolu ET aucune analyse acheteur
 * (contrôlé côté JS, pas par CSS).
 * L7J1-2 : les prix (« 8 crédits ») rendus par mountAcheteurSalesBlock
 * depuis PricingCatalog.creditCost('redaction'). Aucun littéral CSS.
 * ========================================================================= */
.acheteur-sales-block {
  padding: 28px 32px;
  background: linear-gradient(180deg, rgba(79,78,145,0.06) 0%, rgba(79,78,145,0.02) 100%);
  border: 1px solid rgba(79,78,145,0.14);
  margin-bottom: 18px;
}
.acheteur-sales-hero-context {
  margin: 0 0 12px;
  font-size: 12px;
  color: var(--ink2);
  letter-spacing: 0.02em;
}
.acheteur-sales-hero-title {
  margin: 0 0 12px;
  font-size: 26px;
  line-height: 1.24;
  font-weight: 700;
  color: var(--ink);
}
.acheteur-sales-hero-lead {
  margin: 0 0 18px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink2);
  max-width: 62ch;
}
.acheteur-sales-hero-cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.acheteur-sales-hero-cta .btn { padding: 10px 16px; font-size: 14.5px; }
.acheteur-sales-cta-price {
  margin-left: 6px;
  font-weight: 600;
  opacity: 0.92;
}
.acheteur-sales-hero-trust {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  padding: 0;
  margin: 0 0 14px;
  list-style: none;
  font-size: 13px;
  color: var(--ink2);
}
.acheteur-sales-hero-trust li {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.acheteur-sales-hero-incl {
  margin: 0;
  padding: 12px 14px;
  background: rgba(79,78,145,0.06);
  border-left: 3px solid rgba(79,78,145,0.35);
  border-radius: 4px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink);
}

/* A2 — Cartes « ce que vous avez déjà » + A3 « ce que l'analyse ajoute ».
   Miroir strict de .dce-sales-what / .dce-sales-extract. */
.acheteur-sales-what, .acheteur-sales-extract { padding: 20px 24px; margin-bottom: 14px; }
.acheteur-sales-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}
.acheteur-sales-card-head h3 { margin: 0; font-size: 17px; font-weight: 600; }
.acheteur-sales-card-head h4 { margin: 0; font-size: 14.5px; font-weight: 600; color: var(--ink2); }
.acheteur-sales-card-head-right { color: var(--ink2); }

/* Tuiles A2 — 4 preuves gratuites (avis, attributions, holders, montants).
   Grid 4 cols responsive : 4 → 2 → 1 selon la largeur du panel. */
.acheteur-sales-proof-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 20px;
}
@media (max-width: 900px) {
  .acheteur-sales-proof-list { grid-template-columns: repeat(2, 1fr); }
}
.acheteur-sales-proof-cell {
  border: 1px solid rgba(79,78,145,0.12);
  border-radius: 8px;
  padding: 12px 14px;
  background: linear-gradient(160deg, #fbfbfe, #f5f5fb);
}
.acheteur-sales-proof-v {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--primary, #4b45cf);
}
.acheteur-sales-proof-k {
  font-size: 12px;
  color: var(--ink2);
  margin-top: 4px;
  line-height: 1.35;
}

/* Histogramme rythme par année — flex 8 cols, hauteur fixe 104 px
   (patron maquette .hist §382). Une colonne « zero » = motif hachuré. */
.acheteur-sales-hist-wrap { margin-top: 18px; padding-top: 12px; border-top: 1px solid var(--line, #eaeaee); }
.acheteur-sales-hist {
  display: flex;
  gap: 6px;
  align-items: flex-end;
  height: 104px;
  margin-top: 6px;
}
.acheteur-sales-hcol {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 5px;
  height: 100%;
}
.acheteur-sales-hcol-bx {
  width: 100%;
  border-radius: 4px 4px 0 0;
  background: linear-gradient(180deg, var(--primary, #4b45cf), #6c66d9);
  min-height: 2px;
}
.acheteur-sales-hcol-zero .acheteur-sales-hcol-bx {
  background: repeating-linear-gradient(45deg, #e6e9ef, #e6e9ef 3px, #f4f5f8 3px, #f4f5f8 6px);
  border: 1px dashed rgba(0,0,0,0.12);
  border-bottom: 0;
}
.acheteur-sales-hcol-yr {
  font-size: 10.5px;
  color: var(--ink3, #8b8b95);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.acheteur-sales-hcol-vl {
  font-size: 11px;
  font-weight: 700;
  color: var(--ink2);
  font-variant-numeric: tabular-nums;
}
.acheteur-sales-hcol-zero .acheteur-sales-hcol-vl { color: #d97706; }
.acheteur-sales-insight { margin: 10px 0 0; }

/* A3 — liste 5 points, miroir strict de .dce-sales-extract-list. */
.acheteur-sales-extract-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}
.acheteur-sales-extract-list li {
  display: flex;
  gap: 12px;
  padding: 10px 12px;
  background: var(--bg-page);
  border-radius: 8px;
  line-height: 1.45;
}
.acheteur-sales-extract-idx {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-weight: 700;
  font-size: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.acheteur-sales-extract-t { font-weight: 600; font-size: 14px; }
.acheteur-sales-extract-d { font-size: 13px; color: var(--ink2); margin-top: 3px; }

/* Slot échantillon acheteur — hidden pour J1, J2 le peuplera. */
.acheteur-sales-sample-slot { display: block; margin-top: 11px; }
.acheteur-sales-sample-slot[hidden] { display: none; }

/* Compaction fiche-documents dès qu'un DCE est déposé — le bloc de vente
   (état « avant ») ET le rendu #dce-en-page (état « après ») portent déjà
   la mise en scène du dossier (« N pièces », « pièces lues »). Masquer la
   liste des fichiers déposés évite la redondance ET libère de la hauteur.
   Les dropzones restent visibles (L2b-3). Le clic sur le head replie
   `.collapsible-body` (comportement standard collapsible) MAIS ne montre
   PAS la liste — la classe .fiche-documents-dce-compact vit hors du
   collapsible. Le seul chemin client pour retrouver la liste est le
   bouton .doc-list-reveal (passe 2 fix 1 — la liste ne devient jamais
   inatteignable). */
.fiche-documents-dce-compact .doc-list-wrap { display: none; }
.doc-list-reveal-wrap { margin: 6px 0 12px; }
.fiche-documents-dce-compact .doc-list-reveal-wrap { display: block; }
.fiche-documents-dce-compact.fiche-documents-dce-revealed .doc-list-reveal-wrap { display: none; }
.fiche-documents-dce-compact.fiche-documents-dce-revealed .doc-list-wrap { display: block; }

/* Passe 2 (2) — carte « Ce que vous avez déjà, sans rien payer ».
   Compression maximale pour tenir sous 148 px sur 9729 : header réduit
   à 24 px, grille 3-4 colonnes, item une ligne à 20 px, note sur une
   ligne à 16 px. Total viseur ≈ 24 + 40 (2 lignes de 3 cols) + 16 = 80.
   L'avertissement reste distingué (fond teinté + text label). */
.dce-sales-what { padding: 8px 20px 10px; margin-bottom: 8px; }
.dce-sales-what .dce-sales-card-head { margin-bottom: 4px; }
.dce-sales-what .dce-sales-card-head h3 { font-size: 14px; }
.dce-sales-what-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 1px 10px;
}
.dce-sales-what-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 1px 4px;
  border-radius: 3px;
  line-height: 1.3;
  font-size: 11.5px;
  overflow: hidden;
}
.dce-sales-what-item-warn {
  background: rgba(215,120,80,0.09);
  border-left: 2px solid rgba(215,120,80,0.6);
  padding-left: 6px;
}
.dce-sales-what-kind {
  flex-shrink: 0;
  min-width: 38px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--primary);
  text-transform: uppercase;
}
.dce-sales-what-body { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 6px; }
.dce-sales-what-name {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}
.dce-sales-what-meta { font-size: 10.5px; color: var(--ink2); white-space: nowrap; }
.dce-sales-what-warn-text {
  color: rgba(140,60,20,0.9);
  font-weight: 500;
}
/* .dce-sales-what-note supprimée en passe 3 — la note répétait le sous-titre. */

/* ============================================================================
 * Lot 2b — Bloc de vente de l'onglet mémoire (mise en scène p5).
 *
 * Cardinales L2c-1..L2c-6. Layout bento léger (grille 2 col pour hero, span 12
 * pour les cartes). AUCUNE valeur numérique de prix ou de pourcentage en dur.
 * ========================================================================= */

/* Racines d'état — permettent au smoke de discriminer par data-mem-state. */
.mem-p5-locked, .mem-p5-ready, .mem-p5-done {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 14px;
}

/* Hero commun (verrouillé et prêt) */
.mem-hero {
  background: linear-gradient(180deg, rgba(79,78,145,0.06) 0%, rgba(79,78,145,0.02) 100%);
  border: 1px solid rgba(79,78,145,0.14);
  border-radius: 10px;
  padding: 22px 26px;
}
.mem-hero-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 24px;
  align-items: start;
}
.mem-hero-eb {
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--ink2);
  margin-bottom: 8px;
  text-transform: uppercase;
}
.mem-hero-title {
  margin: 0 0 12px;
  font-size: 22px;
  line-height: 1.28;
  font-weight: 700;
  color: var(--ink);
}
.mem-hero-lead {
  margin: 0 0 14px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink2);
  max-width: 62ch;
}
.mem-hero-incl {
  padding: 10px 12px;
  background: rgba(79,78,145,0.05);
  border-left: 3px solid var(--primary);
  border-radius: 4px;
  font-size: 13.5px;
  margin-bottom: 14px;
}
.mem-hero-incl b { display: block; margin-bottom: 2px; }
.mem-hero-cta { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.mem-hero-trust {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  padding: 0;
  margin: 0;
  list-style: none;
  font-size: 13px;
  color: var(--ink2);
}
.mem-hero-trust li { display: inline-flex; align-items: baseline; gap: 6px; }
.mem-hero-honeste { margin-top: 12px; font-size: 13px; color: var(--ink); }
.mem-hero-missing {
  background: rgba(255,255,255,0.6);
  border-radius: 8px;
  padding: 14px 16px;
}
.mem-hero-missing-title {
  font-weight: 600;
  margin-bottom: 10px;
  font-size: 14px;
}
.mem-missing-list, .mem-hero-obtain-list {
  padding: 0;
  margin: 0;
  list-style: none;
}
.mem-missing-item, .mem-hero-obtain-list li {
  padding: 6px 0;
  font-size: 13.5px;
  line-height: 1.4;
  border-bottom: 1px solid rgba(0,0,0,0.05);
}
.mem-missing-list li:last-child, .mem-hero-obtain-list li:last-child { border-bottom: 0; }
.mem-missing-link { color: var(--ink); text-decoration: none; }
.mem-missing-link:hover { text-decoration: underline; }
.mem-missing-warn {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10.5px;
  border-radius: 3px;
  background: rgba(215,120,80,0.15);
  color: rgba(140,60,20,0.9);
  font-weight: 500;
}
.mem-hero-obtain { padding: 14px 16px; background: rgba(255,255,255,0.6); border-radius: 8px; }
.mem-hero-obtain-title { font-weight: 600; margin-bottom: 8px; font-size: 14px; }

/* Cartes p5 (span 12 dans le bento) */
.mem-card {
  background: #ffffff;
  border: 1px solid var(--trait, rgba(0,0,0,0.08));
  border-radius: 8px;
  padding: 18px 22px;
}
.mem-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}
.mem-card-head h3 { margin: 0; font-size: 16px; font-weight: 600; }

/* wsplit */
.mem-wsplit {
  display: flex;
  height: 24px;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 12px;
}
.mem-wsplit i {
  font-style: normal;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  min-width: 20px;
}
.mem-wsplit-mem { background: linear-gradient(135deg, #4f4e91, #7a6dc4); }
.mem-wsplit-hors { background: linear-gradient(135deg, #8b939e, #6c757f); }

/* Sections list */
.mem-section-list {
  padding: 0;
  margin: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 6px;
}
.mem-section-item {
  display: flex;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 4px;
  font-size: 12.5px;
  line-height: 1.35;
}
.mem-section-ordre {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: rgba(0,0,0,0.06);
  color: var(--ink2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 10.5px;
}
.mem-section-targeted .mem-section-ordre {
  background: var(--primary);
  color: #fff;
}
.mem-section-done .mem-section-ordre {
  background: rgba(60,150,90,0.85);
  color: #fff;
}
.mem-section-title { font-weight: 500; }
.mem-section-meta { font-size: 11px; margin-top: 1px; }

/* Verrou pourquoi juste */
.mem-lock-why-body { line-height: 1.55; margin: 0; font-size: 13.5px; color: var(--ink2); }

/* Ready hero honnêteté — les missing dedans redéviennent chip-like */
.mem-hero-honeste .mem-missing-list { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.mem-hero-honeste .mem-missing-item { border: 0; padding: 0; display: inline; }
.mem-hero-honeste .mem-missing-link {
  display: inline-block;
  padding: 2px 8px;
  background: rgba(79,78,145,0.08);
  border-radius: 3px;
  text-decoration: none;
  font-size: 12.5px;
}

/* Révélateur de table */
.mem-scoring-reveal-wrap { margin-top: 8px; }
.mem-scoring-compact .mem-scoring-table-slot { display: none; }
.mem-scoring-compact.mem-scoring-revealed .mem-scoring-table-slot { display: block; }
.mem-scoring-compact.mem-scoring-revealed .mem-scoring-reveal-wrap { display: none; }

/* .syn / .freeze / .next — état rédigé */
.mem-syn {
  background: linear-gradient(135deg, #4f4e91 0%, #6a5fb0 100%);
  color: #ffffff;
  border-radius: 10px;
  padding: 22px 26px;
}
.mem-syn-eb {
  font-size: 12px;
  letter-spacing: 0.02em;
  opacity: 0.85;
  margin-bottom: 8px;
  text-transform: uppercase;
}
.mem-syn-title { margin: 0 0 14px; font-size: 22px; font-weight: 700; line-height: 1.25; }
.mem-freeze-phrase {
  display: flex;
  gap: 12px;
  align-items: start;
  background: var(--bg-page);
  padding: 12px 14px;
  border-radius: 6px;
}
.mem-freeze-ic {
  flex-shrink: 0;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px;
}

/* =============================================================================
   LOT 4 — Tableau de bord (onglet 1, panneau p1). Sept cartes du LOT +
   bloc EE en bas (arbitrage P7). Grille 12 col conservée (spans maquette,
   colonnes géo/issue restent vides pour lots 6/5, arbitrage §2).
   ============================================================================= */

.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 14px;
}

.db-carte {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 16px 18px;
  min-width: 0;
}

.db-carte-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.db-carte-head h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 640;
  color: var(--ink);
}
.db-carte-head-right {
  color: var(--ink3);
  font-size: 12.5px;
}

/* Spans maquette conservés (arbitrage §2 + lot 6 T6 D18.1 : carte géo span 4).
   La carte géo (lot 6) prend sa colonne réservée à côté de l'échéance. Le
   `avancement span 8` bascule en ligne 2 (autoflow grid), la disposition
   totale reste cohérente : lignes 1/2/3/4 = 4+4+4 / 8+4 / 12 / 5+7 etc. */
.db-carte-echeance          { grid-column: span 4; }
.db-carte-geo               { grid-column: span 4; }
.db-carte-avancement        { grid-column: span 8; }
.db-carte-prochaine-etape   { grid-column: span 8; }
.db-carte-pieces            { grid-column: span 12; }
.db-carte-equipe            { grid-column: span 5; }
.db-carte-issue             { grid-column: span 7; }
.db-carte-chronologie       { grid-column: span 12; }
.db-carte-concurrence       { grid-column: span 12; }
/* Lot 7 J3 — carte de démarrage CD-2 (SOMMET, span 12). Rendue ssi le
   marché n'a AUCUNE analyse `success`. Anatomie de la maquette v10
   L686-713 (bloc `.kick`), préfixée `.db-` pour namespacing propre.
   Fond gradient indigo/violet + col droite « Ce que vous obtenez » +
   `.db-kres-lock` avec la phrase de dépendance (arbitrage §3). */
.db-carte-demarrage         { grid-column: span 12; }

/* ── Carte de démarrage (lot 7 J3) ─────────────────────────────────── */
.db-carte-demarrage {
  background: linear-gradient(135deg, var(--primary) 0%, #6b57a3 55%, var(--primary-strong) 100%);
  color: #fff;
  border: 0;
  padding: 24px 26px;
  position: relative;
  overflow: hidden;
  border-radius: 8px;
  box-shadow: 0 10px 34px -14px rgba(43, 38, 96, 0.65);
}
.db-carte-demarrage::after {
  content: '';
  position: absolute;
  right: -90px;
  top: -90px;
  width: 340px;
  height: 340px;
  border-radius: 999px;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.13), transparent 70%);
  pointer-events: none;
}
.db-kick-grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 30px;
  position: relative;
  z-index: 1;
}
.db-kick-col-left { min-width: 0; }
.db-kick-col-right { min-width: 0; }
.db-kick-eb {
  font-size: 10px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  font-weight: 750;
  color: #c3c0f5;
  margin: 0;
}
.db-kick-h2 {
  font-size: 26px;
  margin: 8px 0 0;
  letter-spacing: -0.03em;
  line-height: 1.2;
  font-weight: 730;
  color: #fff;
}
.db-kick-lead {
  font-size: 13.5px;
  line-height: 1.6;
  color: #dedcfa;
  margin: 11px 0 0;
  max-width: 46ch;
}
.db-kick-acts {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-top: 20px;
  flex-wrap: wrap;
}
.db-kbtn {
  border: 0;
  border-radius: 9px;
  padding: 12px 20px;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  letter-spacing: -0.01em;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.db-kbtn-primary {
  background: linear-gradient(135deg, var(--amber), #d97706);
  color: #fff;
  box-shadow: 0 4px 16px -4px rgba(217, 119, 6, 0.7);
}
.db-kbtn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 7px 22px -5px rgba(217, 119, 6, 0.8);
}
.db-kbtn-ghost {
  background: rgba(255, 255, 255, 0.11);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: none;
  font-weight: 600;
}
.db-kbtn-ghost:hover {
  background: rgba(255, 255, 255, 0.19);
}
.db-kbtn-price { opacity: 0.9; }
.db-kfoot {
  font-size: 12px;
  color: #b9b5ef;
  margin-top: 14px;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: center;
}
.db-kfoot b { color: #fff; }
.db-kfoot-item { display: inline-flex; gap: 4px; align-items: baseline; }
.db-kres {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.17);
  border-radius: 6px;
  padding: 16px 18px;
}
.db-kres-t {
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 750;
  color: #c3c0f5;
  margin-bottom: 11px;
}
.db-kres-ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.db-kres-li {
  display: flex;
  gap: 10px;
  padding: 7px 0;
  font-size: 13px;
  line-height: 1.5;
  color: #f0eefc;
  align-items: flex-start;
}
.db-kres-li div { min-width: 0; }
.db-kres-marker {
  color: #8ce0bd;
  font-weight: 800;
  flex-shrink: 0;
  margin-top: 1px;
}
.db-kres-lock {
  margin-top: 11px;
  padding-top: 11px;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  font-size: 12px;
  color: #b9b5ef;
  line-height: 1.5;
}
/* Repli mobile — la col droite passe sous la col gauche, garde d'anatomie
   préservée (tous les sous-éléments existent), fourchette non applicable
   à cette largeur (arbitrage §6 : fourchette mesurée à 1440×900). */
@media (max-width: 900px) {
  .db-kick-grid { grid-template-columns: 1fr; gap: 20px; }
  .db-kick-lead { max-width: none; }
}

/* ── Carte géo (lot 6 T6) ────────────────────────────────────────────── */
.db-carte-geo .db-geo-mapbox {
  width: 100%;
  aspect-ratio: 613 / 585;
  background: #fafbfc;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 12px;
}
.db-carte-geo .db-geo-svg {
  width: 100%;
  height: 100%;
  display: block;
}
/* B1 (verdict passe 1) — fond de carte lisible. Les paths du SVG upstream
   n'ont aucun fill par défaut → aplat noir. On stylise en aplat clair aux
   valeurs maquette (fond neutre, contour fin, non-scaling pour rester lisible
   à toutes les échelles de zoom). Le module marche-fond-france.js inline
   les paths dans le placeholder .fond-france pour que ce CSS s'applique. */
.db-carte-geo .db-geo-svg .fond-france path {
  fill: #eceff3;
  stroke: #c9ced7;
  stroke-width: 1.4;
  vector-effect: non-scaling-stroke;
}
.db-carte-geo .db-geo-meta {
  margin-bottom: 10px;
}
.db-carte-geo .db-geo-meta-empty {
  padding: 20px 8px;
  text-align: center;
  color: var(--ink3);
  font-size: 13px;
}
.db-carte-geo .db-geo-meta-cta {
  padding: 12px 0;
  border-top: 1px dashed var(--line);
}
.db-carte-geo .db-geo-cta {
  display: inline-block;
  margin-top: 6px;
  font-size: 12.5px;
  color: var(--acc, #4f4e91);
  text-decoration: none;
  border-bottom: 1px dashed currentColor;
}
.db-carte-geo .db-geo-cta:hover { text-decoration: none; border-bottom-style: solid; }
.db-carte-geo .db-geo-kfig {
  font-size: 32px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1;
}
.db-carte-geo .db-geo-kfig small {
  font-size: 15px;
  font-weight: 500;
  color: var(--ink3);
  margin-left: 2px;
}
.db-carte-geo .db-geo-note {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink3);
}
.db-carte-geo .db-geo-offmap {
  margin-top: 8px;
  padding: 8px 10px;
  background: #fef7ed;
  border-left: 3px solid #d97706;
  border-radius: 3px;
  font-size: 12.5px;
  color: var(--ink);
  line-height: 1.45;
}
.db-carte-geo .db-geo-legende {
  margin-top: 10px;
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--ink);
}
.db-carte-geo .db-geo-legende-pt {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 99px;
  margin-right: 7px;
  vertical-align: middle;
}
.db-carte-geo .db-geo-legende-pt-marche {
  background: var(--acc, #4f4e91);
}
.db-carte-geo .db-geo-legende-pt-entreprise {
  background: #fff;
  border: 2px solid var(--acc, #4f4e91);
}
.db-carte-geo .db-geo-trajets {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.db-carte-geo .db-geo-trajets-off {
  padding: 8px 0;
  color: var(--ink3);
  font-style: italic;
}
.db-carte-geo .db-geo-trajet {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 4px 0;
  font-size: 13px;
}
.db-carte-geo .db-geo-trajet-mode { color: var(--ink); }
.db-carte-geo .db-geo-trajet-cout {
  font-weight: 640;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.db-carte-geo .db-geo-hypotheses {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
}
.db-carte-geo .db-geo-hypotheses summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--ink);
  outline: none;
}
.db-carte-geo .db-geo-hypotheses summary:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
.db-carte-geo .db-geo-hypotheses-flag {
  margin-top: 8px;
}
.db-carte-geo .db-geo-hypotheses-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 12px;
  margin-top: 10px;
}
.db-carte-geo .db-geo-hypotheses-grid label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 12px;
  color: var(--ink3);
}
.db-carte-geo .db-geo-hypotheses-grid input {
  padding: 5px 8px;
  font-size: 13px;
  border: 1px solid var(--line);
  border-radius: 3px;
  font-variant-numeric: tabular-nums;
}
.db-carte-geo .db-geo-hypotheses-note {
  margin-top: 10px;
  line-height: 1.55;
}
.db-carte-geo .db-geo-hypotheses-actions {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.db-carte-geo .db-geo-bareme-save {
  padding: 6px 12px;
  font-size: 12.5px;
  background: var(--acc, #4f4e91);
  color: #fff;
  border: none;
  border-radius: 3px;
  cursor: pointer;
}
.db-carte-geo .db-geo-bareme-save:hover { opacity: 0.9; }
.db-carte-geo .db-geo-bareme-save:disabled { opacity: 0.5; cursor: wait; }
.db-carte-geo .db-geo-empty-country {
  padding: 40px 12px;
  text-align: center;
  background: #fafbfc;
  border-radius: 4px;
  color: var(--ink3);
}
.db-carte-geo .db-geo-empty-country-msg {
  font-size: 14px;
  color: var(--ink);
  margin-bottom: 12px;
}

/* ── Échéance ────────────────────────────────────────────────────────── */
.db-echeance-body { display: flex; flex-direction: column; gap: 12px; }
.db-echeance-etat {
  font-size: 15px;
  font-weight: 640;
  color: var(--ink);
}
.db-echeance-etat[data-etat="close"] { color: var(--ink2); }
.db-echeance-verdict {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.db-echeance-verdict-score {
  font-size: 20px; font-weight: 700; color: var(--ink);
}
.db-echeance-verdict-score-unit {
  font-size: 12px; font-weight: 500; color: var(--ink3);
}
.db-echeance-verdict-rationale {
  flex-basis: 100%;
  margin: 4px 0 0;
  line-height: 1.45;
}

/* ── Avancement ──────────────────────────────────────────────────────── */
.db-avancement-pct {
  display: flex; align-items: baseline; gap: 2px;
  font-size: 32px; font-weight: 700; color: var(--ink);
}
.db-avancement-pct-unit {
  font-size: 16px; font-weight: 500; color: var(--ink3);
}
.db-avancement-bar {
  height: 9px; background: var(--line); border-radius: 99px;
  overflow: hidden; margin: 10px 0 8px;
}
.db-avancement-bar-fill {
  height: 100%; background: var(--acc); border-radius: 99px;
  transition: width .3s ease;
}
.db-avancement-weights {
  margin-bottom: 12px;
}
.db-avancement-steps {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
}
.db-step {
  display: flex; flex-direction: column;
  padding: 10px; border-radius: 6px;
  background: #f6f7f9;
  min-width: 0;
}
.db-step-label {
  font-size: 12.5px; font-weight: 640; color: var(--ink);
  margin-bottom: 3px;
}
.db-step-meta {
  font-size: 11.5px; line-height: 1.3;
}
.db-step-weight {
  margin-top: 8px;
  display: flex; align-items: baseline; gap: 4px;
}
.db-step-weight-num {
  font-size: 15px; font-weight: 700; color: var(--ink);
}
.db-step-done {
  background: #e8f2eb;
}
.db-step-done .db-step-weight-num { color: #2e7d5e; }

/* ── Prochaine étape ─────────────────────────────────────────────────── */
.db-prochaine-body { display: flex; flex-direction: column; gap: 10px; }
.db-prochaine-nxt {
  margin: 0; font-size: 15.5px; font-weight: 640; color: var(--ink);
}
.db-prochaine-desc { margin: 0; line-height: 1.5; }
.db-prochaine-cta { display: flex; align-items: center; gap: 10px; margin-top: 8px; }

/* ── Résumé pièces ───────────────────────────────────────────────────── */
.db-pieces-counter { font-size: 13.5px; }
.db-pieces-counter strong {
  font-size: 17px; font-weight: 700; color: var(--ink);
}
.db-pieces-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px 24px;
}
.db-pieces-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.db-pieces-row-done .db-pieces-row-label {
  color: var(--ink3);
  text-decoration: line-through;
}
.db-pieces-row-label { color: var(--ink); flex: 1; min-width: 0; }
.db-pieces-row-src {
  font-size: 11.5px; padding: 1px 6px; border-radius: 4px;
  background: #f0f2f5; color: var(--ink2);
}
.db-pieces-more { margin-top: 12px; }

/* ── Équipe ──────────────────────────────────────────────────────────── */
.db-equipe-body { display: flex; flex-direction: column; gap: 12px; }
.db-equipe-list { display: flex; flex-direction: column; gap: 6px; }
.db-equipe-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 0;
}
.db-equipe-avatar {
  width: 28px; height: 28px; border-radius: 50%;
  color: #fff; font-size: 10.5px; font-weight: 650;
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
}
.db-equipe-row-info { min-width: 0; flex: 1; }
.db-equipe-row-name { font-size: 13px; font-weight: 620; color: var(--ink); }
.db-equipe-row-remove {
  background: transparent; border: none; color: var(--ink3);
  font-size: 15px; cursor: pointer; padding: 4px 6px;
  border-radius: 4px;
}
.db-equipe-row-remove:hover { background: #f0f2f5; color: var(--ink); }
.db-equipe-row-remove-self { color: #2e7d5e; }

/* Lot 5c — Invitations externes dans la carte équipe */
.db-equipe-add { display: flex; gap: 8px; flex-wrap: wrap; }
.db-equipe-invite-btn { border-style: dashed; }
.db-equipe-invitations {
  display: flex; flex-direction: column; gap: 8px;
  padding-top: 8px; border-top: 1px dashed #dcdcd0;
}
.db-equipe-invitations[data-empty="1"] {
  padding-top: 0; border-top: none;
}
.db-equipe-invitations-title { font-weight: 640; }
.db-equipe-invitations-list { display: flex; flex-direction: column; gap: 4px; }
.db-equipe-invitation-row {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 0;
}
.invite-row-info { flex: 1; min-width: 0; }
.invite-row-email {
  font-size: 12.5px; font-weight: 620; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.invite-row-meta { margin-top: 2px; }
.invite-status {
  font-size: 11px; font-weight: 620;
  padding: 1px 6px; border-radius: 3px;
  color: #565448; background: #eeece0;
}
.invite-status-actif { color: #2e7d5e; background: #e4f1eb; }
.invite-status-accepte { color: #2e7d5e; background: #e4f1eb; }
.invite-status-expire { color: #886244; background: #f4ead9; }
.invite-status-revoke { color: #8e3f3f; background: #f2dfde; }
.invite-memoire-toggle {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; cursor: pointer;
}
.invite-memoire-toggle input { margin: 0; }
.invite-revoke-btn { color: #8e3f3f; }
.invite-revoke-btn:hover { background: #f7e8e6; }
.db-equipe-effectif {
  padding-top: 6px; border-top: 1px dashed #dcdcd0;
  font-style: italic;
}
.db-equipe-invitation-row[data-status="expire"] .invite-row-email,
.db-equipe-invitation-row[data-status="revoke"] .invite-row-email {
  color: #8a8676; text-decoration: line-through;
}
/* Modale invitation — bloc "lien à copier" */
.invite-link-row {
  display: flex; gap: 8px; align-items: stretch;
  margin: 12px 0;
}
.invite-link-row input {
  flex: 1; font-family: ui-monospace, monospace; font-size: 11.5px;
}
.invite-link-row .is-copied { background: #2e7d5e; border-color: #2e7d5e; color: #fff; }
.modal-checkbox {
  display: flex; align-items: center; gap: 8px;
  margin: 12px 0 4px;
}
.modal-checkbox input { margin: 0; }
.modal-hint { margin: 4px 0 12px; }
.modal-error {
  padding: 8px 12px; margin-top: 12px;
  background: #f7e8e6; color: #8e3f3f;
  border-radius: 4px; font-size: 12.5px;
}
.modal-error.hide { display: none; }
.xs { font-size: 11.5px; }

/* ── Chronologie ─────────────────────────────────────────────────────── */
.db-chronologie-body { display: flex; flex-direction: column; gap: 12px; }
.db-frise {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
}
.db-frise-point {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 10px; border-radius: 6px;
  background: #f6f7f9;
}
.db-frise-point-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--acc); margin-top: 3px; flex: 0 0 auto;
}
.db-frise-point-ok .db-frise-point-dot { background: #2e7d5e; }
.db-frise-point-now .db-frise-point-dot { background: #d67; }
.db-frise-point-pending .db-frise-point-dot { background: #b0b4bd; }
.db-frise-point-body { flex: 1; min-width: 0; }
.db-frise-point-label { font-size: 12.5px; font-weight: 620; color: var(--ink); }
.db-frise-point-date { margin-top: 2px; }
.db-frise-point-actions { margin-top: 6px; display: flex; gap: 8px; }
.db-chronologie-add { display: flex; justify-content: flex-end; }

/* ── Concurrence ─────────────────────────────────────────────────────── */
.db-concurrence-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 10px;
}
.db-concurrence-row {
  display: flex; align-items: center; gap: 14px;
}
.db-concurrence-row-body { flex: 1; min-width: 0; }
.db-concurrence-row-name {
  font-size: 13px; font-weight: 620; color: var(--ink);
  margin-bottom: 4px;
}
.db-concurrence-row-bar {
  height: 6px; background: var(--line); border-radius: 99px; overflow: hidden;
}
.db-concurrence-row-bar-fill {
  height: 100%; background: var(--acc); border-radius: 99px;
}
.db-concurrence-row-amount {
  font-size: 14px; font-weight: 640; color: var(--ink);
  min-width: 100px; text-align: right;
}

/* ── Bloc EE en bas — P7 état de repli INCHANGÉ ──────────────────────── */
.db-ee-wrap { margin-top: 18px; }

/* ── États d'erreur locaux ───────────────────────────────────────────── */
.db-pieces-error, .db-equipe-error, .db-chronologie-error,
.db-concurrence-error {
  padding: 12px; border-radius: 4px;
  background: #fcecec;
}

/* =============================================================================
   LOT 4 passe 2 — compléments d'anatomie (arbitrage passe 2 §1).
   Bloc dl échéance (icône + dlbig + dlsub), rowp par step avancement,
   queue numérotée prochaine étape, états concurrence.
   ============================================================================= */

/* ── Échéance : bloc dl (icône + dlbig + dlsub) ─────────────────────── */
.db-echeance-dl {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 0;
}
.db-echeance-dl-ic {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink3);
}
.db-echeance-dl[data-etat="close"] .db-echeance-dl-ic { color: var(--ink4, #b0b4bd); }
.db-echeance-dl-txt { flex: 1; min-width: 0; }
.db-echeance-dl-big {
  font-size: 16px; font-weight: 660; color: var(--ink);
  margin-bottom: 3px;
  line-height: 1.35;
}
.db-echeance-dl-sub {
  line-height: 1.45;
}

/* ── Avancement : rowp par step (barre progression + %) ─────────────── */
.db-step-rowp {
  display: flex; align-items: center; gap: 6px;
  margin-top: 6px;
}
.db-step-gbar {
  flex: 1; min-width: 0;
  height: 4px; background: var(--line); border-radius: 99px; overflow: hidden;
}
.db-step-gbar i {
  display: block; height: 100%; background: var(--acc);
  border-radius: 99px;
}
.db-step-done .db-step-gbar i { background: #2e7d5e; }
.db-step-pc {
  flex: 0 0 auto;
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
}

/* ── Prochaine étape : nxt-row + queue numérotée ────────────────────── */
.db-prochaine-nxt-row {
  display: flex; align-items: baseline; gap: 10px;
}
.db-prochaine-nxt-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--acc); color: #fff;
  font-size: 13px; font-weight: 700;
  flex: 0 0 auto;
}
.db-prochaine-queue {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
  display: flex; flex-direction: column; gap: 8px;
}
.db-prochaine-qrow {
  display: flex; align-items: baseline; gap: 10px;
  padding: 6px 0;
  cursor: pointer;
}
.db-prochaine-qrow[data-step="remise"] { cursor: default; }
.db-prochaine-qn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%;
  background: #f0f2f5; color: var(--ink2);
  font-size: 11.5px; font-weight: 640;
  flex: 0 0 auto;
}
.db-prochaine-qtxt {
  font-size: 12.5px; line-height: 1.45; color: var(--ink);
}

/* ── Concurrence : états loading / ok / empty / error ───────────────── */
.db-concurrence-body {
  min-height: 60px;
}
.db-concurrence-loading, .db-concurrence-empty {
  padding: 8px 0;
}
.db-carte-concurrence[data-concurrence-state="loading"] .db-concurrence-body {
  opacity: 0.7;
}

/* ── Issue du marché (lot 5a) — miroir maquette L919-946 ────────────── */
/* Ordre : issue-block (icône + titre + description dérivés du nombre de
   lots avec attributaire) → table par lot (header + rows) → bouton add.
   La ligne vide reste vide (arbitrage §5) : les cellules restent visibles
   mais sans valeur. */
.db-issue-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.db-issue-block {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
.db-issue-ic {
  flex-shrink: 0;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: #f2f4f8;
  color: var(--ink3);
  display: flex; align-items: center; justify-content: center;
}
.db-issue-block[data-issue-state="partielle"] .db-issue-ic {
  background: #e5f3ec;
  color: #116448;
}
.db-issue-txt {
  min-width: 0;
  flex: 1;
}
.db-issue-title {
  font-size: 14.5px;
  font-weight: 640;
  color: var(--ink);
}
.db-issue-desc {
  margin-top: 4px;
  line-height: 1.5;
}
.db-issue-lots {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* Grille 5 colonnes miroir header ↔ rows (arbitrage §5) :
     lot_key(80) · attributaire(1fr) · montant(auto) · reconduction(120) · actions(auto). */
.db-issue-lotshd,
.db-issue-lotrow {
  display: grid;
  grid-template-columns: 80px 1fr auto 120px auto;
  gap: 10px;
  align-items: center;
}
.db-issue-lotshd {
  padding-bottom: 6px;
  border-bottom: 1px dashed var(--line);
  font-size: 12px;
  color: var(--ink3);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.db-issue-lotrow {
  padding: 6px 0;
  border-bottom: 1px solid rgba(0,0,0,0.04);
  font-size: 13px;
  color: var(--ink);
}
.db-issue-lotrow:last-of-type { border-bottom: 0; }
.db-issue-lot-key {
  font-weight: 640;
  color: var(--ink2);
}
.db-issue-lot-attrib,
.db-issue-lot-montant,
.db-issue-lot-reconduction {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.db-issue-lot-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  white-space: nowrap;
}
.db-issue-add {
  align-self: flex-start;
  margin-top: 4px;
}
.db-issue-fetch-error {
  padding: 12px 0;
  color: var(--ink3);
}

.mem-freeze-title { font-size: 13px; }
.mem-freeze-body { margin-top: 4px; }
.mem-freeze-edited { margin-top: 6px; }
.mem-next-list {
  padding: 0;
  margin: 0;
  list-style: none;
}
.mem-next-list li {
  display: flex;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(0,0,0,0.05);
  font-size: 13.5px;
  line-height: 1.4;
}
.mem-next-list li:last-child { border-bottom: 0; }
.mem-next-n {
  flex-shrink: 0;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600;
  font-size: 11.5px;
}
.mem-next-ia-warning { margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(0,0,0,0.06); font-size: 11.5px; line-height: 1.5; }

/* Lot 2b passe 4 — carte "Les 9 sections" en état done : liste linéaire (une
   section par ligne), padding item accru, bouton "Ouvrir" à droite comme
   la maquette p5done. En verrouillé/prêt la grille dense reste. */
.mem-p5-done .mem-section-list {
  grid-template-columns: 1fr;
  gap: 4px;
}
.mem-p5-done .mem-section-item {
  padding: 10px 14px;
  font-size: 13.5px;
}
.mem-p5-done .mem-section-title { font-size: 14px; }
.mem-section-open {
  margin-left: auto;
  padding: 4px 12px;
  background: transparent;
  border: 1px solid rgba(0,0,0,0.12);
  border-radius: 4px;
  font-size: 12px;
  cursor: pointer;
  color: var(--ink2);
}
.mem-section-open:hover {
  background: rgba(0,0,0,0.03);
  color: var(--ink);
}
/* Surbrillance temporaire de la .redaction-section-card ciblée par le
   bouton "Ouvrir" (ancre → scrollIntoView + halo). */
.redaction-section-card-highlight {
  outline: 2px solid var(--primary);
  outline-offset: 4px;
  transition: outline-color .3s ease;
}

/* =============================================================================
 * Lot 3 — vue fusionnée dossier + écarts (panneau p4).
 * Compteur / hero verrou-déverrou / groupes R1 / conformité compacte.
 * Réutilise les classes .dossier-list, .dossier-row et le CSS existant du
 * dossier pour les lignes normales — n'ajoute que le vernis spécifique fusion.
 * ========================================================================== */

.fiche-dossier-fusion {
  /* hérite .card, on serre les gaps entre les blocs de fusion (compteur,
   * hero, groupes, conformité) pour rentrer dans les fourchettes D5. */
}
.fiche-dossier-fusion .collapsible-body {
  padding-top: 8px;
  padding-bottom: 8px;
}
.fiche-dossier-fusion .dossier-fusion-compteur,
.fiche-dossier-fusion .dossier-fusion-hero {
  margin-bottom: 8px;
}
.fiche-dossier-fusion .dossier-fusion-groupe-header {
  margin: 10px 0 4px;
}
.fiche-dossier-fusion .dossier-fusion-conformite {
  margin-top: 10px;
  padding-top: 6px;
}
.fiche-dossier-fusion .dossier-list {
  margin: 0;
  padding: 0;
}
.fiche-dossier-fusion .dossier-add {
  margin-top: 8px;
}

/* Compteur N / dénominateur. Aligné à gauche, gros nombre, barre de progression
 * horizontale, mention "manquantes" à droite. Discrète — pas un tableau de bord. */
.dossier-fusion-compteur {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 20px;
  padding: 14px 16px;
  margin-bottom: 12px;
  background: #f7f9fb;
  border: 1px solid #e6e8ec;
  border-radius: 8px;
}
.dossier-fusion-compteur-count {
  display: flex; align-items: baseline; gap: 4px;
}
.dossier-fusion-compteur-N {
  font-size: 32px; font-weight: 700; color: var(--ink, #1a2230);
  font-variant-numeric: tabular-nums;
}
.dossier-fusion-compteur-slash {
  font-size: 24px; color: var(--text-muted); font-weight: 500;
}
.dossier-fusion-compteur-D {
  font-size: 24px; color: var(--text-muted); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.dossier-fusion-compteur-legend { margin-left: 12px; }
.dossier-fusion-compteur-bar {
  height: 6px; background: #e2e4e8; border-radius: 3px; overflow: hidden;
}
.dossier-fusion-compteur-bar-fill {
  height: 100%; background: linear-gradient(90deg, #7dd3a5, #4fbf7f);
  transition: width .3s ease;
}
.dossier-fusion-compteur-manquantes {
  display: flex; align-items: baseline; gap: 4px; text-align: right;
}
.dossier-fusion-compteur-missing {
  font-size: 18px; font-weight: 600; color: var(--cta-t, #b44a2a);
  font-variant-numeric: tabular-nums;
}

/* Hero mémoire — deux états. Locked = carte de vente (fond crème), OK = carte
 * succès (bordure verte, icône check). Layout : icône + corps + CTA à droite. */
.dossier-fusion-hero {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 18px;
  padding: 16px 18px;
  margin-bottom: 16px;
  border-radius: 8px;
  border: 1px solid #e6e8ec;
}
.dossier-fusion-hero-locked {
  background: linear-gradient(135deg, #fff8f0, #fff2e0);
  border-color: #f0d4a0;
}
.dossier-fusion-hero-ok {
  background: linear-gradient(135deg, #f0fdf4, #dcfce7);
  border-color: #7dd3a5;
}
/* Passe 3 B4 — variante « attaché par vos soins » : le client a téléversé
 * son propre mémoire (pas de snapshot plateforme). Fond bleu très pâle
 * pour distinguer du hero verte OK, sans mentir « rédigé ». */
.dossier-fusion-hero-attached {
  background: linear-gradient(135deg, #eff6ff, #dbeafe);
  border-color: #93c5fd;
}
.dossier-fusion-hero-attached .dossier-fusion-hero-icon { background: #3b82f6; }
/* Passe 3 B4 — zone d'attache dans le hero verrouillé : action secondaire
 * discrète sous le CTA principal. Restaure la capacité D3 perdue (attach
 * mémoire déjà rédigé) par le déplacement mémoire → hero. */
.dossier-fusion-hero-attach {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed rgba(0, 0, 0, 0.08);
}
.dossier-fusion-hero-attach .dossier-attach {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 6px;
}
.dossier-fusion-hero-attach .dossier-attach-toggle {
  padding: 2px 10px;
  font-size: 12px;
}
/* La sous-liste des pièces attachées dans le hero (variante attached) —
 * conservée compacte. */
.dossier-fusion-hero-attached .dossier-pieces {
  margin: 8px 0 6px 0;
  padding: 0;
}
.dossier-fusion-hero-attached .dossier-pieces .dossier-piece-row {
  padding: 3px 6px;
}
.dossier-fusion-hero-icon {
  width: 42px; height: 42px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff;
}
.dossier-fusion-hero-locked .dossier-fusion-hero-icon { background: #b44a2a; }
.dossier-fusion-hero-ok .dossier-fusion-hero-icon { background: #4fbf7f; }
.dossier-fusion-hero-title {
  font-weight: 660; font-size: 15px; margin-bottom: 4px;
}
.dossier-fusion-hero-desc {
  font-size: 13px; color: var(--ink2, #2a3444); line-height: 1.5;
  margin-bottom: 6px;
}
.dossier-fusion-hero-label {
  font-size: 13px; color: var(--text-muted); font-style: italic;
}
.dossier-fusion-hero-ref {
  font-size: 11px; background: rgba(0,0,0,.06); padding: 1px 6px; border-radius: 3px;
  margin-left: 6px;
}
.dossier-fusion-hero-cta { text-align: right; }

/* Groupes R1 — titres H3 discrets avec compteur. */
.dossier-fusion-groupe-header {
  display: flex; align-items: baseline; gap: 10px;
  margin: 18px 0 8px;
  padding: 6px 0;
  border-bottom: 1px solid #eef0f3;
}
.dossier-fusion-groupe-title {
  font-size: 14px; font-weight: 600; margin: 0; color: var(--ink, #1a2230);
}
.dossier-fusion-groupe-count {
  font-weight: 400;
}
.dossier-fusion-groupe-note {
  margin: 6px 0 12px; font-size: 12px; font-style: italic;
}

/* Référence RC affichée à côté du label — petite pastille grise. */
.dossier-fusion-ref {
  display: inline-block;
  padding: 1px 6px;
  margin-left: 6px;
  font-size: 11px;
  background: #f3f4f6;
  color: var(--text-muted);
  border-radius: 3px;
  font-weight: 500;
  vertical-align: middle;
}

/* Ligne orpheline écart — badge « exigence relevée » à gauche.
 * Fond légèrement teinté (bleu très pâle) pour distinguer visuellement. */
.dossier-row-orphelin {
  background: #f8fafc;
  border-left: 3px solid #a3b3c7;
}
.dossier-fusion-badge-orphelin {
  display: inline-block;
  padding: 2px 8px;
  font-size: 11px;
  background: #dbeafe;
  color: #1e40af;
  border-radius: 3px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-right: 8px;
}
.dossier-fusion-categorie {
  margin-left: 8px;
  font-style: italic;
}

/* Conformité compacte — section repliable, sous-titres pour clauses vs contexte. */
.dossier-fusion-conformite {
  margin-top: 20px;
  border-top: 1px solid #e2e4e8;
  padding-top: 8px;
}
.dossier-fusion-conformite-sub {
  font-size: 13px; font-weight: 600; margin: 12px 0 6px;
  color: var(--ink2, #2a3444);
}

/* État d'erreur fusion — reprend .ecarts-empty-error, spécialisation minimale. */
.dossier-fusion-error {
  /* hérite .ecarts-empty.ecarts-empty-error du CSS existant */
}

/* --- Compactage vue fusionnée ---
 * La vue fusionnée doit rentrer dans les fourchettes D5 [1550, 2150] sur 7603.
 * Le CSS existant `.dossier-row` et `.dossier-attach` a été dimensionné pour
 * la vue historique isolée où chaque ligne pouvait respirer. Dans la fusion,
 * on scope les compactages à `.fiche-dossier-fusion` pour ne pas casser
 * d'autres écrans qui pourraient utiliser les mêmes classes ailleurs. */
.fiche-dossier-fusion .dossier-row {
  padding: 0 8px;
  margin: 0;
  border-bottom: 1px solid #f0f2f5;
  min-height: 36px;
  font-size: 13px;
  line-height: 1.35;
}
.fiche-dossier-fusion .dossier-row-main {
  padding: 2px 0;
  gap: 8px;
  min-height: 30px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}
.fiche-dossier-fusion .dossier-label {
  line-height: 1.3;
}
.fiche-dossier-fusion .dossier-statut {
  padding: 2px 8px;
  font-size: 11px;
}
/* Zone attach : bouton en inline discret plutôt qu'en ligne séparée dessous. */
.fiche-dossier-fusion .dossier-attach {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  margin: 0 0 0 8px;
}
.fiche-dossier-fusion .dossier-attach-toggle {
  padding: 2px 8px;
  font-size: 12px;
}
/* Sous-liste des pièces attachées : padding réduit, chaque pièce plus compacte. */
.fiche-dossier-fusion .dossier-pieces {
  margin: 4px 0 4px 20px;
  padding: 0;
}
.fiche-dossier-fusion .dossier-pieces .dossier-piece {
  padding: 3px 6px;
}
/* Formulaires vierges — grille horizontale 3 colonnes plutôt qu'une liste
 * verticale. Rétablit une hauteur proche de la maquette (~236 px).
 * Chaque row garde toutes ses actions (D3 : rien ne disparaît), on économise
 * juste la verticalité. */
.fiche-dossier-fusion .formulaires-vierges-block {
  margin-top: 12px;
}
.fiche-dossier-fusion .formulaires-vierges-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px 8px;
  margin: 0;
  padding: 0;
}
.fiche-dossier-fusion .formulaires-vierges-row {
  padding: 3px 6px;
  border-radius: 3px;
  background: #fafbfc;
  border: 1px solid #eef0f3;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
}
.fiche-dossier-fusion .formulaires-vierges-title {
  margin-bottom: 4px;
}
.fiche-dossier-fusion .formulaires-vierges-description {
  display: none;  /* description répète le titre, on économise une ligne */
}
.fiche-dossier-fusion .formulaires-vierges-download {
  padding: 1px 6px;
  font-size: 11px;
}
/* Formulaires admin — boutons compactés. */
.fiche-dossier-fusion .formulaires-admin-block {
  margin-top: 10px;
  margin-bottom: 6px;
}
.fiche-dossier-fusion .formulaires-admin-actions {
  gap: 6px;
}
.fiche-dossier-fusion .formulaires-admin-actions .btn {
  padding: 3px 10px;
  font-size: 12px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Lot 5b — cartes p4 (Coffre + Contrôle avant remise + La remise).
   Anatomie maquette v10 : grille 12 col, coffre span 7, controle span 7,
   remise span 12. La garde d'anatomie du smoke (offsetWidth + display grid)
   assure qu'une carte sans CSS n'entre pas dans la fourchette hauteur en
   étant squeezée horizontalement (leçon 11/08).
   ═══════════════════════════════════════════════════════════════════════════ */
.p4-lot5b-section { margin-top: 14px; }
.p4-lot5b-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 12px;
}
.p4-carte {
  background: var(--bg1, #fff);
  border: 1px solid var(--line, #e5e5e5);
  border-radius: 8px;
  padding: 14px 16px;
  min-width: 0; /* évite le squeeze */
}
.p4-carte-coffre    { grid-column: span 7; }
.p4-carte-controle  { grid-column: span 7; }
.p4-carte-remise    { grid-column: span 12; }
.p4-ch { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.p4-ch h3 { font-size: 15px; font-weight: 700; margin: 0; }
.p4-ch .p4-r { font-size: 12px; color: var(--muted, #7a7a7a); font-weight: 500; }
.p4-error { color: #b3261e; font-size: 13px; padding: 8px 0; }
.p4-empty { color: var(--muted, #7a7a7a); font-size: 13px; padding: 8px 0; }
.p4-note  { color: var(--ink2, #444); font-size: 13px; line-height: 1.55; margin: 10px 0 0; }
.p4-cta   { margin-top: 12px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* Coffre — stats horizontales */
.p4-coffre-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 10px 0 6px;
}
.p4-cf { text-align: left; }
.p4-cf .p4-v { font-size: 28px; font-weight: 700; color: var(--ink, #1a1a1a); }
.p4-cf .p4-k { font-size: 12px; color: var(--muted, #7a7a7a); }

/* Contrôle — checks + manquants */
.p4-chk-list { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.p4-chk { display: grid; grid-template-columns: 22px 1fr; align-items: baseline; gap: 8px; font-size: 13px; line-height: 1.5; }
.p4-chk .p4-m { display: inline-block; width: 22px; height: 22px; border-radius: 50%; text-align: center; line-height: 22px; font-weight: 700; color: #fff; }
.p4-chk.ok     .p4-m { background: #2f8a4a; }
.p4-chk.warn   .p4-m { background: #c47a1a; }
.p4-chk.no     .p4-m { background: #bbb; }
.p4-chk.neutre .p4-m { background: #d4d4d8; color: #52525b; }
.p4-chk.neutre       { color: var(--muted, #7a7a7a); }
.p4-manquants { background: var(--bg2, #f7f7f7); border-radius: 6px; padding: 8px 12px; margin: 8px 0; font-size: 12.5px; }
.p4-manquants-title { font-weight: 600; margin-bottom: 4px; }
.p4-manquants ul { margin: 0; padding-left: 18px; }
.p4-manquants-tag { display: inline-block; background: #e6d8b8; color: #6b4a10; padding: 1px 6px; border-radius: 4px; font-size: 11px; margin-left: 4px; }
.p4-gate { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.p4-credit { font-size: 12px; color: var(--cta-t, #7a5a10); }

/* La remise — 3 étapes horizontales */
.p4-depot { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin: 6px 0; }
.p4-dstep { border: 1px solid var(--line, #e5e5e5); border-radius: 6px; padding: 10px 12px; background: #fafafa; }
.p4-dstep .p4-n { display: inline-block; width: 22px; height: 22px; border-radius: 50%; text-align: center; line-height: 22px; background: #ccc; color: #fff; font-weight: 700; font-size: 12px; margin-bottom: 4px; }
.p4-dstep .p4-t { font-weight: 600; font-size: 13px; margin: 2px 0; }
.p4-dstep .p4-d { font-size: 12px; color: var(--muted, #7a7a7a); line-height: 1.45; }
.p4-dstep.now .p4-n { background: var(--cta, #b48b26); }
.p4-dstep.done .p4-n { background: #2f8a4a; }
.p4-dstep.done { border-color: #b8d6c1; background: #f2faf5; }
.p4-recap { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; margin-top: 10px; }
.p4-recap label { display: flex; flex-direction: column; font-size: 12px; color: var(--muted, #7a7a7a); }
.p4-recap input { border: 1px solid var(--line, #e5e5e5); border-radius: 4px; padding: 6px 8px; font-size: 13px; margin-top: 2px; background: #f7f7f7; }

/* Modale accusé — patron 5a (dialog natif) */
.modal { border: none; border-radius: 8px; padding: 0; max-width: 520px; }
.modal-form { padding: 20px 24px; display: flex; flex-direction: column; gap: 10px; }
.modal-form h3 { margin: 0; font-size: 16px; font-weight: 700; }
.modal-form label { display: flex; flex-direction: column; font-size: 13px; }
.modal-form input { margin-top: 2px; padding: 6px 8px; border: 1px solid var(--line, #e5e5e5); border-radius: 4px; font-size: 13px; }
.modal-buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
.modal-err { color: #b3261e; font-size: 12px; padding: 4px 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   Lot 5c — Mode INVITÉ (guest) : bandeau permanent + hide des zones de
   mutation marquées [data-guest-hide]. Activé par body.guest-mode (posé
   par public/js/marche.js quand ?guest=1 + localStorage.tpia_guest_token).
   ═══════════════════════════════════════════════════════════════════════════ */
body.guest-mode [data-guest-hide] { display: none !important; }

/* R7 stratège — les affordances de mutation sans data-guest-hide ciblé
   se masquent aussi par pattern CSS (belt-and-braces). Trois familles
   d'affordances communes dans la page marché membre :
     - .editable-pencil / [contenteditable] : inline edit metadata
     - [data-drag-drop-zone] : upload documents / drop
     - Les modales de mutation sont en amont derrière un bouton, mais si
       elles sont ouvertes en guest (bug), le fond doit rester actionnable
   Le fail-fast Api.post/patch/del (api.js) reste comme filet — le serveur
   redouble par requireUser/requireAuthOrGuest. Ces règles sont l'INTERFACE
   propre pour le guest, pas la ligne de défense. */
body.guest-mode .editable-pencil { display: none !important; }
body.guest-mode .editable-display { pointer-events: none; user-select: text; }
body.guest-mode [contenteditable="true"] { pointer-events: none; }
/* Passe 2 B3 — le wrapper .editable-field porte onclick=startEdit. On désactive
   les pointer-events sur le wrapper entier (texte visible mais click inactif) —
   la sélection texte reste possible grâce à .editable-display{user-select:text}. */
body.guest-mode .editable-field { pointer-events: none; }
body.guest-mode [data-drag-drop-zone],
body.guest-mode .doc-uploader,
body.guest-mode .extraire-seul-zone,
body.guest-mode .dropzone { display: none !important; }

/* Boutons de mutation identifiés par onclick — belt-and-braces avec les
   data-guest-hide chirurgicaux. Une renommée de fonction JS masque cette
   règle (audit R7 à refaire) — c'est un compromis assumé face au coût
   d'annoter 20+ onclick individuellement. */
body.guest-mode [onclick*="openLaunchModal"],
body.guest-mode [onclick*="openAcheteurResolveModal"],
body.guest-mode [onclick*="_searchAcheteurCandidates"],
body.guest-mode [onclick*="openAddMemberModal"],
body.guest-mode [onclick*="dashboardSelfRemove"],
body.guest-mode [onclick*="removeMember"],
body.guest-mode [onclick*="dossierToggleStatut"],
body.guest-mode [onclick*="dossierDelete"],
body.guest-mode [onclick*="dossierCancelAdd"],
body.guest-mode [onclick*="openSaisiePlateformeModal"],
body.guest-mode [onclick*="openAddLotModal"],
body.guest-mode [onclick*="openEditLotModal"],
body.guest-mode [onclick*="confirmDeleteLot"],
body.guest-mode [onclick*="MarcheJalons."] {
  display: none !important;
}
/* Passe 2 B3 — l'ancienne règle [onclick*="startEdit"]{display:none} masquait
   les DIV lisibles entières (le contenteditable qui porte le titre du marché,
   l'acheteur, etc.), pas seulement le crayon d'édition. Fiche guest sans
   titre ni acheteur. Fix : on désactive uniquement la MUTATION via
   .editable-pencil{display:none} + .editable-display{pointer-events:none}
   (déjà présents plus haut) — le texte reste lisible, le crayon n'apparaît
   pas, le click sur le display n'ouvre plus l'éditeur inline. */
/* La zone plateforme_depot est un champ affiché qui ouvre la modale de
   saisie au click — on garde le champ visible (lecture) mais on désactive
   la mutation via pointer-events. */
body.guest-mode .db-echeance-plat-field { pointer-events: none; }

/* Passe 3 B4-résiduel — l'onglet 4 DÉBLOQUÉ (acces_memoire=true) rend
   renderRedactionSection qui contient les CTA d'écriture « Rédiger — 8
   crédits · verrouillé », « Générer en mode brouillon », « Compléter »,
   « Modifier ». En guest lecture seule, aucun n'est actionnable. On les
   masque tous par un jeu de sélecteurs sur les IDs/classes utilisés par
   marche-redaction.js et marche-memoire-p5.js. */
body.guest-mode #redaction-launch,
body.guest-mode #redaction-complete-first,
body.guest-mode .redaction-actions,
body.guest-mode .redaction-edit-btn,
body.guest-mode .mem-cta-complete,
body.guest-mode .mem-cta-write,
body.guest-mode .mem-cta-write-locked,
body.guest-mode [data-mem-cta-write] { display: none !important; }

.guest-banner {
  background: linear-gradient(90deg, #f7f6f0 0%, #efeee6 100%);
  border-bottom: 2px solid #d9d6c7;
  color: #4a4737;
  padding: 10px 24px;
  font-size: 14px;
  font-weight: 500;
  text-align: center;
  position: sticky;
  top: 0;
  z-index: 1000;
}
.guest-banner strong { color: #2c2a1e; }

.guest-locked-state {
  padding: 32px 24px;
  border: 1px dashed #cfccbe;
  border-radius: 8px;
  background: #fafaf5;
  color: #6b6853;
  text-align: center;
}
.guest-locked-state h3 {
  margin: 0 0 8px 0;
  color: #2c2a1e;
  font-size: 15px;
}
.guest-locked-state p { margin: 0; font-size: 13px; }

/* ============================================================================
   LOT 6 T7 — Carte des attributaires (onglet 3 acheteur).
   ============================================================================ */
.attributaires-carte { margin-bottom: 20px; }
.attributaires-controls {
  display: flex;
  gap: 4px;
  margin-bottom: 12px;
}
.attributaires-zoom {
  padding: 4px 10px;
  font-size: 12px;
  background: #fff;
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}
.attributaires-zoom:hover { background: #f5f5f8; }
.attributaires-zoom.on {
  background: var(--acc, #4f4e91);
  color: #fff;
  border-color: var(--acc, #4f4e91);
}
.attributaires-mapbox {
  width: 100%;
  aspect-ratio: 613 / 585;
  max-height: 480px;
  background: #fafbfc;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 12px;
  display: flex; align-items: center; justify-content: center;
}
.attributaires-svg {
  width: 100%;
  height: 100%;
  display: block;
}
/* B1 (verdict passe 1) — même correctif que .db-geo-svg. Nuance légère du
   fond au ton maquette L1127 (#edeff4 vs #eceff3 dashboard) — cohérent avec
   le pattern L800/L1122 de la maquette v10. */
.attributaires-svg .fond-france path {
  fill: #edeff4;
  stroke: #c4cad3;
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}
.attributaires-loading { padding: 20px; }
.attributaires-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 20px;
  padding: 10px 0;
  border-top: 1px dashed var(--line);
  font-size: 12.5px;
}
.attributaires-legende span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.attributaires-legende i {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 99px;
}
.attributaires-offmap {
  padding: 10px 12px;
  background: #fef7ed;
  border-left: 3px solid #d97706;
  border-radius: 3px;
  margin: 10px 0;
  font-size: 12.5px;
  color: var(--ink);
}
.attributaires-offmap-row {
  line-height: 1.55;
}
.attributaires-note { line-height: 1.55; }
.attributaires-empty-country {
  padding: 40px 12px;
  text-align: center;
  background: #fafbfc;
  border-radius: 4px;
  color: var(--ink3);
}
.attributaires-empty-country-msg {
  font-size: 14px;
  color: var(--ink);
}

/* ============================================================================
   LOT 6 T8 — Partenaires D5 : plafond 5 fiches + modale « Voir les N autres ».
   ============================================================================ */
.partenaires-candidates-more {
  margin-top: 12px;
  text-align: center;
}
.partenaires-modal-open {
  padding: 8px 16px;
  font-size: 13px;
  background: var(--acc, #4f4e91);
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.partenaires-modal-open:hover { opacity: 0.9; }
.partenaires-candidates-modal {
  position: fixed;
  inset: 0;
  z-index: 1050;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.partenaires-candidates-modal[hidden] { display: none; }
.partenaires-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(28, 32, 39, 0.55);
  cursor: pointer;
}
.partenaires-modal-panel {
  position: relative;
  background: #fff;
  border-radius: 8px;
  max-width: 900px;
  width: 100%;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
}
.partenaires-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
}
.partenaires-modal-head h3 { margin: 0; font-size: 16px; font-weight: 640; }
.partenaires-modal-close {
  background: none;
  border: none;
  font-size: 24px;
  color: var(--ink3);
  cursor: pointer;
  padding: 4px 8px;
  line-height: 1;
}
.partenaires-modal-close:hover { color: var(--ink); }
.partenaires-modal-body {
  padding: 16px 20px;
  overflow-y: auto;
  flex: 1;
}
.partenaires-candidates-in-modal {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* =============================================================================
 * Bloc « Vos prochaines actions » (phase 1 + passe 2 UI)
 *
 * Rendu par public/js/next-actions-render.js (module UMD partagé Node/browser).
 * Un item qui nommait un ÉTAT (« Premier Go/No-Go obtenu ✓ ») meurt à l'instant
 * où il devient vrai ; ce bloc nomme une ACTION sur un objet — « Analyser le
 * DCE de <objet> » — donc il se régénère à chaque nouveau marché.
 *
 * Cadrage : docs/cadrage-prochaines-actions-phase1.md §0/§4/§6.
 * Verdict passe 1 §2 : effet « waouh », icônes par famille, boutons primaires,
 * pastille d'échéance. Direction : consommer en indigo primaire (analyses
 * payantes), compléter en ambre doux (attention). INTERDIT : `--go` (vert)
 * sur une action à faire — le vert est la couleur de l'accompli et du verdict
 * « Go ».
 *
 * Contrat visuel gravé :
 *   - Chaque ligne porte un CTA « Accéder » (`.btn-small`, indigo primaire),
 *     atteignable au clavier (:focus-visible). Un bouton qui NAVIGUE ne
 *     débite jamais — jamais « Lancer » (C-PA-4).
 *   - Interdit maintenu : AUCUN pourcentage, AUCUNE fraction (C-PA-6).
 *   - Rien à dire → module retourne '' et conteneur est vide (C-PA-3).
 *   - Pastille d'échéance (kinds consume + date_limite) : buckets
 *     `.tag-urgent` (< 3 j) / `.tag-soon` (< 14 j) / neutre (patron du
 *     tableau, C-PA-5 étendu : même date dans les deux surfaces).
 * ============================================================================= */
.home-next-actions {
  padding: 24px 26px;
}
.home-next-actions-title {
  margin: 0 0 16px;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.005em;
}
.home-next-actions-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 12px;   /* même respiration inter-rangée que l'ancienne .home-checklist-items (D-UI-3) */
}

/* Passe 2b (D-UI-3 addendum) — géométrie EXACTE de l'ancienne
 * `.home-checklist-item` retirée au commit 51a5489 : grille 24px | 1fr,
 * padding 10 12, gap 14, tout sur UNE ligne de texte. Colonnes auto en
 * fin de ligne pour la pastille d'échéance (facultative), le CTA
 * « Accéder » et — phase 2 refus — le bouton « Ne plus proposer » (sur
 * les seules lignes consume). Cinq colonnes auto au max, la géométrie
 * reste fine (rangée ~48 px). */
.home-next-actions-item {
  display: grid;
  grid-template-columns: 24px 1fr auto auto auto;
  align-items: center;
  gap: 14px;
  padding: 10px 12px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  transition: background .12s ease, border-color .12s ease;
}
.home-next-actions-item:hover {
  background: var(--card);
  border-color: var(--border-strong);
}

/* Pastille RONDE 24 px (miroir géométrique de `.home-checklist-marker`) —
 * contenu : icône lucide en BLANC sur fond PLEIN. Deux familles :
 *   .is-consume  → INDIGO primaire (analyses payantes ; compass, file-text)
 *   .is-complete → AMBRE plein (attention ; user, briefcase)
 * INTERDIT gravé (verdict passe 1 §2) : le vert `--go` n'apparaît PAS sur
 * une action à faire — le vert est la couleur de l'accompli. */
.home-next-actions-icon {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: #ffffff;   /* icône SVG en blanc (stroke=currentColor dans common.js) */
}
.home-next-actions-item.is-consume .home-next-actions-icon {
  background: var(--primary);   /* indigo plein */
}
.home-next-actions-item.is-complete .home-next-actions-icon {
  background: var(--amber);     /* ambre plein */
}
.home-next-actions-icon .icon { display: block; }

.home-next-actions-label {
  color: var(--text);
  font-size: 15px;
  line-height: 1.45;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* D-PA2-UI-2 (addendum passe-UI 27/08, décision Laurent) — l'ACTION en
   * gras, la VARIABLE (l'objet du marché, ou le label de l'essentiel) en
   * poids normal. Le parent porte le gras (600), le span-objet le dé-graisse
   * (400). Les 7 fichiers i18n restent intacts — la construction est locale-
   * safe : elle fonctionne quelle que soit la position de `{objet}` dans le
   * template (l'action peut envelopper l'objet en DE). Le poids se pose
   * par CSS, jamais par balise dans une traduction. */
  font-weight: 600;
}
.home-next-actions-label-objet {
  font-weight: 400;
}

/* Pastille d'échéance — réutilise .tag / .tag-urgent / .tag-soon existants.
 * D-UI-2 : jamais rendue pour les échéances passées (le filtrage est en
 * amont). Rangée fine → taille compacte, alignée à la ligne du libellé. */
.home-next-actions-deadline {
  font-size: 12px;
  padding: 2px 8px;
  white-space: nowrap;
}

/* CTA « Accéder » — hérite de `.btn-small` pour la couleur (indigo primaire,
 * blanc, box-shadow). Variante COMPACTE en override local : le CTA ne doit
 * pas gonfler la hauteur de rangée héritée de la checklist F-2 (padding
 * 10 + line-height 22 ≈ 42 px). `.btn-small` (padding 8×16) tirait la rangée
 * à ~54 px ; padding 5×12 + radius 6 la ramène à ~48 px sans casser le
 * gabarit fin. Aucun override de fond, aucune variable `:root` touchée —
 * le geste reste local à `.home-next-actions-cta`. */
.home-next-actions-cta {
  text-decoration: none;
  white-space: nowrap;
  padding: 5px 12px;
  font-size: 13px;
  border-radius: 6px;
}
.home-next-actions-cta:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Phase 2 « le refus » (27/08). Bouton DISCRET à droite du CTA — le geste
 * est définitif par décision produit, le libellé doit rester léger
 * visuellement mais atteignable (aria-label + focus visible). Pas de fond,
 * pas de bordure au repos : le refus est une action secondaire, pas une
 * invitation.
 *
 * D-PA2-UI-1 (addendum passe-UI 27/08 matin, décision Laurent) : le survol
 * garde l'indigo assumé. La règle globale `button:hover` (l. 709) pose déjà
 * `--primary-strong` — spécificité (0,1,1) qui BATTAIT `.home-next-actions-
 * refuse:hover` (0,1,0) et faisait apparaître un texte rouge sur fond
 * indigo (fuite de cascade). On pose donc EXPLICITEMENT `--primary-strong`
 * au hover avec `#fff` et `text-decoration: none` — une règle qui dit ce
 * qu'elle fait, pas une fuite laissée gagner. Le `--danger` disparaît du
 * survol ET du focus (l'outline focus prend `--primary`). */
.home-next-actions-refuse {
  background: transparent;
  border: 0;
  padding: 5px 8px;
  margin-left: 4px;
  font-size: 12px;
  color: var(--muted);
  cursor: pointer;
  border-radius: 4px;
  white-space: nowrap;
}
.home-next-actions-refuse:hover {
  background: var(--primary-strong);
  color: #ffffff;
  text-decoration: none;
}
.home-next-actions-refuse:focus-visible {
  background: var(--primary-strong);
  color: #ffffff;
  text-decoration: none;
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Mini-passe dashboard G4 (D-PA2-UI-3, 27/08/2026) — transition visible au
 * refus. La ligne refusée se replie (~200 ms), la remplaçante glisse en
 * place au re-render (le DOM final est strictement identique à sans cette
 * classe : `.is-refusing` disparaît AVEC le re-render qui suit). Aucune
 * assertion de timing dans les smokes — la transition est bornée en
 * durée, le re-render attend max(POST, 220 ms). `prefers-reduced-motion`
 * respecté : repli sans animation (transition supprimée), le repli
 * lui-même reste (invariant : la ligne disparaît instantanément avant
 * re-render, jamais visible « à côté »).
 *
 * `max-height` inline posé en JS avant l'ajout de la classe (mesure de
 * la hauteur réelle) — nécessaire car on ne peut pas transitionner de
 * `auto` à `0` en CSS. */
.home-next-actions-item.is-refusing {
  overflow: hidden;
  max-height: 0 !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  border-color: transparent !important;
  opacity: 0;
  pointer-events: none;
  transition:
    max-height 200ms ease,
    padding 200ms ease,
    opacity 200ms ease,
    border-color 200ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .home-next-actions-item.is-refusing {
    transition: none;
  }
}

/* =============================================================================
 * Lot 7bis J3 D-J3-4 — état de bienvenue de la page profil (`#welcome-essentials`).
 *
 * Surface DIRIGE (une surface MESURE ou DIRIGE, jamais les deux — patron J2).
 * Rend la liste nommée des essentiels manquants, avec pour chacun un
 * deep-link vers l'onglet cible. Miroir visuel de la checklist F-2
 * (`.home-checklist`) pour cohérence de la charte directive.
 *
 * Interdit maintenu (C-3.7) : AUCUN pourcentage, AUCUNE fraction dans le
 * sous-arbre DOM. Ce fichier ne pose pas de compteur, mais la garde
 * s'exerce à l'écran (front-smoke Playwright sur le sous-arbre).
 *
 * Contrat visuel is-todo vs is-done — CINQ propriétés perceptibles
 * indépendamment (miroir J2, gravé) : background · border-color ·
 * border-width · color de la glyphe · glyphe elle-même (::before). Une
 * classe qu'aucune CSS ne consomme est une garde que rien ne traverse.
 * ============================================================================= */

.welcome-essentials {
  padding: 22px 26px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
}
.welcome-essentials-title {
  margin: 0 0 14px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.005em;
}
.welcome-essentials-body {
  display: block;
}

.welcome-essentials-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 10px;
}
.welcome-essentials-item {
  display: grid;
  grid-template-columns: 24px 1fr;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
}
/* Passe 2 verdict §1 B-1 — le libellé et la mention d'onglet vivent dans
 * un même wrapper flex de la 2e colonne, restent sur UNE ligne quand la
 * largeur le permet. Avant le fix, `<a>` et `<span>` étaient enfants
 * directs du <li> (grid à 2 colonnes) — le 3e enfant retombait dans une
 * nouvelle ligne, colonne 1 (24 px), qui brisait le texte mot par mot.
 * Six lignes pour trois mots. Le wrapper .welcome-essentials-item-body
 * fait de link+tag deux enfants inline dans la même cellule de grille. */
.welcome-essentials-item-body {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
}

.welcome-essentials-marker {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 13px;
  line-height: 1;
  font-weight: 700;
}
.welcome-essentials-marker.is-todo {
  background: var(--card);
  border: 2px solid var(--border-strong);
  color: transparent;
}
.welcome-essentials-marker.is-done {
  background: var(--go);
  border: 2px solid var(--go);
  color: #ffffff;
}

.welcome-essentials-item-link {
  color: var(--text);
  font-size: 15px;
  line-height: 1.45;
  text-decoration: none;
  font-weight: 500;
}
a.welcome-essentials-item-link:hover {
  color: var(--laiton);
  text-decoration: underline;
}
/* Passe 2 verdict §2 B-2 — un item déjà fait (is-done) rend son libellé
 * en texte (span, pas <a>), avec une couleur adoucie qui prolonge le
 * contrat visuel J2 (le done s'atténue, le todo attire). */
.welcome-essentials-item.is-done .welcome-essentials-item-link {
  color: var(--text-soft);
  font-weight: 400;
}
.welcome-essentials-item-tab {
  font-size: 13px;
  color: var(--text-soft);
  white-space: nowrap;
}

/* ==========================================================================
 * Chantier « Discussions / Messagerie » — geste ÉCRAN
 * cadrage docs/cadrage-discussions-ecran.md — volets A→F.
 * Palette existante (navy/cobalt/indigo/ambre) réutilisée strictement.
 * ========================================================================== */

.discussions-header-card { display: flex; flex-direction: column; gap: 12px; }
.discussions-header-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.discussions-header-row h1 { margin: 0; font-size: 22px; font-weight: 700; }
.discussions-header-actions { display: flex; gap: 8px; align-items: center; }

/* Volet E — jauge stockage */
.discussions-storage { display: flex; flex-direction: column; gap: 6px; }
.discussions-storage-row {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 13px; color: var(--text-soft);
}
.discussions-storage-percent { font-weight: 700; color: var(--text); }
.discussions-storage-row.is-warning .discussions-storage-percent { color: #8a5a07; }
.discussions-storage-row.is-critical .discussions-storage-percent { color: #a11f2c; }
.discussions-storage-bar {
  height: 6px; background: rgba(0,0,0,0.06); border-radius: 999px; overflow: hidden;
}
.discussions-storage-bar-fill {
  height: 100%; background: var(--accent); border-radius: 999px;
  transition: width 0.2s ease;
}
.discussions-storage-row.is-warning + .discussions-storage-bar .discussions-storage-bar-fill { background: var(--amber); }
.discussions-storage-row.is-critical + .discussions-storage-bar .discussions-storage-bar-fill { background: #d64857; }
.discussions-storage-hint {
  font-size: 11px; color: var(--text-soft);
  margin-top: 2px; line-height: 1.35;
}

/* Volets B/C — onglets */
.discussions-list-card { padding-top: 0; }
.discussions-tabs {
  display: flex; gap: 4px; border-bottom: 1px solid var(--border-soft);
  margin: 0 -20px 16px; padding: 0 20px;
}
.discussions-tab {
  padding: 12px 14px 10px; background: transparent; border: none;
  border-bottom: 2px solid transparent;
  font: inherit; font-weight: 600; color: var(--text-soft);
  cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
}
.discussions-tab:hover { color: var(--text); }
.discussions-tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.discussions-tab-badge {
  min-width: 18px; height: 18px; padding: 0 6px;
  border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}

.discussions-empty { padding: 30px 0; text-align: center; }
.discussions-list { display: flex; flex-direction: column; gap: 4px; }
.discussions-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 12px 14px; border-radius: 10px; cursor: pointer;
  transition: background 0.12s ease;
  border: 1px solid transparent;
}
.discussions-row:hover { background: rgba(46, 91, 186, 0.04); border-color: var(--border-soft); }
.discussions-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* M3 (06/10/2026) R2 — row Dashboard Accueil : CSS racine additive décalquée
   de .discussions-row (sélecteur ci-dessus, intouché par construction option
   α). Le DOM pose role="button" tabindex="0" sur .home-discussions-row ; sans
   ce bloc, display:block + cursor:auto + pas de focus-visible. */
.home-discussions-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 12px 14px; border-radius: 10px; cursor: pointer;
  transition: background 0.12s ease;
  border: 1px solid transparent;
}
.home-discussions-row:hover { background: rgba(46, 91, 186, 0.04); border-color: var(--border-soft); }
.home-discussions-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.discussions-row-main { flex: 1 1 auto; min-width: 0; }
.discussions-row-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.discussions-row-title {
  font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.discussions-row-sub { color: var(--text-soft); font-size: 12px; margin-top: 2px; }
.discussions-row-tag {
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 2px 8px; border-radius: 999px;
  background: rgba(46, 91, 186, 0.08); color: var(--accent);
}
.discussions-row-tag.is-private   { background: rgba(122, 79, 200, 0.10); color: #5b3b96; }
.discussions-row-tag.is-marche    { background: rgba(0, 0, 0, 0.05); color: var(--text-soft); }
.discussions-row-archived {
  font-size: 10px; font-weight: 600; padding: 2px 8px;
  border-radius: 999px; background: rgba(0,0,0,0.06); color: var(--text-soft);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.discussions-row-badge {
  min-width: 22px; height: 22px; padding: 0 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff; font-weight: 700; font-size: 12px;
  border-radius: 999px; flex-shrink: 0;
}

/* Volet D — vue conversation */
.discussions-thread-card { display: flex; flex-direction: column; gap: 12px; }
.discussions-thread-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.discussions-thread-head-main { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.discussions-thread-title { margin: 0; font-size: 18px; font-weight: 700; }
.discussions-thread-head-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.discussions-thread-participants {
  font-size: 12px; color: var(--text-soft);
  padding: 6px 10px; background: rgba(0,0,0,0.03); border-radius: 8px;
}
.discussions-thread-load-more { text-align: center; }
.discussions-thread-messages {
  display: flex; flex-direction: column; gap: 12px;
  max-height: 55vh; overflow-y: auto; padding: 4px 0;
}
.discussions-message {
  padding: 10px 12px; border-radius: 10px;
  background: rgba(0,0,0,0.02); border: 1px solid var(--border-soft);
}
.discussions-message.is-mine { background: rgba(46, 91, 186, 0.05); border-color: rgba(46, 91, 186, 0.15); }
.discussions-message-head {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: 12px; color: var(--text-soft);
}
.discussions-message-author { font-weight: 700; color: var(--text); }
.discussions-message-date { font-variant-numeric: tabular-nums; }
.discussions-message-edited {
  font-style: italic; padding: 1px 6px; border-radius: 4px;
  background: rgba(255, 214, 91, 0.20);
}
.discussions-message-body {
  margin: 6px 0 0; word-break: break-word; font-size: 14px; line-height: 1.5;
}
.discussions-message-attachments { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.discussions-attachment {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 8px; background: rgba(255,255,255,0.6); border-radius: 6px;
  border: 1px solid var(--border-soft); font-size: 12px;
}
.discussions-attachment-name { font-weight: 600; color: var(--accent); background: transparent; border: none; cursor: pointer; padding: 0; }
.discussions-attachment-size { color: var(--text-soft); font-variant-numeric: tabular-nums; }
.discussions-message-footer {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 8px; flex-wrap: wrap;
}
.discussions-message-tags { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.discussions-tag {
  font-size: 11px; padding: 2px 8px; border-radius: 999px;
  background: rgba(46, 91, 186, 0.08); color: var(--accent);
  display: inline-flex; align-items: center; gap: 4px;
}
.discussions-tag-remove {
  background: transparent; border: none; color: var(--text-soft);
  cursor: pointer; padding: 0 2px; font-size: 14px; line-height: 1;
}
.discussions-tag-remove:hover { color: var(--text); }
.discussions-tag-picker { position: relative; display: inline-block; }
.discussions-tag-add {
  font-size: 11px; padding: 2px 6px; border-radius: 6px;
  background: transparent; border: 1px dashed var(--border);
  color: var(--text-soft); cursor: pointer;
}
.discussions-tag-menu {
  position: absolute; top: 24px; left: 0; z-index: 10;
  background: #fff; border: 1px solid var(--border);
  border-radius: 8px; padding: 6px; display: flex; flex-direction: column;
  min-width: 140px; box-shadow: 0 4px 12px rgba(0,0,0,0.10);
}
.discussions-tag-menu button {
  background: transparent; border: none; padding: 6px 10px;
  text-align: left; cursor: pointer; border-radius: 4px; font-size: 12px;
}
.discussions-tag-menu button:hover { background: rgba(46, 91, 186, 0.08); }
.discussions-message-actions { display: inline-flex; gap: 6px; }

.discussions-thread-composer {
  display: flex; flex-direction: column; gap: 8px;
  padding-top: 12px; border-top: 1px solid var(--border-soft);
}
.discussions-thread-composer.is-archived { color: var(--text-soft); font-style: italic; }
.discussions-thread-composer-textarea {
  width: 100%; padding: 10px 12px; border-radius: 8px;
  border: 1px solid var(--border); font: inherit; resize: vertical;
  min-height: 60px;
}
.discussions-thread-composer-textarea:focus {
  outline: 2px solid var(--accent); outline-offset: -2px; border-color: var(--accent);
}
.discussions-thread-composer-actions { display: flex; justify-content: flex-end; gap: 8px; align-items: center; }
.discussions-thread-composer-error {
  padding: 8px 12px; background: rgba(214, 72, 87, 0.10);
  color: #a11f2c; border-radius: 6px; font-size: 13px;
}

/* Modale « Nouveau message ».
 * Le sélecteur générique .modal-backdrop (défini plus haut ligne 3434 avec
 * `display: flex`) l'emporte sur le comportement UA de l'attribut `hidden` —
 * il faut donc forcer `display: none` avec `[hidden]` pour que la modale
 * pré-DOM reste HORS écran tant qu'elle n'est pas ouverte. Sans ce forceur,
 * la backdrop et la modale interceptent les clicks sur la liste dès le
 * premier chargement (bug reproduit au 1er run du filet C-ECR-*). */
.modal-backdrop[hidden], .discussions-compose-modal[hidden] { display: none !important; }
#discussions-compose-backdrop { z-index: 1000; }
.discussions-compose-modal {
  position: fixed; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: #fff; padding: 24px; border-radius: 12px;
  width: min(560px, 92vw); max-height: 90vh; overflow-y: auto;
  z-index: 1001; box-shadow: 0 20px 60px rgba(0,0,0,0.25);
}
.discussions-compose-modal h2 { margin: 0 0 12px; font-size: 18px; font-weight: 700; }
.discussions-compose-mode {
  display: flex; gap: 12px; padding: 0; margin: 0 0 12px; border: none;
}
.discussions-compose-mode legend {
  padding: 0; margin-bottom: 6px; font-size: 12px; font-weight: 600;
  color: var(--text-soft);
}
.discussions-compose-mode label { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; }
.discussions-compose-recipients-block {
  margin-bottom: 12px; padding: 10px; background: rgba(0,0,0,0.02); border-radius: 8px;
}
.discussions-compose-recipients-legend {
  font-size: 12px; font-weight: 600; color: var(--text-soft); margin: 0 0 6px;
}
.discussions-compose-recipients {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 200px; overflow-y: auto;
}
.discussions-compose-recipient {
  display: flex; gap: 8px; align-items: center; padding: 4px 6px;
  border-radius: 6px; cursor: pointer;
}
.discussions-compose-recipient:hover { background: rgba(46, 91, 186, 0.05); }
.discussions-compose-error {
  padding: 8px 12px; background: rgba(214, 72, 87, 0.10);
  color: #a11f2c; border-radius: 6px; font-size: 13px; margin-bottom: 8px;
}
.discussions-compose-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
.link.tiny { font-size: 11px; }
.ghost.tiny { font-size: 11px; padding: 2px 6px; }

/* ==========================================================================
 * Modale « Votre espace de stockage » — addendum verdict ÉCRAN 4/09 soir.
 * Ouverte depuis le menu compte (topbar dropdown, entrée entre Tarifs et
 * Mon profil). Une PAGE dédiée avec ventilation par famille + purge ciblée
 * + offre payante d'extension (+10 Go pour 49 €/an) est un chantier à part,
 * gravé au roadmap.
 * ========================================================================== */
.modal-backdrop[hidden].storage-modal-backdrop,
.storage-modal[hidden] { display: none !important; }
.storage-modal-backdrop { z-index: 1000; }
.storage-modal {
  position: fixed; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: #fff; padding: 0; border-radius: 12px;
  width: min(480px, 92vw); max-height: 90vh; overflow-y: auto;
  z-index: 1001; box-shadow: 0 20px 60px rgba(0,0,0,0.25);
}
.storage-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px 12px;
  border-bottom: 1px solid var(--border-soft);
}
.storage-modal-head h2 { margin: 0; font-size: 16px; font-weight: 700; }
.storage-modal-close {
  background: transparent; border: none; color: var(--text-soft);
  padding: 4px; cursor: pointer; border-radius: 6px;
  display: inline-flex; align-items: center;
}
.storage-modal-close:hover { color: var(--text); background: rgba(0,0,0,0.04); }
.storage-modal-body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 8px; }
.storage-modal-row {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 14px; color: var(--text);
}
.storage-modal-label { font-weight: 600; }
.storage-modal-percent { font-weight: 700; color: var(--text); }
.storage-modal-row.is-warning .storage-modal-percent { color: #8a5a07; }
.storage-modal-row.is-critical .storage-modal-percent { color: #a11f2c; }
.storage-modal-bar {
  height: 6px; background: rgba(0,0,0,0.06); border-radius: 999px; overflow: hidden;
}
.storage-modal-bar-fill {
  height: 100%; background: var(--accent); border-radius: 999px;
  transition: width 0.2s ease;
}
.storage-modal-row.is-warning + .storage-modal-bar .storage-modal-bar-fill { background: var(--amber); }
.storage-modal-row.is-critical + .storage-modal-bar .storage-modal-bar-fill { background: #d64857; }
.storage-modal-hint {
  font-size: 12px; color: var(--text-soft);
  margin-top: 4px; line-height: 1.4;
}

/* =========================================================================
   MESSAGERIE v2 « Messenger » — geste M2 (docs/cadrage-discussions-m2.md).
   Cobalt --accent (#3865c8) pour les bulles MIENNES à droite ; neutres avec
   avatar initiales à gauche pour les autres. Deux panneaux (liste gauche +
   fil droite) via CSS grid ; sous 900 px, bascule sur vue seule (liste →
   fil avec bouton retour). AUCUN survol style Messenger (dégradés Meta),
   AUCUNE lib.
   ========================================================================= */

/* Shell 2 panneaux — élargit le .wrap pour laisser respirer la liste. */
main.wrap.discussions-shell {
  max-width: 1360px;
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
  padding: 24px 20px 60px;
}
.discussions-pane {
  background: #fff;
  border: 1px solid var(--border-soft, rgba(0,0,0,0.08));
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.02);
  min-height: 480px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.discussions-pane-left { max-height: calc(100vh - 140px); }
.discussions-pane-right { max-height: calc(100vh - 140px); }

.discussions-pane-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--border-soft, rgba(0,0,0,0.06));
}
.discussions-pane-title { margin: 0; font-size: 18px; font-weight: 700; }
.discussions-pane-head-actions { display: flex; gap: 8px; }

/* Onglets dans le panneau gauche */
.discussions-pane-left .discussions-tabs { padding: 0 10px; }
.discussions-pane-left .discussions-list {
  padding: 8px; overflow-y: auto; flex: 1 1 auto;
}

/* Row de conversation avec avatar rond */
.discussions-row {
  display: flex; gap: 10px; align-items: center;
  padding: 10px 10px; border-radius: 10px;
  cursor: pointer; border: 1px solid transparent; background: transparent;
}
.discussions-row.is-active {
  background: var(--accent-soft, #dce7fb);
  border-color: rgba(56, 101, 200, 0.15);
}
.discussions-row-avatar {
  flex: 0 0 auto;
  width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 15px;
  letter-spacing: 0.4px;
}

/* Panneau DROITE : en-tête, messages, composer */
.discussions-pane-right .discussions-thread-head {
  padding: 14px 18px; gap: 8px;
  border-bottom: 1px solid var(--border-soft, rgba(0,0,0,0.06));
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap;
}
.discussions-pane-right .discussions-thread-messages {
  padding: 16px 18px;
  overflow-y: auto;
  /* M2 retouche B.1 (verdict addendum 7/09) : coupe défensive de tout
     débordement HORIZONTAL au niveau du conteneur ; les fixes ciblés
     ci-dessous (attachment, body) empêchent la cause, l'overflow-x
     hidden est le filet de sécurité. Une assertion scrollWidth <=
     clientWidth (C-M2-no-overflow) verrouille l'invariant. */
  overflow-x: hidden;
  flex: 1 1 auto;
  display: flex; flex-direction: column; gap: 14px;
  min-height: 240px;
}
.discussions-pane-right .discussions-thread-composer {
  padding: 12px 18px 16px;
  border-top: 1px solid var(--border-soft, rgba(0,0,0,0.06));
  display: flex; flex-direction: column; gap: 8px;
}
.discussions-thread-empty {
  padding: 40px 20px; text-align: center;
  color: var(--text-soft, #6a6f7a);
  display: flex; align-items: center; justify-content: center; min-height: 300px;
}

/* Grappes (M2 volet B) — un ensemble de bulles consécutives du même auteur */
.discussions-cluster {
  display: flex; gap: 10px;
  align-items: flex-end; /* avatar et bulles alignés au bas de la grappe */
}
.discussions-cluster.is-mine { flex-direction: row-reverse; }
.discussions-cluster-avatar {
  flex: 0 0 auto;
  width: 32px; height: 32px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 12px; letter-spacing: 0.4px;
}
.discussions-cluster-main {
  display: flex; flex-direction: column; gap: 4px;
  max-width: 72%;
}
.discussions-cluster.is-mine .discussions-cluster-main { align-items: flex-end; }
.discussions-cluster-author {
  font-size: 12px; color: var(--text-soft, #6a6f7a); font-weight: 600;
  margin-left: 12px;
}
.discussions-cluster-time {
  font-size: 11px; color: var(--text-soft, #94989f);
  margin: 2px 12px 0;
}
.discussions-cluster.is-mine .discussions-cluster-time { text-align: right; }
.discussions-cluster-bubbles {
  display: flex; flex-direction: column;
  /* M2 — retour Laurent check-in 7/09 : les bulles consécutives d'une même
     grappe doivent presque se toucher (patron Messenger). gap ~2px suffit. */
  gap: 2px;
}
.discussions-cluster.is-mine .discussions-cluster-bubbles { align-items: flex-end; }

/* Bulle — override de la surface héritée .discussions-message pour l'effet
   Messenger (rectangles arrondis, alignés, sans encadré carré). */
.discussions-pane-right .discussions-message {
  padding: 0; background: transparent; border: 0; border-radius: 0;
  margin: 0;
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 4px;
}
.discussions-pane-right .discussions-message.is-mine { align-items: flex-end; }
.discussions-pane-right .discussions-message.is-mine .discussions-message-body { text-align: left; }

.discussions-bubble {
  position: relative;
  padding: 8px 12px;
  border-radius: 18px;
  background: #eef1f5;
  color: var(--text, #1f232a);
  max-width: 100%;
  word-wrap: break-word;
}
.discussions-message.is-mine .discussions-bubble {
  background: var(--accent, #3865c8);
  color: #fff;
}
.discussions-message-body {
  font-size: 14px; line-height: 1.45;
  white-space: pre-wrap;
  /* M2 retouche B.1 (verdict addendum 7/09) : casse les longs « mots »
     sans espace (patron : filename fallback en body quand l'upload PJ
     n'a pas de texte associé). Sans ça, un nom de fichier long fait
     déborder la bulle → scroll horizontal sur toute la zone messages. */
  overflow-wrap: anywhere;
}

/* Édité, actions, tags — visibles au survol seulement pour rester sobres.
   M2 — retour Laurent check-in 7/09 : max-height + overflow au lieu d'opacity
   pour NE PAS réserver de hauteur quand caché ; les grappes se resserrent. */
.discussions-pane-right .discussions-message-footer {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12px;
  margin: 0 6px;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 0.15s ease, opacity 0.15s ease;
}
.discussions-pane-right .discussions-message:hover .discussions-message-footer,
.discussions-pane-right .discussions-message:focus-within .discussions-message-footer {
  max-height: 32px; opacity: 1;
}
.discussions-pane-right .discussions-message-edited {
  font-size: 11px; color: var(--text-soft, #94989f); font-style: italic;
}
.discussions-pane-right .discussions-message-actions { display: inline-flex; gap: 6px; }

/* PJ — attachées SOUS la bulle (rendu 1 ligne compact) */
.discussions-pane-right .discussions-message-attachments {
  display: flex; flex-direction: column; gap: 4px;
  margin: 4px 6px 0;
}
.discussions-pane-right .discussions-message.is-mine .discussions-message-attachments {
  align-items: flex-end;
}
.discussions-pane-right .discussions-attachment {
  display: inline-flex; align-items: center; gap: 8px;
  background: rgba(0,0,0,0.05); padding: 6px 10px; border-radius: 10px;
  font-size: 12px;
  /* M2 retouche B.1 (verdict addendum 7/09) : la carte PJ ne déborde
     JAMAIS de la grappe (72% max) — sans ça, un long filename étirait
     la ligne PJ et poussait tout le conteneur en scroll horizontal. */
  max-width: 100%; min-width: 0;
}
.discussions-pane-right .discussions-message.is-mine .discussions-attachment {
  background: rgba(56, 101, 200, 0.12);
}
.discussions-pane-right .discussions-attachment-name {
  background: transparent; border: 0; color: var(--accent, #3865c8);
  font-weight: 600; cursor: pointer; padding: 0;
  /* M2 retouche B.1 : ellipse discrète du nom long (le fichier reste
     téléchargeable via le bouton, le tooltip natif du <button title>
     n'est pas posé — on peut l'ajouter si besoin). */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 100%; min-width: 0; text-align: left;
}
.discussions-pane-right .discussions-attachment-size {
  color: var(--text-soft, #6a6f7a); font-variant-numeric: tabular-nums;
}

/* M2 volet C — citation DANS la bulle (rendue cliquable, sauts). Placée
   à l'intérieur pour ne pas entrer en collision avec la reactions-bar
   qui vit au-dessus du bord haut de la bulle (bug attrapé au filet C-M2-
   citation au 1er run — le bar overlapait la citation posée en sibling
   au-dessus de la bulle). */
.discussions-message-quote {
  display: flex; flex-direction: column; gap: 2px;
  padding: 6px 10px;
  margin: 0 0 6px 0;
  border-left: 3px solid var(--accent-strong, #2e5bba);
  background: rgba(0,0,0,0.03);
  border-radius: 6px;
  cursor: pointer;
  max-width: 100%;
  text-align: left;
  font-size: 12px;
  color: var(--text, #1f232a);
  border-top: 0; border-right: 0; border-bottom: 0;
}
/* Citation dans une bulle MIENNE (cobalt) : fond blanc opaque avec texte
   cobalt-foncé pour rester lisible ; sinon la citation « blanche sur cobalt »
   se lit comme un rectangle vide (retour Laurent check-in 7/09). */
.discussions-message.is-mine .discussions-message-quote {
  background: rgba(255,255,255,0.92);
  color: var(--accent-strong, #2e5bba);
  border-left-color: #fff;
}
.discussions-message.is-mine .discussions-message-quote-author { color: var(--accent-strong, #2e5bba); }
.discussions-message.is-mine .discussions-message-quote-body { color: var(--text, #1f232a); opacity: 0.85; }
.discussions-message-quote-author { font-weight: 700; }
.discussions-message-quote-body { opacity: 0.85; }
.discussions-message-quote.is-deleted {
  cursor: not-allowed;
  font-style: italic;
  color: var(--text-soft, #94989f);
}
.discussions-message-quote:hover:not(.is-deleted) { filter: brightness(1.05); }

/* Aperçu citation dans le composer */
.discussions-composer-reply {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 12px;
  border-left: 3px solid var(--accent, #3865c8);
  background: rgba(56, 101, 200, 0.06);
  border-radius: 8px;
  font-size: 12px;
}
.discussions-composer-reply-main {
  flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
}
.discussions-composer-reply-legend {
  color: var(--text-soft, #6a6f7a); font-size: 11px;
}
.discussions-composer-reply-author { font-weight: 700; }
.discussions-composer-reply-body {
  color: var(--text-soft, #6a6f7a);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.discussions-composer-reply-cancel {
  background: transparent; border: 0; cursor: pointer;
  color: var(--text-soft, #6a6f7a); font-size: 18px; line-height: 1;
  padding: 0 4px;
}
.discussions-composer-reply-cancel:hover { color: var(--text, #1f232a); }

/* Saut de citation : surligne brièvement la cible */
.discussions-pane-right .discussions-message.is-jumped .discussions-bubble {
  outline: 2px solid var(--accent, #3865c8);
  outline-offset: 2px;
  transition: outline 0.4s ease;
}

/* F2 R3 (verdict addendum 9/09 soir) — Menu ⋮ par message : remplace le
   bouton Répondre flottant + boutons Modifier/Supprimer/Tag étalés. Un
   seul point d'entrée par message, popover compact. Les data-attributes
   historiques (data-msg-reply/edit/delete/tag-key-add) survivent DANS
   les entrées du menu — la rétro-compat handler délégué est préservée. */
.discussions-message-menu-wrap {
  position: absolute; top: -8px;
  right: -8px;
  z-index: 6;
}
.discussions-message.is-mine .discussions-message-menu-wrap {
  right: auto; left: -8px;
}
.discussions-message-menu-btn {
  background: #fff;
  border: 1px solid var(--border-soft, rgba(0,0,0,0.12));
  border-radius: 50%; width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; opacity: 0; transition: opacity 0.15s ease;
  color: var(--text-soft, #6a6f7a);
  font-size: 16px; line-height: 1;
  box-shadow: 0 2px 4px rgba(0,0,0,0.06);
  pointer-events: none;
  padding: 0;
}
.discussions-message:hover .discussions-message-menu-btn,
.discussions-message:focus-within .discussions-message-menu-btn,
.discussions-message-menu-btn[aria-expanded="true"] {
  opacity: 1; pointer-events: auto;
}
.discussions-message-menu-btn:hover {
  color: var(--accent, #3865c8);
  border-color: var(--accent, #3865c8);
}
/* F2-bis défaut 1 (10/09) — menu ⋮ s'ouvre TOUJOURS vers l'intérieur du
   panneau. Sur OTHER (bulle left-aligned, wrap sur bord DROIT du bubble)
   → menu extends RIGHTWARD (left:0). Sur MINE (bulle right-aligned, wrap
   sur bord GAUCHE du bubble) → menu extends LEFTWARD (right:0). L'ancien
   default `right:0` seul faisait déborder OTHER à gauche sur bulle courte ;
   l'ancien override MINE `left:0` faisait déborder MINE à droite sur bulle
   courte. Nouvelle grammaire : direction toujours interior-side. */
.discussions-message-menu {
  position: absolute; top: 28px;
  left: 0;
  right: auto;
  background: #fff;
  border: 1px solid var(--border-soft, rgba(0,0,0,0.10));
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  min-width: 180px; max-width: 260px;
  padding: 6px;
  display: flex; flex-direction: column;
  z-index: 20;
}
.discussions-message.is-mine .discussions-message-menu {
  left: auto;
  right: 0;
}
.discussions-message-menu[hidden] { display: none; }
.discussions-message-menu-item {
  background: transparent; border: 0; cursor: pointer;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--text, #1f232a);
  display: flex; align-items: center; gap: 10px;
  text-align: left;
}
.discussions-message-menu-item:hover {
  background: rgba(0, 0, 0, 0.05);
}
.discussions-message-menu-item.is-danger {
  color: #c92a2a;
}
.discussions-message-menu-item.is-danger:hover {
  background: rgba(201, 42, 42, 0.08);
}
.discussions-message-menu-item-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; font-size: 14px; line-height: 1;
  color: var(--text-soft, #6a6f7a);
}
.discussions-message-menu-item.is-danger .discussions-message-menu-item-icon {
  color: #c92a2a;
}
.discussions-message-menu-sep {
  border: 0; border-top: 1px solid var(--border-soft, rgba(0,0,0,0.08));
  margin: 4px 6px;
}
.discussions-message-menu-tag-header {
  font-size: 11px;
  color: var(--text-soft, #6a6f7a);
  font-weight: 600;
  padding: 6px 12px 2px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.discussions-message-menu-tags {
  display: flex; flex-wrap: wrap; gap: 4px; padding: 0 8px 4px;
}
.discussions-message-menu-tag-btn {
  background: rgba(0, 0, 0, 0.05);
  border: 0; border-radius: 999px;
  padding: 4px 10px;
  font-size: 11px;
  cursor: pointer;
  color: var(--text, #1f232a);
}
.discussions-message-menu-tag-btn:hover {
  background: rgba(56, 101, 200, 0.12);
  color: var(--accent-strong, #2e5bba);
}

/* Bouton Répondre — flottant sur le bord droit de la bulle, visible au
   survol seulement. On accroche la position à la bulle (position:relative
   déjà posée par la structure), pas au message, pour ne pas déborder dans
   la zone du cluster voisin qui interceptait les clics.
   F2 R3 : ce bouton n'est plus rendu par renderBubble (migré dans menu ⋮).
   Les règles ci-dessous restent au cas où un ancien rendu resterait —
   inertes en pratique. */
.discussions-bubble-reply {
  position: absolute; top: -8px;
  right: -8px;
  background: #fff;
  border: 1px solid var(--border-soft, rgba(0,0,0,0.12));
  border-radius: 50%; width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; opacity: 0; transition: opacity 0.15s ease;
  color: var(--text-soft, #6a6f7a);
  font-size: 12px; line-height: 1;
  box-shadow: 0 2px 4px rgba(0,0,0,0.06);
  z-index: 5;
  pointer-events: none;
}
.discussions-message.is-mine .discussions-bubble-reply { right: auto; left: -8px; }
.discussions-message:hover .discussions-bubble-reply,
.discussions-message:focus-within .discussions-bubble-reply {
  opacity: 1; pointer-events: auto;
}
.discussions-bubble-reply:hover { color: var(--accent, #3865c8); border-color: var(--accent, #3865c8); }

/* M2 volet D — barre 6 émojis au survol.
   F2-bis défaut 2 (10/09) : la barre était centrée sur la bulle (left:50% +
   translateX(-50%)) — sur bulle COURTE right-aligned MINE, la moitié droite
   dépassait le bord droit du panneau. Nouvelle règle : ancrage à l'INTÉRIEUR
   du panneau — bord gauche de la bulle sur OTHER, bord droit sur MINE.
   La barre reste à hauteur -34px, décor + interactions inchangés. */
.discussions-reactions-bar {
  position: absolute; top: -34px;
  left: 8px;
  right: auto;
  transform: none;
  background: #fff;
  border: 1px solid var(--border-soft, rgba(0,0,0,0.1));
  border-radius: 20px;
  padding: 4px 6px;
  display: flex; gap: 4px;
  opacity: 0; pointer-events: none;
  transition: opacity 0.15s ease;
  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  z-index: 10;
}
.discussions-message.is-mine .discussions-reactions-bar {
  left: auto;
  right: 8px;
}
.discussions-message:hover .discussions-reactions-bar,
.discussions-message:focus-within .discussions-reactions-bar {
  opacity: 1; pointer-events: auto;
}
.discussions-reactions-bar-btn {
  background: transparent; border: 0; cursor: pointer;
  font-size: 18px; padding: 2px 4px; border-radius: 6px; line-height: 1;
}
.discussions-reactions-bar-btn:hover { background: rgba(0,0,0,0.06); }

/* Agrégats de réactions sous la bulle */
.discussions-reactions-agg {
  display: inline-flex; gap: 4px; flex-wrap: wrap;
  margin: 4px 8px 0;
}
.discussions-reactions-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: rgba(0,0,0,0.05);
  border: 1px solid transparent;
  padding: 2px 8px; border-radius: 999px;
  font-size: 12px; cursor: pointer;
}
.discussions-reactions-chip.is-mine {
  background: var(--accent-soft, #dce7fb);
  border-color: var(--accent, #3865c8);
  color: var(--accent-strong, #2e5bba);
  font-weight: 700;
}
.discussions-reactions-chip-emoji { line-height: 1; font-size: 14px; }
.discussions-reactions-chip-count { font-variant-numeric: tabular-nums; }

/* Vu par N sous la dernière bulle mienne */
.discussions-message-seen {
  font-size: 11px; color: var(--text-soft, #94989f);
  margin: 2px 8px 0; text-align: right;
}

/* Panneau Fichiers partagés (modale) — mêmes couches que la modale compose
   (backdrop z-index 1000, modal z-index 1001, position: fixed centrée, sinon
   .modal héritée reste sous la backdrop et bloque les clics — bug attrapé
   par le filet C-M2-fichiers au 1er run). */
#discussions-files-backdrop { z-index: 1000; }
.discussions-files-modal[hidden] { display: none !important; }
.discussions-files-modal {
  position: fixed; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: #fff; padding: 20px 24px; border-radius: 12px;
  width: min(640px, 92vw); max-height: 90vh; overflow-y: auto;
  z-index: 1001; box-shadow: 0 20px 60px rgba(0,0,0,0.25);
}
.discussions-files-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px;
}
.discussions-files-head h2 { margin: 0; font-size: 18px; font-weight: 700; }
.discussions-files-list {
  display: flex; flex-direction: column; gap: 6px;
  max-height: 50vh; overflow-y: auto;
}
.discussions-file-row {
  display: grid; grid-template-columns: 1fr auto auto auto;
  gap: 12px; align-items: center;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--border-soft, rgba(0,0,0,0.06));
  font-size: 13px;
}
.discussions-file-row:hover { background: rgba(56, 101, 200, 0.04); }
.discussions-file-name {
  background: transparent; border: 0; color: var(--accent, #3865c8);
  font-weight: 600; cursor: pointer; padding: 0; text-align: left;
}
.discussions-file-size,
.discussions-file-author,
.discussions-file-date {
  color: var(--text-soft, #6a6f7a); font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.discussions-files-empty { padding: 20px; text-align: center; }

/* PURGE-PJ (05/10/2026) §2.4 — pied admin de la modale Fichiers partagés.
   Zone séparée de la liste par une bordure supérieure. 2 boutons (Télécharger,
   Supprimer en rouge). En mode confirmation, texte + 2 boutons (Annuler,
   Confirmer en rouge). Membre non admin : la zone n'est jamais rendue. */
.discussions-files-purge-zone {
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--border-soft, rgba(0,0,0,0.08));
  display: flex; flex-direction: column; gap: 10px;
}
.discussions-files-purge-total {
  color: var(--text-soft, #6a6f7a); font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.discussions-files-purge-actions {
  display: flex; gap: 10px; justify-content: flex-end;
}
.discussions-files-purge-actions .danger {
  background: var(--danger, #d64545); color: #fff;
  border: 1px solid transparent;
}
.discussions-files-purge-actions .danger:hover:not([disabled]) {
  background: var(--danger-hover, #b43636);
}
.discussions-files-purge-actions .danger[disabled] {
  opacity: 0.5; cursor: not-allowed;
}
.discussions-files-purge-confirm-text {
  margin: 0; color: var(--text, #1a1a1a); font-size: 14px;
}

/* PURGE-PJ (05/10/2026) §2.4 — trace de PJ purgée dans une bulle. Patron
   visuel .discussions-message-quote.is-deleted (italique, muted). Classe
   racine DISTINCTE de .discussions-attachment (option α amendée — rétros
   intacts par construction). */
.discussions-attachment-trace {
  display: block; padding: 6px 10px;
  color: var(--text-soft, #6a6f7a); font-style: italic;
  font-size: 12px;
  border-left: 3px solid var(--border-soft, rgba(0,0,0,0.12));
  background: rgba(0,0,0,0.02); border-radius: 4px;
  margin-top: 4px;
}

/* Marche.js — bouton Discussion sur la fiche marché (volet G, chirurgical) */
.fiche-header-quick-actions .fiche-discussion-btn {
  /* rien de spécifique — hérite du style .ghost.small */
}

/* M2 retouche B.3 (verdict addendum 7/09) : boutons icon-only en en-tête
   du fil — carré compact, aria-label + title pour l'accessibilité. */
.discussions-pane-right .discussions-thread-head-actions .icon-only {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 6px 8px; min-width: 34px; height: 32px;
  line-height: 1; color: var(--text-soft, #6a6f7a);
}
.discussions-pane-right .discussions-thread-composer-actions .icon-only {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 6px 8px; min-width: 34px; height: 32px;
  line-height: 1; color: var(--text-soft, #6a6f7a);
}
.discussions-pane-right .icon-only:hover { color: var(--accent, #3865c8); }

/* M2 retouche B.5 (verdict addendum 7/09) : alignement propre du choix
   de mode dans la modale Nouveau message — chaque label sur SA ligne
   avec radio + libellé sur la MÊME ligne (fini le rond orphelin entre
   les deux). Réutilise la disposition en colonne du fieldset. */
.discussions-compose-mode {
  display: flex; flex-direction: column; gap: 8px;
  padding: 0; margin: 0 0 12px; border: 0;
}
.discussions-compose-mode legend {
  padding: 0; margin: 0 0 6px; font-weight: 600; font-size: 13px;
  color: var(--text-soft, #6a6f7a);
}
.discussions-compose-mode label {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 6px 10px; border-radius: 8px;
}
.discussions-compose-mode label:hover { background: rgba(56, 101, 200, 0.06); }
.discussions-compose-mode input[type="radio"] {
  /* M2 B.5bis (verdict 7/09 soir, œil-nu Laurent Chrome) : neutralise
   * `input, select, textarea { width:100%; padding:10px 12px; border:... }`
   * (style.css:720) qui étirait le radio à ~260 px et détachait son libellé.
   * Miroir strict `.partenaires-scope-tile input[type="radio"]` (style.css:9677)
   * et `.launch-piece-row > input[type="radio"]` (style.css:4647). */
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  padding: 0;
  border: none;
  margin: 0;
  vertical-align: middle;
  accent-color: var(--primary);
}

/* F1 volet A (8/09 après-midi, œil-nu Laurent live) — MÊME défaut que B.5bis
 * sur les CASES à cocher de la liste Destinataires : la globale
 * `input, select, textarea { width:100%; padding:10px 12px }` (style.css:720)
 * étirait la case au milieu de son label. Miroir strict de B.5bis (ci-dessus),
 * appliqué au sélecteur wrappant du picker (compose modal ET participant
 * picker partagent la classe `.discussions-compose-recipient`). Le
 * `.discussions-compose-recipient` était déjà `display: flex; align-items:
 * center` — la case + le libellé étaient donc sameLine=true par CSS parent,
 * il ne restait qu'à neutraliser width/padding/border sur l'input. */
.discussions-compose-recipient input[type="checkbox"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  padding: 0;
  border: none;
  margin: 0;
  vertical-align: middle;
  accent-color: var(--primary);
}

/* F1 volet C (8/09 après-midi, œil-nu Laurent live) — `.discussions-tab-badge`
 * définit `display: inline-flex` (style.css:12678) qui a la MÊME spécificité
 * qu'`.discussions-tab-badge[hidden]` en attribut-selector (=0,2,0 > 0,1,0
 * seul), mais le browser applique le PLUS SPÉCIFIQUE — pas assez pour battre
 * l'attribut `hidden` du HTML qui, sans règle, donne `display: none` par
 * defaut UA (spécificité 0,0,0). Résultat : le badge reste visible même quand
 * le JS pose `hidden` → « point bleu permanent » constaté par Laurent.
 * Fix minimal : règle attribut-selector qui force `display: none`. La
 * spécificité (0,0,2,0) écrase `.discussions-tab-badge` (0,0,1,0). */
.discussions-tab-badge[hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   F2 volet A — RESTYLE MESSENGER (le fil qui ressemble enfin a Messenger)
   Cadrage : docs/cadrage-messagerie-f2.md §0.1 + §1.A
   Reference : docs/refs/reference-messenger-m2.png (capture Laurent)
   Principes :
   - Coins ASYMETRIQUES par POSITION de bulle dans sa grappe (is-first /
     is-mid / is-last / is-solo) — signature visuelle Messenger.
   - Cobalt charte GARDE cote « mine » (jamais dégradé Meta, grave M2).
   - Gris cote « other » plus doux (#eef1f5 → #eaeef3, +2 pts plus clair).
   - Rythme vertical INCHANGE (gap 2px intra-grappe, 14px inter-grappe —
     hérités M2, déjà serrés).
   - Horodatage plus discret (opacité ↓, poids ↓).
   ADDITIF strict — les classes existantes .discussions-bubble et border-radius:
   18px du fallback survivent. Les regles ci-dessous, plus spécifiques
   (.discussions-message.is-first.is-mine .discussions-bubble), l'emportent. */

/* Coins par position × cote — patron Messenger : le coin « colle » (4 px)
   du cote de la bulle adjacente meme auteur, le coin « libre » reste rond
   (18 px). MINE (droite) : pointe a droite. OTHER (gauche) : pointe a gauche. */

/* MINE — pointe à droite */
.discussions-pane-right .discussions-message.is-mine.is-solo .discussions-bubble {
  border-radius: 18px;
}
.discussions-pane-right .discussions-message.is-mine.is-first .discussions-bubble {
  border-radius: 18px 18px 4px 18px;
}
.discussions-pane-right .discussions-message.is-mine.is-mid .discussions-bubble {
  border-radius: 18px 4px 4px 18px;
}
.discussions-pane-right .discussions-message.is-mine.is-last .discussions-bubble {
  border-radius: 18px 4px 18px 18px;
}

/* OTHER — pointe à gauche (mirroir strict) */
.discussions-pane-right .discussions-message:not(.is-mine).is-solo .discussions-bubble {
  border-radius: 18px;
}
.discussions-pane-right .discussions-message:not(.is-mine).is-first .discussions-bubble {
  border-radius: 18px 18px 18px 4px;
}
.discussions-pane-right .discussions-message:not(.is-mine).is-mid .discussions-bubble {
  border-radius: 4px 18px 18px 4px;
}
.discussions-pane-right .discussions-message:not(.is-mine).is-last .discussions-bubble {
  border-radius: 4px 18px 18px 18px;
}

/* Gris « other » plus doux (mesure : #eef1f5 v1 → #eaeef3 F2).
   Décalage +2 pts plus clair, plus proche du ton Messenger neutre.
   Le cobalt « mine » reste STRICT charte (var --accent, #3865c8). */
.discussions-pane-right .discussions-message:not(.is-mine) .discussions-bubble {
  background: #eaeef3;
}

/* Horodatage plus discret : opacité ↓ à 0.75, poids allégé. La couleur
   var(--text-soft) reste inchangée (pas de dérive charte). */
.discussions-cluster-time {
  opacity: 0.75;
}

/* ═══════════════════════════════════════════════════════════════════════════
   F2 volet B — VIGNETTES d'images dans la bulle + LIGHTBOX à la main
   Cadrage : §0.2 + §1.B — img blob:, jamais token en URL, dimensions bornées,
   clic RÉEL → lightbox, Escape ferme. Coexiste avec les cartes fichiers
   non-image existantes (.discussions-attachment sans .discussions-attachment-image). */

/* Conteneur d'une PJ image dans une bulle. Hérite `.discussions-attachment`
   (contrainte max-width, min-width — évite débordement horizontal M2 B.1) ;
   on override le padding/bg pour laisser l'image respirer. */
.discussions-pane-right .discussions-attachment.discussions-attachment-image {
  background: transparent;
  padding: 0;
  border-radius: 12px;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.discussions-pane-right .discussions-message.is-mine
  .discussions-attachment.discussions-attachment-image {
  background: transparent;
  align-items: flex-end;
}

/* Le bouton vignette (clic → lightbox) : reset natif, cadre soft, image
   contenue avec dimensions bornées. */
.discussions-image-thumb {
  display: inline-block;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: zoom-in;
  border-radius: 12px;
  overflow: hidden;
  line-height: 0;
  /* Bornes : la vignette ne s'étale jamais plus que 280×280 px, respecte
     l'aspect ratio du fichier (object-fit: cover garde la vignette carrée
     sans distordre). Fallback si `<img src>` pas encore hydraté : cadre
     gris avec dimension minimale. */
  min-width: 120px; min-height: 120px;
  max-width: 280px; max-height: 280px;
}
.discussions-image-thumb:hover { filter: brightness(0.98); }
.discussions-image-thumb:focus-visible {
  outline: 2px solid var(--accent, #3865c8);
  outline-offset: 2px;
}
.discussions-image-thumb img {
  display: block;
  width: 100%; height: 100%;
  max-width: 280px; max-height: 280px;
  object-fit: cover;
  background: #eaeef3; /* fallback visuel avant hydratation blob */
  border-radius: 12px;
}
/* Meta (poids fichier + delete) : petite ligne sous la vignette, discrète. */
.discussions-image-thumb-meta {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11px;
}

/* Lightbox : overlay plein écran, backdrop sombre semi-transparent, image
   centrée max 90vw/90vh. Bouton fermer en haut-droite. Fait à la main
   (aucune lib), fermé par backdrop, croix, ou Escape (handler global). */
#discussions-lightbox-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.85);
  z-index: 2000;
}
#discussions-lightbox-backdrop[hidden] { display: none; }
#discussions-lightbox {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2001;
  max-width: 92vw;
  max-height: 92vh;
  display: flex; align-items: center; justify-content: center;
}
#discussions-lightbox[hidden] { display: none; }
#discussions-lightbox-img {
  max-width: 92vw;
  max-height: 92vh;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
/* F2 R1 — Actions lightbox (Télécharger + Fermer) groupées en haut-droite. */
#discussions-lightbox-actions {
  position: fixed; top: 20px; right: 24px;
  display: flex; gap: 8px;
  z-index: 2002;
}
#discussions-lightbox-close,
#discussions-lightbox-download {
  background: rgba(255, 255, 255, 0.9);
  border: 0;
  width: 36px; height: 36px;
  border-radius: 50%;
  font-size: 22px; line-height: 1;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  color: #1f232a;
}
#discussions-lightbox-close:hover,
#discussions-lightbox-download:hover {
  background: #fff;
}
#discussions-lightbox-download { font-size: 20px; }

/* F2 R1 — bouton Télécharger sous la vignette dans la bulle (patron
   .link tiny neutralisé pour intégration ligne méta). */
.discussions-pane-right .discussions-image-thumb-download {
  background: transparent; border: 0; cursor: pointer;
  color: var(--accent, #3865c8);
  font-size: 11px;
  padding: 0;
  text-decoration: underline;
  font-weight: 500;
}
.discussions-pane-right .discussions-image-thumb-download:hover {
  color: var(--accent-strong, #2e5bba);
}

/* ═══════════════════════════════════════════════════════════════════════════
   F2 volet C — ICÔNES TYPÉES par extension (sur carte fichier bulle ET modale
   Fichiers partagés) + MODALE FICHIERS restylée (vignettes images + icônes
   typées + lignes aérées + en-tête propre).
   Cadrage : §0.3 + §1.C + précision Laurent check-in A+B 9/09 (icône aussi
   sur carte bulle, pas seulement dans la modale). */

/* Badge icône typée : rectangle coloré compact avec label 2-3 lettres.
   Reconnaissance universelle (PDF/DOC/XLS/PPT/ZIP/TXT) sans dépendance
   graphique. Type inconnu → variante générique (trombone gris). */
.discussions-file-type-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 44px;
  color: #fff; font-weight: 700; font-size: 10px;
  border-radius: 4px;
  letter-spacing: 0.5px;
  flex: 0 0 auto;
  line-height: 1;
}
.discussions-file-type-icon.is-generic {
  background: rgba(0, 0, 0, 0.06);
  color: var(--text-soft, #6a6f7a);
  width: 32px; height: 32px;
}

/* Sur la carte fichier DANS la bulle : l'icône vit à gauche du nom. Le
   .discussions-attachment est déjà `inline-flex align-items:center gap:8px`
   (M2), donc l'icône s'insère naturellement en tête. */
.discussions-pane-right .discussions-attachment .discussions-file-type-icon {
  width: 28px; height: 32px; font-size: 9px;
}
.discussions-pane-right .discussions-attachment .discussions-file-type-icon.is-generic {
  width: 24px; height: 24px;
}

/* Modale Fichiers partagés restylée — lignes aérées, vignette/icône à gauche,
   nom + méta en colonne à droite. On override le grid v1 (grid-template-
   columns v2) en flex. */
.discussions-files-list .discussions-file-row {
  display: flex; align-items: center; gap: 12px;
  grid-template-columns: none; /* neutralise le grid v1 */
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--border-soft, rgba(0, 0, 0, 0.06));
  font-size: 13px;
}
.discussions-files-list .discussions-file-row:hover {
  background: rgba(56, 101, 200, 0.04);
}
.discussions-file-thumb {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: 8px;
  overflow: hidden;
  background: #eaeef3;
}
.discussions-file-thumb img {
  width: 44px; height: 44px;
  object-fit: cover;
  display: block;
}
.discussions-file-row-main {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.discussions-file-row-main .discussions-file-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 100%;
}
.discussions-file-row-sub {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  color: var(--text-soft, #6a6f7a); font-size: 12px;
}
.discussions-file-sub-dot { opacity: 0.5; }

/* ═══════════════════════════════════════════════════════════════════════════
   F2 volet D — SÉLECTEUR DESTINATAIRES : recherche + chips retirables
   (§0.4 + §1.D). Les checkboxes v1 restent en place et mesurables (garde
   F1-checkbox préservée par construction) — chips = miroir dynamique. */

.discussions-compose-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 0 8px 0;
  min-height: 0;
}
.discussions-compose-chips:empty { margin: 0; }
.discussions-compose-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 4px 4px 10px;
  border-radius: 999px;
  background: rgba(56, 101, 200, 0.1);
  border: 1px solid rgba(56, 101, 200, 0.25);
  color: var(--accent-strong, #2e5bba);
  font-size: 12px;
  font-weight: 600;
  max-width: 100%;
}
.discussions-compose-chip-label {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 180px;
}
.discussions-compose-chip-remove {
  background: transparent; border: 0; cursor: pointer;
  width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 16px; line-height: 1;
  color: var(--accent-strong, #2e5bba);
  padding: 0;
}
.discussions-compose-chip-remove:hover {
  background: rgba(56, 101, 200, 0.18);
}

.discussions-compose-search-wrap {
  display: block;
  margin: 0 0 8px 0;
}
.discussions-compose-search {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border-soft, rgba(0, 0, 0, 0.12));
  border-radius: 8px;
  font-size: 13px;
  background: #fff;
}
.discussions-compose-search:focus {
  outline: 2px solid var(--accent, #3865c8);
  outline-offset: -1px;
  border-color: transparent;
}
.discussions-compose-search-empty {
  padding: 8px 0 0 4px;
  font-size: 12px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CONVERSATIONS À SUJET (10/09/2026) — champ Objet FACULTATIF dans la modale
   Nouveau message + sous-ligne interlocuteur/badge sous le titre principal
   quand un objet existe (§2 cadrage). Décisions Laurent §0 gravées :
   sans objet → comportement inchangé, avec objet → création systématique. */

.discussions-compose-subject-wrap {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 12px 0 8px 0;
}
.discussions-compose-subject-label {
  font-size: 12px;
  color: var(--text-soft);
  font-weight: 500;
}
.discussions-compose-subject {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border-soft, rgba(0, 0, 0, 0.12));
  border-radius: 8px;
  font-size: 14px;
  background: #fff;
}
.discussions-compose-subject:focus {
  outline: 2px solid var(--accent, #3865c8);
  outline-offset: -1px;
  border-color: transparent;
}
.discussions-row-subject-subline {
  color: var(--text-soft);
  font-size: 12px;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.discussions-thread-subject-subline {
  color: var(--text-soft);
  font-size: 13px;
  margin-top: 4px;
  font-weight: 400;
  /* Parent `.discussions-thread-head-main` est en `display:flex; flex-wrap:wrap`
     — sans flex-basis:100% la sous-ligne s'aligne à droite du H2 au lieu de
     descendre. Force le passage à la ligne pour tenir le contrat visuel
     (sous-ligne SOUS le titre, mesuré au check-in). */
  flex-basis: 100%;
}

/* ═══════════════════════════════════════════════════════════════════════════
   F2 volet E — PJ dès la modale premier message (§0.5 + §1.E). Ligne compacte
   trombone + preview (nom + poids + ×) sous le textarea, au-dessus de la
   ligne d'erreurs. Réutilise le patron fallback filename côté client
   (contrat serveur body_required inchangé). */

.discussions-compose-attach-row {
  display: flex; align-items: center; gap: 8px;
  margin: 4px 0 0 0;
  min-height: 32px;
}
.discussions-compose-attach-preview[hidden] { display: none; }
.discussions-compose-attach-preview {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 4px 4px 10px;
  background: rgba(56, 101, 200, 0.06);
  border: 1px solid rgba(56, 101, 200, 0.2);
  border-radius: 999px;
  font-size: 12px;
  min-width: 0; max-width: 100%;
}
.discussions-compose-attach-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 240px; min-width: 0;
  font-weight: 600;
  color: var(--accent-strong, #2e5bba);
}
.discussions-compose-attach-size {
  color: var(--text-soft, #6a6f7a);
  font-variant-numeric: tabular-nums;
}
.discussions-compose-attach-remove {
  background: transparent; border: 0; cursor: pointer;
  width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 16px; line-height: 1;
  color: var(--accent-strong, #2e5bba);
  padding: 0;
}
.discussions-compose-attach-remove:hover {
  background: rgba(56, 101, 200, 0.18);
}
/* Bouton trombone : neutralise le style .icon-only global déjà utilisé dans
   la topbar du fil, tient dans la ligne compose. */
.discussions-compose-modal .icon-only {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 6px 8px; min-width: 34px; height: 32px;
  line-height: 1; color: var(--text-soft, #6a6f7a);
}
.discussions-compose-modal .icon-only:hover { color: var(--accent, #3865c8); }

/* ═══════════════════════════════════════════════════════════════════════════
   Fin F2 volets A + B + C + D + E */

/* F2-bis défaut 3 (10/09) — bulle « vide » de dédoublonnage.
   Un message dont le body est dédoublonné (body === filename) ET qui n'a PAS
   de citation ne doit PAS afficher le cadre `.discussions-bubble` : la PJ et
   ses métadonnées suffisent. On garde le `.discussions-bubble` dans le DOM
   (position: relative sert d'ancre aux flottants menu ⋮ / reactions-bar),
   mais on neutralise son rendu visuel : padding 0, background transparent,
   radius 0 → pilule cobalt VIDE disparaît. Rétro : `[data-msg-body][hidden]
   [data-body-hidden-dup="1"]` reste mesurable (garde C-F2-dedoublon). */
.discussions-bubble.is-empty-shell {
  padding: 0;
  background: transparent;
  color: inherit;
  border-radius: 0;
  min-height: 0;
}
.discussions-message.is-mine .discussions-bubble.is-empty-shell {
  background: transparent;
  color: inherit;
}

/* Responsive : sous 900 px, bascule vue liste OU fil (patron simple).
   On garde les IDs stables ; c'est le CSS qui masque le panneau non-actif. */
@media (max-width: 900px) {
  main.wrap.discussions-shell {
    grid-template-columns: 1fr;
  }
  main.wrap.discussions-shell.is-thread-open .discussions-pane-left { display: none; }
  main.wrap.discussions-shell:not(.is-thread-open) .discussions-pane-right { display: none; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   Geste PHOTOS DE PROFIL (11/09/2026) — bloc photo de la page Mon profil +
   avatar photo dans grappes conversations, chips équipe marché, topbar.
   ───────────────────────────────────────────────────────────────────────────── */

/* Bloc Mon profil : aperçu rond + boutons + helper.
   Retour Laurent check-in passe 1 : le rond doit être IDENTIQUE à celui de
   la topbar (patron .account-avatar l.7435) — le background couleur est porté
   par le PARENT via inline style, pas par un enfant. Le span initials ne rend
   que le texte, centré par les règles flex du parent. */
.user-photo-row {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 12px;
}
.user-photo-preview {
  position: relative;
  width: 96px; height: 96px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--panel, #f3f4f7);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* background couleur posé inline par renderPhotoPreview() quand pas de
     photo (miroir strict topbar .account-avatar). */
}
.user-photo-preview img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.user-photo-preview #user-photo-initials {
  color: #fff;
  font: 600 32px/1 var(--sans);
  letter-spacing: 0.02em;
  /* Pas de width/height 100% — le PARENT porte la couleur, le span centré
     par flex du parent (align-items+justify-content:center). Miroir strict
     .account-avatar topbar. */
}
.user-photo-preview.has-photo #user-photo-initials { display: none; }
.user-photo-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}
/* Retour Laurent check-in passe 1 : le label upload doit rendre comme le
   bouton primaire de la page (Enregistrer). Le sélecteur existant
   `button.primary` (l.764) est STRICT sur <button> — il ne matche pas <label>.
   Duplique les styles ici pour aligner le rendu. */
.user-photo-controls .user-photo-upload-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: 500 14px var(--sans);
  cursor: pointer;
  border: none;
  border-radius: var(--radius-s);
  padding: 10px 18px;
  background: var(--primary);
  color: #ffffff;
  box-shadow: 0 2px 6px -1px rgba(79,78,145,0.35), 0 1px 0 rgba(255,255,255,0.06) inset;
  transition: background .15s ease, box-shadow .15s ease, transform .05s ease;
}
.user-photo-controls .user-photo-upload-btn:hover {
  background: var(--primary-strong);
  box-shadow: 0 4px 12px -2px rgba(79,78,145,0.45);
}
.user-photo-controls .user-photo-upload-btn:active { transform: translateY(1px); }
.user-photo-controls .muted.small { margin: 0; }
#user-photo-status:not(:empty) { margin-top: 4px; }
#user-photo-status.error { color: var(--danger, #c92a2a); }
#user-photo-status.success { color: var(--success, #0ca678); }

/* Grappe conversations (OTHER) : avatar rond, photo cover ou initiales.
   La classe .discussions-cluster-avatar existait déjà pour les initiales ; on
   ne fait qu'ajouter le sous-cas image (structure additive). */
.discussions-cluster-avatar.has-photo {
  padding: 0;
  overflow: hidden;
  background: transparent !important;
}
.discussions-cluster-avatar.has-photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}

/* Chip équipe marché (memberChip) : miroir de l'avatar cluster — photo cover
   ou initiales. La classe .team-chip existait déjà. */
.team-chip.has-photo {
  padding: 0;
  overflow: hidden;
  background: transparent !important;
}
.team-chip.has-photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}

/* Topbar : miroir sur .account-avatar. */
.account-avatar.has-photo {
  padding: 0;
  overflow: hidden;
  background: transparent !important;
}
.account-avatar.has-photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}
