/* ==========================================================================
   Film and TV (its own agent). Every rule is scoped to #film.

   The page's one night: a small cinema after dark. Nine lit poster cases run
   along the front; above them an orchid marquee, ringed with warm bulbs,
   spells out the line I love from whichever poster is picked. Colour comes
   from the posters and from light: the bulbs, the lit board, the warm light
   under the marquee, the glow a case throws on the wall in its own colour,
   and its reflection in the wet pavement.

   Picking is native: each poster is a <label> for a visually hidden radio, so
   click, tap and arrow keys work with no script; gallery.js adds hover and
   snaps the letters onto the board's rails.
   ========================================================================== */

#film {
  --gap: clamp(9px, 1vw, 18px);              /* between poster cases */
  --case: clamp(3px, .3vw, 5px);             /* the case's frame */
  --frame: clamp(15px, 1.8vw, 32px);         /* the marquee's painted frame */
  --marq: clamp(15px, 2.7vw, 54px);          /* marquee letter size */
  --lh: 1.16;                                /* letter rows; the rails follow it */
  --board-pad: clamp(12px, 1.6vw, 30px);
  --wall-gap: clamp(30px, 3.6vw, 60px);      /* marquee to posters */
  --bulb: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Cdefs%3E%3CradialGradient id='g' cx='.4' cy='.36' r='.68'%3E%3Cstop offset='0' stop-color='%23fffef9'/%3E%3Cstop offset='.38' stop-color='%23fff1cc'/%3E%3Cstop offset='.78' stop-color='%23ffc966'/%3E%3Cstop offset='1' stop-color='%23f0982c'/%3E%3C/radialGradient%3E%3C/defs%3E%3Ccircle cx='20' cy='20' r='10.6' fill='%237d1449' fill-opacity='.5'/%3E%3Ccircle cx='20' cy='20' r='8.4' fill='url(%23g)'/%3E%3C/svg%3E");
  position: relative;
  padding-block: clamp(64px, 7.2vw, 128px) clamp(76px, 8vw, 136px);
  overflow: clip;                             /* light from the end cases stays inside (and bounds paint) */
  contain: layout;                            /* nothing in here relayouts the page */
}

#film .film__front {
  width: min(100% - 2 * var(--gutter), 1680px);
  margin-inline: auto;
}

/* --------------------------------------------------------------------------
   The marquee
   -------------------------------------------------------------------------- */
#film .film__marquee {
  position: relative;
  padding: var(--frame);
  border-radius: calc(var(--frame) * .42);
  background: linear-gradient(180deg, #f772b6 0%, var(--orchid) 42%, #e04e98 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .38),
    inset 0 -2px 0 rgba(110, 16, 64, .32),
    0 2px 0 rgba(8, 5, 22, .5),
    0 40px 70px -36px rgba(4, 2, 14, .9);
}
/* Bulbs: a row along the top and the bottom, a column down each side.
   "space" spreads them evenly, so none is ever cut in half. */
#film .film__marquee::before,
#film .film__marquee::after {
  content: ""; position: absolute; pointer-events: none;
}
#film .film__marquee::before {
  inset: 0;
  background:
    var(--bulb) top / var(--frame) var(--frame) space no-repeat,
    var(--bulb) bottom / var(--frame) var(--frame) space no-repeat;
}
#film .film__marquee::after {
  inset: var(--frame) 0;
  background:
    var(--bulb) left / var(--frame) var(--frame) no-repeat space,
    var(--bulb) right / var(--frame) var(--frame) no-repeat space;
}

/* The lit letter board: warm, brightest in the middle like a real light box */
#film .film__board {
  position: relative;
  display: grid; align-items: center;
  padding: var(--board-pad) calc(var(--board-pad) * 1.4);
  border-radius: 3px;
  background: radial-gradient(130% 160% at 50% 42%, #fffdf6 0%, #fff5e1 55%, #fbe7c6 100%);
  box-shadow:
    inset 0 3px 10px -2px rgba(110, 24, 70, .38),
    inset 0 0 0 1px rgba(110, 24, 70, .3);
}
/* The rails the letters ride on. Drawn once gallery.js has snapped every
   line onto them (without it the lines centre and the rails stay off). */
#film .film__board.is-railed::before {
  content: ""; position: absolute; pointer-events: none;
  left: calc(var(--board-pad) * .55); right: calc(var(--board-pad) * .55);
  top: calc(var(--board-pad) - .5px); bottom: calc(var(--board-pad) - 1.5px);
  background: repeating-linear-gradient(180deg,
    rgba(28, 24, 48, .13) 0 1.5px, transparent 1.5px calc(var(--marq) * var(--lh)));
}
/* All nine lines share one cell, so the board keeps the tallest line's
   height and never jumps; only the picked one shows. */
#film .film__line {
  position: relative;
  grid-area: 1 / 1;
  font: 800 var(--marq) / var(--lh) var(--font-display);
  letter-spacing: .015em;
  text-transform: uppercase;
  text-align: center;
  text-wrap: balance;
  color: var(--ink-fixed);
  opacity: 0;
  transform: translateY(.14em);
  transition: opacity 100ms ease-in, transform 100ms ease-in;
}
/* Who said it: a row of smaller letters in the frame's orchid, on the rail
   under the line (one row tall, so the letters still snap to the rails) and
   sitting on it the way the big letters do */
#film .film__who {
  display: flex; align-items: flex-end; justify-content: center;
  height: calc(var(--marq) * var(--lh));
  padding-bottom: calc(var(--marq) * .15);
  font-size: max(.56em, 11.5px); line-height: 1; letter-spacing: .08em;
  color: var(--orchid-deep);
}
#film:has(#film-whiplash:checked) #film-line-whiplash,
#film:has(#film-avatar:checked) #film-line-avatar,
#film:has(#film-greenbook:checked) #film-line-greenbook,
#film:has(#film-goodwill:checked) #film-line-goodwill,
#film:has(#film-assclass:checked) #film-line-assclass,
#film:has(#film-breakingbad:checked) #film-line-breakingbad,
#film:has(#film-ratatouille:checked) #film-line-ratatouille,
#film:has(#film-aot:checked) #film-line-aot,
#film:has(#film-hxh:checked) #film-line-hxh {
  opacity: 1; transform: none;
  transition: opacity 240ms var(--ease-out) 100ms, transform 320ms var(--ease-out) 100ms;
}

/* --------------------------------------------------------------------------
   The poster cases. Every case in a row is the same height and as wide as its
   own poster: --h is the row height, worked out from the wall's width and the
   sum of the posters' aspect ratios in its widest row.
     one row of nine          sum 6.2849
     five and four (tablet)   first row 3.5178, the four centred under it
     three rows of three      2.0919 / 2.0925 / 2.1006
   -------------------------------------------------------------------------- */
#film .film__wall {
  --per: 9; --sum: 6.285;
  position: relative;
  isolation: isolate;
  container-type: inline-size;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
  column-gap: var(--gap); row-gap: 0;
  margin-top: var(--wall-gap);
}
/* Warm light falling from the underside of the marquee onto the front */
#film .film__wall::before {
  content: ""; position: absolute; z-index: -2; pointer-events: none;
  left: 0; right: 0;
  top: calc(-1 * var(--wall-gap));
  height: calc(var(--wall-gap) + 55%);
  background: linear-gradient(180deg, rgba(255, 196, 150, .16), rgba(255, 196, 150, .05) 55%, rgba(255, 196, 150, 0));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
/* The pavement: wet, catching a little of the light, where the reflections lie */
#film .film__wall::after {
  content: ""; position: absolute; z-index: -2; pointer-events: none;
  left: -1.5%; right: -1.5%; top: calc(100% + 1px);
  height: clamp(56px, 7vw, 120px);
  border-top: 1px solid rgba(255, 236, 214, .07);
  background: linear-gradient(180deg, rgba(126, 108, 214, .08), rgba(126, 108, 214, 0));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
#film .film__br { display: none; flex-basis: 100%; height: var(--gap); }

#film .film__case {
  --h: calc((100cqw - (var(--per) - 1) * var(--gap) - var(--per) * 2 * var(--case) - 2px) / var(--sum));
  position: relative;
  flex: none;
  width: calc(var(--h) * var(--a) + 2 * var(--case));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* The light a lit case throws on the wall, in its own colour */
#film .film__case::before {
  content: ""; position: absolute; z-index: -1; inset: -18% -36% -8%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--glow) 50%, transparent), transparent);
  opacity: 0;
  transition: opacity 320ms var(--ease-out);
  pointer-events: none;
}
/* The case itself: a slim dark frame, glass, the poster */
#film .film__glass {
  position: relative;
  isolation: isolate;
  display: block;
  padding: var(--case);
  border-radius: 4px;
  background: linear-gradient(180deg, #3a3368 0%, #221c45 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .16),
    0 22px 34px -20px rgba(4, 2, 14, .95);
  transition: transform 240ms var(--ease-out);
  /* The wet pavement below (Chromium and WebKit; elsewhere, no reflection) */
  -webkit-box-reflect: below 5px linear-gradient(transparent 72%, rgba(0, 0, 0, .26));
}
/* The picked case's frame is painted in the marquee's orchid (a ring the
   width of the frame, so an empty case never shows a pink slab) */
#film .film__glass::before {
  content: ""; position: absolute; inset: 0; z-index: 0; border-radius: inherit;
  padding: var(--case);
  background: linear-gradient(180deg, #f772b6 0%, var(--orchid) 45%, #e04e98 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0;
  transition: opacity 240ms var(--ease-out);
}
#film .film__glass img {
  position: relative; z-index: 1;
  width: 100%; height: auto;
  aspect-ratio: var(--a);
  object-fit: cover;
  border-radius: 2px;
  background: var(--night-surface);
  transition: opacity 280ms var(--ease-out);
}
/* Set by gallery.js only while a poster is still on its way */
#film .film__glass img.is-waiting { opacity: 0; }
/* Unpicked cases sit a little darker behind their glass */
#film .film__glass::after {
  content: ""; position: absolute; z-index: 2; inset: var(--case); border-radius: 2px;
  background:
    linear-gradient(158deg, rgba(255, 255, 255, .09) 0%, rgba(255, 255, 255, 0) 34%),
    rgba(14, 10, 34, .24);
  transition: opacity 260ms var(--ease-out);
  pointer-events: none;
}
#film .film__pick:checked + .film__case::before { opacity: 1; }
#film .film__pick:checked + .film__case .film__glass::before { opacity: 1; }
#film .film__pick:checked + .film__case .film__glass::after { opacity: 0; }
#film .film__pick:focus-visible + .film__case .film__glass { outline: 2px solid var(--focus); outline-offset: 5px; }
/* With the viewer loaded, the picked poster opens larger */
#film.has-viewer .film__pick:checked + .film__case { cursor: zoom-in; }
/* The hover lift: set by gallery.js (never during a scroll), transform only,
   on a case that already has its own layer, so it runs on the compositor */
#film .film__case.is-hover .film__glass { transform: translateY(-3px); }
@media (hover: hover) and (pointer: fine) {
  #film .film__glass { will-change: transform; }
}

/* Firefox has no -webkit-box-reflect: the same reflection is drawn from the
   case itself with -moz-element() (each label's --refl), mirrored and fading
   exactly like the box-reflect above */
@supports (background-image: -moz-element(#film)) and (not (-webkit-box-reflect: below)) {
  #film .film__case::after {
    content: ""; position: absolute; pointer-events: none;
    left: 0; right: 0; top: calc(100% + 5px); height: 100%;
    background: var(--refl) center / 100% 100% no-repeat;
    transform: scaleY(-1);
    mask-image: linear-gradient(transparent 72%, rgba(0, 0, 0, .26));
  }
}

/* --------------------------------------------------------------------------
   Smaller screens: five over four, then three rows of three
   -------------------------------------------------------------------------- */
@media (max-width: 1099px) {
  #film .film__wall { --per: 5; --sum: 3.518; }
  #film .film__br--5 { display: block; }
  #film .film__case:nth-of-type(-n+5) .film__glass { -webkit-box-reflect: unset; }
  #film .film__case:nth-of-type(-n+5)::after { content: none; }
}
@media (max-width: 639px) {
  #film { --marq: clamp(14px, 4.3vw, 19px); --frame: 15px; --board-pad: 12px; }
  #film .film__wall { --per: 3; --sum: 2.101; }
  #film .film__br--5 { display: none; }
  #film .film__br--3 { display: block; }
  #film .film__case:nth-of-type(-n+6) .film__glass { -webkit-box-reflect: unset; }
  #film .film__case:nth-of-type(-n+6)::after { content: none; }
}
