/* ============================================================
   Design system du contenu de page (hors header/splash, qui ont
   leurs propres fichiers et ne sont pas touchés ici).
   Style : tech précis et premium, inspiration Stripe en clair.
   ============================================================ */

:root {
  /* Même beige que le header/splash (--color-bg, header.css) : un seul
     fond sur toute la page, pas d'alternance. */
  --color-surface: var(--color-bg);
  --color-footer-bg: #1a1a2e;

  /* Texte des sections de contenu */
  --color-ink: #1a1a2e;
  --color-ink-muted: #5a5a72;

  /* Dégradé violet → bleu : boutons principaux, un mot-clé par titre
     de section, bordure de carte au hover. Nulle part ailleurs. */
  --color-accent-blue: #3b82f6;
  --gradient-brand: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-blue) 100%);

  /* Cartes */
  --card-radius: 16px;
  --card-border-color: rgba(26, 26, 46, 0.08);
  --card-shadow: 0 1px 2px rgba(26, 26, 46, 0.04);
  --card-shadow-hover: 0 16px 32px -12px rgba(26, 26, 46, 0.16);

  /* Typo : hiérarchie stricte, une seule taille par rôle */
  --fs-section-title: clamp(2.25rem, 4vw, 3.25rem);
  --fs-card-title: 1.25rem;
  --fs-body: 1.0625rem;

  /* Rythme vertical constant entre sections */
  /* Chaque section ajoute ce padding en haut ET en bas : deux sections
     adjacentes cumulent donc 2x cette valeur comme espace visuel entre
     elles (98+98=196px desktop, 82+82=164px mobile). Exception : le hero,
     qui a sa propre hauteur d'écran pleine et son propre padding-top
     (règle .hero-section dédiée, plus bas). */
  --section-gap-desktop: 98px;
  --section-gap-mobile: 82px;
}

/* ---------- Rythme de page ---------- */

.section {
  position: relative;
  overflow: hidden;
  background: var(--color-surface);
  padding-block: var(--section-gap-desktop);
}

.container {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding-inline: 24px;
}

@media (max-width: 768px) {
  .section { padding-block: var(--section-gap-mobile); }
}

/* Halo radial très subtil en fond de chaque section, positionné en
   alternance haut-gauche / bas-droite (.section--halo-tl / --br) pour
   suggérer une continuité douce d'une section à l'autre plutôt qu'une
   coupure nette — sans jamais changer la couleur de fond elle-même.
   --halo-y (parallax.js, ≤ 30px) : léger décalage au scroll. */
.section::before {
  content: '';
  position: absolute;
  width: 900px;
  height: 900px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--color-accent) 0%, var(--color-accent-blue) 55%, transparent 72%);
  opacity: 0.05;
  filter: blur(90px);
  pointer-events: none;
  z-index: 0;
  transform: translateY(var(--halo-y, 0px));
  will-change: transform;
}

.section--halo-tl::before { top: -300px; left: -300px; }
.section--halo-br::before { bottom: -300px; right: -300px; }

/* Pas de halo sur le hero : sur cette section basse et sans marge en haut
   (juste après le splash), le dégradé se faisait couper net par
   overflow:hidden avant de s'être suffisamment estompé — un bloc teinté
   à bord visible plutôt qu'un halo discret. */
.hero-section::before { content: none; }

@media (max-width: 768px) {
  .section::before { width: 560px; height: 560px; }
  .section--halo-tl::before { top: -180px; left: -180px; }
  .section--halo-br::before { bottom: -180px; right: -180px; }
}

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

/* ---------- Primitives de texte ---------- */

.section-title {
  margin: 0;
  font-size: var(--fs-section-title);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--color-ink);
}

.text-gradient {
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.section-lead {
  margin: 20px 0 0;
  max-width: 640px;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--color-ink-muted);
}

/* ---------- Boutons ---------- */
/* .cta-button existe déjà (header.css, fond plein) : on lui superpose le
   dégradé ici — c'est la seule propriété qu'on change, tout le reste
   (padding, radius, focus...) vient déjà du header, pour rester cohérent
   avec le bouton du header lui-même. */
.cta-button {
  background: var(--gradient-brand);
}

.cta-button:hover,
.cta-button:focus-visible {
  background: var(--gradient-brand);
  filter: brightness(0.93);
}

/* Bouton secondaire : violet uni (le dégradé est réservé aux boutons
   principaux), même gabarit que .cta-button pour une hauteur identique. */
.btn-outline {
  display: inline-flex;
  align-items: center;
  padding: 8.5px 18px;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-accent);
  background: transparent;
  border: 1.5px solid var(--color-accent);
  border-radius: 8px;
  white-space: nowrap;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.btn-outline:hover,
.btn-outline:focus-visible {
  background: var(--color-accent);
  color: var(--color-accent-contrast);
}

/* ---------- Hero ---------- */

/* Hauteur d'écran pleine (comme le splash, #intro) : c'est ce qui permet
   à splash-transition.js de mesurer une cible de scroll stable (le haut
   de .hero-section), et ce qui rend le centrage vertical ci-dessous
   cohérent avec "le hero occupe l'écran". 100dvh en repli : s'ajuste à la
   barre d'adresse mobile plutôt que de laisser un residu à défiler.
   padding-top (box-sizing:border-box, header.css) réserve la place du
   header fixe À L'INTÉRIEUR de cette hauteur : le centrage vertical se
   fait donc sur l'espace réellement visible sous le header, pas dessus. */
.hero-section {
  height: 100vh;
  height: 100dvh;
  padding-top: var(--header-height-scrolled);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* L'animation d'entrée de l'accroche du splash (intro.css,
   .intro-tagline, translateY + fondu) est prévue pour ne jouer qu'une
   fois, à l'arrivée initiale sur la page. La classe ci-dessous est posée
   par splash-transition.js (hasIntroPlayed) une fois cette animation
   terminée (événement animationend, jamais avant — sinon un scroll très
   rapide au tout premier chargement la couperait en plein vol) : on la
   neutralise alors définitivement, pour qu'elle ne puisse plus se
   rejouer à un retour ultérieur sur le splash. Seul le fondu d'opacité
   (intro.css, .intro-js .intro-tagline, inchangé) continue de s'appliquer
   ensuite, sans aucun déplacement vertical résiduel. */
html.splash-has-transitioned .intro-tagline {
  animation: none;
}

/* Remontée uniquement (phase 4, séquentielle — cf. splash-transition.js) :
   retarde le fondu d'apparition de l'accroche (.intro-js .intro-tagline,
   intro.css, inchangé — même durée/courbe 420ms ease dans les deux sens)
   jusqu'à ce que la course du logo vers le splash (phase 3) soit
   terminée. La remontée ne défile plus (scrollY est repositionné
   instantanément, à écran vide, avant que cette phase ne démarre) : ce
   délai garantit malgré tout que l'accroche apparaît une fois le logo
   arrivé, jamais en même temps.
   545ms = DURATION, la durée de la transition du logo (intro.css,
   .intro-js .logo) reprise dans splash-transition.js (à garder
   synchronisé si cette valeur change).
   Classe posée/retirée par splash-transition.js (tagline-return-delay). */
html.tagline-return-delay .intro-tagline {
  transition-delay: 545ms;
}

/* transition sur opacity uniquement : utilisée par splash-transition.js
   pour faire disparaître le contenu du hero AVANT que le logo ne
   reparte vers le splash (remontée), pour qu'il ne le chevauche jamais.
   420ms ease : même durée/courbe que le fondu du splash (intro.css,
   .intro-js .intro-bg), pour rester cohérent avec l'existant. */
.hero-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 24px;
  transition: opacity 420ms ease;
}

.hero-title {
  max-width: 900px;
}

.hero-title-line {
  display: block;
  color: var(--color-ink);
}

.hero-title-line--accent {
  color: var(--color-accent);
}

.hero-subtitle {
  margin: 0;
  max-width: 620px;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--color-ink-muted);
}

.hero-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 8px;
}

@media (max-width: 640px) {
  .hero-actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: 12px;
  }

  .hero-actions .cta-button,
  .hero-actions .btn-outline {
    justify-content: center;
    width: 100%;
  }
}

/* ---------- Carte de base (partagée : stats, services, méthode) ----------
   Fond blanc légèrement translucide pour se détacher du beige uniforme ;
   plein blanc au hover pour un léger effet de "solidification". */

.card {
  background: rgba(255, 255, 255, 0.6);
  border-radius: var(--card-radius);
  border: 1px solid var(--card-border-color);
  box-shadow: var(--card-shadow);
  transition: box-shadow 0.25s ease, border-color 0.25s ease, background 0.25s ease, transform 0.25s ease;
}

.card--hoverable:hover {
  border-color: transparent;
  background:
    linear-gradient(#ffffff, #ffffff) padding-box,
    var(--gradient-brand) border-box;
  box-shadow: var(--card-shadow-hover);
  transform: translateY(-4px);
}

@media (prefers-reduced-motion: reduce) {
  .card { transition-duration: 0s; }
}

.card-title {
  margin: 0;
  font-size: var(--fs-card-title);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-ink);
}

.card-text {
  margin: 8px 0 0;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--color-ink-muted);
}


/* ---------- Services ---------- */

.section-head {
  max-width: 640px;
  margin: 0 auto;
  text-align: center;
}

.section-head .section-lead { margin-inline: auto; }

.services-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  margin-top: 56px;
}

@media (max-width: 1024px) {
  .services-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 640px) {
  .services-grid { grid-template-columns: 1fr; }
}

/* Stagger entre cartes (base 240ms posée par .reveal--content) */
.services-grid .reveal--content:nth-child(2) { transition-delay: 330ms; }
.services-grid .reveal--content:nth-child(3) { transition-delay: 420ms; }
.services-grid .reveal--content:nth-child(4) { transition-delay: 510ms; }
.services-grid .reveal--content:nth-child(5) { transition-delay: 600ms; }
.services-grid .reveal--content:nth-child(6) { transition-delay: 690ms; }

.service-card {
  padding: 32px 28px;
}

.service-card-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-bottom: 20px;
  border-radius: 10px;
  border: 1px solid var(--card-border-color);
  color: var(--color-accent);
}

.service-card-icon svg {
  position: absolute;
  transition: opacity 0.25s ease;
}

.service-card-icon .icon-gradient {
  opacity: 0;
}

.service-card:hover .icon-base {
  opacity: 0;
}

.service-card:hover .icon-gradient {
  opacity: 1;
}

.services-note {
  margin-top: 56px;
  text-align: center;
}

.services-note-text {
  margin: 0 0 20px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--color-ink-muted);
}

@media (prefers-reduced-motion: reduce) {
  .service-card-icon svg { transition-duration: 0s; }
}

/* ---------- Diagnostic (questionnaire interactif) ---------- */

.diagnostic-content {
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
}

.diagnostic-content .section-lead {
  margin-inline: auto;
}

/* .card (radius/bordure/ombre) fournit déjà le cadre ; ici juste le
   padding et la mise en page interne, sans le hover des grilles. */
.quiz-card {
  margin-top: 48px;
  padding: 40px;
  min-height: 460px;
  text-align: left;
}

.quiz-progress-row {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 28px;
}

.quiz-progress-track {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--card-border-color);
  overflow: hidden;
}

.quiz-progress-fill {
  height: 100%;
  width: 0%;
  background: var(--gradient-brand);
  border-radius: 2px;
  transition: width 0.35s ease;
}

.quiz-progress-label {
  flex-shrink: 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-ink-muted);
  white-space: nowrap;
}

/* Hauteur stable entre les questions/le résultat, pour éviter les sauts
   de mise en page pendant les transitions. */
.quiz-body {
  position: relative;
}

.quiz-step {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.quiz-step--from-right { opacity: 0; transform: translateX(24px); }
.quiz-step--from-left { opacity: 0; transform: translateX(-24px); }
.quiz-step--to-left { opacity: 0; transform: translateX(-24px); }
.quiz-step--to-right { opacity: 0; transform: translateX(24px); }

.quiz-question {
  margin: 0 0 24px;
  font-size: var(--fs-card-title);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-ink);
}

.quiz-answers {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Q1 (7 options) : 2 colonnes sur desktop pour éviter une liste trop
   longue ; "Autre" (dernier item) prend toute la largeur en dessous.
   Repasse en liste simple sous 640px, cf. media query plus bas. */
.quiz-answers--grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.quiz-answers--grid .quiz-answer--other {
  grid-column: 1 / -1;
}

.quiz-answer {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 14px 20px;
  font-size: 0.95rem;
  font-weight: 600;
  font-family: inherit;
  line-height: 1.4;
  text-align: left;
  color: var(--color-ink);
  background: #ffffff;
  border: 1.5px solid var(--card-border-color);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.quiz-answer:hover {
  border-color: var(--color-accent);
}

.quiz-answer:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.quiz-answer.is-selected {
  background: var(--gradient-brand);
  border-color: transparent;
  color: #ffffff;
}

.quiz-answer:disabled {
  cursor: default;
}

/* Ligne d'exemples sous le libellé (Q1 uniquement, quand a.examples est
   fourni) : une seule ligne, tronquée proprement plutôt que d'alourdir le
   bouton. Le bouton garde une hauteur de base >= 48px (.quiz-answer
   ci-dessus) même sans cette ligne, qui s'ajoute simplement au-dessus. */
.quiz-answer-label {
  display: block;
}

.quiz-answer-examples {
  display: block;
  margin-top: 3px;
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--color-ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.quiz-answer.is-selected .quiz-answer-examples {
  color: rgba(255, 255, 255, 0.75);
}

/* Case "Autre" (Q1 à Q5) : un <div role="button"> et non un <button>, pour
   pouvoir contenir un <input> — imbriquer un champ dans un vrai <button>
   est invalide en HTML. Pas de hauteur imposée ici : la case suit
   naturellement la taille de son contenu (label, puis champ/bouton qui
   s'animent eux-mêmes ci-dessous) — aucune valeur à deviner, donc aucun
   espace résiduel possible. */
.quiz-answer--other {
  display: flex;
  flex-direction: column;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

/* Sélectionnée : fond dégradé plein (au lieu du fond pâle générique des
   autres réponses) et texte blanc, pour une case bien plus visible une
   fois qu'on écrit dedans. */
.quiz-answer--other.is-selected {
  background: var(--gradient-brand);
  border-color: transparent;
  color: #ffffff;
}

.quiz-answer-other-label {
  display: block;
}

/* Replié : hauteur 0 (donc invisible, sans clipping approximatif). Ouvert :
   se déploie sur sa propre hauteur réelle (une ligne de texte, jamais plus). */
.quiz-answer-other-input {
  display: block;
  width: 100%;
  max-height: 0;
  margin-top: 0;
  padding: 0;
  border: none;
  background: transparent;
  font: inherit;
  color: var(--color-ink);
  overflow: hidden;
  opacity: 0;
  transition: max-height 0.25s ease, margin-top 0.25s ease, opacity 0.2s ease;
}

.quiz-answer--other.is-selected .quiz-answer-other-input {
  max-height: 32px;
  margin-top: 4px;
  opacity: 1;
}

.quiz-answer-other-input::placeholder {
  color: var(--color-ink-muted);
}

.quiz-answer--other.is-selected .quiz-answer-other-input {
  color: #ffffff;
}

.quiz-answer--other.is-selected .quiz-answer-other-input::placeholder {
  color: rgba(255, 255, 255, 0.75);
}

/* La case elle-même porte déjà le retour visuel (fond dégradé + texte
   blanc) : pas besoin d'un second anneau de focus sur le champ lui-même
   une fois la saisie commencée. */
.quiz-answer-other-input:focus-visible {
  outline: none;
}

/* Bouton "Continuer" commun aux questions à choix multiple (Q2 à Q5) */
.quiz-continue {
  display: inline-flex;
  margin-top: 16px;
}

.quiz-continue:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .quiz-answer--other { transition-duration: 0s; }
}

/* Q6 : question ouverte, textarea seule + bouton final */
.quiz-textarea {
  width: 100%;
  min-height: 120px;
  padding: 14px 16px;
  font-size: 0.95rem;
  font-family: inherit;
  line-height: 1.5;
  color: var(--color-ink);
  background: #ffffff;
  border: 1.5px solid var(--card-border-color);
  border-radius: 10px;
  resize: vertical;
}

.quiz-textarea:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-color: var(--color-accent);
}

.quiz-final-continue {
  display: inline-flex;
  margin-top: 20px;
}

.quiz-back {
  display: inline-flex;
  margin-top: 24px;
  font-size: 0.85rem;
  font-weight: 600;
  font-family: inherit;
  color: var(--color-ink-muted);
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.2s ease;
}

.quiz-back:hover,
.quiz-back:focus-visible {
  color: var(--color-accent);
}

.quiz-result-title {
  margin: 0 0 12px;
  font-size: var(--fs-card-title);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-ink);
}

.quiz-result-intro {
  margin: 0 0 24px;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--color-ink-muted);
}

/* Les cartes de résultat réutilisent .card/.card--hoverable/.service-card
   (mêmes radius/bordure/ombre/icônes que la grille Services) : ici juste
   la mise en grille. */
.quiz-result-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.quiz-result-actions {
  margin-top: 32px;
}

.quiz-restart-link {
  display: inline-flex;
  margin-top: 16px;
  font-size: 0.85rem;
  font-weight: 600;
  font-family: inherit;
  color: var(--color-ink-muted);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.2s ease;
}

.quiz-restart-link:hover,
.quiz-restart-link:focus-visible {
  color: var(--color-accent);
}

@media (max-width: 640px) {
  .quiz-card { padding: 28px 20px; }

  .quiz-answers--grid {
    display: flex;
    flex-direction: column;
  }

  .quiz-result-list {
    grid-template-columns: 1fr;
  }

  .quiz-result-actions .cta-button {
    justify-content: center;
    width: 100%;
  }
}

/* ---------- Méthode ---------- */

.steps-grid {
  list-style: none;
  margin: 56px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
}

@media (max-width: 900px) {
  .steps-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 560px) {
  .steps-grid { grid-template-columns: 1fr; }
}

/* Stagger entre cartes (base 240ms posée par .reveal--content) */
.steps-grid .reveal--content:nth-child(2) { transition-delay: 330ms; }
.steps-grid .reveal--content:nth-child(3) { transition-delay: 420ms; }
.steps-grid .reveal--content:nth-child(4) { transition-delay: 510ms; }

.step-card {
  padding: 28px 24px;
}

/* Chiffre 01-04 : léger scale en plus du fade de la carte, décalé après le
   début de l'apparition de chaque carte (delay carte + 100ms). */
.step-number {
  display: block;
  margin-bottom: 16px;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-accent);
  opacity: 0;
  transform: scale(0.9);
  transition: opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1), transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: 340ms;
}

.step-card.is-visible .step-number {
  opacity: 1;
  transform: scale(1);
}

.step-card:nth-child(2) .step-number { transition-delay: 430ms; }
.step-card:nth-child(3) .step-number { transition-delay: 520ms; }
.step-card:nth-child(4) .step-number { transition-delay: 610ms; }

@media (prefers-reduced-motion: reduce) {
  .step-number {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------- À propos ---------- */

.about-content {
  max-width: 800px;
  margin: 0 auto;
  text-align: center;
}

.about-content .section-lead {
  margin-inline: auto;
}

.reassurance-line {
  margin: 32px 0 0;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--color-ink-muted);
}

/* ---------- Contact ---------- */

.section--contact {
  background: var(--color-accent);
  color: #ffffff;
}

/* Pas de halo générique .section::before ici : sans objet sur un fond déjà
   violet plein. */
.section--contact::before { content: none; }

.section--contact .section-title {
  color: #ffffff;
}

/* Sur fond violet, l'anneau de focus violet (header.css) serait invisible */
.section--contact a:focus-visible,
.section--contact button:focus-visible,
.section--contact input:focus-visible {
  outline-color: #ffffff;
}

/* Formulaire = élément principal : bloc centré, pas de colonne téléphone.
   --lift-y (parallax.js, léger, ≤ 24px) : la section "monte" doucement au
   scroll pour donner un effet de légère superposition avec ce qui précède. */
.contact-content {
  max-width: 560px;
  margin: 0 auto;
  text-align: center;
  transform: translateY(var(--lift-y, 0px));
  will-change: transform;
}

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

.contact-lead {
  margin: 20px 0 40px;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.82);
}

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
  text-align: left;
}

.form-status {
  margin: 0;
  padding: 16px 18px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.14);
  border-radius: 8px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.form-status--visible {
  opacity: 1;
}

.form-status--error {
  color: #ffe1e1;
  background: rgba(255, 255, 255, 0.1);
}

@media (prefers-reduced-motion: reduce) {
  .form-status { transition: none; }
}

.contact-alt {
  margin: 24px 0 0;
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.7);
}

.contact-alt a {
  color: #ffffff;
  font-weight: 600;
}

.contact-alt a:hover,
.contact-alt a:focus-visible {
  text-decoration: underline;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.form-field label {
  font-size: 14px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.9);
}

.form-field input {
  padding: 12px 14px;
  font-size: 15px;
  font-family: inherit;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 8px;
}

.form-field input::placeholder {
  color: rgba(255, 255, 255, 0.5);
}

.form-field input:focus-visible {
  background: rgba(255, 255, 255, 0.2);
}

.btn-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 8px;
  padding: 14px 24px;
  font-size: 15px;
  font-weight: 600;
  color: var(--color-accent);
  background: #ffffff;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background-color 0.2s ease, opacity 0.2s ease;
}

.btn-submit:hover,
.btn-submit:focus-visible {
  background: #f4f0fb;
}

/* Pendant l'envoi : inactif, aspect atténué. Une fois envoyé
   (.btn-submit--sent), le bouton reste inactif mais garde son aspect
   plein (blanc/violet) — c'est un état "validé", pas un état désactivé
   ordinaire. */
.btn-submit--sending {
  opacity: 0.7;
  cursor: not-allowed;
}

.btn-submit--sent {
  cursor: default;
}

.btn-submit-check {
  display: none;
  flex-shrink: 0;
  transform: scale(0.9);
}

.btn-submit-check path {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}

.btn-submit--sent .btn-submit-check {
  display: inline-flex;
  animation: btn-check-pop 0.2s ease 0.4s forwards;
}

.btn-submit--sent .btn-submit-check path {
  animation: btn-check-draw 0.4s ease forwards;
}

@keyframes btn-check-draw {
  from { stroke-dashoffset: 100; }
  to { stroke-dashoffset: 0; }
}

@keyframes btn-check-pop {
  from { transform: scale(0.9); }
  to { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .btn-submit--sent .btn-submit-check,
  .btn-submit--sent .btn-submit-check path {
    animation: none;
  }

  .btn-submit--sent .btn-submit-check {
    transform: scale(1);
  }

  .btn-submit--sent .btn-submit-check path {
    stroke-dashoffset: 0;
  }
}

/* ---------- Footer ---------- */

.site-footer {
  background: var(--color-footer-bg);
  padding-block: 56px;
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
}

.footer-logo {
  display: block;
  height: 32px;
  width: auto;
  margin-bottom: 10px;
}

.footer-tagline {
  margin: 0;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
}

.footer-phone {
  display: inline-block;
  margin-top: 8px;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.6);
  transition: color 0.2s ease;
}

.footer-phone:hover,
.footer-phone:focus-visible {
  color: #ffffff;
}

.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.footer-nav a {
  font-size: 14px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.75);
  transition: color 0.2s ease;
}

.footer-nav a:hover,
.footer-nav a:focus-visible {
  color: #ffffff;
}

/* ---------- Navigation : ancres, scroll fluide, label mobile ---------- */

html {
  scroll-behavior: smooth;
}

#services,
#diagnostic,
#methode,
#apropos,
#contact {
  scroll-margin-top: var(--header-height-scrolled);
}

/* .mobile-nav-label est un <p> dans header.css ; ici c'est un <a>
   (pour pointer vers #services) — on lui redonne son affichage bloc
   et un état hover cohérent avec .mobile-nav-link. */
.mobile-nav-label {
  display: block;
  transition: color var(--transition-fast);
}

.mobile-nav-label:hover,
.mobile-nav-label:focus-visible {
  color: var(--color-accent);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ---------- Révélation au scroll (cf. reveal.js) ----------
   reveal.js ne fait qu'observer et poser .is-visible (threshold 15%, une
   seule fois) : toute la chorégraphie (délais, stagger) est ici, en CSS.
   .reveal-trigger : même mécanisme d'observation mais sans effet visuel
   propre — sert de déclencheur pour d'autres règles (ligne Méthode qui se
   dessine, séparateurs de section, plus bas).

   Chorégraphie par rôle : titre (délai 0, par défaut), sous-titre
   (.reveal--subtitle, 120ms), carte ou contenu (.reveal--content, 240ms)
   — puis un stagger de 90ms entre cartes d'une même grille via nth-child
   (cf. .services-grid/.steps-grid plus bas). */

.reveal {
  opacity: 0;
  transform: translateY(40px);
  transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1), transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.reveal--subtitle { transition-delay: 120ms; }
.reveal--content { transition-delay: 240ms; }

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal--subtitle,
  .reveal--content {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------- Filigranes de section (arc du logo, très discret) ----------
   Une seule classe commune + deux variantes de côté, réutilisée à
   l'identique (forme, couleur, opacité) sur toutes les sections qui en
   ont une (hero, services, diagnostic, méthode, à propos), en alternance
   gauche/droite — pas de code dupliqué par section, un seul endroit pour
   ajuster l'opacité si besoin.
   Le décalage de parallaxe (--parallax-y) est posé par parallax.js ;
   sans JS ou avec prefers-reduced-motion, il reste à 0 (valeur de repli).
   --watermark-nudge : léger décalage vertical fixe (voir modificateurs
   --nudge-* plus bas), pour qu'une section à l'autre l'arc ne soit pas
   toujours centré exactement pareil (effet moins mécanique). Combiné au
   parallaxe dans le même transform plutôt que dans margin-top, pour ne
   pas entrer en conflit avec les tailles qui changent par breakpoint. */

.section-watermark {
  position: absolute;
  top: 50%;
  width: 940px;
  height: 940px;
  margin-top: -470px;
  color: var(--color-accent);
  opacity: 0.06;
  pointer-events: none;
  z-index: 0;
  transform: translateY(calc(var(--watermark-nudge, 0px) + var(--parallax-y, 0px)));
  will-change: transform;
}

.section-watermark svg {
  width: 100%;
  height: 100%;
  display: block;
}

.section-watermark--left {
  left: -390px;
}

.section-watermark--right {
  right: -390px;
}

.section-watermark--right svg {
  transform: scaleX(-1);
}

.section-watermark--nudge-a { --watermark-nudge: -60px; }
.section-watermark--nudge-b { --watermark-nudge: 55px; }
.section-watermark--nudge-c { --watermark-nudge: -35px; }
.section-watermark--nudge-d { --watermark-nudge: 40px; }

@media (max-width: 1024px) {
  .section-watermark {
    width: 644px;
    height: 644px;
    margin-top: -322px;
  }

  .section-watermark--left { left: -255px; }
  .section-watermark--right { right: -255px; }
}

@media (max-width: 768px) {
  .section-watermark {
    width: 370px;
    height: 370px;
    margin-top: -185px;
    opacity: 0.04;
  }

  .section-watermark--left { left: -160px; }
  .section-watermark--right { right: -160px; }
}

@media (prefers-reduced-motion: reduce) {
  .section-watermark { transition: none; }
}

/* ---------- Halo derrière les titres de section (très subtil) ---------- */

.section-title {
  position: relative;
  z-index: 1;
}

.section-title::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -30px -50px;
  background: var(--gradient-brand);
  opacity: 0.04;
  filter: blur(40px);
  border-radius: 50%;
  pointer-events: none;
}

/* Halo central du hero : plus grand/diffus que le halo générique des
   titres de section ci-dessus (même mécanisme, valeurs seulement
   surchargées ici) pour détacher légèrement le titre du fond beige,
   sans jamais concurrencer visuellement le texte (opacité max 0.06). */
.hero-title::before {
  inset: -70px -140px;
  opacity: 0.06;
  filter: blur(70px);
}

/* ---------- Méthode : ligne qui se dessine au scroll ---------- */

.steps-wrap {
  position: relative;
}

.steps-line {
  position: absolute;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 1s cubic-bezier(0.22, 1, 0.36, 1);
}

.steps-wrap.is-visible .steps-line {
  stroke-dashoffset: 0;
}

.steps-line--horizontal {
  display: block;
  top: 33px;
  left: 12.5%;
  width: 75%;
  height: 2px;
}

.steps-line--vertical {
  display: none;
}

@media (max-width: 900px) {
  .steps-line--horizontal { display: none; }

  .steps-line--vertical {
    display: block;
    top: 40px;
    bottom: 40px;
    left: 24px;
    width: 2px;
    height: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .steps-line {
    transition: none;
    stroke-dashoffset: 0;
  }
}

/* ---------- Page mentions légales ---------- */

.legal-header {
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  padding-block: 20px;
}

.legal-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.legal-header .logo-image {
  height: 40px;
}

.legal-main {
  padding-top: 64px;
}

.legal-content {
  max-width: 720px;
}

.legal-content h2 {
  margin-top: 40px;
}
