@font-face {
  font-family: "Custom Dot Monda";
  /* WOFF2 first and under a NEW name: this stylesheet is content-hashed, so a changed
     font reaches every browser by arriving at a URL none of them has cached. The OTF
     stays as the fallback. A future font change must ship under a new file name. */
  src: url("/static/custom-dot-monda.woff2") format("woff2"),
       url("/static/custom-dot-monda.otf") format("opentype");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

:root {
  --gold: #ff9b12;
  --ink: #f4f3f1;
  /* D-64 (ruled 2026-09-09): one step brighter than the .74/.56 that shipped; 11.6:1 / 6.7:1 on the dome. */
  --muted: rgba(244, 243, 241, 0.80);
  --faint: rgba(244, 243, 241, 0.60);
  --dome: #060607;
  --line: rgba(244, 243, 241, 0.15);
  --plate: #0d0c0f;
}

/* ── ONE WEIGHT, AND NO INVENTED ONE ──────────────────────────────────────────
   Ethan, 2026-09-01: "we hired a designer years ago to make concertdome monda and
   they never made a bold. so we don't have one to use and I don't want to render a
   fake one."

   Custom Dot Monda holds a single weight. Asking for 700 does not produce a bold —
   it makes the browser smear the normal letters sideways, closing the counters on a
   geometric face. So nothing here asks for one, and `font-synthesis: none` means a
   `font-weight: 700` that slips in later (a UA default on <h1>, <strong>, <dt>, or
   a hand-written style) renders as the real drawing instead of a fake bold.
   Emphasis comes from SIZE, COLOR and CASE now. It cannot come from weight, because
   we do not own a second weight. */
:root { font-synthesis: none; font-synthesis-weight: none; }
h1, h2, h3, h4, h5, h6, strong, b, dt, th, optgroup { font-weight: 400; }

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--dome); color-scheme: dark; }
body { margin: 0; min-height: 100vh; font-family: "Custom Dot Monda", ui-sans-serif, system-ui, sans-serif; color: var(--ink); background: var(--dome); }
h1, h2, h3, p, figure, address { margin: 0; }
button, a { -webkit-tap-highlight-color: transparent; }
button { font: inherit; }
[hidden] { display: none !important; }
::selection { background: var(--gold); color: #1a1205; }
::-webkit-scrollbar { width: 11px; }
::-webkit-scrollbar-track { background: #0b0b0d; }
::-webkit-scrollbar-thumb { background: #36343a; border: 3px solid #0b0b0d; border-radius: 20px; }
a:focus-visible, button:focus-visible { outline: 3px solid var(--gold); outline-offset: 4px; border-radius: 14px; }
/* ConcertDome Monda is not Inter. Negative tracking closes its counters and is what makes it
   muddy at display sizes; NOTHING on the live marketing site is negative (measured
   2026-09-01 across every ConcertDome Monda run on concertdome.co: 0em at 80px and at every
   size <=24px, +0.03em on 32-35px copy, +0.05em on the 44px tagline). These pages
   had inherited -0.01 to -0.03em throughout. Uppercase eyebrows keep their wide
   tracking -- that is a different convention and the marketing site does it too. */
.display { letter-spacing: 0; line-height: 0.98; }
.rule { color: var(--faint); font-size: 0.69rem; letter-spacing: 0.24em; text-transform: uppercase; }

/* The hero is bottom-anchored so the photograph owns the space above the copy
   (Ethan 2026-08-24, against the Tixr event-page header). Height is taller than
   v2b's 25.25rem for the same reason; the scrim is vertical-first so the top of
   the frame stays clean and the ramp only starts under the wordmark. */
/* L-37 (ruled 2026-09-09, set by Ethan on the M04 v5 panel): 19rem at every size, and the
   photograph cropped at 41% 5% — the audience band, not the blur above it. Replaces
   clamp(30rem, 58vh, 38rem) at 50% 46%. The copy sets the height on a phone. */
.hero { position: relative; min-height: 19rem; overflow: hidden; border-bottom: 1px solid var(--line); isolation: isolate; }
.hero-picture, .hero-picture img { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero-picture { z-index: -2; }
.hero-picture img { display: block; object-fit: cover; object-position: 41% 5%; }
.hero .scrim { position: absolute; inset: 0; z-index: -1; background: linear-gradient(180deg, rgba(6, 6, 7, 0.34) 0%, rgba(6, 6, 7, 0.05) 16%, rgba(6, 6, 7, 0.08) 30%, rgba(6, 6, 7, 0.36) 46%, rgba(6, 6, 7, 0.64) 62%, rgba(6, 6, 7, 0.9) 84%, rgba(6, 6, 7, 0.96) 100%), linear-gradient(94deg, rgba(6, 6, 7, 0.46) 0%, rgba(6, 6, 7, 0.22) 44%, rgba(6, 6, 7, 0) 82%); }
.hero .inner { position: relative; display: flex; min-height: inherit; flex-direction: column; justify-content: flex-end; width: min(100%, 78rem); margin: 0 auto; padding: 7.5rem 1.25rem 3.25rem; }
.hero h1 { margin-top: 1.15rem; font-size: clamp(2.4rem, 7vw, 4.5rem); font-weight:400; }
.hero-lede { max-width: 42rem; margin-top: 0.85rem; font-size: clamp(1.08rem, 2vw, 1.25rem); line-height: 1.55; }
.hero-venue { margin-top: 0.9rem; color: var(--muted); font-size: 0.875rem; }
.hero-jump { display: none; margin-top: 1.1rem; min-height: 44px; align-items: center; color: var(--gold); text-decoration: none; font-size: 0.95rem; }
.hero-jump:hover { text-decoration: underline; }
@media (max-width: 900px) { .hero-jump { display: inline-flex; } }

.catalog { width: min(100%, 78rem); margin: 0 auto; padding: 2.5rem 1.25rem; }
.catalog > * + * { margin-top: 3rem; }
.vibes-h { margin-bottom: 0.9rem; font-size: 1.35rem; font-weight:400; letter-spacing: 0; }
/* L-40 (ruled 2026-09-09): "Find your sound" is ONE ROW that scrolls sideways. The chips
   wrapped to three rows on a phone and pushed the first card most of a screen down. Chips keep
   their size and 44px targets; below 760px the row bleeds to the viewport edges so the last
   visible chip is cut mid-way (the cue that there is more), hides its scrollbar, snaps per chip
   and fades at the right edge. Desktop already fit on one row and is unchanged in effect. */
.vibes-row { display: flex; flex-wrap: nowrap; gap: 0.5rem; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding-bottom: 0.35rem; }
.vibes-row::-webkit-scrollbar { display: none; }
.vibe { flex: none; scroll-snap-align: start; min-height: 44px; appearance: none; cursor: pointer; padding: 0.65rem 0.95rem; border: 1px solid var(--line); border-radius: 999px; color: var(--ink); background: transparent; font-size: 0.9rem; font-weight:400; line-height: 1; transition: background 160ms ease, color 160ms ease, border-color 160ms ease; }
.vibe:hover { border-color: rgba(255, 155, 18, 0.7); }
.vibe[aria-pressed="true"] { border-color: var(--gold); color: #1a1205; background: var(--gold); }
.filter-status { min-height: 1.35rem; margin-top: 0.8rem; color: var(--gold); font-size: 0.82rem; font-variant-numeric: tabular-nums; }
.no-js .filter-status { display: none; }

.month-h { display: flex; align-items: baseline; gap: 0.75rem; padding: 0 0.25rem; font-size: 1.5rem; font-weight:400; letter-spacing: 0; }
.month-yr { color: var(--faint); font-size: 1rem; font-weight: 400; }
.month-n { margin-left: auto; color: var(--muted); font-size: 0.8rem; font-weight: 400; }
.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem 1rem; margin-top: 1.1rem; }
.card { min-width: 0; display: flex; flex-direction: column; color: inherit; text-decoration: none; }
.card .poster { position: relative; aspect-ratio: 3 / 4; overflow: hidden; border: 1px solid var(--line); border-radius: 16px; background: radial-gradient(115% 90% at 24% 8%, hsl(var(--h1) 78% 29% / 0.75), transparent 53%), linear-gradient(152deg, hsl(var(--h1) 70% 17%) 0%, hsl(var(--h2) 62% 9%) 100%); transition: transform 200ms ease, border-color 200ms ease, box-shadow 200ms ease; }
/* M24 — the real photograph. Above the gradient and its texture, below the
   scrim and the price pill, so the tile's legibility does not depend on how
   bright the picture happens to be. `--fx/--fy` come from the stored focal
   point; the fallback pair is the house anchor, not 50% 50%, because a centred
   crop of a landscape frame cuts the players in half. */
.poster-img { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--fx, 50%) var(--fy, 42%);
  transform: scale(var(--fs, 1)); transform-origin: var(--fx, 50%) var(--fy, 42%); }
.poster-tex { position: absolute; inset: 0; background: url("/static/dome-hero-768.webp") center / cover; opacity: 0.22; mix-blend-mode: soft-light; }
.poster-mark { position: absolute; inset: 0; display: flex; align-items: flex-end; overflow-wrap: anywhere; padding: 0.85rem 0.9rem 3.1rem; color: rgba(255, 255, 255, 0.16); font-size: clamp(1.2rem, 3.4vw, 2.5rem); font-weight:400; letter-spacing: 0; line-height: 0.86; text-transform: uppercase; }
.poster-scrim { position: absolute; inset: 0; background: linear-gradient(180deg, transparent 45%, rgba(6, 6, 7, 0.62) 100%); }
.pill { position: absolute; z-index: 2; top: 0.7rem; right: 0.7rem; max-width: calc(100% - 1.4rem); padding: 0.38rem 0.62rem; border-radius: 999px; color: #1a1205; background: var(--gold); box-shadow: 0 8px 20px -8px rgba(0, 0, 0, 0.85); font-size: 0.78rem; font-weight:400; white-space: nowrap; }
.card:hover .poster, .card:focus-visible .poster { transform: translateY(-4px); border-color: rgba(255, 155, 18, 0.7); box-shadow: 0 26px 54px -30px rgba(0, 0, 0, 0.9); }
.info { min-width: 0; padding: 0.7rem 0.15rem 0; }
.c-date { color: var(--gold); font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; }
.c-name { margin-top: 0.3rem; overflow-wrap: anywhere; font-size: clamp(1rem, 1.6vw, 1.5rem); font-weight:400; letter-spacing: 0; line-height: 1.08; }
.c-name .mi, .poster-mark .mi { display: inline-block; width: 0.12em; }
.c-times { margin-top: 0.4rem; color: var(--muted); font-size: 0.82rem; line-height: 1.45; }

.no-results { padding: clamp(2.5rem, 7vw, 5rem) 1.25rem; border: 1px solid var(--line); border-radius: 16px; text-align: center; }
.no-results[hidden] { display: none; }
.no-results p { max-width: 35ch; margin: 0 auto; color: var(--muted); line-height: 1.6; }
.show-all { min-height: 44px; margin-top: 1rem; cursor: pointer; padding: 0.65rem 1rem; border: 1px solid var(--gold); border-radius: 999px; color: #1a1205; background: var(--gold); font-weight:400; }

.cold-close { overflow: hidden; border-top: 1px solid var(--line); background: #0b0a0d; }
.cold-close-inner { width: min(100%, 78rem); margin: 0 auto; padding: clamp(3rem, 6vw, 5rem) 1.25rem 2rem; }
.room-grid { display: grid; gap: clamp(2rem, 4vw, 3.5rem); }
.room-copy h2 { max-width: 15ch; font-size: clamp(2rem, 5vw, 4rem); }
.room-copy > p { max-width: 62ch; margin-top: 1.1rem; color: var(--muted); font-size: 1rem; line-height: 1.7; }
.room-facts { display: grid; gap: 0; margin: 1.6rem 0 0; padding: 0; list-style: none; }
.room-facts li { display: grid; grid-template-columns: 6.5rem 1fr; gap: 1rem; align-items: baseline; padding: 0.75rem 0; border-top: 1px solid var(--line); }
.room-facts strong { color: var(--gold); font-size: 1.45rem; font-variant-numeric: tabular-nums; }

/* ── The close reveals as you reach it (M27) ──────────────────────────────────
   Every rule here is gated on `.js-reveal`, which JS adds to <html> and nothing
   else does. With JS off, or under prefers-reduced-motion, the class never
   arrives and the section renders settled — LD#51/DC-05. Hiding in plain CSS and
   revealing with JS would leave a no-JS visitor looking at nothing.
   The motion is scroll-LINKED, not timed: the inline opacity/transform are
   written per frame from the element's own position on screen, so the entrance
   finishes where the reader is looking on every viewport and at any scroll speed
   (`scroll-entrance-timing`). */
.js-reveal .cd-rise { opacity: 0; transform: translateY(16px); will-change: opacity, transform; }
.js-reveal .room-facts strong { min-width: 5.2ch; display: inline-block; }
.room-facts span { color: var(--muted); font-size: 0.88rem; line-height: 1.45; }
.room-photo img { display: block; width: 100%; height: auto; border-radius: 12px; }
.no-js .room-photo .js-room-photo { display: none; }
.room-photo figcaption { margin-top: 0.65rem; color: var(--faint); font-size: 0.75rem; line-height: 1.5; }
.entity { display: grid; gap: 1.5rem; margin-top: clamp(2rem, 5vw, 3.5rem); padding-top: 1.5rem; border-top: 1px solid var(--line); color: var(--muted); font-size: 0.875rem; }
.entity h3 { margin-bottom: 0.55rem; color: var(--faint); font-size: 0.69rem; font-weight: 400; letter-spacing: 0.22em; text-transform: uppercase; }
.entity address { font-style: normal; line-height: 1.6; }
.entity a { color: var(--muted); text-underline-offset: 0.22em; }
.entity a:hover { color: var(--ink); }
.footer-credit { margin-top: 2rem; color: var(--faint); font-size: 0.75rem; }

@media (min-width: 640px) {
  .entity { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 760px) {
  .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.4rem 1.25rem; }
  .room-grid { grid-template-columns: 1.05fr 0.95fr; align-items: center; }
}
@media (min-width: 1200px) {
  .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .vibes-row { margin-inline: -1.25rem; padding-inline: 1.25rem; scroll-padding-inline: 1.25rem;
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 2.5rem), transparent 100%);
            mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 2.5rem), transparent 100%); }
}
@media (max-width: 520px) {
  /* L-37: the same 19rem pin and 41% 5% crop on a phone; the copy sets the height. */
  .hero .inner { padding-top: 6rem; padding-bottom: 2.75rem; }
  .catalog { padding-top: 2.25rem; }
  .grid { gap-inline: 0.75rem; }
  .pill { top: 0.55rem; right: 0.55rem; padding: 0.34rem 0.5rem; font-size: 0.69rem; }
  .poster-mark { padding-inline: 0.65rem; font-size: clamp(1.05rem, 6vw, 1.55rem); }
}
/* SHORT VIEWPORTS (a phone held sideways, ~844x390). The same inverted axis as the
   event and program heroes: this hero reserves `clamp(30rem, 58vh, 38rem)`, and 58vh
   of a 390px screen is 226px, so the 30rem floor wins and the hero asks for 480px
   inside a 390px window. Measured live at 844x390 before this block: the hero ran
   481px, the H1 did not START until 359px down, and the lede and venue line sat
   entirely below the fold -- the section's own landing page showed a photograph and
   no words at all. Drop the reserved height, clear the 59px site header that overlays
   this hero, and size from min(vw, vh) so the title cannot grow into the space the
   words need. */
@media (max-height: 520px) and (orientation: landscape) {
  .hero { min-height: 0; }
  .hero .inner { padding-top: 4.5rem; padding-bottom: 1.5rem; }
  .hero h1 { margin-top: 0; font-size: clamp(1.9rem, min(5vw, 9vh), 3rem); }
  .hero-lede { margin-top: 0.5rem; max-width: 52rem; font-size: clamp(0.95rem, min(2.2vw, 4.2vh), 1.1rem); }
  .hero-venue { margin-top: 0.5rem; }
  .catalog { padding-top: 1.75rem; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: 0.01ms !important; }
}

/* ── ALL PROGRAMS — the rest of the catalog, below the dated grid.
   A list, not cards: a card here would imply something to buy, and nothing in
   this section is on sale (LD#49/DC-03). Names that go somewhere, nothing more. */
.allprograms { margin-top: 3rem; border-top: 1px solid var(--line); padding-top: 1.75rem; }
.proglist { display: grid; gap: 0.15rem 1.5rem; margin-top: 1rem; padding: 0 0.25rem; list-style: none;
            grid-template-columns: 1fr; }
@media (min-width: 640px) { .proglist { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .proglist { grid-template-columns: 1fr 1fr 1fr; } }
.proglist a { display: block; padding: 0.55rem 0; color: var(--muted);
              text-decoration: none; border-bottom: 1px solid transparent; }
.proglist a:hover { color: var(--ink); border-bottom-color: var(--line); }
.proglist a:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
