/* motion (03.11, approved by Amir from the demo): every effect is scoped to its class on <html>, set by motion.js */

/* media inside frames: hover, reveal and parallax share one scale; parallax moves with `translate` */
.tile img, .tile video, .ptile img, .ftile img, .work img {
  scale: calc(var(--pz, 1) * var(--hz, 1) * var(--rz, 1));
  translate: 0 var(--py, 0px);
  transition: scale 1.4s cubic-bezier(.2, .7, .2, 1), clip-path 1.1s cubic-bezier(.77, 0, .18, 1), opacity .6s;
}
html .tile:hover img, html .tile:hover video, html .ptile:hover img, html .ftile:hover img { transform: none; }
@media (hover: hover) {
  .tile:hover, .ptile:hover, .ftile:hover, .work .w:hover { --hz: 1.035; }
}
.ptile .ph { position: relative; }

/* 1 · reveal on scroll */
html.m-reveal .rv { transition: opacity .7s ease, translate 1s cubic-bezier(.16, 1, .3, 1); transition-delay: var(--rd, 0ms); }
html.m-reveal .rv:not(.in) { opacity: 0; translate: 0 34px; }
html.m-reveal .rv-img img, html.m-reveal .rv-img video, html.m-reveal img.rv-self { transition-delay: var(--rd, 0ms); }
html.m-reveal .rv-img:not(.in) img, html.m-reveal .rv-img:not(.in) video, html.m-reveal img.rv-self:not(.in) {
  clip-path: inset(100% 0 0 0); --rz: 1.18;
}
html.m-reveal img.rv-self { transition: opacity .7s ease, translate 1s cubic-bezier(.16, 1, .3, 1), clip-path 1.1s cubic-bezier(.77, 0, .18, 1); transition-delay: var(--rd, 0ms); }
html.m-reveal .rv-img img, html.m-reveal .rv-img video { clip-path: inset(0 0 0 0); }

/* 3 · tile grows into the full-screen viewer */
.mfly { position: fixed; z-index: 70; overflow: hidden; pointer-events: none; background: #000; }
.mfly img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.mshade { position: fixed; inset: 0; z-index: 69; background: #000; pointer-events: none; }

/* 5 · headings rise letter by letter */
.tt .tw { display: inline-block; white-space: nowrap; }
html.m-title .tt .tw { overflow: hidden; vertical-align: top; padding-bottom: .14em; margin-bottom: -.14em; }
.tt .tc { display: inline-block; }
html.m-title .tt .tc { transition: translate 1s cubic-bezier(.16, 1, .3, 1); transition-delay: calc(var(--ci) * 24ms); }
html.m-title .tt:not(.in) .tc { translate: 0 112%; }

/* 6 · parallax: media is a bit larger than its frame and slides inside it */
html.m-parallax .tile, html.m-parallax .ptile .ph, html.m-parallax .ftile, html.m-parallax .work .w { --pz: 1.07; }

/* 7 · smooth scroll (lenis) — computer only */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

/* 9 · project preview: frames of the project take turns inside the cover */
.mpv img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0;
  transition: opacity .5s ease, scale 1.4s cubic-bezier(.2, .7, .2, 1);
}
.mpv img.on { opacity: 1; }
.mpv-bar { position: absolute; left: 10px; right: 10px; bottom: 10px; display: flex; gap: 4px; opacity: 0; transition: opacity .3s; }
.mpv-bar i { flex: 1; height: 2px; border-radius: 1px; background: rgba(255, 255, 255, .35); transition: background .3s; }
.mpv-bar i.on { background: #fff; }
.ph.pv .mpv-bar { opacity: 1; }

/* 10 · soft change between pages: the old page fades up and away, the new one rises in; the header stays */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: mvt-out .24s ease-in both; }
::view-transition-new(root) { animation: mvt-fade .5s ease-out .18s both, mvt-rise .9s cubic-bezier(.16, 1, .3, 1) .18s both; }
@keyframes mvt-out { to { opacity: 0; transform: translateY(-10px); } }
@keyframes mvt-fade { from { opacity: 0; } }
@keyframes mvt-rise { from { transform: translateY(26px); } }
header.top { view-transition-name: mtop; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }
