/* ============================================================
   Déneigement Roger — démo premium YannCode Solutions · VERSION 2 « NUIT »
   (7 août 2026 — la V1 reste intacte dans DEMOS/Deneigement-Roger-demo/)

   CE QUI CHANGE PAR RAPPORT À LA V1, ET POURQUOI :
   ① Valeur INVERSÉE — nuit dominante au lieu du blanc/bleu pâle. La V1
      n'était forte que dans ses 2 sections sombres ; United Carriers est
      noir à 80 % et fait de la lumière son sujet.
   ② Typo d'INSTRUMENT — Archivo Black (display massif) + Geist Mono
      (chiffres, étiquettes) au lieu de Playfair. Le déneigement se raconte
      en mesures : 5 cm, 5 h 30, 8 secteurs, 9 pieds de lame.
   ③ Le SUJET est montré — photo de machine plein cadre au héros, au lieu
      d'attendre 80 % du défilement.
   ④ Le blizzard devient VISIBLE : les flocons sont blancs, ils étaient
      peints sur du blanc.
   Les couleurs restent MESURÉES sur les photos (3 août) — c'est leur rôle
   qui change : le jaune de lame et le bleu de glace passent d'ornement à
   signal, sur fond de nuit.

   ─── REFONTE « GLACIER » — 25 AOÛT 2026 ────────────────────────────────────
   MOTIF : la V2 partageait sa signature visuelle avec le site vendu au client
   SME (accent ambre + Archivo Black + héros photo-plein-cadre-texte-à-gauche).
   Deux sites en vitrine ne peuvent pas se ressembler. Trois leviers, tous
   approuvés par Yannick :
   ① IDENTITÉ FROIDE — l'accent ambre #f9b134 devient le bleu glacier #7ecbe8
      (SME garde le chantier chaud). Ratios RECALCULÉS, pas jugés à l'œil :
      détail dans le bloc :root. Le bandeau défilant, qui était à ≈1,4:1 (bogue
      WCAG franc), est reconstruit en texte outline.
   ② TYPO — Archivo Black → ANTON (display condensée, bibliothèque du 3 août),
      avec repli métrique calibré. Geist/Geist Mono ne bougent pas.
   ③ SILHOUETTE — cartes de prix et témoignages en « fiche technique ».
      ⚠️ Le volet HÉROS du levier ③ (photo cadrée à droite, fond grainé, relevé
      en bandeau) a été ANNULÉ le 25 août par Yannick : retour à la photo plein
      cadre du 7 août. Le conflit avec le héros « bandeau » de SME décrit
      ci-dessous est donc CLOS — les deux compositions ne se ressemblent plus.
   NE BOUGENT PAS : moteur de neige, piste horizontale + parallaxe du 24 août,
   LuxAnim/Lenis, structure des sections, textes, images.
   Sauvegarde de l'état d'avant : maquettes-sources/roger-v2-20260825-avant-glacier/

   CONFLIT CLOS le 25 août. Il portait sur le héros cadré : le MÊME JOUR, un
   autre chantier avait posé sur SME (chantiers-clients/entreprise-sme-
   deneigement/css/styles.css, ~ligne 1441) exactement cette composition —
   texte à gauche, photo cadrée à droite. Le retour au plein cadre ici règle la
   question : les deux héros ne se ressemblent plus.
   ============================================================ */

/* ---------- Racine fluide ACCESSIBLE ----------
   1rem = 10 px @1728px, suit le réglage de police du navigateur (WCAG 1.4.4).
   Le vw sec (0.5787vw) casserait ce réglage. */
html { font-size: clamp(0.611rem, 0.3125rem + 0.29vw, 0.72rem); }
@media (max-width: 991px) { html { font-size: clamp(0.611rem, 0.3125rem + 0.42vw, 0.72rem); } }
@media (max-width: 767px) { html { font-size: clamp(0.6rem, 0.47rem + 0.6vw, 0.72rem); } }
/* Les min des clamp garantissent les planchers CLAUDE.md en px RÉELS
   (corps ≥ 16 px mobile / ≥ 17,6 px desktop), quelle que soit la fenêtre. */

:root {
  /* ── Socle NUIT (le fond général est sombre — c'est l'inversion V2) ── */
  --neige: #0b0e13;    /* [USAGE : fond général de la page · fond des cartes] — ex-blanc */
  --glace: #10151c;    /* [USAGE : fonds sections Prix, Équipement, CTA · loader] — un ton au-dessus du fond */
  --glace-2: #161d26;  /* [USAGE : fonds alternés · cartes posées sur --glace] */
  --glace-3: #1e2632; /* [USAGE : réserve] */
  --encre: #e9eef4;    /* [USAGE : tout le texte principal] — glace claire, 15,8:1 sur --neige */
  --nuit: #06080b;     /* [USAGE : fonds les plus profonds — Pourquoi Roger · pied de page] */
  /* Le gris des textes secondaires. Trois états dans la journée du 7 août :
     rgba 0,58 (5,6:1 — « ne paraît pas », verdict de Yannick) · vert #00db2c
     (10,3:1, mais il se battait avec le jaune des boutons — essayé, écarté) ·
     et ce gris froid OPAQUE, 11,9:1. L'opacité pleine compte autant que la
     valeur : en rgba, la photo du héros transparaissait sous le kicker et le
     délavait. Reste sous --encre (15,8:1) pour garder la hiérarchie. */
  --note: #c3ccd6;   /* [USAGE : textes secondaires · légendes · kickers] */
  --bord: rgba(233, 238, 244, 0.14);   /* [USAGE : bordures fines cartes · séparateurs] */
  --bord-fort: rgba(233, 238, 244, 0.38); /* [USAGE : bordures boutons · champs de formulaire] */

  /* ── Accents — REFONTE « GLACIER » (25 août 2026) ──────────────────────────
     L'ambre #f9b134 partait de la lame Metal Pless ; il partageait aussi sa
     signature avec le site vendu à SME (chantier CHAUD, orange). Le déneigement,
     lui, c'est le FROID : l'accent bascule dans la famille cyan de glace, et
     l'ambre ne survit qu'au gyrophare du QG sur la carte (une balise
     d'urgence — le seul point chaud de la page, et c'est voulu).
     Ratios CALCULÉS (WCAG 2.1, sRGB relative luminance), pas jugés à l'œil :
       #7ecbe8 sur --nuit #06080b .......... 11,07:1   (AA texte normal ✓)
       #7ecbe8 sur --neige #0b0e13 ......... 10,67:1   ✓
       #7ecbe8 sur --glace #10151c ......... 10,12:1   ✓
       #7ecbe8 sur --glace-2 #161d26 ........ 9,37:1   ✓
       #7ecbe8 sur les fonds de section (#131a23 / #0f141b / #151d27) : 9,4 à 10,2:1 ✓
       texte --neige #0b0e13 SUR bouton plein #7ecbe8 ... 10,67:1  (AA ✓)
       texte --neige #0b0e13 SUR bouton survolé #a6e2f5 . 13,64:1  ✓
     L'ancien ambre tenait 10,5:1 sur --nuit : le glacier fait mieux (11,07). */
  --vert: #7ecbe8;     /* [USAGE : RÉSERVE — aligné sur l'accent pour que les surcharges par section ne réintroduisent pas une 2e teinte] */
  --vert-f: #7ecbe8;   /* BLEU GLACIER · [USAGE : boutons pleins · liens · crochets · kickers · compteurs · prix] — 11,07:1 sur nuit */
  --vert-n: #a6e2f5;   /* glacier clair · [USAGE : survol des boutons] — 13,64:1 avec le texte nuit */
  --jaune: #b5e8f7;    /* (nom historique, valeur glacier pâle) · [USAGE : étoiles · anneaux de focus · curseur flocon] — 13,8:1 sur --glace, et il se DÉTACHE d'un élément déjà rempli en --vert-f */
  --jaune-2: #b5e8f7;  /* [USAGE : réserve] */
  /* --rouge : GARDÉ pour l'urgence. Vérifié le 25 août — aucune règle du fichier
     ne l'utilise aujourd'hui (3 tokens de réserve). Il ne jure donc avec rien à
     l'écran, et s'il sert un jour il tient l'AA : 6,09:1 sur --nuit, 5,57:1 sur
     --glace. Sa teinte (354°) est un rouge FROID, pas un rouge orangé : c'est
     précisément celui qui cohabite avec un cyan sans virer au sapin de Noël. */
  --rouge: #ff4a5b;    /* souffleuse · [USAGE : réserve — 3 usages MAX] — 6,09:1 sur nuit */
  --rouge-f: #e0384a;  /* [USAGE : réserve] */
  --brique: #e0384a;   /* [USAGE : réserve] */
  --phare: #cfeefb;    /* ex-#ffe9a8 (halo CHAUD) · [USAGE : lueur froide du héros] — 16,5:1 sur nuit */

  /* ── Typo d'INSTRUMENT (tokens attendus par la tweaks bar) ── */
  /* ANTON remplace Archivo Black (refonte GLACIER, 25 août 2026) : Archivo Black
     était l'AUTRE moitié de la signature partagée avec SME. Anton est la display
     condensée massive de la bibliothèque (id « anton », OFL, 18 Ko) — même
     autorité d'affiche, silhouette opposée : haute et étroite au lieu de large
     et carrée. Repli 'Arial Narrow' AVANT Impact : Impact est absente de la
     plupart des Mac récents et le repli tombait alors sur du sans-serif normal. */
  --police-titre: 'Anton', 'Anton Repli', 'Arial Narrow', Impact, sans-serif; /* [USAGE : TOUS les titres · logo · chiffres géants] */
  --police-corps: 'Geist', 'Inter', system-ui, sans-serif;           /* [USAGE : tout le texte courant] */
  --police-mono: 'Geist Mono', 'SF Mono', Consolas, monospace;       /* [USAGE : kickers · étiquettes · mesures · numéros de section · PRIX] */
  /* Anton porte ~30 % plus étroit qu'Archivo Black à taille égale : la même
     ligne tient dans moins de largeur, donc on MONTE l'échelle au lieu de la
     baisser. « Chaque entrée » en nowrap tient à 11rem là où Archivo Black
     plafonnait à 8rem. C'est le caractère qu'on va chercher. */
  --h1-min: 5.4rem;     /* ex-4.4rem · [USAGE : taille MINIMALE du grand titre du héros] */
  --h1-max: 11rem;      /* ex-8rem · [USAGE : taille MAXIMALE du grand titre du héros] */
  --h1-graisse: 400;    /* Anton n'existe qu'en 400 (déjà noire) · [USAGE : graisse de tous les titres] */
  /* Anton est DÉJÀ crénée serré : le -0.025em d'Archivo Black collait les fûts
     entre eux à grande taille. Interlettre quasi neutre, à peine resserrée. */
  --h1-interlettre: -0.005em; /* ex--0.025em · [USAGE : espacement des lettres des titres] */
  --fs-corps:2.63rem; /* ⟵ réglage Yannick (tweaks bar, 3 août) */   /* ≈ 18 px réels @1728 · [USAGE : paragraphes · descriptions] */
  --fs-note:2.85rem; /* ⟵ réglage Yannick (tweaks bar, 3 août) */    /* [USAGE : notes · légendes · sous-textes] */
  --fs-ui:2.58rem; /* ⟵ réglage Yannick (tweaks bar, 3 août) */      /* [USAGE : boutons · liens de navigation] */
  --fs-badge:2rem; /* ⟵ réglage Yannick (tweaks bar, 3 août) */  /* [USAGE : kickers · mentions du pied de page] */

  /* ── La carte du héros — V2 : elle devient l'objet LUMINEUX sur la nuit
        (le rôle que joue le globe chez United Carriers) ── */
  --carte-neige: #b9d4f2;   /* [USAGE : carte : surface du Québec, haut] */
  --carte-glace: #5f7f9e;   /* [USAGE : carte : surface du Québec, bas · vitres des tracteurs] */
  --carte-flanc: #24313f;   /* [USAGE : carte : épaisseur 3D (flancs)] */
  /* GLACIER (25 août) : les flèches et les pastilles étaient d'un bleu pervenche
     #8bccfd — proche de l'accent, mais pas LUI. Elles prennent exactement la
     valeur de --vert-f pour que la carte parle la même langue que les boutons. */
  --carte-fleche: #7ecbe8;  /* ex-#8bccfd · [USAGE : carte : les 8 flèches et leurs pointes] */
  --carte-lueur: #2f7fa4;   /* ex-#3d7fc4, glissé vers le cyan · [USAGE : carte : halo sous les flèches · contour des étiquettes] */
  --carte-qg: #f9c134;      /* [USAGE : carte : point et pulsation du QG] — LE GYROPHARE : seul point chaud conservé, c'est une balise d'urgence, pas un accent de marque */
  --carte-pin: #7ecbe8;     /* ex-#8bccfd · [USAGE : carte : pastilles des secteurs] */
  --carte-tracteur: #f9c134;/* [USAGE : carte : corps des 8 tracteurs] */
  --carte-cabine: #d8a72c;  /* [USAGE : carte : cabines des tracteurs] */
  --carte-lame: #ffe9a8;    /* [USAGE : carte : lames et jantes des tracteurs] */

  /* ── Layout ── */
  --pad-container:1.93rem; /* ⟵ réglage Yannick (tweaks bar, 3 août) */      /* [USAGE : marges latérales de toute la page] */
  --col-gap:3.6rem; /* ⟵ réglage Yannick (tweaks bar, 3 août) */            /* [USAGE : écart entre les colonnes et cartes] */
  --radius:1.97rem; /* ⟵ réglage Yannick (tweaks bar, 3 août) */           /* [USAGE : arrondi des cartes et boutons] */
  --bord-1: max(1px, 0.1rem); /* [USAGE : épaisseur de toutes les bordures] */
}
@media (max-width: 767px) {
  :root { --pad-container: 1.93rem; } /* aligné sur le réglage Yannick */
}

/* ---------- Polices auto-hébergées (bibliothèque Awwwards, OFL) ----------
   Aucune Google Fonts externe (règle CLAUDE.md) : 3 woff2 servis en local,
   41 Ko au total, contre 42 Ko pour les deux polices de la V1. */
@font-face {
  font-family: 'Anton';
  src: url('../fonts/anton.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
/* Repli MÉTRIQUE d'Anton, pour que le `swap` ne fasse pas sauter la page.
   CALIBRÉ AU NAVIGATEUR le 25 août, pas au jugé. Protocole : chaîne
   « CHAQUE ENTRÉE AVANT VOTRE JOURNÉE » à font-size 100px, line-height normal,
   getBoundingClientRect sur chaque famille. Relevé :
     Anton .............. 1415 px de large · boîte de ligne 151 px  ⟵ la cible
     Impact ............. 1501 px (+6 %)   · 122 px
     Arial Narrow ....... 2084 px (+47 %)  · 115 px
   Impact est donc le SEUL repli local honnête pour une condensée aussi serrée
   qu'Anton — Arial Narrow, malgré son nom, est presque 50 % plus large et
   ferait sauter toute la mise en page au swap. D'où l'ordre local() ci-dessous,
   inversé par rapport à la pile de la bibliothèque.
   Réglage retenu, vérifié par itération : size-adjust 95 % → 1417 px (cible
   1415, écart 0,1 %) · ascent 134 % + descent 25 % → 151 px (exact).
   ⚠️ Limite assumée : sur une machine SANS Impact (plusieurs Mac récents),
   local() retombe sur Arial Narrow et le repli redevient large. C'est le prix
   d'un repli local ; la vraie protection reste le <link rel=preload> d'Anton,
   qui fait que ce repli n'est visible que quelques dizaines de ms.
   Ce @font-face ne télécharge RIEN — il habille une police déjà installée. */
@font-face {
  font-family: 'Anton Repli';
  src: local('Impact'), local('Arial Narrow'), local('ArialNarrow');
  size-adjust: 95%;
  ascent-override: 134%;
  descent-override: 25%;
  line-gap-override: 0%;
  font-display: swap;
}
@font-face {
  font-family: 'Geist';
  src: url('../fonts/geist.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: 'Geist Mono';
  src: url('../fonts/geist-mono.woff2') format('woff2');
  font-weight: 400 600;
  font-display: swap;
}

/* ---------- Reset court ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
img, svg, video, canvas { display: block; max-width: 100%; }
button { font: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; }
ul, ol { list-style: none; }

/* Le clip sur body seul laissait la boîte de défilement de html s'élargir :
   sur téléphone la page glissait latéralement (débordement du héros — attrapé
   au test du 4 août). Les deux niveaux doivent clipper. */
html { overflow-x: clip; }
body {
  font-family: var(--police-corps);
  font-size: var(--fs-corps);
  line-height: 1.62;
  color: var(--encre);
  background: var(--neige);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

/* ---------- Échelle de titres (patron United : uppercase, lh 1.05) ---------- */
.h0, .h1, .h2, .h3, .h4, h1, h2, h3 {
  font-family: var(--police-titre);
  font-weight: var(--h1-graisse);
  text-transform: uppercase;
  /* 1.05 (patron United) clippait les accents FRANÇAIS : le É de RÉSIDENTIEL
     touchait le kicker au-dessus (retour Yannick 3 août). L'anglais n'a pas
     d'accents ; le français exige plus d'air au-dessus des capitales. */
  /* Anton a des capitales très hautes et des accents qui montent haut : 1.14
     laissait des trous entre les lignes du H1 une fois la police condensée
     posée. 1.06 resserre le bloc SANS toucher aux accents (vérifié sur
     « ENTRÉE » et « RÉSIDENTIEL », qui sont les deux cas limites français). */
  line-height: 1.06;
  letter-spacing: var(--h1-interlettre);
}
.kicker + h1, .kicker + h2, .kicker + h3, .kicker + .h4 { margin-top: 1.4rem; }
/* Échelle REMONTÉE d'un cran avec Anton (25 août) : la condensée rend ~30 % de
   largeur, on la rend en HAUTEUR. Les h2 restent bornés par les panneaux de
   100vw de la séquence horizontale — 6.6rem est le plafond mesuré avant que
   « Chaque entrée avant votre journée » ne cherche une 3e ligne sur un
   portable 1366×768. */
.h0 { font-size: 16.5rem; }
h1, .h1 { font-size: clamp(var(--h1-min), 8vw, var(--h1-max)); }
h2, .h2 { font-size: 6.6rem; }
h3, .h3 { font-size: 4.5rem; }
.h4 { font-size: 3.5rem; }
@media (max-width: 991px) {
  .h0 { font-size: 10.4rem; }
  h2, .h2 { font-size: 5rem; }
  h3, .h3 { font-size: 3.6rem; }
}

/* V2 : tous les kickers passent en mono — étiquette d'instrument, pas titre. */
.kicker {
  font-family: var(--police-mono);
  font-size: var(--fs-badge);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--note);
}
/* Le trait court devant l'étiquette : repère de relevé, emprunté au patron
   United Carriers (leurs libellés de section portent le même). */
.kicker::before {
  content: ''; display: inline-block; width: 2.4rem; height: 1px;
  margin-right: 1.2rem; vertical-align: 0.35em; background: var(--vert-f);
}
.note { font-size: var(--fs-note); color: var(--note); }

/* ---------- Grille 16 colonnes full-bleed (patron United) ---------- */
.grille {
  display: grid;
  grid-template-columns:
    [pleine-deb] minmax(var(--pad-container), 1fr)
    [contenu-deb] repeat(16, minmax(0, 8.4rem))
    [contenu-fin] minmax(var(--pad-container), 1fr)
    [pleine-fin];
  column-gap: var(--col-gap);
}
.grille > * { grid-column: contenu-deb / contenu-fin; }
.pleine { grid-column: pleine-deb / pleine-fin; }

section { position: relative; }
/* Chaque section RÉ-ÉVALUE la couleur de texte localement : sans ça, la
   couleur héritée de body resterait figée et la vue « par section » de la
   tweaks bar ne pourrait pas re-teinter le texte d'UNE seule section. */
header.nav, main > [id], .piste-hiver [id] { color: var(--encre); }
/* (#pourquoi et footer.pied redéclarent déjà la leur plus bas — même effet) */
.section-pad { padding-block: 12rem; }
@media (max-width: 767px) { .section-pad { padding-block: 7rem; } }

/* ---------- Boutons (plat, prononcé) ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 1rem;
  padding: 1.6rem 3rem;
  font-size: var(--fs-ui);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  /* DIFFÉRENCIATION 24 août 2026 : le bouton prend son PROPRE rayon, une capsule
     pleine, au lieu de partager --radius avec les cartes. --radius ne bouge pas :
     les cartes, les champs et les médias gardent exactement leur arrondi. */
  border-radius: 999rem;
  border: var(--bord-1) solid transparent;
  transition: background-color 0.3s, color 0.3s, border-color 0.3s, transform 0.3s, box-shadow 0.3s;
  min-height: 4.4rem;
}
.btn-plein { background: var(--vert-f); color: var(--neige); }
/* Survol : le bouton se SOULÈVE avec un halo de sa propre couleur, au lieu du
   simple échange de fond. Le halo reste sous le seuil de la lueur radiale
   interdite en maquette (c'est une ombre de bouton, pas un fond de section). */
.btn-plein:hover {
  background: var(--vert-n); transform: translateY(-0.3rem);
  box-shadow: 0 0.8rem 2rem -0.4rem color-mix(in srgb, var(--vert-f) 55%, transparent);
}
.btn-contour { border-color: var(--bord-fort); color: var(--encre); }
.btn-contour:hover { border-color: var(--encre); transform: translateY(-0.3rem); }
/* :active APRÈS les :hover — à spécificité égale c'est le dernier qui gagne, et
   l'enfoncement doit l'emporter sur le soulèvement. */
.btn:active { transform: translateY(1px); box-shadow: none; }

/* ---------- Utilitaires ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
.sep-congere { width: 100%; height: auto; color: var(--glace); }

/* ============================================================
   SECTIONS
   ============================================================ */

/* ---------- S0 Loader ---------- */
#chargement {
  position: fixed; inset: 0; z-index: 90;
  background: var(--nuit);
  display: flex; align-items: flex-end; justify-content: space-between;
  padding: var(--pad-container);
}
#chargement .chargement-compteur {
  font-family: var(--police-mono); color: var(--vert-f); line-height: 1;
}
.chargement-secteurs {
  display: flex; flex-direction: column; gap: 0.6rem; overflow: hidden;
  height: 3em; text-align: right; font-family: var(--police-mono); font-size: var(--fs-ui);
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--note);
}
/* Ligne d'horizon qui se remplit pendant le décompte : on voit la route se
   dégager, ce n'est pas juste une attente. */
#chargement::after {
  content: ''; position: absolute; left: var(--pad-container); right: var(--pad-container);
  bottom: calc(var(--pad-container) - 1rem); height: 1px; background: var(--bord);
}

/* ---------- Nav ---------- */
/* V2 : la barre ne pose plus un bandeau opaque sur la photo du héros. Elle est
   transparente en haut de page et se voile dès qu'on défile (classe .nav-fond
   posée par premium.js). */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.8rem var(--pad-container);
  background: transparent;
  border-bottom: var(--bord-1) solid transparent;
  transition: background-color 0.4s, border-color 0.4s, backdrop-filter 0.4s;
}
.nav.nav-fond {
  background: color-mix(in srgb, var(--nuit) 94%, transparent);
  /* 19 août 2026 : backdrop-filter retiré (recomposition GPU plein écran sur nav fixe — bug Fournel ; nav ~94 % opaque, retrait sans effet visuel) */
  border-bottom-color: var(--bord);
}
.nav-logo {
  font-family: var(--police-titre); font-size: 2rem; letter-spacing: 0.02em;
  text-decoration: none; text-transform: uppercase;
}
.nav-logo span { color: var(--vert-f); }
.nav nav { display: flex; align-items: center; gap: 2.8rem; }
.nav-liens { display: flex; align-items: center; gap: 2.8rem; }
.nav nav a:not(.btn) {
  font-family: var(--police-mono);
  font-size: var(--fs-ui); font-weight: 500; text-decoration: none;
  letter-spacing: 0.12em; text-transform: uppercase;
}
/* Le bouton du menu n'existe qu'en petite largeur (voir la media query). */
.nav-burger { display: none; }
.nav nav a:not(.btn):hover { color: var(--vert-f); }
.nav-cta { padding: 1rem 2rem; min-height: 0; }
/* ---------- Menu mobile ----------
   Jusqu'au 7 août, les trois liens étaient simplement masqués sous 768 px :
   sur téléphone, on ne pouvait atteindre Prix, Secteurs et Questions qu'en
   faisant défiler toute la page. Le panneau ci-dessous les rend cliquables.
   QA 25 août : la barre desktop a besoin de ~1000 px pour tenir (bouton
   Réserver coupé à 768, logo sur deux lignes jusqu'à ~1000) — le burger
   couvre désormais toute la bande morte 768-999. */
@media (max-width: 999px) {
  .nav-burger {
    display: inline-flex; flex-direction: column; justify-content: center;
    gap: 0.5rem; width: 4.4rem; height: 4.4rem; padding: 1rem;
    border: var(--bord-1) solid var(--bord); border-radius: var(--radius);
  }
  .nav-burger span {
    display: block; height: max(2px, 0.2rem); width: 100%;
    background: var(--encre); border-radius: 1px;
    transition: transform 0.28s, opacity 0.2s;
  }
  /* Trois barres qui deviennent une croix : l'état ouvert doit se voir. */
  .nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(0.7rem) rotate(45deg); }
  .nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-0.7rem) rotate(-45deg); }

  .nav nav { gap: 1.2rem; }
  .nav-liens {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: color-mix(in srgb, var(--nuit) 96%, transparent);
    backdrop-filter: blur(14px);
    border-bottom: var(--bord-1) solid var(--bord);
    /* Fermé = replié à zéro, sans display:none : la transition reste possible
       et le contenu sort du parcours de tabulation grâce à visibility. */
    max-height: 0; overflow: hidden; visibility: hidden;
    transition: max-height 0.32s ease, visibility 0.32s;
  }
  .nav.menu-ouvert .nav-liens { max-height: 60vh; visibility: visible; }
  .nav-liens a {
    padding: 2rem var(--pad-container);
    border-top: var(--bord-1) solid var(--bord);
  }
}

/* ---------- S1 Héros + carte ----------
   25 août : la « fenêtre cadrée à droite sur fond grainé » de la refonte
   Glacier est ANNULÉE (verdict Yannick). Retour à la composition plein cadre du
   7 août — photo absolue pleine section, texte par-dessus, relevé sous les
   boutons. Ce qui RESTE de Glacier ici : le H1 en Anton et son échelle
   (--h1-min/--h1-max), l'accent #7ecbe8, et le voile radial re-teinté froid
   (--phare est passé du jaune de phare au bleu de glace #cfeefb). */
.hero {
  min-height: 100svh; align-items: center; padding-top: 12rem; padding-bottom: 6rem;
  overflow: clip; background: var(--nuit);
}
/* 25 août — RÈGLE : le but d'une image héros est de la MONTRER, pas de la
   cacher. Plus de voile global (le dégradé 100° qui noyait les 2/3 gauches et
   le halo --phare sont partis). Le contraste se pose LOCALEMENT derrière le
   texte (.hero-texte::before). */
/* pleine-deb/pleine-fin : dans une grille, un enfant absolu s'ancre sur SA zone
   de grille — sans ça la photo restait dans les marges de contenu. Hauteur
   bornée au premier écran : c'est là que la machine doit être vue. */
.hero-fond {
  position: absolute; grid-column: pleine-deb / pleine-fin;
  inset: 0 0 auto 0; height: 100svh; z-index: 0; overflow: clip;
}
/* Réglage de cohésion seulement (l'image doit se VOIR) : un souffle de
   désaturation froide, la luminosité reste quasi intacte. */
.hero-fond img {
  width: 100%; height: 100%; object-fit: cover; object-position: 58% 74%;
  filter: saturate(0.9) contrast(1.02);
}
/* ⚠️ Jamais `transparent` dans ces dégradés : en CSS il vaut rgba(0,0,0,0),
   donc l'interpolation traverse du NOIR et éteint la photo. On écrit la
   couleur du voile en alpha 0 (rgba(6,8,11,0)). */
/* Ne restent que les deux RACCORDS de bord — le haut pour que la barre de nav
   reste lisible, le bas pour que la photo se fonde dans la nuit de la section
   suivante. Ni l'un ni l'autre ne touche le corps de l'image. */
.hero-fond::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, rgba(6, 8, 11, 0.62) 0%, rgba(6, 8, 11, 0) 11%),
    linear-gradient(to top, rgba(6, 8, 11, 0.88) 0%, rgba(6, 8, 11, 0) 13%);
}
/* span 10 (et non 9 comme avant Glacier) : mesuré au navigateur à 1440 px, le
   kicker « DÉNEIGEMENT RÉSIDENTIEL ET COMMERCIAL · MIRABEL » demande ~745 px et
   cassait en deux lignes dans les 725 px du span 9. Une étiquette d'instrument
   sur deux lignes, ça n'est plus une étiquette. 10/16 = 62,5 % de la colonne de
   contenu, soit encore dans la zone SOMBRE du voile (qui ne s'ouvre qu'à 48-64 %). */
.hero-texte { grid-column: contenu-deb / span 10; position: relative; z-index: 3; }
/* SCRIM LOCAL — le seul assombrissement du héros, et il ne vit que derrière ce
   bloc. Deux effets superposés, tous les deux MASQUÉS pour que les bords
   meurent en fondu (jamais de boîte à arêtes) :
   ① backdrop-filter: brightness — rabat les hautes lumières (toits au soleil,
     tas de neige) sans aplatir la couleur ;
   ② un aplat nuit très léger — plancher de contraste là où la photo est déjà
     sombre, où le brightness seul ne donne plus rien.
   L'œil lit le produit (1−aplat)×brightness : ici 0,82 × 0,62 ≈ 0,51 de la
   luminance d'origine, contre ~0,08 sous l'ancien voile global. Testé plus
   discret encore (0,68/0,14 ≈ 0,585) : le sous-titre repassait à 76 % de
   glyphes sous 4,5:1. C'est le plancher.
   Masque en DEUX dégradés croisés (intersect) plutôt qu'une ellipse : mesuré
   au rendu, une ellipse assez large pour couvrir la fin du kicker s'éteignait
   déjà sous le relevé (kicker 52 % d'échec, relevé 100 %). Les deux axes se
   règlent séparément :
   · horizontal — plein jusqu'à 78 %, éteint à 100 % de la boîte, soit un fondu
     de ~205 px qui meurt à x≈1010 à 1440. Un fondu court (86 %) tenait les
     mêmes chiffres mais laissait une arête verticale LISIBLE sur la nappe de
     neige uniforme à droite : sur un aplat sans texture, il faut de la longueur ;
   · vertical — fondu sur les 7 % du haut et les 14 % du bas, donc le scrim
     n'a aucune arête visible ni au ras de la nav ni au bas du héros. */
.hero-texte::before {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  inset: -12rem -14rem -10rem -18rem;
  background: rgba(6, 8, 11, 0.18);
  backdrop-filter: brightness(0.62);
  -webkit-backdrop-filter: brightness(0.62);
  -webkit-mask-image:
    linear-gradient(to right, #000 0 78%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000 7%, #000 86%, rgba(0, 0, 0, 0) 100%);
  mask-image:
    linear-gradient(to right, #000 0 78%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000 7%, #000 86%, rgba(0, 0, 0, 0) 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
.hero-h1 .ligne { display: block; overflow: hidden; white-space: nowrap; }
.hero-h1 { font-size: clamp(var(--h1-min), 5.5vw, var(--h1-max)); }
/* Le texte du héros passe sur une photo dont la neige est claire : ombre
   portée douce pour tenir la lisibilité partout, quel que soit le cadrage. */
.hero-texte .kicker, .hero-h1, .hero-sous, .hero-releve { text-shadow: 0 0.2rem 1.6rem rgba(6, 8, 11, 0.8); }
/* Les PETITS textes (kicker, étiquettes et chiffres du relevé) reçoivent en
   plus un halo SERRÉ. C'est le contraste le plus local qui existe : il colle du
   sombre contre le glyphe lui-même au lieu d'assombrir une région. C'est lui
   qui permet de garder le scrim discret — sans lui, il fallait descendre le
   backdrop à 0.42 pour tenir le 4,5:1 sur les toits au soleil. */
.hero-texte .kicker, .hero-sous, .hero-releve dt, .hero-releve dd {
  text-shadow: 0 0 0.5rem rgba(6, 8, 11, 0.98), 0 0 1.1rem rgba(6, 8, 11, 0.9),
               0 0.2rem 1.6rem rgba(6, 8, 11, 0.8);
}
.hero-sous {
  margin-top: 2.4rem; font-family: var(--police-mono); font-size: var(--fs-note);
  color: rgba(233, 238, 244, 0.88); letter-spacing: 0.02em;
}
.hero-cta { display: flex; flex-wrap: wrap; gap: 1.6rem; margin-top: 3.6rem; }

/* Relevé de la nuit — le métier parle en mesures, la typo mono le dit. */
.hero-releve {
  display: flex; flex-wrap: wrap; gap: 0 5rem; margin-top: 5rem;
  padding-top: 2.4rem; border-top: var(--bord-1) solid var(--bord);
  font-family: var(--police-mono);
}
.hero-releve dt {
  font-size: var(--fs-badge); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--note);
}
.hero-releve dd {
  margin-top: 0.5rem; font-size: 3.2rem; color: var(--vert-f);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 767px) {
  .hero-releve { gap: 0 3rem; margin-top: 3.4rem; }
  .hero-releve dd { font-size: 2.6rem; }
}

/* La carte grossit ×2,2 au défilement et son SVG est en overflow:visible (pour
   ne pas couper les étiquettes) : sans clip sur la section, elle débordait de
   480 px en 390 px de large. Dans le héros, le clip existait déjà — il est
   parti avec le déménagement. */
#secteurs { overflow: clip; }

/* ---------- La carte du Québec — DÉPLACÉE dans « Zone desservie » (V2) ----------
   Dans le héros, elle se battait avec la photo de la machine pour le même coin
   d'écran, et ses noms de secteurs étaient illisibles à cette taille. Ici elle
   est deux fois plus grande, seule sur la nuit, et elle remplace le radar
   décoratif qui ne disait rien (supprimé). */
.carte-secteurs {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.carte-secteurs::before {
  content: ''; position: absolute; inset: -10% -14%; z-index: -1;
  background: radial-gradient(closest-side, rgba(61, 127, 196, 0.16), transparent 78%);
  pointer-events: none;
}
.carte-scene { perspective: 1400px; width: min(56rem, 100%); }
.carte {
  width: 100%; height: auto;
  transform: rotateX(38deg) rotateZ(-14deg);
  transform-style: preserve-3d;
  overflow: visible; /* le zoom A+ déborde du viewBox : ne jamais couper les étiquettes */
  /* V2 : la carte est la source de lumière de l'écran, pas un aplat gris. */
  filter: drop-shadow(0 0 3rem rgba(139, 204, 253, 0.28));
}
.carte-note { margin-top: 0.8rem; text-align: center; }
.carte-glow {
  position: absolute; border-radius: 50%; z-index: -1;
  filter: blur(clamp(20px, 4vw, 48px));
  pointer-events: none;
}
/* V2 : les halos passent du blanc laiteux (invisible sur blanc) au bleu de
   glace et au jaune de gyrophare — sur la nuit, ils font l'aura. */
.carte-glow.g1 {
  width: 52rem; height: 52rem; left: 50%; top: 44%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(61, 127, 196, 0.5), rgba(61, 127, 196, 0) 70%);
  animation: glow-derive-a 22s ease-in-out infinite alternate;
}
/* g2 est passé du halo JAUNE au glacier (25 août) : c'était une nappe chaude
   diffuse sur toute la carte, pas la balise du QG. Le gyrophare, lui, garde
   son ambre — mais c'est un point, pas une ambiance. */
.carte-glow.g2 {
  width: 30rem; height: 30rem; left: 22%; top: 66%;
  background: radial-gradient(circle, rgba(126, 203, 232, 0.24), rgba(126, 203, 232, 0) 70%);
  animation: glow-derive-b 19s ease-in-out infinite alternate;
}
.carte-glow.g3 {
  width: 26rem; height: 26rem; left: 62%; top: 18%;
  background: radial-gradient(circle, rgba(139, 204, 253, 0.42), rgba(139, 204, 253, 0) 72%);
  animation: glow-derive-a 26s ease-in-out infinite alternate-reverse;
}
@keyframes glow-derive-a {
  from { transform: translate(-50%, -50%) translate(-2rem, 1rem); opacity: 0.75; }
  to   { transform: translate(-50%, -50%) translate(2.5rem, -1.5rem); opacity: 1; }
}
@keyframes glow-derive-b {
  from { transform: translate(-1.5rem, 0); opacity: 0.6; }
  to   { transform: translate(1.5rem, -2rem); opacity: 0.95; }
}
/* Le CSS gagne toujours sur les attributs de présentation SVG : ces règles
   branchent la carte sur les tokens --carte-* (éditables à la tweaks bar). */
#qc-flanc use { fill: var(--carte-flanc); }
#qc-flanc use:nth-child(2) { fill: color-mix(in srgb, var(--carte-flanc) 95%, white); }
#qc-flanc use:nth-child(3) { fill: color-mix(in srgb, var(--carte-flanc) 89%, white); }
#qc-flanc use:nth-child(4) { fill: color-mix(in srgb, var(--carte-flanc) 83%, white); }
#qc-flanc use:nth-child(5) { fill: color-mix(in srgb, var(--carte-flanc) 77%, white); }
#qc-flanc use:nth-child(6) { fill: color-mix(in srgb, var(--carte-flanc) 71%, white); }
#qc-flanc use:nth-child(7) { fill: color-mix(in srgb, var(--carte-flanc) 65%, white); }
#qc-province > use { stroke: var(--carte-glace); }
.fleche { stroke: var(--carte-fleche); }
.fleche-lueur { stroke: var(--carte-lueur); }
.qg-halo, .qg-point { stroke: var(--carte-qg); }
.qg-point { fill: var(--carte-qg); }
.pins { fill: var(--carte-pin); }
/* V2 : les plaques étaient blanches à texte encre — sur la nuit, elles
   faisaient huit taches de papier. Elles deviennent des étiquettes rétro-
   éclairées, en mono, comme les repères de carte d'United Carriers. */
.etiquette rect { fill: rgba(6, 8, 11, 0.82); stroke: var(--carte-lueur); }
.etiquettes { fill: var(--carte-neige); font-family: var(--police-mono); font-size: 17px; }

/* (jamais de transform-origin CSS sur .qg-halo : GSAP gère l'origine en
   coordonnées viewBox — la double origine détachait l'anneau de la carte) */
.pin, .etiquette { opacity: 0; }
.tracteur { opacity: 0; }
@media (max-width: 991px) {
  .hero { padding-top: 12rem; }
  /* .carte-secteurs a quitté le héros : elle vit dans .secteurs-flex, où les
     lignes nommées contenu-deb/contenu-fin n'existent pas. Les lui imposer
     créait des colonnes implicites (la grille passait à 3 colonnes et la carte
     se retrouvait collée à droite de la liste). */
  .hero-texte { grid-column: contenu-deb / contenu-fin; }
  .carte-scene { width: min(52rem, 84vw); }
  /* Empilé, le héros dépasse un écran : la photo couvre les deux tiers hauts
     et se fond dans la nuit, au lieu de s'arrêter net au milieu du texte. */
  .hero-fond { height: 78svh; }
}
@media (max-width: 767px) {
  /* « Chaque entrée » en nowrap à la taille desktop déborde de l'écran :
     la display condensée garde sa propre échelle en petite largeur (Anton
     tient plus de texte qu'Archivo Black, d'où le plafond remonté à 5.4rem). */
  .hero-h1 { font-size: clamp(3.3rem, 9.6vw, 5.4rem); }
  .hero-fond img { object-position: 62% 62%; }
  /* 25 août — même philosophie qu'en desktop : le voile mobile plein cadre
     (qui plancherait à 0,42 d'opacité au MILIEU de l'image) tombe. Ne restent
     que les deux raccords de bord — la nav en haut, la fonte dans la nuit en
     bas, la photo se fond en 78svh sous un héros plus haut. Le contraste du
     texte est déjà tenu par le scrim local et les halos serrés : mesuré à
     390 px avant allègement, l'élément le PIRE était à 6,7:1. */
  .hero-fond::after {
    background:
      linear-gradient(to bottom, rgba(6, 8, 11, 0.72) 0%, rgba(6, 8, 11, 0) 15%,
                      rgba(6, 8, 11, 0) 60%, rgba(6, 8, 11, 0.94) 92%);
  }
  /* En 390 px le texte occupe l'écran : le scrim couvre forcément une plus
     grande part de l'image, alors il doit aussi porter seul ce que l'ancien
     plancher mobile (0,42 pleine image) faisait. Un cran plus sombre suffit —
     sans lui le kicker retombait à 8,5 % de glyphes sous 4,5:1. */
  .hero-texte::before {
    background: rgba(6, 8, 11, 0.24);
    backdrop-filter: brightness(0.5);
    -webkit-backdrop-filter: brightness(0.5);
  }
}

/* ---------- S2 Intro 2 temps ---------- */
.intro-bloc { grid-column: contenu-deb / span 13; }
.intro-l1 { color: var(--note); }
.intro-l2 { color: var(--encre); }
.intro-p { max-width: 62rem; margin-top: 3.2rem; }

/* ---------- S3 Chiffres ---------- */
.chiffres-grille {
  grid-column: contenu-deb / contenu-fin;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--col-gap);
  border-top: var(--bord-1) solid var(--bord);
}
.chiffre { padding-top: 3rem; border-right: var(--bord-1) solid var(--bord); padding-right: 2rem; }
.chiffre:last-child { border-right: 0; }
.chiffre-val { color: var(--vert-f); }
.chiffre-lib { font-size: var(--fs-note); color: var(--note); max-width: 24rem; }
@media (max-width: 767px) {
  .chiffres-grille { grid-template-columns: 1fr; }
  .chiffre { border-right: 0; border-bottom: var(--bord-1) solid var(--bord); padding-bottom: 2rem; }
  .chiffre:last-child { border-bottom: 0; }
}

/* ---------- S2-S4 : la séquence (blizzard + écrans) ----------
   Depuis le 4 août 2026, la zone intro → services vit dans .piste-hiver
   (séquence HORIZONTALE desktop, bloc dédié plus bas). Les règles ici sont
   le SOCLE commun + le repli vertical (mobile, tier statique, sans JS). */
/* ⚠️ Toutes les règles #services sont scopées à .piste : #services n'est un
   écran de la séquence horizontale QUE dans ce contexte. Non scopées, elles
   suivaient une copie où #services est une section normale et l'étalaient sur
   4 écrans de large (cas SME, 18 août). */
/* position:relative — CORRECTIF 8 sept. 2026 (trouvé sur la copie Laforce). En repli
   VERTICAL (< 992 px), .piste-colle n'est plus collée, donc plus positionnée : le
   .blizzard en absolu remontait au premier ancêtre positionné et restait coincé dans
   le premier écran → aucun flocon sur toute la zone des services en 768×1024. Avec
   un ancêtre positionné, le blizzard couvre la piste empilée. En horizontal, rien ne
   change (.piste-colle est sticky, donc positionnée). */
.piste-hiver { position: relative; }
.piste #services { background: var(--glace); }
.blizzard {
  position: absolute; inset: 0; z-index: 0; overflow: clip; pointer-events: none;
}
/* Les canvas de neige des sections CLAIRES (#secteurs, #reserver, #contact) sont
   insérés par effets.js en premier enfant, en position absolue : un élément
   positionné peint APRÈS le contenu en flux, donc les flocons passaient par-dessus
   le texte et les champs du formulaire. On relève le contenu d'un cran (8 sept. 2026). */
#secteurs > :not(canvas), #reserver > :not(canvas), #contact > :not(canvas) {
  position: relative; z-index: 1;
}
.blizzard canvas { position: sticky; top: 0; width: 100%; height: 100vh; }
.neige-arriere { filter: blur(2.5px); }
.neige-avant { margin-top: -100vh; }
.ecran {
  min-height: 100vh;
  display: flex; align-items: center;
  /* Voile LÉGER : le blizzard doit se voir (retour Yannick 3 août, 2e passe —
     88 % l'étouffait). Les écrans étant désormais côte à côte (plus de
     superposition sticky), le texte-fantôme n'existe plus. */
  background: color-mix(in srgb, var(--glace) 42%, transparent);
}
/* (Tracteur du défilement + route : retirés le 4 août au soir — stand-by.) */
.ecran-contenu { grid-column: contenu-deb / contenu-fin; padding-block: 10rem; width: 100%; }
.cartes-prix {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--col-gap);
  margin-top: 4rem;
}
/* CARTES PRIX — STYLE « FICHE TECHNIQUE » (25 août 2026).
   AVANT : boîte pleine, bordure sur les 4 côtés, rayon 1.97rem (le même que
   SME), prix en display. C'était une carte de site web ; ça devient une entrée
   de catalogue de pièces. Séparateurs horizontaux fins, pas de boîte, coins
   nets, chiffres tabulaires en mono. Le rayon partagé --radius ne bouge pas :
   il sert encore aux champs, aux médias d'équipement et aux pastilles. */
.carte-prix {
  background: none; border: 0; border-radius: 0;
  border-top: max(2px, 0.22rem) solid var(--bord-fort);  /* Chromium tronque les bordures sous-pixel : 0.2rem (1,96 px) retombait a 1 px et le filet ne se voyait plus. */
  border-bottom: var(--bord-1) solid var(--bord);
  padding: 2.6rem 0 3rem;
  transition: border-top-color 0.3s, transform 0.3s;
}
/* Survol DISCRET : le filet du haut s'allume en glacier. Pas de soulèvement de
   boîte — il n'y a plus de boîte à soulever. */
.carte-prix:hover { border-top-color: var(--vert-f); }
.carte-desc { margin-top: 1.2rem; font-size: var(--fs-note); color: var(--note); }
.carte-montant {
  margin-top: 2.4rem; font-size: var(--fs-note); color: var(--note);
  display: flex; align-items: baseline; gap: 0.8rem;
}
/* Le prix quitte la display pour la MONO à chasse fixe, en chiffres tabulaires :
   les trois cartes alignent leurs montants à la colonne près, comme un relevé.
   C'est le même argument que le bandeau du héros — le métier parle en mesures. */
.carte-montant .prix {
  font-family: var(--police-mono); font-variant-numeric: tabular-nums;
  font-size: 4.4rem; font-weight: 600; line-height: 1;
  color: var(--vert-f); letter-spacing: -0.03em;
  /* « 465 $ » et « 1 450 $ » portent l'espace insécable typographique du
     français. En chasse fixe à 44 px, cette espace fait la largeur d'un chiffre
     et le dollar partait en voyage. On la resserre sans toucher au texte. */
  word-spacing: -0.22em;
}
.inclus-liste { margin-top: 4rem; max-width: 72rem; }
.inclus-liste li {
  padding: 2.2rem 0 2.2rem 4.4rem; position: relative;
  border-bottom: var(--bord-1) solid var(--bord); font-size: 2rem;
}
.inclus-liste li::before {
  content: ''; position: absolute; left: 0; top: 2.9rem;
  width: 2.4rem; height: 1.2rem;
  border-left: 0.35rem solid var(--vert-f); border-bottom: 0.35rem solid var(--vert-f);
  transform: rotate(-45deg);
}
@media (max-width: 991px) {
  /* minmax(0,1fr) et non 1fr : un 1fr nu prend la taille MIN-CONTENT de la
     carte, qui dépassait le conteneur de 21 px (mot long en Archivo Black). */
  .cartes-prix { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- S5 Pourquoi (nuit) ---------- */
/* V2 : --glace et --neige sont devenus des FONDS sombres — les sections nuit
   prennent maintenant --encre comme couleur de texte. */
#pourquoi { background: var(--nuit); color: var(--encre); overflow: clip; }
#pourquoi .inverse { color: var(--encre); }
#pourquoi .kicker.inverse { color: var(--note); }
/* (.pourquoi-lueur + @keyframes lueur-respire supprimés le 25 août — règle du
   19 août : ces halos radiaux se lisent comme un défaut d'affichage.) */
.pourquoi-tete { grid-column: contenu-deb / span 10; margin-bottom: 5rem; }
.pourquoi-liste { grid-column: contenu-deb / span 12; }
.pourquoi-liste li {
  display: flex; gap: 2.8rem; align-items: baseline;
  padding: 2.6rem 0; font-size: 2.2rem; line-height: 1.45;
  border-bottom: var(--bord-1) solid rgba(223, 228, 233, 0.14);
}
/* Numéros en jaune de lame (7 août) : le bleu de glace n'existait plus que
   ICI et sur le soulignement des liens de contact — un orphelin qui attirait
   l'œil sur des repères d'ordre. Le bleu reste vivant là où il a un sens :
   la carte des secteurs (flèches, pastilles, halo). */
.pourquoi-num {
  font-family: var(--police-mono); font-size: var(--fs-badge); font-weight: 500;
  letter-spacing: 0.18em; color: var(--vert-f); flex-shrink: 0;
}

/* ---------- S6 Marquee — RÉÉCRIT EN OUTLINE (25 août 2026) ----------
   BOGUE WCAG CORRIGÉ : le bandeau était un aplat d'accent (--jaune) portant du
   texte --encre #e9eef4. Mesuré : ≈1,4:1. Sous le 4,5:1 de l'AA, et de très
   loin — un bandeau que personne ne pouvait lire.
   Le correctif n'est pas « choisir deux couleurs plus contrastées » mais
   CHANGER DE FORME : texte outline géant sur la nuit. Le contraste devient une
   propriété de la construction (trait glacier sur fond nuit = 11,07:1) et non
   un réglage à re-vérifier au prochain changement de palette. Même défilement
   30 s, même contenu, même doublon .sr-only pour les lecteurs d'écran. */
.marquee {
  background: var(--nuit); overflow: clip;
  padding: 1.8rem 0; border-block: var(--bord-1) solid var(--bord);
}
.marquee-piste {
  display: flex; white-space: nowrap; width: max-content;
  animation: defile 30s linear infinite;
  font-family: var(--police-titre);
  font-size: clamp(4.2rem, 6.4vw, 9rem);
  line-height: 1.08;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  /* FALLBACK, actif partout : glacier PLEIN sur la nuit — 11,07:1, AA franc.
     Un navigateur sans -webkit-text-stroke lit ce bandeau parfaitement. */
  color: var(--vert-f);
}
/* Là où le trait existe (tous les moteurs modernes, préfixe -webkit- compris
   par Firefox), on vide le remplissage et on garde le contour. Le trait porte
   exactement la couleur du fallback : le ratio ne bouge pas d'un point. */
@supports (-webkit-text-stroke: 1px red) {
  .marquee-piste {
    color: transparent;
    -webkit-text-stroke: 0.19rem var(--vert-f);
  }
}
@keyframes defile { to { transform: translateX(-50%); } }

/* ---------- S7 Témoignages + passage du tracteur ---------- */
/* (padding-bottom 26rem retiré avec la traversée du tracteur, 4 août au soir) */
#temoignages { overflow: clip; }
.temoignages-grille {
  grid-column: contenu-deb / contenu-fin;
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--col-gap);
  margin-top: 4rem;
}
/* Même logique de fiche que les cartes de prix (cohérence 25 août) : filet
   haut, coins nets, pas de boîte. Deux géométries dans une même page, c'est ce
   qui fait « gabarit » ; une seule, c'est ce qui fait « studio ». */
.temoignage {
  border: 0; border-radius: 0; background: none;
  border-top: max(2px, 0.22rem) solid var(--bord-fort);  /* Chromium tronque les bordures sous-pixel : 0.2rem (1,96 px) retombait a 1 px et le filet ne se voyait plus. */
  border-bottom: var(--bord-1) solid var(--bord);
  padding: 2.6rem 0 3rem;
  transition: border-top-color 0.3s;
}
.temoignage:hover { border-top-color: var(--vert-f); }
/* Les étoiles suivent enfin leur token (le SVG les avait figées en ambre codé
   en dur). currentColor traverse le <use> : la couleur héritée ici s'applique
   au <path> référencé. */
.etoiles { color: var(--jaune); }
.temoignage blockquote { margin-top: 1.6rem; font-size: 1.9rem; line-height: 1.55; }
.temoignage figcaption { margin-top: 2rem; font-size: var(--fs-note); color: var(--note); font-weight: 600; }
.passage {
  position: absolute; bottom: 2rem; left: 0; right: 0; height: 18rem;
  pointer-events: none; overflow: visible;
}
.tracteur-passe {
  position: absolute; bottom: 0; left: 0; width: 26rem; height: auto;
  -webkit-mask-image: radial-gradient(ellipse 62% 70% at 50% 55%, #000 58%, transparent 92%);
          mask-image: radial-gradient(ellipse 62% 70% at 50% 55%, #000 58%, transparent 92%);
  will-change: transform;
}
.congere {
  position: absolute; bottom: 0; left: 0; width: 12rem; height: 5rem;
  background: radial-gradient(ellipse at 30% 100%, var(--neige) 55%, rgba(255, 255, 255, 0) 75%);
  transform-origin: left bottom; opacity: 0;
}
.panache { position: absolute; inset: 0; }
@media (max-width: 767px) {
  .temoignages-grille { grid-template-columns: 1fr; }
  .tracteur-passe { width: 17rem; }
}

/* ---------- S8 Équipement ---------- */
#equipement { background: var(--glace); }
.equipement-cartes {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--col-gap);
  padding: 5rem var(--pad-container) 0;
}
.equipement-carte {
  background: var(--neige); border: var(--bord-1) solid var(--bord);
  border-radius: var(--radius); overflow: clip;
}
.equipement-media { position: relative; overflow: clip; aspect-ratio: 3 / 2; }
.equipement-media img { width: 100%; height: 100%; object-fit: cover; will-change: transform; }
.equipement-info { padding: 3.2rem; }
.equipement-specs { margin-top: 1.8rem; }
.equipement-specs li {
  padding: 1.1rem 0 1.1rem 2.6rem; position: relative;
  font-size: var(--fs-note); border-bottom: var(--bord-1) solid var(--bord);
}
.equipement-specs li:last-child { border-bottom: 0; }
.equipement-specs li::before {
  content: ''; position: absolute; left: 0.2rem; top: 1.9rem;
  width: 1.1rem; height: 0.55rem;
  border-left: 0.25rem solid var(--vert-f); border-bottom: 0.25rem solid var(--vert-f);
  transform: rotate(-45deg);
}
@media (max-width: 991px) { .equipement-cartes { grid-template-columns: minmax(0, 1fr); } }

/* ---------- Légende « photo d'exemple » (8 sept. 2026) ----------
   Règle Yannick : sous chaque image de tracteur, une note qui dit au prospect
   que ce sont SES photos qui prennent cette place — et qu'à défaut on génère
   des images au modèle et à la couleur de SON tracteur (motif : Marie-Claude
   tenait aux tracteurs orange ; Alex Fillion a peut-être décroché parce que
   les siens étaient devenus bleus).
   POSÉE EN COIN ABSOLU, jamais en flux : la page est pinnée (piste horizontale)
   et parallaxée, un élément de flux sous une photo changerait une hauteur de
   panneau. Les deux parents (.hero-fond, .equipement-media) sont déjà en
   overflow:clip — .hero-fond est déjà absolu, seul .equipement-media a besoin
   du position:relative ajouté plus haut.
   CONTRASTE : blanc sur prune #2d1628 à 0,88 d'alpha. Même composé sur du blanc
   pur (le pire cas : un banc de neige au soleil), le fond rend rgb(70,50,66) et
   le blanc dessus mesure ≈ 11:1 — très au-dessus du 4,5 exigé.
   TAILLES : racine ≈ 9,8 px ici, donc 1,85rem ≈ 18,1 px desktop (plancher
   CLAUDE.md 17,6 px) et 1,6rem ≈ 15,8 px mobile (plancher 14,4 px). */
.legende-exemple {
  position: absolute; right: 0; bottom: 0; z-index: 4;
  width: min(56rem, 100%);
  margin: 0; padding: 1.3rem 1.8rem;
  background: rgba(45, 22, 40, 0.88);
  color: #fff; font-style: italic;
  font-size: 1.85rem; line-height: 1.45;
}
@media (max-width: 767px) {
  .legende-exemple { width: 100%; font-size: 1.6rem; padding: 1.1rem 1.4rem; }
  /* Au héros seulement : le fond photo s'arrête à 78svh alors que la section en
     fait 100 — une légende collée au bas de la photo recouvrait les boutons.
     Elle repasse donc en FLUX, dernier bloc du héros, et la section grandit. */
  .hero > .legende-exemple { position: static; margin-top: 2.4rem; }
}

/* ---------- S9 Secteurs + carte des 8 secteurs ---------- */
.secteurs-flex {
  grid-column: contenu-deb / contenu-fin;
  display: grid; grid-template-columns: 5fr 7fr; gap: var(--col-gap);
  align-items: center; margin-top: 5rem;
}
.secteurs-liste { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem 2rem; }
.secteurs-liste li {
  font-family: var(--police-titre); font-size: 2.8rem; text-transform: uppercase;
  padding: 1rem 0; border-bottom: var(--bord-1) solid var(--bord);
}
/* (Le radar décoratif a été SUPPRIMÉ en V2 : la vraie carte des 8 secteurs
   prend sa place — un objet qui dit quelque chose au lieu d'un ornement.) */
.secteurs-note { grid-column: contenu-deb / contenu-fin; margin-top: 3rem; font-size: var(--fs-note); }
.secteurs-note a { color: var(--vert-f); font-weight: 600; }
@media (max-width: 767px) {
  .secteurs-flex { grid-template-columns: 1fr; }
  .secteurs-liste li { font-size: 2.2rem; }
}

/* ---------- S10 FAQ ---------- */
.faq-liste { grid-column: contenu-deb / span 12; margin-top: 4rem; }
.faq-item { border-bottom: var(--bord-1) solid var(--bord); }
.faq-item summary {
  cursor: pointer; list-style: none; position: relative;
  padding: 2.4rem 5rem 2.4rem 0; font-size: 2rem; font-weight: 600;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: ''; position: absolute; right: 1rem; top: 50%;
  width: 1.2rem; height: 1.2rem;
  border-right: 0.28rem solid var(--vert-f); border-bottom: 0.28rem solid var(--vert-f);
  transform: translateY(-70%) rotate(45deg); transition: transform 0.3s;
}
.faq-item[open] summary::after { transform: translateY(-30%) rotate(225deg); }
.faq-item p { padding: 0 0 2.6rem; max-width: 68rem; color: var(--note); }

/* ---------- S11 CTA ---------- */
#cta { text-align: center; background: var(--glace); }
.cta-titre { grid-column: contenu-deb / contenu-fin; }
.cta-texte { grid-column: contenu-deb / contenu-fin; margin-top: 2.4rem; font-size: 2rem; }
.cta-btn { justify-self: center; grid-column: contenu-deb / contenu-fin; margin-top: 3.6rem; }

/* ---------- S12 Formulaire-offre ---------- */
.offre { grid-column: contenu-deb / span 11; }
.offre-sous { margin-top: 1.6rem; color: var(--note); }
.offre-form { margin-top: 4rem; position: relative; }
.offre-progression {
  height: 0.4rem; background: var(--glace); border-radius: 0.2rem;
  margin-bottom: 3.2rem; overflow: hidden;
}
.offre-barre {
  display: block; height: 100%; width: 20%;
  background: var(--vert-f); transition: width 0.4s;
}
.offre-etape { border: 0; }
.offre-etape legend { margin-bottom: 2.4rem; }
.offre-pastilles { display: flex; flex-wrap: wrap; gap: 1.2rem; }
.offre-pastilles label { cursor: pointer; position: relative; }
.offre-pastilles input { position: absolute; opacity: 0; }
.offre-pastilles span {
  display: inline-flex; flex-direction: column; align-items: center; gap: 0.6rem;
  padding: 1.4rem 2.2rem; border: var(--bord-1) solid var(--bord-fort);
  border-radius: var(--radius); font-size: var(--fs-ui); font-weight: 600;
  transition: border-color 0.3s, background-color 0.3s, color 0.3s;
}
.offre-pastilles span b { font-family: var(--police-titre); font-size: 2.2rem; font-weight: 400; }
.offre-pastilles input:checked + span { background: var(--vert-f); border-color: var(--vert-f); color: var(--neige); }
.offre-pastilles input:focus-visible + span { outline: 0.3rem solid var(--jaune); outline-offset: 0.2rem; }
.offre-types span { min-width: 16rem; }
.offre-champ {
  width: min(38rem, 100%); padding: 1.6rem 2rem; font: inherit;
  border: var(--bord-1) solid var(--bord-fort); border-radius: var(--radius);
}
.offre-champ:focus-visible { outline: 0.3rem solid var(--jaune); outline-offset: 0.2rem; }
.offre-suivant { margin-top: 3.2rem; }
.offre-suivant:disabled { opacity: 0.35; cursor: not-allowed; }
.offre-recap { padding-top: 2rem; }
.offre-recap-detail { font-size: 2rem; margin: 1.2rem 0 0.6rem; }
.offre-recap-prix { color: var(--vert-f); margin-bottom: 2.8rem; }
.offre-recap .note { margin-top: 2rem; }

/* ---------- S13 Contact ---------- */
.contact-colonnes {
  grid-column: contenu-deb / contenu-fin;
  display: flex; justify-content: space-between; align-items: flex-end; gap: 4rem;
  flex-wrap: wrap;
}
.contact-liste { margin-top: 2.8rem; }
.contact-liste li { padding: 0.9rem 0; font-size: 2rem; }
.contact-liste a { text-decoration-color: var(--vert-f); text-underline-offset: 0.4rem; }
.contact-sociaux { display: flex; gap: 1.6rem; }
.contact-sociaux a {
  display: grid; place-items: center; width: 4.8rem; height: 4.8rem;
  border: var(--bord-1) solid var(--bord-fort); border-radius: 50%;
  transition: border-color 0.3s, color 0.3s;
}
.contact-sociaux a:hover { border-color: var(--vert-f); color: var(--vert-f); }

/* ---------- S14 Pied ---------- */
/* overflow:clip — le rappel géant en filigrane est plus large que l'écran en
   mobile ; c'est voulu (il doit être coupé), mais sans clip il élargissait la
   page de 98 px. Bug hérité de la V1, trouvé à la QA scriptée du 7 août. */
.pied { background: var(--nuit); color: var(--encre); position: relative; overflow: clip; }
.pied .sep-congere { color: var(--nuit); position: absolute; top: 0; transform: translateY(-98%); }
.pied-interieur { padding-block: 10rem 4rem; }
.pied-rappel {
  grid-column: contenu-deb / contenu-fin;
  color: rgba(223, 228, 233, 0.1); line-height: 0.95;
}
.pied-nav {
  grid-column: contenu-deb / contenu-fin;
  display: flex; flex-wrap: wrap; gap: 2.8rem; margin-top: 5rem;
  font-size: var(--fs-ui); text-transform: uppercase; letter-spacing: 0.08em;
}
.pied-nav a { text-decoration: none; }
.pied-nav a:hover { color: var(--vert-f); }
.pied-demo {
  grid-column: contenu-deb / contenu-fin;
  margin-top: 4rem; font-size: var(--fs-badge); color: var(--note);
}
.pied-demo a { color: var(--encre); }

/* ---------- S15 Légal (:target) ---------- */
.legal { display: none; background: var(--neige); color: var(--encre); }
.legal:target { display: block; }
.legal-interieur { max-width: 78rem; margin-inline: auto; padding: 8rem var(--pad-container); }
.legal-interieur h2 { margin-top: 3rem; }
.legal-interieur p { margin-top: 1.4rem; font-size: var(--fs-note); }
.legal-interieur a { color: var(--vert-f); }

/* ---------- Curseur FLOCON (pointeur fin seulement — idée Yannick 3 août) ---------- */
@media (pointer: fine) {
  .curseur {
    position: fixed; z-index: 99; width: 3rem; height: 3rem;
    pointer-events: none; top: -1.5rem; left: -1.5rem;
    color: var(--vert-f); opacity: 0;
    transition: transform 0.25s, color 0.25s, opacity 0.25s;
  }
  .curseur svg { width: 100%; height: 100%; animation: flocon-tourne 14s linear infinite; }
  .curseur.actif { opacity: 0.85; }
  .curseur.survole { transform: scale(1.55); color: var(--jaune); opacity: 1; }
  @keyframes flocon-tourne { to { transform: rotate(360deg); } }
}

/* ---------- Reduced motion : tout a l'etat final ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  .pin, .etiquette, .tracteur, .congere { opacity: 1 !important; }
  .fleche { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
}

/* ═══ SÉQUENCE HORIZONTALE (patron United Carriers — 4 août 2026) ═══
   Active seulement : desktop ≥768px ET html SANS .anim-statique (classe posée
   par premium.js quand reduced-motion / tier LuxAnim statique / GSAP absent).
   Partout ailleurs, le socle vertical ci-dessus fait le repli tout seul. */
@media (min-width: 768px) {
  html:not(.anim-statique) .piste-hiver { height: calc(100vh + 400vw); }
  html:not(.anim-statique) .piste-colle {
    position: sticky; top: 0; height: 100vh; overflow: clip;
  }
  /* SENS INVERSÉ (différenciation du 24 août 2026) : `row-reverse` met la piste
     en MIROIR — le panneau 1 se retrouve tout à DROITE de la course. Le tween de
     premium.js part alors de -(course) pour revenir à 0 : les panneaux entrent
     par la GAUCHE au lieu de sortir par la gauche. L'ordre du récit est intact
     (c'est l'ordre du DOM qui est simplement lu de droite à gauche) — mais
     #services doit être renversé LUI AUSSI, sinon ses 3 écrans se lisent à
     l'envers à l'intérieur du miroir. */
  html:not(.anim-statique) .piste {
    display: flex; flex-direction: row-reverse;
    width: max-content; position: relative; z-index: 1;
    height: 100%; will-change: transform;
  }
  html:not(.anim-statique) .piste > .panneau {
    width: 100vw; flex: 0 0 auto; min-height: 100vh; align-content: center;
  }
  html:not(.anim-statique) .piste #services {
    display: flex; flex-direction: row-reverse; background: transparent;
  }
  html:not(.anim-statique) .piste #services .ecran { width: 100vw; flex: 0 0 auto; }
  /* Le blizzard devient l'overlay du viewport sticky (le hack canvas-sticky
     du mode vertical n'a plus de sens ici) */
  html:not(.anim-statique) .blizzard canvas { position: absolute; inset: 0; height: 100%; }
  html:not(.anim-statique) .neige-avant { margin-top: 0; }
  /* (Règles route + tracteur retirées le 4 août au soir — stand-by.) */
}

/* ═══ MOBILE : la grille 16 colonnes se replie en UNE colonne ═══
   (7 août 2026 — bug hérité, trouvé à la QA scriptée en 390 px.)
   Le socle 16 colonnes garde ses 15 gouttières de 3,6 rem quelle que soit la
   largeur : ~520 px de vide sur un écran de 390. Les colonnes, elles, tombent
   à 0 (minmax(0,…)) — donc le contenu était poussé HORS de l'écran et coupé
   par le `overflow-x: clip` posé en urgence le 4 août. Le clip cachait le
   symptôme, pas la cause.
   Ici : une seule colonne de contenu, zéro gouttière, et TOUS les enfants
   ramenés sur cette colonne (sinon un `span 9` créerait des colonnes
   implicites et le débordement reviendrait par la porte d'à côté). */
@media (max-width: 767px) {
  .grille {
    grid-template-columns:
      [pleine-deb] var(--pad-container)
      [contenu-deb] minmax(0, 1fr)
      [contenu-fin] var(--pad-container) [pleine-fin];
    column-gap: 0;
  }
  .grille > * { grid-column: contenu-deb / contenu-fin; }
  .grille > .pleine, .grille > .hero-fond { grid-column: pleine-deb / pleine-fin; }

  /* ── Échelle de texte propre au mobile ──
     Les --fs-* du 3 août sont calibrés pour le desktop : reportés tels quels
     sur 390 px, le corps sortait à 26 px et le kicker prenait trois lignes.
     Valeurs ci-dessous en px RÉELS à 390 px de large (racine ≈ 9,9 px), toutes
     au-dessus des planchers CLAUDE.md : corps 17 px (min 16) · UI 15 px
     (min 12,8) · badges 13 px (min 12). */
  :root {
    --fs-corps: 1.72rem;  /* ≈ 17 px */
    --fs-note: 1.68rem;   /* ≈ 16,6 px */
    --fs-ui: 1.5rem;      /* ≈ 15 px */
    --fs-badge: 1.32rem;  /* ≈ 13 px */
  }
  /* La barre : le logo passait SOUS le bouton et se faisait recouvrir. */
  .nav { padding: 1.2rem var(--pad-container); gap: 1.2rem; }
  .nav-logo { font-size: 1.5rem; line-height: 1.15; }
  .nav-cta { padding: 0.9rem 1.6rem; white-space: nowrap; }
  .hero { padding-top: 9rem; }
  .hero-cta .btn { flex: 1 1 auto; justify-content: center; }

  /* Même condensée, une display en capitales déborde vite sur 390 px : les
     titres de section descendent d'un cran de plus que le palier 991 px.
     Anton gagne ~30 % de largeur, donc le cran est moins bas qu'avec Archivo. */
  h2, .h2 { font-size: 3.9rem; }
  h3, .h3 { font-size: 3rem; }

  /* Le relevé en flex donnait 2 + 1 en quinconce ; en grille, les trois
     colonnes s'alignent, libellé au-dessus de sa valeur. */
  .hero-releve { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem 2.4rem; }

  /* « SAINTE-SCHOLASTIQUE » cassait en deux dans une demi-colonne : la liste
     des secteurs passe sur une seule colonne. */
  .secteurs-liste { grid-template-columns: 1fr; }
  .secteurs-liste li { font-size: 2rem; }

  /* La carte à plat en mobile : inclinée à 38°, avec un SVG en overflow:visible,
     elle remontait par-dessus la liste des secteurs au lieu de rester dans sa
     rangée. À plat, elle s'inscrit dans sa boîte. */
  .carte { transform: none; filter: none; }
  .carte-scene { width: 100%; perspective: none; }
  .carte-secteurs { margin-top: 4rem; }

  /* Le rappel géant du pied faisait cinq lignes plein écran avant d'arriver
     aux liens : c'est un filigrane, pas une section. */
  .pied-rappel { font-size: 4.6rem; }
  .pied-interieur { padding-block: 6rem 3rem; }
}

/* ═══ TWEAKS PAR SECTION — VERSION 2 « NUIT » (7 août 2026) ═══
   ⚠️ Le bloc du 3 août (réglages tweaks bar de Yannick) forçait ici
   `--encre:#000000` sur l'entête et le héros, et `--glace:#8bccfd` sur sept
   sections : c'est LUI qui produisait le bleu ciel pâle de la V1, pas le socle.
   Il est conservé intact dans DEMOS/Deneigement-Roger-demo/ (la V1).
   Ci-dessous, les mêmes leviers, réglés pour la nuit — chaque section reçoit
   sa profondeur pour que le défilement respire au lieu d'être un aplat noir. */
#accueil {
  --glace: #10151c;
}
.piste #services {   /* les prix : le palier le plus clair de la nuit */
  --glace: #131a23;
}
#pourquoi {          /* la tempête : le point le plus profond de la page */
  --vert: #7ecbe8;   /* aligné GLACIER 25 août (ex-#8bccfd) */
}
#equipement {
  --glace: #0f141b;
}
#secteurs {
  --vert: #7ecbe8;   /* aligné GLACIER 25 août (ex-#8bccfd) */
}
#cta {               /* l'appel : remonte d'un ton pour appeler le clic */
  --glace: #151d27;
}
#reserver {
  --glace: #10151c;
}
#contact {
  --vert: #7ecbe8;   /* aligné GLACIER 25 août (ex-#8bccfd) */
}

/* ═══ PISTE HORIZONTALE — VIEWPORTS COURTS (20 août 2026) ═══
   Bug rapporté au téléphone par le client 4G, reproduit au navigateur.

   CAUSE : .piste-colle est collée à `height: 100vh` avec `overflow: clip`, et
   .ecran centre son contenu (`align-items: center`). Dès qu'un panneau est plus
   haut que l'écran, le débordement part des DEUX côtés et se fait rogner — le
   kicker et le titre disparaissent en haut, les cartes en bas — sans aucun
   moyen d'y accéder, puisque le conteneur est clippé et non défilant.
   Invisible sur un 1920×1080 (il restait 22 px de marge sur le panneau le plus
   haut), franc sur un portable 1366×768 à l'échelle Windows 125 % (≈ 1093×614 px
   CSS) : 145 à 365 px de texte perdus selon le panneau. À l'échelle 100 % du même
   portable (1366×768) le panneau le plus lourd débordait encore de 211 px — ce
   qui explique « à 80 % ça s'améliore » : baisser l'échelle rallonge le viewport.

   CORRECTIF, en deux temps :
   1. `safe center` — garde-fou permanent. Si un panneau déborde malgré tout
      (contenu plus long sur une future maquette, échelle Windows 150 %), il
      s'aligne en HAUT au lieu de couper le titre.
   2. Un traitement COMPACT sous 1050 px de hauteur : l'air vertical et les deux
      blocs de texte lourds deviennent fluides en vh. Au-dessus de 1050 px —
      donc sur 1920×1080 — AUCUNE de ces règles ne s'applique : la maquette
      validée par Yannick est intacte par construction, pas par calcul.
   Mesuré : les panneaux tiennent dès 550 px de hauteur utile, sous la barre
   fixe et au-dessus du bandeau, texte à 18,6 px (plancher CLAUDE.md : 17,6 px).

   Deux boutons de calibration, à MESURER par maquette (barre et bandeau sont en
   rem, donc les valeurs suivent l'échelle) et à relever au-dessus de ce bloc
   quand la mesure l'exige :
   · --degagement-nav       hauteur de la barre fixe du haut (défaut 10rem =
                            une barre sur une ligne ; 14,5rem si elle en fait deux)
   · --degagement-piste-bas hauteur du bandeau « maquette » du bas (défaut 4rem =
                            une ligne ; 7rem si le texte en prend deux) */
@media (min-width: 768px) {
  html:not(.anim-statique) .piste .ecran { align-items: safe center; }
  html:not(.anim-statique) .piste > .panneau { align-content: safe center; }
}
@media (min-width: 768px) and (max-height: 1050px) {
  html:not(.anim-statique) .piste .ecran-contenu {
    padding-top: var(--degagement-nav, 10rem);
    padding-bottom: max(var(--degagement-piste-bas, 4rem), clamp(2.4rem, 5vh, 10rem));
  }
  html:not(.anim-statique) .piste .cartes-prix,
  html:not(.anim-statique) .piste .inclus-liste { margin-top: clamp(1.4rem, 2.6vh, 4rem); }
  /* La fiche n'a plus de padding latéral (elle n'a plus de boîte) : seul l'air
     vertical se compresse sur les écrans courts. */
  html:not(.anim-statique) .piste .carte-prix { padding: clamp(1.4rem, 2.6vh, 2.6rem) 0 clamp(1.6rem, 2.9vh, 3rem); }
  html:not(.anim-statique) .piste .carte-montant { margin-top: clamp(0.9rem, 1.8vh, 2.4rem); }
  html:not(.anim-statique) .piste .carte-montant .prix { font-size: clamp(2.4rem, 4.2vh, 4.2rem); }
  html:not(.anim-statique) .piste .carte-desc { font-size: clamp(1.85rem, 2.9vh, var(--fs-note)); }
  html:not(.anim-statique) .piste .inclus-liste li {
    padding-block: clamp(0.9rem, 1.8vh, 2.2rem);
    font-size: clamp(1.85rem, 3.05vh, var(--fs-note));
    line-height: 1.35;
  }
  /* Le crochet suit la nouvelle marge haute de son item. */
  html:not(.anim-statique) .piste .inclus-liste li::before { top: calc(clamp(0.9rem, 1.8vh, 2.2rem) + 0.7rem); }
}
