/* ============================================================
   Motion layer for the Sandra R. Dayan site.
   Loaded after the page's own <style> block so it can override, and
   every rule is gated on html.motion so the static path (?static, or
   prefers-reduced-motion) renders completely untouched.

   Taste rule: quiet luxury. If a movement announces itself, it is
   wrong. Everything below is slow, small, and only happens once.
   ============================================================ */

/* Smooth-scroll hijacking (Lenis) was tried here and removed — it fought the
   trackpad and read as sluggish. Native scrolling only. */

/* ---- 2 + 3 · image mask reveal and parallax ------------------------------
   The picture is the masked/scaled element; the <img> inside carries the
   parallax. Splitting them means the two never fight over one transform.
   The image is deliberately taller than its frame so a ±6% drift never
   exposes an edge. */
/* Only the opening photograph drifts now. The portrait is left completely
   still — no parallax, no reveal, no hover zoom. */
html.motion .opening img {
  height: 112%;
  top: -6%;
  position: relative;
  will-change: transform;
}
/* On phones the parallax is off (see motion.js), so the image must not be the
   oversized/offset version — that would just show a zoomed, shifted crop that
   doesn't match the static frame. Fill it exactly instead. */
@media (max-width: 820px) {
  html.motion .opening img { height: 100%; top: 0; will-change: auto; }
}

/* ---- 4 · the signature signs itself --------------------------------------
   The .sig elements are now her real signature painted through a PNG mask
   (see .sig-img in index.html), so the reveal can no longer be a second mask —
   the image mask already owns mask-image. Instead clip it left-to-right: as
   --sig-ink runs 0→108% the right inset shrinks 100%→0 and the ink appears
   the way a pen lays it down. --sig-ink is driven by motion.js exactly as
   before, and in the static path (no html.motion) the signature just shows. */
html.motion .about .sig,
html.motion footer .sig {
  clip-path: inset(0 calc(100% - var(--sig-ink, 0%)) 0 0);
}

/* ---- 5 · hairlines draw themselves ---------------------------------------
   The real border is handed to a pseudo-element so only transform animates.
   --line is the scale GSAP drives. */
/* .details (Let's talk) is NOT in this list any more. Its animation was cut, and
   leaving the border transparent here would have left those hairlines missing
   until a backstop rescued them — the rule that hides the border and the tween
   that draws it have to be removed together. */
html.motion .service .col,
html.motion .rgrid blockquote { border-top-color: transparent; position: relative; }

html.motion .service .col::before,
html.motion .rgrid blockquote::before {
  content: ""; position: absolute; inset-inline: 0; top: -1px; height: 1px;
  background: #DCCFBB;
  transform: scaleX(var(--line, 0)); transform-origin: left center;
}

/* ---- 6 · the quote arrives a line at a time ------------------------------ */
html.motion .line-box { display: block; overflow: clip; }
html.motion .line-in  { display: block; will-change: transform, opacity, filter; }

/* ---- 7 · quiet polish ---------------------------------------------------- */
html.motion .opening > picture { overflow: hidden; }
/* the portrait hover zoom was cut with the rest of its movement */

/* the mobile bar slides up instead of appearing. It has to stay in the DOM as
   flex for the transform to animate, so visibility keeps it out of the tab
   order while it is off-screen. */
@media (max-width: 900px) {
  html.motion .sticky,
  html.motion body.is-scrolled .sticky { display: flex; }
  /* Resting state carries NO transition. motion.css only takes effect once JS
     adds .motion, so the bar would otherwise animate from its default position
     down and off-screen on every single page load — a visible flash before the
     visitor has done anything. .motion-ready arrives a beat later and is what
     actually turns the movement on. */
  html.motion .sticky { transform: translateY(115%); visibility: hidden; }
  html.motion body.is-scrolled .sticky { transform: none; visibility: visible; }

  html.motion.motion-ready .sticky {
    transition: transform .75s cubic-bezier(.16,1,.3,1), visibility 0s linear .75s;
  }
  html.motion.motion-ready body.is-scrolled .sticky {
    transition: transform .75s cubic-bezier(.16,1,.3,1), visibility 0s;
  }
}

/* (Removed: a blunt "[data-anim][data-shown] .line-in { opacity:1 !important }"
   safety rule used to live here. But the quote <p> IS a [data-anim] element, so
   the moment the page's reveal marked it shown this rule forced every line to
   opacity 1 — pre-empting the line-by-line blur reveal before it could play.
   Stranded lines are already rescued by settle() in motion.js, which checks
   real visibility and does not fire until the reveal has had its chance.) */
