@charset "UTF-8";
/* ==========================================================================
   ORANGE CHARIOT — design system
   1. Tokens            6. Project treatments
   2. Reset & base      7. Sections
   3. Layout            8. Header, nav, footer
   4. Typography        9. Motion
   5. Components       10. Responsive
   ========================================================================== */

/* 1. Tokens ---------------------------------------------------------------- */
:root {
  /* Brand */
  --orange: #ff7900;
  --orange-soft: #ffa45c;
  --ink: #171717;
  --ink-deep: #0e0e0e;
  --charcoal: #303030;
  --paper: #f7f6f3;
  --white: #ffffff;

  /* Accessible accent for text/graphics on light grounds */
  --orange-ink: #b14b00;

  /* Type — two deliberately opposed voices -------------------------------
     DISPLAY: Archivo at its widest width axis (wdth 125%), heavy. The extended
     proportions come from the font's real variable width axis — never from
     CSS stretching or scaleX transforms.
     SUPPORTING: Inter. Neutral, quiet, functional. Carries body copy, nav,
     labels and all smaller headings so the display voice can dominate. */
  --font-display: "Archivo", "Arial Black", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  /* Extended faces occupy far more horizontal space per character, so the
     display scale is set below the equivalent grotesque scale. */
  --step--2: clamp(0.6875rem, 0.67rem + 0.08vw, 0.75rem);
  --step--1: clamp(0.8125rem, 0.79rem + 0.1vw, 0.875rem);
  --step-0: clamp(1rem, 0.97rem + 0.16vw, 1.0625rem);
  --step-1: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  --step-2: clamp(1.25rem, 1.15rem + 0.45vw, 1.5rem);
  --step-3: clamp(1.5rem, 1.25rem + 1vw, 2.05rem);
  --step-4: clamp(1.7rem, 1.25rem + 1.85vw, 2.7rem);
  --display: clamp(1.9rem, 0.95rem + 4.05vw, 4.4rem);
  --display-lg: clamp(2.15rem, 0.5rem + 6.2vw, 6rem);

  /* Space */
  --gutter: clamp(1.25rem, 4vw, 4rem);
  --section-y: clamp(4.5rem, 8vw, 8.5rem);
  --max: 1440px;
  --hair: rgba(23, 23, 23, 0.14);

  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* Homepage only: a slightly more generous vertical rhythm (~10% more than the
   shared --section-y). Applied through the existing spacing token so every
   section stays in proportion rather than gaining ad-hoc margins. */
body.page-home { --section-y: clamp(4.95rem, 8.8vw, 9.35rem); }

/* 2. Reset & base --------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.62;
  letter-spacing: 0.002em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

img, svg, video { display: block; max-width: 100%; }

h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }

ul, ol { margin: 0; padding: 0; list-style: none; }

a { color: inherit; }

button { font: inherit; color: inherit; }

::selection { background: var(--orange); color: #111; }

:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 4px;
}

.skip-link {
  position: fixed;
  left: 1rem;
  top: 1rem;
  z-index: 200;
  padding: 0.75rem 1.1rem;
  background: var(--orange);
  color: #111;
  font-size: var(--step--1);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform 0.3s var(--ease);
}
.skip-link:focus-visible { transform: translateY(0); }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* 3. Layout --------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow {
  max-width: 980px;
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.stack > * + * { margin-top: 1.15em; }
.stack--tight > * + * { margin-top: 0.7em; }

/* Grounds: every section defines its own colour context */
.section {
  --bg: var(--paper);
  --fg: var(--ink);
  --muted: #5d5a54;
  --accent: var(--orange-ink);
  --line: rgba(23, 23, 23, 0.14);
  position: relative;
  background: var(--bg);
  color: var(--fg);
  padding-block: var(--section-y);
  overflow: clip;
}

.section--dark {
  --bg: var(--ink-deep);
  --fg: var(--paper);
  --muted: #a5a09a;
  --accent: var(--orange);
  --line: rgba(247, 246, 243, 0.16);
}

.section--charcoal {
  --bg: #1b1b1b;
  --fg: var(--paper);
  --muted: #a5a09a;
  --accent: var(--orange);
  --line: rgba(247, 246, 243, 0.16);
}

.section--tight { padding-block: clamp(3rem, 5.5vw, 5.5rem); }
.section--flush { padding-block: 0; }

/* 4. Typography -----------------------------------------------------------
   Two voices, deliberately opposed:
   DISPLAY — Archivo, widened to 125% on its real width axis, heavy weight,
   tight tracking. Used selectively: hero statements, project titles, and
   section headings. Never for body copy or UI.
   SUPPORTING — Inter. Everything else. Quiet on purpose. */

.display,
.h1,
.h2,
.h3 {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  text-wrap: balance;
  /* The extended proportions are genuine width-axis behaviour. */
}

/* Hero statements — the loudest the system gets. Sentence case on purpose:
   extended heavy type already carries the identity, and uppercase would make
   long titles unusable at phone widths. */
.display,
.h1 {
  font-weight: 700;
  font-stretch: 125%;
  font-size: var(--display);
  line-height: 0.94;
  letter-spacing: -0.035em;
}

.display--lg {
  font-size: var(--display-lg);
  letter-spacing: -0.042em;
  line-height: 0.9;
}

/* Section headings — display voice, but a step down in pressure */
.h2 {
  font-weight: 700;
  font-stretch: 118%;
  font-size: var(--step-4);
  line-height: 0.96;
  letter-spacing: -0.028em;
}

/* Smaller headings revert to the supporting voice so the display face stays
   an event rather than the default. */
.h3 {
  font-family: var(--font-ui);
  font-weight: 600;
  font-stretch: 100%;
  font-size: var(--step-3);
  line-height: 1.16;
  letter-spacing: -0.017em;
}

/* Emphasis inside a display headline is a colour shift only — never an italic
   or a second face, so the composition stays art-directed and consistent.
   .page-hero__title is listed explicitly: it is a standalone display class, not
   one of the .h1-.h3 aliases, so without it the browser default italic leaks. */
.display em,
.h1 em,
.h2 em,
.h3 em,
.page-hero__title em,
.project__title em,
.person__name em {
  font-style: normal;
  color: var(--accent);
}

.lede {
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--muted);
  max-width: 46ch;
}

.prose {
  max-width: 62ch;
  font-size: var(--step-0);
  line-height: 1.68;
  color: var(--muted);
}

.prose p + p { margin-top: 1.1em; }
.prose strong { color: var(--fg); font-weight: 500; }

.prose--bright { color: var(--fg); }

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.kicker::before {
  content: "";
  width: 22px;
  height: 11px;
  border: 1px solid var(--accent);
  border-bottom: 0;
  border-radius: 22px 22px 0 0;
  flex: none;
  opacity: 0.9;
}

.kicker--accent { color: var(--accent); }

.eyebrow {
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}

.meta {
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  color: var(--muted);
}

.num {
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  color: var(--accent);
}

/* Pull statements stay in the supporting voice at a larger size — the
   quiet counterweight to the display headlines around them. */
.pull {
  font-family: var(--font-ui);
  font-size: var(--step-2);
  font-weight: 500;
  line-height: 1.34;
  letter-spacing: -0.014em;
  text-wrap: pretty;
  max-width: 38ch;
  color: var(--fg);
}

/* Editorial quote: hairline accent + generous measure */
.pull--accent {
  position: relative;
  max-width: 40ch;
  padding-left: clamp(1rem, 2vw, 1.75rem);
  border-left: 1px solid var(--accent);
  color: var(--fg);
}

/* Featured statement — the loudest voice inside a section body. Uses the
   display face so it reads as a deliberate typographic event rather than
   just larger body copy. */
.statement {
  position: relative;
  margin: clamp(2rem, 3.6vw, 3rem) 0 0;
  padding-top: clamp(1.5rem, 2.6vw, 2rem);
  border-top: 1px solid var(--line);
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 118%;
  font-size: clamp(1.35rem, 0.95rem + 1.9vw, 2.5rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
  text-wrap: balance;
  max-width: 26ch;
  color: var(--fg);
}

/* Concise editorial lead-in paragraph */
.prose--lead {
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--fg);
  max-width: 52ch;
}

/* Two-column running copy for longer editorial passages */
.prose-columns {
  columns: 2;
  column-gap: clamp(1.75rem, 3.5vw, 3.25rem);
  max-width: 78ch;
}
.prose-columns > p {
  break-inside: avoid;
  margin-bottom: 1.15em;
  color: var(--muted);
  max-width: 42ch;
}
.prose-columns > p:last-child { margin-bottom: 0; }
.prose-columns strong { color: var(--fg); font-weight: 500; }

/* Below tablet width, two columns leave each measure too narrow to read
   comfortably, so running copy collapses to a single column. */
@media (max-width: 780px) {
  .prose-columns { columns: 1; }
  .prose-columns > p { max-width: none; }
}

.small { font-size: var(--step--1); line-height: 1.6; color: var(--muted); }

.footnote {
  font-size: var(--step--2);
  line-height: 1.55;
  letter-spacing: 0.02em;
  color: var(--muted);
  border-left: 1px solid var(--line);
  padding-left: 0.9rem;
  max-width: 52ch;
}

/* 5. Components ----------------------------------------------------------- */
.kicker + .h2,
.kicker + .display,
.kicker + .h1 { margin-top: clamp(1.1rem, 2vw, 1.8rem); }

/* Section head: title left, supporting copy right */
.section-head {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: start;
  margin-bottom: clamp(2.5rem, 5vw, 5rem);
}

.section-head__title { grid-column: 1 / span 7; }
.section-head__aside {
  grid-column: 9 / -1;
  padding-top: 0.35rem;
}
.section-head__aside .lede { max-width: 40ch; }
.section-head--wide .section-head__title { grid-column: 1 / span 8; }
.section-head__aside > * + * { margin-top: 1.4rem; }

/* Headline-only section head (homepage Selected Projects) -------------------
   The aside copy was removed on purpose: the homepage already establishes
   approach and capabilities elsewhere, and the two-paragraph panel left a large
   empty gap under the headline before the first project. With no aside the
   grid still reserves the right-hand tracks, so the title keeps its natural
   7-column width and the bottom margin is reduced to a deliberate step rather
   than a spacer. */
.section-head--single { margin-bottom: clamp(1.5rem, 2.6vw, 2.25rem); }
.section-head--single .section-head__title { grid-column: 1 / span 8; }

/* Links */
.link-arrow {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding-bottom: 0.45rem;
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--fg);
  transition: color 0.4s var(--ease);
}

.link-arrow::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  opacity: 0.32;
  transition: background 0.4s var(--ease), opacity 0.4s var(--ease);
}

.link-arrow .arr { transition: transform 0.45s var(--ease); }

.link-arrow:hover { color: var(--accent); }
.section--dark .link-arrow:hover,
.section--charcoal .link-arrow:hover { color: var(--orange); }
.link-arrow:hover::after { background: var(--accent); opacity: 1; }
.link-arrow:hover .arr { transform: translateX(6px); }

/* Content CTAs — true pill shape, substantial weight.
   One shared system for the whole site: every content action uses .btn (primary,
   solid orange) or .btn--outline (secondary). Deliberately NOT applied to
   navigation, footer links, inline editorial links or LinkedIn profile links. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  min-height: 52px;
  max-width: 100%;
  padding: 0.95rem clamp(1.6rem, 2.4vw, 2.15rem);
  background: var(--orange);
  color: #141414;
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.085em;
  text-align: center;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--orange);
  border-radius: 999px;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease),
              color 0.3s var(--ease), transform 0.3s var(--ease);
}

/* Long labels (e.g. "Read the Deadline announcement") wrap onto a second line
   instead of forcing the pill wider than its column. Padding stays symmetric so
   a wrapped two-line pill keeps the same rounded silhouette. */
.btn .arr { flex: none; transition: transform 0.4s var(--ease); }
.btn:hover { background: #ff9134; border-color: #ff9134; }
.btn:hover .arr { transform: translateX(4px); }
.btn:active { transform: translateY(1px); }

/* Outlined variant — for light grounds and quieter invitations.
   Text inherits the section foreground so it inverts correctly. */
.btn--outline {
  background: transparent;
  color: var(--fg);
  border-color: color-mix(in srgb, var(--fg) 34%, transparent);
}
.btn--outline:hover {
  background: var(--orange);
  border-color: var(--orange);
  color: #141414;
}

/* On dark grounds the outline needs a touch more definition */
.section--dark .btn--outline,
.section--charcoal .btn--outline {
  border-color: rgba(247, 246, 243, 0.34);
}

/* Page heroes set no --fg (they use the paper foreground directly), so the
   outline variant resolves its colours explicitly here instead of relying on an
   undefined custom property. Guarantees legible contrast on the dark hero. */
.page-hero .btn--outline {
  color: var(--paper);
  border-color: rgba(247, 246, 243, 0.42);
}
.page-hero .btn--outline:hover {
  background: var(--orange);
  border-color: var(--orange);
  color: #141414;
}

.btn--ghost {
  background: transparent;
  color: var(--fg);
  border-color: var(--orange);
}
.btn--ghost:hover { background: rgba(255, 121, 0, 0.1); color: var(--fg); }

/* Pending-content marker (unreleased links / assets) */
.pending {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--step--2);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px dashed var(--line);
  padding: 0.4rem 0.6rem;
  border-radius: 1px;
}
.pending::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

/* Curved divider — the recurring brand motif */
.curve {
  position: relative;
  display: block;
  width: 100%;
  height: clamp(46px, 7vw, 110px);
  color: var(--accent, var(--orange));
  pointer-events: none;
}
.curve svg { width: 100%; height: 100%; display: block; overflow: visible; }
.curve path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: var(--dash, 2400);
  stroke-dashoffset: var(--dash, 2400);
  transition: stroke-dashoffset 2.4s var(--ease-out) 0.15s;
}
.curve.is-in path { stroke-dashoffset: 0; }
.curve--hair { opacity: 0.55; }

/* Divider riding the top edge of a section */
.section.has-curve { padding-top: calc(var(--section-y) + clamp(1.5rem, 3vw, 2.75rem)); }
.section > .curve--top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
  opacity: 0.85;
}
.section.has-curve > .container { position: relative; z-index: 2; }

/* Large composition arc used behind sections */
.arc {
  position: absolute;
  left: 50%;
  translate: -50% 0;
  width: min(2200px, 190vw);
  aspect-ratio: 1;
  border: 1px solid var(--line);
  border-radius: 50%;
  pointer-events: none;
  opacity: 0.75;
}
.arc--accent { border-color: color-mix(in srgb, var(--orange) 45%, transparent); opacity: 0.6; }
.arc--top { top: 0; translate: -50% -82%; }
.arc--bottom { bottom: 0; translate: -50% 82%; }

.rule {
  height: 1px;
  background: var(--line);
  border: 0;
  margin: 0;
}

/* Media placeholders ------------------------------------------------------- */
.ph {
  --ph-bg: #191919;
  --ph-ink: rgba(247, 246, 243, 0.62);
  --ph-line: rgba(247, 246, 243, 0.13);
  position: relative;
  display: block;
  aspect-ratio: var(--ratio, 16 / 9);
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 20% 0%, rgba(255, 255, 255, 0.06), transparent 60%),
    var(--ph-bg);
  border: 1px solid var(--ph-line);
  color: var(--ph-ink);
  isolation: isolate;
}

.ph::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    135deg,
    var(--ph-line) 0 1px,
    transparent 1px 11px
  );
  opacity: 0.5;
}

.ph::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 45%, rgba(0, 0, 0, 0.5));
  opacity: 0.85;
}

.ph__label {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.35rem 1rem;
  padding: clamp(0.8rem, 1.4vw, 1.15rem);
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.4;
}

.ph__label span:first-child {
  color: var(--orange);
  font-weight: 600;
}

.ph__tag {
  position: absolute;
  z-index: 2;
  top: clamp(0.8rem, 1.4vw, 1.15rem);
  right: clamp(0.8rem, 1.4vw, 1.15rem);
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  padding: 0.25rem 0.5rem;
  opacity: 0.75;
}

.ph__mark {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: 0.5;
}
.ph__mark svg { width: clamp(48px, 8vw, 86px); height: auto; }

/* Delivered key art ------------------------------------------------------
   Real artwork is shown as supplied: no filters, no colour treatment, no
   decorative overlay. The frame ratio comes from the same `--ratio` custom
   property the `.ph` placeholders use, so a real image and a placeholder can
   occupy an identical box. Defaults to 16:9 for the project-page hero. */
.keyart {
  position: relative;
  display: block;
  aspect-ratio: var(--ratio, 16 / 9);
  overflow: hidden;
  background: #0d1018;
  /* Colour is deliberately inherited, not set: the "In development" badge uses
     `.ph__tag` with currentColor, so it reads dark on a light section and light
     inside the dark project hero. */
}
.keyart img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform 1s var(--ease-out);
}
.project__media:hover .keyart img { transform: scale(1.012); }

.keyart__tag {
  position: absolute;
  z-index: 2;
  top: clamp(0.8rem, 1.4vw, 1.15rem);
  right: clamp(0.8rem, 1.4vw, 1.15rem);
  padding: 0.25rem 0.5rem;
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper);
  background: rgba(10, 10, 10, 0.42);
  border: 1px solid rgba(247, 246, 243, 0.42);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}

/* Project-page hero: the section's own bottom padding is suppressed inline so
   the artwork closes the hero; this keeps it off the following section edge. */
.keyart--hero { margin-bottom: clamp(1.5rem, 4vw, 3.5rem); }

/* Project-specific tones — each IP keeps its own atmosphere */
.ph--cinema {
  --ph-bg: #16100f;
  background:
    radial-gradient(90% 70% at 75% 15%, rgba(255, 121, 0, 0.18), transparent 62%),
    radial-gradient(90% 80% at 10% 100%, rgba(120, 20, 30, 0.35), transparent 60%),
    #16100f;
}

.ph--ninja {
  --ph-bg: #e9e3d7;
  --ph-ink: rgba(23, 23, 23, 0.6);
  --ph-line: rgba(23, 23, 23, 0.14);
  background:
    radial-gradient(100% 80% at 20% 0%, rgba(255, 255, 255, 0.7), transparent 60%),
    radial-gradient(90% 90% at 90% 100%, rgba(23, 23, 23, 0.14), transparent 55%),
    #e9e3d7;
}
.ph--ninja::after { background: linear-gradient(180deg, transparent 55%, rgba(23, 23, 23, 0.22)); }
.ph--ninja .ph__label span:first-child { color: var(--orange-ink); }

.ph--game {
  --ph-bg: #14171c;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.07) 1px, transparent 1px),
    radial-gradient(80% 60% at 50% 120%, rgba(255, 121, 0, 0.16), transparent 60%);
  background-size: 46px 46px, 46px 46px, 100% 100%;
  background-color: #14171c;
}
.ph--game::before { opacity: 0.18; }

.ph--portrait { --ratio: 4 / 5; }
.ph--portrait::after { background: linear-gradient(180deg, transparent 40%, rgba(0, 0, 0, 0.62)); }

.ph--portrait.ph--paper {
  --ph-bg: #e4e0d7;
  --ph-ink: rgba(23, 23, 23, 0.62);
  --ph-line: rgba(23, 23, 23, 0.13);
  background: radial-gradient(90% 70% at 30% 10%, rgba(255, 255, 255, 0.75), transparent 60%), #e4e0d7;
}
.ph--portrait.ph--paper::after { background: linear-gradient(180deg, transparent 45%, rgba(23, 23, 23, 0.3)); }
.ph--portrait.ph--paper .ph__label span:first-child { color: var(--orange-ink); }

/* 6. Project treatments --------------------------------------------------- */
.project {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem);
  align-items: end;
}

.project__media {
  grid-column: 1 / span 7;
  display: block;
  text-decoration: none;
  position: relative;
}
.project__media .ph { transition: transform 0.9s var(--ease-out), border-color 0.5s var(--ease); }
.project__media:hover .ph { transform: scale(1.012); }

.project__body { grid-column: 8 / -1; padding-bottom: 0.4rem; }
.project__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem 0.85rem;
  font-size: var(--step--2);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.project__meta .dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}
.project__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 125%;
  font-size: clamp(1.5rem, 1rem + 1.75vw, 2.75rem);
  line-height: 0.98;
  letter-spacing: -0.032em;
  margin: 1rem 0 1.15rem;
  text-wrap: balance;
}
.project__title a { text-decoration: none; }
.project__title a:hover { color: var(--accent); }
.project__body .prose { max-width: 42ch; }
.project__body > .link-arrow { margin-top: 1.8rem; }

/* Mirrored project row (media right, copy left).

   BUG FIXED HERE: this rule used to move only the media, to `6 / -1`, while
   `.project__body` stayed at its default `8 / -1`. Both then occupied columns
   8-12, and because `.project__media` is `position: relative` it painted over
   the `position: static` body — so the copy was rendered but invisible
   underneath the image. It only looked fine below 780px, where the collapsed
   layout puts both on their own rows (`grid-row: auto`).

   A flip must move BOTH columns. The body now takes 1 / span 5, the mirror of
   the media's 6 / -1, so the two can never share a track again. */
.project--flip .project__media { grid-column: 6 / -1; }
.project--flip .project__body { grid-column: 1 / span 5; }
.project__media { grid-row: 1; }
.project__body { grid-row: 1; }
/* NOTE: every homepage project row uses this exact structure — plain `.project`,
   a `.project__media` on 7 columns, copy from column 8, and one `<hr class="rule">`
   above the row. There is deliberately no `.project--lead`, `.project--thumb` or
   `.keyart--thumb` override: those earlier modifiers forced `grid-column: 1 / -1`,
   a different title size or a smaller frame on a single row, which is exactly what
   made Lollipop Chainsaw stop matching Ninja Throne. Do not reintroduce them —
   add a modifier to the shared component and apply it to every row instead. */
.project__media--tall .ph { --ratio: 5 / 4; }

.project-index {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.project-index li {
  flex: 1 1 200px;
  border-left: 1px solid var(--line);
}
.project-index li:first-child { border-left: 0; }
.project-index a {
  display: block;
  padding: 1.15rem clamp(0.9rem, 1.6vw, 1.5rem);
  text-decoration: none;
  transition: background 0.4s var(--ease), color 0.4s var(--ease);
}
.project-index a:hover { background: rgba(255, 121, 0, 0.1); }
.project-index .pi-title {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 112%;
  font-size: clamp(0.95rem, 0.9rem + 0.3vw, 1.1rem);
  line-height: 1.2;
  letter-spacing: -0.018em;
}
.project-index .pi-meta {
  display: block;
  margin-top: 0.35rem;
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.project-index a:hover .pi-meta { color: var(--accent); }

/* 7. Sections ------------------------------------------------------------- */
/* Hero ------------------------------------------------------------------- */
.hero {
  --accent: var(--orange);
  --line: rgba(247, 246, 243, 0.16);
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100svh;
  padding-top: clamp(7rem, 14vh, 11rem);
  padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
  background: var(--ink-deep);
  color: var(--paper);
  overflow: clip;
}

.hero::before { /* warm floor glow, very restrained */
  content: "";
  position: absolute;
  inset: auto 0 -30% 0;
  height: 70%;
  background: radial-gradient(60% 100% at 50% 100%, rgba(255, 121, 0, 0.14), transparent 72%);
  pointer-events: none;
}

.hero__inner { position: relative; z-index: 2; display: flex; flex-direction: column; gap: clamp(2rem, 4.5vw, 3.5rem); flex: 1; justify-content: center; }

/* Company descriptor — two stacked lines above the headline. The first names
   the company, the second lists its disciplines in a quieter tone so the
   hierarchy reads at a glance. */
.hero__topline {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
  font-size: var(--step--2);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(247, 246, 243, 0.72);
}
.hero__disciplines {
  color: rgba(247, 246, 243, 0.48);
  letter-spacing: 0.14em;
}
.hero__topline .accent { color: var(--orange); }

/* The display face is far wider per glyph, so the hero measure is generous
   but bounded — keeps the three-line composition intact at desktop widths. */
.hero__title { max-width: 26ch; }
.hero__title .line { display: block; }

.hero__foot {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) auto;
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: end;
  padding-top: clamp(1.5rem, 3vw, 2.5rem);
  border-top: 1px solid rgba(247, 246, 243, 0.16);
}
.hero__foot .prose { color: #bdb8b1; max-width: 62ch; }
.hero__lede { font-size: var(--step-0); line-height: 1.66; }
.hero__cta { justify-self: end; }

/* Hero orbit composition — the identity, drawn */
.hero__orbit {
  position: absolute;
  z-index: 1;
  top: clamp(6rem, 12vh, 9rem);
  right: calc(var(--gutter) * -0.15);
  width: clamp(280px, 34vw, 500px);
  aspect-ratio: 1;
  pointer-events: none;
  opacity: 0.85;
}
.hero__orbit svg { width: 100%; height: 100%; overflow: visible; }
.orbit__ring { fill: none; stroke: rgba(247, 246, 243, 0.16); stroke-width: 1; }
.orbit__ring--accent { stroke: rgba(255, 121, 0, 0.55); }
.orbit__tick { stroke: rgba(247, 246, 243, 0.12); stroke-width: 1; }
.orbit__mark { fill: var(--orange); }
.orbit__spin { transform-origin: 200px 200px; animation: spin 160s linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } }

.hero__index { position: relative; z-index: 2; margin-top: clamp(2rem, 4vw, 3rem); }

/* Page hero (interior pages) ---------------------------------------------- */
.page-hero {
  --accent: var(--orange);
  --line: rgba(247, 246, 243, 0.16);
  position: relative;
  padding-top: clamp(8rem, 17vh, 12rem);
  padding-bottom: clamp(3rem, 6vw, 5.5rem);
  background: var(--ink-deep);
  color: var(--paper);
  overflow: clip;
}

/* Light page hero (used where a project carries its own pale palette) */
.page-hero--light {
  --accent: var(--orange-ink);
  --line: rgba(23, 23, 23, 0.14);
  background: #efeade;
  color: var(--ink);
}
.page-hero .arc { opacity: 0.5; }
.page-hero__inner { position: relative; z-index: 2; }

/* Compact hero variant ------------------------------------------------
   Short-copy pages (About, Contact) carry a single sentence where the other
   interiors carry two paragraphs, so the default hero heights leave the
   section looking under-filled. Padding is reduced by exactly 20% on both
   edges rather than replaced with fixed values, so the proportional rhythm
   established by the default hero is preserved at every viewport width.
   The intro copy is also pulled closer to its headline (see below), since a
   one-sentence lede does not need the breathing room of a two-paragraph one.
   Note: `.page-hero` deliberately sets no `min-height`; the only min-height
   in the hero system belongs to the homepage `.hero`, so there is no
   dead-space floor to remove here. */
.page-hero--compact {
  padding-top: clamp(6.4rem, 13.6vh, 9.6rem);
  padding-bottom: clamp(2.4rem, 4.8vw, 4.4rem);
}
.page-hero--compact .page-hero__lede { margin-top: clamp(1.1rem, 2vw, 1.6rem); }
.page-hero__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 125%;
  font-size: clamp(1.95rem, 0.85rem + 4.3vw, 4.6rem);
  line-height: 0.95;
  letter-spacing: -0.035em;
  margin: clamp(1.2rem, 2.4vw, 2rem) 0 0;
  max-width: 20ch;
  text-wrap: balance;
}
.page-hero__lede {
  margin-top: clamp(1.5rem, 3vw, 2.4rem);
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.2rem, 3vw, 2.5rem);
  align-items: start;
}
.page-hero__lede .prose { grid-column: 1 / span 5; color: #c6c1ba; }
.page-hero__lede .prose--aside { grid-column: 7 / span 3; font-size: var(--step--1); }

/* Hero introduction --------------------------------------------------------
   One cohesive left-aligned text block, replacing the old prose + aside pair
   that put supporting copy in a second column on the right. The block spans
   the full grid and is capped by `max-width` instead of a column span: a span
   silently narrows at intermediate widths (it was 456px at 1024px, well under
   the intended measure), whereas a cap holds the requested measure and lets
   the text reflow naturally below it. */
.page-hero__lede .page-hero__intro {
  grid-column: 1 / -1;
  max-width: 700px;
}

/* Wider variant (About). A single long paragraph reads better on a longer
   line than the standard two-paragraph hero measure. */
.page-hero__lede .page-hero__intro--wide { max-width: 800px; }

/* Paragraph rhythm inside the block: ~20–24px between paragraphs. */
.page-hero__lede .page-hero__intro p + p {
  margin-top: clamp(1.25rem, 1.2vw, 1.5rem);
}

/* Deliberate two-line hero composition (Film & Television).
   The title breaks after "The best stories" so the orange second half reads as
   its own line. `max-width` is relaxed from the default 20ch because the second
   line is 25 characters and would otherwise wrap again into a third line. At
   phone widths the span reverts to inline and the headline wraps naturally,
   which is why this is not a hard `<br>`. */
.page-hero__title--two-line { max-width: 26ch; }
.page-hero__line { display: block; }

@media (max-width: 640px) {
  .page-hero__title--two-line { max-width: 20ch; }
  .page-hero__line { display: inline; }
}

/* Hero content CTA. These slots used to hold small underlined text links, which
   fitted a two-column track. A pill label is far wider, so a 2-column track
   forced the text onto two lines (measured 69px tall instead of the 52px
   baseline). The button now takes its own full-width row and stays right
   aligned, preserving the original bottom-right position of the hero while
   guaranteeing a single-line, uniform-height pill on every page. */
.page-hero__lede .page-hero__cta {
  grid-column: 1 / -1;
  justify-self: end;
  align-self: end;
  margin-top: clamp(0.4rem, 1.2vw, 0.9rem);
}

.page-hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: center;
  font-size: var(--step--2);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(247, 246, 243, 0.62);
}
.page-hero__meta .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--orange); }

/* Editorial split: label column + content column --------------------------- */
.split {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: start;
}
.split__label { grid-column: 1 / span 3; position: sticky; top: 7rem; }
.split__body { grid-column: 5 / -1; }
.split__body .h2 { max-width: 24ch; }
.split__body > * + * { margin-top: clamp(1.25rem, 2.4vw, 2rem); }
.split--wide .split__body { grid-column: 4 / -1; }

/* Approach section — balanced editorial two columns ------------------------
   Left ~40%: the section label, then the headline. Right ~60%: one continuous
   copy column. This replaces the old `.split` arrangement on this section,
   which parked a lone kicker in columns 1–3 and pushed everything else to
   column 5 — leaving an empty track between them (the dead gap) and pushing the
   headline far to the right of its own label.

   Alignment: the headline and the body copy are both placed in grid row 2, so
   their tops coincide exactly and the two main columns open on one line. The
   label occupies row 1 alone, and the row gap supplies the spacing beneath it.
   An earlier attempt put the body in `grid-row: 1 / span 2` instead; a spanning
   item splits its height across the rows it covers, which pushed the headline
   ~170px below the copy. Do not reintroduce a span here. */
.approach {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.1rem, 2vw, 1.8rem) clamp(1.5rem, 3vw, 2.5rem);
  align-items: start;
}

.approach__label {
  grid-column: 1 / span 5;
  grid-row: 1;
}

.approach .approach__title {
  grid-column: 1 / span 5;
  grid-row: 2;
  max-width: 16ch;
  /* The global `.kicker + .h2` rule adds a top margin for the usual stacked
     label-then-heading pattern, and at (0,2,0) it outranks a plain class
     selector. Here the label is in its own grid row and the grid's row-gap
     already spaces it, so that margin would push the headline 25px below the
     first line of the copy and break the two-column alignment. The extra
     `.approach` prefix exists purely to win that specificity contest with a
     rule that is correct for the site's other sections. */
  margin-top: 0;
}

.approach__body {
  grid-column: 6 / -1;
  grid-row: 2;
  max-width: 62ch;
}
.approach__body > p + p { margin-top: 1.15em; }
/* Running copy keeps the site's muted body colour (it was inherited from
   `.prose-columns` before the rebuild). */
.approach__body p { color: var(--muted); line-height: 1.68; }

/* Mobile / narrow tablet: label, headline and paragraphs stack in that order. */
@media (max-width: 900px) {
  .approach { gap: 0; }
  .approach__label,
  .approach__title,
  .approach__body {
    grid-column: 1 / -1;
    grid-row: auto;
    max-width: none;
  }
  .approach__title { margin-top: clamp(1rem, 2.5vw, 1.5rem); }
  .approach__body { margin-top: clamp(1.4rem, 3vw, 2rem); }
}

.split-head {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: end;
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
}
.split-head > .h2 { grid-column: 1 / span 7; }
.split-head > .prose { grid-column: 9 / -1; padding-bottom: 0.4rem; }

/* Row list — activities, engagement models -------------------------------- */
.rows { border-top: 1px solid var(--line); }
.row {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 2.5rem);
  padding-block: clamp(1.6rem, 3.2vw, 2.6rem);
  border-bottom: 1px solid var(--line);
  align-items: start;
  position: relative;
}
.row__num { grid-column: 1 / span 1; padding-top: 0.35rem; }
.row__title { grid-column: 2 / span 4; }
.row__title .h3 { font-size: clamp(1.5rem, 1.1rem + 1.3vw, 2.2rem); }
.row__title a { text-decoration: none; }
.row__title a:hover { color: var(--accent); }
.row__body { grid-column: 7 / -1; }
.row__body .prose { max-width: 52ch; color: var(--muted); }
.row__body > .link-arrow,
.row__body > .row__action { margin-top: 1.25rem; }
.row__aside { grid-column: 7 / -1; display: flex; flex-wrap: wrap; gap: 1rem 2rem; align-items: baseline; }

.row:hover .num { color: var(--orange); }

/* Numbered article blocks (strategy) ------------------------------------- */
.articles { border-top: 1px solid var(--line); }
.article {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
  padding-block: clamp(2.25rem, 4.5vw, 4rem);
  border-bottom: 1px solid var(--line);
  align-items: start;
}
.article__head { grid-column: 1 / span 5; position: sticky; top: 7rem; }
.article__head .num { display: block; margin-bottom: 0.9rem; }
.article__head .h3 { font-size: clamp(1.5rem, 1.1rem + 1.5vw, 2.4rem); max-width: 20ch; }
.article__body { grid-column: 7 / -1; }
.article__body > * + * { margin-top: 1.15em; }
.article__body .prose { max-width: 58ch; }

/* Founders --------------------------------------------------------------- */
.people {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.person { grid-column: span 6; }

/* Homepage founder cards are flex columns so the profile links settle on a
   shared baseline even when the two bios differ in length. Scoped to .people
   so the About page's wide founder layout is untouched. */
.people .person {
  display: flex;
  flex-direction: column;
}
.people .person__links { margin-top: auto; padding-top: 1.1rem; }
.person__media { margin-bottom: clamp(1.1rem, 2vw, 1.6rem); overflow: hidden; }
.person__media .ph { transition: transform 1s var(--ease-out); }
.person:hover .person__media .ph { transform: scale(1.015); }

/* Supplied founder photography -------------------------------------------
   The approved files are 717x1024 (5:7) and the portrait slot is 4:5, so
   `cover` matches the width exactly and takes its surplus from the vertical
   axis only — nothing is stretched, squashed or resampled into a different
   shape. Anchoring to the top edge means no part of the head or hair can ever
   be cropped; the discarded area is the lower chest, the least significant part
   of a headshot. No filters, borders, overlays or decorative grounds. */
.person__photo {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}
.person__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  transition: transform 1s var(--ease-out);
}
/* Mirrors the placeholder's hover behaviour so the two pages stay consistent */
.person:hover .person__photo img { transform: scale(1.015); }
.person__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 120%;
  font-size: clamp(1.3rem, 1.05rem + 0.95vw, 1.9rem);
  line-height: 1.02;
  letter-spacing: -0.028em;
}
.person__role {
  margin-top: 0.5rem;
  font-size: var(--step--2);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.person__copy { margin-top: 1rem; color: var(--muted); max-width: 44ch; }

/* Discreet external profile links on founder profiles */
.person__links {
  margin-top: 1.1rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.6rem;
  align-items: center;
}
.chip-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.42rem 0.85rem;
  min-height: 34px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.05em;
  text-decoration: none;
  color: var(--fg);
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease),
              background 0.3s var(--ease);
}
.chip-link span[aria-hidden] {
  font-size: 0.95em;
  opacity: 0.7;
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.chip-link:hover {
  border-color: var(--orange);
  color: var(--accent);
}
.chip-link:hover span[aria-hidden] { transform: translate(2px, -2px); opacity: 1; }

/* Franchise format badges ------------------------------------------------
   A single horizontal row naming the formats a property operates in. These are
   informational, not calls to action: no hover state, no pointer cursor and no
   link semantics, so they can never be mistaken for clickable the way a pill
   button would be. They borrow the chip's pill silhouette and typography
   (uppercase, tracking, --step--2) so the language matches the rest of the
   site, but keep a hairline muted border and muted text.

   `flex-wrap` handles mobile: the labels are short enough to sit on one line at
   desktop and wrap naturally to two on a phone without any media query. */
.formats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.6rem;
  margin-top: clamp(1.35rem, 2.4vw, 1.85rem);
  padding: 0;
  list-style: none;
}
.formats li {
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--font-ui);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.14em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--muted);
  /* Never a pointer: these are labels, not controls. */
  cursor: default;
}

/* Founder closing statement -------------------------------------------------
   The conclusion to the founder section. It previously reused `.split`, which
   parked the copy in a right-hand content column and left the left half of the
   section empty — the copy read as two columns floating in space rather than a
   deliberate close.

   It now sits directly below the founder grid, starting on the SAME left edge
   as Robert's profile (the container edge, which is where `.people` starts), and
   is capped at a comfortable editorial measure so the lines stay readable and the
   block never stretches into the dead space on the right.

   The lead paragraph carries slightly more weight than the closing one via size
   and colour only — no new font, no oversized headline, no italics. */
.people__closing {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  max-width: 46rem; /* ~736px — inside the 700–800px brief */
}

.people__closing p {
  color: var(--muted);
  line-height: 1.62;
}

/* Lead: a step up in size and full foreground colour, so it reads as the
   statement the second paragraph then qualifies. Specificity is deliberately
   `.people__closing .people__closing-lead` (0,2,0): the generic
   `.people__closing p` muted rule above would otherwise win and flatten both
   paragraphs back to the same quiet colour. */
.people__closing .people__closing-lead {
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--fg);
  letter-spacing: -0.006em;
  text-wrap: pretty;
}

.people__closing > p + p { margin-top: clamp(1rem, 1.8vw, 1.4rem); }

/* The CTA hangs directly off the text block, aligned to its left edge. */
.people__closing-cta { margin-top: clamp(1.6rem, 2.8vw, 2.25rem); }

.person--wide {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  padding-block: clamp(2.25rem, 4vw, 3.5rem);
  border-top: 1px solid var(--line);
  align-items: start;
}
.person--wide .person__media { grid-column: 1 / span 4; margin-bottom: 0; }
.person--wide .person__info { grid-column: 6 / -1; }
.person__info > * + * { margin-top: 1.1rem; }
/* Long-form biography paragraphs sit a touch brighter than default muted copy
   so the wide founder layout stays comfortable over 5-6 paragraphs. */
.person__info .prose { color: #bdb8b1; }

/* Selected credits — set apart from the running biography as its own small
   editorial panel rather than an inline list. */
.person__credits-block {
  padding-top: clamp(0.9rem, 1.5vw, 1.15rem);
  border-top: 1px solid var(--line);
  max-width: 42ch;
}
.person__credits-block .eyebrow { margin-bottom: 0.7rem; }
.person__credits {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.6rem;
  font-size: var(--step--1);
  color: var(--fg);
}
.person__credits li {
  border: 1px solid var(--line);
  padding: 0.3rem 0.65rem;
  border-radius: 1px;
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.01em;
}

/* Definition list (project facts) ---------------------------------------- */
.spec {
  border-top: 1px solid var(--line);
}
.spec__row {
  display: grid;
  grid-template-columns: minmax(140px, 1fr) 2fr;
  gap: 1rem 2rem;
  padding-block: 0.95rem;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.spec__key {
  font-size: var(--step--2);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);
}
.spec__val { font-size: var(--step-0); line-height: 1.55; }
.section--dark .split__label .kicker,
.section--charcoal .split__label .kicker { color: var(--muted); }

/* Feature panel (dark IP block) ------------------------------------------ */
.feature {
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: center;
}
.feature__media { grid-column: 1 / span 7; }
.feature__body { grid-column: 8 / -1; }
.feature--flip .feature__media { grid-column: 6 / -1; }
.feature--flip .feature__body { grid-column: 1 / span 4; grid-row: 1; }
.feature__body > * + * { margin-top: 1.15rem; }

/* Featured project with delivered key art ---------------------------------
   The approved Lollipop Chainsaw asset is only 681x383, so it is paired with
   the production details in a 6/6 split rather than stretched across the full
   container. Six of twelve columns is ~632px at the 1440px max width, i.e.
   always *smaller* than the source, so the image is never upscaled and its
   resolution never becomes the thing you notice.

   The 16:9 `--ratio` matches the source exactly, so `object-fit: cover` crops
   nothing at all — no black bars, no distortion, no aggressive reframing, and
   Juliet and her chainsaw stay entirely in frame. (The old 21:9 slot was wider
   than the artwork could ever fill; it is the reason the real image had to be
   letterboxed or heavily cropped.)

   The artwork's ~355px height lands close to the ~320px of the six-row spec
   table beside it, so the two columns read as deliberately balanced. */
.feature--proj {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: start;
}
.proj-art { grid-column: 1 / span 6; margin: 0; }
/* The source is only 681px wide, so the frame is capped there: between roughly
   780px and 1000px the stacked layout would otherwise stretch it wider than the
   file and make its low resolution visible. Below the cap it scales down only. */
.proj-art .keyart { max-width: 681px; }
.proj-spec { grid-column: 7 / -1; }

/* Running copy sits below the artwork/details pair, at a readable measure. */
.proj-copy { max-width: 62ch; margin-top: clamp(2rem, 4vw, 3rem); }
.proj-copy > * + * { margin-top: 1.15rem; }
.proj-copy .eyebrow { margin-bottom: 0.75rem; }

/* Callout / announcement ------------------------------------------------ */
.announce {
  position: relative;
  border: 1px solid var(--line);
  padding: clamp(1.6rem, 4vw, 3.25rem);
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: end;
  background: linear-gradient(140deg, rgba(255, 121, 0, 0.07), transparent 55%);
  overflow: hidden;
}
.announce::after {
  content: "";
  position: absolute;
  right: -12%;
  top: -55%;
  width: 60%;
  aspect-ratio: 1;
  border: 1px solid rgba(255, 121, 0, 0.4);
  border-radius: 50%;
  pointer-events: none;
}
.announce__body { grid-column: 1 / span 7; position: relative; z-index: 1; }
.announce__date { grid-column: 9 / -1; position: relative; z-index: 1; text-align: right; }
.announce__date .big {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 125%;
  font-size: clamp(1.6rem, 1.15rem + 1.5vw, 2.5rem);
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--accent);
}

/* CTA block ------------------------------------------------------------- */
.cta {
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: end;
}
.cta__title { grid-column: 1 / span 7; }
/* 5 columns, not 3. These slots previously held small text links; a pill label
   is much wider and wrapped onto two lines in a 3-column track (measured 67-68px
   tall vs the 52px baseline). */
.cta__links { grid-column: 8 / -1; display: flex; flex-direction: column; gap: 1rem; align-items: flex-start; }

/* Contact directory ------------------------------------------------------
   Direct Contact (Contact page) is an editorial directory of two horizontal
   rows, not a pair of parallel columns. Each row is a small uppercase label
   against a large email address, so the addresses carry the section instead
   of floating in distant columns with a void between them.

   Earlier arrangements and why they were abandoned:
   - a three-column `.contact-panel` gave each address 4 of 12 tracks, which
     was narrower than `productions@orangechariot.com` itself, so the only way
     to fit was hyphenating the domain via `overflow-wrap: anywhere`;
   - two wide parallel columns then fixed the clipping but left the addresses
     small and disconnected, reading as an unfinished section.

   The row layout solves both: the addresses get ~70% of the measure at a
   display size, and the paired label keeps them anchored.

   `align-items: baseline` is what makes the row read as one line of type —
   the label's baseline sits on the address's baseline rather than being
   vertically centred against a much taller line box. */

/* ~30% less vertical padding than a default section on both edges, counting
   the extra `.has-curve` top offset the orange transition adds. Specificity
   is (0,2,0) to match `.section.has-curve` and this rule comes later, so it
   wins the padding-top without touching the shared section tokens. */
.section.section--direct {
  padding-top: calc(var(--section-y) * 0.7 + clamp(1.05rem, 2.1vw, 1.93rem));
  padding-bottom: max(3rem, calc(var(--section-y) * 0.7));
}

.direct-contact .kicker { margin-bottom: 0; }

.direct-contact__rows {
  margin-top: clamp(1.15rem, 2vw, 1.6rem);
  border-top: 1px solid var(--line);
}

.direct-contact__row {
  display: grid;
  grid-template-columns: 30% minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 3rem);
  align-items: baseline;
  padding-block: clamp(1.35rem, 2.6vw, 2.1rem);
  border-bottom: 1px solid var(--line);
}

.direct-contact__row .contact-label {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.16em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--muted);
}

.direct-contact__row a {
  font-family: var(--font-ui);
  /* ~20px on a phone through ~30-34px on a wide desktop. The upper bound is
     capped at 34px and the whole ramp is width-driven, so the longest
     address (~28 characters) still occupies a single line in its ~70%
     column at every width. */
  font-size: clamp(1.25rem, 0.9rem + 1.55vw, 2.125rem);
  font-weight: 500;
  letter-spacing: -0.022em;
  line-height: 1.2;
  text-decoration: none;
  color: var(--fg);
  /* A hairline under the address, not a button: it signals the link without
     turning the address into a filled or outlined pill. */
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.06em;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
  /* An address is one token. Sizes above are chosen so it never needs to
     break, and this guarantees it cannot hyphenate mid-domain instead. */
  white-space: nowrap;
  display: inline-block;
  max-width: 100%;
}
.direct-contact__row a:hover,
.direct-contact__row a:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
}

/* Secondary channel — LinkedIn CTA.
   Reuses the shared `.btn .btn--outline` pill so the channel speaks the site's
   established CTA language instead of reading as a leftover text link. Two
   deliberate scoped differences from the shared variant, both to keep it
   SECONDARY to the email addresses above it:

   1. The rule is charcoal at ~42% rather than the shared 34%, and the pill
      carries slightly more horizontal padding, so it has real visual weight
      without out-shouting the addresses.
   2. Hover/focus shifts border + text to orange on the transparent ground.
      The shared `.btn--outline:hover` fills solid orange, which would make
      LinkedIn the loudest element on the page and read as a primary button —
      explicitly not wanted here.

   It occupies column 2 of the row grid so it starts on the address column's
   left edge, stays content-width via `justify-self: start`, and has no
   trailing margin so no dead space is left above the footer. */
.direct-contact__elsewhere {
  display: grid;
  grid-template-columns: 30% minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 3rem);
  /* 24–32px of separation from the email rows. */
  margin-top: clamp(1.5rem, 2.4vw, 2rem);
  margin-bottom: 0;
}

.direct-contact__elsewhere .btn {
  grid-column: 2;
  justify-self: start;
  width: auto;
  padding-inline: clamp(1.85rem, 2.8vw, 2.6rem);
  border-color: color-mix(in srgb, var(--fg) 42%, transparent);
}

.direct-contact__elsewhere .btn:hover,
.direct-contact__elsewhere .btn:focus-visible {
  background: transparent;
  border-color: var(--accent);
  color: var(--accent);
}

/* Focus must stay unmistakable on the light ground: the global rule already
   paints a 2px orange outline with a 4px offset, which clears WCAG non-text
   contrast against the off-white. Declared here so a future hover tweak
   cannot quietly drop it. */
.direct-contact__elsewhere .btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* 8. Header, nav, footer -------------------------------------------------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 120;
  color: var(--paper);
  transition: background 0.45s var(--ease), backdrop-filter 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.site-header::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 1px;
  background: rgba(247, 246, 243, 0.14);
  opacity: 0;
  transition: opacity 0.45s var(--ease);
}
.site-header.is-scrolled {
  background: rgba(12, 12, 12, 0.88);
  backdrop-filter: blur(16px) saturate(130%);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
}
.site-header.is-scrolled::after { opacity: 1; }

/* Light-hero override: pages that open on a light palette need dark chrome
   until the header becomes a solid bar on scroll. */
.site-header--light:not(.is-scrolled) {
  color: var(--ink);
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.site-header--light:not(.is-scrolled) .nav__link { color: rgba(23, 23, 23, 0.7); }
.site-header--light:not(.is-scrolled) .nav__link:hover,
.site-header--light:not(.is-scrolled) .nav__link:focus-visible,
.site-header--light:not(.is-scrolled) .nav__link[aria-current="page"] { color: var(--ink); }
.site-header--light:not(.is-scrolled) .nav-toggle { color: var(--ink); }
.site-header--light:not(.is-scrolled)::after { background: rgba(23, 23, 23, 0.12); opacity: 1; }
/* Scrolled state on a light-hero page keeps the solid dark bar */
.site-header--light.is-scrolled { color: var(--paper); }

/* The header sits above the mobile drawer, so an open drawer covers the page
   with a dark panel. On a light-hero page the dark wordmark would then sit on
   near-black and disappear, so force the dark-ground treatment while locked. */
body.is-locked .site-header--light .logo__img--white { display: block; }
body.is-locked .site-header--light .logo__img--dark { display: none; }
body.is-locked .site-header--light .nav__link { color: rgba(247, 246, 243, 0.72); }
body.is-locked .site-header--light .nav__link:hover,
body.is-locked .site-header--light .nav__link:focus-visible { color: var(--paper); }
body.is-locked .site-header--light .nav-toggle { color: var(--paper); }
body.is-locked .site-header--light::after { background: rgba(247, 246, 243, 0.14); }

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: clamp(0.85rem, 1.6vw, 1.15rem);
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: inherit;
  flex: none;
}

/* Official lockup. Only the height is set and width follows the intrinsic
   ratio, because the supplied white and dark files are not identical ratios
   (1024x178 vs 1000x180). Setting both dimensions would distort the logo.

   Sized for stronger brand presence (+30% vs the original 19-23px band), while
   staying clearly subordinate to the navigation: the nav sits at --step--1, so
   the wordmark reads as the anchor without competing for attention. The mobile
   floor rises proportionally but the upper bound is deliberately tighter so the
   logo cannot crowd the menu toggle on a narrow screen. */
.logo__img {
  display: block;
  width: auto;
  height: clamp(25px, 2.02vw, 30px);
  max-width: none;
}

/* Default: white wordmark, for dark grounds (heroes, scrolled bar). */
.logo__img--white { display: block; }
/* Dark wordmark, revealed only over a light hero. */
.logo__img--dark { display: none; }

.site-header--light:not(.is-scrolled) .logo__img--white { display: none; }
.site-header--light:not(.is-scrolled) .logo__img--dark { display: block; }

.nav { display: flex; align-items: center; gap: clamp(1rem, 2vw, 1.9rem); }
.nav__link {
  position: relative;
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  text-decoration: none;
  color: rgba(247, 246, 243, 0.72);
  padding-block: 0.35rem;
  transition: color 0.35s var(--ease);
  white-space: nowrap;
}
.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s var(--ease);
}
.nav__link:hover { color: var(--paper); }
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { color: var(--paper); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.7rem;
  background: none;
  border: 0;
  padding: 0.5rem 0;
  cursor: pointer;
  font-size: var(--step--2);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--paper);
}
.nav-toggle__bars {
  display: block;
  width: 24px;
  position: relative;
}
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 24px;
  height: 1px;
  background: currentColor;
  transition: transform 0.4s var(--ease), opacity 0.3s var(--ease), top 0.4s var(--ease);
}
.nav-toggle__bars::before { top: -4px; }
.nav-toggle__bars::after { top: 4px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after { top: 0; transform: rotate(-45deg); }

/* Mobile drawer */
.nav-drawer {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: #0d0d0d;
  color: var(--paper);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(5rem, 16vh, 8rem) var(--gutter) clamp(2rem, 6vh, 3rem);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-1.5%);
  transition: opacity 0.45s var(--ease), transform 0.5s var(--ease), visibility 0.45s;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.nav-drawer.is-open { opacity: 1; visibility: visible; transform: none; }
.nav-drawer__list { display: flex; flex-direction: column; }
.nav-drawer__list li { border-bottom: 1px solid rgba(247, 246, 243, 0.14); }
.nav-drawer__list a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: clamp(0.85rem, 2.2vh, 1.2rem);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: clamp(1.25rem, 3.6vw, 1.65rem);
  line-height: 1.15;
  letter-spacing: -0.022em;
  text-decoration: none;
  color: var(--paper);
  transition: color 0.35s var(--ease), padding-left 0.4s var(--ease);
}
.nav-drawer__list a:hover,
.nav-drawer__list a[aria-current="page"] { color: var(--orange); padding-left: 0.4rem; }
.nav-drawer__list .n {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  letter-spacing: 0.16em;
  color: rgba(247, 246, 243, 0.4);
  flex: none;
}
.nav-drawer__foot {
  margin-top: clamp(1.75rem, 5vh, 2.5rem);
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  justify-content: space-between;
  align-items: baseline;
  font-size: var(--step--1);
  color: rgba(247, 246, 243, 0.6);
}
.nav-drawer__foot a { color: var(--paper); text-decoration: none; border-bottom: 1px solid rgba(247, 246, 243, 0.3); }

/* Footer ---------------------------------------------------------------- */
.site-footer {
  position: relative;
  background: #0c0c0c;
  color: var(--paper);
  padding-top: clamp(3rem, 6vw, 5rem);
  padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
  overflow: clip;
}
.site-footer::before {
  content: "";
  position: absolute;
  left: 50%;
  translate: -50% 0;
  top: -150%;
  width: min(2400px, 200vw);
  aspect-ratio: 1;
  border: 1px solid rgba(247, 246, 243, 0.1);
  border-radius: 50%;
  pointer-events: none;
}
.footer__top {
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  padding-bottom: clamp(2rem, 4vw, 3.5rem);
  border-bottom: 1px solid rgba(247, 246, 243, 0.14);
}
.footer__statement { grid-column: 1 / span 6; }
.footer__statement .h2 { font-size: clamp(1.8rem, 1.2rem + 2vw, 3rem); max-width: 18ch; }
.footer__statement p { margin-top: 1rem; font-size: var(--step--1); color: rgba(247, 246, 243, 0.6); max-width: 40ch; }
.footer__nav { grid-column: 8 / span 2; }
.footer__contact { grid-column: 10 / -1; }
.footer__col-title {
  font-size: var(--step--2);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(247, 246, 243, 0.45);
  margin-bottom: 0.9rem;
}
.footer__list { display: flex; flex-direction: column; gap: 0.5rem; }
.footer__list a {
  font-size: var(--step--1);
  text-decoration: none;
  color: rgba(247, 246, 243, 0.82);
  transition: color 0.3s var(--ease);
}
.footer__list a:hover { color: var(--orange); }
.footer__bottom {
  position: relative;
  margin-top: clamp(1.5rem, 3vw, 2rem);
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2rem;
  justify-content: space-between;
  align-items: center;
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  color: rgba(247, 246, 243, 0.45);
}
/* Footer brand mark. Replaces the previous ghosted wordmark with the real
   supplied lockup, so the wordmark is never an approximation. */
.footer__logo {
  position: relative;
  margin-top: clamp(2rem, 4vw, 3rem);
  display: flex;
  justify-content: center;
}
.footer__logo img {
  width: auto;
  height: clamp(22px, 2.3vw, 32px);
  opacity: 0.9;
}

/* 9. Motion -------------------------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 1s var(--ease-out), transform 1s var(--ease-out);
  transition-delay: var(--delay, 0ms);
}
[data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
  .curve path { stroke-dashoffset: 0; }
}

/* 10. Responsive --------------------------------------------------------- */
@media (max-width: 1080px) {
  .hero__foot { grid-template-columns: 1fr; }
  .hero__foot .hero__cta { justify-self: start; }
  .section-head__title { grid-column: 1 / -1; }
  .section-head__aside { grid-column: 1 / -1; }
  .article__head { grid-column: 1 / span 5; }
  .article__body { grid-column: 7 / -1; }
  .split__label { grid-column: 1 / -1; position: static; }
  .split__body { grid-column: 1 / -1; }
  .split--wide .split__body { grid-column: 1 / -1; }
  .feature__media { grid-column: 1 / span 6; }
  .feature__body { grid-column: 7 / -1; }
  .feature--flip .feature__media { grid-column: 5 / -1; }
  .feature--flip .feature__body { grid-column: 1 / span 4; }
}

@media (max-width: 900px) {
  .nav { display: none; }
  .nav-toggle { display: inline-flex; }
  .page-hero__lede .prose,
  .page-hero__lede .prose--aside { grid-column: 1 / -1; }
  .page-hero__lede .page-hero__cta { grid-column: 1 / -1; justify-self: start; margin-top: 0.5rem; }
  .hero__orbit { opacity: 0.5; top: auto; bottom: 34%; width: 62vw; right: -18%; }
}

@media (max-width: 780px) {
  .project { grid-template-columns: 1fr; gap: 1.25rem; }
  /* Both flip selectors must be listed here. `.project--flip .project__body`
     is (0,2,0) and would otherwise outrank a bare `.project__body` (0,1,0),
     leaving the flipped row's copy stuck in `1 / span 5` and shrinking the
     media next to it instead of stacking full width. */
  .project__media,
  .project--flip .project__media,
  .project__body,
  .project--flip .project__body { grid-column: 1 / -1; grid-row: auto; }
  .project--flip .project__media { order: 0; }
  .project-index li { flex: 1 1 100%; border-left: 0; border-top: 1px solid var(--line); }
  .project-index li:first-child { border-top: 0; }
  .row { grid-template-columns: 1fr; gap: 0.85rem; }
  .row__num,
  .row__title,
  .row__body,
  .row__aside { grid-column: 1 / -1; }
  .row__title .h3 { font-size: 1.5rem; }
  .article { grid-template-columns: 1fr; }
  .article__head,
  .article__body { grid-column: 1 / -1; position: static; }
  .article__head { margin-bottom: 0.35rem; }
  .person,
  .person--wide { grid-column: 1 / -1; }
  .person--wide { grid-template-columns: 1fr; }
  .person--wide .person__media,
  .person--wide .person__info { grid-column: 1 / -1; }
  .person--wide .person__media { max-width: 320px; }
  .feature,
  .feature--flip { grid-template-columns: 1fr; }
  .feature__media,
  .feature--flip .feature__media,
  .feature__body,
  .feature--flip .feature__body { grid-column: 1 / -1; grid-row: auto; }
  /* Featured project with real key art: artwork above the production details. */
  .feature--proj { grid-template-columns: 1fr; }
  .proj-art,
  .proj-spec { grid-column: 1 / -1; }
  .announce { grid-template-columns: 1fr; }
  .announce__body,
  .announce__date { grid-column: 1 / -1; text-align: left; }
  .cta { grid-template-columns: 1fr; }
  .cta__title,
  .cta__links { grid-column: 1 / -1; }
  .split-head { grid-template-columns: 1fr; }
  .split-head > .h2,
  .split-head > .prose { grid-column: 1 / -1; }
  /* Contact directory: each row stacks its label above its address. At this
     width the ~30% label column plus the address column stops being
     comfortable (measured 340px of text in a 393px track at 640px, too tight
     to survive a fallback font), so the label moves above the address and the
     address takes the full measure. The type ramp below is recomputed for
     that wider box and steps down so the longest address never clips. */
  .direct-contact__row,
  .direct-contact__elsewhere {
    grid-template-columns: 1fr;
    gap: 0.55rem;
    align-items: start;
  }
  .direct-contact__row a { font-size: clamp(1.05rem, 4.4vw, 1.5rem); }
  /* The CTA drops out of the 30% row grid and starts at the container edge,
     so it aligns with the stacked labels/addresses rather than floating in a
     phantom second column. */
  .direct-contact__elsewhere .btn { grid-column: 1; }
  .hero { min-height: 92svh; }
  .hero__foot { grid-template-columns: 1fr; gap: 1.4rem; }
  .hero__foot .prose { max-width: 52ch; }
  .spec__row { grid-template-columns: 1fr; gap: 0.25rem; }
  .footer__statement,
  .footer__nav,
  .footer__contact { grid-column: 1 / -1; }
  .footer__nav .footer__list { flex-direction: row; flex-wrap: wrap; gap: 0.5rem 1.25rem; }
  .footer__top { gap: 2rem; }
  .section-head { grid-template-columns: 1fr; }
  .grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

@media (max-width: 520px) {
  :root { --section-y: 3.75rem; }
  /* Homepage keeps its ~10% extra rhythm at phone widths too. */
  body.page-home { --section-y: 4.125rem; }
  /* No display-size override here: the --display token clamp is already
     tuned for the extended face. Forcing a larger min would overflow. */
  .hero__title { max-width: 100%; }
  .hero__orbit { display: none; }
  /* The discipline line is long by nature; tighten its tracking at phone
     widths so it stays a single legible line rather than fragmenting. */
  .hero__disciplines { letter-spacing: 0.05em; }
  .person__credits li { font-size: var(--step--1); }
  .announce::after { display: none; }
}
