/* ===========================================================================
   regard. | couche de mouvement
   Le mouvement sert la lecture : il hiérarchise l'arrivée des éléments et
   souligne les changements d'état. Rien ne bouge en boucle, rien ne retarde
   l'accès à l'information, et tout se désactive si le système le demande.
   =========================================================================== */

:root{
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-io:cubic-bezier(.65,0,.35,1);
  --t-court:.35s;
  --t-moyen:.6s;
  --t-long:.9s;
}

/* --- Barre de progression de lecture ------------------------------------- */
.progress{
  position:fixed;top:0;left:0;height:2px;width:100%;z-index:70;
  transform:scaleX(var(--p,0));transform-origin:0 50%;
  background:var(--red);pointer-events:none;
  transition:transform .1s linear;
}
html:not(.js) .progress{display:none}

/* --- Header : se compacte des que la page defile -------------------------- */
.header{transition:border-color var(--t-court) var(--ease-out),
                   background var(--t-court) var(--ease-out),
                   box-shadow var(--t-court) var(--ease-out)}
.header__in{transition:height var(--t-court) var(--ease-out)}
.header .wordmark{transition:font-size var(--t-court) var(--ease-out)}
.js .header.is-stuck .header__in{height:60px}
.js .header.is-stuck .wordmark{font-size:1.45rem}
.js .header.is-stuck{box-shadow:0 1px 0 var(--line)}

/* --- Titres : ouverture par masque ---------------------------------------- */
.js .rv-title{
  clip-path:inset(0 0 105% 0);
  transform:translateY(.22em);
  transition:clip-path var(--t-long) var(--ease-out),transform var(--t-long) var(--ease-out);
}
.js .rv-title.in{clip-path:inset(0 0 -20% 0);transform:none}

/* --- Blocs : arrivee sobre, en cascade ------------------------------------ */
.js .rv{opacity:0;transform:translateY(22px);
  transition:opacity var(--t-moyen) var(--ease-out),transform var(--t-moyen) var(--ease-out)}
.js .rv.in{opacity:1;transform:none}

/* --- Images : le cadre s'ouvre, l'image se pose --------------------------- */
/* Le clip porte sur les ENFANTS, jamais sur le conteneur observé : un élément
   entièrement clippé a une aire d'intersection nulle, donc l'IntersectionObserver
   ne le révèle jamais — il resterait masqué pour toujours. */
.js .rv-media > *{clip-path:inset(0 0 100% 0);transition:clip-path 1.05s var(--ease-io)}
.js .rv-media.in > *{clip-path:inset(0 0 0 0)}
.js .rv-media img{transform:scale(1.08);transition:transform 1.4s var(--ease-out)}
.js .rv-media.in img{transform:none}
.js .pole__head{transform-origin:0 50%}

/* --- Chiffres et libelles en mono : legere montee ------------------------- */
.js .rv-up{opacity:0;transform:translateY(10px);
  transition:opacity var(--t-moyen) var(--ease-out),transform var(--t-moyen) var(--ease-out)}
.js .rv-up.in{opacity:1;transform:none}

/* --- Liens et cartes : reponse au survol ---------------------------------- */
.card,.polecard,.presta,.module,.way,.aud{transition:background var(--t-court) var(--ease-out),
                                                      transform var(--t-court) var(--ease-out)}
@media (hover:hover){
  a.card:hover,.polecard:hover,.way:hover{transform:translateY(-2px)}
}
.btn{transition:background var(--t-court) var(--ease-out),
                border-color var(--t-court) var(--ease-out),
                transform .12s var(--ease-out),
                box-shadow var(--t-court) var(--ease-out)}
@media (hover:hover){
  .btn:hover{box-shadow:0 6px 18px rgba(232,0,29,.22)}
  .btn--ghost:hover{box-shadow:0 6px 18px rgba(10,10,10,.14)}
}

/* --- Transition entre les pages ------------------------------------------- */
@view-transition{navigation:auto}
::view-transition-old(root){animation:sortie .28s var(--ease-io) both}
::view-transition-new(root){animation:entree .42s var(--ease-out) both}
@keyframes sortie{to{opacity:0;transform:translateY(-8px)}}
@keyframes entree{from{opacity:0;transform:translateY(10px)}}

/* --- Respect du reglage systeme ------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .js .rv,.js .rv-title,.js .rv-media,.js .rv-rule,.js .rv-up{
    opacity:1;transform:none;clip-path:none;transition:none;
  }
  .js .rv-media > *{clip-path:none;transition:none}
  .js .rv-media img{transform:none;transition:none}
  .progress{display:none}
  .js .header.is-stuck .header__in{height:72px}
  .js .header.is-stuck .wordmark{font-size:1.7rem}
  @view-transition{navigation:none}
}

/* ===========================================================================
   Grille éditoriale
   Les sections s'ouvrent sur un filet, le titre occupe la colonne de gauche
   et le chapeau se décale sur la colonne suivante. Le regard descend en
   diagonale au lieu de tomber à la verticale.
   =========================================================================== */

.sect > .wrap,
.pagehead > .wrap{position:relative}

/* Filet d'ouverture de section */
.sect{position:relative}
.sect::before{
  content:"";position:absolute;left:var(--gut);right:var(--gut);top:0;height:1px;
  background:var(--line);
}
.sect--tight::before,.hero::before,.pagehead::before,.ctaband::before,
.statement::before,.strip::before,.pledge::before{display:none}
.sect + .sect::before{background:var(--line)}

/* Chapeaux et titres partagent le même bord gauche */
@media (min-width:1000px){
  /* Le chapeau était décalé de 10 % : il était alors le seul élément d'une
     section à ne pas partager le bord gauche du titre, de la grille et des
     boutons. On ne garde que la limite de largeur, qui sert la lisibilité. */
  .sect .wrap > .lead,
  .sect .wrap > p.lead{max-width:56ch}
  .pagehead .wrap > .lead{max-width:56ch}
  .h2{max-width:17ch}
}

/* Repère de section : un trait court avant le titre, tracé à l'arrivée */
@media (min-width:1000px){
  .sect .wrap > .h2::before,
  .pagehead .wrap > .h1::before{
    content:"";display:block;width:56px;height:3px;background:var(--red);
    margin-bottom:1.6rem;transform-origin:0 50%;
  }
  .js .sect .wrap > .h2::before,
  .js .pagehead .wrap > .h1::before{transform:scaleX(0);transition:transform .7s var(--ease-io) .15s}
  .js .sect .wrap > .h2.in::before,
  .js .pagehead .wrap > .h1.in::before{transform:scaleX(1)}
}
@media (prefers-reduced-motion:reduce){
  .js .sect .wrap > .h2::before,
  .js .pagehead .wrap > .h1::before{transform:none;transition:none}
}

/* ===========================================================================
   Motion design
   Chorégraphie d'arrivée des titres, chiffres qui se comptent, images qui
   respirent au défilement, traits qui se dessinent. Tout est gouverné par
   une seule règle : servir la lecture, jamais la retarder.
   =========================================================================== */

/* --- Titres révélés mot à mot -------------------------------------------- */
.js .wd{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.06em;margin-bottom:-.06em}
.js .wd__i{
  display:inline-block;transform:translateY(105%);
  transition:transform .85s var(--ease-out);
  transition-delay:calc(min(var(--i,0), 12) * 55ms);
}
.js .in .wd__i,.js .wd.in .wd__i{transform:none}
/* Le découpage remplace le masque global : plus de clip-path sur ces titres. */
.js .rv-title.is-split{clip-path:none;transform:none;transition:none}

/* --- Images : respiration au défilement ---------------------------------- */
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .parallax img{
      animation:derive linear both;
      animation-timeline:view();
      animation-range:entry 0% exit 100%;
      will-change:transform;
    }
    @keyframes derive{
      from{transform:translateY(-2.5%) scale(1.06)}
      to{transform:translateY(2.5%) scale(1.06)}
    }
  }
}

/* --- Traits qui se dessinent le long d'une frise -------------------------- */
.steps{position:relative}
@media (min-width:760px){
  .js .steps::before{
    content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--red);
    transform:scaleX(0);transform-origin:0 50%;
    transition:transform 1.1s var(--ease-io);
  }
  .js .steps.in::before{transform:scaleX(1)}
  .js .step{border-top-color:transparent}
}

/* --- Boutons : réponse magnétique ---------------------------------------- */
.js .btn{will-change:transform}
.js .btn.magnet{transform:translate(var(--mx,0),var(--my,0))}

/* --- Séquence d'entrée du hero ------------------------------------------- */
.js .home-hero .eyebrow,.js .pro-hero .badge,.js .pagehead .eyebrow{
  opacity:0;transform:translateY(12px);
  animation:monte .7s var(--ease-out) .1s forwards;
}
.js .home-hero__lead,.js .pro-hero__intro,.js .pagehead .lead{
  opacity:0;transform:translateY(14px);
  animation:monte .8s var(--ease-out) .5s forwards;
}
.js .home-hero__cta,.js .pro-hero .btn{
  opacity:0;transform:translateY(14px);
  animation:monte .8s var(--ease-out) .68s forwards;
}
@keyframes monte{to{opacity:1;transform:none}}

/* Le point du wordmark se pose après le mot */
.js .header .wordmark .dot{
  display:inline-block;transform:scale(0);
  animation:pose .5s var(--ease-out) .35s forwards;
}
@keyframes pose{60%{transform:scale(1.25)}to{transform:scale(1)}}

@media (prefers-reduced-motion:reduce){
  .js .wd__i{transform:none;transition:none}
  .js .home-hero .eyebrow,.js .pro-hero .badge,.js .pagehead .eyebrow,
  .js .home-hero__lead,.js .pro-hero__intro,.js .pagehead .lead,
  .js .home-hero__cta,.js .pro-hero .btn,
  .js .header .wordmark .dot{opacity:1;transform:none;animation:none}
  .js .steps::before{transform:scaleX(1);transition:none}
  .js .btn.magnet{transform:none}
}

/* --- Page agence : les lignes de pôles arrivent l'une après l'autre ------- */
.js .plist__i{transition-delay:calc(var(--i,0) * 85ms)}
.js .principe{transition-delay:calc(var(--i,0) * 90ms)}
.js .refs > li{transition-delay:calc(min(var(--i,0), 5) * 80ms)}

@media (prefers-reduced-motion:reduce){
  .js .plist__i,.js .principe,.js .refs > li{transition-delay:0s}
}
