/* ==========================================================================
   Echoes — one system: charcoal / cream / ochre, one sans in five weights,
   one mono for the technical skeleton, one easing, two triggers.
   ========================================================================== */
:root {
  --bg: #101012;
  --ink: #f0ebde;
  --ochre: #fbbd47;
  --teal: #00597b;
  --hair: rgba(240, 235, 222, .16);
  --hair-d: rgba(16, 16, 18, .18);
  --dim: rgba(240, 235, 222, .62);
  --dim-d: rgba(16, 16, 18, .66);
  --sans: "Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --dur: .9s;
  --pad: clamp(20px, 5.5vw, 84px);
  --rail: 0px;
  --panel: 40vw;
}
@media (min-width: 900px) { :root { --rail: 72px; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--bg); }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 300;
  font-optical-sizing: auto;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; height: auto; }
h1, h2, h3, p, ol, ul, figure { margin: 0; padding: 0; }
ol, ul { list-style: none; }
::selection { background: var(--ochre); color: var(--bg); }

.mono {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.4;
}

/* ---------- line masks: the one entrance move ---------- */
.mask { display: block; overflow: hidden; padding-bottom: .14em; margin-bottom: -.14em; }
.mask .line { display: block; will-change: transform; text-wrap: balance; }
.js .mask .line {
  transform: translate3d(0, 112%, 0);
  transition: transform var(--dur) var(--ease);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.js .in .mask .line { transform: none; }
.reduced .mask .line { transition: none !important; }

/* ---------- top bar ---------- */
.top {
  position: fixed; inset: 0 0 auto 0; z-index: 40;
  display: flex; justify-content: space-between; align-items: center;
  padding: max(22px, env(safe-area-inset-top)) var(--pad) 22px;
  pointer-events: none;
}
.top > * { pointer-events: auto; position: relative; }
/* the header sits over scrolling copy; a scrim keeps both readable. Not on the
   hero, where it would darken the top of the ochre panel for nothing. */
.top::before {
  content: "";
  position: absolute; inset: -20% 0 -120% 0;
  background: linear-gradient(rgba(16, 16, 18, .78), rgba(16, 16, 18, 0));
  opacity: 1; transition: opacity .4s var(--ease);
  pointer-events: none;
}
.hero-on .top::before { opacity: 0; }
.logo svg { display: block; width: 44px; height: 30px; }
/* the mark is a <symbol> drawn through <use>: selectors cannot reach inside,
   custom properties can, so each place sets --mark-e / --mark-arcs */
.mark-e { fill: var(--mark-e, var(--ink)); transition: fill .4s; }
.mark-arcs { stroke: var(--mark-arcs, var(--ink)); transition: stroke .4s; }
/* while the hero holds, the top-right link sits on the ochre panel */
.top .cta { transition: color .4s; }
.hero-on .top .cta { color: var(--bg); }
@media (max-width: 899px) {
  .hero-on .top .logo { --mark-e: var(--bg); --mark-arcs: var(--bg); }
}
.js .top { opacity: 0; transition: opacity 1s var(--ease) .9s; }
.js.ready .top { opacity: 1; }

/* ---------- the signature: text + three arcs that ripple on hover ---------- */
.cta {
  display: inline-flex; align-items: center; gap: 14px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink);
}
.cta .arcs { position: relative; width: 22px; height: 22px; display: block; }
.cta .arcs i {
  position: absolute; top: 50%; left: 0;
  border: 1.5px solid currentColor; border-color: transparent currentColor transparent transparent;
  border-radius: 50%;
  transform: translate(0, -50%);
  transition: opacity .45s var(--ease), transform .45s var(--ease), color .45s;
  opacity: .35;
}
.cta .arcs i:nth-child(1) { width: 8px;  height: 8px;  left: -1px; }
.cta .arcs i:nth-child(2) { width: 14px; height: 14px; left: -1px; transition-delay: 70ms; }
.cta .arcs i:nth-child(3) { width: 20px; height: 20px; left: -1px; transition-delay: 140ms; }
.cta:hover .arcs i, .cta:focus-visible .arcs i { opacity: 1; transform: translate(4px, -50%); color: var(--ochre); }
.cta.big { font-size: 12px; padding: 14px 0; border-bottom: 1px solid var(--hair); }
.cta:focus-visible { outline: 1px solid var(--ochre); outline-offset: 6px; }

/* ---------- rail ---------- */
.rail {
  position: fixed; left: 26px; top: 50%; z-index: 40;
  transform: translateY(-50%);
  display: none; flex-direction: column; gap: 18px;
  filter: drop-shadow(0 1px 2px rgba(16, 16, 18, .6));
}
@media (min-width: 900px) { .rail { display: flex; } }
.rail a { display: flex; align-items: center; gap: 12px; height: 14px; color: var(--ink); }
.rail .dot { width: 6px; height: 6px; border-radius: 50%; border: 1px solid var(--ink); opacity: .5; transition: opacity .4s, background .4s, transform .4s var(--ease); }
.rail .lbl { font-family: var(--mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; opacity: 0; transform: translateX(-6px); transition: opacity .35s var(--ease), transform .35s var(--ease); }
.rail a:hover .lbl, .rail a.on .lbl { opacity: 1; transform: none; }
/* while the frames travel under the rail, the active label steps aside */
.rail.stage-on a.on:not(:hover) .lbl { opacity: 0; transform: translateX(-6px); }
.rail a.on .dot { background: var(--ink); opacity: 1; transform: scale(1.35); }
.js .rail { opacity: 0; transition: opacity 1s var(--ease) 1.1s; }
.js.ready .rail { opacity: 1; }

/* ==========================================================================
   THE FILM — fixed behind the page; the ochre panel, the scene canvas and the
   hero portrait live here and are driven by scroll
   ========================================================================== */
.film { position: fixed; inset: 0; z-index: 0; overflow: hidden; background: var(--bg); pointer-events: none; }
main, .foot { position: relative; z-index: 1; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.stage { position: relative; height: 560vh; }
.pin { position: sticky; top: 0; height: 100vh; overflow: hidden; }

.panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: var(--panel); z-index: 1;
  background: var(--ochre);
  will-change: transform, clip-path;
}
.js .panel { clip-path: inset(0 0 0 100%); transition: clip-path 1.1s var(--ease) .05s; }
.js.ready .panel { clip-path: inset(0); }

/* scene films: full-bleed clips scrubbed through a chapter */
.scene { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 4; opacity: 0; }

/* the hero portrait: the crisp crossed-arms figure from the banner art stands
   in the panel until the first clip takes over with a hard cut. It is also
   what stays when clips cannot load or motion is reduced. */
.mascot {
  position: absolute; right: 7vw; bottom: -3vh;
  height: 84vh; width: auto;
  z-index: 5;
  transform-origin: 50% 100%;
  will-change: transform;
  opacity: 0;
  transition: opacity 1s var(--ease) .45s;
}
.js.ready .mascot { opacity: 1; }
/* once the entrance is over, the portrait can cut away quickly */
.js.ready.settled .mascot { transition: opacity .12s linear; }
/* entrance rise uses the independent `translate` property so the JS transform can coexist */
.js.ready:not(.reduced) .mascot { animation: rise 1.2s var(--ease) .4s both; }
@keyframes rise { from { translate: 0 6vh; } to { translate: 0 0; } }

.hero-text {
  position: absolute; left: calc(var(--pad) + var(--rail)); bottom: 13vh; z-index: 2;
  max-width: min(58vw, 900px);
  will-change: transform, opacity;
}
.hero-line { transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease); transition-delay: calc(var(--i, 0) * 90ms + .15s); }
.js .hero-text .meta, .js .hero-text .cta { opacity: 0; transform: translateY(14px); }
.js.ready .hero-text .meta, .js.ready .hero-text .cta { opacity: 1; transform: none; }
.js.ready .hero-text .mask .line { transform: none; transition-delay: calc(var(--i, 0) * 90ms + .2s); }
.hero-text .meta { color: var(--dim); margin-bottom: 18px; }
.wordmark {
  /* sized so the word ends before the ochre panel (60vw) at any width:
     ECHOES is about 3.3 em wide, the left edge sits at pad + rail */
  font-size: clamp(88px, 18.1vw - 54px, 250px);
  font-weight: 800;
  font-variation-settings: "opsz" 96;
  line-height: .86;
  letter-spacing: -.035em;
  text-transform: uppercase;
  margin-left: -.04em;
}
.sub {
  margin-top: 26px;
  font-size: clamp(20px, 2.3vw, 32px);
  font-weight: 250;
  line-height: 1.2;
  letter-spacing: -.01em;
  max-width: 22ch;
}
.hero-text .cta { margin-top: 34px; }

.cue { position: absolute; left: calc(var(--pad) + var(--rail)); bottom: 4vh; z-index: 2; color: var(--dim); }
.cue-in { display: flex; align-items: center; gap: 12px; }
.cue i { display: block; width: 56px; height: 1px; background: var(--ink); opacity: .5; transform-origin: left; }
.js .cue { opacity: 0; transition: opacity 1s var(--ease) 1.5s; }
.js.ready .cue { opacity: 1; }
.js.ready:not(.reduced) .cue i { animation: draw 2.4s var(--ease) 1.5s infinite; }
@keyframes draw { 0% { transform: scaleX(0); transform-origin: left; } 55% { transform: scaleX(1); transform-origin: left; } 56% { transform: scaleX(1); transform-origin: right; } 100% { transform: scaleX(0); transform-origin: right; } }

.chapter {
  position: absolute; left: calc(var(--pad) + var(--rail)); top: 11vh; z-index: 4;
  max-width: min(54vw, 780px);
  opacity: 0; visibility: hidden;
  will-change: transform, opacity;
}
.chap-h {
  font-size: clamp(28px, 3.7vw, 54px);
  font-weight: 250;
  line-height: 1.02;
  letter-spacing: -.025em;
}
.chap-h b { font-weight: 700; }
.chapter p { margin-top: 22px; font-size: clamp(16px, 1.25vw, 19px); max-width: 44ch; color: var(--ink); }


/* ==========================================================================
   FLOW SECTIONS — rulers, hairlines, asymmetry
   ========================================================================== */
.section { position: relative; padding: 16vh var(--pad) 14vh calc(var(--pad) + var(--rail)); }
.ruler { display: grid; grid-template-columns: auto 1fr auto; gap: 22px; align-items: center; color: var(--dim); }
.ruler i { height: 1px; background: var(--hair); transform: scaleX(0); transform-origin: left; transition: transform 1.4s var(--ease); }
.in .ruler i { transform: none; }

.head { display: grid; grid-template-columns: repeat(12, 1fr); gap: 24px; margin-top: 56px; align-items: end; }
.head h2 { grid-column: 1 / 8; font-size: clamp(40px, 5.6vw, 88px); font-weight: 250; line-height: .98; letter-spacing: -.03em; }
.head .intro { grid-column: 9 / 13; font-size: 17px; color: var(--dim); max-width: 34ch; }

/* ---------- work rows ---------- */
.rows { margin-top: 64px; border-top: 1px solid var(--hair); }
.row {
  display: grid; grid-template-columns: 64px 1fr 130px 48px; gap: 24px; align-items: baseline;
  padding: 24px 0; border-bottom: 1px solid var(--hair);
}
.row .n { color: var(--dim); transition: color .4s; }
.row .t { font-size: clamp(20px, 2.3vw, 32px); font-weight: 400; letter-spacing: -.015em; line-height: 1.15; transition: transform .6s var(--ease); }
.row .d, .row .l { color: var(--dim); text-align: right; }
.row:hover .t, .row:focus-visible .t { transform: translateX(12px); }
.row:hover .n { color: var(--ochre); }
.tag { font-style: normal; color: var(--ochre); margin-left: 12px; vertical-align: middle; }
.peek {
  position: fixed; top: 0; left: 0; z-index: 30; width: 170px;
  pointer-events: none; opacity: 0;
  transition: opacity .35s var(--ease);
  will-change: transform;
}
.peek img { aspect-ratio: 9 / 16; object-fit: cover; }
.peek.on { opacity: 1; }
/* no hover on a touch screen: hide the peek and the sentence that promises it */
@media (hover: none) { .peek, .on-hover { display: none; } }

/* ---------- making ---------- */
.steps { margin-top: 72px; }
.step {
  display: grid; grid-template-columns: repeat(12, 1fr); gap: 24px; align-items: start;
  padding: 44px 0 52px; border-top: 1px solid var(--hair);
}
.step:last-child { border-bottom: 1px solid var(--hair); }
.step .num { grid-column: 1 / 5; font-size: clamp(96px, 13vw, 210px); font-weight: 200; line-height: .8; letter-spacing: -.05em; font-variation-settings: "opsz" 96; color: var(--ochre); }
.step .body { grid-column: 6 / 12; padding-top: .6em; }
.step h3 { font-size: clamp(22px, 2.4vw, 34px); font-weight: 600; letter-spacing: -.02em; margin-bottom: 14px; }
.step p { font-size: clamp(16px, 1.25vw, 19px); max-width: 48ch; }

.timeline { margin-top: 18vh; }
.tl-head { display: flex; justify-content: space-between; align-items: baseline; color: var(--dim); margin-bottom: 18px; }
.tl-cap { color: var(--ink); min-height: 1.4em; }
.tl { display: flex; gap: 3px; height: 64px; }
.seg {
  flex: var(--d) 1 0; min-width: 0;
  background: rgba(240, 235, 222, .16);
  transform: scaleX(0); transform-origin: left;
  transition: transform .8s var(--ease) calc(var(--i) * 45ms), background .3s;
  cursor: crosshair;
}
.seg.nar { background: var(--ochre); }
.in .seg { transform: none; }
.seg:hover { background: var(--ink); }
.tl-axis { display: flex; justify-content: space-between; margin-top: 12px; color: var(--dim); border-top: 1px solid var(--hair); padding-top: 10px; }
.tl-note { margin-top: 20px; font-size: 14px; color: var(--dim); max-width: 52ch; }

/* ---------- asked ---------- */
.qa { margin-top: 64px; border-top: 1px solid var(--hair); max-width: 900px; }
details { border-bottom: 1px solid var(--hair); }
summary {
  list-style: none; cursor: pointer;
  display: flex; justify-content: space-between; align-items: center; gap: 24px;
  padding: 26px 0;
  font-size: clamp(20px, 2vw, 28px); font-weight: 400; letter-spacing: -.015em;
}
summary::-webkit-details-marker { display: none; }
summary i { position: relative; width: 14px; height: 14px; flex: none; }
summary i::before, summary i::after { content: ""; position: absolute; background: var(--ink); left: 0; top: 6.5px; width: 14px; height: 1px; transition: transform .5s var(--ease); }
summary i::after { transform: rotate(90deg); }
details[open] summary i::after { transform: rotate(0); }
details[open] summary i::before { transform: rotate(180deg); }
.a { padding: 0 0 28px; }
.a p { max-width: 58ch; font-size: clamp(16px, 1.2vw, 18px); color: var(--dim); }
details[open] .a { animation: open .6s var(--ease); }
@keyframes open { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
summary:focus-visible { outline: 1px solid var(--ochre); outline-offset: 4px; }

/* ---------- footer ---------- */
.foot {
  position: relative; overflow: hidden; min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  padding: 16vh var(--pad) 8vh calc(var(--pad) + var(--rail)); border-top: 1px solid var(--hair);
}
.manifesto { font-size: clamp(44px, 7.4vw, 124px); font-weight: 250; line-height: .96; letter-spacing: -.035em; max-width: 16ch; }
.manifesto .mask:last-child .line { font-weight: 700; }
.foot .cta.big { margin-top: 56px; }
.foot-meta { display: flex; flex-wrap: wrap; gap: 12px 40px; margin-top: 14vh; color: var(--dim); }
.foot-mark { position: absolute; right: -6vw; bottom: -10vw; width: 46vw; height: auto; opacity: .08; pointer-events: none; }
.foot-mark { --mark-e: var(--ink); --mark-arcs: var(--ochre); }

/* ==========================================================================
   404 — its own page, no film layer, same type and palette
   ========================================================================== */
.lost { min-height: 100vh; display: flex; }
.lost .top { opacity: 1; }
.lost-in {
  margin: auto;
  padding: 0 var(--pad);
  max-width: 720px;
}
.lost-in .code { color: var(--ochre); margin-bottom: 22px; }
.lost-in h1 {
  font-size: clamp(40px, 6.4vw, 96px);
  font-weight: 250;
  line-height: .98;
  letter-spacing: -.03em;
}
.lost-note { margin-top: 24px; font-size: clamp(16px, 1.3vw, 19px); color: var(--dim); max-width: 46ch; }
.lost-in .cta.big { margin-top: 44px; display: inline-flex; }

/* frame-time readout, only with ?perf=1 */
.hud { position: fixed; left: 50%; bottom: 10px; transform: translateX(-50%); z-index: 50; padding: 6px 10px; background: rgba(16, 16, 18, .8); color: var(--ochre); pointer-events: none; }

/* ==========================================================================
   small screens
   ========================================================================== */
@media (max-width: 899px) {
  .stage { height: 460vh; }
  /* the banner turns portrait: ochre on top with the narrator in it, text below */
  .panel { top: 0; left: 0; right: 0; bottom: auto; width: 100%; height: 52vh; }
  .js .panel { clip-path: inset(0 0 100% 0); }
  .js.ready .panel { clip-path: inset(0); }
  .mascot { right: -4vw; bottom: 48vh; height: 43vh; }
  .hero-text { max-width: 88vw; bottom: 7vh; }
  .wordmark { font-size: clamp(64px, 19vw, 120px); }
  .sub { font-size: 19px; margin-top: 18px; }
  .hero-text .cta { margin-top: 24px; }
  .cue { display: none; }
  .chapter { max-width: 90vw; top: 12vh; }
  .chapter p { font-size: 16px; margin-top: 16px; }
  .head { grid-template-columns: 1fr; }
  .head h2, .head .intro { grid-column: auto; }
  .row { grid-template-columns: 40px 1fr; gap: 6px 16px; }
  .row .d, .row .l { grid-column: 2; text-align: left; }
  .step { grid-template-columns: 1fr; }
  .step .num, .step .body { grid-column: auto; }
  .step .num { font-size: 96px; }
  .foot-meta { flex-direction: column; }
}

/* ==========================================================================
   no JS: the stage unrolls into a plain column; nothing is hidden
   ========================================================================== */
.no-js .film { position: relative; inset: auto; height: auto; padding: 120px var(--pad) 0; }
.no-js .pin { position: relative; height: auto; overflow: visible; }
.no-js .panel { display: none; }
.no-js .mascot { position: static; height: 60vh; margin: 0 0 0 auto; opacity: 1; }
.no-js .hero-text, .no-js .chapter { position: static; opacity: 1; visibility: visible; transform: none; max-width: none; padding: 40px var(--pad); }
.no-js .cue, .no-js .peek, .no-js .scene { display: none; }
.no-js .ruler i, .no-js .seg { transform: none; }
