/* Motion (2026-10-19, Michael: "basicly everything should animate in some way but they need to be within the same
   movement family but not exactly the same. it cannot feel repetitive or random or wild. it must feel like a sharp
   premium product").

   One family, "focus": everything arrives slightly soft and settles sharp on the same curve, the way a lens
   acquires focus, and the headline brackets lock like the autofocus box. Kinds, picked by js/motion.js from
   what the element is:
     word    headlines: each word snaps up out of a mask, then the brackets lock
     media   photos, video, photo cards: a focus pull (soft and a touch wide, to sharp and framed)
     rise    text, rows, prices, FAQs, steps, stats, buttons, form fields: rises a few pixels into focus
   Order, not randomness, keeps it from repeating: things arrive in reading order, each batch cascades 55ms
   apart, and each kind has its own length (rise .56s, word .64s, media .9s).
   Only with JavaScript (html.mo, set in the head) and never with Reduce Motion. */

:root {
  --mo-ease: cubic-bezier(.2, .8, .2, 1);          /* the site's own curve (the brackets, the AF box) */
  --mo-snap: cubic-bezier(.3, 0, .2, 1);
}

/* Until motion.js has tagged the page, main waits (motion.js runs at the end of the body, before first paint
   in practice; the head's fallback drops html.mo after 3 seconds if it never ran). */
html.mo:not(.mo-ready) main { opacity: 0; }

html.mo [data-mo] { opacity: 0; }
/* the hero's older one off fades (site.css copy-in) give way to this, so nothing plays twice */
html.mo .vp-copy > *, html.mo .vp-stats-in > div { animation: none; }
html.mo [data-mo="word"] { opacity: 1; }
html.mo [data-mo].in { opacity: 1; animation-duration: .56s; animation-timing-function: var(--mo-ease); animation-fill-mode: both;
  animation-delay: var(--mo-d, 0ms); }

html.mo [data-mo="rise"].in { animation-name: mo-rise; }
html.mo [data-mo="media"].in { animation-name: mo-focus; animation-duration: .9s; }
html.mo [data-mo="media-hero"].in { animation-name: mo-focus-hero; animation-duration: 1.1s; }

@keyframes mo-rise {
  from { opacity: 0; transform: translateY(14px); filter: blur(5px); }
  to { opacity: 1; transform: none; filter: none; }
}
@keyframes mo-focus {
  from { opacity: 0; transform: scale(1.06); filter: blur(12px); clip-path: inset(5%); }
  to { opacity: 1; transform: none; filter: none; clip-path: inset(0); }
}
@keyframes mo-focus-hero {
  from { opacity: .001; transform: scale(1.05); filter: blur(14px) brightness(.8); }
  to { opacity: 1; transform: none; filter: none; }
}

/* headlines: each word in a mask (motion.js wraps them), rising one after another */
.mo-w { display: inline-block; overflow: hidden; vertical-align: top; padding: 0 .07em .1em 0; margin: 0 -.07em -.1em 0; }
.mo-w > span { display: inline-block; }
html.mo [data-mo="word"] .mo-w > span { transform: translateY(110%); }
html.mo [data-mo="word"].in .mo-w > span { animation: mo-word .64s var(--mo-ease) both; animation-delay: calc(var(--mo-d, 0ms) + var(--mo-i, 0) * var(--mo-step, 36ms)); }
@keyframes mo-word { from { transform: translateY(110%); } to { transform: none; } }

/* the brackets lock after the last word (site.css's own lk-in, lk-lock and lk-glow, re-timed) */
html.mo [data-mo="word"] .lock > .lk { animation: none; opacity: 0; }
html.mo [data-mo="word"].in .lock > .lk { opacity: 1; animation: lk-in .5s var(--mo-ease) var(--mo-lk, .6s) both; }
html.mo [data-mo="word"].in .lock > .lk i:nth-child(4) { animation: lk-lock .01s linear calc(var(--mo-lk, .6s) + .42s) both; }
html.mo [data-mo="word"].in .lock > .lk i:nth-child(1), html.mo [data-mo="word"].in .lock > .lk i:nth-child(2),
html.mo [data-mo="word"].in .lock > .lk i:nth-child(3) { animation: lk-glow .45s ease-out calc(var(--mo-lk, .6s) + .36s) both; }

/* hover and press: the same family, quicker */
.link { transition: text-decoration-color .18s var(--mo-snap), text-underline-offset .18s var(--mo-snap); }
.link:hover { text-underline-offset: 3px; }
.btn:active { transform: translateY(0) scale(.985); box-shadow: none; transition-duration: .06s; }
.nav-link { transition: background-color .18s var(--mo-snap), box-shadow .18s var(--mo-snap); }
.nav-link:hover { box-shadow: inset 0 -3px 0 var(--orange); }
.svc-card img, .svc-card video { transition: transform .5s var(--mo-ease); }
/* a photo card under the pointer gets the autofocus corners, the orange one last */
.svc-card::after {
  content: ""; position: absolute; inset: 12px; z-index: 2; pointer-events: none; opacity: 0; transform: scale(1.08);
  --c: var(--chalk); --t: 3px; --l: 22px;
  background:
    linear-gradient(var(--c), var(--c)) top left / var(--l) var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) top left / var(--t) var(--l) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / var(--l) var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / var(--t) var(--l) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / var(--l) var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / var(--t) var(--l) no-repeat,
    linear-gradient(var(--orange), var(--orange)) top right / var(--l) var(--t) no-repeat,
    linear-gradient(var(--orange), var(--orange)) top right / var(--t) var(--l) no-repeat;
  transition: opacity .16s var(--mo-snap), transform .28s var(--mo-ease);
}
.svc-card:hover::after, .svc-card:focus-visible::after { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .svc-card::after { transition: none; transform: none; }
  .link, .nav-link, .svc-card img, .svc-card video { transition: none; }
}
