/* =====================================================================
 * JDW – Titre à Effets — Feuille de style des effets
 * ---------------------------------------------------------------------
 * Chaque effet est piloté par des variables CSS injectées en inline
 * par le widget (--fx-c1, --fx-c2, --fx-speed, --fx-shift, etc.).
 * Les classes de déclenchement (--trigger-*) décident QUAND l'animation
 * tourne : en continu, au survol, ou à l'apparition (classe is-active
 * ajoutée par le JS via IntersectionObserver).
 * ===================================================================== */

.jdw-heading-title {
	margin: 0;
}

/* Conteneur générique d'un fragment animé. */
.jdw-fx {
	position: relative;
	display: inline-block;
	/* Valeurs par défaut au cas où l'inline-style manque. */
	--fx-speed: 6s;
	--fx-c1: #ff0069;
	--fx-c2: #00e5ff;
	--fx-shift: 4px;
}

/* =====================================================================
 * 1) EFFET GLITCH  (réplique de la maquette Figma « DU BRUIT. »)
 * ===================================================================== */
/*
 * SEO : le texte n'est présent QU'UNE fois dans le DOM (le contenu du span).
 * Les deux calques colorés sont des pseudo-éléments dont le texte vient de
 * l'attribut data-text (généré en CSS, donc NON indexé comme texte dupliqué).
 * isolation:isolate confine les pseudo-calques (z-index négatif) derrière le
 * texte réel sans passer derrière l'arrière-plan du conteneur.
 */
.jdw-fx--glitch {
	isolation: isolate;
}

.jdw-fx--glitch::before,
.jdw-fx--glitch::after {
	content: attr(data-text);
	position: absolute;
	inset: 0;
	z-index: -1; /* derrière le texte réel */
	user-select: none;
	pointer-events: none;
}

.jdw-fx--glitch::before {
	color: var(--fx-c1);
}

.jdw-fx--glitch::after {
	color: var(--fx-c2);
}

/* -- Déclenchement EN CONTINU -- */
.jdw-fx--glitch.jdw-fx--trigger-always::before {
	animation: jdw-glitch-1 var(--fx-speed) infinite ease;
}
.jdw-fx--glitch.jdw-fx--trigger-always::after {
	animation: jdw-glitch-2 var(--fx-speed) infinite ease;
	animation-delay: calc(var(--fx-speed) * 0.05);
}

/* -- Déclenchement AU SURVOL -- */
.jdw-fx--glitch.jdw-fx--trigger-hover:hover::before {
	animation: jdw-glitch-1 var(--fx-speed) infinite ease;
}
.jdw-fx--glitch.jdw-fx--trigger-hover:hover::after {
	animation: jdw-glitch-2 var(--fx-speed) infinite ease;
	animation-delay: calc(var(--fx-speed) * 0.05);
}

/* -- Déclenchement À L'APPARITION (.is-active posé par le JS) -- */
.jdw-fx--glitch.jdw-fx--trigger-inview.is-active::before {
	animation: jdw-glitch-1 var(--fx-speed) infinite ease;
}
.jdw-fx--glitch.jdw-fx--trigger-inview.is-active::after {
	animation: jdw-glitch-2 var(--fx-speed) infinite ease;
	animation-delay: calc(var(--fx-speed) * 0.05);
}

/*
 * Keyframes glitch : décalage horizontal des calques colorés + découpe
 * de bandes via clip-path, pour l'effet « écran cassé ».
 * --fx-shift contrôle l'amplitude.
 */
@keyframes jdw-glitch-1 {
	0%, 100%   { transform: translate(0); clip-path: inset(0 0 0 0); }
	8%         { transform: translate(calc(var(--fx-shift) * -1), 1px); clip-path: inset(20% 0 50% 0); }
	16%        { transform: translate(var(--fx-shift), -1px); clip-path: inset(60% 0 10% 0); }
	24%        { transform: translate(calc(var(--fx-shift) * -0.5), 0); clip-path: inset(10% 0 70% 0); }
	32%        { transform: translate(var(--fx-shift), 1px); clip-path: inset(40% 0 30% 0); }
	40%        { transform: translate(0); clip-path: inset(0 0 0 0); }
	/* le reste du cycle reste calme → impulsions périodiques */
}

@keyframes jdw-glitch-2 {
	0%, 100%   { transform: translate(0); clip-path: inset(0 0 0 0); }
	10%        { transform: translate(var(--fx-shift), -1px); clip-path: inset(70% 0 5% 0); }
	18%        { transform: translate(calc(var(--fx-shift) * -1), 1px); clip-path: inset(30% 0 45% 0); }
	26%        { transform: translate(calc(var(--fx-shift) * 0.5), 0); clip-path: inset(55% 0 25% 0); }
	34%        { transform: translate(calc(var(--fx-shift) * -1), -1px); clip-path: inset(15% 0 65% 0); }
	42%        { transform: translate(0); clip-path: inset(0 0 0 0); }
}

/* =====================================================================
 * 2) EFFET NÉON  (lueur clignotante)
 * ===================================================================== */
.jdw-fx--neon {
	color: var(--fx-neon);
}

.jdw-fx--neon.jdw-fx--trigger-always,
.jdw-fx--neon.jdw-fx--trigger-hover:hover,
.jdw-fx--neon.jdw-fx--trigger-inview.is-active {
	animation: jdw-neon var(--fx-speed) infinite ease-in-out;
}

@keyframes jdw-neon {
	0%, 100% {
		text-shadow:
			0 0 4px var(--fx-neon),
			0 0 11px var(--fx-neon),
			0 0 19px var(--fx-neon),
			0 0 40px var(--fx-neon);
		opacity: 1;
	}
	45% {
		text-shadow:
			0 0 4px var(--fx-neon),
			0 0 11px var(--fx-neon),
			0 0 19px var(--fx-neon),
			0 0 40px var(--fx-neon);
		opacity: 1;
	}
	48% { text-shadow: none; opacity: 0.75; }
	50% {
		text-shadow:
			0 0 4px var(--fx-neon),
			0 0 11px var(--fx-neon),
			0 0 19px var(--fx-neon);
		opacity: 1;
	}
	53% { text-shadow: none; opacity: 0.8; }
}

/* =====================================================================
 * 3) DÉGRADÉ ANIMÉ  (texte rempli d'un dégradé qui défile)
 * ===================================================================== */
.jdw-fx--gradient {
	background-image: linear-gradient( var(--fx-angle, 90deg), var(--fx-from), var(--fx-to), var(--fx-from) );
	background-size: 200% 100%;
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}

.jdw-fx--gradient.jdw-fx--trigger-always,
.jdw-fx--gradient.jdw-fx--trigger-hover:hover,
.jdw-fx--gradient.jdw-fx--trigger-inview.is-active {
	animation: jdw-gradient var(--fx-speed) infinite linear;
}

@keyframes jdw-gradient {
	0%   { background-position: 0% 50%; }
	100% { background-position: 200% 50%; }
}

/* =====================================================================
 * 3 bis) DÉGRADÉ STATIQUE  (remplissage fixe, sans animation)
 * ===================================================================== */
.jdw-fx--gradient_static {
	background-image: linear-gradient( var(--fx-angle, 90deg), var(--fx-from), var(--fx-to) );
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}

/* =====================================================================
 * 4) BALAYAGE LUMINEUX  (reflet qui traverse le texte)
 * ===================================================================== */
.jdw-fx--shine {
	background-image: linear-gradient(
		120deg,
		currentColor 0%,
		currentColor 40%,
		var(--fx-shine) 50%,
		currentColor 60%,
		currentColor 100%
	);
	background-size: 250% 100%;
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

.jdw-fx--shine.jdw-fx--trigger-always,
.jdw-fx--shine.jdw-fx--trigger-hover:hover,
.jdw-fx--shine.jdw-fx--trigger-inview.is-active {
	animation: jdw-shine var(--fx-speed) infinite ease-in-out;
}

@keyframes jdw-shine {
	0%   { background-position: 150% 0; }
	100% { background-position: -50% 0; }
}

/* =====================================================================
 * ACCESSIBILITÉ — respect de prefers-reduced-motion
 * On coupe les animations mais on conserve les couleurs/lueurs statiques.
 * ===================================================================== */
@media ( prefers-reduced-motion: reduce ) {
	.jdw-fx--glitch::before,
	.jdw-fx--glitch::after {
		animation: none !important;
		opacity: 0 !important; /* on masque les calques glitch décalés */
	}
	.jdw-fx--neon,
	.jdw-fx--gradient,
	.jdw-fx--shine {
		animation: none !important;
	}
}
