@font-face{font-family:'BigShoulders';src:url(assets/fonts/BigShouldersDisplay-Thin.ttf) format('truetype');
  font-weight:100;font-style:normal;font-display:swap}
@font-face{font-family:Anton;src:url("assets/fonts/Anton-Regular-subset.ttf") format("truetype");font-display:swap}@font-face{font-family:Inter;src:url("assets/fonts/Inter-Regular-subset.ttf") format("truetype");font-display:swap}@font-face{font-family:JetBrains;src:url("assets/fonts/JetBrainsMono-Regular-subset.ttf") format("truetype");font-display:swap}
:root{--white:#f5f7fb;--dim:#a5abb7;--blue:#1267ff;--cyan:#4eb9ff;--line:rgba(255,255,255,.14)}*{box-sizing:border-box}html{scroll-behavior:smooth}html,body{width:100%;min-height:100%;margin:0;background:#02040a;color:var(--white);font-family:Inter,Arial,sans-serif}body{overflow-x:hidden}a{color:inherit;text-decoration:none}
.hero-art{position:relative;width:100%;height:100svh;overflow:hidden;isolation:isolate;cursor:none;background:#02040a}.hero-video{position:absolute;inset:0;z-index:-3;width:100%;height:100%;object-fit:cover;object-position:center}.video-grade{position:absolute;inset:0;z-index:-2;pointer-events:none;background:linear-gradient(90deg,rgba(2,4,10,.95),rgba(2,4,10,.8) 32%,rgba(2,4,10,.2) 65%,rgba(2,4,10,.04)),linear-gradient(0deg,rgba(2,4,10,.3),transparent 45%)}
.nav{position:absolute;z-index:5;top:0;left:0;width:100%;height:86px;padding:0 clamp(24px,4vw,68px);display:flex;align-items:center;justify-content:space-between}.logo{font:700 13px JetBrains,monospace;letter-spacing:.15em;border:1px solid var(--line);padding:7px 10px;border-radius:4px}.nav-links{font:11px JetBrains,monospace;letter-spacing:.15em;color:var(--dim)}.nav-links ul{display:flex;gap:10px;margin:0;padding:0;list-style:none}.nav-links li{position:relative;border-radius:100px}.nav-links a{display:block;padding:8px 13px}.nav-links li.active{background:var(--blue);color:#fff}.gooey-nav-container{position:relative}.gooey-effect{position:absolute;pointer-events:none}.gooey-text{display:none!important}
.hero-content{position:absolute;z-index:3;left:clamp(28px,7vw,138px);top:50%;width:min(620px,48vw);transform:translateY(-47%)}.eyebrow{display:flex;align-items:center;gap:10px;margin:0 0 22px;color:var(--dim);font:10px JetBrains,monospace;letter-spacing:.17em;white-space:nowrap}.eyebrow span{width:7px;height:7px;border-radius:50%;background:var(--blue);box-shadow:0 0 12px var(--blue)}.eyebrow i{display:block;width:64px;height:1px;background:linear-gradient(90deg,var(--line),transparent)}
h1{margin:0 0 20px;font:clamp(68px,7.35vw,118px)/.88 Anton,Impact,sans-serif;letter-spacing:0;background:linear-gradient(100deg,#fff 0 40%,#8bb6ff 50%,#fff 60% 100%);background-size:250% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;animation:wash 7s linear infinite}h1 span{display:block}h1 span+span{margin-top:.035em}@keyframes wash{from{background-position:140% 0}to{background-position:-140% 0}}
.role{margin:0 0 22px;color:#5f9bff;font:700 clamp(14px,1.35vw,20px) JetBrains,monospace;letter-spacing:.055em}.intro{max-width:560px;margin:0 0 22px;color:#d3d6dd;font-size:clamp(14px,1.2vw,18px);line-height:1.55}.skill-cards{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:28px}.skill-cards span{padding:7px 10px;border:1px solid rgba(255,255,255,.12);border-radius:4px;background:rgba(4,8,18,.42);backdrop-filter:blur(8px);font:9px JetBrains,monospace;letter-spacing:.08em;color:#c2c8d2}
.cta-row{display:flex;gap:12px}.btn{position:relative;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;min-height:52px;padding:0 24px;border:1px solid var(--line);border-radius:6px;font:700 11px JetBrains,monospace;letter-spacing:.11em}.btn-primary{border-color:transparent;background:linear-gradient(135deg,#2676ff,#0c4ee1);box-shadow:0 12px 34px rgba(18,103,255,.28)}.btn-secondary{background:rgba(3,6,14,.4);backdrop-filter:blur(8px)}.btn-fx{position:absolute;inset:0}.btn-label{position:relative;z-index:2;display:flex;gap:12px;align-items:center}.btn b{font-size:17px}.location{margin:24px 0 0;color:#8f96a3;font:10px JetBrains,monospace;letter-spacing:.13em}.location span{padding:0 9px;color:#4f80d5}
.discipline-cards{position:absolute;z-index:3;right:clamp(22px,4vw,70px);top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:64px}.discipline-cards span{display:flex;align-items:center;gap:10px;color:#bbc2cd;font:10px JetBrains,monospace;letter-spacing:.17em}.discipline-cards span::before{content:"";width:8px;height:8px;border:1px solid #9da7b5;border-radius:50%;box-shadow:inset 0 0 0 2px #02040a}.discipline-cards span::after{content:"";position:absolute;right:100%;width:34px;height:1px;background:linear-gradient(90deg,transparent,var(--line))}
.video-hover-zone{position:absolute;z-index:2;left:52%;right:13%;top:8%;bottom:6%;cursor:none}
.glass-lens-ball{position:absolute;z-index:6;width:min(37.12vw,166.4px);aspect-ratio:1;left:50%;top:50%;transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;opacity:0;transition:opacity .22s ease;backdrop-filter:url(#glassLensDistort) saturate(1.15) brightness(1.05);-webkit-backdrop-filter:blur(.3px);box-shadow:inset -14px -18px 32px rgba(0,0,0,.35),inset 11px 13px 24px rgba(255,255,255,.35),inset 0 0 0 1px rgba(255,255,255,.25),0 16px 36px rgba(0,0,0,.5)}
.glass-lens-ball::after{content:"";position:absolute;inset:0;border-radius:inherit;background:radial-gradient(circle at 36% 30%,rgba(162,205,255,.18),rgba(25,111,255,.09) 48%,rgba(0,52,190,.16) 100%);box-shadow:inset 0 0 26px rgba(36,119,255,.22),0 0 28px rgba(18,103,255,.12);mix-blend-mode:screen}.laser-cursor{position:absolute;inset:0;z-index:7;width:100%;height:100%;pointer-events:none;mix-blend-mode:screen}
/* the last 260px of the section fade from its own navy into the page colour,
   so the seam with the section below is a dissolve rather than a hard line */
.motion-section{position:relative;min-height:100svh;overflow:hidden;isolation:isolate;
  background:linear-gradient(180deg,#03122a 0,#03122a calc(100% - 260px),#02060f 100%)}.motion-background{position:absolute;inset:0;z-index:-3;width:100%;height:100%;object-fit:cover}.motion-shade{position:absolute;inset:0;z-index:-2;background:linear-gradient(90deg,rgba(1,9,24,.62) 0%,rgba(1,13,34,.2) 48%,rgba(1,10,28,.34) 100%),linear-gradient(0deg,rgba(1,7,20,.72),transparent 28%)}.motion-layout{position:relative;width:100%;min-height:100svh;padding:clamp(72px,8vh,110px) clamp(46px,6vw,118px) 30px}.motion-copy{position:relative;z-index:2;width:min(31vw,510px);padding-top:5vh}.section-kicker{display:flex;align-items:center;gap:12px;margin:0 0 28px;color:#d7e9ff;font:11px JetBrains,monospace;letter-spacing:.08em}.section-kicker i{width:36px;height:1px;background:#5cb9ff}.motion-copy h2{margin:0;font:clamp(42px,4.15vw,72px)/1.03 Anton,Impact,sans-serif;letter-spacing:.015em}.motion-copy h2 span{color:#82bfff;text-shadow:0 0 28px rgba(49,139,255,.25)}.motion-tagline{margin:22px 0 0;color:#55b9ff;font:clamp(12px,1.05vw,17px) JetBrains,monospace;letter-spacing:.17em}.motion-summary{width:min(100%,470px);margin:42px 0 0;color:#e2ebf6;font-size:clamp(13px,1vw,17px);line-height:1.75}.scroll-cue{display:inline-flex;align-items:center;gap:16px;margin-top:54px;font:12px JetBrains,monospace;letter-spacing:.12em}.scroll-cue b{display:grid;place-items:center;width:45px;height:45px;border:1px solid #62c3ff;border-radius:50%;color:#67c8ff;font-size:23px;box-shadow:0 0 24px rgba(34,147,255,.2)}
.service-field{position:absolute;inset:5.5% 7% 23% 34%;z-index:2}.service-card{position:absolute;display:grid;grid-template-columns:auto 46px 1fr;gap:14px;width:min(25vw,390px);min-height:175px;padding:28px 26px 24px;border:1px solid rgba(187,222,255,.7);border-radius:13px;background:linear-gradient(145deg,rgba(27,70,119,.76),rgba(8,30,65,.7));box-shadow:inset 0 1px 0 rgba(255,255,255,.13),0 22px 60px rgba(0,5,20,.28);backdrop-filter:blur(13px);transition:transform .35s ease,border-color .35s ease,box-shadow .35s ease}.service-card:hover{transform:translateY(-7px);border-color:#8bd5ff;box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 28px 70px rgba(0,10,35,.4),0 0 32px rgba(38,137,255,.18)}.service-card> b{position:absolute;right:17px;top:12px;font-size:22px;font-weight:400}.card-number{color:#4eaeff;font:28px Anton,sans-serif}.card-icon{display:grid;place-items:center;width:44px;height:44px;margin-top:49px;border:1px solid rgba(198,224,255,.45);border-radius:10px;background:rgba(91,155,220,.13);font-size:24px}.service-card h3{margin:2px 0 14px;font:clamp(17px,1.35vw,24px) Anton,sans-serif;letter-spacing:.035em}.service-card p{margin:0;color:#edf5ff;font-size:clamp(11px,.82vw,14px);line-height:1.55}.service-card div:last-of-type i{display:block;width:41px;height:2px;margin-top:15px;background:#38bfff;box-shadow:0 0 10px #188cff}.card-1{right:0;top:0}.card-2{left:0;top:18%}.card-3{right:0;top:39%}.card-4{left:-1%;top:59%}.card-5{right:0;top:78%}
.section-rail{position:absolute;z-index:2;right:2.4%;top:13%;bottom:28%;display:flex;flex-direction:column;align-items:center;justify-content:space-between;font:10px JetBrains,monospace;letter-spacing:.08em}.section-rail ol{position:relative;display:flex;flex-direction:column;justify-content:space-between;height:75%;margin:0;padding:0;list-style:none}.section-rail ol::before{content:"";position:absolute;left:5px;top:4px;bottom:4px;width:1px;background:#bed8f3}.section-rail li{position:relative;padding-left:27px}.section-rail li::before{content:"";position:absolute;left:0;top:1px;width:11px;height:11px;border:1px solid #fff;border-radius:50%;background:#06214a}.section-rail li.active{color:#57b9ff}.section-rail li.active::before{border-color:#41b8ff;box-shadow:0 0 12px #1688ff,inset 0 0 0 3px #0d59bb}
.process-panel{position:absolute;z-index:3;left:5.7%;right:5.7%;bottom:8.5%;display:grid;grid-template-columns:190px 1fr;min-height:140px;padding:22px 28px;border:1px solid rgba(195,225,255,.62);border-radius:14px;background:linear-gradient(100deg,rgba(13,36,75,.8),rgba(9,37,78,.72));box-shadow:inset 0 1px 0 rgba(255,255,255,.11),0 20px 60px rgba(0,6,24,.35);backdrop-filter:blur(13px)}.process-panel>h3{margin:27px 0;border-right:1px solid rgba(255,255,255,.7);color:#59baff;font:22px Anton,sans-serif;letter-spacing:.03em}.process-panel>h3 i{display:block;width:40px;height:2px;margin-top:13px;background:#51baff}.process-panel ol{display:grid;grid-template-columns:repeat(5,1fr);gap:25px;margin:0;padding:0 0 0 44px;list-style:none}.process-panel li{position:relative;display:flex;flex-direction:column;justify-content:center;gap:6px}.process-panel li:not(:last-child)::after{content:"›";position:absolute;right:-15px;top:44%;font-size:30px}.process-panel li b{color:#4aaeff;font:18px Anton,sans-serif}.process-panel li strong{font:18px Anton,sans-serif;font-weight:400}.process-panel li span{color:#e2eaf4;font-size:11px;line-height:1.45}.motion-location,.availability{position:absolute;z-index:3;bottom:2.2%;margin:0;font:10px JetBrains,monospace;letter-spacing:.1em}.motion-location{left:5.7%}.motion-location span{padding:0 10px;color:#4ab5ff}.availability{right:5.7%;padding:7px 14px;border:1px solid rgba(255,255,255,.45);border-radius:99px}.availability i{display:inline-block;width:6px;height:6px;margin-right:9px;border-radius:50%;background:#21e881;box-shadow:0 0 9px #21e881}
@media(max-width:1000px){.motion-section{min-height:auto}.motion-layout{padding:100px 24px 44px}.motion-copy{width:min(620px,100%)}.service-field{position:relative;inset:auto;display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin:60px 0 190px}.service-card{position:relative!important;inset:auto!important;width:auto;min-height:190px}.process-panel{left:24px;right:24px;bottom:65px;grid-template-columns:150px 1fr}.process-panel ol{gap:14px;padding-left:24px}.section-rail{display:none}.motion-location,.availability{bottom:22px}.motion-location{left:24px}.availability{right:24px}}
@media(max-width:820px){.hero-art{min-height:100svh;height:auto;cursor:default}.hero-video{position:absolute}.video-grade{position:absolute;background:linear-gradient(0deg,rgba(2,4,10,.9),rgba(2,4,10,.38))}.nav{height:70px;padding:0 20px}.nav-links li:nth-child(2){display:none}.nav-links a{padding:7px 8px}.hero-content{position:relative;left:auto;top:auto;width:auto;min-height:100svh;padding:126px 22px 60px;transform:none;display:flex;flex-direction:column;justify-content:center}.eyebrow{white-space:normal;line-height:1.5}.eyebrow i{display:none}h1{font-size:clamp(64px,20vw,96px)}.role{font-size:13px}.cta-row{flex-direction:column}.btn{width:100%}.discipline-cards,.video-hover-zone,.glass-lens-ball,.laser-cursor{display:none}.motion-copy h2{font-size:clamp(40px,12vw,64px)}.service-field{grid-template-columns:1fr;margin-bottom:360px}.process-panel{position:absolute;display:block;padding:20px}.process-panel>h3{margin:0 0 14px;padding-bottom:12px;border-right:0;border-bottom:1px solid var(--line)}.process-panel ol{grid-template-columns:1fr 1fr;gap:16px;padding:0}.process-panel li:not(:last-child)::after{display:none}.motion-location,.availability{font-size:10.5px}}
@media(min-width:1001px){.service-field{bottom:30%}.service-card{height:clamp(140px,17.5vh,175px);min-height:0;padding:clamp(14px,2.2vh,24px) 22px}.card-icon{margin-top:clamp(28px,4.5vh,49px)}.service-card h3{margin-bottom:clamp(7px,1.5vh,14px)}.service-card div:last-of-type i{margin-top:clamp(7px,1.5vh,15px)}.card-2{top:18%;height:clamp(145px,18vh,180px)}.card-3{top:34%}.card-4{top:58%}.card-5{top:69%}}
@media(min-width:1001px){.motion-copy h2{font-size:clamp(42px,3.45vw,64px);font-family:Inter,Arial,sans-serif;font-weight:600;letter-spacing:-.035em}.service-card{--rx:0deg;--rz:0deg;--lift:0px;width:min(21.5vw,410px);overflow:hidden;transform-origin:center;transform-style:preserve-3d;transform:perspective(1100px) rotateY(var(--rx)) rotateZ(var(--rz)) translateY(var(--lift));background:linear-gradient(135deg,rgba(31,74,122,.76),rgba(8,29,62,.68));box-shadow:inset 0 1px 0 rgba(255,255,255,.16),inset 18px 0 40px rgba(77,151,232,.05),0 24px 70px rgba(0,7,27,.32);transition:transform .38s cubic-bezier(.2,.8,.2,1),border-color .35s ease,box-shadow .35s ease}.service-card::before{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(115deg,rgba(255,255,255,.09),transparent 28%,transparent 70%,rgba(52,146,255,.08));mix-blend-mode:screen}.service-card:hover{--lift:-7px;transform:perspective(1100px) rotateY(var(--rx)) rotateZ(var(--rz)) translateY(var(--lift));border-color:#99d9ff;box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 32px 75px rgba(0,8,31,.44),0 0 34px rgba(37,139,255,.16)}.card-1{--rx:-3deg;--rz:-1.8deg;right:.5%;top:1%}.card-2{--rx:4deg;--rz:2.4deg;left:2%;top:20%}.card-3{--rx:-3deg;--rz:-1deg;right:.2%;top:36%}.card-4{--rx:3deg;--rz:.6deg;left:1%;top:61%}.card-5{--rx:-3deg;--rz:1deg;right:.4%;top:72%}.process-panel{min-height:0;height:140px;padding-top:16px;padding-bottom:16px}.process-panel>h3{margin:20px 0}.process-panel ol{gap:20px}.process-panel li strong{font-size:17px}}
@media(min-width:1001px){.service-card p{font-size:clamp(9px,.72vw,13px);line-height:1.45}.service-card h3{font-size:clamp(16px,1.2vw,22px)}.card-2{height:clamp(155px,18.5vh,185px)}.card-3{height:clamp(145px,18vh,180px)}.card-5{top:67%;height:clamp(160px,19.5vh,195px)}}
.motion-stage{position:relative;min-height:100svh;overflow:hidden;isolation:isolate}
@media(min-width:821px){.motion-section{height:240svh;min-height:0;overflow:visible}.motion-stage{position:sticky;top:0;height:100svh;min-height:0}.motion-layout{height:100svh}}
/* Page 2 build sequence: Layer 01 — scroll-scrubbed video only. */
.motion-section .motion-shade,.motion-section .motion-layout{display:none}
@media(min-width:821px){.motion-section{height:174svh}.motion-stage{height:100svh}}
.pressure-layer{--pressure-reveal:0;position:absolute;z-index:2;left:clamp(34px,7.2vw,138px);top:17%;width:min(58vw,880px);pointer-events:none;opacity:var(--pressure-reveal);filter:blur(calc((1 - var(--pressure-reveal)) * 14px));clip-path:inset(0 calc((1 - var(--pressure-reveal)) * 100%) 0 0);transform:translateY(calc((1 - var(--pressure-reveal)) * 42px));transition:opacity .08s linear;will-change:opacity,filter,clip-path,transform}.pressure-kicker{display:flex;align-items:center;gap:14px;margin:0 0 28px;color:#d7e9ff;font:13px JetBrains,monospace;letter-spacing:.09em}.pressure-kicker i{width:46px;height:1px;background:#5cb9ff}.pressure-title{display:flex;flex-direction:column;align-items:flex-start;margin:0;color:#f5f8ff;font-family:"Roboto Flex",Anton,Impact,sans-serif;font-size:clamp(54px,6.3vw,108px);font-optical-sizing:auto;line-height:.94;letter-spacing:-.055em;text-transform:uppercase;text-shadow:0 10px 32px rgba(0,7,25,.34)}.pressure-title>span{display:flex;white-space:nowrap}.pressure-title .pressure-char{display:inline-block;font-variation-settings:"wght" 650,"wdth" 86,"slnt" 0;will-change:font-variation-settings,transform}.pressure-layer.is-visible{pointer-events:auto}.pressure-layer:not(.is-pressure-ready) .pressure-char{font-variation-settings:"wght" 650,"wdth" 86,"slnt" 0!important}.pressure-layer.is-pressure-ready .pressure-title{cursor:none}.pressure-layer.is-pressure-ready .pressure-char{transition:font-variation-settings .08s linear}
@media(min-width:821px){.motion-section{height:250svh}}
@media(max-width:820px){.pressure-layer{top:16%;left:22px;width:calc(100% - 44px);opacity:1;filter:none;clip-path:none;transform:none}.pressure-kicker{font-size:10.5px}.pressure-title{font-size:clamp(48px,13vw,76px)}}
.chapter-rail{--rail-reveal:0;--rail-position:0%;position:absolute;z-index:4;right:clamp(22px,3.4vw,66px);top:13%;bottom:12%;display:flex;flex-direction:column;align-items:center;color:#f2f6fd;font:12px JetBrains,monospace;letter-spacing:.06em;opacity:var(--rail-reveal);transform:translateX(calc((1 - var(--rail-reveal)) * 42px));filter:blur(calc((1 - var(--rail-reveal)) * 8px));pointer-events:none;will-change:opacity,transform,filter}.chapter-rail ol{position:relative;display:flex;flex:1;width:58px;flex-direction:column;justify-content:space-between;margin:20px 0;padding:12px 0;list-style:none}.chapter-rail ol::before{content:"";position:absolute;left:8px;top:17px;bottom:17px;width:1px;background:linear-gradient(180deg,rgba(224,239,255,.9),rgba(142,190,238,.75))}.chapter-rail ol::after{content:"";position:absolute;z-index:2;left:1px;top:calc(17px + (100% - 34px) * var(--rail-position));width:15px;height:15px;border:1px solid #7fd4ff;border-radius:50%;background:#0a64cf;box-shadow:0 0 0 4px rgba(10,98,207,.22),0 0 18px 5px #138cff;transform:translateY(-50%);transition:top .7s cubic-bezier(.16,1,.3,1)}.chapter-rail li{position:relative;z-index:3;display:flex;align-items:center;gap:17px;height:18px;color:#edf3fb;transition:color .5s ease,text-shadow .5s ease}.chapter-rail li i{width:15px;height:15px;border:1px solid #eef7ff;border-radius:50%;background:#061a38;transition:opacity .35s ease}.chapter-rail li.active{color:#54baff;text-shadow:0 0 12px rgba(45,155,255,.75)}.chapter-rail li.active i{opacity:0}.chapter-rail li b{font-weight:400}.rail-top,.rail-next{text-align:center;line-height:1.6}.rail-next{margin-left:4px}
.detail-layer{--detail-reveal:0;position:absolute;z-index:3;left:clamp(34px,7.2vw,138px);top:50%;width:min(35vw,540px);color:#eef5ff;pointer-events:none}.detail-tagline{margin:0;color:#58c4ff;font:clamp(12px,1.05vw,17px) JetBrains,monospace;letter-spacing:.16em;opacity:var(--detail-reveal);transform:translateY(calc((1 - var(--detail-reveal)) * 25px));filter:blur(calc((1 - var(--detail-reveal)) * 8px))}.detail-rule{display:block;width:calc(var(--detail-reveal) * 46px);height:2px;margin:18px 0 27px;background:#4fc4ff;box-shadow:0 0 14px rgba(34,164,255,.65)}.detail-summary{margin:0;font-size:clamp(13px,1vw,17px);line-height:1.72;opacity:var(--detail-reveal);clip-path:inset(0 calc((1 - var(--detail-reveal)) * 100%) 0 0);transform:translateY(calc((1 - var(--detail-reveal)) * 32px))}.detail-explore{display:flex;align-items:center;gap:17px;width:max-content;margin-top:45px;font:12px JetBrains,monospace;letter-spacing:.12em;opacity:var(--detail-reveal);transform:translateY(calc((1 - var(--detail-reveal)) * 40px));pointer-events:auto}.detail-explore b{display:grid;place-items:center;width:46px;height:46px;border:1px solid #67c8ff;border-radius:50%;color:#67c8ff;font-size:24px;font-weight:400;box-shadow:0 0 0 0 rgba(28,144,255,0),inset 0 0 18px rgba(31,127,255,.1);transition:box-shadow .35s ease,transform .35s ease}.detail-explore i{width:46px;height:1px;background:#55bfff;transform:scaleX(var(--detail-reveal));transform-origin:left}.detail-explore:hover b{transform:translateY(4px);box-shadow:0 0 24px rgba(28,144,255,.38),inset 0 0 18px rgba(31,127,255,.2)}.detail-layer.is-visible{pointer-events:auto}
.detail-warp-wrap{position:relative}.detail-warp-stage{position:absolute;inset:0;opacity:var(--detail-reveal);clip-path:inset(0 calc((1 - var(--detail-reveal)) * 100%) 0 0);transform:translateY(calc((1 - var(--detail-reveal)) * 32px));pointer-events:auto}.warp-text__canvas{position:absolute;inset:0;width:100%;height:100%;cursor:none}.detail-warp-wrap.is-warp-painted .detail-summary{opacity:0}.chapter-rail ol::after{top:var(--rail-position)}
@media(max-width:820px){.chapter-rail{display:none}.detail-layer{left:22px;top:53%;width:calc(100% - 44px)}.detail-tagline{font-size:10px}.detail-summary{font-size:13px}.detail-explore{margin-top:28px}}
.detail-warp-wrap{min-height:clamp(105px,13vh,140px)}
.mini-pressure{display:inline-flex;align-items:center;font-family:"Roboto Flex",JetBrains,monospace;font-optical-sizing:auto;white-space:nowrap}.mini-pressure-char{display:inline-block;font-variation-settings:"wght" 520,"wdth" 100,"slnt" 0;will-change:font-variation-settings,transform}
.hero-masked-name{position:relative;display:inline-block;isolation:isolate}.hero-masked-name.is-masked{background:none;color:transparent;animation:none}.hero-masked-name.is-masked>span:not(.hero-mask-reveal){visibility:hidden}.hero-mask-defs{position:absolute;width:0;height:0;overflow:hidden;pointer-events:none}.hero-mask-reveal,.hero-mask-clip,.hero-mask-media{position:absolute;inset:0}.hero-mask-media{will-change:transform}.hero-mask-media video{display:block;width:100%;height:100%;object-fit:cover;filter:saturate(1.22) brightness(1.2) contrast(1.04)}
.hero-mask-media{background:linear-gradient(105deg,#f7fbff 0%,#6ea8ff 44%,#edf6ff 72%,#4389ff 100%)}.hero-mask-media video{opacity:.84;mix-blend-mode:screen;filter:saturate(1.35) brightness(1.65) contrast(1.08)}
.page2-trail-canvas{position:absolute;inset:0;z-index:12;width:100%;height:100%;pointer-events:none;mix-blend-mode:screen}.resume-shine-card::after{content:"";position:absolute;z-index:1;top:-45%;bottom:-45%;left:-65%;width:38%;pointer-events:none;background:linear-gradient(90deg,transparent,rgba(176,214,255,.12),rgba(255,255,255,.78),rgba(118,181,255,.18),transparent);filter:blur(1px);transform:skewX(-22deg);opacity:0}.resume-shine-card:hover::after{animation:resumeGlare .9s cubic-bezier(.16,1,.3,1) forwards}.resume-shine-card:hover{border-color:rgba(131,187,255,.46);box-shadow:0 12px 38px rgba(31,108,255,.16),inset 0 0 22px rgba(69,139,255,.06)}@keyframes resumeGlare{0%{left:-65%;opacity:0}18%{opacity:1}100%{left:135%;opacity:0}}
@media(prefers-reduced-motion:reduce){h1{animation:none}.glass-lens-ball{display:none}.pressure-layer{opacity:1;filter:none;clip-path:none;transform:none}.pressure-title .pressure-char{font-variation-settings:"wght" 650,"wdth" 86,"slnt" 0!important}.chapter-rail,.detail-layer{opacity:1;filter:none;transform:none}.mini-pressure-char{font-variation-settings:"wght" 520,"wdth" 100,"slnt" 0!important}.resume-shine-card:hover::after{animation:none}}

/* ===== MY PROCESS — self-drawing rail (Page 2 layer / image 1) ===== */
.process-rail-layer{position:absolute;left:clamp(24px,5.7vw,118px);right:clamp(24px,5.7vw,118px);bottom:clamp(46px,7vh,88px);z-index:6;pointer-events:none;
  opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.8,.2,1)}
#processRail.is-drawing,#processRail.is-drawn{opacity:1;transform:none}
.prl-panel{position:relative;display:grid;grid-template-columns:200px 1fr;gap:0 40px;align-items:center;min-height:118px;padding:20px 30px;
  border-radius:16px;border:1px solid rgba(150,200,255,.16);
  background:linear-gradient(100deg,rgba(11,30,62,.62),rgba(8,28,60,.5));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 26px 70px rgba(0,6,24,.4);backdrop-filter:blur(8px)}
.prl-frame{position:absolute;inset:-1px;width:calc(100% + 2px);height:calc(100% + 2px);pointer-events:none;overflow:visible}
.prl-frame rect{fill:none;stroke:#5cbcff;stroke-width:1.4;vector-effect:non-scaling-stroke;filter:drop-shadow(0 0 6px rgba(74,174,255,.75));stroke-dasharray:100;stroke-dashoffset:100}
#processRail.is-drawing .prl-frame rect{transition:stroke-dashoffset 1.2s cubic-bezier(.65,0,.35,1);stroke-dashoffset:0}
#processRail.is-drawn .prl-frame rect{stroke-dashoffset:0;opacity:.3;transition:opacity .7s ease .1s}
.prl-beam{position:absolute;top:-16px;left:50%;width:2px;height:150%;transform:translateX(-50%) scaleY(0);transform-origin:top center;
  background:linear-gradient(180deg,rgba(120,200,255,0),rgba(160,220,255,.95),rgba(120,200,255,0));
  box-shadow:0 0 24px 5px rgba(90,180,255,.5);opacity:0;pointer-events:none}
#processRail.is-drawing .prl-beam{animation:prlBeam 1.2s ease-out .05s both}
@keyframes prlBeam{0%{opacity:0;transform:translateX(-50%) scaleY(0)}25%{opacity:1}60%{opacity:.9;transform:translateX(-50%) scaleY(1)}100%{opacity:0;transform:translateX(-50%) scaleY(1)}}
.prl-head{position:relative;padding-right:38px;border-right:1px solid rgba(255,255,255,.18)}
.prl-head h3{margin:0;color:#dfeeff;font:22px Anton,Impact,sans-serif;letter-spacing:.04em;clip-path:inset(0 100% 0 0);opacity:0;transition:clip-path .7s ease,opacity .01s}
.prl-head i{display:block;width:40px;height:2px;margin-top:12px;background:#51baff;transform:scaleX(0);transform-origin:left;transition:transform .5s ease .35s}
.prl-steps{display:grid;grid-template-columns:repeat(5,1fr);gap:26px;margin:0;padding:0;list-style:none}
.prl-steps li{position:relative;display:flex;flex-direction:column;gap:6px}
.prl-steps li:not(:last-child)::after{content:"\203A";position:absolute;right:-17px;top:34%;color:rgba(200,225,255,.55);font-size:26px;opacity:0;transition:opacity .45s ease}
.prl-steps b{color:#4aaeff;font:17px Anton,Impact,sans-serif;letter-spacing:.02em;opacity:0;transform:translateY(6px);transition:opacity .4s ease,transform .4s cubic-bezier(.2,.8,.2,1)}
.prl-steps strong{color:#eef4ff;font:17px Anton,Impact,sans-serif;font-weight:400;letter-spacing:.02em;clip-path:inset(0 100% 0 0);opacity:0;transition:opacity .01s,clip-path .55s ease}
.prl-steps span{color:#dbe6f4;font-size:11px;line-height:1.5;opacity:0;transform:translateY(8px);transition:opacity .5s ease,transform .5s ease}
#processRail.is-drawing .prl-head h3,#processRail.is-drawn .prl-head h3{opacity:1;clip-path:inset(0 0 0 0);transition-delay:.15s}
#processRail.is-drawing .prl-head i,#processRail.is-drawn .prl-head i{transform:scaleX(1)}
#processRail.is-drawing .prl-steps b,#processRail.is-drawn .prl-steps b{opacity:1;transform:none;transition-delay:calc(.5s + var(--i) * .12s)}
#processRail.is-drawing .prl-steps strong,#processRail.is-drawn .prl-steps strong{opacity:1;clip-path:inset(0 0 0 0);transition-delay:calc(.57s + var(--i) * .12s)}
#processRail.is-drawing .prl-steps span,#processRail.is-drawn .prl-steps span{opacity:1;transform:none;transition-delay:calc(.65s + var(--i) * .12s)}
#processRail.is-drawing .prl-steps li::after,#processRail.is-drawn .prl-steps li::after{opacity:1;transition-delay:calc(.68s + var(--i) * .12s)}
@media(max-width:1000px){
  .process-rail-layer{left:20px;right:20px;bottom:26px}
  .prl-panel{grid-template-columns:1fr;gap:16px;padding:18px 20px}
  .prl-head{padding:0 0 12px;border-right:0;border-bottom:1px solid rgba(255,255,255,.16)}
  .prl-steps{grid-template-columns:1fr 1fr;gap:14px}
  .prl-steps li:not(:last-child)::after{display:none}
}
@media(prefers-reduced-motion:reduce){
  .process-rail-layer{opacity:1;transform:none}
  .prl-frame,.prl-beam{display:none}
  .prl-head h3,.prl-head i,.prl-steps b,.prl-steps strong,.prl-steps span,.prl-steps li::after{opacity:1;clip-path:none;transform:none}
}

/* ===== MY PROCESS rail — tuning: room, spacing, continuous motion ===== */
/* point 7 needs its own point of travel too: 5.40 viewport-heights of scroll
   (height minus the 100svh sticky stage) for a script that now ends at 4.90 */
@media(min-width:821px){.motion-section{height:810svh}}
/* right-side chapter line: smaller + lifted so NEXT clears the process card */
.chapter-rail{bottom:30%;font-size:11px}
/* de-clutter the text stack above the panel */
.detail-summary{font-size:clamp(12px,.92vw,15px);line-height:1.6}
.detail-tagline{font-size:clamp(11px,.95vw,15px)}
.detail-rule{margin:14px 0 20px}
.detail-explore{margin-top:34px}
/* more compact panel so it stops fighting the copy */
.process-rail-layer{right:clamp(24px,6vw,132px);bottom:clamp(40px,6vh,70px)}
.prl-panel{grid-template-columns:170px 1fr;gap:0 30px;min-height:100px;padding:16px 24px}
.prl-head h3{font-size:19px}
.prl-head i{width:34px;margin-top:10px}
.prl-steps{gap:20px}
.prl-steps b{font-size:15px}
.prl-steps strong{font-size:15px}
.prl-steps span{font-size:10px;line-height:1.45}
.prl-steps li:not(:last-child)::after{right:-13px;font-size:22px}
/* continuous "still being drawn" motion after the reveal completes — GPU-only, pauses during scroll */
#processRail.is-drawn .prl-frame rect{opacity:1;transition:none}
#processRail.is-live .prl-frame rect{stroke-dasharray:15 85;stroke-dashoffset:100;filter:none;animation:prlTrace 4.6s linear infinite}
@keyframes prlTrace{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
#processRail.is-live .prl-beam{opacity:0;animation:prlBeamLoop 3.8s ease-in-out infinite}
@keyframes prlBeamLoop{0%,100%{opacity:0;transform:translateX(-50%) scaleY(.28)}50%{opacity:.6;transform:translateX(-50%) scaleY(1)}}
#processRail.is-live.is-paused .prl-frame rect,
#processRail.is-live.is-paused .prl-beam,
#processRail.is-scrolling .prl-frame rect,
#processRail.is-scrolling .prl-beam{animation-play-state:paused}
@media(prefers-reduced-motion:reduce){#processRail.is-live .prl-frame rect,#processRail.is-live .prl-beam{animation:none}}

#processRail.is-drawing .prl-panel,#processRail.is-drawn .prl-panel{pointer-events:auto}

/* ===== Page 2 copy (points 2 & 3): shrink ~10% + lift the whole stack so
   SCROLL TO EXPLORE always sits above the process rail (layer 4) ===== */
@media(min-width:821px){
  /* the nav is fixed at 70px -- a percentage alone put the kicker underneath
     it on a short viewport, so the floor is in pixels and the percentage only
     takes over once there is room for it */
  .pressure-layer{top:clamp(112px,13%,190px)}
  .pressure-title{font-size:clamp(38px,4.32vw,77px)}
  .detail-layer{top:clamp(300px,42%,520px);width:min(32vw,482px)}
  .detail-tagline{font-size:clamp(10.5px,.85vw,13px)}
  .detail-summary{font-size:clamp(12px,.92vw,14.5px);line-height:1.62}
  .detail-rule{margin:12px 0 16px}
  .detail-warp-wrap{min-height:clamp(90px,10.5vh,122px)}
  .detail-explore{margin-top:14px}
  .detail-explore b{width:38px;height:38px;font-size:20px}
  .detail-explore i{width:38px}
}

/* ===== ease cursor/lens effects off while scrolling (perf) ===== */
#laserCursor,#glassLensBall,.page2-trail-canvas{transition:opacity .12s linear}
html.is-scrolling #laserCursor,
html.is-scrolling #glassLensBall,
html.is-scrolling .page2-trail-canvas{opacity:0!important}
html.is-scrolling #glassLensBall{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}

/* custom cursors removed — restore the pointer on the hero */
.hero-art{cursor:auto}

/* Page 2 mouse effects removed (matching Page 1): keep the normal cursor,
   and let the plain paragraph text show now that the WebGL layer is gone. */
.pressure-layer.is-pressure-ready .pressure-title{cursor:auto}
.detail-warp-wrap .detail-summary{opacity:var(--detail-reveal)}

/* ===== POINT 4 — 3D depth corridor of cards (pure CSS 3D, transform/opacity only) =====
   Cards fly in from the vanishing point (z far) toward the viewer as --depth-reveal
   goes 0 -> 1. Drop an <img> inside .dc-face later to fill each card. */
.depth-corridor{--depth-left:0;--depth-right:0;--depth-reveal:0;position:absolute;inset:0;z-index:4;pointer-events:none;
  perspective:1150px;perspective-origin:50% 47%;
  opacity:1}
.dc-space{position:absolute;inset:0;transform-style:preserve-3d}
.dc-card{position:absolute;left:50%;top:50%;--y:0vh;
  width:clamp(112px,10.5vw,196px);aspect-ratio:9/16;
  transform-style:preserve-3d;will-change:transform,opacity;
  /* a real corridor: the wall sits at a FIXED x, only z changes; perspective
     converges the cards toward the vanishing point on its own.
     --i 0 = nearest the viewer, 5 = deepest.
     --enter 0 -> 1 makes that side rush forward out of the depth. */
  --wall:clamp(300px,40vw,820px);
  --z:calc(var(--i) * -520px);
  --stagger:calc(var(--i) * .14);
  --enter:0;
  opacity:clamp(0, calc((var(--enter) - var(--stagger)) * 3.2), 1);
  transition:opacity .28s linear;
  transform:
    translate3d(calc(var(--wall) * var(--dir)), var(--y), calc(var(--z) + (1 - var(--enter)) * -1350px))
    rotateY(var(--ry))
    translate(-50%,-50%)}
.dc-l{--dir:-1;--ry:20deg;--enter:var(--depth-left)}
.dc-r{--dir:1;--ry:-20deg;--enter:var(--depth-right)}
.dc-face{position:absolute;inset:0;border-radius:8px;overflow:hidden;
  border:1px solid rgba(120,190,255,.85);
  background:linear-gradient(150deg,rgba(30,90,180,.30),rgba(8,28,70,.18) 55%,rgba(20,70,150,.26));
  box-shadow:inset 0 0 22px rgba(70,160,255,.22),0 0 18px rgba(50,140,255,.30);
  transition:transform .45s cubic-bezier(.2,.8,.2,1),border-color .35s ease,box-shadow .35s ease}
/* once the corridor has arrived its cards answer the pointer the same way the
   featured card does — lift, straighten toward the viewer, and light up */
.depth-corridor.is-live{pointer-events:none}
.depth-corridor.is-live .dc-card{pointer-events:auto;cursor:pointer}
.depth-corridor.is-live .dc-card:hover .dc-face{
  transform:translateZ(46px) rotateY(calc(var(--ry) * -0.55)) scale(1.06);
  border-color:#bfe4ff;
  box-shadow:inset 0 0 26px rgba(120,190,255,.34),0 0 34px rgba(70,160,255,.5)}
.dc-face img,.dc-face video{width:100%;height:100%;object-fit:cover;display:block}
.dc-card[style*="--i:2"] .dc-face,
.dc-card[style*="--i:3"] .dc-face{border-color:rgba(110,180,255,.6);box-shadow:inset 0 0 16px rgba(70,160,255,.16),0 0 12px rgba(50,140,255,.2)}
.depth-corridor.is-paused .dc-space{transition:none}
@media(max-width:820px){
  .depth-corridor{perspective:760px}
  .dc-card{width:86px;--wall:46vw;--z:calc(var(--i) * -280px)}
}
@media(prefers-reduced-motion:reduce){
  .dc-space{transform:none}
  .dc-card{opacity:var(--depth-reveal)}
}

/* ===== POINT 3 -> 4 : video out, black page in ===== */
.stage-blackout{--blackout:0;position:absolute;inset:0;z-index:3;overflow:hidden;
  pointer-events:none;background:#01050e;opacity:var(--blackout);will-change:opacity}
/* the S turning over inside the black page: barely visible, just enough that
   the page reads as depth rather than as a flat fill */
/* the wide cut sits back in the frame: scaled down inside a dark surround and
   faded at its edges, so the mark reads as something behind the card rather
   than a wall right behind it */
.blackout-clip{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:var(--backdrop,0);pointer-events:none;
  transform:scale(.78);transform-origin:50% 46%;
  /* dissolved on every edge, so the clip never shows its own frame -- the
     scene just fades into the black page it sits on. The ellipse is taller
     and sits lower than the mark itself so the wet floor and its reflection
     stay in frame instead of being cut off into a black band. */
  -webkit-mask-image:radial-gradient(ellipse 50% 54% at 50% 52%,#000 40%,rgba(0,0,0,.82) 66%,rgba(0,0,0,.38) 84%,transparent 99%);
          mask-image:radial-gradient(ellipse 50% 54% at 50% 52%,#000 40%,rgba(0,0,0,.82) 66%,rgba(0,0,0,.38) 84%,transparent 99%)}
/* just enough of a wash in the middle that the card still separates from it */
.stage-blackout::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 42% 34% at 50% 44%,rgba(1,5,14,.34),transparent 76%)}
/* 4. the pool of blue the card throws down onto the wet floor beneath it --
      it breathes rather than sitting still, and fades in with the clip */
.stage-blackout::before{content:"";position:absolute;inset:0;pointer-events:none;
  z-index:1;opacity:var(--backdrop,0);
  background:
    radial-gradient(ellipse 26% 9% at 50% 74%,rgba(96,182,255,.42),transparent 72%),
    radial-gradient(ellipse 42% 15% at 50% 77%,rgba(46,124,235,.24),transparent 78%);
  animation:pool-breathe 7.5s ease-in-out infinite}
@keyframes pool-breathe{
  0%,100%{transform:scaleX(1) scaleY(1);filter:brightness(1)}
  50%{transform:scaleX(1.07) scaleY(1.14);filter:brightness(1.22)}}
@media(prefers-reduced-motion:reduce){.blackout-clip{display:none}}
/* ===== POINT 5 : everything but the cards leaves ===== */
.motion-stage{--copy-out:0}
.motion-stage .pressure-layer,
.motion-stage .detail-layer,
.motion-stage .process-rail-layer{--copy-fade:calc(1 - var(--copy-out))}
.motion-stage.is-copy-leaving .pressure-layer,
.motion-stage.is-copy-leaving .detail-layer,
.motion-stage.is-copy-leaving .process-rail-layer{
  opacity:var(--copy-fade)!important;
  /* scroll drives this directly — any easing here would make one layer lag
     behind the others instead of all three leaving together */
  transition:none!important;pointer-events:none}

/* ===== POINT 3 — one big featured card, before the black page =====
   Combines two library effects into a single card:
   · Parallax depth card — preserve-3d, every row on its own translateZ plane,
     so tilting toward the cursor parallaxes the layers apart.
   · 3D Pin project card — a perspective-tilted glow beneath it, like the card
     is floating above a beam of light.
   Only transform/opacity animate. */
.hero-card-layer{--hc-reveal:0;--hc-morph:0;--hc-front:0;--hc-swap:0;position:absolute;z-index:5;right:clamp(24px,9vw,190px);top:40%;
  width:clamp(300px,31vw,470px);
  transform:translateY(-50%);pointer-events:none;
  opacity:var(--hc-reveal)}
.hc-wrap{position:relative;perspective:1100px;
  /* rise-in, then collapse toward the corridor's vanishing point so the single
     card visibly turns into the many cards streaming out of that same spot */
  transform:
    translate(calc(var(--hc-morph) * var(--hc-shift, -22vw)), calc((1 - var(--hc-reveal)) * 46px + var(--hc-morph) * 6vh))
    scale(calc((.9 + var(--hc-reveal) * .1) * (1 - var(--hc-morph) * .08)));
  will-change:transform,opacity}
.hero-card-layer.is-live .hc-wrap{pointer-events:auto}

/* ===== POINT 4.5 -> 5 : the card swap =====
   Both cards share one spot inside .hc-wrap. --hc-swap runs 0 -> 1 across that
   half point: card 01 climbs out through the top while card 02 rises into the
   same place from below, so the exit and the entrance are one continuous move.
   The slots carry the swap so .hc-card's own transform stays free for the
   pointer tilt (and its :hover variant) -- preserve-3d lets .hc-wrap's
   perspective reach through the slot to the card, or the tilt would go flat. */
.hc-slot{transform-style:preserve-3d;will-change:transform,opacity}
.hc-slot-1{position:relative;z-index:2;
  transform:translateY(calc(var(--hc-swap) * -132%));
  opacity:clamp(0,calc(1 - var(--hc-swap) * 2.1),1)}
.hc-slot-2{position:absolute;left:0;top:0;z-index:1;width:100%;
  transform:translateY(calc((1 - var(--hc-swap)) * 132%));
  opacity:clamp(0,calc(var(--hc-swap) * 2.1 - 1.1),1)}
/* only whichever card is actually in the spot answers the pointer */
.hero-card-layer .hc-slot-2{pointer-events:none}
.hero-card-layer.is-swapped .hc-slot-1{pointer-events:none}
.hero-card-layer.is-swapped .hc-slot-2{pointer-events:auto}

/* ===== CARD 02 : the SSN plate =====
   Card 02 keeps card 01's invisible skeleton (eyebrow/title/media/grid/bar) so
   it settles at the identical size and the swap lands cleanly. The artwork is
   the design itself, and the card carries no chrome of its own -- the plate's
   own drawn frame IS the card, so no border or glass fights it.
   The two avatars are then laid back over their own circles at full
   resolution, since the plate's copies are only as sharp as the plate. */
.hc-card.hc-card-b{background:none;border:0;backdrop-filter:none;
  -webkit-backdrop-filter:none;box-shadow:none;padding:0}
.hero-card-layer.is-live .hc-card.hc-card-b:hover{border:0;box-shadow:none}

.hc-ssn{position:absolute;inset:0;z-index:3;pointer-events:none;
  transform:translateZ(70px)}
/* top:0/bottom:0 pins the plate to the card's height outright -- no percentage
   height to resolve through the 3D-transformed group, which is what let the
   width win and pushed the plate out of the card. aspect-ratio then derives the
   width, so the artwork can never overflow. */
.ssn-flow{position:absolute;top:0;bottom:0;left:50%;transform:translateX(-50%);
  aspect-ratio:601/1000}
.ssn-plate{position:relative;z-index:2;display:block;width:100%;height:100%;
  object-fit:contain}
/* opaque backing in the plate's own shape, so the ring cards passing behind the
   card stay hidden instead of showing through its transparent interior */
.ssn-fill{position:absolute;inset:0;z-index:1;width:100%;height:100%;
  object-fit:contain}
/* the plate now carries its own avatars and names, correctly labelled, so
   nothing is overlaid on top of it any more -- only .ssn-fill sits behind */
}

.hc-card{--rx:7deg;--ry:-15deg;position:relative;z-index:2;display:block;padding:20px;
  border-radius:20px;border:1px solid rgba(150,200,255,.30);
  background:linear-gradient(155deg,rgba(16,42,86,.80),rgba(6,18,44,.72));
  backdrop-filter:blur(7px);
  box-shadow:0 2px 6px rgba(0,0,0,.4),30px 40px 80px -22px rgba(0,4,20,.65),inset 0 1px 0 rgba(255,255,255,.10);
  transform-style:preserve-3d;
  transform:
    rotateX(calc(var(--rx) * (1 - var(--hc-front))))
    rotateY(calc(var(--ry) * (1 - var(--hc-front))));
  transition:transform .5s cubic-bezier(.2,.8,.2,1),border-color .4s ease}
.hero-card-layer.is-live .hc-card{cursor:pointer}
.hero-card-layer.is-live .hc-card:hover{border-color:rgba(190,225,255,.85);
  box-shadow:0 2px 6px rgba(0,0,0,.4),30px 40px 80px -22px rgba(0,4,20,.65),
             inset 0 1px 0 rgba(255,255,255,.14),0 0 42px rgba(70,160,255,.42)}
/* once it is front-on the tilt is gone, so hover lifts it toward the viewer */
.hero-card-layer.is-live .hc-card:hover{
  transform:
    rotateX(calc(var(--rx) * (1 - var(--hc-front))))
    rotateY(calc(var(--ry) * (1 - var(--hc-front))))
    translateZ(calc(var(--hc-front) * 34px))
    scale(calc(1 + var(--hc-front) * .03))}

/* each row lives on its own depth plane -> real parallax on tilt */
.hc-title{margin:0 0 11px;color:#f1f6ff;font:clamp(29px,2.4vw,38px) Anton,Impact,sans-serif;letter-spacing:.02em;
  line-height:1.08;transform:translateZ(48px)}
.hc-media{aspect-ratio:16/9;margin-bottom:12px;border-radius:12px;overflow:hidden;
  border:1px solid rgba(140,190,255,.24);
  background:linear-gradient(135deg,rgba(40,96,180,.55),rgba(10,24,58,.5) 58%,rgba(70,50,150,.45));
  box-shadow:inset 0 0 26px rgba(90,160,255,.16);
  transform:translateZ(58px)}
.hc-media img{width:100%;height:100%;object-fit:cover;display:block}
/* contain, never cover: the clip is shown whole, at its own framing */
.hc-media video{width:100%;height:100%;object-fit:contain;display:block}
.hc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:11px;
  transform:translateZ(66px)}
.hc-tile{position:relative;aspect-ratio:1.32;border-radius:10px;overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  text-align:center;padding:6px;
  border:1px solid rgba(120,190,255,.26);
  background:
    linear-gradient(rgba(130,195,255,.055) 1px,transparent 1px) 0 0/100% 7px,
    linear-gradient(90deg,rgba(130,195,255,.055) 1px,transparent 1px) 0 0/7px 100%,
    linear-gradient(160deg,rgba(14,38,78,.9),rgba(5,13,32,.92));
  box-shadow:inset 0 0 22px rgba(60,150,255,.14),0 6px 16px -8px rgba(0,0,0,.6)}
/* the hairline that runs along the top edge of each readout */
.hc-tile::before{content:"";position:absolute;left:14%;right:14%;top:0;height:1px;
  background:linear-gradient(90deg,transparent,#6fc6ff,transparent);opacity:.85}
.hc-tile b{color:#eaf4ff;font:clamp(15px,1.5vw,24px) Anton,Impact,sans-serif;letter-spacing:.03em;
  text-shadow:0 0 12px rgba(90,180,255,.55)}
.hc-tile i{color:#8fb2d6;font:normal clamp(7px,.58vw,9.5px) JetBrains,monospace;
  letter-spacing:.13em;line-height:1.25;text-transform:uppercase}
.hc-bar{display:flex;align-items:center;gap:7px;transform:translateZ(80px)}
.hc-tag{padding:5px 10px;border:1px solid rgba(255,255,255,.16);border-radius:999px;
  background:rgba(4,12,30,.55);font:9px JetBrains,monospace;letter-spacing:.08em;color:#cfdcee}
.hc-link{margin-left:auto;color:#8ccaff;font:10px JetBrains,monospace;letter-spacing:.1em;white-space:nowrap}
.hc-link b{display:inline-block;transition:transform .3s ease}
.hero-card-layer.is-live .hc-card:hover .hc-link b{transform:translate(3px,-3px)}

/* 3D-pin beam of light under the card */
.hc-glow{position:absolute;left:50%;top:100%;margin-top:-6px;z-index:1;width:80%;height:96px;
  transform-origin:center top;
  transform:translateX(-50%) rotateX(70deg) scale(calc(.8 + var(--hc-reveal) * .2));
  background:radial-gradient(ellipse at center,rgba(140,200,255,.62),rgba(90,160,255,.16) 55%,transparent 76%);
  filter:blur(3px);opacity:calc(var(--hc-reveal) * (1 - var(--hc-morph) * .55) * .9);pointer-events:none;
  animation:hcGlowPulse 3.4s ease-in-out infinite}
@keyframes hcGlowPulse{0%,100%{opacity:calc(var(--hc-reveal) * (1 - var(--hc-morph) * .55) * .62)}50%{opacity:calc(var(--hc-reveal) * (1 - var(--hc-morph) * .55) * .95)}}
.hero-card-layer:not(.is-live) .hc-glow{animation-play-state:paused}

@media(max-width:1000px){
  .hero-card-layer{right:20px;top:34%;width:min(260px,52vw)}
  .hc-title{font-size:23px}.hc-media{height:80px}
}
@media(max-width:820px){.hero-card-layer{display:none}}
@media(prefers-reduced-motion:reduce){
  .hc-wrap{transform:none}
  .hc-glow{animation:none}
  .hc-card{transition:none}
}

/* ===== POINT 5 — what I do: four big laser-lit headings over the corridor ===== */
.stage-headline{--sh-reveal:0;position:absolute;z-index:6;left:50%;bottom:6%;
  width:min(1560px,94vw);transform:translateX(-50%);text-align:center;pointer-events:none;
  opacity:var(--sh-reveal)}
.sh-kicker{display:flex;align-items:center;justify-content:center;gap:14px;
  margin:0 0 20px;color:#7fc0ff;font:11px JetBrains,monospace;letter-spacing:.2em;
  opacity:clamp(0,calc(var(--sh-reveal) * 2.4),1)}
.sh-kicker i{width:38px;height:1px;background:#5cb9ff}
.sh-list{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(16px,2.4vw,44px);margin:0}
.sh-list span{position:relative;display:block;
  font:clamp(16px,2.1vw,35px)/1.1 Anton,Impact,sans-serif;letter-spacing:.03em;white-space:nowrap;
  color:#eef6ff;
  /* laser glow: layered text-shadows only — no filter, so it stays cheap */
  text-shadow:
    0 0 4px rgba(190,225,255,.95),
    0 0 14px rgba(90,175,255,.75),
    0 0 34px rgba(40,130,255,.55),
    0 0 72px rgba(20,90,220,.40);
  opacity:clamp(0,calc((var(--sh-reveal) - var(--n) * .13) * 3.4),1);
  transform:translateY(calc((1 - clamp(0,calc((var(--sh-reveal) - var(--n) * .13) * 3.4),1)) * 22px));
  will-change:opacity,transform}
/* thin laser rule that draws itself under each line */
.sh-list span::after{content:"";position:absolute;left:50%;bottom:-4px;height:1px;
  width:calc(clamp(0,calc((var(--sh-reveal) - var(--n) * .13 - .06) * 3.4),1) * 100%);
  transform:translateX(-50%);
  background:linear-gradient(90deg,transparent,#7fd0ff,transparent);
  box-shadow:0 0 10px rgba(90,180,255,.9)}
.sh-sub{margin:26px 0 0;color:#a9bdd6;font:11px JetBrains,monospace;letter-spacing:.14em;
  opacity:clamp(0,calc((var(--sh-reveal) - .62) * 2.8),1)}
@media(max-width:1000px){.stage-headline{bottom:6%;width:94vw}.sh-list{gap:14px}.sh-list span{font-size:clamp(12px,3vw,18px)}}
@media(prefers-reduced-motion:reduce){.sh-list span{transform:none}}

/* ===== POINT 5 — the featured card becomes a wide split panel =====
   Same glass shell, same position: the stacked view cross-fades out and a
   media-left / services-right layout takes its place as --hc-morph goes 0 -> 1. */
.hc-card{overflow:hidden}
.hc-title,.hc-media,.hc-grid,.hc-bar{
  opacity:calc(1 - var(--hc-morph) * 1.6);
  transition:opacity .2s linear}

.hc-split{position:absolute;inset:0;display:grid;grid-template-columns:minmax(0,1fr);
  align-content:center;gap:clamp(12px,1.4vw,18px);padding:clamp(14px,1.3vw,20px);align-items:start;
  opacity:clamp(0,calc((var(--hc-morph) - .55) * 2.6),1);
  pointer-events:none;transform:translateZ(70px)}
.hc-split-media{position:relative;border-radius:12px;overflow:hidden;
  width:100%;aspect-ratio:16/9;
  border:1px solid rgba(140,190,255,.28);
  background:linear-gradient(135deg,rgba(40,96,180,.55),rgba(10,24,58,.5) 58%,rgba(70,50,150,.45));
  box-shadow:inset 0 0 26px rgba(90,160,255,.18)}
.hc-split-media video,.hc-split-media img{width:100%;height:100%;object-fit:cover;display:block}
.hc-split-copy{min-width:0}
/* the same rule the 02 / SERVICES kicker on the motion stage uses, so the two
   read as the same label in two places */
.hc-split-kicker{display:flex;align-items:center;justify-content:center;gap:14px;
  margin:20px 0 0;color:#7fc0ff;font:11px JetBrains,monospace;letter-spacing:.2em}
.hc-split-kicker i{flex:0 0 auto;width:38px;height:1px;background:#5cb9ff}
.hc-split-text{margin:0 0 clamp(10px,1vw,14px);color:#dce8f8;
  font-family:JetBrains,monospace;font-size:clamp(9px,.72vw,12px);
  letter-spacing:.02em;line-height:1.72}
.hc-split-tags{display:flex;flex-wrap:wrap;gap:5px}
.hc-split-tags span{padding:4px 9px;border:1px solid rgba(255,255,255,.16);border-radius:999px;
  background:rgba(4,12,30,.55);font:8.5px JetBrains,monospace;letter-spacing:.06em;color:#cfdcee;
  white-space:nowrap}
@media(max-width:1000px){
  .hc-split{grid-template-columns:minmax(0,.8fr) minmax(0,1fr);padding:12px;gap:10px}
  .hc-split-text{font-size:10.5px}
}

/* ==================== FULL PAGE SHELL ====================
   Hero, work grid, about and contact wrapped around the motion system.
   Reveals are one-shot; nothing keeps animating after it has played. */
body{background:#02060f}
[data-reveal]{opacity:0;transform:translateY(22px);
  transition:opacity .7s ease,transform .7s cubic-bezier(.2,.8,.2,1);
  transition-delay:calc(var(--n,0) * .07s);will-change:opacity,transform}
[data-reveal].is-in{opacity:1;transform:none}

/* ---- top bar ---- */
.nav{position:fixed;z-index:40;top:0;left:0;width:100%;height:70px;padding:0 clamp(18px,4vw,60px);
  display:flex;align-items:center;justify-content:space-between;
  transition:background .35s ease,border-color .35s ease;
  border-bottom:1px solid transparent}
.nav.is-stuck{background:rgba(2,6,15,.72);backdrop-filter:blur(10px);border-bottom-color:rgba(255,255,255,.09)}
.nav-logo{padding:6px 10px;border:1px solid rgba(255,255,255,.18);border-radius:5px;
  font:700 12px JetBrains,monospace;letter-spacing:.16em;color:#eef4ff}
.nav-links{display:flex;gap:clamp(12px,2vw,30px)}
.nav-links a{color:#9fb0c6;font:11px JetBrains,monospace;letter-spacing:.14em;text-transform:uppercase;
  transition:color .25s ease}
.nav-links a:hover{color:#eef4ff}
.nav-cta{padding:8px 15px;border:1px solid rgba(120,190,255,.4);border-radius:99px;
  font:11px JetBrains,monospace;letter-spacing:.12em;color:#9dd0ff;transition:background .3s,border-color .3s}
.nav-cta:hover{background:rgba(60,150,255,.16);border-color:#9dd0ff}
@media(max-width:760px){.nav-links{display:none}}

/* ---- hero ---- */
.hero{position:relative;min-height:100svh;display:flex;flex-direction:column;justify-content:center;
  padding:110px clamp(22px,7vw,140px) 90px;
  background:
    radial-gradient(1100px 620px at 18% 30%,rgba(20,70,170,.30),transparent 65%),
    radial-gradient(900px 520px at 85% 75%,rgba(70,40,150,.22),transparent 68%),
    #02060f}
.hero-eyebrow{display:flex;align-items:center;gap:11px;margin:0 0 26px;color:#9db2cc;
  font:10px JetBrains,monospace;letter-spacing:.18em}
.hero-eyebrow i{width:7px;height:7px;border-radius:50%;background:#2d84ff;box-shadow:0 0 12px #2d84ff;flex:none}
.hero-name{margin:0 0 20px;font:clamp(54px,8.4vw,132px)/.88 Anton,Impact,sans-serif;letter-spacing:.005em;
  background:linear-gradient(100deg,#fff 0 42%,#8bb6ff 52%,#fff 62% 100%);background-size:250% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent}
.hero-name span{display:block}
.hero-role{margin:0 0 22px;color:#61a0ff;font:700 clamp(13px,1.3vw,19px) JetBrains,monospace;letter-spacing:.06em}
.hero-intro{max-width:600px;margin:0 0 34px;color:#c6d0dd;font-size:clamp(14px,1.15vw,18px);line-height:1.65}
.hero-stats{display:flex;flex-wrap:wrap;gap:clamp(20px,3.4vw,56px);margin:0 0 36px;padding:0;list-style:none}
.hero-stats li{display:flex;flex-direction:column;gap:5px}
.hero-stats b{font:clamp(24px,2.6vw,40px) Anton,Impact,sans-serif;color:#eaf3ff;letter-spacing:.01em}
.hero-stats span{color:#8b9bb0;font:10px JetBrains,monospace;letter-spacing:.12em}
.hero-cta{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:30px}
.btn{display:inline-flex;align-items:center;gap:11px;min-height:52px;padding:0 24px;border-radius:7px;
  font:700 11px JetBrains,monospace;letter-spacing:.11em;transition:transform .3s,box-shadow .3s,background .3s}
.btn:hover{transform:translateY(-2px)}
.btn-solid{background:linear-gradient(135deg,#2676ff,#0c4ee1);color:#fff;
  box-shadow:0 12px 34px rgba(18,103,255,.30)}
.btn-solid:hover{box-shadow:0 16px 44px rgba(18,103,255,.45)}
.btn-ghost{border:1px solid rgba(255,255,255,.18);background:rgba(4,10,24,.5);color:#dfe7f2}
.btn-ghost:hover{border-color:rgba(150,200,255,.6)}
.hero-loc{margin:0;color:#7f8da1;font:10px JetBrains,monospace;letter-spacing:.13em}
.hero-loc span{padding:0 9px;color:#4f80d5}
.hero-scroll{position:absolute;left:50%;bottom:34px;width:24px;height:38px;transform:translateX(-50%);
  border:1px solid rgba(255,255,255,.24);border-radius:99px}
.hero-scroll i{position:absolute;left:50%;top:8px;width:3px;height:7px;border-radius:2px;background:#7fc0ff;
  transform:translateX(-50%);animation:heroScroll 1.9s ease-in-out infinite}
@keyframes heroScroll{0%,100%{transform:translate(-50%,0);opacity:1}55%{transform:translate(-50%,13px);opacity:.2}}

/* ---- shared section head ---- */
.sec-head{margin-bottom:clamp(30px,4vw,58px)}
.sec-kicker{display:flex;align-items:center;gap:12px;margin:0 0 16px;color:#9dd0ff;
  font:10px JetBrains,monospace;letter-spacing:.22em}
.sec-kicker i{width:44px;height:1px;background:linear-gradient(90deg,#5cb9ff,transparent)}
.sec-title{margin:0;font:clamp(30px,4.6vw,68px)/1 Anton,Impact,sans-serif;letter-spacing:.02em;color:#f0f5ff}
.sec-note{margin:16px 0 0;max-width:560px;color:#9dabbe;font-size:13px;line-height:1.7}

/* --- WORK: the heading at display size ---
   The band above the slider was mostly empty, and a 68px heading in it read as
   a label rather than as the opening of the section. The word is set at display
   size instead, one <span> per letter so it can arrive letter by letter and
   carry a light sweep afterwards. `aria-label` on the <h2> keeps it one word to
   a screen reader rather than four. */
/* The letters are spread to the full width of the column rather than set
   solid: four glyphs at any readable size leave most of this band empty, and
   spacing them out is what turns the word into the masthead the section was
   missing. */
.sec-title--giant{display:flex;justify-content:space-between;
  font-size:clamp(76px,15.5vw,240px);line-height:.82;letter-spacing:-.012em}
.gw{display:inline-block;opacity:0;
  /* the sweep is a gradient moving behind the glyphs, not a second copy of the
     text on top of them: one paint, and it stays legible at any size */
  background:linear-gradient(100deg,#cddff3 0%,#f4f8ff 16%,#fff 26%,#f4f8ff 36%,
    #a7bdd6 60%,#cddff3 100%);
  background-size:300% 100%;-webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent}
.is-in .gw{animation:gwIn .95s cubic-bezier(.19,1,.22,1) var(--d,0s) both,
  gwSheen 7s linear calc(var(--d,0s) + .95s) infinite}
@keyframes gwIn{from{opacity:0;transform:translateY(.34em) rotate(2.5deg)}
  to{opacity:1;transform:none}}
@keyframes gwSheen{from{background-position:130% 0}to{background-position:-170% 0}}

/* The note and the scroll cue share the line under the heading, so the cue
   lands in the empty half of that row instead of needing a band of its own. */
/* The cue sits directly under the heading and above the note, on the left --
   the first empty spot the eye lands on after reading the word. */
.projects .scroll-cue{margin-top:clamp(14px,1.6vw,26px)}
/* A visible way down. The slider under it eats vertical scroll gestures, so a
   visitor who lands on it needs something that says the page keeps going. */
.scroll-cue{display:inline-flex;align-items:center;gap:11px;padding:9px 15px 9px 11px;
  border:1px solid rgba(140,195,255,.28);border-radius:999px;background:rgba(10,18,30,.55);
  color:#bcd3ec;font:10px JetBrains,monospace;letter-spacing:.22em;cursor:pointer;
  transition:border-color .3s ease,color .3s ease,transform .3s ease}
.scroll-cue:hover{border-color:rgba(140,195,255,.65);color:#eaf3ff;transform:translateY(2px)}
.scroll-cue-rail{position:relative;width:13px;height:21px;border:1px solid currentColor;
  border-radius:999px;opacity:.8}
.scroll-cue-rail i{position:absolute;left:50%;top:4px;width:2px;height:5px;border-radius:2px;
  background:currentColor;transform:translateX(-50%);animation:cueDrop 1.8s ease-in-out infinite}
@keyframes cueDrop{0%,100%{transform:translate(-50%,0);opacity:0}
  35%{opacity:1}70%{transform:translate(-50%,8px);opacity:0}}
@media(prefers-reduced-motion:reduce){
  .is-in .gw{animation:none;opacity:1}
  .scroll-cue-rail i{animation:none;opacity:1}}
@media(max-width:820px){
  .sec-title--giant{font-size:clamp(58px,19vw,120px)}
  .sec-head-foot{gap:16px}}

/* ---- work grid ---- */
.projects{position:relative;padding:clamp(74px,10vh,130px) clamp(22px,7vw,140px);background:#02060f}
.pj-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:clamp(16px,1.8vw,26px)}
/* Two shapes, so the section reads in formats rather than as one flat grid:
   the pieces shot wide lead in a single row, everything below is cut 9:16.
   In both, the frame is about three quarters of the card and the caption sits
   under it, so the eye lands on the work first. */
/* ---- the showcase: films shown at the size they were shot ----
   One across the full column, then a pair, then one across again. The frame IS
   the card -- the caption lies on it under a scrim -- so nothing is a thumbnail
   and the run never repeats the same rectangle twice in a row. */
.pj-show{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(16px,1.8vw,26px)}
.pj-card--full{grid-column:1 / -1}
.pj-card--full .pj-shot{aspect-ratio:2.35/1}
.pj-card--half .pj-shot{aspect-ratio:16/9}
.pj-card--full,.pj-card--half{position:relative}
/* the caption rides on the film */
.pj-card--full .pj-meta,.pj-card--half .pj-meta{position:absolute;inset:auto 0 0 0;
  z-index:2;padding:clamp(18px,2.2vw,34px) clamp(18px,2.2vw,34px) clamp(15px,1.8vw,26px);
  background:linear-gradient(180deg,transparent,rgba(2,6,16,.55) 45%,rgba(2,6,16,.9))}
.pj-card--full .pj-meta h3{margin:0 0 10px;font-size:clamp(22px,2.4vw,38px);color:#fff}
.pj-card--half .pj-meta h3{margin:0 0 9px;font-size:clamp(18px,1.6vw,25px);color:#fff}
.pj-card--full .pj-num,.pj-card--half .pj-num{margin-bottom:7px;color:#8ec6ff}
.pj-card--full .pj-tag,.pj-card--half .pj-tag{background:rgba(6,14,32,.6);
  border-color:rgba(190,225,255,.4);color:#e6f1ff}
/* the frame lifts a little instead of the whole card sliding */
.pj-card--full:hover,.pj-card--half:hover{transform:none}
.pj-card--full .pj-shot img,.pj-card--full .pj-shot video,
.pj-card--half .pj-shot img,.pj-card--half .pj-shot video{
  transition:transform .8s cubic-bezier(.2,.8,.2,1)}
.pj-card--full:hover .pj-shot video,.pj-card--half:hover .pj-shot video{transform:scale(1.03)}

/* ---- the vertical cuts, four across, caption underneath ---- */
.pj-grid--reel{grid-template-columns:repeat(4,minmax(0,1fr));margin-top:clamp(16px,1.8vw,26px)}
.pj-grid--reel .pj-shot{aspect-ratio:9/16}
.pj-grid--reel .pj-meta{padding:12px 14px 14px}
.pj-grid--reel .pj-meta p{margin:0 0 10px;font-size:11.5px;line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pj-grid--reel .pj-meta h3{margin:0 0 6px;font-size:15px}
.pj-grid--reel .pj-num{margin-bottom:5px}
.pj-card{border-radius:15px;overflow:hidden;border:1px solid rgba(255,255,255,.09);
  background:linear-gradient(160deg,rgba(14,32,64,.62),rgba(5,12,28,.55));
  transition:transform .45s cubic-bezier(.2,.8,.2,1),border-color .35s,box-shadow .35s}
.pj-card:hover{transform:translateY(-6px);border-color:rgba(140,195,255,.5);
  box-shadow:0 26px 60px rgba(0,6,26,.6),0 0 34px rgba(50,140,255,.16)}
.pj-shot{position:relative;aspect-ratio:4/3;display:grid;place-items:center;overflow:hidden;
  background:linear-gradient(135deg,rgba(34,80,160,.42),rgba(8,18,44,.5) 58%,rgba(64,44,138,.4));
  border-bottom:1px solid rgba(255,255,255,.07)}
/* drop an img or video straight in here later */
.pj-shot img,.pj-shot video{width:100%;height:100%;object-fit:cover;display:block}
.pj-slot{font:clamp(34px,4vw,58px) Anton,Impact,sans-serif;color:rgba(160,200,255,.14);letter-spacing:.04em}
.pj-meta{padding:17px 18px 20px}
.pj-num{display:block;margin-bottom:8px;color:#5ba8ff;font:10px JetBrains,monospace;letter-spacing:.2em}
.pj-meta h3{margin:0 0 8px;font:17px Anton,Impact,sans-serif;font-weight:400;letter-spacing:.02em;color:#eef4ff}
.pj-meta p{margin:0 0 13px;color:#93a3b8;font-size:12px;line-height:1.62}
.pj-tag{display:inline-block;padding:4px 11px;border:1px solid rgba(255,255,255,.14);border-radius:99px;
  background:rgba(4,12,30,.5);font:9px JetBrains,monospace;letter-spacing:.1em;color:#b9c8dc}

/* ---- about ---- */
.about{padding:clamp(74px,10vh,130px) clamp(22px,7vw,140px);
  background:linear-gradient(180deg,#02060f,#04101f 50%,#02060f)}
.ab-wrap{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:clamp(28px,4vw,70px);
  align-items:start}
.ab-copy p{margin:0 0 18px;color:#c2cfdf;font-size:clamp(13px,1vw,16px);line-height:1.78}
.ab-copy b{color:#eef4ff;font-weight:600}
.ab-skills{margin:0;padding:0;list-style:none;display:grid;gap:1px;background:rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.08);border-radius:13px;overflow:hidden}
.ab-skills li{display:flex;flex-direction:column;gap:6px;padding:16px 18px;background:#040d1c}
.ab-skills b{color:#8ec8ff;font:12px JetBrains,monospace;letter-spacing:.1em;font-weight:600}
.ab-skills span{color:#8e9db1;font-size:12px;line-height:1.6}
/* ---- tools: one horizontal card that runs on its own ----
   A lit capsule on black, with thin diagonal streaks drifting behind the
   names -- the glow lives on the rail itself, so the edge fade that hides
   the loop's seam is applied to an inner track instead of the border. */
.tool-rail{position:relative;display:flex;align-items:center;overflow:hidden;
  margin:clamp(28px,4vw,52px) 0 0;padding:clamp(15px,1.6vw,24px) 0;
  border:1px solid rgba(198,224,255,.55);border-radius:999px;background:#000;
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.06),
    inset 0 0 30px rgba(150,195,255,.10),
    0 0 1px rgba(220,238,255,.9),
    0 0 22px rgba(150,200,255,.28),
    0 0 66px rgba(90,160,255,.16)}
/* the streaks: thin light lines raked across the black, drifting slowly */
.tr-streaks{position:absolute;inset:-60% -30%;pointer-events:none;
  background:repeating-linear-gradient(107deg,
    transparent 0 52px,
    rgba(178,214,206,.11) 52px 53px,
    transparent 53px 118px,
    rgba(150,196,190,.055) 118px 119px,
    transparent 119px 210px);
  filter:blur(.4px);
  animation:tr-drift 30s linear infinite}
@keyframes tr-drift{from{transform:translateX(0)}to{transform:translateX(210px)}}
.tr-track{position:relative;z-index:1;display:flex;align-items:center;
  width:100%;
  /* the two ends dissolve so the loop never shows its seam */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 10%,#000 90%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 10%,#000 90%,transparent)}
.ab-tools{flex:0 0 auto;display:flex;flex-wrap:nowrap;gap:8px;
  margin:0;padding:0 4px;list-style:none;
  animation:tool-rail 34s linear infinite}
.tool-rail:hover .ab-tools{animation-play-state:paused}
.ab-tools li{flex:0 0 auto;padding:7px 14px;white-space:nowrap;
  border:1px solid rgba(255,255,255,.16);border-radius:99px;
  background:rgba(255,255,255,.035);
  font:10px JetBrains,monospace;letter-spacing:.1em;color:#cddcee;
  transition:border-color .35s ease,color .35s ease,background .35s ease,box-shadow .35s ease}
.ab-tools li:hover{border-color:rgba(200,230,255,.75);color:#fff;
  background:rgba(255,255,255,.09);box-shadow:0 0 18px rgba(150,200,255,.3)}
/* the track is printed twice, so shifting by exactly one copy loops seamlessly */
@keyframes tool-rail{from{transform:translateX(0)}to{transform:translateX(-100%)}}
@media(prefers-reduced-motion:reduce){
  .ab-tools,.tr-streaks{animation:none}
  .tr-track{flex-wrap:wrap}
  .ab-tools{flex-wrap:wrap}}
@media(max-width:900px){.ab-wrap{grid-template-columns:1fr}}

/* ---- contact ---- */
.contact{padding:clamp(80px,11vh,150px) clamp(22px,7vw,140px) 0;
  background:radial-gradient(900px 480px at 50% 12%,rgba(24,78,180,.24),transparent 68%),#02060f}
.ct-inner{text-align:center;max-width:760px;margin:0 auto}
.ct-inner .sec-kicker{justify-content:center}
.ct-title{margin:0 0 20px;font:clamp(34px,6vw,88px)/.98 Anton,Impact,sans-serif;letter-spacing:.02em;
  background:linear-gradient(100deg,#fff 30%,#8bb6ff 55%,#fff 80%);-webkit-background-clip:text;
  background-clip:text;color:transparent}
.ct-note{margin:0 0 34px;color:#9dabbe;font-size:13px;line-height:1.7}
.ct-links{display:flex;flex-wrap:wrap;justify-content:center;gap:12px}
.ct-links a{padding:12px 20px;border:1px solid rgba(255,255,255,.14);border-radius:99px;
  background:rgba(4,12,30,.5);font:11px JetBrains,monospace;letter-spacing:.08em;color:#c8d5e6;
  transition:border-color .3s,color .3s,transform .3s}
.ct-links a:hover{border-color:rgba(150,200,255,.65);color:#fff;transform:translateY(-2px)}
.ct-links .ct-primary{background:linear-gradient(135deg,#2676ff,#0c4ee1);border-color:transparent;color:#fff}
.ft{display:flex;flex-wrap:wrap;justify-content:space-between;gap:10px;
  margin-top:clamp(60px,9vh,110px);padding:26px 0;border-top:1px solid rgba(255,255,255,.08);
  color:#6f7c8e;font:10px JetBrains,monospace;letter-spacing:.1em}
@media(prefers-reduced-motion:reduce){.hero-scroll i{animation:none}}

/* ============ seam between the hero and the motion section ============
   The hero sits on #02050c and the motion stage on #03122a, so the join read
   as a hard line. These two long gradients meet in the middle: the hero bleeds
   down into the motion blue, and the stage bleeds up into the hero black. Both
   are plain gradients — no filter: blur — so the blend costs nothing. */
.hero{position:relative}
/* the hero itself dissolves over the motion stage: a mask fades its bottom
   edge to nothing, so the video underneath simply comes through. No edge to
   see, and it is one composited property rather than a stack of overlays. */
.hero{z-index:2;
  -webkit-mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 30vh),rgba(0,0,0,.55) calc(100% - 12vh),transparent 100%);
  mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 30vh),rgba(0,0,0,.55) calc(100% - 12vh),transparent 100%)}

/* Page 2 is pulled up UNDER the hero, so the two never meet at an edge at all.
   The hero simply dissolves away over the top of the motion stage. */
.motion-section{margin-top:-26vh}
/* the hero used to leave a long empty tail before the motion section pulled
   itself up over it -- this trims the tail so the two overlap slightly and the
   stage fades in over the hero instead of after a gap */
.hero{padding-bottom:calc(26vh - 45px)}
/* a gentle, permanent top vignette keeps the video from starting hard-edged;
   it is small enough to read as depth rather than as a band */
.motion-stage::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:11vh;
  pointer-events:none;
  background:linear-gradient(180deg,rgba(1,6,18,.72) 0%,rgba(1,6,18,.28) 52%,rgba(1,6,18,0) 100%)}

/* and the same idea where the motion section hands over to the work grid */
.projects{position:relative}
.projects::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:16vh;
  pointer-events:none;
  background:linear-gradient(180deg,rgba(3,18,42,.85) 0%,rgba(3,18,42,.35) 45%,rgba(3,18,42,0) 100%)}
.projects > *{position:relative;z-index:2}

/* ==================== HERO — the S with the glass lens ====================
   The state that worked: the letter sits still on its own on the right, and a
   glass ball follows the cursor over it, bending what is behind through an SVG
   displacement map (built in glass-lens.js). No card, no float, no crop. */
.hero{overflow:hidden;background-color:#02050c}
.hero > *:not(.hero-art){position:relative;z-index:2}

.hero-art{position:absolute;z-index:1;right:clamp(28px,6vw,150px);top:50%;
  height:min(78vh,880px);width:auto;aspect-ratio:900/1376;
  transform:translateY(-50%);
  /* an old .hero-art rule earlier in this file paints a solid #02040a box and
     clips it — both have to be cleared or the transparent PNG reads as a card */
  background:transparent;overflow:visible;
  -webkit-tap-highlight-color:transparent;
  /* its own stacking context, so the lens samples the letter rather than the
     whole page — that is what keeps it smooth */
  isolation:isolate;
  opacity:0;transition:opacity 1s ease .2s}
.hero-art.is-in{opacity:1}

/* Two S monograms stacked on exactly the same box: the metallic one is what
   you see, the blue/white swirl one is hidden behind it and is NEVER visible
   at rest. It is painted above the metal but masked down to a single circle
   parked on the cursor, so the only place it exists is inside the glass ball
   -- move the mouse and the second S is what the lens finds underneath.
   --lens-x/--lens-y/--lens-r are written by glass-lens.js in px, relative to
   .hero-art; the mask is soft at the rim so the swirl never shows a hard
   cut-out edge inside the glass. */
.hero-art{--lens-x:-999px;--lens-y:-999px;--lens-r:0px}
.art-under{position:absolute;z-index:2;inset:0;width:100%;height:100%;
  pointer-events:none;user-select:none;
  object-fit:cover;object-position:center;
  opacity:0;transition:opacity .4s ease;
  filter:saturate(1.08) brightness(1.02);
  -webkit-mask-image:radial-gradient(circle var(--lens-r) at var(--lens-x) var(--lens-y),#000 62%,rgba(0,0,0,.55) 84%,transparent 100%);
  mask-image:radial-gradient(circle var(--lens-r) at var(--lens-x) var(--lens-y),#000 62%,rgba(0,0,0,.55) 84%,transparent 100%)}
.hero-art.is-lens-on .art-under{opacity:1}

.art-img{position:absolute;inset:0;z-index:1;width:100%;height:100%;object-fit:contain;object-position:center}

.art-glow{position:absolute;inset:-10%;z-index:-1;pointer-events:none;opacity:.55;
  background:radial-gradient(circle at 50% 45%,rgba(11,95,255,.35),transparent 65%);
  filter:blur(30px)}

.glass-lens-ball{position:absolute;z-index:6;left:0;top:0;
  width:44%;aspect-ratio:1;max-width:270px;border-radius:50%;
  transform:translate3d(0,0,0) translate(-50%,-50%);pointer-events:none;
  will-change:transform;
  opacity:0;transition:opacity .4s ease;
  backdrop-filter:url(#glassLensDistort) saturate(1.15) brightness(1.05);
  -webkit-backdrop-filter:blur(.3px);
  box-shadow:
    inset -18px -22px 40px rgba(0,0,0,.35),
    inset 14px 16px 30px rgba(255,255,255,.35),
    inset 0 0 0 1px rgba(255,255,255,.25),
    0 20px 45px rgba(0,0,0,.5)}

/* the lens is the one costly thing here, so it never runs while the hero is
   off screen or while the page is being scrolled */
.hero-art.is-paused .art-under,
html.is-scrolling .art-under{opacity:0!important}
.hero-art.is-paused .glass-lens-ball,
html.is-scrolling .glass-lens-ball{opacity:0!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}

/* keep the copy clear of the letter */
.hero-eyebrow,.hero-name,.hero-stats,.hero-cta{max-width:min(980px,54vw)}
.hero-intro,.hero-loc{max-width:min(620px,42vw)}

@media(max-width:1000px){
  .hero-art{height:min(54vh,460px);right:4vw;opacity:.38}
  .hero-art.is-in{opacity:.4}
  .hero-eyebrow,.hero-name,.hero-stats,.hero-cta,.hero-intro,.hero-loc{max-width:none}
}
@media(max-width:640px){.hero-art{display:none}}
@media(prefers-reduced-motion:reduce){.glass-lens-ball{transition:none}.art-under{display:none}}


/* ==================== POINT 6 -> 7 : the ring ====================
   Cards ride a wide, shallow ellipse whose top passes behind the centre card:
   each one rises out of the lower left, crosses the middle behind the card and
   drops away to the lower right. ring-cards.js solves the ellipse and writes
   the transform; everything here is just the look of a card.
   z-index 4 keeps the whole wheel under the centre card (z-index 5), which is
   what makes them read as coming out from behind it. */
.ring-layer{position:absolute;inset:0;z-index:4;pointer-events:none;
  overflow:visible}
.ring-card{position:absolute;left:50%;top:50%;
  width:clamp(196px,19.5vw,368px);aspect-ratio:3/4;
  border-radius:clamp(10px,1vw,18px);overflow:visible;
  opacity:0;will-change:transform,opacity;
  box-shadow:0 30px 70px -20px rgba(0,4,20,.75),
             inset 0 0 0 1px rgba(255,255,255,.10)}
/* placeholder fills -- swap each one for a real <img> when the work is ready.
   Every card is the same size; only the fill differs. */
.ring-card span{position:absolute;inset:0;display:block;
  border-radius:inherit;overflow:hidden}
/* the one card that carries real work rather than a colour fill */
.rc-video{width:100%;height:100%;display:block;object-fit:cover}
/* the name rides ABOVE its card, not inside it -- the card stays a clean plate
   of colour and the word sits over it, lit, so it carries the eye as the wheel
   sweeps past. overflow on .ring-card is clipped, so the label is a sibling
   layer pinned to the card's top edge. */
.ring-card b{position:absolute;left:50%;bottom:calc(100% + clamp(14px,1.4vw,26px));
  z-index:3;transform:translateX(-50%);
  font:clamp(17px,1.75vw,31px)/1.05 Anton,Impact,sans-serif;letter-spacing:.045em;
  text-transform:uppercase;white-space:nowrap;color:#ffffff;
  text-shadow:0 0 6px rgba(255,255,255,.55),
              0 0 22px rgba(130,190,255,.85),
              0 0 52px rgba(60,140,255,.6),
              0 4px 16px rgba(0,4,18,.8)}
/* a thin lit rule under the word, drawn out from the middle */
.ring-card b::after{content:"";position:absolute;left:50%;right:auto;bottom:-8px;
  width:64%;height:1px;transform:translateX(-50%);
  background:linear-gradient(90deg,transparent,#9fd4ff,transparent);
  box-shadow:0 0 10px rgba(120,190,255,.9)}
.rc1 span{background:linear-gradient(150deg,#2f6df0,#0d1f52)}
.rc2 span{background:linear-gradient(150deg,#e0567f,#3a1140)}
.rc3 span{background:linear-gradient(150deg,#f0a63a,#4a2208)}
.rc4 span{background:linear-gradient(150deg,#22c3a6,#062f36)}
.rc5 span{background:linear-gradient(150deg,#8a5cf6,#1d1046)}
.rc6 span{background:linear-gradient(150deg,#4ea8ff,#08203f)}

@media(max-width:820px){.ring-layer{display:none}}
@media(prefers-reduced-motion:reduce){.ring-layer{display:none}}

/* ==================== 03 / CAPABILITIES ====================
   A wide intro card (copy left, device right), the three service cards, the two
   process cards, then the flowing band that hands over to the work section. */
/* no hard seam with the motion section above -- the band of flowing rows sits
   right on the join and the ground colour dissolves through it */
.capes{position:relative;padding:clamp(46px,6vh,84px) clamp(22px,7vw,140px) 0;
  background:linear-gradient(180deg,#020a18,#02060f 22%)}

.cap-wide{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.62fr);
  gap:clamp(24px,3vw,56px);align-items:center;overflow:hidden;
  margin-bottom:clamp(16px,1.8vw,26px);padding:clamp(26px,3vw,52px);
  border:1px solid rgba(255,255,255,.09);border-radius:18px;
  background:linear-gradient(150deg,rgba(10,22,46,.72),rgba(3,7,16,.8))}
.cw-copy h3{margin:0 0 12px;font:clamp(26px,2.9vw,44px)/1.06 Anton,Impact,sans-serif;
  letter-spacing:.02em;color:#f0f5ff}
.cw-copy h3 span{color:#7fc0ff}
/* the strapline under the title: smaller, quieter, sets up the paragraphs */
.cw-copy > p.cw-role{margin:-4px 0 15px;max-width:none;color:#9fb6d4;
  font:clamp(11px,.86vw,13px) JetBrains,monospace;letter-spacing:.11em}
.cw-copy > p{margin:0;max-width:60ch;color:#9dabbe;font-size:clamp(12.5px,1vw,15px);
  line-height:1.62}
/* the block runs to three paragraphs now, so they need air between them */
.cw-copy > p + p:not(.cw-markets){margin-top:clamp(9px,.8vw,12px)}
/* `.cw-copy > p` outranks `.cw-markets`, so its own margin never applied */
.cw-copy > p.cw-markets{margin-top:clamp(26px,2.8vw,38px)}
.cw-meta{display:flex;flex-wrap:wrap;gap:clamp(24px,3vw,50px);
  margin:clamp(18px,1.9vw,26px) 0 0;padding:0;list-style:none}
/* each figure sits under its own lit rule, the way the section kickers do */
.cw-meta li{display:flex;flex-direction:column;gap:6px;padding-top:10px;
  border-top:1px solid rgba(120,175,240,.28)}
.cw-meta b{font:clamp(34px,3.6vw,56px)/.92 Anton,Impact,sans-serif;
  letter-spacing:.01em;color:#eaf2fb;
  background:linear-gradient(168deg,#ffffff 12%,#a8d2ff 92%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent}
.cw-meta span{color:#8fa6c2;font:clamp(9.5px,.78vw,11.5px) JetBrains,monospace;
  letter-spacing:.16em;text-transform:uppercase}
/* the one claim the whole section is building to, so it is allowed to shout */
.cw-copy > p.cw-lead{margin:clamp(14px,1.4vw,19px) 0 0;padding-left:clamp(13px,1.2vw,18px);
  max-width:62ch;border-left:2px solid #5cb9ff;color:#cfe2fa;
  font-size:clamp(13px,1.06vw,16px);line-height:1.68}
.cw-copy > p.cw-lead b{font-weight:600;color:#fff}

/* the four disciplines the figure above is counting, named out loud */
.cw-disciplines{display:flex;flex-wrap:wrap;align-items:center;
  gap:clamp(7px,.75vw,11px);margin:clamp(11px,1.1vw,15px) 0 0;padding:0;list-style:none}
.cw-disciplines li{position:relative;padding:7px 14px;border-radius:999px;
  border:1px solid rgba(120,175,240,.34);background:rgba(10,26,56,.5);
  color:#d3e4fa;font:clamp(10px,.8vw,12px) JetBrains,monospace;letter-spacing:.09em;
  white-space:nowrap}
/* 3D Web is the headline discipline, so it is bigger and lit */
.cw-disciplines li.is-lead{padding:11px 20px;
  border-color:rgba(120,190,255,.85);
  background:linear-gradient(150deg,rgba(28,92,180,.55),rgba(10,30,68,.6));
  color:#fff;font-size:clamp(12px,1.02vw,15px);font-weight:600;letter-spacing:.11em;
  box-shadow:0 0 0 1px rgba(92,185,255,.18),0 0 26px rgba(60,150,255,.3)}
.cw-markets{margin:clamp(24px,2.6vw,36px) 0 0;color:#6f7d90;
  font:10px JetBrains,monospace;letter-spacing:.1em;line-height:1.7}

/* service cards under the studio block — the art is a real image, the copy
   underneath stays live HTML so it reflows and stays readable */
.cw-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:clamp(14px,1.6vw,22px);margin:0 0 clamp(16px,1.8vw,26px);padding:0;list-style:none}
.cw-cards li{display:flex;flex-direction:column;overflow:hidden;
  border:1px solid rgba(255,255,255,.09);border-radius:16px;
  background:linear-gradient(160deg,rgba(12,26,52,.6),rgba(3,7,16,.55));
  transition:border-color .4s ease,transform .5s cubic-bezier(.2,.8,.2,1),
             box-shadow .5s cubic-bezier(.2,.8,.2,1)}
.cw-cards li:hover{border-color:rgba(150,200,255,.38);transform:translateY(-4px);
  box-shadow:0 22px 50px -28px rgba(90,150,255,.55)}
.cwc-shot{display:block;position:relative;aspect-ratio:4/3;overflow:hidden;
  background:#04070f}
.cwc-shot img{width:100%;height:100%;display:block;object-fit:cover;
  object-position:50% 50%;transform:scale(1.02);
  transition:transform .7s cubic-bezier(.2,.8,.2,1)}
/* card 01's artwork has no number or badge baked into it, so it gets the same
   two drawn on, matched to the ones in the other two frames */
.cwc-num{position:absolute;left:clamp(14px,1.5vw,22px);top:clamp(10px,1.1vw,17px);
  color:#fff;font:clamp(16px,1.45vw,22px)/1 Inter,Arial,sans-serif;font-weight:500;
  letter-spacing:.01em;text-shadow:0 2px 14px rgba(0,0,0,.55)}
.cwc-icon{position:absolute;left:clamp(14px,1.5vw,22px);bottom:clamp(12px,1.3vw,20px);
  display:flex;align-items:center;justify-content:center;
  width:clamp(30px,2.7vw,40px);aspect-ratio:1;border-radius:clamp(8px,.8vw,11px);
  border:1px solid rgba(255,255,255,.16);background:rgba(10,16,30,.5);
  backdrop-filter:blur(7px);color:#fff}
.cwc-icon svg{width:56%;height:56%}
.cw-cards li:hover .cwc-shot img{transform:scale(1.06)}
.cwc-shot::after{content:"";position:absolute;inset:auto 0 0;height:42%;
  background:linear-gradient(180deg,rgba(3,7,16,0),rgba(3,7,16,.92))}
.cwc-body{display:flex;align-items:flex-start;gap:clamp(12px,1.3vw,20px);
  padding:clamp(14px,1.4vw,20px) clamp(16px,1.5vw,22px) clamp(16px,1.6vw,22px)}
.cwc-head{flex:1 1 auto;min-width:0;display:block}
.cwc-tags{flex:0 0 auto;display:flex;flex-direction:column;gap:5px;
  padding-top:3px;text-align:right}
.cwc-tags i{font-style:normal;color:#7d8ea4;
  font:clamp(8px,.6vw,9.5px) JetBrains,monospace;letter-spacing:.13em;
  text-transform:uppercase;white-space:nowrap}
.cw-cards b{display:block;margin-bottom:8px;color:#eef4ff;
  font-size:clamp(14px,1.15vw,17px);font-weight:600;line-height:1.25;
  letter-spacing:.01em}
.cwc-copy{display:block;color:#8794a6;font-size:clamp(11.5px,.85vw,13px);
  line-height:1.65}


/* the device is drawn, not photographed */
/* the art column carries no height of its own — the copy sets how tall the
   banner is, and the phone simply runs past the bottom edge and gets trimmed
   by the card's own overflow:hidden */
.cw-art{position:relative;align-self:stretch;min-height:0;
  margin:calc(clamp(26px,3vw,52px) * -1) 0 calc(clamp(26px,3vw,52px) * -1)}
.phone{position:absolute;left:50%;top:clamp(18px,2vw,32px);
  transform:translateX(-50%);
  display:flex;flex-direction:column;
  width:min(100%,clamp(280px,30vw,400px));aspect-ratio:9/17.5;
  padding:11px 9px 12px;border:1px solid rgba(160,205,255,.35);border-radius:38px;
  background:linear-gradient(165deg,#0b1428,#050a16 45%,#080f20);
  box-shadow:0 30px 70px -24px rgba(0,4,20,.85),inset 0 0 0 1px rgba(255,255,255,.05),
             0 0 40px rgba(70,150,255,.14)}
.ph-notch{position:absolute;left:50%;top:8px;width:38%;height:16px;
  transform:translateX(-50%);border-radius:0 0 12px 12px;background:#04070f}
.ph-bar{display:flex;align-items:center;justify-content:space-between;
  padding:2px 10px 12px;color:#cfe0f5;font:9px JetBrains,monospace}
.ph-bar i{width:22px;height:7px;border:1px solid rgba(207,224,245,.5);border-radius:2px}
.ph-body{flex:1;min-height:0;display:flex;flex-direction:column;
  padding:6px 12px 0;text-align:center}
.ph-handle{margin:0 0 10px;color:#7fc0ff;font:9px JetBrains,monospace;letter-spacing:.18em}
.ph-mark{padding:22px 0;border:1px solid rgba(150,200,255,.22);border-radius:14px;
  background:linear-gradient(150deg,rgba(30,84,170,.4),rgba(8,20,48,.5));
  font:clamp(30px,3.4vw,46px) Anton,Impact,sans-serif;letter-spacing:.06em;color:#eaf3ff;
  text-shadow:0 0 26px rgba(80,160,255,.5)}
.ph-screen{position:relative;flex:1;min-height:0;overflow:hidden;
  border:1px solid rgba(150,200,255,.22);
  border-radius:18px;background:linear-gradient(150deg,rgba(30,84,170,.4),rgba(8,20,48,.5))}
.ph-clip{display:block;width:100%;height:100%;object-fit:cover;
  background:#03081a}
.ph-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:5px;margin-top:12px}
.ph-chips span{padding:4px 8px;border:1px solid rgba(255,255,255,.14);border-radius:999px;
  background:rgba(4,12,30,.6);color:#c2d2e6;font:8px JetBrains,monospace;letter-spacing:.06em}
.ph-dock{display:flex;gap:6px;margin-top:12px}
.ph-dock span{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:7px 2px;border:1px solid rgba(150,200,255,.16);border-radius:9px;
  background:rgba(8,18,40,.7);color:#c2d2e6;font:7.5px JetBrains,monospace;
  letter-spacing:.1em}
.ph-dock i{font-style:normal;font-size:11px;line-height:1;color:#7fc0ff}

@media(max-width:900px){
  .cap-wide{grid-template-columns:1fr}
  .cw-art{order:-1}
  .cw-art{position:static;min-height:0;margin:0}
  .phone{width:min(100%,300px);aspect-ratio:9/17.5}
}


/* ==================== FACE VARIANT : the head replaces the two S ====================
   Same hero, same everything else -- only the artwork changes. The clip keeps
   its own 16:9 frame: object-fit:contain means it is never stretched and never
   cropped, so the face holds exactly the proportions it was rendered at. Its
   surround is black, which is the hero's own colour, so the empty left half of
   the frame simply is not there to the eye.
   --face-w is the only size knob; the box derives its height from the aspect. */
.hero-art{--face-w:min(62vw,880px);
  width:var(--face-w);height:auto;aspect-ratio:16/9;
  right:clamp(0px,3vw,60px)}
.art-face{position:absolute;inset:0;width:100%;height:100%;display:block;
  object-fit:contain;pointer-events:none;will-change:transform;
  /* the clip's black is a shade off the hero's, so its frame reads as a faint
     rectangle. A narrow fade band on all four edges dissolves that boundary.
     An ellipse mask was tried first and left the right edge hard -- the head
     sits at 66% across, so any ellipse wide enough to clear it reaches the
     right edge at full opacity. Two crossed linear fades treat every side the
     same and stay well outside the head. */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent),
    linear-gradient(180deg,transparent,#000 8%,#000 92%,transparent);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent),
    linear-gradient(180deg,transparent,#000 8%,#000 92%,transparent);
  mask-composite:intersect}
/* the glow sat behind a tall portrait monogram. The head in this clip is
   centred in its frame -- the earlier clip had it off in the right third, which
   is why this was pushed to 68% before -- so it sits centred again. */
.art-glow{inset:-14% -8%;
  background:radial-gradient(circle at 50% 46%,rgba(11,95,255,.32),transparent 62%)}

@media(max-width:1000px){
  .hero-art{--face-w:min(86vw,620px);height:auto}
}

/* ==================== GAZE : the head follows the pointer ====================
   .face-grid is just the stage that holds
   the single clip. gaze-circle.js creates one .fg-clip inside it and seeks that
   clip by the pointer's angle; the eight-clip version this replaced is gone.

   The four-edge fade is kept from the single-clip version: the render's black
   is a shade off the hero's, so without it the clip's frame reads as a faint
   rectangle sitting on the page. */
.face-grid{position:absolute;inset:0}
/* the shared neutral frame, shown until the clips are in memory and seekable */
.face-grid::before{content:"";position:absolute;inset:0;
  background:url(assets/gaze-neutral-0831.webp) center/contain no-repeat;
  opacity:1;transition:opacity .5s ease;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent),
    linear-gradient(180deg,transparent,#000 8%,#000 92%,transparent);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent),
    linear-gradient(180deg,transparent,#000 8%,#000 92%,transparent);
  mask-composite:intersect}
.face-grid.is-ready::before{opacity:0}
.fg-clip{position:absolute;inset:0;width:100%;height:100%;display:block;
  object-fit:contain;pointer-events:none;
  /* no fade: the swap only ever happens at the shared neutral frame, so a
     hard cut is invisible -- and a fade between two different poses is exactly
     what made it look like one video laid over another */
  opacity:0;
  will-change:transform;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent),
    linear-gradient(180deg,transparent,#000 8%,#000 92%,transparent);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent),
    linear-gradient(180deg,transparent,#000 8%,#000 92%,transparent);
  mask-composite:intersect}
.fg-clip.is-on{opacity:1}

@media(prefers-reduced-motion:reduce){
  /* the script bails out entirely here; show one still frame so the hero is
     not left empty */
  .fg-clip:first-child{opacity:1}
}

/* ==================== FLOWING MENU ====================
   The four capability rows are the seam between the motion section and the
   studio block -- a full-bleed band rather than a card, so the scroll melts
   from one into the other instead of hitting a border.

   The labels are hollow: transparent fill plus a stroke, with an extruded
   second copy behind them. So when the marquee slides in it reads THROUGH the
   letters, which is the whole point of the effect. */
.fm-menu{position:relative;overflow:hidden;
  margin:clamp(56px,6.5vw,96px) calc(clamp(22px,7vw,140px) * -1) 0;
  border-top:1px solid rgba(255,255,255,.08);
  border-bottom:1px solid rgba(255,255,255,.08)}
/* both edges of the band fade into whatever sits above and below it */
.fm-menu::before,.fm-menu::after{content:"";position:absolute;z-index:3;
  left:0;right:0;height:clamp(28px,4vw,54px);pointer-events:none}
.fm-menu::before{top:0;background:linear-gradient(180deg,rgba(2,6,15,.92),transparent)}
.fm-menu::after{bottom:0;background:linear-gradient(0deg,rgba(2,6,15,.92),transparent)}

.fm-item{position:relative;overflow:hidden;
  border-top:1px solid rgba(255,255,255,.07);
  opacity:0;transform:translateY(26px);
  transition:opacity .7s cubic-bezier(.16,1,.3,1) calc(var(--n,0) * .09s),
             transform .7s cubic-bezier(.16,1,.3,1) calc(var(--n,0) * .09s)}
.fm-item.is-in{opacity:1;transform:none}
.fm-item:first-child{border-top:none}

.fm-link{position:relative;z-index:1;
  display:flex;align-items:center;justify-content:center;
  height:clamp(74px,7.6vw,112px);padding:0 20px;
  font:400 clamp(19px,3.1vw,46px)/1 Anton,Impact,sans-serif;
  letter-spacing:.035em;text-transform:uppercase;text-decoration:none;
  white-space:nowrap;
  color:transparent;-webkit-text-fill-color:transparent;
  -webkit-text-stroke:1px rgba(226,240,255,.62);
  transition:-webkit-text-stroke-color .5s ease}
/* the extruded copy sitting a hair below and behind, which is what makes the
   hollow letters read as carved rather than merely outlined */
.fm-link::before{content:attr(data-text);position:absolute;z-index:-1;
  left:50%;top:50%;transform:translate(-50%,calc(-50% + 3px));
  -webkit-text-stroke:1px rgba(90,150,235,.3);
  -webkit-text-fill-color:transparent;pointer-events:none}
.fm-item:hover .fm-link{-webkit-text-stroke-color:rgba(255,255,255,.92)}
.fm-item:hover .fm-link::before{-webkit-text-stroke-color:rgba(4,18,43,.45)}

.fm-marquee{position:absolute;inset:0;overflow:hidden;pointer-events:none;
  background:linear-gradient(120deg,#3d8cff,#7fc0ff 55%,#b9dcff);
  transform:translate3d(0,101%,0);
  transition:transform .6s cubic-bezier(.16,1,.3,1)}
.fm-inner{height:100%;width:100%;overflow:hidden;
  transform:translate3d(0,-101%,0);
  transition:transform .6s cubic-bezier(.16,1,.3,1)}
.fm-track{display:flex;align-items:center;height:100%;width:max-content;
  will-change:transform;animation:fm-scroll 26s linear infinite}
.fm-part{display:flex;align-items:center;flex-shrink:0}
.fm-part b{padding:0 clamp(12px,1.2vw,22px);color:#04122b;
  font:400 clamp(19px,3.1vw,46px)/1 Anton,Impact,sans-serif;letter-spacing:.035em;
  text-transform:uppercase;white-space:nowrap}
.fm-part i{flex-shrink:0;width:clamp(96px,11vw,180px);
  height:clamp(40px,4.4vw,66px);margin:0 clamp(10px,1.1vw,20px);
  border-radius:999px;background-size:cover;background-position:50% 50%}
@keyframes fm-scroll{to{transform:translate3d(-50%,0,0)}}

@media(prefers-reduced-motion:reduce){
  .fm-track{animation:none}
  .fm-marquee,.fm-inner{transition:none}
  .fm-item{opacity:1;transform:none;transition:none}
}
@media(max-width:640px){
  .fm-link{height:clamp(62px,14vw,86px)}
}

/* ===== THE CARDS FLANKING THE CENTRE ONE =====
   Proportions taken off the reference: the left card is the largest of the
   three, the two on the right are a size family of their own, and thin blurred
   plates sit behind each group. Everything is turned on the stage's own
   perspective so the panels read as glass floating in the scene.
   --in runs 0 -> 1 as each one arrives (info-cards.js). */
.info-layer{position:absolute;inset:0;z-index:6;pointer-events:none;
  perspective:1250px;perspective-origin:50% 46%;transform-style:preserve-3d}

.info-card,.ic-ghost{--in:0;position:absolute;opacity:var(--in)}

/* thin lit edge, translucent dark glass, bloom around it */
.info-card{padding:clamp(16px,1.45vw,26px);
  border:1px solid rgba(120,196,255,.80);border-radius:clamp(15px,1.35vw,22px);
  background:linear-gradient(158deg,rgba(16,40,84,.46),rgba(5,13,32,.60));
  -webkit-backdrop-filter:blur(11px) saturate(1.15);
          backdrop-filter:blur(11px) saturate(1.15);
  box-shadow:
    inset 0 1px 0 rgba(190,228,255,.26),
    inset 0 0 26px rgba(46,120,225,.16),
    0 0 1px rgba(150,210,255,.9),
    0 0 18px rgba(70,160,255,.45),
    0 0 54px rgba(40,120,255,.22),
    0 30px 64px -26px rgba(0,4,20,.9)}

/* a light travelling around the card's own edge: a conic sweep clipped to a
   1px ring, so the border itself is what moves rather than anything drawn
   over the content. Each card is offset so the three never pulse together. */
.info-card{isolation:isolate}
.info-card::before{content:"";position:absolute;inset:-1px;z-index:-1;
  border-radius:inherit;pointer-events:none;
  background:conic-gradient(from var(--sweep,0deg),
    transparent 0deg,rgba(150,215,255,0) 48deg,
    rgba(170,225,255,.95) 74deg,rgba(90,180,255,.55) 96deg,
    rgba(150,215,255,0) 130deg,transparent 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  padding:1px;
  animation:card-sweep 6s linear infinite;
  opacity:calc(var(--in,0) * .95)}
.ic-2::before{animation-delay:-2s}
.ic-3::before{animation-delay:-4s}
/* and a soft halo that breathes with it, so the card feels lit rather than drawn */
.info-card::after{content:"";position:absolute;inset:-14px;z-index:-2;
  border-radius:inherit;pointer-events:none;
  background:radial-gradient(60% 55% at 50% 50%,rgba(66,150,255,.30),transparent 72%);
  filter:blur(9px);opacity:calc(var(--in,0) * .9);
  animation:card-halo 5.4s ease-in-out infinite}
.ic-2::after{animation-delay:-1.8s}
.ic-3::after{animation-delay:-3.6s}
@keyframes card-sweep{to{--sweep:360deg}}
@keyframes card-halo{
  0%,100%{transform:scale(.97);opacity:calc(var(--in,0) * .6)}
  50%{transform:scale(1.04);opacity:calc(var(--in,0) * 1)}}
/* --sweep has to be a registered property or the conic angle cannot animate */
@property --sweep{syntax:"<angle>";inherits:false;initial-value:0deg}
@media(prefers-reduced-motion:reduce){
  .info-card::before,.info-card::after,.stage-blackout::before{animation:none}}

/* the decorative plates: softer, blurred, set back */
.ic-ghost{border-radius:clamp(13px,1.2vw,20px);
  border:1px solid rgba(112,182,255,.32);
  background:linear-gradient(158deg,rgba(14,34,72,.26),rgba(4,11,28,.34));
  -webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);
  box-shadow:0 0 16px rgba(60,140,255,.16),0 20px 44px -24px rgba(0,4,20,.7);
  filter:blur(.6px)}

/* --- left group: the biggest card, two plates stepping back behind it --- */
.ic-1{left:12.7%;top:27.5%;width:13.3%;min-height:clamp(210px,34vh,340px);
  transform:translateX(calc((1 - var(--in)) * -52px)) translateZ(30px) rotateY(24deg)}
.g1{left:2.3%;top:33%;width:3.9%;height:26%;
  transform:translateZ(-90px) rotateY(24deg)}
.g2{left:7.6%;top:31%;width:5.4%;height:29.5%;
  transform:translateZ(-45px) rotateY(24deg)}

/* --- right group: a pair one size down, one plate behind them --- */
.ic-2{right:24.3%;top:29.5%;width:10.2%;min-height:clamp(184px,29vh,292px);
  transform:translateX(calc((1 - var(--in)) * 52px)) translateZ(12px) rotateY(-24deg)}
.ic-3{right:11.5%;top:28.4%;width:11.3%;min-height:clamp(196px,31.5vh,314px);
  transform:translateX(calc((1 - var(--in)) * 52px)) translateZ(26px) rotateY(-24deg)}
.g3{right:8.4%;top:32%;width:5%;height:27%;
  transform:translateZ(-70px) rotateY(-24deg)}

.ic-icon{display:block;width:clamp(23px,2vw,33px);color:#93cbff;
  margin-bottom:clamp(15px,1.4vw,25px)}
.ic-icon svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 0 9px rgba(110,185,255,.75))}
.info-card h3{margin:0 0 clamp(12px,1.1vw,19px);
  font:600 clamp(11.5px,.98vw,15px) JetBrains,monospace;letter-spacing:.16em;
  text-transform:uppercase;color:#eef5ff;
  text-shadow:0 0 14px rgba(110,180,255,.4)}
.info-card ul{margin:0;padding:0;list-style:none;display:grid;gap:clamp(9px,.85vw,14px)}
.info-card li{position:relative;padding-left:17px;color:#d7e6f8;
  font-size:clamp(11px,.9vw,14.5px);line-height:1.4}
.info-card li::before{content:"";position:absolute;left:0;top:.5em;
  width:5px;height:5px;border-radius:50%;background:#5cb2ff;
  box-shadow:0 0 9px rgba(92,178,255,.95)}
.ic-chips{display:grid;gap:clamp(7px,.6vw,10px);justify-items:start}
.ic-chips span{padding:6px 13px;border:1px solid rgba(150,205,255,.40);
  border-radius:999px;background:rgba(7,20,46,.5);
  color:#e2eefc;font-size:clamp(10px,.76vw,12.5px);
  box-shadow:0 0 12px rgba(60,140,255,.14)}

@media(max-width:1100px){.info-layer{display:none}}
@media(prefers-reduced-motion:reduce){.info-card,.ic-ghost{transition:none}}

/* Particle Text -- the 03 / APPROACH heading is sampled onto a canvas and
   rebuilt out of particles that gather when the section comes into view. The
   stage takes the space the heading itself would have taken. */
.sec-title-particle{position:relative;line-height:1}
/* the stage is only as wide as the heading needs, so the particles land on the
   left where the Anton heading used to sit rather than centred in the column */
/* the stage reaches past the column on both sides and stands taller than the
   letters, so the scattered particles have somewhere to come from */
.particle-text-stage{position:relative;display:block;
  width:calc(100% + 2 * clamp(30px,7vw,120px));
  margin-inline:calc(-1 * clamp(30px,7vw,120px));
  height:clamp(110px,20vw,300px);cursor:default}
/* the glow is one GPU pass on the canvas instead of a per-particle canvas
   shadow -- at this size that is the difference between 5fps and 60 */
.particle-text__canvas{position:absolute;inset:0;width:100%;height:100%;display:block;
  filter:drop-shadow(0 0 6px rgba(92,185,255,.55)) drop-shadow(0 0 18px rgba(92,185,255,.25))}
.particle-text__sr{position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap}

/* ============================================================
   PHONE ONLY. Every rule below is either a default that hides a
   phone-only element outright, or lives inside
   @media(max-width:820px) -- the desktop layout lives inside
   @media(min-width:821px) and is never read here.
   ============================================================ */

/* the phone menu and the phone story do not exist on desktop */
.nav-toggle{display:none}
.nav-drawer{display:none}
.mobile-story{display:none}

@media(max-width:820px){

  /* ---- 1. a menu you can actually use -------------------- */
  .nav-toggle{display:flex;flex-direction:column;justify-content:center;gap:5px;
    width:46px;height:46px;padding:0 11px;margin-left:10px;
    border:1px solid rgba(120,175,240,.4);border-radius:12px;
    background:rgba(6,14,32,.6);cursor:pointer;-webkit-tap-highlight-color:transparent}
  .nav-toggle i{display:block;height:1.5px;background:#dceaff;border-radius:2px;
    transition:transform .22s ease,opacity .18s ease}
  .nav-toggle[aria-expanded="true"] i:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
  .nav-toggle[aria-expanded="true"] i:nth-child(2){opacity:0}
  .nav-toggle[aria-expanded="true"] i:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

  .nav-drawer{display:flex;flex-direction:column;position:fixed;z-index:60;
    top:70px;left:0;right:0;padding:10px 20px 26px;
    background:rgba(4,10,24,.97);backdrop-filter:blur(16px) saturate(1.3);
    border-bottom:1px solid rgba(120,175,240,.24);
    box-shadow:0 26px 60px rgba(0,4,16,.6)}
  .nav-drawer[hidden]{display:none}
  .nav-drawer a{display:flex;align-items:center;min-height:52px;
    color:#e6f0ff;font:14px JetBrains,monospace;letter-spacing:.14em;
    text-decoration:none;border-bottom:1px solid rgba(120,175,240,.14)}
  .nav-drawer a:last-child{border-bottom:0}
  .nd-cv{margin-top:12px;justify-content:center;border:1px solid rgba(120,175,240,.45);
    border-radius:999px;background:rgba(20,70,150,.3)}
  body.nav-open{overflow:hidden}

  /* ---- 2. the story the sticky stage cannot tell here ----- */
  .mobile-story{display:block;padding:12px 20px 64px;background:#03070f}
  .ms-card{margin-bottom:26px;padding:14px;border-radius:18px;
    border:1px solid rgba(105,165,235,.32);
    background:linear-gradient(160deg,rgba(14,34,70,.72),rgba(5,12,28,.85));
    box-shadow:0 22px 50px rgba(0,5,20,.5)}
  .ms-media{overflow:hidden;border-radius:12px;aspect-ratio:16/9;
    background:#05101f;border:1px solid rgba(120,175,240,.2)}
  .ms-media video{width:100%;height:100%;object-fit:cover;display:block}
  .ms-tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;
    margin:14px 0 0;padding:0;list-style:none}
  .ms-tiles li{padding:12px 8px;border-radius:12px;text-align:center;
    border:1px solid rgba(120,175,240,.2);background:rgba(8,20,44,.6)}
  .ms-tiles b{display:block;color:#fff;font:22px/1 Anton,Impact,sans-serif}
  .ms-tiles span{display:block;margin-top:6px;color:#9fb6d4;
    font:11px JetBrains,monospace;letter-spacing:.05em}
  .ms-copy{margin:14px 0 0;color:#dce8f8;
    font:13px/1.62 JetBrains,monospace;letter-spacing:.01em}
  .ms-tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:14px}
  .ms-tags span{padding:8px 13px;border-radius:999px;
    border:1px solid rgba(255,255,255,.18);background:rgba(4,12,30,.6);
    color:#cfdcee;font:11px JetBrains,monospace;letter-spacing:.06em}
  .ms-kicker{display:flex;align-items:center;justify-content:center;gap:12px;
    margin:20px 0 2px;color:#7fc0ff;font:11px JetBrains,monospace;letter-spacing:.2em}
  .ms-kicker i{flex:1 1 auto;max-width:52px;height:1px;background:#5cb9ff}

  .ms-info{display:grid;gap:14px}
  .ms-info-card{padding:18px;border-radius:16px;
    border:1px solid rgba(105,180,255,.55);
    background:linear-gradient(165deg,rgba(12,38,84,.6),rgba(4,10,26,.75));
    box-shadow:0 0 24px rgba(50,140,255,.14)}
  .ms-info-card h3{margin:0 0 12px;color:#eaf3ff;
    font:15px JetBrains,monospace;letter-spacing:.16em;text-transform:uppercase}
  .ms-info-card ul{margin:0;padding-left:18px;color:#c9dcf3;
    font-size:14px;line-height:1.85}
  .ms-chips{display:flex;flex-wrap:wrap;gap:8px}
  .ms-chips span{padding:8px 14px;border-radius:999px;
    border:1px solid rgba(120,175,240,.4);background:rgba(8,24,54,.6);
    color:#d6e6fb;font:12px JetBrains,monospace}

  /* ---- 3. the sticky stage becomes an ordinary stack -------
       On desktop these four layers are absolutely placed inside a
       100svh sticky stage and revealed by scroll. There is no sticky
       stage here, so they were all landing on top of each other and
       spilling out of the section. On phones they just stack. */
  .motion-section{height:auto;min-height:0}
  .motion-stage{position:relative;height:auto;min-height:0;padding:96px 0 44px}
  .pressure-layer,.detail-layer,.process-rail-layer,.stage-headline{
    position:static;inset:auto;width:auto;margin:0 20px 36px;
    transform:none;opacity:1;filter:none;clip-path:none}
  .process-rail-layer{margin-bottom:0}
  .pressure-kicker{font-size:11px}
  /* choreography-only scrims that have nothing to sit over here */
  .stage-blackout,.depth-corridor{display:none}
  /* --detail-reveal is driven by the sticky stage's scroll maths, which
     never runs here, so the copy stayed at opacity 0 in a 240px gap */
  .detail-layer{--detail-reveal:1!important}
  .detail-tagline,.detail-rule,.detail-summary,.detail-explore,
  .stage-headline,.sh-list,.sh-list span{
    opacity:1!important;transform:none!important;clip-path:none!important;filter:none!important}

  /* ---- 4. MY PROCESS readable instead of a crushed column - */
  .prl-panel{display:block;padding:20px 18px}
  .prl-head{margin:0 0 16px;padding:0 0 14px;
    border-right:0;border-bottom:1px solid rgba(120,175,240,.22)}
  .prl-steps{display:grid;grid-template-columns:1fr;gap:16px;padding:0}
  .prl-steps li{padding-left:0}
  .prl-steps li::after{display:none}

  /* ---- 5. things you are meant to be able to tap ----------
       Apple's minimum is 44px; the contact links sat at 40 and the smallest
       labels dropped to 8px, which is below what a phone can render cleanly. */
  .ct-links a{min-height:48px;padding:14px 22px}
  .cw-meta span,.ms-tiles span,.ph-bar b,.ph-handle,
  .hc-tile i,.cwc-tags i,.ab-tools li,.ph-chips span,.ph-dock span,
  .pj-tag,.ms-tags span,.ms-chips span,.hc-tag,.hc-split-tags span,
  .prl-steps li span,.motion-location,.availability{font-size:10.5px}
  .cw-disciplines li,.ic-chips span{font-size:11px}
  .nav-logo{display:flex;align-items:center;min-height:44px;padding:0 12px}
  /* with the links hidden, space-between would strand the CV mid-header */
  .nav-cta{display:flex;align-items:center;min-height:44px;padding:0 16px;margin-left:auto}
  .detail-explore{min-height:44px;align-items:center}
  .hc-tile i,.prl-steps li span{font-size:11px}

  /* ---- 6. the scroll cue stops sitting on the location ---- */
  .hero-scroll{display:none}

  /* the phone mockup was still position:absolute here, so .cw-art measured
     0px tall and the stats underneath ran straight through the artwork */
  .cw-meta{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
  .cw-meta b{font-size:clamp(26px,8vw,34px)}
  .cw-meta span{font-size:10.5px;letter-spacing:.09em}
  .pj-show{grid-template-columns:minmax(0,1fr)}
  .pj-card--half .pj-shot{aspect-ratio:4/3}
  .pj-card--full .pj-shot{aspect-ratio:16/10}
  .pj-grid--reel{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cwc-body{flex-direction:column;gap:12px}
  .cwc-tags{flex-direction:row;flex-wrap:wrap;gap:6px 12px;text-align:left;padding-top:0}
  .cwc-tags i{font-size:10.5px}
  .cw-art{position:static;min-height:0;margin:0 0 26px}
  .phone{position:static;transform:none;margin:0 auto;
    width:min(100%,300px);aspect-ratio:9/17.5}

  /* ---- 7. Particle Text needs width to be legible. At 393px the
       glyphs turn to mush, so the phone gets the real Anton heading
       (the same string the screen reader was already being given). */
  .particle-text-stage{display:none}
  .particle-text__sr{position:static;width:auto;height:auto;overflow:visible;
    clip:auto;clip-path:none;white-space:normal;display:block;
    font:clamp(38px,11.5vw,60px)/1 Anton,Impact,sans-serif;
    letter-spacing:.02em;color:#f0f5ff}
}

/* ---- WORK: wheel rail + coverflow screen + lightbox ------------------- */
/* The list lives outside the video frame, pulled back to the page edge, so
   nothing sits on top of the clip. The negative margin cancels the side
   padding that the section itself sets. */
.pj-stage{position:relative;display:grid;align-items:center;
  grid-template-columns:minmax(260px,29%) 1fr;gap:clamp(18px,2.6vw,46px);
  margin:clamp(26px,3.4vw,48px) calc(-1 * clamp(22px,7vw,140px)) 0;
  padding-left:clamp(16px,2.4vw,44px);outline:none}

/* --- left rail: the option wheel, the copy, the counter --- */
.pjs-rail{position:relative;height:clamp(540px,86vh,860px);min-width:0}
.pjs-wheel{position:absolute;top:0;bottom:150px;left:0;right:0;
  margin:0;padding:0;list-style:none;cursor:grab;touch-action:none;outline:none}
.pjs-wheel:active{cursor:grabbing}
.pjs-opt{position:absolute;top:50%;left:0;
  font:clamp(19px,2.15vw,34px)/1 Anton,Impact,sans-serif;font-weight:400;
  letter-spacing:.015em;text-transform:uppercase;white-space:nowrap;
  color:rgba(196,214,238,.55);transform-origin:left center;user-select:none;
  cursor:pointer;will-change:transform,opacity,filter;transition:color .3s ease}
/* The selected project is lit by a laser scan: a narrow band travels across the
   word, and the letters brighten only where it passes. Two layers do it --
   the band is painted into the type itself with background-clip so it lights
   the glyphs rather than a box over them, and a thin blurred line rides on top
   at the same phase so the beam is visible in the air as well as on the word.
   The two animations share one duration and easing, which is what keeps the
   glow welded to the line instead of drifting behind it. */
.pjs-opt.is-selected{color:#fff;position:absolute;
  background-image:linear-gradient(100deg,
    #ffffff 0%,#ffffff 38%,
    #9fd4ff 45%,#ffffff 49%,#e8f6ff 51%,#9fd4ff 55%,
    #ffffff 62%,#ffffff 100%);
  background-size:280% 100%;background-repeat:repeat-x;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  animation:pjsLaserBurn 3.6s cubic-bezier(.55,.05,.25,1) infinite}
.pjs-opt.is-selected::after{content:"";position:absolute;top:-14%;bottom:-14%;
  left:0;width:2px;border-radius:2px;pointer-events:none;
  background:linear-gradient(180deg,rgba(159,212,255,0),#eaf7ff 22%,
    #ffffff 50%,#eaf7ff 78%,rgba(159,212,255,0));
  box-shadow:0 0 10px 2px rgba(150,205,255,.75),0 0 26px 6px rgba(90,170,255,.35);
  mix-blend-mode:screen;
  animation:pjsLaserBeam 3.6s cubic-bezier(.55,.05,.25,1) infinite}
@keyframes pjsLaserBurn{
  0%,8%{background-position:130% 0}
  58%,100%{background-position:-30% 0}}
@keyframes pjsLaserBeam{
  0%,8%{left:-4%;opacity:0}
  12%{opacity:.95}
  52%{opacity:.95}
  58%,100%{left:104%;opacity:0}}
@media (prefers-reduced-motion:reduce){
  .pjs-opt.is-selected{animation:none;background-image:none;
    -webkit-text-fill-color:#fff}
  .pjs-opt.is-selected::after{display:none}}
.pjs-wheel:focus-visible .pjs-opt.is-selected{text-decoration:underline;text-underline-offset:8px}

.pjs-info{position:absolute;left:0;right:8px;bottom:52px}
.pjs-des{margin:0 0 14px;color:#93a3b8;
  font-size:clamp(12.5px,1.05vw,14px);line-height:1.65}
.pjs-tag{display:inline-block;padding:5px 13px;border-radius:99px;
  border:1px solid rgba(255,255,255,.14);background:rgba(6,14,32,.5);
  color:#cfe0f5;font:10px JetBrains,monospace;letter-spacing:.16em}
.pjs-info.is-enter .pjs-des,.pjs-info.is-enter .pjs-tag{
  animation:pjsRise .55s cubic-bezier(.2,.7,.2,1) both}
.pjs-info.is-enter .pjs-tag{animation-delay:.09s}
@keyframes pjsRise{from{opacity:0;transform:translateY(18px);filter:blur(5px)}
  to{opacity:1;transform:none;filter:blur(0)}}

.pjs-bar{position:absolute;left:0;bottom:8px;display:flex;align-items:baseline;gap:16px}
.pjs-count{color:#8ea3bd;font:11px JetBrains,monospace;letter-spacing:.2em}
.pjs-count b{color:#eaf2ff;font-weight:400}
.pjs-hint{color:rgba(142,163,189,.45);font:9.5px JetBrains,monospace;
  letter-spacing:.18em;text-transform:uppercase;transition:opacity .4s ease}
.pj-stage.is-manual .pjs-hint{opacity:0}

/* --- right: the video frame, now unobstructed --- */
.pjs-screen{--cw:clamp(104px,8vw,142px);
  position:relative;height:clamp(540px,86vh,860px);min-width:0;
  border-radius:22px 0 0 22px;overflow:hidden;isolation:isolate;
  border:1px solid rgba(255,255,255,.09);border-right:0;background:#050b18;
  box-shadow:0 44px 100px rgba(0,0,0,.55)}
.pjs-frames{position:absolute;inset:0}
.pjs-frame{position:absolute;inset:0;opacity:0;transition:opacity .7s ease;
  will-change:opacity}
.pjs-frame.is-active{opacity:1}
.pjs-frame video{width:100%;height:100%;object-fit:cover;display:block}
.pjs-frame img{width:100%;height:100%;object-fit:contain;display:block;background:#050b18}
/* A film that carries its own title card. The type is set in the page rather
   than burned into the clip so it stays sharp at any frame size, and is sized
   in cqw so it tracks the frame instead of the viewport. */
.pjs-frame .pjs-title{position:absolute;left:0;right:0;top:clamp(10px,3.5cqw,54px);
  container-type:inline-size;text-align:center;color:#fff;pointer-events:none;
  text-shadow:0 2px 26px rgba(0,0,0,.45)}
.pjs-title-main{margin:0;font-family:BigShoulders,"Big Shoulders Display",
  "Bahnschrift Light Condensed","Arial Narrow",sans-serif;
  font-weight:100;font-size:clamp(46px,13.5cqw,196px);
  line-height:.9;letter-spacing:.14em;text-indent:.14em}
.pjs-title-by{margin:clamp(4px,.9cqw,14px) 0 0;
  font-family:"Bahnschrift","Arial Narrow",sans-serif;font-weight:400;
  font-size:clamp(7px,1.35cqw,19px);letter-spacing:.24em;text-indent:.24em;
  opacity:.92}
/* An editorial title card: type set as a layout rather than a caption, so the
   frame reads as a designed page instead of a clip with a label on it.
   Everything is in cqw, so the whole composition scales with the frame. */
.pjs-frame .pjs-edit{position:absolute;inset:0;container-type:inline-size;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:clamp(14px,3.2cqw,52px) clamp(16px,3.6cqw,58px);
  color:#fff;pointer-events:none;
  text-shadow:0 2px 22px rgba(0,0,0,.42);
  background:linear-gradient(180deg,rgba(4,8,16,.42),rgba(4,8,16,0) 34%,
    rgba(4,8,16,0) 62%,rgba(4,8,16,.5))}
.pjs-edit-side{position:absolute;left:clamp(10px,1.5cqw,24px);top:50%;
  transform:translateY(-50%) rotate(180deg);writing-mode:vertical-rl;
  font:clamp(6.5px,.86cqw,12px) JetBrains,monospace;letter-spacing:.42em;
  opacity:.55}
.pjs-edit-kick{margin:0 0 clamp(4px,.8cqw,12px);display:flex;align-items:center;
  gap:.9em;font:clamp(7px,.95cqw,13px) JetBrains,monospace;letter-spacing:.3em;
  color:#dbe7f7;opacity:.8}
.pjs-edit-kick i{flex:0 0 clamp(14px,3cqw,48px);height:1px;
  background:currentColor;opacity:.5}
/* The wordmark is stacked and set tight, which is what separates a designed
   title from a heading: the two lines read as one shape. */
.pjs-edit-title{margin:0;display:flex;flex-direction:column;
  font-family:BigShoulders,"Big Shoulders Display","Arial Narrow",sans-serif;
  font-weight:100;font-size:clamp(38px,13cqw,188px);line-height:.82;
  letter-spacing:.09em;text-indent:.09em}
.pjs-edit-title span:last-child{padding-left:clamp(10px,3.4cqw,54px);opacity:.86}
.pjs-edit-foot{display:flex;align-items:center;gap:clamp(6px,1.2cqw,18px);
  font:clamp(6.5px,.86cqw,12px) JetBrains,monospace;letter-spacing:.26em;
  opacity:.72}
.pjs-edit-foot i{flex:0 0 clamp(8px,1.6cqw,26px);height:1px;
  background:currentColor;opacity:.45}

/* A built page shown as itself: its own hero film with its own copy laid back
   over it, so the frame reads as the live page rather than as a clip of one.
   Everything is sized in cqw so it scales with the frame instead of the page. */
.pjs-frame .pjs-page{position:absolute;inset:0;container-type:inline-size;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:clamp(14px,2.2cqw,30px) clamp(16px,3cqw,44px);
  color:#fff;text-shadow:0 2px 18px rgba(0,0,0,.5);pointer-events:none;
  background:linear-gradient(90deg,rgba(6,10,18,.62),rgba(6,10,18,.12) 62%)}
.pjs-page-bar,.pjs-page-foot{display:flex;justify-content:space-between;
  align-items:center;font:clamp(8px,1.05cqw,13px) Inter,system-ui,sans-serif;
  letter-spacing:.02em;opacity:.9}
.pjs-page-mark{font-weight:600;letter-spacing:.01em}
.pjs-page-back,.pjs-page-foot{opacity:.72}
.pjs-page-body{max-width:62%}
.pjs-page-kick{display:flex;align-items:center;gap:.6em;margin:0 0 .9em;
  font:clamp(7.5px,.92cqw,11px) JetBrains,monospace;letter-spacing:.14em;
  color:#9ec2ff}
.pjs-page-kick i{width:.5em;height:.5em;border-radius:50%;background:#5b9cff}
.pjs-page-head{margin:0;font:600 clamp(20px,4.6cqw,64px)/1.02 Inter,system-ui,sans-serif;
  letter-spacing:-.02em}
.pjs-page-sub{margin:1em 0 0;max-width:34em;
  font:clamp(8.5px,1.15cqw,15px)/1.5 Inter,system-ui,sans-serif;opacity:.86}
.pjs-page-cta{display:flex;gap:.7em;margin-top:1.4em}
.pjs-page-btn{padding:.75em 1.5em;border-radius:99px;background:#fff;color:#0a0f18;
  font:500 clamp(8px,1.05cqw,14px) Inter,system-ui,sans-serif;text-shadow:none;
  white-space:nowrap}
.pjs-page-btn.is-ghost{background:transparent;color:#fff;
  border:1px solid rgba(255,255,255,.55)}
/* A project shown as a row of three films. The slider's own clip is first in
   the DOM (that is the one the lightbox moves) but sits in the middle here. */
.pjs-frame.is-trio{display:flex;gap:2px}
.pjs-frame.is-trio video{width:calc((100% - 4px)/3);height:100%;object-fit:cover}
.pjs-frame.is-trio .is-before{order:-1}
.pjs-frame.is-trio .is-mid{order:0}
.pjs-frame.is-trio .is-after{order:1}
.pjs-slot{position:absolute;inset:0;display:grid;place-items:center;
  background:linear-gradient(150deg,#0b1a33,#060d1c 62%,#0a1526);
  font:clamp(90px,16vw,260px) Anton,Impact,sans-serif;
  color:rgba(150,196,255,.13);letter-spacing:.04em}
/* only a soft vignette now, since no copy sits on the clip */
.pjs-scrim{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 32% 45%,rgba(2,6,15,0) 42%,rgba(2,6,15,.5) 100%)}

/* --- CoverFlow deck --- */
.pjs-deck{--flow:92;--sides:2;
  position:absolute;z-index:4;top:50%;
  /* the frame bleeds past the page edge, so the deck is pushed in by the
     same amount to stay fully on screen */
  right:calc(clamp(22px,7vw,140px) + clamp(24px,3vw,54px));
  width:calc(var(--cw)*3.1);height:calc(var(--cw)*1.5);
  transform:translateY(-50%);perspective:1100px;perspective-origin:50% 50%}
.pjs-card{position:absolute;top:50%;left:50%;padding:0;cursor:pointer;
  width:var(--cw);height:calc(var(--cw)*1.42);
  border-radius:13px;overflow:hidden;border:1px solid rgba(255,255,255,.1);
  background:#0a1425 var(--shot,none) center/cover no-repeat;
  box-shadow:0 22px 46px rgba(0,0,0,.62);transform-style:preserve-3d;
  will-change:transform,opacity;
  transition:transform .58s cubic-bezier(.4,.05,.15,1),opacity .45s ease,
    border-color .3s ease,box-shadow .3s ease}
.pjs-card.is-active{border-color:rgba(140,195,255,.6);
  box-shadow:0 26px 58px rgba(0,0,0,.7),0 0 0 1px rgba(140,195,255,.22)}
.pjs-card--slot::before{content:attr(data-num);position:absolute;inset:0;
  display:grid;place-items:center;
  background:linear-gradient(150deg,#0e1e3a,#060d1c);
  font:clamp(30px,3.4vw,52px) Anton,Impact,sans-serif;color:rgba(150,196,255,.2)}
.pjs-card-name{position:absolute;inset:auto 0 0 0;padding:22px 9px 8px;
  background:linear-gradient(0deg,rgba(2,6,15,.9),rgba(2,6,15,0));
  color:#e6eefb;font:9.5px JetBrains,monospace;letter-spacing:.09em;
  text-transform:uppercase;opacity:0;transition:opacity .3s ease}
.pjs-card.is-active .pjs-card-name{opacity:1}
/* the centre card doubles as the open-full-size control */
/* Self-initiated work says so, on the card and again in the description.
   A concept piece presented like a client job is the one thing in a portfolio
   that costs trust when it is found out, and it costs nothing to label. */
.pjs-card-flag{position:absolute;z-index:2;top:7px;left:7px;
  padding:3px 7px;border-radius:4px;border:1px solid rgba(190,215,245,.3);
  background:rgba(6,12,22,.72);backdrop-filter:blur(6px);
  color:#c4d8f0;font:8px JetBrains,monospace;letter-spacing:.16em;
  opacity:0;transition:opacity .3s ease;pointer-events:none}
.pjs-card.is-active .pjs-card-flag{opacity:.8}
.pjs-flag{display:inline-block;margin-right:8px;padding:3px 8px;border-radius:4px;
  border:1px solid rgba(190,215,245,.26);background:rgba(140,195,255,.09);
  color:#bcd3ec;font:8px JetBrains,monospace;letter-spacing:.16em;
  vertical-align:1px;font-weight:400}
.pjs-card-zoom{position:absolute;z-index:2;top:7px;right:7px;
  width:21px;height:21px;display:grid;place-items:center;border-radius:6px;
  background:rgba(4,10,22,.7);color:#dbe8fb;font:11px/1 JetBrains,monospace;
  opacity:0;transition:opacity .3s ease}
.pjs-card.is-active .pjs-card-zoom{opacity:.75}
.pjs-card.is-active:hover .pjs-card-zoom{opacity:1}
.pjs-card--slot .pjs-card-zoom{display:none}

/* --- lightbox: the clip at its own aspect ratio, still muted --- */
.pjs-lb{position:fixed;z-index:90;inset:0;display:grid;place-items:center;
  padding:clamp(26px,5vw,70px);background:rgba(2,5,12,.9);
  backdrop-filter:blur(14px);opacity:0;transition:opacity .32s ease}
/* display:grid above outranks the browser's [hidden] rule, so the closed
   overlay has to be taken out of the layout explicitly -- otherwise it covers
   the whole page invisibly and eats every click. */
.pjs-lb[hidden]{display:none}
.pjs-lb:not(.is-open){pointer-events:none}
.pjs-lb.is-open{opacity:1;pointer-events:auto}
.pjs-lb-hold{position:relative;z-index:2;display:grid;place-items:center;max-width:100%;max-height:100%}
.pjs-lb-cap{position:relative;z-index:2}
.pjs-lb-close{z-index:5}
.pjs-lb-hold video{max-width:100%;max-height:82vh;width:auto;height:auto;
  object-fit:contain;display:block;border-radius:10px;
  box-shadow:0 40px 110px rgba(0,0,0,.7)}
.pjs-lb-cap{margin:18px 0 0;text-align:center;color:#9fb2c9;
  font:10px JetBrains,monospace;letter-spacing:.2em;text-transform:uppercase}
.pjs-lb-close{position:absolute;top:clamp(16px,3vw,34px);right:clamp(16px,3vw,34px);
  width:44px;height:44px;display:grid;place-items:center;cursor:pointer;
  border-radius:50%;border:1px solid rgba(255,255,255,.2);
  background:rgba(6,14,32,.6);color:#eaf2ff;font-size:22px;line-height:1;
  transition:background .25s ease,border-color .25s ease}
.pjs-lb-close:hover{background:rgba(91,168,255,.24);border-color:rgba(140,195,255,.6)}
body.pjs-lb-open{overflow:hidden}

/* --- fashion orbit: the shoot flies around the film ---
   Positions come from fashion-orbit.js, so nothing here places a card; this
   only says what a card looks like and how it behaves once pulled forward.
   z-index:0 keeps the whole cloud in its own stacking context underneath the
   clip and the close button, however deep the per-card z-index goes. */
.fo-stage{--fo-w:76px;position:absolute;z-index:0;inset:0;overflow:hidden;
  touch-action:none;cursor:grab;contain:strict}
.fo-stage.is-drag{cursor:grabbing}
.fo-stage[hidden]{display:none}
/* Deliberately bare: no radius, border or shadow. In a cloud this dense any
   chrome on a card turns into visual noise, and depth is already being read
   from size and brightness. Height is left to the image so the set keeps its
   mix of portrait, landscape and square rather than being cropped to one
   shape. --fo-k is the per-project card size and --w the per-card jitter,
   both set in orbit-cards.js; --fo-w is the base the media queries move. */
.fo-card{position:absolute;left:50%;top:50%;
  width:calc(var(--fo-w) * var(--fo-k,1) * var(--w,1));height:auto;
  padding:0;border:0;background:none;cursor:pointer;opacity:0;
  will-change:transform,opacity;line-height:0}
.fo-card img{width:100%;height:auto;display:block;pointer-events:none}
.fo-card:hover{filter:brightness(1.25)}

/* Pulled forward: parked dead centre at a readable size. The orbit skips a
   focused card, so this transform is the only one acting on it. */
.fo-card.is-focus{transform:translate(-50%,-50%) scale(1);
  width:min(86vw,660px);opacity:1;filter:none;
  transition:width .5s cubic-bezier(.22,1,.36,1),transform .5s cubic-bezier(.22,1,.36,1);
  box-shadow:0 50px 130px rgba(0,0,0,.8),0 0 0 1px rgba(140,195,255,.55)}
/* A tall still would otherwise run off the top and bottom once the width cap
   grew, so the image -- not the button -- carries the height limit. */
.fo-card.is-focus img{max-height:82vh;width:auto;max-width:100%;margin:0 auto}
.fo-stage.has-focus .fo-card:not(.is-focus){opacity:.1!important;
  transition:opacity .35s ease}

/* A live project page, running inside the lightbox instead of at the end of a
   link. It takes the space the film would have had; the film itself is left in
   the hold, hidden, so the slider can put it back on close exactly as always. */
.pjs-lb.has-live .pjs-lb-hold video{display:none}
.pjs-lb.has-live .pjs-lb-hold{width:min(1180px,94vw)}
.pjs-live{display:block;width:100%;height:min(78vh,700px);border:0;border-radius:8px;
  background:#05070b;box-shadow:0 50px 130px rgba(0,0,0,.75),0 0 0 1px rgba(140,195,255,.28)}
@media(max-width:760px){.pjs-live{height:66vh}}

/* With the cloud up the clip gives back some height, so the orbit has room to
   swing past above and below it rather than only at the sides. */
.pjs-lb.has-orbit .pjs-lb-hold video{max-height:62vh}
/* The scrubbed set: a line of stills the wheel pushes through, laid out in
   perspective around the film rather than orbiting it. */
.pjs-scrub{position:absolute;inset:0;z-index:1;perspective:1400px;
  perspective-origin:50% 50%;pointer-events:none}
.pjs-scrub-shot{position:absolute;left:50%;top:76%;
  width:clamp(104px,11vw,172px);aspect-ratio:3/4;border-radius:10px;
  background:#0a1425 center/cover no-repeat;
  box-shadow:0 30px 70px rgba(0,0,0,.66);border:1px solid rgba(255,255,255,.09);
  transform-style:preserve-3d;will-change:transform,opacity;visibility:hidden}
.pjs-lb.has-scrub .pjs-lb-hold{align-items:start}
.pjs-lb.has-scrub .pjs-lb-hold video{max-height:44vh;margin-top:-14vh;position:relative;z-index:3}
.pjs-lb.has-scrub .pjs-lb-hold{position:relative;z-index:3}
.pjs-scrub-rail{position:absolute;left:50%;bottom:clamp(16px,4vh,42px);
  transform:translateX(-50%);display:flex;gap:7px;z-index:4}
.pjs-scrub-rail i{width:16px;height:2px;border-radius:2px;
  background:rgba(255,255,255,.22);transition:background .3s ease,width .3s ease}
.pjs-scrub-rail i.is-on{background:#cfe0f5;width:26px}
@media (max-width:900px){
  .pjs-scrub-shot{width:clamp(76px,22vw,108px);top:78%}
  .pjs-lb.has-scrub .pjs-lb-hold video{max-height:30vh;margin-top:-10vh}
}
/* A three-clip project: the films sit side by side instead of one filling the
   frame, so none of them is blown up past its own resolution. */
.pjs-lb.has-trio .pjs-lb-hold{display:flex;align-items:center;justify-content:center;gap:clamp(8px,1.4vw,22px)}
.pjs-lb.has-trio .pjs-lb-hold video{max-height:58vh;max-width:30vw;border-radius:6px}
.pjs-lb.has-trio .pjs-lb-side{opacity:.9}
@media (max-width:900px){
  .pjs-lb.has-trio .pjs-lb-hold{gap:6px}
  .pjs-lb.has-trio .pjs-lb-hold video{max-height:34vh;max-width:31vw}
}
@media (max-width:720px){
  /* The clip gives up more height here so the orbit has a lane at all. */
  .pjs-lb.has-orbit .pjs-lb-hold video{max-height:36vh}
  .fo-stage{--fo-w:50px}
}

@media (prefers-reduced-motion:reduce){
  .fo-card,.fo-card img{transition:none}
}

@media (max-width:1100px){
  .pj-stage{grid-template-columns:minmax(210px,34%) 1fr;
    padding-left:clamp(14px,2vw,28px)}
  .pjs-screen{--cw:clamp(88px,10vw,116px)}
}
/* Narrow screens have no room for a rail beside the frame, so the list drops
   below the clip and the deck moves to the middle of it. */
@media (max-width:820px){
  .pj-stage{grid-template-columns:minmax(0,1fr);gap:22px;
    padding-inline:clamp(18px,5vw,30px)}
  .pjs-screen{--cw:78px;height:clamp(300px,42vh,420px);
    border-radius:16px;border-right:1px solid rgba(255,255,255,.09)}
  .pjs-deck{--flow:64;--sides:1;right:auto;left:50%;
    width:calc(var(--cw)*2.4);transform:translate(-50%,-50%)}
  .pjs-rail{height:auto;min-height:300px}
  .pjs-wheel{position:relative;top:auto;bottom:auto;height:210px}
  .pjs-opt{top:50%;font-size:clamp(21px,6.4vw,32px)}
  .pjs-info{position:relative;left:auto;right:auto;bottom:auto;margin-top:14px}
  .pjs-bar{position:relative;left:auto;bottom:auto;margin-top:18px}
}
@media (prefers-reduced-motion:reduce){
  .pjs-card{transition:opacity .2s ease}
  .pjs-frame,.pjs-lb{transition:none}
  .pjs-info.is-enter .pjs-des,.pjs-info.is-enter .pjs-tag{animation:none}
}

/* Pure scroll target for the nav's "Services" link.

   #work is not an ordinary section -- it is a tall pinned scroll sequence of
   seven chapters, and 01 / ABOUT and 02 / SERVICES are two moments inside the
   SAME element. So an anchor at the element's start sends Services to exactly
   where About already goes, which is what the nav did before.

   02 / SERVICES is revealed by depth-corridor.js between t = 5.50 and 6.70,
   where t is scroll travel into the section measured in viewport heights. 600vh
   therefore lands on it fully revealed, with room before it fades at 6.70.
   Re-check this number if that reveal window is ever retimed.

   Zero-size and absolutely positioned so it takes part in no layout;
   scroll-margin-top keeps the fixed header off the heading it lands on. */
.sec-anchor{
  position:absolute;
  width:0;height:0;
  pointer-events:none;
}
#services{
  top:600vh;
  scroll-margin-top:96px;
}

/* Project note under the lightbox clip.

   The orbit stage is inset:0 and its cards are laid out on a radius that
   reaches the bottom of the screen, so this text has cards flying behind it,
   not around it. Hence the scrim and the z-index: .fo-stage is z-index 0, so
   sitting at 4 keeps the copy above the swarm, and the blur keeps it readable
   when a bright still passes underneath. */
.pjs-lb-case{
  position:relative;z-index:4;
  width:min(760px,90vw);margin:14px auto 0;
  padding:15px 20px;
  border:1px solid rgba(190,215,245,.16);border-radius:8px;
  background:rgba(4,9,18,.74);backdrop-filter:blur(10px);
  text-align:left;
}
.pjs-lb-meta{margin:0 0 8px;color:#cfe0f5;
  font:8px JetBrains,monospace;letter-spacing:.18em;text-transform:uppercase}
.pjs-lb-body{margin:0;color:#9fb2c9;font:12.5px/1.68 Inter,Arial,sans-serif}

@media(max-width:560px){
  .pjs-lb-case{padding:12px 14px}
  .pjs-lb-body{font-size:11.5px;line-height:1.58}
}

/* At 600px of viewport the case study ran 8px past the bottom edge: the clip
   is capped at 62vh, which leaves less than the text needs once the caption
   and the block are under it. Only the three cards carrying a case study are
   affected, hence .has-case -- every other card keeps the full 62vh. */
@media(max-height:820px){
  .pjs-lb.has-case.has-orbit .pjs-lb-hold video{max-height:50vh}
}
@media(max-height:660px){
  .pjs-lb.has-case.has-orbit .pjs-lb-hold video{max-height:42vh}
  .pjs-lb.has-case .pjs-lb-cap{margin-top:10px}
  .pjs-lb.has-case .pjs-lb-case{margin-top:10px;padding:11px 14px}
  .pjs-lb.has-case .pjs-lb-body{font-size:11.5px;line-height:1.5}
}

/* Flags in the project note.

   Drawn, not emoji: Windows ships no glyphs for the regional-indicator flag
   characters, so the emoji renders as the bare letters "FR" / "TR" on the
   machines most of these visitors are using. A drawn flag looks the same
   everywhere. */
.fl{display:inline-block;width:15px;height:11px;margin-right:7px;
  border-radius:2px;vertical-align:-1px;
  border:1px solid rgba(255,255,255,.22);
  box-shadow:0 1px 3px rgba(0,0,0,.45)}
.fl-fr{background:linear-gradient(90deg,
  #0055A4 0 33.34%, #f4f6fa 33.34% 66.67%, #EF4135 66.67% 100%)}
.fl-tr{background:#E30A17
  url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 20'%3E%3Cg fill='%23fff'%3E%3Cpath d='M13 10a4.4 4.4 0 1 1-3.2-4.24A3.55 3.55 0 1 0 9.8 14.24 4.4 4.4 0 0 1 13 10z'/%3E%3Cpath d='M15.3 10l1.36.9-.5-1.57 1.32-.96h-1.63L15.3 6.8l-.53 1.57h-1.63l1.32.96-.5 1.57z'/%3E%3C/g%3E%3C/svg%3E")
  center/contain no-repeat}
