/* ============================================================
   Lightworker Collective — Animations (animations.css)
   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.

   Cette page « Aide » n'utilise QUE des reveals au scroll
   (IntersectionObserver), aucune scène épinglée : c'est le
   choix le plus robuste (charte §4, §11).
   ============================================================ */

/* ------------------------------------------------------------
   Écran de chargement (à chaque chargement de page — voir loading.js)
   ------------------------------------------------------------ */

html.lw-loading { background: var(--charcoal); }
html.lw-loading body { visibility: hidden; }
html.lw-loading body .lw-loader { visibility: visible; }

.lw-loader {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  background: var(--charcoal);
  opacity: 1;
  transition: opacity 0.6s var(--ease-soft);
}

.lw-loader.is-done { opacity: 0; pointer-events: none; }

.lw-loader-mark {
  position: relative;
  display: grid;
  place-items: center;
  width: min(420px, 82vw);
  aspect-ratio: 16 / 10;
}

.lw-loader-bloom {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  margin: -140px 0 0 -140px;
  animation-duration: 4.5s;
}

.lw-loader-orb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: #6D9BA8;   /* orbe du loader en bleu clair (currentColor) */
}

.lw-loader-logo {
  position: relative;
  text-align: center;
  color: var(--cream);
}

.lw-loader-logo .logo-light { font-size: 2.1rem; }
.lw-loader-logo .logo-worker { font-size: 1.42rem; }
.lw-loader-logo .logo-collective { font-size: 0.68rem; }

/* ------------------------------------------------------------
   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; }
}

/* Teintes de lueur permises : powder blue, teal, tan (toutes -> bleu de marque). */
.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--tan    { background: radial-gradient(circle, color-mix(in srgb, var(--tan) 45%, transparent), transparent 70%); }
.bloom--light  { background: radial-gradient(circle, color-mix(in srgb, var(--color-celestial-light) 50%, transparent), transparent 70%); }

/* Positions */
.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; }
/* À cheval sur la jointure : le halo semble émaner vers la section voisine */
.bloom--joint-bottom { bottom: calc(-0.5 * min(46vw, 620px)); left: 16%; animation-duration: 10s; }

/* Les blooms qui débordent sur la section voisine passent au-dessus de son fond
   (couche z-auto) tout en restant sous les contenus (.section > .container = z:1). */
.bloom--joint-bottom,
.bloom--br { z-index: 1; }

/* Motif « boule de lumière » en orbite (SVG inline, SMIL) */
.lw-orb { pointer-events: none; color: var(--teal); }

/* ------------------------------------------------------------
   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 (fin du fondu du loader).
   ------------------------------------------------------------ */

.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 — sans cette
   règle, le H1 resterait clippé sous l'overflow de .h1-line. */
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; }

/* Mot vidéo de Kiki — 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; }

/* « Ce que tu vis » — poème révélé LIGNE PAR LIGNE au scroll : montée +
   dé-floutage (blur -> none), en cascade via --i (charte §4). Choix explicite :
   révélation au scroll plutôt que scène épinglée (plus robuste). */
.js [data-reveal="poeme"] .poeme-line {
  opacity: 0;
  transform: translateY(22px);
  filter: blur(8px);
  transition:
    opacity 0.9s var(--ease-soft) calc(var(--i, 0) * 90ms),
    transform 0.9s var(--ease-soft) calc(var(--i, 0) * 90ms),
    filter 0.9s var(--ease-soft) calc(var(--i, 0) * 90ms);
}
.js [data-reveal="poeme"].is-visible .poeme-line { opacity: 1; transform: none; filter: none; }

/* « Ce n'est pas un refus » — 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"] .reassure-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 .reassure-card { opacity: 1; transform: none; }
.js [data-reveal="check-draw"].is-visible .check path { stroke-dashoffset: 0; }

/* Services + puces de situations — 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; }

/* Bande CTA finale + 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; }

/* Le bouton de la bande CTA est interactif : « backwards » pour ne pas
   écraser sa transition de hover. */
.js [data-reveal="fade"] .cta-band-inner .btn { opacity: 0; }
.js [data-reveal="fade"].is-visible .cta-band-inner .btn {
  opacity: 1;
  animation: rv-fade 1s var(--ease-soft) 0.35s backwards;
}
@keyframes rv-fade { from { opacity: 0; } }

/* ------------------------------------------------------------
   Reveal RÉVERSIBLE (bande CTA) : les éléments entrent en fondu + montée quand
   la section arrive à l'écran, et RESSORTENT (transition inverse) quand on
   remonte. Piloté par .is-in (IntersectionObserver, main.js). On anime la
   propriété `translate` (indépendante de `transform`) pour composer avec le
   hover du bouton sans conflit.
   ------------------------------------------------------------ */
.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 : chaque élément part 0,26 s après le précédent, en
   entrée comme en sortie (transition bidirectionnelle). */
.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; }

/* ------------------------------------------------------------
   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, sans casser la lisibilité.
   ------------------------------------------------------------ */

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

  .js .hro,
  .js [data-reveal] .section-head,
  .js [data-reveal] [data-rv],
  .js [data-reveal="poeme"] .poeme-line,
  .js [data-reveal="check-draw"] .reassure-card,
  .js [data-reveal="cascade-rise"] .rise-item,
  .js [data-reveal="fade"] > .container,
  .js [data-reveal="fade"] .cta-band-inner .btn,
  .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;
  }

  /* Les lueurs deviennent statiques, les orbites disparaissent. */
  .bloom {
    animation: none !important;
    opacity: 0.7 !important;
    transition: none !important;
  }

  .lw-orb { display: none !important; }

  .btn, .btn-arrow, .video-play, .nav-links a::after, .social-icon {
    transition: none !important;
    animation: none !important;
  }

  .lw-loader { transition: none !important; }
}
