/* ===========================================================================
   FLAPARENA - anim.css
   Keyframes and motion utilities. Loaded after theme.css on every page.
   Every animation here is switched off inside the reduced-motion block
   at the bottom of the file. Nothing in the product depends on motion to
   convey state - motion is always decoration over an already-legible layer.
   ---------------------------------------------------------------------------
   SECTION MAP
     01  KEYFRAMES ............ named motions
     02  ENTRANCE UTILITIES ... reveal on load / on scroll
     03  LOOPING UTILITIES .... live indicators, sweeps, tickers
     04  FEEDBACK UTILITIES ... press, flash, shake, count pop
     05  DELAY / DURATION ..... stagger helpers
     06  REDUCED MOTION ....... global off switch
   =========================================================================== */


/* ===========================================================================
   01  KEYFRAMES
   =========================================================================== */

/* fade + rise: section and card entrances */
@keyframes fa-rise {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}

/* fade only */
@keyframes fa-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* slide in from the left edge, for toast and drawer */
@keyframes fa-slide-in {
  from { opacity: 0; transform: translate3d(12px, 0, 0); }
  to   { opacity: 1; transform: none; }
}

/* the bird's idle bob - vertical only, tiny amplitude */
@keyframes fa-bob {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -5px, 0); }
}

/* a single wing beat: quick up, slow settle */
@keyframes fa-flap {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
  18%  { transform: translate3d(0, -9px, 0) rotate(-7deg); }
  46%  { transform: translate3d(0, -2px, 0) rotate(2deg); }
  100% { transform: translate3d(0, 0, 0) rotate(0deg); }
}

/* live dot heartbeat */
@keyframes fa-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.32; }
}

/* ring that expands out of a live dot */
@keyframes fa-ring {
  0%   { opacity: 0.6; transform: scale(1); }
  100% { opacity: 0;   transform: scale(2.6); }
}

/* broadcast sweep across a frame or panel */
@keyframes fa-sweep {
  0%   { transform: translate3d(-120%, 0, 0); }
  100% { transform: translate3d(220%, 0, 0); }
}

/* scanline drifting down a framed surface */
@keyframes fa-scanline {
  0%   { transform: translate3d(0, -100%, 0); }
  100% { transform: translate3d(0, 900%, 0); }
}

/* terminal caret */
@keyframes fa-blink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* horizontal marquee for the status ticker */
@keyframes fa-ticker {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* skeleton shimmer */
@keyframes fa-shimmer {
  from { background-position: -180% 0; }
  to   { background-position: 280% 0; }
}

/* spinner */
@keyframes fa-spin {
  to { transform: rotate(360deg); }
}

/* indeterminate loading bar */
@keyframes fa-indet {
  0%   { left: -35%; right: 100%; }
  60%  { left: 100%; right: -20%; }
  100% { left: 100%; right: -20%; }
}

/* gold flash on a freshly-updated figure */
@keyframes fa-flash-gold {
  0%   { background-color: rgba(240, 185, 11, 0.34); }
  100% { background-color: transparent; }
}
@keyframes fa-flash-cyan {
  0%   { background-color: rgba(34, 211, 238, 0.30); }
  100% { background-color: transparent; }
}
@keyframes fa-flash-lime {
  0%   { background-color: rgba(61, 220, 132, 0.28); }
  100% { background-color: transparent; }
}
@keyframes fa-flash-crimson {
  0%   { background-color: rgba(255, 59, 78, 0.30); }
  100% { background-color: transparent; }
}

/* elimination judder */
@keyframes fa-shake {
  0%, 100% { transform: translate3d(0, 0, 0); }
  20%      { transform: translate3d(-3px, 0, 0); }
  40%      { transform: translate3d(3px, 0, 0); }
  60%      { transform: translate3d(-2px, 0, 0); }
  80%      { transform: translate3d(2px, 0, 0); }
}

/* a number that just changed value */
@keyframes fa-pop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.09); }
  100% { transform: scale(1); }
}

/* gate closing: border colour urgency */
@keyframes fa-urgent {
  0%, 100% { border-color: var(--crimson); }
  50%      { border-color: var(--line-strong); }
}

/* bar filling from zero to its inline width */
@keyframes fa-bar-grow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* slow drift for background art layers */
@keyframes fa-drift {
  0%   { transform: translate3d(0, 0, 0); }
  50%  { transform: translate3d(-18px, 6px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}


/* ===========================================================================
   02  ENTRANCE UTILITIES
   =========================================================================== */

.anim-rise {
  animation: fa-rise var(--dur-4) var(--ease-out) both;
}
.anim-fade {
  animation: fa-fade var(--dur-3) var(--ease) both;
}
.anim-slide {
  animation: fa-slide-in var(--dur-3) var(--ease-out) both;
}

/* scroll reveal: JS adds .is-in when the element enters the viewport.
   Without JS the element is fully visible - never hidden by default. */
.reveal {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--dur-4) var(--ease-out),
    transform var(--dur-4) var(--ease-out);
}
.js .reveal {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
}
.js .reveal.is-in {
  opacity: 1;
  transform: none;
}


/* ===========================================================================
   03  LOOPING UTILITIES
   =========================================================================== */

.anim-bob   { animation: fa-bob 3.4s var(--ease) infinite; }
.anim-flap  { animation: fa-flap 1.5s var(--ease) infinite; transform-origin: 50% 70%; }
.anim-pulse { animation: fa-pulse 1.6s var(--ease) infinite; }
.anim-spin  { animation: fa-spin 900ms linear infinite; }
.anim-drift { animation: fa-drift 22s var(--ease) infinite; }

/* live dot with an expanding ring */
.live-dot {
  position: relative;
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cyan);
  flex: 0 0 auto;
  animation: fa-pulse 1.6s var(--ease) infinite;
}
.live-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--cyan);
  animation: fa-ring 1.9s var(--ease-out) infinite;
}
.live-dot--gold { background: var(--gold); }
.live-dot--gold::after { border-color: var(--gold); }
.live-dot--idle { background: var(--ink-dim); animation: none; }
.live-dot--idle::after { display: none; }

/* one-pass light sweep across a framed surface */
.sweep { position: relative; overflow: hidden; }
.sweep::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 22%;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(232, 234, 237, 0.06),
    transparent
  );
  animation: fa-sweep 5.5s var(--ease) infinite;
  pointer-events: none;
}

/* drifting scanline inside a frame */
.scanline { position: relative; overflow: hidden; }
.scanline::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 12px;
  background: linear-gradient(
    to bottom,
    transparent,
    rgba(34, 211, 238, 0.10),
    transparent
  );
  animation: fa-scanline 7s linear infinite;
  pointer-events: none;
}

/* blinking terminal caret */
.caret::after {
  content: "_";
  font-family: var(--font-mono);
  color: var(--gold);
  animation: fa-blink 1.05s var(--ease-step) infinite;
}

/* marquee ticker: duplicate the track contents in markup for a seamless loop */
.ticker {
  position: relative;
  overflow: hidden;
  border-block: 1px solid var(--line);
  background: var(--panel);
}
.ticker__track {
  display: inline-flex;
  gap: var(--s-6);
  padding: var(--s-2) 0;
  white-space: nowrap;
  will-change: transform;
  animation: fa-ticker 34s linear infinite;
}
.ticker:hover .ticker__track { animation-play-state: paused; }
.ticker__item {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--muted);
}

/* shimmering skeleton */
.skeleton.is-loading {
  background-image: linear-gradient(
    90deg,
    var(--panel-3) 0%,
    var(--line) 42%,
    var(--panel-3) 84%
  );
  background-size: 220% 100%;
  animation: fa-shimmer 1.5s linear infinite;
}

/* indeterminate progress line */
.loadbar {
  position: relative;
  height: 2px;
  overflow: hidden;
  background: var(--panel-3);
}
.loadbar::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--cyan);
  animation: fa-indet 1.4s var(--ease) infinite;
}

/* small ring spinner */
.spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid var(--line-strong);
  border-top-color: var(--gold);
  border-radius: 50%;
  animation: fa-spin 800ms linear infinite;
}


/* ===========================================================================
   04  FEEDBACK UTILITIES
   =========================================================================== */

/* apply, then remove, on any figure that just took a new value */
.flash-gold    { animation: fa-flash-gold    900ms var(--ease-out) 1; }
.flash-cyan    { animation: fa-flash-cyan    900ms var(--ease-out) 1; }
.flash-lime    { animation: fa-flash-lime    900ms var(--ease-out) 1; }
.flash-crimson { animation: fa-flash-crimson 900ms var(--ease-out) 1; }

.anim-pop   { animation: fa-pop 320ms var(--ease-out) 1; }
.anim-shake { animation: fa-shake 380ms var(--ease) 1; }

/* countdown entering the last seconds before the gate closes */
.countdown--urgent .countdown__unit {
  animation: fa-urgent 900ms var(--ease) infinite;
}

/* stamina / odds bars grow from the left on first paint */
.bar--grow .bar__fill {
  transform-origin: left center;
  animation: fa-bar-grow var(--dur-4) var(--ease-out) both;
}

/* hover lift, kept to 1px because the system is hard-edged */
.lift { transition: transform var(--dur-2) var(--ease); }
.lift:hover { transform: translate3d(0, -1px, 0); }


/* ===========================================================================
   05  DELAY / DURATION HELPERS
   =========================================================================== */

.d-0  { animation-delay: 0ms;   transition-delay: 0ms; }
.d-1  { animation-delay: 60ms;  transition-delay: 60ms; }
.d-2  { animation-delay: 120ms; transition-delay: 120ms; }
.d-3  { animation-delay: 180ms; transition-delay: 180ms; }
.d-4  { animation-delay: 240ms; transition-delay: 240ms; }
.d-5  { animation-delay: 300ms; transition-delay: 300ms; }
.d-6  { animation-delay: 360ms; transition-delay: 360ms; }
.d-7  { animation-delay: 420ms; transition-delay: 420ms; }

.dur-fast { animation-duration: var(--dur-2); }
.dur-slow { animation-duration: 700ms; }

.anim-paused { animation-play-state: paused !important; }


/* ===========================================================================
   06  REDUCED MOTION - the global off switch
   =========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .anim-rise,
  .anim-fade,
  .anim-slide,
  .anim-bob,
  .anim-flap,
  .anim-pulse,
  .anim-spin,
  .anim-drift,
  .anim-pop,
  .anim-shake,
  .flash-gold,
  .flash-cyan,
  .flash-lime,
  .flash-crimson,
  .bar--grow .bar__fill,
  .countdown--urgent .countdown__unit,
  .ticker__track,
  .skeleton.is-loading,
  .spinner {
    animation: none !important;
  }

  .js .reveal,
  .js .reveal.is-in {
    opacity: 1 !important;
    transform: none !important;
  }

  .sweep::after,
  .scanline::after,
  .loadbar::after,
  .live-dot::after,
  .caret::after {
    animation: none !important;
  }

  .sweep::after,
  .scanline::after,
  .live-dot::after { display: none; }

  /* the loading bar stays visible but static so the state is still readable */
  .loadbar::after { left: 0; right: 0; opacity: 0.55; }

  .caret::after { opacity: 1; }

  .lift:hover { transform: none; }

  .spinner { border-top-color: var(--gold); opacity: 0.8; }
}
