/* ============================================================
   07 · MOUVEMENT · direction « L'AFFICHE »

   Pourquoi ce fichier existe. La page tient deja sa mise en
   page ; ce qui lui manque, c'est le temps. Une affiche
   serigraphiee n'est pas imprimee d'un coup : elle est posee
   plaque par plaque, une encre apres l'autre. C'est la seule
   metaphore de mouvement autorisee ici, et elle suffit a tout
   couvrir : un aplat se racle, un bloc arrive, une serie se pose
   dans l'ordre.

   Ce que ce fichier n'ajoute PAS, et c'est delibere : pas de
   parallaxe, pas de zoom au defilement, pas de compteur anime,
   pas d'apparition lettre par lettre. Ce qui fait marque
   internationale, ce n'est pas le nombre de gestes, c'est que
   le meme geste se retrouve partout, a la meme vitesse, avec la
   meme sortie.

   ------------------------------------------------------------
   CE QUI A CHANGE, ET SUR QUELLE MESURE

   Le client disait « il n'y a pas d'animations ». Au sens
   litteral c'etait faux : le systeme tournait, il ne coutait
   rien. Mesure faite avant de toucher a quoi que ce soit, sur
   huit pages de la preprod :

     accueil        23 elements marques
     rayon           8 elements marques, course 0 px
     savoir-faire    7 elements marques
     engagements     0
     faq             0
     contact         0
     espace pro      0
     CGV             0

   Cinq pages sur huit n'avaient aucun geste, et la course de
   celles qui en avaient un valait 14 px etales sur 620 ms en
   sortie exponentielle : passe la 150e milliseconde, le
   deplacement restant tient sous le pixel. Ce n'etait pas un
   mouvement discret, c'etait un mouvement invisible.

   Trois corrections, dans l'ordre de leur effet :

   1. La course passe de 14 px a 26 px, soit exactement une
      rangee de la grille de base du site. Le bloc arrive de la
      ligne d'en dessous, il ne « monte » pas de nulle part.
   2. L'aplat pleine largeur recoit son propre geste, la racle.
      C'est lui qui porte le mouvement sur les pages de contenu,
      qui n'ont ni serie ni en-tete de pan a animer.
   3. Le survol et l'appui prennent le meme vocabulaire que la
      carte produit : le decalage d'impression. Sur une boutique,
      c'est la que le mouvement se remarque.
   ------------------------------------------------------------

   Quatre regles tenues sans exception.

   1. Transform et opacity uniquement. Jamais une propriete de
      mise en page. Animer une largeur ou une marge force le
      navigateur a recalculer la page a chaque image ; le
      defilement passe alors sous 60 i/s sur les grilles longues
      comme le rayon a douze produits.

   2. Sortie en exponentielle, jamais de rebond. On reutilise
      --wrj-ease, deja pose dans 01-tokens : cubic-bezier(0.16,
      1, 0.3, 1). C'est une decelaration forte qui s'arrete net,
      exactement le comportement d'une racle de serigraphie. Un
      rebond ferait flotter l'affiche, or rien ne flotte ici.
      Seule la racle prend --wrj-ease-cut, et la raison est dans
      sa section.

   3. L'etat par defaut est l'etat lisible. Aucun selecteur de
      ce fichier ne s'applique tant que mouvement.js n'a pas
      pose lui-meme l'attribut data-wrj-vu. Sans JavaScript, ou
      si le script echoue avant sa fin, la page reste entiere :
      il n'y a rien a « reveler », donc rien a perdre.

   4. « reduce » neutralise, il ne raccourcit pas. Voir la
      derniere section du fichier.
   ============================================================ */

:root {
  /* Duree d'entree. Plus long que --wrj-d-etat (220ms) parce
     qu'il ne s'agit pas d'un changement d'etat mais d'une
     arrivee : sous 500ms l'oeil lit une apparition brutale,
     au-dela de 700ms il attend. */
  --wrj-d-entree: 620ms;

  /* Duree de la racle. Plus longue que l'entree parce que le
     geste traverse toute la largeur de la fenetre et non 16 px :
     a duree egale, la racle filerait dix fois plus vite que tout
     le reste du site.

     Elle valait 720ms en --wrj-ease-cut. Deux corrections apres
     retour : la duree monte a 880ms, et surtout la courbe passe
     en sortie exponentielle. Une courbe en S accelere au milieu
     du parcours ; sur 1440 px de large, ce milieu rapide est
     exactement ce qui se lit comme un coup de fouet. Une sortie
     exponentielle part vite et se pose : meme distance, meme
     energie au depart, mais elle finit en se calmant au lieu de
     s'arreter net. */
  --wrj-d-racle: 880ms;

  /* Course de l'entree. Elle valait 14 px, sous le seuil de
     perception ; portee a 26 px, une rangee de la grille de
     base, elle est passee au-dessus mais trop haut : signalee
     comme trop violente. 16 px est la valeur retenue, entre les
     deux et plus pres du seuil que du plafond. Le geste se voit
     sans se faire remarquer, ce qui est le contrat du fichier.

     A retenir de l'aller-retour : le vrai defaut n'etait pas
     l'amplitude, c'etait la couverture. Cinq pages sur huit
     n'avaient aucun geste. Une fois la couverture reparee,
     l'amplitude peut redescendre. */
  --wrj-rev-y: 16px;

  /* Retard entre deux elements d'une meme serie. Pose en ligne
     par le script sous le nom --wrj-rev-d ; ces deux valeurs
     sont les pas de reference. A 55 et 70ms, quatre cartes d'une
     rangee arrivaient dans un intervalle de 165ms, soit dix
     images, ce que l'oeil lit comme une arrivee simultanee et
     non comme une sequence. A 70 et 90 la sequence se lisait,
     mais la derniere carte d'une rangee de quatre attendait
     270ms. 60 et 75 tiennent les deux bouts. */
  --wrj-rev-pas: 60ms;
  --wrj-rev-pas-large: 75ms;

  /* Decalage d'impression au survol. Une seule valeur pour tout
     ce qui est cliquable et petit ; la carte produit garde la
     sienne, plus grande, dans 05-boutique. */
  --wrj-rev-appui: 2px;
}

/* ------------------------------------------------------------
   LE MECANISME

   Un seul couple d'etats pour tout le site.

   data-wrj-vu="non" est l'etat de depart, pose par le script et
   par lui seul. Il n'existe jamais dans le HTML servi : c'est
   ce qui garantit qu'une page sans JavaScript n'a rien de
   masque. Le script ne le pose d'ailleurs que sur ce qui se
   trouve SOUS la ligne de flottaison au premier rendu, si bien
   qu'aucun masquage n'est jamais visible a l'ecran, et que le
   plus grand element affiche (le LCP) n'est jamais retarde.

   data-wrj-vu="oui" ne porte volontairement aucune declaration.
   Quand l'attribut bascule, la regle "non" cesse simplement de
   s'appliquer et chaque propriete revient a la valeur que le
   composant definit lui-meme. C'est ce qui permet a la carte
   produit de retrouver intact son transform de survol, au lieu
   de se le faire ecraser par un `transform: none` venu d'ici.

   --wrj-rev-d porte le retard de sequence. Il est pose en ligne
   par le script plutot qu'ecrit en regles :nth-child, parce que
   le retard depend de la position dans la RANGEE et non dans la
   liste : sur une grille de douze produits, un :nth-child
   ferait attendre la douzieme carte douze crans alors qu'elle
   n'est que la quatrieme de sa rangee.
   ------------------------------------------------------------ */
.wrj-js [data-wrj-vu="non"] {
  opacity: 0;
  transform: translate3d(0, var(--wrj-rev-y), 0);
}

.wrj-js [data-wrj-vu] {
  transition:
    opacity   var(--wrj-d-entree) var(--wrj-ease) var(--wrj-rev-d, 0ms),
    transform var(--wrj-d-entree) var(--wrj-ease) var(--wrj-rev-d, 0ms);
}

/* Pas de will-change ici. Il reserve une couche memoire par
   element ; sur un rayon de douze cartes plus les en-tetes, le
   cout depasse le gain. Opacity et transform sont deja traites
   par le compositeur sans qu'on ait a le demander. */

/* ------------------------------------------------------------
   Tempo 1 · LE BLOC QUI ARRIVE.
   L'en-tete d'un pan porte le label, le titre et le chapo :
   c'est lui qui annonce ce qu'on va lire. Le faire arriver
   avant son contenu, c'est donner a voir la hierarchie plutot
   que de la decrire. Un seul mouvement pour le groupe entier,
   jamais un par ligne de texte.
   ------------------------------------------------------------ */

/* (aucune regle propre : le bloc prend les valeurs de base) */

/* ------------------------------------------------------------
   Tempo 2 · LA SERIE QUI SE POSE.

   Les six disciplines sont le seul endroit du site ou les six
   encres se croisent. C'est l'element de marque. Elles se
   posent donc de gauche a droite, une plaque apres l'autre,
   avec le pas le plus large du site : c'est le seul moment ou
   la sequence doit se LIRE comme une sequence.

   La course y reste plus courte qu'ailleurs : les pans sont
   cote a cote, c'est le balayage horizontal qui porte le geste,
   pas la montee de chaque pan. Elle passe tout de meme de 10 a
   18 px, pour la meme raison que la course generale.
   ------------------------------------------------------------ */
.wrj-js .wrj-famille[data-wrj-vu="non"] { --wrj-rev-y: 12px; }

/* ------------------------------------------------------------
   Tempo 3 · L'APLAT QUI SE RACLE.

   Le geste demande par la direction « Les univers », et le seul
   geste du site sur les pages de contenu : elles n'ont ni serie
   ni en-tete de pan a animer, seulement de la prose, qu'on
   n'anime pas. Ce qu'elles ont, ce sont les aplats.

   La metaphore est litterale. Avant le passage de la racle, le
   papier est nu ; la racle passe de gauche a droite et l'encre
   apparait derriere elle, avec ce qui est imprime dessus. On ne
   deplace donc pas l'aplat, on RETIRE le papier qui le couvre :

     - le fond de l'aplat n'est jamais touche, il reste celui que
       02-composants lui donne. Sans JavaScript, sans cette
       feuille, ou si le script echoue, l'aplat est simplement
       imprime, ce qui est l'etat normal de la page ;
     - le voile est un pseudo-element, il n'existe donc dans
       aucun gabarit et ne peut rien couter a un aplat qui n'est
       pas anime ;
     - il est en transform pur, scaleX de 1 a 0. Le compositeur
       le traite seul, sans un seul recalcul de mise en page.

   Origine a droite : le voile se retracte VERS la droite, donc
   l'encre se decouvre de la gauche vers la droite. C'est le sens
   de lecture, et le sens d'un passage de racle sur un ecran.

   La courbe est --wrj-ease-cut, et c'est la seule exception du
   fichier. Une racle n'est pas une arrivee : elle demarre, elle
   traverse, elle s'arrete. Une sortie exponentielle lui donnerait
   une vitesse maximale au premier centimetre puis une longue
   derive, ce qui se lit comme un fondu rate. --wrj-ease-cut est
   deja dans 01-tokens sous ce nom exact, et ne rebondit pas
   davantage que --wrj-ease.

   Un aplat marque NE PREND PAS l'entree generale : il ne monte
   pas et ne se fond pas, sinon deux gestes se superposeraient sur
   le meme bloc. Le script, de son cote, ne marque aucun element
   contenu dans un aplat marque : un aplat, un geste.

   Portee. Tout ce qui porte .wrj-drench herite du geste sans
   rien avoir a declarer, y compris les aplats d'univers ajoutes
   sur les pages de contenu. Pour un aplat qui ne serait pas un
   .wrj-drench, l'attribut [data-wrj-aplat] suffit a l'inscrire.
   ------------------------------------------------------------ */

/* Le voile est absolu, il lui faut un bloc conteneur. La regle
   est en specificite zero, volontairement : n'importe quelle
   autre feuille reprend la main sur `position` sans avoir a
   surencherir, et la valeur ne depend pas de la presence de
   l'attribut, donc rien ne bouge quand le script l'efface. */
:where(.wrj-js) :where(.wrj-drench, .wrj-respiration, [data-wrj-aplat]) {
  position: relative;
}

.wrj-js .wrj-drench[data-wrj-vu],
.wrj-js .wrj-respiration[data-wrj-vu],
.wrj-js [data-wrj-aplat][data-wrj-vu] {
  opacity: 1;
  transform: none;
}

.wrj-js .wrj-drench[data-wrj-vu]::after,
.wrj-js .wrj-respiration[data-wrj-vu]::after,
.wrj-js [data-wrj-aplat][data-wrj-vu]::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Au-dessus du contenu de l'aplat : la racle decouvre l'encre
     ET ce qui est imprime dessus, d'un seul geste. z-index 3
     passe devant les badges et les cartes survolees, qui montent
     a 1, et reste tres loin sous l'en-tete collant, a 100. */
  z-index: 3;
  background: var(--wrj-papier);
  transform: scaleX(1);
  transform-origin: 100% 50%;
  /* Sortie exponentielle, et non plus la courbe en S : voir la
     note sur --wrj-d-racle. Le milieu rapide d'une courbe en S
     est ce qui faisait lire le geste comme un coup de fouet. */
  transition: transform var(--wrj-d-racle) var(--wrj-ease) var(--wrj-rev-d, 0ms);
  pointer-events: none;
}

.wrj-js .wrj-drench[data-wrj-vu="oui"]::after,
.wrj-js .wrj-respiration[data-wrj-vu="oui"]::after,
.wrj-js [data-wrj-aplat][data-wrj-vu="oui"]::after {
  transform: scaleX(0);
}

/* ------------------------------------------------------------
   LA CARTE PRODUIT

   Elle n'avait aucune course : seule son opacite bougeait, pour
   eviter que le transform d'entree ne se dispute avec le
   decalage d'impression de son survol, de meme specificite dans
   05-boutique. Resultat mesure : sur le rayon, huit cartes
   marquees et zero pixel de mouvement. La seule page marchande
   du site n'avait donc, litteralement, aucune animation.

   La regle d'entree porte l'attribut, elle vaut (0,3,0) contre
   (0,2,0) pour `.wrj-produit:hover` : elle gagne pendant qu'elle
   s'applique, et elle ne s'applique que tant que la carte est
   masquee, c'est-a-dire tant qu'elle est hors de l'ecran et donc
   hors de portee du pointeur. Des que l'attribut passe a "oui",
   plus aucune declaration ne vient d'ici et le survol retrouve
   son transform intact.

   Reste un cas : le pointeur pose sur une carte pendant la
   fenetre de revelation. Sans precaution, son decalage
   d'impression s'etirerait sur 620ms au lieu de 120ms. La regle
   de survol ci-dessous rend sa duree a la carte des que le
   pointeur la touche.
   ------------------------------------------------------------ */
.wrj-js .wrj-produit[data-wrj-vu] {
  transition:
    opacity   var(--wrj-d-entree) var(--wrj-ease) var(--wrj-rev-d, 0ms),
    transform var(--wrj-d-entree) var(--wrj-ease) var(--wrj-rev-d, 0ms);
}

.wrj-js .wrj-produit[data-wrj-vu]:hover {
  transition:
    opacity   var(--wrj-d-entree) var(--wrj-ease) var(--wrj-rev-d, 0ms),
    transform var(--wrj-d-tap) var(--wrj-ease);
}

/* ------------------------------------------------------------
   LE POIDS DU GESTE · survol et appui

   C'est la moitie du probleme. Une entree ne se joue qu'une
   fois par element et par visite ; le survol et l'appui se
   rejouent a chaque intention. Sur une boutique, c'est la que
   le mouvement se remarque, et c'est la qu'il manquait : le
   bouton, la carte de contenu et la pastille de pointure
   changeaient de couleur et rien d'autre.

   Un seul vocabulaire, celui qui existait deja sur la carte
   produit : le DECALAGE D'IMPRESSION. Au survol l'element se
   decale vers le haut a gauche, comme une plaque posee un
   dixieme de millimetre a cote ; a l'appui il revient et se fait
   tamponner. Aucune elevation, aucune ombre portee, aucun flou :
   rien ne flotte sur ce site.

   Les regles de survol sont sous `hover: hover` et
   `pointer: fine`. Sur telephone, un survol simule reste colle
   apres le doigt : la carte resterait decalee jusqu'au prochain
   toucher ailleurs. L'appui, lui, vaut partout : sans survol,
   c'est le SEUL retour que l'interface puisse donner au doigt.
   ------------------------------------------------------------ */
@media (hover: hover) and (pointer: fine) {
  .wrj-btn:hover { transform: translate(calc(-1 * var(--wrj-rev-appui)), calc(-1 * var(--wrj-rev-appui))); }
  .wrj-pointure:hover { transform: translate(calc(-1 * var(--wrj-rev-appui)), calc(-1 * var(--wrj-rev-appui))); }

  /* La carte de contenu ne se decale que si elle mene quelque
     part. Une carte sans lien n'est pas cliquable : lui donner
     un retour de survol serait un mensonge d'interface. */
  .wrj-carte:has(.wrj-carte__lien):hover { transform: translate(-3px, -3px); }
}

/* .wrj-carte ne fait transiter aucune propriete dans 04-sections :
   il faut lui donner la sienne. Elle ne remplace donc rien. */
.wrj-carte { transition: transform var(--wrj-d-etat) var(--wrj-ease); }

/* .wrj-famille ne fait transiter que flex-grow. On REPREND cette
   declaration a l'identique avant d'y ajouter le transform : la
   propriete `transition` est une propriete raccourcie, la
   redeclarer sans flex-grow ramenerait l'ouverture du pan de
   420ms a la valeur par defaut et casserait l'effet d'accordeon
   de 04-sections. */
.wrj-famille {
  transition:
    flex-grow var(--wrj-d-panneau) var(--wrj-ease),
    transform var(--wrj-d-tap) var(--wrj-ease);
}

/* L'appui vient APRES le survol dans le fichier, et c'est
   necessaire : `:hover` et `:active` ont la meme specificite,
   (0,2,0). A egalite, c'est l'ordre qui tranche. Ecrites avant,
   ces regles ne se verraient jamais, puisqu'on appuie toujours
   sur ce qu'on survole.
   `.wrj-btn:active` existe deja dans 03-composants ; on la
   reprend ici pour la meme raison d'ordre, cette feuille sortant
   la derniere. La valeur est inchangee. */
.wrj-btn:active     { transform: scale(0.985); }
.wrj-pointure:active{ transform: scale(0.96); }
.wrj-carte:has(.wrj-carte__lien):active { transform: scale(0.99); }
.wrj-famille:active { transform: scale(0.99); }
.wrj-produit:active { transform: scale(0.985); }

/* ------------------------------------------------------------
   NEUTRALISATION

   « reduce » ne veut pas dire « plus vite », il veut dire
   « pas de mouvement ». On ne raccourcit donc aucune duree :
   on supprime la transition et on ramene tout a l'etat final.
   Le script s'arrete de son cote avant meme de poser un
   attribut ; ces regles couvrent le cas ou l'utilisateur active
   le reglage APRES le chargement, alors que des attributs sont
   deja en place.

   Le voile de la racle est supprime, pas fige : fige a scaleX(1)
   il couvrirait l'aplat d'un rectangle de papier. C'est la seule
   regle de ce bloc qui protege un CONTENU et pas seulement un
   geste, d'ou le `content: none` explicite.

   L'impression suit la meme logique : une page imprimee avec
   des blocs restes a opacity 0 serait une page trouee.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .wrj-js [data-wrj-vu] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .wrj-js .wrj-drench[data-wrj-vu]::after,
  .wrj-js .wrj-respiration[data-wrj-vu]::after,
  .wrj-js [data-wrj-aplat][data-wrj-vu]::after { content: none !important; }

  .wrj-btn,
  .wrj-carte,
  .wrj-pointure,
  .wrj-famille,
  .wrj-produit,
  .wrj-btn:hover,
  .wrj-carte:hover,
  .wrj-pointure:hover,
  .wrj-btn:active,
  .wrj-pointure:active,
  .wrj-carte:active,
  .wrj-famille:active,
  .wrj-produit:active {
    transition: none;
    transform: none;
  }
}

@media print {
  .wrj-js [data-wrj-vu] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .wrj-js .wrj-drench[data-wrj-vu]::after,
  .wrj-js .wrj-respiration[data-wrj-vu]::after,
  .wrj-js [data-wrj-aplat][data-wrj-vu]::after { content: none !important; }
}
