/* ==========================================================================
   Ace Animation Studios — landing page
   Implements design option 2a. Tokens derive from assets/nocturne-tokens.css.
   ========================================================================== */

:root {
  /* Ground + surfaces */
  --ground:        #161826;
  --surface:       #232532;
  --surface-tint:  #2b2741;   /* flip back face */

  /* Text */
  --text:          #e9e9ed;
  --text-muted:    #b2b6ca;
  --text-faint:    #9397ab;
  --text-footer:   #75798c;

  /* Accent (Nocturne blurple) */
  --accent:        #9184d9;
  --accent-light:  #b5abfc;
  --accent-pale:   #e7e5fe;
  --accent-pale-2: #d2cefd;
  --accent-pale-3: #f5f4ff;

  /* Card glow */
  --glow:          0 0 0 1px rgba(78,158,255,.55), 0 0 18px rgba(78,158,255,.35), 0 0 48px rgba(78,158,255,.15);
  --glow-strong:   0 0 0 1px rgba(78,158,255,.8),  0 0 22px rgba(78,158,255,.5),  0 0 60px rgba(78,158,255,.2);

  /* Layout */
  --gutter:        40px;
  --rhythm:        120px;
  --radius:        8px;
  --radius-inner:  6px;

  /* Content is capped at the 1280px design canvas and centred. Backgrounds —
     the hero reel, the body wash, the contact gradient — stay full-bleed. */
  --maxw:          1280px;

  /* Film posters: 2:3, the shape of a standard one-sheet (27x40 is close
     enough that cover-cropping trims only a sliver). */
  --film-art-ratio: 2 / 3;

  --ease:          cubic-bezier(.2,.8,.2,1);
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

h1, h2 { font-weight: 500; }

/* Section heading.
   Design baseline was a flat 48/500. Three things give it energy without
   leaving the system: it scales up with the viewport (weight stays 500 — the
   handoff is firm that headings never go bolder), it carries a soft version of
   the same blue the cards glow with, and it ends in an accent mark that echoes
   the blue "O" in the logo. */
.h2 {
  margin: 0;
  font-size: clamp(40px, 5.2vw, 72px);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -.03em;
  text-wrap: balance;
  text-shadow: 0 0 60px rgba(78,158,255,.45), 0 0 24px rgba(78,158,255,.2);
}

.h2__mark {
  color: var(--accent-light);
  /* Pull the mark tight against the word so it reads as one unit. */
  margin-left: -.02em;
}

/* Headings rise into place with the same easing the laurels use. JS adds .js
   to <html>, so without it they are simply visible. */
.js .h2-reveal {
  opacity: 0;
  transform: translateY(18px);
}
.js .h2-reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}

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

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 10px 16px;
  background: var(--surface);
  color: var(--text);
  border-radius: 0 0 var(--radius) 0;
  font-size: 14px;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* ==========================================================================
   1. Hero
   ========================================================================== */

.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 640px;
  overflow: hidden;
  background: var(--ground);
}

.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  /* First layer: a soft dark halo behind the centred logo. The reel has
     near-white scenes, and the white logo needs something to stand on. The
     second layer is the design's vignette. */
  background:
    radial-gradient(ellipse 44% 26% at 50% 50%, rgba(22,24,38,.5), rgba(22,24,38,0) 100%),
    radial-gradient(ellipse at 50% 55%, rgba(22,24,38,.15) 20%, rgba(22,24,38,.9) 100%);
}

/* -- Nav -- */
.nav {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 32px;
  padding: 22px var(--gutter);
  font-size: 14px;
  max-width: var(--maxw);
  margin-inline: auto;
}

.nav__home { margin-right: auto; display: block; line-height: 0; }

.nav__logo {
  height: 22px;
  width: auto;
  filter: invert(1) hue-rotate(180deg);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 32px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav__links a {
  color: var(--text);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.nav__links a:hover { color: var(--accent-light); }

.nav__links a[aria-current="page"] {
  color: var(--accent-light);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 6px;
}

.nav__cta {
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 7px 14px;
  text-decoration: none;
  font-weight: 500;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.nav__cta:hover {
  background: rgba(145,132,217,.12);
  color: var(--accent-light);
  border-color: var(--accent-light);
}

/* -- Centred logo -- */
.hero__center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  pointer-events: none;
}

.hero__title { margin: 0; line-height: 0; }

.hero__logo {
  width: min(640px, 80vw);
  height: auto;
  filter: invert(1) hue-rotate(180deg) drop-shadow(0 12px 40px rgba(0,0,0,.7));
}

/* ==========================================================================
   2. Dark body wrapper + bokeh
   ========================================================================== */

.wash {
  position: relative;
  /* clip, not just hidden: an overflow:hidden box can still be scrolled
     (scrollIntoView, focusing a field), and the drifting bokeh overhang it,
     which shifted the whole page body up inside it on phones. */
  overflow: hidden;
  overflow: clip;
  background: linear-gradient(180deg, #161826 0%, #1a1d3a 35%, #161826 70%, #1c2148 100%);
}

.wash__content { position: relative; }

@keyframes drift {
  0%   { transform: translate(0,0) scale(1); }
  33%  { transform: translate(60px,-40px) scale(1.12); }
  66%  { transform: translate(-40px,50px) scale(.94); }
  100% { transform: translate(0,0) scale(1); }
}

.bokeh {
  position: absolute;
  border-radius: 50%;
  filter: blur(30px);
  pointer-events: none;
  animation: drift 30s ease-in-out infinite;
  will-change: transform;
}

.bokeh--1 {
  width: 520px; height: 520px; left: -140px; top: 8%;
  background: radial-gradient(circle, rgba(78,158,255,.32), rgba(78,158,255,0) 70%);
  animation-duration: 26s;
}
.bokeh--2 {
  width: 380px; height: 380px; right: -80px; top: 30%;
  background: radial-gradient(circle, rgba(145,132,217,.34), rgba(145,132,217,0) 70%);
  animation-duration: 32s; animation-delay: -9s;
}
.bokeh--3 {
  width: 640px; height: 640px; left: 30%; top: 58%;
  background: radial-gradient(circle, rgba(78,158,255,.22), rgba(78,158,255,0) 70%);
  animation-duration: 38s; animation-delay: -17s;
}
.bokeh--5 {
  /* Down by the mailing-list band, so the glow carries on to the contact block. */
  width: 460px; height: 460px; left: -6%; bottom: 0;
  background: radial-gradient(circle, rgba(145,132,217,.26), rgba(145,132,217,0) 70%);
  animation-duration: 34s; animation-delay: -12s;
}
.bokeh--4 {
  width: 260px; height: 260px; right: 12%; top: 82%;
  background: radial-gradient(circle, rgba(181,171,252,.3), rgba(181,171,252,0) 70%);
  animation-duration: 22s; animation-delay: -5s;
}

/* ==========================================================================
   3. About
   ========================================================================== */

/* Two columns: the tagline on the left, the copy on the right. */
.about {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 64px;
  align-items: center;
  padding: var(--rhythm) var(--gutter);
  max-width: var(--maxw);
  margin-inline: auto;
}

/* Three lines, always. Each line is unbreakable, and the type is sized in
   container units (a share of this column's width) rather than px, so as the
   column narrows the words shrink instead of wrapping. --lead-fit is tuned so
   the longest line, "EMOTIONAL STORYTELLING.", just fills the column; the
   52px cap stops it swelling when it runs full width on tablets. */
.about__lead {
  container-type: inline-size;
  margin: 0;
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -.01em;
  text-transform: uppercase;
}
.about__line {
  display: block;
  white-space: nowrap;
  font-size: min(calc(var(--lead-fit, 7) * 1cqi), 52px);
}

.about__cols {
  display: grid;
  gap: 24px;
  font-size: 17px;
  line-height: 1.6;
  color: var(--text-muted);
}
.about__cols p { margin: 0; }
.about__cols em { color: var(--text); font-style: normal; }

/* ==========================================================================
   4. The team — flip rows
   ========================================================================== */

.team {
  padding: 0 var(--gutter) var(--rhythm);
  max-width: var(--maxw);
  margin-inline: auto;
}
.team__heading { margin-bottom: 36px; }

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

.flip {
  height: 200px;
  perspective: 1400px;
}

/* A row with nothing on its back is a plain card rather than a flip. */
.team__row { height: 200px; }

.flip__inner {
  position: relative;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform .7s var(--ease);
}

.flip:not(.is-front):hover .flip__inner,
.flip:not(.is-front):focus-visible .flip__inner,
.flip.is-flipped .flip__inner { transform: rotateX(180deg); }
/* Kept apart: a browser without :has() drops only this rule. */
.flip:has(:focus-visible) .flip__inner { transform: rotateX(180deg); }

.flip__face {
  height: 100%;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  align-items: center;
  gap: 32px;
  padding: 20px 32px;
  border-radius: var(--radius);
}

.flip__front {
  display: grid;
  grid-template-columns: 160px 1fr 1fr;
  background: var(--surface);
  box-shadow: var(--glow);
}

.flip__back {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 160px 1fr;
  transform: rotateX(180deg);
  background: var(--surface-tint);
  box-shadow: var(--glow-strong);
}

.team__photo {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  object-fit: cover;
}

.team__photo--empty {
  display: grid;
  place-items: center;
  background: repeating-linear-gradient(135deg, #2f3242 0 8px, #353849 8px 16px);
  font: 11px ui-monospace, Menlo, monospace;
  color: var(--text-faint);
}

/* Stands in for a photo: the person's initials. */
.team__photo--monogram {
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, #353b80, #4c5397);
  font-size: 52px;
  font-weight: 500;
  letter-spacing: .02em;
  color: var(--accent-pale);
}

.team__id { display: block; }

.team__name {
  display: block;
  font-size: 34px;
  font-weight: 500;
  letter-spacing: -.02em;
}

.team__role {
  display: block;
  font-size: 16px;
  color: var(--text-faint);
  margin-top: 6px;
}

.team__bio {
  margin: 0;
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-muted);
}

.team__label {
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-light);
}

.team__facts {
  font-size: 24px;
  line-height: 1.35;
  color: var(--accent-pale);
}
/* For a back face with a paragraph rather than a line or two. */
.team__facts--long { font-size: 18px; line-height: 1.5; }

.team__back-body { display: grid; gap: 14px; align-content: center; }

/* "More about Stephanie →": on the back of a flip card (the front flips
   away under the pointer), on the front of a plain one. */
.team__link {
  justify-self: start;
  font-size: 15px;
  font-weight: 500;
  color: var(--accent-light);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
  transition: color .2s var(--ease);
}
.team__link:hover { color: #fff; }
.team__id .team__link { display: inline-block; margin-top: 12px; }

.team__noscript { margin: 0; padding-left: 1.2em; color: var(--text-muted); line-height: 1.8; }
.team__noscript a { color: var(--accent-light); }

/* ==========================================================================
   5. Recognition — laurels
   ========================================================================== */

/* Always two rows (lanes). main.js measures each: a lane that fits sits
   still and centred; one that doesn't gets a copy of its row and the pair
   loops slowly sideways, the second lane drifting the other way. */
.laurels {
  display: grid;
  gap: 28px;
  padding: 0 var(--gutter) var(--rhythm);
  max-width: var(--maxw);
  margin-inline: auto;
}

.laurels__lane { overflow: hidden; }
.laurels__track { display: flex; justify-content: center; }

.laurels__row {
  display: flex;
  flex: none;
  gap: 36px;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.laurels__lane.is-marquee {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 56px, #000 calc(100% - 56px), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 56px, #000 calc(100% - 56px), transparent);
}
.laurels__lane.is-marquee .laurels__track {
  justify-content: flex-start;
  width: max-content;
  animation: laurel-marquee var(--marquee-duration, 40s) linear infinite;
}
/* Trailing gap on each copy, so two copies tile seamlessly at -50%. */
.laurels__lane.is-marquee .laurels__row { padding-right: 36px; }
.laurels__lane.is-marquee + .laurels__lane.is-marquee .laurels__track { animation-direction: reverse; }
.laurels__lane.is-marquee:hover .laurels__track { animation-play-state: paused; }
@keyframes laurel-marquee { to { transform: translateX(-50%); } }

/* Reduced motion: no loop, just let the row be scrolled by hand. */
.laurels__lane.is-scrollable { overflow-x: auto; scrollbar-width: none; }
.laurels__lane.is-scrollable .laurels__track { justify-content: flex-start; }

.laurel img {
  height: 84px;
  width: auto;
  filter: invert(1) brightness(1.1);
}

/* Black artwork is inverted to white; laurels that already ship light carry
   .laurel--light. */
.laurel--light img { filter: none; }

/* A short rise rather than a sideways slide: sliding in from the right got
   clipped at the section edge, so laurels looked as if they stalled halfway. */
@keyframes laurel-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* Hidden until main.js reveals the whole row at once (it adds .js to <html>,
   so without JS they are simply visible). */
.js .laurel { opacity: 0; }
.js .laurel.is-in { animation: laurel-in .7s var(--ease) both; }

/* ==========================================================================
   6. News
   ========================================================================== */

.news {
  padding: 0 var(--gutter) var(--rhythm);
  max-width: var(--maxw);
  margin-inline: auto;
}

.news__heading { margin-bottom: 36px; }

/* Outlined like the Contact button in the nav, a size up. */
.news__more {
  display: inline-block;
  margin-top: 32px;
  padding: 10px 18px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  font-size: 15px;
  font-weight: 500;
  color: var(--accent);
  text-decoration: none;
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.news__more:hover {
  background: rgba(145,132,217,.12);
  color: var(--accent-light);
  border-color: var(--accent-light);
}

/* -- Instagram grid --
   Four posts, tall enough to show a real stretch of each caption: one row of
   four on desktop, 2x2 on tablets, and compact rows (thumbnail beside text) on
   phones so the feed doesn't take over a small screen. */
.ig-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

.ig-tile {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  padding: 12px;
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  box-shadow: var(--glow);
  transition: box-shadow .3s var(--ease), transform .3s var(--ease);
}

a.ig-tile:hover {
  box-shadow: var(--glow-strong);
  transform: translateY(-3px);
}

.ig-tile__media {
  position: relative;
  display: block;
  aspect-ratio: 1;
  border-radius: var(--radius-inner);
  overflow: hidden;
  background: repeating-linear-gradient(135deg, #2f3242 0 8px, #353849 8px 16px);
}

.ig-tile__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .6s var(--ease);
}
a.ig-tile:hover .ig-tile__media img { transform: scale(1.04); }

.ig-tile__badge {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(22,24,38,.72);
  color: #fff;
}
.ig-tile__badge svg { width: 14px; height: 14px; }

.ig-tile__caption {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--ig-caption-lines, 7);
  line-clamp: var(--ig-caption-lines, 7);
  overflow: hidden;
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
a.ig-tile:hover .ig-tile__caption { color: var(--text); }

.ig-tile__date {
  margin-top: auto;
  font-size: 12px;
  color: var(--text-faint);
}

/* Placeholder tiles: striped square plus two quiet caption bars. */
.ig-tile__line {
  display: block;
  height: 10px;
  border-radius: 5px;
  background: #2c2f40;
}
.ig-tile__line--short { width: 55%; }

.ig-fallback {
  margin: 0;
  padding: 28px;
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--glow);
  font-size: 16px;
  color: var(--text-muted);
}
.ig-fallback a { color: var(--accent-light); font-weight: 500; }

/* ==========================================================================
   7. Contact
   ========================================================================== */

/* The gradient stays full-bleed; only the content inside is capped. */
.contact {
  overflow: hidden;
  background: linear-gradient(135deg, #262a60, #353b80 60%, #4c5397);
}

.contact__inner {
  position: relative;
  /* Lets the email size itself to this box (cqi units below). */
  container-type: inline-size;
  padding: 110px var(--gutter) var(--rhythm);
  max-width: var(--maxw);
  margin-inline: auto;
}

.contact__h2 { margin-bottom: 20px; color: var(--accent-pale-3); }

.contact__email {
  display: inline-block;
  /* Always one line, never split mid-address: it shrinks to fit instead.
     --email-fit is the address's width in ems; raise it if the address gets
     longer. */
  --email-fit: 14; /* forecastedmovie@gmail.com is 13.46em */
  font-size: min(56px, calc(100cqi / var(--email-fit)));
  white-space: nowrap;
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 1.05;
  color: var(--accent-pale-2);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.contact__email:hover { color: var(--accent-pale-3); }

.contact__social {
  display: flex;
  gap: 28px;
  margin: 40px 0 0;
  padding: 0;
  list-style: none;
  font-size: 15px;
}

.contact__social a {
  color: var(--accent-pale);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.contact__social a:hover { color: #fff; }

.contact__mascot {
  position: absolute;
  right: 56px;
  bottom: -14px;
  width: 150px;
  height: auto;
}

/* ==========================================================================
   8. Footer
   ========================================================================== */

.footer {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding: 20px var(--gutter);
  font-size: 12px;
  color: var(--text-footer);
  max-width: var(--maxw);
  margin-inline: auto;
}

.footer__links { display: flex; gap: 20px; }

.footer a {
  color: var(--text-footer);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.footer a:hover { color: var(--text-muted); }

/* ==========================================================================
   9. Films page
   ========================================================================== */

/* The body wash doubles as the page background here; it just needs enough
   height to hold the grid and let the bokeh breathe. */
.wash--page { min-height: 100vh; min-height: 100svh; }

/* Holds the nav, which is absolutely positioned as it is over the hero. */
.page-head { position: relative; height: 84px; }

.films {
  padding: 64px var(--gutter) var(--rhythm);
  max-width: var(--maxw);
  margin-inline: auto;
}

.films__intro {
  /* Room above the cards for the cameos to rise into. */
  margin: 20px 0 96px;
  font-size: 17px;
  line-height: 1.6;
  color: var(--text-muted);
}

.films__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.films__noscript { margin: 0; padding-left: 20px; color: var(--text-muted); line-height: 1.8; }

/* -- Card --
   Key art takes its shape from --film-art-ratio in :root, which the cards and
   the modal both follow. */

.film-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 14px 14px 20px;
  border: 0;
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--glow);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: box-shadow .3s var(--ease), transform .3s var(--ease);
}

.film-card:hover,
.film-card:focus-visible {
  box-shadow: var(--glow-strong);
  transform: translateY(-4px);
}

.film-card__art,
.film-modal__art {
  display: block;
  aspect-ratio: var(--film-art-ratio, 2 / 3);
  border-radius: var(--radius-inner);
  overflow: hidden;
  background: #232532;
}

.film-card__art img,
.film-modal__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .6s var(--ease);
}
.film-card:hover .film-card__art img { transform: scale(1.03); }

.film-card__art.is-empty,
.film-modal__art.is-empty {
  display: grid;
  place-items: center;
  background: repeating-linear-gradient(135deg, #2f3242 0 8px, #353849 8px 16px);
}

.film-art-note {
  font: 11px ui-monospace, Menlo, monospace;
  letter-spacing: .04em;
  color: var(--text-faint);
}

.film-card__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 6px;
}

.film-card__status,
.film-modal__label {
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-light);
}

.film-card__title {
  font-size: 28px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -.02em;
}

.film-card__meta { font-size: 14px; color: var(--text-faint); }

.film-card__cta {
  margin-top: 8px;
  font-size: 14px;
  font-weight: 500;
  color: var(--accent);
  transition: color .2s var(--ease);
}
.film-card:hover .film-card__cta { color: var(--accent-light); }

/* -- Modal --
   Native <dialog>: showModal() supplies the focus trap, inert page and
   Escape. The panel never scrolls itself; .film-modal__body does, so the
   scrollbar stays inside the rounded corners. */
.film-modal {
  width: min(920px, calc(100% - 32px));
  max-width: none;
  max-height: 88vh;
  max-height: 88dvh;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: #1c1e2d;
  color: var(--text);
  box-shadow: var(--glow-strong), 0 30px 80px rgba(0,0,0,.55);
  overflow: hidden;
}

/* Only when open — display on a closed <dialog> would show it. */
.film-modal[open] {
  display: flex;
  flex-direction: column;
  animation: modal-in .35s var(--ease);
}

.film-modal::backdrop {
  background: rgba(10,11,20,.74);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.film-modal[open]::backdrop { animation: backdrop-in .25s ease; }

@keyframes modal-in {
  from { opacity: 0; transform: translateY(18px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes backdrop-in { from { opacity: 0; } to { opacity: 1; } }

/* Hold the page still while the modal is up. films.js sets the class for
   browsers without :has(). */
html:has(.film-modal[open]),
html.has-open-modal { overflow: hidden; }
html.has-open-modal body { overflow: hidden; }

/* Where films.js parks focus after a tap: no ring on the content itself. */
.film-modal__body:focus,
.film-viewer__figure:focus { outline: none; }

/* Phones without <dialog> (iOS before 15.4): films.js shows the same
   elements as a fixed overlay with its own backdrop. Those browsers would
   show a closed <dialog> inline, hence the first rule. */
dialog:not([open]) { display: none; }
.film-modal.is-fallback,
.film-viewer.is-fallback {
  position: fixed;
  inset: 0;
  z-index: 1001;
  margin: auto;
  /* Reopening can freeze the entrance animation on its first, invisible
     frame in these older engines. */
  animation: none;
}
.film-modal.is-fallback { height: fit-content; }
.film-viewer.is-fallback { height: 100%; }
.modal-fallback-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(10,11,20,.8);
}
.modal-fallback-backdrop.is-viewer { z-index: 1002; background: rgba(8,9,16,.92); }
.modal-fallback-backdrop.is-viewer + .film-viewer.is-fallback { z-index: 1003; }

.film-modal__body {
  /* auto, not flex: 1. Older iOS Safari reads flex: 1 (a 0% basis) as zero
     height in this auto-height column and squashes the popup to a strip. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 40px;
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}
.film-modal__body::-webkit-scrollbar { width: 6px; }
.film-modal__body::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 999px; }

.film-modal__close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(22,24,38,.7);
  color: var(--text-muted);
  cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.film-modal__close svg { width: 20px; height: 20px; }
.film-modal__close:hover { background: rgba(145,132,217,.2); color: #fff; }

.film-modal__top {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 32px;
  align-items: start;
}

.film-modal__art { box-shadow: 0 10px 30px rgba(0,0,0,.35); }

.film-modal__info {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.film-modal__title {
  margin: 0;
  /* Leave room for the close button. */
  padding-right: 44px;
  font-size: clamp(32px, 4vw, 44px);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -.025em;
}

.film-modal__credit { margin: -4px 0 0; font-size: 15px; color: var(--accent-light); }
.film-modal__meta { margin: 0; font-size: 14px; color: var(--text-faint); }
.film-modal__synopsis { margin: 0; font-size: 17px; line-height: 1.6; color: var(--text-muted); }
.film-modal__genres { margin: 0; font-size: 13px; letter-spacing: .04em; color: var(--text-faint); }
.film-modal__contact { margin: 0; font-size: 15px; color: var(--text-muted); }
.film-modal__contact a { color: var(--accent-light); }

/* -- Click-to-load video -- */
.film-video {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-inner);
  overflow: hidden;
  background: #0e0f18;
  box-shadow: 0 8px 24px rgba(0,0,0,.3);
}

.film-video__play {
  position: absolute;
  inset: 0;
  padding: 0;
  border: 0;
  font: inherit; /* Safari gives buttons the system font otherwise */
  background: none;
  color: #fff;
  cursor: pointer;
}

.film-video__thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .5s var(--ease), filter .3s var(--ease);
  filter: brightness(.82);
}
.film-video__play:hover .film-video__thumb { transform: scale(1.03); filter: brightness(.95); }
/* A still standing in for a video: shown as is, nothing to press. */
.film-video__still { filter: none; }

.film-video__icon {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 68px;
  height: 68px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 1px rgba(78,158,255,.55), 0 0 28px rgba(78,158,255,.45);
  transform: translate(-50%, -50%);
  transition: transform .2s var(--ease), background-color .2s var(--ease);
}
.film-video__icon svg { width: 28px; height: 28px; margin-left: 4px; }
.film-video__play:hover .film-video__icon { transform: translate(-50%, -50%) scale(1.07); background: var(--accent-light); }

.film-video__label {
  position: absolute;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  padding: 5px 14px;
  border-radius: 999px;
  background: rgba(22,24,38,.82);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.film-video__iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* -- Sections: press, accolades, credits -- */
.film-modal__section {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid rgba(233,233,237,.1);
}
.film-modal__label { margin: 0 0 18px; font-weight: 400; }

.film-press { display: flex; flex-wrap: wrap; gap: 10px; }
.film-press__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--glow);
  color: var(--text);
  font-size: 14px;
  text-decoration: none;
}
.film-press__link:hover { color: var(--accent-light); box-shadow: var(--glow-strong); }
.film-press__icon svg { display: block; width: 13px; height: 13px; }

.film-accolades { display: flex; flex-direction: column; gap: 22px; }
.film-accolades__name { margin: 0 0 8px; font-size: 16px; font-weight: 500; color: var(--accent-pale); }
.film-accolades__rows { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.film-accolades__rows li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--text-muted);
}
.film-accolades__rows strong { font-weight: 500; color: var(--text); }
.film-accolades__icon { flex: none; margin-top: 3px; }
.film-accolades__icon svg { display: block; width: 15px; height: 15px; }
.is-win .film-accolades__icon { color: #f2c46b; }
.is-nomination .film-accolades__icon { color: var(--accent-light); }
.is-selection .film-accolades__icon { color: rgb(78,158,255); }

.film-credits {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 28px;
  row-gap: 10px;
  margin: 0;
}
.film-credits__row { display: contents; }
.film-credits dt {
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--text-faint);
}
.film-credits dd { margin: 0; font-size: 15px; line-height: 1.5; color: var(--text); }

/* Full-bleed still closing the panel: cancels the body's padding. */
.film-modal__still {
  margin: 36px -40px -40px;
  line-height: 0;
}
.film-modal__still img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
/* Or, in its place, the behind-the-scenes video, full-bleed the same way. */
.film-video.film-modal__bts { margin: 36px -40px -40px; border-radius: 0; }
.film-bts__video { display: block; width: 100%; height: 100%; object-fit: contain; background: #000; }
/* Autoplay has to start muted; this brings the sound in. */
.film-bts__sound {
  position: absolute;
  top: 14px;
  left: 14px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px 8px 10px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: rgba(22,24,38,.82);
  color: var(--accent-pale);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color .2s var(--ease);
}
.film-bts__sound:hover { background: rgba(145,132,217,.35); }
.film-bts__sound-icon { display: inline-grid; }
.film-bts__sound-icon svg { width: 18px; height: 18px; }
.film-bts__sound[hidden] { display: none; }

/* -- The film's own laurels, atop Accolades -- */
.film-laurels {
  --laurel-gap: 24px;
  overflow-x: auto;
  margin: 0 -40px 8px;
  padding: 4px 40px 12px;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent);
}
.film-laurels__track { display: flex; }
.film-laurels__row {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--laurel-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}
.film-laurels li { flex: none; }
/* Wider than the modal: films.js adds a copy of the row and the pair drifts
   slowly left on a loop (the home page's laurel-marquee). Hover pauses it.
   Under reduced motion it stays a row you can swipe. */
.film-laurels.is-marquee { overflow: hidden; padding-inline: 0; }
.film-laurels.is-marquee .film-laurels__track {
  width: max-content;
  animation: laurel-marquee var(--marquee-duration, 40s) linear infinite;
}
/* Trailing gap on each copy, so the two tile seamlessly at -50%. */
.film-laurels.is-marquee .film-laurels__row { padding-right: var(--laurel-gap); }
.film-laurels.is-marquee:hover .film-laurels__track { animation-play-state: paused; }
.film-laurels img { display: block; height: 60px; width: auto; filter: invert(1) brightness(1.1); }
.film-laurels .is-light img { filter: none; }

/* -- Gallery: filmstrips in the modal -- */
.film-strip {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Bleed to the modal's edges so the strip reads as a reel running past. */
  margin: 0 -40px;
  padding: 4px 40px 12px;
  scroll-padding-inline: 40px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent);
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}

.film-strip__item {
  position: relative;
  flex: none;
  width: 248px;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 0;
  border-radius: var(--radius-inner);
  overflow: hidden;
  background: #0e0f18;
  cursor: zoom-in;
  scroll-snap-align: start;
  box-shadow: 0 6px 18px rgba(0,0,0,.3);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.film-strip__item:hover,
.film-strip__item:focus-visible { transform: translateY(-3px); box-shadow: var(--glow); }

.film-strip__item img,
.film-strip__item video { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Pencil tests carry their scene number like a slate on a dope sheet. */
.film-strip__slate {
  position: absolute;
  left: 8px;
  bottom: 8px;
  padding: 3px 7px;
  border-radius: 4px;
  background: rgba(22,24,38,.82);
  color: #fff;
  font: 500 11px ui-monospace, Menlo, monospace;
  letter-spacing: .06em;
}

/* -- Gallery viewer: a second dialog over the film modal -- */
.film-viewer {
  width: min(1200px, calc(100% - 128px));
  max-width: none;
  max-height: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  overflow: visible;
}
.film-viewer[open] { display: grid; place-items: center; animation: modal-in .3s var(--ease); }
.film-viewer::backdrop { background: rgba(8,9,16,.92); }

.film-viewer__figure { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.film-viewer__stage { display: grid; place-items: center; }
.film-viewer__media {
  display: block;
  max-width: 100%;
  max-height: calc(100vh - 120px);
  max-height: calc(100dvh - 120px);
  border-radius: var(--radius-inner);
  background: #0e0f18;
  box-shadow: 0 20px 60px rgba(0,0,0,.6);
}
.film-viewer__caption { font-size: 14px; color: var(--text-muted); text-align: center; }

.film-viewer__close { position: fixed; top: 16px; right: 16px; }

.film-viewer__prev,
.film-viewer__next {
  position: fixed;
  top: 50%;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(22,24,38,.75);
  color: var(--text);
  cursor: pointer;
  transform: translateY(-50%);
  transition: background-color .2s var(--ease);
}
.film-viewer__prev { left: 16px; }
.film-viewer__next { right: 16px; }
.film-viewer__prev:hover,
.film-viewer__next:hover { background: rgba(145,132,217,.3); }
.film-viewer__prev svg,
.film-viewer__next svg { width: 22px; height: 22px; }
.film-viewer [hidden] { display: none; }

/* -- Cameos --
   Character cut-outs that peek over an edge, like the blueberry in the
   contact band. Each one is cut flat at the bottom, and that cut sits exactly
   on the edge it hides behind, so the character reads as standing behind it.
   Sparing on purpose: one on the home page, one per film card on /films. */

/* Films page: the character waits behind its card and rises over the top
   edge on hover or keyboard focus. */
.film-slot { position: relative; display: flex; }
.film-slot > .film-card { position: relative; z-index: 1; flex: 1; }

.film-cameo {
  position: absolute;
  z-index: 0;
  top: 18px;
  right: 22px;
  height: 120px;
  width: auto;
  pointer-events: none;
  transition: transform .5s var(--ease);
}
.film-slot:hover .film-cameo,
.film-slot:focus-within .film-cameo { transform: translateY(-96px); }

/* Home: Carter waits behind a News tile and rises until his chin sits on its
   top edge as the section scrolls into view. On desktop that's the second
   tile (the first sits under the heading); where tiles stack, the top-right
   one. */
.news__feed { position: relative; }
.news__feed > .ig-grid,
.news__feed > .ig-fallback { position: relative; z-index: 1; }

.cameo {
  position: absolute;
  z-index: 0;
  pointer-events: none;
}
.cameo--news {
  top: 0;
  /* Second of four columns: its right edge is 8px (half the 16px gap) left
     of the grid's centre line. */
  right: calc(50% + 8px + 28px);
  width: 126px;
  height: auto;
  transition: transform .9s var(--ease);
}
.cameo--news.is-in { transform: translateY(-100%); }

/* Stephanie's card: Ahmad (Our Song) rises behind it as the flip settles, and drops straight back when the hover ends. He stays invisible
   until then, because a card turning edge-on mid-flip would reveal him. The
   delay lives on the hover state, so leaving has none. */
.flip { position: relative; }
.flip__inner { z-index: 1; }
.team-cameo {
  position: absolute;
  z-index: 0;
  top: 0;
  right: 56px;
  height: 150px;
  width: auto;
  opacity: 0;
  pointer-events: none;
  transition: transform .35s var(--ease), opacity .25s ease;
}
.flip:not(.is-front):hover .team-cameo,
.flip:not(.is-front):focus-visible .team-cameo,
.flip.is-flipped .team-cameo {
  opacity: 1;
  transform: translateY(-100%);
  /* The flip (.7s) does most of its turning early, so .35s in the card is
     nearly flat again and can hide him. */
  transition: transform .55s var(--ease) .35s, opacity .2s ease .35s;
}
/* Kept apart: a browser without :has() drops only this rule. */
.flip:has(:focus-visible) .team-cameo {
  opacity: 1;
  transform: translateY(-100%);
  /* The flip (.7s) does most of its turning early, so .35s in the card is
     nearly flat again and can hide him. */
  transition: transform .55s var(--ease) .35s, opacity .2s ease .35s;
}

/* ==========================================================================
   About Stephanie (/stephanie)
   A playful take on the house style: tilted cards that straighten under the
   pointer, and characters from the films peeking over each
   chapter once it scrolls into view.
   ========================================================================== */

.steph {
  padding: 56px var(--gutter) var(--rhythm);
  max-width: var(--maxw);
  margin-inline: auto;
}

.steph-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 64px;
  align-items: center;
}

.steph-eyebrow {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-light);
}
.steph-eyebrow::before { content: "✦ "; color: #7fb2ff; }

.steph-hero__name { margin: 0; }
.steph-hero__roles { margin: 16px 0 0; font-size: 18px; color: var(--accent-pale-2); }
.steph-hero__lede { margin: 24px 0 0; font-size: 18px; line-height: 1.65; color: var(--text-muted); max-width: 60ch; }
.steph-hero__lede a { color: var(--accent-light); }

/* Portrait in a glowing ring. */
.steph-hero__portrait { position: relative; justify-self: center; width: min(380px, 100%); }
.steph-portrait {
  position: relative;
  z-index: 1;
  aspect-ratio: 1;
  padding: 10px;
  border-radius: 50%;
  background: conic-gradient(from 200deg, #4e9eff, #9184d9, #ffb3cf, #4e9eff);
  box-shadow: 0 0 60px rgba(78,158,255,.35);
}
.steph-portrait img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  border: 6px solid var(--ground);
}

/* Chapters: tilted cards, each with a character waiting behind it. */
.chapters {
  display: grid;
  gap: 150px;
  margin-top: 190px;
}

.chapter {
  position: relative;
  max-width: 820px;
  transform: rotate(var(--tilt, -1deg));
  transition: transform .5s var(--ease);
}
.chapter:nth-child(even) { --tilt: 1deg; justify-self: end; }
.chapter:hover { transform: rotate(0); }

.chapter__card {
  position: relative;
  z-index: 1;
  padding: 40px 44px;
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--glow);
  transition: box-shadow .3s var(--ease);
}
.chapter:hover .chapter__card { box-shadow: var(--glow-strong); }
.chapter__card p { margin: 0 0 16px; font-size: 17px; line-height: 1.7; color: var(--text-muted); }
.chapter__card p a { color: var(--accent-light); }

.chapter__title {
  margin: 0 0 18px;
  font-size: clamp(30px, 3.6vw, 44px);
  font-weight: 500;
  letter-spacing: -.02em;
  text-shadow: 0 0 40px rgba(78,158,255,.35);
}
.chapter__link {
  display: inline-block;
  margin-top: 6px;
  font-weight: 500;
  color: var(--accent-light);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
}
.chapter__link:hover { color: #fff; }

/* The character sits behind the card's top edge and rises when main.js
   adds .is-in. (No hop on hover: lifting him showed the flat bottom of the
   cut-out above the card.) */
.popout {
  position: absolute;
  z-index: 0;
  top: 6px;
  height: 150px;
  width: auto;
  pointer-events: none;
  transition: transform .9s var(--ease);
}
.popout--left { left: 56px; }
.popout--right { right: 56px; }
.chapter.is-in .popout { transform: translateY(-100%); }

/* ==========================================================================
   Privacy Policy and Legal (/privacy, /legal)
   The logo, large, as the page's hero; then the text in a readable column
   on a card like the rest of the site.
   ========================================================================== */

.legal {
  padding: 40px var(--gutter) var(--rhythm);
  max-width: var(--maxw);
  margin-inline: auto;
}
.legal__hero {
  display: grid;
  place-items: center;
  padding: 56px 0 72px;
}
.legal__logo {
  width: min(720px, 86vw);
  height: auto;
  filter: invert(1) hue-rotate(180deg) drop-shadow(0 0 40px rgba(78,158,255,.35)) drop-shadow(0 12px 40px rgba(0,0,0,.6));
}
.legal__doc {
  max-width: 780px;
  margin-inline: auto;
  padding: 48px 56px 52px;
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--glow);
}
.legal__title { margin: 0; font-size: clamp(36px, 4.4vw, 56px); }
.legal__updated { margin: 12px 0 32px; font-size: 14px; color: var(--text-faint); }
.legal__doc h2 {
  margin: 40px 0 12px;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -.01em;
  color: var(--accent-pale);
}
.legal__doc p,
.legal__doc li { font-size: 16px; line-height: 1.75; color: var(--text-muted); }
.legal__doc p { margin: 0 0 14px; }
.legal__doc ul { margin: 0 0 14px; padding-left: 1.2em; display: grid; gap: 10px; }
.legal__doc strong { color: var(--text); font-weight: 500; }
.legal__doc a { color: var(--accent-light); overflow-wrap: anywhere; }
.legal__doc a:hover { color: #fff; }
.legal__lede { font-size: 18px !important; color: var(--text) !important; }

.footer__links a[aria-current="page"] { color: var(--accent-light); }

/* ==========================================================================
   Mailing list — the last thing in the page gradient, just above the contact
   block, on every page. Carter peeks up from its bottom edge and asks; the form lives in his speech bubble.
   ========================================================================== */

/* No background of its own: it sits inside .wash, so the page gradient runs
   unbroken down to the contact block. Only the bottom edge clips (so Carter
   can hide below it before rising); clipping all sides with overflow:hidden
   cut the drifting bokeh off in a hard line on Android Chrome. */
.newsletter {
  position: relative;
  clip-path: inset(-100vh -100vw 0 -100vw);
}

.newsletter__inner {
  display: grid;
  grid-template-columns: 175px minmax(0, 700px);
  justify-content: center;
  align-items: end;
  gap: 44px;
  max-width: var(--maxw);
  margin-inline: auto;
  /* The section above already ends with its own bottom space. */
  padding: 0 var(--gutter);
}

/* His chin rests on the band's bottom edge, so he looks up from behind the
   contact block. He starts lower and rises once the band is in view. */
.newsletter__character {
  width: 175px;
  height: auto;
  transform: translateY(40%);
  transition: transform .9s var(--ease);
}
.newsletter.is-in .newsletter__character { transform: none; }

.newsletter__bubble {
  position: relative;
  margin-bottom: 110px;
  padding: 30px 34px 24px;
  border-radius: 28px;
  /* The same dark card and blue glow as the team and film cards. A filter
     rather than box-shadow, so the glow follows the tail too. */
  background: var(--surface);
  color: var(--text);
  filter: drop-shadow(0 0 1px rgba(78,158,255,.95)) drop-shadow(0 0 16px rgba(78,158,255,.35));
}
/* The tail, pointing down to Carter. */
.newsletter__bubble::before {
  content: "";
  position: absolute;
  left: -30px;
  bottom: 22px;
  width: 52px;
  height: 40px;
  background: inherit;
  clip-path: polygon(100% 0, 0 100%, 100% 62%);
}

.newsletter__title {
  margin: 0;
  font-size: clamp(22px, 2.4vw, 28px);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -.01em;
  color: var(--text);
}
.newsletter__note { margin: 8px 0 18px; font-size: 15px; color: var(--text-muted); }

.signup__fields { display: flex; flex-wrap: wrap; gap: 10px; }
.signup__input {
  flex: 1 1 170px;
  min-width: 0;
  padding: 12px 16px;
  border: 1px solid #3a3e58;
  border-radius: 999px;
  background: var(--ground);
  color: var(--text);
  font: inherit;
  font-size: 15px;
}
.signup__input::placeholder { color: var(--text-faint); }
.signup__input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(145,132,217,.3); }
.signup__button {
  flex: none;
  padding: 12px 24px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: transparent;
  color: var(--accent-light);
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color .2s var(--ease), box-shadow .2s var(--ease);
}
.signup__button:hover { background: rgba(145,132,217,.14); border-color: var(--accent-light); color: #fff; }
.signup__button:disabled { opacity: .6; cursor: default; }
/* The honeypot: hidden from people, filled in by bots. */
.signup__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.signup__status { min-height: 1.4em; margin: 12px 4px 0; font-size: 15px; color: var(--accent-pale); }
.signup__status.is-error { color: #ffc2c2; }
.signup__status:empty { min-height: 0; margin: 0; }
[data-signup].is-done .signup__fields { display: none; }
[data-signup].is-done .signup__status { font-size: 17px; font-weight: 500; }
/* ==========================================================================
   Responsive
   ========================================================================== */

/* Instagram grid: 4 across on desktop, 2x2 on tablets, rows on phones. */
@media (max-width: 1040px) {
  .ig-grid { grid-template-columns: repeat(2, 1fr); }
  .cameo--news { right: 28px; }
  .ig-grid { --ig-caption-lines: 6; }
}

@media (max-width: 900px) {
  :root { --gutter: 24px; --rhythm: 80px; }

  /* Nav collapses to logo + Films + Contact. The in-page links go (the page
     scrolls to them anyway); Films stays because it is a separate page. */
  .nav { gap: 20px; }
  .nav__links li:not(.nav__keep) { display: none; }

  .about { grid-template-columns: 1fr; gap: 40px; }

  /* Team rows grow: photo above text */
  .flip, .team__row { height: auto; min-height: 320px; }
  .flip__inner { height: auto; min-height: 320px; }

  .flip__front,
  .flip__back {
    grid-template-columns: 1fr;
    justify-items: start;
    align-content: center;
    gap: 20px;
    padding: 28px 24px;
  }
  .flip__front { height: auto; min-height: 320px; }
  .flip__back { height: 100%; overflow: hidden; }

  .team__name { font-size: 28px; }
  .team__facts { font-size: 20px; }


  .contact__mascot { width: 110px; right: 16px; opacity: .9; }

  .legal { padding-top: 16px; }
  .legal__hero { padding: 40px 0 48px; }
  .legal__doc { padding: 32px 22px 36px; }

  /* About Stephanie: portrait above the text, gentler tilts, smaller
     characters. */
  .steph { padding-top: 32px; }
  .steph-hero { grid-template-columns: 1fr; gap: 40px; }
  .steph-hero__portrait { order: -1; width: min(280px, 72%); }
  .steph-hero__lede { font-size: 17px; }
  .chapters { gap: 120px; margin-top: 150px; }
  .chapter { --tilt: -.6deg; }
  .chapter:nth-child(even) { --tilt: .6deg; }
  .chapter__card { padding: 30px 24px; }
  .chapter__card p { font-size: 16px; }
  .popout { height: 112px; }
  .popout--left { left: 28px; }
  .popout--right { right: 28px; }
  /* Mailing list: bubble on top, Carter below it with the tail pointing
     down to him. */
  .newsletter__inner { grid-template-columns: 1fr; gap: 22px; }
  .newsletter__bubble { order: -1; margin-bottom: 0; padding: 26px 22px 20px; }
  .newsletter__bubble::before { left: 46px; bottom: -28px; width: 40px; height: 30px; clip-path: polygon(0 0, 100% 0, 14% 100%); }
  .newsletter__character { width: 112px; margin-left: 24px; }

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

@media (max-width: 760px) {
  /* Films: one column of compact rows, art beside the text. */
  .films { padding-top: 40px; }
  .films__intro { margin-bottom: 32px; }
  .films__grid { grid-template-columns: 1fr; gap: 14px; }
  .film-card { flex-direction: row; align-items: center; gap: 18px; padding: 12px; }
  .film-card__art { flex: none; width: 112px; }
  .film-card__body { padding: 0; }
  .film-card__title { font-size: 24px; }
  .film-card__cta { margin-top: 4px; }

  /* Modal: a full-screen sheet with a fixed height, so its size never
     depends on the content (see .film-modal__body); art above the text. */
  .film-modal {
    width: 100%;
    max-width: 100%;
    height: 100%;
    max-height: 100%;
    margin: 0;
    border-radius: 0;
    box-shadow: none;
  }
  .film-modal__close { top: 12px; right: 12px; }
  .film-modal__body { padding: 28px 20px calc(28px + env(safe-area-inset-bottom, 0px)); }
  .film-modal__top { grid-template-columns: 1fr; gap: 22px; }
  .film-modal__art { width: min(200px, 60%); }
  .film-modal__still,
  .film-video.film-modal__bts { margin: 28px -20px -28px; }
  .film-strip { margin: 0 -20px; padding-inline: 20px; scroll-padding-inline: 20px; }
  .film-laurels { margin-inline: -20px; padding-inline: 20px; --laurel-gap: 18px; }
  .film-laurels img { height: 48px; }
  .film-strip__item { width: 200px; }
  /* Card rows on phones: no room above them for a cameo to rise into. */
  .film-cameo { display: none; }
  .cameo--news { width: 92px; right: 20px; }
  .team-cameo { height: 120px; right: 28px; }
  .film-viewer { width: calc(100% - 24px); }
  .film-viewer__prev, .film-viewer__next { top: auto; bottom: 20px; transform: none; }
  .film-credits { grid-template-columns: 1fr; row-gap: 4px; }
  .film-credits dd { margin-bottom: 10px; }
}

@media (max-width: 560px) {
  /* Compact rows: thumbnail on the left, caption and date beside it. */
  .ig-grid { grid-template-columns: 1fr; gap: 12px; --ig-caption-lines: 4; }
  .ig-tile {
    display: grid;
    grid-template-columns: 104px minmax(0, 1fr);
    align-content: start;
    column-gap: 14px;
    row-gap: 6px;
    padding: 10px;
  }
  .ig-tile { grid-template-rows: auto 1fr; }
  .ig-tile__media { grid-column: 1; grid-row: 1 / span 2; }
  /* Placeholders stack four caption bars beside the thumbnail. */
  .ig-tile--placeholder { grid-template-rows: repeat(3, auto) 1fr; }
  .ig-tile--placeholder .ig-tile__media { grid-row: 1 / span 4; }
  .ig-tile__caption { font-size: 14px; line-height: 1.45; }
  .ig-tile__date { margin-top: 0; }
}

@media (max-width: 480px) {
  .laurel img { height: 60px; }
  .laurels { gap: 20px; }
  .laurels__row { gap: 24px; }
  .laurels__lane.is-marquee .laurels__row { padding-right: 24px; }
}

/* ==========================================================================
   Reduced motion — fade instead of rotate, hold the bokeh, hold the reel
   ========================================================================== */

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

  .bokeh { animation: none; }

  .film-modal[open],
  .film-modal[open]::backdrop,
  .film-viewer[open] { animation: none; }
  .film-cameo, .cameo--news, .team-cameo, .popout, .chapter, .newsletter__character { transition: none !important; }
  .newsletter__character { transform: none !important; }
  .cameo--news { transform: translateY(-100%); }
  .film-card, .ig-tile, .film-card__art img, .ig-tile__media img { transition: none; }
  .film-card:hover, a.ig-tile:hover { transform: none; }

  .js .laurel { opacity: 1; }
  .js .laurel.is-in { animation: none; }

  .js .h2-reveal { opacity: 1; transform: none; }
  .js .h2-reveal.is-in { transition: none; }

  .flip__inner { transition: none; }
  .flip:not(.is-front):hover .flip__inner,
  .flip:not(.is-front):focus-visible .flip__inner,
  .flip.is-flipped .flip__inner { transform: none; }
  .flip:has(:focus-visible) .flip__inner { transform: none; }

  /* Cross-fade the two faces in place */
  .flip__face { transition: opacity .3s ease; }
  .flip__back {
    transform: none;
    opacity: 0;
    backface-visibility: visible;
    -webkit-backface-visibility: visible;
  }
  .flip:not(.is-front):hover .flip__front,
  .flip:not(.is-front):focus-visible .flip__front,
  .flip.is-flipped .flip__front { opacity: 0; }
  .flip:has(:focus-visible) .flip__front { opacity: 0; }
  .flip:not(.is-front):hover .flip__back,
  .flip:not(.is-front):focus-visible .flip__back,
  .flip.is-flipped .flip__back { opacity: 1; }
  .flip:has(:focus-visible) .flip__back { opacity: 1; }
}
