/* ===========================================================================
   Austin Video Store - base stylesheet
   Decisions behind this file are recorded in ../../DESIGN-DECISIONS.md.

   THE RULE: no blend mode and no backdrop filter on anything that animates.
   Those two, plus background-attachment:fixed, were the measured cause of the
   demo heating up laptops. Nothing here reads back pixels behind itself.
   The only animated property in this file is `transform`, which the
   compositor handles without a repaint.
   =========================================================================== */

/* --- type ----------------------------------------------------------------
   Self-hosted. No Google Fonts link: that costs a third-party DNS lookup and
   TLS handshake on the critical path, and tells a third party that somebody
   is buying a ticket.
   ------------------------------------------------------------------------- */
@font-face {
  font-family: 'Anton';
  src: url('/fonts/anton-latin.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Barlow';
  src: url('/fonts/barlow-latin-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Barlow';
  src: url('/fonts/barlow-latin-600.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'VT323';
  src: url('/fonts/vt323-latin.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}

:root {
  /* Their palette, lifted from their own stylesheet. Contrast against
     --dark is in the decisions doc. --purple is 4.2:1, which clears large
     display type and borders but NOT body copy. Never set small text in it. */
  --purple:        #8B5BB8;
  --light-purple:  #C494E8;
  --green:         #9DFF57;
  --silver:        #CFCFCF;
  --blue:          #9FE7FF;
  --dark:          #050505;

  --ink:           var(--silver);
  --label:         var(--green);
  --raised:        #0D0D0F;
  --line:          #22222A;

  --display: 'Anton', Impact, 'Arial Narrow', sans-serif;
  --text:    'Barlow', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --osd:     'VT323', 'Courier New', monospace;

  --gutter: 16px;
  --measure: 64ch;
  --shell: 1100px;
  --radius: 3px;
}

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

/* An author rule that sets `display` beats the user agent's [hidden] rule,
   so a hidden button with a display of its own still paints. This keeps the
   attribute meaning what it says. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--dark);
  color: var(--ink);
  font-family: var(--text);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
  overflow-x: hidden;
}

/* Every number a person has to read correctly is in Barlow with tabular
   figures, so the hold countdown does not jitter as digit widths change
   and seat IDs line up down a column. */
time, .num, .price, .seat-id, .countdown { font-variant-numeric: tabular-nums; }

img { max-width: 100%; height: auto; display: block; }

a { color: var(--blue); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:focus-visible, button:focus-visible, [role="button"]:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

/* =========================================================================
   EFFECT LAYER
   Static grain + static scanlines in one fixed, non-interactive overlay, and
   one tracking bar whose only animated property is transform.

   `position: fixed` with a gradient background is cheap: one composited
   layer that does not repaint on scroll. `background-attachment: fixed` on a
   scrolling element is the expensive thing, and it is not used anywhere.
   ========================================================================= */
.fx {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  /* Grain is a rasterized-once SVG tile, not a live filter on content. */
  background-image:
    repeating-linear-gradient(
      to bottom,
      rgba(0,0,0,0.26) 0px,
      rgba(0,0,0,0.26) 1px,
      rgba(0,0,0,0) 1px,
      rgba(0,0,0,0) 3px
    ),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/></filter><rect width='180' height='180' filter='url(%23n)' opacity='0.42'/></svg>");
  background-size: 100% 3px, 180px 180px;
  opacity: 0.5;
}

/* One bar. One animated property. No filter, no blend mode. */
.fx-track {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 23vh;
  z-index: 61;
  pointer-events: none;
  will-change: transform;
  transform: translate3d(0, -25vh, 0);
  background: linear-gradient(
    to bottom,
    rgba(157,255,87,0)    0%,
    rgba(207,207,207,0.03) 42%,
    rgba(207,207,207,0.09) 50%,
    rgba(157,255,87,0.05)  54%,
    rgba(207,207,207,0)   100%
  );
  animation: fx-track 8.5s linear infinite;
}
@keyframes fx-track {
  from { transform: translate3d(0, -25vh, 0); }
  to   { transform: translate3d(0, 102vh, 0); }
}

/* Tickets carries grain only. Nothing moves on a page where somebody is
   mid-checkout on a phone with a card in their hand. */
body[data-fx="still"] .fx-track { display: none; }

/* Tape start, once per session. The inline head script decides. */
.tape {
  position: fixed;
  inset: 0;
  z-index: 70;
  pointer-events: none;
  background: var(--dark);
  display: none;
}
html[data-tape="play"] .tape {
  display: block;
  animation: tape-out 900ms steps(6, end) forwards;
}
@keyframes tape-out {
  0%   { opacity: 1; transform: translate3d(0,0,0) scaleY(1.04); }
  55%  { opacity: 1; transform: translate3d(0,0,0) scaleY(1); }
  100% { opacity: 0; transform: translate3d(0,0,0) scaleY(1); }
}

@media (prefers-reduced-motion: reduce) {
  .fx-track { display: none; }
  html[data-tape="play"] .tape { display: none; animation: none; }
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; }
}

/* =========================================================================
   SHELL + NAV
   ========================================================================= */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: var(--gutter);
  top: 8px;
  z-index: 90;
  background: var(--green);
  color: var(--dark);
  padding: 8px 14px;
  font-weight: 600;
}

.masthead {
  position: relative;
  z-index: 10;
  border-bottom: 1px solid var(--line);
  padding-block: 14px;
}
.masthead-in {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}
/* The official purple logo, big and centered, with the same glow their
   current site gives it: a soft purple halo and a hard dark offset (D23).
   The filter is on a static image and never animates, so it is painted once.
   The white version lives in the footer. */
.wordmark {
  display: block;
  line-height: 0;
  margin-inline: auto;
  border-radius: var(--radius);
}
.wordmark img {
  width: clamp(230px, 64vw, 400px);
  height: auto;
  filter: drop-shadow(0 0 8px rgba(196, 148, 232, 0.8)) drop-shadow(4px 4px 0 rgba(62, 36, 87, 0.85));
}
.masthead[data-home] .wordmark img { width: clamp(280px, 84vw, 640px); }
.masthead[data-home] { padding-block: 26px 18px; }

/* Desktop: logo left, nav right (D26). Phones keep the centered stack. */
@media (min-width: 760px) {
  .masthead-in { flex-direction: row; justify-content: space-between; gap: 24px; }
  .wordmark { margin-inline: 0; }
  .wordmark img { width: clamp(240px, 28vw, 320px); }
  .masthead[data-home] .wordmark img { width: clamp(300px, 36vw, 440px); }
  .nav { justify-content: flex-end; }
}
.nav {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav a {
  display: block;
  padding: 7px 13px;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--light-purple);
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
}
.nav a:hover { border-color: var(--line); background: var(--raised); }
/* Five items (once News is on) must fit one row on a 360px phone. */
@media (max-width: 480px) {
  .nav { gap: 2px; }
  .nav a { padding: 7px 8px; letter-spacing: 0.08em; }
}
.nav a[aria-current="page"] {
  border-color: var(--green);
}

/* The channel readout. Decorative, and the only VT323 in the masthead.
   20px floor, per the type rule. */
.ch {
  font-family: var(--osd);
  font-size: 1.25rem;
  line-height: 1;
  color: var(--purple);
  letter-spacing: 0.06em;
}

/* =========================================================================
   SHOWTIME BAND
   Renders only when an upcoming showtime row exists. Adding a showtime is
   the whole act of promoting a screening: no home page edit, ever.
   ========================================================================= */
.band {
  position: relative;
  z-index: 10;
  background: var(--raised);
  border-bottom: 1px solid var(--line);
}
.band-in {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 16px;
  padding-block: 11px;
}
.band-kicker {
  font-family: var(--osd);
  font-size: 1.25rem;
  line-height: 1;
  color: var(--green);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.band-title {
  font-weight: 600;
  color: #FFF;
}
.band-when { color: var(--silver); font-size: 0.9375rem; }
.band-cta {
  margin-left: auto;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green);
  text-decoration: none;
  border-bottom: 1px solid var(--green);
  padding-bottom: 1px;
}

/* =========================================================================
   TYPE SCALE
   ========================================================================= */
main { position: relative; z-index: 10; }

h1, h2, h3 { font-family: var(--display); font-weight: 400; text-transform: uppercase; line-height: 1.02; margin: 0; }
h1 { font-size: clamp(2.35rem, 9vw, 4.6rem); letter-spacing: 0.005em; color: #FFF; }
h2 { font-size: clamp(1.5rem, 5vw, 2.3rem); color: var(--light-purple); }
h3 { font-size: clamp(1.1rem, 3.4vw, 1.3rem); color: var(--light-purple); }

.eyebrow {
  font-family: var(--osd);
  font-size: 1.3125rem;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green);
  margin: 0 0 10px;
}
.lede { font-size: clamp(1.0625rem, 2.6vw, 1.1875rem); max-width: var(--measure); color: #E6E6E6; }
p { max-width: var(--measure); }

.hero { padding-block: clamp(40px, 9vw, 86px); }
.hero h1 { margin-bottom: 18px; }

.slab { padding-block: clamp(34px, 6vw, 60px); border-top: 1px solid var(--line); }

/* =========================================================================
   BUTTONS
   ========================================================================= */
.btn {
  display: inline-block;
  font-family: var(--text);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 13px 24px;
  border-radius: var(--radius);
  border: 2px solid var(--green);
  background: var(--green);
  color: var(--dark);
  text-decoration: none;
  cursor: pointer;
  min-height: 48px;
}
.btn:hover { background: #AEFF78; }
.btn-ghost { background: transparent; color: var(--green); }
.btn-ghost:hover { background: rgba(157,255,87,0.1); }
.btn[disabled], .btn[aria-disabled="true"] {
  border-color: var(--line);
  background: transparent;
  color: #6A6A72;
  cursor: not-allowed;
}

/* =========================================================================
   CARDS
   ========================================================================= */
.cards { display: grid; gap: 14px; margin: 0; padding: 0; list-style: none; }
@media (min-width: 720px) { .cards { grid-template-columns: repeat(2, 1fr); } }

.card {
  display: block;
  padding: 20px;
  background: var(--raised);
  border: 1px solid var(--line);
  border-left: 3px solid var(--purple);
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
}
.card:hover { border-left-color: var(--green); }
.card h3 { color: #FFF; margin-bottom: 6px; }
.card-when { font-family: var(--text); font-size: 0.9375rem; color: var(--silver); }
.card-left {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green);
  margin-top: 10px;
}
.card-left[data-sold="true"] { color: #8A8A92; }
/* A card with a poster: the poster small on the left (D45). */
.card[data-poster] { display: grid; grid-template-columns: 72px 1fr; gap: 16px; align-items: start; }
.card-poster { width: 72px; aspect-ratio: 2 / 3; object-fit: cover; border-radius: var(--radius); background: var(--dark); }

/* Staff: a card with more than one link in it, and the add/edit form. */
div.card { cursor: default; }
.card-links { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 10px; font-size: 0.9375rem; }
.staff-form fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px 18px; margin: 18px 0 0; }
.staff-form legend { padding: 0 6px; color: var(--light-purple); font-weight: 600; }
.radios { display: grid; gap: 10px; }
.flash-ok { border-left-color: var(--green); }
.refund summary { cursor: pointer; color: var(--silver); font-size: 0.875rem; margin-top: 6px; }
.refund form { margin-top: 8px; display: grid; gap: 8px; }

/* =========================================================================
   SEAT GRID
   Four rows of four. Every target is comfortably past the 44px minimum,
   the whole room fits a phone in portrait, no pan and no pinch. That is the
   one thing a 16-seat house can do that a 200-seat house cannot.

   STATE IS CARRIED BY FILL, NOT HUE. Roughly one man in twelve cannot
   reliably separate red from green, and held vs sold vs yours is exactly the
   distinction that produces an angry phone call. Each state below is also
   distinct in grayscale and in a screenshot.
   ========================================================================= */
.screen {
  margin: 0 auto 22px;
  max-width: 420px;
  text-align: center;
  font-family: var(--osd);
  font-size: 1.25rem;
  line-height: 1;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--purple);
  padding-bottom: 10px;
  border-bottom: 2px solid var(--purple);
  border-radius: 50% 50% 0 0 / 14px 14px 0 0;
}

.house { max-width: 420px; margin-inline: auto; }

.row {
  display: grid;
  grid-template-columns: 26px repeat(var(--per-row, 4), 1fr);
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.row-letter {
  font-family: var(--osd);
  font-size: 1.25rem;
  line-height: 1;
  color: var(--purple);
  text-align: center;
}

.seat {
  position: relative;
  aspect-ratio: 1 / 1;
  min-height: 56px;
  display: grid;
  place-items: center;
  font-family: var(--text);
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius) var(--radius) 8px 8px;
  border: 2px solid var(--green);
  background: transparent;
  color: var(--green);
  cursor: pointer;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}

/* selected -- solid fill */
.seat[data-state="selected"] {
  background: var(--green);
  border-color: var(--green);
  color: var(--dark);
}

/* held by someone else -- hatched and dimmed */
.seat[data-state="held"] {
  border-color: #55555E;
  color: #9A9AA2;
  cursor: not-allowed;
  background-image: repeating-linear-gradient(
    45deg,
    rgba(207,207,207,0.20) 0px,
    rgba(207,207,207,0.20) 3px,
    rgba(0,0,0,0) 3px,
    rgba(0,0,0,0) 7px
  );
}

/* sold -- dim, and struck through corner to corner */
.seat[data-state="sold"] {
  border-color: #3A3A44;
  color: #85858E;
  cursor: not-allowed;
  background: #0A0A0C;
}
.seat[data-state="sold"]::after {
  content: "";
  position: absolute;
  left: 8%;
  right: 8%;
  top: 50%;
  height: 2px;
  background: #85858E;
  transform: rotate(-38deg);
  transform-origin: center;
}

.seat[data-state="available"]:hover { background: rgba(157,255,87,0.14); }

.legend {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px 18px;
  margin: 22px auto 0;
  max-width: 420px;
  padding: 0;
  list-style: none;
  font-size: 0.875rem;
  color: var(--silver);
}
.legend li { display: flex; align-items: center; gap: 9px; }

/* The legend draws an actual .seat, shrunk. One source of truth for the four
   treatments: change a state above and the key changes with it. */
.legend .seat {
  width: 24px;
  height: 24px;
  min-height: 0;
  flex: none;
  aspect-ratio: auto;
  font-size: 0;
  cursor: default;
  border-radius: 2px 2px 6px 6px;
}
.legend .seat[data-state="sold"]::after { height: 2px; }

/* =========================================================================
   CHECKOUT TRAY
   ========================================================================= */
.tray {
  position: sticky;
  bottom: 0;
  z-index: 50;
  margin-top: 26px;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px var(--gutter);
}
.tray-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; }
.tray-sum { font-size: 0.9375rem; color: var(--silver); margin-right: auto; }
.tray-sum strong { color: #FFF; }
.countdown {
  font-family: var(--text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--blue);
}
.countdown[data-low="true"] { color: #FFD166; }

.note {
  font-size: 0.875rem;
  color: #A8A8B0;
  max-width: var(--measure);
}

.alert {
  border: 1px solid var(--line);
  border-left: 3px solid #FFD166;
  background: var(--raised);
  padding: 12px 14px;
  border-radius: var(--radius);
  font-size: 0.9375rem;
  margin-bottom: 16px;
}

/* =========================================================================
   FOOT
   ========================================================================= */
.foot {
  position: relative;
  z-index: 10;
  border-top: 1px solid var(--line);
  margin-top: 60px;
  padding-block: 30px 44px;
  font-size: 0.9375rem;
  color: #9A9AA2;
}
.foot a { color: var(--silver); }
.foot-in { display: grid; gap: 22px; justify-items: center; text-align: center; }
.foot-logo { display: block; line-height: 0; width: max-content; }
.foot-logo img { width: 200px; height: auto; }
.foot-info { display: grid; gap: 14px; justify-items: center; }
.foot-info > p { margin: 0; }
.foot-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; margin: 0; padding: 0; list-style: none; }
/* Desktop: the logo beside the details, sized to match their height (D26). */
@media (min-width: 760px) {
  .foot-in { grid-template-columns: auto 1fr; align-items: center; justify-items: start; text-align: left; gap: 48px; }
  .foot-logo img { width: 300px; }
  .foot-info { justify-items: start; }
  .foot-links { justify-content: flex-start; }
}
.signup { display: grid; gap: 8px; max-width: 420px; }
.rewind {
  font-family: var(--osd);
  font-size: 1.3125rem;
  line-height: 1;
  color: var(--purple);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.vh {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* =========================================================================
   PLACEHOLDERS
   Visible on purpose. Anything in .tk is a fact nobody has given us yet, and
   a photo frame stands where a specific shot from the brief will land. Both
   are meant to be impossible to ship by accident.
   ========================================================================= */
.tk {
  font-family: var(--text);
  font-weight: 600;
  color: #FFD166;
  background: rgba(255,209,102,0.1);
  border-bottom: 1px dashed #FFD166;
  padding: 0 4px;
}

.frame {
  display: grid;
  place-items: center;
  text-align: center;
  gap: 4px;
  aspect-ratio: 16 / 9;
  background: var(--raised);
  border: 1px dashed #44444E;
  border-radius: var(--radius);
  color: #85858E;
  padding: 18px;
  margin-block: 18px;
}
.frame b {
  display: block;
  font-family: var(--osd);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--purple);
}
.frame span { font-size: 0.875rem; max-width: 46ch; }
.frame[data-ratio="wide"] { aspect-ratio: 21 / 9; }

.pair { display: grid; gap: 26px; }
@media (min-width: 860px) { .pair { grid-template-columns: 1fr 1fr; align-items: start; } }

.stack > * + * { margin-top: 14px; }
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }

dl.facts { margin: 0; }
dl.facts dt {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--green);
  margin-top: 16px;
}
dl.facts dd { margin: 2px 0 0; color: var(--silver); }

/* =========================================================================
   FORMS
   Checkout, and later the mailing list and the staff admin.
   16px inputs so iOS does not zoom the page when one is focused.
   ========================================================================= */
.field { display: grid; gap: 6px; }
.field + .field { margin-top: 14px; }
.field label, .field .label {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--green);
}
.field input[type="text"], .field input[type="email"], .field input[type="number"], .signup input,
.field input[type="date"], .field input[type="time"], .field select, .field textarea {
  font: inherit;
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
  color: #FFF;
  background: var(--dark);
  border: 1px solid #3A3A44;
  border-radius: var(--radius);
  padding: 11px 12px;
  width: 100%;
  max-width: 420px;
}
.field textarea { max-width: 640px; min-height: 7em; resize: vertical; line-height: 1.5; }
.field input[type="date"], .field input[type="time"] { max-width: 220px; color-scheme: dark; }
.field select { max-width: 220px; }
.field input[type="file"] { font: inherit; font-size: 0.9375rem; color: var(--silver); max-width: 420px; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-color: var(--blue); }
.field .hint { font-size: 0.875rem; color: #A8A8B0; margin: 0; }
.field .err { font-size: 0.875rem; color: #FFD166; margin: 0; }
.money-in { display: flex; align-items: center; gap: 8px; max-width: 220px; }
.money-in span { font-size: 1.25rem; color: var(--silver); }
.check, .field label.check {
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 0.9375rem; font-weight: 400; letter-spacing: normal; text-transform: none;
  color: var(--silver);
}
.check input { width: 20px; height: 20px; margin-top: 2px; accent-color: var(--green); flex: none; }

.checkout {
  margin-top: 18px;
  padding: 18px;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.checkout h3 { margin-bottom: 14px; color: #FFF; }
.card-slot { min-height: 56px; margin-top: 16px; }
.card-slot:empty { display: none; }
.pay-line { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; margin-top: 18px; }
.small { font-size: 0.875rem; color: #A8A8B0; }

/* =========================================================================
   POLICIES
   ========================================================================= */
.prose h2 { margin-top: 30px; margin-bottom: 10px; font-size: clamp(1.3rem, 4vw, 1.7rem); }
.prose p, .prose li { color: #E0E0E4; }
.prose ul { padding-left: 1.2em; max-width: var(--measure); }
.prose li + li { margin-top: 8px; }
.draft {
  border: 1px dashed #FFD166;
  background: rgba(255,209,102,0.08);
  color: #FFD166;
  padding: 12px 14px;
  border-radius: var(--radius);
  font-weight: 600;
  max-width: var(--measure);
}

/* =========================================================================
   CONFIRMATION AND TICKETS
   ========================================================================= */
.tix { display: grid; gap: 14px; margin: 18px 0 0; padding: 0; list-style: none; }
@media (min-width: 720px) { .tix { grid-template-columns: repeat(2, 1fr); } }
.tix li {
  display: grid;
  grid-template-columns: 112px 1fr;
  gap: 14px;
  align-items: center;
  padding: 14px;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.tix .qr { background: #FFF; padding: 6px; border-radius: 2px; line-height: 0; }
.tix .qr svg { width: 100px; height: 100px; }
.tix .seat-id { font-family: var(--display); font-size: 2rem; color: #FFF; line-height: 1; }

/* =========================================================================
   STAFF
   Behind Cloudflare Access. Built for a phone held at the door.
   ========================================================================= */
.door { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: 1rem; }
.door th, .door td { text-align: left; padding: 12px 8px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.door th { font-size: 0.8125rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--green); font-weight: 600; }
.door td.seat-id { font-weight: 600; color: #FFF; width: 3.5em; }
.door tr[data-in="true"] td { color: #8A8A92; }
.door form { margin: 0; }
.door .btn { padding: 9px 14px; min-height: 44px; }
.stat { display: flex; flex-wrap: wrap; gap: 8px 22px; font-size: 1rem; color: var(--silver); margin-top: 8px; }
.stat b { color: #FFF; font-variant-numeric: tabular-nums; }

/* =========================================================================
   CRT DETAILS (D23)
   ========================================================================= */
/* CH-01 and so on: alone at the right, like a TV's channel readout. */
.osd {
  font-family: var(--osd);
  font-size: clamp(1.75rem, 5.5vw, 2.5rem);
  line-height: 1;
  letter-spacing: 0.06em;
  color: var(--green);
  text-shadow: 0 0 6px rgba(157, 255, 87, 0.55);
  text-align: right;
  max-width: none;
  margin: 0 0 10px;
}
/* A placeholder showing title, purple so it reads as not real yet. */
.tk-title { color: var(--light-purple); }

/* BUY, SELL, AND TRADE: the home page's big readout, with a static
   colour fringe so it reads as a picture on a tube. */
.crt {
  font-family: var(--osd);
  font-size: clamp(2.3rem, 9vw, 3.8rem);
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--green);
  text-shadow: 0 0 10px rgba(157, 255, 87, 0.45), 2px 0 0 rgba(255, 40, 120, 0.35), -2px 0 0 rgba(60, 200, 255, 0.35);
  margin: 6px 0 16px;
  max-width: none;
}
/* What they carry, on a programmable LED sign (D29). The body width, white
   letters, purple bullets. sign.js moves things with transform and opacity
   only. The dot-matrix screen is a static overlay above the moving text. */
.sign {
  position: relative;
  margin: 4px 0 22px;
  background: #07070A;
  border: 1px solid #2A2A33;
  border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px #000, 0 0 18px rgba(139, 91, 184, 0.18);
}
.sign::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background: radial-gradient(circle, transparent 55%, rgba(0, 0, 0, 0.55) 56%) 0 0 / 4px 4px;
}
.sign-stage {
  position: relative;
  overflow: hidden;
  height: 3rem;
}
.sign-static, .sign-line {
  font-family: var(--osd);
  font-size: 1.75rem;
  line-height: 3rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #FFFFFF;
  text-shadow: 0 0 6px rgba(255, 255, 255, 0.55);
  white-space: nowrap;
}
.sign-static { padding-inline: 14px; overflow: hidden; text-overflow: clip; }
.sign-b { font-size: 1.35em; line-height: 1; align-self: center; }
.sign-static b, .sign-b { color: var(--light-purple); text-shadow: 0 0 6px rgba(196, 148, 232, 0.8); font-weight: 400; }
.sign-static b { padding-inline: 12px; }
.sign-line { position: absolute; left: 0; top: 0; display: flex; will-change: transform; }
.sign-line span { display: inline-block; }
.sign-beam {
  position: absolute;
  left: 0;
  top: 15%;
  height: 70%;
  width: 3px;
  background: var(--light-purple);
  box-shadow: 0 0 10px 3px rgba(196, 148, 232, 0.9);
}
@media (prefers-reduced-motion: reduce) {
  .sign-stage { height: auto; }
  .sign-static { white-space: normal; line-height: 1.5; padding-block: 8px; }
}
.hours { margin: 4px 0 0; padding: 0; list-style: none; font-variant-numeric: tabular-nums; }
.hours li { display: grid; grid-template-columns: 6.5em 1fr; gap: 10px; }
.hours li span:first-child { color: var(--silver); }

/* Showtime head: the poster beside the details on wider screens. */
.show-head { display: grid; gap: 22px; }
.show-head .frame[data-ratio="poster"], .show-head .poster {
  aspect-ratio: 2 / 3;
  width: min(200px, 50vw);
  margin: 0 auto;
}
.show-head .poster { object-fit: cover; border-radius: var(--radius); }
@media (min-width: 720px) {
  .show-head { grid-template-columns: 220px 1fr; align-items: start; }
  .show-head .frame[data-ratio="poster"], .show-head .poster { width: 220px; margin: 0; }
}

/* =========================================================================
   MYSTERY POSTER REEL (D28)
   Public domain horror posters, pre-blurred into one strip, spinning past
   like a slot machine reel behind a big question mark. One image, two
   copies, transform only.
   ========================================================================= */
.reel {
  position: relative;
  overflow: hidden;
  aspect-ratio: 2 / 3;
  width: min(200px, 50vw);
  margin: 0 auto;
  border-radius: var(--radius);
  border: 1px solid #2A2A33;
  background: #000;
}
@media (min-width: 720px) { .reel { width: 220px; margin: 0; } }
.reel-track { display: flex; height: 100%; width: max-content; animation: reel 4.8s linear infinite; /* half speed, 2026-10-11 (was 2.4s) */ }
.reel-track img { height: 100%; width: auto; max-width: none; display: block; }
@keyframes reel { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
.reel-q {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-size: clamp(6rem, 22vw, 9rem);
  line-height: 1;
  color: #FFF;
  text-shadow: 0 0 18px rgba(196, 148, 232, 0.95), 0 0 2px #000, 4px 4px 0 rgba(62, 36, 87, 0.9);
}
@media (prefers-reduced-motion: reduce) { .reel-track { animation: none; } }

/* SUPPORT */
.support-grid { display: grid; gap: 18px; margin-top: 8px; }
@media (min-width: 860px) { .support-grid { grid-template-columns: repeat(3, 1fr); } }
.support-card { padding: 20px; background: var(--raised); border: 1px solid var(--line); border-radius: var(--radius); }
.support-card h2 { margin-bottom: 10px; }
.support-card .actions { margin-top: 16px; }
.foot-support { margin: 0; }
.foot-support a { color: var(--light-purple); font-weight: 600; }

/* Visit page map. Lazy-loaded Google embed; dark-tinted to sit on the page. */
.map {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  margin-top: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--raised);
  filter: grayscale(0.35) contrast(1.05);
}

/* =========================================================================
   DOOR: scan results and the scanner (D46)
   One big panel says what to do. Tone by colour AND by the words, so it
   reads the same in sunlight, in the dark, and to anyone colour blind.
   ========================================================================= */
.verdict {
  border: 1px solid var(--line);
  border-left: 8px solid #3A3A44;
  background: var(--raised);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin-top: 14px;
}
.verdict p { margin: 4px 0 0; }
.verdict-big { font-family: var(--display, inherit); font-size: clamp(1.6rem, 7vw, 2.4rem); line-height: 1.05; color: #FFF; margin: 0 0 6px !important; text-transform: uppercase; }
.verdict-seat { font-size: clamp(2.4rem, 12vw, 3.6rem); font-weight: 700; line-height: 1; color: #FFF; font-variant-numeric: tabular-nums; }
.verdict-name { font-size: 1.25rem; color: #FFF; }
.verdict[data-tone="ok"] { border-left-color: var(--green); background: rgba(157, 255, 87, 0.12); }
.verdict[data-tone="ok"] .verdict-big { color: var(--green); }
.verdict[data-tone="go"] { border-left-color: var(--blue); }
.verdict[data-tone="warn"] { border-left-color: #FFD166; background: rgba(255, 209, 102, 0.12); }
.verdict[data-tone="warn"] .verdict-big { color: #FFD166; }
.verdict[data-tone="bad"] { border-left-color: #FF5C5C; background: rgba(255, 92, 92, 0.14); }
.verdict[data-tone="bad"] .verdict-big { color: #FF8A8A; }
.verdict[data-tone="idle"] .verdict-big { font-size: 1.25rem; color: var(--silver); }

.scan-view { position: relative; margin-top: 12px; background: #000; border-radius: var(--radius); overflow: hidden; aspect-ratio: 4 / 3; display: grid; place-items: center; }
.scan-view video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.scan-frame { position: absolute; width: 58%; aspect-ratio: 1; border: 3px solid rgba(255, 255, 255, 0.85); border-radius: 12px; box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.35); display: none; }
.scanner[data-live] .scan-frame { display: block; }
.scan-view [data-start] { position: relative; z-index: 1; }
