@font-face {
  font-family: Bricolage;
  src: url("../main/assets/ui/fonts/bricolage-medium.woff2") format("woff2");
  font-weight: 400 900;
  font-display: swap;
}
@font-face {
  font-family: Instrument;
  src: url("../main/assets/case-studies/fonts/font-0.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: Instrument;
  font-weight: 500;
  src: url("../main/assets/case-studies/fonts/font-1.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: Instrument;
  font-weight: 600;
  src: url("../main/assets/case-studies/fonts/font-2.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: Instrument;
  font-weight: 700;
  src: url("../main/assets/case-studies/fonts/font-3.woff2") format("woff2");
  font-display: swap;
}
:root {
  --sky: #c5e0ed;
  --paper: #f5f3ec;
  --ink: #10242b;
  --muted: #415b64;
  --blue: #0d52d1;
  --line: #183b4828;
  --accent: #eaff7b;
  --nav: rgba(206, 229, 238, 0.88);
  --display: Bricolage, Arial, sans-serif;
  color-scheme: light;
}
html[data-theme="dark"] {
  --sky: #0d1d39;
  --paper: #151e28;
  --ink: #f3f2e9;
  --muted: #a8bfce;
  --blue: #80b4ff;
  --line: #b7d5fa25;
  --nav: rgba(13, 29, 57, 0.9);
  color-scheme: dark;
}
* {
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
  scroll-padding-top: 100px;
}
/* Lenis (app.js) drives wheel scrolling; native smooth-scroll would fight it */
html.lenis,
html.lenis body {
  height: auto;
}
html.lenis-smooth {
  scroll-behavior: auto !important;
}
html.lenis-stopped {
  overflow: clip;
}
body {
  margin: 0;
  background: var(--sky);
  color: var(--ink);
  font-family: Instrument, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  transition:
    background 0.5s,
    color 0.3s;
}
a {
  color: inherit;
  text-decoration: none;
}
button,
summary {
  font: inherit;
  color: inherit;
}
button {
  cursor: pointer;
  background: none;
  border: 0;
}
a,
button,
summary {
  -webkit-tap-highlight-color: transparent;
}
button,
a,
summary {
  touch-action: manipulation;
}
:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 6px;
}
::selection {
  background: var(--accent);
  color: #172c35;
}
h1,
h2,
h3,
p {
  margin: 0;
}
h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 500;
}
em {
  font-style: normal;
  color: var(--blue);
}
.eyebrow,
.nav,
.section-baseline,
.viewport-meta,
.project-meta,
.project-open,
.portrait-note,
.drag-hint,
footer,
.contact-links,
.status {
  font-family: Instrument, Arial, sans-serif;
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.025em;
}
.skip {
  position: fixed;
  top: -100px;
  left: 20px;
  z-index: 30;
  padding: 14px;
  background: var(--paper);
}
.skip:focus {
  top: 10px;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.atmosphere {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: -2;
  /* Sunlit pool: pale turquoise at the top deepening to teal; the WebGL layer draws caustics and ripples over it. */
  background:
    radial-gradient(ellipse at 70% 20%, #effbe655, transparent 40%),
    linear-gradient(180deg, #b2e9ec, #86d7df 50%, #62c4d0);
  transition: background 0.5s;
}
/* Hero -> About: the pool fades to paper as the card rises (--d from scene.js). */
.atmosphere::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--paper);
  opacity: var(--d, 0);
}
.light-beam {
  position: absolute;
  width: 145%;
  height: 135px;
  left: -20%;
  top: 29%;
  transform: rotate(-35deg);
  filter: blur(30px);
  background: #ffffed40;
}
.beam-two {
  top: 67%;
  height: 95px;
  opacity: 0.55;
}
/* No persistent full-page drafting grid. */
#scene {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}
#scene canvas {
  display: block;
  image-rendering: pixelated;
  width: 100%;
  height: 100%;
}
.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: 20;
  height: 88px;
  padding: 0 4.7%;
  display: flex;
  align-items: center;
  gap: 20px;
  font: 500 12px/1 Instrument, Arial, sans-serif;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  backdrop-filter: blur(14px);
  -webkit-mask-image: linear-gradient(#000 55%, transparent);
  mask-image: linear-gradient(#000 55%, transparent);
  opacity: 0;
  transition: opacity 0.3s;
}
.scrolled .nav::before {
  opacity: 1;
}
.wordmark {
  font: 600 23px var(--display);
  letter-spacing: -1.2px;
  white-space: nowrap;
  text-transform: none;
  margin-right: auto;
}
.brand-dot {
  color: var(--blue);
}
.brand-symbol {
  font-size: 24px;
  display: inline-block;
  margin-left: 10px;
  color: var(--blue);
  transition: transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.wordmark:hover .brand-symbol {
  transform: rotate(90deg);
}
.menu {
  display: contents;
}
.nav .menu-toggle,
.menu-fill,
.menu-note,
.menu-foot {
  display: none;
}
.nav button {
  text-transform: inherit;
  letter-spacing: inherit;
}
nav {
  display: flex;
  gap: 4px;
}
.nav a:not(.wordmark),
.nav button,
.nav summary {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.nav button:hover,
.nav summary:hover {
  color: var(--blue);
}
nav a > i {
  display: none;
}
nav a b {
  font-weight: inherit;
}
.nav nav a[href="#work"] span {
  display: none;
}
.nav nav a {
  position: relative;
  isolation: isolate;
  padding: 0 12px;
  transition: color 0.25s;
}
.nav nav a::before {
  content: "";
  position: absolute;
  inset: auto 12px 11px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.4s cubic-bezier(0.7, 0, 0.2, 1);
}
.nav nav a:hover,
.nav nav a:focus-visible {
  color: var(--blue);
}
.nav nav a:hover::before,
.nav nav a:focus-visible::before {
  transform: scaleX(1);
  transform-origin: left;
}
.settings {
  display: flex;
  gap: 22px;
  align-items: center;
  margin-left: 14px;
  padding-left: 24px;
  border-left: 1px solid var(--line);
}
.settings button {
  padding: 0;
}
.settings > button,
.settings summary {
  position: relative;
}
.settings > button::after,
.settings summary::after {
  content: "";
  position: absolute;
  inset: auto 0 12px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.35s cubic-bezier(0.7, 0, 0.2, 1);
}
.settings > button:hover::after,
.settings summary:hover::after,
#sound[open] summary::after {
  transform: scaleX(1);
  transform-origin: left;
}
.settings button span,
#sound-status {
  text-transform: uppercase;
}
details {
  position: relative;
}
summary {
  cursor: pointer;
  list-style: none;
}
summary::-webkit-details-marker {
  display: none;
}
.sound-panel {
  position: absolute;
  top: 50px;
  right: 0;
  padding: 22px;
  width: 245px;
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: 0 18px 50px #0002;
}
.sound-panel p {
  font-family: var(--display);
  font-size: 20px;
  margin-bottom: 14px;
}
.sound-panel button {
  width: 100%;
  justify-content: space-between;
  border-bottom: 1px solid var(--line);
}
.sound-panel small {
  display: block;
  margin-top: 14px;
  color: var(--muted);
}
.sound-panel {
  text-transform: none;
  letter-spacing: 0.02em;
  line-height: 1.5;
}
/* The HUD is a lone progress bar; white under difference blending inverts whatever is behind it. */
.viewport-meta {
  mix-blend-mode: difference;
}
.hud-scroll {
  margin: 0 auto;
  display: inline-flex;
  align-items: center;
}
.hud-bar {
  position: relative;
  width: 120px;
  height: 2px;
  border-radius: 2px;
  overflow: hidden;
  background: #ffffff4d;
}
.hud-bar i {
  position: absolute;
  inset: 0;
  background: #fff;
  transform: scaleX(0);
  transform-origin: left;
}
@media (max-width: 700px) {
  .nav {
    height: 68px;
    padding: 0 6%;
  }
  .wordmark {
    font-size: 21px;
    position: relative;
    z-index: 2;
  }
  .brand-symbol {
    font-size: 19px;
    margin-left: 5px;
  }
  .nav .menu-toggle {
    position: relative;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    min-width: 44px;
    margin-right: -10px;
    padding: 0 10px;
  }
  .menu-word {
    min-width: 5ch;
    text-align: right;
  }
  .menu-icon {
    position: relative;
    width: 24px;
    height: 10px;
  }
  .menu-icon i {
    position: absolute;
    inset: 0 0 auto;
    height: 2px;
    background: currentColor;
    transform-origin: left;
    transition: transform 0.45s cubic-bezier(0.7, 0, 0.2, 1);
  }
  .menu-icon i + i {
    top: auto;
    bottom: 0;
    transform: scaleX(0.55);
  }
  .is-open .menu-icon i {
    transform-origin: center;
    transform: translateY(4px) rotate(45deg);
  }
  .is-open .menu-icon i + i {
    transform: translateY(-4px) rotate(-45deg);
  }
  .menu {
    position: fixed;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    padding: 92px 6% calc(18px + env(safe-area-inset-bottom));
    visibility: hidden;
    overflow: hidden;
    transition: visibility 0s 0.75s;
  }
  .is-open .menu {
    visibility: visible;
    transition-delay: 0s;
  }
  .menu-fill {
    display: block;
    position: absolute;
    z-index: -1;
    top: 34px;
    right: calc(6% + 12px);
    width: 250vmax;
    height: 250vmax;
    border-radius: 50%;
    background: var(--paper);
    translate: 50% -50%;
    transform: scale(0);
    transition: transform 0.5s cubic-bezier(0.7, 0, 0.3, 1) 0.2s;
  }
  .is-open .menu-fill {
    transform: none;
    transition: transform 0.6s cubic-bezier(0.65, 0, 0.35, 1);
  }
  .menu nav {
    flex-direction: column;
    gap: 0;
    border-top: 1px solid var(--line);
  }
  .menu nav a {
    padding: 0;
    min-height: 0;
    padding-block: 12px 10px;
    align-items: baseline;
    gap: 14px;
    overflow: hidden;
    border-bottom: 1px solid var(--line);
    font: 500 clamp(44px, 14vw, 64px)/1 var(--display);
    letter-spacing: -0.045em;
    text-transform: none;
  }
  .menu nav a::before {
    display: none;
  }
  .menu nav a:hover,
  .menu nav a:focus-visible {
    color: var(--blue);
  }
  .menu nav a > i,
  .menu nav a > span {
    display: inline;
    font: 500 11px/1 Instrument, Arial, sans-serif;
    letter-spacing: 0.05em;
    font-style: normal;
    color: var(--blue);
    opacity: 1;
  }
  .menu nav a > i {
    width: 3ch;
    align-self: flex-start;
    margin-top: 10px;
  }
  .menu nav a > span {
    align-self: flex-start;
    margin-top: 6px;
  }
  .menu nav a b {
    display: inline-block;
    transform: translateY(105%);
    transition: transform 0.25s cubic-bezier(0.7, 0, 0.2, 1);
  }
  .menu nav a:nth-child(2) b { --n: 1; }
  .menu nav a:nth-child(3) b { --n: 2; }
  .is-open .menu nav a b {
    transform: none;
    transition: transform 0.55s cubic-bezier(0.2, 0.8, 0.2, 1) calc(220ms + var(--n, 0) * 60ms);
  }
  .menu nav,
  .menu nav a > i,
  .menu nav a > span,
  .menu .settings,
  .menu-note,
  .menu-foot {
    opacity: 0;
    transition: opacity 0.2s;
  }
  .is-open .menu nav,
  .is-open .menu nav a > i,
  .is-open .menu nav a > span,
  .is-open .menu .settings,
  .is-open .menu-note,
  .is-open .menu-foot {
    opacity: 1;
    transition: opacity 0.4s 0.32s;
  }
  .menu .settings {
    margin: auto 0 0;
    padding: 6px 0 0;
    border: 0;
    border-top: 1px solid var(--line);
    justify-content: space-between;
  }
  .menu .sound-panel {
    position: fixed;
    inset: auto 6% calc(120px + env(safe-area-inset-bottom));
    width: auto;
  }
  .menu-note {
    display: grid;
    gap: 6px;
    margin-top: 28px;
    text-transform: none;
    letter-spacing: 0.02em;
    color: var(--muted);
  }
  .nav .menu-note a {
    color: var(--blue);
    font: 500 20px/1.2 var(--display);
    letter-spacing: -0.02em;
  }
  .menu-foot {
    display: flex;
    justify-content: space-between;
    margin-top: 10px;
    font-size: 10px;
  }
  .menu-open,
  .menu-open body {
    overflow: hidden;
  }
  .motion-paused .menu,
  .motion-paused .menu *,
  .motion-paused .menu-icon i {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
  }
  .hud-bar {
    width: 80px;
  }
}
.hero {
  min-height: 900px;
  height: 100svh;
  max-height: 1200px;
  padding: 124px 4.7% 55px;
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 1;
}
.hero-intro {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 35px;
  position: relative;
  z-index: 3;
}
.hero-intro > .eyebrow {
  font: 500 23px/1.3 var(--display);
  letter-spacing: -0.7px;
}
.hero-intro > p:not(:first-child) {
  font: 12px/1.65 Instrument, Arial, sans-serif;
}
.hero-note {
  justify-self: end;
}
.hero-note > span:last-child {
  color: var(--muted);
}
.status-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--blue);
  margin-right: 7px;
  vertical-align: middle;
  box-shadow: 0 0 0 4px #165df112;
}
.sculpture-space {
  flex: 1;
  position: relative;
  min-height: 330px;
}
.fallback-word,
.contact-fallback {
  position: absolute;
  left: 10%;
  right: 10%;
  top: 15%;
  font: 700 clamp(100px, 20vw, 350px)/1 var(--display);
  letter-spacing: -0.08em;
  text-align: center;
  color: #124fbf;
  text-shadow:
    0 2px #cde7ff,
    0 8px #114aba,
    0 20px 30px #16468344;
  transform: rotate(-7deg);
  transition: opacity 0.5s;
}
.scene-ready .fallback-word,
.scene-ready .contact-fallback {
  opacity: 0;
}
.sculpture-control {
  position: absolute;
  inset: 8% 5% 0;
  z-index: 5;
  cursor: grab;
  touch-action: pan-y;
  border-radius: 50%;
}
.sculpture-control:active {
  cursor: grabbing;
}
.drag-hint {
  position: absolute;
  right: 0;
  bottom: 10%;
  display: flex;
  gap: 14px;
  align-items: center;
  pointer-events: none;
}
.drag-hint > span {
  border: 1px solid var(--line);
  border-radius: 50%;
  padding: 7px;
  font-size: 18px;
}
.hero-bottom {
  position: relative;
  z-index: 3;
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: 25px;
}
.hero h1 {
  font-size: clamp(45px, 5.7vw, 87px);
  line-height: 1.02;
  letter-spacing: -0.05em;
}
.hero h1 em {
  position: relative;
}
.hero h1 em:after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1px;
  border-bottom: 2px solid currentColor;
  transform: rotate(-2deg);
}
.text-link {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  min-height: 46px;
  font-size: 13px;
  border-bottom: 1px solid var(--line);
  transition:
    color 0.2s,
    border-color 0.2s;
}
.text-link:hover {
  color: var(--blue);
  border-color: var(--blue);
}
.explore {
  min-width: 165px;
  margin-bottom: 5px;
}
.section-baseline {
  display: flex;
  justify-content: space-between;
  margin-top: 32px;
  border-top: 1px solid var(--line);
  padding-top: 14px;
  color: var(--muted);
}
.viewport-meta {
  position: fixed;
  bottom: 13px;
  left: 4.7%;
  right: 4.7%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 10;
  pointer-events: none;
}
.intro {
  --p: 1;
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding: 0 4% clamp(64px, 6vw, 96px);
}
.portrait-block,
.intro-copy {
  padding-inline: clamp(16px, 1.3vw, 24px);
}
.portrait-block {
  position: relative;
  grid-column: 3;
  grid-row: 2;
  margin: clamp(56px, 7vw, 104px) 0 0;
  max-width: 440px;
}
.portrait-frame {
  --r: clamp(0, calc((var(--p) - 0.3) * 2), 1);
  position: relative;
  aspect-ratio: 5/6;
  overflow: hidden;
  background: #070e1a;
  transform: translate3d(0, calc((1 - var(--r)) * 56px), 0) rotate(calc((1 - var(--r)) * -4deg));
  transform-origin: 0 100%;
}
.portrait-frame:after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--paper);
  transform: translate3d(0, calc(var(--r) * -101%), 0);
  transition: background 0.5s;
}
.portrait-frame img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 20%;
  transform: scale(calc(1 + (1 - var(--r)) * 0.18));
  transform-origin: 45% 30%;
}
.signature {
  position: absolute;
  z-index: 3;
  top: 2%;
  left: calc(clamp(16px, 1.3vw, 24px) - 5%);
  width: 64%;
  overflow: visible;
  pointer-events: none;
  transform: rotate(-9deg) skewX(-10deg);
}
.signature path {
  fill: none;
  stroke: #d4fb4a;
  stroke-width: 4.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 0.9s cubic-bezier(0.65, 0, 0.25, 1);
}
.intro.sig-wait .signature path {
  stroke-dashoffset: 1;
  transition: none;
}
.portrait-note {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-top: 14px;
  color: var(--muted);
}
.intro-copy {
  grid-column: 1 / 3;
  grid-row: 2;
  margin-top: clamp(56px, 7vw, 104px);
}
.intro-copy h2,
.intro-copy > p {
  font: 500 clamp(30px, 3.5vw, 54px)/1.08 Instrument, Arial, sans-serif;
  letter-spacing: -0.02em;
  word-spacing: -0.04em;
  max-width: 15em;
}
.intro-copy > p {
  margin-top: 0.55em;
  color: var(--muted);
}
.intro-copy > p a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 0.05em;
  text-underline-offset: 0.12em;
  transition: color 0.2s;
}
.intro-copy > p a:last-child {
  white-space: nowrap;
}
.intro-copy > p a:hover {
  color: var(--blue);
}
/* Gallery: #work section. Its column rhythm stays local to the work surface. */
.work {
  --g: 20px;
  --cols: 12;
  position: relative;
  z-index: 2;
  background: var(--paper);
  padding: 96px 4% 0;
  transition: background 0.5s;
}
.work .work-heading,
.work .work-grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  column-gap: var(--g);
  padding-inline: calc(var(--g) / 2);
  margin: 0;
  width: auto;
}
.work .work-heading {
  row-gap: 32px;
  align-items: end;
  padding-bottom: 56px;
}
.work .work-heading h2 {
  grid-column: 1 / 10;
  grid-row: 1;
  align-self: last baseline;
  font-size: clamp(56px, 6.4vw, 108px);
  line-height: 0.92;
  letter-spacing: -0.045em;
  margin: 0;
}
/* heading row: headline and lede sit on the headline's last baseline, each on its own column edge */
.work .work-lede {
  grid-column: 10 / 13;
  grid-row: 1;
  align-self: last baseline;
  justify-self: end;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  max-width: 30ch;
  margin: 0;
}
/* one big card per project in a zigzag (right, left, right); the open third holds that project's drawing (art.js) */
.work .work-grid {
  row-gap: clamp(80px, 9vw, 150px);
  padding-bottom: 120px;
}
.work .project {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  min-width: 0;
  margin: 0;
}
.work .tile-lead {
  grid-column: 5 / -1;
  grid-row: 1;
  display: grid;
  grid-template-areas: "media" "cap";
}
.work .project-two .tile-lead {
  grid-column: 1 / 9;
}
.project-art {
  grid-column: 1 / 4;
  grid-row: 1;
  position: relative;
  margin-block: 8% calc(8% + 30px);
  color: var(--ink);
}
.project-two .project-art {
  grid-column: 10 / -1;
}
.project-art canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.work .project-media {
  grid-area: media;
  aspect-ratio: 16 / 9;
}
.work .tile-cap {
  grid-area: cap;
}
.work .project-media {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 2px;
  background: #e9e7df;
  isolation: isolate;
}
/* bend.js: the images and their grounds are drawn on a fixed WebGL sheet behind the tiles; the DOM keeps layout,
   links, captions and tags; its hidden images, stat text and reveal wipe are what the sheet reads. */
.work-gl {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}
.work.gl {
  isolation: isolate; /* keeps the z -1 sheet above the section's paper */
}
.work.gl .project-media {
  background: transparent;
}
.work.gl .project-media :is(img, video),
.work.gl .project-media::after {
  opacity: 0 !important;
}
.work .project-media > a {
  position: absolute;
  inset: 0;
  display: block;
  aspect-ratio: auto;
}
.work .project-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition:
    filter 0.5s,
    transform 0.5s;
}
/* the product shot stays hidden: the page transition clones it. Open state frosts the film itself. */
.work .project-media .shot {
  display: none;
}
.work .is-open video {
  filter: blur(18px);
  transform: scale(1.08); /* keeps the blurred edge off the card border */
}
/* hover: the project's name and what it changed, centred on the frosted shot */
.work .project-info {
  grid-area: media;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 0;
  padding: 24px;
  text-align: center;
  color: #10242b;
  pointer-events: none;
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.3s ease,
    transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.work:not(.gl) .project-info {
  background: rgb(230 225 212 / 0.45); /* DOM fallback: the same wash bend.js paints */
}
.work .is-open + .project-info {
  opacity: 1;
  transform: none;
  transition-delay: 0.22s;
}
.info-title {
  font: 500 clamp(34px, 4.2vw, 68px)/0.92 var(--display);
  letter-spacing: -0.035em;
  text-transform: uppercase;
}
.info-did {
  max-width: 34ch;
  font-size: clamp(14px, 1.15vw, 18px);
  line-height: 1.4;
  text-wrap: balance;
}
.work .tile:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}
.work .project-media > a:focus-visible {
  outline-offset: -4px;
}
/* the hover label is redundant with the custom cursor's "View" state */
.work .project-open {
  display: none;
}
/* the fixed HUD steps aside while the gallery is on screen (gallery.js sets .in-work) */
.viewport-meta {
  transition: opacity 0.3s;
}
.in-work .viewport-meta {
  opacity: 0;
  pointer-events: none;
}
.work .tile-cap {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin: 0;
  padding-top: 10px;
  font: 500 12px/1.3 Instrument, Arial, sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}
.work .tile-cap > span:first-child {
  font-weight: 700;
}
.work .tile-cap > span:last-child {
  white-space: nowrap;
}
/* scroll entry: a paper panel wipes off (transform only) while the image settles from 1.12x */
.work .project-media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  background: var(--paper);
  transform-origin: 50% 0;
  transform: scaleY(0);
  pointer-events: none;
}
.work.js-reveal .tile:not(.is-in) .project-media::after {
  transform: scaleY(1);
}
.work.js-reveal .tile .project-media::after {
  transition: transform 0.75s cubic-bezier(0.76, 0, 0.24, 1) var(--d, 0s);
}
@media (hover: hover) {
  /* the caption answers the hover too: the title steps in */
  body:not(.motion-paused) .work.js-reveal .tile.is-in:hover .tile-cap > span:first-child {
    transform: translateX(10px);
    transition-delay: 0s;
  }
  .work .tile:hover .tile-cap > span:first-child {
    color: var(--blue);
  }
}
.work.js-reveal .tile:not(.is-in) .tile-cap > span {
  opacity: 0;
  transform: translateY(6px);
}
.work.js-reveal .tile .tile-cap > span {
  display: inline-block;
  transition:
    opacity 0.5s ease calc(var(--d, 0s) + 0.3s),
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--d, 0s) + 0.3s);
}
.motion-paused .work .tile .project-media::after {
  transform: scaleY(0);
  transition: none;
}
.motion-paused .work .tile .tile-cap > span {
  opacity: 1;
  transform: none;
  transition: none;
}
@media (max-width: 1000px) and (min-width: 701px) {
  .work {
    --g: 16px;
  }
  .work .work-heading h2 {
    grid-column: 1 / -1;
  }
  .work .work-lede {
    grid-column: 7 / 13;
    grid-row: 2;
  }
  .work .tile-lead,
  .work .project-two .tile-lead {
    grid-column: 1 / -1;
  }
  .project-art {
    display: none;
  }
}
/* narrow screens: the film stays, and the title sits under the card instead of over it */
@media (max-width: 1000px) {
  .work .tile-lead {
    grid-template-areas: "media" "cap" "info";
  }
  .work .project-info {
    grid-area: info;
    align-items: start;
    gap: 6px;
    padding: 14px 0 0;
    text-align: left;
    color: var(--ink);
    background: none;
    opacity: 1;
    transform: none;
  }
  .info-title {
    font-size: 30px;
  }
}
@media (max-width: 700px) {
  /* overlay is inset 6%, 2 cols -> 4-col grid; every card aligns full width to the gutters */
  .work {
    --g: 12px;
    --cols: 4;
    padding: 72px 6% 0;
  }
  .work .work-heading {
    row-gap: 24px;
    padding-bottom: 44px;
  }
  .work .work-heading h2 {
    grid-column: 1 / -1;
  }
  .work .work-lede {
    grid-column: 2 / -1;
  }
  .work .work-heading h2 {
    font-size: 58px;
  }
  .work .work-lede {
    grid-row: 2;
    font-size: 13px;
  }
  .work .work-grid {
    row-gap: 64px;
    padding-bottom: 56px;
  }
  .work .tile-lead,
  .work .project-two .tile-lead {
    grid-column: 1 / -1;
  }
  .project-art {
    display: none;
  }
  .work .tile-cap {
    flex-wrap: wrap;
    font-size: 11px;
    gap: 2px 8px;
    padding-top: 10px;
  }
  .work .project-open {
    display: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .work .tile .project-media::after {
    display: none;
  }
  .work .tile .tile-cap > span {
    scale: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}
#trail {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  pointer-events: none;
  overflow: hidden;
}
/* Custom cursor. System cursor is hidden only while .has-cursor is on (mouse, motion allowed). */
.has-cursor,
.has-cursor * {
  cursor: none !important;
}
.cursor {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  transition: opacity 0.2s;
  will-change: transform;
}
.has-cursor .cursor {
  opacity: 1;
}
.has-cursor .cursor.is-out {
  opacity: 0;
}
.cursor-tilt,
.cursor-body {
  position: absolute;
  left: 0;
  top: 0;
}
.cursor-tilt {
  will-change: transform;
}
.cursor-body {
  transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}
.is-down .cursor-body {
  transform: scale(0.82);
}
.cursor-arrow {
  position: absolute;
  left: -6.5px;
  top: -1.7px;
  width: 52px;
  height: 55px;
  overflow: visible;
  transform-origin: 6.5px 1.7px;
  filter: drop-shadow(0 6px 7px rgba(8, 36, 140, 0.35));
  transition:
    transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.2s;
}
.cursor-spark,
.cursor-beam,
.cursor-disc {
  position: absolute;
  opacity: 0;
  transition:
    transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.12s;
}
.cursor-spark {
  left: 30px;
  top: 30px;
  color: var(--blue);
  font: 700 17px/1 var(--display);
  transform: scale(0) rotate(-90deg);
}
.cursor-beam {
  left: -1.5px;
  top: -13px;
  width: 3px;
  height: 26px;
  border-radius: 2px;
  background: linear-gradient(90deg, #8db3ff, #1f5cff 60%, #0a2fae);
  box-shadow: 0 0 0 1px #fff8;
  transform: scaleY(0.3);
}
.cursor-disc {
  left: -64px;
  top: -64px;
  width: 128px;
  height: 128px;
  border-radius: 50%;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 6px;
  color: #fff;
  background: radial-gradient(circle at 34% 26%, #ffffffcc 0 4%, #9ab9ff 13%, #2a66ff 42%, #0c3bd0 72%, #061f86);
  box-shadow:
    inset 0 -10px 18px #00114d66,
    inset 0 4px 8px #ffffff55,
    0 16px 32px #0b2fa04d;
  transform: scale(0.2);
}
.cursor-disc b {
  font: 600 19px/1 var(--display);
  letter-spacing: -0.01em;
}
.cursor-disc i {
  order: -1;
  font: 700 26px/1 var(--display);
  font-style: normal;
  animation: cursor-spin 4s linear infinite;
}
.cursor[data-state="drag"] .cursor-disc b::before {
  content: "← ";
}
.cursor[data-state="drag"] .cursor-disc b::after {
  content: " →";
}
@keyframes cursor-spin {
  to {
    transform: rotate(1turn);
  }
}
.cursor[data-state="link"] .cursor-arrow {
  transform: scale(0.78) rotate(-10deg);
}
.cursor[data-state="link"] .cursor-spark {
  opacity: 1;
  transform: none;
}
.cursor[data-state="text"] .cursor-arrow,
.cursor[data-state="view"] .cursor-arrow,
.cursor[data-state="drag"] .cursor-arrow,
.cursor[data-state="lens"] .cursor-arrow {
  opacity: 0;
  transform: scale(0.4);
}
.cursor[data-state="text"] .cursor-beam {
  opacity: 1;
  transform: none;
}
.cursor[data-state="view"] .cursor-disc,
.cursor[data-state="drag"] .cursor-disc {
  opacity: 1;
  transform: none;
}
/* Hero word: the glass itself is the cursor (a lens in scene.js); a thin ring outlines the lens. */
.cursor[data-state="lens"] .cursor-disc {
  opacity: 1;
  transform: scale(1.12);
  background: none;
  box-shadow:
    inset 0 0 0 1px #ffffffb0,
    0 0 0 1px #0b2fa024;
}
.cursor[data-state="lens"] .cursor-disc > * {
  visibility: hidden;
}
.cursor[data-state="drag"] .cursor-disc {
  left: -60px;
  top: -30px;
  width: 120px;
  height: 60px;
  border-radius: 30px;
  grid-auto-flow: column;
  gap: 6px;
  color: #0b37c9;
  background: radial-gradient(120% 90% at 30% 20%, #fff 0 20%, #eef3ff 45%, #c9d8ff);
  box-shadow:
    inset 0 -6px 12px #3a63d94d,
    inset 0 2px 4px #fff,
    0 14px 30px #0b2fa040;
}
.cursor[data-state="drag"] .cursor-disc b {
  font-size: 17px;
}
.cursor[data-state="drag"] .cursor-disc i {
  display: none;
}
.is-down.cursor[data-state="drag"] .cursor-disc {
  transform: scaleX(1.12) scaleY(0.94);
}
.burst {
  position: fixed;
  z-index: 25;
  color: var(--blue);
  pointer-events: none;
  font: 30px var(--display);
  animation: burst 0.8s forwards;
}
@keyframes burst {
  from {
    opacity: 1;
    transform: translate(-50%, -50%) scale(0.5) rotate(0);
  }
  to {
    opacity: 0;
    transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1.3) rotate(90deg);
  }
}
html[data-theme="dark"] .light-beam {
  opacity: 0.1;
}
html[data-theme="dark"] .atmosphere {
  background: radial-gradient(ellipse at 65% 35%, #26497a70, transparent 50%), var(--sky);
}
.motion-paused .burst {
  display: none;
}
.motion-paused .light-beam {
  animation: none;
}
.no-scene .drag-hint {
  display: none;
}
@media (min-width: 1700px) {
  .hero,
  .intro,
  .work,
  .contact {
    padding-inline: max(4.7%, calc((100vw - 1550px) / 2));
  }
}
@media (max-width: 1000px) {
  .nav {
    gap: 14px;
  }
  .settings {
    gap: 13px;
  }
  nav {
    gap: 22px;
  }
  .hero {
    min-height: 830px;
  }
  .hero-intro {
    grid-template-columns: 1fr 1.3fr;
    gap: 25px;
  }
  .hero-intro > .hero-note {
    display: none;
  }
  .project-one {
    width: 100%;
  }
  .project-two,
  .project-three {
    width: 85%;
  }
  .hero h1 {
    font-size: 5.6vw;
  }
}
@media (max-width: 700px) {
  html {
    scroll-padding-top: 118px;
  }
  .hero {
    height: 92svh;
    min-height: 760px;
    max-height: 1000px;
    padding: 135px 6% 45px;
  }
  .hero-intro {
    gap: 20px;
    grid-template-columns: 1fr 1fr;
  }
  .hero-intro > .eyebrow {
    font-size: 20px;
  }
  .hero-intro > p:not(:first-child) {
    font-size: 10px;
    line-height: 1.5;
  }
  .sculpture-space {
    min-height: 260px;
  }
  .sculpture-control {
    inset: 10% 0 0;
  }
  .drag-hint {
    font-size: 9px;
    bottom: 7%;
  }
  .hero-bottom {
    display: block;
  }
  .hero h1 {
    font-size: clamp(34px, 8.3vw, 57px);
    line-height: 1.04;
    letter-spacing: -0.045em;
  }
  .explore {
    font-size: 12px;
    margin-top: 15px;
    min-width: 135px;
  }
  .section-baseline {
    font-size: 8px;
    margin-top: 20px;
    gap: 12px;
  }
  .viewport-meta {
    left: 6%;
    right: 6%;
  }
  .intro {
    grid-template-columns: minmax(0, 1fr);
    padding: 0 6% 120px;
  }
  .portrait-block,
  .intro-copy {
    padding-inline: 0;
  }
  .portrait-block {
    grid-column: 1;
    grid-row: auto;
    order: 1;
    margin-top: 44px;
    max-width: none;
  }
  .portrait-frame {
    aspect-ratio: 4/5;
  }
  .signature {
    left: -3%;
    top: 1%;
    width: 62%;
  }
  .portrait-note {
    font-size: 10px;
  }
  .intro-copy {
    grid-column: 1;
    grid-row: auto;
    margin-top: 36px;
  }
  .intro-copy h2,
  .intro-copy > p {
    font-size: clamp(25px, 7vw, 32px);
    line-height: 1.08;
  }
  .work {
    padding: 65px 6% 20px;
  }
  .work-heading {
    align-items: start;
    gap: 20px;
    margin-bottom: 45px;
  }
  .work-heading h2 {
    font-size: 58px;
    margin-top: 18px;
  }
  .work-heading > p {
    font-size: 11px;
    margin: 30px 0 0;
    max-width: 110px;
  }
  .work-heading > p > span {
    font-size: 9px;
    margin-top: 15px;
  }
  .project-one,
  .project-two,
  .project-three {
    width: 100%;
    margin-bottom: 70px;
  }
  .project-meta {
    font-size: 9px;
    gap: 14px;
  }
  .project-media > a {
    aspect-ratio: 4/3;
  }
  .project-media img,
  .project-media video {
    object-fit: contain;
  }
  .project-caption {
    grid-template-columns: 1fr;
    gap: 18px;
    padding-top: 20px;
  }
  .project-caption h3 {
    font-size: 35px;
  }
  .project-caption p {
    font-size: 13px;
  }
  .project-open {
    display: none;
  }
  .fallback-word {
    top: 30%;
    font-size: 24vw;
  }
  .sculpture-control:focus-visible {
    outline-offset: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *:before,
  *:after {
    transition: none !important;
    animation: none !important;
  }
  #trail,
  .burst {
    display: none;
  }
  .drag-hint {
    display: none;
  }
}
/* The scene shares the page; type and controls keep a stable reading plane. */
#scene {
  z-index: 2;
}
.hero-intro,
.hero-bottom {
  z-index: 5;
}
.intro {
  z-index: 3;
}
.work {
  z-index: auto;
}
.work-heading,
.project {
  position: relative;
  z-index: 5;
}
.hero-intro > p:not(:first-child) {
  font-size: 13px;
}
@media (min-width: 701px) and (max-height: 850px) {
  .hero {
    min-height: 720px;
    padding-top: 112px;
    padding-bottom: 42px;
  }
  .sculpture-space {
    min-height: 210px;
  }
  .hero h1 {
    font-size: clamp(40px, 4.8vw, 72px);
  }
  .section-baseline {
    margin-top: 20px;
    padding-top: 10px;
  }
  .hero-intro > .eyebrow {
    font-size: 21px;
  }
  .hero-intro > p:not(:first-child) {
    font-size: 11px;
  }
}
@media (max-width: 700px) {
  .hero-intro > p:not(:first-child) {
    font-size: 10px;
  }
}

/* Section-local structure replaces the removed full-page reference grid and portal stage. */
@media (max-width: 700px) {
  .hero-intro > p:not(:first-child) {
    font-size: 11px;
  }
  .work-heading {
    display: block;
  }
  .work-heading h2 {
    font-size: 61px;
  }
  .work-heading > p {
    max-width: none;
    margin-top: 22px;
    font-size: 12px;
  }
  .work-heading > p > span {
    margin-top: 9px;
  }
  .project-meta {
    font-size: 9px;
  }
  .hero-intro {
    grid-template-columns: 1fr 1.1fr;
  }
}
.work {
  clip-path: none;
}

/* Hero: one lockup. The glass-tube "Robert" (scene.js) writes itself in one continuous line from the
   first frame, with clear air above the headline. The headline types on in step with the pen: scene.js
   writes --pen (0..1) on the h1, each .char (hero-intro.js sets --i and --n) fades and settles as the pen
   passes its share of the word. body.stroke-done marks the end. Fallbacks: no JS reveals by animation at
   2.4s, no WebGL (no-scene) or a scene that never boots shows the text, reduced motion shows the final
   frame. The HUD scroll readout stays hidden until the word is written. */
.hero .sculpture-space {
  position: relative;
}
.hero .hero-bottom {
  z-index: auto;
  align-items: end;
  opacity: calc(1 - var(--veil, 0) * 1.6);
}
.hero h1 {
  font-size: clamp(44px, 5.4vw, 104px);
  font-weight: 800;
  line-height: 0.92;
  letter-spacing: -0.045em;
  color: var(--ink);
}
.hero h1 em {
  color: var(--blue);
}
.hero h1 em:after {
  display: none;
}
/* Line masks: padding gives the comma and the caps room, the negative margin keeps the layout. */
.hero h1 .line {
  display: block;
  overflow: hidden;
  padding: 0.12em 0.04em 0.14em 0;
  margin: -0.12em -0.04em -0.14em 0;
}
.hero h1,
.hero .explore {
  position: relative;
  z-index: 3;
}
.hero h1 .line > span {
  display: block;
  animation: hero-mask 0.9s cubic-bezier(0.2, 0.9, 0.2, 1) 2.4s both;
}
.hero h1.split .line > span {
  animation: none;
}
.hero h1 .word {
  display: inline-block;
  white-space: nowrap;
}
.hero h1 .char {
  --show: min(1, max(0, var(--pen, 0) * var(--n, 16) - var(--i)));
  display: inline-block;
  opacity: var(--show);
  transform: translate3d(0, calc((1 - var(--show)) * 0.12em), 0);
}
.stroke-done .hero h1 .char,
.no-scene .hero h1 .char,
.motion-paused .hero h1 .char {
  opacity: 1;
  transform: none;
}
body:not(.stroke-done):not(.no-scene) .hud-scroll {
  opacity: 0;
}
@keyframes hero-mask {
  from {
    transform: translate3d(0, 115%, 0);
  }
}
.hero-intro > p:not(:first-child) {
  color: var(--ink);
  font-size: 14px;
  font-weight: 400;
}
.hero-intro > * {
  animation: hero-fade 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.2s both;
}
.hero-intro > :nth-child(2) {
  animation-delay: 0.3s;
}
.hero-intro > :nth-child(3) {
  animation-delay: 0.4s;
}
.hero .explore {
  animation: hero-fade 0.9s cubic-bezier(0.16, 1, 0.3, 1) 1.9s both;
}
.hero .drag-hint {
  display: none;
}
.in-hero .hud-scroll {
  opacity: 0;
  transition: opacity 0.3s;
}
.streaks {
  animation: hero-glow 1.2s ease 0.1s both;
}
.fallback-word {
  animation: hero-fade 0.6s ease 2.4s both;
}
.no-scene .fallback-word {
  animation-delay: 0s;
}
.atmosphere > * {
  will-change: transform;
}
.light-beam {
  animation:
    hero-glow 1.6s ease both,
    beam-drift 16s ease-in-out -4s infinite alternate;
}
.beam-two {
  animation-duration: 1.6s, 21s;
  animation-delay: 0.2s, -11s;
}
.caustic {
  position: absolute;
  inset: -25%;
  background:
    radial-gradient(closest-side at 28% 34%, #fffbe2c0, transparent),
    radial-gradient(closest-side at 72% 58%, #f2fbffb0, transparent),
    radial-gradient(closest-side at 50% 80%, #fff6d680, transparent);
  background-size: 55% 45%, 60% 50%, 50% 40%;
  background-repeat: no-repeat;
  background-position: 10% 20%, 90% 40%, 40% 90%;
  filter: blur(30px);
  opacity: 0.3;
  animation:
    hero-glow 1.8s ease 0.1s both,
    caustic-drift 24s ease-in-out infinite alternate;
}
.streaks {
  opacity: 0.6;
  position: absolute;
  left: -10%;
  top: -10%;
  width: 120%;
  height: 120%;
}
.lamp {
  position: absolute;
  left: -300px;
  top: -300px;
  width: 600px;
  height: 600px;
  border-radius: 50%;
  background: radial-gradient(closest-side, #fffbeaa0, #fffbea00);
  opacity: 0;
}
html[data-theme="dark"] .streaks {
  opacity: 0.18;
}
html[data-theme="dark"] .caustic {
  opacity: 0.12;
}
.motion-paused .caustic {
  animation: none;
}
@keyframes hero-fade {
  from {
    opacity: 0;
    transform: translate3d(0, 14px, 0);
  }
}
@keyframes hero-underline {
  from {
    transform: rotate(-2deg) scaleX(0);
  }
  to {
    transform: rotate(-2deg) scaleX(1);
  }
}
@keyframes hero-glow {
  from {
    opacity: 0;
  }
}
@keyframes beam-drift {
  from {
    transform: rotate(-35deg) translate3d(-7%, -20px, 0);
  }
  to {
    transform: rotate(-35deg) translate3d(7%, 40px, 0);
  }
}
@keyframes caustic-drift {
  from {
    transform: translate3d(-4%, -2%, 0) rotate(-4deg) scale(1);
  }
  to {
    transform: translate3d(5%, 3%, 0) rotate(5deg) scale(1.08);
  }
}
@media (max-width: 700px) {
  .hero h1 {
    font-size: clamp(44px, 13vw, 64px);
  }
  /* Phone lockup: the word fills the middle band of the screen (scene.js centres it), the headline
     and link sit under it toward the bottom. The hero fills the screen so the next section never
     peeks in under it while the scene boots. */
  .hero {
    height: 100svh;
    min-height: 700px;
  }
  .hero .sculpture-space {
    flex: 0 0 auto;
    min-height: 0;
    height: 44vw;
    margin-top: auto;
  }
  .hero .hero-bottom {
    padding-bottom: max(56px, 8svh);
  }
  .hero-intro > p:not(:first-child) {
    font-size: 12px;
  }
  .hero-intro > p:not(:first-child) br {
    display: none;
  }
}

/* Finale: one short line over the lit glass "Robert" (scene.js inflates the letters into
   .contact-word, their own band), a copyable address and a one-row footer. On arrival a sky dome
   swells out of the page paper (scroll-driven mask) and takes over the screen. */
.contact {
  position: relative;
  height: 100svh;
  min-height: 720px;
  max-height: 1100px;
  padding: 104px 4.7% 36px;
  display: flex;
  flex-direction: column;
}
.contact-top {
  position: relative;
  z-index: 5;
  display: flex;
  justify-content: space-between;
  gap: 20px;
}
.contact-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-rows: auto 1fr;
  padding-top: clamp(28px, 6vh, 64px);
}
.contact-word {
  position: relative;
  min-height: 0;
}
.contact-fallback {
  top: 50%;
  left: 6%;
  right: 6%;
  translate: 0 -50%;
  font-size: clamp(90px, 19vw, 330px);
}
.contact-title {
  position: relative;
  z-index: 5;
  font: 500 clamp(40px, 5.4vw, 96px)/1 var(--display);
  letter-spacing: -0.05em;
}
.ct-line {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  padding: 0 0.04em 0.07em;
}
.ct-line > span {
  display: inline-block;
}
.contact-bottom {
  position: relative;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 22px 40px;
  padding-top: 22px;
}
.contact-label,
.contact-copy-btn,
.contact-links a,
footer {
  font: 500 11px/1 Instrument, Arial, sans-serif;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.contact-label {
  color: var(--muted);
  margin-bottom: 12px;
}
.contact-mail-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
}
.contact-email {
  font: 500 clamp(26px, 3.4vw, 54px)/1.15 var(--display);
  letter-spacing: -0.035em;
  padding-bottom: 3px;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 2px no-repeat;
  transition:
    background-size 0.5s cubic-bezier(0.2, 0.7, 0.2, 1),
    color 0.2s;
}
.contact-email:hover,
.contact-email:focus-visible {
  color: var(--blue);
  background-size: 100% 2px;
}
.contact-copy-btn {
  display: inline-grid;
  place-items: center;
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  overflow: hidden;
  transition:
    background-color 0.25s,
    color 0.25s;
}
.contact-copy-btn > span {
  grid-area: 1 / 1;
  transition:
    opacity 0.2s,
    transform 0.35s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.copy-done,
.is-copied .copy-idle {
  opacity: 0;
  transform: translateY(-120%);
}
.copy-done {
  transform: translateY(120%);
}
.is-copied .copy-done {
  opacity: 1;
  transform: none;
}
.contact-copy-btn:hover,
.is-copied {
  background: var(--ink);
  color: var(--paper);
}
.contact-links {
  display: flex;
  gap: 8px 32px;
}
.contact-links a,
footer a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.contact-links a:hover,
footer a:hover {
  color: var(--blue);
}
footer {
  position: relative;
  z-index: 5;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: center;
  padding: 0 4.7% 28px;
  letter-spacing: 0.1em;
}
footer > * {
  padding: 10px 18px 0;
}
footer > :first-child {
  padding-left: 0;
}
footer > :nth-child(2) {
  text-align: center;
}
footer > a {
  justify-self: end;
  gap: 8px;
  padding-right: 0;
}
footer > a span {
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
}
footer > a:hover span {
  transform: translateY(-4px);
}
/* Arrival: contact.js arms the section, then flips .is-in once it is a third in view. */
.ct-line > span,
.contact-bottom {
  transition: transform 1s cubic-bezier(0.16, 0.84, 0.2, 1), opacity 0.8s;
}
.contact-bottom {
  transition-delay: 0.45s;
}
@media (prefers-reduced-motion: no-preference) {
  body:not(.motion-paused) .contact.arm:not(.is-in) .ct-line > span {
    transform: translate3d(0, 108%, 0) rotate(5deg);
  }
  body:not(.motion-paused) .contact.arm:not(.is-in) .contact-bottom {
    opacity: 0;
    transform: translate3d(0, 28px, 0);
  }
}
@media (min-width: 701px) and (max-height: 850px) {
  .contact {
    min-height: 640px;
    padding-top: 96px;
  }
  .contact-title {
    font-size: clamp(36px, 4.8vw, 84px);
  }
}
@media (max-width: 700px) {
  .contact {
    height: 92svh;
    min-height: 640px;
    padding: 92px 6% 28px;
  }
  .contact-top .eyebrow,
  .status {
    font-size: 9px;
  }
  .contact-title {
    font-size: clamp(34px, 10vw, 48px);
  }
  .ct-line {
    white-space: normal;
  }
  .contact-email {
    font-size: clamp(21px, 6.2vw, 28px);
  }
  .contact-links {
    gap: 28px;
  }
  footer {
    grid-template-columns: 1fr auto;
    padding: 0 6% 20px;
    font-size: 9px;
  }
  footer > :nth-child(2) {
    display: none;
  }
}
/* Keep the last child's bottom margin inside the paper section (it collapsed out as a sky strip). */
.work {
  display: flow-root;
}
/* Work hands into contact through a short, quiet paper-to-sky seam. */
.contact::before {
  content: "";
  position: absolute;
  inset: -72px 0 auto;
  height: 144px;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, var(--paper) 48%, var(--sky));
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--sky) 72%, var(--paper)) 48%, var(--sky));
  opacity: 0.9;
}
/* At the finale the page is its own footer: the HUD and the header's "Let's talk" step aside. */
.nav nav a[href="#contact"] {
  transition:
    color 0.25s,
    opacity 0.4s,
    visibility 0.4s;
}
html.at-contact .viewport-meta {
  opacity: 0;
  pointer-events: none;
}
@media (min-width: 701px) {
  html.at-contact .nav nav a[href="#contact"] {
    opacity: 0;
    visibility: hidden;
  }
}

/* Kind words: a pinned stage between Work and Contact, on the same paper so both seams stay quiet.
   app.js writes --p (0..4) as the section scrolls past; each quote (--i) inks in word by word (--w of --n),
   its key phrase takes a lime highlighter sweep, the caption and the original message follow, then it lifts
   away for the next. Without .is-live (no JS) the quotes simply stack, fully inked. */
.voices {
  position: relative;
  z-index: 2;
  background: var(--paper);
  padding-inline: 4.7%;
  transition: background 0.5s;
}
.voices.is-live {
  height: 392.5svh; /* one screen + 3.25 steps; app.js reads the step back from this height */
}
/* scroll targets for the rail: #voice-N lands (with the 100px scroll padding) where quote N is inked */
.voices-mark {
  position: absolute;
  top: calc((var(--k) - 0.9) * 90svh + 100px);
}
.voices-mark:nth-child(1) { --k: 1; }
.voices-mark:nth-child(2) { --k: 2; }
.voices-mark:nth-child(3) { --k: 3; }
.voices-mark:nth-child(4) { --k: 4; }
.voices-stage {
  display: flex;
  flex-direction: column;
  gap: 48px;
  padding-block: 40px 120px;
}
.voices.is-live .voices-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  padding-block: 104px 44px;
}
.voices-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
}
.voices-rail {
  display: flex;
  gap: 10px;
}
.voices-rail a {
  --f: 1;
  width: clamp(72px, 9vw, 136px);
  display: grid;
  gap: 2px;
  color: var(--muted);
  text-decoration: none;
  font: 12px/1.3 Instrument, Arial, sans-serif;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  transition: color 0.3s;
}
.voices-rail a::before {
  content: "";
  height: 2px;
  margin-bottom: 8px;
  background:
    linear-gradient(var(--ink), var(--ink)) no-repeat 0 0 / calc(var(--f) * 100%) 100%,
    var(--line);
}
.voices-rail small {
  font-size: 11px;
  opacity: 0.7;
}
.voices-rail a:hover,
.voices-rail a[aria-current="true"] {
  color: var(--ink);
}
.voices-rail a:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 4px;
}
.voices-list {
  flex: 1;
  min-height: 0;
  display: grid;
  gap: 120px;
}
.voice {
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(28px, 5vh, 56px);
}
.voice blockquote {
  margin: 0;
}
.voice blockquote p {
  max-width: 19em;
  font: 500 clamp(32px, 5.1vw, 88px)/1.02 var(--display);
  letter-spacing: -0.045em;
  text-wrap: balance;
}
.voice mark {
  --hl: 1;
  color: #10242b;
  background: linear-gradient(var(--accent), var(--accent)) no-repeat 0 0 / calc(var(--hl) * 100%) 100%;
}
html[data-theme="dark"] .voice mark {
  color: inherit;
  background-position: 0 94%;
  background-size: calc(var(--hl) * 100%) 0.1em;
}
.voice figcaption {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 18px;
}
.voice figcaption > img {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
}
.voice-who {
  display: grid;
  gap: 3px;
  font: 12px/1.3 Instrument, Arial, sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.voice-who b {
  font-weight: 400;
  font-size: 13px;
  color: var(--ink);
}
/* the receipt: the real chat message, pinned on the page like a clipping; opens full size */
.voice-proof {
  --r: 1;
  margin-left: auto;
  width: clamp(240px, 27vw, 400px);
  display: grid;
  gap: 8px;
  padding: 8px 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: #10242b;
  font: 11px/1 Instrument, Arial, sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
  box-shadow: 0 22px 40px -26px rgb(16 36 43 / 0.5);
  rotate: -2.5deg;
  opacity: var(--r);
  translate: 0 calc((1 - var(--r)) * 48px);
  transition:
    rotate 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    scale 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.voice-proof:hover,
.voice-proof:focus-visible {
  rotate: 0deg;
  scale: 1.04;
}
.voice-proof:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 4px;
}
.voice-proof img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 5px;
}
/* live: every quote shares one cell; --t is this quote's own progress */
.voices.is-live .voice {
  --t: calc(var(--p, 0.95) - var(--i));
  --out: clamp(0, calc((var(--t) - 1) / 0.12), 1);
  grid-area: 1 / 1;
  opacity: calc(clamp(0, calc((var(--t) - 0.12) / 0.06), 1) * (1 - var(--out)));
  translate: 0 calc(var(--out) * -56px);
}
.voices.is-live .voice:not(.is-current) {
  pointer-events: none;
}
.voices.is-live .voice:not(.is-current) .voice-proof {
  visibility: hidden;
}
.voices.is-live .w {
  opacity: calc(0.12 + 0.88 * clamp(0, calc((var(--t) - 0.16) / 0.5 * var(--n) - var(--w)), 1));
}
.voices.is-live .voice mark {
  --hl: clamp(0, calc((var(--t) - 0.66) / 0.18), 1);
}
.voices.is-live .voice figcaption > :not(.voice-proof) {
  --c: clamp(0, calc((var(--t) - 0.48) / 0.2), 1);
  opacity: var(--c);
  translate: 0 calc((1 - var(--c)) * 14px);
}
.voices.is-live .voice-proof {
  --r: clamp(0, calc((var(--t) - 0.7) / 0.18), 1);
}
.receipt {
  width: min(1040px, 92vw);
  padding: 0;
  border: 0;
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 40px 80px -40px rgb(16 36 43 / 0.6);
}
.receipt::backdrop {
  background: rgb(16 36 43 / 0.45);
  backdrop-filter: blur(6px);
}
.receipt img {
  display: block;
  width: 100%;
  height: auto;
}
.receipt form {
  display: flex;
  justify-content: flex-end;
  padding: 0 16px 14px;
}
.receipt button {
  padding: 8px 14px;
  border: 1px solid #183b4833;
  border-radius: 99px;
  background: none;
  color: #10242b;
  font: 12px Instrument, Arial, sans-serif;
  text-transform: uppercase;
  cursor: pointer;
}
@media (max-width: 700px) {
  .voices-top {
    flex-direction: column;
  }
  .voices-rail {
    width: 100%;
  }
  .voices-rail a {
    flex: 1;
    width: auto;
  }
  .voices-rail small {
    display: none;
  }
  .voice-proof {
    margin-left: 0;
    width: min(100%, 320px);
  }
}

/* Dive: Kind words -> Contact. A glass drop hits the paper, the ripple opens a pool, the view plunges through a
   tunnel of light past three lines, then surfaces into the Contact pool. app.js writes --p (0..1) over the pin. */
.dive {
  position: relative;
  z-index: 2;
  display: none;
}
.dive.is-live {
  display: block;
  height: 300svh;
}
.dive.is-live + .contact::before {
  display: none;
}
.dive-stage {
  --x: 50%;
  --y: 56%;
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.4em;
  /* the last tenth fades the (now pool-coloured) sea away over the live pool behind it */
  opacity: calc(1 - clamp(0, (var(--p, 0) - 0.9) / 0.1, 1));
}
.dive-stage > * {
  position: absolute;
  margin: 0;
  pointer-events: none;
}
.dive-sea {
  inset: 0;
  /* tunnel rings flow outward from the impact point (phase --o), over deep water */
  --o: calc(var(--p, 0) * 140vmin);
  background:
    repeating-radial-gradient(ellipse at var(--x) var(--y), #0000 var(--o), #bff3f41c calc(var(--o) + 3vmin), #0000 calc(var(--o) + 8vmin), #0000 calc(var(--o) + 20vmin)),
    radial-gradient(ellipse at var(--x) var(--y), #1d93a2, #0b5468 42%, #06303f);
}
/* speed lines: faint rays out of the impact point, turning a little as you sink */
.dive-sea::before,
.dive-sea::after {
  content: "";
  position: absolute;
  inset: 0;
}
.dive-sea::before {
  background: repeating-conic-gradient(from calc(var(--p, 0) * 50deg) at var(--x) var(--y), #0000 0 4deg, #d8fffa14 5.5deg, #0000 7deg 11deg);
  -webkit-mask: radial-gradient(circle at var(--x) var(--y), #0000 8vmin, #000 60vmin);
  mask: radial-gradient(circle at var(--x) var(--y), #0000 8vmin, #000 60vmin);
}
/* surfacing: the sea brightens into the same sunlit pool the Contact section sits in */
.dive-sea::after {
  background:
    radial-gradient(ellipse at 70% 20%, #effbe655, transparent 40%),
    linear-gradient(180deg, #b2e9ec, #86d7df 50%, #62c4d0);
  opacity: clamp(0, (var(--p, 0) - 0.8) / 0.1, 1);
}
html[data-theme="dark"] .dive-sea::after {
  background: radial-gradient(ellipse at 65% 35%, #26497a70, transparent 50%), var(--sky);
}
.dive-line {
  --t: clamp(0, (var(--p, 0) - 0.26 - var(--i) * 0.1) / 0.13, 1);
  left: var(--x);
  top: var(--y);
  max-width: 88vw;
  width: max-content;
  translate: -50% -50%;
  text-align: center;
  text-wrap: balance;
  font: 500 clamp(30px, 5.2vw, 88px)/1 var(--display);
  letter-spacing: -0.045em;
  color: #eafffc;
  /* each line rises out of the deep and rushes past the viewer */
  scale: calc(0.3 + var(--t) * var(--t) * 2.6);
  opacity: calc(sin(var(--t) * 3.1416) * 1.6 - 0.3);
}
.dive-paper {
  --h: clamp(0, (var(--p, 0) - 0.15) / 0.14, 1);
  --z: clamp(0, (var(--p, 0) - 0.25) / 0.2, 1);
  --rx: calc(var(--h) * 15vmin + var(--z) * var(--z) * var(--z) * 420vmin + 0.1px);
  inset: 0;
  background: var(--paper);
  transition: background 0.5s;
  /* the ripple opens a flat, elliptical pool in the paper, then the view drops through it */
  -webkit-mask: radial-gradient(var(--rx) calc(var(--rx) * 0.36) at var(--x) var(--y), #0000 94%, #000);
  mask: radial-gradient(var(--rx) calc(var(--rx) * 0.36) at var(--x) var(--y), #0000 94%, #000);
}
.dive-ring {
  --t: clamp(0, (var(--p, 0) - 0.14 - var(--i) * 0.035) / 0.2, 1);
  left: calc(var(--x) - 30vmin);
  top: calc(var(--y) - 10.8vmin);
  width: 60vmin;
  height: 21.6vmin;
  border: 1.5px solid var(--blue);
  border-radius: 50%;
  scale: calc(0.02 + var(--t) * 1.5);
  opacity: calc(clamp(0, var(--t) * 30, 1) * (1 - var(--t)));
}
.dive-hint {
  left: var(--x);
  top: calc(var(--y) + 6vmin);
  translate: -50% 0;
  font: 12px/1.5 Instrument, Arial, sans-serif;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  opacity: calc(1 - clamp(0, (var(--p, 0) - 0.1) / 0.05, 1));
}
/* the drop: the cobalt of the glass word, falling with gravity (ease-in) onto the impact point */
.dive-drop {
  --f: clamp(0, var(--p, 0) / 0.14, 1);
  left: calc(var(--x) - 9px);
  top: calc(var(--y) - 26px);
  width: 18px;
  height: 26px;
  border-radius: 50% 50% 50% 50% / 62% 62% 40% 40%;
  background: radial-gradient(circle at 36% 58%, #fff 0 9%, #8db8ff 26%, #1766f2 62%, #0a3a9e);
  box-shadow: 0 8px 18px #0d52d140;
  translate: 0 calc((var(--f) * var(--f) - 1) * 64svh);
  opacity: calc(1 - clamp(0, (var(--p, 0) - 0.14) / 0.01, 1));
}
/* WebGL (dive.js): the canvas draws the page, drop, rings, plunge and sea; CSS keeps the lines and the surfacing */
.dive-gl {
  inset: 0;
  width: 100%;
  height: 100%;
}
.dive.gl .dive-sea,
.dive.gl:not(.is-still) :is(.dive-paper, .dive-ring, .dive-drop) {
  display: none;
}
.dive.gl :is(.dive-line, .dive-beats) {
  text-shadow: 0 0 40px #0a1450;
}
/* the cadence: at full warp speed, four beats hang in the tunnel at once, 1 hour to 1 month */
.dive-beats {
  inset: 0;
}
.dive-beats p {
  --t: clamp(0, (var(--p, 0) - 0.64 - var(--i) * 0.02) / 0.16, 1);
  position: absolute;
  left: var(--bx);
  top: var(--by);
  max-width: min(34vw, 15em);
  margin: 0;
  font: 500 clamp(17px, 2vw, 32px)/1.15 var(--display);
  letter-spacing: -0.03em;
  color: #eafffc;
  scale: calc(0.9 + var(--t) * 0.2);
  opacity: calc(sin(var(--t) * 3.1416) * 1.8 - 0.4);
}
.dive-beats b {
  display: block;
  font-weight: 500;
  color: #7ff0e4;
}
/* nav and HUD ink turns pale while the deep sea is behind them */
html.in-sea :is(.nav, .viewport-meta) {
  --ink: #eafffc;
  --muted: #bfe9ea;
  color: var(--ink);
  transition: color 0.3s;
}
/* over the coloured sea the difference blend tints the bar; plain white reads cleaner */
html.in-sea .viewport-meta {
  mix-blend-mode: normal;
}
/* Still (reduced motion / Motion off): no fall, no plunge. The paper crossfades to the sea with the lines at rest. */
.dive.is-still :is(.dive-drop, .dive-ring, .dive-hint) {
  display: none;
}
.dive.is-still .dive-sea {
  --p: 0.4;
}
.dive.is-still .dive-paper {
  -webkit-mask: none;
  mask: none;
  opacity: calc(1 - clamp(0, (var(--p, 0) - 0.15) / 0.2, 1));
}
.dive.is-still .dive-beats {
  position: relative;
  inset: auto;
  display: grid;
  grid-template-columns: repeat(2, auto);
  gap: 1.5em 3em;
}
.dive.is-still .dive-beats p {
  position: static;
  scale: none;
  opacity: 1;
}
.dive.is-still .dive-line {
  position: relative;
  inset: auto;
  translate: none;
  scale: none;
  opacity: 1;
}
