/* ============================================================================
   REKOV — intro du héro, pilotée par le CSS
   ----------------------------------------------------------------------------
   Principe : le contenu est VISIBLE par défaut, ou rendu visible par une
   animation CSS qui se termine toujours d'elle-même. Aucun état de départ
   n'est posé par JS.

   Pourquoi : une intro en gsap.from() pose immédiatement opacity:0 en style
   inline, puis compte sur le ticker GSAP pour la relever. Si le ticker ne
   démarre pas — onglet en arrière-plan, iframe masquée au chargement, CDN
   lent ou bloqué — le héro reste vide et il ne reste que le header. Une
   animation CSS, elle, est portée par le moteur de rendu : elle se termine
   même si aucun JS ne tourne.

   GSAP reste, mais uniquement en enrichissement : scrub au scroll, dérive au
   pointeur, balayages. Ces effets ne sont branchés qu'après la première image
   réellement rendue (voir hero-intro.js).
============================================================================ */

/* ---- Entrées séquencées : --i porte le rang, pas le délai ---- */
[data-in] {
  animation: rkIn 0.85s var(--ease) both;
  animation-delay: calc(0.12s + var(--i, 0) * 0.085s);
}
@keyframes rkIn {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: none; }
}

/* ---- Titre : une ligne monte depuis son propre masque ----
   Un masque = une vraie ligne de texte. Le nombre de lignes est décidé dans
   le HTML, jamais par le retour à la ligne automatique : sinon le masque
   coupe une phrase en plein milieu.

   La réserve de jambage. Un overflow:hidden coupe au bord de la boîte de
   PADDING : sans réserve, il rogne les descendantes. Manrope 800 a une boîte
   de glyphe de 1,366em pour un interlignage de 1,15em — le demi-interligne
   est donc NÉGATIF (−0,108em de chaque côté) et le « p » de « transporteurs »
   perdait 1,5 px de queue.

   Corrigé sur la contrainte et non au pixel : une réserve sous la ligne,
   annulée par une marge négative de même valeur. L'interlignage reste celui
   du socle (1,15) et la composition ne bouge pas d'un pixel, mais le masque
   gagne la place du jambage. La valeur étant en em, elle tient sur toute la
   plage de la clamp au lieu de se dégrader aux grandes tailles. */
.hero-lines .line-mask {
  display: block; overflow: hidden;
  --jamb: 0.16em;
  padding-bottom: var(--jamb);
  margin-bottom: calc(var(--jamb) * -1);
}
.hero-lines .line-mask > span {
  display: block;
  animation: rkLine 1s var(--ease) both;
}
.hero-lines .line-mask:nth-child(1) > span { animation-delay: 0.20s; }
.hero-lines .line-mask:nth-child(2) > span { animation-delay: 0.29s; }
.hero-lines .line-mask:nth-child(3) > span { animation-delay: 0.40s; }
.hero-lines .line-mask:nth-child(4) > span { animation-delay: 0.49s; }
/* 140 % et non 106 % : la réserve de jambage agrandit la zone visible du
   masque vers le bas, donc la ligne doit partir de plus bas pour y rester
   cachée au repos. Sans ça, le haut des glyphes dépasse sous le masque avant
   que l'animation ne démarre. */
@keyframes rkLine {
  from { transform: translateY(140%); }
  to   { transform: none; }
}

/* ---- Le zéro se trace ----
   La longueur du tracé est fixée en unités de viewBox, pas mesurée en JS :
   c'est ce qui permet au tracé de partir sans attendre aucun script. La
   valeur couvre le contour extérieur et le contour intérieur du zéro. */
[data-zero] .z-stroke {
  stroke-dasharray: 480;
  animation: rkDraw 1.7s var(--ease-io) 0.15s both;
}
@keyframes rkDraw {
  from { stroke-dashoffset: 480; }
  to   { stroke-dashoffset: 0; }
}
[data-zero] .z-fill {
  animation: rkFade 0.9s var(--ease) 1.15s both;
}
@keyframes rkFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* L'arc est complet par défaut. S'il doit se refermer au scroll, c'est
   hero-intro.js qui reprend la main — et seulement s'il peut animer. */
[data-zero] .z-arc { stroke-dasharray: none; stroke-dashoffset: 0; }

/* ---- Moteur muet ou motion réduit : tout est déjà en place ---- */
@media (prefers-reduced-motion: reduce) {
  [data-in],
  .hero-lines .line-mask > span,
  [data-zero] .z-stroke,
  [data-zero] .z-fill { animation: none; }
  [data-zero] .z-stroke { stroke-dasharray: none; stroke-dashoffset: 0; }
}
