/* ==========================================================================
   QUALITECH : tokens
   Source de vérité unique du design system. Aucune valeur brute ailleurs.
   Toute couleur, taille, espacement ou durée utilisée dans le site vient d'ici.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0 · LA POLICE, SERVIE DEPUIS CE DOMAINE
   Outfit était chargée depuis fonts.googleapis.com. Ce chargement transmettait
   à Google l'adresse IP de CHAQUE visiteur, à chaque page, sans son
   consentement et vers un prestataire susceptible de la traiter hors UE.
   C'était le seul transfert hors Union européenne du site, et le seul motif
   de l'article 06 de la politique de confidentialité.

   Les deux fichiers sont les woff2 que Google servait lui-même, déposés dans
   assets/fonts/. Ils sont en VARIABLE : un seul fichier couvre les graisses
   100 à 900, là où sept fichiers statiques auraient été nécessaires pour les
   sept graisses utilisées par le site (200, 300, 400, 500, 600, 700, 800).
   Coût total : 47 Ko, soit exactement ce que Google envoyait déjà.

   Déclaré ici plutôt que dans une quatrième feuille de style : tokens.css est
   la première chargée, la police part donc au plus tôt sans requête en plus.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Outfit";
  font-style: normal;          /* Outfit n'a pas d'italique réelle, cf. § 5 */
  font-weight: 100 900;        /* police variable : une seule plage */
  font-display: swap;          /* le texte s'affiche tout de suite, en police système */
  src: url("../assets/fonts/outfit-variable-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: "Outfit";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/outfit-variable-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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {

  /* ---------------------------------------------------------------
     1. COULEURS
     Palette issue du logo, étendue pour tenir les contrastes WCAG.
     --------------------------------------------------------------- */

  /* Bleus : la colonne vertébrale */
  --qt-nuit:          #050B14;  /* fond le plus profond, sections dark */
  --qt-marine:        #07274A;  /* primaire logo */
  --qt-marine-haut:   #0C3663;  /* cartes surélevées sur fond sombre */
  --qt-marine-voile:  #103F73;  /* hover, états actifs */

  /* Chauds : la lumière */
  --qt-sable:         #BA9D74;  /* secondaire logo. JAMAIS en texte sur fond clair */
  --qt-sable-clair:   #D9C6A8;  /* texte secondaire sur fond sombre (9,01:1 sur marine) */
  --qt-sable-pale:    #EDE4D6;  /* logo monochrome, texte fort sur fond sombre */
  --qt-or:            #B78A2B;  /* accent CTA, aplats, filets. JAMAIS en texte sur clair */
  --qt-or-vif:        #D9A538;  /* survol des aplats or */
  --qt-or-encre:      #7A5C1C;  /* LA variante or lisible en texte sur fond clair (5,3:1) */

  /* Surfaces claires : jamais de blanc pur, jamais de gris froid */
  --qt-creme:         #F5F1EA;
  --qt-creme-profond: #EAE3D7;
  --qt-creme-voile:   #FBF9F5;
  --qt-lin:           #FDFCFA;  /* le plus clair des fonds, jamais #FFF */
  --qt-blanc:         #FFFFFF;  /* réservé au texte sur fond sombre */

  /* Rôles sémantiques : c'est ce qu'on utilise dans le code, pas les couleurs brutes */
  --qt-fond:              var(--qt-creme);
  --qt-fond-alt:          var(--qt-creme-profond);
  --qt-fond-sombre:       var(--qt-nuit);
  --qt-fond-sombre-alt:   var(--qt-marine);

  --qt-encre:             var(--qt-marine);       /* texte principal sur clair */
  --qt-encre-douce:       #46586E;                /* texte secondaire sur clair (5,9:1) */
  --qt-encre-tenue:       #5E6E82;                /* légendes sur clair (4,63:1 mesuré) */
  --qt-encre-inverse:     var(--qt-blanc);        /* texte principal sur sombre */
  --qt-encre-inverse-douce: var(--qt-sable-clair);/* texte secondaire sur sombre */

  --qt-accent:            var(--qt-or);           /* aplats et filets uniquement */
  --qt-accent-texte:      var(--qt-or-encre);     /* accent en TEXTE sur fond clair */
  --qt-accent-texte-inv:  var(--qt-sable);        /* accent en TEXTE sur fond sombre */

  /* Filets : toujours dérivés, jamais en dur */
  --qt-filet-clair:   color-mix(in srgb, var(--qt-marine) 12%, transparent);
  --qt-filet-fort:    color-mix(in srgb, var(--qt-marine) 22%, transparent);
  --qt-filet-sombre:  color-mix(in srgb, var(--qt-sable) 16%, transparent);
  --qt-filet-sombre-fort: color-mix(in srgb, var(--qt-sable) 30%, transparent);

  /* États */
  --qt-focus:         var(--qt-or-vif);
  --qt-succes:        #2F6B4F;
  --qt-erreur:        #9B2C2C;


  /* ---------------------------------------------------------------
     2. TYPOGRAPHIE
     Famille unique : Outfit (variable 100 à 900, PAS d'italique réelle).
     Le contraste vient de la graisse et de l'échelle, pas d'une 2e police.

     Outfit ne livre que le style normal : Google renvoie uniquement
     font-style:normal même quand on demande « ital ». Tout <em> laissé en
     italique recevrait donc un oblique SYNTHÉTIQUE, penché par le
     navigateur, qui se repère immédiatement. Les 156 accents du site
     passent en droit, soulignés d'or — le traitement que le hero utilisait
     déjà pour ses propres accents.
     --------------------------------------------------------------- */

  --qt-police: "Outfit", ui-sans-serif, system-ui, -apple-system,
               "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Graisses */
  /* Graisses sémantiques. Dans ce registre le display ne se met JAMAIS en gras :
     c'est l'espace et la photo qui portent, pas l'épaisseur du trait. */
  --qt-w-display: 300;
  --qt-w-titre:   400;

  /* Graisses des titres. Le H1 du hero porte la voix de la marque, les H2
     de section viennent juste en dessous : un cran de graisse d'écart,
     jamais deux, sinon la page a deux niveaux de cri au lieu d'une
     hiérarchie. */
  --qt-w-h1: 700;
  --qt-w-h2: 600;

  --qt-w-fin:     200;
  --qt-w-leger:   300;
  --qt-w-normal:  400;
  --qt-w-moyen:   500;
  --qt-w-semi:    600;
  --qt-w-gras:    700;
  --qt-w-noir:    800;

  /* Échelle fluide. Ratio display / corps d'environ 7,2x au plus large. */
  /* Registre « marque de matériau » : le display est modéré et léger.
     Référence mesurée : Louis Poulsen tient son hero en ~48 px light.
     Un display qui mange le viewport est l'échec n°1 du genre. */
  --qt-t-display-xl: clamp(2.35rem, 1.55rem + 2.5vw, 4.1rem);    /* 37,6 -> 65,6 px */
  --qt-t-display-l:  clamp(1.95rem, 1.48rem + 1.45vw, 2.85rem);  /* 31,2 -> 45,6 px */
  --qt-t-titre:      clamp(1.35rem, 1.22rem + 0.42vw, 1.7rem);   /* 21,6 -> 27,2 px */
  --qt-t-sous-titre: clamp(1.1rem, 1.05rem + 0.2vw, 1.25rem);    /* 17,6 -> 20 px   */
  --qt-t-chapeau:    clamp(1.05rem, 1.01rem + 0.16vw, 1.18rem);  /* 16,8 -> 18,9 px */
  --qt-t-corps:      1rem;                                        /* 16 px          */
  --qt-t-petit:      0.9375rem;                                   /* 15 px         */
  --qt-t-mention:    0.8125rem;                                   /* 13 px         */
  --qt-t-sur-titre:  0.75rem;                                     /* 12 px         */
  --qt-t-stat:       clamp(1.9rem, 1.42rem + 1.45vw, 2.75rem);   /* 30,4 -> 44 px   */

  /* Interlignages : serrés en display, aérés en corps */
  --qt-lh-display: 1.06;
  --qt-lh-titre:   1.18;
  --qt-lh-sous:    1.28;
  --qt-lh-corps:   1.65;
  --qt-lh-dense:   1.45;

  /* Approches */
  --qt-ls-display:  -0.022em;
  --qt-ls-titre:    -0.015em;
  --qt-ls-sous:     -0.012em;
  --qt-ls-corps:    -0.005em;
  --qt-ls-sur-titre: 0.18em;

  /* Longueurs de ligne : lisibilité non négociable */
  --qt-mesure-large:  68ch;
  --qt-mesure:        58ch;
  --qt-mesure-etroite: 44ch;


  /* ---------------------------------------------------------------
     3. ESPACEMENTS
     Échelle fluide. Les sections respirent, les blocs techniques serrent.
     --------------------------------------------------------------- */

  --qt-e-3xs: 0.25rem;
  --qt-e-2xs: 0.5rem;
  --qt-e-xs:  0.75rem;
  --qt-e-s:   1rem;
  --qt-e-m:   1.5rem;
  --qt-e-l:   2rem;
  --qt-e-xl:  3rem;
  --qt-e-2xl: clamp(3rem, 2.1rem + 3.7vw, 5.5rem);
  --qt-e-3xl: clamp(4.5rem, 3.1rem + 5.8vw, 9rem);
  --qt-e-4xl: clamp(6rem, 3.9rem + 8.8vw, 13rem);

  /* Rythme vertical des sections : UNE seule cadence, à toutes les coutures.
     Mesure de référence du genre : ~96 px de pas médian, 80 à 160 px de plage. */
  --qt-section-y:       clamp(4.5rem, 3.4rem + 4.6vw, 8.75rem);  /* 72 -> 140 px */
  --qt-section-y-large: var(--qt-section-y);

  /* Conteneurs */
  --qt-largeur-max:     1320px;
  --qt-largeur-etroite: 880px;
  --qt-largeur-texte:   680px;
  --qt-gouttiere:       clamp(1.25rem, 0.6rem + 2.7vw, 3.5rem);
  --qt-grille-ecart:    clamp(1.25rem, 0.75rem + 2vw, 2.75rem);


  /* ---------------------------------------------------------------
     4. MATIÈRE
     Pas d'ombres portées molles. Des ombres directionnelles longues
     qui rejouent la lumière rasante du pictogramme du logo.
     --------------------------------------------------------------- */

  /* Rayons courts et assumés. Au-delà de 12px on tombe dans la card Bootstrap.
     Échelle resserrée d'un tiers : à 12px les photos et les cartes tiraient
     vers le gabarit SaaS arrondi. Le geste reste lisible, il ne domine plus. */
  --qt-rayon-xs:  2px;
  --qt-rayon-s:   4px;
  --qt-rayon-m:   6px;
  --qt-rayon-l:   8px;
  --qt-rayon-xl:  10px;

  /* En-tête flottant mobile : aligné sur --qt-rayon-xl. L'exception à 18 px
     de la première passe est annulée, le système n'a plus de valeur isolée. */
  --qt-rayon-flottant: var(--qt-rayon-xl);
  --qt-rayon-plein: 999px;

  /* Dégagement sous l'en-tête flottant.
     L'en-tête est en position fixe sur mobile : son bas tombe à 82 px. Toute
     section placée en premier dans <main> doit réserver cette hauteur, sinon
     son premier élément passe DERRIÈRE l'en-tête sans qu'aucune erreur ne le
     signale. C'était une valeur en dur dans .qt-hero ; la page devis, qui
     n'utilise pas de hero, l'avait donc perdue. */
  --qt-degagement-entete: 5.75rem;

  --qt-trait: 1px;

  /* Ombres rasantes : décalées en bas à droite, comme l'ombre du logo */
  --qt-ombre-posee:  10px 14px 28px -16px rgba(5, 11, 20, 0.30);
  --qt-ombre-levee:  20px 28px 56px -26px rgba(5, 11, 20, 0.42);
  --qt-ombre-haute:  34px 46px 90px -36px rgba(5, 11, 20, 0.50);
  --qt-ombre-sombre: 28px 34px 70px -30px rgba(0, 0, 0, 0.72);

  /* Ombres du bouton primaire. Plus de lueur dorée : le bouton est désormais
     blanc sur fond sombre et marine sur fond clair. Une ombre portée nette
     remplace le halo, qui virait au néon sur un aplat blanc. */
  /* Descente des sections claires. Aucune étape ne vaut #FFFFFF : du blanc
     pur à côté du crème du reste du site lit comme un trou froid dans la
     page. On part du lin et on descend vers le crème, sans palier plat. */
  --qt-degrade-clair: linear-gradient(to bottom,
      var(--qt-lin) 0%,
      var(--qt-creme-voile) 38%,
      color-mix(in srgb, var(--qt-creme-voile) 45%, var(--qt-creme)) 72%,
      var(--qt-creme) 100%);

  /* Variante du hero. Identique, sauf qu'elle s'arrête sur le voile au lieu
     de rejoindre le crème du corps : le hero garde ainsi son propre plan et
     la section suivante commence sur un ton franchement distinct. La version
     ci-dessus, qui fondait les deux sans couture, reste utilisée par le CTA
     final, où la descente vers le crème amorce le pied de page sombre. */
  --qt-degrade-hero: linear-gradient(to bottom,
      var(--qt-lin) 0%,
      var(--qt-creme-voile) 45%,
      var(--qt-creme-voile) 100%);

  --qt-ombre-btn:       0 10px 26px -12px rgba(5, 11, 20, 0.55);
  --qt-ombre-btn-forte: 0 16px 38px -14px rgba(5, 11, 20, 0.7);

  /* Lueur dorée des CTA primaires */
  --qt-lueur-or:       0 0 0 1px color-mix(in srgb, var(--qt-or) 55%, transparent),
                       0 14px 40px -14px color-mix(in srgb, var(--qt-or) 60%, transparent);
  --qt-lueur-or-forte: 0 0 0 1px color-mix(in srgb, var(--qt-or-vif) 70%, transparent),
                       0 18px 52px -14px color-mix(in srgb, var(--qt-or) 75%, transparent);

  /* Grain : appliqué en overlay global, empêche les aplats marine de faire plastique */
  --qt-grain-opacite: 0.035;


  /* ---------------------------------------------------------------
     5. MOUVEMENT
     Fluide et pondéré. On simule le poids de la matière, pas le rebond.
     --------------------------------------------------------------- */

  --qt-ease:        cubic-bezier(0.16, 1, 0.3, 1);
  --qt-ease-sortie: cubic-bezier(0.87, 0, 0.13, 1);
  --qt-ease-doux:   cubic-bezier(0.4, 0, 0.2, 1);

  --qt-d-instant: 140ms;
  --qt-d-micro:   240ms;
  --qt-d-court:   380ms;
  --qt-d-moyen:   700ms;
  --qt-d-long:    1000ms;

  --qt-cascade: 60ms; /* décalage entre enfants d'un reveal */


  /* ---------------------------------------------------------------
     6. PROFONDEURS
     --------------------------------------------------------------- */

  --qt-z-fond:     0;
  --qt-z-contenu:  1;
  --qt-z-flottant: 10;
  --qt-z-entete:   100;
  --qt-z-panneau:  300;  /* menu plein écran */
  --qt-z-grain:    400;  /* overlay grain, au-dessus de tout, non cliquable */
}


/* ==========================================================================
   Contexte sombre
   Toute section dark bascule les rôles sémantiques. Les composants enfants
   n'ont rien à savoir : ils lisent --qt-encre et --qt-fond, point.
   ========================================================================== */

.qt-sombre,
.qt-sombre-marine {
  --qt-fond:          var(--qt-nuit);
  --qt-fond-alt:      var(--qt-marine);
  --qt-encre:         var(--qt-blanc);
  --qt-encre-douce:   var(--qt-sable-clair);
  --qt-encre-tenue:   color-mix(in srgb, var(--qt-sable-clair) 72%, transparent);
  --qt-accent-texte:  var(--qt-sable);
  --qt-filet-clair:   var(--qt-filet-sombre);
  --qt-filet-fort:    var(--qt-filet-sombre-fort);
  --qt-ombre-posee:   var(--qt-ombre-sombre);
  --qt-ombre-levee:   var(--qt-ombre-sombre);
  --qt-ombre-haute:   var(--qt-ombre-sombre);

  color: var(--qt-encre);
  background-color: var(--qt-fond);
}

.qt-sombre-marine {
  --qt-fond:     var(--qt-marine);
  --qt-fond-alt: var(--qt-marine-haut);
}


/* ==========================================================================
   Garde-fou d'accessibilité
   Le sable et l'or ne doivent JAMAIS servir de couleur de texte sur fond clair.
   Ces deux règles existent pour que toute tentative saute aux yeux en revue.
   ========================================================================== */

/* stylelint-disable-next-line */
.qt-interdit-sable-sur-clair { color: var(--qt-accent-texte); }
