/* Display name + bio: the fixed-palette gradient effects (NAME_EFFECTS_FX) and
   the animated overlays (NAME_OVERLAYS). Loaded by a layout only when the name
   or bio uses either, and by the portal pickers (.nfx / .nfo demo classes).
   Targets both layouts: Layout 1 h1 / .bio, Layout 2 #profile-name / #profile-bio. */


/* ================= Gradients: ice | aurora | gold | rainbow | pink =================
   A repeating gradient clipped to the letters, drifting sideways by exactly one
   repeat per loop. The glow is a filter drop-shadow, not text-shadow - a
   text-shadow paints over a background-clip:text fill and muddies it. The
   palettes are fixed: the name / bio colour doesn't tint these. */

:is([data-name-effect="ice"], [data-name-effect="aurora"], [data-name-effect="gold"],
    [data-name-effect="rainbow"], [data-name-effect="pink"]) :is(h1, #profile-name),
:is([data-bio-effect="ice"], [data-bio-effect="aurora"], [data-bio-effect="gold"],
    [data-bio-effect="rainbow"], [data-bio-effect="pink"]) :is(.bio, #profile-bio),
.nfx {
  --nfx-band: 12em;    /* width of one gradient repeat */
  color: transparent;
  -webkit-text-fill-color: transparent;
  background: var(--nfx-grad) 0 0 / var(--nfx-band) 100% repeat;
  -webkit-background-clip: text;
  background-clip: text;
  filter: drop-shadow(0 0 6px var(--nfx-glow));
}

[data-name-effect="ice"] :is(h1, #profile-name),
[data-bio-effect="ice"] :is(.bio, #profile-bio),
.nfx--ice {
  /* frost: near-white through pale cyan to periwinkle */
  --nfx-grad: linear-gradient(100deg, #e8fbff, #9be7ff 30%, #7aa8ff 60%, #e8fbff);
  --nfx-glow: rgba(150, 220, 255, 0.6);
  --nfx-solid: #9be7ff;
}
[data-name-effect="aurora"] :is(h1, #profile-name),
[data-bio-effect="aurora"] :is(.bio, #profile-bio),
.nfx--aurora {
  /* northern lights: teal, sky blue, violet */
  --nfx-grad: linear-gradient(95deg, #3cf2c4, #38b6ff 33%, #9b6bff 66%, #3cf2c4);
  --nfx-glow: rgba(60, 242, 196, 0.5);
  --nfx-solid: #3cf2c4;
}
[data-name-effect="gold"] :is(h1, #profile-name),
[data-bio-effect="gold"] :is(.bio, #profile-bio),
.nfx--gold {
  --nfx-band: 10em;
  /* polished metal: deep bronze, a bright highlight band, warm amber */
  --nfx-grad: linear-gradient(100deg, #8a5a12, #f9d976 22%, #fff6c9 34%, #e2a93b 52%, #b97a1e 72%, #8a5a12);
  --nfx-glow: rgba(249, 217, 118, 0.45);
  --nfx-solid: #e2a93b;
}
[data-name-effect="rainbow"] :is(h1, #profile-name),
[data-bio-effect="rainbow"] :is(.bio, #profile-bio),
.nfx--rainbow {
  --nfx-band: 16em;
  /* soft candy spectrum rather than pure primaries */
  --nfx-grad: linear-gradient(90deg, #ff6ec7, #ffb86c 17%, #f1fa8c 33%, #50fa7b 50%, #8be9fd 67%, #bd93f9 83%, #ff6ec7);
  --nfx-glow: rgba(255, 255, 255, 0.3);
  --nfx-solid: #ffb86c;
}
[data-name-effect="pink"] :is(h1, #profile-name),
[data-bio-effect="pink"] :is(.bio, #profile-bio),
.nfx--pink {
  /* hot pink, blush, lilac */
  --nfx-grad: linear-gradient(95deg, #ff4fa3, #ffb3c7 33%, #c48bff 66%, #ff4fa3);
  --nfx-glow: rgba(255, 79, 163, 0.6);
  --nfx-solid: #ff4fa3;
}

/* Neon glow toggle: its accent glow replaces the gradient's own. */
[data-name-neon="1"]:is([data-name-effect="ice"], [data-name-effect="aurora"], [data-name-effect="gold"],
    [data-name-effect="rainbow"], [data-name-effect="pink"]) :is(h1, #profile-name) {
  filter: drop-shadow(0 0 5px var(--name-col, var(--accent, #8a93a6))) drop-shadow(0 0 13px var(--name-col, var(--accent, #8a93a6)));
}
[data-bio-neon="1"]:is([data-bio-effect="ice"], [data-bio-effect="aurora"], [data-bio-effect="gold"],
    [data-bio-effect="rainbow"], [data-bio-effect="pink"]) :is(.bio, #profile-bio) {
  filter: drop-shadow(0 0 4px var(--bio-col, var(--accent, #8a93a6))) drop-shadow(0 0 11px var(--bio-col, var(--accent, #8a93a6)));
}

@media (prefers-reduced-motion: no-preference) {
  :is([data-name-effect="ice"], [data-name-effect="aurora"], [data-name-effect="gold"],
      [data-name-effect="rainbow"], [data-name-effect="pink"]) :is(h1, #profile-name),
  :is([data-bio-effect="ice"], [data-bio-effect="aurora"], [data-bio-effect="gold"],
      [data-bio-effect="rainbow"], [data-bio-effect="pink"]) :is(.bio, #profile-bio),
  .nfx {
    animation: nfx-drift 8s linear infinite;
  }
  /* Neon on top: run the layout's pulse alongside (name-neon / bio-neon are
     defined in each layout's style.css). */
  [data-name-neon="1"]:is([data-name-effect="ice"], [data-name-effect="aurora"], [data-name-effect="gold"],
      [data-name-effect="rainbow"], [data-name-effect="pink"]) :is(h1, #profile-name) {
    animation: nfx-drift 8s linear infinite, name-neon 2.2s ease-in-out infinite;
  }
  [data-bio-neon="1"]:is([data-bio-effect="ice"], [data-bio-effect="aurora"], [data-bio-effect="gold"],
      [data-bio-effect="rainbow"], [data-bio-effect="pink"]) :is(.bio, #profile-bio) {
    animation: nfx-drift 8s linear infinite, bio-neon 2.2s ease-in-out infinite;
  }
}
@keyframes nfx-drift { to { background-position: var(--nfx-band) 0; } }

/* No background-clip: text (old engines): a solid letter in the gradient's main colour. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  :is([data-name-effect="ice"], [data-name-effect="aurora"], [data-name-effect="gold"],
      [data-name-effect="rainbow"], [data-name-effect="pink"]) :is(h1, #profile-name),
  :is([data-bio-effect="ice"], [data-bio-effect="aurora"], [data-bio-effect="gold"],
      [data-bio-effect="rainbow"], [data-bio-effect="pink"]) :is(.bio, #profile-bio),
  .nfx {
    background: none;
    color: var(--nfx-solid);
    -webkit-text-fill-color: var(--nfx-solid);
  }
}


/* ================= Overlays: sparkle | flare | fire =================
   A ::after layer over the text box, so it stacks on ANY base effect without
   touching the base's own background. The artwork is animated images in
   name-fx/ (spark.webp + fire.webp are animated WebP, flare.gif a GIF), which
   play on their own; CSS only drifts each layer sideways by exactly one tile
   per loop, so it never jumps. The element shrinks to its text (fit-content)
   so the overlay stays on the words, not across the whole card. */

[data-name-overlay] :is(h1, #profile-name),
[data-bio-overlay] :is(.bio, #profile-bio),
.nfo {
  position: relative;
  width: fit-content;
}
/* Layout 1 centres its name; fit-content needs auto side margins to stay
   centred (its .bio already has them). */
[data-name-overlay] h1:not(#profile-name) {
  max-width: 100%;
  margin-inline: auto;
}
[data-name-overlay] :is(h1, #profile-name)::after,
[data-bio-overlay] :is(.bio, #profile-bio)::after,
.nfo::after {
  content: "";
  position: absolute;
  inset: -0.2em -0.15em;
  pointer-events: none;
  background-image: var(--nfo-img);
  background-size: var(--nfo-size);
  background-repeat: repeat;
  filter: drop-shadow(0 0 2px var(--nfo-glow));
  /* kept well see-through so the text underneath stays readable */
  --nfo-op: 0.55;
  opacity: var(--nfo-op);
}

/* Sparkle: the spark image drifting over the text. */
[data-name-overlay="sparkle"] :is(h1, #profile-name),
[data-bio-overlay="sparkle"] :is(.bio, #profile-bio),
.nfo--sparkle {
  --nfo-img: url("name-fx/spark.webp");
  --nfo-size: 3em auto;
  --nfo-end: 3em 0;
  --nfo-glow: rgba(255, 255, 255, 0.8);
  --nfo-dur: 8s;
}
/* Flare: the flare image gliding past. */
[data-name-overlay="flare"] :is(h1, #profile-name),
[data-bio-overlay="flare"] :is(.bio, #profile-bio),
.nfo--flare {
  --nfo-img: url("name-fx/flare.gif");
  --nfo-size: 7em auto;
  --nfo-end: 7em 0;
  --nfo-glow: rgba(127, 216, 255, 0.9);
  --nfo-dur: 5s;
}
/* Fire: the flame image alone, in 2em tiles. It stays put (end 0 0) - the
   flames rise on their own. */
[data-name-overlay="fire"] :is(h1, #profile-name),
[data-bio-overlay="fire"] :is(.bio, #profile-bio),
.nfo--fire {
  --nfo-img: url("name-fx/fire.webp");
  --nfo-size: 2em auto;
  --nfo-end: 0 0;
  --nfo-glow: rgba(255, 170, 60, 0.55);
  --nfo-dur: 8s;
}
[data-name-overlay="fire"] :is(h1, #profile-name)::after,
[data-bio-overlay="fire"] :is(.bio, #profile-bio)::after,
.nfo--fire::after {
  --nfo-op: 0.85;
}

@media (prefers-reduced-motion: no-preference) {
  [data-name-overlay] :is(h1, #profile-name)::after,
  [data-bio-overlay] :is(.bio, #profile-bio)::after,
  .nfo::after {
    animation: nfo-drift var(--nfo-dur) linear infinite;   /* no flicker - the images have their own */
  }
}
@keyframes nfo-drift { to { background-position: var(--nfo-end); } }

/* Reduced motion / forced colours: no overlay. The images animate on their
   own (a GIF / WebP ignores the media query), so they can't just be paused. */
@media (prefers-reduced-motion: reduce) {
  [data-name-overlay] :is(h1, #profile-name)::after,
  [data-bio-overlay] :is(.bio, #profile-bio)::after,
  .nfo::after {
    display: none;
  }
}
@media (forced-colors: active) {
  [data-name-overlay] :is(h1, #profile-name)::after,
  [data-bio-overlay] :is(.bio, #profile-bio)::after,
  .nfo::after {
    display: none;
  }
  .nfx {
    background: none;
    color: CanvasText;
    -webkit-text-fill-color: CanvasText;
  }
}
