/* ============================================================
   Lightworker Collective — Animations (animations.css)
   Page « Activation de Kundalini ». La lumière est la signature :
   lueurs floutées qui respirent, lentement. Tout le reste demeure
   sobre et discipliné.

   Cohérence : une seule famille d'easing (--ease-soft),
   durées 0,6 à 1,1 s, staggers 60 à 120 ms. La variété vient
   de la direction et de la nature du mouvement, jamais du rythme.
   Les états initiaux cachés sont scopés sous html.js : sans
   JavaScript, tout le contenu est visible (accessibilité).

   Le scroll CONTRÔLE l'apparition : reveals IntersectionObserver
   partout + UNE scène épinglée scrubée (trailer -> « C'est pour
   toi si… », voir components.css + main.js).
   ============================================================ */

/* ------------------------------------------------------------
   Blooms ambiants — grands radial-gradients très flous qui
   respirent en boucle lente (transform/opacity seulement).
   Jamais plus de 2 par viewport. Jamais néon.
   ------------------------------------------------------------ */

.bloom {
  position: absolute;
  width: min(46vw, 620px);
  aspect-ratio: 1;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.7;
  pointer-events: none;
  z-index: 0;
  animation: bloom-breathe 12s ease-in-out infinite alternate;
  will-change: transform, opacity;
}

@keyframes bloom-breathe {
  from { transform: scale(1);    opacity: 0.7; }
  to   { transform: scale(1.12); opacity: 0.9; }
}

.bloom--powder { background: radial-gradient(circle, color-mix(in srgb, var(--powder-blue) 55%, transparent), transparent 70%); }
.bloom--teal   { background: radial-gradient(circle, color-mix(in srgb, var(--teal) 50%, transparent), transparent 70%); }
.bloom--light  { background: radial-gradient(circle, color-mix(in srgb, var(--color-celestial-light) 50%, transparent), transparent 70%); }

.bloom--tl { top: -8%; left: -6%; }
.bloom--br { right: -8%; bottom: -10%; animation-duration: 14s; }
.bloom--center { left: calc(50% - min(23vw, 310px)); top: -12%; animation-duration: 13s; }

/* Les blooms qui débordent passent au-dessus du fond voisin (couche z-auto)
   tout en restant sous les contenus (.section > .container = z:1). */
.bloom--br { z-index: 1; }

/* ------------------------------------------------------------
   HERO — séquence orchestrée au chargement.
   Chaque élément .hro porte son délai (--d); tout démarre quand
   loading.js pose html.lw-ready.
   ------------------------------------------------------------ */

.js .hro {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.9s var(--ease-soft) var(--d, 0s),
              transform 0.9s var(--ease-soft) var(--d, 0s);
}

/* Le titre entre ligne par ligne, masqué par sa ligne */
.hero .h1-line { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.hero .h1-inner { display: block; }
.js .hero .h1-line .hro { transform: translateY(105%); }

html.lw-ready .hro { opacity: 1; transform: none; }

/* Spécificité supérieure à l'état initial des lignes du titre. */
html.lw-ready .hero .h1-line .hro { transform: none; }

/* ------------------------------------------------------------
   Chorégraphie des reveals — pattern interrupts.
   Mécanique commune : IntersectionObserver ajoute .is-visible
   une seule fois par section (voir main.js).
   ------------------------------------------------------------ */

/* Tête de section : entrée douce commune à tous les patterns */
.js [data-reveal] .section-head {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.8s var(--ease-soft), transform 0.8s var(--ease-soft);
}

.js [data-reveal].is-visible .section-head { opacity: 1; transform: none; }

/* Trailer + vidéo FAQ — split croisé : média par la gauche, intention par
   la droite, directions opposées simultanées. */
.js [data-reveal="split-cross"] [data-rv="from-left"],
.js [data-reveal="split-cross"] [data-rv="from-right"] {
  opacity: 0;
  transition: opacity 0.95s var(--ease-soft), transform 0.95s var(--ease-soft);
}

.js [data-reveal="split-cross"] [data-rv="from-left"]  { transform: translateX(-48px); }
.js [data-reveal="split-cross"] [data-rv="from-right"] { transform: translateX(48px); }

.js [data-reveal="split-cross"].is-visible [data-rv="from-left"],
.js [data-reveal="split-cross"].is-visible [data-rv="from-right"] { opacity: 1; transform: none; }

/* Trailer — la copie (petit texte -> titre -> paragraphe) se révèle
   SÉQUENTIELLEMENT en fade-in/fly-in. Repli hors scène épinglée : cascade via
   IntersectionObserver + stagger --i. En scène épinglée, c'est le JS qui scrube
   ces mêmes éléments (état masqué posé par components.css .kd-reveal.is-on). */
.js [data-reveal="split-cross"] .tr-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.75s var(--ease-soft) calc(0.1s + var(--i, 0) * 0.22s),
    transform 0.75s var(--ease-soft) calc(0.1s + var(--i, 0) * 0.22s);
}
.js [data-reveal="split-cross"].is-visible .tr-reveal { opacity: 1; transform: none; }

/* FAQ — les questions montent en cascade APRÈS le split (délai de base 0.35s
   + stagger --i), pour que la colonne se construise sous les yeux. */
.js [data-reveal="split-cross"] .faq-item {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.7s var(--ease-soft) calc(0.35s + var(--i, 0) * 90ms),
    transform 0.7s var(--ease-soft) calc(0.35s + var(--i, 0) * 90ms);
}
.js [data-reveal="split-cross"].is-visible .faq-item { opacity: 1; transform: none; }

/* ------------------------------------------------------------
   Reveal SÉQUENTIEL (data-reveal="stagger") — chaque élément .seq apparaît
   UN À LA FOIS, lentement (gros stagger 0.5s). Utilisé par #faq et #dates.
   La tête de section reste visible : ce sont ses enfants .seq qui se révèlent.
   ------------------------------------------------------------ */
.js [data-reveal="stagger"] .section-head { opacity: 1; transform: none; transition: none; }
.js [data-reveal="stagger"] .seq {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.8s var(--ease-soft) calc(var(--i, 0) * 0.5s),
    transform 0.8s var(--ease-soft) calc(var(--i, 0) * 0.5s);
}
.js [data-reveal="stagger"].is-visible .seq { opacity: 1; transform: none; }

/* « C'est pour toi si… » (repli hors scène) — le lede fond, puis les cartes
   montent en cascade (stagger --i) et le crochet SVG se dessine
   (stroke-dashoffset) juste après chaque carte. */
.js [data-reveal="check-draw"] .pt-lede {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.85s var(--ease-soft) 0.1s, transform 0.85s var(--ease-soft) 0.1s;
}
.js [data-reveal="check-draw"].is-visible .pt-lede { opacity: 1; transform: none; }

.js [data-reveal="check-draw"] .pt-card {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 0.7s var(--ease-soft) calc(var(--i, 0) * 90ms),
    transform 0.7s var(--ease-soft) calc(var(--i, 0) * 90ms);
}
.js [data-reveal="check-draw"] .check path {
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
  transition: stroke-dashoffset 0.6s var(--ease-soft) calc(var(--i, 0) * 90ms + 0.2s);
}

.js [data-reveal="check-draw"].is-visible .pt-card { opacity: 1; transform: none; }
.js [data-reveal="check-draw"].is-visible .check path { stroke-dashoffset: 0; }

/* Témoignages + dates — montée + léger scale en cascade. */
.js [data-reveal="cascade-rise"] .rise-item {
  opacity: 0;
  transform: translateY(26px) scale(0.96);
  transition:
    opacity 0.7s var(--ease-soft) calc(var(--i, 0) * 60ms),
    transform 0.7s var(--ease-soft) calc(var(--i, 0) * 60ms);
}
.js [data-reveal="cascade-rise"].is-visible .rise-item { opacity: 1; transform: none; }

/* Note d'urgence sous les dates : fondu tardif, après les cartes. */
.js [data-reveal="cascade-rise"] .date-note {
  opacity: 0;
  transition: opacity 0.9s var(--ease-soft) 0.45s;
}
.js [data-reveal="cascade-rise"].is-visible .date-note { opacity: 1; }

/* Footer — simple fondu, on termine calme. */
.js [data-reveal="fade"] > .container {
  opacity: 0;
  transition: opacity 1s var(--ease-soft);
}

.js [data-reveal="fade"].is-visible > .container { opacity: 1; }

/* ------------------------------------------------------------
   Reveal RÉVERSIBLE (bande CTA) : les éléments entrent en fondu + montée
   quand la section arrive à l'écran, et RESSORTENT quand on remonte.
   Piloté par .is-in (main.js). On anime `translate` (indépendante de
   `transform`) pour composer avec le hover du bouton sans conflit.
   Sur mobile : à sens unique (une fois révélé, ça reste — main.js).
   ------------------------------------------------------------ */
.js [data-reveal-2way] .cta-band-inner > * {
  opacity: 0;
  translate: 0 30px;
  transition: opacity 0.6s var(--ease-soft), translate 0.6s var(--ease-soft);
}
.js [data-reveal-2way].is-in .cta-band-inner > * {
  opacity: 1;
  translate: 0 0;
}
/* Cascade ITEM PAR ITEM, en entrée comme en sortie. */
.js [data-reveal-2way] .cta-band-inner > *:nth-child(1) { transition-delay: 0s; }
.js [data-reveal-2way] .cta-band-inner > *:nth-child(2) { transition-delay: 0.26s; }
.js [data-reveal-2way] .cta-band-inner > *:nth-child(3) { transition-delay: 0.52s; }
.js [data-reveal-2way] .cta-band-inner > *:nth-child(4) { transition-delay: 0.78s; }
.js [data-reveal-2way] .cta-band-inner > *:nth-child(5) { transition-delay: 1.04s; }

/* ------------------------------------------------------------
   FAQ : le corps de la réponse glisse doucement à l'ouverture.
   ------------------------------------------------------------ */
.faq-item[open] .faq-body { animation: faq-open 0.45s var(--ease-soft); }
@keyframes faq-open {
  from { opacity: 0; translate: 0 -6px; }
  to   { opacity: 1; translate: 0 0; }
}

/* ------------------------------------------------------------
   Vidéo : placeholder visible tant que le fichier n'existe pas.
   ------------------------------------------------------------ */

.video-frame.no-poster .img-placeholder { display: flex; z-index: 0; }
.video-frame.no-poster video { position: relative; z-index: 1; }

/* ------------------------------------------------------------
   prefers-reduced-motion : toutes les animations décoratives se
   désactivent; tout apparaît instantanément.
   ------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {

  .js .hro,
  .js [data-reveal] .section-head,
  .js [data-reveal] [data-rv],
  .js [data-reveal="stagger"] .seq,
  .js [data-reveal="split-cross"] .tr-reveal,
  .js [data-reveal="split-cross"] .faq-item,
  .js [data-reveal="check-draw"] .pt-lede,
  .js [data-reveal="check-draw"] .pt-card,
  .js [data-reveal="cascade-rise"] .rise-item,
  .js [data-reveal="cascade-rise"] .date-note,
  .js [data-reveal="fade"] > .container,
  .js [data-reveal-2way] .cta-band-inner > * {
    opacity: 1 !important;
    transform: none !important;
    translate: none !important;
    clip-path: none !important;
    filter: none !important;
    transition: none !important;
    animation: none !important;
  }

  .js [data-reveal="check-draw"] .check path {
    stroke-dashoffset: 0 !important;
    transition: none !important;
  }

  .faq-item[open] .faq-body { animation: none !important; }

  .bloom {
    animation: none !important;
    opacity: 0.7 !important;
    transition: none !important;
  }

  .btn, .btn-arrow, .video-play, .nav-links a::after, .social-icon,
  .date-badge--hot, .tmn-card, .pt-card, .date-card {
    transition: none !important;
    animation: none !important;
  }
}
