/* ═══════════════════════════════════════════════════════════════════════
   paso-tokens.css — ÉTAGE 0 du design system : les tokens SÉMANTIQUES.
   ───────────────────────────────────────────────────────────────────────
   POURQUOI CE FICHIER EXISTE
   Jusqu'ici on sautait du token PRIMITIF (--navy, --gray-200) directement à
   l'usage (`background:var(--white)`). Résultat : impossible de changer une
   intention ("les bordures discrètes") sans un chercher-remplacer global, et
   le white-label devait recalculer 84 color-mix() au runtime.

   Ici on pose l'étage du MILIEU : des tokens d'INTENTION, tous DÉRIVÉS des
   primitifs via var(). Conséquence directe et voulue : quand paso-brand.js ou
   paso-tenants.js surchargent --navy/--amber sur :root, TOUT cet étage suit
   automatiquement. Le white-label devient gratuit.

   RÈGLE D'USAGE (à tenir) :
     • Un COMPOSANT ne consomme QUE des tokens sémantiques (--surface-*, --text-*…).
     • Un token sémantique ne consomme QUE des primitifs (--navy, --gray-*…).
     • On n'écrit JAMAIS une valeur brute (#hex, 14px) dans un composant.

   ORDRE DES COUCHES (déclaré ici, une seule fois pour toute la lib) :
     paso.reset < paso.tokens < paso.base < paso.components < paso.patterns < paso.utilities
   Le CSS NON-LAYERÉ (tout paso-ui.css historique + le CSS local des outils)
   garde la PRIORITÉ LA PLUS HAUTE — c'est volontaire, c'est le filet de
   sécurité de la migration : l'existant continue de gagner tant qu'un
   composant ne l'a pas remplacé. Quand un composant est validé, son CSS
   legacy est supprimé de paso-ui.css et la couche prend le relais. Cliquet.

   DEUX BLOCS AJOUTÉS LE 2026-08-27, tous deux documentés sur place :
     1. la triade --accent-fill / --accent-ink / --accent-base, qui NOMME la
        paire fond/encre de l'ambre au lieu de la laisser à l'oeil de chacun ;
     2. le socle :root[data-theme="dark"], inerte tant que l'attribut n'est
        pas posé, donc sans effet sur l'existant.

   Charger AVANT paso-ui.css :
     <link rel="stylesheet" href="../_shared/paso-tokens.css">
     <link rel="stylesheet" href="../_shared/paso-ui.css">
   ═══════════════════════════════════════════════════════════════════════ */

@layer paso.reset, paso.tokens, paso.base, paso.components, paso.patterns, paso.utilities;

/* ═══ RESET MINIMAL ═════════════════════════════════════════════════════
   POURQUOI (vécu 2026-07-27, détecté au screenshot) : la palette ⌘K
   (.pui-cmdk-item) est en `width:100%` PLUS `padding:11px 16px`. Sans
   box-sizing:border-box elle déborde de 32 px exactement et les badges de
   raccourci sont coupés. La bibliothèque SUPPOSAIT donc que la page hôte
   pose le box-sizing — une dépendance implicite jamais écrite, et 14 des
   27 outils ne la posent pas.

   Une supposition tacite est un piège ; on la rend explicite ici, dans la
   couche la PLUS BASSE : n'importe quelle page peut encore surcharger.
   `:where()` met la spécificité à 0 → ces règles ne se battent jamais.
   ═══════════════════════════════════════════════════════════════════════ */
@layer paso.reset {
  *, *::before, *::after { box-sizing: border-box; }
  /* Un média ne déborde jamais de son conteneur (cause n°1 de scroll horizontal). */
  :where(img, svg, video, canvas) { max-width: 100%; }
  /* Les contrôles héritent de la typo au lieu de la police système du navigateur. */
  :where(button, input, select, textarea) { font-family: inherit; }
}

@layer paso.tokens {
  :root {
    /* ─── SURFACES ─────────────────────────────────────────────────────
       De la plus basse (fond de page) à la plus haute (élément inversé). */
    --surface-page:         var(--bg-page);
    --surface-sunken:       var(--gray-50);
    --surface-raised:       var(--white);
    --surface-overlay:      var(--white);
    --surface-inverse:      var(--navy);
    --surface-inverse-deep: var(--navy-deep);
    --surface-accent:       var(--amber);
    --surface-accent-soft:  color-mix(in srgb, var(--amber) 8%, transparent);
    --surface-muted:        var(--gray-100);
    --surface-hover:        var(--gray-50);

    /* ─── TEXTE ─────────────────────────────────────────────────────────
       Quatre niveaux de hiérarchie. Au-delà, c'est du bruit. */
    --text-strong:     var(--navy);
    --text-default:    var(--gray-800);
    --text-muted:      var(--gray-600);
    --text-subtle:     var(--gray-400);
    --text-inverse:    var(--white);
    --text-on-inverse-muted: color-mix(in srgb, var(--white) 62%, transparent);
    --text-accent:     var(--amber-dark);
    --text-on-accent:  var(--white);

    /* ─── BORDURES ─────────────────────────────────────────────────────*/
    --border-subtle:  var(--gray-200);
    --border-default: var(--gray-300);
    --border-strong:  var(--gray-400);
    --border-accent:  color-mix(in srgb, var(--amber) 30%, transparent);
    --border-inverse: color-mix(in srgb, var(--white) 14%, transparent);

    /* ─── ÉTATS SÉMANTIQUES ────────────────────────────────────────────
       Un état = un trio fg / bg / border. Aucun composant ne réinvente
       sa palette d'alerte : il pioche un trio. */
    --state-good-fg:     var(--good);
    --state-good-bg:     var(--good-bg);
    --state-good-border: color-mix(in srgb, var(--good) 28%, transparent);

    --state-warn-fg:     var(--amber-dark);
    --state-warn-bg:     color-mix(in srgb, var(--amber) 12%, transparent);
    --state-warn-border: color-mix(in srgb, var(--amber) 30%, transparent);

    --state-bad-fg:      var(--bad);
    --state-bad-bg:      var(--bad-bg);
    --state-bad-border:  color-mix(in srgb, var(--bad) 25%, transparent);

    --state-info-fg:     var(--info);
    --state-info-bg:     var(--info-bg);
    --state-info-border: color-mix(in srgb, var(--info) 25%, transparent);

    --state-neutral-fg:     var(--gray-700);
    --state-neutral-bg:     var(--gray-100);
    --state-neutral-border: var(--gray-200);

    /* ─── ESPACEMENT ───────────────────────────────────────────────────
       Échelle de 4. Un composant qui a besoin d'un 13px a un problème
       de conception, pas de token. */
    --space-0: 0;
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 40px;
    --space-9: 56px;

    /* ─── ÉLÉVATION (alias d'intention des --shadow-*) ──────────────────*/
    --elevation-0: none;
    --elevation-1: var(--shadow-sm);
    --elevation-2: var(--shadow-md);
    --elevation-3: var(--shadow-lg);

    /* ─── FOCUS (accessibilité — un seul anneau pour toute la plateforme) */
    --focus-ring:        0 0 0 3px color-mix(in srgb, var(--amber) 45%, transparent);
    --focus-ring-inverse: 0 0 0 3px color-mix(in srgb, var(--white) 55%, transparent);
    --focus-outline:     2px solid var(--amber);

    /* ─── MOUVEMENT ────────────────────────────────────────────────────*/
    --motion-fast: var(--t-fast);
    --motion-base: var(--t-base);
    --motion-slow: 360ms;
    --motion-ease: var(--ease);
    --motion-ease-out: cubic-bezier(.16, 1, .3, 1);

    /* ─── TYPO (intentions, adossées à l'échelle --fs-*) ────────────────*/
    --text-size-display: var(--fs-display);
    --text-size-title:   var(--fs-h2);
    --text-size-heading: var(--fs-h3);
    --text-size-body:    var(--fs-body);
    --text-size-sm:      var(--fs-sm);
    --text-size-xs:      var(--fs-xs);
    --text-size-label:   var(--fs-label);
    --text-numeric: 700 var(--fs-h3) / 1 var(--font);

    /* ─── ACCENT SCINDÉ EN TROIS RÔLES (2026-08-27) ─────────────────────
       POURQUOI. L'ambre de marque a un défaut physique : il est trop clair
       pour porter du texte sur fond clair, et trop foncé pour porter du
       texte blanc. Un seul token nommé « accent » oblige donc chaque écran
       à redécider, à l'oeil, s'il écrit en blanc ou en sombre dessus.
       La charte disait déjà « l'ambre est un accent ponctuel, jamais une
       couleur de remplissage » et « jamais sur du texte long », mais aucune
       PAIRE fond/encre n'était nommée : la règle restait déclarative au
       lieu d'être mécanique. On la rend mécanique en scindant l'accent en
       trois rôles distincts, chacun dérivé des primitifs existants.

       --accent-fill  le FOND des CTA et des éléments pleins. L'ambre vif,
                      identique dans les deux thèmes : c'est la marque, et
                      la marque ne se relooke pas avec le thème.
       --accent-ink   le TEXTE et l'ICÔNE posés SUR ce fond. Sombre dans
                      les deux thèmes, JAMAIS blanc : du blanc sur l'ambre
                      ne donne que 2,62:1, très en dessous du plancher WCAG
                      AA de 4,5:1, donc illisible pour un libellé de bouton.
                      Le navy de marque sur ce même ambre donne 6,57:1.
       --accent-base  le TEXTE et la BORDURE écrits EN accent, posés sur
                      une surface neutre. En thème clair il faut assombrir :
                      l'ambre vif sur le fond de page ne fait que 2,53:1, et
                      --amber-dark seul 3,72:1, toujours sous AA. On le
                      pousse donc de 15 % vers le navy, ce qui atteint
                      4,70:1 tout en restant reconnaissable comme de l'ambre.
                      En thème sombre l'ambre vif suffit (7,39:1 sur --black).

       NOTE DE COMPATIBILITÉ. --text-on-accent vaut encore --white plus
       haut : c'est exactement la dette que cette triade corrige. On ne le
       change PAS en thème clair, pour qu'aucun écran existant ne bouge.
       Tout nouvel écran utilise --accent-ink. */
    --accent-fill: var(--amber);
    --accent-ink:  var(--navy);
    --accent-base: color-mix(in srgb, var(--amber-dark) 85%, var(--navy));
  }

  /* Respect systémique du réglage d'accessibilité : aucune surface de la
     plateforme n'anime quoi que ce soit si l'OS demande le calme. */
  @media (prefers-reduced-motion: reduce) {
    :root {
      --motion-fast: 1ms;
      --motion-base: 1ms;
      --motion-slow: 1ms;
    }
  }

  /* ═══ SOCLE DU THÈME SOMBRE (2026-08-27) ═══════════════════════════════
     POURQUOI UN ATTRIBUT ET PAS prefers-color-scheme. La bascule reste un
     CHOIX EXPLICITE. Un outil d'agence s'ouvre en partage d'écran devant un
     client : le réglage nocturne de l'OS du poste n'a pas à décider seul de
     la tête d'un livrable. Tant que le document ne porte pas
     data-theme="dark", ce bloc est inerte, donc le fichier reste
     strictement rétrocompatible.

     CE QU'ON REDÉFINIT ICI, ET RIEN D'AUTRE : les tokens d'INTENTION déjà
     déclarés plus haut. Aucun primitif de marque n'est touché. --navy et
     --amber gardent leur valeur dans les deux thèmes, c'est la marque.
     Aucune surface n'est basculée non plus : ce bloc est un SOCLE, les
     écrans viendront s'y brancher ensuite, un par un.

     LE FOND PART DE --black, PAS DE --navy. Règle Paso : en aplat plein
     écran, le navy est trop vibrant et fatigue l'oeil. Le fond de page est
     donc le noir de marque, et l'élévation se lit en REMONTANT par voiles
     de blanc (6 %, 9 %, 12 %, 14 %). Sur un thème sombre, plus une surface
     est haute, plus elle est claire : l'inverse du thème clair.
     ═══════════════════════════════════════════════════════════════════ */
  :root[data-theme="dark"] {
    /* ─── SURFACES ─────────────────────────────────────────────────────*/
    --surface-page:         var(--black);
    /* Rien ne descend sous le fond de page en thème sombre : le plancher
       est déjà le noir de marque. « Enfoncé » y vaut « au ras du sol ». */
    --surface-sunken:       var(--black);
    --surface-raised:       color-mix(in srgb, var(--white) 6%, var(--black));
    --surface-muted:        color-mix(in srgb, var(--white) 9%, var(--black));
    --surface-overlay:      color-mix(in srgb, var(--white) 12%, var(--black));
    --surface-hover:        color-mix(in srgb, var(--white) 14%, var(--black));
    /* « Inverse » veut dire « à contre-courant du thème » : en sombre,
       c'est donc une surface CLAIRE. Le couple surface/texte bascule
       ensemble, sinon on obtiendrait du blanc sur du blanc. */
    --surface-inverse:      var(--white);
    --surface-inverse-deep: var(--gray-100);
    /* L'ambre reste l'ambre ; seul le voile doux est renforcé, parce que
       8 % de teinte posés sur du noir ne se voient tout simplement pas. */
    --surface-accent:       var(--amber);
    --surface-accent-soft:  color-mix(in srgb, var(--amber) 16%, transparent);

    /* ─── TEXTE ─────────────────────────────────────────────────────────
       Les quatre niveaux gardent leur écart relatif. Mesuré sur une carte
       (--surface-raised) : 13,0:1 pour le courant, 6,0:1 pour l'atténué,
       4,8:1 pour le discret. */
    --text-strong:     var(--white);
    --text-default:    var(--gray-200);
    --text-muted:      var(--gray-400);
    --text-subtle:     var(--navy-light);
    /* Posé sur --surface-inverse, qui est CLAIRE ici : donc du navy. */
    --text-inverse:    var(--navy);
    --text-on-inverse-muted: color-mix(in srgb, var(--navy) 62%, transparent);
    /* Sur fond sombre l'ambre vif est lisible (7,39:1) : inutile de
       l'assombrir comme on le fait en thème clair. */
    --text-accent:     var(--amber);
    /* On ne reconduit pas la dette du thème clair : l'encre posée sur de
       l'ambre est sombre, jamais blanche. Voir --accent-ink. */
    --text-on-accent:  var(--navy);

    /* ─── BORDURES ─────────────────────────────────────────────────────
       En sombre, une bordure n'est plus un gris plus foncé que le fond,
       c'est un voile de LUMIÈRE. On passe donc aux mix de blanc, qui
       suivent automatiquement la surface sur laquelle ils se posent. */
    --border-subtle:  color-mix(in srgb, var(--white) 10%, transparent);
    --border-default: color-mix(in srgb, var(--white) 16%, transparent);
    --border-strong:  color-mix(in srgb, var(--white) 28%, transparent);
    --border-accent:  color-mix(in srgb, var(--amber) 45%, transparent);
    --border-inverse: color-mix(in srgb, var(--navy) 14%, transparent);

    /* ─── ÉTATS SÉMANTIQUES ────────────────────────────────────────────
       Le trio s'inverse : le fond devient une teinte SOMBRE de l'état
       (mélangée au noir de page) et le texte une teinte CLAIRE. Ratios
       texte/fond obtenus : bon 7,9:1, alerte 9,7:1, mauvais 7,1:1,
       info 7,3:1. */
    --state-good-fg:     color-mix(in srgb, var(--good) 55%, var(--white));
    --state-good-bg:     color-mix(in srgb, var(--good) 18%, var(--black));
    --state-good-border: color-mix(in srgb, var(--good) 42%, transparent);

    --state-warn-fg:     var(--amber-light);
    --state-warn-bg:     color-mix(in srgb, var(--amber) 16%, var(--black));
    --state-warn-border: color-mix(in srgb, var(--amber) 40%, transparent);

    --state-bad-fg:      color-mix(in srgb, var(--bad) 55%, var(--white));
    --state-bad-bg:      color-mix(in srgb, var(--bad) 18%, var(--black));
    --state-bad-border:  color-mix(in srgb, var(--bad) 40%, transparent);

    --state-info-fg:     color-mix(in srgb, var(--info) 55%, var(--white));
    --state-info-bg:     color-mix(in srgb, var(--info) 18%, var(--black));
    --state-info-border: color-mix(in srgb, var(--info) 40%, transparent);

    --state-neutral-fg:     var(--gray-300);
    --state-neutral-bg:     color-mix(in srgb, var(--white) 8%, var(--black));
    --state-neutral-border: color-mix(in srgb, var(--white) 16%, transparent);

    /* ─── FOCUS ────────────────────────────────────────────────────────
       L'anneau ambre à 45 % se dilue sur du noir : on le monte à 60 %.
       L'anneau « inverse » se pose sur la surface claire, il passe au navy.
       Les --elevation-* ne sont PAS redéfinies : elles dérivent du navy et
       deviennent naturellement discrètes sur fond noir, ce qui est correct.
       En thème sombre la profondeur se lit à la CLARTÉ de la surface, pas
       à l'ombre portée. */
    --focus-ring:         0 0 0 3px color-mix(in srgb, var(--amber) 60%, transparent);
    --focus-ring-inverse: 0 0 0 3px color-mix(in srgb, var(--navy) 55%, transparent);
    --focus-outline:      2px solid var(--amber);

    /* ─── ACCENT SCINDÉ ────────────────────────────────────────────────
       Le fond et l'encre ne bougent pas : l'ambre reste l'ambre, et une
       encre sombre dessus reste la bonne réponse quel que soit le thème.
       Seul --accent-base repasse à l'ambre vif, puisqu'il s'écrit
       désormais sur du noir et non plus sur du blanc. */
    --accent-base: var(--amber);
  }
}
