/* ============================================================
   ERYON · BOUNCE ANIMATIONS — kit autonome
   Version : 1.0
   
   Usage minimal :
     <link rel="stylesheet" href="bounce-animations.css">
     <script src="bounce-animations.js" defer></script>
   
   Aucun attribut requis sur <body>. Le runtime tagge automatiquement
   les sélecteurs courants (cartes, sections, grilles, glyphes).
   
   Pour cibler manuellement un élément :
     <div class="b-anim">...</div>           ← fade-up
     <div class="b-anim-scale">...</div>     ← scale + bounce
     <div class="b-fade">...</div>           ← fade pur
     <div class="b-anim-left">...</div>      ← slide depuis gauche
     <div class="b-stagger">                 ← stagger sur enfants
       <div class="b-anim-scale">...</div>
       <div class="b-anim-scale">...</div>
     </div>
   ============================================================ */

/* ------------------------------------------------------------
   1. TOKENS — easing & timings du preset "bounce"
   ------------------------------------------------------------ */
:root {
  --b-ease: cubic-bezier(.34, 1.56, .64, 1);
  --b-ease-soft: cubic-bezier(.22, .61, .36, 1);
  --b-dur: .9s;
  --b-dur-slow: 1.3s;
  --b-stagger: 70ms;
  --b-distance: 32px;
  --b-scale-from: .88;
}

/* ------------------------------------------------------------
   2. PRIMITIVES
   ------------------------------------------------------------ */

/* Fade-up avec rebond — only hidden when JS is active (.js-bounce on body) */
.js-bounce .b-anim {
  opacity: 0;
  transform: translateY(var(--b-distance));
  transition:
    opacity var(--b-dur) var(--b-ease-soft),
    transform var(--b-dur) var(--b-ease);
  will-change: opacity, transform;
}
.b-anim.is-in {
  opacity: 1;
  transform: translateY(0);
}
/* Above-the-fold hero heading must NEVER be hidden then animated in.
   The JS auto-tags `.hero h1` with `.b-anim`, which causes a visible
   translate when JS runs after first paint — counted as CLS by Chrome.
   Force the hero h1 to stay at its natural position with full opacity. */
.js-bounce .hero h1.b-anim,
.js-bounce .hero h1.b-anim.is-in {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* Fade pur */
.js-bounce .b-fade {
  opacity: 0;
  transition: opacity var(--b-dur-slow) var(--b-ease-soft);
}
.b-fade.is-in { opacity: 1; }

/* Slide depuis gauche */
.js-bounce .b-anim-left {
  opacity: 0;
  transform: translateX(-32px);
  transition:
    opacity var(--b-dur) var(--b-ease-soft),
    transform var(--b-dur) var(--b-ease);
}
.b-anim-left.is-in {
  opacity: 1;
  transform: translateX(0);
}

/* Slide depuis droite */
.js-bounce .b-anim-right {
  opacity: 0;
  transform: translateX(32px);
  transition:
    opacity var(--b-dur) var(--b-ease-soft),
    transform var(--b-dur) var(--b-ease);
}
.b-anim-right.is-in {
  opacity: 1;
  transform: translateX(0);
}

/* Scale + translation */
.js-bounce .b-anim-scale {
  opacity: 0;
  transform: scale(var(--b-scale-from)) translateY(calc(var(--b-distance) * .65));
  transition:
    opacity var(--b-dur) var(--b-ease-soft),
    transform var(--b-dur) var(--b-ease);
  will-change: opacity, transform;
}
.b-anim-scale.is-in {
  opacity: 1;
  transform: scale(1) translateY(0);
}

/* ------------------------------------------------------------
   3. STAGGER — décale les enfants successifs
   ------------------------------------------------------------ */
.b-stagger.is-in > *:nth-child(1)  { transition-delay: calc(var(--b-stagger) * 0); }
.b-stagger.is-in > *:nth-child(2)  { transition-delay: calc(var(--b-stagger) * 1); }
.b-stagger.is-in > *:nth-child(3)  { transition-delay: calc(var(--b-stagger) * 2); }
.b-stagger.is-in > *:nth-child(4)  { transition-delay: calc(var(--b-stagger) * 3); }
.b-stagger.is-in > *:nth-child(5)  { transition-delay: calc(var(--b-stagger) * 4); }
.b-stagger.is-in > *:nth-child(6)  { transition-delay: calc(var(--b-stagger) * 5); }
.b-stagger.is-in > *:nth-child(7)  { transition-delay: calc(var(--b-stagger) * 6); }
.b-stagger.is-in > *:nth-child(8)  { transition-delay: calc(var(--b-stagger) * 7); }
.b-stagger.is-in > *:nth-child(9)  { transition-delay: calc(var(--b-stagger) * 8); }
.b-stagger.is-in > *:nth-child(10) { transition-delay: calc(var(--b-stagger) * 9); }
.b-stagger.is-in > *:nth-child(11) { transition-delay: calc(var(--b-stagger) * 10); }
.b-stagger.is-in > *:nth-child(12) { transition-delay: calc(var(--b-stagger) * 11); }

/* ------------------------------------------------------------
   4. GLYPHES — animations spécifiques arches & iris
   ------------------------------------------------------------ */

/* ARCHES — only hidden when JS active */
.js-bounce .arches {
  opacity: 0;
  transform: translateY(20px) scale(.92);
  transition:
    opacity var(--b-dur) var(--b-ease-soft),
    transform var(--b-dur) var(--b-ease);
}
.arches.is-in {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.js-bounce .arches svg path {
  stroke-dasharray: 600;
  stroke-dashoffset: 600;
  opacity: 0;
  transition:
    stroke-dashoffset var(--b-dur-slow) var(--b-ease-soft),
    opacity .5s var(--b-ease-soft);
}
.arches.is-in svg path {
  stroke-dashoffset: 0;
  opacity: 1;
}
.arches.is-in svg path:nth-child(1) { transition-delay: 0ms; }
.arches.is-in svg path:nth-child(2) { transition-delay: calc(var(--b-stagger) * 3); }
.arches.is-in svg path:nth-child(3) { transition-delay: calc(var(--b-stagger) * 6); }

/* IRIS */
.js-bounce .iris-glyph {
  opacity: 0;
  transform: rotate(-12deg) scale(.7);
  transition:
    opacity var(--b-dur) var(--b-ease-soft),
    transform var(--b-dur) var(--b-ease);
}
.iris-glyph.is-in {
  opacity: 1;
  transform: rotate(0deg) scale(1);
}

/* SPECTRUM & DUO-GLYPH */
.js-bounce .duo-glyph-large {
  opacity: 0;
  transform: scaleX(0);
  transform-origin: center;
  transition:
    opacity .6s var(--b-ease-soft),
    transform var(--b-dur) var(--b-ease);
}
.duo-glyph-large.is-in {
  opacity: 1;
  transform: scaleX(1);
}
.js-bounce .spectrum {
  opacity: 0;
  transform: scaleX(0);
  transform-origin: left center;
  transition:
    opacity .8s var(--b-ease-soft),
    transform var(--b-dur-slow) var(--b-ease);
}
.spectrum.is-in {
  opacity: 1;
  transform: scaleX(1);
}

/* ------------------------------------------------------------
   5. PILL-MARKS dans les titres — pop avec rebond marqué
   Only hide when .js-bounce class is on body (set by bounce JS)
   ------------------------------------------------------------ */
/* Pill-marks: fade only (no scale — display:inline can't transform).
   This prevents pills from being clipped by container overflow. */
/* Only hide pills inside scroll-animated containers (not hero/page-header) */
.js-bounce .section-head .pill-mark,
.js-bounce .editorial .pill-mark,
.js-bounce .cta-section .pill-mark {
  opacity: 0;
  transition: opacity .6s var(--b-ease-soft);
}
/* Hero & page-header pills are ALWAYS visible (above the fold) */
.hero .pill-mark,
.page-header .pill-mark {
  opacity: 1 !important;
}
/* Reveal pills when parent is scrolled into view */
.b-anim.is-in .pill-mark,
.b-anim-scale.is-in .pill-mark,
.section-head.is-in .pill-mark,
.editorial.is-in .pill-mark,
.cta-section.is-in .pill-mark {
  opacity: 1;
  transition-delay: 220ms;
}

/* Numéros de section */
.section-head .num,
.sec-head .num,
.b-num {
  display: inline-block;
  transform: translateY(-10px) scale(.85);
  opacity: 0;
  transition:
    opacity .6s var(--b-ease-soft),
    transform .8s var(--b-ease);
}
.section-head.is-in .num,
.sec-head.is-in .num,
.is-in .b-num {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* ------------------------------------------------------------
   6. PARALLAXE SOFT — discrète sur ce preset
   ------------------------------------------------------------ */
.b-parallax {
  will-change: transform;
  transform: translate3d(0, var(--b-parallax, 0px), 0);
  transition: transform .15s linear;
}

/* ------------------------------------------------------------
   7. ACCESSIBILITÉ
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .b-anim,
  .b-anim-left,
  .b-anim-right,
  .b-anim-scale,
  .b-fade,
  .arches,
  .arches svg path,
  .iris-glyph,
  .duo-glyph-large,
  .spectrum,
  h1 .pill-mark,
  h2 .pill-mark,
  h3 .pill-mark,
  .section-head .num,
  .sec-head .num,
  .b-num,
  .b-parallax {
    opacity: 1 !important;
    transform: none !important;
    stroke-dashoffset: 0 !important;
    transition: none !important;
  }
}
