/* Open Dawn Entertainment — shared site styles.
   Design system lifted from the live offer page (offer/index.html):
   navy/gold palette, Oswald display, Inter body, gold-glow hovers. */

@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 200 700;
  src: url(/assets/fonts/oswald.woff2) format('woff2');
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  src: url(/assets/fonts/inter.woff2) format('woff2');
  font-display: swap;
}

:root {
  color-scheme: dark;
  --navy: #0F172A;
  --card: #1E293B;
  --line: #334155;
  --line-soft: #475569;
  --white: #F8FAFC;
  --muted: #B6C0D0;
  --gold: #F0A621;
  --gold-bright: #FFD82B;
  --display: 'Oswald', 'Arial Narrow', 'Helvetica Neue', sans-serif;
  --body: 'Inter', -apple-system, 'Segoe UI', sans-serif;
}
:root[data-theme="light"], :root[data-theme="dark"] { color-scheme: dark; }

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
html, body { background: var(--navy); }
body {
  font-family: var(--body);
  color: var(--white);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; }
a { color: inherit; text-decoration: none; cursor: pointer; }

.wrap { max-width: 1020px; margin: 0 auto; padding: 0 24px; }


/* ---------- Hero ---------- */
.hero { text-align: center; padding: 72px 0 8px; }
.eyebrow {
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.82rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
}
/* Keyword kicker inside the H1: looks identical to the eyebrow, but sits in
   the heading so the page's H1 carries a service + location term. */
h1 .h1-kicker {
  display: block;
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.82rem;
  letter-spacing: 0.22em;
  line-height: 1.65;
  color: var(--gold);
  margin-bottom: 14px;
}
h1 {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(2.4rem, 6vw, 4.2rem);
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: 0.015em;
  margin: 14px 0 20px;
  text-wrap: balance;
}
.lede { font-size: 1.1rem; color: var(--muted); max-width: 34em; margin-inline: auto; transition: color 0.4s ease; }
.lede:hover { color: var(--white); }

/* ---------- Section headings ---------- */
section { margin: 72px 0; }
h2.sec {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.6rem, 3.4vw, 2.3rem);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.15;
  margin-bottom: 10px;
}
.sec-sub { color: var(--muted); max-width: 40em; margin-bottom: 30px; }

/* ---------- Trust strip ---------- */
.trust {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-block: 1px solid var(--line);
  margin: 56px 0;
}
.trust > div { padding: 20px 22px; border-left: 1px solid var(--line); transition: background 0.3s ease, box-shadow 0.3s ease, padding 0.3s ease; cursor: pointer; }
.trust > div:first-child { border-left: none; }
.trust > div:hover { background: var(--card); box-shadow: inset 0 2px 0 var(--gold), inset 0 -2px 0 var(--gold); padding-block: 27px; }
.trust b {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.28rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  line-height: 1.35;
  margin-bottom: 6px;
}
/* The description, and ONLY the description. `.trust span` used to be the
   selector, which also caught the two spans the stage layer builds inside the
   figure for the split-flap: the heading then rendered at 0.92rem in muted
   grey, with glyph slots measured against the figure's larger size, so every
   letter sat in a box a third too narrow and the words closed up on
   themselves. Found 2026-09-15 on the venues tab, live on every page that
   carries the strip. Keep this a child selector. */
.trust > div > span { color: var(--muted); font-size: 0.92rem; }
@media (max-width: 720px) {
  .trust { grid-template-columns: 1fr; }
  .trust > div { border-left: none; border-top: 1px solid var(--line); }
  .trust > div:first-child { border-top: none; }
}

/* ---------- Cards ---------- */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 28px;
  align-items: stretch;
}
.card {
  background: var(--card);
  border: 1px solid var(--line);
  padding: 32px 30px 28px;
  display: flex;
  flex-direction: column;
  position: relative;
  transition: border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.card:hover { border-color: var(--gold); box-shadow: 0 18px 40px -18px rgba(240, 166, 33, 0.4); transform: translateY(-3px); }
.card h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.45rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.15;
  margin-bottom: 10px;
}
.card p { color: var(--muted); font-size: 0.97rem; }
.card .price-line { font-family: var(--display); color: var(--white); margin-bottom: 10px; font-size: 1rem; }
.card .price-line b { color: var(--gold); font-weight: 600; font-size: 1.7rem; letter-spacing: 0.01em; font-variant-numeric: tabular-nums; transition: color 0.3s ease, text-shadow 0.3s ease; }
.card:hover .price-line b { color: var(--gold-bright); text-shadow: 0 0 16px rgba(255, 216, 43, 0.5); }
.card .price-line span { display: block; font-family: var(--body); color: var(--muted); font-size: 0.85rem; }
.card .go {
  margin-top: auto;
  padding-top: 18px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
  transition: color 0.25s ease, text-shadow 0.25s ease, letter-spacing 0.25s ease;
}
.card:hover .go { color: var(--gold-bright); text-shadow: 0 0 14px rgba(255, 216, 43, 0.55); letter-spacing: 0.2em; }
.chip {
  position: absolute;
  top: -13px;
  left: 30px;
  background: var(--gold);
  color: var(--navy);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 3px 12px 2px;
}

/* ---------- Tick lists ---------- */
ul.inc { list-style: none; display: flex; flex-direction: column; gap: 12px; margin: 14px 0 6px; }
ul.inc li { display: flex; gap: 12px; align-items: flex-start; font-size: 0.98rem; }
ul.inc .tick { color: var(--gold); font-weight: 600; flex: 0 0 auto; transform: translateY(1px); }

/* ---------- Steps ---------- */
.steps { counter-reset: step; display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 26px; margin-top: 14px; }
.step { counter-increment: step; border-top: 2px solid var(--line-soft); padding: 14px 16px 18px; transition: border-color 0.3s ease, background 0.3s ease; cursor: pointer; }
.step:hover { border-top-color: var(--gold); background: var(--card); }
.step::before {
  content: "0" counter(step);
  font-family: var(--display);
  font-weight: 500;
  color: var(--gold);
  font-size: 0.85rem;
  letter-spacing: 0.18em;
  transition: text-shadow 0.3s ease;
}
.step:hover::before { text-shadow: 0 0 12px rgba(240, 166, 33, 0.65); }
.step h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.12rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 6px 0 8px;
}
.step p { color: var(--muted); font-size: 0.94rem; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: var(--gold);
  color: var(--navy);
  padding: 14px 30px 12px;
  transition: background 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}
.btn:hover { background: var(--gold-bright); box-shadow: 0 0 30px rgba(255, 216, 43, 0.5); transform: translateY(-2px); }
.btn.ghost {
  background: transparent;
  color: var(--gold);
  border: 1px solid var(--gold);
}
.btn.ghost:hover { color: var(--navy); background: var(--gold-bright); border-color: var(--gold-bright); }
.btn-row { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; margin-top: 26px; }

/* ---------- CTA band ---------- */
.cta-band {
  text-align: center;
  border-block: 1px solid var(--line);
  padding: 64px 24px;
  margin: 88px 0 0;
  transition: background 0.4s ease;
}
.cta-band:hover { background: var(--card); }
.cta-band h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2rem, 5vw, 3.2rem);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--gold);
  margin-bottom: 12px;
  text-wrap: balance;
}
.cta-band p { color: var(--muted); max-width: 36em; margin: 0 auto; }

/* ---------- Forms ---------- */
form.contact { display: grid; gap: 18px; max-width: 560px; margin-top: 26px; }
form.contact label {
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.8rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
  display: block;
  margin-bottom: 6px;
}
form.contact label .req { color: var(--gold-bright); }
form.contact label .opt { color: var(--muted); font-weight: 400; letter-spacing: 0.06em; text-transform: none; }
form.contact input, form.contact textarea {
  width: 100%;
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--white);
  font-family: var(--body);
  font-size: 1rem;
  padding: 12px 14px;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
form.contact input:hover, form.contact textarea:hover { border-color: var(--line-soft); }
form.contact input:focus, form.contact textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(240, 166, 33, 0.2);
}

/* ---------- Footer ---------- */
footer.site {
  border-top: 1px solid var(--line);
  margin-top: 0;
  padding: 40px 24px 48px;
  text-align: center;
  color: var(--muted);
  font-size: 0.95rem;
}
/* Footer uses the same animated lockup (passive shine / active glow), scaled up inside a
   fixed box the same way as the nav in assets/nav.css; negative margins keep the footer's vertical rhythm. */
/* Same treatment as the nav logo: 67 x 4.19104 = 104 x 2.7, so the rendered
   size is unchanged and the margins keep the original 106px footprint and centre. */
/* THE BOX IS THE MARK, as with .nav-logo in assets/nav.css. 67px of canvas rendered 74.54px
   of ink (67 x 4.19104 x 236/889), so --ink-h keeps the size identical, and
   --overhang is the 3.77px the mark used to spill above and below its box,
   taken off the margins so the footer's rhythm is unchanged. */
footer.site .foot-logo {
  --ink-h: 74.54px;
  --overhang: calc((var(--ink-h) - var(--ink-h) / 1.11255) / 2);
  position: relative; display: block;
  height: var(--ink-h);
  width: calc(var(--ink-h) * 386 / 236);
  margin: calc(12.5px - var(--overhang)) auto calc(26.5px - var(--overhang));
  transition: transform 0.35s ease;
}
footer.site .foot-logo img {
  position: absolute;
  width: calc(var(--ink-h) * 1057 / 236);
  height: calc(var(--ink-h) * 889 / 236);
  max-width: none;
  left: calc(var(--ink-h) * -335 / 236);
  top: calc(var(--ink-h) * -326 / 236);
  pointer-events: none;
  transition: opacity 0.35s ease;
}
footer.site .foot-logo:hover { transform: scale(1.1); filter: none; }
/* The active (hover) lockup is a background inside @media (hover: hover), not a
   second <img>. It used to be an image parked at opacity 0, so every touch device
   downloaded 606 KB it could never display: hover is the only thing that reveals
   it, and touch has no hover. A background declared inside an unmatched media
   query is never fetched, which is why this is not display:none on an <img>
   (browsers fetch those anyway). Geometry matches the old .logo-b exactly, same
   box and same scale, painted above .logo-a on z-index. */
@media (hover: hover) {
  footer.site .foot-logo::before {
    content: ""; position: absolute; z-index: 1; pointer-events: none;
    width: calc(var(--ink-h) * 1057 / 236);
    height: calc(var(--ink-h) * 889 / 236);
    left: calc(var(--ink-h) * -335 / 236);
    top: calc(var(--ink-h) * -326 / 236);
    background: url("/assets/img/logo/logo-text-active.webp") center / 100% 100% no-repeat;
    opacity: 0; transition: opacity 0.35s ease;
  }
  footer.site .foot-logo:hover::before { opacity: 1; }
  footer.site .foot-logo:hover img { opacity: 0; }
}
footer.site a { color: var(--white); transition: color 0.25s ease, text-shadow 0.25s ease; }
footer.site a:hover { color: var(--gold-bright); text-shadow: 0 0 12px rgba(255, 216, 43, 0.5); }
footer.site .foot-nav { margin-top: 14px; display: flex; gap: 18px; justify-content: center; flex-wrap: wrap; }
footer.site .foot-nav a {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
footer.site .foot-nav a:hover { color: var(--gold); }
footer.site .fine { margin-top: 18px; font-size: 0.85rem; }

/* ---------- Video ---------- */
.video-card {
  border: 1px solid var(--line);
  background: var(--card);
  padding: 10px;
  transition: border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.video-card:hover { border-color: var(--gold); box-shadow: 0 22px 48px -20px rgba(240, 166, 33, 0.45); transform: translateY(-3px); }
.video-card video { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: var(--navy); }
.video-card.vertical { max-width: 430px; margin-inline: auto; }
.video-card.vertical video { aspect-ratio: 9 / 16; }
.video-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 20px; }
.video-row .video-card { max-width: none; margin: 0; }
.video-row .video-card video { aspect-ratio: 9 / 16; }
.video-row .video-cap { padding: 12px 6px 4px; }
.video-row .video-cap b { font-size: 0.95rem; }
.video-cap {
  display: flex;
  gap: 12px;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 14px 8px 6px;
}
.video-cap b {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.video-cap span { color: var(--muted); font-size: 0.92rem; }

/* ---------- Playlist card ---------- */
.playlist-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 1rem;
  padding: clamp(20px, 3vw, 32px);
  max-width: 460px;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.playlist-card:hover { border-color: var(--gold); box-shadow: 0 18px 40px -18px rgba(240, 166, 33, 0.4); }
.playlist-header { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; }
.playlist-cover { width: 56px; height: 56px; border-radius: 8px; object-fit: cover; flex-shrink: 0; }
.playlist-eyebrow {
  font-family: var(--display);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  color: var(--gold);
  display: block;
  margin-bottom: 4px;
}
.playlist-title { font-family: var(--display); font-weight: 600; font-size: 1.3rem; text-transform: uppercase; letter-spacing: 0.02em; }
.playlist-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.playlist-track {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px;
  border-radius: 8px;
  transition: background 0.2s ease;
}
.playlist-track:hover { background: rgba(240, 166, 33, 0.08); }
.playlist-thumb { width: 40px; height: 40px; border-radius: 6px; object-fit: cover; flex-shrink: 0; }
.playlist-meta { display: flex; flex-direction: column; min-width: 0; }
.playlist-track-name { color: var(--white); font-size: 0.95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.playlist-artist { color: var(--muted); font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.playlist-cta {
  display: inline-block;
  margin-top: 20px;
  padding: 10px 24px;
  border: 1px solid var(--gold);
  border-radius: 999px;
  color: var(--gold);
  font-family: var(--display);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.85rem;
  transition: box-shadow 0.3s ease, color 0.3s ease;
}
.playlist-cta:hover { box-shadow: 0 0 22px rgba(255, 216, 43, 0.45); color: var(--gold-bright); }

/* ---------- Photo grids ---------- */
.photo-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.photo-grid.three { grid-template-columns: repeat(3, 1fr); }
.photo-grid figure {
  margin: 0;
  border: 1px solid var(--line);
  background: var(--card);
  padding: 8px;
  transition: border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.photo-grid figure:hover { border-color: var(--gold); box-shadow: 0 18px 40px -18px rgba(240, 166, 33, 0.45); transform: translateY(-3px); }
.photo-grid img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; filter: saturate(1); transition: filter 0.3s ease; }
.photo-grid figure:hover img { filter: saturate(1.08) brightness(1.05); }
.photo-grid figcaption { color: var(--muted); font-size: 0.85rem; padding: 10px 6px 4px; }
.photo-grid.four { grid-template-columns: repeat(4, 1fr); }
.photo-grid.portrait img { aspect-ratio: 2 / 3; }
.photo-grid figure.wide { grid-column: 1 / -1; }
.photo-grid figure.wide img { aspect-ratio: 16 / 9; }
@media (max-width: 720px) {
  .photo-grid, .photo-grid.three { grid-template-columns: 1fr; }
  .photo-grid.four { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- Prose ---------- */
.prose { max-width: 44em; }
.prose p { margin-bottom: 18px; }
.prose p.big { font-size: 1.15rem; color: var(--white); }
.prose strong { color: var(--gold); font-weight: 600; }
/* 0913: the phone number in the closing band is one thing, and stays on one line. */
.cta-band a[href^="tel"] { white-space: nowrap; }
.cta-band p a { color: inherit; transition: color 0.25s ease, text-shadow 0.25s ease; }
.cta-band p a:hover { color: var(--gold-bright); text-shadow: 0 0 14px rgba(255, 216, 43, 0.45); }
.cta-band p a:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 3px; border-radius: 2px; }
.prose a, .app-note a, .sec-sub a { color: var(--gold); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; transition: color 0.25s ease, text-shadow 0.25s ease; }
.prose a:hover, .app-note a:hover, .sec-sub a:hover { color: var(--gold-bright); text-shadow: 0 0 14px rgba(255, 216, 43, 0.45); }
.prose a:focus-visible, .app-note a:focus-visible, .sec-sub a:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 3px; border-radius: 2px; }
/* The "last updated" line under a policy page's intro. It used to sit hard up
   against the lede, so the date read as a third sentence of the introduction
   rather than as the note about the document that it is. Only the privacy and
   terms pages carry a .fine inside a .hero; the footer's own .fine is a
   different rule below. */
.hero .fine { font-size: 0.85rem; color: var(--muted); max-width: 34em; margin-inline: auto; margin-top: 28px; }

/* ---------- Strategy-call signup ---------- */
.subscribe {
  border-block: 1px solid var(--line);
  margin: 88px 0 0;
  padding: 64px 24px;
  background:
    radial-gradient(120% 140% at 50% -10%, rgba(240, 166, 33, 0.14), rgba(15, 23, 42, 0) 60%);
}
.subscribe-inner {
  max-width: 1020px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  gap: 48px;
  align-items: center;
}
.subscribe-pitch .kick {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  display: block;
  margin-bottom: 14px;
}
.subscribe-pitch h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.9rem, 4vw, 2.9rem);
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--white);
  text-wrap: balance;
  margin-bottom: 16px;
}
.subscribe-pitch h2 em { color: var(--gold); font-style: normal; }
.subscribe-pitch p { color: var(--muted); max-width: 34em; }
.subscribe-pitch .reassure {
  margin-top: 18px;
  font-size: 0.9rem;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 8px;
}
.subscribe-pitch .reassure b { color: var(--gold); font-weight: 700; }

.subscribe-card {
  background: var(--card);
  border: 1px solid var(--line);
  padding: 28px;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.subscribe-card:hover { border-color: var(--line-soft); box-shadow: 0 22px 48px -24px rgba(240, 166, 33, 0.35); }

form.signup { display: grid; gap: 16px; }
form.signup .row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
form.signup .field { display: block; }
form.signup label {
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.76rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  display: block;
  margin-bottom: 6px;
}
form.signup label .req { color: var(--gold-bright); }
form.signup label .opt { color: var(--muted); font-weight: 400; letter-spacing: 0.06em; }
form.signup input,
form.signup select {
  width: 100%;
  background: var(--navy);
  border: 1px solid var(--line);
  color: var(--white);
  font-family: var(--body);
  font-size: 1rem;
  padding: 12px 14px;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
form.signup select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23F0A621' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 40px;
}
form.signup select:invalid { color: var(--muted); }
form.signup input:hover, form.signup select:hover { border-color: var(--line-soft); }
form.signup input:focus, form.signup select:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(240, 166, 33, 0.2);
}
form.signup .btn { width: 100%; margin-top: 4px; }
form.signup .foot-note { font-size: 0.82rem; color: var(--muted); text-align: center; margin-top: 2px; }
form.signup .foot-note a { color: var(--gold); }

.signup-done { display: none; text-align: center; padding: 20px 8px; }
.subscribe-card.done form.signup { display: none; }
.subscribe-card.done .signup-done { display: block; }
.signup-done .check {
  width: 56px; height: 56px; margin: 0 auto 16px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(240, 166, 33, 0.15);
  color: var(--gold);
  font-size: 1.8rem;
  border: 1px solid var(--gold);
}
.signup-done h3 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.5rem;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 8px;
}
.signup-done p { color: var(--muted); max-width: 24em; margin: 0 auto; }
.signup-error {
  display: none;
  color: #FCA5A5;
  font-size: 0.88rem;
  text-align: center;
}
.subscribe-card.errored .signup-error { display: block; }

@media (max-width: 820px) {
  .subscribe-inner { grid-template-columns: 1fr; gap: 32px; }
  .subscribe { padding: 52px 24px; margin-top: 64px; }
}
@media (max-width: 460px) {
  form.signup .row { grid-template-columns: 1fr; }
}

/* ---------- Pinned signup tab + modal ---------- */
.signup-tab {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 60;
  writing-mode: vertical-rl;
  transform: translateY(-50%) rotate(180deg);
  background: var(--gold);
  color: var(--navy);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 18px 11px;
  border: none;
  border-radius: 0 0 6px 6px;
  cursor: pointer;
  box-shadow: -4px 0 22px -6px rgba(0, 0, 0, 0.5);
  transition: background 0.25s ease, box-shadow 0.25s ease, padding 0.25s ease;
}
.signup-tab:hover {
  background: var(--gold-bright);
  box-shadow: -4px 0 30px -4px rgba(255, 216, 43, 0.6);
  padding-right: 15px;
}
.signup-tab .tab-star { display: inline-block; margin-bottom: 8px; }

.signup-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(5, 9, 18, 0.78);
  backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.28s ease, visibility 0.28s ease;
}
.signup-modal.open { opacity: 1; visibility: visible; }
.signup-modal-card {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: 92vh;
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--gold);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.7), 0 0 40px -10px rgba(240, 166, 33, 0.35);
  padding: 32px 28px 28px;
  transform: translateY(14px) scale(0.98);
  transition: transform 0.28s ease;
}
.signup-modal.open .signup-modal-card { transform: translateY(0) scale(1); }
.signup-modal-close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 1.7rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  transition: color 0.2s ease, background 0.2s ease;
}
.signup-modal-close:hover { color: var(--gold-bright); background: rgba(255, 216, 43, 0.12); }
.signup-modal-card .kick {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  display: block;
  margin-bottom: 8px;
}
.signup-modal-card h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2rem);
  line-height: 1.04;
  text-transform: uppercase;
  color: var(--white);
  margin-bottom: 8px;
  text-wrap: balance;
}
.signup-modal-card h2 em { color: var(--gold); font-style: normal; }
.signup-modal-card > p.lead { color: var(--muted); font-size: 0.95rem; margin-bottom: 20px; }
body.modal-open { overflow: hidden; }
.signup-modal-card.done form.signup { display: none; }
.signup-modal-card.done .signup-done { display: block; }
.signup-modal-card.errored .signup-error { display: block; }

@media (max-width: 600px) {
  .signup-tab {
    writing-mode: horizontal-tb;
    transform: none;
    top: auto;
    bottom: 16px;
    right: 16px;
    border-radius: 999px;
    padding: 12px 20px;
    font-size: 0.82rem;
    box-shadow: 0 8px 22px -6px rgba(0, 0, 0, 0.6);
  }
  .signup-tab:hover { padding-right: 20px; }
  .signup-tab .tab-star { margin-bottom: 0; margin-right: 6px; }
}

/* ---------- The venue app ----------
   The one door on this site that leads somewhere a venue can actually do
   something: app.opendawn.com.au, where they pick a night and ask for it.
   It wore the app's own terracotta until 2026-09-05, when Yannai asked for
   the gold instead: one orange across the site, the app door the solid one
   and the call button beside it stepped back to an outline so the two do not
   shout together.

   Everything moves in CSS, deliberately. A GIF would be heavier, would blur
   at any size the button is not, cannot take a hover state, and would keep
   moving for the one visitor in fifty who has asked their machine to stop
   animations. */
a.app-cta {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  font-family: var(--display);
  font-weight: 600;
  text-transform: uppercase;
  color: var(--navy);
  background: var(--gold);
  box-shadow: 0 0 0 rgba(240, 166, 33, 0);
  transition: background 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}

a.app-cta:hover {
  background: var(--gold-bright);
  box-shadow: 0 0 26px rgba(255, 216, 43, 0.5), 0 0 0 1px rgba(255, 216, 43, 0.35) inset;
  transform: translateY(-1px);
}
a.app-cta:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}

/* A light sweeps across the face every few seconds, the way a bar sign
   catches the light. Long gap, short pass: enough to pull an eye that is
   already scanning, not enough to nag one that is reading. */
a.app-cta::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -60%;
  width: 45%;
  z-index: -1;
  pointer-events: none;
  transform: skewX(-22deg);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.45), transparent);
  animation: appSheen 4.6s ease-in-out infinite;
}
a.app-cta::after { animation-duration: 5.4s; }

@keyframes appSheen {
  0%, 62% { left: -60%; }
  88%, 100% { left: 125%; }
}
@keyframes appBreathe {
  0%, 100% { box-shadow: 0 0 0 rgba(240, 166, 33, 0); }
  50% { box-shadow: 0 0 20px rgba(240, 166, 33, 0.55); }
}

/* The arrow leans forward when you point at it. */
a.app-cta .app-arrow {
  display: inline-block;
  margin-left: 7px;
  transition: transform 0.25s ease;
}
a.app-cta:hover .app-arrow { transform: translateX(4px); }

/* ---------- The app band ----------
   The big one, for the top of a page rather than the corner of a nav. */
.app-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 26px;
  flex-wrap: wrap;
  margin: 34px 0 8px;
  padding: 26px 30px;
  border: 1px solid rgba(240, 166, 33, 0.45);
  background:
    radial-gradient(120% 180% at 0% 0%, rgba(240, 166, 33, 0.16), transparent 62%),
    var(--card);
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.app-band:hover {
  border-color: rgba(240, 166, 33, 0.8);
  box-shadow: 0 22px 48px -24px rgba(240, 166, 33, 0.55);
}
.app-band-text { min-width: 260px; flex: 1; }
.app-band .app-eyebrow {
  display: block;
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 7px;
}
.app-band h2 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.55rem;
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--white);
  margin-bottom: 8px;
}
.app-band p {
  color: var(--muted);
  font-size: 0.98rem;
  margin: 0;
  max-width: 54ch;
}
a.app-cta {
  flex: none;
  font-size: 1rem;
  letter-spacing: 0.13em;
  padding: 16px 30px 14px;
  animation: appBreathe 3.4s ease-in-out infinite;
}
.app-band .app-note {
  display: block;
  width: 100%;
  font-size: 0.82rem;
  color: var(--muted);
  margin-top: -6px;
}

@media (max-width: 760px) {
  .app-band { padding: 22px 20px; gap: 18px; }
  .app-band h2 { font-size: 1.3rem; }
  a.app-cta { width: 100%; text-align: center; }
}

/* ---------- /home/ scroll + entrance motion ----------
   Progressive enhancement: everything below renders in its resting state by
   default, so a no-JS visitor, a crawler, or anyone who has asked their
   machine to stop animating sees the full page immediately. assets/home-
   motion.js adds .motion-on to <body> only once it has confirmed
   IntersectionObserver support and that reduced motion was NOT requested;
   only then do [data-reveal] elements start hidden and animate in — as a
   real overshoot bounce, not a smooth ease — as they cross the viewport (or
   right on load, for anything already on screen, e.g. the hero).
   animation-delay reads --reveal-d (a plain number of ms set inline per
   element) so groups cascade in rather than arriving together. Each
   direction is its own keyframe set (rather than one parameterised
   animation driving transform via custom properties) because a bounce path
   isn't just "start here, end at none" — the overshoot needs its own
   in-between beats per direction, e.g. left's overshoot rotates the
   opposite way it entered, which a single shared curve can't express. */
body.home.motion-on [data-reveal]:not(.is-in) { opacity: 0; }
body.home.motion-on [data-reveal].is-in {
  animation-duration: 1.15s;
  animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
  animation-fill-mode: both;
  animation-delay: calc(var(--reveal-d, 0) * 1ms);
}
body.home.motion-on [data-reveal="rise"].is-in  { animation-name: bounceRise; }
body.home.motion-on [data-reveal="scale"].is-in { animation-name: bounceScale; }
body.home.motion-on [data-reveal="left"].is-in  { animation-name: bounceLeft; }
body.home.motion-on [data-reveal="right"].is-in { animation-name: bounceRight; }

/* All four bounce paths scaled to 70% of their original travel and overshoot
   (30% less big, per Yannai's call after seeing the first pass): translate
   scaled directly, scale keyframes scaled by their DEVIATION from 1 so "30%
   less big" reads the same way for a size change as it does for a distance.

   The left and right paths used to swing in tilted as well, up to five
   degrees, settling square. That came out on 2026-09-05 with the scroll
   rotation, and for the same reason: "flatten the entrance tilt too". They
   slide and overshoot now, which is the part that carries the arrival. */
@keyframes bounceRise {
  0%   { opacity: 0; transform: translateY(98px) scale(0.874); }
  55%  { opacity: 1; transform: translateY(-15px) scale(1.035); }
  75%  { transform: translateY(7px) scale(0.986); }
  100% { opacity: 1; transform: none; }
}
@keyframes bounceScale {
  0%   { opacity: 0; transform: translateY(56px) scale(0.65); }
  50%  { opacity: 1; transform: translateY(-11px) scale(1.098); }
  72%  { transform: translateY(4px) scale(0.965); }
  88%  { transform: scale(1.021); }
  100% { opacity: 1; transform: none; }
}
@keyframes bounceLeft {
  0%   { opacity: 0; transform: translateX(-196px); }
  55%  { opacity: 1; transform: translateX(18px); }
  78%  { transform: translateX(-8px); }
  100% { opacity: 1; transform: none; }
}
@keyframes bounceRight {
  0%   { opacity: 0; transform: translateX(196px); }
  55%  { opacity: 1; transform: translateX(-18px); }
  78%  { transform: translateX(8px); }
  100% { opacity: 1; transform: none; }
}

/* Once a [data-zoom] element's entrance bounce finishes, home-motion.js
   clears animation-name (see there for why) and takes over `transform`
   itself every frame: each such block keeps gently swelling as it passes the
   centre of the viewport and settling as it leaves, at its own amplitude,
   speed and phase (data-zoom plus the per-element variety the script derives
   from index), so the page doesn't all breathe in lockstep.

   It used to turn a degree or two as well, and that came out on 2026-09-05:
   a dozen blocks each tilting on their own frequency read as messy rather
   than alive. The scale is the part that was worth keeping. */

/* A gently arched "What we do" row and a staircase for "How it starts": pure
   static layout, independent of the reveal transform above, so each
   block's resting position stays put once it has finished animating in. */
@media (min-width: 761px) {
  .home .cards .card:nth-child(2) { margin-top: -18px; }
  .home .steps .step:nth-child(2),
  .home .steps .step:nth-child(4) { margin-top: 26px; }
}

/* A gold breath behind the headline, echoing the accent colour used
   everywhere else on the page. Sits behind the text (own stacking context,
   negative z-index) so it never fights it for contrast. */
.hero { position: relative; }
.hero::before {
  content: "";
  position: absolute;
  top: 46%;
  left: 50%;
  width: min(64vw, 760px);
  aspect-ratio: 1;
  translate: -50% -50%;
  background: radial-gradient(circle, rgba(240, 166, 33, 0.26), rgba(240, 166, 33, 0) 68%);
  z-index: -1;
  animation: heroBreathe 6s ease-in-out infinite;
}
@keyframes heroBreathe {
  0%, 100% { opacity: 0.5; scale: 0.86; }
  50% { opacity: 1; scale: 1.16; }
}

/* ---------- Background texture ----------
   A faint, slow-drifting layer of colour over the whole page, INCLUDING
   over card/section backgrounds, not just the plain navy gaps between them
   — z-index sits above ordinary content (but below the nav) rather than
   behind it. That's safe for legibility specifically because of how it's
   composited: the source clip is bold colour against a PURE BLACK
   background (Runway cannot output an alpha channel), so mix-blend-mode:
   screen is used instead of alpha transparency. Screen only ever ADDS
   light — black contributes nothing, and it can never darken or obscure
   text under it the way a normal layered-on-top overlay would — so
   opacity here is purely about how much colour shows through, not about
   protecting readability. Off on small screens and under reduced motion,
   both to keep mobile weight down and because it never stops moving. */
.home .bg-texture-layer {
  position: fixed;
  inset: 0;
  z-index: 5;
  overflow: hidden;
  opacity: 0.12;
  mix-blend-mode: screen;
  pointer-events: none;
}
.home .bg-texture-layer video {
  position: absolute;
  top: 50%;
  left: 50%;
  min-width: 100%;
  min-height: 120%;
  width: auto;
  height: auto;
  translate: -50% -50%;
  object-fit: cover;
}
@media (max-width: 760px), (prefers-reduced-motion: reduce) {
  .home .bg-texture-layer { display: none; }
}


/* ---------- Flair layer ----------
   Yannai's brief, 2026-08-29: more life on the Venues page, then the same
   treatment on the rest of the tabs, Musicians excepted. It is written once
   here rather than page by page, because every one of those tabs already
   loads this file and /artists/ is the single page that does not (it is
   built by Astro and carries its own stylesheet), so the exception he asked
   for is the one the stylesheet boundary already draws.

   Two rules kept this from turning into a rewrite. Every effect decorates an
   element that already exists, so no page's markup changed and the tabs open
   in the homepage's frame exactly as before. And every effect is built from
   the logo's own vocabulary: the sun's widening bands, one gold at rest, the
   brighter gold reserved for the moment somebody touches something.

   /home/ is held out of the scroll reveal at the bottom. It has its own,
   driven by assets/home-motion.js, and two systems writing the same
   `transform` on one element is precisely the bug that file was built to
   avoid. Everything above the reveal applies there too. */

/* -- Section headings wear the mark's widening bands. Three bars rather than
      the logo's four, so it reads as a signature and not as a second logo. -- */
h2.sec::before {
  content: "";
  display: block;
  width: 56px;
  height: 10px;
  margin-bottom: 15px;
  transform-origin: left center;
  background:
    linear-gradient(var(--gold), var(--gold)) 0 0 / 24px 2px no-repeat,
    linear-gradient(var(--gold), var(--gold)) 0 4px / 38px 2px no-repeat,
    linear-gradient(var(--gold), var(--gold)) 0 8px / 56px 2px no-repeat;
  filter: drop-shadow(0 0 5px rgba(240, 166, 33, 0.45));
  transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1), filter 0.45s ease;
}
section:hover h2.sec::before {
  transform: scaleX(1.28);
  filter: drop-shadow(0 0 11px rgba(255, 216, 43, 0.8));
}
.cta-band h2, .sec { text-wrap: balance; }

/* -- Cards get a face with some depth in it, a rule that draws itself across
      the top, and a light that passes over when you point at one. The sheen is
      a moving background-position rather than a sliding box, so the card needs
      no `overflow: hidden` and the .chip hanging off its top edge survives. -- */
.card {
  background: linear-gradient(158deg, #24334e 0%, var(--card) 44%, #17233a 100%);
  isolation: isolate;
}
.card::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--gold-bright), var(--gold) 45%, transparent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.card::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(104deg, transparent 38%, rgba(255, 238, 200, 0.13) 48%, transparent 58%);
  background-size: 260% 100%;
  background-position: 135% 0;
  opacity: 0;
  transition: background-position 0.9s ease, opacity 0.3s ease;
}
.card:hover { box-shadow: 0 22px 48px -18px rgba(240, 166, 33, 0.5); transform: translateY(-5px); }
.card:hover::before { transform: scaleX(1); }
.card:hover::after { opacity: 1; background-position: -35% 0; }
a.card:active {
  transform: translateY(-1px);
  border-color: var(--gold-bright);
  box-shadow: 0 8px 22px -12px rgba(255, 216, 43, 0.7);
}
.card:hover .chip { background: var(--gold-bright); box-shadow: 0 0 18px rgba(255, 216, 43, 0.55); }
.chip { transition: background 0.3s ease, box-shadow 0.3s ease; }

/* -- The trust strip warms from underneath instead of just changing colour. -- */
.trust > div:hover {
  background: linear-gradient(180deg, var(--card) 30%, rgba(240, 166, 33, 0.11));
}
.trust b { transition: color 0.3s ease, text-shadow 0.3s ease; }
.trust > div:hover b { color: var(--gold-bright); text-shadow: 0 0 16px rgba(255, 216, 43, 0.5); }

/* -- Steps: the rule above each one lights along its length. -- */
.step { position: relative; }
.step::after {
  content: "";
  position: absolute;
  left: 0;
  top: -2px;
  height: 2px;
  width: 100%;
  background: linear-gradient(90deg, var(--gold-bright), var(--gold) 55%, transparent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.step:hover::after { transform: scaleX(1); }

/* -- The opening line of a prose block gets the gold margin rule. -- */
.prose p.big { position: relative; padding-left: 20px; }
.prose p.big::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.3em;
  bottom: 0.3em;
  width: 3px;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold) 55%, rgba(240, 166, 33, 0));
  box-shadow: 0 0 12px rgba(240, 166, 33, 0.5);
}

/* -- Ticks catch the light, and answer individually. -- */
ul.inc .tick { text-shadow: 0 0 9px rgba(240, 166, 33, 0.5); transition: text-shadow 0.3s ease, transform 0.3s ease; }
ul.inc li:hover .tick { text-shadow: 0 0 16px rgba(255, 216, 43, 0.85); transform: translateY(1px) scale(1.2); }

/* -- Buttons pick up the third state they were missing, plus the same pass of
      light the app button has had all along. -- */
.btn { position: relative; overflow: hidden; }
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, 0.45) 50%, transparent 60%);
  background-size: 250% 100%;
  background-position: 145% 0;
  transition: background-position 0.75s ease;
}
.btn:hover::after { background-position: -45% 0; }
.btn:active {
  transform: translateY(0);
  box-shadow: 0 0 0 2px rgba(255, 216, 43, 0.85) inset, 0 0 26px rgba(255, 216, 43, 0.55);
}
.btn.ghost:active { background: var(--gold); color: var(--navy); border-color: var(--gold-bright); }

/* -- The closing band gets a dawn behind it, the way the hero has one. -- */
.cta-band { position: relative; }
.cta-band::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 52%;
  width: min(88vw, 920px);
  aspect-ratio: 2 / 1;
  translate: -50% -50%;
  background: radial-gradient(ellipse, rgba(240, 166, 33, 0.22), rgba(240, 166, 33, 0) 68%);
  pointer-events: none;
  z-index: 0;
  opacity: 0.8;
  transition: opacity 0.5s ease, scale 0.6s var(--ease-out, ease);
}
.cta-band:hover::before { opacity: 1; scale: 1.14; }
.cta-band > * { position: relative; z-index: 1; }
.cta-band h2 { transition: text-shadow 0.4s ease; }
.cta-band:hover h2 { text-shadow: 0 0 28px rgba(240, 166, 33, 0.55); }

/* -- Blocks rise as they come into view. Driven by the scroll position itself
      (`animation-timeline: view()`), so there is no script to load, nothing to
      observe, and nothing that can leave a block stuck at opacity 0 the way the
      /home/ reveal once did: a browser without the feature never runs the rule,
      and anything already on screen at load has passed its range and resolves
      to the finished state on the first frame. -- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    body:not(.home) section,
    body:not(.home) .trust,
    body:not(.home) .app-band,
    body:not(.home) .cta-band,
    body:not(.home) .subscribe {
      animation: flairIn linear both;
      animation-timeline: view();
      animation-range: entry 4% entry 56%;
    }
  }
}
@keyframes flairIn {
  from { opacity: 0; transform: translateY(44px) scale(0.978); }
  to { opacity: 1; transform: none; }
}

/* ============================================================================
   Page signatures — Yannai's brief, 2026-09-01: each tab reads as its own
   room, not another copy of the same one. One motif per page, built from the
   house vocabulary (navy ground, one gold, Oswald), scoped by a body class so
   nothing leaks between pages. Musicians stays out: it never loads this file.

     .venues   — the ticket office: numbered stubs, stage light, folded FAQ
     .home     — the calendar: a week grid with one night lit, steps ignite
     .about    — the editorial: sticky margin headings, drop cap, the numbers
     .contact  — the soundline: a waveform that answers the pointer

   Depth comes from fixed light layers behind the page that drift on the
   scroll timeline where the browser supports it, and simply hold still where
   it does not. The reduced-motion block at the end of this file already
   silences everything here; nothing below needs its own escape hatch beyond
   what is written in place.
   ========================================================================= */

/* The hero must be its own stacking context for any layer drawn behind its
   text at negative z-index to be visible at all. Both html AND body carry the
   navy background, and a body with its own background paints it over every
   negative z-index descendant in the root context (backgrounds of in-flow
   boxes paint after negative stacking contexts). `isolation` scopes the
   negative layer to the hero, above whatever the page painted below it.
   This also puts the flair layer's dawn breath (.hero::before) on screen,
   which had been sitting under the body background on every tab page. */
.hero { isolation: isolate; }

/* ----------------------------------------------------------------------------
   VENUES — the ticket office.
   ------------------------------------------------------------------------- */

/* Stage light behind the whole page: two soft cones crossing from the top
   corners, the way a room reads from the floor. Fixed, so the page scrolls
   through the light rather than carrying it along. */
body.venues::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(58% 42% at 12% -6%, rgba(240, 166, 33, 0.09), transparent 70%),
    radial-gradient(52% 38% at 88% -4%, rgba(240, 166, 33, 0.05), transparent 70%);
}
body.venues .wrap, body.venues .cta-band, body.venues .subscribe, body.venues footer.site { position: relative; z-index: 1; }

/* Every card on this page is a ticket: a stub column on the right behind a
   perforated rule, punched notches where the tear line meets the edges, and
   the ticket number standing on end in the stub. The notches are cut with a
   mask, so the card face, border and shadow all honour them. */
body.venues .cards { counter-reset: tix; }
body.venues .cards .card {
  --stub: 58px;
  counter-increment: tix;
  padding-right: calc(var(--stub) + 22px);
  -webkit-mask:
    radial-gradient(circle 9px at calc(100% - var(--stub)) 0, transparent 8.5px, #000 9.5px),
    radial-gradient(circle 9px at calc(100% - var(--stub)) 100%, transparent 8.5px, #000 9.5px);
  -webkit-mask-composite: source-in;
  mask:
    radial-gradient(circle 9px at calc(100% - var(--stub)) 0, transparent 8.5px, #000 9.5px),
    radial-gradient(circle 9px at calc(100% - var(--stub)) 100%, transparent 8.5px, #000 9.5px);
  mask-composite: intersect;
}
/* THE CHIP HAS TO COME INSIDE THE TICKET.
 *
 * A mask clips every descendant, not just the face it was drawn for. The .chip
 * sits at top: -13px so it straddles the card's top edge everywhere else on the
 * site, and on this page the notch mask above sliced each one clean in half:
 * "ONE NIGHT", "TWO OR MORE A WEEK" and "ONE-OFFS" were all showing their
 * bottom halves only. Yannai found it on 2026-09-02.
 *
 * There is no exempting one child from a mask, and the notches are the point of
 * the ticket, so the chip moves rather than the mask. It sits fully inside the
 * card here, which reads as a ticket class marking rather than as a tab, and
 * the card's top padding grows by the same amount so the heading has somewhere
 * to be. Every other page keeps the straddle. */
body.venues .cards .card { padding-top: 56px; }
body.venues .cards .chip { top: 18px; }

/* The perforation: a dashed hairline down the tear, drawn as a background so
   it needs no pseudo-element (both of the card's are already spoken for). */
body.venues .cards .card {
  background:
    repeating-linear-gradient(180deg,
      rgba(240, 166, 33, 0.4) 0 5px, transparent 5px 11px)
      calc(100% - var(--stub)) 0 / 1px 100% no-repeat,
    linear-gradient(158deg, #24334e 0%, var(--card) 44%, #17233a 100%);
}
/* The ticket number, standing on end in the stub, numbered like the roster. */
body.venues .cards .card h3::after {
  content: "N\00BA  0" counter(tix);
  /* The number is decoration, and without the alt syntax it was being read
     into the three pricing links' own names. */
  content: "N\00BA  0" counter(tix) / "";
  position: absolute;
  top: 50%;
  right: calc((var(--stub) + 2px) / 2);
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(240, 166, 33, 0.55);
  transition: color 0.3s ease, text-shadow 0.3s ease;
}
body.venues .cards .card:hover h3::after {
  color: var(--gold-bright);
  text-shadow: 0 0 10px rgba(255, 216, 43, 0.55);
}
@media (max-width: 460px) {
  body.venues .cards .card { --stub: 44px; }
}

/* The folded questions. Content is untouched (the JSON-LD carries the same
   words), but a wall of eight paragraphs becomes eight hairlines that open
   one at a time, so the page shows its questions rather than its answers. */
body.venues .faq { max-width: 44em; }
body.venues .faq details { border-top: 1px solid var(--line); }
body.venues .faq details:last-child { border-bottom: 1px solid var(--line); }
body.venues .faq summary {
  list-style: none;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  padding: 17px 2px 15px;
  cursor: pointer;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: color 0.25s ease, padding-left 0.3s ease;
}
body.venues .faq summary::-webkit-details-marker { display: none; }
body.venues .faq summary::after {
  content: "+";
  flex: 0 0 auto;
  font-family: var(--display);
  font-weight: 500;
  font-size: 1.25rem;
  line-height: 1;
  color: var(--gold);
  transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1), color 0.25s ease;
}
body.venues .faq summary:hover { color: var(--gold); padding-left: 8px; }
body.venues .faq summary:hover::after { color: var(--gold-bright); text-shadow: 0 0 12px rgba(255, 216, 43, 0.6); }
body.venues .faq details[open] summary { color: var(--gold); }
body.venues .faq details[open] summary::after { transform: rotate(45deg); }
body.venues .faq .faq-a { padding: 0 2px 20px; color: var(--muted); max-width: 58ch; }
body.venues .faq .faq-a strong { color: var(--gold); font-weight: 600; }

/* ----------------------------------------------------------------------------
   HOW IT WORKS — the calendar.
   ------------------------------------------------------------------------- */

/* A faint week behind the hero: seven columns, one night lit. The grid is
   nothing but lines and one warm cell, so it reads as a suggestion of a
   calendar rather than a picture of one. */
body.home .hero::after {
  content: "";
  position: absolute;
  top: 4%;
  left: 50%;
  width: min(78vw, 860px);
  height: 88%;
  translate: -50%;
  z-index: -1;
  pointer-events: none;
  opacity: 0.75;
  background:
    /* the lit night, four columns in, second row */
    radial-gradient(closest-side at 64.3% 38%, rgba(240, 166, 33, 0.5), rgba(240, 166, 33, 0.14) 62%, transparent 100%) no-repeat,
    /* verticals */
    repeating-linear-gradient(90deg, rgba(182, 192, 208, 0.16) 0 1px, transparent 1px calc(100% / 7)),
    /* horizontals */
    repeating-linear-gradient(180deg, rgba(182, 192, 208, 0.16) 0 1px, transparent 1px 25%);
  background-size: 26% 32%, 100% 100%, 100% 100%;
  background-position: 51.5% 24%, 0 0, 0 0;
  -webkit-mask: radial-gradient(75% 75% at 50% 45%, #000 30%, transparent 100%);
  mask: radial-gradient(75% 75% at 50% 45%, #000 30%, transparent 100%);
}

/* Steps wear their numbers as marks that ignite: a ring that closes and
   fills as the step arrives in view, scroll-driven, no script. */
body.home .step::before {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--line-soft);
  background: radial-gradient(circle at 50% 35%, rgba(240, 166, 33, 0.12), transparent 70%);
  font-size: 0.8rem;
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    body.home .step::before {
      animation: stepIgnite linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 80%;
    }
  }
}
@keyframes stepIgnite {
  from {
    border-color: var(--line-soft);
    color: var(--muted);
    box-shadow: 0 0 0 rgba(240, 166, 33, 0);
  }
  to {
    border-color: var(--gold);
    color: var(--gold);
    box-shadow: 0 0 18px rgba(240, 166, 33, 0.45);
  }
}

/* ----------------------------------------------------------------------------
   ABOUT — the editorial.
   ------------------------------------------------------------------------- */

/* Margin headings: on a wide screen each section runs as two columns, the
   heading held in the margin and staying with you while its prose scrolls.
   The one deliberate break from the site's single-column rhythm. */
@media (min-width: 861px) {
  body.about .wrap section {
    display: grid;
    grid-template-columns: 240px minmax(0, 1fr);
    column-gap: 48px;
    align-items: start;
  }
  body.about .wrap section > h2.sec {
    position: sticky;
    top: 110px;
    margin-bottom: 0;
  }
  body.about .wrap section > *:not(h2.sec) { grid-column: 2; }
}

/* The opening letter of the story, set like print. */
body.about .prose > p.big::first-letter {
  float: left;
  font-family: var(--display);
  font-weight: 600;
  font-size: 3.6em;
  line-height: 0.82;
  padding: 4px 12px 0 0;
  color: var(--gold);
  text-shadow: 0 0 22px rgba(240, 166, 33, 0.4);
}

/* The numbers, oversized and counting. The figures land at their real values
   with no script: the count-up is decoration layered over static text. */
body.about .ledger {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
  margin: 26px 0 6px;
}
body.about .ledger > div { border-top: 2px solid var(--line-soft); padding-top: 14px; transition: border-color 0.3s ease; }
body.about .ledger > div:hover { border-top-color: var(--gold); }
body.about .ledger b {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(2.6rem, 6vw, 4rem);
  line-height: 1;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 26px rgba(240, 166, 33, 0.3);
}
body.about .ledger span { color: var(--muted); font-size: 0.92rem; }
@media (max-width: 720px) {
  body.about .ledger { grid-template-columns: 1fr; gap: 18px; }
}

/* ----------------------------------------------------------------------------
   CONTACT — the soundline.
   ------------------------------------------------------------------------- */

/* A waveform across the page: forty reeds, each a beat behind its
   neighbour, so a wave travels the line forever. The pointer plays it:
   assets/soundline.js lifts the reeds nearest the cursor. With no script
   and no motion it is simply a hairline of gold reeds, which still reads. */
.soundline {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 64px;
  margin: 44px 0 8px;
}
.soundline i {
  flex: 1;
  height: 8px;
  min-width: 2px;
  background: var(--gold);
  opacity: 0.55;
  border-radius: 2px;
  animation: soundIdle 3.2s ease-in-out infinite;
  animation-delay: calc(var(--i) * -0.16s);
  transition: height 0.18s ease, opacity 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
@keyframes soundIdle {
  0%, 100% { transform: scaleY(1); }
  50% { transform: scaleY(3.4); }
}
.soundline i.lift {
  animation-play-state: paused;
  opacity: 1;
  background: var(--gold-bright);
  box-shadow: 0 0 12px rgba(255, 216, 43, 0.6);
  height: calc(8px + var(--lift, 0) * 46px);
}

/* The direct line, set large: the phone number is the point of this page,
   so it is the biggest thing on it after the headline. */
body.contact .trust { border-block: 0; margin: 40px 0 0; grid-template-columns: 1fr; }
body.contact .trust > div {
  display: flex;
  align-items: baseline;
  gap: 26px;
  border-left: 0;
  border-top: 1px solid var(--line);
  padding: 18px 2px;
}
body.contact .trust > div:hover { padding-block: 18px; box-shadow: none; background: linear-gradient(90deg, rgba(240, 166, 33, 0.07), transparent 60%); }
body.contact .trust b { flex: 0 0 120px; font-size: 0.82rem; font-weight: 500; letter-spacing: 0.22em; color: var(--gold); margin-bottom: 0; }
body.contact .trust > div > span {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.3rem, 3.6vw, 2.1rem);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--white);
}
body.contact .trust > div > span a { transition: color 0.25s ease, text-shadow 0.25s ease; }
body.contact .trust > div > span a:hover { color: var(--gold-bright); text-shadow: 0 0 18px rgba(255, 216, 43, 0.45); }
@media (max-width: 720px) {
  body.contact .trust > div { flex-direction: column; gap: 2px; }
  body.contact .trust b { flex: none; }
  body.contact .trust > div > span { font-size: 1.15rem; }
}

/* Form fields on this page answer with a drawn underline rather than a ring:
   the border stays, and a gold line sweeps along the bottom edge on focus. */
body.contact form.contact div { position: relative; }
body.contact form.contact div::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: linear-gradient(90deg, var(--gold-bright), var(--gold) 60%, transparent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
  pointer-events: none;
}
body.contact form.contact div:focus-within::after { transform: scaleX(1); }
body.contact form.contact input:focus, body.contact form.contact textarea:focus { box-shadow: none; }
body.contact form.contact input, body.contact form.contact textarea { caret-color: var(--gold-bright); }

@media (prefers-reduced-motion: reduce) {
  /* The pseudo-elements are named because `*` never matches them: without
     them the hero's dawn breath kept running for the one visitor who asked
     it not to (found by web-reviewer, 2026-09-02). */
  *, *::before, *::after { transition: none !important; animation: none !important; }
  html { scroll-behavior: auto; }
  /* The sheen is decoration; with motion off it should not sit frozen
     mid-sweep across the face of the button. */
  a.app-cta::after { display: none; }
}


/* ============================================================================
   VENUES — the easiest booking system. Yannai, 2026-09-02: "the real thing
   I'm selling is ease of use", "constant movement". Everything below is the
   venue page showing its own machinery running: a board that never stops
   scrolling, tasks that leave the venue's desk for ours on a loop, a live
   pulse on each of the nine things handled, a saving that draws itself, and
   a stage light that breathes. Built from the same vocabulary as the ticket
   office above it (navy ground, one gold, Oswald), scoped to body.venues.
   The reduced-motion block earlier in this file silences all of it, and every
   resting state below is the FINISHED state, so with motion off the page
   reads complete rather than caught mid-move.
   ========================================================================= */

/* -- The stage light breathes, and a second warmth drifts across the page. -- */
@keyframes venuesBreathe {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }
  50%      { transform: translate3d(0, 1.5vh, 0) scale(1.05); opacity: 0.82; }
}
@keyframes venuesDrift {
  from { transform: translate3d(-14vw, 0, 0); }
  to   { transform: translate3d(14vw, -6vh, 0); }
}
body.venues::before {
  transform-origin: 50% 0;
  animation: venuesBreathe 16s ease-in-out infinite;
}
body.venues::after {
  content: "";
  position: fixed;
  z-index: 0;
  pointer-events: none;
  left: 50%;
  top: 34%;
  width: 62vmax;
  height: 62vmax;
  margin-left: -31vmax;
  background: radial-gradient(closest-side, rgba(240, 166, 33, 0.075), transparent 72%);
  animation: venuesDrift 28s ease-in-out infinite alternate;
}

/* -- The board: everything handled, running past like a departures board.
      Two copies of the list, the track slides half its width, so the loop
      never shows a seam. Hover holds it still so a line can be read. -- */
body.venues .board {
  position: relative;
  margin: 38px 0 0;
  padding: 13px 0 11px;
  border-block: 1px solid var(--line);
  overflow: hidden;
  -webkit-mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
body.venues .board-track {
  display: flex;
  width: max-content;
  animation: boardRun 48s linear infinite;
}
body.venues .board:hover .board-track,
body.venues .board:focus-visible .board-track { animation-play-state: paused; }
body.venues .board:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
body.venues .board-list { display: flex; list-style: none; margin: 0; padding: 0; }
body.venues .board-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 28px;
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.84rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  transition: color 0.25s ease, text-shadow 0.25s ease;
}
body.venues .board-list li:hover { color: var(--gold-bright); text-shadow: 0 0 12px rgba(255, 216, 43, 0.5); }
body.venues .board-list .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 10px rgba(240, 166, 33, 0.75);
  animation: dotPulse 2.8s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * -0.37s);
}
@keyframes boardRun { to { transform: translate3d(-50%, 0, 0); } }
@keyframes dotPulse {
  0%, 100% { transform: scale(1); opacity: 0.75; }
  50%      { transform: scale(1.45); opacity: 1; box-shadow: 0 0 16px rgba(255, 216, 43, 0.9); }
}

/* -- Your desk, our desk. Eight tasks slide from the venue's column into
      ours and land with a tick, one after another, forever. The resting
      state (and the reduced-motion state) is every task already on our side
      and one line left on theirs: approve the night. -- */
body.venues .desk {
  --desk-gap: 44px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--desk-gap);
  margin-top: 34px;
}
body.venues .desk-col { border-top: 1px solid var(--line); padding-top: 14px; min-width: 0; }
body.venues .desk-col h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 14px;
}
body.venues .desk-ours h3 { color: var(--gold); text-shadow: 0 0 14px rgba(240, 166, 33, 0.35); }
body.venues .desk ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
body.venues .desk li {
  position: relative;
  font-size: 0.95rem;
  line-height: 1.4;
  padding: 9px 14px 9px 36px;
  border: 1px solid var(--line);
  background: linear-gradient(158deg, #24334e 0%, var(--card) 60%);
  color: var(--white);
}
body.venues .desk li::before {
  content: "\2713";
  content: "\2713" / "";
  position: absolute;
  left: 13px;
  top: 8px;
  color: var(--gold);
  font-weight: 700;
}
body.venues .desk .desk-keep {
  border-color: var(--gold);
  box-shadow: 0 0 22px rgba(240, 166, 33, 0.22), inset 0 0 0 1px rgba(240, 166, 33, 0.25);
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gold);
  animation: keepGlow 3.6s ease-in-out infinite;
}
body.venues .desk .desk-keep::before { content: "\2192"; content: "\2192" / ""; color: var(--gold-bright); }
@keyframes keepGlow {
  0%, 100% { box-shadow: 0 0 22px rgba(240, 166, 33, 0.22), inset 0 0 0 1px rgba(240, 166, 33, 0.25); }
  50%      { box-shadow: 0 0 34px rgba(255, 216, 43, 0.45), inset 0 0 0 1px rgba(255, 216, 43, 0.5); }
}
body.venues .desk .desk-spacer { visibility: hidden; border-color: transparent; }
body.venues .desk .desk-spacer::before { content: none; }
/* `backwards` matters: with the default fill, a task waits out its delay in
   the base state (landed and ticked) and then snaps to the 0% frame on the
   venue's desk, an instant swap on the one piece that carries the argument.
   Filled backwards, every task starts on the venue's desk and the first wave
   carries them across one by one. */
body.venues .desk-ours li:not(.desk-spacer) {
  animation: deskMove 17s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
  animation-delay: calc(var(--i, 0) * 1.15s);
  animation-fill-mode: backwards;
  /* Colour fades; the gradient cannot, so it is left to change on the same
     frame rather than promising a fade it does not deliver. */
  transition: color 0.25s ease;
}
body.venues .desk:focus-visible { outline: 2px solid var(--gold); outline-offset: 6px; }
body.venues .desk:focus-visible .desk-ours li:not(.desk-spacer),
body.venues .desk:focus-visible .desk-ours li:not(.desk-spacer)::before { animation-play-state: paused; }
/* Never the text I-beam over the showpieces: they are things to look at,
   not select. */
body.venues .board, body.venues .desk, body.venues .saving, body.venues .pass { cursor: default; }
body.venues .desk-ours li:not(.desk-spacer):hover { color: var(--gold-bright); background: linear-gradient(158deg, var(--line) 0%, var(--card) 60%); }
body.venues .desk-ours li:not(.desk-spacer):hover::before { color: var(--gold-bright); }
body.venues .desk-ours li:not(.desk-spacer)::before {
  animation: deskTick 17s linear infinite;
  animation-delay: calc(var(--i, 0) * 1.15s);
  animation-fill-mode: backwards;
}
@keyframes deskMove {
  0%   { transform: translateX(calc(-100% - var(--desk-gap))); border-color: var(--line-soft); }
  5%   { transform: translateX(calc(-100% - var(--desk-gap))); }
  11%  { transform: translateX(0); border-color: var(--gold); box-shadow: 0 0 24px rgba(240, 166, 33, 0.35); }
  17%  { border-color: var(--line); box-shadow: 0 0 0 rgba(240, 166, 33, 0); }
  80%  { transform: translateX(0); opacity: 1; }
  86%  { transform: translateX(0); opacity: 0; }
  88%  { transform: translateX(calc(-100% - var(--desk-gap))); opacity: 0; }
  94%  { transform: translateX(calc(-100% - var(--desk-gap))); opacity: 1; }
  100% { transform: translateX(calc(-100% - var(--desk-gap))); }
}
@keyframes deskTick {
  0%, 10% { opacity: 0; transform: scale(0.4); }
  13%     { opacity: 1; transform: scale(1.35); text-shadow: 0 0 12px rgba(255, 216, 43, 0.9); }
  18%     { transform: scale(1); text-shadow: none; }
  85%     { opacity: 1; }
  86%, 100% { opacity: 0; }
}
@media (max-width: 560px) {
  body.venues .desk { grid-template-columns: 1fr; gap: 18px; }
  body.venues .desk-ours li:not(.desk-spacer),
  body.venues .desk-ours li:not(.desk-spacer)::before { animation: none; transform: none; opacity: 1; }
  body.venues .desk .desk-spacer { display: none; }
}

/* -- The nine tickets. Each carries a live pulse so the whole wall reads as
      running, and the pulses fall out of phase card by card. The third
      state the cards lacked: pressed sits a hair lower than hovered. -- */
body.venues .stack-cards .card { cursor: default; }
body.venues .stack-cards .card:active { transform: translateY(-1px) scale(0.995); }
body.venues .stack-cards .card h3 { font-size: 1.22rem; padding-left: 19px; text-indent: -19px; }
body.venues .stack-cards .card p { font-size: 0.94rem; }
/* Inline, not absolutely positioned: giving the heading `position: relative`
   for an absolute dot would also capture the ticket number (h3::after), which
   positions against the card, and drag it out of the stub onto the words. */
body.venues .card .live {
  display: inline-block;
  vertical-align: 0.08em;
  margin-right: 10px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 10px rgba(240, 166, 33, 0.7);
  animation: dotPulse 3.2s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * -0.45s);
}
body.venues .card:hover .live { background: var(--gold-bright); box-shadow: 0 0 18px rgba(255, 216, 43, 0.95); }

/* -- The saving draws itself. A ring that fills as it scrolls into view where
      the browser can drive it from the scroll position, and on load where it
      cannot, then keeps turning slowly so the figure never sits dead. The
      numbers are plain text, so they are readable, indexable and countable by
      the price checks whether or not the ring ever draws. -- */
body.venues .saving {
  display: grid;
  grid-template-columns: 148px minmax(0, 1fr);
  gap: 30px;
  align-items: center;
  margin-top: 34px;
  padding: 26px 30px;
  border: 1px solid var(--line);
  background: linear-gradient(120deg, rgba(240, 166, 33, 0.07), transparent 55%), var(--card);
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
body.venues .saving:hover { border-color: var(--gold); box-shadow: 0 18px 40px -18px rgba(240, 166, 33, 0.4); }
body.venues .ring { width: 148px; height: 148px; animation: ringTurn 32s linear infinite; }
body.venues .ring circle { fill: none; stroke-width: 6; }
body.venues .ring-bg { stroke: var(--line); }
body.venues .ring-fg {
  stroke: var(--gold);
  stroke-linecap: round;
  stroke-dasharray: 327;
  stroke-dashoffset: 62;
  filter: drop-shadow(0 0 6px rgba(240, 166, 33, 0.7));
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  animation: ringDraw 1.8s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    body.venues .ring-fg { animation: ringDraw linear both; animation-timeline: view(); animation-range: entry 10% entry 70%; }
  }
}
@keyframes ringDraw { from { stroke-dashoffset: 327; } to { stroke-dashoffset: 62; } }
@keyframes ringTurn { to { transform: rotate(360deg); } }
body.venues .saving-kick {
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}
body.venues .saving-num {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.1;
  margin-bottom: 8px;
}
body.venues .saving-num b {
  color: var(--gold);
  font-size: clamp(2.6rem, 6vw, 3.8rem);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 26px rgba(240, 166, 33, 0.35);
  transition: color 0.3s ease, text-shadow 0.3s ease;
}
body.venues .saving:hover .saving-num b { color: var(--gold-bright); text-shadow: 0 0 30px rgba(255, 216, 43, 0.6); }
body.venues .saving-sub { color: var(--muted); font-size: 0.95rem; max-width: 46em; }
body.venues .saving-sub b { color: var(--white); font-family: var(--display); font-size: 1.15rem; letter-spacing: 0.02em; }
@media (max-width: 640px) {
  body.venues .saving { grid-template-columns: 1fr; justify-items: start; }
  body.venues .ring { width: 112px; height: 112px; }
}

/* -- The pass: Yannai's line, set in print italics against the display type
      everywhere else on the page. A light travels down the left rule so
      even the quiet section is moving. -- */
body.venues .proof { position: relative; }
body.venues .pass {
  position: relative;
  margin: 0;
  padding: 10px 0 10px 36px;
  max-width: 54em;
}
body.venues .pass::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, transparent, var(--gold) 30%, var(--gold-bright) 50%, var(--gold) 70%, transparent);
  background-size: 100% 300%;
  animation: passLight 5.5s ease-in-out infinite;
}
@keyframes passLight { 0% { background-position: 0 100%; } 100% { background-position: 0 -100%; } }
body.venues .pass blockquote { margin: 0; }
body.venues .pass blockquote p {
  font-family: 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-size: clamp(1.35rem, 2.6vw, 1.9rem);
  line-height: 1.4;
  color: var(--white);
  text-wrap: pretty;
}
body.venues .pass blockquote p::before { content: "\201C"; color: var(--gold); margin-right: 2px; }
body.venues .pass blockquote p::after { content: "\201D"; color: var(--gold); margin-left: 2px; }
body.venues .pass figcaption {
  margin-top: 16px;
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.8rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}
body.venues .pass figcaption b { color: var(--gold); font-weight: 600; }

/* -- Motion off. The site-wide reduced-motion rule above uses `*`, which never
      matches a pseudo-element, so the pieces of this page that live on
      ::before and ::after would keep moving for the one visitor who asked
      them not to. Named here, so the desk sits landed with every tick showing,
      the stage light holds still and the quote's rule is a plain gold line. -- */
@media (prefers-reduced-motion: reduce) {
  body.venues::before,
  body.venues::after,
  body.venues .desk li::before,
  body.venues .desk .desk-keep,
  body.venues .pass::before {
    animation: none !important;
  }
  body.venues .pass::before { background: var(--gold); }
}
