/* Shared base for Vire Design concept demos */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img{display:block;max-width:100%}
a{color:inherit}
button,input,select,textarea{font:inherit;color:inherit}
h1,h2,h3,h4,p,figure{margin:0}
.sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.img-missing{opacity:0!important}
.skip{position:absolute;left:12px;top:-60px;z-index:300;padding:10px 14px;background:#fff;color:#000;border-radius:6px;text-decoration:none;font-weight:600}
.skip:focus{top:12px}
/* reveals */
.js [data-r]{opacity:0;transform:translateY(28px);transition:opacity 1.1s cubic-bezier(.2,.7,.1,1),transform 1.1s cubic-bezier(.2,.7,.1,1);transition-delay:var(--dl,0s)}
.js [data-r="fade"]{transform:none}
.js [data-r="img"]{opacity:1;transform:none;clip-path:inset(100% 0 0 0);transition:clip-path 1.4s cubic-bezier(.7,0,.2,1);transition-delay:var(--dl,0s)}
.js [data-r="img"] img{transform:scale(1.25);transition:transform 1.8s cubic-bezier(.2,.7,.1,1);transition-delay:var(--dl,0s)}
.js [data-r].in{opacity:1;transform:none;clip-path:inset(0 0 0 0)}
.js [data-r="img"].in img{transform:none}
.sl{display:block;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em}
.sl-i{display:block}
.js [data-split] .sl-i{transform:translateY(110%) rotate(2deg);transform-origin:0 0;transition:transform 1.2s cubic-bezier(.2,.75,.1,1);transition-delay:calc(var(--i) * .09s + var(--dl,0s))}
.js [data-split].in .sl-i{transform:none}
/* per-character reveal (opacity + transform only, so it stays smooth on phones) */
.cw{display:inline-block;white-space:nowrap}
.ch{display:inline-block}
.js [data-chars] .ch{opacity:0;transform:translateY(.42em);transition:opacity .9s cubic-bezier(.2,.7,.1,1),transform 1.1s cubic-bezier(.2,.75,.1,1);transition-delay:calc(var(--ci) * .018s + var(--dl,0s))}
.js [data-chars].in .ch{opacity:1;transform:none}
/* ambient video (poster/background stays underneath until the clip is actually playing) */
video[data-vid]{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity 1.6s cubic-bezier(.2,.7,.1,1);pointer-events:none}
video[data-vid].vid-on{opacity:1}
video[data-vid].vid-off{display:none}
/* velocity marquee */
.mq-js>*{animation:none!important;will-change:transform}
/* tilt glare */
[data-tilt]{transform-style:preserve-3d}
.glare{position:absolute;inset:0;pointer-events:none;z-index:3;border-radius:inherit;opacity:0;transition:opacity .5s;background:radial-gradient(circle at var(--gx,50%) var(--gy,50%),rgba(255,255,255,.38),rgba(255,255,255,0) 55%);mix-blend-mode:soft-light}
.tilting .glare{opacity:1}
/* cursor image trail */
.trail{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:0}
.trail img{position:absolute;width:clamp(150px,14vw,230px);aspect-ratio:4/5;object-fit:cover;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(var(--rot,0deg));border-radius:2px}
.trail img.go{animation:trail 1.5s cubic-bezier(.2,.7,.1,1) forwards}
@keyframes trail{0%{opacity:0;transform:translate(-50%,-50%) scale(.5) rotate(var(--rot,0deg));clip-path:inset(50% 0 50% 0)}18%{opacity:1;transform:translate(-50%,-50%) scale(1) rotate(var(--rot,0deg));clip-path:inset(0)}70%{opacity:1}100%{opacity:0;transform:translate(-50%,-62%) scale(.92) rotate(var(--rot,0deg));clip-path:inset(0)}}
/* loupe */
[data-loupe]{overflow:hidden;cursor:zoom-in}
[data-loupe] img{transition:transform .6s cubic-bezier(.2,.7,.1,1)}
[data-loupe].loupe-on img{transform:scale(2.1)!important}
/* ===== Page transitions =====
   Browsers with cross-document View Transitions get a native transition; pages can name shared elements
   (view-transition-name) so e.g. a card image grows into the next page's hero. Others fall back to the curtain. */
@view-transition{navigation:auto}
::view-transition-old(root){animation:vd-vt-out .45s cubic-bezier(.7,0,.2,1) both}
::view-transition-new(root){animation:vd-vt-in .7s cubic-bezier(.2,.7,.1,1) .1s both}
::view-transition-group(*){animation-duration:.8s;animation-timing-function:cubic-bezier(.7,0,.2,1)}
@keyframes vd-vt-out{to{opacity:0;transform:translateY(-2vh)}}
@keyframes vd-vt-in{from{opacity:0;transform:translateY(3vh)}}
@media (prefers-reduced-motion:reduce){@view-transition{navigation:none}}
.vd-pt{position:fixed;inset:0;z-index:2147483630;pointer-events:none;display:grid;place-items:center;background:var(--pt,var(--ink,#111));color:var(--pt-ink,var(--bg,#fff));transform:translateY(105%);border-radius:50% 50% 0 0/16vh 16vh 0 0;visibility:hidden}
.vd-pt__b{font-family:var(--pt-f,var(--serif,inherit));font-size:clamp(30px,5vw,72px);letter-spacing:-.02em;line-height:1;opacity:0;transform:translateY(40px)}
.pt-leave .vd-pt{visibility:visible;transform:none;border-radius:0;transition:transform .72s cubic-bezier(.76,0,.24,1),border-radius .72s cubic-bezier(.76,0,.24,1)}
.pt-leave .vd-pt__b{opacity:1;transform:none;transition:opacity .5s .28s,transform .7s cubic-bezier(.2,.7,.1,1) .22s}
.pt-arrive .vd-pt{visibility:visible;transform:none;border-radius:0;transition:none}
.pt-arrive .vd-pt__b{opacity:1;transform:none;transition:none}
.pt-arrive.pt-go .vd-pt{transform:translateY(-105%);border-radius:0 0 50% 50%/0 0 16vh 16vh;transition:transform 1s cubic-bezier(.76,0,.24,1) .2s,border-radius 1s cubic-bezier(.76,0,.24,1) .2s}
.pt-arrive.pt-go .vd-pt__b{opacity:0;transform:translateY(-40px);transition:opacity .4s .1s,transform .7s cubic-bezier(.7,0,.2,1)}
@media (prefers-reduced-motion:reduce){.vd-pt{display:none}}

/* ===== Cinematic openers (pinned; --pp 0→1 while pinned) ===== */
.op{position:relative;height:var(--op-h,250vh)}
.op__pin{position:sticky;top:0;height:100svh;overflow:hidden;isolation:isolate;
  --o1:clamp(0,calc((var(--pp,0) - .55) * 3.2),1);--fade:clamp(0,calc(1 - var(--pp,0) * 7),1);--q:clamp(0,calc(var(--pp,0) * 1.45),1)}
.op__media{position:absolute;inset:0;z-index:1;background-color:#111;background-size:cover;background-position:center;background-repeat:no-repeat}
.op__shade{position:absolute;inset:0;z-index:2;pointer-events:none;background:linear-gradient(180deg,rgba(0,0,0,.35),rgba(0,0,0,0) 30%,rgba(0,0,0,0) 45%,rgba(0,0,0,.75));opacity:var(--o1)}
.op__kick{position:absolute;z-index:4;left:0;right:0;top:clamp(96px,14vh,140px);text-align:center;opacity:var(--fade);transform:translateY(calc((1 - var(--fade)) * -20px))}
.op__cue{position:absolute;z-index:4;left:50%;bottom:clamp(24px,5vh,44px);transform:translateX(-50%);opacity:var(--fade);display:flex;flex-direction:column;align-items:center;gap:12px;font-size:11px;letter-spacing:.3em;text-transform:uppercase}
.op__cue::after{content:"";width:1px;height:54px;background:currentColor;transform-origin:top;animation:opcue 2.2s cubic-bezier(.7,0,.2,1) infinite}
@keyframes opcue{0%{transform:scaleY(0)}50%{transform:scaleY(1);transform-origin:top}50.1%{transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}
.op__c{position:absolute;z-index:5;inset:auto 0 0;padding-bottom:clamp(40px,8vh,90px);color:#fff}
/* A: film seen through giant letters that rush past the camera */
.xm .op__media{transform:scale(calc(1.32 - var(--pp,0) * .32))}
.xm__svg{position:absolute;inset:0;width:100%;height:100%;z-index:3;pointer-events:none;opacity:calc(1 - clamp(0,calc((var(--pp,0) - .5) * 4),1))}
.xm__fill{fill:var(--op-bg,#000)}
.xm__g{transform-box:view-box;transform-origin:50% 50%;transform:scale(calc(1 + var(--pp,0) * var(--pp,0) * var(--pp,0) * 34))}
.xm__g text{font-size:var(--xm-fs,15vw);font-family:var(--xm-ff,inherit);font-weight:var(--xm-fw,400);font-style:var(--xm-fst,normal);letter-spacing:var(--xm-ls,0);fill:#000}
/* B: a shaped window (arch, pill…) that opens to full screen while the words part */
.xw .op__media{clip-path:inset(calc(var(--t,22%) * (1 - var(--q))) calc(var(--s,32%) * (1 - var(--q))) calc(var(--b,22%) * (1 - var(--q))) calc(var(--s,32%) * (1 - var(--q))) round calc(var(--r1,0px) * (1 - var(--q))) calc(var(--r1,0px) * (1 - var(--q))) calc(var(--r2,0px) * (1 - var(--q))) calc(var(--r2,0px) * (1 - var(--q))));transform:rotate(calc(var(--rot,0deg) * (1 - var(--q))));will-change:clip-path}
.xw .op__media video{transform:scale(calc(1.35 - var(--q) * .35))}
.xw__w{position:absolute;inset:0;z-index:0;display:flex;justify-content:space-between;align-items:center;padding:0 2.4vw;white-space:nowrap;pointer-events:none}
.xw__w span{display:block;transition:none}
.xw__w span:first-child{transform:translateX(calc(var(--q) * -42vw))}
.xw__w span:last-child{transform:translateX(calc(var(--q) * 42vw))}
@media (max-width:760px){
  .xw .op__pin{--s:var(--sm,12%)}
  .xw__w{flex-direction:column;justify-content:space-between;padding:13svh 0 6svh}
  .xw__w span:first-child{transform:translateY(calc(var(--q) * -30vh))}
  .xw__w span:last-child{transform:translateY(calc(var(--q) * 30vh))}
}
.is-reduced .op,.is-embed .op{height:100svh}
.is-reduced .op__pin,.is-embed .op__pin{position:relative}
.is-embed .vd-badge{display:none}
/* Inside portfolio previews: show everything immediately, no scroll-triggered hiding */
.is-embed [data-r],.is-embed [data-r="img"],.is-embed [data-split] .sl-i,.is-embed [data-chars] .ch{opacity:1!important;transform:none!important;clip-path:none!important;transition:none!important}
.is-embed [data-r="img"] img{transform:none!important}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;transition-delay:0s!important;scroll-behavior:auto!important}
  .js [data-r],.js [data-r="img"],.js [data-split] .sl-i,.js [data-chars] .ch{opacity:1;transform:none;clip-path:none}
  video[data-vid]{display:none}
  .js [data-r="img"] img{transform:none}
}
