/* ==========================================================================
   victoriaprobert.com — black / red / white, editorial

   One spacing system for every page:
     --margin-page-side     left/right page margin (grows to centre content past --container-max)
     --margin-page-top      distance from the top of the page to the first headline
     --margin-section  gap between major sections / blocks
     --space-block    gap inside a section (head to body, hero to text)
     --space-media    gap around media blocks, stats, press, awards
     --space-column-gap  grid column gap
     --space-row      padding of list rows
   Every text block starts at the same left edge; body text columns share
   the 12-column grid (labels 1–3, text 4–11).
   ========================================================================== */
:root {
  /* colour */
  --color-background: #000;
  --color-surface: #0b0b0b;
  --color-text: #fff;
  --color-text-secondary: rgba(255,255,255,.74);
  --color-text-tertiary: rgba(255,255,255,.46);
  --color-rule: rgba(255,255,255,.16);
  --color-rule-subtle: rgba(255,255,255,.08);
  --color-accent: #E14444;   /* brand red, brightened from #D32F2F (Nov 2026) so small red labels pass contrast on black (5.1:1) */
  --color-accent-hover: #ff5a4f;

  /* type families */
  --font-family-display: "Playfair Display", "Freight Big Pro", Georgia, serif;
  /* serif = editorial and expressive (headlines, project titles, statements, big numbers); sans = information, reading and interface */
  --font-family-body: "Instrument Sans", "Inter", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;   /* body copy and values; the red sub-heds, nav and labels stay in Inter */
  --font-weight-body: 400;
  --font-family-ui: "Inter", "Freight Sans Pro", system-ui, -apple-system, Helvetica, Arial, sans-serif;

  /* type scale */
  --font-size-h1: clamp(44px, 7.2vw, 108px);
  --font-size-h1-hero: clamp(42px, 7.2vw, 108px);
  --font-size-h1-essay: clamp(40px, 6.4vw, 84px);
  --font-size-h2-list: clamp(26px, 3.4vw, 46px);
  --font-size-h2-next: clamp(30px, 4vw, 64px);
  --font-size-h2-row: clamp(26px, 3vw, 44px);
  --font-size-h2-card: clamp(24px, 2.4vw, 36px);
  --font-size-h3-more: clamp(20px, 2vw, 28px);
  --font-size-lede: clamp(17px, 1.3vw, 20px);
  --font-size-intro: clamp(22px, 1.9vw, 30px);
  --font-size-quote: clamp(22px, 2.2vw, 34px);
  --font-size-stat: clamp(38px, 4vw, 60px);
  --font-size-tagline: clamp(16px, 1.4vw, 21px);
  --font-size-body: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);   /* body copy: 16px on phones easing to 18px on desktop; never below 1rem */
  --font-size-body-essay: clamp(17px, 1.25vw, 19px);
  --font-size-contact: clamp(28px, 4vw, 60px);
  --font-size-testimonial: clamp(20px, 1.7vw, 25px);
  --font-size-strap: clamp(15px, 1.25vw, 19px);
  --font-size-h2-list-mobile: clamp(26px, 6.8vw, 36px);
  --font-size-tagline-essay: clamp(17px, 1.4vw, 20px);
  --font-size-ui: 11.5px;
  --font-size-caption: 12px;
  --font-size-meta: 13px;
  --font-size-small: 16px;
  --font-size-base: 16px;
  --letter-spacing-ui: .14em;
  --line-height-body: 1.5;

  /* layout */
  --container-max: 1440px;
  --space-page-gutter: clamp(20px, 3.2vw, 48px);
  --margin-page-side: max(var(--space-page-gutter), calc((100% - var(--container-max)) / 2));
  --margin-page-top: clamp(120px, 18vh, 200px);
  --margin-section: clamp(48px, 6vw, 96px);
  --space-block: clamp(32px, 4vw, 56px);
  --section-space: var(--space-block);   /* one rule for every case-study section: the same space above and below its content */
  --space-media: clamp(28px, 3.6vw, 48px);
  --space-column-gap: clamp(16px, 2.2vw, 32px);
  --space-gallery-gap: clamp(8px, 1.2vw, 16px);
  --space-row: 16px;
  --measure-body: 65ch;
  --motion-ease: cubic-bezier(.2,.7,.2,1);
}
* { box-sizing: border-box; }
html { background: var(--color-background); color: var(--color-text); -webkit-text-size-adjust: 100%; }
html.smooth { scroll-behavior: smooth; }   /* enabled by site.js after load, so a #fragment on arrival jumps instantly */
@media (prefers-reduced-motion: reduce) { html.smooth { scroll-behavior: auto; } }
body {
  margin: 0; font-family: var(--font-family-body); font-weight: var(--font-weight-body); font-size: var(--font-size-base); line-height: 1.6;
  font-feature-settings: "kern", "liga";
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  min-height: 100svh; display: flex; flex-direction: column;
}
b, strong { font-weight: 600; }   /* bold reads as bold against the light body weight */
main { flex: 1 0 auto; }
a { color: inherit; text-decoration: none; }
img, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; border-radius: 2px; }   /* one keyboard focus ring site-wide: shows only for keyboard focus, never on tap or click */
::selection { background: var(--color-accent); color: #fff; }
.nobr { white-space: nowrap; }   /* build.py wraps hyphenated phrases in this so they never break at a hyphen */
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip { position: absolute; left: -999px; top: 8px; background: var(--color-accent); color: #fff; padding: 8px 12px; font-family: var(--font-family-ui); font-size: 13px; z-index: 100; }
.skip:focus { left: 8px; }

/* every page-width block shares the same side margins */
.top, .foot-in, .stage, .page-head, .grid-list, .more, .essay-list, .hero-text, .credits, .body, .next, .essay-wrap, .info-head {
  padding-left: var(--margin-page-side); padding-right: var(--margin-page-side); width: 100%;
}

/* type helpers */
.lab, .k, .nav a, .credits .lab, .strap .meta, .press .lab, .awards .lab, .cv .dates, .more .lab {
  font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; font-weight: 500;
}
.k i, .cap .k i, .hero-text .k i { font-style: normal; color: var(--color-accent); padding: 0 .15em; }
.display { font-family: var(--font-family-display); font-weight: 400; letter-spacing: -.012em; line-height: .98; margin: 0; text-wrap: balance; }
.head-intro { font-family: var(--font-family-body); font-size: var(--font-size-body); line-height: var(--line-height-body); color: var(--color-text-secondary); max-width: var(--measure-body); margin: 1.1em 0 0; }
.lede { font-family: var(--font-family-body); font-size: var(--font-size-lede); line-height: 1.45; color: var(--color-text-secondary); max-width: var(--measure-body); margin: 1.2em 0 0; text-wrap: pretty; }   /* no single word left alone on the last line */
.pilcrow { color: var(--color-accent); font-family: var(--font-family-display); font-style: italic; }
.foot-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--color-accent); vertical-align: middle; margin: -2px 6px 0 0; }
.dim { color: var(--color-text-tertiary); }

/* ---------- light theme (site.yml: theme: light) ---------- */
html[data-theme="light"] {
  --color-background: #fff;
  --color-surface: #f2f2f2;
  --color-text: #000;
  --color-text-secondary: rgba(0,0,0,.72);
  --color-text-tertiary: rgba(0,0,0,.46);
  --color-rule: rgba(0,0,0,.14);
  --color-rule-subtle: rgba(0,0,0,.07);
  --color-accent: #D32F2F;   /* on white the original red already passes (4.8:1); the brighter one wouldn't */
  --color-accent-hover: #b71c1c;
}
html[data-theme="light"] .top::before { background: linear-gradient(to bottom, rgba(255,255,255,.75), rgba(255,255,255,.35) 45%, rgba(255,255,255,0)); }
html[data-theme="light"] .top.is-solid { background: rgba(255,255,255,.86); }
html[data-theme="light"] .reel { background: #fff; }
html[data-theme="light"] .reel .scrim { background:
  linear-gradient(to right, rgba(255,255,255,.78) 0%, rgba(255,255,255,.4) 45%, rgba(255,255,255,.06) 100%),
  linear-gradient(to top, rgba(255,255,255,.8) 0%, rgba(255,255,255,0) 40%); }
html[data-theme="light"] .hero { background: #fff; }
html[data-theme="light"] .hero::after { background: linear-gradient(to top, rgba(255,255,255,.86) 0%, rgba(255,255,255,.3) 38%, rgba(255,255,255,0) 65%); }
html[data-theme="light"] .sound { border-color: rgba(0,0,0,.4); background: rgba(255,255,255,.55); }
@media (max-width: 700px) {
  html[data-theme="light"] .reel .scrim { background: linear-gradient(to top, rgba(255,255,255,.92) 0%, rgba(255,255,255,.5) 55%, rgba(255,255,255,.18) 100%); }
}

/* ---------- lightbox ---------- */
.lb-zoom { cursor: zoom-in; }
body.lb-open { overflow: hidden; }
.lightbox { position: fixed; inset: 0; z-index: 200; background: rgba(0,0,0,.94); display: grid; place-items: center; opacity: 0; transition: opacity .22s var(--motion-ease); cursor: zoom-out; }
.lightbox[hidden] { display: none; }   /* keep the closed overlay out of the way of clicks */
.lightbox.is-on { opacity: 1; }
.lightbox figure { margin: 0; max-width: 94vw; max-height: 94vh; display: grid; gap: 12px; justify-items: center; }
.lightbox img, .lightbox video { display: block; max-width: 94vw; max-height: 94vh; width: auto; height: auto; object-fit: contain; box-shadow: 0 30px 80px rgba(0,0,0,.6); }
.lightbox video { width: min(94vw, calc(94vh * 1.4)); cursor: zoom-out; }
.lightbox.is-film video { width: auto; max-width: 94vw; cursor: auto; background: #000; }   /* a film from a carousel: its own shape (wide or upright), with its play bar */
.lightbox [hidden] { display: none; }
.head-media video[loop] { cursor: zoom-in; }
.lightbox figcaption { font-family: var(--font-family-ui); font-size: var(--font-size-caption); letter-spacing: .04em; color: rgba(255,255,255,.7); text-align: center; min-height: 1em; }
.lightbox figcaption:empty { display: none; }
.lightbox button { position: absolute; background: none; border: 0; color: #fff; cursor: pointer; font-family: var(--font-family-display); line-height: 1; opacity: .7; transition: opacity .2s; padding: 14px; }
.lightbox button:hover, .lightbox button:focus-visible { opacity: 1; outline: none; }
.lightbox .lb-close { top: 14px; right: 18px; font-size: 40px; }
/* previous / next: the site's ringed chevron, exactly as on the hero scroll arrow (.hero-more) and back-to-top (.to-top), turned sideways */
.lightbox .lb-prev, .lightbox .lb-next { top: 50%; transform: translateY(-50%); width: 40px; height: 40px; padding: 0; border-radius: 50%; border: 1px solid rgba(255,255,255,.55); background: rgba(0,0,0,.35); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); opacity: 1; display: inline-flex; align-items: center; justify-content: center; transition: border-color .2s, background .2s; }
.lightbox .lb-prev svg, .lightbox .lb-next svg { width: 9px; height: 14px; fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); transition: stroke .2s; }
.lightbox .lb-prev:hover, .lightbox .lb-next:hover, .lightbox .lb-prev:focus-visible, .lightbox .lb-next:focus-visible { border-color: var(--color-accent); background: rgba(0,0,0,.5); }
.lightbox .lb-prev:hover svg, .lightbox .lb-next:hover svg, .lightbox .lb-prev:focus-visible svg, .lightbox .lb-next:focus-visible svg { stroke: var(--color-accent-hover); }
.lightbox .lb-prev { left: 18px; } .lightbox .lb-next { right: 18px; }
.lightbox.single .lb-prev, .lightbox.single .lb-next { display: none; }
@media (max-width: 700px) {
  /* phones: the pair sits centred directly under the picture, like the carousel arrows do at narrow widths */
  .lightbox:not(.is-tall) { grid-template-columns: auto auto; grid-template-rows: auto auto; align-content: center; justify-content: center; column-gap: 8px; row-gap: 18px; }
  .lightbox:not(.is-tall) figure { grid-row: 1; grid-column: 1 / -1; max-height: 78vh; }
  .lightbox:not(.is-tall) img, .lightbox:not(.is-tall) video { max-height: 78vh; }
  .lightbox:not(.is-tall) .lb-prev, .lightbox:not(.is-tall) .lb-next { position: static; transform: none; grid-row: 2; }
  .lightbox:not(.is-tall) .lb-prev { grid-column: 1; justify-self: end; }
  .lightbox:not(.is-tall) .lb-next { grid-column: 2; justify-self: start; }
  .lightbox.single:not(.is-tall) { grid-template-columns: 1fr; }
  .lightbox.is-tall .lb-prev, .lightbox.is-tall .lb-next { top: auto; bottom: calc(14px + env(safe-area-inset-bottom)); transform: none; left: 50%; right: auto; }
  .lightbox.is-tall .lb-prev { margin-left: -48px; } .lightbox.is-tall .lb-next { margin-left: 4px; }
}

/* ---------- header ---------- */
.top {
  position: fixed; inset: 0 0 auto 0; z-index: 50; display: flex; align-items: center; justify-content: space-between;
  padding-top: 36px; padding-bottom: 18px; transition: transform .5s var(--motion-ease), background .4s;
}
.top { pointer-events: none; } .top > * { pointer-events: auto; }   /* the header's empty strip lets taps through (e.g. to a hero's Watch with sound just below it); only its logo, links and MENU catch them */
.top::before { content: ""; position: absolute; inset: 0 0 auto 0; height: calc(100% + 70px); z-index: -1; pointer-events: none; background: linear-gradient(to bottom, rgba(0,0,0,.62) 0%, rgba(0,0,0,.34) 45%, rgba(0,0,0,.1) 78%, rgba(0,0,0,0) 100%); transition: opacity .4s; }   /* a light fade to black over the full-bleed hero, so the nav stays legible */
.top.is-solid { background: rgba(0,0,0,.82); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }   /* only once the hero has scrolled away */
.top.is-solid::before { opacity: 0; }
.top.is-hidden { transform: translateY(-110%); }
.wordmark { display: inline-flex; align-items: center; justify-content: center; width: 66px; height: 66px; border-radius: 50%; background: #fff; flex: none; box-shadow: 0 1px 3px rgba(0,0,0,.05), 0 4px 14px rgba(0,0,0,.05); }   /* a 5% shadow: lifts the logo off bright heroes, disappears into the dark fade */
.wordmark img { display: block; width: 45px; height: auto; }   /* two 5% steps up from 41 (Nov 2026) */
.nav { display: flex; gap: clamp(14px, 2.2vw, 36px); flex-wrap: wrap; justify-content: flex-end; row-gap: 2px; }
.sec[id] { scroll-margin-top: 114px; }
.info-body h3 { margin-top: var(--space-block); }
.info-body .awards { margin-top: 0; padding-top: 0; border-top: 0; }   /* the section label already introduces it */
.info-body .awards .lab { display: none; }
.nav a { position: relative; padding: 6px 0; color: var(--color-text-secondary); transition: color .25s; }
.nav a:hover, .nav a[aria-current="page"] { color: var(--color-text); }
.nav a::after { content: ""; position: absolute; left: 0; right: 100%; bottom: 2px; height: 1px; background: var(--color-accent); transition: right .35s var(--motion-ease); }
.nav a:hover::after, .nav a[aria-current="page"]::after { right: 0; }
/* Work menu: hovering WORK lists every project underneath in small type, so nobody has to scroll the Work page */
.nav-work { position: relative; display: inline-flex; align-items: center; gap: 6px; }
.work-chev { width: 9px; height: 6px; fill: none; stroke: var(--color-text-secondary); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: transform .25s var(--motion-ease), stroke .25s; }   /* a little chevron: there's a list under WORK */
.nav-work:hover .work-chev, .nav-work:focus-within .work-chev { transform: rotate(180deg); stroke: var(--color-text); }
.work-menu { position: absolute; top: calc(100% + 14px); left: -28px; z-index: 2; width: max-content; opacity: 0; visibility: hidden; transform: translateY(-3px); transition: opacity .18s ease, transform .18s ease, visibility 0s .18s; }   /* a narrow, contained index hung under WORK */
.nav-work:hover .work-menu, .nav-work:focus-within .work-menu { opacity: 1; visibility: visible; transform: none; transition: opacity .18s ease, transform .18s ease, visibility 0s; }
.nav-work > a::before { content: ""; position: absolute; left: -12px; right: -28px; top: 100%; height: 26px; }   /* an invisible bridge from WORK down to the list, so the hover holds */
.work-menu-in { display: block; padding: 20px 24px 22px; background: rgba(10,10,10,.9); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border-radius: 8px; box-shadow: 0 18px 44px rgba(0,0,0,.35); }   /* no border: a soft, translucent panel */
.work-menu-list { display: flex; flex-direction: column; }   /* one column: an index read top to bottom */
.work-col { display: contents; }
.nav .work-menu a { position: relative; align-self: flex-start; }   /* each row is as wide as its title */
.nav .work-menu a .meta { position: absolute; left: 100%; top: 0; bottom: 0; display: flex; align-items: center; gap: 8px; padding-left: 12px; white-space: nowrap; pointer-events: none; }   /* client and arrow take no width until they appear, so the panel hugs the titles */
.nav .work-menu a { display: flex; align-items: baseline; gap: 10px; padding: 4px 0; white-space: nowrap; letter-spacing: 0; text-transform: none; color: rgba(236,232,224,.82); transition: opacity .18s; }   /* warm ivory at rest */
.work-menu-list:has(> a:hover, > a:focus-visible, > .wm-folder:hover, > .wm-folder:focus-within) > :is(a, .wm-folder):not(:hover):not(:focus-visible):not(:focus-within) { opacity: .5; }   /* hovering one client quietly recedes the rest */
.wm-sub-in:has(a:hover, a:focus-visible) a:not(:hover):not(:focus-visible) { opacity: .5; }
.wm-folder { display: block; transition: opacity .18s; }   /* a client with several projects: hovering it opens them underneath, indented */
.wm-lab { display: flex; align-items: center; gap: 9px; padding: 4px 0; cursor: default; outline: none; color: rgba(236,232,224,.82); }
.nav .work-menu .wm-lab .t { font-family: var(--font-family-body); font-size: 13px; font-weight: 400; letter-spacing: -.005em; line-height: 1.35; transition: color .18s, transform .18s var(--motion-ease); }
.wm-chev { width: 5px; height: 8px; flex: none; fill: none; stroke: var(--color-text-tertiary); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: stroke .18s, transform .25s var(--motion-ease); }   /* a small chevron marks a folder; it turns down as the folder opens */
.wm-folder:hover .wm-lab .t, .wm-folder:focus-within .wm-lab .t { color: #fff; transform: translateX(5px); }
.wm-folder:hover .wm-chev, .wm-folder:focus-within .wm-chev { stroke: var(--color-accent); transform: translateX(5px) rotate(90deg); }
.wm-sub { display: grid; grid-template-rows: 0fr; opacity: 0; visibility: hidden; transition: grid-template-rows .25s var(--motion-ease), opacity .18s ease, visibility 0s .25s; }
.wm-folder:hover .wm-sub, .wm-folder:focus-within .wm-sub { grid-template-rows: 1fr; opacity: 1; visibility: visible; transition: grid-template-rows .25s var(--motion-ease), opacity .18s ease .05s, visibility 0s; }
.wm-sub-in { display: flex; flex-direction: column; min-height: 0; overflow: hidden; padding-left: 17px; }   /* indented under the client's name */
.nav .work-menu .wm-sub a { color: var(--color-text-secondary); }
.nav .work-menu .wm-sub a:hover .t, .nav .work-menu .wm-sub a:focus-visible .t { color: #fff; }
.wm-folder:hover .wm-sub-in a:last-child, .wm-folder:focus-within .wm-sub-in a:last-child { margin-bottom: 4px; }
html[data-theme="light"] .wm-lab { color: rgba(0,0,0,.78); } html[data-theme="light"] .wm-folder:hover .wm-lab .t, html[data-theme="light"] .nav .work-menu .wm-sub a:hover .t { color: #000; }
.nav .work-menu a::after { display: none; }
.nav .work-menu a .t { font-family: var(--font-family-body); font-size: 13px; font-weight: 400; letter-spacing: -.005em; line-height: 1.35; transition: color .18s, transform .18s var(--motion-ease); }
.nav .work-menu a .k { font-family: var(--font-family-body); font-size: 13px; font-weight: 400; letter-spacing: -.005em; text-transform: none; color: var(--color-text-tertiary); opacity: 0; transform: translateX(-6px); transition: opacity .18s, transform .18s var(--motion-ease); }
.nav .work-menu a .arr { color: var(--color-accent); font-family: var(--font-family-body); font-size: 13px; opacity: 0; transform: translateX(-4px); transition: opacity .18s, transform .18s var(--motion-ease); }
.nav .work-menu a:hover .t, .nav .work-menu a:focus-visible .t { color: #fff; transform: translateX(5px); }
.nav .work-menu a:hover .k, .nav .work-menu a:focus-visible .k, .nav .work-menu a:hover .arr, .nav .work-menu a:focus-visible .arr { opacity: 1; transform: translateX(5px); }   /* on hover: the title steps in, the client and a red arrow appear beside it */
html[data-theme="light"] .work-menu-in { background: rgba(255,255,255,.9); box-shadow: 0 18px 44px rgba(0,0,0,.12); } html[data-theme="light"] .nav .work-menu a { color: rgba(0,0,0,.78); }
html[data-theme="light"] .nav .work-menu a:hover .t { color: #000; }
@media (hover: none) { .work-menu, .work-chev { display: none; } }
@media (hover: none) { .menu-btn:focus-visible, .mnav-close:focus-visible { outline: none; } }   /* on a phone the menu hands focus back to MENU when it closes; no red ring for a tap */   /* phones and tablets just tap through to the Work page */
@media (max-width: 560px) {
  .wordmark { width: 58px; height: 58px; } .wordmark img { width: 39px; }
  .top { padding-top: 24px; }
  .nav { gap: 12px; max-width: 70%; } .nav a { font-size: 10.5px; letter-spacing: .08em; padding: 4px 0; }
}

/* ---------- footer ---------- */
.foot { margin-top: var(--margin-section); }
.foot-in::before { content: ""; flex-basis: 100%; height: 1px; background: var(--color-rule); margin-bottom: 26px; }   /* footer rule inside the page margins */
.foot-in { padding-top: 0; padding-bottom: 40px; display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; font-family: var(--font-family-ui); font-size: 12.5px; letter-spacing: .02em; color: var(--color-text-secondary); }
.foot .r { display: flex; gap: 22px; }
.foot a:hover { color: var(--color-accent-hover); }
.home .foot { display: none; }

/* ==========================================================================
   HOME — reel + list
   ========================================================================== */
body.home { overflow: hidden; height: 100svh; }
.reel { position: fixed; inset: 0; background: #000; z-index: 0; }
.reel video.bg, .reel img.bg {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0;
  transition: opacity 1.1s var(--motion-ease); will-change: opacity; filter: saturate(.92);
}
.reel video.bg.portrait, .reel video.bg.square, .reel img.bg.portrait, .reel img.bg.square { object-fit: contain; }
.reel video.bg.is-on, .reel img.bg.is-on { opacity: 1; }
.reel .shade { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 1.1s var(--motion-ease); }   /* loop_shade: a soft dark oval over one bright spot of a frame (e.g. the Marshalls bag behind the list); fades with its frame */
.reel .shade.is-on { opacity: 1; }
@media (max-width: 820px) { .reel .shade { display: none; } }   /* phones crop the frame differently */
.reel video.bg.fit-fill, .reel img.bg.fit-fill { object-fit: cover; }   /* loop_fit: fill, beats the square/portrait letterbox rule above */
.reel img.bg.m-still { display: none; }   /* desktop keeps the film */
.reel img.bg.m-backdrop { display: none; }   /* phones only: the blur behind a shrunk phone frame */
.reel video.bg.m-loop { display: none; }   /* a still project's phone film: phones only (loop_mobile_* with a home_image) */
.reel img.bg.m-loop-still { display: none; }   /* the phone film's opening frame as a picture, under the film: phones only */
.reel img.bg.backdrop { object-fit: cover; filter: blur(32px) saturate(.9) brightness(.9); transform: scale(1.12); }   /* fills behind a zoomed-out still */
.reel .scrim { position: absolute; inset: 0; background:   /* darker behind the project list (left, lower half) so the titles read over bright frames; the top and right stay clear */
  linear-gradient(to right, rgba(0,0,0,.72) 0%, rgba(0,0,0,.5) 35%, rgba(0,0,0,.18) 62%, rgba(0,0,0,0) 85%),
  linear-gradient(to top, rgba(0,0,0,.7) 0%, rgba(0,0,0,.3) 38%, rgba(0,0,0,0) 60%); }
.reel .scrim::after { content: ""; position: absolute; inset: 0; background: rgba(0,0,0,.07); opacity: 0; transition: opacity .2s ease; }
body:has(.list:hover, .list a:focus-visible) .reel .scrim::after { opacity: 1; }   /* only while hovering the project list: a 7% darker veil over the film, for readability */
.stage { position: relative; z-index: 1; height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: 28px; }
.list-lab { margin: 0 0 18px; color: var(--color-accent); }
.list { list-style: none; margin: 0 0 var(--space-block); padding: 0; max-height: 72svh; overflow: auto; scrollbar-width: none; }
.list::-webkit-scrollbar { display: none; }
.list li { margin: 0; }
.list a {
  display: grid; grid-template-columns: 1fr; align-items: baseline;
  font-family: var(--font-family-display); font-size: var(--font-size-h2-list); line-height: 1.26; letter-spacing: -.012em;
  color: color-mix(in srgb, var(--color-text) 78%, var(--color-background)); transition: color .35s, transform .5s var(--motion-ease); padding: .03em 0;   /* dimmed by colour, not opacity: the titles stay solid over bright frames and keep their shadow */
  text-shadow: 0 1px 2px rgba(0,0,0,.35), 0 0 18px rgba(0,0,0,.4);   /* lifts the titles off busy frames */
}
.list a .m { grid-column: 1; font-family: var(--font-family-ui); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-secondary); line-height: 1; max-height: 0; overflow: hidden; opacity: 0; transition: max-height .4s var(--motion-ease), opacity .4s, margin .4s; }
.list a .m i { font-style: normal; color: var(--color-accent); }
.list a.is-active, .list a:hover, .list a:focus-visible { color: var(--color-text); outline: none; }
.list a.is-active .m { max-height: 2em; opacity: 1; margin: .35em 0 .45em; }
.strap { display: flex; justify-content: space-between; align-items: baseline; gap: 24px; border-top: 1px solid var(--color-rule); padding-top: var(--space-row); }
.strap .line { margin: 0; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; font-weight: 500; color: var(--color-accent); line-height: 1.6; }
.strap .meta { margin: 0; color: var(--color-text-secondary); display: flex; gap: .4em; align-items: baseline; }
.strap .meta .sep { color: var(--color-accent); }
.strap .all { color: var(--color-text); border-bottom: 1px solid var(--color-accent); padding-bottom: 2px; }
.strap .all:hover { color: var(--color-accent-hover); }
@media (max-width: 700px) {
  .list a { font-size: var(--font-size-h2-list-mobile); }
  .strap { flex-direction: column; align-items: flex-start; gap: 10px; }
  .reel .scrim { background: linear-gradient(to top, rgba(0,0,0,.85) 0%, rgba(0,0,0,.5) 50%, rgba(0,0,0,.08) 100%); }
}

/* ==========================================================================
   PAGE HEADS (work, writing, information, essays, 404) — same top, same edge
   ========================================================================== */
.page-head, .info-head, .essay-head { padding-top: var(--margin-page-top); padding-bottom: var(--space-block); }
.page-head .display, .info-head .display { font-size: var(--font-size-h1); max-width: 12em; }
.info-head.has-photo { display: grid; grid-template-columns: minmax(0, 1fr) clamp(346px, 38.9%, 605px); column-gap: clamp(32px, 5vw, 96px); align-items: start; }   /* portrait to the right of the headline */
.head-photo { margin: 0; justify-self: end; width: 100%; }
.head-photo img { display: block; width: 100%; height: auto; border-radius: 12px; }
@media (max-width: 820px) { .info-head.has-photo { grid-template-columns: 1fr; row-gap: var(--space-media); } .info-head .head-photo { max-width: 320px; justify-self: center; } }   /* centred in the column (asked for, Nov 2026), like the NSFW page's photo */   /* the About portrait only; case-study intro photos have their own phone rule below */
.info-head .display em { font-style: italic; color: var(--color-accent); }
.info-head .display.is-long { font-size: calc(var(--font-size-h1) * 0.6); max-width: 22em; }   /* a sentence-length headline (About): the Contact headline's size, on a wider line, so it reads in three or four lines */
.info-body .sec.has-aside .sec-body { display: grid; grid-template-columns: minmax(0, 1fr) clamp(346px, 38.9%, 605px); column-gap: clamp(32px, 5vw, 96px); align-items: start; }   /* copy on the left, a picture on the right: the same columns as the CV page header */
.info-body .sec.no-label .prose > p, .info-body .sec.has-aside .aside-copy .prose > p { font-family: var(--font-family-body); font-size: var(--font-size-body); line-height: var(--line-height-body); letter-spacing: normal; color: var(--color-text-secondary); max-width: var(--measure-body); text-wrap: pretty; }   /* body copy like the CV intro, not the serif headline a first paragraph gets */
.sec-aside { margin: 0; justify-self: end; width: 100%; }
.sec-aside :is(img, video) { display: block; width: 100%; height: auto; border-radius: 12px; }
@media (max-width: 820px) { .info-body .sec.has-aside .sec-body { grid-template-columns: 1fr; row-gap: var(--space-media); } .sec-aside { max-width: 320px; justify-self: start; } }   /* phones: the picture stacks under the copy, at the CV photo's size */
.page-head .lede a { border-bottom: 1px solid var(--color-accent); }

/* ==========================================================================
   INDEX PAGES (work, writing)
   ========================================================================== */
.grid-list { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--margin-section) var(--space-column-gap); }
.card { grid-column: span 4; display: block; border-top: 1px solid var(--color-rule); padding-top: var(--space-row); }   /* even tiles, three across; the hairline sits above each piece: head + sub, hairline, work, hairline, work */
@media (max-width: 1100px) { .card { grid-column: span 6; } }
.card .thumb { aspect-ratio: 16/9; background: var(--color-surface); overflow: hidden; position: relative; }
.card .thumb.portrait, .card .thumb.square { aspect-ratio: 16/9; max-width: 100%; }   /* every tile the same shape */
.card .thumb video, .card .thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--motion-ease), opacity .6s; }
.card:hover .thumb video, .card:hover .thumb img { transform: scale(1.025); }
.card .cap { display: grid; grid-template-columns: 1fr; gap: 6px; margin-top: var(--space-row); }
.card .cap .k { color: var(--color-text-secondary); }
.card .cap .t { font-family: var(--font-family-display); font-size: var(--font-size-h2-card); line-height: 1.05; text-wrap: balance; }
.card .cap .s { font-family: var(--font-family-body); font-style: italic; color: var(--color-text-secondary); font-size: 15px; }
.card:hover .cap .t { color: var(--color-accent-hover); transition: color .3s; }
@media (max-width: 700px) { .card { grid-column: span 12; } }

.more { margin-top: var(--margin-section); }
.more .lab { color: var(--color-accent); margin: 0 0 var(--space-row); display: block; }
.more-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--color-rule); }
.more-list a { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: var(--space-column-gap); align-items: baseline; padding: var(--space-row) 0; border-bottom: 1px solid var(--color-rule-subtle); }
.more-list .t { grid-column: 1 / span 6; font-family: var(--font-family-display); font-size: var(--font-size-h3-more); }
.more-list .k { grid-column: 7 / span 6; color: var(--color-text-tertiary); }
.more-list a:hover .t { color: var(--color-accent-hover); }

/* writing index: same 12-col rhythm */
.essay-list { border-top: 1px solid var(--color-rule); }
.essay-row { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: var(--space-column-gap); align-items: baseline; padding: calc(var(--space-row) * 1.5) 0; border-bottom: 1px solid var(--color-rule-subtle); }
.essay-row .n { grid-column: 1 / span 1; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); color: var(--color-accent); }
.essay-row .t { grid-column: 2 / span 5; font-family: var(--font-family-display); font-size: var(--font-size-h2-row); line-height: 1.02; }
.essay-row .s { grid-column: 7 / span 4; color: var(--color-text-secondary); font-size: 17px; }
.essay-row .k { grid-column: 11 / span 2; color: var(--color-text-tertiary); }
.essay-row:hover .t { color: var(--color-accent-hover); }
@media (max-width: 820px) {
  .more-list .t, .more-list .k { grid-column: 1 / -1; }
  .essay-row .n { grid-column: 1 / -1; } .essay-row .t, .essay-row .s, .essay-row .k { grid-column: 1 / -1; }
  .essay-row .s { margin-top: 8px; }
}

/* ==========================================================================
   PROJECT
   ========================================================================== */
.hero { position: relative; min-height: 100svh; display: flex; align-items: flex-end; background: #000; overflow: hidden; }
.hero-media { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.hero.landscape .hero-media video, .hero.landscape .hero-media img { width: 100%; height: 100%; object-fit: cover; }
.hero.portrait .hero-media video, .hero.square .hero-media video, .hero.portrait .hero-media img, .hero.square .hero-media img { height: 100%; width: auto; max-width: 100%; object-fit: contain; }
.hero.hero-fill .hero-media video, .hero.hero-fill .hero-media img { width: 100%; height: 100%; max-width: none; object-fit: cover; }   /* hero_fit: fill */
.hero.portrait .hero-media::before, .hero.square .hero-media::before { content: ""; position: absolute; inset: 0; background: var(--color-surface); z-index: -1; }
.hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(0,0,0,.82) 0%, rgba(0,0,0,.25) 38%, rgba(0,0,0,0) 65%); pointer-events: none; }
.hero-text { position: relative; z-index: 2; padding-bottom: var(--space-block); }
.hero-text .k { margin: 0 0 14px; color: var(--color-text-secondary); }
.hero-text .display { font-size: var(--font-size-h1-hero); max-width: 11em; }
.hero-text .tag { margin: 16px 0 0; font-family: var(--font-family-body); font-style: italic; font-size: var(--font-size-tagline); color: var(--color-text-secondary); max-width: 30em; }
.sound { position: absolute; right: var(--margin-page-side); bottom: calc(var(--space-block) + 24px + 37px + 16px); z-index: 3; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; padding: 10px 14px 9px; border: 1px solid rgba(255,255,255,.5); border-radius: 999px; background: rgba(0,0,0,.35); backdrop-filter: blur(6px); transition: border-color .3s, background .3s; }
.sound:hover { border-color: var(--color-accent); }
.sound .off { display: none; } .sound.is-on .on { display: none; } .sound.is-on .off { display: inline; } .sound.is-on { background: var(--color-accent); border-color: var(--color-accent); }
/* hero film controls: appear on hover (always on touch screens) for pause, play and seek */
.hero-ctrl { position: absolute; left: var(--margin-page-side); right: var(--margin-page-side); bottom: calc(var(--space-block) + 24px); z-index: 3; display: flex; align-items: center; gap: 14px; height: 37px; opacity: 0; transform: translateY(6px); transition: opacity .12s ease-out, transform .12s ease-out; }
.hero-ctrl.is-shown, .hero-ctrl:has(:focus-visible) { opacity: 1; transform: none; }   /* shown only while the cursor is on the bar's row; gone the moment it moves away (site.js) */   /* shows while the cursor is over the film (or a keyboard user is in the controls), hides when it leaves */
.hc-play { flex: none; width: 37px; height: 37px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 1px solid rgba(255,255,255,.5); border-radius: 50%; background: rgba(0,0,0,.35); cursor: pointer; transition: border-color .3s, background .3s; }
.hc-play:hover { border-color: #fff; }
.hc-play svg { width: 11px; height: 13px; }
.hc-play .i-pause { fill: none; stroke: #fff; stroke-width: 2.2; stroke-linecap: round; }
.hc-play .i-play { fill: #fff; display: none; }
.hero-ctrl.is-paused .i-pause { display: none; } .hero-ctrl.is-paused .i-play { display: inline; }
.hc-seek { flex: 1; min-width: 0; height: 18px; margin: 0; background: none; cursor: pointer; -webkit-appearance: none; appearance: none; --p: 0%; }
.hc-seek::-webkit-slider-runnable-track { height: 3px; border-radius: 2px; background: linear-gradient(to right, #fff var(--p), rgba(255,255,255,.3) var(--p)); }
.hc-seek::-moz-range-track { height: 3px; border-radius: 2px; background: rgba(255,255,255,.3); }
.hc-seek::-moz-range-progress { height: 3px; border-radius: 2px; background: #fff; }
.hc-seek::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; margin-top: -4.5px; border: 0; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.4); }
.hc-seek::-moz-range-thumb { width: 12px; height: 12px; border: 0; border-radius: 50%; background: #fff; }
.hc-seek:focus-visible { outline: none; } .hc-seek:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--color-accent); }
.hc-time { flex: none; min-width: 6.5em; font-family: var(--font-family-ui); font-size: 12px; letter-spacing: .04em; font-variant-numeric: tabular-nums; color: rgba(255,255,255,.85); text-shadow: 0 1px 3px rgba(0,0,0,.5); }
@media (hover: none) { .hero-ctrl { opacity: 1; transform: none; } }
@media (max-width: 700px) { .hero-ctrl { gap: 10px; } .hc-time { display: none; } }   /* phones: a compact bar under the sound button */
@media (max-width: 700px) { .sound { bottom: auto; top: 76px; } }
.hero.img-hero { min-height: 0; flex-direction: column; align-items: stretch; padding-top: 90px; }
.hero.img-hero::after { display: none; }
.hero.img-hero .hero-media { position: relative; inset: auto; display: block; }
.hero.img-hero .hero-media img { width: 100%; height: auto; max-height: 85svh; object-fit: contain; object-position: left center; }
.hero.img-hero .hero-text { padding-top: var(--space-block); }

.credits { padding-top: 48.075px; padding-bottom: 47.925px; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); column-gap: var(--space-column-gap); row-gap: var(--space-row); }   /* optically centred: hero edge to the labels' cap tops = last line's baseline to the divider; the 96px total is unchanged, so the divider stays put */
.credits > div { display: grid; gap: 6px; align-content: start; }
.credits h1.val { margin: 0; font-weight: 400; }
.credits .lab { color: var(--color-accent); }
.credits .val { font-family: var(--font-family-body); font-size: 15px; font-weight: 400; line-height: 1.4; color: var(--color-text); text-wrap: balance; }   /* same sans as its label: the label is small, bold and red, the value regular and white */
.credits .channels .ch + .ch::before { content: "\00B7"; margin: 0 .4em; }   /* desktop: one line, separated by middle dots */
@media (max-width: 820px) { .credits { grid-template-columns: repeat(2, 1fr); } .credits .channels .ch { display: block; } .credits .channels .ch + .ch::before { content: none; } }   /* phones: one channel per line, no dots */

/* editorial sections: labels in columns 1–3, text in 4–11 */
.body { padding-top: var(--margin-section); }
.credits + .body { padding-top: 0; }   /* the credits' own bottom padding is the whole run down to the first section rule */
.sec { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: var(--space-column-gap); border-top: 1px solid var(--color-rule); padding-top: var(--section-space); padding-bottom: var(--section-space); }   /* every section: a rule across the content width, one block-space down to the label — same as the CV and NSFW pages */
.sec-label { grid-column: 1 / span 3; }
.sec-label h2 { position: static; margin: 0; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; font-weight: 500; color: var(--color-accent); }   /* the rule now belongs to the section, not the label */
.sec-body { grid-column: 4 / -1; min-width: 0; }   /* runs to the right page margin, so media lines up with the full-width media above and below; copy keeps its own measure */
@media (min-width: 821px) { .sec:has(> .sec-body > .audio-list) > .sec-label { grid-column: 1 / span 2; } .sec:has(> .sec-body > .audio-list) > .sec-body { grid-column: 3 / -1; } }   /* radio tracks start one column further left */
@media (max-width: 820px) {
  .sec-label, .sec-body { grid-column: 1 / -1; }
  .sec-label h2 { position: static; margin-bottom: var(--space-row); }
}

.prose { max-width: var(--measure-body); font-size: var(--font-size-body); line-height: var(--line-height-body); color: var(--color-text-secondary); }
.prose p { margin: 0 0 1.15em; }
.body .prose p { margin: 0 0 1em; max-width: 32em; font-weight: 400; letter-spacing: normal; text-align: left; text-wrap: pretty; }   /* case-study body: Regular, natural spacing, 45–65 characters a line, paragraph space set by margin not leading. capped in em, not ch: Instrument Sans has a wide zero, so 60ch ran ~70 characters; 32em is ~62 */
.body .prose p.p-wide { max-width: 34em; }   /* a one-off paragraph set to run two lines instead of three (VS New Faces) */
.prose p:first-child { color: var(--color-text); }
.sec:first-child .prose > p:first-child { font-size: var(--font-size-intro); line-height: 1.12; font-family: var(--font-family-display); color: var(--color-text); letter-spacing: -.005em; text-wrap: balance; }   /* the serif case-study headline: tight, balanced lines */
.prose h3 { font-family: var(--font-family-display); font-weight: 500; font-size: 1.35em; line-height: 1.15; margin: 1.6em 0 .5em; color: var(--color-text); }
.prose a { border-bottom: 1px solid var(--color-accent); transition: color .25s; }
.prose a:hover { color: var(--color-accent-hover); }
.prose ul, .prose ol { padding-left: 1.2em; }
.prose li { margin: .25em 0; }
.prose em { font-style: italic; }
.prose strong { color: var(--color-text); font-weight: 600; }
.prose hr { border: 0; border-top: 1px solid var(--color-rule); margin: 2em 0; }
.prose blockquote { margin: 1.6em 0; padding-left: 1.2em; border-left: 2px solid var(--color-accent); font-style: italic; }
.prose .small { font-size: .85em; color: var(--color-text-tertiary); }
.prose .dateline { font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; color: var(--color-accent); margin-bottom: 1.4em; }

/* media — all share --space-media vertical rhythm and the text column's left edge */
.media { margin: var(--space-media) 0; }
.media .frame { background: var(--color-surface); position: relative; }
.media .frame video { width: 100%; height: 100%; object-fit: cover; }
.media.video.portrait, .media.loop.portrait { max-width: 420px; }
.media.video.square, .media.loop.square { max-width: 720px; }
.media.image img { width: 100%; }
.media.image.portrait { max-width: 560px; }
.media figcaption { display: flex; justify-content: space-between; gap: 16px; font-family: var(--font-family-ui); font-size: var(--font-size-caption); letter-spacing: .02em; color: var(--color-text-tertiary); padding: 10px 0 0; }
.media figcaption .dur { font-variant-numeric: tabular-nums; }
.gallery { columns: 2; column-gap: var(--space-gallery-gap); }
.gallery.cols-3 { columns: 3; } .gallery.cols-4 { columns: 4; } .gallery.cols-5 { columns: 5; }
.gallery .cell { margin: 0 0 var(--space-gallery-gap); break-inside: avoid; background: var(--color-surface); }
.gallery .cell img { width: 100%; height: auto; }
.gallery.videos { columns: auto; display: grid; gap: var(--space-gallery-gap); }
.gallery.videos.cols-2 { grid-template-columns: repeat(2, 1fr); } .gallery.videos.cols-3 { grid-template-columns: repeat(3, 1fr); } .gallery.videos.cols-4 { grid-template-columns: repeat(4, 1fr); }
.gallery.videos .cell { margin: 0; }
.gallery.videos .frame { width: 100%; }
@media (max-width: 820px) { .gallery.cols-3, .gallery.cols-4, .gallery.cols-5 { columns: 2; } .gallery.videos.cols-3, .gallery.videos.cols-4 { grid-template-columns: repeat(2, 1fr); } .media.video.portrait { max-width: 100%; } }

/* stats */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--space-media) var(--space-column-gap); margin: var(--space-media) 0; padding-top: var(--space-row); border-top: 1px solid var(--color-rule); }
/* even rows: pick the column count from how many stats there are */
.stats.n-3, .stats.n-6, .stats.n-9 { grid-template-columns: repeat(3, 1fr); }
.stats.n-4, .stats.n-8 { grid-template-columns: repeat(4, 1fr); }
.stats.n-2 { grid-template-columns: repeat(2, 1fr); }
.stats.n-5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 820px) { .stats:not(.n-1):not(.n-2):not(.n-3) { grid-template-columns: repeat(2, 1fr); } }   /* four or more numbers: two across, however many there are */
@media (max-width: 560px) { .stats.n-3 { grid-template-columns: repeat(2, 1fr); } }
.stats .num { font-family: var(--font-family-display); font-size: var(--font-size-stat); line-height: 1; letter-spacing: -.02em; color: var(--color-text); }
.stats .lab { display: block; margin-top: 10px; color: var(--color-text-secondary); line-height: 1.4; }

/* press / awards */
.press { margin: var(--space-media) 0; font-family: var(--font-family-body); font-size: 15.5px; }
.press .lab { display: block; color: var(--color-accent); margin: 0 0 var(--space-row); }   /* the label sits on its own line; the outlets run beneath it */
.press .press-links { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 32px; }   /* outlets in even columns */
.press .press-links > * { position: relative; color: var(--color-text-secondary); line-height: 1.35; }
.press .press-links > *::before { content: ""; position: absolute; left: -16px; top: 0; bottom: 0; border-left: 1px solid var(--color-rule); }   /* divider centred in the gap */
.press .press-links > :nth-child(3n+1)::before { display: none; }   /* each row starts clean at the margin */
@media (max-width: 600px) {
  .press .press-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .press .press-links > :nth-child(3n+1)::before { display: block; }
  .press .press-links > :nth-child(2n+1)::before { display: none; }
}
.press a:hover { color: var(--color-accent-hover); }
.awards { margin: var(--space-media) 0 0; padding-top: var(--space-row); border-top: 1px solid var(--color-rule); }
.awards .lab { color: var(--color-accent); display: block; margin-bottom: var(--space-row); }
.awards ul { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: var(--margin-section); font-family: var(--font-family-ui); font-size: 13px; line-height: 1.5; color: var(--color-text-secondary); }
.awards li { break-inside: avoid; padding: 4px 0; }   /* no rules between award rows */
.awards li .result { color: var(--color-text-tertiary); }   /* "– Silver", "– Shortlist": the result steps back, like the dates column on the CV */
@media (max-width: 640px) { .awards ul { columns: 1; } }

/* pull quote */
blockquote.pull { margin: var(--space-media) 0; padding: 0; border: 0; position: relative; max-width: 30em; }
blockquote.pull p { margin: 0; font-family: var(--font-family-display); font-style: italic; font-size: var(--font-size-quote); line-height: 1.22; color: var(--color-text); }
blockquote.pull p::before { content: "“"; color: var(--color-accent); margin-left: -.45em; }
blockquote.pull cite { display: block; margin-top: 14px; font-style: normal; font-family: var(--font-family-ui); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--color-text-tertiary); }

/* audio */
.audio { display: grid; grid-template-columns: 44px 1fr auto; align-items: center; gap: var(--space-row); padding: var(--space-row) 0; border-top: 1px solid var(--color-rule-subtle); max-width: var(--measure-body); }
.audio .play { width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--color-text-tertiary); position: relative; transition: border-color .3s, background .3s; }
.audio .play::before { content: ""; position: absolute; left: 17px; top: 13px; border-style: solid; border-width: 9px 0 9px 14px; border-color: transparent transparent transparent var(--color-text); }
.audio.is-playing .play { background: var(--color-accent); border-color: var(--color-accent); }
.audio.is-playing .play::before { border: 0; width: 12px; height: 14px; left: 16px; top: 15px; background: linear-gradient(to right, #fff 0 4px, transparent 4px 8px, #fff 8px); }
.audio .title { font-family: var(--font-family-body); font-size: 15.5px; }
.audio .time { font-family: var(--font-family-ui); font-size: 12px; color: var(--color-text-tertiary); font-variant-numeric: tabular-nums; }
.audio-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: clamp(24px, 3vw, 48px); }   /* tracks in columns so the section stays short */
.audio-list .audio { max-width: none; padding: var(--space-row) 0; border-top: 0; border-bottom: 1px solid var(--color-rule-subtle); }   /* in the columns, each track has its rule below, not above */   /* every track in the columns keeps the same padding, so rows line up */
@media (max-width: 1000px) { .audio-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .audio-list { grid-template-columns: minmax(0, 1fr); } }

/* cv rows */
.cv { border-top: 0; }
.cv .row { display: grid; grid-template-columns: 1.1fr 1.3fr .9fr 1.6fr; gap: var(--space-row); padding: calc(var(--space-row) * .7) 0; border-bottom: 0; font-size: 15.5px; line-height: 1.4; }
.cv .org { font-family: var(--font-family-ui); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; font-weight: 500; padding-top: 3px; }
.cv .role { color: var(--color-text); }
.cv .dates { color: var(--color-text-tertiary); padding-top: 3px; letter-spacing: .06em; }
#education .cv .clients { color: var(--color-text-tertiary); }   /* honours sit in the same tone as the dates beside them */
.cv .clients { color: var(--color-text-secondary); font-size: 14.5px; }
@media (max-width: 820px) { .cv .row { grid-template-columns: 1fr 1fr; } .cv .clients { grid-column: 1 / -1; } }

/* next */
.next { display: grid; grid-template-columns: clamp(240px, 22vw, 340px) minmax(0, 1fr); column-gap: clamp(24px, 2.6vw, 40px); align-items: end; width: auto; max-width: 1040px; margin: calc(var(--margin-section) + var(--space-block)) var(--margin-page-side) 0; padding: 26px 30px; background: #1e1e1e; border: 1px solid rgba(255,255,255,.06); border-radius: 18px; }   /* a compact rounded card, flush with the left margin: a sign-off to the next project, not a second hero */
.next-media { grid-column: 1; aspect-ratio: 16/9; background: var(--color-surface); overflow: hidden; border-radius: 10px; }
.next-media.portrait { aspect-ratio: 4/5; max-width: 62%; } .next-media.square { aspect-ratio: 1; max-width: 80%; }
.next-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--motion-ease); }
.next:hover .next-media img { transform: scale(1.03); }
.next-text { grid-column: 2; display: flex; flex-direction: column; justify-content: flex-end; gap: 10px; padding-bottom: 6px; }
.next.slim .next-text { grid-column: 1 / -1; }
.next-text .lab { color: #EA5252; }   /* a shade brighter on the grey Next band, so it passes contrast there (4.6:1) */
html[data-theme="light"] .next-text .lab { color: var(--color-accent); }
.next-text .t { font-family: var(--font-family-display); font-size: clamp(22px, 2vw, 30px); line-height: 1.1; }   /* footer-sized: the next project is a sign-off, not a headline */
.next-text .k { color: var(--color-text-secondary); }
.next:hover .next-text .t { color: var(--color-accent-hover); transition: color .3s; }
@media (max-width: 700px) { .next { grid-template-columns: minmax(0, 1fr); padding: 20px; } .next-media, .next-text { grid-column: 1 / -1; } .next-text { margin-top: var(--space-row); } }

/* ==========================================================================
   ESSAY (writing) — same grid as a case study: head at the page edge,
   body in the text column (4–11)
   ========================================================================== */
.essay-wrap { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: var(--space-column-gap); }
.essay-head { grid-column: 1 / -1; padding-left: 0; padding-right: 0; }
.essay-head .k { margin: 0 0 14px; color: var(--color-text-secondary); }
.essay-head .display { font-size: var(--font-size-h1-essay); max-width: 12em; }
.essay-head .tag { font-family: var(--font-family-body); font-style: italic; font-size: var(--font-size-tagline-essay); color: var(--color-text-secondary); margin: 18px 0 0; max-width: 30em; }
.essay-hero { grid-column: 1 / -1; margin: 0 0 var(--space-block); }
.essay-hero img { width: 100%; height: auto; }
.essay-body { grid-column: 4 / span 8; min-width: 0; }
.essay-body .prose { font-size: var(--font-size-body-essay); line-height: 1.65; }
.essay-body > .prose:first-child > p:first-child::first-letter { font-family: var(--font-family-display); font-size: 4.1em; line-height: .8; float: left; padding: .12em .12em 0 0; color: var(--color-accent); }
.essay-h2 { font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; color: var(--color-accent); margin: var(--space-media) 0 var(--space-row); padding-top: 10px; border-top: 1px solid var(--color-rule); }
.essay-body .media.image.portrait { max-width: 100%; }
.essay-body .verse p { white-space: pre-line; font-family: var(--font-family-body); }
@media (max-width: 820px) { .essay-body { grid-column: 1 / -1; } }

/* ==========================================================================
   INFORMATION — same section grid as a case study
   ========================================================================== */
.info-body { padding-top: 0; }
.info-body .sec { border-top: 1px solid var(--color-rule); padding-top: var(--space-block); }
.info-body .sec-label h2 { border-top: 0; padding-top: 0; }
.info-body .sec.no-label:first-child { border-top: 0; padding-top: 0; }   /* a page that opens straight into copy (About) has no line under its header, like Writing and NSFW; labelled sections (CV) keep theirs */
/* Information page: label on top, content below it at the same left edge */
.info-body .sec { grid-template-columns: 1fr; row-gap: 22px; }
.info-body .sec-label, .info-body .sec-body { grid-column: 1 / -1; }
.info-body .sec-label h2 { position: static; }
/* layout: wide (front matter) — case studies that want the full column, like Information */
.body.wide { padding-top: calc(var(--space-block) * 0.89); }   /* hero to first divider, a touch tighter */
.body.wide .sec { grid-template-columns: 1fr; row-gap: 22px; }
.body.wide .sec-label, .body.wide .sec-body { grid-column: 1 / -1; }
.body.wide .sec { border-top: 1px solid var(--color-rule); padding-top: var(--section-space); }   /* same rule-to-label distance as the CV and About pages */
.body.wide .sec-label h2 { position: static; border-top: 0; padding-top: 0; }
.body.wide .sec:has(.ticker) + .sec { border-top: 0; padding-top: 0; }
.body.wide .sec:first-child:has(> .sec-body .ticker:first-child), .body.wide .sec:first-child:has(.ticker) { border-top: 0; padding-top: 0; }   /* the ticker already draws its own rules; no second line above the next label */
.body.wide .gallery.cols-2 { columns: 2; }
/* banner hero (hero_fit: banner) with the title above it (title_above: true) */
.hero.img-hero.hero-banner { padding: var(--margin-page-top) var(--margin-page-side) 0; }   /* same top and side margins as the CV and Information pages */
.hero.img-hero.hero-banner .hero-media img { width: 100%; height: auto; aspect-ratio: 16 / 5; max-height: 56vh; object-fit: cover; object-position: center; border-radius: 12px; }
/* title_over: true — the title sits on top of the banner, left, vertically centred */
.hero.hero-banner .hero-media { position: relative; }
.hero.hero-banner.title-over .hero-media { aspect-ratio: 4.6 / 1; background: #000; border-radius: 12px; overflow: clip; display: flex; align-items: center; justify-content: flex-start; position: relative; }   /* bar keeps its shape but grows if the copy under the headline needs more room */
.hero.hero-banner.title-over .hero-media img { position: absolute; top: 0; right: 0; width: auto; height: 100%; max-width: 40%; aspect-ratio: auto; max-height: none; object-fit: cover; object-position: right center; border-radius: 0; }   /* photo pinned right on black */
.hero-over { position: relative; z-index: 1; flex: 0 1 58%; padding: 44px 0; }   /* headline and copy start at the page margin */
.hero-over h1 { margin: 0; font-size: var(--font-size-h1); max-width: 12em; color: #fff; }   /* mirrors .page-head .display */
.hero-over .head-intro { color: var(--color-text); max-width: var(--measure-body); }   /* body copy under the headline: same face, size, leading and spacing as the CV page intro */   /* same sub line as the CV and About pages, sitting under the headline on the banner */
.hero-title { padding: 0 0 var(--space-block); }
.hero-title h1 { margin: 0; font-size: min(var(--font-size-h1), 5.2vw); max-width: none; white-space: nowrap; }   /* one line */
/* "ode" intro: text left, a small picture right */
.prose:has(.ode) { max-width: none; }
.ode { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: clamp(32px, 5vw, 96px); align-items: start; }
.ode-text .lede { font-family: var(--font-family-display); font-size: clamp(30px, 3vw, 48px); line-height: 1.1; letter-spacing: -.012em; color: var(--color-text); margin: 0 0 .7em; max-width: 20ch; }
.ode-text p { max-width: 60ch; }
.ode-text { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: clamp(32px, 5vw, 96px); align-items: start; }   /* copy column a touch wider than half */
.ode-text p { max-width: none; color: var(--color-text); }   /* both columns in full white */
.ode-text p.clients { margin-top: 0; align-self: start; }   /* clients sit beside the copy as the second column */
.body .sec .prose:has(> p.clients-foot) { max-width: none; }   /* the clients row runs the full page width like the grid above it */
.body .sec .prose > p.clients.clients-foot { text-wrap: balance; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); line-height: 1.9; text-transform: uppercase; color: var(--color-text-secondary); max-width: none; margin: calc(var(--margin-section) - var(--mosaic-gap, 14px)) 0 0; }   /* under the grid: one section space above and one down to the Next rule; outranks the intro-paragraph style */
.ode-text .col > .lab { font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; font-weight: 500; color: var(--color-accent); line-height: 1.9; margin: 0 0 13px; }   /* same red label as "Freelance clients", so the two sit on one line */
.ode-text .col > p:not(.lab) { margin-top: 0; }
.body.wide .sec.no-label .sec-label { display: none; }
@media (max-width: 820px) { .ode-text { grid-template-columns: 1fr; } }
.ode:not(:has(.ode-photo)) { display: block; }   /* no photo beside the text: plain single column */
.ode-photo { margin: 0; justify-self: end; width: min(100%, 420px); }
.ode-photo img { display: block; width: 100%; height: auto; border-radius: 12px; }
@media (max-width: 820px) { .ode { grid-template-columns: 1fr; row-gap: var(--space-media); } .ode-photo { justify-self: start; } }
p.clients { font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; color: var(--color-text-secondary); line-height: 1.9; margin-top: var(--space-row); }
p.clients b { display: block; color: var(--color-accent); font-weight: 500; margin-bottom: 6px; }
/* ticker: a full-bleed marquee in the display serif */
.ticker { overflow: hidden; margin: calc(var(--space-media) * 0.8) 0 20px; padding: 14px 0; border-top: 1px solid var(--color-rule-subtle); border-bottom: 1px solid var(--color-rule-subtle); white-space: nowrap; }
.ticker-track { display: inline-flex; width: max-content; animation: ticker 48s linear infinite; }
.ticker:hover .ticker-track { animation-play-state: paused; }
.ticker-run { display: inline-flex; align-items: center; }
.ticker-run span { font-family: var(--font-family-display); font-style: italic; font-size: clamp(22px, 2.2vw, 34px); color: var(--color-accent); padding: 0 .55em; }
.ticker-run i { font-style: normal; font-family: var(--font-family-ui); font-weight: 300; font-size: .9em; line-height: 1; color: var(--color-text); display: inline-flex; align-items: center; transform: translateY(.1em); }
@keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .ticker-track { animation: none; } .ticker { overflow-x: auto; } }
/* mosaic: a Pinterest-style mixed grid, edge to edge, images and videos together */
.mosaic { --mosaic-gap: 14px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: 1px; grid-auto-flow: dense; row-gap: 0; column-gap: var(--mosaic-gap); margin: var(--space-media) 0; }   /* 1px rows: site.js spans each cell to its exact image height, so every gap is the same 14px */
.mosaic .cell { margin: 0 0 var(--mosaic-gap); grid-row-end: span 300; background: var(--color-surface); border-radius: 10px; overflow: hidden; }
.mosaic .cell.alpha { background: transparent; border-radius: 0; }
.mosaic .cell.span-2 { grid-column: span 2; } .mosaic .cell.span-3 { grid-column: span 3; } .mosaic .cell.span-4 { grid-column: span 4; }
.mosaic .cell img, .mosaic .cell video { display: block; width: 100%; height: auto; object-fit: cover; border-radius: inherit; transition: transform .7s var(--motion-ease); }
.mosaic .cell.is-stretched .frame, .mosaic .cell.is-stretched img { height: 100%; object-fit: cover; }   /* fill the stretched cell completely: no strip of tile colour at the bottom */   /* a tile stretched a few px to keep the gaps even */
.mosaic .cell:hover img { transform: scale(1.025); }
.mosaic .cell .frame { position: relative; }
.mosaic .cell video { height: 100%; object-fit: cover; }
@media (max-width: 1100px) { .mosaic { grid-template-columns: repeat(3, minmax(0, 1fr)); } .mosaic .cell.span-4 { grid-column: span 3; } }
@media (max-width: 700px) { .mosaic { --mosaic-gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); } .mosaic .cell.span-3, .mosaic .cell.span-4 { grid-column: span 2; } }
.services { display: flex; flex-wrap: wrap; align-items: baseline; margin: 0; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; color: var(--color-text); }
.services span + span::before { content: "·"; color: var(--color-accent); margin: 0 14px; }
/* testimonials: a row of cards you can swipe or arrow through (site.js adds the arrows and dots) */
.prose:has(.testimonials) { max-width: none; }   /* the card row is not body copy: let it use the full column */
.prose:has(.testimonials) { position: relative; }   /* the arrows are positioned against this */
.testimonials { display: flex; gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding: 2px 2px 6px; margin: 0 -2px; }
.testimonials::-webkit-scrollbar { display: none; }
.testimonials blockquote { flex: 0 0 min(400px, 86%); scroll-snap-align: start; margin: 0; padding: 28px 26px 24px; border: 1px solid rgba(255,255,255,.08); border-radius: 18px; background: #181818; font-style: normal; display: flex; flex-direction: column; gap: 14px; text-align: center; }   /* everything in the card is centred */
.testimonials .t { font-family: var(--font-family-display); font-style: normal; font-weight: 500; font-size: var(--font-size-testimonial); line-height: 1.2; letter-spacing: -.005em; color: var(--color-text); margin: 0; min-height: 4.8em; }   /* room for four lines so every quote starts level */
.testimonials .t::before { content: "“"; }   /* no hanging quote mark now the text is centred */
.testimonials .t::after { content: "”"; }
.testimonials .q { font-family: var(--font-family-body); font-size: 14.5px; line-height: 1.6; color: var(--color-text-secondary); margin: 0; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; min-height: 4.8em; }   /* three lines, so Read more sits level */
.testimonials blockquote.is-open .q { display: block; -webkit-line-clamp: unset; }
.testimonials .more { align-self: center; min-height: 1.2em; background: none; border: 0; padding: 0; margin: 18px 0 28px; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; color: var(--color-accent); cursor: pointer; }
.testimonials .more { color: #E54848; }   /* a shade brighter on the grey quote cards, so it passes contrast there too (4.5:1) */
html[data-theme="light"] .testimonials .more { color: var(--color-accent); }
.testimonials .more:hover { color: var(--color-accent-hover); }
.testimonials .more.is-idle { visibility: hidden; }   /* keeps the row so names stay level on short quotes */
.testimonials cite { margin-top: 0; padding-top: 16px; min-height: calc(8em + 16px); border-top: 1px solid var(--color-rule-subtle); font-style: normal; font-family: var(--font-family-ui); font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--color-text-tertiary); line-height: 1.6; display: block; }
.testimonials cite b { color: var(--color-text); font-weight: 500; display: block; }
.body .prose .testimonials p { text-align: center; max-width: none; margin: 0; }   /* the body-copy paragraph rule (left, 32em) must not reach the cards: quotes stay centred */
.carousel-nav { display: flex; align-items: center; justify-content: center; gap: 28px; margin-top: 18px; }
.carousel-nav .dots { display: flex; gap: 0; }
.carousel-nav .dots button { width: 24px; height: 24px; border-radius: 50%; border: 0; padding: 0; background: none; cursor: pointer; position: relative; }   /* each dot is a 24px target (the minimum for a tap); the dot itself is drawn smaller inside it */
.carousel-nav .dots button::before { content: ""; position: absolute; left: 50%; top: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: var(--color-text-tertiary); opacity: .5; transition: opacity .2s, background .2s; }
.carousel-nav .dots button.is-on::before { background: var(--color-accent); opacity: 1; }
.carousel-nav .arrows { display: contents; }
.carousel-nav .arrows button { position: absolute; top: var(--row-mid, 50%); transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--color-rule); background: none; color: var(--color-text); cursor: pointer; font-family: var(--font-family-display); font-size: 22px; line-height: 1; transition: border-color .2s, color .2s; }
.carousel-nav .arrows button:hover { border-color: var(--color-accent); color: var(--color-accent-hover); }
.carousel-nav .arrows button:disabled { opacity: .3; cursor: default; }
.carousel-nav .c-prev { left: calc(-1 * var(--margin-page-side) / 2 - 20px); }    /* centred in the left page margin */
.carousel-nav .c-next { right: calc(-1 * var(--margin-page-side) / 2 - 20px); }   /* and the right one */
@media (max-width: 1100px) { .carousel-nav .arrows { display: flex; gap: 8px; } .carousel-nav .arrows button { position: static; transform: none; } }
@media (max-width: 700px) { .testimonials blockquote { padding: 22px 20px 20px; } }

/* favorites: the intro, category tabs and a grid of product cards on the left, the photo of Victoria on the right (site.js filters the grid by tab) */
.sec-body:has(> .favs) { display: grid; grid-template-columns: minmax(0, 1fr) clamp(260px, 30%, 440px); column-gap: clamp(40px, 6vw, 120px); align-items: start; }
.sec-body:has(> .favs) > .prose { display: contents; }   /* its intro and photo join the section's grid */
.sec-body:has(> .favs) .fav-list { grid-column: 1; grid-row: 1; font-size: var(--font-size-lede); max-width: var(--measure-body); }   /* 65ch measured at the sub's size: the copy runs to the same width as the sub */
.sec-body:has(> .favs) .fav-photo { grid-column: 2; grid-row: 1 / span 2; margin: 6px 0 0; position: sticky; top: 130px; }   /* stays in view beside the grid as it scrolls; 6px down so its top lines up with the tops of the first line's letters, not the line box */
.favs { grid-column: 1; grid-row: 2; min-width: 0; margin-top: 8px; }   /* min-width 0: the sideways tab strip on phones can't widen the column */
.fav-tabs { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 28px; }
.fav-tabs button { padding: 11px 20px; border: 1px solid var(--color-rule); border-radius: 999px; background: none; color: var(--color-text-secondary); cursor: pointer; font-family: var(--font-family-ui); font-size: 11.5px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; transition: border-color .2s, color .2s, background .2s; }
.fav-tabs button:hover { border-color: var(--color-text-secondary); color: var(--color-text); }
.fav-tabs button.is-on { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }   /* the chosen category: a red pill */
.fav-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 36px 20px; }   /* three across, stacked in rows */
.fav-card { display: flex; flex-direction: column; min-width: 0; color: var(--color-text); text-decoration: none; }
.fav-card[hidden] { display: none; }
.fav-img { display: block; aspect-ratio: 4 / 5; border-radius: 12px; overflow: hidden; background: #fff; margin-bottom: 14px; }   /* product shots sit on white, rounded like every other photo */
.fav-img img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .4s var(--motion-ease); }   /* each photo is already a 4:5 tile on its own background, so it fills the rounded tile edge to edge */
.fav-ph { display: flex; align-items: center; justify-content: center; height: 100%; padding: 12%; background: #1a1a1a; color: var(--color-text-tertiary); font-family: var(--font-family-display); font-size: 20px; text-align: center; }
.fav-brand { font-family: var(--font-family-ui); font-size: 11.5px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--color-text); margin-bottom: 6px; }
.fav-name { font-family: var(--font-family-body); font-size: 15px; line-height: 1.4; color: var(--color-text-secondary); text-wrap: pretty; }
.fav-name .arr { margin-left: .3em; color: var(--color-accent); opacity: 0; transition: opacity .2s; }
.fav-note { margin-top: 6px; font-family: var(--font-family-body); font-size: 13.5px; font-style: italic; color: var(--color-text-tertiary); }
.favs[data-cat="all"]:not(.is-open) .fav-card:nth-child(n+7) { display: none; }   /* "All" opens on two rows of three */
.fav-more { display: none; align-items: center; gap: .5em; width: fit-content; margin: 40px auto 0; padding: 0; border: 0; background: none; cursor: pointer; font-family: var(--font-family-ui); font-size: 11.5px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--color-accent); }
.favs[data-cat="all"] .fav-more { display: flex; }   /* centred under "All": See more, then See less once it's open */
.fav-more:hover { color: var(--color-accent-hover); }
.fav-more .arr { font-weight: 400; transition: transform .2s var(--motion-ease); }   /* the down arrow from the CV's Download links */
.fav-more:hover .arr { transform: translateY(2px); }
a.fav-card:hover .fav-img img { transform: scale(1.04); }
a.fav-card:hover .fav-name { color: var(--color-text); }
a.fav-card:hover .fav-name .arr, a.fav-card:focus-visible .fav-name .arr { opacity: 1; }
@media (max-width: 820px) {   /* phones and small tablets: intro, photo, tabs, then two cards across */
  .sec-body:has(> .favs) { grid-template-columns: minmax(0, 1fr); }
  .sec-body:has(> .favs) .fav-photo { grid-column: 1; grid-row: 2; position: static; max-width: 320px; margin: 4px auto var(--space-block); }   /* centred in the column (asked for, Nov 2026): it is narrower than the text, and sat against the left margin */
  .favs { grid-row: 3; }
  .fav-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 14px; }
  .fav-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 calc(-1 * var(--margin-page-side)) 22px; padding: 0 var(--margin-page-side); }   /* the tabs scroll sideways in one line */
  .fav-tabs::-webkit-scrollbar { display: none; }
  .fav-tabs button { flex: none; }
}
.contact-big { font-family: var(--font-family-display); font-size: var(--font-size-contact); line-height: 1.1; }
.contact-big a { border-bottom: 2px solid var(--color-accent); }
.contact-big a:hover { color: var(--color-accent-hover); }
.links { display: flex; flex-wrap: wrap; gap: 10px 28px; margin-top: var(--space-row); font-family: var(--font-family-ui); font-size: 12.5px; letter-spacing: .1em; text-transform: uppercase; }
.links a { border-bottom: 1px solid var(--color-rule); padding-bottom: 3px; }
.links a:hover { border-color: var(--color-accent); }
.fav-list > p:first-child { margin-top: 0; }
.body .prose .fav-list > p { max-width: none; font-size: var(--font-size-body); line-height: var(--line-height-body); color: var(--color-text-secondary); }   /* the same line length as the sub above */   /* one step under the sub: the same grey, a touch smaller */
.body .prose .fav-list > p.fine { margin-top: 1.2em; font-size: 14.5px; line-height: 1.55; color: var(--color-text-tertiary); }   /* the disclaimer reads as a footnote */
.fav-list > p:last-of-type { margin-bottom: 36px; }   /* room between the intro and the categories */
.fav-photo img { display: block; width: 100%; height: auto; border-radius: 12px; }   /* rounded like every other photo */
.prose:has(> .portrait-pair) { max-width: none; display: grid; grid-template-columns: minmax(0, 36em) auto; justify-content: space-between; grid-template-rows: auto 1fr; column-gap: clamp(32px, 4vw, 72px); align-items: start; }   /* copy left at reading width, photos right — same pattern as My Current Favorites */
.prose:has(> .portrait-pair) > p { grid-column: 1; }
@media (min-width: 821px) {
  .prose:has(> .portrait-pair) > .portrait-pair { grid-column: 2; grid-row: 1 / -1; margin: 0; display: flex; gap: var(--space-gallery-gap); }
  .prose:has(> .portrait-pair) > .portrait-pair img { height: var(--pair-h, 400px); width: auto; max-width: none; }   /* site.js sets --pair-h to the height of the copy beside it */
}
@media (max-width: 820px) { .prose:has(> .portrait-pair) { grid-template-columns: 1fr; grid-template-rows: none; } .prose:has(> .portrait-pair) > .portrait-pair { grid-column: 1; grid-row: auto; margin-top: var(--space-media); } }
.portrait-pair { display: grid; grid-template-columns: 0.8fr 0.5594fr; gap: var(--space-gallery-gap); margin: var(--space-media) 0; }   /* columns in proportion to each photo's shape, so both stand the same height with nothing cropped */
.portrait-pair { align-items: start; }
.portrait-pair img { width: 100%; height: auto; }

/* ---------- reveal ---------- */
.contact-big .mail-line { white-space: nowrap; }   /* emoji and address always share a line */
.contact-big .mail-line a { display: inline; }
/* Contact page: label, then the invitation, then the email as the biggest thing on the page */
.contact-page .info-head .lab.eyebrow { display: block; color: var(--color-accent); margin: 0 0 var(--space-row); }
.contact-page .info-head .display { font-size: calc(var(--font-size-h1) * 0.82); }   /* the invitation, ~18% under the standard headline */
.contact-cta { margin: calc(var(--space-block) * 0.9) 0 0; font-family: var(--font-family-display); font-size: calc(var(--font-size-h1) * 1.12); line-height: 1.05; letter-spacing: -.012em; }   /* the destination: largest type on the page */
.contact-cta a { border-bottom: 3px solid var(--color-accent); white-space: nowrap; }
.contact-cta a:hover { color: var(--color-accent-hover); }
.contact-cta .arr { font-family: var(--font-family-ui); font-weight: 300; font-size: .42em; vertical-align: .9em; margin-left: .15em; color: var(--color-accent); }
.contact-page .info-head .links { margin-top: var(--space-block); }
.contact-page .info-head.has-side { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: clamp(40px, 5vw, 96px); align-items: start; }   /* all the text in one column, the photo on the right beside it */
.contact-page .info-head.has-side > * { grid-column: 1; }
.contact-page .info-head.has-side .display { font-size: calc(var(--font-size-h1) * 0.6); }   /* smaller type, so the photo has room */
.contact-page .info-head.has-side .contact-cta { font-size: calc(var(--font-size-h1) * 0.8); }
.contact-photo { grid-column: 2 !important; grid-row: 1 / span 4; align-self: center; margin: 0; width: clamp(220px, calc(38.6vw - 116px), 480px); aspect-ratio: 1; border-radius: 50%; overflow: hidden; }   /* the coffee loop in a circle, as big as the space beside the email allows (the email is ~56vw wide) */
.contact-photo video { display: block; width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 820px) { .contact-page .info-head.has-side { display: block; } .contact-photo { width: 200px; margin-bottom: var(--space-block); } .contact-page .info-head.has-side .display { font-size: clamp(34px, 9vw, 48px); } }   /* phones: a smaller circle above the eyebrow */
@media (max-width: 700px) { .contact-page .info-head.has-side .contact-cta { font-size: clamp(22px, 8.4vw, 40px); } .contact-page .info-head.has-side .contact-cta a { white-space: nowrap; } }   /* the email stays on one line */
@media (max-width: 700px) { .contact-cta { font-size: clamp(30px, 10.5vw, 60px); } .contact-cta a { white-space: normal; overflow-wrap: anywhere; } }
.head-cta { margin: var(--space-block) 0 0; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; }   /* same treatment as ALL WORK on the home page */
.head-cta a { color: var(--color-text); border-bottom: 1px solid var(--color-accent); padding-bottom: 3px; }
.head-cta a:hover { color: var(--color-accent-hover); }
.head-cta .arr { margin-left: .6em; color: var(--color-accent); }
.head-cta + .head-cta { margin-top: 1.4em; }   /* stacked CTAs: CV, then the detailed résumé */

.sec-body > .media:first-child, .sec-body > .prose > .media:first-child, .sec-body > .prose:first-child > .media:first-child { margin-top: 0; }   /* a section that opens with images starts level with its label, like text does */

/* Case-study intro: starts at the page margin like the CV header, with an optional photo on the right */
.body .sec.sec-intro .sec-label { display: none; }
.body .sec.sec-intro .sec-body { grid-column: 1 / -1; }
.body .sec.sec-intro.has-photo .sec-body { display: grid; grid-template-columns: minmax(0, 1fr) clamp(346px, 38.9%, 605px); column-gap: clamp(32px, 5vw, 96px); align-items: start; }
.body .sec.sec-intro .head-photo img { cursor: zoom-in; }
@media (max-width: 1199px) { .body .sec.sec-intro.has-photo .sec-body { grid-template-columns: 1fr; row-gap: var(--space-media); } }   /* laptops, tablets and phones: the intro photo stacks under the copy, so the paragraph keeps a full measure */
@media (min-width: 821px) and (max-width: 1199px) { .body .sec.sec-intro.has-photo:not(.photo-wide) .head-photo { max-width: 520px; } }
@media (max-width: 1199px) { .body .sec.sec-intro.has-photo .head-photo { justify-self: start; margin-left: 0; margin-right: 0; } }   /* stacked, the photo sits flush left with the copy */   /* a portrait photo stacked at tablet width stays a sensible size */

/* A section that holds a mosaic runs the full content width, label on top, like the NSFW page */
.body .sec:has(> .sec-body > .mosaic) { grid-template-columns: 1fr; row-gap: 22px; }
.body .sec:has(> .sec-body > .mosaic) .sec-label, .body .sec:has(> .sec-body > .mosaic) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .mosaic) .sec-label h2 { position: static; }
.body .sec > .sec-body > .mosaic:first-child { margin-top: 0; }

.head-photo a { display: block; border-radius: 12px; }   /* a linked photo (e.g. the DADS poster to Apple TV+) */
.head-photo a img { transition: opacity .3s var(--motion-ease); }
.head-photo a:hover img { opacity: .88; }
@media (max-width: 820px) { .media.image[style*="max-width"] { max-width: none !important; } }   /* a narrowed image runs the full column on phones */

/* live emoji set (DADS): real Unicode text, not a picture */
.prose p.emoji-set { display: grid; grid-template-columns: repeat(3, max-content); justify-content: center; gap: .02em .45em; margin: var(--space-media) 0 0; max-width: none; font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif; font-size: clamp(76px, 8.4vw, 128px); line-height: 1.17; color: var(--color-text); }
.prose p.emoji-set span { display: block; }

/* Section spacing rule: the section's own padding is the whole gap at each end, so trailing margins of the
   last element (a paragraph, a figure, a gallery, the press grid) don't stack on top of it */
.sec-body > :last-child, .sec-body > :last-child > :last-child:not(.cell), .sec-body > :last-child > :last-child > :last-child:not(.cell) { margin-bottom: 0; }
.sec-body > :first-child, .sec-body > :first-child > :first-child { margin-top: 0; }   /* nothing adds space above a section's first content either */
.sec-body > :is(.stats, .awards):first-child, .sec-body > .prose:first-child > :is(.stats, .awards):first-child { border-top: 0; padding-top: 0; }   /* a results block that opens a section: the section divider already does its rule's job, so the numbers sit level with the label */
.sec-body > .audio:last-child, .sec-body > :last-child:not(.audio-list) > .audio:last-child { padding-bottom: 0; }   /* the last track row ends at its controls */
.sec-body > .mosaic:last-child, .sec-body > :last-child > .mosaic:last-child { margin-bottom: calc(-1 * var(--mosaic-gap)); }   /* the grid's last row carries a gap-sized margin of its own */
.body + .next { margin-top: var(--space-block); }
.body + .pn { margin-top: calc(var(--space-block) * 2); }   /* the prev/next footer sits a block lower, clear of the last section */   /* the last section's bottom padding plus one block of air down to the Next band */

.body .sec.sec-intro .sec-body.intro-tail { grid-column: 1 / -1; display: block; margin-top: var(--space-media); }   /* media after the intro copy runs full width below the copy-and-photo row */
.sec-body > .awards:first-child > .lab, .sec-body > .prose:first-child > .awards:first-child > .lab { display: none; }   /* the section label on the left already names it */
.sec-body > .awards:first-child > ul, .sec-body > .prose:first-child > .awards:first-child > ul { margin: -4px 0; }   /* the rows' own 4px padding doesn't add to the section's top and bottom space */

/* carousel: same-height images in a row, scroll-snapped; arrows and a counter underneath */
.carousel-track { display: flex; gap: var(--mosaic-gap, 14px); overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; scrollbar-width: none; overscroll-behavior-x: contain; outline: none; }
.carousel-track::-webkit-scrollbar { display: none; }
.carousel .slide { flex: none; margin: 0; scroll-snap-align: start; height: calc(clamp(380px, 48vw, 720px) * var(--slide-scale, 1)); border-radius: 10px; overflow: hidden; background: var(--color-surface); }
.carousel .slide img { display: block; height: 100%; width: auto; }
.carousel-ui { display: flex; align-items: center; gap: 18px; margin-top: var(--space-row); font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); color: var(--color-text-tertiary); }
.carousel-ui button { width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--color-rule); background: none; color: var(--color-text); font-size: 26px; line-height: 1; cursor: pointer; padding: 0 0 3px; transition: border-color .2s, color .2s; }
.carousel-ui button:hover { border-color: var(--color-accent); color: var(--color-accent); }
.carousel-count { font-variant-numeric: tabular-nums; min-width: 4.5em; text-align: center; }
.body .sec:has(> .sec-body > .carousel) { grid-template-columns: 1fr; row-gap: 22px; }
.body .sec:has(> .sec-body > .carousel) .sec-label, .body .sec:has(> .sec-body > .carousel) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .carousel) .sec-label h2 { position: static; }
@media (max-width: 700px) { .carousel .slide { height: calc(420px * var(--slide-scale, 1)); } }

/* a captioned pair or gallery: a plain grid (photos top-aligned, no column-balancing gap) with the caption right under it */
.gallery.as-grid { columns: auto; display: grid; grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr)); gap: var(--space-gallery-gap); align-items: start; }
.gallery.as-grid.cols-3 { --cols: 3; } .gallery.as-grid.cols-4 { --cols: 4; } .gallery.as-grid.cols-5 { --cols: 5; }
.gallery.as-grid .cell { margin: 0; }

/* a captioned carousel (Out of home): landscape photos at one height, each with its location underneath */
.carousel.has-caps .slide { height: auto; background: none; border-radius: 0; overflow: visible; }
.carousel.has-caps .slide img { height: clamp(300px, 34vw, 560px); width: auto; border-radius: 10px; background: var(--color-surface); }
.carousel.has-caps .slide figcaption { font-family: var(--font-family-ui); font-size: var(--font-size-caption); letter-spacing: .02em; color: var(--color-text-tertiary); padding-top: 10px; }
@media (max-width: 700px) { .carousel.has-caps .slide { width: 100%; } .carousel.has-caps .slide img { width: 100%; height: auto; } }
/* a section built around a carousel runs the full content width, label on top, like the collage sections */
.body .sec:has(> .sec-body > .carousel) { grid-template-columns: 1fr; row-gap: 22px; }
.body .sec:has(> .sec-body > .carousel) .sec-label, .body .sec:has(> .sec-body > .carousel) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .carousel) .sec-label h2 { position: static; margin-top: 0 !important; }

/* @row: photos side by side at the same height, filling the width; full-width section with the label on top */
.media.row { display: flex; gap: var(--mosaic-gap, 14px); }
.media.row.collage { --collage-gap: clamp(16px, 1.6vw, 24px); gap: var(--collage-gap); }
.media.row.collage + .media.row.collage { margin-top: calc(var(--collage-gap) - var(--space-media)); }   /* consecutive collage rows sit exactly one gap apart, the same gap as inside a row */
.media.row.collage .cell { overflow: visible; background: none; }
.media.row.collage .cell img { border-radius: 10px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); }   /* a whisper of a shadow on each piece */
.media.row .cell { margin: 0; min-width: 0; border-radius: 10px; overflow: hidden; background: var(--color-surface); }
.media.row .cell img { display: block; width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 700px) { .media.row { flex-direction: column; max-width: none !important; } .media.row .cell { flex: none !important; } }   /* a narrowed row (e.g. @row 90%) uses the full width on a phone */
@media (max-width: 700px) { .media.row:is(.n-4, .n-5, .n-6) { display: grid; grid-template-columns: 1fr 1fr; } }   /* a long row of photos goes two across on a phone instead of one tall stack */
.body .sec:has(> .sec-body > .media.row) { grid-template-columns: 1fr; row-gap: 22px; }
.body .sec:has(> .sec-body > .media.row) .sec-label, .body .sec:has(> .sec-body > .media.row) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .media.row) .sec-label h2 { position: static; margin-top: 0 !important; }

/* credits row: the items sit with equal space between them, first at the left margin, last ending at the right margin */
.credits { display: flex; flex-wrap: wrap; justify-content: space-between; column-gap: var(--space-column-gap); }
.credits > div { flex: 0 1 auto; max-width: 30em; }
@media (max-width: 1100px) { .credits { display: grid; grid-template-columns: repeat(2, 1fr); } .credits > div { max-width: none; } }

/* hero_fit: full — an image hero that fills the first screen behind the menu, exactly where a video hero sits */
.hero.img-hero.hero-full { min-height: 100svh; padding-top: 0; }
.hero.img-hero.hero-full .hero-media { position: absolute; inset: 0; }
.hero.img-hero.hero-full .hero-media img { width: 100%; height: 100%; max-height: none; object-fit: cover; object-position: var(--hero-focus, center); }
.hero.img-hero.hero-full::before { content: ""; position: absolute; inset: 0 0 auto; height: 180px; z-index: 1; pointer-events: none; background: linear-gradient(to bottom, rgba(0,0,0,.55), rgba(0,0,0,0)); }   /* keeps the white menu readable over a light photo */

/* @split: copy on the left, its film on the right; the section runs full width with the label on top */
.media.split { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: clamp(32px, 5vw, 96px); align-items: start; }
.media.split + .media.split { margin-top: var(--space-block); padding-top: var(--space-block); border-top: 1px solid var(--color-rule); }   /* a hairline between one film and the next */
.media.split .split-text > :first-child { margin-top: 0; }
.media.split .split-text > :last-child { margin-bottom: 0; }
.media.split > .media { margin: 0; }
@media (max-width: 820px) {   /* stacked: headline, then the film, then the copy */
  .media.split { grid-template-columns: 1fr; row-gap: 0; }
  .media.split .split-text { display: contents; }
  .media.split .split-text > h3 { order: -2; margin: 0 0 18px; }
  .media.split > .media, .sec-body > .media.split:last-child > .media:last-child { order: -1; margin: 0 0 22px; }   /* beats the "last item ends flush" rule, since here the film is followed by its copy */
}
.body .sec:has(> .sec-body > .split) { grid-template-columns: 1fr; row-gap: 22px; }
.body .sec:has(> .sec-body > .split) .sec-label, .body .sec:has(> .sec-body > .split) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .split) .sec-label h2 { margin-top: 0 !important; }

/* intro_photo_wide: a landscape intro photo takes the wider column, on the same 5:7 split as the films below it */
.body .sec.sec-intro.has-photo.photo-wide .sec-body { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
@media (max-width: 1199px) { .body .sec.sec-intro.has-photo.photo-wide .sec-body { grid-template-columns: 1fr; } }

/* a credit line under an intro photo, e.g. the story a poster quotes */
.head-photo .photo-credit { padding-top: 10px; font-family: var(--font-family-ui); font-size: var(--font-size-caption); letter-spacing: .02em; color: var(--color-text-tertiary); }
.head-photo .photo-credit b { font-weight: 600; color: var(--color-text-secondary); }
.head-photo .photo-credit i { font-family: var(--font-family-body); font-size: 1.08em; letter-spacing: 0; }
.head-photo .photo-credit a { display: inline; border-radius: 0; border-bottom: 0; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; color: inherit; }   /* a plain inline link, not the block style the photo link uses */
.head-photo .photo-credit a:hover { color: var(--color-accent-hover); }

/* outlined pill button, same look as the "Watch with sound" button */
.prose p.btn-row { margin: var(--space-media) 0 0; }
.prose a.btn, a.btn { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-family-ui); font-size: var(--font-size-ui); letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; color: var(--color-text); padding: 14px 22px; border: 1px solid rgba(255,255,255,.45); border-bottom: 1px solid rgba(255,255,255,.45); border-radius: 999px; transition: border-color .25s, color .25s, background .25s; }
.prose a.btn:hover, a.btn:hover { border-color: var(--color-accent); color: #fff; background: var(--color-accent); }
html[data-theme="light"] a.btn { border-color: rgba(0,0,0,.4); }

/* carousel "landscape": a lower row so very wide photos fit the page width */
.carousel.is-landscape .slide { height: calc(clamp(240px, 34vw, 560px) * var(--slide-scale, 1)); max-width: 100%; }
.carousel.is-landscape .slide img { object-fit: cover; max-width: 100%; }
@media (max-width: 700px) { .carousel.is-landscape .carousel-track { align-items: center; } .carousel.is-landscape .slide { height: auto; width: 100%; } .carousel.is-landscape .slide img { width: 100%; height: auto; } }   /* each photo keeps its own height on phones, centred in the row */

/* hero_fit: whole — a video hero sized to the film's own shape, so nothing at the edges is cropped */
.hero.has-video.hero-whole { min-height: 0; aspect-ratio: var(--hero-ar, 16 / 9); }
.hero.has-video.hero-whole .hero-media video { width: 100%; height: 100%; object-fit: cover; }
.hero.has-video.hero-whole::after { display: none; }   /* no dark fade over the credit line at the bottom of the film */
/* hero_fit: whole on a photo — the first screen, full bleed: the photo sits a little below the menu at its own shape, nothing cropped, with a soft blurred copy of itself filling the strip behind the menu */
.hero.img-hero.hero-whole { min-height: 100svh; padding-top: 0; }
.hero.img-hero.hero-whole .hero-media { position: absolute; inset: 0; overflow: hidden; }
.hero.img-hero.hero-whole .hero-media .hero-backdrop { display: none; }
.hero.img-hero.hero-whole::before { content: ""; position: absolute; inset: 0 0 auto; height: 180px; z-index: 1; pointer-events: none; background: linear-gradient(to bottom, rgba(0,0,0,.32), rgba(0,0,0,.1) 55%, rgba(0,0,0,0)); }   /* a light extra fade at the top of the photo, on top of the menu's own */   /* no blurred strip: the top fades to black like the other heroes */
.hero.img-hero.hero-whole .hero-media img:not(.hero-backdrop) { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none; object-fit: cover; object-position: var(--hero-focus, 75% center); }   /* full bleed from the very top, under the menu's soft fade, like the other heroes */
@media (max-width: 700px) {   /* phones: the whole photo runs from the very top of the screen, under the menu's fade, with no black strip above it */
  .hero.img-hero.hero-whole { min-height: 0; aspect-ratio: auto; padding-top: 0; }
  .hero.img-hero.hero-whole::before { display: none; }   /* the menu's own soft fade is enough; the faces sit just under it */
  .hero.img-hero.hero-whole .hero-media { position: relative; inset: auto; }
  .hero.img-hero.hero-whole .hero-media img:not(.hero-backdrop) { position: static; height: auto; aspect-ratio: auto; object-fit: cover; }   /* the phone picture (hero_image_mobile) shows whole, at its own shape */
}

/* a film slide in a carousel: same height as the row, width from the film's own shape */
.carousel .slide.video { width: auto; background: #000; }
.carousel .slide.video video { display: block; height: 100%; width: 100%; object-fit: cover; }
@media (max-width: 700px) { .carousel .slide.video { height: 520px; } }
@media (max-width: 700px) { .carousel.is-landscape .slide.video { height: auto; width: 100%; } }   /* wide films fill the phone width at their own shape */

/* press in an intro with no photo: same width as the copy column beside an intro photo (as on DADS), so the three columns sit the same */
.body .sec.sec-intro:not(.has-photo) .sec-body > .press { max-width: calc(100% - clamp(346px, 38.9%, 605px) - clamp(32px, 5vw, 96px)); }
@media (max-width: 820px) { .body .sec.sec-intro:not(.has-photo) .sec-body > .press { max-width: none; } }

/* intro_photo_fill: the photo runs from the top of the copy to the bottom of the left column (press included), cropping rather than distorting */
.body .sec.sec-intro.has-photo.photo-fill .sec-body { align-items: stretch; }
.body .sec.sec-intro.has-photo.photo-fill .head-photo { display: flex; height: 100%; }
.body .sec.sec-intro.has-photo.photo-fill .head-photo img { height: 100%; width: 100%; object-fit: cover; object-position: var(--photo-focus, center); }
@media (max-width: 1199px) { .body .sec.sec-intro.has-photo.photo-fill .head-photo, .body .sec.sec-intro.has-photo.photo-fill .head-photo img { height: auto; } }
.body .sec.sec-intro .head-photo { width: calc(100% * var(--photo-scale, 1)); }   /* intro_photo_scale: a smaller photo, still flush right */
@media (max-width: 820px) { .body .sec.sec-intro .head-photo { width: 100%; max-width: none; justify-self: stretch; } }   /* phones: every intro photo fills the page margin to margin, whatever its desktop scale */
/* intro_photo_2: two photos side by side beside the intro copy, cropped to the same 3:4 shape */
.body .sec.sec-intro.photo-pair .head-photo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-gallery-gap); }   /* same gap as the side-by-side galleries */
.body .sec.sec-intro.photo-pair .head-photo img { aspect-ratio: 3 / 4; height: auto; object-fit: cover; }
.body .sec.sec-intro.photo-pair .head-photo .photo-credit { grid-column: 1 / -1; }
@media (max-width: 1199px) { .body .sec.sec-intro.photo-pair .head-photo { max-width: none; } }
.body .sec.sec-intro .intro-text > :last-child, .body .sec.sec-intro .intro-text > :last-child > :last-child { margin-bottom: 0; }   /* the copy column ends at its last line, so a stretched photo stops level with the text */

/* a six-tile collage (True Originals On set) on a three-column tablet grid: run it as two columns so the bottom stays level */
@media (min-width: 701px) and (max-width: 1100px) { .mosaic.n-6, .mosaic.n-7 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .mosaic.n-6 .cell.span-3, .mosaic.n-6 .cell.span-4, .mosaic.n-7 .cell.span-3, .mosaic.n-7 .cell.span-4 { grid-column: span 2; } }

/* @reactions: a wall of fan comments lifted out of the app onto white cards (Instagram's light-mode look), so they read
   differently from the dark LeagueFits caption above. Each card is laid out like a real comment, avatar to the left of the
   handle and words, so the cards are wide, short rectangles. Each line ("/" in @reactions) holds three or four cards at
   their own natural size, centred and staggered against the lines above and below; the gap between neighbours is the same */
.reactions { --card: #fff; --gap: clamp(12px, 1.1vw, 16px); display: flex; flex-direction: column; gap: var(--gap); margin: 0; }
.reaction-row { display: flex; justify-content: center; align-items: center; gap: var(--gap); }
.reaction { --ig: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif; --fs: 12px;
  /* every card is the same Instagram comment at a different scale: username ~0.93x the comment size, avatar ~2.3x, spacing in step */
  flex: 0 1 auto; max-width: calc(var(--max, 340px) + var(--fs) * 2.4); min-width: min-content; margin: 0; background: var(--card, #fff); color: #000;
  border-radius: min(14px, calc(var(--fs) * .9)); padding: calc(var(--fs) * .95) calc(var(--fs) * 1.05);
  display: grid; grid-template-columns: calc(var(--fs) * 2.3) minmax(0, 1fr) auto; column-gap: calc(var(--fs) * .8); row-gap: calc(var(--fs) * .12); align-content: start; text-align: left; }
.reaction figcaption { display: contents; }
.reaction .avatar { grid-column: 1; grid-row: 1 / span 2; align-self: start; width: calc(var(--fs) * 2.3); height: calc(var(--fs) * 2.3); border-radius: 50%; object-fit: cover; background: #efefef; }
.reaction .who { grid-column: 2; grid-row: 1; white-space: normal; font-family: var(--ig); font-size: calc(var(--fs) * .93); line-height: 1.25; color: #737373; }
.reaction .who b { font-weight: 600; color: #000; white-space: nowrap; }
.reaction .who span { color: #737373; white-space: nowrap; }   /* a username never breaks; on a tight line an X @handle may drop under the name */
.reaction blockquote { grid-column: 2; grid-row: 2; margin: 0; padding: 0; border: 0; font-style: normal; font-family: var(--ig); font-size: var(--fs); font-weight: 400; color: #000; line-height: 1.28; letter-spacing: -.01em; }   /* the comment itself in Instagram's own type: the system sans (SF Pro on Apple devices) */
.reaction blockquote .nw { white-space: nowrap; }
/* each card keeps its own app's footer, with only the real numbers from the original screenshot */
.reaction .who .label { display: block; font-size: .92em; color: #737373; }
.reaction footer { grid-column: 2; grid-row: 3; display: flex; align-items: center; font-family: var(--ig); font-size: calc(var(--fs) * .82); color: #737373; margin-top: calc(var(--fs) * .2); }
.reaction footer b { font-weight: 600; }
.reaction footer svg { width: 1.25em; height: 1.25em; flex: none; }
.reaction .fb-actions { gap: 1.1em; } .reaction .fb-actions b { font-weight: 600; }
.reaction .x-actions { gap: .9em; justify-content: space-between; max-width: 15em; margin-top: calc(var(--fs) * .5); color: #536471; }
.reaction .x-actions i { display: inline-flex; align-items: center; gap: .35em; font-style: normal; }
.reaction .ig-heart { grid-column: 3; grid-row: 1 / span 3; align-self: center; display: flex; flex-direction: column; align-items: center; gap: .15em; color: #737373; font-family: var(--ig); font-size: calc(var(--fs) * .72); }
.reaction .ig-heart svg { width: calc(var(--fs) * 1.05); height: calc(var(--fs) * 1.05); stroke-width: 2.1; }
.reaction.on-x, .reaction.on-fb { grid-template-columns: calc(var(--fs) * 2.3) minmax(0, 1fr); }   /* only Instagram comments carry the heart column */
.reaction.on-fb blockquote { background: #f0f2f5; border-radius: 1em; padding: .45em .8em; justify-self: start; margin-left: -.1em; }   /* Facebook sets the comment in a grey bubble */
.reaction.on-fb .who { padding-left: .8em; }
@media (max-width: 1100px) { .reaction blockquote .nw { white-space: normal; } .reaction-row { flex-wrap: wrap; } }   /* on narrower screens a long emoji run may wrap, and a full line wraps instead of squeezing its cards */
.reaction.r-s  { --fs: clamp(11.2px, .84vw, 12.8px); --max: 272px; }
.reaction.r-m  { --fs: clamp(13.6px, 1.08vw, 16.8px); --max: 320px; }
.reaction.r-l  { --fs: clamp(16.8px, 1.52vw, 22.4px); --max: 416px; }
.reaction.r-xl { --fs: clamp(22.4px, 2.24vw, 33.6px); --max: 560px; }
.body .sec:has(> .sec-body > .reactions) { grid-template-columns: 1fr; row-gap: 22px; }   /* the wall runs the full width, label on top */
.body .sec:has(> .sec-body > .reactions) .sec-label, .body .sec:has(> .sec-body > .reactions) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .reactions) .sec-label h2 { position: static; margin-top: 0 !important; }
@media (max-width: 700px) {
  .reactions { --gap: 10px; }
  .reaction-row { flex-wrap: wrap; }
  .reaction-row { gap: var(--gap); }
  .reaction { max-width: 100%; } .reaction.r-l, .reaction.r-xl { flex-basis: 100%; }
  .reaction.r-xl { --fs: 20.8px; } .reaction.r-l { --fs: 16px; }
}

/* @spread: the fits as a fashion spread. Each row is a 12-column grid; the locked photo keeps its own shape and sets
   the row height, the others crop to fill beside it (object-position from --focus) */
.media.spread { display: flex; flex-direction: column; gap: var(--mosaic-gap, 14px); margin: 0; }
.spread-row { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--mosaic-gap, 14px); }
.spread .cell { position: relative; margin: 0; border-radius: 10px; overflow: hidden; background: var(--color-surface); min-height: 0; }
.spread .cell img { display: block; width: 100%; height: 100%; object-fit: cover; }
.spread .cell:not(.lock) img { position: absolute; inset: 0; object-position: var(--focus, 50% 50%); }
.body .sec:has(> .sec-body > .media.spread) { grid-template-columns: 1fr; row-gap: 22px; }   /* full width, label on top */
.body .sec:has(> .sec-body > .media.spread) .sec-label, .body .sec:has(> .sec-body > .media.spread) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .media.spread) .sec-label h2 { position: static; margin-top: 0 !important; }
@media (max-width: 700px) {
  .spread-row { grid-template-columns: 1fr 1fr; gap: 10px; }
  .media.spread { gap: 10px; }
  .spread .cell { grid-column: auto !important; aspect-ratio: 3 / 4; }
  .spread .cell.lock { grid-column: 1 / -1 !important; }
  .spread-row.has-solo .cell:not(.lock) { grid-column: 1 / -1 !important; aspect-ratio: 4 / 3; }
}

/* @postcaption: the post's own caption, set huge as the campaign line, with the account in small sans above it */
.postcaption { margin: 0; }
.postcaption figcaption { display: flex; align-items: center; gap: 12px; font-family: var(--font-family-ui); font-size: 15px; color: var(--color-text); margin-bottom: clamp(14px, 1.6vw, 26px); }
.postcaption figcaption b { font-weight: 600; }
.postcaption .avatar { display: block; flex: none; width: 40px; height: 40px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 1px rgba(255,255,255,.18); }   /* a hairline ring so the black logo reads as an avatar on the black page */
.postcaption blockquote { margin: 0; padding: 0; border: 0; font-style: normal; font-family: var(--font-family-display); font-size: var(--cap-size, 7.8vw); line-height: 1.04; letter-spacing: -.02em; color: var(--color-text); }
.postcaption .line { display: block; white-space: nowrap; }   /* the campaign line stays on one line, nearly the full width */
.postcaption .after { display: inline-flex; align-items: center; gap: .3em; margin-top: .12em; }
.postcaption .emoji { font-size: .62em; letter-spacing: .04em; }
.postcaption .tail { font-family: var(--font-family-ui); font-size: clamp(15px, 1.5vw, 24px); letter-spacing: 0; color: #7ea2f5; }   /* the hashtag, in Instagram's link blue */
@media (max-width: 700px) { .postcaption .line { white-space: normal; } .postcaption blockquote { --cap-size: 44px; } }
.body .sec:has(> .sec-body > .postcaption) { grid-template-columns: 1fr; row-gap: 22px; }
.body .sec:has(> .sec-body > .postcaption) .sec-label, .body .sec:has(> .sec-body > .postcaption) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .postcaption) .sec-label h2 { position: static; margin-top: 0 !important; }

/* @igphones: the post and its comments drawer pulled straight out of the app onto the black page: no band or card behind
   them, just a soft shadow, side by side with the drawer staggered a little lower. The post's photos cross-fade through the carousel; the comments scroll on a slow loop (paused on hover,
   and still for anyone who has asked for reduced motion) */
.media.igphones { --ig: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif; --pw: clamp(260px, 21.2vw, 330px); --g: clamp(24px, 2.4vw, 40px);
  display: grid; grid-template-columns: minmax(0, 1fr) var(--pw) var(--pw) minmax(0, 1fr); column-gap: var(--g); align-items: start; margin: 0; padding: 0; }   /* equal side columns, so the pair of screens is always exactly centred */
.media.igphones > .ig-post { grid-column: 2; } .media.igphones > .ig-comments { grid-column: 3; }
.media.igphones > .ig-left { grid-column: 1; grid-row: 1; } .media.igphones > .ig-right { grid-column: 4; grid-row: 1; }
.ig-phone { flex: none; width: var(--pw); aspect-ratio: 9 / 19; background: #fff; color: #000; border-radius: calc(var(--pw) * .11); overflow: hidden;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,.55); font-family: var(--ig); font-size: calc(var(--pw) * .039); line-height: 1.3;
  display: flex; flex-direction: column; padding-top: calc(var(--pw) * .1); }
a.ig-phone { color: #000; text-decoration: none; border: 0; transition: transform .35s var(--motion-ease, ease), box-shadow .35s var(--motion-ease, ease); }
a.ig-phone:hover { transform: translateY(-4px); }   /* the screens open the real post; a small lift says they can be clicked */
a.ig-phone:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 4px; }
.ig-comments { margin-top: calc(var(--pw) * .22); margin-left: calc(var(--overlap) * -1); position: relative; z-index: 1; }   /* the stagger */
.ig-post { --ig-x: 1.2em; aspect-ratio: auto; padding-bottom: 1.5em; }   /* text inset a touch more so the last lines clear the rounded corners */   /* Instagram crops tight under the last comment */
.media.igphones { --overlap: 0px; }   /* set above 0 to tuck the drawer over the post; the text rows then stop short of it */
.ig-post .ig-actions, .ig-post .ig-liked, .ig-post .ig-cap, .ig-post .ig-all, .ig-post .ig-preview { padding-right: calc(var(--overlap) + var(--ig-x, .9em)); }   /* the rows under the photo stop short of the drawer, so nothing (least of all #ad) is hidden behind it */
.ig-av { flex: none; width: calc(var(--pw) * .09); height: calc(var(--pw) * .09); border-radius: 50%; object-fit: cover; background: #efefef; display: block; }
.ig-ico { width: calc(var(--pw) * .068); height: calc(var(--pw) * .068); flex: none; }
.ig-tick { width: 1.05em; height: 1.05em; vertical-align: -.16em; margin-left: .25em; }
/* the post */
.ig-head { display: flex; align-items: center; gap: .7em; padding: 0 var(--ig-x, .9em) .63em; margin-top: calc(var(--pw) * -.009); }   /* ~9% less air above and below the header */
.ig-who { flex: 1; min-width: 0; line-height: 1.25; }
.ig-who > b { font-weight: 600; }
.ig-who span { display: block; font-size: .88em; color: #000; }
.ig-who span b { font-weight: 600; }
.ig-more { color: #000; letter-spacing: .05em; font-size: .9em; }
.ig-photos { position: relative; aspect-ratio: 3 / 4; background: #efefef; overflow: hidden; }
.ig-photos img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; animation: ig-slide calc(var(--n) * 3.2s) infinite; animation-delay: calc(var(--i) * 3.2s - .8s); }   /* the -.8s starts the first photo already in view */
.ig-photos img:first-child { opacity: 1; }
@keyframes ig-slide { 0% { opacity: 0; } 4% { opacity: 1; } 20% { opacity: 1; } 24% { opacity: 0; } 100% { opacity: 0; } }
.ig-pager { display: flex; justify-content: center; gap: .3em; padding: .5em 0 0; }   /* dots 2-3px closer to the photo */
.ig-pager i { width: .42em; height: .42em; border-radius: 50%; background: #c7c7c7; animation: ig-dot calc(var(--n) * 3.2s) infinite; animation-delay: calc(var(--i) * 3.2s - .8s); }
@keyframes ig-dot { 0%, 22% { background: #0095f6; } 23%, 100% { background: #c7c7c7; } }
.ig-actions { display: flex; align-items: center; gap: .35em; padding: 0 var(--ig-x, .9em) .4em; margin-top: .3em; font-weight: 500; font-size: .95em; }   /* pulled up toward the dots; counts a touch lighter and ~7% smaller than before */
.ig-actions span { margin-right: .65em; }
.ig-actions svg + svg { margin-left: .5em; }   /* an icon with no count still gets the same breathing room */
.ig-actions .ig-save { margin-left: auto; }
.ig-liked, .ig-cap, .ig-all, .ig-preview { margin: 0; padding: 0 var(--ig-x, .9em) .18em; line-height: 1.28; }   /* Instagram stacks these almost like consecutive lines */
.ig-liked { padding-bottom: .3em; }
.ig-all { padding-top: .12em; }
.ig-preview { padding-top: .3em; }
.ig-preview b { font-weight: 600; }
.ig-liked b, .ig-cap > b { font-weight: 600; }
.ig-tag { color: #00376b; }
.ig-all { color: #8e8e8e; }
/* the comments */
.ig-sheet { display: flex; flex-direction: column; align-items: center; gap: .7em; padding: 0 0 .8em; border-bottom: 1px solid #efefef; }
.ig-sheet i { width: 2.6em; height: .3em; border-radius: 1em; background: #c7c7c7; }
.ig-sheet b { font-weight: 600; font-size: 1.05em; }
.ig-scroll { flex: 1; overflow: hidden; position: relative; }
.ig-track { list-style: none; margin: 0; padding: .4em 0 0; animation: ig-scroll calc(var(--count) * 2.6s) linear infinite; }
.ig-scroll:hover .ig-track { animation-play-state: paused; }
@keyframes ig-scroll { to { transform: translateY(-50%); } }
.ig-track li { display: flex; align-items: flex-start; gap: .75em; padding: .7em .95em; }
.ig-track li > div { flex: 1; min-width: 0; }
.ig-track li b { font-weight: 600; font-size: .93em; }
.ig-track li p { margin: .1em 0 .25em; }
.ig-track li span { font-size: .85em; color: #737373; font-weight: 600; }
.ig-track li time { font-size: .85em; color: #737373; margin-left: .3em; }
.ig-track li aside { display: flex; flex-direction: column; align-items: center; gap: .1em; margin-top: 1.1em; color: #8e8e8e; }
.ig-track li aside em { font-style: normal; font-size: .78em; }
.ig-like { width: 1.05em; height: 1.05em; color: #8e8e8e; stroke-width: 2.2; }
.ig-add { display: flex; align-items: center; gap: .7em; padding: .8em .95em 1.6em; border-top: 1px solid #efefef; color: #737373; }
@media (prefers-reduced-motion: reduce) {
  .ig-photos img { animation: none; } .ig-photos img:first-child { opacity: 1; }
  .ig-pager i { animation: none; } .ig-pager i:first-child { background: #0095f6; }
}   /* the comment list keeps its slow loop even with Reduce Motion on: it is the point of the mock, it crawls at about a line a second, and a finger on it pauses it */
/* a few standout comments on the black either side of the phones: all the same size, width and height, on one edge, like a real comment list */
.ig-side { --stagger: clamp(14px, 1.4vw, 22px); display: grid; gap: clamp(24px, 2.5vw, 40px); align-content: start; min-width: 0; }   /* site.js centres each column on the screen beside it */
.ig-left { justify-items: end; } .ig-right { justify-items: start; }
.ig-side .reaction footer { display: none; }
.ig-side .reaction .ig-heart { display: none; }   /* beside the phones: no heart either, just avatar, name and words */
.ig-side .reaction { grid-template-columns: calc(var(--fs) * 2.3) minmax(0, 1fr); padding: calc(var(--fs) * 1.615) !important; }   /* the same white on every side; site.js evens out the font's built-in line spacing */
   /* beside the phones the comments are just avatar, name and words: no Reply line, no action row */
.ig-side .reaction { --fs: clamp(12.5px, 1.05vw, 15px); width: auto; max-width: 100%; }
.ig-side .reaction:nth-child(even) { max-width: calc(100% - var(--stagger)); }
.ig-side .reaction { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); }   /* a whisper of depth against the black; the two screens keep their own shadow */   /* only the stepped cards give up the step's width */
.ig-left .reaction:nth-child(even) { margin-right: var(--stagger); }   /* one even step: the nearest card is one gap from the screen, the next steps out, and so on */
.ig-right .reaction:nth-child(even) { margin-left: var(--stagger); }
@media (max-width: 1199px) { .ig-side { display: none; } }   /* no room beside the phones on smaller screens; these comments are on the wall below too */
.body .sec:has(> .sec-body > .media.igphones) { grid-template-columns: 1fr; row-gap: 22px; }   /* full width, label on top */
.body .sec:has(> .sec-body > .media.igphones) .sec-label, .body .sec:has(> .sec-body > .media.igphones) .sec-body { grid-column: 1 / -1; }
.body .sec:has(> .sec-body > .media.igphones) .sec-label h2 { position: static; margin-top: 0 !important; }
@media (max-width: 700px) {
  .media.igphones { --pw: min(80vw, 310px); display: flex; flex-direction: column; align-items: center; gap: 0; padding: 0; }
  .media.igphones { --overlap: 0px; }
  .ig-comments { margin-top: 18px; margin-left: 0; }   /* on a phone the drawer simply stacks under the post */
}

/* the side comment tiles open large over a dimmed page (click or Enter; click anywhere or Esc to close) */
.ig-side .reaction { cursor: zoom-in; transition: transform .3s var(--motion-ease, ease); }
.ig-side .reaction:hover { transform: translateY(-2px); }
.ig-side .reaction:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 4px; }
.comment-box { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: 24px; background: rgba(0, 0, 0, .86); cursor: zoom-out; opacity: 0; transition: opacity .25s ease; }
.comment-box.is-open { opacity: 1; }
.comment-box .reaction { --fs: clamp(18px, 2.2vw, 30px); width: auto; max-width: min(92vw, 760px); margin: 0; padding: calc(var(--fs) * 1.615); grid-template-columns: calc(var(--fs) * 2.3) minmax(0, 1fr); box-shadow: 0 24px 60px rgba(0, 0, 0, .45); transform: scale(.96); transition: transform .25s ease; cursor: zoom-out; }
.comment-box.is-open .reaction { transform: none; }
.comment-box .reaction footer, .comment-box .reaction .ig-heart { display: none; }
.comment-box .close { position: absolute; top: 18px; right: 22px; width: 44px; height: 44px; border: 0; background: none; color: #fff; font-size: 34px; line-height: 1; cursor: pointer; }
@media (prefers-reduced-motion: reduce) { .comment-box, .comment-box .reaction, .ig-side .reaction { transition: none; } }

/* card_fit: whole: a tall card image (e.g. a press quote poster) shown in full on black instead of cropped to the card's shape */
.card .thumb img.whole, .next-media img.whole { object-fit: contain !important; background: #000; }

/* red sub-heds: bold Inter, uppercase, tracked (locked in) */
.list-lab, .strap .line, .more .lab, .credits .lab, .sec-label h2, .prose .dateline, .press .lab, .awards .lab, .next-text .lab, .pn-text .lab, .essay-h2, .ode-text .col > .lab, .contact-page .info-head .lab.eyebrow, .testimonials .more { font-weight: 600; }

/* project footer: previous and next as an editorial transition — black on black, fine rules, the content does the work */
.pn { display: grid; grid-template-columns: 1fr 1fr; position: relative; margin: calc(var(--margin-section) + var(--space-block)) var(--margin-page-side) 0; }
.pn::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--color-rule); }   /* the chapter break: a grey hairline, the same as the section rules above */
body:has(.pn) .foot { margin-top: 0; }   /* the footer sits on the site footer's own rule: two lines, not three */
.pn-item { position: relative; display: flex; align-items: center; gap: clamp(16px, 1.76vw, 28px); padding: clamp(19px, 2.1vw, 28px) 0; min-width: 0; transition: opacity .18s ease; }
.pn-prev { padding-right: clamp(16px, 1.76vw, 28px); }
.pn-next { justify-content: flex-end; text-align: right; padding-left: clamp(16px, 1.76vw, 28px); border-left: 1px solid var(--color-rule-subtle); }
.pn:has(.pn-item:hover, .pn-item:focus-visible) .pn-item:not(:hover):not(:focus-visible) { opacity: .55; }   /* the other half steps back */
.pn-item::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--color-accent); transform: scaleX(0); transition: transform .12s ease-out; }
.pn-prev::after { transform-origin: right; } .pn-next::after { transform-origin: left; }   /* previous draws right to left, next left to right */
.pn-item:hover::after, .pn-item:focus-visible::after { transform: scaleX(1); }   /* one thin red line draws in, fast, in the direction you're going */
.pn-media { flex: none; width: clamp(132px, 13.2vw, 211px); aspect-ratio: 16/9; overflow: hidden; border-radius: 6px; background: var(--color-surface); }
.pn-media img { width: 100%; height: 100%; object-fit: cover; filter: saturate(.92) brightness(.93); transition: filter .18s ease; }   /* a touch dimmed at rest */
.pn-item:hover .pn-media img, .pn-item:focus-visible .pn-media img { filter: none; }
.pn-text { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.pn-text .lab, .pn-text .k { font-size: calc(var(--font-size-ui) * .88); }   /* the whole footer runs 12% smaller than the body labels */
.pn-next .pn-text { align-items: flex-end; }
.pn-head { display: inline-flex; align-items: center; gap: 7px; color: var(--color-accent); }
.pn-chev { width: 5.3px; height: 8.8px; fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; transition: transform .18s ease; }
.pn-prev:hover .pn-chev, .pn-prev:focus-visible .pn-chev { transform: translateX(-5px); } .pn-next:hover .pn-chev, .pn-next:focus-visible .pn-chev { transform: translateX(5px); }
.pn-text .t { font-family: var(--font-family-display); font-size: clamp(17.6px, 1.5vw, 22.9px); line-height: 1.12; color: rgba(236,232,224,.82); text-wrap: balance; transition: color .18s ease; }
.pn-item:hover .pn-text .t, .pn-item:focus-visible .pn-text .t { color: #fff; }
.pn-text .k { color: var(--color-text-secondary); }
@media (max-width: 1000px) { .pn-item { flex-direction: column; align-items: flex-start; } .pn-next { align-items: flex-end; } .pn-next .pn-media { order: -1; } .pn-media { width: 100%; } }
@media (max-width: 640px) {   /* phones: Previous and Next side by side, each a small picture over compact type; no hover, so images stay full colour */
  .pn { grid-template-columns: 1fr 1fr; }
  .pn-item { gap: 10px; padding: 16px 0 18px; }
  .pn-prev { padding-right: 12px; } .pn-next { padding-left: 12px; }
  .pn-media img { filter: none; }
  .pn-text { gap: 5px; }
  .pn-text .lab, .pn-text .k { font-size: 10px; letter-spacing: .11em; }   /* 10px: the smallest type on the site, matching the hero sound pill */
  .pn-head { gap: 5px; } .pn-chev { width: 4.4px; height: 7.3px; }
  .pn-text .t { font-size: 15px; line-height: 1.15; }
}
html[data-theme="light"] .pn-chev { stroke: #000; } html[data-theme="light"] .pn-text .t { color: rgba(0,0,0,.8); } html[data-theme="light"] .pn-item:hover .pn-text .t { color: #000; }

/* phones: the nav becomes MENU, which opens a full-screen contents page of the work */
.menu-btn { display: none; padding: 10px 0 10px 12px; border: 0; background: none; cursor: pointer; font-family: var(--font-family-ui); font-size: 11.5px; font-weight: 500; letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; color: var(--color-text); }
.mnav { position: fixed; inset: 0; z-index: 80; height: 100dvh; display: flex; flex-direction: column; background: rgba(5,5,5,.985); opacity: 0; visibility: hidden; transition: opacity .2s ease, visibility 0s .2s; }
.mnav.is-open { opacity: 1; visibility: visible; transition: opacity .2s ease, visibility 0s; }
.mnav-top { flex: none; display: flex; align-items: center; justify-content: space-between; padding: 24px; }
.mnav-top .wordmark { width: 58px; height: 58px; } .mnav-top .wordmark img { width: 39px; }
.mnav-close { width: 44px; height: 44px; margin-right: -12px; display: inline-flex; align-items: center; justify-content: center; border: 0; background: none; cursor: pointer; }
.mnav-close svg { width: 16px; height: 16px; stroke: #fff; stroke-width: 1.6; stroke-linecap: round; }
.mnav-body { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 12px 24px calc(32px + env(safe-area-inset-bottom)); }   /* the list scrolls; the logo and close stay put */
/* "Work" heads the project list in the same type as Home and the other site links (it was a small red label), and opens the Work page */
.mnav-work { display: flex; flex-direction: column; }
.mnav-work a { display: flex; align-items: center; min-height: 38px; padding: 3px 0; font-family: var(--font-family-body); font-size: clamp(14.5px, 4vw, 16px); line-height: 1.2; color: rgba(236,232,224,.9); opacity: 0; transform: translateY(6px); transition: opacity .18s ease, transform .18s ease; }
.mnav.is-open .mnav-work a { opacity: 1; transform: none; transition-delay: calc(var(--i, 0) * 6ms); }   /* the titles rise in with a barely-there stagger */
.mnav-folder { display: flex; flex-direction: column; opacity: 0; transform: translateY(6px); transition: opacity .18s ease, transform .18s ease; }   /* a client with several projects: its name, then its projects tucked beneath */
.mnav.is-open .mnav-folder { opacity: 1; transform: none; transition-delay: calc(var(--i, 0) * 6ms); }
.mnav-client { display: flex; align-items: center; min-height: 38px; padding: 3px 0; font-family: var(--font-family-body); font-size: clamp(14.5px, 4vw, 16px); line-height: 1.2; color: rgba(236,232,224,.9); }
.mnav-folder a { opacity: 1; transform: none; min-height: 34px; padding-left: 14px; font-size: clamp(13px, 3.5vw, 14px); color: var(--color-text-secondary); }
.mnav-folder a:last-child { margin-bottom: 6px; }
.mnav-folder a::before { content: "\2192"; margin-right: .55em; color: var(--color-accent); font-size: .92em; }   /* the red arrow in front of each project tucked under a client, as on the home list */
/* the site's own pages (Home, CV, NSFW, About, Contact) lead the menu's list, set like the client names, so nobody scrolls past every project to find them (they used to sit in a small row at the foot) */
.mnav-links { display: flex; flex-direction: column; margin: 0 0 26px; }
.mnav-links a, .mnav-head { display: flex; align-items: center; min-height: 38px; padding: 3px 0; font-family: var(--font-family-body); font-size: clamp(14.5px, 4vw, 16px); line-height: 1.2; color: rgba(236,232,224,.9); opacity: 0; transform: translateY(6px); transition: opacity .18s ease, transform .18s ease; }
.mnav.is-open .mnav-links a, .mnav.is-open .mnav-head { opacity: 1; transform: none; transition-delay: calc(var(--i, 0) * 6ms); }
.mnav-links a[aria-current="page"], .mnav-head[aria-current="page"] { color: #fff; }
.mnav-head { --i: 5; }
.mnav a { -webkit-tap-highlight-color: transparent; }   /* no grey box flashing behind a tapped link: the red is the feedback */
.mnav-links a:active, .mnav-links a.is-tapped, .mnav-head:active, .mnav-head.is-tapped, .mnav-work a:active, .mnav-work a.is-tapped { color: var(--color-accent); transition-duration: 0s; }   /* a tapped link goes red */
@media (max-width: 820px) { .nav { display: none; } .menu-btn { display: inline-flex; } }
@media (min-width: 821px) { .mnav { display: none; } }
@media (prefers-reduced-motion: reduce) { .mnav, .mnav-work a, .mnav-links a, .mnav-head, .mnav-folder { transition: none; } }
html.mnav-open, html.mnav-open body { overflow: hidden; }

/* a quiet chevron at the foot of every hero, below the film controls, pointing down to the case study */
.hero-more { position: absolute; left: 50%; bottom: 8px; z-index: 3; width: 40px; height: 40px; margin-left: -20px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid rgba(255,255,255,.55); border-radius: 50%; background: rgba(0,0,0,.35); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); opacity: 1; transition: opacity .2s ease, transform .2s ease; }
.hero-more svg { width: 14px; height: 9px; fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); animation: hero-more-nudge 2.4s ease-in-out infinite; }
.hero-more:hover { border-color: #fff; background: rgba(0,0,0,.5); }
.hero-more:hover svg, .hero-more:focus-visible svg { animation: hero-more-bounce .7s ease-in-out infinite; }   /* bounces on hover, so it reads as a button */
@keyframes hero-more-bounce { 0%, 100% { transform: translateY(-2px); } 50% { transform: translateY(4px); } }   /* a ringed button, like the play button and carousel arrows */
.to-top { position: fixed; left: max(4px, calc((var(--margin-page-side) - 40px) / 2)); top: 50%; z-index: 60; width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 1px solid rgba(255,255,255,.55); border-radius: 50%; background: rgba(0,0,0,.35); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); cursor: pointer; transform: translateY(-50%); opacity: 0; visibility: hidden; transition: opacity .25s ease, visibility 0s .25s, border-color .2s, background .2s; }   /* back to top: the hero's ringed arrow (as on Freelance), pointing up, centred in the left page margin halfway down the screen */
.to-top.is-on { opacity: 1; visibility: visible; transition: opacity .25s ease, visibility 0s, border-color .2s, background .2s; }
.to-top svg { width: 14px; height: 9px; fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); transition: stroke .2s; }   /* the hero arrow's exact chevron, turned up */
.to-top:hover, .to-top:focus-visible { border-color: var(--color-accent); background: rgba(0,0,0,.5); }
.to-top:hover svg, .to-top:focus-visible svg { stroke: var(--color-accent-hover); }   /* red on hover */
@media (max-width: 700px) { .to-top { left: auto; right: 12px; top: auto; bottom: 16px; transform: none; } }   /* phones: the margin is too narrow to hold it mid-screen, so it sits in the bottom-right corner, clear of left-aligned text */
html.mnav-open .to-top { display: none; }
@keyframes hero-more-nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(4px); } }
@media (prefers-reduced-motion: reduce) { .hero-more svg { animation: none; } }
@media (max-width: 700px) { .hero-more { display: none; } }   /* phones: the hero is short enough that the case study already shows */
.hero.has-video { cursor: pointer; }   /* click the film to pause or play */
.sub-lab { display: block; color: var(--color-accent); font-weight: 600; margin: var(--space-media) 0 var(--space-row); max-width: none; line-height: 1.5; }   /* a red sub-head inside a section, above its media */
.carousel-track { cursor: grab; } .carousel-track.is-dragging { cursor: grabbing; user-select: none; }   /* click and drag through the images */
.carousel-track.is-dragging img { pointer-events: none; }
.carousel-track figcaption { cursor: text; user-select: text; }   /* highlight caption text without dragging the carousel */

/* @proofs: captioned proof-point tiles, one crop shape so the captions line up */
.proofs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(36px, 3.4vw, 56px) var(--space-gallery-gap); align-items: start; }
.proof { margin: 0; }
.proof-pic { aspect-ratio: 4 / 5; overflow: hidden; background: var(--color-surface); }
.proof-pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
.proof figcaption { display: block; padding: 14px 0 0; }
.proof figcaption .lab { display: block; color: var(--color-accent); font-weight: 600; margin: 0 0 6px; }
.proof figcaption p { font-family: var(--font-family-body, "Instrument Sans", sans-serif); font-size: 15px; line-height: 1.45; color: var(--color-text-secondary, rgba(255,255,255,.72)); margin: 0; max-width: none; text-wrap: pretty; }
@media (max-width: 820px) { .proofs { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .proofs { grid-template-columns: 1fr; } }

/* @carousel proofs: same 4:5 crop on every slide so the red hed + sentence captions line up */
.carousel.is-proofs { --pw: clamp(260px, 25vw, 380px); --mosaic-gap: 22px; }   /* a little more air between slides than the photo carousels */
.carousel.is-proofs .slide { width: var(--pw); }
.carousel.is-proofs .slide img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; }
.carousel.is-proofs .slide.wide { width: calc(var(--pw) * 2 + var(--mosaic-gap, 14px)); }   /* a side-by-side pair: two slides wide, same height */
.carousel.is-proofs .slide.wide img { aspect-ratio: auto; height: calc(var(--pw) * 1.25); }
.carousel.is-proofs .slide.natural { width: calc(var(--pw) * 1.25 * var(--ar, .8)); }   /* the photo at its own shape, same height as the rest */
.carousel.is-proofs .slide.natural img { aspect-ratio: auto; width: 100%; height: auto; }
.carousel.is-proofs .slide figcaption { display: block; letter-spacing: 0; padding: 14px clamp(20px, 2vw, 32px) 0 0; }   /* room on the right so captions never run into the next slide */
.carousel.is-proofs .slide figcaption .lab { display: block; color: rgba(255,255,255,.86); font-weight: 700; font-size: 11px; margin: 0 0 6px; }   /* white and bold, so only the section hed is red */
.carousel.is-proofs .slide figcaption .cap-line { display: block; font-family: var(--font-family-body); font-size: 13.5px; line-height: 1.4; color: var(--color-text-secondary); text-wrap: pretty; }
@media (max-width: 700px) { .carousel.is-proofs .slide.natural { width: calc(100vw - 2 * var(--margin-page-side, 16px)); } .carousel.is-proofs .slide.natural img { width: 100%; height: auto; } .carousel.is-proofs { --pw: 78vw; } .carousel.is-proofs .slide.wide { width: calc(100vw - 2 * var(--margin-page-side, 16px)); } .carousel.is-proofs .slide.wide img { height: auto; } }

/* intro_media: a carousel in the intro photo's place, one full-width slide at a time */
.head-media .carousel { margin: 0; }
.head-media .carousel .slide { width: 100%; height: auto; }
.head-media .carousel .slide video { display: block; width: 100%; height: 100%; object-fit: cover; }
.carousel.is-proofs .slide.wide figcaption .cap-line, .carousel.is-proofs .slide.natural figcaption .cap-line { max-width: none; }   /* wide slides: captions run the full width of the photo */
.media .frame { border-radius: 10px; overflow: hidden; }   /* inline films get the same 10px corners as the photos */
.media .frame video, .media .frame iframe { border-radius: inherit; }
.carousel.is-proofs .tk-pic { aspect-ratio: 4 / 5; border-radius: 10px; border: 1px dashed rgba(255,255,255,.22); background: var(--color-surface); display: grid; place-items: center; font-family: var(--font-family-ui); font-size: 13px; letter-spacing: .14em; color: var(--color-text-tertiary); }   /* TK placeholder slide */
.carousel.is-proofs .cap-list { list-style: none; margin: 10px 0 0; padding: 0; font-family: var(--font-family-body); font-size: 13.5px; line-height: 1.55; color: var(--color-text-secondary); }   /* a caption's list of names */
.carousel.is-proofs .cap-list b { font-weight: 600; color: rgba(255,255,255,.9); }
.carousel.is-proofs figcaption > .cap-list:first-child { margin-top: 0; }
.carousel.is-proofs .cap-name { display: block; font-family: var(--font-family-body); font-size: 14px; font-weight: 600; color: rgba(255,255,255,.92); margin: 0 0 3px; }   /* a solo portrait's name, its descriptor below */
.carousel-ui { justify-content: center; }   /* arrows and counter sit centred under every carousel */
.carousel.is-single .carousel-ui { display: none; }   /* a lone slide has nothing to step through */

/* @carousel rows2: two rows scrolling together; each column pairs two similar shapes, "tall" items fill both rows */
.carousel.is-rows2 { --rh: clamp(130px, 16.5vw, 275px); --rg: var(--mosaic-gap, 14px); }
.carousel.is-rows2 .col { flex: none; display: flex; flex-direction: column; gap: var(--rg); width: calc(var(--rh) * var(--ar)); scroll-snap-align: start; }
.carousel.is-rows2 .col.tall { width: calc((var(--rh) * 2 + var(--rg)) * var(--ar)); }
.carousel.is-rows2 .slide { height: var(--rh); width: 100%; border-radius: 10px; overflow: hidden; }
.carousel.is-rows2 .col.tall .slide { height: calc(var(--rh) * 2 + var(--rg)); }
.carousel.is-rows2 .slide img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 700px) { .carousel.is-rows2 { --rh: 150px; } .carousel.is-rows2 .slide { height: var(--rh); width: 100%; } .carousel.is-rows2 .slide img { height: 100%; } }

/* @credits: a credits column to the right of a section's opening paragraph */
.body .sec-body:has(> .side-credits) { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 520px); column-gap: clamp(22px, 2.6vw, 48px); align-items: start; }   /* credits sit close to the film, like liner notes */
.body .sec-body:has(> .side-credits) > * { grid-column: 1 / -1; min-width: 0; }   /* min-width 0: a carousel inside never stretches the grid */
.body .sec-body:has(> .side-credits) > :first-child { grid-column: 1; grid-row: 1; }
.body .sec-body > .side-credits { grid-column: 2; grid-row: 1; display: grid; gap: 22px; margin: 0; }
.side-credits .lab { display: block; color: var(--color-accent); font-weight: 600; margin: 0 0 8px; }
.side-credits ul { list-style: none; margin: 0; padding: 0; font-family: var(--font-family-body); font-size: 14.5px; line-height: 1.5; color: rgba(255,255,255,.6); }   /* family names a touch brighter than tertiary, still subordinate */
.side-credits li { margin: 0 0 3px; }
.side-credits li b { font-weight: 500; color: #fff; }   /* masthead: the name in bold, the family lighter */
@media (max-width: 900px) { .body .sec-body:has(> .side-credits) { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-row); } .body .sec-body > .side-credits { grid-column: 1; grid-row: auto; } }
@media (min-width: 901px) {   /* story first, across the top; then the film and its credits side by side, tops aligned */
  .body .sec-body:has(> .side-credits) > :first-child { grid-column: 1 / -1; grid-row: 1; }
  .body .sec-body:has(> .side-credits) > :first-child p { max-width: 40em; }
  .body .sec-body:has(> .side-credits) > .prose:has(> p.p-wide) { max-width: none; }
  .body .sec-body:has(> .side-credits) > :first-child p.p-wide { max-width: 46em; }   /* the VS Mother's Day paragraph, set to run two lines */
  .body .sec-body:has(> .side-credits) > .media.video { grid-column: 1; grid-row: 2; align-self: start; }
  .body .sec-body > .side-credits { grid-column: 2; grid-row: 2; align-self: center; margin: var(--space-media) 0 calc(var(--space-media) + var(--film-cap, 30px)); }   /* centred on the film itself: the bottom margin also covers the running-time line under it */
  .body .sec-body:has(> .side-credits) > .sub-lab { margin-top: 0; }   /* the next module follows the film closely */
  .body .sec-body:has(> .side-credits) > .media.video:first-child ~ .carousel { grid-row: 3; }   /* no story paragraph: the film and credits lead, the carousel follows them */
}
@media (max-width: 900px) {   /* phones: story, then the film, then its credits */
  .body .sec-body:has(> .side-credits) > .media.video { grid-row: 2; }
  .body .sec-body:has(> .side-credits) > .side-credits { grid-row: 3; }
  .body .sec-body:has(> .side-credits) > .sub-lab { grid-row: 4; }
  .body .sec-body:has(> .side-credits) > .carousel { grid-row: 5; }
}

/* "@ side": a long caption set beside its photo, so it doesn't make the whole carousel taller */
.carousel.is-proofs .slide.side { display: grid; grid-template-columns: calc(var(--pw) * 1.25 * var(--ar, 1)) minmax(260px, 320px); column-gap: 24px; align-items: end; width: auto; }
.carousel.is-proofs .slide.side img { aspect-ratio: auto; width: 100%; height: calc(var(--pw) * 1.25); }
.carousel.is-proofs .slide.side figcaption { padding: 0; }
@media (max-width: 700px) { .carousel.is-proofs .slide.side { display: block; width: calc(100vw - 2 * var(--margin-page-side, 16px)); } .carousel.is-proofs .slide.side img { width: 100%; height: auto; } .carousel.is-proofs .slide.side figcaption { padding: 14px 0 0; } }
/* credits after a carousel (no film beside them): they simply follow it, left-aligned, at the usual media spacing */
.body .sec-body:has(> .side-credits):not(:has(> .media.video)) { display: block; }
.body .sec-body:not(:has(> .media.video)) > .side-credits { margin: var(--space-media) 0 0; }
@media (min-width: 901px) {   /* desktop: the credits start level with the carousel's arrows, at the left, instead of below them */
  .body .sec-body:not(:has(> .media.video)) > .carousel + .side-credits { margin-top: calc(-44px - var(--space-media)); width: fit-content; position: relative; }   /* 44px = the arrow row's height, plus the carousel's own bottom margin it collapses with; fit-content keeps the arrows clickable */
}
/* "@carousel grow": a shorter row whose slides lift and grow under the mouse. The growth is a transform, not a size change,
   so nothing shifts under the cursor and the carousel never re-snaps (a size change made it jump back and forth) */
@media (hover: hover) and (min-width: 701px) {
  .carousel.is-grow { display: flow-root; }   /* keeps the track's negative margin from shrinking the gap above */
  .carousel.is-grow .carousel-track { --bleed: min(40px, max(var(--space-page-gutter), calc((100vw - var(--container-max)) / 2))); padding: 40px var(--bleed); margin: -40px calc(-1 * var(--bleed)); scroll-padding-inline: var(--bleed); }   /* room for a grown slide, so it isn't clipped; never reaches past the page margin (narrow windows) */
  .carousel.is-grow .slide { height: calc(clamp(380px, 48vw, 720px) * .7); transition: transform .3s ease, box-shadow .3s ease; position: relative; }
  .carousel.is-grow .slide:hover { transform: scale(1.15); z-index: 2; box-shadow: 0 16px 44px rgba(0,0,0,.65); }
}
/* a section with no heading: its first subhed sits where a section heading would, not a subhed's gap lower */
.sec.no-label:not(.sec-intro) > .sec-label { display: none; }   /* no empty heading row (and its gap) above the content */
.sec.no-label .sec-body > .sub-lab:first-child, .sec.no-label .sec-body > :empty:first-child + .sub-lab { margin-top: 0; }   /* :empty also skips a wrapper that holds only a comment */
/* inside a credits grid, margins add up instead of overlapping like they do in normal flow; trim them back to the standard gaps */
.body .sec-body:has(> .side-credits) > .sub-lab + .carousel { margin-top: calc(var(--space-media) - 16px); }   /* subhed to carousel: the usual --space-media, not 16px more */
.body .sec-body:has(> .side-credits) > .media.video:first-child ~ .carousel { margin-top: 0; }   /* film to carousel: just the film's own bottom margin */
/* stacked catalogs (the shorter "grow" carousels) read as one run: a tighter gap between them than between separate modules */
.sec-body > .carousel:has(+ .carousel.is-grow) { margin-bottom: 24px; }
.sec-body > .carousel + .carousel.is-grow { margin-top: 24px; }
/* two-row carousels: the tile under the mouse lifts and grows a little; the track gets breathing room so the grown tile isn't clipped */
@media (hover: hover) and (min-width: 701px) {
  .carousel.is-rows2 { display: flow-root; }   /* keeps the track's negative margin from leaking out and shrinking the gap above */
  .carousel.is-rows2 .carousel-track { padding: 24px; margin: -24px; scroll-padding-inline: 24px; }
  .carousel.is-rows2 .col { position: relative; }
  .carousel.is-rows2 .col:hover { z-index: 2; }
  .carousel.is-rows2 .slide { transition: transform .3s ease, box-shadow .3s ease; }
  .carousel.is-rows2 .slide:hover { transform: scale(1.14); box-shadow: 0 14px 40px rgba(0,0,0,.65); position: relative; z-index: 2; }
  .carousel.is-rows2 .col.tall .slide:hover { transform: scale(1.06); }   /* the tall tiles have less room to grow into */
}
@media (hover: hover) and (min-width: 701px) {   /* the tracks above reach past the column for hover room; clip the sides back to the column so no neighbouring slide peeks into the margin */
  .carousel.is-grow .carousel-track { clip-path: inset(0 40px); }
  .carousel.is-rows2 .carousel-track { clip-path: inset(0 24px); }
}
/* "@carousel rows3": three shorter rows; tall tiles fill all three */
.carousel.is-rows3 { --rh: calc(clamp(110px, 12.5vw, 205px) * var(--rows-scale, 1)); }   /* --rows-scale: "@carousel rows3 85%" */
.carousel.is-rows3 .col.tall { width: calc((var(--rh) * 3 + var(--rg) * 2) * var(--ar)); }
.carousel.is-rows3 .col.tall .slide { height: calc(var(--rh) * 3 + var(--rg) * 2); }
@media (max-width: 700px) { .carousel.is-rows3 { --rh: calc(110px * var(--rows-scale, 1)); } }
/* credits that open a section (A Summer Story): they sit in a narrow column under the heading, the work beside them on the right */
@media (min-width: 901px) {
  .body .sec-body:has(> .side-credits:first-child):not(:has(> .media.video)) { display: grid; grid-template-columns: minmax(170px, 230px) minmax(0, 1fr); column-gap: clamp(22px, 2.6vw, 48px); align-items: start; }
  .body .sec-body:has(> .side-credits:first-child):not(:has(> .media.video)) > * { grid-column: 2; min-width: 0; }
  .body .sec-body:has(> .side-credits:first-child):not(:has(> .media.video)) > .side-credits { grid-column: 1; grid-row: 1 / span 6; align-self: start; margin: 0; width: auto; }
  .body .sec-body:has(> .side-credits:first-child):not(:has(> .media.video)) > .carousel:nth-child(2) { margin-top: 0; }   /* the first carousel starts level with the credits */
}
/* the two-row, three-row and grow carousels have big tiles, so their stops are far apart; mandatory snapping pulled a small swipe
   right back to the previous stop (it looked like the carousel jumping left). Proximity only snaps when a stop is close by */
.carousel.is-rows2 .carousel-track, .carousel.is-grow .carousel-track { scroll-snap-type: none; }   /* no snapping at all: a swipe stays where it lands; the arrows still step tile by tile */
.carousel-ui button:disabled { opacity: .3; cursor: default; }   /* at either end of a carousel the arrow rests, dimmed */

/* rows3: a stack of two splits the full height between them (half-size tiles, no empty third row) */
.carousel.is-rows3 .col.pair { width: calc((var(--rh) * 3 + var(--rg)) / 2 * var(--ar)); }
.carousel.is-rows3 .col.pair .slide { height: calc((var(--rh) * 3 + var(--rg)) / 2); }
/* when a stacked tile does crop, keep the top of the frame, where the faces are */
.carousel.is-rows2 .slide img { object-position: 50% 15%; }
/* no hover zoom mid-scroll (site.js sets .is-scrolling); the track itself still takes the wheel */
.is-scrolling .carousel .slide { pointer-events: none; }
/* all-film rows grid: taller rows so the player controls fit; the film fills its tile */
.carousel.is-rows2.is-video { --rh: clamp(230px, 23vw, 360px); }
.carousel.is-rows2 .slide.video { background: #000; }
.carousel.is-rows2 .slide.video video { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (max-width: 700px) { .carousel.is-rows2.is-video { --rh: 230px; } }
/* an all-film three-row strip: full-height films already have room for controls, so keep the same height as the mixed strips */
.carousel.is-rows3.is-video { --rh: calc(clamp(110px, 12.5vw, 205px) * var(--rows-scale, 1)); }
@media (max-width: 700px) { .carousel.is-rows3.is-video { --rh: calc(110px * var(--rows-scale, 1)); } }
/* with a mouse or trackpad nothing snaps: a scroll stays exactly where it lands (snapping read as the row bouncing away); phones keep one-at-a-time snapping */
@media (hover: hover) and (pointer: fine) { .carousel-track, .testimonials { scroll-snap-type: none; } }
/* phones: a film in a carousel is never wider than the screen (a fixed 520px height made wide films 900px across); each sits centred at its own shape */
@media (max-width: 700px) {
  .carousel:not(.is-rows2):not(.is-grow) .carousel-track { align-items: center; }
  .carousel:not(.is-rows2):not(.is-grow) .slide.video { width: 100%; height: auto; max-height: 70vh; }
}
.press .note { white-space: nowrap; }   /* "Beauty Awards 2022" wraps as one piece, never "Beauty / Awards 2022" */
@media (min-width: 1200px) { .body .sec.sec-intro .head-media > .media.video { margin-left: auto; margin-right: 0; } }   /* a film beside the intro lines up with the page's right edge, like the intro photos do */
.body .sec.sec-intro .head-media > .media.video { margin-top: 0; }   /* the film's top lines up with the headline's */
.body .sec.sec-intro .head-media > .media.video figcaption { display: none; }   /* no running-time caption beside the intro */
.carousel.is-rows2 .slide.video.fit video { object-fit: contain; }   /* a film shown whole in a wider tile; the figure's background matches the film's own */
/* phones, hero_fit: whole film: the play bar and "Watch with sound" sit in a strip under the film, so they never cover captions or credits in the picture */
@media (max-width: 700px) {
  .hero.has-video.hero-whole { aspect-ratio: auto; display: block; padding-top: 84px; padding-bottom: 56px; }   /* starts below the menu, so the logo never sits on words in the film */
  .hero.has-video.hero-whole .hero-media { position: relative; inset: auto; display: block; }
  .hero.has-video.hero-whole .hero-media video { height: auto; }
  .hero.has-video.hero-whole .sound { top: auto; bottom: 9px; }
  .hero.has-video.hero-whole .hero-ctrl { bottom: 9px; right: calc(var(--margin-page-side) + 190px); }
  .hero.has-video.hero-whole .hero-ctrl.no-sound { right: var(--margin-page-side); }
  .hero.has-video.hero-whole .hero-more { display: none; }   /* the case study starts right under the strip anyway */
}
/* hero_inset (e.g. 2.5vw): a full-frame film pulled in from the screen edges on a black field, so captions in the picture get breathing room */
.hero.has-video.hero-whole.has-inset .hero-media { padding: calc(var(--hero-inset) * .5625) var(--hero-inset); }
.hero.has-video.hero-whole.has-inset .hero-media video { object-fit: contain; }
@media (max-width: 700px) { .hero.has-video.hero-whole.has-inset .hero-media { padding: 0; } }   /* phones keep the film edge to edge; every pixel of width counts there */
/* hero_fit: whole on wider screens: "Watch with sound" drops to the play bar's row, below the picture's captions; the bar stops short of it */
@media (min-width: 701px) {
  .hero.has-video.hero-whole .sound { bottom: calc(var(--space-block) + 24px - 1px); }
  .hero.has-video.hero-whole .hero-ctrl:not(.no-sound) { right: calc(var(--margin-page-side) + 196px); }
}
.media.row .cell.video { background: #000; }
.media.row .cell video { display: block; width: 100%; height: 100%; object-fit: cover; }
.head-media > .media.row { margin: 0; }
@media (max-width: 700px) { .head-media > .media.row { flex-direction: row; } .head-media > .media.row .cell { flex: var(--r) 1 0 !important; } }   /* beside-the-intro pairs stay side by side on phones */
@media (max-width: 1199px) { .body .sec.sec-intro .head-media:has(> .media.row) { justify-self: stretch; width: 100%; max-width: 620px; } }   /* a film-and-photo pair stacked under the intro keeps a real width (a flexible row can't size itself) */

/* mobile_lead: on phones a film sits between the credits and the intro (the copy further down is hidden there); elsewhere it doesn't show */
.mobile-lead { display: none; padding-left: var(--margin-page-side); padding-right: var(--margin-page-side); }
.credits + .mobile-lead + .body { padding-top: 0; }   /* the hidden phone-only film mustn't break the credits-to-intro spacing (the credits' own padding is the whole run to the rule) */
@media (max-width: 700px) {
  .mobile-lead { display: block; padding-bottom: 47.925px; }
  .mobile-lead > .media { margin: 0; }
  .mobile-lead figcaption { display: none; }
  .mobile-lead .mobile-lead-cap { margin: 0; padding-top: 10px; font-family: var(--font-family-ui); font-size: var(--font-size-caption); letter-spacing: .02em; color: var(--color-text-tertiary); }   /* the intro photo's caption, when that photo leads on phones: same style as under the photo on desktop */
  .mobile-lead .mobile-lead-cap i { font-family: var(--font-family-body); font-size: 1.08em; letter-spacing: 0; }
  .mobile-lead .mobile-lead-cap a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; color: inherit; }
  .mobile-lead + .body { padding-top: 0; }
  .body .media.not-phone, .body .head-photo.not-phone { display: none; }
  .mobile-lead > .media.image img { border-radius: 12px; }
  .body .sec-body > .media.not-phone:first-child + * { margin-top: 0; }   /* what follows the hidden film sits where the film did */
}

/* play badge: a round play button centred on every click-to-play film until it starts */
.play-badge { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 72px; height: 72px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .7); background: rgba(0, 0, 0, .45); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); color: #fff; display: grid; place-items: center; cursor: pointer; z-index: 2; padding: 0; transition: background .2s, border-color .2s, transform .2s, opacity .2s; }
.play-badge svg { width: 28px; height: 28px; fill: currentColor; margin-left: 3px; }
.play-badge:hover { background: rgba(0, 0, 0, .6); border-color: var(--color-accent); transform: translate(-50%, -50%) scale(1.06); }
.play-badge.is-hidden { opacity: 0; pointer-events: none; }
@media (max-width: 700px) { .play-badge { width: 52px; height: 52px; } .play-badge svg { width: 22px; height: 22px; } }

/* a red lead-in that makes a payoff line pop, e.g. "The result:" */
.prose .lead-in, .lead-in { color: var(--color-accent); font-weight: 600; }

/* hero-wide: a widescreen film (wider than 2:1) shown whole at its own shape; on every screen the play bar and "Watch with sound" sit in a strip under the picture, clear of its titles and subtitles */
.hero.has-video.hero-whole.hero-wide { aspect-ratio: auto; display: block; padding-bottom: 76px; }
.hero.has-video.hero-whole.hero-wide .hero-media { position: relative; inset: auto; display: block; }
.hero.has-video.hero-whole.hero-wide .hero-media video { height: auto; aspect-ratio: var(--hero-ar); }
.hero.has-video.hero-whole.hero-wide .sound { top: auto; bottom: 16px; }
.hero.has-video.hero-whole.hero-wide .hero-ctrl { bottom: 16px; }
.hero.has-video.hero-whole.hero-wide .hero-more { display: none; }
@media (max-width: 700px) { .hero.has-video.hero-whole.hero-wide { padding-top: 84px; padding-bottom: 56px; }   /* a short widescreen film starts below the menu, so the logo never sits on its titles */ .hero.has-video.hero-whole.hero-wide .sound, .hero.has-video.hero-whole.hero-wide .hero-ctrl { bottom: 9px; } }

/* phones: a wide film in a rows strip never runs wider than the screen; it shows whole at its own shape (vertical films are already narrower and stay as they are) */
@media (max-width: 700px) {
  .carousel.is-rows2 .col.tall:has(> .slide.video) { max-width: calc(100vw - 2 * var(--margin-page-side)); }
  .carousel.is-rows2 .col.tall:has(> .slide.video) .slide { height: auto; aspect-ratio: var(--ar); max-height: calc(var(--rh) * 3 + var(--rg) * 2); }
}

/* lightbox, tall pieces (recipe pins): shown at a readable width and scrolled, not shrunk to the screen height */
.lightbox.is-tall:not([hidden]) { display: block; overflow-y: auto; overscroll-behavior: contain; }   /* :not([hidden]): once closed it must not linger as an invisible layer over the page */
.lightbox.is-tall figure { max-width: none; max-height: none; padding: 7vh 0 9vh; }
.lightbox.is-tall img { max-height: none; max-width: 94vw; width: min(94vw, 820px); cursor: default; }
.lightbox.is-tall .lb-close, .lightbox.is-tall .lb-prev, .lightbox.is-tall .lb-next { position: fixed; }

/* home list, hover: the active title at full strength, the rest drop to ~25%; the film behind crossfades in 300ms */
.list a { position: relative; }
.list a.is-active, .list a.is-active .t { color: var(--color-text); }   /* full strength (white in the dark theme) */
.list:hover a:not(.is-active) { color: color-mix(in srgb, var(--color-text) 35%, var(--color-background)); }   /* a solid mid grey, never see-through, so busy frames don't bleed into the letters */
html[data-theme="light"] .list a { text-shadow: none; }
body:has(.list:hover, .list a:focus-visible) .reel .bg { transition-duration: .3s; }   /* a quick, soft crossfade while choosing; the slow 1.1s fade stays for the auto-advance */

/* the TV grid: no hover zoom (clicking plays the spot large instead), and no play bar on the tiles */
.carousel.is-rows2.is-video:not(.is-rows3) .slide:hover, .carousel.is-rows2.is-video:not(.is-rows3) .col.tall .slide:hover { transform: none; box-shadow: none; }
.carousel.is-rows2.is-video:not(.is-rows3) .slide { cursor: pointer; }

/* title-over banner: the copy a little narrower than its column; the scroll arrow centred just below the banner, clear of the copy */
.hero-over .head-intro { max-width: min(var(--measure-body), 85%); }
.hero.hero-banner.title-over { padding-bottom: 64px; }
.hero.hero-banner.title-over .hero-more { bottom: 12px; }

/* a square hero film shown whole on black: "Watch with sound" sits in the film's own bottom-right corner, not out in the black */
@media (min-width: 701px) { .hero.square.has-video .sound { right: calc((100% - min(100svh, 100%)) / 2 + 20px); bottom: 20px; } }

/* lightbox zoom: click the picture to zoom 2.5x on that spot and move to look around; click again to zoom out */
.lightbox:not(.is-tall) img { cursor: zoom-in; transition: transform .3s var(--motion-ease); }
.lightbox.is-zoomed img { transform: scale(2.5); cursor: zoom-out; }
.lightbox.is-zoomed figure { overflow: hidden; max-width: 94vw; max-height: 94vh; }
.lightbox button { z-index: 2; }

/* ---------- Phones: touch targets, the title-over banner, safe areas ---------- */
@media (max-width: 820px) {
  .menu-btn { min-height: 44px; align-items: center; }   /* MENU is a 44px-tall tap target */
}
@media (max-width: 700px) {
  /* every control at least 44px tall to tap, without changing how it looks */
  .foot .r a, .foot-in > a { display: inline-flex; align-items: center; min-height: 44px; }
  .foot .r { flex-wrap: wrap; column-gap: 22px; row-gap: 0; }
  .press .press-links > a { display: flex; flex-wrap: wrap; align-items: center; align-content: center; column-gap: .3em; min-height: 32px; }   /* single-spaced rows (still a comfortable full-width tap); a note (an award) can still drop to its own line */
  .press .press-links { row-gap: 0; }
  .fav-tabs button { min-height: 44px; }
  .fav-more { min-height: 44px; }
  .carousel-nav .arrows button { width: 44px; height: 44px; }
  .carousel-nav .dots button::after { content: ""; position: absolute; inset: -10px 0; }   /* on phones each dot's tap target is 44px tall */
  .testimonials .more { min-height: 44px; display: inline-flex; align-items: center; margin-top: 6px; margin-bottom: 16px; }
  /* hero controls: visually small (the pill text sits under the body copy's size), each with an invisible 44px tap area */
  .hc-seek { height: 28px; }   /* the play bar's line stays 3px; the bar itself is a 28px-tall target */
  .hc-play { width: 32px; height: 32px; position: relative; }
  .hc-play svg { width: 9px; height: 11px; }
  .hc-play::after { content: ""; position: absolute; inset: -6px; }
  .sound { font-size: 10px; padding: 7px 11px 6px; }
  .sound::after { content: ""; position: absolute; inset: -8px -4px; }
  /* the title-over banner (Freelance): headline and copy at full width, the photo beneath them, as on the CV page */
  .hero.hero-banner.title-over .hero-media { display: flex; flex-direction: column; align-items: stretch; aspect-ratio: auto; overflow: visible; background: none; border-radius: 0; }
  .hero.hero-banner.title-over .hero-media img { position: static; order: 2; width: 100%; max-width: none; height: auto; aspect-ratio: 4 / 3; object-fit: cover; object-position: 70% center; border-radius: 12px; }
  .hero-over { flex: none; padding: 0 0 var(--space-media); }
  .hero-over .head-intro { max-width: none; }
  .hero.hero-banner.title-over { padding-bottom: 72px; }
  .list a { text-wrap: balance; }   /* home: a two-line title splits evenly, never leaving one word on its own line */
  /* fixed controls clear the iPhone home bar */
  .to-top { bottom: calc(16px + env(safe-area-inset-bottom)); }
}

/* phones: a full-screen hero film shows whole (letterboxed, never cropped), below the menu, with its play bar and "Watch with sound" in a strip under it,
   so the project's credits start on the first screen. Same layout as the whole-film heroes (Bombshell, 5 Gum). Vertical films already fit a phone and stay full-screen. */
@media (max-width: 700px) {
  .hero.has-video:not(.hero-whole):not(.portrait) { min-height: 0; aspect-ratio: auto; display: block; padding-top: 84px; padding-bottom: 56px; }
  .hero.has-video:not(.hero-whole):not(.portrait)::before, .hero.has-video:not(.hero-whole):not(.portrait)::after { display: none; }
  .hero.has-video:not(.hero-whole):not(.portrait) .hero-media { position: relative; inset: auto; display: block; }
  .hero.has-video:not(.hero-whole):not(.portrait) .hero-media video { width: 100%; height: auto; object-fit: contain; }
  .hero.has-video:not(.hero-whole):not(.portrait) .sound { top: auto; bottom: 9px; }
  .hero.has-video:not(.hero-whole):not(.portrait) .hero-ctrl { bottom: 9px; right: calc(var(--margin-page-side) + 190px); }
  .hero.has-video:not(.hero-whole):not(.portrait) .hero-ctrl.no-sound { right: var(--margin-page-side); }
  .hero.has-video:not(.hero-whole):not(.portrait) .hero-more { display: none; }
}

/* ---------- Home on phones ---------- */
.top-all { display: none; }
.m-br { display: none; }
@media (max-width: 820px) {
  .top-all { display: inline-flex; align-items: center; min-height: 44px; margin: 0 22px 0 auto; font-family: var(--font-family-ui); font-size: 11.5px; font-weight: 500; letter-spacing: var(--letter-spacing-ui); text-transform: uppercase; color: var(--color-text); }   /* All work moves up beside MENU */
  .top-all span, .top-all { text-decoration: none; }
  body.home .strap .meta { display: none; }
  .m-br { display: inline; }   /* "who makes brands feel human" on its own line */
  .strap .line { text-wrap: balance; }
  .list a { font-size: calc(var(--font-size-h2-list-mobile) * .9); }   /* titles 10% smaller */
  .reel .bg[style*="--mpos"] { object-position: var(--mpos) !important; }   /* each reel item's phone framing (loop_focus_mobile) */
  .reel video.bg.has-m-still { display: none; } .reel img.bg.m-still { display: block; }   /* a loop project with home_image_mobile: phones show that still instead of the film (sharper than a tall crop of footage) */
  .reel .bg[style*="--mzoom"] { transform: scale(var(--mzoom)) !important; transform-origin: var(--mzoom-origin, 50% 100%) !important; }
  .reel .bg.m-zoom-out { -webkit-mask-image: radial-gradient(ellipse 50% 52% at 50% 50%, #000 64%, rgba(0,0,0,.5) 84%, transparent 100%); mask-image: radial-gradient(ellipse 50% 52% at 50% 50%, #000 64%, rgba(0,0,0,.5) 84%, transparent 100%); }   /* the shrunk frame fades out in a soft oval, into the blurred copy behind it */
  .reel img.bg.m-backdrop { display: block; }
  .reel video.bg.m-loop { display: block; } .reel img.bg.has-m-loop { display: none; }   /* phones: the film in place of the still */
  .reel img.bg.m-loop-still { display: block; }   /* the film's opening frame is always there as a picture, so the screen is never empty if a phone doesn't start the film (Low Power Mode, Reduce Motion, a slow connection) */
  .reel video.bg.m-loop.is-on { opacity: 0; } .reel video.bg.m-loop.is-on.is-playing { opacity: 1; }   /* the film shows over that picture only once it is really playing (site.js) */   /* loop_zoom_mobile: the phone frame grows from its foot, so the people in it move up and get bigger, and the top of the picture goes */
}
@media (hover: none) and (max-width: 820px) {
  .list a .m::after { content: "\2192"; margin-left: .5em; color: var(--color-accent); font-family: var(--font-family-body); letter-spacing: 0; }   /* tap the showing title again to open it */
}

/* home list: the client sits beside the active title, on its baseline, instead of underneath it */
.list a { display: block; }
.list a .t { display: inline; }
.list a .m { display: inline-block; max-height: none; max-width: 0; margin: 0; white-space: nowrap; vertical-align: baseline; transition: max-width .4s var(--motion-ease), opacity .4s, margin .4s; }
.list a.is-active .m { max-width: 22em; margin: 0 0 0 .9em; }

/* phones, films shown whole: the smaller sound pill sits level with the play bar, which runs up to 15px short of it */
@media (max-width: 700px) {
  .hero.has-video:not(.portrait) .sound { bottom: 12px !important; }   /* beats the older per-layout 9px rules */
  .hero.has-video:not(.portrait) .hero-ctrl:not(.no-sound) { right: calc(var(--margin-page-side) + 166px); }
  /* a full-screen portrait film (Marshalls): the same arrangement, the pill level with the play bar at the foot of the film instead of floating under the menu */
  .hero.has-video.portrait .sound { top: auto; bottom: calc(var(--space-block) + 24px + 4px); }
  .hero.has-video.portrait .hero-ctrl:not(.no-sound) { right: calc(var(--margin-page-side) + 166px); }
}

@media (max-width: 360px) { .strap .line { font-size: 10.5px; letter-spacing: .11em; } }
@media (max-width: 340px) { .strap .line { font-size: 10px; letter-spacing: .08em; } }   /* the smallest phones: the tagline's first line, "Victoria Probert is a creative director", still fits on one line */

/* phones: a mixed-shape carousel row (site.js sets its height to the slide in view); slides sit at the top and the row eases between heights */

/* phones, essays: paired pieces stack one per row, so the poems and notes (text inside the pictures) read at full width; case-study pairs stay side by side */
@media (max-width: 600px) {
  body.essay .media.row, body.essay .media.gallery { display: flex; flex-direction: column; columns: auto; }
  body.essay .media.row .cell, body.essay .media.gallery .cell { flex: none !important; width: 100% !important; }
  body.essay .media.row.collage + .media.row.collage { margin-top: var(--collage-gap); }
}

/* phones held sideways (short screens): the home list stays below the header and scrolls within the space left, with slightly smaller titles */
@media (max-height: 520px) and (orientation: landscape) {
  .stage { padding-top: 116px; padding-bottom: 16px; }
  .list { flex: 0 1 auto; min-height: 0; max-height: none; margin-bottom: 14px; }
  .list-lab { margin-bottom: 10px; }
  .list a { font-size: clamp(20px, 3.4vw, 28px); }
  .strap { padding-top: 10px; }
}

/* ---------- Phones: every carousel slide shows the whole picture at the screen's width, whatever its shape (wide, square or tall), so nothing is cropped or runs off the edge; tap it to zoom in. Rows of mixed shapes are evened out or stacked (site.js, and the block at the end of this file). ---------- */
@media (max-width: 700px) {
  .carousel:not(.is-proofs) .carousel-track { align-items: center; }
  .carousel:not(.is-proofs) .slide, .carousel:not(.is-proofs) .slide.video { height: auto; width: 100%; max-width: 100%; }
  .carousel:not(.is-proofs) .slide img { width: 100%; height: auto; object-fit: contain; }
  .carousel:not(.is-proofs) .slide.video video { height: auto; aspect-ratio: inherit; }
}
@media (max-width: 700px) {
  .carousel.is-proofs .slide.natural, .carousel.is-proofs .slide.wide, .carousel.is-proofs .slide.side { width: 100%; max-width: 100%; }   /* sized to the column, so a wide or natural-shape proof never runs past the screen */
}
/* phones: the credits' right column is only as wide as its longest line and sits against the right margin, so the block reads as two columns with equal margins either side, not one column crowding the middle */
@media (max-width: 820px) {
  .credits { grid-template-columns: minmax(0, 1fr) fit-content(58%); justify-content: space-between; column-gap: clamp(20px, 6vw, 40px); }
  .credits > div:nth-child(2n+3) { padding-right: 14px; }   /* the 1st child is the hidden heading, so the right column is children 3, 5, ... */   /* the right column stops a hair short of the margin, so it doesn't sit hard against the edge */
}

/* hero_image_mobile: the hero can swap to an upright picture on phones (a <picture> with a phone source); hero_focus_mobile aims the crop there */
.hero .hero-media picture { display: contents; }
@media (max-width: 700px) {
  .hero.img-hero.hero-full .hero-media img { object-position: var(--hero-focus-mobile, var(--hero-focus, center)); }
  .hero.img-hero.hero-full { min-height: 74svh; }   /* phones: short of the screen, so the first credits show before the fold (no scroll arrow) */
}

/* phones, home: the list never moves. Every title keeps its client label laid out beside it (just invisible until it is the one showing), the titles are a touch smaller so each title and client fits on one line, and the list sits lower, a shorter step above the tagline */
@media (max-width: 700px) {
  .list a { font-size: calc(var(--font-size-h2-list-mobile) * .8); }
  .list a .m { max-width: none; margin: 0 0 0 .8em; font-size: 10.5px; letter-spacing: .1em; visibility: hidden; opacity: 0; transition: opacity .4s, visibility 0s .4s; }
  .list a.is-active .m { visibility: visible; opacity: 1; transition: opacity .4s, visibility 0s; }
  .list { margin-bottom: 14px; }
  .list-lab { margin-bottom: 12px; }
}

/* ---------- Phones: carousels are sorted by shape in site.js. m-eq: slides nearly one height all take the shortest (--eq-h), each as wide as its own shape. m-rows: a row of wide and tall pictures rebuilt as a two-row stacked carousel; every tile is sized to its picture's exact shape (--w, --h), so nothing is cropped. Captioned slides: pictures at one height, captions beneath, tops level. The arrows stay below the pictures. ---------- */
@media (max-width: 700px) {
  .carousel.is-rows2 .carousel-track { align-items: flex-start; }   /* grids: a column with fewer tiles starts level with the rest, not floating in the middle */
  /* every slide's width is set outright (--w, from its shape) so nothing depends on how a browser works a film's width out from its height: Safari showed a square film as a tall, cropped tile */
  .carousel.m-eq:not(.has-caps) .slide, .carousel.m-eq:not(.has-caps) .slide.video { height: var(--eq-h) !important; width: var(--w) !important; max-width: none !important; max-height: none !important; aspect-ratio: auto !important; }
  .carousel.m-eq:not(.has-caps) .slide img, .carousel.m-eq:not(.has-caps) .slide.video video { height: 100% !important; width: 100% !important; object-fit: cover !important; aspect-ratio: auto !important; }
  .carousel.m-eq.has-caps .carousel-track { align-items: flex-start !important; }
  .carousel.m-eq.has-caps .slide { width: var(--w) !important; height: auto !important; max-width: none !important; }
  .carousel.m-eq.has-caps .slide img { height: var(--eq-h) !important; width: 100% !important; max-width: none !important; object-fit: cover; }
  .carousel.m-rows .col, .carousel .col.m-pair { flex: none; display: flex; flex-direction: column; gap: 14px; width: var(--w) !important; max-width: none !important; }
  .carousel.m-rows .slide, .carousel.m-rows .col.tall .slide, .carousel.m-rows .slide.video, .carousel .col.m-pair .slide, .carousel .col.m-pair .slide.video { height: var(--h) !important; width: 100% !important; max-width: none !important; max-height: none !important; aspect-ratio: auto !important; border-radius: 10px; overflow: hidden; }
  .carousel.m-rows .slide img, .carousel.m-rows .slide.video video, .carousel .col.m-pair .slide img, .carousel .col.m-pair .slide.video video { width: 100% !important; height: 100% !important; object-fit: cover !important; aspect-ratio: auto !important; }
  .carousel.m-rows .col.m-head .m-sub { display: flex; gap: 14px; }   /* "phone-one": the two pictures under the lead on the carousel's first page */
  .carousel.m-rows .col.m-head .m-sub .slide { flex: none; width: var(--w) !important; }
  .media.m-lead { margin: 0 0 14px; }   /* a wide picture or film with no partner: whole, full width, above its stacked row */
  .media.m-lead .slide { margin: 0; width: 100%; border-radius: 10px; overflow: hidden; background: var(--color-surface); }
  .media.m-lead .slide img, .media.m-lead .slide video { display: block; width: 100%; height: 100%; object-fit: cover; }
}

/* phones, press: two even columns of single-line names, like every page; a name too long for half the width (site.js marks it .full) takes its own line across both */
@media (max-width: 700px) {
  .press { font-size: 14.5px; }
  .press .press-links { column-gap: 20px; grid-auto-flow: dense; }
  .press .press-links > *::before { left: -10px; }
  .press .press-links > .full { grid-column: 1 / -1; }
  .press .press-links > :nth-child(odd of :not(.full))::before { display: none; }
  .press .press-links > :nth-child(even of :not(.full))::before { display: block; }
  .press .press-links > .full::before { display: none !important; }
}

/* phones: the header stays at the top of the page and scrolls away with it (asked for, Nov 2026: following down the page it covered the pictures). The back-to-top arrow brings it back. */
@media (max-width: 820px) {
  .top { position: absolute; }
  .top.is-solid { background: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
  .top.is-solid::before { opacity: 1; }
  .top.is-hidden { transform: none; }
}

/* the comments mock on touch screens: held still only while a finger is on the phone (site.js adds is-held), never left paused by a tap's lingering hover; no link preview or text selection while holding */
.ig-phone.ig-comments.is-held .ig-track { animation-play-state: paused; }
@media (hover: none) {
  .ig-scroll:hover .ig-track { animation-play-state: running; }
  .ig-phone.ig-comments.is-held .ig-scroll .ig-track { animation-play-state: paused; }
  .ig-phone.ig-comments, .ig-phone.ig-comments * { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; -webkit-user-drag: none; }
  .ig-phone.ig-comments img { pointer-events: none; }   /* a long press on an avatar would otherwise open the save-image sheet */
  .ig-phone.ig-comments { -webkit-tap-highlight-color: transparent; cursor: default; }
}

/* phones: a whole-photo hero (VJ Maxx) fills most of the first screen, so the site's ringed down arrow sits centred beneath it and leads on to the case study (asked for, Nov 2026). Other heroes on phones stay without it: the case study already shows under them. */
@media (max-width: 700px) {
  .hero.img-hero.hero-whole .hero-more { display: flex; position: static; left: auto; bottom: auto; margin: 24px auto 0; }
}

/* phones, one carousel only ("@carousel … | side-arrows", The new faces on Victoria's Secret): the arrows sit at the left and right of the picture, level with its middle, because its first caption is long enough to push arrows underneath a screen away. Every other carousel, captioned or not, keeps its arrows below (asked for, Nov 2026: this one only). They straddle the picture's edge so they cover as little of it as possible. The counter stays under the captions. */
@media (max-width: 700px) {
  .carousel.m-side-arrows { position: relative; }
  .carousel.m-side-arrows > .carousel-ui button { position: absolute; top: calc(var(--eq-h, 240px) / 2 - 20px); z-index: 3; width: 40px; height: 40px; border-color: rgba(255,255,255,.55); background: rgba(0,0,0,.45); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
  .carousel.m-side-arrows > .carousel-ui .carousel-prev { left: -18px; }
  .carousel.m-side-arrows > .carousel-ui .carousel-next { right: -18px; }
  .carousel.m-side-arrows > .carousel-ui button:disabled { opacity: 0; pointer-events: none; }   /* nothing that way: the arrow goes, instead of sitting dimmed over the picture */
}

/* phones, home list: the type is sized so the longest title ("The Right Question Changes Everything") sits on one line, on any phone width (asked for, Nov 2026). A title never breaks; its client label drops to the line beneath when the two don't fit together. 17.7 is that title's width in ems, with a little room. */
@media (max-width: 700px) {
  .list a { font-size: min(calc(var(--font-size-h2-list-mobile) * .8), calc((100vw - 2 * var(--margin-page-side, 20px)) / 17.7)); text-wrap: wrap; }
  .list a .t { white-space: nowrap; margin-right: 8px; }   /* the gap to the label belongs to the title, so a label that drops to the next line starts flush with the titles */
  .list a .m, .list a.is-active .m { margin-left: 0; }
}

/* phones, home: a wide still shown as a band (home_band_mobile) rather than a tall, tight crop. It sits just below the menu at the shape asked for, on plain black (a blurred copy behind it read as washed out under the list), and fades out at its top and before its foot, so only the picture's subject shows and the list sits on clean black */
@media (max-width: 820px) {
  .reel img.bg.m-band { inset: auto; left: 0; top: 84px; width: 100%; height: calc(100vw / var(--mband, 1.14)); -webkit-mask-image: linear-gradient(transparent 0, #000 9%, #000 64%, transparent 86%); mask-image: linear-gradient(transparent 0, #000 9%, #000 64%, transparent 86%); }
  .reel img.bg.m-backdrop.m-band-base { filter: brightness(0); transform: none; }   /* the black the band sits on, in either theme */
}

/* accessibility, nothing here changes the look for mouse or touch: the two client names in the desktop Work menu show the site's focus ring when reached by keyboard (they had none), and the résumé link's tap area is at least 24px tall (its text line is 18px) */
.wm-lab:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; border-radius: 2px; }
.head-cta a { position: relative; }
.head-cta a::after { content: ""; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px; }

