/* Subtle motion layer: hero entrance, scroll reveals, case-study transitions.
   Everything here is opt-in through html.motion-ready, which is only set when
   the visitor has not asked for reduced motion. */
:root{--ease-out:cubic-bezier(.16,1,.3,1)}
/* Page-to-page fade (both pages must opt in; the incoming page styles it) */
@media(prefers-reduced-motion:no-preference){@view-transition{navigation:auto}::view-transition-old(root){animation:.4s ease both ru-page-out}::view-transition-new(root){animation:.75s cubic-bezier(.16,1,.3,1) both ru-page-in}@keyframes ru-page-out{to{opacity:0}}@keyframes ru-page-in{from{opacity:0;transform:scale(1.02)}}}

/* Hero entrance */
@keyframes rise-in{from{opacity:0;translate:0 26px}to{opacity:1;translate:0 0}}
@keyframes nav-in{from{opacity:0;translate:0 -14px}to{opacity:1;translate:0 0}}
@keyframes fan-in{from{opacity:0;translate:0 90px}to{opacity:1;translate:0 0}}
.motion-ready .site-nav{animation:nav-in .8s var(--ease-out) backwards}
.motion-ready .hero-copy h1{animation:rise-in 1.1s var(--ease-out) .12s backwards}
.motion-ready .hero-copy p{animation:rise-in 1s var(--ease-out) .32s backwards}
.motion-ready .hero-copy .btn{animation:rise-in 1s var(--ease-out) .46s backwards}
.motion-ready .fan{animation:fan-in 1.4s var(--ease-out) .5s backwards}

/* Sky drifts a touch slower than the page */
@supports (animation-timeline:scroll()){
 @keyframes sky-drift{to{transform:translateY(90px) scale(1.06)}}
 @media(min-width:651px) and (hover:hover){.motion-ready .sky-hero:before{animation:sky-drift linear both;animation-timeline:scroll(root);animation-range:0 900px}}
 @keyframes read-progress{from{transform:scaleX(0)}to{transform:scaleX(1)}}
 .motion-ready body:before{content:'';position:fixed;top:0;left:0;right:0;height:2px;z-index:100;background:linear-gradient(90deg,#316cf0,#7aa2ff);transform-origin:0 50%;pointer-events:none;animation:read-progress linear both;animation-timeline:scroll(root)}
}

/* Scroll reveals: motion.js tags elements with [data-reveal] and animates them in */
.motion-ready [data-reveal]:not(.is-revealed){opacity:0}
@media print{.motion-ready [data-reveal]{opacity:1!important}}

/* Process timeline: a transform-only line fills with blue as you scroll,
   and each number lights up once the fill reaches it */
.motion-ready .timeline-step:not(:last-child):before{width:2px;margin-left:-.5px;background:#dfe7f5}
.motion-ready .step-number{transition:background .45s var(--ease-out),color .45s var(--ease-out),border-color .45s,box-shadow .6s var(--ease-out)}
.motion-ready .timeline-step.is-active .step-number{background:#316cf0;border-color:#316cf0;color:#fff;box-shadow:0 0 0 7px #316cf01a}

.timeline-fill{position:absolute;left:26.5px;top:50%;height:100%;width:2px;background:#316cf0;transform:scaleY(0);transform-origin:top;pointer-events:none}
@media(max-width:900px){.timeline-fill{left:22.5px}}
@media(max-width:650px){.timeline-fill{left:18.5px;top:44px}}
/* Case studies: copy cascades in, photo breathes while open */
.case-reveal h3{font-variant-numeric:tabular-nums}
@keyframes case-line{from{opacity:0;translate:0 18px}to{opacity:1;translate:0 0}}
@keyframes case-breathe{from{transform:scale(1.001)}to{transform:scale(1.07)}}
.motion-ready .case-panel.is-open .case-reveal-inner>*{animation:case-line .7s var(--ease-out) both}
.motion-ready .case-panel.is-open .case-reveal-inner>:nth-child(2){animation-delay:.22s}
.motion-ready .case-panel.is-open .case-reveal-inner>:nth-child(3){animation-delay:.3s}
.motion-ready .case-panel.is-open .case-reveal-inner>:nth-child(4){animation-delay:.38s}
.motion-ready .case-panel.is-open .case-cover-photo img{animation:case-breathe 9s ease-out both;animation-play-state:paused}
.motion-ready .cases-in-view .case-panel.is-open .case-cover-photo img{animation-play-state:running}
.motion-ready .paused .case-panel .case-cover-photo img{animation:none}

/* Gallery: the desktop auto-drift moves in sub-pixel steps, which mandatory snapping keeps undoing */
@media(hover:hover) and (min-width:701px){.portfolio-track{scroll-snap-type:none}}

/* Navigation: sticks once you scroll, hides while reading down, returns on scroll up */
.motion-ready section[id]{scroll-margin-top:96px}
.site-nav.is-floating{position:fixed;top:12px;z-index:60;margin:0;background:#fffffff5;box-shadow:0 12px 32px #1a2b4a14;transition:translate .5s var(--ease-out),box-shadow .3s}
.site-nav.is-floating.is-tucked{translate:0 calc(-100% - 24px);box-shadow:none}
.site-nav nav>a:not(.btn){background:linear-gradient(currentColor,currentColor) 0 100%/0 1.5px no-repeat;padding-bottom:2px;transition:background-size .35s var(--ease-out),color .25s}
.site-nav nav>a:not(.btn):hover,.site-nav nav>a.is-current{background-size:100% 1.5px}
.site-nav nav>a.is-current{color:#316cf0}
@keyframes menu-item{from{opacity:0;translate:0 -8px}to{opacity:1;translate:0 0}}
.motion-ready .site-nav nav.open>*{animation:menu-item .45s var(--ease-out) backwards}
.motion-ready .site-nav nav.open>:nth-child(2){animation-delay:.04s}
.motion-ready .site-nav nav.open>:nth-child(3){animation-delay:.08s}
.motion-ready .site-nav nav.open>:nth-child(4){animation-delay:.12s}
.motion-ready .site-nav nav.open>:nth-child(5){animation-delay:.16s}
.motion-ready .site-nav nav.open>:nth-child(6){animation-delay:.2s}

/* Case-study exit: blue loading screen that expands from the click point */
.case-transition{position:fixed;inset:0;z-index:1000;display:grid;place-items:center;background:#316cf0;color:#fff;pointer-events:none}
.case-transition-copy{text-align:center;padding:24px}
.case-transition-copy span{display:block;font-size:14px;font-weight:500;opacity:.75;margin-bottom:10px}
.case-transition-copy strong{display:block;font-size:clamp(40px,6vw,84px);line-height:1;letter-spacing:-.04em;font-weight:600}
.case-transition-copy i{display:block;width:120px;height:3px;margin:28px auto 0;border-radius:3px;background:#ffffff33;overflow:hidden;position:relative}
.case-transition-copy i:after{content:'';position:absolute;inset:0;width:40%;border-radius:3px;background:#fff;animation:ru-loading 1.1s cubic-bezier(.65,0,.35,1) infinite}
@keyframes ru-loading{from{translate:-100% 0}to{translate:250% 0}}

/* Buttons: soft light sweep and a nudge of the calendar icon */
.btn{position:relative;overflow:hidden;isolation:isolate}
.btn:after{content:'';position:absolute;inset:0;z-index:-1;background:linear-gradient(105deg,transparent 30%,#ffffff40 50%,transparent 70%);translate:-120% 0;transition:translate .8s var(--ease-out)}
.btn svg{transition:transform .35s var(--ease-out)}
@media(hover:hover){
 .btn:hover:after{translate:120% 0}
 .btn:hover svg{transform:translateY(-2px) rotate(-6deg)}
 .play{transition:transform .35s var(--ease-out),box-shadow .35s}
 .video-preview>img{transition:transform .8s var(--ease-out)}
 .video-preview:hover>img{transform:scale(1.04)}
 .video-preview:hover .play{transform:translate(-50%,-50%) scale(1.1);box-shadow:0 0 0 10px #316cf026,0 6px 25px #0003}
}
.btn:active{transform:scale(.98)}

/* FAQ answers ease open where the browser supports it */
@supports (interpolate-size:allow-keywords){
 .motion-ready .faq{interpolate-size:allow-keywords}
 .motion-ready .faq details::details-content{height:0;overflow:clip;transition:height .45s var(--ease-out),content-visibility .45s allow-discrete}
 .motion-ready .faq details[open]::details-content{height:auto}
}
.faq summary:after{transition:transform .3s var(--ease-out)}
.faq details[open] summary:after{transform:rotate(180deg)}

@media(prefers-reduced-motion:reduce){
 .btn:after,.case-transition{display:none}
 .site-nav.is-floating{transition:none}
 .btn,.btn svg,.play,.video-preview>img{transition:none!important}
}

/* Suspend CSS effects as well as script-driven motion when the page cannot be seen. */
.motion-suspended *, .motion-suspended *:before, .motion-suspended *:after{animation-play-state:paused!important}

html:not(.motion-ready) .timeline-fill{display:none}
