/* THE VIBE TIMES — the tower's own sheet (crane-hoist BP-2026-08-18-501).
 *
 * Loads after the kit's inline styles and overrides nothing the kit owns
 * except the two geometry facts the horizontal axis needs: a floor is wider
 * than the viewport, and the three world layers pan as one.
 *
 * The paint is 1930s action-comics rendering on a newsroom-with-steampunk
 * set — bold inks, flat blocks, halftone warmth, brass on the machines. It
 * is a STAGED set, deliberately: the moment a real plate lands at
 * assets/rooms/comms/<floor>-plate.png the baker uses it instead and none
 * of this shows. Nothing here is a placeholder — an unlit sign is a sign
 * that is off, and a floor whose machine has not been switched on is still
 * a room.
 */

html, body { overflow: hidden; margin: 0; background: #07090d; }

/* ── THE FOUR-DIRECTION GEOMETRY ─────────────────────────────────────────
   Each floor is 160vw of set behind a 100vw window; tower.js drives
   --vt-pan from 0 to -60vw. The three layers that make up a floor — its
   plate, its props, its crew — carry the SAME transform so they walk
   together. #deckplates and #crewlayer are given the exact box they
   already occupied (#world's own), so becoming a transform containing
   block cannot move a single figure: the kit's ruler is untouched. */
.deckplate { width: 160vw; }
#deckplates, #crewlayer {
  position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  transform: translate3d(var(--vt-pan, 0), 0, 0);
}
.sm-room { transform: translate3d(var(--vt-pan, 0), 0, 0); }
#deckplates, #crewlayer, .vt-set, .vt-ticker { transition: transform .18s linear; }

/* ── THE SET ─────────────────────────────────────────────────────────── */
.vt-set { position: absolute; inset: 0; pointer-events: none;
  font-family: ui-sans-serif, "Helvetica Neue", Arial, sans-serif; }
.vt-set::before { content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 70% at 30% 30%, #FFF2D40E, #0000 70%); }

.vt-prop { position: absolute; height: var(--h, 14%); box-sizing: border-box;
  color: #F2E9D8; font-size: clamp(9px, .78vw, 13px); letter-spacing: .12em;
  text-transform: uppercase; padding: 6px 8px; line-height: 1.35;
  border-radius: 3px; overflow: hidden; }
.vt-prop b { display: block; font-weight: 600; letter-spacing: .04em;
  text-transform: none; margin-top: 5px; font-size: .94em; }
.vt-prop i { display: block; font-style: normal; opacity: .82;
  text-transform: none; letter-spacing: .02em; margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* THE STRUCTURES — boards, walls, screens, shelving: inked panel + brass */
.vt-bigboard, .vt-pinwall, .vt-press, .vt-screen, .vt-shelves, .vt-gallery,
.vt-founders, .vt-partnership, .vt-frontpages, .vt-stacks, .vt-radiobooth,
.vt-alcove, .vt-seats, .vt-booth, .vt-aotd {
  background: linear-gradient(180deg, #0F1319E8, #05070BEE);
  border: 2px solid #C8A15B77; box-shadow: inset 0 0 30px #0009, 0 6px 18px #0007;
}
.vt-bigboard { --h: 34%; border-color: #E8654A99; }
.vt-aotd { --h: 22%; border-color: #E8654A; box-shadow: 0 0 22px #E8654A44; }
.vt-pinwall { --h: 30%; background: #2A2419E8; }
.vt-press { --h: 46%; border-width: 3px;
  background: repeating-linear-gradient(90deg, #1B2622 0 14px, #243029 14px 28px); }
.vt-screen { --h: 34%; background: #0A0A12; border-color: #B9A0E866; }
.vt-shelves { --h: 52%;
  background: repeating-linear-gradient(180deg, #2E2318 0 13%, #4A3826 13% 15%); }
.vt-gallery { --h: 34%; background: #F4F1EA; color: #23201B; border-color: #C8A15B; }
.vt-founders, .vt-partnership { --h: 30%; background: #241809EE; border-color: #C8A15B; }
/* THE GRAY SLAB retired (Tom 2026-09-01 12:59 PM): the painted noticeboard
   IS the front-pages wall — this hotspot sits exactly over it, invisible at
   rest, and hover/focus reveals a brass ring + its edition line. Height
   matches the painted board's own box. */
.vt-frontpages { --h: 26%; opacity: 0; background: none;
  border-color: #C8A15B; box-shadow: 0 0 18px #C8A15B44; color: #F2E9D8;
  transition: opacity .25s ease; cursor: pointer; }
.vt-frontpages:hover, .vt-frontpages:focus { opacity: 1; }
.vt-stacks { --h: 50%;
  background: repeating-linear-gradient(90deg, #171514 0 9px, #221F1C 9px 18px); }
.vt-radiobooth { --h: 40%; background: #1A1420EE; border-color: #E8B54A66; }
.vt-alcove { --h: 40%; background: #0C0B10; border-color: #C8A15B44; }
.vt-seats { --h: 20%; border: none; box-shadow: none;
  background: repeating-linear-gradient(90deg, #1B1622 0 3.4%, #0000 3.4% 5%); }
.vt-booth { --h: 26%; }

/* THE FURNITURE — desks, lecterns, counters: solid slabs, top light */
.vt-editordesk, .vt-typewriter, .vt-lectern, .vt-deskbook, .vt-frontdesk,
.vt-newsstand, .vt-catalog, .vt-armchairs, .vt-stack, .vt-referral,
.vt-plaque, .vt-tank, .vt-copytray {
  background: linear-gradient(180deg, #4A3826, #2A1F14);
  border-top: 2px solid #C8A15BAA; border-radius: 3px 3px 1px 1px;
  box-shadow: 0 8px 16px #0008;
}
.vt-editordesk, .vt-frontdesk { --h: 16%; }
.vt-typewriter, .vt-lectern, .vt-deskbook, .vt-copytray { --h: 11%; }
.vt-newsstand { --h: 20%; background: linear-gradient(180deg, #3A2E1E, #1E1810); }
.vt-catalog { --h: 26%; background: linear-gradient(180deg, #2A2420, #16130F); }
.vt-armchairs { --h: 20%; background: linear-gradient(180deg, #5A2E2A, #33191A);
  border-radius: 10px 10px 2px 2px; }
.vt-stack { --h: 22%; background: repeating-linear-gradient(180deg, #E8E4DA 0 3px, #B9B3A6 3px 5px); }
.vt-referral { --h: 18%; }
.vt-plaque { --h: 14%; background: linear-gradient(180deg, #C8A15B, #8A6C36);
  color: #1B1408; border-top-color: #F2E0B4; }
.vt-tank { --h: 22%; border-radius: 6px; }

/* THE MACHINES + SIGNS — the parts that glow, and the parts that do not */
.vt-teletype, .vt-beacon, .vt-antenna, .vt-klaxon, .vt-onair, .vt-marquee,
.vt-lamp, .vt-morguelamp, .vt-spot, .vt-sparks, .vt-warming, .vt-runsheet {
  border: 2px solid currentColor; background: #0A0C11CC; border-radius: 4px;
  text-align: center;
}
.vt-teletype { --h: 22%; color: #8CEFC0; box-shadow: 0 0 18px #8CEFC033; }
.vt-beacon { --h: 12%; color: #E8654A; border-radius: 50%;
  box-shadow: 0 0 26px #E8654A66; }
.vt-antenna { --h: 26%; color: #6FD3E8; background: #0000; border-width: 0 0 0 3px;
  border-radius: 0; box-shadow: -1px 0 18px #6FD3E855; }
.vt-klaxon { --h: 9%; color: #E8654A; font-size: clamp(8px, .62vw, 11px); }
.vt-onair { --h: 8%; color: #5A4038; background: #14100E; letter-spacing: .3em; }
.vt-marquee { --h: 11%; color: #E8B54A; background: #1A1206E8;
  box-shadow: 0 0 30px #E8B54A2E; }
.vt-lamp, .vt-morguelamp { --h: 10%; color: #E8B54A; border-radius: 50% 50% 3px 3px;
  box-shadow: 0 14px 60px #E8B54A3A; }
.vt-spot { --h: 10%; color: #FFF2D4; border: none;
  background: radial-gradient(60% 100% at 50% 0, #FFF2D43A, #0000 72%); }
.vt-sparks { --h: 30%; color: #6FD3E8; border: none; background: #0000;
  box-shadow: 0 0 40px #6FD3E844; }
.vt-warming { --h: 12%; color: #B9A0E8; font-size: clamp(8px, .6vw, 11px); }
.vt-runsheet { --h: 22%; color: #8CEFC0; text-align: left; }

/* THE AIR — windows, weather, motion, the cat: no frame, all atmosphere */
.vt-window, .vt-rain, .vt-dust, .vt-beam, .vt-stream, .vt-pigeons, .vt-cat,
.vt-tube, .vt-tubein, .vt-tubeout, .vt-mast, .vt-revolve, .vt-sheet {
  border: none; box-shadow: none;
}
.vt-window, .vt-rain { --h: 46%;
  background: linear-gradient(180deg, #0B1420, #16283A),
    repeating-linear-gradient(90deg, #6FD3E81A 0 6%, #0000 6% 12%);
  border: 3px solid #2A3441; }
.vt-rain { border-color: #3A4A5A; }
.vt-dust { --h: 30%; background: radial-gradient(50% 50% at 50% 50%, #C8A15B18, #0000 70%); }
.vt-beam { --h: 40%; background: linear-gradient(100deg, #FFFFFF22, #0000 62%);
  clip-path: polygon(0 0, 100% 26%, 100% 74%, 0 100%); }
.vt-stream { --h: 8%;
  background: repeating-linear-gradient(90deg, #E8E4DA 0 22px, #A8A296 22px 26px); }
.vt-pigeons, .vt-cat { --h: 6%;
  background: radial-gradient(50% 100% at 20% 60%, #E6EDF0AA, #0000 60%),
    radial-gradient(50% 100% at 62% 50%, #E6EDF088, #0000 60%); }
.vt-cat { background: radial-gradient(60% 100% at 50% 70%, #2A2420, #0000 65%); }
.vt-tube, .vt-tubein, .vt-tubeout { --h: 60%;
  background: linear-gradient(90deg, #6FD3E81A, #C8A15B55, #6FD3E81A);
  border-radius: 999px; }
.vt-mast { --h: 34%; background: linear-gradient(180deg, #C8A15B, #6FD3E822); }
.vt-revolve { --h: 40%; border: 3px solid #C8A15B77; border-radius: 999px;
  background: conic-gradient(#0000 0 25%, #C8A15B22 25% 50%, #0000 50% 75%, #C8A15B22 75%); }
.vt-sheet { --h: 8%; background: #E8E4DA; }

/* ── THE WIRE ────────────────────────────────────────────────────────── */
.vt-ticker { width: 160vw; height: 30px; overflow: hidden; display: flex;
  align-items: center; border-top: 1px solid #C8A15B44; border-bottom: 1px solid #C8A15B44;
  background: #0A0C11E8; transform: translate3d(var(--vt-pan, 0), 0, 0); }
.vt-crawl { display: flex; gap: 46px; white-space: nowrap; padding-left: 100%;
  animation: vt-crawl var(--vt-crawl-s, 48s) linear infinite; }  /* the duration follows the strip's length at a reading pace (comms_floors.ticker_html) */
.vt-crawl span { color: #F2E9D8; font-size: 12px; letter-spacing: .06em; }
.vt-crawl span::before { content: "\25C6"; color: #E8654A; margin-right: 12px; }
/* THE RIDE ITEMS (Tom 2026-09-01, Mira's shape): one per other floor,
   woven between headlines — brass, italic, an elevator diamond for a
   bullet; click rides there (spine.js). Distinct at a glance from news. */
.vt-crawl .vt-crawl-floor { color: #C8A15B; font-style: italic; cursor: pointer; }
.vt-crawl .vt-crawl-floor::before { content: "\25B2"; color: #C8A15B; }
.vt-crawl .vt-crawl-floor:hover { color: #E8CE8F; text-shadow: 0 0 8px #C8A15B66; }
@keyframes vt-crawl { to { transform: translateX(-100%); } }
/* THE WIRE AT REST — no bundle, no headlines: the bulbs are simply unlit.
   An object switched off, never a caption about missing data. */
.vt-ticker.is-dark { background: #0A0C11B8; border-color: #2A3441; gap: 26px;
  justify-content: center; }
.vt-ticker.is-dark i { width: 6px; height: 6px; border-radius: 50%;
  background: #2A3441; margin: 0 13px; }

/* ── THE ROOM'S OWN STRIP ─────────────────────────────────────────────
   BOTTOM, not top: the ship's serve-time chrome (handlers/room_chrome.py)
   floats its BACK TO THE BRIDGE and SHIP MAP badges at top-left, z-index
   99999, on every /rooms/ page. A room bar at the top sits under them and
   the two back-links stack — visible on the arcade today. The tower gives
   that corner to the ship and keeps the press strip along the floor. */
.vt-hud { position: fixed; left: 0; right: 0; bottom: 0; z-index: 70; height: 40px;
  display: flex; align-items: center; gap: 18px; padding: 0 16px;
  background: #05070Bd8; border-top: 1px solid #C8A15B33;
  font-family: ui-sans-serif, "Helvetica Neue", Arial, sans-serif; font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase; color: #C8A15B; }
.vt-hud .home { color: #6FD3E8; text-decoration: none; }
.vt-hud .home:hover { text-decoration: underline; }
.vt-hud .vt-name { color: #F2E9D8; letter-spacing: .3em; font-weight: 600; }
.vt-hud .vt-hint { margin-left: auto; color: #8A8578; letter-spacing: .1em; }

/* ── NIGHT: its own mood, not a dimmer on the day ────────────────────── */
html[data-edition-state="night"] .vt-set::before {
  background: radial-gradient(120% 70% at 70% 20%, #6FD3E812, #0000 66%); }
html[data-edition-state="night"] .vt-window,
html[data-edition-state="night"] .vt-rain {
  background: linear-gradient(180deg, #05080E, #0A1420),
    repeating-linear-gradient(90deg, #E8B54A3A 0 6%, #0000 6% 12%); }
html[data-edition-state="night"] .vt-lamp,
html[data-edition-state="night"] .vt-morguelamp { box-shadow: 0 16px 90px #E8B54A66; }
html[data-edition-state="night"] .vt-beacon { box-shadow: 0 0 44px #E8654AAA; }
html[data-edition-state="night"] .vt-marquee { color: #8A7A4A; box-shadow: none; }
/* the presses are visibly at rest overnight — never dead air, just still */
html[data-edition-state="night"] .vt-stream { opacity: .35; }
html[data-edition-state="night"] .vt-ticker { background: #05070BE8; }
html[data-edition-state="night"] .vt-crawl span { color: #C8C0AE; }

/* ── STOP THE PRESSES — the once-daily flourish ──────────────────────── */
html.vt-pressrun .vt-klaxon { animation: vt-klaxon 1.1s steps(1) 6; }
html.vt-pressrun .vt-press { border-color: #E8654A; }
/* paint + opacity only — never a layout property, and never an animated
   box-shadow on a repeating cycle (the craft rule, and the cheap way) */
@keyframes vt-klaxon {
  0%, 49% { background: #E8654A; color: #14100E; opacity: 1; }
  50%, 100% { background: #0A0C11CC; color: #E8654A; opacity: .82; }
}

@media (prefers-reduced-motion: reduce) {
  /* motion goes; the floor, the wire and the run all stay reachable */
  #deckplates, #crewlayer, .vt-set, .vt-ticker { transition: none; }
  .vt-crawl { animation: none; padding-left: 0; }
  html.vt-pressrun .vt-klaxon { animation: none; background: #E8654A; color: #14100E; }
}

/* ── THE REVEAL ────────────────────────────────────────────────────────
   A data prop is a HOTSPOT ON THE PAINTED ART until it is asked for.
   Tom, 2026-08-19, on the first installed newsroom plate: "there is all
   this stuff in the way... i only want display windows up when i click on
   a crew member or if we have a piece of art that opens up a window like
   we have for the arcade."

   Closed, a prop paints NOTHING — the plate's own art shows through, and
   only a brass hairline on hover or keyboard focus says there is something
   here. Opened, it is exactly the panel it always was: the STRUCTURES,
   FURNITURE and MACHINES rules above are untouched, and this only gates
   when they are seen. Nothing leaves the DOM, so the reader's data-story
   mounts and any assistive reading of the panel survive a closed state. */
/* POINTER EVENTS BACK ON. `.vt-set` suppresses them for the whole set —
   correct while props were pure display, fatal the moment they became
   hotspots, because the click handlers in tower.js could never fire and no
   panel could ever open. Restored here, on the props alone: the set's own
   ::before wash and everything else in it stay untouchable, so a click that
   is not on a prop still reaches the crew sprite underneath. Props sit at
   z-index 1 with the furniture; crew are at 10-54 and keep winning. */
.vt-prop { pointer-events: auto; }
.vt-prop:not(.is-open) {
  background: none; border-color: transparent; box-shadow: none;
  color: transparent; cursor: pointer;
}
.vt-prop:not(.is-open) > * { display: none; }
.vt-prop:not(.is-open):hover,
.vt-prop:not(.is-open):focus-visible {
  border-color: #C8A15B77; box-shadow: 0 0 14px #C8A15B26;
}
/* an opened panel sits above the ticker (z 4) and the ambient layer (z 2) */
.vt-prop.is-open { z-index: 6; }

/* ── THE MOMENT — a scene, not a paragraph (newsroom, 2026-08-29) ────────
   swallow-arrive mounts four hidden moments inside the newsroom set and a
   client chooser shows ONE per visit. Unpainted, the chosen one fell into
   block flow across the top of the plate — Tom's "all that strange text".
   A moment is a scene card on the floor: ABSOLUTE (the set is a transform
   containing block, so fixed would be swallowed), above the furniture and
   under the crew, panning with the floor it belongs to. Pinned by
   tests/test_comms_moments_scene.py. */
/* top 12%, not 3% (Tom 2026-09-01 1:28 PM, "what's that box"): the ticker
   owns the 8vh band — the scene card starts below the crawling wire. */
.vt-moment-mount { position: absolute; left: 42%; top: 12%; width: 38%;
  max-height: 26%; overflow: hidden; z-index: 5; box-sizing: border-box;
  padding: 8px 12px 10px; color: #1B1A17;
  background: linear-gradient(180deg, #E8E4DAF2, #D9D3C4F2);
  border: 2px solid #C8A15B99; border-radius: 3px; box-shadow: 0 6px 18px #0007;
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(10px, .82vw, 14px); line-height: 1.4; }
.vt-moment-mount::before { content: "OVERHEARD \00b7 " attr(data-moment-id);
  display: block; font-family: ui-sans-serif, "Helvetica Neue", Arial, sans-serif;
  font-size: .72em; letter-spacing: .14em; text-transform: uppercase; color: #7A6A4A;
  border-bottom: 1px solid #C8A15B66; margin-bottom: 6px; padding-bottom: 4px; }
.vt-moment { display: block; }
.vt-moment p { margin: 0 0 5px; }
.vt-moment i { display: block; font-style: normal; margin: 0 0 4px; }  /* desk-read items: one headline per line */
.vt-moment b { font-weight: 700; color: #3A2A10; text-transform: capitalize; }
.vt-moment-desk-read, .vt-moment-reporters-brief,
.vt-moment-rooftop-break, .vt-moment-presses-running { display: block; }

/* SMALL SCREENS (Tom 2026-09-06 2:11 PM: "on mobile view our people stand in the same
   spot as each other"). The engine sizes a figure in pixels and places it by a
   percentage of the width, so on a phone in landscape two figures 178px apart were
   each 238px wide and stood on each other. Scale every figure about its FEET as the
   screen shrinks; the sprite's own inline transform is the engine's and untouched. */
#crewlayer .crew { transform-origin: 50% 100%; }
@media (max-width: 1599px) { #crewlayer .crew { transform: scale(0.85); } }
@media (max-width: 1199px) { #crewlayer .crew { transform: scale(0.7); } }
@media (max-width: 899px), (max-height: 640px) { #crewlayer .crew { transform: scale(0.5); } }
