/* work-film.css: the Selected-work films. Film session (2026-10-12), built on the c1 video session's stand-in.
   Two parts: (1) the card preview (posters, the visible pause mark), (2) the pop-up player, a port of goxnp.com's
   assets/xnp-video.css (see work-film.js for the behaviour). hero.css already sizes `.card__media video` (absolute,
   cover, radius inherit) and lifts the tag + arrow above it. */

/* ---- 1. the card -------------------------------------------------------------------------------------------- */

/* Posters: the same box, fit and radius as the video, so the handover cannot shift a pixel. */
.card__media .card__poster {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%;
  border-radius: inherit; pointer-events: none;
  transition: opacity var(--theme-t) var(--theme-ease);
}
/* light poster in light mode, dark poster in dark mode, cross-faded on the shared theme transition */
.card__poster--dark { opacity: 0; }
:root[data-theme="dark"] .card__poster--dark { opacity: 1; }
:root[data-theme="dark"] .card__poster--light { opacity: 0; }
/* the first video frame is painted: posters go at once, no fade, until the page reloads */
.card__media.is-live .card__poster { display: none; }
.card__media .card__poster ~ .card__tag, .card__media .card__poster ~ .card__arrow { z-index: 1; }

/* THE PAUSE MARK (owner, 2026-10-12 night). Only a pause the visitor made ON PURPOSE shows it (the phone tap, the
   press-and-hold); a pause the page made (the pull letting go, leaving the band, the pop-up) shows nothing, and the
   picture itself never dims or moves. work-film.js puts .is-flash on for 2.5 s: the mark comes in quickly, stays,
   then fades away on a slow, smooth ease-in-out. Only transitions on a class change: nothing runs while still. */
.card__pause {
  position: absolute; left: 14px; bottom: 14px; z-index: 1; width: 34px; height: 34px; border-radius: 999px;
  display: grid; place-items: center; background: var(--tab-bg); color: var(--tab-text); pointer-events: none;
  opacity: 0; transform: scale(.92);
  transition: opacity 700ms var(--ix-ease), transform 700ms var(--ix-ease);   /* the way out: slow and smooth */
}
.card__pause svg { width: 14px; height: 14px; fill: currentColor; }
.card__media.is-flash .card__pause {
  opacity: 1; transform: none;
  transition: opacity 200ms var(--ix-ease), transform 260ms var(--ease-out);  /* the way in: at once */
}
@media (prefers-reduced-motion: reduce) {
  .card__pause, .card__media.is-flash .card__pause { transform: none; transition: opacity 300ms linear; }
}

/* While the film is open the page behind is still (work-film.js stillPage): no scrolling, and the scrollbar's room
   is kept so nothing shifts sideways. */
:root.wf-film-open { overflow: hidden; scrollbar-gutter: stable; }

/* ---- 2. the pop-up player: goxnp.com assets/xnp-video.css, on this page's tokens ---------------------------- */

/* Width set by work-film.js (--xv-w, XNP sizeFilm); the frame takes the film's own shape (--xv-ar: 4:3, Konnect
   16:9). The fallback is only for the instant before the script has measured. */
.xv { padding: 0; border: 0; background: transparent; overflow: visible; max-width: none; max-height: none;
      width: var(--xv-w, min(66.667vw, calc(100vw - 3rem), calc((100dvh - 3rem) * 4 / 3))); }
/* the dim follows the page theme: ink over paper in light, deeper black in dark */
.xv::backdrop { background: rgba(20, 22, 26, .62); backdrop-filter: blur(4px); }
:root[data-theme="dark"] .xv::backdrop { background: rgba(0, 0, 0, .72); }
.xv__frame { position: relative; aspect-ratio: var(--xv-ar, 4 / 3); border-radius: var(--radius-card); overflow: hidden;
             background: var(--paper-2); box-shadow: 0 2rem 6rem rgba(10, 11, 13, .45);
             transition: background-color var(--theme-t) var(--theme-ease); }
.xv__frame video { display: block; width: 100%; height: 100%; object-fit: contain; background: var(--paper-2);
                   transition: background-color var(--theme-t) var(--theme-ease); }

/* X: top right of the SCREEN, 16px in, 44px round (numbers must match XGAP/XSIZE in work-film.js). Paper on the dim. */
.xv__x { position: fixed; top: max(16px, env(safe-area-inset-top)); right: max(16px, env(safe-area-inset-right));
         width: 44px; height: 44px; border-radius: 999px; display: grid; place-items: center; cursor: pointer;
         border: 1px solid color-mix(in srgb, var(--paper) 60%, transparent); background: var(--paper); color: var(--ink);
         z-index: 2; box-shadow: 0 .5rem 1.5rem rgba(10, 11, 13, .25); opacity: 1;
         transition: background-color 180ms ease, color var(--theme-t) var(--theme-ease), transform 220ms var(--ease-out), opacity 220ms ease; }
.xv__x:hover { background: var(--paper-2); transform: scale(1.05); }
/* nothing over the film while it plays; the X is invisible, not absent (its corner still counts as the film) */
.xv.is-bare .xv__x { opacity: 0; }
.xv.is-bare.is-out .xv__x { opacity: 1; }
.xv.is-bare .xv__x:focus-visible { opacity: 1; pointer-events: auto; }
/* the tap catcher over the bare film (hidden while the controls are up, so the next tap reaches them) */
.xv-tap { position: absolute; inset: 0; z-index: 4; display: block; width: 100%; height: 100%; margin: 0; padding: 0;
          border: 0; background: transparent; cursor: pointer; -webkit-tap-highlight-color: transparent;
          appearance: none; -webkit-appearance: none; }
.xv-tap[hidden] { display: none; }

.xv__wait { position: absolute; left: 50%; top: 50%; width: 2.5rem; height: 2.5rem; margin: -1.25rem 0 0 -1.25rem;
            border-radius: 999px; border: 3px solid color-mix(in srgb, var(--ink) 20%, transparent); border-top-color: var(--ink);
            pointer-events: none; opacity: 0; transition: opacity 200ms ease; }
.xv.is-waiting .xv__wait { opacity: 1; animation: xv-spin 800ms linear infinite; }
@keyframes xv-spin { to { transform: rotate(360deg); } }

/* open: 280ms (the film starts as it lands), close: 200ms. The dialog itself only fades (a transform on it would
   become the fixed X's containing block). */
@media (prefers-reduced-motion: no-preference) {
  .xv[open] { animation: xv-fade 280ms ease-out; }
  .xv[open] .xv__frame { animation: xv-in 280ms var(--ease-out); }
  .xv[open]::backdrop { animation: xv-fade 280ms ease-out; }
  .xv.xv--out { animation: xv-fade-out 200ms ease-in both; }
  .xv.xv--out .xv__frame { animation: xv-out 200ms cubic-bezier(.4, 0, 1, 1) both; }
  .xv.xv--out::backdrop { animation: xv-fade-out 200ms ease-in both; }
}
@media (prefers-reduced-motion: reduce) { .xv__x { transition: none; } }
@keyframes xv-in { from { opacity: 0; transform: translateY(14px) scale(.975); } to { opacity: 1; transform: none; } }
@keyframes xv-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes xv-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(10px) scale(.985); } }
@keyframes xv-fade-out { from { opacity: 1; } to { opacity: 0; } }
