/* ══════════════════════════════════════════════════════════════════════════
   IPX — Couche 1 : TOKENS
   Palette dérivée du LOGO.

   ⚗ ESSAI EN COURS — le THÈME CLAIR est en cours d'arbitrage. Le thème sombre
   est validé et n'est PAS touché par ces essais. La variante montée
   actuellement est nommée dans le bloc des neutres ci-dessous.

   Le logo contient deux bleus et aucun vert. C'est toute la structure de
   cette palette :
     • le bleu PROFOND (#1f6a9b — point du « i », losange du « X ») porte les
       actions en thème clair, où il faut soutenir du texte blanc ;
     • l'AZUR (#4a90ce — les lettres) porte les actions en thème sombre, où
       il faut au contraire soutenir de l'encre sombre.
   Chaque thème utilise donc une couleur réelle du logo, sans invention.

   Deux conséquences à assumer :
     • le mint #7DD3A8 disparaît — il n'était pas dans la marque ;
     • « info » ne peut plus être bleu. Quand la marque est bleue, le bleu dit
       « le produit vous parle » ou « voici l'action » ; il ne peut pas dire
       aussi « voici un fait ». --info prend donc l'indigo.

   Règle : un composant ne cite JAMAIS une couleur brute. Il cite un token
   sémantique. C'est ce qui rend le thème sombre gratuit.
═══════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────────────────
   1. PALETTE BRUTE — les teintes, sans intention
   ───────────────────────────────────────────────────────────────────────── */
:root {
  /* Bleu IPX — la rampe du logo, teinte 206° */
  --ipx-blue-50:#eff6fc;   --ipx-blue-100:#dbeaf6;  --ipx-blue-200:#b5d4ea;
  --ipx-blue-300:#85b8dc; --ipx-blue-400:#4a90ce;  /* ← LOGO, les lettres */
  --ipx-blue-500:#2f7cb8; --ipx-blue-600:#1f6a9b;  /* ← LOGO, le bleu profond */

  /* ── TROIS BLEUS SOMBRES, HORS MARQUE ──────────────────────────────────
     Ils s'appelaient `--ipx-blue-700/800/900` et n'ont PAS changé de valeur.
     Ce qui change, c'est ce qu'ils prétendent être : ils ne portent plus
     l'identité. Depuis que la barre latérale, les en-têtes de carte et les
     toasts sont en ardoise, la marque ne vit plus que dans `--ipx-blue-600`
     (l'action) et `--ipx-blue-400` (l'azur du logo). Ces trois crans ne sont
     plus que des nuances d'interaction — le survol et le clic d'un bouton —
     et le préfixe `ipx-` affirmait le contraire.

     `--blue-900` n'a plus aucun consommateur. Il reste ici pour que l'échelle
     ne soit pas trouée, et pour qu'on retrouve la valeur si l'ancien bleu
     revient un jour. */
  --blue-700:#1a5679; --blue-800:#144760; --blue-900:#0f3446;

  /* ── NEUTRES — PALETTE À L'ESSAI n° 1 : « ARDOISE AFFINÉE » ─────────────
     Deux reproches au jeu bleuté d'origine (#f4f7fa / #eaf0f6 / #dde5ee) :

     1. Le fond de page ne se distinguait presque pas des cartes — 16,37:1
        contre 17,60:1 sur la même encre. Un écart d'un vingtième : à l'œil,
        pas de fond ni de carte, une seule nappe blanche où la hiérarchie ne
        tenait plus qu'aux traits. Le fond descend donc d'un cran franc
        (15,74:1 contre 18,61:1) : la carte blanche redevient un objet POSÉ.
     2. Le bleu des neutres concurrençait celui de la marque. Il en reste ici
        un soupçon (les neutres sont froids, pas gris-caillou), mais assez peu
        pour que le #1f6a9b du logo se lise comme une intention et non comme
        la teinte ambiante.

     Le bleu du logo, lui, ne bouge pas — c'est tout le propos de cet essai :
     ce n'est pas la marque qui allait mal, c'est le support. */
  --ipx-n-50:#f8f9fb;  --ipx-n-100:#eaecf0; --ipx-n-200:#e1e4ea;
  --ipx-n-300:#d3d8e0; --ipx-n-400:#b8bfc9;

  /* Encre — resserrée sur le gris froid, et le cran clair assombri : sur un
     fond de page plus profond, l'ancien #646d79 tombait à 4,1:1. */
  --ipx-ink-900:#101318; --ipx-ink-500:#4b5462; --ipx-ink-400:#5c6472;

  /* Ardoise — les neutres du thème sombre */
  --ipx-slate-950:#0e1116; --ipx-slate-900:#151a22; --ipx-slate-850:#1b2230;
  --ipx-slate-800:#232c3b; --ipx-slate-700:#2f3947; --ipx-slate-600:#3d4859;
  --ipx-slate-300:#98a2b3; --ipx-slate-200:#c3cad6; --ipx-slate-100:#e7eaef;

  /* Teintes fonctionnelles — clair */
  --ipx-green-600:#187c47;  --ipx-green-100:#e8f5ee;  --ipx-green-300:#a8d9bc;
  --ipx-amber-600:#92610f;  --ipx-amber-100:#fdf3dc;  --ipx-amber-300:#e8c07a;
  --ipx-red-600:#c1372a;    --ipx-red-100:#fdefed;    --ipx-red-300:#f0b0aa;
  /* Catégories : le bleu est réservé à la marque, d'où teal, indigo et rose */
  --ipx-teal-600:#0f766e;   --ipx-teal-100:#e2f2f0;
  --ipx-violet-600:#6d28d9; --ipx-violet-100:#ede9fe;
  --ipx-indigo-600:#4338ca; --ipx-indigo-100:#eef0fd; --ipx-indigo-300:#c7c9f7;
  --ipx-indigo-700:#362da8;
  --ipx-orange-600:#c2440a; --ipx-orange-100:#fef0e6;
  --ipx-rose-600:#be185d;   --ipx-rose-100:#fdeaf2;
  /* Traits moyens, cités par le bloc de compatibilité des anciennes pages */
  --ipx-teal-300:#86c5c7; --ipx-violet-300:#c4b5fd; --ipx-orange-300:#f5b58a;

  /* Teintes fonctionnelles — sombre */
  --ipx-green-d-txt:#55cc8e;  --ipx-green-d-bg:#15291e;  --ipx-green-d-brd:#2c4c3a;
  --ipx-amber-d-txt:#efb149;  --ipx-amber-d-bg:#2a2114;  --ipx-amber-d-brd:#54452e;
  --ipx-red-d-txt:#eb7466;    --ipx-red-d-bg:#2d1917;    --ipx-red-d-brd:#58342f;
  --ipx-teal-d-txt:#4fb8ad;   --ipx-teal-d-bg:#0f2422;
  --ipx-violet-d-txt:#a98bf0; --ipx-violet-d-bg:#201b30;
  --ipx-indigo-d-txt:#8b84f0; --ipx-indigo-d-bg:#1b1a33; --ipx-indigo-d-brd:#3a3866;
  --ipx-indigo-d-solid:#4b41c4; --ipx-indigo-d-solid-hv:#3f36a6;
  --ipx-orange-d-txt:#ec8b54; --ipx-orange-d-bg:#2c1d14;
  --ipx-rose-d-txt:#ef6f9e;   --ipx-rose-d-bg:#2d1420;
}

/* ─────────────────────────────────────────────────────────────────────────
   2. TYPOGRAPHIE, ESPACEMENT, FORMES — invariants entre thèmes
   ───────────────────────────────────────────────────────────────────────── */
:root {
  --font-sans:'DM Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-mono:'DM Mono','SF Mono',ui-monospace,monospace;

  --text-micro:0.6875rem;  /* 11px — surtitres, en-têtes de tableau, badges */
  --text-xs:0.75rem;       /* 12px — métadonnées, aides, mono en tableau     */
  --text-sm:0.8125rem;     /* 13px — libellés de champ, texte secondaire     */
  --text-base:0.875rem;    /* 14px — corps par défaut                        */
  --text-md:1rem;          /* 16px — titres de carte                         */
  --text-lg:1.125rem;      /* 18px — sous-titre de section                   */
  --text-xl:1.375rem;      /* 22px — titre de page                           */
  --text-2xl:1.75rem;      /* 28px — valeur de KPI, total mis en avant       */

  --leading-tight:1.25; --leading-snug:1.45; --leading-normal:1.6;
  --weight-regular:400; --weight-medium:500; --weight-semibold:600; --weight-bold:700;
  --tracking-display:-0.02em; --tracking-wide:0.03em; --tracking-caps:0.09em;

  --space-1:0.25rem; --space-2:0.5rem;  --space-3:0.75rem; --space-4:1rem;
  --space-5:1.25rem; --space-6:1.5rem;  --space-8:2rem;    --space-10:2.5rem;
  --space-12:3rem;   --space-16:4rem;

  --radius-xs:4px; --radius-sm:6px; --radius-md:10px; --radius-lg:14px; --radius-pill:999px;

  --control-sm:2rem; --control-md:2.5rem; --control-lg:3rem;
  --row-height:2.75rem; --row-height-dense:2.25rem;

  --page-narrow:34rem; --page-form:52rem; --page-default:70rem; --page-wide:82rem;
  --sidenav-width:15rem;
  /* Hauteur de la barre supérieure, qui n'existe qu'en dessous de 48rem. Elle
     est un token parce que DEUX règles doivent s'accorder : la barre elle-même,
     et le décalage du bandeau d'endossement qui se colle juste dessous. */
  --topbar-height:3.25rem;

  --ease:cubic-bezier(.4,0,.2,1);
  --duration-fast:120ms; --duration:180ms; --duration-slow:260ms;

  /* --z-popover : un panneau accroché à un champ, AU-DESSUS d'une modale — celle
     où vit la liste avec recherche (05/10/2026). --z-dropdown reste sous
     l'overlay : un menu d'en-tête n'a pas à passer devant une modale. */
  --z-sticky:100; --z-sidenav:200; --z-dropdown:400; --z-overlay:500; --z-popover:600; --z-toast:900;
}

/* ─────────────────────────────────────────────────────────────────────────
   3. COUCHE SÉMANTIQUE — THÈME CLAIR (défaut)
   ───────────────────────────────────────────────────────────────────────── */
:root {
  color-scheme:light;

  --canvas:var(--ipx-n-100);
  --surface:#ffffff;
  --surface-sunken:var(--ipx-n-100);
  --surface-raised:#ffffff;
  --surface-hover:var(--ipx-n-100);
  --surface-active:var(--ipx-n-200);
  /* Le CREUX d'une case où l'on tape, dans un tableau de saisie. Il lui faut
     son propre cran : la carte est en `--surface`, les axes du tableau en
     `--surface-sunken`, et une case éditable doit se distinguer des DEUX —
     sinon on ne voit pas où l'on peut écrire. Plus bas que la surface dans les
     deux thèmes, comme un champ creusé et non un bloc posé. */
  --surface-inset:var(--ipx-n-50);

  --border:var(--ipx-n-300);
  --border-subtle:var(--ipx-n-200);
  --border-strong:var(--ipx-n-400);

  --text:var(--ipx-ink-900);
  --text-muted:var(--ipx-ink-500);
  --text-subtle:var(--ipx-ink-400);
  --text-inverse:#ffffff;

  /* Marque — le bleu PROFOND du logo. Il porte du blanc à 5,84:1. */
  --brand:var(--ipx-blue-600);
  --brand-hover:var(--blue-700);   /* inchangé — voir « hors marque » plus haut */
  --brand-active:var(--blue-800);  /* inchangé */
  --on-brand:#ffffff;
  --brand-tint:rgba(31,106,155,.07);
  --brand-tint-strong:rgba(31,106,155,.13);
  --brand-ring:rgba(31,106,155,.20);
  /* Le bord d'un tableau qui continue au-delà de l'écran. Il lui faut son
     propre cran, plus franc que `--brand-ring` : celui-là est calibré pour un
     anneau de focus posé SUR un champ qu'on regarde déjà, alors que celui-ci
     doit attirer l'œil vers un endroit où il n'est pas. */
  --scroll-edge:rgba(31,106,155,.42);

  /* Accent — l'AZUR du logo. Réservé au pictogramme et aux fonds profonds ;
     il ne porte jamais de petit texte (1,72:1 sur l'en-tête). */
  --accent:var(--ipx-blue-400);
  --accent-on-dark:var(--ipx-blue-300);

  /* ── EN-TÊTE DE CARTE ───────────────────────────────────────────────────
     Il était en bleu profond #144760 (`--ipx-blue-800` à l'époque, aujourd'hui
     `--blue-800`). Il passe à l'ardoise
     du chrome, comme la barre latérale et les toasts : le commanditaire ne veut
     plus voir ce bleu sombre dans l'interface.

     Ce que ça déplace, et qu'il faut savoir : l'en-tête plein reste la
     signature du SI — un devis, un dossier, une société le portent, un simple
     groupe de champs prend `--plain` — mais cette signature n'est plus une
     signature DE MARQUE. Le bleu du logo ne vit plus que là où il désigne
     quelque chose : une action (`--brand`), un lien, l'accent azur. C'est
     défendable, et même plus lisible — mais la règle 4 de CHARTE.md parle
     désormais d'un en-tête PLEIN, pas d'un en-tête bleu.

     L'encre secondaire passe en couleur pleine : une opacité ne se mesure pas
     à la lecture du fichier. */
  --header-bg:var(--ipx-slate-900);
  --on-header:#ffffff;                    /* 17,46:1 */
  --on-header-muted:#a7b0bf;              /* 7,99:1 — était blanc à 58 % */
  --header-border:transparent;

  /* ── BARRE LATÉRALE — LA MÊME DANS LES DEUX THÈMES ──────────────────────
     Elle était en bleu pétrole (#0f3446, alors `--ipx-blue-900`) en clair et en
     ardoise en sombre. Deux motifs pour l'unifier sur l'ardoise :

     1. Ce que le thème change, c'est la SURFACE DE TRAVAIL — le fond sur
        lequel on lit et on saisit. Le chrome qui l'entoure n'a pas de raison
        de basculer avec elle, et une barre bleu profond à côté de boutons
        bleus et d'en-têtes de carte bleus faisait concourir la marque avec
        elle-même. Neutre, la barre rend au bleu son sens : « voici l'action ».
     2. Le pétrole ne tenait pas ses contrastes. Mesuré : le titre de section
        était à 2,86:1 et l'azur du logo à 3,86:1 sur ce fond — les deux sous
        le seuil que cette charte s'impose. Sur l'ardoise, ils passent
        respectivement à 4,82:1 et 5,13:1.

     Les encres sont des couleurs PLEINES et non du blanc translucide : une
     opacité se mesure mal, et c'est ainsi qu'un titre de section à 34 % de
     blanc a pu passer sous le seuil sans que personne ne le voie. */
  --nav-bg:var(--ipx-slate-900);
  --nav-text:var(--ipx-slate-300);        /* 6,78:1 */
  --nav-text-active:#ffffff;              /* 17,46:1 */
  --nav-hover:rgba(255,255,255,.06);
  --nav-active:rgba(74,144,206,.18);      /* lavis azur — blanc à 13,63:1 dessus */
  --nav-section:#7e8797;                  /* 4,82:1 — le blanc à 34 % n'était qu'à 3,12:1 */
  --nav-border:var(--ipx-slate-800);

  /* Le toast est du chrome, comme la barre latérale : même ardoise, même
     motif. Il était le dernier élément en bleu pétrole, et une confirmation
     fugace posée dans la couleur de la marque revendiquait plus d'importance
     qu'elle n'en a. Blanc dessus : 17,46:1. */
  --toast-bg:var(--ipx-slate-900); --toast-fg:#ffffff; --toast-border:transparent;

  /* États. « info » pointe vers la marque : même voix, même couleur. */
  --success:var(--ipx-green-600); --success-bg:var(--ipx-green-100); --success-border:var(--ipx-green-300);
  --warning:var(--ipx-amber-600); --warning-bg:var(--ipx-amber-100); --warning-border:var(--ipx-amber-300);
  --danger:var(--ipx-red-600);    --danger-bg:var(--ipx-red-100);    --danger-border:var(--ipx-red-300);
  /* « info » a sa propre teinte : l'indigo. Le bleu de la marque dit « le
     produit vous parle » ou « l'action à faire » ; l'indigo dit « un fait à
     connaître ». Il partage sa teinte avec la famille Cybersécurité, comme
     --success partage exactement son vert avec Matériel : c'est la règle 2 —
     un état est un aplat, une catégorie est un point. La forme sépare. */
  --info:var(--ipx-indigo-600);   --info-bg:var(--ipx-indigo-100);   --info-border:var(--ipx-indigo-300);
  --neutral:var(--ipx-ink-500);   --neutral-bg:var(--ipx-n-100);     --neutral-border:var(--ipx-n-300);

  --success-solid:var(--ipx-green-600); --success-solid-hover:#136338;
  --warning-solid:var(--ipx-amber-600); --warning-solid-hover:#77500c;
  --danger-solid:var(--ipx-red-600);    --danger-solid-hover:#a12b20;
  --info-solid:var(--ipx-indigo-600);   --info-solid-hover:var(--ipx-indigo-700);
  --on-solid:#ffffff;

  /* Catégories métier — étiquettes, jamais des jugements */
  --cat-fixe:var(--ipx-teal-600);     --cat-fixe-bg:var(--ipx-teal-100);
  --cat-mobile:var(--ipx-violet-600); --cat-mobile-bg:var(--ipx-violet-100);
  --cat-internet:var(--ipx-amber-600);--cat-internet-bg:var(--ipx-amber-100);
  --cat-materiel:var(--ipx-green-600);--cat-materiel-bg:var(--ipx-green-100);
  --cat-cyber:var(--ipx-indigo-600);  --cat-cyber-bg:var(--ipx-indigo-100);  /* = --info, cf. règle 2 */
  --cat-install:var(--ipx-orange-600);--cat-install-bg:var(--ipx-orange-100);
  --cat-porta:var(--ipx-rose-600);    --cat-porta-bg:var(--ipx-rose-100);
  --cat-autre:var(--ipx-ink-400);     --cat-autre-bg:var(--ipx-n-200);

  /* La NATURE d'un montant (30/09/2026) — frais d'accès, mensuel, annuel.
     Une catégorie, pas un jugement : elle se lit en point ou en unité, jamais
     en aplat. Les couples sont ceux des catégories, donc déjà mesurés (texte
     ≥ 4,56:1 sur leur fond, ≥ 5,09:1 sur la surface). */
  --nature-fas:var(--ipx-orange-600);  --nature-fas-bg:var(--ipx-orange-100);
  --nature-mois:var(--ipx-teal-600);   --nature-mois-bg:var(--ipx-teal-100);
  --nature-an:var(--ipx-violet-600);   --nature-an-bg:var(--ipx-violet-100);

  /* Les ombres portaient la teinte du bleu pétrole disparu (#0f3446). Elles
     prennent l'encre : une ombre bleue sur un fond gris se lit comme un
     halo coloré. */
  --shadow-xs:0 1px 2px rgba(16,19,24,.04);
  --shadow-sm:0 1px 3px rgba(16,19,24,.06),0 1px 2px rgba(16,19,24,.04);
  --shadow-md:0 4px 16px rgba(16,19,24,.08),0 1px 3px rgba(16,19,24,.04);
  --shadow-lg:0 16px 48px rgba(16,19,24,.16),0 2px 8px rgba(16,19,24,.06);
  /* La seule ombre LATÉRALE : le bord d'une colonne figée, sous laquelle le
     tableau défile. Les quatre autres tombent vers le bas, et une ombre qui
     tombe ne dit pas qu'il passe quelque chose à côté. */
  --shadow-sticky:2px 0 6px -2px rgba(16,19,24,.14);
  --overlay-scrim:rgba(16,19,24,.50);

  --focus-ring:0 0 0 3px var(--brand-ring);
  --focus-border:var(--brand);
}

/* ─────────────────────────────────────────────────────────────────────────
   4. THÈME SOMBRE
   L'inversion à comprendre : en clair la marque est le bleu PROFOND et porte
   du blanc ; en sombre elle devient l'AZUR du logo et porte de l'encre
   sombre. Aucun composant ne voit ce basculement : ils citent --brand et
   --on-brand. Les ombres, elles, ne se lisent plus : la hiérarchie passe par
   la surface et le trait, et les tokens d'ombre s'effacent volontairement.
   ───────────────────────────────────────────────────────────────────────── */
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"]) { color-scheme:dark; }
}
:root[data-theme="dark"] { color-scheme:dark; }

@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"]) {
    --canvas:var(--ipx-slate-950);
    --surface:var(--ipx-slate-900);
    --surface-sunken:var(--ipx-slate-850);
    --surface-raised:var(--ipx-slate-850);
    --surface-hover:var(--ipx-slate-850);
    --surface-active:var(--ipx-slate-800);
    /* En sombre le creux descend franchement : c'est le seul cran disponible
       sous `--surface`, et c'est lui qui fait lire la case comme un champ. */
    --surface-inset:var(--ipx-slate-950);

    --border:var(--ipx-slate-700);
    --border-subtle:var(--ipx-slate-800);
    --border-strong:var(--ipx-slate-600);

    --text:var(--ipx-slate-100);
    --text-muted:var(--ipx-slate-300);
    --text-subtle:#838ea0;
    --text-inverse:var(--ipx-slate-950);

    /* La marque devient l'AZUR du logo : encre sombre par-dessus, 5,56:1 */
    --brand:var(--ipx-blue-400);
    --brand-hover:#6ba6da;
    --brand-active:#2f86ce;   /* sature au lieu de foncer : l'encre est sombre */
    --on-brand:var(--ipx-slate-950);
    --brand-tint:rgba(74,144,206,.12);
    --brand-tint-strong:rgba(74,144,206,.20);
    --brand-ring:rgba(74,144,206,.34);
    --scroll-edge:rgba(74,144,206,.52);

    --accent:var(--ipx-blue-300);
    --accent-on-dark:var(--ipx-blue-300);

    /* ⚠ PAS `--ipx-slate-900` ici : c'est déjà la valeur de `--surface` en
       sombre, donc l'en-tête serait invisible sur sa propre carte (1,00:1). Il
       prend le cran au-dessus, qui est le vocabulaire de superposition déjà
       utilisé par `--surface-active`. */
    --header-bg:var(--ipx-slate-800);
    --on-header:var(--ipx-slate-100);     /* 11,65:1 */
    --on-header-muted:var(--ipx-slate-300); /* 5,45:1 */
    --header-border:var(--ipx-slate-700);

    /* Rien pour la barre latérale : elle est identique dans les deux thèmes,
       donc déclarée une seule fois, en clair. La redéclarer ici, c'est
       s'exposer à ce que les deux copies divergent. */

    --toast-bg:var(--ipx-slate-800); --toast-fg:var(--ipx-slate-100); --toast-border:var(--ipx-slate-600);

    --success:var(--ipx-green-d-txt); --success-bg:var(--ipx-green-d-bg); --success-border:var(--ipx-green-d-brd);
    --warning:var(--ipx-amber-d-txt); --warning-bg:var(--ipx-amber-d-bg); --warning-border:var(--ipx-amber-d-brd);
    --danger:var(--ipx-red-d-txt);    --danger-bg:var(--ipx-red-d-bg);    --danger-border:var(--ipx-red-d-brd);
    --info:var(--ipx-indigo-d-txt);   --info-bg:var(--ipx-indigo-d-bg);   --info-border:var(--ipx-indigo-d-brd);
    --neutral:var(--ipx-slate-300);   --neutral-bg:var(--ipx-slate-850);  --neutral-border:var(--ipx-slate-700);

    --success-solid:#22774a; --success-solid-hover:#1c5f3b;
    --warning-solid:#8a5410; --warning-solid-hover:#70430c;
    --danger-solid:#c94a3c;  --danger-solid-hover:#ad3c30;
    --info-solid:var(--ipx-indigo-d-solid); --info-solid-hover:var(--ipx-indigo-d-solid-hv);
    --on-solid:#ffffff;

    --cat-fixe:var(--ipx-teal-d-txt);     --cat-fixe-bg:var(--ipx-teal-d-bg);
    --cat-mobile:var(--ipx-violet-d-txt); --cat-mobile-bg:var(--ipx-violet-d-bg);
    --cat-internet:var(--ipx-amber-d-txt);--cat-internet-bg:var(--ipx-amber-d-bg);
    --cat-materiel:var(--ipx-green-d-txt);--cat-materiel-bg:var(--ipx-green-d-bg);
    --cat-cyber:var(--ipx-indigo-d-txt);  --cat-cyber-bg:var(--ipx-indigo-d-bg);
    --cat-install:var(--ipx-orange-d-txt);--cat-install-bg:var(--ipx-orange-d-bg);
    --cat-porta:var(--ipx-rose-d-txt);    --cat-porta-bg:var(--ipx-rose-d-bg);
    --cat-autre:var(--ipx-slate-300);     --cat-autre-bg:var(--ipx-slate-800);

    --nature-fas:var(--ipx-orange-d-txt);  --nature-fas-bg:var(--ipx-orange-d-bg);
    --nature-mois:var(--ipx-teal-d-txt);   --nature-mois-bg:var(--ipx-teal-d-bg);
    --nature-an:var(--ipx-violet-d-txt);   --nature-an-bg:var(--ipx-violet-d-bg);

    --shadow-xs:none;
    --shadow-sm:0 1px 2px rgba(0,0,0,.4);
    --shadow-md:0 4px 16px rgba(0,0,0,.45);
    --shadow-lg:0 16px 48px rgba(0,0,0,.6);
    /* Plus marquée qu'en clair : sur fond sombre, une ombre légère ne se voit
       pas, et c'est elle qui dit que le tableau passe sous la colonne figée. */
    --shadow-sticky:2px 0 8px -2px rgba(0,0,0,.55);
    --overlay-scrim:rgba(0,0,0,.65);
  }
}

/* Bascule explicite — doit rejouer les mêmes tokens pour gagner sur le réglage
   système dans les deux sens. TOUTE modification se fait AUX DEUX ENDROITS. */
:root[data-theme="dark"] {
    --canvas:var(--ipx-slate-950);
    --surface:var(--ipx-slate-900);
    --surface-sunken:var(--ipx-slate-850);
    --surface-raised:var(--ipx-slate-850);
    --surface-hover:var(--ipx-slate-850);
    --surface-active:var(--ipx-slate-800);
    /* En sombre le creux descend franchement : c'est le seul cran disponible
       sous `--surface`, et c'est lui qui fait lire la case comme un champ. */
    --surface-inset:var(--ipx-slate-950);

    --border:var(--ipx-slate-700);
    --border-subtle:var(--ipx-slate-800);
    --border-strong:var(--ipx-slate-600);

    --text:var(--ipx-slate-100);
    --text-muted:var(--ipx-slate-300);
    --text-subtle:#838ea0;
    --text-inverse:var(--ipx-slate-950);

    /* La marque devient l'AZUR du logo : encre sombre par-dessus, 5,56:1 */
    --brand:var(--ipx-blue-400);
    --brand-hover:#6ba6da;
    --brand-active:#2f86ce;   /* sature au lieu de foncer : l'encre est sombre */
    --on-brand:var(--ipx-slate-950);
    --brand-tint:rgba(74,144,206,.12);
    --brand-tint-strong:rgba(74,144,206,.20);
    --brand-ring:rgba(74,144,206,.34);
    --scroll-edge:rgba(74,144,206,.52);

    --accent:var(--ipx-blue-300);
    --accent-on-dark:var(--ipx-blue-300);

    /* ⚠ PAS `--ipx-slate-900` ici : c'est déjà la valeur de `--surface` en
       sombre, donc l'en-tête serait invisible sur sa propre carte (1,00:1). Il
       prend le cran au-dessus, qui est le vocabulaire de superposition déjà
       utilisé par `--surface-active`. */
    --header-bg:var(--ipx-slate-800);
    --on-header:var(--ipx-slate-100);     /* 11,65:1 */
    --on-header-muted:var(--ipx-slate-300); /* 5,45:1 */
    --header-border:var(--ipx-slate-700);

    /* Rien pour la barre latérale : elle est identique dans les deux thèmes,
       donc déclarée une seule fois, en clair. La redéclarer ici, c'est
       s'exposer à ce que les deux copies divergent. */

    --toast-bg:var(--ipx-slate-800); --toast-fg:var(--ipx-slate-100); --toast-border:var(--ipx-slate-600);

    --success:var(--ipx-green-d-txt); --success-bg:var(--ipx-green-d-bg); --success-border:var(--ipx-green-d-brd);
    --warning:var(--ipx-amber-d-txt); --warning-bg:var(--ipx-amber-d-bg); --warning-border:var(--ipx-amber-d-brd);
    --danger:var(--ipx-red-d-txt);    --danger-bg:var(--ipx-red-d-bg);    --danger-border:var(--ipx-red-d-brd);
    --info:var(--ipx-indigo-d-txt);   --info-bg:var(--ipx-indigo-d-bg);   --info-border:var(--ipx-indigo-d-brd);
    --neutral:var(--ipx-slate-300);   --neutral-bg:var(--ipx-slate-850);  --neutral-border:var(--ipx-slate-700);

    --success-solid:#22774a; --success-solid-hover:#1c5f3b;
    --warning-solid:#8a5410; --warning-solid-hover:#70430c;
    --danger-solid:#c94a3c;  --danger-solid-hover:#ad3c30;
    --info-solid:var(--ipx-indigo-d-solid); --info-solid-hover:var(--ipx-indigo-d-solid-hv);
    --on-solid:#ffffff;

    --cat-fixe:var(--ipx-teal-d-txt);     --cat-fixe-bg:var(--ipx-teal-d-bg);
    --cat-mobile:var(--ipx-violet-d-txt); --cat-mobile-bg:var(--ipx-violet-d-bg);
    --cat-internet:var(--ipx-amber-d-txt);--cat-internet-bg:var(--ipx-amber-d-bg);
    --cat-materiel:var(--ipx-green-d-txt);--cat-materiel-bg:var(--ipx-green-d-bg);
    --cat-cyber:var(--ipx-indigo-d-txt);  --cat-cyber-bg:var(--ipx-indigo-d-bg);
    --cat-install:var(--ipx-orange-d-txt);--cat-install-bg:var(--ipx-orange-d-bg);
    --cat-porta:var(--ipx-rose-d-txt);    --cat-porta-bg:var(--ipx-rose-d-bg);
    --cat-autre:var(--ipx-slate-300);     --cat-autre-bg:var(--ipx-slate-800);

    --nature-fas:var(--ipx-orange-d-txt);  --nature-fas-bg:var(--ipx-orange-d-bg);
    --nature-mois:var(--ipx-teal-d-txt);   --nature-mois-bg:var(--ipx-teal-d-bg);
    --nature-an:var(--ipx-violet-d-txt);   --nature-an-bg:var(--ipx-violet-d-bg);

    --shadow-xs:none;
    --shadow-sm:0 1px 2px rgba(0,0,0,.4);
    --shadow-md:0 4px 16px rgba(0,0,0,.45);
    --shadow-lg:0 16px 48px rgba(0,0,0,.6);
    /* Plus marquée qu'en clair : sur fond sombre, une ombre légère ne se voit
       pas, et c'est elle qui dit que le tableau passe sous la colonne figée. */
    --shadow-sticky:2px 0 8px -2px rgba(0,0,0,.55);
    --overlay-scrim:rgba(0,0,0,.65);
}
