/* Motion system — Oct 2026
   One easing curve (the site's own), 0.4–0.9s durations, transform / opacity / clip-path only.
   Everything is gated behind html.mo, which an inline <head> script adds only when the visitor
   has not asked the OS to reduce motion. Without it (or without JS) the site is fully static. */
:root{--mo-ease:cubic-bezier(.22,1,.36,1)}

/* ---------- 1. Page-to-page morph (cross-document View Transitions) ---------- */
@media (prefers-reduced-motion:no-preference){
  @view-transition{navigation:auto}
  ::view-transition-old(root),::view-transition-new(root){animation-duration:.32s;animation-timing-function:ease}
  ::view-transition-group(case-media){animation-duration:.62s;animation-timing-function:var(--mo-ease);overflow:clip}
  ::view-transition-old(case-media),::view-transition-new(case-media){height:100%;width:100%;object-fit:cover;animation-duration:.62s}
}

/* ---------- 2. Scroll reveals (elements below the fold, marked by motion.js) ---------- */
.mo [data-mo]{transition:opacity .8s var(--mo-ease),transform .8s var(--mo-ease),clip-path .9s var(--mo-ease);transition-delay:var(--mo-d,0s)}
.mo [data-mo="up"]:not(.mo-in){opacity:0;transform:translateY(24px)}
.mo [data-mo="soft"]:not(.mo-in){opacity:0;transform:translateY(12px)}
/* mono kickers ("01 / EXPERTISE") type themselves out */
.mo [data-mo="type"]{transition:clip-path .75s steps(18,end);transition-delay:var(--mo-d,0s)}
.mo [data-mo="type"]:not(.mo-in){clip-path:inset(0 100% 0 0)}
.mo [data-mo="type"].mo-done{clip-path:none;transition:none}
/* project cards: the image opens like a curtain, the text rises after it */
.mo [data-mo="card"] .media{transition:clip-path 1s var(--mo-ease);transition-delay:var(--mo-d,0s)}
.mo [data-mo="card"]:not(.mo-in) .media{clip-path:inset(0 0 100% 0)}
.mo [data-mo="card"] .workdata{transition:opacity .8s var(--mo-ease),transform .8s var(--mo-ease);transition-delay:calc(var(--mo-d,0s) + .18s)}
.mo [data-mo="card"]:not(.mo-in) .workdata{opacity:0;transform:translateY(14px)}

/* ---------- 3. Hero: plays once on load (pure CSS, no flash) ---------- */
@keyframes mo-type{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
@keyframes mo-rise{from{opacity:0;transform:translateY(.32em)}to{opacity:1;transform:none}}
@keyframes mo-fade-up{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes mo-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
@keyframes mo-settle{from{transform:scale(1.07)}to{transform:scale(1)}}

/* fill "backwards" only: once typed, the clip is released entirely (Safari otherwise
   holds the last stepped value and trims the final character) */
.mo .ya-home-kicker span{animation:mo-type .8s steps(20,end) .15s backwards}
.mo .ya-home-kicker span+span{animation-delay:.5s;animation-duration:.9s}
.mo .hello{animation:mo-rise 1s var(--mo-ease) .25s both}
.mo .hello span{display:inline-block;animation:mo-rise 1s var(--mo-ease) .42s both}
.mo .ya-pronunciation{animation:mo-fade-up .8s var(--mo-ease) .7s both}
.mo .v4-hello-visual{animation:mo-fade-up 1.1s var(--mo-ease) .2s both,mo-float 7s ease-in-out 1.4s infinite;will-change:transform}
.mo .intro-right{animation:mo-fade-up 1s var(--mo-ease) .55s both}

/* Case-study heroes: the image settles, the title rises */
.mo header.hero .hero-media :is(img,video):first-child,
.mo header.hero > img:first-child{animation:mo-settle 1.8s var(--mo-ease) both}
.mo header.hero h1{animation:mo-rise 1s var(--mo-ease) .15s both}
.mo header.hero .hero-content > :not(h1){animation:mo-fade-up .9s var(--mo-ease) .35s both}
/* Arriving through a morph: the morph is the entrance, so skip the settle */
.mo.mo-vt header.hero :is(img,video){animation:none}

/* ---------- 5. Wireframe ↔ render comparator (Lagomya LOD section) ---------- */
.mo-cmp{position:relative;touch-action:pan-y;cursor:ew-resize}
.mo-cmp img.wf{clip-path:inset(0 0 0 var(--split,50%))!important;opacity:1!important;visibility:visible!important}
.mo-cmp .mo-handle{position:absolute;top:0;bottom:0;left:var(--split,50%);width:0;z-index:3;pointer-events:none}
.mo-cmp .mo-handle::before{content:"";position:absolute;top:0;bottom:0;left:-.5px;width:1px;background:currentColor;opacity:.85}
.mo-cmp .mo-handle::after{content:"";position:absolute;top:50%;left:-15px;width:30px;height:30px;margin-top:-15px;border-radius:50%;background:var(--bg,#e9e9e6);border:1px solid currentColor;box-shadow:0 4px 18px rgba(0,0,0,.18)}
.mo-cmp .mo-tag{position:absolute;bottom:10px;z-index:3;font-family:var(--mono,ui-monospace,monospace);font-size:10px;letter-spacing:.1em;padding:3px 7px;background:rgba(20,22,21,.72);color:#eee;pointer-events:none;transition:opacity .3s}
.mo-cmp .mo-tag.l{left:10px}.mo-cmp .mo-tag.r{right:10px}
.mo-cmp:focus-visible{outline:2px solid currentColor;outline-offset:3px}
.mo-cmp.sweep img.wf,.mo-cmp.sweep .mo-handle{transition:clip-path 1.6s var(--mo-ease),left 1.6s var(--mo-ease)}
@media (max-width:760px){
  .mo-cmp .mo-tag{display:none}
  .mo-cmp .mo-handle::after{width:16px;height:16px;left:-8px;margin-top:-8px;box-shadow:0 2px 8px rgba(0,0,0,.2)}
}

