/* ============================================================================
   Vega's Bell - animations.css
   Motion layer: keyframes + animation utility classes.
   Owner: ANIMATION/FX agent. Companion doc: docs/ANIMATION_GUIDE.md

   RULES BAKED IN:
   - Only `transform` and `opacity` are animated. Never width/height/top/left/
     margin/box-shadow inside a loop. Glow and shine effects animate the
     opacity/transform of a generated pseudo-element instead of a live shadow.
   - Every effect has a `prefers-reduced-motion: reduce` substitute at the
     bottom of this file: a non-moving opacity cue, never silent nothing.
   - Nothing here assumes a DOM structure beyond the class being applied.
     Effects that need an extra layer create their own pseudo-element.
   - Colours come from tokens.css with hard-coded fallbacks, so this file is
     safe to load standalone or before tokens.css resolves.
   ========================================================================= */

/* ---------------------------------------------------------------- tokens -- */
:root {
  /* Spring-like easings. Nothing user-facing uses `linear`. */
  --vb-ease-back:   cubic-bezier(.34, 1.56, .64, 1);   /* overshoot / pop     */
  --vb-ease-punch:  cubic-bezier(.18, .89, .32, 1.28); /* harder overshoot    */
  --vb-ease-out:    cubic-bezier(.22, 1, .36, 1);      /* quint out, snappy   */
  --vb-ease-in:     cubic-bezier(.55, 0, 1, .45);      /* exits               */
  --vb-ease-soft:   cubic-bezier(.65, 0, .35, 1);      /* symmetric, calm     */

  /* Celebrations are punchy and quick; ambient loops are slow and calm. */
  --vb-dur-1: 140ms;
  --vb-dur-2: 220ms;
  --vb-dur-3: 340ms;
  --vb-dur-4: 480ms;
  --vb-dur-ambient: 4.5s;

  --vb-delay-step: 80ms;
  --vb-stagger-step: 60ms;

  /* Per-effect tunables. Override on the element, not here. */
  --vb-float-dist: 10px;
  --vb-sway: 7deg;
  --vb-shake-amp: 3px;      /* screen-shake: deliberately tiny */
  --vb-shake-x-amp: 8px;    /* shake-x on a single control     */
  --vb-twinkle-min: .25;
  --vb-twinkle-dur: 3.2s;
  --vb-heartbeat-dur: 1.1s;
  --vb-shimmer-dur: 3.2s;
  --vb-glow-color: var(--accent-cyan, #22D3EE);
}

/* ================================================================ KEYFRAMES */

/* -- entrances ------------------------------------------------------------ */
@keyframes vb-fade-in-up {
  from { opacity: 0; transform: translate3d(0, 18px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes vb-pop-in {
  0%   { opacity: 0; transform: scale3d(.55, .55, 1); }
  70%  { opacity: 1; }
  100% { opacity: 1; transform: scale3d(1, 1, 1); }
}
@keyframes vb-slide-in-right {
  from { opacity: 0; transform: translate3d(36px, 0, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* -- idle / ambient ------------------------------------------------------- */
@keyframes vb-float {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, calc(var(--vb-float-dist) * -1), 0); }
}
@keyframes vb-pulse-glow {
  0%, 100% { opacity: .28; transform: scale(.88); }
  50%      { opacity: .62; transform: scale(1.06); }
}
@keyframes vb-twinkle {
  0%, 100% { opacity: var(--vb-twinkle-min); transform: scale(.82); }
  50%      { opacity: 1;                     transform: scale(1.16); }
}
@keyframes vb-shimmer {
  0%        { transform: translate3d(-140%, 0, 0) skewX(-14deg); }
  55%, 100% { transform: translate3d(140%, 0, 0)  skewX(-14deg); }
}
@keyframes vb-bell-sway {
  0%, 100% { transform: rotate(calc(var(--vb-sway) * -1)); }
  50%      { transform: rotate(var(--vb-sway)); }
}

/* -- feedback ------------------------------------------------------------- */
@keyframes vb-shake-x {
  0%   { transform: translate3d(0, 0, 0); }
  15%  { transform: translate3d(calc(var(--vb-shake-x-amp) * -1), 0, 0); }
  30%  { transform: translate3d(calc(var(--vb-shake-x-amp) * .82), 0, 0); }
  45%  { transform: translate3d(calc(var(--vb-shake-x-amp) * -.6), 0, 0); }
  60%  { transform: translate3d(calc(var(--vb-shake-x-amp) * .4), 0, 0); }
  78%  { transform: translate3d(calc(var(--vb-shake-x-amp) * -.2), 0, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
@keyframes vb-correct-swell {
  0%   { transform: scale3d(1, 1, 1); }
  35%  { transform: scale3d(1.09, 1.09, 1); }
  100% { transform: scale3d(1, 1, 1); }
}
@keyframes vb-correct-veil {
  0%   { opacity: 0;   transform: scale(.78); }
  28%  { opacity: .85; transform: scale(1.04); }
  100% { opacity: 0;   transform: scale(1.28); }
}
@keyframes vb-letter-pop {
  0%   { opacity: 0; transform: scale3d(.4, .4, 1) translate3d(0, 10px, 0); }
  60%  { opacity: 1; transform: scale3d(1.18, 1.18, 1) translate3d(0, -3px, 0); }
  100% { opacity: 1; transform: scale3d(1, 1, 1) translate3d(0, 0, 0); }
}
@keyframes vb-tile-flip {
  0%   { transform: rotateY(0deg)  scale3d(1, 1, 1); }
  50%  { transform: rotateY(90deg) scale3d(1.06, 1.06, 1); }
  100% { transform: rotateY(0deg)  scale3d(1, 1, 1); }
}
@keyframes vb-tile-flip-in {
  0%   { opacity: 0; transform: rotateX(-92deg); }
  65%  { opacity: 1; transform: rotateX(12deg); }
  100% { opacity: 1; transform: rotateX(0deg); }
}
@keyframes vb-rubber-band {
  0%   { transform: scale3d(1, 1, 1); }
  30%  { transform: scale3d(1.25, .75, 1); }
  40%  { transform: scale3d(.75, 1.25, 1); }
  50%  { transform: scale3d(1.15, .85, 1); }
  65%  { transform: scale3d(.95, 1.05, 1); }
  75%  { transform: scale3d(1.05, .95, 1); }
  100% { transform: scale3d(1, 1, 1); }
}
@keyframes vb-heartbeat {
  0%        { transform: scale3d(1, 1, 1); }
  14%       { transform: scale3d(1.13, 1.13, 1); }
  28%       { transform: scale3d(1, 1, 1); }
  42%       { transform: scale3d(1.08, 1.08, 1); }
  70%, 100% { transform: scale3d(1, 1, 1); }
}

/* -- hype ----------------------------------------------------------------- */
@keyframes vb-streak-flame-flicker {
  0%   { opacity: .92; transform: scale3d(1, 1, 1) translate3d(0, 0, 0); }
  18%  { opacity: 1;   transform: scale3d(1.05, .95, 1) translate3d(0, -1px, 0); }
  37%  { opacity: .88; transform: scale3d(.96, 1.07, 1) translate3d(0, 1px, 0); }
  58%  { opacity: 1;   transform: scale3d(1.07, .97, 1) translate3d(0, -2px, 0); }
  76%  { opacity: .9;  transform: scale3d(.97, 1.04, 1) translate3d(0, 0, 0); }
  100% { opacity: .95; transform: scale3d(1, 1, 1) translate3d(0, 0, 0); }
}
@keyframes vb-combo-punch {
  0%   { transform: scale3d(1, 1, 1); }
  22%  { transform: scale3d(1.42, 1.42, 1); }
  45%  { transform: scale3d(.92, .92, 1); }
  68%  { transform: scale3d(1.08, 1.08, 1); }
  100% { transform: scale3d(1, 1, 1); }
}
@keyframes vb-rank-up-burst {
  0%   { opacity: 0; transform: scale3d(.3, .3, 1) rotate(-14deg); }
  45%  { opacity: 1; transform: scale3d(1.22, 1.22, 1) rotate(5deg); }
  70%  { opacity: 1; transform: scale3d(.96, .96, 1) rotate(-2deg); }
  100% { opacity: 1; transform: scale3d(1, 1, 1) rotate(0deg); }
}
/* Subtle on purpose: <= 3px translate, no rotation, one 320ms pass. */
@keyframes vb-screen-shake {
  0%, 100% { transform: translate3d(0, 0, 0); }
  14%      { transform: translate3d(calc(var(--vb-shake-amp) * -1), calc(var(--vb-shake-amp) * .3), 0); }
  30%      { transform: translate3d(calc(var(--vb-shake-amp) * .8), calc(var(--vb-shake-amp) * -.4), 0); }
  46%      { transform: translate3d(calc(var(--vb-shake-amp) * -.55), 0, 0); }
  64%      { transform: translate3d(calc(var(--vb-shake-amp) * .4), calc(var(--vb-shake-amp) * .25), 0); }
  82%      { transform: translate3d(calc(var(--vb-shake-amp) * -.18), 0, 0); }
}
@keyframes vb-countdown-zoom {
  0%   { opacity: 0; transform: scale3d(2.6, 2.6, 1); }
  18%  { opacity: 1; transform: scale3d(1, 1, 1); }
  70%  { opacity: 1; transform: scale3d(1, 1, 1); }
  100% { opacity: 0; transform: scale3d(.62, .62, 1); }
}

/* -- transitions ---------------------------------------------------------- */
@keyframes vb-screen-enter {
  from { opacity: 0; transform: translate3d(0, 14px, 0) scale3d(.985, .985, 1); }
  to   { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1); }
}
@keyframes vb-screen-exit {
  from { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1); }
  to   { opacity: 0; transform: translate3d(0, -12px, 0) scale3d(.975, .975, 1); }
}
@keyframes vb-modal-in {
  0%   { opacity: 0; transform: translate3d(0, 16px, 0) scale3d(.9, .9, 1); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1); }
}
@keyframes vb-modal-out {
  from { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1); }
  to   { opacity: 0; transform: translate3d(0, 10px, 0) scale3d(.94, .94, 1); }
}
@keyframes vb-backdrop-fade   { from { opacity: 0; } to { opacity: 1; } }
@keyframes vb-backdrop-unfade { from { opacity: 1; } to { opacity: 0; } }

/* -- reduced-motion substitutes (opacity only, zero movement) ------------- */
@keyframes vb-rm-fade     { from { opacity: 0; } to { opacity: 1; } }
@keyframes vb-rm-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes vb-rm-blink    { 0%, 100% { opacity: 1; }   50% { opacity: .5; } }
@keyframes vb-rm-soft     { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }


/* ================================================================== CLASSES */

/* -- entrances ------------------------------------------------------------ */
.fade-in-up {
  animation: vb-fade-in-up var(--vb-dur-3) var(--vb-ease-out) both;
}
.pop-in {
  animation: vb-pop-in var(--vb-dur-3) var(--vb-ease-back) both;
}
.slide-in-right {
  animation: vb-slide-in-right var(--vb-dur-3) var(--vb-ease-out) both;
}

/* Stagger helper. Set --i on each child (0-based) or use .stagger--auto.
   Works with any entrance class on the children. */
.stagger > * {
  animation-delay: calc(var(--i, 0) * var(--vb-stagger-step));
}
.stagger--auto > *:nth-child(1)  { --i: 0; }
.stagger--auto > *:nth-child(2)  { --i: 1; }
.stagger--auto > *:nth-child(3)  { --i: 2; }
.stagger--auto > *:nth-child(4)  { --i: 3; }
.stagger--auto > *:nth-child(5)  { --i: 4; }
.stagger--auto > *:nth-child(6)  { --i: 5; }
.stagger--auto > *:nth-child(7)  { --i: 6; }
.stagger--auto > *:nth-child(8)  { --i: 7; }
.stagger--auto > *:nth-child(9)  { --i: 8; }
.stagger--auto > *:nth-child(10) { --i: 9; }
.stagger--auto > *:nth-child(11) { --i: 10; }
.stagger--auto > *:nth-child(12) { --i: 11; }
.stagger--auto > *:nth-child(13) { --i: 12; }
.stagger--auto > *:nth-child(14) { --i: 13; }
.stagger--auto > *:nth-child(15) { --i: 14; }
.stagger--auto > *:nth-child(16) { --i: 15; }

/* -- idle / ambient ------------------------------------------------------- */
.float {
  animation: vb-float var(--vb-dur-ambient) var(--vb-ease-soft) infinite;
}

/* Shooting star: a streak that crosses, then leaves a long gap before the next
   pass. The gap is what stops four of them reading as a marching pattern --
   with co-prime durations the group takes minutes to repeat itself. Callers set
   --vb-star-ang (direction), --vb-star-run (distance) and the animation timing;
   placement is the caller's job too, since only it knows the container. */
.shooting-star {
  position: absolute;
  width: var(--vb-star-len, 130px);
  height: 2px;
  border-radius: 999px;
  background: linear-gradient(90deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(165, 180, 252, .75) 55%,
    rgba(255, 255, 255, .98) 100%);
  opacity: 0;
  /* Deliberately no `will-change`. It was here and was wrong: this class is
     never removed, so it promoted five permanent compositor layers on the
     landing hero, against this file's own rule at `.will-animate` below. Worse,
     it promoted them under `prefers-reduced-motion: reduce` too, where the
     animation computes to `none` and the layers pay for an effect nobody sees.
     transform and opacity are composited anyway while an animation is running,
     so the hint bought nothing. Do not add it back. */
  animation: vb-shoot var(--vb-star-dur, 9s) var(--vb-ease-soft) var(--vb-star-delay, 0s) infinite;
}
/* The head: a small bright dot at the leading edge. */
.shooting-star::after {
  content: '';
  position: absolute;
  right: -1px; top: -1.5px;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 8px 2px rgba(34, 211, 238, .85);
}

@keyframes vb-shoot {
  0%          { opacity: 0; transform: rotate(var(--vb-star-ang, 20deg)) translateX(0) scaleX(.25); }
  3%          { opacity: 1; }
  22%         { opacity: 1; }
  30%, 100%   { opacity: 0; transform: rotate(var(--vb-star-ang, 20deg)) translateX(var(--vb-star-run, 60vw)) scaleX(1); }
}

/* Neon bloom without animating box-shadow: a screen-blended radial layer. */
.pulse-glow { position: relative; }
.pulse-glow::after {
  content: "";
  position: absolute;
  inset: -35%;
  z-index: 1;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, var(--vb-glow-color) 0%, transparent 70%);
  mix-blend-mode: screen;
  opacity: .28;
  transform: scale(.88);
  animation: vb-pulse-glow 4s var(--vb-ease-soft) infinite;
}

.twinkle {
  animation: vb-twinkle var(--vb-twinkle-dur) var(--vb-ease-soft) infinite;
  animation-delay: calc(var(--i, 0) * 170ms);
}

/* Sweeping gold highlight. Put it on the gold surface itself. */
.shimmer { position: relative; overflow: hidden; }
.shimmer::after {
  content: "";
  position: absolute;
  top: -10%;
  bottom: -10%;
  left: 0;
  right: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 32%,
    rgba(253, 230, 138, .18) 44%,
    rgba(255, 255, 255, .55) 50%,
    rgba(253, 230, 138, .18) 56%,
    transparent 68%
  );
  transform: translate3d(-140%, 0, 0) skewX(-14deg);
  animation: vb-shimmer var(--vb-shimmer-dur) var(--vb-ease-soft) infinite;
}

.bell-sway {
  transform-origin: 50% 8%;
  animation: vb-bell-sway 3.6s var(--vb-ease-soft) infinite;
}

/* -- feedback ------------------------------------------------------------- */
.shake-x {
  animation: vb-shake-x 420ms var(--vb-ease-out) both;
}

.correct-flash {
  position: relative;
  animation: vb-correct-swell var(--vb-dur-4) var(--vb-ease-back) both;
}
.correct-flash::after {
  content: "";
  position: absolute;
  inset: -12%;
  z-index: 1;
  pointer-events: none;
  border-radius: inherit;
  background: radial-gradient(circle at 50% 50%, var(--success, #34D399) 0%, transparent 72%);
  mix-blend-mode: screen;
  opacity: 0;
  animation: vb-correct-veil var(--vb-dur-4) var(--vb-ease-out) both;
}

.letter-pop {
  animation: vb-letter-pop 360ms var(--vb-ease-back) both;
  animation-delay: calc(var(--i, 0) * var(--vb-stagger-step));
}

/* Give the tile's parent .flip-scene so the rotation reads as 3D. */
.flip-scene { perspective: 700px; }
.tile-flip {
  backface-visibility: hidden;
  animation: vb-tile-flip 420ms var(--vb-ease-soft) both;
}
.tile-flip-in {
  transform-origin: 50% 0%;
  backface-visibility: hidden;
  animation: vb-tile-flip-in 420ms var(--vb-ease-back) both;
  animation-delay: calc(var(--i, 0) * var(--vb-stagger-step));
}

.rubber-band {
  animation: vb-rubber-band 700ms var(--vb-ease-out) both;
}

.heartbeat {
  animation: vb-heartbeat var(--vb-heartbeat-dur) var(--vb-ease-out) infinite;
}

/* -- hype ----------------------------------------------------------------- */
.streak-flame-flicker {
  transform-origin: 50% 100%;
  animation: vb-streak-flame-flicker 900ms var(--vb-ease-soft) infinite;
}
.combo-punch {
  animation: vb-combo-punch 300ms var(--vb-ease-punch) both;
}
.rank-up-burst {
  animation: vb-rank-up-burst 620ms var(--vb-ease-back) both;
}
.screen-shake {
  animation: vb-screen-shake 320ms var(--vb-ease-out) 1 both;
}
.screen-shake--soft   { --vb-shake-amp: 2px; }
.screen-shake--strong { --vb-shake-amp: 5px; }  /* ceiling: never go above this */
.countdown-zoom {
  animation: vb-countdown-zoom 900ms var(--vb-ease-out) both;
}

/* -- transitions ---------------------------------------------------------- */
.screen-enter  { animation: vb-screen-enter  var(--vb-dur-4) var(--vb-ease-out) both; }
.screen-exit   { animation: vb-screen-exit   var(--vb-dur-2) var(--vb-ease-in)  both; }
.modal-in      { animation: vb-modal-in      var(--vb-dur-3) var(--vb-ease-back) both; }
.modal-out     { animation: vb-modal-out     var(--vb-dur-2) var(--vb-ease-in)  both; }
.backdrop-fade { animation: vb-backdrop-fade var(--vb-dur-2) var(--vb-ease-out) both; }
.backdrop-out  { animation: vb-backdrop-unfade var(--vb-dur-2) var(--vb-ease-in) both; }


/* ================================================================ UTILITIES */
/* Declared after the effect classes so equal-specificity overrides win. */

.anim-delay-1 { animation-delay: calc(1 * var(--vb-delay-step)); }
.anim-delay-2 { animation-delay: calc(2 * var(--vb-delay-step)); }
.anim-delay-3 { animation-delay: calc(3 * var(--vb-delay-step)); }
.anim-delay-4 { animation-delay: calc(4 * var(--vb-delay-step)); }
.anim-delay-5 { animation-delay: calc(5 * var(--vb-delay-step)); }
.anim-delay-6 { animation-delay: calc(6 * var(--vb-delay-step)); }
.anim-delay-7 { animation-delay: calc(7 * var(--vb-delay-step)); }
.anim-delay-8 { animation-delay: calc(8 * var(--vb-delay-step)); }

.anim-fast { animation-duration: var(--vb-dur-1); }
.anim-slow { animation-duration: 720ms; }
.anim-once { animation-iteration-count: 1; animation-fill-mode: both; }
.anim-loop { animation-iteration-count: infinite; }
.anim-paused { animation-play-state: paused; }
.anim-none { animation: none !important; }

/* Promote to its own layer just before a big animation. REMOVE this class
   when the animation ends (animationend) - a permanent will-change wastes
   GPU memory and can actually make things slower. */
.will-animate { will-change: transform, opacity; }

/* Full-screen particle canvas mounted by fx.js. Never intercepts input. */
.fx-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  z-index: 9999;
}


/* ============================================================ ACCESSIBILITY */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* Skip links etc: hidden until keyboard-focused. */
.sr-only-focusable:focus,
.sr-only-focusable:focus-visible {
  position: static;
  width: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
}

:focus-visible {
  outline: 3px solid var(--accent-cyan, #22D3EE);
  outline-offset: 2px;
}
/* Opt-in ring for custom controls that clip their own outline. */
.focus-ring:focus-visible {
  outline: 3px solid var(--accent-cyan, #22D3EE);
  outline-offset: 3px;
  border-radius: inherit;
}


/* ========================================================= REDUCED MOTION ==
   Safety net first (kills any motion, including anything another agent
   writes), then explicit non-moving substitutes so feedback is never silent.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {

  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* Entrances and reveals: appear with a plain fade, no travel. */
  .fade-in-up,
  .pop-in,
  .slide-in-right,
  .letter-pop,
  .tile-flip,
  .tile-flip-in,
  .screen-enter,
  .modal-in,
  .backdrop-fade,
  .rank-up-burst,
  .countdown-zoom,
  .combo-punch {
    animation-name: vb-rm-fade !important;
    animation-duration: 180ms !important;
    animation-timing-function: ease-out !important;
    transform: none !important;
  }

  /* Exits: fade out only. */
  .screen-exit,
  .modal-out,
  .backdrop-out {
    animation-name: vb-rm-fade-out !important;
    animation-duration: 160ms !important;
    transform: none !important;
  }

  /* Error / attention feedback: a double dim instead of a shake. */
  .shake-x,
  .rubber-band,
  .screen-shake,
  .screen-shake--soft,
  .screen-shake--strong {
    animation-name: vb-rm-blink !important;
    animation-duration: 260ms !important;
    animation-iteration-count: 2 !important;
    transform: none !important;
  }

  /* Success: keep the green veil, drop the swell. */
  .correct-flash {
    animation-name: vb-rm-blink !important;
    animation-duration: 320ms !important;
    transform: none !important;
  }
  .correct-flash::after {
    animation-name: vb-rm-fade-out !important;
    animation-duration: 420ms !important;
    opacity: .7;
    transform: none !important;
  }

  /* Ambient travel: off entirely. A star that still crosses the hero in 1ms
     is worse than one that never appears, so this is `none`, not the blanket
     duration clamp above. The layer is decorative; nothing is lost with it
     hidden, so it goes rather than sitting frozen mid-flight. */
  .float,
  .bell-sway,
  .streak-flame-flicker,
  .shooting-star,
  .shimmer::after {
    animation: none !important;
    transform: none !important;
  }
  .shooting-star { opacity: 0 !important; }
  .shimmer::after { opacity: 0 !important; }

  /* Ambient light: slow opacity-only breathing is retained (well under 3Hz)
     so glowing elements still read as "alive". */
  .twinkle,
  .pulse-glow::after {
    animation-name: vb-rm-soft !important;
    animation-duration: 4s !important;
    animation-iteration-count: infinite !important;
    transform: none !important;
  }

  /* Timer running out still needs to be noticeable. */
  .heartbeat {
    animation-name: vb-rm-blink !important;
    animation-duration: 1.4s !important;
    animation-iteration-count: infinite !important;
    transform: none !important;
  }

  .stagger > *,
  .letter-pop,
  .tile-flip-in,
  .twinkle {
    animation-delay: 0ms !important;
  }

  .will-animate { will-change: auto; }
}
