/* ==========================================================================
   KYLE SHERIDAN — "Field Notes"

   Built from the design handoff (design_handoff_kyle_sheridan_website).
   Printed-editorial: warm paper stock, Instrument Serif display, DM Mono
   utility labels, double rules, real captions with credits.

   The prototype was authored at a fixed 1440px width. Here the page is fluid
   up to that width, so every plate that the design gave a pixel height is
   expressed as an aspect-ratio that resolves to exactly that height at 1440px
   and scales proportionally below it. Each one carries the design figure it
   came from.

   Fonts: Instrument Serif, Instrument Sans and DM Mono, self-hosted from
   Google Fonts (the handoff asks for self-hosting) alongside the woff2 files
   the previous build already shipped.
   ========================================================================== */

/* --- Instrument Serif — display: headlines, project titles, pull quotes --- */
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/instrument-serif-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/instrument-serif-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Italic carries the emphasised phrase inside a headline — "behind the
   scenes.", "impact.", "something." — so it is a real weight, not synthesised. */
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/instrument-serif-400-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/instrument-serif-400-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Instrument Sans — body copy, nav, buttons (variable, 400–700) ------- */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/instrument-sans-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/instrument-sans-var-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- DM Mono — utility labels, folios, captions -------------------------- */
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/dm-mono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/dm-mono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

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

:root {
  /* Colour. The accent is hover/active only — never a resting fill, except
     the selected filter chip on Contact. */
  --paper:        #f1ede5;
  --paper-rgb:    241, 237, 229;   /* for gradients that fade paper to nothing */
  --paper-alt:    #e7e1d5;
  --ink:          #191713;
  --ink-80:       #3d3831;
  --ink-60:       #4a453d;
  --ink-45:       #6b6459;
  --muted:        #8a8175;
  --rule:         #cdc5b6;
  --field-rule:   #a89f90;
  /* Accent history — swap the value here and the whole site follows.
       #b94e35  terracotta, the handoff's original accent
       #803833  deep brick, tried and judged too dark
       #8a3f39  brick (current) */
  --accent:       #8a3f39;
  /* The accent, lifted for the ink footer. Kyle asked for footer links to hover
     to the site red like everything else; the brick itself reads 2.43:1 on
     #191713, so hovering would drop a link from 15.3:1 to below the 4.5:1 AA
     floor and make it harder to read than not hovering. This is the same hue at
     4.87:1 — it reads as the accent, and passes. Set it to #8a3f39 for the
     literal brick if the contrast is not wanted. */
  --accent-on-ink: #c96a60;
  --footer-body:  #b4ac9e;
  --footer-rule:  #3d3831;

  --serif: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --sans:  'Instrument Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --mono:  'DM Mono', ui-monospace, 'SF Mono', SFMono-Regular, Menlo, monospace;

  --gutter: 56px;         /* page gutter, left and right */
  --pad-section: 56px;    /* standard section vertical padding */
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

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

/* The UA default is `margin: 1em 40px`, which quietly narrows every figure used
   as a grid cell — the photography frames, the About portrait, the project
   plates — by 80px. */
figure { margin: 0; }

a { color: inherit; text-decoration: none; }

/* Keyboard focus. Browsers do draw their own ring, so this is not about
   restoring something missing — it's about it being the site's ring rather than
   an amber system default over warm paper. :focus-visible means a mouse click
   never draws it; tabbing always does. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* On the ink footer the brick accent falls to 2.4:1 and all but disappears, so
   the focus ring goes paper there. Note the footer link *hover* no longer uses
   paper — it uses --accent-on-ink, the lifted accent — but a focus ring has to
   be unmissable rather than merely legible, so it stays paper. */
.site-footer :focus-visible,
.marquee :focus-visible {
  outline-color: var(--paper);
}

/* Over a photograph, a paper ring reads on any frame. */
.plate :focus-visible,
.reel-action:focus-visible {
  outline-color: var(--paper);
  outline-offset: -4px;
}

/* No border radius anywhere except the play glyph, and no box shadows — the
   drop shadows in the prototype are canvas presentation chrome. */
button { border-radius: 0; }

/* Full-bleed: the rules, the marquee and the footer run the whole width of the
   browser rather than stopping at the design width. The layout keeps the
   design's proportions through the gutter and the per-plate aspect ratios, so
   it stretches rather than sitting boxed in the middle of a wide monitor. */
.page {
  width: 100%;
  background: var(--paper);
}

/* Visible only to screen readers — used for the per-page <h1> where the
   design's largest type is a project title rather than the page name. */
.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;
}

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

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

.caption {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 88px;
  line-height: 0.94;
  letter-spacing: -0.02em;
}

.h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 42px;
  line-height: 1;
  letter-spacing: -0.01em;
}

.lede {
  margin: 0;
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink-80);
  text-wrap: pretty;
}

em { font-style: italic; }

/* ------------------------------------------------------------ masthead --- */

/* Full-width rail: place, disciplines, volume.
   The middle item sits directly above the centred logo, so it is centred on the
   page rather than merely spaced evenly from its neighbours. This used to be
   `justify-content: space-between`, which equalises the two gaps — and because
   the place and volume strings are different lengths, equal gaps put the
   disciplines line visibly off-centre against the wordmark below it.
   Three tracks instead: the 1fr pair is equal by definition, so the auto track's
   centre is the content box's centre, and the box carries the same gutter either
   side. Place and volume stay flush to those gutters, exactly where they were. */
.masthead-rail {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  padding: 16px var(--gutter);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-45);
  border-bottom: 1px solid var(--ink);
}

.masthead-rail > :last-child { justify-self: end; text-align: right; }

/* The weather item ships empty and is filled by assets/site.js once the fetch
   lands. The zero-width space gives the empty span a line box so it reserves
   its row up front: without it the single-column mobile rail is 17px shorter
   until the fetch returns, and the whole page jumps down when it does. The
   ::before drops as soon as the span has text, and if the fetch never lands the
   reserved row just stays blank — which is the intended failure. */
.masthead-rail > [data-weather]:empty::before { content: "\200b"; }

/* The 3px double rule under the logo/nav block is a signature of the design.
   The block is padded evenly, so the logo sits the same distance below the rail
   rule as the nav sits above the double rule. */
.masthead {
  position: relative;
  padding: 26px var(--gutter);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
  border-bottom: 3px double var(--ink);
}

.masthead .logo img {
  height: 52px;
  width: auto;
}

.site-navigation {
  display: flex;
  gap: 46px;
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-60);
}

.site-navigation a {
  color: var(--ink-60);
  transition: color .25s ease, border-color .25s ease;
}

.site-navigation a:hover { color: var(--accent); }

.site-navigation a[aria-current='page'] {
  color: var(--ink);
  border-bottom: 1px solid var(--ink);
  padding-bottom: 3px;
}

.site-navigation a[aria-current='page']:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.nav-toggle {
  display: none;
  position: absolute;
  right: var(--gutter);
  top: 44px;
  border: 1px solid var(--ink);
  background: none;
  padding: 9px 15px;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  transition: background .25s ease, color .25s ease, border-color .25s ease;
}

.nav-toggle:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--paper);
}

/* ------------------------------------------------------------- marquee --- */

@keyframes ks-ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.marquee {
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
  padding: 14px 0;
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
}

/* The item set is duplicated in the markup, so -50% lands exactly on the seam. */
.marquee-track {
  display: flex;
  width: max-content;
  animation: ks-ticker 34s linear infinite;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.marquee-track span { padding-right: 40px; }

/* Not in the prototype; the handoff calls it worth adding. */
.marquee:hover .marquee-track { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* ------------------------------------------------------------- buttons --- */

.btn {
  align-self: flex-start;
  display: inline-block;
  padding: 16px 30px;
  background: var(--ink);
  color: var(--paper);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border: 1px solid var(--ink);
  cursor: pointer;
  font-family: inherit;
  transition: background .25s ease, border-color .25s ease, color .25s ease;
}

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

.btn-outline {
  background: none;
  color: var(--ink);
  padding: 16px 34px;
  font-family: var(--mono);
  letter-spacing: 0.16em;
}

.btn-outline:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--paper);
}

/* Underlined text link — "See the set →". */
.link-rule {
  align-self: flex-start;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 5px;
  transition: color .25s ease, border-color .25s ease;
}

.link-rule:hover { color: var(--accent); border-color: var(--accent); }

/* -------------------------------------------------------- spec tables ---- */

/* Mono label left, value right, 1px rule above each row and below the last. */
.spec { display: flex; flex-direction: column; }

.spec-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 20px;
  padding: 11px 0;
  border-top: 1px solid var(--rule);
  font-size: 13px;
}

.spec-row:last-child { border-bottom: 1px solid var(--rule); }

.spec-row dt,
.spec-row .spec-key {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.spec-row dd { margin: 0; text-align: right; }

/* --------------------------------------------------------------- plates -- */

/* Every image position. object-fit keeps the designed crop as the column
   narrows; the aspect-ratio is set per plate below. */
.plate {
  position: relative;
  overflow: hidden;
  background: var(--paper-alt);
}

.plate img,
.plate iframe {
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
  object-position: center;
}

.plate-caption {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding-top: 10px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Background video: muted, looping, no controls, filling the plate the way the
   poster does. A 16:9 embed is wider than any of these plates, so it is scaled
   off the plate's height and the sides crop — `--ar` carries the plate's own
   ratio so the arithmetic works for each one. Pointer events are off so the
   YouTube chrome never intercepts a click. */
/* --bg-zoom overscans the player so YouTube's title bar and watermark sit
   outside the plate entirely. `modestbranding` no longer suppresses them and
   the chrome is drawn inside the iframe, so cropping it out is the only
   reliable way to keep the plate clean. */
.plate-video iframe {
  --bg-zoom: 1.3;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: calc(100% * var(--bg-zoom));
  width: calc(100% * (16 / 9) / var(--ar) * var(--bg-zoom));
  border: 0;
  pointer-events: none;
}

/* Once the player is in, the poster underneath it is dead weight on screen —
   it stays in the DOM as the reduced-motion and no-JS fallback. */
.plate-video.is-playing img,
.plate-video.is-playing .video-poster { display: none; }

/* Click-to-load video: the poster stays until someone asks for the player, so
   a page never opens several YouTube embeds at once. Carried over from the
   previous build; the glyph is the one round corner in the design. */
.video-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.video-poster::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 62px;
  height: 62px;
  transform: translate(-50%, -50%);
  border: 1px solid var(--paper);
  border-radius: 50%;
  transition: background .25s ease, border-color .25s ease;
}

.video-poster::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  transform: translate(-32%, -50%);
  border-style: solid;
  border-width: 9px 0 9px 15px;
  border-color: transparent transparent transparent var(--paper);
}

.video-poster:hover::before {
  background: var(--accent);
  border-color: var(--accent);
}

/* ---------------------------------------------------------- card links --- */

/* Project cards: image, ink rule, serif title with mono meta right-aligned,
   then a one-line description. The whole card resolves to the accent. */
.card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  transition: color .25s ease;
}

.card:hover { color: var(--accent); }

/* `hidden` alone loses to the display rules above, so both the filtered cards
   and the exhausted "load more" button need it spelled out. */
.card[hidden],
.btn[hidden] { display: none; }

.card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--ink);
}

.card-title {
  font-family: var(--serif);
  font-size: 34px;
  line-height: 1;
}

.card-meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.7;
}

.card-note {
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-80);
}

/* The card colour transition must not drag the body copy with it, or the
   description turns terracotta too. */
.card:hover .card-note { color: inherit; }

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

.site-footer {
  padding: 72px var(--gutter) 44px;
  background: var(--ink);
  color: var(--paper);
  display: flex;
  flex-direction: column;
  gap: 44px;
}

.footer-cols {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 44px;
  align-items: start;
}

.footer-lead h2 {
  margin: 0 0 18px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 56px;
  line-height: 1.02;
  letter-spacing: -0.015em;
}

.footer-lead p {
  margin: 0;
  max-width: 380px;
  font-size: 15px;
  line-height: 1.7;
  color: var(--footer-body);
  text-wrap: pretty;
}

.footer-col {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.footer-col .label { font-size: 10px; }

.footer-col a {
  font-size: 17px;
  transition: color .25s ease;
}

/* Footer links hover to the site red like everywhere else — Kyle's call,
   21 Aug 2026, replacing the paper-grey hover the design used. The value is
   --accent-on-ink rather than --accent: the brick is 2.43:1 on this ground and
   would make a hovered link less legible than an un-hovered one. See the token. */
.footer-col a:hover { color: var(--accent-on-ink); }

.footer-bottom {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding-top: 24px;
  border-top: 1px solid var(--footer-rule);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ================================================================= HOME == */

/* No. 001 — Spotlight. No right padding: the feature image bleeds to the
   page edge, and the title sits over its left edge. */
.spotlight {
  padding: 44px 0 26px var(--gutter);
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.spotlight-frame {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.spotlight-plate {
  margin-left: 280px;
  --ar: 1.4526;                    /* 1104 / 760 */
  aspect-ratio: var(--ar);         /* 760px tall at the 1440px design width */
}

/* The title is set in ink and overlaps the plate's left edge by ~185px, where a
   dark frame swallows it. Rather than washing the image, the same letterforms
   are repeated behind it in paper, offset right and down — slightly further
   right than down, which is Kyle's call — so the type reads as though it is
   lifting off the photograph.

   text-shadow paints the identical glyphs behind the fill, so this is the
   duplicate-type approach without a second element to keep in sync or hide
   from screen readers. Zero blur keeps the copy as crisp as the type itself.

   The offset is in em rather than px so it tracks the three responsive font
   sizes without needing an override at each breakpoint. Against the paper
   margin the copy is invisible; it only appears where the title crosses the
   footage. */
.spotlight-overlay h1 {
  /*           x       y     — 3.28px / 2.688px at the 84px display size     */
  text-shadow: 0.039em 0.032em 0 var(--paper);
}

.spotlight-caption {
  margin-left: 280px;
  padding-right: var(--gutter);
}

.spotlight-overlay {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 22px;
  z-index: 3;
}

.spotlight-overlay h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 84px;
  line-height: 0.94;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

/* Features 002 / 003 — a split and its exact mirror. */
.feature {
  display: grid;
  gap: 56px;
  padding: var(--pad-section);
  align-items: center;
  border-top: 1px solid var(--rule);
}

.feature-image-left  { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
.feature-image-right { grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); }

.feature .plate {
  --ar: 1.4052;
  aspect-ratio: var(--ar);                  /* 520px tall at 1440px */
}

.feature-body {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.feature-body h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 52px;
  line-height: 1.02;
  letter-spacing: -0.01em;
}

.folio {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--muted);
}

.feature .spec { margin-top: 6px; }

/* A feature opened from the index. It arrives after the page has settled, so
   it fades itself in rather than waiting on the scroll-reveal pass. */
@keyframes ks-feature-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

.feature-slot-item {
  animation: ks-feature-in .5s cubic-bezier(.22, .61, .36, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  .feature-slot-item { animation: none; }
}

/* Explore more — a two-column printed index. */
.explore {
  padding: var(--pad-section);
  border-top: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 34px;
}

.explore-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
}

.explore-head h2 { font-size: 44px; }

.explore-head .label { letter-spacing: 0.18em; }

.index-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 56px;
}

.index-col { display: flex; flex-direction: column; }

/* Rows bleed 14px wider on both sides on hover — padding grows, margin pulls
   back by the same amount, so the rule and text stay put horizontally. */
.index-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 15px 0;
  border-top: 1px solid var(--rule);
  transition: background .3s ease, color .3s ease, padding .3s ease,
              margin .3s ease, border-color .3s ease;
}

.index-col .index-row:last-child { border-bottom: 1px solid var(--rule); }

.index-row:hover {
  background: var(--accent);
  color: var(--paper);
  padding-left: 14px;
  padding-right: 14px;
  margin-left: -14px;
  margin-right: -14px;
  border-color: var(--accent);
}

/* The row whose project is currently open above. The accent as a resting fill
   is otherwise reserved for the selected filter chip; this is the same idea —
   it marks a selection, not a hover. */
.index-row.is-open {
  background: var(--accent);
  color: var(--paper);
  padding-left: 14px;
  padding-right: 14px;
  margin-left: -14px;
  margin-right: -14px;
  border-color: var(--accent);
}

.index-row-title {
  font-family: var(--serif);
  font-size: 26px;
}

/* Inherits the row colour, so it flips to paper on hover. */
.index-row-meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.9;
}

/* =============================================================== MOTION == */

.section-hero {
  padding: var(--pad-section) var(--gutter) 34px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 56px;
  align-items: end;
}

.section-hero-body {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.section-hero p { margin: 0 0 8px; }

.reel {
  padding: 0 var(--gutter) 46px;
}

.reel-frame { position: relative; }

.reel .plate { aspect-ratio: 2.2133; }      /* 600px tall at 1440px */

/* Paper-coloured button inset 28px from the bottom-left of the plate. */
.reel-action {
  position: absolute;
  left: 28px;
  bottom: 28px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 28px 16px 20px;
  background: var(--paper);
  color: var(--ink);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  transition: background .25s ease, color .25s ease;
}

.reel-action:hover { background: var(--accent); color: var(--paper); }

.reel-action .glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid currentColor;
  font-size: 11px;
}

.film-grid {
  padding: var(--pad-section);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 56px 46px;
}

.film-grid .plate { aspect-ratio: 1.6868; }  /* 380px tall at 1440px */

/* Numbered rows — "How a shoot runs", "What I do". */
.rows-block {
  padding: 0 var(--gutter) 62px;
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 56px;
  align-items: start;
}

.rows-block-head {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.rows-block-head .label { letter-spacing: 0.16em; }

.rows { display: flex; flex-direction: column; }

.row-item {
  display: grid;
  grid-template-columns: 56px 200px 1fr;
  gap: 24px;
  align-items: baseline;
  padding: 20px 0;
  border-top: 1px solid var(--rule);
}

.rows .row-item:last-child { border-bottom: 1px solid var(--rule); }

.row-num {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
}

.row-title {
  font-family: var(--serif);
  font-size: 26px;
}

.row-body {
  font-size: 15px;
  line-height: 1.7;
  color: var(--ink-80);
}

/* ========================================================== PHOTOGRAPHY == */

.photo-hero {
  padding: var(--pad-section) var(--gutter) 30px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 56px;
}

.photo-hero-body {
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-width: 760px;
}

.photo-hero p { margin: 0 0 8px; max-width: 340px; }

/* Filter rail reads as a printed index, not as chips. */
.filter-rail {
  padding: 0 var(--gutter) 26px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 30px;
  border-bottom: 1px solid var(--ink);
}

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.filters button {
  padding: 0 0 5px;
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--ink-45);
  transition: color .25s ease, border-color .25s ease;
}

.filters button:hover { color: var(--accent); }

.filters button[aria-pressed='true'] {
  color: var(--ink);
  border-bottom: 1px solid var(--ink);
}

.filters button[aria-pressed='true']:hover { border-color: var(--accent); }

.filter-rail .label { letter-spacing: 0.16em; }

/* Contact sheet — a matched grid, the way the original site ran its galleries:
   even gutters, no feature sizes and no staggering. Six columns is the common
   denominator, so a portrait frame spans two (three to a row, 3:4) and a
   landscape frame spans three (two to a row, 4:3). Orientation is read off the
   files at build time, so the rhythm follows the pictures rather than a
   hard-coded list. */
.contact-sheet {
  padding: 44px var(--gutter);
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 44px 30px;
}

.contact-sheet .card { gap: 10px; grid-column: span 2; }

.contact-sheet .card.is-wide { grid-column: span 3; }

.contact-sheet .plate { aspect-ratio: 3 / 4; }

.contact-sheet .is-wide .plate { aspect-ratio: 4 / 3; }

.load-more {
  padding: 0 var(--gutter) 62px;
  display: flex;
  justify-content: center;
}

/* ================================================================ ABOUT == */

.about-split {
  padding: var(--pad-section) var(--gutter) 46px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: 56px;
  align-items: center;
}

.about-portrait {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Portrait orientation — 820px tall at the design width. */
.about-portrait .plate { aspect-ratio: 0.7051; }

.about-body {
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.about-body h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 52px;
  line-height: 1.1;
  letter-spacing: -0.015em;
}

.about-body p {
  margin: 0;
  max-width: 540px;
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink-80);
  text-wrap: pretty;
}

.about-body .btn { margin-top: 6px; }

/* "What I do" gives its title column 240px rather than Motion's 200px. */
/* "What I do" is the one rows block that follows the marquee rather than a
   section with its own bottom padding, so it needs a top of its own — the
   design gives it 56px all round where the others open at 0. */
.rows-wide { padding-top: var(--pad-section); }

.rows-wide .row-item { grid-template-columns: 56px 240px 1fr; padding: 22px 0; }

.rows-wide .row-title { font-size: 28px; }

.client-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0 46px;
}

.client-list li {
  list-style: none;
  padding: 14px 0;
  border-top: 1px solid var(--rule);
  font-family: var(--serif);
  font-size: 24px;
}

.client-list { margin: 0; padding-left: 0; }

/* ============================================================== CONTACT == */

.contact-split {
  padding: var(--pad-section) var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: 72px;
  align-items: start;
}

.contact-body {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.contact-body h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 78px;
  line-height: 0.96;
  letter-spacing: -0.02em;
}

.contact-body > p { margin: 0; max-width: 420px; }

.contact-details { margin-top: 6px; }

.contact-details .spec-row { padding: 15px 0; }

.contact-details dd,
.contact-details .spec-val {
  font-family: var(--serif);
  font-size: 22px;
}

.contact-details a { transition: color .25s ease; }

.contact-details a:hover { color: var(--accent); }

.social-row {
  display: flex;
  flex-wrap: wrap;
  gap: 26px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.social-row a { color: var(--ink-45); transition: color .25s ease; }

.social-row a:hover { color: var(--accent); }

/* Inquiry form — an inset panel on the alternate paper stock. */
.inquiry {
  background: var(--paper-alt);
  padding: 44px;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.inquiry > .label { color: var(--ink-45); }

.field-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.field > span,
.chip-group > span {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Underline-only inputs: no box, no outline on focus — the rule darkens to ink. */
.inquiry input,
.inquiry textarea {
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  padding: 11px 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--field-rule);
  color: var(--ink);
  outline: none;
  transition: border-color .25s ease;
}

/* Text fields keep the design's underline-only treatment rather than taking the
   ring — browsers count a click into a text field as focus-visible, and a ring
   on click would undo the point of the inset panel. The underline doubles and
   goes to ink, which is a clear indicator on its own. */
.inquiry input:focus-visible,
.inquiry textarea:focus-visible { outline: none; }

.inquiry input:focus,
.inquiry textarea:focus {
  border-bottom-width: 2px;
  border-bottom-color: var(--ink);
  padding-bottom: 10px;      /* hold the baseline as the rule thickens */
}

.inquiry textarea { resize: vertical; }

.inquiry ::placeholder { color: var(--muted); }

.chips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* The one place the accent is not hover-only: the selected chip. */
.chip {
  padding: 9px 15px;
  border: 1px solid var(--field-rule);
  background: none;
  color: var(--ink-80);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .25s ease, color .25s ease, border-color .25s ease;
}

.chip[aria-pressed='true'] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.chip:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--paper);
}

.chip-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

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

.form-notice[hidden] { display: none; }

/* Netlify's spam honeypot — must exist in the DOM but never be seen. */
.form-hp { display: none; }

.closing-plate {
  padding: 0 var(--gutter) 62px;
}

.closing-plate .plate { aspect-ratio: 3.6889; }   /* 360px tall at 1440px */

/* ======================================================= PROJECT DETAIL == */

.breadcrumb {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  padding: 14px var(--gutter);
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.breadcrumb a { transition: color .25s ease; }

.breadcrumb a:hover { color: var(--accent); }

.breadcrumb-here { color: var(--ink); }

.breadcrumb-trail,
.breadcrumb-pager { display: flex; gap: 10px; }

.breadcrumb-pager { gap: 22px; }

.project-head {
  padding: var(--pad-section) var(--gutter) 36px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: 72px;
  align-items: end;
}

.project-head-body {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.project-head h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 96px;
  line-height: 0.92;
  letter-spacing: -0.025em;
}

.project-head p {
  margin: 0;
  max-width: 620px;
  font-size: 17px;
  line-height: 1.7;
  color: var(--ink-80);
  text-wrap: pretty;
}

/* Lead plate bleeds to the right edge, so no right padding. */
.project-lead {
  padding: 0 0 12px var(--gutter);
}

.project-lead .plate { aspect-ratio: 1.9222; }    /* 720px tall at 1440px */

.project-lead .plate-caption { padding-right: var(--gutter); }

.two-up {
  padding: 46px var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 36px;
}

.two-up figure {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.two-up figure:nth-child(2) { padding-top: 64px; }

.two-up .plate { aspect-ratio: 1.2423; }          /* 520px tall at 1440px */

.set-notes {
  padding: 0 var(--gutter) 46px;
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 56px;
  align-items: start;
}

.set-notes p {
  margin: 0;
  max-width: 760px;
  font-family: var(--serif);
  font-size: 30px;
  line-height: 1.3;
  letter-spacing: -0.01em;
  text-wrap: pretty;
}

.wide-plate {
  padding: 0 var(--gutter) 56px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.wide-plate .plate { aspect-ratio: 2.075; }       /* 640px tall at 1440px */

.wide-plate .plate-caption { padding-top: 0; }

.three-up {
  padding: 0 var(--gutter) 56px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 26px;
}

.three-up .plate { aspect-ratio: 1.4178; }        /* 300px tall at 1440px */

/* The whole next-project row flips to the accent. */
.next-project {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 400px;
  gap: 56px;
  align-items: center;
  padding: 46px var(--gutter);
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  transition: background .3s ease, color .3s ease;
}

.next-project:hover { background: var(--accent); color: var(--paper); }

.next-project-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.next-project .label,
.next-project .caption { color: inherit; opacity: 0.75; }

.next-project-title {
  font-family: var(--serif);
  font-size: 64px;
  line-height: 1;
  letter-spacing: -0.02em;
}

.next-project .plate { aspect-ratio: 1.8182; }    /* 220px tall at 1440px */

/* ================================================================== 404 == */

/* Written as a page of the magazine rather than an error screen, so it uses
   the same measure and rhythm as a section hero. */
/* Shared by 404 and the form confirmations: a page that is one statement,
   a line of explanation, and the way onward. */
/* The emphasised tail of a section headline is a phrase, not a run of words:
   letting it break strands the last word on a line of its own. Keeping it
   whole makes the line break fall at the comma, where the sentence wants it. */
.section-hero .h1 em,
.photo-hero .h1 em { white-space: nowrap; }

.notfound,
.thanks {
  padding: 92px var(--gutter) 72px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
  max-width: 900px;
}

.notfound h1,
.thanks h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 78px;
  line-height: 0.98;
  letter-spacing: -0.02em;
}

.notfound p,
.thanks p { max-width: 460px; }

/* Inline links inside body copy. The site had none until the inquiry
   confirmation named a phone number — every other link is a nav item, a button,
   a footer column or a .link-rule, and the global rule is
   `a { color: inherit; text-decoration: none }`. A number that renders as plain
   body text is a number nobody taps, so prose links carry a hairline underline
   and resolve to the accent like every other link on paper. */
.lede a {
  text-decoration: underline;
  text-decoration-color: var(--field-rule);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.lede a:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
}

.notfound-links {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px 34px;
  margin-top: 14px;
}

.notfound-links .link-rule { align-self: center; }

@media (max-width: 767px) {
  .notfound,
  .thanks { padding: 56px var(--gutter) 44px; }
  .notfound h1,
  .thanks h1 { font-size: 44px; }
}

/* ============================================================ POSTCARDS == */

/* Unlisted page kept from the previous build — restyled onto Field Notes so
   it does not sit outside the system. Form behaviour is unchanged: it still
   posts through Netlify Forms. */
.postcards {
  padding: var(--pad-section) var(--gutter) 62px;
  display: flex;
  flex-direction: column;
  gap: 34px;
}

.postcards-head {
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-width: 620px;
}

.postcards .plate { aspect-ratio: 2500 / 1385; }

.pc-form {
  max-width: 620px;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.pc-field { border: 0; margin: 0; padding: 0; }

.pc-legend,
.pc-sub > span {
  display: block;
  margin-bottom: 8px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.pc-req, .pc-desc { color: var(--muted); }

.pc-desc {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  margin-bottom: 10px;
}

/* Netlify's spam honeypot — must exist in the DOM but never be seen. */
.pc-hp { display: none; }

.pc-row { display: grid; gap: 22px; }

.pc-row-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.pc-row-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.pc-sub { display: block; margin-bottom: 16px; }

.pc-form input,
.pc-form select,
.pc-form textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: 16px;
  padding: 11px 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--field-rule);
  border-radius: 0;
  color: var(--ink);
  outline: none;
  transition: border-color .25s ease;
}

.pc-form input:focus-visible,
.pc-form select:focus-visible,
.pc-form textarea:focus-visible { outline: none; }

.pc-form input:focus,
.pc-form select:focus,
.pc-form textarea:focus {
  border-bottom-width: 2px;
  border-bottom-color: var(--ink);
  padding-bottom: 10px;
}

.pc-form textarea { resize: vertical; min-height: 96px; line-height: 1.6; }

.pc-form ::placeholder { color: var(--muted); }

.pc-section {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 8px 0;
}

.pc-notice {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--accent);
}

/* --------------------------------------------------------- scroll reveal - */

/* Applied by script so that a no-JS visitor never gets a blank page; the
   handoff's curve and distance, unobserved after firing. */
.reveal-ready {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s cubic-bezier(.22, .61, .36, 1),
              transform .7s cubic-bezier(.22, .61, .36, 1);
}

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

@media (prefers-reduced-motion: reduce) {
  .reveal-ready { opacity: 1; transform: none; transition: none; }
}

/* ------------------------------------------------------------ responsive - */

/* Mobile was not designed. These are the handoff's stated safe defaults:
   collapse the multi-column grids, scale the display type down, drop the
   deliberate vertical staggers, and keep the double rule. */

@media (max-width: 1180px) {
  .h1 { font-size: 72px; }
  .spotlight-overlay h1 { font-size: 64px; }
  .project-head h1 { font-size: 76px; }
  .contact-body h1 { font-size: 64px; }
  .footer-lead h2 { font-size: 44px; }
  .next-project-title { font-size: 52px; }
  .site-navigation { gap: 32px; }
  .rows-block,
  .set-notes { grid-template-columns: 240px 1fr; gap: 36px; }
  .row-item { grid-template-columns: 44px 160px 1fr; }
  .rows-wide .row-item { grid-template-columns: 44px 180px 1fr; }
}

@media (max-width: 900px) {
  :root { --gutter: 32px; --pad-section: 44px; }

  .section-hero,
  .feature-image-left,
  .feature-image-right,
  .about-split,
  .contact-split,
  .project-head,
  .two-up,
  .rows-block,
  .set-notes,
  .next-project,
  .footer-cols,
  .index-cols {
    grid-template-columns: 1fr;
    gap: 36px;
  }

  /* Mirror layouts collapse to image-then-text in both directions. */
  .feature-image-right .plate { order: -1; }

  /* Everything steps down one: portrait goes two to a row, landscape one. */
  .contact-sheet .card { grid-column: span 3; }
  .contact-sheet .card.is-wide { grid-column: span 6; }

  .three-up { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }

  .client-list { grid-template-columns: repeat(2, 1fr); }

  /* The deliberate offset reads as a mistake once stacked. */
  .two-up figure:nth-child(2) { padding-top: 0; }

  .index-cols { column-gap: 0; }

  /* Homepage spotlight: title above the plate rather than over it. */
  .spotlight { padding: 34px var(--gutter) 26px; }
  .spotlight-plate,
  .spotlight-caption { margin-left: 0; }
  .spotlight-caption { padding-right: 0; }
  /* The overlay is last in the source so it paints over the plate. Stacked, the
     handoff wants the title above the image, so pull it back to the top. */
  .spotlight-overlay {
    position: static;
    transform: none;
    order: -1;
    margin-bottom: 4px;
  }

  /* Stacked, the title sits on paper rather than over the plate, so a
     paper-coloured copy behind it has nothing to do. */
  .spotlight-overlay h1 { text-shadow: none; }
  .spotlight-overlay h1 { white-space: normal; }

  .project-lead { padding: 0 var(--gutter) 12px; }
  .project-lead .plate-caption { padding-right: 0; }

  .photo-hero { flex-direction: column; align-items: flex-start; gap: 24px; }
  .photo-hero p { max-width: none; }

  .filter-rail { flex-direction: column; align-items: flex-start; gap: 16px; }
  .filters { gap: 20px; }

  .masthead-rail { font-size: 10px; letter-spacing: 0.1em; gap: 12px; }
}

@media (max-width: 767px) {
  :root { --gutter: 20px; }

  .h1,
  .spotlight-overlay h1,
  .project-head h1,
  .contact-body h1 { font-size: 44px; line-height: 1; }

  .h2,
  .explore-head h2,
  .feature-body h2,
  .footer-lead h2 { font-size: 32px; }

  .about-body h1 { font-size: 34px; }

  .card-title { font-size: 26px; }

  .next-project-title { font-size: 36px; }

  .set-notes p { font-size: 22px; }

  .masthead { padding: 20px var(--gutter); }

  .masthead .logo img { height: 34px; }

  .nav-toggle { display: block; top: 20px; right: var(--gutter); }

  /* Wrapped two-row list rather than a drawer, so the double rule still
     closes the block. Tap targets stay at 44px. */
  .site-navigation {
    display: none;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px 24px;
  }

  .site-navigation.open { display: flex; }

  .site-navigation a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  /* Stacked and flush left — there is no centring to do when each item has the
     row to itself. `flex-direction` would be ignored now the rail is a grid, so
     the stack comes from collapsing to one column. */
  .masthead-rail {
    grid-template-columns: 1fr;
    justify-items: start;
    gap: 4px;
  }

  .masthead-rail > :last-child { justify-self: start; text-align: left; }

  .film-grid,
  .three-up { grid-template-columns: 1fr; gap: 26px; }

  /* One frame to a row, whichever way it runs. */
  .contact-sheet { gap: 26px; }
  .contact-sheet .card,
  .contact-sheet .card.is-wide { grid-column: span 6; }

  .client-list { grid-template-columns: 1fr; }

  .field-pair,
  .pc-row-2,
  .pc-row-3 { grid-template-columns: 1fr; }

  .inquiry { padding: 26px 20px; }

  .row-item,
  .rows-wide .row-item {
    grid-template-columns: 34px 1fr;
    gap: 6px 16px;
  }

  .row-body { grid-column: 2; }

  .reel-action { left: 12px; bottom: 12px; padding: 12px 18px 12px 14px; gap: 12px; }

  .btn, .btn-outline { min-height: 44px; }

  .footer-bottom { flex-direction: column; gap: 8px; }

  .breadcrumb { flex-direction: column; align-items: flex-start; gap: 10px; }
}
