/* ============================================================================
   Composant : animations « nouvelle génération » (lot du 25/09).
   Chargé APRÈS app.css : remplace le style des révélations existantes
   (mêmes attributs data-reveal / data-words / data-panel, aucun balisage cassé)
   et ajoute la cascade orchestrée (--d posé par app.js), les survols riches
   et la parallaxe au défilement (data-drift).
   Principes : déclenchement à l'arrivée sur la section (IntersectionObserver),
   entrées par animations (keyframes) puis .reveal-done → plus aucune animation
   résiduelle : les survols restent vifs. prefers-reduced-motion respecté.
   ========================================================================== */
:root {
  --ease-exp: cubic-bezier(.16, 1, .3, 1);      /* sortie expressive (signature) */
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1); /* léger rebond (petits éléments) */
}

/* ---------- Révélations : neutralise l'ancien système à transitions ---------- */
html.js [data-reveal] { opacity: 0; transform: none; filter: none; transition: none; }
html.js [data-reveal].is-in {
  animation: mv-up .85s var(--ease-exp) both;
  animation-delay: var(--d, 0s);
}
html.js [data-reveal="left"].is-in   { animation-name: mv-left; }
html.js [data-reveal="right"].is-in  { animation-name: mv-right; }
html.js [data-reveal="down"].is-in   { animation-name: mv-down; }
html.js [data-reveal="zoom"].is-in   { animation-name: mv-zoom; }
html.js [data-reveal="blur"].is-in   { animation-name: mv-blur; animation-duration: 1s; }
html.js [data-reveal="rotate"].is-in { animation-name: mv-rotate; }
html.js [data-reveal="flip"].is-in   { animation-name: mv-flip; perspective: 1000px; }
/* Entrée jouée : plus d'animation (les survols — dont le basculement 3D — reprennent la main).
   transform/filter ne sont PAS redéclarés ici : l'état de base les laisse à none et
   .mv-tilt (défini plus bas, même spécificité, donc prioritaire) pilote le transform. */
html.js [data-reveal].reveal-done { animation: none; opacity: 1; }

@keyframes mv-up     { from { opacity: 0; transform: translateY(46px) scale(.985); filter: blur(9px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes mv-down   { from { opacity: 0; transform: translateY(-46px) scale(.985); filter: blur(9px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes mv-left   { from { opacity: 0; transform: translateX(-64px) rotate(-1.1deg); filter: blur(9px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes mv-right  { from { opacity: 0; transform: translateX(64px) rotate(1.1deg); filter: blur(9px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes mv-zoom   { from { opacity: 0; transform: scale(.86) translateY(14px); filter: blur(7px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes mv-blur   { from { opacity: 0; transform: translateY(20px); filter: blur(20px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes mv-rotate { from { opacity: 0; transform: rotate(-4deg) translateY(38px); filter: blur(7px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes mv-flip   { from { opacity: 0; transform: perspective(1000px) rotateX(32deg) translateY(28px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }

/* ---------- Titres mot à mot : cascade après le délai du groupe ---------- */
[data-words] { perspective: 900px; }
html.js .word { display: inline-block; opacity: 0; transform: none; filter: none; transition: none; }
html.js .is-in .word {
  animation: mv-word .75s var(--ease-exp) both;
  /* animation-delay posé par app.js : calc(var(--d) + n × 38 ms) */
}
html.js .is-in.reveal-done .word { animation: none; opacity: 1; }
@keyframes mv-word { from { opacity: 0; transform: translateY(.65em) rotateX(40deg); filter: blur(7px); } to { opacity: 1; transform: none; filter: blur(0); } }

/* ---------- Héros de l'accueil : séquence « suspense » (25/09) ----------
   1. « Assurance transport professionnel : » arrive en zoom qui se révèle,
   2. puis « roulez couvert, », 3. puis « partout en France. » qui descend.
   Le h1 porte data-reveal pour l'observation seulement : les segments font tout. */
html.js h1.h1-seq, html.js h1.h1-seq.is-in { opacity: 1; animation: none; }
html.js .hseq { display: inline-block; opacity: 0; }
html.js .h1-seq.is-in .hseq1 { animation: hs-zoom 1.05s var(--ease-exp) .15s both; }
html.js .h1-seq.is-in .hseq2 { animation: hs-up .8s var(--ease-exp) 1.05s both; }
html.js .h1-seq.is-in .hseq3 { animation: hs-down .85s var(--ease-exp) 1.65s both; }
@keyframes hs-zoom { from { opacity: 0; transform: scale(.55); filter: blur(12px); } 60% { filter: blur(0); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes hs-up   { from { opacity: 0; transform: translateY(30px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes hs-down { from { opacity: 0; transform: translateY(-42px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }

/* ---------- Images : rideau doux à l'entrée, zoom vif au survol ---------- */
[data-panel] { overflow: hidden; }
html.js [data-panel] img, html.js [data-panel] video { transform: scale(1.09); transition: transform 1.1s var(--ease-exp); }
html.js [data-panel].is-in img, html.js [data-panel].is-in video { transform: none; transition: transform .6s var(--ease-exp); }

/* ---------- Trait des surtitres : se déploie à l'arrivée ---------- */
html.js [data-reveal] .tick { transform: scaleX(0); transform-origin: 0 50%; transition: transform .8s var(--ease-exp); transition-delay: calc(var(--d, 0s) + .3s); }
html.js [data-reveal].is-in .tick { transform: scaleX(1); }

/* ---------- Compteurs : petite impulsion en fin de course ---------- */
.count-pop { animation: mv-pop .45s var(--ease-spring); }
@keyframes mv-pop { 40% { transform: scale(1.14); } to { transform: none; } }

/* ============================================================================
   Survols riches (le « jeu sur le hover ») — pointeur précis uniquement.
   Le basculement 3D des grandes cartes est piloté par app.js (data-tilt).
   ========================================================================== */
@media (hover: hover) and (pointer: fine) {
  /* Grandes cartes : l'élévation vit dans le tilt JS ; ici ombre, bordure, contenus. */
  .sol-card, .art-card, .prot-card, .step-card, .rev-card { transition: box-shadow .35s var(--ease-exp), border-color .35s; }
  .sol-card:hover, .art-card:hover { box-shadow: 0 30px 60px -22px rgba(11, 99, 206, .38); }
  .prot-card:hover, .step-card:hover, .rev-card:hover { box-shadow: 0 24px 48px -20px rgba(16, 24, 43, .28); }

  /* L'image répond au survol de la carte (zoom léger, jamais brutal). */
  .sol-card:hover [data-panel].is-in img, .art-card:hover [data-panel].is-in img { transform: scale(1.055); }

  /* Le numéro de carte glisse, la flèche avance : l'œil est guidé vers l'action. */
  .sol-card .sol-num { transition: transform .45s var(--ease-exp), opacity .3s; }
  .sol-card:hover .sol-num { transform: translateY(-6px); opacity: .92; }
  .link-arrow { transition: color .25s; }
  .link-arrow .ic { transition: transform .35s var(--ease-spring); }
  .sol-card:hover .link-arrow .ic, .art-card:hover .link-arrow .ic { transform: translateX(5px); }

  /* Icônes de cartes : petite bascule élastique. */
  .sol-ic, .prot-ic, .step-ic { transition: transform .45s var(--ease-spring); }
  .sol-card:hover .sol-ic { transform: translateY(-4px) rotate(-4deg) scale(1.06); }
  .prot-card:hover .prot-ic, .step-card:hover .step-ic { transform: translateY(-4px) scale(1.08); }

  /* Boutons pleins : balayage lumineux discret. */
  .btn-cta, .btn-solid { position: relative; overflow: hidden; }
  .btn-cta::after, .btn-solid::after {
    content: ""; position: absolute; inset: 0 auto 0 -80%; width: 55%;
    background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .5), transparent);
    transform: skewX(-18deg); transition: none; pointer-events: none;
  }
  .btn-cta:hover::after, .btn-solid:hover::after { left: 130%; transition: left .7s var(--ease-exp); }
}

/* ---------- Basculement 3D (app.js pose la variable de transform) ----------
   Classe doublée : bat la règle « .is-in { transform:none } » du CSS historique
   (spécificité 0,3,1) tout en restant pilotée par la variable --mv-t. */
html.js .mv-tilt.mv-tilt { transform: var(--mv-t, none); }
html.js .mv-tilt.is-tilting { transition: none; }
html.js .mv-tilt:not(.is-tilting) { transition: transform .5s var(--ease-exp), box-shadow .35s var(--ease-exp), border-color .35s; }

/* ---------- Mobile : trajets raccourcis, cascade resserrée (fluidité) ---------- */
@media (max-width: 640px) {
  @keyframes mv-up    { from { opacity: 0; transform: translateY(30px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }
  @keyframes mv-down  { from { opacity: 0; transform: translateY(-30px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }
  @keyframes mv-left  { from { opacity: 0; transform: translateX(-34px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }
  @keyframes mv-right { from { opacity: 0; transform: translateX(34px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }
}

/* ---------- Réduction des animations demandée par le système ---------- */
@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal], html.js .word, html.js .hseq { opacity: 1 !important; transform: none !important; filter: none !important; animation: none !important; transition: none !important; }
  html.js [data-panel] img, html.js [data-panel] video { transform: none !important; }
  html.js [data-reveal] .tick { transform: none !important; transition: none !important; }
  html.js .mv-tilt { transform: none !important; }
  .btn-cta::after, .btn-solid::after { display: none; }
  .count-pop { animation: none; }
}
