/* ==========================================================================
   AN AUSTRIAN ECONOMIST · V4 GAZETTE FOUNDATION · MOTION
   --------------------------------------------------------------------------
   Ink does not bounce. Everything here is compositor-thread (transform and
   opacity only), wrapped in prefers-reduced-motion, and authored so the
   RESTING state is the complete page: browsers without a given API simply
   never play the delta. Scroll effects use animation-timeline: view()
   where supported; js/gazette.js arms an IntersectionObserver fallback
   (adds .io-motion to <html>, then .is-inked per element) elsewhere.
   ========================================================================== */

@layer motion {

/* --------------------------------------------------------------------------
   1 · Cross-document view transitions: the page turns beneath a masthead
   that holds still. Pure CSS opt-in; unsupported engines get a plain
   navigation. Both leaves must load this sheet.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }

  ::view-transition-old(root) {
    animation: vt-leaf-out var(--dur-exit, 150ms) var(--ease-in, ease-in) both;
  }
  ::view-transition-new(root) {
    animation: vt-leaf-in var(--dur-enter, 240ms) var(--ease-out, ease-out) both;
  }

  /* The masthead persists: same name on both leaves, snapshots swap with no
     animation, so identical mastheads read as one fixed nameplate. */
  .masthead { view-transition-name: masthead; }
  ::view-transition-group(masthead) { animation: none; }
  ::view-transition-old(masthead), ::view-transition-new(masthead) { animation: none; }
}

@keyframes vt-leaf-out {
  to { opacity: 0; }
}
@keyframes vt-leaf-in {
  from { opacity: 0; transform: translateY(7px); }
  to { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   2 · Scroll-driven settles and rule draw-ins.
   .settle        : a figure or module bites into the paper as it enters.
   .rule--draw    : a rule inks in from its left end.
   --settle-order : staggers siblings on the IO fallback path (n * 45ms).
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .settle {
      animation: gz-settle linear both;
      animation-timeline: view();
      animation-range: entry 8% entry 48%;
    }
    .rule--draw {
      transform-origin: left center;
      animation: gz-rule-draw linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 55%;
    }
  }

  /* IntersectionObserver fallback (armed by js/gazette.js only when the
     scroll-timeline API is absent). */
  .io-motion .settle {
    opacity: 0;
    transform: translateY(10px);
    transition:
      opacity var(--dur-settle) var(--ease-out) calc(var(--settle-order, 0) * 45ms),
      transform var(--dur-settle) var(--ease-out) calc(var(--settle-order, 0) * 45ms);
  }
  .io-motion .settle.is-inked { opacity: 1; transform: none; }

  .io-motion .rule--draw {
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 640ms var(--ease-out);
  }
  .io-motion .rule--draw.is-inked { transform: scaleX(1); }
}

@keyframes gz-settle {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@keyframes gz-rule-draw {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

/* --------------------------------------------------------------------------
   3 · The reading hairline: a 2px gold thread under a running head,
   driven by document scroll. Essay furniture; typography's progress bar.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    .progress-hair {
      height: 2px;
      background: var(--gold);
      transform-origin: left center;
      transform: scaleX(0);
      animation: gz-rule-draw linear both;
      animation-timeline: scroll(root);
    }
  }
}

/* --------------------------------------------------------------------------
   4 · Hover ink-in: ink meeting paper, 180-220ms, desktop pointers only.
   Touch never depends on hover; keyboard gets the same ink via
   :focus-visible. The state change itself is instant under reduced motion
   (the transition is what the media query gates).
   -------------------------------------------------------------------------- */
.ink-link {
  position: relative;
  text-decoration: none;
  color: var(--gold-deep);
}
.ink-link::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: -0.1em;
  height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left center;
}
.ink-link:hover::after,
.ink-link:focus-visible::after { transform: scaleX(1); }

/* Flex-box targets (44px min-height links) anchor the ink to an inner
   text span, so the rule draws under the WORDS, not the hit-box floor
   (checkpoint N2). Markup: <a class="ink-link"><span class="ink">…</span></a>.
   The 44px box stays on the anchor; the ink moves to the span. */
.ink-link:has(.ink)::after { content: none; }
.ink-link .ink { position: relative; }
.ink-link .ink::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: -0.12em;
  height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left center;
}
.ink-link:hover .ink::after,
.ink-link:focus-visible .ink::after { transform: scaleX(1); }

/* Two-tone headlines ink WHOLE to one gold on hover (creator ruling,
   ledger item 25, July 2026): the ink words take the accent's own shade
   and the accent word holds it, so the title reads as one gold piece.
   --gold is large-text-only (3.72:1); .ink-head lives on display heads. */
.ink-head { color: inherit; text-decoration: none; }
.ink-head:hover,
.ink-head:focus-visible { color: var(--gold); }
.ink-head:hover .display-accent,
.ink-head:focus-visible .display-accent { color: inherit; }

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .ink-link::after,
  .ink-link .ink::after { transition: transform var(--dur-ui) var(--ease-out); }
  .ink-head,
  .ink-head .display-accent { transition: color var(--dur-ui) var(--ease-out); }
}

/* --------------------------------------------------------------------------
   5 · Masthead press-in: the sheet comes off the press. Subliminal, once
   per session (js/gazette.js adds .press-in to <html> on the first leaf).
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .press-in .masthead__wordmark {
    animation: gz-press-fade 350ms var(--ease-out) both;
  }
  .press-in .masthead__rule {
    transform-origin: center top;
    animation: gz-press-rule 350ms var(--ease-out) both;
  }
}
@keyframes gz-press-fade {
  from { opacity: 0.96; }
  to { opacity: 1; }
}
@keyframes gz-press-rule {
  from { opacity: 0.55; transform: scaleY(0.6); }
  to { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   6 · The fold-out unfolds: a quiet settle on open. Direct manipulation
   inside the viewer is untweened, so reduced motion loses nothing.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .foldout[open] { animation: gz-foldout-open 220ms var(--ease-out); }
}
@keyframes gz-foldout-open {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

} /* @layer motion */
