/* Film ring on /film.html.
   Frames stand on a circle (preserve-3d, rotateX tilt, rotateY + translateZ),
   matching the sanctuary reel: 0.8s, cubic-bezier(0.22, 0.61, 0.2, 1).
   The front frame is larger and closer. Side pictures are dimmer.
   Opacity, filter, and overflow stay off the ring itself — any one of
   those flattens the 3D. Body overflow-x:hidden also flattens it in
   Safari and paints the side frames mirrored, so this page uses clip.
   Type, color, header, and footer stay in styles.css. */

html:has(.film-page),
body:has(.film-page) {
  overflow-x: clip;
}

.film-page {
  --film-spin: 0.8s;
  --ease-spin: cubic-bezier(0.22, 0.61, 0.2, 1);
  --film-base: #101012;
  --film-edge: #9a9a9a;
  --film-edge-strong: #d5d5d5;
  --hole: #0c0c0c;
  --hole-w: 0.4rem;
  --hole-h: 0.52rem;
  --stock-pad-x: 0.55rem;
  --stock-pad-y: var(--hole-h);
  --hole-gap: var(--hole-h);
  --sprocket-inset: calc(var(--stock-pad-x) + 0.16rem);
  --play: #fbf8f3;
  --play-ink: #1f2a22;
  --frame-w: min(12rem, 74vw);
  --window-h: calc((var(--frame-w) - (2 * var(--stock-pad-x))) / 2.39);
  --frame-h: calc(var(--window-h) + (6 * var(--hole-h)));
  /* Pull the circle back so rotateX does not swing a wide reel down
     the page. 0.75 keeps the front frame near the glass. Perspective
     is set from the same ratio the sanctuary uses (front z / 2600). */
  --pull-back: -0.75;
  --turn: 0deg;
  --step: 20deg;
  --radius: calc(var(--frame-w) * 2.836);
  --ring-perspective: calc(var(--frame-w) * 2.7);
  padding-top: calc(var(--header-h) + 2.5rem);
  min-height: 70svh;
  background-color: #0c0c0e;
  background-image:
    linear-gradient(to bottom, rgba(8, 8, 10, 0.72) 0%, rgba(8, 8, 10, 0.48) 40%, rgba(8, 8, 10, 0.62) 75%, rgba(8, 8, 10, 0.85) 100%),
    url("/images/backgrounds/film_strip_bg.jpg");
  background-image:
    linear-gradient(to bottom, rgba(8, 8, 10, 0.72) 0%, rgba(8, 8, 10, 0.48) 40%, rgba(8, 8, 10, 0.62) 75%, rgba(8, 8, 10, 0.85) 100%),
    image-set(
      url("/images/backgrounds/film_strip_bg.webp") type("image/webp"),
      url("/images/backgrounds/film_strip_bg.jpg") type("image/jpeg")
    );
  background-size: cover;
  background-position: center 30%;
  background-repeat: no-repeat;
}

.film-page .section-head {
  position: relative;
  z-index: 2;
  margin-bottom: 0.35rem;
}

.film-page .section-head h1,
.film-page .eyebrow {
  color: #fbf8f3;
}

.film-page .lede,
.film-page .films-status,
.film-page .films-fallback {
  color: rgba(251, 248, 243, 0.82);
}

.ring-stage {
  position: relative;
  z-index: 1;
  width: 100%;
  height: calc(var(--frame-h) * 1.72 + var(--frame-w) * 0.22 + 1.5rem);
  margin: 0 auto;
  perspective: var(--ring-perspective);
  perspective-origin: 50% 0%;
  overflow: visible;
  touch-action: pan-y;
  user-select: none;
}

.ring-stage::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0.35rem;
  width: min(34rem, 78%);
  height: 1.35rem;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at center, rgba(31, 42, 34, 0.16), rgba(31, 42, 34, 0) 72%);
  pointer-events: none;
}

.ring-tilt {
  position: absolute;
  inset: 0;
  overflow: visible;
  transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;
  transform: rotateX(-8deg);
}

.ring {
  position: absolute;
  left: 50%;
  top: calc(var(--frame-h) * 0.58 + 0.85rem);
  width: var(--frame-w);
  height: var(--frame-h);
  margin: 0;
  padding: 0;
  overflow: visible;
  transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;
  transform: translate(-50%, -50%) translateZ(calc(var(--radius) * var(--pull-back))) rotateY(var(--turn));
  transition: transform var(--film-spin) var(--ease-spin);
}

.ring.is-settling,
.ring.is-settling .cell,
.ring.is-settling .cell-face,
.ring.is-holding,
.ring.is-holding .cell,
.ring.is-holding .cell-face {
  transition: none;
}

.cell {
  position: absolute;
  inset: 0;
  margin: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transform: rotateY(calc(var(--i) * var(--step))) translateZ(var(--radius));
}

.cell:not(.is-front) {
  pointer-events: none;
}

.cell-face {
  height: 100%;
  transform: scale(1);
  transform-origin: center center;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transition: transform var(--film-spin) var(--ease-spin);
}

.cell.is-front .cell-face {
  transform: scale(1.12);
}

.cell:not(.is-front) .cell-window img {
  opacity: 0.5;
}

.cell-window img:not([src]) {
  visibility: hidden;
}

.filmstock {
  position: relative;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  min-width: 0;
  padding: var(--stock-pad-y) var(--stock-pad-x);
  background: var(--film-base);
  color: #fff;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  touch-action: manipulation;
  box-shadow:
    inset 0 1px 0 var(--film-edge),
    inset 0 -1px 0 var(--film-edge),
    inset 1px 0 0 rgba(154, 154, 154, 0.55),
    inset -1px 0 0 rgba(154, 154, 154, 0.55),
    0 16px 28px rgba(0, 0, 0, 0.38);
}

.cell.is-front .filmstock,
.filmstock:hover,
.filmstock:focus-visible {
  box-shadow:
    inset 0 0 0 2px var(--film-edge-strong),
    0 18px 32px rgba(0, 0, 0, 0.48);
}

.filmstock:focus-visible {
  outline: 2px solid var(--sage);
  outline-offset: 4px;
}

.sprockets {
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
  height: var(--hole-h);
  flex: none;
  width: calc(100% + (2 * var(--stock-pad-x)));
  margin-inline: calc(var(--stock-pad-x) * -1);
  padding-inline: var(--sprocket-inset);
}

.sprockets-top { margin-bottom: var(--hole-gap); }
.sprockets-bottom { margin-top: var(--hole-gap); }

.hole {
  width: var(--hole-w);
  height: var(--hole-h);
  flex: none;
  border-radius: 2px;
  background: var(--hole);
  box-shadow: 0 0 0 1px var(--film-edge);
}

.cell-window {
  position: relative;
  flex: none;
  width: 100%;
  min-width: 0;
  height: var(--window-h);
  background: #1a120c;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(62, 40, 18, 0.55);
}

.cell-window img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  border: 0;
  display: block;
  object-fit: cover;
  opacity: 1;
  -webkit-user-drag: none;
  filter: sepia(0.42) saturate(0.84) contrast(1.05) brightness(0.95);
  transition: filter 0.35s var(--ease), transform 0.55s var(--ease), opacity var(--film-spin) var(--ease-spin);
}

.filmstock:hover .cell-window img,
.filmstock:focus-visible .cell-window img {
  filter: sepia(0.1) saturate(1.02) contrast(1.04) brightness(1);
  transform: scale(1.045);
}

.cell-window::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to top, rgba(8, 8, 10, 0.78) 0%, rgba(8, 8, 10, 0.12) 46%, rgba(8, 8, 10, 0) 62%),
    rgba(61, 42, 24, 0.14);
}

.play {
  display: none;
  place-items: center;
  position: absolute;
  left: 50%;
  top: 42%;
  z-index: 2;
  width: clamp(1.85rem, 6vw, 2.85rem);
  height: clamp(1.85rem, 6vw, 2.85rem);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--play);
  box-shadow: 0 8px 18px rgba(12, 8, 4, 0.38);
  pointer-events: none;
  transition: background 0.2s var(--ease), transform 0.2s var(--ease);
}

.cell.is-front .play { display: grid; }

.filmstock:hover .play,
.filmstock:focus-visible .play {
  background: #fff;
  transform: translate(-50%, -50%) scale(1.06);
}

.play-icon {
  display: block;
  width: 0;
  height: 0;
  margin-left: 0.16rem;
  border-style: solid;
  border-width: 0.42rem 0 0.42rem 0.7rem;
  border-color: transparent transparent transparent var(--play-ink);
}

.cell-caption {
  position: absolute;
  z-index: 3;
  left: 0.55rem;
  right: 0.55rem;
  bottom: 0.4rem;
  margin: 0;
  color: #fff;
  font-family: var(--font-body);
  font-size: clamp(0.68rem, 1.5vw, 0.92rem);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: 0.01em;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 8px rgba(0, 0, 0, 0.75);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  pointer-events: none;
}

.film-actions {
  display: flex;
  justify-content: center;
  position: relative;
  z-index: 2;
  margin: 0.35rem 0 0.35rem;
}

.film-projector {
  position: relative;
  z-index: 1;
  display: block;
  width: 7.5rem;
  max-width: 46vw;
  height: auto;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  line-height: 0;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  user-select: none;
}

.projector-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.film-projector:hover:not(:disabled) .projector-svg {
  filter: brightness(1.12);
}

.film-projector:active:not(:disabled) .projector-svg {
  transform: translateY(1px);
}

.film-projector:focus-visible {
  outline: 2px solid var(--on-primary);
  outline-offset: 4px;
  border-radius: 0.75rem;
}

.film-projector:disabled {
  opacity: 0.45;
  cursor: default;
}

/* Beam sits outside the button so a browser that clips button overflow
   still lets the cone reach the ring. It does not take clicks. */
.projector-beam {
  position: absolute;
  z-index: 0;
  left: 50%;
  top: 11%;
  width: min(calc(var(--frame-w) * 1.35), 86vw);
  height: calc(var(--frame-h) * 0.95);
  transform: translate(-50%, -100%);
  pointer-events: none;
}

.projector-beam-core {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transform-origin: 50% 100%;
  pointer-events: none;
  background:
    linear-gradient(to top,
      rgba(255, 248, 230, 0.95) 0%,
      rgba(255, 220, 160, 0.72) 10%,
      rgba(255, 196, 110, 0.32) 36%,
      rgba(255, 186, 90, 0.1) 68%,
      rgba(255, 186, 90, 0) 100%);
  clip-path: polygon(42% 100%, 58% 100%, 84% 0%, 16% 0%);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
  mix-blend-mode: screen;
}

.film-actions:has(.film-projector.is-flashing) .projector-beam-core {
  animation: projector-beam 0.52s linear;
}

.film-projector.is-flashing .projector-lamp {
  animation: projector-lamp 0.52s linear;
}

.film-page:has(.film-projector.is-flashing) .cell.is-front .cell-window::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 46%,
    rgba(255, 236, 200, 0.62) 0%,
    rgba(255, 200, 120, 0.24) 46%,
    rgba(255, 186, 90, 0) 74%);
  mix-blend-mode: screen;
  animation: projector-glow 0.52s linear forwards;
}

@keyframes projector-beam {
  0%   { opacity: 0; transform: scaleY(0.42); }
  7%   { opacity: 1; transform: scaleY(1); }
  13%  { opacity: 0.06; transform: scaleY(0.9); }
  20%  { opacity: 0.95; transform: scaleY(1); }
  28%  { opacity: 0.16; }
  38%  { opacity: 1; }
  66%  { opacity: 0.62; }
  100% { opacity: 0; transform: scaleY(1); }
}

@keyframes projector-lamp {
  0%   { filter: brightness(1); }
  7%   { filter: brightness(2.5); }
  13%  { filter: brightness(0.35); }
  20%  { filter: brightness(2.3); }
  28%  { filter: brightness(0.5); }
  38%  { filter: brightness(2.6); }
  66%  { filter: brightness(1.25); }
  100% { filter: brightness(1); }
}

@keyframes projector-glow {
  0%   { opacity: 0; }
  7%   { opacity: 1; }
  13%  { opacity: 0.12; }
  20%  { opacity: 0.95; }
  28%  { opacity: 0.22; }
  38%  { opacity: 1; }
  66%  { opacity: 0.55; }
  100% { opacity: 0; }
}

.films-status,
.films-fallback {
  width: min(40rem, 100%);
  margin: 0.75rem auto 0;
  text-align: center;
  color: var(--muted);
  font-family: var(--font-body);
}

.films-status.is-error {
  color: var(--status-error-fg);
}

.film-page .films-status.is-error {
  color: #ffb4a8;
}

.films-status:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}

@media (max-width: 719px) {
  .film-projector {
    width: min(6.5rem, 40vw);
  }

  .film-page {
    background-image:
      linear-gradient(to bottom, rgba(8, 8, 10, 0.72) 0%, rgba(8, 8, 10, 0.48) 40%, rgba(8, 8, 10, 0.62) 75%, rgba(8, 8, 10, 0.85) 100%),
      url("/images/backgrounds/film_strip_bg-960w.jpg");
    background-image:
      linear-gradient(to bottom, rgba(8, 8, 10, 0.72) 0%, rgba(8, 8, 10, 0.48) 40%, rgba(8, 8, 10, 0.62) 75%, rgba(8, 8, 10, 0.85) 100%),
      image-set(
        url("/images/backgrounds/film_strip_bg-960w.webp") type("image/webp"),
        url("/images/backgrounds/film_strip_bg-960w.jpg") type("image/jpeg")
      );
  }
}

@media (min-width: 720px) {
  .film-page { --frame-w: 16.5rem; }
}

@media (min-width: 1100px) {
  .film-page { --frame-w: 21rem; }
}

@media (min-width: 1440px) {
  .film-page { --frame-w: 24rem; }
}

@media (max-width: 420px) {
  .film-page {
    --hole-w: 0.26rem;
    --hole-h: 0.36rem;
    --stock-pad-x: 0.36rem;
    --frame-w: min(10.75rem, 70vw);
  }

  .play-icon {
    border-width: 0.34rem 0 0.34rem 0.56rem;
    margin-left: 0.12rem;
  }

  .cell-caption {
    left: 0.35rem;
    right: 0.35rem;
    bottom: 0.22rem;
    font-size: 0.64rem;
  }

  .film-projector {
    width: min(5.6rem, 42vw);
  }
}

@media (prefers-reduced-motion: reduce) {
  .film-page { --film-spin: 0s; }

  .ring-stage {
    height: auto;
    perspective: none;
  }

  .ring-stage::before { display: none; }

  .ring-tilt {
    position: relative;
    inset: auto;
    transform: none;
  }

  .ring {
    position: relative;
    left: auto;
    top: auto;
    width: min(42rem, 100%);
    height: auto;
    transform: none;
  }

  .cell {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    transform: none;
    opacity: 0;
    pointer-events: none;
  }

  .cell.is-front {
    position: relative;
    opacity: 1;
    pointer-events: auto;
    transition: opacity 0.25s linear;
  }

  .cell.is-front.is-fading { opacity: 0; }

  .cell-face,
  .filmstock {
    height: auto;
    transform: none;
  }

  .cell-window {
    height: auto;
    aspect-ratio: 2.39 / 1;
  }

  .cell:not(.is-front) .cell-window img { opacity: 1; }

  .ring,
  .cell-face,
  .cell-window img,
  .play {
    transition: none;
  }

  .projector-beam-core,
  .film-projector.is-flashing .projector-lamp,
  .film-page:has(.film-projector.is-flashing) .cell.is-front .cell-window::before {
    animation: none;
    opacity: 0;
  }

  .filmstock:hover .cell-window img,
  .filmstock:focus-visible .cell-window img {
    transform: none;
  }

  .filmstock:hover .play,
  .filmstock:focus-visible .play {
    transform: translate(-50%, -50%);
  }
}

/* On-page player. The ring underneath is unchanged.
   Scroll lock pins the body in place. overflow:hidden is avoided here
   because it flattens the 3D reel in Safari. */
html.is-film-playing:has(.film-page) {
  overscroll-behavior: none;
}

.film-player {
  --film-player-max: calc(100svh - 4.75rem - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
  position: fixed;
  inset: 0;
  z-index: 500;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  max-height: 100svh;
  margin: 0;
  padding:
    calc(0.65rem + env(safe-area-inset-top, 0px))
    env(safe-area-inset-right, 0px)
    calc(0.65rem + env(safe-area-inset-bottom, 0px))
    env(safe-area-inset-left, 0px);
  border: 0;
  background: rgba(8, 8, 10, 0.92);
  opacity: 0;
  overscroll-behavior: none;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 0.2s linear;
}

.film-player[hidden] {
  display: none !important;
}

.film-player.is-open {
  opacity: 1;
}

.film-player-panel {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  width: min(100%, calc(var(--film-player-max) * 16 / 9));
  max-width: 100%;
  touch-action: manipulation;
  transform: scale(0.985);
  transition: transform 0.2s cubic-bezier(0.22, 0.61, 0.2, 1);
}

.film-player.is-open .film-player-panel {
  transform: none;
}

.film-player-close {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  margin: 0 0 0.4rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #fbf8f3;
  color: #1f2a22;
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.38);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.film-player-close span {
  display: block;
  width: 0.95rem;
  height: 0.95rem;
  background:
    linear-gradient(#1f2a22, #1f2a22) center / 100% 2px no-repeat,
    linear-gradient(#1f2a22, #1f2a22) center / 2px 100% no-repeat;
  transform: rotate(45deg);
}

.film-player-close:hover,
.film-player-close:focus-visible {
  background: #fff;
}

.film-player-close:focus-visible {
  outline: 2px solid #fbf8f3;
  outline-offset: 3px;
}

.film-player-stage {
  align-self: stretch;
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}

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

.film-player-missing {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  margin: 0;
  padding: 1.25rem;
  background: #1a120c;
  color: #fbf8f3;
  border: 3px dashed #d5d5d5;
  text-align: center;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.45;
}

@media (min-width: 720px) {
  .film-player {
    --film-player-max: calc(100svh - 6rem - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
    padding:
      calc(1.25rem + env(safe-area-inset-top, 0px))
      calc(1.25rem + env(safe-area-inset-right, 0px))
      calc(1.25rem + env(safe-area-inset-bottom, 0px))
      calc(1.25rem + env(safe-area-inset-left, 0px));
  }

  .film-player-panel {
    width: min(90vw, 100%, calc(var(--film-player-max) * 16 / 9));
  }
}

@media (prefers-reduced-motion: reduce) {
  .film-player,
  .film-player-panel {
    transition: none;
  }

  .film-player-panel {
    transform: none;
  }
}
