/*! ART VIDEO — generated by build/build.mjs. Edit build/css/*.css instead. */
/* ==========================================================================
   ART VIDEO — design tokens
   A monochrome interface: pure black, near-black, paper white, warm bone and a
   narrow band of neutral greys. Colour belongs to the photographs alone.
   ========================================================================== */

@font-face {
  font-family: 'Cormorant Garamond';
  src: url('../fonts/cormorant-garamond-latin.woff2') format('woff2-variations');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Cormorant Garamond';
  src: url('../fonts/cormorant-garamond-latin-italic.woff2') format('woff2-variations');
  font-weight: 300 700;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Jost';
  src: url('../fonts/jost-latin.woff2') format('woff2-variations');
  font-weight: 200 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ---- palette ---------------------------------------------------------- */
  --void: #000000;
  --ink: #0b0b0b;
  --ink-soft: #141414;
  --paper: #ffffff;
  --bone: #f3f1ed;
  --bone-deep: #e8e4dd;
  --grey-70: #6f6f6f;
  --grey-45: #a8a8a8;
  --grey-20: #d8d6d2;

  /* ---- theme (overridden per section) -----------------------------------
     `--fg-faint` is the quietest voice on the page — the micro labels, the
     notes, the craft lists under a name. It used to sit at 0.34 on light and
     0.30 on dark, which measures about 2.2:1: technically visible, actually
     unreadable for anyone whose eyes are not perfect, on a phone, outdoors.

     The alphas below are chosen so the faint tone clears 4.5:1 against the
     background of every theme it appears on, and the dim tone clears 6:1. The
     grey is still recessive — it reads as a whisper rather than as body text —
     but it is a whisper that can actually be heard.
     ---------------------------------------------------------------------- */
  --bg: var(--paper);
  --fg: var(--ink);
  --fg-dim: rgb(11 11 11 / 0.72);
  --fg-faint: rgb(11 11 11 / 0.58);
  --rule: rgb(11 11 11 / 0.13);
  --rule-strong: rgb(11 11 11 / 0.3);
  --plate-bg: var(--bone-deep);

  /* Multiplied into directional transforms so a nudge that travels with the
     reading direction in English travels the other way in Arabic. */
  --flip: 1;

  /* ---- typography ------------------------------------------------------- */
  --display: 'Cormorant Garamond', 'Didot', 'Bodoni 72', 'Times New Roman', serif;
  --sans: 'Jost', 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;

  --t-mega: clamp(3rem, 13.2vw, 15rem);
  --t-hero: clamp(2.75rem, 9.6vw, 10.5rem);
  --t-display: clamp(2.35rem, 6.6vw, 7rem);
  --t-h2: clamp(1.9rem, 4.4vw, 4.25rem);
  --t-h3: clamp(1.45rem, 2.5vw, 2.5rem);
  --t-h4: clamp(1.15rem, 1.6vw, 1.5rem);
  --t-lede: clamp(1.05rem, 1.45vw, 1.5rem);
  --t-body: clamp(0.95rem, 0.62vw + 0.78rem, 1.0625rem);
  --t-small: clamp(0.8rem, 0.4vw + 0.7rem, 0.875rem);
  --t-micro: clamp(0.6rem, 0.18vw + 0.56rem, 0.6875rem);

  --lh-display: 0.92;
  --lh-body: 1.62;
  --track-micro: 0.3em;
  --track-display: -0.018em;

  /* ---- rhythm ----------------------------------------------------------- */
  --pad-x: clamp(1.25rem, 4.6vw, 5.5rem);
  --section-y: clamp(3.75rem, 7.5vh, 6.5rem);
  --section-y-lg: clamp(5rem, 11vh, 9rem);
  --gutter: clamp(0.75rem, 1.4vw, 1.75rem);
  --rule-w: 1px;
  --header-h: clamp(4.25rem, 6vw, 6rem);
  --max: 1720px;

  /* ---- motion ----------------------------------------------------------- */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out-soft: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.76, 0, 0.24, 1);
  --ease-mask: cubic-bezier(0.62, 0.05, 0.01, 0.99);
  --dur-fast: 320ms;
  --dur: 620ms;
  --dur-slow: 1100ms;
  --dur-mask: 1300ms;

  color-scheme: dark light;
}

[data-theme='dark'] {
  --bg: var(--ink);
  --fg: var(--bone);
  --fg-dim: rgb(243 241 237 / 0.76);
  --fg-faint: rgb(243 241 237 / 0.56);
  --rule: rgb(243 241 237 / 0.16);
  --rule-strong: rgb(243 241 237 / 0.34);
  --plate-bg: #1a1a1a;
}

[data-theme='void'] {
  --bg: var(--void);
  --fg: var(--bone);
  --fg-dim: rgb(243 241 237 / 0.76);
  --fg-faint: rgb(243 241 237 / 0.54);
  --rule: rgb(243 241 237 / 0.14);
  --rule-strong: rgb(243 241 237 / 0.32);
  --plate-bg: #101010;
}

[data-theme='bone'] {
  --bg: var(--bone);
  --fg: var(--ink);
  --fg-dim: rgb(11 11 11 / 0.72);
  --fg-faint: rgb(11 11 11 / 0.58);
  --rule: rgb(11 11 11 / 0.14);
  --rule-strong: rgb(11 11 11 / 0.3);
  --plate-bg: var(--bone-deep);
}

/* ==========================================================================
   Reset, document, typography primitives
   ========================================================================== */

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

/* Scroll behaviour is deliberately left at `auto`: the smoothing layer in
   assets/js/modules/scroll.js drives window.scrollTo every frame, and a CSS
   smooth behaviour would animate each of those writes against it. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto;
}

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

ol[class],
ul[class] {
  list-style: none;
  padding: 0;
}

html,
body {
  max-width: 100%;
  overflow-x: clip;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-weight: 300;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  transition: background-color 700ms var(--ease-out), color 700ms var(--ease-out);
}

body[data-lock] {
  overflow: hidden;
}

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

/* Every image carries width/height attributes so the browser can reserve its
   box. Those attributes are presentational hints, so any rule that sets only a
   CSS width would leave the attribute height in place and squash the image.
   Defaulting height to auto neutralises that; the few frames that need to fill
   their box set `height: 100%` on a class, which wins. */
img {
  height: auto;
}

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  margin: 0;
  border-radius: 0;
  -webkit-appearance: none;
  appearance: none;
}

button {
  cursor: pointer;
  padding: 0;
  text-align: inherit;
}

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

::selection {
  background: var(--fg);
  color: var(--bg);
}

:focus-visible {
  outline: 1px solid var(--fg);
  outline-offset: 0.35em;
}

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

.skip-link {
  position: fixed;
  top: 0.75rem;
  inset-inline-start: 0.75rem;
  z-index: 200;
  padding: 0.7em 1.2em;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  transform: translateY(-160%);
  transition: transform var(--dur-fast) var(--ease-out);
}

.skip-link:focus-visible {
  transform: translateY(0);
}

/* ---- type primitives ----------------------------------------------------- */

.display {
  font-family: var(--display);
  font-weight: 300;
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  text-wrap: balance;
}

.micro {
  font-family: var(--sans);
  font-size: var(--t-micro);
  font-weight: 400;
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  /* Wide tracking needs generous leading or wrapped labels read as a block. */
  line-height: 1.75;
}

.micro--tight {
  line-height: 1.35;
}

.note {
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--fg-faint);
  max-width: 40ch;
  text-wrap: pretty;
}

.lede {
  font-size: var(--t-lede);
  line-height: 1.45;
  font-weight: 300;
  text-wrap: pretty;
}

.body-copy {
  max-width: 62ch;
  color: var(--fg-dim);
  text-wrap: pretty;
}

.body-copy + .body-copy {
  margin-top: 1.35em;
}

.rule {
  height: var(--rule-w);
  background: var(--rule);
  border: 0;
  width: 100%;
  transform-origin: left center;
}

/* ==========================================================================
   Layout: sections, editorial grid, photographic plates, reveal choreography
   ========================================================================== */

.section {
  position: relative;
  background: var(--bg);
  color: var(--fg);
  padding-block: var(--section-y);
  isolation: isolate;
}

.section--flush {
  padding-block: 0;
}
.section--tall {
  padding-block: var(--section-y-lg);
}
.section--top-flush {
  padding-block-start: 0;
}

.shell {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

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

@media (max-width: 899px) {
  .grid {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
  .grid > * {
    grid-column: 1 / -1;
  }
}

@media (min-width: 900px) {
  /* Two halves of a form row. */
  .grid--split > * {
    grid-column-end: span 6;
  }
}

/* ---- section headers ----------------------------------------------------- */

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem 2rem;
  flex-wrap: wrap;
  padding-block-end: clamp(1.5rem, 3vw, 2.75rem);
  border-block-end: var(--rule-w) solid var(--rule);
  margin-block-end: clamp(2rem, 5vw, 4.5rem);
}

.section-head__label {
  display: flex;
  align-items: baseline;
  gap: 0.9em;
  color: var(--fg-dim);
}

.section-head__index {
  color: var(--fg-faint);
}

/* ==========================================================================
   Photographic plate
   The original files are never modified; framing happens here, in CSS.
   ========================================================================== */

.plate {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--plate-bg);
  margin: 0;
}

.plate img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 40%);
  opacity: 0;
  transition: opacity 900ms var(--ease-out);
}

.plate img.is-loaded {
  opacity: 1;
}

.plate--45 { aspect-ratio: 4 / 5; }
.plate--23 { aspect-ratio: 2 / 3; }
.plate--34 { aspect-ratio: 3 / 4; }
.plate--169 { aspect-ratio: 16 / 9; }

.plate figcaption {
  margin-block-start: 0.9rem;
  color: var(--fg-faint);
}

/* ---- reveal choreography ------------------------------------------------- */

[data-anim] {
  --anim-delay: 0ms;
}

/* Photographs do not travel. The frame fades up while the image settles out of
   a slight over-scale — the photograph arrives already in place, which reads
   far calmer than a panel sliding in. */
[data-anim='plate'] {
  opacity: 0;
}

[data-anim='plate'] .plate img {
  transform: scale(1.07);
}

.js-ready [data-anim='plate'] {
  transition: opacity 1000ms var(--ease-out);
  transition-delay: var(--anim-delay);
}

.js-ready [data-anim='plate'] .plate img {
  transition: transform var(--dur-mask) var(--ease-out-soft), opacity 900ms var(--ease-out);
  transition-delay: var(--anim-delay);
}

[data-anim='plate'].is-in {
  opacity: 1;
}

[data-anim='plate'].is-in .plate img {
  transform: scale(1);
}

/* Line-by-line text reveal. */
/* The clipping box is grown slightly so descenders and italic tails are never
   shaved off by the mask, then pulled back so the rhythm is unchanged. */
.line {
  display: block;
  overflow: hidden;
  padding-block-end: 0.14em;
  margin-block-end: -0.14em;
}

.line > span {
  display: block;
  transform: translate3d(0, 110%, 0);
}

.js-ready .line > span {
  transition: transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--anim-delay);
}

.is-in .line > span,
.line.is-in > span {
  transform: translate3d(0, 0, 0);
}

/* Soft fade + rise for supporting elements. */
[data-anim='rise'] {
  opacity: 0;
  transform: translate3d(0, 1.6rem, 0);
}

.js-ready [data-anim='rise'] {
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--anim-delay);
}

[data-anim='rise'].is-in {
  opacity: 1;
  transform: none;
}

[data-anim='fade'] {
  opacity: 0;
}

.js-ready [data-anim='fade'] {
  transition: opacity var(--dur-slow) var(--ease-out);
  transition-delay: var(--anim-delay);
}

[data-anim='fade'].is-in {
  opacity: 1;
}

/* Hairline that draws itself. */
[data-anim='rule'] {
  transform: scaleX(0);
}

.js-ready [data-anim='rule'] {
  transition: transform var(--dur-slow) var(--ease-in-out);
  transition-delay: var(--anim-delay);
}

[data-anim='rule'].is-in {
  transform: scaleX(1);
}

/* Before the motion layer boots, nothing should be hidden. */
html:not(.js) [data-anim],
html:not(.js) .line > span {
  opacity: 1 !important;
  transform: none !important;
}

html:not(.js) [data-anim='plate'] .plate img {
  transform: none !important;
}

html:not(.js) .plate img {
  opacity: 1;
}

/* ==========================================================================
   Site chrome: loader, masthead, fullscreen menu, cursor, footer
   ========================================================================== */

/* ---- loading experience -------------------------------------------------- */

.loader {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  background: var(--void);
  color: var(--bone);
  transition: opacity 700ms var(--ease-out), visibility 700ms;
}

.loader[hidden] {
  display: none;
}

.loader__inner {
  display: grid;
  justify-items: center;
  gap: clamp(1.6rem, 3vw, 2.4rem);
  width: min(23rem, 68vw);
}

.loader__logo {
  width: min(15rem, 46vw);
  height: auto;
  opacity: 0;
  filter: brightness(0) invert(1);
  transform: translate3d(0, 0.6rem, 0);
  animation: loader-mark 1200ms var(--ease-out) 120ms forwards;
}

.loader__track {
  position: relative;
  width: 100%;
  height: 1px;
  background: rgb(243 241 237 / 0.16);
  overflow: hidden;
}

.loader__bar {
  position: absolute;
  inset: 0;
  background: var(--bone);
  transform: scaleX(var(--progress, 0));
  transform-origin: left center;
  transition: transform 420ms var(--ease-out);
}

.loader__meta {
  display: flex;
  justify-content: space-between;
  width: 100%;
  color: rgb(243 241 237 / 0.62);
}

.loader.is-out {
  opacity: 0;
  visibility: hidden;
}

@keyframes loader-mark {
  to {
    opacity: 1;
    transform: none;
  }
}

/* The first paint of a page is held behind a thin veil that lifts as the
   transition completes; this keeps navigation continuous rather than abrupt. */
.veil {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: var(--void);
  transform-origin: bottom center;
  transform: scaleY(0);
  pointer-events: none;
}

.veil.is-covering {
  transform-origin: bottom center;
  transform: scaleY(1);
  transition: transform 620ms var(--ease-in-out);
}

.veil.is-lifting {
  transform-origin: top center;
  transform: scaleY(0);
  transition: transform 760ms var(--ease-in-out);
}

html.is-entering .veil {
  transform: scaleY(1);
  transform-origin: top center;
}

.veil__mark {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  width: min(14rem, 42vw);
  height: auto;
  translate: -50% -50%;
  filter: brightness(0) invert(1);
  opacity: 0;
  transition: opacity 380ms var(--ease-out);
}

.veil.is-covering .veil__mark,
html.is-entering .veil__mark {
  opacity: 0.9;
  transition-delay: 220ms;
}

.veil.is-lifting .veil__mark {
  opacity: 0;
  transition-delay: 0ms;
}

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

.masthead {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  /* Above the fullscreen menu, so the mark and the close control stay reachable. */
  z-index: 100;
  --tone-fg: var(--bone);
  --logo-invert: 1;
  color: var(--tone-fg);
  transition: color 520ms var(--ease-out), transform 620ms var(--ease-out), opacity 400ms linear;
  mix-blend-mode: normal;
}

.masthead[data-tone='light'] {
  --tone-fg: var(--ink);
  --logo-invert: 0;
}

/* While the menu or the viewer is open the backdrop is black, whatever section
   happens to be behind it. */
body[data-lock] .masthead {
  --tone-fg: var(--bone);
  --logo-invert: 1;
}

.masthead.is-hidden {
  transform: translate3d(0, -110%, 0);
}

.masthead__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  block-size: var(--header-h);
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

.logo {
  display: inline-flex;
  align-items: center;
  line-height: 0;
}

.logo img {
  width: clamp(4.75rem, 6vw, 6.5rem);
  height: auto;
  filter: brightness(0) invert(var(--logo-invert));
  transition: filter 520ms var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}

.logo:hover img {
  opacity: 0.62;
}

.nav {
  display: none;
  align-items: baseline;
  gap: clamp(1.4rem, 2.6vw, 2.8rem);
}

@media (min-width: 1000px) {
  .nav {
    display: flex;
  }
}

.nav__link {
  position: relative;
  padding-block: 0.35em;
  color: currentColor;
  opacity: 0.72;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.nav__link::after {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 480ms var(--ease-out);
}

.nav__link:hover,
.nav__link:focus-visible,
.nav__link[aria-current='page'] {
  opacity: 1;
}

.nav__link:hover::after,
.nav__link:focus-visible::after,
.nav__link[aria-current='page']::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.masthead__end {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2vw, 2rem);
}

.masthead__phone {
  display: none;
  color: currentColor;
  opacity: 0.72;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.masthead__phone:hover {
  opacity: 1;
}

@media (min-width: 1240px) {
  .masthead__phone {
    display: inline-block;
  }
}

/* ---- menu button --------------------------------------------------------- */

.menu-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.75em;
  color: currentColor;
  z-index: 101;
}

.menu-toggle__label {
  position: relative;
  display: inline-block;
  min-width: 4.6em;
  height: 1.5em;
  overflow: hidden;
}

.menu-toggle__label span {
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0;
  display: block;
  transition: transform 520ms var(--ease-out), opacity 380ms var(--ease-out);
}

.menu-toggle__label span:last-child {
  transform: translate3d(0, 100%, 0);
  opacity: 0;
}

.menu-toggle[aria-expanded='true'] .menu-toggle__label span:first-child {
  transform: translate3d(0, -100%, 0);
  opacity: 0;
}

.menu-toggle[aria-expanded='true'] .menu-toggle__label span:last-child {
  transform: translate3d(0, 0, 0);
  opacity: 1;
}

.menu-toggle__bars {
  display: grid;
  gap: 5px;
  width: 1.5rem;
}

.menu-toggle__bars i {
  display: block;
  height: 1px;
  background: currentColor;
  transform-origin: right center;
  transition: transform 520ms var(--ease-out);
}

.menu-toggle:hover .menu-toggle__bars i:first-child {
  transform: scaleX(0.6);
}

.menu-toggle:hover .menu-toggle__bars i:last-child {
  transform: scaleX(0.8);
}

.menu-toggle[aria-expanded='true'] .menu-toggle__bars i:first-child {
  transform: translateY(3px) rotate(-8deg);
}

.menu-toggle[aria-expanded='true'] .menu-toggle__bars i:last-child {
  transform: translateY(-3px) rotate(8deg);
}

/* ---- fullscreen menu ----------------------------------------------------- */

.menu {
  position: fixed;
  inset: 0;
  z-index: 95;
  background: var(--void);
  color: var(--bone);
  visibility: hidden;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 900ms var(--ease-mask), visibility 900ms;
}

.menu.is-open {
  visibility: visible;
  clip-path: inset(0 0 0 0);
}

.menu__inner {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2rem;
  height: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding: calc(var(--header-h) + clamp(1.5rem, 4vh, 3rem)) var(--pad-x) clamp(1.75rem, 5vh, 3rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.menu__list {
  display: grid;
  gap: clamp(0.1rem, 0.8vh, 0.5rem);
}

.menu__item {
  overflow: hidden;
  border-block-end: 1px solid rgb(243 241 237 / 0.12);
}

.menu__item:last-child {
  border-block-end: 0;
}

.menu__link {
  display: flex;
  align-items: baseline;
  gap: clamp(0.8rem, 2vw, 1.6rem);
  padding-block: clamp(0.5rem, 1.6vh, 1rem);
  transform: translate3d(0, 110%, 0);
  transition: transform 900ms var(--ease-out), opacity 500ms var(--ease-out);
  opacity: 0;
}

.menu.is-open .menu__link {
  transform: translate3d(0, 0, 0);
  opacity: 1;
}

.menu__index {
  font-size: var(--t-micro);
  letter-spacing: 0.18em;
  color: rgb(243 241 237 / 0.62);
  min-width: 2.2em;
}

.menu__word {
  position: relative;
  font-family: var(--display);
  font-weight: 300;
  font-size: clamp(2.35rem, 8vw, 5.5rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  transition: transform 620ms var(--ease-out), opacity 420ms var(--ease-out);
}

.menu__note {
  margin-inline-start: auto;
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: rgb(243 241 237 / 0.62);
  opacity: 0;
  transform: translate3d(-0.6rem, 0, 0);
  transition: opacity 420ms var(--ease-out), transform 520ms var(--ease-out);
  display: none;
}

@media (min-width: 720px) {
  .menu__note {
    display: block;
  }
  .menu__link:hover .menu__word {
    transform: translate3d(clamp(0.6rem, 1.4vw, 1.4rem), 0, 0);
  }
  .menu__link:hover .menu__note {
    opacity: 1;
    transform: none;
  }
}

.menu__foot {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2rem);
  grid-template-columns: 1fr;
  padding-block-start: clamp(1.25rem, 3vh, 2rem);
  border-block-start: 1px solid rgb(243 241 237 / 0.12);
  color: rgb(243 241 237 / 0.62);
  opacity: 0;
  transform: translate3d(0, 1rem, 0);
  transition: opacity 600ms var(--ease-out) 320ms, transform 700ms var(--ease-out) 320ms;
}

.menu.is-open .menu__foot {
  opacity: 1;
  transform: none;
}

@media (min-width: 720px) {
  .menu__foot {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: end;
  }
}

.menu__social {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.15rem;
}

/* ---- custom cursor ------------------------------------------------------- */

/* A disc that trails the pointer and zooms open over anything interactive.
   It adopts the tone of the section it is over rather than inverting the page. */
.cursor {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: 0;
  /* Above every other layer, including the viewer. */
  z-index: 150;
  pointer-events: none;
  opacity: 0;
  /* Position only — no transition here, the trailing is eased in the rAF loop. */
  transform: translate3d(-200px, -200px, 0);
  transition: opacity 320ms var(--ease-out);
  will-change: transform;

  --cursor-ink: var(--bone);
  --cursor-face: var(--ink);
}

.cursor[data-tone='light'] {
  --cursor-ink: var(--ink);
  --cursor-face: var(--bone);
}

.cursor.is-active {
  opacity: 1;
}

.cursor__disc {
  display: grid;
  place-items: center;
  width: 5.25rem;
  height: 5.25rem;
  margin: -2.625rem 0 0 -2.625rem;
  border-radius: 50%;
  background: var(--cursor-ink);
  color: var(--cursor-face);
  transform: scale(0.115);
  transition: transform 620ms var(--ease-out-soft), background-color 420ms var(--ease-out),
    color 420ms var(--ease-out);
}

.cursor__label {
  font-family: var(--sans);
  font-size: 0.5625rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transform: scale(0.55);
  transition: opacity 260ms var(--ease-out), transform 420ms var(--ease-out-soft);
}

.cursor.is-labelled .cursor__disc {
  transform: scale(1);
}

.cursor.is-labelled .cursor__label {
  opacity: 1;
  transform: none;
  transition-delay: 90ms;
}

.cursor.is-pressed .cursor__disc {
  transform: scale(0.075);
}

.cursor.is-labelled.is-pressed .cursor__disc {
  transform: scale(0.86);
}

@media (hover: none), (pointer: coarse) {
  .cursor {
    display: none;
  }
}

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

.colophon {
  background: var(--void);
  color: var(--bone);
  padding-block: clamp(3.5rem, 9vh, 8rem) clamp(1.75rem, 4vh, 3rem);
  overflow: hidden;
}

.colophon__mark {
  display: block;
  width: 100%;
  margin-block-end: clamp(2.25rem, 5vw, 4rem);
  padding-block-end: clamp(1.75rem, 4vw, 3rem);
  border-block-end: 1px solid rgb(243 241 237 / 0.12);
}

.colophon__mark img {
  width: clamp(6.5rem, 11vw, 10.5rem);
  height: auto;
  filter: brightness(0) invert(1);
  opacity: 0.9;
}

.colophon__grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
  padding-block-end: clamp(2.5rem, 5vw, 4rem);
}

@media (min-width: 700px) {
  .colophon__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1080px) {
  .colophon__grid {
    grid-template-columns: 1.4fr 1fr 1fr 1.1fr;
  }
}

.colophon__title {
  color: rgb(243 241 237 / 0.62);
  margin-block-end: 1.4em;
}

.colophon__list {
  display: grid;
  gap: 0.5em;
}

.colophon__lede {
  font-family: var(--display);
  font-size: var(--t-h4);
  line-height: 1.3;
  color: var(--bone);
  max-width: 22ch;
}

.colophon__base {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2rem;
  justify-content: space-between;
  align-items: baseline;
  padding-block-start: clamp(1.5rem, 3vw, 2.25rem);
  border-block-start: 1px solid rgb(243 241 237 / 0.14);
  color: rgb(243 241 237 / 0.62);
}

.colophon__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
}

/* ==========================================================================
   Components: links, buttons, story index, horizontal reel, viewer
   ========================================================================== */

/* ---- link + button treatments -------------------------------------------- */

/* Links carry no permanent rule; the hairline draws itself in from the left on
   hover and retracts to the left on leave. */
.link {
  position: relative;
  display: inline-block;
  padding-block-end: 0.18em;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.link::after {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  opacity: 0.7;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 460ms var(--ease-out);
}

.link:hover::after,
.link:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

/* A rule that is always present, for the one or two links that anchor a block. */
.link--ruled::after {
  transform: scaleX(1);
  transform-origin: left center;
  opacity: 0.35;
}

.link--ruled:hover::after,
.link--ruled:focus-visible::after {
  opacity: 1;
}

.action {
  display: inline-flex;
  align-items: center;
  gap: 0.9em;
  padding: 1.1em 1.9em;
  border: 1px solid var(--rule-strong);
  color: var(--fg);
  overflow: hidden;
  position: relative;
  isolation: isolate;
  transition: color 480ms var(--ease-out), border-color 480ms var(--ease-out);
}

.action::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--fg);
  transform: translate3d(0, 101%, 0);
  transition: transform 620ms var(--ease-mask);
}

.action:hover,
.action:focus-visible {
  color: var(--bg);
  border-color: var(--fg);
}

.action:hover::before,
.action:focus-visible::before {
  transform: translate3d(0, 0, 0);
}

.action__arrow {
  display: inline-block;
  transition: transform 520ms var(--ease-out);
}

.action:hover .action__arrow {
  transform: translateX(0.35em);
}

/* ---- story index (editorial list with hover preview) --------------------- */

.index {
  position: relative;
  border-block-start: var(--rule-w) solid var(--rule);
}

.index__row {
  position: relative;
  display: block;
  border-block-end: var(--rule-w) solid var(--rule);
}

.index__link {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: clamp(0.9rem, 2.4vw, 2.5rem);
  padding-block: clamp(1.1rem, 2.6vw, 2rem);
  transition: opacity 500ms var(--ease-out);
}

.index__num {
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  color: var(--fg-faint);
  transition: color 480ms var(--ease-out);
}

.index__title {
  font-family: var(--display);
  font-weight: 300;
  font-size: clamp(1.6rem, 4.2vw, 3.4rem);
  line-height: 1.06;
  letter-spacing: -0.015em;
  transition: transform 620ms var(--ease-out);
  will-change: transform;
}

.index__aside {
  display: none;
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--fg-faint);
  transition: opacity 420ms var(--ease-out), transform 520ms var(--ease-out);
}

@media (min-width: 760px) {
  .index__aside {
    display: block;
    opacity: 0.55;
  }
  .index__link:hover .index__title {
    transform: translate3d(clamp(0.6rem, 1.6vw, 1.6rem), 0, 0);
  }
  .index__link:hover .index__aside {
    opacity: 1;
  }
  /* Everything else recedes while one row is hovered. */
  .index:hover .index__link {
    opacity: 0.38;
  }
  .index:hover .index__link:hover {
    opacity: 1;
  }
}

/* Floating preview that follows the pointer across the index. */
.index__preview {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: 60;
  width: clamp(13rem, 17vw, 19rem);
  aspect-ratio: 4 / 5;
  pointer-events: none;
  opacity: 0;
  overflow: hidden;
  transform: translate3d(-50%, -50%, 0) scale(0.94);
  transition: opacity 420ms var(--ease-out), transform 620ms var(--ease-out);
  will-change: transform;
  background: var(--plate-bg);
}

.index__preview.is-visible {
  opacity: 1;
}

.index__preview img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 460ms var(--ease-out);
}

.index__preview img.is-current {
  opacity: 1;
}

@media (hover: none), (pointer: coarse), (max-width: 759px) {
  .index__preview {
    display: none;
  }
}

/* ---- horizontal reel ----------------------------------------------------- */

.reel {
  position: relative;
  overflow: hidden;
}

.reel__track {
  display: flex;
  gap: clamp(0.75rem, 1.6vw, 1.75rem);
  padding-inline: var(--pad-x);
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  cursor: grab;
  padding-block-end: 0.5rem;
}

.reel__track::-webkit-scrollbar {
  display: none;
}

.reel__track.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  scroll-behavior: auto;
}

.reel__item {
  flex: 0 0 auto;
  width: clamp(15rem, 27vw, 26rem);
  scroll-snap-align: center;
}

.reel__item:first-child {
  scroll-snap-align: start;
}

.reel__item--drop {
  margin-block-start: clamp(1.5rem, 5vw, 5rem);
}

.reel__figure {
  position: relative;
  overflow: hidden;
}

.reel__caption {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-block-start: 0.85rem;
  color: var(--fg-faint);
}

.reel__progress {
  position: relative;
  height: 1px;
  margin: clamp(1.75rem, 4vw, 3rem) var(--pad-x) 0;
  background: var(--rule);
}

.reel__progress i {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  display: block;
  width: 22%;
  background: var(--fg);
  transform: translate3d(var(--reel-progress, 0%), 0, 0);
  transition: transform 120ms linear;
}

/* ---- gallery grids ------------------------------------------------------- */

.mosaic {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.5rem, 1.4vw, 1.5rem);
}

@media (min-width: 760px) {
  .mosaic {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(0.75rem, 1.6vw, 2rem);
  }
}

@media (min-width: 1180px) {
  .mosaic {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.mosaic__item {
  position: relative;
}

/* Every fifth and eleventh frame is dropped to break the grid's regularity. */
@media (min-width: 760px) {
  .mosaic__item:nth-child(5n + 3) {
    margin-block-start: clamp(0.75rem, 2vw, 2rem);
  }
  .mosaic__item:nth-child(7n + 6) {
    margin-block-start: clamp(0.5rem, 1.2vw, 1.25rem);
  }
}

.frame-button {
  display: block;
  width: 100%;
  position: relative;
  overflow: hidden;
}

.frame-button .plate img {
  transition: opacity 900ms var(--ease-out), transform 1400ms var(--ease-out-soft);
}

@media (hover: hover) {
  .frame-button:hover .plate img,
  .frame-link:hover .plate img {
    transform: scale(1.045);
  }
}

.frame-button:focus-visible {
  outline-offset: -2px;
}

/* ---- filters ------------------------------------------------------------- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.6rem;
  align-items: baseline;
}

.filter {
  position: relative;
  padding-block-end: 0.3em;
  color: var(--fg-faint);
  transition: color 420ms var(--ease-out);
}

.filter::after {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 480ms var(--ease-out);
}

.filter:hover,
.filter[aria-pressed='true'] {
  color: var(--fg);
}

.filter[aria-pressed='true']::after,
.filter:hover::after {
  transform: scaleX(1);
}

/* ---- viewer (lightbox) --------------------------------------------------- */

.viewer {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--void);
  color: var(--bone);
  opacity: 0;
  visibility: hidden;
  transition: opacity 520ms var(--ease-out), visibility 520ms;
}

.viewer.is-open {
  opacity: 1;
  visibility: visible;
}

.viewer__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(1rem, 2.5vw, 1.75rem) var(--pad-x);
  color: rgb(243 241 237 / 0.6);
}

.viewer__stage {
  position: relative;
  min-height: 0;
}

/* Anchored to the stage's box so the photograph's max-height has something
   definite to resolve against, whatever the aspect ratio. */
.viewer__figure {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: clamp(0.25rem, 1vw, 1rem) clamp(0.75rem, 4vw, 4rem);
}

/* The height limit is expressed against the viewport rather than the parent:
   a percentage max-height on a replaced element inside a centred grid does not
   reliably resolve, and the photograph must never overflow the stage. */
.viewer__figure img {
  max-width: 100%;
  max-height: calc(100svh - var(--viewer-chrome, 9rem));
  width: auto;
  height: auto;
  opacity: 0;
  transform: scale(0.985);
  transition: opacity 620ms var(--ease-out), transform 900ms var(--ease-out);
}

@media (min-width: 760px) {
  .viewer {
    --viewer-chrome: 12.5rem;
  }
}

.viewer__figure img.is-current {
  opacity: 1;
  transform: none;
}

.viewer__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(0.9rem, 2.2vw, 1.6rem) var(--pad-x) clamp(1.25rem, 3vw, 2rem);
}

.viewer__nav {
  display: flex;
  gap: clamp(0.75rem, 2vw, 1.5rem);
}

.viewer__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  padding: 0.7em 0;
  color: rgb(243 241 237 / 0.65);
  transition: color 320ms var(--ease-out);
  min-height: 44px;
}

.viewer__btn:hover:not(:disabled),
.viewer__btn:focus-visible {
  color: var(--bone);
}

.viewer__btn:disabled {
  opacity: 0.3;
  cursor: default;
}

.viewer__close {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  color: rgb(243 241 237 / 0.65);
  transition: color 320ms var(--ease-out);
}

.viewer__close:hover {
  color: var(--bone);
}

.viewer__count {
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Homepage compositions
   ========================================================================== */

/* ---- hero ---------------------------------------------------------------- */

.hero {
  position: relative;
  /* Phones open on a single full-screen frame; wider screens get the push-in,
     which needs a second screenful of scroll to travel through. */
  height: 100vh;
  height: 100svh;
  background: var(--void);
  color: var(--bone);
}

@media (min-width: 760px) {
  .hero {
    height: 180vh;
    height: 180svh;
  }
}

.hero__sticky {
  position: sticky;
  inset-block-start: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  display: grid;
  place-items: center;
}

/* On phones the photograph fills the screen: a 4:5 frame in a tall viewport
   crops the sides, which never costs a face. From tablet up the plate holds the
   complete 4:5 photograph and scrolling scales it until it covers the viewport,
   so the opening reads as a slow push into the frame. */
.hero__plate {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--plate-bg);
  transform: scale(var(--hero-scale, 1));
  transform-origin: center center;
  will-change: transform;
  margin: 0;
}

@media (min-width: 760px) {
  .hero__plate {
    width: auto;
    height: min(78svh, 92vw);
    aspect-ratio: 4 / 5;
  }
}

.hero__plate img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 40%);
  opacity: 0;
  transition: opacity 1400ms var(--ease-out);
}

.hero__plate img.is-loaded {
  opacity: 1;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgb(0 0 0 / 0.5) 0%,
    rgb(0 0 0 / 0.06) 28%,
    rgb(0 0 0 / 0.28) 56%,
    rgb(0 0 0 / 0.82) 100%
  );
  opacity: var(--hero-scrim, 0.4);
  transition: opacity 400ms linear;
}

.hero__type {
  position: absolute;
  inset-inline: 0;
  inset-block-end: clamp(4.5rem, 12vh, 9rem);
  padding-inline: var(--pad-x);
  max-width: var(--max);
  margin-inline: auto;
  z-index: 2;
  pointer-events: none;
  transform: translate3d(0, var(--hero-type-y, 0), 0);
  opacity: var(--hero-type-o, 1);
}

.hero__kicker {
  color: rgb(243 241 237 / 0.6);
  margin-block-end: clamp(0.9rem, 2vw, 1.6rem);
}

.hero__title {
  font-size: var(--t-hero);
  text-shadow: 0 0.05em 0.5em rgb(0 0 0 / 0.28);
}

.hero__lede {
  margin-block-start: clamp(0.8rem, 1.6vw, 1.4rem);
  color: rgb(243 241 237 / 0.72);
  font-family: var(--display);
  font-style: italic;
  font-size: clamp(1.15rem, 2.4vw, 2.15rem);
  line-height: 1.2;
}

.hero__corner {
  position: absolute;
  z-index: 2;
  color: rgb(243 241 237 / 0.6);
  pointer-events: none;
  opacity: var(--hero-type-o, 1);
}

.hero__corner--left {
  inset-block-end: clamp(1.25rem, 3vh, 2.5rem);
  inset-inline-start: var(--pad-x);
  display: none;
}

.hero__corner--right {
  inset-block-end: clamp(1.25rem, 3vh, 2.5rem);
  inset-inline-end: var(--pad-x);
  display: flex;
  align-items: center;
  gap: 0.75em;
}

@media (min-width: 760px) {
  .hero__corner--left {
    display: block;
  }
}

.hero__scroll-line {
  display: inline-block;
  width: clamp(2rem, 4vw, 3.5rem);
  height: 1px;
  background: currentColor;
  transform-origin: right center;
  animation: scroll-hint 2600ms var(--ease-in-out) infinite;
}

@keyframes scroll-hint {
  0%,
  100% {
    transform: scaleX(0.35);
    opacity: 0.5;
  }
  50% {
    transform: scaleX(1);
    opacity: 1;
  }
}

/* ---- statement ----------------------------------------------------------- */

.statement {
  position: relative;
}

.statement__head {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: end;
  margin-block-end: clamp(2rem, 4vw, 3.5rem);
}

@media (min-width: 900px) {
  .statement__head {
    grid-template-columns: 1fr auto;
  }
}

.statement__title {
  font-size: var(--t-display);
  max-width: 16ch;
}

.statement__lede {
  max-width: 34ch;
  color: var(--fg-dim);
  font-family: var(--display);
  font-size: var(--t-h4);
  line-height: 1.35;
}

/* Two columns that finish level with one another: a tall photograph running off
   the left edge, and beside it the copy with a pair of frames beneath that grow
   to take up whatever height is left. Nothing is auto-placed, so nothing can be
   pushed onto a row of its own and open a hole in the middle of the section. */
.statement__body {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
}

.statement__mid {
  display: flex;
  flex-direction: column;
  gap: clamp(1.75rem, 3vw, 2.75rem);
  min-height: 0;
}

.statement__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.5rem, 1.2vw, 1.25rem);
  flex: 1 1 auto;
  min-height: clamp(11rem, 26vw, 24rem);
}

@media (min-width: 900px) {
  .statement__body {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
    align-items: stretch;
  }
  .statement__figure--a {
    grid-column: 1 / span 5;
    grid-row: 1;
    margin-inline-start: calc(var(--pad-x) * -1);
  }
  .statement__mid {
    grid-column: 7 / span 6;
    grid-row: 1;
  }
  /* The pair fills the height the copy leaves over, so the two columns end level. */
  .statement__pair .plate--fill {
    height: 100%;
    aspect-ratio: auto;
  }
}

@media (min-width: 1280px) {
  .statement__figure--a {
    grid-column: 1 / span 6;
  }
  .statement__mid {
    grid-column: 8 / span 5;
  }
}

.statement__note {
  margin-block-start: clamp(1.5rem, 2.5vw, 2.25rem);
  padding-block-start: 1.25rem;
  border-block-start: var(--rule-w) solid var(--rule);
}

.statement__note-body {
  margin-block-start: 0.9em;
}

/* ---- chapters (story index) ---------------------------------------------- */

.chapters__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 2.5rem;
  align-items: center;
  justify-content: space-between;
  margin-block-start: clamp(2.5rem, 5vw, 4rem);
}

.chapters__foot .note {
  max-width: 46ch;
}

/* ---- reel ---------------------------------------------------------------- */

.reel-section__head {
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--pad-x);
  margin-block-end: clamp(2rem, 5vw, 4rem);
}

/* ---- studio preview ------------------------------------------------------ */

.studio-preview__grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4.5rem);
  align-items: center;
}

@media (min-width: 960px) {
  .studio-preview__grid {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
  }
  .studio-preview__media {
    grid-column: 1 / span 5;
    position: relative;
  }
  .studio-preview__copy {
    grid-column: 7 / span 5;
  }
}

.studio-preview__stack {
  position: relative;
}

.studio-preview__stack .plate:last-child {
  position: absolute;
  inset-block-end: clamp(-3rem, -6vw, -5rem);
  inset-inline-end: clamp(-1.5rem, -4vw, -4rem);
  width: 44%;
  /* A thin band of the page colour separates the two frames instead of a shadow. */
  outline: clamp(0.4rem, 0.9vw, 0.85rem) solid var(--bg);
}

@media (max-width: 959px) {
  .studio-preview__stack .plate:last-child {
    position: relative;
    inset: auto;
    width: 62%;
    margin: -18% 0 0 auto;
  }
}

.studio-preview__quote {
  font-family: var(--display);
  font-size: var(--t-h3);
  line-height: 1.24;
  letter-spacing: -0.012em;
  max-width: 20ch;
  margin-block-end: clamp(1.5rem, 3vw, 2.25rem);
}

/* ---- figures / counters -------------------------------------------------- */

.figures__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 3.5rem) clamp(1rem, 3vw, 3rem);
}

@media (min-width: 900px) {
  .figures__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.figure-stat {
  padding-block-start: clamp(1rem, 2vw, 1.5rem);
  border-block-start: var(--rule-w) solid var(--rule);
}

.figure-stat__value {
  display: flex;
  align-items: baseline;
  gap: 0.06em;
  font-family: var(--display);
  font-weight: 300;
  font-size: clamp(2.75rem, 7vw, 6rem);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: lining-nums tabular-nums;
}

.figure-stat__suffix {
  font-size: 0.42em;
  letter-spacing: 0;
  opacity: 0.6;
}

.figure-stat__label {
  margin-block-start: clamp(0.75rem, 1.5vw, 1.1rem);
  color: var(--fg-faint);
  max-width: 22ch;
}

/* ---- interlude ----------------------------------------------------------- */

.interlude {
  position: relative;
  height: clamp(70svh, 92svh, 100svh);
  overflow: hidden;
  background: var(--void);
  display: grid;
  place-items: center;
  isolation: isolate;
}

.interlude__media {
  position: absolute;
  inset-block: -14%;
  inset-inline: 0;
  z-index: -2;
  transform: translate3d(0, var(--parallax, 0px), 0);
  will-change: transform;
}

.interlude__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 40%);
  opacity: 0;
  transition: opacity 1200ms var(--ease-out);
}

.interlude__media img.is-loaded {
  opacity: 1;
}

.interlude::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgb(0 0 0 / 0.46);
}

.interlude__quote {
  position: relative;
  max-width: min(22ch, 90vw);
  padding-inline: var(--pad-x);
  text-align: center;
  color: var(--bone);
  font-family: var(--display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.9rem, 5.4vw, 5rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-shadow: 0 0.05em 0.6em rgb(0 0 0 / 0.35);
}

.interlude__attribution {
  margin-block-start: clamp(1.25rem, 3vw, 2rem);
  color: rgb(243 241 237 / 0.6);
  font-family: var(--sans);
  font-style: normal;
}

/* A vertical caption set into the left margin, magazine-style. */
.interlude__spine {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: clamp(1rem, 2.5vw, 2.5rem);
  writing-mode: vertical-rl;
  transform: translateY(-50%) rotate(180deg);
  color: rgb(243 241 237 / 0.62);
  display: none;
  pointer-events: none;
}

@media (min-width: 900px) {
  .interlude__spine {
    display: block;
  }
}

/* ---- services preview ---------------------------------------------------- */

.craft-list {
  border-block-start: var(--rule-w) solid var(--rule);
}

.craft-list__row {
  border-block-end: var(--rule-w) solid var(--rule);
}

.craft-list__link {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(0.9rem, 2.4vw, 2.5rem);
  align-items: baseline;
  padding-block: clamp(0.9rem, 2vw, 1.5rem);
  transition: opacity 480ms var(--ease-out);
}

.craft-list__num {
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  color: var(--fg-faint);
}

.craft-list__name {
  font-family: var(--display);
  font-size: clamp(1.35rem, 3.2vw, 2.6rem);
  line-height: 1.1;
  transition: transform 620ms var(--ease-out);
}

@media (min-width: 760px) {
  .craft-list:hover .craft-list__link {
    opacity: 0.34;
  }
  .craft-list:hover .craft-list__link:hover {
    opacity: 1;
  }
  .craft-list__link:hover .craft-list__name {
    transform: translate3d(clamp(0.5rem, 1.4vw, 1.4rem), 0, 0);
  }
}

/* ---- closing call to action ---------------------------------------------- */

.closing {
  position: relative;
  background: var(--void);
  color: var(--bone);
  overflow: hidden;
}

.closing__grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: end;
}

@media (min-width: 960px) {
  .closing__grid {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
  }
  .closing__copy {
    grid-column: 1 / span 7;
  }
  .closing__media {
    grid-column: 9 / span 4;
  }
}

.closing__title {
  font-size: var(--t-display);
}

.closing__body {
  margin-block-start: clamp(1.5rem, 3vw, 2.25rem);
  max-width: 40ch;
  color: rgb(243 241 237 / 0.6);
}

.closing__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  margin-block-start: clamp(2rem, 4vw, 3rem);
}

/* ==========================================================================
   Inner pages: page openings, stories, gallery, studio, services, contact
   ========================================================================== */

/* ---- page opening -------------------------------------------------------- */

.page-head {
  position: relative;
  background: var(--void);
  color: var(--bone);
  padding-block: calc(var(--header-h) + clamp(2rem, 6vh, 4rem)) clamp(2.5rem, 6vh, 4.5rem);
  overflow: hidden;
}

.page-head__grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  align-items: end;
}

@media (min-width: 900px) {
  .page-head__grid {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
  }
  .page-head__copy {
    grid-column: 1 / span 7;
  }
  .page-head__media {
    grid-column: 9 / span 4;
  }
  /* Policy pages carry no photograph — the copy takes the full measure. */
  .page-head--text .page-head__copy {
    grid-column: 1 / span 9;
  }
}

.page-head__label {
  display: flex;
  align-items: baseline;
  gap: 1em;
  color: rgb(243 241 237 / 0.62);
  margin-block-end: clamp(1.25rem, 3vw, 2.25rem);
}

.page-head__title {
  font-size: var(--t-hero);
}

.page-head__lede {
  margin-block-start: clamp(1.5rem, 3vw, 2.25rem);
  max-width: 46ch;
  color: rgb(243 241 237 / 0.62);
}

.page-head__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2.5rem;
  margin-block-start: clamp(2rem, 4vw, 3rem);
  padding-block-start: clamp(1rem, 2vw, 1.5rem);
  border-block-start: 1px solid rgb(243 241 237 / 0.16);
  color: rgb(243 241 237 / 0.62);
}

/* ---- weddings index ------------------------------------------------------ */

.stories {
  display: grid;
  gap: clamp(2rem, 4vw, 4rem) var(--gutter);
  grid-template-columns: repeat(12, minmax(0, 1fr));
}

.story-card {
  grid-column: 1 / -1;
}

@media (min-width: 760px) {
  /* An asymmetric editorial rhythm: wide, narrow-offset, pair, tall. */
  .story-card:nth-child(6n + 1) {
    grid-column: 1 / span 7;
  }
  .story-card:nth-child(6n + 2) {
    grid-column: 8 / span 5;
    margin-block-start: clamp(2rem, 5vw, 5rem);
  }
  .story-card:nth-child(6n + 3) {
    grid-column: 1 / span 5;
  }
  .story-card:nth-child(6n + 4) {
    grid-column: 7 / span 6;
    margin-block-start: clamp(1.5rem, 3vw, 3rem);
  }
  .story-card:nth-child(6n + 5) {
    grid-column: 1 / span 5;
  }
  .story-card:nth-child(6n + 6) {
    grid-column: 7 / span 6;
    margin-block-start: clamp(2rem, 4vw, 4rem);
  }
}

.story-card__link {
  display: block;
}

.story-card__frame {
  position: relative;
  overflow: hidden;
}

.story-card__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-block-start: clamp(0.9rem, 1.6vw, 1.4rem);
  padding-block-start: clamp(0.75rem, 1.4vw, 1.1rem);
  border-block-start: var(--rule-w) solid var(--rule);
}

.story-card__title {
  font-family: var(--display);
  font-size: clamp(1.35rem, 2.8vw, 2.35rem);
  line-height: 1.1;
  transition: transform 560ms var(--ease-out);
}

.story-card__link:hover .story-card__title {
  transform: translate3d(0.35rem, 0, 0);
}

.story-card__index {
  color: var(--fg-faint);
}

.story-card__note {
  margin-block-start: 0.75rem;
  color: var(--fg-faint);
  max-width: 46ch;
}

/* ---- single story -------------------------------------------------------- */

.story-open {
  position: relative;
  height: 100svh;
  min-height: 34rem;
  overflow: hidden;
  background: var(--void);
  color: var(--bone);
}

.story-open__media {
  position: absolute;
  inset-block: -10%;
  inset-inline: 0;
  transform: translate3d(0, var(--parallax, 0px), 0);
  will-change: transform;
}

.story-open__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 38%);
  opacity: 0;
  transition: opacity 1200ms var(--ease-out);
}

.story-open__media img.is-loaded {
  opacity: 1;
}

.story-open::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgb(0 0 0 / 0.5) 0%, rgb(0 0 0 / 0.12) 40%, rgb(0 0 0 / 0.78) 100%);
}

.story-open__type {
  position: absolute;
  inset-block-end: clamp(2.5rem, 8vh, 6rem);
  inset-inline: 0;
  z-index: 2;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

.story-open__title {
  font-size: var(--t-hero);
}

.story-open__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 2.25rem;
  margin-block-start: clamp(1.25rem, 2.5vw, 2rem);
  color: rgb(243 241 237 / 0.62);
}

.story-intro {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem);
}

@media (min-width: 900px) {
  .story-intro {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
  }
  .story-note {
    grid-column: 2 / span 6;
  }
  .story-intro__credit {
    grid-column: 10 / span 3;
  }
}

.story-note {
  max-width: 44ch;
  font-family: var(--display);
  font-size: var(--t-h3);
  line-height: 1.28;
  letter-spacing: -0.01em;
}

.story-intro__credit {
  color: var(--fg-faint);
}

.chapter {
  padding-block: clamp(2rem, 4vw, 3.5rem) 0;
}

.chapter__head {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  padding-block-end: clamp(1rem, 2vw, 1.5rem);
  margin-block-end: clamp(2rem, 4vw, 3.5rem);
  border-block-end: var(--rule-w) solid var(--rule);
}

.chapter__name {
  font-family: var(--display);
  font-size: var(--t-h3);
  line-height: 1;
}

.chapter__count {
  margin-inline-start: auto;
  color: var(--fg-faint);
}

/* Sequence layouts — each block deliberately differs from its neighbour. */
.seq {
  display: grid;
  gap: clamp(0.75rem, 2vw, 2rem) var(--gutter);
  grid-template-columns: repeat(12, minmax(0, 1fr));
  margin-block-end: clamp(1.5rem, 3vw, 3rem);
}

.seq > * {
  grid-column: 1 / -1;
}

.seq--solo > * {
  grid-column: 1 / -1;
}

@media (min-width: 760px) {
  .seq--solo > * {
    grid-column: 2 / span 10;
  }
  .seq--solo-left > * {
    grid-column: 1 / span 8;
  }
  .seq--solo-right > * {
    grid-column: 5 / span 8;
  }

  .seq--pair > *:nth-child(1) {
    grid-column: 1 / span 6;
  }
  .seq--pair > *:nth-child(2) {
    grid-column: 8 / span 5;
    margin-block-start: clamp(1.5rem, 4vw, 4rem);
  }

  .seq--pair-tight > *:nth-child(1) {
    grid-column: 2 / span 5;
  }
  .seq--pair-tight > *:nth-child(2) {
    grid-column: 7 / span 5;
    margin-block-start: clamp(1.25rem, 3vw, 3rem);
  }

  .seq--triptych > *:nth-child(1) {
    grid-column: 1 / span 4;
  }
  .seq--triptych > *:nth-child(2) {
    grid-column: 5 / span 4;
    margin-block-start: clamp(1.25rem, 3vw, 3rem);
  }
  .seq--triptych > *:nth-child(3) {
    grid-column: 9 / span 4;
  }

  .seq--stagger > *:nth-child(1) {
    grid-column: 1 / span 4;
    margin-block-start: clamp(1.5rem, 4vw, 4rem);
  }
  .seq--stagger > *:nth-child(2) {
    grid-column: 5 / span 4;
  }
  .seq--stagger > *:nth-child(3) {
    grid-column: 9 / span 4;
    margin-block-start: clamp(2.5rem, 6vw, 6rem);
  }
}

/* A monumental frame that touches both edges of the viewport.
   The photographs are all 4:5, so this keeps their native shape and simply lets
   them grow — a tall crop rather than a wide one, which never loses a face. */
.seq--bleed {
  grid-template-columns: 1fr;
  margin-inline: calc(var(--pad-x) * -1);
  width: calc(100% + var(--pad-x) * 2);
  margin-block-end: clamp(2.5rem, 6vw, 6rem);
}

.seq--bleed > * {
  grid-column: 1 / -1;
}

.seq--bleed .plate {
  aspect-ratio: 4 / 5;
  max-height: min(124svh, 68rem);
}

.story-close {
  position: relative;
  background: var(--void);
  color: var(--bone);
}

.story-next {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: end;
  padding-block: clamp(3rem, 8vw, 7rem);
}

@media (min-width: 860px) {
  .story-next {
    grid-template-columns: 1fr auto;
  }
}

.story-next__title {
  font-family: var(--display);
  font-size: var(--t-display);
  line-height: 1;
  transition: transform 620ms var(--ease-out);
}

.story-next__link:hover .story-next__title {
  transform: translate3d(clamp(0.5rem, 1.5vw, 1.5rem), 0, 0);
}

.story-next__thumb {
  width: clamp(7rem, 14vw, 12rem);
}

/* ---- gallery ------------------------------------------------------------- */

.gallery__bar {
  position: sticky;
  inset-block-start: 0;
  z-index: 40;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  align-items: baseline;
  justify-content: space-between;
  padding-block: clamp(1rem, 2vw, 1.5rem);
  margin-block-end: clamp(2rem, 4vw, 3.5rem);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(14px);
  border-block-end: var(--rule-w) solid var(--rule);
}

.mosaic__item[hidden] {
  display: none;
}

.gallery__more {
  display: flex;
  justify-content: center;
  margin-block-start: clamp(2.5rem, 6vw, 5rem);
}

.gallery__empty {
  padding-block: clamp(3rem, 8vw, 6rem);
  text-align: center;
  color: var(--fg-faint);
}

/* ---- studio -------------------------------------------------------------- */

.studio-body {
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem) var(--gutter);
  grid-template-columns: repeat(12, minmax(0, 1fr));
}

.studio-body__aside {
  grid-column: 1 / -1;
}

.studio-body__copy {
  grid-column: 1 / -1;
}

@media (min-width: 960px) {
  .studio-body__aside {
    grid-column: 1 / span 4;
    position: sticky;
    inset-block-start: calc(var(--header-h) + 2rem);
    align-self: start;
  }
  .studio-body__copy {
    grid-column: 6 / span 6;
  }
}

.studio-body__copy p {
  font-size: clamp(1.02rem, 0.4vw + 0.92rem, 1.2rem);
  color: var(--fg-dim);
  max-width: 60ch;
}

.studio-body__copy p + p {
  margin-block-start: 1.5em;
}

.studio-body__copy p:first-child {
  color: var(--fg);
  font-family: var(--display);
  font-size: var(--t-h4);
  line-height: 1.42;
}

.disciplines {
  display: grid;
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

.discipline {
  display: grid;
  gap: 0.7rem;
}

.discipline__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.discipline__name {
  font-family: var(--display);
  font-size: var(--t-h4);
}

.discipline__value {
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}

.discipline__track {
  height: 1px;
  background: var(--rule);
  overflow: hidden;
}

.discipline__bar {
  display: block;
  height: 100%;
  background: var(--fg);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1400ms var(--ease-out);
  transition-delay: var(--anim-delay, 0ms);
}

.is-in .discipline__bar {
  transform: scaleX(var(--level, 1));
}

.rooms {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  color: var(--fg-faint);
}

/* ---- services ------------------------------------------------------------ */

.craft {
  border-block-start: var(--rule-w) solid var(--rule);
}

.craft__item {
  border-block-end: var(--rule-w) solid var(--rule);
}

.craft__inner {
  display: grid;
  gap: clamp(1rem, 2.5vw, 2rem) var(--gutter);
  grid-template-columns: repeat(12, minmax(0, 1fr));
  padding-block: clamp(2rem, 4.5vw, 4rem);
  align-items: start;
}

.craft__num {
  grid-column: 1 / -1;
  color: var(--fg-faint);
}

.craft__name {
  grid-column: 1 / -1;
  font-family: var(--display);
  font-weight: 300;
  font-size: clamp(1.85rem, 4.6vw, 3.75rem);
  line-height: 1.04;
  letter-spacing: -0.018em;
}

.craft__body {
  grid-column: 1 / -1;
  color: var(--fg-dim);
  max-width: 58ch;
}

.craft__media {
  grid-column: 1 / -1;
}

@media (min-width: 900px) {
  .craft__num {
    grid-column: 1 / span 1;
    padding-block-start: 0.75rem;
  }
  .craft__name {
    grid-column: 2 / span 4;
  }
  .craft__body {
    grid-column: 7 / span 4;
  }
  .craft__media {
    grid-column: 11 / span 2;
  }
}

/* ---- films --------------------------------------------------------------- */

.screening {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem) var(--gutter);
}

@media (min-width: 1000px) {
  .screening {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
  }
  .screening__preview {
    grid-column: 1 / span 7;
    position: sticky;
    inset-block-start: calc(var(--header-h) + 1.5rem);
  }
  .screening__list {
    grid-column: 9 / span 4;
  }
}

.film__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--ink);
  isolation: isolate;
}

.film__poster {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1400ms var(--ease-out-soft), opacity 420ms var(--ease-out);
}

.film__poster.is-swapping {
  opacity: 0;
}

.film__frame::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgb(0 0 0 / 0.28) 0%, rgb(0 0 0 / 0.06) 45%, rgb(0 0 0 / 0.42) 100%);
  transition: opacity 500ms var(--ease-out);
  pointer-events: none;
}

.film__play {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
}

/* A single hairline circle — the only ornament on the page. */
.film__play-mark {
  width: clamp(3.5rem, 7vw, 5.5rem);
  height: clamp(3.5rem, 7vw, 5.5rem);
  border: 1px solid rgb(243 241 237 / 0.7);
  border-radius: 50%;
  display: grid;
  place-items: center;
  transition: transform 620ms var(--ease-out), background-color 500ms var(--ease-out),
    border-color 500ms var(--ease-out);
}

.film__play-mark::before {
  content: '';
  width: 0;
  height: 0;
  margin-inline-start: 0.22em;
  border-block: 0.44em solid transparent;
  border-inline-start: 0.72em solid var(--bone);
  font-size: clamp(1rem, 1.8vw, 1.5rem);
  transition: border-inline-start-color 500ms var(--ease-out);
}

@media (hover: hover) {
  .film__frame:hover .film__poster {
    transform: scale(1.035);
  }
  .film__play:hover .film__play-mark {
    transform: scale(1.08);
    background: var(--bone);
    border-color: var(--bone);
  }
  .film__play:hover .film__play-mark::before {
    border-inline-start-color: var(--ink);
  }
}

.film__play:focus-visible {
  outline-offset: -0.75rem;
}

.film__badge {
  position: absolute;
  inset-block-end: clamp(0.9rem, 2vw, 1.5rem);
  inset-inline-start: clamp(0.9rem, 2vw, 1.5rem);
  z-index: 2;
  color: rgb(243 241 237 / 0.75);
  pointer-events: none;
}

.film__player {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  z-index: 3;
}

.film__frame.is-playing .film__poster,
.film__frame.is-playing .film__play,
.film__frame.is-playing .film__badge,
.film__frame.is-playing::after {
  opacity: 0;
  pointer-events: none;
}

.screening__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin-block-start: clamp(0.9rem, 1.8vw, 1.4rem);
  padding-block-start: clamp(0.75rem, 1.4vw, 1.1rem);
  border-block-start: var(--rule-w) solid var(--rule);
}

.film__index {
  color: var(--fg-faint);
  margin-block-end: 0.35em;
  font-variant-numeric: tabular-nums;
}

.film__title {
  font-size: clamp(1.35rem, 2.6vw, 2.25rem);
  line-height: 1.1;
}

.film__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  color: var(--fg-faint);
}

/* ---- the list ------------------------------------------------------------ */

.screening__hint {
  color: var(--fg-faint);
  padding-block-end: 0.9rem;
  border-block-end: var(--rule-w) solid var(--rule);
}

@media (min-width: 1000px) {
  .screening__scroll {
    max-height: min(64svh, 40rem);
    overflow-y: auto;
    scrollbar-width: thin;
    overscroll-behavior: contain;
    /* The list fades out at its foot rather than stopping dead. */
    mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 3rem), transparent 100%);
  }
}

.film-group + .film-group {
  margin-block-start: clamp(1.5rem, 2.5vw, 2rem);
}

.film-group__name {
  position: sticky;
  inset-block-start: 0;
  z-index: 1;
  padding-block: 0.9rem 0.5rem;
  background: var(--bg);
  font-size: var(--t-h4);
  line-height: 1.2;
  color: var(--fg);
}

.track {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 0.9rem;
  width: 100%;
  padding-block: 0.7rem;
  border-block-end: var(--rule-w) solid var(--rule);
  color: var(--fg-dim);
  transition: color 380ms var(--ease-out), padding-inline-start 420ms var(--ease-out);
}

.track__num {
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
  transition: color 380ms var(--ease-out);
}

.track__label {
  text-align: start;
}

.track__cue {
  opacity: 0;
  color: var(--fg-faint);
  transform: translate3d(-0.4rem, 0, 0);
  transition: opacity 320ms var(--ease-out), transform 420ms var(--ease-out);
}

.track[aria-current='true'] {
  color: var(--fg);
}

.track[aria-current='true'] .track__num {
  color: var(--fg);
}

.track[aria-current='true'] .track__cue {
  opacity: 1;
  transform: none;
}

@media (hover: hover) {
  .track:hover {
    color: var(--fg);
    padding-inline-start: 0.5rem;
  }
  .track:hover .track__cue {
    opacity: 1;
    transform: none;
  }
}

/* ---- leadership board ---------------------------------------------------- */

.board {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem) var(--gutter);
}

.board__team {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem) var(--gutter);
}

@media (min-width: 700px) {
  .board__team {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1000px) {
  .board {
    grid-template-columns: repeat(12, minmax(0, 1fr));
  }
  /* The founder leads; the two team leaders sit alongside. */
  .person--lead {
    grid-column: 1 / span 6;
  }
  .board__team {
    grid-column: 8 / span 5;
    grid-template-columns: 1fr;
    align-content: start;
  }
}

/* The portrait is a small plate set beside the name, not a panel above it. */
.person {
  display: grid;
  grid-template-columns: clamp(4.5rem, 12vw, 7rem) minmax(0, 1fr);
  align-items: start;
  gap: clamp(1rem, 2.5vw, 1.75rem);
}

.person--lead {
  grid-template-columns: clamp(6rem, 16vw, 9.5rem) minmax(0, 1fr);
}

/* A frame reserved for a portrait. Until one is added it holds the person's
   initials, so the composition is complete either way. */
.person__portrait {
  position: relative;
  aspect-ratio: 4 / 5;
  display: grid;
  place-items: center;
  overflow: hidden;
  margin: 0;
  background: color-mix(in srgb, var(--fg) 4%, transparent);
  border: 1px solid var(--rule);
}

.person__body {
  min-width: 0;
}

.person__portrait.has-photo {
  border-color: transparent;
}

.person__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
}

.person__initials {
  font-size: clamp(1.05rem, 2.2vw, 1.6rem);
  line-height: 1;
  letter-spacing: 0.08em;
  color: var(--fg-faint);
}

.person--lead .person__initials {
  font-size: clamp(1.5rem, 3vw, 2.25rem);
}

.person__index {
  color: var(--fg-faint);
  margin-block-end: 0.6em;
}

.person__name {
  font-size: clamp(1.6rem, 3.4vw, 2.75rem);
  line-height: 1.05;
}

.person--lead .person__name {
  font-size: clamp(2rem, 4.6vw, 3.75rem);
}

.person__roles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2em 0.9em;
  margin-block-start: 0.6em;
  font-family: var(--display);
  font-size: var(--t-h4);
  line-height: 1.3;
}

/* A hairline bullet between roles, and again between crafts. */
.person__roles span + span::before,
.person__craft span + span::before {
  content: '·';
  margin-inline-end: 0.9em;
  opacity: 0.45;
}

.person__craft {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2em 0.9em;
  margin-block-start: 1em;
  padding-block-start: 0.9em;
  border-block-start: var(--rule-w) solid var(--rule);
  color: var(--fg-faint);
  max-width: 46ch;
}

/* ---- security & data protection ------------------------------------------ */

.vault {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem) var(--gutter);
}

@media (min-width: 900px) {
  .vault {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
  }
  .vault__copy {
    grid-column: 1 / span 5;
    position: sticky;
    inset-block-start: calc(var(--header-h) + 2rem);
  }
  .vault__body {
    grid-column: 7 / span 6;
  }
}

.vault__heading {
  font-size: var(--t-h2);
  max-width: 18ch;
}

.vault__lede {
  margin-block-start: clamp(1rem, 2vw, 1.5rem);
  color: var(--fg-dim);
  max-width: 42ch;
}

.vault__body p {
  color: var(--fg-dim);
  max-width: 62ch;
}

.vault__body p + p {
  margin-block-start: 1.35em;
}

/* A band of archived frames running the full width, under the statement. */
.archive-band {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.5rem, 1.2vw, 1.25rem);
  margin-block: clamp(2.5rem, 6vw, 5rem);
  padding-inline: var(--pad-x);
  max-width: var(--max);
  margin-inline: auto;
}

@media (min-width: 760px) {
  .archive-band {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  /* A slight stagger, so the band reads as a shelf rather than a strip. */
  .archive-band__frame:nth-child(even) {
    margin-block-start: clamp(1rem, 3vw, 3rem);
  }
}

.pledge {
  padding-block-start: clamp(1.5rem, 3vw, 2.5rem);
  border-block-start: 1px solid var(--rule);
}

.pledge__line {
  font-family: var(--display);
  font-size: var(--t-h3);
  line-height: 1.24;
  letter-spacing: -0.012em;
  max-width: 26ch;
}

.pledge__sign {
  margin-block-start: clamp(1rem, 2vw, 1.5rem);
  color: var(--fg-faint);
}

/* ---- policies ------------------------------------------------------------ */

.policy-block + .policy-block {
  margin-block-start: clamp(3rem, 6vw, 5rem);
}

.policy-block .chapter__head {
  margin-block-end: clamp(1.25rem, 2.5vw, 2rem);
}


.policy {
  max-width: 68ch;
}

.policy__section + .policy__section {
  margin-block-start: clamp(2.5rem, 5vw, 4rem);
  padding-block-start: clamp(1.75rem, 3.5vw, 2.75rem);
  border-block-start: var(--rule-w) solid var(--rule);
}

.policy__heading {
  display: flex;
  align-items: baseline;
  gap: clamp(0.9rem, 2vw, 1.6rem);
  font-family: var(--display);
  font-weight: 300;
  font-size: var(--t-h3);
  line-height: 1.1;
  letter-spacing: -0.012em;
  margin-block-end: clamp(1rem, 2vw, 1.5rem);
}

.policy p {
  color: var(--fg-dim);
  max-width: 60ch;
}

.policy p + p {
  margin-block-start: 1.2em;
}

.policy__foot {
  margin-block-start: clamp(2.5rem, 5vw, 4rem);
  padding-block-start: clamp(1.5rem, 3vw, 2.25rem);
  border-block-start: var(--rule-w) solid var(--rule);
}

.policy__foot .note {
  max-width: 60ch;
}

/* ---- contact ------------------------------------------------------------- */

.contact-grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4.5rem) var(--gutter);
  grid-template-columns: repeat(12, minmax(0, 1fr));
}

.contact-grid__details,
.contact-grid__form {
  grid-column: 1 / -1;
}

@media (min-width: 960px) {
  .contact-grid__details {
    grid-column: 1 / span 4;
  }
  .contact-grid__form {
    grid-column: 6 / span 7;
  }
}

.detail-block + .detail-block {
  margin-block-start: clamp(1.75rem, 3.5vw, 2.75rem);
  padding-block-start: clamp(1.25rem, 2.5vw, 2rem);
  border-block-start: var(--rule-w) solid var(--rule);
}

.detail-block__label {
  color: var(--fg-faint);
  margin-block-end: 0.85em;
}

.detail-block__list {
  display: grid;
  gap: 0.4em;
  font-family: var(--display);
  font-size: var(--t-h4);
  line-height: 1.35;
}

.field {
  position: relative;
  display: block;
  margin-block-end: clamp(1.5rem, 3vw, 2.25rem);
}

.field__label {
  display: block;
  color: var(--fg-faint);
  margin-block-end: 0.7em;
}

.field__input {
  width: 100%;
  padding-block: 0.85em;
  border-block-end: 1px solid var(--rule-strong);
  font-family: var(--display);
  font-size: var(--t-h4);
  color: var(--fg);
  transition: border-color 420ms var(--ease-out);
  background: transparent;
}

.field__input::placeholder {
  color: var(--fg-faint);
  opacity: 1;
}

.field__input:focus {
  outline: none;
  border-color: var(--fg);
}

.field__input:focus-visible {
  outline: none;
}

textarea.field__input {
  resize: vertical;
  min-height: 7.5rem;
  line-height: 1.45;
}

.form__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
  justify-content: space-between;
}

.form__note {
  color: var(--fg-faint);
  max-width: 34ch;
}

.form__status {
  min-height: 1.5em;
  margin-block-start: 1rem;
  color: var(--fg-dim);
}

.contact-channels {
  display: grid;
  gap: 0;
  border-block-start: var(--rule-w) solid var(--rule);
  margin-block-start: clamp(3rem, 7vw, 6rem);
}

.contact-channels__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  padding-block: clamp(1rem, 2vw, 1.5rem);
  border-block-end: var(--rule-w) solid var(--rule);
  transition: padding-inline-start 520ms var(--ease-out);
}

@media (hover: hover) {
  .contact-channels__row:hover {
    padding-inline-start: 1rem;
  }
}

.contact-channels__name {
  font-family: var(--display);
  font-size: var(--t-h4);
}

.contact-channels__value {
  color: var(--fg-faint);
}

/* ==========================================================================
   Depth, glass and micro-interaction
   ==========================================================================

   An additive layer. It changes no colour, no size and no position in the
   static design — everything here is a translucent surface, a shadow, or a
   transform that only exists while a pointer is over an element or the page is
   moving. Remove this file and the site looks exactly the same at rest.

   Every effect is transform/opacity/filter only, and every one of them is
   switched off in 09-preferences.css when reduced motion is asked for.
   ========================================================================== */

:root {
  /* One shared glass recipe, tinted by whatever section it sits over. */
  --glass-blur: 18px;
  --glass-tint: rgb(11 11 11 / 0.55);
  --glass-edge: rgb(243 241 237 / 0.14);
  --glass-sheen: rgb(243 241 237 / 0.07);
  --lift: 0 1.5rem 3rem -1rem rgb(0 0 0 / 0.28);
}

/* ---- masthead: a pane of glass that appears once the page has moved -------- */

.masthead::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--glass-tint);
  border-block-end: 1px solid var(--glass-edge);
  opacity: 0;
  transition: opacity 620ms var(--ease-out);
  pointer-events: none;
}

/* A single highlight along the top edge, the way light catches real glass. */
.masthead::after {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: -1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--glass-sheen) 22%, var(--glass-sheen) 78%, transparent);
  opacity: 0;
  transition: opacity 620ms var(--ease-out);
  pointer-events: none;
}

.masthead[data-tone='light']::before {
  --glass-tint: rgb(243 241 237 / 0.62);
  --glass-edge: rgb(11 11 11 / 0.1);
}

.masthead.is-glass::before,
.masthead.is-glass::after {
  opacity: 1;
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .masthead.is-glass::before {
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.15);
    backdrop-filter: blur(var(--glass-blur)) saturate(1.15);
    background: color-mix(in srgb, var(--glass-tint) 72%, transparent);
  }
}

/* The menu sits above the masthead; the bar should not glaze over it. */
body[data-lock] .masthead::before,
body[data-lock] .masthead::after {
  opacity: 0;
}

/* ---- overlays ------------------------------------------------------------- */

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .menu {
    background: rgb(6 6 6 / 0.82);
    -webkit-backdrop-filter: blur(26px) saturate(1.1);
    backdrop-filter: blur(26px) saturate(1.1);
  }

  .viewer {
    background: rgb(4 4 4 / 0.88);
    -webkit-backdrop-filter: blur(30px);
    backdrop-filter: blur(30px);
  }

  .gallery__bar {
    -webkit-backdrop-filter: blur(20px) saturate(1.1);
  }
}

/* ---- buttons: glass, and a specular sweep on hover ------------------------ */

.action {
  border-color: var(--rule-strong);
  will-change: transform;
  transform: translate3d(var(--magnet-x, 0px), var(--magnet-y, 0px), 0);
  transition: color 480ms var(--ease-out), border-color 480ms var(--ease-out),
    transform 620ms var(--ease-out), box-shadow 620ms var(--ease-out);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .action {
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
  }
}

/* A narrow band of light that crosses the button as the pointer arrives. */
.action::after {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: -40%;
  width: 32%;
  z-index: -1;
  background: linear-gradient(100deg, transparent, rgb(243 241 237 / 0.5), transparent);
  transform: translate3d(0, 0, 0) skewX(-14deg);
  opacity: 0;
  transition: opacity 200ms linear;
  pointer-events: none;
}

.action:hover::after,
.action:focus-visible::after {
  opacity: 1;
  animation: sheen 900ms var(--ease-out) forwards;
}

@keyframes sheen {
  from {
    transform: translate3d(0, 0, 0) skewX(-14deg);
  }
  to {
    transform: translate3d(460%, 0, 0) skewX(-14deg);
  }
}

.action.is-magnetic {
  box-shadow: var(--lift);
}

.menu-toggle,
.film__play,
.viewer__btn,
.viewer__close {
  transform: translate3d(var(--magnet-x, 0px), var(--magnet-y, 0px), 0);
  transition: transform 620ms var(--ease-out);
}

/* ---- photographs: depth under the pointer --------------------------------- */

/* The frame lifts a little and the photograph inside drifts toward the pointer.
   Both are transforms on elements that are already composited. */
.frame-button,
.frame-link,
.story-card__frame,
.film__frame {
  transform: translate3d(0, var(--card-lift, 0px), 0);
  transition: transform 720ms var(--ease-out), box-shadow 720ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .story-card__link:hover .story-card__frame,
  .frame-button:hover,
  .film__frame:hover {
    --card-lift: -6px;
    box-shadow: var(--lift);
  }

  /* Inside the frame the photograph answers the pointer, a few pixels at most. */
  .frame-button .plate img,
  .frame-link .plate img,
  .story-card__frame .plate img,
  .mosaic__item .plate img {
    transform: scale(1.001) translate3d(var(--tilt-x, 0px), var(--tilt-y, 0px), 0);
    transition: transform 900ms var(--ease-out), opacity 900ms var(--ease-out);
  }

  .frame-button:hover .plate img,
  .frame-link:hover .plate img,
  .story-card__link:hover .plate img {
    transform: scale(1.05) translate3d(var(--tilt-x, 0px), var(--tilt-y, 0px), 0);
  }

  /* A hairline of glass around a frame while it is being looked at. */
  .mosaic__item .frame-button::after,
  .story-card__frame::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    border: 1px solid rgb(243 241 237 / 0);
    transition: border-color 620ms var(--ease-out);
    pointer-events: none;
  }

  .mosaic__item .frame-button:hover::after,
  .story-card__link:hover .story-card__frame::after {
    border-color: rgb(243 241 237 / 0.22);
  }
}

/* ---- the film play control ------------------------------------------------ */

.film__play-mark {
  position: relative;
  overflow: hidden;
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .film__play-mark {
    -webkit-backdrop-filter: blur(6px) saturate(1.2);
    backdrop-filter: blur(6px) saturate(1.2);
    background: rgb(243 241 237 / 0.08);
  }
}

/* A slow ring that breathes outward, so the control reads as live. */
.film__play::before {
  content: '';
  position: absolute;
  inset: 50%;
  width: clamp(3.5rem, 7vw, 5.5rem);
  height: clamp(3.5rem, 7vw, 5.5rem);
  margin: calc(clamp(3.5rem, 7vw, 5.5rem) / -2);
  border: 1px solid rgb(243 241 237 / 0.4);
  border-radius: 50%;
  animation: pulse-ring 3200ms var(--ease-out) infinite;
  pointer-events: none;
}

@keyframes pulse-ring {
  0% {
    transform: scale(1);
    opacity: 0.5;
  }
  70%,
  100% {
    transform: scale(1.55);
    opacity: 0;
  }
}

.film__frame.is-playing .film__play::before {
  animation: none;
  opacity: 0;
}

/* ---- scroll-linked motion ------------------------------------------------- */

/* Frames drift a few pixels against the page as it scrolls. The value is set
   once per frame by the shared rAF loop in assets/js/modules/scenes.js. */
[data-drift] .plate img,
[data-drift] > img {
  transform: translate3d(0, var(--drift, 0px), 0) scale(1.06);
}

.js-ready [data-drift] .plate img,
.js-ready [data-drift] > img {
  transition: opacity 900ms var(--ease-out);
}

/* A hairline that draws itself as its section arrives. */
.section-head,
.chapter__head,
.story-card__meta,
.screening__meta {
  position: relative;
}

.section-head::after,
.chapter__head::after {
  content: '';
  position: absolute;
  inset-block-end: -1px;
  inset-inline-start: 0;
  width: 100%;
  height: 1px;
  background: var(--fg);
  opacity: 0.25;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1400ms var(--ease-out);
}

.section-head.is-in::after,
.is-in .chapter__head::after,
.chapter__head.is-in::after {
  transform: scaleX(1);
}

/* ---- text and link micro-interaction -------------------------------------- */

.nav__link,
.filter,
.track,
.index__link,
.craft-list__link,
.menu__link,
.contact-channels__row {
  will-change: auto;
}

.logo img {
  transform: translate3d(0, 0, 0) scale(1);
  transition: filter 520ms var(--ease-out), opacity var(--dur-fast) var(--ease-out),
    transform 620ms var(--ease-out);
}

.logo:hover img {
  transform: scale(1.04);
}

/* The counters' figures settle in with a touch of weight. */
.figure-stat {
  transition: transform 900ms var(--ease-out), opacity 900ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .figure-stat:hover {
    transform: translate3d(0, -4px, 0);
  }
}

/* ---- keep compositing cheap ----------------------------------------------- */

.hero__plate,
.interlude__media,
.story-open__media,
.cursor,
.index__preview {
  backface-visibility: hidden;
}

/* ==========================================================================
   Reduced motion + print
   Visitors who ask for less motion get the same layout, art direction and
   photography — simply without travel, parallax or scroll-linked scaling.
   ========================================================================== */

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

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  /* Opacity fades are gentle enough to keep, at a shorter duration. */
  .plate img,
  .hero__plate img,
  .interlude__media img,
  .story-open__media img,
  [data-anim='fade'],
  .viewer,
  .viewer__figure img {
    transition-duration: 220ms !important;
  }

  [data-anim] {
    opacity: 1 !important;
    transform: none !important;
  }

  [data-anim='plate'] .plate img,
  .line > span {
    transform: none !important;
  }

  .hero {
    height: 100svh;
  }

  .hero__plate {
    transform: none !important;
  }

  .hero__type,
  .hero__corner {
    transform: none !important;
    opacity: 1 !important;
  }

  .interlude__media,
  .story-open__media {
    transform: none !important;
  }

  .cursor {
    display: none !important;
  }

  .menu {
    transition: none !important;
  }

  .discipline__bar {
    transform: scaleX(var(--level, 1)) !important;
  }

  .hero__scroll-line,
  .film__play::before {
    animation: none !important;
    transform: scaleX(1) !important;
  }

  /* The added depth layer: no lift, no lean, no drift, no sweep. Glass stays,
     because a translucent surface is not motion. */
  .action,
  .menu-toggle,
  .film__play,
  .viewer__btn,
  .viewer__close,
  .frame-button,
  .frame-link,
  .story-card__frame,
  .film__frame,
  .figure-stat,
  .logo img {
    transform: none !important;
    box-shadow: none !important;
  }

  [data-drift] .plate img,
  [data-drift] > img,
  .frame-button .plate img,
  .frame-link .plate img,
  .story-card__frame .plate img,
  .mosaic__item .plate img {
    transform: none !important;
  }

  .action::after,
  .film__play::before {
    display: none !important;
  }

  .section-head::after,
  .chapter__head::after {
    transform: scaleX(1) !important;
  }
}

/* ==========================================================================
   Touch comfort
   Desktop keeps its tight editorial density; touch devices get tap targets that
   comfortably clear 44px without changing the visual rhythm.
   ========================================================================== */

@media (pointer: coarse) {
  .link,
  .filter,
  .nav__link,
  .viewer__btn {
    padding-block: 0.7em;
  }

  .colophon__list {
    gap: 0.15em;
  }

  .logo,
  .menu-toggle,
  .contact-channels__name {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }

  /* The masthead phone number stays hidden until there is room for it. */
  @media (min-width: 1240px) {
    .masthead__phone {
      min-height: 44px;
      display: inline-flex;
      align-items: center;
    }
  }

  .menu-toggle {
    gap: 0.6em;
  }

  .index__link,
  .craft-list__link,
  .contact-channels__row {
    min-height: 48px;
  }
}

@media print {
  .masthead,
  .menu,
  .cursor,
  .loader,
  .veil,
  .viewer,
  .index__preview {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }

  .hero {
    height: auto;
  }
}

/* ==========================================================================
   Language, direction and the components added alongside them.

   The Arabic pages are not a mirrored copy of the stylesheet — the layout is
   written in logical properties throughout, so it flips on its own. What is
   left here is the handful of things logical properties cannot express: the
   Arabic typefaces, a few nudges that must travel with the reading direction,
   and the arrows, which are drawings of a direction rather than a layout.

   Both Arabic families are self-hosted (assets/fonts), subset to the Arabic
   ranges, and licensed under the SIL Open Font License 1.1 — see
   assets/fonts/LICENSE-NOTO.txt.
   ========================================================================== */

@font-face {
  font-family: 'Noto Naskh Arabic';
  src: url('../fonts/noto-naskh-arabic.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1,
    U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74,
    U+FE76-FEFC;
}

@font-face {
  font-family: 'Noto Sans Arabic';
  src: url('../fonts/noto-sans-arabic.woff2') format('woff2-variations');
  font-weight: 200 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1,
    U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74,
    U+FE76-FEFC;
}

/* --------------------------------------------------------------------------
   Arabic typography

   Naskh carries the display sizes: it has the calligraphic weight the
   Cormorant does in English, and it holds a large size without looking like
   an interface. Noto Sans Arabic takes the body and the micro labels.

   Arabic has no capitals, so `text-transform: uppercase` does nothing to it —
   but the wide tracking that goes with the small caps in English pulls Arabic
   letters apart from the words they are joined to, which is why it is undone
   here rather than inherited.
   -------------------------------------------------------------------------- */

[lang='ar'] {
  --display: 'Noto Naskh Arabic', 'Geeza Pro', 'Times New Roman', serif;
  --sans: 'Noto Sans Arabic', 'Geeza Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;

  /* Arabic sits on a deeper body and needs the extra leading to breathe. */
  --lh-body: 1.85;
  --lh-display: 1.16;
  --track-micro: 0.08em;
  --track-display: 0;
}

[lang='ar'] .display,
[lang='ar'] .micro {
  text-transform: none;
}

/* Arabic display type at English display sizes overshoots badly on a phone;
   these keep the same visual weight without spilling out of the viewport. */
[lang='ar'] {
  --t-mega: clamp(2.4rem, 10vw, 11rem);
  --t-hero: clamp(2.1rem, 7.4vw, 7.6rem);
  --t-display: clamp(1.85rem, 5.2vw, 5rem);
  --t-h2: clamp(1.6rem, 3.6vw, 3.4rem);
}

/* Latin runs inside Arabic — names, the brand, 4K, an email address — keep the
   Latin faces so they do not fall back to a default serif mid-sentence. */
[lang='ar'] [dir='ltr'] {
  font-family: 'Jost', 'Helvetica Neue', -apple-system, sans-serif;
  letter-spacing: normal;
}

[lang='ar'] .display[dir='ltr'],
[lang='ar'] [dir='ltr'].display {
  font-family: 'Cormorant Garamond', 'Didot', serif;
}

/* Phone numbers, email addresses and URLs are Latin sequences: they must read
   left to right even in the middle of an Arabic paragraph.

   Deliberately no `display` here. Setting one overrode the masthead's own
   `display: none`, which put the studio's phone number back into a header that
   hides it below 1240px — and at 375px it wrapped across two lines. */
[dir='rtl'] a[href^='tel:'],
[dir='rtl'] a[href^='mailto:'] {
  direction: ltr;
  unicode-bidi: isolate;
}

/* --------------------------------------------------------------------------
   Direction

   `--flip` inverts the small travelling nudges — a title stepping aside on
   hover, a cue sliding in — so they move with the reading direction rather
   than against it. Everything else is already logical.
   -------------------------------------------------------------------------- */

[dir='rtl'] {
  --flip: -1;
}

[dir='rtl'] .menu__note {
  transform: translate3d(0.6rem, 0, 0);
}

[dir='rtl'] .track__cue {
  transform: translate3d(0.4rem, 0, 0);
}

@media (min-width: 720px) {
  [dir='rtl'] .menu__link:hover .menu__word {
    transform: translate3d(calc(clamp(0.6rem, 1.4vw, 1.4rem) * -1), 0, 0);
  }
}

@media (min-width: 760px) {
  [dir='rtl'] .index__link:hover .index__title {
    transform: translate3d(calc(clamp(0.6rem, 1.6vw, 1.6rem) * -1), 0, 0);
  }
}

[dir='rtl'] .story-next__link:hover .story-next__title {
  transform: translate3d(calc(clamp(0.5rem, 1.5vw, 1.5rem) * -1), 0, 0);
}

[dir='rtl'] .action:hover .action__arrow {
  transform: translateX(-0.35em);
}

/* Arrows are pictures of a direction, so they turn round. The one that points
   down is not directional and stays as it is — as does the logo, and the play
   triangle, which are marks rather than instructions. */
[dir='rtl'] .action__arrow,
[dir='rtl'] .viewer__arrow {
  display: inline-block;
  transform: scaleX(-1);
}

[dir='rtl'] .action__arrow--down,
[dir='rtl'] .logo img,
[dir='rtl'] .colophon__mark img,
[dir='rtl'] .veil__mark,
[dir='rtl'] .loader__logo {
  transform: none;
}

/* The play triangle always points right — it is the universal mark for
   "start", not a direction of travel, and every media player keeps it that way
   in Arabic. It is drawn as a CSS triangle out of `border-inline-start`, which
   in RTL resolves to the right-hand border and turned the arrow round; these
   redraw it from physical sides so it cannot flip. */
[dir='rtl'] .film__play-mark::before {
  margin-inline-start: 0;
  margin-left: 0.22em;
  border-inline-start: 0;
  border-inline-end: 0;
  border-left: 0.72em solid var(--bone);
  border-right: 0;
}

@media (hover: hover) {
  [dir='rtl'] .film__play:hover .film__play-mark::before {
    border-left-color: var(--ink);
  }
}

[dir='rtl'] .action:hover .action__arrow--down {
  transform: translateY(0.35em);
}

/* The reel is a horizontal scroller; in RTL it should start at its own start. */
[dir='rtl'] .reel__progress > i {
  transform-origin: right center;
}

/* --------------------------------------------------------------------------
   Language switch
   -------------------------------------------------------------------------- */

.lang-switch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding-inline: 0.75em;
  border: var(--rule-w) solid rgb(243 241 237 / 0.28);
  border-radius: 999px;
  color: rgb(243 241 237 / 0.86);
  text-decoration: none;
  letter-spacing: 0.12em;
  line-height: 1;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out);
}

.lang-switch:hover,
.lang-switch:focus-visible {
  border-color: rgb(243 241 237 / 0.7);
  color: var(--bone);
  background: rgb(243 241 237 / 0.08);
}

.masthead[data-tone='light'] .lang-switch {
  border-color: rgb(11 11 11 / 0.24);
  color: rgb(11 11 11 / 0.82);
}

.masthead[data-tone='light'] .lang-switch:hover,
.masthead[data-tone='light'] .lang-switch:focus-visible {
  border-color: rgb(11 11 11 / 0.6);
  color: var(--ink);
  background: rgb(11 11 11 / 0.05);
}

.lang-switch--compact .lang-switch__full {
  display: none;
}

.lang-switch:not(.lang-switch--compact) .lang-switch__short {
  display: none;
}

.menu__lang {
  display: flex;
  align-items: center;
}

.menu__lang .lang-switch {
  border-color: rgb(243 241 237 / 0.3);
  color: rgb(243 241 237 / 0.9);
}

/* --------------------------------------------------------------------------
   Background music

   Four bars that stand still until the music is on, then breathe. The button
   is a real button with a real accessible name, and it is 44px square so it
   can be hit with a thumb.
   -------------------------------------------------------------------------- */

.music {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: var(--rule-w) solid rgb(243 241 237 / 0.28);
  border-radius: 999px;
  background: none;
  color: inherit;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}

.music:hover,
.music:focus-visible {
  border-color: rgb(243 241 237 / 0.7);
  background: rgb(243 241 237 / 0.08);
}

.masthead[data-tone='light'] .music {
  border-color: rgb(11 11 11 / 0.24);
}

.masthead[data-tone='light'] .music:hover,
.masthead[data-tone='light'] .music:focus-visible {
  border-color: rgb(11 11 11 / 0.6);
  background: rgb(11 11 11 / 0.05);
}

.music__bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 13px;
}

.music__bars i {
  display: block;
  width: 2px;
  height: 4px;
  background: currentColor;
  opacity: 0.75;
  transition: height 320ms var(--ease-out);
}

.music.is-playing .music__bars i {
  animation: music-bar 1200ms var(--ease-in-out) infinite;
}

.music.is-playing .music__bars i:nth-child(1) { animation-delay: 0ms; }
.music.is-playing .music__bars i:nth-child(2) { animation-delay: 180ms; }
.music.is-playing .music__bars i:nth-child(3) { animation-delay: 90ms; }
.music.is-playing .music__bars i:nth-child(4) { animation-delay: 260ms; }

@keyframes music-bar {
  0%, 100% { height: 4px; }
  50% { height: 13px; }
}

/* The player itself is never seen — it exists only to make sound. */
.music__player {
  position: fixed;
  width: 1px;
  height: 1px;
  inset-block-end: 0;
  inset-inline-start: 0;
  opacity: 0;
  border: 0;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Reading line

   The loader fills a hairline; the page carries on filling it as you read.
   -------------------------------------------------------------------------- */

.read-line {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  height: 2px;
  z-index: 190;
  pointer-events: none;
}

.read-line > i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, rgb(243 241 237 / 0.15), rgb(243 241 237 / 0.85));
  transform: scaleX(var(--read, 0));
  transform-origin: left center;
}

[dir='rtl'] .read-line > i {
  transform-origin: right center;
  background: linear-gradient(270deg, rgb(243 241 237 / 0.15), rgb(243 241 237 / 0.85));
}

/* --------------------------------------------------------------------------
   Film grain

   A photographic studio's pages should feel like a print, not a screen. This
   is a single tiled SVG of monochrome noise at very low opacity — no images
   fetched, no JavaScript, and it sits above the page but below every control.

   It drifts by a few pixels on a slow loop, which is what stops the texture
   reading as a dirty screen. Anyone who has asked for reduced motion gets the
   grain standing perfectly still.
   -------------------------------------------------------------------------- */

.grain {
  position: fixed;
  inset: -150px;
  z-index: 120;
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain-drift 6s steps(6) infinite;
  will-change: transform;
}

@keyframes grain-drift {
  0% { transform: translate3d(0, 0, 0); }
  16% { transform: translate3d(-14px, 8px, 0); }
  33% { transform: translate3d(9px, -13px, 0); }
  50% { transform: translate3d(-7px, 15px, 0); }
  66% { transform: translate3d(13px, 6px, 0); }
  83% { transform: translate3d(-11px, -9px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* --------------------------------------------------------------------------
   Photographs arriving like a print developing

   Instead of a plain opacity fade, a frame resolves: it comes up slightly
   soft and desaturated and settles into focus. It is a quarter of a second
   and most people will never consciously notice it — which is the point.
   -------------------------------------------------------------------------- */

.plate img,
.hero__plate img,
.story-open__media img,
.interlude__media img {
  transition: opacity var(--dur) var(--ease-out), filter var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}

.plate img:not(.is-loaded),
.hero__plate img:not(.is-loaded),
.story-open__media img:not(.is-loaded),
.interlude__media img:not(.is-loaded) {
  filter: saturate(0.4) blur(12px);
}

.plate img.is-loaded,
.hero__plate img.is-loaded,
.story-open__media img.is-loaded,
.interlude__media img.is-loaded {
  filter: none;
}

/* --------------------------------------------------------------------------
   Components introduced with the rewrite
   -------------------------------------------------------------------------- */

/* The unit beside a figure: "200+ TB" rather than the old "200TB+". */
.figure-stat__unit {
  margin-inline-start: 0.28em;
  font-size: 0.5em;
  letter-spacing: 0.06em;
  color: var(--fg-dim);
}

/* "(optional)", set beside a field label without the label's small caps. */
.field__optional {
  text-transform: none;
  letter-spacing: 0;
  color: var(--fg-faint);
}

/* An invalid field states it, and the message beside it is unmistakable. */
.field__input[aria-invalid='true'] {
  border-color: #b3261e;
  box-shadow: 0 1px 0 0 #b3261e;
}

.form__status.is-error {
  color: #b3261e;
  font-weight: 500;
}

[data-theme='void'] .form__status.is-error,
[data-theme='dark'] .form__status.is-error {
  color: #ff8a80;
}

/* The link to the untouched original, beside the viewer's close button. */
.viewer__tools {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.5rem);
}

.viewer__original {
  color: rgb(243 241 237 / 0.62);
  text-decoration: none;
  border-block-end: 1px solid rgb(243 241 237 / 0.3);
  padding-block-end: 0.2em;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.viewer__original:hover,
.viewer__original:focus-visible {
  color: var(--bone);
  border-color: var(--bone);
}

/* Classes that replaced inline styles, so the templates carry no colour. */
.studio-preview__label,
.closing__label,
.chapter__index,
.story-open__kind,
.story-next__label,
.studio-body__label,
.gallery__hint {
  color: var(--fg-faint);
}

.studio-preview__label {
  margin-block-end: 1.6em;
}

.closing__label {
  margin-block-end: 2em;
}

.story-open__kind {
  margin-block-end: 1.2em;
}

.story-next__label {
  margin-block-end: 0.8em;
}

.studio-body__label {
  margin-block-end: 1.6em;
}

.studio-body__label--spaced {
  margin-block: 2.5em 1em;
}

.studio-preview__action {
  margin-block-start: clamp(2rem, 4vw, 3rem);
}

.weddings__also {
  max-width: 44ch;
  margin-block-end: clamp(2rem, 4vw, 3rem);
}

.about__intro {
  max-width: 52ch;
  margin-block-end: clamp(2rem, 4vw, 3rem);
}

.policy-block__lede {
  margin-block-end: clamp(1.5rem, 3vw, 2.5rem);
}

.page-head__entity,
.colophon__entity {
  color: var(--fg-faint);
  margin-block-start: 1.2em;
  max-width: 44ch;
}

.colophon__credit {
  color: var(--fg-dim);
}

/* --------------------------------------------------------------------------
   The map

   A still panel until a visitor asks for it, then the live frame in its place.
   Same idea as the film posters: the page requests nothing from a third party
   on load.
   -------------------------------------------------------------------------- */

.map {
  border: var(--rule-w) solid var(--rule);
  background: var(--plate-bg);
}

.map__stage {
  position: relative;
  aspect-ratio: 16 / 9;
  min-height: 18rem;
  overflow: hidden;
}

@media (max-width: 759px) {
  .map__stage {
    aspect-ratio: 4 / 5;
    min-height: 0;
  }
}

.map__facade {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 2.5vw, 1.75rem);
  padding: var(--gutter);
  text-align: center;
  /* A quiet cartographic hatch, drawn in CSS — no image is fetched for it. */
  background-image:
    linear-gradient(var(--rule) 1px, transparent 1px),
    linear-gradient(90deg, var(--rule) 1px, transparent 1px);
  background-size: 3.5rem 3.5rem;
  background-position: center;
}

.map__address {
  font-family: var(--display);
  font-size: var(--t-h4);
  line-height: 1.5;
  color: var(--fg);
}

.map__notice {
  color: var(--fg-faint);
  max-width: 34ch;
}

.map__button {
  min-height: 44px;
}

.map__frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.map__foot {
  display: flex;
  justify-content: flex-end;
  padding: 1rem var(--gutter);
  border-block-start: var(--rule-w) solid var(--rule);
}

.map.is-loaded .map__foot {
  border-block-start-color: var(--rule);
}

/* --------------------------------------------------------------------------
   Touch targets

   Anything a thumb has to find is at least 44×44, which the filters and the
   viewer's controls were not.
   -------------------------------------------------------------------------- */

/* The menu toggle was 15px tall — too small to hit reliably with any pointer,
   and well under the 44px a thumb needs. The masthead is tall enough to carry
   a proper target without moving anything else. */
.menu-toggle {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 0.75em;
}

@media (pointer: coarse) {
  .filter,
  .viewer__btn,
  .viewer__close,
  .viewer__original,
  .nav__link {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }

  .filter {
    padding-inline: 1em;
  }
}

/* --------------------------------------------------------------------------
   Motion preferences

   These come last so they win: the grain stops drifting, the music bars stop
   dancing, and a photograph arrives without the softening.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .grain {
    animation: none !important;
  }

  .music.is-playing .music__bars i {
    animation: none !important;
    height: 9px;
  }

  .plate img:not(.is-loaded),
  .hero__plate img:not(.is-loaded),
  .story-open__media img:not(.is-loaded),
  .interlude__media img:not(.is-loaded) {
    filter: none;
  }

  .read-line > i {
    transition: none !important;
  }
}
