/* ---------------------------------------------------------------------------
   Story origin pages — /song-origins/<slug>/ for entries that carry prose.

   This file deliberately styles almost nothing above the fold. The hero is the
   SONG PAGE hero: renderStoryOriginPage emits .sp-hero / .sp-cover / .sp-hero-mid
   / .sp-facts, and song-page.css (loaded first) does all of that work including
   every phone breakpoint it already fought for. Reusing the markup rather than
   re-describing it is the only reason these two page types cannot drift apart.

   What IS here: the reading column, and the four blocks that hang off it —
   the nights table, the research list, the share control and the pager.
   --------------------------------------------------------------------------- */

/* The deck. A summary sentence sitting under the title, the way a magazine
   standfirst does — so the reader knows what the piece is before committing to
   it, and the story below never has to restate itself in its first line. */
/* THE MEASURE WAS NARROWER THAN THE COLUMN IT SITS IN. 46ch rendered 579px
   inside a 729px column, so 150px went unused and every summary broke a line
   early — which is what Alex saw: "you could probably also expand the width of
   the text area so it didn't break where it is."
   58ch fills the column and stays inside the 45–75 character measure that keeps
   a line readable, so this is the column doing its job, not a wider line.
   THREE LINES IS FINE; A STRANDED WORD IS NOT. His rule: "i'm allergic to
   orphans if it needs to be on 3 lines that's fine."
   `pretty` was not enough on its own: MEASURED across all 40 decks it still left
   eight with a two-word last line ("is in.", "the morning.", "his bedroom.").
   `balance` evens every line of the block instead of only rescuing the last one,
   which is what a standfirst wants anyway — it reads as a shape rather than as
   prose that ran out. Chrome and Safari balance up to a handful of lines and
   fall back to normal wrapping elsewhere, so nothing breaks where it is absent.
   THE POINT: the sentences are not counted down to fit. Alex's words stay as
   written and the layout does the accommodating. */
body.stagelight .og-deck {
  margin: 14px 0 0;
  max-width: 58ch;
  font: 400 clamp(16.5px, 1.35vw, 19px)/1.55 var(--sl-body);
  color: var(--sl-muted);
  text-wrap: balance;
}

/* ---- the reading column -------------------------------------------------
   .og-body carries .sp-hero-in as well, which is where its width, its two
   columns and every one of their breakpoints come from. Nothing about the grid
   is restated here — only the things a body needs that a hero does not: top
   alignment instead of bottom, and its own vertical padding. That is the whole
   trick to the story starting on the same line as the title.

   68 characters is the measure the prose is set to. The nights table and the
   pager share the column but are scannable rather than readable, so they are
   allowed to use all of it. */
body.stagelight .og-body {
  align-items: start;
  padding: 0 0 96px;
}
body.stagelight .og-col {
  grid-column: 2;
  min-width: 0;
  max-width: 68ch;
}

/* ---- the rail -----------------------------------------------------------
   The artwork column, reused. It holds the share control and the filed-under
   chips and sticks while the story scrolls past — the only thing on this page
   that needed to stay reachable through a long read. Deliberately NOT an audio
   player: the player belongs to the listen shell, and bolting it onto an
   article would be a second component doing a job this page does not have. */
/* ---- the hero picture ---------------------------------------------------
   NO REFLECTION, AND SQUARE. Alex, 8/7: "we don't need that mirror thing. Just
   put a square image. You can zoom in or whatever."
   The reflection is a real part of the SONG page's hero, where the picture is
   an album sleeve sitting on a surface and the depth is the point. Here the
   picture is a photograph of a venue, and a mirrored venue reads as a glitch
   rather than a sleeve on glass — it also doubles the block's height for no
   information, which on a page already accused of going on too long is the
   wrong trade.
   SCOPED, NOT REMOVED. These rules live in origin-page.css, which is loaded by
   exactly the thirteen story pages and nothing else, so the song pages he has
   already signed off keep their reflection untouched.
   Square by cropping, not by squashing: object-fit cover on a 1:1 frame, which
   is the "zoom in or whatever". */
body.stagelight .og-body ~ * .sp-cover::after,
body.stagelight .sp-hero .sp-cover::after { display: none; }
body.stagelight .sp-hero .sp-cover { filter: drop-shadow(0 16px 34px rgba(0,0,0,.5)); }
body.stagelight .sp-hero .sp-cover img {
  aspect-ratio: 1;
  width: 100%;
  height: auto;
  object-fit: cover;
  object-position: center;
  border-radius: 10px;
}

/* ---- A PHOTOGRAPH ALEX FRAMED KEEPS THE FRAME ----------------------------
   The square above is right for a record sleeve: a sleeve IS square, so a 1:1
   crop takes nothing. It is wrong for a photograph a person composed. Of his
   forty images 26 are landscape — a 1:1 crop discards 44% of The Take Out and
   40% of Space Wrangler, and because object-fit centres the crop it eats BOTH
   edges, which is precisely what he chose when he framed it.
   So: no forced ratio and no cropping. The picture arrives at its own shape.
   Alex: "the image is gonna typically be a rectangle or a unique size so design
   with that in mind."

   WHY A HEIGHT CEILING RATHER THAN NONE. Three of the forty are portrait, and
   an uncapped portrait at 264px wide runs to ~350px and drags the whole hero
   down with it. The cap lets a tall picture shrink to fit instead of setting
   the height of the row; a landscape one never reaches it.
   The sleeve's hard-edged shadow is softened here too — a sleeve sits on a
   surface, a photograph is a window, and the same heavy drop reads as a sticker
   once the shape stops being square. */
/* IT ALIGNS TO THE TITLE, NOT TO THE BASELINE. The hero bottom-aligns its
   three columns, which was right when the picture was a 264px square and set
   the row's height itself. A landscape photograph is 179px, so it dropped to
   the baseline and left 85px of empty column ABOVE it — next to the song title,
   which is the first thing the eye lands on. Alex read it as the page starting
   late: "weird layout... padding at the top. why?"
   Nothing was added or removed to fix it; the slack simply moves to the bottom
   of that column, where the title block and the fact strip already end, so it
   reads as the hero's floor rather than a hole beside the headline.

   THEN IT WENT TO CENTRE, and this is the third position tried, so the whole
   argument is written down. `start` traded one lopsided gap for another:
   MEASURED on Fishwater, 56px above the photograph and 112px below it, exactly
   double, because the picture is the shortest thing in the row and every spare
   pixel pooled under it. Alex: "Is the space above and below the fishwater
   image equal?" It was not. `center` splits it — 84 above, 84 below, on every
   page whatever shape the picture is.
   THE TRADE, so nobody silently reverts this: centring moves ~28px of that
   slack back ABOVE the photograph, which is the direction of the original
   "padding at the top" complaint. It is a quarter of what he saw then (85px),
   and it buys a gap that is equal instead of one that is merely small. If he
   wants it hung off the title line again, this one word is the whole change. */
body.stagelight .sp-hero .sp-cover-own {
  aspect-ratio: auto;
  align-self: center;
  overflow: visible;
  /* The sleeve's 1px ring is drawn on .sp-cover and would outline the BOX, not
     the picture, the moment the box stops matching the picture's shape. */
  box-shadow: none;
  border-radius: 0;
  line-height: 0;          /* no inline descender gap under the image */
  display: flex;
  /* CENTRED IN ITS COLUMN. The column is sized for a 264px sleeve; a landscape
     photograph is narrower or shorter than that, and left-aligning it left the
     slack on one side only, which is what Alex saw: "center the image within
     the hero it's lopsided." */
  justify-content: center;
  align-items: flex-start;
  filter: drop-shadow(0 14px 30px rgba(0, 0, 0, .45));
  /* OPTICALLY CENTRED, NOT ARITHMETICALLY. align-self:center made the two gaps
     identical to the pixel — measured 84/84 at 1440 and at 1800, on the cover,
     the hero, the tint and the ambient box alike — and Alex still read it as
     wrong: "dude you can't tell me there isn't less space below than above."
     He was right, and the amount is measured, not guessed: the page was
     rendered twice, once with the shadow above and once with `filter:none`,
     and the two screenshots differenced. The shadow paints 43px ABOVE the
     picture and 53px BELOW it — the 30px blur spreads upward and cancels most
     of the 14px downward offset, so the asymmetry is 10px, not the 44px the
     offset alone suggests. With the box centred, the gaps the EYE is given are
     41px above and 32px below. Nine less below. Exactly what he said.
     Half the difference, so the seen gaps land at 36 and 37. The measured ones
     go 5px top-heavy, which is the right trade — nobody reads a page with a
     ruler. transform, so nothing reflows. Re-measure with the diff before
     touching this number; the shadow and the number move together. */
  transform: translateY(-5px);
}
/* width:auto + max-width + max-height is what actually preserves the ratio:
   the browser scales the picture down until it satisfies BOTH bounds. Setting
   width:100% with a max-height instead would break the ratio and letterbox. */
body.stagelight .sp-hero .sp-cover-own img {
  aspect-ratio: auto;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 320px;
  object-fit: contain;
  border-radius: 8px;
}

/* THE GRID ITEM STICKS, NOT A CHILD OF IT — copied from .album-aside, which is
   the pattern already working on the album pages. Alex, 8/8: "that is not
   sticky that left sidebar. there should be some code for sidebar already on
   the listen page. don't rebuild."
   He was right and the earlier report that it WAS sticky was wrong: the style
   said position:sticky, so it was never scrolled to check. Measured properly —
   the sidebar's top went 494px to -706px over a 1200px scroll, i.e. straight off
   the screen.
   WHY IT COULD NEVER HAVE WORKED: .og-body sets align-items:start, so .og-rail
   is only as tall as its own contents — 488px against a 1081px story. A sticky
   child cannot travel further than its containing block, so it ran out after
   488px and left. Making the ITEM sticky puts its containing block at the grid
   row's full height, which is exactly what .album-aside does. */
body.stagelight .og-rail {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
  position: sticky;
  top: 92px;
  align-self: start;
}
/* THE RAIL STARTS WITH THE STORY, AND ITS BLOCKS STAY TOGETHER. It used to
   begin 62px down, which floated the Share button alone in the middle of an
   empty column with the picks and the video far below it — three islands rather
   than one group. Alex: "The sidebar should be top aligned with just a little
   padding at the top ... share and the listen links and youtube need to be
   close together."
   6px is the optical nudge that lines Share's cap-height up with the story's
   first line; the 10px gap holds the three as one stack. */
body.stagelight .og-rail-in {
  display: grid;
  gap: 10px;
  justify-items: start;
  /* THE SAME OFFSET .og-story USES, so Share starts on the story's first line
     rather than near it. Alex: "share button can align with the text on the
     right and then the listening links and youtube can stack below."
     Measured: story first line 542, Share 542. */
  padding-top: clamp(38px, 5vw, 62px);
}


/* The credit line wraps here, unlike the song page's, because an origins credit
   carries three facts rather than one. See the comment in renderStoryOriginPage. */
body.stagelight .og-meta {
  flex-wrap: wrap;
  row-gap: 4px;
  /* THE COLUMN CANNOT REACH THE FACTS RAIL. A 98-character credit ran straight
     under "performances" on Red Beans (Alex, 8/7). The credit is a name again,
     which is the real fix, but a container that only holds when its content
     behaves is not a container — this bounds it whatever arrives. */
  max-width: 62ch;
}
/* A separator is not allowed to start a line. When the credit wrapped, the row
   put a bare "·" at the head of line two with nothing to its left. */
body.stagelight .og-meta .sp-meta-sep:first-child { display: none; }

body.stagelight .og-story {
  padding-top: clamp(38px, 5vw, 62px);
  font: 400 clamp(17.5px, 1.5vw, 20px)/1.72 var(--sl-body);
  color: rgba(242, 242, 240, .9);
  text-wrap: pretty;
}
body.stagelight .og-story p { margin: 0 0 1.15em; }
body.stagelight .og-story p:last-child { margin-bottom: 0; }

/* The opening line earns a little extra weight and a tighter measure — the
   first sentence of each of these is doing the work of a lede. No drop cap:
   the titles are already display-scale and a cap would be a second voice. */
body.stagelight .og-story > p:first-child {
  font-size: 1.06em;
  color: var(--sl-ink);
}

/* ---- pull quote ---------------------------------------------------------
   One per entry at most, and only where the data carries one. Set large, in
   the display face, breaking the measure slightly so the eye catches it while
   scrolling. The rule on the left is the only ornament on the page. */
body.stagelight .og-pull {
  margin: clamp(30px, 4vw, 46px) 0;
  padding-left: clamp(18px, 2.4vw, 30px);
  border-left: 2px solid rgba(255, 255, 255, .22);
}
body.stagelight .og-pull p {
  margin: 0;
  font: 600 clamp(23px, 2.9vw, 33px)/1.24 var(--sl-display);
  letter-spacing: -.018em;
  color: var(--sl-ink);
  text-wrap: balance;
}
body.stagelight .og-pull cite {
  display: block;
  margin-top: 12px;
  font: 400 13.5px/1.5 var(--sl-body);
  font-style: normal;
  color: var(--sl-faint);
}

/* ---- attributed quotes --------------------------------------------------
   These are evidence, not decoration, and there can be eight of them. So they
   are set at reading size rather than display size — quieter than the prose
   they support, with the speaker carrying the weight, because on a page whose
   entire claim is that it checked, the name and the citation ARE the content. */
body.stagelight .og-quotes {
  margin: clamp(34px, 4.5vw, 52px) 0 0;
  display: grid;
  gap: 20px;
}
/* PULL QUOTES, NOT CARDS. Alex, 8/7: "your quote sections, or whatever, with a
   little tiny text in the bentos. I don't really get this." Eight identical
   bordered boxes stacked down a page read as a form, not as testimony — the box
   is the loudest thing in each one, and every box is the same, so nothing is
   emphasised and nobody reaches box five. The border and fill come off and a
   single rule on the left does the work: it marks the words as somebody else's
   without building a container around them, which is the same move the site
   already makes on .og-pull. */
body.stagelight .og-quote {
  margin: 0;
  padding: 2px 0 2px 20px;
  background: none;
  border: 0;
  border-left: 2px solid var(--sl-line-strong);
  border-radius: 0;
}
body.stagelight .og-quote p {
  margin: 0;
  font: 400 clamp(16px, 1.3vw, 17.5px)/1.62 var(--sl-body);
  color: var(--sl-ink);
}
/* THE CITATION WAS NOT LEGIBLE AND IT IS HALF THE POINT. At 12.5px in muted
   grey a three-line citation is a texture, not a credit — and on a page whose
   whole standing is that it checked, the name IS content. The speaker now
   carries reading weight; the volume and page number that follow it stay quiet
   (.og-cite-src below), so the eye gets "Bob Weir" and can stop there. */
body.stagelight .og-quote cite {
  display: block;
  margin-top: 10px;
  font-style: normal;
  font: 560 13.5px/1.5 var(--sl-body);
  color: var(--sl-ink);
}
body.stagelight .og-quote cite .og-cite-src {
  font-weight: 400;
  color: var(--sl-faint);
}
body.stagelight .og-quote cite a { color: var(--sl-muted); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(255,255,255,.25); }
body.stagelight .og-quote cite a:hover { color: var(--sl-ink); text-decoration-color: rgba(255,255,255,.6); }

/* A footnote-weight caveat. Sits under the quotes because it is usually about
   them: a disputed credit, a session date three sources disagree on. */
body.stagelight .og-note {
  margin: 26px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--sl-line);
  font: 400 14.5px/1.65 var(--sl-body);
  color: var(--sl-faint);
}

/* ---- the original recording --------------------------------------------
   The lite YouTube facade already exists (renderLiteEmbed / .yt-lite in
   stagelight.css). This only gives it a frame and a caption. The caption
   identifies and orients; it never judges the performance. */
body.stagelight .og-hear {
  margin: clamp(34px, 4.5vw, 52px) 0 0;
  scroll-margin-top: 84px;
}
body.stagelight .og-hear .yt-lite { border-radius: var(--sl-r-md); overflow: hidden; display: block; }
body.stagelight .og-hear figcaption {
  margin-top: 12px;
  font: 400 14px/1.6 var(--sl-body);
  color: var(--sl-faint);
}
body.stagelight .og-hear figcaption b { color: var(--sl-muted); font-weight: 500; }

/* ---- nights -------------------------------------------------------------
   The listen archive's row, rebuilt at article scale: a mono date on the left,
   the place in the middle, the reason this night is listed on the right, and a
   whole-row link when we hold the tape. Same reading order as /listen/, same
   mono-date-first rhythm, so a reader who has used that page already knows how
   to read this one. */
body.stagelight .og-nights {
  margin: clamp(40px, 5vw, 64px) 0 0;
  border-top: 1px solid var(--sl-line-strong);
}
/* FOUR CHILDREN, FOUR COLUMNS. This declared three — date, where, why — while
   the markup emits a fourth, the arrow. So the arrow wrapped onto a second grid
   row and landed in column one, under the date, pointing at nothing, and the
   extra row plus its 18px gap is what made a two-line row stand ~230px tall.
   Alex, 8/7: "why is this so bad looking?" One stray glyph and a doubled row
   height, from a column count. */
body.stagelight .og-night {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr) auto auto;
  gap: 4px 16px;
  align-items: baseline;
  padding: 13px 8px 13px 2px;
  border-bottom: 1px solid var(--sl-line);
  border-radius: var(--sl-r-sm);
  transition: background .16s ease;
}
body.stagelight a.og-night:hover { background: rgba(255, 255, 255, .04); }
body.stagelight .og-night-date {
  font: 500 13px/1.5 var(--sl-mono);
  color: var(--sl-muted);
  letter-spacing: -.01em;
  white-space: nowrap;
}
body.stagelight a.og-night:hover .og-night-date { color: var(--sl-ink); }
body.stagelight .og-night-where { min-width: 0; }
body.stagelight .og-night-venue {
  display: block;
  font: 560 15.5px/1.35 var(--sl-body);
  color: var(--sl-ink);
}
body.stagelight .og-night-city {
  display: block;
  margin-top: 2px;
  font: 400 13px/1.4 var(--sl-body);
  color: var(--sl-faint);
}
/* 22ch broke "back after about 239 shows away" across two lines and left the
   word "away" hanging alone against a ragged right edge, which is what made the
   two ends of the row stop belonging to each other. The longest label the data
   holds is 31 characters, so it gets room to stay on one line. */
body.stagelight .og-night-why {
  justify-self: end;
  text-align: right;
  font: 400 12.5px/1.45 var(--sl-body);
  color: var(--sl-muted);
  max-width: 34ch;
  white-space: nowrap;
}
@media (max-width: 620px) {
  /* On a phone the row stacks, so nowrap would push the label off the edge. */
  body.stagelight .og-night-why { white-space: normal; max-width: none; }
}
/* The arrow only appears on rows that actually go somewhere, so a row with no
   tape never looks like a dead link. */
body.stagelight .og-night-go {
  display: inline-block;
  margin-left: 8px;
  color: var(--sl-faint);
  transition: transform .16s ease, color .16s ease;
}
body.stagelight a.og-night:hover .og-night-go { color: var(--sl-ink); transform: translateX(3px); }

/* ---- research -----------------------------------------------------------
   Every source, at footnote weight. This is the block that makes the page
   checkable, and it is deliberately the quietest thing on it: a reader who
   wants it will find it, and a reader who does not is never taxed by it. */
body.stagelight .og-research {
  margin: clamp(40px, 5vw, 64px) 0 0;
  padding-top: 22px;
  border-top: 1px solid var(--sl-line);
}
body.stagelight .og-research-label {
  display: block;
  margin-bottom: 14px;
  font: 500 11px/1 var(--sl-mono);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sl-faint);
}
body.stagelight .og-research ul { list-style: none; display: grid; gap: 9px; }
body.stagelight .og-research li {
  font: 400 13.5px/1.55 var(--sl-body);
  color: var(--sl-muted);
}
body.stagelight .og-research a { color: var(--sl-muted); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(255,255,255,.2); }
body.stagelight .og-research a:hover { color: var(--sl-ink); text-decoration-color: rgba(255,255,255,.55); }
body.stagelight .og-research-pub { color: var(--sl-faint); }
@media (min-width: 860px) {
  body.stagelight .og-research ul { grid-template-columns: 1fr 1fr; gap: 9px 30px; }
}

/* ---- FAQ ---------------------------------------------------------------- */
body.stagelight .og-faq {
  margin: clamp(40px, 5vw, 64px) 0 0;
  padding-top: 22px;
  border-top: 1px solid var(--sl-line);
  display: grid;
  gap: 20px;
}
body.stagelight .og-faq dt {
  font: 600 16px/1.4 var(--sl-body);
  color: var(--sl-ink);
  margin-bottom: 6px;
}
body.stagelight .og-faq dd {
  margin: 0;
  font: 400 15px/1.65 var(--sl-body);
  color: var(--sl-muted);
}

/* ---- filed under -------------------------------------------------------- */
body.stagelight .og-tags { margin: 30px 0 0; display: flex; flex-wrap: wrap; gap: 8px; }
body.stagelight .og-tag {
  font: 500 12px/1 var(--sl-body);
  color: var(--sl-muted);
  padding: 7px 13px;
  border: 1px solid var(--sl-line-strong);
  border-radius: var(--sl-r-pill);
}
body.stagelight a.og-tag:hover { color: var(--sl-ink); border-color: rgba(255,255,255,.34); }

/* ---- share --------------------------------------------------------------
   One control. It uses the native share sheet where the browser has one and
   copies the link where it does not, which is why the label is a live region:
   the only feedback a copy can give is a word changing. */
body.stagelight .og-share { margin: clamp(34px, 4vw, 48px) 0 0; display: flex; align-items: center; gap: 12px; }
body.stagelight .og-share-btn { position: relative; }
body.stagelight .og-share-btn svg { flex: none; }
body.stagelight .og-share-btn.is-done { background: rgba(255,255,255,.14); }

/* ---- pager --------------------------------------------------------------
   A story page's real next action is another story, so the pager is a
   destination rather than a footnote: the neighbouring title set at heading
   weight, in a card the whole width of the reading column. */
body.stagelight .og-pager {
  grid-column: 2;
  max-width: 68ch;
  min-width: 0;
  margin: clamp(48px, 6vw, 76px) 0 0;
  padding-top: 26px;
  border-top: 1px solid var(--sl-line-strong);
  display: grid;
  gap: 12px;
}
@media (min-width: 720px) {
  body.stagelight .og-pager { grid-template-columns: 1fr 1fr; gap: 16px; }
}
/* THE NEXT SONG SHOWS ITS FACE. Two empty outlined boxes at the foot of a story
   are the least inviting thing on the page; the record cover is what makes the
   next one look worth opening. The picture sits in a ::before under a scrim so
   the title holds at any brightness, and it lifts slightly on hover — the card
   behaves like the artwork it is showing rather than like a button. */
body.stagelight .og-pager-link {
  position: relative;
  display: block;
  overflow: hidden;
  padding: 20px 22px;
  min-height: 92px;
  border: 1px solid var(--sl-line);
  border-radius: var(--sl-r-md);
  background: rgba(255, 255, 255, .025);
  isolation: isolate;
  transition: background .16s ease, border-color .16s ease, transform .16s ease;
}
body.stagelight .og-pager-link.has-art::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image: var(--pager-art);
  background-size: cover;
  background-position: center;
  opacity: .38;
  transform: scale(1.02);
  transition: opacity .2s ease, transform .3s ease;
}
/* The scrim is what keeps the title readable over a bright sleeve. It leans to
   whichever side that card's text sits on, so the words always have the darkest
   part of the gradient under them. */
body.stagelight .og-pager-link.has-art::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(10,10,12,.94) 30%, rgba(10,10,12,.55) 100%);
}
body.stagelight .og-pager-next.has-art::after {
  background: linear-gradient(270deg, rgba(10,10,12,.94) 30%, rgba(10,10,12,.55) 100%);
}
body.stagelight .og-pager-link:hover {
  background: rgba(255, 255, 255, .06);
  border-color: var(--sl-line-strong);
  transform: translateY(-1px);
}
body.stagelight .og-pager-link.has-art:hover::before { opacity: .5; transform: scale(1.05); }
body.stagelight .og-pager-next { text-align: right; }
body.stagelight .og-pager-dir {
  display: block;
  font: 500 11px/1 var(--sl-mono);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sl-faint);
  margin-bottom: 9px;
}
body.stagelight .og-pager-title {
  display: block;
  font: 600 clamp(17px, 1.8vw, 21px)/1.25 var(--sl-display);
  letter-spacing: -.015em;
  color: var(--sl-ink);
}
body.stagelight .og-pager-by {
  display: block;
  margin-top: 4px;
  font: 400 13px/1.4 var(--sl-body);
  color: var(--sl-faint);
}

/* ---- phone --------------------------------------------------------------
   The hero's phone behaviour is song-page.css's and is inherited untouched.
   These are the article's own: the nights row loses its third column (the
   reason moves under the venue, where there is room for it to be a sentence),
   and the reading column gets its margins back. */
@media (max-width: 660px) {
  /* THE DECK NEEDS AN ORDER OR IT GOES TO THE FRONT, and "the front" here means
     above the song title. Below 660 song-page.css sets .sp-hero-mid to
     display:contents, so every line of the hero becomes a direct grid item and
     is placed by `order` alone; anything without one takes order:0 and leads the
     page. The deck shipped without one and rendered the summary above the title,
     ahead of the artwork and the credit.
     song-page.css hit this exact bug on .sp-rarity-line and left the note that
     caught it here. Its scale: title 1, cover 2, meta 3, credit 4, actions 5,
     facts 6. The deck belongs with the credit, under the name of the song. */
  body.stagelight .og-deck { order: 4; margin-top: 18px; }

  /* The shared grid collapses to one column at this width and sets gap:0 for the
     hero, which is right there and wrong here — the article and the rail below it
     need air between them. Source order already puts the story first. */
  body.stagelight .og-body { grid-template-columns: 1fr; gap: 0; padding-bottom: 64px; }
  body.stagelight .og-col { grid-column: 1; max-width: none; }
  body.stagelight .og-pager { grid-column: 1; max-width: none; }
  body.stagelight .og-rail { grid-column: 1; grid-row: auto; }
  body.stagelight .og-rail-in {
    position: static;
    padding-top: 0;
    margin-top: 34px;
    gap: 16px;
  }
  body.stagelight .og-deck { max-width: none; }

  body.stagelight .og-night {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 14px;
    padding: 15px 4px;
  }
  body.stagelight .og-night-date { grid-column: 1; grid-row: 1; }
  body.stagelight .og-night-go { grid-column: 2; grid-row: 1; justify-self: end; margin-left: 0; }
  body.stagelight .og-night-where { grid-column: 1 / -1; grid-row: 2; margin-top: 2px; }
  body.stagelight .og-night-why {
    grid-column: 1 / -1;
    grid-row: 3;
    justify-self: start;
    text-align: left;
    max-width: none;
    margin-top: 5px;
  }

  body.stagelight .og-quote { padding: 17px 18px; }
  body.stagelight .og-pager-next { text-align: left; }
}

@media (prefers-reduced-motion: reduce) {
  body.stagelight .og-pager-link,
  body.stagelight .og-night,
  body.stagelight .og-night-go { transition: none; }
  body.stagelight .og-pager-link:hover { transform: none; }
  body.stagelight a.og-night:hover .og-night-go { transform: none; }
}

/* ---- facts that go somewhere ---------------------------------------------
   The hero's three figures are links now (see renderStoryOriginPage), so they
   have to say so. Quietly: this rail is reference, not navigation, and a row of
   underlined blue would shout over the story. Hover lifts the number and the
   mark the way the notable-performance rows behave, so the two lists on the
   page answer a cursor the same way. */
body.stagelight a.sp-fact-link {
  text-decoration: none;
  color: inherit;
  border-radius: var(--sl-r-sm);
  transition: background .16s ease;
}
/* NO CHEVRONS. They were added on the argument that a link should look like one
   before the cursor arrives, and on a phone there is no hover at all — a fair
   argument that produced a worse strip. Alex: "remove the stupid arrows i didn't
   ask fro that."
   They also told a half-truth: only three of the four facts are links, so the
   column read as a ragged stack of three arrows and one blank. The hover
   background stays and is the affordance; the facts are a quiet strip beside a
   story, not a menu. Do not reintroduce a per-row marker without him. */
body.stagelight a.sp-fact-link:hover { background: rgba(255, 255, 255, .05); }
body.stagelight a.sp-fact-link:hover strong { color: var(--sl-ink); }
body.stagelight a.sp-fact-link:focus-visible {
  outline: 2px solid var(--sl-line-strong);
  outline-offset: 3px;
}

/* ---- Burnthday's picks, in the rail --------------------------------------
   Alex, 8/8: "is this styled like shit? line and then burnthday's picks? Design
   it dude like you work at Webflow."
   He is right about the specific fault. A full-width rule followed by a shouted
   all-caps label is the laziest section header there is: the rule announces a
   division the list has not earned, then the label shouts over the two rows it
   introduces. It also floated the whole thing in dead space, so it read as
   leftover rather than designed.
   WHAT IT IS NOW: one object. The block sits on a faint panel so the rows
   belong to each other and to the heading; the heading is small, sentence-case
   and sits INSIDE that panel rather than above a rule; and the play control
   stays invisible until the row is hovered, the way a track list does — the
   artwork already tells you it is playable, so a permanent grey disc on every
   row is noise. */
body.stagelight .og-picks {
  display: grid;
  gap: 1px;
  width: 100%;
  padding: 12px 10px 10px;
  margin-left: -10px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .035);
  border: 1px solid var(--sl-line);
}
body.stagelight .og-picks-h {
  margin: 0 0 8px 2px;
  font: 560 12px/1.2 var(--sl-body);
  letter-spacing: .01em;
  text-transform: none;
  color: var(--sl-muted);
}
body.stagelight .og-pick-wrap { position: relative; }
body.stagelight .og-pick {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) 22px;
  align-items: center;
  gap: 10px;
  padding: 6px;
  text-decoration: none;
  color: inherit;
  border-radius: 8px;
  transition: background .16s ease;
}
/* A ROW THAT PLAYS IS A <button>, so it needs the browser's button chrome taken
   off before it looks like the link it sits beside — no grey face, no border,
   no centred 13px system font, and full width because a button shrink-wraps its
   content where an anchor filled the column. Same grid, same padding, same
   hover: the two kinds of row must be indistinguishable. */
body.stagelight button.og-pick {
  width: 100%;
  background: none;
  border: 0;
  margin: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
body.stagelight a.og-pick:hover,
body.stagelight button.og-pick:hover { background: rgba(255, 255, 255, .07); }
body.stagelight button.og-pick.is-playing .og-pick-play { color: var(--sl-ink); }
body.stagelight .og-pick-art {
  width: 40px; height: 40px;
  border-radius: 3px;
  object-fit: cover;
  background: rgba(255, 255, 255, .05);
  box-shadow: 0 1px 5px rgba(0,0,0,.5);
}
body.stagelight .og-pick-art-none { display: block; border: 1px solid var(--sl-line); }
body.stagelight .og-pick-text { min-width: 0; display: grid; gap: 1px; }
body.stagelight .og-pick-date {
  font: 560 13px/1.35 var(--sl-body);
  color: var(--sl-ink);
  letter-spacing: -.005em;
  white-space: nowrap;
}
body.stagelight .og-pick-venue {
  font: 400 11.5px/1.35 var(--sl-body);
  color: var(--sl-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.stagelight a.og-pick:hover .og-pick-venue { color: var(--sl-muted); }
/* HIDDEN UNTIL WANTED. The artwork already says "this is a recording"; a grey
   disc parked on every row just adds furniture. It appears on hover and on
   keyboard focus, so it is never unreachable. */
body.stagelight .og-pick-play {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: #f4f0e8;
  color: #111;
  opacity: 0;
  transform: scale(.85);
  transition: opacity .16s ease, transform .16s ease;
}
body.stagelight a.og-pick:hover .og-pick-play,
body.stagelight a.og-pick:focus-visible .og-pick-play { opacity: 1; transform: scale(1); }
body.stagelight a.og-pick:focus-visible { outline: 2px solid var(--sl-line-strong); outline-offset: 2px; }
body.stagelight .og-pick-dead { opacity: .6; }
body.stagelight .og-pick-yt {
  display: inline-block;
  margin: 0 0 6px 56px;
  font: 500 10px/1 var(--sl-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--sl-faint);
  text-decoration: none;
  border-bottom: 1px solid var(--sl-line);
}
body.stagelight .og-pick-yt:hover { color: var(--sl-ink); border-bottom-color: var(--sl-line-strong); }

/* ---- by the numbers ------------------------------------------------------
   Carried over from the Blogger-era layout, which had it and this one did not.
   Analysis, not identity — it sits after the story because it rewards a reader
   who is already in, where the hero strip has to work at a glance.
   Set as label/value pairs on the site's own line rule rather than a boxed
   table: the notable-performance rows above use exactly this shape, so the two
   scannable blocks on the page read as one family. */
body.stagelight .og-numbers {
  margin: clamp(34px, 4.5vw, 52px) 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--sl-line-strong);
}
body.stagelight .og-numbers-h {
  margin: 0 0 10px;
  font: 600 11px/1.2 var(--sl-mono);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sl-muted);
}
body.stagelight .og-numbers dl { margin: 0; display: grid; gap: 0; }
body.stagelight .og-numbers div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: baseline;
  padding: 11px 2px;
  border-bottom: 1px solid var(--sl-line);
}
body.stagelight .og-numbers dt {
  font: 400 12.5px/1.5 var(--sl-mono);
  letter-spacing: .02em;
  color: var(--sl-faint);
  text-transform: lowercase;
}
body.stagelight .og-numbers dd {
  margin: 0;
  text-align: right;
  font: 560 14px/1.45 var(--sl-body);
  color: var(--sl-ink);
}

/* The receipt: back to the post this page came from. Footnote weight — it is
   provenance, not a call to action. */
body.stagelight .og-sourcepost {
  margin: clamp(28px, 3.5vw, 40px) 0 0;
  font: 400 12px/1.5 var(--sl-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
}
body.stagelight .og-sourcepost a { color: var(--sl-faint); text-decoration: none; border-bottom: 1px solid var(--sl-line); }
body.stagelight .og-sourcepost a:hover { color: var(--sl-ink); border-bottom-color: var(--sl-line-strong); }

/* A page with no story still needs its top edge. Deliberately NOT named
   og-story: a gate classifies pages by that class, and an empty story block
   wearing the name made 52 pages read as a different layout. */
body.stagelight .og-nostory { padding-top: clamp(38px, 5vw, 62px); }

/* ---- related origins -----------------------------------------------------
   Hand-made connections carried by 47 of the short entries — same writer, same
   era, same story. The "why" is the value: "Jerry Joseph" beside Chainsaw City
   says what the link IS, which no automatic related-songs list can do, so it
   reads as a caption under the title rather than being dropped. */
body.stagelight .og-related {
  margin: clamp(34px, 4.5vw, 52px) 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--sl-line-strong);
}
body.stagelight .og-related-h {
  margin: 0 0 12px;
  font: 600 11px/1.2 var(--sl-mono);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sl-muted);
}
body.stagelight .og-related-in { display: grid; gap: 2px; }
body.stagelight .og-rel {
  display: grid;
  gap: 2px;
  padding: 10px 8px 10px 2px;
  border-bottom: 1px solid var(--sl-line);
  border-radius: var(--sl-r-sm);
  text-decoration: none;
  transition: background .16s ease;
}
body.stagelight .og-rel:hover { background: rgba(255, 255, 255, .04); }
body.stagelight .og-rel-title { font: 560 15px/1.35 var(--sl-body); color: var(--sl-ink); }
body.stagelight .og-rel-why { font: 400 12.5px/1.4 var(--sl-body); color: var(--sl-faint); }
@media (min-width: 760px) {
  body.stagelight .og-related-in { grid-template-columns: 1fr 1fr; gap: 2px 26px; }
}


/* Provenance: where the writing came from, above the writing. It is not a
   heading and not body text — italic, small, and separated by a rule, the way
   a source note sits above a reprinted letter. */
body.stagelight .og-provenance {
  margin: clamp(38px, 5vw, 62px) 0 -6px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--sl-line);
  font: 400 13px/1.55 var(--sl-body);
  color: var(--sl-faint);
}
body.stagelight .og-provenance em { font-style: italic; color: var(--sl-muted); }
body.stagelight .og-provenance a { color: var(--sl-faint); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(255,255,255,.2); }
body.stagelight .og-provenance a:hover { color: var(--sl-ink); text-decoration-color: rgba(255,255,255,.55); }
/* The story follows a source note directly, so it does not also pay the top
   padding it uses when it opens the column. */
body.stagelight .og-provenance + .og-story { padding-top: 22px; }

/* ---- WATCH, IN THE RAIL ---------------------------------------------------
   Two placements for one component. A video that IS the story sits inline in
   the story (og-hear). A video that is simply a good performance sits here,
   under his picks, because that is what it is: another way to hear the night.
   Same card vocabulary as .og-picks — the panel, the hairline, the 12px
   sentence-case heading — so the rail reads as one column of his choices
   rather than two competing widgets. */
body.stagelight .og-watch {
  width: 100%;
  margin: 14px 0 0;
  padding: 12px 10px 10px;
  margin-left: -10px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .035);
  border: 1px solid var(--sl-line);
}
body.stagelight .og-watch-h {
  margin: 0 0 8px 2px;
  font: 560 12px/1.2 var(--sl-body);
  letter-spacing: .01em;
  text-transform: none;
  color: var(--sl-muted);
}
/* The poster frame reserves its own box before the image arrives, so the rail
   does not jump when it loads — the layout-shift complaint on /listen/ was
   exactly this, and it is cheaper to not cause it than to fix it later. */
body.stagelight .og-watch-embed {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 8px;
  overflow: hidden;
  background: rgba(0, 0, 0, .45);
}
body.stagelight .og-watch-embed > * { width: 100%; height: 100%; }
body.stagelight .og-watch-cap {
  margin: 8px 2px 0;
  font: 400 12px/1.45 var(--sl-body);
  color: var(--sl-faint);
}

/* ---- SOURCES --------------------------------------------------------------
   Was one all-caps line reading ORIGINAL FACEBOOK POST, hanging on its own
   under the story. Alex, twice: "we would probably put all of the source links
   here... Probably not all caps either."
   A list, sentence case, at the foot of the reading column where a receipt
   belongs — quiet enough not to compete with the story, present enough to be
   the answer to "says who". */
body.stagelight .og-sources {
  margin: clamp(28px, 3.5vw, 40px) 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--sl-line);
}
body.stagelight .og-sources-h {
  margin: 0;
  font: 560 12px/1.2 var(--sl-body);
  letter-spacing: .01em;
  text-transform: none;
  color: var(--sl-muted);
}
/* IN LINE. The label and every source share one baseline and wrap as a row,
   so three short facts take one line instead of six. Separated by the site's
   own middot, the same divider the hero credit uses. */
body.stagelight .og-sources {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
}
body.stagelight .og-source-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  min-width: 0;
}
body.stagelight .og-source-list li {
  font: 400 13.5px/1.5 var(--sl-body);
  color: var(--sl-faint);
  position: relative;
}
/* The divider belongs BETWEEN items, so it is drawn by every li after the
   first — never trailing the last one, which is the classic separator bug. */
body.stagelight .og-source-list li + li::before {
  content: "·";
  position: absolute;
  left: -9px;
  color: var(--sl-line-strong);
}
body.stagelight .og-source-list a {
  color: var(--sl-muted);
  text-decoration: none;
  border-bottom: 1px solid var(--sl-line);
}
body.stagelight .og-source-list a:hover {
  color: var(--sl-ink);
  border-bottom-color: var(--sl-line-strong);
}

/* ---- PHONE: THE RAIL PANELS SIT ON THE PAGE'S OWN GUTTER ------------------
   THIS BLOCK IS LAST IN THE FILE ON PURPOSE. It was first written inside the
   @media (max-width:660px) section higher up and did nothing, because both
   .og-picks and .og-watch are DEFINED BELOW that section — same specificity,
   later wins, so the desktop rule kept overriding the phone one. Measured
   before and after rather than assumed: 6px/26px before, 16px/16px after.

   MEASURED at 390px: the hero, the story column and the rail all hold a 16px
   gutter, and the picks panel sat at left 6 / right 26 — six pixels off the
   screen edge on one side, twenty-six on the other. Lopsided, and tight enough
   to read as a mistake.
   The cause is a DESKTOP trick doing the wrong job on a phone: the panel pulls
   itself 10px left so its inner padding cancels and the rows optically align
   with the rail's edge. Right in a 264px rail beside a story; wrong when the
   rail IS the page. */
@media (max-width: 660px) {
  body.stagelight .og-picks,
  body.stagelight .og-watch {
    margin-left: 0;
    padding-left: 12px;
    padding-right: 12px;
  }
  /* The 40px thumbnail and 22px chevron are fixed, so only the middle column
     gives — this keeps the venue line from clipping mid-word at 390px. */
  body.stagelight .og-pick { padding: 8px 4px; gap: 12px; }
  /* Touch target: a pick is the primary action in this panel and was 40px tall. */
  body.stagelight .og-pick { min-height: 44px; }
}

/* ---- PHONE TOUCH TARGET ON THE SHARE CONTROL -----------------------------
   Measured across all 105 origin pages at 390px: the only thing left under a
   finger-sized target was this one, at 38px against the 44px minimum. The pick
   rows and the pager already clear it.
   Raised here rather than on .sc-chip itself, which is a site-wide component —
   this file is loaded by the origin pages and nothing else, so no page Alex has
   already signed off changes. The chip keeps its own padding and type; only the
   box it sits in grows, so it looks identical and is easier to hit. */
@media (max-width: 660px) {
  body.stagelight .og-share-btn {
    min-height: 44px;
    padding-top: 0;
    padding-bottom: 0;
  }
}

/* ---- A PASTED URL MUST NOT SET THE WIDTH OF THE PAGE ----------------------
   Eleven of Alex's forty posts quote their source as a raw address, and some
   run long: swampland.com/articles/view/title:true_to_my_nature_daniel_hutchens…
   is 120 characters with nothing a browser may break on. A word wider than the
   screen cannot be laid out at 390px, so the phone widens the layout viewport
   to fit it — and the whole page renders zoomed out, every other element
   shrinking to accommodate one link.

   MEASURED, which is how it was found: a sweep of all 105 pages could not get
   these eleven to report a 390px viewport no matter how long it waited, while
   the other 94 settled immediately. The discriminator is exact — their longest
   unbroken string is 58-120 characters; every page that behaves has 12-21.

   `anywhere` rather than `break-word` because only `anywhere` lets the long
   token affect the intrinsic minimum width, which is the actual thing forcing
   the viewport open. Applied to the prose and the sources, not globally: this
   is about pasted addresses, and ordinary words should keep breaking on their
   own terms. */
body.stagelight .og-story,
body.stagelight .og-story a,
body.stagelight .og-source-list,
body.stagelight .og-source-list a {
  overflow-wrap: anywhere;
}

/* ---- THE HERO'S VERTICAL BALANCE -----------------------------------------
   Alex: "something is off bc the padding looks larger on the top but it is
   centered based on the third row."
   He read it exactly right. The shared hero pads 60px above and 44px below and
   bottom-aligns its columns, so the band carried 16px more air at the top than
   the bottom while the eye measured the gap against the fact strip's rows. On
   the song page that imbalance is invisible because a 264px square fills the
   left column; here the picture is shorter and the slack is on show.
   Equal above and below, so the block sits where it looks like it sits. */
body.stagelight .sp-hero .sp-hero-in {
  padding-top: clamp(40px, 4vw, 56px);
  padding-bottom: clamp(40px, 4vw, 56px);
}

/* ---- THE RAIL IS ONE GROUP, NOT THREE ISLANDS -----------------------------
   LAST IN THE FILE ON PURPOSE, for the second time today: .og-share carries its
   own `margin: clamp(34px,4vw,48px) 0 0` and is DEFINED BELOW the rail block,
   so an override written up there lost on source order and did nothing. The
   same trap that made the phone gutter fix silently no-op.

   Share carried 48px above it and the picks panel another 84px, which spread
   three small blocks down an otherwise empty column — Alex: "share and the
   listen links and youtube need to be close together." The grid's 10px gap is
   the only spacing between them now, and the group starts on the story's own
   first line. */
body.stagelight .og-rail-in > .og-share,
body.stagelight .og-rail-in > .og-picks,
body.stagelight .og-rail-in > .og-watch {
  margin-top: 0;
  margin-bottom: 0;
}
/* DESKTOP ONLY. Written unscoped, this sat after the phone block and undid the
   16px gutter fix for the third time tonight — the panels went back to 6px from
   one screen edge and 26px from the other. The -10px pull is an optical
   alignment for a 264px rail beside a story; on a phone the rail IS the page
   and the pull is simply wrong, so it is fenced to the width it belongs to
   rather than left to win a source-order race. */
@media (min-width: 661px) {
  body.stagelight .og-rail-in > .og-picks,
  body.stagelight .og-rail-in > .og-watch { margin-left: -10px; }
}
