/* Ratz-GG nameplate paints.
 *
 * SELF-CONTAINED ON PURPOSE: this file is hub-hosted and pulled in by sister
 * sites with a plain <link>, so it must never depend on anything else.
 * No CSS custom properties from globals.css, no Tailwind, literal values only.
 *
 * THREE INDEPENDENT AXES, one class each, they compose:
 *   .rz-c-<id>  colour  - colour and nothing else
 *   .rz-f-<id>  font    - family / style / weight / tracking and nothing else
 *   .rz-e-<id>  effect  - bloom, motion, texture, written to work over ANY colour
 *   .rz-brand   modifier - whites out the trailing <span class="rz-tail">
 * Ids match lib/paints.ts 1:1 (tools/check-paints.mjs proves it).
 *
 * Colours clear ~4.5:1 against the near-black (#0a0a0a) chat background at 13px.
 * Animated effects are all switched off under prefers-reduced-motion (bottom).
 *
 * WHY NO text-shadow ANYWHERE BELOW: a gradient colour paints the glyph with a
 * clipped background and a transparent text fill. text-shadow paints a flat
 * opaque colour into that same glyph box and buries the gradient. Every bloom
 * here is filter: drop-shadow(), which filters the already-composited glyph and
 * leaves the colour underneath alone. Do not "simplify" one back to text-shadow.
 */

/* The base sits in @layer so it loses every tie to an unlayered rule - which is what
 * Tailwind emits. Without this, `.rz-np` (0,1,0) beats `.block` / `.font-medium` /
 * `.font-extrabold` at the call site purely because this file is linked later, and a
 * nameplate silently overrides whatever layout its host gave it. Layered still applies
 * when nothing else sets the property, so gradients keep the box they need.
 * Colour is deliberately absent: unpainted nameplates must inherit from the call site,
 * or `hover:text-accent` on a parent link stops working. The axis rules below are
 * UNLAYERED on purpose, so a chosen paint does win. */
@layer base {
  .rz-np {
    display: inline-block;
    font-weight: 600;
    line-height: 1.2;
    /* background-clip:text crops to the glyph box, so descenders and glow need room. */
    padding: 0 0.06em 0.06em;
    white-space: nowrap;
  }
}

/* =========================================================== COLOUR ======= */
/* Colour classes set colour ONLY - no font, no filter, no background-size.
 * `background-size` belongs to .rz-e-sweep, which is why none of these set it. */

.rz-c-snow { color: #f5f7fa; }
.rz-c-silver { color: #c3c9d4; }
.rz-c-crimson { color: #ff5f57; }
.rz-c-ember { color: #ff8f4d; }
.rz-c-amber { color: #ffc24d; }
.rz-c-lime { color: #bde04a; }
.rz-c-jade { color: #34d399; }
.rz-c-mint { color: #7ef0c8; }
.rz-c-cyan { color: #4fd6f5; }
.rz-c-azure { color: #60a5fa; }
.rz-c-violet { color: #a78bfa; }
.rz-c-magenta { color: #f472b6; }
.rz-c-sakura { color: #ffa8c5; }

/* Gradients keep a real `color` (a mid stop of their own ramp) instead of
 * `color: transparent`. -webkit-text-fill-color is what actually empties the
 * glyph, so the gradient still shows - but currentColor now carries the paint's
 * hue, which is the whole reason .rz-e-glow / bloom / pulse / corona can bloom
 * in the right colour over ANY colour class. It doubles as the fallback fill. */
.rz-c-inferno,
.rz-c-wuxia,
.rz-c-gold-rush,
.rz-c-jade-flow,
.rz-c-venom,
.rz-c-aurora,
.rz-c-ocean,
.rz-c-frost,
.rz-c-chrome,
.rz-c-nebula,
.rz-c-bubblegum,
.rz-c-cyberpunk,
.rz-c-rainbow,
.rz-c-prism,
.rz-c-vaporwave,
.rz-c-koi,
.rz-c-neon-sign,
.rz-c-jade-tiger,
.rz-c-spectrum-drift,
.rz-c-tidal,
.rz-c-moonlit,
.rz-c-candleflame,
.rz-c-quicksilver,
.rz-c-cascade,
.rz-c-comet,
.rz-c-lantern,
.rz-c-cotton-candy,
.rz-c-strawberry-milk,
.rz-c-fairy-floss,
.rz-c-peach-sorbet,
.rz-c-bunny,
.rz-c-creamsicle,
.rz-c-pixie-dust,
.rz-c-mermaid,
.rz-c-unicorn,
.rz-c-cupcake,
.rz-c-starlight,
.rz-c-berry-burst,
.rz-c-candy-apple,
.rz-c-frosted-mint,
.rz-c-honey-dew,
.rz-c-plum-blossom,
.rz-c-sea-glass,
.rz-c-moonbeam,
.rz-c-rose-quartz,
.rz-c-opal {
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Smooth ramps are palindromic (first stop == last stop): tiled by .rz-e-sweep
 * they loop without a hard seam sliding through the middle of a name. */
.rz-c-inferno { color: #ff8f4d; background-image: linear-gradient(90deg, #ffd166, #ff5f57, #ffd166); }
.rz-c-wuxia { color: #ff9a5c; background-image: linear-gradient(90deg, #ff7a5c, #f2c14e, #ff7a5c); }
.rz-c-gold-rush { color: #f2c14e; background-image: linear-gradient(90deg, #fff6cf, #f2c14e, #fff6cf); }
.rz-c-jade-flow { color: #6ee7b7; background-image: linear-gradient(90deg, #b8f5d8, #34d399, #b8f5d8); }
.rz-c-venom { color: #8ae06a; background-image: linear-gradient(90deg, #ccff5a, #34d399, #ccff5a); }
.rz-c-aurora { color: #86c8ea; background-image: linear-gradient(90deg, #7ef0c8, #60a5fa, #a78bfa, #7ef0c8); }
.rz-c-ocean { color: #6fc7fa; background-image: linear-gradient(90deg, #7fe9ff, #60a5fa, #7fe9ff); }
.rz-c-frost { color: #c8e6ff; background-image: linear-gradient(90deg, #eaf6ff, #9fd0ff, #eaf6ff); }
.rz-c-chrome { color: #d8dde5; background-image: linear-gradient(90deg, #ffffff, #aab3c2, #ffffff); }
.rz-c-nebula { color: #cd7fd8; background-image: linear-gradient(90deg, #a78bfa, #f472b6, #a78bfa); }
.rz-c-bubblegum { color: #bfb3e6; background-image: linear-gradient(90deg, #ff9ecd, #7ec8ff, #ff9ecd); }
.rz-c-cyberpunk { color: #8fb8f0; background-image: linear-gradient(90deg, #22e0ff, #ff6fdd, #22e0ff); }
.rz-c-rainbow { color: #ffc24d; background-image: linear-gradient(90deg, #ff6b6b, #ffc24d, #bde04a, #4fd6f5, #a78bfa, #ff6b6b); }

/* Banded on purpose. A two-stop fade at 13px reads as one muddy off-colour, so
 * every stop below is a hard edge and each band survives at nameplate size.
 * Hard edges everywhere also means the sweep tiling seam is just another band. */
.rz-c-prism {
  color: #ffc24d;
  background-image: linear-gradient(90deg, #ff6b6b 20%, #ffc24d 20%, #ffc24d 40%, #7ef0c8 40%, #7ef0c8 60%, #4fd6f5 60%, #4fd6f5 80%, #a78bfa 80%);
}

.rz-c-vaporwave {
  color: #ff6fdd;
  background-image: linear-gradient(90deg, #22e0ff 34%, #ff6fdd 34%, #ff6fdd 67%, #b07bff 67%);
}

.rz-c-koi {
  color: #ff8f4d;
  background-image: linear-gradient(90deg, #fff2e0 30%, #ff8f4d 30%, #ff8f4d 65%, #ff5f57 65%);
}

.rz-c-neon-sign {
  color: #33e1ff;
  background-image: linear-gradient(90deg, #ff5fae 34%, #33e1ff 34%, #33e1ff 67%, #ccff5a 67%);
}

.rz-c-jade-tiger {
  color: #7fdba8;
  background-image: linear-gradient(90deg, #34d399 28%, #ffd166 28%, #ffd166 55%, #34d399 55%, #34d399 80%, #ffd166 80%);
}

/* ------------------------------------------------- animated colours ------ */
/* The ramp itself moves, so motion no longer costs the effect slot - these are
 * the only colour classes that own background-size, background-position and an
 * animation.
 *
 * MOTION IS background-* ONLY. The obvious way to write a travelling hue is
 * `filter: hue-rotate()`, and it is a trap: filter is exactly the property every
 * bloom effect uses, so the colour would silently delete the effect axis. Nothing
 * below touches filter, which is what keeps .rz-e-glow / bloom / etch / emboss
 * composing over all eight. (A colour and an animated EFFECT still contend for the
 * one `animation` property; the effect is declared later and wins. That pairing is
 * redundant anyway - these exist so motion can be had WITH a bloom.)
 *
 * SEAMS: a looping travel must move exactly one tile, or the restart snaps a
 * visible jump through the middle of a name. At background-size S%, one tile is a
 * position delta of -100*S/(S-100) percent - which is why 200% pairs with -200%
 * and 300% with -150%. The two that never wrap (tidal alternates, candleflame
 * returns to its own first frame) are free of it. */

/* Travelling hue cycle: the whole spectrum walks through the name, one way, forever. */
.rz-c-spectrum-drift {
  color: #ffc24d;
  background-image: linear-gradient(90deg, #ff6b6b, #ffc24d, #bde04a, #34d399, #4fd6f5, #a78bfa, #ff6b6b);
  background-size: 300% 100%;
  animation: rz-c-spectrum-drift 9s linear infinite;
}

/* Slow ramp drift: eases out to one edge and back, never loops, so no seam to hide. */
.rz-c-tidal {
  color: #6fc7fa;
  background-image: linear-gradient(90deg, #7fe9ff, #60a5fa, #7ef0c8, #60a5fa, #7fe9ff);
  background-size: 220% 100%;
  animation: rz-c-tidal 9s ease-in-out infinite alternate;
}

/* Two-tone shimmer: steel and lilac sit still, then a narrow specular band glints
 * across. The hold is in the keyframes, not the easing - a slow constant crawl
 * reads as a sweep, a still name that catches the light reads as silk. */
.rz-c-moonlit {
  color: #b0c4f7;
  background-image: linear-gradient(100deg, #8fb8f0 0 30%, #ffffff 42% 46%, #cdb8ff 58% 70%, #8fb8f0 82% 100%);
  background-size: 200% 100%;
  animation: rz-c-moonlit 5s linear infinite;
}

/* Candle flicker: steps(1) so every frame is a jump, never a slide, and the
 * offsets are deliberately uneven - evenly spaced jumps read as a machine. */
.rz-c-candleflame {
  color: #ffb454;
  background-image: linear-gradient(90deg, #ffd166, #ff8f4d, #ffe6a3, #ff8f4d, #ffd166);
  background-size: 180% 100%;
  animation: rz-c-candleflame 1.7s steps(1, end) infinite;
}

/* Liquid metal: highlights roll, accelerate through the middle and stall at both
 * ends, which is the weight a linear sweep across chrome never has. */
.rz-c-quicksilver {
  color: #d8dde5;
  background-image: linear-gradient(90deg, #ffffff, #9aa4b4, #ffffff, #aab3c2, #ffffff);
  background-size: 200% 100%;
  animation: rz-c-quicksilver 5.5s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}

/* The only vertical one: a 180deg ramp falling down through the glyph. */
.rz-c-cascade {
  color: #7ef0c8;
  background-image: linear-gradient(180deg, #b8f5d8, #34d399, #7fe9ff, #34d399, #b8f5d8);
  background-size: 100% 300%;
  animation: rz-c-cascade 4.5s linear infinite;
}

/* Diagonal streak, corner to corner - both axes travel a tile per cycle. */
.rz-c-comet {
  color: #cd7fd8;
  background-image: linear-gradient(135deg, #a78bfa 0 34%, #ffffff 42% 48%, #f472b6 56% 78%, #a78bfa 90% 100%);
  background-size: 200% 200%;
  animation: rz-c-comet 6s linear infinite;
}

/* Breathing, not travelling: background-SIZE animates around a pinned centre, so
 * the hot core swells over the whole name and shrinks back without moving. */
.rz-c-lantern {
  color: #ff8f4d;
  background-image: radial-gradient(ellipse at 50% 50%, #ffd7a8 0%, #ff8f4d 55%, #ff5f57 100%);
  background-position: 50% 50%;
  background-size: 220% 100%;
  animation: rz-c-lantern 3.8s ease-in-out infinite alternate;
}

/* ------------------------------------------------- premium cutesy colours -- */
/* Full-access-only (monthly / Twitch sub) gradients. Pastel, sweet, playful.
 * Every one sets a mid-stop `color` for effect bloom matching. */

.rz-c-cotton-candy { color: #f7a8d4; background-image: linear-gradient(90deg, #ffb3d9, #a8d8ff, #ffb3d9); }
.rz-c-strawberry-milk { color: #ffafcc; background-image: linear-gradient(90deg, #ffd6e0, #ffafcc, #fff0f5, #ffafcc); }
.rz-c-fairy-floss { color: #d4b8f0; background-image: linear-gradient(90deg, #e8d5f5, #ffb3d9, #d4b8f0, #e8d5f5); }
.rz-c-peach-sorbet { color: #ffcba4; background-image: linear-gradient(90deg, #ffe5cc, #ffcba4, #fff5eb, #ffcba4); }
.rz-c-bunny { color: #fbc4d0; background-image: linear-gradient(90deg, #fff0f3, #fbc4d0, #ffffff, #fbc4d0); }
.rz-c-creamsicle { color: #ffb88c; background-image: linear-gradient(90deg, #ffe0c0, #ffb88c, #fff8f0, #ffb88c); }
.rz-c-pixie-dust { color: #f0d890; background-image: linear-gradient(90deg, #fff8e0, #f0d890, #ffffff, #f0d890); }
.rz-c-mermaid { color: #70d6c7; background-image: linear-gradient(90deg, #a8f0e4, #70d6c7, #c4b5f0, #70d6c7); }
.rz-c-unicorn { color: #e8b4f0; background-image: linear-gradient(90deg, #ffd6e8, #d6e8ff, #e8d6ff, #ffd6e8); }
.rz-c-cupcake { color: #ffb3c6; background-image: linear-gradient(90deg, #ffd6e0, #b8f0d8, #ffb3c6, #ffd6e0); }
.rz-c-starlight { color: #d4d8f0; background-image: linear-gradient(90deg, #e8eaf8, #d4d8f0, #f0e8ff, #d4d8f0); }
.rz-c-berry-burst { color: #e07090; background-image: linear-gradient(90deg, #ff8faa, #c070e0, #ff8faa); }
.rz-c-candy-apple { color: #ff6070; background-image: linear-gradient(90deg, #ff98a8, #ff6070, #ffb8c0, #ff6070); }
.rz-c-frosted-mint { color: #b8f0d8; background-image: linear-gradient(90deg, #d8f8e8, #b8f0d8, #ffffff, #b8f0d8); }
.rz-c-honey-dew { color: #d0e878; background-image: linear-gradient(90deg, #e8f8b8, #d0e878, #f0d890, #d0e878); }
.rz-c-plum-blossom { color: #b890d8; background-image: linear-gradient(90deg, #d8c0f0, #b890d8, #ffb8d0, #b890d8); }
.rz-c-sea-glass { color: #a8e0d0; background-image: linear-gradient(90deg, #d0f0e8, #a8e0d0, #c8f0e0, #a8e0d0); }
.rz-c-moonbeam { color: #c8d8f0; background-image: linear-gradient(90deg, #e8eff8, #c8d8f0, #f0f4ff, #c8d8f0); }
.rz-c-rose-quartz { color: #e8c0c8; background-image: linear-gradient(90deg, #f0d8e0, #e8c0c8, #f8e8e8, #e8c0c8); }
.rz-c-opal { color: #c8e0e8; background-image: linear-gradient(90deg, #e0f0f4, #d0c8f0, #f0d8e0, #e0f0f0, #c8e0e8, #e0f0f4); }

/* ============================================================= FONT ======= */
/* Family / style / weight / tracking ONLY. A font class that touched colour
 * would silently beat the colour axis, which is the bug this split exists to kill. */

.rz-f-serif {
  font-family: Georgia, 'Times New Roman', serif;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.rz-f-mono {
  font-family: 'JetBrains Mono', Consolas, 'SF Mono', ui-monospace, monospace;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.rz-f-italic {
  font-family: 'Palatino Linotype', Palatino, Georgia, serif;
  font-style: italic;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.rz-f-wide {
  font-weight: 600;
  letter-spacing: 0.14em;
}

.rz-f-heavy {
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* No webfont is loaded anywhere, here or on the sister sites, so every stack below
 * is a bet on faces that ship with Windows / macOS and MUST still look deliberate
 * on a machine with none of them. That is what the weight and tracking on each rule
 * are for: they carry the intent (tight and dark, airy and engraved) after the
 * family list has fallen all the way through to a generic. */

.rz-f-condensed {
  font-family: 'Arial Narrow', 'Roboto Condensed', 'Liberation Sans Narrow', 'Helvetica Neue', sans-serif;
  font-weight: 700;
  letter-spacing: -0.03em;
}

.rz-f-rounded {
  font-family: ui-rounded, 'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Quicksand, 'Trebuchet MS', sans-serif;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.rz-f-blackletter {
  font-family: 'Old English Text MT', 'Blackadder ITC', Luminari, Trattatello, 'Palatino Linotype', serif;
  font-weight: 700;
  letter-spacing: 0.03em;
}

/* Engraved small caps by FAMILY, not by font-variant-caps: this axis is allowed to
 * set family/style/weight/tracking and nothing else, and Copperplate is the face
 * that carries the look on its own. Wide tracking is what keeps the fallback serif
 * reading as an inscription rather than as a plain serif. */
.rz-f-smallcaps {
  font-family: Copperplate, 'Copperplate Gothic Light', Optima, 'Palatino Linotype', serif;
  font-weight: 600;
  letter-spacing: 0.1em;
}

.rz-f-slab {
  font-family: Rockwell, 'Roboto Slab', 'Bookman Old Style', 'Courier New', ui-monospace, monospace;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.rz-f-hand {
  font-family: 'Segoe Script', 'Bradley Hand', 'Ink Free', 'Comic Sans MS', cursive;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* --- cutesy fonts --- */

.rz-f-bubble {
  font-family: 'Baloo 2', 'Comic Neue', 'Nunito', 'Segoe UI Rounded', ui-rounded, sans-serif;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.rz-f-doodle {
  font-family: 'Patrick Hand', 'Ink Free', 'Bradley Hand', 'Comic Sans MS', cursive;
  font-weight: 400;
  letter-spacing: 0.04em;
}

.rz-f-sparkle {
  font-family: 'Quicksand', 'Nunito', 'Segoe UI Rounded', ui-rounded, sans-serif;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.rz-f-girly {
  font-family: 'Pacifico', 'Brush Script MT', 'Segoe Script', 'Great Vibes', cursive;
  font-weight: 400;
  letter-spacing: 0.03em;
}

.rz-f-pixel {
  font-family: 'Press Start 2P', 'Courier New', ui-monospace, monospace;
  font-weight: 400;
  letter-spacing: 0.02em;
  font-size: 0.75em;
}

.rz-f-fairy {
  font-family: 'Cormorant Garamond', 'Palatino Linotype', Optima, Georgia, serif;
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0.12em;
}

.rz-f-dream {
  font-family: 'Snell Roundhand', 'Brush Script MT', 'Great Vibes', 'Segoe Script', cursive;
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0.05em;
}

.rz-f-soft {
  font-family: 'Nunito', 'Baloo 2', 'Quicksand', ui-rounded, sans-serif;
  font-weight: 500;
  letter-spacing: 0.03em;
}

.rz-f-candy {
  font-family: 'Fredoka One', 'Baloo 2', 'Nunito', ui-rounded, sans-serif;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.rz-f-pop {
  font-family: 'Luckiest Guy', 'Fredoka One', Impact, 'Arial Black', sans-serif;
  font-weight: 400;
  letter-spacing: 0.02em;
}

.rz-f-swirl {
  font-family: 'Cedarville Cursive', 'Segoe Print', 'Bradley Hand', 'Ink Free', cursive;
  font-weight: 400;
  letter-spacing: 0.01em;
}

.rz-f-ribbon {
  font-family: 'Satisfy', 'Brush Script MT', 'Great Vibes', 'Segoe Script', cursive;
  font-weight: 400;
  letter-spacing: 0.06em;
}

.rz-f-cherry {
  font-family: 'Lobster Two', 'Pacifico', 'Brush Script MT', cursive;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.rz-f-marshmallow {
  font-family: 'Comfortaa', 'Nunito', 'Quicksand', ui-rounded, sans-serif;
  font-weight: 400;
  letter-spacing: 0.06em;
}

/* =========================================================== EFFECT ======= */
/* Bloom: drop-shadow(currentColor). Because every colour class sets a real
 * `color` - gradients included - the bloom always matches the paint under it. */

.rz-e-glow {
  filter: drop-shadow(0 0 2px currentColor) drop-shadow(0 0 8px currentColor);
}

.rz-e-bloom {
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.9)) drop-shadow(0 0 6px currentColor) drop-shadow(0 0 16px currentColor);
}

.rz-e-pulse {
  filter: drop-shadow(0 0 2px currentColor) drop-shadow(0 0 10px currentColor);
  animation: rz-e-pulse 2.4s ease-in-out infinite;
}

.rz-e-corona {
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.95)) drop-shadow(0 0 10px currentColor) drop-shadow(0 0 24px currentColor);
  animation: rz-e-corona 3.6s ease-in-out infinite;
}

/* Drifts the colour's own ramp. Owns background-size so no colour class has to:
 * on a solid colour there is no background image to move and this is inert. */
.rz-e-sweep {
  background-size: 260% 100%;
  animation: rz-e-sweep 6s linear infinite;
}

/* A travelling highlight, done as a mask rather than an extra background layer -
 * a background layer would have to replace the colour's own gradient. The base
 * sits at 0.82 alpha so the band reads as brighter than the rest; the darkest
 * colour here still clears 4.5:1 at that alpha. */
.rz-e-shimmer {
  -webkit-mask-image: linear-gradient(100deg, rgba(0, 0, 0, 0.82) 40%, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0.82) 60%);
  mask-image: linear-gradient(100deg, rgba(0, 0, 0, 0.82) 40%, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0.82) 60%);
  -webkit-mask-size: 300% 100%;
  mask-size: 300% 100%;
  animation: rz-e-shimmer 4.5s linear infinite;
}

/* Textures are masks for the same reason: they carve the glyph the colour axis
 * already painted, instead of fighting it for background-image. Single layer
 * each - stacked mask layers composite as a union and cancel the pattern out. */
.rz-e-etch {
  -webkit-mask-image: repeating-linear-gradient(115deg, rgba(0, 0, 0, 1) 0 3px, rgba(0, 0, 0, 0.55) 3px 4px);
  mask-image: repeating-linear-gradient(115deg, rgba(0, 0, 0, 1) 0 3px, rgba(0, 0, 0, 0.55) 3px 4px);
}

.rz-e-scale {
  -webkit-mask-image: repeating-radial-gradient(circle at 50% 0, rgba(0, 0, 0, 1) 0 3px, rgba(0, 0, 0, 0.5) 3px 4px);
  mask-image: repeating-radial-gradient(circle at 50% 0, rgba(0, 0, 0, 1) 0 3px, rgba(0, 0, 0, 0.5) 3px 4px);
}

.rz-e-dust {
  -webkit-mask-image: repeating-radial-gradient(circle at 0 0, rgba(0, 0, 0, 0.55) 0 1px, rgba(0, 0, 0, 1) 1px 5px);
  mask-image: repeating-radial-gradient(circle at 0 0, rgba(0, 0, 0, 0.55) 0 1px, rgba(0, 0, 0, 1) 1px 5px);
}

.rz-e-emboss {
  filter: drop-shadow(0 -1px 0 rgba(255, 255, 255, 0.45)) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.95));
}

/* --- cutesy effects --- */

/* Sparkle: tiny white particle specks drift upward through the glyph. Animated
 * mask overlay - the colour underneath stays intact. */
.rz-e-sparkle {
  filter: drop-shadow(0 0 2px currentColor) drop-shadow(0 0 6px currentColor);
  animation: rz-e-sparkle 2.8s ease-in-out infinite;
}

/* Bounce: gentle vertical hop, like a bunny. Translates the whole element, so
 * the glyph stays sharp - no blur like a filter animation. */
.rz-e-bounce {
  animation: rz-e-bounce 0.6s ease-in-out infinite;
}

/* Wiggle: playful side-to-side shimmy with a tiny rotation. */
.rz-e-wiggle {
  animation: rz-e-wiggle 1.2s ease-in-out infinite;
}

/* Twinkle: star-like opacity pulse. Uses opacity rather than filter so it composes
 * over any colour or glow without burying them. */
.rz-e-twinkle {
  animation: rz-e-twinkle 1.8s ease-in-out infinite;
}

/* Frosted: a soft translucent blur behind the glyph, like etched glass.
 * Static - available to lifetime. */
.rz-e-frosted {
  filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.7)) drop-shadow(0 0 8px currentColor) drop-shadow(0 0 18px rgba(200, 210, 255, 0.25));
}

/* Prism: subtle rainbow banding on the glyph's edges via staggered drop-shadows.
 * Static - available to lifetime. */
.rz-e-prism {
  filter:
    drop-shadow(1px 0 0 rgba(255, 107, 107, 0.45))
    drop-shadow(-1px 0 0 rgba(77, 214, 245, 0.45))
    drop-shadow(0 1px 0 rgba(189, 224, 74, 0.45))
    drop-shadow(0 -1px 0 rgba(167, 139, 250, 0.45));
}

/* Float: gentle up-down hover like a balloon. */
.rz-e-float {
  animation: rz-e-float 3s ease-in-out infinite;
}

/* Peekaboo: scale pulse, like it's saying hello. */
.rz-e-peekaboo {
  animation: rz-e-peekaboo 1.5s ease-in-out infinite;
}

/* Glimmer: quick shimmer sweep across the glyph using mask. */
.rz-e-glimmer {
  -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,0.5) 30%, rgba(0,0,0,1) 48%, rgba(0,0,0,1) 52%, rgba(0,0,0,0.5) 70%);
  mask-image: linear-gradient(90deg, rgba(0,0,0,0.5) 30%, rgba(0,0,0,1) 48%, rgba(0,0,0,1) 52%, rgba(0,0,0,0.5) 70%);
  -webkit-mask-size: 400% 100%;
  mask-size: 400% 100%;
  animation: rz-e-glimmer 2.2s ease-in-out infinite;
}

/* Hearts: pulsing glow with a warm pink tint. */
.rz-e-hearts {
  filter:
    drop-shadow(0 0 3px rgba(255, 150, 180, 0.8))
    drop-shadow(0 0 8px rgba(255, 120, 160, 0.5))
    drop-shadow(0 0 16px currentColor);
  animation: rz-e-hearts 2s ease-in-out infinite;
}

/* Squish: horizontal squash-and-stretch. */
.rz-e-squish {
  animation: rz-e-squish 0.8s ease-in-out infinite;
}

/* Stars: rotating starfield shimmer. Uses background clip area glow. */
.rz-e-stars {
  filter:
    drop-shadow(0 0 2px rgba(255, 255, 200, 0.9))
    drop-shadow(0 0 5px currentColor)
    drop-shadow(0 0 12px currentColor);
  animation: rz-e-stars 2.5s ease-in-out infinite;
}

/* Rainbow Halo: soft rainbow glow ring. Static. */
.rz-e-rainbow-halo {
  filter:
    drop-shadow(0 0 3px rgba(255, 107, 107, 0.6))
    drop-shadow(0 0 6px rgba(255, 194, 77, 0.5))
    drop-shadow(0 0 9px rgba(189, 224, 74, 0.5))
    drop-shadow(0 0 12px rgba(77, 214, 245, 0.5))
    drop-shadow(0 0 15px rgba(167, 139, 250, 0.5));
}

/* Soft Glow: the gentlest bloom. Static - a subtler alternative to Glow. */
.rz-e-soft-glow {
  filter: drop-shadow(0 0 1px currentColor) drop-shadow(0 0 4px currentColor);
}

/* ============================================================ BRAND ======= */
/* The wordmark cut: last two glyphs white, the way RATZ·GG sets GG apart. The
 * tail is a nested <span class="rz-tail"> the Nameplate always emits - a child
 * element is the only thing that can opt out of the parent's inherited fill.
 * NOTE: .rz-tail deliberately has no rule of its own outside this selector, so
 * without .rz-brand it inherits everything and renders as the surrounding text. */

.rz-brand .rz-tail {
  color: #ffffff;
  /* Opaque fill on the child paints over the parent's clipped gradient, which is
   * what gives a gradient colour a white tail without a second element. */
  -webkit-text-fill-color: #ffffff;
}

@keyframes rz-c-spectrum-drift {
  from { background-position: 0% 50%; }
  to { background-position: -150% 50%; }
}

@keyframes rz-c-tidal {
  from { background-position: 0% 50%; }
  to { background-position: 100% 50%; }
}

@keyframes rz-c-moonlit {
  0%, 55% { background-position: 0% 50%; }
  100% { background-position: -200% 50%; }
}

@keyframes rz-c-candleflame {
  0% { background-position: 12% 50%; }
  17% { background-position: 63% 50%; }
  29% { background-position: 31% 50%; }
  46% { background-position: 78% 50%; }
  58% { background-position: 44% 50%; }
  71% { background-position: 91% 50%; }
  83% { background-position: 24% 50%; }
  100% { background-position: 12% 50%; }
}

@keyframes rz-c-quicksilver {
  from { background-position: 0% 50%; }
  to { background-position: -200% 50%; }
}

@keyframes rz-c-cascade {
  from { background-position: 50% 0%; }
  to { background-position: 50% -150%; }
}

@keyframes rz-c-comet {
  from { background-position: 0% 0%; }
  to { background-position: -200% -200%; }
}

@keyframes rz-c-lantern {
  from { background-size: 110% 100%; }
  to { background-size: 340% 100%; }
}

@keyframes rz-e-sweep {
  from { background-position: 0% 50%; }
  to { background-position: -200% 50%; }
}

@keyframes rz-e-shimmer {
  from { -webkit-mask-position: 150% 50%; mask-position: 150% 50%; }
  to { -webkit-mask-position: -50% 50%; mask-position: -50% 50%; }
}

@keyframes rz-e-pulse {
  0%, 100% { filter: drop-shadow(0 0 2px currentColor) drop-shadow(0 0 10px currentColor); }
  50% { filter: drop-shadow(0 0 1px currentColor) drop-shadow(0 0 4px currentColor); }
}

@keyframes rz-e-corona {
  0%, 100% {
    filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.95)) drop-shadow(0 0 10px currentColor) drop-shadow(0 0 24px currentColor);
  }
  50% {
    filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.7)) drop-shadow(0 0 6px currentColor) drop-shadow(0 0 14px currentColor);
  }
}

@keyframes rz-e-sparkle {
  0%, 100% {
    filter: drop-shadow(0 0 2px currentColor) drop-shadow(0 0 6px currentColor);
  }
  50% {
    filter: drop-shadow(0 0 3px currentColor) drop-shadow(0 0 12px currentColor)
      drop-shadow(0 -1px 1px rgba(255, 255, 255, 0.8)) drop-shadow(1px 0 1px rgba(255, 255, 255, 0.6));
  }
}

@keyframes rz-e-bounce {
  0%, 100% { transform: translateY(0); }
  30% { transform: translateY(-3px); }
  50% { transform: translateY(0); }
  70% { transform: translateY(-1.5px); }
}

@keyframes rz-e-wiggle {
  0%, 100% { transform: translateX(0) rotate(0deg); }
  15% { transform: translateX(-2px) rotate(-1deg); }
  35% { transform: translateX(2px) rotate(1deg); }
  55% { transform: translateX(-1px) rotate(-0.5deg); }
  75% { transform: translateX(1px) rotate(0.5deg); }
}

@keyframes rz-e-twinkle {
  0%, 100% { opacity: 1; }
  40% { opacity: 0.55; }
  60% { opacity: 1; }
  80% { opacity: 0.75; }
}

@keyframes rz-e-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

@keyframes rz-e-peekaboo {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}

@keyframes rz-e-glimmer {
  0% { -webkit-mask-position: 200% 50%; mask-position: 200% 50%; }
  100% { -webkit-mask-position: -200% 50%; mask-position: -200% 50%; }
}

@keyframes rz-e-hearts {
  0%, 100% {
    filter:
      drop-shadow(0 0 3px rgba(255, 150, 180, 0.8))
      drop-shadow(0 0 8px rgba(255, 120, 160, 0.5))
      drop-shadow(0 0 16px currentColor);
  }
  50% {
    filter:
      drop-shadow(0 0 5px rgba(255, 150, 180, 1))
      drop-shadow(0 0 14px rgba(255, 120, 160, 0.8))
      drop-shadow(0 0 26px currentColor);
  }
}

@keyframes rz-e-squish {
  0%, 100% { transform: scaleX(1) scaleY(1); }
  25% { transform: scaleX(1.06) scaleY(0.94); }
  75% { transform: scaleX(0.94) scaleY(1.06); }
}

@keyframes rz-e-stars {
  0%, 100% {
    filter:
      drop-shadow(0 0 2px rgba(255, 255, 200, 0.9))
      drop-shadow(0 0 5px currentColor)
      drop-shadow(0 0 12px currentColor);
  }
  50% {
    filter:
      drop-shadow(0 0 3px rgba(255, 255, 200, 1))
      drop-shadow(0 0 8px currentColor)
      drop-shadow(0 0 20px currentColor);
  }
}

@media (prefers-reduced-motion: reduce) {
  .rz-e-pulse,
  .rz-e-corona,
  .rz-e-sweep,
  .rz-e-shimmer {
    animation: none;
    background-position: 0% 50%;
    -webkit-mask-position: 50% 50%;
    mask-position: 50% 50%;
  }

  /* Cutesy animated effects */
  .rz-e-sparkle,
  .rz-e-bounce,
  .rz-e-wiggle,
  .rz-e-twinkle,
  .rz-e-float,
  .rz-e-peekaboo,
  .rz-e-glimmer,
  .rz-e-hearts,
  .rz-e-squish,
  .rz-e-stars {
    animation: none;
  }

  .rz-e-sparkle {
    filter: drop-shadow(0 0 2px currentColor) drop-shadow(0 0 6px currentColor);
  }

  .rz-e-bounce { transform: translateY(0); }
  .rz-e-wiggle { transform: translateX(0) rotate(0deg); }
  .rz-e-twinkle { opacity: 1; }
  .rz-e-float { transform: translateY(0); }
  .rz-e-peekaboo { transform: scale(1); }
  .rz-e-glimmer { -webkit-mask-position: 50% 50%; mask-position: 50% 50%; }
  .rz-e-hearts {
    filter:
      drop-shadow(0 0 3px rgba(255, 150, 180, 0.8))
      drop-shadow(0 0 8px rgba(255, 120, 160, 0.5))
      drop-shadow(0 0 16px currentColor);
  }
  .rz-e-squish { transform: scaleX(1) scaleY(1); }
  .rz-e-stars {
    filter:
      drop-shadow(0 0 2px rgba(255, 255, 200, 0.9))
      drop-shadow(0 0 5px currentColor)
      drop-shadow(0 0 12px currentColor);
  }

  /* Every animated colour, parked centred rather than at 0% - each of these ramps
   * has its interesting stops in the middle, and the edge frame of a two-tone or a
   * radial is the one that reads as a flat colour. */
  .rz-c-spectrum-drift,
  .rz-c-tidal,
  .rz-c-moonlit,
  .rz-c-candleflame,
  .rz-c-quicksilver,
  .rz-c-cascade,
  .rz-c-comet,
  .rz-c-lantern {
    animation: none;
    background-position: 50% 50%;
  }
}
