/* effects.css — améliorations UI "site moderne" (sept. 2026, validé par
   Thomas le 24/09/2026 : en-tête sticky, apparition au scroll, survol
   cartes/boutons, barre de progression, défilement fluide, feedback
   formulaire contact — mode sombre explicitement exclu du périmètre).
   Complété le 24/09/2026 (deuxième vague, validée par Thomas) : transition
   douce entre les pages, FAQ en accordéon (accueil), coche animée sur la
   page de confirmation (merci.html), sous-menu scroll-spy (offre.html).
   Complété le 25/09/2026 (troisième vague, niveaux 1 et 2 validés par
   Thomas) : pulsation du point du logo, soulignement animé de la nav,
   flèche des CTA au survol, reveal dédié du titre d'accueil, ligne de
   connexion des étapes (méthode.html), focus animé des champs de contact,
   spinner d'envoi (contact.html).

   Fichier additif et autonome : n'importe quelle règle ci-dessous peut être
   retirée sans toucher à site.css ni styles.css. Pour tout annuler d'un
   coup : supprimer ce fichier + effects.js + les balises <link>/<script>
   correspondantes + la classe "site-header" injectée par add_mobile_nav
   dans build_site.py. */

/* ---------------------------------------------------------------------
   1) En-tête sticky + masquage au scroll vers le bas / réapparition au
   scroll vers le haut — mobile ET tablette (même seuil que le burger).
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* position: sticky ne fonctionne pas ici : .page a "overflow-x: hidden"
     (nécessaire pour éviter le débordement horizontal des éléments à
     largeur fixe du design), ce qui force overflow-y à "auto" par la
     spec CSS et neutralise le sticky de tout descendant. On utilise donc
     position: fixed, ancré à la fenêtre plutôt qu'à .page, avec un
     padding-top compensatoire sur <main> (calculé par effects.js selon
     la hauteur réelle de l'en-tête) pour ne pas masquer le haut de page. */
  .site-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 150;
    background: var(--iat-fond);
    transition:
      transform 0.25s var(--iat-ease, ease),
      box-shadow 0.25s var(--iat-ease, ease);
  }
  .site-header--hidden {
    transform: translateY(-100%);
  }
  .site-header--scrolled {
    box-shadow: var(--iat-ombre);
  }
  main {
    padding-top: var(--iat-header-h, 0px);
  }
}

/* ---------------------------------------------------------------------
   2) Apparition progressive au scroll (sections de <main> + cartes).
   Appliquée par effects.js via IntersectionObserver. --iat-reveal-order
   sert à décaler légèrement les cartes d'une même grille (effet de
   cascade) ; 0 par défaut pour les blocs qui ne sont pas des cartes.
   --------------------------------------------------------------------- */
.iat-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 600ms var(--iat-ease, ease),
    transform 600ms var(--iat-ease, ease);
  transition-delay: calc(var(--iat-reveal-order, 0) * 80ms);
}
.iat-reveal--visible {
  opacity: 1;
  transform: translateY(0);
}

/* ---------------------------------------------------------------------
   3) Survol plus "vivant" sur les cartes et les boutons — s'ajoute aux
   transitions de couleur déjà définies dans styles.css, ne les remplace
   pas (une seule propriété "transition" par sélecteur au final, le
   navigateur combine simplement les deux fichiers).
   --------------------------------------------------------------------- */
.iat-card {
  transition:
    transform var(--iat-duree, 240ms) var(--iat-ease, ease),
    box-shadow var(--iat-duree, 240ms) var(--iat-ease, ease);
}
.iat-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--iat-ombre);
}
.iat-button {
  transition:
    transform var(--iat-duree, 240ms) var(--iat-ease, ease),
    box-shadow var(--iat-duree, 240ms) var(--iat-ease, ease);
}
.iat-button--primary:hover:not(:disabled),
.iat-button--secondary:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: var(--iat-ombre);
}

/* ---------------------------------------------------------------------
   4) Barre de progression de lecture — fine ligne fixée en haut de
   l'écran, couleurs de marque, au-dessus de tout le reste (z-index 300).
   --------------------------------------------------------------------- */
.iat-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 300;
  background: transparent;
  pointer-events: none;
}
.iat-progress__bar {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--iat-corail), var(--iat-ambre));
  transition: width 100ms linear;
}

/* ---------------------------------------------------------------------
   5) Défilement fluide vers les ancres (ex. sommaire de offre.html).
   --------------------------------------------------------------------- */
html {
  scroll-behavior: smooth;
}

/* ---------------------------------------------------------------------
   6) Feedback d'envoi du formulaire de contact — le bouton passe déjà en
   opacité réduite via .iat-button:disabled (styles.css) ; on ajoute
   juste un curseur "attente" tant que l'envoi est en cours.
   --------------------------------------------------------------------- */
.iat-button--loading {
  cursor: wait;
}

/* ---------------------------------------------------------------------
   7) Transition douce entre les pages (View Transitions API, navigation
   multi-documents). Purement progressif : un navigateur qui ne connaît
   pas @view-transition ignore simplement la règle et garde le
   comportement actuel (aucun fallback à écrire). Le fondu par défaut du
   navigateur suffit ; on ne personnalise pas la durée pour rester sur des
   valeurs éprouvées et cohérentes entre navigateurs.
   --------------------------------------------------------------------- */
@view-transition {
  navigation: auto;
}

/* ---------------------------------------------------------------------
   8) FAQ en accordéon (accueil, section "Vos questions avant de vous
   lancer"). Une seule question ouverte à la fois (logique dans
   effects.js) ; l'ouverture/fermeture est animée en CSS pur via la
   technique grid-template-rows 0fr -> 1fr (pas de mesure de hauteur en
   JS, pas de saut visuel).
   --------------------------------------------------------------------- */
.iat-faq__item {
  border-top: 1px solid var(--iat-bordure);
}
.iat-faq__item:last-child {
  border-bottom: 1px solid var(--iat-bordure);
}
.iat-faq__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  padding: 18px 0;
  margin: 0;
  background: none;
  border: none;
  text-align: left;
  color: inherit;
  cursor: pointer;
  font: inherit;
  -webkit-appearance: none;
  appearance: none;
}
.iat-faq__question:hover {
  color: var(--iat-petrole);
}
.iat-faq__chevron {
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  margin-top: 2px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--iat-duree, 240ms) var(--iat-ease, ease);
}
.iat-faq__item--open .iat-faq__chevron {
  transform: rotate(-135deg);
  margin-top: 6px;
}
.iat-faq__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--iat-duree, 240ms) var(--iat-ease, ease);
}
.iat-faq__panel > .iat-faq__answer-inner {
  overflow: hidden;
  min-height: 0;
}
.iat-faq__answer {
  margin: 0;
  padding-bottom: 20px;
}
.iat-faq__item--open .iat-faq__panel {
  grid-template-rows: 1fr;
}

/* ---------------------------------------------------------------------
   9) Coche animée sur la page de confirmation (merci.html) — le tracé du
   cercle puis de la coche se dessine au chargement (stroke-dashoffset),
   séquence courte (cercle puis coche) pour marquer visuellement "c'est
   fait" après l'envoi du formulaire de contact.
   --------------------------------------------------------------------- */
.iat-check {
  display: block;
  margin-bottom: 4px;
}
.iat-check__circle,
.iat-check__mark {
  fill: none;
  stroke: var(--iat-corail);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.iat-check__circle {
  stroke-dasharray: 160;
  stroke-dashoffset: 160;
  animation: iat-check-draw 500ms var(--iat-ease, ease) forwards;
}
.iat-check__mark {
  stroke-dasharray: 36;
  stroke-dashoffset: 36;
  animation: iat-check-draw 300ms var(--iat-ease, ease) 450ms forwards;
}
@keyframes iat-check-draw {
  to {
    stroke-dashoffset: 0;
  }
}

/* ---------------------------------------------------------------------
   10) Sous-menu "scroll-spy" (offre.html uniquement) — PME / Collectivités
   / Syndics. Périmètre volontairement réduit à cette seule page (validé
   par Thomas le 24/09/2026) : methode.html est trop courte pour justifier
   une navigation de ce type.

   position: sticky ne fonctionne PAS ici, pour la même raison que
   l'en-tête (règle 1 ci-dessus) : .page a "overflow-x: hidden", ce qui
   force overflow-y à "auto" par la spec CSS et neutralise le sticky de
   tout descendant. On reproduit donc le même mécanisme que l'en-tête :
   position: fixed appliquée par effects.js (classe .iat-offre-subnav--
   pinned) une fois que le scroll dépasse la position d'origine du
   sous-menu, avec un "espaceur" (.iat-offre-subnav-spacer, hauteur
   calculée en JS) pour éviter tout saut de mise en page au moment de
   l'épinglage/désépinglage. Sous le bandeau d'en-tête fixe sur
   mobile/tablette (--iat-header-h, même variable que la règle 1) ;
   directement en haut au-delà de 900px puisque l'en-tête n'y est pas
   fixe et a déjà défilé hors champ à ce moment-là.

   La mise en évidence de la section active (indépendante de
   l'épinglage) est gérée par effects.js via IntersectionObserver.
   --------------------------------------------------------------------- */
.iat-offre-subnav {
  z-index: 120;
  display: flex;
  gap: 32px;
  padding: 14px 80px;
  background: var(--iat-fond);
  border-bottom: 1px solid var(--iat-bordure);
}
.iat-offre-subnav--pinned {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}
.iat-offre-subnav-spacer {
  height: 0px;
}
@media (max-width: 900px) {
  .iat-offre-subnav {
    padding: 14px 24px;
    gap: 20px;
  }
  .iat-offre-subnav--pinned {
    top: var(--iat-header-h, 0px);
  }
}
.iat-offre-subnav__link {
  font-family: var(--iat-font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--iat-gris-texte);
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 2px solid transparent;
  transition:
    color var(--iat-duree, 240ms) var(--iat-ease, ease),
    border-color var(--iat-duree, 240ms) var(--iat-ease, ease);
}
.iat-offre-subnav__link:hover {
  color: var(--iat-petrole);
}
.iat-offre-subnav__link--active {
  color: var(--iat-petrole);
  border-bottom-color: var(--iat-corail);
}

/* Ancres des 3 sous-sections (PME / Collectivités / Syndics) : marge de
   défilement augmentée par rapport à l'origine (24px) pour tenir compte
   du sous-menu qui peut désormais se trouver épinglé par-dessus au
   moment du clic. */
.iat-offre-anchor {
  scroll-margin-top: 90px;
}
@media (max-width: 900px) {
  .iat-offre-anchor {
    scroll-margin-top: calc(var(--iat-header-h, 0px) + 90px);
  }
}

/* ---------------------------------------------------------------------
   11) Point du logo qui respire — pulsation douce et continue, sur toutes
   les occurrences du logo (en-tête, pied de page), quelle que soit la
   variante. Purement décoratif, n'affecte ni la position ni la taille de
   l'élément (déjà positionné en absolu par styles.css) : seules opacity
   et transform sont animées. Si la classe .iat-logo--anime (déjà définie
   dans styles.css pour une animation ponctuelle "le point tombe" au
   chargement) est un jour posée sur un logo, elle reprend la main sans
   conflit — sa règle est plus spécifique que celle-ci.
   --------------------------------------------------------------------- */
@keyframes iat-logo-respire {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.55;
    transform: scale(1.35);
  }
}
.iat-logo__point {
  animation: iat-logo-respire 3200ms ease-in-out infinite;
  transform-origin: center;
}

/* ---------------------------------------------------------------------
   12) Soulignement animé de la navigation au survol — trait corail qui
   grandit de gauche à droite (0 → 100% de la largeur du lien). Exclut le
   lien de la page active : celui-ci garde son soulignement statique déjà
   posé par build_site.py (linkify_header_nav), pour éviter un double
   trait au survol.
   --------------------------------------------------------------------- */
.site-nav a {
  position: relative;
}
.site-nav a:not([aria-current="page"])::after {
  content: "";
  position: absolute;
  left: 0;
  right: 100%;
  bottom: -4px;
  height: 2px;
  background: var(--iat-corail);
  transition: right var(--iat-duree, 240ms) var(--iat-ease, ease);
}
.site-nav a:not([aria-current="page"]):hover::after {
  right: 0;
}

/* ---------------------------------------------------------------------
   13) Flèche des boutons/CTA principaux et secondaires au survol — en
   plus du léger soulèvement déjà en place (règle 3). Positionnée en
   absolu dans la zone de padding du bouton (jamais dans la zone de texte,
   quelle que soit la longueur du libellé) : n'affecte donc jamais la
   largeur ni le centrage du bouton, contrairement à un ajout dans le flux
   normal. Exclue des boutons tertiaires (simples liens soulignés).
   --------------------------------------------------------------------- */
.iat-button--primary,
.iat-button--secondary {
  position: relative;
}
.iat-button--primary::after,
.iat-button--secondary::after {
  content: "→";
  position: absolute;
  right: 8px;
  top: 50%;
  opacity: 0;
  transform: translate(-6px, -50%);
  transition:
    opacity var(--iat-duree, 240ms) var(--iat-ease, ease),
    transform var(--iat-duree, 240ms) var(--iat-ease, ease);
  pointer-events: none;
}
.iat-button--primary:hover:not(:disabled)::after,
.iat-button--secondary:hover:not(:disabled)::after {
  opacity: 1;
  transform: translate(0, -50%);
}

/* ---------------------------------------------------------------------
   14) Titre de l'accueil ("L'IA, version humaine.") : apparition dédiée
   au chargement, plus marquée que le fade générique appliqué au reste de
   <main> (règle 2 ci-dessus, qui continue de s'appliquer au bloc parent
   — les deux effets se superposent sans se contredire, même direction et
   même famille d'easing). .iat-heading--display n'existe qu'une fois sur
   tout le site (le H1 de l'accueil) : aucun risque de débordement sur
   d'autres pages.
   --------------------------------------------------------------------- */
@keyframes iat-hero-titre {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.iat-heading--display {
  animation: iat-hero-titre 900ms var(--iat-ease, ease) 150ms both;
}

/* ---------------------------------------------------------------------
   15) Méthode : ligne de connexion entre les 3 étapes (Observer /
   Diagnostiquer / Accompagner), qui se dessine au fil du scroll
   (méthode.html uniquement). Piste fixe discrète + remplissage corail
   dont la hauteur est pilotée en JS (effects.js, section 7) selon la
   progression du lecteur entre le premier et le dernier numéro. Purement
   décorative (aria-hidden) : la grille de contenu (grid-methode-step)
   n'est pas modifiée. Masquée sous 900px, où grid-methode-step repasse
   en une colonne (site.css) — la ligne, alignée sur la colonne des
   numéros à 120px, n'a alors plus de sens géométrique.
   --------------------------------------------------------------------- */
.iat-methode-etapes {
  position: relative;
}
.iat-methode-ligne {
  position: absolute;
  top: 32px;
  bottom: 32px;
  left: 60px;
  width: 2px;
  background: var(--iat-bordure);
  transform: translateX(-1px);
}
.iat-methode-ligne__remplissage {
  width: 100%;
  height: 0%;
  background: var(--iat-corail);
}
@media (max-width: 900px) {
  .iat-methode-ligne {
    display: none;
  }
}

/* ---------------------------------------------------------------------
   16) Contact : trait corail qui se dessine sous le champ actif (au
   focus), en plus de l'anneau de focus déjà présent (styles.css,
   accessibilité — non touché). :focus-within sur .iat-field plutôt que
   :focus sur l'input : couvre aussi bien les champs texte que le select
   et le textarea sans règle dédiée à chacun.
   --------------------------------------------------------------------- */
.iat-field {
  position: relative;
}
.iat-field::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 0%;
  background: var(--iat-corail);
  transition: width var(--iat-duree, 240ms) var(--iat-ease, ease);
  pointer-events: none;
}
.iat-field:focus-within::after {
  width: 100%;
}

/* ---------------------------------------------------------------------
   17) Contact : petit indicateur de chargement (spinner SVG en rotation)
   inséré par effects.js à côté du texte "Envoi en cours…", même famille
   technique que la coche animée de merci.html (cercle SVG, stroke
   corail) mais en rotation continue plutôt qu'en tracé unique — plus
   adapté à une attente de durée inconnue.
   --------------------------------------------------------------------- */
@keyframes iat-spin {
  to {
    transform: rotate(360deg);
  }
}
.iat-spinner {
  display: inline-block;
  margin-right: 8px;
  vertical-align: -3px;
  animation: iat-spin 800ms linear infinite;
}

/* ---------------------------------------------------------------------
   Accessibilité : si l'utilisateur a demandé "reduce motion" au niveau
   système, on neutralise tous les effets de mouvement ci-dessus (même
   principe que l'animation du logo déjà présente dans styles.css) sans
   rien retirer côté contenu ou fonctionnalité.
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .site-header {
    transition: none;
  }
  .site-header--hidden {
    transform: none;
  }
  .iat-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .iat-card,
  .iat-button {
    transition:
      background-color var(--iat-duree, 240ms) var(--iat-ease, ease),
      color var(--iat-duree, 240ms) var(--iat-ease, ease),
      border-color var(--iat-duree, 240ms) var(--iat-ease, ease);
  }
  .iat-card:hover,
  .iat-button--primary:hover:not(:disabled),
  .iat-button--secondary:hover:not(:disabled) {
    transform: none;
  }
  html {
    scroll-behavior: auto;
  }
  .iat-progress__bar {
    transition: none;
  }
  @view-transition {
    navigation: none;
  }
  .iat-faq__chevron,
  .iat-faq__panel {
    transition: none;
  }
  .iat-check__circle,
  .iat-check__mark {
    animation: none;
    stroke-dashoffset: 0;
  }
  .iat-offre-subnav__link {
    transition: none;
  }
  .iat-logo__point {
    animation: none;
  }
  .site-nav a:not([aria-current="page"])::after {
    transition: none;
  }
  .iat-button--primary::after,
  .iat-button--secondary::after {
    transition: none;
  }
  .iat-heading--display {
    animation: none;
    opacity: 1;
    transform: none;
  }
  .iat-methode-ligne__remplissage {
    height: 100%;
  }
  .iat-field::after {
    transition: none;
  }
  .iat-spinner {
    animation: none;
  }
}
