/* Sagacitix Prospecting — station d'écoute (pas de framework, aucune ressource tierce)

   Le produit n'est pas un CRM : il guette le moment où une marque lance quelque chose.
   D'où deux partis pris qui expliquent tout le reste de cette feuille :
   1. L'ÂGE d'un signal prime sur son score. Le score est bruité — mesuré le 13 août :
      27 % des scores bougent entre deux runs, ±13 points. La couleur saturée est donc
      réservée à la fraîcheur (rampe --h0..--h3), la seule donnée objective ; le score,
      lui, redevient un nombre en mono avec un filet de niveau.
   2. La DA Avrelios (avrelios.com) : papier, encre, et l'orange réservé à ce
      qui décide — ici, l'âge du signal. Rien d'autre n'a le droit d'être saturé, sinon le
      filet ne se voit plus. */

/* Trois rôles, aucun system-ui, aucun Inter, tout auto-hébergé (CSP `default-src 'self'`,
   et un panel qui ne doit rien à un CDN). Sous-jeu latin uniquement : 100 ko en tout. */
@font-face { font-family: "Plex Sans"; src: url("/static/fonts/plex-sans-var.woff2") format("woff2");
             font-weight: 400 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Plex Cond"; src: url("/static/fonts/plex-cond-600.woff2") format("woff2");
             font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Plex Cond"; src: url("/static/fonts/plex-cond-700.woff2") format("woff2");
             font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Avrelios"; src: url("/static/fonts/manrope-latin.woff2") format("woff2");
             font-weight: 800; font-style: normal; font-display: swap; }   /* le logo seul */
@font-face { font-family: "Plex Mono"; src: url("/static/fonts/plex-mono-400.woff2") format("woff2");
             font-weight: 400; font-style: normal; font-display: swap; }

/* Palette Avrelios (relevée sur avrelios.com le 15 nov. 2026, refonte orange) : le panel
   appartient à Avrelios. Papier, encre, et l'orange réservé à ce qui décide : la couleur
   saturée reste à la fraîcheur d'un signal et au bouton d'action. Les --hX-t sont les versions texte (≥ 4,6:1 sur le papier). */
:root {
  --papier: #F8F7F3;      /* crème de la DA — jamais blanc, c'est ce qui fait le grain */
  --encre: #191B18;       /* bleu-noir des blocs pleins du deck, pas un noir pur */
  --trait: #DDDED6;
  --action: #191B18;      /* boutons primaires : le bloc d'encre, comme la carte DÉCISION */
  /* Rampe de chaleur : la fraîcheur d'un signal, et rien d'autre.
     Un post à J-13 est de l'or, le même à J-172 est mort.
     h0 est l'orange de marque — le signal le plus frais porte la couleur qui décide. */
  --h0: #F26643;  --h1: #E98A5E;  --h2: #C9A27A;  --h3: #B3B4AC;
  /* Versions encre des mêmes teintes, pour le TEXTE : les vives passent en filet (AA
     n'exige rien d'un trait de 3 px) mais pas en glyphe. Toutes ≥ 4,6:1 sur le papier. */
  --h0-t: #A8401F; --h1-t: #9A4A22; --h2-t: #7D6440; --h3-t: #63665F;

  /* Noms historiques, gardés pour que les 700 lignes de composants ci-dessous suivent
     la nouvelle palette sans être réécrites une à une. */
  --bg: var(--papier);
  --surface: #FFFFFF;
  --border: var(--trait);
  /* Le deck sépare les deux noirs : le bleu-noir sert aux aplats (barre, boutons pleins),
     le texte est en noir neutre. En glyphe fin, l'encre bleutée tire visiblement au bleu
     sur le crème — un tableau de chiffres en mono suffit à le rendre criant. */
  --text: #191B18;
  --muted: #686A63;
  --primary: var(--action);
  --primary-dark: #363A33;
  --primary-soft: #EEEDE6;
  --green: #1C793F;  --green-bg: #E6F0E8;   /* vert du badge « strong fit » : validation seule */
  --amber: #836412;  --amber-bg: #FAF1E2;
  --red: #C0264C;    --red-bg: #FBE7E9;
  --side: #191B18;       /* l'encre du pied de page avrelios.com */
  /* 4 px : un registre a des angles, pas des galets. 10 px était le rayon par défaut
     du gabarit « dashboard SaaS » qu'on quitte. */
  --radius: 4px;
  /* Plus d'ombres portées : les tableaux SONT le produit, ils tiennent par leur trait.
     La variable reste (elle est référencée partout) mais ne dessine plus rien. */
  --shadow: none;
}
* { box-sizing: border-box; }
/* `hidden` doit l'emporter sur le `display` d'un composant : `.btn` est en
   inline-block, donc un bouton masqué en JS restait affiché. */
[hidden] { display: none !important; }
body { margin: 0; font-family: "Plex Sans", system-ui, sans-serif;
       background: var(--bg); color: var(--text); font-size: 15px; line-height: 1.45;
       display: flex; min-height: 100vh; }
/* Chiffres, dates, J-118, scores, ids, montants : en mono et en chasse fixe. Alignés en
   colonne, c'est un gain de lecture réel — on compare des ordres de grandeur d'un coup
   d'œil au lieu de lire chaque nombre. */
.mono, .num, .score, .age, .kpi b, .e-pas b, .chip b, .facette-n, .ac-chip b, .ac-row b,
.conv-meta, .barre-dossier b, .compteur, .progress small, .pager .muted,
input[type=number], td.num, table.docs td.num {
  font-family: "Plex Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; }

/* ---- Sidebar ---- */
/* Quatre entrées pour trois moments de travail (choisir qui viser → voir un signal →
   écrire et suivre), plus les réglages en pied de barre : ils ne sont pas du travail
   quotidien et n'ont rien à faire au même rang qu'un écran qu'on ouvre tous les jours. */
aside { width: 200px; flex-shrink: 0; position: sticky; top: 0; height: 100vh;
        display: flex; flex-direction: column; gap: 4px; padding: 18px 10px 14px;
        background: var(--side); color: #DEDDD4; }
/* Le logo d'avrelios.com : la marque (deux traits en « A ») et le mot « Avrelios » en Manrope
   800, sa police. Le panel appartient à Avrelios ; « for Sagacitix » dit pour qui. */
.brand { display: flex; align-items: center; gap: 9px; color: #fff; text-decoration: none;
         font-family: "Avrelios", "Plex Sans", sans-serif; font-weight: 800; font-size: 23px;
         letter-spacing: -0.06em; padding: 2px 6px 18px; line-height: 1.05; }
.brand small { display: block; font-family: "Plex Cond", sans-serif; font-weight: 600;
               color: #A3A59C; font-size: 11px; text-transform: uppercase; letter-spacing: 0.14em; }
.logo { width: 22px; height: 24px; flex-shrink: 0; fill: currentColor; }
aside nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }
aside nav a { display: flex; align-items: center; gap: 10px; color: #DEDDD4; text-decoration: none;
              font-family: "Plex Cond", sans-serif; font-weight: 600; font-size: 15px;
              text-transform: uppercase; letter-spacing: 0.05em;
              padding: 9px 10px; border-radius: 3px; }
aside nav a:hover { background: rgb(255 255 255 / 8%); color: #fff; }
aside nav a.active { background: rgb(255 255 255 / 12%); color: #fff; font-weight: 700;
                     box-shadow: inset 3px 0 0 var(--h0); }
aside nav svg, .side-logout svg { width: 17px; height: 17px; fill: none; stroke: currentColor;
       stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
/* `aside` en tête de sélecteur : `.btn`, déclaré plus bas, gagnait la cascade et repeignait
   ce bouton en blanc plein — un aplat qui écrasait toute la barre d'encre. */
aside .side-new { margin: 10px 2px; text-align: center; background: rgb(255 255 255 / 10%);
                  border: 1px solid rgb(255 255 255 / 22%); color: #fff; }
aside .side-new:hover { background: rgb(255 255 255 / 18%); border-color: rgb(255 255 255 / 30%); }
.side-logout { display: flex; align-items: center; gap: 10px; color: #8A8C83; text-decoration: none;
               font-size: 13px; padding: 8px 10px; border-radius: var(--radius); }
.side-logout:hover { background: rgb(255 255 255 / 8%); color: #fff; }
.side-logout.active { background: rgb(255 255 255 / 12%); color: #fff;
                      box-shadow: inset 3px 0 0 #fff; }

.content { flex: 1; min-width: 0; }
/* large : les tableaux du panel ont jusqu'à 8 colonnes, un cadre à 1220px les tronquait
   alors qu'il restait 500 px de marge vide sur un écran 1920 */
main { max-width: 1560px; margin: 0 auto; padding: 26px 26px 60px; }

/* Titres et étiquettes de section : condensé, capitales resserrées. C'est la voix du
   registre — elle nomme, elle ne raconte pas. Le corps de texte, lui, reste en Plex Sans. */
h1, h2, h3, th, .onglets a, .facette > summary, .btn, legend {
  font-family: "Plex Cond", "Plex Sans", system-ui, sans-serif; }
/* La DA affirme ses titres : capitales très grasses, serrées, posées sur deux lignes sans
   presque d'interligne. Plex Cond 700 est la graisse la plus lourde qu'on héberge — on lui
   donne le serrage et l'échelle du deck plutôt qu'une police de plus à télécharger. */
h1 { font-size: 28px; margin: 4px 0 4px; font-weight: 700;
     text-transform: uppercase; letter-spacing: -0.005em; line-height: 1.02; }
h2 { font-size: 17px; margin: 30px 0 10px; font-weight: 600;
     text-transform: uppercase; letter-spacing: 0.05em; color: var(--text); }
.sub { color: var(--muted); margin: 0 0 18px; font-size: 14px; max-width: 78ch; }
/* Le complément d'un titre est une phrase, pas une étiquette : il garde sa casse. Sinon
   « — du plus récent au plus ancien, fais défiler pour l'historique » passe en capitales
   et devient illisible. */
h1 .muted-h, h2 .muted-h, h1 small, h2 small { text-transform: none; letter-spacing: 0; }
.muted { color: var(--muted); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden;
                   clip-path: inset(50%); white-space: nowrap; }
.muted-h { color: var(--muted); font-weight: 400; font-size: 13px; }
.strong { font-weight: 600; color: var(--text); }
a.strong { text-decoration: none; }
a.strong:hover { color: var(--primary); }
/* Les liens sans classe prenaient le bleu par défaut du navigateur — invisible sur l'ancien
   papier froid, criard sur le crème. Ils passent à l'encre soulignée, et à l'orange au
   survol : la seule couleur que la DA accorde à ce qu'on s'apprête à ouvrir. */
main a, main a:visited { color: var(--text); text-decoration-color: var(--border);
                         text-underline-offset: 2px; }
main a:hover { color: var(--h0-t); text-decoration-color: currentColor; }

/* ---- KPIs ---- */
/* Plafond à 215 px : en `1fr`, trois indicateurs se partageaient les 1 186 px du cadre et
   chaque carte faisait 390 px pour porter un nombre à deux chiffres. Une carte d'indicateur
   a la taille de ce qu'elle affiche ; le reste de la ligne est du blanc, pas du remplissage.
   215 et non 250 : à cinq cartes (l'accueil), 250 débordait de 64 px et la cinquième
   retombait seule sur une deuxième ligne — 5 × 215 + 4 × 14 de gouttière = 1 131. */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 215px));
        gap: 14px; margin: 18px 0 20px; }
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
       padding: 15px 18px; box-shadow: var(--shadow); text-decoration: none; color: inherit; display: block; }
.kpi b { display: block; font-size: 25px; letter-spacing: -0.02em; color: var(--text); }
.kpi span { color: var(--muted); font-size: 13px; }
.kpi.accent { border-color: #DEDDD4; background: linear-gradient(180deg, #FFFFFF, #F1F0EA); }
.kpi.accent b { color: var(--primary); }
a.kpi:hover { border-color: var(--primary); }

/* ---- Distribution des scores ---- */
.dist { display: flex; gap: 3px; margin: 4px 0 14px; border-radius: var(--radius); overflow: hidden;
        font-size: 12px; font-weight: 600; }
.dist span { padding: 5px 10px; white-space: nowrap; text-align: center; min-width: max-content; }
/* Entonnoir d'une mission : N leads → contactés → relancés → réponses. Contrairement à
   `.dist`, les marches ne sont PAS proportionnelles — 62 → 0 écraserait tout le reste, et
   c'est le chiffre qui compte, pas la surface. */
.entonnoir { display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
             margin: 4px 0 14px; font-size: 13px; }
.e-pas { display: inline-flex; align-items: baseline; gap: 6px; padding: 6px 12px;
         border-radius: var(--radius); background: var(--surface); border: 1px solid var(--border); }
.e-pas b { font-size: 17px; font-weight: 700; }
.e-pas small { color: var(--muted); font-size: 12px; }
.e-fin { background: #E6F0E8; border-color: #BFD8C6; color: var(--green); }
.e-attente { background: var(--amber-bg); border-color: var(--amber); color: var(--amber);
             margin-left: 6px; }
/* une marche jamais atteinte reste lisible mais ne se donne pas l'air d'un résultat */
.e-vide { color: var(--muted); background: transparent; }
.e-vide b { font-weight: 600; }
.e-fleche { color: var(--muted); }
/* Répartition des scores : en gris, du plus dense au plus clair. Elle était en vert/ambre,
   c'est-à-dire dans la couleur réservée à la fraîcheur — et elle donnait au score une
   autorité que son bruit (27 % d'écart entre deux runs) ne justifie pas. */
.d-hi  { background: #CFCFC6; color: var(--text); }
.d-ok  { background: #DDDED6; color: var(--text); }
.d-mid { background: #E7E7E0; color: var(--muted); }
.d-lo  { background: #F0EFE9; color: var(--muted); }

/* ---- Cards & tables ---- */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
        padding: 16px 18px; margin-bottom: 18px; box-shadow: var(--shadow); }
/* Panneau de données : hauteur bornée + overflow auto sur les deux axes. C'est ce qui rend
   l'en-tête `sticky` réellement collant (sans conteneur scrollable, `top: 0` ne fait rien)
   et ce qui permet de figer la colonne d'actions à droite. */
.tablewrap { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
             max-height: calc(100vh - 120px); overflow: auto; box-shadow: var(--shadow); }
table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
/* 11 px et non 14 : sur un tableau à 7 colonnes, 3 px de gouttière en moins de chaque côté
   rendent 42 px à la ligne — assez pour que Signaux tienne dans le cadre au lieu de passer
   la moitié de sa colonne « Contenu » sous la colonne d'actions figée. Un registre est dense,
   c'est ce qui permet d'en voir beaucoup d'un coup. */
th, td { text-align: left; padding: 10px 11px; border-bottom: 1px solid #E7E7E0; white-space: nowrap;
         background: var(--surface); }
tbody tr:last-child td { border-bottom: none; }
td.wrap { white-space: normal; min-width: 220px; max-width: 420px; }
/* texte long tenu sur une ligne : garde des lignes de tableau de hauteur régulière
   et empêche une seule colonne (raisons sociales à rallonge) d'étirer tout le tableau */
td.ellip span { display: block; max-width: 185px; overflow: hidden;
                text-overflow: ellipsis; white-space: nowrap; }
/* poste et email : 185 px coupait « Managing Director, Head o… » et
   « christophe_cerisier@yaho… » — on ne savait plus qui on cochait (retour du 7 août).
   ⚠️ Le `max-width` du span ne RÉSERVE rien : la mise en page du tableau écrasait la colonne
   dès que la fenêtre se resserrait (127 px et 29 postes coupés sur 50 en 1280 px, mesuré le
   10 août). C'est la cellule qui doit poser un plancher — `min-width` —, le `max-width` du
   span n'étant plus qu'un plafond pour ne pas étirer le tableau. */
td.ellip.large { min-width: 340px; }
td.ellip.large span { max-width: 340px; white-space: normal; display: -webkit-box;
                      -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
th { color: var(--muted); font-weight: 600; font-size: 12px;
     text-transform: uppercase; letter-spacing: 0.06em; position: sticky; top: 0; z-index: 2;
     background: #F0EFE9; border-bottom-color: var(--border); }
/* journal long (historique des runs) : plus court que la hauteur d'écran par défaut */
.tablewrap.scroll { max-height: 320px; }
th.check, td.check { width: 34px; padding-right: 4px; }
/* colonne d'actions figée à droite : reste visible même quand le tableau défile
   horizontalement — l'action principale ne doit jamais sortir de l'écran */
th.act, td.act { position: sticky; right: 0; z-index: 1;
                 box-shadow: -10px 0 12px -10px rgb(25 27 24 / 25%); }
th.act { z-index: 3; }
tbody tr:hover td { background: #F0EFE9; }
.cell-sub { display: block; color: var(--muted); font-size: 13px; margin-top: 1px; }
.empty { color: var(--muted); padding: 26px; text-align: center; white-space: normal; }
.err-text { color: var(--red); font-size: 13px; }

/* ---- Buttons ---- */
.btn { display: inline-block; border: 1px solid var(--border); border-radius: var(--radius);
       background: var(--surface); color: var(--text); padding: 8px 15px; font-size: 14px;
       font-weight: 600; cursor: pointer; text-decoration: none; font-family: inherit;
       transition: background .12s, border-color .12s; }
.btn:hover { background: #F0EFE9; border-color: #C4C5BC; }
/* Le bouton d'appel d'avrelios.com (`.button.orange`) : orange, texte encre. */
.btn.primary { background: var(--h0); border-color: var(--h0); color: var(--encre); font-weight: 700; }
.btn.primary:hover { background: #FF815E; border-color: #FF815E; }
/* Le trait redevient neutre : « Écarter » est sur chaque ligne du tableau, et bordé de rose
   il tirait l'œil autant que le filet de fraîcheur. Le mot rouge suffit à le désigner. */
.btn.danger { background: var(--surface); border-color: var(--border); color: var(--red); }
.btn.danger:hover { background: var(--red-bg); }
.btn.small { padding: 5px 12px; font-size: 13px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
button.btn { line-height: 1.45; }

/* ---- Forms ---- */
form.inline, .inline { display: flex; gap: 12px; align-items: end; flex-wrap: wrap; }
.stack { margin-bottom: 14px; }
label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 4px; font-weight: 500; }
.checkline { display: flex; align-items: center; gap: 7px; margin: 0 0 9px; font-size: 14px;
             color: var(--text); cursor: pointer; }
/* cases à cocher d'un filtre : empilées, alignées sur le bas des champs voisins */
.inline .checks { display: flex; flex-direction: column; gap: 4px; padding-bottom: 7px; }
.inline .checks .checkline { margin: 0; }
/* `search` fait partie de la liste depuis le 10 août : sans lui, le champ « L'entreprise
   fait… » de /entreprises restait à sa largeur intrinsèque (~155 px) au milieu d'un champ
   étiré, alors que c'est la recherche principale de l'écran. */
input[type=text], input[type=search], input[type=email], input[type=password],
input[type=number], input[type=date], select, textarea {
  border: 1px solid #C4C5BC; border-radius: var(--radius); padding: 8px 11px; font-size: 14px;
  font-family: inherit; background: var(--surface); color: var(--text); width: 100%; }
input:focus-visible, select:focus-visible, textarea:focus-visible, .btn:focus-visible {
  outline: 2px solid var(--h0-t); outline-offset: 1px; border-color: var(--primary); }
.field { min-width: 190px; flex: 1; max-width: 270px; }
.field.wide { max-width: 520px; flex: 2; }
/* bornes numériques (CA, effectif) et code postal : un champ pleine largeur pour 5 chiffres
   étirerait la barre de filtres sur trois lignes de plus */
.field.narrow { min-width: 108px; max-width: 132px; }
/* listes déroulantes à libellés longs (secteur, sous-secteur, prestation) : les 270 px de
   `.field` coupaient « Matériels électroniques et informatique professionnelle » (55 signes)
   — dans le champ fermé comme dans le menu, que Chrome cale sur la largeur du select. */
/* La part d'un champ dans une ligne qui enveloppe se calcule sur sa `flex-basis`, pas sur
   son `max-width` : à base égale avec les autres filtres, le sous-secteur retombait à
   254 px utiles pour 387 px de texte (mesuré au navigateur).
   436 px de champ = 390 px utiles, soit le plus long libellé de la nomenclature
   (« Matériels électroniques et informatique professionnelle », 387 px).
   `min(…, 100%)` : sur un écran étroit le champ redevient fluide au lieu de déborder. */
.field.large { flex: 1 1 440px; min-width: min(436px, 100%); max-width: 480px; }
/* bloc de filtres repliable : il porte sa propre barre, sans l'encadré d'une .card */
.filters-more { margin-top: 4px; width: 100%; }
.filters-more > summary { padding: 6px 0; }
.filters-more .inline { margin-top: 8px; }
/* ---- Saisie assistée d'entreprise (Lead Explorer) ---- */
.autoco { position: relative; }
.autoco .ac-chips:not(:empty) { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 5px; }
.ac-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
           padding: 3px 5px 3px 10px; border-radius: 999px; background: var(--primary-soft);
           border: 1px solid #DEDDD4; color: var(--text); font-size: 13px; font-weight: 600; }
.ac-chip b { color: var(--muted); font-weight: 600; font-variant-numeric: tabular-nums; }
.ac-x { border: none; background: none; cursor: pointer; font-family: inherit; font-size: 15px;
        line-height: 1; padding: 1px 4px; border-radius: 50%; color: var(--muted); }
.ac-x:hover { background: #fff; color: var(--red); }
/* le menu était calé sur la largeur du champ (`right: 0`) : « CAISSE REGIONALE DE … » et
   « CREDIT AGRICOLE CO… » se ressemblaient tous, on choisissait à l'aveugle (retour du
   7 août). Il prend maintenant la largeur de son contenu, et les noms trop longs passent
   à la ligne au lieu d'être coupés. */
.ac-menu { position: absolute; top: 100%; left: 0; right: auto; z-index: 60; margin-top: 4px;
           min-width: 100%; width: max-content; max-width: min(620px, 90vw);
           background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
           box-shadow: 0 12px 32px rgb(25 27 24 / 18%); max-height: 330px; overflow-y: auto;
           padding: 4px; }
.ac-row { display: flex; align-items: baseline; gap: 10px; width: 100%; text-align: left;
          border: none; background: none; cursor: pointer; font-family: inherit; font-size: 13px;
          padding: 7px 9px; border-radius: var(--radius); color: var(--text); }
.ac-row span { flex: 1; min-width: 0; white-space: normal; overflow-wrap: anywhere; }
.ac-row b { color: var(--muted); font-weight: 600; font-size: 13px;
            font-variant-numeric: tabular-nums; }
.ac-row small { color: var(--muted); font-weight: 500; }
.ac-row small::before { content: "· "; }
.ac-row:hover, .ac-row.on { background: var(--primary-soft); }
/* correspondances « commence par », dépliées à la demande : présentes mais visiblement
   secondaires, c'est le rang qui ramenait EDITIONS BELIN sur une recherche « bel » */
.ac-row.faible { color: var(--muted); }
.ac-plus, .ac-note { display: block; width: 100%; text-align: left; font-family: inherit;
                     font-size: 13px; color: var(--muted); padding: 8px 9px; margin: 0;
                     border: none; background: none; }
.ac-plus { border-top: 1px solid var(--border); cursor: pointer; }
.ac-plus:hover { color: var(--primary); }

/* select posé directement dans une barre d'action (sans .field) : ne pas l'étirer */
.inline > select { width: auto; min-width: 200px; max-width: 260px; }
input[type=checkbox] { width: 15px; height: 15px; accent-color: var(--primary); }
textarea { resize: vertical; }

/* ---- Flash / badges / score ---- */
.flash { position: relative; border-radius: var(--radius); padding: 11px 40px 11px 15px; margin-bottom: 16px;
         font-weight: 500; font-size: 14px; }
.flash button { position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
                border: none; background: none; color: inherit; opacity: .55; cursor: pointer;
                font-size: 17px; line-height: 1; padding: 4px 8px; border-radius: var(--radius); font-family: inherit; }
.flash button:hover { opacity: 1; background: rgb(0 0 0 / 6%); }
.flash.ok { background: var(--green-bg); color: var(--green); border: 1px solid #BFD8C6; }
.flash.err { background: var(--red-bg); color: var(--red); border: 1px solid #EFC4C9; }
.flash.info { background: var(--primary-soft); color: var(--primary-dark); border: 1px solid #DEDDD4; }
/* bandeau de nouveauté : le lien d'action reste dans le fil du texte, seule la croix est à droite */
.flash .lien { position: static; transform: none; opacity: 1; font-size: inherit; font-weight: 600;
               color: var(--h0-t); padding: 0 0 0 6px; }
.flash .lien:hover { background: none; text-decoration: underline; }
/* page « Connecter Claude » */
.prerequis { list-style: none; padding: 0; margin: 0 0 18px; display: flex; flex-wrap: wrap; gap: 8px 22px; }
.prerequis li { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.prerequis li::before { content: "✓"; font-weight: 700; color: var(--green); }
.prerequis li.manque::before { content: "!"; color: var(--h0-t); }
.prerequis span { color: var(--muted); }
.connecteurs { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr)); gap: 16px; max-width: 1100px; }
.connecteurs h2 { margin-top: 0; }
.etapes { margin: 0; padding-left: 22px; display: grid; gap: 12px; font-size: 14px; line-height: 1.5; }
.etapes li::marker { font-weight: 700; color: var(--h0-t); }
.copie { display: flex; gap: 8px; margin: 6px 0; }
.copie input { flex: 1; min-width: 0; font-family: "Plex Mono", ui-monospace, monospace; font-size: 13px; }
.exemples { margin: 0; padding-left: 18px; color: var(--muted); font-size: 14px; line-height: 1.8; }

.badge { display: inline-flex; align-items: center; gap: 6px; border-radius: 999px; padding: 2px 10px;
         font-size: 12px; font-weight: 600; background: #E7E7E0; color: #686A63; }
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge.active, .badge.success { background: var(--green-bg); color: var(--green); }
.badge.running, .badge.queued, .badge.paused { background: var(--amber-bg); color: var(--amber); }
.badge.error, .badge.canceled { background: var(--red-bg); color: var(--red); }
/* Lead que le prochain run sautera parce qu'il a été scrapé récemment : ce n'est pas une
   erreur, mais ça doit se voir — sinon le lead semble simplement absent du run. */
.badge.skip { background: var(--amber-bg); color: var(--amber); white-space: nowrap; }
.small-note { font-size: 12px; }

/* Statut de mission modifiable d'un clic (liste + fiche) : même allure qu'un .badge,
   mais c'est un <select> — la pastille et le chevron sont portés par le formulaire */
.status-pick { position: relative; display: inline-flex; align-items: center; vertical-align: middle;
               border-radius: 999px; background: #E7E7E0; color: #686A63; }
.status-pick.active { background: var(--green-bg); color: var(--green); }
.status-pick.paused { background: var(--amber-bg); color: var(--amber); }
.status-pick::before { content: ""; position: absolute; left: 10px; width: 6px; height: 6px;
                       border-radius: 50%; background: currentColor; pointer-events: none; }
.status-pick::after { content: "▾"; position: absolute; right: 9px; font-size: 11px;
                      opacity: .75; pointer-events: none; }
.status-pick select { appearance: none; -webkit-appearance: none; border: none; background: none;
                      color: inherit; font: inherit; font-size: 12px; font-weight: 600;
                      line-height: 1.45; padding: 3px 22px; border-radius: 999px; cursor: pointer; }
.status-pick:hover { filter: brightness(.96); }
.status-pick select:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
/* le menu déroulant natif hérite sinon de la couleur d'état : illisible sur fond blanc */
.status-pick option { color: var(--text); background: var(--surface); }

/* ---- Progression (Sélection IA : avancement sur la base d'entreprises) ---- */
.progress { display: flex; align-items: center; gap: 10px; margin: 6px 0 2px; }
.progress-bar { flex: 1; max-width: 320px; height: 6px; border-radius: 3px;
                background: #E1E1D9; overflow: hidden; }
/* min-width : un avancement de 0,1 % doit rester visible, sinon la barre paraît vide */
.progress-bar i { display: block; height: 100%; min-width: 3px; border-radius: 3px;
                  background: linear-gradient(90deg, #191B18, #1C793F); }
.progress-bar i[style*="width: 0%"] { min-width: 0; }
.progress-bar.done i { background: var(--green); }
/* durée inconnue (import Apify) : va-et-vient plutôt qu'un pourcentage inventé */
.progress-bar.indeterminate { max-width: 100%; }
.progress-bar.indeterminate i { width: 35%; animation: slide 1.4s ease-in-out infinite; }
@keyframes slide { 0% { margin-left: -35%; } 100% { margin-left: 100%; } }
@media (prefers-reduced-motion: reduce) { .progress-bar.indeterminate i { animation: none; width: 100%; } }
.progress small { color: var(--muted); font-variant-numeric: tabular-nums; }
/* même jauge en version compacte dans une cellule de tableau */
td .progress-bar { width: 90px; max-width: 90px; height: 5px; }

/* ---- Zone de danger (actions irréversibles, écartées des actions courantes) ---- */
.danger-zone { border-color: #EFC4C9; background: linear-gradient(180deg, #FFFFFF, var(--red-bg)); }
.danger-zone b { display: block; margin-bottom: 3px; }
.danger-zone p { color: var(--muted); font-size: 13px; margin: 0 0 13px; max-width: 560px; }

.score { display: inline-block; min-width: 38px; text-align: center; border-radius: var(--radius);
         padding: 3px 8px; font-weight: 700; font-size: 13px; }
.score.hi  { background: #E6F0E8; color: #16632F; }
.score.ok  { background: #E6F0E8; color: var(--green); }
.score.mid { background: var(--amber-bg); color: var(--amber); }
.score.lo  { background: #EEEDE6; color: var(--muted); }

/* ---- Login ---- */
/* La couverture du deck : le crème, et le halo orange flou qui déborde du cadre. C'est le
   seul effet de toute la DA, et cette page est le seul écran qui a la place de le porter. */
body.login-page { display: grid; place-items: center; background: var(--papier); }
body.login-page::before { content: ""; position: fixed; inset: 0; z-index: 0;
  background: radial-gradient(circle at 84% 62%, var(--h0) 0%,
              rgb(242 102 67 / 45%) 22%, rgb(242 102 67 / 0%) 52%); }
.login-card { position: relative; z-index: 1;
              background: var(--surface); border-radius: var(--radius); padding: 34px 34px 26px;
              width: min(380px, 92vw); box-shadow: 0 20px 50px rgb(25 27 24 / 14%); text-align: center; }
.login-card h1 { margin: 14px 0 2px; }
.login-card .sub { margin-bottom: 22px; }
.login-card h1 + form, .login-card h1 + .flash { margin-top: 22px; }
.login-card form { text-align: left; }
/* Rien ne style les liens globalement dans ce fichier : chaque contexte pose le sien. Sur
   cette carte, un lien bleu souligné du navigateur casserait le seul écran qui porte la DA
   en entier. Même traitement discret que `.selcount a`. */
.login-card a { color: var(--muted); text-decoration: none; border-bottom: 1px solid transparent; }
.login-card a:hover { color: var(--encre); border-bottom-color: currentColor; }
.login-brand { display: flex; justify-content: center; }
.login-brand .brand { color: var(--encre); padding: 0; text-align: left; }
.login-brand .brand small { color: var(--muted); }


.rowform { display: inline-flex; gap: 4px; align-items: center; }

/* ---- Notifications ---- */
.notif { position: relative; }
.notif button { width: 100%; border: none; background: none; cursor: pointer; font-family: inherit; }
.notif-badge { background: var(--h0); color: var(--encre); border-radius: var(--radius); padding: 0 7px;
               font-size: 11px; font-weight: 700; line-height: 18px; margin-left: auto; }
.notif-panel { position: absolute; bottom: 42px; left: 8px; z-index: 50; width: 300px;
               background: var(--surface); color: var(--text); border: 1px solid var(--border);
               border-radius: var(--radius); box-shadow: 0 12px 32px rgb(0 0 0 / 25%);
               max-height: 340px; overflow-y: auto; }
/* Le filet gauche porte le statut, comme sur les toasts : c'est ce qui a remplacé
   les ✅ / ❌ / ⏳ qui ouvraient chaque ligne. */
.notif-item { display: flex; justify-content: space-between; gap: 10px; align-items: baseline;
              padding: 10px 13px 10px 10px; border-bottom: 1px solid #E7E7E0; font-size: 13px;
              border-left: 3px solid transparent;
              color: var(--text); text-decoration: none; white-space: normal; }
.notif-item:last-child { border-bottom: none; }
.notif-item.ok  { border-left-color: #1C793F; }
.notif-item.err { border-left-color: var(--red); }
.notif-item.run { border-left-color: var(--amber); }
a.notif-item:hover { background: #F0EFE9; }
.notif-item small { color: var(--muted); flex-shrink: 0; }

.toasts { position: fixed; right: 18px; bottom: 18px; z-index: 100; display: flex;
          flex-direction: column; gap: 10px; max-width: 360px; }
.toast { background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--primary);
         border-radius: var(--radius); padding: 12px 15px; font-size: 14px; box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
         opacity: 0; transform: translateY(8px); transition: opacity .3s, transform .3s; }
.toast.show { opacity: 1; transform: none; }
.toast.ok { border-left-color: #1C793F; }
.toast.err { border-left-color: var(--red); }
.toast.run { border-left-color: var(--amber); }

@media (max-width: 860px) {
  .notif-panel { bottom: auto; top: 42px; left: auto; right: 0; }
}

/* ---- Filtres en pastilles (Conversations) ---- */
.filters .chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 13px;
                  padding-bottom: 13px; border-bottom: 1px solid var(--border); }
.chip { display: inline-flex; align-items: center; gap: 8px; padding: 6px 13px; border-radius: 999px;
        border: 1px solid var(--border); background: var(--surface); color: var(--muted);
        font-size: 13px; font-weight: 600; text-decoration: none; white-space: nowrap;
        transition: border-color .12s, background .12s; }
.chip:hover { border-color: #C4C5BC; background: #F0EFE9; }
.chip b { color: var(--text); font-variant-numeric: tabular-nums; }
.chip::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--c, #A3A59C); }
.chip.all::before { display: none; }
.chip.on { background: var(--side); border-color: var(--side); color: #DEDDD4; }
.chip.on b { color: #fff; }
/* filtre sans résultat : montré (l'information « 0 à traiter » compte) mais non cliquable */
.chip.void { opacity: .5; pointer-events: none; }
.tag { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
       color: var(--muted); background: #EEEDE6; border-radius: var(--radius); padding: 2px 6px; }

/* ---- Liste des conversations ---- */
/* --c / --c-soft : couleur d'état, portée par la ligne et reprise par le rail, l'avatar et le badge */
.convlist { display: flex; flex-direction: column; gap: 9px; }
.conv { --c: #5A6F68; --c-soft: #E7E7E0;
        position: relative; display: flex; align-items: center; gap: 14px;
        padding: 13px 16px 13px 19px; background: var(--surface); border: 1px solid var(--border);
        border-radius: var(--radius); box-shadow: var(--shadow); text-decoration: none;
        color: inherit; overflow: hidden; transition: border-color .12s, box-shadow .12s; }
.conv::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--c); }
/* Le survol d'une ligne la faisait DÉCOLLER de la page (deux ombres portées de 22 px) —
   le geste du gabarit « carte SaaS » qu'on a quitté partout ailleurs. Une ligne de registre
   ne lévite pas : elle prend le fond de survol des tableaux et son filet d'état s'affirme. */
.conv:hover { border-color: var(--c); background: #F0EFE9; }
.conv:focus-visible { outline: 2px solid var(--h0-t); outline-offset: 2px; }
.st-reply    { --c: var(--green); --c-soft: var(--green-bg); }
.st-draft    { --c: var(--amber); --c-soft: var(--amber-bg); }
.st-followup { --c: var(--h0-t);      --c-soft: var(--red-bg); }

.avatar { flex-shrink: 0; display: grid; place-items: center; width: 38px; height: 38px;
          border-radius: var(--radius); background: var(--c-soft); color: var(--c);
          font-weight: 700; font-size: 13px; }
.avatar.big { width: 52px; height: 52px; border-radius: var(--radius); font-size: 17px; }
.conv-main { flex: 1; min-width: 0; }
.conv-name { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.conv-name b { font-size: 15px; letter-spacing: -0.01em; }
.conv-org { color: var(--muted); font-size: 13px; }
.conv-preview { display: flex; align-items: baseline; gap: 7px; margin-top: 2px;
                color: var(--muted); font-size: 13px; }
.conv-preview i { font-style: normal; font-weight: 700; color: var(--c); flex-shrink: 0; }
.conv-preview span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv-preview em { font-style: normal; font-weight: 500; color: var(--text); }
.conv-side { flex-shrink: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }
.conv-meta { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.badge.b-state { background: var(--c-soft); color: var(--c); }
/* jauge de relance : jours écoulés sur les 5 qui déclenchent une relance */
.meter { width: 64px; height: 3px; border-radius: 2px; background: #E1E1D9; overflow: hidden; }
.meter i { display: block; height: 100%; background: var(--c); }

.empty-state { text-align: center; padding: 40px 24px; }
.empty-state b { display: block; font-size: 17px; margin-bottom: 5px; }
.empty-state p { color: var(--muted); margin: 0 auto 16px; max-width: 430px; font-size: 14px; }

/* ---- Connexion Gmail ---- */
.gmail { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.gmail .gmail-txt { flex: 1; min-width: 260px; }
.gmail .gmail-txt b { display: block; }
.gmail .gmail-txt .sub { margin: 3px 0 0; }
.gmail .actions { display: flex; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.gmail.off { border-color: #E0CDA0; background: linear-gradient(180deg, #FFFFFF, var(--amber-bg)); }
.gmail-dot { flex-shrink: 0; width: 9px; height: 9px; border-radius: 50%;
             background: var(--green); box-shadow: 0 0 0 4px var(--green-bg); }
.off .gmail-dot { background: var(--amber); box-shadow: 0 0 0 4px var(--amber-bg); }
/* même information en une ligne discrète sur la fiche d'un lead */
.gmail-line { display: flex; align-items: center; gap: 9px; margin: -6px 0 14px; }
/* Barre d'état (Conversations) : connexion Gmail + mode d'envoi en une seule ligne. Ces deux
   informations doivent être visibles en permanence, mais elles ne sont pas le sujet de la
   page — leurs réglages vivent sur /reglages. */
.barre { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 16px;
         padding: 9px 14px; font-size: 13px; color: var(--muted); background: var(--surface);
         border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); }
.barre b { color: var(--text); font-weight: 600; }
.barre .fin { margin-left: auto; }
.barre.off { background: var(--amber-bg); border-color: #E0CDA0; color: var(--amber); }
.barre.off b { color: var(--amber); }

/* pièces jointes d'un message (le fichier reste chez Gmail) */
.files { list-style: none; margin: 9px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.files li { display: flex; align-items: baseline; gap: 8px; font-size: 13px; }
.files small { color: var(--muted); font-variant-numeric: tabular-nums; }

/* langue du mail, collée au bouton de génération */
.lang-pick select { padding: 7px 9px; font-size: 13px; width: auto; }

/* ---- Fil de conversation (page lead) ---- */
.lead-head { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.lead-head h1 { margin: 0; }
.lead-head .sub { margin: 2px 0 0; }
.lead-head .who { flex: 1; min-width: 240px; }
.lead-head .actions { display: flex; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.lead-facts { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 8px;
              font-size: 13px; color: var(--muted); }

.thread { display: flex; flex-direction: column; gap: 14px; margin: 4px 0 22px; }
.msg { max-width: min(660px, 90%); background: var(--surface); border: 1px solid var(--border);
       border-radius: var(--radius); padding: 11px 16px 13px; box-shadow: var(--shadow); }
.msg-out { align-self: flex-end; background: var(--primary-soft); border-color: #DEDDD4;
           border-bottom-right-radius: 4px; }
.msg-in { align-self: flex-start; border-left: 3px solid var(--green); border-bottom-left-radius: 4px; }
.msg-head { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; margin-bottom: 7px;
            font-size: 13px; color: var(--muted); }
.msg-head b { color: var(--text); font-size: 13px; }
.msg-subject { font-weight: 600; margin-bottom: 3px; }
.msg-body { white-space: pre-wrap; margin: 0; color: var(--text); font-size: 14px; }
/* Prompt assemblé (aperçu de /mail-ai) : c'est du texte à relire, pas du code — police de
   lecture, mais retours à la ligne conservés, ce sont eux qui séparent les consignes. */
.prompt-view { white-space: pre-wrap; word-break: break-word; margin: 0; max-height: 620px;
               overflow: auto; background: var(--bg); border: 1px solid var(--border);
               border-radius: var(--radius); padding: 14px 16px; font-family: inherit; font-size: 13px;
               line-height: 1.6; color: var(--text); }

.msg-status { border-radius: var(--radius); padding: 2px 7px; font-weight: 600; font-size: 12px;
              background: var(--amber-bg); color: var(--amber); }
.msg-status.done { background: var(--green-bg); color: var(--green); }

.composer summary { list-style: none; font-weight: 600; color: var(--text); }
.composer summary::before { content: "＋ "; color: var(--primary); font-weight: 700; }
.composer[open] summary::before { content: "− "; }
.composer summary::-webkit-details-marker { display: none; }
.composer form { margin-top: 14px; max-width: 660px; }

/* ---- Divers ---- */
.pager { display: flex; gap: 8px; align-items: center; margin: 14px 0; flex-wrap: wrap; }
.pager form { display: flex; gap: 6px; align-items: center; }
.pager input[type=number] { width: 78px; padding: 5px 9px; font-size: 13px; }
.pager .muted { font-variant-numeric: tabular-nums; }
.toolbar { display: flex; gap: 12px; align-items: center; justify-content: space-between;
           margin: 10px 0; flex-wrap: wrap; }
.toolbar .actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* une action POST au milieu de liens porte son propre <form> (imbriquer des formulaires est
   interdit) : le formulaire ne doit rien peser dans la ligne, seul son bouton compte */
.inline-form { display: inline-flex; margin: 0; }
a.ext { color: var(--primary); }

/* ---- Posts scorés : sélecteur de personne + posts déjà ouverts ---- */
.peoplebar { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin: 0 0 10px; }
.peoplebar .field { max-width: 340px; }
.peoplebar [data-people-count] { padding-bottom: 9px; font-variant-numeric: tabular-nums; }
.peoplebar button { margin-bottom: 1px; }
/* La ligne d'un post déjà ouvert est assombrie : ça suffit à la repérer, pas besoin de badge.
   Sélecteurs préfixés par tbody pour passer devant `tbody tr:hover td`, sinon le survol
   rendait la ligne vue indiscernable des autres. */
tbody tr.seen td { background: #E5E5DD; }
tbody tr.seen:hover td { background: #DADAD1; }
details summary { cursor: pointer; color: var(--primary); font-weight: 500; }
/* analyse repliable dans une cellule de tableau (Opportunités, Mission) */
td details p { white-space: normal; min-width: 260px; max-width: 420px; margin: 6px 0 2px;
               color: var(--muted); font-size: 13px; }

@media (max-width: 640px) {
  /* La colonne d'actions cesse d'être figée sous 640 px. Figée, elle occupe 172 px d'un écran
     qui en fait 390 — 44 % — et recouvrait en permanence la colonne « Lead », c'est-à-dire
     la seule chose qui dit DE QUI parle le signal. Sur un grand écran elle garde tout son
     sens (l'action reste sous la main pendant qu'on fait défiler) ; ici elle coûte l'essentiel
     pour épargner un geste. */
  th.act, td.act { position: static; box-shadow: none; }
  /* la ligne passe sur deux étages : identité puis état, pour garder l'aperçu lisible */
  .conv { flex-wrap: wrap; row-gap: 8px; }
  .conv-main { flex-basis: calc(100% - 52px); }
  .conv-side { flex-direction: row; align-items: center; gap: 10px; width: 100%; }
  .msg { max-width: 100%; }
  .lead-head .actions { margin-left: 0; }
}

@media (max-width: 860px) {
  /* barre supérieure compacte : identité + actions sur une ligne, navigation sur une seconde
     ligne qui défile horizontalement — au lieu des 6 liens empilés qui mangeaient un demi-écran */
  body { flex-direction: column; }
  aside { width: 100%; height: auto; position: sticky; top: 0; z-index: 40;
          flex-direction: row; align-items: center; flex-wrap: wrap; gap: 6px 10px;
          padding: 9px 12px; box-shadow: 0 2px 10px rgb(25 27 24 / 18%); }
  aside .brand { padding: 0; font-size: 15px; }
  aside .brand small { display: none; }
  /* ordre explicite : identité à gauche, actions à droite, navigation sur la ligne du dessous */
  aside nav { flex: 1 0 100%; order: 4; flex-direction: row; flex-wrap: nowrap; gap: 4px;
              overflow-x: auto; scrollbar-width: none; margin: 0 -12px; padding: 0 12px; }
  aside nav::-webkit-scrollbar { display: none; }
  aside nav a { flex-shrink: 0; padding: 7px 11px; font-size: 13px; }
  .side-new { order: 1; margin: 0 0 0 auto; padding: 7px 13px; font-size: 13px; }
  .notif { order: 2; }
  .side-logout { order: 3; padding: 7px 9px; }
  .side-logout span:not(.notif-badge) { display: none; }
  .notif-badge { position: absolute; top: 0; right: 0; margin: 0; padding: 0 5px;
                 line-height: 15px; font-size: 11px; }
  .tablewrap { max-height: calc(100vh - 170px); }
  main { padding: 18px 14px 50px; }
}

/* très petits écrans : le logo seul suffit à porter l'identité, et libère la place
   qu'il faut pour garder actions et déconnexion sur une seule ligne */
@media (max-width: 560px) {
  aside .brand span:not(.logo) { display: none; }
}

/* ---- Bulle d'aide « ? » (macro `aide` de _aide.html) ----
   Les explications longues sortent du flux de la page : elles restent accessibles d'un clic
   sans imposer leur pavé à qui connaît déjà la manœuvre. */
.aide { position: relative; display: inline-block; vertical-align: middle; margin-left: 6px; }
.aide > summary { list-style: none; cursor: pointer; width: 18px; height: 18px; border-radius: 50%;
                  display: grid; place-items: center; font-size: 12px; font-weight: 700;
                  background: var(--primary-soft); color: var(--primary-dark);
                  border: 1px solid #DEDDD4; }
.aide > summary::-webkit-details-marker { display: none; }
.aide > summary::after { content: "?"; }
.aide > summary:hover { background: #E5E5DD; }
.aide[open] > summary { background: var(--primary); border-color: var(--primary); color: #fff; }
.aide-pop { position: absolute; z-index: 40; top: 26px; left: -4px; width: min(430px, 80vw);
            background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
            box-shadow: 0 4px 24px rgb(25 27 24 / 14%); padding: 14px 16px;
            font-size: 13px; font-weight: 400; line-height: 1.55; color: var(--text); }
/* près du bord droit, la bulle sortirait de l'écran : on l'accroche à droite */
.aide-pop.droite { left: auto; right: -4px; }
/* le titre seul passe en bloc : `.aide-pop b` cassait la ligne à chaque mot en gras du corps */
.aide-pop > b:first-child { display: block; margin-bottom: 7px; }
.aide-pop p { margin: 0 0 8px; color: var(--muted); }
.aide-pop p:last-child, .aide-pop ol:last-child, .aide-pop ul:last-child { margin-bottom: 0; }
.aide-pop ol, .aide-pop ul { margin: 0 0 8px; padding-left: 19px; color: var(--muted); }
.aide-pop li { margin-bottom: 5px; }
.aide-pop li b, .aide-pop strong { color: var(--text); }
.aide-pop code { background: var(--bg); padding: 1px 5px; border-radius: var(--radius); font-size: 13px; }

/* Colonne de lecture des pages de configuration. Les blocs sont des formulaires à relire, pas
   des tableaux : étalés sur 1560 px ils se décalent les uns par rapport aux autres et les
   lignes de texte deviennent trop longues. */
.colonne { max-width: 940px; }

/* Section repliée à l'intérieur d'un formulaire : des champs qu'on règle une fois et qu'on
   ne rouvre plus. Ils restent dans le <form>, donc enregistrés même repliés. */
.repli { border-top: 1px solid var(--border); padding-top: 12px; margin-bottom: 4px; }
.repli > summary { font-weight: 600; color: var(--text); font-size: 14px; padding: 2px 0; }
.repli[open] > summary { margin-bottom: 14px; }

/* ---- Réglages ---- */
/* Deux gros choix côte à côte plutôt qu'une liste déroulante : le mode d'envoi est la
   décision la plus lourde du panel, elle doit se voir sans l'ouvrir. */
.modes { display: flex; gap: 12px; flex-wrap: wrap; margin: 0 0 16px; }
.modes .mode { flex: 1; min-width: 250px; display: block; cursor: pointer; padding: 13px 15px;
               border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.modes .mode:hover { border-color: #C4C5BC; }
.modes .mode b { display: flex; align-items: center; gap: 8px; font-size: 15px; }
.modes .mode span { display: block; margin-top: 5px; color: var(--muted); font-size: 13px; }
.modes .mode input { margin: 0; accent-color: var(--primary); }
.modes .mode:has(input:checked) { border-color: var(--green); background: var(--green-bg); }
.modes .mode:has(input:checked) b { color: var(--green); }
.modes .mode.reel:has(input:checked) { border-color: var(--amber); background: var(--amber-bg); }
.modes .mode.reel:has(input:checked) b { color: var(--amber); }

/* bandeau d'état en tête d'une carte de réglage : ce qui s'applique en ce moment */
.etat { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 14px;
        padding: 10px 14px; border-radius: var(--radius); font-size: 14px;
        background: var(--green-bg); color: var(--green); border: 1px solid #BFD8C6; }
.etat.warn { background: var(--amber-bg); color: var(--amber); border-color: #E0CDA0; }
.etat b { font-weight: 700; }
.etat .btn { margin-left: auto; }

/* ---- Espace « IA des mails » ---- */
/* Onglets de rubrique : deux pages (le prompt, le dossier) plutôt qu'un empilement.
   Ce ne sont pas les onglets d'un widget mais deux vraies URL — d'où les <a>. */
.onglets { display: flex; gap: 4px; margin: 0 0 20px; border-bottom: 1px solid var(--border); }
.onglets a { display: flex; align-items: center; gap: 8px; padding: 9px 15px 10px;
             margin-bottom: -1px; border-bottom: 2px solid transparent; text-decoration: none;
             color: var(--muted); font-size: 14px; font-weight: 600; white-space: nowrap; }
.onglets a:hover { color: var(--text); }
.onglets a.on { color: var(--primary); border-bottom-color: var(--primary); }
.onglets svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2;
               stroke-linecap: round; stroke-linejoin: round; }
.onglets b { background: var(--primary-soft); color: var(--primary-dark); border-radius: 999px;
             padding: 1px 8px; font-size: 12px; font-variant-numeric: tabular-nums; }
.onglets a.on b { background: var(--primary); color: #fff; }

/* Ordre d'assemblage du prompt : le texte envoyé au modèle est un montage de cinq morceaux
   dont trois changent selon le mail. Le montrer évite de chercher « où est le reste ». */
.assemblage { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0 0 22px;
              padding: 0; counter-reset: etape; }
.assemblage li { counter-increment: etape; }
.assemblage a, .assemblage li.fige { display: flex; align-items: baseline; gap: 7px;
    padding: 8px 14px 8px 11px; border: 1px solid var(--border); border-radius: 999px;
    background: var(--surface); text-decoration: none; color: var(--text); font-size: 13px; }
.assemblage a::before, .assemblage li.fige::before { content: counter(etape);
    display: grid; place-items: center; width: 17px; height: 17px; border-radius: 50%;
    background: var(--primary-soft); color: var(--primary-dark); font-size: 11px;
    font-weight: 700; flex-shrink: 0; align-self: center; }
.assemblage a:hover { border-color: var(--primary); }
.assemblage b { font-weight: 600; }
.assemblage span { color: var(--muted); font-size: 13px; }
/* le contexte du lead est fabriqué par le workflow, il ne se règle nulle part */
.assemblage li.fige { background: var(--bg); border-style: dashed; }

/* ---- Zone de dépôt des documents ---- */
.depot { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 18px;
         padding: 22px 24px; border: 2px dashed #DEDDD4; border-radius: var(--radius);
         background: linear-gradient(180deg, #FFFFFF, var(--primary-soft));
         transition: border-color .12s, background .12s; }
.depot label { display: flex; align-items: center; gap: 14px; flex: 1; min-width: 260px;
               margin: 0; cursor: pointer; color: var(--text); }
.depot svg { width: 28px; height: 28px; flex-shrink: 0; fill: none; stroke: var(--primary);
             stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.depot b { display: block; font-size: 15px; }
.depot label span { display: block; margin-top: 3px; color: var(--muted); font-size: 13px;
                    font-weight: 400; }
.depot input[type=file] { width: auto; max-width: 260px; font-size: 13px; }
/* fichiers survolant la zone : la cible doit être franche, on lâche à l'aveugle */
.depot.survol { border-color: var(--primary); border-style: solid;
                background: #EAEAE3; }
.depot.survol * { pointer-events: none; }

/* ---- Barre du dossier (compteurs + enregistrement) ---- */
.barre-dossier { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 0 0 12px;
                 font-size: 13px; color: var(--muted); }
.barre-dossier b { color: var(--text); font-variant-numeric: tabular-nums; }
.barre-dossier .fin { margin-left: auto; }
/* modifications en attente : le tableau part en un seul envoi, il faut que ça se voie */
form.sale .barre-dossier .fin::after { content: " •"; }
form.sale .barre-dossier::before { content: "Modifications non enregistrées";
    order: 3; margin-left: auto; padding: 3px 11px; border-radius: 999px;
    background: var(--amber-bg); color: var(--amber); border: 1px solid #E0CDA0;
    font-size: 13px; font-weight: 600; }

/* ---- Tableau du dossier ---- */
/* Une ligne par document, ses réglages éditables sur place : ouvrir un accordéon pour
   changer une langue puis attendre un rechargement complet ne tenait pas à l'usage. */
table.docs td { vertical-align: middle; }
table.docs th.poignee, table.docs td.poignee { width: 28px; padding: 0 0 0 10px; }
table.docs th.mid, table.docs td.mid { text-align: center; width: 54px; }
table.docs th.num, table.docs td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.docs td.num { color: var(--muted); font-size: 13px; }
table.docs td.num .cell-sub { font-size: 12px; }
/* Le nom prend la place restante, les listes déroulantes sont bornées : sans ça le
   tableau dépassait la largeur, la colonne d'actions figée à droite venait recouvrir la
   case « Actif » et les noms de fichiers étaient coupés en plein milieu. */
table.docs th:nth-child(2) { width: 100%; }
table.docs input.nom { width: 100%; min-width: 170px; font-weight: 600; }
table.docs select { min-width: 0; width: 100%; font-size: 13px; padding: 6px 6px; }
/* `min-width` et non `width` : la colonne du nom réclame 100 %, et une largeur simple
   se faisait alors écraser jusqu'au contenu minimum — les listes déroulantes tombaient à
   « Tou⌄ », « Premier m⌄ ». Le minimum, lui, tient. */
table.docs td:nth-child(3) { min-width: 118px; }
table.docs td:nth-child(4) { min-width: 152px; }
table.docs td:nth-child(5) { min-width: 172px; }
table.docs th, table.docs td { padding-left: 9px; padding-right: 9px; }
/* champs posés dans une cellule : discrets au repos, francs à la saisie — sinon huit lignes
   de bordures bleues font un mur et on ne lit plus les noms */
table.docs input[type=text], table.docs select { border-color: transparent;
    background: transparent; }
table.docs tr:hover input[type=text], table.docs tr:hover select,
table.docs input[type=text]:focus, table.docs select:focus { border-color: #C4C5BC;
    background: var(--surface); }
table.docs td.act .actions-cell { display: flex; gap: 6px; align-items: center; }
.grip { display: inline-block; cursor: grab; color: var(--muted); font-size: 15px;
        line-height: 1; padding: 4px 2px; user-select: none; }
.grip:active { cursor: grabbing; }
tbody tr.tiree td { opacity: .4; }
/* contenu déplié sous sa ligne : c'est le document lui-même, il a droit à toute la largeur */
table.docs tr.contenu td { white-space: normal; background: var(--bg); padding: 12px 16px 16px; }
table.docs tr.contenu textarea { font-size: 13px; line-height: 1.55; }
.compteur { display: block; margin-top: 5px; color: var(--muted); font-size: 12px;
            font-variant-numeric: tabular-nums; }
.compteur.trop { color: var(--red); font-weight: 600; }

/* ---- Simulateur « ce qui part vraiment » ---- */
/* La portée (langue × type × catégorie) décide de ce qu'un mail reçoit : on choisit la
   combinaison et on voit la liste réelle, dans l'ordre du dossier. */
.simu-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.simu-liste li { display: flex; align-items: baseline; gap: 10px; padding: 8px 12px;
                 border-radius: var(--radius); background: var(--bg); font-size: 13px; }
.simu-liste b { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
                white-space: nowrap; font-weight: 600; }
.simu-liste span { color: var(--muted); font-size: 13px; flex-shrink: 0; }
.simu-liste li.entier { background: var(--green-bg); }
.simu-liste li.entier span { color: var(--green); }
.simu-liste li.vide { color: var(--muted); }

@media (max-width: 860px) {
  .depot { padding: 16px; }
  .assemblage { gap: 6px; }
}

/* ---- Réglages numériques (/reglages) ---- */
/* Un champ court, son unité et son aide : le nombre doit se lire et se corriger d'un coup
   d'œil, pas se chercher dans une grille de formulaire. */
.reglage { padding: 14px 0; border-top: 1px solid var(--border); }
.reglage:first-of-type { border-top: none; padding-top: 0; }
.reglage > label { font-size: 14px; color: var(--text); font-weight: 600; margin-bottom: 7px; }
.reglage .valeur { display: flex; align-items: center; gap: 9px; }
.reglage input[type=number] { width: 92px; font-variant-numeric: tabular-nums;
                              font-weight: 600; text-align: right; }
.reglage .valeur > span { color: var(--muted); font-size: 13px; }
.reglage .sub { margin: 7px 0 0; max-width: 620px; }

/* ---- Facettes d'entreprise (/entreprises, bloc « Filtres entreprise » du Lead Explorer) ---- */
/* Cinq listes fermées en cases à cocher. Le compteur à droite de chaque valeur est ce qui
   distingue un explorateur d'un formulaire : on voit où il y a de la matière avant de
   cliquer. Chaque groupe est repliable — 39 univers dépliés d'office noieraient le reste. */
.facettes { display: grid; gap: 10px; margin-top: 14px;
            border-top: 1px solid var(--border); padding-top: 14px; }
.facette { border: 1px solid var(--border); border-radius: var(--radius); background: #FCFBF8; }
.facette > summary { display: flex; align-items: center; gap: 9px; cursor: pointer;
                     padding: 9px 13px; font-size: 13px; font-weight: 600;
                     color: var(--text); list-style: none; }
.facette > summary::-webkit-details-marker { display: none; }
/* chevron maison : le marqueur natif se place mal dans un summary en flex */
.facette > summary::before { content: "▸"; color: var(--muted); font-size: 11px;
                             transition: transform .12s; }
.facette[open] > summary::before { transform: rotate(90deg); }
.facette-titre { flex: 1; }
/* nombre de cases cochées : visible même quand le groupe est replié, sinon un filtre actif
   se cache derrière un titre fermé et le total devient inexplicable */
.facette-n { background: var(--primary); color: #fff; border-radius: 999px; min-width: 20px;
             text-align: center; padding: 1px 7px; font-size: 12px; font-variant-numeric: tabular-nums; }
.facette-cases { display: grid; gap: 5px; padding: 2px 11px 11px;
                 grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.facette-case { display: flex; align-items: center; gap: 8px; margin: 0; padding: 5px 9px;
                border-radius: var(--radius); cursor: pointer; font-size: 13px; font-weight: 500;
                color: var(--text); background: var(--surface);
                border: 1px solid transparent; }
.facette-case:hover { border-color: #C4C5BC; background: #F0EFE9; }
.facette-case input { flex-shrink: 0; margin: 0; }
.facette-case > span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.facette-case b { color: var(--muted); font-weight: 600; font-size: 13px;
                  font-variant-numeric: tabular-nums; }
/* valeur sans aucune entreprise sous les autres filtres : montrée (l'information « rien
   ici » compte) mais visiblement inutile. Pas `pointer-events: none` : la case peut être
   cochée, et il faut pouvoir la décocher. */
.facette-case.vide { opacity: .45; }
.facette-case:has(input:checked) { background: var(--primary-soft); border-color: #DEDDD4; }

/* Étiquettes de lecture dans les listes. Volontairement plus petites et plus sobres que
   `.chip`, qui est un filtre cliquable. */
.fchip { display: inline-block; padding: 2px 8px; margin: 0 4px 4px 0; border-radius: 999px;
         font-size: 12px; font-weight: 600; white-space: nowrap;
         background: #EEEDE6; color: var(--muted); }
.chip-univers { background: var(--primary-soft); color: var(--primary-dark); }
.chip-cli     { background: #EEEDE6; color: var(--text); }
.chip-profil  { background: #EEEDE6; color: var(--text); }
.chip-zone    { background: #EEEDE6; color: var(--muted); }
/* Les signaux marketing étaient en ambre : une couleur chaude et saturée, alors que la
   chaleur est réservée à la fraîcheur. Étiquette cerclée, donc, pas colorée. */
.chip-signal  { background: transparent; color: var(--text); border: 1px solid var(--trait); }
.tag-chip     { background: transparent; color: var(--muted); border: 1px solid var(--border);
                font-weight: 500; }
.fchip-plus   { background: transparent; color: var(--muted); font-weight: 500; }

/* Colonne « Entreprise » de /entreprises : nom, secteur, description, mots-clés empilés.
   La description est la raison d'être de l'écran, elle a droit à de la place. */
.ent-nom { max-width: 520px; }
/* Deux lignes, pas plus. Une description de quatre lignes plus deux rangées de mots-clés
   faisaient des lignes de 200 px : DEUX entreprises tenaient à l'écran sur 27 477. Le texte
   entier reste dans l'infobulle. */
.ent-desc { margin: 5px 0 0; font-size: 13px; color: var(--muted); line-height: 1.4;
            display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
            line-clamp: 2; overflow: hidden; }

/* Pastille de facette CLIQUABLE : elle ramène la liste filtrée sur sa valeur. Elle doit donc
   se donner pour ce qu'elle est — cliquable — sans devenir un bouton : le fond se ferme au
   survol, c'est tout. */
a.fchip { text-decoration: none; cursor: pointer; }
a.fchip:hover { border-color: var(--action); color: var(--text); }
a.chip-univers:hover { background: #E5E5DD; }
a.fchip:focus-visible { outline: 2px solid var(--action); outline-offset: 1px; }
.card.compact { padding: 12px 18px; }
/* La recherche libre est le champ principal de /entreprises : dans la ligne commune, sa
   `.field.wide` retombait au min-width de 190 px derrière les sélecteurs de secteur. */
.recherche-libre .field { flex: 1; max-width: 620px; }

/* =====================================================================
   Refonte du 14 août — les composants de la « station d'écoute »
   ===================================================================== */

/* ---- LA SIGNATURE : la bande de fraîcheur ----
   Un filet de 3 px au bord gauche de chaque ligne (opportunité, pub), coloré sur la rampe,
   avec l'âge en mono juste à côté. Un seul coup d'œil dans la colonne dit où sont les
   signaux vivants avant d'avoir lu un mot. C'est LE geste de l'interface : tout le reste
   reste sobre. `box-shadow: inset` et non `border-left` — une bordure sur la première
   cellule décalerait le texte de 3 px et casserait l'alignement des colonnes. */
tr[data-age] > td:first-child { box-shadow: inset 3px 0 0 var(--f, var(--h3)); }
[data-age="0"] { --f: var(--h0); }   /* moins de 7 jours   */
[data-age="1"] { --f: var(--h1); }   /* moins de 30 jours  */
[data-age="2"] { --f: var(--h2); }   /* moins de 90 jours  */
[data-age="3"] { --f: var(--h3); }   /* au-delà : s'éteint */

/* L'âge lui-même : en mono, à la couleur encre de la rampe (contraste AA), et non plus
   en gris fade posé à côté d'un score en gros. */
.age { display: inline-block; font-size: 13px; font-weight: 400; white-space: nowrap;
       color: var(--ft, var(--h3-t)); }
[data-age="0"] .age { --ft: var(--h0-t); font-weight: 500; }
[data-age="1"] .age { --ft: var(--h1-t); }
[data-age="2"] .age { --ft: var(--h2-t); }
.age small { display: block; color: var(--muted); font-size: 12px;
             font-family: "Plex Sans", system-ui, sans-serif; }

/* Légende de la rampe, une seule fois en tête de liste : sans elle, une couleur ne veut
   rien dire tant qu'on ne l'a pas devinée. */
.rampe { display: inline-flex; align-items: center; gap: 12px; flex-wrap: wrap;
         font-size: 12px; color: var(--muted); }
.rampe span { display: inline-flex; align-items: center; gap: 5px; }
.rampe i { width: 3px; height: 13px; background: var(--f); display: inline-block; }

/* ---- Ce que la machine en pense ----
   Le score avait une COLONNE, au deuxième rang de lecture, avant même le nom de la personne.
   Pour un nombre dont 27 % des valeurs bougent d'un run à l'autre à prompt inchangé (±13 pts,
   mesuré le 13 août). Il rejoint la recommandation et le raisonnement sous le signal qu'ils
   qualifient : un seul bloc « avis du modèle », qu'on prend ou qu'on laisse — au lieu de trois
   morceaux dispersés dont un occupait une colonne entière.
   La note reste un nombre en mono avec son filet de niveau : 58 et 62 se ressemblent, ce qui
   est la vérité. Le tri par score vit dans le panneau de filtres. */
.avis { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; margin-top: 5px;
        font-size: 12px; }
/* La recommandation était une pastille grise à fond plein, posée au milieu du texte : elle
   avait l'allure d'un bouton qu'on peut cliquer. C'est un classement, pas une commande —
   donc un mot, sans boîte. */
.reco { color: var(--muted); font-weight: 600; text-transform: uppercase;
        letter-spacing: 0.07em; font-size: 11px; }
.reco::before { content: "→ "; }
.score { display: inline-block; padding: 0; border-radius: 0; background: none;
         color: var(--muted); font-size: 13px; font-weight: 400; text-align: left;
         font-family: "Plex Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; }
.score::after { content: ""; display: block; height: 2px; margin-top: 2px;
                width: calc(2px + var(--n, 0) * 0.26px); background: var(--encre); opacity: .22; }
/* le raisonnement du modèle : un repli discret, à la même ligne que sa note */
.avis details summary { color: var(--muted); font-weight: 400; font-size: 12px; }
.avis details p { margin: 5px 0 0; }

/* Ma passe de revue, sous l'avis du modèle. Filet à gauche plutôt que pastille : c'est une
   annotation en marge, pas un statut de la ligne — le statut vit dans la colonne « Revue ».
   L'orange ne va qu'à l'accroche : c'est le seul des trois verdicts qui dit d'agir, et la
   règle de la DA est que la couleur saturée ne sert qu'à ce qui décide. */
.avis-claude { margin: 6px 0 0; padding-left: 9px; border-left: 2px solid var(--trait);
               font-size: 12px; color: var(--muted); }
.avis-claude > span { text-transform: uppercase; letter-spacing: 0.07em; font-size: 10px;
                      font-weight: 600; margin-right: 6px; }
.avis-claude small { display: block; margin-top: 2px; font-size: 11px; line-height: 1.45; }
.avis-claude.v-accroche { border-left-color: var(--h0); color: var(--h0-t); font-weight: 600; }
.avis-claude.v-accroche small { font-weight: 400; color: var(--muted); }
.avis-claude.v-ecarte { text-decoration-line: none; }
.avis-claude.v-ecarte > span { color: var(--red); }
/* la variante est le verdict le plus fréquent (32 sur 42) : elle doit se voir le moins */
.avis-claude.v-variante small { display: none; }

/* ---- Analyse Sagacitix d'un post ----
   Même forme que l'avis de revue au-dessus, et pour la même raison : c'est un regard de plus
   posé À CÔTÉ du score, pas une décision. Aucune couleur saturée, donc — la règle de la DA la
   réserve à ce qui décide, et une ligne qui apparaît sur chaque post analysé n'en est pas.
   Seul STOP prend le rouge : c'est le seul verdict qui demande de se retenir d'écrire. */
.moa { margin: 6px 0 0; padding-left: 9px; border-left: 2px solid var(--trait);
       font-size: 12px; color: var(--muted); }
.moa > span { text-transform: uppercase; letter-spacing: 0.07em; font-size: 10px;
              font-weight: 600; margin-right: 6px; }
.moa small { display: block; margin-top: 2px; font-size: 11px; line-height: 1.45; }
.moa.v-stop > span { color: var(--red); }
.moa a.moa-plus { display: inline-block; margin-top: 3px; font-size: 12px; }

/* =====================================================================
   RAPPORT D'ANALYSE (/analyse/<post>)
   L'analyse ne tient pas dans une ligne de tableau : sept notes avec leur fourchette, trois
   lectures, une synthèse, des sources. Elle a donc sa page — bâtie sur les composants
   existants (`.card`, `.repli`, `.badge`), et non sur un gabarit de plus.
   ===================================================================== */
.verdict { border-left: 3px solid var(--trait); }
/* L'orange ne va qu'à ADJUST et STOP — ce sont les deux verdicts qui demandent un geste.
   Un GO ne décide de rien : il dit de ne rien faire, il reste en filet neutre. */
.verdict.v-adjust { border-left-color: var(--h1); }
.verdict.v-stop { border-left-color: var(--red); }
.verdict.v-go { border-left-color: var(--green); }
.verdict-mode { margin: 0 0 2px; font-size: 11px; font-weight: 700; letter-spacing: 0.09em;
                text-transform: uppercase; font-family: "Plex Mono", ui-monospace, monospace; }
.verdict-mode > span { font-family: inherit; font-weight: 400; color: var(--muted);
                       letter-spacing: 0.04em; text-transform: none; margin-left: 8px; }
.verdict h2 { margin: 0 0 8px; font-size: 20px; text-transform: none; letter-spacing: 0;
              line-height: 1.35; }
.lead-p { margin: 0 0 10px; font-size: 15px; line-height: 1.55; max-width: 78ch; }
.conditions { margin: 8px 0 0; padding-left: 18px; color: var(--text); font-size: 14px; }
.conditions li { margin-bottom: 4px; }
.tension { margin: 10px 0 0; font-size: 13px; color: var(--muted); max-width: 78ch; }
.tension b { color: var(--text); margin-right: 6px; }
/* Ce que l'analyse ne sait pas se lit AVANT de s'en servir devant un prospect : le panel a
   jugé sans modèle d'audience réel, et il l'écrit lui-même dans le contrat. */
.reserve { margin: 12px 0 0; padding: 8px 10px; background: var(--amber-bg); color: var(--amber);
           border-radius: var(--radius); font-size: 13px; line-height: 1.5; max-width: 78ch; }

.jauges { display: grid; gap: 9px; }
.jauge { display: grid; grid-template-columns: 190px 1fr 76px; gap: 12px; align-items: center; }
.jauge-lbl { font-size: 13px; }
.jauge-lbl small { display: block; color: var(--muted); font-size: 11px; }
.jauge-barre { height: 8px; background: var(--primary-soft); border-radius: 2px; overflow: hidden; }
.jauge-barre > i { display: block; height: 100%; background: var(--encre); }
/* `risk_score` s'inverse : 27 sur 100 y est une bonne note. La barre reste la même longueur —
   c'est bien la valeur mesurée — mais elle est en creux, pour ne pas se lire comme les six
   autres où plus long veut dire mieux. */
.jauge.inverse .jauge-barre > i { background: var(--h3); }
.jauge-n { font-family: "Plex Mono", ui-monospace, monospace; font-size: 14px; text-align: right;
           font-variant-numeric: tabular-nums; }
.jauge-n small { display: block; color: var(--muted); font-size: 11px; }

.persona h3 { margin: 0 0 8px; font-size: 15px; display: flex; gap: 8px; align-items: center;
              flex-wrap: wrap; }
.persona p { margin: 0; line-height: 1.6; max-width: 78ch; }
.notes-inline { margin-top: 10px !important; display: flex; flex-wrap: wrap; gap: 6px 14px;
                font-size: 12px; color: var(--muted); }
.notes-inline b { font-family: "Plex Mono", ui-monospace, monospace; color: var(--text); }

/* Deux colonnes : l'intitulé tient sur un mot, la réponse est une phrase. Empilés, on relisait
   huit fois le même chemin de l'œil pour comparer deux lignes. */
.synthese { display: grid; grid-template-columns: 200px 1fr; gap: 6px 18px; margin: 0; }
.synthese dt { font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em;
               color: var(--muted); padding-top: 2px; }
.synthese dd { margin: 0; line-height: 1.55; }
table.simple { width: 100%; border-collapse: collapse; margin-top: 12px; }
table.simple th, table.simple td { text-align: left; padding: 7px 10px; border-top: 1px solid var(--border);
                                   font-weight: 400; vertical-align: top; white-space: normal; }
table.simple th { width: 200px; font-weight: 600; }
.tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0 0; }
.sources { margin: 8px 0 0; padding-left: 18px; }
.sources li { margin-bottom: 8px; }
.sources small { display: block; color: var(--muted); font-size: 12px; line-height: 1.45;
                 margin-top: 2px; }

@media (max-width: 760px) {
  .jauge { grid-template-columns: 1fr 64px; }
  .jauge-barre { grid-column: 1 / -1; order: 3; }
  .synthese { grid-template-columns: 1fr; gap: 2px 0; }
  .synthese dd { margin-bottom: 10px; }
  table.simple th { width: auto; }
}

/* Le rapport imprimé : c'est lui qu'on envoie au prospect quand le mail lui propose
   « l'analyse complète ». Trois règles suffisent — la navigation et les boutons sortent,
   les replis s'ouvrent (un PDF ne se déplie pas), et rien ne se coupe au milieu d'une carte. */
@media print {
  aside, .commande .actions, .toasts, .moa-plus { display: none !important; }
  body { background: #fff; }
  main { margin: 0; padding: 0; max-width: none; }
  .card { break-inside: avoid; box-shadow: none; }
  /* les replis sont ouverts par app.js avant l'impression : leur flèche n'a plus de sens */
  details.repli > summary { list-style: none; font-weight: 600; }
  details.repli > summary::marker { content: ''; }
  h2 { break-after: avoid; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10px; color: #555;
                           word-break: break-all; }
}

/* ---- Barre de commande ----
   Un écran = une barre en haut (qui je suis, ce que je peux faire), le résultat plein
   cadre dessous. Remplace la carte-dans-la-carte : le titre ne flotte plus au-dessus
   d'un empilement de panneaux. */
.commande { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap;
            margin: 0 0 14px; padding-bottom: 12px; border-bottom: 1px solid var(--trait); }
.commande > div:first-child { flex: 1; min-width: 260px; }
.commande h1 { margin: 0; }
.commande .sub { margin: 3px 0 0; }
.commande .actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* Bascule interne d'un écran (Entreprises ⇄ Personnes, Posts ⇄ Publicités) : ce sont
   deux vues d'un même moment de travail, pas deux rubriques — d'où une bascule dans la
   page et non deux entrées de menu. Reprend `.onglets`, en plus compact. */
.onglets.bascule { border-bottom: none; gap: 6px; margin-bottom: 14px; }
.onglets.bascule a { border: 1px solid var(--trait); border-radius: var(--radius);
                     margin-bottom: 0; padding: 7px 14px; font-size: 13px;
                     text-transform: uppercase; letter-spacing: 0.04em; }
.onglets.bascule a.on { background: var(--action); border-color: var(--action); color: #fff; }
.onglets.bascule a:not(.on):hover { background: #F0EFE9; color: var(--text); }
.onglets a { text-transform: uppercase; letter-spacing: 0.04em; }

/* ---- Panneau de filtres escamotable ----
   Les filtres s'empilaient au-dessus du tableau et poussaient les résultats sous la ligne
   de flottaison (110 champs sur /entreprises). Ils vivent maintenant dans un panneau
   replié : ouvert seulement quand on règle, et toujours ouvert si un filtre est actif —
   sinon un filtre invisible expliquerait un total sans qu'on comprenne pourquoi. */
.filtres { border: 1px solid var(--trait); border-radius: var(--radius);
           background: var(--surface); margin-bottom: 14px; }
.filtres > summary { display: flex; align-items: center; gap: 10px; cursor: pointer;
                     padding: 10px 14px; font-family: "Plex Cond", sans-serif; font-weight: 600;
                     font-size: 14px; text-transform: uppercase; letter-spacing: 0.04em;
                     color: var(--text); list-style: none; }
.filtres > summary::-webkit-details-marker { display: none; }
.filtres > summary::before { content: "▸"; color: var(--muted); font-size: 11px;
                             transition: transform .12s; }
.filtres[open] > summary::before { transform: rotate(90deg); }
.filtres > summary .compte { margin-left: auto; font-family: "Plex Mono", monospace;
                             font-size: 12px; color: var(--muted); font-weight: 400;
                             text-transform: none; letter-spacing: 0; }
.filtres > summary .actif { background: var(--action); color: #fff; border-radius: 999px;
                            padding: 1px 8px; font-size: 12px; font-family: "Plex Mono", monospace;
                            font-weight: 400; letter-spacing: 0; }
.filtres-corps { padding: 4px 14px 14px; border-top: 1px solid var(--trait); }

/* ---- Filtres actifs, en toutes lettres ----
   Le panneau ne s'ouvre plus tout seul dès qu'un filtre est posé : il dépliait 91 cases à
   cocher et jetait les résultats sous la ligne de flottaison. Ce qu'il fallait vraiment, ce
   n'était pas voir TOUS les filtres possibles, c'était voir CEUX QUI SONT POSÉS — et pouvoir
   les défaire. Une étiquette par valeur, son « × », et le compte reste juste au-dessus. */
.actifs { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin: -6px 0 14px; }
.actif-chip { display: inline-flex; align-items: center; gap: 8px; padding: 3px 9px;
              border-radius: 999px; background: var(--action); color: #fff; font-size: 13px;
              font-weight: 600; text-decoration: none; }
.actif-chip b { font-weight: 400; opacity: .7; font-size: 14px; line-height: 1; }
.actif-chip:hover { background: var(--primary-dark); }
.actif-chip:hover b { opacity: 1; }
.actif-vider { color: var(--muted); font-size: 13px; }
@media (prefers-reduced-motion: reduce) { .filtres > summary::before { transition: none; } }

/* ---- Recherche en langage clair ----
   L'ancienne « Sélection IA » n'était pas une page : elle redirigeait toujours vers
   Entreprises avec les cases pré-cochées. C'était un CHAMP qui avait obtenu un onglet.
   Le voici à sa place : en tête de l'écran où le résultat s'affiche. */
.dire { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 0 0 14px;
        padding: 12px 14px; background: var(--surface); border: 1px solid var(--trait);
        border-radius: var(--radius); }
.dire label { margin: 0 0 2px; font-family: "Plex Cond", sans-serif; font-weight: 600;
              font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em;
              color: var(--text); }
.dire .field { flex: 1; min-width: 280px; max-width: none; }
.dire .sub { margin: 4px 0 0; font-size: 13px; }

/* ---- Barre d'action d'une sélection ----
   Sur Cibler, quatre commandes vives flottaient au-dessus d'une liste de 207 000 lignes sans
   rien dire de ce sur quoi elles portaient — et le premier clic, sans case cochée, rendait
   une erreur. La barre est maintenant un objet : elle porte un fond, elle est ÉTEINTE tant
   que rien n'est coché, et le compteur juste au-dessus dit sur quoi on agit. */
.barre-sel { display: flex; align-items: center; gap: 12px 22px; flex-wrap: wrap;
             margin: 0 0 14px; padding: 12px 14px; background: var(--surface);
             border: 1px solid var(--trait); border-radius: var(--radius); }
/* `nowrap` : chaque destination est un groupe indivisible (son champ + son bouton). En
   `wrap`, le groupe le plus court retombait d'une ligne et les deux barres se décalaient
   l'une par rapport à l'autre — on ne voyait plus quel bouton allait avec quel champ. */
.barre-sel .inline { gap: 8px; flex-wrap: nowrap; align-items: center; }
.barre-sel .inline + .inline { padding-left: 22px; border-left: 1px solid var(--trait); }
.barre-sel select, .barre-sel input[type=text] { min-width: 150px; }
.barre-sel .btn { white-space: nowrap; }

/* Colonne « Contenu » des posts : elle porte le lien vers le post ET son engagement. Sans
   plancher, elle est la première que la mise en page du tableau écrase quand la colonne
   d'actions figée s'élargit — et l'engagement disparaissait sous les boutons de revue. */
td.contenu { min-width: 190px; }
.barre-sel.vide { background: transparent; border-style: dashed; opacity: .55; }

/* Le compteur de sélection : il porte la consigne quand la sélection est vide, le nombre
   dès qu'elle ne l'est plus (app.js échange le texte). Un seul objet pour les deux états —
   sinon la consigne reste affichée à côté du compte et se contredit. */
.selcount { margin: 0; font-size: 13px; color: var(--muted); }
.selcount.on { color: var(--text); font-weight: 600; }
.selcount a { color: var(--muted); font-size: 13px; }

/* L'étiquette « démo » a été retirée : le panel n'a pas à qualifier l'authenticité des
   données de son utilisateur. Ce qui ne sert plus s'archive, et sort de l'accueil. */

/* Plancher de qualité : un parcours au clavier doit se voir. Les champs et les boutons
   avaient leur anneau, pas les liens ni les résumés repliables — c'est-à-dire ni la
   navigation, ni les filtres, ni les lignes de tableau. */
a:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--action); outline-offset: 2px; border-radius: 2px; }
aside a:focus-visible { outline-color: #fff; }

/* ---- LE MUR DE SPOTS (15 août) ----
   /pubs ne compte plus les pubs, il les montre. Un tableau de compteurs demandait de faire
   confiance à la définition du mot « spot » — et cette confiance a été démentie deux fois en
   deux jours : des fiches produit générées le 14, des fiches d'établissement Google Maps le 15,
   les deux étiquetées comme de la création par le registre. Une vignette, elle, se juge sans
   intermédiaire : une carte Maps se reconnaît en un dixième de seconde.

   Grille libre plutôt que colonnes fixes : le nombre de spots va de 0 à 120 selon la mission,
   et `auto-fill` évite d'avoir à choisir un nombre de colonnes qui vaudrait pour les deux. */
.mur { display: grid; gap: 18px; margin-bottom: 8px;
       grid-template-columns: repeat(auto-fill, minmax(228px, 1fr)); }
.mur .empty { grid-column: 1 / -1; background: var(--surface);
              border: 1px solid var(--border); border-radius: var(--radius); }

.spot { background: var(--surface); border: 1px solid var(--border);
        border-radius: var(--radius); overflow: hidden; display: flex; flex-direction: column; }
/* La bande de fraîcheur du tableau, transposée : elle passe du bord gauche d'une ligne au
   haut d'une vignette. Même rampe, même sens — c'est la signature de l'interface, elle ne
   change pas de couleur en changeant de forme. */
.spot { box-shadow: inset 0 3px 0 var(--f, var(--h3)); }
.spot-vue { display: block; position: relative; margin-top: 3px; background: #E7E7E0;
            aspect-ratio: 16 / 9; overflow: hidden; }
.spot-vue img { width: 100%; height: 100%; object-fit: cover; display: block;
                /* La vignette YouTube arrive en 480×360 avec deux bandes noires : `cover` les
                   recadre. Sans lui, les bandes doublent le poids visuel du mur. */ }
/* Le pictogramme de lecture : il dit que le lien ouvre un film, pas une fiche de registre.
   Discret — c'est la vignette qu'on regarde, pas le bouton. */
.spot-play { position: absolute; inset: auto 8px 8px auto; width: 26px; height: 26px;
             display: grid; place-items: center; border-radius: 50%; font-size: 11px;
             background: rgb(25 27 24 / 72%); color: #fff; }
.spot-vue:hover .spot-play { background: var(--action); }
.spot-txt { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 1px;
             flex: 1; }
.spot-nom { font-weight: 700; font-size: 15px; color: var(--text); text-decoration: none;
            font-family: "Plex Cond", "Plex Sans", sans-serif; letter-spacing: .01em; }
.spot-nom:hover { text-decoration: underline; }
/* La case à cocher de l'écran de recherche, posée sur la même ligne que le nom : c'est le nom
   qu'on sélectionne, pas la vignette. Elle ne sert que là, d'où la règle au plus près. */
.spot-tete { display: flex; align-items: baseline; gap: 7px; }
.spot-tete input[type=checkbox] { flex: none; }
/* Le titre du film, borné à trois lignes : ceux du registre vont de « T'as eu ton BAC ? » à
   « PA-CFS-10021_VOYAG_JUILLET_S33_PMAX_DERNIERES_MINUTES-1080 », et un titre qui déborde
   décale toute la rangée — ce qui casse précisément ce qui rend un mur scannable. */
.spot-titre { font-size: 13px; line-height: 1.35; color: var(--text); margin: 3px 0 1px;
              display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
              overflow: hidden; }
/* La chaîne est le tri le plus utile du mur, donc elle est cliquable — mais elle reste en
   sous-titre : c'est une provenance, pas le sujet de la vignette. */
.spot-chaine { color: var(--muted); text-decoration: none; border-bottom: 1px dotted var(--trait);
               align-self: flex-start; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
               white-space: nowrap; }
.spot-chaine:hover { color: var(--text); border-bottom-color: currentColor; }
/* « 131 personnes en base » ou « personne en base » : la vignette dit s'il y a quelqu'un à
   qui écrire. Sans cette ligne, reconnaître un beau spot ne mène nulle part. */
 /* `margin-top: auto` et non 5px : le nom d'un compte annonceur passe sur deux lignes
    (« Caisse Régionale du Crédit Agricole Charente-Périgord ») et la ligne du bas se
    retrouvait décalée d'une vignette à l'autre. Poussée en bas, elle s'aligne sur toute
    la rangée — c'est ce qui rend un mur scannable plutôt qu'une mosaïque. */
.spot-qui { margin-top: auto; padding-top: 6px; border-top: 1px solid #E7E7E0; }

/* ---- Ce qu'on peut FAIRE d'un spot (31 août 2026) ----
   Le mur montrait des films depuis le 15 août et ne menait nulle part : « je kiffe une
   publicité, y a pas de bouton ». Les deux gestes vivent en pied de vignette, sous le trait
   qui les sépare de ce qu'on lit — analyser le film, ou aller écrire à qui l'a commandé.
   Empilés et non côte à côte : à 228 px de large, deux boutons sur une ligne coupent leurs
   libellés, et « Analyser avec Sagacitix » ne se devine pas à moitié. */
.spot-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
                margin-top: 8px; padding-top: 8px; border-top: 1px solid #E7E7E0; }
.spot-actions .btn { width: 100%; justify-content: center; }
/* L'analyse tient dans la même ligne que sur un post (`.moa`), à ceci près qu'elle vit dans
   une vignette : elle se resserre sur la largeur utile. */
.spot .moa { margin-top: 8px; }
.spot .moa .badge { font-size: 10px; padding: 1px 8px; vertical-align: 1px; }

/* Le film retenu, en tête de « Qui contacter » : il dit de quoi le mail va parler avant qu'on
   choisisse à qui l'envoyer. Encadré parce qu'il porte une décision — pas un sous-titre. */
.film-retenu { border-left: 2px solid var(--h1); padding: 8px 0 8px 11px; margin: 0 0 14px; }
.film-retenu a { margin-left: 8px; }

/* Les formulaires de mail de la fiche entreprise : un `<form>` ne s'imbrique pas dans un
   autre, ils vivent donc hors du tableau et leurs boutons s'y rattachent par `form=`. */
.hors-flux { display: none; }

/* Vignette absente ou périmée (cf. app.js) : la tuile le dit au lieu de montrer un trou. */
.spot-vue.sans-vignette::after { content: attr(data-fallback); position: absolute; inset: 0;
       display: grid; place-items: center; padding: 12px; text-align: center;
       font-size: 13px; color: var(--muted); }
.spot-vue.sans-vignette img { display: none; }

/* Suivi du lead (3 nov. 2026, remplace Attio) : une ligne de formulaire sous l'en-tête */
.suivi .inline { align-items: flex-end; }
.suivi .field { display: flex; flex-direction: column; }
.suivi textarea { min-height: 38px; resize: vertical; }
.suivi .conv-meta { margin: 8px 0 0; }
.st-clos { --c: var(--muted); --c-soft: var(--trait); }
/* Compteur du menu : réponses à traiter + relances dues (même pastille que la cloche) */
.nav-count { background: var(--h0); color: var(--encre); border-radius: var(--radius); padding: 0 7px;
             font-size: 11px; font-weight: 700; line-height: 18px; margin-left: auto; }
.suivi .raccourcis { display: flex; gap: 6px; padding-bottom: 6px; }
/* Pipeline par étape, sous les états */
.pipeline { margin-top: 10px; align-items: center; }
.pipeline-titre { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
                  color: var(--muted); margin-right: 4px; }
/* Journal : notes datées dans le fil, changements d'étape en une ligne */
.msg-note { align-self: center; background: #FFF8E8; border-style: dashed; }
.journal-etape { align-self: center; margin: 0; font-size: 13px; color: var(--muted); }
.journal { display: flex; gap: 10px; align-items: flex-end; }
.journal textarea { flex: 1; min-height: 42px; resize: vertical; }
/* Prochaine action dans la liste : le « quoi » se lit avant le « quand » */
.conv-action { color: var(--text); font-weight: 600; max-width: 320px; text-align: right;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Pipeline (kanban) : une colonne par étape, défilement horizontal sur petit écran */
.kanban { display: grid; grid-template-columns: repeat(6, minmax(170px, 1fr)); gap: 10px;
          overflow-x: auto; padding-bottom: 8px; align-items: start; }
.kcol { background: #EFEFE9; border-radius: var(--radius); padding: 10px; min-height: 160px;
        border: 2px dashed transparent; transition: border-color .1s; }
.kcol.over { border-color: var(--primary); }
.kcol-clos { opacity: .8; }
.kcol h2 { font-size: 12px; margin: 2px 4px 10px; display: flex; justify-content: space-between; }
.kcol h2 b { color: var(--muted); font-variant-numeric: tabular-nums; }
.kcards { display: flex; flex-direction: column; gap: 8px; min-height: 60px; }
.kcard { position: relative; display: flex; flex-direction: column; gap: 3px; padding: 10px 11px 10px 14px;
         background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
         color: inherit; text-decoration: none; cursor: grab; overflow: hidden; font-size: 13px; }
.kcard::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--c, var(--trait)); }
.kcard:hover { border-color: var(--c, #C4C5BC); }
.kcard.drag { opacity: .4; }
.kcard-nom { display: flex; justify-content: space-between; gap: 6px; align-items: baseline; }
.kcard-nom b { font-size: 14px; }
.kcard-nom .badge { font-size: 11px; white-space: nowrap; }
.kcard-action { font-weight: 600; color: var(--text); }
