/* ==========================================================================
   The Shot List / Aftersun (2022)
   Design system: "sun-bleached"
   Faded paper, soft ink, and one accent: the pale turquoise of the resort
   pool. Faded orange lives only inside the illustrations (art.js). Two image
   treatments alternate: CAMCORDER (4:3, page-drawn display) and MEMORY
   (35mm, warmer and grainier). One theme, no dark mode.
   ========================================================================== */

/* ---------- Tokens ---------- */
:root {
  --bg: #f4efe6;
  --bg-2: #ece5d8;
  --bg-3: #e2d9c9;
  --card: #fbf9f3;
  --ink: #2c2a27;
  --ink-2: #4a4641;
  --ink-3: #6e675e;
  --rule: #d8cfbf;
  --accent: #46b3ad;
  --accent-ink: #22706b;
  --accent-soft: #d3ebe7;
  --rec: #d0453b;
  --osd: #f7f4ec;
  --night: #131412;
  --night-2: #1d1e1b;
  --night-ink: #e9e3d7;
  --night-ink-2: #b3ab9e;
  --night-rule: #34352f;

  --f-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --f-body: "Newsreader", Georgia, "Times New Roman", serif;
  --f-osd: "VT323", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  --fs-body: clamp(18px, 0.6vw + 15px, 21px);
  --measure: 64ch;
  --wide: 1080px;
  --sheet: 1240px;
  --gutter: 16px;
  --mast-h: 58px;

  --noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");

  color-scheme: light;
}

@media (min-width: 720px) {
  :root { --gutter: clamp(24px, 4vw, 48px); --mast-h: 64px; }
}

/* ---------- Base ---------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--bg);
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: var(--fs-body);
  font-optical-sizing: auto;
  line-height: 1.66;
  overflow-wrap: break-word;
  font-kerning: normal;
  font-variant-ligatures: common-ligatures;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

main { display: block; overflow-x: clip; }

::selection { background: var(--accent-soft); color: var(--ink); }

a {
  color: var(--accent-ink);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: color-mix(in srgb, var(--accent-ink) 45%, transparent);
}
a:hover { color: var(--ink); text-decoration-color: currentColor; }

button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 3px;
}
[tabindex="-1"]:focus { outline: none; }

cite { font-style: italic; }

h1, h2, h3, p, figure, dl, dd, ul, blockquote { margin: 0; }

.fx-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 100;
  padding: 8px 14px;
  background: var(--ink);
  color: var(--bg);
  font: 400 18px/1 var(--f-osd);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}
.skip-link:focus { top: 12px; color: var(--bg); }

/* ---------- Reading progress ---------- */
.progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 3px;
  z-index: 60;
  pointer-events: none;
}
.progress-bar {
  display: block;
  height: 100%;
  background: var(--accent);
  transform-origin: 0 50%;
  transform: scaleX(0);
  will-change: transform;
}

/* ---------- Masthead ---------- */
.masthead {
  position: relative;
  z-index: 3;
  border-bottom: 1px solid var(--rule);
}
.masthead-inner {
  width: min(var(--sheet), 100% - 2 * var(--gutter));
  min-height: var(--mast-h);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
  color: var(--ink);
  text-decoration: none;
}
.brand:hover { color: var(--accent-ink); }
.brand-mark {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
}
.brand-name {
  font: 500 14px/1 var(--f-display);
  letter-spacing: 0.28em;
  margin-right: -0.28em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ---------- Hero: the Polaroid ---------- */
.hero {
  position: relative;
  isolation: isolate;
  width: min(var(--sheet), 100% - 2 * var(--gutter));
  margin-inline: auto;
  padding: clamp(40px, 8vw, 72px) 0 clamp(64px, 10vw, 112px);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(40px, 7vw, 72px);
}
/* sun on the paper, behind the photograph */
.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -12% -20% 0 -30%;
  background:
    radial-gradient(48% 52% at 34% 44%, rgba(255, 252, 245, 0.95) 0%, rgba(255, 252, 245, 0) 72%),
    radial-gradient(40% 40% at 70% 70%, rgba(70, 179, 173, 0.07) 0%, rgba(70, 179, 173, 0) 70%);
  pointer-events: none;
}
.hero-photo {
  justify-self: center;
  width: min(76vw, 340px);
}
.polaroid {
  position: relative;
  padding: 6.5% 6.5% 23%;
  background: var(--card);
  border-radius: 2px;
  transform: rotate(-2.4deg);
  box-shadow:
    0 1px 1px rgba(44, 42, 39, 0.06),
    0 10px 22px -10px rgba(44, 42, 39, 0.24),
    0 34px 60px -34px rgba(44, 42, 39, 0.32);
}
/* the faint sheen of the print's surface */
.polaroid::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(125deg, rgba(255, 255, 255, 0) 42%, rgba(255, 255, 255, 0.12) 52%, rgba(255, 255, 255, 0) 62%);
  pointer-events: none;
}
.pol-window {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #e7e6e0;
}
.pol-window > * {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}
.pol-window::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 1px rgba(44, 42, 39, 0.08), inset 0 1px 4px rgba(44, 42, 39, 0.16);
  pointer-events: none;
}
.pol-img {
  object-fit: cover;
  object-position: 50% 50%;
  opacity: 0;
}
/* no photograph to hand: the pool, in soft focus */
.pol-fallback {
  opacity: 0;
  background:
    radial-gradient(55% 40% at 72% 22%, rgba(255, 251, 238, 0.95) 0%, rgba(255, 251, 238, 0) 70%),
    radial-gradient(80% 50% at 25% 85%, rgba(34, 112, 107, 0.35) 0%, rgba(34, 112, 107, 0) 70%),
    linear-gradient(172deg, #e9f2ee 0%, #bfe2dd 30%, #8ccfc8 55%, #5dbcb5 78%, #46b3ad 100%);
}
/* the chemical haze the picture comes up through */
.pol-haze {
  background:
    radial-gradient(70% 55% at 30% 28%, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0) 70%),
    radial-gradient(60% 50% at 76% 72%, rgba(196, 207, 203, 0.55) 0%, rgba(196, 207, 203, 0) 70%),
    #e8e7e1;
}
.polaroid[data-src="img"] .pol-img,
.polaroid[data-src="haze"] .pol-fallback { opacity: 1; }
.polaroid.is-developing .pol-haze { animation: pol-clear 7.5s cubic-bezier(0.45, 0, 0.25, 1) both; }
.polaroid.is-developing .pol-img,
.polaroid.is-developing .pol-fallback { animation: pol-tone 9.5s cubic-bezier(0.3, 0, 0.2, 1) both; }
.polaroid.is-developed .pol-haze { opacity: 0; }
.polaroid.is-developed .pol-img,
.polaroid.is-developed .pol-fallback { filter: saturate(0.94) contrast(0.97) brightness(1.01) sepia(0.08); }
/* without the script there is nothing to develop: the pool, already there */
.no-js .pol-fallback { opacity: 1; filter: saturate(0.94) contrast(0.97) sepia(0.08); }
.no-js .pol-haze { opacity: 0; }

@keyframes pol-clear {
  0% { opacity: 1; }
  14% { opacity: 0.97; }
  100% { opacity: 0; }
}
@keyframes pol-tone {
  0% { filter: saturate(0.1) contrast(0.42) brightness(1.38) sepia(0.28); }
  100% { filter: saturate(0.94) contrast(0.97) brightness(1.01) sepia(0.08); }
}

.hero-text { min-width: 0; }
.hero-kicker {
  display: flex;
  align-items: center;
  gap: 12px;
  font: 400 20px/1 var(--f-osd);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.hero-kicker::before {
  content: "";
  flex: none;
  width: 28px;
  height: 2px;
  background: var(--accent);
}
.hero-title {
  margin: 0.16em 0 0.08em -0.04em;
  font: 300 clamp(3.9rem, 2.2rem + 7.4vw, 9.25rem)/0.92 var(--f-display);
  font-optical-sizing: auto;
  letter-spacing: -0.025em;
  color: var(--ink);
}
.hero-film {
  font: italic 400 clamp(1.2rem, 1rem + 0.6vw, 1.5rem)/1.3 var(--f-display);
  color: var(--ink-2);
}
.hero-film span { margin: 0 0.3em; color: var(--accent); font-style: normal; }
.hero-dek {
  margin-top: clamp(1.1rem, 2.4vw, 1.6rem);
  max-width: 34ch;
  font-size: clamp(1.1rem, 0.98rem + 0.45vw, 1.3rem);
  line-height: 1.5;
  color: var(--ink);
  text-wrap: pretty;
}
.hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 0;
  margin-top: clamp(1.4rem, 3vw, 2rem);
  font: 400 18px/1.2 var(--f-osd);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.hero-meta > * + *::before {
  content: "·";
  margin: 0 0.7em;
  color: var(--accent);
}
.hero-by { color: var(--ink); }
/* phones: the byline on its own line, so no separator ever starts a line */
@media (max-width: 519px) {
  .hero-by { flex-basis: 100%; }
  .hero-by + *::before { content: none; }
}

@media (min-width: 900px) {
  .hero {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: center;
    min-height: clamp(560px, 82svh, 860px);
    column-gap: clamp(48px, 6vw, 96px);
  }
  .hero-photo { width: min(100%, 450px); }
}

/* ---------- The flow grid ---------- */
.flow {
  --wide-extra: calc((var(--wide) - var(--measure)) / 2);
  position: relative;
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wide-start] minmax(0, var(--wide-extra))
    [text-start] min(var(--measure), 100% - 2 * var(--gutter))
    [text-end] minmax(0, var(--wide-extra))
    [wide-end] minmax(var(--gutter), 1fr)
    [full-end];
}
.flow > * { grid-column: text; min-width: 0; }
.flow > * + * { margin-top: 1.15em; }

.chapter { scroll-margin-top: 24px; }
.chapter + .chapter { margin-top: clamp(4.5rem, 9vw, 7.25rem); }

.flow > p {
  text-wrap: pretty;
  hanging-punctuation: first;
}
@media (max-width: 559px) {
  .flow > p { hyphens: auto; -webkit-hyphens: auto; }
}

.flow > :is(figure, aside) { margin-top: clamp(2.5rem, 6vw, 3.75rem); }
.flow > :is(figure, aside) + * { margin-top: clamp(2.5rem, 6vw, 3.75rem); }
/* a still that is not on the page leaves no gap behind it */
html:not(.show-placeholders) .flow > .is-missing + :not(figure, aside) { margin-top: 1.15em; }
.flow > .ch-title + * { margin-top: 1.05em; }

/* ---------- Chapter headings ---------- */
.ch-title {
  font: 400 clamp(1.95rem, 1.4rem + 1.8vw, 2.8rem)/1.06 var(--f-display);
  letter-spacing: -0.012em;
  color: var(--ink);
  text-wrap: balance;
}
.ch-idx {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 0.5em;
  font: 400 20px/1 var(--f-osd);
  letter-spacing: 0.1em;
  color: var(--accent-ink);
}
.ch-idx::after {
  content: "";
  width: 28px;
  height: 2px;
  background: var(--accent);
}
.ch-text { display: block; }

/* ---------- Drop cap ---------- */
.dropcap::first-letter {
  float: left;
  font-family: var(--f-display);
  font-style: normal;
  font-weight: 300;
  font-size: 4.1em;
  line-height: 0.8;
  margin: 0.08em 0.08em 0 -0.03em;
  color: var(--accent-ink);
}
@supports (initial-letter: 3) or (-webkit-initial-letter: 3) {
  .dropcap::first-letter {
    float: none;
    font-size: inherit;
    line-height: inherit;
    margin: 0 0.1em 0 0;
    -webkit-initial-letter: 3;
    initial-letter: 3;
  }
}

/* ---------- Sidenotes ---------- */
.sn { white-space: normal; }
.sn-ref {
  position: relative;
  top: -0.42em;
  margin: 0 0.02em 0 0.06em;
  padding: 0 0.12em;
  border: 0;
  background: none;
  font: 400 0.82em/1 var(--f-osd);
  color: var(--accent-ink);
  cursor: pointer;
  vertical-align: baseline;
  transition: color 160ms ease;
}
.sn-ref::after {
  content: "";
  position: absolute;
  inset: -10px -7px;
}
.sn-ref:hover,
:root:not(.sn-margin) .sn-ref[aria-expanded="true"],
.sn.is-hot .sn-ref { color: var(--ink); }

.sn-note {
  display: none;
  font-size: 0.8em;
  line-height: 1.55;
  color: var(--ink-3);
  text-wrap: pretty;
  hyphens: manual;
}
.sn-num {
  font: 400 1.1em/1 var(--f-osd);
  color: var(--accent-ink);
  margin-right: 0.6em;
}

/* inline (narrow) mode: tap to expand */
.no-js .sn-note,
.sn.is-open .sn-note {
  display: block;
  margin: 0.85em 0 0.95em;
  padding: 0.15em 0 0.15em 1.05em;
  border-left: 2px solid var(--accent);
  color: var(--ink-2);
}

/* margin mode (wide screens), positioned by page.js */
.sn-margin .sn-note {
  display: block;
  position: absolute;
  top: 0;
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 0.74em;
  line-height: 1.5;
  transition: color 200ms ease;
}
/* margin mode, but no room beside the reference: set open under its line */
.sn-margin .sn.sn-inline .sn-note {
  position: static;
  width: auto;
  margin: 0.85em 0 0.95em;
  padding: 0.15em 0 0.15em 1.05em;
  border-left: 2px solid var(--accent);
  font-size: 0.8em;
  line-height: 1.55;
  color: var(--ink-2);
}
.sn-margin .sn.is-hot .sn-note { color: var(--ink); }

/* ---------- Tape labels: every caption's tag ---------- */
.tape-label,
.art figcaption::before {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 3px 9px 2px 8px;
  font: 400 17px/1.1 var(--f-osd);
  letter-spacing: 0.06em;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--rule);
  border-left: 5px solid var(--accent);
  border-radius: 1px;
  box-shadow: 0 1px 2px rgba(44, 42, 39, 0.08);
  white-space: nowrap;
  transform: rotate(-0.6deg);
}

/* ---------- Film stills ---------- */
.flow > .still { grid-column: full; }
@media (min-width: 720px) {
  .flow > .still { grid-column: wide; }
  .flow > .still--cam { justify-self: center; width: min(100%, 720px); }
}
.still { container-type: inline-size; }
.still-frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: 1.85 / 1;
  background: var(--bg-3);
}
.still-frame img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
  opacity: 0;
}
.still.is-loaded .still-frame img { opacity: 1; }

/* MEMORY: 35mm, warmer and grainier, nothing on top */
.still--film img { filter: sepia(0.13) saturate(1.05) contrast(1.03) brightness(1.01); }
.still--film.is-loaded .still-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background-image: var(--noise);
  background-size: 200px 200px;
  opacity: 0.2;
  mix-blend-mode: overlay;
  pointer-events: none;
}
/* a hairline keyline, so pale skies and sand still read as the edge of a frame */
.still.is-loaded .still-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  box-shadow: inset 0 0 0 1px rgba(44, 42, 39, 0.28);
  pointer-events: none;
}

/* CAMCORDER: 4:3, washed, scanlines and the camera's own display */
.still--cam .still-frame { aspect-ratio: 4 / 3; background: #1a1b18; }
.still--cam img { filter: saturate(0.8) contrast(0.9) brightness(1.06) sepia(0.05); }
.cam-scan,
.land-scan {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: repeating-linear-gradient(to bottom, rgba(16, 18, 17, 0.11) 0 1px, rgba(16, 18, 17, 0) 1px 3px);
  mix-blend-mode: multiply;
  pointer-events: none;
}
.osd {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto minmax(0, 1fr) auto;
  padding: 5.5% 6.5%;
  font: 400 max(15px, 4.6cqw)/1 var(--f-osd);
  letter-spacing: 0.05em;
  color: var(--osd);
  /* white with a dark edge, as camcorder displays were, so it reads on sand and sky */
  text-shadow: 0 0 1px rgba(0, 0, 0, 0.85), 1px 1px 0 rgba(0, 0, 0, 0.5), 0 0 5px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}
.osd-rec {
  grid-area: 1 / 1;
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  transition: opacity 400ms ease;
}
.osd-dot {
  flex: none;
  width: 0.6em;
  height: 0.6em;
  border-radius: 50%;
  background: var(--rec);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15), 0 0 6px rgba(208, 69, 59, 0.55);
  transition: opacity 300ms ease;
}
.osd-tc { grid-area: 1 / 2; justify-self: end; font-variant-numeric: tabular-nums; }
.osd-date { grid-area: 3 / 1 / 4 / 3; align-self: end; }

/* RAVE: frozen frames. Nothing here flashes or moves. */
.still--frozen img { filter: saturate(0.9) contrast(1.05) brightness(0.98); }
.freeze-tag {
  position: absolute;
  z-index: 3;
  top: 6%;
  left: 4.5%;
  display: inline-flex;
  align-items: center;
  gap: 0.18em;
  font: 400 max(15px, 3.4cqw)/1 var(--f-osd);
  letter-spacing: 0.08em;
  color: var(--osd);
  text-shadow: 0 0 1px rgba(0, 0, 0, 0.85), 1px 1px 0 rgba(0, 0, 0, 0.5), 0 0 5px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}
.freeze-tag i {
  display: block;
  width: 0.2em;
  height: 0.72em;
  background: currentColor;
  box-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
}
.freeze-tag i + i { margin-right: 0.35em; }
/* the band of noise a paused tape holds near the bottom of the picture */
.freeze-band {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 9%;
  height: max(4px, 1.6%);
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.35) 50%, rgba(255, 255, 255, 0)),
    var(--noise);
  background-size: auto, 120px 120px;
  opacity: 0.4;
  mix-blend-mode: screen;
  pointer-events: none;
}
.still:not(.is-loaded) :is(.osd, .cam-scan, .freeze-tag, .freeze-band) { display: none; }

/* the rave cutting into the ending: one frozen frame on its own dark band */
.flow > .still--night {
  grid-column: full;
  justify-self: stretch;
  width: auto;
  padding: clamp(28px, 6vw, 64px) 0 clamp(24px, 5vw, 44px);
  background: var(--night);
}
@media (min-width: 720px) {
  .flow > .still--night { padding-inline: max(var(--gutter), (100% - var(--wide)) / 2); }
}

/* Until page.js has found its file, a still or landscape holds its place in
   the layout but is not drawn, so a missing one never flashes up as an
   empty frame. The class is page.js's: if it never runs, it is gone by load. */
.stills-probing :is(.still, .land):not(.is-found):not(.is-missing) { visibility: hidden; }

/* a file that does not exist is not on the page at all;
   ?placeholders in the URL shows a labelled placeholder in its place */
.is-missing { display: none; }
.show-placeholders .is-missing { display: block; }
.ph { display: none; }
.is-missing :is(.still-frame, .land-frame) {
  background: var(--bg-2);
  outline: 1px dashed var(--ink-3);
  outline-offset: -1px;
}
.is-missing .ph {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: max(6px, 0.9cqw);
  padding: 4% 8%;
  text-align: center;
}
.ph-id {
  font: 400 max(17px, 2cqw)/1.2 var(--f-osd);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.ph-desc {
  max-width: 46ch;
  font: italic 400 max(14px, 1.8cqw)/1.4 var(--f-body);
  color: var(--ink-2);
  text-wrap: balance;
}
.ph-file {
  font: 400 max(15px, 1.4cqw)/1.3 var(--f-osd);
  letter-spacing: 0.04em;
  color: var(--ink-3);
}
@container (max-width: 420px) {
  .ph-desc { display: none; }
}
.still--night.is-missing { background: none; padding: 0; }

/* captions */
.still figcaption,
.art figcaption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 14px;
  margin-top: 14px;
  max-width: 66ch;
  font-size: 0.84em;
  line-height: 1.5;
  color: var(--ink-2);
}
.cap {
  flex: 1 1 24ch;
  min-width: 0;
  text-wrap: pretty;
}
@media (max-width: 719px) {
  .flow > .still figcaption { padding-inline: var(--gutter); }
}
@media (min-width: 720px) {
  .flow > .still--cam figcaption { max-width: none; }
}

/* ---------- Landscapes: full-width bands, on tape ---------- */
.land {
  position: relative;
  margin: clamp(4.5rem, 10vw, 8rem) 0;
  container-type: inline-size;
}
.land + .chapter { margin-top: 0; }
.land-frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--bg-3);
}
@media (min-width: 720px) {
  .land-frame { aspect-ratio: 21 / 9; max-height: 78svh; }
}
/* The VHS look is drawn on the page: an SVG filter (#vhs in index.html)
   for the chroma bleed, the red/blue offset and the bloom; scanlines and
   the tracking line on top. The photograph itself is untouched. The image
   overhangs the frame a little so the colour offset never shows an edge. */
.land-frame img {
  position: absolute;
  top: -4px;
  left: -4px;
  display: block;
  width: calc(100% + 8px);
  height: calc(100% + 8px);
  object-fit: cover;
  object-position: 50% 55%;
  opacity: 0;
  filter: url(#vhs) saturate(0.94);
}
.land.is-loaded .land-frame img { opacity: 1; }
.land-scan { background: repeating-linear-gradient(to bottom, rgba(16, 18, 17, 0.075) 0 1px, rgba(16, 18, 17, 0) 1px 3px); }
.land:not(.is-loaded) :is(.land-scan, .land-track) { display: none; }

/* one tracking line, drifting down once when the band comes into view */
.land-track {
  position: absolute;
  inset: 0;
  z-index: 3;
  opacity: 0;
  transform: translateY(-6%);
  pointer-events: none;
}
.land-track::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: max(7px, 1.1cqw);
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.14) 40%, rgba(255, 255, 255, 0.26) 55%, rgba(255, 255, 255, 0));
  -webkit-backdrop-filter: blur(1.2px) brightness(1.06) saturate(0.75);
  backdrop-filter: blur(1.2px) brightness(1.06) saturate(0.75);
}
.land-track::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: max(4px, 0.62cqw);
  height: 1px;
  background: repeating-linear-gradient(90deg,
    rgba(255, 255, 255, 0.55) 0 9px, rgba(255, 255, 255, 0) 9px 13px,
    rgba(255, 255, 255, 0.3) 13px 31px, rgba(255, 255, 255, 0) 31px 37px,
    rgba(255, 255, 255, 0.45) 37px 52px, rgba(255, 255, 255, 0) 52px 61px);
  opacity: 0.55;
}
.land.is-tracking .land-track { animation: track-drift 3.6s cubic-bezier(0.4, 0.1, 0.6, 0.9) both; }
@keyframes track-drift {
  0% { transform: translateY(-6%); opacity: 0; }
  7% { opacity: 1; }
  86% { opacity: 0.85; }
  100% { transform: translateY(104%); opacity: 0; }
}

/* the label stuck on below the band: place and photo credit */
.land-cap {
  position: relative;
  z-index: 4;
  display: flex;
  width: min(var(--wide), 100% - 2 * var(--gutter));
  margin: -15px auto 0;
}
.tape-label--land {
  display: inline-grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 0.5em;
  row-gap: 1px;
  max-width: 100%;
  padding: 5px 12px 4px 10px;
  white-space: normal;
  transform: rotate(-0.8deg);
}
.tl-id { color: var(--accent-ink); text-transform: uppercase; }
.tl-place { text-transform: uppercase; letter-spacing: 0.08em; }
.tl-place::before { content: "·"; margin-right: 0.5em; color: var(--accent); }
.tl-credit {
  grid-column: 1 / -1;
  font-size: 15px;
  color: var(--ink-3);
}
.tl-place:empty,
.tl-credit:empty { display: none; }
.is-missing .land-cap { margin-top: 10px; }

/* ---------- The rave: the one dark room ---------- */
.rave {
  padding-block: clamp(4rem, 10vw, 7.5rem);
  background: var(--night);
  color: var(--night-ink);
}
.rave .ch-title { color: var(--night-ink); }
.rave .ch-idx { color: var(--accent); }
.rave .still-frame { background: var(--night-2); }
.rave .still.is-loaded .still-frame::after,
.still--night.is-loaded .still-frame::after { box-shadow: inset 0 0 0 1px rgba(233, 227, 215, 0.12); }
:is(.rave, .still--night) figcaption { color: var(--night-ink-2); }
:is(.rave, .still--night) .tape-label {
  color: var(--night-ink);
  background: var(--night-2);
  border-color: var(--night-rule);
  border-left-color: var(--accent);
  box-shadow: none;
}
.rave ::selection { background: var(--accent-ink); color: #fff; }
.rave :focus-visible { outline-color: var(--accent); }

/* ---------- Illustrations (drawn by art.js) ---------- */
body { counter-reset: print; }
.flow > .art {
  grid-column: wide;
  justify-self: center;
  width: 100%;
  max-width: 760px;
}
.art-canvas { width: 100%; }
.art-canvas > svg,
.art-canvas > canvas { display: block; width: 100%; height: auto; }
.art figcaption::before {
  counter-increment: print;
  content: "PRINT " counter(print);
}

/* ---------- Sign-off: the tape runs out ---------- */
.signoff {
  padding: clamp(5.5rem, 12vw, 9rem) var(--gutter) 0;
}
.so-cam {
  width: min(100%, 620px);
  margin-inline: auto;
  container-type: inline-size;
}
.so-frame {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 3px;
  background: var(--night);
  box-shadow: 0 0 0 1px rgba(44, 42, 39, 0.18), 0 24px 50px -32px rgba(44, 42, 39, 0.55);
}
.so-img,
.so-fallback {
  position: absolute;
  top: -4%;
  left: -4%;
  display: block;
  width: 108%;
  height: 108%;
}
.so-img {
  object-fit: cover;
  opacity: 0;
  filter: saturate(0.82) contrast(0.9) brightness(1.05) sepia(0.06);
}
/* no landscape to hand: sea and sky, out of focus */
.so-fallback {
  background:
    radial-gradient(30% 22% at 68% 24%, rgba(255, 249, 234, 0.95) 0%, rgba(255, 249, 234, 0) 100%),
    linear-gradient(180deg, #f3eee2 0%, #e1ece7 34%, #b9ddd8 49%, #7fc6bf 51%, #55b6af 70%, #3e9f99 100%);
  filter: saturate(0.85) blur(0.6px);
}
.so-cam[data-src="img"] .so-img { opacity: 1; }
.so-cam[data-src="img"] .so-fallback { opacity: 0; }
.so-cam.is-rolling :is(.so-img, .so-fallback) { animation: so-pan 11s linear both; }
.so-cam.is-frozen :is(.so-img, .so-fallback) { animation-play-state: paused; }
@keyframes so-pan {
  0% { transform: translate3d(-1.7%, 0.3%, 0) rotate(-0.12deg); }
  24% { transform: translate3d(-0.7%, -0.25%, 0) rotate(0.1deg); }
  49% { transform: translate3d(0.1%, 0.3%, 0) rotate(-0.05deg); }
  74% { transform: translate3d(0.9%, -0.1%, 0) rotate(0.1deg); }
  100% { transform: translate3d(1.7%, 0.2%, 0) rotate(0deg); }
}
.so-cam .freeze-band { opacity: 0; transition: opacity 250ms ease; }
.so-cam.is-frozen .freeze-band { opacity: 0.4; }
.so-cam.is-stopped .osd-dot { opacity: 0; }
.so-cam.is-stopped .osd-rec { opacity: 0.55; }
.so-cam .osd { transition: opacity 600ms ease; }
.so-cam.is-ended .osd { opacity: 0; }

.so-end {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.6em;
  background: var(--night);
  opacity: 0;
  transition: opacity 1.6s ease;
}
.so-end::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.025) 0 1px, rgba(255, 255, 255, 0) 1px 3px);
  pointer-events: none;
}
.so-name {
  font: 400 clamp(72px, 24cqw, 156px)/0.82 var(--f-osd);
  letter-spacing: 0.1em;
  margin-right: -0.1em;
  color: var(--osd);
  text-shadow: 0 0 14px rgba(70, 179, 173, 0.35);
}
.so-stamp {
  font: 400 max(17px, 4.4cqw)/1 var(--f-osd);
  letter-spacing: 0.08em;
  color: var(--accent);
  white-space: nowrap;
}
.so-name,
.so-stamp { opacity: 0; transition: opacity 1s ease 1.3s; }
.so-cam.is-ended .so-end,
.so-cam.is-ended .so-name,
.so-cam.is-ended .so-stamp,
.no-js .so-end,
.no-js .so-name,
.no-js .so-stamp { opacity: 1; }
.no-js .so-cam .osd { opacity: 0; }

.so-credit {
  margin-top: 12px;
  text-align: center;
  font: 400 16px/1.35 var(--f-osd);
  letter-spacing: 0.05em;
  color: var(--ink-3);
}
.signoff-line {
  margin-top: clamp(1.4rem, 3vw, 2.1rem);
  text-align: center;
  font: 400 18px/1.4 var(--f-osd);
  letter-spacing: 0.2em;
  margin-right: -0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
}
main:has(.signoff) + .site-footer { margin-top: clamp(4rem, 9vw, 6.5rem); }

/* ---------- Footer ---------- */
.site-footer {
  margin-top: clamp(6rem, 14vw, 10rem);
  padding: 40px var(--gutter) 56px;
  border-top: 1px solid var(--rule);
  background: var(--bg-2);
}
.footer-inner {
  width: min(var(--wide), 100%);
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 22px;
}
@media (min-width: 820px) {
  .footer-inner {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 48px;
  }
}
.footer-brand {
  display: flex;
  align-items: center;
  gap: 11px;
}
.footer-name {
  font: 500 14px/1 var(--f-display);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
}
.colophon {
  max-width: 60ch;
  font-size: 0.78em;
  line-height: 1.6;
  color: var(--ink-3);
}
.back-top {
  justify-self: start;
  font: 400 18px/1 var(--f-osd);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

/* ---------- Motion ---------- */
/* Only the pictures move, each once: the Polaroid develops on load, a
   tracking line crosses each landscape, the sign-off tape runs out. Body
   text never animates. With reduced motion, everything is shown at rest. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Utilities ---------- */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media print {
  .progress, .land-track { display: none !important; }
  .sn-note { display: block; }
  .rave, .still--night { background: none; color: var(--ink); }
}
