/* ==========================================================================
   Jobson Garden — page motion

   Loaded by About, Services and Garden Tips. Scoped to [data-motion] rather
   than to one page's class, so the three inner pages open the same way.

   Motion vocabulary lifted from the supplied walkthrough reel, frame by
   frame. Per section the reel plays: heading first, then the imagery from
   further away and slightly scaled, then body copy, then the button, then
   small hand-drawn accent marks popping in last — roughly 90ms apart, with
   a short overshoot as each element settles. Imagery also drifts against
   the text while scrolling.

   Everything is scoped to .js, which is set before first paint. If scripting
   fails the page renders flat and complete — never blank.
   ========================================================================== */

[data-motion] {
  /* Overshoot lives on transform only. Opacity easing past 1 would flicker. */
  --rv-spring: cubic-bezier(.16, 1.08, .3, 1);
  --rv-fade:   cubic-bezier(.22, .61, .36, 1);
  --rv-move:   780ms;
  --rv-opacity: 520ms;
  --rv-step:   90ms;    /* gap between siblings in a sequence */
}

/* --- Base hidden state ---------------------------------------------------- */

.js [data-motion] [data-rv] {
  opacity: 0;
  transition:
    opacity var(--rv-opacity) var(--rv-fade) var(--rv-delay, 0ms),
    transform var(--rv-move) var(--rv-spring) var(--rv-delay, 0ms);
  will-change: transform, opacity;
}

/* Travel distances differ by role — that difference is what reads as depth.
   Text moves a little, imagery moves a lot and arrives slightly scaled. */
.js [data-motion] [data-rv="up"]    { transform: translate3d(0, 26px, 0); }
.js [data-motion] [data-rv="media"] { transform: translate3d(0, 48px, 0) scale(.965); }
.js [data-motion] [data-rv="left"]  { transform: translate3d(-38px, 14px, 0); }
.js [data-motion] [data-rv="right"] { transform: translate3d(38px, 14px, 0); }
.js [data-motion] [data-rv="pop"]   { transform: scale(.55) rotate(-8deg); }

.js [data-motion] [data-rv].rv-in {
  opacity: 1;
  transform: none;
  filter: none;
}
/* Released once settled: a permanent will-change holds a compositor layer
   for every element on the page. */
.js [data-motion] [data-rv].rv-done { will-change: auto; }

/* --- Accent marks ---------------------------------------------------------
   The reel puts small hand-drawn sparkles beside each heading, arriving
   after the words. Brand leaf green, decorative only. */

.about-spark {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-left: 0.35em;
  vertical-align: baseline;
  color: var(--leaf);
  transform-origin: 50% 60%;
  pointer-events: none;
}
.about-spark svg { width: 100%; height: 100%; display: block; }

/* --- Parallax -------------------------------------------------------------
   --px is written by assets/js/motion.js as a pixel offset. Combined with the
   reveal transform via a separate wrapper so the two never fight: the
   reveal animates the child, the parallax translates the parent. */

.js [data-motion] [data-parallax] {
  transform: translate3d(0, calc(var(--px, 0) * 1px), 0);
  will-change: transform;
}

/* --- Cover --------------------------------------------------------------- */

/* The reel opens by flying into the banner, the image settling from a slight
   zoom. Runs on load, not on scroll — it is the first thing on screen, so
   there is nothing to wait for it to scroll into. */
.js [data-motion] .page-cover__img {
  animation: jg-cover-settle 1400ms var(--rv-spring) both;
}
@keyframes jg-cover-settle {
  from { transform: scale(1.08); }
  to   { transform: scale(1); }
}

/* --- Reduced motion -------------------------------------------------------
   Rule 7: every animation branches here. Nothing hidden, nothing moving. */

@media (prefers-reduced-motion: reduce) {
  .js [data-motion] [data-rv],
  .js [data-motion] [data-rv].rv-in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .js [data-motion] [data-parallax] { transform: none !important; }
  .js [data-motion] .page-cover__img { animation: none !important; }
  .about-spark { display: none; }
}
