/* ═══ base.css ═══ */
/* ═══════════════════════════════════════════════════════════════
   THOMAX — Système v4
   Direction relevée sur clickway.fr, l'autre agence de Thomas, et
   adaptée à Thomax Studio.

   Rien ici n'est estimé : la palette, les corps de texte, les rayons
   et la largeur du conteneur ont été mesurés dans un navigateur sur
   le site de référence, page entière déroulée. Un système reconstruit
   de mémoire ressemble au modèle sans jamais l'égaler, parce que ce
   qui fait l'accord — un fond crème plutôt que blanc, un or terne
   plutôt que vif, un rayon de 10 px plutôt que 12 — ne se retient pas
   à l'œil.

     · fond           #FFFDF7   crème chaud, jamais blanc pur
     · noir           #000000   les blocs pleins
     · noir-2         #101010   les cartes dans un bloc noir
     · noir-3         #171717   le pied
     · or             #D1A326   l'accent unique
     · conteneur      1200 px, centré
     · typographie    Codec Pro — Light 200, Regular 400,
                      Bold 500, Heavy 700
   ═══════════════════════════════════════════════════════════════ */

/* ─── Les fontes ───
   Codec Pro (Zetafonts). Les fichiers sont ceux servis par le site de
   référence ; la licence doit couvrir thomax-studio.fr avant toute
   mise en ligne. */
/* Questrial ne sert qu'au mot du logo. C'est la fonte du logo réel,
   relevée sur thomax-studio.fr ; la composer autrement donnerait un
   autre logo. */
@font-face {
  font-family: 'Questrial';
  src: url('../../assets/fontes/questrial.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}

@font-face {
  font-family: 'Codec Pro';
  src: url('../../assets/fontes/codec/codec-extralight.woff2') format('woff2');
  font-weight: 100 250; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Codec Pro';
  src: url('../../assets/fontes/codec/codec-light.woff2') format('woff2');
  font-weight: 251 350; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Codec Pro';
  src: url('../../assets/fontes/codec/codec-regular.woff2') format('woff2');
  font-weight: 351 450; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Codec Pro';
  src: url('../../assets/fontes/codec/codec-bold.woff2') format('woff2');
  font-weight: 451 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Codec Pro';
  src: url('../../assets/fontes/codec/codec-heavy.woff2') format('woff2');
  font-weight: 601 900; font-style: normal; font-display: swap;
}

:root {
  /* ═══ Couleurs ═══ */
  --fond:       #FFFDF7;
  --fond-2:     #F4F4F4;
  --fond-3:     #F2F2F2;
  --noir:       #000000;
  --noir-2:     #101010;
  --noir-3:     #171717;

  --encre:      #000000;
  --encre-2:    #222222;
  --encre-3:    #5A5A5A;   /* 6,78:1 sur le crème */
  --sur-noir:   #FFFFFF;
  --sur-noir-2: rgba(255, 255, 255, 0.81);
  --sur-noir-3: rgba(255, 255, 255, 0.55);

  /* TROIS ORS, PARCE QU'UN SEUL NE PEUT PAS TOUT FAIRE.

     Le modèle compose ses mots dorés en #D1A326 sur le crème : c'est
     2,3:1, mesuré — sous le seuil de 3:1 que le WCAG demande même
     pour du très grand texte. Or ce site publie ses propres articles
     sur l'accessibilité et sortait à 100 sur l'audit : reprendre la
     valeur telle quelle, ce serait recopier un défaut.

     L'écart à l'œil est d'un demi-ton. Les trois valeurs sont
     mesurées sur le crème #FFFDF7 :
       · --or          2,30:1  décor seul, et texte sur fond noir (8,98:1)
       · --or-titre    3,58:1  les mots dorés des grands titres
       · --or-lisible  4,92:1  l'or à taille de texte courant */
  --or:         #D1A326;
  --or-titre:   #A8801A;
  --or-lisible: #8A6B12;
  --or-clair:   #FFEEBA;

  /* LE FOND D'UNE CARTE EST UN JETON, PAS UNE COULEUR.

     Écrit « blanc » en dur, il restait blanc à l'intérieur d'un pavé
     noir — où l'encre, elle, avait basculé en clair. Résultat : du
     texte blanc sur une carte blanche, sur soixante pages, et l'audit
     comptait sept cent soixante défauts de contraste dont c'était la
     seule et même cause. */
  --carte:      #FFFFFF;

  /* Le vert des plateformes d'avis. Deux valeurs, comme l'or : le
     foncé mesure 5,35:1 sur blanc mais tombe à 3,56 sur le charbon
     des cartes sombres — sous le seuil pour du 11,5 px. Le clair y
     remonte à 8,27. */
  --vert-avis:  #0A7A54;

  --trait:      rgba(0, 0, 0, 0.10);
  --trait-fin:  rgba(0, 0, 0, 0.06);
  --trait-nuit: rgba(255, 255, 255, 0.14);

  /* ═══ Typographie ═══ */
  --police: 'Codec Pro', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --t1: clamp(2.4rem, 5vw, 4.375rem);   /* 70 px */
  --t2: clamp(1.9rem, 3.4vw, 3.125rem); /* 50 px */
  --t3: clamp(1.35rem, 2.1vw, 2.0625rem); /* 33 px */
  --t4: 1.75rem;    /* 28 */
  --t5: 1.4375rem;  /* 23 */
  --lead: 1.3125rem;/* 21 */
  --p:   1.125rem;  /* 18 */
  --p-2: 1rem;      /* 16 */
  --p-3: 0.9375rem; /* 15 */
  --p-4: 0.875rem;  /* 14 */
  --p-5: 0.8125rem; /* 13 */
  --micro: 0.625rem;/* 10 */

  /* ═══ Rayons — les six valeurs relevées ═══ */
  --r1: 8px;  --r2: 10px; --r3: 16px;
  --r4: 22px; --r5: 30px; --r6: 35px; --r7: 80px;

  /* ═══ Espaces ═══ */
  --e1: 0.25rem; --e2: 0.5rem;  --e3: 0.75rem; --e4: 1rem;
  --e5: 1.5rem;  --e6: 2rem;    --e7: 3rem;    --e8: 4rem;
  --e9: 6rem;    --e10: 8rem;

  --conteneur: 1200px;
  --gouttiere: 24px;

  /* ═══ Mouvement ═══
     Le ressort relevé sur le site de référence : la moitié du chemin
     en 17 % du temps, quatre-vingt-dix pour cent en 43 %, puis un
     long repos. Aucune courbe de Bézier ne dit cela. */
  --ressort: linear(
    0, 0.009 1.4%, 0.034 2.9%, 0.069 4.3%, 0.111 5.8%, 0.158 7.2%,
    0.208 8.7%, 0.259 10.1%, 0.309 11.6%, 0.358 13%, 0.406 14.5%,
    0.452 15.9%, 0.496 17.4%, 0.537 18.8%, 0.576 20.3%, 0.613 21.7%,
    0.647 23.2%, 0.679 24.6%, 0.709 26.1%, 0.737 27.5%, 0.762 29%,
    0.786 30.4%, 0.808 31.9%, 0.828 33.3%, 0.846 34.8%, 0.863 36.2%,
    0.878 37.7%, 0.892 39.1%, 0.905 40.6%, 0.916 42%, 0.927 43.5%,
    0.936 44.9%, 0.945 46.4%, 0.952 47.8%, 0.959 49.3%, 0.966 50.7%,
    0.971 52.2%, 0.976 53.6%, 0.98 55.1%, 0.984 56.5%, 0.987 58%,
    0.99 59.4%, 0.992 60.9%, 0.994 62.3%, 0.996 63.8%, 0.997 65.2%,
    0.998 66.7%, 0.999 68.1%, 1 69.6%, 1 71%, 1 72.5%, 1 73.9%,
    1 75.4%, 1 76.8%, 1 78.3%, 1 100%
  );
  --net:   180ms;
  --pose:  320ms;
  --ample: 640ms;
}

/* ═══ Remise à zéro ═══ */
*, *::before, *::after { box-sizing: border-box; }

/* `[hidden]` doit gagner contre nos propres règles d'affichage.

   La règle du navigateur, `[hidden] { display: none }`, a la
   spécificité d'un attribut : n'importe quelle règle de classe la
   bat. `.tiroir { display: grid }` l'a battue, et le menu de
   téléphone s'affichait par-dessus la moitié droite de chaque page,
   sur trente-cinq pages, y compris sur grand écran. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  /* PAS DE `scroll-behavior: smooth` ICI.

     Le défilement lissé est tenu par Lenis, qui écrit la position à
     chaque image. Avec `smooth`, le navigateur transforme CHACUNE de
     ces écritures en une animation native qui vise l'ancienne valeur :
     les deux se battent, et le défilement s'arrête presque. Mesuré :
     vingt-six crans de molette faisaient avancer la page de sept cent
     quinze pixels au lieu de sept mille huit cents.

     `overflow-x: clip` et non `hidden` : `hidden` fait de l'élément un
     conteneur de défilement, ce qui donne une seconde boîte qui défile
     sous celle que Lenis pilote. `clip` rogne sans rien créer. */
  overflow-x: clip;
}
@media (prefers-reduced-motion: reduce) {
  /* Sans moteur de lissage, on rend le défilement doux au navigateur. */
  html { scroll-behavior: smooth; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--fond);
  color: var(--encre);
  font-family: var(--police);
  font-size: var(--p-2);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Une adresse électronique ou une URL sans espace ne se coupe pas
     toute seule : sur un téléphone, elle sort du cadre. */
  overflow-wrap: break-word;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.02em;
}
h1 { font-size: var(--t1); }
h2 { font-size: var(--t2); }
h3 { font-size: var(--t3); }
h4 { font-size: var(--t4); }
h5 { font-size: var(--t5); line-height: 1.2; }
p  { margin: 0; }
/* Le navigateur pose 40 px de marge horizontale sur `blockquote` et
   sur `figure`. Dans une carte de 280 px, cela ne laisse que 200 px
   au texte : les avis se composaient sur trois mots par ligne. */
blockquote, figure, dl, dd { margin: 0; }
/* `height: auto` autant que `max-width`. Sans lui, une image portant
   `width="1600" height="900"` garde ses 900 pixels de haut pendant que
   sa largeur se réduit : elle s'étire, et l'audit la signale comme
   démesurée — à juste titre. Les vues qui recadrent posent leur
   propre hauteur et l'emportent par spécificité. */
img, svg, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

:focus-visible {
  outline: 2px solid var(--or-lisible);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ═══ Le conteneur ═══
   Mille deux cents pixels, centrés, avec une gouttière qui ne tombe
   jamais à zéro : c'est la mesure relevée sur le site de référence,
   et c'est ce qui donne à toutes les sections leur alignement commun. */
.cadre {
  width: 100%;
  max-width: calc(var(--conteneur) + var(--gouttiere) * 2);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

/* ═══ Le lien d'évitement ═══ */
.evitement {
  position: fixed;
  top: var(--e4);
  left: 50%;
  z-index: 200;
  padding: var(--e3) var(--e5);
  background: var(--noir);
  color: var(--sur-noir);
  border-radius: var(--r2);
  font-size: var(--p-4);
  transform: translate(-50%, -200%);
  transition: transform var(--pose) var(--ressort);
}
.evitement:focus { transform: translate(-50%, 0); }


/* ═══ chrome.css ═══ */
/* ═══════════════════════════════════════════════════════════════
   LE CHROME — barre du haut, pied de page
   ═══════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────
   LA BARRE

   Elle ne tient pas dans le conteneur de 1200 px : le logo va
   chercher le bord gauche, le bouton le bord droit, et la navigation
   reste centrée sur la page. C'est ce décrochage qui fait qu'on la
   lit comme un bandeau et non comme une première section.
   ───────────────────────────────────────────────────────────── */
.barre {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 90;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--e5);
  padding: 14px 44px;
  transition: background var(--pose) ease, backdrop-filter var(--pose) ease,
              box-shadow var(--pose) ease, padding var(--pose) var(--ressort);
}
/* Au défilement, la barre se pose sur un voile flouté : sans cela,
   les titres noirs passent derrière les liens noirs et plus rien
   n'est lisible. */
.barre.est-posee {
  padding-block: 10px;
  background: rgba(255, 253, 247, 0.82);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  box-shadow: 0 1px 0 var(--trait-fin);
}

.marque {
  display: inline-grid;
  justify-items: start;
  gap: 2px;
}
.marque-logo { width: 148px; height: 32px; display: block; overflow: visible; }
/* LA ROTATION DE 45° EST ÉCRITE ICI, PAS DANS LE HTML.

   Le SVG d'origine la porte en attribut : `transform="rotate(45 12
   12)"`. Dès qu'on ajoute `transform-box: fill-box` pour pouvoir
   l'animer, le navigateur RECENTRE aussi cette rotation sur la boîte
   de remplissage — le losange se décalait de six pixels vers la
   droite et venait manger le T de THOMAX. Une propriété CSS et un
   attribut de présentation ne se composent pas : la première remplace
   le second. On met donc tout du même côté. */
.marque-losange {
  stroke: #0A0A0A;
  transform-box: fill-box;
  transform-origin: 50% 50%;
  transform: rotate(45deg);
  transition: transform 900ms var(--ressort), stroke var(--pose) ease;
}
.marque-etincelle {
  fill: #9A7820;
  transform-box: fill-box;
  transform-origin: 50% 80%;
  transition: transform 700ms var(--ressort), fill var(--pose) ease;
}
.marque:hover .marque-losange { transform: rotate(135deg); }
.marque:hover .marque-etincelle { transform: translateY(-12%) scale(1.12); }
.marque-mot > tspan, .marque:hover .marque-mot { transition: fill var(--pose) ease; }
@media (prefers-reduced-motion: reduce) {
  .marque-losange, .marque-etincelle { transition: none; }
  .marque-losange { transform: rotate(45deg); }
  .marque:hover .marque-losange { transform: rotate(45deg); }
  .marque:hover .marque-etincelle { transform: none; }
}
.marque-mot { fill: #0A0A0A; font-family: 'Questrial', system-ui, sans-serif; }

/* La ligne de lieu fait partie du nom complet : « Thomax Studio ·
   Monaco · Paris ». La retirer de la barre revient à afficher un
   autre logo que celui de la marque. Elle s'aligne sous le mot, donc
   après la largeur du losange. */
.marque-lieu {
  padding-left: 32px;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.19em;
  color: var(--encre-3);
  line-height: 1;
}

.barre-nav {
  display: flex;
  align-items: center;
  gap: var(--e6);
}
.barre-nav a {
  font-size: var(--p-4);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--encre-3);
  transition: color var(--net) ease;
}
.barre-nav a:hover, .barre-nav a[aria-current] { color: var(--encre); }

.barre-droite {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--e5);
}
.barre-lien-client {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--p-3);
  font-weight: 500;
  white-space: nowrap;
}

/* ─── Le sélecteur de langue ───
   Une pastille d'or qui glisse sous le code actif. Le mot couvert
   passe en noir : sur l'or, c'est le seul contraste qui tienne le
   ratio AA à cette taille de texte (10 px, donc pas de tolérance).

   `data-i18n-skip` est posé sur le bouton dans le gabarit : sans lui
   le moteur traduirait « FR » / « EN » eux-mêmes, et le bouton
   clignoterait à chaque bascule. */
.lang-toggle {
  --piste: 66px;
  flex: none;
  width: var(--piste);
  height: 28px;
  padding: 0;
  border: 1px solid rgba(0, 0, 0, 0.20);
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
  transition: border-color var(--pose) ease;
}
.lang-toggle:hover { border-color: rgba(0, 0, 0, 0.42); }
.lang-toggle:focus-visible { outline: 2px solid var(--or-lisible); outline-offset: 2px; }

.lang-toggle-track {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  height: 100%;
}
.lang-toggle-pastille {
  position: absolute;
  top: 2px;
  left: 2px;
  width: calc(50% - 2px);
  height: calc(100% - 4px);
  border-radius: 999px;
  background: var(--or);
  transition: transform 520ms var(--ressort);
}
.lang-toggle-track.is-en .lang-toggle-pastille { transform: translateX(100%); }

.lang-toggle-mot {
  position: relative;
  z-index: 1;
  font-family: 'Codec Pro', system-ui, sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-align: center;
  color: var(--encre-3);
  transition: color var(--pose) ease;
}
/* Le mot sous la pastille : noir sur or. */
.lang-toggle-track:not(.is-en) .lang-toggle-mot:first-of-type,
.lang-toggle-track.is-en     .lang-toggle-mot:last-of-type { color: #0A0A0A; }

/* Dans le tiroir, la pastille se pose sur un fond déjà sombre. */
.lang-toggle--tiroir { --piste: 76px; height: 32px; border-color: rgba(0, 0, 0, 0.24); }
.lang-toggle--tiroir .lang-toggle-mot { font-size: 11px; }

/* Sur l'espace client, pas de barre : le sélecteur se pose lui-même. */
.lang-toggle--porte {
  position: fixed;
  top: 22px;
  right: 22px;
  z-index: 40;
  background: var(--carte);
}

@media (prefers-reduced-motion: reduce) {
  .lang-toggle-pastille { transition: none; }
}

/* L'ESPACE CLIENT SE RÉDUIT À SON SIGNE.

   La barre portait quatre éléments à droite — audit, espace client,
   bouton d'appel, WhatsApp — et commençait à ressembler à une barre
   d'outils. L'espace client ne s'adresse qu'à ceux qui l'ont déjà
   utilisé : ils reconnaissent le signe, et les autres n'ont rien à y
   faire. Le nom reste dans le `title` et l'`aria-label`, donc au
   survol comme au lecteur d'écran — l'icône seule ne se devine pas. */
.barre-signe {
  width: 38px; height: 38px;
  flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--trait);
  color: var(--encre-2);
  transition: background var(--pose) ease, color var(--pose) ease, transform var(--pose) var(--ressort);
}
.barre-signe svg { width: 18px; height: 18px; }
.barre-signe:hover {
  background: var(--noir);
  color: var(--sur-noir);
  border-color: var(--noir);
  transform: translateY(-2px);
}


/* ─── Le bouton noir, et son texte qui roule ───
   Au survol, le libellé monte d'une hauteur de ligne et sa copie
   arrive par le bas. L'effet est écrit en CSS pur : deux exemplaires
   du texte dans une fenêtre à hauteur fixe, et une seule
   transformation. Aucun JavaScript, donc rien à réparer le jour où
   le moteur d'animation change. */
.bouton {
  --fond-bouton: var(--noir);
  --encre-bouton: var(--sur-noir);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 18px;
  border-radius: var(--r2);
  background: var(--fond-bouton);
  color: var(--encre-bouton);
  /* Le trait tireté autour du bouton, relevé sur le modèle. C'est lui
     qui donne aux deux boutons du premier écran leur air de vignette
     découpée.

     Par défaut il est CLAIR, parce que le bouton par défaut est noir :
     un tiret sombre sur un fond noir ne se voit pas, et c'est ce que
     j'avais laissé. Les variantes claires le repassent en sombre. */
  border: 1px dashed var(--trait-bouton, rgba(255, 255, 255, 0.45));
  /* Six couches d'ombre plutôt qu'une : c'est ce que pose le modèle,
     et c'est ce qui fait qu'un bouton posé sur du crème a l'air posé
     dessus et non collé dedans. */
  box-shadow:
    0 0.7px 0.7px -0.3px rgba(16, 49, 77, 0.05),
    0 1.8px 1.8px -0.6px rgba(16, 49, 77, 0.06),
    0 3.6px 3.6px -0.9px rgba(16, 49, 77, 0.06),
    0 6.9px 6.9px -1.2px rgba(16, 49, 77, 0.06),
    0 13.6px 13.6px -1.5px rgba(16, 49, 77, 0.07),
    0 30px 30px -1.8px rgba(16, 49, 77, 0.10);
  font-size: var(--p-5);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  transition: transform var(--pose) var(--ressort), box-shadow var(--pose) ease;
}
.bouton:hover { transform: translateY(-2px); }
.bouton:active { transform: translateY(0); }

.bouton-clair { --fond-bouton: var(--sur-noir); --encre-bouton: var(--noir); --trait-bouton: rgba(0, 0, 0, 0.22); }
.bouton-or    { --fond-bouton: var(--or);       --encre-bouton: var(--noir); --trait-bouton: rgba(0, 0, 0, 0.30); }
.bouton-fin {
  --fond-bouton: var(--carte);
  --encre-bouton: var(--encre);
  --trait-bouton: rgba(0, 0, 0, 0.22);
}

.roule {
  display: block;
  overflow: hidden;
  height: 1em;
  line-height: 1;
}
.roule > span {
  display: block;
  transition: transform var(--ample) var(--ressort);
}
.bouton:hover .roule > span { transform: translateY(-1em); }
.roule > span > span { display: block; height: 1em; }

.bouton-fleche {
  flex: none;
  width: 12px; height: 12px;
  transition: transform var(--pose) var(--ressort);
}
.bouton:hover .bouton-fleche { transform: translate(2px, -2px); }

/* ─── La bulle WhatsApp, en bas à droite ─── */
.bulle {
  position: fixed;
  right: 24px; bottom: 24px;
  z-index: 80;
  width: 56px; height: 56px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: #25D366;
  color: #fff;
  /* L'anneau blanc : sur le modèle, la pastille est détourée d'un
     liseré clair qui la détache de tout ce qui passe dessous. */
  border: 3px solid #fff;
  box-shadow: 0 10px 28px -8px rgba(0, 0, 0, 0.35);
  transition: transform var(--pose) var(--ressort);
}
.bulle:hover { transform: scale(1.08); }
.bulle svg { width: 30px; height: 30px; }

/* ─────────────────────────────────────────────────────────────
   LE PIED — bloc noir, horloges, et la marque en très grand
   ───────────────────────────────────────────────────────────── */
.pied {
  position: relative;
  margin-top: var(--e9);
  padding: var(--e9) 0 0;
  background: var(--noir-3);
  color: var(--sur-noir);
  border-radius: var(--r5) var(--r5) 0 0;
  overflow: hidden;
}
.pied-haut {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: var(--e8);
  align-items: start;
}
.pied-marque { display: grid; justify-items: start; gap: 4px; }
.marque-logo--pied { width: 190px; height: 41px; }
.marque-logo--pied .marque-losange { stroke: #FFFFFF; }
.marque-logo--pied .marque-mot { fill: #FFFFFF; }
.marque-logo--pied .marque-etincelle { fill: var(--or); }
.pied-lieu {
  padding-left: 41px;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sur-noir-3);
}

.pied-mot { margin-top: var(--e4); color: var(--sur-noir-2); font-size: var(--p-4); max-width: 34ch; }
/* Un filet au-dessus du bloc d'adresses, comme chez le modèle : il
   sépare la marque des coordonnées sans qu'il faille un titre. */
.pied-adresses {
  margin-top: var(--e5);
  padding-top: var(--e5);
  border-top: 1px solid var(--trait-nuit);
  display: grid;
  gap: 10px;
  color: var(--sur-noir-2);
  font-size: var(--p-4);
}
.pied-ligne { display: flex; align-items: center; gap: 12px; }
/* L'icône ne rétrécit pas quand l'adresse passe sur deux lignes, et
   ne s'étire pas non plus : c'est un repère, pas une décoration qui
   suivrait le texte. */
.pied-icone { width: 19px; height: 19px; flex: none; color: var(--sur-noir); }
.pied-ligne a { border-bottom: 1px solid var(--trait-nuit); transition: border-color var(--net) ease; }
.pied-ligne a:hover { border-color: var(--sur-noir); }

.pied-horloges {
  display: flex;
  gap: var(--e7);
  justify-content: flex-end;
  flex-wrap: wrap;
}
.horloge-h {
  font-size: var(--t4);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.horloge-ville { display: block; margin-top: 2px; font-size: var(--p-4); }
.horloge-note { display: block; color: var(--sur-noir-3); font-size: var(--p-5); }

.pied-bas {
  margin-top: var(--e8);
  padding-block: var(--e5);
  border-top: 1px solid var(--trait-nuit);
  display: flex;
  flex-wrap: wrap;
  gap: var(--e3) var(--e6);
  align-items: center;
  justify-content: space-between;
  color: var(--sur-noir-3);
  font-size: var(--p-4);
}
.pied-legal { display: flex; flex-wrap: wrap; gap: var(--e5); }
.pied-legal a { transition: color var(--net) ease; }
.pied-legal a:hover { color: var(--sur-noir); }

/* La marque, en très grand, coupée par le bas du document. Elle ne
   se lit pas : elle signe. */
.pied-signature {
  display: block;
  width: 100%;
  margin-top: var(--e5);
  /* La signature reprend la composition du logo : Questrial en
     capitales espacées, et non la display du site. Écrite autrement,
     ce serait le nom de la marque sans être sa marque. */
  font-family: 'Questrial', system-ui, sans-serif;
  font-size: clamp(3rem, 13vw, 11.5rem);
  font-weight: 400;
  line-height: 0.9;
  letter-spacing: 0.06em;
  text-align: center;
  transform: translateY(0.16em);
  user-select: none;

  /* LE DÉGRADÉ D'OR DE LA MARQUE, ET UNE DISPARITION PAR LE BAS.

     Les quatre premiers arrêts sont ceux du logo — les mêmes valeurs
     que porte le losange dans assets/identity. Le cinquième descend
     vers le noir du pied : la signature ne s'arrête donc pas, elle
     s'éteint dans le bord de la page, et l'on ne voit plus la coupure
     franche que faisait le blanc.

     `color` est posé AVANT le découpage : si un navigateur ignore
     `background-clip: text`, il rend le mot en or plein au lieu de le
     rendre invisible. Une signature qui disparaît faute de support
     serait pire que pas de signature. */
  color: #E0BC6C;
  background-image: linear-gradient(180deg,
    #FFEFC2 0%, #F1D78F 22%, #E0BC6C 46%, #B89345 68%, #7E5D17 86%, #171717 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* Sans découpage sur le texte, on annule le remplissage transparent
   pour ne pas effacer le mot. */
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .pied-signature { background-image: none; -webkit-text-fill-color: currentColor; }
}

@media (max-width: 980px) {
  .barre { grid-template-columns: 1fr auto; padding-inline: 20px; gap: var(--e3); }
  .barre-nav { display: none; }
  /* Sur trois cent quatre-vingt-dix pixels, le bouton d'appel et le
     lien d'audit poussaient la barre à quatre cent soixante-sept :
     la page débordait horizontalement. Le tiroir les reprend tous
     les deux. */
  .barre-lien-client, .barre-signe, .barre-droite .bouton { display: none; }
  .marque-lieu { display: none; }
  .pied-haut { grid-template-columns: 1fr; gap: var(--e6); }
  .pied-horloges { justify-content: flex-start; gap: var(--e5); }
}

/* ─── Le tiroir de téléphone ─── */
.barre-gauche { display: flex; align-items: center; }
.barre-menu {
  display: none;
  width: 40px; height: 40px;
  border-radius: var(--r2);
  border: 1px solid var(--trait);
  place-items: center;
  gap: 5px;
  flex-direction: column;
}
.barre-menu span {
  display: block;
  width: 16px;
  height: 1.5px;
  background: var(--encre);
  transform-origin: 50% 50%;
  transition: transform 560ms var(--ressort), width 380ms var(--ressort);
}
/* Les deux barres se rejoignent en croix. Le rail fait 8 px de haut
   (deux traits de 1,5 et un intervalle de 5) : chaque centre est donc
   à 3,25 px du milieu, et c'est exactement ce qu'il faut rattraper
   pour que la croix se ferme sans décalage d'un demi-pixel. */
.barre-menu[aria-expanded="true"] span { width: 18px; }
.barre-menu[aria-expanded="true"] span:first-child { transform: translateY(3.25px) rotate(45deg); }
.barre-menu[aria-expanded="true"] span:last-child  { transform: translateY(-3.25px) rotate(-45deg); }
@media (max-width: 980px) { .barre-menu { display: flex; justify-content: center; } }

/* ─── L'OUVERTURE DU TIROIR ───

   Rien ne peut s'animer tant que l'élément porte `hidden` : la règle
   `[hidden] { display: none !important }` de base.css gagne contre
   tout. Le script retire donc l'attribut AVANT de poser la classe, et
   ne le remet qu'une fois le mouvement fini — sans quoi le panneau
   apparaîtrait d'un coup, exactement comme avant.

   Le mouvement se lit en trois temps : le panneau glisse, un filet
   d'or se trace le long de son bord, puis les liens montent l'un
   après l'autre. Les retards sont portés par `--d`, une seule valeur
   par ligne, que le losange et le texte partagent : les deux entrent
   ensemble au lieu de se courir après. */
.tiroir {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: 95;
  width: min(88vw, 380px);
  padding: 88px var(--e6) var(--e6);
  background: var(--fond);
  border-left: 1px solid var(--trait);
  display: grid;
  align-content: start;
  gap: var(--e2);
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform 620ms var(--ressort);
  will-change: transform;
}
.tiroir.est-ouvert { transform: translateX(0); }

/* Le filet d'or qui se trace du haut vers le bas, une fois le panneau
   presque en place. C'est la signature de la marque, reprise du
   dégradé du losange. */
.tiroir::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: linear-gradient(180deg, transparent, var(--or) 16%, var(--or) 84%, transparent);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 720ms var(--ressort) 90ms;
}
.tiroir.est-ouvert::before { transform: scaleY(1); }

.tiroir-lien {
  position: relative;
  padding: var(--e3) 0 var(--e3) 22px;
  font-size: var(--t5);
  border-bottom: 1px solid var(--trait-fin);
}
/* Le losange de la marque, en miniature, qui se pose devant le mot. */
.tiroir-lien::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 50%;
  width: 6px;
  height: 6px;
  margin-top: -3px;
  border: 1px solid var(--or);
  transform: rotate(0deg) scale(0);
  transition: transform 620ms var(--ressort) var(--d, 0ms);
}
.tiroir.est-ouvert .tiroir-lien::before { transform: rotate(45deg) scale(1); }

.tiroir-lien,
.tiroir-pied {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 420ms ease var(--d, 0ms),
              transform 560ms var(--ressort) var(--d, 0ms);
}
.tiroir.est-ouvert .tiroir-lien,
.tiroir.est-ouvert .tiroir-pied { opacity: 1; transform: none; }

/* Une cascade de 55 ms. Au-delà de la neuvième ligne on cesse de
   retarder : un menu plus long ne doit pas faire attendre son pied. */
.tiroir > :nth-child(1) { --d:  90ms; }
.tiroir > :nth-child(2) { --d: 145ms; }
.tiroir > :nth-child(3) { --d: 200ms; }
.tiroir > :nth-child(4) { --d: 255ms; }
.tiroir > :nth-child(5) { --d: 310ms; }
.tiroir > :nth-child(6) { --d: 365ms; }
.tiroir > :nth-child(7) { --d: 420ms; }
.tiroir > :nth-child(8) { --d: 475ms; }
.tiroir > :nth-child(n + 9) { --d: 530ms; }

/* À la fermeture, plus aucun retard : le tiroir doit partir d'un
   bloc. Une cascade inversée donne l'impression d'un panneau qui
   traîne. */
.tiroir:not(.est-ouvert) .tiroir-lien,
.tiroir:not(.est-ouvert) .tiroir-pied,
.tiroir:not(.est-ouvert) .tiroir-lien::before { transition-delay: 0ms; }

.tiroir-pied { margin-top: var(--e5); display: grid; gap: var(--e4); justify-items: start; }
.tiroir-pied p { font-size: var(--p-4); color: var(--encre-3); }

.voile-tiroir {
  position: fixed;
  inset: 0;
  z-index: 94;
  background: rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 420ms ease;
}
.voile-tiroir.est-ouvert { opacity: 1; }
.tiroir-ouvert body { overflow: hidden; }

/* LE BOUTON DOIT RESTER AU-DESSUS DU TIROIR.
   La barre est à 90, le tiroir à 95 : le panneau recouvrait donc le
   bouton. Il se changeait en croix — l'invitation la plus claire qui
   soit à le toucher pour fermer — et le geste ne faisait rien. Le
   défaut existait déjà, mais la croix le rendait trompeur.
   On ne remonte la barre que pendant l'ouverture : son empilement
   habituel avec le reste de la page n'est pas touché. */
.tiroir-ouvert .barre { z-index: 96; }

/* Le tiroir porte son propre sélecteur de langue, dans son pied.
   Depuis que la barre passe au-dessus, les deux s'affichaient côte à
   côte. L'en-tête d'un menu ouvert se réduit à deux choses : la
   marque, et la croix pour sortir. */
.tiroir-ouvert .barre .lang-toggle {
  opacity: 0;
  /* `visibility` et pas seulement `opacity` : un bouton transparent
     reste dans l'ordre de tabulation et dans l'arbre d'accessibilité.
     L'utilisateur au clavier atterrissait sur un contrôle qu'il ne
     voyait pas, et le lecteur d'écran l'annonçait deux fois puisque le
     tiroir porte le sien. La visibilité se transitionne après le fondu
     pour que la disparition reste douce. */
  visibility: hidden;
  transition: opacity 240ms ease, visibility 0s linear 240ms;
}

@media (prefers-reduced-motion: reduce) {
  .tiroir, .tiroir::before, .tiroir-lien, .tiroir-pied,
  .tiroir-lien::before, .voile-tiroir, .barre-menu span { transition: none; }
  .tiroir { transform: translateX(0); }
  .tiroir-lien, .tiroir-pied { opacity: 1; transform: none; }
}

.horloge { display: block; }


/* ═══════════════════════════════════════════════════════════════
   LE VOILE D'OUVERTURE

   Le modèle n'en a aucun : à deux cent cinquante millisecondes, sa
   page est déjà entièrement dessinée — vérifié en filmant l'arrivée
   image par image. Celui-ci est donc une addition, pas une copie, et
   il obéit à une règle : ne jamais faire attendre. Neuf cents
   millisecondes en tout, le temps que les fontes arrivent, et pas un
   dixième de plus.

   IL S'EFFACE SANS JAVASCRIPT. L'animation CSS le fait disparaître
   toute seule et lui retire les événements de pointeur à la fin. Un
   voile qui dépend d'un script pour se lever est un écran blanc en
   puissance : il suffit que le script ne charge pas, et le site
   n'existe plus. Le script, lui, ne sert qu'à l'ôter du document une
   fois l'affaire terminée.
   ═══════════════════════════════════════════════════════════════ */
.voile {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  background: var(--fond);
  animation: voile-partir 900ms var(--ressort) forwards;
}
@keyframes voile-partir {
  0%, 62%  { opacity: 1; }
  100%     { opacity: 0; visibility: hidden; pointer-events: none; }
}

.voile-logo { width: 210px; height: 45px; overflow: visible; }
.voile-losange {
  stroke: #0A0A0A;
  transform-box: fill-box;
  transform-origin: 50% 50%;
  /* Le trait se dessine : le contour d'un carré de 20 de côté fait
     quatre-vingts unités, on part donc d'un tiret de longueur nulle. */
  stroke-dasharray: 80;
  stroke-dashoffset: 80;
  animation: voile-tracer 620ms var(--ressort) forwards;
}
@keyframes voile-tracer {
  0%   { stroke-dashoffset: 80; transform: rotate(0deg); }
  100% { stroke-dashoffset: 0;  transform: rotate(45deg); }
}
.voile-etincelle {
  fill: #9A7820;
  transform-box: fill-box;
  transform-origin: 50% 100%;
  opacity: 0;
  animation: voile-etinceler 420ms var(--ressort) 300ms forwards;
}
@keyframes voile-etinceler {
  0%   { opacity: 0; transform: translateY(40%) scale(0.6); }
  100% { opacity: 1; transform: none; }
}
.voile-mot {
  fill: #0A0A0A;
  font-family: 'Questrial', system-ui, sans-serif;
  opacity: 0;
  animation: voile-mot 460ms var(--ressort) 260ms forwards;
}
@keyframes voile-mot {
  0%   { opacity: 0; transform: translateX(-6px); }
  100% { opacity: 1; transform: none; }
}

/* Le premier écran monte derrière le voile qui se lève. */
.js .ouverture > .cadre > * { animation: entrer 700ms var(--ressort) both; }
.js .ouverture > .cadre > *:nth-child(1) { animation-delay: 480ms; }
.js .ouverture > .cadre > *:nth-child(2) { animation-delay: 540ms; }
.js .ouverture > .cadre > *:nth-child(3) { animation-delay: 600ms; }
.js .ouverture > .cadre > *:nth-child(4) { animation-delay: 660ms; }
.js .ouverture > .cadre > *:nth-child(5) { animation-delay: 720ms; }
@keyframes entrer {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .voile { animation: voile-partir 1ms linear forwards; }
  .voile-losange { stroke-dashoffset: 0; transform: rotate(45deg); animation: none; }
  .voile-etincelle, .voile-mot { opacity: 1; animation: none; }
  .js .ouverture > .cadre > * { animation: none; }
}


/* ═══ sections.css ═══ */
/* ═══════════════════════════════════════════════════════════════
   LES SECTIONS
   L'ordre est celui du site de référence : ouverture, offres,
   projets, processus, clients, offre chiffrée, appel à l'action.
   ═══════════════════════════════════════════════════════════════ */

.plage { position: relative; padding-block: var(--e9); }
.plage-serree { padding-block: var(--e8); }
/* Une section qui enchaîne sans respiration sur celle du dessus. */
.plage-collee { padding-top: 0; }

/* Le bloc noir pleine largeur, aux angles très arrondis. C'est la
   figure la plus reconnaissable du modèle : le crème s'interrompt,
   un pavé noir prend toute la largeur moins la gouttière, et tout ce
   qu'il contient bascule en clair. */
.pave {
  --carte: var(--noir-2);
  --vert-avis: #22C286;
  --fond-reponse: rgba(209, 163, 38, 0.14);
  --encre: var(--sur-noir);
  --encre-2: var(--sur-noir-2);
  --encre-3: var(--sur-noir-2);
  --or-lisible: var(--or);
  --or-titre: var(--or);
  --trait: var(--trait-nuit);
  --trait-fin: var(--trait-nuit);
  background: var(--noir);
  color: var(--sur-noir);
  border-radius: var(--r5);
  padding: var(--e8) var(--e7);
}
.pave h1, .pave h2, .pave h3, .pave h4, .pave h5 { color: var(--sur-noir); }

/* La ligne de réassurance : trois têtes qui se chevauchent, les
   étoiles, puis le nombre. Le modèle la pose au-dessus de deux de ses
   titres, et c'est la première chose que l'œil rencontre. */
.pile-tetes { display: inline-flex; }
.pile-tete {
  width: 26px; height: 26px;
  margin-left: -8px;
  border-radius: 50%;
  border: 2px solid var(--fond);
  background: var(--noir-2);
  color: #fff;
  display: grid; place-items: center;
  font-size: 10px;
  font-weight: 500;
}
.pile-tete:first-child { margin-left: 0; background: var(--or); color: var(--noir); }
.pave .pile-tete { border-color: var(--noir); }
.eyebrow-signe { width: 12px; height: 12px; flex: none; color: var(--or-lisible); }

/* Le logo complet en surtitre, à la place du mot « thomax » composé
   dans la police du site. La rotation du losange vit en CSS — elle
   doit pouvoir s'animer ailleurs — et doit donc être redite ici. */
.eyebrow-logo { height: 21px; width: auto; display: block; overflow: visible; }
.eyebrow-losange {
  stroke: currentColor;
  transform-box: fill-box;
  transform-origin: 50% 50%;
  transform: rotate(45deg);
}
.eyebrow-etincelle { fill: var(--or-lisible); }
.eyebrow-mot { fill: currentColor; font-family: 'Questrial', system-ui, sans-serif; }
.pave .eyebrow-etincelle { fill: var(--or); }
.eyebrow-etoiles { display: inline-flex; gap: 2px; color: var(--or-lisible); }
.eyebrow-etoiles svg { width: 12px; height: 12px; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--p-4);
  color: var(--encre-3);
}
.pave .eyebrow { color: var(--sur-noir-3); }

/* ─────────────────────────────────────────────────────────────
   1. L'OUVERTURE
   ───────────────────────────────────────────────────────────── */
.ouverture {
  position: relative;
  padding-top: 150px;
  /* Rien sous la pile : la section suivante enchaîne au pixel. */
  padding-bottom: 0;
  text-align: center;
  overflow: hidden;
}
/* La lueur dorée derrière le titre. Un dégradé radial très étalé et
   très pâle : on ne doit pas le voir, on doit voir que le fond n'est
   pas plat. */
.ouverture::before {
  content: '';
  position: absolute;
  top: -20%; left: 50%;
  width: 1100px; height: 700px;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(255, 224, 138, 0.55) 0%, rgba(255, 224, 138, 0) 70%);
  pointer-events: none;
}
.ouverture > * { position: relative; }

/* ─── Les marques flottantes ───
   Le modèle pose deux petits objets de part et d'autre du titre : un
   curseur gris à gauche, un logo d'outil à droite. Ils ne disent
   rien, et c'est leur fonction — ils cassent la symétrie d'un premier
   écran entièrement centré, qui sans eux ressemble à une diapositive.
   Ils disparaissent sous mille pixels, où il n'y a plus de marge où
   les poser. */
.flottant {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  animation: flotter 6s ease-in-out infinite;
}
.flottant-curseur { top: 150px; left: 6%; width: 34px; color: #A9A9A9; }
.flottant-signe {
  top: 96px; right: 7%;
  width: 52px; height: 52px;
  display: grid; place-items: center;
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 14px 30px -16px rgba(0, 0, 0, 0.4);
  animation-delay: -3s;
}
.flottant-signe img { width: 26px; height: 26px; }
@keyframes flotter {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-12px) rotate(-3deg); }
}
@media (max-width: 1100px) { .flottant { display: none; } }
@media (prefers-reduced-motion: reduce) { .flottant { animation: none; } }

/* ─── La couronne de confiance ───
   Toutes les valeurs sont relevées au pixel sur le modèle, dans le
   navigateur : branches de 42 sur 42, badge de 74 sur 21, aucun
   espace entre eux — les branches touchent le badge. J'avais mis des
   branches de 30 et un badge de 128, soit l'inverse du rapport
   voulu : le badge écrasait la couronne au lieu d'être tenu par elle.

   Les branches sont en gris pâle et non en noir. Le fichier est une
   silhouette noire ; c'est l'opacité qui fait le gris, ce qui la rend
   juste sur le crème comme sur un fond sombre. */
.laurier {
  display: inline-flex;
  align-items: center;
  gap: 0;
  margin-bottom: var(--e5);
}
.laurier-feuille {
  width: 42px;
  height: 42px;
  object-fit: contain;
  opacity: 0.26;
}
.laurier-feuille--gauche { transform: scaleX(-1); }
.laurier-coeur { display: grid; gap: 4px; justify-items: center; }
.laurier-etoiles {
  display: inline-flex;
  gap: 3px;
  color: var(--encre);
  line-height: 1;
}
.laurier-etoiles svg { width: 11px; height: 11px; }
.laurier-badge { width: 74px; height: 21px; object-fit: contain; }

.ouverture-titre { max-width: 1040px; margin-inline: auto; line-height: 1.14; }
.ouverture-titre em { font-style: normal; color: var(--or-titre); }

/* ─── La fiche du mot qui tourne ───
   Relevée au pixel sur le modèle : traits de CINQ pixels (j'en avais
   mis deux, d'où l'impression de contour timide), rayon de 10,
   remplissage blanc, ombre douce et large, inclinaison de trois
   degrés exactement — `matrix(0.99863, -0.052336, …)` lue dans le
   navigateur — et un rembourrage de 10 sur 15.

   La largeur SUIT LE MOT. Sur le modèle, la fiche se resserre sur
   « boîtes » et s'élargit sur « agences » ; une largeur figée sur le
   mot le plus long laisse un grand vide blanc à droite des mots
   courts, et c'est ce vide qu'on remarque. */
.fiche {
  position: relative;
  display: inline-block;
  vertical-align: baseline;
  padding: 10px 15px;
  margin-inline: 0.08em;
  background: #fff;
  border: 5px dashed var(--or);
  border-radius: 10px;
  transform: rotate(-3deg);
  box-shadow: 0 1px 16px rgba(0, 0, 0, 0.25);
  /* La largeur est écrite par le module de mouvement, qui mesure le
     mot courant. La transition la rend continue. */
  width: var(--fiche-large, auto);
  transition: width 620ms var(--ressort);
}
.fiche-fenetre {
  display: block;
  height: 1em;
  overflow: hidden;
}
.fiche-piste { display: block; }
.fiche-mot {
  display: block;
  height: 1em;
  line-height: 1;
  white-space: nowrap;
  text-align: center;
  opacity: 0;
}

.ouverture-lead {
  margin: var(--e5) auto 0;
  max-width: 34em;
  font-size: var(--lead);
  color: var(--encre-2);
}
.ouverture-lead b { font-weight: 700; }

.duo-boutons {
  margin-top: var(--e6);
  display: flex;
  gap: var(--e3);
  justify-content: center;
  flex-wrap: wrap;
}

/* ─── Le tas d'écrans, sous les boutons ───
   Relevé au pixel sur le modèle, à 1440 de large. Cinq captures en
   PAYSAGE — non des cartes de couleur : ce qu'on prend pour du bleu
   ou du vert, ce sont les sites eux-mêmes — disposées en éventail
   très serré, presque superposées, dont on ne voit que la tranche.

     carte      taille     centre      y      rotation
     extrême   607×395    −89 px     +19     ∓1,72°
     proche    637×407    −43 px      +5     ∓1,15°
     centre    650×409      0         0        0

   J'avais d'abord fait un éventail large avec des cartes en portrait
   écartées de 280 pixels : la composition était juste dans l'esprit
   et fausse dans tous les nombres. C'est le chevauchement serré qui
   fait la pile ; écartées, les cartes redeviennent une rangée.

   Les tailles sont exprimées en fraction de la largeur du centre,
   pour que l'éventail se resserre proportionnellement sur un écran
   plus étroit. */
.tas {
  position: relative;
  --centre: min(650px, 45vw);
  margin-top: var(--e7);
  /* LA PILE EST COUPÉE, ET C'EST TOUT L'EFFET.

     Sur le modèle, le premier écran s'arrête à 720 pixels alors que
     la carte du centre commence à 568 et en fait 409 de haut : on
     n'en voit que cent cinquante-deux, soit trente-sept pour cent.
     Le pavé noir commence immédiatement après, sans un pixel de
     blanc entre les deux.

     J'affichais la pile entière puis laissais respirer avant la
     section suivante : la page perdait exactement ce qui fait
     descendre — une image commencée qu'on veut voir en entier. */
  height: calc(var(--centre) * 0.234);
  overflow: hidden;
}
.tas-carte {
  position: absolute;
  left: 50%;
  margin: 0;
  border-radius: 16px;
  overflow: hidden;
  background: var(--noir);
  box-shadow: 0 24px 50px -30px rgba(0, 0, 0, 0.45);
}
.tas-carte img { width: 100%; height: 100%; object-fit: cover; object-position: top; }

.tas-centre {
  z-index: 3;
  width: var(--centre);
  height: calc(var(--centre) * 0.629);
  top: 0;
  transform: translateX(-50%);
}
.tas-pres {
  z-index: 2;
  width: calc(var(--centre) * 0.98);
  height: calc(var(--centre) * 0.626);
  top: calc(var(--centre) * 0.0077);
}
.tas-loin {
  z-index: 1;
  width: calc(var(--centre) * 0.934);
  height: calc(var(--centre) * 0.608);
  top: calc(var(--centre) * 0.0292);
}
.tas-gauche.tas-pres { transform: translateX(calc(-50% - var(--centre) * 0.0654)) rotate(-1.15deg); }
.tas-gauche.tas-loin { transform: translateX(calc(-50% - var(--centre) * 0.1392)) rotate(-1.72deg); }
.tas-droite.tas-pres { transform: translateX(calc(-50% + var(--centre) * 0.0669)) rotate(1.15deg); }
.tas-droite.tas-loin { transform: translateX(calc(-50% + var(--centre) * 0.1362)) rotate(1.72deg); }

@media (max-width: 860px) {
  .tas { --centre: 82vw; }
}

/* ─────────────────────────────────────────────────────────────
   2. LES OFFRES — dans le pavé noir
   ───────────────────────────────────────────────────────────── */
.confiance-mot {
  text-align: center;
  color: var(--sur-noir-3);
  font-size: var(--p-3);
}

/* ─── Le ruban de clients ───
   Mesuré sur le modèle : cinq mille deux cents pixels changent toutes
   les 260 ms sur cette bande, régulièrement, sans qu'on touche à
   rien — c'est un défilement continu, pas une rangée immobile. Les
   noms sont écrits deux fois dans le HTML : la piste se translate de
   la moitié de sa largeur, et la seconde moitié reprend exactement là
   où la première s'arrête. Sans le doublon, la boucle saute. */
.ruban {
  margin-top: var(--e4);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.ruban-piste {
  display: flex;
  align-items: center;
  gap: var(--e8);
  width: max-content;
  animation: ruban-defile 42s linear infinite;
}
.ruban:hover .ruban-piste { animation-play-state: paused; }
@keyframes ruban-defile { to { transform: translateX(-50%); } }
/* LES VRAIS LOGOS, PAS LEURS NOMS ÉCRITS.

   Ils viennent des sites eux-mêmes. Sur un fond noir, ils sont
   ramenés au blanc par filtre : les logos des clients ont chacun
   leur couleur, et six couleurs différentes sur une même bande
   donnent une guirlande, pas une preuve. Le filtre garde la FORME,
   qui est ce qu'on reconnaît. */
.ruban-logo {
  height: 34px;
  width: auto;
  flex: none;
  object-fit: contain;
  filter: brightness(0) invert(1);
  opacity: 0.62;
  transition: opacity var(--pose) ease;
}
.ruban:hover .ruban-logo { opacity: 0.85; }
@media (prefers-reduced-motion: reduce) { .ruban-piste { animation: none; } }

.pave-titre {
  margin: var(--e8) auto 0;
  max-width: 24ch;
  text-align: center;
  font-size: var(--t2);
}
.pave-titre em { font-style: normal; color: var(--sur-noir); text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 2px; }

.offres {
  margin-top: var(--e7);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e5);
}
.offre-carte {
  position: relative;
  display: grid;
  align-content: end;
  min-height: 480px;
  padding: var(--e6);
  border-radius: var(--r4);
  background: var(--noir-2);
  overflow: hidden;
  isolation: isolate;
}
.offre-image {
  position: absolute;
  inset: 0 0 auto 0;
  height: 58%;
  z-index: -2;
}
.offre-image img { width: 100%; height: 100%; object-fit: cover; }
/* Le fondu qui rattache l'image au fond de la carte. Sans lui, la
   photo se termine par une arête nette au milieu de la carte. */
.offre-carte::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg,
    rgba(16,16,16,0.10) 0%, rgba(16,16,16,0.45) 26%,
    rgba(16,16,16,0.92) 46%, var(--noir-2) 56%);
}
.offre-nom { font-size: var(--t3); }
.offre-nom span { color: var(--sur-noir-3); }
.offre-quoi { margin-top: var(--e3); color: var(--sur-noir-2); font-size: var(--p-2); max-width: 42ch; }
.offre-carte .bouton { margin-top: var(--e5); justify-self: start; }

/* La lueur d'or au bord de la seconde carte, relevée sur le modèle. */
.offre-carte.est-doree { box-shadow: 0 0 60px -12px rgba(209, 163, 38, 0.55); }

/* Les trois garanties, séparées par des filets verticaux. */
.gages {
  margin-top: var(--e8);
  padding-top: var(--e7);
  border-top: 1px solid var(--trait-nuit);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.gage { padding-inline: var(--e6); border-left: 1px solid var(--trait-nuit); }
.gage:first-child { padding-left: 0; border-left: 0; }
/* Les pictogrammes remplacent les caractères typographiques qui
   tenaient ce rôle. Un glyphe comme « ⟲ » n'existe pas dans toutes
   les polices, se dessine autrement d'un système à l'autre, et se lit
   à voix haute par les lecteurs d'écran sous un nom qui n'a rien à
   voir. Un tracé ne change pas. */
.gage-signe { display: block; width: 26px; height: 26px; color: var(--or); }
.gage-signe svg { width: 100%; height: 100%; }
.gage-nom { margin-top: var(--e4); font-size: var(--t5); }
.gage-quoi { margin-top: var(--e3); color: var(--sur-noir-2); font-size: var(--p-4); }
/* Le décalage vertical d'une colonne sur deux : le modèle ne les
   aligne pas, et c'est ce qui empêche le bloc de ressembler à un
   tableau. */
.gage:nth-child(2) { transform: translateY(18px); }

.parole-vedette {
  margin-top: var(--e8);
  padding-top: var(--e7);
  border-top: 1px solid var(--trait-nuit);
  display: flex;
  align-items: center;
  gap: var(--e7);
  flex-wrap: wrap;
}
/* Le vrai logo, dans sa version blanche servie par le site du client
   — le pavé est noir, c'est celle qui convient. */
.parole-logo { height: 44px; width: auto; flex: none; object-fit: contain; }
.parole-vedette blockquote { margin: 0; font-size: var(--t3); max-width: 22ch; }
.parole-vedette figcaption { margin-top: var(--e3); font-size: var(--p-5); color: var(--sur-noir-3); text-transform: uppercase; letter-spacing: 0.08em; }

/* ─────────────────────────────────────────────────────────────
   3. LES PROJETS
   ───────────────────────────────────────────────────────────── */
.section-tete { text-align: center; display: grid; gap: var(--e4); justify-items: center; }
.section-tete h2 { font-size: var(--t2); }
.section-lead {
  max-width: 58ch;
  font-size: var(--p-3);
  line-height: 1.6;
  color: var(--encre-3);
}

.projets {
  margin-top: var(--e7);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e5);
}
/* LE SURVOL AGRANDIT LA CARTE, relevé sur le modèle : 590×397 au
   repos, 615×420 sous le curseur — quatre pour cent de plus. Rien
   d'autre ne bouge : pas de zoom dans l'image, pas de voile, pas de
   libellé qui apparaît.

   Lui, anime la largeur et la hauteur ; on passe par `scale`, qui
   donne la même image sans faire recalculer la mise en page à chaque
   image — et qui laisse donc la carte déborder sur ses voisines au
   lieu de les pousser. D'où le `z-index` : sans lui, la carte
   agrandie passerait SOUS celle d'à côté. */
.projet {
  display: grid;
  position: relative;
  border-radius: var(--r4);
  overflow: hidden;
  background: var(--fond-3);
  border: 1px solid var(--trait-fin);
  transition: transform 420ms var(--ressort), box-shadow 420ms ease;
}
.projet:hover, .projet:focus-visible {
  transform: scale(1.042);
  z-index: 2;
  box-shadow: 0 30px 60px -34px rgba(0, 0, 0, 0.45);
}
.projet-vue { aspect-ratio: 16 / 10; overflow: hidden; background: var(--noir); }
.projet-vue img { width: 100%; height: 100%; object-fit: cover; }
@media (prefers-reduced-motion: reduce) {
  .projet { transition: none; }
  .projet:hover, .projet:focus-visible { transform: none; }
}
.projet-dire { padding: var(--e5) var(--e5) var(--e6); }
.projet-nom { font-size: var(--t3); }
.projet-quoi { margin-top: var(--e3); color: var(--encre-3); font-size: var(--p); }
.etiquettes { margin-top: var(--e4); display: flex; flex-wrap: wrap; gap: 6px; }
.etiquette {
  font-size: var(--p-5);
  padding: 5px 10px;
  border-radius: 6px;
  background: rgba(0,0,0,0.05);
  color: var(--encre-2);
}
.projet.est-sombre { background: var(--noir-2); border-color: transparent; color: var(--sur-noir); }
.projet.est-sombre .projet-quoi { color: var(--sur-noir-2); }
.projet.est-sombre .etiquette { background: rgba(255,255,255,0.10); color: var(--sur-noir-2); }

.centre { display: flex; justify-content: center; margin-top: var(--e6); }
.centre-duo { gap: var(--e3); flex-wrap: wrap; }
/* L'audit posé sous la signature : celui qui n'est pas prêt à
   réserver un appel peut au moins repartir avec quelque chose. */
.appel-audit { margin-top: var(--e6); }

/* ─────────────────────────────────────────────────────────────
   4. LE PROCESSUS
   ───────────────────────────────────────────────────────────── */
.processus-titre { text-align: center; font-size: var(--t2); }
.processus-titre em { display: block; font-style: normal; color: var(--or-titre); }

/* ─── Le calendrier de quatorze jours ───
   Relevé sur le modèle : deux rangs de sept jours dans une grande
   carte à angles très arrondis, des séparateurs TIRETÉS et non
   pleins, le numéro du jour en petit gris en haut de chaque case, et
   seulement quatre jours qui portent quelque chose.

   Les jours qui comptent — cadrage, lancement, présentation, mise en
   ligne — ont un fond crème et un jeton doré. Les autres sont vides,
   et c'est le sujet : on montre que la semaine n'est pas remplie de
   réunions.

   Les fiches d'événement portent un filet doré à gauche, l'icône de
   l'outil employé posée en débord, et les initiales de qui est dans
   la pièce. */
.frise {
  margin-top: var(--e7);
  border-radius: var(--r5);
  background: linear-gradient(150deg, #FFFCF2 0%, #F7F7F5 55%, #F4F4F4 100%);
  padding: var(--e4);
  overflow: hidden;
}
.frise-rang {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  min-height: 200px;
}
.frise-rang + .frise-rang { border-top: 2px dashed rgba(0, 0, 0, 0.09); }

.frise-case {
  position: relative;
  padding: var(--e4) var(--e3);
  border-left: 2px dashed rgba(0, 0, 0, 0.09);
}
.frise-case:first-child { border-left: 0; }
.frise-case.est-vedette { background: linear-gradient(180deg, rgba(255, 246, 214, 0.75), rgba(255, 246, 214, 0.25)); }

.frise-jour {
  display: block;
  font-size: var(--p-5);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(0, 0, 0, 0.34);
}
.frise-jour.est-marque {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 6px;
  background: var(--or);
  color: #fff;
  font-weight: 500;
  letter-spacing: 0.06em;
}

/* La fiche d'événement. Elle déborde volontairement de sa case quand
   elle est « large » : sur le modèle, une tâche de plusieurs jours
   traverse les colonnes qu'elle occupe. */
.frise-carte {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--e3);
  margin-top: var(--e3);
  padding: 12px 14px;
  border-radius: var(--r1);
  background: rgba(255, 255, 255, 0.92);
  border-left: 3px solid var(--or);
  box-shadow: 0 8px 20px -14px rgba(0, 0, 0, 0.5);
  font-size: var(--p-4);
  line-height: 1.25;
}
.frise-carte.est-large { width: 250%; z-index: 2; }
.frise-quoi { flex: 1; }

/* L'icône de l'outil, posée en débord sur le coin de la fiche et
   légèrement tournée — le modèle ne les aligne jamais. */
/* Les icônes d'outils flottent, comme celles du modèle — il leur
   pose un attribut `data-parallaxfloating`. Un décalage d'animation
   différent par icône, sinon les six montent et descendent au
   garde-à-vous. */
.frise-appli {
  position: absolute;
  top: -16px; right: 12px;
  width: 30px; height: 30px;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.22));
  animation: appli-flotter 5.5s ease-in-out infinite;
}
.frise-case:nth-child(2n) .frise-appli { animation-delay: -1.8s; }
.frise-case:nth-child(3n) .frise-appli { animation-delay: -3.4s; }
@keyframes appli-flotter {
  0%, 100% { transform: rotate(-8deg) translateY(0); }
  50%      { transform: rotate(-5deg) translateY(-7px); }
}
@media (prefers-reduced-motion: reduce) {
  .frise-appli { animation: none; transform: rotate(-8deg); }
}
.frise-carte.est-large .frise-appli { right: auto; left: 58%; }

.frise-gens { display: flex; flex: none; }
.frise-tete {
  width: 24px; height: 24px;
  margin-left: -7px;
  border-radius: 50%;
  border: 2px solid #fff;
  background: var(--noir-2);
  color: #fff;
  display: grid; place-items: center;
  font-size: 10px;
  font-weight: 500;
}
.frise-tete:first-child { margin-left: 0; background: var(--or); color: var(--noir); }

.frise-apercu {
  display: block;
  margin-top: var(--e3);
  border-radius: 6px 6px 0 0;
  overflow: hidden;
  box-shadow: 0 10px 24px -16px rgba(0, 0, 0, 0.5);
}
.frise-apercu img { width: 100%; height: 84px; object-fit: cover; object-position: top; }

@media (max-width: 980px) {
  .frise-rang { grid-template-columns: repeat(2, minmax(0, 1fr)); min-height: 0; }
  .frise-carte.est-large { width: auto; }
  .frise-carte.est-large .frise-appli { left: auto; right: 12px; }
  .frise-case:nth-child(odd) { border-left: 0; }
}

/* Le bandeau de compétences qui défile en boucle. */
.bandeau {
  margin-top: var(--e6);
  /* DE LA PLACE POUR L'OMBRE.

     Les pastilles portent une ombre de vingt-huit pixels vers le bas.
     Avec `overflow: hidden` posé au ras de la piste, elle était
     tranchée net : les pastilles paraissaient coupées par une ligne
     invisible. Le rembourrage vertical lui rend la place qu'il lui
     faut, et la marge négative reprend cette place dans le flux pour
     que l'espacement de la section ne bouge pas. */
  padding-block: 34px;
  margin-block: calc(var(--e6) - 34px) -34px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.bandeau-piste {
  display: flex;
  gap: var(--e3);
  width: max-content;
  animation: bandeau-defile 52s linear infinite;
}
.bandeau:hover .bandeau-piste { animation-play-state: paused; }
@keyframes bandeau-defile { to { transform: translateX(-50%); } }
/* Les pastilles du bandeau, relevées sur le modèle : blanches, sans
   filet, posées sur une ombre large et douce, avec un macaron doré à
   gauche du mot. Le filet gris que j'avais mis les faisait ressembler
   à des étiquettes de formulaire. */
.bandeau-mot {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 22px;
  border-radius: var(--r7);
  font-size: var(--p);
  white-space: nowrap;
  background: #fff;
  box-shadow:
    0 1px 2px rgba(16, 49, 77, 0.05),
    0 6px 12px -4px rgba(16, 49, 77, 0.10),
    0 20px 28px -12px rgba(16, 49, 77, 0.10);
}
.bandeau-macaron { width: 20px; height: 20px; flex: none; color: var(--or); }
@media (prefers-reduced-motion: reduce) { .bandeau-piste { animation: none; } }

/* ─────────────────────────────────────────────────────────────
   5. LES CLIENTS
   ───────────────────────────────────────────────────────────── */
/* ─── Le film ───
   Un cadre de la vidéo sert d'affiche tant que le fichier n'est pas
   au dépôt : la mise en page est donc juste dès maintenant, et
   brancher la vidéo ne demandera qu'une ligne. `preload="none"` pour
   qu'aucun octet ne parte avant que le visiteur ne le demande. */
.film {
  margin: var(--e7) 0 0;
  border-radius: var(--r4);
  overflow: hidden;
  background: var(--noir);
  box-shadow: 0 40px 80px -46px rgba(0, 0, 0, 0.55);
}
.film { position: relative; }
.film-video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }

/* ─── Le bouton de son ───
   La lecture automatique n'est autorisée qu'en silence : la vidéo
   démarre donc muette, et ce bouton est le seul moyen d'entendre la
   bande. Il porte un LIBELLÉ et pas seulement un pictogramme — un
   haut-parleur barré se confond avec un bouton de pause pour qui ne
   connaît pas la convention. */
.film-son {
  position: absolute;
  right: var(--e4);
  bottom: var(--e4);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--r7);
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: #fff;
  font-size: var(--p-4);
  font-weight: 500;
  transition: background var(--pose) ease, transform var(--pose) var(--ressort);
}
.film-son:hover { background: rgba(0, 0, 0, 0.72); transform: translateY(-2px); }
.film-son-icone { display: grid; place-items: center; width: 20px; height: 20px; }
.film-son-icone svg { grid-area: 1 / 1; width: 20px; height: 20px; }
/* Un seul des deux pictogrammes est montré, selon l'état. */
.film-son .film-son-actif { display: none; }
.film-son[aria-pressed="true"] .film-son-coupe { display: none; }
.film-son[aria-pressed="true"] .film-son-actif { display: block; }

@media (max-width: 620px) {
  .film-son-mot { display: none; }
  .film-son { padding: 11px; }
}

.avis-vedette {
  --encre-3: rgba(0, 0, 0, 0.62);
  margin-top: var(--e7);
  border-radius: var(--r4);
  padding: var(--e8) var(--e6) 0;
  text-align: center;
  background: linear-gradient(160deg, #FFF6DA 0%, #FDE9A8 48%, #F7D775 100%);
  overflow: hidden;
}
.avis-vedette-titre { font-size: var(--t2); }
.avis-vedette-titre em { font-style: normal; position: relative; }
/* La capture, dans un cadre de navigateur, à demi sortie du panneau.
   Le modèle met là une vidéo d'avis ; nous n'en avons pas, et poser
   un bouton de lecture qui ne lit rien serait un mensonge d'un pixel
   de large et de deux ans de long. Une référence en ligne dit la même
   chose et elle, on peut la vérifier. */
.avis-ecran {
  margin: var(--e6) auto -2px;
  max-width: 760px;
  border-radius: var(--r3) var(--r3) 0 0;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 40px 80px -40px rgba(0, 0, 0, 0.5);
}
.avis-ecran-barre {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  background: var(--fond-2);
  border-bottom: 1px solid var(--trait-fin);
}
.avis-ecran-point { width: 9px; height: 9px; border-radius: 50%; background: rgba(0,0,0,0.16); }
.avis-ecran-adresse {
  margin-left: 10px;
  padding: 3px 12px;
  border-radius: var(--r7);
  background: #fff;
  font-size: var(--p-5);
  color: var(--encre-3);
}
/* La capture est rognée par le bas : c'est une FENÊTRE sur le site,
   pas la page entière. Sans hauteur maximale, le panneau doré faisait
   mille pixels de haut pour montrer un pied de page. */
.avis-ecran img { width: 100%; display: block; max-height: 340px; object-fit: cover; object-position: top; }

.avis-logos {
  padding-bottom: var(--e6);
  margin-top: var(--e5);
  display: flex;
  gap: var(--e7);
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  font-size: var(--p);
  font-weight: 500;
  opacity: 0.72;
}

/* ─── LA CARTE D'AVIS, AUX VALEURS DE /audit ───
   Relevées une à une dans css/audit.css, parce que « à peu près la
   même » se voit : mes étoiles avaient un rayon de 3 au lieu de 4 et
   un glyphe dimensionné par le rembourrage plutôt qu'en dur, ma
   pastille faisait 36 au lieu de 40, mes noms étaient en demi-gras
   là où la référence est en gras.

     étoile      22×22, rayon 4, fond #00b67a, glyphe 15 blanc
     vérifié     11,5 px, gras 600, icône 13
     texte       15 px, interligne 1,55
     pastille    40×40, ronde, 14 px gras 700, encre blanche
     nom         14 px gras 700
     rôle        12,5 px
     date        11,5 px, poussée à droite, alignée en haut
     carte       rayon 16, rembourrage 20/20/18

   Seules les COULEURS passent par des jetons : la carte doit rester
   lisible sur le plan sombre de la page Références, où la référence
   n'a jamais eu à aller. */
.avis {
  padding: 20px 20px 18px;
  border-radius: 16px;
  border: 1px solid var(--trait);
  background: var(--carte);
  box-shadow: 0 12px 34px -22px rgba(20, 20, 20, 0.22);
}
.avis-haut {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 13px;
}
.avis-etoiles { display: inline-flex; gap: 3px; }
.avis-etoiles i {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  background: #00b67a;
  border-radius: 4px;
}
.avis-etoiles i svg { width: 15px; height: 15px; fill: #fff; }
.avis-verifie {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--vert-avis);
  white-space: nowrap;
}
.avis-verifie svg { width: 13px; height: 13px; }

.avis-mot { font-size: 15px; line-height: 1.55; color: var(--encre-2); margin: 0 0 17px; }

.avis-qui { display: flex; align-items: center; gap: 11px; }
.avis-portrait {
  width: 40px; height: 40px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-weight: 700;
  font-size: 14px;
  color: #fff;
  flex-shrink: 0;
}
.avis-identite { display: grid; gap: 1px; min-width: 0; }
.avis-nom {
  font-weight: 700; font-size: 14px; color: var(--encre);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.avis-role {
  font-size: 12.5px; color: var(--encre-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.avis-date {
  margin-left: auto;
  align-self: flex-start;
  font-size: 11.5px;
  color: var(--encre-3);
  white-space: nowrap;
}

/* La réponse du studio, telle que /audit/avis la pose : un encadré
   sur fond crème, filet doré à gauche. Elle vaut autant que l'avis —
   un client qui voit qu'on répond sait qu'il sera lu lui aussi. */
.avis-reponse {
  margin-top: 13px;
  padding: 13px 15px;
  border-radius: 12px;
  border-left: 3px solid var(--or);
  background: var(--fond-reponse, #f3ecdf);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--encre-2);
}
.avis-reponse-qui { font-weight: 700; font-size: 12.5px; color: var(--encre); margin-bottom: 3px; }

/* ─────────────────────────────────────────────────────────────
   6. L'OFFRE

   La section la plus dense du modèle, et celle où je m'étais le plus
   éloigné. Un grand cadre noir contient tout : à gauche une carte en
   dégradé d'or qui porte la marque, la promesse et le bouton, puis
   deux blocs de détail dont chaque ligne est une gélule à coche
   dorée ; à droite un carrousel de sites livrés qui avance seul, et
   sous lui le prix et les options.
   ───────────────────────────────────────────────────────────── */
.offre-plan {
  margin-top: var(--e7);
  display: grid;
  gap: var(--e5);
  padding: var(--e5);
  border-radius: var(--r5);
  background: var(--noir);
}

/* Le carrousel de sites livrés, en tête du cadre : on montre le
   travail avant d'énumérer les métiers. */
.offre-galerie {
  border-radius: var(--r4);
  overflow: hidden;
  background: var(--noir-2);
  padding: var(--e4) 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.offre-galerie-piste {
  display: flex;
  gap: var(--e4);
  width: max-content;
  animation: offre-defile 56s linear infinite;
}
.offre-galerie:hover .offre-galerie-piste { animation-play-state: paused; }
@keyframes offre-defile { to { transform: translateX(-50%); } }
.offre-galerie figure {
  flex: 0 0 340px;
  border-radius: var(--r3);
  overflow: hidden;
  background: var(--noir);
}
.offre-galerie img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: top; }
@media (prefers-reduced-motion: reduce) { .offre-galerie-piste { animation: none; } }

/* ─── Les quatre métiers ───
   Le modèle n'a qu'une offre et lui donne une carte en dégradé d'or.
   Thomax en a quatre : le premier garde l'or, les trois autres le
   gris du cadre. Sans cette hiérarchie, quatre cartes identiques se
   lisent comme un tableau et plus personne ne sait par où commencer.

   Chaque ligne est une gélule à coche dorée, comme chez lui. */
.metiers {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e4);
}
/* LES QUATRE CARTES SONT NOIRES, ET S'ALLUMENT AU SURVOL.

   Le modèle n'a qu'une offre et lui donne l'or d'office. Thomax en a
   quatre : en dorer une revient à dire que les trois autres sont des
   seconds choix, ce qui n'est pas le propos. Toutes partent donc du
   même noir, et l'or désigne celle qu'on regarde.

   Le dégradé est porté par un calque et non par le fond : une image
   de fond ne se transitionne pas, son opacité si. Sans cela, l'or
   apparaîtrait d'un coup au lieu de monter. */
.metier {
  position: relative;
  isolation: isolate;
  display: grid;
  align-content: start;
  gap: var(--e3);
  padding: var(--e6);
  border-radius: var(--r4);
  background: var(--noir-2);
  border: 1px solid rgba(255, 255, 255, 0.06);
  color: #fff;
  transition: transform var(--ample) var(--ressort), border-color var(--pose) ease;
}
.metier::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  /* LE DERNIER ARRÊT NE PEUT PAS ÊTRE AUSSI SOMBRE QUE CELUI DU
     MODÈLE. Sa carte dorée descend presque au noir, mais son texte
     tient dans le haut ; la mienne est remplie jusqu'en bas. Mesuré
     sur #8A6B1C avec de l'encre sombre : description à 3,39:1,
     gélules à 3,02:1 — le seuil est 4,5. À #B8901F on est à 5,24 et
     4,82, et l'œil ne fait pas la différence entre les deux ors.

     L'audit ne contrôle pas les états de survol : ce calcul est à
     refaire à la main si le dégradé bouge. */
  background: linear-gradient(168deg, #E8B93A 0%, #D2A52C 46%, #B8901F 100%);
  opacity: 0;
  transition: opacity var(--ample) ease;
}
.metier:hover, .metier:focus-within {
  transform: translateY(-4px);
  border-color: transparent;
  color: #0B0B0B;
}
.metier:hover::before, .metier:focus-within::before { opacity: 1; }

.metier-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--e3); }
.metier-icone {
  width: 34px; height: 34px;
  padding: 6px;
  border-radius: var(--r1);
  background: #fff;
  box-sizing: content-box;
}
.metier-num {
  font-size: var(--p-5);
  letter-spacing: 0.14em;
  opacity: 0.62;
  transition: opacity var(--pose) ease;
}
.metier-nom { font-size: var(--t3); font-weight: 500; letter-spacing: -0.02em; }
.metier-pitch { font-size: var(--p-4); line-height: 1.55; opacity: 0.82; max-width: 42ch; }
.metier .offre-liste { margin-top: var(--e3); }
/* LA MENTION D'ÉQUIPE.
   Tout y hérite de `currentColor` : la carte est blanche sur noir au
   repos et encre sombre sur or au survol, et un ton fixe serait faux
   dans l'un des deux états. Le filet passe par `color-mix` pour la
   même raison — une valeur en dur ne suivrait pas la bascule.
   L'opacité reprend celle du descriptif, dont les contrastes sont
   déjà mesurés sur les deux fonds. */
.metier-equipe {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-top: var(--e2);
  padding-top: var(--e3);
  border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent);
  font-size: var(--p-5);
  line-height: 1.45;
  opacity: 0.82;
}
.metier-equipe-icone { width: 15px; height: 15px; flex: none; margin-top: 1px; }

.metier-fleche { width: 15px; height: 15px; transition: transform var(--pose) var(--ressort); }
.metier-aller:hover .metier-fleche { transform: translateX(3px); }
.metier-aller {
  margin-top: var(--e4);
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--p-4);
  font-weight: 500;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
}

/* Au survol, les gélules et leurs coches s'inversent : sur l'or, du
   blanc sur blanc ne se lit plus. */
.metier:hover .offre-liste li,
.metier:focus-within .offre-liste li { background: rgba(0, 0, 0, 0.16); color: #0B0B0B; }
.metier:hover .offre-coche,
.metier:focus-within .offre-coche { background: #0B0B0B; color: var(--or); }
.metier .offre-liste li,
.metier .offre-coche { transition: background var(--ample) ease, color var(--ample) ease; }

@media (prefers-reduced-motion: reduce) {
  .metier, .metier::before { transition: none; }
  .metier:hover, .metier:focus-within { transform: none; }
}

.offre-liste { display: grid; gap: 8px; }
.offre-liste li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border-radius: var(--r7);
  background: rgba(255, 255, 255, 0.10);
  font-size: var(--p-4);
  color: rgba(255, 255, 255, 0.92);
}
.offre-coche {
  flex: none;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--or);
  color: #0B0B0B;
}
.offre-coche svg { width: 12px; height: 12px; }

/* ─── Le pied du cadre : le devis et les options ─── */
.offre-pied {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--e4);
  /* LES DEUX CARTES REMPLISSENT LA MÊME RANGÉE.

     Avec `align-items: start`, chacune prenait la hauteur de son
     contenu : 260 pixels pour le devis contre 488 pour l'option, soit
     deux cent vingt-huit pixels de noir sous la première. `stretch`
     est le comportement par défaut d'une grille — c'est moi qui
     l'avais annulé. */
  align-items: stretch;
}
.offre-prix {
  /* COLONNE FLEXIBLE, PAS GRILLE.

     Avec `display: grid` et `align-content: start`, les rangées se
     tassent en haut et l'espace libre reste en bas, hors d'atteinte :
     `margin-top: auto` sur le bouton n'a alors rien à pousser. En
     colonne flexible, la marge automatique absorbe l'espace restant
     et le bouton descend vraiment. */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background: var(--carte);
  border-radius: var(--r4);
  /* Même rembourrage que la carte voisine : sans cela leurs deux
     appels à l'action ne tombent pas à la même hauteur, et c'est
     précisément le décalage qu'on cherche à supprimer. */
  padding: var(--e5);
}
/* Le bouton descend au bas de la carte plutôt que de rester collé au
   texte : les deux appels à l'action des deux cartes s'alignent
   alors sur la même ligne. */
.offre-prix .bouton { margin-top: auto; }
/* L'illustration occupe la même bande de 150 pixels que celle de la
   carte voisine : les deux cartes gardent ainsi la même structure —
   image, texte, appel à l'action — et donc la même hauteur.

   `contain` et non `cover` : c'est un dessin détouré sur blanc, et
   le recadrer couperait la main ou la facture. Le fond de la carte
   étant blanc lui aussi, rien ne trahit la boîte. */
.offre-prix-vue {
  display: block;
  width: 100%;
  height: 150px;
  margin-bottom: var(--e4);
  flex: none;
}
.offre-prix-vue img { width: 100%; height: 100%; object-fit: contain; object-position: center; }

.offre-prix-quand { font-size: var(--t5); }
.offre-prix-chiffre { font-size: clamp(1.7rem, 2.2vw, 2.4rem); font-weight: 700; letter-spacing: -0.03em; line-height: 1.08; }
.offre-prix-chiffre sup {
  display: block;
  margin-top: 6px;
  font-size: var(--p-5);
  font-weight: 500;
  vertical-align: baseline;
  color: var(--encre-3);
}
.offre-prix-mot { margin-top: var(--e3); margin-bottom: var(--e5); font-size: var(--p-4); color: var(--encre-3); max-width: 40ch; }


.offre-sup { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e4); }
.offre-sup-large { grid-column: 1 / -1; }
.offre-sup-film { width: 100%; height: 100%; object-fit: cover; display: block; }
.offre-sup-carte {
  --encre: #fff;
  --encre-3: rgba(255, 255, 255, 0.7);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--e3);
  padding: var(--e5);
  border-radius: var(--r3);
  background: var(--noir-2);
  color: #fff;
}
/* La carte d'option reprend la composition de la carte de devis :
   un surtitre, un grand titre avec son exposant, un paragraphe, une
   pastille en bas. Deux cartes côte à côte qui n'annoncent pas leur
   contenu de la même façon se lisent comme deux blocs sans rapport. */
.offre-sup-carte .offre-prix-quand { color: rgba(255, 255, 255, 0.7); }
.offre-sup-carte .offre-prix-chiffre { color: #fff; }
.offre-sup-carte .offre-prix-chiffre sup { color: rgba(255, 255, 255, 0.62); }
.offre-sup-carte .offre-prix-mot { color: rgba(255, 255, 255, 0.7); }
/* LA HAUTEUR DE L'IMAGE RÈGLE CELLE DES DEUX CARTES.

   Les deux cartes partagent la même rangée : la plus haute impose sa
   taille à l'autre. L'image en 16/9 faisait 315 pixels, la carte 488,
   et la carte de devis — qui n'a besoin que de 260 — se retrouvait
   avec deux cents pixels de vide.

   Cent cinquante pixels de haut ramènent l'ensemble autour de 340 :
   il reste de l'air sous le texte du devis, mais de l'air qui
   ressemble à une respiration et non à un trou. `cover` recadre au
   lieu de déformer. */
.offre-sup-vue {
  display: block;
  width: 100%;
  height: 150px;
  border-radius: var(--r1);
  overflow: hidden;
  flex: none;
}
/* LE CADRAGE EST DANS LE CSS, PAS DANS LE FICHIER.

   La fenêtre fait 560 sur 150, soit un rapport de 3,7 pour 1 : très
   large. Découpée au centre d'une image 16/9, elle coupait l'appareil
   par le milieu. `object-position` déplace la fenêtre vers le haut du
   sujet — et se corrige d'une valeur, sans refaire l'image. */
.offre-sup-vue img { width: 100%; height: 100%; object-fit: cover; object-position: center 32%; }
.offre-langues { display: flex; flex-wrap: wrap; gap: 6px; }
.offre-langue {
  padding: 6px 12px;
  border-radius: var(--r7);
  background: #fff;
  color: #0B0B0B;
  font-size: var(--p-4);
  font-weight: 500;
}
.jeton-prix {
  margin-top: auto;
  padding: 6px 12px;
  border-radius: var(--r7);
  background: var(--or);
  color: #0B0B0B;
  font-size: var(--p-4);
  font-weight: 500;
}

@media (max-width: 980px) {
  .metiers, .offre-pied, .offre-sup { grid-template-columns: 1fr; }
  .offre-galerie figure { flex-basis: 260px; }
}

/* ─────────────────────────────────────────────────────────────
   7. L'APPEL
   ───────────────────────────────────────────────────────────── */
.appel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr); gap: var(--e8); align-items: start; }
.appel h2 { font-size: var(--t2); max-width: 16ch; }
.appel-listes { margin-top: var(--e6); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e5); }
.appel-liste { display: grid; gap: 8px; align-content: start; }
.appel-liste li {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px;
  border-radius: var(--r7);
  background: rgba(255,255,255,0.07);
  font-size: var(--p-4);
  color: var(--sur-noir-2);
}
.appel-coche { color: var(--or); flex: none; width: 15px; height: 15px; display: block; }
.appel-coche svg { width: 100%; height: 100%; }
.appel-signature { margin-top: var(--e7); display: flex; align-items: center; gap: 12px; }
.appel-portrait { width: 40px; height: 40px; border-radius: 50%; background: var(--or); color: var(--noir); display: grid; place-items: center; font-weight: 500; }

.formulaire {
  background: rgba(255,255,255,0.04);
  border: 1px dashed var(--trait-nuit);
  border-radius: var(--r4);
  padding: var(--e6);
  display: grid;
  gap: var(--e4);
}
.champ { display: grid; gap: 6px; }
.champ label { font-size: var(--p-5); color: var(--sur-noir-3); }
.champ input, .champ textarea, .champ select {
  font: inherit;
  font-size: var(--p-4);
  color: var(--sur-noir);
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--trait-nuit);
  border-radius: var(--r2);
  padding: 12px 14px;
}
.champ textarea { min-height: 96px; resize: vertical; }
.champ input::placeholder, .champ textarea::placeholder { color: rgba(255,255,255,0.35); }

@media (max-width: 980px) {
  .offres, .projets, .offre-plan, .appel, .appel-listes { grid-template-columns: 1fr; }
  .gages { grid-template-columns: 1fr; gap: var(--e5); }
  .gage { padding-inline: 0; border-left: 0; }
  .gage:nth-child(2) { transform: none; }
  .frise-entete, .frise-rang { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pave { padding: var(--e7) var(--e5); }
  .ouverture .vitrine { width: 128%; margin-inline: -14%; }
}


/* ═══ pages.css ═══ */
/* ═══════════════════════════════════════════════════════════════
   LES PAGES INTÉRIEURES

   Trente-quatre pages portent la structure de la version
   précédente. Leur texte porte le référencement : le réécrire pour
   changer d'habillage reviendrait à jeter ce qui est acquis pour
   gagner de la cohérence de classe. On rhabille donc les classes
   existantes dans le langage du nouveau système — mêmes couleurs,
   même typographie, mêmes rayons, mêmes filets.
   ═══════════════════════════════════════════════════════════════ */

/* ─── Les plans ───
   La version précédente alternait un plan clair et un plan sombre.
   Le nouveau système ne connaît que le crème et le pavé noir : le
   plan sombre devient donc un pavé, avec ses angles arrondis. */
.plan-fond { background: transparent; color: var(--encre); }

.plage.plan-contre {
  padding: 0;
  margin-block: var(--e8);
}
.plage.plan-contre > .cadre {
  /* LES JETONS D'ENCRE SE REDÉFINISSENT DANS LE PAVÉ.

     Sans cela, chaque classe héritée gardait son gris de texte
     courant — #5A5A5A, taillé pour le crème — et le posait sur du
     noir : 3,04:1, mesuré, sous le seuil. Il aurait fallu réécrire
     une règle par classe et en oublier quelques-unes. Redéfinir les
     jetons à la racine du pavé corrige tout ce qu'il contient, y
     compris ce qu'on y ajoutera demain. */
  --carte: var(--noir-2);
  --vert-avis: #22C286;
  --fond-reponse: rgba(209, 163, 38, 0.14);
  --encre: var(--sur-noir);
  --encre-2: var(--sur-noir-2);
  --encre-3: var(--sur-noir-2);
  --or-lisible: var(--or);
  --or-titre: var(--or);
  --trait: var(--trait-nuit);
  --trait-fin: var(--trait-nuit);
  background: var(--noir);
  color: var(--sur-noir);
  border-radius: var(--r5);
  padding: var(--e8) var(--e7);
  max-width: var(--conteneur);
}
.plage.plan-contre h1, .plage.plan-contre h2, .plage.plan-contre h3,
.plage.plan-contre h4, .plage.plan-contre .t0, .plage.plan-contre .t1,
.plage.plan-contre .t2, .plage.plan-contre .t3 { color: var(--sur-noir); }
.plage.plan-contre p { color: var(--sur-noir-2); }
.plage.plan-contre .donnee { color: var(--sur-noir-3); }
.plage.plan-contre .donnee--accent,
.plage.plan-contre .tete-num { color: var(--or); }

/* ─── La grille de douze ─── */
.douze {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--e5);
}
/* CE QUI N'EST PAS PLACÉ PREND TOUTE LA LARGEUR.

   La version précédente plaçait chaque enfant de la grille par une
   règle nommée : `.combinaisons-titre` sur cinq colonnes, sa légende
   sur les quatre suivantes, et ainsi de suite sur trente pages. Ces
   règles ont disparu avec l'ancienne feuille — et sans elles, chaque
   enfant tombe dans UNE colonne de cent pixels : les titres se
   composaient sur un mot par ligne.

   Le défaut sûr est donc « toute la largeur ». Les mises en page à
   deux colonnes sont ensuite rétablies une par une, ci-dessous, là
   où elles servent vraiment la lecture. */
.douze > * { grid-column: 1 / -1; }

/* Titre à gauche, texte d'accompagnement à droite. */
.douze > .combinaisons-titre,
.douze > .constat-titre,
.douze > .methode-titre,
.douze > .appel-titre { grid-column: 1 / span 6; }
.douze > .combinaisons-lead,
.douze > .constat-texte,
.douze > .methode-lead,
.douze > .appel-actions { grid-column: 8 / -1; align-self: end; }

@media (max-width: 900px) {
  .douze { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .douze > * { grid-column: 1 / -1 !important; }
}

/* ─── Les corps de texte ─── */
.t0 { font-size: var(--t1); font-weight: 500; line-height: 1.08; letter-spacing: -0.02em; }
.t1 { font-size: var(--t2); font-weight: 500; line-height: 1.1; letter-spacing: -0.02em; }
.t2 { font-size: var(--t3); font-weight: 500; line-height: 1.15; letter-spacing: -0.02em; }
.t3 { font-size: var(--t5); font-weight: 500; line-height: 1.2; }
.lead em, p em { color: var(--or-lisible); font-style: normal; }
/* L'or des grands titres n'est admis qu'au-dessus de vingt-quatre
   pixels — seuil du WCAG pour le « grand texte », où 3:1 suffit.
   `.t0` et `.t1` ne descendent jamais sous trente pixels, même sur
   téléphone ; `.t2` tombe à 21,6 et repasse donc à l'or lisible. */
.t0 em, .t1 em, .t2 em, .t3 em { font-style: normal; }
.t0 em, .t1 em { color: var(--or-titre); }
.t2 em, .t3 em { color: var(--or-lisible); }
.plage.plan-contre .t0 em, .plage.plan-contre .t1 em,
.plage.plan-contre .t2 em, .plage.plan-contre .t3 em { color: var(--or); }

.lead { font-size: var(--lead); color: var(--encre-2); line-height: 1.5; }
.plage.plan-contre .lead { color: var(--sur-noir-2); }

/* La « donnée » était une mono à chasse fixe. Le nouveau système n'a
   qu'une famille : on garde la fonction — un libellé technique, en
   petites capitales espacées — sans la seconde police. */
.donnee {
  font-size: var(--p-5);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--encre-3);
}
.donnee--accent { color: var(--or-lisible); }

/* ─── L'ouverture des pages intérieures ─── */
.ouverture-interieur { display: grid; justify-items: center; gap: var(--e4); text-align: center; }
.donnee-ouverture { margin: 0; }
.ouverture-pied {
  margin-top: var(--e6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--e3);
  justify-content: center;
}
.hero-mesure {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border: 1px solid var(--trait);
  border-radius: var(--r7);
  background: var(--carte);
  font-size: var(--p-4);
}
.hero-mesure .donnee { color: var(--or-lisible); }

/* ─── La tête de section ─── */
.tete {
  display: flex;
  align-items: center;
  gap: var(--e3);
  margin-bottom: var(--e6);
  font-size: var(--p-5);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--encre-3);
}
/* Dans un pavé noir, le gris de texte courant tombe à 3,66:1. */
.plage.plan-contre .tete,
.plage.plan-contre .tete-nom { color: var(--sur-noir-2); }
.tete::after { content: ''; flex: 1; height: 1px; background: var(--trait); }
.plage.plan-contre .tete::after { background: var(--trait-nuit); }
.tete-num { color: var(--or-lisible); }
.plage.plan-contre .tete-num { color: var(--or); }

/* ─── Les listes de disciplines et de livrables ─── */
.disciplines { display: grid; gap: 0; }
.discipline {
  display: grid;
  grid-template-columns: 3rem minmax(0, 16rem) minmax(0, 1fr) auto;
  gap: var(--e5);
  align-items: center;
  padding: var(--e5) 0;
  border-top: 1px solid var(--trait-nuit);
  transition: padding-inline var(--pose) var(--ressort);
}
.discipline:last-child { border-bottom: 1px solid var(--trait-nuit); }
.discipline:hover { padding-inline: var(--e4); }
.discipline-num { color: var(--or); font-size: var(--p-5); letter-spacing: 0.08em; }
.discipline-nom { font-size: var(--t5); font-weight: 500; }
.discipline-desc { font-size: var(--p-4); color: var(--sur-noir-2); }
.discipline-aller { font-size: var(--p-4); white-space: nowrap; color: var(--or); }

.livrables, .lectures, .formules, .temps, .questions { display: grid; gap: var(--e4); }
.livrable, .formule, .question, .temps-etape, .lecture {
  border: 1px solid var(--trait);
  border-radius: var(--r3);
  background: var(--carte);
  padding: var(--e5);
}
.livrable-marque, .temps-num, .legal-num { color: var(--or-lisible); font-size: var(--p-5); letter-spacing: 0.08em; }
.plage.plan-contre .livrable-marque, .plage.plan-contre .temps-num { color: var(--or); }
.livrable-nom, .formule-nom, .temps-nom, .lecture-nom { font-size: var(--t5); font-weight: 500; margin-top: 6px; }
.livrable-quoi, .formule-quoi, .temps-quoi { margin-top: var(--e3); font-size: var(--p-4); color: var(--encre-3); }
.plage.plan-contre .livrable-quoi, .plage.plan-contre .formule-quoi,
.plage.plan-contre .temps-quoi { color: var(--sur-noir-2); }
.formule-liste { margin-top: var(--e4); display: grid; gap: 6px; font-size: var(--p-4); }
.formule-devis { margin-top: var(--e4); font-weight: 500; }

.question { padding: 0; }
.question > summary {
  cursor: pointer;
  list-style: none;
  padding: var(--e5);
  font-size: var(--p);
  font-weight: 500;
}
.question > summary::-webkit-details-marker { display: none; }
/* Le signe tourne au lieu de changer de caractère : un « + » qui
   devient « – » saute, un « + » qui pivote de 45 degrés devient une
   croix en glissant, et le mouvement dit lui-même ce qui se passe. */
.question > summary::after {
  content: '';
  float: right;
  width: 14px;
  height: 14px;
  margin-top: 0.35em;
  background:
    linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat;
  color: var(--or-lisible);
  transition: transform 380ms cubic-bezier(0.33, 1, 0.68, 1);
}
.question[open] > summary::after { transform: rotate(135deg); }
@media (prefers-reduced-motion: reduce) {
  .question > summary::after { transition: none; }
}
.question-reponse { padding: 0 var(--e5) var(--e5); color: var(--encre-3); font-size: var(--p-4); }
.plage.plan-contre .question-reponse { color: var(--sur-noir-2); }

/* ─── Les cartes de référence ─── */
.references, .reference-cadre { display: grid; gap: var(--e5); }
.reference, .reference--carte {
  display: grid;
  align-content: start;
  border: 1px solid var(--trait);
  border-radius: var(--r4);
  overflow: hidden;
  background: var(--carte);
  transition: transform var(--ample) var(--ressort), box-shadow var(--ample) ease;
}
/* Le texte sous l'image, pas dessus. Le cadre de la capture était
   sorti du flux par sa position absolue : les deux se superposaient
   et l'on lisait le nom du site par-dessus sa propre page d'accueil. */
.reference-cadre { position: relative; border: 0; border-radius: 0; }
.reference-cadre img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: top; max-height: none; }
.reference > div:last-child { padding: var(--e5); display: grid; gap: 6px; }
.reference-tete { display: grid; gap: 2px; }
.reference-desc { margin: 0; }
.reference-visiter { margin-top: var(--e3); display: inline-block; }
.reference:hover, .reference--carte:hover {
  transform: translateY(-5px);
  box-shadow: 0 26px 50px -30px rgba(0,0,0,0.35);
}
.reference-tete, .reference-nom { font-size: var(--t5); font-weight: 500; }
.reference-desc, .reference-adresse { font-size: var(--p-4); color: var(--encre-3); }
.reference-visiter { font-size: var(--p-4); color: var(--or-lisible); }
.reference img { width: 100%; height: auto; }

/* ─── Le blog ─── */
.billets { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--e5); }
.billet {
  display: grid;
  align-content: start;
  border: 1px solid var(--trait);
  border-radius: var(--r4);
  overflow: hidden;
  background: var(--carte);
  transition: transform var(--ample) var(--ressort), box-shadow var(--ample) ease;
}
.billet:hover { transform: translateY(-5px); box-shadow: 0 26px 50px -30px rgba(0,0,0,0.35); }
.billet-couv { aspect-ratio: 16 / 10; overflow: hidden; background: var(--fond-2); }
.billet-couv img { width: 100%; height: 100%; object-fit: cover; }
.billet-meta { padding: var(--e5) var(--e5) 0; display: flex; gap: var(--e3); font-size: var(--p-5); color: var(--encre-3); text-transform: uppercase; letter-spacing: 0.06em; }
.billet-cat { color: var(--or-lisible); }
.billet-nom { padding: var(--e3) var(--e5) 0; font-size: var(--t5); font-weight: 500; }
.billet-chapo { padding: var(--e3) var(--e5) 0; font-size: var(--p-4); color: var(--encre-3); }
.billet-lire { padding: var(--e4) var(--e5) var(--e5); font-size: var(--p-4); color: var(--or-lisible); }

/* ─── L'article ─── */
.article-titre { max-width: 20ch; }
.article-couv { margin-block: var(--e6); border-radius: var(--r4); overflow: hidden; }
/* CE CONTENEUR N'A QU'UN SEUL ENFANT.

   Je l'avais pris pour une mise en page à deux colonnes — article
   d'un côté, sommaire de l'autre — et lui avais donné une grille de
   15 rem plus le reste. Or les vingt et un articles ne contiennent
   qu'un `<article>` : il tombait donc dans la colonne de 240 pixels,
   avec mille cent trente-six pixels de vide à sa droite. Un article
   composé sur six mots par ligne, sur douze mille pixels de haut.

   C'est une section de lecture, pas une grille : une colonne, centrée,
   à la largeur de l'œil. */
.article-corps-plan { padding-block: var(--e8); }
.article-corps {
  max-width: 72ch;
  margin-inline: auto;
  padding-inline: var(--gouttiere);
  font-size: var(--p);
  line-height: 1.7;
  color: var(--encre-2);
}
.article-corps > * + * { margin-top: var(--e5); }
.article-corps h2 { margin-top: var(--e8); font-size: var(--t3); }
.article-corps h3 { margin-top: var(--e6); font-size: var(--t5); }
.article-corps ul, .article-corps ol { display: grid; gap: 8px; padding-left: 1.1em; list-style: disc; }
.article-corps a:not(.bouton) { color: var(--or-lisible); text-decoration: underline; text-underline-offset: 3px; }
.article-corps blockquote {
  padding-left: var(--e5);
  border-left: 3px solid var(--or);
  font-size: var(--lead);
}
.lecture { display: grid; gap: 6px; }
.retour { display: inline-flex; align-items: center; gap: 8px; font-size: var(--p-4); color: var(--encre-3); }
.suite-lien { display: grid; gap: 4px; }
.suite-nom { font-size: var(--t5); font-weight: 500; }

/* ─── Divers ─── */
/* LIMITER LA LARGEUR NE CENTRE PAS.

   `.cadre-lis` portait un `max-width` et rien d'autre : le bloc
   restait donc collé à gauche, avec la moitié de l'écran vide à sa
   droite. C'est ce qui décalait l'en-tête et la couverture de tous
   les articles du blog — quatre-vingt-deux emplois dans le site.

   La gouttière est reprise ici parce que ce conteneur remplace le
   `.cadre` : sans elle, le texte toucherait le bord sur un
   téléphone. */
.cadre-lis {
  max-width: 72ch;
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}
.fleche { display: inline-block; transition: transform var(--pose) var(--ressort); }
a:hover > .fleche, .bouton:hover .fleche { transform: translateX(3px); }
/* UN SVG SANS DIMENSION OCCUPE LA PLACE QU'ON LUI DONNE.

   Les cinq étoiles de chaque avis sont des SVG en ligne sans width ni
   height. Sans règle de taille, elles s'étiraient à la largeur de leur
   carte : cinq formes noires de trois cents pixels sur du noir, et la
   section des avis passait à six mille six cents pixels de haut.

   C'est le genre de défaut qu'on ne voit pas dans le HTML — il est
   parfaitement valide — et que seule la page montre. */
.avis-etoiles {
  display: inline-flex;
  gap: 3px;
  color: var(--or);
}
.avis-etoiles svg { width: 14px; height: 14px; flex: none; fill: currentColor; }
.mesures-source { margin-top: var(--e5); font-size: var(--p-5); color: var(--encre-3); }
.bouton--plein { --fond-bouton: var(--noir); --encre-bouton: var(--sur-noir); }
.plage.plan-contre .bouton--plein,
.plage.plan-contre .bouton { --fond-bouton: var(--sur-noir); --encre-bouton: var(--noir); }
.plage.plan-contre .bouton-fin { --fond-bouton: transparent; --encre-bouton: var(--sur-noir); border-color: var(--trait-nuit); }

/* La version précédente animait au défilement des éléments portant
   `.monte`. Le nouveau moteur lit `[data-monte]` ; on garde les deux
   noms plutôt que de retoucher trente-quatre pages. */
.monte { will-change: opacity, transform; }

@media (max-width: 900px) {
  .discipline { grid-template-columns: 1fr; gap: var(--e2); }
  .plage.plan-contre > .cadre { padding: var(--e7) var(--e5); }
}

/* ═══════════════════════════════════════════════════════════════
   LE RESTE DE L'HÉRITAGE

   Ce bloc couvre les classes que l'outil `orphelines.mjs` a
   trouvées sans règle après la première passe. Une classe sans
   règle ne provoque aucune erreur : elle se contente de rendre un
   bloc nu au milieu d'une page soignée, et c'est le genre de défaut
   qu'on ne voit qu'en descendant les trente-cinq pages une par une.
   ═══════════════════════════════════════════════════════════════ */

.tete-nom { color: inherit; }
.hero-mesure-valeur { font-weight: 500; }
.livrable-texte { display: grid; gap: 4px; }
.marque-num { color: var(--or-lisible); font-size: var(--p-5); letter-spacing: 0.08em; }
.gage-marque { color: var(--or); }

/* ─── Grilles simples : deux ou trois colonnes selon la place ─── */
.cas, .mesures, .lieux, .equipe, .journal, .avis-mur,
.geo-grille, .champs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: var(--e4);
  margin-top: var(--e5);
}
/* UNE CELLULE DE GRILLE NE SE LAISSE PAS ÉCARTER PAR SON CONTENU.

   Par défaut, `min-width` vaut `auto` sur un enfant de grille : la
   piste s'élargit alors jusqu'au plus long mot qu'il contient. Le
   sommaire des CGV porte un lien de 341 pixels ; sur un téléphone de
   390, la colonne passait à 419, le conteneur à 467, et toute la
   page débordait horizontalement. */
.cas > *, .mesures > *, .lieux > *, .equipe > *, .journal > *,
.avis-mur > *, .geo-grille > *,
.champs > * { min-width: 0; }
.constat, .methode, .combinaisons, .suite, .contact-grille {
  display: grid;
  gap: var(--e5);
}
.contact-grille { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); align-items: start; }

/* ─── La carte, forme commune ───
   Une seule règle porte le carton : bord fin, angle arrondi, fond
   blanc sur le crème et charbon dans un pavé noir. Tout ce qui
   ressemble à une fiche la partage, ce qui évite trente variantes
   qui divergent au premier ajustement. */
/* `.avis-texte` n'est plus de la liste : la fiche d'avis est
   elle-même une carte depuis qu'elle a sa propre règle, et le
   paragraphe se retrouvait encadré À L'INTÉRIEUR d'elle — une boîte
   dans une boîte, que rien ne justifie. */
.cas-carte, .rythme-etape, .mesure, .membre, .lieu, .temoignage,
.cote-bloc, .legal-sommaire, .panneau,
.galerie-fenetre, .geo-texte, .billet--une {
  border: 1px solid var(--trait);
  border-radius: var(--r3);
  background: var(--carte);
  padding: var(--e5);
}

.cas-quand, .rythme-quand, .membre-role, .lieu-quoi, .temoignage-role,
.mesure-base, .avis-note, .galerie-compte, .galerie-note {
  font-size: var(--p-5);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--or-lisible);
}
.plage.plan-contre .cas-quand, .plage.plan-contre .rythme-quand,
.plage.plan-contre .membre-role, .plage.plan-contre .temoignage-role { color: var(--or); }

/* `.geo-titre` et `.cote-titre` portent déjà `.t1` ou `.t2` dans le
   HTML : les inclure ici ramenait un titre de cinquante pixels à
   vingt-trois, et l'or des grands titres y devenait illisible. Une
   règle d'habillage ne redéfinit pas une échelle typographique. */
.cas-nom, .rythme-nom, .mesure-nom, .membre-nom, .temoignage-nom,
.onglet-nom {
  font-size: var(--t5); font-weight: 500; margin-top: 6px;
}
.cas-quoi, .rythme-quoi, .membre-quoi, .lieu-adresse, .cote-quoi,
.temoignage-texte, .avis-texte p, .geo-texte p, .legal-texte {
  margin-top: var(--e3); font-size: var(--p-4); color: var(--encre-3);
}
.plage.plan-contre .cas-quoi, .plage.plan-contre .rythme-quoi,
.plage.plan-contre .membre-quoi, .plage.plan-contre .temoignage-texte { color: var(--sur-noir-2); }
.cas-mix, .membre-outils, .membre-tete { margin-top: var(--e3); font-size: var(--p-5); color: var(--encre-3); }

/* Chiffre, nom, base : trois lignes, dans cet ordre. Les trois
   étaient des `<span>` — donc en ligne — et se lisaient « 80 Missions
   livrées depuis la création du studio », une phrase où le nombre
   n'est plus un nombre mais un adjectif. */
.mesure { display: grid; align-content: start; gap: 6px; }
.mesure-valeur {
  display: block;
  font-size: var(--t2);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--encre);
}
.mesure-nom { display: block; font-size: var(--p); font-weight: 500; margin-top: 4px; }
.mesure-base { display: block; font-size: var(--p-5); line-height: 1.5; text-transform: none; letter-spacing: 0; }
.mesure-valeur--hausse { color: var(--or-lisible); }
.plage.plan-contre .mesure-valeur--hausse { color: var(--or); }

/* ─── Le plan doré ─── */
.plan-or {
  background: linear-gradient(160deg, #FFF6DA 0%, #FDE9A8 48%, #F7D775 100%);
  border-radius: var(--r5);
  padding: var(--e8) var(--e7);
  margin-block: var(--e8);
}
.plan-or .donnee { color: rgba(0,0,0,0.55); }

/* ─── La galerie horizontale ───
   La première version de ces règles supposait une structure et le
   HTML en avait une autre : `.galerie-jauge` n'est pas la barre mais
   la LIGNE qui la contient — le compteur, le rail, la mention. Peinte
   en or, elle mettait un libellé gris sur un aplat doré : 1,62:1.
   On relit le HTML, on ne le devine pas. */
.galerie-fenetre { padding: 0; overflow: hidden; }
.galerie-piste {
  display: flex;
  gap: var(--e4);
  overflow-x: auto;
  padding: var(--e4);
  scrollbar-width: none;
  scroll-snap-type: x proximity;
  align-items: stretch;
}
.galerie-piste::-webkit-scrollbar { display: none; }
.galerie-piste > * { flex: 0 0 clamp(240px, 30vw, 400px); scroll-snap-align: start; }

.galerie-jauge {
  margin-top: var(--e4);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--e4);
}
.galerie-rail { display: block; height: 2px; border-radius: 2px; background: var(--trait); overflow: hidden; }
.galerie-fil { display: block; height: 100%; background: var(--or); transform-origin: left; transform: scaleX(0.12); }

/* ─── Les onglets ─── */
.onglets { display: flex; flex-wrap: wrap; gap: var(--e2); margin-bottom: var(--e5); }
.onglet {
  padding: 9px 16px;
  border: 1px solid var(--trait);
  border-radius: var(--r7);
  background: var(--carte);
  font-size: var(--p-4);
}
.onglet[aria-selected="true"], .onglet.est-actif {
  /* Les jetons basculent avec le fond, sinon le libellé technique
     qu'il contient garde son gris de texte clair : 3,04:1 sur noir. */
  --encre-3: var(--sur-noir-2);
  --or-lisible: var(--or);
  background: var(--noir);
  color: var(--sur-noir);
  border-color: var(--noir);
}

/* ─── Les formulaires des pages ─── */
.formulaire-titre { font-size: var(--t3); font-weight: 500; }
.formulaire-mention { font-size: var(--p-5); color: var(--encre-3); }
.champ--large { grid-column: 1 / -1; }
.requis { color: var(--or-lisible); }
.contact-cote, .cote-bloc { display: grid; gap: var(--e3); align-content: start; }
.cote-ligne { display: flex; justify-content: space-between; gap: var(--e3); font-size: var(--p-4); }
.cote-mail { font-weight: 500; }
.cote-dispo { display: inline-flex; align-items: center; gap: 8px; font-size: var(--p-4); }
.cote-pastille { width: 8px; height: 8px; border-radius: 50%; background: #2FBF71; }

/* ─── Le brief ─── */
.brief-echappatoire { margin-top: var(--e5); font-size: var(--p-4); color: var(--encre-3); }

/* ─── Les avis et le mur ─── */
.avis-pied { margin-top: var(--e4); display: flex; align-items: center; gap: 10px; font-size: var(--p-4); }

/* ─── LE MUR D'AVIS, COPIÉ DE /audit ───
   Trois colonnes qui défilent verticalement, celle du milieu à
   contresens. Valeurs relevées dans css/audit.css, pas approchées :
   hauteur 580, écart 18, durées 48, 58 et 52 secondes, masque qui
   estompe sur 9 % en haut et en bas.

   Trois durées DIFFÉRENTES et un sens inversé au milieu : à vitesse
   égale, les trois colonnes défileraient comme un seul bloc et le mur
   ressemblerait à une page qui glisse, pas à un mur vivant.

   Chaque piste contient ses cartes deux fois et se translate de la
   moitié de sa hauteur : à l'instant où la seconde moitié atteint le
   départ de la première, l'image est identique — la boucle ne se voit
   pas. */
.avis-mur {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  height: 580px;
  margin-top: var(--e6);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 91%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 91%, transparent 100%);
}
.avis-colonne { overflow: hidden; }
.avis-piste { display: flex; flex-direction: column; gap: 18px; will-change: transform; }
.avis-mur [data-avis-col="0"] .avis-piste { animation: avis-monte 48s linear infinite; }
.avis-mur [data-avis-col="1"] .avis-piste { animation: avis-descend 58s linear infinite; }
.avis-mur [data-avis-col="2"] .avis-piste { animation: avis-monte 52s linear infinite; }
.avis-mur:hover .avis-piste { animation-play-state: paused; }
@keyframes avis-monte   { from { transform: translateY(0); }    to { transform: translateY(-50%); } }
@keyframes avis-descend { from { transform: translateY(-50%); } to { transform: translateY(0); } }

@media (max-width: 980px) {
  .avis-mur { grid-template-columns: repeat(2, 1fr); height: 520px; }
  .avis-mur [data-avis-col="2"] { display: none; }
}
@media (max-width: 640px) {
  .avis-mur { grid-template-columns: 1fr; height: 460px; }
  .avis-mur [data-avis-col="1"] { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  /* Sans mouvement, un mur qui ne défile pas doit au moins se lire :
     on le laisse grandir et on retire le masque. */
  .avis-mur { height: auto; mask-image: none; -webkit-mask-image: none; }
  .avis-piste { animation: none; }
  .avis-piste > :nth-child(n + 5) { display: none; }
}
.avis-tous { margin-top: var(--e5); display: flex; justify-content: center; }

/* ═══════════════════════════════════════════════════════════════
   LES PAGES LÉGALES

   Trois pages de texte pur — mentions, CGV, confidentialité — dont
   les CGV font trente-cinq mille pixels de haut. Elles héritaient de
   la grille générique : deux colonnes d'égale largeur, donc une
   colonne de lecture de trois cent quatre-vingts pixels pendant que
   la moitié droite de l'écran restait vide, et des titres plus larges
   que leur propre colonne.

   Ce qu'il leur faut n'est pas une grille de cartes mais une mise en
   page de document : un sommaire étroit qui suit le lecteur, une
   colonne de lecture d'environ soixante-dix signes — au-delà, l'œil
   perd la ligne suivante en revenant à la marge — et un rythme qui
   fasse voir la structure sans qu'on ait à la chercher.
   ═══════════════════════════════════════════════════════════════ */
.legal-plan { padding-block: var(--e8); }
.legal-grille {
  display: grid;
  grid-template-columns: 250px minmax(0, 72ch);
  gap: var(--e9);
  align-items: start;
  justify-content: center;
}

/* ─── Le sommaire ─── */
.legal-sommaire {
  position: sticky;
  top: 110px;
  padding: var(--e5);
  border: 1px solid var(--trait);
  border-radius: var(--r3);
  background: var(--carte);
  /* Une table des matières plus haute que l'écran ne sert plus à
     rien : elle défile avec elle-même. */
  max-height: calc(100vh - 150px);
  overflow-y: auto;
}
.legal-sommaire > .donnee { margin-bottom: var(--e4); }
.legal-sommaire nav { display: grid; gap: 2px; }
.legal-sommaire nav a {
  padding: 7px 10px;
  border-radius: 8px;
  font-size: var(--p-4);
  line-height: 1.35;
  color: var(--encre-3);
  transition: background var(--net) ease, color var(--net) ease;
}
.legal-sommaire nav a:hover { background: rgba(0, 0, 0, 0.05); color: var(--encre); }
.legal-aide {
  margin-top: var(--e5);
  padding-top: var(--e4);
  border-top: 1px solid var(--trait-fin);
  font-size: var(--p-5);
  line-height: 1.5;
  color: var(--encre-3);
}

/* ─── Le corps du document ─── */
.legal-texte { font-size: var(--p-2); line-height: 1.7; color: var(--encre-2); }
.legal-texte > section + section {
  margin-top: var(--e8);
  padding-top: var(--e7);
  border-top: 1px solid var(--trait);
}
/* Le numéro de section, en surtitre doré : c'est lui qui donne au
   lecteur sa position dans un document de quinze chapitres. */
.legal-num {
  display: block;
  font-size: var(--p-5);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--or-lisible);
}
.legal-texte h2 {
  margin-top: 6px;
  font-size: var(--t3);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--encre);
}
.legal-texte h3 {
  margin-top: var(--e6);
  font-size: var(--t5);
  font-weight: 500;
  color: var(--encre);
}
.legal-texte p { margin-top: var(--e4); }
.legal-texte ul, .legal-texte ol {
  margin-top: var(--e4);
  padding-left: 1.15em;
  list-style: disc;
  display: grid;
  gap: 8px;
}
.legal-texte ol { list-style: decimal; }
.legal-texte li::marker { color: var(--or-lisible); }
.legal-texte strong { color: var(--encre); font-weight: 600; }
.legal-texte a { color: var(--or-lisible); text-decoration: underline; text-underline-offset: 3px; }
.legal-texte table { width: 100%; border-collapse: collapse; margin-top: var(--e4); font-size: var(--p-4); }
.legal-texte th, .legal-texte td { padding: 10px 12px; border: 1px solid var(--trait); text-align: left; }
.legal-texte th { background: rgba(0, 0, 0, 0.04); font-weight: 500; }

/* La navigation entre les trois documents, sous le titre. */
.legal-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  justify-content: center;
  margin-top: var(--e5);
}
.legal-nav a {
  padding: 9px 16px;
  border: 1px solid var(--trait);
  border-radius: var(--r7);
  background: var(--carte);
  font-size: var(--p-4);
  transition: background var(--net) ease, color var(--net) ease, border-color var(--net) ease;
}
.legal-nav a:hover { background: var(--noir); color: var(--sur-noir); border-color: var(--noir); }

@media (max-width: 1100px) {
  .legal-grille { grid-template-columns: minmax(0, 1fr); gap: var(--e6); }
  /* Sur une colonne, un sommaire collant mangerait la moitié de
     l'écran : il se replie au-dessus du texte, une fois pour toutes. */
  .legal-sommaire { position: static; max-height: none; }
  .legal-sommaire nav { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
}
@media (max-width: 620px) {
  .legal-texte > section + section { margin-top: var(--e7); padding-top: var(--e6); }
}

/* ─── Les vitrines de référence des pages métier ─── */
.vitrine--lien { display: grid; gap: var(--e4); }
.reference-cadre { position: relative; border-radius: var(--r4); overflow: hidden; border: 1px solid var(--trait); }
.reference-cadre img { width: 100%; max-height: 620px; object-fit: cover; object-position: top; }
.reference-adresse {
  position: absolute;
  top: var(--e3); left: var(--e3);
  z-index: 1;
  padding: 5px 10px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.66);
  color: #fff;
  font-size: var(--p-5);
}
.vitrine-texte { display: grid; gap: 6px; }
.formule--marquee { border-color: var(--or); }
.billet--une { padding: 0; }
.suite-lien--apres { justify-self: end; text-align: right; }
.lieu-plan, .lieu-lire { font-size: var(--p-4); color: var(--or-lisible); }

@media (max-width: 900px) {
  .contact-grille, .legal-plan { grid-template-columns: 1fr; }
  .legal-nav { position: static; }
}
.temoignage-qui { margin-top: var(--e4); display: flex; align-items: center; gap: 10px; font-size: var(--p-4); }
.rythme { display: grid; gap: var(--e4); margin-top: var(--e5); }

/* ═══════════════════════════════════════════════════════════════
   L'ESPACE CLIENT

   Écran d'application, pas page de site : ni barre ni pied. La
   composition est relevée sur app.clickway.fr/login — fond #0A0A0A,
   mosaïque de sites livrés assombrie derrière, carte de verre de 360
   de large à 28 de rayon, bouton or en gélule.
   ═══════════════════════════════════════════════════════════════ */
.ecran { background: #0A0A0A; color: #fff; }
.ecran-fond {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: var(--e6) var(--e4);
  overflow: hidden;
}

/* La mosaïque : neuf captures en grille, très assombries. Elles ne
   se regardent pas, elles occupent le fond — c'est la seule raison
   pour laquelle un écran de connexion n'est pas un rectangle vide. */
.mosaique {
  position: absolute;
  inset: -4%;
  z-index: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  pointer-events: none;
}
.mosaique img {
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: 14px;
  opacity: 0.14;
  filter: grayscale(0.25);
}
/* Le voile qui éteint le centre, pour que la carte s'en détache. */
.ecran-fond::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(60% 55% at 50% 50%, rgba(10,10,10,0.96) 0%, rgba(10,10,10,0.72) 55%, rgba(10,10,10,0.55) 100%),
    linear-gradient(180deg, rgba(10,10,10,0.5), rgba(10,10,10,0.5));
  pointer-events: none;
}

.porte { position: relative; z-index: 2; display: grid; justify-items: center; gap: var(--e5); }

.porte-carte {
  /* Les mesures du modèle, au pixel : carte de 360 de large,
     rembourrage 40/32/32, ce qui laisse 296 au contenu — les champs y
     font 294 chez lui. */
  width: 360px;
  max-width: 100%;
  padding: 40px 32px 32px;
  border-radius: 28px;
  background: rgba(13, 13, 13, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.05);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  text-align: center;
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.9);
}
/* LE RYTHME VERTICAL DU MODÈLE, RELEVÉ LIGNE À LIGNE dans sa carte
   de 360 sur 473 :

     40  rembourrage haut
     28  le logo
     32  jusqu'au titre
     55  le titre, deux lignes
      8  jusqu'au sous-titre
     20  le sous-titre
     61  jusqu'au formulaire
     17  l'étiquette
      5  jusqu'au champ
     50  le champ
     16  jusqu'au bouton
     48  le bouton
     15  jusqu'au lien d'aide
     44  le lien d'aide
     32  rembourrage bas

   Somme : 471. Sa carte en fait 473 — deux pixels d'arrondi. */
.porte-marque { display: block; height: 28px; margin: 0 auto 32px; }
.porte-marque svg { height: 100%; width: auto; display: block; margin: 0 auto; overflow: visible; }
/* La rotation de 45° vit en CSS depuis qu'elle doit pouvoir être
   animée dans la barre. Cet écran-ci ne l'avait pas : le losange y
   était un carré posé à plat, et le logo n'était plus le logo. */
.porte-losange {
  stroke: #fff;
  transform-box: fill-box;
  transform-origin: 50% 50%;
  transform: rotate(45deg);
}
.porte-etincelle { fill: var(--or); }
.porte-mot { fill: #fff; font-family: 'Questrial', system-ui, sans-serif; }

.porte-titre { font-size: 1.4rem; font-weight: 500; line-height: 1.28; letter-spacing: -0.02em; }
/* LES OPACITÉS DU MODÈLE NE PASSENT PAS LE SEUIL AA.

   Mesurées sur son fond de carte composé (#0D0D0D à 85 % sur
   #0A0A0A, soit un gris 12,5) :

     blanc à 0,40 → 3,80:1   sous-titre
     blanc à 0,35 → 3,17:1   étiquettes et lien d'aide
     blanc à 0,20 → 1,77:1   la ligne du bas

   Le seuil est 4,5 pour du texte de cette taille, et c'est atteint à
   0,45. Les valeurs ci-dessous sont donc les plus proches de celles
   du modèle qui restent lisibles — la hiérarchie entre les trois
   niveaux est conservée, seul le plancher remonte. */
.porte-sous { margin-top: 8px; font-size: 13px; color: rgba(255, 255, 255, 0.62); }

.porte-form { margin-top: 61px; display: grid; gap: 16px; text-align: left; }
.porte-champ { display: grid; gap: 5px; }
.porte-champ label {
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.55);
}
.porte-champ input {
  font: inherit;
  font-size: var(--p-4);
  height: 50px;
  padding: 0 15px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.06);
  color: #fff;
}
.porte-champ input::placeholder { color: rgba(255, 255, 255, 0.45); }
.porte-champ input:focus-visible { border-color: rgba(209, 163, 38, 0.55); outline: none; }

.porte-bouton {
  height: 48px;
  border-radius: 9999px;
  background: var(--or);
  color: #0A0A0A;
  font-size: var(--p-4);
  font-weight: 600;
  transition: filter var(--pose) ease, transform var(--pose) var(--ressort);
}
.porte-bouton:hover { filter: brightness(1.06); transform: translateY(-1px); }
.porte-bouton:disabled { opacity: 0.55; cursor: default; transform: none; }

.porte-aide {
  margin-top: -1px;
  justify-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Quarante-quatre pixels de haut chez le modèle, et ce n'est pas
     un hasard d'espacement : c'est la taille minimale d'une cible
     tactile. Mon lien n'en faisait que quinze — lisible à la souris,
     pénible au doigt. */
  min-height: 44px;
  gap: 7px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.55);
  transition: color var(--pose) ease;
}
.porte-aide svg { width: 14px; height: 14px; }
.porte-aide:hover { color: rgba(255, 255, 255, 0.9); }

.porte-erreur, .porte-info {
  font-size: 12px;
  padding: 10px 13px;
  border-radius: 10px;
  text-align: center;
}
.porte-erreur { background: rgba(192, 86, 62, 0.16); color: #FFB4A0; }
.porte-info { background: rgba(209, 163, 38, 0.14); color: #F0D289; }

.porte-pied {
  position: relative;
  z-index: 2;
  font-size: 11px;
  /* Cette ligne-ci est posée sur le fond de la page, plus sombre que
     la carte : il lui faut donc un peu plus. */
  color: rgba(255, 255, 255, 0.52);
}

/* ─── Le tableau, une fois la session ouverte ─── */
.client-tableau {
  position: relative;
  z-index: 2;
  width: 100%;
  align-self: start;
  padding-block: var(--e8);
}
.client-tete {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e4);
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: var(--e7);
}
.client-tableau .eyebrow { color: rgba(255, 255, 255, 0.4); }
.client-titre { font-size: var(--t3); font-weight: 500; margin-top: var(--e3); }
.client-tableau .bouton-fin {
  --fond-bouton: rgba(255, 255, 255, 0.06);
  --encre-bouton: #fff;
  --trait-bouton: rgba(255, 255, 255, 0.16);
  box-shadow: none;
}
.client-grille { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e5); }
.client-bloc {
  padding: var(--e6);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
}
.client-bloc-titre { font-size: var(--t5); font-weight: 500; margin-bottom: var(--e4); color: #fff; }
.client-liste { display: grid; gap: 10px; }
.client-ligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e4);
  padding: 13px 16px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
}
.client-ligne-nom { font-size: var(--p-4); font-weight: 500; }
.client-ligne-detail { margin-top: 2px; font-size: 12px; color: rgba(255, 255, 255, 0.45); }
.client-vide { font-size: var(--p-4); color: rgba(255, 255, 255, 0.35); }
.client-jeton {
  flex: none;
  padding: 5px 11px;
  border-radius: 9999px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.75);
}
.client-jeton.est-fait   { background: rgba(47, 191, 113, 0.16); color: #8FE3B4; }
.client-jeton.est-cours  { background: rgba(209, 163, 38, 0.18); color: #F0D289; }
.client-jeton.est-alerte { background: rgba(192, 86, 62, 0.18); color: #FFB4A0; }

@media (max-width: 900px) {
  .mosaique { grid-template-columns: repeat(2, 1fr); }
  .client-grille { grid-template-columns: 1fr; }
}


/* ═══════════════════════════════════════════════════════════════
   LE QUESTIONNAIRE DE BRIEF

   Treize questions posées une à une. Le composant vient de la version
   précédente et son habillage n'avait pas été repris : la barre
   d'avancement, l'intitulé, l'indice et les quatre réponses tombaient
   les uns derrière les autres en un seul paragraphe, et les boutons
   ressemblaient à du texte. Il restait fonctionnel — c'est bien le
   pire, on ne le voyait pas dans le HTML.

   Rien ici ne touche au comportement : le module continue de tout
   piloter, on ne fait que lui donner une forme.
   ═══════════════════════════════════════════════════════════════ */
.brief-carte {
  margin-top: var(--e6);
  padding: var(--e7);
  border: 1px solid var(--trait);
  border-radius: var(--r4);
  background: var(--carte);
  box-shadow:
    0 1px 2px rgba(16, 49, 77, 0.04),
    0 24px 48px -34px rgba(16, 49, 77, 0.22);
}

/* ─── L'avancement ─── */
.wizard-progress { display: grid; gap: 10px; margin-bottom: var(--e6); }
.wizard-progress-bar {
  order: 2;
  height: 3px;
  border-radius: 3px;
  background: var(--trait);
  overflow: hidden;
}
.wizard-progress-fill {
  display: block;
  height: 100%;
  background: var(--or);
  border-radius: inherit;
  transition: width var(--ample) var(--ressort);
}
.wizard-step-counter {
  order: 1;
  font-size: var(--p-5);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--encre-3);
}

/* ─── LE PASSAGE D'UNE QUESTION À L'AUTRE ──────────────────────
   Le module garde les DEUX étapes dans le document pendant trois cent
   vingt millisecondes : la sortante porte `is-leaving-*` jusqu'à son
   retrait, l'entrante arrive derrière. Aucune règle v4 ne traitait ces
   états — les deux questions restaient donc dans le flux, la carte
   doublait de hauteur puis se rétractait d'un coup. C'est la question
   « qui s'affiche puis s'enlève ».

   La sortante est donc SORTIE DU FLUX le temps de s'effacer : elle
   glisse et s'éteint par-dessus, sans rien pousser. L'entrante seule
   dicte la hauteur.

   Le sens du glissement suit celui du parcours — vers la gauche quand
   on avance, vers la droite quand on revient — pour que le mouvement
   dise dans quelle direction on va. */
.wizard-stage { position: relative; }
.wizard-step {
  transition: opacity 240ms ease, transform 320ms var(--ressort);
}
.wizard-step.is-entering-next { opacity: 0; transform: translateX(26px); }
.wizard-step.is-entering-prev { opacity: 0; transform: translateX(-26px); }
.wizard-step.is-in { opacity: 1; transform: none; }
.wizard-step.is-leaving-next,
.wizard-step.is-leaving-prev {
  position: absolute;
  inset: 0 0 auto 0;
  opacity: 0;
  pointer-events: none;
}
.wizard-step.is-leaving-next { transform: translateX(-26px); }
.wizard-step.is-leaving-prev { transform: translateX(26px); }

@media (prefers-reduced-motion: reduce) {
  .wizard-step { transition: none; }
  .wizard-step.is-entering-next, .wizard-step.is-entering-prev { opacity: 1; transform: none; }
}
.wizard-step-head { display: grid; gap: 8px; margin-bottom: var(--e5); }
.wizard-step-icon { width: 26px; height: 26px; color: var(--or-lisible); }
.wizard-step-icon svg { width: 100%; height: 100%; }
.wizard-step-label {
  font-size: var(--t5);
  font-weight: 500;
  line-height: 1.25;
  color: var(--encre);
}
.wizard-step-hint { font-size: var(--p-4); color: var(--encre-3); }
.wizard-required { color: var(--or-lisible); }

/* ─── Les réponses ───
   Une réponse est une CIBLE, pas une ligne de texte : elle occupe
   une carte entière, et le bouton radio natif est masqué au profit
   du point dessiné — le natif ne se met pas à la taille du doigt. */
.wizard-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: var(--e3);
}
.wizard-card {
  position: relative;
  display: grid;
  grid-template-columns: 20px 1fr;
  gap: var(--e3);
  align-items: start;
  padding: var(--e4) var(--e5);
  border: 1px solid var(--trait);
  border-radius: var(--r3);
  background: var(--fond);
  cursor: pointer;
  transition: border-color var(--net) ease, background var(--net) ease, transform var(--pose) var(--ressort);
}
.wizard-card:hover { border-color: rgba(0, 0, 0, 0.24); transform: translateY(-2px); }
.wizard-card input { position: absolute; opacity: 0; width: 0; height: 0; }
.wizard-card-dot {
  width: 18px; height: 18px;
  margin-top: 2px;
  border-radius: 50%;
  border: 2px solid var(--trait);
  display: grid;
  place-items: center;
  transition: border-color var(--net) ease;
}
.wizard-card-dot::after {
  content: '';
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--or);
  transform: scale(0);
  transition: transform var(--pose) var(--ressort);
}
.wizard-card:has(input:checked) { border-color: var(--or); background: #FFFCF2; }
.wizard-card:has(input:checked) .wizard-card-dot { border-color: var(--or); }
.wizard-card:has(input:checked) .wizard-card-dot::after { transform: scale(1); }
.wizard-card:has(input:focus-visible) { outline: 2px solid var(--or-lisible); outline-offset: 3px; }
.wizard-card-content { display: grid; gap: 3px; }
.wizard-card-label { font-size: var(--p-2); font-weight: 500; color: var(--encre); }
.wizard-card-desc { font-size: var(--p-4); color: var(--encre-3); line-height: 1.5; }

/* ─── Les champs libres des étapes suivantes ─── */
.wizard-step input[type="text"], .wizard-step input[type="email"],
.wizard-step input[type="tel"], .wizard-step input[type="url"],
.wizard-step textarea, .wizard-step select {
  font: inherit;
  width: 100%;
  font-size: var(--p-2);
  padding: 13px 15px;
  border: 1px solid var(--trait);
  border-radius: var(--r2);
  background: var(--fond);
  color: var(--encre);
}
.wizard-step textarea { min-height: 120px; resize: vertical; }

/* ─── La navigation ─── */
.wizard-nav {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--e4);
  margin-top: var(--e6);
  padding-top: var(--e5);
  border-top: 1px solid var(--trait-fin);
}
.wizard-prev, .wizard-next {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px;
  border-radius: var(--r2);
  font-size: var(--p-4);
  font-weight: 500;
  transition: transform var(--pose) var(--ressort), opacity var(--net) ease;
}
.wizard-prev { border: 1px dashed var(--trait); color: var(--encre-3); }
.wizard-prev:hover { color: var(--encre); transform: translateX(-2px); }
.wizard-prev[disabled], .wizard-prev[hidden] { opacity: 0.35; pointer-events: none; }
.wizard-prev svg { width: 14px; height: 14px; }
.wizard-next {
  background: var(--noir);
  color: var(--sur-noir);
  border: 1px dashed rgba(255, 255, 255, 0.45);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--p-5);
  padding: 13px 20px;
}
.wizard-next:hover { transform: translateY(-2px); }
.wizard-nav-msg { display: grid; gap: 3px; justify-items: center; text-align: center; }
.wizard-privacy {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--p-5);
  color: var(--encre-3);
}
.wizard-privacy svg { width: 13px; height: 13px; flex: none; }
.wizard-status { font-size: var(--p-5); color: var(--or-lisible); min-height: 1em; }

@media (max-width: 700px) {
  .brief-carte { padding: var(--e5); }
  .wizard-nav { grid-template-columns: 1fr 1fr; row-gap: var(--e3); }
  .wizard-nav-msg { grid-column: 1 / -1; order: 3; }
}

