/* =============================================================================
   tokens.css
   Design tokens — source de vérité unique pour toute l'interface.
   RÈGLE : aucun autre fichier CSS ne définit de valeur brute.
           Tout passe par ces variables.
   ============================================================================= */

:root {

  /* ---------------------------------------------------------------------------
     COULEURS — Palette principale
  --------------------------------------------------------------------------- */

  /* Primary (Teal) */
  --color-primary:        #28C3A9;
  --color-primary-hover:  #20A892;
  --color-primary-dark:   #178A78;
  --color-primary-light:  #DDF8F3;
  --color-primary-subtle: #EBF9F6;

  /* Primary alpha — overlays, focus rings, hover tints.
     Règle : utiliser ces tokens, ne jamais écrire rgba(40,195,169,…) en dur. */
  /* Échelle alpha du teal. Elle était INCOMPLÈTE : quatre paliers manquaient et
     les feuilles les réécrivaient à la main (15 occurrences, neuf opacités).
     Complétée pour que tout passe par le thème. */
  --color-primary-alpha-02: rgba(40,195,169,0.02);  /* fond de ligne quasi imperceptible */
  --color-primary-alpha-04: rgba(40,195,169,0.04);  /* hover ligne tableau (très subtil) */
  --color-primary-alpha-06: rgba(40,195,169,0.06);  /* hover bouton per-page             */
  --color-primary-alpha-08: rgba(40,195,169,0.08);  /* hover ghost, combobox, back-link  */
  --color-primary-alpha-10: rgba(40,195,169,0.10);  /* focus ring — toolbar, filter      */
  --color-primary-alpha-12: rgba(40,195,169,0.12);  /* focus ring — card-toolbar, combo  */
  --color-primary-alpha-14: rgba(40,195,169,0.14);  /* élément actif du menu             */
  --color-primary-alpha-15: rgba(40,195,169,0.15);  /* survol d'un élément déjà actif    */
  --color-primary-alpha-20: rgba(40,195,169,0.20);  /* dot glow — stat-strip is-active   */
  --color-primary-alpha-30: rgba(40,195,169,0.30);  /* bordure d'un élément actif        */

  /* Surfaces & Backgrounds */
  --color-bg:             #F8FAFC;
  --color-surface:        #FFFFFF;
  --color-surface-raised: #FFFFFF;

  /* Textes */
  --color-text-main:      #1F2937;
  --color-text-muted:     #6B7280;
  --color-text-light:     #9CA3AF;
  /* Texte et icônes posés sur un fond PLEIN et coloré (bouton primaire, badge
     de statut, pastille du parcours, barre sombre…).
     Cette intention s'écrivait de DEUX façons dans le projet : ce token
     (10 usages) et un `#fff` en dur (23 usages) — avec deux valeurs
     différentes, #F8FAFC ici et le blanc pur là. Même défaut que les deux verts
     du rôle superadmin : une intention, deux sources, qui dérivent.
     Unifié sur le BLANC PUR, majoritaire et standard sur un aplat saturé. Les
     10 anciens usages gagnent 3 % de clarté — invisible à l'œil, mais il faut
     le dire plutôt que de le taire. */
  --color-text-inverse:   #FFFFFF;

  /* Bordures */
  --color-border:         #E5E7EB;
  --color-border-strong:  #D1D5DB;

  /* États sémantiques */
  --color-success:        #16A34A;
  --color-success-bg:     #F0FDF4;
  --color-success-border: #BBF7D0;
  --color-success-alpha-08: rgba(22, 163, 74, 0.08);

  --color-warning:        #F59E0B;
  --color-warning-bg:     #FFFBEB;
  --color-warning-border: #FDE68A;
  /* Ambre dense pour le PREMIER PLAN (texte/bord) : l'amber-500 ci-dessus est
     trop lumineux face au rouge/vert et paraît délavé sur fond blanc. */
  --color-warning-strong: #B45309;
  /* Ambre encore plus foncé, pour du TEXTE posé sur --color-warning-bg. Écrit
     en dur à plusieurs endroits (badge STOP OUT, avertissement d'identifiants
     techniques) avant d'exister comme token. */
  --color-warning-text:   #92400E;

  --color-danger:         #EF4444;
  --color-danger-hover:   #DC2626;
  --color-danger-bg:      #FEF2F2;
  --color-danger-border:  #FECACA;
  /* Rouge FONCÉ, pour du TEXTE — exact pendant de --color-warning-text, et il
     manquait pour la même raison. `--color-danger` est un ton d'APLAT : posé
     en texte sur --color-danger-bg il ne donne que 3,4:1 (mesuré), sous le
     plancher de 4,5:1. Celui-ci monte à 5,9:1 sur le même fond.
     ⚠ Il reste à porter là où le rouge sert de TEXTE et non d'aplat :
     `.text-danger`, `.form-error`, `.pf-error`, `.pf-label .req` sont encore
     en --color-danger sur fond blanc (3,8:1). À faire module par module,
     validé à l'œil — pas en bloc. */
  --color-danger-text:    #B91C1C;
  /* Voiles rouges — fond d'un champ, d'une ligne ou d'un bloc en erreur.
     La teinte s'écrivait en dur à six alphas différents dans cinq feuilles ;
     l'échelle se complète module par module, à mesure qu'ils passent. Restent
     à convertir : .04 (pipeline_specs), .12 (login). Le .15 de shell.css est
     converti. */
  --color-danger-alpha-03: rgba(239, 68, 68, 0.03);
  --color-danger-alpha-06: rgba(239, 68, 68, 0.06);
  --color-danger-alpha-08: rgba(239, 68, 68, 0.08);
  --color-danger-alpha-15: rgba(239, 68, 68, 0.15);

  --color-info:           #3B82F6;
  --color-info-bg:        #EFF6FF;
  --color-info-border:    #BFDBFE;
  --color-info-alpha-08:  rgba(59, 130, 246, 0.08);

  /* Sidebar */
  --color-sidebar-bg:     #1F2937;
  --color-sidebar-text:   #D1D5DB;
  --color-sidebar-text-active: #FFFFFF;
  /* États de la barre latérale — REMPLISSAGES NEUTRES, ACCENT TEAL.
     Ils étaient des voiles TEAL posés sur le chrome (`--color-primary-alpha-*`).
     Tant que le chrome était bleu-nuit partout, ça passait ; teinté (brun en
     dev, indigo en préprod) le voile teal vire à l'olive. Un blanc translucide,
     lui, éclaircit le chrome QUEL QU'IL SOIT — et le teal reste là où il se
     lit vraiment : le texte actif et la barre de 3px. */
  --color-sidebar-item-hover:  rgba(255,255,255,0.07);
  --color-sidebar-item-active: rgba(255,255,255,0.10);
  --color-sidebar-item-active-border: var(--color-primary);
  /* Accent du chrome — la couleur du TEXTE mis en avant sur la barre : libellé
     du menu actif, rôle, code de l'organisation, glyphe de l'icône, anneau de
     focus. Ces usages lisaient `--color-primary` EN DIRECT, donc un
     environnement ne pouvait pas les changer sans repeindre aussi le logo et
     les avatars, qui sont des aplats teal et doivent le rester.
     Séparer les deux permet à un chrome clair (ambre, jaune) de basculer son
     accent en sombre — sur #F59E0B le teal tombe à 1,03:1, soit invisible. */
  --color-chrome-accent: var(--color-primary);
  --color-sidebar-fill:        rgba(255,255,255,0.06);
  --color-sidebar-fill-border: rgba(255,255,255,0.12);
  --color-sidebar-fill-hover:  rgba(255,255,255,0.12);
  --color-sidebar-fill-hover-border: rgba(255,255,255,0.22);
  --color-sidebar-border:  rgba(255,255,255,0.06);

  /* ── ENCRES DU CHROME ────────────────────────────────────────────────────
     Textes et voiles posés sur la barre latérale et le bandeau. Ils étaient
     ÉCRITS EN DUR dans shell.css : 23 occurrences, NEUF opacités différentes
     pour trois ou quatre intentions — et le token `--color-sidebar-text`
     existait sans que rien ne l'utilise. C'est ce qui a fait échouer l'essai
     de chrome clair : basculer le token ne changeait rien, la valeur vivait
     ailleurs.
     Les valeurs sont reprises À L'IDENTIQUE : aucun pixel ne bouge, mais elles
     ont désormais UNE source. Le nommage suit celui de `--color-primary-alpha-*`
     déjà en place.
     ⚠ Les paliers 30/35/40/45 disent tous « texte secondaire » à quatre
     nuances près. Les fondre changerait le rendu : à traiter comme un
     arbitrage visuel, pas dans ce passage. */
  --color-chrome-alpha-90: rgba(255,255,255,0.90);  /* texte au survol, nom user */
  --color-chrome-alpha-70: rgba(255,255,255,0.70);  /* icône burger              */
  --color-chrome-alpha-60: rgba(255,255,255,0.60);  /* texte de menu au repos    */
  --color-chrome-alpha-45: rgba(255,255,255,0.45);  /* sous-titres               */
  --color-chrome-alpha-40: rgba(255,255,255,0.40);  /* déconnexion, code absent  */
  --color-chrome-alpha-35: rgba(255,255,255,0.35);  /* catégorie de rôle         */
  --color-chrome-alpha-30: rgba(255,255,255,0.30);  /* mention multi-org, vide   */
  --color-chrome-veil-08:  rgba(255,255,255,0.08);  /* survol d'un bouton        */
  --color-chrome-veil-04:  rgba(255,255,255,0.04);  /* fond d'un état vide       */
  /* --color-chrome-ring SUPPRIMÉ. Il cerclait les pastilles de comptage de la
     cloche avec un bleu-nuit quasi noir écrit en dur — `rgba(15,23,42,0.90)` —
     que AUCUN environnement ne redéfinissait. L'anneau doit valoir la couleur du
     bandeau pour ne pas se voir ; `.topbar__badge` consomme donc directement
     --color-topbar-bg (shell.css).

     ⚠ POURQUOI PAS UN TOKEN `--color-chrome-ring: var(--color-topbar-bg)` ICI.
     Un `var()` dans une propriété personnalisée est résolu sur l'élément qui la
     DÉCLARE. Déclaré sur `:root`, il aurait figé la valeur de prod (#1F2937) et
     ignoré les surcharges par stack, qui vivent sur `body[data-env=…]` : le
     violet du DEV serait resté cerclé de bleu-nuit. Consommer le token au point
     d'usage, dans un sélecteur situé sous `body`, est la seule écriture qui
     suive la teinte. */

  /* ── PASTILLES D'ENVIRONNEMENT ───────────────────────────────────────────
     Elles étaient écrites en dur (quatre hex + quatre rgba) et bâties à
     l'envers : fond = 20 % de leur propre couleur, texte = cette MÊME couleur.
     Une couleur sur un lavis d'elle-même ne peut pas contraster. Ça passait
     tant que le chrome était bleu-nuit partout ; sur le gris de la préprod la
     pastille tombait à 2,03:1 — illisible.
     Elles deviennent PLEINES : la couleur en fond, du blanc par-dessus. Les
     tons sont assez denses pour que le blanc tienne (mesuré ≥ 5:1), et la
     pastille se détache désormais sur N'IMPORTE QUEL chrome. */
  /* ALIGNÉES SUR LE CHROME (2026-09-03). Chaque environnement avait DEUX
     couleurs : un chrome (aubergine en dev, gris en préprod, navy en prod) et
     une pastille sans rapport (ambre, violet, vert). Deux langages qui se
     contredisaient pour dire la même chose.
     La pastille reprend donc la TEINTE de son chrome, à une clarté plus haute
     (~42 %) — assez sombre pour porter du texte blanc, assez claire pour se
     lire sur le fond clair de la page de connexion.
     ⚠ Elle ne peut PAS se détacher de son chrome par la seule teinte : à teinte
     égale le contraste plafonne à 2,4:1. D'où le liseré clair de `.env-badge`,
     qui fait le travail que la couleur ne peut plus faire. */
  --color-env-dev:     #833B9B;   /* aubergine claire — blanc à 6,85:1 */
  --color-env-test:    #1D4ED8;   /* bleu dense (pas de chrome dédié)   */
  --color-env-preprod: #757575;   /* gris clair       — blanc à 4,61:1 */
  --color-env-prod:    #3061A6;   /* navy clair       — blanc à 6,20:1 */

  /* ── VITRINE DE LA PAGE DE CONNEXION ─────────────────────────────────────
     Le panneau de gauche (logo, accroche, chiffres) lisait
     `--color-sidebar-bg` — un EMPRUNT de commodité, pas une intention. Résultat :
     dès que le chrome s'est teinté par environnement, la vitrine a suivi sans
     que personne ne l'ait décidé.
     DÉCISION (Dany, 2026-09-03) : la vitrine garde le navy PARTOUT. C'est la
     face du produit au moment où on le présente ; l'environnement n'a pas à la
     manger. Elle a donc sa propre valeur, et le chrome peut bouger sans elle.
     ⚠ Une teinte ne NOMME rien : cet écran n'a aujourd'hui aucun signal
     d'environnement (ni pastille, ni mention). Si on veut le dire ici, c'est la
     pastille qu'il faut poser — pas la couleur. */
  --color-login-brand-bg: #1F2937;

  /* Topbar */
  --color-topbar-bg:      #1F2937;
  --color-topbar-text:    #F8FAFC;
  --color-topbar-border:  rgba(255,255,255,0.08);
}

/* ---------------------------------------------------------------------------
   CHROME PAR ENVIRONNEMENT

   La barre latérale et le bandeau se teintent selon la stack, pour qu'on ne
   puisse pas confondre l'endroit où l'on agit. Jusqu'ici seule une pastille
   distinguait la prod de la dev — peu, pour ce que ça protège.

   La PROD garde le bleu-nuit ci-dessus, volontairement : c'est l'état normal,
   l'écran qu'on regarde le plus souvent, et il ne doit pas crier. Ce sont les
   AUTRES environnements qui signalent qu'on n'y est pas.

   Seule la TEINTE change : `#1F2937` vaut hsl(215, 28%, 17%), et les variantes
   gardent cette clarté. Le contraste du texte blanc est donc identique partout,
   et les trois chromes appartiennent visiblement à la même application.

   On redéfinit les TOKENS, pas les composants : tout ce qui s'y adosse suit
   sans qu'on ait à énumérer quoi que ce soit (`.sidebar`, `.topbar`, et la
   page de connexion qui réutilise `--color-sidebar-bg`).
--------------------------------------------------------------------------- */

/* LES TROIS CHROMES — tranchés à l'écran avec Dany, le 2026-09-03.

   PROD ...... `#1F2937` navy. INCHANGÉ, et sans bloc : la prod hérite du :root.
               C'est l'état normal, l'écran qu'on regarde le plus — il ne doit
               pas crier. Ce sont les autres qui signalent qu'on n'y est pas.
   PRÉPROD ... `#424242` gris neutre — le plus distinct de la prod, y compris
               en niveaux de gris et en vision daltonienne. C'est la paire
               qu'on peut réellement confondre (même domaine, toutes deux à
               distance).
   DEV ....... `#392640` aubergine. Locale : déjà distinguée par l'URL.

   ── Ce que le chemin a appris, et qui vaut pour la suite ──────────────────

   · Les essais CLAIRS (gris clair #E9EBEE, ambre, jaune, orange vif) imposent
     tous de RENVERSER les encres : les textes du chrome sont des blancs
     translucides, et sur fond clair ils tombent sous le plancher de 4,5:1.
     Mesuré : blanc 60 % sur #C2410C → 2,80:1 ; sur #F9C56D → 1,6:1.
   · Un chrome clair tue aussi l'ACCENT TEAL : 1,03:1 sur l'ambre, invisible.
     D'où `--color-chrome-accent`, qui sépare le teal des TEXTES mis en avant
     (libellé actif, rôle, code d'organisation) du teal des APLATS (logo,
     avatars) — les seconds gardent l'identité, les premiers peuvent basculer.
   · Le NOIR PUR a été essayé : « c'est beau mais ça fait mal aux yeux ».
     Contraste maximal = halation. Aucune interface sombre ne descend à #000.
   · Rien de tout cela n'était réglable AVANT que les valeurs du chrome ne
     deviennent des tokens : elles étaient écrites en dur dans shell.css,
     23 occurrences sur neuf opacités, et le token `--color-sidebar-text`
     existait sans que rien ne l'utilise.

   Les trois se distinguent par la TEINTE autant que par la profondeur :
   215° navy · neutre · 285° aubergine, à 17 %, 26 % et 20 % de clarté.

   Contrastes du texte de menu (blanc 60 %) : prod 6,22:1 · préprod 4,79:1 ·
   dev 5,96:1. Tous au-dessus du plancher. L'accent teal, lui, se lit à 6,21:1
   sur l'aubergine — mieux que sur le bleu éclairci (4,81:1).
--------------------------------------------------------------------------- */

/* POURQUOI CE JEU-LÀ — arbitré sur mesure ET sur le modèle de risque.

   Mesuré en niveaux de gris et en vision deutéranope (≈5 % des hommes), une
   paire est forcément faible : les trois chromes sont sombres, désaturés et
   tiennent dans 9 points de clarté. Le gris est le SEUL vraiment loin du navy.

       navy ↔ gris       N&B 39,8
       navy ↔ aubergine  N&B  6,9   ← quasi identiques hors couleur

   L'environnement qui porte le gris est donc le seul protégé. Il va à la
   PRÉPROD, et la raison n'est pas esthétique : ce sont prod et préprod qu'on
   peut RÉELLEMENT confondre — même domaine à un sous-domaine près, toutes deux
   à distance, toutes deux avec des données crédibles. La dev, elle, est locale :
   la barre d'adresse la distingue déjà.

   ⚠ Ce que la couleur ne fera jamais : survivre au gris, au daltonisme et à la
   vision périphérique en même temps. Pour un vrai second canal, il faudrait un
   ÉCART DE CLARTÉ franc (donc un environnement clair, encres inversées) ou un
   bandeau portant le NOM écrit — modèle Stripe. */

/* DEV — aubergine : hsl(285, 25%, 20%). */
body[data-env="dev"] {
  --color-sidebar-bg: #392640;
  --color-topbar-bg:  #392640;
}

/* PRÉPROD — gris neutre : hsl(0, 0%, 26%). Le plus distinct de la prod. */
body[data-env="preprod"] {
  --color-sidebar-bg: #424242;
  --color-topbar-bg:  #424242;
}

:root {

  /* ---------------------------------------------------------------------------
     TYPOGRAPHIE
  --------------------------------------------------------------------------- */

  --font-sans:   'DM Sans', system-ui, -apple-system, sans-serif;
  --font-mono:   'JetBrains Mono', 'Fira Code', monospace;

  --text-2xs:    0.625rem;   /* 10px — thead, labels compacts */
  --text-xs:     0.75rem;    /* 12px */
  --text-sm:     0.875rem;   /* 14px */
  --text-base:   1rem;       /* 16px */
  --text-md:     1.0625rem;  /* 17px */
  --text-lg:     1.125rem;   /* 18px */
  --text-xl:     1.25rem;    /* 20px — valeurs KPI, stat-strip */
  --text-2xl:    1.5rem;     /* 24px — valeurs KPI card */
  --text-3xl:    1.875rem;   /* 30px */

  /* Hors-échelle — usage restreint aux tableaux compacts uniquement */
  --text-compact: 0.65625rem; /* 10.5px — data-table--compact th */

  --font-normal:  400;
  --font-medium:  500;
  --font-semi:    600;
  --font-bold:    700;

  --leading-tight:  1.25;
  --leading-normal: 1.5;
  --leading-loose:  1.75;

  /* ---------------------------------------------------------------------------
     ESPACEMENT — Échelle de 4px
  --------------------------------------------------------------------------- */

  --space-1:   0.25rem;   /* 4px  */
  --space-2:   0.5rem;    /* 8px  */
  --space-3:   0.75rem;   /* 12px */
  --space-4:   1rem;      /* 16px */
  --space-5:   1.25rem;   /* 20px */
  --space-6:   1.5rem;    /* 24px */
  --space-8:   2rem;      /* 32px */
  --space-10:  2.5rem;    /* 40px */
  --space-12:  3rem;      /* 48px */
  --space-16:  4rem;      /* 64px */

  /* ---------------------------------------------------------------------------
     DIMENSIONS — Layout
  --------------------------------------------------------------------------- */

  --sidebar-width:         240px;
  --sidebar-collapsed:     64px;
  --topbar-height:         56px;

  /* Padding HORIZONTAL des cellules de tableau — SOURCE UNIQUE.
     Consommé par .data-table/.file-table th et td ; l'ajustement responsive
     vit dans components.css, au contact des règles concernées (même motif que
     --sidebar-width, déclaré ici et redéfini dans shell.css).

     Pourquoi ce token existe. 16px de chaque côté sur 10 colonnes = 320px, soit
     près d'un tiers de la largeur d'une liste dépensé en air. Tant que la place
     ne manque pas, c'est du confort de lecture et on le garde. Dès qu'elle
     manque, c'est la première chose à rendre — avant de tronquer une donnée ou
     de masquer une colonne, qui retirent l'une et l'autre de l'information. */
  --table-cell-pad-x:      var(--space-4);   /* 16px */
  /* Largeurs de page canoniques — SOURCE UNIQUE des valeurs.
     Appliquées via les wrappers de components.css, JAMAIS en px dans une page.

       0. Liste large : --page-width-wide    → .page-layout        (tables denses)
       2. Formulaire  : --page-width-form    → .pf-form-page       (saisie centrée)
                                             → .page-layout--form  (liste étroite)
       3. Compact     : --page-width-compact → .pf-form-page--compact (tertiaire)

     Palier 0 : plafond HAUT + CENTRAGE. Calibré pour que 1920 reste inchangé
     (largeur utile = 1920 − 240 sidebar − 40 padding = 1640) et que seuls les
     2560+ soient bornés. Une table à 10 colonnes y garde 160px par colonne ;
     à 1280 elle n'en aurait que 128, or une cellule `d/m/Y H:i` en mono avec son
     padding en réclame ~130 et `white-space:nowrap` interdit le repli.

     ⚠ --content-max-width (1280) n'a AUCUN consommateur depuis que .page-layout
     est passé au palier 0. Il est conservé le temps de l'arbitrage « 1600 partout
     VS 1280 par défaut + modificateur --wide sur les 6 écrans à 9-10 colonnes ».
     Si l'arbitrage retient 1600 partout, le SUPPRIMER — un token déclaré que rien
     ne consomme est un mensonge, et c'est ce qui a rendu l'audit de largeur si
     confus (le CSS annonçait un palier Liste que plus aucune règle n'appliquait). */
  --page-width-wide:       1600px;
  --content-max-width:     1280px;   /* cf. ⚠ ci-dessus — actuellement inutilisé */
  --page-width-form:       1100px;
  --page-width-compact:     900px;

  /* ---------------------------------------------------------------------------
     CHAMPS DE FORMULAIRE — Hauteurs canoniques
     Règle : 3 tailles, pas plus. Chaque contexte utilise UNE taille.
       --input-sm  → filtres, toolbars, tableaux compacts (28px)
       --input-md  → formulaires standards, modales (34px)
       --input-lg  → login, formulaires hero (40px)
  --------------------------------------------------------------------------- */

  --input-height-sm:  28px;
  --input-height-md:  34px;
  --input-height-lg:  40px;

  /* ---------------------------------------------------------------------------
     BORDURES & RAYONS
  --------------------------------------------------------------------------- */

  --radius-sm:   4px;
  --radius-md:   6px;
  --radius-lg:   8px;
  --radius-xl:   12px;
  --radius-2xl:  16px;
  --radius-full: 9999px;

  --border-width:    1px;
  --border-width-md: 1.5px;  /* bordures card, sections dépliables, pill */

  /* ---------------------------------------------------------------------------
     OMBRES
  --------------------------------------------------------------------------- */

  --shadow-xs:   0 1px 2px rgba(0,0,0,0.05);
  --shadow-sm:   0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.04);
  --shadow-md:   0 4px 6px rgba(0,0,0,0.06), 0 2px 4px rgba(0,0,0,0.04);
  --shadow-lg:   0 10px 15px rgba(0,0,0,0.08), 0 4px 6px rgba(0,0,0,0.04);
  --shadow-xl:   0 20px 25px rgba(0,0,0,0.08), 0 8px 10px rgba(0,0,0,0.04);
  --shadow-card: 0 10px 8px rgba(0,0,0,0.07); /* cards dépliables : pf-section, pd-card, filter-panel */

  /* ---------------------------------------------------------------------------
     TRANSITIONS
  --------------------------------------------------------------------------- */

  --transition-fast:   150ms ease;
  --transition-normal: 200ms ease;
  --transition-slow:   300ms ease;

  /* ---------------------------------------------------------------------------
     Z-INDEX — Hiérarchie des couches
  --------------------------------------------------------------------------- */

  --z-base:     0;
  --z-raised:   10;
  --z-dropdown: 100;
  --z-sticky:   200;
  --z-sidebar:  300;
  --z-topbar:   400;
  --z-modal:    500;
  --z-toast:    600;
  --z-tooltip:  700;

  /* ---------------------------------------------------------------------------
     BADGES / STATUS — tokens sémantiques
  --------------------------------------------------------------------------- */

  --status-ok-color:       var(--color-success);
  --status-ok-bg:          var(--color-success-bg);
  --status-ok-border:      var(--color-success-border);

  --status-ko-color:       var(--color-danger);
  --status-ko-bg:          var(--color-danger-bg);
  --status-ko-border:      var(--color-danger-border);

  --status-warn-color:     var(--color-warning);
  --status-warn-bg:        var(--color-warning-bg);
  --status-warn-border:    var(--color-warning-border);

  --status-skip-color:     var(--color-text-muted);
  --status-skip-bg:        #F3F4F6;
  --status-skip-border:    var(--color-border);

  --status-pending-color:  var(--color-info);
  --status-pending-bg:     var(--color-info-bg);
  --status-pending-border: var(--color-info-border);

  /* MD mode (manuel/bloqué) — violet */
  --color-md:        #6d28d9;
  --color-md-border: #ddd6fe;
  --color-md-bg:     #ede9fe;
  --color-md-hover:  #d8b4fe;

  /* ---------------------------------------------------------------------------
     FILTRES — tokens pour les panneaux de filtres compacts
     Consommés par : .filter-panel, .combobox (contexte filtre)
     Règle : ces tokens définissent la taille et l'espacement des champs
             dans les panneaux filtres. Les formulaires standards
             continuent d'utiliser --input-height-md / --input-height-lg.
  --------------------------------------------------------------------------- */

  --filter-field-height:    28px;
  --filter-label-size:      var(--text-2xs);           /* 10px */
  --filter-label-color:     #4B5563;                   /* gray-600 — plus foncé que muted */
  --filter-label-weight:    var(--font-medium);
  --filter-ctrl-size:       var(--text-xs);            /* 12px */
  --filter-ctrl-color:      var(--color-text-muted);
  --filter-ctrl-border:     var(--color-text-muted);   /* #6B7280 — même couleur que le label */
  --filter-placeholder:     var(--color-text-light);   /* #9CA3AF — placeholder unifié (input, select vide, combobox) */
  --filter-col-title-size:  var(--text-xs);            /* 12px */
  --filter-col-title-color: var(--color-text-main);
  --filter-gap-field:       var(--space-1);            /* 4px — label ↔ ctrl */
  --filter-gap-grid:        var(--space-1) var(--space-2);  /* 4px 8px — grille label+ctrl */
  --filter-col-padding:     10px 14px;

  /* CATEGORIES REFERENTIELS */
  --cat-transco:            #178A78;
  --cat-transco-bg:         #EBF9F6;
  --cat-transco-border:     #B2ECE1;
  --cat-transco-subtle:     #DDF8F3;
  --cat-articles:           #6D28D9;
  --cat-articles-bg:        #EDE9FE;
  --cat-articles-border:    #DDD6FE;
  --cat-articles-subtle:    #E8E0FE;
  --cat-commercial:         #92400E;
  --cat-commercial-bg:      #FFFBEB;
  --cat-commercial-border:  #FDE68A;
  --cat-commercial-subtle:  #FEF3C7;
  /* Documents — ces 4 tokens étaient CONSOMMÉS 7 fois par referentiels.css sans
     avoir jamais été déclarés. Une var() non déclarée sans repli rend toute la
     déclaration invalide : le badge « Type document » sortait donc transparent,
     bordure currentColor, et la tuile du wizard sans fond d'icône. Teinte bleue,
     seule famille libre face au teal (transco), au violet (articles) et à
     l'ambre (commercial) ; alignée sur --color-info-*. */
  --cat-documents:          #1E40AF;
  --cat-documents-bg:       #EFF6FF;
  --cat-documents-border:   #BFDBFE;
  --cat-documents-subtle:   #DBEAFE;

  /* ---------------------------------------------------------------------------
     RÔLES — un token par RÔLE, jamais une valeur partagée réutilisée
     Un rôle se montre à DEUX endroits sur la même ligne : la pastille des
     initiales et l'étiquette du rôle. Les deux étaient peintes à la main, dans
     deux blocs distincts de tenancy.css — et avaient déjà divergé : superadmin
     sortait en #085041 sur la pastille et #0F6E56 sur l'étiquette. Deux verts
     proches, côte à côte, pour un même rôle.
     Retenu : #085041, le plus sombre. C'est celui qui s'accorde au reste de la
     famille (owner, admin et analyste ont tous un texte foncé) et qui contraste
     le mieux sur son fond pâle ; #0F6E56 était l'exception.
     Un token par rôle même quand deux rôles partagent une teinte : ajuster
     « analyste » ne doit pas déplacer une catégorie de référentiel qui se
     trouve avoir le même ambre.
  --------------------------------------------------------------------------- */
  --role-owner-bg:          #EEEDFE;
  --role-owner-text:        #3C3489;
  --role-superadmin-bg:     #E1F5EE;
  --role-superadmin-text:   #085041;
  --role-admin-bg:          #DBEAFE;
  --role-admin-text:        #1E40AF;
  --role-analyste-bg:       #FEF3C7;
  --role-analyste-text:     #92400E;
  /* Opérateur et lecteur restent neutres — délibérément : ce sont les rôles
     sans pouvoir, et la couleur ici SIGNALE l'étendue des droits. */
  --role-operator-bg:       var(--color-bg);
  --role-operator-text:     var(--color-text-muted);
  --role-viewer-bg:         var(--color-bg);
  --role-viewer-text:       var(--color-text-light);

  /* ---------------------------------------------------------------------------
     DRAPEAUX DE BLOCAGE — badges STOP OUT / STOP IN (liste des partenaires)
     Un token par DRAPEAU : ce sont deux signaux distincts (livraison bloquée /
     réception bloquée) et rien ne dit qu'ils resteront de la même famille.
     Valeurs reprises À L'IDENTIQUE, la tokenisation ne change pas le rendu —
     elle rend seulement ces deux badges pilotables depuis le thème, ce qu'ils
     n'étaient pas : le violet de STOP IN était écrit entièrement à la main et
     ne bougeait donc pas d'un pouce si l'on changeait la palette.
  --------------------------------------------------------------------------- */
  --flag-stop-out-bg:       var(--color-warning-bg);
  --flag-stop-out-text:     var(--color-warning-text);
  --flag-stop-out-border:   var(--color-warning-border);
  /* ---------------------------------------------------------------------------
     PROTOCOLES DE TRANSPORT — badges de la table des runs (tableau de bord)
     Un token par PROTOCOLE. Ce sont les seuls badges de protocole RÉELLEMENT
     affichés de l'application : deux autres palettes concurrentes existaient
     dans components.css et pages/projects.css, pour des variantes qu'aucun
     gabarit ne composait — elles ont été supprimées. Celles-ci sont donc la
     référence, et les valeurs sont reprises à l'identique.
  --------------------------------------------------------------------------- */
  --proto-sftp-bg:          #DBEAFE;
  --proto-sftp-text:        #1E40AF;
  --proto-ftp-bg:           #E0E7FF;
  --proto-ftp-text:         #3730A3;
  --proto-as2-bg:           #DDF8F3;
  --proto-as2-text:         #178A78;
  --proto-email-bg:         #FEF3C7;
  --proto-email-text:       #B45309;
  --proto-x400-bg:          #EDE9FE;
  --proto-x400-text:        #6D28D9;
  --proto-api-bg:           #FCE7F3;
  --proto-api-text:         #9D174D;
  --proto-local-bg:         #F3F4F6;
  --proto-local-text:       #6B7280;

  /* ---------------------------------------------------------------------------
     SENS DU FLUX — ENTRANT / SORTANT
     Une seule source pour toute l'application : badges IN/OUT des Fichiers,
     pastilles d'icône de la bande de statistiques de l'accueil, et ce qui
     viendra. Deux vocabulaires coexistaient — bleu/violet sur l'accueil,
     teal/teal dans les Fichiers, où les deux directions étaient si proches
     qu'on ne les distinguait plus. Arbitré : ENTRANT teal, SORTANT bleu.

     Le bleu du sortant n'est pas une invention : deux tokens `--badge-out-*`
     le déclaraient déjà dans pages/files.css… sans que rien ne les consomme.
     Même défaut que `--badge-in-*` avant lui — déclaré, oublié, et le badge
     peint à côté.
  --------------------------------------------------------------------------- */
  --direction-in:           var(--color-primary-dark);
  --direction-in-bg:        var(--color-primary-light);
  --direction-in-border:    var(--color-primary);
  --direction-in-tint:      var(--color-primary-alpha-08);
  --direction-out:          var(--color-info);
  --direction-out-bg:       var(--color-info-bg);
  --direction-out-border:   var(--color-info-border);
  --direction-out-tint:     var(--color-info-alpha-08);

  --flag-stop-in-bg:        #FDF4FF;
  --flag-stop-in-text:      #6B21A8;
  --flag-stop-in-border:    #E9D5FF;

  /* ---------------------------------------------------------------------------
     APERÇU DE FICHIER — surface de code et coloration syntaxique
     Consommés par pages/flows.css (tiroir d'aperçu IN/OUT). Ces valeurs étaient
     en dur ; elles sont reprises À L'IDENTIQUE, la tokenisation ne change rien
     au rendu — elle rend seulement la palette pilotable d'un seul endroit.
  --------------------------------------------------------------------------- */

  /* Voile d'arrière-plan des surfaces modales (modale, tiroir d'aperçu…).
     Il en existait TROIS variantes pour le même geste : rgba(0,0,0,.4) sur la
     modale canonique, rgba(0,0,0,.38) sur le tiroir Monitoring et
     rgba(15,23,42,.45) sur la modale de recherche en masse. La valeur retenue
     est celle du composant canonique, donc `.modal-overlay` ne bouge pas. */
  --color-overlay:          rgba(0, 0, 0, 0.4);

  /* Surface. Noir pur assumé : sur du contenu brut (EDIFACT, largeurs fixes),
     le contraste maximal aide à distinguer les caractères. C'est le seul
     endroit du produit qui ne suit pas --color-text-main (#1F2937) — à
     rediscuter si l'on veut adoucir ces grandes surfaces de mono. */
  /* Texte posé sur une surface SOMBRE (bloc <pre>, éditeur de spec, résultat de
     bundle). Écrit en dur sept fois, dans quatre feuilles, toujours la même
     valeur — un gris très clair, volontairement pas le blanc pur : sur un fond
     presque noir, le blanc pur vibre. */
  --color-text-on-dark:     #E5E7EB;
  --color-code-text:        #000000;
  --color-code-focus-bg:    #FFFEF7;   /* crème discret — champ d'édition actif */
  --color-code-hover-bg:    #F5F5F5;   /* survol d'un document replié          */
  --color-code-inline-bg:   rgba(0,0,0,0.04); /* <code> au fil du texte         */

  /* Coloration syntaxique — six teintes distinguables.
     Un token par RÔLE, même quand deux rôles partagent aujourd'hui la même
     valeur (tag/number en ambre, value/key en bleu) : ajuster la couleur des
     nombres JSON ne doit pas déplacer celle des balises XML. */
  --color-syntax-keyword:   #7C3AED;   /* EDI segments de contrôle · JSON true/false/null */
  --color-syntax-envelope:  #2563EB;   /* EDI enveloppe (UNB/UNZ)                        */
  --color-syntax-string:    #16A34A;   /* EDI références · JSON chaînes                  */
  --color-syntax-party:     #C2410C;   /* EDI NAD (parties, adresses)                    */
  --color-syntax-tag:       #B45309;   /* XML balises                                    */
  --color-syntax-number:    #B45309;   /* JSON nombres                                   */
  --color-syntax-value:     #1D4ED8;   /* XML valeurs d'attribut                         */
  --color-syntax-key:       #1D4ED8;   /* JSON clés                                      */

  /* ---------------------------------------------------------------------------
     ÉDITEUR DE SPEC — surface sombre
     La visionneuse (fiche d'une spec) et l'éditeur (formulaire) montrent le
     MÊME JSON sur deux fonds DIFFÉRENTS : la visionneuse empruntait
     `--color-text-main` (#1F2937 — la couleur du TEXTE de l'application) comme
     fond, l'éditeur peignait #1A1F2E à côté. Une surface, une source.
  --------------------------------------------------------------------------- */
  --editor-bg:              #1A1F2E;
  --editor-gutter-text:     #6B7280;   /* numéros de ligne — retrait assumé   */
  --editor-gutter-border:   #374151;   /* filet entre gouttière et code       */
  --editor-selection:       rgba(56, 189, 248, 0.25);

  /* Coloration syntaxique JSON sur fond SOMBRE. Mêmes RÔLES que
     `--color-syntax-*` ci-dessus (qui vaut pour les fonds clairs), valeurs
     éclaircies pour rester lisibles sur l'éditeur. Deux palettes, un seul
     vocabulaire — jusqu'ici la seconde n'était déclarée nulle part. */
  --color-syntax-dark-key:     #34D399;
  --color-syntax-dark-string:  #FB923C;
  --color-syntax-dark-number:  #93C5FD;
  --color-syntax-dark-bool:    #C084FC;
  --color-syntax-dark-null:    #6B7280;
  --color-syntax-dark-punct:   #9CA3AF;
  --color-syntax-dark-comment: #6B7280;

  /* ---------------------------------------------------------------------------
     ÉTAPES DU PIPELINE — couleur par famille de spec
     Une famille d'étape = une couleur. Ce langage existait déjà, mais il
     SQUATTAIT les badges de sens (`badge-success`, `badge-warn`, `badge-info`,
     `badge-muted`, `badge-primary`), qu'il repeignait au passage. Conséquence
     visible : sur l'historique d'une spec, un badge vert voulait dire « Active »
     sur une ligne et « Transco » sur le titre — et « Inactive » portait la
     couleur de l'étape Syntaxe. Les étapes ont désormais leurs propres noms.
  --------------------------------------------------------------------------- */
  --step-identification-bg:     #CCFBF1;
  --step-identification-text:   #0F766E;
  --step-identification-border: #99F6E4;
  --step-syntaxe-bg:            #F1F5F9;
  --step-syntaxe-text:          #475569;
  --step-syntaxe-border:        #E2E8F0;
  --step-contrat-in-bg:         #DBEAFE;
  --step-contrat-in-text:       #1E40AF;
  --step-contrat-in-border:     #BFDBFE;
  --step-regles-bg:             #FEF3C7;
  --step-regles-text:           #92400E;
  --step-regles-border:         #FDE68A;
  --step-transco-bg:            #D1FAE5;
  --step-transco-text:          #065F46;
  --step-transco-border:        #A7F3D0;
  --step-mapping-bg:            #FCE7F3;
  --step-mapping-text:          #9D174D;
  --step-mapping-border:        #FBCFE8;
  --step-render-bg:             #E0E7FF;
  --step-render-text:           #3730A3;
  --step-render-border:         #C7D2FE;

  /* ---------------------------------------------------------------------------
     ROUTAGE SANS PIPELINE — badges REDIRECT / FORWARD de la liste des specs.
     Deux ardoises, du plus clair (brut, non transformé) au plus soutenu.
  --------------------------------------------------------------------------- */
  --route-redirect-bg:      #F1F5F9;
  --route-redirect-text:    #1F2937;
  --route-forward-bg:       #CBD5E1;
  --route-forward-text:     #0F172A;

  /* Palier intermédiaire de la barre de complétude : entre l'ambre (incomplet)
     et le vert (complet), le « presque fini ». Aucune couleur sémantique ne
     l'exprimait. */
  --color-completeness-near: #84CC16;

  /* ---------------------------------------------------------------------------
     MOTEURS DE FORMAT — badge IN → OUT d'un pipeline.
     Le modèle en déclare HUIT ; cinq seulement étaient peints. IDoc, X12 et
     Tradacoms retombaient sur le gris neutre : un pipeline IDoc → X12
     affichait deux badges identiques, impossibles à distinguer d'un coup d'œil.
     Complété, et sorti des feuilles où il s'écrivait en dur.
  --------------------------------------------------------------------------- */
  --engine-csv-bg:          #D1FAE5;
  --engine-csv-text:        #065F46;
  --engine-csv-border:      #A7F3D0;
  --engine-fixed-bg:        #FEF3C7;
  --engine-fixed-text:      #92400E;
  --engine-fixed-border:    #FDE68A;
  --engine-edifact-bg:      #DBEAFE;
  --engine-edifact-text:    #1E40AF;
  --engine-edifact-border:  #BFDBFE;
  --engine-xml-bg:          #EDE9FE;
  --engine-xml-text:        #6D28D9;
  --engine-xml-border:      #DDD6FE;
  --engine-idoc-bg:         #FFE4E6;
  --engine-idoc-text:       #9F1239;
  --engine-idoc-border:     #FECDD3;
  --engine-x12-bg:          #E0F2FE;
  --engine-x12-text:        #075985;
  --engine-x12-border:      #BAE6FD;
  --engine-tradacoms-bg:    #FAE8FF;
  --engine-tradacoms-text:  #86198F;
  --engine-tradacoms-border:#F5D0FE;
  /* JSON garde le teal de la marque — il sert aussi de type de valeur en
     transcodification, hors du contexte « moteur ». */
}