/* Brief Connection — global layer.
   SOURCE. Hand-edited. Assembled by scripts/brief-connection-assemble.mjs.

   Everything below is site-wide: tokens, reset, type scale, shell, the shared
   media primitives and the chrome the assembler writes (header, footer, skip
   link, lightbox). Anything that belongs to one section lives in that section's
   own <style> block and is prefixed with its #id. */

/* ---------------------------------------------------------------- tokens --- */

:root {
  --white: #ffffff;
  --surface: #f8f8f8;
  --surface-2: #f4f4f4;
  --ink: #282828;
  --grey: #a2a2a2;
  --grey-light: #b3b3b3;
  /* Secondary TEXT on white. His sampled mid grey measures 2.5 to 1 against
     white, which is under half of what a caption needs to be read on a laptop
     in daylight. The sampled greys stay as the brand's hairline and placeholder
     colour; anything anybody has to read uses this instead. It clears AA. */
  --ink-soft: #6d6d6d;
  /* One accent. It is a mark, an underline, a hover and a kicker rule. It is
     never running text: lime on white measures about 1.4:1. */
  --lime: #d5ef8a;

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 44px;
  --s-8: 64px;
  --s-9: 88px;
  --s-10: 120px;
  --s-11: 160px;

  --gutter: clamp(22px, 5vw, 80px);
  --shell: 1560px;
  --measure: 46ch;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --band: clamp(88px, 11vw, 176px);
}

/* ----------------------------------------------------------------- reset --- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--white);
  color: var(--ink);
  font-family: var(--font);
  font-size: 18px;
  font-weight: 400;
  line-height: 1.62;
  letter-spacing: -0.003em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* height:auto is load bearing. Every media element on this site carries real
   width and height attributes so nothing shifts while it loads, and without
   this an <img width="512" height="582"> sized to 54px in CSS still reserves
   582px of height. The frames below override it where a cover crop needs a
   real height. */
img, video { display: block; max-width: 100%; height: auto; }
button { font: inherit; color: inherit; }

h1, h2, h3, h4, p, figure, ul, ol, dl, dd, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

::selection { background: var(--lime); color: var(--ink); }

/* ------------------------------------------------------------------ type --- */

/* The display face is set very large and very tight, because a stop statement
   on a white page has to earn the white around it. Line height under 1 is
   deliberate: at these sizes 1.1 reads as a gap, not as leading. */
.display {
  font-size: clamp(38px, 8.2vw, 128px);
  font-weight: 500;
  line-height: 0.95;
  letter-spacing: -0.038em;
  text-wrap: balance;
}

.h2 {
  font-size: clamp(29px, 4.2vw, 58px);
  font-weight: 500;
  line-height: 1.04;
  letter-spacing: -0.032em;
  text-wrap: balance;
}

.h3 {
  font-size: clamp(21px, 2vw, 29px);
  font-weight: 500;
  line-height: 1.18;
  letter-spacing: -0.024em;
}

.lede {
  font-size: clamp(19px, 1.5vw, 23px);
  line-height: 1.55;
  max-width: var(--measure);
}

.body { max-width: var(--measure); }

.caption {
  font-size: 13.5px;
  line-height: 1.5;
  letter-spacing: 0;
  color: var(--ink-soft);
}

.kicker {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--ink);
}

.kicker::before {
  content: "";
  width: 26px;
  height: 9px;
  flex: none;
  background: var(--lime);
}

.serial {
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- layout ---- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--band); }
.section--tight { padding-block: clamp(56px, 7vw, 104px); }
.section--surface { background: var(--surface); }

.bleed { width: 100%; }

.rule-top { border-top: 1px solid #e6e6e6; }

/* --------------------------------------------------------------- reveals --- */

/* Opacity plus a 12px lift, once, on the way in. Driven by IntersectionObserver
   rather than a scroll library so it still runs on a phone where the heavier
   motion libraries are never loaded at all. */
.js .reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 550ms var(--ease), transform 550ms var(--ease);
  will-change: opacity, transform;
}

.reveal.is-in { opacity: 1; transform: none; }

.reveal--d1 { transition-delay: 70ms; }
.reveal--d2 { transition-delay: 140ms; }
.reveal--d3 { transition-delay: 210ms; }

/* Nothing on this site depends on motion to become readable, so the whole
   system collapses to "already there" rather than to a shorter animation. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; }
}

/* ----------------------------------------------------------------- media --- */

/* Every frame carries its own aspect-ratio, written by the assembler from the
   real poster file, so nothing on the page moves while media loads. */
.vframe {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--ink);
}

.vframe video,
.vframe img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The poster is a real image stacked under the clip. A <video> with no src
   paints nothing, and the src is withheld until the runtime picks an encode,
   so without this every frame is a black rectangle until it starts, and stays
   one forever with motion reduced or scripting off. */
.vframe__poster,
.vframe__video {
  position: absolute;
  inset: 0;
}

.vframe__video {
  opacity: 0;
  transition: opacity 420ms var(--ease);
}

.vframe__video.is-playing { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .vframe__video { transition: none; }
}

.still { width: 100%; height: auto; background: var(--surface-2); }

.figure { display: block; }
.figure figcaption { margin-top: var(--s-3); }

/* ---------------------------------------------------------------- button --- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 54px;
  padding: 0 var(--s-6);
  border: 0;
  background: var(--ink);
  color: var(--white);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  transition: background 220ms var(--ease), color 220ms var(--ease);
}

.btn:hover { background: #000; }

.btn--lime { background: var(--lime); color: var(--ink); }
.btn--lime:hover { background: #c7e76b; }

.btn__arrow { transition: transform 260ms var(--ease); }
.btn:hover .btn__arrow { transform: translateX(4px); }

/* A text link that underlines in lime. The lime sits under the word rather than
   inside it, which keeps the contrast on the ink and the colour on the brand. */
.link {
  display: inline-block;
  text-decoration: none;
  font-weight: 500;
  box-shadow: inset 0 -2px 0 var(--lime);
  transition: box-shadow 200ms var(--ease);
}

.link:hover { box-shadow: inset 0 -10px 0 var(--lime); }

/* ---------------------------------------------------------------- header --- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: var(--s-3) var(--s-5);
  background: var(--ink);
  color: var(--white);
  text-decoration: none;
}

.skip-link:focus { left: var(--s-4); top: var(--s-4); }

.site-header {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 40;
  padding-block: clamp(18px, 2.4vw, 30px);
}

/* Over film the mark and the three words are lime and white on whatever the
   first frame of that page happens to be, which on a skincare close-up is pale
   skin. A short wash at the very top guarantees them without darkening the
   picture anybody came to look at. */
.site-header:not(.site-header--ink)::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 190px;
  background: linear-gradient(to bottom, rgba(20, 20, 20, .45), rgba(20, 20, 20, 0));
  pointer-events: none;
}

.site-header__inner { position: relative; }

/* The inner page templates put the header over white rather than over film, so
   the link colour flips. One class, set by the assembler per page. */
.site-header--ink .site-nav a { color: var(--ink); }
.site-header--ink .site-nav a::after { background: var(--ink); }

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}

.site-header__mark { display: block; line-height: 0; }
.site-header__mark img { width: clamp(34px, 3.4vw, 46px); height: auto; }

.site-nav { display: flex; align-items: center; gap: clamp(var(--s-5), 2.6vw, var(--s-8)); }

.site-nav a {
  position: relative;
  color: var(--white);
  font-size: 14.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
  padding-block: 6px;
}

.site-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--white);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 260ms var(--ease);
}

.site-nav a:hover::after,
.site-nav a[aria-current="page"]::after { transform: scaleX(1); }

.site-nav a[aria-current="page"]::after { background: var(--lime); }

/* --------------------------------------------------------------- footer ---- */

.site-footer {
  background: var(--ink);
  color: var(--white);
  padding-block: clamp(64px, 8vw, 110px) var(--s-8);
}

.site-footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
  gap: clamp(var(--s-7), 5vw, var(--s-10));
  align-items: start;
}

.site-footer__wordmark { width: clamp(200px, 22vw, 320px); height: auto; }

.site-footer__blurb {
  margin-top: var(--s-6);
  max-width: 34ch;
  font-size: 16px;
  color: #cfcfcf;
}

.site-footer h2 {
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--lime);
  margin-bottom: var(--s-5);
}

.site-footer li + li { margin-top: var(--s-3); }

.site-footer li a,
.site-footer li span {
  font-size: 16.5px;
  color: var(--white);
  text-decoration: none;
  transition: color 200ms var(--ease);
}

.site-footer li a:hover { color: var(--lime); }

.site-footer__base {
  margin-top: clamp(var(--s-8), 7vw, var(--s-10));
  padding-top: var(--s-6);
  border-top: 1px solid #3d3d3d;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4) var(--s-6);
}

.site-footer__legal { display: flex; flex-wrap: wrap; gap: var(--s-5); }

.site-footer__base a,
.site-footer__base span {
  font-size: 14px;
  /* On ink rather than on white, where the sampled grey measures 6 to 1. */
  color: var(--grey);
  text-decoration: none;
}

.site-footer__base a:hover { color: var(--lime); }

/* -------------------------------------------------------------- lightbox --- */

/* One dialog for the whole page. The iframe is created on click and destroyed
   on close, so no page ever ships a YouTube frame it has not been asked for. */
.lb {
  width: min(94vw, 1400px);
  max-width: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--white);
  overflow: visible;
}

.lb::backdrop { background: rgba(20, 20, 20, .93); }

.lb__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}

.lb__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.lb__close {
  position: absolute;
  right: 0;
  bottom: calc(100% + 12px);
  min-height: 44px;
  padding: 0 var(--s-5);
  border: 1px solid #5a5a5a;
  background: transparent;
  color: var(--white);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.lb__close:hover { border-color: var(--lime); color: var(--lime); }

/* --------------------------------------------------------------- mobile ---- */

@media (max-width: 899px) {
  body { font-size: 17px; }
  .site-nav { gap: var(--s-5); }
  .site-nav a { font-size: 14px; }
  .site-footer__top { grid-template-columns: 1fr; gap: var(--s-8); }
  .site-footer__base { flex-direction: column; align-items: flex-start; }
}

/* Brief Connection — case study template layer.
   SOURCE. Hand-edited. Assembled by scripts/brief-connection-assemble.mjs.

   Shared by every page under work/. The per-case folders under
   _sections-src/case/<slug>/ carry content only, so a rhythm change lands on
   all fourteen at once instead of being retyped fourteen times. */

/* ------------------------------------------------------------ case hero --- */

#case-hero {
  position: relative;
  background: var(--ink);
}

#case-hero .case-hero__media {
  width: 100%;
  height: clamp(62vh, 76vh, 860px);
  min-height: 420px;
}

#case-hero .case-hero__media .vframe,
#case-hero .case-hero__media video,
#case-hero .case-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ----------------------------------------------------------- case intro --- */

#case-intro { padding-block: clamp(56px, 7vw, 104px) clamp(48px, 6vw, 88px); }

#case-intro .case-intro__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(var(--s-7), 6vw, var(--s-10));
  align-items: start;
}

#case-intro .case-intro__serial { margin-bottom: var(--s-5); }

#case-intro h1 { margin-bottom: var(--s-5); }

#case-intro .case-intro__meta {
  display: grid;
  gap: var(--s-5);
  padding-top: var(--s-2);
}

#case-intro .case-intro__meta dt {
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: var(--s-2);
}

#case-intro .case-intro__meta dd { font-size: 17px; }

/* -------------------------------------------------------- case sequence --- */

/* Full bleed, then a two-up, then one small frame held off to one side. The
   offset is what keeps a long scroll of good photographs from turning into a
   contact sheet. */
#case-seq { padding-bottom: clamp(72px, 9vw, 132px); }

/* minmax(0, 1fr) everywhere below, never a bare 1fr. A grid track sized auto or
   1fr takes its minimum from the content, and the minimum of a 1600px wide
   photograph is 1600px, so a bare track quietly grows the whole page past the
   viewport on a phone. max-width on the image does not prevent it. */
#case-seq .seq {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(var(--s-6), 4vw, var(--s-9));
}

#case-seq img { width: 100%; }

#case-seq .seq__bleed { width: 100%; }
#case-seq .seq__bleed img,
#case-seq .seq__bleed .vframe { width: 100%; }

#case-seq .seq__pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(var(--s-4), 2.4vw, var(--s-6));
  padding-inline: var(--gutter);
}

#case-seq .seq__inset {
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(var(--s-6), 5vw, var(--s-9));
  align-items: end;
}

#case-seq .seq__inset--right { direction: rtl; }
#case-seq .seq__inset--right > * { direction: ltr; }

/* The note is the only editorial voice in a long run of photographs, so it is
   set at reading size rather than caption size and carries the lime rule that
   marks every other aside on the site. */
#case-seq .seq__inset .seq__note {
  padding-bottom: var(--s-4);
  max-width: 32ch;
  font-size: 15.5px;
  line-height: 1.6;
  color: #4a4a4a;
}

#case-seq .seq__inset .seq__note::before {
  content: "";
  display: block;
  width: 26px;
  height: 9px;
  background: var(--lime);
  margin-bottom: var(--s-4);
}

#case-seq .seq__trio {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--s-4), 2.4vw, var(--s-6));
  padding-inline: var(--gutter);
}

#case-seq .seq__wide { padding-inline: var(--gutter); }

/* A vertical cut is a column, never a band. Full width it is over a
   thousand pixels tall on a laptop and the page stops being a sequence. */
#case-seq .seq__wide .vframe--portrait {
  max-width: min(420px, 62vw);
  margin-inline: auto;
}

/* --------------------------------------------------------- case episode --- */

#case-seq .ep {
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-5);
}

#case-seq .ep__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-3) var(--s-5);
}

#case-seq .ep__title { font-weight: 500; }

#case-seq .ep__play {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 48px;
  padding: 0 var(--s-5);
  border: 1px solid var(--ink);
  background: transparent;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.02em;
  transition: background 220ms var(--ease), color 220ms var(--ease);
}

#case-seq .ep__play:hover { background: var(--ink); color: var(--white); }
#case-seq .ep__play .dot { width: 9px; height: 9px; background: var(--lime); flex: none; }

/* ------------------------------------------------------------- case next --- */

#case-next { background: var(--surface); }

#case-next a {
  display: block;
  padding-block: clamp(56px, 7vw, 104px);
  text-decoration: none;
}

#case-next .case-next__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-5);
}

#case-next .case-next__label {
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: var(--s-4);
}

#case-next .case-next__name { box-shadow: inset 0 -3px 0 var(--lime); transition: box-shadow 240ms var(--ease); }
#case-next a:hover .case-next__name { box-shadow: inset 0 -0.5em 0 var(--lime); }

#case-next .case-next__cat { font-size: 15px; color: var(--ink-soft); }

@media (max-width: 899px) {
  /* Antonio 2026-09-22: the serial and the name must land inside the first
     screen on a phone, so the frame gives up a little height and the intro
     loses its top air. Keep this shorter than the home hero on purpose. */
  #case-hero .case-hero__media { height: 52svh; min-height: 320px; }
  #case-intro { padding-block: 36px clamp(48px, 6vw, 88px); }
  #case-intro .case-intro__grid { grid-template-columns: 1fr; gap: var(--s-7); }
  #case-seq .seq__pair { grid-template-columns: minmax(0, 1fr); }
  #case-seq .seq__trio { grid-template-columns: minmax(0, 1fr); }
  #case-seq .seq__inset { grid-template-columns: minmax(0, 1fr); align-items: start; gap: var(--s-6); }
  #case-seq .seq__inset--right { direction: ltr; }
  #case-seq .seq__inset .seq__note { padding-bottom: 0; }
}

/* ---- section: hero ---- */
#hero {
    position: relative;
    height: 100svh;
    min-height: 520px;
    overflow: hidden;
    background: var(--ink);
  }

  /* 118% tall, hung 9% above the section, so the parallax drift has 9% of slack
     to travel into at both ends. The drift in site/assets/js/site.js is 7%, and
     the two numbers have to stay in that order or a gap opens at the top of the
     page as it scrolls. With motion off, or on a phone, the extra height simply
     crops a little tighter. */
  #hero .hero__inner {
    position: absolute;
    inset: -9% 0;
    height: 118%;
  }

  #hero .vframe,
  #hero video { width: 100%; height: 100%; }

  @media (max-width: 899px) {
    #hero { height: 88svh; min-height: 440px; }
  }

/* ---- section: statement ---- */
#statement { padding-block: clamp(104px, 15vw, 230px); }

  #statement .statement__type {
    max-width: 18ch;
    margin-bottom: clamp(var(--s-7), 5vw, var(--s-9));
  }

  /* Each sentence owns a line. Left to reflow it breaks after "Brief" on a
     phone, which reads as four fragments instead of three statements. */
  #statement .statement__type > span { display: block; }

  /* The period sits in lime. It is the smallest possible use of the accent and
     it lands on the word the sentence turns on. */
  #statement .statement__dot { color: var(--lime); }

  #statement .statement__foot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-4) var(--s-8);
    align-items: baseline;
    border-top: 1px solid #e6e6e6;
    padding-top: var(--s-6);
  }

  #statement .statement__where { font-size: 15.5px; color: var(--ink-soft); }

  /* The longest line is "Lasting impressions." at 20 characters. At the 38px
     floor it overruns a 390px screen, so the display steps down here rather
     than wrapping a sentence that is meant to hold one line. */
  @media (max-width: 899px) {
    #statement .statement__type { max-width: none; font-size: clamp(27px, 7.3vw, 46px); }
  }

/* ---- section: clients ---- */
#clients { padding-block: clamp(48px, 6vw, 88px); border-block: 1px solid #ededed; }

  #clients .clients__head { margin-bottom: var(--s-7); }

  #clients .clients__view {
    overflow: hidden;
    padding-inline: var(--gutter);
  }

  #clients .clients__track {
    display: flex;
    align-items: center;
    gap: clamp(var(--s-8), 7vw, var(--s-11));
    width: max-content;
    animation: clients-drift 46s linear infinite;
  }

  #clients .clients__track:hover { animation-play-state: paused; }

  /* A common height is not a common size. Set to 30px, EDIFIER runs 127px wide
     and the Spina Bride lockup runs 372px, so one client shouts and another
     disappears. The width cap plus contain evens them out optically. */
  #clients .clients__track img {
    height: clamp(20px, 2.1vw, 30px);
    width: auto;
    max-width: clamp(96px, 10vw, 152px);
    object-fit: contain;
    opacity: .52;
    filter: grayscale(1);
  }

  /* The track carries the run twice, so translating by exactly half its width
     lands the second copy where the first one started and the loop is seamless.
     Halving depends on the two copies being identical, which the assembler
     guarantees by emitting the same generated block twice. */
  @keyframes clients-drift {
    from { transform: translate3d(0, 0, 0); }
    to { transform: translate3d(-50%, 0, 0); }
  }

  /* Under 900px the marquee stops and the strip becomes a swipe. A logo row
     that moves on its own on a phone is a row nobody can read. */
  @media (max-width: 899px) {
    #clients .clients__view {
      overflow-x: auto;
      scrollbar-width: none;
    }
    #clients .clients__view::-webkit-scrollbar { display: none; }
    #clients .clients__track { animation: none; gap: var(--s-8); }
    #clients .clients__track img { height: 24px; max-width: 110px; }
    #clients .clients__track > .clients__run + .clients__run { display: none; }
  }

  @media (prefers-reduced-motion: reduce) {
    #clients .clients__track { animation: none; }
  }

  #clients .clients__run {
    display: flex;
    align-items: center;
    gap: clamp(var(--s-8), 7vw, var(--s-11));
    padding-right: clamp(var(--s-8), 7vw, var(--s-11));
  }

/* ---- section: rail ---- */
#rail { padding-block: clamp(72px, 9vw, 132px); }

  #rail .rail__head {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    justify-content: space-between;
    gap: var(--s-5);
    margin-bottom: clamp(var(--s-7), 5vw, var(--s-9));
  }

  #rail .rail__title { max-width: 16ch; margin-top: var(--s-5); }

  #rail .rail__view {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    scroll-snap-type: x mandatory;
    padding-inline: var(--gutter);
    -webkit-overflow-scrolling: touch;
  }

  #rail .rail__view::-webkit-scrollbar { display: none; }

  #rail .rail__track {
    display: flex;
    gap: clamp(var(--s-4), 1.8vw, var(--s-6));
    width: max-content;
    padding-right: var(--gutter);
  }

  #rail .tile {
    flex: none;
    width: clamp(268px, 30vw, 460px);
    scroll-snap-align: start;
    text-decoration: none;
    display: block;
  }

  #rail .tile__frame {
    position: relative;
    overflow: hidden;
    background: var(--surface-2);
  }

  #rail .tile__frame > * { transition: transform 620ms var(--ease); }
  #rail .tile:hover .tile__frame > * { transform: scale(1.04); }

  #rail .tile__meta {
    display: flex;
    align-items: baseline;
    gap: var(--s-4);
    margin-top: var(--s-4);
  }

  #rail .tile__name { font-weight: 500; font-size: 18px; letter-spacing: -0.015em; }
  #rail .tile__line { margin-top: var(--s-1); font-size: 14.5px; color: var(--ink-soft); max-width: 30ch; }

  #rail .tile__name span {
    box-shadow: inset 0 0 0 var(--lime);
    transition: box-shadow 260ms var(--ease);
  }

  #rail .tile:hover .tile__name span { box-shadow: inset 0 -0.55em 0 var(--lime); }

  /* Pinned mode. The view stops scrolling itself and GSAP moves the track. */
  .has-rail-pin #rail {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  .has-rail-pin #rail .rail__view {
    overflow: hidden;
    scroll-snap-type: none;
  }

  @media (max-width: 899px) {
    #rail .rail__view { padding-inline: var(--gutter); }
    #rail .tile { width: 78vw; }
    #rail .rail__head { align-items: flex-start; }
  }

/* ---- section: eye ---- */
#eye {
    padding-block: clamp(104px, 15vw, 230px);
    background: var(--surface);
  }

  #eye .eye__type { max-width: 15ch; }

  #eye .eye__mark {
    width: 54px;
    height: auto;
    margin-bottom: clamp(var(--s-6), 4vw, var(--s-8));
  }

  @media (max-width: 899px) {
    #eye .eye__type { max-width: 13ch; }
    #eye .eye__mark { width: 42px; }
  }

/* ---- section: series ---- */
#series .series__head { margin-bottom: clamp(var(--s-7), 5vw, var(--s-9)); }
  #series .series__title { max-width: 18ch; margin-top: var(--s-5); }

  #series .chapter + .chapter { margin-top: clamp(var(--s-9), 8vw, var(--s-11)); }

  #series .chapter__frame { margin-bottom: var(--s-6); }

  #series .chapter__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: clamp(var(--s-6), 5vw, var(--s-9));
    align-items: start;
  }

  #series .chapter__name { margin-bottom: var(--s-4); }
  #series .chapter__blurb { color: #4a4a4a; max-width: 38ch; }

  #series .eps { display: grid; gap: var(--s-3); }

  #series .ep {
    color: inherit;
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: var(--s-4);
    width: 100%;
    min-height: 56px;
    padding: var(--s-3) var(--s-4);
    border: 0;
    border-top: 1px solid #e6e6e6;
    background: transparent;
    text-align: left;
    cursor: pointer;
    transition: background 220ms var(--ease), padding-left 220ms var(--ease);
  }

  #series .eps .ep:last-child { border-bottom: 1px solid #e6e6e6; }
  #series .ep:hover { background: var(--surface); padding-left: var(--s-6); }

  #series .ep__no {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: 0.16em;
    color: var(--ink-soft);
    font-variant-numeric: tabular-nums;
    flex: none;
  }

  #series .ep__name { flex: 1 1 auto; font-size: 17px; font-weight: 500; letter-spacing: -0.015em; }

  #series .ep__go {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: var(--lime);
    color: var(--ink);
    font-size: 12px;
  }

  @media (max-width: 899px) {
    #series .chapter__grid { grid-template-columns: 1fr; gap: var(--s-6); }
    #series .ep:hover { padding-left: var(--s-4); }
  }

/* ---- section: films ---- */
#films { background: var(--ink); color: var(--white); }

  #films .films__head { margin-bottom: clamp(var(--s-7), 5vw, var(--s-9)); }
  #films .films__head .kicker { color: var(--white); }
  #films .films__title { max-width: 16ch; margin-top: var(--s-5); }

  #films .films__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(var(--s-5), 3vw, var(--s-7));
  }

  #films .film { display: block; text-decoration: none; color: inherit; }

  /* The three films were cut from sources with different letterbox, so their
     clean frames are 1.53, 1.81 and 1.89 to one. Side by side that gives three
     different heights and three misaligned captions, so the row is held to one
     ratio and each clip is cropped into it. The !important is the only way past
     the per-clip aspect-ratio the assembler writes inline. */
  #films .film__frame { aspect-ratio: 16 / 9; overflow: hidden; background: #111; }
  #films .film__frame .vframe { height: 100%; aspect-ratio: auto !important; }
  #films .film__frame > * { transition: transform 620ms var(--ease); }
  #films .film:hover .film__frame > * { transform: scale(1.04); }

  #films .film__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-4);
    margin-top: var(--s-4);
  }

  #films .film__name { font-size: 18px; font-weight: 500; letter-spacing: -0.015em; }
  #films .film__watch { font-size: 13px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--lime); }

  @media (max-width: 899px) {
    #films .films__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-7); }
  }

/* ---- section: founder-teaser ---- */
#founder-teaser { background: var(--surface); }

  #founder-teaser .ft__grid {
    display: grid;
    grid-template-columns: minmax(0, .85fr) minmax(0, 1fr);
    gap: clamp(var(--s-7), 6vw, var(--s-10));
    align-items: center;
  }

  #founder-teaser .ft__portrait { width: 100%; height: auto; }

  #founder-teaser .ft__name { margin-bottom: var(--s-5); }
  #founder-teaser .ft__copy { color: #4a4a4a; max-width: 40ch; }
  #founder-teaser .ft__copy p + p { margin-top: var(--s-4); }
  #founder-teaser .ft__link { margin-top: clamp(var(--s-6), 4vw, var(--s-8)); }

  @media (max-width: 899px) {
    #founder-teaser .ft__grid { grid-template-columns: 1fr; gap: var(--s-7); }
  }

/* ---- section: start ---- */
#start { position: relative; overflow: hidden; background: var(--ink); color: var(--white); }

  #start .start__bg { position: absolute; inset: 0; }
  #start .start__bg .vframe,
  #start .start__bg video { width: 100%; height: 100%; }
  #start .start__bg video { object-fit: cover; }

  #start .start__scrim {
    position: absolute;
    inset: 0;
    background: rgba(24, 24, 24, .72);
  }

  #start .start__inner {
    position: relative;
    padding-block: clamp(104px, 14vw, 210px);
  }

  #start .start__type { max-width: 16ch; margin-bottom: clamp(var(--s-7), 5vw, var(--s-9)); }
  #start .start__note { margin-top: var(--s-6); font-size: 15.5px; color: #cdcdcd; }
  #start .start__note a { color: var(--lime); text-decoration: none; }
  #start .start__note a:hover { text-decoration: underline; }

/* ---- section: work-head ---- */
#work-head { padding-block: clamp(120px, 16vw, 200px) clamp(40px, 5vw, 64px); }
  #work-head .work-head__title { max-width: 14ch; margin-bottom: var(--s-6); }
  #work-head .work-head__lede { color: #4a4a4a; }

/* ---- section: work-grid ---- */
#work-grid { padding-bottom: clamp(88px, 11vw, 160px); }

  #work-grid .filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
    margin-bottom: clamp(var(--s-7), 5vw, var(--s-9));
    padding-bottom: var(--s-6);
    border-bottom: 1px solid #e6e6e6;
  }

  #work-grid .filter {
    min-height: 44px;
    padding: 0 var(--s-5);
    border: 1px solid #dcdcdc;
    background: transparent;
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.01em;
    cursor: pointer;
    transition: background 200ms var(--ease), border-color 200ms var(--ease), color 200ms var(--ease);
  }

  #work-grid .filter:hover { border-color: var(--ink); }
  #work-grid .filter[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--white); }

  #work-grid .grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(var(--s-6), 3.4vw, var(--s-8)) clamp(var(--s-4), 2.2vw, var(--s-6));
  }

  #work-grid .card { display: block; text-decoration: none; }
  #work-grid .card[hidden] { display: none; }

  #work-grid .card__frame { overflow: hidden; background: var(--surface-2); }
  #work-grid .card__frame > * { transition: transform 620ms var(--ease); }
  #work-grid .card:hover .card__frame > * { transform: scale(1.04); }

  #work-grid .card__meta { display: flex; align-items: baseline; gap: var(--s-4); margin-top: var(--s-4); }
  #work-grid .card__name { font-size: 18px; font-weight: 500; letter-spacing: -0.015em; }
  #work-grid .card__name span { box-shadow: inset 0 0 0 var(--lime); transition: box-shadow 260ms var(--ease); }
  #work-grid .card:hover .card__name span { box-shadow: inset 0 -0.55em 0 var(--lime); }
  #work-grid .card__cat { margin-top: var(--s-1); font-size: 14px; color: var(--ink-soft); }

  #work-grid .empty { padding-block: var(--s-9); color: var(--ink-soft); }

  @media (max-width: 1099px) {
    #work-grid .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }

  @media (max-width: 699px) {
    #work-grid .grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-7); }
  }

/* ---- section: founder-hero ---- */
#founder-hero { padding-block: clamp(120px, 16vw, 200px) clamp(56px, 7vw, 96px); }

  #founder-hero .fh__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
    gap: clamp(var(--s-7), 6vw, var(--s-10));
    align-items: end;
  }

  #founder-hero .fh__name { max-width: 10ch; }
  #founder-hero .fh__role { margin-top: var(--s-6); font-size: 15.5px; color: var(--ink-soft); }
  #founder-hero .fh__portrait { width: 100%; height: auto; }

  @media (max-width: 899px) {
    #founder-hero .fh__grid { grid-template-columns: 1fr; gap: var(--s-7); align-items: start; }
  }

/* ---- section: definition ---- */
#definition {
    padding-block: clamp(96px, 13vw, 200px);
    background: var(--surface);
  }

  #definition .def__word {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: clamp(var(--s-6), 4vw, var(--s-8));
  }

  #definition .def__type {
    font-size: clamp(28px, 4.6vw, 64px);
    font-weight: 500;
    line-height: 1.08;
    letter-spacing: -0.03em;
    max-width: 22ch;
    text-wrap: balance;
  }

  #definition .def__mark { background: var(--lime); padding: 0 .12em; }

/* ---- section: bio ---- */
#bio { padding-block: clamp(88px, 11vw, 160px); }

  #bio .bio__grid {
    display: grid;
    grid-template-columns: minmax(0, .42fr) minmax(0, 1fr);
    gap: clamp(var(--s-7), 6vw, var(--s-10));
    align-items: start;
  }

  #bio .bio__copy p { font-size: clamp(18px, 1.35vw, 21px); line-height: 1.6; max-width: 48ch; }
  #bio .bio__copy p + p { margin-top: var(--s-5); }

  #bio .bio__facts { margin-top: clamp(var(--s-8), 6vw, var(--s-9)); display: grid; gap: var(--s-5); }
  #bio .bio__facts dt {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: var(--s-2);
  }
  #bio .bio__facts dd { font-size: 17px; max-width: 52ch; }

  #bio .bio__cta { margin-top: clamp(var(--s-8), 6vw, var(--s-9)); }

  @media (max-width: 899px) {
    #bio .bio__grid { grid-template-columns: 1fr; gap: var(--s-6); }
  }

/* ---- section: contact-head ---- */
#contact-head { padding-block: clamp(120px, 16vw, 200px) clamp(40px, 5vw, 64px); }
  #contact-head .ch__title { max-width: 13ch; margin-bottom: var(--s-6); }
  #contact-head .ch__lede { color: #4a4a4a; }

/* ---- section: contact-form ---- */
#contact-form { padding-bottom: clamp(88px, 11vw, 160px); }

  #contact-form .cf__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, .66fr);
    gap: clamp(var(--s-7), 6vw, var(--s-10));
    align-items: start;
  }

  #contact-form .field { display: grid; gap: var(--s-2); margin-bottom: var(--s-6); }

  #contact-form .field label {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-soft);
  }

  /* 16px minimum on every input. Anything smaller and iOS Safari zooms the
     whole page on focus, which reads as the layout breaking. */
  #contact-form .input {
    width: 100%;
    min-height: 54px;
    padding: var(--s-3) 0;
    border: 0;
    border-bottom: 1px solid #d8d8d8;
    border-radius: 0;
    background: transparent;
    color: var(--ink);
    font-family: var(--font);
    font-size: 16.5px;
    transition: border-color 200ms var(--ease);
  }

  #contact-form textarea.input { min-height: 130px; padding-top: var(--s-4); line-height: 1.6; resize: vertical; }
  #contact-form select.input { appearance: none; cursor: pointer; }
  #contact-form .input:focus { border-color: var(--ink); outline: none; }
  #contact-form .input::placeholder { color: var(--grey-light); }

  #contact-form .field--pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-5); }
  #contact-form .cf__submit { margin-top: var(--s-4); }
  #contact-form .cf__fine { margin-top: var(--s-5); font-size: 14px; color: var(--ink-soft); }

  #contact-form .cf__side { display: grid; gap: clamp(var(--s-6), 4vw, var(--s-8)); }

  #contact-form .cf__block dt {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: var(--s-3);
  }

  #contact-form .cf__block dd { font-size: 18px; }
  #contact-form .cf__block dd + dd { margin-top: var(--s-2); }
  #contact-form .cf__block a { text-decoration: none; box-shadow: inset 0 -2px 0 var(--lime); }
  #contact-form .cf__block a:hover { box-shadow: inset 0 -10px 0 var(--lime); }

  #contact-form .cf__social { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5); }
  #contact-form .cf__social a { font-size: 16px; }

  #contact-form .cf__still { width: 100%; height: auto; }

  @media (max-width: 899px) {
    #contact-form .cf__grid { grid-template-columns: 1fr; gap: var(--s-8); }
    #contact-form .field--pair { grid-template-columns: minmax(0, 1fr); gap: 0; }
  }
