:root {
  /* Pure void blacks for massive depth */
  --black-deep: #020202;
  --black-soft: #0b090b;
  --black-panel: #1a1419;

  /* Hyper-saturated, aggressive club reds */
  --red-core: #d6001c;
  --red-glow: #ff2a4b;
  --red-laser: #ff5c75;
  --red-dark: #7b1123;

  /* Typography contrast tokens */
  --white: #ffffff;
  --white-muted: #8b888b;
  --line: rgba(255, 255, 255, 0.12);
  --glass: rgba(10, 12, 16, 0.72);
  --black: var(--black-deep);
  --graphite: var(--black-soft);
  --charcoal: var(--black-panel);
  --charcoal-2: #261d23;
  --gold: var(--red-core);
  --gold-bright: var(--red-glow);
  --silver: var(--white-muted);
  --steel: #968e93;
  --blue: #1a0d12;
  --red: var(--red-core);
  --white: var(--white);
  --muted: #b6b3ae;
  --max: 1180px;
  color-scheme: dark;
  font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

/* Every <img> now carries width/height attributes so the browser can reserve
   its space before the file loads (no layout shift). The catch: those
   attributes also supply a *used* height when CSS sets only a width — which
   stretched the footer logo to 360x835 and squashed the page-card photos.
   `height: auto` restores aspect-ratio scaling while keeping the reserved box.
   Rules that deliberately set their own height (.brand img, .showcase-card img,
   and the aspect-ratio tiles) override this by coming later. */
img {
  height: auto;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background-color: var(--black-deep);
  background-image:
    radial-gradient(circle at 80% 20%, rgba(214, 0, 28, 0.18) 0%, rgba(2, 2, 2, 0) 50%),
    radial-gradient(circle at 10% 80%, rgba(255, 42, 75, 0.08) 0%, rgba(2, 2, 2, 0) 40%);
  background-attachment: fixed;
  color: var(--white);
  min-width: 320px;
  overflow-x: hidden;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.024) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.018) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: linear-gradient(180deg, black, transparent 85%);
  z-index: -1;
}

img {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
select,
textarea {
  font: inherit;
}

/* Visually hidden but still readable by screen readers — used for the
   aria-live status region that announces form success/error messages. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  left: 1rem;
  top: -4rem;
  z-index: 100;
  background: linear-gradient(135deg, var(--red-glow), var(--red-core));
  color: #fff;
  padding: 0.75rem 1rem;
  border-radius: 0.25rem;
}

.skip-link:focus {
  top: 1rem;
}

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 900;
  min-height: 76px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem clamp(1rem, 4vw, 3.25rem);
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.74), rgba(0, 0, 0, 0.16));
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(18px);
}

.brand {
  display: inline-flex;
  align-items: center;
  width: clamp(126px, 16vw, 194px);
}

.brand img {
  filter: drop-shadow(0 0 18px rgba(216, 162, 74, 0.24));
}

.nav-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(0.8rem, 2vw, 1.9rem);
  color: var(--silver);
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: uppercase;
}

.nav-links a {
  /* The links were 15px tall, under the 24x24 minimum WCAG 2.2 AA asks of a
     pointer target. Vertical padding grows the hit area only — the header is
     flex-centred, so nothing moves and the type size is unchanged. */
  display: inline-block;
  padding: 0.32rem 0;
  transition: color 180ms ease;
}

.nav-links a:hover {
  color: var(--gold-bright);
}

.header-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

/* Hamburger toggle — hidden on desktop, shown ≤920px via the media query below */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 10px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 0.4rem;
  background: rgba(255, 255, 255, 0.06);
  cursor: pointer;
}

.nav-toggle span {
  display: block;
  height: 2px;
  width: 100%;
  background: #fff;
  border-radius: 2px;
  transition: transform 220ms ease, opacity 180ms ease;
}

.site-header.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.site-header.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
.site-header.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.header-cta,
.button,
.contact-actions a,
.stream-links a,
.vault-card button {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.25rem;
  font-size: 0.78rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0;
  transition:
    transform 180ms ease,
    border-color 180ms ease,
    background 180ms ease,
    color 180ms ease;
}

.header-cta {
  padding: 0.78rem 1.25rem;
  color: #fff;
  background: linear-gradient(135deg, var(--red-glow), var(--red-core) 55%, var(--red-dark));
  box-shadow: 0 12px 32px rgba(255, 59, 87, 0.24);
  white-space: nowrap;
  border: 1px solid rgba(255, 120, 140, 0.35);
  animation: ctaGlow 2.6s ease-in-out infinite;
}

/* Gentle pulsing glow to draw the eye to the primary booking CTA */
@keyframes ctaGlow {
  0%, 100% { box-shadow: 0 12px 32px rgba(255, 59, 87, 0.24), 0 0 0 0 rgba(255, 42, 75, 0.0); }
  50%      { box-shadow: 0 12px 34px rgba(255, 59, 87, 0.40), 0 0 18px 2px rgba(255, 42, 75, 0.35); }
}

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

.button {
  padding: 0.95rem 1.2rem;
  border: 1px solid transparent;
}

.button:hover,
.header-cta:hover,
.contact-actions a:hover,
.stream-links a:hover,
.vault-card button:hover {
  transform: translateY(-2px);
}

.button-gold {
  background: linear-gradient(135deg, var(--red-glow), var(--red-core) 55%, var(--red-dark));
  color: #fff;
  box-shadow: 0 16px 44px rgba(255, 59, 87, 0.25);
}

.button-glass {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.22);
  color: var(--white);
  backdrop-filter: blur(14px);
}

.button-line {
  border-color: rgba(255, 59, 87, 0.58);
  color: var(--red-glow);
  background: rgba(255, 59, 87, 0.08);
}

.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 100vh;

  padding:
    120px clamp(40px, 6vw, 90px) 80px;

  overflow: hidden;

  isolation: isolate;
}

.hero-media,
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.hero-media img,
.hero-media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 54% center;
  filter: saturate(0.95) contrast(1.1) brightness(0.64);
  transform: scale(1.04);
}

.hero-scrim {
  z-index: -1;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.5) 47%, rgba(0, 0, 0, 0.15) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, 0.72) 0%, rgba(0, 0, 0, 0.18) 48%, rgba(5, 5, 5, 0.96) 100%),
    radial-gradient(circle at 28% 26%, rgba(255, 59, 87, 0.26), transparent 24rem),
    radial-gradient(circle at 80% 68%, rgba(200, 16, 46, 0.28), transparent 22rem);
}

.hero-inner {
  width: min(760px, 100%);
  /* Extra bottom room so the fixed mini-player (bottom-left) never
     overlaps the role tags at the end of this column. */
  padding-bottom: clamp(7rem, 12vh, 10rem);

  animation: heroFade 1s ease-out;
}

.eyebrow {
  margin: 0 0 0.85rem;
  color: var(--gold-bright);
  font-size: 0.77rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0;
  opacity: 0;
  animation: heroFade .8s ease forwards;
  animation-delay: .2s;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1 {
  margin-bottom: 0.55rem;
  font-size: clamp(3.5rem, 13vw, 10.8rem);
  line-height: 0.82;
  text-transform: uppercase;
  font-weight: 900;
  letter-spacing: 0;
  text-shadow: 0 18px 60px rgba(0, 0, 0, 0.72);
}

h2 {
  margin-bottom: 1rem;
  font-size: clamp(2rem, 6vw, 5rem);
  line-height: 0.96;
  text-transform: uppercase;
  font-weight: 900;
  letter-spacing: 0;
}

/* Active hero title glow per user request */
.hero-title,
.hero-content h2 {
  color: var(--white) !important;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -1px;
  text-shadow: 0 0 20px rgba(255, 42, 75, 0.25), 0 0 40px rgba(214, 0, 28, 0.15);
  opacity: 0;
  animation: heroFade .9s ease forwards;
  animation-delay: .45s;
}

h3 {
  font-size: 1.16rem;
  line-height: 1.1;
  text-transform: uppercase;
  font-weight: 900;
}

p {
  color: var(--muted);
  line-height: 1.72;
}

.hero-tagline {
  margin-bottom: 0.9rem;
  color: var(--silver);
  font-size: clamp(1.18rem, 3vw, 2rem);
  font-weight: 800;
  text-transform: uppercase;
  opacity: 0;
  animation: heroFade .9s ease forwards;
  animation-delay: .7s;
}

.hero-copy {
  max-width: 610px;
  margin-bottom: 1.6rem;
  color: #d8dbe0;
  font-size: clamp(1rem, 2vw, 1.16rem);
  opacity: 0;
  animation: heroFade 1s ease forwards;
  animation-delay: .95s;
}

.music-showcase {
  margin-top: 2.2rem;
  display: flex;
  flex-direction: column;
  gap: 2.2rem;
}

.release-status {
  padding: 2.2rem;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 1.125rem;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.02));
  backdrop-filter: blur(20px);
  box-shadow: 0 0 60px rgba(255, 42, 75, 0.08);
}

.release-status span {
  display: inline-block;
  padding: 0.5rem 1.125rem;
  border-radius: 1.875rem;
  background: #ff2a4b;
  color: white;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.125rem;
  margin-bottom: 1.25rem;
}

.release-status h3 {
  font-size: 2.625rem;
  margin-bottom: 0.95rem;
}

.release-status p {
  font-size: 1.125rem;
  max-width: 40.625rem;
  color: #d5d5d5;
}

.music-buttons {
  display: flex;
  gap: 1.125rem;
  flex-wrap: wrap;
}

.music-buttons .button {
  padding: 1rem 2.125rem;
  font-size: 0.875rem;
  letter-spacing: 0.0625rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}

.hero-panel {
  position: absolute;
  right: clamp(1rem, 5vw, 4rem);
  bottom: clamp(1rem, 4vw, 2.5rem);
  width: min(340px, calc(100% - 2rem));
  padding: 1rem;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.04));
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 0.5rem;
  backdrop-filter: blur(20px);
}

.hero-panel span {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--gold-bright);
  font-size: 0.75rem;
  font-weight: 900;
  text-transform: uppercase;
}

.hero-panel strong {
  color: var(--white);
  font-size: 1.05rem;
}

.section {
  width: min(var(--max), calc(100% - 2rem));
  margin: 0 auto;
  padding: clamp(4.5rem, 10vw, 8.5rem) 0;
}

.showcase-band {
  display: grid;
  gap: 1.25rem;
}

.showcase-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 0.9fr);
  gap: 1.2rem;
  padding: 1.25rem;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0.7rem;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.028));
}

.showcase-card img {
  width: 100%;
  height: 100%;
  min-height: 280px;
  object-fit: cover;
  border-radius: 0.5rem;
}

.showcase-card h2 {
  font-size: clamp(1.65rem, 3vw, 2.6rem);
}

.hero-tags {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 10px;

  margin-top: 0.4rem;
  padding: 0;

  background: transparent;
  border: none;

  color: #ffffff;

  transition: all .35s ease;

}

.hero-tags span:hover {

  background: #d6001c;

  border-color: #ff2a4b;

  color: #fff;

  transform: translateY(-4px);

  box-shadow: 0 0 22px rgba(255, 42, 75, .4);

}

.hero-tags span {
  padding: 0.5rem 1rem;
  border: 1px solid rgba(255, 42, 75, 0.5);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3), inset 0 0 12px rgba(255, 42, 75, 0.12);
}

/* CTA and role tag styles (more active) */
.btn-cta,
.role-tag {
  display: inline-flex;

  align-items: center;

  justify-content: center;

  padding: 12px 22px;

  border-radius: 50px;

  background: rgba(255, 255, 255, .05);

  border: 1px solid rgba(255, 255, 255, .10);

  color: #fff;

  font-size: 13px;

  font-weight: 700;

  letter-spacing: .8px;

  transition: .35s;

  cursor: pointer;

}

.role-tag:hover {

  transform: translateY(-4px);

  background: #d6001c;

  border-color: #ff2a4b;

  box-shadow: 0 0 25px rgba(255, 42, 75, .40);

}

.btn-cta:hover {
  background: linear-gradient(135deg,
      #ff2a4b 0%,
      #d6001c 60%,
      #900012 100%);

  color: #fff;

  border: 1px solid rgba(255, 92, 117, .45);

  box-shadow:
    0 12px 35px rgba(214, 0, 28, .45);

}

.btn-cta:hover {

  background: linear-gradient(135deg,
      #ff5c75,
      #ff2a4b,
      #d6001c);

  box-shadow:
    0 0 35px rgba(255, 42, 75, .6);

  transform: translateY(-3px);

}

.intro-band {
  width: 100%;
  padding-inline: clamp(1rem, 5vw, 4rem);
  background:
    linear-gradient(90deg, rgba(16, 27, 51, 0.7), rgba(24, 26, 32, 0.8), rgba(70, 12, 17, 0.55)),
    var(--graphite);
  border-block: 1px solid var(--line);
}

.section-grid {
  max-width: var(--max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: end;
}

.section-grid h2 {
  font-size: clamp(2rem, 4.8vw, 4.3rem);
}

.about,
.booking {
  display: grid;
  grid-template-columns: minmax(280px, 0.78fr) minmax(0, 1fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
}

.portrait-frame {
  position: relative;
  overflow: hidden;
  border-radius: 0.55rem;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: var(--charcoal);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.42);
}

.portrait-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 48%, rgba(0, 0, 0, 0.54));
}

.portrait-frame img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

.timeline,
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.7rem;
  margin-top: 1.5rem;
}

.timeline span,
.stats strong,
.vault-card,
.booking-form,
.release-card {
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.095), rgba(255, 255, 255, 0.028));
  border: 1px solid rgba(255, 255, 255, 0.13);
  border-radius: 0.55rem;
}

.timeline span {
  min-height: 86px;
  padding: 0.95rem;
  color: var(--silver);
  font-size: 0.75rem;
  text-transform: uppercase;
}

.timeline strong {
  display: block;
  margin-top: 0.25rem;
  color: var(--white);
  font-size: 1rem;
}

.stats {
  grid-template-columns: repeat(3, 1fr);
}

.stats strong {
  padding: 1rem;
  color: var(--gold-bright);
  font-size: clamp(1.45rem, 3vw, 2.2rem);
}

.stats span {
  display: block;
  margin-top: 0.35rem;
  color: var(--muted);
  font-size: 0.72rem;
  text-transform: uppercase;
}

.release-card {
  display: grid;
  grid-template-columns: minmax(260px, 0.72fr) minmax(0, 1fr);
  gap: clamp(1.3rem, 4vw, 3rem);
  padding: clamp(1rem, 4vw, 2rem);
  background:
    radial-gradient(circle at 22% 25%, rgba(216, 162, 74, 0.22), transparent 20rem),
    linear-gradient(135deg, rgba(16, 27, 51, 0.74), rgba(24, 26, 32, 0.92) 45%, rgba(70, 12, 17, 0.48)),
    var(--charcoal);
}

.release-art {
  position: relative;
  min-height: 320px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 0.45rem;
  background: linear-gradient(160deg, #090b10, #20242c);
}

.release-art img {
  width: 82%;
  filter: drop-shadow(0 24px 32px rgba(0, 0, 0, 0.58));
}

.equalizer {
  position: absolute;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  height: 48px;
  display: flex;
  align-items: end;
  justify-content: center;
  gap: 0.45rem;
}

.equalizer i {
  width: 0.45rem;
  height: 55%;
  display: block;
  border-radius: 99px;
  background: linear-gradient(180deg, var(--gold-bright), var(--red));
}

.equalizer i:nth-child(2) {
  height: 82%;
}

.equalizer i:nth-child(3) {
  height: 34%;
}

.equalizer i:nth-child(4) {
  height: 70%;
}

.track-meta {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.7rem;
  margin: 1.4rem 0;
}

.track-meta div {
  padding: 0.85rem;
  border: 1px solid var(--line);
  border-radius: 0.35rem;
}

.track-meta dt {
  color: var(--steel);
  font-size: 0.72rem;
  text-transform: uppercase;
}

.track-meta dd {
  margin: 0.3rem 0 0;
  color: var(--white);
  font-weight: 800;
}

.track-list {
  padding: 0;
  margin: 0 0 1.4rem;
  list-style: none;
}

.track-list li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--line);
  color: var(--silver);
}

.stream-links,
.contact-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}

.stream-links a,
.contact-actions a {
  padding: 0.7rem 0.9rem;
  border: 1px solid rgba(216, 162, 74, 0.35);
  color: var(--gold-bright);
  background: rgba(216, 162, 74, 0.07);
}

.section-heading {
  max-width: 820px;
  margin-bottom: clamp(1.5rem, 4vw, 2.8rem);
}

.vault-grid,
.experience-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.vault-card {
  position: relative;
  overflow: hidden;

  display: flex;
  flex-direction: column;
  justify-content: space-between;

  padding: 1.2rem;

  background: linear-gradient(145deg,
      rgba(255, 255, 255, .08),
      rgba(255, 255, 255, .02));

  border: 1px solid rgba(255, 255, 255, .10);
  border-radius: 18px;

  backdrop-filter: blur(18px);

  transition:
    transform .35s ease,
    box-shadow .35s ease,
    border-color .35s ease;
}

.vault-card:hover {
  transform: translateY(-10px);

  border-color: rgba(255, 42, 75, .65);

  box-shadow:
    0 25px 60px rgba(0, 0, 0, .45),
    0 0 35px rgba(255, 42, 75, .22);
}

.vault-card span {
  color: var(--gold-bright);
  font-size: 0.75rem;
  font-weight: 900;
  text-transform: uppercase;
}

.vault-card div {
  display: flex;
  gap: 0.6rem;
}

.vault-card button {
  flex: 1;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.06);
  color: var(--white);
  cursor: pointer;
}

.experience-grid {
  grid-template-columns: repeat(3, 1fr);
}

.experience-grid article {
  min-height: 320px;
  position: relative;
  display: flex;
  align-items: end;
  overflow: hidden;
  border-radius: 0.5rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.82)), var(--bg);
  background-size: cover;
  background-position: center;
  transition: transform 220ms ease, border-color 220ms ease;
}

.experience-grid article:hover {
  transform: translateY(-4px);
  border-color: rgba(216, 162, 74, 0.64);
}

.experience-grid span {
  padding: 1rem;
  font-weight: 900;
  text-transform: uppercase;
}

.media-grid {
  display: grid;
  grid-template-columns: 1.35fr 0.8fr;
  gap: 1rem;
}

.media-grid figure {
  position: relative;
  min-height: 290px;
  margin: 0;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.13);
  border-radius: 0.5rem;
}

.media-grid .wide {
  grid-row: span 2;
}

.media-grid img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 320ms ease;
}

.media-grid figure:hover img {
  transform: scale(1.04);
}

.media-grid figcaption {
  position: absolute;
  left: 1rem;
  bottom: 1rem;
  padding: 0.65rem 0.8rem;
  border-radius: 0.3rem;
  background: rgba(0, 0, 0, 0.62);
  color: var(--white);
  font-weight: 800;
  backdrop-filter: blur(14px);
}

.marquee {
  width: 100%;
  overflow: hidden;
  border-block: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.035);
}

.marquee div {
  display: flex;
  gap: 2rem;
  width: max-content;
  padding: 1.1rem 1rem;
  animation: scrollMarquee 60s linear infinite;
}

.marquee span {
  color: var(--silver);
  font-size: clamp(1rem, 2vw, 1.6rem);
  font-weight: 900;
  text-transform: uppercase;
  white-space: nowrap;
}

@keyframes scrollMarquee {
  from {
    transform: translateX(0);
  }

  to {
    transform: translateX(-100%);
  }
}

.booking {
  align-items: start;
}

.booking-copy {
  position: sticky;
  top: 7rem;
}

.booking-form {
  display: grid;
  /* minmax(0, 1fr), not 1fr. A plain `1fr` track is min-content floored, and
     `input[type=date]` and the longest <option> in the event <select> both
     have a stubborn intrinsic width — on a tablet that pushed one column past
     half the form and spilled the controls out through the card's border. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.9rem;
  padding: clamp(1rem, 3vw, 1.4rem);
  background:
    radial-gradient(circle at 85% 0%, rgba(216, 162, 74, 0.16), transparent 16rem),
    rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(18px);
}

.booking-form label {
  display: grid;
  gap: 0.42rem;
  color: var(--silver);
  font-size: 0.78rem;
  font-weight: 800;
  text-transform: uppercase;
}

.booking-form input,
.booking-form select,
.booking-form textarea {
  width: 100%;
  min-height: 46px;
  border: 1px solid rgba(255, 255, 255, 0.13);
  border-radius: 0.25rem;
  padding: 0.72rem 0.78rem;
  color: var(--white);
  background: rgba(0, 0, 0, 0.28);
  outline: none;
}

.booking-form input:focus,
.booking-form select:focus,
.booking-form textarea:focus {
  border-color: rgba(216, 162, 74, 0.78);
}

.full {
  grid-column: 1 / -1;
}

.footer {
  padding: clamp(3rem, 8vw, 6rem) clamp(1rem, 5vw, 4rem);
  border-top: 1px solid var(--line);
  background: #050505;
}

/* Sizing moved to the .footer-brand wrapper so the shine overlay can be
   positioned against a box that matches the logo exactly. */
.footer-brand {
  position: relative;
  width: min(360px, 88vw);
  margin: 0 auto 1.2rem;
}

.footer-brand img {
  width: 100%;
  height: auto;
  display: block;
  /* Same metallic depth as the header crest. */
  filter:
    drop-shadow(0 1px 0 rgba(255, 255, 255, 0.28))
    drop-shadow(0 10px 22px rgba(0, 0, 0, 0.6))
    drop-shadow(0 0 20px rgba(216, 162, 74, 0.22));
}

.footer p {
  color: var(--white);
  font-size: 1.35rem;
  font-weight: 800;
  text-transform: uppercase;
}

.footer div {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.footer a {
  color: var(--muted);
  font-weight: 800;
  text-transform: uppercase;
}

@media (max-width: 920px) {
  .site-header {
    min-height: 70px;
  }

  .showcase-card {
    grid-template-columns: 1fr;
  }

  /* Once the card stacks, the photo and the copy share one column instead of
     sitting side by side. `height: 100%` was written for the two-column layout
     (photo matches the copy's height); in the stacked layout Safari resolves
     that percentage against the whole card rather than the photo's own row, so
     the image grew to the full card height and the heading and paragraph were
     painted on top of it. Natural aspect scaling is what the stacked layout
     actually wants. */
  .showcase-card img {
    height: auto;
    min-height: 0;
  }

  .nav-toggle {
    display: inline-flex;
  }

  /* Closed by default; opens as a full-width dropdown panel under the header */
  .nav-links {
    display: none;
  }

  .site-header.nav-open .nav-links {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;

    position: fixed;
    top: 76px;
    left: 0;
    right: 0;

    padding: 0.5rem clamp(1rem, 4vw, 3.25rem) 1rem;

    background: rgba(6, 6, 8, 0.97);
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    backdrop-filter: blur(18px);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);

    font-size: 0.95rem;
    max-height: calc(100vh - 76px);
    overflow-y: auto;
  }

  .site-header.nav-open .nav-links a {
    padding: 0.95rem 0.25rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  }

  .hero {
    min-height: 94svh;
  }

  .hero-panel {
    display: none;
  }

  .section-grid,
  .about,
  .release-card,
  .booking {
    grid-template-columns: 1fr;
  }

  .booking-copy {
    position: static;
  }

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

  .experience-grid {
    grid-template-columns: repeat(2, 1fr);
  }

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

  .media-grid .wide {
    grid-row: auto;
  }
}

@media (max-width: 620px) {
  .site-header {
    padding-inline: 0.85rem;
  }

  .showcase-card {
    padding: 0.9rem;
  }

  .brand {
    width: 122px;
  }

  .header-cta {
    padding-inline: 0.85rem;
  }

  .hero {
    padding: 6.5rem 1rem 1.5rem;
  }

  .hero-actions,
  .stream-links,
  .contact-actions,
  .vault-card div {
    display: grid;
    grid-template-columns: 1fr;
  }

  .button {
    width: 100%;
  }

  .timeline,
  .stats,
  .track-meta,
  .booking-form {
    grid-template-columns: 1fr;
  }

  .release-art {
    min-height: 250px;
  }

  .experience-grid article {
    min-height: 260px;
  }

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

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }
}

/* The native cursor is used. A custom arrow used to be drawn here with
   `body { cursor: none }`, but six later rules set `cursor: pointer`, which
   outranked it — so over buttons and nav controls the OS cursor came back and
   the viewer saw two cursors at once. Native cursors also carry the right
   affordances for free (pointer over links, I-beam over inputs), which a
   single custom bitmap cannot. The mouse-following .spotlight glow is kept. */

.spotlight {
  position: fixed;
  pointer-events: none;
  z-index: 9999;
}

.spotlight {
  inset: 0;
  z-index: 0;
  background: radial-gradient(circle 260px at var(--mouse-x, 50vw) var(--mouse-y, 40vh), rgba(216, 162, 74, 0.16), transparent 68%);
  mix-blend-mode: screen;
}

.stage-particles {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 1;
}

.stage-particles i {
  position: absolute;
  bottom: -8vh;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: rgba(255, 215, 123, 0.72);
  box-shadow: 0 0 18px rgba(255, 215, 123, 0.7);
  animation: floatUp 12s linear infinite;
}

.stage-particles i:nth-child(1) {
  left: 12%;
  animation-delay: 0s;
}

.stage-particles i:nth-child(2) {
  left: 28%;
  animation-delay: 2s;
}

.stage-particles i:nth-child(3) {
  left: 44%;
  animation-delay: 4s;
}

.stage-particles i:nth-child(4) {
  left: 62%;
  animation-delay: 1s;
}

.stage-particles i:nth-child(5) {
  left: 78%;
  animation-delay: 5s;
}

.stage-particles i:nth-child(6) {
  left: 90%;
  animation-delay: 3s;
}

@keyframes floatUp {
  from {
    transform: translate3d(0, 0, 0) scale(1);
    opacity: 0;
  }

  15% {
    opacity: 0.75;
  }

  to {
    transform: translate3d(28px, -112vh, 0) scale(2.4);
    opacity: 0;
  }
}

.site-header {
  transition: background 240ms ease, min-height 240ms ease, box-shadow 240ms ease;
}

.site-header.is-scrolled {
  min-height: 66px;
  background: rgba(7, 9, 13, 0.84);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.38);
}

.hero-media img {
  will-change: transform;
}

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(115deg, transparent 0 32%, rgba(255, 215, 123, 0.08) 43%, transparent 54%),
    radial-gradient(circle at 50% 105%, rgba(186, 44, 53, 0.24), transparent 28rem);
  opacity: var(--show-energy, 0.35);
  transition: opacity 220ms ease;
}

.hero::before {
  content: "";
  position: absolute;
  inset: -20%;
  z-index: -1;
  pointer-events: none;

  background: linear-gradient(115deg,
      transparent 35%,
      rgba(255, 42, 75, 0.18) 47%,
      rgba(255, 120, 140, 0.35) 50%,
      rgba(255, 42, 75, 0.18) 53%,
      transparent 65%);

  transform: translateX(-130%);
  animation: laserSweep 9s linear infinite;
}

.button:focus-visible,
.header-cta:focus-visible,
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}

.equalizer i,
.mini-player.is-playing .player-wave i {
  animation: pulseBar 780ms ease-in-out infinite alternate;
}

.equalizer i:nth-child(2),
.player-wave i:nth-child(2) {
  animation-delay: 120ms;
}

.equalizer i:nth-child(3),
.player-wave i:nth-child(3) {
  animation-delay: 240ms;
}

.equalizer i:nth-child(4),
.player-wave i:nth-child(4) {
  animation-delay: 80ms;
}

.equalizer i:nth-child(5),
.player-wave i:nth-child(5) {
  animation-delay: 320ms;
}

@keyframes pulseBar {
  from {
    transform: scaleY(0.42);
    opacity: 0.68;
  }

  to {
    transform: scaleY(1);
    opacity: 1;
  }
}

.track-list li {
  align-items: center;
}

.track-list li span {
  flex: 1;
}

.track-play,
.player-toggle {
  border: 1px solid rgba(216, 162, 74, 0.48);
  border-radius: 999px;
  background: rgba(216, 162, 74, 0.1);
  color: var(--gold-bright);
  font-size: 0.7rem;
  font-weight: 900;
  text-transform: uppercase;
  min-width: 48px;
  min-height: 34px;
}

.vault-card {
  position: relative;
  overflow: hidden;
}

.vault-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 80% 0%, rgba(216, 162, 74, 0.16), transparent 12rem);
  pointer-events: none;
}

.vault-card>* {
  position: relative;
}

.vault-card img {
  width: 150px;
  opacity: 0.62;
  filter: drop-shadow(0 16px 24px rgba(0, 0, 0, 0.45));
}

.vault-icon {
  max-width: 74px;
}

.vault-card.is-favorited {
  border-color: rgba(216, 162, 74, 0.72);
}

.tour {
  width: 100%;
  max-width: none;
  padding-inline: clamp(1rem, 5vw, 4rem);
  background:
    linear-gradient(180deg, rgba(16, 27, 51, 0.62), rgba(5, 5, 5, 0.1)),
    radial-gradient(circle at 50% 50%, rgba(216, 162, 74, 0.1), transparent 30rem);
}

.tour .section-heading,
.route-map {
  max-width: var(--max);
  margin-inline: auto;
}

.route-map {
  position: relative;
  min-height: 340px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 0.55rem;
  overflow: hidden;
  background:
    linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px),
    linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px),
    #0a0d14;
  background-size: 58px 58px;
}

.route-map::before {
  content: "";
  position: absolute;
  left: 8%;
  right: 10%;
  top: 52%;
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gold), var(--blue), var(--red), var(--gold-bright));
  box-shadow: 0 0 24px rgba(216, 162, 74, 0.58);
  transform: scaleX(var(--route-progress, 0.25));
  transform-origin: left;
  transition: transform 500ms ease;
}

.route-map span {
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  min-width: 84px;
  padding: 0.65rem 0.75rem;
  border: 1px solid rgba(216, 162, 74, 0.42);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.62);
  color: var(--white);
  font-size: 0.72rem;
  font-weight: 900;
  text-align: center;
  text-transform: uppercase;
  box-shadow: 0 0 28px rgba(216, 162, 74, 0.1);
}

.booking-form.is-sent {
  border-color: rgba(216, 162, 74, 0.72);
  box-shadow: 0 0 0 1px rgba(216, 162, 74, 0.18), 0 24px 70px rgba(216, 162, 74, 0.12);
}

.epk-panel {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

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

.epk-grid article {
  min-height: 190px;
  padding: 1.1rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 0.55rem;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.025));
}

.epk-grid span {
  color: var(--gold-bright);
  font-weight: 900;
}

.epk-grid strong {
  display: block;
  margin: 1rem 0 0.5rem;
  color: var(--white);
  font-size: 1.1rem;
  text-transform: uppercase;
}

/* Pages carrying the fixed preview player need room at the bottom so the last
   row of content can clear it instead of sitting under it permanently. Scoped
   to both classes so it outranks the .page-shell padding shorthand defined
   further down the file. */
.page-shell.has-player {
  padding-bottom: 9rem;
}

.mini-player {
  position: fixed;
  left: clamp(0.75rem, 3vw, 1.5rem);
  right: clamp(0.75rem, 3vw, 1.5rem);
  bottom: clamp(0.75rem, 3vw, 1.5rem);
  z-index: 45;
  max-width: 560px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.9rem;
  align-items: center;
  padding: 0.8rem;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0.55rem;
  background: rgba(7, 9, 13, 0.82);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(18px);
}

.mini-player strong,
.mini-player span {
  display: block;
}

.mini-player strong {
  color: var(--white);
  font-size: 0.9rem;
  text-transform: uppercase;
}

.mini-player span {
  color: var(--muted);
  font-size: 0.78rem;
}

.player-wave {
  display: flex;
  align-items: end;
  gap: 0.25rem;
  height: 32px;
}

.player-wave i {
  width: 4px;
  height: 38%;
  border-radius: 999px;
  background: var(--gold-bright);
}

.player-wave i:nth-child(2) {
  height: 74%;
}

.player-wave i:nth-child(3) {
  height: 46%;
}

.player-wave i:nth-child(4) {
  height: 88%;
}

.player-wave i:nth-child(5) {
  height: 52%;
}

.player-wave i:nth-child(6) {
  height: 68%;
}

.newsletter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin: 1.4rem 0;
}

.newsletter label {
  display: grid;
  gap: 0.35rem;
  min-width: min(320px, 100%);
  color: var(--silver);
  font-size: 0.74rem;
  font-weight: 900;
  text-transform: uppercase;
}

.newsletter input {
  min-height: 46px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0.25rem;
  padding: 0.75rem;
  color: var(--white);
  background: rgba(255, 255, 255, 0.05);
}

.newsletter button {
  align-self: end;
  min-height: 46px;
  border: 0;
  border-radius: 0.25rem;
  padding: 0.75rem 1.2rem;
  color: #111;
  background: var(--gold);
  font-weight: 900;
  text-transform: uppercase;
}

@media (max-width: 920px) {
  .epk-panel {
    grid-template-columns: 1fr;
  }

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

@media (max-width: 620px) {
  .mini-player {
    position: sticky;
    display: grid;
    grid-template-columns: 1fr;
    margin: 1rem;
    bottom: 1rem;
  }

  /* The mini-player is a tall, sticky bottom bar on phones — reserve room
     below the role tags so it never covers them, and keep the tags compact. */
  .hero-inner {
    padding-bottom: 12rem;
  }

  .hero-tags {
    justify-content: center;
  }

  .hero-tags span {
    font-size: 0.72rem;
    padding: 0.4rem 0.75rem;
  }

  .route-map {
    min-height: 420px;
  }

  .route-map::before {
    left: 50%;
    top: 8%;
    bottom: 8%;
    right: auto;
    width: 4px;
    height: auto;
    transform: scaleY(var(--route-progress, 0.25));
    transform-origin: top;
  }

  .route-map span {
    left: 50% !important;
  }
}

.page-shell {
  width: min(var(--max), calc(100% - 2rem));
  margin: 0 auto;
  padding: 8rem 0 3rem;
}

.page-hero {
  padding: clamp(2rem, 5vw, 3rem) 0 1.25rem;
}

.page-content {
  padding-bottom: 3rem;
}

/* Page bodies stack several independent blocks: /booking runs three
   `.page-grid` sections back to back, /about follows its card grid with the
   press-kit panel, /spotlight follows it with the venue rails. Each block
   spaced its own children (`.page-grid` has a gap) but nothing spaced the
   blocks from one another, and <section> carries no UA margin — so the last
   card of one block and the first card of the next met with zero gap and
   their two 1px outlines read as one doubled, overlapping border.
   Margin rather than a gap on `.page-content`, so it collapses with
   `.gallery-section`'s own margin-bottom instead of stacking on top of it. */
.page-content > * + * {
  margin-top: clamp(2rem, 5vw, 3rem);
}

.page-grid {
  display: grid;
  gap: 1.25rem;
}

/* NOTE: `.page-card-grid` itself is defined once, in the CONTENT CARD PAGES
   block near the end of this file. It used to be declared here as a two-column
   grid as well, and that earlier copy was silently defeated by the later one —
   which is what let the vault grids fall through into column flow. One
   definition only; keep it that way. */

.page-card {
  padding: 1.2rem;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0.7rem;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.028));
}

.page-card img {
  width: 100%;
  border-radius: 0.5rem;
  margin-bottom: 0.8rem;
}

/* Media cards crop their photo into one shared frame. The source photos are a
   mix of landscape and portrait, so without this the image keeps its natural
   ratio while the card stretches to the grid row height — leaving a dead gap
   under the shorter images. */
.media-card picture {
  display: block;
  margin-bottom: 0.8rem;
}

.media-card img {
  /* Square rather than the old 4/5 portrait. 4/5 made each photo card roughly
     a screen tall on its own, which is what drove the page height. A square
     also crops sensibly for both the portrait sources and the landscape live
     shot, where a landscape ratio would cut the portraits' heads off. */
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: center;
  margin-bottom: 0;
}

.media-card h3 {
  margin-bottom: 0;
}

.muted-line {
  color: var(--silver);
  font-size: 0.92rem;
}

.vault-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  margin-top: 1rem;
}

.vault-actions strong {
  color: var(--gold-bright);
  font-size: 1rem;
}

.vault-actions small {
  width: 100%;
  color: var(--silver);
  font-size: 0.8rem;
  text-transform: uppercase;
}

/* The narrow-width `.page-card-grid` override lives with the rest of its rules
   in the CONTENT CARD PAGES block at the end of this file. */

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
  }

  body,
  a,
  button,
  input,
  select,
  textarea {
    cursor: auto;
  }

  .spotlight,
  .stage-particles {
    display: none;
  }
}

/* Touch devices have no hovering pointer, so the mouse-following glow has
   nothing to follow. */
@media (pointer: coarse) {
  .spotlight {
    display: none;
  }
}

@keyframes heroFade {
  from {
    opacity: 0;
    transform: translateY(40px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes laserSweep {

  0% {
    transform: translateX(-130%);
  }

  100% {
    transform: translateX(130%);
  }

}

/* ===============================
   HERO LOCATION
==================================*/

.hero {
  position: relative;
}

.hero-location {

  position: absolute;

  top: 130px;

  right: 60px;

  display: inline-flex;
  align-items: center;
  gap: 9px;

  padding: 10px 18px;

  border: 1px solid rgba(255, 42, 75, .4);

  border-radius: 40px;

  background: rgba(0, 0, 0, .55);

  backdrop-filter: blur(20px);

  color: #fff;

  font-size: 13px;

  font-weight: 700;

  letter-spacing: 1px;

  text-transform: uppercase;

  box-shadow: 0 8px 24px rgba(0, 0, 0, .4), 0 0 18px rgba(255, 42, 75, .18);

  z-index: 20;

  transition: .35s;
}

/* Live red "on tour" pin dot with a gentle pulse */
.hero-location::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ff2a4b;
  box-shadow: 0 0 0 0 rgba(255, 42, 75, .55);
  animation: locationPulse 2.2s ease-out infinite;
}

@keyframes locationPulse {
  0%   { box-shadow: 0 0 0 0 rgba(255, 42, 75, .55); }
  70%  { box-shadow: 0 0 0 8px rgba(255, 42, 75, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 42, 75, 0); }
}

.hero-location:hover {

  border-color: #ff2a4b;

  box-shadow: 0 0 25px rgba(255, 42, 75, .35);

}

/* The badge is pinned to a fixed top/right offset that was measured against the
   desktop hero photo. On a phone that spot is exactly where the brand crest
   sits, so the pill landed on top of the logo. Below the stacking breakpoint
   the hero is already a flex column, so dropping the badge into normal flow
   makes it the first item in that column — above the crest, no overlap, and it
   still reads as a label for the hero. */
@media (max-width: 900px) {
  .hero-location {
    position: static;
    top: auto;
    right: auto;
    align-self: flex-start;
    margin-bottom: 1.1rem;
    max-width: 100%;
  }
}

.hero-stats {
  position: absolute;
  right: 3%;
  top: 55%;
  transform: translateY(-50%);

  display: flex;
  flex-direction: column;
  gap: 18px;

  z-index: 10;
}

.hero-stat {
  width: 96px;
  height: 96px;

  border-radius: 50%;

  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  background: rgba(255, 255, 255, .08);

  backdrop-filter: blur(20px);

  border: 1px solid rgba(255, 255, 255, .15);

  box-shadow:
    0 12px 35px rgba(0, 0, 0, .35),
    0 0 20px rgba(255, 35, 70, .18);

  animation: bubbleFloat 7s ease-in-out infinite;

  transition: .35s;
}

.hero-stat strong {
  display: block;
  font-size: 24px;
  color: #fff;
  font-weight: 800;
  margin-bottom: 6px;
}

.hero-stat span {
  margin-top: 6px;
  color: rgba(255, 255, 255, .75);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 1px;
}

.hero-stat:hover {
  transform: translateY(-6px);
  border-color: rgba(255, 59, 87, .7);
  box-shadow: 0 18px 40px rgba(255, 59, 87, .25);
}

.hero {
  position: relative;
}

.hero-stats {
  position: absolute;

  right: 4%;
  top: 52%;

  transform: translateY(-50%);

  display: flex;
  flex-direction: column;
  gap: 14px;

  z-index: 8;
}

.hero-stats strong {
  display: block;

  padding: 0;
  border: none;
  background: transparent;
  backdrop-filter: none;
  box-shadow: none;

  color: #ffffff;
  font-size: 16px;
  font-weight: 800;
  text-align: center;
}

.hero-stats strong span {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: #cfcfcf;
  letter-spacing: 1px;
  text-transform: uppercase;
}

@keyframes heroFloat {

  0% {
    transform: translate(0, 0);
  }

  25% {
    transform: translate(8px, -8px);
  }

  50% {
    transform: translate(-6px, 6px);
  }

  75% {
    transform: translate(6px, -4px);
  }

  100% {
    transform: translate(0, 0);
  }

}

.hero-stat:nth-child(2) {
  margin-left: 0;
}

.hero-stat:nth-child(3) {
  margin-left: 0;
}

@keyframes bubbleFloat {

  0%,
  100% {
    transform: translateY(0);
  }

  25% {
    transform: translateY(-6px) translateX(6px);
  }

  50% {
    transform: translateY(4px) translateX(-4px);
  }

  75% {
    transform: translateY(-5px) translateX(5px);
  }
}
/* Vault purchase flow */
.order-summary {
  list-style: none;
  margin: 0.5rem 0 1rem;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}
.order-summary li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--line);
  color: var(--white-muted);
}
.order-summary li strong { color: var(--white); }
.order-total {
  font-size: 1.15rem;
  margin: 0.5rem 0 1.25rem;
}
.order-total strong { color: var(--gold); font-size: 1.4rem; }
.order-total small { color: var(--white-muted); font-weight: 500; }
.upi-id {
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  word-break: break-all;
}
.purchase-downloads {
  margin-top: 1.25rem;
  display: grid;
  gap: 0.75rem;
}

/* The panel ships `hidden` and is only revealed after payment. `hidden` is a
   UA `display: none`, which any author `display` outranks — so the `grid`
   above was un-hiding it and giving the empty div a row (plus its margin) in
   the middle of the checkout form. */
.purchase-downloads[hidden] {
  display: none;
}
.purchase-downloads .button { width: 100%; text-align: center; }

/* Homepage stats band (3 boxes between hero and showcase, no photo overlap) */
.stats-band {
  padding-top: 2.5rem;
  padding-bottom: 0.5rem;
}
.stats-band .stats {
  grid-template-columns: repeat(3, 1fr);
  max-width: 900px;
  margin: 0 auto;
  gap: 1rem;
}
.stats-band .stats strong {
  font-size: 2rem;
  text-align: center;
  padding: 1.4rem 1rem;
}
.stats-band .stats span {
  display: block;
  margin-top: 0.4rem;
}

/* Homepage teaser rows (short sections linking to full pages) */
.teaser-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
}
.teaser-row .section-heading {
  margin-bottom: 0;
  max-width: 720px;
}
.teaser-row .section-heading p:last-child {
  color: var(--white-muted);
  margin-top: 0.5rem;
}
.teaser-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.media > .button {
  margin-top: 1.5rem;
}

/* Hero eyebrow hashtag */
.hero-inner .eyebrow {
  color: var(--red-glow);
  letter-spacing: 0.18em;
}
@media (max-width: 720px) {
  .stats-band .stats {
    grid-template-columns: 1fr;
  }
  .teaser-row {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Hero stat bubbles — uniform size, aligned column, staggered float only */
.hero-stat:nth-child(1) {
  animation-delay: 0s;
  width: 108px;
  height: 108px;
}
.hero-stat:nth-child(2) {
  animation-delay: 1.6s;
  width: 108px;
  height: 108px;
  margin-right: 0;
}
.hero-stat:nth-child(3) {
  animation-delay: 3.2s;
  width: 108px;
  height: 108px;
  margin-right: 0;
}
.hero-stat::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid rgba(255, 42, 75, 0.35);
  animation: bubblePulse 3.2s ease-in-out infinite;
  pointer-events: none;
}
.hero-stat {
  position: relative;
}
.hero-stat:nth-child(2)::after { animation-delay: 1s; }
.hero-stat:nth-child(3)::after { animation-delay: 2s; }
@keyframes bubblePulse {
  0%, 100% { transform: scale(1); opacity: 0.55; }
  50% { transform: scale(1.05); opacity: 0; }
}
@media (max-width: 900px) {
  /* .hero is a flex ROW, and .hero-stats is a sibling of .hero-inner. Dropping
     the stats out of absolute positioning without also turning the hero into a
     column just made them a second flex item beside the copy — the bubble row
     (3 x 108px plus gaps) then pushed ~200px past the viewport and got clipped
     by body{overflow-x:hidden}. Stacking the hero is what actually puts them
     underneath the headline. */
  .hero {
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
  }

  .hero-inner {
    width: 100%;
  }

  .hero-stats {
    position: static;
    transform: none;
    flex-direction: row;
    justify-content: center;
    flex-wrap: wrap;
    gap: 14px;
    width: 100%;
    margin-top: 1.5rem;
  }
  .hero-stat:nth-child(2),
  .hero-stat:nth-child(3) {
    margin-right: 0;
  }
}

@media (max-width: 460px) {
  /* Three 108px bubbles plus gaps need 352px, and the hero's own side padding
     eats 80px, so they start wrapping to a second row below ~435px. Shrinking
     to 92px (296px total) keeps them on one line down to the 320px floor. */
  .hero-stat:nth-child(1),
  .hero-stat:nth-child(2),
  .hero-stat:nth-child(3) {
    width: 92px;
    height: 92px;
  }

  .hero-stats {
    gap: 10px;
  }
}

/* ============================================================
   Brand logo — header sizing fix + glossy/metallic showcase.
   The logo artwork itself is never altered (no recolor, no
   reshaping); these are pure CSS overlays: depth shadows for a
   metallic feel, and a light-sweep masked to the logo's own
   silhouette so the shine only ever passes across the actual
   artwork, never a rectangle around it.
   ============================================================ */

/* Header logo: size by height (not width) so the new wide logo
   fits the header without overflow at any screen size. */
.brand {
  position: relative;
  height: 100%;
  width: auto;
}
.brand img {
  height: clamp(34px, 5.2vw, 50px);
  width: auto;
  max-width: none;
  filter:
    drop-shadow(0 1px 0 rgba(255, 255, 255, 0.28))
    drop-shadow(0 8px 18px rgba(0, 0, 0, 0.55))
    drop-shadow(0 0 16px rgba(216, 162, 74, 0.22));
}

/* Shared shine-sweep overlay: a diagonal highlight band, masked to
   the logo's own alpha shape, that periodically flashes across it. */
.brand::after,
.brand-crest::after,
.footer-brand::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    115deg,
    transparent 32%,
    rgba(255, 255, 255, 0.9) 47%,
    rgba(255, 240, 210, 0.35) 53%,
    transparent 68%
  );
  background-size: 300% 300%;
  -webkit-mask-image: url("assets/skyyrex-brand-logo.png");
  mask-image: url("assets/skyyrex-brand-logo.png");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  mix-blend-mode: screen;
  pointer-events: none;
}
.brand::after {
  animation: crestShine 6s ease-in-out infinite;
}

/* Hero brand crest: a larger showcase of the logo above the eyebrow,
   with more pronounced metallic depth and a slower, bolder sweep. */
.brand-crest {
  position: relative;
  width: clamp(150px, 20vw, 232px);
  margin-bottom: clamp(1rem, 2.4vw, 1.6rem);
}
.brand-crest img {
  width: 100%;
  height: auto;
  filter:
    drop-shadow(0 1px 0 rgba(255, 255, 255, 0.3))
    drop-shadow(0 14px 30px rgba(0, 0, 0, 0.6))
    drop-shadow(0 0 26px rgba(216, 162, 74, 0.26));
}
.brand-crest::after {
  animation: crestShine 5s ease-in-out infinite;
}

.footer-brand::after {
  animation: crestShine 6s ease-in-out infinite;
  animation-delay: 1.5s;
}

@keyframes crestShine {
  0%, 55% {
    background-position: 140% 0%;
  }
  75% {
    background-position: -40% 0%;
  }
  100% {
    background-position: -40% 0%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .brand::after,
  .brand-crest::after,
  .footer-brand::after {
    animation: none;
    opacity: 0;
  }
}

@media (max-width: 640px) {
  .brand-crest {
    width: clamp(120px, 34vw, 170px);
  }
}

/* ---------------------------------------------------------------------------
   GALLERY — vertical reel rail + mixed landscape wall (videos and photos)
   Driven by data/gallery.json; markup in server/views.js renderGalleryPage().
   --------------------------------------------------------------------------- */

.gallery-section {
  margin-bottom: 4.5rem;
}

.gallery-head {
  margin-bottom: 1.5rem;
}

.gallery-head h2 {
  margin: 0.35rem 0 0.5rem;
}

/* --- Reel rail: horizontal scroll-snap of 9:16 clips --- */

/* Positioning context for the prev/next arrows, which overlay the rail edges. */
.reel-carousel {
  position: relative;
}

.reel-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: clamp(210px, 22vw, 280px);
  gap: 1rem;
  margin: 0;
  padding: 0 0 1rem;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* `proximity`, not `mandatory`: mandatory snapping fights the programmatic
     smooth scroll the auto-advance uses, and can cancel it mid-flight. */
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

/* The rail advances on its own, so the scrollbar is visual noise. Dragging and
   wheel-scrolling still work. */
.reel-rail::-webkit-scrollbar {
  display: none;
}

.reel-nav {
  position: absolute;
  top: calc(50% - 1.4rem);
  z-index: 4;
  width: 2.8rem;
  height: 2.8rem;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.62);
  color: var(--white);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(10px);
  transition: border-color 180ms ease, transform 180ms ease;
}

.reel-nav:hover,
.reel-nav:focus-visible {
  border-color: rgba(255, 42, 75, 0.85);
  transform: scale(1.06);
}

.reel-prev {
  left: -0.6rem;
}

.reel-next {
  right: -0.6rem;
}

@media (max-width: 640px) {
  /* Arrows would sit on top of the cards at this width; the rail is swipeable
     and still auto-advances, so drop them. */
  .reel-nav {
    display: none;
  }
}

.reel {
  position: relative;
  aspect-ratio: 9 / 16;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0.7rem;
  overflow: hidden;
  background: #0a0d14;
  scroll-snap-align: center;
}

/* The clip fills its frame; sources are already 9:16 so cover crops nothing. */
.reel-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Legibility scrim behind the caption — the footage underneath varies wildly
   in brightness, so the label needs its own contrast floor. */
.reel::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.82), transparent);
  pointer-events: none;
}

.reel-meta {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  padding: 0.85rem;
  display: grid;
  gap: 0.15rem;
}

.reel-meta strong {
  font-size: 0.92rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.reel-loc {
  color: var(--silver);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.reel-sound {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 3;
  padding: 0.35rem 0.6rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.6);
  color: var(--white);
  font-size: 0.66rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
  backdrop-filter: blur(8px);
}

.reel-sound:hover,
.reel-sound:focus-visible {
  border-color: rgba(216, 162, 74, 0.75);
}

/* No `is-playing` highlight: every on-screen reel plays, so a "playing" border
   would just outline all of them and mean nothing. The class is still set —
   it's what the sound toggle and the observer read. */

/* --- Landscape wall: mixed video + photo tiles --- */

.tile-wall {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  /* Tiles hug their own content. Without this they stretch to the row height,
     and since a `wide` tile spans two columns its 16:9 media is taller than a
     single-column neighbour's — leaving a dead black gap under the short one. */
  align-items: start;
}

.tile {
  position: relative;
  margin: 0;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0.7rem;
  overflow: hidden;
  background: #0a0d14;
}

/* Wide tiles span two columns — breaks up the grid so it reads as a designed
   wall rather than a uniform contact sheet. */
.tile.wide {
  grid-column: span 2;
}

/* One shared 16:9 frame for every tile, photo or video, so rows line up
   regardless of the source aspect ratio. */
.tile img,
.tile video {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}

.tile figcaption {
  padding: 0.85rem;
  display: grid;
  gap: 0.2rem;
}

.tile figcaption strong {
  font-size: 0.9rem;
  font-weight: 900;
  text-transform: uppercase;
}

.tile figcaption p {
  margin: 0;
  color: var(--silver);
  font-size: 0.82rem;
}

.tile-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 3.4rem;
  height: 3.4rem;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.34);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  color: var(--white);
  font-size: 1.1rem;
  cursor: pointer;
  backdrop-filter: blur(8px);
  transition: opacity 180ms ease, transform 180ms ease, border-color 180ms ease;
}

/* Caption sits below the frame, so centre the button on the video area only. */
.tile-video .tile-play {
  top: calc((100% - 3.2rem) / 2);
}

.tile-play:hover,
.tile-play:focus-visible {
  border-color: rgba(216, 162, 74, 0.8);
  transform: translate(-50%, -50%) scale(1.06);
}

/* While a tile plays the control gets out of the way — nothing sits over the
   picture until you go looking for it — and fades back in on hover or keyboard
   focus. It keeps `pointer-events`, unlike the original rule here, which paired
   `opacity: 0` with `pointer-events: none` and left a playing clip with no stop
   control at all. */
.tile.is-playing .tile-play {
  opacity: 0;
}

.tile.is-playing:hover .tile-play,
.tile.is-playing:focus-within .tile-play,
.tile.is-playing .tile-play:focus-visible {
  opacity: 1;
}

/* Touch has no hover to reveal anything, so on those devices the button stays
   faintly visible rather than disappearing for good. Tapping the picture
   toggles playback as well, but a control you cannot see is not a control, and
   this is the only affordance that says the clip can be stopped. */
@media (hover: none) {
  .tile.is-playing .tile-play {
    opacity: 0.32;
  }
}

/* The picture itself toggles playback, so say so. */
.tile-video .tile-video-el {
  cursor: pointer;
}

@media (max-width: 920px) {
  .tile-wall {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .tile-wall {
    grid-template-columns: 1fr;
  }

  /* With one column, a spanning tile would overflow the track. */
  .tile.wide {
    grid-column: auto;
  }
}

/* ---------------------------------------------------------------------------
   HOMEPAGE DENSITY PASS
   The homepage used to stack five near-identical "teaser row" sections, each
   holding one heading and one sentence, separated by up to 17rem of combined
   .section padding. That is where the empty space came from. These rules
   replace that with a tighter vertical rhythm plus two horizontal rails, so
   every fact stays on the page while the page itself gets materially shorter.
   Markup: public/index.html; data filled in by renderHomePage() in views.js.
   --------------------------------------------------------------------------- */

/* Roughly half the stock .section padding. Applied to every homepage block so
   the rhythm stays even — mixing tight and untight sections reads as a mistake. */
.section-tight {
  padding: clamp(2.5rem, 5vw, 4rem) 0;
}

/* Heading on the left, the section's escape hatch on the right, sharing one
   line instead of costing a whole row of its own. */
.section-heading-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  max-width: none;
}

.section-heading-row > div {
  /* Without min-width:0 a long h2 refuses to shrink below its text width and
     wraps the button onto its own line, which is what it was doing. */
  flex: 1 1 auto;
  min-width: 0;
  max-width: 820px;
}

.section-heading-row h2 {
  margin: 0.35rem 0 0;
}

.section-heading-row .button {
  flex: none;
}

/* --- Credentials strip -----------------------------------------------------
   Six presskit proof points in one band. auto-fit means it reflows from 3x2 to
   2x3 to 1 column without a single media query. */

.credentials-strip {
  display: grid;
  /* Exactly three across: there are six credentials, so this fills two rows
     with no empty cells. auto-fit gave four and left two gaps. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--line);
  border-radius: 0.7rem;
  overflow: hidden;
  /* The 1px grid gap shows through as hairline dividers between cells, so the
     strip reads as one object rather than six floating boxes. */
  background: var(--line);
}

.credential {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 1.1rem 1.2rem;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.02));
}

.credential strong {
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.01em;
  color: var(--white);
}

.credential span {
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--white-muted);
}

/* --- Explore grid ----------------------------------------------------------
   One grid replacing five teaser rows. Every destination visible at once. */

.explore-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.explore-card {
  display: flex;
}

.explore-card a {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: 100%;
  padding: 1.35rem 1.3rem 1.5rem;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0.7rem;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.025));
  color: var(--white);
  text-decoration: none;
  transition: border-color 180ms ease, transform 180ms ease, background 180ms ease;
}

.explore-card a:hover,
.explore-card a:focus-visible {
  border-color: rgba(255, 42, 75, 0.75);
  background: linear-gradient(145deg, rgba(255, 42, 75, 0.14), rgba(255, 255, 255, 0.03));
  transform: translateY(-3px);
}

.explore-index {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  color: var(--red-glow);
}

.explore-card strong {
  font-size: 1.25rem;
  font-weight: 900;
  letter-spacing: -0.01em;
}

.explore-card a > span:last-child {
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--white-muted);
}

/* The Vault is the one card that sells something, so it gets the accent. */
.explore-card-gold a {
  border-color: rgba(255, 42, 75, 0.42);
  background: linear-gradient(145deg, rgba(255, 42, 75, 0.16), rgba(255, 255, 255, 0.03));
}

/* --- Venue rails -----------------------------------------------------------
   45 venues. Stacked vertically that is a wall of text; as rails each group
   costs one row of height and stays scannable. */

.venue-group + .venue-group {
  margin-top: 1.6rem;
}

.venue-group-title {
  margin: 0 0 0.7rem;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red-glow);
}

.venue-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(210px, 240px);
  gap: 0.75rem;
  margin: 0;
  padding: 0 0 0.6rem;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.22) transparent;
  /* Fades the right edge so it reads as "there is more here" rather than as a
     row that happens to end at the viewport. */
  mask-image: linear-gradient(to right, #000 0, #000 92%, transparent 100%);
}

.venue-rail::-webkit-scrollbar {
  height: 6px;
}

.venue-rail::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.22);
}

.venue-card {
  display: flex;
  flex-direction: column;
  gap: 0.22rem;
  padding: 0.85rem 0.95rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 0.55rem;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02));
  scroll-snap-align: start;
}

.venue-card strong {
  font-size: 0.94rem;
  font-weight: 700;
  line-height: 1.3;
}

.venue-city {
  font-size: 0.8rem;
  color: var(--white-muted);
}

.venue-note {
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--red-laser);
}

/* --- Homepage reel band ---------------------------------------------------- */

/* Slightly smaller than the /gallery rail: on the homepage this is a taste of
   the gallery, not the destination itself. */
.reel-band .reel-rail {
  grid-auto-columns: clamp(180px, 19vw, 240px);
}

.showcase-actions {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}

/* The booking CTA closes the page, so it keeps a divider above it — the other
   tightened sections no longer need one now that they carry real content. */
.booking-cta {
  border-top: 1px solid var(--line);
}

@media (max-width: 920px) {
  .explore-grid,
  .credentials-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  /* Two across, not one: six full-width cards is most of a phone screen of
     scrolling on its own, and these cards are short enough to pair up. */
  .explore-grid,
  .credentials-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
  }

  .explore-card a {
    padding: 0.9rem 0.85rem 1rem;
    gap: 0.25rem;
  }

  .explore-card strong {
    font-size: 1.05rem;
  }

  .explore-card a > span:last-child {
    font-size: 0.8rem;
  }

  .credential {
    padding: 0.85rem 0.9rem;
  }

  /* Phones have the least room to spare, so the rhythm tightens again here. */
  .section-tight {
    padding: 1.9rem 0;
  }

  .section-heading-row {
    align-items: flex-start;
  }

  .venue-rail {
    grid-auto-columns: minmax(180px, 72vw);
  }
}

/* Below this the two-column cards get too narrow to read. */
@media (max-width: 380px) {
  .explore-grid,
  .credentials-strip {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Footer links were 20px tall — under the 24x24 minimum WCAG 2.2 AA asks for on
   touch targets, and genuinely fiddly to hit on a phone. Padding lifts them
   past the threshold without changing the type size or the layout. */
.footer div a {
  display: inline-block;
  padding: 0.35rem 0.15rem;
}


/* ---------------------------------------------------------------------------
   BOOK DJ — primary header CTA
   The button carries both .header-cta and .btn-cta. .btn-cta comes later in
   this file and sets `background: rgba(255,255,255,.05)`, so it was winning and
   the button rendered as a near-black pill — the opposite of a primary action.
   The doubled selector below outranks it.

   Note --gold in :root is aliased to the brand red, so it cannot be used here;
   these are the actual gold stops from the logo artwork.
   --------------------------------------------------------------------------- */

.header-cta.btn-cta {
  position: relative;
  overflow: hidden;
  isolation: isolate;

  background: linear-gradient(135deg, #ffeaa9 0%, #e2ab52 36%, #b8762a 62%, #ffe08d 100%);
  /* Dark ink on gold — white text on this gradient fails contrast badly. */
  color: #2b1c05;
  border: 1px solid rgba(255, 226, 154, 0.8);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
  box-shadow:
    0 10px 28px rgba(224, 169, 79, 0.38),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
  /* Replaces the red ctaGlow pulse, which clashed with a gold face. */
  animation: ctaGoldGlow 3s ease-in-out infinite;
}

/* Light sweep across the face, in the same spirit as the logo shine. */
.header-cta.btn-cta::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    115deg,
    transparent 34%,
    rgba(255, 255, 255, 0.85) 48%,
    rgba(255, 246, 214, 0.5) 54%,
    transparent 66%
  );
  background-size: 250% 100%;
  background-repeat: no-repeat;
  animation: ctaShine 4.5s ease-in-out infinite;
  pointer-events: none;
}

.header-cta.btn-cta:hover,
.header-cta.btn-cta:focus-visible {
  background: linear-gradient(135deg, #fff4c6 0%, #f0bd63 36%, #cc8730 62%, #ffeaa5 100%);
  border-color: rgba(255, 244, 198, 0.95);
  box-shadow:
    0 14px 34px rgba(240, 189, 99, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

@keyframes ctaGoldGlow {
  0%, 100% {
    box-shadow:
      0 10px 28px rgba(224, 169, 79, 0.34),
      inset 0 1px 0 rgba(255, 255, 255, 0.6);
  }
  50% {
    box-shadow:
      0 12px 32px rgba(255, 205, 110, 0.55),
      0 0 20px 2px rgba(255, 198, 92, 0.4),
      inset 0 1px 0 rgba(255, 255, 255, 0.7);
  }
}

@keyframes ctaShine {
  0%, 62% { background-position: 135% 0; }
  88%, 100% { background-position: -45% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .header-cta.btn-cta {
    animation: none;
  }
  .header-cta.btn-cta::after {
    animation: none;
    opacity: 0;
  }
}


/* ---------------------------------------------------------------------------
   CONTENT CARD PAGES (/about, /spotlight, /privacy, /terms)
   Two problems this fixes:

   1. Card headings inherited the global h2 size — clamp(2rem, 6vw, 5rem), i.e.
      up to 80px. That is a hero size. Inside a half-width card it wrapped
      "Certified by A.R. Rahman's KM Music Conservatory." onto five lines and
      made each card enormous.

   2. The cards were a two-column grid. Their content lengths vary a lot (some
      carry a photo, some are three lines), so one column ran far longer than
      the other and left large empty panels beside the short cards.
      Column flow packs them by height instead, so the two sides stay level and
      no gaps open up.
   --------------------------------------------------------------------------- */

.page-card-grid {
  display: block;
  column-count: 2;
  column-gap: 1rem;
}

/* Every direct child of a column-flow container needs this, not just
   `.page-card`. A multicol container has no `gap` in the block direction and
   no row model, so each child has to carry its own bottom margin, be a
   full-column-wide block, and refuse to be split across the column break.
   The guard used to be written as `.page-card-grid .page-card`, which meant
   any child that was not a `.page-card` — the vault cards, see below — got
   none of it and stacked border-to-border.
   `:not(.vault-grid)` because that variant is put back on a real grid below,
   where these declarations would fight the grid rather than help it. */
.page-card-grid:not(.vault-grid) > * {
  /* Stop a card being split across the column break. */
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  display: inline-block;
  width: 100%;
  margin-bottom: 1rem;
}

/* --- The vault collection grids are the exception --------------------------
   server/views.js renders them as `<div class="vault-grid page-card-grid">`,
   so the column-flow rules above were catching them too, and broke them twice:

   1. `display: block` defeated `.vault-grid`'s grid, so the three-up layout
      collapsed into two content-packed columns.
   2. The children are `.vault-card`, not `.page-card`, so before the guard
      above was broadened they had neither `break-inside: avoid` nor a bottom
      margin. Adjacent cards' 1px borders met with zero gap and read as one
      doubled outline, and because `.vault-card` sets `overflow: hidden` it is
      a monolithic box — the browser cannot split it, so a tall card spills out
      of its column and lands on top of the next column's card instead.

   Vault cards are uniform in shape, so they want a real grid with a real gap,
   not the height-packed column flow the content cards on /about and
   /spotlight are asking for. Two classes here so this outranks both the
   single-class column rules above and `.vault-grid`'s own narrow-width rule.

   Follow-up worth doing in markup: drop `page-card-grid` from that div in
   server/views.js and these three overrides stop being necessary. */
.page-card-grid.vault-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-count: auto;
  gap: 1rem;
  /* Same intent the old grid rule carried: cards size to their own content
     rather than stretching to the tallest in the row, so a short card does not
     open a dead panel underneath itself. */
  align-items: start;
}

.page-card h2 {
  font-size: clamp(1.15rem, 1.7vw, 1.55rem);
  line-height: 1.2;
  margin-bottom: 0.55rem;
  letter-spacing: -0.01em;
}

.page-card p {
  font-size: 0.94rem;
  line-height: 1.6;
}

.page-card .eyebrow {
  margin-bottom: 0.35rem;
}

@media (max-width: 920px) {
  .page-card-grid {
    column-count: 1;
  }

  /* Same ladder the other three-up grids in this file use: three, then two,
     then one. `.vault-grid`'s own rule drops straight from three to one at
     this width, which leaves a single narrow card per row on a tablet. */
  .page-card-grid.vault-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .page-card-grid.vault-grid {
    grid-template-columns: 1fr;
  }
}


/* The press-kit panel's heading was still picking up the global h2 clamp
   (up to 80px), so "Everything a promoter needs before confirming the show."
   ran to seven lines beside a four-item grid. Sized to sit with the panel. */
.epk-panel .section-heading h2 {
  font-size: clamp(1.4rem, 2.4vw, 2.1rem);
  line-height: 1.15;
}

.epk-panel .section-heading {
  max-width: 46ch;
}


/* Same story on the vault pages. `.page-stack` is the intro block that sits
   above the collection grid (`renderVaultPage` / the category page in
   server/views.js) and its <h2> was still on the global hero clamp — up to
   80px of uppercase sitting directly above 1.16rem card headings, which read
   as two unrelated pages stacked rather than one. Sized to lead the grid it
   introduces, and capped so the line does not run the full 1180px shell. */
.page-stack h2 {
  font-size: clamp(1.5rem, 3vw, 2.3rem);
  line-height: 1.1;
  margin-bottom: 0.6rem;
}

.page-stack p {
  max-width: 62ch;
}


/* Optional outbound link on a content card (data/pages.json `link`). Sits
   under the copy as a quiet inline action rather than a button, so it does not
   compete with the page's real CTAs. */
.page-card .card-link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.7rem;
  padding: 0.3rem 0;
  color: var(--red-laser);
  font-size: 0.86rem;
  font-weight: 800;
  letter-spacing: 0.01em;
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 92, 117, 0.4);
  transition: color 160ms ease, border-color 160ms ease;
}

.page-card .card-link::after {
  content: "\2197";
  font-size: 0.95em;
}

.page-card .card-link:hover,
.page-card .card-link:focus-visible {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.6);
}

/* Site credit line under the footer links. Overrides the big uppercase
   .footer p / .footer a styles so it reads as a quiet sign-off. */
.footer .footer-credit {
  margin-top: 1.6rem;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}

.footer .footer-credit a {
  color: var(--white);
  font-weight: 700;
  text-transform: none;
}

/* Direct-UPI checkout steps (shown inside .purchase-downloads after the
   order is created). Each step is a bordered block so "pay" and "confirm"
   read as two separate actions. */
.purchase-downloads .pay-step {
  display: grid;
  gap: 0.6rem;
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
}

.purchase-downloads .pay-step-title {
  color: var(--white);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.purchase-downloads .upi-id {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  word-break: break-all;
}

.purchase-downloads .upi-id .button {
  width: auto;
}

.purchase-downloads .upi-qr {
  width: min(220px, 100%);
  height: auto;
  border-radius: 8px;
  background: #fff;
  padding: 0.5rem;
}

/* ---------------------------------------------------------------------------
   PAID COLLECTION LAUNCH (2026-10)
   Exclusive set block, pack track counts, and the two-step UPI checkout
   (QR -> UTR + screenshot).
   ------------------------------------------------------------------------- */
.vault-featured {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  border: 1px solid var(--red-glow);
  background:
    radial-gradient(circle at 15% 0%, rgba(255, 42, 75, 0.22), transparent 60%),
    var(--black-panel);
  box-shadow: 0 0 0 1px rgba(255, 42, 75, 0.25), 0 24px 70px rgba(214, 0, 28, 0.18);
}

.vault-featured > div:first-child {
  flex: 1 1 320px;
}

.vault-featured .vault-actions {
  display: grid;
  gap: 0.75rem;
  justify-items: start;
}

.vault-featured .vault-actions strong {
  font-size: 2rem;
  color: var(--white);
}

.vault-tracks {
  color: var(--red-laser);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.pay-howto {
  margin: 1rem 0;
  padding-left: 1.25rem;
  display: grid;
  gap: 0.4rem;
  color: var(--white);
}

.purchase-downloads .upi-qr {
  width: min(240px, 100%);
  justify-self: center;
}

.purchase-downloads .pay-summary {
  margin: 0;
  padding-left: 1.1rem;
  color: var(--muted);
  display: grid;
  gap: 0.2rem;
}

.purchase-downloads .pay-step label {
  display: grid;
  gap: 0.4rem;
}

.purchase-downloads .pay-step input[type="file"] {
  padding: 0.6rem;
}

.purchase-downloads .pay-status:empty {
  display: none;
}

.purchase-downloads .pay-done {
  border-color: var(--red-glow);
}

/* `.vault-card div` lays every inner block out as a row, which squeezed the
   pack count / description beside the title. Stack the title block only; the
   actions row below keeps its row layout. */
.vault-card > div:first-child {
  flex-direction: column;
  gap: 0.35rem;
  margin-bottom: 1rem;
}

/* Page titles with a long single word ("Performance-Ready", "Moombahton") ran
   off the right edge at the full-size h1, widening the page and leaving a dark
   strip. views.js adds .title-long for those; overflow-wrap is the last resort
   for anything longer still. */
h1.title-long {
  font-size: clamp(2.2rem, 8vw, 6.5rem);
  line-height: 0.9;
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------------------
   WHATSAPP ORDERING (2026-10)
   Home hero call to action, the "Buy opens WhatsApp" hint, the How buying
   works card, and the hand-off panel shown after a Buy / Contact tap.
   ------------------------------------------------------------------------- */
.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

.buy-hint {
  color: var(--muted);
  font-size: 0.95rem;
}

.buy-hint a,
.how-it-works a {
  color: var(--red-laser);
  font-weight: 700;
}

.how-it-works {
  scroll-margin-top: 90px;
}

.how-it-works .pay-howto li {
  line-height: 1.5;
}

.wa-handoff {
  position: fixed;
  z-index: 1000;
  right: 1.25rem;
  bottom: 1.25rem;
  width: min(420px, calc(100vw - 2rem));
  max-height: calc(100vh - 2.5rem);
  overflow-y: auto;
  padding: 1.25rem 1.25rem 1rem;
  border: 1px solid var(--red-glow);
  border-radius: 16px;
  background: var(--black-panel);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(255, 42, 75, 0.2);
}

.wa-handoff h2 {
  font-size: 1.35rem;
  margin: 0.25rem 2rem 0.5rem 0;
}

.wa-handoff h2:focus {
  outline: none;
}

.wa-handoff p {
  margin: 0 0 0.75rem;
}

.wa-handoff-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

/* z-index: the panel's "Check WhatsApp" label (.eyebrow) runs a fade-in
   animation, which puts it in its own layer painted above this button, so its
   full-width line swallowed clicks on the X. */
.wa-handoff-close {
  position: absolute;
  z-index: 2;
  top: 0.6rem;
  right: 0.6rem;
  width: 36px;
  height: 36px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--white);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

@media (max-width: 600px) {
  .wa-handoff {
    right: 1rem;
    left: 1rem;
    bottom: 1rem;
    width: auto;
  }
  .wa-handoff-actions .button {
    flex: 1 1 100%;
    text-align: center;
  }
}

.footer .footer-follow {
  margin: 0.5rem 0 1rem;
}

.footer .footer-follow a {
  color: var(--white);
  text-transform: none;
}

/* ---------------------------------------------------------------------------
   GOLD CALL-OUT (2026-10)
   The selling panel under the Vault / category headings: a gold-edged glass
   panel, a headline in the same gold as the Buy Packs button with a slow light
   sweep across the letters, one supporting sentence, and gold badges.
   The headline gradient is painted through the text (background-clip), so
   color is the fallback; the sweep stops for visitors who ask for reduced
   motion.
   ------------------------------------------------------------------------- */
.gold-callout {
  position: relative;
  max-width: 52rem;
  margin: 0.5rem 0 1.6rem;
  padding: 1.15rem 1.35rem 1.2rem 1.6rem;
  border: 1px solid rgba(226, 171, 82, 0.55);
  border-radius: 18px;
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(255, 234, 169, 0.16), transparent 60%),
    linear-gradient(135deg, rgba(226, 171, 82, 0.14), rgba(184, 118, 42, 0.05) 55%, rgba(0, 0, 0, 0.25));
  box-shadow: 0 0 0 1px rgba(255, 234, 169, 0.08) inset, 0 18px 50px rgba(224, 169, 79, 0.16);
  overflow: hidden;
}

/* Gold edge down the left side. */
.gold-callout::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 5px;
  background: linear-gradient(180deg, #ffeaa9, #e2ab52 45%, #b8762a);
}

.gold-callout-title {
  margin: 0 0 0.5rem;
  font-size: clamp(1.35rem, 4.2vw, 2.35rem);
  font-weight: 900;
  line-height: 1.08;
  letter-spacing: 0.035em;
  text-transform: uppercase;
  color: #e2ab52;
  background-image: linear-gradient(
    100deg,
    #b8762a 0%,
    #e2ab52 20%,
    #ffeaa9 36%,
    #fffbe8 46%,
    #ffeaa9 56%,
    #e2ab52 72%,
    #b8762a 100%
  );
  background-size: 250% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 14px rgba(224, 169, 79, 0.4));
  animation: gold-sweep 5.5s ease-in-out infinite;
}

.gold-callout-text {
  margin: 0 0 0.9rem;
  color: #f6ead0;
  font-size: clamp(0.98rem, 2.3vw, 1.15rem);
  font-weight: 600;
  line-height: 1.5;
}

.gold-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.gold-chips li {
  padding: 0.32rem 0.8rem;
  border: 1px solid rgba(226, 171, 82, 0.6);
  border-radius: 999px;
  background: rgba(226, 171, 82, 0.1);
  color: #ffeaa9;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.gold-chips li::before {
  content: "◆";
  margin-right: 0.45em;
  font-size: 0.7em;
  vertical-align: 0.1em;
  color: #e2ab52;
}

@keyframes gold-sweep {
  0%,
  100% { background-position: 100% 0; }
  50% { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .gold-callout-title {
    animation: none;
    background-position: 40% 0;
  }
}

/* ---------------------------------------------------------------------------
   HERO BUTTONS + SMALL-PHONE HEADINGS (2026-10 layout audit)
   The two buttons under the home hero and under every page heading came in
   three different shapes — a dark pill (.btn-cta), a square glass box
   (.button-glass) and a square red outline (.button-line) — and the home pair
   sat flush against the credits paragraph. One shape for all of them now: the
   main action in the same gold as the header's Buy Packs, the other a quiet
   outline. Buttons inside cards and panels are untouched.
   ------------------------------------------------------------------------- */
.hero-cta {
  margin: 1.4rem 0 1.9rem;
}

.hero-cta .button,
.page-hero .hero-actions .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 50px;
  padding: 0 1.6rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.hero-cta .btn-cta,
.page-hero .hero-actions .btn-cta {
  background: linear-gradient(135deg, #ffeaa9 0%, #e2ab52 36%, #b8762a 62%, #ffe08d 100%);
  color: #2b1c05;
  border: 1px solid rgba(255, 226, 154, 0.8);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
  box-shadow: 0 10px 28px rgba(224, 169, 79, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

.hero-cta .btn-cta:hover,
.page-hero .hero-actions .btn-cta:hover {
  background: linear-gradient(135deg, #fff1c2 0%, #ebb862 36%, #c4832f 62%, #ffe8a6 100%);
  color: #2b1c05;
  border-color: rgba(255, 234, 169, 0.95);
  box-shadow: 0 14px 34px rgba(224, 169, 79, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.hero-cta .button:not(.btn-cta),
.page-hero .hero-actions .button:not(.btn-cta) {
  background: rgba(255, 255, 255, 0.05);
  color: var(--white);
  border: 1px solid rgba(255, 255, 255, 0.3);
}

.hero-cta .button:not(.btn-cta):hover,
.page-hero .hero-actions .button:not(.btn-cta):hover {
  border-color: rgba(255, 234, 169, 0.7);
  color: #ffeaa9;
}

@media (max-width: 600px) {
  .hero-cta .button,
  .page-hero .hero-actions .button {
    flex: 1 1 100%;
  }
}

/* Small phones: the page heading's 56px minimum made a nine-letter word
   ("BOLLYWOOD") wider than a 360px screen, so the whole page scrolled
   sideways. Let it shrink with the screen. Long-word titles keep their own,
   smaller .title-long size. */
@media (max-width: 420px) {
  .page-hero h1:not(.title-long) {
    font-size: clamp(2.3rem, 12.5vw, 3.5rem);
  }
}

/* "Everything, one tap away" grid: as many columns as there are cards. The
   launch hides four of the six, and the fixed 3-column grid left the last
   column empty. The numbers come from a counter, so they read 01, 02... for
   whichever cards are visible instead of the old fixed "04", "05". */
.explore-grid {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  counter-reset: explore;
}

.explore-card {
  counter-increment: explore;
}

.explore-index {
  font-size: 0;
}

.explore-index::before {
  content: counter(explore, decimal-leading-zero);
  font-size: 0.72rem;
}

/* Bookings teaser buttons: same pill as the hero buttons. When "Book Now" is
   hidden (booking switched off), the remaining button becomes the gold one so
   the section still has a clear action. */
.teaser-actions .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 50px;
  padding: 0 1.6rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.teaser-actions .btn-cta,
.teaser-actions .button:only-child {
  background: linear-gradient(135deg, #ffeaa9 0%, #e2ab52 36%, #b8762a 62%, #ffe08d 100%);
  color: #2b1c05;
  border: 1px solid rgba(255, 226, 154, 0.8);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
  box-shadow: 0 10px 28px rgba(224, 169, 79, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

/* Inside the WhatsApp hand-off panel the label needs no entrance animation,
   and it must stop short of the close button. */
.wa-handoff .eyebrow {
  animation: none;
  opacity: 1;
  margin-right: 2.75rem;
}
