/* ============================================================
   HERO INTRO — séquence d'ouverture "calage de signal vidéo"
   ------------------------------------------------------------
   Module isolé. Tout est porté par la classe .hero-intro,
   posée sur <html> par hero-intro.js dès son exécution.
   Sans le script, aucune de ces règles ne s'applique :
   le hero s'affiche normalement dans son état final.

   Désactivation : commenter la ligne <script src="hero-intro.js">
   dans index.html. Ce fichier peut rester lié sans effet.
   ============================================================ */

:root{
  --intro-ease:cubic-bezier(0.16, 1, 0.3, 1);
}

/* ------------------------------------------------------------
   ÉTAT INITIAL — appliqué uniquement pendant que la séquence
   est armée (.hero-intro), retiré à la fin (.hero-intro-done).
   Uniquement opacity / transform / clip-path : zéro layout shift,
   les éléments occupent leur place finale dès le premier paint.
   ------------------------------------------------------------ */

/* Les animations d'arrivée d'origine sont neutralisées :
   la timeline JS pilote tout, sinon les deux se superposent. */
.hero-intro:not(.hero-intro-done) .hero .eyebrow,
.hero-intro:not(.hero-intro-done) .hero h1,
.hero-intro:not(.hero-intro-done) .hero p.lead,
.hero-intro:not(.hero-intro-done) .hero .cta-row,
.hero-intro:not(.hero-intro-done) .hero .hero-stats,
.hero-intro:not(.hero-intro-done) .viewport,
.hero-intro:not(.hero-intro-done) .vp-corner,
.hero-intro:not(.hero-intro-done) .vp-hud-top,
.hero-intro:not(.hero-intro-done) .vp-hud-bottom{
  animation:none !important;
}

.hero-intro:not(.hero-intro-done) .bg-pattern,
.hero-intro:not(.hero-intro-done) .hero .eyebrow,
.hero-intro:not(.hero-intro-done) .hero p.lead,
.hero-intro:not(.hero-intro-done) .hero .cta-row > *,
.hero-intro:not(.hero-intro-done) .hero .stat,
.hero-intro:not(.hero-intro-done) .vp-hud-top > *,
.hero-intro:not(.hero-intro-done) .vp-hud-bottom > *{
  opacity:0;
}

/* Les coins sont tracés par stroke-dashoffset (SVG, pathLength=100) */
.hero-intro:not(.hero-intro-done) .vp-corner path{
  stroke-dasharray:100;
  stroke-dashoffset:100;
}

/* La bordure du cadre s'accroche avec les coins */
.hero-intro:not(.hero-intro-done) .viewport{
  border-color:transparent;
}

/* La dalle de verre se pose avec le cadre, pas avant */
.hero-intro:not(.hero-intro-done) .viewport::before{
  opacity:0;
}

/* Les deux lignes de titre sont masquées par le bas */
.hero-intro:not(.hero-intro-done) .hero h1 .h1-line > span{
  opacity:0;
  transform:translateY(24px);
}

/* Eyebrow : crochets refermés au centre, texte masqué.
   Le décalage exact (--eb-shift) est mesuré en JS puis figé,
   donc le bloc occupe sa largeur finale dès le premier paint. */
.hero-intro:not(.hero-intro-done) .eyebrow-unfold .eb-open{transform:translateX(var(--eb-shift, 3.2em));}
.hero-intro:not(.hero-intro-done) .eyebrow-unfold .eb-close{transform:translateX(calc(-1 * var(--eb-shift, 3.2em)));}
.hero-intro:not(.hero-intro-done) .eyebrow-unfold .eb-text{
  clip-path:inset(0 50% 0 50%);
  opacity:0;
}

/* Ligne de séparation des stats : se déploie depuis la gauche */
.hero-intro:not(.hero-intro-done) .hero-stats{
  border-top-color:transparent;
}
.hero-intro:not(.hero-intro-done) .hero-stats::before{
  transform:scaleX(0);
}

/* Le REC et le ► ne clignotent qu'une fois la séquence terminée */
.hero-intro:not(.hero-intro-done) .vp-hud-top .rec::before,
.hero-intro:not(.hero-intro-done) .vp-hud-bottom .playing{
  animation:none !important;
}

/* ------------------------------------------------------------
   STRUCTURE — éléments ajoutés pour la séquence.
   Ces règles s'appliquent hors .hero-intro aussi (structure pure),
   les états animés restent sous .hero-intro.
   ------------------------------------------------------------ */

/* Ligne de séparation des stats, en pseudo-élément pour pouvoir
   l'animer en scaleX sans toucher au border (zéro layout shift). */
.hero-stats{position:relative;}
.hero-stats::before{
  content:'';
  position:absolute;top:-1px;left:0;right:0;height:1px;
  background:var(--steel-line);
  transform-origin:left center;
  pointer-events:none;
}

/* Titre découpé en deux lignes.
   Le masque n'existe QUE le temps que les lignes montent : ensuite
   overflow redevient visible, sinon il rogne les drop-shadow du
   bloom de "premium." (une ombre qui déborde de la ligne est
   clippée comme n'importe quel débordement). */
.hero h1 .h1-line{
  display:block;
}
.hero-intro:not(.hero-titles-in) .hero h1 .h1-line{
  overflow:hidden;          /* le masque : la ligne sort par le bas */
  /* marge compensée : le masque ne rogne pas les jambages
     (virgule, p, y) et le décalage net reste nul. */
  padding-bottom:0.34em;
  margin-bottom:-0.34em;
}
.hero h1 .h1-line > span{
  display:block;
}

/* Eyebrow "[ MOTION DESIGN STUDIO ]" : les crochets se déplient.
   Les crochets d'origine sont des pseudo-éléments (::before/::after)
   non ciblables par la Web Animations API — pour ce seul eyebrow on
   les neutralise et on les remplace par de vrais spans animables.
   Les autres eyebrows du site gardent leurs pseudo-éléments. */
.eyebrow-unfold::before,
.eyebrow-unfold::after{content:none;}
.eyebrow-unfold{gap:0;}
.eyebrow-unfold .eb-bracket{
  color:var(--steel-mid);
  display:inline-block;
  will-change:transform;
}
.eyebrow-unfold .eb-text{
  display:inline-block;
  padding:0 8px;              /* reprend le gap:8px d'origine */
}

/* Eyebrows de section ([ SÉLECTION ], [ À PROPOS ]…) : état armé,
   posé par le JS tant que la section n'est pas entrée dans le viewport.
   Le fallback 3.2em ne sert qu'avant la première mesure ; le JS écrit
   la valeur réelle dans --eb-shift. */
.eyebrow-unfold.eb-armed{opacity:0;}
.eyebrow-unfold.eb-armed .eb-open{transform:translateX(var(--eb-shift, 3.2em));}
.eyebrow-unfold.eb-armed .eb-close{transform:translateX(calc(-1 * var(--eb-shift, 3.2em)));}
.eyebrow-unfold.eb-armed .eb-text{
  clip-path:inset(0 50% 0 50%);
  opacity:0;
}

/* Balayage de calage : fine ligne lumineuse qui descend le cadre */
.vp-align-sweep{
  position:absolute;inset:0;z-index:1;
  border-radius:inherit;overflow:hidden;
  pointer-events:none;
  opacity:0;
}
.vp-align-sweep::after{
  content:'';
  position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg,
    transparent 0%,
    rgba(143,180,217,0.35) 12%,
    rgba(210,235,255,0.95) 50%,
    rgba(143,180,217,0.35) 88%,
    transparent 100%);
  box-shadow:0 0 14px 2px rgba(120,190,255,0.55);
  transform:translateY(-4px);
  will-change:transform;
}

/* Reflet chrome qui traverse le bouton primaire, une seule fois */
.btn-primary .intro-sheen{
  position:absolute;inset:0;z-index:4;
  border-radius:inherit;overflow:hidden;
  pointer-events:none;
  opacity:0;
}
.btn-primary .intro-sheen::after{
  content:'';
  position:absolute;top:-60%;left:0;
  width:38%;height:220%;
  background:linear-gradient(90deg,
    transparent,
    rgba(255,255,255,0.55) 45%,
    rgba(255,255,255,0.85) 50%,
    rgba(255,255,255,0.55) 55%,
    transparent);
  transform:translateX(-260%) rotate(16deg);
  will-change:transform;
}

/* Dégradé du titre : élargi pour laisser la place au balayage
   de l'étape 1500 ms. Position finale = 0% (état stable). */
.hero-intro .hero h1 em{
  background-size:200% 100%;
  background-position:0% 0;
}

/* Repli si la Web Animations API ne sait pas animer les
   pseudo-éléments : les états finaux sont forcés. */
.hero-intro.no-pseudo-anim .hero-stats::before{transform:scaleX(1);}
.hero-intro.no-pseudo-anim .viewport::before{opacity:1;}
.hero-intro.no-pseudo-anim .vp-align-sweep,
.hero-intro.no-pseudo-anim .btn-primary .intro-sheen{display:none;}

/* Chiffres de stats : tabular-nums pour que le comptage
   ne fasse pas danser la largeur pendant l'incrément. */
.stat b{font-variant-numeric:tabular-nums;}

/* ------------------------------------------------------------
   ÉTATS PERMANENTS — activés à la fin de la timeline (2400 ms)
   ------------------------------------------------------------ */

/* Clignotement du point REC : cycle 1,2 s, rendu "machine" */
.hero-intro-done .vp-hud-top .rec::before{
  animation:intro-rec-blink 1.2s steps(1, end) infinite !important;
}
@keyframes intro-rec-blink{
  0%,55%{opacity:1;}
  56%,100%{opacity:0.15;}
}

/* Clignotement lent du ► devant PLAYING */
.hero-intro-done .vp-hud-bottom .playing{
  animation:intro-playing-blink 2.4s steps(1, end) infinite !important;
}
@keyframes intro-playing-blink{
  0%,88%{opacity:1;}
  89%,94%{opacity:0.4;}
  95%,100%{opacity:1;}
}

/* ------------------------------------------------------------
   ACCESSIBILITÉ — prefers-reduced-motion
   Pas de timeline, pas de balayage, pas de clignotement,
   pas de comptage. État final immédiat + fondu global 200 ms.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion:reduce){
  .hero-intro .hero .eyebrow,
  .hero-intro .hero p.lead,
  .hero-intro .hero .cta-row > *,
  .hero-intro .hero .stat,
  .hero-intro .vp-hud-top > *,
  .hero-intro .vp-hud-bottom > *,
  .hero-intro .hero h1 .h1-line > span{
    opacity:1 !important;
    transform:none !important;
  }
  .hero-intro .vp-corner path{stroke-dashoffset:0 !important;}
  .hero-intro .eyebrow-unfold .eb-text{clip-path:none !important;opacity:1 !important;}
  .hero-intro .viewport{border-color:var(--steel-line) !important;}
  .hero-intro .viewport::before{opacity:1 !important;}
  .hero-intro .hero-stats::before{transform:scaleX(1) !important;}
  .hero-intro .vp-align-sweep,
  .hero-intro .btn-primary .intro-sheen{display:none !important;}

  .hero-intro-done .vp-hud-top .rec::before,
  .hero-intro-done .vp-hud-bottom .playing{animation:none !important;}

  /* fondu global unique */
  .hero-intro .hero{animation:intro-reduced-fade .2s linear both;}
  @keyframes intro-reduced-fade{from{opacity:0;}to{opacity:1;}}
}
