/* ============================================================================
   ALESIA · DESIGN TOKENS — source unique de vérité
   ----------------------------------------------------------------------------
   Extrait de ui-kit.html + va_control_plane.html (blocs :root identiques).
   Les noms historiques (--bg, --tx, --accent…) sont CONSERVÉS À L'IDENTIQUE :
   les deux maquettes d'origine restent compatibles sans modification.
   Ce qui est AJOUTÉ ici, ce sont les échelles qui étaient improvisées dans
   les maquettes (typo, espace, durées, z-index) — désormais nommées.

   Règle : aucune valeur brute (#hex, px de couleur, ms) dans le code produit.
   Tout passe par une variable de ce fichier.
   ========================================================================== */

:root{

  /* 🔴 CE QUE LE NAVIGATEUR DESSINE LUI-MÊME. `color-scheme` n'était déclaré
     nulle part : tous les widgets NATIFS — flèches d'un champ nombre, barres
     de défilement, sélecteur de date, anneau de focus d'un contrôle système —
     étaient donc rendus en CLAIR, quel que soit le thème. Sur une console
     sombre, deux triangles gris pâle collés au bord d'un champ ; et personne
     ne les avait vus parce qu'aucun champ n'était assez large pour les montrer.

     ⚠️ C'EST LE SEUL MOYEN CONFORME À LA LOI 13. Un filtre CSS sur ces flèches
     aurait demandé une règle qui CONNAÎT le thème, hors de ce fichier —
     exactement ce que la loi interdit. Ici la déclaration vit avec la palette,
     elle bascule avec elle, et elle vaut pour tous les widgets à la fois. */
  color-scheme: dark;

  /* ==========================================================================
     1 · SURFACES — empilement du plus profond au plus proche
     bg → panel → panel2 → elev
     Chaque niveau monte de ~4 points de luminance. Ne jamais sauter un niveau
     ni en inventer un cinquième : au-delà d'elev, on utilise une bordure.
     ========================================================================== */
  --bg:#08080a;        /* fond de page, seul niveau qui porte les halos       */
  --panel:#0e0e11;     /* carte, tableau, panneau — le niveau par défaut      */
  --panel2:#141418;    /* bloc imbriqué dans une carte, pill, node de flow    */
  --elev:#17171d;      /* contrôle interactif : bouton, toast, seg actif      */

  /* Séparateurs — trois graduations, jamais une couleur pleine */
  /* L'ARÊTE D'UN OBJET DESSINÉ — pas un filet d'interface.
     `--hair` sépare deux zones d'un écran ; celui-ci trace le CONTOUR d'une
     chose représentée, aujourd'hui la silhouette d'un iPhone dans le parc. Il
     lui faut son propre token parce qu'il ne suit pas la même règle : un filet
     s'efface, une silhouette doit se lire — donc pâle sur fond sombre, et
     franchement sombre sur fond clair, où `--hair` la rendait invisible. */
  --silhouette:#33333d;

  --hair:#1c1c22;      /* filet par défaut : bordure de carte, ligne de table */
  --line:#2a2a31;      /* filet appuyé : bordure de contrôle, box SVG         */
  --border:#232329;    /* intermédiaire, réservé aux cas de contraste         */

  /* Surfaces creusées (input, piste de seg, fond de barre) */
  --sunken:#0b0b0e;
  --track:#18181d;

  /* Hovers de surface — valeurs figées, ne pas improviser */
  --hover-nav:#101014;      /* .nav-item:hover                               */
  --hover-nav-on:#131319;   /* .nav-item:active / .active                    */
  --hover-row:#0c0c10;      /* ligne de liste (feed, rank)                   */
  --hover-cell:#0f0f14;     /* ligne de tableau                              */
  --hover-border:#26262d;   /* bordure de carte au survol                    */
  --hover-line:#3a3a44;     /* bordure de contrôle au survol                 */
  --zebra:#0c0c0f;          /* tbody tr:nth-child(even)                      */

  /* ==========================================================================
     2 · TEXTE — trois niveaux, jamais plus
     ========================================================================== */
  --tx:#ececee;        /* contenu, valeur, titre                             */
  --tx2:#9a9aa3;       /* secondaire : description, sous-titre, label actif   */
  --tx3:#63636d;       /* tertiaire : note, légende, unité, placeholder       */

  /* ==========================================================================
     3 · COULEURS DE MARQUE & SÉMANTIQUES
     Le teal est LA couleur du produit. Le cyan est son voisin de données.
     Le violet ne signifie jamais un état : il marque l'exception / le lien fort.
     ========================================================================== */
  --accent:#3dd6c3;                        /* teal — marque, focus, actif     */
  --accent-dim:#15453d;                    /* teal sourd — fond de sélection  */
  --accent-glow:rgba(61,214,195,.55);      /* teal diffusé — glow, halo       */

  --cyan:#43d3de;      /* données, séries, lien d'information                 */
  --violet:#7c74ff;    /* exception, attribution, lien fort de schéma         */
  --navy:#22314f;      /* bordure de bandeau d'information                    */
  --navy-bg:#0b1322;   /* fond de bandeau d'information                       */

  /* --------------------------------------------------------------------------
     VERT-JAUNE ÉLECTRIQUE — halo de survol, et RIEN D'AUTRE.

     La note sur les teintes de classement, plus bas, écarte explicitement un
     vert-jaune (h≈117) parce qu'il se confond « avec --ok et --warn à la fois ».
     Cette teinte-ci n'entre pas dans cette roue et ne contredit donc pas la
     note : elle ne sert JAMAIS à classer, à qualifier un état ni à écrire du
     texte. Elle n'apparaît qu'au survol, sous la forme d'une lumière derrière
     un objet — un endroit où rien d'autre ne se lit, et où la confusion avec un
     statut n'a pas d'occasion de se produire.

     La séparation vient d'ailleurs de la CLARTÉ et non de la teinte : L≈93
     contre 77 pour --ok et 78 pour --warn. Posée en aplat de texte elle
     échouerait au contraste ; posée en halo elle est exactement ce qu'on veut.

     `--lime-glow` et `--lime-halo` existent en toutes lettres plutôt que sous
     forme de `--lime-rgb` : une feuille locale ne peut pas écrire `rgba(…)`,
     même construit à partir d'un token — c'est une FAUTE au vérificateur, sans
     exception pour le cas licite. Même montage que `--accent-glow`.
     -------------------------------------------------------------------------- */
  --lime:#cbf82b;                          /* vert-jaune électrique — survol   */
  --lime-glow:rgba(203,248,43,.66);        /* cœur de la lumière               */
  --lime-halo:rgba(203,248,43,.30);        /* sa diffusion, plus large         */

  /* --------------------------------------------------------------------------
     TEINTES DE CLASSEMENT — deux ajouts, dérivés et non choisis
     Les six accents historiques suivent une formule : clarté perçue L≈74 et
     chroma C≈0,147 en OKLCH. Ces deux-là ont été générés à cette formule, aux
     deux plus grands trous de la roue (244° et 320°), puis retenus par
     optimisation sur la distance perceptuelle MINIMALE face à tous les accents
     existants — évaluée en vision normale ET sous les trois daltonismes.

     Écart minimal obtenu : 8,7 pour le bleu, 8,1 pour le magenta. À comparer au
     couple le plus serré déjà en place (teal↔cyan, 0,5 en tritanopie) : les
     nouvelles teintes sont donc largement plus séparables que ce que le système
     tolère déjà. Un rose plus chaud (h≈350) a été écarté : il se confondait
     avec --err, et un vert-jaune (h≈117) avec --ok et --warn à la fois.

     LE CAS DU ROUGE est différent des deux autres. Il ne pouvait pas être posé
     dans un trou de la roue : la zone rouge est déjà occupée par --err (#ec6a5e,
     h28 L68). La séparation vient donc de la CLARTÉ — le cramoisi est à L60
     contre L68 pour le corail d'erreur — et non de la teinte. Écart obtenu :
     9,1 face à --err, 8,5 au pire face à l'ensemble, tous daltonismes compris.

     Un grenat plus profond (#c0405a, L56) séparait mieux encore (12,5) mais ne
     tenait que 3,93:1 sur le fond sombre : écarté, il aurait été illisible dès
     qu'il sert de couleur de texte. Ne pas le réintroduire sans revérifier.

     LEUR SENS EST LIBRE. Le livrable d'origine leur assignait des
     significations imposées — EXTERNE, HUMAIN, RISQUE. Retiré le 1er août 2026 :
     ce sont des teintes de classement, à employer selon les besoins du moment,
     y compris comme identité visuelle d'une page.

     Seule contrainte conservée, et elle est technique : --red et --err sont
     deux rouges distincts, séparés par la clarté (L60 contre L68). Les employer
     côte à côte reste lisible ; les confondre annule le travail ci-dessus.
     -------------------------------------------------------------------------- */
  --blue:#4fa6e9;      /* bleu de classement — usage libre                    */
  --blue-rgb:79,166,233;
  --mag:#cc77df;       /* magenta de classement — usage libre                 */
  --mag-rgb:204,119,223;
  --red:#cd4f66;       /* cramoisi de classement — usage libre                */
  --red-rgb:205,79,102;

  --ext-bg:#0a2133;    --ext-line:#1c405d;   --ext-tx:#aad7fd;
  --hum-bg:#2b1531;    --hum-line:#502d58;   --hum-tx:#edbdf7;
  --risk-bg:#351218;   --risk-line:#602932;  --risk-tx:#ffbac1;
  --tile-b:#a6d7ff;    --tile-m:#efbbfb;     --tile-r:#ffb7c0;

  --ok:#35d29a;        /* succès, actif, en ligne                             */
  --warn:#e6a75c;      /* attente, seuil, dégradé                             */
  --err:#ec6a5e;       /* erreur, échec, suppression                          */
  --off:#41414a;       /* inactif, jamais démarré, désactivé                  */
  --info:#43d3de;      /* information neutre (= cyan)                         */

  /* Teintes de badge — fond / bordure / texte par état.
     Toujours utilisées en trio, jamais recomposées à la main. */
  --ok-bg:#0c1a15;     --ok-line:#1c3a30;   --ok-tx:#8ff0cf;
  --warn-bg:#1a1509;   --warn-line:#3a3120; --warn-tx:#f0d59b;
  --err-bg:#1c0f0d;    --err-line:#4a221d;  --err-tx:#f3a49b;
  --acc-bg:#12111e;    --acc-line:#2c2a52;  --acc-tx:#c3bfff;
  --cy-bg:#0a1a1c;     --cy-line:#1d4a52;   --cy-tx:#8fd8de;

  /* --------------------------------------------------------------------------
     DATAVIZ — remplissages PLEINS, et le nominal recule
     Deux principes, appris à l'usage :

     1. Pas de dégradé sur une barre de 6px. Il n'y est pas lisible et n'ajoute
        que du bruit. Les remplissages sont des aplats.
     2. LE NOMINAL NE CRIE PAS. Une valeur à 92 % ne demande aucune action : si
        elle est aussi lumineuse qu'un défaut à 24 %, l'œil n'a plus de repos et
        les vrais problèmes ne ressortent plus. Le remplissage par défaut est
        donc un teal calme, en retrait ; seuls les seuils franchis prennent une
        couleur qui appelle.
     -------------------------------------------------------------------------- */
  --bar-track:rgba(255,255,255,.07);  /* piste creusée, jamais une dalle noire  */
  --bar-fill:#4f8dcc;   /* NOMINAL ≥75 % — bleu franc, en retrait               */
  --bar-warn:#c69254;   /* 50–74 % — appelle sans alarmer                       */
  --bar-err:#c55a50;    /* <50 % — le seul qui doit accrocher                   */
  --bar-ok:#31a076;     /* succès EXPLICITE, pas « valeur haute » — reste vert  */
  --col-dim:#50667c;    /* colonne d'historique — sourde                        */
  --col-on:#5497d9;     /* dernière colonne — la seule accentuée                */

  /* Rampe séquentielle — pour données ORDINALES (paliers, tranches, quantiles).
     Une seule teinte du sombre au clair : l'ordre se lit sans légende. Ne
     JAMAIS peindre de l'ordinal en couleurs catégorielles — un arc-en-ciel de
     paliers de prix ne dit pas lequel est le plus élevé. */
  --ramp-1:#354f6a; --ramp-2:#46709b; --ramp-3:#5693cf; --ramp-4:#66b6ff;

  /* Alias historiques — conservés pour ne rien casser, mais un aplat suffit. */
  --grad-bar:var(--bar-fill);
  --grad-ok:var(--bar-ok);
  --grad-warn:var(--bar-warn);
  --grad-err:var(--bar-err);
  --grad-col:var(--col-on);

  /* --------------------------------------------------------------------------
     BOUTON PRIMAIRE — relief physique, sans halo lumineux
     Dégradé VERTICAL clair→sombre : c'est la lumière qui vient du haut. Le
     relief se joue en quatre couches, pas en une ombre :
       1. une arête spéculaire d'1px en haut (le reflet de la lumière),
       2. une assise sombre d'1px en bas (l'épaisseur de la pièce),
       3. un cerne interne qui détache le bouton de son fond,
       4. une ombre de contact courte + une ombre ambiante TEINTÉE par le
          bouton lui-même — un objet coloré projette une ombre colorée.
     Au clic, la pièce s'enfonce : le spéculaire s'éteint, l'ombre se referme.

     POURQUOI BLEU ET NON TEAL — c'est une contrainte de gamut, pas un goût.
     Un teal assez sombre pour porter du texte blanc plafonne à un chroma de
     0,099 en OKLCH : il est physiquement impossible de le rendre vif, il vire
     au vert sourd. À la même clarté, un bleu à h250 atteint 0,151 — soit +52 %
     de saturation. Le bouton est donc bleu, et la marque reste teal (--accent
     sert au focus, à l'item de nav actif, au logo).
     Contraste avec le blanc : 4,66:1 au sommet, 6,83:1 en bas.
     Le même dégradé sert dans les deux thèmes : c'est une surface pleine.
     -------------------------------------------------------------------------- */
  --grad-btn-p:linear-gradient(180deg,#1377c9 0%,#005ca5 100%);

  /* UNE SEULE ARÊTE NETTE : le spéculaire du haut. Tout le reste du modelé est
     FLOU. Un `inset 0 0 0 1px` dessinerait un trait dur qui fait le tour de la
     pièce — on le voit comme une bande, pas comme une ombre. L'assise et le
     pourtour sont donc posés avec du flou et un spread négatif, pour qu'ils
     montent depuis le bord et s'éteignent au lieu de s'arrêter net. */
  --btn-p-spec:rgba(255,255,255,.40);  /* arête spéculaire haute — la seule nette */
  --btn-p-wash:rgba(255,255,255,.14);  /* voile de lumière, s'éteint à 42%     */
  --btn-p-seat:rgba(0,0,0,.34);        /* assise basse — diffuse, jamais un trait */
  --btn-p-edge:rgba(0,0,0,.28);        /* pourtour — vignette douce            */
  --btn-p-cast:rgba(0,43,93,.55);      /* ombre ambiante teintée par le bouton */
  /* Pastille de compte POSÉE SUR la pièce. Un voile de la lumière du bouton, et
     non une surface du thème : `--sunken` y peindrait un pavé noir en sombre et
     blanc en clair, deux corps étrangers sur un aplat bleu identique dans les
     deux thèmes. */
  --btn-p-cnt:rgba(255,255,255,.20);

  /* --------------------------------------------------------------------------
     SÉPARATEURS À DÉGRADÉ
     Un filet plein s'arrête net et durcit la mise en page. Ceux-ci s'éteignent
     sur leurs extrémités : la ligne existe là où elle sépare, et disparaît là
     où elle toucherait un bord.
     -------------------------------------------------------------------------- */
  --sep-accent:rgba(61,214,195,.28);   /* filet teal — séparation structurante */
  --sep-neutral:rgba(255,255,255,.12); /* filet neutre — séparation ordinaire  */

  /* --------------------------------------------------------------------------
     HALO DE SURVOL
     Valeurs par défaut d'une carte non teintée. Chaque teinte de bandeau
     (.hd-g / .hd-c / .hd-o / .hd-v) les redéfinit : le halo prend la couleur
     de la carte qu'il éclaire, il n'a pas de couleur propre.
     -------------------------------------------------------------------------- */
  --glow-1:rgba(95,221,157,.5);
  --glow-2:rgba(67,211,222,.25);

  /* ==========================================================================
     4 · TYPOGRAPHIE
     Deux familles, aucune troisième. Inter porte le sens, JetBrains Mono
     porte la donnée (identifiants, chiffres, chemins, clés).
     Tout ce qui est un NOMBRE COMPARABLE est en mono avec tnum.
     ========================================================================== */
  --sans:'Inter',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  /* Emoji — Apple sur macOS/iOS, repli système ailleurs. Ce n'est pas une
     troisième famille de texte : réservé aux glyphes, jamais à une phrase. */
  --emoji:'Apple Color Emoji','Segoe UI Emoji','Noto Color Emoji',sans-serif;

  /* Échelle — 11 crans, volontairement serrée et dense.
     Les demi-pixels sont intentionnels : ils tiennent la densité à 14px de base. */
  --fs-micro:9.5px;    /* tag d'animation, label d'axe de graphe             */
  --fs-caption:10.5px; /* eyebrow, en-tête de tableau, label de section      */
  --fs-meta:11px;      /* label de KPI, badge, chip, légende                 */
  --fs-note:11.5px;    /* note, sous-cellule, bouton small, fil d'ariane     */
  --fs-code:12px;      /* code inline, seg, flow, donnée mono                */
  --fs-sm:12.5px;      /* bouton, kv, feed, lead, texte secondaire           */
  --fs-base:13px;      /* item de nav, cellule de tableau, titre de carte    */
  --fs-title:13.5px;   /* h1 de topbar, nom de marque                        */
  --fs-body:14px;      /* corps de texte — la base du document               */
  --fs-metric:26px;    /* valeur de KPI                                      */
  --fs-metric-lg:32px; /* valeur de KPI hero                                 */

  /* Graisses — 400 / 500 / 600 / 700, rien d'autre */
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;

  /* Interlettrage — le produit respire par les majuscules espacées */
  --ls-tight:-.5px;    /* valeur de KPI                                      */
  --ls-title:-.2px;    /* nom de marque, gros titre                          */
  --ls-caps:.07em;     /* titre en capitales (topbar, titre de carte)        */
  --ls-label:.09em;    /* en-tête de tableau                                 */
  --ls-nav:.13em;      /* label de groupe de nav                             */
  --ls-eyebrow:.16em;  /* eyebrow — le plus espacé                           */

  --lh:1.5;            /* interligne unique du produit                        */

  /* ==========================================================================
     5 · GÉOMÉTRIE
     Quatre rayons, du point à la carte. Aucun autre : pas de 4px, pas de 6px,
     pas de 12px, pas de 16px. Un rayon absent de cette liste est une dérive.

     Règle de concentricité — un bloc posé DANS un autre prend le rayon du
     contenant moins son rembourrage. Un segmenté de 8px rembourré de 3px
     porte donc des boutons de 5px : les angles restent parallèles.
     ========================================================================== */
  --r:10px;            /* carte, tableau, panneau, bandeau                    */
  --r-sm:8px;          /* bouton, input, node, tuile, bloc imbriqué           */
  --r-xs:5px;          /* code inline, tag, case à cocher, bloc concentrique  */
  --r-dot:2px;         /* pastille, marque, indicateur — carré à peine adouci */
  --r-pill:20px;       /* badge, pill, barre — au-delà de la demi-hauteur     */
  --r-tile:9px;        /* tuile d'icône (32px) — seule exception assumée      */

  --bw:1px;            /* toute bordure fait 1px. Sans exception.             */
  --rail:3px;          /* indicateur de nav, liseré gauche de bandeau         */

  /* ==========================================================================
     6 · ESPACE — rythme de 14 / 18 / 24
     gap:14 entre blocs · padding:18 dans une carte · 24×32 en marge de page
     ========================================================================== */
  --sp-1:4px;   --sp-2:7px;   --sp-3:10px;  --sp-4:14px;
  --sp-5:18px;  --sp-6:24px;  --sp-7:32px;  --sp-8:48px;  --sp-9:64px;

  --gap:var(--sp-4);          /* gap canonique de toutes les grilles          */
  --stack:var(--sp-5);        /* respiration entre deux blocs empilés d'une vue */
  --pad-card:var(--sp-5);     /* padding intérieur de carte                   */
  --pad-cell:11px 14px;       /* padding de cellule de tableau                */
  /* La marge de page RESPIRE avec l'écran : 16px sur un portable, 40px sur un
     grand écran. Une valeur fixe donne soit un écran étouffé en bas de gamme,
     soit un liseré ridicule en haut. */
  --pad-page-x:clamp(16px,2.4vw,40px);
  --pad-page:var(--sp-6) var(--pad-page-x) var(--sp-9);
  --h-top:56px;               /* hauteur de la topbar — constante             */
  --h-sub:42px;               /* bande de sous-navigation                     */
  /* Réserve sous une galerie surmontée d'une barre ancrée. Sans elle, la barre
     masque les dernières images et rien n'indique qu'il en reste. Généreuse
     exprès : la barre grandit quand ses pastilles passent à la ligne. */
  --h-dock:230px;
  --frame-h:70vh;             /* hauteur d'un cadre hors charte, par defaut   */
  /* Fond d'ATTENTE d'un cadre embarquant une application entiere. Ajoute le
     1er aout 2026 : `.frame` retombait sur `Canvas`, c'est-a-dire BLANC. Entre
     deux pages, l'ancien document dispara?t avant que le nouveau ne peigne, et
     ce blanc apparaissait une demi-seconde — un flash a chaque navigation.

     Volontairement SOMBRE ET FIXE, sans suivre le theme de la console : c'est
     le fond de l'application embarquee qu'il doit imiter, pas celui de la page
     qui l'entoure. NODE reste sombre meme quand la console passe en clair. */
  --frame-bg:#08080a;
  /* Cadre pleine hauteur — pour une application entière embarquée, qui a sa
     propre navigation, son propre défilement et ses propres marges. Seul le
     bandeau est retiré : le reste de la fenêtre lui revient, de bord à bord.
     70vh conviendrait à un extrait ; à une application, il fait une lucarne. */
  --frame-h-plein:calc(100vh - var(--h-top));

  /* PAS de plafond de largeur. Une console n'est pas un article : ses tableaux
     et ses grilles gagnent à chaque pixel, et un plafond fabrique deux bandes
     mortes sur un grand écran. Ce qui doit rester lisible se borne lui-même,
     par --w-read, pas par le conteneur. */
  --w-max:none;
  --w-read:74ch;              /* mesure de lecture d'un bloc de prose         */

  /* --------------------------------------------------------------------------
     BARRE DE NAVIGATION RÉTRACTABLE
     Deux largeurs, jamais une intermédiaire. La barre est EN FLUX : sa largeur
     pousse le contenu, elle ne le recouvre pas.
     L'icône vit dans un slot de largeur fixe dont le centre est invariant entre
     les deux états — c'est ce qui l'empêche de glisser à l'ouverture.
     -------------------------------------------------------------------------- */
  --w-rail:64px;              /* barre repliée — icônes seules                */
  --w-side:244px;             /* barre déployée — icônes + libellés           */
  --slot-ico:48px;            /* slot d'icône, centre invariant               */
  --rail-pad:8px;             /* marge latérale des items de nav              */
  --ico-sz:16px;              /* tracé de l'icône, centré dans son slot       */
  /* Verticale où COMMENCE le tracé — 24px. À ne pas confondre avec le bord du
     slot (8px) : entre les deux il y a le centrage, et un titre aligné sur 8
     paraît collé au bord. C'est sur --axe-ico que se posent les titres de
     section, pour démarrer exactement en même temps que les icônes. */
  --axe-ico:calc(var(--rail-pad) + (var(--slot-ico) - var(--ico-sz)) / 2);
  --t-panel:.2s;                              /* durée du dépliage            */
  --ease-panel:cubic-bezier(.22,1,.36,1);     /* courbe du dépliage           */
  --delay-open:100ms;         /* intention d'ouverture — anti-survol fortuit  */
  --delay-close:220ms;        /* intention de fermeture — anti-aller-retour   */

  /* --------------------------------------------------------------------------
     HAUTEURS DE CONTRÔLE — la condition de l'alignement horizontal
     Tout contrôle posé sur une même ligne partage une de ces hauteurs.
     C'est une hauteur FIXE, jamais un padding : deux contrôles au contenu
     différent doivent occuper exactement la même boîte.

     DEUX tailles, pas trois. Le 40px a été essayé puis retiré : dans une
     console dense il écrase la ligne sur laquelle il se pose. Une action
     importante se distingue par sa couleur (.btn.p), pas par sa hauteur.
     -------------------------------------------------------------------------- */
  --h-ctrl:32px;              /* bouton, champ, segmented — la taille normale */
  --h-ctrl-sm:28px;           /* variante compacte                            */
  --h-badge:22px;             /* badge et pill — s'aligne au centre d'une ligne */

  /* --------------------------------------------------------------------------
     MENUS DÉROULANTS
     Un menu se pose AU-DESSUS du contenu : il doit rester lisible.
     Plancher d'opacité 70 % — en dessous, le texte du menu se confond avec ce
     qu'il recouvre. On travaille en pratique à 94 % + flou.
     -------------------------------------------------------------------------- */
  --dd-opacity-min:.7;        /* plancher contractuel — ne jamais descendre    */
  --dd-w-min:180px;
  --h-dd-item:30px;

  /* --------------------------------------------------------------------------
     SURFACES MODALES
     Le voile assombrit ET floute : le flou dit « ce qui est derrière est
     inactif », l'assombrissement rend le contenu de la modale lisible.
     -------------------------------------------------------------------------- */
  --backdrop:rgba(4,4,6,.72);
  --backdrop-blur:3px;
  --modal-w:520px;            /* défaut ; .sm 380 · .lg 760 · .xl éditeur      */
  --drawer-w:420px;

  /* --------------------------------------------------------------------------
     AUTRES GABARITS D'ÉCRAN
     -------------------------------------------------------------------------- */
  --h-tab:38px;               /* barre d'onglets                              */
  --h-row:38px;               /* ligne cliquable d'une liste                  */
  --h-palette:46px;           /* bande de saisie de la palette                */
  /* Ces trois-la sont des hauteurs de MISE EN PAGE (bandes, lignes), pas des
     hauteurs de controle : la loi des deux tailles ne porte que sur ce qui se
     pose cote a cote dans une .row. Une bande de surface suit --h-top. */
  --av:28px;                  /* avatar — .sm 22 · .lg 36 · .xl 64 (alesia.css) */
  /* LARGEUR MINIMALE D'UNE CARTE-AFFICHE. C'est elle, et non un nombre de
     colonnes, qui décide combien tiennent sur une ligne : la grille en pose
     autant que la largeur en autorise, sans qu'aucun palier soit écrit nulle
     part.

     LE CALCUL, POUR POUVOIR LA RÉGLER SANS TÂTONNER. La grille pose
     `floor((L + gap) / (piste + gap))` colonnes, où `L` est la largeur utile —
     la fenêtre moins le rail de 64 px et deux fois `--pad-page-x`. À 205 px :
     cinq colonnes à 1280, six de 1440 à 1600, sept vers 1800, huit au-delà.

     205 px tient une photo 3:4 lisible et un prénom sans le tronquer — et la
     piste ne DESCEND jamais là : c'est un plancher, les colonnes s'élargissent
     dès qu'il reste de la place. */
  --w-affiche:205px;          /* carte-affiche — voir .g-affiches               */

  /* AU-DELÀ, LA GRILLE CESSE D'AJOUTER DES COLONNES — mais elle continue de
     remplir la largeur. Sur un très grand écran, `auto-fill` en poserait dix ou
     douze : les cartes deviennent une mosaïque qu'on ne balaie plus, et le
     regard doit traverser toute la dalle pour lire une ligne. Huit est le point
     où un catalogue reste un catalogue.

     ⚠️ PLAFONNER LE NOMBRE, PAS LA LARGEUR. Une `max-width` sur la grille aurait
     aussi tenu les huit colonnes — en laissant sept cents pixels de vide à
     droite sur un écran de 2560. Ici ce sont les CARTES qui grandissent : huit
     de 290 px au lieu de huit de 205 px collées à gauche. */
  --n-affiches-max:8;         /* colonnes au maximum — voir .g-affiches         */
  --sk-base:rgba(255,255,255,.06);   /* squelette : la plaque                 */
  --sk-shine:rgba(255,255,255,.09);  /* squelette : le balayage               */
  --tip-bg:rgba(20,20,25,.96);       /* infobulle — opaque, elle doit se lire */

  /* ==========================================================================
     7 · PROFONDEUR
     Le produit ne pose jamais d'ombre portée franche : la hiérarchie se lit
     par le liseré haut (--inset-hi) et la couleur de surface.
     ========================================================================== */
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.028); /* liseré haut — signature */
  --shadow-1:0 1px 2px rgba(0,0,0,.35);            /* posé — carte, bouton    */
  --shadow-2:0 8px 24px -12px rgba(0,0,0,.55);     /* flottant — toast, popup */

  /* Relief du bouton neutre — la seule pièce du produit qui a un volume.
     Reflet en haut, ombre portée en bas ; au clic il s'enfonce d'un pixel et
     l'ombre s'inverse. Ne pas appliquer ce relief à autre chose qu'un bouton. */
  --relief:inset 0 1px 0 rgba(255,255,255,.06),
           0 1px 2px rgba(0,0,0,.4),
           0 2px 6px rgba(0,0,0,.25);
  --relief-hover:inset 0 1px 0 rgba(255,255,255,.08),
                 0 2px 4px rgba(0,0,0,.45),
                 0 4px 10px rgba(0,0,0,.3);
  --relief-active:inset 0 1px 2px rgba(0,0,0,.3),
                  0 0 0 1px rgba(255,255,255,.06);

  /* Champ creusé — l'inverse du relief : la saisie s'enfonce dans la surface. */
  --sunk:inset 0 1px 3px rgba(0,0,0,.5),
         inset 0 -1px 0 rgba(255,255,255,.04);

  /* ==========================================================================
     8 · MOUVEMENT
     Une seule courbe pour tout le produit. Les durées sont typées par intention.
     ========================================================================== */
  --ease:cubic-bezier(.22,.61,.36,1);

  --t-fast:.14s;    /* teinte de ligne au survol — quasi imperceptible        */
  --t-quick:.16s;   /* état d'un contrôle : bouton, input, node               */
  --t-ui:.2s;       /* bascule d'un composant : switch, carte, chevron        */
  --t-state:.25s;   /* changement d'état sémantique : badge, glow, toast      */
  --t-slide:.28s;   /* déplacement de l'indicateur de nav                     */
  --t-enter:.5s;    /* entrée d'un élément : boot, reveal                     */
  --t-chart:.9s;    /* remplissage d'une barre                                */
  --t-draw:1.1s;    /* tracé d'une sparkline                                  */
  --stagger:55ms;   /* décalage entre deux enfants révélés                    */

  /* ==========================================================================
     9 · EMPILEMENT — la seule échelle z autorisée
     ========================================================================== */
  /* Réservé aux cellules figées d'un tableau. NE PAS le reposer sur un
     conteneur de contenu : un élément positionné qui porte un z-index crée un
     contexte d'empilement, et tout menu déroulant ouvert à l'intérieur s'y
     retrouve enfermé — il passe sous le bloc voisin. Pour surmonter un
     `::before` de bandeau, `position:relative` seul suffit. */
  --z-base:1;       /* cellule figée — jamais un conteneur de contenu         */
  --z-sticky:2;     /* en-tête de tableau, cellule figée                      */
  --z-float:3;      /* bouton flottant dans une planche (replay, copier)      */
  --z-topbar:5;     /* barre supérieure                                       */
  --z-dd:20;        /* menu déroulant — au-dessus du contenu, sous les toasts */
  --z-modal:30;     /* voile + modale / tiroir                                */
  --z-tip:36;       /* infobulle — au-dessus d'une modale, sous les toasts    */
  --z-toast:40;     /* pile de notifications                                  */

  /* ==========================================================================
     10 · FOND DE PAGE — signature visuelle du produit
     Deux halos froids décentrés + une trame de points à 26px.
     Fixe au scroll : le fond est un décor, pas un contenu.
     ========================================================================== */
  --page-halo-1:radial-gradient(1100px 480px at 72% -12%, rgba(67,211,222,.06) 0%, transparent 60%);
  --page-halo-2:radial-gradient(900px 420px at 8% 8%, rgba(95,221,157,.045) 0%, transparent 55%);
  --page-dots:radial-gradient(rgba(255,255,255,.09) 1px, transparent 1.3px);
  --page-dots-size:26px;

  /* BANDEAUX DE TÊTE — LA TEINTE ENTRE PAR LES QUATRE BORDS.

     Jusqu'au 5 août 2026 elle descendait du haut et mourait à mi-carte. Elle
     part maintenant des quatre côtés vers le centre, sur toute la surface :
       180deg = du haut vers le bas → la couleur est EN HAUT ;  0deg = EN BAS
        90deg = de gauche à droite  → À GAUCHE                ; 270deg = À DROITE

     CHAQUE RAMPE EST BORNÉE DANS LES DEUX SENS, par `min()`. Une carte n'a pas
     de taille : une colonne de journal fait 600 px de haut, une ligne
     d'automatisation 90 ; l'une 1400 px de large, l'autre 465. Une rampe en
     pourcentage seul devient un aplat sur une petite carte ; en distance seule,
     un filet invisible sur une grande. Le plus petit des deux garde un bord
     franc ET un centre propre dans les deux cas.

     13 % ET NON 15 % : les quatre se superposent aux angles, où deux couleurs
     s'additionnent. Les coins plus lumineux sont voulus — un objet éclairé par
     ses quatre bords fait ça — mais un cran plus haut ils viraient à l'aplat.

     UNE SEULE DÉFINITION POUR LES DEUX THÈMES, et c'est nouveau. Les valeurs
     étaient écrites deux fois, en clair, avec le risque d'en corriger une et
     pas l'autre. Elles partent maintenant du token de teinte : `var(--violet)`
     est résolu à l'EMPLOI, donc il vaut le violet clair sous `data-theme=light`
     sans qu'on ait rien à redire ici. Le bloc clair n'en porte donc plus. */
  --hd-g:
      linear-gradient(180deg,
        color-mix(in srgb,var(--ok) 13%,transparent) 0,
        color-mix(in srgb,var(--ok) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(0deg,
        color-mix(in srgb,var(--ok) 13%,transparent) 0,
        color-mix(in srgb,var(--ok) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(90deg,
        color-mix(in srgb,var(--ok) 13%,transparent) 0,
        color-mix(in srgb,var(--ok) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem)),
      linear-gradient(270deg,
        color-mix(in srgb,var(--ok) 13%,transparent) 0,
        color-mix(in srgb,var(--ok) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem));
  --hd-c:
      linear-gradient(180deg,
        color-mix(in srgb,var(--cyan) 13%,transparent) 0,
        color-mix(in srgb,var(--cyan) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(0deg,
        color-mix(in srgb,var(--cyan) 13%,transparent) 0,
        color-mix(in srgb,var(--cyan) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(90deg,
        color-mix(in srgb,var(--cyan) 13%,transparent) 0,
        color-mix(in srgb,var(--cyan) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem)),
      linear-gradient(270deg,
        color-mix(in srgb,var(--cyan) 13%,transparent) 0,
        color-mix(in srgb,var(--cyan) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem));
  --hd-o:
      linear-gradient(180deg,
        color-mix(in srgb,var(--warn) 13%,transparent) 0,
        color-mix(in srgb,var(--warn) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(0deg,
        color-mix(in srgb,var(--warn) 13%,transparent) 0,
        color-mix(in srgb,var(--warn) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(90deg,
        color-mix(in srgb,var(--warn) 13%,transparent) 0,
        color-mix(in srgb,var(--warn) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem)),
      linear-gradient(270deg,
        color-mix(in srgb,var(--warn) 13%,transparent) 0,
        color-mix(in srgb,var(--warn) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem));
  --hd-v:
      linear-gradient(180deg,
        color-mix(in srgb,var(--violet) 13%,transparent) 0,
        color-mix(in srgb,var(--violet) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(0deg,
        color-mix(in srgb,var(--violet) 13%,transparent) 0,
        color-mix(in srgb,var(--violet) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(90deg,
        color-mix(in srgb,var(--violet) 13%,transparent) 0,
        color-mix(in srgb,var(--violet) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem)),
      linear-gradient(270deg,
        color-mix(in srgb,var(--violet) 13%,transparent) 0,
        color-mix(in srgb,var(--violet) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem));
  --hd-b:
      linear-gradient(180deg,
        color-mix(in srgb,var(--blue) 13%,transparent) 0,
        color-mix(in srgb,var(--blue) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(0deg,
        color-mix(in srgb,var(--blue) 13%,transparent) 0,
        color-mix(in srgb,var(--blue) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(90deg,
        color-mix(in srgb,var(--blue) 13%,transparent) 0,
        color-mix(in srgb,var(--blue) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem)),
      linear-gradient(270deg,
        color-mix(in srgb,var(--blue) 13%,transparent) 0,
        color-mix(in srgb,var(--blue) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem));
  --hd-m:
      linear-gradient(180deg,
        color-mix(in srgb,var(--mag) 13%,transparent) 0,
        color-mix(in srgb,var(--mag) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(0deg,
        color-mix(in srgb,var(--mag) 13%,transparent) 0,
        color-mix(in srgb,var(--mag) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(90deg,
        color-mix(in srgb,var(--mag) 13%,transparent) 0,
        color-mix(in srgb,var(--mag) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem)),
      linear-gradient(270deg,
        color-mix(in srgb,var(--mag) 13%,transparent) 0,
        color-mix(in srgb,var(--mag) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem));
  --hd-r:
      linear-gradient(180deg,
        color-mix(in srgb,var(--red) 13%,transparent) 0,
        color-mix(in srgb,var(--red) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(0deg,
        color-mix(in srgb,var(--red) 13%,transparent) 0,
        color-mix(in srgb,var(--red) 5%,transparent) min(22%,3rem),
        transparent min(55%,8rem)),
      linear-gradient(90deg,
        color-mix(in srgb,var(--red) 13%,transparent) 0,
        color-mix(in srgb,var(--red) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem)),
      linear-gradient(270deg,
        color-mix(in srgb,var(--red) 13%,transparent) 0,
        color-mix(in srgb,var(--red) 5%,transparent) min(15%,4.5rem),
        transparent min(45%,13rem));

  /* ==========================================================================
     11 · SURFACES COMPOSÉES
     Tout ce qui était écrit en dur dans les composants et qui doit basculer
     avec le thème. Aucun `#hex` ne doit subsister hors de ce fichier.
     ========================================================================== */
  --side-grad:linear-gradient(180deg,#0c0c0f,#090909); /* fond de la barre     */
  /* La pastille de marque reste SOMBRE dans les deux thèmes : c'est un objet
     de marque, pas une surface d'interface. En clair, un logo blanc sur un
     panneau blanc disparaît, et le point d'accent qu'il porte avec lui. */
  --logo-grad:linear-gradient(145deg,#232c3d,#141a26);
  --logo-line:#2e394d;
  --thead-grad:linear-gradient(180deg,#101014,#0e0e11);/* en-tête de tableau   */
  --thead-solid:#101014;                               /* cellule figée        */
  --glass:rgba(8,8,10,.78);                            /* topbar translucide   */
  --glass-chip:rgba(14,14,17,.6);                      /* chip d'environnement */
  --scroll-thumb:#26262d;
  --scroll-thumb-h:#31313a;
  --sel-tx:#eafff3;                                    /* texte sélectionné    */

  /* Marque posée SUR un aplat d'accent — coche, glyphe, pictogramme.
     MESURÉ, pas choisi : une coche blanche sur `--accent` ne tient que
     1,81:1 en sombre, elle disparaît. Ce teal très sombre donne 9,09:1 en
     sombre et 4,77:1 en clair — la même valeur convient aux deux, l'accent
     restant clair dans les deux thèmes. */
  --on-accent:#04241f;

  /* L'infobulle garde un fond sombre dans les DEUX thèmes : son texte ne
     bascule donc pas avec le reste. */
  --tip-tx:#f2f4f7;
  --pulse-halo:rgba(53,210,154,.45);                   /* onde de la pastille  */

  /* Encre des tuiles d'icônes — s'assombrit en thème clair, sinon l'icône
     disparaît dans le lavis pastel de sa propre tuile. */
  --tile-g:#7ce8b4; --tile-c:#7fe2ea; --tile-o:#f0c894; --tile-v:#b6b0ff;

  /* Face du bouton neutre. Elle porte du texte BLANC dans les deux thèmes :
     en sombre c'est un voile clair sur le panneau, en clair c'est une face
     ardoise pleine. C'est la contrepartie du texte blanc — un bouton clair à
     texte blanc serait illisible. */
  --btn-face:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,.02));
  --btn-face-h:linear-gradient(180deg,rgba(255,255,255,.09),rgba(255,255,255,.04));
  --btn-line:var(--line);

  /* Champ de saisie — creusé */
  --field-bg:rgba(0,0,0,.25);
  --field-line:rgba(0,0,0,.5);

  /* Bandeau d'information */
  --lead-tx:#b6c1d4;
  --lead-bg2:#0a0f19;
  --lead-line:#2c3f66;
  --lead-code-bg:#0a1420;

  /* Menu déroulant — voile opaque au-dessus du plancher de 70 % */
  /* Un menu se pose AU-DESSUS du contenu : il doit rester lisible sur ce qu'il
     recouvre. Le flou donne la profondeur, l'alpha garantit la lecture — et
     c'est l'alpha, pas le flou, qui décide qu'on lit ou qu'on devine.
     Relevé de .94 le 2 août 2026 : à 94 %, un bouton clair situé dessous se
     lisait encore en filigrane à travers les items. Vérifié à l'écran. */
  --dd-bg:rgba(20,20,25,.99);
  --dd-shadow:0 12px 32px -10px rgba(0,0,0,.7);

  /* Texte des boutons — blanc détaché du fond par une ombre courte.
     C'est ce qui le fait ressortir aussi bien sur le voile neutre que sur le
     dégradé teal, sans avoir à changer de couleur selon la variante. */
  --btn-tx:#ffffff;
  --btn-tx-shadow:0 1px 1px rgba(0,0,0,.55), 0 0 2px rgba(0,0,0,.35);
  --btn-ico-shadow:drop-shadow(0 1px 1px rgba(0,0,0,.5));
}

/* ============================================================================
   THÈME CLAIR
   ----------------------------------------------------------------------------
   Activé par `data-theme="light"` sur <html>. Le moteur (alesia.js) le pose
   selon le choix de l'utilisateur, à défaut selon `prefers-color-scheme`.

   PRINCIPE : ce bloc ne redéfinit QUE des tokens. Aucun composant n'a de règle
   `[data-theme="light"] .machin` — si un composant nécessite une exception,
   c'est qu'il lui manque un token.

   Le clair n'est pas l'inverse mécanique du sombre : les accents sont
   assombris pour tenir le contraste sur fond blanc, et le liseré haut
   (--inset-hi) devient une ombre, faute de quoi tout paraît plat.
   ========================================================================== */
:root[data-theme="light"]{
  /* Voir le commentaire de `color-scheme` en tête : elle bascule avec la
     palette, et avec elle tout ce que le navigateur dessine lui-même. */
  color-scheme: light;

  /* Surfaces — papier, jamais blanc pur pour le fond de page */
  --bg:#f2f4f7;
  --panel:#ffffff;
  --panel2:#f6f8fa;
  --elev:#ffffff;
  --sunken:#eceff3;
  --track:#e2e6ec;

  /* Quasi noir : sur du papier, une silhouette d'objet se dessine au trait. */
  --silhouette:#14161c;

  --hair:#e4e7ed;
  --line:#d2d8e1;
  --border:#dce0e7;

  --hover-nav:#eceff4;
  --hover-nav-on:#e3e8ef;
  --hover-row:#f4f6f9;
  --hover-cell:#eff2f6;
  --hover-border:#c6cdd8;
  --hover-line:#b3bcc9;
  --zebra:#fafbfc;

  /* Texte */
  --tx:#14161c;
  --tx2:rgba(20,22,28,.68);
  --tx3:rgba(20,22,28,.5);

  /* Marque & sémantiques — assombries pour tenir sur fond clair */
  --accent:#0f9b8c;
  --accent-dim:#d3f2ed;
  --accent-glow:rgba(15,155,140,.45);
  --cyan:#0c8fa1;
  --violet:#5646d8;
  --blue:#1973af;   --blue-rgb:25,115,175;
  --mag:#9547a6;    --mag-rgb:149,71,166;
  --red:#911b3a;    --red-rgb:145,27,58;
  --navy:#bcc7dc;
  --navy-bg:#eef3fb;

  /* Le vert-jaune reste VIF sur fond clair : c'est une lumière, et une lumière
     assombrie devient une ombre. Seul le trait — qui, lui, se lit — descend en
     clarté pour tenir sur du blanc. */
  --lime:#6f8f00;
  --lime-glow:rgba(174,224,0,.78);
  --lime-halo:rgba(174,224,0,.40);

  --ok:#12996b;
  --warn:#a56a10;
  --err:#c53a2c;
  --off:#9aa2ae;
  --info:#0c8fa1;

  --ok-bg:#e4f6ee;   --ok-line:#b6e3cf;   --ok-tx:#0b6b4a;
  --warn-bg:#fbf0da; --warn-line:#eed9a8; --warn-tx:#7d4f08;
  --err-bg:#fbe6e3;  --err-line:#f2c2ba;  --err-tx:#94261a;
  --acc-bg:#ecebfb;  --acc-line:#cdc6f4;  --acc-tx:#3d2fa8;
  --cy-bg:#e0f2f6;   --cy-line:#b3dde6;   --cy-tx:#075f6d;
  --ext-bg:#dbf2ff;  --ext-line:#b0d6f7;  --ext-tx:#005a91;
  --hum-bg:#fee5ff;  --hum-line:#e9c0f2;  --hum-tx:#793089;
  --risk-bg:#ffe3e6; --risk-line:#ffbdc4; --risk-tx:#94263f;
  --tile-b:#005a91;  --tile-m:#793089;    --tile-r:#94263f;

  /* Dataviz — mêmes rôles, assombris pour tenir sur blanc */
  --bar-track:rgba(20,22,28,.09);
  --bar-fill:#0863a9;
  --bar-warn:#9b6721;
  --bar-err:#982b26;
  --bar-ok:#00764d;
  --col-dim:#a8c1da;
  --col-on:#116bb5;
  --ramp-1:#a6c1dd; --ramp-2:#739ecb; --ramp-3:#3e7cb8; --ramp-4:#0059a4;
  /* Le bouton primaire garde exactement le même relief : c'est une pièce
     pleine, elle ne dépend pas du fond sur lequel elle est posée. Seule
     l'ombre projetée s'allège, une surface claire renvoyant plus de lumière. */
  --btn-p-cast:rgba(0,43,93,.32);

  /* Profondeur — le liseré blanc n'a plus de sens : on passe à une ombre. */
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.9);
  --shadow-1:0 1px 2px rgba(20,22,28,.08);
  --shadow-2:0 8px 24px -12px rgba(20,22,28,.22);
  --relief:inset 0 1px 0 rgba(255,255,255,.85),
           0 1px 2px rgba(20,22,28,.1),
           0 2px 6px rgba(20,22,28,.06);
  --relief-hover:inset 0 1px 0 rgba(255,255,255,.95),
                 0 2px 4px rgba(20,22,28,.12),
                 0 4px 10px rgba(20,22,28,.08);
  --relief-active:inset 0 1px 2px rgba(20,22,28,.14),
                  0 0 0 1px rgba(20,22,28,.05);
  --sunk:inset 0 1px 2px rgba(20,22,28,.1),
         inset 0 -1px 0 rgba(255,255,255,.8);

  /* Fond de page — mêmes halos, opacités relevées pour rester perceptibles */
  --page-halo-1:radial-gradient(1100px 480px at 72% -12%, rgba(12,143,161,.07) 0%, transparent 60%);
  --page-halo-2:radial-gradient(900px 420px at 8% 8%, rgba(18,153,107,.055) 0%, transparent 55%);
  --page-dots:radial-gradient(rgba(20,22,28,.11) 1px, transparent 1.3px);


  --glow-1:rgba(18,153,107,.45);
  --glow-2:rgba(12,143,161,.22);

  /* Séparateurs */
  --sep-accent:rgba(15,155,140,.32);
  --sep-neutral:rgba(20,22,28,.12);

  /* Surfaces composées */
  /* La barre est un élément de CHÂSSIS : elle doit se lire comme distincte du
     contenu. En sombre elle est plus noire que la page ; en clair elle doit
     être plus grise — blanche, elle se confondrait avec les panneaux. */
  --side-grad:linear-gradient(180deg,#e9edf3,#e4e9f0);
  --logo-grad:linear-gradient(145deg,#232c3d,#141a26);
  --logo-line:#2e394d;
  --thead-grad:linear-gradient(180deg,#f7f9fb,#f2f5f8);
  --thead-solid:#f7f9fb;
  --glass:rgba(242,244,247,.82);
  --glass-chip:rgba(255,255,255,.7);
  --scroll-thumb:#c9d0da;
  --scroll-thumb-h:#b2bcc9;
  --sel-tx:#04241f;
  --pulse-halo:rgba(18,153,107,.4);
  --tile-g:#0b6b4a; --tile-c:#075f6d; --tile-o:#7d4f08; --tile-v:#3d2fa8;

  /* Face ardoise pleine : c'est ce qui permet au texte blanc de tenir en clair. */
  --btn-face:linear-gradient(180deg,#3d4557,#2c3341);
  --btn-face-h:linear-gradient(180deg,#4a5468,#363e4e);
  --btn-line:#2c3341;

  --field-bg:#ffffff;
  --field-line:#d2d8e1;

  --lead-tx:#33455f;
  --lead-bg2:#e6eefa;
  --lead-line:#b3c4de;
  --lead-code-bg:#dfeaf8;

  --dd-bg:rgba(255,255,255,.99);
  --dd-shadow:0 12px 32px -10px rgba(20,22,28,.28);

  /* En thème clair le voile est plus léger : le contraste du panneau blanc
     suffit à détacher la modale, l'assombrir à 72 % serait brutal. */
  --backdrop:rgba(20,22,28,.42);
  --sk-base:rgba(20,22,28,.07);
  --sk-shine:rgba(20,22,28,.04);
  --tip-bg:rgba(20,22,28,.96);

  /* Le texte des boutons reste blanc dans les DEUX thèmes : la face neutre
     s'assombrit en clair précisément pour que ce blanc tienne. */
  --btn-tx:#ffffff;
  --btn-tx-shadow:0 1px 1px rgba(20,22,28,.6), 0 0 2px rgba(20,22,28,.35);
  --btn-ico-shadow:drop-shadow(0 1px 1px rgba(20,22,28,.5));
}

/* ============================================================================
   THÈME « RAPPORT » — papier clair, éditorial
   ----------------------------------------------------------------------------
   Système SECONDAIRE, réservé aux documents de synthèse imprimables/lisibles
   (cf. synthese_module*.html). Ne jamais le mélanger au thème console dans
   un même écran. On l'active sur un conteneur : <div data-theme="rapport">.
   ========================================================================== */
[data-theme="rapport"]{
  --ink:#14141b; --ink-soft:#3a3a48;
  --paper:#eef0f4; --panel:#ffffff;
  --line:#d7dae2; --line-soft:#e7e9ef;

  --violet:#5b3df5; --violet-deep:#3b23c9; --violet-wash:#efeaff;
  --teal:#00a58e;   --teal-wash:#e0f6f1;
  --amber:#c9860b;  --amber-wash:#fbeecf;
  --rose:#d6336c;   --rose-wash:#fbe4ec;

  --disp:'Space Grotesk',system-ui,sans-serif;
  --body:'Inter',system-ui,sans-serif;

  --paper-grid:34px;   /* trame de fond du thème rapport                      */
  --r-paper:4px;       /* le papier a des angles nets, pas arrondis           */
}
