/*
 * ANIMATIONS DU CMS — même feuille pour le site public et l'éditeur. Règles et garde-fous :
 * apps/shared/cmsAnimations.js (attributs data-cyb-* posés sur la racine des blocs, directive v-cyb-anime).
 *
 * Les apparitions et les boucles animent les propriétés individuelles (translate, scale, rotate) et
 * jamais « transform » : celle-ci reste au bloc (rotation, décalage, survol réglés dans l'inspecteur).
 * Avant (« .cms-anim »), l'animation gardait « transform: translateY(0) » à la fin : l'effet de survol
 * des cartes animées (soulèvement, zoom) ne se voyait plus.
 */

/* ─── 1. Rien ne passe d'un bloc à ses enfants : un titre animé dans une section animée garde SES réglages. */
[data-type] {
    --cyb-delai: initial; --cyb-decalage: initial; --cyb-duree: initial; --cyb-courbe: initial;
    --cyb-accent: initial; --cyb-b-duree: initial; --cyb-b-delai: initial; --cyb-b-courbe: initial;
    --cyb-nom: initial; --cyb-duree-defaut: initial; --cyb-courbe-defaut: initial; --cyb-b-duree-defaut: initial;
    --cyb-o: initial; --cyb-t: initial; --cyb-s: initial; --cyb-r: initial; --cyb-f: initial; --cyb-3d: initial; --cyb-c: initial; --cyb-c-fin: initial;
    --cyb-to: initial; --cyb-tt: initial; --cyb-ts: initial; --cyb-tr: initial; --cyb-tf: initial;
    --cyb-trait-h: initial; --cyb-trait-y: initial; --cyb-trait-couleur: initial;
    --cyb-a-entree: initial; --cyb-a-boucle: initial; --cyb-boucle-nom: initial;
    --cyb-dy: initial; --cyb-dx: initial; --cyb-sc: initial; --cyb-rz: initial; --cyb-rx: initial; --cyb-op: initial;
    --cyb-filtre: initial; --cyb-decoupe: initial; --cyb-bgy: initial;
    --cyb-hx: initial; --cyb-hy: initial; --cyb-mx: initial; --cyb-my: initial;
}

:root {
    --cyb-douce: cubic-bezier(0.16, 1, 0.3, 1);
    --cyb-ressort: cubic-bezier(0.34, 1.56, 0.64, 1);
    --cyb-rebond: linear(0, 0.063, 0.25 18.2%, 0.563, 1 36.4%, 0.813, 0.75, 0.813, 1 63.6%, 0.938, 1 81.8%, 0.984, 1);
}

/* ─── 2. Apparitions (animation) : l'état de départ ; l'arrivée est l'état normal du bloc. */
[data-cyb-entree] { --cyb-nom: cyb-entree; }
[data-cyb-entree="fade-in"] { --cyb-o: 0; }
[data-cyb-entree="fade-in-up"] { --cyb-o: 0; --cyb-t: 0 40px; }
[data-cyb-entree="fade-in-down"] { --cyb-o: 0; --cyb-t: 0 -40px; }
[data-cyb-entree="fade-in-left"] { --cyb-o: 0; --cyb-t: -56px 0; }
[data-cyb-entree="fade-in-right"] { --cyb-o: 0; --cyb-t: 56px 0; }
[data-cyb-entree="blur-in"] { --cyb-o: 0; --cyb-f: blur(16px); --cyb-s: 1.04; --cyb-duree-defaut: 1000ms; }
[data-cyb-entree="rise"] { --cyb-o: 0; --cyb-t: 0 80px; --cyb-s: 0.96; --cyb-f: blur(6px); --cyb-duree-defaut: 1200ms; }
[data-cyb-entree="zoom-in"] { --cyb-o: 0; --cyb-s: 0.86; }
[data-cyb-entree="zoom-out"] { --cyb-o: 0; --cyb-s: 1.14; }
[data-cyb-entree="pop"] { --cyb-o: 0; --cyb-s: 0.55; --cyb-courbe-defaut: var(--cyb-ressort); --cyb-duree-defaut: 700ms; }
[data-cyb-entree="slide-up"] { --cyb-o: 0; --cyb-t: 0 160px; --cyb-duree-defaut: 1100ms; }
[data-cyb-entree="drop-in"] { --cyb-o: 0; --cyb-t: 0 -110px; --cyb-courbe-defaut: var(--cyb-rebond); --cyb-duree-defaut: 1200ms; }
[data-cyb-entree="rotate-in"] { --cyb-o: 0; --cyb-r: -14deg; --cyb-s: 0.88; --cyb-courbe-defaut: var(--cyb-ressort); }
/* 3D : la perspective n'existe que dans « transform » (le temps de l'animation seulement). */
[data-cyb-entree="flip-up"] { --cyb-nom: cyb-entree-3d; --cyb-o: 0; --cyb-3d: perspective(1100px) translateY(40px) rotateX(65deg); --cyb-duree-defaut: 1100ms; }
[data-cyb-entree="flip-left"] { --cyb-nom: cyb-entree-3d; --cyb-o: 0; --cyb-3d: perspective(1100px) rotateY(-70deg); --cyb-duree-defaut: 1100ms; }
/* Rideaux : le bloc se découvre sans fondu. */
[data-cyb-entree^="reveal-"] { --cyb-nom: cyb-entree-rideau; --cyb-duree-defaut: 1100ms; --cyb-courbe-defaut: cubic-bezier(0.77, 0, 0.175, 1); }
[data-cyb-entree="reveal-up"] { --cyb-c: inset(100% 0 0 0); }
[data-cyb-entree="reveal-down"] { --cyb-c: inset(0 0 100% 0); }
[data-cyb-entree="reveal-left"] { --cyb-c: inset(0 100% 0 0); }
[data-cyb-entree="reveal-right"] { --cyb-c: inset(0 0 0 100%); }
[data-cyb-entree="reveal-center"] { --cyb-c: inset(0 50% 0 50%); }
[data-cyb-entree="reveal-circle"] { --cyb-c: circle(0% at 50% 50%); --cyb-c-fin: circle(75% at 50% 50%); }

@keyframes cyb-entree { from { opacity: var(--cyb-o, 1); translate: var(--cyb-t, none); scale: var(--cyb-s, none); rotate: var(--cyb-r, none); filter: var(--cyb-f, none); } }
@keyframes cyb-entree-3d { from { opacity: var(--cyb-o, 1); transform: var(--cyb-3d); } }
@keyframes cyb-entree-rideau { from { clip-path: var(--cyb-c); } to { clip-path: var(--cyb-c-fin, inset(0 0 0 0)); } }

/* En attente d'arriver à l'écran : seulement invisible (sa place et sa taille ne changent pas). */
[data-cyb-entree][data-cyb-etat="attente"] { opacity: 0 !important; }
[data-cyb-entree][data-cyb-etat="joue"] {
    --cyb-a-entree: var(--cyb-nom, cyb-entree) var(--cyb-duree, var(--cyb-duree-defaut, 850ms)) var(--cyb-courbe, var(--cyb-courbe-defaut, var(--cyb-douce))) calc(var(--cyb-delai, 0ms) + var(--cyb-decalage, 0ms)) 1 normal backwards;
}
/* Apparition et boucle dans UNE déclaration : deux règles « animation » sur le même bloc, la seconde effaçait la première. */
[data-cyb-entree][data-cyb-etat="joue"],
[data-cyb-boucle] {
    animation: var(--cyb-a-entree, none), var(--cyb-a-boucle, none);
}

/* ─── 3. Boucles (loopAnimation) : elles partent une fois l'apparition terminée. */
[data-cyb-boucle]:not([data-cyb-etat="attente"]) {
    --cyb-a-boucle: var(--cyb-boucle-nom, none) var(--cyb-b-duree, var(--cyb-b-duree-defaut, 4s)) var(--cyb-b-courbe, ease-in-out) var(--cyb-b-delai, 0ms) infinite;
}
[data-cyb-boucle][data-cyb-entree] { --cyb-b-delai: calc(var(--cyb-delai, 0ms) + var(--cyb-decalage, 0ms) + var(--cyb-duree, var(--cyb-duree-defaut, 850ms))); }
[data-cyb-boucle="float"] { --cyb-boucle-nom: cyb-b-flotte; --cyb-b-duree-defaut: 6s; }
[data-cyb-boucle="pulse"] { --cyb-boucle-nom: cyb-b-pulse; --cyb-b-duree-defaut: 2.4s; }
[data-cyb-boucle="bounce"] { --cyb-boucle-nom: cyb-b-rebond; --cyb-b-duree-defaut: 2.2s; }
[data-cyb-boucle="swing"] { --cyb-boucle-nom: cyb-b-balancier; --cyb-b-duree-defaut: 3s; transform-origin: 50% 0; }
[data-cyb-boucle="spin"] { --cyb-boucle-nom: cyb-b-tourne; --cyb-b-duree-defaut: 18s; --cyb-b-courbe: linear; }
[data-cyb-boucle="glow"] { --cyb-boucle-nom: cyb-b-halo; --cyb-b-duree-defaut: 2.6s; }
[data-cyb-boucle="shake"] { --cyb-boucle-nom: cyb-b-secousse; --cyb-b-duree-defaut: 4s; --cyb-b-courbe: linear; }
/* Fond dégradé qui ondule : le fond est peint par l'enveloppe du bloc (le lien pour un bouton). */
[data-cyb-boucle="gradient-shift"] { --cyb-boucle-nom: none; }
[data-cyb-boucle="gradient-shift"]:not([data-type="button"]) > *,
[data-cyb-boucle="gradient-shift"][data-type="button"] a {
    background-size: 220% 220% !important;
    animation: cyb-b-degrade var(--cyb-b-duree, 8s) ease-in-out infinite;
}

@keyframes cyb-b-flotte { 0%, 100% { translate: 0 0; } 50% { translate: 0 -14px; } }
@keyframes cyb-b-pulse { 0%, 100% { scale: 1; } 50% { scale: 1.06; } }
@keyframes cyb-b-rebond { 0%, 50%, 100% { translate: 0 0; } 22% { translate: 0 -18px; } 36% { translate: 0 0; } 43% { translate: 0 -6px; } }
@keyframes cyb-b-balancier { 0%, 100% { rotate: -5deg; } 50% { rotate: 5deg; } }
@keyframes cyb-b-tourne { from { rotate: 0deg; } to { rotate: 360deg; } }
@keyframes cyb-b-halo { 0%, 100% { filter: drop-shadow(0 0 0 rgba(0, 0, 0, 0)); } 50% { filter: drop-shadow(0 0 18px var(--cyb-accent, rgba(167, 139, 250, 0.85))); } }
@keyframes cyb-b-secousse { 0%, 84%, 100% { translate: 0 0; } 86% { translate: -6px 0; } 88% { translate: 6px 0; } 90% { translate: -5px 0; } 92% { translate: 5px 0; } 94% { translate: -2px 0; } 96% { translate: 2px 0; } }
@keyframes cyb-b-degrade { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }

/* ─── 4. Effets de texte (textAnimation) — texte découpé par texteAnime() : .cyb-txt > .cyb-m (mot) > .cyb-u | .cyb-l */
.cyb-txt .cyb-m { display: inline-block; white-space: nowrap; }
.cyb-txt .cyb-u, .cyb-txt .cyb-l { display: inline-block; position: relative; }

/* Lettres et mots en cascade */
:is([data-cyb-texte^="letters-"], [data-cyb-texte^="words-"])[data-cyb-etat="attente"] :is(.cyb-u, .cyb-l) { opacity: 0; }
:is([data-cyb-texte^="letters-"], [data-cyb-texte^="words-"])[data-cyb-etat="joue"] :is(.cyb-u, .cyb-l) {
    animation: cyb-unite var(--cyb-duree, var(--cyb-duree-defaut, 700ms)) var(--cyb-courbe, var(--cyb-courbe-defaut, var(--cyb-douce))) calc(var(--cyb-delai, 0ms) + var(--cyb-decalage, 0ms) + var(--i, 0) * var(--cyb-pas, 40ms)) 1 normal backwards;
}
@keyframes cyb-unite { from { opacity: var(--cyb-to, 0); translate: var(--cyb-tt, none); scale: var(--cyb-ts, none); rotate: var(--cyb-tr, none); filter: var(--cyb-tf, none); } }

/* « Qui montent » : chaque lettre (ou mot) sort d'une fente invisible, sans fondu. */
[data-cyb-texte="letters-rise"], [data-cyb-texte="words-rise"] { --cyb-to: 1; --cyb-tt: 0 110%; --cyb-duree-defaut: 850ms; }
:is([data-cyb-texte="letters-rise"], [data-cyb-texte="words-rise"]) .cyb-m { clip-path: inset(-0.5em -0.3em -0.22em -0.3em); }
[data-cyb-texte="letters-fade"] { --cyb-tt: 0 0.3em; --cyb-duree-defaut: 650ms; }
[data-cyb-texte="letters-blur"] { --cyb-tf: blur(10px); --cyb-ts: 1.6; --cyb-duree-defaut: 900ms; }
[data-cyb-texte="letters-drop"] { --cyb-tt: 0 -1.2em; --cyb-courbe-defaut: var(--cyb-rebond); --cyb-duree-defaut: 950ms; }
[data-cyb-texte="letters-flip"] { --cyb-tr: x 95deg; --cyb-duree-defaut: 800ms; }
[data-cyb-texte="letters-flip"] .cyb-m { perspective: 500px; }
[data-cyb-texte="words-fade"] { --cyb-tf: blur(12px); --cyb-tt: 0 0.4em; --cyb-duree-defaut: 1000ms; }
[data-cyb-texte="words-pop"] { --cyb-ts: 0.3; --cyb-courbe-defaut: var(--cyb-ressort); --cyb-duree-defaut: 650ms; }

/* Machine à écrire : les lettres arrivent une à une, le curseur les suit puis clignote après la dernière. */
[data-cyb-texte="typewriter"][data-cyb-etat="attente"] .cyb-l { opacity: 0; }
[data-cyb-texte="typewriter"][data-cyb-etat="joue"] .cyb-l {
    animation: cyb-cache 1ms linear calc(var(--cyb-delai, 0ms) + var(--cyb-decalage, 0ms) + var(--i, 0) * var(--cyb-pas, 55ms)) 1 normal backwards;
}
[data-cyb-texte="typewriter"] .cyb-l::after {
    content: ""; position: absolute; top: 0.12em; bottom: 0.1em; right: -0.06em; width: 0.07em; min-width: 2px;
    background: var(--cyb-accent, currentColor); opacity: 0; pointer-events: none;
}
[data-cyb-texte="typewriter"][data-cyb-etat="joue"] .cyb-l::after {
    animation: cyb-curseur var(--cyb-pas, 55ms) linear calc(var(--cyb-delai, 0ms) + var(--cyb-decalage, 0ms) + var(--i, 0) * var(--cyb-pas, 55ms)) 1;
}
[data-cyb-texte="typewriter"][data-cyb-etat="joue"] .cyb-l.cyb-fin::after {
    animation: cyb-clignote 1.05s linear calc(var(--cyb-delai, 0ms) + var(--cyb-decalage, 0ms) + var(--i, 0) * var(--cyb-pas, 55ms)) infinite;
}
@keyframes cyb-cache { from, to { opacity: 0; } }
@keyframes cyb-curseur { from, to { opacity: 1; } }
@keyframes cyb-clignote { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }

/* Décodage (les signes tirés au hasard sont posés par cmsAnimations.js) */
[data-cyb-texte="scramble"][data-cyb-etat="attente"] .cyb-l { opacity: 0; }
[data-cyb-texte="scramble"][data-cyb-etat="joue"] .cyb-l {
    animation: cyb-unite 300ms ease-out calc(var(--cyb-delai, 0ms) + var(--cyb-decalage, 0ms) + var(--i, 0) * var(--cyb-pas, 40ms) * 0.4) 1 normal backwards;
}
/* Compteur : caché jusqu'à son arrivée, puis les chiffres partent de zéro (cmsAnimations.js) */
[data-cyb-texte="counter"][data-cyb-etat="attente"] .cyb-txt { opacity: 0; }
:is([data-cyb-texte="counter"], [data-cyb-texte="scramble"]) .cyb-txt { font-variant-numeric: tabular-nums; }

/* Surligneur et soulignement : le trait se dessine quand le texte arrive à l'écran (le texte reste lisible avant). */
[data-cyb-texte="highlight"] { --cyb-trait-h: 0.42em; --cyb-trait-y: 88%; --cyb-trait-couleur: color-mix(in srgb, var(--cyb-accent, #facc15) 48%, transparent); --cyb-duree-defaut: 1100ms; }
[data-cyb-texte="underline"] { --cyb-trait-h: 0.08em; --cyb-trait-y: 100%; --cyb-trait-couleur: var(--cyb-accent, currentColor); --cyb-duree-defaut: 900ms; }
:is([data-cyb-texte="highlight"], [data-cyb-texte="underline"]) .cyb-txt {
    background-image: linear-gradient(var(--cyb-trait-couleur), var(--cyb-trait-couleur));
    background-repeat: no-repeat;
    background-position: 0 var(--cyb-trait-y);
    background-size: 100% var(--cyb-trait-h);
}
:is([data-cyb-texte="highlight"], [data-cyb-texte="underline"])[data-cyb-etat="attente"] .cyb-txt { background-size: 0% var(--cyb-trait-h); }
:is([data-cyb-texte="highlight"], [data-cyb-texte="underline"])[data-cyb-etat="joue"] .cyb-txt {
    animation: cyb-trait var(--cyb-duree, var(--cyb-duree-defaut, 1000ms)) var(--cyb-courbe, cubic-bezier(0.65, 0, 0.35, 1)) calc(var(--cyb-delai, 0ms) + var(--cyb-decalage, 0ms)) 1 normal backwards;
}
@keyframes cyb-trait { from { background-size: 0% var(--cyb-trait-h); } }

/* En continu : la couleur du texte reste « currentColor » (seul le remplissage devient transparent). */
[data-cyb-texte="gradient-flow"] .cyb-txt {
    background-image: linear-gradient(90deg, currentColor 0%, var(--cyb-accent, #a78bfa) 25%, currentColor 50%, var(--cyb-accent, #a78bfa) 75%, currentColor 100%);
    background-size: 200% 100%;
    -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
    animation: cyb-flux var(--cyb-b-duree, 6s) linear infinite;
}
@keyframes cyb-flux { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }
[data-cyb-texte="shimmer"] .cyb-txt {
    background-image: linear-gradient(105deg, currentColor 0%, currentColor 42%, var(--cyb-accent, #ffffff) 50%, currentColor 58%, currentColor 100%);
    background-size: 250% 100%;
    -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
    animation: cyb-reflet var(--cyb-b-duree, 3.4s) ease-in-out infinite;
}
@keyframes cyb-reflet { 0% { background-position: 100% 50%; } 55%, 100% { background-position: 0% 50%; } }
[data-cyb-texte="wave"] .cyb-l { animation: cyb-vague var(--cyb-b-duree, 1.8s) ease-in-out calc(var(--i, 0) * var(--cyb-pas, 70ms)) infinite; }
@keyframes cyb-vague { 0%, 45%, 100% { translate: 0 0; } 22% { translate: 0 -0.2em; } }
[data-cyb-texte="neon"] .cyb-txt {
    --cyb-lueur: var(--cyb-accent, currentColor);
    text-shadow: 0 0 4px var(--cyb-lueur), 0 0 14px var(--cyb-lueur), 0 0 34px var(--cyb-lueur);
    animation: cyb-neon var(--cyb-b-duree, 4s) linear infinite;
}
@keyframes cyb-neon {
    0%, 18%, 22%, 25%, 53%, 57%, 100% { text-shadow: 0 0 4px var(--cyb-lueur), 0 0 14px var(--cyb-lueur), 0 0 34px var(--cyb-lueur); opacity: 1; }
    20%, 24%, 55% { text-shadow: none; opacity: 0.8; }
}
[data-cyb-texte="glitch"] .cyb-txt { animation: cyb-glitch var(--cyb-b-duree, 3.2s) steps(1, end) infinite; }
@keyframes cyb-glitch {
    0%, 82%, 97%, 100% { text-shadow: none; }
    83% { text-shadow: -3px 0 rgba(255, 45, 85, 0.85), 3px 0 rgba(0, 229, 255, 0.85); }
    86% { text-shadow: 3px 1px rgba(255, 45, 85, 0.85), -3px -1px rgba(0, 229, 255, 0.85); }
    89% { text-shadow: -2px -1px rgba(255, 45, 85, 0.85), 2px 1px rgba(0, 229, 255, 0.85); }
    92% { text-shadow: 2px 0 rgba(255, 45, 85, 0.85), -2px 0 rgba(0, 229, 255, 0.85); }
}

/* ─── 5. Effets au défilement (scrollEffect) — valeurs calculées à chaque image par cmsAnimations.js.
   Les déplacements du bloc passent par sa « transform » (transformAnimee) ; ici, le reste. */
[data-cyb-defil="fade"] { opacity: var(--cyb-op, 1); }
[data-cyb-defil="blur"] { filter: var(--cyb-filtre, none); }
[data-cyb-defil="reveal"] { clip-path: var(--cyb-decoupe, none); }
/* Une image bouge DANS son cadre (agrandie pour ne jamais montrer de bord vide). */
[data-cyb-cible="image"] img { scale: var(--cyb-sc, 1); translate: 0 var(--cyb-dy, 0px); }
/* Image agrandie dans son cadre (parallaxe, zoom) : le cadre garde les coins arrondis du bloc. */
:is([data-cyb-cible="image"], [data-cyb-survol="zoom-image"]) > div { border-radius: inherit; }
/* Image de fond d'une section ou d'un conteneur : elle glisse dans la marge que lui laisse « cover ». */
[data-cyb-cible="fond"] > * { background-position-y: var(--cyb-bgy, 50%) !important; }

/* ─── 6. Survol (hoverEffect) — jamais dans l'éditeur, jamais sur la carte du tunnel de réservation. */
[data-cyb-survol="lift"]:hover { translate: 0 -6px; filter: drop-shadow(0 18px 24px rgba(15, 23, 42, 0.18)); }
[data-cyb-survol="glow"]:hover { filter: drop-shadow(0 0 14px var(--cyb-accent, rgba(167, 139, 250, 0.8))); }
[data-cyb-survol="zoom-image"] img { transition: scale 0.7s var(--cyb-douce); }
[data-cyb-survol="zoom-image"]:hover img { scale: 1.08; }
[data-cyb-survol="shine"][data-type="button"] a { position: relative; }
[data-cyb-survol="shine"]:not([data-type="button"])::after,
[data-cyb-survol="shine"][data-type="button"] a::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 1;
    background: linear-gradient(110deg, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 60%) no-repeat;
    background-size: 250% 100%;
    background-position: 130% 0;
    transition: background-position 0.9s var(--cyb-douce);
}
[data-cyb-survol="shine"]:not([data-type="button"]):hover::after,
[data-cyb-survol="shine"][data-type="button"]:hover a::after { background-position: -30% 0; }

/* ─── 7. « Réduire les animations » (réglage du système) et impression : tout visible, rien ne bouge. */
@media (prefers-reduced-motion: reduce) {
    html [data-cyb-etat][data-cyb-etat], html [data-cyb-etat] :is(.cyb-txt, .cyb-u, .cyb-l) { opacity: 1 !important; }
    html [data-cyb-entree], html [data-cyb-boucle], html [data-cyb-boucle] > *, html [data-cyb-boucle] a, .cyb-txt, .cyb-txt *, .cyb-txt *::after { animation: none !important; }
    html :is([data-cyb-texte="highlight"], [data-cyb-texte="underline"]) .cyb-txt { background-size: 100% var(--cyb-trait-h) !important; }
}
@media print {
    html [data-cyb-etat][data-cyb-etat], html [data-cyb-etat] :is(.cyb-txt, .cyb-u, .cyb-l) { opacity: 1 !important; }
    html [data-cyb-entree], html [data-cyb-boucle], .cyb-txt, .cyb-txt *, .cyb-txt *::after { animation: none !important; }
}
