/* =========================================================
   AUSTAL MUSIC — STYLESHEET
   Mobile-first: base rules below target small screens (this
   is where ~90% of traffic lands), enhancements for larger
   screens live in the min-width media query at the bottom.
   Structure follows r3hab.com (dark, single-column,
   music/tour-dates-forward, big tap-friendly CTAs).

   Brand system v1 (from Austin's web guidelines image):
     AUSTAL Black    #171717
     AUSTAL Gray     #252525
     AUSTAL White    #F2F0EF
     AUSTAL Infrared #FF574D
   Only those 4 colors are officially defined. Border/muted-text
   values below are opacity variants of White rather than new
   hardcoded grays, so everything still derives from the 4
   official tokens — flag if a literal 5th gray was intended
   instead.
   ========================================================= */

@font-face {
  font-family: 'Integral CF';
  src: url('fonts/IntegralCF-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Integral CF';
  src: url('fonts/IntegralCF-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Integral CF';
  src: url('fonts/IntegralCF-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Mundial (body copy) loads via Adobe Fonts/Typekit — the
   <link rel="stylesheet" href="https://use.typekit.net/usz1uuq.css">
   tag is added to each page's <head>, above this stylesheet's
   own <link> so Mundial is requested as early as possible. */

:root {
  /* --- brand palette --- */
  --bg: #171717;             /* AUSTAL Black */
  --bg-alt: #252525;         /* AUSTAL Gray — cards, inputs, alt surfaces */
  --surface: #252525;        /* AUSTAL Gray */
  --border: rgba(242, 240, 239, 0.14); /* AUSTAL White, low opacity — hairlines */
  --text: #f2f0ef;           /* AUSTAL White */
  --text-muted: rgba(242, 240, 239, 0.62); /* AUSTAL White, reduced opacity */
  --accent: #ff574d;         /* AUSTAL Infrared — labels, active/hover states, primary CTAs */
  --accent-contrast: #171717; /* text color used ON TOP of the Infrared accent */

  /* --- type --- */
  /* Integral CF: headings, eyebrows/labels (self-hosted above).
     Mundial: body copy, served via Adobe Fonts/Typekit — see the
     <link> tag added in each page's <head>. */
  --font-display: 'Integral CF', Arial Black, 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'mundial', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  /* --- spacing scale (mobile default; scales up at desktop bp) --- */
  --space-xs: 0.5rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2.5rem;
  --space-xl: 3.5rem;

  --container: 1100px;
  --nav-h: 56px;
  --tap-min: 48px; /* minimum comfortable touch target */
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500; /* Integral CF Medium, per spec */
  letter-spacing: 0.02em;
  margin: 0 0 var(--space-sm);
}

/* mobile-first fluid type, minimums tuned for small screens */
h1 { font-size: clamp(2rem, 9vw, 4.5rem); }
h2 { font-size: clamp(1.5rem, 6vw, 2.5rem); }
h3 { font-size: 1.15rem; }

p { color: var(--text-muted); margin: 0 0 var(--space-sm); }

a { color: var(--text); text-decoration: none; }

.container {
  width: 100%; /* explicit, not just implicit block-fill — needed since v17: a flex
    item (which every section's .container now is, see "one section = one
    screen" below) with auto side-margins and no explicit width shrinks to
    its content's size instead of stretching, because flexbox auto-margins
    take priority over stretch. Writing width: 100% here is a no-op for the
    non-flex .container usages (nav, footer) and restores the intended
    fill-up-to-max-width-then-center behavior for the flex ones. */
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--space-sm);
}

/* ---------- placeholder blocks ---------- */
.placeholder {
  border: 1px dashed var(--border);
  background: var(--surface);
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  min-height: 110px;
  padding: var(--space-sm);
}

.placeholder--logo {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  margin: 0 auto var(--space-md);
}

.placeholder--photo { aspect-ratio: 4 / 5; }
.placeholder--wide { aspect-ratio: 16 / 9; }
.placeholder--square { aspect-ratio: 1 / 1; }

/* ---------- header / nav (mobile default = collapsed) ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  /* Solid background rather than backdrop-filter: a blur here would
     create a new CSS containing block and break the fixed-position
     mobile nav overlay below (it would get clipped to the header's
     own height instead of covering the full viewport). */
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

/* Homepage-only: transparent nav floating directly over the full-bleed
   hero photo, so just the logo + link text sit on top of the image —
   no bar behind them. Switched to fixed (from the default sticky)
   because sticky still reserves its own height in the layout, which
   would push the hero down instead of letting it render behind the
   nav; fixed removes it from flow entirely. A tiny scroll listener
   (see index.html's inline script) adds .is-scrolled once the user
   scrolls past the hero, at which point it becomes the same solid bar
   used on every other page. */
.site-header--hero {
  position: fixed;
  left: 0;
  right: 0;
  background: transparent;
  border-bottom-color: transparent;
  transition: background 0.25s ease, border-color 0.25s ease;
}

.site-header--hero.is-scrolled {
  background: var(--bg);
  border-bottom-color: var(--border);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--nav-h);
}

.nav__brand {
  display: flex;
  align-items: center;
}

/* Centered wordmark used only in the desktop 3-column nav layout —
   hidden by default so mobile just shows the regular left-aligned
   .nav__brand plus the slide-down link list. */
.nav__brand--center {
  display: none;
}

.nav__logo {
  height: 41.25px; /* 22px base, up 25% (v16) then up another 50% per Austin's request — logo is wide/flat, so sized by height to fit the 56px mobile nav bar */
  width: auto;
  display: block;
}

.nav__toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  background: none;
  border: none;
  color: var(--text);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
}

/* full-screen slide-down menu on mobile — big, thumb-friendly links.
   inset spans the FULL viewport (not just below the header) so that
   translateY(-100%) parks it completely off-screen when closed —
   sizing it to start at --nav-h instead would leave its closed
   position overlapping the header row itself. padding-top pushes
   the actual link content below the header once it's open.
   .nav__links is now a <div> wrapping two <ul> link groups plus the
   centered brand mark (rather than one flat <ul>), so the desktop
   layout below can lay all three out side by side in one row while
   mobile just stacks them in a single centered column. */
.nav__links {
  position: fixed;
  inset: 0;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-lg);
  padding: var(--space-md);
  padding-top: calc(var(--nav-h) + var(--space-md));
  transform: translateY(-100%);
  transition: transform 0.25s ease;
  pointer-events: none; /* belt-and-suspenders: never eat clicks while closed */
}

.nav__links.is-open {
  transform: translateY(0);
  pointer-events: auto;
}

.nav__links-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-lg);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__links-group a {
  font-size: 1.25rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  padding: var(--space-xs) var(--space-sm);
}

.nav__links-group a:active,
.nav__links-group a[aria-current="page"] {
  color: var(--accent);
}

/* ---------- section rhythm (tighter on mobile) ---------- */
section {
  padding: var(--space-xl) 0;
}

/* ---------- one fluid scroll (v38, reverts v17/v22) ----------
   v17 locked every non-hero section to exactly one screen tall
   (height: 100vh minus the nav bar) with internal overflow-y: auto
   scrolling for anything that didn't fit, plus a v22 `safe center`
   fix so an overflowing section's own heading couldn't get scrolled
   out of reach. Austin tried it, decided he doesn't want the
   inner-scroll-per-section feel after all, and asked for one
   continuous page scroll instead — sections just take up whatever
   height their content needs, and he'll size individual sections by
   hand from here as needed rather than have every section fight to
   fit one viewport. So: no more forced height, no flex-centering, no
   internal overflow — sections are back to plain block boxes, sized
   by their content plus the padding above. Two things elsewhere in
   this file existed only to serve the old locked-height system and
   were reverted alongside it — see the desktop Events & Venues grid
   (`.venues-grid`'s old `max-height: calc(100vh - 22rem)` cap, below)
   and the note on `.about-intro__grid`'s `height: 100%` (that rule is
   left in place but is now inert/harmless: a percentage height
   against a parent with no explicit height of its own simply computes
   as auto, so the about-intro photo now naturally matches the bio
   column's content height instead of a locked full-screen height). */

/* ---------- scroll-in reveal (fade + slide up) ----------
   Applied via JS (see the inline <script> at the bottom of each page)
   to every <section> except .hero, which is visible immediately on
   load and never gets this treatment. .reveal-init is the hidden
   starting state; .is-visible is added by an IntersectionObserver the
   first time a section scrolls into view, and isn't removed again —
   this is a one-time entrance, not a repeating scroll effect. */
section.reveal-init {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

section.reveal-init.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  section.reveal-init {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

.section-label {
  font-family: var(--font-display);
  font-weight: 400; /* Integral CF Regular, per spec's "EYEBROW" sample */
  color: var(--accent); /* AUSTAL Infrared #FF574D, per the web guidelines doc */
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  margin-bottom: 0.35rem; /* tighter gap so the eyebrow sits close under the heading below it */
}

.section-head {
  margin-bottom: var(--space-md);
}

.section-head .btn { margin-top: var(--space-xs); }

/* ---------- section titles (recurring pattern) ----------
   The big heading that opens a content section — either wrapped in
   .section-head (EVENTS & VENUES, SETS & MIXES, and live-sets.html's
   own <h1> reuse of that same markup, Upcoming Shows) or following an
   eyebrow .section-label directly with no .section-head wrapper
   (Contact, General Inquiries). Sized up, set to Bold, and tightened
   from the base h1/h2 rule above so these read as a heavier, more
   condensed headline treatment (reference: a section heading style
   Austin pointed to on nexuprecz.com) — the max-width below keeps
   multi-word titles from running the full section width, so they wrap
   onto two lines instead of sitting on one. A single-word title like
   "Contact" won't wrap no matter the width (breaking a single word
   mid-letter would look broken, so this doesn't force that) — it just
   renders large and bold on one line instead. (The gallery section
   used to carry a title here too — "Press & Live Photos" — removed
   per Austin's request; see .gallery .section-label below.) */
.section-head h1,
.section-head h2,
.section-label + h2 {
  font-weight: 700; /* Integral CF Bold */
  font-size: clamp(2.75rem, 8vw, 4.75rem);
  line-height: 0.9;
  letter-spacing: -0.02em;
  max-width: 7em; /* scales with the clamp()'d font-size above; ~530px at the desktop max, narrow enough to force EVENTS & VENUES / SETS & MIXES / Upcoming Shows / General Inquiries onto two lines there without over-wrapping on smaller screens */
  text-wrap: balance; /* even split across the forced line-wrap, rather than a lopsided first/second line */
}

/* ---------- about intro (home — directly under the hero) ----------
   Photo + copy, two-up on desktop. The section's own top/bottom
   padding is zeroed out here so .about-intro__media can bleed flush
   to the section's true edges (photo fills the full section height,
   left edge flush with the true left edge of the browser window on
   desktop, per Austin's mockup); .about-intro__inner supplies its own
   padding for the copy instead of relying on .container, since the
   copy no longer needs to be centered in a max-width column — it sits
   left-justified within the right half. */
.about-intro {
  padding: 0;
  /* Matches the page's default background (AUSTAL Black) — this is
     what the photo-fade gradient below blends into on the About page.
     .about-intro--home overrides it to that instance's own darker
     background so the fade always matches whichever color is actually
     behind the section, on either page, without hardcoding it twice. */
  --intro-bg: #171717;
}

/* Homepage-only background tweak (v39): a touch darker than the AUSTAL
   Black page background, per Austin's request — scoped to this one
   instance via .about-intro--home (added only on index.html's copy of
   this section) rather than the shared .about-intro class, since the
   About page reuses the exact same section/class and wasn't mentioned.
   Flag if this was meant to apply there too. */
.about-intro--home {
  background: #0d0d0d;
  --intro-bg: #0d0d0d;
}

.about-intro__grid {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}

.about-intro__media {
  aspect-ratio: 4 / 3;
  position: relative; /* anchors the fade overlay below */
}

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

/* Photo-to-background fade (v42, widened v43): a soft blend where the
   photo meets the section's own background color, rather than a
   hard-edged cut. The outer ~20% of the photo is touched — transparent
   the rest of the way, so the fade reads as a subtle edge treatment,
   not a wash over the whole image (widened from the original ~10% for
   a smoother, more gradual transition). Mobile: photo sits above the
   copy, so the blend runs along the bottom edge (to bottom). Desktop
   swaps this to the right edge instead, where the photo meets the copy
   column — see the override in the min-width: 780px block below.
   Uses the --intro-bg custom property set above so the exact color
   always matches whichever background is actually behind the photo
   on that page/instance, home or About, without duplicating hex
   values in two places. */
.about-intro__media::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent 0%, transparent 80%, var(--intro-bg) 100%);
}

.about-intro__inner {
  padding: var(--space-lg) var(--space-sm);
  max-width: 40rem; /* keeps the bio a comfortable reading width once there's room */
}

.about-intro__inner p:not(.section-label) {
  color: var(--text);
}

.about-intro__social {
  /* Mobile only, effectively — see the 780px-up override below. On
     mobile .about-intro__inner is a plain block, so this margin-top
     collapses with the last <p>'s own var(--space-sm) bottom margin
     (adjacent sibling margins collapse to the larger of the two, they
     don't add), so the visible gap was staying stuck at 16px no
     matter how tight things looked. Bumped to --space-lg so the
     collapsed gap is actually bigger instead of a no-op. */
  margin-top: var(--space-lg);
  justify-content: flex-start;
}

/* ---------- events & venues (home) ----------
   Mobile (v46, replaces the v22 single-column/4-logo layout): a 2
   column x 4 row grid showing 8 of the 9 logos — Breakaway, House
   Vibrations / G, Dahlia's / Gallery House, Novelty House / SYN,
   Canopy — per Austin's mockup. Hermanita is the one tile dropped
   from mobile entirely (display: none), same technique as v22: the
   DOM order itself stays the desktop 3x3 reading order, and `order`
   on the 8 visible tiles re-sequences them into the mockup's
   row-by-row reading order without touching the markup. Desktop
   (780px+) is completely unaffected — still the original 3x3 grid
   with all 9 logos. Logos float directly on the section's own
   background (no card background/border) — they're white/light marks
   on transparent PNGs, so the background does the job. No eyebrow
   label on this section's heading (removed per Austin's request);
   the title itself is centered and set in AUSTAL Infrared instead of
   the usual White. */
.venues {
  /* First leg of a page-wide alternating gradient (v44, per Austin's
     request): every homepage section from here down trades the same
     two tones — #0d0d0d and #171717 (AUSTAL Black) — flipping
     direction each time, so each section's top stop matches the
     previous section's bottom stop and the whole page reads as one
     continuous fade rather than flat color blocks. This section
     starts at #0d0d0d (matching .about-intro--home just above it) and
     eases down to #171717, which .sets-carousel below then opens
     with. See that section, .upcoming-teaser, .contact-hero, and
     .gallery for the rest of the chain. */
  background: linear-gradient(to bottom, #0d0d0d, #171717);
}

.venues .section-head {
  text-align: center;
  justify-content: center; /* overrides .section-head's desktop space-between — there's only the one centered heading here */
}

.venues .section-head h2 {
  color: var(--accent); /* AUSTAL Infrared #FF574D, per Austin's request */
  /* .section-head is only display:flex from 780px up (see the desktop
     media query below), so justify-content:center above has nothing to
     act on below that width — on mobile this h2 is a plain block, and
     its own max-width:7em (from the shared section-title rule) was
     leaving it flush against the left edge of .section-head even
     though the text inside it was centered. margin-inline:auto centers
     the box itself at every width, so it also just no-ops harmlessly
     once justify-content:center takes over on desktop. */
  margin-inline: auto;
}

/* Wider max-width than the site's usual 1100px container (v39), just
   for this section, so the logo grid has more room to breathe and each
   logo can render a little larger — a scoped override rather than
   raising the global --container, which would also widen the nav,
   Sets & Mixes, Upcoming Shows, Contact, and footer. */
.venues .container {
  max-width: 1400px;
}

.venues-grid {
  display: grid;
  grid-template-columns: 1fr;
  /* Mobile only — the 780px-up override below replaces this with its
     own 3-column gap. Was var(--space-md) (24px); Austin flagged the
     single-column mobile stack as too much blank space between logos,
     so this is tightened down. */
  gap: 0.75rem;
}

/* Each logo fades + slides up on its own, staggered slightly so they
   don't all pop in at once — triggered by .venues picking up the
   site-wide .is-visible class (see the scroll-in reveal rules above)
   the first time the section enters the viewport, same one-time
   entrance as everything else, just one layer more granular. */
.venue-logo {
  /* Mobile only (780px-up override sets height:auto) — was 160px with
     var(--space-sm) padding; both reduced together with the grid gap
     above so the mobile logo stack sits noticeably tighter without
     shrinking the logos themselves more than necessary. Dropped
     further to 100px (from an intermediate 130px) because each venue
     PNG has a lot of transparent canvas margin baked in around the
     actual logo art — at 130px that built-in padding was still
     reading as most of the "blank space" Austin was pointing at, so
     the box itself needed to shrink more than the gap/padding alone
     could fix. */
  height: 100px; /* fixed row height (mobile) so object-fit: contain below has something to size against */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-xs);
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.venues.is-visible .venue-logo {
  opacity: 1;
  transform: translateY(0);
}

.venue-logo:nth-child(1) { transition-delay: 0.03s; }
.venue-logo:nth-child(2) { transition-delay: 0.08s; }
.venue-logo:nth-child(3) { transition-delay: 0.13s; }
.venue-logo:nth-child(4) { transition-delay: 0.18s; }
.venue-logo:nth-child(5) { transition-delay: 0.23s; }
.venue-logo:nth-child(6) { transition-delay: 0.28s; }
.venue-logo:nth-child(7) { transition-delay: 0.33s; }
.venue-logo:nth-child(8) { transition-delay: 0.38s; }
.venue-logo:nth-child(9) { transition-delay: 0.43s; }

/* Mobile-only 2-col/4-row, 8-logo grid + order (v46). Scoped to a
   max-width query (not relying on the desktop media query below to
   reset it) — an unscoped `.venue-logo:nth-child(n)` selector
   outranks the desktop-scoped plain `.venue-logo`/`.venues-grid`
   resets on specificity alone, a gotcha already hit once with v21's
   placement rules. */
@media (max-width: 779px) {
  .venues-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .venue-logo:nth-child(1) { order: 1; } /* Breakaway — row 1, col 1 */
  .venue-logo:nth-child(2) { order: 2; } /* House Vibrations — row 1, col 2 */
  .venue-logo:nth-child(3) { order: 3; } /* Gangstarz (G) — row 2, col 1 */
  .venue-logo:nth-child(4) { order: 4; } /* Dahlia's — row 2, col 2 */
  .venue-logo:nth-child(9) { order: 5; } /* Gallery House — row 3, col 1 */
  .venue-logo:nth-child(5) { order: 6; } /* Novelty House — row 3, col 2 */
  .venue-logo:nth-child(8) { order: 7; } /* Syn — row 4, col 1 */
  .venue-logo:nth-child(6) { order: 8; } /* Canopy — row 4, col 2 */
  .venue-logo:nth-child(7) {
    display: none; /* Hermanita — desktop-only as of v46, per Austin's mockup */
  }
}

.venue-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform 0.25s ease;
}

/* Subtle hover-enlarge (v39) — desktop/pointer devices only (same
   @media (hover: hover) guard as the Gallery's hover effect), so it
   never gets stuck "on" after a tap on mobile. Scales just the <img>,
   not its .venue-logo wrapper, so the grid's own layout/spacing never
   shifts — the logo simply grows slightly past its box. A small
   z-index bump on the wrapper keeps the enlarged logo drawing on top
   of neighboring grid tiles instead of being clipped by paint order. */
@media (hover: hover) {
  .venue-logo:hover {
    position: relative;
    z-index: 2;
  }

  .venue-logo:hover img {
    transform: scale(1.12);
  }
}

@media (prefers-reduced-motion: reduce) {
  .venue-logo {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .venue-logo img {
    transition: none;
  }
}

/* ---------- hero (home) ---------- */
/* Full-viewport photo hero. isolation:isolate gives the three layers
   (photo / scrim / content) their own stacking context so explicit
   z-index on each is all that's needed to keep text on top — without
   it, the absolutely-positioned photo would paint over the normal-flow
   text regardless of source order.
   100svh (small viewport height) is used instead of 100vh so mobile
   Safari/Chrome's collapsing address bar doesn't cut off the bottom of
   the hero — vh includes that hidden space, svh doesn't. The plain vh
   line stays first as a fallback for browsers that don't know svh. */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding-top: var(--space-xl);
  padding-bottom: var(--space-xl);
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%; /* keep the face/subject in frame on tall crops */
  display: block;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* bottom-weighted so the CTA buttons always sit on solid contrast,
     while the top stays closer to the photo's natural exposure */
  background: linear-gradient(
    to bottom,
    rgba(23, 23, 23, 0.25) 0%,
    rgba(23, 23, 23, 0.35) 45%,
    rgba(23, 23, 23, 0.8) 100%
  );
}

.hero__content {
  position: relative;
  z-index: 2;
}

.hero p { max-width: 32ch; }

/* small "keep scrolling" cue pinned to the bottom of the hero photo */
.hero__scroll-cue {
  position: absolute;
  bottom: var(--space-md);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  color: var(--text); /* AUSTAL White #F2F0EF */
  font-family: var(--font-display); /* Integral CF */
  font-weight: 400;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  pointer-events: none; /* purely decorative */
}

.hero__scroll-icon {
  width: 14px;
  height: 14px;
  animation: hero-scroll-bounce 1.8s ease-in-out infinite;
}

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

.hero__actions {
  display: flex;
  flex-direction: column;
  width: 100%;
  gap: var(--space-sm);
  margin-top: var(--space-md);
}

/* ---------- buttons — full-width & tall on mobile for easy tapping ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--tap-min);
  padding: 0.5em 1.5em;
  border: 1px solid var(--text);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.btn--primary {
  background: var(--accent);
  color: var(--text); /* AUSTAL White #F2F0EF */
  border-color: var(--accent);
}
.btn--ghost { background: transparent; color: var(--text); }
.btn--inline { width: auto; }

/* Non-interactive "not booked yet" state (e.g. a show-row date with no
   ticket link yet) — same visual footprint as a real button, but on a
   <span> rather than an <a>, and dimmed so it doesn't read as clickable. */
.btn--disabled {
  opacity: 0.5;
  cursor: default;
}

/* ---------- grids (mobile default = single column) ---------- */
.grid {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: 1fr;
}

/* ---------- gallery (straight grid, flush, no borders) ----------
   Switched from CSS multi-column masonry to a plain CSS grid (per
   Austin's request) — every slot is a fixed 3:4 vertical rectangle
   (aspect-ratio below) with the photo cropped to fill it via
   object-fit: cover, rather than each photo keeping its own natural
   height. Still full-width and zero-gap (grid-template-columns + gap:
   0), just uniform rows instead of a tiled wall. */

/* Fifth and final leg of the alternating gradient (see .venues above,
   in the events & venues section rules): back to .venues'/
   .upcoming-teaser's direction, opening at #0d0d0d (matching
   .contact-hero's bottom stop on the homepage) and easing down to
   #171717, which the footer below (background: var(--bg), the same
   #171717) picks up seamlessly. Reused as-is on about.html, where
   this section follows the page's own (non-gradient) about-intro. */
.gallery {
  background: linear-gradient(to bottom, #0d0d0d, #171717);
}

.gallery__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0;
}

.gallery__item {
  width: 100%;
  margin: 0;
  border: none;
  transition: filter 0.25s ease;
}

img.gallery__item {
  display: block;
  height: auto;
  aspect-ratio: 3 / 4; /* fixed vertical slot per Austin's request — object-fit below crops each photo to fill it */
  object-fit: cover;
}

/* Subtle "light up" hover — desktop/pointer devices only, so it never
   gets stuck "on" after a tap on mobile. Photos are intentionally not
   links/buttons, just a visual gallery wall. */
@media (hover: hover) {
  .gallery__item:hover {
    filter: brightness(1.18);
  }
}

/* ---------- cards ---------- */
.card {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  padding: var(--space-md);
}

.card__meta {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: var(--space-xs);
}

.card .btn { margin-top: var(--space-sm); }

/* ---------- sets carousel (Live Sets page) ----------
   Built to match the "Upcoming Events" section on nexuprecz.com
   (Squarespace) as closely as plain HTML/CSS/JS allows: a heading +
   ghost button row (reuses .section-head, which already does exactly
   this — stacked on mobile, space-between on desktop, no changes
   needed there), then a horizontal row of flush image cards that
   peeks the next card at the edge. The reference site's version is a
   proprietary Squarespace carousel widget (large invisible click
   zones driving a translateX animation) — reimplemented here with
   native CSS scroll-snap instead: overflow-x auto + scroll-snap-type
   gives free touch/trackpad swipe on mobile with no JS, and the two
   arrow buttons just call scrollBy() on desktop. Card proportions
   (407:541 image, ~3:4) and button style (1px white outline,
   uppercase) were measured directly off the reference page and are
   reused as-is; .btn--ghost/.btn--inline already match its ticket
   buttons exactly with zero new button CSS. */
/* Wider max-width than the site's usual 1100px container (v40), same
   scoped-override pattern used for Events & Venues (v39) — more room
   for the carousel's cards rather than raising the global --container.
   Shared by both the homepage and Live Sets page, since they use this
   exact same carousel section/markup. */
/* Second leg of the alternating gradient (see .venues above): reversed
   direction, opening at #171717 (matching .venues' bottom stop) and
   easing up to #0d0d0d, which .upcoming-teaser then opens with. Also
   reused as-is on live-sets.html, where this section sits right under
   the nav (also #171717 / --bg) — the top stop matches seamlessly
   there too. */
.sets-carousel {
  background: linear-gradient(to bottom, #171717, #0d0d0d);
}

.sets-carousel .container {
  max-width: 1400px;
}

.sets-carousel__wrap {
  position: relative;
}

.sets-carousel__track {
  display: flex;
  gap: var(--space-md);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px; /* keeps focus outlines from clipping */
  scrollbar-width: none;
}

.sets-carousel__track::-webkit-scrollbar { display: none; }

.sets-carousel__card {
  flex: 0 0 78%;
  scroll-snap-align: start;
}

.sets-carousel__card .placeholder,
.sets-carousel__card img {
  aspect-ratio: 3 / 4;
  margin-bottom: var(--space-sm);
}

.sets-carousel__card img {
  width: 100%;
  display: block;
  object-fit: cover;
  border-radius: 2px;
}

.sets-carousel__card h3 {
  margin-bottom: 0.15rem;
}

.sets-carousel__meta {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: var(--space-sm);
}

/* Desktop-only prev/next controls — hidden on mobile, which relies on
   native touch-scroll/swipe over .sets-carousel__track instead. */
.sets-carousel__arrow {
  display: none;
}

/* ---------- responsive video embed (Featured Set) ---------- */
/* Taller on mobile (3:4, per Austin's request) than desktop (16:9,
   the standard widescreen embed ratio) — mobile screens are narrow
   enough that 16:9 left the embed quite short; 3:4 gives it more
   vertical presence without needing a fixed pixel height. Desktop
   gets its own override back to 16:9 inside the min-width: 780px
   block below. */
.video-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  background: var(--surface);
  overflow: hidden;
}

.video-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ---------- show / event rows (Upcoming) — stacked on mobile ---------- */
/* Wider max-width than the site's usual 1100px container (v40), same
   scoped-override pattern used for Events & Venues (v39) and Sets &
   Mixes (v40) — .upcoming-teaser only appears on the homepage. */
/* Third leg of the alternating gradient (see .venues above): back to
   .venues' direction, opening at #0d0d0d (matching .sets-carousel's
   bottom stop) and easing down to #171717, which .contact-hero then
   opens with. */
.upcoming-teaser {
  background: linear-gradient(to bottom, #0d0d0d, #171717);
}

.upcoming-teaser .container {
  max-width: 1400px;
}

.show-list { border-top: 1px solid var(--border); }

.show-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xs);
  padding: var(--space-md) 0;
  border-bottom: 1px solid var(--border);
}

.show-row__date {
  font-size: 0.8rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.show-row__details h3 { margin: 0 0 0.25rem; }
.show-row__details p { margin: 0; font-size: 0.9rem; }
.show-row .btn { margin-top: var(--space-xs); }

/* ---------- contact (above-the-fold card) ---------- */
/* A single simple contact card — name, phone, email — plus a Social
   row reusing the exact same .social-icon markup/styling as the site
   footer, per Austin's request. Constrained to a narrower reading
   column (like .about-intro__inner) rather than the full 1100px
   container, since a short card stretched full-width would look
   sparse. */
/* Fourth leg of the alternating gradient (see .venues above): reversed
   again, opening at #171717 (matching .upcoming-teaser's bottom stop)
   and easing up to #0d0d0d, which .gallery then opens with. Also
   reused as-is on contact.html, where this section sits right under
   the nav (also #171717 / --bg) — the top stop matches seamlessly
   there too. */
.contact-hero {
  background: linear-gradient(to bottom, #171717, #0d0d0d);
}

.contact-hero__inner {
  max-width: 30rem;
}

.contact-card {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin: var(--space-md) 0;
}

.contact-card__name {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--text);
  font-size: 1.1rem;
  margin: 0 0 0.15rem;
}

.contact-card__row {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  color: var(--text);
  text-decoration: none;
}

.contact-card__row:hover,
.contact-card__row:focus-visible {
  color: var(--accent);
}

.contact-card__icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.contact-social {
  margin-top: var(--space-md);
}

/* Left-aligned at every breakpoint (not the centered default used
   elsewhere, e.g. the footer) so the icon row lines up under the
   left-aligned name/phone/email rows above it. */
.contact-social .social-row {
  justify-content: flex-start;
}

/* ---------- contact form ---------- */
.form-field { margin-bottom: var(--space-md); }

.form-field label {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}

.form-field input,
.form-field textarea {
  width: 100%;
  min-height: var(--tap-min);
  background: var(--bg-alt);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.75em;
  font-family: inherit;
  font-size: 1rem; /* 16px+ prevents iOS auto-zoom on focus */
}

.form-field textarea { min-height: 140px; }

.form-field input:focus,
.form-field textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

.social-row {
  display: flex;
  justify-content: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.social-row .placeholder {
  width: var(--tap-min);
  height: var(--tap-min);
  min-height: 0;
  border-radius: 50%;
  font-size: 0.6rem;
}

.social-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  border-radius: 50%;
  border: 1px solid var(--border);
  /* Per Austin's request: always AUSTAL Infrared (#FF574D), not just on
     hover — was var(--text)/AUSTAL White by default, with --accent only
     kicking in on hover/focus below. This is a single shared rule used
     everywhere .social-icon appears (About, Contact, and the footer on
     every page), so the color change applies site-wide from here. */
  color: var(--accent);
  transition: color 0.2s ease, border-color 0.2s ease;
}

.social-icon:hover,
.social-icon:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
}

.social-icon svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
  display: block;
}

/* ---------- footer ---------- */
.site-footer {
  padding: var(--space-lg) 0;
  text-align: center;
  color: var(--text-muted);
  font-size: 0.8rem;
}

.site-footer .social-row { margin-bottom: var(--space-md); }

/* =========================================================
   DESKTOP / LARGER-SCREEN ENHANCEMENTS
   Mobile styles above are the baseline; this layer adds
   room-appropriate layout once there's space for it.
   ========================================================= */
@media (min-width: 780px) {
  :root {
    --space-md: 2rem;
    --space-lg: 4rem;
    --space-xl: 6rem;
  }

  .container { padding: 0 var(--space-md); }

  .nav__brand { display: none; } /* replaced by the centered wordmark below */
  .nav__toggle { display: none; }

  /* Desktop nav: HOME · ABOUT · LIVE SETS on the left, the AUSTAL
     wordmark dead-center, UPCOMING · CONTACT on the right. A real
     3-column grid (not flex space-between) so the logo stays exactly
     centered regardless of the two link groups having different
     widths (3 links vs. 2). */
  .nav__links {
    position: static;
    inset: auto;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    width: 100%;
    gap: var(--space-md);
    padding: 0;
    transform: none;
    background: none;
    pointer-events: auto;
  }

  .nav__links-group {
    flex-direction: row;
    gap: var(--space-md);
  }

  .nav__links-group--left { justify-self: start; }
  .nav__links-group--right { justify-self: end; }

  .nav__brand--center {
    display: flex;
    justify-self: center;
  }
  .nav__brand--center .nav__logo { height: 45px; } /* 24px base, up 25% (v16) then up another 50% per Austin's request */

  .nav__links-group a { font-size: 0.85rem; padding: var(--space-xs) 0; border-bottom: 1px solid transparent; }
  .nav__links-group a[aria-current="page"],
  .nav__links-group a:hover { color: var(--accent); border-bottom-color: var(--accent); }

  .hero__actions { flex-direction: row; width: auto; }
  .btn { width: auto; }

  .section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-md);
    flex-wrap: wrap;
  }

  .section-head .btn { margin-top: 0; }

  /* Sets carousel: bigger fixed-width cards (~measured off the
     reference site) and real arrow controls, vertically centered on
     the card image. Per Austin's request the arrows sit outside the
     image row rather than overlapping it (unlike the reference site,
     which floats them on top of the images) — .sets-carousel__wrap
     gets side padding reserved just for the arrows, so the track/images
     stay fully inset from them at any viewport width. */
  .sets-carousel__card { flex: 0 0 320px; }

  .sets-carousel__wrap { padding: 0 3.5rem; }

  .sets-carousel__arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: calc((320px * 4 / 3) / 2); /* vertical center of the 3:4 card image */
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    background: none;
    border: none;
    color: var(--text);
    cursor: pointer;
    z-index: 2;
  }

  .sets-carousel__arrow:hover,
  .sets-carousel__arrow:focus-visible { color: var(--accent); }

  .sets-carousel__arrow svg { width: 28px; height: 28px; }
  .sets-carousel__arrow--prev { left: 0; }
  .sets-carousel__arrow--next { right: 0; }

  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--about { grid-template-columns: 1fr 1.2fr; align-items: center; gap: var(--space-lg); }
  .gallery__grid { grid-template-columns: repeat(3, 1fr); }

  /* About intro (home) — photo left, copy right, per Austin's mockup.
     .about-intro__media is a plain flex child (not wrapped in
     .container), so it bleeds flush to the true left edge of the
     viewport; the grid fills the section's full locked height
     (section:not(.hero) above) so the photo covers it edge-to-edge
     vertically too. The copy column keeps its own left padding and a
     max-width for readability, left-justified rather than centered. */
  .about-intro__grid {
    flex-direction: row;
  }

  .about-intro__media {
    aspect-ratio: auto;
    width: 50%;
    flex-shrink: 0;
  }

  /* Desktop fade direction (v42): photo is on the left, copy on the
     right, so the blend moves to the photo's right edge — where it
     actually meets the copy column — instead of the bottom edge used
     on mobile's stacked layout. */
  .about-intro__media::after {
    background: linear-gradient(to right, transparent 0%, transparent 80%, var(--intro-bg) 100%);
  }

  .about-intro__inner {
    width: 50%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--space-lg) var(--space-xl);
  }

  /* Reset the mobile-only margin-top bump above (see .about-intro__social)
     back to its original --space-sm here: .about-intro__inner is flex
     at this width, so sibling margins no longer collapse and the bio's
     last-<p> bottom margin plus this margin-top would otherwise add up
     to noticeably more space than desktop already had (which wasn't
     flagged as a problem — only the mobile version was). */
  .about-intro__social {
    margin-top: var(--space-sm);
  }

  /* Events & Venues — all 9 logos, desktop (v17, height cap removed
     v38 — see the "one fluid scroll" note above). The mobile layout
     (v22: only 4 of the 9 logos shown, stacked one per row — see the
     mobile rules above, scoped to a max-width query so none of it
     reaches here) is unaffected by/irrelevant to this breakpoint —
     this resets back to a plain 3-column, 3-row auto-flow grid with
     all 9 logos, matching the original 3x3 (top-left-to-bottom-right
     reading order, per Austin's v19 request). Rows are no longer
     capped to fit one screen (that max-height was tied directly to
     the section-per-screen system, now reverted); each 1fr row just
     sizes to its own content, and the logo <img> still scales via
     max-width/max-height + object-fit: contain, so nothing crops or
     stretches, it's just no longer forced square. */
  .venues-grid {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    gap: 0.5rem 2rem;
  }

  .venue-logo {
    height: auto;
    aspect-ratio: auto;
    grid-column: auto;
    grid-row: auto;
    padding: var(--space-xs) var(--space-md);
  }

  .venue-logo img {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
  }

  /* Featured Set video embed — back to the standard 16:9 widescreen
     ratio on desktop (mobile is 3/4, see the base rule above). */
  .video-embed {
    aspect-ratio: 16 / 9;
  }

  .show-row {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .show-row__date { width: 100px; flex-shrink: 0; }
  .show-row__details { flex: 1; padding: 0 var(--space-md); }
  .show-row .btn { margin-top: 0; }

  .social-row { justify-content: flex-start; }
  .site-footer .social-row { justify-content: center; }
}
