/* ==========================================================================
   FGM TECHNOLOGIES — Système d'animation (motion system)
   Fichier : assets/css/animations.css · Version 1.0 · 26/10/2026
   --------------------------------------------------------------------------
   PROMPT 06 — un seul système réutilisable pour toute la page, à partir des
   comportements réellement mesurés sur la référence Qarin (livrable PROMPT 02,
   catalogue appear_catalog.json : ressorts 350/70 et 300/80, tween 0,6 s
   [.5, 0, .88, .77], signature H1 mot à mot 0,2 s / 0,05 s / flou 10 px).

   PRINCIPES :
   1. PROGRESSIF — tout état masqué est doublement verrouillé :
        html.fgm-js  (posée par animations.js lui-même : si le script ne
        s'exécute pas, rien n'est jamais masqué) ;
        @media (prefers-reduced-motion: no-preference)  (mouvement réduit :
        rien n'est masqué ni animé).
   2. PERFORMANT — uniquement des propriétés compositées (transform, opacity),
      plus filter sur la seule signature mot-à-mot (limitée au H1). Aucune
      propriété de layout animée, aucune boucle infinie décorative.
   3. NON BLOQUANT — déplacements ≤ 48 px, durées ≤ 750 ms, délais
      d'échelonnement plafonnés (tokens --fgm-echelon-*).
   4. RÉUTILISABLE — 3 variantes de révélation + échelonnement déclaratif :
        .fgm-reveal              (proche : 20 px, ressort 350/70) [QARIN]
        .fgm-reveal--section     (section : 48 px, ressort 300/80 amorti)
        .fgm-reveal--media       (visuel : échelle 1,06 → 1, tween 0,6 s)
        [data-fgm-echelon]       (conteneur : échelonne ses .fgm-reveal)
        [data-fgm-delai="300"]   (délai explicite en ms)
      Les révélations sont portées par des ANIMATIONS (une seule fois, fill
      both) et non par des transitions : les transitions de survol propres à
      chaque composant (.fgm-card, .fgm-btn, .fgm-link) restent intactes.
      Le nettoyage .fgm-reveal--fini (posé par animations.js à animationend)
      rend définitivement la main aux styles normaux.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Défilement entre ancres — transition de navigation sans JavaScript
      (neutralisé en mouvement réduit par le bloc global de fgm-tokens.css)
   -------------------------------------------------------------------------- */
html.fgm-js { scroll-behavior: smooth; }
html { scroll-padding-top: 5.5rem; }   /* ancrages sous l'en-tête collant */

/* --------------------------------------------------------------------------
   2. En-tête — transition d'état au défilement
      animations.js pose data-defile="true" au-delà de 8 px (rAF throttlé) ;
      sans JavaScript, l'en-tête garde son état de repos, pleinement usable.
   -------------------------------------------------------------------------- */
.fgm-header {
  transition:
    background-color var(--fgm-dur-base) var(--fgm-ease-standard),
    box-shadow var(--fgm-dur-base) var(--fgm-ease-standard);
}
html.fgm-js .fgm-header[data-defile="true"] {
  background: color-mix(in srgb, var(--fgm-bg) 96%, transparent);
  box-shadow: var(--fgm-ombre-sm);
}

/* --------------------------------------------------------------------------
   3. Révélations au scroll — le système (double porte d'entrée)
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {

  /* État d'attente : masqué uniquement si JS actif ET mouvement souhaité */
  html.fgm-js .fgm-reveal:not(.fgm-reveal--visible) {
    opacity: 0;
  }

  /* Révélation « proche » — défaut (éléments, cartes)
     [QARIN] y : 20 px · ressort Framer 350/70 → cubic-bezier(.34, 1.56, .64, 1) */
  html.fgm-js .fgm-reveal--visible {
    opacity: 1;
    transform: none;
    animation: fgm-revelation var(--fgm-dur-reveal-proche) var(--fgm-ease-ressort) both;
    animation-delay: var(--fgm-reveal-delai, 0ms);
  }

  /* Révélation « section » — blocs d'en-tête de section
     [QARIN] y : 80 px mesurés, appliqués à 48 px (grands déplacements évités)
     · ressort 300/80 → courbe amortie sans dépassement */
  html.fgm-js .fgm-reveal--section {
    --fgm-distance-revele: var(--fgm-reveal-section);
    animation-duration: var(--fgm-dur-reveal-section);
    animation-timing-function: var(--fgm-ease-ressort-lourd);
  }

  /* Révélation « média » — visuels et panneaux illustrés
     [QARIN] échelle 1,06 → 1 · tween 0,6 s (.5, 0, .88, .77) · palier
     d'opacité .7 = état initial mesuré (adapté : départ à 0 pour rester
     masqué pendant le délai d'échelonnement) */
  html.fgm-js .fgm-reveal--media {
    animation-name: fgm-revelation-media;
    animation-duration: var(--fgm-dur-media);
    animation-timing-function: var(--fgm-ease-entree);
  }

  /* Le titre « mot à mot » n'anime que ses mots : le conteneur H1 sert
     d'ancêtre observé, sans animation propre (pas d'opacité composée). */
  html.fgm-js .fgm-titre-anime.fgm-reveal--visible {
    animation: none;
  }

  /* Nettoyage après animation : les survols des composants reprennent
     leurs transitions propres (cartes, boutons, liens). */
  html.fgm-js .fgm-reveal--fini {
    animation: none;
  }

  /* Repli immédiat (IO absent, échec, mouvement réduit basculé en cours de
     session) : les classes d'état suffisent, aucune animation jouée. */
  html.fgm-instant .fgm-reveal--visible {
    animation: none;
  }

  /* Signature « titre mot à mot » — équivalent natif de la signature Qarin :
     chaque mot est un <span class="fgm-mot"> généré côté serveur (PHP),
     cascade --fgm-mot-depart + --i × --fgm-mot-delai [QARIN : 0,2 s / 0,05 s]. */
  html.fgm-js .fgm-titre-anime .fgm-mot {
    display: inline-block;
    opacity: 0;
    filter: blur(10px);
    transform: translateY(5px);
    transition:
      opacity var(--fgm-dur-lente) var(--fgm-ease-ressort),
      filter var(--fgm-dur-lente) var(--fgm-ease-standard),
      transform var(--fgm-dur-lente) var(--fgm-ease-ressort);
    transition-delay: calc(var(--fgm-mot-depart, 200ms) + var(--i, 0) * var(--fgm-mot-delai));
  }
  html.fgm-js .fgm-titre-anime.fgm-reveal--visible .fgm-mot {
    opacity: 1;
    filter: blur(0);
    transform: none;
  }

  /* Panneau de navigation mobile — fondu et glissement légers.
     Hors de ce bloc (mouvement réduit), l'ouverture reste instantanée :
     la règle display est posée plus bas, hors du gate. */
  @media (max-width: 1023px) {
    html.fgm-js .fgm-nav {
      display: block;                 /* géré hors gate aussi — voir §5 */
      opacity: 0;
      transform: translateY(-12px);
      visibility: hidden;
      transition:
        opacity var(--fgm-dur-base) var(--fgm-ease-standard),
        transform var(--fgm-dur-base) var(--fgm-ease-standard),
        visibility 0s linear var(--fgm-dur-base);
    }
    html.fgm-js .fgm-nav[data-ouvert="true"] {
      opacity: 1;
      transform: none;
      visibility: visible;
      transition-delay: 0s;
    }
  }
}

/* Images-clés du système — transform/opacity exclusivement */
@keyframes fgm-revelation {
  from {
    opacity: 0;
    transform: translateY(var(--fgm-distance-revele, var(--fgm-reveal-proche)));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fgm-revelation-media {
  0% {
    opacity: 0;
    transform: scale(1.06);           /* [QARIN] échelle initiale mesurée */
  }
  35% {
    opacity: .7;                      /* [QARIN] palier d'opacité mesuré */
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

/* --------------------------------------------------------------------------
   4. Panneau mobile — l'ouverture doit rester possible même en mouvement
      réduit (hors gate) : avec JS, le panneau est rendu et bascule via
      data-ouvert ; sans JS, le patron display:none/block du design system
      s'applique (liens de secours dans le pied de page).
   -------------------------------------------------------------------------- */
@media (max-width: 1023px) {
  html.fgm-js .fgm-nav {
    display: block;
  }
  html.fgm-js .fgm-nav[data-ouvert="false"] {
    visibility: hidden;               /* fermé : hors tabulation et lecture */
  }
}

/* --------------------------------------------------------------------------
   5. Filets de sécurité complémentaires
   -------------------------------------------------------------------------- */

/* Impression : tout est visible, quel que soit l'état de révélation. */
@media print {
  html.fgm-js .fgm-reveal,
  html.fgm-js .fgm-reveal:not(.fgm-reveal--visible),
  html.fgm-js .fgm-titre-anime .fgm-mot {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
    transition: none !important;
  }
}

/* Utilitaire pour les futures images réelles (fiches projets, articles) :
   envelopper l'image dans .fgm-media-cadre et poser .fgm-reveal--media sur
   l'élément révélé — l'échelle 1,06 → 1 reste contenue dans le cadre. */
.fgm-media-cadre {
  overflow: hidden;
  border-radius: var(--fgm-radius-md);
}
.fgm-media-cadre > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
