/* ==========================================================================
   Tokens
   ========================================================================== */
:root {
  --bg: #0b0b0b;           /* soft black, matched to Danny Gevirtz */
  --surface: #161616;
  --text: #efe4cf;         /* warm cream, the P mark's colour (was #fff until 3 Nov 2026) */
  --text-muted: #b3ab9c;   /* warm grey to match the cream; 8.6:1 on --bg (was #a3a3a3) */
  --line: #363636;
  --overlay: rgba(0, 0, 0, 0.55);

  --font: "Poppins", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;

  --gutter: clamp(16px, 3vw, 60px);
  --header-h: 128px;   /* roomier top strip, closer to Danny Gevirtz's */
  --grid-gap: 0px;

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 180ms;
  --dur: 320ms;
  --dur-slow: 600ms;

  --z-header: 10;
  --z-modal: 100;

  --pm-ink: #efe4cf;   /* the P mark's warm cream */
  --pm-hal: #ff7a3c;   /* its film halation */
}

/* ==========================================================================
   P mark — Ethan's small logo: a slanted P with a dot tucked under its bowl ("the little things"),
   warm cream with film bloom and halation. Used by the intro and the cursor; size it with font-size
   ========================================================================== */
.pmark {
  position: relative;
  display: inline-block;
  width: 0.68em;   /* E and P share this box, so they line up exactly in the intro */
  font-weight: 600;
  line-height: 1;
  text-align: center;
  color: var(--pm-ink);
  filter: blur(0.35px);
  text-shadow:
    0 0 0.04em color-mix(in srgb, var(--pm-ink) 80%, transparent),
    0 0 0.16em color-mix(in srgb, var(--pm-hal) 50%, transparent),
    0 0 0.55em color-mix(in srgb, var(--pm-ink) 28%, transparent),
    0 0 1em color-mix(in srgb, var(--pm-hal) 10%, transparent);
}
.pmark__l { display: inline-block; transform: skewX(-14deg); }
.pmark__dot {
  position: absolute;
  left: 50%;
  top: 71%;
  width: 0.15em;
  height: 0.15em;
  border-radius: 50%;
  background: var(--pm-ink);
  transform: translate(-50%, -50%);
  box-shadow:
    0 0 0.05em color-mix(in srgb, var(--pm-ink) 80%, transparent),
    0 0 0.16em color-mix(in srgb, var(--pm-hal) 50%, transparent),
    0 0 0.4em color-mix(in srgb, var(--pm-ink) 28%, transparent);
}

/* Intro (after Coda Filmworks): on arriving at the site, E and P glide into each other, the E melts into
   the P, a beat later the dot drops in, it holds, and the page appears. 2.3 s; once per visit (inline
   script in each page); a click or key skips it */
.intro {
  position: fixed;
  inset: 0;
  z-index: 200;
  overflow: hidden;
  background: var(--bg);
}
.intro .pmark {
  position: absolute;
  left: 50%;
  top: 50%;
  font-size: 37px;
  transform: translate(-50%, -50%);
  opacity: 0;
}
.intro__p .pmark__dot { opacity: 0; }
html.intro-done .intro { display: none; }

/* Timeline: 0–11% fade up as "EP" · 11–46% glide together, the E melting · 40–58% the P's glow swells
   and settles · 58–70% the dot drops in · 70–87% hold · 87–100% fade out to the page */
.intro.is-playing { animation: intro-out 2.3s ease forwards; }
.intro.is-playing .intro__e { animation: intro-e 2.3s cubic-bezier(0.65, 0, 0.35, 1) forwards; }
.intro.is-playing .intro__p { animation: intro-p 2.3s cubic-bezier(0.65, 0, 0.35, 1) forwards; }
.intro.is-playing .pmark__dot { animation: intro-dot 2.3s forwards; }
@keyframes intro-out { 0%, 87% { opacity: 1; } 100% { opacity: 0; } }
@keyframes intro-e {
  0%   { translate: -0.36em 0; opacity: 0; filter: blur(0.35px); }
  11%  { translate: -0.36em 0; opacity: 1; filter: blur(0.35px); }
  30%  { opacity: 0.8; }
  40%  { opacity: 0.35; filter: blur(1.5px); }
  46%  { translate: 0 0; opacity: 0; filter: blur(3px); }
  100% { translate: 0 0; opacity: 0; }
}
@keyframes intro-p {
  0%   { translate: 0.36em 0; opacity: 0; filter: blur(0.35px) brightness(1); }
  11%  { translate: 0.36em 0; opacity: 1; }
  40%  { filter: blur(0.35px) brightness(1); }
  46%  { translate: 0 0; filter: blur(0.6px) brightness(1.06); }   /* the glow swells; kept low so the cream never clips to white */
  58%  { filter: blur(0.35px) brightness(1); }
  100% { translate: 0 0; opacity: 1; filter: blur(0.35px) brightness(1); }
}
@keyframes intro-dot {
  0%, 58% { opacity: 0; transform: translate(-50%, -150%) scale(0.6); }
  66%     { opacity: 1; transform: translate(-50%, -42%) scale(1); animation-timing-function: ease-out; }
  70%     { transform: translate(-50%, -50%) scale(1); }
  100%    { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
/* Reduced motion: no glide, just the finished P for a moment */
@media (prefers-reduced-motion: reduce) {
  .intro.is-playing { animation: intro-still 0.9s ease forwards; }
  .intro.is-playing .intro__e { animation: none; opacity: 0; }
  .intro.is-playing .intro__p,
  .intro.is-playing .pmark__dot { animation: none; opacity: 1; }
}
@keyframes intro-still { 0%, 66% { opacity: 1; } 100% { opacity: 0; } }

/* Cursor (after Coda Filmworks): the P mark follows the mouse in place of the arrow ("Cursor" in main.js).
   Mouse only; text fields and embedded players keep the normal cursor */
.cursor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 300;
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms;
  will-change: transform;
  transform-origin: calc(0.18 * 22px) calc(0.15 * 22px);   /* leans around its tip */
}
.cursor.is-on { opacity: 1; }
.cursor.is-on.is-menu { opacity: 0; transition-duration: 0s; }   /* near the menu (the menu zone) it vanishes at once, so a quick swipe never catches it mid-fade; it fades back in on leaving */
.cursor .pmark {
  display: block;
  font-size: 22px;
  transform-origin: 0.18em 0.15em;   /* the tip (as in main.js), so it presses in place */
  transition: filter 200ms, transform 260ms cubic-bezier(0.34, 1.56, 0.64, 1);   /* springs back on release */
}
.cursor.is-hot .pmark { filter: blur(0.5px) brightness(1.06); }   /* over a link or film: the glow swells a touch, staying cream */
.cursor.is-down .pmark { transform: scale(0.78); transition-duration: 200ms, 90ms; transition-timing-function: ease, ease-out; }   /* click: squashes in while held */
.cursor.is-film .pmark { transform: scale(1.25); }   /* over a film: just grows a little, keeping its own slant */
.cursor.is-film.is-down .pmark { transform: scale(0.98); }
@media (prefers-reduced-motion: reduce) { .cursor .pmark { transition: none; } }
html.has-cursor,
html.has-cursor * { cursor: none; }
html.has-cursor :is(input, textarea, select, iframe) { cursor: auto; }
/* A full-screen video sits above everything, the P included, so it gets the normal cursor back */
html.has-cursor :fullscreen,
html.has-cursor :fullscreen * { cursor: auto; }

/* The text glow's strength, animated by text-glow (on body) */
@property --glow { syntax: "<number>"; inherits: true; initial-value: 1; }
@keyframes text-glow { from { --glow: 0.7; } to { --glow: 1.3; } }
@media (prefers-reduced-motion: reduce) { html body { animation: none; } }   /* "html body" so it beats the body rule below */
/* Touch screens: the glow stays, but doesn't breathe. Animating it redraws all the text every frame, which left
   iPhones too little time to draw the films while scrolling fast (black blocks; 4 Nov 2026) */
@media (hover: none) { html body { animation: none; } }

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  /* A very slight film bloom and halation on all text, much softer than the P mark's. It breathes very
     gently (--glow between 0.7 and 1.3 over 5 s each way); held still with reduced motion */
  text-shadow: 0 0 0.12em color-mix(in srgb, var(--pm-hal) calc(14% * var(--glow)), transparent), 0 0 0.5em color-mix(in srgb, var(--pm-ink) calc(14% * var(--glow)), transparent);
  animation: text-glow 5s ease-in-out infinite alternate;
  font-family: var(--font);
  font-weight: 300;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* Light — one large, very soft, faint glow from the bottom-right corner on every page. It breathes slowly
   and its brightness follows the mouse (see the "Light" block in main.js) */
.ambient {
  position: fixed;
  inset: -8%;   /* larger than the screen so the drift never uncovers an edge */
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse 120% 110% at 100% 100%, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.014) 35%, rgba(255, 255, 255, 0.005) 65%, transparent 90%);
  transform-origin: 100% 100%;
  animation: ambient-breathe 12s ease-in-out infinite alternate;
  transition: opacity 1.2s var(--ease-out);
}
.ambient__grain {
  position: absolute;
  inset: 0;
  opacity: 0.05;
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 1.6 -0.35'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  -webkit-mask-image: radial-gradient(ellipse 120% 110% at 100% 100%, #000, transparent 90%);
          mask-image: radial-gradient(ellipse 120% 110% at 100% 100%, #000, transparent 90%);
}
@keyframes ambient-breathe {
  from { opacity: 0.75; transform: translate(0, 0) scale(1); }
  to   { opacity: 1; transform: translate(-3%, -2%) scale(1.08); }
}
/* Stage: holds the light, behind all content */
.light-stage {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;   /* set by main.js from the mouse's distance to the bottom-right corner */
  transition: opacity 3.5s cubic-bezier(0.25, 0.1, 0.25, 1);
}
.light-stage .ambient { position: absolute; z-index: auto; }
@media (hover: none) { .light-stage { display: none; } }


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

a { color: inherit; }

button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 3px;
}

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: -100px;
  background: var(--text);
  color: var(--bg);
  padding: 10px 16px;
  z-index: calc(var(--z-header) + 1);
  text-decoration: none;
  font-size: 13px;
}
.skip-link:focus { top: 12px; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ==========================================================================
   Header — nav left, wordmark centre, socials right
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  height: var(--header-h);
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
}
/* Clear at the top so the light reaches the menu; a soft fade once scrolled keeps it readable over films */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(var(--bg) 55%, transparent);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.site-header.is-scrolled::before { opacity: 1; }

.nav { display: flex; gap: 56px; }

/* Menu spaced like Morgan's (his items sit about 58px apart at about 19px; Ethan asked for it slightly bigger and
   further apart like his, 3 Nov 2026), regular weight, no extra letter spacing */
.nav a {
  font-size: 17px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: uppercase;
  text-decoration: none;
  padding: 12px 0;
  white-space: nowrap;   /* "2nd AC" stays on one line */
  color: var(--text-muted);
  background: linear-gradient(currentColor, currentColor) left calc(100% - 8px) / 0 1px no-repeat;
  transition: color var(--dur-fast), background-size var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out), text-shadow var(--dur) var(--ease-out), opacity var(--dur) var(--ease-out);
}
.nav a:hover { color: var(--text); background-size: 100% 1px; }
/* Hovered menu items lift a touch and give off a faint glow */
@media (hover: hover) {
  .nav a:hover, .nav a:focus-visible {
    transform: translateY(-2px);
    text-shadow: 0 0 10px color-mix(in srgb, var(--text) 35%, transparent);
  }
}
@media (prefers-reduced-motion: reduce) {
  .nav a:hover, .nav a:focus-visible { transform: none; }
}
.nav a[aria-current="page"] { color: var(--text); background-size: 100% 1px; }
/* Menu zone (main.js "Cursor"): with the mouse near the menu, the tab it would open is lit and the other two
   step back (Ethan's pick, look B), and their own hover is held off so only the lit tab looks lit */
.nav.is-caught a { opacity: 0.32; }
.nav.is-caught a.is-near {
  opacity: 1;
  color: var(--text);
  background-size: 100% 1px;
  text-shadow: 0 0 12px color-mix(in srgb, var(--text) 45%, transparent);
}
/* Pressed: the lit tab blooms for a moment (warm halation + a wider glow; kept cream, never clipped to white) */
.nav.is-caught a.is-near.is-pressed {
  text-shadow: 0 0 .1em color-mix(in srgb, var(--pm-hal) 45%, transparent),
               0 0 8px color-mix(in srgb, var(--text) 70%, transparent),
               0 0 22px color-mix(in srgb, var(--text) 45%, transparent);
  transition-duration: 120ms;
}
.nav.is-caught a:not(.is-near):hover { color: var(--text-muted); background-size: 0 1px; transform: none; text-shadow: none; }
.nav.is-caught a[aria-current="page"]:not(.is-near):hover { color: var(--text); background-size: 100% 1px; }

.wordmark {
  font-size: 28px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.5em;
  margin-right: -0.5em; /* offset trailing tracking so it centres optically */
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

/* Signature detail: one round letter leans forward */
.wordmark__slant {
  display: inline-block;
  transform: skewX(-14deg);
}

.socials {
  display: flex;
  justify-content: flex-end;
  gap: 4px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.socials a {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  opacity: 0.85;
  transition: opacity var(--dur-fast);
}
.socials a:hover { opacity: 1; }
.socials svg { width: 16px; height: 16px; fill: currentColor; }
/* TikTok and Instagram sit close together in the header (Ethan, 4 Nov 2026): their 44px tap areas overlap, so the
   icons are 30px apart, and Instagram stays where it was */
.site-header .socials li + li { margin-left: -18px; }
.footer-socials { display: none; }   /* phones only, see the phone header and menu rules */

/* The phone menu button (three-bar style, after Morgan): phones only, see "Phone menu" at the end */
.menu-toggle { display: none; }

/* ==========================================================================
   Work grid — edge-to-edge 16:9 boxes (Danny Gevirtz) with play cue (Morgan)
   ========================================================================== */
main { flex: 1; }

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

.tile {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9; /* every tile the same box, as on Danny Gevirtz's grid */
  padding: 0;
  border: 2px solid #000;   /* thin black frame, as on Danny Gevirtz's grid */
  background: var(--surface);
  overflow: hidden;
  cursor: pointer;
  text-decoration: none;
  opacity: 0;
  transform: translateY(12px);
  animation: tile-in var(--dur-slow) var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 50ms);
}

.tile img:not(.tile__logo) {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 900ms var(--ease-out), filter var(--dur) var(--ease-out);
}

/* Hover preview clip — sits over the still, already blurred and darkened,
   and fades in once it's actually playing */
.tile__preview {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.08);
  filter: var(--bw);   /* hover previews play in black and white */
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  pointer-events: none;
}
.tile.is-previewing .tile__preview { opacity: 1; }

/* Live tiles: clips loop sharp and in colour all the time, and turn black and white, blurred and darkened under the title on hover */
.tile--live .tile__preview {
  opacity: 1;   /* its poster (the clip's first frame) covers the still until the clip plays */
  transform: none;
  filter: grayscale(0);
  transition: opacity var(--dur) var(--ease-out), transform 900ms var(--ease-out), filter var(--dur) var(--ease-out);
}
/* ...so the still underneath is never needed: hide it, or tiles sitting on a fraction of a pixel (the Social page's
   bottom row) show a sliver of it, a different frame, along the clip's soft edges */
.tile--live:has(.tile__preview) img:not(.tile__logo) { visibility: hidden; }
/* Touch screens (iPhone, iPad): the clip's first frame shows underneath, and the clip appears only once it's really
   playing, with no filter on the video (filters on video are heavy for iPhone Safari while scrolling) */
@media (hover: none) {
  .tile--live:has(.tile__preview) img:not(.tile__logo) { visibility: visible; }
  .tile.tile--live .tile__preview { opacity: 0; filter: none; transition: none; }   /* ".tile" so it outranks .is-previewing */
  .tile.tile--live.is-shown .tile__preview { opacity: 1; }
}
.tile--live:hover .tile__preview,
.tile--live:focus-visible .tile__preview {
  transform: scale(1.08);
  filter: var(--bw);
}

.tile__badge {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 1;
  width: 18px;
  height: 18px;
  fill: var(--text);
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
  pointer-events: none;
}

/* Small logo in a tile's top-left corner (the 2nd AC films) */
.tile__logo {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 1;
  width: clamp(32px, 3vw, 46px);
  height: auto;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
  pointer-events: none;
}

.tile__views {
  position: absolute;
  top: 12px;
  right: 14px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}
.tile__views svg { width: 12px; height: 12px; fill: currentColor; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6)); }

.tile__info {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 16px;
  text-align: center;
  background: rgba(0, 0, 0, 0.2);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.tile__play {
  width: 0; height: 0;
  border-left: 22px solid var(--text);
  border-top: 13px solid transparent;
  border-bottom: 13px solid transparent;
  margin-bottom: 12px;
}

/* Titles echo the wordmark: bold capitals, spaced a little less widely than the logo */
.tile__title {
  font-size: clamp(16px, 1.3vw, 22px);
  font-weight: 600;
  letter-spacing: 0.3em;
  margin-right: -0.3em; /* offset trailing tracking so it stays centred */
  text-transform: uppercase;
}

.tile__meta {
  font-size: clamp(12px, 0.85vw, 15px);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #d4d4d4;
}

/* Hover look, shared by stills and clips: hard black and white, softened and darkened so the title reads
   clearly (the scale hides blurred edges) */
.tile { --bw: grayscale(1) contrast(1.1) brightness(0.5) blur(4px); }
/* Black and white, blurred and darkened still so the title reads clearly; the scale hides blurred edges */
.tile:hover img:not(.tile__logo),
.tile:focus-visible img:not(.tile__logo) {
  transform: scale(1.08);
  filter: var(--bw);
}
.tile:hover .tile__info,
.tile:focus-visible .tile__info { opacity: 1; }

/* Film grain over the black and white on hover (mouse/keyboard only — phones always show the title).
   Its own layer between the picture and the title, fading by itself: inside the fading title layer
   the blend can't reach the picture, so it flashed grey at the start of the hover. */
@media (hover: hover) {
  .tile::after {
    content: "";
    position: absolute;
    inset: -50%;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
    mix-blend-mode: hard-light;   /* unlike overlay, shows on dark films as well as bright ones */
    opacity: 0;
    transition: opacity var(--dur) var(--ease-out);
    pointer-events: none;
  }
  .tile:hover::after,
  .tile:focus-visible::after { opacity: 0.18; animation: grain 0.5s steps(1) infinite; }
  .tile__info { z-index: 1; }   /* title above the grain */
}
@keyframes grain {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-7%, 4%); }
  40%  { transform: translate(5%, -6%); }
  60%  { transform: translate(-4%, -3%); }
  80%  { transform: translate(6%, 5%); }
}
@media (prefers-reduced-motion: reduce) {
  .tile:hover::after,
  .tile:focus-visible::after { animation: none; }
}
.tile:focus-visible { outline-offset: -2px; }

@keyframes tile-in {
  to { opacity: 1; transform: none; }
}

/* ==========================================================================
   Footer — © left, slogan centred (Danny Gevirtz), email right
   ========================================================================== */
.site-footer {
  padding: 72px var(--gutter) 80px;   /* roomier bottom strip, closer to Danny Gevirtz's */
}
/* Social: four films per row */

.work-grid[data-work-grid="social"] { grid-template-columns: repeat(4, 1fr); }
/* 2nd AC: two smaller films side by side, centred with a small gap between (room for a logo later) */
.work-grid[data-work-grid="ac"] {
  grid-template-columns: repeat(2, minmax(0, 640px));
  justify-content: center;
  gap: 12px;
}
/* The AVT Media logo, centred just below the two 2nd AC films */
.ac-logo {
  display: block;
  width: clamp(72px, 6vw, 100px);
  height: auto;
  margin: 28px auto 0;
}
/* Films/Social/2nd AC: the footer follows straight after the films instead of being pushed to the bottom */
main:has(.work-grid) { flex: none; }
main:has(.work-grid) ~ .site-footer { padding-top: 56px; }

.footer-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  font-size: 12px;
  color: var(--text-muted);
}
.footer-row > :last-child { justify-self: end; }
.footer-row a { text-underline-offset: 3px; }

.slogan {
  margin: 0;
  font-size: 13px;
  font-weight: 300;
  color: var(--text);
  text-align: center;
}

.site-footer--compact { padding-top: 32px; }

/* ==========================================================================
   About — centred photo, bio, location, CTA (Morgan)
   ========================================================================== */
.about-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: clamp(24px, 6vh, 88px) var(--gutter) 0;
}

/* Sized as on Morgan's About page (measured from his screenshot at full size): a landscape picture 660 × 475,
   the bio the same width 158px below it, and about 206px before the email. The photo is cropped to that
   shape from his hair down to the camera. Ethan asked for the picture smaller (3 Nov 2026): 500px wide, same shape.
   Then (3 Nov 2026) Ethan had the bio moved to the top: bio, picture, email */
.portrait {
  width: min(500px, 100%);
  margin: clamp(40px, 8vh, 96px) 0 0;
  aspect-ratio: 660 / 475;
  border-radius: 16px;
  overflow: hidden;
  background: var(--surface);
}
.portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 66%; }

/* Small, fine text in a wide block with plenty of room around it, as on Morgan's */
.bio {
  max-width: 660px;
  margin: 0;
  font-size: 14px;
  font-weight: 300;
  line-height: 1.65;
  text-align: justify;   /* lines end in a straight edge on the right too */
  color: var(--text-muted);
}
.bio p { margin: 0; }
.bio p + p { margin-top: 1em; }
.bio strong { color: var(--text); font-weight: 500; }

.based {
  margin: clamp(32px, 7vh, 80px) 0 20px;
  font-size: clamp(28px, 3vw, 40px);
  font-weight: 300;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.btn--wide { justify-self: auto; min-width: 220px; text-decoration: none; text-align: center; }

/* ==========================================================================
   Contact — intro + email left, form right (Morgan)
   ========================================================================== */
.contact-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(40px, 8vw, 160px);
  align-items: start;
  max-width: 1100px;
  margin: 0 auto;
  padding: clamp(24px, 12vh, 140px) var(--gutter) 40px;
}

.contact-intro h1 {
  font-size: 13px;
  font-weight: 300;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 34ch;
  margin: 0 0 16px;
}

.email {
  display: inline-block;
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 300;
  text-decoration: none;
  margin-bottom: 8px;
  background: linear-gradient(currentColor, currentColor) left bottom / 0 1px no-repeat;
  transition: background-size var(--dur) var(--ease-out);
}
.email:hover { background-size: 100% 1px; }
.about-email { margin: clamp(48px, 10vh, 120px) 0 0; }

.contact-intro .socials { justify-content: flex-start; margin-left: -14px; }

/* Form */
.form { display: grid; gap: 24px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }

.field { display: grid; gap: 4px; }
.field label { font-size: 13px; font-weight: 400; }
.field label span { color: var(--text-muted); font-weight: 300; font-size: 12px; margin-left: 4px; }

.field input,
.field textarea {
  width: 100%;
  min-height: 44px;
  padding: 8px 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  color: var(--text);
  font: inherit;
  font-size: 16px;
  transition: border-color var(--dur-fast);
}
.field textarea { min-height: 110px; resize: vertical; }
.field input:focus,
.field textarea:focus { outline: none; border-bottom-color: var(--text); }
.field input:focus-visible,
.field textarea:focus-visible { box-shadow: 0 1px 0 var(--text); }

.field[data-invalid] input,
.field[data-invalid] textarea { border-bottom-color: #ff8a8a; }
.field-error { color: #ff8a8a; font-size: 12px; min-height: 0; }
.field-error:empty { display: none; }

.btn {
  justify-self: start;
  min-height: 44px;
  padding: 10px 28px;
  border: 1px solid var(--text);
  background: transparent;
  color: var(--text);
  font-size: 13px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background-color var(--dur-fast), color var(--dur-fast);
}
.btn:hover { background: var(--text); color: var(--bg); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.form-status { font-size: 13px; color: var(--text-muted); margin: 0; min-height: 1.6em; }

/* ==========================================================================
   Social — bold profile header above the grid: photo, name, follow buttons, TikTok numbers
   ========================================================================== */
.social-intro {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "avatar main stats";
  align-items: center;
  gap: clamp(20px, 3vw, 48px);
  margin: 0 var(--gutter) clamp(28px, 5vh, 48px);
  padding: clamp(8px, 2vh, 28px) 0 clamp(28px, 5vh, 48px);
  border-bottom: 1px solid var(--line);
}

.social-intro__avatar {
  grid-area: avatar;
  width: clamp(110px, 11vw, 168px);
  height: auto;
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
  background: var(--surface);
}
.social-intro__main { grid-area: main; min-width: 0; }
.social-intro__name {
  margin: 0;
  font-size: clamp(40px, 5.4vw, 84px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 0.95;
}
/* The name links to the TikTok profile (Ethan, 4 Nov 2026) */
.social-intro__name a { color: inherit; text-decoration: none; transition: opacity var(--dur-fast) var(--ease-out); }
.social-intro__name a:hover,
.social-intro__name a:focus-visible { opacity: 0.8; }
.social-intro__bio { margin: 12px 0 24px; font-size: 15px; color: var(--text-muted); }

.follow { display: flex; flex-wrap: wrap; gap: 28px; }
/* Colour logos, no box */
.follow__btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--text);
  text-decoration: none;
  opacity: 0.9;
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.follow__btn:hover,
.follow__btn:focus-visible { opacity: 1; transform: translateY(-1px); }
.follow__icon { width: 22px; height: 22px; flex: none; }
.follow__word--tiktok { font-size: 19px; font-weight: 600; letter-spacing: -0.03em; }
.follow__word--instagram { font-family: "Grand Hotel", cursive; font-size: 27px; line-height: 1; transform: translateY(2px); }

/* TikTok logo at the bottom of the Social page */
.tiktok-sign {
  display: flex;
  align-items: center;
  gap: 12px;
  width: max-content;
  margin: 72px auto 0;
  color: var(--text);
  text-decoration: none;
  opacity: 0.85;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.tiktok-sign:hover,
.tiktok-sign:focus-visible { opacity: 1; }
.tiktok-sign__icon { width: 38px; height: 38px; }
.tiktok-sign span { font-size: 40px; font-weight: 600; letter-spacing: -0.03em; line-height: 1; }

.social-stats { --stat-size: clamp(34px, 3.8vw, 60px); grid-area: stats; display: flex; margin: 0; }
.social-stats div { display: flex; flex-direction: column-reverse; justify-content: flex-end; gap: 8px; padding: 0 clamp(18px, 2.2vw, 36px); } /* numbers line up even when a label wraps */
.social-stats div + div { border-left: 1px solid var(--line); }
/* the last number's final letter has built-in space on its right — pull it out so the M ends on the line's edge */
.social-stats div:last-child { padding-right: 0; margin-right: calc(var(--stat-size) * -0.035); }
.social-stats dd {
  margin: 0;
  font-size: var(--stat-size);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  margin-left: -0.045em; /* pull the big digits' built-in side spacing back so they line up with the label */
}
/* Poppins' digits stand about 4.5% taller than its capitals, so the K and M are sized up to meet the digits' tops
   (same baseline; line-height 0 so the bigger letter doesn't grow the line) */
.social-stats .unit { font-size: 1.045em; line-height: 0; }
.social-stats dt { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); white-space: nowrap; }

/* Social: the heading on the left and the TikTok logo on the far right, on one line just under the profile's
   divider (Ethan, 4 Nov 2026: computers and tablets; the TikTok and Instagram links under the name are hidden there) */
.grid-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: 0 var(--gutter) 12px;
}
.grid-head .grid-heading { margin: 0; }
.grid-head__tiktok { margin-right: -2px; }
@media (min-width: 768px) {
  .social-intro .follow { display: none; }
}

.grid-heading {
  margin: 0 var(--gutter) 16px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ==========================================================================
   Film page — laid out after Serr: centred title and small credit lines,
   a large centred player, then the stills two across
   ========================================================================== */
.film {
  --player-w: min(800px, 100%);   /* the player, Serr's size (his measures 800px); also kept short enough to fit the window */
  --film-w: min(760px, 100%);     /* each still, Serr's size (his measure about 760px) */
  --stills-gap: 86px;            /* Serr's gap between stills, across and down */
  padding: clamp(24px, 5vh, 56px) var(--gutter) 24px;
}

.film__head {
  max-width: 640px;
  margin: 0 auto clamp(24px, 4vh, 36px);
  text-align: center;
}

.film__title {
  margin: 0 0 12px;
  font-size: clamp(17px, 1.5vw, 20px);
  font-weight: 600;
  letter-spacing: 0.2em;
  line-height: 1.4;
  text-transform: uppercase;
}
/* Serr's small lines under the title: the film type, then one line per credit */
.film__kind {
  display: block;
  margin-top: 12px;
  font-size: 12px;
  font-weight: 300;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--text-muted);
}

/* Each credit (the parts of a line between " · ") stays whole, so on narrow screens a line only breaks between credits */
.film__credit { white-space: nowrap; }
.film__credits p {
  margin: 0;
  font-size: 12px;
  font-weight: 300;
  line-height: 2.1;
  color: var(--text-muted);
}

.film__about {
  margin: 18px 0 0;
  font-size: 14px;
  line-height: 1.7;
  color: #d4d4d4;
}

.film__player {
  position: relative;
  width: min(var(--player-w), calc((100dvh - var(--header-h) - 48px) * var(--ar)));
  aspect-ratio: var(--ar);
  margin: 0 auto;
  background: var(--surface);
}
.film__player iframe,
.film__player video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #000; }
/* Click-to-play poster for YouTube/Vimeo films */
.film__poster {
  position: absolute;
  inset: 0;
  padding: 0;
  border: 0;
  background: #000;
  cursor: pointer;
}
.film__poster img { width: 100%; height: 100%; object-fit: cover; transition: filter var(--dur) var(--ease-out); }
.film__play {
  position: absolute;
  left: clamp(12px, 3%, 24px);
  bottom: clamp(12px, 4%, 24px);
  width: 60px;
  height: 60px; /* bottom-left so it never covers the middle of the frame (e.g. festival laurels) */
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid color-mix(in srgb, var(--text) 70%, transparent);
  backdrop-filter: blur(4px);
  transition: transform var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out);
}
.film__play::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -10px 0 0 -6px;
  border-left: 18px solid var(--text);
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
}
.film__poster:hover img { filter: brightness(0.85); }
.film__poster:hover .film__play { transform: scale(1.06); background: rgba(0, 0, 0, 0.6); }
.film__poster:focus-visible { outline-offset: -4px; }

/* The box already matches the film's shape, so cover only affects the poster (no bars before play) */
.film__player video { object-fit: cover; }

/* Two across with a wide gap; an odd last still sits centred on its own row */
.film__stills {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: var(--stills-gap);
  width: min(calc(var(--film-w) * 2 + var(--stills-gap)), 100%);
  margin: clamp(56px, 11vh, 120px) auto 0;
}
.film__stills img {
  width: calc(50% - var(--stills-gap) / 2);
  height: auto;
  aspect-ratio: 3 / 2; /* reserved until the still loads, then set to its real shape */
  background: var(--surface);
}

/* A note at the bottom of a film page, under the stills (the "note" field in projects.js, e.g. 855-FOR-TRUTH's
   camera operator and rights line): small grey text like the credits, the highlighted words in full cream */
.film__note {
  max-width: 640px;
  margin: clamp(56px, 9vh, 96px) auto 0;
  font-size: 13px;
  font-weight: 300;
  line-height: 1.8;
  text-align: center;
  color: var(--text-muted);
}
.film__note strong { color: var(--text); font-weight: 500; }

.film__nav {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  width: min(calc(var(--film-w) * 2 + var(--stills-gap)), 100%);
  margin: clamp(40px, 7vh, 72px) auto 0;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.film__nav a {
  color: var(--text-muted);
  text-decoration: none;
  padding: 12px 0;
  transition: color var(--dur-fast);
}
.film__nav a:hover { color: var(--text); }

.film__missing { text-align: center; color: var(--text-muted); padding: 80px 0; }

/* Stills fade in one after another where they sit, as they come into view (main.js) */
.film__stills img.will-fade {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 600ms ease-out, transform 800ms var(--ease-out);
}
.film__stills img.will-fade.is-in { opacity: 1; transform: none; }

/* Back to top — round button, bottom right (Danny Gevirtz) */
.to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: var(--z-header);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: #2a2a2a;
  color: var(--text);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out), background-color var(--dur-fast);
}
.to-top.is-visible { opacity: 1; pointer-events: auto; transform: none; }
.to-top:hover { background: #3a3a3a; }
.to-top svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.6; }
/* keep the footer email clear of the button, without shifting the centred slogan */
body:has(.to-top) .footer-row > :last-child { margin-right: 56px; }

/* ==========================================================================
   Responsive
   ========================================================================== */
/* Laptops: Danny's 19px menu only fits beside the wordmark from ~1300px, so step it down a little below that */
@media (max-width: 1299px) {
  .nav { gap: 48px; }
  .nav a { font-size: 16px; }
}
/* Small laptops: tighten a little more so the one-row header fits down to 1024px */
@media (max-width: 1199px) {
  .wordmark { font-size: 22px; letter-spacing: 0.42em; margin-right: -0.42em; }
  .nav { gap: 40px; }
  .nav a { font-size: 15px; }
}

@media (max-width: 1023px) {
  /* Tablets: wordmark and socials on top, the menu on its own row below, so they can't run into each other */
  .site-header {
    height: auto;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "mark socials"
      "nav  nav";
    padding-top: 28px;
    padding-bottom: 12px;
  }
  .wordmark { grid-area: mark; margin-right: 0; }
  .socials { grid-area: socials; margin-right: -12px; }
  .nav { grid-area: nav; gap: 56px; }
  .nav a { font-size: 17px; }   /* the menu has its own row here, so the full size fits */

  .work-grid,
  .work-grid[data-work-grid="social"] { grid-template-columns: repeat(2, 1fr); }
  .social-intro {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "avatar main" "stats stats";
  }
  .social-stats div:first-child { padding-left: 0; }
  .contact-page { grid-template-columns: 1fr; gap: 48px; padding-top: 24px; }
}

@media (max-width: 767px) {
  :root { --header-h: auto; }
  .film { --stills-gap: 16px; }
  /* Film page credits on phones (Ethan, 4 Nov 2026): a clear gap after the film type, and one before the kit line */
  .film__kind { margin-bottom: 28px; }   /* was 18px; Ethan asked for a bit more */
  .film__credits .film__kit { margin-top: 18px; }
  .film__credit { display: block; }   /* one credit per line, like the computer version (Ethan, 4 Nov 2026) */
  .film__dot { display: none; }
  .film__stills img { width: 100%; }
  .film__stills { margin-top: 32px; }   /* closer to the video on phones (was about 90px; Ethan, 4 Nov 2026) */


  .social-intro {
    grid-template-areas: "avatar name" "follow follow" "stats stats";   /* no line under the name (the slogan is only in the footer) */
    column-gap: 18px;
    row-gap: 0;
  }
  .social-intro__main { display: contents; }
  .social-intro__avatar { width: 92px; }
  .social-intro__name { grid-area: name; align-self: center; font-size: clamp(28px, 8.8vw, 40px); }   /* "@ethan.peck" fits beside the photo */
  .social-intro__bio { grid-area: bio; align-self: start; margin: 8px 0 0; font-size: 14px; }
  /* Phones: just the TikTok logo, centred (Ethan, 4 Nov 2026; Instagram is in the menu) */
  .follow { grid-area: follow; display: flex; justify-content: center; margin-top: 14px; }   /* the TikTok logo sits halfway between "ethan.peck" and the numbers */
  .follow__btn { justify-content: center; }
  .follow__btn:has(.follow__word--instagram) { display: none; }
  .follow__btn { gap: 12px; }
  .follow .follow__icon { width: 32px; height: 32px; }   /* bigger TikTok logo on phones (Ethan, 4 Nov 2026; was 22px / 19px) */
  .follow .follow__word--tiktok { font-size: 27px; }
  .grid-head { justify-content: center; margin-bottom: 16px; }
  .grid-heading { text-align: center; }   /* centred above the full-width films */
  .grid-head__tiktok { display: none; }   /* phones keep the TikTok logo under the name */
  .social-stats { margin-top: 38px; }
  .social-stats div { flex: 1 1 auto; padding: 0 10px; }
  .social-stats { --stat-size: clamp(26px, 8vw, 34px); }
  .social-stats dt { font-size: 9px; letter-spacing: 0.08em; }


  .work-grid,
  .work-grid[data-work-grid="social"],
  .work-grid[data-work-grid="ac"] { grid-template-columns: 1fr; }

  .form-row { grid-template-columns: 1fr; }
  /* Phone footer, after Danny Gevirtz's iPhone site (Ethan's screenshots FILM PAGE REFERNCES/IMG_1958-1959,
     4 Nov 2026): just the slogan, small, light and grey, centred below the films. The ©, the email and the
     back-to-top button are left off on phones (the email is on the About page) */
  .site-footer,
  main:has(.work-grid) ~ .site-footer,
  .site-footer--compact { padding-top: 48px; padding-bottom: 56px; }
  .footer-row { grid-template-columns: 1fr; justify-items: center; }
  .footer-row > :not(.slogan) { display: none; }
  .slogan { font-size: 11px; font-weight: 300; color: var(--text-muted); letter-spacing: 0.01em; }   /* smaller on phones (Ethan, 4 Nov 2026; was 14px) */
  .to-top { display: none; }

  /* Films and Social: each film the full width of the phone, edge to edge, with only a thin dark line between
     them (Danny's iPhone grid) */
  .work-grid { padding: 0; }
  .work-grid .tile { border-width: 2px 0; }
  .work-grid li[data-slug="fast-lane"] { order: -1; }   /* Films on phones: Fast Lane first (Ethan, 4 Nov 2026) */
  .work-grid .tile__info { display: none; }   /* just the pictures, no titles, like Danny's (Ethan, 4 Nov 2026) */
  /* ...but the Social films keep their TikTok icon and view count (Ethan asked for them back, 4 Nov 2026) */

  /* The About bio is much smaller on phones (Ethan, 4 Nov 2026); 14px from tablets up */
  .bio { font-size: 11px; }
}

@media (prefers-reduced-motion: reduce) {
  .ambient { animation: none !important; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    transition-duration: 1ms !important;
  }
}

/* ==========================================================================
   In-place page switches (main.js "In-place pages"): the content fades out quickly, is swapped, and the new
   content fades in; the header, light and cursor stay put. Ethan's pick, the quick fade
   ========================================================================== */
main:focus { outline: none; }   /* focused after a switch so keyboard visitors carry on from the new content */
main, .site-footer { transition: opacity 0.3s ease; }   /* the back-to-top button keeps its own fade */
html.is-leaving main, html.is-leaving .to-top, html.is-leaving .site-footer { opacity: 0; transition-duration: 0.15s; }
html.is-arriving main, html.is-arriving .site-footer { opacity: 0; transition: none; }
/* Touch screens: the page being left goes at once rather than fading, so it doesn't flash before the new one (Ethan, 4 Nov 2026) */
@media (hover: none) {
  html.is-leaving main, html.is-leaving .to-top, html.is-leaving .site-footer { transition: none; }
}
@media (prefers-reduced-motion: reduce) {
  main, .site-footer { transition: none; }
}

/* Touch screens (phones and iPads) have no hover, so the title and type always sit along the bottom of
   each tile. iPads used to show bare pictures with no names (fixed 4 Nov 2026). */
@media (max-width: 767px), (hover: none) {
  .tile__info { opacity: 1; background: linear-gradient(transparent 45%, rgba(0,0,0,0.8)); justify-content: flex-end; align-items: flex-start; text-align: left; }
  .tile__play { display: none; }
  .tile--titled .tile__info { display: none; } /* title is already in the image */
}

/* ==========================================================================
   Phone menu (after Morgan's iPhone site, Ethan's screenshots in FILM PAGE REFERNCES/IMG_1955-1956, 4 Nov 2026):
   the name centred with two thin bars on the right; tapping them fills the screen with the site background,
   the bars turn into a thin X, the three pages sit large, light and centred, and Instagram sits at the bottom.
   The header stays on top, so the name and the X show over the open menu. main.js "Phone menu" opens and
   closes it (a tap on a page, the X, or Escape closes it)
   ========================================================================== */
@media (max-width: 767px) {
  .site-header {
    height: 104px;   /* roomy, like Danny Gevirtz's iPhone header */
    padding-top: 0;
    padding-bottom: 0;
    grid-template-columns: 1fr auto 1fr;
    grid-template-areas: ". mark toggle";
  }
  .wordmark {
    grid-area: mark;
    position: relative;
    z-index: 2;
    font-size: clamp(15px, 5.2vw, 20px);
    letter-spacing: 0.34em;
    margin-right: -0.34em;   /* trailing tracking offset, so the name sits truly centred like Morgan's */
  }

  /* Three thin bars, 34px wide and 8px apart (Morgan has two; Ethan asked for three, 4 Nov 2026); the outer two
     cross into an X when open and the middle one fades out */
  .menu-toggle {
    grid-area: toggle;
    justify-self: end;
    position: relative;
    z-index: 2;
    display: block;
    width: 48px;
    height: 44px;
    margin-right: -7px;   /* bars line up with the page edge, the tap area reaches past it */
    padding: 0;
    border: 0;
    background: none;
    color: var(--text);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .menu-toggle span {
    position: absolute;
    left: 7px;
    top: 50%;
    width: 34px;
    height: 1.5px;
    margin-top: -0.75px;
    background: currentColor;
    border-radius: 1px;
    transition: transform 0.4s var(--ease-out), width 0.4s var(--ease-out), left 0.4s var(--ease-out);
  }
  .menu-toggle span:first-child { transform: translateY(-8px); }
  .menu-toggle span:last-child { transform: translateY(8px); }
  .menu-toggle span:nth-child(2) { transition: opacity 0.2s var(--ease-out); }
  html.menu-open .menu-toggle span { width: 28px; left: 13px; }
  html.menu-open .menu-toggle span:first-child { transform: rotate(45deg); }
  html.menu-open .menu-toggle span:last-child { transform: rotate(-45deg); }
  html.menu-open .menu-toggle span:nth-child(2) { opacity: 0; }

  /* The open menu: a full screen of the site background, under the name and the X */
  /* Opens and closes at once (Ethan, 4 Nov 2026): any fade let iPhone Safari's floating bottom bar show the page
     underneath for a moment. Only the pages rising in and the bars turning into an X are animated */
  .nav {
    opacity: 0;
    visibility: hidden;
    transition: none;
  }
  .nav {
    position: fixed;
    inset: 0;
    z-index: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    padding: 104px var(--gutter);
  }
  /* The menu's background reaches well past the bottom of the screen: on iPhone a fixed full-screen layer can stop
     short of the area behind Safari's bottom bar, which let a strip of the page show there (4 Nov 2026) */
  .nav::before {
    content: "";
    position: absolute;
    inset: -20vh 0 -40vh;
    z-index: -1;
    background: var(--bg);
  }
  .nav a {
    font-size: clamp(30px, 9vw, 36px);
    font-weight: 300;
    line-height: 1.2;
    padding: 8px 0;
    color: var(--text);
    background-position: left calc(100% - 6px);
    transform: translateY(10px);
    opacity: 0;
  }
  /* Phones: TikTok and Instagram sit at the bottom of every page, centred just above the slogan, a little apart
     (Ethan, 4 Nov 2026; they were briefly at the top left of the header, and before that at the menu's bottom) */
  .site-header .socials { display: none; }
  .footer-socials {
    display: flex;
    justify-content: center;
    gap: 20px;
    margin: 0 0 18px;
  }
  .footer-socials a { width: 36px; }
  .footer-socials svg { width: 18px; height: 18px; }

  /* The page isn't locked with overflow: hidden (switching that on and off made iPhone Safari redraw its bottom bar, which
     flashed the page there); main.js stops scrolling on the open menu instead */
  /* The page is hidden while the menu is open: iPhone Safari's floating bottom bar can show the page beneath it rather
     than the menu, which left a strip of films showing at the bottom. It comes back the moment the menu closes */
  html.menu-open main,
  html.menu-open .site-footer { visibility: hidden; }
  html.menu-open .to-top { opacity: 0; visibility: hidden; pointer-events: none; }
  html.menu-open .nav {
    opacity: 1;
    visibility: visible;
  }
  /* The pages rise into place one after another */
  html.menu-open .nav a { transform: none; opacity: 1; transition: transform 0.5s var(--ease-out), opacity 0.5s var(--ease-out); }
  html.menu-open .nav a:nth-child(1) { transition-delay: 0.06s; }
  html.menu-open .nav a:nth-child(2) { transition-delay: 0.12s; }
  html.menu-open .nav a:nth-child(3) { transition-delay: 0.18s; }
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .nav a, html.menu-open .nav a { transform: none; transition-delay: 0s; }
  .menu-toggle span { transition: none; }
}

/* ==========================================================================
   Film page head and player on computers and iPads, after Danny Gevirtz's film pages (Ethan, 4 Nov 2026;
   measured from dannygevirtz.com/rapha-rides-maui-commercial-documentary-hybrid). Danny: title 30px Futura (capitals
   20px tall) 30px below the header; credits straight under it, one per line, 20px Futura (small letters 8px tall) on
   26px lines, grey; the video 100px below, nearly the full width (29px from each side) up to 1400px. Poppins draws
   larger letters than Futura, so the sizes here match how big his letters look: title 28px, credits 15px.
   Ethan's bold spaced capitals for the title are kept. Phones keep their own layout. Before:
   .superpowers/sdd/before-danny-film-head/style.css
   ========================================================================== */
@media (min-width: 768px) {
  .film { padding-top: 30px; }
  .film__head { max-width: 900px; margin-bottom: 100px; }
  .film__title { margin: 0; font-size: 28px; line-height: 34px; }
  /* the film type, credits and kit: one per line, straight under the title */
  .film__kind,
  .film__credits p {
    margin: 0;
    font-size: 15px;
    font-weight: 300;
    line-height: 26px;
    letter-spacing: 0;
    color: var(--text-muted);
  }
  .film__kind { display: block; margin: 0 0 20px; }   /* a clear gap between the film type and the credits (Ethan, 4 Nov 2026) */
  .film__credit { display: block; }
  /* the kit sits on its own after one empty line, like the camera sentence on Danny's Sony page (Ethan, 4 Nov 2026) */
  .film__credits .film__kit { margin-top: 26px; }
  .film__dot { display: none; }
  .film__player { width: min(1400px, 100%); }
  /* Stills: the same two-across layout (an odd last one centred), grouped together with a thin black frame on
     each, like the stills on Danny's film pages (about 8px of black between pictures; Ethan, 4 Nov 2026) */
  .film { --stills-gap: 0px; }
  .film__stills img { box-sizing: border-box; border: 4px solid #000; }
}

/* A Social film's page has no credits under its views and likes, so no gap is kept for them */
.film__head:has(.film__credits:empty) .film__kind { margin: 18px 0 0; }   /* and the views and likes sit a clear gap below the title (Ethan, 4 Nov 2026) */
