/* Static stage: white backdrop, black road, machine centred. */

* { box-sizing: border-box; }

html, body { height: 100%; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  overflow-x: hidden;
  background: #ffffff;
}

/* The canvas is pinned; the page scrolls behind it to scrub the sequence. */
#scene {
  position: fixed; inset: 0;
  display: block; width: 100vw; height: 100vh;
  z-index: 1;              /* over the sky type, under the road copy */
}

/* Scroll length for the pick-up sequence. */
.track { height: 3900vh; pointer-events: none; }

/* three dots, fading out once the first frame is drawn */
.loader {
  position: fixed; inset: 0; z-index: 10;
  display: flex; align-items: center; justify-content: center; gap: 7px;
  background: #ffffff;
  transition: opacity .4s ease, visibility .4s;
}
.loader span {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--black);
  animation: pulse 1s ease-in-out infinite;
}
.loader span:nth-child(2) { animation-delay: .15s; }
.loader span:nth-child(3) { animation-delay: .3s; }
@keyframes pulse { 0%, 100% { opacity: .2; transform: scale(.75); } 50% { opacity: 1; transform: scale(1); } }

body.is-ready .loader { opacity: 0; visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .loader span { animation: none; opacity: 1; }
}

/* ==================================================================
   Closing overlay: headings on the white half, about on the black.
   Revealed by --reveal, which the timeline drives from 0 to 1.
   ================================================================== */

:root {
  --reveal: 0;
  /* charcoal black, its shades, and pure white - no hues anywhere */
  --black: #14161a;
  --ink: #14161a;
  --ink-dim: #565d66;
  --paper: #ffffff;
  --paper-dim: #9aa1a9;
  /* the sky type sits a long way back: grey, barely there, so the machines
     stay the loudest thing on the white half */
  --ghost: #bcc2c9;
  --ghost-soft: #ccd1d7;
  --gold: #c8a14a;
  --champagne: #d8c193;
  --accent: var(--gold);
  --sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* No box of its own: a fixed wrapper would be a stacking context in Chrome and
   would trap the head and the copy on the same side of the canvas. */
.overlay {
  display: contents;
  pointer-events: none;
  font-family: var(--sans);
}

/* ---- upper half: wordmark, kept clear of the truck on the left ---- */
.head {
  position: fixed; top: 0; right: 0; left: 0; height: 50%;
  z-index: 0;              /* behind the canvas: the machines pass in front */
  pointer-events: none;
  font-family: var(--sans);
  display: flex; justify-content: flex-end;
  padding: clamp(1.6rem, 7vh, 4rem) 5vw 0;
  text-align: right;
  color: var(--ghost);
  transition: color .6s ease;
  overflow: hidden;        /* it enters and leaves through the frame edges */
}
.head__inner {
  display: flex; flex-direction: column; align-items: flex-end;
  gap: .5rem;
  /* Crosses the sky the way the base crosses the ground: in from beyond the
     right edge, out past the left one. --headP runs 0 to 1 across the whole
     read, and the 100% is the type's own width, so it clears the frame
     completely whatever the wordmark measures. */
  transform: translate3d(
    calc((100% + 5vw) - var(--headP, 0) * (100% + 100vw)), 0, 0);
}

.eyebrow {
  margin: 0;
  font: 500 clamp(.66rem, .95vw, .86rem)/1 var(--mono);
  letter-spacing: .34em; text-transform: uppercase; color: var(--ghost-soft);
}
.wordmark {
  margin: 0;
  font-size: clamp(2.6rem, 7.4vw, 7.6rem);
  font-weight: 900; line-height: .9; letter-spacing: -.04em;
  white-space: nowrap;
}
.wordmark em { font-style: normal; color: var(--ghost-soft); padding: 0 .12em; }
.tagline {
  margin: 0; max-width: 32ch;
  font-size: clamp(.9rem, 1.3vw, 1.18rem); line-height: 1.5; color: var(--ghost-soft);
}

/* ---- lower half: staged copy, sitting on the road ---- */
.about {
  position: fixed; top: 50%; left: 0; right: 0; bottom: 0;
  z-index: 3;              /* over the road, so the copy stays readable */
  pointer-events: none;
  font-family: var(--sans);
  color: var(--paper);
  overflow: hidden;          /* panels enter and leave through these edges */
  /* fades up with the road, and clears again for the closing plan view */
  opacity: calc(var(--reveal) * (1 - var(--outro, 0)));
}

/* The base is a filmstrip: panels sit side by side and the whole strip tracks
   right to left as you scroll, so the ground appears to run past the truck. */
.strip {
  position: absolute; inset: 0;
  display: flex; align-items: stretch;
  width: max-content;
  --travel: calc((var(--panels, 4) - 1) * 100vw);
  transform: translate3d(calc(var(--p, 0) * -1 * var(--travel)), 0, 0);
  will-change: transform;
}

.panel {
  flex: 0 0 100vw; width: 100vw;
  display: flex; flex-direction: column; justify-content: center;
  gap: clamp(.9rem, 2.6vh, 1.7rem);
  padding: clamp(1.2rem, 4vh, 2.8rem) clamp(1.25rem, 5vw, 5.5rem);
}

.panel__title {
  margin: 0;
  font: 500 clamp(.62rem, .78vw, .72rem)/1 var(--mono);
  letter-spacing: .3em; text-transform: uppercase; color: var(--gold);
}

.lead { display: flex; gap: clamp(1.5rem, 5vw, 4rem); align-items: flex-start; flex-wrap: wrap; }
.lead h2 {
  margin: 0; flex: 0 0 auto; max-width: 14ch;
  font-size: clamp(1.5rem, 2.9vw, 2.5rem); font-weight: 900; line-height: 1.02; letter-spacing: -.03em;
}
.lead p {
  margin: 0; flex: 1 1 26ch; max-width: 64ch;
  font-size: clamp(.86rem, 1.1vw, 1.02rem); line-height: 1.64; color: var(--paper-dim);
}

.grid {
  display: grid; gap: clamp(.8rem, 2.4vw, 2.4rem) clamp(1rem, 3vw, 2.8rem);
  margin: 0; padding: clamp(.7rem, 2vh, 1.3rem) 0 0;
  list-style: none;
  border-top: 1px solid rgba(255, 255, 255, .16);
}
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid .num {
  display: block; margin-bottom: .3rem;
  font: 500 clamp(.58rem, .72vw, .68rem)/1 var(--mono);
  letter-spacing: .22em; color: var(--accent);
}
.grid h3 {
  margin: 0 0 .25rem;
  font-size: clamp(.88rem, 1.1vw, 1.02rem); font-weight: 700; letter-spacing: -.01em;
}
.grid p {
  margin: 0; max-width: 36ch;
  font-size: clamp(.76rem, .94vw, .88rem); line-height: 1.54; color: var(--paper-dim);
}

.contact { display: block; margin-top: .5rem; color: var(--champagne); font-family: var(--mono); font-size: .9em; }

/* ---- narrow screens: stack the copy, keep the titles clear of the machine ---- */
@media (max-width: 820px) {
  /* left-aligned on narrow screens, so it only needs a hint of drift */
  .head { justify-content: flex-start; }
  .head__inner { align-items: flex-start; text-align: left;
                 transform: translate3d(calc(95vw - var(--headP, 0) * (100vw + 100%)), 0, 0); }
  .tagline { max-width: 26ch; }
  .lead { flex-direction: column; gap: .5rem; }
  .lead h2 { max-width: none; }
  .grid--3, .grid--4 { grid-template-columns: 1fr 1fr; }
  .grid p { display: none; }
}

/* ---- short viewports: half a screen is not much, so tighten everything ---- */
@media (max-height: 680px) {
  .head { padding-top: clamp(.9rem, 3vh, 1.6rem); gap: .3rem; }
  .panel { padding: .9rem clamp(1.25rem, 5vw, 5.5rem); gap: .7rem; }
  .lead h2 { font-size: clamp(1.3rem, 2.4vw, 1.9rem); }
  .lead p { font-size: clamp(.78rem, .95vw, .9rem); line-height: 1.5; }
  .grid { padding-top: .7rem; gap: .7rem 1.6rem; }
  .grid h3 { font-size: .86rem; }
  .grid p { font-size: .74rem; line-height: 1.45; }
}

@media (prefers-reduced-motion: reduce) {
  .head__inner { transform: none; }
}


/* ==================================================================
   Type entrance: everything starts hidden and is animated in once the
   road has reached the halfway line (body.copy-in).
   ================================================================== */

@keyframes riseIn {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}
@keyframes maskIn {
  from { clip-path: inset(0 0 108% 0); }
  to   { clip-path: inset(0 0 -8% 0); }
}

.head__inner > *, .panel > *, .grid li { opacity: 0; }

body.copy-in .head__inner > * { animation: riseIn .85s cubic-bezier(.22, .9, .28, 1) both; }
body.copy-in .head__inner > *:nth-child(1) { animation-delay: .04s; }
body.copy-in .head__inner > *:nth-child(2) { animation-delay: .13s; }
body.copy-in .head__inner > *:nth-child(3) { animation-delay: .26s; }
body.copy-in .wordmark {
  animation: riseIn .85s cubic-bezier(.22, .9, .28, 1) .13s both,
             maskIn 1s cubic-bezier(.22, .9, .28, 1) .13s both;
}

/* The base copy lights up: each panel glows on as it takes the centre of the
   road, then settles to crisp white. Driven by .is-lit, which the timeline
   moves from panel to panel, so it replays every time one comes round. */
@keyframes glowIn {
  0%   { opacity: 0; transform: translateY(14px); filter: blur(10px);
         text-shadow: 0 0 30px rgba(255, 255, 255, .85); }
  55%  { opacity: 1; filter: blur(0);
         text-shadow: 0 0 22px rgba(255, 255, 255, .45); }
  100% { opacity: 1; transform: none; filter: blur(0);
         text-shadow: 0 0 0 rgba(255, 255, 255, 0); }
}
@keyframes goldGlow {
  0%   { text-shadow: 0 0 28px rgba(200, 161, 74, .95), 0 0 8px rgba(200, 161, 74, .8); }
  100% { text-shadow: 0 0 0 rgba(200, 161, 74, 0), 0 0 0 rgba(200, 161, 74, 0); }
}

.panel.is-lit > * { animation: glowIn .95s cubic-bezier(.22, .9, .28, 1) both; }
.panel.is-lit > *:nth-child(2) { animation-delay: .12s; }

.panel.is-lit .panel__title {
  animation: glowIn .8s cubic-bezier(.22, .9, .28, 1) both,
             goldGlow 1.4s ease-out both;
}
.panel.is-lit .lead h2 {
  animation: glowIn 1.05s cubic-bezier(.22, .9, .28, 1) both,
             maskIn 1s cubic-bezier(.22, .9, .28, 1) both;
}

.panel.is-lit .grid li { animation: glowIn .85s cubic-bezier(.22, .9, .28, 1) both; }
.panel.is-lit .grid li:nth-child(1) { animation-delay: .22s; }
.panel.is-lit .grid li:nth-child(2) { animation-delay: .32s; }
.panel.is-lit .grid li:nth-child(3) { animation-delay: .42s; }
.panel.is-lit .grid li:nth-child(4) { animation-delay: .52s; }
.panel.is-lit .grid li:nth-child(5) { animation-delay: .62s; }
.panel.is-lit .grid li:nth-child(6) { animation-delay: .72s; }
.panel.is-lit .num { animation: goldGlow 1.4s ease-out both; animation-delay: inherit; }
.panel.is-lit .contact { animation: goldGlow 1.6s ease-out .4s both; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  body.copy-in .head__inner > *,
  body.copy-in .wordmark,
  .panel.is-lit > *,
  .panel.is-lit .grid li,
  .panel.is-lit .lead h2,
  .panel.is-lit .panel__title { animation: none; opacity: 1; clip-path: none; transform: none; filter: none; text-shadow: none; }
}

/* ==================================================================
   Route stops: copy taken alternately either side of the road on the
   closing run. Every one is placed from the 3-D scene each frame, so
   the CSS only has to describe how they look, never where they are.
   ================================================================== */
.route {
  position: fixed; inset: 0;
  z-index: 3;
  /* The cloud closes over the scene, and over its captions with it - but twice
     as fast, so the type is gone before the white is, rather than lingering on
     it as a set of grey smudges. */
  opacity: calc(1 - var(--veil, 0) * 2);
  pointer-events: none;
  font-family: var(--sans);
  overflow: hidden;
}
.stop {
  position: absolute; top: 0; left: 0;
  width: min(34ch, 30vw);
  opacity: 0;
  will-change: transform, opacity;
}
/* the odd ones sit to the left of the road and read back towards it */
.stop:nth-child(odd) { text-align: right; }
.stop .num {
  display: block; margin-bottom: .55rem;
  font: 500 .74rem/1 var(--mono);
  letter-spacing: .3em; color: var(--gold);
}
.stop h3 {
  margin: 0 0 .5rem;
  font-size: clamp(1.05rem, 1.9vw, 1.7rem);
  font-weight: 700; letter-spacing: -.02em; line-height: 1.1;
  color: var(--ink);
}
.stop p {
  margin: 0;
  font-size: clamp(.82rem, 1.05vw, 1.02rem); line-height: 1.55;
  color: var(--ink-dim);
}
.stop .contact { margin-top: .55rem; color: var(--gold); }

/* the last two stand out at sea, on deep water rather than on white ground */
.stop--dark h3 { color: var(--paper); }
.stop--dark p { color: var(--paper-dim); }
.stop--dark .contact { color: var(--champagne); }


@media (max-width: 820px) {
  .stop { width: min(30ch, 42vw); }
  .stop p { font-size: .78rem; line-height: 1.45; }
}

@media (prefers-reduced-motion: reduce) {
  .stop { transition: none; }
}

/* ==================================================================
   After the sequence: an ordinary page, on the white the cloud
   closed to. Opaque, and above the fixed canvas, so it simply
   arrives over the top of it.
   ================================================================== */
.after {
  position: relative;
  z-index: 6;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
}
.sheet {
  max-width: 62rem;
  margin: 0 auto;
  padding: clamp(4rem, 12vh, 9rem) clamp(1.5rem, 6vw, 5rem);
  border-top: 1px solid #e6e9ec;
}
.after .sheet:first-child { border-top: 0; }
.sheet__lead {
  margin: .9rem 0 1.6rem;
  font-size: clamp(1.7rem, 3.6vw, 3.1rem);
  font-weight: 900; letter-spacing: -.035em; line-height: 1.05;
  max-width: 20ch;
}
.sheet p {
  margin: 0 0 1.1rem;
  max-width: 62ch;
  font-size: clamp(.95rem, 1.15vw, 1.1rem); line-height: 1.65;
  color: #464c54;
}
.sheet .eyebrow { color: var(--gold); }

.people {
  list-style: none; margin: 2rem 0 1.5rem; padding: 0;
  display: grid; gap: 2rem clamp(1.5rem, 4vw, 3.5rem);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.people h3 {
  margin: 0 0 .4rem;
  font-size: 1.05rem; font-weight: 700; letter-spacing: -.01em;
}
.people p { margin: 0; font-size: .92rem; line-height: 1.55; }
.sheet__note {
  font: 500 .82rem/1.5 var(--mono);
  color: #8b9199;
}

.sheet--foot { padding-bottom: clamp(5rem, 16vh, 11rem); }
.mail {
  display: inline-block; margin: .4rem 0 2.5rem;
  font: 500 clamp(1rem, 1.7vw, 1.35rem)/1 var(--mono);
  color: var(--ink); text-decoration: none;
  border-bottom: 2px solid var(--gold);
  padding-bottom: .25rem;
}
.mail:hover { color: var(--gold); }
.colophon {
  font: 400 .78rem/1.6 var(--mono);
  color: #9aa1a9; max-width: 46ch;
}

@media (max-width: 820px) {
  .sheet__lead { max-width: none; }
}
