/* La sous-navigation collante (.secnav) a été retirée le 26/07/2026 :
   elle doublait le menu principal, mangeait 56 px de haut en permanence
   sur mobile, et n'existait que sur 4 pages sur 9 — donc inconstante. */

@import url('fonts.css');

/* =========================================================================
   RÉPARE TA POMME — « L'Atelier »
   Charte : ../../DESIGN.md   ·   Contrastes : node tools/contrast.mjs
   ========================================================================= */

/* --- 1. Tokens ---------------------------------------------------------- */
:root {
  /* Établi — le tapis antistatique bleu */
  --bench-950: oklch(0.155 0.028 236);
  --bench-900: oklch(0.196 0.034 236);
  --bench-850: oklch(0.238 0.040 235);
  --bench-800: oklch(0.283 0.046 234);
  --bench-700: oklch(0.360 0.052 232);
  --bench-600: oklch(0.482 0.048 231);
  --bench-400: oklch(0.680 0.036 231);
  --bench-300: oklch(0.786 0.028 231);
  --bench-200: oklch(0.882 0.016 233);
  --bench-100: oklch(0.930 0.010 234);

  /* Papier — neutre froid, teinté vers la marque, jamais crème */
  --sheet:     oklch(0.981 0.004 235);
  --sheet-2:   oklch(0.955 0.007 235);
  /* Surface intermédiaire de la passe « premium ». Elle remplace le gris
     d'apple.fr (f5-f5-f7), qui était codé en dur 15 fois et que PRODUCT.md
     exclut nommément : même clarté, mais teinté vers le bleu de marque
     plutôt que vers le neutre froid d'Apple. 15,9:1 sur --ink. */
  --sheet-3:   oklch(0.966 0.005 235);   /* #f1f4f7 */
  --sheet-3-rgb: 241 244 247;            /* pour les dégradés translucides */
  --ink:       oklch(0.215 0.026 240);
  --ink-soft:  oklch(0.455 0.022 240);

  /* Ambre — couleur d'action de la marque */
  --flux:      oklch(0.795 0.150 72);
  --flux-deep: oklch(0.700 0.150 62);
  --flux-ink:  oklch(0.505 0.125 55);

  /* Signal dégât liquide */
  --alert:     oklch(0.640 0.195 27);
  --alert-ink: oklch(0.505 0.185 27);

  /* Rôles contextuels — réassignés par .on-dark / .on-light */
  --bg: var(--sheet);
  --fg: var(--ink);
  --fg-soft: var(--ink-soft);
  --rule: var(--bench-100);
  --accent: var(--flux-ink);

  /* Typographie */
  --font-display: 'Bricolage Grotesque', 'Trebuchet MS', system-ui, sans-serif;
  --font-body: 'Public Sans', system-ui, -apple-system, sans-serif;

  --fs-xs: 0.8125rem;
  --fs-sm: 0.9375rem;
  --fs-base: 1.0625rem;
  --fs-lg: 1.1875rem;
  --fs-xl: 1.375rem;
  --fs-h4: clamp(1.3rem, 1.1rem + 0.85vw, 1.6rem);
  --fs-h3: clamp(1.6rem, 1.25rem + 1.5vw, 2.25rem);
  --fs-h2: clamp(2.1rem, 1.45rem + 2.8vw, 3.5rem);
  --fs-h1: clamp(2.7rem, 1.7rem + 4.5vw, 4.75rem);
  --fs-hero: clamp(3.1rem, 1.7rem + 6.4vw, 5.9rem);

  /* Espace */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-5: 1.5rem;   --sp-6: 2rem;     --sp-7: 2.75rem;  --sp-8: 4rem;
  --sp-9: 6rem;
  --sp-section: clamp(5rem, 3.4rem + 6.6vw, 10.5rem);
  --sp-chapter: clamp(6rem, 4rem + 8vw, 13rem);
  --gutter: clamp(1.25rem, 0.6rem + 2.6vw, 3rem);
  --measure: 42rem;      /* ~68ch en rem : constant quel que soit le corps */
  --measure-tight: 34rem;
  --shell: 78rem;

  /* Forme */
  --r-sm: 6px; --r-md: 12px; --r-lg: 22px; --r-xl: 34px; --r-pill: 980px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 420ms;

  /* Plans — l'échelle complète, du fond vers l'avant. Elle vivait en trois
     morceaux dans la feuille (ici, §32 pour la progression, §60 pour le
     dock) ; regroupée, on voit d'un coup qui passe devant qui. */
  --z-grid: 0;
  --z-sticky: 20;        /* sous-nav collante */
  --z-header: 30;
  --z-progress: 35;      /* barre de lecture */
  --z-fab-scrim: 44;     /* voile derrière la feuille de canaux */
  --z-fab: 46;           /* dock Appeler / Message */
  --z-dialog: 50;
}

/* --- 2. Reset ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* en-tete 4,5rem + sous-navigation ~3,2rem : sinon l'ancre passe dessous. */
  scroll-padding-top: 8.5rem;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.62;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, svg, video { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

/* Le « premium » tient au poids, pas a la taille : 700 en chasse etroite
   donnait une affiche, 600 en chasse pleine donne un titre. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.07;
  letter-spacing: -0.026em;
  text-wrap: balance;
  font-variation-settings: 'wdth' 100, 'opsz' 48;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); letter-spacing: -0.02em; }
h4 { font-size: var(--fs-h4); letter-spacing: -0.015em; font-weight: 600; }

p, li { text-wrap: pretty; }
p { max-width: var(--measure); }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
a:hover { text-decoration-color: var(--accent); }

/* Motif progressif : le focus est visible par défaut, puis retiré uniquement
   là où le navigateur sait qu'il s'agit d'un pointeur. Sur un navigateur sans
   :focus-visible, on garde un anneau plutôt que rien. */
:focus {
  outline: 3px solid var(--flux);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }
:focus-visible {
  outline: 3px solid var(--flux);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection { background: var(--flux); color: var(--bench-950); }

/* --- 3. Contextes clair / sombre --------------------------------------- */
.on-dark {
  --bg: var(--bench-950);
  --fg: var(--bench-200);
  --fg-soft: var(--bench-400);
  --rule: color-mix(in oklch, var(--bench-600) 55%, transparent);
  --accent: var(--flux);
  background: var(--bg);
  color: var(--fg);
}
.on-dark h1, .on-dark h2, .on-dark h3, .on-dark h4 { color: #fff; }

/* Règle de l'îlot : une carte claire posée sur du sombre reprend l'encre sombre */
.on-dark .island,
.on-light {
  --bg: var(--sheet);
  --fg: var(--ink);
  --fg-soft: var(--ink-soft);
  --rule: var(--bench-100);
  --accent: var(--flux-ink);
  background: var(--bg);
  color: var(--fg);
}
.on-dark .island h1, .on-dark .island h2,
.on-dark .island h3, .on-dark .island h4,
.on-light h1, .on-light h2, .on-light h3, .on-light h4 { color: var(--ink); }

/* --- 4. Grille d'établi ------------------------------------------------- */
.bench-grid { position: relative; isolation: isolate; }
.bench-grid::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: var(--z-grid);
  pointer-events: none;
  background-image:
    linear-gradient(to right, color-mix(in oklch, var(--bench-700) 40%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in oklch, var(--bench-700) 40%, transparent) 1px, transparent 1px),
    linear-gradient(to right, color-mix(in oklch, var(--bench-700) 72%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in oklch, var(--bench-700) 72%, transparent) 1px, transparent 1px);
  background-size: 24px 24px, 24px 24px, 120px 120px, 120px 120px;
  mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
  opacity: 0.55;
}
.bench-grid > * { position: relative; z-index: 1; }

/* --- 5. Structure ------------------------------------------------------- */
.shell {
  width: min(100% - var(--gutter) * 2, var(--shell));
  margin-inline: auto;
}
.shell--narrow { width: min(100% - var(--gutter) * 2, 54rem); }

.section { padding-block: var(--sp-section); }
.section--tight { padding-block: clamp(2.75rem, 2rem + 3vw, 5rem); }

.skip-link {
  position: absolute;
  left: var(--sp-4); top: var(--sp-4);
  z-index: var(--z-dialog);
  padding: var(--sp-3) var(--sp-5);
  background: var(--flux);
  color: var(--bench-950);
  font-weight: 700;
  border-radius: var(--r-md);
  transform: translateY(-160%);
  transition: transform 180ms var(--ease);
}
.skip-link:focus-visible { transform: translateY(0); }

/* --- 6. En-tête --------------------------------------------------------- */
/* Le fond flouté vit sur un pseudo-élément, PAS sur .header : backdrop-filter
   ferait de l'en-tête un bloc conteneur pour ses descendants position:fixed,
   ce qui écrasait le panneau du menu mobile à la hauteur de l'en-tête. */
.header {
  position: sticky; top: 0;
  z-index: var(--z-header);
  /* .on-dark poserait un fond opaque et masquerait le ::before flouté. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: border-color 260ms var(--ease);
}
.header::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in oklch, var(--bench-950) 82%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  transition: background 260ms var(--ease);
}
.header[data-scrolled='true']::before {
  background: color-mix(in oklch, var(--bench-950) 97%, transparent);
}
.header[data-scrolled='true'] {
  border-bottom-color: color-mix(in oklch, var(--flux) 34%, transparent);
}
.header__inner {
  display: flex; align-items: center; gap: var(--sp-5);
  min-height: 4.5rem;
}

.brand { display: flex; align-items: center; gap: 0.7rem; min-height: 2.75rem; text-decoration: none; flex: none; }
.brand__mark { flex: none; }
.brand__name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.0625rem;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: #fff;
  font-variation-settings: 'wdth' 88;
}
.brand__name span { display: block; font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.06em; color: var(--flux); text-transform: uppercase; font-family: var(--font-body); }

.nav { margin-left: auto; }
.nav__list { display: flex; align-items: center; gap: clamp(0.5rem, 1.4vw, 1.5rem); list-style: none; padding: 0; }
.nav__link {
  display: block;
  padding: 0.55rem 0.15rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--bench-300);
  text-decoration: none;
  position: relative;
  transition: color 180ms var(--ease);
}
.nav__link:hover { color: #fff; }
.nav__link::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0.1rem;
  height: 2px; background: var(--flux);
  transform: scaleX(0); transform-origin: left;
  transition: transform 260ms var(--ease);
}
.nav__link:hover::after, .nav__link[aria-current='page']::after { transform: scaleX(1); }
.nav__link[aria-current='page'] { color: #fff; }

.header__cta { display: flex; align-items: center; gap: var(--sp-3); flex: none; }

.burger { display: none; }

/* --- 7. Boutons --------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.6rem;
  min-height: 3rem;
  padding: 0.7rem 1.4rem;
  font-family: var(--font-body);
  font-weight: 650;
  font-size: var(--fs-sm);
  letter-spacing: -0.005em;
  text-decoration: none;
  border-radius: var(--r-pill);
  border: 1.5px solid transparent;
  transition: transform 200ms var(--ease), background-color 200ms var(--ease),
              border-color 200ms var(--ease), color 200ms var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn svg { flex: none; }

.btn--flux { background: var(--flux); color: var(--bench-950); }
.btn--flux:hover { background: var(--flux-deep); }

.btn--ghost { border-color: var(--bench-600); color: var(--bench-200); }
.btn--ghost:hover { border-color: var(--flux); color: #fff; }

.on-light .btn--ghost, .island .btn--ghost { border-color: var(--bench-100); color: var(--ink); background: #fff; }
.on-light .btn--ghost:hover, .island .btn--ghost:hover { border-color: var(--flux-ink); color: var(--flux-ink); }

.btn--ink { background: var(--ink); color: var(--sheet); }
.btn--ink:hover { background: var(--bench-800); }

.btn--lg { min-height: 3.5rem; padding: 0.9rem 1.9rem; font-size: var(--fs-base); }
.btn--block { width: 100%; }

/* --- 8. Hero ------------------------------------------------------------ */
.hero { position: relative; overflow: clip; min-height: min(88vh, 54rem); display: flex; align-items: center; padding-block: clamp(4.5rem, 2.5rem + 9vw, 9rem) clamp(4rem, 2.5rem + 6vw, 7.5rem); }
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; opacity: 0.34; filter: saturate(0.55) contrast(1.05); }
.hero__media::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(105deg, var(--bench-950) 8%, color-mix(in oklch, var(--bench-950) 74%, transparent) 52%, color-mix(in oklch, var(--bench-950) 38%, transparent) 100%),
    linear-gradient(to top, var(--bench-950) 2%, transparent 42%);
}
/* La lampe d'établi */
.hero__lamp {
  position: absolute; inset: -20% -10% auto auto;
  width: min(52rem, 88vw); aspect-ratio: 1; z-index: 1;
  pointer-events: none;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in oklch, var(--flux) 26%, transparent) 0%,
    color-mix(in oklch, var(--flux) 9%, transparent) 38%,
    transparent 68%);
  animation: lamp 18s var(--ease) infinite alternate;
}
@keyframes lamp {
  from { transform: translate3d(0, 0, 0) scale(1); opacity: 0.85; }
  to   { transform: translate3d(-7%, 6%, 0) scale(1.14); opacity: 1; }
}
.hero__inner { position: relative; z-index: 2; }

.hero__eyebrow {
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.35rem 0.9rem 0.35rem 0.55rem;
  margin-bottom: var(--sp-5);
  border: 1px solid color-mix(in oklch, var(--flux) 40%, transparent);
  border-radius: var(--r-pill);
  background: color-mix(in oklch, var(--flux) 10%, transparent);
  font-size: var(--fs-sm);
  font-weight: 550;
  color: var(--bench-200);
}
.hero__eyebrow b { color: var(--flux); font-weight: 700; }
.hero__eyebrow .dot {
  width: 1.5rem; height: 1.5rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--flux); color: var(--bench-950);
  font-size: 0.75rem; font-weight: 800;
}

.hero h1 {
  font-size: var(--fs-hero);
  font-variation-settings: 'wdth' 100, 'opsz' 96;
  font-weight: 620;
  letter-spacing: -0.032em;
  line-height: 1.04;
  max-width: 15ch;
}
.hero h1 em { font-style: normal; color: var(--flux); }

.hero__lead {
  margin-top: var(--sp-5);
  font-size: clamp(1.0625rem, 1rem + 0.5vw, 1.3125rem);
  line-height: 1.55;
  color: var(--bench-300);
  max-width: 36rem;
}

.hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-6); }

/* --- 9. Bandeau de confiance ------------------------------------------- */
.trust {
  display: grid;
  /* 9.5rem laisse passer 2 colonnes sur un écran de 390 px : 4 lignes
     empilées repoussaient tout le reste sous la ligne de flottaison. */
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 1px;
  margin-top: clamp(2.5rem, 2rem + 3vw, 4.5rem);
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.trust__cell {
  background: color-mix(in oklch, var(--bench-950) 88%, transparent);
  padding: var(--sp-5) var(--sp-4);
  display: flex; flex-direction: column; gap: 0.2rem;
}
.trust__k {
  font-family: var(--font-display);
  font-size: 1.5rem; font-weight: 700; line-height: 1.1;
  color: #fff; letter-spacing: -0.03em;
  /* Pas de gap ici : il s'ajouterait a l'espace insecable de « 70 % ». */
  display: flex; align-items: baseline;
}
.trust__k .star { color: var(--flux); font-size: 1.1rem; margin-right: 0.35rem; }
.trust__v { font-size: var(--fs-sm); color: var(--bench-400); }

/* --- 10. Titres de section --------------------------------------------- */
.sec-head { max-width: 46rem; margin-bottom: clamp(2.5rem, 1.7rem + 3vw, 4.5rem); }
.sec-head p { margin-top: var(--sp-4); color: var(--fg-soft); font-size: var(--fs-lg); }
.sec-head--center { margin-inline: auto; text-align: center; }
.sec-head--center p { margin-inline: auto; }

/* --- 11. Services : filets, pas cartes ---------------------------------- */
.services { display: grid; gap: clamp(1.5rem, 1rem + 2vw, 2.5rem); }
@media (min-width: 62rem) { .services { grid-template-columns: 1.05fr 1fr; align-items: stretch; } }

.feature {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--bench-900);
  border: 1px solid var(--rule);
  display: flex; flex-direction: column;
  min-height: 100%;
  text-decoration: none;
  transition: border-color 260ms var(--ease);
}
.feature:hover { border-color: color-mix(in oklch, var(--flux) 45%, transparent); }
.feature__media img { transition: transform 700ms var(--ease); }
.feature:hover .feature__media img { transform: scale(1.03); }
.feature__media { position: relative; aspect-ratio: 16 / 10; }
.feature__media img { width: 100%; height: 100%; object-fit: cover; }
.feature__media::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, var(--bench-900) 4%, color-mix(in oklch, var(--bench-900) 30%, transparent) 55%, transparent);
}
.feature__flag {
  position: absolute; z-index: 2; left: var(--sp-4); top: var(--sp-4);
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.35rem 0.85rem;
  border-radius: var(--r-pill);
  background: var(--alert); color: #fff;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.01em;
}
.feature__body { padding: var(--sp-5) var(--sp-5) var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-4); flex: 1; }
.feature__body p { color: var(--bench-300); }
.feature__stat {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.8rem + 2vw, 3.25rem);
  font-weight: 800; line-height: 1;
  color: var(--flux); letter-spacing: -0.04em;
}
.feature__stat + p { margin-top: -0.5rem; }

.svc-list { list-style: none; padding: 0; display: flex; flex-direction: column; justify-content: center; height: 100%; }
.svc-list > li { display: flex; }
.svc {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--sp-4);
  width: 100%;
  padding: clamp(1.15rem, 0.8rem + 1.1vw, 1.9rem) 0;
  border-top: 1px solid var(--rule);
  text-decoration: none;
}
.svc__txt { display: block; min-width: 0; }
.svc__t, .svc__d { display: block; }
.svc:last-child { border-bottom: 1px solid var(--rule); }
/* L'indentation au survol passe par transform : pas de recalcul de layout. */
.svc__icon, .svc__txt { transition: transform 320ms var(--ease); }
.svc:hover .svc__icon, .svc:hover .svc__txt { transform: translateX(8px); }
.svc__icon {
  width: 2.75rem; height: 2.75rem; border-radius: var(--r-md);
  display: grid; place-items: center;
  background: color-mix(in oklch, var(--bench-700) 45%, transparent);
  color: var(--flux);
  transition: background-color 260ms var(--ease);
}
.svc:hover .svc__icon { background: color-mix(in oklch, var(--flux) 20%, transparent); }
.svc__t { font-family: var(--font-display); font-size: var(--fs-xl); font-weight: 650; letter-spacing: -0.02em; color: #fff; }
.svc__d { font-size: var(--fs-sm); color: var(--bench-400); margin-top: 0.15rem; max-width: 34rem; }
.svc__go { color: var(--bench-400); transition: transform 300ms var(--ease), color 200ms var(--ease); }
.svc:hover .svc__go { transform: translateX(5px); color: var(--flux); }

/* --- 12. Étapes (vraie séquence) ---------------------------------------- */
.steps { list-style: none; padding: 0; display: grid; gap: 1px; background: var(--rule); border-block: 1px solid var(--rule); }
@media (min-width: 52rem) { .steps { grid-template-columns: repeat(4, 1fr); } }
.step { background: var(--bg); padding: var(--sp-6) var(--sp-5) var(--sp-7); }
.step__n {
  font-family: var(--font-display);
  font-size: var(--fs-sm); font-weight: 800;
  color: var(--accent);
  display: block; margin-bottom: var(--sp-4);
  font-variant-numeric: tabular-nums;
}
.step h3 { font-size: var(--fs-h4); margin-bottom: var(--sp-3); }
.step p { font-size: var(--fs-sm); color: var(--fg-soft); }

/* --- 13. Atelier / adresse ---------------------------------------------- */
.atelier { display: grid; gap: clamp(2rem, 1rem + 4vw, 4rem); align-items: center; }
@media (min-width: 60rem) { .atelier { grid-template-columns: 1fr 1.15fr; } }
.atelier__media { border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--rule); }
.atelier__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

.nap { list-style: none; padding: 0; margin-top: var(--sp-6); display: grid; gap: var(--sp-4); }
.nap li { display: grid; grid-template-columns: 1.5rem 1fr; gap: var(--sp-4); align-items: start; }
.nap svg { color: var(--accent); margin-top: 0.28rem; }
.nap b { display: block; font-weight: 650; }
.nap span { color: var(--fg-soft); font-size: var(--fs-sm); }
.nap a { color: inherit; }

.map-frame {
  margin-top: var(--sp-6);
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--rule);
  aspect-ratio: 16 / 9;
  background: var(--bench-900);
}
.map-frame iframe { width: 100%; height: 100%; border: 0; }

/* Aperçu tant que la carte n'a pas été demandée. Panneau sombre posé sur une
   page claire : on force les couleurs de texte du contexte sombre, sinon
   l'encre foncée héritée donnerait un texte invisible (règle de l'îlot). */
.map-frame--idle { display: grid; place-items: center; padding: var(--sp-5); }
.map-frame__ph { max-width: 30rem; text-align: center; }
.map-frame__addr {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--fs-lg); color: #fff;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  margin-inline: auto;
}
.map-frame__addr svg { color: var(--flux); flex: none; }
.map-frame__note {
  margin: var(--sp-3) auto var(--sp-5);
  font-size: var(--fs-sm); color: var(--bench-300);   /* 9,34:1 sur bench-900 */
}

/* --- 14. Avis ----------------------------------------------------------- */
.reviews { display: grid; gap: var(--sp-5); grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }
.review {
  display: flex; flex-direction: column; gap: var(--sp-4);
  padding: var(--sp-5);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: color-mix(in oklch, var(--bench-900) 60%, transparent);
}
.review__stars { color: var(--flux); letter-spacing: 0.12em; font-size: var(--fs-sm); }
.review blockquote { font-size: var(--fs-base); line-height: 1.6; color: var(--bench-200); }
.review figcaption { font-size: var(--fs-sm); color: var(--bench-400); margin-top: auto; }
.review figcaption b { color: #fff; font-weight: 650; }

/* --- 15. Panneau urgence ------------------------------------------------ */
.urgence {
  border: 1.5px solid color-mix(in oklch, var(--alert) 55%, transparent);
  border-radius: var(--r-lg);
  background: color-mix(in oklch, var(--alert) 9%, transparent);
  padding: clamp(1.5rem, 1.1rem + 1.6vw, 2.25rem);
}
.on-light .urgence, .island .urgence { background: color-mix(in oklch, var(--alert) 7%, #fff); }
.urgence :is(h2, h3) { display: flex; align-items: center; gap: 0.55rem; margin-bottom: var(--sp-4); }
/* L'icône suit le corps du titre : à 20 px fixes elle disparaissait à côté d'un H2. */
.urgence :is(h2, h3) svg { color: var(--alert-ink); flex: none; width: 0.92em; height: 0.92em; stroke-width: 2; }
.on-dark .urgence :is(h2, h3) svg { color: var(--alert); }
.urgence ol { margin: 0 0 var(--sp-5); padding-left: 1.35rem; display: grid; gap: var(--sp-2); }
.urgence li::marker { color: var(--accent); font-weight: 700; }
.urgence .no { color: var(--alert-ink); font-weight: 700; }
.on-dark .urgence .no { color: var(--alert); }

/* --- 16. Prose ---------------------------------------------------------- */
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--sp-5); }
.prose h2 { margin-top: var(--sp-8); }
.prose h3 { margin-top: var(--sp-7); }
.prose h2 + p, .prose h3 + p, .prose h2 + ul, .prose h3 + ul { margin-top: var(--sp-4); }
.prose ul, .prose ol { padding-left: 1.3rem; display: grid; gap: var(--sp-2); }
.prose li::marker { color: var(--accent); }
.prose strong { font-weight: 650; }
.prose a { color: var(--accent); font-weight: 550; }
.prose small { color: var(--fg-soft); font-size: var(--fs-sm); }

.lede { font-size: var(--fs-xl); line-height: 1.5; color: var(--fg); max-width: 34rem; }

/* --- 17. Grille de pannes ----------------------------------------------- */
/* Le fond de la grille sert de filet (gap 1px) : une dernière rangée
   incomplète laisserait donc un aplat gris. Le nombre de colonnes est fixé
   par page via --cols, choisi comme diviseur du nombre d'éléments. */
.pannes {
  list-style: none; padding: 0; display: grid; gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
@media (min-width: 62rem) {
  .pannes { grid-template-columns: repeat(var(--cols, 3), 1fr); }
}
.panne { background: var(--bg); padding: var(--sp-5); display: flex; gap: var(--sp-4); align-items: flex-start; }
.panne svg { color: var(--accent); flex: none; margin-top: 0.15rem; }
.panne b { display: block; font-weight: 650; margin-bottom: 0.15rem; }
.panne span { font-size: var(--fs-sm); color: var(--fg-soft); }

/* --- 18. Diagnostics (maintenance) -------------------------------------- */
.diags { display: grid; gap: var(--sp-6); }
@media (min-width: 54rem) { .diags { grid-template-columns: repeat(3, 1fr); } }
.diag { display: flex; flex-direction: column; border: 1px solid var(--rule); border-radius: var(--r-lg); overflow: hidden; background: var(--bg); }
.diag img { aspect-ratio: 16 / 10; object-fit: cover; width: 100%; }
.diag__body { padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-4); flex: 1; }
.diag__body h3 { font-size: var(--fs-h4); }
.diag ul { list-style: none; padding: 0; display: grid; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--fg-soft); }
.diag ul li { padding-left: 1.1rem; position: relative; }
.diag ul li::before { content: '·'; position: absolute; left: 0.25rem; color: var(--accent); font-weight: 800; }
.diag__fix { margin-top: auto; padding-top: var(--sp-4); border-top: 1px solid var(--rule); font-size: var(--fs-sm); }
.diag__fix b { color: var(--accent); }

/* --- 19. FAQ ------------------------------------------------------------ */
/* Le titre et la sortie téléphone tiennent la colonne de gauche ; la liste
   garde sa mesure de lecture à droite. Sous 60rem, tout retombe en une
   colonne et l'ordre du DOM (titre puis questions) est déjà le bon. */
.faq-layout { display: grid; gap: var(--sp-6); }
@media (min-width: 60rem) {
  .faq-layout {
    grid-template-columns: minmax(16rem, 22rem) minmax(0, 1fr);
    gap: clamp(3rem, 1rem + 6vw, 7rem);
    align-items: start;
  }
  .faq-layout__aside { position: sticky; top: 9rem; }
}
.faq-layout__out { margin: var(--sp-5) 0; color: var(--fg-soft); }

.faq { border-top: 1px solid var(--rule); max-width: var(--measure); }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-5);
  padding: var(--sp-5) 0;
  font-family: var(--font-display);
  font-size: var(--fs-lg); font-weight: 600; letter-spacing: -0.015em;
  cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ''; flex: none; width: 1rem; height: 1rem; margin-top: 0.35rem;
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1v14M1 8h14' stroke='%23000' stroke-width='2' fill='none'/%3E%3C/svg%3E") center / contain no-repeat;
  color: var(--accent);
  transition: transform 300ms var(--ease);
}
.faq details[open] summary::after { transform: rotate(135deg); }
.faq details > div { padding-bottom: var(--sp-5); color: var(--fg-soft); }
.faq details > div > * + * { margin-top: var(--sp-3); }

/* --- 20. Formulaires ---------------------------------------------------- */
.form { display: grid; gap: var(--sp-5); }
.form__row { display: grid; gap: var(--sp-5); }
@media (min-width: 40rem) { .form__row--2 { grid-template-columns: 1fr 1fr; } }
/* align-content: start est indispensable. Deux .field côte à côte dans un
   .form__row--2 sont étirés à la même hauteur ; sans cela, celui qui a le
   moins d'enfants (pas d'indice sous le champ) voit ses lignes de grille
   grossir pour combler — son label passait de 24 à 38 px et son input de
   55 à 69 px, désalignant la paire. */
.field { display: grid; gap: 0.45rem; align-content: start; }
.field label { font-size: var(--fs-sm); font-weight: 600; }
.field label .opt { font-weight: 400; color: var(--fg-soft); }
.field input, .field select, .field textarea {
  width: 100%;
  font-size: 16px;                 /* < 16px : iOS Safari zoome au focus */
  padding: 0.85rem 1rem;
  background: #fff;
  color: var(--ink);
  border: 1.5px solid var(--bench-100);
  border-radius: var(--r-md);
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}
.on-dark .field input, .on-dark .field select, .on-dark .field textarea {
  background: var(--bench-900); color: var(--bench-200); border-color: var(--bench-600);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-soft); }
.on-dark .field input::placeholder, .on-dark .field textarea::placeholder { color: var(--bench-400); }
.field :is(input, select, textarea):focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 25%, transparent);
}
.field textarea { min-height: 8rem; resize: vertical; }
.field__hint { font-size: var(--fs-xs); color: var(--fg-soft); }
.field__err { font-size: var(--fs-xs); color: var(--alert-ink); font-weight: 600; display: none; }
.on-dark .field__err { color: var(--alert); }
.field[data-invalid='true'] :is(input, select, textarea) { border-color: var(--alert-ink); }
.field[data-invalid='true'] .field__err { display: block; }

.form__consent { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3); align-items: start; font-size: var(--fs-sm); color: var(--fg-soft); }
/* 24 px = cible minimale WCAG 2.5.8 (le libellé entier reste cliquable). */
.form__consent input { width: 1.5rem; height: 1.5rem; flex: none; margin-top: 0.05rem; accent-color: var(--flux-ink); }

.form-note {
  padding: var(--sp-5);
  border-radius: var(--r-md);
  border: 1px dashed var(--rule);
  font-size: var(--fs-sm);
  color: var(--fg-soft);
}

/* --- 21. Fil d'Ariane ---------------------------------------------------
   Il vit dans le bloc sombre entre l'en-tête et le hero : le passer en clair
   creuserait une bande blanche entre deux surfaces sombres. */
.crumbs {
  background: var(--bench-950);
  color: var(--bench-400);
  --rule: color-mix(in oklch, var(--bench-600) 60%, transparent);
  --fg: var(--bench-200);
  --accent: var(--flux);
  font-size: var(--fs-sm);
  padding-block: var(--sp-5) 0;
}
.crumbs ol { list-style: none; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.crumbs li { display: flex; align-items: center; }
.crumbs li + li::before { content: '/'; margin-right: 0.5rem; color: var(--rule); }
.crumbs a { color: inherit; text-decoration: none; display: flex; align-items: center; min-height: 2.75rem; }
.crumbs a:hover { color: var(--accent); text-decoration: underline; }
.crumbs [aria-current] { color: var(--fg); }

/* --- 22. En-tête de page interne ---------------------------------------- */
/* Aligne sur l'echelle premium : les en-tetes internes restaient a l'ancienne
   respiration et paraissaient etriquees a cote de l'accueil. */
.page-hero { position: relative; overflow: clip; padding-block: clamp(3.5rem, 2.4rem + 4.5vw, 6.5rem) clamp(4rem, 2.6rem + 5.5vw, 7.5rem); }
.page-hero h1 { font-variation-settings: 'wdth' 100, 'opsz' 72; font-weight: 620; letter-spacing: -0.03em; max-width: 18ch; }
.page-hero .lede { font-size: clamp(1.0625rem, 0.98rem + 0.5vw, 1.3125rem); max-width: 38rem; }
.page-hero__media { position: absolute; inset: 0; z-index: 0; }
.page-hero__media img { width: 100%; height: 100%; object-fit: cover; opacity: 0.52; filter: saturate(0.6) contrast(1.05); }
.page-hero__media::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(100deg, var(--bench-950) 12%, color-mix(in oklch, var(--bench-950) 82%, transparent) 46%, color-mix(in oklch, var(--bench-950) 42%, transparent) 100%),
    linear-gradient(to top, var(--bench-950) 1%, transparent 58%);
}
.page-hero__inner { position: relative; z-index: 2; }
.page-hero .lede { color: var(--bench-300); margin-top: var(--sp-5); }
.page-hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-6); }

/* --- 23. Bandeau d'appel ------------------------------------------------ */
.cta-band { position: relative; overflow: clip; }
.cta-band__inner { display: grid; gap: var(--sp-6); align-items: center; padding-block: var(--sp-section); }
@media (min-width: 56rem) { .cta-band__inner { grid-template-columns: 1.3fr auto; } }
.cta-band h2 { max-width: 20ch; }
.cta-band p { color: var(--bench-300); margin-top: var(--sp-4); }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* --- 24. Pied de page --------------------------------------------------- */
.footer { background: var(--bench-950); color: var(--bench-300); border-top: 1px solid color-mix(in oklch, var(--bench-600) 45%, transparent); }
.footer__grid { display: grid; gap: var(--sp-7); padding-block: var(--sp-8) var(--sp-6); }
/* 1 bloc de marque + un track par groupe de FOOTER_NAV (src/data.mjs).
   Il y avait 4 tracks pour 3 blocs depuis le retrait du groupe « Occasions » :
   une colonne fantôme qui tirait tout vers la gauche. */
@media (min-width: 56rem) { .footer__grid { grid-template-columns: 1.5fr repeat(2, minmax(0, 1fr)); } }
.footer h2 { font-size: var(--fs-sm); font-family: var(--font-body); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--bench-400); margin-bottom: var(--sp-4); }
.footer ul { list-style: none; padding: 0; display: grid; font-size: var(--fs-sm); }
.footer a { color: var(--bench-300); text-decoration: none; }
/* Cibles tactiles : les liens de pied de page faisaient 17-20 px de haut. */
.footer li { display: flex; align-items: center; min-height: 2.75rem; }
.footer li > a { display: flex; align-items: center; min-height: 2.75rem; width: 100%; }
.footer a:hover { color: var(--flux); text-decoration: underline; }
.footer__legal { border-top: 1px solid color-mix(in oklch, var(--bench-600) 35%, transparent); padding-block: var(--sp-5); display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-6); justify-content: space-between; font-size: var(--fs-xs); color: var(--bench-400); }
.footer__legal a { color: var(--bench-400); }

/* --- 25. (libre) --------------------------------------------------------
   L'ancienne « barre d'action mobile » (.actionbar) vivait ici. Elle a été
   remplacée par le dock flottant .fab le 25/07 ; ses règles restaient dans
   la feuille sans plus aucun usage dans le HTML. Supprimées.            */

/* --- 26. Divers --------------------------------------------------------- */
.tag {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.3rem 0.75rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--rule);
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0.01em;
  color: var(--fg-soft);
}
.tag--flux { border-color: color-mix(in oklch, var(--accent) 45%, transparent); color: var(--accent); }
.tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

.rule { border: 0; border-top: 1px solid var(--rule); margin-block: var(--sp-7); }
.center { text-align: center; }
.mt-6 { margin-top: var(--sp-6); }
.mt-5 { margin-top: var(--sp-5); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.split { display: grid; gap: clamp(2rem, 1.2rem + 4vw, 4.5rem); align-items: center; }
@media (min-width: 58rem) { .split { grid-template-columns: 1fr 1fr; } .split--wide-left { grid-template-columns: 1.25fr 1fr; } }
.split img { border-radius: var(--r-lg); width: 100%; object-fit: cover; }

/* --- 27. Révélation (enrichit un état déjà visible) --------------------- */
.js .reveal { opacity: 0; transform: translateY(18px); transition: opacity 600ms var(--ease), transform 600ms var(--ease); }
.js .reveal.is-in { opacity: 1; transform: none; }

/* --- 28. Responsive ----------------------------------------------------- */
@media (max-width: 60rem) {
  .nav { display: none; }
  .burger {
    display: grid; place-items: center; margin-left: auto;
    width: 2.75rem; height: 2.75rem; border-radius: var(--r-md);
    border: 1px solid var(--bench-600); color: #fff;
  }
  .header__cta .btn--label { display: none; }

  /* Sur mobile, le dock flottant porte déjà « Appeler » en permanence, en
     bas d'écran donc sous le pouce. Le bouton téléphone de l'en-tête faisait
     un troisième appel ambre pour le même numéro sur le premier écran (avec
     celui du hero) : trois fois la même offre, c'est une de trop, et ça
     resserre un en-tête déjà juste sous 360 px. Il reste sur desktop, où il
     affiche le numéro en clair et où le pouce n'existe pas. */
  .header__cta { display: none; }
  .burger { margin-left: auto; }

  /* La règle qui réduit la hauteur de l'en-tête est plus bas dans le
     fichier (section 50 la repose à 4.25rem, et gagne par l'ordre). */

  .nav--open {
    display: block;
    /* --header-h est posée par site.js à l'ouverture (hauteur mesurée de
       l'en-tête) ; 4.5rem n'est plus qu'un repli si le script ne tourne pas. */
    position: fixed; inset: var(--header-h, 4.5rem) 0 0; z-index: var(--z-sticky);
    background: var(--bench-950);
    padding: var(--sp-6) var(--gutter);
    overflow-y: auto;
  }
  .nav--open .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav--open .nav__link { padding: var(--sp-4) 0; font-size: var(--fs-xl); font-family: var(--font-display); border-bottom: 1px solid color-mix(in oklch, var(--bench-600) 40%, transparent); }
  .nav--open .nav__link::after { display: none; }
  .nav--open .nav__foot { display: grid; gap: var(--sp-3); margin-top: var(--sp-6); padding-bottom: var(--sp-6); }
  .nav--open .nav__foot p { margin-top: var(--sp-3); font-size: var(--fs-sm); color: var(--bench-300); }
  .nav--open .nav__foot span { color: var(--bench-400); }
}
/* Le bloc de contact n'existe que dans le panneau mobile ouvert. */
.nav__foot { display: none; }
/* En-tête resserré sur très petits écrans : à 360 px le bouton téléphone
   dépassait de ~4 px (rogné par overflow-x:hidden). */
@media (max-width: 30rem) {
  .header__inner { gap: 0.85rem; }
  .header__cta .btn { padding: 0 0.95rem; }
}
@media (max-width: 22.5rem) {
  .brand__name span { display: none; }
}
/* L'ancienne barre d'action mobile est remplacée par le FAB (section 51). */
@media (max-width: 40rem) {
  .hero h1 { max-width: none; }
  .trust__cell { padding: var(--sp-4); }
  /* Boutons pleine largeur : cibles tactiles régulières, pas de bouton orphelin. */
  .hero__actions, .page-hero__actions, .cta-band__actions { display: grid; }
  .hero__actions .btn, .page-hero__actions .btn, .cta-band__actions .btn { width: 100%; }
}

/* --- 29. Mouvement réduit ----------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .hero__lamp { animation: none; transform: none; }
  .js .reveal { opacity: 1; transform: none; }

  /* ⚠️ Une animation-timeline: view() tire sa progression du DÉFILEMENT,
     pas du temps : `animation-duration` au-dessus n'a aucun effet sur elle.
     Il faut la couper explicitement, sinon .settle garde son blur(6px) et
     son scale(1.07) — mesuré identique aux deux états avant ce correctif.
     Un scale + flou liés au scroll est précisément ce qui déclenche les
     troubles vestibulaires. */
  .settle, .lift {
    animation: none !important;
    animation-timeline: auto !important;
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }
  /* Le rail de courant se montre plein plutôt que vide : l'information
     (« voici la séquence ») survit, c'est le remplissage qui disparaît. */
  .steps::after {
    animation: none !important;
    animation-timeline: auto !important;
    transform: scaleX(1) !important;
  }
}

/* --- 30. Impression ------------------------------------------------------ */
@media print {
  .header, .notice, .fab, .fab__scrim, .cta-band, .hero__lamp, .map-frame { display: none !important; }
  body { background: #fff; color: #000; }
  .on-dark { background: #fff !important; color: #000 !important; }
  .on-dark h1, .on-dark h2, .on-dark h3 { color: #000 !important; }
}

/* =========================================================================
   31. « SOUS TENSION » — couche d'effets
   Une seule idée directrice : le courant qui traverse la page. Chaque effet
   en dérive (la lampe d'établi, le flux qui circule, la ligne qui se remplit).
   Tout est neutralisé par prefers-reduced-motion, section 39.
   ========================================================================= */

@property --spin { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
@property --sweep { syntax: '<percentage>'; inherits: false; initial-value: 0%; }

:root {
  --ease-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-quint: cubic-bezier(0.22, 1, 0.36, 1);
  /* --z-progress a rejoint l'échelle complète, §1. */
}

/* --- 32. Barre de progression de lecture -------------------------------
   « Où j'en suis » : la réponse la moins chère à donner. */
.progress {
  position: fixed; inset: 0 0 auto 0; height: 2px;
  z-index: var(--z-progress);
  background: var(--flux);
  transform: scaleX(0); transform-origin: 0 50%;
  will-change: transform;
}

/* --- 34. La lampe d'établi suit le curseur ------------------------------
   Elle existait déjà en dérive lente ; elle répond maintenant au pointeur.
   Sans JS et sans souris, l'animation d'origine continue seule. */
.hero__lamp {
  --mx: 72%; --my: 18%;
  transition: opacity 600ms var(--ease-quart);
}
.hero[data-pointer='true'] .hero__lamp {
  animation: none;
  inset: 0; width: auto;
  background: radial-gradient(38rem 38rem at var(--mx) var(--my),
    color-mix(in oklch, var(--flux) 24%, transparent) 0%,
    color-mix(in oklch, var(--flux) 8%, transparent) 34%,
    transparent 66%);
}

/* --- 35. Révélation du titre, ligne par ligne --------------------------- */
.reveal-lines { display: block; }
/* Le masque de revelation rognait les descendantes : on lui donne de l'air
   vertical, repris en marge negative pour ne pas decaler l'interlignage. */
.reveal-lines .line { display: block; overflow: hidden; padding-block: 0.12em 0.18em; margin-block: -0.12em -0.18em; }
.reveal-lines .line > span {
  display: block;
  transform: translateY(105%);
  animation: line-up 900ms var(--ease-quint) forwards;
  animation-delay: calc(var(--i, 0) * 110ms + 120ms);
}
@keyframes line-up { to { transform: translateY(0); } }
/* Sans JS ni animation, le texte est déjà là : on ne masque jamais le contenu. */
.no-anim .reveal-lines .line > span { transform: none; animation: none; }

/* --- 36. Bordure sous tension (@property) -------------------------------
   Réservée à DEUX éléments par page au maximum : l'urgence et l'appel
   principal. Au-delà, le signal se dilue et ce n'est plus qu'un décor. */
.energized { position: relative; isolation: isolate; }
.energized::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: conic-gradient(from var(--spin),
    transparent 0 58%,
    color-mix(in oklch, var(--flux) 55%, transparent) 72%,
    var(--flux) 80%,
    #fff 83%,
    var(--flux) 86%,
    color-mix(in oklch, var(--flux) 55%, transparent) 94%,
    transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: spin-current 7s linear infinite;
  pointer-events: none;
  z-index: 1;
}
.energized--alert::before {
  background: conic-gradient(from var(--spin),
    transparent 0 60%,
    color-mix(in oklch, var(--alert) 60%, transparent) 74%,
    var(--alert) 82%, #fff 85%, var(--alert) 88%,
    transparent 100%);
  animation-duration: 5s;
}
@keyframes spin-current { to { --spin: 360deg; } }

/* --- 37. Ticker de réparations -----------------------------------------
   Idée reprise des galeries de composants (21st.dev) mais chargée
   d'information : chaque vignette est une réparation réellement faite.
   Le débordement des deux côtés dit « il y en a beaucoup d'autres ». */
.ticker { position: relative; overflow: hidden; padding-block: var(--sp-3); }
.ticker::before, .ticker::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: clamp(3rem, 10vw, 9rem);
  z-index: 2; pointer-events: none;
}
.ticker::before { left: 0; background: linear-gradient(to right, var(--bench-950), transparent); }
.ticker::after { right: 0; background: linear-gradient(to left, var(--bench-950), transparent); }

.ticker__track {
  display: flex; width: max-content; gap: 0.75rem;
  animation: slide var(--dur-ticker, 64s) linear infinite;
}
.ticker--reverse .ticker__track { animation-direction: reverse; }
.ticker:hover .ticker__track, .ticker:focus-within .ticker__track { animation-play-state: paused; }
@keyframes slide { to { transform: translate3d(-50%, 0, 0); } }

.tick {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.62rem 1.05rem;
  border: 1px solid color-mix(in oklch, var(--bench-600) 50%, transparent);
  border-radius: var(--r-pill);
  background: color-mix(in oklch, var(--bench-900) 70%, transparent);
  font-size: var(--fs-sm); white-space: nowrap; color: var(--bench-300);
}
.tick b { color: #fff; font-weight: 600; }
.tick i {
  font-style: normal; font-size: var(--fs-xs); font-weight: 700;
  color: var(--flux); letter-spacing: 0.02em;
}
.tick s { text-decoration: none; color: var(--bench-600); }

/* --- 38. Pastille d'état de l'atelier ----------------------------------- */
.live {
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.34rem 0.85rem 0.34rem 0.6rem;
  border-radius: var(--r-pill);
  border: 1px solid color-mix(in oklch, var(--bench-600) 60%, transparent);
  background: color-mix(in oklch, var(--bench-900) 60%, transparent);
  font-size: var(--fs-sm); font-weight: 550; color: var(--bench-200);
}
.live__dot {
  position: relative; width: 0.55rem; height: 0.55rem; border-radius: 50%;
  background: oklch(0.78 0.17 148); flex: none;
}
.live__dot::after {
  content: ''; position: absolute; inset: -3px; border-radius: 50%;
  border: 1.5px solid oklch(0.78 0.17 148);
  animation: ping 2.4s var(--ease-quart) infinite;
}
.live[data-open='false'] .live__dot { background: var(--flux); }
.live[data-open='false'] .live__dot::after { border-color: var(--flux); }
@keyframes ping {
  0%   { transform: scale(0.7); opacity: 0.9; }
  70%  { transform: scale(2.1); opacity: 0; }
  100% { transform: scale(2.1); opacity: 0; }
}

/* --- 39. Compteurs ------------------------------------------------------ */
.count { font-variant-numeric: tabular-nums; }

/* --- 40. Rail de progression des étapes --------------------------------
   Une ligne de courant qui se remplit à mesure qu'on descend la séquence.
   Scroll-driven natif quand le navigateur sait faire, sinon simple filet. */
.steps { position: relative; }
.steps::after {
  content: ''; position: absolute; left: 0; top: 0; height: 3px;
  width: 100%; transform-origin: 0 50%; transform: scaleX(0);
  background: linear-gradient(to right, var(--flux), color-mix(in oklch, var(--flux) 35%, transparent));
  z-index: 2;
}
@supports (animation-timeline: view()) {
  .steps::after {
    animation: fill-rail linear both;
    animation-timeline: view();
    animation-range: entry 30% cover 60%;
  }
}
@keyframes fill-rail { to { transform: scaleX(1); } }

/* --- 41. Projecteur sur les lignes de service ---------------------------
   Encore la lampe : elle éclaire la ligne survolée. */
.svc { position: relative; }
.svc::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(22rem 12rem at var(--px, 50%) 50%,
    color-mix(in oklch, var(--flux) 11%, transparent), transparent 72%);
  opacity: 0; transition: opacity 320ms var(--ease-quart);
  pointer-events: none; border-radius: var(--r-md);
}
.svc:hover::before, .svc:focus-visible::before { opacity: 1; }

/* --- 42. Révélation des médias par volet -------------------------------
   Un volet qui s'ouvre, pas un fondu générique de plus. */
@supports (animation-timeline: view()) {
  .wipe {
    animation: wipe-in 1ms linear both;
    animation-timeline: view();
    animation-range: entry 10% entry 85%;
  }
  @keyframes wipe-in {
    from { clip-path: inset(0 0 100% 0); opacity: 0.4; }
    to   { clip-path: inset(0 0 0 0);    opacity: 1; }
  }
}

/* --- 43. Typographie à deux tons ---------------------------------------
   Une phrase, deux poids d'attention : l'affirmation, puis la nuance. */
.duo { color: var(--fg-soft); }
.duo b { color: var(--fg); font-weight: inherit; }
.on-dark .duo b { color: #fff; }

/* --- 44. Retour d'appui sur les boutons -------------------------------- */
.btn { will-change: auto; }
.btn--flux:hover { box-shadow: 0 0 0 4px color-mix(in oklch, var(--flux) 22%, transparent); }
.btn:active { transform: translateY(1px) scale(0.99); }

/* --- 45. Mouvement réduit : on coupe tout le chapitre 31-44 ------------- */
@media (prefers-reduced-motion: reduce) {
  .ticker__track { animation: none; transform: none; }
  .ticker { overflow-x: auto; }
  .energized::before { animation: none; --spin: 135deg; }
  .live__dot::after { animation: none; opacity: 0.35; }
  .reveal-lines .line > span { transform: none; animation: none; }
  .steps::after { transform: scaleX(1); animation: none; }
  .wipe { animation: none; clip-path: none; opacity: 1; }
  .hero[data-pointer='true'] .hero__lamp { background: radial-gradient(38rem 38rem at 72% 18%, color-mix(in oklch, var(--flux) 20%, transparent), transparent 66%); }
  .progress { display: none; }
}

/* =========================================================================
   46. CHAPITRES — grammaire reprise d'apple.fr
   Un sujet par écran, titre centré, une phrase, deux pilules, une grande
   image. Ce n'est PAS l'habillage d'Apple (ni SF Pro, ni leur bleu, ni leur
   gris) : c'est leur découpage narratif, appliqué à notre charte.
   ========================================================================= */

.chapter {
  position: relative;
  overflow: clip;
  display: grid;
  align-content: center;
  min-height: min(90vh, 58rem);
  padding-block: var(--sp-chapter);
  text-align: center;
}
.chapter--auto { min-height: 0; }

.chapter__inner {
  position: relative; z-index: 2;
  width: min(100% - var(--gutter) * 2, 56rem);
  margin-inline: auto;
}

.chapter__title {
  font-size: clamp(2.3rem, 1.35rem + 4.1vw, 4.5rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.032em;
  font-variation-settings: 'wdth' 100, 'opsz' 72;
  text-wrap: balance;
}
.chapter__title em { font-style: normal; color: var(--accent); }

.chapter__sub {
  margin: clamp(1rem, 0.7rem + 0.9vw, 1.6rem) auto 0;
  max-width: 40rem;
  font-size: clamp(1.0625rem, 0.98rem + 0.5vw, 1.375rem);
  line-height: 1.5;
  color: var(--fg-soft);
}

.chapter__actions {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 0.85rem;
  margin-top: clamp(1.75rem, 1.2rem + 1.6vw, 2.75rem);
}

/* Le média du chapitre : grand, net, sans voile qui l'embourbe. */
.chapter__media {
  margin-top: clamp(2.5rem, 1.5rem + 4vw, 5.5rem);
  width: min(100% - var(--gutter) * 2, 74rem);
  margin-inline: auto;
  border-radius: var(--r-xl);
  overflow: hidden;
}
.chapter__media img { width: 100%; height: auto; display: block; }

/* Fond photographique plein cadre, éclairé dans le noir. */
.chapter--photo { color: #fff; }
.chapter--photo .chapter__bg { position: absolute; inset: 0; z-index: 0; }
.chapter--photo .chapter__bg img { width: 100%; height: 100%; object-fit: cover; }
/* Le voile est le plus DENSE au centre, la ou le texte se pose. Un radial
   transparent au centre faisait exactement l'inverse : titre blanc sur cafe
   en pleine lumiere. Verifie au pixel, pas au jugement. */
.chapter--photo .chapter__bg img { filter: saturate(0.72) brightness(0.72); }
.chapter--photo .chapter__bg::after {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(78% 62% at 50% 50%,
      color-mix(in oklch, var(--bench-950) 86%, transparent) 0%,
      color-mix(in oklch, var(--bench-950) 74%, transparent) 52%,
      color-mix(in oklch, var(--bench-950) 46%, transparent) 100%),
    linear-gradient(to bottom,
      var(--bench-950) 0%,
      color-mix(in oklch, var(--bench-950) 30%, transparent) 22%,
      color-mix(in oklch, var(--bench-950) 30%, transparent) 74%,
      var(--bench-950) 100%);
}
.chapter--photo .chapter__title { color: #fff; }
.chapter--photo .chapter__sub { color: var(--bench-200); }

/* Effet de profondeur : le média se pose en douceur pendant le défilement. */
@supports (animation-timeline: view()) {
  .settle {
    animation: settle linear both;
    animation-timeline: view();
    animation-range: entry 5% entry 92%;
  }
  @keyframes settle {
    from { transform: scale(1.07); opacity: 0.55; filter: blur(var(--settle-blur, 6px)); }
    to   { transform: scale(1);    opacity: 1;    filter: blur(0); }
  }
  /* Un blur() animé au défilement re-rastérise l'image à chaque image-écran :
     c'est le seul effet du site qui ne tourne pas sur le compositeur. Sur
     pointeur grossier (mobile, le public à 70 %, souvent en 4G sur un
     appareil modeste) on garde l'échelle et le fondu, on retire le flou. */
  @media (pointer: coarse) { :root { --settle-blur: 0px; } }
  /* Le texte arrive plus tot et plus discretement que l'image. */
  .lift {
    animation: lift linear both;
    animation-timeline: view();
    animation-range: entry 8% entry 62%;
  }
  @keyframes lift {
    from { opacity: 0; transform: translateY(26px); }
    to   { opacity: 1; transform: none; }
  }
}

/* --- 47. Retenue chromatique -------------------------------------------
   L'ambre servait partout : puces, icônes, filets, numéros, étiquettes.
   Elle est ramenée aux actions et au signal d'urgence ; le reste passe en
   neutre, et la chaleur vient désormais des photographies. */
.svc__icon { color: var(--bench-200); background: color-mix(in oklch, var(--bench-700) 38%, transparent); }
.svc:hover .svc__icon { background: color-mix(in oklch, var(--bench-600) 45%, transparent); color: #fff; }
.step__n { color: var(--fg-soft); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.tag { border-color: var(--rule); color: var(--fg-soft); }
.tag--flux { border-color: var(--rule); color: var(--fg-soft); }
.tick i { color: var(--bench-400); font-weight: 600; }
.nap svg { color: var(--fg-soft); }
.panne svg { color: var(--fg-soft); }
.prose li::marker { color: var(--fg-soft); }
.diag ul li::before { color: var(--fg-soft); }

/* --- 48. Boutons : pilules pleines, plus larges, plus calmes ------------ */
.btn {
  border-radius: var(--r-pill);
  font-weight: 600;
  padding: 0.8rem 1.6rem;
  min-height: 3.1rem;
}
.btn--lg { min-height: 3.6rem; padding: 1rem 2.1rem; font-size: var(--fs-base); }
.btn--flux:hover { box-shadow: none; background: var(--flux-deep); transform: translateY(-1px); }
.btn--ghost:hover { transform: translateY(-1px); }

/* --- 49. Surfaces : moins de filets, plus de matière -------------------- */
.feature, .review, .diag, .atelier__media, .map-frame, .split img,
.chapter__media, .trust { border-radius: var(--r-lg); }
.pannes { border-radius: var(--r-lg); }
.review { border-color: color-mix(in oklch, var(--bench-600) 32%, transparent); }

/* --- 50. En-tête plus discret ------------------------------------------ */
.nav__link { font-size: 0.875rem; font-weight: 500; }
.header__inner { min-height: 4.25rem; }
.brand__name { font-size: 1rem; font-weight: 700; }
.brand__name span { color: var(--bench-400); }

/* En-tête + sous-nav restent collés en permanence : à 69 + 56 px ils
   mangeaient 15 % d'un écran de 844 px. On récupère la hauteur sur
   l'en-tête, qui n'a plus que la marque et le menu à porter sur mobile.
   Placé ici et pas dans le bloc responsive plus haut : la règle
   `.header__inner` ci-dessus est postérieure et l'emporterait. */
@media (max-width: 60rem) {
  .header__inner { min-height: 3.5rem; }
  .brand__mark { width: 34px; height: 34px; }
}

/* La liste de services occupe maintenant toute la largeur : les lignes
   respirent au lieu de se serrer dans une demi-colonne. */
.svc-list--wide { max-width: 62rem; margin-inline: auto; }
.svc-list--wide .svc { padding-block: clamp(1.4rem, 1rem + 1.4vw, 2.2rem); }
.svc-list--wide .svc__t { font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.6rem); font-weight: 600; }
.svc-list--wide .svc__d { font-size: var(--fs-base); margin-top: 0.35rem; max-width: 42rem; }
.svc-list--wide .svc__icon { width: 3.1rem; height: 3.1rem; border-radius: var(--r-md); }

/* La liste large est dimensionnee pour le desktop : sur un ecran de 390 px,
   le corps agrandi faisait des lignes de 450 px de haut. On revient au
   dimensionnement compact sous 48rem. */
@media (max-width: 48rem) {
  .svc-list--wide .svc { padding-block: var(--sp-5); gap: var(--sp-3); }
  .svc-list--wide .svc__t { font-size: var(--fs-lg); }
  .svc-list--wide .svc__d { font-size: var(--fs-sm); }
  .svc-list--wide .svc__icon { width: 2.5rem; height: 2.5rem; }
  .chapter { min-height: 0; padding-block: clamp(4rem, 3rem + 6vw, 7rem); }
  .chapter--photo { min-height: min(84vh, 40rem); }
  .chapter__media { margin-top: clamp(2rem, 1.5rem + 3vw, 3rem); border-radius: var(--r-lg); }
}

/* --- 51. Accueil lumineux — édition premium 2026 -----------------------
   La photo porte la matière, l'interface reste calme et très lisible. */
.hero--premium {
  --bg: var(--sheet-3);
  --fg: var(--ink);
  --fg-soft: var(--ink-soft);
  --rule: color-mix(in oklch, var(--ink) 14%, transparent);
  --accent: var(--flux-ink);
  min-height: min(89vh, 58rem);
  background: var(--bg);
  color: var(--fg);
  /* Haut resserré : depuis le retrait des deux pastilles, le titre n'a plus
     rien devant lui et l'écart avec l'en-tête se voyait comme un trou. Le
     bas garde sa respiration pour détacher la barre de confiance. */
  padding-block: clamp(2.5rem, 1.5rem + 3vw, 4.5rem) clamp(5rem, 4rem + 6vw, 9rem);
}
.hero--premium .hero__media {
  left: 48%;
  overflow: hidden;
}
.hero--premium .hero__media img {
  opacity: 1;
  filter: none;
  object-position: 62% center;
}
.hero--premium .hero__media::after {
  background: linear-gradient(90deg, var(--sheet-3) 0%, color-mix(in srgb, var(--sheet-3) 94%, transparent) 12%,
    color-mix(in srgb, var(--sheet-3) 22%, transparent) 44%, transparent 68%);
}
.hero--premium .hero__lamp { display: none; }
.hero--premium .hero__inner { width: min(100% - var(--gutter) * 2, var(--shell)); }
.hero--premium .hero__inner > :not(.trust) { max-width: 38rem; }
.hero--premium h1 {
  max-width: 9.4ch;
  color: var(--ink);
  font-size: clamp(3.4rem, 2rem + 5.4vw, 6.6rem);
  line-height: .98;
  letter-spacing: -.042em;
}
.hero--premium h1 em { color: var(--flux-ink); }
.hero--premium .hero__lead {
  color: var(--ink-soft);
  font-size: clamp(1.06rem, .96rem + .35vw, 1.3rem);
  line-height: 1.5;
}
.hero--premium .hero__eyebrow {
  color: var(--ink);
  background: color-mix(in srgb, #fff 82%, transparent);
  border-color: color-mix(in srgb, var(--ink) 14%, transparent);
}
.hero--premium .hero__eyebrow .dot { background: var(--flux); color: var(--ink); }
.hero--premium .live {
  color: var(--ink);
  background: color-mix(in srgb, #fff 82%, transparent);
  border-color: color-mix(in srgb, var(--ink) 14%, transparent);
}
.hero--premium .btn--ghost {
  color: var(--ink);
  border-color: color-mix(in srgb, var(--ink) 30%, transparent);
  background: color-mix(in srgb, #fff 68%, transparent);
}
.hero--premium .trust {
  max-width: 62rem;
  margin-top: clamp(3rem, 2rem + 3vw, 5.5rem);
  background: color-mix(in srgb, #fff 86%, transparent);
  border-color: color-mix(in srgb, var(--ink) 12%, transparent);
  box-shadow: 0 24px 70px rgb(15 25 35 / .08);
}
.hero--premium .trust__cell { border-color: color-mix(in srgb, var(--ink) 12%, transparent); }
.hero--premium .trust__cell { background: rgb(255 255 255 / .86); }
.hero--premium .trust__k { color: var(--ink); }
.hero--premium .trust__v { color: var(--ink-soft); }

.service-catalog {
  background: #fff;
}
.service-catalog .sec-head p,
.service-catalog .svc__d { color: var(--ink-soft); }
.service-catalog .svc { border-color: color-mix(in srgb, var(--ink) 14%, transparent); }
.service-catalog .svc__t { color: var(--ink); }
.service-catalog .svc__icon {
  color: var(--ink);
  background: var(--sheet-3);
}
.service-catalog .svc__go { color: var(--ink-soft); }
.service-catalog .svc::before {
  background: radial-gradient(55% 150% at var(--px, 50%) 50%,
    color-mix(in oklch, var(--flux) 12%, transparent), transparent 75%);
}

.chapter--liquid {
  align-items: center;
  justify-content: flex-start;
  background: var(--sheet-3);
  color: var(--ink);
}
.chapter--liquid .chapter__bg img {
  filter: none;
  object-position: center;
}
.chapter--liquid .chapter__bg::after {
  background: linear-gradient(90deg, rgb(var(--sheet-3-rgb) / .98) 0%, rgb(var(--sheet-3-rgb) / .9) 29%,
    rgb(var(--sheet-3-rgb) / .18) 58%, transparent 76%);
}
.chapter--liquid .chapter__inner {
  width: min(100% - var(--gutter) * 2, var(--shell));
  margin-inline: auto;
  text-align: left;
  align-items: flex-start;
}
.chapter--liquid .chapter__inner > * { max-width: 35rem; }
.chapter--liquid .chapter__title { color: var(--ink); }
.chapter--liquid .chapter__sub { color: var(--ink-soft); }
.chapter--liquid .chapter__sub strong { color: var(--ink) !important; }
.chapter--liquid .chapter__actions,
.chapter--liquid .tags { justify-content: flex-start !important; }
.chapter--liquid .btn--ghost {
  color: var(--ink);
  border-color: color-mix(in srgb, var(--ink) 28%, transparent);
  background: rgb(255 255 255 / .72);
}

@media (max-width: 62rem) {
  .hero--premium {
    flex-direction: column;
    padding-top: 4.5rem;
    padding-bottom: 3rem;
  }
  .hero--premium .hero__media {
    position: relative;
    inset: auto;
    order: 2;
    width: calc(100% - var(--gutter) * 2);
    height: clamp(18rem, 58vw, 32rem);
    margin: 2.5rem auto 0;
    border-radius: var(--r-xl);
  }
  .hero--premium .hero__inner { order: 1; }
  .hero--premium .hero__media::after { display: none; }
  .hero--premium .hero__inner > :not(.trust) { max-width: 44rem; }
  .hero--premium h1 { max-width: 10ch; }
}

@media (max-width: 48rem) {
  .hero--premium h1 { font-size: clamp(3rem, 14vw, 4.4rem); }
  .hero--premium .trust { box-shadow: none; }
  .chapter--liquid {
    min-height: 0;
    display: grid;
    padding: 0;
  }
  .chapter--liquid .chapter__bg {
    position: relative;
    height: 24rem;
    order: 2;
  }
  .chapter--liquid .chapter__bg::after { display: none; }
  .chapter--liquid .chapter__inner {
    padding-block: 5rem 3rem;
    order: 1;
  }
}

/* --- 52. Direction blanche ---------------------------------------------
   Les zones sombres deviennent l'exception (pied de page), pas la scène. */
.header::before,
.header[data-scrolled='true']::before {
  background: rgb(255 255 255 / .9);
  backdrop-filter: blur(18px) saturate(160%);
}
.header,
.header[data-scrolled='true'] {
  border-bottom-color: rgb(14 27 36 / .1);
}
/* ⚠️ Ces règles doivent être SCOPÉES À L'EN-TÊTE. Non scopées, elles
   atteignaient aussi le bloc de marque du pied de page, qui est sur
   --bench-950 : « Répare ta Pomme » y ressortait à 1,12:1 et sa baseline
   à 2,7:1, sur les 9 pages. C'est la règle de l'îlot — un test de paires
   de tokens ne peut pas la voir, seul le rendu la montre
   (tools/check-ilot.js). */
.header .brand__name,
.header .nav__link,
.header .nav__link[aria-current='page'] { color: var(--ink); }
.header .brand__name span { color: var(--ink-soft); }
.header .nav__link:hover { color: var(--flux-ink); }

.ticker-section--premium {
  background: #fff;
  color: var(--ink);
}
.ticker-section--premium .duo { color: var(--ink-soft); }
.ticker-section--premium .duo b { color: var(--ink); }
.ticker-section--premium .ticker::before {
  background: linear-gradient(to right, #fff, transparent);
}
.ticker-section--premium .ticker::after {
  background: linear-gradient(to left, #fff, transparent);
}
.ticker-section--premium .tick {
  background: var(--sheet-3);
  border-color: rgb(14 27 36 / .09);
  color: var(--ink-soft);
}
.ticker-section--premium .tick b { color: var(--ink); }
.ticker-section--premium .tick i { color: var(--ink-soft); }

.reviews-premium { background: var(--sheet-3); }
.reviews-premium .sec-head p { color: var(--ink-soft); }
.reviews-premium .review {
  background: #fff;
  border-color: rgb(14 27 36 / .08);
  box-shadow: 0 16px 45px rgb(14 27 36 / .055);
}
.reviews-premium .review blockquote { color: var(--ink); }
.reviews-premium .review figcaption { color: var(--ink-soft); }
.reviews-premium .review figcaption b { color: var(--ink); }

.cta-band--premium {
  background: var(--sheet-3);
  color: var(--ink);
}
.cta-band--premium p { color: var(--ink-soft); }
.cta-band--premium .btn--ghost {
  color: var(--ink);
  background: #fff;
  border-color: rgb(14 27 36 / .18);
}

.page-hero {
  --bg: var(--sheet-3);
  --fg: var(--ink);
  --fg-soft: var(--ink-soft);
  --rule: rgb(14 27 36 / .1);
  --accent: var(--flux-ink);
  background: var(--bg);
  color: var(--fg);
}
.page-hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, var(--sheet-3) 4%, rgb(var(--sheet-3-rgb) / .97) 35%, rgb(var(--sheet-3-rgb) / .72) 55%, rgb(var(--sheet-3-rgb) / .12) 100%),
    linear-gradient(to top, var(--sheet-3), transparent 48%);
}
.page-hero__media img {
  opacity: .72;
  filter: saturate(.35) contrast(.96);
}
.page-hero h1 { color: var(--ink) !important; }
.page-hero .lede { color: var(--ink-soft) !important; }
.page-hero .tag { color: var(--ink-soft); border-color: rgb(14 27 36 / .14); }
.page-hero .btn--ghost {
  color: var(--ink);
  border-color: rgb(14 27 36 / .22);
  background: rgb(255 255 255 / .75);
}

/* --- 53. L'ambre lisible sur les surfaces claires ------------------------
   `--flux` (#f7aa3b) est calibré pour le texte SUR FOND SOMBRE : il tombe à
   1,9:1 sur blanc. Depuis le passage en direction claire, plusieurs textes
   ambre se sont retrouvés sur des surfaces claires — la note « 4,9/5 » du
   hero, les étoiles des avis, le compteur de la barre de confiance. Ils
   passent sur `--flux-ink` (5,81:1 sur --sheet), qui reste de l'ambre.
   Idem pour l'étiquette d'urgence, en `--alert-ink`.
   Mesuré sur le rendu par tools/check-ilot.js. */
.hero__eyebrow b { color: var(--flux-ink); }
.review__stars { color: var(--flux-ink); }
.trust__k .star { color: var(--flux-ink); }
.tag--alert { color: var(--alert-ink); border-color: color-mix(in oklch, var(--alert-ink) 45%, transparent); }

@media (max-width: 60rem) {
  .burger { color: var(--ink); border-color: rgb(14 27 36 / .18); }
  .nav--open { background: #fff; }
  .nav--open .nav__link {
    color: var(--ink);
    border-bottom-color: rgb(14 27 36 / .1);
  }
  .nav--open .nav__foot p,
  .nav--open .nav__foot span { color: var(--ink-soft); }
  /* Oubli de cette bascule : quand le panneau est passé au blanc, le bouton
     « Demander un devis » a gardé son encre de surface sombre (--bench-200)
     et se lisait à 1,42:1 — invisible. Encore la règle de l'îlot, et
     invisible à check-ilot.js, qui mesure la page menu FERMÉ. On reprend le
     traitement clair canonique (.on-light .btn--ghost, §7). */
  .nav--open .nav__foot .btn--ghost {
    border-color: var(--bench-100);
    color: var(--ink);
    background: #fff;
  }
  .nav--open .nav__foot .btn--ghost:hover {
    border-color: var(--flux-ink);
    color: var(--flux-ink);
  }
}

/* --- 53. Hero collage, adapté du composant Modern Hero de 21st.dev ----- */
/* La marque est un SVG inline : le rayon vient du dessin lui-même, on ne
   pose ici que l'ombre qui la décolle de l'en-tête. */
.brand__mark {
  border-radius: 9px;
  box-shadow: 0 2px 10px rgb(14 27 36 / .12);
}
.hero--collage {
  min-height: 0;
  padding-block: clamp(5rem, 4rem + 5vw, 8rem) clamp(4rem, 3rem + 4vw, 7rem);
  display: block;
  overflow: hidden;
}
.hero--collage .hero__inner { text-align: center; }
.hero--collage .hero__inner > :not(.trust):not(.hero-collage) {
  max-width: 54rem;
  margin-inline: auto;
}
.hero--collage .hero__inner > div:first-child { justify-content: center; }
.hero--collage h1 {
  max-width: 11.5ch;
  font-size: clamp(3.7rem, 2rem + 6vw, 7.4rem);
  margin-inline: auto;
}
.hero--collage .hero__lead {
  max-width: 47rem;
  margin: var(--sp-6) auto 0;
}
.hero--collage .hero__actions { justify-content: center; }
.hero--collage .trust {
  margin-inline: auto;
  position: relative;
  z-index: 4;
}

.hero-collage {
  position: relative;
  width: min(100%, 76rem);
  height: clamp(23rem, 39vw, 34rem);
  margin: clamp(3.5rem, 2rem + 4vw, 6rem) auto 0;
  perspective: 1200px;
}
.hero-collage__item {
  position: absolute;
  overflow: hidden;
  margin: 0;
  background: #eee;
  border: 7px solid #fff;
  border-radius: clamp(1.25rem, 1rem + 1vw, 2rem);
  box-shadow: 0 28px 65px rgb(14 27 36 / .13);
  transform: rotate(var(--rotate, 0deg));
  transition: transform 500ms var(--ease), box-shadow 500ms var(--ease);
}
.hero-collage__item:hover {
  z-index: 8;
  transform: rotate(0) translateY(-8px) scale(1.025);
  box-shadow: 0 34px 75px rgb(14 27 36 / .19);
}
.hero-collage__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero-collage__item--a {
  --rotate: -8deg;
  left: 0;
  top: 18%;
  width: 25%;
  height: 56%;
}
.hero-collage__item--b {
  --rotate: -2deg;
  left: 25%;
  top: 2%;
  z-index: 3;
  width: 34%;
  height: 82%;
}
.hero-collage__item--c {
  --rotate: 5deg;
  right: 18%;
  top: 16%;
  z-index: 2;
  width: 27%;
  height: 59%;
}
.hero-collage__item--d {
  --rotate: 9deg;
  right: -1%;
  top: 6%;
  width: 22%;
  height: 48%;
}
.hero-collage__item--e {
  --rotate: 3deg;
  right: 6%;
  bottom: 0;
  z-index: 4;
  width: 25%;
  height: 41%;
}

/* L'image historique du dégât liquide reste à sa taille crédible au lieu
   d'être étirée comme une photo de campagne. */
.chapter--liquid {
  min-height: min(82vh, 48rem);
  width: min(calc(100% - var(--gutter) * 2), var(--shell));
  margin: var(--sp-section) auto;
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--sheet-3);
}
.chapter--liquid .chapter__bg {
  left: 45%;
  border-radius: var(--r-xl);
  overflow: hidden;
}
.chapter--liquid .chapter__bg img {
  object-fit: cover;
  image-rendering: auto;
}

@media (max-width: 62rem) {
  .hero--collage { display: block; }
  .hero--collage .hero__inner { order: initial; }
}
@media (max-width: 48rem) {
  .hero--collage { padding-top: 3.5rem; }
  .hero--collage h1 { font-size: clamp(3.25rem, 15vw, 4.8rem); }
  .hero-collage {
    height: 25rem;
    width: calc(100% + 2rem);
    margin-left: -1rem;
  }
  .hero-collage__item { border-width: 4px; border-radius: 1.15rem; }
  .hero-collage__item--a { left: -4%; top: 14%; width: 36%; height: 42%; }
  .hero-collage__item--b { left: 24%; top: 2%; width: 48%; height: 61%; }
  .hero-collage__item--c { right: -3%; top: 18%; width: 36%; height: 38%; }
  .hero-collage__item--d { left: 8%; top: 53%; width: 39%; height: 35%; }
  .hero-collage__item--e { right: 5%; bottom: 0; width: 45%; height: 38%; }
  .chapter--liquid {
    width: 100%;
    margin-block: 0;
    border-radius: 0;
  }
  .chapter--liquid .chapter__bg { left: 0; border-radius: 0; }
}

/* --- 54. Premier écran scindé : proposition + preuve photographique ----- */
.hero--split {
  display: block;
  min-height: 0;
  padding-block: clamp(4.5rem, 3.5rem + 4vw, 7.5rem) clamp(3rem, 2rem + 3vw, 5rem);
  background: var(--sheet-3);
}
.hero--split .hero__inner {
  display: grid;
  grid-template-columns: minmax(0, .9fr) minmax(28rem, 1.1fr);
  gap: clamp(3rem, 2rem + 4vw, 6.5rem);
  align-items: center;
  text-align: left;
}
.hero--split .hero-copy { min-width: 0; }
.hero--split .hero-copy > * { max-width: 40rem; }
.hero--split .hero-copy > div:first-child { justify-content: flex-start; }
.hero--split h1 {
  max-width: 8.8ch;
  margin: 0;
  font-size: clamp(4rem, 2.2rem + 5.4vw, 6.8rem);
  line-height: .96;
}
.hero--split .hero__lead {
  margin: var(--sp-6) 0 0;
  max-width: 37rem;
}
.hero--split .hero__actions { justify-content: flex-start; }
.hero--split .trust {
  grid-column: 1 / -1;
  width: min(100%, 68rem);
  margin: clamp(2.5rem, 1.5rem + 3vw, 4rem) auto 0;
}

.hero-photo-block {
  position: relative;
  min-height: clamp(32rem, 43vw, 43rem);
  isolation: isolate;
}
.hero-photo-block figure { margin: 0; }
.hero-photo-block__main {
  position: absolute;
  inset: 3% 5% 4% 5%;
  overflow: hidden;
  border-radius: clamp(1.75rem, 1.3rem + 1.4vw, 3rem);
  background: #dfe5e8;
  box-shadow: 0 32px 80px rgb(14 27 36 / .14);
}
.hero-photo-block__main::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 42%;
  background: linear-gradient(transparent, rgb(5 16 23 / .8));
}
.hero-photo-block__main img,
.hero-photo-block__detail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero-photo-block__main figcaption {
  position: absolute;
  z-index: 2;
  left: clamp(1.4rem, 1rem + 1vw, 2.2rem);
  right: 8rem;
  bottom: clamp(1.4rem, 1rem + 1vw, 2.2rem);
  color: #fff;
}
.hero-photo-block__main figcaption span {
  display: block;
  margin-bottom: .3rem;
  color: rgb(255 255 255 / .72);
  font-size: var(--fs-sm);
}
.hero-photo-block__main figcaption b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 1.1rem + .8vw, 1.9rem);
  line-height: 1.1;
}
.hero-photo-block__detail {
  position: absolute;
  z-index: 3;
  overflow: hidden;
  width: clamp(8rem, 12vw, 11.5rem);
  aspect-ratio: 4 / 5;
  border: 6px solid var(--sheet-3);
  border-radius: 1.5rem;
  box-shadow: 0 20px 45px rgb(14 27 36 / .18);
}
.hero-photo-block__detail--top {
  top: 0;
  right: 0;
  transform: rotate(4deg);
}
.hero-photo-block__detail--bottom {
  right: 0;
  bottom: 0;
  transform: rotate(-4deg);
}

.section-soft {
  background: #f1f5f7;
  color: var(--ink);
}
.section-soft h1,
.section-soft h2,
.section-soft h3,
.section-soft h4 { color: var(--ink); }
.section-soft p,
.section-soft .sec-head p { color: var(--ink-soft) !important; }
.section-soft .panne,
.section-soft .step {
  background: #fff !important;
  color: var(--ink);
}
.section-soft .panne span,
.section-soft .step p { color: var(--ink-soft); }
.section-soft .urgence {
  background: #fff;
  color: var(--ink);
}
.section-soft .btn--ghost {
  color: var(--ink);
  border-color: rgb(14 27 36 / .18);
  background: #fff;
}

@media (max-width: 62rem) {
  .hero--split .hero__inner {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }
  .hero--split .hero-copy { text-align: center; }
  .hero--split .hero-copy > * { margin-inline: auto; }
  .hero--split .hero-copy > div:first-child,
  .hero--split .hero__actions { justify-content: center; }
  .hero--split h1 { max-width: 10ch; }
  .hero-photo-block {
    width: min(100%, 42rem);
    min-height: clamp(27rem, 82vw, 38rem);
    margin-inline: auto;
  }
}
@media (max-width: 48rem) {
  .hero--split { padding-top: 2.5rem; }
  .hero--split .hero__inner { gap: 1.75rem; }
  .hero--split h1 { font-size: clamp(3.05rem, 14vw, 4.25rem); }
  .hero--split .hero__lead {
    margin-top: 1.25rem;
    font-size: 1.06rem;
    line-height: 1.55;
  }
  .hero--split .hero__actions { margin-top: 1.5rem; }
  .hero-photo-block { min-height: 25rem; }
  .hero-photo-block__main { inset: 2% 4% 3%; }
  .hero-photo-block__detail {
    width: 8rem;
    border-width: 4px;
    border-radius: 1.1rem;
  }
}

/* =========================================================================
   51. FAB — appeler / message toujours à portée
   Deux boutons flottants bas-droite. « Appeler » est un lien direct (1 tap).
   « Message » ouvre les canaux (SMS, e-mail, formulaire). Remplace l'ancienne
   barre d'action mobile : un seul dispositif fixe, sur tous les écrans.
   ========================================================================= */
/* --z-fab et --z-fab-scrim ont rejoint l'échelle complète, §1. */

/* Hauteur réellement occupée par le dock : deux pilules empilées (118 px
   mesurés) plus sa marge basse. Le pied de page doit réserver au moins
   ça, sinon ses derniers liens finissent DÉFINITIVEMENT sous le dock —
   en fin de défilement, on ne peut plus les dégager en faisant défiler. */
/* Hauteur réellement occupée par le dock, marge basse comprise. Elle a
   grandi avec le 3e bouton (« y aller ») : 189 + 16 = 205 px mesurés, contre
   9rem/144px avant — « Mentions légales » et « ATMOTECH » repassaient sous
   le dock, définitivement. Vérifié par tools/check-fab-overlap.js. */
:root { --fab-clearance: 14rem; }

.fab {
  position: fixed;
  right: clamp(1rem, 0.4rem + 1.6vw, 2rem);
  bottom: calc(clamp(1rem, 0.4rem + 1.6vw, 2rem) + env(safe-area-inset-bottom));
  z-index: var(--z-fab);
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 0.65rem;
}

/* Les deux boutons du dock (pilules icône + libellé). */
.fab__btn {
  display: inline-flex; align-items: center; gap: 0.55rem;
  height: 3.5rem; padding: 0 1.35rem;
  border: 1.5px solid transparent;
  border-radius: var(--r-pill);
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-sm);
  letter-spacing: -0.005em;
  text-decoration: none; cursor: pointer;
  box-shadow: 0 12px 30px -10px color-mix(in oklch, var(--bench-950) 65%, transparent),
              0 2px 6px -2px color-mix(in oklch, var(--bench-950) 40%, transparent);
  animation: fab-in 0.5s var(--ease-quint) both;
  transition: transform 0.24s var(--ease-quart), box-shadow 0.24s var(--ease-quart),
              background-color 0.2s var(--ease-quart), border-color 0.2s var(--ease-quart);
}
.fab__btn:hover { transform: translateY(-2px); }
.fab__btn:active { transform: translateY(0) scale(0.98); }
.fab__ic { display: inline-flex; flex: none; }
.fab__ic svg { width: 22px; height: 22px; }
@keyframes fab-in { from { opacity: 0; transform: translateY(14px) scale(0.9); } to { opacity: 1; transform: none; } }

/* Appeler — primaire, ambre, en bas, 1 tap. */
.fab__btn--call {
  order: 3; background: var(--flux); color: var(--bench-950);
  animation-delay: 0.12s;
}
.fab__btn--call:hover {
  background: var(--flux-deep);
  box-shadow: 0 16px 36px -10px color-mix(in oklch, var(--flux) 60%, transparent);
}

/* Message — secondaire, verre sombre, ouvre les canaux. */
.fab__btn--msg {
  order: 2;
  background: color-mix(in oklch, var(--bench-950) 80%, transparent);
  backdrop-filter: blur(16px) saturate(140%);
  border-color: color-mix(in oklch, var(--bench-400) 45%, transparent);
  color: #fff;
  animation-delay: 0.05s;
}
.fab__btn--msg:hover { border-color: color-mix(in oklch, var(--flux) 55%, transparent); }

/* Icône ↔ croix. Piloté par aria-expanded DU BOUTON, pas par data-open du
   dock : avec trois boutons, l'état du dock ne dit pas lequel est ouvert —
   les trois basculaient ensemble. */
.fab__btn .fab__ic--close { display: none; }
.fab__btn[aria-expanded='true'] .fab__ic--open { display: none; }
.fab__btn[aria-expanded='true'] .fab__ic--close { display: inline-flex; }

/* La feuille de canaux, au-dessus des deux boutons. */
.fab__sheet {
  order: 1;
  display: flex; flex-direction: column; gap: 0.5rem;
  width: min(20rem, 82vw);
  margin-bottom: 0.15rem;
}
.fab__sheet[hidden] { display: none; }

.fab__opt {
  display: flex; align-items: center; gap: 0.85rem;
  padding: 0.75rem 0.9rem;
  border-radius: var(--r-lg);
  background: color-mix(in oklch, var(--bench-950) 88%, transparent);
  backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid color-mix(in oklch, var(--bench-400) 40%, transparent);
  box-shadow: 0 14px 34px -14px color-mix(in oklch, var(--bench-950) 85%, transparent);
  text-decoration: none;
  transform: translateY(12px); opacity: 0;
  transition: transform 0.32s var(--ease-quint), opacity 0.32s var(--ease-quint),
              border-color 0.2s var(--ease-quart);
}
.fab[data-open='true'] .fab__opt { transform: none; opacity: 1; }
.fab[data-open='true'] .fab__opt:nth-child(1) { transition-delay: 0.02s; }
.fab[data-open='true'] .fab__opt:nth-child(2) { transition-delay: 0.06s; }
.fab[data-open='true'] .fab__opt:nth-child(3) { transition-delay: 0.10s; }
.fab__opt:hover { border-color: color-mix(in oklch, var(--flux) 55%, transparent); }
.fab__opt-ic {
  flex: none; width: 2.6rem; height: 2.6rem; border-radius: 50%;
  display: grid; place-items: center;
  background: color-mix(in oklch, var(--flux) 18%, transparent);
  color: var(--flux);
}
.fab__opt-ic svg { width: 20px; height: 20px; }
.fab__opt-txt { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.fab__opt-txt b { font-weight: 650; font-size: var(--fs-base); color: #fff; }
.fab__opt-txt small { font-size: var(--fs-xs); color: var(--bench-300); }

/* Voile derrière la feuille ouverte. */
.fab__scrim {
  position: fixed; inset: 0; z-index: var(--z-fab-scrim);
  background: color-mix(in oklch, var(--bench-950) 52%, transparent);
  backdrop-filter: blur(2px);
  opacity: 0; transition: opacity 0.3s var(--ease-quart);
}
.fab__scrim[hidden] { display: none; }
.fab__scrim.is-on { opacity: 1; }

/* Sous 30rem : on garde le libellé « Appeler » (l'action n°1) mais on réduit
   « Message » à son icône pour ne pas encombrer le pouce. */
@media (max-width: 30rem) {
  .fab__btn { height: 3.35rem; padding: 0 1.1rem; }
  .fab__btn--msg .fab__name { display: none; }
  .fab__btn--msg { padding: 0; width: 3.35rem; justify-content: center; }
}

/* Le pied de page laisse la place au FAB sur mobile. */
/* 5,5rem (88 px) ne suffisait pas : le dock en occupe 134. « Facebook »
   était masqué à 65 %, « Mentions légales » et « Contact & accès » à 34 %,
   sans possibilité de les dégager. Mesuré par tools/check-fab-overlap.js. */
@media (max-width: 60rem) {
  .footer__legal { padding-bottom: var(--fab-clearance); }
}

@media (prefers-reduced-motion: reduce) {
  .fab__btn { animation: none; }
  .fab__opt { transition: opacity 0.01ms; transform: none; }
}
@media print { .fab, .fab__scrim { display: none !important; } }

/* =========================================================================
   61. FORMINATOR — le formulaire de production, habillé
   Le thème WordPress n'affiche pas le formulaire de la maquette : il rend
   Forminator #752, celui qui reçoit des demandes depuis avril 2023. On
   réimplémenterait sinon ses notifications, son anti-spam et son historique.
   Ces règles l'alignent sur les champs de la charte (§20). Elles n'ont
   aucun effet sur la maquette statique, où ce balisage n'existe pas.
   ========================================================================= */

.rtp-form { margin-top: var(--sp-6); }

/* Forminator pose son propre thème « material » (labels flottants) : on le
   ramène à des labels au-dessus, comme partout ailleurs sur le site. */
.forminator-ui.forminator-custom-form { font-family: var(--font-body) !important; }

.forminator-ui .forminator-row { display: grid; gap: var(--sp-5); margin-bottom: var(--sp-5); }
@media (min-width: 40rem) {
  .forminator-ui .forminator-row:has(.forminator-col-6 + .forminator-col-6) {
    grid-template-columns: 1fr 1fr;
  }
}
.forminator-ui .forminator-row-last { margin-bottom: 0; }
.forminator-ui .forminator-col { min-width: 0; }

.forminator-ui .forminator-field {
  display: grid; gap: 0.45rem; align-content: start;   /* cf. §20 : sans ça les paires se désalignent */
  position: static !important;
}

.forminator-ui .forminator-label {
  position: static !important;
  transform: none !important;
  font-family: var(--font-body) !important;
  font-size: var(--fs-sm) !important;
  font-weight: 600 !important;
  color: var(--ink) !important;
  background: none !important;
  padding: 0 !important;
  margin: 0 !important;
}
.forminator-ui .forminator-required { color: var(--alert-ink) !important; }

.forminator-ui input.forminator-input,
.forminator-ui textarea.forminator-textarea,
.forminator-ui select.forminator-select {
  width: 100%;
  font-family: var(--font-body) !important;
  font-size: 16px !important;              /* < 16 px : iOS Safari zoome au focus */
  line-height: 1.45 !important;
  height: auto !important;
  padding: 0.85rem 1rem !important;
  background: #fff !important;
  color: var(--ink) !important;
  border: 1.5px solid var(--bench-100) !important;
  border-radius: var(--r-md) !important;
  box-shadow: none !important;
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}
.forminator-ui textarea.forminator-textarea { min-height: 8rem !important; resize: vertical; }

.forminator-ui input.forminator-input:focus,
.forminator-ui textarea.forminator-textarea:focus,
.forminator-ui select.forminator-select:focus {
  outline: none !important;
  border-color: var(--accent) !important;
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 25%, transparent) !important;
}

.forminator-ui .forminator-description { font-size: var(--fs-xs) !important; color: var(--fg-soft) !important; }

/* Erreurs : en texte, jamais en couleur seule (cf. PRODUCT.md, a11y). */
.forminator-ui .forminator-error input.forminator-input,
.forminator-ui .forminator-error textarea.forminator-textarea {
  border-color: var(--alert-ink) !important;
}
.forminator-ui .forminator-error-message {
  font-size: var(--fs-xs) !important;
  font-weight: 600 !important;
  color: var(--alert-ink) !important;
}

/* Le bouton d'envoi reprend .btn--flux : l'ambre est l'action, partout. */
.forminator-ui button.forminator-button-submit {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.6rem;
  width: 100%;
  min-height: 3.6rem !important;
  padding: 1rem 2.1rem !important;
  font-family: var(--font-body) !important;
  font-size: var(--fs-base) !important;
  font-weight: 650 !important;
  letter-spacing: -0.005em;
  color: var(--bench-950) !important;
  background: var(--flux) !important;
  border: 0 !important;
  border-radius: var(--r-pill) !important;
  box-shadow: none !important;
  cursor: pointer;
  transition: background-color 180ms var(--ease), transform 180ms var(--ease);
}
.forminator-ui button.forminator-button-submit:hover {
  background: var(--flux-deep) !important;
  transform: translateY(-1px);
}
.forminator-ui button.forminator-button-submit:focus-visible {
  outline: 3px solid var(--flux) !important;
  outline-offset: 3px;
}

/* Message de retour après envoi. */
.forminator-ui .forminator-response-message {
  padding: var(--sp-5) !important;
  border-radius: var(--r-md) !important;
  font-size: var(--fs-sm) !important;
  background: color-mix(in oklch, var(--flux) 12%, #fff) !important;
  color: var(--ink) !important;
  border: 1px solid color-mix(in oklch, var(--flux) 40%, transparent) !important;
}
.forminator-ui .forminator-response-message.forminator-error {
  background: color-mix(in oklch, var(--alert) 10%, #fff) !important;
  border-color: color-mix(in oklch, var(--alert-ink) 40%, transparent) !important;
}

@media (prefers-reduced-motion: reduce) {
  .forminator-ui button.forminator-button-submit:hover { transform: none; }
}

/* =========================================================================
   62. DOCK À GAUCHE SUR MOBILE + RETOUR EN HAUT
   Deux zones pour deux gestes : à gauche ce qu'on veut déclencher (appeler,
   écrire), à droite ce qui ramène en haut. Les superposer, c'était se
   tromper de bouton au pouce.
   ========================================================================= */

@media (max-width: 60rem) {
  .fab {
    right: auto;
    left: clamp(1rem, 0.4rem + 1.6vw, 2rem);
    align-items: flex-start;
  }
  /* Icônes seules : les libellés doublaient une intention déjà lisible au
     pictogramme, et deux pilules côte à côte mangeaient le tiers de la
     largeur d'écran. */
  .fab__btn .fab__name { display: none; }
  .fab__btn {
    width: 3.5rem; height: 3.5rem;
    padding: 0 !important;
    justify-content: center;
    border-radius: 50%;
  }
  .fab__sheet { left: 0; right: auto; transform-origin: bottom left; }
}

/* L'ancienne règle gardait le libellé « Appeler » sous 30rem : le dock est
   désormais en icônes sur tout le mobile, on la neutralise. */
@media (max-width: 30rem) {
  .fab__btn--call .fab__name { display: none; }
}

.totop {
  position: fixed;
  right: clamp(1rem, 0.4rem + 1.6vw, 2rem);
  bottom: calc(clamp(1rem, 0.4rem + 1.6vw, 2rem) + env(safe-area-inset-bottom));
  z-index: var(--z-fab);
  width: 3.5rem; height: 3.5rem;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid color-mix(in oklch, var(--ink) 12%, transparent);
  background: rgb(255 255 255 / .88);
  backdrop-filter: blur(14px);
  color: var(--ink);
  cursor: pointer;
  box-shadow: 0 12px 30px -12px color-mix(in oklch, var(--bench-950) 45%, transparent);
  animation: totop-in .32s var(--ease-quint) both;
  transition: transform .24s var(--ease-quart), background-color .2s var(--ease-quart);
}
@keyframes totop-in { from { opacity: 0; transform: translateY(10px); } }

/* Sur grand écran le dock reste à droite : la flèche se range AU-DESSUS de
   lui, sinon les deux occupent le même coin (mesuré : 29 px du bord tous
   les deux). Sur mobile le dock est à gauche, la flèche garde le coin. */
@media (min-width: 60rem) {
  .totop { bottom: calc(var(--fab-clearance) + clamp(1rem, 0.4rem + 1.6vw, 2rem)); }
}

.totop[hidden] { display: none; }
.totop:hover { background: #fff; transform: translateY(-2px); }
.totop:focus-visible { outline: 3px solid var(--flux); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .totop { animation: none; }
  .totop:hover { transform: none; }
}

/* =========================================================================
   63. AVIS — badge Google et en-tête de carte
   Les avis sont réels et vérifiables : le logo Google et la date le disent
   mieux qu'une promesse. Le badge renvoie vers la fiche, pour contrôler.
   ========================================================================= */

.reviews__badge {
  display: inline-flex; align-items: center; gap: .55rem;
  margin-top: var(--sp-5);
  padding: .55rem .95rem;
  border: 1px solid var(--bench-100);
  border-radius: var(--r-pill);
  background: #fff;
  font-size: var(--fs-sm);
  color: var(--ink);
  text-decoration: none;
  box-shadow: 0 1px 3px color-mix(in oklch, var(--bench-950) 8%, transparent);
  transition: box-shadow .2s var(--ease), transform .2s var(--ease);
}
.reviews__badge:hover { transform: translateY(-1px); box-shadow: 0 6px 18px -8px color-mix(in oklch, var(--bench-950) 35%, transparent); }
.reviews__badge b { font-weight: 700; }
.reviews__badge-n { color: var(--ink-soft); }
.reviews__badge-n::before { content: '·'; margin-right: .5rem; color: var(--bench-100); }

.review__top { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); }
.review figcaption { display: grid; gap: .1rem; }
.review figcaption span { font-size: var(--fs-xs); color: var(--fg-soft); font-weight: 400; }

/* Les logos de marques tierces gardent leurs couleurs : un logo Google
   monochrome n'est plus le logo Google. */
.brandmark { flex: none; display: block; }

@media (prefers-reduced-motion: reduce) {
  .reviews__badge:hover { transform: none; }
}

/* Le logo client est un PNG blanc sur transparent : il lui faut la pastille
   ambre de la charte comme support, sinon il disparaît sur l'en-tête clair. */
.brand__mark--client {
  display: grid; place-items: center;
  background: var(--flux);
  border-radius: 9px;
  box-shadow: 0 2px 10px rgb(14 27 36 / .12);
  overflow: hidden;
  flex: none;
}
.brand__mark--client img { width: 76%; height: 76%; object-fit: contain; display: block; }

/* Sur desktop le dock occupe le coin bas-droit : la ligne légale doit
   s'arrêter avant, sinon son dernier élément finit dessous — « ATMOTECH »
   était masqué à 87 %, et en fin de page on ne peut plus le dégager.
   Mesuré par tools/check-fab-overlap.js. */
@media (min-width: 60rem) {
  .footer__legal { padding-right: 11rem; }
}

/* Crédit d'agence : présent, mais il ne dispute rien aux mentions légales. */
.footer__credit a { color: var(--bench-300); text-decoration-color: color-mix(in oklch, var(--bench-400) 60%, transparent); }
.footer__credit a:hover { color: var(--flux); }

/* =========================================================================
   64. DOCK — trois boutons, aucun libellé
   Le dock porte désormais trois gestes : y aller, écrire, appeler. Avec des
   libellés il occupait la moitié de la largeur d'un téléphone ; les
   pictogrammes se lisent seuls, et le nom passe par aria-label pour les
   lecteurs d'écran. Les règles ci-dessous s'appliquent à TOUS les écrans et
   remplacent les surcharges mobiles de la section 62.
   ========================================================================= */

.fab__btn .fab__name { display: none; }
.fab__btn {
  width: 3.5rem; height: 3.5rem;
  padding: 0 !important;
  justify-content: center;
  border-radius: 50%;
}

/* La feuille s'aligne sur le bord du dock, quel que soit le côté. */
.fab__sheet { align-self: flex-start; }
@media (min-width: 60rem) { .fab__sheet { align-self: flex-end; } }

/* Le bouton « y aller » se distingue sans crier : verre clair, pas d'ambre.
   L'ambre reste l'appel, c'est le principe n°1 du projet. */
.fab__btn--go {
  background: rgb(255 255 255 / .92);
  color: var(--ink);
  border-color: color-mix(in oklch, var(--ink) 12%, transparent);
  backdrop-filter: blur(14px);
}
.fab__btn--go:hover { background: #fff; }


/* Ordre de la pile, explicite. Les boutons portaient déjà des `order`
   (message 2, appel 3) ; le nouveau bouton « y aller » tombait à 0 et
   s'affichait AU-DESSUS de la feuille, coupant le dock en deux. On repose
   la pile de haut en bas : les feuilles, puis les trois boutons groupés. */
.fab__sheet    { order: 0; }
.fab__btn--go  { order: 1; }
.fab__btn--msg { order: 2; }
.fab__btn--call{ order: 3; }


/* --- 55. Bandeau de congés ----------------------------------------------
   Une information datée, pas une alerte. Elle se pose SOUS l'en-tête et s'en
   va au premier défilement : rien de collant — la sous-navigation avait été
   retirée le 26/07 précisément parce qu'elle mangeait 56 px en permanence sur
   mobile, et on ne les reprend pas pour un message temporaire.

   Bande CLAIRE, pas sombre : depuis la « direction blanche » (§52) l'en-tête
   est blanc sur les 9 pages. Un bandeau sombre s'y collait comme une pièce
   rapportée, et sur les pages intérieures il se fondait dans le fil d'Ariane
   sombre juste dessous — deux bandes noires que rien ne séparait.

   Une seule phrase, la pastille en tête de ligne : le texte coule après elle
   au lieu d'occuper sa propre rangée. L'ambre ne sort pas de son rôle — il
   teinte le fond, la pastille et le soulignement des liens, le corps du
   message reste en --ink.                                                  */
.notice {
  background: color-mix(in oklch, var(--flux) 22%, #fff);
  border-bottom: 1px solid color-mix(in oklch, var(--flux-deep) 32%, transparent);
  color: var(--ink);
  font-size: var(--fs-sm);
}
/* `p { max-width: var(--measure) }` (§4) s'applique aussi ici : combiné au
   `margin-inline: auto` de .shell, il ramenait le bandeau à 42 rem CENTRÉS au
   milieu de l'écran, désaligné de l'en-tête et cassé en deux lignes dès 1280 px.
   Un bandeau n'est pas un paragraphe de lecture : il prend la largeur du site. */
.notice__inner {
  max-width: none;
  padding-block: 0.6rem;
  /* 1.62 (corps de lecture) donnait 83 px de bande sur mobile, où la phrase
     tient sur trois lignes. Un bandeau ne se lit pas comme un paragraphe. */
  line-height: 1.5;
}
.notice__badge {
  /* inline-flex : l'icône reste soudée à sa date, la phrase coule après. */
  display: inline-flex; align-items: baseline; gap: 0.4rem;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--flux-ink);
  margin-right: 0.15rem;
}
.notice__badge svg { width: 15px; height: 15px; flex: none; transform: translateY(2px); }
.notice a {
  color: var(--ink);
  text-decoration: underline;
  /* Le soulignement est le SEUL indice qui distingue ces liens du texte
     autour (même couleur d'encre) : il doit se voir. À 55 % de --flux-deep
     il tombait à 2,4:1 sur le fond ambré, à peine un liseré. */
  text-decoration-color: color-mix(in oklch, var(--flux-ink) 75%, transparent);
  text-underline-offset: 3px;
  text-decoration-thickness: 1.5px;
  /* Le numéro ne doit jamais se couper en fin de ligne. */
  white-space: nowrap;
}
.notice a:hover { color: var(--flux-ink); text-decoration-color: currentColor; }

@media (max-width: 40rem) {
  .notice { font-size: var(--fs-xs); }
  .notice__inner { padding-block: 0.55rem; }
}
