/* Self-hosted so the fonts are preloaded on every page (no flash of
   fallback-font text while Google Fonts loads). Latin subset, variable. */
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/oswald-latin.woff2') format('woff2');
}

@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../fonts/newsreader-latin.woff2') format('woff2');
}

:root {
  --bg: #16130d;
  --bg-alt: #f4f4f4;
  --accent: #e8d9a0;
  --logo-red: #6d0c2e;
  --text: #f5f2ea;
  --text-dim: #c9c2b0;
  --font-heading: 'Oswald', 'Arial Narrow', sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

* , *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scrollbar-gutter: stable;
  background: var(--bg);
  /* iOS otherwise inflates text it thinks is too small, which re-wraps it */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* Page-to-page navigation: keep the old page on screen until the new one is
   ready to paint, then crossfade. The nav is pinned as its own layer so it
   doesn't flash or disappear while the rest of the page swaps. (Chrome /
   Edge / Safari; other browsers just navigate normally.) */
@view-transition { navigation: auto; }

.nav { view-transition-name: site-nav; }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: 0.18s; }

::view-transition-group(site-nav) { animation-duration: 0s; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.6;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main { flex: 1 0 auto; width: 100%; }

h1, h2, h3, .nav a {
  font-family: var(--font-heading);
  color: var(--accent);
  letter-spacing: 0.03em;
}

a { color: var(--accent); }

.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 1.25rem;
}

.nav {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  gap: 1.5rem;
  align-items: center;
  padding: 1.25rem;
  background: var(--bg-alt);
}

.nav a {
  flex-shrink: 0;
  text-decoration: none;
  font-size: 0.95rem;
  text-transform: uppercase;
  opacity: 0.75;
  transition: color 0.15s ease;
}

.nav a:hover {
  color: var(--logo-red);
  opacity: 1;
}

.nav-logo {
  display: none;
  align-items: center;
  margin-right: 0.5rem;
  opacity: 1;
}

.nav-logo:not([href]) { cursor: default; } /* the home page's logo isn't a link */

.nav-logo img {
  height: 32px;
  width: auto;
  display: block;
}

@media (min-width: 720px) {
  .nav-logo { display: flex; }
}

.nav a[aria-current="page"] {
  opacity: 1;
  border-bottom: 2px solid var(--accent);
}

.nav a[aria-current="page"]:hover {
  border-bottom-color: var(--logo-red);
}

.sticky-header {
  position: sticky;
  top: 0;
  z-index: 10;
}

.page-title-bar {
  max-width: 1100px;
  margin: 0 auto;
  padding: 2.5rem 1.25rem 1.5rem;
  background: var(--bg);
  text-align: center;
}

.page-title { margin: 0; }

.year-tabs-bar {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 1.25rem 1rem;
  background: var(--bg);
}

.site-footer {
  flex-shrink: 0;
  padding: 2rem 1.25rem;
  text-align: center;
  color: var(--text-dim);
  font-size: 0.85rem;
}

.site-footer--overlay {
  flex-shrink: 0;
  color: var(--text);
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
}

.empty-state {
  color: var(--text-dim);
  font-style: italic;
  padding: 2rem 0;
}

@media (min-width: 720px) {
  .nav { padding: 1.5rem 2.5rem; }
}

.year-tabs {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  justify-content: center;
}

.year-tab {
  font-family: var(--font-heading);
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 1.5rem;
  padding: 0.25rem 0;
  cursor: pointer;
  border-bottom: 2px solid transparent;
}

.year-tab--active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.75rem;
}

.gallery-item {
  border: none;
  padding: 0;
  background: none;
  cursor: pointer;
  overflow: hidden;
  border-radius: 4px;
  transition: transform 0.15s ease;
  aspect-ratio: 3 / 4;
}

.gallery-item:hover { transform: translateY(-3px); }

/* Tiles fade in with a short stagger set by js/gallery.js (--i). Plain
   animation, so tiles always end up visible. */
.gallery-item {
  animation: roster-fade-in 0.7s ease both;
  animation-delay: calc(var(--i, 0) * 40ms);
}

@media (prefers-reduced-motion: reduce) {
  .gallery-item { animation: none; }
}

.gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; }

.lightbox {
  position: fixed;
  inset: 0;
  background: rgba(10, 8, 5, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  touch-action: pinch-zoom; /* swipes are handled in js/gallery.js */
}

.lightbox[hidden] { display: none; }

.lightbox-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  max-width: 85vw;
}

.lightbox img {
  max-width: 85vw;
  max-height: 68vh;
  user-select: none;
  -webkit-user-drag: none;
}

.lightbox-caption { text-align: center; }

.lightbox-caption-text { color: var(--text); font-size: 1rem; margin: 0; }

.lightbox-credit { color: var(--text-dim); font-size: 0.85rem; margin: 0.25rem 0 0; }

.lightbox-credit:empty { display: none; }

.lightbox button {
  background: none;
  border: none;
  color: var(--accent);
  font-size: 2rem;
  cursor: pointer;
}

.lightbox-close { position: absolute; top: 1.5rem; right: 1.5rem; }

.lightbox-nav {
  position: absolute;
  left: 50%;
  bottom: 2.5rem;
  transform: translateX(-50%);
  display: flex;
  gap: 3rem;
}

.lightbox-nav button { font-size: 3.5rem; }

.setlist {
  list-style: decimal;
  padding-left: 1.5rem;
  margin-top: 1.5rem;
  font-size: 1.25rem;
  max-width: 800px;
  margin-left: auto;
  margin-right: auto;
}

.setlist li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--bg-alt);
}

/* Desktop: pull the song and performer text in toward the middle; the row's
   rule (its bottom border) still runs the full width. */
@media (min-width: 720px) {
  .setlist li { padding-left: 1rem; padding-right: 1rem; }
}

.setlist-footnote {
  max-width: 800px;
  margin: 1rem auto 0;
  font-size: 1rem;
  color: var(--text-dim);
  text-align: center;
}

.setlist-performer { color: var(--text-dim); }

.setlist-song { font-weight: 600; }

.bio {
  max-width: 65ch;
  margin: 1.5rem 0 2rem;
  color: var(--text-dim);
  text-align: justify;
  hyphens: auto; /* keeps the word spacing even in narrow columns */
}

.bio p + p {
  margin-top: 1rem;
}

.about-copy .bio {
  font-weight: 700;
}

.bio a {
  text-decoration: none;
  transition: color 0.15s ease;
}

.bio a:hover {
  color: var(--logo-red);
}

.about-feature {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2rem;
  align-items: center;
  margin-top: 2rem;
}

.about-poster-figure {
  order: 1;
  flex: 0 0 320px;
  width: 320px;
  margin: 0;
}

.about-poster {
  width: 100%;
  height: auto;
  border-radius: 4px;
  display: block;
}

.about-poster-figure figcaption {
  margin-top: 0.5rem;
  color: var(--text-dim);
  font-size: 0.85rem;
  text-align: center;
}

.about-copy {
  order: 2;
  flex: 0 1 auto;
  min-width: 280px;
}

.about-copy .bio {
  max-width: 56ch;
}

.scroll-hint {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  transform: translateX(-50%);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 2.5rem;
  padding: 0 1rem 0 1.15rem;
  border-radius: 999px;
  background: rgba(22, 19, 13, 0.9);
  border: 1px solid var(--accent);
  color: var(--accent);
  font-family: var(--font-heading);
  font-size: 0.9rem;
  letter-spacing: 0.03em;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.scroll-hint svg {
  width: 1.1rem;
  height: 1.1rem;
  flex-shrink: 0;
}

.scroll-hint--visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

@keyframes scroll-hint-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(4px); }
}

.scroll-hint--visible svg {
  animation: scroll-hint-bounce 1.6s ease-in-out infinite;
}

/* On narrow screens the centred pill would sit on top of the theme toggle
   (bottom-left), so it moves to the bottom-right instead. */
@media (max-width: 519px) {
  .scroll-hint {
    left: auto;
    right: 1rem;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-hint--visible svg { animation: none; }
}

.roster-grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
}

.roster-item {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  background: var(--bg-alt);
  padding: 1rem;
  border-radius: 4px;
  height: 12.4rem;
  overflow: hidden;
}

@keyframes roster-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Cards fade in with a stagger set by js/roster.js (--i). */
.roster-item {
  animation: roster-fade-in 0.7s ease both;
  animation-delay: calc(var(--i, 0) * 45ms);
}

/* Photos fade in just after their card, on the same stagger. This is a
   plain animation, so photos always end up visible even if a script fails
   or is cached from an older version. */
img.roster-photo {
  animation: roster-fade-in 0.8s ease both;
  animation-delay: calc(var(--i, 0) * 45ms + 150ms);
}

@media (prefers-reduced-motion: reduce) {
  .roster-item,
  img.roster-photo { animation: none; }
}

.roster-photo {
  flex-shrink: 0;
  width: 4.5rem;
  height: 6rem;
  border-radius: 4px;
  object-fit: cover;
  background: var(--bg);
}

.roster-photo--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed var(--text-dim);
}

.roster-photo--placeholder svg {
  width: 1.6rem;
  height: 1.6rem;
  color: var(--text-dim);
  opacity: 0.5;
}

.roster-info {
  flex: 1 1 auto;
  min-width: 0;
}

.roster-name {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--accent);
}

.roster-credit {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  font-size: 0.95rem;
  color: var(--text-dim);
  margin-top: 0.25rem;
}

.roster-years {
  display: block;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--text-dim);
  opacity: 0.75;
  margin-top: 0.25rem;
}

.house-band-grid {
  --hb-size: min(190px, 40vw);
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2rem 1.5rem;
  margin-top: 1.5rem;
}

.house-band-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: var(--hb-size);
  text-align: center;
}

/* Wide screens: the five cards span the full content width, so the row lines
   up with the edges of the Gallery grid. */
@media (min-width: 1000px) {
  .house-band-grid { justify-content: space-between; column-gap: 1.5rem; }
  .house-band-item { width: calc((100% - 4 * 1.5rem) / 5); }
  .house-band-photo { width: 100%; height: auto; aspect-ratio: 1; }
}

.house-band-photo {
  width: var(--hb-size);
  height: var(--hb-size);
  border-radius: 8px;
  object-fit: cover;
  background: var(--bg-alt);
}

.house-band-photo--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed var(--text-dim);
}

.house-band-photo--placeholder svg {
  width: 3rem;
  height: 3rem;
  color: var(--text-dim);
  opacity: 0.5;
}

.house-band-name {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--accent);
  margin-top: 0.75rem;
}

.house-band-credit {
  display: block;
  font-size: 0.95rem;
  color: var(--text-dim);
  margin-top: 0.25rem;
}

.house-band-instruments {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.6rem;
  color: var(--accent);
  opacity: 0.85;
}

.instrument-icon {
  width: 2.4rem;
  height: 2.4rem;
}

body.home {
  height: 100vh;
  overflow: hidden;
}

body.home main {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}

.hero-bg {
  position: relative;
  flex: 1 1 auto;
  min-height: 480px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero-bg-track {
  position: absolute;
  inset: 0;
}

.hero-bg-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 2.4s ease-in-out;
}

/* js/hero-photos.js marks the current photo "is-active" and rotates it on
   a plain setInterval — no CSS animation timeline to fall out of sync with,
   so it's immune to slow image loads shifting which photo looks current.
   The first photo carries this class from the initial render (see
   buildHeroPhotosHtml), so it's already fully visible with no fade-in. */
.hero-bg-photo.is-active {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .hero-bg-photo { transition: none; }
}

.hero-bg-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(22, 19, 13, 0.5) 0%, rgba(22, 19, 13, 0.75) 100%);
}

.hero-stack {
  position: relative;
  z-index: 2;
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.hero-overlay-content {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.1rem;
  text-align: center;
  padding: 2rem 1.25rem;
}

.hero-logo {
  width: auto;
  height: auto;
  max-width: min(480px, 80vw);
  max-height: 42vh;
  filter: drop-shadow(0 12px 32px rgba(0, 0, 0, 0.55));
}

.hero-overlay-content h1 { margin: 0; }

@media (min-width: 720px) {
  .hero-overlay-content {
    transform: translateY(-2.5rem);
  }
}

.tagline {
  max-width: 62ch;
  line-height: 1.4;
  text-wrap: balance;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 1.05rem;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7);
}

/* Logo, then tagline, fade in on load. Plain animation with fill-mode
   "both", so both always end fully visible. */
@keyframes hero-content-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.hero-logo {
  animation: hero-content-fade-in 1.6s ease-out both;
}

.tagline {
  animation: hero-content-fade-in 1.6s ease-out 0.6s both;
}

.hero-contact {
  font-family: var(--font-heading);
  font-size: 1.1rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--accent);
  background: var(--logo-red);
  border: 1px solid var(--logo-red);
  border-radius: 4px;
  padding: 0.75rem 2rem;
  margin-top: 1rem; /* on top of the hero's flex gap */
  animation: hero-content-fade-in 1.6s ease-out 1s both;
  transition: filter 0.15s ease;
}

.hero-contact:hover,
.hero-contact:focus-visible {
  filter: brightness(1.2);
}

/* The line break after "concert" only applies on phones. */
.tagline-break { display: none; }

/* Phones: bigger sentence-case type, broken after "Dylan" into two lines. */
@media (max-width: 719px) {
  .hero-overlay-content { padding-left: 0.5rem; padding-right: 0.5rem; }
  .tagline-break { display: inline; }
  .tagline {
    /* Sentence case is much narrower than all caps, so it can be bigger and
       still fit on two lines; it scales with the width of the screen. */
    text-transform: none;
    font-size: clamp(0.8rem, 4.75vw, 1.4rem);
    letter-spacing: 0;
    max-width: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-logo,
  .tagline,
  .hero-contact { animation: none; }
}

@media (max-width: 719px) {
  .page-title-bar {
    padding: 1.25rem 1.25rem 0.75rem;
  }

  /* The nav arrows are pinned to the bottom of the viewport on desktop,
     where there's room below a centered photo+caption. On short phone
     screens a tall photo's caption can reach that low, so here the arrows
     stack in normal flow below the caption instead of floating over it,
     and the whole lightbox scrolls if it's still taller than the screen. */
  .lightbox {
    flex-direction: column;
    justify-content: flex-start;
    padding: 4.5rem 1.25rem 2rem;
    gap: 1.25rem;
    overflow-y: auto;
  }

  .lightbox-nav {
    position: static;
    transform: none;
  }

  .gallery-grid {
    grid-template-columns: 1fr;
  }

  .gallery-item {
    aspect-ratio: auto;
  }

  .gallery-item img {
    height: auto;
  }

  .about-poster-figure {
    flex-basis: 100%;
    width: 100%;
    max-width: 320px;
    margin: 0 auto;
  }

  .setlist li {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
  }

  .contact-page .bio {
    margin: 1rem 0 1.25rem;
  }

  .contact-form {
    margin-top: 1rem;
    gap: 0.85rem;
  }

  .form-row {
    gap: 0.85rem;
  }

  .form-field {
    gap: 0.3rem;
  }

  .field-error {
    min-height: 0;
  }
}

.contact-main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: 0.5rem;
  padding-bottom: 0.75rem;
}

.contact-page {
  max-width: 560px;
  margin: 0 auto;
  width: 100%;
}

.contact-page .bio {
  margin: 0.75rem 0 1.25rem;
}

.contact-form {
  margin-top: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  background: var(--bg-alt);
  border-top: 3px solid var(--accent);
  border-radius: 8px;
  padding: 1.5rem 1.75rem;
}

.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-row {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

.form-row .form-field {
  flex: 1 1 200px;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.form-field label {
  font-size: 0.8rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.form-field input,
.form-field textarea {
  background: var(--bg);
  border: 1px solid rgba(201, 194, 176, 0.25);
  border-radius: 6px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 0.75rem 0.9rem;
  transition: border-color 0.15s ease;
}

.form-field input:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--accent);
}

.form-field textarea {
  resize: vertical;
}

.field-error {
  color: #e08a8a;
  font-size: 0.85rem;
  min-height: 1.1em;
}

.form-submit {
  align-self: flex-start;
  background: var(--accent);
  color: var(--bg);
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 0.7rem 1.75rem;
  font-family: var(--font-heading);
  font-size: 1rem;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: filter 0.15s ease;
}

.form-submit:hover:not(:disabled) {
  filter: brightness(0.92);
}

.form-submit:disabled {
  opacity: 0.6;
  cursor: default;
}

.contact-status {
  font-size: 0.9rem;
  min-height: 1.2em;
}

.contact-status--success { color: var(--accent); }

.contact-status--error { color: #e08a8a; }
