/* ── film.css: a real film strip on screen. Standalone and reusable (no dependency on any page). ──────────────────────────────
   Drawn from the measurements in the vault note "Film Strip — References" (SMPTE ST 139 for 35 mm, ISO 732 for 120), at one
   scale: 1 mm = --mm. Every frame is a <li class="film-fr"> made by film.js; put them in an <ol class="film-strip"> in a row.

   35 mm (.film-fr.f35): film 35 mm high; image gate 36 × 24 mm, frame pitch 38 mm; KS perforations 1.981 mm along the film ×
   2.794 mm across it (taller than wide; a real scan confirmed it, 2026-10-26) at 4.75 mm pitch, 2.01 mm from the edge, 8 a frame;
   the edge print in the outer margin, between the film's edge and the holes, as on real film.
   The look is Mika's reference of 2026-10-26 (a scanned strip of Fuji Velvia RVP100, and one of Ilford HP5): a pure black rebate,
   white holes with a faint halo, the orange print in the outer margins (the stock name on one edge; the frame number big at the
   corner and "▷ 16A" beside it on the other), the gate with a soft bright fringe. Drawn, not borrowed: a frame cut from someone
   else's scan carries their picture (tried and dropped the same day).
   120 (.film-fr.f120): a 6 × 6 frame drawn at the strip's height: no holes, a wide rebate, the print on one edge only.
   Portraits (.film-fr.rot): the photograph turned 90° clockwise so it fills the gate as a landscape.
   The film look (html.film): grain, a touch less contrast and saturation, a little warmth, a soft vignette, on the photographs only.
   Tokens: --mm (scale), --film-base (the rebate), --film-print (the edge print), --film-hole (what shows through the holes). ── */
:root {
  --mm: 7.5px;
  --film-base: #050404;          /* the rebate: black, as on the Velvia reference */
  --film-print: #f3a53a;         /* the edge print: Fuji's orange */
  --film-hole: #ffffff;          /* the light through the perforations */
  --film-gap: calc(2 * var(--mm));
  --f35-h: calc(35 * var(--mm)); --f35-pitch: calc(38 * var(--mm)); --f35-w: calc(36 * var(--mm)); --f35-img: calc(24 * var(--mm));
  --f35-gate-y: calc(5.5 * var(--mm));           /* (35 − 24) / 2 */
  --f35-print-y: calc(.35 * var(--mm));          /* the outer margin: the print sits between the film's edge and the holes */
  --f35-hole-h: calc(2.794 * var(--mm));         /* a hole across the film */
  --f120-img: calc(24 * var(--mm)); --f120-pitch: calc(38 * var(--mm));   /* in a continuous strip the 6 × 6 gate keeps the strip's height and pitch: no holes, a wide rebate */
}
.film-strip { display: flex; list-style: none; margin: 0; padding: 0; background: var(--film-base); width: max-content; height: var(--f35-h); }
.film-fr { position: relative; flex: 0 0 auto; height: var(--f35-h); background: var(--film-base); overflow: hidden; cursor: pointer; }
.film-fr .fw { position: absolute; overflow: hidden; background: #000; }
.film-fr .fw img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* the gate's soft, slightly uneven edge, and the scanning lens's fall-off toward the corners */
.film-fr .fw::before { content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: inherit; box-shadow: inset 0 0 0 1px rgba(255, 250, 240, .28), inset 0 0 calc(.5 * var(--mm)) rgba(255, 250, 240, .12), inset 0 0 calc(2 * var(--mm)) rgba(0, 0, 0, .22); }
.film-fr .fw { box-shadow: 0 0 calc(.6 * var(--mm)) rgba(255, 250, 240, .16); }   /* the gate's soft bright fringe, as in the reference */

/* ── 35 mm ── */
.film-fr.f35 { width: var(--f35-pitch); }
.film-fr.f35 .fw { left: var(--film-gap); top: var(--f35-gate-y); width: var(--f35-w); height: var(--f35-img); border-radius: calc(.4 * var(--mm)); }
/* perforations: 8 a frame, 1.981 × 2.794 mm holes with 0.51 mm fillets, 2.01 mm in from each edge; tiled so a row of frames reads as one strip */
.film-fr.f35::before, .film-fr.f35::after { content: ''; position: absolute; left: 0; width: 100%; height: var(--f35-hole-h); pointer-events: none;
  background: var(--film-hole); -webkit-mask: var(--film-perfs) 0 0 / calc(4.75 * var(--mm)) 100% repeat-x; mask: var(--film-perfs) 0 0 / calc(4.75 * var(--mm)) 100% repeat-x; }
.film-fr.f35::before { top: calc(2.01 * var(--mm)); }
.film-fr.f35::after { bottom: calc(2.01 * var(--mm)); }
.film-fr.f35::before, .film-fr.f35::after, .film-leader::before, .film-leader::after { filter: drop-shadow(0 0 calc(.2 * var(--mm)) rgba(255, 255, 255, .9)) drop-shadow(0 0 calc(.7 * var(--mm)) rgba(255, 255, 255, .35)); }   /* the holes' halo: light bleeding round them, as in the reference */
:root { --film-perfs: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4.75 2.794'%3E%3Crect x='1.3845' y='0' width='1.981' height='2.794' rx='0.51'/%3E%3C/svg%3E"); }
/* the edge print, in the outer margins beyond the holes (the reference): the stock name's edge above the gate ("PICANHR · 1986"
   where the film reads "FUJI RVP100"), the frame-number edge below it; a condensed bold face, tracked, in Fuji's orange, glowing a
   little as exposed light does */
.film-fr .fp { position: absolute; left: var(--film-gap); width: var(--f35-w); height: calc(1.55 * var(--mm)); line-height: calc(1.55 * var(--mm)); display: flex; justify-content: space-between; gap: 1em; padding: 0 calc(.6 * var(--mm)); box-sizing: border-box;
  font-family: "Arial Narrow", "Helvetica Neue", Roboto, Arial, sans-serif; font-stretch: condensed; font-size: calc(1.3 * var(--mm)); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--film-print); white-space: nowrap; overflow: hidden; font-variant-numeric: tabular-nums; text-shadow: 0 0 calc(.18 * var(--mm)) rgba(243, 165, 58, .55); }
.film-fr .fp b, .film-fr .fp i { font-weight: inherit; font-style: normal; }
.film-fr .fp b { min-width: 0; overflow: hidden; text-overflow: ellipsis; } .film-fr .fp i { flex: none; }
.film-fr.f35 .fp.t { top: var(--f35-print-y); }
/* the number edge: the frame number big and bold at the corner, "▷ 26 SEP · 4 PM" as the "▷ 16A" line, the number again small at the far end */
.film-fr.f35 .fp.b { bottom: calc(.1 * var(--mm)); }
.film-fr .fp.b { align-items: baseline; height: calc(2.6 * var(--mm)); line-height: calc(2.6 * var(--mm)); }
.film-fr .fp.b .n { font-size: calc(2.4 * var(--mm)); letter-spacing: .02em; margin-right: auto; }
.film-fr .fp.b b { flex: none; margin-left: 1em; } .film-fr .fp.b i { margin-left: 1em; }
.film-fr .fp.b .n2 { font-size: calc(1.1 * var(--mm)); margin-left: 1.2em; opacity: .85; }
/* ── 120, a 6 × 6 frame at the strip's height: no holes, the rebate wide and quiet, the print along one edge ── */
.film-fr.f120 { width: var(--f120-pitch); }
.film-fr.f120 .fw { left: calc((var(--f120-pitch) - var(--f120-img)) / 2); top: calc((35 * var(--mm) - var(--f120-img)) / 2); width: var(--f120-img); height: var(--f120-img); border-radius: calc(.3 * var(--mm)); }
.film-fr.f120 .fp { left: calc((var(--f120-pitch) - var(--f120-img)) / 2); width: var(--f120-img); }
.film-fr.f120 .fp.t { top: calc(2.4 * var(--mm)); }
.film-fr.f120 .fp.b { bottom: calc(2.4 * var(--mm)); opacity: .55; }

/* ── a portrait turned 90° clockwise: the top short edge becomes the right short edge ── */
.film-fr.rot .fw img { position: absolute; left: 50%; top: 50%; width: var(--f35-img); height: var(--f35-w); margin: calc(-.5 * var(--f35-w)) 0 0 calc(-.5 * var(--f35-img)); transform: rotate(90deg); }
.film-fr.f120.rot .fw img { width: var(--f120-img); height: var(--f120-img); margin: calc(-.5 * var(--f120-img)) 0 0 calc(-.5 * var(--f120-img)); }

/* ── the film look (html.film): on the photographs only, never on the rebate or the print ── */
html.film .film-fr .fw img { filter: contrast(.94) saturate(.86) sepia(.14) brightness(1.02); }
html.film .film-fr .fw::after { content: ''; position: absolute; inset: 0; pointer-events: none; mix-blend-mode: overlay; opacity: .55;
  background: var(--film-grain) 0 0 / calc(24 * var(--mm)) calc(24 * var(--mm)) repeat; }
html.film .film-fr .fw::before { box-shadow: inset 0 0 0 1px rgba(255, 246, 220, .09), inset 0 0 calc(3.5 * var(--mm)) rgba(0, 0, 0, .45); }
:root { --film-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); }
/* a site in black and white (D44): the print goes white, as on a black-and-white negative */
html:not(.color) .film-fr .fw img { filter: grayscale(1) contrast(1.02); }
html:not(.color).film .film-fr .fw img { filter: grayscale(1) contrast(.95) brightness(1.03); }
html:not(.color) { --film-print: #efe9dc; }

/* ── the mark of NOW: a grease-pencil ring round the frame, over the gate's edge and onto the rebate, the way a chosen frame is
   ringed on a contact sheet; the word beside it in the same hand. Red-orange pencil; the frame under it reads at full strength. ── */
.film-fr .fp-mark { position: absolute; left: calc(var(--film-gap) - 1.6 * var(--mm)); top: calc(var(--f35-gate-y) - 1.4 * var(--mm)); width: calc(var(--f35-w) + 3.2 * var(--mm)); height: calc(var(--f35-img) + 2.8 * var(--mm)); color: #ee4b2b; pointer-events: none; z-index: 2; filter: drop-shadow(0 0 calc(.15 * var(--mm)) rgba(238, 75, 43, .5)); }
.film-fr .fp-mark svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.film-fr .fp-mark b { position: absolute; right: calc(.6 * var(--mm)); bottom: calc(-2.5 * var(--mm)); font-family: "Arial Narrow", "Helvetica Neue", Roboto, Arial, sans-serif; font-stretch: condensed; font-weight: 700; font-size: calc(2.6 * var(--mm)); letter-spacing: .08em; line-height: 1; transform: rotate(-4deg); }
.film-fr.f120 .fp-mark { left: calc((var(--f120-pitch) - var(--f120-img)) / 2 - 1.6 * var(--mm)); top: calc((35 * var(--mm) - var(--f120-img)) / 2 - 1.4 * var(--mm)); width: calc(var(--f120-img) + 3.2 * var(--mm)); height: calc(var(--f120-img) + 2.8 * var(--mm)); }
.film-fr.marked { overflow: visible; z-index: 3; }
@media (prefers-reduced-motion: no-preference) { .film-fr .fp-mark svg path { stroke-dasharray: 400; stroke-dashoffset: 400; animation: fp-draw 1.1s ease-out .4s forwards; } }
@keyframes fp-draw { to { stroke-dashoffset: 0; } }

/* ── a leader: a length of film with words on it, for a heading between segments ── */
.film-leader { position: relative; display: flex; align-items: center; height: var(--f35-h); background: var(--film-base); color: var(--film-print); padding: 0 calc(6 * var(--mm)); box-sizing: border-box; overflow: hidden; }
.film-leader::before, .film-leader::after { content: ''; position: absolute; left: 0; width: 100%; height: calc(1.981 * var(--mm)); background: var(--film-hole); -webkit-mask: var(--film-perfs) 0 0 / calc(4.75 * var(--mm)) 100% repeat-x; mask: var(--film-perfs) 0 0 / calc(4.75 * var(--mm)) 100% repeat-x; }
.film-leader::before { top: calc(2.01 * var(--mm)); } .film-leader::after { bottom: calc(2.01 * var(--mm)); }
.film-leader b { font-family: "Arial Narrow", "Helvetica Neue", Roboto, Arial, sans-serif; font-stretch: condensed; font-weight: 700; font-size: calc(9 * var(--mm)); letter-spacing: .08em; text-transform: uppercase; line-height: 1; }
.film-leader span { margin-left: calc(4 * var(--mm)); font-family: "Arial Narrow", "Helvetica Neue", Roboto, Arial, sans-serif; font-stretch: condensed; font-size: calc(2.4 * var(--mm)); letter-spacing: .16em; text-transform: uppercase; opacity: .8; }
.film-leader.now b { color: #fff; }
@media (max-width: 700px) {   /* a phone-wide frame scales the lettering up; the leader stacks and its words come down */
  .film-leader { flex-direction: column; align-items: flex-start; justify-content: center; padding: 0 calc(4 * var(--mm)); }
  .film-leader b { font-size: calc(5.5 * var(--mm)); }
  .film-leader span { margin: calc(1.2 * var(--mm)) 0 0; font-size: calc(1.6 * var(--mm)); }
}

/* ── motion: a frame settles in as it comes into view (film.js adds .in); none under reduced motion ── */
.film-fr { opacity: 0; transform: translateY(calc(1.5 * var(--mm))); transition: opacity .6s ease, transform .6s ease; }
.film-fr.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .film-fr { opacity: 1; transform: none; transition: none; } }
