/* EIGHT ROOMS — the cinema layer.
   Added on top of the companion app, never instead of it. Every variable used here is
   one the original page already declared, so the two halves cannot drift apart:
   --night --panel --panel-2 --plaster --ash --lamp --cold --walnut --line.

   The house is dark and lit in one place at a time. That is the whole design rule:
   a loop is a room with the light on, and the type stands in the dark next to it. */

/* ------------------------------------------------------------------ chrome ------ */

.topnav {
  position: sticky; top: 0; z-index: 40;
  background: rgba(14, 20, 23, .93);
  backdrop-filter: blur(9px);
  border-bottom: 1px solid var(--line);
}
.topnav .wrap { display: flex; align-items: center; gap: 6px; padding: 0 24px; min-height: 52px; flex-wrap: wrap }
.topnav .brand {
  font-family: "Fraunces", Georgia, serif; font-size: .98rem; font-weight: 600;
  letter-spacing: .01em; color: var(--plaster); margin-right: 12px; white-space: nowrap;
}
.topnav .brand em { font-style: italic; color: var(--lamp) }
.topnav a {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: .66rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ash); text-decoration: none; padding: 8px 9px; border-bottom: 2px solid transparent;
}
.topnav a:hover, .topnav a:focus-visible { color: var(--plaster) }
.topnav a[aria-current="true"] { color: var(--lamp); border-bottom-color: var(--lamp) }
.topnav .spacer { flex: 1 }
.motion-btn {
  background: none; border: 1px solid var(--line); color: var(--ash);
  font-family: "JetBrains Mono", monospace; font-size: .6rem; letter-spacing: .12em;
  text-transform: uppercase; padding: 6px 10px; cursor: pointer; white-space: nowrap;
}
.motion-btn:hover { color: var(--plaster); border-color: var(--cold) }
.motion-btn:focus-visible, .topnav a:focus-visible { outline: 2px solid var(--lamp); outline-offset: 2px }

/* ------------------------------------------------------------------- loops ------ */
/* One component for every moving image on the page. The media sits under a two-stop
   scrim: a flat wash to hold the whole frame down, plus a bottom-weighted gradient
   where the type actually sits. Measured on the glyph rects, not on the box. */

.loop { position: relative; overflow: hidden; background: var(--night) }
.loop > video, .loop > img.poster {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.loop > video { opacity: 0; transition: opacity .9s ease }
.loop > video.ready { opacity: 1 }
.loop::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  /* Bottom-weighted, because that is where the type is. The 38% stop was .55 and left
     the gold kicker measuring 4.51:1 over the storm band — passing, but on a MOVING
     ground a passing sample is not a passing floor. */
  background:
    linear-gradient(to top, rgba(14,20,23,.95) 0%, rgba(14,20,23,.72) 38%, rgba(14,20,23,.34) 72%, rgba(14,20,23,.48) 100%);
}
.loop.plain::after {
  background: linear-gradient(to top, rgba(14,20,23,.55), rgba(14,20,23,.28));
}
.loop > .loop-body { position: relative; z-index: 2 }

/* the hero, behind the hall */
.hall { position: relative; overflow: hidden }
.hall > .loop {
  position: absolute; inset: 0; z-index: 0;
}
.hall > .wrap { position: relative; z-index: 2 }
.hall::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--line); z-index: 3;
}

/* A full-bleed band between sections. The loop is positioned, NOT laid out as a flex
   child: as a flex item it sized itself to the width of the sentence sitting on it and
   the picture came out a box in the corner of an empty band. */
.band { position: relative; min-height: 62vh; border-bottom: 1px solid var(--line) }
.band > .loop { position: absolute; inset: 0 }
.band > .loop > .loop-body { position: absolute; left: 0; right: 0; bottom: 0; padding: 0 0 46px }
.band .wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px }
/* Every run over a band carries its own shadow. A scrim alone cannot hold a fixed ratio
   when the ground underneath it is MOVING — the gold kicker measured 6.3:1 over the
   drive and 4.28:1 over the storm, from the same token. The shadow travels with the
   glyphs, so the floor holds whatever the weather does. */
.band .kicker, .band .line, .band .src { text-shadow: 0 1px 4px rgba(14, 20, 23, .92) }
.band .kicker {
  font-family: "JetBrains Mono", monospace; font-size: .66rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--lamp); margin-bottom: 12px;
}
.band .line {
  font-family: "Fraunces", Georgia, serif; font-weight: 400; font-variation-settings: "opsz" 100, "wght" 400;
  font-size: clamp(1.35rem, 3.1vw, 2.35rem); line-height: 1.24; color: #fff;
  max-width: 22ch; text-wrap: balance; margin: 0;
}
.band .line.wide { max-width: 30ch }
/* #93A5A2 was the obvious muted choice and measured 4.0:1 and 4.37:1 over two of the
   four bands — under the 4.5:1 body-text floor, at 10px, on moving ground. Measured on
   the glyph rects, not guessed from the token. */
.band .src {
  margin-top: 14px; font-family: "JetBrains Mono", monospace; font-size: .62rem;
  letter-spacing: .12em; text-transform: uppercase; color: #C6D2CF;
}

/* The ninth door, fixed. Her `.rm text` rule sets the plan's label type at 8.5px, but
   the ninth door is deliberately NOT a `.rm` — it has no room behind it — so its three
   labels fell back to the SVG default of 16px and ran straight out of the dashed box and
   off the side of the plan. This is a defect in the drawing, not a matter of taste, so
   it is corrected rather than reported. Two classes deep, to outrank her `.ninth text`. */
.plan .ninth text {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 8.5px; letter-spacing: .1em; text-transform: uppercase;
}

/* ------------------------------------------------------ the room, with its loop -- */

/* Bled to the edges of the detail card, which carries 30px of padding. */
.roomloop {
  height: 200px; margin: -30px -30px 26px; border-bottom: 1px solid var(--line);
}
.roomloop .loop-body {
  height: 100%; display: flex; align-items: flex-end; padding: 14px 18px;
}
.roomloop .tag {
  font-family: "JetBrains Mono", monospace; font-size: .62rem; letter-spacing: .14em;
  text-transform: uppercase; color: #B9C7C3;
}

/* ------------------------------------------------------------------ reader ------ */

.readgrid { display: grid; grid-template-columns: 268px minmax(0, 1fr); gap: 34px; margin-top: 34px; align-items: start }
.toc { position: sticky; top: 66px; max-height: calc(100vh - 96px); overflow-y: auto; border: 1px solid var(--line); background: var(--panel) }
.toc .part {
  font-family: "JetBrains Mono", monospace; font-size: .6rem; letter-spacing: .15em;
  text-transform: uppercase; color: var(--cold); padding: 15px 16px 7px; border-top: 1px solid var(--line);
}
.toc .part:first-child { border-top: none }
.toc button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  color: var(--ash); font-family: "Instrument Sans", sans-serif; font-size: .89rem;
  padding: 7px 16px; cursor: pointer; line-height: 1.35; border-left: 2px solid transparent;
}
.toc button:hover { color: var(--plaster); background: var(--panel-2) }
.toc button[aria-current="true"] { color: var(--lamp); border-left-color: var(--lamp); background: var(--panel-2) }
.toc button:focus-visible { outline: 2px solid var(--lamp); outline-offset: -2px }
.toc .n { font-family: "JetBrains Mono", monospace; font-size: .62rem; color: var(--cold); margin-right: 7px }

.reader { border: 1px solid var(--line); background: var(--panel); padding: 34px clamp(20px, 4vw, 52px) 46px; min-height: 60vh }
.reader .ch-part {
  font-family: "JetBrains Mono", monospace; font-size: .62rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--cold); margin-bottom: 10px;
}
.reader h3 { font-family: "Fraunces", serif; font-size: clamp(1.7rem, 3.4vw, 2.5rem); font-variation-settings: "opsz" 120, "wght" 500; margin: 0 0 4px; color: var(--plaster) }
.reader .ch-head { font-family: "JetBrains Mono", monospace; font-size: .66rem; letter-spacing: .16em; text-transform: uppercase; color: var(--lamp); margin-bottom: 12px }
.reader .prose { max-width: var(--measure); font-size: 1.04rem; line-height: 1.72 }
.reader .prose p { margin: 0 0 1.15em }
.reader .prose em { font-style: italic; color: #DDE4E0 }
.reader .prose strong { font-weight: 600; color: #fff }
.reader .prose hr { border: none; border-top: 1px solid var(--line); margin: 2em 0; }
.reader .prose blockquote { margin: 1.4em 0; padding-left: 18px; border-left: 2px solid var(--walnut); color: var(--ash) }
.reader .prose .break { text-align: center; color: var(--cold); letter-spacing: .5em; margin: 1.8em 0 }

.apparatus { margin-top: 40px; border-top: 1px solid var(--line); padding-top: 4px }
.apparatus .mode {
  display: inline-block; margin: 22px 0 6px; padding: 5px 11px; background: var(--panel-2);
  border: 1px solid var(--line); border-left: 2px solid var(--lamp);
  font-family: "JetBrains Mono", monospace; font-size: .63rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--lamp);
}
.apparatus h4 { font-family: "Fraunces", serif; font-size: 1.28rem; font-variation-settings: "opsz" 60, "wght" 500; margin: 8px 0 14px; color: var(--plaster) }
.apparatus .prose { color: #B6C4C0 }

.readnav { display: flex; justify-content: space-between; gap: 14px; margin-top: 40px; border-top: 1px solid var(--line); padding-top: 18px; flex-wrap: wrap }
.readnav button {
  background: none; border: 1px solid var(--line); color: var(--ash);
  font-family: "JetBrains Mono", monospace; font-size: .64rem; letter-spacing: .12em;
  text-transform: uppercase; padding: 10px 15px; cursor: pointer; max-width: 48%; text-align: left;
}
.readnav button:hover:not(:disabled) { color: var(--lamp); border-color: var(--lamp) }
.readnav button:disabled { opacity: .32; cursor: default }
.readnav button:focus-visible { outline: 2px solid var(--lamp); outline-offset: 2px }

/* ------------------------------------------------------------------- songs ------ */

.songgrid { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 34px }
/* flex with a basis, not auto-fit/minmax — a grid leaves ragged holes on the last row */
.songcard {
  flex: 1 1 262px; min-width: 0; border: 1px solid var(--line); background: var(--panel);
  padding: 20px; text-align: left; cursor: pointer; color: inherit; font: inherit;
  transition: border-color .2s, background .2s;
}
.songcard:hover { border-color: var(--lamp); background: var(--panel-2) }
.songcard:focus-visible { outline: 2px solid var(--lamp); outline-offset: 2px }
.songcard[aria-expanded="true"] { border-color: var(--lamp); background: var(--panel-2) }
.songcard .n { font-family: "JetBrains Mono", monospace; font-size: .62rem; letter-spacing: .14em; color: var(--cold) }
.songcard h3 { font-family: "Fraunces", serif; font-size: 1.16rem; font-variation-settings: "opsz" 60, "wght" 600; margin: 7px 0 6px; color: var(--plaster) }
.songcard .style { font-size: .82rem; color: var(--ash); line-height: 1.45 }
.songcard .bpm { margin-top: 10px; font-family: "JetBrains Mono", monospace; font-size: .62rem; letter-spacing: .1em; color: var(--lamp) }

.lyric { margin-top: 26px; border: 1px solid var(--lamp); background: var(--panel); padding: 30px clamp(20px, 4vw, 44px) 36px }
.lyric .close { float: right; background: none; border: 1px solid var(--line); color: var(--ash); font-family: "JetBrains Mono", monospace; font-size: .62rem; letter-spacing: .12em; text-transform: uppercase; padding: 6px 11px; cursor: pointer }
.lyric .close:hover { color: var(--lamp); border-color: var(--lamp) }
.lyric h3 { font-family: "Fraunces", serif; font-size: clamp(1.5rem, 3vw, 2.1rem); font-variation-settings: "opsz" 100, "wght" 500; margin: 0 0 4px; color: var(--plaster) }
.lyric .meta { font-family: "JetBrains Mono", monospace; font-size: .64rem; letter-spacing: .13em; text-transform: uppercase; color: var(--cold); margin-bottom: 22px }
.lyric .sheet { columns: 2; column-gap: 44px; max-width: 78ch }
.lyric .sheet .part {
  font-family: "JetBrains Mono", monospace; font-size: .62rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--lamp); margin: 18px 0 7px; break-after: avoid;
}
.lyric .sheet .part:first-child { margin-top: 0 }
.lyric .sheet p { margin: 0 0 1em; white-space: pre-wrap; font-family: "Fraunces", serif; font-variation-settings: "opsz" 60, "wght" 350; font-size: 1.02rem; line-height: 1.55; color: var(--plaster); break-inside: avoid }

/* ------------------------------------------------------------------ listen ------ */

.tracklist { margin-top: 32px; border-top: 1px solid var(--line) }
.track { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 18px; align-items: center; padding: 16px 4px; border-bottom: 1px solid var(--line) }
.track .play {
  width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--lamp);
  background: none; color: var(--lamp); cursor: pointer; font-size: .82rem; line-height: 1;
  display: grid; place-items: center; flex: none;
}
.track .play:hover { background: var(--lamp); color: #12191A }
.track .play:focus-visible { outline: 2px solid var(--cold); outline-offset: 2px }
.track .t { font-family: "Fraunces", serif; font-size: 1.06rem; font-variation-settings: "opsz" 60, "wght" 500; color: var(--plaster) }
.track .d { font-size: .85rem; color: var(--ash); margin-top: 3px }
.track .len { font-family: "JetBrains Mono", monospace; font-size: .68rem; color: var(--cold) }
.track.on { background: var(--panel) }
.track.on .t { color: var(--lamp) }

/* ------------------------------------------------------------------ plates ------ */

.plates { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 34px }
.plate { flex: 1 1 320px; min-width: 0; border: 1px solid var(--line); background: var(--panel) }
.plate .loop { height: 210px }
.plate .cap { padding: 14px 16px 16px }
.plate .cap .t { font-family: "Fraunces", serif; font-size: 1.02rem; font-variation-settings: "opsz" 60, "wght" 500; color: var(--plaster) }
.plate .cap .d { font-size: .84rem; color: var(--ash); margin-top: 4px; line-height: 1.45 }

/* ------------------------------------------------------------------- films ------ */

.films, .herofilms { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 34px }
.film { flex: 1 1 380px; min-width: 0; border: 1px solid var(--line); background: var(--panel) }
/* The lead film takes the whole row — it is the two minutes that make the rest legible. */
.film.lead { flex: 1 1 100% }
.film.lead video { max-height: 62vh; object-fit: contain }
.film video { width: 100%; height: auto; display: block; background: #000 }
.film .cap { padding: 15px 18px 18px }
.film .cap .t { font-family: "Fraunces", serif; font-size: 1.12rem; font-variation-settings: "opsz" 60, "wght" 500; color: var(--plaster) }
.film.lead .cap .t { font-size: 1.5rem }
.film .cap .t .len { font-family: "JetBrains Mono", monospace; font-size: .68rem; letter-spacing: .1em; color: var(--cold); margin-left: 8px; vertical-align: middle }
.film .cap .d { font-size: .86rem; color: var(--ash); margin-top: 5px; line-height: 1.5 }

/* ---------------------------------------------------------------- read aloud --- */

.readaloud { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 20px }
.ra-play {
  display: inline-flex; align-items: center; gap: 10px;
  background: none; border: 1px solid var(--lamp); color: var(--lamp);
  font-family: "JetBrains Mono", ui-monospace, monospace; font-size: .68rem;
  letter-spacing: .13em; text-transform: uppercase; padding: 9px 16px; cursor: pointer;
}
.ra-play:hover { background: var(--lamp); color: #12191A }
.ra-play:focus-visible { outline: 2px solid var(--cold); outline-offset: 2px }
.ra-play .ico { font-size: .82rem; line-height: 1 }
.ra-play .len { color: inherit; opacity: .72 }
.readaloud.on .ra-play { background: var(--lamp); color: #12191A }

.ts { max-width: var(--measure) }
.ts summary {
  cursor: pointer; color: var(--cold);
  font-family: "JetBrains Mono", ui-monospace, monospace; font-size: .64rem;
  letter-spacing: .13em; text-transform: uppercase; padding: 4px 0;
}
.ts summary:hover { color: var(--plaster) }
.ts summary:focus-visible { outline: 2px solid var(--lamp); outline-offset: 2px }
.ts p { font-size: .9rem; color: var(--ash); line-height: 1.6; margin: 8px 0 0 }
.film .ts { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 8px }

/* ------------------------------------------------------------------- misc ------- */

.note-src { color: var(--ash); font-size: .88rem; max-width: var(--measure); line-height: 1.6 }
.note-src b { color: var(--plaster) }
.counts { display: flex; flex-wrap: wrap; gap: 26px; margin-top: 26px }
.counts .c .v { font-family: "Fraunces", serif; font-size: 1.9rem; font-variation-settings: "opsz" 100, "wght" 500; color: var(--lamp); line-height: 1 }
.counts .c .k { font-family: "JetBrains Mono", monospace; font-size: .62rem; letter-spacing: .13em; text-transform: uppercase; color: var(--ash); margin-top: 6px }

@media (max-width: 880px) {
  /* Eight links wrapped to three rows made the sticky bar ~100px of permanent chrome on
     a phone. One scrolling row instead, with the brand and the motion toggle pinned to
     the ends so the two things you always need stay put. */
  .topnav .wrap { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; gap: 2px; padding: 0 12px }
  .topnav .wrap::-webkit-scrollbar { display: none }
  .topnav .brand, .topnav .motion-btn { position: sticky; flex: none; background: rgba(14, 20, 23, .96); z-index: 1 }
  .topnav .brand { left: 0; padding-right: 10px; margin-right: 4px }
  .topnav .motion-btn { right: 0 }
  .topnav a { flex: none; white-space: nowrap }
  .topnav .spacer { flex: 1 0 12px }

  .readgrid { grid-template-columns: 1fr }
  .toc { position: static; max-height: 340px }
  .lyric .sheet { columns: 1 }
  .band { min-height: 52vh }
  .roomloop { height: 150px }
}

/* Reduced motion is honoured by pausing every loop and showing its poster — the still
   frame is the same graded image, so nothing disappears. The Motion button in the nav
   overrides it in either direction, because the OS setting is not always the answer for
   this page on this day. */
@media (prefers-reduced-motion: reduce) {
  .loop > video { transition: none }
}
