/* ==========================================================================
   TOKENS — source unique de vérité
   Aucune valeur en dur ailleurs. Jamais. (CADRAGE §7.1 bis A)
   ========================================================================== */

:root {

  /* — Fonts ————————————————————————————————————————————————————————————— */
  --font-display: 'Outfit', sans-serif;          /* titres, noms, chiffres */
  --font-text:    'Roboto', sans-serif;          /* lecture, labels, UI    */

  /* — Graisses ——————————————————————————————————————————————————————————
     Outfit est VARIABLE (100→900), Roboto est chargée en 300 et 600.

     ⚠️ DEUX FAMILLES, DEUX ÉCHELLES. Outfit est variable : elle accepte
     n'importe quelle graisse. Roboto n'est chargée QU'EN 300 ET 600 —
     lui demander 900 ferait synthétiser un faux gras par le navigateur,
     au rendu grossier. Les tokens sont donc séparés par famille :

       texte (Roboto)     --fw-light 300  ·  --fw-bold 600
       display (Outfit)   --fw-light 300 (titres)  ·  --fw-mid 500 (natures)

     Chaque famille garde ainsi deux graisses — le plafond du §7.1 bis C
     tient, il s'applique simplement par famille et non globalement.
     Toute autre hiérarchie passe par taille / couleur / casse.             */
  --fw-light: 300;
  --fw-mid:   500;   /* natures de la fiche — display uniquement */
  --fw-bold:  600;   /* TEXTE (Roboto) — la seule graisse forte chargée */
  /* ⚠️ `--fw-black` (900) a été RETIRÉ le 31/07/2026 : les titres display
     sont passés en `--fw-light`, et plus rien ne le lisait. Un token qui
     ne règle plus rien devient un piège à la relecture (§7.1 bis A). */

  /* — Tailles — 6 paliers max (CADRAGE §7.1 bis C) ——————————————————————— */
  --fs-label:   11px;                        /* labels, mentions, micro    */
  --fs-body:    14px;                        /* texte courant              */
  --fs-value:   18px;                        /* valeur mise en avant       */
  --fs-read:    30px;                        /* récit long — intro, description
                                                 de la fiche. Fixe : pas de clamp,
                                                 le repli mobile bascule sur
                                                 --fs-value plutôt que de le
                                                 faire varier en continu       */
  --fs-title:   clamp(20px, 2.4vw, 32px);    /* sous-titres, intro         */
  --fs-display: clamp(36px, 4.8vw, 68px);    /* titres de section          */
  --fs-hero:    clamp(48px, 7vw, 110px);     /* nom de projet              */

  /* — Couleurs ————————————————————————————————————————————————————————— */
  --ink:       #111111;   /* texte par défaut                              */
  --ink-soft:  #777777;   /* hiérarchie secondaire                         */
  --paper:       #d8d8d8; /* fond de la landing                            */
  --paper-light: #f0f0f1; /* fond de la fiche projet                       */
  /* ⚠️ L'ACCENT EST UN APLAT, JAMAIS UNE COULEUR DE TEXTE.

     Le vert lemon a remplacé le rouge #cc2200 le 31/07/2026. En texte il
     donne **1,23:1 sur blanc** — invisible ; en fond avec du noir dessus,
     **15,3:1**. Ce n'est pas un défaut de la couleur, c'est sa nature.

     ⚠️ IL NE SERT PLUS QU'À L'ALERTE. Le même jour, il a été essayé sur
     l'infobox, la pastille du hero et le surlignage des liens — les trois
     sont revenus au noir. La leçon tient en une phrase : **une couleur qui
     ne dure pas se juge autrement qu'une couleur qui accompagne.** Un
     repère permanent en vert lemon prend le pas sur un corpus d'images
     désaturées ; une alerte, elle, doit trancher.

     Le noir a l'autre avantage : il est lisible sur les deux fonds du site
     et sur n'importe quelle image de hero, dont on ne maîtrise pas la
     teinte.                                                              */
  --accent:    #AAFF00;   /* réservé à l'alerte (`.is-accent`)             */
  --ink-invert:#ffffff;   /* texte sur aplat noir (logo, infobox)          */

  /* Aplats */
  --block:     #000000;   /* carré logo, infobox                           */
  --hint-bg:   #39FF14;   /* pastille « scroll for more » — vert fluo      */

  /* Texture de fond — opacité réglable seule, sans toucher à --paper      */
  --texture-opacity: 0.5;

  /* Trame du hero, façon écran cathodique — opacité simple, jamais de blend.
     vignette : assombrissement des bords. La trame elle-même est un PNG. */
  --crt-vignette: 0.35;

  /* — Grille 12 (CADRAGE §4.1) ——————————————————————————————————————————
     Tout le site est calé dessus : modules 4 col / 2 col / 1 col.          */
  --grid-cols: 12;
  --grid-gap:  0px;   /* les boîtes se touchent — la trame est jointive */

  /* — Rythme VERTICAL ————————————————————————————————————————————————————
     ⚠️ La trame en carrés régit l'HORIZONTAL. Un carré vaut `vw / 12` : il
     n'a aucun rapport fixe à la hauteur, si bien qu'un placement vertical
     exprimé en carrés dérive de ~13% entre un 16:10 et un 16:9 — la même
     page ne se compose plus pareil selon l'écran.
     Le vertical se règle donc en `vh`. Décision prise à l'écran, après
     avoir essayé les carrés (CADRAGE §4.3).                               */
  --v-body:    12vh;   /* air au-dessus du texte, sous le hero             */

  /* — ESPACEMENTS — les écarts À L'INTÉRIEUR du texte ————————————————————

     ⚠️ DEUX FAMILLES, ET ELLES NE SE MÉLANGENT PAS.

     `--v-*` ci-dessus est en `vh` : il COMPOSE L'ÉCRAN — l'air avant le
     corps, le recul de la galerie. Ces valeurs doivent suivre la hauteur
     disponible, c'est leur raison d'être.

     `--sp-*` ici est en `rem` : il RYTHME LE TEXTE — titre/natures,
     intro/description, entre paragraphes. En `vh`, l'écart entre un titre
     et son intro se serrerait sur un 16:9 court et s'ouvrirait sur un
     grand écran : la respiration du texte deviendrait subie au lieu d'être
     composée. Un rapport typographique ne dépend pas de la fenêtre.

     LA RÈGLE, en une phrase : entre deux éléments de texte → `--sp-*` ;
     entre deux sections de la page → `--v-*`.

     ⚠️ NOMMÉS PAR RÔLE, PAS PAR RANG. Une première version numérotait les
     paliers (`--sp-1` … `--sp-5`) en doublant à chaque cran. Deux réglages à
     l'œil ont suffi à la casser : l'écart titre/texte devait grandir, celui
     de fin de page rétrécir — et `--sp-4` s'est retrouvé plus grand que
     `--sp-5`. Les noms mentaient, et la seule façon de les remettre d'aplomb
     était de renuméroter, donc de renommer partout.

     Un rôle ne peut pas être « dans le mauvais ordre ». Chacun se règle à
     l'œil sans rien devoir aux autres — ce qui est exactement ce qu'on fait
     devant l'écran. La contrepartie est qu'il faut se retenir d'en créer un
     par cas : un nom nouveau ne se justifie que si l'écart qu'il décrit
     existe à plusieurs endroits (§7.1 bis A).                              */
  --sp-tight:   0.5rem;   /*   8px — ce qui se colle : natures sous le titre,
                                     label et sa valeur, gaps internes       */
  --sp-close:     1rem;   /*  16px — entre paragraphes : l'écart de lecture   */
  --sp-block:     2rem;   /*  32px — entre deux blocs voisins : intro →
                                     description, paires de crédits          */
  --sp-part:      4rem;   /*  64px — entre deux parties d'une même vue :
                                     titre → texte et texte → contact dans
                                     l'about, médias empilés d'une galerie   */
  --sp-section:   8rem;   /* 128px — entre deux temps de la fiche : titre →
                                     texte, récit → crédits                  */
  --sp-end:       6rem;   /*  96px — ce qui ferme : avant le pas à pas, bas
                                     de page                                 */

  /* — Durées — tokens, pas des nombres dispersés (§7.1 bis B) ———————————— */
  --d-fast: 200ms;
  --d-base: 400ms;
  --d-slow: 800ms;

  /* Le temps d'annonce du pas à pas : la fiche s'écarte et découvre la
     colonne AVANT que le projet ne change (§4.4). Token à part et non
     `--d-slow`, bien que ce soit lui qui porte le décalage : ce qu'on règle
     ici n'est pas la vitesse du mouvement mais LE TEMPS QU'ON LAISSE avant
     d'enchaîner. Les confondre reviendrait à ne plus pouvoir raccourcir
     l'attente sans accélérer aussi le glissement du décor et le survol.   */
  --d-step: 600ms;

  /* — Easings ——————————————————————————————————————————————————————————— */
  --e-out:   cubic-bezier(0.16, 1, 0.30, 1);    /* sortie franche, se pose */
  --e-inout: cubic-bezier(0.65, 0, 0.35, 1);    /* symétrique, aller-retour*/

  /* — SON — les volumes sont des tokens, comme les durées ————————————————

     ⚠️ Même raison qu'au §7.1 bis B pour les timings : régler le son du site
     doit être un geste, pas une chasse dans `audio.js`. Ce sont des gains
     linéaires (0 → 1), lus UNE FOIS à la création du contexte audio — jamais
     sur le chemin d'un son, où la lecture tomberait sur la frame d'un clic.

     ⚠️ ILS NE SUIVENT PAS `prefers-reduced-motion`. Ne pas vouloir de
     mouvement et ne pas vouloir de son sont deux préférences distinctes, et
     le navigateur les expose séparément. Le son est de toute façon coupé par
     défaut : personne ne l'entend sans l'avoir demandé.                    */
  /* ⚠️ CES TROIS VALEURS SE MULTIPLIENT — c'est ce qui rendait tout inaudible.

     La nappe sort à `master × pad`, les sons d'interface à `master × sfx` :
     avec 0.35 / 0.18, la nappe jouait à **6 % du volume**. Chaque token
     paraissait raisonnable isolément, et le produit ne se lit nulle part.

     Relevés le 11/08/2026 après écoute. La hiérarchie est conservée : la
     nappe reste SOUS les sons d'interface, pour que ceux-ci ressortent sans
     qu'on ait à les pousser (§4.7).                                        */
  --snd-master: 0.85;   /* le volume général — ce que le casque module      */
  --snd-pad:    0.55;   /* la nappe, sous le master : elle accompagne       */
  --snd-sfx:    0.70;   /* les sons de l'interface                          */

  /* Le fondu du casque, en ms.

     ⚠️ IL NE PEUT PAS ÊTRE `--d-slow`, bien qu'il en porte la valeur. Les
     durées ci-dessus tombent à 1ms sous `prefers-reduced-motion` — juste
     pour un mouvement à l'écran, faux ici : le son se couperait NET au lieu
     de descendre, soit exactement le défaut que ce fondu existe pour
     éviter. Il vit donc hors de la media query.

     Même raisonnement qu'au `--d-step` : une valeur qui décrit autre chose
     que le token voisin prend son propre nom (§4.4).                     */
  --snd-fade:  800;

  /* — Profondeur (CSS 3D — §7.1 ter) ————————————————————————————————————— */
  --perspective: 1200px;


  /* — Couches ——————————————————————————————————————————————————————————— */
  --z-grid:    1;
  --z-project: 10;
  --z-logo:    100;
  --z-info:    200;   /* l'infobox suit le curseur : rien ne la masque */
  --z-texture: 250;   /* la texture recouvre tout le site               */
  --z-corners: 300;   /* les 4 mentions : au-dessus de tout, toujours   */
  --z-veil:    350;   /* le voile — assombrit le site poussé, DEVANT les
                         coins (ils partent avec le site) et DERRIÈRE le
                         volet, qui seul reste en pleine lumière        */
  --z-about:   400;   /* le volet about — il POUSSE le site, donc rien
                         ne doit passer devant lui, pas même les coins  */
  --z-consent: 500;   /* le bandeau cookies — au-dessus de tout, y compris
                         l'about : une décision RGPD n'attend pas qu'on
                         referme un volet pour être prise               */
}

/* Le mouvement est le sujet du site — mais il ne s'impose à personne.
   (CADRAGE §7.2)                                                          */
@media (prefers-reduced-motion: reduce) {
  :root {
    --d-fast: 1ms;
    --d-base: 1ms;
    --d-slow: 1ms;
    /* Sans ça, le pas à pas attendrait 600ms devant un mouvement supprimé. */
    --d-step: 1ms;
  }
}

/* `--ink` doit être ANIMABLE : les coins le basculent en blanc au-dessus du
   hero (`.corner.is-over`, main.css) et tout ce qu'ils contiennent le suit
   image par image, sans qu'aucun enfant ne déclare sa propre transition.
   Déclarer la propriété n'en change pas la valeur : c'est `:root` qui la pose. */
@property --ink {
  syntax: '<color>';
  inherits: true;
  initial-value: #111111;
}
