/* ═══════════════════════════════════════════════════════════════════════════
   GeoGardien — jetons de conception
   ═══════════════════════════════════════════════════════════════════════════

   Source unique des décisions visuelles. Chargé AVANT app.css, qui n'y puise
   que des variables et n'écrit plus aucune couleur en dur.

   ── POURQUOI CE FICHIER EXISTE ────────────────────────────────────────────
   Trois défauts mesurés dans l'ancien CSS le rendaient nécessaire :

   1. DEUX systèmes de jetons parallèles cohabitaient (`--encre` / `--pil-encre`,
      `--bord` / `--pil-bord`…) avec des valeurs DIFFÉRENTES pour la même
      intention. La page de pilotage ne s'accordait pas au reste de
      l'application, sans que personne ne l'ait décidé.

   2. 60 couleurs écrites en dur hors jetons, dont le vert de marque #14532d
      dans 7 règles. Or le moteur white-label ne surchargeait QUE deux
      variables : le ministère, dont la marque est bleue (#005b88), voyait
      donc des verts résiduels sur ses écrans. Le défaut était ACTIF en
      production, pas théorique.

   3. Onze valeurs de rayon distinctes, pour trois intentions.

   ── CE QUI DÉPEND DE LA MARQUE, ET CE QUI N'EN DÉPEND PAS ─────────────────
   Distinction structurante de ce fichier :

   • Les jetons `--marque-*` sont DÉRIVÉS de la couleur du tenant, calculés
     côté serveur par Marque::palette() et injectés dans <style>. Un tenant
     change de couleur, toute l'échelle suit.

   • Les jetons `--etat-*` PORTENT DU SENS MÉTIER et ne suivent jamais la
     marque. Un site critique doit être rouge chez tous les clients : laisser
     une charte graphique repeindre une alerte serait une faute, pas une
     personnalisation.

   Tous les contrastes ci-dessous ont été mesurés sur les deux marques réelles
   en service (vert #14532d, bleu #005b88) : aucun ne descend sous WCAG AA,
   la plupart atteignent AAA.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Typographie ────────────────────────────────────────────────────────────
   BAHNSCHRIFT CONDENSED, demandée pour toute l'application.

   ── CE QU'IL FAUT SAVOIR ──────────────────────────────────────────────────
   Bahnschrift est une police SYSTÈME DE WINDOWS. Elle n'existe ni sur Android,
   ni sur iOS, ni sur macOS, ni sur Linux, et sa licence Microsoft interdit de
   l'embarquer sur un site — impossible donc de la vendorer comme les autres.

   Or l'application est consultée en Côte d'Ivoire, majoritairement depuis des
   téléphones Android : la demander seule aurait donné le dessin voulu sur les
   postes Windows, et une police système quelconque partout ailleurs — c'est-à-
   dire chez la plupart des utilisateurs.

   ── LA RÉPONSE RETENUE ────────────────────────────────────────────────────
   1. Bahnschrift d'abord, sous ses DEUX formes de sélection : le nom d'instance
      « Bahnschrift Condensed » et la famille « Bahnschrift » associée à
      font-stretch (posé sur body). Les deux ont été mesurées comme
      fonctionnelles ; le premier moteur qui en reconnaît une l'emploie.
   2. ARCHIVO NARROW en repli universel, vendorée : une grotesque condensée
      libre, à 3,5 % de la chasse de Bahnschrift (mesuré sur un même texte :
      0,837 contre 0,872 rapportés à la police système). Tous les appareils
      obtiennent donc le même dessin.

   Le fichier est VARIABLE, ce qui n'est pas un luxe : la feuille emploie dix
   graisses distinctes, de 400 à 800. En graisses statiques il aurait fallu dix
   fichiers.

   ── BUDGET ────────────────────────────────────────────────────────────────
   18,7 Ko, contre 58 Ko pour la Newsreader qu'elle remplace : l'application
   s'allège de 39 Ko tout en couvrant désormais TOUT le texte, et non les seuls
   titres.

   Vendorée dans le dépôt, jamais chargée depuis un CDN : la CSP n'autorise que
   l'origine. Archivo Narrow — SIL Open Font License 1.1, Omnibus-Type. */
@font-face {
  font-family: 'Archivo Narrow';
  src: url('/assets/fonts/archivo-narrow-variable-latin.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;   /* le texte s'affiche immédiatement dans le repli */
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Une seule pile pour toute l'application : titres, corps, tableaux.
     Les replis système en fin de liste sont eux aussi CONDENSÉS — un appareil
     privé d'Archivo Narrow, le temps du chargement ou si la requête échoue,
     garde ainsi la même proportion au lieu de s'élargir d'un coup sous les
     yeux du lecteur. */
  --police: 'Bahnschrift Condensed', 'Bahnschrift', 'Archivo Narrow',
            'Roboto Condensed', 'Liberation Sans Narrow', 'Arial Narrow',
            system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* Les titres ne se distinguent plus par la police mais par la taille et la
     graisse. L'alias est conservé pour que les règles écrites contre lui
     continuent de fonctionner sans réécriture. */
  --police-titre: var(--police);

  /* SEULE EXCEPTION, et elle est fonctionnelle : les codes de suivi
     (« SIG-XXXXXXXX ») et les identifiants techniques restent en chasse fixe.
     Un citoyen recopie son code caractère par caractère, souvent à la main ;
     une condensée y rapproche le 1 du I et le 0 du O. La lisibilité prime ici
     sur l'unité typographique. */
  --police-chiffres: ui-monospace, SFMono-Regular, 'SF Mono', Menlo,
                     'Cascadia Mono', 'Liberation Mono', monospace;


  /* Échelle typographique — tierce majeure (1,25), base 15 px.
     L'ancienne échelle sautait de 32 px à 18,4 px puis à rien : deux niveaux
     seulement, un écart de 1,74 entre eux, et un h2 à peine distinct du corps.
     La hiérarchie ne se lisait pas. */
  --t-xs:   0.75rem;    /* 12 px — mentions légales, notes de provenance */
  --t-s:    0.8125rem;  /* 13 px — libellés, méta, légendes */
  --t-base: 0.9375rem;  /* 15 px — corps */
  --t-m:    1.0625rem;  /* 17 px — chapô, intertitre */
  --t-l:    1.3125rem;  /* 21 px — h3 */
  --t-xl:   1.75rem;    /* 28 px — h2 */
  --t-2xl:  2.375rem;   /* 38 px — h1 */
  --t-3xl:  3.25rem;    /* 52 px — titre d'accroche, surfaces publiques */

  --interligne-titre: 1.15;
  --interligne:       1.55;
  /* Remise à zéro. Le resserrement de -0,015em avait été calibré pour une
     serif de grand corps ; une condensée est DÉJÀ resserrée par dessin, et lui
     retirer encore de la chasse collerait les lettres — surtout aux petites
     tailles, où vivent les libellés et les tableaux. */
  --chasse-titre: normal;

  /* ── Espacement — échelle de 8 px ───────────────────────────────────────── */
  --e-1: 0.25rem;   /*  4 px */
  --e-2: 0.5rem;    /*  8 px */
  --e-3: 0.75rem;   /* 12 px */
  --e-4: 1rem;      /* 16 px */
  --e-5: 1.5rem;    /* 24 px */
  --e-6: 2rem;      /* 32 px */
  --e-7: 3rem;      /* 48 px */
  --e-8: 4rem;      /* 64 px */

  /* ── Formes ─────────────────────────────────────────────────────────────
     Deux rayons SCALAIRES, contre onze auparavant. La pilule et le cercle ne
     sont pas des rayons mais des primitives de forme : ils n'entrent pas dans
     ce décompte. */
  --rayon:    6px;    /* boutons, champs, étiquettes, vignettes */
  --rayon-l:  12px;   /* panneaux, cartes, modales, menus flottants */

  /* Micro-formes de moins de 10 px : pastille carrée de légende, jauge de
     5 px, symbole de couche. Un rayon de 6 px sur une pastille de 10 px la
     rendrait ronde — or la légende cartographique OPPOSE le carré (surface)
     au rond (point). Les forcer sur l'échelle détruirait cette distinction.
     C'est une dérogation assumée aux deux rayons de composant, pas un oubli. */
  --rayon-micro: 3px;

  /* Primitives de forme, hors échelle : elles ne décrivent pas un arrondi
     mais une géométrie complète. */
  --rayon-pilule: 999px;
  --rayon-cercle: 50%;

  /* Ombres portées : deux niveaux, discrets. Une ombre marquée est le premier
     signe du rendu « template » que ce projet doit éviter. */
  --ombre:   0 1px 2px rgb(17 24 39 / 6%), 0 1px 3px rgb(17 24 39 / 8%);
  --ombre-l: 0 4px 12px rgb(17 24 39 / 8%);

  /* ── Neutres — une seule échelle ────────────────────────────────────────
     encre        sur fond   : 16,98:1  AAA
     encre-douce  sur fond   :  7,23:1  AAA
     encre-pale   sur blanc  :  4,83:1  AA   (jamais sous 16 px)
     `--encre-pale` était utilisée sans être déclarée : elle rendait une
     valeur vide, donc la couleur héritée. */
  --encre:       #111827;
  --encre-douce: #4b5563;
  --encre-pale:  #6b7280;
  --bord:        #e5e7eb;
  --bord-fort:   #d1d5db;
  --fond:        #f9fafb;
  --surface:     #ffffff;
  --surface-douce: #f3f4f6;

  /* ── Marque ─────────────────────────────────────────────────────────────
     Valeurs de repli. En service, Marque::palette() les remplace TOUTES par
     une échelle dérivée de la couleur du tenant — c'est la correction du
     défaut n° 2 décrit en tête de fichier. */
  --marque:       #14532d;
  --marque-fort:  #0f3e22;
  --marque-encre: #114726;   /* texte sur --marque-doux */
  --marque-bord:  #b9cbc0;
  --marque-doux:  #e8eeea;
  --marque-voile: #f6f8f7;
  --marque-accent: #166534;

  /* ── États métier — indépendants de la marque ───────────────────────────
     Chaque état dispose d'un plein (fond coloré, texte blanc), d'un doux
     (fond très clair) et d'une encre (texte sur le doux), tous mesurés AA.
     L'information n'est jamais portée par la seule couleur : ces jetons
     accompagnent toujours un libellé ou une forme. */
  --etat-critique:       #b42318;   /* actif, jamais traité */
  --etat-critique-doux:  #f9eded;
  --etat-critique-encre: #9e1f15;

  --etat-suivi:          #b54708;   /* intervention en cours */
  --etat-suivi-doux:     #f9f0eb;
  --etat-suivi-encre:    #9f3e07;

  --etat-maitrise:       #0f766e;   /* intervention terminée */
  --etat-maitrise-doux:  #ecf4f3;
  --etat-maitrise-encre: #0d6861;

  /* L'incertitude comme élément de conception de premier rang : ce produit
     affiche des ESTIMATIONS (superficies dérivées, cours d'eau « susceptibles
     d'être impactés », indices de confiance). Leur donner une couleur propre
     évite qu'un chiffre calculé passe pour un constat de terrain. */
  --etat-estime:         #a16207;
  --etat-estime-doux:    #f7f2eb;
  --etat-estime-encre:   #8e5606;

  --etat-info:           #175cd3;
  --etat-info-doux:      #ecf2fb;
  --etat-info-encre:     #1451ba;

  /* Bordures d'étiquettes : elles dessinent la forme quand le fond est très
     clair, et restent visibles à l'impression là où un aplat pâle disparaît. */
  --etat-critique-bord: #f3b4ae;
  --etat-suivi-bord:    #f0c3a3;
  --etat-maitrise-bord: #a7cfcb;
  --etat-estime-bord:   #e4c98f;
  --etat-info-bord:     #b8cdf1;

  /* ── Sources de données ─────────────────────────────────────────────────
     Le satellite et le citoyen sont deux ORIGINES d'information, pas deux
     états : leur couleur répond à « d'où vient ce point ? », jamais à « où en
     est-il ? ». Elles ne suivent donc ni la marque ni l'échelle des états.

     Le cyan précédent (#0891b2) ne tenait que 3,68:1 contre le blanc des
     pastilles : sous le seuil AA. La teinte est conservée dans sa famille,
     assombrie jusqu'à 7,27:1 — le sens appris par les agents est préservé,
     la lisibilité ne l'est plus au prix du contraste. */
  --source-satellite: #6941c6;   /* blanc dessus : 6,62:1 AA */
  --source-citoyen:   #155e75;   /* blanc dessus : 7,27:1 AA */

  /* ── Second canal, non chromatique ──────────────────────────────────────
     Mesure faite sur la palette : en niveaux de gris, les états ne se
     distinguent que de 0 à 7 valeurs sur 255. Ils sont donc INDISCERNABLES
     sur un PDF imprimé en noir et blanc — or ce produit exporte des rapports
     lus en comité — et pour une part des daltonismes.

     La couleur ne peut donc pas porter l'information seule. Ces marqueurs
     reprennent ceux déjà employés par le rapport PDF de pilotage, pour que
     l'écran et le document impriment le même vocabulaire. */
  --marqueur-critique: '!';
  --marqueur-suivi:    '~';
  --marqueur-maitrise: '+';
  --marqueur-estime:   '≈';   /* « de l'ordre de » : une estimation, pas une mesure */

  /* ── Console éditeur ────────────────────────────────────────────────────
     Un indigo réservé à la console TERRINOVA, volontairement absent de
     l'application cliente. Ce n'est pas une coquetterie : la console voit TOUS
     les tenants, et un opérateur doit reconnaître d'un coup d'œil qu'il est
     dans l'outil éditeur et non chez un client. La console n'applique jamais
     la palette de marque, pour la même raison.
     blanc dessus 7,90:1 AAA — encre sur doux 8,06:1 AAA */
  --console-accent:       #4338ca;
  --console-accent-doux:  #e0e7ff;
  --console-accent-encre: #3730a3;

  --largeur-max: 1440px;
  --largeur-texte: 68ch;   /* longueur de ligne confortable en lecture suivie */

  /* Colonne d'outils cartographiques : 34 px de bouton, bordures, marge au
     bord et jeu visuel. Les panneaux s'arrêtent là pour ne jamais la couvrir. */
  --gouttiere-outils: 3.2rem;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Compatibilité — anciens noms conservés en ALIAS.
   ═══════════════════════════════════════════════════════════════════════════
   app.css compte 1443 lignes écrites contre l'ancien vocabulaire. Les renommer
   d'un bloc aurait été une réécriture massive à haut risque pour un gain nul :
   ces alias laissent l'existant fonctionner tel quel pendant que le nouveau
   vocabulaire s'installe. Ils disparaîtront au fil des reprises de sections. */
:root {
  --vert-fonce:  var(--marque-fort);
  --vert:        var(--marque);
  --vert-clair:  var(--marque-doux);
  --encre-tres-douce: var(--encre-pale);

  --rouge:       var(--etat-critique);
  --rouge-clair: var(--etat-critique-doux);
  --terre:       var(--etat-suivi);
  --terre-clair: var(--etat-suivi-doux);
  --ambre:       var(--etat-estime);
  --bleu:        var(--etat-info);
  --bleu-clair:  var(--etat-info-doux);

  /* La page de pilotage rejoint l'échelle commune. Ses valeurs propres
     (#1A1A2E, #DEE2E6, #F8F9FA…) étaient proches sans être identiques : assez
     pour que les deux surfaces jurent l'une à côté de l'autre, trop peu pour
     que l'écart soit lisible comme une intention. */
  --pil-critique: var(--etat-critique);
  --pil-suivi:    var(--etat-suivi);
  --pil-maitrise: var(--etat-maitrise);
  --pil-action:   var(--etat-maitrise);
  --pil-fond:     var(--fond);
  --pil-surface:  var(--surface);
  --pil-sidebar:  var(--surface-douce);
  --pil-encre:    var(--encre);
  --pil-encre-2:  var(--encre-douce);
  --pil-bord:     var(--bord);
  --pil-ombre:    var(--ombre-l);
  --pil-rayon:    var(--rayon-l);
  --pil-rayon-s:  var(--rayon);
}

/* ── Mouvement ──────────────────────────────────────────────────────────────
   Les transitions servent à rendre un changement d'état compréhensible, jamais
   à décorer. Aucune animation d'apparition, aucun agrandissement au survol. */
:root {
  --transition: 120ms cubic-bezier(.2, 0, .38, .9);
}

@media (prefers-reduced-motion: reduce) {
  :root { --transition: 0ms; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
