/* ==========================================================================
   WS Bannière - Atelier
   Une image plein cadre, un voile coloré qui la couvre d'un côté en
   s'effaçant vers le centre, et le texte posé dessus.

   CE N'EST PAS UN SPLIT EN DEUX COLONNES. L'image occupe toute la bannière ;
   le panneau de gauche est un voile posé par-dessus. C'est ce qui donne un
   vrai fondu au lieu d'une jointure entre deux matières qui se touchent, et
   c'est ce qui permet de passer en « image seule » en baissant une seule
   valeur, sans qu'aucune règle n'ait à changer.

   POINTS DE RUPTURE ALIGNÉS SUR ELEMENTOR
   La bannière s'empile à 1024 px et les boutons passent en colonne à 767 px,
   soit exactement les bornes tablette et mobile d'Elementor. Les valeurs
   responsive des contrôles tombent donc toujours sur la mise en page qu'elles
   sont censées habiller. Un décalage entre les deux crée une bande où les
   réglages d'un appareil habillent la mise en page d'un autre.

   RÈGLE DE SPÉCIFICITÉ
   Les valeurs par défaut restent en spécificité faible : Elementor écrit
   `.elementor-element-XXX .classe` (0-2-0) et doit toujours gagner.
   ========================================================================== */

.wsbn-atelier{
  /* Cadre */
  --wsbn-atl-c1:#FAF8F5;
  --wsbn-atl-c2:#EFEBE3;
  --wsbn-atl-angle:90deg;
  --wsbn-atl-radius:20px;
  --wsbn-atl-minh:470px;
  --wsbn-atl-media-h:290px;
  --wsbn-atl-texte-w:580px;
  --wsbn-atl-pad-x:56px;
  --wsbn-atl-pad-y:54px;
  --wsbn-atl-pad-b:54px;
  --wsbn-atl-debord-h:0px;
  --wsbn-atl-debord-b:0px;
  --wsbn-atl-texte-v:flex-start;

  /* Voile. Un seul angle commande la couleur ET l'effacement : ils suivent
     le meme axe, comme dans le degrade natif d'Elementor. */
  --wsbn-atl-plein:40%;
  --wsbn-atl-fondu:78%;
  --wsbn-atl-opacite:1;

  /* Image */
  --wsbn-atl-pos-x:50%;
  --wsbn-atl-pos-y:50%;
  --wsbn-atl-zoom:1;
  --wsbn-atl-decal-x:0%;
  --wsbn-atl-decal-y:0%;

  /* Textes */
  --wsbn-atl-sur:#6E7268;
  --wsbn-atl-titre:#23261F;
  --wsbn-atl-sous:#23261F;
  --wsbn-atl-desc:#6E7268;
  --wsbn-atl-gap-sur:22px;
  --wsbn-atl-gap-sous:6px;
  --wsbn-atl-gap-desc:20px;

  /* Boutons */
  --wsbn-atl-btn-w:max-content;
  --wsbn-atl-btn-gap:14px;
  --wsbn-atl-btn-top:28px;
  --wsbn-atl-btn-py:11px;
  --wsbn-atl-btn-px:22px;
  --wsbn-atl-btn-radius:999px;

  /* Bouton 1 et bouton 2, chacun ses deux etats. Le FOND n'est pas ici : il
     est ecrit par Elementor directement sur l'element, seule facon d'offrir
     le degrade et de rendre "Aucun fond" reellement atteignable. */
  --wsbn-atl-btn1-txt:#FFFFFF;
  --wsbn-atl-btn1-txt-h:#FFFFFF;
  --wsbn-atl-btn1-bord:transparent;
  --wsbn-atl-btn1-bord-h:transparent;
  --wsbn-atl-btn1-grow:1.04;
  --wsbn-atl-btn1-lift:0px;
  --wsbn-atl-btn1-ico-x:3px;
  --wsbn-atl-btn1-fx-c:rgba(255,255,255,0.55);
  --wsbn-atl-btn1-fx-dur:.45s;
  --wsbn-atl-btn1-fx-loop:5s;
  --wsbn-atl-btn1-perm-dur:2.4s;
  --wsbn-atl-btn1-halo:rgba(74,90,60,0.45);

  --wsbn-atl-btn2-txt:#23261F;
  --wsbn-atl-btn2-txt-h:#23261F;
  --wsbn-atl-btn2-bord:#D8D4CC;
  --wsbn-atl-btn2-bord-h:#23261F;
  --wsbn-atl-btn2-grow:1.04;
  --wsbn-atl-btn2-lift:0px;
  --wsbn-atl-btn2-ico-x:3px;
  --wsbn-atl-btn2-fx-c:rgba(255,255,255,0.55);
  --wsbn-atl-btn2-fx-dur:.45s;
  --wsbn-atl-btn2-fx-loop:5s;
  --wsbn-atl-btn2-perm-dur:2.4s;
  --wsbn-atl-btn2-halo:rgba(74,90,60,0.45);

  /* Apparition. `--in` porte le nom de l'animation : changer d'effet, c'est
     changer ce seul nom, pas reecrire cinq regles. */
  --wsbn-atl-in:wsbn-atl-in-up;
  --wsbn-atl-in-dur:.7s;
  --wsbn-atl-in-gap:90ms;
  --wsbn-atl-in-ease:cubic-bezier(.16,1,.3,1);

  /* Espace entre la signature et la note quand elles partagent la rangee. */
  --wsbn-atl-bas-gap:24px;

  /* Signature */
  --wsbn-atl-sig-ico:#23261F;
  --wsbn-atl-sig-ico-size:38px;
  --wsbn-atl-sig-titre:#23261F;
  --wsbn-atl-sig-texte:#6E7268;
  --wsbn-atl-sig-gap:14px;
  --wsbn-atl-sig-top:38px;

  /* Note manuscrite */
  --wsbn-atl-note:#3F4A38;
  --wsbn-atl-note-x:80%;
  --wsbn-atl-note-y:80%;
  --wsbn-atl-note-rot:-6deg;
  --wsbn-atl-note-size:23px;

  position:relative;

  /* LE FOND PERDU.
     Le rembourrage allonge le cadre vers le haut et vers le bas, la marge
     negative rend exactement la meme hauteur a la page. Resultat : l'image,
     qui couvre tout le cadre, gagne ces bandes, et le contenu ne bouge pas
     d'un pixel par rapport a ce qui l'entoure.

     La banniere passe donc PAR-DESSUS ce qui la precede et la suit. C'est le
     principe meme du fond perdu, mais il faut le savoir : si la section
     voisine recouvre le debord, c'est qu'elle est empilee au-dessus, et son
     onglet Avance dans Elementor porte de quoi la faire passer dessous. */
  padding-top:var(--wsbn-atl-debord-h);
  padding-bottom:var(--wsbn-atl-debord-b);
  margin-top:calc(-1 * var(--wsbn-atl-debord-h));
  margin-bottom:calc(-1 * var(--wsbn-atl-debord-b));

  /* Colonne flex des le grand ecran, alors qu'il n'y a qu'un seul enfant dans
     le flux : c'est ce qui permet de caler le texte en haut, au milieu ou en
     bas. L'image, le voile et la note sont positionnes en absolu, ils ne
     participent pas et ne sont donc pas deranges. */
  display:flex;
  flex-direction:column;
  justify-content:var(--wsbn-atl-texte-v);

  min-height:var(--wsbn-atl-minh);
  border-radius:var(--wsbn-atl-radius);
  overflow:hidden;
  isolation:isolate;
  background:linear-gradient(var(--wsbn-atl-angle), var(--wsbn-atl-c1), var(--wsbn-atl-c2));
  font-family:"Plus Jakarta Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  -webkit-font-smoothing:antialiased;
}

.wsbn-atelier,
.wsbn-atelier *,
.wsbn-atelier *::before,
.wsbn-atelier *::after{box-sizing:border-box}

/* --------------------------------------------------------------------------
   L'IMAGE
   -------------------------------------------------------------------------- */

.wsbn-atelier__media{
  position:absolute;
  inset:0;
  z-index:0;
  overflow:hidden;
}

.wsbn-atelier__picture{display:block;width:100%;height:100%}

/* CADRAGE, ZOOM ET DÉCALAGE SONT TROIS GESTES DIFFÉRENTS.
     cadrage  choisit quelle partie de l'image on garde. Il n'agit que sur
              l'axe où l'image déborde, et ne peut jamais la sortir du cadre.
     zoom     agrandit l'image et crée du débord sur les deux axes : c'est lui
              qui rend le cadrage utile quand un seul axe débordait.
     décalage pousse l'image et ASSUME de laisser une bande vide, qui montre
              alors le dégradé du fond.
   `translate` et `scale` sont des propriétés individuelles : elles se
   composent au lieu de s'écraser, là où deux `transform` se seraient
   annulées. */
.wsbn-atelier__media img{
  width:100%;
  height:100%;
  display:block;
  object-fit:cover;
  object-position:var(--wsbn-atl-pos-x) var(--wsbn-atl-pos-y);
  transform-origin:var(--wsbn-atl-pos-x) var(--wsbn-atl-pos-y);
  translate:var(--wsbn-atl-decal-x) var(--wsbn-atl-decal-y);
  scale:var(--wsbn-atl-zoom);
}

/* --------------------------------------------------------------------------
   LE VOILE

   C'est lui le panneau coloré. Un aplat dégradé plein cadre, effacé
   progressivement par un MASQUE.

   POURQUOI UN MASQUE ET PAS UN DÉGRADÉ VERS `transparent` : la couleur suit
   son propre angle, souvent en diagonale. Si le fondu était écrit dans le
   même dégradé, les deux directions se mélangeraient et l'une abîmerait
   l'autre. Le masque sépare les deux questions. En prime, un fondu vers
   `transparent` vire au gris sur certains moteurs, un masque jamais.
   Le masque est statique : la règle de CLAUDE.md sur `mask-position` vise les
   masques ANIMÉS, ce n'est pas le cas ici.
   -------------------------------------------------------------------------- */

.wsbn-atelier__voile{
  position:absolute;
  inset:0;
  z-index:1;
  pointer-events:none;
  opacity:var(--wsbn-atl-opacite);
  background:linear-gradient(var(--wsbn-atl-angle), var(--wsbn-atl-c1), var(--wsbn-atl-c2));
  -webkit-mask-image:linear-gradient(var(--wsbn-atl-angle), #000 var(--wsbn-atl-plein), transparent var(--wsbn-atl-fondu));
          mask-image:linear-gradient(var(--wsbn-atl-angle), #000 var(--wsbn-atl-plein), transparent var(--wsbn-atl-fondu));
}

/* MODE "IMAGE SEULE".
   La classe est posee par Elementor sur l'element du widget, donc AU-DESSUS
   de notre racine : la regle est plus specifique que les variables ecrites
   par les curseurs de largeur, et gagne sans avoir a les desactiver. Les deux
   curseurs concernes sont d'ailleurs masques dans ce mode, il ne reste que
   l'opacite, qui garde tout son sens : c'est elle qui rend le texte lisible
   par-dessus la photo. */
.wsbn-atelier-fond-image .wsbn-atelier__voile{
  --wsbn-atl-plein:0%;
  --wsbn-atl-fondu:58%;
}

/* --------------------------------------------------------------------------
   LE TEXTE
   -------------------------------------------------------------------------- */

/* `position:static` VOLONTAIRE. Si cette colonne etait positionnee, la note
   en absolu se calerait sur elle et non sur la banniere : ses deux curseurs
   changeraient de sens du jour au lendemain. Le `z-index` tient quand meme,
   un element flex cree un contexte d'empilement sans avoir besoin d'une
   position. */
.wsbn-atelier__texte{
  position:static;
  z-index:2;
  max-width:var(--wsbn-atl-texte-w);
  padding:var(--wsbn-atl-pad-y) var(--wsbn-atl-pad-x) var(--wsbn-atl-pad-b);
  display:flex;
  flex-direction:column;
  align-items:flex-start;
}

/* DEUXIEME DISPOSITION : LE PANNEAU PASSE A DROITE.
   Une seule marge automatique suffit : le bloc va a droite, mais son contenu
   reste cale a gauche a l'interieur. C'est ce qu'on veut, un texte aligne a
   droite se lit mal des qu'il fait plus d'une ligne. */
.wsbn-atelier-cote-droite .wsbn-atelier__texte{
  margin-left:auto;
}

.wsbn-atelier__sur{
  margin:0 0 var(--wsbn-atl-gap-sur);
  color:var(--wsbn-atl-sur);
  font-size:11px;
  font-weight:500;
  letter-spacing:.22em;
  text-transform:uppercase;
  line-height:1.4;
}

.wsbn-atelier__titre{
  margin:0;
  color:var(--wsbn-atl-titre);
  font-family:"Playfair Display",Georgia,"Times New Roman",serif;
  font-size:clamp(30px, 3.2vw, 42px);
  font-weight:400;
  line-height:1.18;
  letter-spacing:-.005em;
}

.wsbn-atelier__sous{
  margin:var(--wsbn-atl-gap-sous) 0 0;
  color:var(--wsbn-atl-sous);
  font-family:"Playfair Display",Georgia,"Times New Roman",serif;
  font-size:clamp(20px, 2vw, 25px);
  font-weight:400;
  line-height:1.3;
}

.wsbn-atelier__desc{
  margin:var(--wsbn-atl-gap-desc) 0 0;
  max-width:44ch;
  color:var(--wsbn-atl-desc);
  font-size:14px;
  line-height:1.72;
}

/* --------------------------------------------------------------------------
   LES BOUTONS

   `width:max-content` sur une grille en `1fr` ne donne pas la somme des deux
   contenus mais DEUX FOIS LE PLUS LARGE : c'est ainsi que la largeur
   intrinsèque d'une piste `fr` se calcule. Les deux boutons font donc la même
   longueur, chacun assez large pour son libellé, sans largeur fixe qui aurait
   cassé au premier changement de texte. Le réglage de largeur remplace cette
   valeur par un pourcentage quand on veut resserrer ou étirer le groupe.
   -------------------------------------------------------------------------- */

.wsbn-atelier__actions{
  display:grid;
  grid-auto-flow:column;
  grid-auto-columns:1fr;
  gap:var(--wsbn-atl-btn-gap);
  margin-top:var(--wsbn-atl-btn-top);
  width:var(--wsbn-atl-btn-w);
  max-width:100%;
}

/* Le reset `a{color:inherit}` de beaucoup de thèmes bat une classe simple
   posée sur un <a> : on qualifie donc par `a.` pour garder la main. */
a.wsbn-atelier__btn{
  text-decoration:none;
}

.wsbn-atelier__btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:10px;
  padding:var(--wsbn-atl-btn-py) var(--wsbn-atl-btn-px);
  border:1px solid transparent;
  border-radius:var(--wsbn-atl-btn-radius);
  font-family:inherit;
  font-size:13.5px;
  font-weight:500;
  line-height:1.35;
  cursor:pointer;
  transition:background-color .25s ease, background-image .25s ease,
             color .25s ease, border-color .25s ease, box-shadow .25s ease,
             scale .25s cubic-bezier(.2,.8,.2,1),
             translate .25s cubic-bezier(.2,.8,.2,1);
}

/* L'agrandissement et le soulevement s'écrivent sur `scale` et `translate`,
   pas sur `transform` : ces proprietes se composent, la ou deux `transform`
   se seraient annulees. Chaque bouton a les siennes. */
.wsbn-atelier__btn svg{
  width:1em;
  height:1em;
  font-size:15px;
  flex:none;
  fill:currentColor;
  transition:translate .25s ease;
}

a.wsbn-atelier__btn--plein{
  color:var(--wsbn-atl-btn1-txt);
  border-color:var(--wsbn-atl-btn1-bord);
}
a.wsbn-atelier__btn--plein:hover{
  color:var(--wsbn-atl-btn1-txt-h);
  border-color:var(--wsbn-atl-btn1-bord-h);
  scale:var(--wsbn-atl-btn1-grow);
  translate:0 calc(-1 * var(--wsbn-atl-btn1-lift));
}
.wsbn-atelier__btn--plein:hover svg{
  translate:var(--wsbn-atl-btn1-ico-x) 0;
}

a.wsbn-atelier__btn--ligne{
  color:var(--wsbn-atl-btn2-txt);
  border-color:var(--wsbn-atl-btn2-bord);
}
a.wsbn-atelier__btn--ligne:hover{
  color:var(--wsbn-atl-btn2-txt-h);
  border-color:var(--wsbn-atl-btn2-bord-h);
  scale:var(--wsbn-atl-btn2-grow);
  translate:0 calc(-1 * var(--wsbn-atl-btn2-lift));
}
.wsbn-atelier__btn--ligne:hover svg{
  translate:var(--wsbn-atl-btn2-ico-x) 0;
}

/* --------------------------------------------------------------------------
   LA SIGNATURE DU BAS
   -------------------------------------------------------------------------- */

/* LA RANGEE DU BAS : signature a gauche, note a droite.
   Quand la note flotte, elle est hors flux et cette rangee ne contient plus
   que la signature : elle se comporte alors exactement comme avant. */
.wsbn-atelier__bas{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--wsbn-atl-bas-gap);
  width:100%;
  flex-wrap:nowrap;
}

/* SANS CECI, RIEN NE SE PARTAGE LA LIGNE.
   Un element flex refuse par defaut de descendre sous la largeur de son
   contenu : le premier prend toute la place et le second est repousse. Le
   min-width a zero les autorise a se retrecir, et leur texte passe alors a
   la ligne A L INTERIEUR de sa colonne, ce qui est le comportement voulu. */
.wsbn-atelier__bas > *{
  min-width:0;
}

.wsbn-atelier__signature{
  display:flex;
  align-items:center;
  gap:var(--wsbn-atl-sig-gap);
  margin-top:var(--wsbn-atl-sig-top);
}

.wsbn-atelier__signature-ico{
  display:inline-flex;
  flex:none;
  /* Couleur DÉDIÉE : l'icône ne suit pas le texte, sinon elle disparaît dès
     qu'on retouche la couleur du libellé. */
  color:var(--wsbn-atl-sig-ico);
  font-size:var(--wsbn-atl-sig-ico-size);
}

.wsbn-atelier__signature-ico svg{
  width:1em;
  height:1em;
  fill:none;
  stroke:currentColor;
  stroke-width:1.1;
}

.wsbn-atelier__signature-txt{
  font-size:13px;
  line-height:1.55;
}

.wsbn-atelier__signature-titre{
  display:block;
  color:var(--wsbn-atl-sig-titre);
  font-weight:500;
}

.wsbn-atelier__signature-sous{
  display:block;
  color:var(--wsbn-atl-sig-texte);
}

/* --------------------------------------------------------------------------
   LA NOTE MANUSCRITE

   Posée par son CENTRE : déplacer un objet par son centre est le seul repère
   qui reste juste quand sa taille change. Avec un coin, chaque changement de
   taille aurait demandé de retoucher la position.
   `translate` et `rotate` sont individuelles, elles se composent : le
   centrage ne mange donc pas la rotation.
   -------------------------------------------------------------------------- */

.wsbn-atelier__note{
  position:absolute;
  z-index:2;
  left:var(--wsbn-atl-note-x);
  top:var(--wsbn-atl-note-y);
  margin:0;
  translate:-50% -50%;
  rotate:var(--wsbn-atl-note-rot);
  width:max-content;
  max-width:46%;
  color:var(--wsbn-atl-note);
  font-family:"Kaushan Script","Segoe Script",cursive;
  /* Taille de repli. Le groupe typographique du panneau ecrit son
     `font-size` sur un selecteur plus specifique et l'emporte donc des
     qu'il est regle. Cette ligne sert quand il ne l'est pas. */
  font-size:var(--wsbn-atl-note-size);
  line-height:1.35;
  text-align:center;
  pointer-events:none;
}


/* --------------------------------------------------------------------------
   LA NOTE POSEE A COTE DE LA SIGNATURE

   Elle quitte l'absolu et redevient un element de la rangee. Ses deux
   curseurs de position n'ont alors plus d'objet, c'est la rangee qui place :
   la feuille les neutralise plutot que de les laisser agir a moitie.

   `--cotepetit` ne s'applique que sous 1024 px : la note flotte sur
   l'ordinateur, ou il y a de la place, et rejoint la signature sur les
   ecrans etroits, ou il n'y en a plus. C'est le cas de loin le plus utile,
   et il ne demande aucun reglage par appareil.
   -------------------------------------------------------------------------- */

.wsbn-atelier-note-cote .wsbn-atelier__note{
  position:static;
  translate:none;
  max-width:none;
  width:auto;
  text-align:right;
  flex:0 1 auto;
}

@media (max-width:1024px){
  .wsbn-atelier-note-cotepetit .wsbn-atelier__note{
    position:static;
    translate:none;
    max-width:none;
    width:auto;
    text-align:right;
    flex:0 1 auto;
  }
}

/* --------------------------------------------------------------------------
   TABLETTE ET MOBILE

   1024 px : la borne tablette d'Elementor.

   L'empilement (image au-dessus, texte dessous) est le comportement par
   defaut, mais il se coupe : la classe `wsbn-atelier-petit-plein`, posee par
   le reglage « Disposition sur petit ecran », laisse la banniere telle
   qu'elle est sur ordinateur. Rien a annuler dans ce cas, il suffit que ce
   bloc ne s'applique pas, d'ou la classe portee par CHAQUE regle plutot
   qu'un contre-bloc qui aurait tout remis en place a la main.
   -------------------------------------------------------------------------- */

@media (max-width:1024px){
  .wsbn-atelier-petit-empile .wsbn-atelier{
    min-height:0;
    /* La hauteur suit le contenu une fois empile : il n'y a plus d'espace
       libre a repartir, le calage vertical n'a donc plus d'objet. */
    justify-content:flex-start;
  }

  .wsbn-atelier-petit-empile .wsbn-atelier__media{
    position:relative;
    inset:auto;
    order:1;
    height:var(--wsbn-atl-media-h);
  }

  .wsbn-atelier-petit-empile .wsbn-atelier__voile{display:none}

  /* LA LARGEUR DU TEXTE RESTE PILOTEE, MEME EMPILEE.
     Ici vivait `max-width:none`, qui ecrasait la variable du reglage : le
     curseur bougeait et la banniere ne bougeait pas. La valeur par defaut
     (580 px) depasse la largeur d'un telephone, la colonne prend donc tout
     l'espace comme avant, mais une valeur plus petite se voit enfin. */
  .wsbn-atelier-petit-empile .wsbn-atelier__texte{
    order:2;
    max-width:var(--wsbn-atl-texte-w);
  }

  /* CENTRÉ DÈS QUE C'EST EMPILÉ, et le centrage se joue sur TROIS choses. En
     oublier une donne un centrage à moitié fait : l'alignement du texte,
     celui des blocs entre eux (le conteneur est en flex), et les marges
     automatiques du paragraphe, qui garde une largeur de lecture limitée et
     ne se centrerait pas tout seul. */
  /* La colonne elle-meme se recentre : sans ces marges, une colonne plus
     etroite que le cadre resterait collee a gauche, centrage ou pas. */
  .wsbn-atelier-petit-empile .wsbn-atelier--centre .wsbn-atelier__texte{align-items:center;text-align:center;margin-left:auto;margin-right:auto}
  .wsbn-atelier-petit-empile .wsbn-atelier--centre .wsbn-atelier__desc{margin-left:auto;margin-right:auto}
  .wsbn-atelier-petit-empile .wsbn-atelier--centre .wsbn-atelier__signature{justify-content:center}
  .wsbn-atelier-petit-empile .wsbn-atelier--centre .wsbn-atelier__actions{margin-left:auto;margin-right:auto}
}

/* 767 px : la borne mobile d'Elementor. Deux boutons côte à côte y deviennent
   trop étroits pour leur libellé. */
@media (max-width:767px){
  .wsbn-atelier__actions{grid-auto-flow:row}
}


/* --------------------------------------------------------------------------
   L'APPARITION

   `wsbn-apparition` est posee par ws-banniere-apparition.js des le chargement,
   `wsbn-apparition-vu` a l'entree dans l'ecran. C'est le SCRIPT qui masque :
   s'il ne se charge pas, aucune classe n'arrive et la banniere s'affiche
   entiere tout de suite. Un titre invisible est le seul defaut qu'on ne
   rattrape pas depuis l'admin.

   `backwards` et non `both` : `both` laisserait la derniere image de
   l'animation inscrite sur l'element, et un `transform` fige la bloquerait
   ensuite pour tout le reste.
   -------------------------------------------------------------------------- */

.wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__sur,
.wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__titre,
.wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__sous,
.wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__desc,
.wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__actions,
.wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__signature,
.wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__note{
  opacity:0;
}

/* L'ordre des retards est celui de la lecture : le regard descend, les blocs
   arrivent dans le meme sens. */
.wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__sur       { animation:var(--wsbn-atl-in) var(--wsbn-atl-in-dur) var(--wsbn-atl-in-ease) calc(var(--wsbn-atl-in-gap) * 0) backwards; }
.wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__titre     { animation:var(--wsbn-atl-in) var(--wsbn-atl-in-dur) var(--wsbn-atl-in-ease) calc(var(--wsbn-atl-in-gap) * 1) backwards; }
.wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__sous      { animation:var(--wsbn-atl-in) var(--wsbn-atl-in-dur) var(--wsbn-atl-in-ease) calc(var(--wsbn-atl-in-gap) * 2) backwards; }
.wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__desc      { animation:var(--wsbn-atl-in) var(--wsbn-atl-in-dur) var(--wsbn-atl-in-ease) calc(var(--wsbn-atl-in-gap) * 3) backwards; }
.wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__actions   { animation:var(--wsbn-atl-in) var(--wsbn-atl-in-dur) var(--wsbn-atl-in-ease) calc(var(--wsbn-atl-in-gap) * 4) backwards; }
.wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__signature { animation:var(--wsbn-atl-in) var(--wsbn-atl-in-dur) var(--wsbn-atl-in-ease) calc(var(--wsbn-atl-in-gap) * 5) backwards; }
.wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__note      { animation:var(--wsbn-atl-in) var(--wsbn-atl-in-dur) var(--wsbn-atl-in-ease) calc(var(--wsbn-atl-in-gap) * 6) backwards; }

.wsbn-atelier--in-fade { --wsbn-atl-in:wsbn-atl-in-fade; }
.wsbn-atelier--in-up   { --wsbn-atl-in:wsbn-atl-in-up; }
.wsbn-atelier--in-left { --wsbn-atl-in:wsbn-atl-in-left; }
.wsbn-atelier--in-zoom { --wsbn-atl-in:wsbn-atl-in-zoom; }

/* Ces animations n'ecrivent que `opacity` et `transform`, jamais `translate`
   ni `rotate` : la note manuscrite est deja posee par son centre avec
   `translate` et inclinee avec `rotate`, et ces proprietes individuelles se
   composent avec `transform` au lieu de l'ecraser. Elle arrive donc en place,
   toujours penchee. */
@keyframes wsbn-atl-in-fade{
  from { opacity:0; }
  to   { opacity:1; }
}
@keyframes wsbn-atl-in-up{
  from { opacity:0; transform:translateY(18px); }
  to   { opacity:1; transform:none; }
}
@keyframes wsbn-atl-in-left{
  from { opacity:0; transform:translateX(-22px); }
  to   { opacity:1; transform:none; }
}
@keyframes wsbn-atl-in-zoom{
  from { opacity:0; transform:scale(.94); }
  to   { opacity:1; transform:none; }
}

/* Le script ne pose meme pas la classe quand la preference est active. Cette
   regle est la ceinture : un cache navigateur peut servir un HTML deja marque
   alors que la preference vient de changer. */
@media (prefers-reduced-motion:reduce){
  .wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__sur,
  .wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__titre,
  .wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__sous,
  .wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__desc,
  .wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__actions,
  .wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__signature,
  .wsbn-atelier.wsbn-apparition:not(.wsbn-apparition-vu) .wsbn-atelier__note{
    opacity:1;
  }
  .wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__sur,
  .wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__titre,
  .wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__sous,
  .wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__desc,
  .wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__actions,
  .wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__signature,
  .wsbn-atelier.wsbn-apparition-vu .wsbn-atelier__note{
    animation:none;
  }
}


/* --------------------------------------------------------------------------
   LES EFFETS DES BOUTONS

   Tout passe par deux pseudo-elements, jamais par du balisage en plus : une
   banniere deja posee garde exactement le meme HTML.

   `::before` porte le halo, `::after` la bande de lumiere. Le bouton devient
   donc un contexte de positionnement, et il rogne ce qui depasse.
   -------------------------------------------------------------------------- */

.wsbn-atelier__btn{
  position:relative;
  overflow:hidden;
}

/* Le contenu repasse au-dessus des deux calques. */
.wsbn-atelier__btn > *{
  position:relative;
  z-index:1;
}

/* LA BANDE DE LUMIERE.
   Elle traverse en `translate`, pas en `background-position` : le deplacement
   est compose par la carte graphique au lieu de repeindre le fond a chaque
   image. Large de 60 % et posee a gauche, elle va de -167 % a 333 % de sa
   propre largeur, ce qui fait -100 % a +200 % de celle du bouton. */
.wsbn-atelier__btn::after{
  content:"";
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  width:60%;
  pointer-events:none;
  opacity:0;
  translate:-167% 0;
  background:linear-gradient(100deg, transparent, var(--wsbn-atl-fx-c), transparent);
}

.wsbn-atelier__btn--plein{ --wsbn-atl-fx-c:var(--wsbn-atl-btn1-fx-c); }
.wsbn-atelier__btn--ligne{ --wsbn-atl-fx-c:var(--wsbn-atl-btn2-fx-c); }

/* Au survol : un seul passage, a la vitesse reglee. */
.wsbn-atelier-fx1-shine .wsbn-atelier__btn--plein:hover::after,
.wsbn-atelier-fx1-shine-loop .wsbn-atelier__btn--plein:hover::after{
  animation:wsbn-atl-reflet var(--wsbn-atl-btn1-fx-dur) ease-out;
}
.wsbn-atelier-fx2-shine .wsbn-atelier__btn--ligne:hover::after,
.wsbn-atelier-fx2-shine-loop .wsbn-atelier__btn--ligne:hover::after{
  animation:wsbn-atl-reflet var(--wsbn-atl-btn2-fx-dur) ease-out;
}

/* En boucle : le meme passage, bien plus lent, sans fin. */
.wsbn-atelier-fx1-loop .wsbn-atelier__btn--plein::after,
.wsbn-atelier-fx1-shine-loop .wsbn-atelier__btn--plein::after{
  animation:wsbn-atl-reflet var(--wsbn-atl-btn1-fx-loop) ease-out infinite;
}
.wsbn-atelier-fx2-loop .wsbn-atelier__btn--ligne::after,
.wsbn-atelier-fx2-shine-loop .wsbn-atelier__btn--ligne::after{
  animation:wsbn-atl-reflet var(--wsbn-atl-btn2-fx-loop) ease-out infinite;
}

/* Le passage occupe le premier tiers du cycle, le reste est la pause. */
@keyframes wsbn-atl-reflet{
  0%   { opacity:0; translate:-167% 0; }
  8%   { opacity:1; }
  30%  { opacity:1; translate:333% 0; }
  31%  { opacity:0; translate:333% 0; }
  100% { opacity:0; translate:-167% 0; }
}

/* LE HALO, PORTE PAR LE CONTOUR ET NON PAR UN PSEUDO.
   Un pseudo-element est un ENFANT du bouton : l'`overflow:hidden` qui rogne
   le reflet le rognerait aussi, et le halo resterait invisible. Le contour,
   lui, appartient au bouton lui-meme et echappe a son propre overflow.

   `outline-color` et `outline-offset` ne touchent pas a la mise en page :
   rien ne se recalcule, seule la peinture change. Le contour suit l'arrondi
   du bouton, y compris a 999 px. */
.wsbn-atelier-perm1-halo .wsbn-atelier__btn--plein{
  --wsbn-atl-halo-c:var(--wsbn-atl-btn1-halo);
  outline:5px solid transparent;
  animation:wsbn-atl-halo var(--wsbn-atl-btn1-perm-dur) ease-in-out infinite;
}
.wsbn-atelier-perm2-halo .wsbn-atelier__btn--ligne{
  --wsbn-atl-halo-c:var(--wsbn-atl-btn2-halo);
  outline:5px solid transparent;
  animation:wsbn-atl-halo var(--wsbn-atl-btn2-perm-dur) ease-in-out infinite;
}

/* Mis en pause au survol, comme la pulsation : le contour se figerait sinon
   sur une image quelconque pendant que le bouton grossit. */
.wsbn-atelier-perm1-halo .wsbn-atelier__btn--plein:hover,
.wsbn-atelier-perm2-halo .wsbn-atelier__btn--ligne:hover{
  animation-play-state:paused;
}

@keyframes wsbn-atl-halo{
  0%,100% { outline-color:transparent;              outline-offset:0; }
  50%     { outline-color:var(--wsbn-atl-halo-c);   outline-offset:5px; }
}

/* LA PULSATION.
   Elle ecrit sur `scale`, comme l'agrandissement au survol. Les deux ne
   peuvent pas jouer ensemble sur la meme propriete : la boucle se met donc en
   pause au survol, et l'agrandissement reprend la main proprement. */
.wsbn-atelier-perm1-pulse .wsbn-atelier__btn--plein{
  animation:wsbn-atl-pulse var(--wsbn-atl-btn1-perm-dur) ease-in-out infinite;
}
.wsbn-atelier-perm2-pulse .wsbn-atelier__btn--ligne{
  animation:wsbn-atl-pulse var(--wsbn-atl-btn2-perm-dur) ease-in-out infinite;
}
.wsbn-atelier-perm1-pulse .wsbn-atelier__btn--plein:hover,
.wsbn-atelier-perm2-pulse .wsbn-atelier__btn--ligne:hover{
  animation-play-state:paused;
}

@keyframes wsbn-atl-pulse{
  0%,100% { scale:1; }
  50%     { scale:1.035; }
}

/* --------------------------------------------------------------------------
   LA VEILLE

   `wsbn-hors-vue` est posee sur la banniere par ws-banniere-veille.js quand
   elle quitte l'ecran, `wsbn-onglet-cache` sur <html> quand l'onglet passe en
   arriere-plan. C'est la classe POSEE qui met en pause, jamais son absence :
   si le script ne se charge pas, rien ne se fige.
   -------------------------------------------------------------------------- */

.wsbn-hors-vue .wsbn-atelier__btn,
.wsbn-hors-vue .wsbn-atelier__btn::after,
.wsbn-onglet-cache .wsbn-atelier__btn,
.wsbn-onglet-cache .wsbn-atelier__btn::after{
  animation-play-state:paused;
}

/* --------------------------------------------------------------------------
   ANIMATIONS RÉDUITES
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion:reduce){
  .wsbn-atelier__btn,
  .wsbn-atelier__btn svg{
    transition:none;
  }
  .wsbn-atelier__btn:hover{
    scale:1;
    translate:0;
  }
  .wsbn-atelier__btn:hover svg{
    translate:0;
  }
  /* Ni reflet ni pulsation : ce sont des boucles, exactement ce que la
     preference demande de couper. */
  .wsbn-atelier__btn,
  .wsbn-atelier__btn::after{
    animation:none;
  }
}
