/* Earth Music Theater — flight test stylesheet.
   Design direction: docs/EMT/02.
   Near-black rather than pure black (pure black crushes the footage's
   shadows at the frame edge). One serif with presence, one grotesque for
   utility. No cards. No shadows. Nothing bounces. */

:root {
  /* ONE home for the menu bar's height. The bar is PINNED to this value,
     and everything that must clear it derives from it: the hero's height,
     every section's jump offset, the edit page's sticky bar. Restyle the
     bar freely — alignment cannot drift again. (Structural cleanup,
     Jul 30, after jump offsets went stale three restyles in a row.) */
  --headh:    64px;

  --ink:      #0A0B0D;          /* field  */
  --paper:    #F2EFE9;          /* type   */
  --dim:      #8B8880;
  --dimmer:   #55534E;
  --rule:     #23252A;
  --accent:   #E8A33D;          /* sodium-orange of city lights at night */
  --aurora:   #63DF7C;          /* the bright green of the aurora itself */
  --tile:     #16181C;          /* empty artwork cell */
  --tile-ink: #2C2F35;
  --scrim:    rgba(10,11,13,.72);
  --prose:    #DBD8D1;
  --ghost:    #3A3D43;          /* input placeholders */
  --heroveil: .58;              /* hero image opacity */
  --veil-1:   rgba(10,11,13,.75);
  --veil-2:   rgba(10,11,13,.55);
  --veil-3:   rgba(10,11,13,.12);
  --slow:     900ms cubic-bezier(.22,.61,.36,1);
  --slower:   1400ms cubic-bezier(.22,.61,.36,1);
}

/* Light mode — an experiment, toggled in the masthead.
   Not a simple inversion: the accent has to darken sharply to hold against
   white, and the hero image needs less veil because there is no darkness
   for it to emerge from. */
body.light {
  --ink:      #FAF8F4;
  --paper:    #14161A;
  --dim:      #6E6B65;
  --dimmer:   #9A968E;
  --rule:     #E0DCD4;
  --accent:   #A8620C;
  --tile:     #EDE9E2;
  --tile-ink: #CFCAC1;
  --scrim:    rgba(250,248,244,.82);
  --prose:    #2A2D33;
  --ghost:    #BBB6AD;
  --heroveil: .92;
  --veil-1:   rgba(250,248,244,.82);
  --veil-2:   rgba(250,248,244,.62);
  --veil-3:   rgba(250,248,244,.14);
}
/* The player keeps its dark surround in both modes — a film should not sit
   on white. */
body.light .player-wrap, body.light .player { background: #0A0B0D; }

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }


body {
  background: var(--ink);
  color: var(--paper);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }

.serif {
  font-family: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  font-weight: 400;
  letter-spacing: -0.01em;
}

/* ---- the kicker: small letterspaced caps. The repeating unit. --------- */
.kicker {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim);
  font-weight: 500;
}
.kicker .num { color: var(--accent); }

/* ---- masthead --------------------------------------------------------- */
/* A defined bar above the content, not a veil over it (Dan, Jul 30).
   Sticky so it stays while scrolling; solid in both modes — EVERY
   page including the watch page (Dan, Aug 6: a reliable anchor). */
header.top {
  position: sticky; top: 0; left: 0; right: 0; z-index: 60;
  height: var(--headh); box-sizing: border-box;
  /* Brand leads (Aug 6): brand · menu, search pushed right by its
     own margin inside the nav (which now flexes to fill). */
  display: flex; gap: 30px; align-items: center;
  padding: 0 40px;
  background: var(--ink);
  border-bottom: 1px solid var(--rule);
}
header.top .wordmark { font-size: 19px; letter-spacing: .005em; }
/* The beta flag (Aug 7, go-live): centered in the sticky header,
   above the flex flow. Remove at cutover. */
.betaflag {
  position: absolute; left: 50%; transform: translateX(-50%);
  color: var(--accent); border: 1px solid var(--accent);
  border-radius: 999px; padding: 4px 14px;
  font-size: 12px; letter-spacing: .14em; white-space: nowrap;
}
.topbrand { display: flex; align-items: center; gap: 12px; }
.toplogo { height: 40px; width: auto; }
header.top .season a { transition: color var(--slow); }
header.top .season a:hover { color: var(--paper); }
/* The marquee light (D30): the active program's button. */
header.top .season a.marq.on { color: var(--accent); }
.mode {
  background: transparent; border: 1px solid var(--rule); color: var(--dim);
  border-radius: 999px; font: inherit; font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; padding: 5px 12px; margin-left: 18px;
  cursor: pointer;
  transition: color var(--slow), border-color var(--slow);
}
.mode:hover { color: var(--paper); border-color: var(--dimmer); }
header.top .season   { font-size: 13px; letter-spacing: .18em;
                       text-transform: uppercase; color: var(--dim);
                       display: flex; align-items: center;
                       flex: 1 1 auto; }
/* Separators live in CSS so the same markup can stack on phones. */
.season a + a::before { content: "\00B7"; margin: 0 12px;
                        color: var(--dimmer); }
/* Dan's desks, far right (Aug 6): a shade quieter than the visitor
   menu — present, not advertised. Gone from the nav at cutover. */
.season a.desk { color: var(--dimmer); }
/* The desks-and-Light cluster takes the far right; everything before
   it (brand · menu · search) holds the left. */
.season .topsearch + a.desk { margin-left: auto; }
.navburger {
  display: none; background: none; border: 0; color: var(--paper);
  font-size: 22px; cursor: pointer; padding: 0 4px; line-height: 1;
}


/* .ncard: the medium card (ui.medium, _parts.html) — the film page's
   recommendation rails wear it. (.nhead/.nbar died with triage, Aug 3.) */
.ncard { display: block; }
.ncard-art {
  /* 4K aspect, like every format (Dan, Jul 30). */
  display: block; position: relative; aspect-ratio: 16/9;
  background: var(--tile); background-size: cover; background-position: center;
  border: 1px solid var(--dim);
  transition: opacity var(--slow);
}
.ncard:hover .ncard-art { opacity: .85; }
.ncard-art .dur {
  position: absolute; right: 10px; bottom: 10px;
  background: rgba(10,11,13,.72); color: #F2EFE9;
  font-size: 11px; padding: 3px 8px; border-radius: 2px;
  font-variant-numeric: tabular-nums;
}
/* Copy below the art — the large feature's voice at card scale
   (the NatGeo white panel is retired; Dan, Jul 30). */
.ncard-copy { display: block; padding: 14px 0 0; }
.ncard-copy .kicker { font-size: 10.5px; }
.ncard-title { display: block; font-size: 24px; line-height: 1.15;
  margin-top: 6px; }
.ncard-desc {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; font-size: 13.5px; line-height: 1.55; color: var(--dim);
  margin-top: 8px;
}


/* ==== Responsive system (Jul 30) — breakpoints used SITE-WIDE:
   1024px  grid collapses to one column (tablets portrait and down)
    900px  nav collapses to the burger panel
    640px  phone scale: type, ring, lockup, paddings
   The bar height (--headh) is the one shared constant; media queries
   cannot read CSS vars, so these three numbers are the convention —
   change them here and nowhere else. ==== */

@media (max-width: 900px) {
  .navburger { display: block; }
  /* Phone header is burger + brand; the centered beta flag would sit
     on the wordmark, so it docks right instead. */
  .betaflag { left: auto; right: 16px; transform: none;
              font-size: 10px; padding: 3px 10px; }
  .season { display: none; }
  .season.open {
    display: flex; flex-direction: column; align-items: flex-start;
    gap: 16px; position: absolute; top: var(--headh); left: 0; right: 0;
    padding: 18px 24px 22px; background: var(--ink);
    border-bottom: 1px solid var(--rule);
  }
  .season.open a + a::before { content: none; margin: 0; }
}

@media (max-width: 640px) {
  header.top { padding: 0 20px; }
  footer.foot { padding: 40px 20px; }
}

/* ---- film page -------------------------------------------------------- */
/* The whole 16:9 frame must fit on screen without scrolling. Sizing the
   width from the viewport HEIGHT is what guarantees that: at most 100svh
   tall, at most 100vw wide, whichever binds first. */
.player-wrap {
  padding: 0; background: #000;
  /* The sticky header (--headh) is real estate the film can't have
     (Dan's "menu stays" ruling, Aug 6) — subtract it, so header +
     player = exactly one screen, whole film visible without
     scrolling (Dan, Aug 8). */
  height: calc(100svh - var(--headh)); display: flex;
  align-items: center; justify-content: center;
}
.player {
  position: relative;
  width: min(100vw, calc((100svh - var(--headh)) * 16 / 9));
  aspect-ratio: 16 / 9;
  background: #000;
}

/* Watching (Dan, Aug 6): the menu STAYS — a reliable anchor above
   the movie, just like on every page. The old dissolve-on-watch
   (doc 02 principle 1) is retired for the HEADER; the film itself
   still owns the space below it. Its mousemove script left
   film.html the same day. */
.player iframe { position: absolute; inset: 0; width: 100%; height: 100%;
                 border: 0; }

/* the sound-on moment: explicit, once, unmissable */
.sound {
  position: absolute; inset: 0; z-index: 5;
  display: flex; align-items: center; justify-content: center;
  background: rgba(10,11,13,.55);
  background-size: cover; background-position: center;
  cursor: pointer; transition: opacity var(--slow);
}
.sound.gone { opacity: 0; pointer-events: none; }
.sound span {
  border: 1px solid rgba(242,239,233,.5); border-radius: 2px;
  padding: 16px 34px; font-size: 12px;
  letter-spacing: .2em; text-transform: uppercase;
  background: rgba(10,11,13,.35); backdrop-filter: blur(3px);
  transition: border-color var(--slow), letter-spacing var(--slow);
}
.sound:hover span { border-color: var(--paper); letter-spacing: .28em; }

article.film { padding: 74px 40px 120px; max-width: 1180px; }
article.film h1 { font-size: clamp(38px, 5.4vw, 76px); line-height: 1;
                  margin: 16px 0 26px; max-width: 18ch; }

/* The VIEW (D6) — what the film shows, right under the title. */
.viewline { font-size: clamp(17px, 2vw, 22px); color: var(--dim);
            margin: -14px 0 26px; max-width: 60ch; }
/* The music under the view (Dan, Aug 15) — the card plate's surname
   voice, quieter than the view. */
.musicline { font-size: clamp(15px, 1.6vw, 18px); color: var(--dimmer);
             margin: -16px 0 26px; max-width: 60ch; }

/* Two rows: the short scannable facts on top, the music underneath with the
   whole width to itself — a full work title with catalogue number will not
   sit politely in a column (Dan, Jul 28). */
.credits {
  padding: 26px 0 34px; border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule); margin-bottom: 56px;
}
/* The globe sits left, credits shift right to make room (Dan, Jul 28).
   Transparent PNG-derived WebP — no plate, no border, it just sits on the
   page like an object rather than an image in a box. */
.credits.has-globe { display: flex; gap: 46px; align-items: flex-start; }
.credits .globe {
  width: clamp(112px, 11vw, 168px); height: auto; flex-shrink: 0;
  margin-top: -4px;
}
.cstack { flex: 1 1 auto; min-width: 0; }
.crow { display: flex; flex-wrap: wrap; gap: 44px; }
.crow + .crow { margin-top: 30px; }
.credit .kicker { display: block; margin-bottom: 6px; }
.credit .v { font-size: 17px; }
.credit.wide { flex: 1 1 100%; }
/* (.grow/.mid retired Aug 15 with the Music row — Movie ID joined
   row one; the one-grid alignment machinery went with them.) */
@media (min-width: 901px) {
  .cstack { display: grid;
    grid-template-columns: repeat(5, max-content);
    column-gap: 44px; row-gap: 30px; align-items: start; }
  .crow { display: contents; }
  .credit.wide { grid-column: 1 / -1; }
}

/* The cover takes the column the prose was leaving empty (Dan, Jul 28), and
   stays with you while you read. */
/* Title + cover share the head row (Dan, Aug 15) — the cover moved
   up from the body's left column, freeing it for the people stack. */
.headwrap { display: flex; gap: 60px; align-items: flex-start;
  justify-content: space-between; margin-bottom: 40px;
  /* Same hairline the credits block wears (Dan, Aug 15) — the head
     and the body are two rooms. */
  padding-bottom: 40px; border-bottom: 1px solid var(--rule); }
.headwrap .headtext { flex: 1 1 auto; min-width: 0; }
.covertop { flex: 0 0 clamp(280px, 34vw, 520px); width: clamp(280px, 34vw, 520px);
  height: auto; border-radius: 3px; display: block;
  border: 1px solid rgba(242, 239, 233, .16); }
@media (max-width: 900px) {
  .headwrap { flex-direction: column; gap: 24px; }
  .covertop { width: 100%; flex: 1 1 auto; }
}

.bodywrap { display: flex; gap: 60px; align-items: flex-start;
            margin-bottom: 56px; }
.coverfig {
  flex: 0 0 clamp(220px, 26vw, 380px);
  position: sticky; top: calc(var(--headh) + 40px);
}
.coverfig img { width: 100%; height: auto; border-radius: 3px;
  display: block; box-sizing: border-box;
  border: 1px solid rgba(242, 239, 233, .16); }
/* The people stack (Dan, Aug 15 — was "the musician under the
   cover"): photo first, name below, musician above astronaut(s).
   Every piece optional (D12). */
/* Fonts match the prose across the aisle (Dan, Aug 6): name = the
   lead sentence's voice (21px paper), instrument = body voice. */
/* People stack: the first card starts flush (the cover no longer
   sits above it); the astronaut card follows the musician. */
.mcard { margin-top: 34px; }
.coverfig .mcard:first-child { margin-top: 0; }
.acard .mport + .mport { margin-top: 10px; }
/* Photo first, names below (Dan, Aug 15). */
.mname { display: block; margin-top: 12px; font-size: 21px;
  color: var(--paper); }
.minstr { display: block; margin: 4px 0 0; font-size: 17.5px;
  color: var(--prose); line-height: 1.5; }
.mport { width: 100%; max-width: 300px; aspect-ratio: 1;
  object-fit: cover; border-radius: 3px; display: block;
  border: 1px solid rgba(242, 239, 233, .16); }

.prose { max-width: 63ch; flex: 1 1 auto; min-width: 0; }
.prose p { margin-bottom: 1.5em; font-size: 17.5px; color: var(--prose); }
.prose p:first-child { font-size: 21px; color: var(--paper); }
/* The blurb leads in GOLD (Dan, Aug 15) — the invitation, prominent.
   (p + class matches :first-child's specificity; later wins.) */
.prose p.blurblead { color: var(--accent); }
.prose .prule { border: 0; border-top: 1px solid var(--rule);
                margin: 0 0 1.5em; }
.prose .prule.gold { border-top-color: var(--accent); }
/* LIVE + WEB (Dan, Aug 18): the film page's two quiet sections
   after the description — events from the catalog, the musician's
   own site with its screenshot. Gallery restraint throughout. */
.fsec { margin-top: 34px; padding-top: 18px;
  border-top: 1px solid var(--accent); }
.fsec .kicker { display: block; margin-bottom: 12px;
  color: var(--accent); font-size: 16px; letter-spacing: .18em; }
.fsrowwrap { display: flex; gap: 14px; align-items: center;
  margin-bottom: .7em; }
.fsphoto { width: 120px; flex: 0 0 auto; border-radius: 4px;
  border: 1px solid var(--rule); }
.prose p.fsrow { font-size: 15px; color: var(--dim);
  margin-bottom: .55em; }
.fsrowwrap .fsrow { margin-bottom: 0; }
.fswhen { color: var(--paper); font-variant-numeric: tabular-nums;
  margin-right: 10px; }
.fsrow.up .fswhen { color: var(--accent); }
.fsname { color: var(--paper); }
.fswhere { color: var(--dimmer); margin-left: 10px; }
.fstix { color: var(--accent); margin-left: 10px;
  text-decoration: none; border-bottom: 1px solid var(--accent); }
.prose p.fsmore { font-size: 13px; margin: 6px 0 0; }
.fsmore a { color: var(--dim); text-decoration: none; }
.fsmore a:hover { color: var(--paper); }
.fweb { margin-bottom: 14px; }
.fwebthumb { display: block; max-width: 380px; width: 100%;
  border: 1px solid var(--rule); border-radius: 6px;
  margin-bottom: 8px; }
.fweb a:hover .fwebthumb { border-color: var(--dim); }
.fweblink { color: var(--paper); font-size: 15px;
  text-decoration: none; border-bottom: 1px solid var(--rule); }
.fweblink:hover { border-bottom-color: var(--paper); }

@media (max-width: 900px) {
  .bodywrap { flex-direction: column; gap: 34px; }
  .coverfig { position: static; flex: 1 1 auto; max-width: 460px; }
}

.more-head {
  font-family: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  font-weight: 400; letter-spacing: -0.01em;
  font-size: clamp(30px, 4vw, 44px); line-height: 1.1;
  padding: 0 40px 34px; max-width: 1180px;
  color: var(--accent);
}
.more { padding: 0 40px 120px; max-width: 1180px; }
.more .kicker { display: block; margin-bottom: 22px; }
/* The musician's other films, medium format, in a left-right grid. */
.more-grid {
  display: grid; gap: 36px 28px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

/* ---- browse: Apple Music logic, our palette --------------------------- */
/* Header is in-flow now, so the page no longer clears a fixed bar. */
.browse { padding: 48px 40px 120px; }

.browse-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 30px; flex-wrap: wrap; margin-bottom: 30px;
}
.browse-head h2 { font-size: clamp(32px, 4vw, 52px); line-height: 1; }

.search input {
  background: transparent; border: 0; border-bottom: 1px solid var(--rule);
  color: var(--paper); font: inherit; font-size: 14px;
  padding: 9px 2px; width: min(360px, 68vw);
  transition: border-color var(--slow);
}
.search input::placeholder { color: var(--dimmer); }
.search input:focus { outline: none; border-color: var(--paper); }

.bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 0; border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.bar .kicker { margin-right: 4px; }
.bar .count { margin-left: auto; color: var(--dimmer); font-size: 12px;
              font-variant-numeric: tabular-nums; }

.chip {
  font-size: 12.5px; padding: 6px 13px; border-radius: 999px;
  border: 1px solid var(--rule); color: var(--dim);
  transition: color var(--slow), border-color var(--slow),
              background var(--slow);
  white-space: nowrap;
}
.chip:hover { color: var(--paper); border-color: var(--dimmer); }
.chip.on { color: var(--ink); background: var(--paper);
           border-color: var(--paper); }

/* (The old flat-grid card system — .grid/.cell/.art/.ct/.cs/.prov —
   and the facet-filter styles died in the Aug 2 nail-down: D29's ONE
   card and D31's no-filters ruling made them unreachable. The 452px
   "Large is best" cell was superseded by the home card. Git holds
   everything.) */

/* ---- the editor's desk ------------------------------------------------ */
.edit .hint { color: var(--dim); font-size: 13px; line-height: 1.7; }
.edit .hint em { color: var(--dimmer); }

.bar.sticky { position: sticky; top: var(--headh); z-index: 40;
              background: var(--ink); }

/* FIELD DRESS (.efields) — the desk's shared field styling: kickers,
   underlined inputs, read-only .ro, grey-italic .prop. The GRID that
   arranges the groups is .ckflow (the cockpit's flow columns, below).
   Pre-cockpit relics (.save/.saved button, .erow/.ethumb/.enum desk
   rows, .ecol) deleted Aug 11 — git holds them. */
.efields {
  display: grid; gap: 12px 34px; align-items: start;
}
.egroup { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.eghead {
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--accent); padding-bottom: 7px; margin-bottom: 1px;
  border-bottom: 1px solid var(--rule);
}
/* Two fields on one row (Vimeo ID + date; Flight path + Confirmed
   astronaut — Dan, Aug 11): equal halves. */
.efields .pair { display: flex; gap: 14px; align-items: flex-end; }
.efields .pair > label { flex: 1; min-width: 0; }
.efields label { display: block; }
.efields .kicker { display: block; margin-bottom: 5px; }
.efields input, .efields textarea {
  width: 100%; background: transparent; color: var(--paper);
  border: 0; border-bottom: 1px solid var(--rule);
  font: inherit; font-size: 15px; padding: 7px 2px;
  transition: border-color var(--slow), color var(--slow);
}
.efields textarea { resize: vertical; line-height: 1.5; }
/* Read-only DERIVED value, dressed like an input without the invite.
   Full brightness (Dan, Aug 4): grey is reserved for machine PROPOSALS
   awaiting a human (D34). These are confirmed facts the system worked
   out — the dotted underline is what says "not yours to type". */
.efields .ro { display: block; font-size: 15px; padding: 7px 2px;
  color: var(--paper); border-bottom: 1px dotted var(--rule); }

/* (The pubbox flags left .efields for the head row's .ckflags —
   D62, Aug 11. Their dress lives with them, under THE COCKPIT.) */

/* D39 — the third state: in development, not released */
.draftbadge { color: var(--accent); font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase; }

/* D37 — "Multiple Paths": site chrome laid over the globe crop for
   films drawing on several Earth passes. Never baked into the WebP. */
.globewrap { display: inline-block; }
.globeimg { position: relative; display: inline-block; }
.globewrap .globelabel {
  position: absolute; left: 50%; top: 12%;
  transform: translateX(-50%);
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  white-space: nowrap; color: var(--paper);
  background: rgba(0, 0, 0, .55); padding: 3px 10px;
  border-radius: 999px; backdrop-filter: blur(2px);
}
.efields input:focus, .efields textarea:focus {
  outline: none; border-color: var(--paper); }
.efields input::placeholder, .efields textarea::placeholder {
  color: var(--ghost); }
/* proposed, not yet confirmed */
.efields input.prop { color: var(--dim); font-style: italic; }
.vname { display: block; margin-top: 5px; font-size: 11.5px;
         color: var(--dimmer); }

/* ---- SHARE (Aug 12 — the ASE launch) ----------------------------------
   One quiet pill; a small popover where there's no native sheet.
   Gallery restraint: no badge rows, no brand colors — the theater's
   own dress. */
.shareseat { position: relative; display: inline-block; margin-left: 10px; }
.shareb { font: inherit; font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim); background: none;
  border: 1px solid var(--rule); border-radius: 999px;
  padding: 3px 13px; cursor: pointer; vertical-align: middle;
  transition: color var(--slow), border-color var(--slow); }
.shareb:hover { color: var(--paper); border-color: var(--dimmer); }
.sharepop { position: absolute; left: 0; top: calc(100% + 8px);
  z-index: 60; min-width: 150px; display: flex; flex-direction: column;
  background: var(--tile); border: 1px solid var(--rule);
  border-radius: 6px; padding: 6px; text-transform: none;
  letter-spacing: 0; }
/* display:flex would defeat the hidden attribute (the popover shipped
   OPEN — Dan caught it on first look). Explicit wins. */
.sharepop[hidden] { display: none; }
/* On the film page the seat hugs the right edge — the popover opens
   leftward so it can't overflow the viewport. */
.film .sharepop { left: auto; right: 0; }
.sharepop a, .sharepop .sharecopy { font: inherit; font-size: 13.5px;
  color: var(--paper); text-align: left; background: none; border: 0;
  padding: 7px 10px; border-radius: 4px; cursor: pointer;
  text-decoration: none; white-space: nowrap; }
.sharepop a:hover, .sharepop .sharecopy:hover {
  background: rgba(255, 255, 255, .07); }
/* About's share sits INLINE beside the About kicker (Dan's placement
   ruling, Aug 12 — not floated to the far edge; two earlier seats
   retired). Popover opens rightward here — plenty of viewport.
   Doubled class beats the later .film float rule at any distance. */
.film.about-article .shareseat { float: none; margin: -3px 0 0 14px; }
.film.about-article .sharepop { left: 0; right: auto; }

/* ---- RAIL CHEVRONS (Aug 12 — Dan asked for standard practice) ----------
   The streaming grammar's answer: arrows appear on rail hover
   (desktop pointers only — touch swipes natively), page the rail,
   and hide themselves at the ends. The peek (cut-off card) stays
   the primary signal. JS in base.html wraps each shelf rail. */
.railwrap { position: relative; }
/* On person shelves the JS wrapper takes the rail's old flex seat
   beside the portrait. */
.shelf-body .railwrap { flex: 1 1 auto; min-width: 0; }
.railarr {
  position: absolute; top: 0; bottom: 8px; width: 46px;
  border: 0; cursor: pointer; padding: 0;
  color: var(--paper); font-size: 46px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity var(--slow); z-index: 5;
  font-family: inherit;
}
.railarr.prev { left: 0;
  background: linear-gradient(90deg, var(--ink) 0%, transparent); }
.railarr.next { right: 0;
  background: linear-gradient(270deg, var(--ink) 0%, transparent); }
@media (hover: hover) and (pointer: fine) {
  .railwrap:hover .railarr { opacity: .92; }
  .railwrap:hover .railarr:hover { opacity: 1; }
}
.railwrap.at-start .railarr.prev,
.railwrap.at-end .railarr.next { opacity: 0; pointer-events: none; }

/* ---- LIVE: the musician prologue (Aug 14 — the Live cleanup) -----------
   Portrait + live_note sentence + their full shelf open each group;
   the event list follows with context. */
.lmus-head { display: flex; gap: 26px; align-items: flex-start;
  margin: 14px 0 18px; }
.lmus-note { align-self: center; }
/* Same height as the movie thumbnails (Dan, Aug 14) — the
   shelf-portrait equation: card width × 9/16. */
.lmus-photo { width: calc(var(--card-w) * 9 / 16);
  height: calc(var(--card-w) * 9 / 16); object-fit: cover;
  object-position: top; border-radius: 6px;
  border: 1px solid rgba(242, 239, 233, .16); flex: 0 0 auto; }
.lmus-note { margin: 6px 0 0; font-size: 15.5px; line-height: 1.55;
  color: var(--dim); max-width: 640px; }
.lmus-shelf { margin-bottom: 26px; }
/* "Sample Movies" in the event-name voice: white serif (Dan, Aug 14). */
.lmus-samples { color: var(--paper); font-size: 30px;
  font-weight: 400; margin: 0 0 16px; }

/* ---- TRAFFIC DESK (Aug 12 — roll-our-own analytics) --------------------
   Desk-only. Bars: dim = views, gold = daily-unique visitors. */
.traffic .tstats { display: flex; gap: 22px; flex-wrap: wrap;
  margin: 4px 0 26px; }
.tstat { border: 1px solid var(--rule); border-radius: 6px;
  padding: 14px 24px; min-width: 132px; }
.tstat b { display: block; font-size: 30px; font-weight: 600;
  color: var(--accent); font-variant-numeric: tabular-nums; }
.tstat span { font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dim); }
/* Explorers (Aug 14): the humans-vs-scanners line, under the count. */
.tstat .tsub { display: block; font-size: 10px; font-style: normal;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--dimmer); margin-top: 3px; }
/* One instrument row (Dan, Aug 14, final tweak before the launch
   freeze): matrix · 30-day chart · today-by-hour, side by side. */
.tstatrow { display: flex; gap: 30px; align-items: stretch;
  margin-bottom: 26px; flex-wrap: wrap; }
.tstatrow .tchart { flex: 1 1 300px; min-width: 260px;
  display: flex; flex-direction: column; }
/* The watch curve takes half a chart's seat (Dan, Aug 21 — first
   sight of it live: "make it thinner by half"). */
.tstatrow .twcurve { flex: .5 1 150px; min-width: 140px; }
/* Its minute ruler (Dan, same night): boundary ticks (.ttick,
   styled once at the timeline ruler below — paper) + grey
   numerals; viewing counts moved to hover. */
.tval.tvald { color: var(--dimmer); }
/* Timeline play marks (Dan, Aug 21): aurora green, journey-tall —
   the moment someone pressed the watch button. */
.tplay { fill: var(--aurora); }
.tstatrow .tchart-l { margin-top: 4px; }
/* Chart titles (Dan, Aug 15): Daily / Hourly, gold and unmissable. */
.tctitle { color: var(--accent); font-size: 16px;
  letter-spacing: .18em; text-transform: uppercase;
  margin-bottom: 8px; }
/* Value labels sit in one quiet row UNDER the bars (Dan, Aug 14 —
   the bar-top overlay scattered; simplified). HTML, not SVG text,
   so the numerals never distort with the stretched SVG. */
.tplot { position: relative; flex: 1 1 auto; display: flex;
  margin-bottom: 14px; min-height: 110px; }
/* The svg FILLS the plot box (Aug 14 fix: a fixed height left the
   labels anchored far below the bars when the row stretched). */
.tplot svg { width: 100%; height: 100%; display: block; }
.tval { position: absolute; transform: translateX(-50%);
  bottom: -14px; font-size: 9.5px; color: var(--paper);
  pointer-events: none; font-variant-numeric: tabular-nums;
  line-height: 1; }
/* The scale label (Dan, Aug 20): one quiet number at top-left —
   the chart's max — replacing the per-column rows that collided
   as the record grew. */
.tymax { position: absolute; top: 2px; left: 4px;
  font-size: 11px; color: var(--dimmer); pointer-events: none;
  font-variant-numeric: tabular-nums; line-height: 1; }
/* THE MATRIX (Dan, Aug 14): rows of time frame × cols of metric —
   journeys, visitors, views at 24h / window / all-time, one glance. */
.tmatrix { display: grid; flex: 0 0 auto;
  grid-template-columns: auto repeat(11, minmax(76px, auto));
  gap: 10px 34px; align-items: baseline;
  border: 1px solid var(--rule); border-radius: 6px;
  padding: 14px 24px; }
.tmx-h { font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--dim); }
/* Gold headers mark PEOPLE counts — Visitors, Explorers (Dan,
   Aug 15); the grey ones are event counts. */
.tmx-h.tmx-hg { color: var(--accent); }
.tmx-r { font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim); }
.tmx-c b { font-size: 24px; font-weight: 600; color: var(--accent);
  font-variant-numeric: tabular-nums; }
.tmx-c em { display: block; font-size: 10px; font-style: normal;
  letter-spacing: .06em; color: var(--dimmer); margin-top: 1px; }
/* The percentage itself in white (Dan, Aug 15) — the rate is the
   readout; "of visits" is the caption. */
.tmx-p { color: var(--paper); font-size: 12px; }
/* Hidden bots "ops / identities" never wraps (Dan, Aug 20; the ≈
   was dropped same breath — "even humans are estimates"). */
.tmx-wide b, b.tmx-wide { white-space: nowrap; }
/* The who|what rule (Dan, Aug 20): a quiet divider where the
   census ends and the deeds begin — drawn in the grid gap on the
   Visits column, headers and cells alike. */
.tmx-div { border-left: 1px solid var(--rule);
  margin-left: -17px; padding-left: 16px; }
@media (max-width: 1300px) { .tstatrow .tchart { flex-basis: 100%; } }
.theart { color: var(--accent); font-size: 12px; margin-left: 6px; }
/* Plays (schema 037, Aug 15): the applause meter's quiet mark. */
.tplay { color: var(--paper); font-size: 11px; margin-left: 6px; }
/* Samples (schema 040, Aug 18): budding interest — the ♪ count. */
.tsamp { color: var(--paper); font-size: 12px; margin-left: 6px; }
.tjour { margin-top: 36px; }
/* The 24h visit timeline (Aug 15) — arrival marks above the list.
   Flex row since Aug 15 night: the Active-30m card sits left of
   the pulse (open visits — sessions the 30-min gap hasn't closed). */
.tline { margin: 10px 0 16px; display: flex; gap: 18px;
  align-items: stretch; }
.tline-g { flex: 1 1 auto; min-width: 0; }
.tactive { flex: 0 0 auto; text-align: center;
  border: 1px solid var(--rule); border-radius: 6px;
  padding: 6px 18px 4px; align-self: flex-start; }
.tactive .tctitle { margin-bottom: 2px; font-size: 11px; }
.tactive b { font-size: 24px; font-weight: 600;
  color: var(--accent); font-variant-numeric: tabular-nums; }
.tline svg { width: 100%; height: 44px; display: block;
  background: rgba(255, 255, 255, .02);
  border: 1px solid var(--rule); border-radius: 6px; }
/* Hour graduations: a ruler row under the strip. Scoped hard —
   the .tline svg rule was dressing this one in the full 44px strip
   styling (Dan caught the giants). */
.tline svg.tlruler { width: 100%; height: 6px; display: block;
  margin-top: 2px; background: none; border: 0; border-radius: 0; }
.ttick { fill: var(--paper); }
/* Night band on the hourly chart (Dan, Aug 15): midnight–8am US
   Eastern, a black deeper than the page ink. */
.tnight { fill: #000; }
/* D69 (Aug 20): bot ticks on the timeline — the faintest species. */
.tbot { fill: var(--ghost); }
/* D69: bot journeys in the list render faint; the Nation seat
   carries the family name. */
tr.tj-bot td { opacity: .6; }
/* Scrolling journeys (Dan, Aug 15): ~12 rows visible, the rest by
   wheel — the launch era outgrew a fixed 14. */
.tjour .tjscroll { max-height: 460px; overflow-y: auto;
  scrollbar-width: thin; }
.tjcount { font-size: 13.5px; color: var(--dim); margin: 10px 0 6px; }
.tjcount b { color: var(--accent); font-size: 17px; }
.tj-when { white-space: nowrap; }
/* The browsing span in gold (Dan, Aug 15) — time spent moving is
   the row's precious number; recency stays grey. */
.tj-c { white-space: nowrap; color: var(--paper); }
/* Page count beside the trail (Dan, Aug 15 — the right edge lost
   it). Gold like every count; the trail cell, now last-child,
   must NOT inherit the count column's gold/right-align. */
.ttab td.tj-n { color: var(--accent); text-align: right;
  font-variant-numeric: tabular-nums; }
/* Duration, split out of the recency cell (Dan, Aug 15): its own
   gold column after the page count. */
.ttab td.tj-s { color: var(--accent); text-align: right;
  font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Top-movies columns (D63 plays, Dan Aug 15, swapped same night):
   the deeper act gets the accent, and last-child gilds it for
   free. D71 (Aug 21, twice in one night): Time then Full each
   took the gold on arrival; Visit·Listen·Watch·Time wear tj-w
   white, Full — the funnel's last rung — is last-child gold. */
.ttab td.tj-w { color: var(--paper); text-align: right;
  font-variant-numeric: tabular-nums; }
/* Journey column labels (Dan, Aug 15) — the matrix header voice. */
.tjhead th { font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--dim); font-weight: 400;
  text-align: left; padding: 0 10px 6px 0;
  border-bottom: 1px solid var(--rule); }
.tjhead th.tjh-r { text-align: right; }
/* Top movies' headers gold (Dan, Aug 21, following the totals
   row) — scoped so the Journeys panel's labels stay grey. */
.tjhead.tjgold th { color: var(--accent); }
/* Movie-count line under Top movies' headers (Dan, Aug 20):
   breadth, not volume — quiet, white, right-aligned like the
   columns it counts. */
/* Gold since Aug 21 (Dan) — the totals row earns the accent. */
.ttab tr.tjmov td { font-size: 12px; color: var(--accent);
  text-align: right; padding-top: 2px; padding-bottom: 8px;
  border-bottom: 1px solid var(--rule);
  font-variant-numeric: tabular-nums; }
.ttab tr.tjmov td:first-child { text-align: left;
  color: var(--dimmer); text-transform: uppercase;
  letter-spacing: .14em; font-size: 9.5px; }
/* Trail greys swapped (Dan, Aug 15): musicians LIGHT grey, paths
   DARK — the person outranks the plumbing. Movies stay blue. */
.tj-trail { color: var(--dimmer); }
.ttab td.tj-trail:last-child { text-align: left; color: var(--dimmer);
  font-variant-numeric: normal; white-space: normal; }
/* Movies in the trail wear blue, their musician in grey (Aug 14). */
.tjf { color: #88ccff; }
.tjw { color: var(--dim); font-size: 12.5px; }
.tchart svg { width: 100%; height: 200px; display: block;
  background: rgba(255, 255, 255, .02);
  border: 1px solid var(--rule); border-radius: 6px; }
.tbar { fill: rgba(255, 255, 255, .15); }
.tbaru { fill: var(--accent); }
.tchart-l { display: flex; justify-content: space-between;
  font-size: 11px; color: var(--dimmer); margin-top: 6px; }
/* The center label IS the chart's title — white, not grey (Dan,
   Aug 14). Edge spans (date/hour bounds) stay quiet. */
.tchart-l span:nth-child(2) { color: var(--paper); }
.tcols { display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 44px; margin-top: 36px; align-items: start; }
.ttab { width: 100%; font-size: 13.5px; border-collapse: collapse; }
.ttab td { padding: 6px 10px 6px 0; border-bottom: 1px solid var(--rule);
  color: var(--paper); overflow-wrap: anywhere; }
.ttab td:last-child { text-align: right; color: var(--accent);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.ttab .tdim { color: var(--dimmer); }
.ckbtn.on { border-color: var(--accent); color: var(--accent); }
@media (max-width: 1100px) { .tcols { grid-template-columns: 1fr; } }

/* ---- musicians roster -------------------------------------------------- */
.murow { grid-template-columns: 90px 1fr; }
.mucount { text-align: center; padding-top: 8px;
           display: flex; flex-wrap: wrap; gap: 4px 10px;
           justify-content: center; max-width: 140px; }
.mufilm { color: var(--accent); text-decoration: none;
          font-variant-numeric: tabular-nums; }
.mufilm.mudraft { color: var(--dim); }
.mufilm:hover { text-decoration: underline; }
.nfilm { display: block; font-size: 26px; font-weight: 700;
         font-variant-numeric: tabular-nums; }
.nfilm.zero { color: var(--dimmer); }
.mudel .dec { margin-top: 8px; }

/* ---- tags & collections ------------------------------------------------ */
.collection-grid { padding-top: 28px; }

/* ---- shared row controls (.dec lives on in roster + sections) --------- */
.dec { display: flex; gap: 16px; margin-top: 10px; font-size: 12.5px;
       color: var(--dim); }
.dec label { display: flex; gap: 6px; align-items: center; cursor: pointer; }
.dec input { accent-color: var(--accent); }

.nothing { padding: 60px 0; color: var(--dim); }
.nothing a { border-bottom: 1px solid var(--dimmer); }

footer.foot {
  padding: 60px 40px; border-top: 1px solid var(--rule);
  color: var(--dimmer); font-size: 12px;
  display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  /* Lifted above the About underlay (a fixed element paints over
     unpositioned content); harmless everywhere else. */
  position: relative; z-index: 1;
}

@media (max-width: 760px) {
  article.film, .more, .more-head { padding-left: 20px; padding-right: 20px; }
  .prose { margin-left: 0; }
}

/* ==========================================================================
   THE THEATER (graduated from stage.html's playground block, Aug 2 —
   the day the stage grammar became every listing page's grammar).
   Home / All Films / Season One / Bach / any collection: one stage,
   one card, one rail, one grid. Dan: "so we're not building one-offs."
   ========================================================================== */

/* ---- the stage ---- */
/* No margin-top: header.top is STICKY, so it already occupies its
   64px in flow — adding margin doubled the offset (the black band
   Dan caught, Aug 1). */
.stage { position: relative; overflow: hidden; background: var(--ink);
         height: min(56.25vw, 84vh);
         /* Teaser zoom (Dan, Jul 31): finished films carry a lower-left
            overlay that collides with the stage's own label. Scaling
            from the TOP-RIGHT crops out left and bottom. */
         --tz: 1.35;
         transition: height var(--slower); }
.stage-vid { position: absolute; inset: 0; }
.stage-vid iframe { position: absolute; top: 0; right: 0;
  width: 100vw; height: 56.25vw; border: 0;
  transform: scale(var(--tz)); transform-origin: top right;
  opacity: 0; transition: opacity var(--slower); }
.stage-vid iframe.live { opacity: 1; }
.stage-vid video { position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity var(--slower); }
.stage-vid video.live { opacity: 1; }
.stage-poster { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity var(--slower); }
.stage-poster.show { opacity: .55; }
/* The stage keeps its DARK veil in BOTH modes (Dan, Aug 2): a film
   should not sit on white. */
.stage-veil { position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(10,11,13,.75), transparent 45%),
              linear-gradient(to right, rgba(10,11,13,.55), transparent 55%); }
/* Stage chrome pinned to the dark palette in light mode too. */
body.light #stageTop {
  --paper: #F2EFE9; --ink: #0A0B0D; --dim: #8B8880;
  --dimmer: #55534E; --accent: #E8A33D; }
.stage-lower { position: absolute; left: 5vw; bottom: 8vh;
  display: flex; align-items: center; gap: clamp(24px, 4vw, 64px); }
.stage-info { max-width: 44ch;
  display: flex; flex-direction: column; gap: 10px; }
.stage-port { width: clamp(120px, 16vw, 260px);
  height: clamp(120px, 16vw, 260px); flex: 0 0 auto;
  border-radius: 50%; object-fit: cover;
  border: 1px solid rgba(242, 239, 233, .45);
  opacity: 0; visibility: hidden;
  transition: opacity var(--slower), visibility var(--slower); }
.stage-port.show { opacity: 1; visibility: visible; }
/* The portrait seat (Dan, Aug 10): holds one circle, or the DUET —
   overlapping circles for a film credited to several named
   astronauts. First face on top, later faces tuck behind. */
.stage-ports { display: flex; align-items: center; flex: 0 0 auto; }
.stage-ports .stage-port { position: relative; }
.stage-ports.duet .stage-port {
  width: clamp(96px, 12vw, 200px); height: clamp(96px, 12vw, 200px); }
.stage-ports.duet .stage-port + .stage-port {
  margin-left: calc(clamp(96px, 12vw, 200px) / -3.5); }
.stage-ports.duet .stage-port:nth-child(1) { z-index: 3; }
.stage-ports.duet .stage-port:nth-child(2) { z-index: 2; }
.stage-ports.duet .stage-port:nth-child(3) { z-index: 1; }
.stage-info .kicker { color: var(--accent); }
.stage-title { font-size: clamp(30px, 4.4vw, 62px); line-height: 1.04;
  color: var(--paper); font-weight: 400; }
/* The view on the stage (Dan, Aug 6): the authored line under the
   title, serif like the room's voice, quiet against the footage. */
.stage-view { color: var(--paper); opacity: .92; font-size: 18px;
  letter-spacing: .01em; max-width: 44ch; }
.stage-meta { color: var(--dim); font-size: 14px; letter-spacing: .02em; }
/* The music line (Dan, Aug 2): the work's authored short form, serif
   like a concert program; bright after Dan's legibility call. */
.stage-music { color: var(--paper); font-size: 16px;
  font-style: italic; letter-spacing: .01em; }
/* The blurb below Watch (Dan, Aug 6): brief, quiet, readable over
   footage; vanishes cleanly when unwritten (D12). */
.stage-blurb { color: var(--prose); opacity: .88; font-size: 14.5px;
  line-height: 1.55; max-width: 46ch; margin-top: 16px; }
.stage-blurb:empty { display: none; }
.stage-watch .wt { color: var(--accent); margin-left: 4px; }
.stage-watch { align-self: flex-start; margin-top: 8px;
  padding: 10px 26px; border: 1px solid var(--paper); border-radius: 999px;
  color: var(--paper); text-decoration: none; font-size: 14px;
  letter-spacing: .14em; text-transform: uppercase;
  transition: background var(--slow), color var(--slow); }
.stage-watch:hover { background: var(--paper); color: var(--ink); }
/* Watch + ♪ Sample side by side (Aug 9). The sample is the quieter
   sibling: dimmer border, same pill; gold while playing. */
.stage-actions { display: flex; gap: 12px; align-items: center;
  align-self: flex-start; margin-top: 8px; }
.stage-actions .stage-watch { align-self: auto; margin-top: 0; }
.stage-sample { padding: 10px 20px; border-radius: 999px;
  border: 1px solid rgba(242, 239, 233, .45); background: none;
  color: var(--paper); font-size: 14px; letter-spacing: .14em;
  text-transform: uppercase; cursor: pointer;
  transition: border-color var(--slow), color var(--slow); }
.stage-sample .wt { color: var(--accent); margin-left: 4px; }
.stage-sample:hover { border-color: var(--paper); }
.stage-sample.on { border-color: var(--accent); color: var(--accent); }
.stage-dots { position: absolute; left: 50%; transform: translateX(-50%);
  bottom: 22px; display: flex; gap: 12px; }
.stage-dots button { width: 8px; height: 8px; border-radius: 50%;
  border: 0; padding: 0; cursor: pointer; background: var(--dimmer);
  transition: background var(--slow), transform var(--slow); }
.stage-dots button.on { background: var(--paper); transform: scale(1.3); }

/* ---- the welcome: same room, lights up (home only) ---- */
.stage.welcome { height: calc(100vh - var(--headh)); }
.stage-wel { position: absolute; inset: 0; opacity: 0;
  visibility: hidden; pointer-events: none;
  transition: opacity var(--slower), visibility var(--slower); }
/* While welcoming, the whole room accepts the entering click (Dan,
   Aug 2); pointer-events retire with the welcome. */
.stage.welcome .stage-wel { opacity: 1; visibility: visible;
  pointer-events: auto; cursor: pointer; }
.stage.welcome .stage-lower, .stage.welcome .stage-dots {
  opacity: 0; visibility: hidden; }
.stage-lower, .stage-dots {
  transition: opacity var(--slower), visibility var(--slower); }
@keyframes welrise { from { opacity: 0; } to { opacity: 1; } }
.stage.welcome .wel-title {
  opacity: 0; animation: welrise 1400ms cubic-bezier(.22,.61,.36,1)
  900ms forwards; }
.stage.welcome .wel-brand {
  opacity: 0; animation: welrise 1400ms cubic-bezier(.22,.61,.36,1)
  1500ms forwards; }
.stage.welcome .wel-enter {
  opacity: 0; animation: welrise 1400ms cubic-bezier(.22,.61,.36,1)
  2100ms forwards; }
.wel-title { position: absolute; left: 7vw; top: 10vh;
  font-size: clamp(40px, 5.5vw, 84px); color: var(--paper);
  font-weight: 400; }
.wel-brand { position: absolute; left: 3vw; bottom: 6vh;
  display: flex; align-items: center; gap: 14px;
  color: var(--prose); font-size: 15px; line-height: 1.35; }
.wel-brand img { width: 74px; height: 74px; border-radius: 50%; }
/* Center stage (Dan, Aug 2): the ring waits where the eye rests. */
.wel-enter { position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%); text-align: center;
  pointer-events: auto; cursor: pointer; background: none;
  border: 0; color: var(--paper); }
.wel-enter .lbl { display: block; font-size: 12px;
  letter-spacing: .3em; margin-bottom: 12px; }
.wel-enter .ring { display: flex; align-items: center;
  justify-content: center; width: 64px; height: 64px; margin: 0 auto;
  border: 1px solid var(--aurora); border-radius: 50%;
  font-size: 18px; transition: box-shadow var(--slow),
  transform var(--slow); box-shadow: 0 0 18px rgba(99,223,124,.25); }
.wel-enter:hover .ring { transform: scale(1.08);
  box-shadow: 0 0 30px rgba(99,223,124,.45); }
/* With the body and footer hidden the welcome is EXACTLY one viewport
   — scroll restoration has nowhere to jump (the "black band", Aug 1).
   The body lives in #tbody since D30 (the marquee's swap target). */
.stage.welcome ~ #tbody { display: none; }
.stage.welcome ~ footer.foot { display: none; }
/* The curtain line: spoken once as the first film takes the stage. */
/* The tagline (Dan, Aug 8 — chose "playbill rules" from four
   mockups): one white serif line, thin gold hairlines stretching to
   either side. Flex line: the ::before/::after ARE the rules.
   Replaces the stage's timed curtain line (.stage-tag). */
.home-tag {
  margin: 0; padding: 58px 5vw 22px;
  display: flex; align-items: center; gap: 24px;
  color: var(--paper);
  /* Doubled at Dan's call, Aug 8 ("try 2x") — marquee scale. */
  font-size: clamp(34px, 4.8vw, 72px);
  font-weight: 400; line-height: 1.25;
  text-align: center; white-space: nowrap;
}
.home-tag::before, .home-tag::after {
  content: ""; flex: 1; height: 1px;
  background: var(--accent); opacity: .6;
}
@media (max-width: 720px) {
  /* Phones: the line wraps, the rules would crush it — let the text
     breathe and keep one short rule beneath instead. */
  .home-tag { display: block; white-space: normal;
              padding: 36px 8vw 30px; }
  .home-tag::before { display: none; }
  .home-tag::after { content: ""; display: block; width: 64px;
                     height: 1px; margin: 18px auto 0; }
}

/* ---- the About hero (Aug 9): Samantha in the Cupola, static —
        the one page without the teaser theater. Banner is an HTML
        overlay in the mockup's sage green; the photo is the clean
        master, cropped by object-position to match the mockup. ---- */
.about-hero { position: relative; width: 100%;
  aspect-ratio: 16 / 9; max-height: calc(100svh - var(--headh));
  overflow: hidden; background: #000; }
.about-hero img { width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 40%; display: block; }
/* ---- LIVE performances (Aug 9): upcoming + past. Rich when the
        record is rich, a clean line when it's just name+date (D12). */
.live-hero { width: 100%; aspect-ratio: 3 / 1; overflow: hidden;
  background: #000; }
.live-hero img { width: 100%; height: 100%; object-fit: cover;
  object-position: center bottom; display: block; }
.live-page { padding: 0 5vw 80px; }
.live-page .home-tag { padding-left: 0; padding-right: 0; }
.lsection { margin-top: 30px; }
.lgroup { margin-top: 34px; }
.lmusician { font-weight: 400; font-size: 36px;
  font-family: 'Inter', sans-serif; color: var(--accent);
  margin: 0 0 4px;
  /* The band gets its marquee (Dan, Aug 9): a gold hairline running
     from the name to the right edge — the playbill flank, one-sided. */
  display: flex; align-items: center; gap: 24px; }
.lmusician::after { content: ""; flex: 1; height: 1px;
  background: var(--accent); opacity: .55; }
.lgroup .levent:first-of-type { border-top: none; }
.lsection > .shelf-label { display: block; margin-bottom: 18px; }
.levent { padding: 26px 0; border-bottom: 1px solid var(--rule); }
.levent .lhead .ldate { color: var(--accent); font-size: 14px;
  letter-spacing: .12em; text-transform: uppercase; }
.levent h2 { font-weight: 400; font-size: clamp(24px, 2.6vw, 40px);
  margin: 4px 0 2px; }
.lvenue { color: var(--dim); margin: 0 0 10px; }
.lbody { display: flex; gap: 36px; align-items: flex-start; }
.lphoto { flex: 0 0 min(34%, 420px); margin: 0; }
.lphoto img { width: 100%; border-radius: 3px; display: block; }
.ltext { flex: 1 1 auto; min-width: 0; max-width: 720px; }
.lline { margin: 0 0 8px; }
.lline.dim { color: var(--dim); }
.lline .gold, .lline a { color: var(--accent); text-decoration: none; }
.lblurb { color: var(--prose); margin: 10px 0; }
.lprogram { color: var(--dim); font-size: 14.5px; line-height: 1.7;
  margin: 10px 0; }
.lrail { margin-top: 18px; }
@media (max-width: 900px) {
  .lbody { flex-direction: column; gap: 18px; }
  .lphoto { flex: none; width: 100%; }
}

/* The About underlay (Dan, Aug 9): the Sahara flyover, full-screen
   and fixed beneath everything; a dark veil keeps the words legible.
   Content sections lift above it (position+z); the opaque hero
   simply covers it until you scroll. */
.about-bg { position: fixed; inset: 0; z-index: 0; overflow: hidden;
  background: var(--ink); }
.about-bg video { width: 100%; height: 100%; object-fit: cover; }
.about-bg::after { content: ""; position: absolute; inset: 0;
  background: rgba(10, 11, 13, .40); }
.about-bg ~ section, .about-bg ~ p { position: relative; z-index: 1; }
@media (max-width: 700px), (prefers-reduced-motion: reduce) {
  .about-bg video { display: none; }
}

/* Breathing room (Dan, Aug 9): the About block steps in from the
   left edge — the composition the pre-photo layout had. */
.about-article { margin-left: clamp(24px, 13vw, 300px); }
@media (max-width: 900px) { .about-article { margin-left: 0; } }
.about-head { display: flex; align-items: center; gap: 26px;
  margin-top: 8px; }
.about-crest { width: clamp(84px, 9vw, 130px); height: auto;
  flex: 0 0 auto; }
/* Photo left, text right, pull-quote under the text (Dan, Aug 9 v2).
   Stacks on phones. The photo container's aspect matches the
   panorama's LEFT HALF; object-position:left crops the rest away. */
.about-cols { display: flex; gap: 56px; align-items: flex-start;
  margin-top: 24px; }
.about-photo { flex: 0 0 min(38%, 440px); margin: 0;
  aspect-ratio: 0.884; overflow: hidden; border-radius: 3px; }
.about-photo img { width: 100%; height: 100%;
  object-fit: cover; object-position: left center; display: block; }
.about-main { flex: 1 1 auto; min-width: 0; }
.about-quote { margin-top: 36px;
  font-size: 25px; line-height: 1.5; color: var(--accent);
  font-style: italic; }
@media (max-width: 900px) {
  .about-cols { flex-direction: column; gap: 30px; }
  .about-photo { flex: none; width: 100%; }
}

/* ---- shelves and rails ---- */
.shelves { padding: 44px 5vw 80px; display: flex;
  flex-direction: column; gap: 52px; }
.shelf-head { display: flex; align-items: baseline; gap: 14px;
  margin-bottom: 16px; }
/* Shelf-label experiment (Dan, Aug 8): 1.5x and SANS — overrides the
   markup's .serif class, so no template edit needed to try it on
   (or revert it) everywhere at once. */
.shelf-label { font-size: 36px; color: var(--accent);
               font-family: 'Inter', sans-serif; }
a.shelf-label { text-decoration: none; }
/* A label that FOLLOWS a kicker is a person's name (Featured
   Musician: / Featured Astronaut:) — kicker gold, name white
   (Dan, Aug 8). */
.shelf-kick + .shelf-label { color: var(--paper); }
/* Gold kicker before a home person-shelf's name (Dan, Aug 6):
   "Featured Musician: Brian Hoffman". */
.shelf-kick { color: var(--accent); margin-right: 2px; }
.shelf-note { color: var(--dim); font-size: 13px;
  letter-spacing: .04em; }
.rail { display: flex; gap: 18px; overflow-x: auto;
  scroll-snap-type: x proximity; padding-bottom: 8px;
  /* Headroom for the .ritem.on selection ring (outline-offset 3px +
     hover scale): the scroll container clips anything past its
     content box — top edge first (Dan, Aug 8), then the LEFT edge on
     a rail's first card (same day). Padding on three sides gives the
     ring room; negative margins cancel the layout shift so nothing
     moves. (Bottom already had its 8px.) */
  padding-top: 8px; margin-top: -8px;
  padding-left: 8px; margin-left: -8px;
  padding-right: 8px; margin-right: -8px;
  scrollbar-width: thin; scrollbar-color: var(--rule) transparent; }
/* The Featured shelf closes with a gold hairline (Dan, Aug 6) —
   curtain-edge between the staged picks and the taste shelves. The
   accent touches almost nothing (doc 02 §1), which is why one thin
   line is enough to mark the boundary. */
.shelf-featured { padding-bottom: 44px;
  border-bottom: 1px solid var(--accent); }
.shelf-featured .shelf-label { color: var(--accent); }
/* Person shelves wear their portrait (Dan, Aug 6): the '{Name} -
   Square' photo, square and unmasked — the circle is the stage's
   voice; the shelf hangs the photo like the covers, same frame
   language. Height matches the card thumb at its floor (300px
   card ≈ 169px thumb) so portrait and covers read as one row. */
.shelf-body { display: flex; gap: 18px; align-items: flex-start; }
.shelf-portrait { flex: 0 0 auto; aspect-ratio: 1;
  height: calc(var(--card-w) * 9 / 16);   /* = the thumb's height */
  width: auto; object-fit: cover; border-radius: 4px;
  /* Crop from the TOP (Dan, Aug 12 — Nicole Mann's head was cut):
     heads live at the top of standing portraits; center-crop
     decapitates. No effect on square musician photos or wide crew
     photos (those crop horizontally). */
  object-position: top;
  border: 1px solid rgba(242, 239, 233, .16); }
.shelf-body .rail { flex: 1 1 auto; min-width: 0; }

/* ---- THE CARD (one size everywhere — Dan, Aug 2: the home card,
        "big and compelling"). --card-w is THE width; anything that
        must align with the cards (shelf portraits) derives from it. */
:root { --card-w: clamp(300px, 30vw, 440px); }
.ritem { flex: 0 0 auto; width: var(--card-w);
  scroll-snap-align: start; text-decoration: none; display: block; }
/* The frame (Dan, Aug 1): a quiet frame restores each cover as a
   hung work on the dark wall. */
.rthumb { display: block; aspect-ratio: 16 / 9; border-radius: 4px;
  background: var(--tile); position: relative; overflow: hidden;
  border: 1px solid rgba(242, 239, 233, .16);
  transition: transform var(--slow), opacity var(--slow),
              border-color var(--slow); }
.ritem:hover .rthumb { border-color: rgba(242, 239, 233, .34); }
.rthumb img { position: absolute; inset: 0; width: 100%;
  height: 100%; object-fit: cover; }
.ritem:hover .rthumb, .ritem.on .rthumb { transform: scale(1.03); }
.ritem.on .rthumb { outline: 1px solid var(--paper); outline-offset: 3px; }
.rthumb .dur { position: absolute; right: 8px; bottom: 8px;
  font-size: 11px; padding: 3px 8px; border-radius: 3px;
  background: var(--scrim); color: var(--paper); }
/* Over-line — featured person shelves only (Aug 8): the person's
   name above the card, since those shelves mix people. */
.rover { display: block; font-size: 15px; font-weight: 500;
         color: var(--paper); margin-bottom: 6px;
         text-align: center;
         white-space: nowrap; overflow: hidden;
         text-overflow: ellipsis; }
/* Position chip — ordered collections only (the ONE home of episode
   numbers, D27 complete): top-left, quiet. */
.rthumb .rpos { position: absolute; left: 8px; top: 8px;
  font-size: 11px; padding: 3px 8px; border-radius: 3px;
  background: var(--scrim); color: var(--paper); }
/* ♪ Sample button on the card plate (Aug 9 v2 — the thumb chip was
   too subtle): the stage pill's small sibling, after the astronaut
   line. Gold time; gold all over while playing. */
.ritem .rsample { display: inline-block; align-self: flex-start;
  margin-top: 10px; padding: 6px 14px; border-radius: 999px;
  border: 1px solid rgba(242, 239, 233, .45); color: var(--paper);
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  cursor: pointer;
  transition: border-color var(--slow), color var(--slow); }
.ritem .rsample .wt { color: var(--accent); font-weight: 400;
  margin-left: 4px; }
.ritem .rsample:hover { border-color: var(--paper); }
.ritem .rsample.on { border-color: var(--accent);
  color: var(--accent); }
.ritem .rsample.on .wt { color: var(--accent); }
/* ♥ Heart (D59, Aug 9): anonymous fav. Pill on the film page;
   fills gold when THIS browser has hearted it (.on). Count hides
   at zero (empty .hn). */
.heart { cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 12px; border-radius: 999px;
  border: 1px solid rgba(242, 239, 233, .45); color: var(--paper);
  font-size: 13px; line-height: 1;
  transition: border-color var(--slow), color var(--slow); }
.heart:hover { border-color: var(--paper); }
/* Gold counter (Dan, Aug 9: "I like the gold counter") — always. */
.heart .hn { font-weight: 400; font-size: 12px; color: var(--accent); }
.heart .hn:empty { display: none; }
.heart.on { border-color: var(--accent); }
/* The card's seat (Dan, Aug 9 v2): the title row, left of the
   m-number — compact, no pill, quiet like the address beside it. */
.rt .heart { flex: 0 0 auto; border: none; padding: 0; gap: 4px;
  color: var(--dimmer); font-size: 13px; }
.rt .heart:hover { color: var(--paper); }
.rt .heart .hn { font-size: 11.5px; }
/* The film page's seat: right edge of the kicker row. Share floats
   beside it (Dan, Aug 12) — date is information, heart + share are
   ACTIONS, clustered right: love it, then tell someone. Floats
   render right-to-left in source order, so heart first in markup =
   heart at the far edge, Share to its left. */
.film .fheart { float: right; margin-top: -4px; }
.film .shareseat { float: right; margin: -2px 14px 0 0; }
/* A loved movie wears a RED heart (Dan, Aug 9) — server truth
   (hearts >= 1, class .has rendered + toggled by EMTHearts),
   regardless of whose browser did the loving. LAST in the heart
   rules on purpose: it must outrank every seat's quiet gray at
   equal specificity (the first placement lost that cascade — the
   Aug 10 gray-heart bug). */
.heart.has, .rt .heart.has { color: #e0454f; }
/* Label plate: the museum label under the artwork. Title left,
   m-number right (Dan, Aug 6) — the address on the label. */
.rt { display: flex; align-items: baseline; gap: 10px;
  margin-top: 12px; color: var(--prose);
  font-size: 14px; transition: color var(--slow); }
.rt-t { flex: 1 1 auto; min-width: 0; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.rid { flex: 0 0 auto; color: var(--dimmer); font-size: 11.5px; }
.ritem:hover .rt { color: var(--paper); }
/* The authored pair closing the plate (Dan, Aug 6): view — "what
   the film shows", italic, one line — then the brief blurb, two
   lines at most. Both optional (D12). */
.rv { display: block; margin-top: 4px; color: var(--dim);
  font-size: 13px; font-style: italic; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.rb { display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
  margin-top: 2px; color: var(--dimmer); font-size: 12px;
  line-height: 1.45; }
.rs { display: block; margin-top: 3px; color: var(--dim);
  font-size: 12.5px; }
.rx { display: block; margin-top: 2px; color: var(--dimmer);
  font-size: 12px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
/* End-cap: the quiet door into the deep page. */
.rcap .rthumb { display: flex; align-items: center;
  justify-content: center; border: 1px solid var(--rule);
  background: transparent; }
.rcap-in { color: var(--dim); font-size: 17px;
  letter-spacing: .04em; transition: color var(--slow); }
.rcap:hover .rcap-in { color: var(--paper); }

/* ---- the theater grid: same card, wrapping (All Films, collections).
        minmax floor matches the card's clamp floor; cells breathe to
        the same max. ---- */
.tbody { padding: 44px 5vw 80px; }
.tgrid { display: grid; gap: 26px 18px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.tgrid .ritem { width: auto; }
/* Collection/section heading above a grid — same voice as shelf-head. */
.thead { display: flex; align-items: baseline; gap: 14px;
  margin-bottom: 22px; }
/* Collection tiles (D30 v5): the card frame wearing a collection's
   name — the veil keeps the serif legible over any cover. */
.ctile .ctile-name { position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center; text-align: center;
  padding: 12px; font-size: clamp(22px, 2.4vw, 34px);
  color: var(--paper);
  background: linear-gradient(to top, rgba(10,11,13,.66),
              rgba(10,11,13,.25)); }
/* Masthead search (D30 v5 — industry chrome convention): quiet until
   focused. Hidden on phones; the Arrange row's search serves there. */
.topsearch { margin-left: 18px; position: relative; }
/* The x inside the box — visible only when a term is in play. */
.qclear { position: absolute; right: 10px; top: 50%;
  transform: translateY(-50%); background: none; border: 0;
  color: var(--dim); font-size: 15px; cursor: pointer;
  padding: 0 2px; line-height: 1; }
.qclear:hover { color: var(--paper); }
.topsearch input { background: transparent;
  border: 1px solid var(--rule); border-radius: 999px;
  color: var(--prose); padding: 6px 26px 6px 14px; width: 150px;
  font-size: 12.5px; transition: width var(--slow),
  border-color var(--slow); }
.topsearch input:focus { width: 240px; outline: none;
  border-color: var(--dim); }
/* D31: the chrome search is THE search (the Arrange row died) — it
   stays on phones too, sized down. */
@media (max-width: 900px) { .topsearch input { width: 110px; } }


/* ---- EDIT FEATURED (D53, Aug 6 2026) — the stage-five desk --------
   All rules scoped under .fdesk (the D44 collision lesson). Source
   rail wears the cockpit's contact-sheet size; panel slots are
   larger, numbered, with quiet controls. */
.fdesk { padding: 0 40px 120px; }
.fdesk .frail {
  display: flex; gap: 8px; overflow-x: auto; overflow-y: hidden;
  padding: 12px 0 10px; margin-bottom: 30px;
  position: sticky; top: 0; z-index: 30;
  background: var(--ink); border-bottom: 1px solid var(--rule);
  scrollbar-width: thin;
}
.fdesk .fthumb {
  position: relative; flex: 0 0 118px; height: 66px; border-radius: 3px;
  background: var(--tile); overflow: hidden; display: block;
  cursor: pointer; transition: transform var(--slow);
}
.fdesk .fthumb:hover { transform: translateY(-2px); }
.fdesk .fthumb.picked {
  outline: 3px solid var(--accent); outline-offset: -3px;
  box-shadow: 0 0 0 2px var(--ink), 0 0 14px 2px rgba(232,163,61,.55);
  z-index: 1;
}
.fdesk .fthumb img { width: 100%; height: 100%; object-fit: cover;
  display: block; }
.fdesk .fgroup { margin: 34px 0; }
.fdesk .fghead { display: flex; align-items: baseline; gap: 14px;
  margin-bottom: 12px; }
.fdesk .fitems { display: flex; flex-wrap: wrap; gap: 16px; }
.fdesk .fitem { width: 200px; }
.fdesk .fslotthumb { position: relative; display: block;
  aspect-ratio: 16 / 9; border-radius: 3px; background: var(--tile);
  overflow: hidden; cursor: pointer;
  border: 1px solid rgba(242, 239, 233, .16); }
.fdesk .fslotthumb img { position: absolute; inset: 0; width: 100%;
  height: 100%; object-fit: cover; }
.fdesk .fitem:hover .fslotthumb { border-color: var(--accent); }
.fdesk .fpos { position: absolute; left: 6px; top: 5px;
  font-size: 12px; padding: 2px 7px; border-radius: 3px;
  background: var(--scrim); color: var(--accent); }
.fdesk .fitem .rbadge { left: auto; right: 6px; top: 5px; }
.fdesk .ftitle { display: block; margin-top: 6px; font-size: 12.5px;
  color: var(--prose); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.fdesk .fctl { display: flex; gap: 6px; margin-top: 4px; }
.fdesk .fctl button { background: transparent; color: var(--dim);
  border: 1px solid var(--rule); border-radius: 3px; cursor: pointer;
  font-size: 12px; padding: 1px 8px; }
.fdesk .fctl button:hover { color: var(--paper);
  border-color: var(--dim); }
.fdesk .fadd .fslotthumb { display: flex; align-items: center;
  justify-content: center; background: transparent;
  border: 1px dashed var(--rule); }
.fdesk .faddin { color: var(--dim); font-size: 30px; }
.fdesk .fadd:hover .faddin { color: var(--accent); }

/* ---- THE COCKPIT (Dan, Aug 4 2026 — D44; flow layout Aug 11) --------
   One film per page. The rail is the index and never re-renders on a
   field save; the body is FIVE FLOW COLUMNS in review order (.ckflow) —
   Vimeo+Sources · Movie · facts · Teaser+Sample · Certify.
   ALL rules here are scoped under .cockpit (Aug 6): the desk reuses
   the public .rail/.rthumb class names, and the un-scoped originals
   overrode THE CARD site-wide — every public thumbnail collapsed to
   117x66 (height 66 + the card's aspect-ratio). Scoping is the fence;
   never add un-scoped .rail/.rthumb rules below the card spec. */
.cockpit { padding: 0 40px 120px; }

.cockpit .rail {
  display: flex; gap: 8px; overflow-x: auto; overflow-y: hidden;
  padding: 12px 0 10px; margin-bottom: 22px;
  position: sticky; top: 0; z-index: 30;
  background: var(--ink); border-bottom: 1px solid var(--rule);
  scrollbar-width: thin;
}
.cockpit .rthumb {
  /* 25% larger (Dan, Aug 8): 118x66 -> 148x83. Since D76 the anchor
     is a small column — the 148x83 tile (.rimg) plus the musician
     line under it (Dan, Aug 23: "add the musician's name under each
     thumbnail"). Tile facts (frame, badges) live on .rimg. The
     public card spec's aspect-ratio + overflow:hidden must be
     un-done here or the name line clips (the scoping fence cuts
     both ways). */
  position: relative; flex: 0 0 148px; display: block;
  aspect-ratio: auto; height: auto; overflow: visible;
  border: 0; background: none;
  transition: transform var(--slow);
}
.cockpit .rthumb:hover { transform: translateY(-2px); }
.cockpit .rimg {
  position: relative; display: block; width: 148px; height: 83px;
  border-radius: 3px; background: var(--tile); overflow: hidden;
  /* Full brightness for every film (Dan, Aug 4) — the rail is a
     contact sheet, not a dimmed backdrop. The current film is marked
     by the gold frame alone, so that frame has to carry it. */
  transition: box-shadow var(--slow);
}
.cockpit .rthumb.here .rimg {
  outline: 3px solid var(--accent); outline-offset: -3px;
  box-shadow: 0 0 0 2px var(--ink), 0 0 14px 2px rgba(232,163,61,.55);
  z-index: 1;
}
.cockpit .rthumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* UNPUBLISHED reads at a glance — v2 (Dan, Aug 23, superseding the
   Aug 8 grayscale: "grey washes out the thumbnails"). Drafts keep
   FULL COLOR like live films; the draft fact is carried by the red
   m-number plus a red frame around the tile. The current film's
   gold .here outline draws inside it and still wins the eye. */
.cockpit .rthumb.draft .rimg { border: 2px solid #E24B4A; }
.cockpit .rthumb.draft .rbadge { color: #E24B4A; }
/* The musician line (D76) — dim, one line, ellipsized. */
.cockpit .rname { display: block; width: 148px; margin-top: 3px;
  font-size: 10px; letter-spacing: .03em; color: var(--dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-height: 12px; }
.cockpit .rthumb.here .rname { color: var(--accent); }
/* The rail bar (D76): musician-first, then status; count trails. */
.railbar { display: flex; gap: 10px; align-items: center;
  /* Its own line-height + real bottom padding: the cockpit's tight
     inherited line box let glyph descenders (and focus rings) paint
     below the bar, where the rail's opaque sticky background
     covered them (the "clipped bottoms", Aug 23 ×2). */
  line-height: 1.5; padding: 10px 0 8px; position: relative; }
.railbar select { font: inherit; font-size: 12px; line-height: 1.4;
  height: auto; color: var(--paper);
  background: var(--tile); border: 1px solid var(--rule);
  border-radius: 3px; padding: 4px 8px 5px; }
.railcount { font-size: 11.5px; color: var(--dimmer);
  letter-spacing: .04em; }
.railsplit { display: inline-flex; gap: 5px; align-items: center;
  font-size: 12px; color: var(--dim); cursor: pointer;
  white-space: nowrap; }
.railsplit input { accent-color: var(--accent); }
.rnone { position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; color: var(--tile-ink); font-size: 20px; }
.rbadge { position: absolute; left: 4px; top: 3px; font-size: 9.5px;
  letter-spacing: .06em; color: var(--accent); background: var(--scrim);
  padding: 1px 4px; border-radius: 2px; }
.rpips { position: absolute; right: 4px; bottom: 4px; display: flex; gap: 2px; }
.rpips i { width: 4px; height: 4px; border-radius: 50%;
  background: rgba(255,255,255,.28); }
.rpips i.on { background: var(--accent); }

.ckhead {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 30px; flex-wrap: wrap; margin: 0 0 22px;
}
.ckhead h2 { font-size: clamp(26px, 2.6vw, 40px); line-height: 1.05; }
.cknav { display: flex; gap: 10px; align-items: center; }
.ckbtn {
  font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase;
  padding: 8px 16px; border: 1px solid var(--rule); border-radius: 2px;
  color: var(--paper); transition: border-color var(--slow);
}
.ckbtn:hover { border-color: var(--paper); }
.ckbtn.off { opacity: .3; }
#savenote.good { color: var(--accent); }
#savenote.bad  { color: #ff6b6b; }
/* CERTIFY in the head row (Dan, Aug 11): the three judgement flags,
   horizontal, centered between the title and the nav. Outside
   .efields, so they carry their own pubbox dress — grey until
   checked, same read-from-across-the-room rule. */
.ckflags { display: flex; gap: 22px; align-items: center;
  flex-wrap: wrap; margin-top: 8px; }
.ckflags .pubbox { display: flex; align-items: center; gap: 9px; }
.ckflags .pubbox em { font-size: 14px; color: var(--dim); }
/* Checked reads BLUE (Dan, Aug 11) — matches the checkbox itself;
   grey stays the unchecked voice. */
.ckflags .pubbox:has(input:checked) em { color: #88ccff; }
/* Constant height whether empty or speaking — a message must never
   bounce the column below (Dan, Aug 8). */
.cockpit .ckhead .hint { min-height: 1.7em; margin: 0; }

/* THE FLOW (Dan, Aug 11): five columns, left-to-right in review
   order — 1 Vimeo+Sources · 3 Movie · facts · 4 Teaser+Sample ·
   5 Certify. One pass, no bouncing. */
.ckflow { display: grid; gap: 26px 34px; align-items: start;
  grid-template-columns: repeat(5, minmax(0, 1fr)); }
.ckcol { display: flex; flex-direction: column; gap: 26px; min-width: 0; }

/* The m-number rides with the film's name — one address, D27. */
.ckhead h2 .ckid { color: var(--accent); }

.vthumb { position: relative; aspect-ratio: 16/9; border-radius: 3px;
  background: var(--tile); background-size: cover;
  background-position: center; }
.vthumb.empty::after { content: "\266A"; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--tile-ink); font-size: 30px; }
.vdraft { position: absolute; right: 8px; top: 7px; font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--accent);
  background: var(--scrim); padding: 2px 7px; border-radius: 2px; }
.vplayer video, .vplayer iframe {
  width: 100%; aspect-ratio: 16/9; border: 0; border-radius: 3px;
  background: #000; display: block;
}
.vlabel { font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--dim); margin-bottom: 6px; }
.vnone { aspect-ratio: 16/9; border: 1px dashed var(--rule);
  border-radius: 3px; display: flex; align-items: center;
  justify-content: center; color: var(--dimmer); font-size: 13px; }
/* (The old sticky .visuals column and its gold hairlines died with
   the flow layout, Aug 11 — each player now lives in its zone.) */

/* The globe moved into the EARTH block, under the fields it stands on
   (Dan, Aug 4). Site chrome for the D37 label, never baked in. */
.eglobe { position: relative; margin-top: 6px; width: 168px; }
.eglobe img { width: 100%; display: block; }
.egmulti {
  position: absolute; left: 50%; top: 10%; transform: translateX(-50%);
  font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
  white-space: nowrap; color: var(--paper);
  background: rgba(0,0,0,.55); padding: 2px 8px; border-radius: 999px;
}

/* A failed autosave stays visible until a later write succeeds. */
.efields input.failed, .efields textarea.failed {
  border-bottom-color: #ff6b6b; color: #ff6b6b;
}

/* The flow steps down as the window narrows — columns wrap, the
   left-to-right order becomes top-to-bottom (same sequence). */
@media (max-width: 1700px) {
  .ckflow { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 1200px) {
  .ckflow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .ckflow { grid-template-columns: 1fr; }
}

/* The film's own end-credits card (F26) — a source to type from. In
   the flow layout it closes zone 2 (Sources), full column width. */
.ecredits img {
  width: 100%; display: block; margin-top: 10px;
  border: 1px solid var(--rule); border-radius: 3px;
}
.ecalts { margin-top: 8px; font-size: 11.5px; color: var(--dimmer); }
.ecalts a { color: var(--accent); margin-left: 8px; }

/* The cover picker (F27) — candidate thumbnails under the card. Click
   is the save. The matcher gets the easy films; this gets the rest. */
.ecnone { padding: 26px; border: 1px dashed var(--rule); border-radius: 3px;
  color: var(--dimmer); font-size: 13px; text-align: center; }
.ecpick { margin-top: 16px; }
.ecrow { display: flex; gap: 10px; overflow-x: auto; padding: 10px 0 4px; }
.eccand {
  flex: 0 0 132px; background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--dim); font: inherit; text-align: left;
  transition: color var(--slow);
}
.eccand img {
  width: 100%; aspect-ratio: 16/9; object-fit: cover; display: block;
  border: 1px solid var(--rule); border-radius: 2px; opacity: .72;
  transition: opacity var(--slow), border-color var(--slow);
}
.eccand:hover img { opacity: 1; border-color: var(--dimmer); }
.eccand.on img { opacity: 1; border-color: var(--accent); border-width: 2px; }
.eccand.on { color: var(--accent); }
.eccand span {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; font-size: 10.5px; line-height: 1.35; margin-top: 5px;
}

/* Teaser prep (D28 std op, in the cockpit Aug 4; candidate-strip era
   Aug 11 — the old per-passage readout classes deleted with it, git
   holds them). Compact and mono: an instrument readout, not prose. */
.tpload { margin-top: 8px; font-size: 11.5px; color: var(--dimmer); }
.tprep { margin-top: 8px; font-size: 11.5px; line-height: 1.55;
  font-family: ui-monospace, "SF Mono", Menlo, monospace; }
.tprep .tpnone { color: var(--dimmer); }
.tprow { color: var(--dim); overflow-wrap: anywhere; }
.tprow b { color: var(--paper); font-weight: 600; }
.tpsum { margin-top: 0; }
/* Blue, not gold (Dan, Aug 11) — an ACTION button, not an identity
   accent. EE's tier-2 blue; desk-only chrome. */
.tpub { font: inherit; font-size: 11px; color: #88ccff;
  background: none; border: 1px solid #88ccff; border-radius: 3px;
  padding: 3px 10px; cursor: pointer; transition: opacity var(--slow); }
.tpub:hover { opacity: .8; }
.tpub:disabled { color: var(--dimmer); border-color: var(--dimmer);
  cursor: default; }

/* Opening-clip candidates (Dan, Aug 11 — replaced the filename
   morass): the first up to three clip passages, each wearing its
   in-point photo's Explorer thumbnail so the eye decides which clip
   the teaser cuts from. The lead card (passage 1) wears gold. */
.tpcands { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px; margin-bottom: 10px; }
.tpcand img, .tpcand video { width: 100%; aspect-ratio: 8/5;
  object-fit: cover; display: block; background: #000;
  border: 1px solid var(--rule); border-radius: 2px; }
.tpcand.lead img, .tpcand.lead video { border-color: var(--accent); }
.tpcand-none { aspect-ratio: 8/5; border: 1px dashed var(--rule);
  border-radius: 2px; display: flex; align-items: center;
  justify-content: center; color: var(--tile-ink); }
.tpc-head { margin-top: 4px; font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--paper); font-weight: 600; }
.tpcand.lead .tpc-head { color: var(--accent); }
/* D73 (Aug 23): the ruling buttons — quiet cousins of .tpub. "make
   primary" on the unruled cards; "clear override" (dimmer still) on
   the card Dan crowned, to return the film to timeline order. */
.tpc-make { font: inherit; font-size: 10px; letter-spacing: .05em;
  color: #88ccff; background: none; border: 1px solid var(--rule);
  border-radius: 3px; padding: 2px 8px; margin-top: 4px;
  cursor: pointer; transition: border-color var(--slow); }
.tpc-make:hover { border-color: #88ccff; }
.tpc-make:disabled { color: var(--dimmer); border-color: var(--dimmer);
  cursor: default; }
.tpc-clear { color: var(--dimmer); }
.tpc-clear:hover { color: var(--dim); border-color: var(--dimmer); }
.tpc-file { color: var(--paper); overflow-wrap: anywhere; }
.tpc-row { color: var(--dim); overflow-wrap: anywhere; }
.tpc-warn { color: var(--accent); overflow-wrap: anywhere; }
.tpc-dim { color: var(--dimmer); overflow-wrap: anywhere; }
