/* ══════════════════════════════════════════════════════════════════════════
   THÈME PARTAGÉ — FICHIER GÉNÉRÉ, NE PAS ÉDITER À LA MAIN.
   Fabrique : outils/generer-theme.mjs   ·   Régénérer : npm run generer:theme
   Source des couleurs : client/jetons.css (elle seule fait foi)
   Il porte les POLICES et les JETONS, pour que le jeu, les pages d'aide, les
   mentions légales et la vitrine parlent exactement la même langue graphique.
   ══════════════════════════════════════════════════════════════════════════ */

@font-face {
  font-family: 'Space Grotesk'; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url('./spacegrotesk-vf-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk'; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url('./spacegrotesk-vf-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Baloo 2'; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url('./baloo2-vf-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Baloo 2'; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url('./baloo2-vf-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ══════════════════════════════════════════════════════════════════════════
   LES JETONS — la source UNIQUE des couleurs et des rayons du jeu.
   ══════════════════════════════════════════════════════════════════════════

   Source de vérité : `docs\charte-graphique.md` §2 (couleurs) et §5 (règles).
   Toute valeur ici vient de la charte ; si un chiffre doit changer, il change
   DANS LA CHARTE d'abord, puis ici — jamais l'inverse.

   ⚠️ POURQUOI CE FICHIER EST EN CSS ET PAS EN TYPESCRIPT. Les couleurs ont DEUX
   consommateurs qui ne parlent pas la même langue : la feuille de style
   (`index.html`) et PixiJS (des nombres `0xRRGGBB`). La charte exige « UNE
   source de tokens partagée CSS+Pixi (fin des doublons) ». Le CSS est le seul
   format que les deux savent lire : le navigateur applique ce fichier AVANT
   d'exécuter le moindre script (une feuille de style bloque le rendu), et
   `client\jetons.ts` relit ces mêmes variables pour les servir à Pixi en
   nombres. Une valeur, un endroit, zéro recopie.

   ⚠️ CE FICHIER NE DOIT CONTENIR QUE DES DÉCLARATIONS DE VARIABLES. Aucune
   règle qui peint quoi que ce soit : il est chargé par le jeu ET par les pages
   de l'atelier, qui n'ont pas la même mise en page.

   NOMMAGE : `--af-<famille>-<rôle>`. Le préfixe `af-` évite toute collision
   avec une variable d'une page d'atelier ou d'une future dépendance.

   ── UNE SAISON = UN ÉCHANGE DE JETONS ─────────────────────────────────────
   Changer de saison (charte §2 « la preuve saison ») = redéfinir ICI le fond,
   les nébuleuses, la tranche et la vignette — et RIEN d'autre. Ne changent
   JAMAIS : les 4 familles sémantiques (leurs RÔLES), les 13 couleurs de joueur,
   la marque, la géométrie.
   ⚠️ Le SOL est sorti de cette mécanique le 2026-08-02 : ce sont 13 images
   dessinées, couleurs cuites (`client\assets\tuiles\`). Les jetons `case-*`
   ci-dessous ne peignent plus que la tuile TRACÉE de secours, affichée le temps
   que les images arrivent.
   Direction courante : « Voie lactée » (fond `#2f2777 → #131030`, bascule 55 %).
   Étapes précédentes : « Nuit franche » (quasi noir) · « Givre polaire »
   (`#30455e → #121d34`).
   ────────────────────────────────────────────────────────────────────────── */

:root {

  /* ═══ FOND — la nuit ═══════════════════════════════════════ (saison) ═══ */
  /* ⚠️ LE DÉGRADÉ EST INVERSÉ par rapport aux presets : le CLAIR va EN HAUT.
     La lumière du projet vient d'en haut (charte §3, ~10 h 30) ; un fond plus
     sombre en haut qu'en bas contredirait la seule règle d'éclairage du jeu. */
  /* ⚠️ LE CIEL EST « VOIE LACTÉE » BLEU/VIOLET — décision utilisateur du
     2026-08-09. L'histoire en trois temps, et chaque leçon reste vraie :
     · « Nuit franche » gardait un fond quasi noir voilé : « le fond reste
       noir » (utilisateur) — on ne colore pas un ciel avec un voile transparent
       sur du noir, on change sa BASE (haut = base ×1,35, bas = base ×0,55).
     · Le PRUNE (`#4a1d59`) a servi UN JOUR : il écartait la matière Galaxie du
       ciel par la teinte (ΔE 28 contre 24 en indigo). Le LISERÉ D'UNION a rendu
       ce détour inutile — la silhouette est portée par son halo, plus par la
       couleur du fond — et l'utilisateur préfère le bleu/violet : retour à la
       base « voie lactée » `#231d58`, celle de la variante du même nom de la
       matière (`textureGalaxie`, `client\mascotte\vue.ts`).
     ⚠️ SURTOUT PAS DE CYAN, la leçon tient toujours : à clarté égale il tombe à
     ΔE 21 de la Galaxie ET 18 du joueur Noir. Le Noir est une couleur NEUTRE :
     ce qui l'écarte du ciel est la CHROMA du fond — un cyan sombre retombe
     presque au gris, un indigo reste saturé. La saturation protège le Noir. */
  /* ═══ ESSAI « PALETTE VITRINE » — 2026-08-27, demande utilisateur ═══════════
     Essai RÉVERSIBLE : reprendre dans le JEU le fond de la vitrine (bleu nuit en
     haut, halo orange en bas à droite, sans la planète Mars) et ses couleurs de
     texte. Les étoiles, les nébuleuses, les personnages et les tuiles NE CHANGENT
     PAS — seuls le fond, ses dégradés et les titres.
     ⚠️ VALEURS D'AVANT, pour revenir à la main si besoin (sinon : `git revert`) :
        --af-fond-haut: #2f2777 · --af-fond-bas: #131030 · --af-fond-bascule: 55%
     📉 CE QUE ÇA COÛTE, MESURÉ AVANT DE LE FAIRE : la luminance du fond est
     DIVISÉE PAR DEUX (haut L*21,5 → 11,3 · bas L*6,5 → 1,8). La SATURATION, elle,
     est préservée (67 % → 71 %) — c'est elle qui écarte le joueur Noir du ciel,
     donc ce garde-fou-là tient. Le risque restant est celui du 2026-08-08 : un
     fond trop plat DERRIÈRE LE PERSONNAGE (il flotte vers 47 % de hauteur).
     Calcul : à bascule 68 %, il se retrouve sur L*≈4,8 contre L*≈8,7 aujourd'hui —
     soit tout près du L*4,0 que l'utilisateur avait lu comme « je ne vois même
     plus ce dégradé ». 👉 LE LEVIER, si le perso paraît posé sur du noir plat :
     REMONTER `--af-fond-bascule` (68 → 80 %, voire plus). Le halo orange, lui,
     relève le bas à droite. */
  --af-fond-haut: #141a44;   /* bleu nuit de la vitrine — EN HAUT */
  --af-fond-bas: #05060f;    /* le presque-noir de la vitrine — EN BAS */
  /* L'ORANGE DU BAS. ⚠️ Il a d'abord été posé en HALO à droite (comme la lueur de
     Mars sur le site public) puis déplacé EN BAS, sur toute la largeur, à la
     demande de l'utilisateur : « finalement on va le mettre en bas tout court,
     tout en bas, comme le dégradé en haut ». C'est donc un troisième arrêt du
     dégradé vertical, plus un sprite à part — et ça vaut pour le jeu ET pour
     toutes les pages.
     ⚠️ CELA DÉROGE À LA CHARTE §5 (« toujours DEUX arrêts de couleur, on ne fait
     que déplacer le second »). C'est une demande explicite, pas un oubli : la
     règle existait pour empêcher un dégradé qui délave, et l'orange est ici très
     sombre (L*12,2, à peine plus clair que le bleu du haut à L*11,3) — il réchauffe
     le bas sans l'éclaircir. */
  --af-fond-chaud: #3a1410;
  /* OÙ SE POSE LE HALO, en fraction de l'écran.
     ⚠️ QUATRE POSITIONS EN UN JOUR (2026-08-27), et c'est la dernière qui tient :
     angle bas-droit → bandeau tout en bas (« il n'est pas correct ») → retour dans
     l'angle → REMONTÉ ici (« il était un peu trop bas »). Le dégradé vertical, lui,
     est resté à DEUX arrêts, conforme à la charte §5 : le halo est une couche
     au-dessus, jamais un troisième arrêt.
     🪦 UNE PLANÈTE MARS devait s'y poser, et l'idée a été ABANDONNÉE le même jour.
     La raison mérite d'être gardée, parce qu'elle vaut pour tout ce qu'on voudra
     ajouter au fond : **un astre FIXE pendant que le ciel TOMBE se contredit**.
     Le fond de ce jeu raconte la chute — ce qu'on y met doit tomber aussi.
     👉 Ces deux nombres sont LE réglage : monter/descendre le halo, c'est `-y`. */
  --af-fond-halo-x: 85%;
  --af-fond-halo-y: 62%;
  /* ⚠️ OÙ LE DÉGRADÉ A FINI DE DESCENDRE. Sans ce réglage, la transition occupe
     toute la hauteur : clair et sombre se partagent l'écran moitié-moitié, et la
     nuit ne domine jamais.
     ⚠️ ELLE VALAIT 38 %, ET C'ÉTAIT LE VRAI DÉFAUT DE « NUIT FRANCHE » (repéré
     par l'utilisateur le 2026-08-08 : « je ne vois même plus ce dégradé »).
     Terminer la transition à 38 % laisse les DEUX TIERS BAS de l'écran en aplat
     de `fond-bas` — or c'est là que le personnage flotte (~47 %). Mesuré : le
     fond DERRIÈRE LUI est passé de L*11,0 (avant la refonte) à **L*4,0**, un
     noir sans relief. Le dégradé existait toujours, mais hors du champ où on le
     regarde. À 80 %, il redescend sur toute la hauteur et le personnage
     retrouve L*10,2 — son ancien fond, SANS toucher à `fond-haut` ni à
     `fond-bas`.
     ⚠️ Le rapport de contraste ne voit PAS ce défaut : il annonçait 1,21 pour
     l'aplat noir contre 1,07 pour le dégradé restauré, c'est-à-dire l'inverse de
     ce qu'on voit. À ces niveaux de noir son terme de voile (+0,05) écrase les
     écarts — l'œil de l'utilisateur est le bon instrument, pas cette formule.
     ⚠️ Toujours DEUX arrêts de couleur (charte §5) : on ne fait que déplacer le
     second, on n'en ajoute pas un troisième.
     ⚠️ Lu par le CSS **et** par le ciel Pixi (`client\ciel.ts`) : les deux
     surfaces se touchent, un écart se verrait comme une couture. */
  /* ⚠️ REMONTÉE À 55 % le 2026-08-08. Elle valait 80 %, puis 75 % — ce dernier
     cran était trop timide pour se voir, et l'utilisateur l'a lu comme une
     DESCENTE (« t'as descendu le dégradé au lieu de le remonter »). À 55 % la
     couleur vit dans la moitié haute et la nuit reprend le bas : c'est ce que
     « une voie lactée » veut dire, plutôt qu'un écran uniformément coloré.
     ⚠️ SOUS 47 %, PLUS RIEN NE CHANGE derrière le personnage : il se retrouve sur
     du `fond-bas` PUR, et seule la hauteur du dégradé bouge encore. C'est la
     limite utile de ce réglage. */
  /* ⚠️ 55 % → 68 % pour l'essai « palette vitrine » (2026-08-27) : c'est
     l'endroit où le halo bleu de la vitrine s'éteint dans son propre fond. Voir
     l'encadré plus haut — c'est LE levier si le personnage paraît posé sur du
     noir plat. */
  --af-fond-bascule: 68%;

  /* ⚠️ LE SOMBRE DES PANNEAUX N'EST PLUS LE HAUT DU FOND. Tant que le dégradé
     allait du sombre au clair, `fond-haut` servait aux DEUX : le ciel et le noir
     des panneaux, des traits, des pupilles. En inversant, il devient clair — ce
     jeton-ci reprend donc ce rôle, et lui seul. Un jeton = un rôle. */
  --af-nuit: #070a11;

  /* ═══ LES NÉBULEUSES — SEPT, et elles vivent ENFIN ici ═════ (saison) ═══ *
   * ⚠️ CORRIGÉ le 2026-08-08 (défaut relevé par l'utilisateur). Il y avait TROIS
   * jetons ici, que personne ne lisait, pendant que le ciel en peignait SEPT
   * écrits en dur dans `client\ciel.ts`. Changer la palette ne les atteignait
   * donc pas, et les trois jetons mentaient sur ce que l'écran montre.
   * Couleur ET opacité figées ensemble : elles ne se mélangent à aucun autre
   * alpha — c'est ce qui garde le ciel calme (`jetonNum` + `jetonAlpha`). */
  /* ⚠️ REPRISES le 2026-08-08 avec « Voie lactée ». Elles étaient SEPT TEINTES
     DIFFÉRENTES — violet, cyan, rose, turquoise, orange, mauve, or — réparties au
     hasard : elles animaient le ciel mais ne racontaient rien, et l'une d'elles
     (la rose) tombait pile derrière la zone où flottent les personnages, où elle
     était ce qui masquait le plus la matière Galaxie (mesuré : ΔE 7, le pire des
     quatre ciels comparés).
     Elles n'ont plus que TROIS teintes, toutes de la famille du fond — lilas,
     bleu clair, bleu-lavande — et elles sont plus grandes et plus opaques : c'est
     ce qui fait qu'on les VOIT, au lieu d'un voile qui ne colore rien. */
  --af-nebuleuse-1: rgba(200, 180, 255, 0.34);
  --af-nebuleuse-2: rgba(140, 170, 255, 0.30);
  --af-nebuleuse-3: rgba(160, 184, 255, 0.26);
  --af-nebuleuse-4: rgba(140, 170, 255, 0.22);
  --af-nebuleuse-5: rgba(200, 180, 255, 0.20);
  --af-nebuleuse-6: rgba(160, 184, 255, 0.18);
  --af-nebuleuse-7: rgba(140, 170, 255, 0.15);

  /* ═══ TERRAIN — le plateau ═════════════════════════════════ (saison) ═══ */
  --af-case-neuve: #cbd4e2;      /* givre clair (rampe du preset « Givre polaire ») */
  --af-pre-signal: #fff7ec;      /* flash blanc chaud — voir la rampe ci-dessous */
  /* ⚠️ LA RAMPE D'USURE A CHANGÉ D'HISTOIRE le 2026-08-02 (décision utilisateur).
     Avant : neuve → usée → critique, trois gris qui refroidissaient. Maintenant
     la case DIT CE QUI LUI ARRIVE — on marche dessus, elle flashe crème
     (`--af-pre-signal`, atteint TRÈS vite : c'est un accusé de réception), puis
     elle chauffe vers l'orange et finit sur le rouge du MALUS. Une case qui va
     tomber EST un danger : elle en porte la couleur, pas une autre.
     `--af-case-usee` et `--af-case-critique` ne sont donc PLUS dans la rampe ;
     ils restent déclarés (charte §2) tant qu'on n'a pas tranché leur sort. */
  /* ⚠️ CINQ ARRÊTS ENTRE LE GIVRE ET LE ROUGE, et c'est un minimum (retour
     utilisateur 2026-08-02 : « on a du mal à savoir quand c'est à 20, 30, 40 ou
     90 pour cent »). Avec trois arrêts, tout le milieu se ressemblait et la fin
     virait au rouge trop tôt. Chaque arrêt change donc de TEINTE **et** de
     CLARTÉ — c'est ce qui rend un palier lisible d'un coup d'œil, la teinte
     seule ne suffit pas. La fin ASSOMBRIT (braise) avant que le tout dernier
     instant reparte sur le rouge vif du malus : ce sursaut EST l'alerte. */
  --af-case-tiede: #ffcf8a;      /* l'OR de chauffe. ⚠️ Proche de `--af-monnaie` (#ffcf5e)
                                    et c'est assumé : la progression or → orange → braise
                                    est celle qui lisait le mieux l'avancement (retour
                                    utilisateur), et une case au sol ne se confond pas
                                    avec une pièce — qui est DESSINÉE, biseautée, petite
                                    et flottante. Éclairci vers l'abricot pour l'écarter
                                    quand même un peu. */
  --af-case-chaude: #ff8a4c;     /* l'orange de chauffe — le seul arrêt jamais remis en cause */
  --af-case-brulante: #e2543a;   /* la braise. ⚠️ Elle valait #b03620, une braise SOMBRE :
                                    la rampe PLONGEAIT puis remontait vers le rouge vif,
                                    et ce creux cassait la lecture (retour utilisateur).
                                    À #e2543a la descente reste MONOTONE — clarté et
                                    teinte ne font que descendre vers le rouge. */
  --af-case-usee: #a6aeb9;       /* (hors rampe depuis le 2026-08-02) */
  --af-case-critique: #7e838c;   /* (hors rampe depuis le 2026-08-02) */
  --af-case-condamnee: #3a4459;  /* ardoise éteinte : « la nuit a gagné la case » */
  /* LA TÔLE — les hexagones se TOUCHENT désormais (plus de gouttière) : ce qui les
     sépare est une SOUDURE. C'est un NIVEAU DE GRIS : il vit dans la texture de la
     tuile, qui est ensuite multipliée par la couleur d'usure — il suit donc la
     saison tout seul, en restant toujours plus sombre que la face.
     (Un `--af-case-vis` a existé le temps d'un essai de « tôle boulonnée » ;
     retiré avec les vis le 2026-08-02 — une couleur que personne n'utilise ment
     sur la palette.) */
  --af-case-joint: #8d95a3;      /* la soudure entre deux plaques (fin, pas un trait noir) */
  /* ⚠️ LA TRANCHE SUIT LA SAISON, ET SA RAISON D'ÊTRE A CHANGÉ. En version
     martienne elle était VIOLETTE : il fallait ce voile froid pour souder un sol
     CHAUD (sable rosé) à une nuit FROIDE. Le sol est maintenant du givre — donc
     déjà froid : la tranche n'a plus à le refroidir, seulement à l'asseoir. */
  --af-tranche: #55607a;

  /* ═══ SÉMANTIQUE — une famille par rôle ════════════════════════════════ *
   * ⚠️ CES QUATRE RÔLES NE CHANGENT JAMAIS, saison comprise. Ne JAMAIS
   * réattribuer une famille.
   * ⚠️ Leurs VALEURS ont été reprises le 2026-08-08 avec « Nuit franche » : mêmes
   * teintes, PLEINES plutôt que pastel. Un accent pastel sur un fond bleu métal
   * se voyait ; sur du presque noir il perd sa saillance, et un signal qui ne
   * saille plus n'est plus un signal.                                        */
  --af-bonus: #a97bff;      /* halos doux, jamais pulsés */
  --af-activable: #28d3e0;  /* halo des items au sol, arme en main, HUD d'usage */
  --af-danger: #ff4433;     /* le signal le PLUS saillant : chroma max de l'écran et
                               MONOPOLE de la pulsation */
  --af-monnaie: #ffc94d;    /* la pièce est DESSINÉE (disque biseauté 2 tons) */

  /* ── LA PALETTE CATÉGORIELLE (2026-08-29) ────────────────────────────────
   * Pour DISTINGUER des parts sans rien vouloir dire : les tranches d'un
   * camembert, les séries d'un graphique de la console d'admin.
   * 🔴 POURQUOI ELLE EXISTE. Les quatre familles sémantiques ci-dessus ont un
   * SENS (bonus, activable, danger, monnaie) et ne se réattribuent jamais pour
   * faire joli — les employer sur un camembert leur ferait dire autre chose.
   * On s'en tirait avec des OPACITÉS d'un seul jeton : rigoureux, mais illisible
   * — « c'est tous des verts, il faut des couleurs qui se distinguent »
   * (utilisateur, 2026-08-29). Il fallait donc une palette qui ne signifie rien.
   * ⚠️ Les valeurs viennent du CATALOGUE DE COULEURS JOUEUR (`commun/
   * cosmetiques.ts`) : ce sont déjà des teintes du jeu, choisies pour être
   * distinguables les unes des autres — c'est exactement leur métier, puisqu'un
   * joueur doit reconnaître son adversaire à sa couleur.
   * ⚠️ Ni le ROUGE ni le VERT du catalogue n'y figurent : le premier frôlerait le
   * danger, le second la couleur d'action. L'ordre alterne chaud et froid, pour
   * que deux tranches voisines ne se ressemblent jamais.                     */
  --af-cat-1: #3d52db;  /* bleu    (c-bleu)   */
  --af-cat-2: #db8e3d;  /* orange  (c-orange) */
  --af-cat-3: #3ddbbf;  /* cyan    (c-cyan)   */
  --af-cat-4: #db4caa;  /* rose    (c-rose)   */
  --af-cat-5: #dbd44c;  /* jaune   (c-jaune)  */
  --af-cat-6: #813ddb;  /* violet  (c-violet) */

  /* ── LA RAMPE DE LA BOUSCULADE (2026-08-20, décision utilisateur « P3 ») ──
   * L'onde de poussée change de couleur avec le PALIER de celui qui pousse :
   * froid en bas de classement, incandescent au sommet. Cinq degrés :
   *     1  poussee-froid        (bleu-violet)
   *     2  activable            (le cyan d'aujourd'hui)
   *     3  texte / activable-clair   (blanc, halo cyan clair)
   *     4  case-brulante / poussee-chaud-halo   (la braise)
   *     5  monnaie-clair / monnaie             (l'or du roi)
   * Trois teintes seulement sont NOUVELLES : les deux autres degrés réutilisent
   * des jetons existants, et c'est voulu — moins il y a de couleurs à nommer,
   * moins il y en a à tenir d'accord.
   *
   * ⚠️ ELLES ÉTAIENT DES MÉLANGES ANONYMES sur la planche de décision
   * (`atelier\variantes-bousculade.html`, rampe P3). Une couleur retenue par
   * l'utilisateur devient un JETON NOMMÉ — c'était la promesse écrite sur la
   * page, et c'est la règle du projet : « aucune couleur en dur, elles ont
   * des noms ». Les valeurs ci-dessous SONT le résultat exact des mélanges.
   *
   * ⚠️ LE BLEU DU PALIER 1 EMPIÈTE SUR LA FAMILLE BONUS, et c'est assumé : un
   * bleu vraiment profond avait été essayé d'abord et mesuré INVISIBLE sur le
   * ciel nuit (15 pixels au relevé contre 250-420 pour les autres degrés). Le
   * violet du bonus est un halo doux et permanent autour d'un objet ; celui-ci
   * est un arc bref au sol : ils ne se rencontrent ni au même endroit ni au
   * même moment. */
  --af-poussee-froid: #6fa3f1;       /* palier 1 — activable × bonus 55 % */
  --af-poussee-froid-halo: #62abee;  /* son halo — activable × bonus 45 % */
  --af-poussee-chaud-halo: #ee8342;  /* palier 4 — case-brulante × monnaie 40 % */

  /* Flaque de nuit OBLIGATOIRE sous tout élément rouge posé sur le sol chaud :
     le rouge ne touche jamais l'ocre (charte §2). */
  --af-flaque-danger: rgba(7, 10, 17, 0.8);   /* = --af-nuit à 80 % */

  /* ═══ L'ÉTAT DU RÉSEAU ══════════════════════════════════════════════════ *
   * Deux jetons DÉDIÉS (décision utilisateur 2026-08-16, page de variantes
   * `atelier\variantes-ping.html`, variante V3 retenue). ⚠️ Ils ne rejoignent
   * PAS les quatre familles sémantiques et ne leur empruntent rien : la qualité
   * du réseau n'est ni un bonus, ni un activable, ni un malus de jeu, ni une
   * monnaie — un rôle nouveau reçoit son propre jeton, dont le nom dit le rôle.
   * ⚠️ L'ambre est franchement plus ORANGÉ que `--af-monnaie` (#ffc94d) : les
   * deux ne peuvent pas se confondre, et c'est délibéré.
   * ⚠️ Le rouge est un rouge-orangé, PLUS DOUX que `--af-danger` (#ff4433) :
   * une mauvaise connexion informe, elle ne doit pas crier comme un malus qui
   * tue. La forme (les barres) porte déjà l'alerte.                          */
  --af-reseau-moyen: #ffa63d;    /* 100-180 ms : jouable, précision dégradée */
  --af-reseau-mauvais: #ff6a4a;  /* > 180 ms : les coups partent à côté */

  /* ═══ LE BOUTON OR ══════════════════════════════════════════════════════ *
   * La charte détaille le bouton PLAY (vert d'action) mais pas son pendant
   * DORÉ — or le jeu en a un : « ACHETER », « DOUBLER », « OUVRIR LA BOUTIQUE ».
   * Ces quatre-là complètent la famille MONNAIE sur le même patron que le vert :
   * un dégradé à DEUX arrêts (clair → base), un relief PLAT, un texte sombre.
   * Écarts calqués sur ceux du vert d'action (relief ≈ V−30 %, texte très sombre
   * de la même teinte) — ce sont les valeurs déjà validées à l'œil par
   * l'utilisateur sur `atelier\variantes-pictos.html`. */
  --af-monnaie-clair: #ffe8b2;    /* haut du dégradé */
  --af-monnaie-relief: #b38b30;   /* l'ombre plate `0 4px 0` */
  --af-monnaie-texte: #3a2a00;    /* le texte POSÉ sur l'or — contraste 9,8:1, mesuré */

  /* Mêmes déclinaisons pour les deux familles qui portent aussi des surfaces
     (le bouton tactile « utiliser », le ruban des nouveautés). ⚠️ Elles ne sont
     PAS choisies à l'œil : ce sont les ÉCARTS exacts du vert d'action de la
     charte (clair = S×0,43 V×1,23 · relief = S×1,05 V×0,70) appliqués à la
     couleur de famille. Une famille se décline, elle ne s'invente pas. */
  --af-activable-clair: #a5f9ff;
  --af-activable-relief: #16939d;
  --af-bonus-clair: #dac6ff;
  --af-bonus-relief: #7351b3;

  /* ═══ LA PALETTE DES ARMES ═══════════════════════════ (2026-08-18) ═══════ *
   * Une palette PAR ARME pour ses ÉMISSIONS et les effets qu'elle laisse
   * (demande utilisateur, chantier « le filet devient glu ») : elle PRÉPARE
   * les skins d'objets (GLOSSAIRE §2 — un skin d'item change l'apparence ET
   * les émissions) : le jour venu, un skin ÉCHANGERA cette palette, jamais le
   * dessin de l'effet. ⚠️ RIEN N'EST CHOISI À L'ŒIL : la base est la DOMINANTE
   * MESURÉE du sprite de l'arme (histogramme des pixels saturés du .webp,
   * saturation +0,15 pour rester lisible sur le sol sombre) ; le clair suit la
   * formule des familles (S×0,43 V×1,23) ; le contour la formule de la charte
   * (S+0,10 V−0,42). Servies aux effets par `client\palette-armes.ts` — un
   * effet d'arme ne lit QU'ELLE, jamais une famille sémantique. */
  --af-arme-lanceglu: #4f7ac6;         /* le bleu ACIER du lance-glu (H 218) */
  --af-arme-lanceglu-clair: #b5cbf4;
  --af-arme-lanceglu-contour: #1b325b;
  /* ⚠️ LE LASER DE BASE EST JAUNE depuis le 2026-08-19 (décision utilisateur,
   * chantier skins d'item) : la dominante retenue est le JAUNE de la crosse
   * (H 48, 45 % des pixels), pas le bleu ardoise du canon (H 230, 53 %) qui
   * l'emportait à l'histogramme — c'est LE cas où la dominante mesurée ne dit
   * pas la couleur SIGNATURE de l'arme. L'ancien trio ardoise : #626ea9 /
   * #aab1d0 / #1e233e (si un jour un skin « ardoise » le réclame). */
  --af-arme-laser: #efd880;              /* le JAUNE de la crosse (H 48) */
  --af-arme-laser-clair: #fff6d0;
  --af-arme-laser-contour: #766938;
  --af-arme-grenade: #e98a2f;            /* l'ORANGE de la grenade (H 29) */
  --af-arme-grenade-clair: #ffd2a7;
  --af-arme-grenade-contour: #7e440d;

  /* ── Les VARIANTES de skin (chantier skins d'item, 2026-08-19) ─────────────
   * Une palette PAR SKIN, mêmes formules, base mesurée sur le sprite de la
   * variante (`outils\fabriquer-atlas-armes.mjs --mesurer`). Le suffixe est le
   * champ `variante` du catalogue (commun\cosmetiques.ts, CATALOGUE_SKINS_ITEM).
   * ⚠️ Grenade : la base n'est pas la dominante brute (le corps crème domine
   * l'histogramme) mais la BANDE de couleur — c'est elle la signature, comme
   * l'orange l'est sur la grenade de base. */
  --af-arme-lanceglu-c1: #92d0dc;        /* le GIVRE bleu ciel (H 190) */
  --af-arme-lanceglu-c1-clair: #ddf9ff;
  --af-arme-lanceglu-c1-contour: #3b5d64;
  --af-arme-lanceglu-c2: #edc25c;        /* le MIEL doré (H 42) */
  --af-arme-lanceglu-c2-clair: #ffecc1;
  --af-arme-lanceglu-c2-contour: #745d27;
  --af-arme-laser-c1: #3aa02a;           /* le VERT franc (H 124) */
  --af-arme-laser-c1-clair: #86c485;
  --af-arme-laser-c1-contour: #0b3607;
  --af-arme-laser-c2: #f6a3d2;           /* le ROSE (H 326 — la crosse, comme le jaune du C0) */
  --af-arme-laser-c2-clair: #ffddf0;
  --af-arme-laser-c2-contour: #7d4966;
  --af-arme-grenade-c1: #35a01f;         /* la bande VERTE (H 110) */
  --af-arme-grenade-c1-clair: #d3ecab;
  --af-arme-grenade-c1-contour: #0d3506;
  --af-arme-grenade-c2: #6f55d2;         /* la bande VIOLETTE, éclat rose (H 252/326) */
  --af-arme-grenade-c2-clair: #ffd9ee;
  --af-arme-grenade-c2-contour: #2c205b;

  /* ═══ LES ÉTOILES ═══════════════════════════════════════ (saison) ═══════ *
   * Trois plans de profondeur. La charte §2 les veut en jetons PARTAGÉS
   * CSS+Pixi (« fin des doublons ») : `client\ciel.ts` les prendra ici aussi.
   * Valeurs inchangées — le ciel actuel est validé, on ne fait que le nommer. */
  --af-etoile-loin: #b9c2e6;
  --af-etoile-moyen: #d3daf2;
  --af-etoile-pres: #eef3ff;

  /* ═══ CONTOURS TEINTÉS ═════════════════════════════════════════════════ *
   * Un seul régime de contour dans tout le projet (charte §5.3) : teinté,
   * JAMAIS noir pur. Ces valeurs ne sont pas choisies à l'œil — elles sortent
   * de la formule du code (même teinte, S+10, V−42), la même qui donne le
   * contour des skins de la mascotte. Vérification : appliquée à la menthe
   * `#4fc39a`, elle rend `#1b5842`, soit le `#1b5843` noté dans la charte.    */
  /* ⚠️ EXCEPTION ASSUMÉE — LE PERSONNAGE (décision utilisateur 2026-08-03).
   * Son contour est NOIR, pas teinté : essayé au studio d'objets, comparé au
   * contour noir des armes, et adopté. Il sort donc du régime ci-dessus, qui
   * reste la règle pour tout le reste. Le voile d'ombre suit ce trait — c'est
   * un filtre de la couleur du contour — d'où l'intensité ramenée à 25 %.   */
  --af-contour-perso: #000000;
  /* ⚠️ LE LISERÉ DES MATIÈRES (2026-08-08) — une exception, et elle est motivée.
     Le contour du personnage est NOIR ; sur un ciel sombre il ne sépare donc
     RIEN. Ça n'a d'importance que pour la matière Galaxie, dont le corps est
     lui-même un ciel étoilé sombre : mesurée contre le ciel, elle reste à
     ΔE 10 — et AUCUN réglage de fond ne peut l'en sortir (indigo, prune,
     magenta et cyan ont tous été essayés). Un liseré clair posé À L'EXTÉRIEUR du
     trait noir sépare la silhouette indépendamment de ce qu'elle contient.
     ⚠️ POUR LA MATIÈRE UNIQUEMENT (décision utilisateur) : les douze couleurs
     unies gardent leur contour noir seul, y compris le Noir — qui tient à ΔE 31.
     ⚠️ C'est un RENVOI : le liseré est la lumière des étoiles, donc il prend la
     couleur du plan d'étoiles le plus proche. Le jour où il s'en détache, il
     change ICI. */
  --af-liseree-matiere: var(--af-etoile-pres);
  --af-contour-monnaie: #94701e;
  --af-contour-bonus: #583994;
  --af-contour-activable: #096d75;
  --af-contour-danger: #941a0f;
  --af-contour-action: var(--af-marque-contour);  /* le vert a changé : son contour suit */
  --af-contour-texte: #667081;  /* ⚠️ le texte est passé au BLANC : son ombre de picto
                                   n'est plus un brun chaud mais le relief du texte
                                   atténué — sinon un picto blanc traîne une ombre beige */
  --af-contour-case: #4a5460;
  --af-contour-kills: #945131;

  /* Éclat : la charte ne prévoit PAS une couleur claire par famille, mais UN
     micro-highlight blanc haut-gauche. Un seul jeton, donc, et il se pose en
     transparence par-dessus n'importe quelle couleur. */
  --af-highlight: rgba(255, 255, 255, 0.38);

  /* ═══ JOUEURS ═══════════════════════════════════════════════════════════ *
   * ⚠️ IL N'Y A PLUS DE JETONS DE COULEUR JOUEUR ICI, et c'est volontaire.
   * Huit y ont vécu jusqu'au 2026-08-08 ; la refonte forme × couleur du
   * 2026-08-07 les a rendus FAUX (13 couleurs, pas 8) et personne ne les lisait
   * — vérifié : zéro occurrence de `--af-joueur-` hors de ce fichier. Une liste
   * de couleurs que rien ne consomme et que rien ne vérifie MENT sur la palette.
   * Les 13 couleurs vivent à UN endroit, le rig (`client\mascotte\vue.ts`), et
   * leur copie de `commun\cosmetiques.ts` est comparée à chaque commit par
   * `outils\verifier-palettes.mjs`. C'est là qu'on les lit.                   */

  /* ═══ LA MARQUE ═════════════════════════════════════════════════════════ *
   * ⚠️ Le titre « AlienFall » était en OR, c'est-à-dire dans la famille MONNAIE
   * (défaut relevé par l'utilisateur le 2026-08-02) : dans le menu, il avait
   * exactement la couleur du compteur de pièces posé dessous. Un nom de jeu n'est
   * pas de l'argent, et une famille sémantique ne se prête pas.
   * ⚠️ IL A ENSUITE ÉTÉ ORPHELIN : la marque valait la « menthe oxygène »
   * `#4fc39a`, une couleur que la refonte du 2026-08-07 a RETIRÉE du catalogue.
   * Depuis le 2026-08-08 elle vaut le VERT DU CATALOGUE JOUEUR (`c-vert`) : la
   * marque redevient la couleur d'un personnage du jeu.
   * Pourquoi le vert, mesuré (écart CIE Lab à la famille sémantique la plus
   * proche) : Cyan 23 → c'EST l'activable · Jaune 21 → c'EST la monnaie ·
   * VERT 61 · CITRON 65. Le vert est la seule famille de teinte libre qui dise
   * « vas-y » — ce que doit dire un bouton JOUER.
   *
   * ⚠️ CITRON ET NON VERT depuis le 2026-08-09 — et c'est une question
   * d'HARMONIE, pas de contraste. Les 13 couleurs joueur forment DEUX familles
   * de clarté : neuf vives, toutes à 86 %, et quatre sombres — Brun, Galaxie,
   * Noir… et le Vert, à 68 %. La marque avait donc été prise dans le groupe des
   * couleurs faites pour des personnages DISCRETS. « Il ne colle pas avec le
   * reste » (utilisateur) : c'était exact, et mesurable. Le Citron est à 86 %,
   * dans la famille vive, comme les quatre familles sémantiques (88 à 100 %).
   * Le contraste suit (titre 4,6 → 7,5:1), mais ce n'est PAS la raison.
   * ⚠️ Contrepartie assumée : la marque rejoint l'anneau vif, donc la brillance
   * des retours de jeu. Acceptable ici — le vert n'occupe que deux objets
   * PERMANENTS (titre, bouton dominant) : il ne surgit jamais, il ne clignote
   * pas. Ne pas l'étendre à des éléments diffus sans rouvrir la question.
   * ⚠️ OÙ ELLE SE VOIT, exactement : le bouton JOUER, les liens, les filets de
   * titre — via `--af-action` ci-dessous — et le PERSONNAGE. **Pas le titre**, qui
   * est sorti du vert à la variante L du 2026-08-02 pour que le bouton reste la
   * SEULE tache verte du menu (voir `index.html`, `#menu-title`).
   * ⚠️ VALEUR RECOPIÉE, pas pointée : `commun\` n'est pas lisible depuis une
   * feuille de style. La recopie est donc VÉRIFIÉE À CHAQUE COMMIT par
   * `outils\verifier-palettes.mjs`, au même titre que la palette du rig. */
  /* ═══ LE VERT EMBLÉMATIQUE A CHANGÉ — 2026-08-27, demande utilisateur ═══════
     « faire passer le vert emblématique du jeu sur le vert un peu lumineux qui
     était déjà sur la vitrine ». La marque quitte donc le VERT CITRON du
     catalogue de joueurs pour le vert LUMINEUX du site public.
     ⚠️ CONSÉQUENCE ASSUMÉE : la marque n'est PLUS une couleur de personnage. Le
     lien qui les unissait depuis le 2026-08-08 est rompu VOLONTAIREMENT (les
     couleurs de joueur, elles, ne bougent pas — consigne explicite). Le contrôle
     `outilserifier-palettes.mjs` a été réécrit en conséquence : il vérifie
     désormais que la marque vaut le vert lumineux, pas qu'elle appartient au
     catalogue. Le but reste le même — qu'elle ne redevienne jamais ORPHELINE.
     📏 Les contrastes s'AMÉLIORENT : texte sombre sur le bouton 8,5 → 13,2:1 ·
     marque sur le fond 9,4 → 14,6:1.
     ⚠️ `--af-action` suit (`var(--af-marque)`) : le bouton JOUER passe donc au
     même vert. Son ÉCLAT a été remonté d'autant, sinon base et éclat se
     confondaient et le bouton perdait son relief.
     ↩️ Valeurs d'avant : `--af-marque: #6bdb55` · `--af-marque-contour: #2d7020`
        · `--af-action-clair: #c7ffbc`. */
  /* ⚠️ FONCÉ D'UN CRAN le 2026-08-27 (#c7ffbc → #9ceb8c, demande utilisateur : « un
     tout petit peu plus foncé »). Le pâle avait un défaut mesuré : l'ÉCLAT du bouton
     n'était plus qu'à 1,07:1 de sa base, autant dire invisible. À #9ceb8c la
     séparation remonte à 1,34:1 — le relief se voit à nouveau. Et rien ne se perd :
     texte du bouton 10,5:1, marque sur le fond 11,6:1, très au-dessus des seuils. */
  --af-marque: #9ceb8c;          /* le vert lumineux — N'EST PLUS une couleur de joueur */
  --af-marque-contour: #4a803f;  /* formule de contour (même teinte, S+10, V−42) */
  /* ⚠️ `--af-marque` et `--af-action` DÉSIGNENT LA MÊME VALEUR, et c'est voulu :
     le vert du jeu est celui de sa mascotte. Deux noms parce que deux RÔLES —
     l'identité d'un côté, « ceci se clique » de l'autre. Le jour où l'un des deux
     doit s'en détacher, il y a déjà un endroit où l'écrire. */

  /* ═══ LE BADGE « NOUVEAU » ══════════════════════════════════════════════ *
   * Variante E, tranchée le 2026-08-02 après MESURE de la palette. Le badge était
   * corail (l'ancien « activable »), puis vert d'action — mais le vert doit rester
   * celui du BOUTON dominant, et un badge n'est pas un bouton.
   * ⚠️ Pourquoi pas une teinte neuve : sur les 16 teintes déjà prises par le
   * projet, un seul vrai trou subsiste (91° entre le citron et le vert d'action).
   * Le magenta, candidat évident, s'est révélé DISQUALIFIÉ à la mesure — 16 à 21°
   * du violet BONUS, et un contraste de 2,4:1 sur le fond, sous le seuil de
   * lisibilité. Le lime du centre du trou tenait la route (45° de marge, 6,2:1),
   * mais la charte §5.1 réserve les couleurs les plus vives aux FEEDBACKS.
   * D'où ce choix : le crème INVERSÉ. Il n'ajoute aucune teinte et n'emprunte à
   * aucune famille — écart 46 de la plus proche, mesuré.
   *
   * ⚠️ IL A CESSÉ DE POINTER SUR `--af-texte` le 2026-08-08, et le commentaire
   * ci-dessus disait déjà pourquoi c'était possible : « le jour où il change, il
   * change ICI ». Le renvoi valait tant que le texte ÉTAIT crème ; « Nuit
   * franche » l'a passé au BLANC PUR, et un badge blanc plein sur un fond
   * presque noir devient l'objet le plus lumineux de l'écran — il criait plus
   * fort que le bouton JOUER pour dire seulement « il y a du neuf »
   * (retour utilisateur). Il porte donc sa propre valeur.
   * ⚠️ HONNÊTETÉ DU CHIFFRE : le crème ne fait descendre le contraste que de
   * 19,3:1 à 17,1:1 — 11 %. Il RÉCHAUFFE surtout. Si le badge devait vraiment
   * s'effacer, le levier n'est pas la teinte mais l'INVERSION (pilule sombre,
   * texte clair) ou la taille. À rouvrir seulement si ça crie encore. */
  --af-badge: #f4f1e8;
  --af-badge-texte: var(--af-nuit);
  --af-badge-relief: #aba9a2;  /* formule de relief (S ×1,05 · V ×0,70) sur le crème :
                                  un gris CHAUD, là où `--af-texte-attenue` est bleuté */

  /* ═══ INTERFACE ═════════════════════════════════════════════════════════ *
   * ⚠️ REPRIS le 2026-08-08 avec « Nuit franche », et ça corrige un vrai défaut :
   * les panneaux, le liseré et le texte atténué étaient VIOLETS pendant que le
   * fond était BLEU — deux familles de teinte sur le même écran, sans raison.
   * Tout revient dans la famille du fond. Le texte passe au BLANC PUR : contraste
   * maximal en action, là où le crème chaud coûtait de la lisibilité. */
  --af-panneau: rgba(10, 14, 23, 0.86);        /* translucide : la nuit respire au travers */
  --af-panneau-bord: rgba(255, 255, 255, 0.14); /* liseré blanc 1 px */
  --af-texte: #ffffff;
  --af-texte-attenue: #93a1b8;
  /* ═══ ESSAI « PALETTE VITRINE » — LES TITRES (2026-08-27) ══════════════════
     Motif de l'utilisateur : « aujourd'hui tous les textes sont blancs, c'est un
     peu dur de distinguer les titres et les sous-titres ». La vitrine, elle,
     hiérarchise déjà — titres en vert lumineux, valeurs en or.
     ⚠️ DEUX JETONS À EUX, et pas des alias de `--af-action-clair` et
     `--af-monnaie` : ils portent aujourd'hui la MÊME valeur, mais un titre n'est
     ni une action ni une pièce. Les garder distincts permet de bouger l'un sans
     traîner l'autre — et surtout de ne pas réattribuer la famille sémantique
     MONNAIE, ce que la charte §2 interdit.
     ⚠️ AVANT L'ESSAI, les deux valaient `--af-texte` (blanc) partout. */
  /* ⚠️ DEVENU UN ALIAS le 2026-08-27 : le vert lumineux EST maintenant la
     marque. Garder deux littéraux identiques, c'était fabriquer le doublon
     que ce fichier existe pour empêcher. */
  --af-titre: var(--af-marque);
  --af-sous-titre: #ffc94d;  /* l'or — même valeur que la pièce, autre rôle */

  /* ═══ LE VERT — IL N'Y EN A QU'UN ═══════════════════════════════════════ *
   * ⚠️ DÉCISION UTILISATEUR DU 2026-08-02, et elle a été prise à l'œil nu : le
   * bouton JOUER était à `#33c47f` et la marque à `#4fc39a` — SEPT degrés de
   * teinte d'écart, pour une valeur identique à 0,4 % près. Deux couleurs qu'on
   * ne confond jamais sont séparées d'environ 45° ; à 7°, l'œil ne lit pas « deux
   * verts » mais « le même, mal reproduit ».
   * Le projet n'a donc plus qu'UN vert, et c'est une COULEUR DE PERSONNAGE. Il
   * sert au bouton d'action, aux liens cliquables et aux filets des titres de
   * section : partout où quelque chose appartient au jeu ou se clique.
   * ⚠️ Il reste HORS des quatre familles sémantiques.
   * ⚠️ LA MÊME ERREUR A FAILLI SE REFAIRE le 2026-08-08 : la planche de palette
   * proposait un vert d'action `#31c46f`, à DIX degrés du Vert du catalogue —
   * exactement le défaut corrigé six jours plus tôt. Écarté. Un vert, un seul,
   * et c'est celui que porte un alien.
   * Les trois déclinaisons ne sont pas choisies à l'œil : ce sont les ÉCARTS
   * exacts de la charte (clair = S×0,43 V×1,23 · relief = S×1,05 V×0,70). */
  --af-action: var(--af-marque);
  /* ⚠️ DÉRIVÉ DE LA MARQUE par une formule écrite : même teinte, saturation −14
     points, valeur au maximum. Vérifié par `outilserifier-palettes.mjs`, qui a
     été élargi le 2026-08-27 précisément parce qu'un jeton voisin (`action-relief`)
     s'était périmé sans que rien ne le dise — c'est l'utilisateur qui l'a vu.
     📏 Il ne s'agit pas de coquetterie : quand la marque était à #c7ffbc, l'éclat
     n'était plus qu'à **1,07:1** de sa base, c'est-à-dire invisible. La marque
     foncée d'un cran, la formule rend #c7ffbc et la séparation remonte à 1,26:1. */
  --af-action-clair: #c7ffbc;      /* éclat, liseré haut */
  /* ⚠️ UN SEUL RELIEF POUR LE VERT — corrigé le 2026-08-27, défaut repéré à l'œil
     par l'utilisateur : « pourquoi la deuxième couleur du bouton qui fait son relief
     et la deuxième couleur du titre qui fait le relief ne sont pas la même ? »
     Elles ne l'étaient pas, et pour DEUX raisons cumulées :
     ① ce jeton valait encore #479937, dérivé de l'ANCIEN vert — je l'avais oublié en
        changeant la marque. Le bouton portait donc l'ombre d'un vert qui n'existait
        plus : « la moitié de l'écran restée sur l'ancienne palette », en miniature ;
     ② même à jour, les deux suivaient des FORMULES DIFFÉRENTES pour le même rôle
        (S+3 V−26 ici, S+10 V−42 pour le titre) — deux ombres plates `0 4px 0` sous
        deux éléments verts n'ont aucune raison de différer.
     👉 Une seule source. Le titre et le bouton portent désormais la même ombre, et
     elle suit la marque toute seule. */
  --af-action-relief: var(--af-marque-contour);  /* l'ombre plate `0 4px 0` */
  --af-action-texte: #132c0e;      /* le texte POSÉ sur le vert — contraste 8,5:1, mesuré.
                                      Même formule que les trois autres (V×0,20 de la
                                      teinte de marque) : un bouton se décline, il ne
                                      s'invente pas. */

  /* ═══ HUD ═══════════════════════════════════════════════════════════════ *
   * Toujours sur pilule, jamais en texte nu sur le jeu.                      */
  --af-hud-pilule: rgba(10, 14, 23, 0.80);
  --af-hud-score: var(--af-texte);
  --af-hud-kills: #ff9d6e;    /* ⚠️ accent HUD UNIQUEMENT — plus jamais posé sur le sol */
  --af-hud-assists: #b9a8e0;
  --af-hud-pieces: var(--af-monnaie);

  /* ═══ RAYONS — la grille, et RIEN en dehors (charte §2 Interface) ═══════ */
  --af-rayon-panneau: 20px;   /* panneaux majeurs */
  --af-rayon-bouton: 16px;    /* boutons */
  --af-rayon-carte: 12px;     /* cartes et champs */
  --af-rayon-pilule: 999px;   /* pilules */
}


/* ── La typographie commune à TOUTES les pages (charte §4) ────────────────── */
body {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  color: var(--af-texte);
}
h1, h2, h3, .af-titre {
  font-family: 'Baloo 2', system-ui, sans-serif;
  font-weight: 800;
}
/* Les compteurs ne doivent pas sautiller quand un chiffre change. */
.af-nombre { font-variant-numeric: tabular-nums; }
