/* ==========================================================================
   KokoroWorks — Les ambiances par scène
   L'ambiance prolonge la peinture : chaque lieu du voyage (grotte, sortie,
   approche, livre) a sa signature — semée par ambiances.js, éclairée ici.
   Deux calques : .ambiance-fond derrière le théâtre du livre (dans
   .atelier), .ambiance-proche devant lui (pétales flous périphériques).
   Tout est décoratif (aria-hidden), transform/opacity seulement — jamais
   de layout ni de paint par frame.
   ========================================================================== */

:root {
  --petale-clair: #FFF3F0;      /* pointe du pétale */
  --petale-ombre: #F4A9B8;      /* base du pétale (rose peint des tableaux) */
  --mote-grotte:  #8E86B8;      /* poussière minérale froide */
  --mote-or:      #FFE2B0;      /* poussière de lumière (dans les rais) */
  --luciole:      #FFEDC2;      /* cœur de luciole, halo vers --lueur */
  --luciole-coeur: 10px;        /* le cœur renforcé — lisible sur l'aquarelle claire */
  --halo-plein:   .9;           /* halo céleste en pleine lumière */
  --halo-voile:   .12;          /* halo céleste sous le nuage */

  --eclosion: .8s;              /* durée de naissance d'un lieu */
  --extinction: .35s;           /* durée d'oubli d'un lieu */
}

/* ---- Les calques ---------------------------------------------------------
   Le fond vit dans .atelier (fixe, z:0), sous le recueillement, les graines
   et l'éblouissement : le blanc de la bascule couvre toute naissance.
   Le proche est un enfant de body : au-dessus de la scène du livre (z:2),
   sous l'aide (z:20), la nav (z:88+) et le seuil (z:200). */
.ambiance-fond,
.ambiance-proche {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  transition: opacity var(--extinction) ease;
}
.ambiance-proche {
  position: fixed;
  z-index: 10;
}
/* l'extinction : on quitte un lieu, on ne s'attarde pas */
.ambiance-fond.est-en-extinction,
.ambiance-proche.est-en-extinction { opacity: 0; }
/* l'onglet caché : plus un battement d'aile (batterie) */
.ambiance-fond.est-en-pause *,
.ambiance-proche.est-en-pause * { animation-play-state: paused !important; }

/* ---- La naissance : chaque habitant éclot en fondu échelonné ------------
   L'opacité naît à zéro — on voit la vie arriver, pas un décor déjà usé.
   Le retard d'échelonnement est posé par le semeur (ambiances.js). */
.naissance {
  position: absolute;
  inset: 0;
  /* fill backwards, pas both : une éclosion finie doit rendre la main aux
     règles d'état (masquable, finale…) — un fill forwards les battrait
     dans la cascade tant que l'animation reste appliquée */
  animation: ambiance-nait var(--eclosion) var(--allume) backwards;
}
/* la réserve de la nuit naît invisible : pas d'éclosion à contre-emploi */
.naissance.luciole-finale { animation: none; }
@keyframes ambiance-nait {
  from { opacity: 0; scale: .86; }
  to   { opacity: 1; scale: 1; }
}

/* le vent : une même bouffée emporte tous les pétales — l'air est vivant */
.vent {
  position: absolute;
  inset: 0;
  animation: vent-souffle 13s ease-in-out infinite;
}
@keyframes vent-souffle {
  0%, 58%, 100% { transform: translate3d(0, 0, 0); }
  72% { transform: translate3d(3.2vw, 0, 0); }
  84% { transform: translate3d(1vw, 0, 0); }
}

/* ---- Pétale de sakura : chute pendulaire + tournoiement 3D --------------- */
.petale-chute {
  position: absolute;
  top: -4%;
  left: var(--gauche, 50%);
  animation: petale-tombe var(--duree, 18s) linear var(--retard, 0s) infinite;
}
@keyframes petale-tombe {
  from { transform: translate3d(0, -6svh, 0); }
  to   { transform: translate3d(var(--derive-x, 4vw), 110svh, 0); }
}
.petale-balance {
  animation: petale-balance var(--tempo-balance, 3.2s) ease-in-out infinite alternate;
}
@keyframes petale-balance {
  from { transform: translateX(calc(var(--ampleur, 26px) * -1)) rotate(-14deg); }
  to   { transform: translateX(var(--ampleur, 26px)) rotate(14deg); }
}
.petale {
  width: var(--taille, 14px);
  aspect-ratio: .82;
  background: radial-gradient(120% 90% at 50% 12%, var(--petale-clair) 12%, var(--petale-ombre) 74%, #E88EA4 100%);
  clip-path: path('M7 0 C 10.8 2.2, 11.6 6.5, 10.2 10.6 C 9.4 13.2, 8.2 15.4, 7 17 C 5.8 15.4, 4.6 13.2, 3.8 10.6 C 2.4 6.5, 3.2 2.2, 7 0 Z');
  animation: petale-tournoie var(--tempo-3d, 2.6s) ease-in-out infinite alternate;
}
/* variantes de silhouette : l'encoche sommitale, la panse large */
.petale.v2 { clip-path: path('M7 .4 C 11.4 1.8, 12.2 7, 9.8 11.4 C 8.8 13.4, 7.9 15, 7 16.6 C 5.2 14, 3 11.8, 2.6 8.2 C 2.2 4.4, 4 1.4, 7 .4 Z'); }
.petale.v3 { clip-path: path('M6.4 1 C 3 2.6, 2 6.4, 3.4 9.8 C 4.6 12.8, 6 14.6, 7 16 C 8.4 14.2, 10.4 11.6, 11 8.4 C 11.6 5, 10 2, 7.6 1 C 7.2 2.2, 6.8 2.2, 6.4 1 Z'); }
@keyframes petale-tournoie {
  from { transform: rotate3d(1, .4, .2, 24deg); }
  to   { transform: rotate3d(.8, 1, .3, 196deg); }
}
/* les trois plans de profondeur */
.plan-lointain .petale { opacity: .6; }
.plan-proche { filter: blur(1.6px); }
.plan-proche .petale { opacity: .9; }

/* la volée : la poignée de pétales qui traverse sous l'éblouissement */
.petale-volee {
  position: absolute;
  top: -6%;
  left: var(--gauche, 50%);
  animation: volee-traverse var(--duree, 2.6s) ease-in var(--retard, 0s) both;
}
@keyframes volee-traverse {
  from { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 0; }
  12%  { opacity: 1; }
  to   { transform: translate3d(var(--derive-x, 14vw), 118svh, 0) rotate(300deg); opacity: 1; }
}

/* ---- Le battement d'ailes (la fée) --------------------------------------- */
@keyframes papillon-bat-g { from { transform: rotateY(10deg); } to { transform: rotateY(72deg); } }
@keyframes papillon-bat-d { from { transform: rotateY(-10deg); } to { transform: rotateY(-72deg); } }

/* ---- Luciole : errance en boucles + pulsation asynchrone -----------------
   Renforcée (cœur 7px, halo 30px au pic) pour tenir sur l'aquarelle claire.
   Deux vies : standalone (la constellation finale — left/top + erre) ou
   .membre d'un essaim (errance calc() autour de l'ancre du groupe). */
.luciole {
  position: absolute;
  left: var(--gauche, 50%);
  top: var(--haut, 70%);
  width: var(--luciole-coeur); height: var(--luciole-coeur);
  border-radius: 50%;
  /* composition normale, pas de screen : sur l'aquarelle claire (~90% de
     luminance), screen ne peut rien éclaircir — l'or profond composé
     normalement reste lisible partout (écart au design, vérifié au
     navigateur) */
  background: radial-gradient(circle, #FFFDF4 12%, #FFD98E 40%, rgba(255, 176, 64, .55) 68%, transparent 82%);
  animation:
    luciole-erre var(--duree-erre, 17s) ease-in-out var(--retard, 0s) infinite alternate,
    luciole-pulse var(--tempo-pulse, 2.4s) ease-in-out var(--retard-pulse, 0s) infinite;
}
@keyframes luciole-erre {
  0%   { transform: translate3d(0, 0, 0); }
  25%  { transform: translate3d(var(--ex1, 4vw), var(--ey1, -3vh), 0); }
  50%  { transform: translate3d(var(--ex2, -2vw), var(--ey2, -6vh), 0); }
  75%  { transform: translate3d(var(--ex3, 3vw), var(--ey3, -2vh), 0); }
  100% { transform: translate3d(var(--ex4, -3vw), var(--ey4, -5vh), 0); }
}
/* l'éclat se règle par variable : une animation d'opacité ne se laisse pas
   recouvrir par une simple règle — la variable, si (lecture : --eclat .6) */
/* plancher à .35 et plateau au pic : la luciole respire mais ne disparaît
   jamais — retour de test, elle était invisible entre deux pulsations */
@keyframes luciole-pulse {
  0%, 100% {
    opacity: calc(.45 * var(--eclat, 1));
    box-shadow: 0 0 8px 2px rgba(255, 220, 150, calc(.55 * var(--eclat, 1))), 0 0 18px 7px rgba(255, 170, 60, calc(.4 * var(--eclat, 1)));
  }
  40%, 60% {
    opacity: var(--eclat, 1);
    box-shadow: 0 0 12px 3px rgba(255, 220, 150, calc(.95 * var(--eclat, 1))), 0 0 36px 14px rgba(255, 170, 60, calc(.7 * var(--eclat, 1)));
  }
}

/* ---- Essaim : la meneuse invisible voyage, les membres errent autour ----
   Deux étages emboîtés, transform seulement : la route du groupe (ample,
   linéaire) porte des membres en petites boucles bornées autour de l'ancre
   — la cohésion de la grappe est structurelle. Bande basse 52-88svh : le
   sous-bois, là où le doré porte. */
.essaim {
  position: absolute;
  left: 0; top: 0;
  width: 0; height: 0;
}
.essaim-gauche { animation: essaim-balade-gauche 52s var(--derive) infinite; }
.essaim-droite { animation: essaim-balade-droite 64s var(--derive) infinite; }
.essaim-coeur  { animation: essaim-balade-coeur 70s var(--derive) infinite; }
/* lisière gauche : le long des troncs, jamais au-delà de 30vw */
@keyframes essaim-balade-gauche {
  0%   { transform: translate3d(10vw, 78svh, 0); }
  25%  { transform: translate3d(20vw, 62svh, 0); }
  50%  { transform: translate3d(7vw, 55svh, 0); }
  75%  { transform: translate3d(16vw, 72svh, 0); }
  100% { transform: translate3d(10vw, 78svh, 0); }
}
/* lisière droite : longe la zone de Kokomi (borne ouest 78vw), jamais
   au-dessus de sa bulle */
@keyframes essaim-balade-droite {
  0%   { transform: translate3d(88vw, 60svh, 0); }
  25%  { transform: translate3d(78vw, 74svh, 0); }
  50%  { transform: translate3d(92vw, 82svh, 0); }
  75%  { transform: translate3d(83vw, 66svh, 0); }
  100% { transform: translate3d(88vw, 60svh, 0); }
}
/* cœur de clairière : traverse l'arrière-scène, derrière le livre */
@keyframes essaim-balade-coeur {
  0%   { transform: translate3d(30vw, 68svh, 0); }
  30%  { transform: translate3d(48vw, 74svh, 0); }
  55%  { transform: translate3d(66vw, 65svh, 0); }
  80%  { transform: translate3d(44vw, 60svh, 0); }
  100% { transform: translate3d(30vw, 68svh, 0); }
}
.luciole.membre {
  left: 0; top: 0;
  animation:
    membre-erre var(--duree-erre, 9s) ease-in-out var(--retard-erre, 0s) infinite alternate,
    luciole-pulse var(--tempo-pulse, 2.4s) ease-in-out var(--retard-pulse, 0s) infinite;
}
@keyframes membre-erre {
  0%   { transform: translate3d(var(--dx, 0vw), var(--dy, 0vh), 0); }
  33%  { transform: translate3d(calc(var(--dx, 0vw) + var(--ex1, 1vw)), calc(var(--dy, 0vh) + var(--ey1, -1vh)), 0); }
  66%  { transform: translate3d(calc(var(--dx, 0vw) + var(--ex2, -1vw)), calc(var(--dy, 0vh) + var(--ey2, 1vh)), 0); }
  100% { transform: translate3d(calc(var(--dx, 0vw) + var(--ex3, 1vw)), calc(var(--dy, 0vh) + var(--ey3, 1vh)), 0); }
}

/* ---- Rai de lumière : le faisceau flou et son âme vive ------------------- */
.rai {
  position: absolute;
  top: -12%;
  left: var(--gauche, 50%);
  width: var(--largeur-rai, 16vw);
  height: 130%;
  /* de la matière jusqu'à 88% : le faisceau touche le sol de la clairière */
  background: linear-gradient(to bottom,
    rgba(255, 244, 214, .95),
    rgba(255, 216, 170, .55) 30%,
    rgba(255, 211, 168, .28) 60%,
    rgba(255, 208, 165, .14) 88%,
    transparent 100%);
  transform: rotate(16deg);
  transform-origin: 50% 0;
  filter: blur(14px);
  mix-blend-mode: screen;
  /* les flancs du faisceau se fondent : jamais d'arête de lumière */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 30%, #000 70%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 30%, #000 70%, transparent);
  animation: rai-respire var(--tempo-rai, 11s) ease-in-out var(--retard, 0s) infinite alternate;
}
.rai::before {
  content: '';
  position: absolute;
  left: 30%; top: 0;
  width: 26%; height: 92%;
  background: linear-gradient(to bottom, rgba(255, 250, 232, .85), rgba(255, 232, 190, .25) 55%, transparent 90%);
  filter: blur(6px);
}
@keyframes rai-respire {
  from { opacity: var(--rai-min, .45); }
  to   { opacity: var(--rai-max, .85); }
}
/* le cycle nuageux (scène du livre) : pleine lumière → estompage → voilé
   tenu → retour, rien ne claque. Même durée pour tous les halos, retards
   en tiers de cycle posés par le semeur : jamais tous voilés en même
   temps. Sans .nuage (rai de l'approche), la respiration simple demeure. */
/* la variance de gala passe par --halo-gala (inline) : --halo-plein reste
   libre pour les overrides d'état (l'inline battrait la règle ouvert) */
.rai.nuage {
  --halo-plein: var(--halo-gala, .9);
  /* composition normale + or plus dense, scène du livre seulement : le
     screen se dissolvait sur l'aquarelle claire (retour de test) — le rai
     discret de l'approche garde son rendu d'origine */
  mix-blend-mode: normal;
  filter: blur(10px); /* moins flou que le rai discret : le faisceau se dessine */
  background: linear-gradient(to bottom,
    rgba(255, 240, 200, 1),
    rgba(255, 212, 150, .75) 30%,
    rgba(255, 205, 145, .45) 60%,
    rgba(255, 200, 140, .25) 88%,
    transparent 100%);
  animation: halo-nuage 21s ease-in-out var(--nuage-retard, 0s) infinite;
}
.rai.nuage::before {
  width: 34%;
  background: linear-gradient(to bottom, rgba(255, 252, 240, 1), rgba(255, 226, 175, .55) 55%, transparent 90%);
  animation: ame-derive 21s ease-in-out var(--nuage-retard, 0s) infinite;
}
/* la strie sœur : un second trait de lumière plus fin, décalé — c'est le
   couple des deux traits qui fait lire « rayon » et non « nappe » */
.rai.nuage::after {
  content: '';
  position: absolute;
  left: 66%; top: 0;
  width: 14%; height: 80%;
  background: linear-gradient(to bottom, rgba(255, 250, 235, .9), rgba(255, 230, 180, .4) 50%, transparent 88%);
  filter: blur(4px);
  animation: ame-derive 21s ease-in-out var(--nuage-retard, 0s) infinite;
}
@keyframes halo-nuage {
  0%, 26%   { opacity: var(--halo-plein); }
  40%, 58%  { opacity: var(--halo-voile); }
  72%, 100% { opacity: var(--halo-plein); }
}
/* l'âme dérive sous le voile : c'est le bord du nuage qui passe,
   pas un variateur qu'on baisse */
@keyframes ame-derive {
  0%, 26%   { transform: translateX(0); }
  58%       { transform: translateX(14%); }
  72%, 100% { transform: translateX(0); }
}

/* ---- Poussières : l'or des rais, le minéral de la grotte ----------------- */
.mote {
  position: absolute;
  left: var(--gauche, 50%);
  top: var(--haut, 50%);
  width: 2px; height: 2px;
  border-radius: 50%;
  background: var(--mote-or);
  mix-blend-mode: screen;
  animation:
    mote-flotte var(--duree-flotte, 22s) ease-in-out var(--retard, 0s) infinite alternate,
    mote-pulse var(--tempo-pulse, 5s) ease-in-out var(--retard-pulse, 0s) infinite;
}
.mote.froid { background: var(--mote-grotte); mix-blend-mode: normal; }
@keyframes mote-flotte {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(var(--ex1, 2vw), var(--ey1, -4vh), 0); }
}
@keyframes mote-pulse {
  0%, 100% { opacity: .15; }
  50%      { opacity: .75; }
}

/* ---- Scintillement de cristal : l'étoile brève sur les lanternes --------- */
.scintille {
  position: absolute;
  left: var(--gauche, 50%);
  top: var(--haut, 50%);
  width: 18px; height: 18px;
  opacity: 0;
  background:
    radial-gradient(circle, rgba(255, 240, 244, .95) 8%, transparent 20%),
    conic-gradient(from 0deg, transparent 0 40deg, rgba(255, 214, 224, .85) 45deg, transparent 50deg 130deg,
      rgba(255, 214, 224, .85) 135deg, transparent 140deg 220deg, rgba(255, 214, 224, .85) 225deg,
      transparent 230deg 310deg, rgba(255, 214, 224, .85) 315deg, transparent 320deg);
  mix-blend-mode: screen;
}
.scintille.brille { animation: scintille-eclat .7s var(--allume); }
@keyframes scintille-eclat {
  0%   { opacity: 0; transform: scale(.3) rotate(0deg); }
  35%  { opacity: 1; transform: scale(1) rotate(14deg); }
  100% { opacity: 0; transform: scale(.5) rotate(40deg); }
}

/* ---- La fée : la lueur ailée, sa traîne de poussière --------------------- */
.fee-ambiance {
  position: absolute;
  left: 0; top: 0;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: radial-gradient(circle, #FFFDF4 25%, #FFD9A8 60%, transparent 75%);
  box-shadow: 0 0 16px 5px rgba(255, 220, 165, .65);
  animation:
    fee-voyage 47s ease-in-out infinite,
    fee-scintille 1.4s ease-in-out infinite alternate;
}
.fee-ambiance::before, .fee-ambiance::after {
  content: '';
  position: absolute;
  top: -3px;
  width: 8px; height: 12px;
  background: rgba(255, 252, 240, .75);
  border-radius: 60% 40% 60% 40%;
  filter: blur(1px);
}
.fee-ambiance::before { left: -7px; transform-origin: 100% 60%; animation: papillon-bat-g .16s ease-in-out infinite alternate; }
.fee-ambiance::after { right: -7px; transform-origin: 0% 60%; border-radius: 40% 60% 40% 60%; animation: papillon-bat-d .16s ease-in-out infinite alternate; }
.fee-ambiance i { /* la traîne : quatre motes qui meurent dans son sillage */
  position: absolute;
  left: 3px; top: 3px;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--mote-or);
  animation: fee-traine 1.1s linear infinite;
}
.fee-ambiance i:nth-child(2) { animation-delay: .28s; }
.fee-ambiance i:nth-child(3) { animation-delay: .55s; }
.fee-ambiance i:nth-child(4) { animation-delay: .82s; }
@keyframes fee-traine {
  from { opacity: .9; transform: translate3d(0, 0, 0) scale(1); }
  to   { opacity: 0; transform: translate3d(-14px, 8px, 0) scale(.4); }
}
@keyframes fee-voyage {
  0%   { transform: translate3d(14vw, 34svh, 0); }
  18%  { transform: translate3d(26vw, 22svh, 0); }
  36%  { transform: translate3d(12vw, 14svh, 0); }
  52%  { transform: translate3d(74vw, 18svh, 0); }
  70%  { transform: translate3d(88vw, 34svh, 0); }
  86%  { transform: translate3d(70vw, 24svh, 0); }
  100% { transform: translate3d(14vw, 34svh, 0); }
}
@keyframes fee-scintille {
  from { box-shadow: 0 0 12px 3px rgba(255, 220, 165, .5); }
  to   { box-shadow: 0 0 22px 8px rgba(255, 224, 175, .85); }
}

/* ---- Les intensités du livre : gala, lecture, nuit finale ----------------
   Trois vues d'un même semis — rien ne meurt, tout se fond. */
/* lecture : la célébration s'apaise, la page est reine — l'essaim du cœur
   se fond (.masquable posé sur l'essaim), les lisières baissent d'éclat */
.rai, .masquable, .plan-proche, .luciole-finale, .vent, .essaim { transition: opacity 1s ease; }
[data-intensite="ouvert"] .masquable { opacity: 0; }
[data-intensite="ouvert"] .plan-proche { opacity: 0; }
[data-intensite="ouvert"] .essaim .luciole { --eclat: .6; }
[data-intensite="ouvert"] .rai { --rai-min: .14; --rai-max: .3; --halo-plein: .45; --halo-voile: .08; }
/* la nuit finale : la constellation prend le relais, essaims et rais s'éteignent */
.luciole-finale { opacity: 0; }
[data-intensite="finale"] .petale-chute,
[data-intensite="finale"] .petale-balance { animation-play-state: paused; }
[data-intensite="finale"] .vent { opacity: 0; transition: opacity 1s ease; }
[data-intensite="finale"] .rai { opacity: 0 !important; }
[data-intensite="finale"] .essaim { opacity: 0; }
[data-intensite="finale"] .luciole-finale { opacity: 1; }
[data-intensite="finale"] .masquable { opacity: 0; }
[data-intensite="finale"] .plan-proche { opacity: 0; }

/* ---- Les paliers de dégradation (voir design.md — les rais en dernier) --- */
.palier-1 .plan-proche { display: none; }
.palier-1 .essaim-coeur { display: none; }
.palier-2 .plan-proche { display: none; }
.palier-2 .demi { display: none; }
.palier-2 .fee-ambiance { display: none; }
.palier-2 .essaim-coeur,
.palier-2 .essaim-droite { display: none; }
/* sous 30 fps le nuage est un luxe : retour à la respiration simple —
   mais les halos ne partent jamais */
.palier-2 .rai.nuage { animation: rai-respire 11s ease-in-out var(--nuage-retard, 0s) infinite alternate; }
.palier-2 .rai.nuage::before,
.palier-2 .rai.nuage::after { animation: none; }

/* ---- Le profil allégé (mobile / hors cinéma) ----------------------------- */
.est-allege .fee-ambiance, .est-allege .plan-proche { display: none; }
.est-allege .rai {
  animation: none;
  opacity: .3;
}

/* ---- Reduced motion : rien ne bouge — les rais peints des tableaux
   suffisent, l'ambiance animée n'existe pas ---- */
@media (prefers-reduced-motion: reduce) {
  .ambiance-fond, .ambiance-proche { display: none; }
}
