﻿@keyframes blobOrbit1 {
  0%   { transform: translate(0,    0)    scale(1); }
  25%  { transform: translate(80px, 60px) scale(1.12); }
  50%  { transform: translate(40px, 120px) scale(0.95); }
  75%  { transform: translate(-60px, 50px) scale(1.08); }
  100% { transform: translate(0,    0)    scale(1); }
}
@keyframes blobOrbit2 {
  0%   { transform: translate(0,    0)    scale(1); }
  25%  { transform: translate(-90px, 40px) scale(1.05); }
  50%  { transform: translate(-50px, -80px) scale(0.92); }
  75%  { transform: translate(60px, -40px) scale(1.15); }
  100% { transform: translate(0,    0)    scale(1); }
}
@keyframes blobOrbit3 {
  0%   { transform: translate(0,    0)    scale(1); }
  33%  { transform: translate(70px, -60px) scale(1.1); }
  66%  { transform: translate(-50px, -90px) scale(0.9); }
  100% { transform: translate(0,    0)    scale(1); }
}

/* The line of letters drifts side-to-side as one body. */
@keyframes lineSway {
  0%   { transform: translateX(-8px); }
  100% { transform: translateX(8px); }
}

/* Two adjacent tiles dip UNDER the line and slip past each other (their
   --tx values are swapped, so the top/left transition slides them sideways
   while these keyframes carry them down and back). */
@keyframes bridgeArcLeft {
  0%   { transform: translate(0, 0)      rotate(0deg)  scale(1); }
  50%  { transform: translate(-6px, 30px) rotate(-6deg) scale(1.08); }
  100% { transform: translate(0, 0)      rotate(0deg)  scale(1); }
}
@keyframes bridgeArcRight {
  0%   { transform: translate(0, 0)      rotate(0deg) scale(1); }
  50%  { transform: translate(6px, -30px) rotate(6deg) scale(1.08); }
  100% { transform: translate(0, 0)      rotate(0deg) scale(1); }
}

/* Earned letter drops in from above the line and settles with a small bounce. */
@keyframes gravityDrop {
  0%   { transform: translateY(-180px); opacity: 0; }
  55%  { transform: translateY(10px);   opacity: 1; }
  78%  { transform: translateY(-4px); }
  100% { transform: translateY(0); }
}

@keyframes centerPulse {
  0%, 100% { box-shadow:
    0 10px 28px -10px rgba(250,199,117,0.5),
    inset 0 -3px 10px rgba(110,55,0,0.35),
    inset 0 2px 8px rgba(255,255,255,0.5),
    0 0 0 0 rgba(250,199,117,0.4); }
  50%      { box-shadow:
    0 10px 30px -10px rgba(250,199,117,0.7),
    inset 0 -3px 10px rgba(110,55,0,0.35),
    inset 0 2px 8px rgba(255,255,255,0.6),
    0 0 0 12px rgba(250,199,117,0); }
}

@keyframes driftPulse {
  0%, 100% { box-shadow:
    0 10px 28px -10px rgba(93,202,165,0.55),
    inset 0 -3px 10px rgba(0,40,28,0.35),
    inset 0 2px 8px rgba(255,255,255,0.45),
    0 0 0 0 rgba(93,202,165,0.5); }
  50%      { box-shadow:
    0 10px 30px -10px rgba(93,202,165,0.8),
    inset 0 -3px 10px rgba(0,40,28,0.35),
    inset 0 2px 8px rgba(255,255,255,0.55),
    0 0 0 14px rgba(93,202,165,0); }
}

/* Drift entry: pops into existence at its line slot (no "above" position). */
@keyframes driftAppear {
  0%   { transform: scale(0.2); opacity: 0; }
  60%  { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
/* Drift = dark-blue tile + purple halo that pulses to flag "new". */
@keyframes driftPurplePulse {
  0%, 100% { box-shadow:
    0 10px 28px -10px rgba(106,79,245,0.65),
    inset 0 -3px 10px rgba(5,3,20,0.45),
    inset 0 2px 8px rgba(168,140,255,0.5),
    0 0 0 0 rgba(168,90,255,0.55); }
  50%      { box-shadow:
    0 10px 30px -10px rgba(168,90,255,0.95),
    inset 0 -3px 10px rgba(5,3,20,0.45),
    inset 0 2px 8px rgba(200,170,255,0.6),
    0 0 0 16px rgba(168,90,255,0); }
}

/* Pop = scale-only bounce. The persistent tilt lives on the tile's `rotate`
   property (see .tile in tiles.css) so the letter STAYS at its random angle
   between taps — re-tapping the same letter just transitions it to a new
   --tilt-deg, no shake-back-to-upright. */
@keyframes tilePop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.18); }
  100% { transform: scale(1); }
}

@keyframes tileWobble {
  0%   { transform: rotate(0deg) scale(1); }
  25%  { transform: translateY(-6px) rotate(-6deg) scale(1.08); }
  60%  { transform: rotate(4deg) scale(1.04); }
  100% { transform: rotate(0deg) scale(1); }
}

@keyframes earnedShimmer {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.05); }
}
@keyframes earnedSparkle {
  0%   { box-shadow:
    0 10px 28px -8px rgba(93,202,165,0.6),
    0 0 0 0 rgba(93,202,165,0.7); }
  50%  { box-shadow:
    0 10px 30px -8px rgba(93,202,165,0.9),
    0 0 0 18px rgba(93,202,165,0); }
  100% { box-shadow: 0 8px 24px -8px rgba(0,0,0,0.5); }
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-8px); }
  40% { transform: translateX(8px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(5px); }
}

@keyframes fadeInUp {
  0%   { opacity: 0; transform: translateY(8px); }
  100% { opacity: 1; transform: translateY(0); }
}

@keyframes floatUp {
  0%   { opacity: 0; transform: translate(-50%, 0) scale(0.8); }
  20%  { opacity: 1; transform: translate(-50%, -10px) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -80px) scale(0.9); }
}
.float-pts {
  position: absolute; left: 50%; top: 30%;
  font-size: 28px; font-weight: 800;
  color: var(--accent);
  text-shadow: 0 0 12px rgba(244,168,216,0.7);
  pointer-events: none; z-index: 4;
  animation: floatUp 1.2s ease-out forwards;
}
.float-pts.weerrd { color: var(--seagreen); text-shadow: 0 0 12px rgba(93,202,165,0.8); }

/* Top-mounted toasts: drop down into view, lift back up to dismiss. */
@keyframes toastIn  { 0% { opacity: 0; transform: translateY(-20px); }
                     100%{ opacity: 1; transform: translateY(0); } }
@keyframes toastOut { 0% { opacity: 1; transform: translateY(0); }
                     100%{ opacity: 0; transform: translateY(-12px); } }

/* "Wild Weerrd!" celebration ripples — multiple rings expanding from center,
   each colored via inline --burst-hue so the splash reads multicolor. The
   inner solid ring + outer halo both fan out, doubling the density. */
@keyframes wildRipple {
  0%   { box-shadow: 0 0 0 0    hsla(var(--burst-hue, 320), 95%, 65%, 0.85),
                     0 0 0 0    hsla(var(--burst-hue, 320), 95%, 65%, 0.35); }
  100% { box-shadow: 0 0 0 950px hsla(var(--burst-hue, 320), 95%, 65%, 0),
                     0 0 0 1150px hsla(var(--burst-hue, 320), 95%, 65%, 0); }
}
.wild-burst {
  position: fixed; left: 50%; top: 50%;
  width: 18px; height: 18px; border-radius: 50%;
  background: hsl(var(--burst-hue, 320), 95%, 65%);
  pointer-events: none; z-index: 15;
  animation: wildRipple 1.2s cubic-bezier(0.2, 0.7, 0.4, 1) forwards;
}
/* Brief tinted backdrop flash that washes the screen with rainbow light
   right when the bursts fire, then fades. */
@keyframes wildFlash {
  0%   { opacity: 0; }
  18%  { opacity: 1; }
  100% { opacity: 0; }
}
.wild-flash {
  position: fixed; inset: 0; pointer-events: none; z-index: 14;
  background: radial-gradient(ellipse at center,
    rgba(255, 200, 255, 0.45) 0%,
    rgba(244, 168, 216, 0.30) 25%,
    rgba(181, 156, 255, 0.18) 55%,
    rgba(0, 0, 0, 0)          85%);
  animation: wildFlash 1.2s ease-out forwards;
}

@keyframes weerrdBurst {
  0%   { transform: translate(-50%,-50%) scale(0); opacity: 1; }
  60%  { opacity: 0.8; }
  100% { transform: translate(-50%,-50%) scale(40); opacity: 0; }
}
.weerrd-burst {
  position: fixed; left: 50%; top: 50%;
  width: 20px; height: 20px; border-radius: 50%;
  background: radial-gradient(circle, rgba(93,202,165,0.8), rgba(181,156,255,0.4) 60%, transparent 80%);
  pointer-events: none; z-index: 15;
  animation: weerrdBurst 1.0s ease-out forwards;
}

/* Milestone celebration: ambient blobs swell + fade, top-tier spawns more. */
@keyframes bubblePop {
  0%   { transform: scale(1);   opacity: 0.42; }
  40%  { transform: scale(1.5); opacity: 0.85; }
  100% { transform: scale(0.05); opacity: 0; }
}
.blob.pop-once { animation: bubblePop 0.8s ease-out !important; }

@keyframes ephemeralBurst {
  0%   { transform: scale(0.1); opacity: 0; }
  30%  { transform: scale(1);   opacity: 0.6; }
  100% { transform: scale(2);   opacity: 0; }
}
.blob-ephemeral {
  filter: blur(60px);
  pointer-events: none;
  animation: ephemeralBurst 1.6s ease-out forwards !important;
}

/* Hot-wax drip from each used tile on a successful submit. */
@keyframes waxDrip {
  0%   { transform: translate(-50%, 0)    scaleX(0.4) scaleY(0.2); opacity: 0; }
  18%  { transform: translate(-50%, 4px)  scaleX(0.85) scaleY(0.7); opacity: 0.95; }
  45%  { transform: translate(-50%, 16px) scaleX(0.6)  scaleY(1.6); opacity: 0.95; }
  70%  { transform: translate(-50%, 36px) scaleX(0.7)  scaleY(0.85); opacity: 0.85; }
  100% { transform: translate(-50%, 78px) scaleX(0.3)  scaleY(0.3); opacity: 0; }
}

/* Bubble rising from each used tile on submit — counterpoint to the wax
   drip going down. Rises ~110px, expands then fades. Tier-hue tinted in
   the .wax-bubble selector. */
@keyframes bubbleRise {
  0%   { transform: translate(-50%, 0)     scale(0.35); opacity: 0; }
  15%  { transform: translate(-50%, -6px)  scale(1.05); opacity: 0.95; }
  55%  { transform: translate(-50%, -55px) scale(1.15); opacity: 0.78; }
  85%  { transform: translate(-50%, -95px) scale(0.85); opacity: 0.4; }
  100% { transform: translate(-50%, -120px) scale(0.5); opacity: 0; }
}
@keyframes bubbleWobble {
  0%, 100% { margin-left: 0; }
  25%      { margin-left: 6px; }
  50%      { margin-left: -4px; }
  75%      { margin-left: 5px; }
}

/* Side-firework sparks: each spark fans out from the tile edge along its
   own --angle, scaling up briefly then fading. fxHueShift cycles its color
   through the spectrum so the burst reads multicolor like the wax/bubbles. */
@keyframes sparkFly {
  0%   { transform: rotate(var(--angle)) translateX(0)    scale(0.4); opacity: 0; }
  20%  { transform: rotate(var(--angle)) translateX(8px)  scale(1.0); opacity: 1; }
  70%  { transform: rotate(var(--angle)) translateX(34px) scale(0.8); opacity: 0.85; }
  100% { transform: rotate(var(--angle)) translateX(52px) scale(0.2); opacity: 0; }
}

/* Multicolor cycle for wax-drop + wax-bubble. The base color is set per
   spawn via inline --fx-hue; this filter sweep then cycles the hue through
   the full spectrum during the element's lifetime so it reads as a
   shifting-rainbow blob rather than one solid color. */
@keyframes fxHueShift {
  0%   { filter: hue-rotate(0deg)   saturate(1.1); }
  50%  { filter: hue-rotate(180deg) saturate(1.3); }
  100% { filter: hue-rotate(360deg) saturate(1.1); }
}

/* Running rainbow outline for the no-tile center letter — text-stroke color
   cycles through 7 rainbow stops so the outline visibly "runs" around the
   glyph. Single color at any moment, but the moment-to-moment shift reads
   as a flowing rainbow. */
@keyframes centerOutlineRainbow {
  0%   { -webkit-text-stroke-color: #ff5cd0; }
  16%  { -webkit-text-stroke-color: #ff9a5c; }
  32%  { -webkit-text-stroke-color: #ffd45c; }
  48%  { -webkit-text-stroke-color: #b8ff7a; }
  64%  { -webkit-text-stroke-color: #5cffd0; }
  80%  { -webkit-text-stroke-color: #5cb8ff; }
  100% { -webkit-text-stroke-color: #ff5cd0; }
}

/* No-tile letter hue cycle: filter rotates the entire letter (gradient text
   AND its drop-shadow halos) through the color spectrum without panning the
   gradient itself, so the motion reads as smooth color drift rather than a
   sweep across each letter. */
@keyframes noTileHueCycle {
  0%   { filter: drop-shadow(0 2px 4px rgba(0,0,0,0.9))
                 drop-shadow(0 0 14px hsla(290, 95%, 70%, 0.85))
                 drop-shadow(0 0 26px hsla(330, 95%, 65%, 0.55))
                 hue-rotate(0deg); }
  100% { filter: drop-shadow(0 2px 4px rgba(0,0,0,0.9))
                 drop-shadow(0 0 14px hsla(290, 95%, 70%, 0.85))
                 drop-shadow(0 0 26px hsla(330, 95%, 65%, 0.55))
                 hue-rotate(360deg); }
}

/* Drift / earned letter stroke cycles through the rainbow palette. With
   per-slot animation-delays in tiles.css, a row of earned letters reads as
   a flowing multicolor outline instead of uniform dark strokes. */
@keyframes driftStrokeRainbow {
  0%   { -webkit-text-stroke-color: #ff5cd0; }
  16%  { -webkit-text-stroke-color: #ff9a5c; }
  32%  { -webkit-text-stroke-color: #ffd45c; }
  48%  { -webkit-text-stroke-color: #b8ff7a; }
  64%  { -webkit-text-stroke-color: #5cffd0; }
  80%  { -webkit-text-stroke-color: #5cb8ff; }
  100% { -webkit-text-stroke-color: #ff5cd0; }
}
/* Companion halo pulse — matched to the stroke cycle but slightly slower so
   the size + glow color drift independently of the stroke for organic feel. */
@keyframes driftHaloPulse {
  0%, 100% { filter: drop-shadow(0 0 6px hsla(320, 95%, 70%, 0.55)); }
  25%      { filter: drop-shadow(0 0 14px hsla(40, 95%, 65%, 0.85)); }
  50%      { filter: drop-shadow(0 0 10px hsla(140, 95%, 65%, 0.75)); }
  75%      { filter: drop-shadow(0 0 14px hsla(220, 95%, 65%, 0.85)); }
}

/* No-tile drift entrance: scale-only burst when a drift letter first appears.
   Transform-only so it composes with the static #311432 drop-shadow on .drift
   without clobbering the filter. JS adds .drift-entering for ~600ms. */
@keyframes noTileDriftAppearBurst {
  0%   { transform: scale(1.18); }
  100% { transform: scale(1); }
}

@keyframes weerrdlyFadeIn {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
/* Card entry: drops in from above, overshoots, settles. Pairs with the
   ring expansion + ambient bursts for a full top-tier celebration. */
@keyframes weerrdlyCardEnter {
  0%   { opacity: 0; transform: translateY(-30px) scale(0.7) rotate(-3deg); }
  60%  { opacity: 1; transform: translateY(6px)   scale(1.06) rotate(2deg); }
  85%  { transform: translateY(-2px) scale(0.99) rotate(-1deg); }
  100% { opacity: 1; transform: translateY(0)    scale(1)    rotate(0deg); }
}
@keyframes weerrdlyRing {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
  20%  { opacity: 1; transform: translate(-50%, -50%) scale(1.0); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(4.5); border-width: 1px; }
}
@keyframes weerrdlyStarTwinkle {
  0%, 100% { opacity: 0;   transform: scale(0.4); }
  50%      { opacity: 0.95; transform: scale(1.2); }
}

/* Rainbow scroll on the center tile's glyph (text background-clip pans). */
@keyframes centerLetterRainbow {
  0%   { background-position:   0% 50%; }
  100% { background-position: 220% 50%; }
}

/* Wordmark — non-uniform keyframe stops on a linear timing function produce
   visible accel/decel: long lazy stretches between 0%→8%, 18%→35%, 50%→65%,
   80%→100% are SLOW (small position delta over big time delta); the in-between
   sections are FAST (big position delta over small time delta). */
@keyframes wordmarkScroll {
  0%   { background-position:   0% 50%; }
  8%   { background-position:  20% 50%; }   /* slow start */
  18%  { background-position: 110% 50%; }   /* fast burst */
  35%  { background-position: 145% 50%; }   /* slow drift */
  50%  { background-position: 245% 50%; }   /* fast burst */
  65%  { background-position: 280% 50%; }   /* slow drift */
  80%  { background-position: 365% 50%; }   /* fast burst */
  100% { background-position: 400% 50%; }   /* slow finish */
}
@keyframes wordmarkGlow {
  0%, 100% { filter: drop-shadow(0 0 8px rgba(181,156,255,0.45)); }
  50%      { filter: drop-shadow(0 0 22px rgba(244,168,216,0.85)); }
}

/* Milestone bubble respawn — pops the existing blob OUT (scale 0), then
   re-inflates from zero so it reads as a real "burst + reborn" cycle. */
@keyframes bubbleRespawn {
  0%   { transform: scale(1);    opacity: 0.42; }
  25%  { transform: scale(1.55); opacity: 0.9; }
  45%  { transform: scale(0.05); opacity: 0; }
  46%  { transform: scale(0.05); opacity: 0; }
  75%  { transform: scale(1.15); opacity: 0.55; }
  100% { transform: scale(1);    opacity: 0.42; }
}
.blob.respawn { animation: bubbleRespawn 1.6s ease-in-out !important; }

/* Milestone stack JUMPS around the screen — pop in offset-left + tilted,
   bounce to right side, snap back, fade. Translate composes with the inline
   `translate(-50%, -50%)` baseline (so 0/0 at the middle keyframe = centered).
   Each step adds a viewport-relative delta so longer names stay readable. */
@keyframes milestoneJump {
  0%   { opacity: 0; transform: translate(calc(-50% - 22vw), calc(-50% - 6vh)) scale(0.5)  rotate(-9deg); }
  18%  { opacity: 1; transform: translate(calc(-50% - 22vw), calc(-50% - 6vh)) scale(1.18) rotate(-9deg); }
  38%  { opacity: 1; transform: translate(calc(-50% + 18vw), calc(-50% + 4vh)) scale(1.04) rotate(7deg); }
  58%  { opacity: 1; transform: translate(calc(-50% - 12vw), calc(-50% - 3vh)) scale(1.10) rotate(-5deg); }
  60%  { opacity: 1; transform: translate(-50%, -50%)                          scale(1.02) rotate(2deg); }
  88%  { opacity: 1; transform: translate(-50%, -50%)                          scale(1.04) rotate(0deg); }
  100% { opacity: 0; transform: translate(-50%, -50%)                          scale(1.10) rotate(0deg); }
}
/* Fast rainbow scroll across the milestone-name gradient text. */
@keyframes milestoneRainbow {
  0%   { background-position:   0% 50%; }
  100% { background-position: 300% 50%; }
}
/* Continuous hue rotate on the drop-shadow glow so the halo cycles colors. */
@keyframes milestoneHueShift {
  0%   { filter: drop-shadow(0 0 30px hsla(290, 80%, 70%, 0.95)) drop-shadow(0 0 12px hsla(330, 80%, 70%, 0.85)) hue-rotate(0deg); }
  100% { filter: drop-shadow(0 0 30px hsla(290, 80%, 70%, 0.95)) drop-shadow(0 0 12px hsla(330, 80%, 70%, 0.85)) hue-rotate(360deg); }
}
/* Full-screen tinted flash that fades behind the banner. */
@keyframes milestoneBackdrop {
  0%   { opacity: 0; }
  20%  { opacity: 1; }
  70%  { opacity: 0.8; }
  100% { opacity: 0; }
}
/* Glowing ring that expands from the center. */
@keyframes milestoneRing {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
  20%  { opacity: 1; transform: translate(-50%, -50%) scale(1.0); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(5.5); border-width: 1px; }
}

/* Heavy aura pulse for the drift-hat haze around drift/earned tiles in the
   pool. Opacity + scale breathe together so the haze "exhales". */
@keyframes auraPulse {
  0%, 100% { opacity: 0.65; transform: scale(0.94); }
  50%      { opacity: 1.0;  transform: scale(1.10); }
}

/* Reclaim-cost float (−50) after clicking a departure ghost. Shares the
   floatUp animation with regular point floats but in red-pink. */
.float-pts.reclaim-cost {
  color: #ff6b9d;
  text-shadow: 0 0 12px rgba(255, 107, 157, 0.8);
  transform: translate(-50%, 0);
}

@media (prefers-reduced-motion: reduce) {
  /* Dampen loud feedback. Ambient blobs, sway, drift pulse, drawbridge stay. */
  .input-display.shake,
  .tile.pop,
  .tile.selected.pop,
  .tile.wobble,
  .tile.earned-burst,
  .wild-burst,
  .weerrd-burst,
  .float-pts,
  .blob.pop-once,
  .blob-ephemeral,
  .blob.respawn {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
  /* Drop the top-tier rainbow hue cycle entirely; keep the gentle sway. */
  .tile-cluster.rainbow {
    animation: lineSway 16s ease-in-out infinite alternate !important;
  }
}

/* Start-menu launch flourish — particles burst out from each selected
   choice button when Start is clicked. position:fixed so they survive the
   menu→game screen swap; pointer-events:none so they never intercept clicks. */
.start-spark {
  position: fixed;
  border-radius: 50%;
  pointer-events: none;
  z-index: 200;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 0 6px currentColor);
  box-shadow: 0 0 12px rgba(255, 255, 255, 0.45);
}

/* AllWeerrd celebration — fires when a submitted word uses every letter in
   the current pool. Layers: existing weerrd-burst, flash, banner, shower. */
.allweerrd-flash {
  position: fixed; inset: 0;
  pointer-events: none; z-index: 14;
  background: radial-gradient(circle at 50% 50%,
    rgba(255, 255, 255, 0.38) 0%,
    rgba(181, 156, 255, 0.30) 25%,
    rgba(244, 168, 216, 0.20) 50%,
    rgba(93, 202, 165, 0.10) 75%,
    transparent 100%);
  animation: allweerrdFlash 1.0s ease-out forwards;
}
@keyframes allweerrdFlash {
  0%   { opacity: 0; }
  20%  { opacity: 1; }
  100% { opacity: 0; }
}

.allweerrd-banner {
  position: fixed; left: 50%; top: 38%;
  transform: translate(-50%, -50%);
  pointer-events: none; z-index: 25;
  text-align: center;
  animation: allweerrdBanner 2.3s cubic-bezier(0.2, 0.9, 0.3, 1) forwards;
}
.allweerrd-title {
  font-size: 64px; font-weight: 900; letter-spacing: 0.06em;
  background: linear-gradient(90deg,
    #ff5cd0, #b59cff, #5cffd0, #FAC775, #ff5cd0);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  filter: drop-shadow(0 4px 18px rgba(181, 156, 255, 0.7));
  animation: allweerrdHue 1.6s linear infinite;
}
.allweerrd-sub {
  margin-top: 8px;
  font-size: 22px; font-weight: 700;
  color: #FAC775;
  letter-spacing: 0.08em;
  text-shadow: 0 0 14px rgba(250, 199, 117, 0.7);
}
@keyframes allweerrdBanner {
  0%   { transform: translate(-50%, -50%) scale(0.4); opacity: 0; }
  18%  { transform: translate(-50%, -50%) scale(1.2); opacity: 1; }
  35%  { transform: translate(-50%, -50%) scale(1.0); opacity: 1; }
  82%  { transform: translate(-50%, -50%) scale(1.0); opacity: 1; }
  100% { transform: translate(-50%, -55%) scale(0.95); opacity: 0; }
}
@keyframes allweerrdHue {
  0%   { background-position: 0% 50%; }
  100% { background-position: 300% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .allweerrd-flash, .allweerrd-banner, .allweerrd-title {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
