/* ==========================================================================
   HookGuard v55 — motion.

   Additive layer.  Everything here is NEW behaviour (scroll reveals, pane and
   modal entrances, count-up readiness) rather than another round of overrides,
   so it does not join the !important war between the older layers.  The one
   existing rule it deliberately reverses is v54's blanket
   `.hw-step, .doc-step, .pcard, .feature-card { animation: none !important }`.

   Two invariants the earlier layers broke:
   1. Nothing may depend on JS to be VISIBLE.  The hidden state is scoped under
      body.rv-ready, which only JS adds - if the script fails, every element
      renders normally instead of the page coming up blank.
   2. Every animation here is disabled under prefers-reduced-motion.  v49,
      v50-fixes, v51 and v52 shipped 60 keyframes between them with zero
      reduced-motion coverage.
   ========================================================================== */


/* ---------- scroll reveal ----------
   The old entrance animations were time-based: `.doc-step:nth-child(n)` fired
   on page load with a fixed delay, so everything below the fold had already
   finished animating before the user could scroll to it.  Reveals are now
   driven by an IntersectionObserver in app.js, which sets --rv-d for the
   stagger and adds .rv-in when the element actually enters the viewport. */
body.rv-ready .rv {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--dur-4) var(--ease-out),
    transform var(--dur-4) var(--ease-out);
  transition-delay: var(--rv-d, 0s);
}
body.rv-ready .rv.rv-in {
  opacity: 1;
  transform: none;
}
/* Elements that are already on screen at load should not wait for a scroll. */
body.rv-ready .rv.rv-now {
  transition-duration: var(--dur-3);
}

/* A slightly stronger variant for the large home sections. */
body.rv-ready .rv-lift {
  opacity: 0;
  transform: translateY(22px) scale(.994);
  transition:
    opacity .6s var(--ease-out),
    transform .6s var(--ease-out);
  transition-delay: var(--rv-d, 0s);
}
body.rv-ready .rv-lift.rv-in { opacity: 1; transform: none; }


/* ---------- view transitions ----------
   Switching section used to be `paneFade .12s`, a bare opacity blink with no
   spatial cue, so the two screens felt unrelated.  This keeps it fast but adds
   a small rise, and staggers the direct children so a view "assembles" instead
   of appearing all at once. */
.view.active { animation: viewIn var(--dur-3) var(--ease-out) both; }
@keyframes viewIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
/* Mail and staff are fixed app-frame layouts; translating them looks broken. */
#view-mail.view.active,
#view-staff.view.active { animation: paneFade var(--dur-1) ease-out both; }

/* Dashboard/wallet sidebar panes: same treatment, tighter. */
.tab-pane.active { animation: paneIn var(--dur-2) var(--ease-out) both; }
@keyframes paneIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}


/* ---------- modal entrance ----------
   .modal-card had no transform of its own: only the overlay faded, so the
   dialog just appeared at full size.  Scale + rise from the anchor point reads
   as the card coming forward. */
.modal-overlay { transition: opacity var(--dur-2) var(--ease-out); }
.modal-overlay .modal-card {
  opacity: 0;
  transform: translateY(10px) scale(.98);
  transition:
    opacity var(--dur-3) var(--ease-out),
    transform var(--dur-3) var(--ease-spring);
}
.modal-overlay.active .modal-card { opacity: 1; transform: none; }


/* ---------- count-up ----------
   app.js animates dashboard/wallet figures from 0 to their real value.  The
   number is tabular so digits do not jitter the layout as they tick. */
.hg-count {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}


/* ---------- dashboard sidebar affordance ----------
   The active pane marker used to be a static fill.  A short slide makes the
   selection legible when it changes on a click. */
.dash-nav-link { transition: background var(--dur-2) var(--ease-soft), color var(--dur-2) var(--ease-soft); }
.dash-nav-link .ico { transition: transform var(--dur-2) var(--ease-spring); }
.dash-nav-link:hover .ico { transform: translateY(-1px); }
.dash-nav-link.active .ico { transform: none; }


/* ---------- overview stat meters ----------
   The usage bars under HWID slots / projects jumped straight to their width. */
.ov-meter > i { transition: width .7s var(--ease-out); }


/* ---------- reduced motion ----------
   One block covers everything this layer adds, and also neutralises the older
   layers' keyframes, which shipped without any coverage at all. */
@media (prefers-reduced-motion: reduce) {
  body.rv-ready .rv,
  body.rv-ready .rv-lift {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .view.active,
  .tab-pane.active,
  .modal-overlay .modal-card {
    animation: none !important;
    transform: none !important;
    opacity: 1 !important;
    transition: none !important;
  }
  .dash-nav-link .ico,
  .ov-meter > i { transition: none !important; }

  /* The pre-existing animations from style.css / v49 / v50 / v51 / v52 that
     never had a reduced-motion branch. */
  .blob,
  .bg-grid,
  .notif-dot,
  .live-dot,
  .hg-loader,
  .hg-loader-logo,
  .hg-loader-bar,
  .faq-plus,
  .doc-step,
  .hw-step,
  .pcard,
  .feature-card,
  .lib-card,
  .mail-item,
  .notif-item,
  .staff-msg,
  .price-card,
  .hg-gyro,
  .hg-globe-spin,
  .hg-bead,
  .hg-mark {
    animation: none !important;
    transition-duration: 1ms !important;
  }
}
