/**
 * Gutenberg New Gen - Bloc « Bouton avance ».
 *
 * Portage de deux feuilles de WS Booster vers Gutenberg :
 *   assets/css/ws-widget-magnetic-button.css  -> tout le fichier,
 *   assets/css/ws-effets-bouton.css           -> la gelee, en fin de fichier.
 *
 * Les regles sont reprises telles quelles ; seuls les noms de classes et de
 * variables changent (ws-magnetic-btn -> gng-btn, ws-fxb -> gng-btn). Seul le
 * bloc d'adaptation au « fondu sur les bords » a ete retire : cette
 * fonctionnalite transverse de WS Booster n'existe pas ici.
 *
 * Variables (posees par le bloc sur .gng-btn) :
 *   --gng-btn-fx-color    : couleur du reflet
 *   --gng-btn-fx-speed    : duree du reflet
 *   --gng-btn-hover-speed : duree des transitions de survol (Style > Survol)
 */

/* =================================================================
   SOCLE DU BOUTON

   WS Booster posait cette base dans sa feuille commune a tous les
   widgets, que ce portage n'emmene pas : un seul bloc n'a pas besoin
   d'un millier de lignes partagees. Elle est donc reecrite ici, reduite
   a ce dont CE bouton a besoin.

   Chaque valeur passe par une propriete personnalisee : le bloc n'ecrit
   que ce que l'utilisateur a change, et le repli fait le reste.

   Le survol vit ici, et non en style en ligne : un attribut `style` ne
   peut pas exprimer `:hover`. Les apparences plus bas restent
   prioritaires - elles sont ecrites avec un selecteur plus specifique.
   ================================================================= */
.gng-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5em;
    box-sizing: border-box;
    max-width: 100%;
    text-decoration: none;
    cursor: pointer;
    line-height: 1.2;
    border-style: solid;
    border-width: var(--gng-btn-border-w, 0);
    border-color: var(--gng-btn-border-c, transparent);
    border-radius: var(--gng-btn-radius, 999px);
    padding: var(--gng-btn-pad-y, 14px) var(--gng-btn-pad-x, 28px);
    font-size: var(--gng-btn-font-size, 15px);
    font-weight: var(--gng-btn-font-weight, 600);
    background-color: var(--gng-btn-bg, #111827);
    color: var(--gng-btn-color, #ffffff);
}

.gng-btn:hover,
.gng-btn:focus-visible {
    background-color: var(--gng-btn-bg-hover, var(--gng-btn-bg, #111827));
    color: var(--gng-btn-color-hover, var(--gng-btn-color, #ffffff));
}

/* Le contour de mise au point doit rester visible : c'est le seul reperage
   dont dispose une personne qui navigue au clavier. */
.gng-btn:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 3px;
}

.gng-btn {
    --gng-btn-fx-color: #ffffff;
    --gng-btn-fx-speed: 0.4s;
    --gng-btn-hover-speed: 0.3s;
    --gng-btn-hov-speed: 0.3s;
    --gng-btn-hov-k: 1;
    /* Transitions de survol sur les proprietes de style.

       `scale` et `translate` sont des proprietes DISTINCTES de `transform` :
       les animer ici ne marche donc pas sur les pieds de l'effet magnetique,
       qui ecrit dans `transform` depuis le script. Les deux se composent. */
    transition:
        background-color var(--gng-btn-hover-speed, 0.3s) ease,
        color            var(--gng-btn-hover-speed, 0.3s) ease,
        border-color     var(--gng-btn-hover-speed, 0.3s) ease,
        box-shadow       var(--gng-btn-hover-speed, 0.3s) ease,
        scale            var(--gng-btn-hov-speed, 0.3s) ease,
        translate        var(--gng-btn-hov-speed, 0.3s) ease;
}

/* L'icone a sa propre couleur (reglage dedie) : elle a donc besoin de sa
   propre transition. Celle du bouton ne couvre que la couleur du bouton. */
/* L icone est une BOITE, pas du texte en ligne.
   Un <span> est en ligne par defaut, et ni rotate ni scale ne s appliquent a un
   element en ligne : la rotation reglee dans le panneau etait calculee et
   jamais peinte. Les apparences qui posaient deja inline-flex fonctionnaient,
   les autres non - d ou un reglage qui marche ou pas selon l apparence. */
.gng-btn__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.gng-btn__icon,
.gng-btn__icon svg {
    transition: color var(--gng-btn-hover-speed, 0.3s) ease,
                fill  var(--gng-btn-hover-speed, 0.3s) ease,
                /* Agrandissement au survol (Style > Icone > Survol). C'est la
                   propriete INDIVIDUELLE `scale` qui est reglee, pas
                   `transform` : plusieurs apparences transforment deja
                   l'icone, et deux regles sur `transform` s'annulent. */
                scale var(--gng-btn-hover-speed, 0.3s) ease,
                /* Rotation reglee dans le panneau (Style > Icone du bouton).
                   Sa transition la rend agreable a regler : le curseur fait
                   pivoter l'icone sous les yeux au lieu de la faire sauter. */
                rotate var(--gng-btn-hover-speed, 0.3s) ease;
}

/* ============================================================
   POSITION — "Etiree" fait passer l'enveloppe en bloc et le bouton
   a pleine largeur. Les variables sont posees par le controle Position
   (dictionnaire de valeurs) ; hors mode etire elles n'existent pas et
   les valeurs de repli s'appliquent.
   ============================================================ */
.gng-btn-wrap {
    display: var(--gng-btn-wrap-display, inline-block);
}

.gng-btn {
    width: var(--gng-btn-btn-width, auto);
}

/* ============================================================
   MOUVEMENT AU SURVOL — les mouvements du bouton lui-meme, ecrits en
   proprietes individuelles pour ne pas ecraser le `transform` du magnetique.
   ============================================================ */
.gng-btn-hov-grow   .gng-btn:hover { scale: calc(1 + 0.06 * var(--gng-btn-hov-k, 1)); }
.gng-btn-hov-shrink .gng-btn:hover { scale: calc(1 - 0.06 * var(--gng-btn-hov-k, 1)); }
.gng-btn-hov-float  .gng-btn:hover { translate: 0 calc(-6px * var(--gng-btn-hov-k, 1)); }
.gng-btn-hov-sink   .gng-btn:hover { translate: 0 calc(6px * var(--gng-btn-hov-k, 1)); }

/* La pulsation tourne en boucle tant que la souris reste sur le bouton :
   c'est une animation, pas une transition. */
.gng-btn-hov-pulse .gng-btn:hover {
    animation: gng-btn-pulse calc(var(--gng-btn-hov-speed, 0.3s) * 2.5) ease-in-out infinite;
}

@keyframes gng-btn-pulse {
    0%, 100% { scale: 1; }
    50%      { scale: calc(1 + 0.05 * var(--gng-btn-hov-k, 1)); }
}

/* =================================================================
   APPARENCES AU SURVOL — un seul choix a la fois.

   Les quatre "remplissages" partagent le meme calque .gng-btn__fill,
   pose par le rendu uniquement pour eux. Seules la FORME du calque et son
   ORIGINE changent d'une variante a l'autre : une seule mecanique a
   maintenir au lieu de quatre.

   Le calque est anime en `scale` / `translate` (proprietes individuelles),
   jamais en `transform` : le magnetique ecrit dans `transform`.
   ================================================================= */
.gng-btn-ap-fill-cursor .gng-btn,
.gng-btn-ap-fill-center .gng-btn,
.gng-btn-ap-fill-wipe .gng-btn,
.gng-btn-ap-fill-wave .gng-btn {
    position: relative;
    /* Le calque deborde volontairement du bouton : on le rogne a la pilule. */
    overflow: hidden;
}

.gng-btn__fill {
    position: absolute;
    pointer-events: none;
    z-index: 0;
    background-color: #ffffff;
}

/* Le contenu repasse au-dessus du calque, sinon le remplissage le masque. */
.gng-btn__text {
    position: relative;
    z-index: 1;
}

/* --- Remplissage circulaire. `--gng-btn-ox/oy` sont poses par le script au
       point ou la souris entre ; sans script (ou en mode "depuis le centre")
       ils valent 50% et le cercle part du milieu. --- */
.gng-btn-ap-fill-cursor .gng-btn__fill,
.gng-btn-ap-fill-center .gng-btn__fill {
    top: var(--gng-btn-ox-y, 50%);
    left: var(--gng-btn-ox-x, 50%);
    /* Diametre calcule par le script (plus petit disque couvrant le bouton
       depuis le point d'entree). Repli a 260% si le script n'a pas tourne :
       toujours assez grand pour couvrir, simplement moins econome. */
    width: var(--gng-btn-fill-d, 260%);
    aspect-ratio: 1;
    border-radius: 50%;
    translate: -50% -50%;
    scale: 0;
    transition: scale var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

/* Le mode "depuis le centre" ne doit RIEN au curseur : il ecrase les
   variables que le script pourrait avoir posees. */
.gng-btn-ap-fill-center .gng-btn__fill {
    width: 260%;
}

.gng-btn-ap-fill-cursor .gng-btn:hover .gng-btn__fill,
.gng-btn-ap-fill-center .gng-btn:hover .gng-btn__fill {
    scale: 1;
}

/* Le mode "depuis le centre" ignore la position de la souris. */
.gng-btn-ap-fill-center .gng-btn__fill {
    top: 50%;
    left: 50%;
}

/* --- Balayage lateral.
       Le calque couvre deja tout le bouton et s'ouvre HORIZONTALEMENT depuis
       le point ou la souris est entree : entree par la droite = balayage vers
       la gauche. C'est ce qui distingue un vrai "balayage d'origine" d'un pan
       qui glisserait toujours depuis le meme bord.
       `transform-origin` s'applique aussi a la propriete `scale`, on garde
       donc `transform` libre pour le magnetique. --- */
.gng-btn-ap-fill-wipe .gng-btn__fill {
    inset: 0;
    border-radius: inherit;
    transform-origin: var(--gng-btn-ox-x, 0%) 50%;
    scale: 0 1;
    opacity: 0;
    transition: scale var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1)),
                opacity calc(var(--gng-btn-ap-speed, 0.45s) * 0.4) ease;
}

.gng-btn-ap-fill-wipe .gng-btn:hover .gng-btn__fill {
    scale: 1 1;
    opacity: 1;
}

/* --- Vague montante : le calque monte par le bas, son bord superieur est
       arrondi, ce qui dessine la vague pendant la montee. --- */
.gng-btn-ap-fill-wave .gng-btn__fill {
    left: -20%;
    right: -20%;
    top: 0;
    height: 100%;
    border-radius: 45% 45% 0 0 / 32% 32% 0 0;
    translate: 0 100%;
    transition: translate var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

.gng-btn-ap-fill-wave .gng-btn:hover .gng-btn__fill {
    translate: 0 0;
}

/* =================================================================
   PILULE QUI S'ELARGIT + FLECHE QUI BASCULE
   -----------------------------------------------------------------
   Ajoute le 2026-08-17. Cet effet n'existait pas : il a ete releve sur
   un composant de reference et n'avait aucun equivalent ici.

   Observe : une pilule et, DETACHE d'elle, un bouton rond portant une
   fleche. Au survol la pilule s'elargit franchement (146 -> 205 px
   mesures) et la fleche bascule de 180 degres.

   Aucune balise ajoutee, et surtout AUCUN reglage de l'utilisateur
   ecrase :
   - la pastille est mise en `position: absolute` a droite du bouton.
     Sortie du flux, elle n'est plus peinte par le fond de la pilule :
     elle se lit comme un bouton rond separe, alors que le HTML n'a pas
     bouge d'un caractere ;
   - l'elargissement est pose sur le CONTENU (`__text`), jamais sur la
     pilule. Ajouter du `padding` a la pilule ecraserait celui que
     l'utilisateur a regle dans Style ; en poussant le contenu, la
     pilule s'elargit d'elle-meme et les reglages restent intacts.
     C'est aussi ce qui pousse la pastille vers la droite, exactement
     comme sur la reference.
   ================================================================= */
.gng-btn-ap-expand-pill .gng-btn {
    position: relative;
    /* La pastille vit en dehors du cadre : surtout ne pas rogner. */
    overflow: visible;
}

.gng-btn-ap-expand-pill .gng-btn__text {
    transition: padding-inline-end var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

.gng-btn-ap-expand-pill .gng-btn:hover .gng-btn__text {
    padding-inline-end: var(--gng-btn-ap-grow, 48px);
}

.gng-btn-ap-expand-pill .gng-btn__icon {
    position: absolute;
    left: 100%;
    top: 50%;
    translate: 0 -50%;
    margin-inline-start: var(--gng-btn-ap-gap, 10px);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    padding: 0.62em;
    border-radius: 50%;
    background-color: var(--gng-btn-ap-color, #d7f751);
    color: var(--gng-btn-ap-icon-color, #0b0b0b);
}

.gng-btn-ap-expand-pill .gng-btn__icon svg { fill: currentColor; }

/* `rotate` est une propriete a part entiere : elle ne se dispute ni le
   `translate` de la pastille ni le `transform` que GSAP utilise pour
   l'effet magnetique. */
.gng-btn-ap-expand-pill .gng-btn__icon svg,
.gng-btn-ap-expand-pill .gng-btn__icon i {
    display: block;
    transition: rotate var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

.gng-btn-ap-expand-pill .gng-btn:hover .gng-btn__icon svg,
.gng-btn-ap-expand-pill .gng-btn:hover .gng-btn__icon i {
    rotate: 180deg;
}

/* =================================================================
   PASTILLE QUI S'INVERSE  (reglage "Pastille d'icone qui s'etend")
   -----------------------------------------------------------------
   REPARE le 2026-08-17 apres observation du composant de reference.
   L'ancienne version ne faisait que teinter la pastille au survol et
   faire pivoter l'icone : ce n'est PAS ce que fait la reference.

   Ce qui a ete reellement observe :
     - la pastille et son icone ECHANGENT leurs couleurs (la pastille
       claire a fleche sombre devient sombre a fleche claire) ;
     - la pastille GROSSIT nettement (pas un 1,12 discret) ;
     - le libelle s'EFFACE presque entierement.
   Le fond du bouton lui-meme s'inverse aussi sur la reference : cela
   se regle deja dans Style > Bouton > Survol, on ne le refait pas ici.

   L'icone ne pivote PAS sur la reference. Le reglage de rotation est
   conserve (on ne supprime jamais un reglage : des pages l'utilisent
   peut-etre) mais il part desormais de 0.
   ================================================================= */
.gng-btn-ap-icon-pop .gng-btn__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    padding: 0.35em;
    border-radius: 50%;
    background-color: var(--gng-btn-ap-color, #ffffff);
    color: var(--gng-btn-ap-icon-color, #0b0b0b);
    /* `color` et `fill` sont repris ici : cette regle est plus specifique que
       la transition generale de l'icone et l'ecraserait sinon, faisant sauter
       le changement de couleur d'un coup sec dans ce mode. */
    /* `rotate` repris ici pour la meme raison que `color` et `fill` : cette
       regle est plus specifique que la transition generale de l icone, et la
       rotation reglee dans le panneau sauterait d un coup sec dans ce mode. */
    transition: background-color var(--gng-btn-ap-speed, 0.45s) ease,
                color var(--gng-btn-ap-speed, 0.45s) ease,
                fill var(--gng-btn-ap-speed, 0.45s) ease,
                rotate var(--gng-btn-ap-speed, 0.45s) ease,
                scale var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

/* L'icone herite de la couleur de la pastille : une seule variable a
   regler, et le SVG suit qu'il soit en `fill` ou en `stroke`. */
.gng-btn-ap-icon-pop .gng-btn__icon svg { fill: currentColor; }

.gng-btn-ap-icon-pop .gng-btn:hover .gng-btn__icon {
    background-color: var(--gng-btn-ap-color-inv, #0b0b0b);
    color: var(--gng-btn-ap-icon-color-inv, #ffffff);
    scale: var(--gng-btn-ap-pop-scale, 1.28);
}

/* Le libelle s'efface pour laisser la pastille prendre la place. */
.gng-btn-ap-icon-pop .gng-btn__label {
    transition: opacity var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

.gng-btn-ap-icon-pop .gng-btn:hover .gng-btn__label {
    opacity: var(--gng-btn-ap-label-fade, 0.08);
}

/* L'icone elle-meme pivote dans sa pastille. `rotate` est une propriete a
   part entiere : elle n'entre pas en conflit avec le `scale` de la pastille
   ni avec le `transform` du magnetique. */
.gng-btn-ap-icon-pop .gng-btn__icon svg,
.gng-btn-ap-icon-pop .gng-btn__icon i {
    transition: rotate var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

.gng-btn-ap-icon-pop .gng-btn:hover .gng-btn__icon svg,
.gng-btn-ap-icon-pop .gng-btn:hover .gng-btn__icon i {
    rotate: var(--gng-btn-ap-rotate, -45deg);
}

/* --- Pastille qui s'efface en diagonale.
       Releve sur le composant de reference : DEUX disques empiles. Celui du
       dessus est visible au repos ; au survol il retrecit a ~15% en filant en
       haut a droite, ce qui decouvre celui du dessous.
       Le disque du dessus est un pseudo-element : aucune balise ajoutee. --- */
.gng-btn-ap-icon-swap .gng-btn__icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    padding: 0.35em;
    border-radius: 50%;
    /* Disque du DESSOUS : celui qu'on decouvre. */
    background-color: var(--gng-btn-ap-color, rgba(255, 255, 255, 0.18));
}

.gng-btn-ap-icon-swap .gng-btn__icon::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background-color: var(--gng-btn-ap-color-top, #ffffff);
    transition: scale var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1)),
                translate var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1)),
                opacity var(--gng-btn-ap-speed, 0.45s) ease;
}

/* L'icone doit rester AU-DESSUS des deux disques. */
.gng-btn-ap-icon-swap .gng-btn__icon svg,
.gng-btn-ap-icon-swap .gng-btn__icon i {
    position: relative;
    z-index: 1;
}

.gng-btn-ap-icon-swap .gng-btn:hover .gng-btn__icon::before {
    scale: 0.15;
    translate: 60% -60%;
    opacity: 0;
}

/* --- Relais de fleche en diagonale, pose avec le soulignement. La fenetre
       masque le debordement : la premiere icone sort en haut a droite pendant
       que sa copie entre par en bas a gauche. --- */
.gng-btn-ap-underline .gng-btn__icon-slot {
    position: relative;
    display: inline-flex;
    overflow: hidden;
    flex: 0 0 auto;
}

.gng-btn-ap-underline .gng-btn__icon-slot .gng-btn__icon {
    transition: translate var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

.gng-btn-ap-underline .gng-btn__icon--dup {
    position: absolute;
    inset: 0;
    translate: -100% 100%;
}

.gng-btn-ap-underline .gng-btn:hover .gng-btn__icon-slot .gng-btn__icon {
    translate: 100% -100%;
}

.gng-btn-ap-underline .gng-btn:hover .gng-btn__icon--dup {
    translate: 0 0;
}

/* --- Lettres en cascade : chaque lettre part avec un retard proportionnel a
       son rang, ce qui dessine une vague de gauche a droite. --- */
.gng-btn-ap-letters .gng-btn__ltr {
    display: inline-block;
    /* white-space: pre evite que le navigateur avale l'espace insecable. */
    white-space: pre;
    transition: translate var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
    transition-delay: calc(var(--gng-btn-ltr, 0) * var(--gng-btn-ap-stagger, 0.03s));
}

/* Le sens vient d'un simple signe (-1 = haut, 1 = bas) : une seule regle
   couvre les deux directions. */
.gng-btn-ap-letters .gng-btn:hover .gng-btn__ltr {
    translate: 0 calc(0.22em * var(--gng-btn-ap-dir, -1));
}

/* --- Lettres qui roulent.
       Structure relevee sur le composant de reference : chaque LETTRE a sa
       propre copie posee juste en dessous, dans une fenetre a debordement
       masque. Au survol la lettre sort, la copie prend sa place. Le
       dedoublement au niveau de la lettre (et non du mot) est ce qui produit
       le roulement en cascade plutot qu'un bloc qui glisse d'un seul tenant.
       --- */
.gng-btn-ap-letters-roll .gng-btn__ltr {
    position: relative;
    display: inline-block;
    overflow: hidden;
    white-space: pre;
    vertical-align: bottom;
}

.gng-btn-ap-letters-roll .gng-btn__g {
    display: block;
    transition: translate var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
    transition-delay: calc(var(--gng-btn-ltr, 0) * var(--gng-btn-ap-stagger, 0.03s));
}

/* La copie attend hors champ, du cote oppose au sens de sortie. */
.gng-btn-ap-letters-roll .gng-btn__g--dup {
    position: absolute;
    inset: 0;
    translate: 0 calc(100% * var(--gng-btn-ap-dir, -1) * -1);
}

.gng-btn-ap-letters-roll .gng-btn:hover .gng-btn__g {
    translate: 0 calc(100% * var(--gng-btn-ap-dir, -1));
}

.gng-btn-ap-letters-roll .gng-btn:hover .gng-btn__g--dup {
    translate: 0 0;
}

/* =================================================================
   ENFONCEMENT AU CLIC
   Place APRES les mouvements de survol : a specificite egale, la derniere
   regle gagne. Le bouton enfonce l'emporte donc sur le bouton survole,
   ce qui est l'ordre attendu (on survole avant de cliquer).
   Les deux selecteurs sont necessaires : avec survol (souris) et sans
   (clavier, ecran tactile).
   ================================================================= */
.gng-btn-press-yes .gng-btn:active,
.gng-btn-press-yes .gng-btn:hover:active {
    scale: var(--gng-btn-press, 0.96);
    /* Reponse immediate : un enfoncement qui traine ne se sent pas. */
    transition-duration: 0.08s;
}

/* =================================================================
   NAVIGATION AU CLAVIER
   `:focus-visible` ne se declenche PAS au clic souris : l'anneau
   n'apparait donc que pour qui navigue au clavier, sans abimer le rendu
   pour les autres. Aucun reglage : un bouton doit rester atteignable.
   ================================================================= */
.gng-btn:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 3px;
}

/* --- Soulignement qui se relaie : deux barres sur le libelle. La premiere
       se retire vers la droite pendant que la seconde entre par la gauche.
       Les pseudo-elements du libelle sont libres (celui du bouton sert deja
       au reflet de lumiere). --- */
.gng-btn-ap-underline .gng-btn__label {
    position: relative;
}

/* `:not(--clone)` : combine au swipe de texte, le libelle est dedouble. Sans
   cette exclusion, la copie porterait elle aussi ses deux barres et on verrait
   un soulignement fantome passer avec elle. C'est exactement la combinaison
   qui reproduit le bouton "trois effets" (texte dedouble + soulignement +
   fleche), donc celle qu'il faut blinder. */
.gng-btn-ap-underline .gng-btn__label:not(.gng-btn__label--clone)::before,
.gng-btn-ap-underline .gng-btn__label:not(.gng-btn__label--clone)::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -0.18em;
    height: 1px;
    background-color: currentColor;
    transition: scale var(--gng-btn-ap-speed, 0.45s) var(--gng-btn-ap-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

.gng-btn-ap-underline .gng-btn__label::before {
    transform-origin: right center;
    scale: 1 1;
}

.gng-btn-ap-underline .gng-btn__label::after {
    transform-origin: left center;
    scale: 0 1;
    /* Entre juste apres que la premiere soit partie : c'est ce decalage qui
       donne l'impression d'un relais, et non d'un simple aller-retour. */
    transition-delay: calc(var(--gng-btn-ap-speed, 0.45s) * 0.35);
}

.gng-btn-ap-underline .gng-btn:hover .gng-btn__label::before { scale: 0 1; }
.gng-btn-ap-underline .gng-btn:hover .gng-btn__label::after  { scale: 1 1; }

/* ============================================================
   VERRE DEPOLI — le fond translucide et la bordure viennent des reglages
   Elementor (portes par .gng-btn-glass-yes, plus specifiques). Il ne reste
   ici que ce qui n'est pas reglable : isoler la couche pour que le flou
   ne bave pas, et neutraliser une ombre portee qui trahirait l'effet.
   ============================================================ */
.gng-btn-glass-yes .gng-btn {
    isolation: isolate;
    -webkit-backdrop-filter: blur(12px);
}

/* ============================================================
   REFLET DE LUMIERE — une bande claire traverse le bouton.
   Trois modes, poses par le controle "Reflet de lumiere" :
     .gng-btn-fx-shine       au survol seulement
     .gng-btn-fx-loop        en boucle, en permanence
     .gng-btn-fx-shine-loop  en boucle, et le passage accelere au survol

   La bande est le MEME pseudo-element dans les trois cas : c'est aussi la
   raison pour laquelle la section transverse "WS Glossy" n'est pas rabattue
   sur ce bouton - elle utiliserait ce meme ::before et l'un ecraserait
   l'autre.
   ============================================================ */
.gng-btn-fx-shine .gng-btn,
.gng-btn-fx-loop .gng-btn,
.gng-btn-fx-shine-loop .gng-btn {
    position: relative;
}

.gng-btn-fx-shine .gng-btn::before,
.gng-btn-fx-loop .gng-btn::before,
.gng-btn-fx-shine-loop .gng-btn::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    /* La bande est centree sur 50% et s'etale de +/- la largeur choisie. */
    background-image: linear-gradient(
        var(--gng-btn-fx-angle, 105deg),
        transparent calc(50% - var(--gng-btn-fx-band, 12) * 1%),
        color-mix(in srgb, var(--gng-btn-fx-color) 70%, transparent) 50%,
        transparent calc(50% + var(--gng-btn-fx-band, 12) * 1%)
    );
    background-repeat: no-repeat;
    background-size: 220% 100%;
    /* Position de repos : hors du bouton, a droite. */
    background-position: 150% 0;
}

/* --- Au survol seulement : une transition suffit, pas d'animation. --- */
.gng-btn-fx-shine .gng-btn::before {
    transition: background-position var(--gng-btn-fx-speed, 0.4s) ease;
}
.gng-btn-fx-shine .gng-btn:hover::before {
    background-position: -50% 0;
}

/* --- En boucle : le passage occupe le debut du cycle, le reste est une
       pause. Aux deux extremites la bande est hors du bouton, le retour a
       la position de depart est donc invisible. --- */
.gng-btn-fx-loop .gng-btn::before,
.gng-btn-fx-shine-loop .gng-btn::before {
    animation: gng-btn-shine-loop var(--gng-btn-fx-loop-speed, 4s) ease-in-out infinite;
}

@keyframes gng-btn-shine-loop {
    0%        { background-position: 150% 0; }
    40%, 100% { background-position: -50% 0; }
}

/* --- Boucle + survol : le cycle s'accelere tant que la souris est dessus.
       On ne cumule pas deux mecanismes sur la meme propriete : on change
       simplement la duree de celui qui tourne deja. --- */
.gng-btn-fx-shine-loop .gng-btn:hover::before {
    animation-duration: var(--gng-btn-fx-speed, 0.4s);
}

@media (prefers-reduced-motion: reduce) {
    .gng-btn,
    .gng-btn-fx-shine .gng-btn::before {
        transition: none !important;
    }

    /* Les apparences restent VISIBLES (l'etat de survol garde son sens), mais
       sans trajet anime : le changement devient instantane. */
    .gng-btn__fill,
    .gng-btn-ap-icon-swap .gng-btn__icon::before,
    .gng-btn-ap-icon-pop .gng-btn__icon,
    .gng-btn-ap-icon-pop .gng-btn__icon svg,
    .gng-btn-ap-icon-pop .gng-btn__icon i,
    .gng-btn-ap-underline .gng-btn__label::before,
    .gng-btn-ap-underline .gng-btn__label::after,
    .gng-btn-ap-underline .gng-btn__icon-slot .gng-btn__icon,
    .gng-btn-ap-letters .gng-btn__ltr,
    .gng-btn-ap-letters-roll .gng-btn__g {
        transition: none !important;
    }

    /* La cascade n'a plus lieu d'etre : les lettres ne bougent pas du tout. */
    .gng-btn-ap-letters .gng-btn:hover .gng-btn__ltr {
        translate: none;
    }

    /* Le reflet en boucle est un mouvement permanent : c'est exactement ce que
       ce reglage systeme demande de supprimer. */
    .gng-btn-fx-loop .gng-btn::before,
    .gng-btn-fx-shine-loop .gng-btn::before,
    .gng-btn-fx-shine-loop .gng-btn:hover::before {
        animation: none;
    }

    /* Le bouton reste parfaitement utilisable : on retire le mouvement,
       pas l'etat de survol (couleurs, fond, bordure restent actifs). */
    .gng-btn-hov-pulse .gng-btn:hover { animation: none; }

    .gng-btn-hov-grow   .gng-btn:hover,
    .gng-btn-hov-shrink .gng-btn:hover { scale: 1; }

    .gng-btn-hov-float  .gng-btn:hover,
    .gng-btn-hov-sink   .gng-btn:hover { translate: none; }
}

/* ============================================================
   WS FONDU SUR LES BORDS - override pour Bouton Magnetique
   ============================================================
   Le mask CSS est pose par defaut sur le widget wrapper (.elementor-element)
/* =================================================================
   EFFETS PERMANENTS - les memes apparences, en boucle.

   Meme vocabulaire que le survol, seul le declencheur change : une
   animation CSS au lieu de :hover. Fonctionne donc AU DOIGT, la ou
   tous les effets de survol sont inertes.

   RYTHME COMMUN, en une seule duree reglable :
     0%   repos  -> 20%  actif   (aller)
     55%  actif  -> 75%  repos   (retour)
     100% repos          (pause avant de recommencer)
   Un seul reglage de temps, pas quatre : les proportions restent
   justes a toutes les vitesses.

   Placees APRES les regles de survol : a specificite egale, la
   derniere gagne. Si les deux sont actifs, la boucle pilote.
   ================================================================= */
.gng-btn {
    --gng-btn-perm-dur: 4s;
    --gng-btn-perm-delay: 0s;
    --gng-btn-perm-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

.gng-btn-perm-fill-center .gng-btn__fill,
.gng-btn-perm-fill-wipe .gng-btn__fill,
.gng-btn-perm-fill-wave .gng-btn__fill,
.gng-btn-perm-icon-pop .gng-btn__icon,
.gng-btn-perm-icon-swap .gng-btn__icon::before,
.gng-btn-perm-underline .gng-btn__label::before,
.gng-btn-perm-underline .gng-btn__label::after,
.gng-btn-perm-letters .gng-btn__ltr,
.gng-btn-perm-letters-roll .gng-btn__g {
    animation-duration: var(--gng-btn-perm-dur, 4s);
    animation-timing-function: var(--gng-btn-perm-ease, cubic-bezier(0.16, 1, 0.3, 1));
    animation-delay: var(--gng-btn-perm-delay, 0s);
    animation-iteration-count: infinite;
}

.gng-btn-perm-fill-center .gng-btn,
.gng-btn-perm-fill-wipe .gng-btn,
.gng-btn-perm-fill-wave .gng-btn {
    position: relative;
    overflow: hidden;
}

.gng-btn-perm-fill-center .gng-btn__fill {
    top: 50%; left: 50%;
    width: 260%; aspect-ratio: 1;
    border-radius: 50%;
    translate: -50% -50%;
    animation-name: gng-btn-perm-disque;
}
@keyframes gng-btn-perm-disque {
    0%, 100% { scale: 0; }
    20%, 55% { scale: 1; }
    75%      { scale: 0; }
}

.gng-btn-perm-fill-wipe .gng-btn__fill {
    inset: 0;
    border-radius: inherit;
    transform-origin: 0% 50%;
    animation-name: gng-btn-perm-balayage;
}
@keyframes gng-btn-perm-balayage {
    0%, 100% { scale: 0 1; opacity: 0; }
    12%      { opacity: 1; }
    20%, 55% { scale: 1 1; opacity: 1; }
    75%      { scale: 1 1; opacity: 0; }
    76%      { scale: 0 1; opacity: 0; }
}

.gng-btn-perm-fill-wave .gng-btn__fill {
    left: -20%; right: -20%; top: 0; height: 100%;
    border-radius: 45% 45% 0 0 / 32% 32% 0 0;
    animation-name: gng-btn-perm-vague;
}
@keyframes gng-btn-perm-vague {
    0%, 100% { translate: 0 100%; }
    20%, 55% { translate: 0 0; }
    75%      { translate: 0 100%; }
}

.gng-btn-perm-icon-pop .gng-btn__icon {
    display: inline-flex; align-items: center; justify-content: center;
    aspect-ratio: 1; padding: 0.35em; border-radius: 50%;
    animation-name: gng-btn-perm-pastille;
}
@keyframes gng-btn-perm-pastille {
    0%, 100% { background-color: transparent; scale: 1; }
    20%, 55% { background-color: var(--gng-btn-ap-color, rgba(255,255,255,.18)); scale: 1.12; }
    75%      { background-color: transparent; scale: 1; }
}

.gng-btn-perm-icon-swap .gng-btn__icon {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    aspect-ratio: 1; padding: 0.35em; border-radius: 50%;
    background-color: var(--gng-btn-ap-color, rgba(255,255,255,.18));
}
.gng-btn-perm-icon-swap .gng-btn__icon::before {
    content: ""; position: absolute; inset: 0; border-radius: 50%;
    background-color: var(--gng-btn-ap-color-top, #ffffff);
    animation-name: gng-btn-perm-diagonale;
}
.gng-btn-perm-icon-swap .gng-btn__icon svg,
.gng-btn-perm-icon-swap .gng-btn__icon i { position: relative; z-index: 1; }
@keyframes gng-btn-perm-diagonale {
    0%, 100% { scale: 1; translate: 0 0; opacity: 1; }
    20%, 55% { scale: .15; translate: 60% -60%; opacity: 0; }
    75%      { scale: 1; translate: 0 0; opacity: 1; }
}

.gng-btn-perm-underline .gng-btn__label { position: relative; }
.gng-btn-perm-underline .gng-btn__label:not(.gng-btn__label--clone)::before,
.gng-btn-perm-underline .gng-btn__label:not(.gng-btn__label--clone)::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -0.18em;
    height: 1px; background-color: currentColor;
}
.gng-btn-perm-underline .gng-btn__label::before {
    transform-origin: right center;
    animation-name: gng-btn-perm-barre-sort;
}
.gng-btn-perm-underline .gng-btn__label::after {
    transform-origin: left center;
    animation-name: gng-btn-perm-barre-entre;
}
@keyframes gng-btn-perm-barre-sort {
    0%, 100% { scale: 1 1; }
    20%, 55% { scale: 0 1; }
    75%      { scale: 1 1; }
}
@keyframes gng-btn-perm-barre-entre {
    0%, 100% { scale: 0 1; }
    25%, 55% { scale: 1 1; }
    78%      { scale: 0 1; }
}

.gng-btn-perm-letters .gng-btn__ltr {
    display: inline-block; white-space: pre;
    animation-name: gng-btn-perm-lettre;
    animation-delay: calc(var(--gng-btn-perm-delay, 0s) + var(--gng-btn-ltr, 0) * var(--gng-btn-ap-stagger, .03s));
}
@keyframes gng-btn-perm-lettre {
    0%, 100% { translate: 0 0; }
    20%, 55% { translate: 0 calc(.22em * var(--gng-btn-ap-dir, -1)); }
    75%      { translate: 0 0; }
}

.gng-btn-perm-letters-roll .gng-btn__ltr {
    position: relative; display: inline-block; overflow: hidden;
    white-space: pre; vertical-align: bottom;
}
.gng-btn-perm-letters-roll .gng-btn__g {
    display: block;
    animation-name: gng-btn-perm-roule;
    animation-delay: calc(var(--gng-btn-perm-delay, 0s) + var(--gng-btn-ltr, 0) * var(--gng-btn-ap-stagger, .03s));
}
.gng-btn-perm-letters-roll .gng-btn__g--dup {
    position: absolute; inset: 0;
    animation-name: gng-btn-perm-roule-dup;
}
@keyframes gng-btn-perm-roule {
    0%, 100% { translate: 0 0; }
    20%, 55% { translate: 0 calc(100% * var(--gng-btn-ap-dir, -1)); }
    75%      { translate: 0 0; }
}
@keyframes gng-btn-perm-roule-dup {
    0%, 100% { translate: 0 calc(100% * var(--gng-btn-ap-dir, -1) * -1); }
    20%, 55% { translate: 0 0; }
    75%      { translate: 0 calc(100% * var(--gng-btn-ap-dir, -1) * -1); }
}

@media (prefers-reduced-motion: reduce) {
    [class*="gng-btn-perm-"] .gng-btn__fill,
    [class*="gng-btn-perm-"] .gng-btn__icon,
    [class*="gng-btn-perm-"] .gng-btn__icon::before,
    [class*="gng-btn-perm-"] .gng-btn__label::before,
    [class*="gng-btn-perm-"] .gng-btn__label::after,
    [class*="gng-btn-perm-"] .gng-btn__ltr,
    [class*="gng-btn-perm-"] .gng-btn__g {
        animation: none !important;
    }
}

/* ============================================================
   EFFET AU CLIC — gerbe de particules

   Une particule est une boite VIDE : sa forme vient d'un `clip-path` ou d'un
   arrondi, jamais d'un SVG pose dans le DOM. Elles sont creees au clic puis
   RETIREES a la fin de leur animation : rien ne subsiste entre deux clics.

   On n'anime que `opacity` et `transform`, ecrits en entier dans les cles :
   les deux seules proprietes que le navigateur confie a la carte graphique.
   Les `var()` sont resolues une fois a la composition, elles ne coutent rien.
   ============================================================ */

/* Le calque suit le bouton. `overflow: visible` est VOLONTAIRE : les
   particules doivent pouvoir sortir du bouton, c'est tout l'interet. */
.gng-btn-burst-layer {
    position: absolute;
    inset: 0;
    overflow: visible;
    pointer-events: none;   /* ne vole jamais un clic au lien */
    z-index: 4;
}

.gng-btn-burst {
    position: absolute;
    width: var(--gng-btn-b-taille, 8px);
    height: var(--gng-btn-b-taille, 8px);
    background-color: var(--gng-btn-b-couleur, currentColor);
    pointer-events: none;
    opacity: 0;
    /* Pas de `will-change` : il reclamerait une couche graphique par particule
       pour une animation qui dure moins d'une seconde. */
}

.gng-btn-burst--rond     { border-radius: 50%; }
.gng-btn-burst--carre    { border-radius: 2px; }
.gng-btn-burst--triangle { clip-path: polygon(50% 0%, 100% 100%, 0% 100%); }
.gng-btn-burst--etoile   {
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%,
                       50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

@keyframes gng-btn-burst {
    0% {
        opacity: 1;
        transform: translate(-50%, -50%) rotate(var(--gng-btn-b-angle, 0deg)) translateX(0) scale(1);
    }
    100% {
        opacity: 0;
        transform: translate(-50%, -50%) rotate(var(--gng-btn-b-angle, 0deg)) translateX(var(--gng-btn-b-portee, 90px)) scale(0.3);
    }
}

/* Mouvement reduit : le script ne cree aucune particule. Cette regle n'est la
   que comme second verrou, si une particule existait deja. */
@media (prefers-reduced-motion: reduce) {
    .gng-btn-burst { animation: none !important; opacity: 0; }
}

/* =================================================================
   OMBRE DURE — le bouton s'enfonce dans son ombre
   -----------------------------------------------------------------
   Le principe tient dans un seul chiffre : la 3e valeur du
   `box-shadow` est a ZERO. C'est le rayon de flou. A zero, l'ombre ne
   diffuse plus : elle pose un aplat net et decale. Du papier decoupe,
   pas du relief lumineux.

   Au survol, le bouton se deplace EXACTEMENT du decalage de l'ombre,
   et l'ombre tombe a zero : il vient occuper la place qu'elle
   laissait. Les deux sont solidaires. Desolidarises, l'oeil verrait
   un bouton qui GLISSE au lieu d'un bouton qui s'ENFONCE - c'est tout
   ce qui separe l'effet reussi de l'effet rate.

   Anime en `translate`, JAMAIS en `transform` : GSAP ecrit dans
   `transform` pour l'effet magnetique. Deux proprietes distinctes,
   elles se composent au lieu de s'ecraser.

   Le reglage "Mouvement du bouton" est masque avec cette apparence :
   il ecrirait dans le meme `translate`.
   ================================================================= */
.gng-btn-ap-shadow-push .gng-btn {
    box-shadow: var(--gng-btn-push-x, 5px) var(--gng-btn-push-y, 6px) 0 var(--gng-btn-push-color, #1E3A2B);
    translate: 0 0;
    transition:
        translate  var(--gng-btn-ap-speed, 0.13s) var(--gng-btn-ap-ease, cubic-bezier(.2, .7, .3, 1)),
        box-shadow var(--gng-btn-ap-speed, 0.13s) var(--gng-btn-ap-ease, cubic-bezier(.2, .7, .3, 1));
}

.gng-btn-ap-shadow-push .gng-btn:hover {
    /* Meme valeurs que le decalage : c'est ce qui donne l'enfoncement. */
    translate: var(--gng-btn-push-x, 5px) var(--gng-btn-push-y, 6px);
    box-shadow: 0 0 0 var(--gng-btn-push-color, #1E3A2B);
}

/* L'inclinaison vit sur l'ENVELOPPE (reglage "Inclinaison") : le bouton
   garde ainsi `translate` libre pour s'enfoncer, les deux mouvements ne
   se disputent aucune propriete. */
.gng-btn-ap-shadow-push .gng-btn-wrap {
    display: inline-block;
}

@media (prefers-reduced-motion: reduce) {
    .gng-btn-ap-shadow-push .gng-btn { transition: none; }
    /* L'ombre disparait quand meme : l'etat survole reste signale,
       sans deplacement. */
    .gng-btn-ap-shadow-push .gng-btn:hover { translate: none; }
}

/* ==========================================================================
   VEILLE DES ANIMATIONS PERMANENTES
   `gng-hors-vue` est posee par le script quand l'element quitte l'ecran,
   `gng-onglet-cache` sur la racine quand l'onglet passe en arriere-plan. Une
   animation qu'on ne voit pas ne doit pas composer d'image : c'est ce qui
   faisait tourner 100 boucles en continu sur une page.
   Sans le script, aucune de ces classes n'existe et tout joue normalement.
   ========================================================================== */
.gng-hors-vue,
.gng-hors-vue *,
.gng-onglet-cache .gng-marquee *,
.gng-onglet-cache [class*="gng-idle-"],
.gng-onglet-cache [class*="gng-btn-perm-"] * {
    animation-play-state: paused !important;
}

/* ####################################################################
   REPRIS DE ws-effets-bouton.css
   Chez WS Booster, cet effet vit dans le socle partage par tous les
   boutons du plugin. Ici il n'y a qu'un bloc bouton : il n'y a donc
   pas de socle a partager, et l'effet vient se ranger a la suite.
   #################################################################### */

/* ====================================================================
   LA GELEE QUI SUIT LE CURSEUR

   Deux formes de MEME couleur, passees dans un filtre qui les floute puis
   remonte brutalement le contraste : la ou les deux flous se touchent, le
   seuil les recolle en une seule masse. C'est ce recollage qui donne
   l'impression d'un liquide, alors qu'il n'y a aucune simulation.

   LE FILTRE N'EST POSE QU'AU SURVOL, et c'est deliberé. Un flou recalcule
   a chaque image est le geste le plus cher du catalogue (la regle du plus cher geste) :
   sur la petite surface d'un bouton et seulement quand le pointeur est
   dessus, il est abordable ; en permanence, il ne le serait pas.

   LE LIBELLE N'EST JAMAIS FILTRE. Il vit au-dessus de la couche liquide,
   net. Sans cela le texte serait flou et illisible pendant tout le survol.
   ==================================================================== */
[data-gng-btn-gelee] {
    position: relative;
}

/* La couche liquide deborde largement : la bulle doit pouvoir sortir du
   bouton sans etre coupee, c'est meme tout l'interet de l'effet. */
.gng-btn__goo {
    position: absolute;
    inset: calc(-1 * var(--gng-btn-goo-debord, 70px));
    pointer-events: none;
    z-index: 0;
    /* L'ARRONDI DOIT TRAVERSER DEUX NIVEAUX.
       La valeur heritee vient du PARENT DIRECT, pas d'un ancetre lointain :
       sans ce relais, le corps prendrait celle de la couche liquide - dont
       l'arrondi vaut zero - et se dessinerait CARRE derriere un bouton
       arrondi. Avec le filtre, ses angles depasseraient franchement.
       La couche n'a aucun fond : son propre arrondi ne se voit pas, il ne
       sert qu'a etre transmis. */
    border-radius: inherit;
}

/* Le filtre arrive avec la classe posee par le script, jamais avant. */
.gng-btn--gelee-active .gng-btn__goo {
    filter: url(#gng-btn-gelee);
}

/* Le corps recouvre exactement le bouton : c'est la masse a laquelle la
   bulle vient se raccrocher. */
.gng-btn__goo-corps {
    position: absolute;
    inset: var(--gng-btn-goo-debord, 70px);
    border-radius: inherit;
    background: var(--gng-btn-goo-couleur, currentColor);
}

/* La bulle est centree sur le bouton au repos, et le script la deplace en
   ecrivant deux variables. Le retour au centre passe par une transition
   plus longue que le suivi : le pointeur parti, elle revient mollement. */
.gng-btn__goo-bulle {
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--gng-btn-goo-taille, 70px);
    height: var(--gng-btn-goo-taille, 70px);
    margin: calc(-.5 * var(--gng-btn-goo-taille, 70px)) 0 0 calc(-.5 * var(--gng-btn-goo-taille, 70px));
    border-radius: 50%;
    background: var(--gng-btn-goo-couleur, currentColor);
    translate: var(--gng-btn-goo-x, 0px) var(--gng-btn-goo-y, 0px);
    scale: 0;
    transition: scale var(--gng-btn-goo-souplesse, .45s) cubic-bezier(.34, 1.56, .64, 1),
                translate var(--gng-btn-goo-souplesse, .45s) cubic-bezier(.16, 1, .3, 1);
}

.gng-btn--gelee-active .gng-btn__goo-bulle {
    scale: 1;
}

/* Le contenu reste net et au-dessus de la couche liquide. */
[data-gng-btn-gelee] > *:not(.gng-btn__goo) {
    position: relative;
    z-index: 1;
}

/* Le bouton respire legerement, comme une matiere souple qu'on effleure. */
[data-gng-btn-gelee] {
    transition: scale var(--gng-btn-goo-souplesse, .45s) cubic-bezier(.34, 1.56, .64, 1);
}
.gng-btn--gelee-active {
    scale: var(--gng-btn-goo-gonfle, 1.02);
}
[data-gng-btn-gelee]:active {
    scale: var(--gng-btn-goo-presse, .94);
}

/* REPLI SANS FILTRE.
   `filter: url()` echoue sur certaines combinaisons - notamment quand un
   ancetre porte deja une transformation. Le script le detecte et pose cette
   classe : la bulle devient un simple rond net, le bouton reste un bouton.
   Rien ne casse, on perd seulement la fusion. */
.gng-btn--gelee-sansfiltre .gng-btn__goo {
    filter: none;
}
.gng-btn--gelee-sansfiltre .gng-btn__goo-bulle {
    opacity: .55;
}

@media (prefers-reduced-motion: reduce) {
    .gng-btn__goo {
        display: none !important;
    }
    [data-gng-btn-gelee],
    .gng-btn--gelee-active {
        scale: 1 !important;
        transition: none !important;
    }
}
