/* ---------- évolution du crabe (changement de niveau) ---------- */
/* Le crabe en grand au milieu de l'écran, cinq éclats doux qui le cachent,
   puis un éclat plus long au creux duquel il change d'apparence.

   Le halo est un dégradé radial : blanc opaque au centre — il DOIT cacher le
   crabe — et fondu jusqu'à rien sur les bords, pour rester doux. Il ne couvre
   que le crabe, pas tout l'écran : un éclat plein cadre serait agressif.

   Cadence : un éclat toutes les 520 ms, soit moins de deux par seconde. On
   reste loin des trois par seconde au-delà desquels un clignotement devient
   risqué pour les personnes photosensibles. Et sous prefers-reduced-motion,
   il n'y a aucun clignotement du tout — voir plus bas. */
.evo {
  position: fixed; inset: 0; z-index: 300;
  /* Une seule colonne centrée : le crabe au milieu, le texte dessous. La place
     du texte est réservée dès le départ (visibility, pas display) — sinon tout
     remonterait d'un cran au moment de la révélation. */
  display: grid; place-content: center; justify-items: center;
  gap: 20px; padding: 24px;
  /* Plus opaque que la recherche : ici on veut qu'il ne reste que le crabe. */
  background: color-mix(in srgb, var(--bg) 95%, transparent);
  backdrop-filter: blur(7px);
  animation: evoEntre 320ms ease-out both;
}
@keyframes evoEntre { from { opacity: 0; } to { opacity: 1; } }

.evo-scene {
  position: relative;
  display: grid; place-items: center;
  /* Bornée par la HAUTEUR autant que par la largeur : le crabe et son texte
     doivent tenir ensemble, y compris sur un écran bas ou en paysage. */
  width: max(190px, min(52vw, 44vh, 380px)); aspect-ratio: 1;
}
.evo-bas { display: grid; justify-items: center; gap: 14px; min-height: 132px; }
.evo-bas.evo-attente { visibility: hidden; }
/* Le crabe vit dans un conteneur qui porte les animations : au moment de la
   mue, on remplace le <svg> à l'intérieur, et remplacer un nœud animé
   relancerait son animation depuis zéro. Le conteneur, lui, ne bouge pas. */
.evo-corps { width: 100%; display: grid; place-items: center; }
.evo-crabe {
  width: 100%; height: auto;
  animation: evoArrive 520ms cubic-bezier(.2, .9, .3, 1.2) both;
}
@keyframes evoArrive { from { opacity: 0; transform: scale(.72); } to { opacity: 1; transform: scale(1); } }
/* Chaque éclat fait respirer le crabe : sans ça, la lumière semble posée
   devant lui plutôt que de sortir de lui. */
.evo-scene.bat .evo-corps {
  animation-name: evoRespire; animation-duration: var(--evo-bat);
  animation-timing-function: ease-in-out; animation-iteration-count: var(--evo-n);
  animation-fill-mode: both;
}
@keyframes evoRespire { 0%, 100% { transform: scale(1); } 46% { transform: scale(1.05); } }
.evo-scene.mue .evo-corps { animation: evoMue var(--evo-mue) ease-in-out both; }
@keyframes evoMue {
  0%   { transform: scale(1); }
  46%  { transform: scale(1.12); }
  62%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}

.evo-halo {
  position: absolute; inset: -14%;
  border-radius: 50%; pointer-events: none; opacity: 0;
  background: radial-gradient(circle at 50% 52%,
    #fffdf7 0%, #fff6e2 34%,
    color-mix(in srgb, var(--gold) 70%, #fff) 52%,
    color-mix(in srgb, var(--ferris) 45%, transparent) 68%,
    transparent 78%);
}
.evo-scene.bat .evo-halo {
  animation-name: evoEclat; animation-duration: var(--evo-bat);
  animation-timing-function: ease-in-out; animation-iteration-count: var(--evo-n);
  animation-fill-mode: both;
}
@keyframes evoEclat {
  0%, 100% { opacity: 0; transform: scale(.84); }
  46%      { opacity: 1; transform: scale(1.02); }
}
/* L'éclat long : montée jusqu'à 42 %, palier jusqu'à 62 % — c'est au creux de
   ce palier que le crabe change — puis descente lente qui le découvre.
   Les pourcentages sont figés ici (un sélecteur de keyframe n'accepte pas de
   var()) ; c'est le JS qui cale l'échange dessus, à partir de la même durée. */
.evo-scene.mue .evo-halo { animation: evoEclatLong var(--evo-mue) ease-in-out both; }
@keyframes evoEclatLong {
  0%   { opacity: 0; transform: scale(.9); }
  42%  { opacity: 1; transform: scale(1.06); }
  62%  { opacity: 1; transform: scale(1.1); }
  100% { opacity: 0; transform: scale(1.24); }
}

.evo-texte {
  text-align: center; max-width: 34ch;
  animation: evoTexte 520ms ease-out both;
}
.evo-eyebrow {
  display: block; font-family: "IBM Plex Mono", monospace;
  font-size: .72rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold);
}
.evo-titre { font-size: clamp(1.5rem, 5vw, 2.1rem); margin: 6px 0 4px; }
.evo-desc { color: var(--ink-soft); margin: 0; line-height: 1.5; }
@keyframes evoTexte { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.evo-ok {
  margin-top: 4px;
  background: var(--accent); color: var(--accent-ink); border: 0;
  border-radius: 10px; padding: 12px 26px; font: inherit; font-weight: 700; cursor: pointer;
}
.evo-ok:hover { filter: brightness(1.08); }

/* Rien ne clignote pour qui a demandé moins de mouvement : l'ancien crabe
   s'efface, le nouveau apparaît. Le même évènement, raconté sans à-coups. */
@media (prefers-reduced-motion: reduce) {
  .evo, .evo-crabe, .evo-texte,
  .evo-scene.bat .evo-corps, .evo-scene.bat .evo-halo,
  .evo-scene.mue .evo-corps { animation: none; opacity: 1; }
  .evo-scene.mue .evo-halo { animation: evoFondu var(--evo-mue) ease-in-out both; }
  @keyframes evoFondu { 0%, 100% { opacity: 0; } 50% { opacity: .96; } }
}
