/* ============================================================
   JARVIS : mode « Spatial 360° » (Claude Code, 18/10/2026, JAR-034)
   Alexandre : « comme si on était en VR, mais en 4K avec effet HUD » ; « c'est surtout les animations de transitions
   et d'apparition des éléments qui vont faire que ça fait VR ». Maquette validée :
   https://claude.ai/artifact/WJdcEUvyvBtp38VrkttKh9 (« ça a l'air super, tu peux tout appliquer »).
   Chargée après spatial.css, active sous html.rt.sp.d360 (interrupteur « Mode Spatial 360° » des Réglages).
   1. Décor 360°  2. Tourner la tête : sortie  3. Arrivée de la nouvelle page  4. Accueil  5. Traits  6. Repère
   7. Mouvement réduit
   RÈGLE DE spatial.css, TOUJOURS VRAIE ICI : jamais d'opacité, de filtre, de masque ni de transformation sur un parent
   d'un élément de verre (backdrop-filter), jamais de filtre animé. Chaque fenêtre de verre s'anime elle-même ; les
   blocs qui contiennent du verre (.vh, .vh-center, .cv, .vm) ne sont jamais animés.
   ============================================================ */

/* ---------- 1. Décor 360° : la toile WebGL de spatial360.js remplace la photo de l'atelier ---------- */
#env > canvas.sp360 { display: none; }
html.rt.sp.d360.sp360-pret body #env > canvas.sp360 { display: block !important; position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; }
html.rt.sp.d360.sp360-pret body #env::before { display: none !important; }
/* Le voile de spatial.css reste au-dessus de la toile : bandeau du menu et barre de commande lisibles. Un peu plus
   léger au centre, le panorama est déjà assombri par la projection. */
html.rt.sp.d360.sp360-pret body #env::after { background: radial-gradient(130% 90% at 50% 46%, rgba(4, 5, 8, 0) 40%, rgba(4, 5, 8, .34) 100%), linear-gradient(180deg, rgba(4, 5, 8, .46), rgba(4, 5, 8, .06) 24%, rgba(4, 5, 8, .1) 66%, rgba(4, 5, 8, .52)); }

@media (min-width: 1100px) {
  /* Sens de la tête (posé par spatial360.js) : 1 = on tourne à droite, la nouvelle page arrive par la droite. Retards
     des deux côtés : le côté d'où vient la page arrive en premier. */
  html.rt.sp.d360 #app #stage { --s: 1; --sp360-ressort: cubic-bezier(.16, 1.12, .3, 1); --sp360-glisse: cubic-bezier(.2, .9, .22, 1); }
  html.rt.sp.d360 #app #stage[data-sp-dir="-1"] { --s: -1; }
  html.rt.sp.d360 #app #stage { --dl: calc((var(--s) + 1) * 55ms); --dr: calc((1 - var(--s)) * 55ms); }
  /* Inclinaison de repos de chaque fenêtre (celle de spatial.css) : l'animation part d'elle et y revient. */
  html.rt.sp.d360 #app :is(#view > .vhead, .vh-col--l) { --ry0: 20deg; }
  html.rt.sp.d360 #app .vh-col--r { --ry0: -20deg; }

  /* ---------- 2. Sortie : tourner la tête, les fenêtres pivotent hors du champ (270 ms) ---------- */
  /* Les fenêtres partent du côté opposé à la rotation, en s'enfonçant et en pivotant sur elles-mêmes. */
  html.rt.sp.d360 #app #stage.sp-out :is(#view > .vhead, .vh-col),
  html.rt.sp.d360 #app #stage.sp-out:not([data-page="jarvis"]):not([data-page="home"]):not([data-page="chat"])::after,
  html.rt.sp.d360 #app #stage.sp-out #view::before,
  html.rt.sp.d360 #app #stage.sp-out .cv-fil { animation: sp360-part .27s cubic-bezier(.55, 0, .85, .35) both !important; }
  /* Fenêtres à inclinaison imposée (!important) : seules les propriétés individuelles passent. */
  html.rt.sp.d360 #app #stage.sp-out :is(.vm-insp, .cv-sessions) { animation: sp360-part-i .27s cubic-bezier(.55, 0, .85, .35) both !important; }
  /* Le contenu de la vitre s'efface d'abord, sur place (jamais les blocs qui contiennent du verre). */
  html.rt.sp.d360 #app #stage.sp-out #view > :not(.vhead):not(.vh):not(.cv):not(.vm):not(.orb),
  html.rt.sp.d360 #app #stage.sp-out #view .vm-sheet { animation: sp360-efface .16s ease-in both !important; }
  /* Accueil : on n'anime jamais .vh-center (il contient du verre), mais chacune de ses pièces. */
  html.rt.sp.d360 #app #stage.sp-out .vh-center { animation: none !important; }
  html.rt.sp.d360 #app #stage.sp-out :is(.nv, .vh-state, .vh-act, .vh-brief) { animation: sp360-part-i .27s cubic-bezier(.55, 0, .85, .35) both !important; }

  /* ---------- 3. Arrivée : la page entre du côté où l'on tourne, puis son contenu se matérialise ---------- */
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) #view > .vhead,
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .vh-col--l { animation: sp360-entre .56s var(--sp360-glisse) both !important; animation-delay: var(--dl) !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .vh-col--r { animation: sp360-entre .56s var(--sp360-glisse) both !important; animation-delay: var(--dr) !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in):not([data-page="jarvis"]):not([data-page="home"]):not([data-page="chat"])::after,
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) #view::before,
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .cv-fil { animation: sp360-entre .56s var(--sp360-glisse) both !important; animation-delay: 55ms !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .cv-sessions { animation: sp360-entre-i .56s var(--sp360-glisse) both !important; animation-delay: var(--dl) !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .vm-insp { animation: sp360-entre-i .56s var(--sp360-glisse) both !important; animation-delay: calc(var(--dr) + 60ms) !important; }
  /* Le contenu de la vitre attend qu'elle soit posée, puis arrive du fond. */
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) #view > :not(.vhead):not(.vh):not(.cv):not(.vm):not(.orb),
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) #view .vm-sheet { animation: sp360-fond .5s var(--sp360-glisse) both !important; animation-delay: 300ms !important; }
  /* Tuiles : l'une après l'autre, du fond vers soi, avec un léger rebond (rang --hud-i posé par app.js). Même
     sélecteur que la règle des call-outs de spatial.css, plus la classe du mode : il l'emporte sur elle. */
  html.rt.sp.d360 #app #stage .view.hud-entree [data-tilt][style*="--hud-i"]:not(.vh-orn):not(.vm-insp),
  html.rt.sp.d360 #app #stage.sp-co-in .view.hud-entree [data-tilt][style*="--hud-i"]:not(.vh-orn):not(.vm-insp) { animation: sp360-tuile .52s var(--sp360-ressort) both !important; animation-delay: calc(400ms + min(var(--hud-i), 10) * 45ms) !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) #view :is(.section-title, .vm-group) { animation: sp360-efface .3s ease-out reverse both !important; animation-delay: 380ms !important; }

  /* ---------- 4. Accueil : le réacteur se matérialise, les rubriques arrivent une fois les fenêtres posées ---------- */
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .vh-center { animation: none !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .nv { animation: sp360-noyau .8s var(--sp360-ressort) both !important; animation-delay: 140ms !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .vh-act { animation: sp360-fond .5s var(--sp360-glisse) both !important; animation-delay: 260ms !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .vh-state { animation: sp360-fond .5s var(--sp360-glisse) both !important; animation-delay: 420ms !important; }
  html.rt.sp.d360 #app #stage:is(.sp-in, .sp-co-in) .vh-brief { animation: sp360-fond .5s var(--sp360-glisse) both !important; animation-delay: 520ms !important; }
  html.rt.sp.d360 #app #stage.sp-co-in .vh-col > .vh-orn { animation: sp360-tuile .46s var(--sp360-ressort) both !important; animation-delay: calc(var(--dl) + 470ms + var(--co-i, 0) * 80ms) !important; }
  html.rt.sp.d360 #app #stage.sp-co-in .vh-col--r > .vh-orn { animation-delay: calc(var(--dr) + 470ms + var(--co-i, 0) * 80ms) !important; }

  /* ---------- 5. Traits (call-outs) : ils se tracent une fois les fenêtres arrivées (environ 480 ms plus tard) ---------- */
  html.rt.sp.d360 #app .sp-co.is-joue .sp-co__a { animation-delay: calc(var(--d) + 540ms); }
  html.rt.sp.d360 #app .sp-co.is-joue :is(.sp-co__o, .sp-co__t) { animation-delay: calc(var(--d) + 560ms); }
  html.rt.sp.d360 #app .sp-co.is-joue :is(.sp-co__p, .sp-co__h) { animation-delay: calc(var(--d) + 480ms); }
  html.rt.sp.d360 #app .sp-co.is-joue .sp-co__b { animation-delay: calc(var(--d) + 780ms); }
  html.rt.sp.d360 #app .sp-co.is-joue .is-ephemere { animation-duration: 1.6s; }
}

@keyframes sp360-part { to { opacity: 0; transform: perspective(1500px) translate3d(calc(var(--s, 1) * -34vw), 0, -320px) rotateY(calc(var(--ry0, 0deg) + var(--s, 1) * 34deg)); } }
@keyframes sp360-part-i { to { opacity: 0; translate: calc(var(--s, 1) * -30vw) 0; scale: .82; } }
@keyframes sp360-entre {
  from { opacity: 0; transform: perspective(1500px) translate3d(calc(var(--s, 1) * 34vw), 0, -320px) rotateY(calc(var(--ry0, 0deg) - var(--s, 1) * 34deg)); }
  45% { opacity: 1; }
  to { transform: perspective(1500px) translate3d(0, 0, 0) rotateY(var(--ry0, 0deg)); }
}
@keyframes sp360-entre-i { from { opacity: 0; translate: calc(var(--s, 1) * 30vw) 0; scale: .82; } 45% { opacity: 1; } }
@keyframes sp360-efface { to { opacity: 0; scale: .97; } }
@keyframes sp360-fond { from { opacity: 0; translate: 0 18px; scale: .93; } }
@keyframes sp360-tuile { from { opacity: 0; translate: 0 22px; scale: .9; } 60% { opacity: 1; } }
@keyframes sp360-noyau { from { opacity: 0; translate: calc(var(--s, 1) * 9vw) 0; scale: .45; } 55% { opacity: 1; } }

/* ---------- 6. Repère de section : le cap de la caméra à côté du numéro (« 03 / 13 · 055° ») ---------- */
html.rt.sp.d360.sp360-pret #app .sp-pager output[data-cap]::after { content: " · " attr(data-cap); color: var(--sp-t3); }

/* ---------- 7. Mouvement réduit, « Animations » coupé : aucune de ces animations ---------- */
@media (prefers-reduced-motion: reduce) {
  html.rt.sp.d360 #app #stage :is(.vhead, .vm-insp, .vm-sheet, .vh-col, .vh-col > .vh-orn, .cv-fil, .cv-sessions, .nv, .vh-state, .vh-act, .vh-brief, .section-title, .vm-group), html.rt.sp.d360 #app #stage #view > *, html.rt.sp.d360 #app #stage #view::before, html.rt.sp.d360 #app #stage::after, html.rt.sp.d360 #app #stage .view.hud-entree [data-tilt] { animation: none !important; }
}
html.no-motion.sp.d360 #app #stage :is(.vhead, .vm-insp, .vm-sheet, .vh-col, .vh-col > .vh-orn, .cv-fil, .cv-sessions, .nv, .vh-state, .vh-act, .vh-brief, .section-title, .vm-group), html.no-motion.sp.d360 #app #stage #view > *, html.no-motion.sp.d360 #app #stage #view::before, html.no-motion.sp.d360 #app #stage::after, html.no-motion.sp.d360 #app #stage .view.hud-entree [data-tilt] { animation: none !important; }
