/* ============================================================
   Entreprise SME — Excavation & Déneigement
   Maquette LuxAura Studio (18 août 2026) — 3 pages, UNE identité.

   MODE COPIE : structure, patrons de performance et CSS repris de
   maquettes/deneigement-a-chaumont-…/ (elle-même copie de
   DEMOS/Deneigement-Roger-demo-v2/, référence de niche « nuit »).
   Ce qui change ici : la PALETTE (terre et sable mesurés sur les chantiers
   de SME au lieu du rose Chaumont), les photos, et les sections qui
   reposaient sur des faits propres à A. Chaumont (permis municipal,
   zone desservie, équipe, balises roses) — supprimées, faute d'équivalent
   sourcé chez SME. Deux blocs sont NEUFS : le split été/hiver de l'accueil
   et le squelette de la page Excavation (sections numérotées 01-04).

   ── PALETTE, et pourquoi chaque valeur est celle-là ──
   Ancres mesurées sur ses photos (intake du 18 août) : anthracite #13191b,
   terre #8f765e, ambre/sable #c2a17d, rouge machines #743733. Tous les
   contrastes ci-dessous sont CALCULÉS (WCAG 2.1), jamais jugés à l'œil :

     --encre  #eceae6  sur le fond  → 14,78:1  (texte courant)
     --note   #c3bdb4  sur le fond  →  9,52:1  (texte secondaire)
     --sable  #c2a17d  sur le fond  →  7,35:1  (TOUT le texte d'accent)
     --sable-clair #d9c0a1          → 10,15:1  (survol des liens)
     --terre  #8f765e  sur le fond  →  4,16:1  ✗ SOUS le seuil de 4,5:1
                                       → DÉCOR SEULEMENT (filets, aplats,
                                         chiffres géants en filigrane),
                                         JAMAIS de texte à lire.
     --rouge  #743733  : blanc dessus → 8,99:1 ✓ (aplats seulement ;
                         sur le fond il ne fait que 1,98:1 → jamais en texte)
     --rouge-clair #c96a5f sur le fond → 4,83:1 ✓ (accent secondaire lisible)

   Le bouton plein prend le SABLE en fond avec de l'encre foncée dessus
   (7,35:1). L'inverse — blanc sur sable — ne donnait que 2,42:1 : écarté.

   ── Deux ambiances, un seul site ──
   Même typo, même barre, même grille, même grammaire sur les 3 pages.
   La page Déneigement pose `body.hiver`, qui refroidit UNIQUEMENT les trois
   fonds (bleu de nuit hérité de Roger) : les accents chauds, eux, restent —
   c'est ce qui garde l'hiver dans la même maison que l'été.
   ============================================================ */

/* ---------- 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 {
  /* ── Les trois fonds (du plus clair au plus profond) ── */
  --neige: #13191b;    /* [USAGE : fond général de la page · fond des cartes] — anthracite mesuré */
  --glace: #191f21;    /* [USAGE : fonds de section surélevés · loader] */
  --glace-2: #1e2528;  /* [USAGE : cartes posées sur --glace] */
  --glace-3: #232b2e;  /* [USAGE : réserve] */
  --nuit: #0d1113;     /* [USAGE : fonds les plus profonds — héros · pied de page] */
  --encre: #eceae6;    /* [USAGE : tout le texte principal] — 14,78:1 */
  --note: #c3bdb4;     /* [USAGE : textes secondaires · légendes · kickers] — 9,52:1 */
  --bord: rgba(236, 234, 230, 0.14);      /* [USAGE : bordures fines · séparateurs] */
  --bord-fort: rgba(236, 234, 230, 0.36); /* [USAGE : bordures boutons · champs] */

  /* ── Accents chauds : mesurés sur la terre et les machines ── */
  /* Orange machinerie brûlé (verdict 18 août, 3e essai : sable trop pâle,
     jaune chantier refusé — ne ressortait pas sur le thème noir Roger).
     Code couleur de l'industrie (Kubota/Hitachi), présent sur ses chantiers. */
  --sable: #ec8b4a;       /* 7,07:1 — [USAGE : TOUT le texte d'accent] */
  --sable-clair: #f5ad72; /* 9,39:1 — [USAGE : survol des liens texte] */
  --terre: #8f765e;       /* 4,16:1 — [USAGE : DÉCOR seulement : filets, chiffres en filigrane] */
  --rouge: #743733;       /* blanc dessus 8,99:1 — [USAGE : aplats, jamais de texte dessus le fond] */
  --rouge-clair: #c96a5f; /* 4,83:1 — [USAGE : accent secondaire lisible] */
  --phare: #f0dcc2;       /* [USAGE : halos et lueurs chaudes] */

  /* ── Alias hérités de la référence Roger V2 ──
     Les règles de section copiées plus bas parlent encore en « rose »,
     « vert-f », « jaune ». On les REBRANCHE ici au lieu de renommer 900
     lignes : un alias par rôle, aucune couleur nouvelle. */
  --rose: var(--sable);        /* fond des boutons pleins · bandeau défilant */
  --rose-f: var(--sable-clair);/* survol des boutons pleins */
  --vert-f: var(--sable);      /* TOUT le texte d'accent */
  --vert-n: var(--sable-clair);/* survol des liens texte */
  --vert: var(--rouge-clair);  /* accent secondaire */
  --jaune: var(--sable);       /* anneaux de focus */
  --jaune-2: var(--terre);
  --rouge-f: #5c2b28;
  --brique: var(--rouge);

  /* ── Typo d'INSTRUMENT (auto-hébergée, aucune Google Fonts) ── */
  --police-titre: 'Archivo Black', Impact, 'Haettenschweiler', sans-serif;
  --police-corps: 'Geist', 'Inter', system-ui, -apple-system, sans-serif;
  --police-mono: 'Geist Mono', 'SF Mono', Consolas, monospace;
  --h1-min: 4.4rem;
  --h1-max: 8rem;
  --h1-graisse: 400;
  --h1-interlettre: -0.025em;
  --fs-corps: 2.63rem;  /* ≈ 18 px réels @1728 */
  --fs-note: 2.85rem;
  --fs-ui: 2.58rem;
  --fs-badge: 2rem;

  /* ── Layout ── */
  --pad-container: 1.93rem;
  --col-gap: 3.6rem;
  --radius: 1.97rem;
  --bord-1: max(1px, 0.1rem);
}

/* ── AMBIANCE HIVER (page Déneigement seulement) ──
   Seuls les trois FONDS refroidissent : les accents chauds traversent la
   saison, sinon on aurait deux sites au lieu de deux ambiances. Contrastes
   recalculés sur le fond froid : encre 15,55:1 · note 10,01:1 · sable 7,73:1. */
body.hiver {
  --neige: #0d1319;
  --glace: #141c24;
  --glace-2: #1a232c;
  --nuit: #080d12;
}

@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: 'Archivo Black';
  src: url('../fonts/archivo-black.woff2') format('woff2');
  font-weight: 400;
  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. */
  line-height: 1.14;
  letter-spacing: var(--h1-interlettre);
}
.kicker + h1, .kicker + h2, .kicker + h3, .kicker + .h4 { margin-top: 1.4rem; }
/* Échelle redescendue d'un cran : Archivo Black porte beaucoup plus large que
   Playfair, et les titres de la séquence horizontale débordaient de leur
   panneau de 100vw. */
.h0 { font-size: 13rem; }
h1, .h1 { font-size: clamp(var(--h1-min), 8vw, var(--h1-max)); }
h2, .h2 { font-size: 5.6rem; }
h3, .h3 { font-size: 3.9rem; }
.h4 { font-size: 3.1rem; }
@media (max-width: 991px) {
  .h0 { font-size: 8.6rem; }
  h2, .h2 { font-size: 4.2rem; }
  h3, .h3 { font-size: 3.1rem; }
}

/* 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;
  border-radius: var(--radius);
  border: var(--bord-1) solid transparent;
  transition: background-color 0.3s, color 0.3s, border-color 0.3s, transform 0.3s;
  min-height: 4.4rem;
}
.btn:active { transform: translateY(1px); }
/* Le bouton plein est le SEUL aplat de sable qui porte du texte. Le sable est
   CLAIR : c'est donc l'encre foncée qui passe dessus (7,35:1). L'inverse —
   blanc sur sable — ne donnait que 2,42:1 : calculé, puis écarté. */
.btn-plein { background: var(--rose); color: #13191b; }
/* Survol vers le PLUS CLAIR (l'inverse de la référence, dont l'accent était
   sombre) : #d9c0a1 sous l'encre foncée remonte à 10,15:1. */
.btn-plein:hover { background: var(--rose-f); color: #13191b; }
.btn-contour { border-color: var(--bord-fort); color: var(--encre); }
.btn-contour:hover { border-color: var(--encre); }

/* ---------- 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;
}
/* Voile de tête, tant que la barre n'a pas pris son fond (QA 18 août) :
   mesuré sur la photo d'été de l'accueil, le logo orange tombait à 1,22:1 et
   les liens blancs à 3,06:1 sur le ciel. Le dégradé remonte le logo à ~5,5:1
   et les liens à ~13:1, sans poser de barre pleine sur la photo. */
.nav::before {
  content: ''; position: absolute; inset: 0 0 -4rem 0; z-index: -1;
  pointer-events: none; transition: opacity 0.4s;
  background: linear-gradient(to bottom,
    rgba(8, 11, 13, 0.85) 0%, rgba(8, 11, 13, 0.72) 55%, rgba(8, 11, 13, 0) 100%);
}
.nav.nav-fond::before { opacity: 0; }
.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);
}
/* « ❄ DÉNEIGEMENT A. CHAUMONT » fait 25 signes contre 17 à « DÉNEIGEMENT
   ROGER » : à 2rem il passait sur deux lignes à 1280 px et écrasait les liens
   (constaté au navigateur). Un cran plus bas + nowrap, et il tient. */
.nav-logo {
  font-family: var(--police-titre); font-size: 1.7rem; letter-spacing: 0.02em;
  text-decoration: none; text-transform: uppercase; white-space: nowrap;
}
.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. */
@media (max-width: 991px) {
  /* 991 et non 767 (18 août, SME) : entre 768 et 991, la nav complète
     débordait — logo sur « SERVICES », bouton Soumission coupé (vu à 820). */
  /* À 390 px, « ❄ DÉNEIGEMENT A. CHAUMONT » + le bouton + le burger font
     ~480 px : le bouton sortait de l'écran. Le mot générique tombe, le NOM
     reste — c'est lui qu'on doit lire. */
  .nav-logo { font-size: 1.5rem; }
  .nav-logo .nav-long { display: none; }
  .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 ---------- */
.hero {
  min-height: 100svh; align-items: center; padding-top: 12rem; padding-bottom: 6rem;
  overflow: clip; background: var(--nuit);
}
/* Photo plein cadre : elle porte l'ambiance, jamais la lecture. Le voile est
   assez fort pour garder le H1 à 12:1 même sur la partie la plus claire de
   l'image (la neige au soleil). */
/* 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;
}
.hero-fond img {
  /* Verdict Yannick 18 août : la photo héros se montre NUE — aucun filtre.
     Le contraste vit sur le texte (scrim local + ombre portée), voir ::after.
     Chaque page repose object-position à sa photo (voir plus bas). */
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%;
}
/* Le scrim vit SEULEMENT du côté du texte et meurt avant le sujet ; petits
   fondus haut (nav) et bas (transition). Le reste de la photo est nu. */
/* ⚠️ 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 — c'est ce qui a
   fait disparaître la machine deux fois le 7 août. On écrit la couleur du
   voile en alpha 0 (rgba(13,17,19,0)) pour que la transition reste propre. */
.hero-fond::after {
  content: ''; position: absolute; inset: 0;
  background:
    /* Le palier de 30 % laissait la fin des lignes de texte sur la crête de
       neige et la lame jaune (3,6-4,2:1 mesurés en QA le 18 août) : le voile
       tient maintenant jusqu'à 34 % et meurt à 62 %. Le SUJET (la machine,
       au-delà de 60 %) reste nu — c'est le verdict « photo nue » de Yannick. */
    linear-gradient(100deg,
      rgba(13, 17, 19, 0.90) 0%, rgba(13, 17, 19, 0.74) 34%,
      rgba(13, 17, 19, 0) 62%),
    linear-gradient(to bottom, rgba(13, 17, 19, 0.65) 0%, rgba(13, 17, 19, 0) 15%),
    linear-gradient(to top, rgba(13, 17, 19, 0.88) 0%, rgba(13, 17, 19, 0) 15%);
}
/* 11 colonnes et non 9 : les titres de SME finissent par un POINT, et
   `.ligne { overflow: hidden }` (nécessaire au masque du SplitText) coupait
   net ce point sur « LA PELLE ARRIVE. » à 1440 px. Le titre est mesuré, pas
   deviné : 16 signes d'Archivo Black à 79 px font ~784 px, contre ~780 px
   de colonne utile en span 9. Deux colonnes de plus, et la ponctuation
   rentre à toutes les largeurs. */
.hero-texte { grid-column: contenu-deb / span 11; position: relative; z-index: 3; }
.hero-h1 .ligne { display: block; overflow: hidden; white-space: nowrap; }
.hero-h1 { font-size: clamp(var(--h1-min), 5.2vw, 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 {
  text-shadow: 0 0.1rem 0.5rem rgba(13, 17, 19, 0.92), 0 0.3rem 2rem rgba(13, 17, 19, 0.7);
}
.hero-sous {
  margin-top: 2.4rem; font-family: var(--police-mono); font-size: var(--fs-note);
  color: rgba(236, 234, 230, 0.88); letter-spacing: 0.02em;
  /* La ligne courait jusqu'à 62 % de la largeur, donc PAST le voile (qui meurt
     à 58 %) : sur la lame jaune du héros hiver, la fin de phrase tombait à
     4,1:1 (mesuré en QA le 18 août). Bornée, elle reste dans la zone voilée
     et la photo garde son cadrage nu. */
  max-width: 62rem;
}
.hero-cta { display: flex; flex-wrap: wrap; gap: 1.6rem; margin-top: 3.6rem; }

/* Héros déneigement : photo pleine résolution fournie par Yannick le 18 août
   (originaux FB 1536×2048, les DEUX tracteurs dans la neige) — plein cadre
   sans agrandissement, traitement standard. Le panneau divisé essayé plus tôt
   n'est plus nécessaire ; l'alternative reste notée au vault si une photo
   trop petite revient. */
body.hiver .hero-fond img { object-position: 55% 55%; }
@media (max-width: 767px) {
  /* Le ciel blanc de la photo neige passe sous le kicker : léger voile
     continu en haut (0,18-0,28 — la photo reste visible), assise inchangée. */
  body.hiver .hero-fond::after {
    background:
      linear-gradient(to bottom, rgba(8, 13, 18, 0.72) 0%, rgba(8, 13, 18, 0.28) 18%,
                      rgba(8, 13, 18, 0.18) 34%, rgba(8, 13, 18, 0.65) 48%,
                      rgba(8, 13, 18, 0.9) 66%, rgba(8, 13, 18, 0.96) 100%);
  }
}

/* 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); }
@media (max-width: 767px) {
  .hero-releve { gap: 0 3rem; margin-top: 3.4rem; }
  .hero-releve dd { font-size: 2.6rem; }
}

@media (max-width: 991px) {
  .hero { padding-top: 12rem; }
  .hero-texte { grid-column: contenu-deb / contenu-fin; }
  /* 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ébordait de l'écran :
     Archivo Black demande sa propre échelle en petite largeur. */
  /* 8,4vw et non 8,8 (18 août) : le point final de « LA PELLE RENTRE. »
     frôlait le bord à 390 px (16 signes, .ligne coupe en overflow:hidden). */
  .hero-h1 { font-size: clamp(2.9rem, 8.4vw, 4.6rem); }
  .hero-fond img { object-position: 62% 62%; }
  /* Mobile : photo dégagée dans le haut de l'écran, assise sombre sous le
     bloc texte seulement. */
  .hero-fond::after {
    background:
      linear-gradient(to bottom, rgba(13, 17, 19, 0.72) 0%, rgba(13, 17, 19, 0.12) 16%,
                      rgba(13, 17, 19, 0) 30%, rgba(13, 17, 19, 0.6) 46%,
                      rgba(13, 17, 19, 0.88) 66%, rgba(13, 17, 19, 0.96) 100%);
  }
}

/* ---------- 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 héritées de Roger V2 sont scopées à
   body.hiver. La page Excavation utilise le MÊME id pour son ancre de nav,
   et sans ce garde-fou elle héritait du `display:flex` de la séquence
   horizontale : ses quatre sections 01-04 se rangeaient côte à côte et la
   page faisait 4 écrans de large (vu au navigateur le 18 août). */
body.hiver #services { background: var(--glace); }
.blizzard {
  position: absolute; inset: 0; z-index: 0; overflow: clip; pointer-events: none;
}
.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 RETIRÉ (verdict Yannick 18 août, maquette SME) : en défilement
     horizontal, le rectangle pâle de l'écran suivant entrait dans le cadre
     comme une bande qui glisse entre l'intro et les services. Le texte vit
     directement sur la nuit + blizzard. (Historique Roger : 88 % → 42 % le
     3 août, → 0 ici.) */
}
/* (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;
}
.carte-prix {
  background: var(--neige); border: var(--bord-1) solid var(--bord);
  border-radius: var(--radius); padding: 3.2rem;
  transition: border-color 0.3s, transform 0.3s;
}
.carte-prix:hover { border-color: var(--bord-fort); transform: translateY(-0.4rem); }
.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); }
/* Prix en jaune de lame (demande de Yannick, 7 août) : ils rejoignent les
   chiffres géants et les crochets, et deviennent le point de fixation de la
   section — c'est l'information qu'on vient y chercher. */
.carte-montant .prix {
  font-family: var(--police-titre); font-size: 4.2rem; color: var(--vert-f);
  margin-right: 0.6rem; letter-spacing: 0.01em;
}
/* Chez Roger la valeur était un montant court (« 385 $ ») ; ici c'est
   « sur mesure », qui cassait en deux dans une carte de téléphone
   (« sur » / « mesure »). Un cran plus bas sous 640 px et la mention tient
   sur une ligne (QA 18 août). */
@media (max-width: 640px) { .carte-montant .prix { font-size: 3.2rem; } }
.inclus-liste { margin-top: 4rem; max-width: 72rem; }
.inclus-liste li {
  padding: 2.2rem 0 2.2rem 4.4rem; position: relative;
  /* 19 août 2026 (défaut de FAMILLE — fichier FONDATION) : 2rem en dur →
     var(--fs-note), aligné sur les cartes de services (vu sur 4G). */
  border-bottom: var(--bord-1) solid var(--bord); font-size: var(--fs-note);
}
.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 {
  /* 19 août 2026 (verdict Yannick, règle de FAMILLE — ce fichier est la FONDATION
     des copies double-service) : les lueurs radiales des sections sombres sont
     RETIRÉES des maquettes — la tache claire sur fond nuit lisait comme un défaut.
     Ne se réactive que sur demande explicite. */
  display: none;
}
@keyframes lueur-respire {
  from { opacity: 0.5; transform: translate(-2rem, 0); }
  to   { opacity: 1; transform: translate(2rem, -3rem); }
}
.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;
  /* 19 août 2026 (défaut de FAMILLE — fichier FONDATION) : 2.2rem en dur →
     var(--fs-note), aligné sur les cartes de services (vu sur 4G). */
  padding: 2.6rem 0; font-size: var(--fs-note); line-height: 1.45;
  border-bottom: var(--bord-1) solid rgba(236, 234, 230, 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 ---------- */
.marquee {
  background: var(--rose); overflow: clip;
  padding: 1.4rem 0; border-block: var(--bord-1) solid var(--bord);
}
/* L'id est nécessaire : `main > [id]` (0,1,1) rétablit --encre sur la barre et
   battait une simple classe. Blanc pur sur le rose = 5,03:1 ; --encre n'aurait
   donné que 4,31:1 (mesuré au navigateur). */
/* Encre foncée sur le sable = 7,35:1 ; le blanc n'aurait donné que 2,42:1. */
#reassurance.marquee { color: #13191b; }
.marquee-piste {
  display: flex; white-space: nowrap; width: max-content;
  animation: defile 30s linear infinite;
  font-size: var(--fs-ui); font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase;
}
@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;
}
.temoignage {
  border: var(--bord-1) solid var(--bord); border-radius: var(--radius);
  padding: 3.2rem; background: var(--neige);
}
.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; }
/* Un SEUL témoignage, parce qu'il n'y en a qu'un de RÉEL (publication
   Facebook du 13 août 2026). Les trois autres de la référence étaient
   fictifs : ils n'ont pas d'équivalent sourcé ici, donc ils n'existent pas. */
.temoignages-grille.une { grid-template-columns: minmax(0, 1fr); max-width: 96rem; }
.une .temoignage blockquote { font-size: 3.2rem; line-height: 1.4; }
@media (max-width: 767px) { .une .temoignage blockquote { font-size: 2.4rem; } }

/* Zone desservie — une seule ville, donc pas de liste ni de carte. */
.zone-p { grid-column: contenu-deb / span 10; margin-top: 3rem; }

.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 { 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); } }

/* ---------- Galerie 3 photos (variante de .equipement-cartes) ----------
   Sélecteur DOUBLE (.equipement-cartes.galerie-3) : la règle de base et la
   media query ci-dessus sont déjà passées, une classe seule ne les battrait
   pas de façon fiable. */
.equipement-cartes.galerie-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.galerie-3 .equipement-media { aspect-ratio: 4 / 3; }
.galerie-3 figcaption {
  padding: 2rem 2.4rem 2.4rem; font-size: var(--fs-note); color: var(--note);
}
@media (max-width: 991px) {
  .equipement-cartes.galerie-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .equipement-cartes.galerie-3 { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- S1b · L'équipe (section vedette, juste sous le héros) ---------- */
#equipe { background: var(--glace); }
.equipe-flex {
  grid-column: contenu-deb / contenu-fin;
  display: grid; grid-template-columns: 1.1fr 1fr;
  gap: var(--col-gap); align-items: center;
}
.equipe-media {
  overflow: clip; border-radius: var(--radius);
  border: var(--bord-1) solid var(--bord); aspect-ratio: 6 / 5;
}
.equipe-media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; }
.equipe-texte p { margin-top: 2.4rem; }
.equipe-texte .btn { margin-top: 3.4rem; }
@media (max-width: 991px) { .equipe-flex { grid-template-columns: minmax(0, 1fr); } }

/* ---------- Pastille du logo ----------
   Le logo fourni a un fond BLANC opaque : posé nu sur la nuit il ferait une
   tache carrée. Il vit donc dans sa propre carte blanche arrondie. */
.logo-pastille {
  display: inline-grid; place-items: center; width: fit-content;
  background: #ffffff; border-radius: var(--radius); padding: 1.4rem 1.8rem;
}
.logo-pastille img { width: 20rem; height: auto; }

/* ---------- 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(--rose); border-color: var(--rose); color: #13191b; }
.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; }

/* ---------- Formulaire de soumission (page excavation, démonstration) ---------- */
.soumission-form { margin-top: 4rem; }
.soumission-grille { display: grid; grid-template-columns: 1fr 1fr; gap: 2.4rem; }
.soumission-grille label {
  display: grid; gap: 0.9rem;
  font-size: var(--fs-note); color: var(--note);
}
.soumission-grille .offre-champ { width: 100%; }
.soumission-large { grid-column: 1 / -1; }
.soumission-fac { color: var(--note); opacity: 0.7; }
.soumission-form > .btn { margin-top: 3.2rem; }
.soumission-form > .note { margin-top: 2rem; max-width: 52rem; }
@media (max-width: 767px) {
  .soumission-grille { grid-template-columns: 1fr; }
}

/* ---------- 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(236, 234, 230, 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; }
}

/* ═══ 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;
  }
  html:not(.anim-statique) .piste {
    display: flex; 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) body.hiver #services { display: flex; background: transparent; }
  html:not(.anim-statique) body.hiver #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; }

  /* Archivo Black en capitales déborde vite sur 390 px : les titres de section
     descendent d'un cran de plus que le palier 991 px. */
  h2, .h2 { font-size: 3.3rem; }
  h3, .h3 { font-size: 2.6rem; }

  /* 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; }

  /* 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: #191f21;
}
body.hiver #services {  /* les services : le palier le plus clair */
  --glace: #1c2326;
}

#equipement {
  --glace: #171d1f;
}

#cta {               /* l'appel : remonte d'un ton pour appeler le clic */
  --glace: #1f2629;
}
#reserver {
  --glace: #191f21;
}


/* ---------- Bandeau maquette (obligation /demo : aperçu non publié) ---------- */
.bandeau-maquette {
  /* left:50% + translateX(-50%) sur un bloc en largeur auto = shrink-to-fit
     calculé sur la MOITIÉ droite de l'écran : à 390 px, le bandeau tombait à
     ~180 px et empilait 4 lignes par-dessus le héros. left/right + margin auto
     le centre sans amputer sa largeur. */
  position: fixed; left: 0; right: 0; bottom: 0.8rem;
  margin-inline: auto; width: fit-content;
  z-index: 80; max-width: min(92vw, 60rem);
  background: rgba(13, 17, 19, 0.92); color: var(--note);
  border: var(--bord-1) solid var(--bord); border-radius: 999px;
  padding: 0.45rem 1.2rem; font-size: var(--fs-badge);
  text-align: center; line-height: 1.4; pointer-events: none;
}

/* ════════════════════════════════════════════════════════════════════
   BLOCS NEUFS — ils n'existent ni chez Roger V2 ni chez A. Chaumont.
   ① le SPLIT été/hiver de l'accueil   ② le squelette de la page Excavation
   ════════════════════════════════════════════════════════════════════ */

/* ---------- ① Accueil : split plein écran été / hiver ----------
   Deux panneaux-photo, un par univers. Le bloc d'identité ne flotte PAS sur
   les photos : il est posé sur son propre aplat de nuit, à cheval sur la
   couture. C'est ce qui garantit le contraste du nom et du slogan sans
   dépendre du cadrage ni de la météo du jour où la photo a été prise. */
.split {
  display: grid; grid-template-columns: 1fr 1fr;
  min-height: 100svh; position: relative;
}
.split-panneau {
  position: relative; overflow: clip; text-decoration: none;
  display: flex; flex-direction: column; justify-content: flex-end;
  /* Le bas est généreux : c'est là que vit le libellé du panneau, et le
     bandeau de maquette est fixé encore plus bas. Sans cette réserve, le
     lien « Voir l'excavation » passait sous le bandeau (vu au navigateur). */
  padding: 16rem var(--pad-container) 9rem;
  min-height: 100svh;
}
.split-panneau img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  z-index: 0; transition: transform 1.1s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Verdict Yannick 18 août : photos NUES ici aussi — aucun filtre. */
.split-ete img { object-position: 50% 40%; }
.split-hiver img { object-position: 52% 45%; }
/* Le voile n'existe qu'en BAS (assise du libellé) + un souffle en haut pour
   la nav ; le cœur de la photo reste nu. */
.split-panneau::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to top,
      rgba(13, 17, 19, 0.92) 0%, rgba(13, 17, 19, 0.66) 40%, rgba(13, 17, 19, 0) 66%),
    linear-gradient(to bottom, rgba(13, 17, 19, 0.5) 0%, rgba(13, 17, 19, 0) 12%);
  transition: background 0.6s;
}
.split-hiver::after {
  background:
    linear-gradient(to top,
      rgba(8, 13, 18, 0.92) 0%, rgba(8, 13, 18, 0.66) 40%, rgba(8, 13, 18, 0) 66%),
    linear-gradient(to bottom, rgba(8, 13, 18, 0.5) 0%, rgba(8, 13, 18, 0) 12%);
}
@media (hover: hover) {
  .split-panneau:hover img { transform: scale(1.045); }
  .split-panneau:hover::after {
    background:
      linear-gradient(to top,
        rgba(13, 17, 19, 0.88) 0%, rgba(13, 17, 19, 0.4) 30%, rgba(13, 17, 19, 0) 58%),
      linear-gradient(to bottom, rgba(13, 17, 19, 0.5) 0%, rgba(13, 17, 19, 0) 12%);
  }
}
.split-contenu {
  position: relative; z-index: 2;
  text-shadow: 0 0.1rem 0.5rem rgba(13, 17, 19, 0.92), 0 0.3rem 2rem rgba(13, 17, 19, 0.7);
}
.split-contenu h2 { font-size: 4.4rem; }
.split-saison {
  font-family: var(--police-mono); font-size: var(--fs-badge);
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--sable);
  /* ⚠️ EXCEPTION ASSUMÉE (verdict Yannick, 18 août 2026) : l'orange sur photo
     mesure ~2,2-2,6:1, SOUS le AA de la QA. Verdict : reste orange — « trop de
     blanc dans le site » — l'étiquette est décorative et doublée du H2 blanc
     conforme juste dessous. Ne pas « corriger » à la prochaine passe QA. */
}
.split-p { margin-top: 1.8rem; max-width: 40rem; color: var(--note); font-size: var(--fs-note); }
.split-lien {
  display: inline-flex; align-items: center; gap: 1rem; margin-top: 3rem;
  font-family: var(--police-mono); font-size: var(--fs-ui); font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--encre);
  border-bottom: 0.2rem solid var(--sable); padding-bottom: 0.8rem;
}
.split-panneau:hover .split-lien { color: var(--sable-clair); }
/* Le trait vertical qui sépare les deux saisons. */
.split::before {
  content: ''; position: absolute; z-index: 3; top: 0; bottom: 0; left: 50%;
  width: max(1px, 0.1rem); background: var(--bord-fort);
}

/* Le bloc d'identité, posé à cheval sur la couture.
   Il est ACCROCHÉ EN HAUT (top fixe) et non centré : centré, sur un écran de
   900 px de haut, il descendait sur les deux titres de panneau et les coupait
   en deux (vu au navigateur à 1440×900). Depuis le haut, sa hauteur ne peut
   plus grignoter la zone des libellés, quelle que soit la fenêtre. */
.identite {
  /* 19 août 2026 (verdict Yannick, défaut de FAMILLE — ce fichier est la
     FONDATION des copies double-service) : top minimal 11.7rem pour que la
     carte ne touche jamais la barre de navigation (précédent Légaré/4G). */
  position: absolute; z-index: 4; left: 50%; top: 11.7rem;
  transform: translateX(-50%);
  width: min(92vw, 62rem); text-align: center;
  background: rgba(13, 17, 19, 0.9);
  border: var(--bord-1) solid var(--bord-fort);
  border-radius: var(--radius);
  /* Chaque rem de hauteur compte : le bas de la carte doit rester AU-DESSUS
     de l'étiquette de saison des deux panneaux (« L'ÉTÉ » / « L'HIVER »).
     Mesuré à 1440×900 : la carte finit à ~423 px, les étiquettes à ~462 px. */
  padding: 3rem 3.4rem;
  backdrop-filter: blur(10px);
}
/* Une seule ligne : « ENTREPRISE SME » en Archivo Black demande ~0,62 em par
   signe, donc ~435 px à 50 px de corps — il tient dans les 540 px utiles. */
.identite h1 { font-size: clamp(2.6rem, 3.6vw, 5rem); }
.identite-sous {
  margin-top: 1.4rem; font-family: var(--police-mono); font-size: var(--fs-ui);
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--sable);
}
/* 2,5rem et non 2,9 : le slogan tient alors sur UNE ligne dans les 540 px
   utiles de la carte, ce qui lui rend son tranchant et économise 40 px. */
.identite-slogan {
  margin-top: 2rem; font-size: 2.5rem; line-height: 1.4; color: var(--encre);
  max-width: 52rem; margin-inline: auto;
}
.identite-tel { margin-top: 2.4rem; }

@media (max-width: 900px) {
  /* Empilé, l'aplat centré tomberait entre les deux photos et en masquerait
     une : il redevient un bloc de flux, posé AVANT le split. */
  .split { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .split::before { display: none; }
  .split-panneau { min-height: 56svh; padding: 10rem var(--pad-container) 5rem; }
  .identite {
    /* order:-1 — dans le HTML l'identité vient APRÈS les deux panneaux (elle
       leur est superposée en grand écran). Sans ça, en pile, le nom de
       l'entreprise arrivait en TROISIÈME position, sous les deux photos. */
    order: -1;
    position: static; top: auto; transform: none; width: auto; border: 0;
    border-radius: 0; backdrop-filter: none; background: var(--nuit);
    padding: 12rem var(--pad-container) 6rem;
  }
  .split-contenu h2 { font-size: 3.6rem; }
}

/* La bande Transport : le MÊME panneau que le duo (photo, voile, survol,
   libellé), simplement plus basse. Déclarée après la requête média des 900 px
   pour gagner l'ordre de source aux deux largeurs. */
.split-bande {
  min-height: 0; height: 42vh;
  padding: 6rem var(--pad-container) 4.5rem;
}
.split-bande img { object-position: 50% 55%; }
/* Un cran sous les 4,4rem du duo : c'est le troisième service, pas le premier. */
.split-bande h2 { font-size: 3.4rem; }
/* Une seule ligne pour la sous-ligne : c'est une bande, pas un paragraphe. */
.split-bande .split-p { max-width: none; margin-top: 1.2rem; }
.split-bande .split-lien { margin-top: 2rem; }
@media (max-width: 900px) {
  .split-bande { height: 40svh; padding: 5rem var(--pad-container) 4rem; }
  .split-bande h2 { font-size: 3rem; }
}

/* ---------- Accueil : le bloc « qui on est » ---------- */
#maison { background: var(--glace); }
.maison-flex {
  grid-column: contenu-deb / contenu-fin;
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--col-gap);
}
.maison-flex p { margin-top: 2.4rem; }
.maison-releve {
  margin-top: 4rem; padding-top: 2.6rem;
  border-top: var(--bord-1) solid var(--bord);
  display: grid; grid-template-columns: 1fr 1fr; gap: 3rem;
  font-family: var(--police-mono);
}
.maison-releve dt {
  font-size: var(--fs-badge); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--note);
}
.maison-releve dd { margin-top: 0.6rem; font-size: 2.6rem; color: var(--sable); }
@media (max-width: 900px) { .maison-flex { grid-template-columns: minmax(0, 1fr); } }
/* Sous 560 px, les deux relevés en demi-colonne cassaient « Excavation et
   déneigement » sur trois lignes de mono : on les empile (QA 18 août). */
@media (max-width: 560px) { .maison-releve { grid-template-columns: minmax(0, 1fr); gap: 2.2rem; } }

/* ---------- ② Excavation : les services numérotés 01-04 ----------
   Patron J. Derenzo : un service = un écran, image d'un côté, numéro géant
   et texte de l'autre, l'alternance donne le rythme.
   Le NUMÉRO est en --terre (4,16:1 sur le fond) : sous le seuil 4,5:1 du
   texte courant, mais très au-dessus du seuil de 3:1 qui s'applique au
   texte LARGE (ici ~90 à 150 px). C'est le seul endroit où la terre porte
   des glyphes, et c'est calculé, pas toléré. */
.srv { border-top: var(--bord-1) solid var(--bord); }
.srv:first-of-type { border-top: 0; }
.srv-bloc {
  grid-column: contenu-deb / contenu-fin;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--col-gap); align-items: center;
}
.srv-media {
  overflow: clip; border-radius: var(--radius);
  border: var(--bord-1) solid var(--bord); aspect-ratio: 4 / 5;
}
.srv-media img { width: 100%; height: 100%; object-fit: cover; }
.srv-num {
  font-family: var(--police-titre); font-size: clamp(7rem, 9vw, 13rem);
  line-height: 0.82; color: var(--terre); letter-spacing: -0.03em;
  display: block; margin-bottom: 1.6rem;
}
.srv-texte h2 { font-size: 4.6rem; }
.srv-texte p { margin-top: 2.4rem; max-width: 46rem; }
.srv-points { margin-top: 2.8rem; max-width: 46rem; }
.srv-points li {
  position: relative; padding: 1.4rem 0 1.4rem 3.4rem;
  border-bottom: var(--bord-1) solid var(--bord); font-size: 2rem;
}
.srv-points li:last-child { border-bottom: 0; }
.srv-points li::before {
  content: ''; position: absolute; left: 0.2rem; top: 2.1rem;
  width: 1.8rem; height: 0.9rem;
  border-left: 0.3rem solid var(--sable); border-bottom: 0.3rem solid var(--sable);
  transform: rotate(-45deg);
}
/* L'alternance : sur les blocs pairs, l'image passe à droite. `order` plutôt
   que `direction: rtl`, qui aurait aussi retourné la ponctuation française. */
.srv-bloc.a-droite .srv-media { order: 2; }
/* 19 août 2026 (verdict Yannick, défaut de FAMILLE — fichier FONDATION) : dans
   les blocs inversés, le texte se colle à l'image (miroir du bloc 01), sinon un
   trou s'ouvre entre le texte plafonné et l'image (vu sur 4G). Desktop seulement. */
@media (min-width: 901px) {
  .srv-bloc.a-droite .srv-texte { max-width: 46rem; justify-self: end; }
}
@media (max-width: 900px) {
  .srv-bloc { grid-template-columns: minmax(0, 1fr); }
  .srv-bloc.a-droite .srv-media { order: 0; }
  .srv-texte h2 { font-size: 3.3rem; }
}

/* ---------- Excavation : grille équipement à 4 cartes ---------- */
.equipement-cartes.galerie-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.galerie-4 .equipement-media { aspect-ratio: 4 / 3; }
.galerie-4 figcaption {
  padding: 2rem 2.4rem 2.4rem; font-size: var(--fs-note); color: var(--note);
}
@media (max-width: 1100px) { .equipement-cartes.galerie-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .equipement-cartes.galerie-4 { grid-template-columns: minmax(0, 1fr); } }

/* ---------- Excavation : le pont vers l'hiver ----------
   Le seul endroit de la page été où le froid apparaît : un aplat de nuit
   d'hiver au milieu de l'été, pour que le passage d'une saison à l'autre
   se voie avant même de cliquer. */
#pont { background: #0d1319; color: var(--encre); overflow: clip; }
#pont .kicker { color: var(--note); }
.pont-lueur {
  /* 19 août 2026 (verdict Yannick, règle de FAMILLE) : lueur radiale retirée —
     la « lumière qui apparaît du fond foncé » (section L'autre saison). */
  display: none;
}
.pont-texte { grid-column: contenu-deb / span 10; position: relative; }
.pont-texte p { margin-top: 2.6rem; max-width: 52rem; color: var(--note); }
.pont-texte .btn { margin-top: 3.6rem; }

/* ---------- Reveals doux (accueil + excavation, aucun canvas) ----------
   L'état de départ n'est posé QUE si le JS a confirmé qu'il va animer
   (classe .js-reveals sur <html>) : sans JS, sans GSAP ou en reduced-motion,
   rien n'est jamais caché. */
html.js-reveals .reveal { opacity: 0; transform: translateY(2.4rem); }

/* Bandeau maquette mesure a 6,7rem sur cette maquette (texte sur deux lignes). */
:root { --degagement-piste-bas: 7rem; }

/* ═══ 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); }
  html:not(.anim-statique) .piste .carte-prix { padding: clamp(1.6rem, 2.9vh, 3.2rem); }
  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); }
}

/* ============================================================
   20 août 2026 — Accueil : les avis en UN seul endroit, et la
   section À propos. Rien de neuf côté langage visuel : la grille
   d'avis est une variante de .temoignages-grille, le portrait
   réutilise .srv-media, les cartes de donation .equipement-carte.
   ============================================================ */

/* La grille d'avis à 3 colonnes (6 cartes = 2 rangées pleines). */
.temoignages-grille.trois { grid-template-columns: repeat(3, minmax(0, 1fr)); max-width: none; }
.trois .temoignage { padding: 2.8rem; }
/* La citation domine sa légende : en héritant de .temoignage (1.9rem) elle
   passait SOUS le figcaption (--fs-note), hiérarchie inversée. */
.trois .temoignage blockquote { font-size: 3rem; line-height: 1.4; }
.trois .temoignage figcaption { font-size: 2.3rem; line-height: 1.45; }
@media (max-width: 1100px) { .temoignages-grille.trois { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .temoignages-grille.trois { grid-template-columns: minmax(0, 1fr); } }
/* Les 3rem/2.3rem sont calibrés desktop : sur 390 px la légende passait
   au-dessus du corps de page (22,7 px contre 17 px). */
@media (max-width: 767px) {
  .trois .temoignage blockquote { font-size: 2.4rem; }
  .trois .temoignage figcaption { font-size: var(--fs-note); }
}

/* Le relevé de source, sous le titre de section. */
.avis-source { grid-column: contenu-deb / span 10; margin-top: 2.4rem; }

/* ── Les emplacements à remplir EN DIRECT avec Simon ──
   Bordure pointillée + mention visible : impossible de les confondre
   avec du contenu réel, impossible de les publier par accident. */
.temoignage-vide { border-style: dashed; background: transparent; }
.temoignage-vide blockquote { color: var(--note); font-style: italic; }
.a-remplir {
  display: block; margin-top: 1.2rem;
  font-family: var(--police-mono); font-size: var(--fs-badge);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--sable);
}
.nom-vide {
  display: inline-block; min-width: 16rem;
  border-bottom: var(--bord-1) dashed var(--bord-fort);
}

/* Emplacement d'image : la même boîte que .srv-media / .equipement-media,
   en pointillé, avec sa mention au centre. */
.media-vide {
  display: grid; place-items: center; text-align: center; padding: 2rem;
  background: var(--glace-2);
  border: var(--bord-1) dashed var(--bord-fort);
  font-family: var(--police-mono); font-size: var(--fs-note); color: var(--note);
}

/* Le portrait : un vrai format portrait, pas une demi-page. */
#apropos .srv-media { max-width: 42rem; }

/* Les événements de donation : palier surélevé, comme #equipement. */
#donations { background: var(--glace); }
.don-titre {
  display: block; margin-bottom: 0.8rem;
  font-family: var(--police-titre); text-transform: uppercase;
  font-size: 2.4rem; line-height: 1.2; color: var(--encre);
}
