/* The projection booth (see DESIGN.md). A dark room where the screen is the
   brightest thing; films are steel cans named only by the tape across them;
   grease-pencil red marks what is showing and nothing else. */

@font-face {
  font-family: "Permanent Marker";
  src: url(/assets/fonts/permanent-marker.woff2) format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url(/assets/fonts/barlow-condensed-500.woff2) format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url(/assets/fonts/barlow-condensed-700.woff2) format("woff2");
  font-weight: 700;
  font-display: swap;
}

:root {
  color-scheme: dark;
  --booth-black: #0a0c0e;
  --booth-wall: #12161a;
  --booth-panel: #1a1f24;
  --rail: #2a3138;
  --steel-lo: #3b444c;
  --steel: #8d979f;
  --steel-hi: #d5dce0;
  --tape: #d6d0bd;
  --tape-shade: #b9b29b;
  --grease-black: #1b1a18;
  --grease-red: #e0412f;
  --grease-red-ink: #b3301f; /* red on tape, dark enough to read */
  --tape-ink: #4a463c;       /* second line on tape */
  --beam: #f5f2ea;
  --text: #e3e7ea;
  --text-dim: #9aa4ac;
  --text-faint: #6f7982;
  --ok: #57c46b;
  --warn: #e2a93b;
  --bad: #ff6a5c;

  --hand: "Permanent Marker", "Marker Felt", cursive;
  --stamp: "Barlow Condensed", "Arial Narrow", sans-serif;
  --sans: system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  --gutter: 16px;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --can: clamp(128px, 34vw, 176px);
}
@media (min-width: 720px) { :root { --gutter: 24px; } }

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--booth-black);
  color: var(--text);
  font: 15px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

a { color: var(--steel-hi); }
:focus-visible { outline: 2px solid var(--beam); outline-offset: 3px; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
button:disabled { opacity: .4; cursor: not-allowed; }

/* Printed booth labels: tracked condensed caps. */
.stamp {
  margin: 0;
  font: 700 13px/1 var(--stamp);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

kbd {
  font: 500 12px/1 var(--stamp);
  padding: 2px 5px 3px;
  border: 1px solid var(--rail);
  border-radius: 4px;
  color: var(--text-dim);
  text-transform: none;
}

/* ------------------------------------------------------------------- top bar */

header.top {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 1280px;
  margin: 0 auto;
  padding: 12px var(--gutter);
  padding-top: max(12px, env(safe-area-inset-top));
  min-height: 64px;
}
.mark {
  font: 700 15px/1 var(--stamp);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--steel);
  white-space: nowrap;
}

/* The slate: the threaded film's tape, laid across the top bar. */
.slate {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  text-align: left;
}
.slate[hidden] { display: none; }
.slate .now { color: var(--grease-red); white-space: nowrap; }
.slate-tape {
  min-width: 0;
  max-width: min(100%, 520px);
  padding: 7px 16px 6px;
  transform: rotate(-1.2deg);
}
.slate-tape .title {
  display: block;
  font-size: clamp(1rem, 2.6vw, 1.25rem);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Threading lays the new label down from the left, like tape off a roll. */
.slate.laying .slate-tape { animation: lay .52s var(--ease-out) both; }
@keyframes lay {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

.boothbtn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  padding: 9px 12px;
  border: 1px solid var(--rail);
  border-radius: 6px;
  background: var(--booth-panel);
  font: 700 13px/1 var(--stamp);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text);
  white-space: nowrap;
}
.boothbtn:hover { border-color: var(--steel); }
.boothbtn[aria-expanded="true"] { background: var(--steel-lo); }
@media (max-width: 560px) {
  header.top { flex-wrap: wrap; gap: 10px 12px; }
  .slate { order: 3; flex-basis: 100%; }
  .boothbtn kbd { display: none; }
}

/* --------------------------------------------------------------------- tape */

.tape {
  display: block;
  background:
    linear-gradient(180deg, rgb(255 255 255 / .16), transparent 40%, rgb(0 0 0 / .06)),
    var(--tape);
  color: var(--grease-black);
  font-family: var(--hand);
  line-height: 1.05;
  border-radius: 2px;
  box-shadow: 0 1px 2px rgb(0 0 0 / .45);
  /* Torn ends: a few short teeth at each side. */
  clip-path: polygon(
    0 6%, 1.6% 0, 98.4% 2%, 100% 9%, 99% 30%, 100% 52%, 98.8% 74%, 100% 94%,
    98% 100%, 1.4% 98%, 0 90%, 1.2% 70%, 0 48%, 1.1% 26%);
}

/* -------------------------------------------------------------------- stage */

main.room {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 var(--gutter) max(40px, env(safe-area-inset-bottom));
}

.stage {
  position: relative;
  background: #000;
  border-radius: 4px;
  overflow: hidden;
  min-height: 200px;
  box-shadow: 0 30px 60px -30px rgb(0 0 0 / .9);
}
.stage .media {
  display: grid;
  place-items: center;
  min-height: 200px;
}
/* Once there is a picture, the stage is exactly its size: no letterbox band
   around a wide film on a narrow phone. */
.stage:has(.media > canvas, .media > video) { min-height: 0; }
.stage .media:has(> canvas, > video) { min-height: 0; }
.stage .media > video, .stage .media > canvas {
  display: block;
  width: 100%;
  height: auto;
  /* Leave the top of the rack in the first viewport: the titles on the tape
     are how the next film gets picked. */
  max-height: max(220px, min(72vh, 100svh - 330px));
  background: #000;
  /* A portrait clip in a landscape stage keeps its shape. */
  object-fit: contain;
}
.stage:fullscreen { border-radius: 0; width: 100vw; height: 100vh; }
.stage:fullscreen .media { height: 100%; }
.stage:fullscreen .media > video, .stage:fullscreen .media > canvas { height: 100%; max-height: none; }

.stage .empty {
  padding: 40px 28px;
  text-align: center;
  color: var(--text-dim);
  max-width: 60ch;
}
.stage .empty code, .notes code, .booth .meta code {
  font: 12px var(--mono);
  background: var(--booth-wall);
  border: 1px solid var(--rail);
  padding: 1px 6px;
  border-radius: 4px;
  color: var(--text);
}

/* The changeover cue: the dot a projectionist watches for in the frame's top
   right. Here it blinks while the film is fetching or starved, and in its
   last seconds. */
.cue {
  position: absolute;
  top: clamp(10px, 3.5%, 22px);
  right: clamp(10px, 3.5%, 22px);
  width: clamp(12px, 2.4vw, 20px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--beam);
  box-shadow: 0 1px 3px rgb(0 0 0 / .6);
  opacity: 0;
  pointer-events: none;
}
.cue.on { animation: cue 1.1s steps(1, end) infinite; }
@keyframes cue { 0% { opacity: .9; } 55% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .cue.on { animation: none; opacity: .75; } }

/* Status line while the opaque player fetches, and in place of a blank stage
   when WebCodecs is unavailable. */
.stage .status {
  position: absolute;
  left: 0; top: 0;
  max-width: calc(100% - 60px);
  margin: 12px;
  padding: 5px 10px;
  font: 700 12px/1.3 var(--stamp);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--steel-hi);
  background: rgb(10 12 14 / .78);
  border-radius: 4px;
}
.stage .status:empty { display: none; }
.stage .status.err {
  color: var(--bad);
  text-transform: none;
  letter-spacing: .02em;
  font: 13px/1.4 var(--sans);
}

/* The browser held sound back until the user interacts. */
.stage .soundhint {
  position: absolute;
  top: 12px;
  left: 50%;
  translate: -50% 0;
  padding: 8px 14px;
  background: rgb(10 12 14 / .88);
  color: var(--beam);
  border: 1px solid var(--steel-lo);
  border-radius: 6px;
  font: 700 13px/1 var(--stamp);
  letter-spacing: .12em;
  text-transform: uppercase;
}
.stage .soundhint[hidden] { display: none; }
.bar #sound.blocked { color: var(--warn); animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .bar #sound.blocked { animation: none; } }

/* ---------------------------------------------------------------- control bar */

.bar {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 26px 8px 6px;
  background: linear-gradient(transparent, rgb(0 0 0 / .82));
  transition: opacity .2s;
}
/* Hidden while playing and the pointer is idle, like any player's. */
.stage.idle .bar { opacity: 0; pointer-events: none; }
.stage.idle { cursor: none; }

.bar .icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  color: #fff;
  border-radius: 6px;
}
.bar .icon:hover:not(:disabled) { color: var(--steel-hi); background: rgb(255 255 255 / .08); }
.bar svg { width: 22px; height: 22px; fill: currentColor; }
.bar .i-pause, .bar .i-muted { display: none; }
.bar #play.playing .i-play, .bar #sound.on .i-muted { display: none; }
.bar #play.playing .i-pause { display: block; }
.bar #sound:not(.on) .i-sound { display: none; }
.bar #sound:not(.on) .i-muted { display: block; }

.bar .time {
  font: 12px var(--mono);
  color: #eef1f3;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  padding: 0 4px;
}
@media (max-width: 420px) { .bar .time { font-size: 11px; padding: 0; } }

/* The scrubber shows what has been played and what is buffered beyond it,
   from --played and --buffered (percentages set by app.js). */
.bar input[type=range] {
  flex: 1;
  min-width: 60px;
  height: 28px;
  margin: 0 6px;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
}
.bar input[type=range]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right,
    var(--beam) 0 var(--played, 0%),
    rgb(255 255 255 / .42) var(--played, 0%) var(--buffered, 0%),
    rgb(255 255 255 / .16) var(--buffered, 0%) 100%);
}
.bar input[type=range]::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right,
    var(--beam) 0 var(--played, 0%),
    rgb(255 255 255 / .42) var(--played, 0%) var(--buffered, 0%),
    rgb(255 255 255 / .16) var(--buffered, 0%) 100%);
}
.bar input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px; height: 14px;
  margin-top: -5px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / .5);
}
.bar input[type=range]::-moz-range-thumb {
  width: 14px; height: 14px;
  border: 0;
  border-radius: 50%;
  background: #fff;
}

/* --------------------------------------------------------------------- rack */

.rack { margin-top: 28px; }
.rack h2 { display: flex; align-items: baseline; gap: 8px; padding-bottom: 4px; }
.rack .count { color: var(--steel-lo); letter-spacing: .08em; }

/* One shelf of cans, scrolled sideways. A handful of films never needs a
   grid, and a row keeps every can a thumb's reach from the screen. */
.cans {
  list-style: none;
  margin: 0 calc(-1 * var(--gutter));
  padding: 22px var(--gutter) 30px;
  display: flex;
  gap: clamp(14px, 3vw, 28px);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--steel-lo) transparent;
  /* The shelf the cans stand on. */
  background:
    linear-gradient(transparent calc(100% - 22px), var(--booth-wall) calc(100% - 22px),
      var(--booth-panel) calc(100% - 19px), var(--booth-wall) 100%);
}
.cans > li { flex: none; scroll-snap-align: start; }

.can {
  position: relative;
  display: block;
  width: var(--can);
  aspect-ratio: 1;
  border-radius: 50%;
  transition: translate .38s var(--ease-out), filter .38s var(--ease-out);
  filter: drop-shadow(0 6px 7px rgb(0 0 0 / .55));
}
.can:hover { translate: 0 -6px; }
.can:focus-visible { outline-offset: 5px; translate: 0 -6px; }
.can[aria-pressed="true"] {
  translate: 0 -14px;
  filter: drop-shadow(0 18px 15px rgb(0 0 0 / .65));
}

/* The lid: pressed steel, a rolled rim, concentric ridges and a hub. */
.can .lid {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, var(--steel-lo) 0 5.5%, var(--steel) 6% 8%, transparent 8.5%),
    repeating-radial-gradient(circle at 50% 50%,
      transparent 0 10.5%, rgb(0 0 0 / .18) 11%, rgb(255 255 255 / .16) 11.8%, transparent 12.6%),
    radial-gradient(circle at 34% 28%, var(--steel-hi), var(--steel) 42%, #6d777f 100%);
  box-shadow:
    inset 0 0 0 3px #5f6970,
    inset 0 0 0 6px var(--steel-hi),
    inset 0 0 0 8px #6d777f;
}

/* Threaded: the lid is off, showing the reel wound with film. */
.can[aria-pressed="true"] .lid {
  background:
    radial-gradient(circle at 50% 50%, var(--steel-lo) 0 5.5%, var(--steel-hi) 6% 8.5%, transparent 9%),
    conic-gradient(from 12deg, transparent 0 22%, var(--steel) 22% 28%, transparent 28% 55%,
      var(--steel) 55% 61%, transparent 61% 88%, var(--steel) 88% 94%, transparent 94%),
    repeating-radial-gradient(circle at 50% 50%, #241b16 0 1.1%, #2f241d 1.1% 1.8%),
    #241b16;
  -webkit-mask: radial-gradient(circle, #000 0 70%, transparent 70.5% 74%, #000 74.5%);
  mask: radial-gradient(circle, #000 0 70%, transparent 70.5% 74%, #000 74.5%);
  box-shadow: inset 0 0 0 4px var(--steel), inset 0 0 0 7px var(--steel-lo);
}

/* The label: tape across the lid, a little off true. */
.can .tape {
  position: absolute;
  left: 3%;
  right: 3%;
  top: 50%;
  translate: 0 -50%;
  rotate: -3deg;
  padding: 8px 10px 7px;
  text-align: center;
}
.cans > li:nth-child(3n+2) .can .tape { rotate: 2deg; }
.cans > li:nth-child(3n) .can .tape { rotate: -1deg; }
.can .title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  font-size: clamp(1rem, 3.4vw, 1.3rem);
  text-wrap: balance;
  overflow-wrap: anywhere;
}
.can .line {
  display: block;
  margin-top: 4px;
  font: 500 15px/1 var(--stamp);
  letter-spacing: .06em;
  color: var(--tape-ink);
}
.can .resume {
  display: block;
  margin-top: 4px;
  font: 700 13px/1 var(--stamp);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--grease-red-ink);
}
.can .resume:empty { display: none; }
.can[aria-pressed="true"] .resume { display: none; }

/* The grease-pencil tick on the threaded film. */
.can .tick {
  position: absolute;
  top: 1%;
  right: 4%;
  width: 34%;
  height: 34%;
  fill: none;
  stroke: var(--grease-red);
  stroke-width: 3.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 30;
  stroke-dashoffset: 30;
  filter: drop-shadow(0 1px 1px rgb(0 0 0 / .5));
}
.can[aria-pressed="true"] .tick { stroke-dashoffset: 0; transition: stroke-dashoffset .4s .18s var(--ease-out); }

.rack .none {
  padding: 8px 0 0;
  max-width: 60ch;
  color: var(--text-dim);
}

@media (prefers-reduced-motion: reduce) {
  .can, .can .tick { transition: none !important; }
  .slate.laying .slate-tape { animation: none; }
}

/* ---------------------------------------------------------------- booth log */

.booth {
  position: fixed;
  z-index: 10;
  top: 0; right: 0; bottom: 0;
  width: min(380px, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--booth-wall);
  border-left: 1px solid var(--rail);
  box-shadow: -18px 0 40px rgb(0 0 0 / .5);
  translate: 100% 0;
  visibility: hidden;
  transition: translate .36s var(--ease-out), visibility 0s .36s;
}
.booth.open { translate: 0 0; visibility: visible; transition: translate .36s var(--ease-out); }
@media (max-width: 719px) {
  .booth {
    top: auto; left: 0;
    width: 100%;
    max-height: 78vh;
    border-left: 0;
    border-top: 1px solid var(--rail);
    border-radius: 12px 12px 0 0;
    box-shadow: 0 -18px 40px rgb(0 0 0 / .5);
    translate: 0 100%;
    padding-bottom: env(safe-area-inset-bottom);
  }
}
@media (prefers-reduced-motion: reduce) { .booth, .booth.open { transition: none; } }

.booth-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 10px 10px 18px;
  border-bottom: 1px solid var(--rail);
}
.booth-head .stamp { color: var(--text); }
.boothclose { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 6px; color: var(--text-dim); }
.boothclose:hover { color: var(--text); background: var(--booth-panel); }
.boothclose svg { width: 20px; height: 20px; }

.booth-body {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 16px 18px 28px;
}

.pipeline .stamp { display: block; margin-bottom: 10px; }
.modes {
  display: flex;
  border: 1px solid var(--rail);
  border-radius: 6px;
  overflow: hidden;
}
.modes button {
  flex: 1;
  min-height: 40px;
  padding: 8px 10px;
  font: 13px/1.2 var(--sans);
  color: var(--text-dim);
  background: var(--booth-panel);
}
.modes button + button { border-left: 1px solid var(--rail); }
.modes button:hover:not(:disabled) { color: var(--text); }
.modes button[aria-pressed="true"] { background: var(--steel-lo); color: #fff; }
.booth .meta {
  margin: 10px 0 0;
  font: 12px/1.5 var(--mono);
  color: var(--text-dim);
  overflow-wrap: anywhere;
}

.panelmount { margin-top: 20px; }

/* Telemetry, rendered by telemetry.js. */
.panel {
  border: 1px solid var(--rail);
  border-radius: 6px;
  background: var(--booth-black);
  overflow: hidden;
  font: 12px var(--mono);
}
.panel h2 {
  margin: 0;
  padding: 9px 12px 8px;
  font: 700 12px/1 var(--stamp);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
  border-bottom: 1px solid var(--rail);
}
.panel .rows { padding: 4px 0; }
.row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  margin: 0;
  padding: 3px 12px;
  align-items: baseline;
}
.row dt { color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.v-ok { color: var(--ok); }
.v-warn { color: var(--warn); }
.v-bad { color: var(--bad); }
.v-dim { color: var(--text-faint); }

.log {
  margin: 0;
  padding: 6px 12px 10px;
  max-height: 200px;
  overflow-y: auto;
  border-top: 1px solid var(--rail);
  font-size: 11px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
}
.log div { color: var(--text-dim); }
.log .t { color: var(--text-faint); }
.log .err { color: var(--bad); }
.log .good { color: var(--ok); }

.notes { margin-top: 20px; color: var(--text-dim); font-size: 14px; max-width: 68ch; }
.notes p { margin: 0 0 10px; }
.notes em { color: var(--text); font-style: normal; }

/* -------------------------------------------------------------------- views */

/* Nothing shows until the address bar has been read, so a link straight to a
   film never flashes the bench first. */
body:not([data-view]) .landing,
body:not([data-view]) main.room { visibility: hidden; }
body[data-view="landing"] main.room,
body[data-view="landing"] .slate,
body[data-view="landing"] .boothbtn { display: none; }
body[data-view="player"] .landing { display: none; }

a.mark { text-decoration: none; }
a.mark:hover { color: var(--steel-hi); }
/* In the player the mark is the way back to the bench. */
body[data-view="player"] a.mark::before { content: "\2039\00a0"; }

/* -------------------------------------------------------------------- bench */

.landing {
  --bench-can: min(56svh, 440px, 100vw - 150px);
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 var(--gutter) max(40px, env(safe-area-inset-bottom));
}

/* The rewind bench: a steel table the can stands on, with step controls at
   either end. */
.bench {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) 48px;
  align-items: center;
  gap: 8px;
  padding-top: clamp(8px, 3svh, 28px);
}
.bench::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0; right: 0;
  bottom: 14px;
  height: 22%;
  border-radius: 6px;
  border-top: 1px solid var(--steel-lo);
  background: linear-gradient(var(--booth-panel), var(--booth-wall) 70%, var(--booth-black));
  box-shadow: 0 20px 40px -20px rgb(0 0 0 / .8);
}

.bench-slot {
  display: grid;
  place-items: center;
  /* Room for the can's lift and shadow; the roll is clipped at the ends. */
  padding: 20px 0 30px;
  overflow: hidden;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}
.bench-slot > .can {
  grid-area: 1 / 1;
  --can: var(--bench-can);
  filter: drop-shadow(0 16px 16px rgb(0 0 0 / .6));
}
.bench-slot > .can .tape { left: 2%; right: 2%; padding: 14px 16px 12px; }
.bench-slot > .can .title { font-size: clamp(1.35rem, 5.2vw, 2.4rem); }
.bench-slot > .can .line { margin-top: 8px; font-size: clamp(15px, 3.6vw, 20px); }
.bench-slot > .can .resume { margin-top: 6px; font-size: clamp(13px, 3vw, 16px); }

.step {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--rail);
  border-radius: 6px;
  background: var(--booth-panel);
  color: var(--steel-hi);
}
.step:hover { border-color: var(--steel); color: #fff; }
.step[hidden] { visibility: hidden; display: grid; }
.step svg { width: 22px; height: 22px; }

.bench-say {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.bench-actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin-top: 4px;
}
/* The one lit control on the page: the projector's beam. */
.thread {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-width: 220px;
  min-height: 52px;
  padding: 12px 26px;
  border-radius: 6px;
  background: var(--beam);
  color: var(--booth-black);
  font: 700 17px/1 var(--stamp);
  letter-spacing: .12em;
  text-transform: uppercase;
  box-shadow: 0 10px 24px -12px rgb(245 242 234 / .45);
  transition: background .2s;
}
.thread:hover { background: #fff; }
.thread svg { width: 18px; height: 18px; fill: currentColor; }
.fromstart {
  min-height: 52px;
  padding: 12px 20px;
  border: 1px solid var(--rail);
  border-radius: 6px;
  color: var(--text);
  font: 700 14px/1 var(--stamp);
  letter-spacing: .12em;
  text-transform: uppercase;
}
.fromstart:hover { border-color: var(--steel); }
.fromstart[hidden] { display: none; }
@media (max-width: 560px) {
  .bench-actions { flex-direction: column; align-items: stretch; }
}

.bench-rack { margin-top: clamp(20px, 4svh, 40px); }
.bench-rack h2 { display: flex; align-items: baseline; gap: 8px; padding-bottom: 4px; }
.bench-index { --can: 104px; padding-top: 14px; }
.bench-index .can .tape { padding: 5px 6px 4px; }
.bench-index .can .title { font-size: 12.5px; }
.bench-index .can .line,
.bench-index .can .resume,
.bench-index .can .tick { display: none; }
/* The bench film's place in the rack: an empty ring. */
.bench-index .can[aria-pressed="true"] { translate: none; filter: none; }
.bench-index .can[aria-pressed="true"] .lid {
  background: none;
  -webkit-mask: none;
  mask: none;
  box-shadow: inset 0 0 0 2px var(--rail);
}
.bench-index .can[aria-pressed="true"] .tape { visibility: hidden; }

.landing .bench-empty { display: none; }
.landing.is-empty > :not(.bench-empty) { display: none; }
.landing.is-empty .bench-empty {
  display: block;
  max-width: 60ch;
  margin: 12svh auto 0;
  text-align: center;
  color: var(--text-dim);
}
.landing.is-empty .bench-empty .stamp { color: var(--text); font-size: 17px; margin-bottom: 12px; }
.bench-empty code {
  font: 12px var(--mono);
  background: var(--booth-wall);
  border: 1px solid var(--rail);
  padding: 1px 6px;
  border-radius: 4px;
  color: var(--text);
}
