/* createco.ca home preview, scroll-linked (Kay 2026-10-20). Each scene has --p: its progress through the pinned part
   (0 = scene just reached the top, 1 = about to leave; negative while scrolling in). Every reveal below is a window on --p:
   it starts at --a, takes --d to finish, and holds after that. Only opacity and transform move, so it stays light. */
html:has(body[data-pv]){scroll-snap-type:none}
[data-pv] section,[data-pv] footer{scroll-snap-align:none}
[data-pv] h1,[data-pv] h2{font-weight:400;letter-spacing:-.03em}
[data-pv] h3{font-weight:500}
[data-pv] .hero h1{line-height:1}
@media (min-width:821px){[data-pv] .hero-v h1{max-width:none;margin-top:-1.55em}}

.sc{position:relative;z-index:1;--p:-1}
.sc-pin{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;padding:0 var(--g);display:flex;flex-direction:column;justify-content:center;box-sizing:border-box}
.dark .sc-pin{background:#101213;color:#f2f0ec}.cr .sc-pin{background:var(--cream,#f5f2ec);color:#111}.white .sc-pin{background:#fff;color:#111}
.sc .eb{color:inherit;font-weight:400;display:block;font-size:clamp(15px,1.1vw,18px);opacity:.7;margin-bottom:14px}
.sc h2{font-size:clamp(34px,4vw,64px);line-height:1.04;margin:0}
.sc .big{font-size:clamp(48px,7vw,120px);line-height:1;letter-spacing:-.035em;margin:0;font-weight:400}
.sc p{color:inherit;font-weight:300}

/* soft light drifting behind dark scenes (gradients only, no filter) */
.glow{position:absolute;border-radius:50%;pointer-events:none;will-change:transform}
.g1{width:80vw;height:110vh;left:5vw;top:-5vh;background:radial-gradient(closest-side,rgba(130,142,145,.32),rgba(130,142,145,0));animation:drift 20s ease-in-out infinite alternate}
.g2{width:60vw;height:80vh;left:40vw;top:30vh;background:radial-gradient(closest-side,rgba(180,160,130,.22),rgba(180,160,130,0));animation:drift 26s ease-in-out infinite alternate-reverse}
@keyframes drift{from{transform:translate(-6vw,-3vh)}to{transform:translate(6vw,5vh)}}
.sc-pin>div:not([class]),.chap-num,.chap-t,.how-tl,.how-l,.work-l,.desk,.sys-h,.sys-c{position:relative;z-index:1}

/* the two building blocks: words (one after another) and blocks (.rise) */
.w{display:inline-block;--t:clamp(0,(var(--p) - (var(--wa,0) + var(--k,0) * var(--ws,.015))) / var(--wd,.07),1);opacity:var(--t);transform:translateY(calc((1 - var(--t)) * .4em))}
.rise{--t:clamp(0,(var(--p) - var(--a,0)) / var(--d,.08),1);opacity:var(--t);transform:translateY(calc((1 - var(--t)) * 26px))}

/* 1. What We Do opening: question -> headline in its place -> headline steps up, the list and summary come in */
.intro .sc-pin{align-items:center;text-align:center}
.intro-q,.intro-h{position:absolute;left:var(--g);right:var(--g);top:50%;margin:0;z-index:1}
.intro-q{font-size:clamp(48px,7vw,120px);line-height:1;letter-spacing:-.035em;--wa:-.28;--ws:.02;--wd:.08;
  --o:clamp(0,(var(--p) - .17) / .06,1);opacity:calc(1 - var(--o));transform:translateY(calc(-50% - var(--o) * 60px))}
.intro-h{--wa:.24;--ws:.013;--wd:.06;--m:clamp(0,(var(--p) - .42) / .1,1);transform-origin:50% 0;
  transform:translateY(calc(-50% - var(--m) * 30vh)) scale(calc(1 - var(--m) * .38))}
.intro-h .eb{font-size:clamp(18px,1.5vw,24px);opacity:calc(clamp(0,(var(--p) - .24) / .06,1) * .75)}
.intro-h h2{font-size:clamp(48px,7vw,120px);line-height:1;letter-spacing:-.035em}
.intro-b{position:absolute;left:var(--g);right:var(--g);top:34vh;bottom:6vh;display:flex;flex-direction:column;align-items:center;z-index:1}
.intro-l{list-style:none;margin:0;padding:0;width:min(1200px,100%);text-align:left}
.intro-l li{display:flex;justify-content:space-between;align-items:baseline;gap:24px;padding:clamp(12px,1.8vh,20px) 0;border-bottom:1px solid rgba(255,255,255,.16);
  --t:clamp(0,(var(--p) - (.52 + var(--k) * .045)) / .06,1);opacity:var(--t);transform:translateY(calc((1 - var(--t)) * 26px))}
.intro-l span{font-size:clamp(17px,1.4vw,23px);text-transform:uppercase;letter-spacing:.01em}.intro-l b{font-weight:400;opacity:.45;margin-right:18px;font-size:13px}
.intro-l em{font-style:normal;font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#c9b79c;text-align:right}
.intro-s{max-width:44em;font-size:clamp(17px,1.4vw,22px);line-height:1.45;margin:4vh 0 0;opacity:clamp(0,(var(--p) - .78) / .06,1)}

/* 2. chapters: --pos runs 0..4 through the five chapters with a hold on each; the photo melts into the page colour */
.chap .sc-pin{background:#f6f5f2;color:#111;transition:background-color .8s,color .5s}
.chap[data-step="1"] .sc-pin{background:#efeae1}.chap[data-step="2"] .sc-pin{background:#141414;color:#f2f0ec}.chap[data-step="3"] .sc-pin{background:#fff}.chap[data-step="4"] .sc-pin{background:#f3efe7}
.chap-bg{position:absolute;inset:0;z-index:0;-webkit-mask-image:linear-gradient(to right,transparent 30%,rgba(0,0,0,.3) 50%,#000 80%);mask-image:linear-gradient(to right,transparent 30%,rgba(0,0,0,.3) 50%,#000 80%)}
.chap-bg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;--d:max(var(--pos) - var(--k),var(--k) - var(--pos));opacity:clamp(0,(.6 - var(--d)) / .3,1)}
.chap-num{height:clamp(80px,9vw,160px);overflow:hidden;margin-bottom:24px}
.chap-num div{display:flex;flex-direction:column;transform:translateY(calc(var(--pos) * -20%))}
.chap-num span{height:clamp(80px,9vw,160px);font-size:clamp(80px,9vw,160px);line-height:1;font-weight:300;letter-spacing:-.04em}
.chap-t{width:min(40vw,620px);min-height:15em}
.chap-c{position:absolute;inset:0 0 auto 0;--d:max(var(--pos) - var(--k),var(--k) - var(--pos));--t:clamp(0,(.42 - var(--d)) / .14,1);opacity:var(--t);transform:translateY(calc((var(--k) - var(--pos)) * 40px));pointer-events:none}
.chap-c h3{font-size:clamp(32px,3.4vw,56px);line-height:1.06;font-weight:400;margin:0}
.chap-c .w{opacity:1;transform:none}
.chap-c p{font-size:clamp(16px,1.2vw,19px);line-height:1.5;margin:20px 0 0}.chap-c .dl{font-size:13px;margin-top:14px;opacity:.6}
.chap-m{display:none}
.chap-nav{position:absolute;left:var(--g);right:var(--g);bottom:32px;display:flex;gap:26px;flex-wrap:wrap;z-index:1}
.chap-nav button{background:none;border:0;padding:0;color:inherit;font:inherit;font-size:13px;opacity:.45;cursor:pointer;transition:opacity .3s}
.chap-nav button b{font-weight:400;margin-right:8px}.chap-nav button:hover,.chap-nav button:focus-visible{opacity:1}
.chap[data-step="0"] .chap-nav button:nth-child(1),.chap[data-step="1"] .chap-nav button:nth-child(2),.chap[data-step="2"] .chap-nav button:nth-child(3),.chap[data-step="3"] .chap-nav button:nth-child(4),.chap[data-step="4"] .chap-nav button:nth-child(5){opacity:1}

/* 3. quick question, then the answer under it */
.ask .sc-pin,.end .sc-pin{align-items:flex-start}
.ask h2{--wa:-.42;--ws:.03;--wd:.1}
.ask-a{font-size:clamp(24px,2.6vw,42px);line-height:1.25;letter-spacing:-.02em;margin:5vh 0 0;font-weight:300;--wa:.32;--ws:.02;--wd:.07}

/* 4. how it works: the question, then the line (drawn by the script from --p) */
.how .sc-pin{display:block;padding:0}
.how-q{position:absolute;left:var(--g);right:var(--g);top:50%;margin:0;text-align:center;font-size:clamp(48px,7vw,120px);line-height:1;letter-spacing:-.035em;transform:translateY(-50%);--wa:-.45;--ws:.03;--wd:.1;
  transition:top .9s cubic-bezier(.16,1,.3,1),font-size .9s cubic-bezier(.16,1,.3,1),transform .9s cubic-bezier(.16,1,.3,1)}
.how.asked .how-q{top:13vh;transform:none;font-size:clamp(32px,3.6vw,60px);text-align:left;right:auto}
.how-line{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;z-index:1}
.how-line path{fill:none;stroke:#111;stroke-width:1.2;stroke-linecap:round;stroke-dasharray:1;stroke-dashoffset:1}
.how-line .ah{fill:none;stroke:#111;stroke-width:1.4;stroke-linejoin:round;stroke-linecap:round;opacity:0;transition:opacity .3s}.how.arrived .how-line .ah{opacity:1}
.how-tl{position:absolute;left:var(--g);top:29vh;bottom:9vh;width:min(44vw,640px);opacity:0;transition:opacity .5s}.how.asked .how-tl{opacity:1}
.how-lab{position:absolute;left:44px;top:-34px;font-size:15px;opacity:.6}
.how-tl ol{list-style:none;margin:0;padding:0 0 0 44px;height:100%;display:grid;grid-template-rows:repeat(4,1fr)}
.how-tl li{position:relative;display:flex;flex-direction:column;gap:4px;opacity:0;transform:translateX(-14px);transition:opacity .45s,transform .55s cubic-bezier(.16,1,.3,1)}
.how-tl li::before{content:"";position:absolute;left:-44px;top:1.6em;width:13px;height:13px;border-radius:50%;background:#111;transform:scale(0);transition:transform .4s cubic-bezier(.16,1,.3,1)}
.how-tl li.on{opacity:1;transform:none}.how-tl li.on::before{transform:scale(1)}
.how-tl li em{font-style:normal;font-size:13px;opacity:.5;letter-spacing:.04em}
.how-tl li b{font-size:clamp(26px,2.4vw,40px);font-weight:400;letter-spacing:-.02em}.how-tl li span{font-size:15px;color:#666}
.how-l{position:absolute;right:var(--g);top:29vh;width:min(36vw,520px);opacity:0;transition:opacity .6s}
.how.asked .how-l{opacity:.35}.how.arrived .how-l{opacity:1}
.how-l h2{font-size:clamp(34px,3.6vw,60px)}.how-l p{font-size:16px;line-height:1.5;color:#333;margin:24px 0 20px}

/* 6. work: the question, then the heading and a desk of cards sliding in from the right as you scroll.
   Cards: white frame, off-white inside (Kay 2026-10-20: "all off-white for now, I'll redo the mockups later") */
.work .sc-pin{display:grid;grid-template-columns:minmax(0,.48fr) minmax(0,1.52fr);align-items:center;gap:40px;background:#18191b}
.work-q{position:absolute;left:var(--g);right:var(--g);top:50%;margin:0;text-align:center;font-size:clamp(48px,7vw,120px);line-height:1;letter-spacing:-.035em;z-index:2;--wa:-.45;--ws:.03;--wd:.1;
  --o:clamp(0,(var(--p) - .18) / .06,1);opacity:calc(1 - var(--o));transform:translateY(calc(-50% - var(--o) * 70px))}
.work-l{--wa:.25;--ws:.012;--wd:.06}.work-l .eb{opacity:calc(clamp(0,(var(--p) - .24) / .06,1) * .7)}
.work-l .rise{--a:.36}.work-l p{font-size:16px;margin:24px 0 16px;color:#c9c6c0}
.work-btns{display:flex;gap:10px;align-items:center}
.pill.shuffle{border:0;cursor:pointer;font:inherit;background:#f2f0ec!important;color:#111!important}
.pill.ghost{background:transparent!important;color:#f2f0ec!important;box-shadow:inset 0 0 0 1px #f2f0ec}
.desk{position:relative;height:min(80vh,800px)}
.desk .pc{position:absolute;width:calc(min(13vw,210px) * var(--w,1));background:#fff;padding:10px 10px 0;border-radius:3px;box-shadow:0 14px 34px rgba(0,0,0,.45);color:#111;text-decoration:none;
  --t:clamp(0,(var(--p) - (.3 + var(--k) * .035)) / .14,1);opacity:clamp(0,var(--t) * 3,1);
  transform:translate(calc((1 - var(--t)) * 42vw),calc((1 - var(--t)) * -6vh)) rotate(calc(var(--r) + (1 - var(--t)) * 10deg))}
.pc-im{display:block;aspect-ratio:4/3;overflow:hidden;border-radius:2px;background:#f4f1ea}
.pc-im img{display:block;width:100%;height:100%;object-fit:cover}
.pc.sm .pc-im img{object-fit:contain;padding:14%;box-sizing:border-box}
.pc-b{display:flex;flex-direction:column;gap:2px;padding:10px 2px 12px;font-size:clamp(11px,calc(12px * var(--w,1)),15px)}.pc-b b{font-weight:500}.pc-b em{font-style:normal;opacity:.6}
.pc-go{max-height:0;overflow:hidden;opacity:0;font-size:12px;transition:max-height .35s,opacity .3s,margin .35s}
.work.done .desk .pc{transition:transform .45s cubic-bezier(.16,1,.3,1),box-shadow .35s,filter .35s}
.work.done .desk .pc:hover,.work.done .desk .pc:focus-visible{z-index:30!important;transform:translateY(-12px) rotate(0deg) scale(1.2);box-shadow:0 30px 70px rgba(0,0,0,.6)}
.work.done .desk:has(.pc:hover) .pc:not(:hover){filter:brightness(.7)}
.pc:hover .pc-go,.pc:focus-visible .pc-go{max-height:22px;opacity:1;margin-top:6px}
.desk.back .pc{animation:dealin .9s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--k) * 60ms)}
@keyframes dealin{from{opacity:0;transform:translateX(40vw) rotate(calc(var(--r) + 8deg))}to{opacity:1;transform:rotate(var(--r))}}
.desk-hint{position:absolute;right:0;bottom:-34px;margin:0;font-size:13px;color:#9a978f;opacity:clamp(0,(var(--p) - .8) / .06,1)}

/* 7. web systems */
.sys2 .sc-pin{gap:56px}
.sys2 h2{--wa:-.6;--ws:.03;--wd:.12}
.sys-h{display:flex;justify-content:space-between;align-items:flex-end;gap:40px}.sys-h .rise{--a:-.35}
.sys-h p{max-width:300px;font-size:15px;color:#333;margin:0 0 16px}
.sys-c{display:grid;grid-template-columns:repeat(5,1fr)}
.sys-c>div{border-left:1px solid var(--line);padding:0 24px 8px 18px;display:flex;flex-direction:column;align-items:flex-start;--a:calc(-.25 + (var(--k) - 4) * .09);--d:.12}
.sys-c .st{font-size:13px;font-weight:600;margin-bottom:14px}.sys-c .soon .st{color:#999}
.sys-c h3{font-size:clamp(18px,1.5vw,24px);margin:0 0 10px}.sys-c p{font-size:14px;line-height:1.45;color:#555;margin:0 0 14px}

/* 8. closing: the question, then the buttons */
.end h2{--wa:-.5;--ws:.04;--wd:.12}
.end-b{display:flex;gap:24px;align-items:center;margin-top:40px;--a:.3;--d:.1}
.pill.lt{background:#f2f0ec!important;color:#111!important}.end .mail{color:#f2f0ec}

/* static fallback, switched off (Kay 2026-10-21: the scroll story shows even with Reduce Motion on, like other sites) */
@media (prefers-reduced-motion:reduce) and (max-width:0px){
  .sc{height:auto!important}.sc-pin{position:relative;height:auto;min-height:0;padding:96px var(--g)}
  .w,.rise,.intro-l li,.intro-s,.chap-c,.desk .pc,.intro-q,.work-q,.intro-h .eb,.work-l .eb,.desk-hint{opacity:1!important;transform:none!important}
  .intro-q,.intro-h,.intro-b,.work-q,.how-q,.how-tl,.how-l{position:static;transform:none!important}.intro-q,.work-q,.how-q{margin-bottom:40px;text-align:left;font-size:clamp(40px,11vw,64px)}
  .intro-h{margin-bottom:40px}.intro-h h2{font-size:clamp(40px,11vw,64px)}.intro-l li{flex-direction:column;gap:6px}.intro-l em{text-align:left}
  .chap-bg,.chap-num,.chap-nav,.how-line{display:none}.chap-t{width:auto;min-height:0}.chap-c{position:static;margin-bottom:56px;pointer-events:auto}
  .chap-m{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:8px;margin-bottom:24px}
  .how .sc-pin{padding:96px var(--g)}.how-tl,.how-l{opacity:1!important;width:auto}.how-tl{margin-bottom:56px}.how-lab{position:static;display:block;margin-bottom:24px}
  .how-tl ol{display:flex;flex-direction:column;gap:36px}.how-tl li{opacity:1;transform:none}.how-tl li::before{transform:scale(1)}
  .work .sc-pin{display:block}.desk{height:auto;display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:32px}
  .desk .pc{position:relative;left:auto!important;top:auto!important;width:auto}.pc-go{max-height:22px;opacity:1;margin-top:6px}.desk-hint{position:static;grid-column:1/-1}
  .sys-h{flex-direction:column;align-items:flex-start}.sys-c{grid-template-columns:1fr 1fr;row-gap:32px}
}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.glow{animation:none}}

/* desk back on the light grey it had before (Kay 2026-10-20: "the black is odd, the earlier colour was better") */
.work .sc-pin{background:#f4f4f5;color:#111}
.work-l p{color:#444}.desk-hint{color:#888}
.pill.shuffle{background:#111!important;color:#fff!important}
.pill.ghost{color:#111!important;box-shadow:inset 0 0 0 1px #111}
.desk .pc{box-shadow:0 10px 26px rgba(0,0,0,.14)}
.work.done .desk .pc:hover,.work.done .desk .pc:focus-visible{box-shadow:0 28px 56px rgba(0,0,0,.24)}
.work.done .desk:has(.pc:hover) .pc:not(:hover){filter:brightness(.9) saturate(.85)}
.work .sc-pin{grid-template-columns:minmax(0,.62fr) minmax(0,1.38fr)}

/* How it works, fully scrubbed (Kay: "atmospherik changes with every bit of scroll and stops when the scroll stops") */
.how-q,.how.asked .how-q{position:absolute;left:var(--g);right:auto;top:13vh;text-align:left;font-size:clamp(48px,7vw,120px);transform-origin:0 0;transition:none;
  --m:clamp(0,(var(--p) - .05) / .1,1);transform:translate(calc((1 - var(--m)) * var(--qx,0px)),calc((1 - var(--m)) * var(--qy,0px))) scale(calc(1 - var(--m) * .5))}
.how-tl,.how.asked .how-tl{transition:none;opacity:clamp(0,(var(--p) - .1) / .06,1)}
.how-tl li,.how-tl li.on{transition:none;--t:clamp(0,(var(--L,0) - var(--th,0)) / .05,1);opacity:var(--t);transform:translateX(calc((1 - var(--t)) * -14px))}
.how-tl li::before,.how-tl li.on::before{transition:none;transform:scale(var(--t))}
.how-l,.how.asked .how-l,.how.arrived .how-l{transition:none;opacity:calc(clamp(0,(var(--p) - .1) / .06,1) * (.35 + .65 * clamp(0,(var(--L,0) - .95) / .05,1)))}
.how-line .ah,.how.arrived .how-line .ah{transition:none;opacity:clamp(0,(var(--L,0) - .97) / .03,1)}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.how-q{position:static;transform:none!important}.how-tl li{opacity:1!important;transform:none!important}.how-tl li::before{transform:scale(1)!important}.how-l{opacity:1!important}}
/* quick question words slide in from the side instead of rising (Kay 2026-10-20) */
.ask .w{transform:translateX(calc((1 - var(--t)) * 1.2em))}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.ask .w{transform:none!important}}

/* sideways track (Kay 2026-10-20): scenes side by side; the script moves the track and plays each scene */
.track-run{position:relative;z-index:1}
.track-pin{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden}
.track{display:flex;height:100%;will-change:transform}
.track .sc{flex:none;width:100vw;height:100%!important}
.track .sc-pin{position:relative;height:100%}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.track-pin{position:relative;height:auto;overflow:visible}.track{display:block;transform:none!important}.track .sc{width:auto;height:auto!important}}
/* after the arrow: everything else fades and the studio text comes to the centre, larger */
.how{--f:clamp(0,(var(--p) - .78) / .1,1)}
.how-l,.how.asked .how-l,.how.arrived .how-l{transform:translate(calc(var(--f) * var(--fx,0px)),calc(var(--f) * var(--fy,0px))) scale(calc(1 + var(--f) * .3));
  opacity:max(calc(clamp(0,(var(--p) - .1) / .06,1) * (.35 + .65 * clamp(0,(var(--L,0) - .95) / .05,1))),var(--f))}
.how-q,.how-tl,.how-line{--fade:calc(1 - var(--f))}
.how-tl,.how.asked .how-tl{opacity:calc(clamp(0,(var(--p) - .1) / .06,1) * (1 - var(--f)))}
.how-line{opacity:calc(1 - var(--f))}
.how-q{opacity:calc(1 - var(--f))}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.how-l{transform:none!important;opacity:1!important}.how-tl,.how-q{opacity:1!important}}

/* cards land at their own random moment (Kay: "dealt too much in order") */
.desk .pc{--t:clamp(0,(var(--p) - var(--a,.3)) / .16,1)}
/* no beige anywhere (Kay: "that's beige, not off-white"): neutral off-white and cool greys */
.pc-im{background:#f5f5f3}
.cr .sc-pin{background:#f4f4f2}
.chap .sc-pin{background:#f5f5f4}.chap[data-step="1"] .sc-pin{background:#eef0f1}.chap[data-step="3"] .sc-pin{background:#fff}.chap[data-step="4"] .sc-pin{background:#f2f3f4}
.g2{background:radial-gradient(closest-side,rgba(150,156,160,.2),rgba(150,156,160,0))}
.intro-l em{color:#b9bfc3}
/* scenes now lie on top of each other in the pinned frame; the script moves each one in or out its own way */
.track{display:block;position:relative;transform:none!important}
.track .sc{position:absolute;inset:0;width:100%;will-change:transform,opacity}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.track .sc{position:relative;inset:auto}}
/* What We Do list sits lower, headline steps up less (Kay: "the list is too high") */
.intro-b{top:42vh}
.intro-h{transform:translateY(calc(-50% - var(--m) * 25vh)) scale(calc(1 - var(--m) * .38))}
.track-pin{background:#101213}

/* words start only once a scene has fully arrived (Kay: "the quick question lost its scroll effect" - it finished while sliding in) */
.ask h2{--wa:.03;--ws:.035;--wd:.1}
.ask-a{--wa:.55;--ws:.02;--wd:.07}
.how-q{--wa:-.15;--ws:.02;--wd:.08}
.work-q{--wa:.02;--ws:.035;--wd:.1;--o:clamp(0,(var(--p) - .26) / .06,1)}
.work-l{--wa:.32}.work-l .eb{opacity:calc(clamp(0,(var(--p) - .32) / .06,1) * .7)}.work-l .rise{--a:.44}
.desk-hint{opacity:clamp(0,(var(--p) - .84) / .06,1)}
.sys2 h2{--wa:.02;--ws:.035;--wd:.1}.sys-h .rise{--a:.2}
.sys-c>div{--a:calc(.28 + (var(--k) - 4) * .08)}
.end h2{--wa:.02;--ws:.05;--wd:.12}.end-b{--a:.5}
/* questions come up out of a blur again, tied to the scroll (Kay: "like before, out of a blur") - only the big question lines, to stay light */
.intro-q .w,.ask h2 .w,.ask-a .w,.how-q .w,.work-q .w,.end h2 .w,.intro-h h2 .w{filter:blur(calc((1 - var(--t)) * 10px))}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.w{filter:none!important}}

/* How it works ending v2 (Kay 2026-10-20): at the arrow only the heading shows; then the whole scene pans left (no scaling)
   until the heading is in the middle, and the small text and button come up under it as you scroll */
.how-cam{position:absolute;inset:0;transform:translateX(calc(var(--f,0) * -1 * var(--panx,0px)));will-change:transform}
.how-l,.how.asked .how-l,.how.arrived .how-l{transform:none;opacity:max(calc(clamp(0,(var(--p) - .1) / .06,1) * (.35 + .65 * clamp(0,(var(--L,0) - .95) / .05,1))),var(--f))}
.how-tl,.how.asked .how-tl{opacity:clamp(0,(var(--p) - .1) / .06,1)}
.how-line,.how-q{opacity:1}
.how-l p,.how-l .pill{--t:clamp(0,(var(--p) - .84) / .07,1);opacity:var(--t);transform:translateY(calc((1 - var(--t)) * 20px))}
.how-l .pill{display:inline-block}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.how-cam{position:static;transform:none!important}.how-l p,.how-l .pill{opacity:1!important;transform:none!important}}
/* heading arrives and holds first; only then, with more scroll, the text under it (Kay 2026-10-20) */
.how{--f:clamp(0,(var(--p) - .73) / .08,1)}
.how-l p,.how-l .pill{--t:clamp(0,(var(--p) - .87) / .06,1)}
/* shuffle: blown up and away; the new set floats down */
.desk.back .pc{animation:floatin 1.2s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--k) * 70ms)}
@keyframes floatin{from{opacity:0;transform:translateY(-70vh) rotate(calc(var(--r) - 25deg))}60%{opacity:1}to{opacity:1;transform:rotate(var(--r))}}
/* the new set is blown in from the right (Kay 2026-10-20) */
.desk.back .pc{animation:blowin 1.3s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--k) * 70ms)}
@keyframes blowin{from{opacity:0;transform:translate(70vw,-12vh) rotate(calc(var(--r) + 60deg))}50%{opacity:1}to{opacity:1;transform:rotate(var(--r))}}

/* closing: the question on the left, the contact form drifts in on the right as you scroll (Kay 2026-10-20: one page, no separate contact page) */
.end .sc-pin{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.8fr);align-items:center;gap:6vw}
.end-l{position:relative;z-index:1}
.end-f{position:relative;z-index:1;display:flex;flex-direction:column;gap:18px;max-width:520px;
  --t:clamp(0,(var(--p) - .32) / .2,1);opacity:var(--t);transform:translateX(calc((1 - var(--t)) * 14vw))}
.end-f label{display:flex;flex-direction:column;gap:8px;font-size:14px;color:#c9c6c0}
.end-f input,.end-f textarea{font:inherit;font-size:16px;color:#f2f0ec;background:transparent;border:0;border-bottom:1px solid rgba(255,255,255,.28);padding:8px 0;border-radius:0;outline:none;resize:vertical}
.end-f input:focus,.end-f textarea:focus{border-bottom-color:#f2f0ec}
.end-send{display:flex;gap:24px;align-items:center;margin-top:8px}.end-send .pill{border:0;cursor:pointer;font:inherit}
.end-msg{font-size:18px;line-height:1.4;color:#f2f0ec;margin:0}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.end .sc-pin{display:block}.end-f{opacity:1!important;transform:none!important;margin-top:48px}}
/* footer logo sits on the very bottom, running a little off the edge (Kay 2026-10-20) */
[data-pv] .ft-big{margin-bottom:0}

/* "One studio" ending, slower (Kay 2026-10-20): pan to centre -> the whole scene zooms in around the heading -> text -> button -> hold */
.how{--f:clamp(0,(var(--p) - .6) / .08,1);--z:clamp(0,(var(--p) - .7) / .09,1)}
.how-cam{transform-origin:var(--ox,50%) var(--oy,50%);transform:translateX(calc(var(--f) * -1 * var(--panx,0px))) scale(calc(1 + var(--z) * .22))}
.how-l p{--t:clamp(0,(var(--p) - .8) / .07,1)}
.how-l .pill{--t:clamp(0,(var(--p) - .88) / .05,1)}
/* the pan also brings the studio block to the vertical middle */
.how-cam{transform:translate(calc(var(--f) * -1 * var(--panx,0px)),calc(var(--f) * var(--pany,0px))) scale(calc(1 + var(--z) * .22))}

/* a card opened in place (Kay 2026-10-20): grows from where it lay into a large panel; the page waits underneath */
.ov{position:fixed;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;background:rgba(16,18,19,0);pointer-events:none;transition:background .5s}
.ov.on{background:rgba(16,18,19,.55);pointer-events:auto}
.ov-card{position:relative;width:90vw;height:88vh;background:#fff;border-radius:6px;overflow:hidden;box-shadow:0 40px 100px rgba(0,0,0,.35);opacity:0;
  transition:transform .55s cubic-bezier(.16,1,.3,1),opacity .35s}
.ov-x{position:absolute;top:16px;right:16px;z-index:2;background:#111;color:#fff;border:0;border-radius:999px;padding:9px 16px;font:inherit;font-size:13px;cursor:pointer}
.ov-body,.ov-body iframe{width:100%;height:100%;border:0;display:block}
.ov-info{height:100%;display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);align-items:center;gap:5vw;padding:6vh 5vw;box-sizing:border-box}
.ov-info img{width:100%;max-height:76vh;object-fit:contain;background:#f5f5f3;border-radius:4px}
.ov-info h3{font-size:clamp(28px,3vw,48px);font-weight:400;margin:0}.ov-info .ov-k{color:#777;margin:8px 0 20px}.ov-info p{font-size:16px;line-height:1.55;color:#333;max-width:34em}
.ov-info .pill{display:inline-block;margin-top:12px}
.desk .pc{cursor:pointer}
@media (max-width:820px){.ov-card{width:100vw;height:100svh;border-radius:0}.ov-info{grid-template-columns:1fr;overflow:auto}}
/* case studies: a small tag on the card; opened, they fill the whole screen */
.pc-im{position:relative}
.pc-tag{position:absolute;left:8px;top:8px;background:#111;color:#fff;font-style:normal;font-size:11px;letter-spacing:.02em;padding:4px 8px;border-radius:999px;display:none}
.pc.case .pc-tag{display:block}
.ov-card.full{width:100vw;height:100vh;height:100svh;border-radius:0}

/* web systems: photos laid under the scene (Kay 2026-10-20) - paying on a phone, then booking on a phone; white wash keeps the text clear */
.sys-bg{position:absolute;inset:0;z-index:0}
.sys-bg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.sys-bg img+img{opacity:clamp(0,(var(--p) - .45) / .25,1)}
.sys-bg::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(255,255,255,.94) 0%,rgba(255,255,255,.86) 42%,rgba(255,255,255,.55) 100%),linear-gradient(0deg,rgba(255,255,255,.85) 0%,rgba(255,255,255,0) 55%)}
.sys2 .sc-pin>*:not(.sys-bg){position:relative;z-index:1}
.sys-c>div{background:rgba(255,255,255,.6);backdrop-filter:blur(2px)}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.sys-bg img+img{opacity:0}}
.sys-bg::after{background:linear-gradient(90deg,rgba(255,255,255,.93) 0%,rgba(255,255,255,.84) 45%,rgba(255,255,255,.7) 100%),linear-gradient(0deg,rgba(255,255,255,.85) 0%,rgba(255,255,255,0) 55%)}
/* "Want to see a few?" stays a full scroll after it is complete before giving way (Kay 2026-10-20) */
.work-q{--o:clamp(0,(var(--p) - .45) / .06,1)}
.work-l{--wa:.5}.work-l .eb{opacity:calc(clamp(0,(var(--p) - .5) / .05,1) * .7)}.work-l .rise{--a:.6}
.desk-hint{opacity:clamp(0,(var(--p) - .9) / .05,1)}
/* no white boxes behind the system columns (Kay: "awkward") - the wash over the photo is enough */
.sys-c>div{background:none;backdrop-filter:none}

/* web systems v2 (Kay 2026-10-20: "looks unfinished"): words and list on the left, the booking photo clear on the right half */
.sys2 .sc-pin{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.9fr);gap:0;padding:0;align-items:stretch}
.sys-bg{display:none}
.sys-l{padding:96px var(--g) 48px;display:flex;flex-direction:column;justify-content:center;gap:0}
.sys-l h2{--wa:.02;--ws:.035;--wd:.1}
.sys-intro{--a:.18;margin:20px 0 28px}.sys-intro p{max-width:30em;font-size:16px;color:#444;margin:0 0 16px}
.sys-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--line);max-width:620px}
.sys-list li{display:grid;grid-template-columns:120px 1fr;align-items:baseline;column-gap:20px;padding:14px 0;border-bottom:1px solid var(--line);--a:calc(.3 + var(--k) * .07);--d:.1}
.sys-list .st{font-size:12px;color:#999;letter-spacing:.02em}.sys-list li.live .st{color:#111;font-weight:600}
.sys-list b{font-size:clamp(18px,1.5vw,22px);font-weight:400}.sys-list li:not(.live) b{color:#888}
.sys-list li.live p,.sys-list li.live .pill{grid-column:2}.sys-list li.live p{font-size:14px;color:#555;margin:6px 0 10px}.sys-list li.live .pill{justify-self:start}
.sys-pic{position:relative;overflow:hidden}
.sys-pic img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:62% 50%;transform:scale(calc(1.12 - clamp(0,var(--p),1) * .12))}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.sys2 .sc-pin{display:block}.sys-l{padding:96px var(--g) 40px}.sys-pic{height:60vh}.sys-pic img{transform:none}.sys-list li{grid-template-columns:1fr}.sys-list li.live p,.sys-list li.live .pill{grid-column:1}}
.sys-pic img{object-position:88% 45%}
/* "One studio" zooms in further (Kay 2026-10-20: "could be bigger") */
.how-cam{transform:translate(calc(var(--f) * -1 * var(--panx,0px)),calc(var(--f) * var(--pany,0px))) scale(calc(1 + var(--z) * .42))}

/* web systems opens on the photo (Kay 2026-10-20: "systems comes out of nowhere - explain it first, then move on"):
   the booking photo fills the screen and drifts (parallax) while the sentence explains; then it folds into the right half */
.sys2{--c:clamp(0,(var(--p) - .42) / .14,1)}
.sys-pic{position:absolute;inset:0;z-index:0;clip-path:inset(0 0 0 calc(var(--c) * 52%))}
.sys-pic img{transform:translateY(calc((.5 - clamp(0,var(--p),1)) * 8vh)) scale(1.14);object-position:70% 45%}
.sys-pic::after{content:"";position:absolute;inset:0;background:#0d0f10;opacity:calc(.55 * (1 - var(--c)))}
.sys-lead{position:absolute;left:var(--g);top:50%;transform:translateY(calc(-50% - var(--c) * 40px));z-index:2;color:#fff;max-width:min(60vw,900px);opacity:calc(1 - var(--c) * 1.6)}
.sys-lead .eb{color:#fff;opacity:.75}
.sys-lead p{font-size:clamp(30px,3.6vw,58px);line-height:1.12;letter-spacing:-.025em;font-weight:300;margin:0;--wa:.02;--ws:.012;--wd:.06}
.sys-lead .w{filter:blur(calc((1 - var(--t)) * 8px))}
.sys-l{position:relative;z-index:1;width:52%;box-sizing:border-box;opacity:clamp(0,(var(--p) - .5) / .06,1)}
.sys2 .sc-pin{display:block}
.sys-l{height:100%}
.sys-l h2{--wa:.55}.sys-intro{--a:.66}.sys-list li{--a:calc(.68 + var(--k) * .05)}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.sys-pic{position:relative;height:60vh;clip-path:none}.sys-pic::after{opacity:0}.sys-lead{position:static;transform:none;color:#111;opacity:1!important;padding:96px var(--g) 0;max-width:none}.sys-lead .eb{color:#111}.sys-l{width:auto;opacity:1!important;height:auto}}
/* an older rule made every child of the systems frame "relative", which flattened the photo and the lead to nothing */
.sys2 .sc-pin>.sys-pic{position:absolute;inset:0;z-index:0}
.sys2 .sc-pin>.sys-lead{position:absolute;z-index:2}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.sys2 .sc-pin>.sys-pic,.sys2 .sc-pin>.sys-lead{position:relative}}

/* "One studio": only the heading grows; the text and button stay their normal size (Kay 2026-10-20) */
.how-cam{transform:translate(calc(var(--f) * -1 * var(--panx,0px)),calc(var(--f) * var(--pany,0px)))}
.how-l h2{font-size:calc(clamp(34px,3.6vw,60px) * (1 + var(--z,0) * .65))}
.how-l h2{white-space:nowrap}  /* keeps "One studio, from / brand to website." on two lines as it grows */
/* shuffle: no fading - the cards stay solid and are carried up and off by the wind, swaying a little (Kay 2026-10-20) */
.desk.away .pc{opacity:1!important;transition:none!important;animation:blowaway 1s cubic-bezier(.45,0,.8,.35) forwards;animation-delay:var(--bd,0s)}
@keyframes blowaway{
  0%{transform:rotate(var(--r))}
  35%{transform:translate(calc(var(--bx,0vw) * .25 + 2vw),-18vh) rotate(calc(var(--r) + var(--br,40deg) * .25))}
  65%{transform:translate(calc(var(--bx,0vw) * .6 - 2vw),-60vh) rotate(calc(var(--r) + var(--br,40deg) * .6))}
  100%{transform:translate(var(--bx,0vw),-150vh) rotate(calc(var(--r) + var(--br,40deg)))}}

/* web systems opens on a line-drawn street of small shops (Kay 2026-10-20: "diagram-like lines"): the lines draw in with the
   scroll and the three layers slide at different speeds (back slow, shops middle, front fast) for depth */
.street{position:absolute;left:0;right:0;bottom:0;height:62vh;z-index:1;pointer-events:none;opacity:calc(1 - var(--c,0) * 1.4)}
.st-l{position:absolute;left:0;bottom:0;height:100%;width:auto;aspect-ratio:4200/760;overflow:visible}
.st-l path{fill:none;vector-effect:non-scaling-stroke;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:calc(1 - var(--dr,1))}
.st-back{--dr:clamp(0,(var(--p) + .05) / .3,1);transform:translateX(calc(clamp(0,var(--p),1) * -6%))}.st-back path{stroke:#c9ccce;stroke-width:1}
.st-shops{--dr:clamp(0,(var(--p) - 0) / .3,1);transform:translateX(calc(clamp(0,var(--p),1) * -14%))}.st-shops path{stroke:#1b1d1f;stroke-width:1.3}.st-shops path.kerb{stroke:#9aa0a3}
.st-shops text{font:500 22px/1 Outfit,sans-serif;letter-spacing:.18em;fill:#1b1d1f;opacity:clamp(0,(var(--p) - .18) / .08,1)}
.st-front{--dr:clamp(0,(var(--p) - .05) / .3,1);transform:translateX(calc(clamp(0,var(--p),1) * -26%));height:115%}.st-front path{stroke:#1b1d1f;stroke-width:1.6}
/* the street replaces the dark photo at the start; the lead sentence sits above it in dark type */
.sys-pic::after{opacity:0}
.sys-pic{clip-path:inset(0 0 0 calc(52% + (1 - var(--c,0)) * 48%))}
.sys-lead,.sys-lead .eb{color:#111}.sys-lead{top:16vh;transform:translateY(calc(var(--c,0) * -40px))}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.street{display:none}.sys-pic{clip-path:none}}
.sys2 .sc-pin>.street{position:absolute;z-index:1}
.st-shops text.dim{font:400 15px/1 Outfit,sans-serif;letter-spacing:.06em;fill:#8a8f92}
/* shops are solid, so the buildings behind do not show through their windows */
.st-shops g>path:first-child{fill:#fff}

/* web systems intro, plain parallax (Kay 2026-10-20: "the image behind and the words rising slower than it already gives depth"):
   the photo moves up quickly, the words slowly, then the photo folds into the right half as before */
.street{display:none}
.sys-pic{clip-path:inset(0 0 0 calc(var(--c,0) * 52%))}
.sys-pic img{object-position:70% 45%;transform:translateY(calc((.15 - clamp(0,var(--p),.45) * 1.1) * 40vh)) scale(1.25)}
.sys-pic::after{opacity:calc(.5 * (1 - var(--c,0)))}
.sys-lead,.sys-lead .eb{color:#fff}
.sys-lead{top:50%;transform:translateY(calc(-50% + (.12 - clamp(0,var(--p),.45) * .55) * 40vh))}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.sys-pic img{transform:none}.sys-lead,.sys-lead .eb{color:#111}.sys-lead{transform:none}}

/* web systems intro with video (Kay 2026-10-20, after olympic.no): the clip starts as a small window in the middle and opens to the
   full screen as you scroll; the words then rise over it more slowly than the picture; later it folds into the right half */
.sys2{--o:clamp(0,(var(--p) - .02) / .2,1)}
.sys-pic video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transform:translateY(calc((.15 - clamp(0,var(--p),.45) * 1.1) * 30vh)) scale(1.2)}
.sys2 .sc-pin>.sys-pic{clip-path:inset(calc((1 - var(--o)) * 30%) calc((1 - var(--o)) * 34%) calc((1 - var(--o)) * 30%) calc((1 - var(--o)) * 34% + var(--c,0) * 52%) round calc((1 - var(--o)) * 10px))}
.sys-lead{opacity:calc(clamp(0,(var(--p) - .16) / .06,1) * (1 - var(--c,0) * 1.6))}
.sys-lead p{--wa:.18}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.sys2 .sc-pin>.sys-pic{clip-path:none}.sys-pic video{transform:none}.sys-lead{opacity:1}}
/* when the clip folds into the right half, it slides with it so the phone stays in view */
.sys-pic video{transform:translate(calc(var(--c,0) * 30%),calc((.15 - clamp(0,var(--p),.45) * 1.1) * 30vh)) scale(1.2)}
/* web systems timing: the sentence is complete by .36 and stays until .55 before the clip folds (Kay: "it moves on before the words finish") */
.sys-lead p{--wa:.16;--ws:.008;--wd:.05}
.sys2{--c:clamp(0,(var(--p) - .56) / .12,1)}
.sys-l{opacity:clamp(0,(var(--p) - .62) / .06,1)}
.sys-l h2{--wa:.64}.sys-intro{--a:.72}.sys-list li{--a:calc(.74 + var(--k) * .035)}
/* the studio block sizes to its widest line so its centre is the real centre */
.how-l{width:max-content;max-width:min(60vw,900px)}.how-l p{max-width:34em}
/* footer wordmark smaller (Kay 2026-10-20: "too big"), still sitting on the bottom edge */
[data-pv] .ft-big{padding-top:40px}[data-pv] .ft-big img{width:min(58vw,1000px);margin:0 auto}
/* half size, on the left gutter, sunk further below the bottom edge (Kay 2026-10-20) */
[data-pv] .ft-big{padding:40px var(--g) 0}[data-pv] .ft-big img{width:50vw;margin:0}
/* anchor the studio block by its left edge so the growing heading extends right, away from the line and arrow */
.how-l{right:auto;left:calc(100% - var(--g) - min(36vw,520px))}
/* real parallax in web systems (Kay: "it was supposed to feel like parallax"): while the sentence holds, the clip drifts up a
   quarter screen behind it and the sentence rises only a third as far, so the two clearly part */
.sys2{--pp:clamp(0,(var(--p) - .08) / .5,1)}
.sys-pic video{transform:translate(calc(var(--c,0) * 30%),calc((.5 - var(--pp)) * 24vh)) scale(1.32)}
.sys-lead{transform:translateY(calc(-50% + (.5 - var(--pp)) * 8vh))}
@media (prefers-reduced-motion:reduce) and (max-width:0px){.sys-pic video{transform:none}.sys-lead{transform:none}}
/* one smooth gust: two keyframes and a single ease-in, so the cards never stall between steps (Kay: "it glitches"); the
   rotate rides on its own property with its own ease so they still sway */
.desk.away .pc{will-change:transform;animation:blowaway2 1.1s cubic-bezier(.5,0,.85,.45) forwards;animation-delay:var(--bd,0s)}
@keyframes blowaway2{from{transform:translate(0,0) rotate(var(--r))}to{transform:translate(var(--bx,0vw),-150vh) rotate(calc(var(--r) + var(--br,40deg)))}}

/* web systems as true parallax, like lenvalproperties.com (Kay 2026-10-20: "I can't tell where the parallax is"): no fold any
   more; the clip stays full screen and moves only a little, while the words travel past it at full scroll speed: the sentence
   rises, rests in the middle, goes on up, and the systems list follows it up from below over the darkened clip */
@media all{
.sys2{--c:0;--q:clamp(0,(var(--p) - .12) / .5,1);--s:clamp(0,(var(--p) - .5) / .32,1)}
.sys-pic video{transform:translateY(calc((.5 - clamp(0,(var(--p) - .1) / .9,1)) * 12vh)) scale(1.18)}
.sys-pic::after{opacity:calc(.45 + var(--s) * .25)}
.sys-lead{opacity:clamp(0,(var(--p) - .12) / .06,1);transform:translateY(calc(-50% + (.5 - var(--q)) * 110vh))}
.sys-l{position:absolute;left:0;top:0;height:100%;z-index:2;opacity:1;transform:translateY(calc((1 - var(--s)) * 100vh))}
.sys-l,.sys-l h2,.sys-l .eb,.sys-list b,.sys-list li.live .st{color:#fff}
.sys-list,.sys-list li{border-color:rgba(255,255,255,.22)}
.sys-list .st,.sys-list li:not(.live) b{color:rgba(255,255,255,.55)}.sys-list li.live p{color:rgba(255,255,255,.8)}
.sys-l .pill{background:#fff!important;color:#111!important}
.sys-l h2{--wa:.58}.sys-intro{--a:.64}.sys-list li{--a:calc(.66 + var(--k) * .03)}}
/* the sentence rises and stays on the left; the systems list then slides in from the right onto the right half, over the clip (Kay 2026-10-20) */
@media all{
.sys2{--q:clamp(0,(var(--p) - .12) / .5,.5);--s:clamp(0,(var(--p) - .45) / .3,1)}
.sys-lead{max-width:min(44vw,720px)}
.sys-l{left:auto;right:0;width:48%;transform:translateX(calc((1 - var(--s)) * 60vw));opacity:clamp(0,var(--s) * 2,1)}
.sys-l h2{--wa:.52}.sys-intro{--a:.58}.sys-list li{--a:calc(.6 + var(--k) * .03)}}
/* the phone sits on the left of the clip, so the list needs no page of its own: the sentence passes on up, and the list slides
   in from the right onto the right half beside the phone (Kay 2026-10-20) */
@media all{
.sys2{--q:clamp(0,(var(--p) - .12) / .5,1);--s:clamp(0,(var(--p) - .5) / .3,1)}
.sys2 .sc-pin>.sys-l{position:absolute;left:auto;right:0;top:0;width:46%;padding-right:var(--g)}}
@media all{.sys-lead{opacity:calc(clamp(0,(var(--p) - .12) / .06,1) * clamp(0,(1 - var(--q)) / .25,1))}}
/* the clip rises too, a third of a screen while the sentence travels past at three times that, so the speeds part (Kay 2026-10-20) */
@media all{.sys-pic video{transform:translateY(calc((.5 - var(--q)) * 36vh)) scale(1.42)}}
/* parallax at true scroll speed (Kay 2026-10-20: "I feel no parallax at all"): the sentence now travels exactly with the finger
   (110vh over 1.1 screens of scroll, pin 4) and the clip follows at about 40% of that, which is what makes the depth; window
   opens first, the sentence rests once in the middle, the list slides in and rests */
@media all{
.sys2{--o:clamp(0,var(--p) / .14,1);--q:clamp(0,(var(--p) - .14) / .275,1);--s:clamp(0,(var(--p) - .42) / .2,1)}
.sys-lead{transform:translateY(calc(-50% + (.5 - var(--q)) * 110vh));opacity:clamp(0,(1 - var(--q)) / .2,1)}
.sys-lead p{--wa:.14;--ws:.004;--wd:.04}
.sys-pic video{transform:translateY(calc((.5 - var(--q)) * 44vh)) scale(1.5)}
.sys-l h2{--wa:.44}.sys-intro{--a:.5}.sys-list li{--a:calc(.52 + var(--k) * .02)}}
/* the big footer wordmark is gone (Kay 2026-10-20: the small one already says it); the small one a little larger */
[data-pv] .ft-logo{width:190px}
/* more room under the footer now the big wordmark is gone (Kay 2026-10-20) */
[data-pv] .ft{padding-bottom:140px!important}
/* the sentence rises with the finger, then stands still in the middle for a full screen of scroll so it can be read, while the
   clip keeps drifting up behind it; then it leaves and the list slides in (Kay 2026-10-20: "it shoots up, I can't read it") */
@media all{
.sys2{--o:clamp(0,var(--p) / .12,1);--ra:clamp(0,(var(--p) - .12) / .11,1);--rb:clamp(0,(var(--p) - .43) / .11,1);
  --v:clamp(0,(var(--p) - .12) / .42,1);--s:clamp(0,(var(--p) - .5) / .16,1)}
.sys-lead{transform:translateY(calc(-50% + (1 - var(--ra)) * 55vh - var(--rb) * 55vh));opacity:clamp(0,(1 - var(--rb)) / .3,1)}
.sys-lead p{--wa:.12;--ws:.004;--wd:.04}
.sys-pic video{transform:translateY(calc((.5 - var(--v)) * 40vh)) scale(1.5)}
.sys-l h2{--wa:.52}.sys-intro{--a:.58}.sys-list li{--a:calc(.6 + var(--k) * .02)}}
/* the clip stays perfectly still (Kay 2026-10-20): no drift, and while Web systems scrolls away the clip is held in place
   (--hf cancels the scene's own move), so only the words, the list and the dark Contact section come up over it */
@media all{
.sys-pic video{transform:none}
.sys2 .sc-pin>.sys-pic{transform:translateY(calc(var(--hf,0) * 100vh))}}

/* What We Do photos are low-res: soften them a little; the scale hides the blurred edge */
.chap-bg img{filter:blur(5px) grayscale(1);transform:scale(1.04)}
/* product cut-outs under each chapter line (img/home/prod-N.webp, N = chapter index) */
.chap-p{display:block;height:min(24vh,230px);width:auto;margin-top:20px;filter:drop-shadow(0 18px 24px rgba(0,0,0,.18))}
/* chapters alternate light / dark: 01 light, 02 dark, 03 light, 04 dark, 05 light */
.chap .sc-pin,.chap[data-step] .sc-pin{background:#f5f5f4;color:#111}.chap[data-step="1"] .sc-pin,.chap[data-step="3"] .sc-pin{background:#141414;color:#f2f0ec}
/* each chapter stays fully readable over a wider stretch before the next one fades in */
.chap-c{--t:clamp(0,(.5 - var(--d)) / .14,1)}
/* logo cards open with the logo at a modest size on its grey panel, not stretched to fill it (Kay 2026-10-20) */
.ov-info img[src*=".png"],.ov-info img[src*=".svg"]{aspect-ratio:4/3;max-height:60vh;padding:22.5% 30.5%;box-sizing:border-box}
.ov-x:focus{outline:none}.ov-x:focus-visible{outline:2px solid #999;outline-offset:2px}
/* the words over the desk never catch the mouse, so every card underneath can be clicked (Kay 2026-10-20) */
.work .work-q,.work-l{pointer-events:none}.work-l a,.work-l button{pointer-events:auto}
/* photo and mockup cards fill their frame; only cut-out logos sit small on the grey (Kay 2026-10-20) */
.pc.sm .pc-im img[src*=".jpg"]{object-fit:cover;padding:0}
/* a wide cut-out never runs past the text column; it shrinks to fit, anchored bottom-left */
.chap-p{max-width:100%;object-fit:contain;object-position:left bottom}
/* the Branding image is wide: 72% of the text column, still sitting on the shared baseline (Kay 2026-10-20) */
.chap-c[style*="--k:0"] .chap-p{width:72%}
/* cover used while a menu link jumps to its section */
.veil{position:fixed;inset:0;z-index:25;background:#f5f5f4;opacity:0;pointer-events:none;transition:opacity .28s ease}.veil.on{opacity:1}
/* while the veil is up, the Create Co. plus mark turns in the middle as a quick loading sign */
.veil::after{content:"";position:absolute;left:50%;top:50%;width:34px;height:34px;margin:-17px 0 0 -17px;border-radius:50%;background:linear-gradient(#fff,#fff) center/16px 3px no-repeat,linear-gradient(#fff,#fff) center/3px 16px no-repeat,#111;opacity:0;transform:scale(.8);transition:opacity .2s,transform .2s}
.veil.on::after{opacity:1;transform:scale(1);animation:veilspin .6s cubic-bezier(.6,0,.4,1) infinite}
@keyframes veilspin{from{rotate:0deg}to{rotate:180deg}}
/* menu jump: black opens from the centre as a circle behind the spinning plus mark (Kay 2026-10-21) */
.veil{z-index:40;opacity:1;background:#111;clip-path:circle(0 at 50% 50%);transition:clip-path .45s cubic-bezier(.7,0,.3,1)}.veil.on{opacity:1;clip-path:circle(75vmax at 50% 50%)}.veil::after{display:none}
.vmark{position:fixed;left:50%;top:50%;z-index:41;width:34px;height:34px;margin:-17px 0 0 -17px;border-radius:50%;pointer-events:none;background:linear-gradient(#fff,#fff) center/16px 3px no-repeat,linear-gradient(#fff,#fff) center/3px 16px no-repeat,#111;opacity:0;transform:scale(.6);transition:opacity .2s,transform .2s,background-color .3s}
.vmark.on{opacity:1;transform:scale(1);animation:veilspin .6s cubic-bezier(.6,0,.4,1) infinite}
.vmark.dark{background:linear-gradient(#111,#111) center/16px 3px no-repeat,linear-gradient(#111,#111) center/3px 16px no-repeat,#fff}
/* after the jump the black fades out rather than closing back into a circle */
.veil.fade{opacity:0;transition:opacity .5s ease,clip-path .45s cubic-bezier(.7,0,.3,1)}
/* phone menu: one round plus button, opens a black full-screen menu, plus turns into x (Kay 2026-10-21) */
.mnav{display:none}
@media (max-width:820px){
.mnav{display:block;position:relative;z-index:1;width:40px;height:40px;border:0;border-radius:50%;padding:0;cursor:pointer;background:linear-gradient(#fff,#fff) center/16px 2px no-repeat,linear-gradient(#fff,#fff) center/2px 16px no-repeat,#111;transition:transform .35s cubic-bezier(.6,0,.4,1),background-color .3s}
.hd .logo{position:relative;z-index:1}
.hd nav{position:fixed;inset:0;z-index:0;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:6px;height:auto;padding:0 var(--g);background:#111;font-size:40px;font-weight:300;opacity:0;visibility:hidden;transition:opacity .3s,visibility 0s .3s}
.hd nav a{color:#f2f0ec;font-size:40px;padding:6px 0}
.hd.open{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}
.hd.open nav{opacity:1;visibility:visible;transition:opacity .3s}
.hd.open .logo img{filter:invert(1)}
.hd.open .mnav{transform:rotate(45deg);background:linear-gradient(#111,#111) center/16px 2px no-repeat,linear-gradient(#111,#111) center/2px 16px no-repeat,#fff}
}
/* phones keep the scroll story too (Kay 2026-10-21: "polpharmabiologics works so well on mobile"): one column per scene */
@media (max-width:820px){
.intro-l li{flex-direction:column;align-items:flex-start;gap:4px;padding:10px 0}.intro-l span{font-size:16px}.intro-l em{text-align:left;font-size:10px}
.chap-t{width:auto;min-height:0}.chap-nav{display:none}.chap-p{height:20vh;margin-top:16px}
.how-tl,.how.asked .how-tl{right:var(--g);width:auto;top:24vh;bottom:14vh}.how-tl li b{font-size:22px}.how-tl li span{font-size:13px}
.how-l{left:calc(100% + 60px);right:auto;width:max-content;max-width:calc(100vw - 2 * var(--g));top:40vh}
.how-l h2{font-size:calc(28px * (1 + var(--z,0) * .3))}.how-l p{font-size:15px}
.work .sc-pin{display:flex;flex-direction:column;justify-content:center;gap:28px;padding-top:80px}
.work-l h2{font-size:30px}.work-l p{margin:14px 0 12px}
.desk{width:100%;height:50vh}.desk .pc{width:calc(27vw * var(--w,1));padding:6px 6px 0}.desk .pc:nth-child(n+8){display:none}
.sys2 .sc-pin>.sys-l{left:0;width:100%;padding:80px var(--g) 40px}.sys-list li{grid-template-columns:1fr}.sys-list li.live p,.sys-list li.live .pill{grid-column:1}
.sys-lead{max-width:calc(100% - 2 * var(--g))}.sys-lead p{font-size:28px}
.end .sc-pin{display:block;padding-top:96px}.end h2.big{font-size:44px}.end-f{margin-top:32px;max-width:none}
}
/* phone: the clip stays full screen and darkens as the list comes up over it, white text on top */
@media (max-width:820px){
.sys2 .sc-pin>.sys-pic{clip-path:inset(calc((1 - var(--o)) * 30%) calc((1 - var(--o)) * 22%) round calc((1 - var(--o)) * 10px))}
.sys-pic::after{opacity:calc(var(--s,0) * .62)}
.sys-l,.sys-l h2,.sys-l .eb,.sys-list b,.sys-list li.live .st{color:#fff}.sys-list,.sys-list li{border-color:rgba(255,255,255,.22)}
.sys-list .st,.sys-list li:not(.live) b{color:rgba(255,255,255,.55)}.sys-list li.live p{color:rgba(255,255,255,.8)}.sys-l .pill{background:#fff!important;color:#111!important}
.sys2 .sc-pin>.sys-l{right:auto;transform:translateY(calc((1 - var(--s,0)) * 100vh));opacity:1}
}
/* shorter phones: the steps start below the two-line question, never under it */
@media (max-width:820px){.how-tl,.how.asked .how-tl{top:calc(13vh + 130px)}}
/* phone hero: the landscape clip turned upright, so the laptop runs top to bottom and the typing hands sit at the bottom (Kay 2026-10-21) */
@media (max-width:820px){.hero video{inset:auto;left:50%;top:50%;width:max(100svh,560px);height:100vw;transform:translate(-50%,-50%) rotate(90deg)}}
/* the stage is as tall as the screen with the browser bars hidden, so no strip of page shows under it when they slide away (Kay 2026-10-21) */
.track-pin,.sc-pin{height:100vh;height:var(--H,100lvh)}
/* touch screens: no hover lift, so the first tap opens the card instead of only lifting it (Kay 2026-10-21) */
@media (hover:none){.work.done .desk .pc:hover{z-index:auto!important;transform:translate(0,0) rotate(var(--r));box-shadow:0 10px 26px rgba(0,0,0,.14)}.work.done .desk:has(.pc:hover) .pc:not(:hover){filter:none}.pc:hover .pc-go{max-height:0;opacity:0;margin-top:0}}
/* phone: the work heading sits at the top and the desk fills the rest of the screen (Kay 2026-10-21: "too low") */
@media (max-width:820px){.work .sc-pin{justify-content:flex-start;gap:16px;padding-top:84px}.desk{flex:1;height:auto;min-height:0;margin-bottom:56px}}
/* phone footer: logo and line on their own rows, then links and credit side by side (Kay 2026-10-21: cut off at the side) */
@media (max-width:820px){.ft-cols{grid-template-columns:1fr 1fr;gap:20px 24px}.ft-cols .ft-logo,.ft-cols>p:nth-of-type(1){grid-column:1/-1}[data-pv] .ft-logo{width:160px}[data-pv] .ft{padding-bottom:80px!important}}
/* phone contact: the whole form, Send included, fits one screen */
@media (max-width:820px){.end .sc-pin{padding-top:80px}.end h2.big{font-size:38px}.end-f{margin-top:20px;gap:12px}.end-f label{gap:4px;font-size:13px}.end-f input{padding:6px 0}.end-f textarea{height:84px;min-height:84px;padding:6px 0}.end-send{margin-top:4px}}
/* phone: the step lines wrap before the line that runs up the right side (Kay 2026-10-21) */
@media (max-width:820px){.how-tl,.how.asked .how-tl{right:72px}}
/* phone: the clip is darkened under the sentence too, so the white words read (Kay 2026-10-21) */
@media (max-width:820px){.sys-pic::after{opacity:calc(.45 + var(--s,0) * .25)}}
/* footer continues the black of Contact down to the bottom (Kay 2026-10-21) */
[data-pv] .ft{background:#101213;color:#f2f0ec;padding-top:24px}
[data-pv] .ft p,[data-pv] .ft a{color:#9a9a96}[data-pv] .ft a:hover{color:#f2f0ec}[data-pv] .ft-logo{filter:invert(1)}
@media (max-width:820px){[data-pv] .ft{padding-top:32px;padding-bottom:56px!important}}
/* phone: the footer sits in the empty space under the contact form instead of a separate block below (Kay 2026-10-21) */
.end-ft{display:none}
@media (max-width:820px){
[data-pv] .ft{display:none}
.end .sc-pin{display:flex;flex-direction:column;padding-bottom:24px}
.end-ft{display:block;margin-top:auto;padding-top:20px;position:relative;z-index:1}
.end-ft img{width:110px;filter:invert(1);display:block;margin-bottom:10px}
.end-ft p{margin:0 0 8px;font-size:12px;line-height:1.5;color:#9a9a96}
.end-ft a{color:#9a9a96;margin-right:14px}.end-ft span{display:block;margin-top:6px}
}
@media (max-width:820px) and (max-height:700px){.end-f textarea{height:60px;min-height:60px}.end h2.big{font-size:32px}}
/* the browser's overscroll at the page bottom shows black, not white (Kay 2026-10-21) */
html{background:#101213}
@media (max-width:820px){.end .sc-pin{align-items:stretch}}
@media (max-width:820px) and (max-height:700px){.end .sc-pin{padding-top:76px;padding-bottom:12px}.end-f{gap:6px;margin-top:14px}.end-ft{padding-top:8px}.end-ft img{width:96px;margin-bottom:6px}.end-ft p{margin-bottom:4px}}
/* cards as plain pictures, no white frame and no text (Kay 2026-10-21: "does it need to be a polaroid?") */
.desk.nf .pc{padding:0;background:none;border-radius:4px;overflow:hidden}
.desk.nf .pc-im{border-radius:0}.desk.nf .pc-b{display:none}
/* the page stops at the end: no rubber-band pull past the bottom (Kay 2026-10-21) */
html,body{overscroll-behavior-y:none}
/* Our work on the dark glow background of the text scenes (Kay 2026-10-21) */
.work.wd .sc-pin{background:#101213;color:#f2f0ec}
.work.wd .work-l .eb,.work.wd .work-l p,.work.wd .desk-hint{color:#a9a9a5}
.work.wd .pill{background:#f2f0ec!important;color:#111!important}
.work.wd .desk .pc{box-shadow:0 18px 40px rgba(0,0,0,.55)}
/* the dark trial: the card pile sits a little lower, centred in the screen (Kay 2026-10-21: "photos are all high") */
@media (min-width:821px){.work.wd .desk{top:7vh}}
/* each card keeps its picture's own shape: photos at their real proportions, logos on square, wide or tall tiles (Kay 2026-10-21) */
.desk.nf .pc.port{width:calc(min(13vw,210px) * var(--w,1) * .75)}
@media (max-width:820px){.desk.nf .pc.port{width:calc(27vw * var(--w,1) * .75)}}
/* phone: 10 cards instead of 7, a touch smaller so they still fit (Kay 2026-10-21) */
@media (max-width:820px){.desk .pc:nth-child(n+8){display:block}.desk .pc:nth-child(n+11){display:none}.desk .pc{width:calc(24vw * var(--w,1))}.desk.nf .pc.port{width:calc(24vw * var(--w,1) * .75)}}
/* logo cards: the logo stays modest with more room either side (Kay 2026-10-21) */
.desk.nf .pc-im img[src*=".png"],.desk.nf .pc-im img[src*=".svg"]{object-fit:contain;padding:14% 26%;box-sizing:border-box}
/* logo cards: the tile is a quarter bigger but the logo inside stays the same size, so there is more room around it (Kay 2026-10-21) */
.desk.nf .pc.logo{width:calc(min(13vw,210px) * var(--w,1) * 1.25)}
.desk.nf .pc.logo .pc-im img{padding:11% 31%}
@media (max-width:820px){.desk.nf .pc.logo{width:calc(24vw * var(--w,1) * 1.25)}}
/* logo tiles take the logo's own orientation (wide logo, wide tile) with an even margin, so long logos are not tiny (Kay 2026-10-21) */
.desk.nf .pc.logo .pc-im img{padding:15% 18%}
.desk.nf .pc.logo{width:calc(min(13vw,210px) * var(--w,1) * 1.15)}
@media (max-width:820px){.desk.nf .pc.logo{width:calc(24vw * var(--w,1) * 1.15)}}

/* Our work as two moving columns (Kay 2026-11-04): one goes up, one goes down, pause under the pointer, no captions.
   Always on, phones too (Kay rule: motion is never gated on Reduce Motion). Each track holds the column twice, so -50% is one full loop. */
.rr-wrap{display:grid;grid-template-columns:1fr 1fr;gap:16px;height:min(82vh,820px);width:min(100%,640px);justify-self:center;overflow:hidden;-webkit-mask-image:linear-gradient(transparent,#000 8%,#000 92%,transparent);mask-image:linear-gradient(transparent,#000 8%,#000 92%,transparent)}
.rr{overflow:hidden;min-width:0}
.rr-t{display:flex;flex-direction:column;gap:16px;will-change:transform}
@keyframes rr{from{transform:translateY(0)}to{transform:translateY(calc(-50% - 8px))}}
.rc{display:block;border-radius:8px;overflow:hidden;background:#f5f5f3;box-shadow:0 10px 24px rgba(0,0,0,.35);transition:transform .35s cubic-bezier(.16,1,.3,1)}
.rc:hover{transform:scale(1.03)}
.rc img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
.rc.lo img{object-fit:contain;padding:12% 18%;box-sizing:border-box}
/* phones: the two columns fill the screen under the heading */
@media (max-width:820px){.rr-wrap{flex:1;min-height:0;height:auto;width:100%;gap:10px;margin-bottom:24px}.rr-t{gap:10px}}
/* first "Want to see a few?" alone, then the columns come up with the heading (Kay 2026-11-04) */
.work .rr-wrap{--t:clamp(0,(var(--p) - .52) / .1,1);opacity:var(--t);transform:translateY(calc((1 - var(--t)) * 60px))}
/* case studies wear a badge so people know they open (Kay 2026-11-04) */
.rc{position:relative}.rc .pc-tag{display:block;z-index:1;left:10px;top:10px;font-size:12px;padding:5px 10px;box-shadow:0 2px 8px rgba(0,0,0,.25)}
/* Our work card swap (Kay 2026-11-07), after Bencho "Card swap" (MIT): flat stage, perspective on the stage, a slot per card */
.csw{width:100%;display:flex;align-items:center;justify-content:center;height:min(82vh,820px);padding:12% 14% 0 0;box-sizing:border-box}
.csw-stage{position:relative;width:min(100%,320px);aspect-ratio:16/10;perspective:1000px;cursor:pointer}
.csw-card{position:absolute;inset:0;border-radius:8px;overflow:hidden;background:#fff;border:3px solid #fff;box-shadow:0 18px 40px rgba(0,0,0,.28);transform:var(--t);transition:transform .6s cubic-bezier(.22,1,.36,1),opacity .4s;user-select:none;-webkit-user-select:none}
.csw-card img{display:block;width:100%;height:100%;object-fit:cover;object-position:top}
.csw-tag{position:absolute;left:14px;bottom:14px;display:flex;gap:8px;align-items:center;background:#fff;color:#111;border-radius:999px;padding:7px 14px;font-size:14px;font-weight:500;box-shadow:0 2px 10px rgba(0,0,0,.15)}
.csw-tag i{font-style:normal;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#fff;background:#111;border-radius:999px;padding:3px 8px}
.work .csw{--t2:clamp(0,(var(--p) - .52) / .1,1);opacity:var(--t2);transform:translateY(calc((1 - var(--t2)) * 60px))}
@media (max-width:820px){.csw{height:auto;flex:1;min-height:0;padding:56px 26% 24px 6%}.csw-tag{font-size:12px;padding:5px 10px;left:10px;bottom:10px}}
.csw-card.lo img{object-fit:contain;padding:14% 22%;box-sizing:border-box}
.csw-card.lo .csw-tag{display:none}
.csw-card.ph img{object-position:center}
/* Kay 2026-11-07: heading toward the centre, close to the card stack (desktop) */
@media (min-width:821px){.work .sc-pin{grid-template-columns:auto auto;justify-content:center;gap:clamp(40px,5vw,96px)}.work .csw{width:clamp(460px,38vw,640px);padding:14% 230px 0 0}}
.csw-card[data-front]{touch-action:none;cursor:grab}.csw-card[data-front]:active{cursor:grabbing}
.csw-go{font-size:12px;font-weight:600;color:#fff;background:#111;border-radius:999px;padding:4px 10px;text-decoration:none;white-space:nowrap}.csw-go:hover{background:#444}
.csw-card:not([data-front]) .csw-go{pointer-events:none}
.csw-card .csw-go{position:absolute;left:14px;bottom:14px;font-size:14px;padding:8px 16px;box-shadow:0 2px 10px rgba(0,0,0,.2)}
@media (max-width:820px){.csw-card .csw-go{left:10px;bottom:10px;font-size:12px;padding:6px 12px}}
@media (max-width:820px){.csw{padding:84px 34% 24px 8%;align-items:flex-start}}
