/* ═══════════════════════════════════════════════════════════════════════════
   CARAVELLI — OLYMPE · FUMÉE ONDOYANTE v923 — feuille d'accompagnement
   ───────────────────────────────────────────────────────────────────────────
   Portée volontairement close : tous les sélecteurs sont ancrés sur
   [data-fumee-v923], .fumee-v923__canvas, .fumee-v923--on, .fumee-v923--repli
   ou .fumee-v923__repli. Aucune classe existante du site n'est retouchée,
   la feuille peut donc être chargée après olympe-system.css sans collision.

   Deux rendus cohabitent :
     · le canvas WebGL, posé par le module en premier enfant de l'hôte ;
     · un repli purement CSS (.fumee-v923--repli) : mêmes couleurs, même
       composition écran, même fondu de bord — c'est ce que voient les
       navigateurs sans WebGL ou après une perte de contexte.
   ═════════════════════════════════════════════════════════════════════════ */

/* ══ 1. HÔTE ════════════════════════════════════════════════════════════════
   Repère de positionnement pour le canvas, et contexte d'empilement isolé
   pour que le mix-blend-mode ne remonte pas au-delà du héros. */
[data-fumee-v923]{
  position: relative;
  isolation: isolate;
}

/* Tout le contenu réel du héros passe devant la fumée. Le canvas est le seul
   enfant exclu de la règle : il reste en z-index 0. */
[data-fumee-v923] > :not(.fumee-v923__canvas){
  position: relative;
  z-index: 1;
}

/* ══ 2. CANVAS ══════════════════════════════════════════════════════════════
   Pleine surface, jamais cliquable, jamais responsable d'un débordement
   horizontal. Composition écran : la vapeur ajoute de la lumière au bleu
   nuit au lieu de le recouvrir. */
.fumee-v923__canvas{
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: 100%;
  z-index: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 1.8s cubic-bezier(.19, 1, .22, 1);
  will-change: opacity;
}

/* Levée de rideau une fois la première trame réellement dessinée. */
.fumee-v923--on > .fumee-v923__canvas{
  opacity: 1;
}

/* Après une perte de contexte le canvas reste dans le DOM (sans lui aucun
   webglcontextrestored ne peut survenir) mais il ne doit plus rien montrer. */
.fumee-v923--repli > .fumee-v923__canvas{
  display: none;
}

/* ══ 3. REPLI CSS ═══════════════════════════════════════════════════════════
   Fumée de secours : trois nappes de dégradés radiaux en argent / platine,
   floutées et animées en dérives lentes désynchronisées, plus un faisceau
   bronze très retenu. Fondu de bord par masque radial, pour retrouver le
   même « pas de couture rectangulaire » que le nuanceur.

   Deux porteurs possibles :
     · .fumee-v923__repli — un div inséré par le module (chemin normal) ;
     · les pseudo-éléments de l'hôte — chemin purement CSS, utilisé
       uniquement si ce div est absent, pour ne pas écraser un ::before
       déjà utilisé par le héros du site.                                    */

.fumee-v923--repli{
  position: relative;
  isolation: isolate;
}

/* Spécificité volontairement supérieure à la règle « tout enfant passe
   devant » du § 1 : le porteur doit rester en fond, jamais en flux.
   C'est LUI qui porte le fondu de bord, pas les nappes : le masque reste
   ainsi fixe pendant que les nappes dérivent en dessous. */
.fumee-v923__repli,
[data-fumee-v923].fumee-v923--repli > .fumee-v923__repli{
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  -webkit-mask-image: radial-gradient(76% 82% at 52% 50%,
                        #000 14%, rgba(0,0,0,.62) 52%, transparent 86%);
          mask-image: radial-gradient(76% 82% at 52% 50%,
                        #000 14%, rgba(0,0,0,.62) 52%, transparent 86%);
}

/* — Nappe A : les grandes masses lointaines —
   Volontairement peu couvrante : des foyers séparés, pas une nappe pleine.
   Un dégradé qui remplit tout le cadre relève le bleu nuit en gris sale,
   exactement ce qu'on cherche à éviter. */
.fumee-v923__repli::before{
  content: "";
  position: absolute;
  inset: -26%;
  z-index: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  filter: blur(38px);
  background:
    radial-gradient(30% 35% at 64% 44%,
      oklch(.7724 calc(var(--ol-c-body)*.438) var(--ol-h) / .62) 0%, oklch(.7724 calc(var(--ol-c-body)*.438) var(--ol-h) / .20) 44%, transparent 70%),
    radial-gradient(25% 31% at 33% 66%,
      oklch(.9046 calc(var(--ol-c-body)*.11) var(--ol-h) / .48) 0%, oklch(.9046 calc(var(--ol-c-body)*.11) var(--ol-h) / .14) 46%, transparent 72%),
    radial-gradient(33% 25% at 79% 76%,
      oklch(.966 calc(var(--ol-c-body)*.07) var(--ol-h-pap) / .36) 0%, transparent 68%),
    /* deux petits foyers plus contrastés : ils cassent l'aspect « tache »
       et suggèrent des volutes plutôt qu'un halo */
    radial-gradient(11% 15% at 57% 33%,
      oklch(.966 calc(var(--ol-c-body)*.07) var(--ol-h-pap) / .40) 0%, transparent 66%),
    radial-gradient(9% 13% at 72% 62%,
      oklch(.9046 calc(var(--ol-c-body)*.11) var(--ol-h) / .34) 0%, transparent 68%);
  animation: fumeeV923Derive 46s cubic-bezier(.42, 0, .58, 1) infinite alternate;
  will-change: transform;
}

/* — Nappe B : volutes proches + le rai de lumière bronze — */
.fumee-v923__repli::after{
  content: "";
  position: absolute;
  inset: -26%;
  z-index: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  filter: blur(26px);
  background:
    radial-gradient(20% 26% at 70% 54%,
      oklch(.966 calc(var(--ol-c-body)*.07) var(--ol-h-pap) / .52) 0%, transparent 68%),
    radial-gradient(27% 20% at 44% 31%,
      oklch(.7724 calc(var(--ol-c-body)*.438) var(--ol-h) / .40) 0%, transparent 72%),
    /* le rai : oblique, chaud, très en retrait */
    linear-gradient(206deg,
      oklch(.7625 calc(var(--ol-c-pat)*.821) var(--ol-h-pat) / .32) 0%,
      oklch(.7625 calc(var(--ol-c-pat)*.821) var(--ol-h-pat) / .09) 18%,
      oklch(.2817 calc(var(--ol-c-body)*.796) var(--ol-h) / 0) 46%),
    radial-gradient(42% 48% at 85% 0%,
      oklch(.8242 calc(var(--ol-c-pat)*.806) var(--ol-h-pat) / .30) 0%, transparent 62%);
  animation: fumeeV923Volute 33s cubic-bezier(.42, 0, .58, 1) infinite alternate;
  will-change: transform, opacity;
}

/* — Chemin purement CSS —
   Utilisé seulement si le porteur ci-dessus est absent (classe posée à la
   main, ou module non exécuté). Les nappes portent alors elles-mêmes leur
   masque : il dérive avec elles, ce qui reste acceptable et garantit qu'il
   n'y ait jamais d'arête franche.
   :has() n'est pas indispensable — s'il n'est pas compris, la règle saute
   et le porteur assure seul le rendu. */
.fumee-v923--repli:not(:has(.fumee-v923__repli))::before,
.fumee-v923--repli:not(:has(.fumee-v923__repli))::after{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  -webkit-mask-image: radial-gradient(70% 76% at 52% 50%,
                        #000 12%, rgba(0,0,0,.60) 50%, transparent 84%);
          mask-image: radial-gradient(70% 76% at 52% 50%,
                        #000 12%, rgba(0,0,0,.60) 50%, transparent 84%);
  will-change: transform;
}

.fumee-v923--repli:not(:has(.fumee-v923__repli))::before{
  filter: blur(38px);
  background:
    radial-gradient(30% 35% at 64% 44%,
      oklch(.7724 calc(var(--ol-c-body)*.438) var(--ol-h) / .62) 0%, oklch(.7724 calc(var(--ol-c-body)*.438) var(--ol-h) / .20) 44%, transparent 70%),
    radial-gradient(25% 31% at 33% 66%,
      oklch(.9046 calc(var(--ol-c-body)*.11) var(--ol-h) / .48) 0%, oklch(.9046 calc(var(--ol-c-body)*.11) var(--ol-h) / .14) 46%, transparent 72%),
    radial-gradient(33% 25% at 79% 76%,
      oklch(.966 calc(var(--ol-c-body)*.07) var(--ol-h-pap) / .36) 0%, transparent 68%),
    /* deux petits foyers plus contrastés : ils cassent l'aspect « tache »
       et suggèrent des volutes plutôt qu'un halo */
    radial-gradient(11% 15% at 57% 33%,
      oklch(.966 calc(var(--ol-c-body)*.07) var(--ol-h-pap) / .40) 0%, transparent 66%),
    radial-gradient(9% 13% at 72% 62%,
      oklch(.9046 calc(var(--ol-c-body)*.11) var(--ol-h) / .34) 0%, transparent 68%);
  animation: fumeeV923Derive 46s cubic-bezier(.42, 0, .58, 1) infinite alternate;
}

.fumee-v923--repli:not(:has(.fumee-v923__repli))::after{
  filter: blur(26px);
  background:
    radial-gradient(20% 26% at 70% 54%,
      oklch(.966 calc(var(--ol-c-body)*.07) var(--ol-h-pap) / .52) 0%, transparent 68%),
    radial-gradient(27% 20% at 44% 31%,
      oklch(.7724 calc(var(--ol-c-body)*.438) var(--ol-h) / .40) 0%, transparent 72%),
    linear-gradient(206deg,
      oklch(.7625 calc(var(--ol-c-pat)*.821) var(--ol-h-pat) / .32) 0%,
      oklch(.7625 calc(var(--ol-c-pat)*.821) var(--ol-h-pat) / .09) 18%,
      oklch(.2817 calc(var(--ol-c-body)*.796) var(--ol-h) / 0) 46%),
    radial-gradient(42% 48% at 85% 0%,
      oklch(.8242 calc(var(--ol-c-pat)*.806) var(--ol-h-pat) / .30) 0%, transparent 62%);
  animation: fumeeV923Volute 33s cubic-bezier(.42, 0, .58, 1) infinite alternate;
}

@keyframes fumeeV923Derive{
  0%   { transform: translate3d(-4%, 2%, 0) scale(1.06) rotate(-3deg); opacity: .78; }
  50%  { transform: translate3d( 3%, -3%, 0) scale(1.16) rotate(2deg);  opacity: 1; }
  100% { transform: translate3d( 6%, 4%, 0) scale(1.08) rotate(5deg);  opacity: .84; }
}

@keyframes fumeeV923Volute{
  0%   { transform: translate3d( 5%, -3%, 0) scale(1.10) rotate(4deg);  opacity: .58; }
  45%  { transform: translate3d(-3%, 3%, 0) scale(1.20) rotate(-2deg); opacity: .92; }
  100% { transform: translate3d(-6%, -2%, 0) scale(1.06) rotate(-6deg); opacity: .68; }
}

/* Écrans étroits : moins de flou, la charge de compositing y est ressentie. */
@media (max-width: 760px){
  .fumee-v923__repli::before,
  .fumee-v923--repli:not(:has(.fumee-v923__repli))::before{ filter: blur(30px); }
  .fumee-v923__repli::after,
  .fumee-v923--repli:not(:has(.fumee-v923__repli))::after{ filter: blur(22px); }
}

/* ══ 4. MOUVEMENT RÉDUIT ════════════════════════════════════════════════════
   Le module ne lance alors aucune boucle et laisse une trame figée ; côté
   CSS on fige de même le repli sur une composition choisie, sans le faire
   disparaître : la fumée reste visible, elle ne bouge plus.
   On retire aussi le fondu d'apparition du canvas. */
@media (prefers-reduced-motion: reduce){

  .fumee-v923__canvas{
    transition: none;
  }

  .fumee-v923__repli::before,
  .fumee-v923__repli::after,
  .fumee-v923--repli:not(:has(.fumee-v923__repli))::before,
  .fumee-v923--repli:not(:has(.fumee-v923__repli))::after{
    animation: none;
  }

  .fumee-v923__repli::before,
  .fumee-v923--repli:not(:has(.fumee-v923__repli))::before{
    transform: translate3d(0, 0, 0) scale(1.12) rotate(-1deg);
    opacity: .94;
  }

  .fumee-v923__repli::after,
  .fumee-v923--repli:not(:has(.fumee-v923__repli))::after{
    transform: translate3d(0, 0, 0) scale(1.16) rotate(2deg);
    opacity: .84;
  }

}
