/* =====================================================================
   HALDEN · motion.css · shared by every page
   One easing, four durations. Each kind of element has its own entrance:
   headlines rise word by word, line by line; images open inside their
   frames; hairlines draw; glass condenses; groups stagger. Everything once.
   ===================================================================== */
:root{
  --m-ease:cubic-bezier(.16,1,.3,1);
  --m-soft:cubic-bezier(.45,0,.2,1); /* even in and out, for moves that should be watched */
  --m-micro:180ms;--m-el:500ms;--m-reveal:1000ms;--m-orch:1500ms;
}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
.lenis.lenis-stopped{overflow:hidden}

/* headlines: each word in a mask, rising from below, one line at a time */
.mw{display:inline-block;overflow:hidden;vertical-align:top;padding:0 .08em .14em 0;margin:0 -.08em -.14em 0}
.mw>.mi{display:inline-block}
.motion [data-rv=head] .mi{transform:translate3d(0,112%,0);transition:transform var(--m-reveal) var(--m-ease)}
.motion [data-rv=head].on .mi{transform:none}

/* labels: a short, quiet fade */
.motion [data-rv=fade]{opacity:0;transform:translate3d(0,10px,0);transition:opacity var(--m-el) var(--m-ease),transform var(--m-el) var(--m-ease)}
/* body and blocks: a longer rise */
.motion [data-rv=rise]{opacity:0;transform:translate3d(0,32px,0);transition:opacity var(--m-reveal) var(--m-ease),transform var(--m-orch) var(--m-ease)}
.motion [data-rv=group]>*{opacity:0;transform:translate3d(0,40px,0);transition:opacity var(--m-reveal) var(--m-ease),transform var(--m-orch) var(--m-ease)}
.motion [data-rv].on,.motion [data-rv=group].on>*{opacity:1;transform:none}

/* cards: one at a time, rising and settling to full size from a little below */
.motion [data-rv=card]{opacity:0;transform:translate3d(0,64px,0) scale(.965);transform-origin:50% 100%;transition:opacity var(--m-reveal) var(--m-ease),transform 1700ms var(--m-ease)}

/* hairlines draw in from the left */
.motion [data-rv=line]{transform:scaleX(0);transform-origin:left center;transition:transform var(--m-orch) var(--m-ease)}
.motion [data-rv=line].on{transform:none}

/* images open inside a fixed frame: a cover wipes up while the picture settles */
[data-rv=frame]{position:relative;overflow:hidden}
[data-rv=frame] .zi{display:block;position:absolute;inset:0}
.motion [data-rv=frame] .zi{transform:scale(1.14);transition:transform var(--m-orch) var(--m-ease)}
.motion [data-rv=frame]::after{content:"";position:absolute;inset:0;z-index:2;background:var(--m-cover,#EEF1F6);transform-origin:50% 0;transition:transform var(--m-reveal) var(--m-ease) var(--fd,0ms)}
.motion [data-rv=frame].on .zi{transform:none}
.motion [data-rv=frame].on::after{transform:scaleY(0)}

/* case-page windows: each enters its own way (data-fx), so no two pictures in a row arrive alike */
.fx .view{position:relative;overflow:hidden}
.motion [data-rv=fx]{opacity:0;transform:translate3d(0,36px,0);transition:opacity var(--m-reveal) var(--m-ease),transform 1800ms var(--m-ease)}
/* wipe: the window slides in from the text's side and a cover draws back the same way */
.motion [data-fx=wipe]:not(.on){transform:translate3d(-32px,0,0)}
.motion [data-fx=wipe][data-from=r]:not(.on){transform:translate3d(32px,0,0)}
.motion [data-fx=wipe] .view::after{content:"";position:absolute;inset:0;z-index:2;background:var(--m-cover);transform-origin:100% 50%;transition:transform 1800ms var(--m-soft) 300ms}
.motion [data-fx=wipe][data-from=r] .view::after{transform-origin:0 50%}
.motion [data-fx=wipe].on .view::after{transform:scaleX(0)}
.motion [data-fx=wipe] .view img{transition:transform 2600ms var(--m-soft) 300ms}
.motion [data-fx=wipe]:not(.on) .view img{transform:translate3d(-5%,0,0) scale(1.1)}
.motion [data-fx=wipe][data-from=r]:not(.on) .view img{transform:translate3d(5%,0,0) scale(1.1)}
/* survey: the picture comes up through the crosshair grid, clearing along the hillside (motion.js draws it) */
.fx .m-cover{position:absolute;inset:0;z-index:2;width:100%;height:100%;display:block;pointer-events:none}
/* open: the picture opens from the middle and settles to its full width, so nothing ends up cropped */
.motion [data-fx=open] .view{background:var(--m-cover)}
.motion [data-fx=open] .view img{clip-path:inset(0 round 0);transition:clip-path 2200ms var(--m-soft) 200ms,opacity 1200ms var(--m-ease) 200ms,transform 2800ms var(--m-ease) 200ms}
.motion [data-fx=open]:not(.on) .view img{clip-path:inset(16% 14% round 8px);opacity:.4;transform:scale(1.06)}
/* lift: the window tips up from lying back and settles flat */
.fx[data-fx=lift]{perspective:1800px}
.motion [data-fx=lift]:not(.on){transform:none}
.motion [data-fx=lift] .win{transform-origin:50% 100%;transition:transform 2400ms var(--m-ease),box-shadow 2400ms var(--m-ease)}
.motion [data-fx=lift]:not(.on) .win{transform:rotateX(22deg) translate3d(0,56px,0) scale(.93);box-shadow:none}
.motion [data-fx=lift] .view img{transition:transform 2800ms var(--m-ease)}
.motion [data-fx=lift]:not(.on) .view img{transform:scale(1.1)}
/* phone: it rises, and the screen comes on once it has nearly landed */
.motion [data-rv=fx][data-fx=phone]{transition:opacity 1200ms var(--m-ease),transform 2400ms var(--m-ease)}
.motion [data-fx=phone]:not(.on){transform:translate3d(0,96px,0)}
.motion [data-fx=phone] .screen>:not(.island),.motion [data-fx=phone] .screen::after{transition:opacity 1600ms var(--m-soft) 1000ms,transform 2200ms var(--m-ease) 1000ms}
.motion [data-fx=phone] .screen{transition:background-color 1600ms var(--m-soft) 1000ms}
.motion [data-fx=phone]:not(.on) .screen{background:#050506}
.motion [data-fx=phone]:not(.on) .screen>:not(.island),.motion [data-fx=phone]:not(.on) .screen::after{opacity:0}
.motion [data-fx=phone]:not(.on) .screen img{transform:scale(1.025)}

/* work cards: the picture inside each card takes one of the entrances above once the card has risen (motion.js),
   then hands back to the quick hover */
.motion .case .fx[data-fx=wipe]{transition:transform 1800ms var(--m-ease)}
.case .fx.done .win{transition:transform .6s var(--m-ease),box-shadow .6s var(--m-ease)}
.case .fx.done .view img{transition:transform 1.2s var(--m-ease)}

/* glass condenses: fill and blur arrive together */
.motion [data-rv=glass]{transition:background var(--m-reveal) var(--m-ease),-webkit-backdrop-filter var(--m-reveal) var(--m-ease),backdrop-filter var(--m-reveal) var(--m-ease),border-color var(--m-reveal) var(--m-ease),box-shadow var(--m-orch) var(--m-ease),opacity var(--m-el) var(--m-ease),transform var(--m-orch) var(--m-ease)}
.motion [data-rv=glass]:not(.on){background:rgba(255,255,255,0)!important;-webkit-backdrop-filter:blur(0)!important;backdrop-filter:blur(0)!important;border-color:transparent!important;box-shadow:none!important;opacity:0;transform:translate3d(0,24px,0)}

/* the opening holds; the page rises over it through a paper wash */
.motion .pin{position:sticky;top:0;z-index:0}
.m-wash{position:relative;z-index:1;height:0;pointer-events:none;opacity:0}
.m-wash::before{content:"";position:absolute;left:0;right:0;bottom:0;height:clamp(120px,24vh,240px);background:linear-gradient(to bottom,rgba(255,255,255,0),rgba(255,255,255,.14) 30%,rgba(255,255,255,.55) 60%,rgba(255,255,255,.9) 85%,#fff)}
.risen{position:relative;z-index:1}

/* the nav leaves on the way down and comes back on the way up */
[data-nav]{transition:transform var(--m-el) var(--m-ease)}
[data-nav].hide{transform:translate3d(0,-100%,0)}
.motion [data-nav]{animation:m-nav var(--m-el) var(--m-ease) backwards}
@keyframes m-nav{from{opacity:0;transform:translate3d(0,-100%,0)}}

/* between pages the next one rises like a sheet */
@media (prefers-reduced-motion:no-preference){
  @view-transition{navigation:auto}
  [data-nav]{view-transition-name:nav}
  ::view-transition-old(root){animation:m-dim var(--m-reveal) var(--m-ease) both}
  ::view-transition-new(root){animation:m-rise var(--m-reveal) var(--m-ease) both}
}
@keyframes m-dim{to{opacity:.4}}
@keyframes m-rise{from{transform:translate3d(0,100vh,0)}}

.m-field{position:absolute;pointer-events:none;display:block}

@media (prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}
