/* =========================================================
   EIKO CRÉATION — « MUR DE NUIT » : animations
   ---------------------------------------------------------
   Chargé après night.css. Ne contient que ce qui bouge et ce
   qui est injecté par night.js.

   Règle tenue : tout passe par transform / opacity / filter,
   donc aucun décalage de mise en page. Et tout est coupé sous
   prefers-reduced-motion.
   ========================================================= */

/* ---------------------------------------------------------
   1. CURSEUR
   --------------------------------------------------------- */
/* Le curseur natif est masqué partout, y compris sur les éléments qui
   portent leur propre règle `cursor:` (.stage, images du logo, etc.) :
   sinon un curseur système apparaissait en double sous le curseur maison. */
.has-cursor, .has-cursor * { cursor: none !important; }

.cursor-dot, .cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 4000;
  pointer-events: none;
  opacity: 0;
  will-change: transform, opacity;
}
.cursor-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #a6ff1f;
  box-shadow: 0 0 12px rgba(166, 255, 31, .95), 0 0 30px rgba(166, 255, 31, .5);
  transition: opacity .25s, background .25s, box-shadow .25s;
}
.cursor-ring {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1.5px solid rgba(166, 255, 31, .75);
  transition: opacity .25s, width .22s cubic-bezier(.34, 1.56, .64, 1),
              height .22s cubic-bezier(.34, 1.56, .64, 1),
              border-color .22s, background .22s, box-shadow .22s;
  background: radial-gradient(circle, rgba(166, 255, 31, .1), transparent 68%);
}
.cursor-dot.on, .cursor-ring.on { opacity: 1; }
.cursor-ring.big { width: 58px; height: 58px; border-color: rgba(255, 58, 212, .85); background: radial-gradient(circle, rgba(255, 58, 212, .14), transparent 70%); }
.cursor-ring[data-kind="link"] { border-color: rgba(53, 230, 255, .9); }
.cursor-ring.press { width: 22px; height: 22px; background: rgba(53, 230, 255, .22); }
@media (prefers-reduced-motion: reduce) {
  .cursor-dot, .cursor-ring { display: none; }
  .has-cursor, .has-cursor * { cursor: auto !important; }
}

/* ---------------------------------------------------------
   2. BALAYAGE D'ENTRÉE NÉON
   --------------------------------------------------------- */
#wipe {
  position: fixed;
  inset: 0;
  z-index: 3500;
  pointer-events: none;
  transform-origin: top;
  transform: scaleY(1);
  background:
    repeating-linear-gradient(115deg,
      rgba(255, 58, 212, .95) 0 22px,
      rgba(53, 230, 255, .95) 22px 44px,
      rgba(166, 255, 31, .95) 44px 66px);
}
#wipe.out {
  transition: transform .8s cubic-bezier(.7, 0, .2, 1);
  transform: scaleY(0);
  transform-origin: bottom;
}
@media (prefers-reduced-motion: reduce) { #wipe { display: none; } }

/* ---------------------------------------------------------
   3. CANVAS DU HERO
   --------------------------------------------------------- */
.hero .spray-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.1s ease-out .25s;
}
.hero.fx-on .spray-canvas { opacity: 1; }
.hero > .wrap { position: relative; z-index: 1; }

/* ---------------------------------------------------------
   4. TITRE DU HERO : néon qui vacille puis se stabilise
   --------------------------------------------------------- */
@keyframes neonFlicker {
  0%    { opacity: 0; }
  8%    { opacity: 1; }
  10%   { opacity: .35; }
  14%   { opacity: 1; }
  18%   { opacity: .55; }
  22%   { opacity: 1; }
  60%   { opacity: 1; }
  62%   { opacity: .72; }
  64%   { opacity: 1; }
  100%  { opacity: 1; }
}
.hero h1 .w { animation: popin .6s cubic-bezier(.34, 1.56, .64, 1) both; }
.hero h1 .hl {
  animation: popin .6s cubic-bezier(.34, 1.56, .64, 1) both,
             neonFlicker 3.6s ease-in-out 1.1s 1;
}
@media (prefers-reduced-motion: reduce) {
  .hero h1 .w, .hero h1 .hl { animation: none; }
}

/* ---------------------------------------------------------
   5. GRANDS TITRES : mots qui montent + soulignement néon
   --------------------------------------------------------- */
.sec-title.split .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(26px) rotate(-4deg) scale(.96);
  transition: transform .62s cubic-bezier(.34, 1.56, .64, 1), opacity .4s;
}
.spray.show .sec-title.split .w { opacity: 1; transform: none; }
.sec-title.split .w:nth-child(1) { transition-delay: .04s; }
.sec-title.split .w:nth-child(2) { transition-delay: .11s; }
.sec-title.split .w:nth-child(3) { transition-delay: .18s; }
.sec-title.split .w:nth-child(4) { transition-delay: .25s; }
.sec-title.split .w:nth-child(5) { transition-delay: .32s; }
.sec-title.split .w:nth-child(6) { transition-delay: .39s; }
.sec-title.split .w:nth-child(7) { transition-delay: .46s; }
@media (prefers-reduced-motion: reduce) {
  .sec-title.split .w { opacity: 1 !important; transform: none !important; }
}

/* ---------------------------------------------------------
   6. CARTES : inclinaison + reflet néon
   --------------------------------------------------------- */
.tilt { position: relative; transform-style: preserve-3d; will-change: transform; }
.tilt .tilt-glare {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s;
  background: radial-gradient(260px circle at var(--gx, 50%) var(--gy, 50%),
              rgba(53, 230, 255, .18), rgba(255, 58, 212, .08) 45%, transparent 70%);
  z-index: 3;
}
.tilt.on .tilt-glare { opacity: 1; }
/* Bordure orientée : la lumière vient du curseur. */
.tilt::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s;
  background: radial-gradient(180px circle at var(--gx, 50%) var(--gy, 50%),
              rgba(166, 255, 31, .75), transparent 62%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  padding: 1px;
  z-index: 4;
}
.tilt.on::after { opacity: 1; }

/* ---------------------------------------------------------
   7. BOUTONS : onde, éclat, pulsation
   --------------------------------------------------------- */
.btn { position: relative; overflow: hidden; isolation: isolate; }
.btn .ripple, .lb-btn .ripple, .proj-open .ripple {
  position: absolute;
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0);
  background: radial-gradient(circle, rgba(166, 255, 31, .8), rgba(166, 255, 31, 0) 70%);
  pointer-events: none;
  animation: rippleOut .7s ease-out forwards;
  z-index: -1;
}
@keyframes rippleOut {
  to { transform: translate(-50%, -50%) scale(2.8); opacity: 0; }
}
.btn-magnetic { will-change: transform; }

/* ---------------------------------------------------------
   8. ÉCLATS DE BOMBE
   --------------------------------------------------------- */
.paint-blob {
  position: fixed;
  z-index: 3900;
  pointer-events: none;
  width: 12px;
  height: 12px;
  border-radius: 60% 40% 55% 45% / 50% 45% 55% 50%;
  box-shadow: 0 0 16px currentColor, 0 0 34px currentColor;
  will-change: transform, opacity;
  animation: blobOut .8s cubic-bezier(.2, .8, .2, 1) forwards;
}
@keyframes blobOut {
  0%   { transform: translate(-50%, -50%) scale(.15) rotate(0deg); opacity: 1; }
  55%  { opacity: .95; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1) rotate(var(--rot)); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .paint-blob { display: none; } }

/* ---------------------------------------------------------
   9. PROJECTEUR
   --------------------------------------------------------- */
.tone-ink, .tone-green, .tone-yellow { position: relative; }
.tone-ink { overflow: hidden; }
.spotlight {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  transition: opacity .4s;
  background: radial-gradient(460px circle at var(--sx, 50%) var(--sy, 50%),
              rgba(53, 230, 255, .13), rgba(255, 58, 212, .09) 42%, transparent 70%);
}
.spotlight.on { opacity: 1; }
.tone-ink > .wrap, .tone-green > .wrap, .tone-yellow > .wrap { position: relative; z-index: 1; }

/* ---------------------------------------------------------
   10. MÉTHODE : trait néon qui progresse
   --------------------------------------------------------- */
.steps-line {
  position: absolute;
  left: 4%;
  right: 4%;
  top: 2px;
  height: 3px;
  border-radius: 3px;
  pointer-events: none;
  background: linear-gradient(90deg, #ff3ad4, #35e6ff 50%, #a6ff1f);
  box-shadow: 0 0 16px rgba(53, 230, 255, .7);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.6s cubic-bezier(.7, 0, .2, 1) .25s;
}
.steps-line.on { transform: scaleX(1); }
/* le trait pointillé d'origine n'a plus lieu d'être */
.js .spray:not(.show) .steps::before { transform: scaleX(0); }
.steps::before { display: none; }
@media (max-width: 960px) { .steps-line { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .steps-line { transform: scaleX(1); transition: none; }
}

/* ---------------------------------------------------------
   11. APPARITION DES BLOCS
   --------------------------------------------------------- */
.fx-reveal {
  opacity: 0;
  transform: translateY(26px) scale(.985);
  transition: opacity .7s ease-out, transform .7s cubic-bezier(.2, .8, .2, 1);
}
.fx-reveal.fx-in { opacity: 1; transform: none; }
.faq-list .fx-reveal:nth-child(2) { transition-delay: .06s; }
.faq-list .fx-reveal:nth-child(3) { transition-delay: .12s; }
.faq-list .fx-reveal:nth-child(4) { transition-delay: .18s; }
.faq-list .fx-reveal:nth-child(5) { transition-delay: .24s; }
.review-grid .fx-reveal:nth-child(2) { transition-delay: .08s; }
.review-grid .fx-reveal:nth-child(3) { transition-delay: .16s; }
.review-grid .fx-reveal:nth-child(4) { transition-delay: .24s; }
.hub-grid .fx-reveal:nth-child(2) { transition-delay: .07s; }
.hub-grid .fx-reveal:nth-child(3) { transition-delay: .14s; }
.hub-grid .fx-reveal:nth-child(4) { transition-delay: .21s; }
.hub-grid .fx-reveal:nth-child(5) { transition-delay: .28s; }
.hub-grid .fx-reveal:nth-child(6) { transition-delay: .35s; }
.stagger > .fx-reveal:nth-child(2) { transition-delay: .08s; }
.stagger > .fx-reveal:nth-child(3) { transition-delay: .16s; }
.stagger > .fx-reveal:nth-child(4) { transition-delay: .24s; }
.breadcrumb.fx-reveal { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .fx-reveal { opacity: 1 !important; transform: none !important; }
}

/* ---------------------------------------------------------
   12. PHOTOS : survol néon + liseré de balayage
   --------------------------------------------------------- */
/* La vignette remplit toute la carte : .proj est le repère, .proj-img est
   posé dessus (même règle que site.css, que ce fichier écrasait en la
   remettant en flux — les photos se réduisaient alors à leur taille
   intrinsèque au milieu du cadre coloré). */
.proj-img {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 11px;
  will-change: transform;
}
/* Le décalage de parallaxe est borné (±14 px) pour que le zoom de base
   (1.16) garde toujours de la matière sur les bords : sans cette borne,
   l'image découvrait le fond de la carte en haut ou en bas. */
.proj .proj-photo {
  transform: translate3d(0, clamp(-14px, var(--py, 0px), 14px), 0) scale(1.16);
  transition: transform .8s cubic-bezier(.2, .8, .2, 1), filter .5s;
  filter: saturate(1.05) contrast(1.03);
}
.proj:hover .proj-photo, .proj:focus-within .proj-photo {
  transform: translate3d(0, clamp(-14px, var(--py, 0px), 14px), 0) scale(1.22);
  filter: saturate(1.2) contrast(1.08) brightness(1.04);
}
.hero-frame .hero-photo { transition: transform 8s ease-out, filter .6s; }
.hero-visual:hover .hero-photo { transform: scale(1.07); filter: saturate(1.15) brightness(1.05); }

/* ---------------------------------------------------------
   13. FAQ
   --------------------------------------------------------- */
.faq-item[open] .faq-a { animation: faqOpen .36s cubic-bezier(.2, .8, .2, 1); }
@keyframes faqOpen {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
.faq-item summary::after { transition: transform .3s cubic-bezier(.34, 1.56, .64, 1), box-shadow .3s; }
.faq-item[open] summary::after { box-shadow: 0 0 20px rgba(166, 255, 31, .6); }

/* ---------------------------------------------------------
   14. VISIONNEUSE
   --------------------------------------------------------- */
/* Chromium 156 ne cale plus la boîte de dialogue modale sur la fenêtre
   (le navigateur impose « position: absolute » à la couche supérieure).
   Ouverte depuis une vignette en bas de page, la visionneuse se retrouvait
   hors écran : on ne voyait qu'un fond noir. Il faut donc reprendre la main
   en !important, sinon la règle du navigateur garde la priorité. */
.lightbox {
  position: fixed !important;
  inset: 0;
  margin: auto;
  width: max-content;
  height: max-content;
}
.lightbox .lb-img {
  transform-origin: center;
  animation: lbKen 14s ease-in-out alternate infinite;
}
@keyframes lbKen {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.07) translate3d(-1%, -1.4%, 0); }
}
.lightbox[open] .lb-figure {
  animation: lbNeon .4s cubic-bezier(.34, 1.56, .64, 1);
}
@keyframes lbNeon {
  0%   { opacity: 0; transform: scale(.9) rotate(-2deg); filter: brightness(2.2) saturate(1.6); }
  60%  { opacity: 1; filter: brightness(1.15) saturate(1.1); }
  100% { opacity: 1; transform: none; filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .lightbox .lb-img, .lightbox[open] .lb-figure { animation: none; }
}

/* ---------------------------------------------------------
   15. DIVERS
   --------------------------------------------------------- */
/* Le visuel du hero flotte doucement (deux couches de translate :
   pas de rotation, donc pas de flou de rendu). */
.hero-visual { animation: heroFloat 7s ease-in-out infinite alternate; }
@keyframes heroFloat {
  from { transform: translateY(-7px); }
  to   { transform: translateY(9px); }
}
/* Le disque du logo animé tourne plus visiblement sur fond sombre. */
.swirlDisc { filter: drop-shadow(0 0 16px rgba(53, 230, 255, .5)); }
.perso img { animation: pulseNeon 2.6s ease-in-out infinite; }
@keyframes pulseNeon {
  0%, 100% { filter: drop-shadow(0 0 10px rgba(255, 58, 212, .45)); }
  50%      { filter: drop-shadow(0 0 24px rgba(53, 230, 255, .7)); }
}
/* Les bandeaux gagnent un léger flottement. */
.band { animation: bandFloat 9s ease-in-out infinite alternate; }
@keyframes bandFloat {
  from { transform: rotate(-1.2deg) scale(1.03) translateY(0); }
  to   { transform: rotate(-1.2deg) scale(1.03) translateY(-5px); }
}
.band.reverse { animation-name: bandFloatRev; }
@keyframes bandFloatRev {
  from { transform: rotate(1.2deg) scale(1.03) translateY(0); }
  to   { transform: rotate(1.2deg) scale(1.03) translateY(5px); }
}

@media (prefers-reduced-motion: reduce) {
  .tilt, .btn-magnetic { transform: none !important; }
  .tilt .tilt-glare, .tilt::after { display: none; }
  .hero-visual, .band { animation: none; }
  .perso img { animation: none; }
  .spotlight { display: none; }
  .proj .proj-photo, .proj:hover .proj-photo { transform: none; }
  .band .track { animation-duration: 22s !important; }
}
