/* ==========================================================================
   Arthur Toledo — portfolio
   Design tokens
   ========================================================================== */

:root {
  --bg:          #0b0b0a;
  --bg-alt:      #0e0e0d;
  --panel:       #101010;

  --ink:         #ece9e2;
  --ink-2:       #b9b5ad;
  --ink-3:       #8a8781;
  --ink-4:       #6d6a65;

  /* raised for text sitting on a photograph */
  --ink-hi:      #f6f3ec;
  --ink-bright:  #f2efe8;
  --ink-quiet:   #cdc8be;

  --accent:      #e0893c;
  --accent-hi:   #f0a15b;

  --line:        rgba(236, 233, 226, 0.12);
  --line-soft:   rgba(236, 233, 226, 0.09);
  --line-strong: rgba(236, 233, 226, 0.2);
  --hairline:    rgba(236, 233, 226, 0.1);

  --sans: Archivo, system-ui, -apple-system, "Segoe UI", sans-serif;
  --serif: Newsreader, Georgia, "Times New Roman", serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --shell-max: 1440px;
  --shell-pad: clamp(20px, 5vw, 72px);
  --gutter: clamp(18px, 2vw, 28px);
  --header-h: 58px;
}

/* ==========================================================================
   Base
   ========================================================================== */

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

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  overflow-x: hidden;
  position: relative;
}

a { color: var(--ink); text-decoration: none; }
a:hover { color: var(--accent); }

img { max-width: 100%; }

::selection { background: var(--accent); color: var(--bg); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Motion ---------------------------------------------------------------------
   at-rise / at-fade are one-shot entrances; at-bob and at-breathe loop. */

@keyframes at-rise {
  from { opacity: 0; transform: translate3d(0, 0.42em, 0); }
  to   { opacity: 1; transform: none; }
}

@keyframes at-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes at-bob {
  0%, 100% { transform: translateY(0); opacity: 0.55; }
  50%      { transform: translateY(7px); opacity: 1; }
}

@keyframes at-breathe {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 0.9; }
}

/* at-drift walks the cloud plate a few percent sideways and back; at-mote
   lifts a single ember and fades it out at the top of its travel. */

@keyframes at-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-5%, 0, 0); }
}

@keyframes at-mote {
  0%        { opacity: 0; transform: translate3d(0, 0, 0); }
  18%       { opacity: 0.85; }
  70%       { opacity: 0.5; }
  100%      { opacity: 0; transform: translate3d(26px, -170px, 0); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .rise,
  .hero-cue,
  .hero-glow,
  .scene-sun,
  .scene-mote,
  .scene-clouds img {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  /* The embers only exist as motion; frozen they are five orange dots. */
  .scene-motes { display: none; }
}

/* Shared layout primitives --------------------------------------------------- */

.section-shell {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding-left: var(--shell-pad);
  padding-right: var(--shell-pad);
}

.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--gutter);
}

.section-anchor { scroll-margin-top: 80px; }

.eyebrow {
  margin: 0 0 18px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

.section-title {
  margin: 0;
  font-size: clamp(34px, 5.4vw, 76px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 0.95;
}

.section-num {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  color: var(--accent);
  vertical-align: super;
  margin-right: 16px;
}

/* Scroll reveal -------------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 800ms cubic-bezier(.16, 1, .3, 1),
              transform 800ms cubic-bezier(.16, 1, .3, 1);
}

[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

.no-reveal [data-reveal] {
  opacity: 1;
  transform: none;
  transition: none;
}

/* ==========================================================================
   Header
   ========================================================================== */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 80;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  background: rgba(11, 11, 10, 0.72);
  border-bottom: 1px solid var(--line-soft);
}

.header-inner {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 14px var(--shell-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.brand {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.brand-name {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.brand-role {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2.4vw, 34px);
}

.nav-link {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.lang-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-left: clamp(6px, 1.4vw, 18px);
  border-left: 1px solid rgba(236, 233, 226, 0.14);
}

.lang-btn {
  background: none;
  border: none;
  padding: 2px 1px;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--ink-4);
  transition: color 200ms ease;
}

/* Menu toggle. Nothing above 760px ever sees it. */
.nav-toggle {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.nav-toggle-bars {
  position: relative;
  display: block;
  width: 22px;
  height: 12px;
}

.nav-toggle-bars span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.28s ease, opacity 0.2s ease;
}

.nav-toggle-bars span:first-child { top: 2px; }
.nav-toggle-bars span:last-child  { bottom: 2px; }

/* Open: the two bars cross. Same two elements, no third one to hide. */
body.nav-open .nav-toggle-bars span:first-child {
  transform: translateY(4.25px) rotate(45deg);
}

body.nav-open .nav-toggle-bars span:last-child {
  transform: translateY(-4.25px) rotate(-45deg);
}

body.nav-open .nav-toggle { color: var(--accent); }

.lang-btn:hover { color: var(--ink-2); }
.lang-btn.is-active { color: var(--accent); }

/* read-progress rail along the bottom edge of the header */

.scroll-progress {
  height: 2px;
  background: rgba(236, 233, 226, 0.08);
}

.scroll-progress-bar {
  height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  will-change: transform;
}

/* ==========================================================================
   01 — Hero
   ========================================================================== */

/* No offset for the fixed header here — the hero photograph runs full bleed
   underneath it, and the header carries its own translucent background. The
   offset is added back onto .hero-inner so the copy keeps its position. */
.site-main { padding-top: 0; }

.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  isolation: isolate;
}

/* illustrated backdrop, offset by the parallax runtime */
.hero-bg {
  position: absolute;
  inset: -14% 0;
  z-index: 0;
  will-change: transform;
}

.hero-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 58%;
  /* The design specified brightness(0.66), tuned against a photograph. This
     illustration already carries its own near-black ridge across the bottom
     third — the band the headline sits on — so it only needs enough grading to
     sit under the header, and any more buries the sun. */
  filter: brightness(0.82) saturate(0.96) contrast(1.02);
}

/* warm bloom behind the wordmark */
.hero-glow {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(58% 44% at 70% 34%, rgba(224, 137, 60, 0.32), rgba(224, 137, 60, 0) 72%);
  animation: at-breathe 9s ease-in-out infinite;
}

/* Darkens top and bottom so the header and the copy both stay legible. The
   design's 0.86 / 0.22 / 0.62 ramp was tuned against a placeholder; this one is
   tuned against the illustration, where the wordmark lands on lit sky rather
   than on a dark photograph. Measured over the band "Arthur Toledo" actually
   occupies, the design's ramp gives 3.1:1 at the brightest 5% — the floor for
   large text, and only because the type is 181px. Lifting the 20% stop to 0.40
   takes it to 5.2:1 and still reads as a sunset. */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg,
    rgba(11, 11, 10, 0.62) 0%,
    rgba(11, 11, 10, 0.4)  20%,
    rgba(11, 11, 10, 0.56) 50%,
    rgba(11, 11, 10, 0.64) 72%,
    #0b0b0a 100%);
}

/* curve that hands off to the flat page below */
.hero-curve {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  width: 100%;
  height: clamp(38px, 6vw, 88px);
  z-index: 3;
  display: block;
}

.hero-cue {
  position: absolute;
  right: var(--shell-pad);
  bottom: clamp(74px, 11vh, 124px);
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  animation: at-bob 2.6s ease-in-out infinite;
}

.hero-cue-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
}

.hero-cue-line {
  width: 1px;
  height: 42px;
  background: linear-gradient(180deg, var(--accent), rgba(224, 137, 60, 0));
}

.hero-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--shell-max);
  margin: 0 auto;
  /* Tuned so the kicker, the name, the lead and the buttons all clear the
     fold at 1440x900. The old 16vh top alone put 202px above the kicker. */
  padding: calc(var(--header-h) + clamp(56px, 10vh, 120px)) var(--shell-pad) clamp(64px, 10vh, 120px);
  will-change: transform, opacity;
}

.hero-grid { align-items: end; }

.kicker-row {
  grid-column: 1 / -1;
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: clamp(14px, 2.8vh, 30px);
}

.kicker-num {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--accent);
}

.kicker-text {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.kicker-rule {
  flex: 1;
  height: 1px;
  background: rgba(236, 233, 226, 0.13);
}

.hero-title {
  grid-column: 1 / -1;
  margin: 0;
  /* Width alone sized this, and on a short laptop two lines of it pushed the
     buttons under the fold. The vh term only ever wins when the window is
     short — at 1440x900 it lands within 2px of the old value. */
  font-size: clamp(54px, min(12.6vw, 20vh), 196px);
  font-weight: 700;
  letter-spacing: -0.048em;
  line-height: 0.85;
  text-wrap: balance;
  color: var(--ink-hi);
  text-shadow: 0 12px 60px rgba(11, 11, 10, 0.55);
}

.rise {
  display: block;
  animation: at-rise 1.1s cubic-bezier(.16, 1, .3, 1) both;
}

.rise--delayed { animation-delay: 0.12s; }

.hero-body {
  grid-column: 1 / -1;
  max-width: 640px;
  margin-top: clamp(22px, 3.6vh, 40px);
}

.hero-lead {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(20px, 2.3vw, 29px);
  line-height: 1.4;
  color: var(--ink);
  text-wrap: pretty;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: clamp(20px, 3.2vh, 32px);
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 22px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}

.btn--primary {
  background: var(--accent);
  color: var(--bg);
  font-weight: 500;
}

.btn--primary:hover {
  background: var(--accent-hi);
  color: var(--bg);
}

.btn--ghost {
  border: 1px solid rgba(236, 233, 226, 0.22);
  color: var(--ink);
}

.btn--ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.btn--text {
  padding: 13px 4px;
  color: var(--ink-quiet);
  border-bottom: 1px solid rgba(236, 233, 226, 0.28);
  gap: 8px;
}

.btn--text:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.meta-grid {
  margin: clamp(32px, 6vh, 56px) 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 20px 24px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.7;
}

.meta-grid dt {
  color: var(--ink-quiet);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.meta-grid dd {
  margin: 4px 0 0;
  color: var(--ink-2);
}

.meta-grid .meta-strong { color: var(--ink-bright); }

/* ==========================================================================
   02 — Short version
   ========================================================================== */

.intro {
  padding-top: clamp(56px, 9vh, 110px);
  padding-bottom: clamp(70px, 11vh, 140px);
}

.intro-figure {
  margin: 0;
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--gutter);
  align-items: end;
}

.intro-photo {
  grid-column: 1 / span 5;
  min-width: 0;
}

.intro-photo img {
  width: 100%;
  height: auto;
  display: block;
  filter: grayscale(1) contrast(1.06) brightness(0.94);
  border: 1px solid var(--hairline);
}

.intro-caption {
  grid-column: 7 / span 6;
  min-width: 0;
  padding-bottom: clamp(8px, 3vh, 40px);
}

.intro-p {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(18px, 1.55vw, 22px);
  line-height: 1.6;
  color: var(--ink-2);
  text-wrap: pretty;
}

.intro-p + .intro-p { margin-top: 18px; }

.capability-list {
  list-style: none;
  margin: clamp(26px, 4vh, 40px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px 28px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--ink-3);
  line-height: 1.6;
}

/* ==========================================================================
   03 — Selected work
   ========================================================================== */

.work { border-top: 1px solid var(--line); }

.section-head {
  padding-top: clamp(48px, 8vh, 96px);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
}

.section-note {
  margin: 0;
  max-width: 340px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.8;
  color: var(--ink-3);
}

.work-list { margin-top: clamp(36px, 6vh, 64px); }

.case-link {
  display: block;
  border-top: 1px solid var(--line);
  padding: clamp(26px, 4vh, 44px) 0;
  transition: background-color 250ms ease;
}

.case-link:hover { background: rgba(236, 233, 226, 0.025); }
.case-link:hover .case-cta { color: var(--accent); }

.case-grid { align-items: start; }

.case-copy {
  grid-column: 1 / span 5;
  min-width: 0;
}

.case-meta {
  display: flex;
  gap: 16px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.case-title {
  margin: 14px 0 0;
  font-size: clamp(28px, 3.3vw, 46px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.02;
}

.case-sub {
  margin: 6px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
}

.case-desc {
  margin: 18px 0 0;
  max-width: 420px;
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.6;
  color: var(--ink-2);
}

.case-cta {
  margin: 22px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  transition: color 200ms ease;
}

.case-visual {
  grid-column: 7 / span 6;
  min-width: 0;
}

.shot-stack {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: clamp(10px, 1.4vw, 18px);
  align-items: start;
}

.shot {
  position: relative;
  overflow: hidden;
  min-width: 0;
  background: repeating-linear-gradient(135deg, #151513 0 8px, #1b1b18 8px 16px);
  border: 1px solid var(--hairline);
  display: flex;
  align-items: flex-end;
}

/* A shot is its own placeholder. Drop a file in and the image covers the tile;
   without one — or if the file 404s and main.js pulls it back out — the striped
   tile and its caption are what is left, which is where this started. */
.shot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The inset lives on the caption, not on the tile: an absolutely positioned
   child is laid out against the padding box, so padding here would leave a
   12px frame of stripes around every image. */
.shot span {
  padding: 12px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--ink-4);
}

/* Its capture's own ratio rather than a shape it has to be cut down to — the
   same rule .case-shots runs on. */
.shot--wide { aspect-ratio: 1.889; }
.shot--tall { aspect-ratio: 9 / 16; }
.shot--hero { aspect-ratio: 16 / 9; }
.shot--hero span { padding: 14px; }

/* transaction path card */

.flow-card {
  border: 1px solid var(--hairline);
  padding: clamp(18px, 2.4vw, 32px);
  background: var(--panel);
}

.flow-label {
  margin: 0 0 18px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.flow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--ink);
}

.flow-node {
  border: 1px solid var(--line-strong);
  padding: 7px 11px;
}

.flow-node--accent {
  border-color: var(--accent);
  color: var(--accent);
}

.flow-arrow { color: var(--accent); }

.stack-line {
  margin: 18px 0 0;
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1.8;
  color: var(--ink-3);
}

/* also built & shipped */

.more-work {
  border-top: 1px solid var(--line);
  padding: clamp(30px, 5vh, 52px) 0 clamp(56px, 9vh, 110px);
}

.more-label {
  margin: 0 0 clamp(22px, 3.5vh, 34px);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.more-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(22px, 3vw, 44px);
}

.more-tag {
  margin: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.more-title {
  margin: 8px 0 0;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.more-desc {
  margin: 8px 0 0;
  font-family: var(--serif);
  font-size: 16.5px;
  line-height: 1.55;
  color: var(--ink-3);
}

/* ==========================================================================
   Interludes — full-bleed photograph with a single line over it.
   One sits between work/systems, systems/experience and experience/about.
   ========================================================================== */

.interlude {
  position: relative;
  height: clamp(340px, 60vh, 600px);
  overflow: hidden;
  isolation: isolate;
}

.interlude-bg {
  position: absolute;
  inset: -16% 0;
  z-index: 0;
  will-change: transform;
}

.interlude-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.4) brightness(0.48) contrast(1.08);
}

/* Each photograph has its own subject height. The beach differs from the
   design's 60%: at that depth the band lands on flat sand, so it is raised to
   the horizon where the sea and the treeline are. */
.interlude--glacier .interlude-bg img { object-position: 50% 55%; }
.interlude--ridge   .interlude-bg img { object-position: 50% 45%; }
.interlude--beach   .interlude-bg img { object-position: 50% 22%; }

/* Illustrated backdrops instead of photographs. The grading above is built for
   a photograph — desaturate flat colour by 40% and drop it to 0.48 brightness
   and an illustration turns to mud. Add this class alongside the per-image one
   when swapping in a file from img/scene/. */
.interlude--art .interlude-bg img {
  filter: saturate(0.96) brightness(0.82) contrast(1.02);
  object-position: 50% 50%;
}

/* Two axes instead of one. The line and the label both sit on the left, and all
   three illustrations put their subject on the right — the sun, the island, the
   lit ice — so a horizontal ramp buys the type its cover where the type is and
   leaves the half worth looking at alone. That is what pays for the lighter
   vertical ramp here: measured over the glyphs, the 11px accent label goes from
   2.9:1 on the photographs to 4.7:1, while the art stays at 0.82 brightness. */
.interlude--art .interlude-scrim {
  background:
    linear-gradient(90deg,
      rgba(11, 11, 10, 0.62) 0%,
      rgba(11, 11, 10, 0.42) 34%,
      rgba(11, 11, 10, 0) 62%),
    linear-gradient(180deg,
      #0b0b0a 0%,
      rgba(11, 11, 10, 0.22) 38%,
      rgba(11, 11, 10, 0.4) 66%,
      #0b0b0a 100%);
}

.interlude-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg,
    #0b0b0a 0%,
    rgba(11, 11, 10, 0.28) 38%,
    rgba(11, 11, 10, 0.5) 66%,
    #0b0b0a 100%);
}

.interlude-inner {
  position: relative;
  z-index: 2;
  height: 100%;
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 0 var(--shell-pad);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(14px, 2.4vh, 22px);
}

.interlude-label {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.interlude-line {
  margin: 0;
  font-size: clamp(28px, 4.6vw, 66px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.04;
  max-width: 22ch;
  color: var(--ink-hi);
  text-wrap: balance;
}

/* ==========================================================================
   Scene — how the work actually goes, over an illustrated dusk forest.
   Eight layers in one stage, all riding the same [data-par] loop in main.js at
   their own speeds. Underneath the painted panorama is a CSS sky, so the
   section is never blank while the plate loads; over everything is a veil that
   grades the whole illustration back into the site's dark palette, which is
   what lets the same ink colours read here as on the photographs.
   ========================================================================== */

.scene {
  position: relative;
  /* The art is sized off the stage width, so the stage has to answer to width
     too — on a wide, short window a height in vh alone leaves the front
     treeline almost at the bottom edge, with the steps sitting in it. */
  min-height: clamp(700px, max(108vh, 62vw), 1400px);
  display: flex;
  overflow: hidden;
  isolation: isolate;
  border-top: 1px solid var(--line);
  background: #150310;
}

.scene-stage {
  position: absolute;
  inset: 0;
  z-index: 0;
}

/* Fallback sky, and the colour the artwork is graded towards. */
.scene-sky {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    #24123a 0%,
    #4a1c3c 22%,
    #8d3446 44%,
    #c2604f 64%,
    #e0893c 82%,
    #2a0519 100%);
}

/* The painted panorama: sky, sun, clouds and the far range on one plate. */
.scene-plate {
  position: absolute;
  inset: -10% -6%;
  will-change: transform;
}

.scene-plate img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 46%;
  filter: saturate(0.92) brightness(0.84) contrast(1.02);
}

/* The only loop here that is not scroll-driven. It sits behind every treeline,
   so what actually reads is the glow leaking between the trunks. */
.scene-sun {
  position: absolute;
  left: 50%;
  bottom: 33%;
  width: clamp(280px, 33vw, 560px);
  aspect-ratio: 1;
  margin-left: calc(clamp(280px, 33vw, 560px) / -2);
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(253, 217, 116, 0.5) 0%,
    rgba(224, 137, 60, 0.3) 44%,
    rgba(224, 137, 60, 0) 70%);
  animation: at-breathe 9s ease-in-out infinite;
}

.scene-layer {
  position: absolute;
  top: 0;
  left: -6%;
  right: -6%;
  will-change: transform;
}

.scene-layer img {
  display: block;
  width: 100%;
  height: auto;
  /* The ratio has to come from CSS, not from the file: these are lazy, and a
     lazy image whose box is 0px tall never becomes visible enough to load.
     One per plane, because each carries a different amount of slab. */
  aspect-ratio: 1600 / 1400;
}

.scene-l4 img { aspect-ratio: 1600 / 1400; }
.scene-l3 img { aspect-ratio: 1600 / 1800; }
.scene-l2 img { aspect-ratio: 1600 / 2200; }
.scene-l1 img { aspect-ratio: 1600 / 2800; }

/* Every plane is anchored to the top edge and sized off the stage width, so
   the four treelines keep their spacing at any width — the depth lives in
   each file's baseline, not here. */

.scene-clouds { top: 8%; }
.scene-clouds img { aspect-ratio: 1600 / 380; }
.scene-clouds img { animation: at-drift 96s ease-in-out infinite alternate; }

/* Planted on the third treeline, inside a frame with the planes' own ratio so
   its position is measured against the stage width like theirs is — and given
   that plane's parallax speed, or it would slide off its ridge. */
.scene-cabin {
  position: absolute;
  top: 0;
  left: -6%;
  right: -6%;
  aspect-ratio: 1600 / 1400;
  will-change: transform;
}

.scene-cabin img {
  position: absolute;
  left: 60%;
  top: 27.3%;
  width: 5.4%;
  height: auto;
  aspect-ratio: 224 / 170;
}

/* Two close-up trunks at the frame edges — the nearest plane, and the only one
   blurred, which is what sells the distance between them and the ridge. */
.scene-tree {
  position: absolute;
  bottom: -8%;
  width: clamp(120px, 15vw, 240px);
  will-change: transform;
  filter: blur(3px);
  opacity: 0.88;
}

.scene-tree img { display: block; width: 100%; height: auto; aspect-ratio: 300 / 900; }
.scene-tree--l { left: -6%; }
.scene-tree--r { right: -6%; }
.scene-tree--r img { transform: scaleX(-1); }

/* Embers over the treeline. Five is enough to read as air and not as snow. */
.scene-motes { position: absolute; inset: 0; overflow: hidden; }

.scene-mote {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--accent-hi);
  opacity: 0;
  animation: at-mote 15s ease-in-out infinite;
}

.scene-mote:nth-child(1) { left: 14%; bottom: 22%; animation-delay: 0s;   animation-duration: 17s; }
.scene-mote:nth-child(2) { left: 33%; bottom: 16%; animation-delay: 3.5s; animation-duration: 13s; }
.scene-mote:nth-child(3) { left: 57%; bottom: 26%; animation-delay: 7s;   animation-duration: 19s; }
.scene-mote:nth-child(4) { left: 71%; bottom: 14%; animation-delay: 1.8s; animation-duration: 15s; }
.scene-mote:nth-child(5) { left: 88%; bottom: 24%; animation-delay: 9.4s; animation-duration: 21s; }

.scene-veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(11, 11, 10, 0.84) 0%,
    rgba(11, 11, 10, 0.36) 24%,
    rgba(11, 11, 10, 0.12) 46%,
    rgba(11, 11, 10, 0.4)  72%,
    rgba(11, 11, 10, 0.82) 90%,
    #0b0b0a 100%);
}

/* ---------------------------------------------------------------- content */

.scene-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: clamp(64px, 11vh, 128px) var(--shell-pad) clamp(52px, 8vh, 104px);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(48px, 9vh, 110px);
}

.scene-label {
  margin: 0 0 clamp(14px, 2vh, 22px);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.scene-title {
  margin: 0;
  max-width: 16ch;
  font-size: clamp(30px, 4.8vw, 68px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.03;
  color: var(--ink-hi);
  text-wrap: balance;
}

.scene-steps {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gutter);
}

.scene-step {
  padding-top: clamp(16px, 2vh, 24px);
  border-top: 1px solid var(--line-strong);
}

.scene-step-num {
  display: block;
  margin-bottom: clamp(10px, 1.6vh, 18px);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--accent);
}

.scene-step-h {
  margin: 0 0 10px;
  font-size: clamp(17px, 1.5vw, 23px);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-bright);
}

.scene-step-p {
  margin: 0;
  max-width: 34ch;
  font-family: var(--serif);
  font-size: clamp(14px, 1.05vw, 17px);
  font-weight: 300;
  line-height: 1.62;
  color: var(--ink-quiet);
}

.scene-foot {
  margin: clamp(26px, 4vh, 44px) 0 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  line-height: 1.7;
  max-width: 62ch;
  color: var(--ink-3);
}

/* ==========================================================================
   04 — What I work with
   ========================================================================== */

.systems {
  border-top: 1px solid var(--line);
  background: var(--bg-alt);
}

.systems .section-shell {
  padding-top: clamp(48px, 8vh, 100px);
  padding-bottom: clamp(56px, 9vh, 110px);
}

.systems-title { margin-bottom: clamp(32px, 5vh, 56px); }

.skill-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: clamp(24px, 3vw, 48px);
}

.skill-head {
  margin: 0 0 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(236, 233, 226, 0.14);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

.skill-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 2;
  color: var(--ink-2);
}

.philosophy { margin-top: clamp(50px, 8vh, 96px); }

.phil-label {
  grid-column: 1 / span 4;
  min-width: 0;
}

.phil-label p {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.phil-list {
  grid-column: 6 / span 7;
  min-width: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(20px, 3vh, 30px);
}

.phil-item {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 16px;
}

.phil-num {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--accent);
  padding-top: 7px;
}

.phil-text {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(18px, 1.6vw, 23px);
  line-height: 1.5;
  color: var(--ink);
}

/* ==========================================================================
   05 — The route so far
   ========================================================================== */

.experience { border-top: 1px solid var(--line); }

.experience .section-shell {
  padding-top: clamp(48px, 8vh, 100px);
  padding-bottom: clamp(56px, 9vh, 110px);
}

.experience-title { margin-bottom: clamp(36px, 6vh, 64px); }

.timeline { display: grid; gap: 0; }

.role {
  padding: clamp(24px, 3.6vh, 38px) 0;
  border-top: 1px solid var(--line);
}

.role--last { border-bottom: 1px solid var(--line); }

.role-when { grid-column: 1 / span 3; min-width: 0; }
.role-what { grid-column: 4 / span 4; min-width: 0; }
.role-detail { grid-column: 8 / span 5; min-width: 0; }

.role-year {
  margin: 0;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  color: var(--ink);
}

.role-year--now { color: var(--accent); }

.role-place {
  margin: 6px 0 0;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.role-title {
  margin: 0;
  font-size: clamp(20px, 2vw, 28px);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.role-co {
  margin: 6px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
}

.role-steps {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 2;
  color: var(--ink-4);
}

.role-step-date { color: var(--ink-3); }

.role-desc {
  margin: 0;
  font-family: var(--serif);
  font-size: 17.5px;
  line-height: 1.6;
  color: var(--ink-2);
}

.role-stack {
  margin: 12px 0 0;
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1.8;
  color: var(--ink-4);
}

.role-note {
  margin: 10px 0 0;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-4);
}

/* ==========================================================================
   06 — Off the clock
   ========================================================================== */

.about {
  border-top: 1px solid var(--line);
  background: var(--bg-alt);
}

.about-inner {
  padding-top: clamp(48px, 8vh, 100px);
  padding-bottom: clamp(30px, 5vh, 60px);
}

.about-title {
  grid-column: 1 / span 4;
  min-width: 0;
}

.about-body {
  grid-column: 6 / span 7;
  min-width: 0;
  max-width: 640px;
}

.about-p1 {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(19px, 1.8vw, 25px);
  line-height: 1.5;
  color: var(--ink);
  text-wrap: pretty;
}

.about-p2 {
  margin: 20px 0 0;
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.65;
  color: var(--ink-2);
  text-wrap: pretty;
}

.about-p3 {
  margin: 20px 0 0;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.9;
  color: var(--ink-3);
}

.about-edu {
  margin: 14px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.9;
  color: var(--ink-4);
}

.gallery-shell { padding-bottom: clamp(56px, 9vh, 110px); }

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: clamp(10px, 1.4vw, 18px);
}

.gallery img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  display: block;
  filter: grayscale(0.5) contrast(1.05);
  transition: filter 400ms ease;
}

.gallery img:hover { filter: grayscale(0) contrast(1.05); }

/* Fallback tile shown when a photo file is missing --------------------------- */

.photo-fallback {
  width: 100%;
  background: repeating-linear-gradient(135deg, #151513 0 8px, #1b1b18 8px 16px);
  border: 1px solid var(--hairline);
  display: flex;
  align-items: flex-end;
  padding: 12px;
}

.intro-photo .photo-fallback { aspect-ratio: 4 / 5; }
.gallery .photo-fallback { aspect-ratio: 3 / 4; }

.photo-fallback span {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 1.5;
  color: var(--ink-4);
}

/* ==========================================================================
   07 — Contact
   ========================================================================== */

.contact { border-top: 1px solid var(--line); }

.contact .section-shell {
  padding-top: clamp(56px, 10vh, 130px);
  padding-bottom: clamp(56px, 10vh, 130px);
}

.contact-eyebrow {
  margin: 0 0 clamp(20px, 3vh, 32px);
  letter-spacing: 0.18em;
}

.contact-title {
  margin: 0;
  font-size: clamp(38px, 8.4vw, 124px);
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: 0.92;
  max-width: 16ch;
  text-wrap: balance;
}

.contact-email {
  display: inline-block;
  margin-top: clamp(28px, 4.5vh, 52px);
  font-size: clamp(22px, 3vw, 42px);
  font-weight: 500;
  letter-spacing: -0.02em;
  border-bottom: 1px solid rgba(236, 233, 226, 0.3);
  padding-bottom: 6px;
  transition: color 200ms ease, border-color 200ms ease;
}

.contact-email:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.contact-grid {
  margin-top: clamp(36px, 6vh, 72px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 24px;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.9;
}

.contact-label {
  margin: 0;
  color: var(--ink-4);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.contact-value {
  margin: 8px 0 0;
  color: var(--ink-2);
}

.contact-value--tight { margin-top: 2px; }

.contact-value a { color: var(--ink-2); }
.contact-value a:hover { color: var(--accent); }

.contact-cv { color: var(--accent) !important; }
.contact-cv:hover { color: var(--accent-hi) !important; }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer { border-top: 1px solid var(--line); }

.footer-inner {
  padding-top: 28px;
  padding-bottom: 40px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  color: var(--ink-4);
}

.footer-status { color: var(--accent); }

/* ==========================================================================
   Page-wide overlays: film grain and the cursor ring
   ========================================================================== */

.grain {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='0.6'/></svg>");
}

/* shown by main.js only on a fine pointer with motion allowed */
.cursor-ring {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 300;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(224, 137, 60, 0.85);
  border-radius: 50%;
  pointer-events: none;
  will-change: transform;
  mix-blend-mode: difference;
}

/* ==========================================================================
   Case study overlay
   ========================================================================== */

.case-overlay {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: var(--bg);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.case-overlay[hidden] { display: none; }

.case-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  background: rgba(11, 11, 10, 0.86);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--hairline);
}

.case-bar-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 14px clamp(20px, 5vw, 60px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.case-back,
.case-kind {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.case-back { color: var(--ink-2); }
.case-back:hover { color: var(--accent); }
.case-kind { color: var(--ink-4); }

.case-article {
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(40px, 8vh, 90px) clamp(20px, 5vw, 60px) clamp(60px, 10vh, 120px);
}

.case-hero-title {
  margin: 0;
  font-size: clamp(38px, 7vw, 96px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 0.94;
}

.case-lead {
  margin: clamp(22px, 4vh, 36px) 0 0;
  max-width: 720px;
  font-family: var(--serif);
  font-size: clamp(19px, 1.9vw, 26px);
  line-height: 1.5;
  color: var(--ink);
  text-wrap: pretty;
}

.case-facts {
  margin: clamp(34px, 6vh, 60px) 0 0;
  padding: 22px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 22px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.7;
}

.case-facts dt {
  color: var(--ink-quiet);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.case-facts dd {
  margin: 5px 0 0;
  color: var(--ink-2);
}

.case-blocks {
  margin-top: clamp(40px, 7vh, 80px);
  display: grid;
  gap: clamp(34px, 6vh, 64px);
}

.case-block {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(16px, 2vw, 28px);
}

.case-block-h {
  grid-column: 1 / span 3;
  min-width: 0;
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  padding-top: 6px;
}

.case-block-body {
  grid-column: 5 / span 8;
  min-width: 0;
  max-width: 680px;
}

.case-block-p {
  margin: 0;
  font-family: var(--serif);
  font-size: 18.5px;
  line-height: 1.65;
  color: var(--ink-2);
  text-wrap: pretty;
}

.case-items {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--ink-3);
}

.case-items li {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 8px;
}

.case-items li::before {
  content: "·";
  color: var(--accent);
}

/* A row of captures of different shapes. Forcing them all into one tile shape
   means cropping — a 1.89 dashboard sliced to 4:3 loses a third of itself, and
   a 9:16 phone screen either loses more than half or floats letterboxed in a
   dark frame beside desktop shots that fill theirs.
   So no tile has a fixed shape: each takes its own capture's ratio, passed in
   from CASE_SHOTS, and takes that same number as its share of the row. Width
   proportional to ratio means height constant — the shapes vary and the row
   still reads as one line. flex-end holds that line when it wraps. */
.case-shots {
  margin-top: clamp(44px, 7vh, 84px);
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: clamp(10px, 1.4vw, 18px);
}

.case-shots .shot {
  --shot-ratio: 1.3333;
  flex: var(--shot-ratio) 1 calc(var(--shot-ratio) * 190px);
  min-width: 0;
  aspect-ratio: var(--shot-ratio);
}

.case-stack-row {
  margin-top: clamp(40px, 7vh, 80px);
  padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 14px 28px;
  align-items: baseline;
  font-family: var(--mono);
  font-size: 11px;
}

.case-stack-label {
  color: var(--ink-4);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.case-stack-value {
  color: var(--ink-2);
  line-height: 1.9;
}

.case-links-note {
  margin: 18px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
}

.case-next {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  margin-top: clamp(48px, 8vh, 96px);
  padding-top: 26px;
  border-top: 1px solid var(--line-strong);
}

.case-next:hover { color: var(--accent); }
.case-next:hover .case-next-label { color: var(--accent); }

.case-next-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
  transition: color 200ms ease;
}

.case-next-title {
  font-size: clamp(22px, 3vw, 40px);
  font-weight: 600;
  letter-spacing: -0.025em;
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 900px) {
  .grid-12,
  .intro-figure,
  .case-block {
    grid-template-columns: 1fr;
  }

  /* At phone widths cover crops the illustrated interludes to the middle
     quarter of the frame — for the coast, that is the sun's reflection, the
     brightest thing in the set. The composition is lost to the crop either way,
     so the band trades it for cover: 4.7:1 on the label instead of 2.8:1. */
  .interlude--art .interlude-bg img {
    filter: saturate(0.96) brightness(0.72) contrast(1.02);
  }

  .interlude--art .interlude-scrim {
    background:
      linear-gradient(90deg,
        rgba(11, 11, 10, 0.68) 0%,
        rgba(11, 11, 10, 0.5)  45%,
        rgba(11, 11, 10, 0.08) 82%,
        rgba(11, 11, 10, 0) 100%),
      linear-gradient(180deg,
        #0b0b0a 0%,
        rgba(11, 11, 10, 0.34) 36%,
        rgba(11, 11, 10, 0.48) 66%,
        #0b0b0a 100%);
  }

  /* The scene loses the two front trunks and stacks its steps: at this width
     the trunks eat the text column rather than framing it. */
  .scene { min-height: 0; }
  .scene-tree { display: none; }
  .scene-steps { grid-template-columns: 1fr; gap: clamp(24px, 4vh, 36px); }
  .scene-step-p { max-width: 46ch; }
  /* The planes are sized off the stage width, so on a phone they would bunch
     into a strip at the top of a stage that is now far taller than it is wide.
     A fixed art width instead: the treelines land in the top third at any
     phone size, and the front plane's slab is the ground the steps sit on. */
  .scene-layer,
  .scene-cabin {
    left: 50%;
    right: auto;
    width: 880px;
    margin-left: -440px;
  }

  .scene-sun { top: 92px; bottom: auto; }

  /* Stacked, the steps would start halfway up the treeline. The gap pushes
     them onto the ground below the front plane, and what it opens up is sky. */
  .scene-inner { gap: clamp(150px, 26vh, 240px); }

  /* Heavier than the desktop veil at both ends: the headline sits right over
     the sun here, and the steps run much further down the ground. */
  .scene-veil {
    background: linear-gradient(180deg,
      rgba(11, 11, 10, 0.9)  0%,
      rgba(11, 11, 10, 0.54) 20%,
      rgba(11, 11, 10, 0.2)  40%,
      rgba(11, 11, 10, 0.46) 70%,
      rgba(11, 11, 10, 0.85) 90%,
      #0b0b0a 100%);
  }

  .kicker-row,
  .hero-title,
  .hero-body,
  .intro-photo,
  .intro-caption,
  .case-copy,
  .case-visual,
  .phil-label,
  .phil-list,
  .role-when,
  .role-what,
  .role-detail,
  .about-title,
  .about-body,
  .case-block-h,
  .case-block-body {
    grid-column: 1 / -1;
  }

  /* Only 761-900px reaches this now: below 760 the nav is a panel and never
     wraps. Here there is still room for two tidy rows. */
  .site-nav {
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 8px;
  }

  .intro-caption { padding-bottom: 0; margin-top: 28px; }

  .role-what { margin-top: 14px; }
  .role-detail { margin-top: 14px; }

  .about-body { margin-top: 26px; }

  .case-visual { margin-top: 26px; }

  .case-block-body { margin-top: 12px; }
}

/* Six nav links and a language switcher do not fit one row on a phone, and
   letting them wrap gave a two-storey header that ate the top of the hero.
   Below 760px the nav leaves the flow entirely and becomes a panel behind the
   header — which stays put, so the brand and the toggle are always reachable. */
@media (max-width: 760px) {
  .nav-toggle { display: flex; }

  /* backdrop-filter makes an element a containing block for position:fixed
     descendants, exactly like transform does. With it on the header, the panel
     below resolved inset:0 against a 55px-tall header instead of the viewport
     and came out 212px tall. At this width the blur buys little — a nearly
     solid bar over a dark page reads the same — so it goes, and fixed means
     fixed again. */
  .site-header {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(11, 11, 10, 0.94);
  }

  .site-nav {
    position: fixed;
    inset: 0;
    z-index: 70;                 /* under .site-header's 80 */
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: clamp(18px, 3.4vh, 30px);
    padding: calc(var(--header-h) + 9vh) var(--shell-pad) 10vh;
    background: var(--bg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: opacity 0.26s ease, transform 0.26s ease, visibility 0.26s;
  }

  body.nav-open .site-nav {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  .site-nav .nav-link {
    font-size: clamp(19px, 5.6vw, 26px);
    letter-spacing: 0.06em;
    color: var(--ink);
  }

  /* The divider was a vertical rule against the links; stacked, it reads as a
     horizontal one under them. */
  .lang-switch {
    margin-top: auto;
    padding: clamp(16px, 2.6vh, 24px) 0 0;
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--line);
    align-self: stretch;
    gap: 18px;
  }

  .lang-btn { font-size: 13px; }
}

@media (max-width: 560px) {
  .meta-grid,
  .gallery {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Stacked, a 9:16 tile at full width would be 600px tall. It keeps its ratio
     — the capture is a phone screen and reshaping it would crop it — and is
     held to a width that makes that ratio sit still. */
  .shot-stack { grid-template-columns: 1fr; }

  /* Centred on its own, not via justify-items on the track: that makes every
     item size to its content, and a tile whose height comes from aspect-ratio
     has no content to size to — the wide one collapses to 103px. */
  .shot--tall {
    width: 100%;
    max-width: 240px;
    justify-self: center;
  }

  .header-inner { gap: 14px; }
  .brand-role { display: none; }
}
