/* ============================================================
   Name effects (fx-*): shared by the bio page and the builder's
   effect-picker tiles. Per-letter effects (wave, flip) expect
   their text split into .wave-ch / .flip-ch spans.
   ============================================================ */

.fx-glow {
  animation: fx-glow-pulse 2s ease-in-out infinite;
}

@keyframes fx-glow-pulse {
  0%, 100% { text-shadow: 0 0 8px color-mix(in srgb, var(--accent, #fff) 90%, transparent), 0 0 22px color-mix(in srgb, var(--accent, #fff) 55%, transparent), 0 0 48px color-mix(in srgb, var(--accent, #fff) 35%, transparent); }
  50% { text-shadow: 0 0 4px color-mix(in srgb, var(--accent, #fff) 55%, transparent), 0 0 12px color-mix(in srgb, var(--accent, #fff) 28%, transparent); }
}

/* sparkles — classic tiled glitter GIFs overlaid on the name
   (transparent GIFs from static/imgs/sparkles, one per color) */
[class*="fx-sparkle"] {
  position: relative;
  display: inline-block;
}

[class*="fx-sparkle"]::after {
  content: '';
  position: absolute;
  inset: -8px -14px;
  background: url('/static/imgs/sparkles/white.gif') repeat;
  pointer-events: none;
}

.fx-sparkle-red::after { background-image: url('/static/imgs/sparkles/red.gif'); }
.fx-sparkle-orange::after { background-image: url('/static/imgs/sparkles/orange.gif'); }
.fx-sparkle-yellow::after { background-image: url('/static/imgs/sparkles/yellow.gif'); }
.fx-sparkle-green::after { background-image: url('/static/imgs/sparkles/green.gif'); }
.fx-sparkle-lightblue::after { background-image: url('/static/imgs/sparkles/lightblue.gif'); }
.fx-sparkle-blue::after { background-image: url('/static/imgs/sparkles/blue.gif'); }
.fx-sparkle-purple::after { background-image: url('/static/imgs/sparkles/purple.gif'); }
.fx-sparkle-pink::after { background-image: url('/static/imgs/sparkles/pink.gif'); }
.fx-sparkle-rainbow::after { background-image: url('/static/imgs/sparkles/rainbow.gif'); }
.fx-sparkle-black::after { background-image: url('/static/imgs/sparkles/black.gif'); }

.fx-rainbow {
  background: linear-gradient(90deg, #ff5555, #ffaa00, #ffff55, #55ff55, #55ffff, #5555ff, #ff55ff, #ff5555);
  background-size: 400% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
  animation: fx-rainbow-slide 4s linear infinite;
}

@keyframes fx-rainbow-slide {
  0% { background-position: 0% 50%; }
  100% { background-position: 400% 50%; }
}

.fx-glitch {
  position: relative;
  animation: fx-glitch-shift 2.4s steps(1) infinite;
}

@keyframes fx-glitch-shift {
  0%, 88%, 100% { text-shadow: 0 0 6px rgba(255, 255, 255, 0.9), 0 0 18px rgba(255, 255, 255, 0.5); transform: translate(0, 0); }
  90% { text-shadow: -2px 0 #f0f, 2px 0 #0ff; transform: translate(1px, -1px); }
  92% { text-shadow: 2px 0 #f0f, -2px 0 #0ff; transform: translate(-1px, 1px); }
  94% { text-shadow: -1px 0 #0ff, 1px 0 #f0f; transform: translate(1px, 0); }
  96% { text-shadow: 0 0 6px rgba(255, 255, 255, 0.9); transform: translate(0, 0); }
}

.wave-ch {
  display: inline-block;
  animation: fx-wave-bounce 1.4s ease-in-out infinite;
}

@keyframes fx-wave-bounce {
  0%, 100% { transform: translateY(0); }
  30% { transform: translateY(-6px); }
  60% { transform: translateY(2px); }
}

/* shake — constant nervous jitter */
.fx-shake {
  display: inline-block;
  animation: fx-shake-jitter 0.45s linear infinite;
}

@keyframes fx-shake-jitter {
  0%, 100% { transform: translate(0, 0) rotate(0); }
  20% { transform: translate(-1.5px, 1px) rotate(-0.6deg); }
  40% { transform: translate(1.5px, -1px) rotate(0.6deg); }
  60% { transform: translate(-1px, -1px) rotate(0.4deg); }
  80% { transform: translate(1px, 1px) rotate(-0.4deg); }
}

/* flicker — failing neon sign */
.fx-flicker {
  animation: fx-flicker-buzz 3.2s linear infinite;
  text-shadow: 0 0 10px color-mix(in srgb, var(--accent, #fff) 70%, transparent);
}

@keyframes fx-flicker-buzz {
  0%, 6%, 10%, 26%, 30%, 100% { opacity: 1; }
  7%, 9% { opacity: 0.25; }
  27%, 29% { opacity: 0.4; }
  62% { opacity: 1; }
  63% { opacity: 0.2; }
  64% { opacity: 1; }
}

/* shimmer — a bright band sweeping across the letters */
.fx-shimmer {
  background: linear-gradient(100deg, rgba(255, 255, 255, 0.35) 30%, #ffffff 48%, rgba(255, 255, 255, 0.35) 66%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
  animation: fx-shimmer-sweep 2.4s ease-in-out infinite;
}

@keyframes fx-shimmer-sweep {
  0% { background-position: 120% 0; }
  100% { background-position: -120% 0; }
}

/* flames — burning gradient with a flickering ember glow */
.fx-flames {
  background: linear-gradient(0deg, #f97316 15%, #fbbf24 45%, #fde68a 75%);
  background-size: 100% 160%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: fx-flames-lick 1.1s ease-in-out infinite;
}

@keyframes fx-flames-lick {
  0%, 100% { background-position: 0% 20%; filter: drop-shadow(0 -2px 7px rgba(249, 115, 22, 0.55)); }
  50% { background-position: 0% 65%; filter: drop-shadow(0 -5px 13px rgba(251, 191, 36, 0.7)); }
}

/* flip — letters somersault one after another */
.flip-ch {
  display: inline-block;
  animation: fx-flip-turn 2.6s ease-in-out infinite;
  transform-style: preserve-3d;
}

@keyframes fx-flip-turn {
  0%, 55%, 100% { transform: rotateX(0); }
  15%, 40% { transform: rotateX(360deg); }
}

/* scramble is driven by JS (bio.js / builder.js); style stays inherited */

@media (prefers-reduced-motion: reduce) {
  .fx-glow,
  .fx-rainbow, .fx-glitch, .wave-ch, .fx-shake, .fx-flicker, .fx-shimmer,
  .fx-flames, .flip-ch { animation: none; }
  [class*="fx-sparkle"]::after { display: none; }
}
