/* ==========================================================================
   Covenant — product site
   World: a hand-processed 16mm inspection strip. Leader black ground, emulsion
   greys, light-leak orange reserved for a marked frame. Every mark is a verdict.
   No build step. No runtime network request. Self-hosted faces only.
   ========================================================================== */

/* --- faces ---------------------------------------------------------------- */

@font-face {
  font-family: "Anton";
  src: url("fonts/anton-latin-400-normal.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo-latin-wght-normal.woff2") format("woff2-variations");
  font-weight: 100 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono-latin-700-normal.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Caveat";
  src: url("fonts/caveat-latin-700-normal.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

/* --- tokens --------------------------------------------------------------- */

:root {
  /* stock */
  --leader:        #0E0F10;  /* leader black — the ground */
  --base-dark:     #141719;  /* film base, the sprocket margin */
  --shadow:        #1B1F22;  /* shadow gray — raised surfaces */
  --shadow-2:      #24282C;  /* a frame lifted off the bench */
  --edge:          #33383D;  /* rebate / hairline */
  --edge-strong:   #4A5157;

  /* image */
  --base-gray:     #878D92;  /* dim label ink — 4.9:1 on --shadow, 5.7:1 on leader black */
  --emulsion:      #A6ABB0;  /* body ink */
  --emulsion-hi:   #DCE0E3;  /* headline ink */
  --emulsion-max:  #F2F4F5;

  /* events */
  --leak:          #FF8A33;  /* light-leak orange — a struck frame */
  --leak-deep:     #C4571C;
  --leak-dim:      #7A4420;
  --edgecode:      #D0702E;  /* stamped edge code — 5.2:1 on film base */
  --sepia:         #C8B089;  /* chemical stain — a risky finding */
  --sepia-dim:     #6B5C43;

  /* geometry */
  --perf:          30px;     /* sprocket margin width */
  --gap-1: .5rem; --gap-2: .875rem; --gap-3: 1.5rem;
  --gap-4: 2.5rem; --gap-5: 4.5rem; --gap-6: 7.5rem;
  --r-frame: 5px; --r-perf: 3px; --r-chip: 2px;
  --maxw: 1320px;
  --maxw-hero: 1680px;       /* the strip does not read at prose measure */

  /* type */
  --display: Anton, "Arial Narrow", sans-serif;
  --text: Archivo, ui-sans-serif, system-ui, -apple-system, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --hand: Caveat, "Segoe Script", cursive;

  /* materials — produced by assets/make-assets.py, not faked with gradients */
  --grain:  url("img/grain.png");
  --leak-img: url("img/leak.png");
  --stain-img: url("img/stain.png");
  --soot:   url("img/soot.png");
  --ink:    url("img/ink.png");
  --perfs: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='52'%3E%3Crect x='6' y='16' width='14' height='20' rx='3' fill='%230E0F10'/%3E%3C/svg%3E");
  /* a perforation punched in dark stock reads as its lit edge, not as a hole */
  --perfs-lit: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='52'%3E%3Crect x='6' y='16' width='14' height='20' rx='3' fill='%234A5157'/%3E%3C/svg%3E");
  --perfs-h: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='52' height='26'%3E%3Crect x='16' y='6' width='20' height='14' rx='3' fill='%230E0F10'/%3E%3C/svg%3E");
}

/* --- reset + browser surfaces -------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scrollbar-color: var(--edge-strong) var(--base-dark);
  scrollbar-width: thin;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--leader);
  color: var(--emulsion);
  font: 400 1.0625rem/1.65 var(--text);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The page is printed on emulsion. Two fixed layers carry the stock: grain
   (tiled, close) and hand-processing damage (one sheet, far). They travel at
   different rates as the page scrolls, so the material sits in front of the
   content rather than on it. */
.film {
  position: fixed; left: 0; right: 0; top: -30vh; height: 160vh;
  z-index: 60; pointer-events: none;
  transform: translate3d(0, var(--film-y, 0px), 0);
}
/* soft-light over #0E0F10 is very nearly the identity function, so the stock
   would exist in the stylesheet and nowhere on screen. `screen` lifts it. */
.film--grain {
  background: var(--grain) repeat 0 0 / 256px 256px;
  opacity: .34; mix-blend-mode: screen;
}
.film--damage {
  background: url("img/scratches.png") no-repeat center top / cover;
  opacity: .26; mix-blend-mode: screen;
}
@media (prefers-reduced-motion: reduce) { .film { transform: none; } }

::selection { background: var(--leak); color: var(--leader); }
:root { caret-color: var(--leak); accent-color: var(--leak); }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--base-dark); }
::-webkit-scrollbar-thumb { background: var(--edge-strong); border: 3px solid var(--base-dark); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--base-gray); }

:focus-visible {
  outline: 2px solid var(--leak);
  outline-offset: 3px;
  border-radius: 2px;
}

a { color: var(--emulsion-hi); text-decoration-color: var(--leak-dim); text-underline-offset: .22em; text-decoration-thickness: 1px; }
a:hover { text-decoration-color: var(--leak); }

img, svg { max-width: 100%; }
h1, h2, h3, h4 { margin: 0; font-weight: 400; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

/* --- type ----------------------------------------------------------------- */

.display {
  font-family: var(--display);
  font-size: clamp(2.7rem, 6.6vw, 5rem);
  line-height: .94;
  letter-spacing: -.015em;
  color: var(--emulsion-hi);
  text-transform: uppercase;
}
.section-head {
  font-family: var(--display);
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: .98;
  letter-spacing: -.01em;
  color: var(--emulsion-hi);
  text-transform: uppercase;
  text-wrap: balance;
}
.sub-head {
  font-family: var(--display);
  font-size: clamp(1.15rem, 1.9vw, 1.45rem);
  line-height: 1.1;
  color: var(--emulsion-hi);
  text-transform: uppercase;
  letter-spacing: .005em;
}
/* Ink erosion on the display lettering.

   Deliberately an overlay and NOT a mask. A mask governs whether the text
   paints at all, so a texture that fails to load — or an engine that reads the
   image differently — erases the headline. This layer can only darken: no
   image, no blend support, no overlay, and the type simply prints clean. */
.display, .section-head { position: relative; }
.display::after, .section-head::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  mix-blend-mode: multiply;
  opacity: .85;
}
.display::after { background: var(--ink) repeat 0 0 / 300px 94px; }
.section-head::after { background: var(--ink) repeat 0 0 / 250px 78px; }

.lede { font-size: 1.16rem; line-height: 1.6; color: var(--emulsion); max-width: 60ch; }
.prose { max-width: 68ch; }
.prose + .prose { margin-top: var(--gap-2); }
.dim { color: var(--base-gray); }

/* the stamped edge-code label: the world's own marginalia, never a kicker */
.label {
  font-family: var(--mono);
  font-size: .688rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--base-gray);
}
.label--leak { color: var(--leak); }

.hand {
  font-family: var(--hand);
  font-size: 1.5rem;
  line-height: 1;
  color: var(--sepia);
}

code, kbd, samp, pre { font-family: var(--mono); font-variant-ligatures: none; }
:not(pre) > code {
  font-size: .86em;
  color: var(--emulsion-hi);
  background: var(--shadow);
  border: 1px solid var(--edge);
  border-radius: var(--r-chip);
  padding: .08em .34em;
}
.tnum { font-variant-numeric: tabular-nums; }

/* --- layout --------------------------------------------------------------- */

[id] { scroll-margin-top: 5.5rem; }   /* the masthead is sticky */

.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: clamp(1rem, 4vw, 2.5rem); }
.section { padding-block: var(--gap-6); position: relative; }
.section--tight { padding-block: var(--gap-5); }
.rule { border: 0; border-top: 1px solid var(--edge); margin: 0; }

.section-intro { display: grid; gap: var(--gap-3); margin-bottom: var(--gap-4); }
.section-intro .section-head { margin-top: .1em; }

/* --- the film frame: the one container this world has --------------------- */

/* The emulsion belongs on the things that are film — the strip, its frames,
   the cells, the chrome. It does NOT go over a reading surface: a paragraph
   set on grain is a paragraph you have to fight, so the notes rows, the data
   tables and the long prose sit on clean stock. */
.frame, .tape, .strip, .cell {
  background-image: var(--grain);
  background-repeat: repeat;
  background-size: 256px 256px;
  background-blend-mode: screen;
}

.frame {
  position: relative;
  background-color: var(--shadow);
  border: 1px solid var(--edge);
  border-radius: var(--r-frame);
  /* the rebate: a film frame has a hard edge on the emulsion side */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.045), 0 2px 10px rgba(0,0,0,.5);
}
/* perforated ends, drawn not decorated — this is what makes it film */
.frame--perf::before, .frame--perf::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 13px;
  background: var(--perfs) repeat-y center / 13px 26px;
  opacity: .85; pointer-events: none;
}
.frame--perf::before { left: 0; }
.frame--perf::after { right: 0; transform: scaleX(-1); }

/* --- controls ------------------------------------------------------------- */

/* A control in this world is a cell of film: perforated ends, and a leak that
   burns across it when you reach for it. */
.btn {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; gap: .7rem;
  font-family: var(--mono); font-size: .8rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; text-decoration: none;
  padding: .95rem 2.1rem;
  border-radius: 3px;
  border: 1px solid transparent;
  cursor: pointer; overflow: hidden;
  transition: background-color .18s cubic-bezier(.2,.8,.3,1), color .18s, border-color .18s, box-shadow .18s;
}
.btn::before, .btn::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 8px; z-index: 3;
  background: var(--perfs) repeat-y center / 8px 17px;
  opacity: .42; pointer-events: none;
}
.btn::before { left: 0; }
.btn::after { right: 0; transform: scaleX(-1); }
.btn > * { position: relative; z-index: 4; }
.btn__burn {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: var(--leak-img) no-repeat right center / auto 100%;
  opacity: 0; transform: translateX(24%);
  transition: opacity .3s cubic-bezier(.16,1,.3,1), transform .42s cubic-bezier(.16,1,.3,1);
}
.btn:hover .btn__burn, .btn:focus-visible .btn__burn { opacity: .88; transform: none; }
@media (prefers-reduced-motion: reduce) { .btn__burn { transition: opacity .01s; transform: none; } }
.btn--primary {
  background-color: var(--leak); color: var(--leader);
  background-image: var(--grain); background-size: 256px 256px; background-blend-mode: soft-light;
  border-color: var(--leak);
  box-shadow: 0 3px 18px -4px rgba(255,138,51,.5), 0 1px 2px rgba(0,0,0,.6);
}
.btn--primary:hover { background-color: var(--emulsion-max); border-color: var(--emulsion-max); box-shadow: 0 5px 26px -4px rgba(255,138,51,.65), 0 1px 2px rgba(0,0,0,.6); }
/* On dark stock the punched hole is the light thing, not the dark thing, so
   the ghost cell gets a lit perforation and a base to punch it out of. */
.btn--ghost { background-color: var(--base-dark); color: var(--emulsion-hi); border-color: var(--edge-strong); }
.btn--ghost::before, .btn--ghost::after { background-image: var(--perfs-lit); opacity: .55; }
.btn--ghost:hover::before, .btn--ghost:hover::after { opacity: .8; }
.btn--ghost:hover { border-color: var(--leak); color: var(--emulsion-max); }
.btn svg { flex: none; }

/* the install line, set as a frame you can take off the bench */
.install {
  display: flex; align-items: stretch; gap: 0;
  position: relative;
  background: var(--base-dark);
  border: 1px solid var(--edge-strong);
  border-radius: var(--r-frame);
  overflow: hidden;
  max-width: 30rem;
}
.install__cmd {
  flex: 1 1 auto; display: flex; align-items: baseline; gap: .6rem;
  padding: .9rem 1rem; min-width: 0;
  font-family: var(--mono); font-size: .875rem; line-height: 1.5;
  color: var(--emulsion-hi);
  /* it wraps rather than scrolling: a command clipped mid-word under the copy
     button is a command nobody can read, and a hidden scrollbar hides that. */
  white-space: normal; overflow-wrap: anywhere;
}
.install__prompt { color: var(--leak); flex: none; user-select: none; }
.install__copy {
  flex: none; display: inline-flex; align-items: center; gap: .5rem;
  padding: 0 1.05rem;
  background: var(--shadow-2); color: var(--emulsion);
  border: 0; border-left: 1px solid var(--edge-strong);
  font-family: var(--mono); font-size: .7rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  cursor: pointer;
  transition: background-color .18s, color .18s;
}
.install__copy:hover { background: var(--leak); color: var(--leader); }
.install__copy[data-state="done"] { background: var(--leak); color: var(--leader); }

/* --- header --------------------------------------------------------------- */

.masthead {
  position: sticky; top: 0; z-index: 60;
  background: rgba(14,15,16,.86);
  backdrop-filter: blur(9px) saturate(120%);
  border-bottom: 1px solid var(--edge);
}
.masthead__in { display: flex; align-items: center; gap: var(--gap-3); min-height: 62px; }
.brand { display: inline-flex; align-items: center; gap: .65rem; text-decoration: none; margin-right: auto; }
.brand__mark { flex: none; color: var(--leak); }
.brand__name {
  font-family: var(--display); font-size: 1.32rem; letter-spacing: .11em;
  color: var(--emulsion-hi); text-transform: uppercase; line-height: 1;
}
.brand__meta { font-family: var(--mono); font-size: .6rem; letter-spacing: .2em; color: var(--base-gray); line-height: 1; margin-top: .28rem; white-space: nowrap; }
@media (max-width: 520px) { .brand__meta { display: none; } }
.nav { display: flex; align-items: center; gap: var(--gap-3); }
.nav a {
  font-family: var(--mono); font-size: .72rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--base-gray); text-decoration: none;
  padding: .4rem 0; border-bottom: 1px solid transparent;
  transition: color .16s, border-color .16s;
}
.nav a:hover { color: var(--emulsion-hi); border-bottom-color: var(--leak); }
.masthead .btn { padding: .6rem 1.55rem; font-size: .7rem; }
@media (max-width: 900px) { .nav { display: none; } }

/* --- hero ----------------------------------------------------------------- */

.hero { position: relative; border-bottom: 1px solid var(--edge); overflow: hidden; }
.hero__in {
  display: grid; gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.24fr);
  align-items: center;
  padding-block: clamp(3rem, 7vw, 5.5rem);
  max-width: var(--maxw-hero);   /* the hero breaks the reading measure */
}
@media (max-width: 1000px) { .hero__in { grid-template-columns: minmax(0,1fr); } }

.hero__copy { display: grid; gap: var(--gap-3); min-width: 0; }
.hero__lede { max-width: 46ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--gap-2); align-items: center; margin-top: var(--gap-1); }
.hero__trust { display: flex; flex-wrap: wrap; gap: var(--gap-1) var(--gap-3); margin-top: var(--gap-2); }
.hero__trust li { display: inline-flex; align-items: center; gap: .45rem; }

/* the strip: a length of film on the inspection bench */
.bench {
  display: grid; grid-template-columns: minmax(0, 1fr) 17.5rem; gap: var(--gap-2);
  align-items: start; min-width: 0;
  margin: 0; padding: 0; border: 0;    /* it is a fieldset: the group is the six records */
}
@media (max-width: 1240px) { .bench { grid-template-columns: minmax(0,1fr); } }
@media (min-width: 1500px) {
  .rec__json { -webkit-line-clamp: 3; }
  .rec { min-height: 7.6rem; }
}
/* The record has to fit whatever width the strip gets. Narrower frame, fewer
   characters per line, so the line budget goes up rather than the record
   getting cut before it reaches the value that failed. */
@media (max-width: 1240px) {
  .rec__json { -webkit-line-clamp: 3; }
  .rec { min-height: 7.4rem; }
}
@media (max-width: 620px) {
  .rec { font-size: .74rem; padding: .95rem 1rem .95rem 2.4rem; min-height: 8rem; }
  .rec__json { -webkit-line-clamp: 4; }
  .rec__no { font-size: 1.25rem; }
}

.strip {
  position: relative;
  display: grid; grid-template-columns: var(--perf) minmax(0,1fr) var(--perf);
  background-color: var(--base-dark);
  border-radius: 3px;
  box-shadow: 0 18px 50px -18px rgba(0,0,0,.9), 0 0 0 1px var(--edge);
}
.strip__margin {
  background: var(--perfs) repeat-y center / var(--perf) 60px;
  position: relative;
}
/* leader edge: soot and wear where the gate and fingers ride */
.strip__margin::after {
  content: ""; position: absolute; inset: 0;
  background: var(--soot) repeat-y center / 100% 600px;
  opacity: .8; mix-blend-mode: multiply; pointer-events: none;
}
.strip__edgecode {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(180deg);
  writing-mode: vertical-rl;
  font-family: var(--mono); font-size: .66rem; font-weight: 700; letter-spacing: .3em;
  color: var(--edgecode); white-space: nowrap;
  pointer-events: none;
}
.strip__frames { display: grid; gap: 2px; padding-block: 2px; min-width: 0; }

/* one record = one frame */
.rec {
  position: relative; display: block; width: 100%; text-align: left;
  background-color: rgba(27, 31, 34, .62); border: 0; border-radius: 2px;
  padding: 1.05rem 1.2rem 1.05rem 2.7rem;
  min-height: 6.6rem;   /* frames on a strip are the same height, always */
  color: var(--emulsion); cursor: pointer;
  font-family: var(--mono); font-size: .8rem; line-height: 1.58;
  overflow: hidden;
  transition: background-color .2s cubic-bezier(.2,.8,.3,1);
}
.rec__no {
  position: absolute; left: .6rem; top: .6rem;
  font-family: var(--hand); font-size: 1.45rem; color: var(--base-gray);
  line-height: 1; transition: color .2s;
}
.rec__json {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  white-space: normal; overflow-wrap: anywhere;
  color: var(--base-gray);
}
.rec__verdict {
  display: flex; align-items: baseline; gap: .4rem; margin-top: .35rem;
  font-size: .69rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--base-gray);
}
.rec__glyph { position: relative; top: .1em; }
.rec__glyph { flex: none; }

/* A marked frame is real light-leak stock burning in from the right edge. The
   mark is never colour alone: every struck frame also carries a cross glyph
   and the name of the rule that struck it. */
.rec { isolation: isolate; }
.rec > * { position: relative; z-index: 2; }
.rec[data-mark="struck"] {
  background-image: var(--leak-img);
  background-blend-mode: screen;
  background-repeat: no-repeat;
  background-position: right center;
  background-size: auto 100%;
}
/* The bloom: the leak burns across the frame as it becomes the selected one.
   This is the page's one authored moment. */
.rec[data-mark="struck"]::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: var(--leak-img) no-repeat right center / auto 100%;
  opacity: 0;
}
.rec__input:checked + .rec[data-mark="struck"]::after { opacity: .92; }
@media (prefers-reduced-motion: no-preference) {
  .rec__input:checked + .rec[data-mark="struck"]::after {
    animation: leak-bloom .66s cubic-bezier(.16,1,.3,1) both;
  }
  @keyframes leak-bloom {
    from { opacity: 0; transform: translateX(16%) scaleX(.72); filter: blur(7px); }
    to   { opacity: .92; transform: none; filter: none; }
  }
}
.rec[data-mark="struck"] .rec__no { color: var(--leak); }
.rec[data-mark="struck"] .rec__verdict { color: var(--leak); }
.rec[data-mark="struck"] .rec__json { color: var(--emulsion); }
.rec[data-mark="clean"] .rec__verdict { color: var(--base-gray); }

/* selection is native: a radio group, so arrow keys work without a line of script */
.rec__input:checked + .rec { background-color: rgba(36, 40, 44, .82); box-shadow: inset 0 0 0 1px var(--edge-strong); }
.rec__input:checked + .rec[data-mark="struck"] {
  background-color: rgba(36, 40, 44, .74);
  box-shadow: inset 0 0 0 1px rgba(255,138,51,.5);
}
.rec__input:checked + .rec .rec__json { color: var(--emulsion-hi); }
.rec__input:focus-visible + .rec { outline: 2px solid var(--leak); outline-offset: -2px; }
.rec:hover { background-color: rgba(36, 40, 44, .78); }
.rec[data-mark="struck"]:hover { background-color: rgba(36, 40, 44, .72); }

/* the rail: what the inspector wrote down */
.rail { display: grid; gap: 2px; align-content: start; min-width: 0; }
.rail__panel { display: none; gap: 2px; }
.rail__panel--1 { display: grid; }           /* the state without :has() support */
.bench:has(.rec__input:checked) .rail__panel { display: none; }
.bench:has(#rec-0:checked) .rail__panel--0,
.bench:has(#rec-1:checked) .rail__panel--1,
.bench:has(#rec-2:checked) .rail__panel--2,
.bench:has(#rec-3:checked) .rail__panel--3,
.bench:has(#rec-4:checked) .rail__panel--4,
.bench:has(#rec-5:checked) .rail__panel--5 { display: grid; }
.rail__cell { background-color: var(--shadow); border: 1px solid var(--edge); border-radius: var(--r-chip); padding: .9rem 1rem; }
.rail__k { display: block; margin-bottom: .3rem; }
.rail__v { font-family: var(--mono); font-size: .86rem; color: var(--emulsion-hi); line-height: 1.45; overflow-wrap: anywhere; }
.rail__v--leak { color: var(--leak); }
.rail__note { font-family: var(--text); font-size: .89rem; line-height: 1.55; color: var(--emulsion); }

/* --- the contact strip (four boundaries) ---------------------------------- */
/* Four cells on one length of film, sprocketed top and bottom. Not four cards:
   a card row is the arrangement this page's thesis refuses. */

.contact {
  position: relative;
  background-color: var(--base-dark);
  border-radius: 3px;
  overflow: hidden;
  box-shadow: 0 14px 44px -20px rgba(0,0,0,.9), 0 0 0 1px var(--edge);
}
.contact__perf {
  position: relative; height: 24px;
  background: var(--perfs-h) repeat-x center / 52px 24px;
}
.contact__perf::after {
  content: ""; position: absolute; inset: 0;
  background: var(--soot) repeat-x center / 600px 100%;
  opacity: .65; mix-blend-mode: multiply; pointer-events: none;
}
.contact__cells { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 980px) { .contact__cells { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 600px) { .contact__cells { grid-template-columns: minmax(0,1fr); } }

.cell {
  position: relative; isolation: isolate; overflow: hidden;
  display: grid; gap: .5rem; align-content: start;
  padding: var(--gap-3) clamp(1rem, 2.2vw, 1.6rem);
  background-color: var(--shadow);
  border-left: 1px solid var(--edge);
  text-decoration: none;
  transition: background-color .2s cubic-bezier(.2,.8,.3,1);
}
.cell:first-child { border-left: 0; }
@media (max-width: 980px) { .cell:nth-child(3) { border-left: 0; } .cell:nth-child(n+3) { border-top: 1px solid var(--edge); } }
@media (max-width: 600px) { .cell { border-left: 0; border-top: 1px solid var(--edge); } .cell:first-child { border-top: 0; } }

.cell__burn {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--leak-img) no-repeat right center / auto 100%;
  opacity: 0; transform: translateX(20%);
  transition: opacity .3s cubic-bezier(.16,1,.3,1), transform .44s cubic-bezier(.16,1,.3,1);
}
.cell:hover .cell__burn, .cell:focus-visible .cell__burn { opacity: .5; transform: none; }
@media (prefers-reduced-motion: reduce) { .cell__burn { transition: opacity .01s; transform: none; } }

.cell__cmd, .cell__text { position: relative; z-index: 1; }
.cell__cmd {
  font-family: var(--mono); font-size: .8rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--emulsion-hi);
}
.cell:hover .cell__cmd { color: var(--emulsion-max); }
.cell__text { font-size: .875rem; line-height: 1.5; color: var(--base-gray); }
.cell:hover .cell__text { color: var(--emulsion); }

/* --- the two reels (before / after) --------------------------------------- */
/* Two lengths of the same week laid side by side on the bench. Deliberately NOT
   two cards: each beat is a frame in a sprocketed strip, so the comparison reads
   in the world's own grammar. The left reel ends in struck frames because the
   damage was always there and nothing looked; the right reel is struck once, at
   the boundary, and then goes quiet. */

.contrast {
  display: grid; gap: var(--gap-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* stretch, not start: the two reels are the same week, so their frames should
     square up against each other rather than drift out of register */
  align-items: stretch;
}
@media (max-width: 900px) { .contrast { grid-template-columns: minmax(0, 1fr); } }

.reel {
  position: relative;
  background-color: var(--base-dark);
  background-image: var(--grain);
  background-repeat: repeat;
  background-size: 256px 256px;
  background-blend-mode: screen;
  border: 1px solid var(--edge);
  border-radius: var(--r-frame);
  overflow: hidden;
}

.reel__head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--gap-1);
  padding: .7rem .9rem .7rem 1.9rem;
  background: var(--shadow);
  border-bottom: 1px solid var(--edge);
}
.reel__verdict {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--mono); font-size: .69rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
}
/* Never colour alone: each verdict carries its glyph and says what happened. */
.reel__verdict--bad { color: var(--leak); }
.reel__verdict--good { color: var(--emulsion-hi); }

/* the sprocket rail: this is film, not a panel */
.reel__frames { position: relative; padding: 0; margin: 0; list-style: none; }
.reel__frames::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 18px;
  background:
    var(--soot) repeat-y center / 100% 600px,
    var(--perfs-lit) repeat-y center / 18px 36px,
    var(--base-dark);
  background-blend-mode: multiply, normal, normal;
  opacity: .9;
  border-right: 1px solid var(--edge);
  pointer-events: none;
}

.beat {
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: 5.6rem minmax(0, 1fr); gap: var(--gap-2);
  padding: .85rem 1rem .85rem 1.9rem;
  border-top: 1px solid var(--edge);
}
.beat:first-child { border-top: 0; }
@media (max-width: 560px) {
  .beat { grid-template-columns: minmax(0, 1fr); gap: .3rem; }
}

.beat__when {
  font-family: var(--mono); font-size: .69rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--base-gray);
  padding-top: .12em;
}
.beat__what { font-size: .95rem; line-height: 1.55; color: var(--emulsion); }
.beat__what code { font-size: .84em; }

/* A struck beat: the damage surfacing far downstream, on real leak stock. */
.beat--struck {
  background: var(--leak-img) no-repeat right center / auto 100%;
  background-color: rgba(27, 31, 34, .5);
  /* Keep the copy clear of the hot end of the burn. The leak is scaled to the
     beat's height, so it occupies a fixed strip on the right; a line that ran
     the full measure would finish on blown highlight. */
  padding-right: 3.6rem;
}
.beat--struck .beat__when { color: var(--leak); }
.beat--struck .beat__what { color: var(--emulsion-hi); }

/* The one beat where the gate fires. Same stock, but it is a verdict rather
   than a discovery, so it burns from the margin the check sits in. */
.beat--marked { background-color: rgba(36, 40, 44, .72); box-shadow: inset 3px 0 0 0 var(--leak); }
.beat--marked .beat__when { color: var(--leak); }
.beat--marked .beat__what { color: var(--emulsion-hi); }

/* Clean stock, and the point of the whole page. */
.beat--quiet .beat__what { color: var(--base-gray); }

/* --- transcript ----------------------------------------------------------- */

.tape {
  position: relative;
  background-color: var(--base-dark);
  border: 1px solid var(--edge);
  border-radius: var(--r-frame);
  overflow: hidden;
  padding-left: 18px;            /* the sprocket rail rides in this gutter */
}
/* every transcript is a length of film, not a code box */
.tape::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 18px;
  background:
    var(--soot) repeat-y center / 100% 600px,
    var(--perfs-lit) repeat-y center / 18px 36px,
    var(--base-dark);
  background-blend-mode: multiply, normal, normal;
  opacity: .9;
  border-right: 1px solid var(--edge);
  pointer-events: none;
}
.tape__bar {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .6rem .9rem;
  background: var(--shadow);
  border-bottom: 1px solid var(--edge);
}
.tape__bar .label { color: var(--base-gray); }
.tape__bar .label + .label::before {
  content: "·"; margin-right: .55rem; color: var(--edge-strong);
}
.tape__body { margin: 0; padding: 1rem 1.1rem; overflow-x: auto; scrollbar-width: thin; scrollbar-color: var(--edge-strong) var(--base-dark); }
.tape__body:focus-visible { outline-offset: -2px; }
.tape code { font-size: .78rem; line-height: 1.62; display: block; white-space: pre; color: var(--emulsion); background: none; border: 0; padding: 0; }

/* transcript ink — every colour here is a verdict, and each is shape-marked too */
.t-dim { color: var(--base-gray); }
.t-cmd { color: var(--emulsion-hi); }
.t-flag { color: var(--sepia); }
.t-leak { color: var(--leak); }
.t-stain { color: var(--sepia); }
.t-key { color: var(--emulsion-hi); }
.t-str { color: var(--sepia); }
.t-note { color: var(--base-gray); font-style: italic; }

/* --- severity marks ------------------------------------------------------- */
/* A severity tag in a transcript is a mark on the frame: breaking burns,
   risky stains, info is unmarked stock. Shape and word carry it too. */
.sev { padding: 0 .12em; border-radius: 2px; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
/* The chip is a dim burn, not a blaze: the mark has to read as material while
   the label keeps measurable contrast, so the stock is multiplied down. */
.sev--breaking {
  background-image: var(--leak-img); background-size: 100% 100%;
  background-position: 100% 50%; background-repeat: no-repeat;
  background-color: #2A1206; background-blend-mode: multiply;
  color: var(--leak);
}
.sev--risky {
  background-image: var(--stain-img); background-size: 100% 260%;
  background-position: 50% 34%; background-repeat: no-repeat;
  background-color: #241C10; background-blend-mode: multiply;
  color: var(--sepia);
}

/* --- severity legend + findings ------------------------------------------- */

.legend { display: flex; flex-wrap: wrap; gap: var(--gap-1) var(--gap-3); }
.legend__item { display: inline-flex; align-items: center; gap: .45rem; font-family: var(--mono); font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; color: var(--base-gray); }
.legend__swatch { width: 26px; height: 12px; border-radius: 2px; flex: none; display: inline-block; }
.legend__swatch--breaking { background: var(--leak-img) right center / auto 100% no-repeat, var(--shadow); }
.legend__swatch--risky { background: var(--stain-img) 50% 32% / 260% auto no-repeat, var(--shadow); }
.legend__swatch--info { background: linear-gradient(90deg, var(--shadow), var(--base-gray)); }

/* --- data table ----------------------------------------------------------- */

.tbl-scroll { background-color: var(--base-dark); overflow-x: auto; scrollbar-width: thin; scrollbar-color: var(--edge-strong) var(--base-dark); border: 1px solid var(--edge); border-radius: var(--r-frame); }
table { width: 100%; border-collapse: collapse; min-width: 34rem; }
.tbl { border: 1px solid var(--edge); border-radius: var(--r-frame); overflow: hidden; background-color: var(--base-dark); }
.tbl__cap {
  padding: .8rem 1rem; background: var(--shadow);
  border-bottom: 1px solid var(--edge);
}
.tbl > .tbl-scroll { border: 0; border-radius: 0; }
th, td { text-align: left; padding: .75rem 1rem; border-bottom: 1px solid var(--edge); vertical-align: top; font-size: .875rem; line-height: 1.5; }
thead th {
  font-family: var(--mono); font-size: .65rem; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--base-gray);
  background: var(--shadow); position: sticky; top: 0;
}
tbody tr:last-child th, tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: rgba(255,255,255,.018); }
tbody th { font-weight: 600; color: var(--emulsion-hi); font-family: var(--mono); font-size: .8rem; }
td .dim { display: block; font-size: .82rem; margin-top: .2rem; }
.cell-code { font-size: 1.05rem; font-weight: 700; color: var(--leak); }

/* --- panels (pricing seam, condition notes) -------------------------------- */

.split { display: grid; gap: var(--gap-3); grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (max-width: 820px) { .split { grid-template-columns: minmax(0,1fr); } }

.panel { padding: clamp(1.3rem, 2.6vw, 2rem); display: grid; gap: var(--gap-2); align-content: start; }
.panel__list { display: grid; gap: .6rem; margin-top: .3rem; }
.panel__list li { display: grid; grid-template-columns: 1.1rem minmax(0,1fr); gap: .6rem; font-size: .92rem; line-height: 1.5; }
.panel__list svg { margin-top: .28rem; color: var(--leak); }
.panel--vault { background: var(--base-dark); }
.panel--vault .panel__list svg { color: var(--base-gray); }

/* --- condition notes ------------------------------------------------------ */

.notes { background-color: var(--base-dark); display: grid; gap: 0; border: 1px solid var(--edge); border-radius: var(--r-frame); overflow: hidden; }
.notes__row { display: grid; grid-template-columns: 12rem minmax(0,1fr); gap: var(--gap-3); padding: var(--gap-3); border-bottom: 1px solid var(--edge); }
.notes__row:last-child { border-bottom: 0; }
.notes__row:nth-child(odd) { background: rgba(255,255,255,.012); }
@media (max-width: 720px) { .notes__row { grid-template-columns: minmax(0,1fr); gap: .6rem; } }
.notes__k { align-self: start; }

/* --- install matrix ------------------------------------------------------- */

.matrix { display: grid; gap: 2px; grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (max-width: 720px) { .matrix { grid-template-columns: minmax(0,1fr); } }
.matrix__cell { background-color: var(--shadow); border: 1px solid var(--edge); border-radius: var(--r-chip); padding: .9rem 1rem; display: grid; gap: .45rem; }
.matrix__cmd { font-family: var(--mono); font-size: .8rem; color: var(--emulsion-hi); overflow-x: auto; white-space: nowrap; }

/* --- footer --------------------------------------------------------------- */

.foot { border-top: 1px solid var(--edge); background: var(--base-dark); padding-block: var(--gap-4); }
.foot__in { display: flex; flex-wrap: wrap; gap: var(--gap-3); align-items: center; justify-content: space-between; }
.foot__links { display: flex; flex-wrap: wrap; gap: var(--gap-3); }
.foot__links a { font-family: var(--mono); font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--base-gray); text-decoration: none; }
.foot__links a:hover { color: var(--leak); }
.foot__note { font-size: .82rem; color: var(--base-gray); max-width: 46ch; }

/* --- utilities ------------------------------------------------------------ */

.stack-1 { display: grid; gap: var(--gap-1); }
.stack-2 { display: grid; gap: var(--gap-2); }
.stack-3 { display: grid; gap: var(--gap-3); }
.stack-4 { display: grid; gap: var(--gap-4); }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: 1rem; top: -4rem; z-index: 100;
  background: var(--leak); color: var(--leader); padding: .7rem 1.1rem;
  font-family: var(--mono); font-size: .75rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; text-decoration: none; border-radius: var(--r-chip);
  transition: top .18s cubic-bezier(.2,.8,.3,1);
}
.skip:focus { top: 1rem; }

/* --- the one authored motion: film transport ------------------------------ */
/* The strip advances frame by frame. Nothing else on this page moves on its
   own; hover and focus are the only other transitions.                       */

@media (prefers-reduced-motion: no-preference) {
  .rail__panel { animation: pull-down .42s cubic-bezier(.16,1,.3,1); }
  @keyframes pull-down {
    from { transform: translateY(-.55rem); opacity: 0; filter: blur(2px); }
    to   { transform: none; opacity: 1; filter: none; }
  }
}
