/* =============================================================================
   Carto — design tokens
   Charte graphique v1.0 · docs/charte-graphique.md
   Marque : pack technique A1.2 V6 · docs/assets-marque.md
   =============================================================================

   Ce fichier ne style rien. Il ne déclare que des valeurs, exposées **par
   rôle** et non par teinte (charte §13) : une page écrit
   `var(--carto-action-primary)`, jamais `#1558FF`. C'est ce qui permet de
   changer une intention de couleur en un point, et c'est ce qui rend le thème
   sombre possible sans dupliquer une feuille de style.

   ── La règle qui gouverne tout le reste ────────────────────────────────────
   Trois familles de couleurs doivent rester distinctes (charte §3.1) :

     1. l'identité Carto  — navigation, sélection, actions, liens ;
     2. les données métier — opérateurs, technologies, bandes ;
     3. les états          — succès, warning, erreur, hors ligne, signal.

   L'audit a montré cinq collisions entre ces familles dans l'ancien CSS : un
   badge 5G et un message d'erreur partageaient `#dc3545`, un badge 700 MHz
   partageait le bleu du bouton d'action. Les blocs ci-dessous sont séparés
   pour cette raison, et une valeur ne doit jamais être reprise d'un bloc à
   l'autre.

   ── Ce qui n'est chiffré nulle part ────────────────────────────────────────
   La charte nomme certaines couleurs sans les chiffrer (« vert », « orange /
   ambre », « gris neutre très léger », « bleu nuit très sombre »), et le pack
   de marque ne couvre que l'identité. Les états, les neutres et les familles
   métier sont donc dérivés de la palette Tailwind, dont la charte reprend déjà
   `#64748B` (slate-500) et un gris clair voisin de slate-100. Prendre la suite
   de cette famille garde les teintes cohérentes entre elles au lieu de les
   choisir une par une.

   Le bleu de marque, lui, n'en fait pas partie : `#1558FF` vient du symbole et
   n'a pas d'équivalent Tailwind. C'est sans conséquence — il n'appartient pas
   à la même famille que les états, et c'est précisément ce que le système
   cherche à garantir.

   Chaque écart est signalé par un commentaire « hors charte » ou « hors pack ».
   ========================================================================== */

:root {
    color-scheme: light dark;

    /* =========================================================================
       1 · MARQUE — pack technique A1.2 V6, `docs/usage.md`
       Ne pas consommer directement dans une page : passer par les rôles (§3).
       =========================================================================

       ⚠ Ces valeurs ne sont pas celles de la charte v1.0. Le pack officiel
       livré en août 2026 en donne d'autres, et le §40 de la charte place les
       assets vectoriels officiels au-dessus des planches — le pack tranche
       donc, et la charte a été corrigée en conséquence :

         Bleu nuit   #0D182A → #0D1321
         Bleu Carto  #2563EB → #1558FF
         Cyan réseau #00B8D9 → #00D4FF

       Le pack ajoute un bleu intermédiaire, qui n'existait pas : c'est l'arrêt
       médian du gradient du symbole. Il n'a pas de rôle d'interface.

       Ce qui n'a pas bougé : le gris ardoise et le blanc, identiques dans les
       deux documents. Et surtout, aucune couleur métier, d'état ou de signal
       n'est touchée — la séparation des familles est le point dur du système,
       elle ne dépend pas de la teinte exacte du bleu. */

    --carto-night:    #0D1321;   /* Bleu nuit           */
    --carto-blue:     #1558FF;   /* Bleu Carto          */
    --carto-mid-blue: #007AFF;   /* Bleu intermédiaire  */
    --carto-cyan:     #00D4FF;   /* Cyan réseau         */
    --carto-slate:    #64748B;   /* Gris ardoise        */
    --carto-mist:     #EDF2F7;   /* Gris clair          */
    --carto-white:    #FFFFFF;

    /* Nuances dérivées, nécessaires aux états d'interaction (survol, focus,
       surfaces teintées). Hors pack : il livre une identité, pas une échelle
       d'interface. Elles sont construites autour de #1558FF. */
    --carto-blue-700: #0F46D6;
    --carto-blue-800: #0B36A8;
    --carto-blue-050: #EBF1FF;
    --carto-cyan-700: #0A7C93;
    --carto-slate-900: #0F172A;
    --carto-slate-700: #334155;
    --carto-slate-400: #94A3B8;
    --carto-slate-200: #E2E8F0;
    --carto-slate-100: #F1F5F9;

    /* Gradient de marque — celui du symbole, aux trois arrêts du pack et non
       une interpolation à deux couleurs. Réservé à l'identité : ne pas en
       faire le fond des boutons ni des panneaux (charte §3.3). */
    --carto-gradient-brand: linear-gradient(180deg,
        var(--carto-blue) 0%,
        var(--carto-mid-blue) 58%,
        var(--carto-cyan) 100%);

    /* =========================================================================
       2 · TYPOGRAPHIE — charte §4
       ====================================================================== */

    /* Inter en tête, pile système derrière. Tant que les fichiers woff2 ne
       sont pas vendorisés dans /fonts (voir brand/README.md), la pile système
       prend le relais sans requête ratée. */
    --carto-font-sans: "Inter", "Inter var", system-ui, -apple-system,
                       "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --carto-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo,
                       Consolas, "Liberation Mono", monospace;

    --carto-text-display:   2rem;     /* 32 / 40 — Bold      */
    --carto-text-h1:        1.5rem;   /* 24 / 32 — SemiBold  */
    --carto-text-h2:        1.25rem;  /* 20 / 28 — SemiBold  */
    --carto-text-h3:        1rem;     /* 16 / 24 — SemiBold  */
    --carto-text-body:      1rem;     /* 16 / 24 — Regular   */
    --carto-text-secondary: 0.875rem; /* 14 / 20 — Regular   */
    --carto-text-small:     0.75rem;  /* 12 / 16 — métadonnées uniquement */

    --carto-leading-display:   2.5rem;
    --carto-leading-h1:        2rem;
    --carto-leading-h2:        1.75rem;
    --carto-leading-h3:        1.5rem;
    --carto-leading-body:      1.5rem;
    --carto-leading-secondary: 1.25rem;
    --carto-leading-small:     1rem;

    --carto-weight-regular:  400;
    --carto-weight-medium:   500;
    --carto-weight-semibold: 600;
    --carto-weight-bold:     700;

    /* =========================================================================
       3 · RÔLES — c'est ce que les pages consomment
       ====================================================================== */

    /* --- Identité -------------------------------------------------------- */
    --carto-brand-primary:   var(--carto-blue);
    --carto-brand-secondary: var(--carto-cyan);

    /* --- Fonds et surfaces ----------------------------------------------- */
    --carto-background-default:  var(--carto-mist);
    --carto-background-elevated: var(--carto-white);
    --carto-surface-default:     var(--carto-white);
    --carto-surface-secondary:   var(--carto-slate-100);
    /* Fond structurel sombre — navigation, pied de page. */
    --carto-surface-inverse:     var(--carto-night);
    /* Bloc plein qui doit se détacher : en-tête de tableau fort, pastille
       neutre, infobulle. En thème sombre, `surface-inverse` vaut exactement le
       fond de page — un `thead` peint avec lui n'avait plus aucun bord, et une
       pastille disparaissait en tant que forme tout en gardant, elle, un
       contraste de texte parfait. Aucune mesure ne voit ce défaut-là. */
    --carto-surface-strong:      var(--carto-night);

    /* Surface d'un panneau posé *sur la carte* (indicateur de zoom, mention
       d'attribution). Distincte de `surface-default` : elle est translucide,
       parce qu'un panneau cartographique doit laisser deviner le fond. */
    --carto-map-overlay-bg:   rgba(255, 255, 255, 0.92);
    --carto-map-overlay-text: var(--carto-night);

    /* Survol d'une ligne ou d'une surface cliquable. Distinct de
       `surface-secondary`, qui est un fond *statique* : sans token dédié, le
       survol des tableaux reprenait `--carto-blue-050`, un bleu très clair qui
       allumait une ligne blanche au milieu d'un tableau sombre. */
    --carto-surface-hover: var(--carto-blue-050);

    /* Chevron des `<select>` et inversion des icônes monochromes que Bootstrap
       livre en SVG encodé. La couleur est cuite dans l'URI : elle ne peut pas
       venir d'un `var()`, donc l'asset lui-même est un token. */
    --carto-select-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%230D1321' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    --carto-icon-invert: none;

    /* --- Textes ----------------------------------------------------------- */
    --carto-text-primary:   var(--carto-night);
    /* Pas `--carto-slate` directement : mesuré au navigateur, le gris ardoise
       de la charte donne 4,23:1 sur blanc — sous les 4,5:1 de WCAG AA, que la
       charte §10 pose comme minimum. Le gris ardoise reste la couleur de la
       palette ; le **texte** secondaire descend d'un cran pour être lisible.
       C'est exactement la raison d'être d'un token de rôle. */
    --carto-text-secondary-color: #475569;
    /* Pas `--carto-slate-400` : mesuré à 2,3:1 sur les surfaces désactivées.
       Un élément inactif n'est pas dispensé d'être lu — la désactivation se
       dit par le fond, le curseur et `aria-disabled`, pas par l'illisibilité. */
    --carto-text-disabled:  #5B6A7D;
    --carto-text-on-brand:  var(--carto-white);
    --carto-text-on-inverse: var(--carto-white);

    /* --- Bordures --------------------------------------------------------- */
    /* Hors charte : « gris neutre très léger » n'est pas chiffré. */
    --carto-border-default: var(--carto-slate-200);
    --carto-border-strong:  var(--carto-slate-400);
    --carto-border-focus:   var(--carto-blue);

    /* --- Actions ---------------------------------------------------------- */
    --carto-action-primary:       var(--carto-blue);
    --carto-action-primary-hover: var(--carto-blue-700);
    --carto-action-primary-active: var(--carto-blue-800);
    --carto-action-on-primary:    var(--carto-white);
    --carto-action-secondary:     transparent;
    --carto-action-secondary-border: var(--carto-border-strong);
    --carto-action-secondary-text: var(--carto-night);
    --carto-action-disabled-bg:   var(--carto-slate-200);
    /* Pas `--carto-slate-400` : mesuré, il donnait 2,1:1 sur le fond désactivé.
       Un contrôle inactif reste signalé par son fond et par son curseur — il
       n'a aucune raison d'être en plus illisible. */
    --carto-action-disabled-text: var(--carto-text-secondary-color);
    /* Anneau de focus — charte §16 et §31 (focus clavier obligatoire). */
    --carto-focus-ring: 0 0 0 3px rgba(21, 88, 255, 0.35);

    /* --- Composantes RVB -------------------------------------------------- */
    /* Bootstrap compose plusieurs de ses couleurs dans des `rgba()` et attend
       donc un triplet, pas une couleur : `a { color: rgba(var(--bs-link-color-rgb), …) }`.
       Un triplet ne peut pas être dérivé d'une couleur en CSS — il doit être
       déclaré. Sans ces quatre-là, les liens, le texte de corps et les fonds
       composés restaient figés sur la valeur claire, quel que soit le thème :
       c'est ce qui laissait les liens en #1558FF sur fond nuit. */
    --carto-action-primary-rgb:       21, 88, 255;
    --carto-action-primary-hover-rgb: 15, 70, 214;
    --carto-action-on-primary-rgb:    255, 255, 255;
    --carto-text-primary-rgb:         13, 19, 33;
    --carto-background-default-rgb:   237, 242, 247;

    /* =========================================================================
       4 · ÉTATS — charte §3.4
       Famille distincte des opérateurs (§5) et du signal (§6).
       Hors charte : les hex ne sont pas donnés, seulement les teintes.
       ====================================================================== */

    --carto-status-success:    #16A34A;
    --carto-status-success-text: #166534;
    --carto-status-success-bg: #DCFCE7;
    --carto-status-warning:    #D97706;
    --carto-status-warning-text: #92400E;
    --carto-status-warning-bg: #FEF3C7;
    --carto-status-error:      #DC2626;
    --carto-status-error-text:   #991B1B;
    --carto-status-error-bg:   #FEE2E2;
    --carto-status-info:       var(--carto-blue);
    --carto-status-info-text:  #0B36A8;
    --carto-status-info-bg:    var(--carto-blue-050);
    --carto-status-offline:    var(--carto-slate);
    --carto-status-offline-text: #334155;
    --carto-status-offline-bg: var(--carto-slate-100);

    /* « Live : vert ou cyan selon le contexte » (charte §3.4) est ambigu dans
       un document qui exige par ailleurs qu'une couleur n'ait qu'un sens.
       Tranché : le cyan pour le live, le vert reste le succès. */
    --carto-data-live:    var(--carto-cyan);
    --carto-data-live-text: #06414D;
    --carto-data-live-bg: #CFF7FD;

    /* =========================================================================
       5 · CARTOGRAPHIE — charte §7
       ====================================================================== */

    --carto-map-user-position:        var(--carto-blue);
    --carto-map-user-position-halo:   rgba(21, 88, 255, 0.18);
    --carto-map-user-position-ring:   var(--carto-white);
    /* Cercle de précision GPS : très transparent, il ne doit pas masquer le
       fond de carte. */
    --carto-map-accuracy-fill:        rgba(21, 88, 255, 0.08);
    --carto-map-accuracy-stroke:      rgba(21, 88, 255, 0.45);
    --carto-map-selection:            var(--carto-blue);
    --carto-map-selection-ring:       rgba(21, 88, 255, 0.30);
    --carto-map-track:                var(--carto-cyan);

    /* Clusters — charte §7. La couleur reste celle de Carto : la taille d'un
       cluster est portée par son diamètre et par son nombre, jamais par une
       échelle vert → rouge, qui est celle du signal. */
    --carto-map-cluster-bg:     rgba(21, 88, 255, 0.85);
    --carto-map-cluster-ring:   rgba(21, 88, 255, 0.25);
    --carto-map-cluster-text:   var(--carto-white);

    /* =========================================================================
       6 · SIGNAL — charte §3.6
       Grandeur continue, distincte de l'opérateur. Les seuils en dBm sont dans
       la charte ; ces couleurs n'expriment que le rang.
       ====================================================================== */

    --carto-signal-excellent: #15803D;
    --carto-signal-good:      #65A30D;
    --carto-signal-medium:    #CA8A04;
    --carto-signal-weak:      #EA580C;
    --carto-signal-critical:  #B91C1C;
    --carto-signal-unknown:   var(--carto-slate-400);

    /* ── Relief radio — Web 0.5.2 ────────────────────────────────────────────
       Les classes du niveau reçu interpolé portent des noms de **grandeur**
       (« très fort ») et non de rang de charte (« excellent ») : la mesure est
       une puissance reçue, elle ne dit rien du débit ni de la qualité de
       service, et « excellent » l'aurait promis.

       Aucune couleur n'est inventée ici. Les cinq classes reprennent les cinq
       rangs de signal ci-dessus, dans le même ordre vert → rouge. Ce sont des
       alias, pour que la palette puisse évoluer sans toucher au classement
       radio — dont la source unique est `inc/radio_signal_scale.inc.php`.

       Elles ne basculent pas en thème sombre, comme le reste de la palette de
       données : le fond de carte est le même dans les deux thèmes, et une
       échelle qui changerait de teinte cesserait d'être comparable d'une
       capture à l'autre. */
    --carto-signal-very-strong: var(--carto-signal-excellent);
    --carto-signal-strong:      var(--carto-signal-good);
    --carto-signal-very-weak:   var(--carto-signal-critical);

    /* Opacité des zones remplies. Une seule valeur pour les cinq classes :
       moduler l'opacité par classe ajouterait une seconde dimension visuelle à
       une donnée qui n'en a qu'une, et une zone faible paraîtrait alors
       « moins certaine » qu'une zone forte. Elle ne l'est pas.

       0,38 est le réglage retenu à la recette : les rues, les points de mesure
       et les marqueurs de site restent lisibles au travers, et la teinte reste
       identifiable sur les fonds clairs comme sur les fonds chargés. */
    --carto-signal-band-opacity: 0.38;

    /* ── Rôle d'une observation — contour, jamais remplissage ────────────────

       Le remplissage d'un point de mesure dit son **niveau de signal**, et rien
       d'autre. Son contour dit son **rôle radio**. Deux questions sans rapport :
       une cellule servante à −112 dBm existe, et doit rester rouge.

       Ces trois teintes sont donc choisies pour se détacher des cinq classes de
       l'échelle de signal — vert, jaune, orange, rouge — sans en devenir une
       sixième. Aucune n'appartient à cette famille, et aucune n'est une couleur
       d'opérateur.

       Comme le reste de la palette de données, elles ne basculent pas en thème
       sombre : le fond de carte est le même dans les deux thèmes, et un contour
       qui changerait de teinte cesserait d'être comparable d'une capture à
       l'autre.

       ⚠ La couleur ne porte jamais seule la distinction : chaque rôle diffère
       aussi par l'épaisseur du contour, le rayon du marqueur et l'opacité, et la
       porteuse secondaire par un tiret. C'est ce qui la maintient lisible en
       daltonisme, en impression et sur un écran mal calibré. La table de
       référence est `radio_role_map_styles()`, côté serveur.

       ── Pourquoi ces trois-là, et pas des teintes « de rôle » ────────────────

       Un premier jeu avait été choisi sur l'identité — cyan profond pour la
       servante, violet pour la voisine. Mesuré ensuite contre les cinq
       remplissages, le cyan profond ne donnait que **1,11:1 sur le vert** et
       1,16:1 sur le rouge : le contour de la servante disparaissait exactement
       sur les deux remplissages qui comptent le plus. Une teinte choisie pour
       son sens, invisible là où on la regarde.

       Les cinq classes de signal occupent le **milieu** de l'échelle de
       luminance. Un contour qui s'en détache doit donc aller à un extrême — très
       clair ou très sombre —, et aucune couleur ne peut à la fois trancher sur
       ces remplissages et sur les deux fonds de page. C'est un fait de
       colorimétrie, pas un compromis : le contour d'un marqueur n'a pas à
       contraster avec la page, il entoure son propre remplissage, et c'est ce
       remplissage qui tranche sur le fond.

       Le jeu retenu place donc la servante à un extrême et la voisine à
       l'autre. Mesures (rapport de contraste, minimum sur les cinq classes plus
       le remplissage neutre) :

           servante  ≥ 2,82   ·  voisine ≥ 2,32   ·  inconnu ≥ 2,76
           servante / voisine : 14,4:1

       Ce dernier chiffre est le plus important : c'est lui qui fait qu'une
       servante et une voisine restent séparées en niveaux de gris, en
       impression et pour un daltonien. */

    /* Presque blanc, très légèrement cyan : l'évidence principale. La pointe de
       cyan garde l'identité du rôle, la clarté fait le travail — elle tranche
       sur les cinq remplissages, du vert foncé au rouge. */
    --carto-role-serving:   #ECFEFF;
    /* Violet très sombre pour la voisine, à l'autre extrémité de l'échelle.
       Même famille que le trait d'association de vérité terrain, qui ne
       représente lui non plus aucune grandeur physique — ici « vue depuis »,
       pas « sert ». */
    --carto-role-neighbour: #3B0764;
    /* Ardoise très sombre : ne rien affirmer. Tout l'historique antérieur au
       schéma radio v11 est ici, et son rôle n'est pas reconstituable.

       Elle est proche de la voisine en luminance (1,19:1), et c'est assumé : les
       deux sont des rôles **non porteurs de décision**, et ce sont l'épaisseur
       (1,0 contre 1,5 px), le rayon (3,0 contre 3,5) et l'opacité (0,55 contre
       0,70) qui les séparent. La distinction qui devait être franche — servante
       contre le reste — l'est à 14:1. */
    --carto-role-unknown:   var(--carto-slate-900);

    /* ── Qualité de localisation — halo d'incertitude ────────────────────────
       Ce jeton ne peint aucun marqueur : il ne sert qu'au **halo** dessiné
       autour d'une observation dont la précision déclarée dépasse le seuil
       d'exploitation. Il ne représente donc ni un rôle, ni un niveau de signal,
       ni une décision — seulement une incertitude de position.

       Ambre, et non rouge : une observation imprécise n'est pas une erreur, ni
       une mesure fausse. Elle est parfaitement valide et conservée ; c'est
       seulement sa position qui ne permet pas de conclure. Le rouge de
       `--carto-status-danger` aurait dit « défaut », ce qui est faux, et
       l'aurait rangée avec les états d'erreur.

       Le halo n'est jamais seul à porter l'information : il est une géométrie
       — un cercle absent des observations exploitables — et le marqueur qu'il
       entoure est atténué. En niveaux de gris, à l'impression et pour un
       daltonien, c'est la présence du cercle qui distingue, pas sa teinte. */
    --carto-observation-imprecise: var(--carto-status-warning);

    /* ── Vérité terrain — Web 0.5.3 ──────────────────────────────────────────
       Le site confirmé par un humain n'est pas une donnée radio : c'est une
       décision. Il ne prend donc ni une couleur d'opérateur, ni une couleur de
       l'échelle de signal — il aurait paru en être une valeur.

       Le vert de validation est celui des états, pas celui de l'échelle radio :
       `--carto-signal-very-strong` dit « niveau reçu élevé », ce qui n'a aucun
       rapport avec « ce site est le bon ». Deux familles, deux sens, et la
       charte §3.1 interdit de les confondre — c'est pourquoi le marqueur porte
       aussi une forme et une coche, et ne tient jamais à sa seule teinte. */
    --carto-gt-confirmed:      var(--carto-status-success);
    --carto-gt-confirmed-ring: var(--carto-white);
    /* Encre de la coche. **Pas blanc** : mesuré au navigateur par la gate de
       contraste, blanc sur ce vert ne donne que 3,3:1, sous le minimum AA de
       4,5. Le bleu nuit y tient 5,8:1. C'est la convention que `carto.css`
       applique déjà aux rangs de signal — les verts foncés prennent du blanc,
       les verts moyens prennent l'encre sombre. */
    --carto-gt-confirmed-ink:  var(--carto-night);
    --carto-gt-uncertain:      var(--carto-status-warning);
    /* Un candidat écarté reste à l'écran — c'est un exemple négatif, et sans
       exemples négatifs un modèle qui répond « oui » partout paraîtrait
       parfait. Il passe au second plan, il ne disparaît pas. */
    --carto-gt-rejected:       var(--carto-slate-400);

    /* Le trait d'association. Il relie l'estimation au site validé et ne
       représente **rien** de physique : ni faisceau, ni azimut, ni propagation.
       Il est donc violet — aucune autre couche de la carte ne l'emploie — et
       fortement discontinu, pour ne ressembler ni à une route, ni à une
       orientation d'antenne, ni à une isoligne. */
    /* Résultats de la recherche élargie : des propositions, ni des candidats
       générés ni une décision. Violet clair, distinct du trait d'association. */
    --carto-candidate-search:  #A78BFA;

    --carto-gt-link:           #7C3AED;
    --carto-gt-link-dash:      10 6;

    /* Atténuation des candidats non retenus quand une confirmation existe.
       Ils restent lisibles et cliquables : ils servent l'audit, la révision et
       le futur corpus de faux positifs. */
    --carto-gt-dimmed-opacity: 0.45;

    /* Encre des isolignes, tracées **par-dessus** les zones. Un bleu nuit
       plutôt qu'un noir pur : il se détache des cinq teintes de l'échelle sans
       en devenir une sixième. Identique dans les deux thèmes, pour la même
       raison que les zones. */
    --carto-contour-line: var(--carto-slate-900);

    /* =========================================================================
       7 · DONNÉES MÉTIER — opérateurs
       ====================================================================== */

    /* Couleurs de marque réelles des opérateurs, décision du 10/08/2026 :
       elles restent reconnaissables sur le terrain. Elles sont désormais la
       **source unique** pour le Web et pour Android (CartoColors), qui
       divergeaient sur les quatre.

       ⚠ Dette assumée et documentée : `--carto-operator-digi` est un bleu, à
       faible distance du bleu Carto — une couleur de données qui empiète sur
       la couleur d'identité, ce que la charte §3.1 interdit. Conservé tel quel
       sur décision explicite ; à revoir si la confusion se constate à l'usage.

       ⚠ MIROIR de CartoColors dans carto-android (ui/theme/Theme.kt) et de
       inc/belgium_common.inc.php. Toute modification se fait des trois côtés. */
    --carto-operator-proximus: #5C2D91;
    --carto-operator-orange:   #FF7902;
    --carto-operator-telenet:  #FCC120;
    --carto-operator-digi:     #002BFF;
    --carto-operator-sncb:     #1F2937;
    --carto-operator-multi:    #0F766E;  /* site multi-opérateurs */
    --carto-operator-unknown:  var(--carto-slate);

    /* Régions — quatrième famille de données, jusqu'ici écrite nulle part.
       `belgium_coverage` peignait ses trois régions en inline, avec les
       couleurs d'état de Bootstrap ; les valeurs sont reprises telles quelles
       pour ne pas changer une légende que les utilisateurs connaissent.

       ⚠ Dette assumée, sur le modèle de `--carto-operator-digi` : l'ambre et le
       vert empiètent sur la famille des états (charte §3.1). Le nommer est déjà
       la moitié du travail — la teinte se décidera séparément.

       L'encre, elle, est corrigée : la Wallonie était écrite en blanc sur son
       vert, soit 3,3:1. */
    --carto-region-ibge:          #FFC107;
    --carto-region-lne:           #0DCAF0;
    --carto-region-wallonie:      #198754;
    --carto-region-unknown:       var(--carto-slate);

    /* Variantes « temporaire » (permis en instruction) : même teinte, désaturée.
       Reprend le principe des anciennes classes `-temp`. */
    --carto-operator-proximus-temp: #A288C4;
    --carto-operator-orange-temp:   #F6B983;
    --carto-operator-telenet-temp:  #F8E1A0;
    --carto-operator-digi-temp:     #8A9DFA;

    /* =========================================================================
       8 · DONNÉES MÉTIER — technologies et bandes
       Aucune de ces valeurs n'appartient aux familles « état » ou « signal ».
       ====================================================================== */

    /* Deux rampes ordonnées, dans deux zones de teinte que rien d'autre
       n'occupe : le bleu et le cyan appartiennent à la marque, le vert,
       l'ambre et le rouge à l'échelle de signal et aux états. Il reste le
       violet et la sarcelle — les bandes prennent l'un, les technologies
       l'autre.

       Une rampe plutôt que des couleurs indépendantes : « 2600 » se lit
       comme plus haut que « 900 » avant même d'avoir lu le nombre. */

    /* Technologies — sarcelle, 2G mis à part en gris-brun : c'est la seule
       génération qui ne porte pas de données modernes. */
    --carto-tech-2g: #57534E;
    --carto-tech-3g: #115E59;
    --carto-tech-4g: #0F766E;
    --carto-tech-5g: #0D9488;

    /* Bandes — violet du grave à l'aigu, puis magenta pour les hautes. */
    --carto-band-700:     #4C1D95;
    --carto-band-800:     #5B21B6;
    --carto-band-900:     #6D28D9;
    --carto-band-1400:    #7C3AED;
    --carto-band-1800:    #9333EA;
    --carto-band-2100:    #A21CAF;
    --carto-band-2600:    #D946EF;
    --carto-band-3500:    #F0ABFC;
    --carto-band-generic: var(--carto-slate);

    /* =========================================================================
       9 · ESPACEMENT — charte §5, grille de 4
       ====================================================================== */

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

    /* =========================================================================
       10 · RAYONS — charte §5
       ====================================================================== */

    --carto-radius-field:  8px;
    --carto-radius-button: 8px;
    --carto-radius-card:   12px;
    --carto-radius-panel:  16px;
    --carto-radius-chip:   999px;

    /* =========================================================================
       11 · ÉLÉVATIONS — charte §5 (« discrètes »), valeurs hors charte
       Niveau 0 = pas d'ombre : c'est le défaut des cartes dans une page.
       ====================================================================== */

    --carto-elevation-0: none;
    --carto-elevation-1: 0 1px 2px rgba(13, 24, 42, 0.06),
                         0 1px 3px rgba(13, 24, 42, 0.08);
    --carto-elevation-2: 0 2px 4px rgba(13, 24, 42, 0.06),
                         0 4px 12px rgba(13, 24, 42, 0.10);
    --carto-elevation-3: 0 8px 24px rgba(13, 24, 42, 0.16);

    /* =========================================================================
       12 · MOTION — charte §11, « courtes et fonctionnelles »
       ====================================================================== */

    --carto-motion-fast: 120ms;
    --carto-motion-base: 180ms;
    --carto-motion-slow: 260ms;
    --carto-motion-ease: cubic-bezier(0.2, 0, 0.2, 1);
}

/* =============================================================================
   THÈME SOMBRE — charte §9
   Même hiérarchie, exactement : seuls les rôles de surface, de texte et de
   bordure changent. Les couleurs métier (opérateurs, bandes, technologies) ne
   changent pas — elles portent du sens, pas une ambiance.

   Hors charte : « bleu nuit très sombre » n'est pas chiffré. Le fond descend
   sous `#0D1321`, qui devient la surface des cartes — « légèrement plus claire
   que le fond », comme demandé.

   Deux sélecteurs, volontairement : la préférence système par défaut, et un
   `data-carto-theme` qui doit pouvoir gagner dans les deux sens le jour où un
   sélecteur de thème est ajouté.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
    :root:not([data-carto-theme="light"]) {
        --carto-background-default:  #070E1A;
        --carto-background-elevated: #0D1321;
        --carto-surface-default:     #0D1321;
        --carto-surface-secondary:   #152238;
        --carto-surface-inverse:     #070E1A;
        --carto-surface-strong:      #1B2740;

        /* Un panneau posé sur la carte s'assombrit avec le thème : une pastille
           blanche translucide au-dessus d'un fond de carte sombre était le
           défaut le plus visible du mode sombre. */
        --carto-map-overlay-bg:   rgba(13, 19, 33, 0.92);
        --carto-map-overlay-text: #E8EDF5;
        --carto-surface-hover:    #182B4D;
        --carto-select-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23E8EDF5' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
        --carto-icon-invert: invert(1) grayscale(100%) brightness(1.8);

        --carto-text-primary:         #E8EDF5;
        --carto-text-secondary-color: #9AA8BD;
        --carto-text-disabled:        #8493A8;

        --carto-border-default: #1E2C45;
        --carto-border-strong:  #334155;

        --carto-action-primary-rgb:       76, 130, 255;
        --carto-action-primary-hover-rgb: 123, 164, 255;
        --carto-action-on-primary-rgb:    0, 20, 73;
        --carto-text-primary-rgb:         232, 237, 245;
        --carto-background-default-rgb:   7, 14, 26;

        /* Le bleu Carto pur manque de contraste sur fond très sombre : on
           l'éclaircit pour les actions, sans changer la teinte. */
        --carto-action-primary:        #4C82FF;
        --carto-action-primary-hover:  #7BA4FF;
        --carto-action-primary-active: #A5C2FF;
        /* Le texte posé sur le bleu s'inverse avec le thème. Mesuré au
           navigateur : blanc sur ce bleu éclairci ne donne que 3,5:1. Ce n'est
           pas un détail de bouton — la navigation active emploie le même
           couple. */
        --carto-action-on-primary:     #001449;
        --carto-action-secondary-text: #E8EDF5;
        --carto-action-disabled-bg:    #1E2C45;
        --carto-action-disabled-text:  var(--carto-text-secondary-color);

        --carto-status-success-bg: #052E16;
        --carto-status-warning-bg: #422006;
        --carto-status-error-bg:   #450A0A;
        --carto-status-info-bg:    #172554;
        --carto-status-offline-bg: #152238;
        --carto-data-live-bg:      #083344;

        /* Les couleurs de texte des états s'inversent : en thème clair elles
           descendent sous la teinte vive, ici elles montent au-dessus. Sans
           cette reprise, un état gardait son texte foncé sur son fond foncé —
           illisible, et invisible à la relecture d'une feuille claire. */
        --carto-status-success-text: #86EFAC;
        --carto-status-warning-text: #FCD34D;
        --carto-status-error-text:   #FCA5A5;
        --carto-status-info-text:    #A9C4FF;
        --carto-status-offline-text: #CBD5E1;
        --carto-data-live-text:      #A5F3FC;

        /* Le cyan ne doit pas devenir fluorescent (charte §9) : sur fond
           sombre il est légèrement rabattu plutôt qu'éclairci. */
        --carto-data-live: #35C6E8;

        --carto-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.40);
        --carto-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.40),
                             0 4px 12px rgba(0, 0, 0, 0.36);
        --carto-elevation-3: 0 8px 24px rgba(0, 0, 0, 0.50);
    }
}

:root[data-carto-theme="dark"] {
    --carto-background-default:  #070E1A;
    --carto-background-elevated: #0D1321;
    --carto-surface-default:     #0D1321;
    --carto-surface-secondary:   #152238;
    --carto-surface-inverse:     #070E1A;
    --carto-surface-strong:      #1B2740;

    --carto-map-overlay-bg:   rgba(13, 19, 33, 0.92);
    --carto-map-overlay-text: #E8EDF5;
    --carto-surface-hover:    #182B4D;
    --carto-select-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23E8EDF5' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    --carto-icon-invert: invert(1) grayscale(100%) brightness(1.8);

    --carto-text-primary:         #E8EDF5;
    --carto-text-secondary-color: #9AA8BD;
    --carto-text-disabled:        #8493A8;

    --carto-border-default: #1E2C45;
    --carto-border-strong:  #334155;

    --carto-action-primary-rgb:       76, 130, 255;
    --carto-action-primary-hover-rgb: 123, 164, 255;
    --carto-action-on-primary-rgb:    0, 20, 73;
    --carto-text-primary-rgb:         232, 237, 245;
    --carto-background-default-rgb:   7, 14, 26;

    --carto-action-primary:        #4C82FF;
    --carto-action-primary-hover:  #7BA4FF;
    --carto-action-primary-active: #A5C2FF;
    --carto-action-on-primary:     #001449;
    --carto-action-secondary-text: #E8EDF5;
    --carto-action-disabled-bg:    #1E2C45;
    --carto-action-disabled-text:  var(--carto-text-secondary-color);

    --carto-status-success-bg: #052E16;
    --carto-status-warning-bg: #422006;
    --carto-status-error-bg:   #450A0A;
    --carto-status-info-bg:    #172554;
    --carto-status-offline-bg: #152238;
    --carto-data-live-bg:      #083344;

    --carto-status-success-text: #86EFAC;
    --carto-status-warning-text: #FCD34D;
    --carto-status-error-text:   #FCA5A5;
    --carto-status-info-text:    #A9C4FF;
    --carto-status-offline-text: #CBD5E1;
    --carto-data-live-text:      #A5F3FC;
    --carto-data-live:         #35C6E8;

    --carto-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.40);
    --carto-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.40),
                         0 4px 12px rgba(0, 0, 0, 0.36);
    --carto-elevation-3: 0 8px 24px rgba(0, 0, 0, 0.50);
}

/* =============================================================================
   MOTION RÉDUITE — charte §31
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    :root {
        --carto-motion-fast: 0ms;
        --carto-motion-base: 0ms;
        --carto-motion-slow: 0ms;
    }
}
