/* gallery: page-specific styles ported from reference/ets-work.html. Shared rules live in base.css and chrome.css, tokens in tokens.css. */
:root{
  --u:max(calc(100vw / 1440), calc(100svh / 900));
}

*{box-sizing:border-box;margin:0}
html{-webkit-text-size-adjust:100%}
body{font-family:var(--sans);background:var(--base);color:var(--ink);line-height:1.55;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}

/* ============ NAV ============ */

.btn{display:inline-flex;align-items:center;justify-content:center;height:56px;padding:0 34px;border-radius:var(--r-pill);
  font:600 17px/1 var(--sans);white-space:nowrap;transition:transform .2s var(--ease),background-color .2s,border-color .2s,color .2s}
.btn:hover{transform:translateY(-2px)}
.btn:focus-visible{outline:2px solid var(--cyan-pale);outline-offset:3px}
.btn-primary{background:var(--cyan);color:var(--on-cyan)}
.btn-primary:hover{background:var(--cyan-pale)}
.btn-ghost{height:46px;padding:0 24px;font-size:15px;border:1.5px solid rgba(244,251,253,.38);color:var(--ink)}
.btn-ghost:hover{border-color:var(--cyan);color:var(--cyan)}
.btn-ink{background:var(--on-cyan);color:var(--ink)}
.btn-ink:hover{background:#0B2A45}

/* ============ HERO ============ */
.hero{position:relative;height:100svh;min-height:660px;overflow:hidden;background:var(--base);isolation:isolate}
.scene{position:absolute;inset:0;width:100%;height:100%;z-index:-1;display:block}

.hero-copy{position:relative;z-index:2;max-width:1120px;margin:0 auto;padding:clamp(104px,15svh,150px) 24px 0;text-align:center}
.hero h1{font-weight:800;font-size:clamp(2.5rem,5.7vw,5.25rem);line-height:1.04;letter-spacing:-.022em;text-wrap:balance}
.hero h1 em{font-style:normal;color:var(--cyan)}
.hero p{max-width:600px;margin:26px auto 0;font-size:clamp(1.0625rem,1.35vw,1.3125rem);color:var(--muted);text-wrap:pretty}
.hero-copy .btn{margin-top:32px}

/* credentials sit inside the scene, on the mid water */
.creds{position:absolute;z-index:2;left:0;right:0;bottom:calc(var(--u) * 76);
  display:flex;justify-content:center;gap:clamp(28px,6vw,96px);list-style:none;padding:0 24px}
.creds li{width:190px;text-align:center;font-weight:600;font-size:12.5px;line-height:1.35;letter-spacing:.07em;text-transform:uppercase}
.porthole{display:block;width:68px;height:68px;margin:0 auto 12px}

/* ============ SCENE MOTION ============ */
/* waves drift exactly one period (1440 units) so the loop is seamless */
@keyframes drift-l{to{transform:translateX(-1440px)}}
@keyframes drift-r{from{transform:translateX(-1440px)}to{transform:translateX(0)}}
.w1{animation:drift-l 120s linear infinite}
.w2{animation:drift-r 95s linear infinite}
.w3{animation:drift-l 70s linear infinite}
.w4{animation:drift-r 52s linear infinite}
.w5{animation:drift-l 38s linear infinite}

/* data pulses run along the crest lines. Dash period 720 divides the 1440 drift, so it loops clean. */
@keyframes flow{from{stroke-dashoffset:var(--o,0)}to{stroke-dashoffset:calc(var(--o,0) - 720)}}
.pulse{stroke-dasharray:34 686;animation:flow 7s linear infinite}
.trail{stroke-dasharray:130 590;--o:96;stroke-opacity:.22}
.p2{animation-duration:5.5s;animation-delay:-2s}
.p4{stroke-dasharray:60 660;stroke-opacity:.6;animation-duration:9s;animation-delay:-4s}

/* data moving through the sky routes */
@keyframes net{to{stroke-dashoffset:-100}}
.net{stroke-dasharray:7 93;animation:net 6s linear infinite}

@keyframes bob{0%,100%{transform:translateY(0) rotate(-2deg)}50%{transform:translateY(5px) rotate(2.5deg)}}
.boat{transform-box:fill-box;transform-origin:50% 100%;animation:bob 6.5s ease-in-out infinite}

@keyframes moonrise{from{transform:translateY(70px);opacity:0}to{transform:none;opacity:1}}
.orb-in{animation:moonrise 1.8s var(--ease) both .1s}

@keyframes rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
.reveal{animation:rise .8s var(--ease) both;animation-delay:calc(var(--i) * 90ms + 250ms)}

/* short laptops: sit the light lower so it never crowds the button */
.orb-pos{transform:translateY(16px)}
@media (min-width:821px) and (max-height:800px){
  .orb-pos{transform:translateY(40px)}
  .hero-copy{padding-top:88px}
  .hero h1{font-size:clamp(2.5rem,4.7vw,4rem)}
  .hero p{margin-top:18px}
  .hero-copy .btn{margin-top:24px;height:50px}
}

/* scroll parallax, no JS. Far things move less. */
@supports (animation-timeline:scroll()){
  @keyframes sink{to{transform:translateY(var(--d))}}
  .par{animation:sink linear both;animation-timeline:scroll(root);animation-range:0 100svh}
}

/* ============ FLOOD SECTION ============ */
.flood{position:relative;margin-top:-1px;background:var(--cyan);color:var(--on-cyan);text-align:center;padding:clamp(72px,10vw,136px) 24px clamp(96px,12vw,160px)}
.flood h2{max-width:900px;margin:0 auto;font-weight:800;font-size:clamp(2.125rem,4.6vw,4rem);line-height:1.06;letter-spacing:-.02em;text-wrap:balance}
.flood .btn{margin-top:40px}

/* ============ SMALL SCREENS ============ */
@media (max-width:820px){
  .hero-copy{padding-top:112px}
  .creds{flex-direction:column;align-items:center;gap:12px;bottom:calc(var(--u) * 58)}
  .creds li{width:min(320px,100%);display:flex;align-items:center;gap:14px;text-align:left;font-size:11.5px}
  .porthole{width:44px;height:44px;margin:0;flex:none}
}
@media (max-width:820px) and (max-height:760px){.creds{display:none}}

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

/* ============ SUBPAGE SECTIONS ============ */
.hero-copy.top{padding-top:clamp(96px,13svh,132px)}
.hero-copy.top h1{font-size:clamp(2.25rem,4.6vw,4.25rem)}
section{position:relative}
.div{position:absolute;left:0;right:0;bottom:calc(100% - 1px);width:100%;height:clamp(48px,7vw,120px);z-index:1;pointer-events:none}
section:first-of-type .div{display:none}
.wrap{max-width:1160px;margin:0 auto;padding:0 32px}
.sec{padding:clamp(56px,7vw,104px) 0 clamp(72px,9vw,128px)}
h2{font-weight:800;font-size:clamp(1.9rem,3.6vw,3.1rem);line-height:1.08;letter-spacing:-.02em;text-wrap:balance}
.lede{max-width:600px;font-size:clamp(1.0625rem,1.3vw,1.25rem);color:var(--muted);margin-top:16px}
.slot{color:var(--cyan-pale);opacity:.8}
.ink-on .lede{color:rgba(4,18,31,.72)}
.flood .slot{color:#04121F;opacity:.7}
.bubbles{position:absolute;inset:0;pointer-events:none}
.bubbles i{position:absolute;bottom:-12px;width:6px;height:6px;border-radius:50%;background:var(--cyan);opacity:0;animation:riseb 9s linear infinite}
@keyframes riseb{0%{transform:translateY(0) scale(.6);opacity:0}10%{opacity:.7}100%{transform:translateY(-110vh) scale(1);opacity:0}}
.frame{position:relative;background:#04121F;border-radius:22px;padding:14px;outline:1.5px solid var(--ink);outline-offset:-1.5px}
.frame::before{content:"";position:absolute;inset:6px;border-radius:17px;border:1px solid rgba(60,204,240,.7);pointer-events:none}
.frame .shot{display:block;width:100%;aspect-ratio:16/10;border-radius:12px;background:#0B4158;display:grid;place-items:center;font-weight:600;color:var(--cyan-pale)}
.rivet{position:absolute;width:7px;height:7px;border-radius:50%;background:var(--cyan)}
.rivet.a{top:10px;left:10px}.rivet.b{top:10px;right:10px}.rivet.c{bottom:10px;left:10px}.rivet.d{bottom:10px;right:10px}
.porthole-lg{width:min(360px,80vw);aspect-ratio:1;border-radius:50%;background:#0B4158;outline:1.5px solid var(--ink);outline-offset:-1.5px;position:relative;display:grid;place-items:center;font-weight:600;color:var(--cyan-pale);overflow:hidden}
.porthole-lg::before{content:"";position:absolute;inset:8px;border-radius:50%;border:1.5px solid rgba(60,204,240,.7)}
.porthole-lg img{width:100%;height:100%;object-fit:cover}
.gauge{position:relative;padding-left:72px}
.gauge::before{content:"";position:absolute;left:24px;top:8px;bottom:8px;width:2px;background:rgba(165,243,252,.35)}
.gauge li{position:relative;list-style:none;padding:0 0 40px}
.gauge li::before{content:"";position:absolute;left:-55px;top:8px;width:16px;height:16px;border-radius:50%;background:#04121F;border:1.5px solid var(--cyan)}
.gauge li:first-child::before{background:var(--cyan)}
.gauge b{display:block;font-weight:800;font-size:1.25rem}
.gauge p{color:var(--muted);max-width:520px;margin-top:6px}
.split{display:grid;grid-template-columns:1.1fr .9fr;gap:56px;align-items:center}
.stack>*+*{margin-top:14px}
.creds.inline{position:static;justify-content:center;margin-top:48px}
@media (max-width:820px){.split{grid-template-columns:1fr;gap:32px}.gauge{padding-left:56px}}
.ico{width:34px;height:34px;flex:none;border-radius:9px;background:#04121F;border:1.4px solid rgba(165,243,252,.55);display:grid;place-items:center}
.ico svg,.gico svg,.bigico svg{fill:none;stroke:#3CCCF0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.ico svg{width:19px;height:19px}
.ilist{list-style:none;padding:0;margin:0}
.ilist li{display:flex;align-items:center;gap:14px}
.gico{width:30px;height:30px;flex:none;border-radius:8px;background:#04121F;border:1.4px solid rgba(165,243,252,.55);display:grid;place-items:center}
.gico svg{width:17px;height:17px}
.gauge b{display:flex;align-items:center;gap:12px}
.bigico{display:grid;place-items:center;margin:0 auto 16px}
.bigico svg{width:46px;height:46px;stroke-width:1.7}
.repl{display:flex;align-items:center;gap:13px}
.repl .ico{border-color:rgba(4,18,31,.45)}
.repl .ico svg{stroke:#3CCCF0}
.ink-on .repl .ico{background:#04121F}
@keyframes flowc{to{stroke-dashoffset:-720}}
.hero .pulse{stroke-dasharray:40 680;animation:flowc 9s linear infinite}
@keyframes net{to{stroke-dashoffset:-100}}
.net{stroke-dasharray:7 93;animation:net 6s linear infinite}

/* ============ GALLERY: WIDE COVERFLOW ============ */
html,body{height:100%}
.hero{height:100svh;min-height:700px}
.wash{transition:fill 1.2s ease}
.stage{position:absolute;inset:0;z-index:2}
.cf{position:absolute;left:0;right:0;top:63%;height:0;perspective:2200px;perspective-origin:50% 42%;outline:none}
.track{position:relative;list-style:none;padding:0;margin:0;transform-style:preserve-3d}
.card{position:absolute;left:50%;top:0;width:min(760px,56vw);aspect-ratio:16/10;transform-style:preserve-3d;
  transition:transform .8s var(--ease),opacity .6s;cursor:pointer;will-change:transform}
.card.active{cursor:default}
.face{position:absolute;inset:0;border-radius:18px;overflow:hidden;background:#04121F;
  outline:1.5px solid rgba(244,251,253,.55);outline-offset:-1.5px;box-shadow:0 30px 90px rgba(0,0,0,.6)}
.face::after{content:"";position:absolute;inset:6px;border-radius:13px;border:1px solid rgba(60,204,240,.55);pointer-events:none}
.face img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top}
.face .veil{position:absolute;inset:0;background:#04121F;opacity:.5;transition:opacity .6s var(--ease)}
.card.active .face .veil{opacity:0}
.card.active .face{outline-color:var(--cyan)}
.refl{position:absolute;left:0;right:0;top:100%;aspect-ratio:16/10;transform:scaleY(-1);margin-top:12px;opacity:.22;
  -webkit-mask-image:linear-gradient(to top,rgba(0,0,0,.9),transparent 52%);
  mask-image:linear-gradient(to top,rgba(0,0,0,.9),transparent 52%);pointer-events:none}
.refl .face{box-shadow:none;outline:none}.refl .face::after{display:none}

.capwrap{position:absolute;left:50%;top:63%;transform:translate(-50%,-50%);width:min(760px,56vw);aspect-ratio:16/10;
  z-index:200;pointer-events:none;display:flex;align-items:flex-end;border-radius:18px;overflow:hidden}
.cap{width:100%;padding:clamp(22px,3vw,34px) clamp(24px,3.4vw,40px);
  background:linear-gradient(to top,rgba(4,18,31,.97),rgba(4,18,31,.9) 42%,rgba(4,18,31,.55) 72%,rgba(4,18,31,0));
  transition:opacity .3s var(--ease)}
.cap.swap{opacity:0}
.cap .cat{display:block;font:600 .78rem/1 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--cyan)}
.cap h1{margin-top:10px;font-weight:800;font-size:clamp(1.5rem,2.9vw,2.7rem);line-height:1.06;letter-spacing:-.02em}
.cap p{margin-top:8px;font-size:clamp(.95rem,1.15vw,1.1rem);color:var(--ink);max-width:60ch}

.arrow{position:absolute;top:63%;transform:translateY(-50%);width:56px;height:56px;border-radius:50%;
  border:1.5px solid rgba(244,251,253,.5);background:rgba(4,18,31,.55);backdrop-filter:blur(6px);color:var(--ink);
  display:grid;place-items:center;cursor:pointer;z-index:300;transition:border-color .2s,color .2s}
.arrow svg{width:22px;height:22px}.arrow:hover{border-color:var(--cyan);color:var(--cyan)}
.prev{left:clamp(12px,2vw,36px)}.next{right:clamp(12px,2vw,36px)}
.ghead{position:absolute;left:0;right:0;top:clamp(104px,13svh,152px);text-align:center;z-index:5;padding:0 24px}
.ghead .eyebrow{font:500 12px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.28em;text-transform:uppercase;color:var(--cyan)}
.ghead h2{margin-top:12px;font-size:clamp(2.1rem,4.4vw,4rem);letter-spacing:-.028em;line-height:1.04}
@media(max-width:820px){.ghead h2{font-size:1.5rem}}
.dots{position:absolute;left:0;right:0;bottom:clamp(26px,5svh,48px);display:flex;justify-content:center;gap:10px;z-index:300}
.dot{width:8px;height:8px;border-radius:999px;border:1.5px solid var(--cyan);background:transparent;padding:0;cursor:pointer;
  transition:background .25s,width .25s var(--ease)}
.dot.on{background:var(--cyan);width:26px}
@media (max-width:820px){
  .card,.capwrap{width:86vw}
  .cf,.capwrap,.arrow{top:52%}
  .arrow{width:44px;height:44px}
  .refl{display:none}
}
@media (prefers-reduced-motion:reduce){.card{transition:none}}

/* ---- top rail: SOPros carries its mark, Lumen carries its glow ---- */

/* ---- brand mark, upper left ---- */

/* ============ GALLERY: CSS-only, fully in the DOM ============ */
html{scroll-behavior:smooth}
.deck{position:relative;margin-top:clamp(20px,3vh,40px)}
.track{display:flex;gap:clamp(20px,3vw,44px);overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;scroll-padding-inline:calc(50vw - min(410px,31vw));
  padding:0 calc(50vw - min(410px,31vw)) clamp(30px,5vh,64px);
  scrollbar-width:none;-ms-overflow-style:none}
.track::-webkit-scrollbar{display:none}
.slide{flex:0 0 min(820px,62vw);scroll-snap-align:center;scroll-snap-stop:always;margin:0;position:relative}
.shot-wrap{position:relative;border-radius:18px;overflow:hidden;background:#04121F;
  outline:1.5px solid rgba(244,251,253,.45);outline-offset:-1.5px;box-shadow:0 30px 90px rgba(0,0,0,.6);
  aspect-ratio:16/10}
.shot-wrap::after{content:"";position:absolute;inset:6px;border-radius:13px;
  border:1px solid rgba(60,204,240,.5);pointer-events:none}
.shot-wrap img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top}
.cap{position:absolute;left:0;right:0;bottom:0;padding:clamp(20px,2.6vw,32px) clamp(22px,3vw,38px);
  background:linear-gradient(to top,rgba(4,18,31,.97),rgba(4,18,31,.9) 42%,rgba(4,18,31,.55) 72%,rgba(4,18,31,0))}
.cap .cat{display:block;font:600 .78rem/1 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--cyan)}
.cap h2{margin-top:9px;font-weight:800;font-size:clamp(1.4rem,2.7vw,2.5rem);line-height:1.06;letter-spacing:-.02em}
.cap p{margin-top:7px;font-size:clamp(.92rem,1.1vw,1.08rem);color:var(--ink);max-width:62ch}
/* No reflection under the cards. It hung 480px below the track, which made the track a
   vertical scroll container: a mouse wheel over the deck scrolled the cards up out of view.
   Only a 45px sliver of it ever showed in this flowing layout. Removed 2026-09-30. */
/* coverflow without script: the scroll position drives the transform */
@supports (animation-timeline: view(x)){
  .slide{animation:flow linear both;animation-timeline:view(x);animation-range:entry 0% exit 100%}
  @keyframes flow{
    0%{transform:rotateY(38deg) scale(.82);opacity:.55}
    45%,55%{transform:rotateY(0deg) scale(1);opacity:1}
    100%{transform:rotateY(-38deg) scale(.82);opacity:.55}}
  .deck{perspective:2200px;perspective-origin:50% 42%}
  .track{transform-style:preserve-3d}
}
.rail{display:flex;gap:10px;justify-content:center;padding-bottom:clamp(22px,4vh,44px);flex-wrap:wrap}
.rail a{width:10px;height:10px;border-radius:999px;border:1.5px solid var(--cyan);
  background:transparent;transition:background .25s,width .25s var(--ease)}
.rail a:hover,.rail a:focus-visible{background:var(--cyan);width:28px}
@media(max-width:820px){
  .slide{flex:0 0 84vw}
  .track{scroll-padding-inline:8vw;padding:0 8vw clamp(24px,4vh,48px)}
}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}.slide{animation:none}}

/* ---- prev / next arrows, restored from the original coverflow ----
   Same look: 56px circle, foam border, cyan on hover, 44px on phones. Positioned in the
   deck's side gutters, vertically centred on the card (the track's bottom padding is
   excluded from the centring). Hidden until public/js/gallery.js runs; without scripts
   the dots, keyboard arrows and touch swipe remain. */
.deck .arrow{position:absolute;z-index:3;top:calc((100% - clamp(30px,5vh,64px)) / 2);transform:translateY(-50%);
  width:56px;height:56px;border-radius:50%;padding:0;border:1.5px solid rgba(244,251,253,.5);
  background:rgba(4,18,31,.55);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);color:var(--ink);
  display:grid;place-items:center;cursor:pointer;transition:border-color .2s,color .2s,opacity .2s}
.deck .arrow[hidden]{display:none}
.deck .arrow svg{width:22px;height:22px}
.deck .arrow:hover{border-color:var(--cyan);color:var(--cyan)}
.deck .arrow:focus-visible{outline:2px solid var(--cyan-pale);outline-offset:3px}
.deck .arrow:disabled{opacity:.3;cursor:default;border-color:rgba(244,251,253,.5);color:var(--ink)}
/* In the gap between the centred card and its rotated neighbours, 24px off the card's edge.
   At the deck's far edges (left:clamp(12px,2vw,36px)) they would sit over the dimmed
   neighbour cards, which peek in to about 118px from each side at 1440. */
.deck .prev{left:calc(50% - min(410px,31vw) - 56px - 24px)}
.deck .next{right:calc(50% - min(410px,31vw) - 56px - 24px)}
.track{cursor:grab}
.track.dragging{cursor:grabbing;scroll-snap-type:none;user-select:none}
.track.dragging img{pointer-events:none}
@media (max-width:820px){
  /* phones: the cards fill 84vw, so the arrows sit in a row under the cards instead of over them */
  .track{padding-bottom:calc(clamp(24px,4vh,48px) + 56px)}
  .deck .arrow{width:44px;height:44px;top:auto;bottom:clamp(24px,4vh,48px);transform:none;backdrop-filter:none;-webkit-backdrop-filter:none}
  .deck .prev{left:calc(50% - 44px - 28px)}
  .deck .next{right:calc(50% - 44px - 28px)}
}

/* ---- the deck now flows, so release the old absolute hero ---- */
.hero{height:auto!important;min-height:100svh;display:flex;flex-direction:column;overflow:visible}
.hero .scene{position:absolute;inset:0;height:100%}
.ghead{position:static!important;padding:clamp(104px,13svh,152px) 24px 0;text-align:center}
.deck{position:relative;z-index:2;margin-top:auto}
.rail{position:relative;z-index:2;margin-top:auto}

/* ---- the header block was swallowing clicks meant for the nav ---- */
