/* ---------- Tokens ---------- */
:root {
  /* 8px spacing system */
  --s-1: 8px;
  --s-2: 16px;
  --s-3: 24px;
  --s-4: 32px;
  --s-5: 40px;
  --s-6: 48px;
  --s-8: 64px;
  --s-10: 80px;
  --s-12: 96px;

  /* Grid: 12 columns, fluid container with side padding */
  --columns: 12;
  --gutter: var(--s-3);
  --page-padding: var(--s-8);

  /* header = top padding + one line of nav + same space below (for the blur) */
  --header-h: calc(var(--page-padding) * 2 + var(--s-3));

  --color-bg: #0f0f0f; /* same as the solid sections and inner pages */
  --frame: 30px;       /* matte around the whole page */
  --radius: 4px;       /* content and buttons */
  --color-text: #ffffff;
  --color-text-muted: rgba(255, 255, 255, 0.72);
  --color-accent: #FFC5D3; /* pink accent (labels, hovers, progress bars) — same as the milk */
  --milk: #FFC5D3;         /* the milk in transitions */

  --font: "Archivo", system-ui, sans-serif;
  --font-stretch: 125%; /* Archivo Expanded */

  /* Type scale: headings have their own sizes; everything else uses only these two */
  --text: 16px;    /* body copy, descriptions, buttons, nav, list titles */
  --text-sm: 12px; /* labels, numbers, meta, timecode */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-curtain: cubic-bezier(0.76, 0, 0.24, 1);
}

@media (max-width: 1024px) {
  :root { --page-padding: var(--s-6); --gutter: var(--s-2); }
}
@media (max-width: 640px) {
  :root { --page-padding: var(--s-4); --gutter: var(--s-2); --frame: 16px; } /* narrower frame: phone margins are only 32px */
}

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

/* Snap scrolling only on the homepage case slider */
html.snap {
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font);
  font-stretch: var(--font-stretch);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

/* Page frame: a 15px matte in the background colour on every edge, above the content
   (video, header, sections) but under the page-transition curtain and the cursor */
body::after {
  content: "";
  position: fixed;
  inset: var(--frame);
  z-index: 95;
  border-radius: var(--radius); /* rounded inner corners of the frame */
  box-shadow: 0 0 0 calc(var(--frame) * 4) var(--color-bg);
  pointer-events: none;
}

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

.container {
  width: 100%;
  padding-left: var(--page-padding);
  padding-right: var(--page-padding);
}

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

/* ---------- Header ---------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  height: var(--header-h);
}

/* Progressive blur (copied from archer.com): 5 stacked layers,
   each masked to a band, blur grows toward the top edge. */
.gradual-blur {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.gradual-blur > div {
  position: absolute;
  inset: 0;
}
.gradual-blur > div:nth-child(1) {
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  mask-image: linear-gradient(to top, transparent 0%, #000 20%, #000 40%, transparent 60%);
  -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 20%, #000 40%, transparent 60%);
}
.gradual-blur > div:nth-child(2) {
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  mask-image: linear-gradient(to top, transparent 20%, #000 40%, #000 60%, transparent 80%);
  -webkit-mask-image: linear-gradient(to top, transparent 20%, #000 40%, #000 60%, transparent 80%);
}
.gradual-blur > div:nth-child(3) {
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  mask-image: linear-gradient(to top, transparent 40%, #000 60%, #000 80%, transparent 100%);
  -webkit-mask-image: linear-gradient(to top, transparent 40%, #000 60%, #000 80%, transparent 100%);
}
.gradual-blur > div:nth-child(4) {
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  mask-image: linear-gradient(to top, transparent 60%, #000 80%, #000 100%);
  -webkit-mask-image: linear-gradient(to top, transparent 60%, #000 80%, #000 100%);
}
.gradual-blur > div:nth-child(5) {
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  mask-image: linear-gradient(to top, transparent 80%, #000 100%);
  -webkit-mask-image: linear-gradient(to top, transparent 80%, #000 100%);
}

.header-inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* same inset from the top as from the sides */
  padding-top: var(--page-padding);
}

.main-nav {
  display: flex;
  gap: var(--s-4);
}
.main-nav a {
  font-size: var(--text);
  font-weight: 400;
  color: var(--color-text-muted);
  transition: color 0.2s ease;
}
.main-nav a:hover,
.main-nav a:focus-visible { color: var(--color-text); }

.menu-toggle {
  display: none;
  background: none;
  border: 0;
  color: var(--color-text);
  font: inherit;
  font-size: var(--text);
  padding: var(--s-1) 0;
  margin: calc(var(--s-1) * -1) 0; /* bigger tap area without shifting alignment */
  cursor: pointer;
}

@media (max-width: 640px) {
  .menu-toggle { display: block; position: relative; z-index: 2; }
  .main-nav {
    position: fixed;
    inset: 0;
    flex-direction: column;
    justify-content: center;
    padding: 0 var(--page-padding);
    gap: var(--s-3);
    background: rgba(15, 15, 15, 0.92);
    backdrop-filter: blur(50px);
    -webkit-backdrop-filter: blur(50px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.35s var(--ease);
  }
  .main-nav a { font-size: 32px; color: var(--color-text); }
  .site-header.menu-open .main-nav { opacity: 1; pointer-events: auto; }
}

/* ---------- Background video stack ---------- */
.bg-stack {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: #000;
}
.bg-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  /* --crop: zoom to hide letterbox bars baked into a video file (1 = none) */
  transform: scale(calc(var(--crop, 1) * 1.06));
  transition: opacity 1.1s var(--ease), transform 1.6s var(--ease);
}
.bg-media.is-active {
  opacity: 1;
  transform: scale(var(--crop, 1));
}
/* darken bottom-left so text stays readable */
.bg-shade {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.15) 45%, rgba(0,0,0,0) 70%),
    linear-gradient(to bottom, rgba(0,0,0,0.25) 0%, rgba(0,0,0,0) 20%),
    rgba(0, 0, 0, 0.2); /* overall dim of the footage */
}

/* ---------- Case sections ---------- */
.cases { position: relative; z-index: 1; }

.case {
  height: 100vh;
  height: 100svh;
  scroll-snap-align: start;
  display: flex;
  align-items: flex-end;
  padding-bottom: var(--page-padding); /* shot list sits beside the text on desktop */
}
.case .grid { width: 100%; }

.case-content {
  grid-column: 1 / span 6;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
@media (max-width: 1024px) { .case-content { grid-column: 1 / span 9; } .case { padding-bottom: calc(var(--page-padding) + var(--s-8)); } }
@media (max-width: 640px)  { .case-content { grid-column: 1 / -1; } .case { padding-bottom: calc(var(--page-padding) + var(--s-8)); } }

.case-meta {
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.case-title {
  margin: 0;
  font-size: clamp(40px, 6vw, 96px); /* smaller than before: Archivo Expanded is ~25% wider */
  font-weight: 500;
  line-height: 0.95;
  letter-spacing: -0.03em;
}
.case-desc {
  margin: 0;
  max-width: 48ch;
  font-size: var(--text);
  font-weight: 300;
  line-height: 1.5;
  color: var(--color-text-muted);
}
/* "Cast & crew": framed by focus-point corners (same language as the cursor),
   on a soft frosted plate so it reads over any footage */
.case-cta {
  --cta-corner: var(--s-1);
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  margin-top: var(--s-2);
  padding: var(--s-2) var(--s-3);
  /* same type as the "01 — Short Film" label */
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  position: relative;
  border-radius: var(--radius);
  background-color: rgba(255, 255, 255, 0.08);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: color 0.3s ease, background-color 0.3s ease;
}
/* corner brackets: a 1px rounded border, masked so only the four corners show */
.case-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid currentColor;
  border-radius: inherit;
  --m: linear-gradient(#000 0 0);
  -webkit-mask:
    var(--m) top left / var(--cta-corner) var(--cta-corner) no-repeat,
    var(--m) top right / var(--cta-corner) var(--cta-corner) no-repeat,
    var(--m) bottom left / var(--cta-corner) var(--cta-corner) no-repeat,
    var(--m) bottom right / var(--cta-corner) var(--cta-corner) no-repeat;
  mask:
    var(--m) top left / var(--cta-corner) var(--cta-corner) no-repeat,
    var(--m) top right / var(--cta-corner) var(--cta-corner) no-repeat,
    var(--m) bottom left / var(--cta-corner) var(--cta-corner) no-repeat,
    var(--m) bottom right / var(--cta-corner) var(--cta-corner) no-repeat;
  transition: -webkit-mask-size 0.4s var(--ease), mask-size 0.4s var(--ease);
  pointer-events: none;
}
/* hover: focus "locks" — brackets grow, everything turns pink */
.case-cta:hover,
.case-cta:focus-visible {
  color: var(--color-accent);
  background-color: rgba(255, 197, 211, 0.12);
  --cta-corner: var(--s-2);
}

/* Text reveal: staggered when a section becomes active */
.case-content > * {
  opacity: 0;
  transform: translateY(var(--s-3));
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}
.case.is-active .case-content > * { opacity: 1; transform: none; }
.case.is-active .case-content > *:nth-child(1) { transition-delay: 0.15s; }
.case.is-active .case-content > *:nth-child(2) { transition-delay: 0.25s; }
.case.is-active .case-content > *:nth-child(3) { transition-delay: 0.35s; }
.case.is-active .case-content > *:nth-child(4) { transition-delay: 0.45s; }

/* The button needs its hover transitions on top of the reveal ones (the generic rule above would
   otherwise replace them), and the reveal delay must not slow down the hover */
.case-content > .case-cta {
  transition:
    opacity 0.8s var(--ease),
    transform 0.8s var(--ease),
    color 0.3s ease,
    background-color 0.3s ease,
    background-size 0.4s var(--ease);
}
.case.is-active .case-content > .case-cta { transition-delay: 0.45s, 0.45s, 0s, 0s, 0s; }

/* ---------- Case switcher: shot list ---------- */
/* Desktop: a vertical list in the bottom-right (cols 9–12), like a shot list.
   The running film's divider fills pink and shows a camera timecode. */
.case-tabs {
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--page-padding);
  z-index: 10;
  pointer-events: none; /* only the rows are clickable, not the empty grid */
}
.case-tab {
  grid-column: 10 / -1;
  position: relative;
  display: grid;
  grid-template-columns: var(--s-4) 1fr auto;
  align-items: baseline;
  column-gap: var(--s-2);
  padding: var(--s-2) 0;
  border: 0;
  background: none;
  color: var(--color-text);
  font: inherit;
  text-align: left;
  pointer-events: auto;
  opacity: 0.45;
  transition: opacity 0.4s var(--ease);
}
.case-tab:first-child { border-top: 1px solid rgba(255, 255, 255, 0.15); }
.case-tab:hover,
.case-tab.is-active { opacity: 1; }
.case-tab:focus-visible { outline: 1px solid var(--color-accent); outline-offset: var(--s-1); }

/* divider under each row doubles as the progress bar */
.case-tab-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.15);
}
.case-tab-fill {
  position: absolute;
  inset: 0;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
}
.case-tab.is-active .case-tab-bar { height: 2px; }

.case-tab-head { display: contents; } /* num + title sit directly in the row grid */
.case-tab-num {
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.case-tab.is-active .case-tab-num { color: var(--color-accent); }
.case-tab-title {
  font-size: var(--text);
  font-weight: 500;
  transition: transform 0.4s var(--ease);
}
.case-tab:hover .case-tab-title { transform: translateX(var(--s-1)); }

.case-tab-tc {
  display: none;
  grid-column: 3;
  grid-row: 1;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--color-text);
}
.case-tab.is-active .case-tab-tc { display: block; }

/* Tablet and phone: compact numbered bars under the slide text */
@media (max-width: 1024px) {
  .case-tab {
    grid-column: span 3;
    display: flex;
    flex-direction: column;
    align-items: stretch; /* desktop rows use baseline; bars need full width here */
    gap: var(--s-1);
    padding: 0;
  }
  .case-tab:first-child { border-top: 0; }
  .case-tab-bar { position: relative; height: 2px; }
  .case-tab.is-active .case-tab-bar { height: 2px; }
  .case-tab-title,
  .case-tab.is-active .case-tab-tc { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .bg-media, .case-content > * { transition-duration: 0.01s; transform: none; }
}

/* ---------- Shared bits ---------- */
.main-nav a[aria-current="page"] { color: var(--color-text); }

.text-link {
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.4);
  text-underline-offset: 4px;
  transition: text-decoration-color 0.2s ease, color 0.2s ease;
}
.text-link:hover { color: var(--color-accent); text-decoration-color: currentColor; }

/* Entrance reveal (pages other than the homepage).
   transitions.js adds html.is-ready once the curtain has lifted. */
.reveal {
  opacity: 0;
  transform: translateY(var(--s-3));
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.is-ready .reveal { opacity: 1; transform: none; }
.is-ready .reveal:nth-child(2) { transition-delay: 0.08s; }
.is-ready .reveal:nth-child(3) { transition-delay: 0.16s; }
.is-ready .reveal:nth-child(4) { transition-delay: 0.24s; }

/* Subpages sit on the page colour (the homepage has the film behind it) */
.page-inner { background: #0f0f0f; }

/* Small pink label above a heading or beside a section */
.eyebrow {
  margin: 0 0 var(--s-3);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent);
}

/* ---------- Page transition curtain ---------- */
.curtain {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--milk);
  color: #0b0b0b;
  transform: translateY(100%);
  pointer-events: none;
}
.curtain-mark {
  font-size: clamp(32px, 5vw, 72px);
  font-weight: 500;
  letter-spacing: -0.02em;
  opacity: 0;
  transform: translateY(var(--s-4));
}

/* 1. leaving: curtain rises from the bottom and covers the page */
.is-covering .curtain {
  transform: none;
  pointer-events: auto;
  transition: transform 0.65s var(--ease-curtain);
}
.is-covering .curtain-mark {
  opacity: 1;
  transform: none;
  transition: opacity 0.4s ease 0.25s, transform 0.6s var(--ease) 0.2s;
}
/* 2. new page loads already covered */
.is-entering .curtain { transform: none; }
.is-entering .curtain-mark { opacity: 1; transform: none; }
/* 3. curtain lifts off the top */
.is-leaving .curtain {
  transform: translateY(-100%);
  transition: transform 0.9s var(--ease-curtain);
}
.is-leaving .curtain-mark {
  opacity: 0;
  transform: translateY(calc(var(--s-4) * -1));
  transition: opacity 0.3s ease, transform 0.6s var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  .reveal, .portrait-media::before, .portrait-frame, .portrait-frame img, .portrait-caption { transition-duration: 0.01s; transition-delay: 0s; }
}


/* ---------- Custom cursor: camera focus point ---------- */
.has-custom-cursor,
.has-custom-cursor * { cursor: none !important; }

.cursor-cross,
.cursor-frame {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 200; /* above the page-transition curtain */
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.cursor-cross.is-visible,
.cursor-frame.is-visible { opacity: 1; }

/* Crosshair: centred on the pointer, soft pink glow */
.cursor-cross {
  width: var(--s-2);
  height: var(--s-2);
  margin: calc(var(--s-1) * -1) 0 0 calc(var(--s-1) * -1);
  filter: drop-shadow(0 0 2px rgba(255, 197, 211, 0.9));
}
.cursor-cross::before,
.cursor-cross::after {
  content: "";
  position: absolute;
  background: #fff;
  transition: background 0.25s ease;
}
.cursor-cross::before { left: 0; top: 50%; width: 100%; height: 1px; margin-top: -0.5px; }
.cursor-cross::after  { top: 0; left: 50%; height: 100%; width: 1px; margin-left: -0.5px; }

/* Corner brackets: 40 x 32 box, trails the pointer */
.cursor-frame {
  width: var(--s-5);
  height: var(--s-4);
  margin: calc(var(--s-4) * -0.5) 0 0 calc(var(--s-5) * -0.5);
}
.cursor-frame-inner {
  position: absolute;
  inset: 0;
  transition: transform 0.35s var(--ease);
}
.cc {
  position: absolute;
  width: var(--s-1);
  height: var(--s-1);
  border: 0 solid rgba(255, 255, 255, 0.85);
  transition: border-color 0.25s ease;
}
.cc-tl { top: 0;    left: 0;  border-top-width: 1.5px;    border-left-width: 1.5px; }
.cc-tr { top: 0;    right: 0; border-top-width: 1.5px;    border-right-width: 1.5px; }
.cc-bl { bottom: 0; left: 0;  border-bottom-width: 1.5px; border-left-width: 1.5px; }
.cc-br { bottom: 0; right: 0; border-bottom-width: 1.5px; border-right-width: 1.5px; }

/* Over links: focus "locks" — brackets tighten and turn pink */
.cursor-frame.is-locked .cursor-frame-inner { transform: scale(0.7); }
.cursor-frame.is-locked .cc { border-color: var(--color-accent); }
.cursor-cross.is-locked::before,
.cursor-cross.is-locked::after { background: var(--color-accent); }

/* Click: quick squeeze */
.cursor-frame.is-pressed .cursor-frame-inner { transform: scale(0.55); }

/* On the pink milk (page transition, intro) the cursor takes the colour of the logo shown there */
html.milk-mark .cursor-cross,
html:not(.has-milk).is-covering .cursor-cross,
html.is-entering .cursor-cross { filter: none; }
html.milk-mark .cursor-cross::before,
html.milk-mark .cursor-cross::after,
html:not(.has-milk).is-covering .cursor-cross::before,
html:not(.has-milk).is-covering .cursor-cross::after,
html.is-entering .cursor-cross::before,
html.is-entering .cursor-cross::after { background: #6a203c; }
html.milk-mark .cc,
html:not(.has-milk).is-covering .cc,
html.is-entering .cc { border-color: #6a203c; }

/* ---------- Bottom progressive blur ---------- */
/* Same 5 layers as the header, flipped so the blur is strongest at the bottom edge */
.gradual-blur-bottom {
  position: fixed;
  top: auto;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--header-h);
  transform: scaleY(-1);
  z-index: 1; /* homepage: above the video, below the slide text (which comes later in the page) */
}
/* Homepage: taller, so it reaches up behind the description and the shot list */
.gradual-blur-bottom { height: 40vh; }
/* Subpages: content scrolls underneath, so the blur sits on top of it and stays header-height */
.page-inner .gradual-blur-bottom { z-index: 40; height: var(--header-h); }
/* ---------- Homepage intro: loader → pink curtain → hero ---------- */
/* intro.js drives the classes on <html>; the curtain itself is the shared page-transition curtain */
.intro-screen { display: none; }
html.intro:not(.intro-done) body { overflow: hidden; }

html.intro .intro-screen {
  position: fixed;
  inset: 0;
  z-index: 90; /* under the curtain (100), over everything else */
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg);
}
.loader {
  width: calc(var(--s-1) * 24);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--s-2);
}
.loader-bar {
  align-self: stretch;
  height: 1px;
  background: rgba(255, 255, 255, 0.15);
  overflow: hidden;
}
.loader-fill {
  display: block;
  height: 100%;
  background: var(--color-text);
  transform: scaleX(0);
  transform-origin: left;
}
.loader-count {
  font-size: var(--text-sm);
  letter-spacing: 0.16em;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

/* Hero entrance once the curtain lifts: picture settles, UI fades in, slide text staggers up */
html.intro .bg-stack {
  transform: scale(1.12);
  transition: transform 2.2s var(--ease);
}
html.intro.intro-done .bg-stack { transform: none; }

html.intro .site-header,
html.intro .case-tabs,
html.intro .gradual-blur-bottom { transition: opacity 0.9s var(--ease) 0.35s; }
html.intro:not(.intro-done) .site-header,
html.intro:not(.intro-done) .case-tabs,
html.intro:not(.intro-done) .gradual-blur-bottom { opacity: 0; }
html.intro:not(.intro-done) .case-content > * {
  opacity: 0;
  transform: translateY(var(--s-3));
}

/* ---------- Director teaser (homepage, after the films) ---------- */
/* Solid section that scrolls up over the fixed video; the header stays on top */
.teaser {
  position: relative;
  z-index: 20; /* above the video, bottom blur and shot list; below the header (50) */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: var(--header-h) 0;
  background: #0f0f0f;
  scroll-snap-align: start;
}
.teaser .grid { width: 100%; }
.teaser-content { grid-column: 1 / span 8; }
.teaser-lead {
  margin: 0 0 var(--s-5);
  font-size: clamp(28px, 3.2vw, 48px);
  font-weight: 300;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.teaser .case-cta { margin-top: 0; }
@media (max-width: 1024px) { .teaser-content { grid-column: 1 / -1; } }

/* Text rises in when a [data-reveal] section arrives (footer.js adds .is-in) — and only once
   the page is uncovered (.is-ready), so after a transition it does not play under the milk */
.t-reveal {
  opacity: 0;
  transform: translateY(var(--s-3));
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.is-ready .is-in .t-reveal { opacity: 1; transform: none; }
.is-ready .is-in .t-reveal:nth-child(2) { transition-delay: 0.1s; }
.is-ready .is-in .t-reveal:nth-child(3) { transition-delay: 0.2s; }
.is-ready .is-in .t-reveal:nth-child(4) { transition-delay: 0.3s; }

/* Hero-only overlays step aside once the teaser covers the screen */
.case-tabs,
.gradual-blur-bottom { transition: opacity 0.5s var(--ease); }
html.past-hero .case-tabs,
html.past-hero .gradual-blur-bottom { opacity: 0; pointer-events: none; }
html.past-hero .case-tab { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .t-reveal { transition-duration: 0.01s; transform: none; }
}

/* ---------- Contact (homepage, last screen) ---------- */
.outro {
  position: relative;
  z-index: 20; /* covers the fixed video like the teaser */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: #0f0f0f;
  scroll-snap-align: start;
}
.contact {
  flex: 1;
  align-content: center;
  padding-top: var(--header-h);
  padding-bottom: var(--s-12);
}
.contact-content { grid-column: 1 / -1; }
.contact-lead {
  margin: 0 0 var(--s-3);
  font-size: var(--text);
  color: var(--color-text-muted);
}
.contact-title {
  margin: 0 0 var(--s-4);
  font-size: clamp(20px, 6.2vw, 88px); /* sized so the address fits on one line at every width */
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.02em;
}
.contact-email {
  border-bottom: 1px solid rgba(255, 255, 255, 0.25);
  overflow-wrap: anywhere;
  transition: color 0.3s ease, border-color 0.3s ease;
}
.contact-email:hover,
.contact-email:focus-visible { color: var(--color-accent); border-color: currentColor; }

.contact-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-3);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.contact-links a { color: var(--color-text); transition: color 0.3s ease; }
.contact-links a:hover,
.contact-links a:focus-visible { color: var(--color-accent); }

/* ---------- Footer (both pages) ---------- */
.site-footer { padding-bottom: var(--page-padding); }
/* three columns: copyright left, city dead centre, back to top right (whatever their widths) */
.footer-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: baseline;
  gap: var(--s-3);
  padding-top: var(--s-3);
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.footer-inner > * { white-space: nowrap; }
.footer-inner > :last-child { grid-column: 3; justify-self: end; }
/* phones: just copyright + back to top */
@media (max-width: 640px) { .footer-inner > :nth-child(2) { display: none; } }

.to-top {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  transition: color 0.3s ease;
}
.to-top:hover,
.to-top:focus-visible { color: var(--color-accent); }

/* Subpages: the bottom blur steps aside when the footer is in view, so it stays sharp */
.page-inner .gradual-blur-bottom { transition: opacity 0.4s var(--ease); }
html.at-footer .page-inner .gradual-blur-bottom { opacity: 0; }

/* ---------- Work page: film grid ---------- */
.work {
  padding-top: calc(var(--header-h) + var(--s-4));
  padding-bottom: var(--s-12);
}
/* Subpage heading, centred (Work, In Development, film pages, About) */
.work-head {
  justify-items: center;
  align-items: end;
  margin-bottom: var(--s-8);
  text-align: center;
}
.work-head .eyebrow { grid-column: 1 / -1; }
.work-title {
  grid-column: 3 / span 8;               /* the middle 8 of 12 columns */
  margin: 0;
  font-size: clamp(28px, 3.2vw, 48px);
  font-weight: 300;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
@media (max-width: 1024px) {
  .work-title { grid-column: 2 / span 10; }
}

.work-grid { row-gap: var(--s-5); }

/* Card = picture with a caption row on top of it, styled like the hero shot list:
   number · title (+ cast) · type; the bottom edge line fills pink on hover */
.work-card {
  grid-column: span 6;
  position: relative;
  display: block;
}
.work-media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--radius);
  clip-path: inset(0 round var(--radius)); /* keeps the zooming image inside the rounded corners */
  background: #1a1a1a;
}
.work-media img,
.work-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.7); /* dimmed until hovered */
  transition: transform 1.2s var(--ease), opacity 0.6s ease, filter 0.6s ease;
}
.work-video { opacity: 0; transform: scale(var(--crop, 1)); }
.work-card.is-playing .work-video { opacity: 1; }
.work-card:hover .work-media img { transform: scale(1.04); }
.work-card:hover .work-media img,
.work-card:hover .work-video,
.work-card:focus-visible .work-media img { filter: none; }

/* soft shade so the caption reads over any picture */
.work-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 35%);
  pointer-events: none;
}

.work-info {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: var(--s-4) 1fr auto;
  align-items: baseline;
  column-gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
}
.work-num {
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  transition: color 0.4s ease;
}
.work-text { transition: transform 0.4s var(--ease); }
.work-name {
  margin: 0;
  font-size: var(--text);
  font-weight: 500;
}
.work-sub {
  margin: var(--s-1) 0 0;
  font-size: var(--text-sm);
  letter-spacing: 0.02em;
  color: var(--color-text-muted);
}
.work-line {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.15);
}
.work-line-fill {
  position: absolute;
  inset: 0;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.8s var(--ease);
}
.work-card:hover .work-line-fill,
.work-card:focus-visible .work-line-fill { transform: scaleX(1); }
.work-card:hover .work-num { color: var(--color-accent); }
.work-card:hover .work-text { transform: translateX(var(--s-1)); }

@media (max-width: 640px) {
  .work-card,
  .work-title { grid-column: 1 / -1; }
  .work-info { padding: var(--s-2); }
  .work-sub { display: none; } /* keep the caption to one line on small pictures */
}

/* ---------- In Development page ---------- */
.dev {
  padding-top: calc(var(--header-h) + var(--s-4));
  padding-bottom: var(--s-12);
}

/* Full-bleed photo band */
.dev-photo {
  /* full width of the area inside the page frame, so its rounded corners are visible */
  margin: 0 var(--frame) var(--s-8);
  border-radius: var(--radius);
  height: clamp(320px, 70vh, 760px);
  overflow: hidden;
  /* clip-path (not just overflow + radius) so the zooming, parallax-moving image is always
     clipped to the rounded corners, even when the browser puts it on its own layer */
  clip-path: inset(0 round var(--radius));
  background: #1a1a1a;
}
/* Zoom + parallax: js/parallax.js moves the image with the scroll
   (starts zoomed in, pulls back and drifts slower than the page) */
.dev-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 36%; /* keeps the faces (about a third of the way down the photo) in view */
  filter: brightness(0.85);
  transform: scale(1.3);
  will-change: transform;
}
/* caption over the bottom-left corner, on a soft shade so it reads over any picture */
.dev-photo { position: relative; }
.dev-photo:has(figcaption)::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0) 25%);
  pointer-events: none;
}
.dev-photo figcaption {
  position: absolute;
  left: var(--s-3);
  bottom: var(--s-2);
  z-index: 1;
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.85);
}

/* Project list: spacious rows on the 12-column grid (number · title · genre/pages, logline under the title).
   The row closest to the middle of the screen is lit, the others dimmed (js/in-development.js). */
.dev-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.dev-item {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: start;
  padding: var(--s-10) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.dev-item:last-child { border-bottom: 0; }
.dev-num {
  grid-column: 1;
  grid-row: 1;
  padding-top: 0.9em;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.dev-item:hover .dev-num { color: var(--color-accent); }
.dev-name {
  grid-column: 2 / span 7;
  grid-row: 1;
  margin: 0;
  font-size: clamp(26px, 2.8vw, 40px);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.015em;
}
.dev-logline {
  grid-column: 2 / span 6;
  grid-row: 2;
  margin: var(--s-3) 0 0;
  max-width: 56ch;
  font-size: var(--text);
  line-height: 1.6;
  color: var(--color-text-muted);
}
.dev-meta {
  grid-column: 10 / -1;
  grid-row: 1;
  justify-self: start;
  padding-top: 0.9em;
  font-size: var(--text-sm);
  line-height: 1.6;
  letter-spacing: 0.04em;
  text-align: left;
  color: var(--color-text-muted);
}

/* dim everything except the active row; the active number turns pink */
.dev-num,
.dev-name,
.dev-logline,
.dev-meta { transition: opacity 0.6s var(--ease), color 0.6s var(--ease); }
.dev-list.has-active .dev-item:not(.is-active) .dev-num,
.dev-list.has-active .dev-item:not(.is-active) .dev-name,
.dev-list.has-active .dev-item:not(.is-active) .dev-logline,
.dev-list.has-active .dev-item:not(.is-active) .dev-meta { opacity: 0.25; }
.dev-item.is-active .dev-num { color: var(--color-accent); }
.dev-item.is-active .dev-name { color: var(--color-text); }

.is-ready .is-in .t-reveal:nth-child(5) { transition-delay: 0.4s; }

.dev-contact {
  margin: var(--s-5) 0 0;
  font-size: var(--text);
  color: var(--color-text-muted);
}

@media (max-width: 1024px) {
  .dev-name { grid-column: 2 / -1; }
  .dev-logline { grid-column: 2 / span 9; }
  .dev-meta { grid-column: 2 / -1; grid-row: 3; padding-top: 0; margin-top: var(--s-2); }
}
@media (max-width: 640px) {
  .dev-item { padding: var(--s-8) 0; }
  .dev-num { grid-column: 1 / span 2; }
  .dev-name,
  .dev-logline,
  .dev-meta { grid-column: 3 / -1; justify-self: start; text-align: left; }
}

/* ---------- Festival laurel ---------- */
.laurel { display: block; width: 100%; height: auto; color: #fff; }

/* Work: top-right corner of a thumbnail (Billie, Blood Orange), above the shade (30% opacity) */
.work-laurel {
  position: absolute;
  top: var(--s-3);
  right: var(--s-3);
  z-index: 1;
  width: 30%;
  max-width: 200px;
  opacity: 0.3;
  pointer-events: none;
}

/* ---------- WebGL milk transition (milk.js) ---------- */
/* In milk mode the curtain doesn't slide: it's a transparent layer holding the canvas.
   It stays visible all the time (hiding and re-showing it makes some browsers stop
   displaying the WebGL canvas after a page swap); between transitions the canvas is simply
   transparent and the layer lets clicks through. The name shows once the screen is covered. */
.milk-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
html.has-milk .curtain {
  transform: none;
  transition: none;
  background: transparent;
  visibility: visible;
  pointer-events: none;
}
html.has-milk.milk-on .curtain { pointer-events: auto; }
/* Logo: shrinks in (from slightly larger and soft, like a lens finding focus), shrinks out on exit */
html.has-milk .curtain-mark {
  position: relative; /* above the canvas */
  opacity: 0;
  transform: scale(1.35);
  filter: blur(8px);
  transition: opacity 0.45s ease, transform 1s var(--ease), filter 0.7s ease;
}
html.has-milk.milk-mark .curtain-mark { opacity: 1; transform: scale(1); filter: blur(0); }
html.has-milk.milk-mark-out .curtain-mark {
  opacity: 0;
  transform: scale(0.88);
  filter: blur(4px);
  transition: opacity 0.35s ease, transform 0.5s ease, filter 0.35s ease;
}

/* Hero video: an imperceptible filter keeps the browser from moving the playing video onto a
   separate hardware overlay (Chrome on Windows does this), which would hide the WebGL milk
   transition drawn on top of it. */
video.bg-media { filter: brightness(0.999); }

/* ---------- Logo ---------- */
/* White logo in the header (top-left) */
.logo { display: block; }
.logo-img {
  display: block;
  height: calc(var(--s-1) * 7); /* 56px */
  width: auto;
}
@media (max-width: 640px) {
  .logo-img { height: var(--s-5); } /* 40px */
}
/* Black logo on the pink milk during transitions */
.curtain-mark img {
  display: block;
  width: clamp(112px, 12vw, 184px);
  height: auto;
}

/* Work thumbnails: entrance zoom — each picture starts 25% larger and settles as its card
   comes into view (footer.js adds .is-in to the grid), one after another */
.work-media img { transform: scale(1.25); }
.is-ready .work-grid.is-in .work-media img {
  transform: none;
  transition: transform 1.8s var(--ease) var(--zoom-delay, 0s), opacity 0.6s ease, filter 0.6s ease;
}
.is-ready .work-grid.is-in .work-card:nth-child(2) .work-media img { --zoom-delay: 0.1s; }
.is-ready .work-grid.is-in .work-card:nth-child(3) .work-media img { --zoom-delay: 0.2s; }
.is-ready .work-grid.is-in .work-card:nth-child(4) .work-media img { --zoom-delay: 0.3s; }
/* hover keeps its gentle zoom, with no delay */
.is-ready .work-grid.is-in .work-card:hover .work-media img {
  --zoom-delay: 0s;
  transform: scale(1.04);
  transition-duration: 1.2s, 0.6s, 0.6s;
}

/* ---------- Header: centred logo, menu split left / right ---------- */
.header-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
}
.main-nav { display: contents; } /* the two groups sit directly in the header grid */
.nav-group { display: flex; gap: var(--s-4); }
.nav-left  { grid-column: 1; grid-row: 1; justify-self: start; }
.logo      { grid-column: 2; grid-row: 1; }
.nav-right { grid-column: 3; grid-row: 1; justify-self: end; }
.menu-toggle { grid-column: 3; grid-row: 1; justify-self: end; }

/* Phones: logo stays centred, "Menu" on the right opens a full-screen menu with both groups */
@media (max-width: 640px) {
  .main-nav {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--s-3);
  }
  .nav-group {
    flex-direction: column;
    gap: var(--s-3);
  }
}

/* Footer: copyright and city at half opacity; "Back to top" stays fully visible */
.footer-inner > span { opacity: 0.5; }

/* ---------- Homepage: "spilled milk" switch between films (milk-scroll.js) ----------
   While milk-scroll.js runs (html.has-milk-scroll) it draws the switch itself, so the CSS crossfade is off.
   The hero text stays put at the bottom of the screen instead of scrolling away with its section:
   the old text fades out in place, the new one comes in as the milk wave uncovers its film. */
.milk-scroll-canvas { position: absolute; inset: 0; z-index: 4; width: 100%; height: 100%; opacity: 0; pointer-events: none; }
html.milk-scrolling .milk-scroll-canvas { opacity: 1; }
html.has-milk-scroll .bg-media { transition: none; }
html.has-milk-scroll .bg-shade { z-index: 3; }
/* during the switch: the old film stays underneath, the new one sits on top behind a moving mask */
html.has-milk-scroll .bg-media.milk-from { opacity: 1; transform: scale(var(--crop, 1)); z-index: 1; }
html.has-milk-scroll .bg-media.milk-to { z-index: 2; }

html.has-milk-scroll .case > .container { position: fixed; left: 0; right: 0; bottom: var(--page-padding); pointer-events: none; }
html.has-milk-scroll .case.is-active > .container { pointer-events: auto; }
@media (max-width: 1024px) { html.has-milk-scroll .case > .container { bottom: calc(var(--page-padding) + var(--s-8)); } }

/* leaving: fade out in place (0.6s), then drop back to the start position unseen */
html.has-milk-scroll .case-content > * { transition: opacity 0.6s var(--ease), transform 0s linear 0.6s; }
html.has-milk-scroll .case-content > .case-cta {
  transition: opacity 0.6s var(--ease), transform 0s linear 0.6s,
    color 0.3s ease, background-color 0.3s ease, background-size 0.4s var(--ease);
}
/* coming in: rise and fade in, timed to the 1.1s milk wave */
html.has-milk-scroll .case.is-active .case-content > * { transition: opacity 1.1s var(--ease), transform 1.1s var(--ease); }
html.has-milk-scroll .case.is-active .case-content > .case-cta {
  transition: opacity 1.1s var(--ease), transform 1.1s var(--ease),
    color 0.3s ease, background-color 0.3s ease, background-size 0.4s var(--ease);
}
html.has-milk-scroll .case.is-active .case-content > *:nth-child(1) { transition-delay: 0.4s, 0.4s; }
html.has-milk-scroll .case.is-active .case-content > *:nth-child(2) { transition-delay: 0.5s, 0.5s; }
html.has-milk-scroll .case.is-active .case-content > *:nth-child(3) { transition-delay: 0.6s, 0.6s; }
html.has-milk-scroll .case.is-active .case-content > *:nth-child(4) { transition-delay: 0.7s, 0.7s, 0s, 0s, 0s; }

/* ---------- Film page (billie.html) ---------- */
/* Built from the pieces the other pages use: centred head (Work), full-bleed photo with zoom +
   parallax (In Development), label column + lead text (director teaser), hairline rows (shot list). */
.film {
  padding-top: calc(var(--header-h) + var(--s-4));
  padding-bottom: var(--s-12);
}
.film-title {
  grid-column: 1 / -1;
  margin: 0;
  font-size: clamp(56px, 9vw, 136px);
  font-weight: 300;
  line-height: 0.95;
  letter-spacing: -0.03em;
}
.film-credit {
  grid-column: 1 / -1;
  margin: var(--s-3) 0 0;
  font-size: var(--text);
  color: var(--color-text-muted);
}

/* the hero still uses .dev-photo (rounded, full width inside the frame); stills here sit a bit higher */
/* the hero still shows the whole frame (both faces and the eggs): the box has the film's 2:1 shape
   and the zoom stays small (see billie.html) */
.film .dev-photo { height: auto; aspect-ratio: 2 / 1; }
.film .dev-photo img { object-position: 50% 50%; filter: brightness(0.92); }

/* sections: label in the first 3 columns, content in the rest */
.film-section { row-gap: var(--s-3); margin-top: var(--s-12); }
.film-section > .eyebrow { grid-column: 1 / span 3; margin: 0; padding-top: 0.5em; }
.film-body { grid-column: 4 / -1; }
.film-lead {
  margin: 0;
  font-size: clamp(24px, 2.4vw, 36px);
  font-weight: 300;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

/* awards & screenings: hairline rows like the shot list */
.film-rows { list-style: none; margin: 0; padding: 0; border-top: 1px solid rgba(255, 255, 255, 0.15); }
.film-rows li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: var(--gutter);
  padding: var(--s-2) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  font-size: var(--text);
}
.film-rows span:last-child { color: var(--color-text-muted); }
.film-note { margin: var(--s-3) 0 0; font-size: var(--text-sm); line-height: 1.6; color: var(--color-text-muted); max-width: 70ch; }
.film-laurels { display: flex; flex-wrap: wrap; gap: var(--s-4); margin-top: var(--s-5); }
.film-laurels img { width: 136px; height: auto; filter: invert(1); opacity: 0.55; }

/* stills + behind the scenes */
.film-gallery { row-gap: var(--gutter); margin-top: var(--s-12); }
.film-shot {
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius);
  clip-path: inset(0 round var(--radius));
  background: #1a1a1a;
}
.film-shot img { display: block; width: 100%; height: 100%; object-fit: cover; transform: scale(1.12); will-change: transform; }
.film-shot.is-wide { grid-column: 1 / -1; aspect-ratio: 2 / 1; }
.film-shot.is-half { grid-column: span 6; aspect-ratio: 3 / 2; }
.film-caption { grid-column: 1 / -1; margin: 0; font-size: var(--text-sm); color: var(--color-text-muted); }

/* cast & crew: role (small caps) over name */
.film-credits {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-4);
  margin: 0;
}
.film-credits div { margin: 0; }
.film-credits dt {
  margin: 0 0 var(--s-1);
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.film-credits dd { margin: 0; font-size: var(--text); }
.film-credits + .film-credits { margin-top: var(--s-8); padding-top: var(--s-5); border-top: 1px solid rgba(255, 255, 255, 0.15); }


@media (max-width: 1024px) {
  .film-section > .eyebrow, .film-body { grid-column: 1 / -1; }
  .film-credits { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .film-shot.is-half { grid-column: 1 / -1; }
  .film-rows li { grid-template-columns: 1fr; row-gap: var(--s-1); }
  .film-credits { grid-template-columns: 1fr; }
}

/* Previous / next film switcher at the bottom of a film page (hairlines like the shot list) */
.film-pager {
  align-items: center;
  row-gap: var(--s-4);
  margin-top: var(--s-12);
  padding-top: var(--s-5);
  border-top: 1px solid rgba(255, 255, 255, 0.15);
}
.film-pager-link {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  color: var(--color-text);
  text-decoration: none;
}
.film-pager-link.is-prev { grid-column: 1 / span 4; }
.film-pager-link.is-next { grid-column: 9 / -1; align-items: flex-end; text-align: right; }
.film-pager-all { grid-column: 5 / span 4; justify-self: center; }
.film-pager-all .case-cta { margin-top: 0; }
.film-pager-label {
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.film-pager-title {
  font-size: clamp(24px, 2.4vw, 36px);
  font-weight: 300;
  line-height: 1.2;
  letter-spacing: -0.01em;
  transition: color 0.3s ease, transform 0.4s var(--ease);
}
.film-pager-num {
  margin-right: var(--s-2);
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--color-accent);
  vertical-align: 0.6em;
}
a.film-pager-link:hover .film-pager-title { color: var(--color-accent); }
a.film-pager-link.is-prev:hover .film-pager-title { transform: translateX(calc(var(--s-1) * -1)); }
a.film-pager-link.is-next:hover .film-pager-title { transform: translateX(var(--s-1)); }
/* not live yet: shown, but dimmed and not clickable */
.film-pager-link.is-disabled { cursor: default; }
.is-ready .film-pager.is-in .film-pager-link.is-disabled { opacity: 0.35; } /* beats the reveal's opacity: 1 */

@media (max-width: 1024px) {
  .film-pager-link.is-prev { grid-column: 1 / span 6; }
  .film-pager-link.is-next { grid-column: 7 / -1; }
  .film-pager-all { grid-column: 1 / -1; grid-row: 2; }
}

/* In Development, phones: a tall crop of the wide group photo cuts the faces at the sides */
@media (max-width: 640px) { .page-dev .dev-photo { height: auto; aspect-ratio: 4 / 3; } }

/* "Latest film" tag: small pink dot + label (homepage film label, Work thumbnail) */
.latest-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-accent);
}
.latest-tag::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.case-meta .latest-tag { margin-left: var(--s-2); }
.work-latest {
  position: absolute;
  top: var(--s-3);
  left: var(--s-3);
  z-index: 1;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}
/* the dot blinks softly, like a camera's REC light */
.latest-tag::before { animation: rec-blink 1.6s ease-in-out infinite; }
@keyframes rec-blink {
  0%, 45% { opacity: 1; }
  60%, 85% { opacity: 0.2; }
  100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .latest-tag::before { animation: none; } }

/* Film page whose stills are 16:9 (short-stay.html): frames match, so nothing is cut off */
.film-169 .dev-photo,
.film-169 .film-shot.is-wide,
.film-169 .film-shot.is-half { aspect-ratio: 16 / 9; }
/* Fine As I'll Ever Be was shot on film in a squarer frame: keep the faces (upper third) in the 2:1 hero */
.film-faieb .dev-photo img { object-position: 50% 30%; }

/* ---------- About page (about.html) ----------
   Film-page layout; instead of the hero still, a full-width mosaic of dimmed stills from the films
   with Safi's portrait sharp in the middle. */
.about-mosaic {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 var(--frame);
  height: clamp(560px, 92vh, 960px);
  overflow: hidden;
  border-radius: var(--radius);
  clip-path: inset(0 round var(--radius));
  background: #0f0f0f;
}
.about-mosaic-tiles {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  grid-template-rows: repeat(4, minmax(0, 1fr));
  gap: 4px;
  transform: scale(1.12);
  will-change: transform;
}
.about-mosaic-tiles img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.4) saturate(0.7);  /* dimmed, so the portrait leads */
}
.about-mosaic-tiles .is-big { grid-column: span 2; grid-row: span 2; }
.about-mosaic-photo {
  position: relative;
  z-index: 1;
  margin: 0;
  height: 78%;
  aspect-ratio: 594 / 786;               /* the portrait's own format (thin light strip at the top trimmed) */
  overflow: hidden;
  border-radius: var(--radius);
  box-shadow: 0 var(--s-4) var(--s-10) rgba(0, 0, 0, 0.6);
}
.about-mosaic-photo img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 100%; }
.about-mosaic-credit {
  position: absolute;
  left: var(--s-3);
  bottom: var(--s-3);
  z-index: 1;
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.about-row-link { color: inherit; text-decoration: none; transition: color 0.3s ease; }
.about-row-link:hover { color: var(--color-accent); }

@media (max-width: 640px) {
  .about-mosaic { height: auto; aspect-ratio: 3 / 4; }
  .about-mosaic-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .about-mosaic-tiles .is-big { grid-column: span 1; grid-row: span 1; }
  .about-mosaic-photo { height: 66%; }
}

/* the lead is the same size as a film page's synopsis (.about-body p would otherwise shrink it to body text) */
.about-body .film-lead {
  max-width: none;
  margin: 0 0 var(--s-5);
  font-size: clamp(24px, 2.4vw, 36px);
  font-weight: 300;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--color-text);
}
/* body copy under the lead: muted, regular weight, comfortable line length */
.about-body p {
  margin: 0 0 var(--s-3);
  max-width: 64ch;
  font-size: var(--text);
  font-weight: 400;
  line-height: 1.6;
  color: var(--color-text-muted);
}
/* film titles inside body copy: set in white rather than italic */
.about-body em { font-style: normal; font-weight: 400; color: var(--color-text); }
.film-body.about-body p:last-child { margin-bottom: 0; }

/* About: the two paragraphs under the lead sit side by side on wider screens */
@media (min-width: 1025px) {
  .about-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gutter); }
  .film-body.about-body .about-cols p { margin: 0; }
}

/* mosaic tiles get the same rounded corners as every other picture */
.about-mosaic-tiles img { border-radius: var(--radius); }

/* Mosaic load-in, once the page is shown (.is-ready, so it doesn't play under the milk):
   the stills come on one by one in a random order (delays from about.html), already dimmed,
   each settling in from slightly larger; the portrait rises in last. */
.about-mosaic-tiles img,
.about-mosaic-photo { opacity: 0; }
html.is-ready .about-mosaic-tiles img { animation: mosaic-flash 1.4s var(--ease) var(--d, 0ms) both; }
html.is-ready .about-mosaic-photo { animation: mosaic-photo 1.2s var(--ease) var(--photo-d, 1200ms) both; }
@keyframes mosaic-flash {
  from { opacity: 0; transform: scale(1.08); }
  to   { opacity: 1; transform: none; }
}
@keyframes mosaic-photo {
  from { opacity: 0; transform: translateY(var(--s-4)) scale(0.96); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .about-mosaic-tiles img, .about-mosaic-photo { opacity: 1; }
  html.is-ready .about-mosaic-tiles img, html.is-ready .about-mosaic-photo { animation: none; }
}

/* For screen readers and search engines only (the homepage <h1>) */
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
