/*
 * ProgresSport — Collection PRESTIGE
 *
 * 25 bordures d'avatar et 20 animations du bouton « Générer ».
 *
 * Ce qui les distingue des collections précédentes : celles-ci ne se contentent
 * pas de changer de teinte. Chaque pièce a un MÉCANISME propre — un point qui
 * orbite, deux anneaux qui tournent en sens inverse, une comète avec sa traîne,
 * un vitrail à arêtes franches… C'est le mouvement qui fait la différence, pas
 * la couleur.
 *
 * Contraintes tenues :
 *  - jamais de `filter` sur .pp-avatar-wrap (ça déteindrait sur la photo) ;
 *  - les décors passent par ::before / ::after, la photo reste au-dessus ;
 *  - tout est coupé sous `prefers-reduced-motion` (bloc en fin de fichier) ;
 *  - on n'anime que `background-position`, `opacity`, `transform` et l'angle
 *    `--pp-a`, jamais une propriété qui force un recalcul de mise en page.
 *
 * @package ProgresSport
 */

@property --pp-a {
	syntax: '<angle>';
	initial-value: 0deg;
	inherits: false;
}

@keyframes pp-pr-rotate  { to { --pp-a: 360deg; } }
@keyframes pp-pr-rotate-r { to { --pp-a: -360deg; } }
@keyframes pp-pr-sweep   { to { background-position: 300% 50%; } }
@keyframes pp-pr-spin    { to { transform: rotate(360deg); } }
@keyframes pp-pr-spin-r  { to { transform: rotate(-360deg); } }
@keyframes pp-pr-breathe { 0%, 100% { transform: scale(1); opacity: 0.55; } 50% { transform: scale(1.14); opacity: 0.95; } }
@keyframes pp-pr-blink   { 0%, 82%, 100% { opacity: 0; } 86%, 94% { opacity: 1; } }
@keyframes pp-pr-wave    { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }

/* =========================================================================
 * 1. BORDURES PRESTIGE — 25 pièces
 *
 * Base commune. Les couleurs arrivent en variables depuis PHP (attribut
 * `style`), la classe ne décide que du MOUVEMENT. Une même mécanique décline
 * ainsi proprement sur toute la palette du pass.
 * ====================================================================== */

/*
 * L'anneau passe de 3 à 4,5 px. C'est la leçon de la première version : à 3 px,
 * un point qui orbite, trois anneaux concentriques ou un vitrail ne se voient
 * tout simplement PAS — toutes les bordures se ressemblaient. Le mécanisme a
 * besoin de place pour exister.
 */
.pp-ab {
	position: relative;
	padding: 4.5px;
	border-radius: 50%;
	isolation: isolate;
	--a1: #7ad0ff;
	--a2: #2b7fe0;
	--a3: #0b2a5e;
	--sp: 5s;
}

/*
 * Deux couches décoratives par bordure. `z-index: -1` les place au-dessus du
 * fond de l'anneau mais SOUS la photo — c'est `isolation: isolate` sur .pp-ab
 * qui garde ce -1 à l'intérieur de la bordure au lieu de l'envoyer derrière
 * toute la page.
 */
.pp-ab::before,
.pp-ab::after {
	content: "";
	position: absolute;
	border-radius: 50%;
	pointer-events: none;
	z-index: -1;
}

.pp-ab::before { inset: 0; }
.pp-ab::after  { inset: -5px; }

/*
 * PETITS avatars : 4,5 px d'anneau autour d'une photo de 40 px, c'est un
 * huitième de l'image — la bordure mangerait le visage. On l'affine partout où
 * l'avatar est réduit : carte de profil, classement, amis, membres d'un groupe.
 * Les trois mécanismes qui demandaient plus d'épaisseur (double anneau,
 * anneaux, séquence) reviennent au même trait : à cette taille, la finesse
 * compte plus que le détail.
 */
.pp-home-profile .pp-ab,
.pp-c-row .pp-ab,
.pp-friend .pp-ab,
.pp-grp-member .pp-ab {
	padding: 2.5px;
}

/* --- 1. Orbite — un point lumineux fait le tour de l'anneau. ------------- */
.pp-ab--orbite {
	background: conic-gradient(from var(--pp-a), var(--a3), var(--a2) 70%, var(--a1) 88%, #fff 94%, var(--a3) 100%);
	animation: pp-pr-rotate var(--sp) linear infinite;
}
.pp-ab--orbite::after {
	background: radial-gradient(circle at 50% 4%, #fff, var(--a1) 26%, transparent 55%);
	opacity: 0.75;
	animation: pp-pr-spin var(--sp) linear infinite;
}

/* --- 2. Comète — une tête vive suivie d'une traîne qui s'éteint. --------- */
.pp-ab--comete {
	background: conic-gradient(from var(--pp-a),
		transparent 0deg, var(--a3) 30deg, var(--a2) 200deg, var(--a1) 320deg, #fff 350deg, transparent 360deg);
	animation: pp-pr-rotate var(--sp) linear infinite;
}
.pp-ab--comete::after {
	background: conic-gradient(from var(--pp-a), transparent 300deg, var(--a1) 352deg, transparent 360deg);
	opacity: 0.5;
	animation: pp-pr-rotate var(--sp) linear infinite;
}

/* --- 3. Double — un anneau intérieur et un extérieur, sens contraires. --- */
.pp-ab--double {
	padding: 6px;
	background: conic-gradient(from var(--pp-a), var(--a3) 0 40%, var(--a1) 50%, var(--a3) 60% 100%);
	animation: pp-pr-rotate var(--sp) linear infinite;
}
.pp-ab--double::before {
	/*
	 * L'anneau intérieur est SÉPARÉ du grand par un filet sombre, et il tourne
	 * en sens inverse. Sans ce filet, les deux se fondaient en un seul gros
	 * anneau : on voyait bien une couleur, jamais deux cercles.
	 */
	inset: 2.5px;
	background: conic-gradient(from var(--pp-a), var(--a3) 0 25%, #ffffff 42%, var(--a2) 58%, var(--a3) 75% 100%);
	box-shadow: 0 0 0 1.5px rgba(6, 10, 16, 0.85);
	animation: pp-pr-rotate-r calc(var(--sp) * 0.6) linear infinite;
}

/* --- 4. Pointillé — huit tirets qui tournent d'un bloc. ----------------- */
.pp-ab--pointille {
	background: conic-gradient(from var(--pp-a),
		var(--a1) 0 22deg, transparent 22deg 45deg, var(--a1) 45deg 67deg, transparent 67deg 90deg,
		var(--a2) 90deg 112deg, transparent 112deg 135deg, var(--a2) 135deg 157deg, transparent 157deg 180deg,
		var(--a1) 180deg 202deg, transparent 202deg 225deg, var(--a1) 225deg 247deg, transparent 247deg 270deg,
		var(--a2) 270deg 292deg, transparent 292deg 315deg, var(--a2) 315deg 337deg, transparent 337deg 360deg);
	animation: pp-pr-rotate calc(var(--sp) * 1.6) linear infinite;
}

/* --- 5. Pulse — un halo qui respire autour de la photo. ----------------- */
.pp-ab--pulse {
	background: linear-gradient(135deg, var(--a1), var(--a2) 55%, var(--a3));
}
.pp-ab--pulse::after {
	inset: -7px;
	background: radial-gradient(circle, transparent 58%, var(--a2) 74%, transparent 88%);
	animation: pp-pr-breathe calc(var(--sp) * 0.55) ease-in-out infinite;
}

/* --- 6. Prisme — irisation d'huile, très lente. ------------------------- */
.pp-ab--prisme {
	/* Aucun voile blanc par-dessus : la première version en avait un, et il
	   délavait complètement l'arc-en-ciel. Les couleurs restent pures. */
	background: conic-gradient(from var(--pp-a),
		#ff0059, #ff8a00, #ffe600, #00e06a, #00c2ff, #7b2bff, #ff0059);
	animation: pp-pr-rotate calc(var(--sp) * 2.2) linear infinite;
	box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}

/* --- 7. Or noir — anneau sombre traversé d'un éclat doré. --------------- */
.pp-ab--or-noir {
	background: linear-gradient(100deg,
		#14181d 0%, #14181d 34%, #f5c518 46%, #fff3c4 51%, #f5c518 56%, #14181d 68%, #14181d 100%);
	background-size: 300% 100%;
	animation: pp-pr-sweep calc(var(--sp) * 0.9) linear infinite;
	box-shadow: 0 0 10px rgba(245, 197, 24, 0.45);
}

/* --- 8. Cristal — facettes à arêtes franches, rotation saccadée douce. -- */
.pp-ab--cristal {
	background: conic-gradient(from var(--pp-a),
		var(--a1) 0 40deg, #fff 40deg 52deg, var(--a2) 52deg 100deg, var(--a3) 100deg 150deg,
		#fff 150deg 158deg, var(--a1) 158deg 220deg, var(--a2) 220deg 280deg, #fff 280deg 290deg,
		var(--a3) 290deg 360deg);
	animation: pp-pr-rotate calc(var(--sp) * 1.4) linear infinite;
}

/* --- 9. Braise — anneau sombre où des points chauds palpitent. ---------- */
.pp-ab--braise {
	background: radial-gradient(circle, #2a1206 55%, #7a2708 72%, #1a0b04 100%);
}
.pp-ab--braise::before {
	background: conic-gradient(from var(--pp-a),
		transparent 0 18deg, #ff7a18 18deg 30deg, transparent 30deg 96deg,
		#ffb347 96deg 106deg, transparent 106deg 190deg,
		#ff5a00 190deg 202deg, transparent 202deg 288deg,
		#ffcc66 288deg 296deg, transparent 296deg 360deg);
	animation: pp-pr-rotate calc(var(--sp) * 1.1) linear infinite;
}
.pp-ab--braise::after {
	inset: -6px;
	background: radial-gradient(circle, transparent 60%, rgba(255, 110, 0, 0.5) 76%, transparent 90%);
	animation: pp-pr-breathe calc(var(--sp) * 0.4) ease-in-out infinite;
}

/* --- 10. Nébuleuse — nuages colorés qui dérivent. ----------------------- */
.pp-ab--nebuleuse {
	background:
		radial-gradient(circle at 25% 30%, var(--a1), transparent 45%),
		radial-gradient(circle at 75% 68%, var(--a2), transparent 48%),
		radial-gradient(circle at 60% 20%, #fff6, transparent 35%),
		var(--a3);
	background-size: 200% 200%, 220% 220%, 180% 180%, 100% 100%;
	animation: pp-pr-wave calc(var(--sp) * 2.6) ease-in-out infinite;
}

/* --- 11. Foudre — l'anneau reste calme, puis un arc blanc claque. ------- */
.pp-ab--foudre {
	/* Ciel d'orage : sombre, avec une trouée claire. L'anneau doit déjà être
	   beau AVANT que l'éclair ne claque — sinon, entre deux flashes, il n'y a
	   rien à regarder. */
	background: conic-gradient(from var(--pp-a),
		#0b1220, var(--a3) 20%, var(--a2) 42%, #cfe9ff 50%, var(--a2) 58%, var(--a3) 80%, #0b1220);
	animation: pp-pr-rotate calc(var(--sp) * 2.4) linear infinite;
}
.pp-ab--foudre::before {
	background: conic-gradient(from 20deg,
		transparent 0 8deg, #fff 8deg 12deg, transparent 12deg 130deg,
		#eaf6ff 130deg 134deg, transparent 134deg 250deg,
		#fff 250deg 255deg, transparent 255deg 360deg);
	animation: pp-pr-blink calc(var(--sp) * 0.8) linear infinite;
}
.pp-ab--foudre::after {
	inset: -6px;
	background: radial-gradient(circle, transparent 62%, rgba(180, 225, 255, 0.75) 76%, transparent 88%);
	opacity: 0;
	animation: pp-pr-blink calc(var(--sp) * 0.8) linear infinite;
}

/* --- 12. Vague — un reflet monte et redescend sans fin. ----------------- */
.pp-ab--vague {
	/* Le dégradé va du plus sombre au blanc pur : sans cet écart, la vague
	   restait invisible sur une image fixe. */
	background: linear-gradient(160deg,
		#06121f 0%, var(--a3) 18%, var(--a2) 34%, var(--a1) 46%, #ffffff 52%,
		var(--a1) 58%, var(--a2) 70%, var(--a3) 84%, #06121f 100%);
	background-size: 100% 340%;
	animation: pp-pr-wave calc(var(--sp) * 1.2) ease-in-out infinite;
}

/* --- 13. Séquence — six segments s'allument l'un après l'autre. --------- */
.pp-ab--sequence {
	padding: 6px;
	background: conic-gradient(
		var(--a3) 0 56deg, transparent 56deg 60deg, var(--a3) 60deg 116deg, transparent 116deg 120deg,
		var(--a3) 120deg 176deg, transparent 176deg 180deg, var(--a3) 180deg 236deg, transparent 236deg 240deg,
		var(--a3) 240deg 296deg, transparent 296deg 300deg, var(--a3) 300deg 356deg, transparent 356deg 360deg);
}
.pp-ab--sequence::before {
	/* Le segment allumé est blanc au centre : il doit se détacher franchement
	   des cinq segments éteints, sinon on ne voit pas qu'il se déplace. */
	background: conic-gradient(from var(--pp-a),
		var(--a1) 0 20deg, #fff 20deg 36deg, var(--a1) 36deg 56deg, transparent 56deg 360deg);
	animation: pp-pr-rotate var(--sp) steps(6) infinite;
}

/* --- 14. Mercure — métal liquide, reflets qui glissent. ----------------- */
.pp-ab--mercure {
	background: linear-gradient(120deg,
		#5b6672 0%, #aeb9c6 14%, #ffffff 22%, #8d99a8 34%, #4a545f 48%,
		#c8d2dc 62%, #ffffff 70%, #7a8593 82%, #444d57 100%);
	background-size: 280% 280%;
	animation: pp-pr-wave var(--sp) ease-in-out infinite;
	box-shadow: 0 0 8px rgba(200, 215, 230, 0.5);
}

/* --- 15. Laurier — double filet doré, très sobre. ----------------------- */
.pp-ab--laurier {
	padding: 4px;
	background: conic-gradient(from var(--pp-a), #8a6100, #f5c518 25%, #fff6cc 32%, #f5c518 45%, #8a6100 70%, #f5c518 100%);
	animation: pp-pr-rotate calc(var(--sp) * 1.8) linear infinite;
}
.pp-ab--laurier::before {
	inset: 2px;
	box-shadow: inset 0 0 0 1px rgba(255, 246, 204, 0.9);
	background: none;
}

/* --- 16. Spectre — voile blanc qui tourne sur un fond profond. ---------- */
.pp-ab--spectre {
	background: radial-gradient(circle, var(--a3) 60%, #05070c 100%);
}
.pp-ab--spectre::before {
	/* Voile plein et non translucide : à travers un anneau de 4 px, un blanc à
	   15 % d'opacité ne se voyait pas du tout. */
	background: conic-gradient(from var(--pp-a),
		transparent 0 40deg, rgba(255, 255, 255, 0.35) 80deg, #ffffff 130deg,
		rgba(255, 255, 255, 0.35) 180deg, transparent 230deg 360deg);
	animation: pp-pr-rotate calc(var(--sp) * 1.5) linear infinite;
}

/* --- 17. Feu follet — trois lucioles qui tournent à des vitesses différentes. */
.pp-ab--feu-follet {
	background: linear-gradient(135deg, var(--a3), var(--a2));
}
.pp-ab--feu-follet::before {
	background:
		radial-gradient(circle at 50% 2%, #fff, var(--a1) 20%, transparent 42%),
		radial-gradient(circle at 96% 62%, #fff, var(--a1) 18%, transparent 38%);
	animation: pp-pr-spin var(--sp) linear infinite;
}
.pp-ab--feu-follet::after {
	inset: -3px;
	background: radial-gradient(circle at 12% 76%, #fff, var(--a1) 16%, transparent 34%);
	animation: pp-pr-spin-r calc(var(--sp) * 1.7) linear infinite;
}

/* --- 18. Anneaux — trois cercles concentriques très fins. --------------- */
.pp-ab--anneaux {
	padding: 7px;
	background: conic-gradient(from var(--pp-a), var(--a3), var(--a1) 50%, var(--a3));
	animation: pp-pr-rotate calc(var(--sp) * 2) linear infinite;
}
.pp-ab--anneaux::before {
	/*
	 * Les filets séparateurs sont SOMBRES, pas blancs. Le blanc marchait sur
	 * les palettes foncées et disparaissait sur les claires — or la teinte
	 * change à chaque palier. Un filet presque noir tient sur les deux.
	 */
	inset: 0;
	background: none;
	box-shadow:
		inset 0 0 0 2px rgba(6, 10, 16, 0.9),
		inset 0 0 0 4.5px transparent,
		inset 0 0 0 6.5px rgba(6, 10, 16, 0.9);
}

/* --- 19. Soleil — rayons qui s'étirent vers l'extérieur. ---------------- */
.pp-ab--soleil {
	background: radial-gradient(circle, #fff3c4 40%, #f5c518 62%, #e08a00 100%);
}
.pp-ab--soleil::after {
	inset: -8px;
	background: conic-gradient(
		transparent 0 8deg, rgba(245, 197, 24, 0.75) 8deg 12deg, transparent 12deg 38deg,
		rgba(245, 197, 24, 0.75) 38deg 42deg, transparent 42deg 68deg,
		rgba(245, 197, 24, 0.75) 68deg 72deg, transparent 72deg 98deg,
		rgba(245, 197, 24, 0.75) 98deg 102deg, transparent 102deg 128deg,
		rgba(245, 197, 24, 0.75) 128deg 132deg, transparent 132deg 158deg,
		rgba(245, 197, 24, 0.75) 158deg 162deg, transparent 162deg 188deg,
		rgba(245, 197, 24, 0.75) 188deg 192deg, transparent 192deg 218deg,
		rgba(245, 197, 24, 0.75) 218deg 222deg, transparent 222deg 248deg,
		rgba(245, 197, 24, 0.75) 248deg 252deg, transparent 252deg 278deg,
		rgba(245, 197, 24, 0.75) 278deg 282deg, transparent 282deg 308deg,
		rgba(245, 197, 24, 0.75) 308deg 312deg, transparent 312deg 338deg,
		rgba(245, 197, 24, 0.75) 338deg 342deg, transparent 342deg 360deg);
	animation: pp-pr-spin calc(var(--sp) * 3) linear infinite;
}

/* --- 20. Abysse — bleu très profond, une bande claire passe lentement. -- */
.pp-ab--abysse {
	background: linear-gradient(110deg,
		#020b1c 0%, #06255c 30%, #0a4ea8 46%, #4fb8ff 52%, #0a4ea8 58%, #06255c 74%, #020b1c 100%);
	background-size: 320% 100%;
	animation: pp-pr-sweep calc(var(--sp) * 1.8) linear infinite;
}

/* --- 21. Runes — tirets alternés de deux couleurs, rotation inverse. ---- */
.pp-ab--runes {
	background: conic-gradient(from var(--pp-a),
		var(--a1) 0 14deg, transparent 14deg 30deg, var(--a2) 30deg 44deg, transparent 44deg 60deg,
		var(--a1) 60deg 74deg, transparent 74deg 90deg, var(--a2) 90deg 104deg, transparent 104deg 120deg,
		var(--a1) 120deg 134deg, transparent 134deg 150deg, var(--a2) 150deg 164deg, transparent 164deg 180deg,
		var(--a1) 180deg 194deg, transparent 194deg 210deg, var(--a2) 210deg 224deg, transparent 224deg 240deg,
		var(--a1) 240deg 254deg, transparent 254deg 270deg, var(--a2) 270deg 284deg, transparent 284deg 300deg,
		var(--a1) 300deg 314deg, transparent 314deg 330deg, var(--a2) 330deg 344deg, transparent 344deg 360deg);
	animation: pp-pr-rotate-r calc(var(--sp) * 2) linear infinite;
}
.pp-ab--runes::before {
	background: radial-gradient(circle, transparent 62%, var(--a3) 100%);
	opacity: 0.5;
}

/* --- 22. Vitrail — verre coloré serti de plomb. ------------------------- */
.pp-ab--vitrail {
	background: conic-gradient(from var(--pp-a),
		#e63946 0 44deg, #1d1d1d 44deg 48deg, #f4a261 48deg 92deg, #1d1d1d 92deg 96deg,
		#2a9d8f 96deg 140deg, #1d1d1d 140deg 144deg, #264653 144deg 188deg, #1d1d1d 188deg 192deg,
		#8367c7 192deg 236deg, #1d1d1d 236deg 240deg, #e9c46a 240deg 284deg, #1d1d1d 284deg 288deg,
		#3ab5f7 288deg 332deg, #1d1d1d 332deg 336deg, #e63946 336deg 360deg);
	animation: pp-pr-rotate calc(var(--sp) * 3) linear infinite;
}

/* --- 23. Plume — dégradé doux mais lisible, mouvement très lent. -------- */
.pp-ab--plume {
	background: linear-gradient(135deg,
		var(--a3), var(--a2) 18%, #ffffff 34%, var(--a1) 50%, #ffffff 66%, var(--a2) 82%, var(--a3));
	background-size: 260% 260%;
	animation: pp-pr-wave calc(var(--sp) * 3.5) ease-in-out infinite;
}

/* --- 24. Éclipse — disque noir, un croissant lumineux en fait le tour. -- */
.pp-ab--eclipse {
	padding: 5.5px;
	background: #0a0d12;
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}
.pp-ab--eclipse::before {
	/* Croissant plus large et plus lumineux : sur 60° et en blanc franc, il se
	   lit enfin sur le disque noir. */
	background: conic-gradient(from var(--pp-a),
		transparent 0 280deg, var(--a2) 300deg, var(--a1) 325deg, #ffffff 350deg, transparent 360deg);
	animation: pp-pr-rotate var(--sp) linear infinite;
}
.pp-ab--eclipse::after {
	inset: -5px;
	background: radial-gradient(circle, transparent 62%, rgba(255, 255, 255, 0.4) 76%, transparent 92%);
}

/* --- 25. Diamant — éclats blancs qui scintillent à contretemps. --------- */
.pp-ab--diamant {
	/* Base assombrie : sur un anneau tout gris clair, des éclats blancs ne se
	   voyaient pas. Il faut du contraste pour qu'un scintillement scintille. */
	background: conic-gradient(from var(--pp-a),
		#2b3a4d, #ffffff 10%, #486079 26%, #ffffff 42%, #2b3a4d 58%, #ffffff 76%, #486079 90%, #2b3a4d 100%);
	animation: pp-pr-rotate calc(var(--sp) * 1.3) linear infinite;
	box-shadow: 0 0 12px rgba(215, 235, 255, 0.85);
}
.pp-ab--diamant::before {
	background:
		radial-gradient(circle at 50% 2%, #fff, transparent 22%),
		radial-gradient(circle at 90% 74%, #fff, transparent 20%),
		radial-gradient(circle at 10% 70%, #fff, transparent 19%);
	animation: pp-pr-blink calc(var(--sp) * 0.5) linear infinite;
}

/* =========================================================================
 * 2. ANIMATIONS DU BOUTON « GÉNÉRER » — 20 pièces
 *
 * Chaque animation repeint le bouton ET lui ajoute un mouvement. Le fond du
 * bouton doit passer devant celui du thème : d'où les `!important`, déjà la
 * convention des animations existantes dans equipment.css.
 * ====================================================================== */

@keyframes pp-pg-shift   { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
@keyframes pp-pg-slide   { to { background-position: 300% 50%; } }
@keyframes pp-pg-halo    { 0%, 100% { opacity: 0.35; transform: scale(1); } 50% { opacity: 0.9; transform: scale(1.06); } }
@keyframes pp-pg-float   { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
@keyframes pp-pg-tilt    { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(-0.8deg); } 75% { transform: rotate(0.8deg); } }
@keyframes pp-pg-flash   { 0%, 88%, 100% { opacity: 0; } 92%, 96% { opacity: 1; } }
@keyframes pp-pg-orbit   { to { transform: rotate(360deg); } }

/* Socle commun aux 20 : le bouton porte le décor, le halo vit sur le wrap. */
[class*="pp-gen-anim--pr-"] .pp-btn--gen-fx {
	color: #fff;
	border: 0;
	text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
	background-size: 100% 100% !important;
	/* Les couches de scène vivent DANS la pilule : elles sont coupées à
	   son contour, comme l'eau dans un verre. */
	overflow: hidden;
}

/*
 * Deux couches de scène à l'intérieur du bouton. `z-index: -1` dans le
 * contexte d'empilement du bouton = au-dessus de son fond, SOUS son texte :
 * le mot « Générer » reste lisible quoi qu'il se passe derrière.
 */
[class*="pp-gen-anim--pr-"] .pp-btn--gen-fx::before,
[class*="pp-gen-anim--pr-"] .pp-btn--gen-fx::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: -1;
}

[class*="pp-gen-anim--pr-"]::before {
	opacity: 1;
	inset: 2px;
	animation: pp-pg-halo 2.4s ease-in-out infinite;
}

/* Mécanismes partagés par plusieurs scènes. */
@keyframes pp-pg-twinkle { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }
@keyframes pp-pg-drift   { from { transform: translateX(-6px); } to { transform: translateX(6px); } }
@keyframes pp-pg-ring    { 0% { transform: scale(0.3); opacity: 1; } 100% { transform: scale(2.6); opacity: 0; } }

/* ---- Particules propres à la collection (émises par levels.js) --------- */

/* Trait de vent : file de gauche à droite et s'étire. */
.pp-gen-particle--gust {
	width: 34px;
	height: 2px;
	margin: -1px 0 0 -17px;
	border-radius: 999px;
	background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.95), transparent);
	animation: pp-p-gust var(--pp-dur, 0.9s) ease-out forwards;
}
@keyframes pp-p-gust {
	0%   { transform: translate(0, 0) scaleX(0.3); opacity: 0; }
	20%  { opacity: 0.95; }
	100% { transform: translate(var(--pp-x, 90px), var(--pp-y, -6px)) scaleX(1.4); opacity: 0; }
}

/* Grain de sable : emporté de côté, retombe en fin de course. */
.pp-gen-particle--grain {
	width: 3px;
	height: 3px;
	margin: -1.5px 0 0 -1.5px;
	border-radius: 50%;
	background: var(--pp-color, #f2d29b);
	box-shadow: 0 0 2px rgba(120, 80, 20, 0.45);
	animation: pp-p-grain var(--pp-dur, 1s) ease-in forwards;
}
@keyframes pp-p-grain {
	0%   { transform: translate(0, 0); opacity: 0; }
	15%  { opacity: 1; }
	100% { transform: translate(var(--pp-x, 90px), calc(var(--pp-y, 0px) + 22px)); opacity: 0; }
}

/* Vague de chaleur : nappe floue qui monte en ondulant. */
.pp-gen-particle--haze {
	width: 46px;
	height: 10px;
	margin: -5px 0 0 -23px;
	border-radius: 50%;
	background: radial-gradient(ellipse, rgba(255, 255, 255, 0.6), rgba(255, 220, 160, 0.25) 60%, transparent 75%);
	filter: blur(2px);
	animation: pp-p-haze var(--pp-dur, 1.6s) ease-out forwards;
}
@keyframes pp-p-haze {
	0%   { transform: translate(0, 0) skewX(-8deg) scale(0.6); opacity: 0; }
	20%  { opacity: 0.9; }
	50%  { transform: translate(calc(var(--pp-x, 0px) * 0.4), calc(var(--pp-y, -70px) * 0.5)) skewX(8deg) scale(1); }
	100% { transform: translate(var(--pp-x, 0px), var(--pp-y, -70px)) skewX(-8deg) scale(1.3); opacity: 0; }
}

/* ---- Piste gratuite : 10 scènes lumineuses et lisibles ----------------- */

/* 1. Aube — le soleil se lève derrière l'horizon, ses rayons tournent. */
.pp-gen-anim--pr-aube .pp-btn--gen-fx {
	background: linear-gradient(180deg, #5b3a7a 0%, #ff6a88 45%, #ffb36b 76%, #ffe4a8 100%) !important;
	box-shadow: 0 0 18px rgba(255, 150, 110, 0.5);
}
.pp-gen-anim--pr-aube .pp-btn--gen-fx::before {
	inset: auto;
	left: 50%;
	bottom: -14px;
	width: 34px;
	height: 34px;
	margin-left: -17px;
	border-radius: 50%;
	background: radial-gradient(circle, #fff7d6, #ffd36b 55%, rgba(255, 160, 80, 0) 72%);
	box-shadow: 0 0 16px 6px rgba(255, 200, 120, 0.7);
	animation: pp-pg-sunrise 6s ease-in-out infinite;
}
.pp-gen-anim--pr-aube .pp-btn--gen-fx::after {
	inset: -60%;
	background: repeating-conic-gradient(from 0deg, rgba(255, 255, 255, 0.22) 0 6deg, transparent 6deg 20deg);
	opacity: 0.6;
	animation: pp-pr-spin 18s linear infinite;
}
@keyframes pp-pg-sunrise { 0%, 100% { transform: translateY(16px); } 50% { transform: translateY(-8px); } }
.pp-gen-anim--pr-aube::before { background: radial-gradient(circle, rgba(255, 106, 136, 0.6), transparent 70%); }

/* 2. Cascade — filets d'eau qui tombent en continu, écume en bas. */
.pp-gen-anim--pr-cascade .pp-btn--gen-fx {
	background: linear-gradient(180deg, #1263c4 0%, #2f9de8 50%, #a8edea 100%) !important;
	text-shadow: 0 1px 3px rgba(0, 40, 90, 0.75);
	box-shadow: 0 0 18px rgba(56, 182, 255, 0.55);
}
.pp-gen-anim--pr-cascade .pp-btn--gen-fx::before {
	/* Filets d'eau : traits verticaux fins et espacés (masque) dont la
	   matière défile vers le bas — la tuile fait 28 px, le déplacement
	   aussi, la boucle est invisible. Discrets exprès : c'est le mot qui
	   doit rester lisible, pas l'eau qui doit crier. */
	background: repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.42) 0 12px, rgba(255, 255, 255, 0.03) 12px 28px);
	-webkit-mask: repeating-linear-gradient(90deg, #000 0 1.5px, transparent 1.5px 9px, #000 9px 10px, transparent 10px 19px);
	mask: repeating-linear-gradient(90deg, #000 0 1.5px, transparent 1.5px 9px, #000 9px 10px, transparent 10px 19px);
	animation: pp-pg-fall 0.7s linear infinite;
}
.pp-gen-anim--pr-cascade .pp-btn--gen-fx::after {
	inset: auto 0 -6px 0;
	height: 16px;
	background: radial-gradient(ellipse at 50% 100%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.45) 50%, transparent 75%);
	animation: pp-pg-foam 1.2s ease-in-out infinite alternate;
}
@keyframes pp-pg-fall { to { background-position: 0 28px; } }
@keyframes pp-pg-foam { from { transform: scaleX(0.92); opacity: 0.8; } to { transform: scaleX(1.06); opacity: 1; } }
.pp-gen-anim--pr-cascade::before { background: radial-gradient(circle, rgba(56, 182, 255, 0.6), transparent 70%); }
.pp-gen-anim--pr-cascade::after {
	/* Brume au pied de la chute. */
	opacity: 1;
	inset: auto 10% 2px 10%;
	height: 18px;
	background: radial-gradient(ellipse at 50% 30%, rgba(255, 255, 255, 0.9), rgba(180, 235, 255, 0.4) 55%, transparent 78%);
	filter: blur(3px);
	animation: pp-pg-foam 1.6s ease-in-out infinite alternate-reverse;
}

/* 3. Ressort — le bouton bondit (écrasé puis étiré), une spire le porte. */
.pp-gen-anim--pr-ressort .pp-btn--gen-fx {
	background: linear-gradient(135deg, #43e97b, #38f9d7) !important;
	transform-origin: 50% 100%;
	animation: pp-pg-boing 1.6s cubic-bezier(0.3, 0, 0.2, 1) infinite;
}
.pp-gen-anim--pr-ressort .pp-btn--gen-fx::before {
	background: linear-gradient(180deg, rgba(255, 255, 255, 0.4), transparent 55%);
}
@keyframes pp-pg-boing {
	0%, 100% { transform: translateY(0) scale(1, 1); }
	18%      { transform: translateY(2px) scale(1.06, 0.88); }
	40%      { transform: translateY(-10px) scale(0.96, 1.08); }
	58%      { transform: translateY(-12px) scale(1, 1); }
	80%      { transform: translateY(0) scale(1.03, 0.94); }
}
.pp-gen-anim--pr-ressort::before {
	/* Ombre au sol : se resserre quand le bouton s'envole. */
	inset: auto 22% 3px 22%;
	height: 8px;
	border-radius: 50%;
	background: radial-gradient(ellipse, rgba(0, 70, 45, 0.4), transparent 70%);
	animation: pp-pg-shadow 1.6s cubic-bezier(0.3, 0, 0.2, 1) infinite;
}
@keyframes pp-pg-shadow {
	0%, 100% { transform: scaleX(1); opacity: 0.9; }
	40%, 58% { transform: scaleX(0.6); opacity: 0.45; }
}
.pp-gen-anim--pr-ressort::after {
	/* La spire : rayures obliques qui se compriment et se détendent. */
	opacity: 1;
	inset: auto;
	left: 50%;
	bottom: 5px;
	width: 26px;
	height: 24px;
	margin-left: -13px;
	border-radius: 3px;
	background: repeating-linear-gradient(-32deg, #1f9e62 0 2.5px, transparent 2.5px 6.5px);
	transform-origin: 50% 100%;
	animation: pp-pg-coil 1.6s cubic-bezier(0.3, 0, 0.2, 1) infinite;
}
@keyframes pp-pg-coil {
	0%, 100% { transform: scaleY(1); }
	18%      { transform: scaleY(0.55); }
	40%, 58% { transform: scaleY(1.45); }
	80%      { transform: scaleY(0.8); }
}

/* 4. Bulle — savon irisé : reflet arc-en-ciel qui tourne, éclat blanc. */
.pp-gen-anim--pr-bulle .pp-btn--gen-fx {
	background: linear-gradient(135deg, #6aa9ff, #b8e0ff 50%, #e8f6ff) !important;
	color: #123a63;
	text-shadow: none;
	box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.85), 0 4px 14px rgba(106, 169, 255, 0.35);
}
.pp-gen-anim--pr-bulle .pp-btn--gen-fx::before {
	inset: -30%;
	background: conic-gradient(from 0deg, rgba(255, 120, 200, 0.4), rgba(120, 255, 220, 0.4), rgba(255, 240, 120, 0.4), rgba(140, 160, 255, 0.4), rgba(255, 120, 200, 0.4));
	filter: blur(6px);
	animation: pp-pr-spin 7s linear infinite;
}
.pp-gen-anim--pr-bulle .pp-btn--gen-fx::after {
	background:
		radial-gradient(ellipse 30% 22% at 22% 24%, rgba(255, 255, 255, 0.95), transparent 100%),
		radial-gradient(ellipse 12% 10% at 78% 76%, rgba(255, 255, 255, 0.6), transparent 100%);
}
.pp-gen-anim--pr-bulle::before {
	inset: -4px;
	background: radial-gradient(circle, transparent 52%, rgba(120, 190, 255, 0.85) 70%, transparent 86%);
	animation: pp-pg-halo 1.6s ease-in-out infinite;
}

/* 5. Brise — trois lignes de vent filent à travers, feuilles emportées. */
.pp-gen-anim--pr-brise .pp-btn--gen-fx {
	background: linear-gradient(100deg, #7ee8c3, #4bb8d8) !important;
	box-shadow: 0 0 16px rgba(126, 232, 195, 0.5);
}
.pp-gen-anim--pr-brise .pp-btn--gen-fx::before {
	background:
		linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.85) 40%, transparent 70%) no-repeat,
		linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6) 40%, transparent 70%) no-repeat,
		linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.85) 40%, transparent 70%) no-repeat;
	background-size: 60px 2px, 44px 2px, 70px 2px;
	animation: pp-pg-gusts 1.9s linear infinite;
}
@keyframes pp-pg-gusts {
	0%   { background-position: -70px 24%, -140px 50%, -30px 76%; }
	100% { background-position: calc(100% + 70px) 24%, calc(100% + 50px) 50%, calc(100% + 110px) 76%; }
}
.pp-gen-anim--pr-brise::before { background: radial-gradient(circle, rgba(126, 232, 195, 0.55), transparent 70%); }

/* 6. Jade — pierre polie : veines, profondeur, reflet qui balaie. */
.pp-gen-anim--pr-jade .pp-btn--gen-fx {
	background:
		radial-gradient(ellipse 60% 40% at 20% 30%, rgba(214, 255, 240, 0.5), transparent 70%),
		radial-gradient(ellipse 50% 60% at 80% 70%, rgba(4, 52, 36, 0.7), transparent 70%),
		radial-gradient(ellipse 30% 20% at 60% 20%, rgba(123, 232, 180, 0.6), transparent 70%),
		linear-gradient(135deg, #0f5132, #1e9e6a 55%, #0b3d28) !important;
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35), inset 0 -2px 4px rgba(0, 0, 0, 0.35), 0 0 16px rgba(30, 158, 106, 0.5);
}
.pp-gen-anim--pr-jade .pp-btn--gen-fx::after {
	background:
		linear-gradient(115deg, transparent 30%, rgba(214, 255, 240, 0.4) 31%, transparent 33%),
		linear-gradient(105deg, transparent 58%, rgba(214, 255, 240, 0.28) 59%, transparent 61%),
		linear-gradient(125deg, transparent 72%, rgba(4, 52, 36, 0.55) 73%, transparent 75%);
}
.pp-gen-anim--pr-jade .pp-btn--gen-fx::before {
	background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, 0.55) 48%, rgba(255, 255, 255, 0.15) 52%, transparent 62%);
	background-size: 300% 100%;
	animation: pp-pg-slide 4.5s ease-in-out infinite;
}
.pp-gen-anim--pr-jade::before { background: radial-gradient(circle, rgba(30, 158, 106, 0.6), transparent 70%); }

/* 7. Cuivre — métal martelé : bosses, reflet chaud, étincelles à la frappe. */
.pp-gen-anim--pr-cuivre .pp-btn--gen-fx {
	background: linear-gradient(115deg, #7a3b12, #c2703a 45%, #8a4a1e) !important;
	box-shadow: inset 0 1px 0 rgba(255, 220, 170, 0.5), inset 0 -2px 3px rgba(60, 20, 0, 0.5), 0 0 16px rgba(194, 112, 58, 0.5);
}
.pp-gen-anim--pr-cuivre .pp-btn--gen-fx::after {
	background:
		radial-gradient(circle at 30% 30%, rgba(255, 230, 190, 0.45) 0 2px, rgba(80, 30, 0, 0.25) 3px 4px, transparent 5px) 0 0 / 11px 11px,
		radial-gradient(circle at 30% 30%, rgba(255, 230, 190, 0.35) 0 2px, rgba(80, 30, 0, 0.2) 3px 4px, transparent 5px) 5px 6px / 11px 11px;
	opacity: 0.5;
}
.pp-gen-anim--pr-cuivre .pp-btn--gen-fx::before {
	background: linear-gradient(115deg, transparent 30%, rgba(255, 217, 160, 0.75) 46%, rgba(255, 240, 210, 0.9) 50%, rgba(255, 217, 160, 0.75) 54%, transparent 70%);
	background-size: 280% 100%;
	animation: pp-pg-slide 4.6s linear infinite;
}
.pp-gen-anim--pr-cuivre::before { background: radial-gradient(circle, rgba(194, 112, 58, 0.6), transparent 70%); }

/* 8. Ardoise — tableau noir : un trait de craie s'écrit sous le mot puis s'efface. */
.pp-gen-anim--pr-ardoise .pp-btn--gen-fx {
	background: linear-gradient(100deg, #1b2027, #2c343d 50%, #1b2027) !important;
	color: #f3f6f9;
	text-shadow: 0 0 2px rgba(255, 255, 255, 0.5);
	box-shadow: inset 0 0 0 2px #59657a, inset 0 0 0 4px #2c343d, 0 0 12px rgba(143, 162, 182, 0.35);
}
.pp-gen-anim--pr-ardoise .pp-btn--gen-fx::after {
	background:
		radial-gradient(ellipse 60% 40% at 70% 30%, rgba(255, 255, 255, 0.09), transparent 70%),
		radial-gradient(ellipse 40% 50% at 20% 70%, rgba(255, 255, 255, 0.07), transparent 70%),
		repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.035) 0 1px, transparent 1px 3px);
}
.pp-gen-anim--pr-ardoise .pp-btn--gen-fx::before {
	inset: auto 16% 20% 16%;
	height: 2px;
	border-radius: 2px;
	background: linear-gradient(90deg, #ffffff, #e8eef5 60%, rgba(255, 255, 255, 0.6));
	box-shadow: 0 0 3px rgba(255, 255, 255, 0.55);
	transform-origin: 0 50%;
	animation: pp-pg-chalk 3.2s ease-in-out infinite;
}
@keyframes pp-pg-chalk {
	0%       { transform: scaleX(0); opacity: 1; }
	45%, 70% { transform: scaleX(1); opacity: 1; }
	100%     { transform: scaleX(1); opacity: 0; }
}
.pp-gen-anim--pr-ardoise::before { background: radial-gradient(circle, rgba(143, 162, 182, 0.45), transparent 70%); }

/* 9. Menthe — buée fraîche qui monte, deux feuilles posées dans le coin. */
.pp-gen-anim--pr-menthe .pp-btn--gen-fx {
	background: linear-gradient(135deg, #ffffff, #b6ffe6 30%, #4fd9ae 70%, #0f8f6c) !important;
	color: #05493a;
	text-shadow: none;
	box-shadow: 0 0 16px rgba(79, 217, 174, 0.5);
}
.pp-gen-anim--pr-menthe .pp-btn--gen-fx::before {
	background: linear-gradient(0deg, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0) 60%);
	animation: pp-pg-halo 2.6s ease-in-out infinite;
}
.pp-gen-anim--pr-menthe .pp-btn--gen-fx::after {
	inset: auto;
	right: 8px;
	top: 3px;
	width: 14px;
	height: 9px;
	border-radius: 0 100% 0 100%;
	background: linear-gradient(135deg, #7be8b4, #0f8f6c);
	box-shadow: -9px 4px 0 -1px #1fb583;
	animation: pp-pg-leafwave 3s ease-in-out infinite;
}
@keyframes pp-pg-leafwave { 0%, 100% { transform: rotate(-25deg); } 50% { transform: rotate(-10deg); } }
.pp-gen-anim--pr-menthe::before { background: radial-gradient(circle, rgba(53, 199, 154, 0.5), transparent 70%); }

/* 10. Sable — dunes qui ondulent sous un soleil blanc, grains emportés. */
.pp-gen-anim--pr-sable .pp-btn--gen-fx {
	background: linear-gradient(180deg, #ffd27a 0%, #ffb64a 40%, #e9a34a 41%, #c79a53 100%) !important;
	color: #3d2a08;
	text-shadow: 0 1px 0 rgba(255, 240, 200, 0.6);
}
.pp-gen-anim--pr-sable .pp-btn--gen-fx::before {
	inset: 45% -20% -10% -20%;
	background:
		radial-gradient(ellipse 45% 60% at 30% 100%, #d9a557, transparent 70%),
		radial-gradient(ellipse 50% 70% at 75% 100%, #b9853f, transparent 72%);
	animation: pp-pg-drift 6s ease-in-out infinite alternate;
}
.pp-gen-anim--pr-sable .pp-btn--gen-fx::after {
	inset: auto;
	left: 16%;
	top: 3px;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: #fff8e0;
	box-shadow: 0 0 10px 3px rgba(255, 248, 224, 0.85);
}
.pp-gen-anim--pr-sable::before { background: radial-gradient(circle, rgba(199, 154, 83, 0.55), transparent 70%); }

/* ---- Piste Premium : 10 scènes spectaculaires -------------------------- */

/* 11. Supernova — cœur qui pulse, rayons qui tournent, onde de choc en boucle. */
.pp-gen-anim--pr-supernova .pp-btn--gen-fx {
	background: radial-gradient(circle at 50% 50%, #ffffff 0%, #ffe17d 18%, #ff8c1a 45%, #d81e5b 78%, #4a0d2b 100%) !important;
	background-size: 180% 180% !important;
	animation: pp-pg-shift 3s ease-in-out infinite;
	box-shadow: 0 0 26px rgba(255, 140, 26, 0.7), 0 0 46px rgba(216, 30, 91, 0.45);
}
.pp-gen-anim--pr-supernova .pp-btn--gen-fx::before {
	inset: -60%;
	background: repeating-conic-gradient(from 0deg, rgba(255, 255, 255, 0.35) 0 4deg, transparent 4deg 30deg);
	opacity: 0.8;
	animation: pp-pr-spin 9s linear infinite;
}
.pp-gen-anim--pr-supernova::before {
	inset: -6px;
	background: radial-gradient(circle, transparent 46%, rgba(255, 200, 80, 0.8) 62%, transparent 80%);
	animation: pp-pg-halo 1.4s ease-in-out infinite;
}
.pp-gen-anim--pr-supernova::after {
	opacity: 1;
	inset: auto;
	left: 50%;
	top: 50%;
	width: 60px;
	height: 60px;
	margin: -30px 0 0 -30px;
	border-radius: 50%;
	border: 2px solid rgba(255, 225, 125, 0.9);
	box-shadow: 0 0 12px rgba(255, 140, 26, 0.8), inset 0 0 10px rgba(255, 225, 125, 0.6);
	animation: pp-pg-ring 1.6s ease-out infinite;
}

/* 12. Vortex — spirale qui tourne, bras clairs en sens inverse, œil noir. */
.pp-gen-anim--pr-vortex .pp-btn--gen-fx {
	background: conic-gradient(from var(--pp-a), #12002e, #6a00ff 25%, #00d4ff 50%, #6a00ff 75%, #12002e) !important;
	animation: pp-pr-rotate 2.6s linear infinite;
	box-shadow: 0 0 24px rgba(106, 0, 255, 0.65);
}
.pp-gen-anim--pr-vortex .pp-btn--gen-fx::before {
	inset: -40%;
	background: repeating-conic-gradient(from 0deg, rgba(255, 255, 255, 0.3) 0 10deg, transparent 10deg 45deg);
	-webkit-mask: radial-gradient(circle, transparent 12%, #000 40%, transparent 70%);
	mask: radial-gradient(circle, transparent 12%, #000 40%, transparent 70%);
	animation: pp-pr-spin-r 2.2s linear infinite;
}
.pp-gen-anim--pr-vortex .pp-btn--gen-fx::after {
	inset: auto;
	left: 50%;
	top: 50%;
	width: 18px;
	height: 18px;
	margin: -9px 0 0 -9px;
	border-radius: 50%;
	background: radial-gradient(circle, #05001a 40%, rgba(5, 0, 26, 0) 70%);
}
.pp-gen-anim--pr-vortex::before {
	background: conic-gradient(from var(--pp-a), transparent 0 200deg, rgba(0, 212, 255, 0.7) 300deg, transparent 360deg);
	animation: pp-pr-rotate-r 1.8s linear infinite;
	opacity: 0.9;
}

/* 13. Prisme — verre clair : un triangle disperse la lumière en éventail. */
.pp-gen-anim--pr-prisme .pp-btn--gen-fx {
	/* Verre SOMBRE : sur la carte blanche de la boutique, un prisme clair
	   disparaissait. Le spectre ne se lit que sur du foncé. */
	background: linear-gradient(135deg, #141c33, #24305a 50%, #141c33) !important;
	box-shadow: 0 0 22px rgba(120, 150, 255, 0.55), inset 0 0 0 1px rgba(180, 200, 255, 0.45);
}
.pp-gen-anim--pr-prisme .pp-btn--gen-fx::before {
	inset: -10%;
	background: conic-gradient(from 250deg at 16% 50%, transparent 0 20deg, #ff005c 24deg, #ffb300 32deg, #21e065 40deg, #00c2ff 48deg, #7b2bff 56deg, transparent 62deg 360deg);
	opacity: 0.95;
	filter: blur(0.6px);
	transform-origin: 16% 50%;
	animation: pp-pg-fan 4s ease-in-out infinite alternate;
}
.pp-gen-anim--pr-prisme .pp-btn--gen-fx::after {
	inset: auto;
	left: 9%;
	top: 50%;
	width: 16px;
	height: 14px;
	margin-top: -7px;
	clip-path: polygon(50% 0, 100% 100%, 0 100%);
	background: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(160, 190, 255, 0.75));
	filter: drop-shadow(0 0 3px rgba(120, 150, 220, 0.8));
}
@keyframes pp-pg-fan { from { transform: rotate(-7deg); } to { transform: rotate(7deg); } }
.pp-gen-anim--pr-prisme::before {
	background: radial-gradient(circle at 35% 25%, rgba(255, 255, 255, 0.9), transparent 45%);
	animation: none;
	opacity: 0.8;
}

/* 14. Obsidienne — verre volcanique : fissures d'or qui palpitent, reflet vitreux. */
.pp-gen-anim--pr-obsidienne .pp-btn--gen-fx {
	background: linear-gradient(135deg, #05070a, #171c24 50%, #05070a) !important;
	color: #ffe9a8;
	text-shadow: 0 0 6px rgba(245, 197, 24, 0.6);
	box-shadow: 0 0 20px rgba(245, 197, 24, 0.45), inset 0 0 0 1px rgba(245, 197, 24, 0.35);
}
.pp-gen-anim--pr-obsidienne .pp-btn--gen-fx::after {
	background:
		linear-gradient(112deg, transparent 38%, #f5c518 38.6%, #fff3c4 39%, #f5c518 39.4%, transparent 40%),
		linear-gradient(60deg, transparent 62%, #f5c518 62.5%, transparent 63.3%),
		linear-gradient(150deg, transparent 20%, rgba(245, 197, 24, 0.9) 20.5%, transparent 21.2%),
		linear-gradient(95deg, transparent 75%, rgba(245, 197, 24, 0.8) 75.4%, transparent 76%);
	animation: pp-pg-veins 2.4s ease-in-out infinite;
}
@keyframes pp-pg-veins { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; filter: drop-shadow(0 0 3px rgba(245, 197, 24, 0.9)); } }
.pp-gen-anim--pr-obsidienne .pp-btn--gen-fx::before {
	background: linear-gradient(160deg, rgba(255, 255, 255, 0.28), transparent 45%);
}
.pp-gen-anim--pr-obsidienne::before { background: radial-gradient(circle, rgba(245, 197, 24, 0.55), transparent 70%); }

/* 15. Tempête — nuages noirs qui roulent, pluie qui bat, éclairs qui claquent. */
.pp-gen-anim--pr-tempete .pp-btn--gen-fx {
	background: linear-gradient(180deg, #0a1018, #26313f 60%, #3b4a5c) !important;
	color: #dbe7ff;
	animation: pp-pg-tilt 2.4s ease-in-out infinite;
	box-shadow: 0 0 18px rgba(140, 190, 255, 0.4);
}
.pp-gen-anim--pr-tempete .pp-btn--gen-fx::before {
	background:
		repeating-linear-gradient(172deg, rgba(190, 225, 255, 0.45) 0 1px, transparent 1px 5px),
		repeating-linear-gradient(168deg, rgba(150, 195, 255, 0.3) 0 1.5px, transparent 1.5px 8px);
	animation: pp-pg-rain 0.35s linear infinite;
}
@keyframes pp-pg-rain { to { background-position: -4px 18px, -6px 26px; } }
.pp-gen-anim--pr-tempete .pp-btn--gen-fx::after {
	inset: -30% -10% 45% -10%;
	background:
		radial-gradient(ellipse 30% 60% at 20% 60%, #151c25, transparent 70%),
		radial-gradient(ellipse 35% 70% at 50% 40%, #1b232e, transparent 70%),
		radial-gradient(ellipse 30% 60% at 80% 60%, #151c25, transparent 70%);
	filter: blur(1px);
	animation: pp-pg-drift 6s ease-in-out infinite alternate;
}
.pp-gen-anim--pr-tempete::before {
	inset: -3px;
	background: linear-gradient(75deg, transparent 42%, #ffffff 48%, #cfe9ff 50%, transparent 56%);
	animation: pp-pg-flash 2.8s linear infinite;
}

/* 16. Aurore — rideaux de lumière qui ondulent sur un ciel étoilé. */
.pp-gen-anim--pr-aurore .pp-btn--gen-fx {
	background: linear-gradient(180deg, #02101c 0%, #032a3d 60%, #0b3b2f 100%) !important;
	color: #d8fff3;
	text-shadow: 0 0 8px rgba(20, 224, 168, 0.8);
	box-shadow: 0 0 22px rgba(20, 224, 168, 0.5);
}
.pp-gen-anim--pr-aurore .pp-btn--gen-fx::before {
	inset: -20% -10%;
	background: repeating-linear-gradient(95deg, rgba(20, 224, 168, 0) 0 6px, rgba(20, 224, 168, 0.6) 9px, rgba(106, 92, 255, 0.55) 16px, rgba(255, 95, 210, 0.45) 22px, rgba(20, 224, 168, 0) 30px 40px);
	filter: blur(2px);
	animation: pp-pg-curtain 5s ease-in-out infinite alternate;
}
@keyframes pp-pg-curtain {
	from { transform: skewX(-8deg) translateX(-8%); opacity: 0.7; }
	to   { transform: skewX(8deg) translateX(8%); opacity: 1; }
}
.pp-gen-anim--pr-aurore .pp-btn--gen-fx::after {
	background:
		radial-gradient(circle at 12% 30%, #fff 0 1px, transparent 1.6px),
		radial-gradient(circle at 40% 15%, #fff 0 0.8px, transparent 1.4px),
		radial-gradient(circle at 70% 25%, #fff 0 1px, transparent 1.6px),
		radial-gradient(circle at 88% 55%, #fff 0 0.8px, transparent 1.4px),
		radial-gradient(circle at 25% 75%, #fff 0 0.8px, transparent 1.4px),
		linear-gradient(0deg, rgba(255, 255, 255, 0.35), transparent 22%);
	animation: pp-pg-twinkle 3s ease-in-out infinite;
}
.pp-gen-anim--pr-aurore::before {
	background: radial-gradient(ellipse at 50% 120%, rgba(20, 224, 168, 0.8), transparent 62%);
	animation: pp-pg-halo 3s ease-in-out infinite;
}

/* 17. Météore — nuit étoilée traversée par une traînée de feu. */
.pp-gen-anim--pr-meteore .pp-btn--gen-fx {
	background: linear-gradient(180deg, #0b0620, #1a0a2e 55%, #3a1550) !important;
	color: #ffe9d6;
	box-shadow: 0 0 22px rgba(255, 145, 66, 0.55);
}
.pp-gen-anim--pr-meteore .pp-btn--gen-fx::before {
	inset: -20%;
	background: linear-gradient(115deg, transparent 40%, rgba(255, 145, 66, 0) 44%, #ff9142 47%, #fff0d0 49%, #ff9142 51%, transparent 56%);
	background-size: 340% 100%;
	animation: pp-pg-slide 2.4s linear infinite;
}
.pp-gen-anim--pr-meteore .pp-btn--gen-fx::after {
	background:
		radial-gradient(circle at 15% 35%, #fff 0 1px, transparent 1.6px),
		radial-gradient(circle at 35% 70%, #fff 0 0.8px, transparent 1.4px),
		radial-gradient(circle at 55% 20%, #fff 0 1px, transparent 1.6px),
		radial-gradient(circle at 78% 65%, #fff 0 0.8px, transparent 1.4px),
		radial-gradient(circle at 90% 30%, #fff 0 1px, transparent 1.6px);
	animation: pp-pg-twinkle 2.6s ease-in-out infinite;
}
.pp-gen-anim--pr-meteore::before { background: radial-gradient(circle, rgba(255, 145, 66, 0.6), transparent 70%); }

/* 18. Abysse — rais de lumière qui descendent, sonar, lueurs du fond. */
.pp-gen-anim--pr-abysse .pp-btn--gen-fx {
	background: radial-gradient(ellipse at 50% 130%, #0a4ea8 0%, #06255c 45%, #020b1c 100%) !important;
	color: #bfe7ff;
	text-shadow: 0 0 8px rgba(79, 184, 255, 0.7);
	box-shadow: 0 0 20px rgba(79, 184, 255, 0.5);
}
.pp-gen-anim--pr-abysse .pp-btn--gen-fx::before {
	inset: -30% -10% 0;
	background: repeating-linear-gradient(100deg, rgba(120, 200, 255, 0) 0 8px, rgba(120, 200, 255, 0.28) 10px 14px, rgba(120, 200, 255, 0) 16px 28px);
	-webkit-mask: linear-gradient(180deg, #000, transparent 80%);
	mask: linear-gradient(180deg, #000, transparent 80%);
	animation: pp-pg-drift 5s ease-in-out infinite alternate;
}
.pp-gen-anim--pr-abysse .pp-btn--gen-fx::after {
	background:
		radial-gradient(circle at 18% 84%, #7fffd4 0 1.2px, transparent 2.2px),
		radial-gradient(circle at 46% 90%, #4fb8ff 0 1px, transparent 2px),
		radial-gradient(circle at 72% 86%, #7fffd4 0 1.2px, transparent 2.2px),
		radial-gradient(circle at 88% 78%, #4fb8ff 0 0.9px, transparent 1.8px);
	animation: pp-pg-twinkle 2.2s ease-in-out infinite;
}
.pp-gen-anim--pr-abysse::before {
	background: radial-gradient(ellipse at 50% 120%, rgba(79, 184, 255, 0.75), transparent 60%);
	animation: pp-pg-halo 2.8s ease-in-out infinite;
}
.pp-gen-anim--pr-abysse::after {
	opacity: 1;
	inset: auto;
	left: 50%;
	top: 50%;
	width: 56px;
	height: 56px;
	margin: -28px 0 0 -28px;
	border-radius: 50%;
	border: 1.5px solid rgba(79, 184, 255, 0.85);
	animation: pp-pg-ring 2.4s ease-out infinite;
}

/* 19. Couronne — une vraie couronne sertie posée sur l'or, anneau qui tourne. */
.pp-gen-anim--pr-couronne .pp-btn--gen-fx {
	background: linear-gradient(125deg, #8a6100, #f5c518 45%, #b8860b) !important;
	color: #3d2a00;
	text-shadow: 0 1px 1px rgba(255, 246, 204, 0.8);
	box-shadow: 0 0 24px rgba(245, 197, 24, 0.65), inset 0 1px 0 rgba(255, 246, 204, 0.8);
}
.pp-gen-anim--pr-couronne .pp-btn--gen-fx::before {
	background: linear-gradient(115deg, transparent 32%, rgba(255, 246, 204, 0.85) 48%, transparent 64%);
	background-size: 260% 100%;
	animation: pp-pg-slide 4.2s linear infinite;
}
.pp-gen-anim--pr-couronne .pp-btn--gen-fx::after {
	/* Rangée de petites pierres le long du bord bas. */
	inset: auto 12% 3px 12%;
	height: 4px;
	background: radial-gradient(circle, #e63946 0 1.4px, transparent 2px) 0 50% / 12px 4px repeat-x;
	opacity: 0.9;
}
.pp-gen-anim--pr-couronne::before {
	inset: -6px;
	border-radius: 999px;
	background: conic-gradient(from var(--pp-a), transparent 0 250deg, #fff6cc 320deg, #f5c518 350deg, transparent 360deg);
	animation: pp-pr-rotate 2.2s linear infinite;
	opacity: 0.95;
}
.pp-gen-anim--pr-couronne::after {
	opacity: 1;
	inset: auto;
	left: 50%;
	top: 3px;
	width: 34px;
	height: 23px;
	margin-left: -17px;
	border-radius: 0;
	background:
		radial-gradient(circle at 50% 34%, #e63946 0 2.4px, transparent 3.2px),
		radial-gradient(circle at 18% 70%, #2a9df4 0 1.9px, transparent 2.7px),
		radial-gradient(circle at 82% 70%, #2a9df4 0 1.9px, transparent 2.7px),
		linear-gradient(180deg, #fff6cc, #f5c518 45%, #b8860b);
	clip-path: polygon(0% 100%, 0% 30%, 22% 58%, 50% 6%, 78% 58%, 100% 30%, 100% 100%);
	filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35));
	animation: pp-pg-float 2.4s ease-in-out infinite;
}

/* 20. Mirage — horizon de désert : l'air tremble, le soleil se reflète. */
.pp-gen-anim--pr-mirage .pp-btn--gen-fx {
	background: linear-gradient(180deg, #ffb347 0%, #ffd27a 42%, #f4e2b8 50%, #e3b06a 52%, #c9955a 100%) !important;
	color: #4a2a05;
	text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
	box-shadow: 0 0 22px rgba(255, 217, 61, 0.55);
}
.pp-gen-anim--pr-mirage .pp-btn--gen-fx::before {
	inset: 40% -10% -10%;
	background: repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.38) 0 2px, transparent 2px 6px);
	filter: blur(0.6px);
	animation: pp-pg-heat 1.3s ease-in-out infinite alternate;
}
@keyframes pp-pg-heat {
	from { transform: skewX(-6deg) scaleY(1); }
	to   { transform: skewX(6deg) scaleY(1.15); }
}
.pp-gen-anim--pr-mirage .pp-btn--gen-fx::after {
	inset: auto;
	left: 50%;
	top: 4px;
	width: 14px;
	height: 14px;
	margin-left: -7px;
	border-radius: 50%;
	background: #fff5d6;
	box-shadow: 0 0 12px 4px rgba(255, 245, 214, 0.9), 0 14px 6px -2px rgba(255, 255, 255, 0.55);
	animation: pp-pg-halo 2s ease-in-out infinite;
}
.pp-gen-anim--pr-mirage::before {
	background: radial-gradient(circle, rgba(255, 217, 61, 0.6), transparent 70%);
	animation: pp-pg-halo 1.9s ease-in-out infinite;
}

/* =========================================================================
 * 3. Mouvement réduit
 *
 * Réglage système « réduire les animations » : on garde la BELLE image fixe,
 * on retire le mouvement. Une bordure ou un bouton doivent rester reconnaissables
 * même immobiles — c'est pour ça que chaque pièce a d'abord un fond qui tient
 * tout seul, et le mouvement par-dessus.
 * ====================================================================== */

@media (prefers-reduced-motion: reduce) {
	[class*="pp-ab--"],
	[class*="pp-ab--"]::before,
	[class*="pp-ab--"]::after,
	[class*="pp-gen-anim--pr-"] .pp-btn--gen-fx,
	[class*="pp-gen-anim--pr-"]::before,
	[class*="pp-gen-anim--pr-"]::after {
		animation: none !important;
	}
}

/* =========================================================================
 * Prisme — retravail (Vincent) : un faisceau blanc entre par la gauche,
 * frappe un prisme net, et le spectre s'ouvre en éventail vers la droite ;
 * un anneau arc-en-ciel tourne autour du bouton. Les règles ci-dessous
 * viennent APRÈS celles du bloc 2 et les remplacent.
 * ====================================================================== */
.pp-gen-anim--pr-prisme .pp-btn--gen-fx {
	background: linear-gradient(135deg, #0b1026, #1c2550 50%, #0b1026) !important;
	box-shadow: 0 0 26px rgba(140, 170, 255, 0.6), inset 0 0 0 1px rgba(200, 215, 255, 0.5);
}
.pp-gen-anim--pr-prisme .pp-btn--gen-fx::before {
	inset: 18% -12% 18% 24%;
	background: linear-gradient(180deg, #ff005c, #ff8a00 20%, #ffe53b 40%, #21e065 60%, #00c2ff 80%, #7b2bff);
	clip-path: polygon(0 44%, 100% 0, 100% 100%, 0 56%);
	opacity: 0.95;
	filter: blur(0.4px) drop-shadow(0 0 6px rgba(255, 255, 255, 0.35));
	transform-origin: 0 50%;
	animation: pp-pg-fan 3s ease-in-out infinite alternate;
}
.pp-gen-anim--pr-prisme .pp-btn--gen-fx::after {
	inset: auto;
	left: 10%;
	top: 50%;
	width: 22px;
	height: 20px;
	margin-top: -10px;
	clip-path: polygon(50% 0, 100% 100%, 0 100%);
	background: linear-gradient(160deg, rgba(255, 255, 255, 0.98), rgba(190, 210, 255, 0.85) 60%, rgba(120, 150, 230, 0.9));
	filter: drop-shadow(0 0 4px rgba(200, 220, 255, 0.9));
}
.pp-gen-anim--pr-prisme::before {
	inset: -5px;
	border-radius: 999px;
	background: conic-gradient(from var(--pp-a), #ff005c, #ffb300, #21e065, #00c2ff, #7b2bff, #ff005c);
	-webkit-mask: radial-gradient(ellipse, transparent 62%, #000 66%);
	mask: radial-gradient(ellipse, transparent 62%, #000 66%);
	opacity: 0.85;
	animation: pp-pr-rotate 4s linear infinite;
}
.pp-gen-anim--pr-prisme::after {
	opacity: 1;
	inset: auto;
	left: 0;
	top: 50%;
	width: 26%;
	height: 3px;
	margin-top: -1px;
	border-radius: 0;
	background: linear-gradient(90deg, transparent, #ffffff);
	box-shadow: 0 0 8px #ffffff;
	animation: pp-pg-twinkle 1.6s ease-in-out infinite;
}
