/* =============================================================
   33 SOUTH STUDIO — v2
   Static stylesheet. No build step, no framework.

   Structure and motion follow getsticky.framer.ai: rounded slabs
   inset from the viewport edge, pill buttons, a centred logo nav,
   and sticky-pinned panels that hold while you scroll past them.

   PALETTE — five colours, nothing else.
   Vibrant Coral is a weak colour: White Smoke on Coral is 2.53:1
   and Coral on White Smoke is the same. It is therefore only ever
   used as a FILL BEHIND CARBON BLACK (6.36:1), or as text on
   Carbon Black. Never coral text on a light ground.
   ============================================================= */

:root {
  /* Palette */
  --forest: #0D3F25;   /* Deep Forest   */
  --grey:   #EAEAEA;   /* Alabaster Grey */
  --black:  #1A1A1A;   /* Carbon Black  */
  --coral:  #FF6F59;   /* Vibrant Coral */
  --smoke:  #F6F6F4;   /* White Smoke   */

  /* Semantic */
  --bg:         var(--smoke);
  --text:       var(--black);
  --text-quiet: var(--forest);
  --rule:       var(--grey);
  --rule-dark:  rgba(234, 234, 234, 0.28); /* Alabaster Grey, softened for dark slabs */

  /* Type */
  --font-title: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-body:  "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  --fs-hero:  clamp(2.5rem, 6.4vw, 6rem);
  --fs-h2:    clamp(1.75rem, 3.4vw, 3.25rem);
  --fs-big:   clamp(2rem, 4.6vw, 4.25rem);
  --fs-lede:  clamp(1.0625rem, 1.35vw, 1.3125rem);
  --fs-body:  clamp(1rem, 1.05vw, 1.0625rem);
  --fs-row:   clamp(1.0625rem, 1.5vw, 1.375rem);
  --fs-eye:   0.75rem;

  /* Rhythm */
  --sp-1: 0.5rem;  --sp-2: 1rem;   --sp-3: 1.5rem;
  --sp-4: 2rem;    --sp-5: 3rem;   --sp-6: 4rem;
  --band-y: clamp(4.5rem, 9vw, 9rem);
  --gutter: clamp(1.25rem, 4vw, 3.5rem);

  /* Slab geometry — the inset rounded panel the reference leans on */
  --inset:  clamp(0.5rem, 0.7vw, 0.75rem);
  --radius: clamp(20px, 2.2vw, 32px);
  --radius-sm: clamp(14px, 1.6vw, 24px);

  --nav-h: 76px;                          /* the bar's real height — see .nav__inner */
  --nav-gap: clamp(0.875rem, 1.8vw, 1.5rem); /* air between the bar and the first slab */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 240ms;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  overflow-x: clip; /* guard only — `clip` does not create a scroll container */
}
body, h1, h2, h3, p, ul, ol, li, figure { margin: 0; padding: 0; }
ul, ol { list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

:focus-visible { outline: 3px solid var(--black); outline-offset: 3px; border-radius: 4px; }
.hero :focus-visible,
.slab--forest :focus-visible,
.slab--black :focus-visible { outline-color: var(--smoke); }

.skip-link {
  position: fixed; top: 0; left: var(--sp-2);
  transform: translateY(-140%);
  transition: transform var(--dur) var(--ease);
  z-index: 999;
  background: var(--coral); color: var(--black);
  font-family: var(--font-title); font-weight: 600; font-size: 0.875rem;
  padding: var(--sp-2) var(--sp-3);
  border-radius: 100px; text-decoration: none;
}
.skip-link:focus { transform: translateY(var(--sp-2)); }

/* ---------- Layout ---------- */
.wrap { width: 100%; max-width: 1180px; margin-inline: auto; padding-inline: var(--gutter); }
.wrap--wide { max-width: 1500px; }

.band { padding-block: var(--band-y); scroll-margin-top: calc(var(--nav-h) + var(--nav-gap)); }
.band--smoke { background: var(--smoke); }
.band--tight { padding: var(--inset); scroll-margin-top: calc(var(--nav-h) + var(--nav-gap)); }

/* Rounded inset slab.
   `overflow: hidden` is applied ONLY where content actually has to be
   clipped to the corners — it establishes a scroll container that would
   otherwise break position:sticky on the cards inside the forest slab. */
.slab {
  border-radius: var(--radius);
  position: relative;
}
.hero__slab, .slab--black { overflow: hidden; }
.slab--forest {
  background: var(--forest); color: var(--smoke);
  padding-block: clamp(3.5rem, 7vw, 7rem);
}
.slab--forest > .wrap > *:last-child { margin-block-end: 0; }
.slab--black  { background: var(--black);  color: var(--smoke); padding-block: clamp(4rem, 8vw, 8rem) 0; }

/* ---------- Logo ---------- */
.logo {
  display: inline-flex; flex-direction: column; align-items: center;
  font-family: var(--font-title); font-weight: 800;
  text-decoration: none; line-height: 1; white-space: nowrap;
}
.logo__row { display: inline-flex; align-items: baseline; }
.logo__33    { color: var(--forest); font-size: 1.5rem; letter-spacing: -0.045em; }
.logo__south { color: var(--black);  font-size: 1.5rem; letter-spacing: -0.045em; }
.logo__studio {
  font-size: 0.5rem; font-weight: 600; letter-spacing: 0.42em;
  text-transform: uppercase; color: var(--black);
  margin-block-start: 0.28em; margin-inline-start: 0.42em;
}
/* Light variant for dark grounds: "33" coral, "south" White Smoke.
   Unused while the nav carries its own White Smoke bar, but this is the
   agreed treatment for any placement on Deep Forest or Carbon Black. */
.logo--light .logo__33 { color: var(--coral); }
.logo--light .logo__south, .logo--light .logo__studio { color: var(--smoke); }

/* ---------- Nav ----------
   Full width and flush to the top, on a White Smoke ground throughout.
   It does not go transparent over the hero: the green logo measures 2.65:1
   against the brightest part of that photograph, under the 3:1 floor even
   for display-size text. Transparency would need the light logo variant.

   No bottom rule, and --nav-gap of clear ground beneath it, so the bar and the
   first slab read as two separate objects rather than one cut-off one. */
.nav {
  position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 100;
  color: var(--black);
  background: var(--smoke);
}
.nav__inner {
  position: relative;
  max-width: 1500px; margin-inline: auto;
  padding-inline: var(--gutter);
  min-height: var(--nav-h);
  height: var(--nav-h);
  display: flex; align-items: center; gap: var(--sp-2);
}

.nav__links { display: none; flex: 1 1 0; }
.nav__links ul { display: flex; gap: var(--sp-4); }
.nav__links a {
  font-family: var(--font-title); font-weight: 600; font-size: 0.8125rem;
  letter-spacing: 0.02em; text-decoration: none; position: relative;
  padding-block: 0.35rem; opacity: 0.8; transition: opacity var(--dur) var(--ease);
}
.nav__links a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--coral); transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.nav__links a:hover { opacity: 1; }
.nav__links a:hover::after, .nav__links a.is-active::after { transform: scaleX(1); }
.nav__links a.is-active { opacity: 1; }

.nav .logo { margin-inline-end: auto; }
.nav__cta { flex: 0 0 auto; }

@media (min-width: 1000px) {
  .nav__links { display: block; }
  .nav .logo { position: absolute; left: 50%; transform: translateX(-50%); margin: 0; }
  .nav__cta { margin-inline-start: auto; }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0.75rem 1.5rem;
  font-family: var(--font-title); font-weight: 600; font-size: 0.875rem;
  text-decoration: none; border: 2px solid currentColor;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn--pill { border-radius: 100px; }
.btn span[aria-hidden] { margin-inline-start: 0.5em; }
.link span[aria-hidden] { margin-inline-start: 0.35em; }
.btn:hover { transform: translateY(-2px); }

/* Coral fill always carries Carbon Black text — 6.36:1.
   White Smoke on Coral is 2.53:1 and is never used. */
.btn--coral {
  background: var(--coral); color: var(--black); border-color: var(--coral);
}
.btn--coral:hover { background: var(--black); color: var(--coral); border-color: var(--black); }
.btn--lg { min-height: 62px; padding: 1rem 2rem; font-size: clamp(1rem, 1.6vw, 1.25rem); }

/* Get In Touch is a Deep Forest tile: heading, then the address. */
.contact .h2--big { margin-block-end: clamp(2rem, 4vw, 3rem); }
.stack:last-child { margin-block-end: 0; }

/* Sized against the logo lockup (34px) rather than the full .btn, which
   rendered 52px here and read as oversized next to it. */
.nav__cta {
  background: var(--coral); color: var(--black); border-color: var(--coral);
  min-height: 44px; padding: 0.375rem 1.125rem;
  font-size: 0.75rem; letter-spacing: 0.01em;
}
@media (min-width: 1000px) {
  .nav__cta { min-height: 40px; padding: 0.375rem 1.25rem; }
}
.nav__cta:hover { background: var(--black); color: var(--coral); border-color: var(--black); }

.link {
  text-decoration: none; border-bottom: 2px solid var(--forest);
  padding-bottom: 1px; transition: opacity var(--dur) var(--ease);
}
.slab--forest .link, .slab--black .link { border-bottom-color: var(--coral); }
.link:hover { opacity: 0.65; }

/* ---------- Hero ---------- */
.hero { padding: calc(var(--nav-h) + var(--nav-gap)) var(--inset) var(--inset); }
.hero__slab {
  position: relative; isolation: isolate;
  min-height: calc(100svh - var(--nav-h) - var(--nav-gap) - var(--inset));
  display: grid; place-items: center;
  border-radius: var(--radius);
  background: var(--forest);
  padding: clamp(3rem, 7vh, 5rem) var(--gutter) clamp(3.5rem, 8vh, 6rem);
  text-align: center;
}
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: center 55%; }
/* Flat single-opacity wash of Deep Forest — no gradient, no shadow.
   Only large display text sits on it (needs 3:1); it measures 3.3:1. */
.hero__scrim { position: absolute; inset: 0; z-index: 1; background: var(--forest); opacity: 0.54; }
.hero__body { position: relative; z-index: 2; width: 100%; }

.hero__title {
  font-family: var(--font-title); font-weight: 700;
  font-size: var(--fs-hero); line-height: 1.04; letter-spacing: -0.035em;
  color: var(--smoke); text-wrap: balance;
  /* The <br> carries the line break; this only needs to be wide enough that
     neither sentence wraps again on desktop. On a phone they wrap normally. */
  max-width: 24ch; margin-inline: auto;
}
.hero__cta { margin-block-start: clamp(2rem, 4vw, 3rem); }

.hero__cue {
  position: absolute; bottom: clamp(1.5rem, 3vh, 2.5rem); left: 50%;
  translate: -50% 0; z-index: 2;
  width: 2px; height: 46px; background: var(--smoke); opacity: 0.55;
  border-radius: 2px; transform-origin: top;
  animation: cue 2.6s var(--ease) infinite;
}
@keyframes cue {
  0% { transform: scaleY(0); opacity: 0; }
  35% { transform: scaleY(1); opacity: 0.55; }
  75% { transform: scaleY(1); opacity: 0.55; }
  100% { transform: scaleY(1); opacity: 0; }
}

/* ---------- Lede ---------- */
.lede__grid { display: grid; gap: clamp(1.75rem, 3.5vw, 3rem); }
.lede__p { font-size: var(--fs-lede); line-height: 1.7; color: var(--text-quiet); max-width: 72ch; }
.lede__p--lead {
  font-family: var(--font-title); font-weight: 700;
  font-size: clamp(1.25rem, 2.3vw, 2rem); line-height: 1.3;
  letter-spacing: -0.025em; color: var(--black); max-width: none;
}
.lede__ask {
  margin-block-start: clamp(2.5rem, 5vw, 4rem);
  font-family: var(--font-title); font-weight: 600;
  font-size: clamp(1.0625rem, 1.7vw, 1.375rem);
}


/* ---------- Section furniture ---------- */
.eyebrow {
  font-family: var(--font-title); font-weight: 600; font-size: var(--fs-eye);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--forest); display: flex; align-items: center; gap: 0.85em;
  margin-block-end: var(--sp-3);
}
.eyebrow--light { color: var(--smoke); }
.eyebrow--light .eyebrow__num { color: var(--smoke); }
.eyebrow__num {
  color: var(--coral); font-variant-numeric: tabular-nums;
  padding-inline-end: 0.85em; border-inline-end: 2px solid currentColor;
}
/* Coral on White Smoke is 2.53:1, so on light grounds the numeral
   is Deep Forest and coral is held back for fills. */
.band--smoke .eyebrow__num { color: var(--forest); }

.h2 {
  font-family: var(--font-title); font-weight: 700;
  font-size: var(--fs-h2); line-height: 1.12; letter-spacing: -0.03em;
  max-width: 20ch; text-wrap: balance;
}
.h2--light { color: var(--smoke); max-width: 24ch; }
.h2--wide { max-width: 22ch; margin-block-end: clamp(2.5rem, 5vw, 4rem); }
.h2--big { font-size: var(--fs-big); max-width: 18ch; margin-block-end: clamp(2rem, 4vw, 3rem); }

/* ---------- Pinned two-column (About) ---------- */
.pin { display: grid; gap: clamp(2.5rem, 5vw, 4rem); }
@media (min-width: 900px) {
  .pin { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: clamp(3rem, 6vw, 5.5rem); align-items: start; }
  .pin__aside { position: sticky; top: calc(var(--nav-h) + 2rem); }
  .pin--flip .pin__aside { order: 2; }
  .pin--flip .prose { order: 1; }
  .pin--flip { grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr); }
}

/* ---------- Rows ---------- */
.row__num {
  font-family: var(--font-title); font-weight: 700; font-size: 0.75rem;
  letter-spacing: 0.1em; font-variant-numeric: tabular-nums;
  color: var(--forest); padding-block-start: 0.5em;
}
.row__text { font-size: var(--fs-row); line-height: 1.5; color: var(--text-quiet); max-width: 42ch; }
.term { font-family: var(--font-title); font-weight: 700; letter-spacing: -0.02em; color: var(--black); }


/* ---------- Section 02: What We Do ----------
   The five disciplines reuse the How We Work stack wholesale — same markup,
   same classes — so they pin and pile identically and there is no parallel
   set of rules to drift out of step. */

/* ---------- Section 03: pinned stage ----------
   The stage runs on phones as well as desktop — same conveyor, same
   scroll-driven tile, only the grid differs. A column of five photographs
   one after another threw away everything the section does.

   This base layer is the stand-down: a plain heading, the full list of rows
   and the photographs stacked. It is what short viewports, no-JS and
   reduced-motion get. Everything below is layered on top of it. */
.wsa__track { display: grid; gap: clamp(2.5rem, 5vw, 3.5rem); }
.wsa__stage {
  max-width: 1440px; margin-inline: auto; width: 100%;
  padding-inline: var(--gutter);
  display: grid; gap: clamp(2rem, 4vw, 3rem);
  grid-template-columns: minmax(0, 1fr);
}
.wsa__rows { display: grid; gap: 0; border-top: 2px solid var(--rule); }
.wsa__row {
  display: grid; grid-template-columns: 2.75rem 1fr; gap: var(--sp-2);
  align-items: start; padding-block: clamp(1.15rem, 2.2vw, 1.6rem);
  border-bottom: 2px solid var(--rule);
}
.row__body { min-width: 0; }
.row__term {
  font-family: var(--font-title); font-weight: 700;
  font-size: 0.8125rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--black); margin-block-end: 0.4rem;
}
/* White Smoke, not grey, so an outgoing tile dissolves into the page ground
   rather than into a visible card. */
.pane { border-radius: var(--radius-sm); overflow: hidden; background: var(--smoke); }
/* 16:9 everywhere, matching the delivered file, so the stand-down paths
   (short viewport, no JS, reduced motion) crop nothing at all. */
.pane__img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
/* Phone: the five rows and the five photographs are separate parents in the
   markup, so both are flattened into the stage grid and placed by hand. That
   pairs each point with its own picture — text, picture, rule, text, picture —
   instead of listing all five points and then all five photographs. */
@media (max-width: 899.98px) {
  .wsa__rows, .pane { display: contents; }
  .pane__img { border-radius: var(--radius-sm); }
  .wsa__stage { gap: clamp(1.25rem, 4vw, 1.75rem); }
  .wsa__head { grid-row: 1; }
  /* The rule now separates one pair from the next rather than cutting a point
     away from its own photograph, so it moves from the foot of a row to its head. */
  .wsa__row {
    border-bottom: 0; border-top: 2px solid var(--rule);
    padding-block: clamp(1.15rem, 2.2vw, 1.6rem) 0;
  }
  .wsa__row .row__text { font-size: 1.0625rem; line-height: 1.45; max-width: none; }
  .wsa__row .row__num { font-size: 0.75rem; padding-block-start: 0.3em; }
  .wsa__row[data-i="0"] { grid-row: 2; }  .pane__img[data-i="0"] { grid-row: 3; }
  .wsa__row[data-i="1"] { grid-row: 4; }  .pane__img[data-i="1"] { grid-row: 5; }
  .wsa__row[data-i="2"] { grid-row: 6; }  .pane__img[data-i="2"] { grid-row: 7; }
  .wsa__row[data-i="3"] { grid-row: 8; }  .pane__img[data-i="3"] { grid-row: 9; }
  .wsa__row[data-i="4"] { grid-row: 10; } .pane__img[data-i="4"] { grid-row: 11; }
}

/* ---- The pinned stage, desktop only ----
   A phone column is far shorter than a phone screen: heading, one row of text
   and a 16:9 frame come to roughly 575px against 768px of stage. That surplus
   has to sit somewhere, and every arrangement of it reads as a mistake —
   pooled at the edges it is two bars, spread between the elements it is two
   gaps. So phones do not pin at all; they get the paired layout above, where
   each point is followed by its own photograph and there is no surplus to
   place. The height gate matches the desktop grid below exactly: at 620px it
   did not, and a short wide window pinned a stage with no named grid areas,
   letterboxing the tile to 3.5:1. */
@media (min-width: 900px) and (min-height: 700px) {
  .wsa__track {
    display: block;
    /* One viewport to hold the stage, plus travel for each row after the first. */
    min-height: calc(100svh + (4 * var(--wsa-travel)));
  }
  .wsa__stage {
    position: sticky;
    top: var(--nav-h);
    height: calc(100svh - var(--nav-h));
    padding-block: clamp(1.5rem, 4vh, 3.5rem);
    align-content: start;
  }
  .wsa__head { grid-area: head; align-self: start; }
  .pane      { grid-area: tile; display: block; position: relative; }

  /* The slot is framed top and bottom on the container rather than on the row,
     so it stays put whichever row is in it. */
  .wsa__rows {
    grid-area: rows; display: grid;
    border-top: 2px solid var(--rule); border-bottom: 2px solid var(--rule);
    padding-block: clamp(1.25rem, 2.2vw, 2rem);
  }
  /* All five share one cell, so the slot is as tall as the longest row.
     Centring each row within that cell keeps short and long rows optically
     level rather than hanging the short ones off the top rule. */
  .wsa__row {
    grid-area: 1 / 1; align-self: center;
    border-bottom: 0; padding-block: 0;
  }
  .js .wsa__row {
    opacity: 0; transform: translate3d(0, 52px, 0);
    transition: opacity 480ms var(--ease), transform 560ms var(--ease);
  }
  .js .wsa__row.is-past   { opacity: 0; transform: translate3d(0, -52px, 0); }
  .js .wsa__row.is-active { opacity: 1; transform: none; }

  /* Frames are stacked and driven straight from scroll position by
     js/script.js, which writes opacity and transform each frame. These values
     only cover the moment before the driver's first pass. */
  .pane__img {
    position: absolute; inset: 0; width: 100%; height: 100%;
    aspect-ratio: auto; z-index: 1;
    opacity: 0; transform: scale(1.12);
  }
  .pane__img.is-on { opacity: 1; z-index: 2; }
  /* Scroll-linked means no timed transition — a transition here would lag
     behind the scroll rather than track it. */
  .wsa__stage.is-driven .pane__img { transition: none; }

  /* Without JS nothing can advance the conveyor, so the whole enhancement is
     stood down and the section falls back to the plain layout. Otherwise four
     of the five rows would be unreachable. The inline head script also omits
     `js` under reduced motion, so that case lands here too. */
  html:not(.js) .wsa__track { min-height: 0; display: grid; }
  html:not(.js) .wsa__stage {
    position: static; height: auto;
    grid-template-areas: none;
    grid-template-columns: minmax(0, 1fr);
  }
  html:not(.js) .wsa__rows { align-self: start; border-bottom: 0; padding-block: 0; }
  html:not(.js) .wsa__row {
    grid-area: auto; align-self: auto; opacity: 1;
    border-bottom: 2px solid var(--rule);
    padding-block: clamp(1.15rem, 2.2vw, 1.6rem);
  }
  html:not(.js) .pane { display: contents; }
  html:not(.js) .pane__img {
    position: static; opacity: 1; transform: none; aspect-ratio: 16 / 9;
    border-radius: var(--radius-sm);
  }
}

/* ---- Desktop: heading and slot side by side, tile full width beneath ---- */
@media (min-width: 900px) and (min-height: 700px) {
  :root { --wsa-travel: 64vh; }
  .wsa__stage {
    grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
    grid-template-rows: auto minmax(190px, 1fr);
    grid-template-areas: "head rows" "tile tile";
    gap: clamp(1.5rem, 3vw, 2.5rem) clamp(2rem, 4vw, 4rem);
    padding-block: clamp(2rem, 4vh, 3.5rem);
  }
  /* The tile takes whatever height the stage has left, which at full width
     made it a 2.5:1 letterbox — that was cutting 40–70% off photographs shot
     at 3:2. Holding it to 16:9 and letting the width follow keeps far more of
     each frame; it centres in the column rather than spanning it. */
  .pane {
    aspect-ratio: 16 / 9;
    height: 100%; width: auto; max-width: 100%;
    margin-inline: auto;
  }
  .wsa__rows { align-self: center; }
  .wsa__row { grid-template-columns: 3.5rem minmax(0, 1fr); gap: var(--sp-3); }
  /* Sized to sit as a peer of the heading rather than a footnote beside it. */
  .wsa__row .row__text { font-size: clamp(1.0625rem, 1.45vw, 1.4375rem); line-height: 1.45; max-width: none; }
  .wsa__row .row__num { font-size: 0.8125rem; padding-block-start: 0.35em; }

  html:not(.js) .wsa__stage { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  html:not(.js) .wsa__head,
  html:not(.js) .wsa__rows,
  html:not(.js) .pane { grid-area: auto; }
  html:not(.js) .wsa__head, html:not(.js) .wsa__rows { grid-column: 1 / -1; }
}

/* ---------- Sticky stack (How We Work) ---------- */
.stack { margin-block: clamp(3rem, 6vw, 5rem); }
.stack:last-child { margin-block-end: 0; }
.stack__card {
  background: var(--forest);
  border: 2px solid var(--rule-dark);
  border-radius: var(--radius-sm);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  display: grid; grid-template-columns: 2.75rem 1fr; gap: var(--sp-2);
  align-items: start;
  margin-block-end: var(--sp-2);
}
.stack__num {
  font-family: var(--font-title); font-weight: 700; font-size: 0.75rem;
  letter-spacing: 0.1em; font-variant-numeric: tabular-nums;
  color: var(--smoke); padding-block-start: 0.5em;
}
.slab--black .stack__num { color: var(--coral); } /* 6.36:1 on Carbon Black */
.stack__body { min-width: 0; }
.stack__term {
  font-family: var(--font-title); font-weight: 700;
  font-size: 0.8125rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--smoke); margin-block-end: 0.6rem;
}
.stack__text { font-size: var(--fs-body); line-height: 1.6; color: var(--smoke); max-width: 56ch; }
.stack__text + .stack__text { margin-block-start: 0.6rem; }

.sec__intro, .hww__intro {
  font-size: var(--fs-lede); line-height: 1.7; color: var(--smoke);
  /* Always more air under the heading than between the paragraphs below it. */
  max-width: none; margin-block-start: clamp(1.75rem, 2.6vw, 2.25rem);
}
.sec__intro + .sec__intro { margin-block-start: var(--sp-3); }
.hww__close {
  font-family: var(--font-title); font-weight: 700;
  font-size: clamp(1.125rem, 2vw, 1.75rem); letter-spacing: -0.02em;
  color: var(--smoke); padding-block-start: clamp(1.5rem, 3vw, 2.5rem);
  border-top: 2px solid var(--rule-dark);
}
.stack__card .term { color: var(--smoke); }

/* Pin the cards so they pile up. Gated on viewport height rather than width,
   so phones get the pile too and only a short window or a phone held sideways
   falls back to a plain list. */
@media (min-height: 620px) {
  .stack__card {
    position: sticky;
    top: calc(var(--nav-h) + var(--stack-top) + (var(--i) * var(--stack-step)));
    /* The gap between cards is the pin duration: a card stays visible
       until the next one travels up and covers it. */
    margin-block-end: var(--stack-space);
  }
  .stack__card:last-child { margin-block-end: 0; }
  /* Bottom padding extends the sticky container so the finished pile
     holds for a beat before the section moves on. */
  .stack { padding-block-end: var(--stack-hold); }
}

/* Phone: a tighter pile, since six cards of wrapped copy need the room. */
@media (min-height: 620px) and (max-width: 899.98px) {
  :root {
    --stack-top: 1rem;
    --stack-step: 10px;
    --stack-space: clamp(1.5rem, 6vw, 2.5rem);
    /* A short hold on a phone: the cards are tall, so a long one just leaves
       a growing panel of empty green once the pile has formed. */
    --stack-hold: min(10vh, 90px);
  }
}

@media (min-width: 900px) and (min-height: 700px) {
  :root {
    --stack-top: 2rem;
    --stack-step: 14px;
    --stack-space: clamp(2.5rem, 5vw, 5rem);
    /* Enough to let the finished pile settle, not so much that a long panel
       of empty green opens up before the line that closes the section. */
    --stack-hold: min(10vh, 90px);
  }
  .stack__card { grid-template-columns: 4rem 1fr; gap: var(--sp-4); }
}

/* ---------- Figures ---------- */
.figure { border-radius: var(--radius-sm); overflow: hidden; margin-block: clamp(3rem, 6vw, 5rem); }
.figure--flush { border-radius: 0; margin-block: 0; margin-block-start: clamp(3rem, 6vw, 5rem); }
.figure--band { margin-block-end: 0; }
.figure img { width: 100%; }

/* ---------- Prose (About) ---------- */
.prose { max-width: 56ch; }
.prose p { color: var(--text-quiet); font-size: var(--fs-lede); line-height: 1.7; }
.prose p + p { margin-block-start: var(--sp-3); }
.prose__cue { font-family: var(--font-title); font-weight: 600; color: var(--black) !important; margin-block-start: var(--sp-4); }
.prose__claim {
  font-family: var(--font-title); font-weight: 700;
  font-size: clamp(1.125rem, 1.9vw, 1.5rem); line-height: 1.35;
  letter-spacing: -0.02em; color: var(--black) !important;
  margin-block-start: 0.5rem !important; margin-block-end: var(--sp-4);
  padding-inline-start: clamp(1rem, 2vw, 1.5rem);
  border-inline-start: 3px solid var(--forest);
}
.prose__lead {
  font-family: var(--font-title); font-weight: 700;
  font-size: clamp(1.25rem, 2.2vw, 1.875rem); line-height: 1.3;
  letter-spacing: -0.025em; color: var(--black) !important;
  margin-block-end: var(--sp-4);
}
.about__media img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--radius-sm); }
/* Desktop only: the picture stops being a landscape card pinned at the top and
   instead runs the full height of the prose beside it. Phone keeps the 3:2
   landscape, where a tall portrait would push the text off the screen. */
@media (min-width: 900px) {
  .pin--flip { align-items: stretch; }
  .pin--flip .pin__aside { position: static; top: auto; display: flex; }
  .about__media img { height: 100%; aspect-ratio: auto; object-position: center 42%; }
}
/* Matches the photograph's own 3:2, so nothing is cropped away. */

/* ---------- Duo (Who We Work With) ---------- */
.duo { display: grid; gap: var(--sp-4); max-width: 68ch; }
.duo__p { font-size: var(--fs-lede); line-height: 1.75; color: var(--smoke); }
@media (min-width: 900px) {
  .duo { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(2.5rem, 5vw, 4rem); max-width: none; }
  .duo__p { padding-block-start: var(--sp-3); border-top: 2px solid var(--rule-dark); }
}

/* ---------- Footer ---------- */
.footer { background: var(--smoke); border-top: 2px solid var(--rule); padding-block: var(--sp-5); color: var(--text-quiet); }
.footer__inner {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--sp-3) var(--sp-5);
  font-family: var(--font-title); font-size: 0.8125rem; font-weight: 600;
}
.footer__legal { font-variant-numeric: tabular-nums; opacity: 0.75; }

/* ---------- Reveal ---------- */
[data-reveal] { opacity: 1; transform: none; }
.js [data-reveal] {
  opacity: 0; transform: translate3d(0, 22px, 0);
  transition: opacity 700ms var(--ease), transform 700ms var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal].is-revealed { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
  .hero__cue { animation: none; opacity: 0.55; }
  .stack__card { position: static !important; }
  .wsa__track { display: grid !important; min-height: 0 !important; }
  .wsa__stage { position: static !important; height: auto !important; grid-template-areas: none !important; grid-template-columns: minmax(0,1fr) !important; }
  .wsa__head, .wsa__rows, .pane { grid-area: auto !important; }
  .wsa__rows { border-bottom: 0 !important; padding-block: 0 !important; }
  .wsa__row {
    opacity: 1 !important; transform: none !important; grid-area: auto !important;
    border-bottom: 2px solid var(--rule) !important; padding-block: 1.25rem !important;
  }
  .pane { display: contents !important; }
  .pane__img { position: static !important; opacity: 1 !important; transform: none !important; aspect-ratio: 16 / 9 !important; border-radius: var(--radius-sm); }
  .btn:hover, .tile:hover img { transform: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media print {
  .nav, .hero__cue, .figure, .tiles { display: none; }
  body { background: #fff; color: #000; }
}

/* =============================================================
   PRODUCTION BRIEF MODAL
   Deep Forest panel on a Carbon Black scrim, using the same rounded
   geometry as the page's tiles. Only name and email are required;
   everything else can be left blank.
   ============================================================= */
.modal { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: var(--inset); }
.modal[hidden] { display: none; }
.modal__scrim { position: absolute; inset: 0; background: var(--black); opacity: 0.55; }
.modal__panel {
  position: relative;
  width: min(760px, 100%);
  max-height: calc(100dvh - (var(--inset) * 2));
  background: var(--forest); color: var(--smoke);
  border-radius: var(--radius);
  display: flex; flex-direction: column;
}
.modal__scroll { overflow-y: auto; overscroll-behavior: contain; padding: clamp(1.75rem, 4vw, 3.25rem); }
.modal__x {
  position: absolute; top: 0.75rem; right: 0.75rem; z-index: 2;
  width: 44px; height: 44px; border-radius: 100px;
  background: var(--forest); border: 2px solid var(--rule-dark);
  color: var(--smoke); font-size: 1.5rem; line-height: 1; cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.modal__x:hover { background: var(--black); }

.brief__head { margin-block-end: clamp(1.75rem, 3.5vw, 2.5rem); }
.brief__head .eyebrow { color: var(--smoke); }
.brief__head .eyebrow__num { color: var(--smoke); }
.brief__head .h2 { color: var(--smoke); max-width: 20ch; margin-block-end: var(--sp-3); }
.brief__intro { font-size: var(--fs-body); line-height: 1.7; color: var(--smoke); max-width: 62ch; }
.brief__intro + .brief__intro { margin-block-start: var(--sp-2); }
.brief__intro--em { font-family: var(--font-title); font-weight: 600; }

/* ---- Fields ---- */
.f { margin-block-end: clamp(1.1rem, 2.2vw, 1.6rem); border: 0; padding: 0; }
.f__label {
  display: block; font-family: var(--font-title); font-weight: 600;
  font-size: 0.875rem; color: var(--smoke); margin-block-end: 0.4rem;
}
.f__label abbr { color: var(--coral); text-decoration: none; }
.f__help { display: block; font-size: 0.8125rem; line-height: 1.5; color: var(--grey); opacity: 0.75; margin-block-end: 0.5rem; }
/* White Smoke rather than coral: coral text on the forest panel falls short of
   4.5:1. The coral rule carries the signal; the words carry the meaning. */
.f__error {
  display: block; margin-block-start: 0.6rem; padding-inline-start: 0.75rem;
  border-inline-start: 3px solid var(--coral);
  font-size: 0.875rem; line-height: 1.5; color: var(--smoke);
}
.f__control {
  width: 100%; min-height: 48px;
  padding: 0.7rem 0.9rem;
  font-family: var(--font-body); font-size: 1rem; color: var(--smoke);
  background: rgba(246, 246, 244, 0.06);
  border: 2px solid var(--rule-dark); border-radius: 12px;
}
.f__control:focus-visible { outline: 3px solid var(--coral); outline-offset: 2px; }
textarea.f__control { min-height: 0; resize: vertical; line-height: 1.6; }
select.f__control { appearance: none; background-image: none; cursor: pointer; }
select.f__control option { background: var(--forest); color: var(--smoke); }
.f__file { padding: 0.6rem 0.7rem; cursor: pointer; }

.f--group { margin-block-end: clamp(1.4rem, 2.8vw, 2rem); }
.opts { display: grid; gap: 0.4rem; }
@media (min-width: 620px) { .opts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.opts--inline { grid-template-columns: none !important; display: flex; flex-wrap: wrap; gap: 0.4rem 1.25rem; }
.opt {
  display: flex; align-items: flex-start; gap: 0.55rem;
  min-height: 44px; padding-block: 0.35rem;
  font-size: 0.9375rem; line-height: 1.45; color: var(--smoke); cursor: pointer;
}
.opt input { width: 20px; height: 20px; margin-block-start: 0.15rem; accent-color: var(--coral); flex: 0 0 auto; cursor: pointer; }

/* ---- Optional detail ---- */
.more { margin-block: clamp(1.5rem, 3vw, 2.25rem); border-block: 2px solid var(--rule-dark); }
.more__toggle {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.75rem;
  padding-block: clamp(1rem, 2vw, 1.4rem); cursor: pointer; list-style: none;
}
.more__toggle::-webkit-details-marker { display: none; }
.more__label { font-family: var(--font-title); font-weight: 700; font-size: 1.0625rem; color: var(--smoke); }
.more__label::before { content: "+ "; color: var(--coral); }
.more[open] .more__label::before { content: "– "; }
.more__hint { font-size: 0.8125rem; color: var(--grey); opacity: 0.75; }
.more__body { padding-block-end: clamp(0.5rem, 1.5vw, 1rem); }
.f__sub {
  font-family: var(--font-title); font-weight: 700;
  font-size: 0.8125rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--smoke); margin-block: clamp(1.75rem, 3.5vw, 2.5rem) var(--sp-3);
  padding-block-start: var(--sp-3); border-top: 2px solid var(--rule-dark);
}
.more__body > .f__sub:first-child { margin-block-start: 0; padding-block-start: 0; border-top: 0; }

/* ---- Close ---- */
.brief__foot { padding-block-start: clamp(1.5rem, 3vw, 2.25rem); border-top: 2px solid var(--rule-dark); }
.brief__ready { font-family: var(--font-title); font-weight: 700; font-size: clamp(1.25rem, 2.4vw, 1.75rem); color: var(--smoke); margin-block-end: var(--sp-2); }
.crit { display: grid; gap: 0.5rem; margin-block: var(--sp-3); }
.crit li { font-size: 0.9375rem; line-height: 1.55; color: var(--smoke); }
.crit b { font-family: var(--font-title); font-weight: 700; display: block; }
.brief__submit { margin-block-start: clamp(1.5rem, 3vw, 2rem); }
.brief__note { margin-block-start: var(--sp-2); font-size: 0.8125rem; color: var(--grey); opacity: 0.75; }
.brief__done .h2, .brief__fail .h2 { color: var(--smoke); margin-block-end: var(--sp-3); }
.brief__done .eyebrow, .brief__done .eyebrow__num { color: var(--smoke); }

/* Honeypot: a real field, kept out of sight and out of the tab order. */
.hp { position: absolute; left: -9999px; opacity: 0; }
.hp input { pointer-events: none; }

/* A button that reads as the inline text link it replaces. */
.link--btn {
  background: none; border: 0; padding: 0 0 1px;
  font: inherit; color: inherit; cursor: pointer;
  border-bottom: 2px solid var(--forest);
}

html.modal-open, body.modal-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .modal__x, .f__control { transition: none !important; }
}

/* Headings that carry their own <br>: the character cap would only wrap each
   half again, so they run the full width of whatever column they sit in. */
.h2--two { max-width: none; }

/* Each of these must hold two lines and no more, so the ceiling is set by the
   longer half against the column it sits in — measured, not guessed:
     What We Do    longer half 1092px at 49px in a 1068px column → 46px caps it
     Why South Africa      582px at 49px in a 521px column → 40px
     Get In Touch         1195px at 66px in a 1068px column → 56px
   Below those widths the vw term shrinks them together, so the ratio holds. */
#what-we-do-title       { font-size: clamp(1.5rem, 3.15vw, 2.875rem); }
#why-south-africa-title { font-size: clamp(1.375rem, 2.6vw, 2.5rem); }
#get-in-touch-title     { font-size: clamp(1.625rem, 3.85vw, 3.5rem); }
