/* =====================================================================
   Les passages d'un écran à l'autre.

   Le site tient sur trois échelles emboîtées — la vitrine, la galaxie des
   coffres, puis un coffre. Naviguer entre elles n'est pas « changer de
   page » : c'est avancer ou reculer d'un cran dans la même profondeur. Les
   quatre passages ci-dessous portent donc une DIRECTION, et c'est elle, pas
   la décoration, qui doit se lire :

     dive     vitrine  → galaxie      on entre
     land     galaxie  → coffre       on entre (couleur de l'actif)
     orbit    coffre   → galaxie      on recule
     surface  galaxie  → vitrine      on recule

   Trois signaux portent cette direction, dans cet ordre d'importance :
   le décor de la page (il avance et grossit quand on entre, il recule et
   rétrécit quand on sort), le sens des traits, et le sens de l'anneau. Le
   voile d'encre, lui, ne fait que couvrir — un disque qui s'ouvre quand on
   entre, un fondu quand on recule.

   Chaque passage a un PENDANT à l'arrivée : sans lui, le voile s'ouvrirait
   sur une page déjà entièrement affichée et le mouvement s'arrêterait net au
   lieu de déposer le visiteur. L'arrivée est posée par un petit script
   synchrone en tête de <body> (voir les pages), parce qu'elle doit exister
   dès la première image — un module, différé par nature, arriverait trop
   tard.
   ===================================================================== */

:root{
  /* Couleur du passage : l'or de la marque par défaut, la couleur de
     l'actif quand on entre dans son coffre ou qu'on en sort. */
  --wc:#E4B767;
}

/* ---------------------------------------------------------------------
   Le décor pendant le passage

   Ce n'est pas un effet parmi d'autres : c'est CE qui dit la direction. On
   entre → la page grossit et se floute, comme dépassée par la caméra. On
   recule → elle rétrécit, comme lâchée derrière soi.

   La transition n'est déclarée que sous `.warp-active`, posée juste avant
   le passage : hors de ce moment, aucune règle ne pèse sur les éléments de
   premier niveau des pages.
   --------------------------------------------------------------------- */
html.warp-active{overflow:clip;}
html.warp-active > body > *:not(.warp){
  transition:transform .42s cubic-bezier(.25,.46,.45,.94), filter .42s cubic-bezier(.25,.46,.45,.94), opacity .42s cubic-bezier(.25,.46,.45,.94);
  transform-origin:50% 42%;
  will-change:transform, filter, opacity;
  backface-visibility:hidden;
}

/* `data-warp` : on s'en va. `data-warp-in` : on vient d'arriver, et l'état
   de départ est posé avant le premier rendu puis relâché — le décor se
   remet en place au lieu d'apparaître déjà posé. Les deux décrivent le même
   état, donc la même règle. */
html[data-warp="dive"]     > body > *:not(.warp),
html[data-warp-in="dive"]  > body > *:not(.warp)   {transform:scale(1.07); filter:blur(4px); opacity:.45;}
html[data-warp="land"]     > body > *:not(.warp),
html[data-warp-in="land"]  > body > *:not(.warp)   {transform:scale(1.13); filter:blur(5px); opacity:.38;}
html[data-warp="surface"]  > body > *:not(.warp),
html[data-warp-in="surface"] > body > *:not(.warp) {transform:scale(.93); filter:blur(4px); opacity:.45;}
html[data-warp="orbit"]    > body > *:not(.warp),
html[data-warp-in="orbit"] > body > *:not(.warp)   {transform:scale(.85); filter:blur(5px); opacity:.38;}

/* ---------------------------------------------------------------------
   Le voile
   --------------------------------------------------------------------- */
.warp{
  position:fixed; inset:0; z-index:250; pointer-events:none;
  /* L'anneau atteint 190vmax : sans confinement de peinture, il déborderait
     du voile et ferait apparaître des barres de défilement le temps du
     passage. */
  contain:layout paint style;
}

/* Entrer : un disque d'encre s'ouvre depuis le CENTRE de l'écran — jamais
   depuis le point cliqué. Un disque centré atteint les quatre coins à
   pile 100% (c'est la définition même du rayon en pourcentage de
   `clip-path: circle()` — la moitié de la diagonale) ; posé sur un coin, il
   lui en aurait fallu jusqu'à 150% pour couvrir le coin opposé. C'est
   nettement moins de pixels à recomposer à chaque image du passage — la
   différence se sent surtout sur un GPU de téléphone, là où un plein écran
   flouté ET une encre qui grandit depuis un coin coûtent déjà cher chacun. */
.warp .warp-ink{
  position:absolute; inset:0;
  /* Pas un noir plat : le centre porte un souffle de la couleur de
     destination, éteint avant la moitié du rayon. On ne le nomme pas en le
     voyant — on voit juste que le voile a une profondeur. */
  background:radial-gradient(circle at 50% 50%,
    color-mix(in srgb, var(--wc) 13%, var(--ink,#14110F)) 0%,
    var(--ink,#14110F) 58%);
  clip-path:circle(0 at 50% 50%);
  transition:clip-path .58s cubic-bezier(.25,.46,.45,.94);
  will-change:clip-path;
  backface-visibility:hidden;
}
.warp.go .warp-ink{clip-path:circle(108% at 50% 50%);}

/* Reculer : pas de disque. Un disque qui s'ouvre est un mouvement vers
   l'avant — exactement ce qu'on ne veut pas dire ici. L'encre monte en
   fondu, et c'est le décor qui rétrécit derrière elle qui porte le recul. */
.warp-surface .warp-ink, .warp-orbit .warp-ink{
  clip-path:none; opacity:0;
  transition:opacity .40s ease .04s;
}
/* `clip-path` répété ici : sans lui, la règle générique `.warp.go` (plus
   spécifique que `.warp-orbit`) réimposerait le disque au moment du départ. */
.warp-surface.go .warp-ink, .warp-orbit.go .warp-ink{clip-path:none; opacity:1;}

/* L'arrivée rejoue le même geste à l'envers, depuis le centre elle aussi :
   le voile est là dès la première image et s'y retire. */
.warp-arrive .warp-ink{
  clip-path:circle(108% at 50% 50%);
  transition:clip-path .52s cubic-bezier(.25,.46,.45,.94);
  will-change:clip-path;
}
.warp-arrive.go .warp-ink{clip-path:circle(0 at 50% 50%);}
.warp-arrive.warp-surface .warp-ink, .warp-arrive.warp-orbit .warp-ink{
  clip-path:none; opacity:1; transition:opacity .46s ease;
}
.warp-arrive.warp-surface.go .warp-ink, .warp-arrive.warp-orbit.go .warp-ink{opacity:0;}

/* ---------------------------------------------------------------------
   L'anneau — la couleur de l'endroit qu'on quitte ou qu'on rejoint.
   Il s'écarte quand on entre, il se resserre quand on recule. C'est le seul
   élément qui porte la couleur de l'actif : entrer dans le coffre USDC ne
   ressemble pas à entrer dans le coffre EURC.
   --------------------------------------------------------------------- */
.warp .warp-halo{
  position:absolute; left:50%; top:50%;
  width:0; height:0; border-radius:50%; opacity:0;
  transform:translate(-50%,-50%);
  box-shadow:0 0 0 2px var(--wc), 0 0 120px 30px var(--wc);
}
@keyframes warp-halo-out{
  from{width:0; height:0; opacity:0; }
  22%{opacity:.85;}
  to{width:190vmax; height:190vmax; opacity:0;}
}
@keyframes warp-halo-in{
  from{width:190vmax; height:190vmax; opacity:0; }
  40%{opacity:.8;}
  to{width:0; height:0; opacity:0;}
}
.warp .warp-halo{
  backface-visibility:hidden;
}
.warp-dive.go .warp-halo, .warp-land.go .warp-halo{
  animation:warp-halo-out .64s cubic-bezier(.25,.46,.45,.94) both;
}
.warp-surface.go .warp-halo, .warp-orbit.go .warp-halo{
  animation:warp-halo-in .58s cubic-bezier(.25,.46,.45,.94) both;
}
.warp-arrive.go .warp-halo{animation-duration:.72s; animation-delay:.06s;}

/* ---------------------------------------------------------------------
   La marque au centre — celle de l'endroit où l'on va. En entrant dans un
   coffre, c'est le logo de l'actif qu'on vient de cliquer qui se pose : le
   geste et son aboutissement portent la même image.
   --------------------------------------------------------------------- */
.warp .warp-badge{
  position:absolute; left:50%; top:50%;
  display:flex; flex-direction:column; align-items:center; gap:14px;
  opacity:0; transform:translate(-50%,-50%) scale(.8);
  transition:opacity .3s cubic-bezier(.25,.46,.45,.94) .2s, transform .45s cubic-bezier(.25,.46,.45,.94) .2s;
  will-change:opacity,transform;
  backface-visibility:hidden;
}
.warp.go .warp-badge{opacity:1; transform:translate(-50%,-50%) scale(1);}
/* En reculant, la marque part de plus gros et se pose : on s'en éloigne. */
.warp-surface .warp-badge, .warp-orbit .warp-badge{transform:translate(-50%,-50%) scale(1.22);}
.warp .warp-mark{
  width:64px; height:64px; display:flex; align-items:center; justify-content:center;
  filter:drop-shadow(0 0 26px var(--wc));
}
.warp .warp-mark svg{width:100%; height:100%;}
.warp .warp-mark .logo-img{width:100%; height:100%; border-radius:50%; object-fit:cover;}
/* Un logo « glyphe » (sans fond propre) flotte dans le disque au lieu de le
   remplir — même distinction que partout ailleurs sur le site. */
.warp .warp-mark .logo-img.glyph{
  width:76%; height:76%; border-radius:0; object-fit:contain; background:none;
}
.warp .warp-mark .logo-init{font-family:var(--mono); font-weight:600; font-size:1.4rem; color:var(--paper);}
/* Pas de `text-transform` : les libellés sont déjà écrits en bas de casse, et
   une règle générale mettrait aussi le symbole de l'actif en minuscules —
   « ouverture du coffre usdc » se lit comme une faute. */
.warp .warp-badge b{
  font-family:var(--mono); font-weight:400; font-size:.78rem; letter-spacing:.08em;
  color:var(--paper-dim);
}

/* ---------------------------------------------------------------------
   Préférence « moins d'animations » : le passage n'existe plus du tout.
   Le JS ne l'arme déjà pas, mais l'arrivée est posée par un script
   synchrone qui, lui, ne peut pas dépendre d'un module — cette règle est le
   filet.
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  .warp{display:none !important;}
  html.warp-active{overflow:visible !important;}
  html.warp-active > body > *:not(.warp){
    transition:none !important; transform:none !important; filter:none !important; opacity:1 !important;
  }
}

/* =====================================================================
   CE QUI A ÉTÉ RETIRÉ, ET POURQUOI

   Deux couches se sont ajoutées ici au fil des essais : une grille de blocs
   qui couvrait l'écran case par case, et des traits filants partant du
   centre. L'intention était bonne — parler la langue pixel du site jusque
   dans le passage. Le résultat ne l'était pas : la mosaïque clignotait, les
   traits faisaient feu d'artifice, et le disque d'encre avait dû être
   dégradé en simple garantie posée APRÈS la grille pour ne pas la masquer.
   Trois couches se gênaient pour un geste qui doit durer une demi-seconde.

   Il reste les trois éléments qui portaient déjà le sens, et eux seuls :
   le disque d'encre qui couvre depuis le centre (et qui redevient donc le
   voile, avec sa courbe d'accélération d'origine), l'anneau à la couleur de
   la destination, et la marque avec son mot. C'est la même direction, la
   même durée et la même couleur — sans ce qui les encombrait.

   La langue du site reste dans le passage, là où elle se lit sans gêner :
   la fonte pixel du mot, les angles francs, la marque en blocs.
   ===================================================================== */

/* Le badge du passage prend la fonte pixel, comme les étiquettes du reste
   du site depuis que l'accueil parle la langue de l'atelier. */
.warp-badge b{
  font-family:'Press Start 2P','IBM Plex Mono',ui-monospace,monospace;
  font-size:.7rem; letter-spacing:-0.03em; line-height:1.8;
}
.warp-badge{border-radius:0; border-width:2px;}
