/* ==========================================================================
   w-film — the Carly film: poster stage, invitation button, and theater.
   Shared component. Opt in with  sharedCSS: [w-film]  +  sharedJS: [w-film]

   Doctrine applied:
   - Restraint. One play affordance, one duration chip, one hairline frame.
     Nothing here is decorative; every element answers "what is this for".
   - Compositor properties only (transform / opacity / filter). Nothing here
     animates width, height or top.
   - prefers-reduced-motion kills every transition and the hover preview.

   TOKEN NOTES
   - --w-r-full is 50%, NOT a pill. That is correct here because .w-film__play
     is a SQUARE element and wants a circle. Never put it on a wide element.
   - The THEATER block below uses LITERAL colours on purpose. A position:fixed
     overlay inherits ROOT tokens, so a token-driven skin resolves to the dark
     theme even when opened from a .cz-light band, and renders white-on-white.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · THE POSTER STAGE
   Frame chrome is pattern-lifted from .ephow__media (experts.css) so the film
   reads as the same family of object as every other media frame on the site.
   -------------------------------------------------------------------------- */

.w-film {
  --w-film-max: 1100px;
  max-width: var(--w-film-max);
  margin-inline: auto;
  width: 100%;
}

.w-film__poster {
  /* Reset the button chrome; this is a surface, not a control strip. */
  display: block;
  position: relative;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 1px solid var(--w-line);
  background: var(--w-glass-fill);
  border-radius: var(--w-r-2xl);
  overflow: hidden;
  cursor: pointer;
  aspect-ratio: 16 / 9;
  box-shadow: var(--w-shadow-lg);
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform var(--w-dur-slow) var(--w-ease),
    box-shadow var(--w-dur-slow) var(--w-ease);
}

/* The bright rim where light would catch the top edge. */
.w-film__poster::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: inset 0 1px 0 var(--w-glass-rim-top);
  z-index: 3;
}

.w-film__still,
.w-film__loop {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.w-film__loop {
  opacity: 0;
  z-index: 1;
  transition: opacity 520ms var(--w-ease);
}

.w-film__loop.is-live { opacity: 1; }

/* A gentle bottom-weighted scrim so the play mark and the duration chip hold
   their contrast against any frame the film lands on. */
.w-film__scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    radial-gradient(58% 58% at 50% 50%, rgba(6,4,14,.30) 0%, rgba(6,4,14,0) 70%),
    linear-gradient(to top, rgba(6,4,14,.46) 0%, rgba(6,4,14,0) 42%);
  transition: opacity var(--w-dur-slow) var(--w-ease);
}

/* --- the play affordance -------------------------------------------------
   Promoted from .dxv__play (docs.css), which was the only real poster+play UI
   on the site. Kept: the 50% circle, the 2px optical nudge on the glyph, the
   1.08 hover scale. Added: the DS7 glass skin and the rim-light lift.
   -------------------------------------------------------------------------- */
.w-film__play {
  position: absolute;
  z-index: 4;
  top: 50%;
  left: 50%;
  width: 72px;
  height: 72px;
  margin: -36px 0 0 -36px;
  display: grid;
  place-items: center;
  /* Square element → --w-r-full (50%) is the correct circle here. */
  border-radius: var(--w-r-full);
  background: rgba(255,255,255,.94);
  /* THE 2px RING IS LOAD-BEARING, NOT DECORATION. Do not remove it to tidy the
     shadow stack, and do not thin it below .55 alpha.

     A solid white mark assumes a dark poster. The shipped Carly poster runs
     light-grey on the left, lavender through the middle and near-black on the
     right, so a bare white disc measured 1.74:1 at its worst angle — under the
     3:1 bar for UI components (PREMIUM_DOCTRINE §5).

     Measured, not assumed. Three candidates were composited against the real
     poster and sampled at 180 points around the mark:
       white disc, no ring        1.74:1  FAIL
       brand disc, no ring        1.00:1  FAIL  (collides with the lavender)
       white disc + dark ring     4.63:1  PASS
     WCAG 1.4.11 is satisfied if ANY part of the component clears 3:1 against
     the adjacent colour, so this works everywhere by design: on light ground
     the ring carries it, on dark ground the disc does. Sweep found .55 is the
     floor (3.41:1); .85 is used for headroom on posters we haven't seen yet. */
  box-shadow:
    0 0 0 2px rgba(6,4,14,.85),
    0 10px 30px rgba(6,4,14,.34),
    inset 0 1px 0 rgba(255,255,255,1);
  transition:
    transform var(--w-dur-slow) var(--w-ease),
    box-shadow var(--w-dur-slow) var(--w-ease);
}

.w-film__play .w-icon {
  width: 26px;
  height: 26px;
  color: var(--w-charcoal);
  /* Optical centring: a triangle's visual centre sits left of its box centre. */
  margin-left: 3px;
}

/* NOTE: a `posterTone: light` variant that swapped the disc to a brand fill was
   built and then DELETED — it measured 1.00:1 against the poster's lavender
   band, worse than the white disc it replaced. The ring above solves it for
   every ground, so no per-poster configuration is needed. Don't re-add it. */

/* --- the duration contract ------------------------------------------------ */
.w-film__dur {
  position: absolute;
  z-index: 4;
  right: var(--w-s-5);
  bottom: var(--w-s-5);
  padding: 6px 12px;
  border-radius: var(--w-r-pill);          /* wide element → pill, never r-full */
  font-family: var(--w-font-kicker);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums lining-nums;
  color: #fff;
  background: rgba(6,4,14,.52);
  border: 1px solid rgba(255,255,255,.18);
  backdrop-filter: blur(8px);
}

/* --- hover / focus: rim-light lift, never a colour flip ------------------- */
@media (hover: hover) {
  .w-film__poster:hover {
    transform: translateY(-3px);
    box-shadow: 0 28px 64px -22px rgba(111,95,224,.50), var(--w-shadow-lg);
  }
  .w-film__poster:hover .w-film__play {
    transform: scale(1.08);
    box-shadow:
      0 0 0 1px rgba(6,4,14,.24),
      0 16px 40px rgba(6,4,14,.42),
      inset 0 1px 0 rgba(255,255,255,1);
  }
  .w-film__poster:hover .w-film__scrim { opacity: .72; }
}

.w-film__poster:focus-visible {
  outline: 2px solid var(--w-purple-ink);
  outline-offset: 3px;
}

/* --- light-band skin ------------------------------------------------------
   On .cz-light real glass is a lie. Layered elevation instead: brand-tinted
   shadow (never grey) and a hairline brand inner border. The aura behind the
   frame is what makes the elevation legible on a flat ground.
   -------------------------------------------------------------------------- */
.cz-light .w-film__poster {
  border-color: rgba(111,95,224,.20);
  box-shadow:
    0 26px 60px -22px rgba(111,95,224,.45),
    inset 0 0 0 1px rgba(111,95,224,.10);
}

.cz-light .w-film { position: relative; isolation: isolate; }

.cz-light .w-film::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 8% 6% -6% 6%;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(111,95,224,.26) 0%, rgba(111,95,224,0) 72%);
  filter: blur(38px);
  pointer-events: none;
}

@media (hover: hover) {
  .cz-light .w-film__poster:hover {
    box-shadow:
      0 34px 74px -22px rgba(111,95,224,.58),
      inset 0 0 0 1px rgba(111,95,224,.18);
  }
}

/* --------------------------------------------------------------------------
   2 · THE INVITATION (inline duration chip inside a .w-btn)
   -------------------------------------------------------------------------- */

.w-film-dur {
  margin-left: 2px;
  padding: 3px 8px;
  border-radius: var(--w-r-pill);
  font-family: var(--w-font-kicker);
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums lining-nums;
  background: rgba(255,255,255,.12);
  border: 1px solid var(--w-glass-line-bright);
  line-height: 1;
}

.cz-light .w-film-dur {
  background: rgba(111,95,224,.10);
  border-color: rgba(111,95,224,.22);
  color: var(--w-purple-ink);
}

/* --------------------------------------------------------------------------
   3 · THE THEATER
   LITERAL COLOURS ONLY in this block — see the header note.
   -------------------------------------------------------------------------- */

.w-film-theater {
  position: fixed;
  inset: 0;
  z-index: 1200;                 /* above --w-z-modal (500) and the nav */
  display: grid;
  place-items: center;
  padding: clamp(16px, 4vw, 56px);
}

.w-film-theater[hidden] { display: none; }

.w-film-theater__scrim {
  position: absolute;
  inset: 0;
  background: rgba(6, 4, 14, .74);
  backdrop-filter: blur(16px) saturate(70%);
  -webkit-backdrop-filter: blur(16px) saturate(70%);
  opacity: 0;
  transition: opacity 320ms var(--w-ease);
}

.w-film-theater.is-open .w-film-theater__scrim { opacity: 1; }

.w-film-theater__stage {
  position: relative;
  width: 100%;
  max-width: min(1200px, 100%);
  outline: none;
}

.w-film-theater__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: clamp(14px, 2vw, 26px);
  overflow: hidden;
  background: #000;
  box-shadow: 0 50px 120px -30px rgba(0, 0, 0, .86);
  transform-origin: top left;
  opacity: 0;
  /* transform + opacity are written by w-film.js for the FLIP. The transition
     is armed by .is-animating so the initial delta lands instantly. */
}

.w-film-theater.is-animating .w-film-theater__frame {
  transition:
    transform 480ms cubic-bezier(.22, .9, .3, 1),
    opacity 300ms var(--w-ease);
}

.w-film-theater.is-open .w-film-theater__frame { opacity: 1; }

.w-film-theater__slot,
.w-film-theater__slot iframe,
.w-film-theater__slot video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* --- close: appears on pointer move, fades after stillness --------------- */
.w-film-theater__close {
  position: absolute;
  top: -52px;
  right: 0;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;                       /* square element → circle */
  border: 1px solid rgba(255, 255, 255, .18);
  background: rgba(255, 255, 255, .08);
  backdrop-filter: blur(10px);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition:
    opacity 240ms var(--w-ease),
    transform 240ms var(--w-ease),
    background 240ms var(--w-ease);
}

.w-film-theater.is-open.is-chrome .w-film-theater__close { opacity: 1; }
.w-film-theater__close:hover { background: rgba(255, 255, 255, .16); transform: scale(1.08); }
.w-film-theater__close:focus-visible { opacity: 1; outline: 2px solid #fff; outline-offset: 3px; }
.w-film-theater__close .w-icon { width: 18px; height: 18px; }

/* Below the point where a -52px offset would collide with the viewport edge,
   the close mark moves inside the frame.  Derivation: stage padding at 480px
   is clamp(16px,4vw,56px) = 19.2px, which is < 52px + 40px, so the button
   would be clipped off the top of the screen. */
@media (max-width: 700px) {
  .w-film-theater__close {
    top: auto;
    bottom: calc(100% + 12px);
    right: 0;
    width: 36px;
    height: 36px;
  }
}

/* --- unmute, deep-link only ----------------------------------------------
   Deliberately loud for a piece of chrome, because it is answering a question
   the visitor is already asking ("why is this silent?"). It removes itself on
   first tap and never appears on a normal click-to-open. */
.w-film-theater__unmute {
  position: absolute;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 20px;
  border-radius: var(--w-r-pill);            /* wide element → pill, never r-full */
  border: 1px solid rgba(255, 255, 255, .28);
  background: rgba(6, 4, 14, .72);
  backdrop-filter: blur(10px);
  color: #fff;
  font-family: var(--w-font);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  z-index: 4;
  transition: background var(--w-dur) var(--w-ease), transform var(--w-dur) var(--w-ease);
}

.w-film-theater__unmute[hidden] { display: none; }
.w-film-theater__unmute:hover { background: rgba(6, 4, 14, .88); transform: translateX(-50%) scale(1.04); }
.w-film-theater__unmute:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.w-film-theater__unmute .w-icon { width: 15px; height: 15px; }

@media (max-width: 480px) {
  .w-film-theater__unmute { bottom: 14px; font-size: 13px; padding: 9px 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .w-film-theater__unmute { transition: none; }
  .w-film-theater__unmute:hover { transform: translateX(-50%); }
}

/* Body lock. overflow:hidden ONLY — no position:fixed, no scrollTo, no scroll
   guard. Standing rule: a scroll-position guard on a page with heavy embeds
   always becomes the bug it was meant to prevent. The padding-right is
   scrollbar compensation (a layout nudge), written by w-film.js. */
html.w-film-lock,
body.w-film-lock {
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   4 · REDUCED MOTION — mandatory, no exceptions.
   Fail open: no FLIP, no hover preview, final state immediately.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .w-film__poster,
  .w-film__play,
  .w-film__scrim,
  .w-film__loop,
  .w-film-theater__scrim,
  .w-film-theater__frame,
  .w-film-theater__close {
    transition: none !important;
  }
  .w-film__poster:hover { transform: none; }
  .w-film__poster:hover .w-film__play { transform: none; }
  .w-film__loop { display: none; }
  .w-film-theater__close { opacity: 1; }
}

/* --------------------------------------------------------------------------
   5 · BREAKPOINTS
   Verified against the supported eight: 1920 · 1440 · 1024 · 768 · 480 · 375 ·
   360 · 320. The stage is width-driven with aspect-ratio, so it cannot
   overflow horizontally at any of them.
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {
  .w-film__play { width: 60px; height: 60px; margin: -30px 0 0 -30px; }
  .w-film__play .w-icon { width: 22px; height: 22px; }
  .w-film__dur { right: var(--w-s-4); bottom: var(--w-s-4); font-size: 10px; padding: 5px 10px; }
  .w-film__poster { border-radius: var(--w-r-xl); }
}

@media (max-width: 480px) {
  .w-film__play { width: 52px; height: 52px; margin: -26px 0 0 -26px; }
  .w-film__play .w-icon { width: 19px; height: 19px; }
  .w-film__poster { border-radius: var(--w-r-lg); }
  /* Below 480 the aura reads as a smudge rather than elevation. */
  .cz-light .w-film::before { display: none; }
}
