/* ════════════════════════════════════════════════════════════════════════
   TOKENS — SOURCE DE VÉRITÉ UNIQUE DU DESIGN SYSTEM
   ────────────────────────────────────────────────────────────────────────
   Chargé EN DERNIER parmi les CSS globaux (v2 → components → liquid →
   theme-experiment → TOKENS) : ce fichier gagne toujours.

   Lot DS-0 (2026-08-08, décision fondateur « go tout ») : la charte était
   éclatée sur 12 fichiers redéclarant `:root`, 25+ valeurs d'arrondi et
   256 couleurs littérales. Tout converge ici.

   RÈGLE GELÉE — plus aucun littéral dans le code neuf :
     • un arrondi  → var(--radius…)      (jamais « 12px »)
     • une couleur → var(--…)            (jamais « #3A64F2 »)
     • un espace   → var(--sp-…)         (jamais « 20px »)
     • une typo    → var(--fs-…)         (jamais « 12.5px »)
   Les valeurs ci-dessous sont verrouillées par tests/design_tokens_contract_test.js.

   DIRECTION ARTISTIQUE — V04 OBSIDIENNE VIOLETTE (2026-08-21).
   Un CRM calme, éditorial et dense juste ce qu'il faut : la hiérarchie vient
   de la typographie, des règles de 1px, de l'alignement et de l'espace. Les
   ombres sont réservées aux éléments qui flottent réellement. La géométrie
   est désormais adoucie par rôle, de 4 à 16px, tandis que les tableaux et
   séparateurs restent plats. Seuls les avatars et compteurs ronds utilisent
   une géométrie circulaire. Un seul accent signale l'action ou l'état actif.
   Aucun dégradé décoratif, aucun reflet interne.
   ════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════
   1. GÉOMÉTRIE — V04 ARRONDIE ET MAÎTRISÉE
   ───────────────────────────────────────────────────────────────
   Six crans associent le rayon à la taille et à l'élévation : micro-marqueur,
   contrôle dense, contrôle compact, contrôle standard, panneau et surface
   flottante. Les tableaux et listes de données conservent --radius-none.
   `--radius-pill` est réservé aux compteurs ronds et aux jauges ; un statut
   informatif est désormais un point + libellé, jamais une capsule.
   ═══════════════════════════════════════════════════════════════ */
:root,
:root[data-theme="light"],
:root[data-theme="dark"] {
  --radius-none: 0;
  --radius-xs: 6px;
  --radius-dense: 8px;
  --radius-sm: 10px;
  --radius: 12px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --radius-pill: 999px;
}

/* ═══════════════════════════════════════════════════════════════
   2. ESPACEMENT — rythme de 4px
   Les 46 valeurs littérales du site se projettent sur ces 8 crans.
   ═══════════════════════════════════════════════════════════════ */
:root,
:root[data-theme="light"],
:root[data-theme="dark"] {
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-12: 48px;
  --sp-16: 64px;

  /* Alias historiques (v2.css) — conservés le temps du balayage DS-3. */
  --sp-7: 28px;
  --sp-10: 40px;
}

/* ═══════════════════════════════════════════════════════════════
   3. TYPOGRAPHIE — échelle unique à 7 crans
   ───────────────────────────────────────────────────────────────
   Remplace les 84 tailles distinctes relevées (13px, 12.5px, 11.5px,
   .72rem, .68rem… soit le même cran écrit de quatre façons).
   Satoshi pour l'interface, JetBrains Mono pour les DONNÉES
   (chiffres, compteurs, domaines, identifiants).
   ═══════════════════════════════════════════════════════════════ */
:root,
:root[data-theme="light"],
:root[data-theme="dark"] {
  --fs-micro: 11px;   /* étiquettes majuscules, mentions légales */
  --fs-xs: 12px;      /* métadonnées, colonnes secondaires */
  --fs-sm: 13px;      /* texte d'interface dense — le cran le plus courant */
  --fs-base: 14px;    /* corps de texte */
  --fs-md: 16px;      /* sous-titres, chiffres de carte */
  --fs-lg: 20px;      /* titres de section */
  --fs-xl: 28px;      /* titre de section majeur */
  --fs-page: 30px;    /* titre de page Carbon Editorial */

  /* Hors hiérarchie de lecture — DS-3, arbitrage du 2026-08-08.
     Les sept crans ci-dessus décrivent du TEXTE : chacun dit une place dans
     la hiérarchie de lecture. Un chiffre de KPI ou une note d'audit n'a pas
     de place dans cette hiérarchie — c'est un nombre dimensionné pour être
     lu de loin, et le plafonner à 28px écrasait sur un seul cran ce qui en
     occupait trois (34px, 40px, 28px). Ce cran-ci est réservé à ces
     nombres-là, et il est le SEUL au-dessus de --fs-xl : il ne sert jamais
     à un titre ni à du texte courant.
     Cas voisin mais distinct — l'initiale d'une pastille d'avatar est
     dimensionnée sur son cercle, pas sur une échelle : elle reste littérale,
     comme le `border-radius: 50%` qui la porte (cf. §1). */
  --fs-display: 34px;

  --lh-tight: 1.25;   /* titres */
  --lh-page: 34px;    /* contrat titre de page 30/34 */
  --lh-base: 1.5;     /* corps */
  --lh-loose: 1.65;   /* paragraphes longs */

  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;

  --tracking-label: .06em;  /* étiquettes en majuscules */

  --font-ui: 'Satoshi', 'Montserrat', system-ui, -apple-system, sans-serif;
  /* --font-title : titres HISTORIQUES (h1-h6, .page-title, .kpi-value, .mnav-brand,
     et surtout le logo Ciblup rendu par `inc/helpers_logo.php` en graisses 780/800).
     Ce jeton nommait 'Poppins' mais rendait Satoshi, car `css/v2.css` aliasait la
     famille. L'alias est retiré le 2026-08-11 pour rétablir les vraies Poppins ; ce
     jeton est donc explicitement recalé sur Satoshi afin que TOUS ces usages rendent
     exactement comme avant. C'est ce qui protège le logo : Poppins n'existe qu'en
     600/700, le navigateur synthétiserait 780 et 800 — et le logo est hors périmètre
     par consigne du fondateur (« ne touche pas au logo »). */
  --font-title: 'Satoshi', system-ui, sans-serif;
  /* --font-display : les vraies Poppins, réservées aux DEUX rôles de titre nommés par
     le contrat V7 §5.5 (« Titre de page » 24/32, « Titre de panneau » 16/24). Jeton
     déclaré ici, appliqué en U2 — aucun sélecteur ne le consomme encore, donc aucun
     changement de rendu à ce stade. */
  --font-display: 'Poppins', 'Satoshi', system-ui, sans-serif;
  --font-data: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ═══════════════════════════════════════════════════════════════
   4. ÉLÉVATION — 3 niveaux, pas 83
   ───────────────────────────────────────────────────────────────
   Toujours trois niveaux, mais la V4 change leur DESSIN, pas leur
   nombre. DS-0 avait des ombres courtes et denses (1px/2px de flou
   à 28-38 %), pensées comme un simple liseré sous une bordure : à
   l'écran, cela produit un bord dur — l'exact « effet utilitaire »
   que la V4 nomme et rejette. La V4 les remplace par des ombres
   LARGES et PÂLES (28 px et 50 px de flou, opacité basse), qui ne
   se lisent pas comme un trait mais comme de l'air sous l'élément.
   La règle d'usage est inchangée, et elle reste stricte :
     --elev-0  posé — le défaut, l'écrasante majorité des surfaces
     --elev-1  détaché : menu, sélecteur, carte réellement soulevée
     --elev-2  flottant : modale et drawer UNIQUEMENT
   Aucun biseau, aucun reflet interne, aucune ombre portée « pour
   faire joli » : une ombre annonce une distance au fond, sinon elle
   ment. La bordure ne disparaît pas pour autant — elle change de
   métier : elle ne fabrique plus le relief, elle marque une limite
   interactive ou sépare des données denses.
   ═══════════════════════════════════════════════════════════════ */
:root,
:root[data-theme="light"],
:root[data-theme="dark"] {
  --elev-0: none;                              /* posé — le défaut */
  --elev-1: 0 8px 28px rgba(0,0,0,.10);        /* détaché : menu, picker */
  --elev-2: 0 18px 50px rgba(0,0,0,.22);       /* flottant : modale, drawer */
  /* ⚠️ Les deux valeurs ci-dessus sont un REPLI (page sans data-theme). Les vraies
     valeurs sont PAR THÈME, dans les blocs palette plus bas : une ombre noire à 28 %
     posée sur une interface claire fait une tache grise sale, pas une élévation.
     Cf. §4bis. */

  /* [DS-5] Les cinq alias d'ombre hérités (--shadow-card, --m-nav-shadow,
     --shadow-sm/md/lg) ont été SUPPRIMÉS ici, comme leurs commentaires [DS-3] le
     promettaient. Ils redirigeaient déjà vers --elev-1/--elev-2 ; leurs 15 derniers
     usages (outils.css, clients.css, guided-journey.css, conversations.css,
     components.css, v2.css) pointent désormais droit sur le niveau canonique.
     La substitution est à rendu strictement identique — un alias qui vaut
     `var(--elev-1)` produit la même valeur calculée que --elev-1 — donc rien ne
     bouge à l'écran ; ce qui disparaît, c'est le détour qui laissait croire que le
     site avait cinq élévations de plus que les trois du système. */

  /* [DS-3] Même traitement pour la matière : la famille --m-panel-* / --m-ctl-*
     est un SECOND jeu de surfaces, hérité de la strate « liquid », qui vivait à
     côté du jeu canonique. Mesuré en nuit : panneau rgba(20,20,20,.92) au lieu
     de --surface #18181A, bordure rgba(161,161,161,.16) — un gris CLAIR — au lieu
     de --border #212124, contrôle #1a1a1a au lieu de --surface-2. Des écarts
     assez petits pour passer inaperçus une page à la fois, assez systématiques
     pour que deux cartes voisines n'aient pas la même matière.
     Le flou associé valait déjà 0px partout : il n'y avait plus de verre, juste
     une translucidité résiduelle. Ces alias raccrochent les 20+ consommateurs
     (analytics, agenda, clients, prospection, components, liquid, v2, billing,
     parrainage) au jeu canonique d'un seul geste. À supprimer en DS-4 avec
     leurs derniers usages. */
  --m-panel-bg:     var(--surface);
  --m-panel-border: var(--border);
  --m-ctl-bg:       var(--surface-2);
  --m-ctl-bg-hover: var(--surface-hover);
  --m-ctl-border:   var(--border);
}

/* ═══════════════════════════════════════════════════════════════
   5. PALETTE — accent violet V04 (GO fondateur du 2026-08-21)
   ───────────────────────────────────────────────────────────────
   La V04 remplace la direction cyan V05 par un violet premium : #7257D9
   en clair et #9A86F5 en nuit. Le cyan #62C9D0 ne subsiste que comme
   couleur utilitaire secondaire (information et deuxième série de graphe).
   Les jetons dépendants de l'accent sont redéfinis ensemble : RGB, survol,
   état actif, tons, bordure, focus, sélection et graphe primaire.

   Le contraste est porté par rôle : texte blanc sur le violet clair, encre
   profonde sur le violet nuit. Les grandes surfaces restent neutres et mates ;
   la couleur identifie une action, une sélection ou un état, jamais un décor.
   ═══════════════════════════════════════════════════════════════ */

/* ── CLAIR ── */
:root[data-theme="light"] {
  /* Neutres froids très légers : le workspace se détache du shell sans créer
     une succession de cartes blanches ou un contraste clinique. */
  --bg: #F3F3F5; --bg-soft: #F7F7F9; --surface: #FFFFFF; --surface-hover: #F0EFF7; --surface-2: #F7F7FA;
  --text: #19191D; --text-secondary: #4D4D57; --text-muted: #70707C; --text-dim: #70707C;
  /* La COQUILLE (barre latérale, barre haute) n'est pas une surface de contenu :
     dans la maquette elle est d'un cran plus sombre que les cartes, ce qui fait
     lire la zone de travail comme un panneau posé DEVANT le châssis. Le site
     peignait les deux avec --surface, d'où une interface uniformément blanche où
     rien ne distinguait l'outil du contenu. */
  --shell: #ECECF0;
  --context: #F6F6F8;
  --accent: #7257D9; --accent-rgb: 114,87,217; --accent-hover: #6248C9; --accent-active: #523AB7;
  --accent-bright: #7257D9; --accent-bright-rgb: 114,87,217;
  --accent-soft: #EEEAFE; --accent-soft-strong: #E3DCFC; --accent-border: rgba(114,87,217,.34);
  --info: #3F9FA8; --info-border: rgba(63,159,168,.34);
  --border: #DADAE0; --border-strong: #777783;
  --shell-line-strong: #C8C8D0;
  --overlay-veil: rgba(22,20,32,.18);
  /* Élévation en CLAIR (V4) : ombre LARGE et PÂLE, teintée de l'encre du texte
     plutôt que d'un noir pur — sur un fond crème, un noir pur fait une tache grise
     sale. Les valeurs viennent de la maquette V4 : `0 8px 28px rgba(21,21,26,.055)`
     pour la carte, `0 18px 50px …` pour la modale. La maquette écrit la modale en
     noir pur (.18) ; on garde la teinte encre pour que les deux niveaux soient de
     la même famille — à cette opacité l'écart entre #000 et #15151A est sous le
     seuil de perception, et l'homogénéité vaut mieux qu'une fidélité au pixel près.
     L'opacité de la modale monte à .18 (contre .12 avant) parce que le flou passe
     de 24 à 50 px : à surface étalée, il faut plus d'encre pour la même présence. */
  --elev-1: 0 12px 34px rgba(34,27,57,.08);
  --elev-2: 0 26px 72px rgba(26,21,42,.22);
  /* [Ciblup V4, 2026-08-10] Le rouge d'alerte passe de #E52441 (rouge pur, très
     saturé) à #B34A4A, la brique désaturée de la maquette V4. Raison : sur une
     interface qui n'a plus qu'UN accent et aucun dégradé, un rouge à cette
     saturation devient l'élément le plus criard de l'écran — il attire l'œil
     avant l'accent, y compris quand il ne fait qu'étiqueter une ligne « perdu ».
     La brique reste parfaitement identifiable comme alerte (elle est la seule
     couleur chaude du système) sans hurler.
     Mesuré à la main : #B34A4A sur blanc = 5,26:1 (AA texte).
     --danger-text descend d'un cran (#9A3C3C = 5,93:1 sur --danger-soft posé sur
     blanc) au lieu de garder l'ancien #B91C1C : celui-ci reste lisible (5,64:1)
     mais c'est un rouge PUR, donc un badge aurait porté un texte d'une teinte et
     une bordure d'une autre. */
  --danger: #B34A4A; --danger-soft: rgba(179,74,74,.10); --danger-border: rgba(179,74,74,.26);
  --success-text: #166534; --danger-text: #9A3C3C;
  /* [Ciblup v3, 2026-08-10] Troisième membre de la famille « texte sémantique »,
     ajouté pour que le badge bêta puisse abandonner son dégradé sans perdre en
     lisibilité : --warning (#D97706) sur --warning-soft ne vaut que 2,81:1, tandis
     que #854D0E y vaut 6,04:1. La valeur n'est pas inventée — c'est déjà celle
     qu'utilisaient en dur css/guided-journey.css:165 et :461 pour ce même fond.
     [Ciblup V4] La valeur bascule sur #6B4E00 : la V4 remplace l'ambre #D97706
     par l'ocre #8A6400 (cf. css/v2.css), et #854D0E tirait sur le brun-rouge —
     texte et fond n'auraient plus été de la même famille. Mesuré à la main :
     #6B4E00 sur --warning-soft posé sur blanc = 6,58:1. */
  --warning-text: #6B4E00;
  --row-hover: rgba(114,87,217,.055);
  --field-focus-border: #7257D9;
  /* [Ciblup V4, 2026-08-10] LES CHAMPS. La maquette V4 écrit
     `.input{height:11mm;border:0;border-radius:10px;background:#F0F0EC}` puis
     `.input.focus{box-shadow:0 0 0 2px var(--action)}`. Le site faisait l'inverse :
     champ BLANC cerné d'un liseré gris, c'est-à-dire exactement l'échantillon que
     la page 01 de la V4 étiquette « Avant — effet utilitaire ». Un champ est un
     CREUX, pas une boîte : il se signale par un fond légèrement en retrait de la
     carte qui le porte, et la bordure devient inutile.
       --field-bg   #F0F0EC, valeur littérale de la V4. Il ne réutilise pas
                    --surface-2 (#F2F2EE) : celui-ci sert de fond de zone (sous-cartes,
                    entêtes de table) et un champ posé DANS une sous-carte doit rester
                    d'un cran plus creux qu'elle.
       --field-ring anneau de focus : 2 px pleins, « sans halo excessif » (page 07).
                    L'ancien 0 0 0 3px rgba(accent,.12) était un halo de 3 px à 12 %
                    d'opacité — assez pour épaissir le champ, trop pâle pour se voir.
     Contraste mesuré : --text #15151A sur #F0F0EC = 15,7:1 ; --text-dim #6A6A74
     (placeholder) y vaut 5,0:1. Le champ n'est pas un composant d'interface au sens
     de 1.4.11 tant qu'il est identifiable — ici par son aplat contre --surface. */
  --field-bg: #F4F4F7;
  --field-bg-focus: #FFFFFF;
  --field-ring: 0 0 0 3px rgba(114,87,217,.18);
  /* [Refonte v3] Trois orphelins de v2.css rattrapés ici — ils avaient survécu à
     DS-0→DS-5 parce que ces passes n'avaient absorbé QUE --accent, et ils portaient
     donc encore l'azur « Blue Frost » sur une interface devenue cyan. Repérés en
     MESURANT la page rendue, pas en relisant le code : rien dans la console ne
     signale un jeton resté sur son ancienne valeur.
       --accent-link      156 usages (liens, icônes, pastilles de priorité). C'est
                          du texte → il prend la valeur d'action, pas la vive.
       --focus-ring-color l'anneau de focus clavier de TOUT le site était figé en
                          rgba(8,112,207,…) : on l'exprime en rgba(var(--accent-rgb),…)
                          pour qu'il suive automatiquement tout futur accent.
       --accent-warm      l'orange #F0925F de l'étoile « favori » (3 usages).
                          Point 7 du fondateur : « Orange peut être trop futuriste ».
                          L'état favori est déjà porté par la FORME (étoile pleine vs
                          contour) — la couleur n'avait rien à y ajouter, elle suit
                          donc l'accent comme tout autre état actif. */
  --accent-link: #6248C9;
  --focus-ring-color: rgba(114,87,217,.62);
  --accent-warm: #7257D9;
  /* Texte posé SUR un aplat --accent (.btn-primary, .modal-btn-primary, pastilles
     de compteur…). Blanc sur #046C75 = 6,17:1, et 8,42:1 sur le survol. */
  --on-accent: #FFFFFF;
  /* Aplat neutre foncé — le second registre de la maquette v3 (bouton secondaire
     plein, en-tête de tableau dense, pastille de compteur sombre). Il n'a rien à
     voir avec l'accent : c'est de l'encre, elle ne signale rien, elle structure. */
  --ink: #19191D; --on-ink: #FFFFFF;
  /* Statut « à venir » */
  --violet: #6D28D9; --violet-soft: #EDE9FE; --on-violet: #FFFFFF;

  /* [Design system nuit + pilules, 2026-08-21] Triplets sémantiques V04.
     Chaque statut possède un signal (point), un ton (fond) et une encre (texte).
     Les noms décrivent le sens métier ; aucun composant ne recalcule une couleur
     à partir d'un hex API. Les sept encres passent AA sur leur ton associé. */
  --status-neutral-signal: #76878A; --status-neutral-tone: #EEF2F0; --status-neutral-text: #445055;
  --status-pending-signal: #3F7CC9; --status-pending-tone: #E5EEF9; --status-pending-text: #285A93;
  --status-replied-signal: #0C6F78; --status-replied-tone: #E4EEED; --status-replied-text: #0C6F78;
  --status-rdv-signal: #7257D9; --status-rdv-tone: #EEEAFE; --status-rdv-text: #523AB7;
  --status-signed-signal: #24945B; --status-signed-tone: #E2F2E8; --status-signed-text: #166534;
  --status-standby-signal: #9A7312; --status-standby-tone: #F5EEDB; --status-standby-text: #6B4E00;
  --status-lost-signal: #B34A4A; --status-lost-tone: #F7E6E6; --status-lost-text: #9A3C3C;
}

/* ── NUIT ── */
:root[data-theme="dark"] {
  /* V04 « Obsidienne Violette » : le canvas est le niveau le plus profond,
     puis la coquille, les surfaces de lecture et enfin le survol. Les grands
     blocs se séparent par des règles plutôt que par une pile de cartes grises. */
  --bg: #090A0D; --bg-soft: #0D0F13; --surface: #111318; --surface-hover: #1C1E26; --surface-2: #171920;
  --text: #F1F0F5; --text-secondary: #C5C3CD; --text-muted: #92909C; --text-dim: #92909C;
  --shell: #0C0D11;
  --context: #101116;
  --accent: #9A86F5; --accent-rgb: 154,134,245; --accent-hover: #AA99F8; --accent-active: #B9ABFA;
  --accent-bright: #9A86F5; --accent-bright-rgb: 154,134,245;
  --accent-soft: rgba(154,134,245,.13); --accent-soft-strong: rgba(154,134,245,.20); --accent-border: rgba(154,134,245,.38);
  --info: #62C9D0; --info-border: rgba(98,201,208,.36);
  --border: #282B32; --border-strong: #626673;
  --shell-line-strong: #343741;
  --primary-bg: #9A86F5; --primary-ink: #0E0B18;
  --overlay-veil: rgba(0,0,0,.48);
  /* En nuit l'ombre garde du corps : c'est elle qui détache une modale d'un fond
     déjà sombre, là où en clair c'est la bordure qui fait le travail. Même
     géométrie V4 (8/28 puis 18/50), mais opacités plus hautes : sur un fond
     #0E0E10, une ombre à 5 % est purement et simplement invisible. La maquette V4
     ne chiffre pas le versant nuit — elle ne montre la nuit que sur des aplats —,
     donc ces deux valeurs sont une TRANSPOSITION, pas une recopie : on conserve le
     rapport d'opacité entre les deux niveaux de l'ancienne paire nuit (.45 / .55). */
  --elev-1: 0 14px 38px rgba(0,0,0,.38);
  --elev-2: 0 30px 86px rgba(0,0,0,.64);
  --danger: #F56668; --danger-soft: rgba(245,102,104,.14); --danger-border: rgba(245,102,104,.30);
  --success-text: #3AD77F; --danger-text: #F76F71;
  /* Versant nuit : sur --warning-soft (fond sombre), l'ambre pleine teinte vaut
     6,63:1 — pas besoin de l'assombrir comme en clair. */
  --warning-text: #F5A623;
  --row-hover: rgba(154,134,245,.075);
  --field-focus-border: #9A86F5;
  /* Les champs restent mats : un cran sous la surface au repos, puis au niveau
     de la surface au focus. La bordure et l'anneau portent l'interaction. */
  --field-bg: #0D0F13;
  --field-bg-focus: #15171D;
  --field-ring: 0 0 0 3px rgba(154,134,245,.20);
  /* Cf. le bloc clair : les trois orphelins de v2.css, versant nuit. */
  --accent-link: #A997FA;
  --focus-ring-color: rgba(154,134,245,.72);
  --accent-warm: #9A86F5;
  /* Le violet nuit porte une encre profonde pour préserver le contraste. */
  --on-accent: #0E0B18;
  /* En nuit l'encre s'inverse : l'aplat « neutre appuyé » devient clair. */
  --ink: #F1F0F5; --on-ink: #0E0B18;
  /* Statut « à venir » */
  --violet: #A78BFA; --violet-soft: rgba(167,139,250,.15); --on-violet: #0E0A1F;

  /* Versant nuit des mêmes rôles. Les fonds restent mats et proches de la
     surface ; la couleur sert uniquement à lire l'état, jamais à créer un halo. */
  --status-neutral-signal: #8F9A9E; --status-neutral-tone: #20272A; --status-neutral-text: #B9C2C5;
  --status-pending-signal: #68A7EA; --status-pending-tone: #1D2C3A; --status-pending-text: #A9CEF5;
  --status-replied-signal: #66C9D1; --status-replied-tone: #18383D; --status-replied-text: #BDECEF;
  --status-rdv-signal: #9A86F5; --status-rdv-tone: rgba(154,134,245,.16); --status-rdv-text: #D5CCFF;
  --status-signed-signal: #3AD77F; --status-signed-tone: #193226; --status-signed-text: #A5E5BE;
  --status-standby-signal: #EAB308; --status-standby-tone: #342D1C; --status-standby-text: #F5C86B;
  --status-lost-signal: #F56668; --status-lost-tone: #392326; --status-lost-text: #FFB5B6;
}

/* ── Couleurs de MARQUE (constantes : elles ne suivent PAS l'accent) ── */
:root[data-theme="light"] {
  --brand-google: #4285F4; --brand-linkedin: #0A66C2; --brand-instagram: #E4405F;
  --brand-facebook: #1877F2; --brand-x: #16181D; --brand-whatsapp: #25D366; --brand-birthday: #EC4899;
  --brand-discord: #5865F2; --brand-discord-online: #3BA55D;
}
:root[data-theme="dark"] {
  /* Versions éclaircies pour rester lisibles sur fond sombre. */
  --brand-google: #5E97F6; --brand-linkedin: #4A9CE0; --brand-instagram: #F76A8C;
  --brand-facebook: #4A8DF7; --brand-x: #E7E9EA; --brand-whatsapp: #3DDC7E; --brand-birthday: #F472B6;
  --brand-discord: #7A85FF; --brand-discord-online: #4ADE80;
}

/* ── Graphes ──
   Le violet est la série primaire. En nuit seulement, le cyan utilitaire sert
   de série secondaire afin de séparer les données sans multiplier les accents. */
:root[data-theme="light"] { --chart-primary: #7257D9; --chart-muted: #70707C; --chart-secondary: var(--chart-muted); }
:root[data-theme="dark"]  { --chart-primary: #9A86F5; --chart-muted: #92909C; --chart-secondary: #62C9D0; }

:root,
:root[data-theme="light"],
:root[data-theme="dark"] {
  /* Les clés métier restent dans les données ; ces jetons ne décrivent que la
     forme visuelle commune aux badges, progressions et tunnels. */
  --surface-3: var(--surface-hover);
  --state-followup-bg: var(--accent-soft);
  --state-followup-border: var(--accent);
  --state-active-bg: transparent;
  --state-active-border: var(--text);
  --state-planned-bg: var(--surface-3);
  --state-planned-border: var(--border-strong);
  --state-paused-bg: transparent;
  --state-paused-border: var(--text-muted);
  --state-closed-bg: var(--surface-2);
  --state-closed-border: var(--border);
  /* Le voile est défini par thème dans les deux blocs ci-dessus : il reste
     presque imperceptible en clair et légèrement plus dense en nuit. */
}

/* ════════════════════════════════════════════════════════════════════════
   COQUILLE — alias sémantiques (contrat V7 §5.3, unité U1, 2026-08-11)

   Le contrat V7 impose onze noms sémantiques pour que la coquille (barre
   globale, volet contextuel, barre haute, zone de travail) cesse de nommer
   des COULEURS et nomme des RÔLES. Sans eux, chaque règle de `shell.css`
   choisit elle-même son jeton de fond, et deux zones qui doivent différer
   finissent peintes avec le même `--surface` — c'est exactement le défaut
   « accumulation de panneaux gris bordés » que le §4.2 refuse.

   Ce bloc est une INDIRECTION PURE : chaque alias pointe sur le jeton que
   la coquille consomme DÉJÀ aujourd'hui. Le rendu est identique au pixel
   avant/après. Les VALEURS V7 (§5.1/§5.2) ne sont pas reprises ici : elles
   entrent en conflit frontal avec la palette épinglée par
   `tests/design_tokens_contract_test.js` (--accent #046C75, --accent-bright
   #028F9B) et attendent un arbitrage humain. Quand cet arbitrage tombera,
   il se fera EN UN SEUL POINT — ces onze lignes — et non dans les cent
   règles qui les consomment. C'est tout l'intérêt de la couche.

   Une seule déclaration couvre les deux thèmes : `var()` résout au moment
   de l'usage, donc l'alias suit automatiquement le bloc clair ou nuit.

   ESPACEMENTS — le §5.4 demande `--v7-space-1..8` = 4/8/12/16/20/24/32.
   L'échelle `--sp-1..8` ci-dessus porte déjà exactement ces valeurs. Le
   §5.3 tranche ce cas : « si le projet possède déjà un alias équivalent,
   le réutiliser au lieu de créer un doublon ». Aucun jeton d'espacement
   n'est donc ajouté.
   ════════════════════════════════════════════════════════════════════════ */
:root,
:root[data-theme="light"],
:root[data-theme="dark"] {
  /* Les trois fonds structurels. Ce sont les seuls qui DOIVENT différer :
     le châssis est plus sombre que le contenu, sinon rien ne distingue
     l'outil de la donnée. */
  --shell-bg: var(--shell);
  --shell-context-bg: var(--context);
  --shell-workspace-bg: var(--bg);
  /* Surface d'un élément posé DANS la coquille : rangée active, carte,
     infobulle du rail. */
  --shell-surface: var(--surface);
  --shell-text: var(--text);
  --shell-text-secondary: var(--text-secondary);
  --shell-text-muted: var(--text-muted);
  /* Une seule épaisseur de trait dans la coquille (§5.4 : 1px maximum). */
  --shell-line: var(--border);
  /* Deux registres distincts, à ne pas confondre : `action` peint ce sur
     quoi on CLIQUE (bouton primaire, lien actif) et doit tenir le ratio de
     contraste d'un texte ; `accent` est le trait de couture — un filet de
     2px qui ne porte jamais de texte, donc plus clair sans risque. */
  --shell-action: var(--accent);
  --shell-accent: var(--accent-bright);
  --shell-active-bg: var(--accent-soft);
}
