/* Réactivité (spec 2026-10-11, voile du 02/11/2026) : l'appui qui répond, puis,
   si la page tarde, un voile sombre sur tout l'écran et une cocotte qui frémit
   au centre. Les classes sont posées par core/js/reactivite.js ; rien ici ne
   restyle un composant du site.
   Maquette : .claude/design-drafts/2026-11-02-voile-chargement.html. */

/* ── Temps 1 : l'appui ──
   `scale` et non `transform` : l'élément touché peut déjà porter un transform.
   Le sélecteur pèse (0,2,1) pour passer devant l'opacité ou la transition
   qu'une feuille de page poserait sur le même élément. */
html.rx-occupe .rx-appuye {
  scale: .975;
  opacity: .78;
  transition: scale 80ms ease, opacity 80ms ease;
}
html.rx-occupe a,
html.rx-occupe button { cursor: progress; }

/* ── Temps 2 : le voile ──
   Au-dessus de tout (barres, menu, modales, toasts) : la page s'éteint et ne
   prend plus aucun appui, boutons et cases compris. Elle se devine encore
   dessous (--bg-voile) : elle change, elle n'a pas planté. touch-action : un
   glissé sur le voile ne fait pas défiler la page qu'on quitte. Seule une
   <dialog> ouverte par showModal() passe devant tout z-index : l'annonce de
   grade, qui annule déjà le clic de son lien (distinction_unlock.js). */
.rx-voile {
  position: fixed; inset: 0; z-index: 100001;
  background: var(--bg-voile);
  cursor: progress;
  touch-action: none;
  opacity: 0; visibility: hidden;
  transition: opacity 180ms ease, visibility 0s linear 180ms;
}
.rx-voile.rx-actif {
  opacity: 1; visibility: visible;
  transition: opacity 180ms ease;
}

/* ── Temps 2 : la cocotte ──
   Au centre de l'écran, au-dessus du voile. `translate` la centre, `transform`
   la fait entrer : les deux propriétés ne se marchent pas dessus. */
.rx-cocotte {
  position: fixed; left: 50%; top: 50%; z-index: 100002;
  translate: -50% -50%;
  width: 72px; height: 72px;
  box-sizing: border-box;
  display: grid; place-items: center;
  border: 1px solid var(--border-focus); border-radius: 50%;
  background: var(--bg-card-solid);
  box-shadow: var(--shadow-card);
  pointer-events: none;
  opacity: 0; visibility: hidden;
  transform: translateY(8px) scale(.9);
  transition: opacity 180ms ease, transform 180ms ease, visibility 0s linear 180ms;
}
.rx-cocotte.rx-actif {
  opacity: 1; visibility: visible;
  transform: none;
  transition: opacity 180ms ease, transform 180ms ease;
}
.rx-cocotte svg { width: 44px; height: 44px; overflow: visible; }
.rx-cocotte path,
.rx-cocotte rect { fill: var(--text-accent); }
.rx-cocotte .rx-vapeur path {
  fill: none;
  stroke: var(--text-accent); stroke-width: 3.2; stroke-linecap: round;
  opacity: 0;
}
.rx-cocotte.rx-actif .rx-couvercle {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation: rx-fremit .5s ease-in-out infinite;
}
.rx-cocotte.rx-actif .rx-vapeur path { animation: rx-vapeur 1.3s ease-out infinite; }
.rx-cocotte.rx-actif .rx-vapeur path:nth-child(2) { animation-delay: .42s; }
.rx-cocotte.rx-actif .rx-vapeur path:nth-child(3) { animation-delay: .84s; }
@keyframes rx-fremit {
  0%, 100% { transform: translateY(0) rotate(0); }
  25% { transform: translateY(-3px) rotate(-3deg); }
  60% { transform: translateY(-1px) rotate(2.5deg); }
}
@keyframes rx-vapeur {
  0% { opacity: 0; transform: translateY(6px); }
  30% { opacity: .85; }
  100% { opacity: 0; transform: translateY(-14px); }
}

/* ── iOS ──
   Safari gèle transitions et animations dès que la navigation démarre : le
   signe, posé dans le geste (html.rx-ios, reactivite.js), doit se lire dans
   sa première image. Pas de fondu d'entrée ; les volutes partent en cours de
   course, mêmes écarts entre elles. */
html.rx-ios .rx-voile,
html.rx-ios .rx-voile.rx-actif,
html.rx-ios .rx-cocotte,
html.rx-ios .rx-cocotte.rx-actif { transition: none; }
html.rx-ios .rx-cocotte .rx-vapeur path { opacity: .7; }
@media (prefers-reduced-motion: no-preference) {
  html.rx-ios .rx-cocotte.rx-actif .rx-vapeur path { animation-delay: -.52s; }
  html.rx-ios .rx-cocotte.rx-actif .rx-vapeur path:nth-child(2) { animation-delay: -.1s; }
  html.rx-ios .rx-cocotte.rx-actif .rx-vapeur path:nth-child(3) { animation-delay: -.98s; }
}

/* Animations réduites : la cocotte s'affiche, rien ne bouge ; les volutes
   restent visibles. Le voile garde son fondu : il éteint, il ne bouge pas. */
@media (prefers-reduced-motion: reduce) {
  html.rx-occupe .rx-appuye,
  .rx-cocotte,
  .rx-cocotte.rx-actif { transition: none; }
  .rx-cocotte.rx-actif .rx-couvercle,
  .rx-cocotte.rx-actif .rx-vapeur path { animation: none; }
  .rx-cocotte.rx-actif .rx-vapeur path { opacity: .7; }
}
