/* ═══════════════════════════════════════════════════════════════════════
   SCROLER — Hero d'accueil : intro vocale + projecteurs holographiques
   v6                                                     Three.js r128
   ───────────────────────────────────────────────────────────────────────
   Différences avec la v5 :
   • plus aucun !important de mise en forme (264 en v5) : la spécificité
     `#scroler-hero .x` suffit face à un thème WordPress, et l'attribut
     `hidden` redevient donc opérant. Les 5 restants sont cantonnés au bloc
     prefers-reduced-motion, où ils sont indispensables pour neutraliser
     les animations d'auteur ;
   • repli `100vh` avant `100svh` (sinon hauteur nulle sur Safari < 15.4) ;
   • contrastes remontés au seuil AA (boutons, repères, aide, accent) ;
   • styles de focus visibles sur tous les contrôles ;
   • le texte et les liens sont visibles PAR DÉFAUT : c'est le JS qui les
     masque une fois qu'il a pris la main (amélioration progressive) ;
   • media query de faible hauteur (paysage mobile) ;
   • prefers-reduced-motion neutralise aussi les délais, pas que les durées ;
   • `min-height: 420px` : plancher sous lequel le bloc haut se ferait rogner
     par overflow:hidden en paysage mobile ;
   • `width: max-content` sur .scr__poles : les libellés sont plus longs qu’en
     v5 (« Création de site web » et non « Site Web »).
   ═══════════════════════════════════════════════════════════════════════ */

/* ═══ Jetons locaux ════════════════════════════════════════════════════ */
#scroler-hero {
  --scr-d-black: 1.320;  --scr-y-black:  61.1%;
  --scr-d-grey:  0.820;  --scr-y-grey:  -57.7%;

  --scr-o: 82px;                            /* Ø du O = hauteur de capitale */
  --scr-o-big: clamp(104px, 15vmin, 138px); /* Ø du O pendant la diction    */
}

/* ═══ Base ═════════════════════════════════════════════════════════════ */
#scroler-hero {
  position: relative;
  width: 100%;
  /* Ordre volontaire : un navigateur sans `svh` garde la première ligne
     et le hero fait bien la hauteur de l'écran au lieu de 0 px.        */
  height: calc(100vh - var(--scr-header));
  height: calc(100svh - var(--scr-header));
  min-height: 420px;
  margin: 0;
  padding: 0;
  background: var(--scr-paper);
  color: var(--scr-ink);
  font-family: var(--scr-font);
  overflow: hidden;
  overscroll-behavior-y: contain;
  isolation: isolate;
}

/* ═══ Sol ══════════════════════════════════════════════════════════════ */
#scroler-hero .scr__floor {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.5s ease;
  background: linear-gradient(to bottom,
    rgba(23,18,15,0)    0%,
    rgba(23,18,15,0)   42%,
    rgba(23,18,15,.55) 58%,
    rgba(23,18,15,.92) 74%,
    var(--scr-night)   88%);
}
#scroler-hero[data-state="done"] .scr__floor { opacity: 1; }

/* ═══ Scène 3D ═════════════════════════════════════════════════════════
   `pan-y` et non `none` : le doigt fait toujours défiler la page
   verticalement, seul le geste horizontal est capté par le carrousel.   */
#scroler-hero .scr__scene {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 64%;
  z-index: 2;
  opacity: 0;
  transition: opacity 1.4s ease .3s;
  touch-action: pan-y;
  /* Invisible hors « done » : elle ne doit donc rien capter non plus.
     Sans ca, un clic dans le vide pendant une intro rejouee naviguait. */
  pointer-events: none;
}
#scroler-hero[data-state="done"] .scr__scene { opacity: 1; pointer-events: auto; }
#scroler-hero .scr__scene canvas { display: block; width: 100%; height: 100%; }

/* ═══ Bloc haut ════════════════════════════════════════════════════════
   Centré pendant la diction, il remonte quand les projecteurs s'allument
   pour leur libérer les deux tiers bas de l'écran.                      */
#scroler-hero .scr__head {
  position: absolute;
  left: 50%; top: 50%;
  z-index: 4;
  width: 100%;
  max-width: 880px;
  padding: 0 5vw;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  pointer-events: none;
  transition: top 1.2s var(--scr-ease);
}
#scroler-hero[data-state="done"] .scr__head { top: 23%; }

/* ═══ Zone du speaker ══════════════════════════════════════════════════ */
#scroler-hero .scr__orbzone {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: calc(var(--scr-o-big) * 2.2);
  transition: height 1s var(--scr-ease) .2s;
}
/* Le rond noir descend à 1.271 Ø sous le centre : il faut au moins
   2.55 Ø de hauteur pour qu'il ne morde pas sur le texte du bas.       */
#scroler-hero[data-state="done"] .scr__orbzone { height: calc(var(--scr-o) * 2.62); }

/* Sonde invisible : sa largeur vaut toujours --scr-o résolu en pixels.
   Indispensable, car getComputedStyle() rend la custom property BRUTE
   (« clamp(38px,11.5vw,48px) »), que parseFloat ne sait pas lire.      */
#scroler-hero .scr__probe {
  position: absolute;
  left: 0; top: 0;
  width: var(--scr-o);
  height: 1px;
  visibility: hidden;
  pointer-events: none;
}

#scroler-hero .scr__orb {
  position: relative;
  z-index: 1;
  width: var(--scr-o-big);
  height: var(--scr-o-big);
  opacity: 0;
  animation: scrIn 1.1s var(--scr-ease) .15s forwards;
  transition: width 1s var(--scr-ease) .2s, height 1s var(--scr-ease) .2s;
}
#scroler-hero[data-state="done"] .scr__orb { width: var(--scr-o); height: var(--scr-o); }
@keyframes scrIn { from { opacity: 0; transform: scale(.7); } to { opacity: 1; transform: scale(1); } }

#scroler-hero .scr__ring {
  position: absolute;
  inset: 0;
  z-index: 3;
  border: 2px solid var(--scr-orange);
  border-radius: 50%;
  background: var(--scr-ink);
  overflow: hidden;
}
/* Le O est noir pendant toute la séquence ; il ne révèle son anthracite
   qu'au moment précis où le rond noir se détache, donc à couvert.      */
#scroler-hero[data-state="done"] .scr__ring {
  background: var(--scr-coal);
  transition: background-color 0s 1.08s;
}
#scroler-hero .scr__ring.is-breathing { animation: scrBreath 4.5s ease-in-out infinite; }

/* ═══ Reconstitution du logo officiel ══════════════════════════════════
   Mesuré sur le fichier d'origine : noir Ø 1.453 y +0.622, gris Ø 0.860
   y -0.581, soit ~41 % de recouvrement chacun avec l'anneau. Les ronds
   ont été retaillés en conservant ce taux, donc la grappe garde sa
   cohésion. Les deux ronds démarrent CONFONDUS avec le O — le noir à la
   taille de son remplissage, le gris masqué derrière — puis s'en
   extraient.                                                            */
#scroler-hero .scr__dot {
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 100%;
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}
#scroler-hero .scr__dot--grey {
  z-index: 2;
  background: var(--scr-grey);
  transform: translateY(0) scale(var(--scr-d-grey));
  transition: opacity 0s 1.05s, transform 1.15s var(--scr-ease) 1.22s;
}
#scroler-hero .scr__dot--black {
  z-index: 4;
  background: var(--scr-ink);
  transform: translateY(0) scale(.955);   /* = taille du remplissage du O */
  transition: opacity 0s 1.05s, transform 1.2s cubic-bezier(.20,1.12,.35,1) 1.10s;
}
#scroler-hero[data-state="done"] .scr__dot { opacity: 1; }
#scroler-hero[data-state="done"] .scr__dot--grey  { transform: translateY(var(--scr-y-grey))  scale(var(--scr-d-grey)); }
#scroler-hero[data-state="done"] .scr__dot--black { transform: translateY(var(--scr-y-black)) scale(var(--scr-d-black)); }
@keyframes scrBreath { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.028); } }

#scroler-hero .scr__core {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  display: block;
  opacity: 0;
  transition: opacity .7s ease;
  pointer-events: none;
}
#scroler-hero[data-state="speaking"] .scr__core { opacity: 1; }

/* ═══ Aura ═════════════════════════════════════════════════════════════
   Seul `transform` est animé : `border-radius` déclenchait un repaint
   d'une surface floutée à chaque frame, le poste le plus cher de la page
   sur mobile. La déformation organique vient maintenant de la rotation
   de trois calques d'ellipses décalées.                                  */
#scroler-hero .scr__aura {
  --a: 0;
  position: absolute;
  inset: -58%;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transform: scale(calc(.80 + var(--a) * .34));
}
#scroler-hero .scr__aura-l {
  position: absolute;
  inset: 0;
  border-radius: 47% 53% 58% 42% / 52% 46% 54% 48%;
  background: radial-gradient(circle at 50% 50%,
    rgba(233,78,26,.72)  0%,
    rgba(233,78,26,.40) 30%,
    rgba(233,78,26,.15) 50%,
    rgba(233,78,26,.04) 64%,
    rgba(233,78,26,0)   76%);
  will-change: transform;
}
#scroler-hero .scr__aura-l1 { filter: blur(24px); opacity: .90; animation: scrBlobA 17s ease-in-out infinite; }
#scroler-hero .scr__aura-l2 { inset: 6%;  border-radius: 56% 44% 41% 59% / 43% 57% 43% 57%;
                              filter: blur(40px); opacity: .75; animation: scrBlobB 24s ease-in-out infinite; }
#scroler-hero .scr__aura-l3 { inset: 24%; border-radius: 41% 59% 55% 45% / 58% 43% 57% 42%;
                              filter: blur(14px); opacity: .55; animation: scrBlobA 11s ease-in-out infinite reverse; }

/* L'aura ne tourne que pendant la diction : après, plus rien à composer. */
#scroler-hero:not([data-state="speaking"]) .scr__aura-l { animation-play-state: paused; }

@keyframes scrBlobA {
  0%   { transform: rotate(0deg)   scale(1);    }
  33%  { transform: rotate(120deg) scale(1.07); }
  66%  { transform: rotate(240deg) scale(.95);  }
  100% { transform: rotate(360deg) scale(1);    }
}
@keyframes scrBlobB {
  0%   { transform: rotate(0deg)    scale(1.04); }
  50%  { transform: rotate(-180deg) scale(.92);  }
  100% { transform: rotate(-360deg) scale(1.04); }
}

#scroler-hero .scr__ripples { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
#scroler-hero .scr__rip {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid var(--scr-orange);
  filter: blur(3px);
  opacity: 0;
}
@keyframes scrRip { from { transform: scale(1); opacity: .30; } to { transform: scale(2.5); opacity: 0; } }

/* ═══ Logotype ═════════════════════════════════════════════════════════ */
#scroler-hero .scr__mark {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
#scroler-hero .scr__mark-gap { width: calc(var(--scr-o) * 1.814); flex: 0 0 auto; }
#scroler-hero .scr__mark-side {
  --dx: 0px;
  flex: 0 0 auto;
  display: block;
  font-weight: 200;
  font-size: 1em;
  letter-spacing: .05em;
  line-height: 1;
  color: var(--scr-ink);
  opacity: 0;
  transform: translate(var(--dx), var(--dy, 0px));
  transition: opacity .7s ease, transform .9s var(--scr-ease);
}
#scroler-hero .scr__mark-l { --dx:  26px; text-align: right; }
#scroler-hero .scr__mark-r { --dx: -26px; text-align: left;  }
#scroler-hero .scr__mark-l .scr__mark-t { margin-right: -.05em; }
#scroler-hero[data-state="done"] .scr__mark-side { --dx: 0px; opacity: 1; transition-delay: .6s; }

/* ═══ Texte tapé, de part et d'autre du speaker ════════════════════════ */
#scroler-hero .scr__speech {
  margin: 0;
  padding: 0;
  font-weight: 200;
  font-size: clamp(21px, 3.3vw, 34px);
  line-height: 1.34;
  letter-spacing: .005em;
  color: var(--scr-ink);
  max-width: 34ch;
  min-height: 1.34em;
}
#scroler-hero .scr__speech--top { margin-bottom: clamp(10px, 1.6vmin, 20px); }
#scroler-hero .scr__speech--bot { margin-top:    clamp(10px, 1.6vmin, 20px); }
#scroler-hero .scr__w { white-space: nowrap; }

/* Les caractères ne sont masqués QUE si le script a pris la main.
   Sans JS, la phrase reste lisible telle qu'écrite dans le HTML.      */
#scroler-hero.is-typing .scr__c { opacity: 0; transition: opacity .12s linear; }
#scroler-hero.is-typing .scr__c.is-on { opacity: 1; }

/* #C13D12 : 4,6:1 sur le papier (mesuré). L'orange de marque #E94E1A tombe à
   3,3:1 et ne passe pas le seuil AA pour du texte de cette graisse.   */
#scroler-hero .scr__accent { color: var(--scr-orange-d); font-weight: inherit; }
#scroler-hero .scr__caret {
  display: inline-block;
  width: 2px;
  height: .84em;
  background: var(--scr-orange-d);
  vertical-align: -.08em;
  margin-left: .05em;
  animation: scrBlink 1s steps(2) infinite;
}
@keyframes scrBlink { 50% { opacity: 0; } }

/* ═══ Navigation du carrousel ══════════════════════════════════════════
   Cibles tactiles de 26 × 24 px : la barre visible reste fine (2 px),
   c'est le padding transparent qui porte la zone cliquable (WCAG 2.5.8).*/
#scroler-hero .scr__nav {
  position: absolute;
  left: 50%; bottom: 47px;
  z-index: 5;
  transform: translateX(-50%);
  display: flex;
  gap: 9px;
  align-items: center;
  opacity: 0;
  visibility: hidden;
  /* Délais ASYMÉTRIQUES : la règle de base sert au retour vers « wait »
     (clic sur « Rejouer »). Si elle portait le délai d'entrée, les
     repères clairs resteraient affichés 1,2 s sur un sol en train de
     redevenir clair — donc invisibles.                                */
  transition: opacity .35s ease 0s, visibility 0s linear .35s;
}
#scroler-hero[data-state="done"] .scr__nav {
  opacity: 1;
  visibility: visible;
  transition: opacity .8s ease 1.2s, visibility 0s linear 1.2s;
}
#scroler-hero .scr__pip {
  width: 26px;
  height: 24px;
  padding: 11px 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
#scroler-hero .scr__pip::before {
  content: "";
  display: block;
  height: 2px;
  /* .55 sur le sol nocturne #14100D = 5,6:1 (recalculé) ; le seuil d'un
     composant d'interface est de 3:1, on est largement au-dessus. */
  background: rgba(242,239,234,.55);
  transition: background-color .4s ease, transform .4s ease;
}
#scroler-hero .scr__pip[aria-current="true"]::before {
  background: var(--scr-accent, var(--scr-orange));
  transform: scaleY(2);
  transition: background-color .5s ease, transform .4s ease;
}
#scroler-hero .scr__pip:hover::before { background: var(--scr-paper); }
#scroler-hero .scr__pip:focus-visible {
  outline: 3px solid var(--scr-orange);
  outline-offset: 4px;
  border-radius: 2px;
}

#scroler-hero .scr__hint {
  position: absolute;
  left: 50%; bottom: 26px;
  z-index: 5;
  transform: translateX(-50%);
  margin: 0;
  font-family: var(--scr-mono);
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(242,239,234,.72);          /* 8,9:1 sur le sol nocturne #14100D */
  white-space: nowrap;
  opacity: 0;
  transition: opacity .3s ease 0s;       /* retour immédiat vers « wait » */
  pointer-events: none;
}
#scroler-hero[data-state="done"] .scr__hint { opacity: 1; transition: opacity .8s ease 1.6s; }
#scroler-hero .scr__hint.is-gone { opacity: 0; transition-delay: 0s; }

/* ═══ Navigation réelle vers les 3 pôles ═══════════════════════════════
   Ce <nav> est TOUJOURS dans le DOM et toujours focusable : c'est lui qui
   porte la sémantique, l'indexation et le parcours clavier. La scène 3D
   n'en est qu'une représentation décorative.
   Quand la 3D tourne, on le masque VISUELLEMENT (jamais display:none ni
   visibility:hidden, qui le sortiraient de l'ordre de tabulation), et il
   réapparaît en superposition dès qu'il reçoit le focus clavier.       */
#scroler-hero .scr__poles {
  position: absolute;
  left: 50%; bottom: 16%;
  z-index: 5;
  transform: translateX(-50%);
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
  width: max-content;
  max-width: 90%;
}
/* Posée par le JS dès qu’il prend la main, et RETIRÉE en repli : pas de
   Three.js, pas de WebGL, ou contexte perdu. Sans JS, elle n’est jamais
   posée et les liens s’affichent normalement. */
#scroler-hero .scr__poles.is-visually-hidden {
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
#scroler-hero .scr__poles.is-visually-hidden:focus-within {
  width: auto;
  height: auto;
  max-width: 90%;
  overflow: visible;
  clip-path: none;
  white-space: normal;                 /* le clip forçait nowrap */
  padding: 18px;
  background: rgba(23,18,15,.94);
  border: 1px solid rgba(242,239,234,.22);
  border-radius: 18px;
}
/* Ce panneau apporte SON PROPRE fond sombre, indépendamment du sol : la
   couleur du texte doit donc suivre le panneau et non l'état du hero.
   Sans cette règle, un utilisateur clavier qui déplie les liens pendant
   l'intro (le sol est alors encore clair, donc .scr__cta est noir) lit du
   #121211 sur du #241F1C, soit 1,15:1 — parfaitement invisible.        */
#scroler-hero .scr__poles.is-visually-hidden:focus-within .scr__cta {
  color: var(--scr-paper);
  border-color: var(--scr-orange);
}
/* La pastille noire disparaîtrait elle aussi sur ce fond. */
#scroler-hero .scr__poles.is-visually-hidden:focus-within .scr__cta-dot--ink {
  background: var(--scr-coal);
  box-shadow: 0 0 0 1px rgba(242,239,234,.45);
}
/* Repli sans WebGL : le bloc est alors réellement visible, et il peut
   tomber en plein milieu du dégradé du sol — ni clair, ni sombre, donc
   illisible quelle que soit la couleur du texte. Un fond propre garantit
   le contraste où qu'il se place, y compris en colonne sur mobile.     */
#scroler-hero[data-state="done"] .scr__poles:not(.is-visually-hidden) {
  padding: 18px;
  background: rgba(23,18,15,.90);
  border: 1px solid rgba(242,239,234,.16);
  border-radius: 20px;
}

/* Avant l'allumage du sol, le fond est encore clair : le texte doit
   l'être aussi ou non selon l'état, d'où les deux jeux de couleurs.   */
#scroler-hero .scr__cta {
  display: inline-flex;
  align-items: center;
  gap: .85em;
  min-height: 48px;
  padding: 15px 30px;
  border: 2px solid var(--scr-orange-d);
  border-radius: 999px;
  background: transparent;
  color: var(--scr-on-paper);
  font-family: var(--scr-mono);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: .13em;
  text-transform: uppercase;
  text-decoration: none;
  /* La couleur du texte suit le sol, qui met 1,5 s à s'allumer ou à
     s'éteindre : les deux évoluent ensemble, jamais l'un sans l'autre. */
  transition: background-color .3s ease, border-color .3s ease, color 1.5s ease;
}
#scroler-hero[data-state="done"] .scr__cta { border-color: var(--scr-orange); color: var(--scr-paper); }
#scroler-hero .scr__cta:hover { transition: background-color .3s ease, border-color .3s ease, color .3s ease; }
#scroler-hero .scr__cta:hover { background: var(--scr-orange-d); color: #fff; border-color: var(--scr-orange-d); }
#scroler-hero .scr__cta:focus-visible { outline: 3px solid var(--scr-orange); outline-offset: 4px; }
#scroler-hero .scr__cta-dot {
  width: 13px; height: 13px;
  border-radius: 50%;
  flex: 0 0 auto;
}
#scroler-hero .scr__cta-dot--ink  { background: var(--scr-ink); }
#scroler-hero .scr__cta-dot--grey { background: var(--scr-grey); }
#scroler-hero .scr__cta-dot--ring { background: transparent; border: 2px solid var(--scr-orange); }

/* ═══ Contrôles discrets ═══════════════════════════════════════════════ */
#scroler-hero .scr__util {
  position: absolute;
  top: 20px; right: 20px;
  z-index: 6;
  display: flex;
  gap: 4px;
}
#scroler-hero .scr__btn {
  background: none;
  border: 0;
  min-height: 40px;
  padding: 10px 14px;
  cursor: pointer;
  font-family: var(--scr-mono);
  font-size: 10px;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--scr-on-paper-soft);        /* 7,7:1 sur le papier (mesuré) */
  transition: color .25s ease;
  opacity: 0;
  animation: scrFade .5s ease forwards;
}
#scroler-hero .scr__btn:hover { color: var(--scr-orange-d); }
#scroler-hero .scr__btn:focus-visible { outline: 3px solid var(--scr-orange); outline-offset: 2px; border-radius: 2px; }
#scroler-hero .scr__btn--sound { color: var(--scr-orange-d); }
/* Ces boutons gardent une couleur sombre dans TOUS les états : le dégradé
   du sol est encore totalement transparent sur les 42 premiers pour cent
   de la hauteur, donc le fond derrière eux reste le papier clair, même
   une fois les projecteurs allumés.                                    */
@keyframes scrFade { to { opacity: 1; } }

/* ═══ Sans JavaScript ══════════════════════════════════════════════════ */
#scroler-hero .scr__noscript {
  position: absolute;
  left: 50%; top: 20px;
  z-index: 7;
  transform: translateX(-50%);
  width: min(90%, 560px);
  text-align: center;
  font-size: 14px;
  line-height: 1.5;
  color: var(--scr-on-paper-soft);
}

/* ═══ Mobile ═══════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  #scroler-hero { --scr-o: clamp(38px, 11.5vw, 48px); --scr-o-big: clamp(92px, 26vw, 118px); }
  #scroler-hero .scr__speech { font-size: clamp(18px, 5vw, 24px); max-width: none; }
  #scroler-hero .scr__speech--bot { min-height: 2.68em; }
  #scroler-hero .scr__scene { height: 60%; }
  #scroler-hero[data-state="done"] .scr__head { top: 21%; }
  /* En colonne, le bloc mesure ~215 px : ancré à 16 % de hauteur, il
     débordait du hero sur un écran de 568 px et le troisième lien était
     rogné par overflow:hidden. Ancré au bas, il tient partout, et le
     fond opaque ajouté plus haut garantit déjà le contraste.          */
  #scroler-hero .scr__poles {
    flex-direction: column;
    top: auto;
    bottom: 16px;
    width: 80%;
    gap: 14px;
  }
  #scroler-hero .scr__cta { justify-content: center; width: 100%; }
}

/* ═══ Écran court : paysage mobile, fenêtre réduite ════════════════════
   Sans cette règle, .scr__head déborde du hero et la première phrase est
   rognée par overflow:hidden.                                          */
@media (max-height: 520px) {
  #scroler-hero { --scr-o: clamp(34px, 9vmin, 52px); --scr-o-big: clamp(64px, 18vmin, 92px); }
  #scroler-hero .scr__speech { font-size: clamp(15px, 3.4vmin, 21px); }
  #scroler-hero .scr__orbzone { height: calc(var(--scr-o-big) * 1.9); }
  #scroler-hero .scr__scene { height: 56%; }
  #scroler-hero[data-state="done"] .scr__head { top: 19%; }
  #scroler-hero .scr__nav  { bottom: 30px; }
  #scroler-hero .scr__hint { display: none; }
  #scroler-hero .scr__poles { flex-direction: row; bottom: 12%; top: auto; }
}

/* ═══ Mouvement réduit ═════════════════════════════════════════════════
   `animation-delay` et `transition-delay` sont neutralisés eux aussi :
   sans ça, un délai de 1,22 s subsistait et l'interface restait figée
   plus d'une seconde après la fin de l'intro.                          */
@media (prefers-reduced-motion: reduce) {
  #scroler-hero *,
  #scroler-hero *::before,
  #scroler-hero *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
  }
  #scroler-hero .scr__aura,
  #scroler-hero .scr__ripples { display: none; }
}

/* ═══ Contrastes forcés (Windows) ══════════════════════════════════════ */
@media (forced-colors: active) {
  #scroler-hero .scr__cta { border: 2px solid LinkText; color: LinkText; }
  #scroler-hero .scr__pip::before { background: ButtonText; }
  #scroler-hero .scr__scene { display: none; }
  #scroler-hero .scr__poles.is-visually-hidden {
    width: auto; height: auto; clip-path: none; overflow: visible; white-space: normal;
  }
}

/* ═══ Impression ═══════════════════════════════════════════════════════ */
@media print {
  #scroler-hero { height: auto; min-height: 0; overflow: visible; background: #fff; }
  #scroler-hero .scr__scene,
  #scroler-hero .scr__floor,
  #scroler-hero .scr__aura,
  #scroler-hero .scr__util,
  #scroler-hero .scr__nav,
  #scroler-hero .scr__hint { display: none; }
  #scroler-hero .scr__head { position: static; transform: none; max-width: none; }
  #scroler-hero .scr__poles { position: static; transform: none; width: auto; margin-top: 24px; }
  #scroler-hero .scr__poles.is-visually-hidden {
    width: auto; height: auto; clip-path: none; overflow: visible; white-space: normal;
  }
}
