/* =========================================================================
   Sitero — effets-scroll.css
   LES SECTIONS RÉAGISSENT AU DÉFILEMENT : ENTRÉE, PRÉSENCE, SORTIE

   Ce fichier va avec assets/js/effets-scroll.js. Il ne réécrit AUCUNE règle
   des feuilles existantes : tout ce qui est inventé ici commence par
   « sio- » ou passe par l'attribut « data-sio », que le script pose
   lui-même. Il n'y a donc rien à ajouter à la main dans le HTML.

   ─────────────────────────────────────────────────────────────────────
   LA RÈGLE QUI COMMANDE TOUT LE FICHIER
   Une animation ne doit JAMAIS être la seule chose qui rend un contenu
   visible. Aucune règle ici ne met un contenu à « opacity:0 » tant que la
   balise <html> ne porte pas la classe « sio-on », et cette classe n'est
   posée que par le script, une fois toutes ses vérifications faites. Sans
   JavaScript, avec un JavaScript en panne, ou avec « mouvement réduit »,
   la page est exactement la page d'aujourd'hui.
   Le seul état où l'opacité descend est l'état « haut », c'est-à-dire un
   bloc DÉJÀ sorti par le haut de l'écran — et le script le surveille.
   ─────────────────────────────────────────────────────────────────────

   CE QU'ON TROUVE ICI, DANS L'ORDRE
     1. le souffle des blocs : ils arrivent posés, ils s'éloignent en sortant
     2. les surfaces sombres qui s'arrondissent en entrant
     3. la deuxième ligne des grands titres, qui se pose après la première
     4. la dérive des deux mots géants (CSS pur, sans une ligne de script)
     5. les interrupteurs d'urgence, le mouvement réduit et l'impression

   TROIS RÈGLES TENUES PARTOUT
     A. On n'anime que « transform » et « opacity » — les deux seules
        propriétés que la carte graphique sait composer toute seule. Seule
        exception assumée : « border-radius » au point 2, qui ne bouge
        qu'une fois par entrée de section et jamais pendant le défilement.
     B. Aucun flou, aucun backdrop-filter, aucun filtre, aucun
        « content-visibility », aucun « contain » : chacun a déjà fait
        ramer ce site.
     C. Aucun « will-change ». translate3d suffit à obtenir une couche
        graphique dédiée sans réserver de la mémoire en permanence.

   VOCABULAIRE DES COURBES — le même que le reste du site
     --e-out : cubic-bezier(.16,1,.3,1). Ça part vite et ça se pose
     doucement. Une seule famille, jamais de rebond.
   ========================================================================= */


/* =========================================================================
   1. LE SOUFFLE DES BLOCS
   -------------------------------------------------------------------------
   Chaque « bloc » est un conteneur qui existe DÉJÀ dans le site : l'en-tête
   d'une section, une grille de cartes, le pied de page… Le script lui donne
   la classe « sio-b » et lui écrit, dans l'attribut « data-sio », où il en
   est par rapport à l'écran :

     bas   il n'est pas encore arrivé — posé 14 px plus bas, à peine réduit
     ici   il est là — à sa place exacte, taille réelle
     haut  il est sorti par le haut — il s'éloigne et se retire

   Les CARTES à l'intérieur gardent leur propre apparition (la classe
   « reveal » de style.css). Ce fichier ne touche qu'au CONTENEUR : c'est ce
   deuxième étage qui donne la sensation d'un groupe qui se pose, puis d'un
   groupe qui s'éloigne — et non d'une suite d'éléments qui clignotent.

   ⚠ Pourquoi l'état « bas » ne touche PAS à l'opacité : si tout se
     bloquait à cet instant, le contenu serait simplement 14 px trop bas.
     Jamais invisible.
   ========================================================================= */
html.sio-on .sio-b{
  transition:transform .85s var(--e-out,cubic-bezier(.16,1,.3,1)),
             opacity .85s var(--e-out,cubic-bezier(.16,1,.3,1));
}
html.sio-on .sio-b[data-sio="bas"]{
  transform:translate3d(0,14px,0) scale(.988);
}
html.sio-on .sio-b[data-sio="ici"]{
  transform:none;
  opacity:1;
}
html.sio-on .sio-b[data-sio="haut"]{
  transform:translate3d(0,-10px,0) scale(.965);
  opacity:.55;
}

/* LA RÈGLE DU CLAVIER — un bloc dans lequel on est en train d'écrire ou de
   tabuler ne bouge pas et ne pâlit pas, quoi qu'il arrive. Cela concerne
   surtout le formulaire de la page Contact : si le visiteur remplit un
   champ pendant que la page glisse, le champ doit rester net. */
html.sio-on .sio-b:focus-within{
  transform:none!important;
  opacity:1!important;
}


/* =========================================================================
   2. LES SURFACES SOMBRES QUI S'ARRONDISSENT
   -------------------------------------------------------------------------
   La section noire de l'atelier et l'écran de Toulouse arrivent avec des
   angles arrondis, comme une plaque posée sur la page, et redeviennent
   carrées en sortant. C'est le geste le plus reconnaissable des pages
   d'Apple : le fond de la page reste blanc, la matière sombre est un objet
   POSÉ dessus, pas un trou dans la page.

   ⚠ « border-radius » n'est pas une propriété composée par la carte
     graphique : le navigateur redessine les quatre coins pendant la
     transition. C'est admis ICI et nulle part ailleurs, parce que cela ne
     se produit qu'une fois par entrée de section (moins d'une seconde) et
     jamais image par image pendant le défilement.
     Les deux sections concernées portent déjà « overflow:hidden » dans
     style.css et toulouse.css : la vidéo et les photos de fond sont donc
     coupées proprement par l'arrondi, sans rien ajouter.
     Si le rendu devait gratter sur une vieille machine, il y a un
     interrupteur : voir ARRONDI en tête de effets-scroll.js.
   ========================================================================= */
html.sio-on .sio-r{
  transition:border-radius .9s var(--e-out,cubic-bezier(.16,1,.3,1));
}
html.sio-on .sio-r[data-sio="ici"]{
  border-radius:clamp(16px,2.4vw,34px);
}


/* =========================================================================
   3. LES GRANDS TITRES : LA SECONDE LIGNE SE POSE APRÈS LA PREMIÈRE
   -------------------------------------------------------------------------
   Presque tous les grands titres du site sont écrits en deux temps :
   une affirmation, puis une seconde ligne en gris (la balise
   <span class="dim">). Elle arrive maintenant un sixième de seconde après
   la première, en montant de très peu. On lit vraiment le titre en deux
   temps, comme il a été écrit.

   Aucun découpage du texte, aucune balise ajoutée par un script : c'est le
   HTML existant qui porte déjà la séparation.

   ⚠ TROIS VERROUS, parce que c'est le seul endroit du fichier où du TEXTE
     peut être masqué :
     - « html.js-ok » : main.js ne pose cette classe qu'une fois ses
       apparitions réellement installées. Sur les pages qui ne chargent pas
       main.js (mentions légales, confidentialité), rien ne se passe.
     - « .h2.vu » : c'est main.js qui pose « vu ». Son propre filet de
       sécurité le pose de force au bout de quelques secondes si besoin ;
       la seconde ligne suit donc toujours.
     - les trois règles de secours ci-dessous remettent tout en place.
   ========================================================================= */
html.sio-on.js-ok .h2 .dim{
  /* « transform » ne s'applique pas à une balise en ligne : il faut un
     inline-block. Tous les .dim du site suivent un <br>, ils sont donc
     déjà seuls sur leur ligne — la coupure des mots ne change pas. */
  display:inline-block;
  opacity:0;
  transform:translate3d(0,.32em,0);
  transition:opacity .6s var(--e-out,cubic-bezier(.16,1,.3,1)) .16s,
             transform .75s var(--e-out,cubic-bezier(.16,1,.3,1)) .16s;
}
html.sio-on.js-ok .h2.vu .dim{
  opacity:1;
  transform:none;
}

/* Les secours : dès qu'un des mécanismes du site déclare forfait, la
   seconde ligne redevient visible immédiatement et pour de bon. */
html.sio-dim-off .h2 .dim,
html.reveals-off .h2 .dim,
html.js-off .h2 .dim,
html.sio-off .h2 .dim{
  opacity:1!important;
  transform:none!important;
}


/* =========================================================================
   4. LA DÉRIVE DES DEUX MOTS GÉANTS — SANS UNE LIGNE DE JAVASCRIPT
   -------------------------------------------------------------------------
   « Sitero » et « Toulouse » remontent un peu moins vite que la page
   pendant qu'on les traverse. C'est le seul mouvement CONTINU ajouté par
   ce fichier, et il ne coûte rien du tout : il est écrit en CSS avec une
   « animation liée au défilement » (animation-timeline), que le navigateur
   joue sur sa couche de composition, sans jamais réveiller le JavaScript.
   Le site a déjà deux boucles d'animation à l'image (anim-sections.js et
   scroll2.js) : il n'en aura pas de troisième.

   Trois raisons pour lesquelles c'est sans danger :
     - le @supports : les navigateurs qui ne connaissent pas encore cette
       technique (Firefox aujourd'hui) ignorent tout le bloc. Le mot ne
       bouge pas, et c'est tout.
     - on ne touche qu'à « transform ». Le remplissage de couleur des deux
       mots, lui, passe par la variable --p : ce sont deux propriétaires
       différents sur deux propriétés différentes, ils ne se croisent pas.
     - le mouvement reste dans les marges hautes et basses des deux
       sections, qui portent toutes les deux « overflow:hidden ».
   ========================================================================= */
@keyframes sio-derive{
  from{transform:translate3d(0,22px,0)}
  to  {transform:translate3d(0,-22px,0)}
}
@keyframes sio-derive-large{
  from{transform:translate3d(0,30px,0)}
  to  {transform:translate3d(0,-30px,0)}
}

@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .mot__in{
      animation:sio-derive linear both;
      animation-timeline:view();
      animation-range:entry 0% exit 100%;
    }
    .tls__mot{
      animation:sio-derive-large linear both;
      animation-timeline:view();
      animation-range:entry 0% exit 100%;
    }
  }
}


/* =========================================================================
   5. LES INTERRUPTEURS D'URGENCE, LE MOUVEMENT RÉDUIT, L'IMPRESSION
   -------------------------------------------------------------------------
   « sio-off » est posé par le script dès que quelque chose ne va pas. Il
   n'a besoin ni de GSAP ni de l'observateur : il éteint tout, tout de
   suite. C'est la deuxième corde à l'arc, indépendante du script qui remet
   aussi les styles à zéro élément par élément.
   ========================================================================= */
html.sio-off .sio-b,
html.sio-off .sio-b[data-sio],
html.sio-off .sio-r,
html.sio-off .sio-r[data-sio]{
  transform:none!important;
  opacity:1!important;
  border-radius:0!important;
  transition:none!important;
}

@media (prefers-reduced-motion:reduce){
  html .sio-b,html .sio-b[data-sio]{
    transform:none!important;opacity:1!important;transition:none!important;
  }
  html .sio-r,html .sio-r[data-sio]{
    border-radius:0!important;transition:none!important;
  }
  html .h2 .dim{opacity:1!important;transform:none!important}
  .mot__in,.tls__mot{animation:none!important;transform:none!important}
}

@media print{
  html .sio-b,html .sio-b[data-sio]{transform:none!important;opacity:1!important}
  html .sio-r,html .sio-r[data-sio]{border-radius:0!important}
  html .h2 .dim{opacity:1!important;transform:none!important}
  .mot__in,.tls__mot{animation:none!important;transform:none!important}
}


/* =========================================================================
   6. CE QU'ON NE TROUVERA PAS ICI, ET POURQUOI
   -------------------------------------------------------------------------
   - Aucune règle sur .reveal, .h2, .ph, .bc, .pbc, .exc, .opt, .pel,
     .apc, .goc, .ab-num, .op, .st : leur transformation appartient déjà à
     style.css (classe « vu ») ou à anim-sections.js. Un seul propriétaire
     par propriété — c'est la règle qui a déjà coûté un logo qui saute.
   - Aucune règle sur .pb__vid, .pb__cards, .ben__ph, .hero .shead,
     .mock__frame, .wmx__box, .exc__pg, .sc2__pl : ce sont les éléments que
     anim-sections.js et scroll2.js déplacent en continu. Le script de ce
     fichier refuse d'ailleurs de toucher un conteneur qui en abrite un,
     parce qu'une transformation posée sur le parent fausserait les mesures
     de la parallaxe.
   - Aucun overflow-x sur <html> : cela casse « position:sticky » sur
     certains navigateurs, et le portrait de la page Contact en dépend.
   ========================================================================= */
