/* Motion for the service pages. Loaded by build-services.js on /services/*.
   Ported from the scroll-motion kit (reveals with a failsafe, counters, scroll
   zoom, hover zoom) plus scroll-driven steps for pinned sections.
   Everything collapses to its finished state under prefers-reduced-motion. */

:root { --ease-out-soft: cubic-bezier(0.22, 1, 0.36, 1); }

/* Reveals ---------------------------------------------------------------- */
.sm [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .8s var(--ease-out-soft), transform .8s var(--ease-out-soft);
  transition-delay: var(--d, 0ms);
}
.sm [data-reveal="left"]  { transform: translateX(-32px); }
.sm [data-reveal="right"] { transform: translateX(32px); }
.sm [data-reveal="scale"] { transform: scale(.94); }
.sm [data-reveal="line"]  { opacity: 1; transform: scaleX(0); transform-origin: left center; transition: transform 1s var(--ease-out-soft); transition-delay: var(--d, 0ms); }
/* Headline lines rise out of a mask, one line at a time. */
.sm [data-reveal="mask"] { opacity: 1; transform: none; }
[data-reveal="mask"] .m-line { display: block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.sm [data-reveal="mask"] .m-line > span { display: inline-block; transform: translateY(105%); transition: transform 1s var(--ease-out-soft); transition-delay: calc(var(--d, 0ms) + var(--i, 0) * 110ms); }
.sm [data-reveal].is-in { opacity: 1; transform: none; }
.sm [data-reveal="mask"].is-in .m-line > span { transform: none; }

/* Hover zoom: class on the clipping parent and the image. */
.hz { overflow: hidden; }
.hz .hz-img { transition: transform .9s var(--ease-out-soft); }
.hz:hover .hz-img { transform: scale(1.05); }

/* Scroll zoom wrapper (transform written by motion.js). */
[data-zoom] { transform: scale(1.12); transform-origin: center; will-change: transform; }
[data-zoom="hero"] { transform: scale(1.02); }

/* Scroll-driven steps: a [data-steps] section sets data-step; children with
   data-at="n" switch on once the step reaches n. */
[data-at] { transition: opacity .6s var(--ease-out-soft), transform .6s var(--ease-out-soft), background-color .4s, border-color .4s, color .4s; }
.sm [data-at].fade-step { opacity: 0; transform: translateY(14px); }
.sm [data-at].fade-step.is-on { opacity: 1; transform: none; }

/* Captions that hold the stage for one step range (data-only). */
.sm [data-only] { opacity: 0; transform: translateY(18px); transition: opacity .5s var(--ease-out-soft), transform .5s var(--ease-out-soft); pointer-events: none; }
.sm [data-only].is-now { opacity: 1; transform: none; pointer-events: auto; }

/* Scroll-drawn timelines ([data-scrub]): the line grows with --p, each dot
   and step lights up as the line reaches it. --tl sets the colour. */
.tl-track { background: rgba(255,255,255,.12); }
.tl-line, .tl-vline { background: var(--tl, #F600FE); box-shadow: 0 0 12px var(--tl, #F600FE); }
.sm .tl-line { transform: scaleX(var(--p, 0)); transform-origin: left center; }
.sm .tl-vline { transform: scaleY(var(--p, 0)); transform-origin: center top; }
.tl-dot { background: #141418; border: 1px solid rgba(255,255,255,.15); color: #71717a; transition: background-color .4s, border-color .4s, color .4s, box-shadow .4s, transform .5s cubic-bezier(.34,1.56,.64,1); }
.tl-dot svg { width: 22px; height: 22px; }
.tl-dot.is-on { background: var(--tl, #F600FE); border-color: transparent; color: var(--tl-ink, #fff); box-shadow: 0 0 0 7px color-mix(in srgb, var(--tl, #F600FE) 20%, transparent), 0 0 26px var(--tl, #F600FE); transform: scale(1.08); }
/* A sticker that pops in when its step lights up. */
.tl-sticker { --r: -6deg; opacity: 0; transform: scale(.3) rotate(var(--r)); transition: opacity .25s, transform .55s cubic-bezier(.34,1.56,.64,1); transition-delay: .12s; }
.tl-sticker.is-on { opacity: 1; transform: scale(1) rotate(var(--r)); }
.sm .tl-item { opacity: .35; transform: translateY(8px); transition: opacity .6s var(--ease-out-soft), transform .6s var(--ease-out-soft); }
.sm .tl-item.is-on { opacity: 1; transform: none; }

/* Pointer tilt on cards (desktop pointers only, set by motion.js). */
[data-tilt], .sm [data-reveal][data-tilt].is-in { transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); }
[data-tilt] { transition: transform .5s var(--ease-out-soft), opacity .8s var(--ease-out-soft), border-color .3s; }

/* Endless marquee. */
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee-track { display: flex; width: max-content; animation: marquee var(--marquee-s, 40s) linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(-50%); } }

@media (prefers-reduced-motion: reduce) {
  [data-reveal], [data-reveal="mask"] .m-line > span, [data-at].fade-step { opacity: 1 !important; transform: none !important; transition: none !important; }
  [data-zoom], [data-tilt] { transform: none !important; }
  .tl-line, .tl-vline, .tl-item, .tl-sticker { transform: none !important; opacity: 1 !important; }
  .hz:hover .hz-img { transform: none; }
  .marquee-track { animation: none; }
}
