/* ============================================================================
   QZR vNext — Design tokens
   ----------------------------------------------------------------------------
   Fondation "clean base" du redesign vNext (mono-tone, style Duolingo).
   Stratégie strangler : ce fichier est NEUF et isolé. Tout le design vNext
   passe par ces variables `--qz-*`. Règle d'or : aucun code vNext ne référence
   les anciens tokens (--ux-*, --premium-*, --qzr-tone-*).

   - Couleur de marque = UNE seule variable d'accent, déclinée en rampe 50→900.
   - 8 teintes paramétrables via
     [data-qz-theme="teal|ocean|indigo|rose|coral|ardoise|lime|moka"]
     posé sur <html> ou n'importe quel ancêtre.
   - Erreur = rouge système fixe (indépendant du thème).
   - Énergie/XP = or fixe (l'éclair de la mascotte).
   - Dark mode via [data-mode="dark"].
   À charger APRÈS la CSS legacy.
   ============================================================================ */

:root,
:root[data-qz-theme="teal"] {
  --qz-25: #F1FAF6;
  --qz-50:  #E1F5EE;
  --qz-100: #BCEBDB;
  --qz-200: #5DCAA5;
  --qz-400: #16A87A;
  --qz-500: #0F8A64;
  --qz-600: #0F6E56;
  --qz-800: #0A4F40;
  --qz-900: #06342A;
}

:root[data-qz-theme="ocean"] {
  --qz-25: #F3F8FD;
  --qz-50:  #E6F1FB;
  --qz-100: #B5D4F4;
  --qz-200: #85B7EB;
  --qz-400: #2E7CD6;
  --qz-500: #2270C9;
  --qz-600: #185FA5;
  --qz-800: #0C447C;
  --qz-900: #042C53;
}

:root[data-qz-theme="indigo"] {
  --qz-25: #F7F6FF;
  --qz-50:  #EEEDFE;
  --qz-100: #CECBF6;
  --qz-200: #AFA9EC;
  --qz-400: #7A6FE0;
  --qz-500: #6258CC;
  --qz-600: #534AB7;
  --qz-800: #3C3489;
  --qz-900: #26215C;
}

:root[data-qz-theme="rose"] {
  --qz-25: #FDF5F8;
  --qz-50:  #FBEAF0;
  --qz-100: #F4C0D1;
  --qz-200: #ED93B1;
  --qz-400: #D4537E;
  --qz-500: #B84168;
  --qz-600: #993556;
  --qz-800: #72243E;
  --qz-900: #4B1528;
}

:root[data-qz-theme="coral"] {
  --qz-25: #FDF6F3;
  --qz-50:  #FBEDE7;
  --qz-100: #F5C4B3;
  --qz-200: #F2A98D;
  --qz-400: #E4633A;
  --qz-500: #C9512B;
  --qz-600: #B5431F;
  --qz-800: #712B13;
  --qz-900: #4A1B0C;
}

:root[data-qz-theme="ardoise"] {
  --qz-25: #F7F7F8;
  --qz-50:  #F0F1F3;
  --qz-100: #D1D5DC;
  --qz-200: #A2ACB9;
  --qz-400: #64748B;
  --qz-500: #525F72;
  --qz-600: #424D5C;
  --qz-800: #2F3741;
  --qz-900: #1F242B;
}

:root[data-qz-theme="lime"] {
  --qz-25: #F7FAF2;
  --qz-50:  #F3FAE8;
  --qz-100: #DAF0B9;
  --qz-200: #B5E073;
  --qz-400: #84CC16;
  --qz-500: #6CA712;
  --qz-600: #57870F;
  --qz-800: #3E600A;
  --qz-900: #293F07;
  /* Comme safran et azur : accent CLAIR, donc le blanc global n'est pas vrai
     ici. Blanc sur lime = 1.98:1 — sous le seuil du GRAND texte (3:1), donc
     illisible partout, pas seulement en petit. L'encre foncee monte a 7.96:1.
     Corrige apres coup : lime etait livre depuis le 2026-07-15, le defaut a ete
     trouve en mesurant les nouveaux themes et garde volontairement separe pour
     ne pas changer un theme deja en service dans le meme lot. */
  --qz-on-accent: #15233B;
  /* Son fond profond est, avec celui de safran, le seul a rester juste sous le
     seuil : blanc 4.31:1. Assombri a 94 %, il monte a 4.84:1. */
  --qz-btn-primary-bg: color-mix(in srgb, var(--qz-accent-deep) 94%, #000000);
}

:root[data-qz-theme="moka"] {
  --qz-25: #FAF7F4;
  --qz-50:  #F4ECE7;
  --qz-100: #DFC6B7;
  --qz-200: #BE8C6E;
  --qz-400: #92400E;
  --qz-500: #78340B;
  --qz-600: #602A09;
  --qz-800: #451E07;
  --qz-900: #2D1404;
}

/* 2026-08-04 — +4 thèmes. Rampes dérivées avec les mêmes ratios que les huit
   autres (50 = 90% blanc, 100 = 70%, 200 = 40% ; 500 = 18% noir, 600 = 34%,
   800 = 53%, 900 = 69%) — ratios revérifiés en reproduisant exactement la
   rampe lime livrée avant de calculer celles-ci. */
:root[data-qz-theme="safran"] {
  --qz-25: #FCFAF4;
  --qz-50:  #FDF8EB;
  --qz-100: #F8E9C4;
  --qz-200: #F1D289;
  --qz-400: #E8B43A;
  --qz-500: #BE9430;
  --qz-600: #997726;
  --qz-800: #6D551B;
  --qz-900: #483812;
  /* Safran est un accent CLAIR : du blanc dessus tombe à 1.91:1, illisible.
     L'encre foncée y monte à 8.25:1. --qz-on-accent est global (#FFFFFF) et
     n'était jamais redéfini par thème — il l'est ici parce que la valeur
     globale n'est juste pas vraie pour cet accent. Même cas pour azur. */
  --qz-on-accent: #15233B;
  /* Son fond profond est le seul des huit ou NI le blanc (4.18) NI l'encre
     (3.76) ne passent : il faut l'assombrir. 88 % le porte a 5.15:1. */
  --qz-btn-primary-bg: color-mix(in srgb, var(--qz-accent-deep) 88%, #000000);
}

:root[data-qz-theme="azur"] {
  --qz-25: #F3F9FA;
  --qz-50:  #EBF8FB;
  --qz-100: #C3EAF3;
  --qz-200: #88D5E6;
  --qz-400: #38B9D6;
  --qz-500: #2E98AF;
  --qz-600: #257A8D;
  --qz-800: #1A5765;
  --qz-900: #113942;
  --qz-on-accent: #15233B;   /* blanc 2.31:1 → encre 6.80:1 */
}

:root[data-qz-theme="prune"] {
  --qz-25: #FAF6FA;
  --qz-50:  #F6EDF6;
  --qz-100: #E5CAE5;
  --qz-200: #CB95CB;
  --qz-400: #A84FA8;
  --qz-500: #8A418A;
  --qz-600: #6F346F;
  --qz-800: #4F254F;
  --qz-900: #341834;
}

:root[data-qz-theme="rubis"] {
  --qz-25: #FDF5F6;
  --qz-50:  #FBECEE;
  --qz-100: #F4C7CC;
  --qz-200: #E88E99;
  --qz-400: #D94355;
  --qz-500: #B23746;
  --qz-600: #8F2C38;
  --qz-800: #661F28;
  --qz-900: #43151A;
}

:root {
  /* ── Accent (dérivé de la rampe — ne pas redéfinir par thème) ── */
  --qz-accent:        var(--qz-400);
  --qz-accent-deep:   var(--qz-600);   /* liserés bas, états pressés, textes sur clair */
  --qz-accent-soft:   var(--qz-50);    /* fonds de chips, tracks de barres */
  --qz-accent-mid:    var(--qz-200);   /* bordures accent, états "done" */
  --qz-on-accent:     #FFFFFF;         /* texte sur fond accent plein */
  --qz-accent-ink:    var(--qz-800);   /* texte sur fond --qz-accent-soft */

  /* ── Bouton primaire : sa PROPRE paire fond/encre ─────────────────────────
     `--qz-on-accent` ne pouvait pas servir ici. Il est cense nommer « le texte
     sur fond accent plein », mais DEUX fonds pleins coexistent — `--qz-accent`
     et `--qz-accent-deep` — et safran comme azur l'ont regle pour le premier
     (leur accent est clair : blanc 1.91:1 et 2.31:1, encre 8.25 et 6.80). Sur
     le second, plus fonce, ce meme reglage retombe a 3.76 et 3.18. Un jeton,
     deux fonds, deux verites contradictoires.

     Mesures ayant conduit a ce choix (blanc, puis encre #15233B) :
       sur --qz-accent      : rubis 4.30 / 3.66  et ocean 4.23 / 3.72
         -> AUCUNE encre n'y atteint 4.5:1, cet accent est a mi-luminance.
            Le fond DOIT donc etre le fond profond.
       sur --qz-accent-deep : 6.20 a 11.46 partout SAUF safran 4.18 (encre 3.76)
         -> safran est le seul a devoir assombrir son fond.
     Toutes les valeurs verifiees dans le navigateur, pas calculees a la main. */
  --qz-btn-primary-bg:  var(--qz-accent-deep);
  --qz-btn-primary-ink: #FFFFFF;

  /* ── Mascotte ── */
  --qz-ink:           #15233B;         /* visière + contours mascotte (constant) */
  --qz-energy:        #F5C542;         /* éclair / gemme / XP (constant) */
  --qz-energy-deep:   #D4A017;

  /* ── Neutres (teintés subtilement par le thème via color-mix) ── */
  --qz-surface:       #FFFFFF;
  --qz-screen:        color-mix(in srgb, var(--qz-50) 55%, #FFFFFF);
  --qz-line:          color-mix(in srgb, var(--qz-200) 32%, #FFFFFF);
  --qz-line-strong:   color-mix(in srgb, var(--qz-200) 55%, #FFFFFF);
  --qz-text:          #10211B;         /* texte principal (neutre, ne shifte pas) */
  /* MESURE (01.SEP.2026) : #5F7B72 rendait 4,29 sur le fond de feuille dans
     le pire des douze themes — sous le seuil de 4,5 que ce fichier s'impose
     ailleurs. Le defaut ne se voyait pas sur du blanc pur (4,60) : il fallait
     un fond legerement teinte pour le faire apparaitre, et les feuilles en
     ont un. #556F63 rend 5,10 au pire, mesure sur les DOUZE themes.
     Le sombre garde #9FB3AC, qui rend deja 7,82. */
  --qz-muted:         #556F63;         /* texte atténué */
  --qz-bezel:         var(--qz-800);   /* cadre "téléphone" / surfaces sombres de marque */

  /* ── Sémantique ──
     Deux rôles, et un seul ton ne peut pas tenir les deux. La couleur de base
     sert au NON-TEXTE (filets, icônes de statut, bordures, jauges) : le seuil y
     est de 3:1 et elle le tient. L'encre sert au TEXTE, où le seuil est de
     4.5:1 — et là elle échouait partout, dans les deux thèmes :

         success  3.03 clair / 3.71 sombre
         error    3.51 clair / 3.47 sombre
         warning  3.32 clair / 3.52 sombre

     La cause était le commentaire qui tenait ici : « fixe, indépendant du
     thème ». Un texte lisible sur un fond pâle et sur un fond sombre demande
     deux valeurs opposées ; l'encre bascule donc par thème (comme --qz-text),
     la base ne bouge pas. Teinte et saturation conservées, seule la clarté
     bouge, jusqu'à passer 4.5:1 sur le pire fond du thème (la pastille teintée
     dans les deux cas, vérifié aussi contre --qz-surface et --qz-screen). ── */
  --qz-success:       #1E9E63;
  --qz-success-bg:    #E7F4EC;
  --qz-success-ink:   #177C4E;   /* 4.60 sur --qz-success-bg */
  --qz-error:         #E24B4A;
  --qz-error-strong:  #C0392B;
  --qz-error-bg:      #FCEFEF;
  --qz-error-ink:     #D22322;   /* 4.68 sur --qz-error-bg */
  --qz-warning:       #BA7517;
  --qz-warning-bg:    #FBF1DC;
  --qz-warning-ink:   #9A6113;   /* 4.57 sur --qz-warning-bg */

  /* ── Rayons ── */
  --qz-r-control: 12px;
  --qz-r-field:   13px;
  --qz-r-card:    16px;
  --qz-r-screen:  30px;
  --qz-r-pill:    999px;

  /* ── Espacement (base 4) ── */
  --qz-1: 4px;
  --qz-2: 8px;
  --qz-3: 12px;
  --qz-4: 16px;
  --qz-5: 20px;
  --qz-6: 24px;
  --qz-7: 32px;

  /* ── Typographie (2 graisses, sentence case) ── */
  --qz-font: inherit;                  /* hérite de la police de l'app */
  --qz-fw:        400;
  --qz-fw-strong: 500;
  --qz-fs-title:  22px;
  --qz-fs-h2:     18px;
  --qz-fs-h3:     16px;
  --qz-fs-body:   15px;
  --qz-fs-sm:     13px;
  --qz-fs-xs:     11px;
  --qz-lh:        1.5;

  /* ── Motion ─────────────────────────────────────────────────────────────
     TROIS paliers, pas davantage. L'audit du 2026-08-30 a compte 16 durees
     distinctes pour 408 declarations `transition`, dont 93 seulement
     s'appuyaient sur un jeton : 0.15s (118x), 0.18s (78x), 0.2s (57x),
     0.3s (52x), 0.16s (48x), 0.12s (42x)… des valeurs que rien ne distingue
     a l'oeil, et qui se remarquent seulement quand deux controles voisins
     reagissent differemment.

       press  — le retour tactile, sous le doigt : doit etre imperceptible
       ui     — survol, focus, couleur, ombre : le palier par defaut
       pop    — apparition d'un element, ouverture

     `--qz-press-scale` fixe le GESTE lui-meme. L'audit relevait 12 valeurs
     de transform au `:active` (translateY 2px, 1px, scale .98, .97, .95,
     .99, .985, .96, .93…). Le `translateY` est ecarte : il deplace la cible
     sous le doigt au moment ou l'on appuie. */
  --qz-dur-press: 80ms;
  --qz-dur-ui:    150ms;
  --qz-dur-pop:   350ms;
  --qz-dur-bar:   1100ms;
  /* Exception assumee : l'animation de lancement (`.is-pressing`, posee par
     utilities.press()) GROSSIT au lieu de retrecir, pour marquer les actions
     qui demarrent quelque chose. Sa duree est couplee au setTimeout de
     utilities.js — changer l'une sans l'autre laisserait la classe posee
     apres la fin de l'animation, ou l'inverse. */
  --qz-dur-launch: 240ms;
  --qz-press-scale: .97;
  --qz-ease:      cubic-bezier(.2, .7, .3, 1);
  --qz-ease-pop:  cubic-bezier(.2, 1.5, .4, 1);

  /* ── Focus ── */
  --qz-focus-ring: 0 0 0 3px var(--qz-accent-soft);

  /* ── Élévation (dark-aware ; valeurs claires = littéraux historiques) ── */
  --qz-shadow-sm: 0 8px 20px rgba(15, 23, 42, 0.06);
  --qz-shadow-md: 0 14px 34px rgba(15, 23, 42, 0.08);
  /* ── Feuilles et panneaux modaux ────────────────────────────────────────
     Le fond d'une feuille etait pris sur --qz-25, l'extremite CLAIRE de la
     rampe. La rampe est par THEME, jamais par MODE : en sombre le panneau
     restait donc blanc casse pendant que --qz-text passait au clair. Mesure
     du 31.AOU.2026 sur la feuille boutique : titre et solde a 1.07 — du
     texte quasi blanc sur fond quasi blanc.

     REDEFINIR LA RAMPE AURAIT CASSE AUTRE CHOSE. Quatre des sept usages de
     --qz-100 (podium, carte d'activite, avatar, marche du podium) associent
     DELIBEREMENT ce fond clair a une encre --qz-800/--qz-900 : ils marchent
     dans les deux modes precisement parce que la rampe ne bouge pas.

     LE SOMBRE PREND --qz-screen, PAS --qz-surface. Soixante-huit regles
     posent --qz-surface sur des cartes A L'INTERIEUR des feuilles : donner
     --qz-surface au panneau les aplatirait toutes. --qz-screen preserve le
     RELIEF — panneau en retrait, cartes en avant — comme en clair. */
  --qz-sheet:      var(--qz-25);
  --qz-sheet-grip: var(--qz-100);   /* la poignee de glissement */
}

/* ── Dark mode : on ne touche qu'aux neutres ; la rampe accent reste valable ── */
:root[data-mode="dark"] {
  --qz-surface:     #1B2622;
  --qz-screen:      #131D19;
  --qz-line:        rgba(255, 255, 255, .10);
  --qz-line-strong: rgba(255, 255, 255, .18);
  --qz-text:        #EAF2EF;
  --qz-muted:       #9FB3AC;
  --qz-bezel:       #06120E;
  --qz-accent-soft: color-mix(in srgb, var(--qz-400) 22%, #131D19);
  --qz-accent-ink:  var(--qz-200);
  --qz-success-bg:  color-mix(in srgb, var(--qz-success) 22%, #131D19);
  --qz-error-bg:    color-mix(in srgb, var(--qz-error)   22%, #131D19);
  --qz-warning-bg:  color-mix(in srgb, var(--qz-warning) 22%, #131D19);
  /* L'encre s'eclaircit ici alors qu'elle s'assombrit en clair : c'est tout
     l'interet de la separer de la base, qui elle ne bouge pas.
     Vise ~4.8 et non 4.5 : --qz-*-bg est un color-mix calcule par le
     navigateur, et une valeur posee pile sur le seuil retombe dessous
     une fois arrondie (mesure : 4.48 pour le vert). */
  --qz-success-ink: #23B873;
  --qz-error-ink:   #E97776;
  --qz-warning-ink: #DA891B;
  --qz-sheet:       var(--qz-screen);
  --qz-sheet-grip:  var(--qz-line-strong);
  --qz-shadow-sm:   0 8px 20px rgba(0, 0, 0, 0.38);
  --qz-shadow-md:   0 16px 36px rgba(0, 0, 0, 0.46);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-mode="light"]) {
    --qz-surface:     #1B2622;
    --qz-screen:      #131D19;
    --qz-line:        rgba(255, 255, 255, .10);
    --qz-line-strong: rgba(255, 255, 255, .18);
    --qz-text:        #EAF2EF;
    --qz-muted:       #9FB3AC;
    --qz-bezel:       #06120E;
    --qz-accent-soft: color-mix(in srgb, var(--qz-400) 22%, #131D19);
    --qz-accent-ink:  var(--qz-200);
    --qz-success-bg:  color-mix(in srgb, var(--qz-success) 22%, #131D19);
    --qz-error-bg:    color-mix(in srgb, var(--qz-error)   22%, #131D19);
    --qz-warning-bg:  color-mix(in srgb, var(--qz-warning) 22%, #131D19);
    /* L'encre s'eclaircit ici alors qu'elle s'assombrit en clair : c'est tout
       l'interet de la separer de la base, qui elle ne bouge pas.
       Vise ~4.8 et non 4.5 : --qz-*-bg est un color-mix calcule par le
       navigateur, et une valeur posee pile sur le seuil retombe dessous
       une fois arrondie (mesure : 4.48 pour le vert). */
    --qz-success-ink: #23B873;
    --qz-error-ink:   #E97776;
    --qz-warning-ink: #DA891B;
    --qz-sheet:       var(--qz-screen);
    --qz-sheet-grip:  var(--qz-line-strong);
    --qz-shadow-sm:   0 8px 20px rgba(0, 0, 0, 0.38);
    --qz-shadow-md:   0 16px 36px rgba(0, 0, 0, 0.46);
  }
}

/* Respect de prefers-reduced-motion : neutralise les animations vNext */
@media (prefers-reduced-motion: reduce) {
  :root {
    --qz-dur-press:  0ms;
    --qz-dur-ui:     0ms;
    --qz-dur-pop:    0ms;
    --qz-dur-bar:    0ms;
    --qz-dur-launch: 0ms;
    /* Le geste de pression disparait aussi : une mise a l'echelle instantanee
       resterait un saut visible. */
    --qz-press-scale: 1;
  }
}
