html {
  scroll-behavior: smooth;
}
.site-nav {
  /* fixed, not sticky: some browsers paint a sticky element's translucent
     background as solid on the very first frame and only correct it
     after a scroll-triggered repaint (independent of backdrop-filter —
     it happened with and without it). fixed is promoted to its own
     compositing layer from the start, avoiding that class of bug. It
     no longer reserves space in normal flow, so the content right
     after it (.hero, and <main> on the demo page) carries matching
     top padding to clear it. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  padding: 1rem 1.5rem;
  /* Plain alpha background, no backdrop-filter. backdrop-filter's blur
     depends on GPU compositing that isn't reliable across every
     browser/driver combo — when it fails, some renderers fall back to
     a blank/black backdrop source, so even this rgba's own transparency
     ends up blending against black instead of the photo (looks fully
     opaque, not just unblurred). Plain background-color transparency is
     ordinary alpha compositing with no such failure mode. */
  background: rgba(20, 21, 26, 0.45);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  transition: background-color 0.25s ease;
}
.site-nav.scrolled {
  /* Once scrolled, the bar sits over body text rather than the hero
     photo; at 0.28 that text read through it and clashed with the nav
     links (2026-09-28). Near-opaque keeps a hint of depth without the
     show-through. */
  background: rgba(20, 21, 26, 0.85);
}
.nav-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.nav-brand {
  color: var(--text);
  text-decoration: none;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.nav-links {
  display: flex;
  gap: 1.5rem;
}
.nav-links a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.nav-links a:hover {
  color: var(--accent);
}
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 22px;
  height: 22px;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 100%;
  height: 2px;
  background: var(--muted);
  border-radius: 1px;
  transition: transform 0.2s ease, opacity 0.2s ease, background-color 0.2s ease;
}
/* (hover: hover) excludes touchscreens — without it, tapping the
   button (which has no mouse to later move away and clear :hover)
   leaves it stuck gold until the visitor taps elsewhere. */
@media (hover: hover) {
  .nav-toggle:hover span {
    background: var(--accent);
  }
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}
/* Below this, brand + 4 links + growing letter-spacing crowd into each
   other (confirmed by testing an emulated phone viewport) — collapse
   the links into a toggled dropdown instead. .nav-links goes absolute
   (relative to .site-nav, the nearest positioned ancestor) so it drops
   out of the flex row entirely, leaving .nav-toggle as the row's last
   flex item and space-between free to push it to the right edge. */
@media (max-width: 700px) {
  .nav-toggle {
    display: flex;
  }
  .nav-links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    background: rgba(20, 21, 26, 0.97);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease;
  }
  .nav-links.open {
    max-height: 300px;
  }
  .nav-links a {
    padding: 1rem 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
  }
}
/* Full-bleed background band (same treatment .gigs uses on the home
   page) so the footer visibly separates from whatever section sits
   above it on any page — .footer-inner below keeps the text itself
   readably constrained, same "wide section, narrow inner" split
   already used by .about/.gigs/.contact. */
.site-footer {
  background: #17181e;
  text-align: center;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.6;
  padding: 3rem 1.25rem 2.5rem;
}
.footer-inner {
  max-width: 640px;
  margin: 0 auto;
}
.footer-links {
  margin: 0 0 1.25rem;
  font-size: 0.9rem;
  letter-spacing: 0.02em;
}
.footer-links a {
  color: var(--muted);
  text-decoration: none;
}
.footer-links a:hover {
  color: var(--accent);
}
.site-footer .build-time {
  display: block;
  font-size: 0.85em;
  margin-top: 0.35rem;
}

/* Toasts (site/assets/js/toast.js), on any page that has a toast region:
   top centre, just under the fixed nav bar, above everything else. Fades
   out over 0.5s. */
.toast-region {
  position: fixed;
  top: 4.75rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  width: min(90vw, 440px);
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  background: rgba(20, 21, 26, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  color: var(--text);
  opacity: 1;
  transition: opacity 0.5s ease;
}
.toast.toast-hiding {
  opacity: 0;
}
.toast p {
  margin: 0;
  flex: 1;
  line-height: 1.5;
}
.toast a {
  color: var(--accent);
}
.toast-close {
  background: none;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  font: inherit;
  line-height: 1;
  padding: 0.2rem;
}
.toast-close:hover,
.toast-close:focus-visible {
  color: var(--text);
}
@media (prefers-reduced-motion: reduce) {
  .toast {
    transition: none;
  }
}
/* The /listen/ password page (site/listen/index.html). */
:root {
  color-scheme: dark;
  --bg: #14151a;
  --text: #e8e8ec;
  --muted: #a4a9b3;
  --accent: #d8b36a;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
.access-page {
  max-width: 420px;
  margin: 0 auto;
  /* Top padding clears the fixed .site-nav, same as the other pages. */
  padding: calc(4rem + 4rem) 1.5rem 6rem;
  text-align: center;
}
.access-page h1 {
  color: var(--accent);
  font-size: clamp(2rem, 5vw, 2.6rem);
  font-weight: 700;
  margin: 0 0 1rem;
}
.access-page > p {
  color: var(--muted);
  line-height: 1.6;
  margin: 0 0 2rem;
}
.access-form {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  text-align: left;
}
.access-form label {
  color: var(--muted);
  font-size: 0.9rem;
  font-weight: 500;
}
.access-form input {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  padding: 0.65rem 0.85rem;
}
.access-form input:focus {
  outline: none;
  border-color: var(--accent);
}
.access-error {
  color: #e08585;
  font-size: 0.95rem;
  margin: 0.4rem 0 0;
}
/* Same look as the home page's .link buttons. */
.access-button {
  align-self: center;
  margin-top: 1.5rem;
  background: none;
  color: var(--accent);
  font-family: inherit;
  font-size: 1.2rem;
  font-weight: 500;
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 0.75rem 1.5rem;
  cursor: pointer;
}
.access-button:hover {
  background: var(--accent);
  color: var(--bg);
}
.access-page .access-help {
  font-size: 0.95rem;
  margin: 2.5rem 0 0;
}
.access-help a {
  color: var(--accent);
}
