/* ==========================================================================
   AURON CAPITAL · Dashboard unifié — Direction D « Fusion »
   Base : direction A « Registre » (clair, sobre, Geist / Geist Mono, accent indigo)
   + un thème sombre complet (ambiance de la direction B, mêmes tokens).
   Thème : <html data-theme="light|dark">. Sans attribut, on suit
   prefers-color-scheme. L'or (--c-brand, --logo-fg) est réservé au logo.
   Contrastes AA vérifiés dans les deux thèmes (texte >= 4.5:1).
   Polices (OFL, woff2) : Geist + Geist Mono. En prod, auto-héberger :
   ========================================================================== */
/*
@font-face { font-family: "Geist"; src: url("/static/fonts/geist-var.woff2") format("woff2");
             font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("/static/fonts/geist-mono-var.woff2") format("woff2");
             font-weight: 100 900; font-display: swap; }
*/

:root {
  color-scheme: light;

  /* ---- Typographie -------------------------------------------------- */
  --f-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-display: "Geist", ui-sans-serif, system-ui, sans-serif;
  --f-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  --fs-label: 12px;   /* uniquement libellés en capitales / légendes */
  --fs-sm: 13px;      /* texte secondaire (minimum pour du texte courant) */
  --fs-md: 14px;      /* texte courant desktop */
  --fs-lg: 16px;
  --fs-xl: 20px;
  --fs-2xl: 24px;
  --fs-3xl: 30px;
  --lh-tight: 1.2;
  --lh: 1.5;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --tracking-label: 0.04em;
  --tracking-title: -0.02em;

  /* ---- Espacements (base 4) ----------------------------------------- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-7: 32px; --sp-8: 48px;

  /* ---- Rayons, ombres ----------------------------------------------- */
  --r-xs: 4px; --r-sm: 6px; --r-md: 8px; --r-lg: 12px; --r-pill: 999px;
  --sh-1: 0 1px 2px rgba(24, 24, 22, 0.05);
  --sh-2: 0 1px 2px rgba(24, 24, 22, 0.04), 0 4px 12px rgba(24, 24, 22, 0.05);
  --sh-pop: 0 8px 28px rgba(24, 24, 22, 0.14), 0 1px 3px rgba(24, 24, 22, 0.08);

  /* ---- Mise en page -------------------------------------------------- */
  --sidebar-w: 236px;
  --content-max: 1240px;
  --bottomnav-h: 64px;
  --tap: 44px;               /* cible tactile minimale */

  /* ---- Couleurs : neutres ------------------------------------------- */
  --c-frame: #F1F1EE;        /* cadre de l'application (autour de la feuille) */
  --c-bg: #FFFFFF;           /* feuille de contenu */
  --c-surface: #FFFFFF;
  --c-surface-2: #F7F7F5;    /* en-têtes de panneaux, zones secondaires */
  --c-hover: #F2F2EF;
  --c-selected: #ECECE8;
  --c-line: #E7E6E2;
  --c-line-strong: #D5D3CD;
  --c-text: #1B1B19;         /* 16.9:1 sur blanc */
  --c-text-2: #53524D;       /* 7.9:1 */
  --c-text-3: #6B6A64;       /* 5.4:1 — minimum pour du texte */
  --c-text-inv: #FFFFFF;

  /* ---- Marque et accent --------------------------------------------- */
  --c-brand: #9C7A35;        /* or AURON : logo uniquement */
  --c-accent: #3F4FD3;       /* sélection, liens, focus (6.3:1) */
  --c-accent-soft: #EEF0FC;
  --c-primary: #1B1B19;      /* bouton principal : encre */
  --c-primary-hover: #33332F;
  --c-focus: 0 0 0 2px #FFFFFF, 0 0 0 4px #3F4FD3;

  /* ---- États ---------------------------------------------------------- */
  --c-ok: #17794A;    --c-ok-bg: #E9F6EE;    --c-ok-line: #BFE3CD;
  --c-warn: #9A5B00;  --c-warn-bg: #FFF4DE;  --c-warn-line: #F3D9A4;
  --c-err: #C0352B;   --c-err-bg: #FDEDEB;   --c-err-line: #F5C6C1;
  --c-info: #2A62C4;  --c-info-bg: #EBF2FD;  --c-info-line: #C4D7F6;
  --c-off: #6B6A64;   --c-off-bg: #F2F2EF;   --c-off-line: #DDDCD7;

  /* ---- Statuts prospect (entonnoir) --------------------------------- */
  --st-nouveau: #5F6B7A;  --st-nouveau-bg: #EFF1F4;
  --st-accueil: #0B6AA2;  --st-accueil-bg: #E8F3FA;
  --st-marche: #4338CA;   --st-marche-bg: #EEEDFC;
  --st-mt5: #7C2DB8;      --st-mt5-bg: #F5EDFB;
  --st-depot: #17794A;    --st-depot-bg: #E9F6EE;
  --st-copie: #0F6E66;    --st-copie-bg: #E6F4F2;
  --st-perdu: #9F1D3A;    --st-perdu-bg: #FBECEF;

  /* ---- Mode de conversation ----------------------------------------- */
  --mode-bot: #3F4FD3;    --mode-bot-bg: #EEF0FC;
  --mode-humain: #B4530A; --mode-humain-bg: #FFF1E3;
  --mode-ignore: #6B6A64; --mode-ignore-bg: #F2F2EF;

  /* ---- Types de relance ---------------------------------------------- */
  --rt-accueil: #56657A;
  --rt-m130: #0B7285;
  --rt-j1: #6B3FD6;
  --rt-j3: #A1288F;
  --rt-j6: #C0352B;
  --rt-tard: #A15C00;
  --rt-prog: #0F766E;
  --rt-crm: #6F5B3E;         /* moteur CRM (J+4, J+7) */
  --rt-rappel: #1B1B19;      /* rappel posé par l'équipe */

  /* ---- Frise de séquence (signature) -------------------------------- */
  --seq-ok: #17794A;         /* envoyée + répondue */
  --seq-sent: #8A8983;       /* envoyée, sans réponse */
  --seq-next: #3F4FD3;       /* prochaine */
  --seq-late: #C0352B;       /* en retard */
  --seq-todo: #E2E1DC;       /* restante */

  /* ---- Conversation -------------------------------------------------- */
  --chat-client-bg: #F2F2EF;  --chat-client-text: #1B1B19;
  --chat-bot-bg: #EEF0FC;     --chat-bot-text: #22297A;
  --chat-humain-bg: #1B1B19;  --chat-humain-text: #FFFFFF;
  --chat-externe-bg: #FFF4DE; --chat-externe-text: #5E3A00;
  --chat-ghost-line: #B7BDF0;

  /* ---- Ajouts D : tokens nécessaires au thème sombre ------------------ */
  --c-accent-line: #C9CEF5;
  --c-glass: rgba(255, 255, 255, 0.92);      /* barres collantes translucides */
  --c-on-err: #FFFFFF;                        /* texte sur pastille rouge */
  --c-hatch-1: #E2E1DC; --c-hatch-2: #ECEBE7; /* vignette photo */
  --av-s: 45%; --av-bg-l: 92%; --av-fg-l: 28%; /* avatars : hsl(var(--h) …) */
  --logo-bg: #1B1B19; --logo-fg: #F3E3BC;     /* logo : seul usage de l'or */
  --rb-track: #ECECE8;                        /* ruban : axe */
  --rb-past: rgba(63, 79, 211, 0.16);         /* ruban : partie écoulée */
  --now-bg: #F5F6FE;                          /* carte « Maintenant » */
  --now-line: #C9CEF5;

  --motion: 140ms cubic-bezier(.2, .7, .3, 1);
}

@media (max-width: 760px) {
  :root { --fs-md: 15px; --fs-3xl: 26px; }
}

/* ==========================================================================
   Thème sombre — appliqué (1) si l'utilisateur l'a choisi : data-theme="dark",
   (2) sinon si le système est en sombre et que l'utilisateur n'a pas forcé le clair.
   Les deux blocs sont identiques : toute modification doit être faite dans les deux.
   ========================================================================== */
:root[data-theme="dark"] {
  color-scheme: dark;
  --c-frame: #0B0C0F;
  --c-bg: #111317;
  --c-surface: #15171C;
  --c-surface-2: #1A1D23;
  --c-hover: #1F2229;
  --c-selected: #262A32;
  --c-line: #262A32;
  --c-line-strong: #363B45;
  --c-text: #ECEAE5;
  --c-text-2: #B8B5AE;
  --c-text-3: #918E88;
  --c-text-inv: #111317;

  --c-brand: #D8B66D;
  --c-accent: #8F99FF;
  --c-accent-soft: rgba(143, 153, 255, 0.13);
  --c-accent-line: rgba(143, 153, 255, 0.40);
  --c-primary: #ECEAE5;
  --c-primary-hover: #FFFFFF;
  --c-focus: 0 0 0 2px #111317, 0 0 0 4px #8F99FF;

  --c-ok: #5FCB92;   --c-ok-bg: rgba(95, 203, 146, 0.13);  --c-ok-line: rgba(95, 203, 146, 0.35);
  --c-warn: #E9B457; --c-warn-bg: rgba(233, 180, 87, 0.13); --c-warn-line: rgba(233, 180, 87, 0.35);
  --c-err: #F2786D;  --c-err-bg: rgba(242, 120, 109, 0.14); --c-err-line: rgba(242, 120, 109, 0.40);
  --c-info: #7FACF6; --c-info-bg: rgba(127, 172, 246, 0.13); --c-info-line: rgba(127, 172, 246, 0.35);
  --c-off: #918E88;  --c-off-bg: rgba(145, 142, 136, 0.15); --c-off-line: rgba(145, 142, 136, 0.35);

  --st-nouveau: #A6AEBC;  --st-nouveau-bg: rgba(166, 174, 188, 0.13);
  --st-accueil: #72BDEB;  --st-accueil-bg: rgba(114, 189, 235, 0.13);
  --st-marche: #A6A8F8;   --st-marche-bg: rgba(166, 168, 248, 0.14);
  --st-mt5: #CFA6F3;      --st-mt5-bg: rgba(207, 166, 243, 0.14);
  --st-depot: #5FCB92;    --st-depot-bg: rgba(95, 203, 146, 0.13);
  --st-copie: #5AC9BC;    --st-copie-bg: rgba(90, 201, 188, 0.13);
  --st-perdu: #F2786D;    --st-perdu-bg: rgba(242, 120, 109, 0.13);

  --mode-bot: #A6A8F8;    --mode-bot-bg: rgba(166, 168, 248, 0.14);
  --mode-humain: #F3A766; --mode-humain-bg: rgba(243, 167, 102, 0.14);
  --mode-ignore: #918E88; --mode-ignore-bg: rgba(145, 142, 136, 0.15);

  --rt-accueil: #97A8BF;
  --rt-m130: #58C7D9;
  --rt-j1: #AA92FA;
  --rt-j3: #E78FD8;
  --rt-j6: #F2786D;
  --rt-tard: #E9B457;
  --rt-prog: #5AC9BC;
  --rt-crm: #C8A77C;
  --rt-rappel: #ECEAE5;

  --seq-ok: #5FCB92;
  --seq-sent: #8A8781;
  --seq-next: #8F99FF;
  --seq-late: #F2786D;
  --seq-todo: #2C3039;

  --chat-client-bg: #1E2128;  --chat-client-text: #ECEAE5;
  --chat-bot-bg: #1F2346;     --chat-bot-text: #DADDFF;
  --chat-humain-bg: #E6E4DE;  --chat-humain-text: #111317;
  --chat-externe-bg: #2A2418; --chat-externe-text: #EAD8B2;
  --chat-ghost-line: rgba(143, 153, 255, 0.45);

  --sh-1: 0 1px 0 rgba(255, 255, 255, 0.03) inset;
  --sh-2: 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 8px 24px rgba(0, 0, 0, 0.35);
  --sh-pop: 0 18px 50px rgba(0, 0, 0, 0.55);

  --c-glass: rgba(17, 19, 23, 0.88);
  --c-on-err: #1A0A08;
  --c-hatch-1: #22252C; --c-hatch-2: #2A2E36;
  --av-s: 32%; --av-bg-l: 23%; --av-fg-l: 82%;
  --logo-bg: #23262E; --logo-fg: #D8B66D;
  --rb-track: #23262E;
  --rb-past: rgba(143, 153, 255, 0.22);
  --now-bg: rgba(143, 153, 255, 0.07);
  --now-line: rgba(143, 153, 255, 0.42);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --c-frame: #0B0C0F;
    --c-bg: #111317;
    --c-surface: #15171C;
    --c-surface-2: #1A1D23;
    --c-hover: #1F2229;
    --c-selected: #262A32;
    --c-line: #262A32;
    --c-line-strong: #363B45;
    --c-text: #ECEAE5;
    --c-text-2: #B8B5AE;
    --c-text-3: #918E88;
    --c-text-inv: #111317;

    --c-brand: #D8B66D;
    --c-accent: #8F99FF;
    --c-accent-soft: rgba(143, 153, 255, 0.13);
    --c-accent-line: rgba(143, 153, 255, 0.40);
    --c-primary: #ECEAE5;
    --c-primary-hover: #FFFFFF;
    --c-focus: 0 0 0 2px #111317, 0 0 0 4px #8F99FF;

    --c-ok: #5FCB92;   --c-ok-bg: rgba(95, 203, 146, 0.13);  --c-ok-line: rgba(95, 203, 146, 0.35);
    --c-warn: #E9B457; --c-warn-bg: rgba(233, 180, 87, 0.13); --c-warn-line: rgba(233, 180, 87, 0.35);
    --c-err: #F2786D;  --c-err-bg: rgba(242, 120, 109, 0.14); --c-err-line: rgba(242, 120, 109, 0.40);
    --c-info: #7FACF6; --c-info-bg: rgba(127, 172, 246, 0.13); --c-info-line: rgba(127, 172, 246, 0.35);
    --c-off: #918E88;  --c-off-bg: rgba(145, 142, 136, 0.15); --c-off-line: rgba(145, 142, 136, 0.35);

    --st-nouveau: #A6AEBC;  --st-nouveau-bg: rgba(166, 174, 188, 0.13);
    --st-accueil: #72BDEB;  --st-accueil-bg: rgba(114, 189, 235, 0.13);
    --st-marche: #A6A8F8;   --st-marche-bg: rgba(166, 168, 248, 0.14);
    --st-mt5: #CFA6F3;      --st-mt5-bg: rgba(207, 166, 243, 0.14);
    --st-depot: #5FCB92;    --st-depot-bg: rgba(95, 203, 146, 0.13);
    --st-copie: #5AC9BC;    --st-copie-bg: rgba(90, 201, 188, 0.13);
    --st-perdu: #F2786D;    --st-perdu-bg: rgba(242, 120, 109, 0.13);

    --mode-bot: #A6A8F8;    --mode-bot-bg: rgba(166, 168, 248, 0.14);
    --mode-humain: #F3A766; --mode-humain-bg: rgba(243, 167, 102, 0.14);
    --mode-ignore: #918E88; --mode-ignore-bg: rgba(145, 142, 136, 0.15);

    --rt-accueil: #97A8BF;
    --rt-m130: #58C7D9;
    --rt-j1: #AA92FA;
    --rt-j3: #E78FD8;
    --rt-j6: #F2786D;
    --rt-tard: #E9B457;
    --rt-prog: #5AC9BC;
    --rt-crm: #C8A77C;
    --rt-rappel: #ECEAE5;

    --seq-ok: #5FCB92;
    --seq-sent: #8A8781;
    --seq-next: #8F99FF;
    --seq-late: #F2786D;
    --seq-todo: #2C3039;

    --chat-client-bg: #1E2128;  --chat-client-text: #ECEAE5;
    --chat-bot-bg: #1F2346;     --chat-bot-text: #DADDFF;
    --chat-humain-bg: #E6E4DE;  --chat-humain-text: #111317;
    --chat-externe-bg: #2A2418; --chat-externe-text: #EAD8B2;
    --chat-ghost-line: rgba(143, 153, 255, 0.45);

    --sh-1: 0 1px 0 rgba(255, 255, 255, 0.03) inset;
    --sh-2: 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 8px 24px rgba(0, 0, 0, 0.35);
    --sh-pop: 0 18px 50px rgba(0, 0, 0, 0.55);

    --c-glass: rgba(17, 19, 23, 0.88);
    --c-on-err: #1A0A08;
    --c-hatch-1: #22252C; --c-hatch-2: #2A2E36;
    --av-s: 32%; --av-bg-l: 23%; --av-fg-l: 82%;
    --logo-bg: #23262E; --logo-fg: #D8B66D;
    --rb-track: #23262E;
    --rb-past: rgba(143, 153, 255, 0.22);
    --now-bg: rgba(143, 153, 255, 0.07);
    --now-line: rgba(143, 153, 255, 0.42);
  }
}
/* ==========================================================================
   Direction D « Fusion » — composants (base A + ruban B + carte « Maintenant » C)
   Dépend de tokens.css. Aucune étape de build. Mobile : < 760 px.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--c-frame); color: var(--c-text);
  font: var(--fw-regular) var(--fs-md)/var(--lh) var(--f-sans);
  font-feature-settings: "ss01", "cv11"; -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
h1, h2, h3, p { margin: 0; }
.ico { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.ico-sm { width: 14px; height: 14px; }
.ico-lg { width: 20px; height: 20px; }
:focus-visible { outline: none; box-shadow: var(--c-focus); border-radius: var(--r-sm); }
.mono { font-family: var(--f-mono); font-feature-settings: "zero"; letter-spacing: -0.01em; }
.muted { color: var(--c-text-3); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.nowrap { white-space: nowrap; }

/* ---- Cadre de l'application ------------------------------------------- */
.app { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); min-height: 100vh; }
.sheet {
  margin: 8px 8px 8px 0; background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1); min-width: 0;
}

/* ---- Barre latérale ----------------------------------------------------- */
.sidebar { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; padding: 14px 10px 12px; gap: 2px; }
.brand { display: flex; align-items: center; gap: 10px; padding: 4px 8px 14px; }
.brand-mark {
  width: 26px; height: 26px; border-radius: 7px; background: var(--logo-bg); color: var(--logo-fg); box-shadow: inset 0 0 0 1px var(--c-line);
  display: grid; place-items: center; font: 600 13px/1 var(--f-sans); letter-spacing: -0.02em;
}
.brand-name { font-weight: var(--fw-semibold); font-size: 13px; letter-spacing: 0.08em; }
.brand-name small { display: block; font-weight: 400; letter-spacing: 0; color: var(--c-text-3); font-size: 12px; margin-top: 1px; }
.side-search {
  display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; margin: 0 0 10px;
  background: var(--c-bg); border: 1px solid var(--c-line); border-radius: var(--r-md); color: var(--c-text-3); font-size: var(--fs-sm);
}
.side-search kbd { margin-left: auto; }
kbd {
  font: 500 11px/1 var(--f-mono); color: var(--c-text-3); background: var(--c-surface-2);
  border: 1px solid var(--c-line); border-bottom-width: 2px; border-radius: 4px; padding: 3px 5px;
}
.nav-group { font-size: var(--fs-label); font-weight: var(--fw-medium); color: var(--c-text-3); padding: 14px 10px 4px; }
.nav-item {
  display: flex; align-items: center; gap: 10px; height: 32px; padding: 0 10px; border-radius: var(--r-sm);
  color: var(--c-text-2); font-size: var(--fs-sm); font-weight: var(--fw-medium); transition: background var(--motion);
}
.nav-item:hover { background: var(--c-hover); color: var(--c-text); }
.nav-item[aria-current="page"] { background: var(--c-bg); color: var(--c-text); box-shadow: var(--sh-1), inset 0 0 0 1px var(--c-line); }
.nav-item .count { margin-left: auto; font: 500 12px/1 var(--f-mono); color: var(--c-text-3); }
.nav-item .count.err { color: var(--c-err); }
.nav-item .count.warn { color: var(--c-warn); }
.side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 8px; padding: 10px 6px 0; border-top: 1px solid var(--c-line); }
.engine { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--c-text-2); padding: 2px 4px; }
.engine b { font-weight: var(--fw-medium); color: var(--c-text); margin-left: auto; }
.me { display: flex; align-items: center; gap: 8px; padding: 6px 4px 0; font-size: var(--fs-sm); }

/* ---- Pastilles et voyants ---------------------------------------------- */
.dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; display: inline-block; }
.dot.live { color: var(--c-ok); box-shadow: 0 0 0 3px var(--c-ok-bg); }
.dot.fantome { color: var(--c-warn); box-shadow: 0 0 0 3px var(--c-warn-bg); }

/* ---- Barre haute -------------------------------------------------------- */
.topbar {
  display: flex; align-items: center; gap: 12px; height: 52px; padding: 0 20px 0 24px;
  border-bottom: 1px solid var(--c-line);
}
.crumbs { display: flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--c-text-3); min-width: 0; }
.crumbs a:hover { color: var(--c-text); }
.crumbs .here { color: var(--c-text); font-weight: var(--fw-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .spacer { flex: 1; }
.clock { font: 500 var(--fs-sm)/1 var(--f-mono); color: var(--c-text-2); display: flex; align-items: center; gap: 6px; }

/* ---- Boutons ------------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 32px; padding: 0 12px;
  border-radius: var(--r-sm); border: 1px solid var(--c-line-strong); background: var(--c-surface);
  font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--c-text); cursor: pointer; white-space: nowrap;
  box-shadow: var(--sh-1); transition: background var(--motion), border-color var(--motion);
}
.btn:hover { background: var(--c-hover); }
.btn.primary { background: var(--c-primary); border-color: var(--c-primary); color: var(--c-text-inv); }
.btn.primary:hover { background: var(--c-primary-hover); }
.btn.ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--c-text-2); }
.btn.ghost:hover { background: var(--c-hover); color: var(--c-text); }
.btn.danger { color: var(--c-err); }
.btn.sm { height: 28px; padding: 0 10px; }
.btn.icon { width: 32px; padding: 0; }
.btn.sm.icon { width: 28px; }
.btn-row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }

/* ---- En-tête de page ---------------------------------------------------- */
.content { padding: 28px 32px 48px; max-width: var(--content-max); margin: 0 auto; }
.page-head { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 22px; }
.page-head h1 { font: var(--fw-semibold) var(--fs-3xl)/var(--lh-tight) var(--f-display); letter-spacing: var(--tracking-title); }
.page-head .sub { color: var(--c-text-3); margin-top: 6px; font-size: var(--fs-md); }
.page-head .sub b { color: var(--c-text-2); font-weight: var(--fw-medium); }
.page-head .btn-row { margin-left: auto; }

/* ---- Bandeau de chiffres ------------------------------------------------ */
.stats { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); border: 1px solid var(--c-line); border-radius: var(--r-lg); margin-bottom: 24px; background: var(--c-surface); }
.stat { padding: 14px 16px 15px; border-left: 1px solid var(--c-line); min-width: 0; }
.stat:first-child { border-left: 0; }
.stat .k { font-size: var(--fs-sm); color: var(--c-text-2); display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.stat .v { font: var(--fw-semibold) 26px/1.15 var(--f-display); letter-spacing: -0.03em; margin-top: 6px; font-variant-numeric: tabular-nums; }
.stat .v small { font-size: 15px; color: var(--c-text-3); font-weight: var(--fw-medium); letter-spacing: 0; }
.stat .d { font-size: var(--fs-sm); color: var(--c-text-3); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat.err .v { color: var(--c-err); }
.stat.warn .v { color: var(--mode-humain); }
.up { color: var(--c-ok); font-weight: var(--fw-medium); }

/* ---- Panneaux ----------------------------------------------------------- */
.grid-main { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 20px; align-items: start; }
.col { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.panel { background: var(--c-surface); border: 1px solid var(--c-line); border-radius: var(--r-lg); min-width: 0; }
.panel-h { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--c-line); min-height: 48px; }
.panel-h h2 { font-size: var(--fs-md); font-weight: var(--fw-semibold); letter-spacing: -0.01em; display: flex; align-items: center; gap: 8px; }
.panel-h .meta { font-size: var(--fs-sm); color: var(--c-text-3); }
.panel-h .right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.panel-b { padding: 14px 16px; }
.panel-f { padding: 10px 16px; border-top: 1px solid var(--c-line); font-size: var(--fs-sm); color: var(--c-text-3); display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.panel-f a { white-space: nowrap; }
.panel-f a { color: var(--c-accent); font-weight: var(--fw-medium); }
.count-pill { font: 500 12px/1 var(--f-mono); color: var(--c-text-2); background: var(--c-surface-2); border: 1px solid var(--c-line); border-radius: var(--r-pill); padding: 3px 7px; }

/* ---- Onglets segmentés -------------------------------------------------- */
.seg { display: inline-flex; background: var(--c-surface-2); border: 1px solid var(--c-line); border-radius: var(--r-md); padding: 2px; gap: 2px; }
.seg a { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border-radius: 6px; font-size: var(--fs-sm); color: var(--c-text-2); font-weight: var(--fw-medium); white-space: nowrap; }
.seg a[aria-current="true"] { background: var(--c-surface); color: var(--c-text); box-shadow: var(--sh-1), inset 0 0 0 1px var(--c-line); }
.seg a .n { font-family: var(--f-mono); font-size: 12px; color: var(--c-text-3); }
.seg a .n.err { color: var(--c-err); }

/* ---- Avatars ------------------------------------------------------------ */
.av {
  --h: 220; width: 28px; height: 28px; border-radius: 50%; flex: none; display: grid; place-items: center;
  background: hsl(var(--h) var(--av-s) var(--av-bg-l)); color: hsl(var(--h) var(--av-s) var(--av-fg-l)); font: 600 11px/1 var(--f-sans); letter-spacing: 0.02em;
}
.av.lg { width: 52px; height: 52px; font-size: 18px; }

/* ---- Étiquettes --------------------------------------------------------- */
.tag { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--c-text-2); white-space: nowrap; }
.tag::before { content: ""; width: 7px; height: 7px; border-radius: 2px; background: var(--rt, var(--c-text-3)); flex: none; }
.tag.vocal::before { border-radius: 50%; }
.tag .eng { font: 500 11px/1 var(--f-mono); color: var(--c-text-3); border: 1px solid var(--c-line); border-radius: 4px; padding: 2px 4px; }
.t-accueil { --rt: var(--rt-accueil); } .t-m130 { --rt: var(--rt-m130); } .t-j1 { --rt: var(--rt-j1); }
.t-j3 { --rt: var(--rt-j3); } .t-j6 { --rt: var(--rt-j6); } .t-tard { --rt: var(--rt-tard); }
.t-prog { --rt: var(--rt-prog); } .t-crm4, .t-crm7 { --rt: var(--rt-crm); } .t-rappel { --rt: var(--rt-rappel); }

.badge {
  display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px; border-radius: var(--r-pill);
  font-size: 12px; font-weight: var(--fw-medium); white-space: nowrap; background: var(--b-bg, var(--c-surface-2)); color: var(--b-fg, var(--c-text-2));
}
.badge.ok { --b-bg: var(--c-ok-bg); --b-fg: var(--c-ok); }
.badge.warn { --b-bg: var(--c-warn-bg); --b-fg: var(--c-warn); }
.badge.err { --b-bg: var(--c-err-bg); --b-fg: var(--c-err); }
.badge.info { --b-bg: var(--c-info-bg); --b-fg: var(--c-info); }
.badge.outline { background: transparent; box-shadow: inset 0 0 0 1px var(--c-line-strong); }
.s-nouveau { --b-bg: var(--st-nouveau-bg); --b-fg: var(--st-nouveau); }
.s-accueil { --b-bg: var(--st-accueil-bg); --b-fg: var(--st-accueil); }
.s-marche { --b-bg: var(--st-marche-bg); --b-fg: var(--st-marche); }
.s-mt5 { --b-bg: var(--st-mt5-bg); --b-fg: var(--st-mt5); }
.s-depot { --b-bg: var(--st-depot-bg); --b-fg: var(--st-depot); }
.s-copie { --b-bg: var(--st-copie-bg); --b-fg: var(--st-copie); }
.m-bot { --b-bg: var(--mode-bot-bg); --b-fg: var(--mode-bot); }
.m-humain { --b-bg: var(--mode-humain-bg); --b-fg: var(--mode-humain); }
.m-ignore { --b-bg: var(--mode-ignore-bg); --b-fg: var(--mode-ignore); }

/* ---- Frise de séquence (signature) -------------------------------------- */
.frise { display: inline-flex; gap: 3px; align-items: center; }
.frise i { width: 14px; height: 6px; border-radius: 2px; background: var(--seq-todo); display: block; }
.frise i.f-ok { background: var(--seq-ok); }
.frise i.f-sent { background: var(--seq-sent); }
.frise i.f-next { background: var(--c-surface); box-shadow: inset 0 0 0 1.5px var(--seq-next); }
.frise i.f-late { background: var(--seq-late); }
.frise i.f-skip { background: transparent; box-shadow: inset 0 0 0 1px var(--c-line-strong); opacity: .55; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--c-text-3); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend .frise i { width: 10px; }

/* ---- Lignes de relances -------------------------------------------------- */
.group-h { display: flex; align-items: center; gap: 8px; padding: 10px 16px 6px; font-size: var(--fs-label); font-weight: var(--fw-semibold); color: var(--c-text-3); text-transform: uppercase; letter-spacing: var(--tracking-label); background: var(--c-surface-2); border-top: 1px solid var(--c-line); border-bottom: 1px solid var(--c-line); }
.group-h.err { color: var(--c-err); }
.group-h .n { font-family: var(--f-mono); }
.rl {
  display: grid; grid-template-columns: 48px minmax(150px, 1.3fr) minmax(110px, 1fr) 80px minmax(130px, 1.2fr) 104px;
  align-items: center; gap: 12px; padding: 9px 16px; border-top: 1px solid var(--c-line); min-height: 52px;
}
.group-h + .rl { border-top: 0; }
.rl:hover { background: var(--c-surface-2); }
.rl .h { font: 500 var(--fs-md)/1 var(--f-mono); color: var(--c-text); }
.rl.sent .h { color: var(--c-text-3); }
.rl.late .h { color: var(--c-err); }
.who { display: flex; align-items: center; gap: 10px; min-width: 0; }
.who .n { font-weight: var(--fw-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.who .s { font-size: var(--fs-sm); color: var(--c-text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.who > div { min-width: 0; }
.res { font-size: var(--fs-sm); color: var(--c-text-2); min-width: 0; }
.res .l2 { color: var(--c-text-3); font-size: var(--fs-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
.res.ok { color: var(--c-ok); font-weight: var(--fw-medium); }
.res.err { color: var(--c-err); font-weight: var(--fw-medium); }
.res.next { color: var(--c-text); font-weight: var(--fw-medium); }
.rl .acts { display: flex; gap: 4px; justify-content: flex-end; }

/* ---- Colonne droite : listes compactes ---------------------------------- */
.mini { display: flex; gap: 10px; padding: 11px 16px; border-top: 1px solid var(--c-line); align-items: flex-start; }
.mini:first-child { border-top: 0; }
.mini .when { font: 500 var(--fs-sm)/1.4 var(--f-mono); color: var(--c-text-2); width: 74px; flex: none; }
.mini .when small { display: block; font-family: var(--f-sans); color: var(--c-text-3); font-size: 12px; }
.mini .body { min-width: 0; flex: 1; font-size: var(--fs-sm); }
.mini .body b { font-weight: var(--fw-medium); display: block; font-size: var(--fs-md); }
.mini .body span { color: var(--c-text-3); }
.health-sum { display: flex; align-items: baseline; gap: 8px; padding: 14px 16px 10px; }
.health-sum .big { font: var(--fw-semibold) 24px/1 var(--f-display); letter-spacing: -0.03em; }
.svc-dots { display: flex; gap: 4px; padding: 0 16px 14px; flex-wrap: wrap; }
.svc-dots i { width: 14px; height: 14px; border-radius: 3px; background: var(--c-ok-bg); box-shadow: inset 0 0 0 1px var(--c-ok-line); }
.svc-dots i.warn { background: var(--c-warn-bg); box-shadow: inset 0 0 0 1px var(--c-warn-line); }
.svc-dots i.off { background: var(--c-off-bg); box-shadow: inset 0 0 0 1px var(--c-off-line); }
.alert { display: flex; gap: 10px; padding: 10px 16px; border-top: 1px solid var(--c-line); font-size: var(--fs-sm); }
.alert .dot { margin-top: 6px; }
.alert.err .dot { color: var(--c-err); } .alert.warn .dot { color: var(--c-warn); } .alert.off .dot { color: var(--c-off); }
.alert b { font-weight: var(--fw-medium); display: block; color: var(--c-text); }
.alert span { color: var(--c-text-3); }
.funnel { padding: 12px 16px 14px; display: flex; flex-direction: column; gap: 9px; }
.fn-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; font-size: var(--fs-sm); }
.fn-row .l { color: var(--c-text-2); }
.fn-row .n { font-family: var(--f-mono); color: var(--c-text); }
.fn-row .n small { color: var(--c-text-3); margin-left: 6px; }
.fn-bar { grid-column: 1 / -1; height: 6px; background: var(--c-surface-2); border-radius: 3px; overflow: hidden; }
.fn-bar i { display: block; height: 100%; background: var(--c-text); border-radius: 3px; min-width: 3px; }

/* ---- Fiche ---------------------------------------------------------------- */
.person-head { display: flex; gap: 16px; align-items: flex-start; margin-bottom: 20px; }
.person-head h1 { font: var(--fw-semibold) var(--fs-3xl)/var(--lh-tight) var(--f-display); letter-spacing: var(--tracking-title); }
.person-meta { display: flex; flex-wrap: wrap; gap: 4px 14px; color: var(--c-text-3); font-size: var(--fs-sm); margin-top: 6px; }
.person-meta span { display: inline-flex; align-items: center; gap: 5px; }
.person-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.person-head .btn-row { margin-left: auto; padding-top: 4px; }

.stepper { list-style: none; padding: 0; margin: 0 0 20px; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); border: 1px solid var(--c-line); border-radius: var(--r-lg); margin-bottom: 20px; overflow: hidden; }
.step { position: relative; padding: 11px 14px 12px; border-left: 1px solid var(--c-line); min-width: 0; }
.step:first-child { border-left: 0; }
.step .n { font-size: 12px; color: var(--c-text-3); display: flex; align-items: center; gap: 6px; }
.step .l { font-weight: var(--fw-medium); font-size: var(--fs-sm); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.step .d { font: 500 12px/1.3 var(--f-mono); color: var(--c-text-3); margin-top: 2px; white-space: nowrap; }
.step::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: transparent; }
.step.done::after { background: var(--c-text); }
.step.done .n .ico { color: var(--c-ok); }
.step.current { background: var(--st-mt5-bg); }
.step.current::after { background: var(--st-mt5); }
.step.current .l { color: var(--st-mt5); }
.step.pending .l, .step.pending .d { color: var(--c-text-3); }
.step.pending .d.hint { color: var(--c-warn); font-family: var(--f-sans); font-weight: var(--fw-medium); }

.grid-fiche { display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 20px; align-items: start; }

/* conversation */
.chat { padding: 4px 20px 20px; display: flex; flex-direction: column; gap: 6px; }
.chat .day { align-self: center; font-size: 12px; font-weight: var(--fw-medium); color: var(--c-text-3); margin: 14px 0 6px; display: flex; align-items: center; gap: 10px; width: 100%; }
.chat .day::before, .chat .day::after { content: ""; flex: 1; height: 1px; background: var(--c-line); }
.msg { max-width: 76%; display: flex; flex-direction: column; gap: 3px; }
.msg .bub { padding: 8px 12px; border-radius: 14px; font-size: var(--fs-md); line-height: 1.45; white-space: pre-line; }
.msg .meta { font-size: 12px; color: var(--c-text-3); display: flex; gap: 6px; align-items: center; padding: 0 4px; }
.msg.client { align-self: flex-start; }
.msg.client .bub { background: var(--chat-client-bg); color: var(--chat-client-text); border-bottom-left-radius: 4px; }
.msg.out { align-self: flex-end; align-items: flex-end; }
.msg.humain .bub { background: var(--chat-humain-bg); color: var(--chat-humain-text); border-bottom-right-radius: 4px; }
.msg.bot .bub { background: var(--chat-bot-bg); color: var(--chat-bot-text); border-bottom-right-radius: 4px; }
.msg.externe .bub { background: var(--chat-externe-bg); color: var(--chat-externe-text); border-bottom-right-radius: 4px; }
.msg .who-l { font-weight: var(--fw-medium); color: var(--c-text-2); }
.voice { display: flex; align-items: center; gap: 10px; min-width: 220px; }
.voice .play { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: currentColor; flex: none; }
.voice .play .ico { color: var(--c-surface); width: 12px; height: 12px; }
.voice .bars { display: flex; align-items: center; gap: 2px; height: 22px; flex: 1; }
.voice .bars i { width: 2px; border-radius: 1px; background: currentColor; opacity: .55; }
.voice .dur { font: 500 12px/1 var(--f-mono); }
.photo { display: flex; align-items: center; gap: 10px; }
.photo .thumb { width: 64px; height: 48px; border-radius: 8px; background: repeating-linear-gradient(135deg, var(--c-hatch-1) 0 6px, var(--c-hatch-2) 6px 12px); display: grid; place-items: center; color: var(--c-text-3); }
.sysl { align-self: center; font-size: var(--fs-sm); color: var(--c-text-3); padding: 2px 0; text-align: center; max-width: 92%; }
.sysl .ico { vertical-align: -2px; margin-right: 4px; }
.sysl .mono { margin-right: 6px; }
.sysl.strong { color: var(--st-mt5); font-weight: var(--fw-medium); }
.sysl .mono { font-size: 12px; }
.decision { align-self: stretch; margin: 2px 0 6px; border: 1px dashed var(--chat-ghost-line); border-radius: var(--r-md); background: linear-gradient(var(--c-surface), var(--c-surface)) padding-box; }
.decision-h { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--c-text-2); padding: 8px 12px; flex-wrap: wrap; }
.decision-h b { font-weight: var(--fw-medium); color: var(--c-text); }
.decision-h .h { margin-left: auto; font: 500 12px/1 var(--f-mono); color: var(--c-text-3); }
.ghost-reply { display: flex; gap: 10px; padding: 0 12px 10px; }
.ghost-reply .lbl { font-size: 12px; font-weight: var(--fw-semibold); color: var(--mode-bot); white-space: nowrap; display: flex; align-items: center; gap: 5px; padding-top: 7px; }
.ghost-reply .bub { flex: 1; font-size: var(--fs-md); color: var(--c-text-2); background: var(--c-surface-2); border-radius: 10px; padding: 7px 11px; font-style: italic; }
.decision .effet { font-size: var(--fs-sm); color: var(--c-text-2); padding: 0 12px 10px 12px; display: flex; gap: 6px; align-items: center; }
.relance-b { align-self: flex-end; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; max-width: 76%; }
.relance-b .bub { background: var(--chat-bot-bg); color: var(--chat-bot-text); padding: 8px 12px; border-radius: 14px; border-bottom-right-radius: 4px; }
.relance-b .meta { font-size: 12px; color: var(--c-text-3); display: flex; gap: 8px; align-items: center; }
.composer { display: flex; gap: 10px; align-items: center; padding: 12px 16px; border-top: 1px solid var(--c-line); background: var(--c-surface-2); border-radius: 0 0 var(--r-lg) var(--r-lg); }
.composer .fake { flex: 1; height: 36px; border: 1px solid var(--c-line); border-radius: var(--r-md); background: var(--c-surface); display: flex; align-items: center; padding: 0 12px; color: var(--c-text-3); font-size: var(--fs-sm); }
.toggle { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--c-text-2); }
.toggle .sw { width: 28px; height: 16px; border-radius: 8px; background: var(--c-accent); position: relative; }
.toggle .sw::after { content: ""; position: absolute; top: 2px; right: 2px; width: 12px; height: 12px; border-radius: 50%; background: var(--c-surface); }

/* timeline des relances */
.tl { list-style: none; margin: 0; padding: 6px 0 4px; }
.tl-h { padding: 10px 16px 4px; font-size: var(--fs-label); font-weight: var(--fw-semibold); color: var(--c-text-3); text-transform: uppercase; letter-spacing: var(--tracking-label); }
.tl li { display: grid; grid-template-columns: 18px 1fr; gap: 10px; padding: 8px 16px; position: relative; }
.tl li::before { content: ""; position: absolute; left: 24px; top: 26px; bottom: -8px; width: 1px; background: var(--c-line); }
.tl li:last-child::before { display: none; }
.tl .node { width: 10px; height: 10px; border-radius: 50%; margin: 5px 0 0 4px; background: var(--c-surface); box-shadow: inset 0 0 0 2px var(--rt, var(--c-text-3)); position: relative; z-index: 1; }
.tl .past .node { background: var(--rt); box-shadow: none; }
.tl .cancel .node { background: var(--c-surface); box-shadow: inset 0 0 0 2px var(--c-line-strong); }
.tl .when { font: 500 12px/1.3 var(--f-mono); color: var(--c-text-3); }
.tl .what { font-weight: var(--fw-medium); display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 1px; }
.tl .why { font-size: var(--fs-sm); color: var(--c-text-3); }
.tl .r-ok { color: var(--c-ok); } .tl .r-none { color: var(--c-text-3); } .tl .r-cancel { color: var(--c-text-3); text-decoration: line-through; text-decoration-color: var(--c-line-strong); }
.tl .next-card { background: var(--c-accent-soft); border-radius: var(--r-md); margin: 0 -8px; padding: 8px; }
.tl .acts { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.note-guard { margin: 4px 16px 14px; padding: 9px 12px; border-radius: var(--r-md); background: var(--c-surface-2); font-size: var(--fs-sm); color: var(--c-text-2); display: flex; gap: 8px; }

/* attributs clé / valeur */
.kv { display: grid; grid-template-columns: 116px 1fr; gap: 0; font-size: var(--fs-sm); }
.kv dt { color: var(--c-text-3); padding: 7px 0 7px 16px; }
.kv dd { margin: 0; padding: 7px 16px 7px 0; color: var(--c-text); min-width: 0; display: flex; align-items: center; gap: 6px; }
.kv dd a { color: var(--c-accent); }
.acct { padding: 12px 16px; display: grid; gap: 8px; }
.acct-top { display: flex; align-items: center; gap: 8px; }
.acct-num { font: 600 var(--fs-lg)/1 var(--f-mono); letter-spacing: 0.02em; }
.acct .kv { grid-template-columns: 100px 1fr; margin: 0 -16px; }
.secret { font-family: var(--f-mono); letter-spacing: 0.15em; color: var(--c-text-2); }
.dep { padding: 12px 16px; display: flex; align-items: center; gap: 12px; }
.dep .amt { font: 600 var(--fs-xl)/1 var(--f-display); letter-spacing: -0.02em; white-space: nowrap; }
.dep .info { font-size: var(--fs-sm); color: var(--c-text-3); }
.empty-line { padding: 10px 16px 14px; font-size: var(--fs-sm); color: var(--c-text-3); }

/* ---- Barre basse et en-tête mobile -------------------------------------- */
.seg .short { display: none; }
.m-more { display: none; padding: 12px 16px; border-top: 1px solid var(--c-line); font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--c-accent); align-items: center; gap: 6px; }
.m-head, .bottomnav, .m-actions, .subnav, .stepper-m { display: none; }
.stepper-m .top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: var(--fs-sm); color: var(--c-text-3); }
.stepper-m .top b { color: var(--st-mt5); font-weight: var(--fw-semibold); font-size: var(--fs-md); }
.stepper-m .bars { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; margin: 10px 0 8px; }
.stepper-m .bars i { height: 6px; border-radius: 3px; background: var(--seq-todo); }
.stepper-m .bars i.done { background: var(--c-text); }
.stepper-m .bars i.cur { background: var(--st-mt5); }
.stepper-m .nxt { font-size: var(--fs-sm); color: var(--c-text-2); }
.stepper-m .nxt b { color: var(--c-warn); font-weight: var(--fw-medium); }

/* ---- Responsive ------------------------------------------------------------ */
@media (max-width: 1280px) {
  .stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .stat:nth-child(4) { border-left: 0; }
  .stat:nth-child(n+4) { border-top: 1px solid var(--c-line); }
}
@media (max-width: 1100px) {
  .grid-main, .grid-fiche { grid-template-columns: minmax(0, 1fr); }
  .stepper { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .step:nth-child(4) { border-left: 0; }
  .step:nth-child(n+4) { border-top: 1px solid var(--c-line); }
}
@media (max-width: 760px) {
  body { background: var(--c-bg); padding-bottom: calc(var(--bottomnav-h) + env(safe-area-inset-bottom)); }
  .app { display: block; }
  .sidebar, .topbar { display: none; }
  .sheet { margin: 0; border: 0; border-radius: 0; box-shadow: none; }
  .content { padding: 16px 16px 28px; }
  .m-head {
    display: flex; align-items: center; gap: 10px; height: 56px; padding: 0 12px 0 16px; position: sticky; top: 0; z-index: 20;
    background: var(--c-glass); backdrop-filter: blur(10px); border-bottom: 1px solid var(--c-line);
  }
  .m-head .title { font-weight: var(--fw-semibold); font-size: var(--fs-lg); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .m-head .btn.icon { width: var(--tap); height: var(--tap); border: 0; box-shadow: none; background: transparent; }
  .m-head .brand-mark { width: 28px; height: 28px; }
  .page-head { flex-direction: column; align-items: stretch; gap: 10px; margin-bottom: 16px; }
  .page-head .btn-row { margin-left: 0; }
  .page-head h1 { font-size: var(--fs-3xl); }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 16px; }
  .stat { padding: 12px 14px; }
  .stat:nth-child(odd) { border-left: 0; }
  .stat:nth-child(4) { border-left: 1px solid var(--c-line); }
  .stat:nth-child(n+3) { border-top: 1px solid var(--c-line); }
  .stat .v { font-size: 24px; }
  .grid-main, .col { gap: 16px; }
  .panel-h { padding: 12px 14px; flex-wrap: wrap; }
  .panel-h .right { margin-left: 0; width: 100%; }
  .panel-h .right.keep { width: auto; margin-left: auto; }
  .seg { width: 100%; overflow-x: auto; }
  .seg a { flex: 1; justify-content: center; height: 32px; padding: 0 6px; gap: 4px; }
  .seg .long { display: none; }
  .seg .short { display: inline; }
  .legend { padding: 10px 14px 0; }

  /* lignes de relance -> cartes */
  .rl {
    grid-template-columns: 48px minmax(0, 1fr) auto; grid-template-areas: "h who acts" "h type type" "h res res";
    gap: 6px 10px; padding: 12px 14px; align-items: start;
  }
  .rl .h { grid-area: h; padding-top: 8px; }
  .rl .who { grid-area: who; }
  .rl .typecell { grid-area: type; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .rl .frise-cell { display: none; }
  .rl .res { grid-area: res; }
  .rl .acts { grid-area: acts; }
  .rl .acts .btn { width: 40px; height: 40px; padding: 0; }
  .rl .acts .bl { display: none; }
  .rl .acts .opt { display: none; }
  .m-hide { display: none !important; }
  .m-more { display: flex !important; }
  .mini, .alert { padding: 12px 14px; }
  .bottomnav {
    display: grid; grid-template-columns: repeat(5, 1fr); position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    height: calc(var(--bottomnav-h) + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom);
    background: var(--c-glass); backdrop-filter: blur(12px); border-top: 1px solid var(--c-line);
  }
  .bottomnav a { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; font-size: 12px; font-weight: var(--fw-medium); color: var(--c-text-3); position: relative; }
  .bottomnav a .ico { width: 22px; height: 22px; }
  .bottomnav a[aria-current="page"] { color: var(--c-text); }
  .bottomnav a[aria-current="page"]::before { content: ""; position: absolute; top: 0; left: 30%; right: 30%; height: 2px; background: var(--c-text); border-radius: 0 0 2px 2px; }
  .bottomnav .bdg { position: absolute; top: 8px; left: calc(50% + 6px); min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--c-err); color: var(--c-on-err); font: 600 11px/18px var(--f-sans); text-align: center; }
  .bottomnav .bdg.humain { background: var(--mode-humain); }

  /* fiche mobile */
  .person-head { flex-wrap: nowrap; gap: 12px; margin-bottom: 14px; }
  .person-head .av.lg { width: 44px; height: 44px; font-size: 16px; }
  .person-head h1 { font-size: 24px; }
  .person-head .btn-row { display: none; }
  .stepper { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 46%; overflow-x: auto; scroll-snap-type: x mandatory; }
  .step { scroll-snap-align: start; border-top: 0 !important; border-left: 1px solid var(--c-line) !important; }
  .step:first-child { border-left: 0 !important; }
  .subnav {
    display: flex; gap: 6px; overflow-x: auto; position: sticky; top: 56px; z-index: 15; background: var(--c-glass);
    backdrop-filter: blur(10px); margin: 0 -16px 14px; padding: 8px 16px; border-bottom: 1px solid var(--c-line); scrollbar-width: none;
  }
  .subnav a { height: 34px; padding: 0 12px; border-radius: var(--r-pill); border: 1px solid var(--c-line); display: inline-flex; align-items: center; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--c-text-2); white-space: nowrap; }
  .subnav a[aria-current="true"] { background: var(--c-text); color: var(--c-text-inv); border-color: var(--c-text); }
  .grid-fiche { display: flex; flex-direction: column; gap: 16px; }
  .grid-fiche > .col { display: contents; }
  .o-1 { order: 1; } .o-2 { order: 2; } .o-3 { order: 3; } .o-4 { order: 4; } .o-5 { order: 5; } .o-6 { order: 6; } .o-7 { order: 7; } .o-8 { order: 8; } .o-9 { order: 9; }
  .chat { padding: 4px 12px 16px; }
  .msg, .relance-b { max-width: 88%; }
  .voice { min-width: 200px; }
  .composer { display: none; }
  .tl .acts .btn { height: 36px; }
  body.detail { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
  body.detail .bottomnav { display: none; }
  .m-actions {
    display: grid; grid-template-columns: 48px 48px minmax(0, 1fr); gap: 8px; position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom)); background: var(--c-glass); backdrop-filter: blur(12px); border-top: 1px solid var(--c-line);
  }
  .m-actions .btn { height: 48px; font-size: var(--fs-md); padding: 0; }
  .m-actions .btn .ico { width: 20px; height: 20px; }
  .ghost-reply { flex-direction: column; gap: 4px; }
  .ghost-reply .lbl { padding-top: 0; }
  .decision-h .h { margin-left: 0; }
  .relance-b .meta, .msg .meta { flex-wrap: wrap; justify-content: flex-end; }
  .stepper { display: none; }
  .stepper-m { display: block; margin-bottom: 14px; padding: 12px 14px; border: 1px solid var(--c-line); border-radius: var(--r-lg); }
  .subnav { -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent); mask-image: linear-gradient(90deg, #000 85%, transparent); }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* ---- Écran Relances ------------------------------------------------------- */
.filters { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 16px; }
.fpill { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px; border-radius: var(--r-sm); border: 1px dashed var(--c-line-strong); font-size: var(--fs-sm); color: var(--c-text-2); font-weight: var(--fw-medium); white-space: nowrap; }
.fpill.on { border-style: solid; background: var(--c-accent-soft); border-color: var(--c-accent-line); color: var(--c-accent); }
.fpill b { font-weight: var(--fw-semibold); color: var(--c-text); }
.fpill.on b { color: var(--c-accent); }
.filters .sep { width: 1px; height: 20px; background: var(--c-line); }
.pl { display: grid; grid-template-columns: 52px minmax(160px, 1.3fr) minmax(130px, 1fr) minmax(140px, 1.3fr) 104px; gap: 12px; align-items: center; padding: 9px 16px; border-top: 1px solid var(--c-line); min-height: 50px; }
.group-h + .pl { border-top: 0; }
.pl:hover { background: var(--c-surface-2); }
.pl .h { font: 500 var(--fs-md)/1 var(--f-mono); }
.pl .note { font-size: var(--fs-sm); color: var(--c-text-3); min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl .note.warn { color: var(--c-warn); font-weight: var(--fw-medium); }
.pl .acts { display: flex; gap: 4px; justify-content: flex-end; }
.more-row { padding: 9px 16px; border-top: 1px solid var(--c-line); font-size: var(--fs-sm); color: var(--c-accent); font-weight: var(--fw-medium); display: flex; align-items: center; gap: 6px; }
.rate { display: grid; grid-template-columns: minmax(0, 1fr) 46px 40px; gap: 6px 10px; align-items: center; padding: 8px 16px; font-size: var(--fs-sm); }
.rate .bar { grid-column: 1 / -1; height: 6px; border-radius: 3px; background: var(--c-surface-2); overflow: hidden; }
.rate .bar i { display: block; height: 100%; background: var(--rt); border-radius: 3px; min-width: 2px; }
.rate .n { font-family: var(--f-mono); color: var(--c-text-3); text-align: right; }
.rate .p { font: 600 var(--fs-sm)/1 var(--f-mono); text-align: right; }
.rate .p.low { color: var(--c-err); } .rate .p.mid { color: var(--c-warn); } .rate .p.high { color: var(--c-ok); }

@media (max-width: 760px) {
  .filters { flex-wrap: nowrap; overflow-x: auto; margin: 0 -16px 14px; padding: 0 16px; scrollbar-width: none; }
  .filters .fpill { height: 36px; flex: none; }
  .pl { grid-template-columns: 48px minmax(0, 1fr) auto; grid-template-areas: "h who acts" "h ty ty" "h note note"; gap: 6px 10px; padding: 12px 14px; align-items: start; }
  .pl .h { grid-area: h; padding-top: 8px; } .pl .who { grid-area: who; } .pl .typecell { grid-area: ty; } .pl .note { grid-area: note; white-space: normal; } .pl .acts { grid-area: acts; }
  .pl .acts .btn { width: 40px; height: 40px; padding: 0; } .pl .acts .opt, .pl .acts .bl { display: none; }
}

/* ==========================================================================
   Ajouts de la direction D
   ========================================================================== */

/* ---- Barre haute collante + bouton de thème ------------------------------ */
.topbar { position: sticky; top: 0; z-index: 12; background: var(--c-glass); backdrop-filter: blur(10px); border-radius: var(--r-lg) var(--r-lg) 0 0; }
.theme-toggle .t-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .t-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .t-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .t-sun { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .t-moon { display: none; }
}

/* ---- Mise en page « Aujourd'hui » : contenu + colonne latérale collante --- */
.l-today { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 20px; align-items: start; }
.l-today > .col { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.side { position: sticky; top: 64px; max-height: calc(100vh - 76px); overflow-y: auto; scrollbar-width: thin; padding-bottom: 4px; }
.l-today .page-head { margin-bottom: 0; }
.duo { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; }
.stats.s4 { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-bottom: 0; }
.stats.s5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }

/* ---- Ruban des relances (repris de B, au style de A) --------------------- */
.ribbon .figs { margin-left: auto; display: flex; gap: 16px; font-size: var(--fs-sm); color: var(--c-text-3); white-space: nowrap; }
.ribbon .figs b { font: 600 var(--fs-md)/1 var(--f-mono); color: var(--c-text); margin-right: 3px; }
.ribbon .figs .ok b { color: var(--c-ok); } .ribbon .figs .err b { color: var(--c-err); }
.rb-scroll { position: relative; overflow-x: auto; scrollbar-width: none; padding: 0 16px; }
.rb-scroll::-webkit-scrollbar { display: none; }
.rb-track { position: relative; height: calc(var(--lanes, 3) * 28px + 50px); margin: 12px 10px 0; }
.rb-axis { position: absolute; left: 0; right: 0; bottom: 22px; height: 4px; border-radius: 2px; background: var(--rb-track); }
.rb-axis .past { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 2px; background: var(--rb-past); }
.rb-hour { position: absolute; bottom: 0; transform: translateX(-50%); font: 500 11px/1 var(--f-mono); color: var(--c-text-3); }
.rb-hour::before { content: ""; position: absolute; left: 50%; bottom: 15px; width: 1px; height: 8px; background: var(--c-line-strong); }
.rb-needle { position: absolute; top: 0; bottom: 15px; width: 2px; margin-left: -1px; background: var(--c-accent); border-radius: 1px; }
.rb-needle span { position: absolute; top: -2px; left: 7px; font: 600 12px/1 var(--f-mono); color: var(--c-accent); background: var(--c-surface); padding: 2px 4px; border-radius: 4px; white-space: nowrap; }
.mk {
  position: absolute; bottom: calc(36px + var(--lane, 0) * 28px); transform: translateX(-50%);
  width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  font: 600 10px/1 var(--f-sans); color: var(--c-text); background: var(--c-surface); box-shadow: inset 0 0 0 1.5px var(--rt);
}
.mk:hover { z-index: 2; box-shadow: inset 0 0 0 1.5px var(--rt), 0 0 0 3px var(--c-accent-soft); }
.mk.sent { background: color-mix(in srgb, var(--rt) 20%, var(--c-surface)); box-shadow: none; color: var(--c-text-2); }
.mk.rep::after { content: ""; position: absolute; right: -2px; top: -2px; width: 8px; height: 8px; border-radius: 50%; background: var(--c-ok); box-shadow: 0 0 0 2px var(--c-surface); }
.mk.late { background: var(--c-err-bg); box-shadow: inset 0 0 0 1.5px var(--c-err); color: var(--c-err); }
.rb-legend { display: flex; gap: 8px 16px; flex-wrap: wrap; align-items: center; padding: 10px 16px 12px; margin-top: 10px; border-top: 1px solid var(--c-line); font-size: 12px; color: var(--c-text-3); }
.rb-legend span { display: inline-flex; align-items: center; gap: 6px; }
.rb-legend i { width: 11px; height: 11px; border-radius: 50%; display: inline-block; flex: none; }
.rb-legend .l-sent { background: color-mix(in srgb, var(--rt-j1) 25%, var(--c-surface)); }
.rb-legend .l-rep { background: var(--c-ok); width: 8px; height: 8px; }
.rb-legend .l-late { background: var(--c-err-bg); box-shadow: inset 0 0 0 1.5px var(--c-err); }
.rb-legend .l-next { box-shadow: inset 0 0 0 1.5px var(--rt-j1); }
.rb-legend .types { margin-left: auto; display: flex; gap: 6px 12px; flex-wrap: wrap; }
.rb-legend .types .tag { font-size: 12px; color: var(--c-text-3); }

/* ---- Carte « Maintenant » (reprise de C, au style de A) ------------------ */
.now { position: relative; background: var(--now-bg); border: 1px solid var(--now-line); border-radius: var(--r-lg); padding: 16px 16px 14px 18px; box-shadow: var(--sh-2); }
.now::before { content: ""; position: absolute; left: -1px; top: 16px; bottom: 16px; width: 3px; border-radius: 0 3px 3px 0; background: var(--c-accent); }
.now .lbl { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-label); font-weight: var(--fw-semibold); letter-spacing: 0.08em; text-transform: uppercase; color: var(--c-accent); }
.now .lbl .pulse { width: 8px; height: 8px; border-radius: 50%; background: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-soft); }
.now .lbl .when { color: var(--c-text-3); letter-spacing: 0; text-transform: none; font-weight: var(--fw-regular); }
.now h2 { font: var(--fw-semibold) 18px/1.3 var(--f-display); letter-spacing: -0.015em; margin: 8px 0 4px; }
.now p { font-size: var(--fs-sm); color: var(--c-text-2); }
.now .who { display: flex; align-items: center; gap: 10px; margin-top: 12px; font-size: var(--fs-sm); min-width: 0; }
.now .who b { font-weight: var(--fw-medium); display: block; color: var(--c-text); }
.now .who span { color: var(--c-text-3); }
.now .acts { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 14px; }
.now .acts .btn { height: 36px; }
.now .acts .btn:first-child { grid-column: 1 / -1; }
.now .next { margin: 14px -16px 0 -18px; padding: 10px 16px 0 18px; border-top: 1px solid var(--now-line); }
.now .next h3 { font-size: var(--fs-label); font-weight: var(--fw-semibold); color: var(--c-text-3); text-transform: uppercase; letter-spacing: var(--tracking-label); margin-bottom: 4px; }
.now .next ol { list-style: none; margin: 0; padding: 0; }
.now .next li a { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 10px; align-items: center; padding: 7px 0; border-radius: var(--r-sm); }
.now .next li + li a { border-top: 1px solid var(--c-line); }
.now .next .n { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font: 600 11px/1 var(--f-mono); color: var(--c-text-2); background: var(--c-surface); box-shadow: inset 0 0 0 1px var(--c-line-strong); }
.now .next .t { min-width: 0; font-size: var(--fs-sm); }
.now .next .t b { display: block; font-weight: var(--fw-medium); color: var(--c-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.now .next .t span { display: block; color: var(--c-text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.now .next .r { font: 500 12px/1 var(--f-mono); color: var(--c-text-3); white-space: nowrap; }
.now .next .r.err { color: var(--c-err); } .now .next .r.humain { color: var(--mode-humain); }
.now.compact h2 { font-size: var(--fs-lg); }

/* ---- Tableau compact (charge de la semaine) ------------------------------ */
.wtable { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.wtable th { font-size: 12px; font-weight: var(--fw-medium); color: var(--c-text-3); text-align: right; padding: 8px 10px; border-bottom: 1px solid var(--c-line); white-space: nowrap; }
.wtable td { text-align: right; padding: 8px 10px; border-bottom: 1px solid var(--c-line); font-family: var(--f-mono); font-variant-numeric: tabular-nums; }
.wtable tr:last-child td { border-bottom: 0; }
.wtable th:first-child, .wtable td:first-child { text-align: left; padding-left: 16px; font-family: var(--f-sans); }
.wtable th:last-child, .wtable td:last-child { padding-right: 16px; }
.wtable td.z { color: var(--c-text-3); }
.wtable td.tot { font-weight: 600; color: var(--c-text); }
.wtable tr.cur td { background: var(--c-accent-soft); }
.wtable tr.cur td:first-child { color: var(--c-accent); font-weight: var(--fw-medium); }
.wtable th .tag { justify-content: flex-end; font-size: 12px; color: var(--c-text-3); }
.mix { display: flex; height: 8px; width: 120px; border-radius: 4px; overflow: hidden; gap: 1px; background: var(--rb-track); margin-left: auto; }
.mix i { display: block; height: 100%; background: var(--rt); }

/* ---- Suivi par prospect (frise + compteur) ------------------------------- */
.track-row { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 9px 16px; border-top: 1px solid var(--c-line); font-size: var(--fs-sm); }
.track-row:first-child { border-top: 0; }
.track-row .n { font-weight: var(--fw-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.track-row .c { font: 500 12px/1 var(--f-mono); color: var(--c-text-3); }

/* ---- Responsive D -------------------------------------------------------- */
@media (max-width: 1280px) {
  .l-today { grid-template-columns: minmax(0, 1fr) 330px; }
  .stats.s5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .stats.s5 .stat:nth-child(4) { border-left: 0; }
  .stats.s5 .stat:nth-child(n+4) { border-top: 1px solid var(--c-line); }
}
@media (max-width: 1100px) {
  .l-today { grid-template-columns: minmax(0, 1fr); }
  .side { position: static; max-height: none; overflow: visible; }
}
@media (max-width: 760px) {
  .topbar { display: none; }
  .l-today { display: flex; flex-direction: column; align-items: stretch; gap: 16px; }
  .l-today > * , .l-today > .col > * { min-width: 0; }
  .l-today > .col { display: contents; }
  .l-today .page-head { margin: 4px 0 -4px; }
  .l-today .page-head h1 { display: none; }
  .l-today .page-head .sub { margin-top: 0; font-size: var(--fs-sm); }
  .side { position: static; max-height: none; overflow: visible; padding: 0; }
  .duo { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .stats.s4, .stats.s5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats.s5 .stat:last-child { grid-column: 1 / -1; border-left: 0; }
  .ribbon .panel-h { flex-wrap: wrap; }
  .ribbon .figs { margin-left: 0; width: 100%; justify-content: space-between; gap: 8px; }
  .rb-scroll { -webkit-mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent); }
  .rb-track { min-width: 860px; }
  .rb-legend .types { display: none; }
  .now { padding: 14px 14px 12px 16px; }
  .now .next { margin: 12px -14px 0 -16px; padding: 8px 14px 0 16px; }
  .now .acts .btn { height: var(--tap); }
  .wtable .hide-m { display: none; }
  .mix { width: 100%; min-width: 90px; }
  .track-row { padding: 10px 14px; }
}

/* ---- En-tête de fiche : actions sur une seule ligne ------------------------ */
.person-head > div:nth-child(2) { flex: 1; }
.person-head .btn-row { flex-wrap: nowrap; flex: none; }
.tl .acts { gap: 4px; }
.tl .acts .btn.sm { padding: 0 9px; }

/* ---- Planning avec frise (écran Relances) -------------------------------- */
.pl.fr { grid-template-columns: 52px minmax(150px, 1.3fr) minmax(118px, 1fr) 80px minmax(130px, 1.2fr) 104px; }
@media (max-width: 760px) {
  .pl.fr { grid-template-columns: 48px minmax(0, 1fr) auto; }
  .pl.fr .frise-cell { display: none; }
}

/* ==========================================================================
   Compléments du dashboard (services/dashboard) — ajoutés après les maquettes D
   Polices auto-hébergées, recherche, connexion, filtres en <select>, tableaux
   de listes, pagination, états « vide » et « indisponible », menu « Plus ».
   ========================================================================== */
@font-face { font-family: "Geist"; src: url("/static/fonts/Geist-Variable.woff2") format("woff2");
             font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("/static/fonts/GeistMono-Variable.woff2") format("woff2");
             font-weight: 100 900; font-display: swap; }

.side-search input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--c-text); font: inherit; outline: none; }
.side-search:focus-within { border-color: var(--c-accent-line); box-shadow: 0 0 0 2px var(--c-accent-soft); }

.champ { display: grid; gap: 6px; margin-bottom: 14px; font-size: var(--fs-sm); }
.champ label { color: var(--c-text-2); font-weight: var(--fw-medium); }
.champ input, .champ select, .filters select, .filters input[type="search"] {
  height: 36px; padding: 0 10px; border: 1px solid var(--c-line-strong); border-radius: var(--r-sm);
  background: var(--c-surface); color: var(--c-text); font: inherit; font-size: var(--fs-sm); min-width: 0;
}
.filters select, .filters input[type="search"] { height: 30px; }
.filters form { display: contents; }
.case { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--c-text-2); margin-bottom: 18px; }

.page-seule { min-height: 100vh; display: grid; place-items: center; padding: 16px; background: var(--c-frame); }
.carte-seule { width: min(380px, 100%); background: var(--c-surface); border: 1px solid var(--c-line); border-radius: var(--r-lg); padding: 28px; box-shadow: var(--sh-2); }
.carte-seule .brand { margin-bottom: 22px; }
.carte-seule h1 { font-size: var(--fs-xl); margin-bottom: 18px; }
.carte-seule .btn { width: 100%; height: 40px; }
.message-erreur { padding: 10px 12px; margin-bottom: 14px; border-radius: var(--r-sm); background: var(--c-err-bg); border: 1px solid var(--c-err-line); color: var(--c-err); font-size: var(--fs-sm); }

.bloc-indispo { display: flex; align-items: center; gap: 8px; padding: 12px 16px; font-size: var(--fs-sm); color: var(--c-err); background: var(--c-err-bg); border-top: 1px solid var(--c-err-line); }
.fraicheur { font: 500 11px/1 var(--f-mono); color: var(--c-text-3); white-space: nowrap; }

.table-scroll { overflow-x: auto; }
.wtable.lst th, .wtable.lst td { text-align: left; font-family: var(--f-sans); }
.wtable.lst td.num, .wtable.lst th.num { text-align: right; font-family: var(--f-mono); }
.wtable.lst td a { color: var(--c-text); font-weight: var(--fw-medium); }
.wtable.lst td a:hover { color: var(--c-accent); }
.wtable.lst td .s { display: block; color: var(--c-text-3); font-size: 12px; }
.wtable td.alerte { color: var(--c-err); font-weight: var(--fw-semibold); }

.pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; border-top: 1px solid var(--c-line); font-size: var(--fs-sm); color: var(--c-text-3); }
.pager .btn-row { gap: 6px; }

.ligne-lien { display: flex; align-items: center; gap: 10px; padding: 10px 16px; border-top: 1px solid var(--c-line); font-size: var(--fs-sm); }
.ligne-lien:first-child { border-top: 0; }
a.ligne-lien:hover { background: var(--c-surface-2); }  /* seulement les lignes cliquables */
.ligne-lien .n { font-weight: var(--fw-medium); }
.ligne-lien .s { color: var(--c-text-3); margin-left: auto; }

.chat details.fantomes { margin: 4px 0 4px auto; max-width: 92%; }
.chat details.fantomes summary { cursor: pointer; font-size: 12px; color: var(--c-text-3); list-style: none; text-align: right; }
.chat details.fantomes summary::-webkit-details-marker { display: none; }
.msg .bub.non-envoye { border: 1px dashed var(--chat-ghost-line); background: transparent; }
.msg .meta .fantome { color: var(--c-text-3); font-style: italic; }

.btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }

.plus-menu { list-style: none; margin: 0; padding: 0; }
.plus-menu a, .plus-menu button { display: flex; align-items: center; gap: 12px; min-height: var(--tap); padding: 0 16px; border-top: 1px solid var(--c-line); font-size: var(--fs-md); color: var(--c-text); background: none; border-left: 0; border-right: 0; border-bottom: 0; width: 100%; text-align: left; font-family: inherit; cursor: pointer; }
.plus-menu li:first-child a { border-top: 0; }
.plus-menu .count { margin-left: auto; font: 500 12px/1 var(--f-mono); color: var(--c-text-3); }
.plus-menu .count.err { color: var(--c-err); }
.plus-menu .count.warn { color: var(--c-warn); }
.count.indispo { cursor: help; }
.plus-sep { margin-top: 14px; }
.plus-moteur { display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; }

.barres { display: grid; gap: 6px; padding: 10px 16px 14px; }
.barres .b { display: grid; grid-template-columns: 74px minmax(0, 1fr) 44px; gap: 10px; align-items: center; font-size: var(--fs-sm); }
.barres .b .fn-bar { grid-column: auto; height: 8px; margin: 0; }
.barres .b .v { font-family: var(--f-mono); text-align: right; color: var(--c-text-2); }

@media (max-width: 760px) {
  .filters select, .filters .btn { flex: none; }
  .wtable.lst .hide-m { display: none; }
  .pager { flex-wrap: wrap; }
  .carte-seule { padding: 22px; }
}

/* ---- Aujourd'hui : ruban borné, carte Maintenant, largeurs intermédiaires (tâche 14) ----------
   Pastille « +N » du dernier couloir du ruban (routes._relances.plafonner_couloirs) : neutre, ou
   « en retard » si elle contient un retard. */
.mk.pile { width: auto; min-width: 24px; padding: 0 5px; border-radius: 12px; background: var(--c-surface-2); box-shadow: inset 0 0 0 1.5px var(--c-line-strong); color: var(--c-text-2); }
.mk.pile.late { background: var(--c-err-bg); box-shadow: inset 0 0 0 1.5px var(--c-err); color: var(--c-err); }
.mk.pile:hover { box-shadow: inset 0 0 0 1.5px var(--c-line-strong), 0 0 0 3px var(--c-accent-soft); }
.mk.pile.late:hover { box-shadow: inset 0 0 0 1.5px var(--c-err), 0 0 0 3px var(--c-accent-soft); }
/* Carte « Maintenant » : en lecture seule, « Telegram » est seul sur sa ligne (pas de « Plus tard »). */
.now .acts .btn:nth-child(2):last-child { grid-column: 1 / -1; }
.now .next .next-indispo { display: flex; align-items: center; gap: 6px; padding: 8px 0 2px; font-size: var(--fs-sm); color: var(--c-err); }
/* Chiffres clés : le détail passe à la ligne au lieu d'être coupé ; sous 1400 px, tuiles en 2 × 2
   (4 tuiles de moins de 170 px coupaient leur libellé, maquette comprise). */
.l-today .stats.s4 .stat .d { white-space: normal; }
/* À traiter : le motif tient sur 2 lignes (texte complet dans `title`). */
.l-today .pl .note { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
/* Lignes de relance et d'« À traiter » hors mobile : une seule action (chevron, 28 px) au lieu des
   104 px de boutons de la maquette, colonnes souples (minmax(0, …)) : plus aucune ligne ne déborde
   de sa carte, quelle que soit la largeur (1366, 1280, 1100, 1024 px…). La frise disparaît quand la
   liste fait moins de 640 px de large (requête de conteneur sur le panneau). */
@media (min-width: 761px) {
  .l-today .rel-jour { container-type: inline-size; }
  .l-today .rl { grid-template-columns: 48px minmax(0, 1.3fr) minmax(0, 1fr) 80px minmax(0, 1.2fr) 28px; }
  .l-today .pl { grid-template-columns: 52px minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1.4fr) 28px; }
  .l-today .rl .typecell, .l-today .pl .typecell { min-width: 0; overflow: hidden; }
  .l-today .pl .typecell .badge { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; line-height: 22px; }
}
@media (min-width: 761px) and (max-width: 1400px) {
  .l-today .stats.s4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .l-today .stats.s4 .stat:nth-child(3) { border-left: 0; }
  .l-today .stats.s4 .stat:nth-child(4) { border-left: 1px solid var(--c-line); }
  .l-today .stats.s4 .stat:nth-child(n+3) { border-top: 1px solid var(--c-line); }
}
@container (max-width: 640px) {
  .l-today .rl { grid-template-columns: 48px minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1.2fr) 28px; }
  .l-today .rl .frise-cell { display: none; }
}
/* Frise unique des écrans (domain.relances_vue.frise_verifiee) : une relance journalisée sans envoi
   réel (fantôme) est en pointillés, comme sur Relances et la fiche. */
.l-today .frise i.f-fantome { background: transparent; border: 1px dashed var(--seq-sent); box-sizing: border-box; }
/* Relances envoyées : « Envoyée mar. 13/10 à 13:05 · moins de 48 h » tient sur 2 lignes (texte complet
   dans `title`) au lieu d'être coupé. */
@media (min-width: 761px) {
  .l-today .rl.sent .res .l2 { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
}

/* ---- Prospects & clients : filtres, note d'export, cartes jusqu'à 1000 px (tâche 15) ----------
   Les filtres sont des <select> (et non les pastilles de l'écran Relances) : sur mobile ils passent
   en grille de 2 colonnes, au lieu du ruban défilant qui cachait 3 filtres sur 5 hors de l'écran.
   Jusqu'à 1000 px (mobile ET tablette : la barre latérale reste affichée dès 761 px et ne laisse que
   450 à 760 px au contenu), chaque ligne du tableau devient une carte : à ces largeurs, six colonnes
   défilaient dans leur cadre ou coupaient les noms au milieu des mots (« Tchamb/a », « Nova/Pips » :
   mesuré, le tableau n'est propre qu'à partir de 990 px). Le lien de la fiche couvre toute la carte
   (cible tactile pleine). En carte, les en-têtes sont retirés : chaque cellule porte son propre
   libellé (<span class="sr">), sinon un lecteur d'écran annoncerait « Activité » pour le bot. */
.note-export { font-size: var(--fs-sm); align-self: center; }
.filtres-note { margin: -6px 0 16px; border: 1px solid var(--c-err-line); border-radius: var(--r-sm); overflow: hidden; }
.filtres-note .bloc-indispo { border-top: 0; }
/* Garde-fou du TABLEAU (au-dessus de 1000 px) : un nom, un pseudo ou un affilié vient de Telegram,
   une chaîne de 80 caractères sans espace ne doit ni élargir le tableau ni le faire défiler. En
   carte les cellules sont des blocs : la règle n'y change rien. */
.wtable.lst.lst-cartes .c-who, .wtable.lst.lst-cartes .c-aff { overflow-wrap: anywhere; }
.filters.filtres-liste select { max-width: 240px; }  /* un affilié au nom démesuré n'élargit pas le filtre */
.wtable.lst.lst-cartes .c-act { white-space: nowrap; }  /* la date ne se coupe jamais : ce sont les autres colonnes qui cèdent */
/* Tableau de 1001 à 1100 px : sans la colonne « Messages », il reste assez de place pour la date. */
@media (max-width: 1100px) {
  .wtable.lst.lst-cartes .c-msg { display: none; }
}
@media (max-width: 1000px) {
  .wtable.lst.lst-cartes thead { display: none; }
  .wtable.lst.lst-cartes, .wtable.lst.lst-cartes tbody { display: block; }
  .wtable.lst.lst-cartes tr { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 12px 16px; border-bottom: 1px solid var(--c-line); }
  .wtable.lst.lst-cartes tr:last-child { border-bottom: 0; }
  .wtable.lst.lst-cartes tr:has(a:focus-visible) { outline: 2px solid var(--c-accent); outline-offset: -2px; }
  .wtable.lst.lst-cartes td { display: block; padding: 0; border: 0; min-width: 0; font-size: var(--fs-sm); }
  .wtable.lst.lst-cartes .c-who { flex: 1 1 0; }
  .wtable.lst.lst-cartes .c-who a { font-size: var(--fs-md); overflow-wrap: anywhere; }
  .wtable.lst.lst-cartes .c-who a::after { content: ""; position: absolute; inset: 0; }
  .wtable.lst.lst-cartes .c-who .s { overflow-wrap: anywhere; }
  .wtable.lst.lst-cartes .c-statut { flex: none; align-self: flex-start; }
  /* saut de ligne : le détail (bot, broker, affilié, activité) passe sous le nom et le statut */
  .wtable.lst.lst-cartes tr::after { content: ""; flex-basis: 100%; height: 0; margin-top: -4px; order: 1; }
  .wtable.lst.lst-cartes .c-bot, .wtable.lst.lst-cartes .c-broker, .wtable.lst.lst-cartes .c-aff, .wtable.lst.lst-cartes .c-act { order: 2; color: var(--c-text-2); }
  .wtable.lst.lst-cartes .c-bot { display: flex; align-items: center; gap: 4px; }
  .wtable.lst.lst-cartes .c-bot .s { display: none; }  /* l'étape du bot est redondante avec le statut, et fait passer l'activité à la ligne */
  .wtable.lst.lst-cartes .c-aff { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; }
  .wtable.lst.lst-cartes .c-act { margin-left: auto; font: 500 12px/1.4 var(--f-mono); color: var(--c-text-3); }
}
@media (max-width: 760px) {
  .filters.filtres-liste { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; overflow: visible; margin: 0 0 14px; padding: 0; }
  .filters.filtres-liste select { width: 100%; max-width: none; height: 40px; }
  .filters.filtres-liste .btn { width: 100%; height: 40px; justify-content: center; }
  .filters.filtres-liste .btn.ghost { grid-column: 1 / -1; }
  .page-head .btn-row .note-export { flex-basis: 100%; }
}

/* ---- Fiche d'une personne : entonnoir en 5 étapes, textes de Telegram, états indisponibles, tablette,
   relances fantômes, fil borné (tâche 16) ----
   Tous les sélecteurs commencent par `body.detail` (classe posée par fiche.html seulement) : rien de
   ce bloc ne touche un autre écran. La maquette avait 6 étapes, l'entonnoir du dashboard en a 5. */
@media (min-width: 1101px) {
  body.detail .stepper { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
body.detail .stepper-m .bars { grid-template-columns: repeat(5, 1fr); }
/* Sections « indisponibles » (profil CRM, état du bot, statut) : un cadre rouge, sans marge parasite. */
body.detail .statut-indispo { margin: 0 0 20px; border: 1px solid var(--c-err-line); border-radius: var(--r-md); overflow: hidden; }
body.detail .statut-indispo .bloc-indispo { border-top: 0; }
body.detail .statut-indispo .bloc-indispo + .bloc-indispo { border-top: 1px solid var(--c-err-line); }
/* Tout ce qui vient d'un client (message, nom, pseudo, motif de rappel, serveur MT5) peut contenir une
   suite de caractères sans espace (lien, jeton) : elle se coupe au lieu d'élargir la carte ou la page.
   `anywhere` (et non `break-word`) réduit aussi la largeur minimale des bulles. */
body.detail .msg, body.detail .relance-b, body.detail .decision, body.detail .mini .body, body.detail .tl li > div { min-width: 0; }
body.detail .msg .bub, body.detail .ghost-reply .bub, body.detail .decision-h, body.detail .decision .effet,
body.detail .sysl, body.detail .mini .body, body.detail .tl .what, body.detail .tl .why, body.detail .tl .when,
body.detail .acct-num, body.detail .kv dd, body.detail .person-head h1, body.detail .person-meta,
body.detail .empty-line, body.detail .note-guard, body.detail .now h2, body.detail .now p, body.detail .panel-h h2 { overflow-wrap: anywhere; }
body.detail .person-head > div:nth-child(2) { min-width: 0; }
body.detail .person-chips .badge { max-width: 100%; white-space: normal; overflow-wrap: anywhere; height: auto; min-height: 22px; }
body.detail .acct-top { flex-wrap: wrap; }
/* « Dernière activité » et « Premier contact » touchaient leur valeur dans la colonne des étiquettes. */
body.detail #details .kv { grid-template-columns: 136px minmax(0, 1fr); }
body.detail #details .kv dd { flex-wrap: wrap; }
/* Réponses fantômes repliables : à gauche, dans le cadre de la décision, avec un chevron qui dit
   « dépliable » ; les bulles se lisent l'une sous l'autre et pleine largeur (côte à côte, deux bulles
   de 200 px coupaient chaque phrase et laissaient un « » orphelin). */
body.detail .chat .decision details.fantomes { margin: 0; max-width: none; padding: 0 12px 8px; }
body.detail .chat .decision details.fantomes summary { display: flex; align-items: center; gap: 6px; text-align: left; padding: 4px 0; border-radius: var(--r-sm); }
body.detail .chat .decision details.fantomes summary:hover { color: var(--c-text-2); }
body.detail .decision details.fantomes summary .chev { transition: transform .15s; }
body.detail .decision details.fantomes[open] summary .chev { transform: rotate(180deg); }
body.detail .decision .ghost-reply { flex-direction: column; gap: 6px; padding: 4px 0 2px; }
body.detail .decision .ghost-reply .lbl { padding-top: 0; }
body.detail .decision .ghost-reply .bub { text-wrap: pretty; }  /* évite le « » orphelin sur la dernière ligne */
/* Une seule action en pied d'écran mobile (« Ouvrir dans Telegram ») : elle prend toute la largeur au lieu
   de la première colonne de 48 px de la maquette (trois boutons). */
@media (max-width: 760px) {
  body.detail .m-actions { grid-template-columns: minmax(0, 1fr); }
}
/* Sous 760 px les cartes passent en colonne : elles s'étirent (la maquette gardait `align-items: start`
   et laissait « Rappels », « Compte MT5 », « Dépôts » à la largeur de leur contenu). */
@media (max-width: 760px) {
  body.detail .grid-fiche { align-items: stretch; }
}
/* De 761 à 1100 px la fiche est sur une colonne : la conversation (souvent longue) repoussait
   « Prochaine action » et les relances loin sous le pli. On reprend l'ordre du mobile (`.o-N`).
   Les 5 étapes de l'entonnoir laissaient une case vide dans la grille de 3 colonnes : grille de 6,
   3 étapes de 2 colonnes puis 2 de 3 (les bordures de la ligne 2 restent celles de la maquette). */
@media (min-width: 761px) and (max-width: 1100px) {
  body.detail .grid-fiche { display: flex; flex-direction: column; align-items: stretch; }
  body.detail .grid-fiche > .col { display: contents; }
  body.detail .o-1 { order: 1; } body.detail .o-2 { order: 2; } body.detail .o-3 { order: 3; } body.detail .o-4 { order: 4; }
  body.detail .o-5 { order: 5; } body.detail .o-6 { order: 6; } body.detail .o-7 { order: 7; }
  body.detail .stepper { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  body.detail .stepper .step { grid-column: span 2; }
  body.detail .stepper .step:nth-child(n+4) { grid-column: span 3; }
}
/* Relance journalisée sans envoi Telegram (mode fantôme) : mention discrète dans le fil, segment
   en pointillés dans la frise (ni plein comme « envoyée », ni cerclé comme « prochaine »). */
body.detail .relance-b .meta .fantome { color: var(--c-text-3); font-style: italic; }
body.detail .frise i.f-fantome { background: transparent; border: 1px dashed var(--seq-sent); box-sizing: border-box; }
/* Fil borné aux derniers événements : la mention des plus anciens, centrée en tête du fil. */
body.detail .chat .fil-tronque { align-self: center; text-align: center; font-size: 12px; color: var(--c-text-3); margin: 10px 0 0; overflow-wrap: anywhere; }
body.detail .chat .fil-tronque a { color: var(--c-text-2); text-decoration: underline; text-underline-offset: 2px; }
/* Faux champ de réponse : dans la colonne de 1280 px le texte passe sur deux lignes, la boîte (36 px fixes
   dans la maquette) les coupait au ras de ses bords. Hauteur minimale au lieu de hauteur fixe (relevé QA, tâche 24). */
body.detail .composer .fake { height: auto; min-height: 36px; padding-block: 7px; line-height: 1.35; }
/* ---- Fin de la section « Fiche d'une personne » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Relances : listes, charge, tuiles et filtres sans débordement (tâche 17) ----------------
   Tout ce bloc ne touche que l'écran Relances (`.liste-rel`, `.charge-rel`, `body.relances`, posée par
   relances.html). Comme « Aujourd'hui » : une seule action (chevron, 28 px) et des colonnes souples hors
   mobile ; la frise disparaît quand la liste fait moins de 640 px (requête de conteneur sur le panneau). */
@media (min-width: 761px) {
  .liste-rel { container-type: inline-size; }
  .liste-rel .pl.fr { grid-template-columns: 52px minmax(0, 1.3fr) minmax(0, 1fr) 80px minmax(0, 1.2fr) 28px; }
  .liste-rel .rl { grid-template-columns: 48px minmax(0, 1.3fr) minmax(0, 1fr) 80px minmax(0, 1.2fr) 28px; }
  .liste-rel .typecell { min-width: 0; overflow: hidden; }
}
@container (max-width: 640px) {
  .liste-rel .pl.fr { grid-template-columns: 52px minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1.2fr) 28px; }
  .liste-rel .rl { grid-template-columns: 48px minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1.2fr) 28px; }
  .liste-rel .frise-cell { display: none; }
}
/* Relance journalisée sans envoi réel (mode fantôme) dans la frise et sa légende : segment en
   pointillés, ni plein comme « envoyée » ni cerclé comme « prochaine » (comme la fiche). */
body.relances .frise i.f-fantome { background: transparent; border: 1px dashed var(--seq-sent); box-sizing: border-box; }
/* Tuiles : le détail passe à la ligne au lieu d'être coupé (« 5 échecs d'envoi probables » à 390 px). */
body.relances .stats.s5 .stat .d { white-space: normal; }
/* Planning : la cause du retard est l'information, elle passe sur 2 lignes (texte complet dans `title`). */
@media (min-width: 761px) {
  .liste-rel .pl .note { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
  /* Historique : « Envoyée mar. 13/10 à 13:05 · moins de 48 h » sur 2 lignes (texte complet dans `title`). */
  .liste-rel .rl.sent .res .l2 { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
}
/* Charge des 7 jours : en-têtes courts ; selon la largeur de la carte (la colonne de gauche fait de 445 à
   770 px entre 1101 et 1440 px, et le tableau complet à 7 types en demande 750), la colonne « Répartition »
   puis les colonnes par type cèdent : jamais de défilement horizontal du tableau à ces largeurs. */
.charge-rel { container-type: inline-size; }
@container (max-width: 759px) { .charge-rel .c-rep { display: none; } }
@container (max-width: 619px) { .charge-rel .c-rep { display: table-cell; } .charge-rel .hide-m { display: none; } }
/* Filtres sur mobile : grille de 2 colonnes (le ruban défilant de la maquette cachait le bouton). */
@media (max-width: 760px) {
  body.relances .filters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; overflow: visible; margin: 0 0 14px; padding: 0; }
  body.relances .filters select { width: 100%; max-width: none; height: 40px; }
  body.relances .filters .btn { width: 100%; height: 40px; justify-content: center; }
  body.relances .filters .btn.ghost { grid-column: 1 / -1; }
}
/* Ruban : de 761 à 800 px, l'en-tête (titre, créneau, 4 compteurs) dépasse la carte : il passe à la ligne. */
@media (min-width: 761px) and (max-width: 800px) {
  body.relances .ribbon .panel-h { flex-wrap: wrap; }
  body.relances .ribbon .figs { margin-left: 0; width: 100%; justify-content: space-between; gap: 8px; }
}
/* Cinq tuiles sur trois colonnes (761 à 1280 px) : la dernière occupe deux colonnes, sans case vide ni
   filet manquant sous « En retard ». */
@media (min-width: 761px) and (max-width: 1280px) {
  body.relances .stats.s5 .stat:nth-child(5) { grid-column: span 2; }
}
/* Anciennes relances du CRM : la date reste sur une ligne, ce sont les noms et les types qui cèdent. */
body.relances .wtable.lst td.num { white-space: nowrap; }
/* ---- Fin de la section « Relances » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Bot support : mode global, conversations par mode, flux des réponses fantômes (tâche 18) ----
   Tout ce bloc ne touche que l'écran Bot support (`body.bot`, posée par bot.html). Les bulles d'une
   décision fantôme sont EMPILÉES (`.bulles`) : `.ghost-reply` de la fiche les met côte à côte. Le texte
   des clients et du bot passe à la ligne même sans espace (liens, identifiants) : jamais de débordement. */
body.bot .kv { padding: 6px 0; }
body.bot .kv dd { flex-wrap: wrap; row-gap: 2px; }
body.bot .mode-etat { padding: 12px 16px 0; }
body.bot .mode-etat .engine { padding: 0; }
/* Une colonne (moins de 1100 px) : le mode global, court et décisif, passe avant les listes. */
@media (max-width: 1100px) {
  body.bot .grid-main > aside { order: -1; }
}
/* Deux colonnes : le mode global reste à l'écran pendant qu'on fait défiler de longues listes. */
@media (min-width: 1101px) {
  body.bot .grid-main > aside { position: sticky; top: 64px; }
}
/* Conversations : nom, puis détail sur sa propre ligne ; la date ne se comprime jamais. */
body.bot .panel-h + .ligne-lien { border-top: 0; }
body.bot .ligne-lien .corps { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
body.bot .ligne-lien .corps > * { overflow-wrap: anywhere; }
body.bot .ligne-lien .s { flex: none; white-space: nowrap; }
@media (max-width: 760px) {
  body.bot .ligne-lien { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; row-gap: 2px; align-items: start; padding: 12px 14px; }
  body.bot .ligne-lien .av { grid-row: 1 / span 2; }
  body.bot .ligne-lien .s { grid-column: 2; margin-left: 0; }
}
body.bot .note-hist { padding: 10px 16px; font-size: var(--fs-sm); color: var(--c-text-2); background: var(--c-surface-2); border-bottom: 1px solid var(--c-line); overflow-wrap: anywhere; }
/* Flux : un échange = la phrase du client, puis ce que le bot AURAIT répondu (cadre en pointillés). */
body.bot .chat { padding: 0 16px 8px; gap: 0; }
body.bot .echange { display: flex; flex-direction: column; gap: 6px; padding: 12px 0; border-top: 1px solid var(--c-line); min-width: 0; }
body.bot .echange:first-child { border-top: 0; }
body.bot .echange .sysl { align-self: flex-start; text-align: left; max-width: 100%; overflow-wrap: anywhere; }
body.bot .echange .msg { min-width: 0; }
body.bot .msg .bub { overflow-wrap: anywhere; }
body.bot .decision { margin: 0; min-width: 0; }
body.bot .decision-h .etiq { margin-left: auto; font-size: 12px; font-style: italic; color: var(--c-text-3); text-align: right; }
body.bot .decision .bulles { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 0 12px 10px; min-width: 0; }
body.bot .decision .bub { max-width: 100%; font-size: var(--fs-md); line-height: 1.45; font-style: italic; color: var(--c-text-2); background: var(--c-surface-2); border-radius: 10px; padding: 7px 11px; white-space: pre-line; overflow-wrap: anywhere; }
/* Passage à l'humain : lui est RÉEL (même en mode test), donc cadre plein et hors du cadre en pointillés. */
body.bot .echange .passee { display: flex; gap: 6px; align-items: flex-start; min-width: 0; padding: 8px 12px; border: 1px solid var(--c-line); border-radius: var(--r-md); background: var(--c-surface-2); font-size: var(--fs-sm); color: var(--c-text); overflow-wrap: anywhere; }
body.bot .echange .passee .ico { flex: none; margin-top: 2px; }
@media (max-width: 760px) {
  body.bot .panel-h .right.keep { width: 100%; margin-left: 0; }
  body.bot .chat { padding: 0 14px 6px; }
  body.bot .decision-h .etiq { margin-left: 0; width: 100%; text-align: left; }
}
/* ---- Fin de la section « Bot support » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Affiliés : tableau, cartes jusqu'à 1100 px, liens à copier, leads (tâche 19) ----------------
   (Tâche C3 : trois colonnes d'argent réel en plus ; les cartes vont désormais jusqu'à 1280 px, voir la section
   « Argent réel du copieur ».)
   Tout ce bloc ne touche que l'écran Affiliés (`body.affilies`, posée par affilies.html et
   affilie.html). Le libellé de chaque chiffre (`.lib`) n'existe que pour les cartes : tant que les
   en-têtes du tableau sont visibles il est masqué (l'en-tête suffit, rien n'est lu deux fois). Jusqu'à
   1100 px (la barre latérale reste affichée dès 761 px et ne laisse que 470 à 790 px au tableau, dont
   le nom d'affilié et son code étaient coupés au milieu des mots, mesuré à 1024 px), les en-têtes
   disparaissent et chaque ligne devient une carte : le nom couvre toute la surface (cible tactile
   pleine), l'état est à sa droite, puis les six chiffres, chacun avec son libellé. Sous 760 px, le
   nom et l'état prennent chacun une ligne et les chiffres passent sur 3 colonnes.
   (Tâche D2 : la liste est devenue le classement ; ses règles, tableau et cartes compris, sont dans la section
   « Affiliés : classement ». Ce bloc garde l'en-tête de page et la fiche.) */
/* Un nom ou un code d'affilié vient de l'équipe : une chaîne de 60 caractères sans espace ne doit pas
   élargir l'en-tête (ni donc la page). */
body.affilies .page-head > div { min-width: 0; }
body.affilies .page-head h1, body.affilies .page-head .sub { overflow-wrap: anywhere; }
body.affilies .topbar .clock { white-space: nowrap; }  /* un fil d'Ariane long ne fait pas passer l'heure à la ligne */
/* Chiffres de la fiche : la règle commune (3 colonnes sous 1280 px) ne convient pas à 4 tuiles, elle
   effaçait le filet entre « Marches » et « Dépôts détectés ». 4 en ligne au-dessus de 1100 px,
   2 × 2 de 761 à 1100 px (sous 761 px, la règle commune est déjà 2 × 2). */
@media (min-width: 761px) {
  body.affilies .stats.s4 .stat:nth-child(4) { border-left: 1px solid var(--c-line); border-top: 0; }
}
@media (min-width: 761px) and (max-width: 1100px) {
  body.affilies .stats.s4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  body.affilies .stats.s4 .stat:nth-child(3) { border-left: 0; }
  body.affilies .stats.s4 .stat:nth-child(n+3) { border-top: 1px solid var(--c-line); }
}
body.affilies .note-def { margin: 10px 2px 0; font-size: var(--fs-sm); overflow-wrap: anywhere; }
body.affilies .grid-main { margin-top: 20px; }
body.affilies .grid-main.seul { grid-template-columns: minmax(0, 1fr); }
/* Leads : nom, puis détail sur sa propre ligne ; la date ne se comprime jamais. */
body.affilies .panel-h + .ligne-lien { border-top: 0; }
body.affilies .ligne-lien .corps { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
body.affilies .ligne-lien .corps > * { overflow-wrap: anywhere; }
body.affilies .ligne-lien .s { flex: none; white-space: nowrap; }
body.affilies a.ligne-lien:focus-visible { outline: 2px solid var(--c-accent); outline-offset: -2px; }
/* Liens & accès : libellé au-dessus de la valeur (un lien de 40 à 90 caractères ne tiendrait pas à
   côté d'un libellé dans 340 px). Les liens sont du texte, jamais des <a> : un clic les sélectionne
   en entier, prêts à copier. */
body.affilies .note-liens { margin: 0; padding: 10px 16px 0; font-size: var(--fs-sm); color: var(--c-text-3); overflow-wrap: anywhere; }
body.affilies .kv { grid-template-columns: minmax(0, 1fr); padding: 4px 0 10px; }
body.affilies .kv dt { padding: 8px 16px 0; }
body.affilies .kv dd { padding: 2px 16px 0; flex-wrap: wrap; overflow-wrap: anywhere; }
body.affilies .kv dd.lien-copiable { display: block; margin: 3px 16px 0; padding: 7px 9px; background: var(--c-surface-2); border: 1px solid var(--c-line); border-radius: var(--r-sm); font-size: 12px; line-height: 1.5; -webkit-user-select: all; user-select: all; }
@media (max-width: 760px) {
  body.affilies .ligne-lien { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; row-gap: 2px; align-items: start; padding: 12px 14px; }
  body.affilies .ligne-lien .av { grid-row: 1 / span 2; }
  body.affilies .ligne-lien .s { grid-column: 2; margin-left: 0; }
  body.affilies .panel-f { align-items: flex-start; }
}
/* ---- Fin de la section « Affiliés » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Comptes MT5 : tableau, cartes jusqu'à 1100 px, valeurs absentes dites « inconnu » (tâche 20) ----
   (Tâche C3 : les cartes vont désormais jusqu'à 1280 px et le mot de passe est retiré jusqu'à 1440 px, à cause de
   la colonne « Copieur » ; voir la section « Argent réel du copieur ».)
   Tout ce bloc ne touche que l'écran Comptes MT5 (`body.mt5`, posée par mt5.html). Au-dessus de
   1100 px, sept colonnes : à 1101 px le contenu fait 790 px (la barre latérale en prend 236), la colonne
   décorative « Mot de passe » (des points, rien à lire) est donc retirée sous 1280 px. Jusqu'à 1100 px,
   les en-têtes disparaissent et chaque ligne devient une carte : le client (lien vers sa fiche s'il en
   a une) et la date sur la première ligne, puis login, serveur, broker et confiance, chacun avec son
   libellé. Ce libellé est le `<span class="sr">` de la cellule, rendu visible en carte : il n'est donc
   lu qu'une fois par un lecteur d'écran. Une valeur absente s'écrit « Serveur : inconnu » en carte et
   « — » en tableau (le tiret est décoratif, `aria-hidden`). Le login n'est pas couvert par un lien : on
   peut le sélectionner et le copier. Nom, pseudo, serveur, broker et login viennent de Telegram ou
   d'une saisie client : une chaîne de 60 caractères sans espace ne doit élargir ni le tableau ni la
   carte (`overflow-wrap: anywhere`). */
body.mt5 .page-head > div { min-width: 0; }
body.mt5 .page-head h1, body.mt5 .page-head .sub { overflow-wrap: anywhere; }
body.mt5 .topbar .clock { white-space: nowrap; }  /* un fil d'Ariane long ne fait pas passer l'heure à la ligne */
body.mt5 .filters input[type="search"] { width: 280px; max-width: 100%; }
body.mt5 .filters select { max-width: 240px; }  /* un broker au nom démesuré n'élargit pas le filtre */
body.mt5 .lst-mt5 td { vertical-align: top; min-width: 0; overflow-wrap: anywhere; }
body.mt5 .lst-mt5 td.c-login, body.mt5 .lst-mt5 td.c-serveur { font-family: var(--f-mono); }  /* .wtable.lst impose la police sans à toute cellule */
body.mt5 .lst-mt5 td.c-login { min-width: 11ch; font-weight: var(--fw-medium); }  /* 8 à 10 chiffres : jamais coupés tant que la place existe */
body.mt5 .lst-mt5 td.c-date, body.mt5 .lst-mt5 td.c-mdp { white-space: nowrap; }  /* ni la date ni les 8 points ne se coupent */
body.mt5 .lst-mt5 .c-client .nom { font-weight: var(--fw-medium); }  /* sans fiche : même graisse que le lien, sans être un lien */
body.mt5 .lst-mt5 .c-conf { white-space: nowrap; }
body.mt5 .empty-line a { color: var(--c-accent); text-decoration: underline; text-underline-offset: 2px; }  /* « Aller à la dernière page » se reconnaît comme un lien */
@media (max-width: 1280px) {
  body.mt5 .lst-mt5 .c-mdp, body.mt5 .lst-mt5 th.hide-m { display: none; }
}
@media (max-width: 1280px) {  /* 1100 px avant la tâche C3 : voir la section « Argent réel du copieur » */
  body.mt5 .lst-mt5 thead { display: none; }
  body.mt5 .lst-mt5, body.mt5 .lst-mt5 tbody { display: block; }
  body.mt5 .lst-mt5 tr { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; padding: 12px 16px; border-bottom: 1px solid var(--c-line); }
  body.mt5 .lst-mt5 tr:last-child { border-bottom: 0; }
  body.mt5 .lst-mt5 td { display: block; padding: 0; border: 0; text-align: left; font-size: var(--fs-sm); }
  body.mt5 .lst-mt5 td.c-client { order: 1; flex: 1 1 0; font-size: var(--fs-md); }
  body.mt5 .lst-mt5 td.c-date { order: 1; flex: none; margin-left: auto; font: 500 12px/1.4 var(--f-mono); color: var(--c-text-3); }
  /* saut de ligne : le détail du compte passe sous le client et la date */
  body.mt5 .lst-mt5 tr::after { content: ""; flex-basis: 100%; height: 0; margin-top: -4px; order: 2; }
  body.mt5 .lst-mt5 td.c-login, body.mt5 .lst-mt5 td.c-serveur, body.mt5 .lst-mt5 td.c-broker, body.mt5 .lst-mt5 td.c-conf { order: 3; flex: 0 1 auto; color: var(--c-text-2); }
  body.mt5 .lst-mt5 td.c-login { min-width: 0; color: var(--c-text); }
  body.mt5 .lst-mt5 td.c-mdp { display: none; }
  /* le libellé de la cellule (sr-only en tableau) devient visible, en gris, dans la police du texte */
  body.mt5 .lst-mt5 td.c-login .sr, body.mt5 .lst-mt5 td.c-serveur .sr, body.mt5 .lst-mt5 td.c-broker .sr, body.mt5 .lst-mt5 td.c-conf .sr {
    position: static; width: auto; height: auto; overflow: visible; clip: auto; color: var(--c-text-3); font: 400 12px/1.4 var(--f-sans);
  }
  body.mt5 .lst-mt5 .nul { display: none; }  /* le libellé dit déjà « inconnu » */
}
@media (max-width: 760px) {
  body.mt5 .filters { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; overflow: visible; margin: 0 0 14px; padding: 0; }
  body.mt5 .filters input[type="search"] { grid-column: 1 / -1; width: 100%; height: 40px; }
  body.mt5 .filters select { width: 100%; max-width: none; height: 40px; }
  body.mt5 .filters .btn { width: 100%; height: 40px; justify-content: center; }
}
/* ---- Fin de la section « Comptes MT5 » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Stats : entonnoir, efficacité des relances, top affiliés, activité quotidienne (tâche 21) ----
   Tout ce bloc ne touche que l'écran Stats (`body.statistiques`, posée par stats.html). Pas `body.stats` :
   `.stats` est déjà le bandeau de chiffres (une grille de six colonnes), posée sur le body elle écraserait
   toute la page. Les deux rangées de panneaux (`.duo`) gardent leur hauteur propre (un panneau court ne s'étire plus à la hauteur de son
   voisin) et passent sur une colonne jusqu'à 1100 px : la barre latérale reste affichée dès 761 px et
   ne laisse que 350 px à chaque panneau à 1024 px, trop peu pour un tableau de quatre colonnes. Les
   deux tableaux restent des TABLEAUX sur mobile (4 colonnes, en-têtes visibles : rien à libeller en
   `.sr`) ; leurs en-têtes passent à la ligne (« Dépôts détectés » sur deux lignes) et un nom
   d'affilié, qui vient de l'équipe, se coupe au lieu d'élargir la page. La barre d'activité est un
   décor (`aria-hidden`) : le nombre est dans la cellule voisine. */
/* Titre et période à gauche (ils grandissent), sélecteur de période à droite ; s'il ne tient pas à côté (761 à
   830 px), il passe SOUS le titre, à gauche : il ne rétrécit jamais (ses trois onglets ne se coupent pas). */
body.statistiques .page-head { flex-wrap: wrap; row-gap: 12px; }
body.statistiques .page-head > div:first-child { flex: 1 1 280px; min-width: 0; }
body.statistiques .page-head .btn-row { flex: none; margin-left: 0; }
body.statistiques .page-head h1, body.statistiques .page-head .sub { overflow-wrap: anywhere; }
body.statistiques .topbar .clock { white-space: nowrap; }  /* un fil d'Ariane long ne fait pas passer l'heure à la ligne */
body.statistiques .duo { align-items: start; }
body.statistiques .duo + .duo { margin-top: 20px; }
body.statistiques .rates { padding: 6px 0 8px; }
body.statistiques .panel-h { flex-wrap: wrap; row-gap: 2px; }
body.statistiques .panel-f span, body.statistiques .empty-line { overflow-wrap: anywhere; }
body.statistiques .wtable th { white-space: normal; vertical-align: bottom; }
body.statistiques .lst-top td.c-aff { min-width: 0; overflow-wrap: anywhere; }
body.statistiques .lst-top td.num { white-space: nowrap; }
body.statistiques .lst-act td:first-child { white-space: nowrap; }
body.statistiques .lst-act tr.cur td.z { color: var(--c-text-3); }
body.statistiques .jour-cours { margin-left: 8px; font: 400 12px/1 var(--f-sans); color: var(--c-text-3); }
body.statistiques .act-bar { display: block; width: 120px; margin-left: auto; }
/* De 1101 à 1280 px les deux panneaux de 380 à 480 px n'ont pas la place de la barre (120 px) : le nombre de leads,
   lui, reste dans sa cellule. */
@media (min-width: 1101px) and (max-width: 1280px) {
  body.statistiques .lst-act .hide-m { display: none; }
}
@media (max-width: 1100px) {
  body.statistiques .duo { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  body.statistiques .duo + .duo { margin-top: 16px; }
}
@media (max-width: 760px) {
  body.statistiques .page-head > div:first-child { flex: none; }  /* en colonne, la base de 280 px serait une hauteur */
}
/* ---- Fin de la section « Stats » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Santé : services, hubs, actions et erreurs sur 24 h, événements par heure (tâche 22) ----
   Tout ce bloc ne touche que l'écran Santé (`body.sante`, posée par sante.html ; aucune classe de ce nom
   n'existe ailleurs). Comme sur Stats, les deux rangées de panneaux (`.duo`) gardent leur hauteur
   propre ; elles passent sur une colonne jusqu'à 1280 px (et non 1100 comme Stats) : la barre
   latérale reste affichée dès 761 px et ne laisse que 385 px à chaque panneau à 1101 px, trop peu
   pour le tableau des actions (cinq colonnes, « translator » se coupait). Les tableaux restent des TABLEAUX sur mobile (3, 2 et 5 colonnes, en-têtes visibles :
   rien à libeller en `.sr`) ; les noms de services et de hubs, les messages d'erreur et les
   valeurs viennent de la base ou des hubs : une chaîne de 60 caractères sans espace ne doit élargir
   ni le tableau ni la page (`overflow-wrap: anywhere`). La barre de l'heure en cours est plus claire :
   l'heure n'est pas finie. L'alerte d'échecs porte une icône en plus de la couleur. */
body.sante .page-head > div { min-width: 0; }
body.sante .page-head h1, body.sante .page-head .sub { overflow-wrap: anywhere; }
body.sante .topbar .clock { white-space: nowrap; }  /* un fil d'Ariane long ne fait pas passer l'heure à la ligne */
body.sante .duo { align-items: start; }
body.sante .duo + .duo { margin-top: 20px; }
body.sante .panel-h { flex-wrap: wrap; row-gap: 2px; }
body.sante .panel-f span, body.sante .empty-line, body.sante .bloc-indispo { overflow-wrap: anywhere; }
body.sante .sous-h { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; margin: 0; padding: 9px 16px; border-top: 1px solid var(--c-line); border-bottom: 1px solid var(--c-line); background: var(--c-surface-2); font: var(--fw-medium) 12px/1.4 var(--f-sans); color: var(--c-text-2); }
body.sante .sous-h .meta { font-weight: 400; color: var(--c-text-3); }
body.sante .panel > .sous-h:first-child { border-top: 0; }
body.sante .wtable th { white-space: normal; vertical-align: bottom; }
body.sante .wtable td { vertical-align: top; }
body.sante .wtable td:first-child { min-width: 0; overflow-wrap: anywhere; }
body.sante .wtable td.num, body.sante .lst-actions td + td { white-space: nowrap; }  /* « 300 ms » et « 3 · 60 % » ne se coupent jamais : c'est le nom du service qui cède */
body.sante .wtable td.alerte .ico { margin-right: 4px; vertical-align: -2px; }
/* État d'un hub : un badge par dépendance en défaut (Telegram, base, Redis), qui passent à la ligne */
body.sante .lst-svc .etats { display: inline-flex; flex-wrap: wrap; gap: 4px; max-width: 100%; }
body.sante .alert > div { min-width: 0; }
body.sante .alert b, body.sante .alert span:not(.dot) { overflow-wrap: anywhere; }
body.sante .barres .b { grid-template-columns: 92px minmax(0, 1fr) 56px; }
body.sante .barres .b .mono { white-space: nowrap; }
body.sante .barres .b.cours .fn-bar i { opacity: .5; }
@media (max-width: 1280px) {
  body.sante .duo { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  body.sante .duo + .duo { margin-top: 16px; }
}
@media (max-width: 760px) {
  /* Les trois tableaux deviennent des cartes (les en-têtes disparaissent : chaque cellule porte son
     libellé en `.sr`, rendu visible quand il aide à lire, lu une seule fois par un lecteur d'écran). */
  body.sante .lst-svc thead, body.sante .lst-actions thead { display: none; }
  body.sante .lst-svc, body.sante .lst-svc tbody, body.sante .lst-actions, body.sante .lst-actions tbody { display: block; }
  body.sante .lst-svc tr, body.sante .lst-actions tr { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; padding: 12px 16px; border-bottom: 1px solid var(--c-line); }
  body.sante .lst-svc tr:last-child, body.sante .lst-actions tr:last-child { border-bottom: 0; }
  body.sante .lst-svc td, body.sante .lst-actions td { display: block; padding: 0; border: 0; text-align: left; min-width: 0; }
  body.sante .lst-svc td.c-nom { flex: 1 1 0; font-size: var(--fs-md); }
  body.sante .lst-svc td.c-etat { flex: 0 1 auto; max-width: 100%; }  /* plusieurs badges : ils passent à la ligne au lieu de déborder */
  body.sante .lst-svc td.c-etat > .sr { display: none; }  /* le badge dit déjà l'état */
  body.sante .lst-svc td.c-bat { flex: 1 1 100%; order: 3; text-align: left; font: 400 12px/1.4 var(--f-sans); color: var(--c-text-3); }
  body.sante .lst-svc td.c-bat .sr, body.sante .lst-actions td .sr.lib { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
  /* actions : le service et ses échecs sur la première ligne, le reste (actions, p50, p95) dessous */
  body.sante .lst-actions td { font: 500 12px/1.4 var(--f-mono); color: var(--c-text-2); }
  body.sante .lst-actions td .sr.lib { margin-right: 4px; font: 400 12px/1.4 var(--f-sans); color: var(--c-text-3); }
  body.sante .lst-actions td:nth-child(1) { order: 1; flex: 1 1 0; font: var(--fw-medium) var(--fs-md)/1.4 var(--f-sans); color: var(--c-text); }
  body.sante .lst-actions td:nth-child(3) { order: 2; flex: none; font-size: var(--fs-sm); color: var(--c-text); }
  body.sante .lst-actions td.alerte { color: var(--c-err); }
  body.sante .lst-actions tr::after { content: ""; flex-basis: 100%; height: 0; margin-top: -4px; order: 3; }
  body.sante .lst-actions td:nth-child(2), body.sante .lst-actions td:nth-child(4), body.sante .lst-actions td:nth-child(5) { order: 4; }
}
/* ---- Fin de la section « Santé » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Rafraîchissement d'« Aujourd'hui » : cibles hors bande et signal d'échec (tâche 23) ----
   Ces deux classes sont GLOBALES, pas bornées par une classe de `body` comme les sections d'écran :
   `.oob-cible` habille des zones de base.html (barre latérale, barre basse, vues par tous les écrans) et
   `.maj-echec` vit dans Aujourd'hui, dont le gabarit n'a pas de `bodyclass`. Elles ne servent qu'à ces usages.
   `.oob-cible` : cible d'un remplacement hors bande, sans boîte (la mise en page ne change pas).
   `.maj-echec` : boîte du signal d'une mise à jour ratée, ambre (les chiffres affichés datent peut-être) ;
   rafraichir.js y pose le texte (textContent) et ôte `hidden` quand la requête du fragment échoue, puis la
   remet à la prochaine réussite. Elle est dans une région `role="status"` toujours présente, vide, sans style. */
.oob-cible { display: contents; }
.maj-echec { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 10px 14px; border: 1px solid var(--c-warn-line); border-radius: var(--r-sm); background: var(--c-warn-bg); color: var(--c-warn); font-size: var(--fs-sm); font-weight: var(--fw-medium); overflow-wrap: anywhere; }
.maj-echec[hidden] { display: none; }
.maj-echec .ico { flex: none; }
/* ---- Fin de la section « Rafraîchissement d'Aujourd'hui » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Relevés de la QA transverse : contrastes AA et libellés de tuiles (tâche 24) ----
   Les deux corrections sont GLOBALES (comme la section précédente) : elles touchent un jeton et un composant
   partagés par plusieurs écrans, pas un écran.
   1. La règle de la maquette `.now .who span` (spécificité 0,2,1) écrasait la couleur propre de l'avatar `.av`
      (0,1,0) : les initiales de la carte « Maintenant » sortaient en gris de texte secondaire sur le fond pastel
      de l'avatar, soit 4,3:1 en clair et 4,0:1 en sombre (AA : 4,5:1). On rend à l'avatar sa couleur.
   2. En sombre, `--c-text-3` (#918E88) tombait entre 4,39:1 et 4,46:1 sur les fonds teintés (étape courante de
      la fiche, prochaine relance, badge « Ignoré », jour en cours de Stats, ligne sélectionnée). Relevé à #97948E :
      au moins 4,54:1 (pire cas mesuré) sur tous les fonds sombres du jeu de jetons, et toujours nettement sous `--c-text-2`.
      `--c-off` et `--mode-ignore` (texte « hors ligne » et badge « Ignoré », même gris) suivent. Les deux blocs reprennent les deux
      sélecteurs du thème sombre de tokens.css : choix enregistré (data-theme) et préférence système. */
.now .who .av { color: hsl(var(--h) var(--av-s) var(--av-fg-l)); }
:root[data-theme="dark"] { --c-text-3: #97948E; --c-off: #97948E; --mode-ignore: #97948E; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --c-text-3: #97948E; --c-off: #97948E; --mode-ignore: #97948E; }
}
/* ---- Libellés des tuiles de chiffres sur petit téléphone (tâche 24) ----
   `.stat .k` ne passait jamais à la ligne (maquette) : à 360 px, « Nouveaux prospects » et « Taux de réponse · 7 j »
   débordaient de leur tuile de 10 px (et davantage à 320 px). Sur mobile, le libellé passe à la ligne. */
@media (max-width: 760px) {
  .stat .k { white-space: normal; }
}
/* ---- Fin de la section « QA transverse » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Taux de réponse sur petit effectif : couleur neutre (décision du 14/10) ----
   Sous TAUX_EFFECTIF_MIN (5) relances jugeables (domain.relances_vue), le taux d'une ligne de « Taux de réponse par
   type » (Relances) ou d'« Efficacité des relances par étape » (Stats) reste affiché avec son « k/n », mais n'est ni
   rouge, ni orange, ni vert : texte secondaire (--c-text-2, 7,9:1 en clair). `title` et texte `.sr` de la ligne disent
   pourquoi. Les tuiles « Taux de réponse » n'ont jamais de couleur : rien à neutraliser. */
body.statistiques .rate .p.petit, body.relances .rate .p.petit { color: var(--c-text-2); }
/* ---- Fin de la section « Taux de réponse sur petit effectif » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Aujourd'hui sous 1280 px : une colonne, carte « Maintenant » en tête (décision du 14/10) ----
   Entre 761 et 1279 px (tablette, petit portable), la colonne principale tombait à 440-540 px (barre latérale de
   236 px + colonne latérale de 330 px) : noms coupés à 6 caractères, tag « Accueil +24 h » rogné, et la carte
   « Maintenant » aux deux tiers de la page sous 1100 px. La grille passe donc sur UNE colonne, dans l'ordre déjà
   donné au mobile par les classes `o-1` à `o-9` du gabarit (carte, titre, ruban, chiffres, À traiter, relances,
   rappels, santé, entonnoir et arrivées) : on ne touche pas au gabarit. Les deux colonnes (`.col`) deviennent
   `display: contents`, comme sur mobile, pour que ces classes ordonnent tous les blocs ensemble. À partir de
   1280 px, la maquette D à deux colonnes est inchangée ; sous 761 px, la section mobile s'applique.
   Rafraîchissement HTMX : les blocs `frag-…` gardent leur classe `o-N` (macros) et le remplacement hors bande
   les remet à la même place ; `.oob-cible` (`display: contents`) est hors de `.l-today`, rien n'y change.
   Bornes : 1279.98 px, pas 1279 px, pour qu'aucune largeur fractionnaire (zoom) ne tombe entre deux règles. */
@media (min-width: 761px) and (max-width: 1279.98px) {
  .l-today { display: flex; flex-direction: column; align-items: stretch; gap: 20px; }
  .l-today > .col { display: contents; }
  .l-today > *, .l-today > .col > * { min-width: 0; }
  .l-today .o-1 { order: 1; } .l-today .o-2 { order: 2; } .l-today .o-3 { order: 3; }
  .l-today .o-4 { order: 4; } .l-today .o-5 { order: 5; } .l-today .o-6 { order: 6; }
  .l-today .o-7 { order: 7; } .l-today .o-8 { order: 8; } .l-today .o-9 { order: 9; }
  .l-today .side { position: static; max-height: none; overflow: visible; padding: 0; }
  /* Lignes de relance et d'« À traiter » : la colonne unique mesure encore 450 à 970 px. Dès 1010 px
     (colonne de 700 px au moins) la rangée à colonnes tient : le nom reçoit la plus grande part, pour que
     « Christelle Ouédraogo » ne soit plus coupé, et le tag « Accueil +24 h » son plein espace. */
  .l-today .rl { grid-template-columns: 48px minmax(0, 1.6fr) minmax(0, 1fr) 80px minmax(0, 1.2fr) 28px; }
  .l-today .pl { grid-template-columns: 52px minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1.4fr) 28px; }
}
/* En dessous, la rangée de 5 colonnes réduisait un nom à 6 caractères (« Moussa… ») : les lignes passent en
   cartes, comme sur mobile (mêmes zones : heure, nom et chevron, tag, réponse ou motif), le tag n'est plus rogné. */
@media (min-width: 761px) and (max-width: 1009.98px) {
  .l-today .rl {
    grid-template-columns: 48px minmax(0, 1fr) auto; grid-template-areas: "h who acts" "h type type" "h res res";
    gap: 6px 10px; padding: 12px 14px; align-items: start;
  }
  .l-today .rl .h { grid-area: h; padding-top: 8px; }
  .l-today .rl .who { grid-area: who; }
  .l-today .rl .typecell { grid-area: type; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; overflow: visible; }
  .l-today .rl .frise-cell { display: none; }
  .l-today .rl .res { grid-area: res; }
  .l-today .rl .acts { grid-area: acts; }
  .l-today .pl {
    grid-template-columns: 48px minmax(0, 1fr) auto; grid-template-areas: "h who acts" "h ty ty" "h note note";
    gap: 6px 10px; padding: 12px 14px; align-items: start;
  }
  .l-today .pl .h { grid-area: h; padding-top: 8px; }
  .l-today .pl .who { grid-area: who; }
  .l-today .pl .typecell { grid-area: ty; overflow: visible; }
  .l-today .pl .note { grid-area: note; }
  .l-today .pl .acts { grid-area: acts; }
  /* Même traitement que sur mobile pour l'en-tête du ruban (titre, créneau et compteurs sur deux lignes au lieu
     de trois lignes de titre) et pour « Entonnoir » et « Arrivées du jour » (une colonne : leurs titres tenaient
     sur 2 lignes). */
  .l-today .ribbon .panel-h { flex-wrap: wrap; }
  .l-today .ribbon .figs { margin-left: 0; width: 100%; justify-content: space-between; gap: 8px; }
  .l-today .duo { grid-template-columns: minmax(0, 1fr); }
}
/* ---- Fin de la section « Aujourd'hui sous 1280 px » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Argent réel du copieur : fraîcheur, fiche, Aujourd'hui, Comptes MT5, Affiliés, Stats (tâche C3) ----
   Chaque règle vise un seul écran (`body.detail`, `body.mt5`, `body.affilies`, `body.statistiques`, ou `.l-today`
   pour « Aujourd'hui », qui n'a pas de classe de page). Mention de fraîcheur des données du copieur (macro
   `fraicheur_copieur`) : grise quand elles sont fraîches, orange quand elles datent de plus de 15 min, rouge quand
   elles sont indisponibles (le texte le dit aussi : la couleur n'est jamais seule porteuse du sens).
   Comptes MT5 : la colonne « Copieur » (état du suivi puis argent réel, une ligne chacun) élargit le tableau ; la
   colonne décorative « Mot de passe » est donc retirée jusqu'à 1440 px (au lieu de 1280), et les lignes passent en
   cartes jusqu'à 1280 px (au lieu de 1100, seuil modifié dans la section « Comptes MT5 ») : de 1101 à 1280 px les
   sept colonnes ne tenaient plus (logins de 8 chiffres coupés en deux). En carte, l'état et l'argent prennent une
   ligne à eux, sous le détail du compte, avec leur libellé (« Copieur : ») visible. */
body.detail .fraicheur-copieur, body.mt5 .fraicheur-copieur, body.affilies .fraicheur-copieur,
body.statistiques .fraicheur-copieur, .l-today .fraicheur-copieur { font-size: 12px; line-height: 1.4; color: var(--c-text-3); }
body.detail .fraicheur-copieur.perime, body.mt5 .fraicheur-copieur.perime, body.affilies .fraicheur-copieur.perime,
body.statistiques .fraicheur-copieur.perime, .l-today .fraicheur-copieur.perime { color: var(--c-warn); }
body.detail .fraicheur-copieur.indispo, body.mt5 .fraicheur-copieur.indispo, body.affilies .fraicheur-copieur.indispo,
body.statistiques .fraicheur-copieur.indispo, .l-today .fraicheur-copieur.indispo { color: var(--c-err); }
/* Ligne de fraîcheur sous l'en-tête d'un panneau (fiche, Comptes MT5, Affiliés) : une phrase à gauche, la
   fraîcheur à droite, l'une sous l'autre quand la place manque. */
body.detail .note-copieur, body.mt5 .note-copieur, body.affilies .note-copieur {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 12px;
  padding: 8px 16px; border-bottom: 1px solid var(--c-line); font-size: 12px; color: var(--c-text-3); overflow-wrap: anywhere;
}
/* Fiche : lignes de mouvement (montant signé, sens écrit, date, broker, compte abrégé), puis totaux par devise. */
body.detail .mvts { list-style: none; margin: 0; padding: 0; }
body.detail .mvt { display: flex; align-items: baseline; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--c-line); }
body.detail .mvt .amt { flex: none; min-width: 80px; font: 600 var(--fs-md)/1.3 var(--f-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
body.detail .mvt.depot .amt { color: var(--c-ok); }
body.detail .mvt .info { flex: 1; min-width: 0; font-size: var(--fs-sm); }
body.detail .mvt .l1 { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
body.detail .mvt .l2 { margin-top: 2px; color: var(--c-text-3); overflow-wrap: anywhere; }
body.detail .mvt .l2 .cpt { white-space: nowrap; }
body.detail .argent .totaux th[scope="row"], body.affilies .tous-leads .totaux th[scope="row"] { color: var(--c-text-2); font-weight: var(--fw-medium); }
body.detail .argent .totaux td, body.affilies .tous-leads .totaux td { white-space: nowrap; }
body.detail .argent .totaux tr:last-child th, body.affilies .tous-leads .totaux tr:last-child th { border-bottom: 0; }
/* Fiche de 761 à 1100 px (une colonne, ordre du mobile) : la carte « Détails » est devenue la huitième. */
@media (min-width: 761px) and (max-width: 1100px) {
  body.detail .o-8 { order: 8; }
}
/* Aujourd'hui : la fraîcheur sous les montants de la tuile « Dépôts · 7 j ». */
.l-today .stat.argent .d + .d { margin-top: 4px; }
/* Comptes MT5 : cellule « Copieur ». */
/* largeur indicative : sans elle, la phrase d'un login ambigu prenait 370 px et coupait le broker en deux à 1366 px */
body.mt5 .lst-mt5 td.c-copieur { min-width: 150px; width: 200px; }
body.mt5 .lst-mt5 td.c-copieur .badge { white-space: nowrap; }
body.mt5 .lst-mt5 td.c-copieur .ar { display: block; margin-top: 4px; font-size: 12px; color: var(--c-text-2); }
body.mt5 .lst-mt5 td.c-copieur .ar b { font-family: var(--f-mono); font-weight: var(--fw-medium); color: var(--c-text); white-space: nowrap; }
body.mt5 .lst-mt5 td.c-copieur .ar.muted { color: var(--c-text-3); }
@media (max-width: 1440px) {
  body.mt5 .lst-mt5 .c-mdp, body.mt5 .lst-mt5 th.hide-m { display: none; }
}
@media (max-width: 1280px) {
  body.mt5 .lst-mt5 td.c-copieur {
    order: 4; flex: 1 1 100%; min-width: 0; width: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
    margin-top: 4px; padding-top: 8px; border-top: 1px dashed var(--c-line);
  }
  body.mt5 .lst-mt5 td.c-copieur > .sr { position: static; width: auto; height: auto; overflow: visible; clip: auto; color: var(--c-text-3); font: 400 12px/1.4 var(--f-sans); }
  body.mt5 .lst-mt5 td.c-copieur .ar { margin-top: 0; }
}
body.affilies .deposants { padding: 12px 16px 10px; font-size: var(--fs-sm); color: var(--c-text-2); overflow-wrap: anywhere; }
body.affilies .deposants b { font: 600 var(--fs-lg)/1 var(--f-display); color: var(--c-text); }
/* Stats : le top affiliés a une cinquième colonne (« Ont déposé ») ; sur téléphone, le nom de l'affilié garde
   la place d'un nom court (« NovaPips » se coupait en « NovaPip|s ») et les chiffres des marges plus courtes. */
@media (max-width: 760px) {
  body.statistiques .lst-top td.c-aff { min-width: 96px; }
  body.statistiques .lst-top th.num, body.statistiques .lst-top td.num { padding-left: 6px; padding-right: 6px; }
  body.statistiques .lst-top th.num:last-child, body.statistiques .lst-top td.num:last-child { padding-right: 16px; }
}
/* ---- Fin de la section « Argent réel du copieur » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- « Dépôt confirmé » selon l'état du copieur : entonnoirs, fiche, Prospects (correctif de la tâche C3) ----
   L'étape « Dépôt confirmé » des entonnoirs (Stats, Aujourd'hui · 7 jours) porte sa mention de fraîcheur sous la
   ligne (« Données du copieur du JJ/MM HH:MM » ou « … indisponibles », macro `fraicheur_copieur`) ; s'il est inconnu,
   la ligne n'a pas de barre : « — » et la raison. Fiche : la mention est une pastille à côté du statut (inconnu) ou
   un texte discret près du badge (périmé). Prospects (classe de page `prospects`, ajoutée) : la mention est en tête
   de liste, sous le titre du panneau ; elle reprend les couleurs des autres écrans (grise, orange, rouge, et le texte
   le dit aussi). */
body.statistiques .fn-row .fn-note, .l-today .fn-row .fn-note { grid-column: 1 / -1; line-height: 1.3; }
body.detail .person-chips .fraicheur-copieur { align-self: center; }
/* Carte Détails : la pastille longue passe sous le statut (elle ne tient pas à côté sur téléphone) et revient à la ligne. */
body.detail dl.kv dd .depot-inconnu { display: block; width: fit-content; max-width: 100%; margin-top: 4px; height: auto; min-height: 22px; white-space: normal; overflow-wrap: anywhere; }
body.detail dl.kv dd .fraicheur-copieur { display: block; margin-top: 4px; overflow-wrap: anywhere; }
body.prospects .fraicheur-copieur { font-size: 12px; line-height: 1.4; color: var(--c-text-3); }
body.prospects .fraicheur-copieur.perime { color: var(--c-warn); }
body.prospects .fraicheur-copieur.indispo { color: var(--c-err); }
body.prospects .note-copieur {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 12px;
  padding: 8px 16px; border-bottom: 1px solid var(--c-line); font-size: 12px; color: var(--c-text-3); overflow-wrap: anywhere;
}
body.prospects .bloc-indispo, body.prospects .empty-line { overflow-wrap: anywhere; }
/* ---- Fin de la section « Dépôt confirmé selon l'état du copieur » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Affiliés : classement (période, filtres, podium, tri, cartes sous 1280 px) (tâche D2) ----
   Tout ce bloc ne touche que l'écran Affiliés (`body.affilies`). Au-dessus de 1280 px : un tableau dense de 21
   colonnes (deux lignes d'en-têtes : le sens de période, puis la colonne, chaque en-tête est un lien de tri) qui
   défile dans son cadre (`.table-scroll`) si la place manque, la colonne de l'affilié restant collée à gauche. La
   colonne triée est soulignée et porte sa flèche. Jusqu'à 1280 px : les en-têtes disparaissent, chaque ligne devient
   une carte (le nom couvre toute la carte, cible tactile pleine), avec les chiffres clés seulement (`.cle` : ont
   déposé, dépôts, déposé € et $, leads, tendances) et la colonne du tri en cours (`.trie`), chacun avec son libellé
   (`.lib`, masqué tant que les en-têtes sont visibles) ; le formulaire « Trier par » remplace les en-têtes. Taux sur
   petit effectif en gris (la raison est dans l'infobulle et le texte lecteur d'écran) ; tendance en vert ou en rouge,
   la flèche et le signe disent aussi le sens. Ligne masquée : texte grisé (pas d'opacité : la colonne collée
   laisserait voir le défilement dessous). */
body.affilies .periodes { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin: -8px 0 14px; }
body.affilies .periodes .perso { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--c-text-2); }
body.affilies .periodes .perso input[type="date"] {
  height: 30px; padding: 0 8px; border: 1px solid var(--c-line-strong); border-radius: var(--r-sm);
  background: var(--c-surface); color: var(--c-text); font: inherit; font-size: var(--fs-sm); min-width: 0;
}
body.affilies .periodes .perso.active .btn { box-shadow: var(--sh-1), inset 0 0 0 1px var(--c-accent-line); color: var(--c-accent); }
body.affilies .avertissement {
  display: flex; align-items: center; gap: 8px; margin: 0 0 14px; padding: 8px 12px; border-radius: var(--r-sm);
  background: var(--c-warn-bg); color: var(--c-warn); font-size: var(--fs-sm); overflow-wrap: anywhere;
}
body.affilies .filtres-aff input[type="search"] { width: 240px; max-width: 100%; }
body.affilies .note-tri { margin: 0 0 14px; font-size: var(--fs-sm); color: var(--c-warn); overflow-wrap: anywhere; }
body.affilies .panel .note-tri { margin: 0; padding: 8px 16px; border-bottom: 1px solid var(--c-line); }
/* Podium : trois cartes, la première soulignée de la couleur d'accent. */
body.affilies .podium { margin-bottom: 20px; }
body.affilies .podium h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin-bottom: 10px; font-size: var(--fs-md); font-weight: var(--fw-semibold); }
body.affilies .podium h2 .meta { font-size: var(--fs-sm); font-weight: var(--fw-regular); color: var(--c-text-3); }
body.affilies .podium ol { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 0; padding: 0; list-style: none; }
body.affilies .podium li {
  position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 4px 12px;
  padding: 14px 16px; background: var(--c-surface); border: 1px solid var(--c-line); border-radius: var(--r-lg); min-width: 0;
}
body.affilies .podium li.rang-1 { border-color: var(--c-accent-line); box-shadow: inset 0 3px 0 var(--c-accent); }
body.affilies .podium .rang {
  grid-row: 1 / span 3; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%;
  background: var(--c-surface-2); border: 1px solid var(--c-line); font: 600 var(--fs-md)/1 var(--f-mono); color: var(--c-text-2);
}
body.affilies .podium li.rang-1 .rang { background: var(--c-accent-soft); border-color: var(--c-accent-line); color: var(--c-accent); }
body.affilies .podium .qui { min-width: 0; overflow-wrap: anywhere; }
body.affilies .podium .qui a { font-weight: var(--fw-semibold); color: var(--c-text); }
body.affilies .podium .qui a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
body.affilies .podium .qui a:focus-visible { outline: none; }
body.affilies .podium li:has(a:focus-visible) { outline: 2px solid var(--c-accent); outline-offset: 2px; }
body.affilies .podium .qui .s { display: block; font-size: 12px; color: var(--c-text-3); }
body.affilies .podium .v { font: var(--fw-semibold) 22px/1.15 var(--f-display); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; white-space: nowrap; }
body.affilies .podium .k { font-size: 12px; color: var(--c-text-3); }
/* Tableau (au-dessus de 1280 px). Le cadre défilant est positionné : sans cela, les textes pour lecteur d'écran
   (`.sr`, en position absolue) des cellules hors de l'écran prennent la page entière pour bloc conteneur et
   l'élargissent (mesuré : 1 749 px de large à 1440 px). */
body.affilies .table-scroll { position: relative; }
/* Indice de défilement horizontal, sans JavaScript : une ombre grise au bord droit tant qu'il reste des colonnes
   à voir. Fonds à défilement mixte : l'ombre est fixe (`scroll`), le dégradé de la couleur de la surface suit le
   contenu (`local`) et la recouvre en arrivant au bout. Les cellules sont transparentes, l'ombre passe dessous.
   Jusqu'à 1280 px le tableau devient des cartes : rien ne défile. */
@media (min-width: 1281px) {
  body.affilies .table-scroll {
    background:
      linear-gradient(to left, var(--c-surface) 25%, transparent) right center / 56px 100% no-repeat local,
      linear-gradient(to left, color-mix(in srgb, var(--c-text-3) 38%, transparent), transparent) right center / 30px 100% no-repeat scroll;
  }
}
body.affilies .trier-par { display: none; }
body.affilies .lst-clas .lib { display: none; }
body.affilies .lst-clas th, body.affilies .lst-clas td { padding: 7px 8px; vertical-align: top; }
body.affilies .lst-clas td.num { white-space: nowrap; font-size: 13px; }
body.affilies .lst-clas thead th { white-space: normal; vertical-align: bottom; line-height: 1.25; }
body.affilies .lst-clas thead th a { color: var(--c-text-3); }
body.affilies .lst-clas thead th a:hover { color: var(--c-accent); }
body.affilies .lst-clas thead th[aria-sort] a { color: var(--c-text); font-weight: var(--fw-semibold); }
body.affilies .lst-clas thead th[aria-sort] { box-shadow: inset 0 -2px 0 var(--c-accent); }
body.affilies .lst-clas thead .fl { margin-left: 3px; font-size: 10px; color: var(--c-accent); }
body.affilies .lst-clas thead .groupes th { text-align: center; border-bottom: 1px solid var(--c-line); border-left: 1px solid var(--c-line); font-size: 11px; color: var(--c-text-3); padding: 6px 8px; }
body.affilies .lst-clas thead .groupes td { border-bottom: 0; padding: 0; }
body.affilies .lst-clas thead tr + tr th:first-child { padding-left: 16px; }
body.affilies .lst-clas .c-nom { position: sticky; left: 0; z-index: 1; min-width: 170px; max-width: 240px; background: var(--c-surface); overflow-wrap: anywhere; box-shadow: inset -1px 0 0 var(--c-line); }
body.affilies .lst-clas thead .c-nom { z-index: 2; }
body.affilies .lst-clas .c-nom .badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
body.affilies .lst-clas .c-nom .badge { white-space: nowrap; }
body.affilies .lst-clas td.trie { background: var(--c-accent-soft); }
body.affilies .lst-clas tr.masque td, body.affilies .lst-clas tr.masque td a { color: var(--c-text-3); }
body.affilies .lst-clas .petit { color: var(--c-text-3); }
body.affilies .lst-clas .tendance.hausse { color: var(--c-ok); }
body.affilies .lst-clas .tendance.baisse { color: var(--c-err); }
body.affilies .lst-clas .tendance.nouveau { color: var(--c-accent); }
body.affilies .lst-clas tfoot th, body.affilies .lst-clas tfoot td { border-top: 2px solid var(--c-line-strong); border-bottom: 0; font-weight: var(--fw-semibold); color: var(--c-text); }
body.affilies .lst-clas tfoot .c-nom .s { display: block; font-weight: var(--fw-regular); color: var(--c-text-3); font-size: 12px; }
@media (max-width: 1280px) {
  body.affilies .trier-par {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 16px; border-bottom: 1px solid var(--c-line);
    font-size: var(--fs-sm); color: var(--c-text-2);
  }
  body.affilies .trier-par label { display: inline-flex; align-items: center; gap: 6px; }
  body.affilies .trier-par select {
    height: 32px; padding: 0 10px; border: 1px solid var(--c-line-strong); border-radius: var(--r-sm);
    background: var(--c-surface); color: var(--c-text); font: inherit; font-size: var(--fs-sm); min-width: 0; max-width: 100%;
  }
  body.affilies .lst-clas thead { display: none; }
  body.affilies .lst-clas, body.affilies .lst-clas tbody, body.affilies .lst-clas tfoot { display: block; }
  body.affilies .lst-clas tr { position: relative; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px 12px; padding: 14px 16px; border-bottom: 1px solid var(--c-line); }
  body.affilies .lst-clas tbody tr:last-child { border-bottom: 0; }
  body.affilies .lst-clas tr:has(a:focus-visible) { outline: 2px solid var(--c-accent); outline-offset: -2px; }
  body.affilies .lst-clas th, body.affilies .lst-clas td, body.affilies .lst-clas td.num { display: none; padding: 0; border: 0; min-width: 0; text-align: left; }
  body.affilies .lst-clas .c-nom { display: block; grid-column: 1 / -1; position: static; max-width: none; min-width: 0; box-shadow: none; background: transparent; }
  body.affilies .lst-clas .c-nom a { font-size: var(--fs-lg); }
  body.affilies .lst-clas .c-nom a::after { content: ""; position: absolute; inset: 0; }
  body.affilies .lst-clas td.cle, body.affilies .lst-clas td.trie {
    display: flex; flex-direction: column-reverse; justify-content: flex-end; align-items: flex-start;
    font-size: var(--fs-lg); font-weight: var(--fw-medium); white-space: normal; overflow-wrap: anywhere;
  }
  /* ordre des chiffres clés (spec §3) : ont déposé, dépôts, déposé € et $, puis leads et tendances ; la colonne du
     tri en cours, si elle n'en est pas, vient en dernier */
  body.affilies .lst-clas .c-deposants { order: 1; } body.affilies .lst-clas .c-n_depots { order: 2; }
  body.affilies .lst-clas .c-depose_eur { order: 3; } body.affilies .lst-clas .c-depose_usd { order: 4; }
  body.affilies .lst-clas .c-leads { order: 5; } body.affilies .lst-clas .c-tendance_leads { order: 6; }
  body.affilies .lst-clas .c-tendance_deposants { order: 7; } body.affilies .lst-clas td.trie:not(.cle) { order: 8; }
  body.affilies .lst-clas td.trie { background: transparent; }
  body.affilies .lst-clas td.trie .lib { color: var(--c-accent); }
  body.affilies .lst-clas .lib { display: block; margin-top: 2px; font: 400 11px/1.3 var(--f-sans); color: var(--c-text-3); white-space: normal; }
  body.affilies .lst-clas tfoot tr { border-top: 2px solid var(--c-line-strong); background: var(--c-surface-2); }
  body.affilies .lst-clas tfoot th, body.affilies .lst-clas tfoot td { border-top: 0; }
}
@media (max-width: 1100px) {
  body.affilies .podium .v { font-size: 18px; }
}
@media (max-width: 760px) {
  body.affilies .periodes { margin-top: 0; }
  body.affilies .periodes .seg { width: 100%; }
  body.affilies .periodes .seg a { flex: 1; justify-content: center; height: 34px; }
  body.affilies .periodes .perso { width: 100%; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 8px; }
  body.affilies .periodes .perso input[type="date"] { width: 100%; height: 40px; }
  body.affilies .periodes .perso .btn { grid-column: 1 / -1; height: 40px; }
  body.affilies .filtres-aff { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; overflow: visible; margin: 0 0 14px; padding: 0; }
  body.affilies .filtres-aff input[type="search"] { grid-column: 1 / -1; width: 100%; height: 40px; }
  body.affilies .filtres-aff select { width: 100%; height: 40px; }
  body.affilies .filtres-aff .btn { width: 100%; height: 40px; justify-content: center; }
  body.affilies .filtres-aff .btn.ghost { grid-column: 1 / -1; }
  body.affilies .podium ol { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  body.affilies .lst-clas tr { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  body.affilies .trier-par select { flex: 1 1 140px; height: 40px; }
  body.affilies .trier-par .btn { height: 40px; }
}
/* ---- Fin de la section « Affiliés : classement » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Fiche affilié : en-tête, liens, période, tuiles, courbe par jour, entonnoir, déposants, mouvements ; noms du copieur (tâche D3) ----
   Fiche affilié (`body.affilies`, affilie.html, spec 2026-10-19 §4) : en-tête (badges, mention « Masqué »), liens à copier
   en grille (une à quatre colonnes selon la place), phrase de la période, tuiles de la période (déposé et retiré : une
   ligne par devise, jamais additionnées), puis deux rangées de deux panneaux (courbe et entonnoir ; mouvements et
   derniers leads), empilées jusqu'à 1100 px, et « Ses clients qui ont déposé » pleine largeur (tableau au-dessus de
   1100 px, cartes en dessous, chaque chiffre avec son libellé `.lib`). Courbe par jour : une colonne par jour, leads au-
   dessus de l'axe, dépôts réels en dessous, chaque série à sa propre échelle ; l'écart entre colonnes diminue avec leur
   nombre (366 jours tiennent sans défiler) ; les dates sous l'axe sont au plus une dizaine, les autres jours restent dits
   en texte pour un lecteur d'écran. Noms du copieur (macro `noms_copieur`, chaque nom dans un <bdi>) : fiche affilié,
   fiche personne (`body.detail`, au-dessus des mouvements) et Comptes MT5 (`body.mt5`, colonne Copieur). */
body.affilies .fiche-aff .badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }
body.affilies .fiche-aff .badge { white-space: nowrap; }
body.affilies .note-masque { display: flex; align-items: center; gap: 6px; margin: 8px 0 0; font-size: var(--fs-sm); color: var(--c-text-2); overflow-wrap: anywhere; }
body.affilies .liens-aff { margin-bottom: 18px; }
body.affilies .liens-aff .kv { grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); }
body.affilies .liens-aff .kv > div { min-width: 0; }
body.affilies .periode-dite { margin: -6px 0 14px; font-size: var(--fs-sm); color: var(--c-text-3); overflow-wrap: anywhere; }
body.affilies .tuiles-indispo { margin-bottom: 20px; }
body.affilies .stats.s5 { margin-bottom: 0; }
body.affilies .stats.s5 .stat .d { white-space: normal; }
body.affilies .stats.s5 .stat .dv { display: block; }
body.affilies .stats.s5 .t-depose .v, body.affilies .stats.s5 .t-retire .v { font-size: 20px; line-height: 1.25; }
body.affilies .stats.s5 .tendance.hausse { color: var(--c-ok); }
body.affilies .stats.s5 .tendance.baisse { color: var(--c-err); }
body.affilies .stats.s5 .tendance.nouveau { color: var(--c-accent); }
body.affilies .note-tuiles { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 12px; margin: 8px 2px 20px; font-size: 12px; color: var(--c-text-3); overflow-wrap: anywhere; }
body.affilies .duo { align-items: start; margin-bottom: 20px; }
body.affilies .fn-row .fn-note { grid-column: 1 / -1; line-height: 1.3; }
/* Courbe par jour : leads au-dessus de l'axe, dépôts réels dessous. */
body.affilies .courbe .legende { display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 10px 16px 0; font-size: 12px; color: var(--c-text-3); }
body.affilies .courbe .legende span::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 6px; border-radius: 2px; vertical-align: -1px; }
body.affilies .courbe .legende .l-leads::before { background: var(--c-accent); }
body.affilies .courbe .legende .l-depots::before { background: var(--c-ok); }
body.affilies .courbe .jours {
  display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); column-gap: clamp(0px, calc(40% / var(--n)), 4px);
  position: relative; margin: 0; padding: 12px 16px 8px; list-style: none;
}
body.affilies .courbe .jour { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: 96px 48px 18px; min-width: 0; }
body.affilies .courbe .haut { display: flex; align-items: flex-end; border-bottom: 1px solid var(--c-line-strong); }
body.affilies .courbe .bas { display: flex; align-items: flex-start; }
body.affilies .courbe .haut i, body.affilies .courbe .bas i { display: block; width: 100%; }
body.affilies .courbe .b-leads { background: var(--c-accent); border-radius: 2px 2px 0 0; }
body.affilies .courbe .b-depots { background: var(--c-ok); border-radius: 0 0 2px 2px; }
body.affilies .courbe .jour.cours .b-leads, body.affilies .courbe .jour.cours .b-depots { opacity: .6; }
/* date centrée sur sa colonne même plus large qu'elle (flex : le débord se partage des deux côtés) ; la dernière, toujours
   écrite, s'aligne à droite de sa colonne pour ne jamais sortir du panneau, la première à gauche */
body.affilies .courbe .date { display: flex; justify-content: center; margin-top: 4px; font: 11px/14px var(--f-mono); color: var(--c-text-3); white-space: nowrap; }
body.affilies .courbe .jour:first-child .date { justify-content: flex-start; }
body.affilies .courbe .jour:last-child .date { justify-content: flex-end; }
body.affilies .courbe .jour.cours .date { color: var(--c-accent); }
/* « Ses clients qui ont déposé » : tableau, montants une ligne par devise. */
body.affilies .deposants-aff { margin-bottom: 20px; }
body.affilies .lst-dep .lib { display: none; }
body.affilies .lst-dep td { vertical-align: top; }
body.affilies .lst-dep td.num { white-space: nowrap; }
body.affilies .lst-dep .dv { display: block; }
body.affilies .lst-dep .c-client, body.affilies .lst-dep .c-copieur { overflow-wrap: anywhere; min-width: 0; }
body.affilies .lst-dep .c-client .nom { font-weight: var(--fw-medium); }
body.affilies .lst-dep .c-copieur { font-size: 12px; color: var(--c-text-2); }
body.affilies .lst-dep .c-copieur .noms + .noms { margin-top: 8px; }
body.affilies .lst-dep .nom-copieur { display: block; }
body.affilies .lst-dep .c-copieur .cpt { display: block; color: var(--c-text-3); white-space: nowrap; }  /* chaque groupe de noms sous son compte abrégé */
body.affilies .tous-leads { border-top: 1px solid var(--c-line); }
body.affilies .tous-leads h3 { margin: 0; padding: 12px 16px 0; font-size: var(--fs-sm); font-weight: var(--fw-semibold); }
body.affilies .tous-leads .note-tous { margin: 0; padding: 6px 16px 12px; font-size: 12px; }
/* Derniers dépôts et retraits : montant signé, sens, client, noms du compte, date, broker, compte abrégé. */
body.affilies .mvts { list-style: none; margin: 0; padding: 0; }
body.affilies .mvt { display: flex; align-items: baseline; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--c-line); }
body.affilies .mvt:last-child { border-bottom: 0; }
body.affilies .mvt .amt { flex: none; min-width: 84px; font: 600 var(--fs-md)/1.3 var(--f-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
body.affilies .mvt.depot .amt { color: var(--c-ok); }
body.affilies .mvt .info { flex: 1; min-width: 0; font-size: var(--fs-sm); overflow-wrap: anywhere; }
body.affilies .mvt .l1 { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 8px; }
body.affilies .mvt .l1 .qui a { color: var(--c-text); font-weight: var(--fw-medium); }
body.affilies .mvt .l1 .qui a:hover { color: var(--c-accent); }
body.affilies .mvt .l1 .qui .s { margin-left: 6px; color: var(--c-text-3); font-size: 12px; }
body.affilies .mvt .l3 { margin-top: 2px; font-size: 12px; color: var(--c-text-2); }
body.affilies .mvt .l3 .nom-copieur + .nom-copieur::before { content: " · "; color: var(--c-text-3); }
body.affilies .mvt .l2 { margin-top: 2px; color: var(--c-text-3); }
body.affilies .mvt .l2 .cpt { white-space: nowrap; }
@media (max-width: 1100px) {
  body.affilies .duo { grid-template-columns: minmax(0, 1fr); gap: 16px; margin-bottom: 16px; }
  body.affilies .lst-dep thead { display: none; }
  body.affilies .lst-dep, body.affilies .lst-dep tbody { display: block; }
  body.affilies .lst-dep tr.deposant { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px 12px; padding: 12px 16px; border-bottom: 1px solid var(--c-line); }
  body.affilies .lst-dep tbody tr.deposant:last-child { border-bottom: 0; }
  body.affilies .lst-dep tr.deposant td { display: block; padding: 0; border: 0; text-align: left; min-width: 0; }
  body.affilies .lst-dep tr.deposant td.c-client, body.affilies .lst-dep tr.deposant td.c-copieur { grid-column: 1 / -1; }
  body.affilies .lst-dep tr.deposant td.num { white-space: normal; overflow-wrap: anywhere; }
  body.affilies .lst-dep .lib { display: block; margin-bottom: 2px; font: 400 11px/1.3 var(--f-sans); color: var(--c-text-3); }
  /* « compte 8800… » à gauche, ses noms l'un sous l'autre à droite : on voit quel nom va avec quel compte */
  body.affilies .lst-dep .c-copieur .noms { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 10px; }
  body.affilies .lst-dep .c-copieur .cpt { grid-column: 1; grid-row: 1 / span 2; }
  body.affilies .lst-dep .c-copieur .nom-copieur { grid-column: 2; }
}
@media (max-width: 760px) {
  body.affilies .stats.s5 .t-depose .v, body.affilies .stats.s5 .t-retire .v { font-size: 18px; }
  body.affilies .courbe .jour { grid-template-rows: 80px 40px 18px; }
  body.affilies .lst-dep tr.deposant { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  body.affilies .mvt { gap: 10px; padding: 10px 14px; }
  body.affilies .mvt .amt { min-width: 72px; font-size: var(--fs-sm); }
}
/* Fiche personne : chaque compte du copieur et ses noms, au-dessus des mouvements. */
body.detail .comptes-copieur { display: flex; flex-direction: column; gap: 6px; padding: 8px 16px; border-bottom: 1px solid var(--c-line); font-size: 12px; color: var(--c-text-2); }
body.detail .comptes-copieur .cc { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 10px; overflow-wrap: anywhere; min-width: 0; }  /* le compte à gauche, ses noms l'un sous l'autre à droite */
body.detail .comptes-copieur .cpt { grid-column: 1; grid-row: 1 / span 2; color: var(--c-text-3); white-space: nowrap; }
body.detail .comptes-copieur .nom-copieur { grid-column: 2; }
/* Comptes MT5 : les noms du compte, une ligne chacun, dans la colonne Copieur. */
body.mt5 .lst-mt5 td.c-copieur .ar.noms { overflow-wrap: anywhere; }
body.mt5 .lst-mt5 td.c-copieur .nom-copieur { display: block; }
/* ---- Fin de la section « Fiche affilié » (les tâches suivantes ajoutent leur CSS après) ---- */

/* ---- Masquage des affiliés : boutons « Masquer » / « Réafficher », message après l'action (tâche D4) ----
   Liste et fiche affilié (`body.affilies`). Les boutons sont de simples formulaires POST (routes/masquage.py), affichés
   seulement si l'accès en écriture est configuré. Fiche : le bouton à droite de l'en-tête (sous le titre sur mobile).
   Liste : un petit bouton bordé sous le nom de chaque ligne ; sous 1280 px, la carte entière est un lien (pseudo-
   élément du nom posé par-dessus), le formulaire passe donc au-dessus pour rester cliquable. Message après l'action :
   bandeau vert, annoncé aux lecteurs d'écran (`role="status"`). */
body.affilies .fait {
  display: flex; align-items: center; gap: 8px; margin: -8px 0 14px; padding: 8px 12px; border-radius: var(--r-sm);
  background: var(--c-ok-bg); color: var(--c-ok); font-size: var(--fs-sm); font-weight: var(--fw-medium); overflow-wrap: anywhere;
}
body.affilies .page-head .action-masque { margin-left: auto; flex: none; }
body.affilies .lst-clas .action-masque { display: block; margin-top: 6px; }
body.affilies .lst-clas .action-masque .btn { height: 24px; padding: 0 8px; border-color: var(--c-line); font-size: 12px; color: var(--c-text-2); }
body.affilies .lst-clas .action-masque .btn:hover, body.affilies .lst-clas .action-masque .btn:focus-visible { border-color: var(--c-line-strong); color: var(--c-text); }
@media (max-width: 1280px) {
  body.affilies .lst-clas .action-masque { position: relative; z-index: 1; display: inline-block; }
  body.affilies .lst-clas .action-masque .btn { height: 32px; padding: 0 12px; }
}
@media (max-width: 760px) {
  body.affilies .page-head.fiche-aff { flex-wrap: wrap; align-items: flex-start; }
  body.affilies .page-head .action-masque { margin-left: 0; width: 100%; }
  body.affilies .page-head .action-masque .btn { width: 100%; height: 40px; }
  body.affilies .lst-clas .action-masque .btn { height: var(--tap); padding: 0 16px; }
}
/* ---- Fin de la section « Masquage des affiliés » (les tâches suivantes ajoutent leur CSS après) ---- */
