/* ------------------------------------------------------------------
   Motion. Every keyframe and transition in the system lives here.
   The page breathes; it does not perform. transform + opacity only.
   ------------------------------------------------------------------ */

/* Scroll reveal: elements rise 24px into place, staggered, once. */
[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 24px, 0);
  transition:
    opacity   var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
  transition-delay: calc(var(--reveal-i, 0) * var(--stagger));
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* JS failed or absent: everything is visible. Non-negotiable. */
.no-js [data-reveal] { opacity: 1; transform: none; }
.no-js .rule, .no-js .rule-v { transform: none; }

/* The flowy line: a hairline rule that draws itself. */
.rule {
  height: 1px;
  background: var(--tfhp-blue);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-line) var(--ease-line);
  transition-delay: 240ms;
}
.rule.is-in { transform: scaleX(1); }
.s-dark .rule { background: var(--tfhp-sky); }

/* Vertical rule variant (stats band dividers): draws downward. */
.rule-v {
  width: 1px;
  background: var(--tfhp-line);
  transform: scaleY(0);
  transform-origin: center top;
  transition: transform var(--dur-line) var(--ease-line);
  transition-delay: 240ms;
}
.rule-v.is-in { transform: scaleY(1); }

/* Text links: underline draws from the left, retracts to the right. */
.text-link {
  position: relative;
  color: var(--tfhp-blue);
  font-family: var(--font-ui);
  font-weight: 700;
  text-decoration: none;
}
.s-dark .text-link { color: var(--tfhp-sky); }
.text-link::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform var(--dur-mid) var(--ease-soft);
}
.text-link:hover::after,
.text-link:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

/* The swash arrow flicks forward with a small spring on hover */
.arrow {
  display: inline-block;
  width: 1.15em;
  height: auto;
  flex-shrink: 0;
  transition: transform var(--dur-mid) var(--ease-spring);
}
a:hover .arrow, button:hover .arrow,
a:focus-visible .arrow, button:focus-visible .arrow {
  transform: translateX(5px) rotate(-8deg);
}

/* Buttons squash slightly when pressed: the click feels alive */
.btn { transition: background-color var(--dur-fast) var(--ease-soft),
                   color var(--dur-fast) var(--ease-soft),
                   border-color var(--dur-fast) var(--ease-soft),
                   transform var(--dur-mid) var(--ease-spring); }
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0) scale(0.97); }

/* Card hover: springy lift, 4 percent image scale, title colour */
.card { transition: transform var(--dur-mid) var(--ease-spring); }
.card:hover, .card:focus-within { transform: translateY(-5px); }
.card:active { transform: translateY(-2px) scale(0.99); }

/* The play badge pops with a tilt when its card is hovered */
.play-badge { transition: transform var(--dur-mid) var(--ease-spring); }
.card:hover .play-badge,
.video-facade:hover .play-badge,
.video-facade:focus-visible .play-badge {
  transform: scale(1.12) rotate(-8deg);
}

.card__media { overflow: hidden; border-radius: var(--radius); }
.card__media img { transition: transform var(--dur-mid) var(--ease-soft); }
.card:hover .card__media img,
.card:focus-within .card__media img { transform: scale(1.04); }

.card__title { transition: color var(--dur-fast) var(--ease-soft); }
.card:hover .card__title { color: var(--tfhp-blue); }
.s-dark .card:hover .card__title { color: var(--tfhp-sky); }

/* Hero load sequence. The H1 is painted immediately; only opacity and
   transform animate, starting on the first frame. No scroll observer. */
@keyframes tfhp-rise {
  from { opacity: 0; transform: translate3d(0, 24px, 0); }
  to   { opacity: 1; transform: none; }
}

.hero [data-hero-seq] {
  animation: tfhp-rise var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--seq, 0) * 120ms);
}

/* Hero rolling column: vertical, slow, pausable, made of real links.
   The track is duplicated once in the DOM and translated by -50 percent. */
@keyframes tfhp-roll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, -50%, 0); }
}

.roll__track {
  animation: tfhp-roll 45s linear infinite;
  will-change: transform;
}
.roll__track--slow { animation-duration: 60s; }

.roll:hover .roll__track,
.roll:focus-within .roll__track {
  animation-play-state: paused;
}

/* Header compression */
.site-header {
  transition:
    background-color var(--dur-mid) var(--ease-soft),
    box-shadow var(--dur-mid) var(--ease-soft);
}
.site-header .header-bar {
  transition: height var(--dur-mid) var(--ease-soft);
}

/* Accordion: the only reliable way to animate to auto height. */
.accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-mid) var(--ease-soft);
}
.accordion__panel > div { overflow: hidden; }
.accordion__item.is-open .accordion__panel { grid-template-rows: 1fr; }

/* Chips */
.chip { transition: background-color var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft), border-color var(--dur-fast) var(--ease-soft); }

/* Platform marks colourise on hover (colour set per-platform in components). */
.platform-stamp a { transition: color var(--dur-fast) var(--ease-soft); }

/* Mobile nav panel */
.nav-panel {
  transition: transform var(--dur-mid) var(--ease-soft), visibility var(--dur-mid);
}

/* ------------------------------------------------------------------
   Reduced motion. Mandatory, global, honoured everywhere.
   ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .rule   { transform: scaleX(1) !important; }
  .rule-v { transform: scaleY(1) !important; }
  .roll__track { animation: none !important; }
  .hero [data-hero-seq] { animation: none !important; opacity: 1; transform: none; }
}

/* Card hover also flicks the arrow inside its CTA span */
.card:hover .arrow, .card:focus-within .arrow {
  transform: translateX(5px) rotate(-8deg);
}
