/*
 * Scroll-motion system for the public site.
 *
 * Requirements §9: sections fade up as they enter the viewport, cards
 * arrive staggered, hero/feature imagery drifts or zooms gently, counters
 * count, and the header settles into its sticky state - all on transform
 * and opacity only (the two properties a browser can animate off the main
 * thread) and all driven by one IntersectionObserver in js/motion.js.
 *
 * Contract with the JS: an element opts in with a `data-reveal` attribute
 * and is styled by the matching class below; the observer adds
 * `.is-revealed` once, when the element first crosses the threshold. If the
 * script never runs - JS off, an error earlier on the page - the
 * `.js-motion` guard on <html> is absent and every element is simply
 * visible, so content is never hidden by a broken animation.
 */

.js-motion [data-reveal] {
  opacity: 0;
  will-change: opacity, transform;
  transition:
    opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.js-motion [data-reveal='up']    { transform: translate3d(0, 28px, 0); }
.js-motion [data-reveal='down']  { transform: translate3d(0, -22px, 0); }
.js-motion [data-reveal='left']  { transform: translate3d(-28px, 0, 0); }
.js-motion [data-reveal='right'] { transform: translate3d(28px, 0, 0); }
.js-motion [data-reveal='fade']  { transform: none; }
.js-motion [data-reveal='zoom']  { transform: scale(0.94); }

.js-motion [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Staggered children: a parent marked data-stagger hands each child an
   increasing delay, computed in JS so it works for any number of cards. */
.js-motion [data-stagger] > * {
  transition-delay: var(--reveal-delay, 0ms);
}

/* ---- Hover motion -------------------------------------------------- */

.motion-lift {
  transition:
    transform 0.28s cubic-bezier(0.22, 0.61, 0.36, 1),
    box-shadow 0.28s ease,
    border-color 0.28s ease;
}

.motion-lift:hover,
.motion-lift:focus-within {
  transform: translateY(-6px);
  box-shadow: var(--shadow-raised);
}

/* Media that grows very slightly inside a fixed frame on hover - the
   "premium card" feel of the reference site without any layout shift. */
.motion-zoom-frame {
  overflow: hidden;
}

.motion-zoom-frame img,
.motion-zoom-frame .motion-zoom-target {
  transition: transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.motion-lift:hover .motion-zoom-frame img,
.motion-zoom-frame:hover img,
.motion-zoom-frame:hover .motion-zoom-target {
  transform: scale(1.06);
}

/* A slow, continuous drift on hero imagery - the parallax substitute that
   costs nothing and never fights the user's scroll. */
.js-motion .motion-kenburns {
  animation: motion-kenburns 18s ease-in-out infinite alternate;
}

@keyframes motion-kenburns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.08) translate3d(0, -1.5%, 0); }
}

/* True parallax: js/motion.js writes --parallax-shift (px) on scroll for
   elements marked data-parallax. */
.js-motion [data-parallax] {
  transform: translate3d(0, var(--parallax-shift, 0px), 0);
  will-change: transform;
}

/* ---- Buttons ------------------------------------------------------- */

.motion-btn {
  position: relative;
  transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}

.motion-btn:hover { transform: translateY(-2px); }
.motion-btn:active { transform: translateY(0); }

/* An arrow that slides in the reading direction on hover - flips with
   [dir=rtl] because "forward" is leftwards in Arabic. */
.motion-arrow {
  display: inline-block;
  transition: transform 0.25s ease;
}

.motion-btn:hover .motion-arrow,
.motion-lift:hover .motion-arrow {
  transform: translateX(4px);
}

[dir='rtl'] .motion-btn:hover .motion-arrow,
[dir='rtl'] .motion-lift:hover .motion-arrow {
  transform: translateX(-4px);
}

/* ---- Reduced motion ------------------------------------------------
 * Everything above is decoration. Under prefers-reduced-motion the page
 * must still be complete and readable, so reveals resolve instantly and
 * the continuous animations stop entirely. js/motion.js makes the same
 * check and skips observing / counting / parallax. */

@media (prefers-reduced-motion: reduce) {
  .js-motion [data-reveal],
  .js-motion [data-reveal].is-revealed {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  .js-motion .motion-kenburns,
  .js-motion [data-parallax] {
    animation: none !important;
    transform: none !important;
  }

  .motion-lift,
  .motion-btn,
  .motion-arrow,
  .motion-zoom-frame img {
    transition: none !important;
  }

  .motion-lift:hover,
  .motion-btn:hover {
    transform: none !important;
  }
}
