/* ---- film detail view ---------------------------------------------------
   Same gutter, easing and reveal cascade as the work grid. The one deliberate
   departure is the stills gutter: the grid is a mosaic on a 3px hairline, these
   are a gallery and want air. */
/* top padding clears the fixed bar and sets the header-to-content gap — same final
   numbers as the work grid's --grid-top (5rem desktop / 3.4375rem mobile, Tomi's ask,
   2026-09-08, round 2), reused verbatim here rather than through the variable itself
   since standalone film pages don't share index.html's :root scope. Round 14:
   background switched black -> var(--bg) (real bug, not a preference — this view's body
   text (.fd-title, .fd-credit) has always used the page's default --ink/--mut, which are
   dark-on-light tokens with no local override here, so it's been rendering low/no-contrast
   dark text on a black background). */
/* no horizontal padding by default — the hero and stills run full-bleed edge to edge.
   Text elements (.fd-close, .fd-title, .fd-credits) carry their own --edge padding
   instead, so THEY align to the wordmark's gutter while the images stay full width. */
.fd{display:none;position:relative;z-index:1;background:var(--bg);
  padding:5rem 0 clamp(72px,9vw,120px);
  transition:opacity .42s cubic-bezier(.33,0,.2,1),transform .42s cubic-bezier(.33,0,.2,1)}
@media(max-width:820px){.fd{padding-top:3.4375rem}}
.fd.on{display:block}
/* About has no images to bleed — its content (.about-intro/.about-credits, not the
   .fd-title/.fd-credits below) relies entirely on the parent's own padding for its
   left/right edges, so it gets --edge back here instead of staying at 0. */
.fd:has(.about-intro){padding-left:var(--edge,12px);padding-right:var(--edge,12px)}
.fd.leaving{opacity:0;transform:translateY(-40px);pointer-events:none}
@keyframes fdRiseHero{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes fdRise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* hero: the poster's own shape, not a hard-coded 16/9 — these films are anamorphic
   and a 16/9 box would crop them. --fd-ar is set per film from the still. On mobile,
   though, the deliberately wide anamorphic ratio squashes the poster down to a strip
   (an ultra-wide box scaled to a 375px-wide screen is short by definition) — visibly
   smaller than Sarang Song's poster, which was never anamorphic. --fd-ar-m (Tomi's
   ask, 2026-09-08, round 6) is an optional per-film MOBILE-only override to a taller
   16/9, set inline only on the 3 anamorphic films; object-fit:cover on the img crops
   the sides rather than distorting. Sarang Song carries no override — its own ratio
   is already close to 16/9 and needs none. */
/* --fd-maxw holds a sub-floor film to its poster's real width, so a 414p title is
   not blown across the full column while Burden and Tribes keep the full width. Now
   lives on .fd-hero-wrap (not .fd-hero itself) so .fd-close can sit absolutely
   positioned against the SAME box the poster actually renders at, sub-floor width
   included — .fd-hero alone can't host it (it's a <button>; nesting the close
   control's own <a> inside it would be invalid, interactive-in-interactive markup). */
.fd-hero-wrap{position:relative;width:100%;max-width:var(--fd-maxw,none)}
.fd-hero{position:relative;display:block;width:100%;
  border:none;padding:0;cursor:pointer;
  background:#0a0a0a;overflow:hidden;aspect-ratio:var(--fd-ar,16/9);
  animation:fdRiseHero .6s cubic-bezier(.33,0,.2,1) both}
@media(max-width:820px){.fd-hero{aspect-ratio:var(--fd-ar-m,var(--fd-ar,16/9))}}
.fd-hero img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:brightness(.9);transition:transform .6s cubic-bezier(.2,.7,.2,1),filter .4s}
.fd-hero:hover img{transform:scale(1.04);filter:brightness(1)}
/* hairline circle, never a filled button — the site has no filled buttons anywhere */
.fd-play{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:64px;height:64px;border-radius:50%;border:1px solid rgba(255,255,255,.6);
  display:flex;align-items:center;justify-content:center;opacity:.75;
  transition:opacity .4s cubic-bezier(.33,0,.2,1),border-color .4s cubic-bezier(.33,0,.2,1)}
.fd-hero:hover .fd-play{opacity:1;border-color:#fff}
.fd-play svg{width:15px;height:15px;fill:#fff;margin-left:3px}
@media(max-width:520px){.fd-play{width:52px;height:52px}}

/* title block, straight under the hero — tightened further to --edge (Tomi's ask,
   2026-09-08, round 4): was clamp(48px,6.5vw,88px) originally, then clamp(16px,2vw,24px);
   next rung down the site's own spacing scale is --edge (12px, per DECISIONS.md's
   reuse-existing-tokens precedent) rather than a new arbitrary value. */
.fd-title{margin-top:var(--edge,12px);padding-left:var(--edge,12px);padding-right:var(--edge,12px);
  font-size:clamp(22px,2.2vw,28px);font-weight:300;
  letter-spacing:.1em;text-transform:uppercase;line-height:1.25;
  animation:fdRise .55s cubic-bezier(.33,0,.2,1) .2s both}
/* title-to-credits gap tightened past --edge to 8px (Tomi's ask, 2026-09-08, round 7)
   -- the next rung down the site's 4px baseline grid; --edge itself has no smaller
   named token so this is a raw grid-aligned value rather than a new arbitrary one. */
.fd-credits{margin-top:8px;padding-left:var(--edge,12px);padding-right:var(--edge,12px)}
.fd-credit{font-size:clamp(11px,1vw,13px);font-weight:300;letter-spacing:1.6px;
  text-transform:uppercase;color:var(--mut);line-height:1.3}
/* director line — Proxima Nova Regular, one step up from the award line's Light,
   so it reads as the primary credit */
.fd-credit:nth-child(1){font-weight:400;
  animation:fdRise .55s cubic-bezier(.33,0,.2,1) .28s both}
.fd-credit:nth-child(2){animation:fdRise .55s cubic-bezier(.33,0,.2,1) .36s both}
.fd-credit:nth-child(n+3){animation:fdRise .55s cubic-bezier(.33,0,.2,1) .44s both}
/* tracking is already tight enough at 1.6px that the longest credit ("DIRECTORS
   BRENDAN MALLOY & EMMETT MALLOY") no longer needs a separate phone override to
   stay on one line (was .22em/.15em, the old em-based tracking). */
@media(max-width:520px){.fd-credit{font-size:10.5px}}

/* stills: a gallery, every tile cropped to the same 3:2 box so mismatched source
   aspect ratios (the stills arrive at whatever ratio the frame was shot/cropped at,
   anywhere from 450x188 to 500x281) stop reading as a jagged, uneven grid. object-fit
   crops rather than stretching, so no still gets distorted. */
.fd-stills{margin-top:clamp(24px,3vw,40px);display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(16px,2.2vw,28px);align-items:start}
/* two-up on a tablet; one-up on a phone, where two would render these 450px sources
   at ~170px and throw away most of what is in them */
@media(max-width:820px){.fd-stills{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.fd-stills{grid-template-columns:1fr}}
.fd-still{display:block;position:relative;width:100%;aspect-ratio:3/2;border:none;padding:0;
  background:#0a0a0a;cursor:pointer;overflow:hidden;
  opacity:0;transform:translateY(26px);
  transition:opacity .6s cubic-bezier(.33,0,.2,1) var(--d,0s),transform .7s cubic-bezier(.33,0,.2,1) var(--d,0s)}
.fd-still.reveal{opacity:1;transform:none}
.fd-still img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:brightness(.9);
  transition:transform .6s cubic-bezier(.2,.7,.2,1),filter .4s}
.fd-still:hover img{transform:scale(1.04);filter:brightness(1)}

/* close, overlaid on the poster's own top-right corner (Tomi's ask, 2026-09-08, round 3
   — was IN FLOW above the poster, which is what left the header-to-poster gap larger
   than --grid-top actually said). Positioned against .fd-hero-wrap, not .fd-hero
   itself, so it lands on the real rendered poster box even on a sub-floor (--fd-maxw)
   film. Same glyph and weight as the lightbox ×.
   Round 8 (Tomi's ask, 2026-09-08): dropped mix-blend-mode:difference here — it
   self-adapted, but not to a consistent brightness: difference inverts toward the
   BACKGROUND'S COMPLEMENT, not toward neutral white/black, so a saturated still (e.g.
   Burden's green forest) came out hue-tinted and dim instead of bright. The In Between
   only looked "right" because its top-right corner happened to be dark and fairly
   neutral, not because the technique was working correctly. Fixed color instead: solid
   white + a dark drop-shadow, so it reads at the same brightness over every poster
   regardless of footage color. */
.fd-close{position:absolute;top:12px;right:12px;z-index:2;
  display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;
  font-size:28px;line-height:1;cursor:pointer;color:#fff;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.6)) drop-shadow(0 0 5px rgba(0,0,0,.4));
  transition:opacity .3s cubic-bezier(.33,0,.2,1);
  animation:fdRise .55s cubic-bezier(.33,0,.2,1) both}
.fd-close:hover,.fd-close:focus-visible{opacity:.7}

/* ---- lightbox, image-gallery mode ---------------------------------------
   Stills reuse the same fixed layer as the video, so they inherit the landscape
   behaviour for free. */
.lb.gallery .frame,.lb.gallery .stage{display:none!important}
.lb .gal{display:none}
/* shrink-wraps the still so the chevrons sit just outside the picture rather than
   stranded at the far edges of a wide viewport */
.lb.gallery .gal{display:flex;flex-direction:column;gap:16px;align-items:center;
  position:relative;width:auto;max-width:100%;max-height:100%}
.lb .gal img{max-width:100%;max-height:72vh;width:auto;height:auto;object-fit:contain}
.lb .gcount{font-size:11px;letter-spacing:.24em;color:var(--mut);font-variant-numeric:tabular-nums}
/* +20% across the board (46->55, 38->46, icon 16->19, offsets scaled to match so the
   gap to the frame stays proportionally the same) -- shared by the stills gallery and
   the video-nav chevrons, both reuse this one rule on purpose. Mobile 46px also clears
   the 44px WCAG tap-target minimum, which 38px sat just under. */
.lb .gnav{position:absolute;top:50%;transform:translateY(-50%);width:55px;height:55px;
  background:none;border:none;color:#fff;opacity:.55;cursor:pointer;z-index:4;
  display:flex;align-items:center;justify-content:center;transition:opacity .2s ease}
.lb .gnav:hover,.lb .gnav:focus-visible{opacity:1}
.lb .gnav svg{width:19px;height:19px;fill:currentColor}
.lb .gprev{left:-70px}
.lb .gnext{right:-70px;transform:translateY(-50%) rotate(180deg)}
@media(max-width:640px){
  /* the still fills the width on a phone, so the chevrons ride the picture edge --
     offset stays -14px (NOT scaled with size): scaling it too pushed the left chevron's
     edge 1px past the viewport at 375px width (measured directly). Growing width alone
     extends the box further INTO the frame from the same anchored edge, which is safe;
     scaling the offset moved the anchored edge itself off-screen. */
  .lb .gnav{width:46px;height:46px}
  .lb .gprev{left:-14px} .lb .gnext{right:-14px}
  .lb .gal img{max-height:64vh}
}
@media (max-width:900px) and (orientation:landscape){
  .lb.gallery .gal{gap:8px;height:100%;justify-content:center}
  .lb .gal img{max-height:calc(100dvh - 46px)}
}
