/* =============================================================================
   HF Hub — Motion
   -----------------------------------------------------------------------------
   Durations, easings and keyframes only. Motion communicates state change, never
   decoration; boldness is spent in one place, not scattered. Everything here uses
   the motion tokens and the single shared --ease — nothing invents a new duration.

   Reusable across pages: mark elements to opt in. base.css already zeroes
   animation/transition DURATIONS under prefers-reduced-motion, but not animation
   delays, a declared initial transform, or a higher-specificity transition — the
   reduced-motion block at the foot of this file covers those.
============================================================================= */

/* --- Entrance --------------------------------------------------------------
   Elements arrive rather than appear: fade in while rising a short distance over
   the entrance duration, staggered in reading order by --enter-index. The stagger
   step is half the micro token (≈ 60ms), so a 6-element sequence still completes
   well under a second. Opacity/transform only — a marked element is never made
   non-interactive, so it stays focusable and typeable from the first frame. */
@keyframes hf-enter {
  from { opacity: 0; transform: translateY(var(--space-2)); }
  to   { opacity: 1; transform: translateY(0); }
}
.enter {
  animation: hf-enter var(--motion-entrance) var(--ease) both;
  animation-delay: calc(var(--enter-index, 0) * (var(--motion-micro) / 2));
}

/* --- Primary mark ----------------------------------------------------------
   For the page's primary mark (the logo here; the investor-pack hero later). The
   one deliberate flourish where the mark is the focus: it fades in from zero while
   settling very slightly in scale, 1.02 → 1, over the primary-mark settle duration
   so it reads as considered rather than quick — the scale is small enough to
   register as coming to rest, not a zoom, and the slower duration is what makes it
   deliberate, so the scale stays put. transform + opacity only, since the mark is a
   raster PNG and anything else would soften it. A lead-in pause first, so the
   canvas fully establishes and the mark arrives into a settled space rather than
   racing the first frame. */
@keyframes hf-logo-settle {
  from { opacity: 0; transform: scale(1.02); }
  to   { opacity: 1; transform: scale(1); }
}
.enter-logo {
  animation: hf-logo-settle var(--motion-mark-settle) var(--ease) both;
  animation-delay: var(--motion-mark-delay);
}

/* --- Dimension rule draw ---------------------------------------------------
   The signature device gets the one deliberate flourish: the line draws outward
   from the centre — a scaleX transform, not an animated width, so it stays smooth
   — and the end ticks appear once the line has reached them. Same duration and
   stagger slot as the rest of the sequence, so it finishes in step. Quiet and
   precise, not a swipe. */
@keyframes hf-rule-draw {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes hf-rule-tick {
  0%, 70% { opacity: 0; }
  100%    { opacity: 1; }
}
.enter-rule {
  transform: scaleX(0);
  transform-origin: center;
  animation: hf-rule-draw var(--motion-entrance) var(--ease) both;
  animation-delay: calc(var(--enter-index, 0) * (var(--motion-micro) / 2));
}
.enter-rule::before,
.enter-rule::after {
  opacity: 0;
  animation: hf-rule-tick var(--motion-entrance) var(--ease) both;
  animation-delay: calc(var(--enter-index, 0) * (var(--motion-micro) / 2));
}

/* --- Reveal ----------------------------------------------------------------
   For a message shown on demand by toggling [hidden] (a form error, say): fade in
   while rising a very short distance over the standard duration. Keyed to the
   visible state, so changing the text in place never replays the movement — only
   a fresh show animates. No shake, flash or colour animation. */
@keyframes hf-reveal {
  from { opacity: 0; transform: translateY(var(--space-1)); }
  to   { opacity: 1; transform: translateY(0); }
}
.reveal:not([hidden]) {
  animation: hf-reveal var(--motion-standard) var(--ease) both;
}

/* --- Theme transition ------------------------------------------------------
   Applied only while the theme is actually changing: a script adds .theme-anim to
   <html> immediately before flipping data-theme and removes it once the standard
   duration has elapsed. Surfaces, text and the crossfading logo move together.
   Because the class is momentary, no hover or focus state elsewhere in the app is
   ever left permanently transitioning — the real cost a global colour transition
   would carry. */
.theme-anim,
.theme-anim * {
  transition: background-color var(--motion-standard) var(--ease),
              color var(--motion-standard) var(--ease),
              border-color var(--motion-standard) var(--ease),
              opacity var(--motion-standard) var(--ease) !important;
}

/* --- Reduced motion --------------------------------------------------------
   Everything lands in its final state instantly: no entrance, the rule at full
   width with its ticks shown, the theme swapped with no crossfade, the error
   simply present. This explicitly covers what base.css cannot — the staggered
   delays, the rule's declared scaleX(0), and the higher-specificity .theme-anim
   transition. */
@media (prefers-reduced-motion: reduce) {
  .enter,
  .enter-logo,
  .enter-rule,
  .reveal:not([hidden]) {
    animation: none !important;
  }
  .enter-rule {
    transform: none !important;          /* rule at full width */
  }
  .enter-rule::before,
  .enter-rule::after {
    animation: none !important;
    opacity: 1 !important;               /* ticks shown */
  }
  .theme-anim,
  .theme-anim * {
    transition-duration: 0.01ms !important;   /* theme swaps instantly */
  }
}
