/* ---------- Brand fonts (see assets/OGdesigns brand book p.13) ---------- */

@font-face {
  font-family: "Archive Black Title";
  src: url("fonts/archive_black_title.otf") format("opentype");
  font-display: swap;
}
@font-face {
  font-family: "Archive Garamond Pro";
  src: url("fonts/ArchiveGaramondPro.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Archive Garamond Pro";
  src: url("fonts/ArchiveGaramondPro-Bold.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Authentic Sans";
  src: url("fonts/authentic-sans-60.woff2") format("woff2");
  font-weight: 300;
  font-display: swap;
}
@font-face {
  font-family: "Authentic Sans";
  src: url("fonts/authentic-sans-90.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Authentic Sans";
  src: url("fonts/authentic-sans-130.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Authentic Sans";
  src: url("fonts/authentic-sans-150.woff2") format("woff2");
  font-weight: 800;
  font-display: swap;
}

:root {
  /* brand palette, brand book p.12 */
  --old-white: #fffdf5;
  --faded-black: #1d1b1b;
  --espresso: #332e2e;
  --seaweed: #37443f;
  --ferrari-red: #ff2517;
  --hot-pink: #fc2d72;
  --subtle-neon: #6eff75;
  /* buttons that take you off the site (Bandcamp, tickets, YouTube) */
  --leave: var(--old-white);

  --black: #000;
  --white: var(--old-white);
  --sans: "Authentic Sans", -apple-system, system-ui, sans-serif;
  --serif: "Archive Garamond Pro", Georgia, serif;
  --title: "Archive Black Title", "Old English Text MT", serif;

  /* brand submark, section title bullet */
  --star-tile: url("img/submark.svg");
}

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

html { touch-action: manipulation; background: var(--black) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 0.992  0 0 0 0 0.961  0 0 0 0.065 0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E") repeat; }


*, *::before, *::after { touch-action: manipulation; }
body {
  position: relative;
  /* no double-tap zoom, so taps are handled straight away */
  touch-action: manipulation;
  background: transparent;
  color: var(--white);
  font-family: var(--sans);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

/* film grain over the whole page, fixed, on top of everything (modal top layer excepted) */
/* film grain lives on the page canvas itself (html background), so it runs
   seamlessly everywhere the browser paints the page: under the iPhone status
   bar and browser bar, and when the page is pulled past its edges */

/* no scrolling until GO to site is clicked, and nothing below the hero rendered
   at all so Safari cannot show it past the fold when the toolbar collapses */
body.locked { overflow: hidden; height: 100lvh; }
body.locked > :not(.hero, .sticker-layer, dialog) { display: none; }
/* the hero (balloon + menu) fills exactly the part of the screen the browser
   really shows: --app-h is measured in index.html (window height between the
   browser's own bars), so the whole menu is visible in Safari, Chrome and every
   other phone browser. 100svh is the fallback. The grain background (html)
   still runs on underneath the bars */
body.locked .hero { height: 100svh; height: var(--app-h, 100svh); }

img { max-width: 100%; display: block; }
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }

/* ---------- Hero ---------- */

.hero {
  height: 100svh;
  height: var(--app-h, 100svh);
  display: flex;
  flex-direction: column;
  position: relative;
  /* the oversized balloon and the panels running under the nav stay inside the
     screen, so phones never widen the page or zoom out */
  overflow: hidden;
  overflow: clip;
}

.hero-logos {
  position: absolute;
  top: clamp(1.2rem, 3vw, 2.2rem);
  left: clamp(1.5rem, 4vw, 3.5rem);
  right: clamp(1.5rem, 4vw, 3.5rem);
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  z-index: 3;
  pointer-events: none;
}
.hero-logos a { pointer-events: auto; transition: opacity 0.2s; }
@media (hover: hover) { .hero-logos a:hover { opacity: 0.65; } }
.logo-og img { height: clamp(22px, 2.6vw, 36px); width: auto; }
.logo-ftn { height: clamp(28px, 3.6vw, 52px); width: auto; }

.star-stage {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  /* not clipped: panels run on under the nav. The page itself is locked */
  overflow: visible;
}

/* balloon frames and video have a black background. Instead of a blend mode
   (iPhone Safari sometimes stops drawing a video that is blended), the edges of
   the frame fade out with a soft round mask, so there is no visible square */
#star-canvas,
#star-video,
.balloon-grain {
  /* sized from the stage height so the nav always stays in view. The balloon
     fills ~85% of its frame, so 118% of the stage puts the balloon itself at
     roughly full stage height, only empty frame margin gets clipped */
  height: 118%;
  width: auto;
  max-width: none;
  aspect-ratio: 1;
  flex: none;
  display: block;
  transform-style: preserve-3d;
  -webkit-mask-image: radial-gradient(closest-side, #000 82%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 82%, transparent 100%);
}

/* ---------- Stickers ---------- */
/* hover effects only on devices with a real mouse; on phones a tapped sticker
   would otherwise stay half see-through */
/* Hero and nav stickers are supplied PNGs (img/nav/, sources assets/stickers/navbuttons/).
   The element only positions, sizes, tilts and animates the image. */

.sticker {
  --tilt: 0deg;
  --shift: 0px;
  --x: 0px;
  --w: 200px;
  position: relative;
  display: block;
  width: var(--w);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  transform: translate(var(--x), var(--shift)) rotate(var(--tilt));
  transform-origin: 50% 50%;
  z-index: 2;
  transition: transform 0.25s ease, opacity 0.2s;
  animation: slap 0.55s cubic-bezier(0.2, 1.3, 0.4, 1) both;
}
.sticker img {
  width: 100%;
  height: auto;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}

@media (hover: hover) { .sticker:hover {
  transform: translate(var(--x), var(--shift)) rotate(var(--tilt)) scale(1.05);
  opacity: 0.65;
} }

/* hero stickers wait for the balloon, then slap on (delays count from then) */
body:not(.balloon-ready) .sticker-hero { animation-play-state: paused; }
.sticker-hero {
  position: absolute;
  top: 50%;
  --shift: -50%;
}
/* GO clicked: hero stickers peel off, nav stickers slap in */
.hero.revealed .sticker-hero {
  animation: peel 0.4s cubic-bezier(0.5, 0, 0.8, 0.4) forwards;
  pointer-events: none;
}
@keyframes peel {
  to {
    opacity: 0;
    transform: translate(var(--x), var(--shift)) rotate(calc(var(--tilt) + 10deg)) scale(1.5);
  }
}

.sticker-left {
  --tilt: -5deg;
  --w: clamp(220px, 24vw, 330px);
  left: max(4vw, calc(50% - min(45vmin, 410px) - 40px));
  animation-delay: 0.45s;
}

.sticker-right {
  --tilt: 3deg;
  --w: clamp(200px, 22vw, 300px);
  right: max(4vw, calc(50% - min(45vmin, 410px) - 40px));
  animation-delay: 0.7s;
}

@keyframes slap {
  0% {
    opacity: 0;
    transform: translate(var(--x), var(--shift)) rotate(calc(var(--tilt) - 14deg)) scale(1.7);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(var(--x), var(--shift)) rotate(var(--tilt)) scale(1);
  }
}

/* Bottom nav: hidden until "GO to site", then stickers slap in left to right */

.main-nav {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: clamp(0.8rem, 2vw, 1.6rem);
  padding: 1.2rem clamp(1.5rem, 4vw, 3.5rem) 1.6rem;
  visibility: hidden;
}
.hero.revealed .main-nav { visibility: visible; }

.sticker-nav {
  animation: none;
  opacity: 0;
}
.hero.revealed .sticker-nav {
  animation: slap 0.5s cubic-bezier(0.2, 1.3, 0.4, 1) both;
  animation-delay: calc(var(--i) * 0.08s);
}

/* shrink with the screen on tablets and small laptops, full size from ~1270px */
.nav-bandcamp { --w: clamp(110px, 15vw, 190px); --tilt: -4deg; }
.nav-tickets  { --w: clamp(88px, 11.8vw, 150px); --tilt: 3deg; }
.nav-streams  { --w: clamp(80px, 10.6vw, 135px); --tilt: -3deg; }
.nav-music    { --w: clamp(80px, 10.6vw, 135px); --tilt: 5deg; }
.nav-merch    { --w: clamp(70px, 9.4vw, 120px); --tilt: -6deg; }

/* ---------- Views: balloon floats up, panel rises ---------- */
/* body[data-view] is home, tickets, streams, music or merch (js/site.js) */

.balloon {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* coming home: drifts back down and settles with a small bounce */
  transition: transform 1.2s cubic-bezier(0.3, 0, 0.25, 1.12), opacity 0.5s ease;
  /* fades in the moment its first frame is ready (js/star.js) */
  opacity: 0;

  will-change: transform;
}
body.balloon-ready .balloon { opacity: 1; }
/* once it has floated out, it is hidden for good until it comes back down */
body.balloon-away .balloon { visibility: hidden; }
body:not([data-view="home"]) .balloon {
  /* leaving: small dip, then floats up and out of the stage */
  /* a full screen height plus margin: always completely above the screen,
     whatever the phone, the stage size or the balloon size */
  transform: translateY(calc(-1 * var(--app-h, 100svh) - 4rem));
  transition-timing-function: cubic-bezier(0.5, -0.25, 0.65, 1);
}
.balloon-wiggle {
  width: 100%;
  height: 100%;
  /* balloon and its grain layer share one grid cell, so they line up exactly */
  display: grid;
  /* one cell exactly the size of the stage, so the balloon's max-height has a
     real height to stay within and never runs into the menu on short screens */
  grid-template: 100% / 100%;
  place-items: center;
}
.balloon-wiggle > * { grid-area: 1 / 1; }
/* the page grain, repeated on top of the balloon's black frame (same soft round
   mask), so the grain looks the same across the whole screen */
.balloon-grain {
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 0.992  0 0 0 0 0.961  0 0 0 0.078 0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E") repeat;
}
.balloon-wiggle.wobble { animation: wobble 1.2s ease-in-out; }
@keyframes wobble {
  0%   { transform: rotate(0); }
  15%  { transform: rotate(-8deg); }
  35%  { transform: rotate(7deg); }
  55%  { transform: rotate(-5deg); }
  75%  { transform: rotate(3deg); }
  100% { transform: rotate(0); }
}

.panels {
  --panel-top: clamp(4.6rem, 7vw, 6.4rem);
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}
.panel {
  position: absolute;
  /* runs on under the nav so content fades out behind the stickers */
  inset: var(--panel-top) 0 calc(-1 * var(--nav-h, 150px));
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 253, 245, 0.25) transparent;
  opacity: 0;
  visibility: hidden;
  transform: translateY(16vh);
  transition: opacity 0.4s ease, transform 0.5s ease, visibility 0s linear 0.5s;
  /* soft fade where content scrolls under the logos and the nav */
  /* long soft fade: content drifts out under the logos and stays faintly
     visible behind the nav stickers */
  --fade: linear-gradient(to bottom, transparent 0, #000 2.4rem, #000 calc(100% - var(--nav-h, 150px) - 4rem), rgba(0, 0, 0, 0.5) calc(100% - var(--nav-h, 150px) - 0.5rem), rgba(0, 0, 0, 0.12) calc(100% - var(--nav-h, 150px) * 0.45), transparent 100%);
  -webkit-mask-image: var(--fade);
  mask-image: var(--fade);
}
.panel.active {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
  /* waits for the balloon to clear, then floats up into place */
  transition: opacity 0.6s ease 0.6s, transform 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.08) 0.6s, visibility 0s;
}
.panel-inner {
  max-width: 1100px;
  margin: 0 auto;
  /* bottom padding lets the last row scroll clear of the nav */
  padding: 1.6rem clamp(1.5rem, 5vw, 4rem) calc(var(--nav-h, 150px) + 1rem);
}
.panel h2 {
  font-family: var(--title);
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  font-weight: 400;
  text-align: center;
  margin-bottom: 1.2rem;
}
.panel-note {
  font-family: var(--serif);
  font-size: 1.3rem;
  opacity: 0.85;
}
.panel-note a { text-decoration: underline; }

.btn-pill {
  display: inline-block;
  margin-top: 1.8rem;
  background: var(--leave);
  color: #000;
  border-radius: 14px;
  padding: 0.65em 1.5em;
  font-weight: 600;
  transform: rotate(-2deg);
  transition: opacity 0.2s;
}
@media (hover: hover) { .btn-pill:hover { opacity: 0.65; } }

/* Nav: every click wiggles all stickers together */
.hero.revealed .sticker-nav { opacity: 1; }
.hero.revealed .sticker-nav.wiggle {
  animation: nav-wiggle 0.65s ease-in-out both;
}
@keyframes nav-wiggle {
  0%, 100% { transform: translate(var(--x), var(--shift)) rotate(var(--tilt)); }
  20% { transform: translate(var(--x), var(--shift)) rotate(calc(var(--tilt) - 9deg)) scale(1.07); }
  45% { transform: translate(var(--x), var(--shift)) rotate(calc(var(--tilt) + 8deg)) scale(1.04); }
  70% { transform: translate(var(--x), var(--shift)) rotate(calc(var(--tilt) - 4deg)); }
  85% { transform: translate(var(--x), var(--shift)) rotate(calc(var(--tilt) + 2deg)); }
}
.sticker-nav img { transition: opacity 0.3s, filter 0.3s; }
.sticker-nav[aria-current] img { filter: drop-shadow(0 0 14px rgba(255, 253, 245, 0.4)); }

/* Tickets: one row per event, link list style */

.ticket-list {
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  max-width: 780px;
}
.ticket {
  display: grid;
  grid-template-columns: 76px 64px 1fr auto;
  grid-template-areas: "art date info cta";
  align-items: center;
  gap: 1.1rem;
  padding: 0.7rem 1rem 0.7rem 0.7rem;
  border-radius: 14px;
  background: var(--faded-black);
  border: 1px solid rgba(255, 253, 245, 0.08);
  transition: background 0.2s, transform 0.25s ease;
}
@media (hover: hover) { .ticket:hover { background: var(--espresso); transform: rotate(-0.6deg) scale(1.01); } }
.t-art { grid-area: art; }
.t-art img,
.t-art-blank {
  display: block;
  width: 76px;
  height: 76px;
  object-fit: cover;
  border-radius: 8px;
  background: #111 var(--star-tile) center / 38% no-repeat;
}
.t-art img.t-logo { object-fit: contain; padding: 18%; }
.t-date { grid-area: date; display: flex; flex-direction: column; text-transform: uppercase; line-height: 1.15; white-space: nowrap; }
.t-day { font-size: 0.8rem; opacity: 0.65; letter-spacing: 0.06em; }
.t-dm { font-size: 1.15rem; font-weight: 800; }
.t-info { grid-area: info; min-width: 0; }
.t-title { font-size: 1.05rem; font-weight: 600; line-height: 1.3; }
.t-venue { font-family: var(--serif); font-size: 1rem; opacity: 0.8; }
.t-provider { font-size: 0.8rem; opacity: 0.55; margin-top: 0.2rem; }
.t-cta {
  grid-area: cta;
  background: var(--leave);
  color: #000;
  border-radius: 12px;
  padding: 0.5em 1.1em;
  font-weight: 600;
  transform: rotate(-2deg);
  white-space: nowrap;
}

/* Streams */

.stream-player {
  max-width: 900px;
  aspect-ratio: 16 / 9;
  border-radius: 10px;
  overflow: hidden;
  background: #111;
}
.stream-player .yt-out { width: 100%; height: 100%; border-radius: 0; border: 0; padding: 0; cursor: pointer; }
.stream-player iframe { width: 100%; height: 100%; border: 0; display: block; }

.video-grid {
  max-width: 900px;
  margin-top: 1.4rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
  align-items: start;
}
.video-cell {
  border: 0;
  padding: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.video-grid .btn-pill { margin-top: 0.4rem; grid-column: 1 / -1; justify-self: center; }

.yt-thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: 8px;
  overflow: hidden;
  background: #111 center / cover no-repeat;
}
.yt-thumb::after {
  content: "▶";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 2rem;
  color: var(--white);
  background: rgba(0, 0, 0, 0.25);
  transition: background 0.2s;
}
@media (hover: hover) { .video-cell:hover .yt-thumb::after { background: rgba(0, 0, 0, 0.45); } }
.yt-title {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.88rem;
  opacity: 0.8;
  line-height: 1.35;
}

/* Music */

.release-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 1.2rem;
}
.release {
  cursor: pointer;
  border: 0;
  padding: 0;
  background: none;
  color: inherit;
  font-family: inherit;
  text-align: left;
  /* buttons centre their content vertically: start at the top so every cover
     in a row lines up */
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-self: start;
  min-width: 0;
}
.release img,
.merch img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 6px;
  transition: transform 0.25s ease;
}
@media (hover: hover) { .release:hover img, .merch:hover img { transform: scale(1.04) rotate(-1deg); } }
.r-title { margin-top: 0.55rem; font-size: 0.95rem; font-weight: 600; }
/* one line per artist credit, long collab lists end in "…" (full names show in
   the player and on hover), so every release takes the same height */
.r-artist,
.release .r-title {
  font-family: var(--serif);
  font-size: 0.95rem;
  opacity: 0.75;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.release .r-title { font-family: var(--sans); opacity: 1; }

/* Merch */

.merch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 1.4rem;
  max-width: 900px;
}
.merch { display: block; }
.merch-buy { display: inline-block; margin-top: 0.3rem; font-size: 0.88rem; color: var(--leave); font-weight: 600; white-space: nowrap; }

/* Release player modal */

#release-modal {
  margin: auto;
  border: 0;
  border-radius: 10px;
  background: var(--faded-black);
  color: var(--white);
  padding: 1rem;
  width: min(92vw, 480px);
}
#release-modal::backdrop { background: rgba(0, 0, 0, 0.8); }
.modal-title { font-weight: 600; margin: 0.1rem 2rem 0.8rem 0.2rem; }
.modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.7rem;
  background: none;
  border: 0;
  color: var(--white);
  font-size: 1.2rem;
  cursor: pointer;
  z-index: 1;
}
@media (hover: hover) { .modal-close:hover { opacity: 0.65; } }
#modal-player { width: 100%; height: min(66vh, 520px); border: 0; display: block; }
.btn-buy {
  display: block;
  text-align: center;
  background: var(--leave);
  color: #000;
  border-radius: 14px;
  padding: 0.7em 1.5em;
  margin-top: 0.9rem;
  transform: rotate(-1deg);
  font-weight: 600;
  transition: opacity 0.2s;
}
@media (hover: hover) { .btn-buy:hover { opacity: 0.65; } }

/* ↗ on everything that leaves the site */
.btn-pill::after,
.t-cta::after,
.btn-buy::after,
.merch-buy::after { content: " ↗"; font-weight: 400; }


/* Instagram, bottom right once the nav is in */

.socials {
  position: absolute;
  right: clamp(1.5rem, 4vw, 3.5rem);
  bottom: 1.8rem;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 1rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease 0.8s;
}
.hero.revealed .socials { opacity: 1; pointer-events: auto; }
.social svg { height: 26px; width: auto; display: block; transition: opacity 0.2s; }
.social:first-child svg { height: 22px; } /* SoundCloud mark is wide, keep it the same visual weight as Instagram */
@media (hover: hover) { .social:hover svg { opacity: 0.65; } }

/* panel titles stay for screen readers only */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- Click stickers ---------- */

.sticker-layer {
  position: absolute;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  overflow: hidden;
}

.sticker-layer img {
  position: absolute;
  --tilt: 0deg;
  transform: translate(-50%, -50%) rotate(var(--tilt));
  animation: slap-in 0.28s cubic-bezier(0.2, 1.3, 0.4, 1) both;
  filter: drop-shadow(0 0 0 rgba(0, 0, 0, 0));
}
.sticker-layer img.fade {
  animation: sticker-out 2s ease forwards;
}
@media (max-width: 720px) {
  .sticker-layer img.fade { animation-duration: 1s; }
}
@keyframes sticker-out {
  to { opacity: 0; }
}

@keyframes slap-in {
  0% {
    opacity: 1;
    transform: translate(-50%, -50%) rotate(calc(var(--tilt) - 12deg)) scale(1.45);
    filter: drop-shadow(0 30px 30px rgba(0, 0, 0, 0.5));
  }
  100% {
    opacity: 1;
    transform: translate(-50%, -50%) rotate(var(--tilt)) scale(1);
    filter: drop-shadow(0 0 0 rgba(0, 0, 0, 0));
  }
}

/* ---------- Motion ---------- */

@media (prefers-reduced-motion: reduce) {
  .sticker { animation: none; }
  .sticker-layer img { animation: none; }
  .hero.revealed .sticker-nav.wiggle,
  .balloon-wiggle.wobble { animation: none; }
  .balloon, .panel, .panel.active { transition-duration: 0.01s; transition-delay: 0s; }
}

/* ---------- Mobile ---------- */

@media (max-width: 720px) {
  /* logos: no tagline, OG Records centred and only after GO to site */
  .logo-ftn { display: none; }
  .hero-logos { justify-content: center; top: 2.2rem; }
  .logo-og { opacity: 0; transition: opacity 0.6s ease 0.3s; }
  .logo-og img { height: 26px; }
  .hero.revealed .logo-og { opacity: 1; }
  /* balloon: layout is fixed in its post-reveal state (nav space reserved, stage
     padded under the logo). Before reveal the video is only transformed, scaled
     up 1.27x and shifted to the viewport centre (--pre-shift set by star.js), so
     the reveal is one GPU transform transition, no layout jumps */
  .star-stage { padding: 5.8rem 0 0.5rem; }
  .balloon { top: 5.8rem; bottom: 0.5rem; }
  .panels { --panel-top: 4.4rem; }
  /* SoundCloud top left, Instagram top right, logo centred between */
  .panel {
    --fade: linear-gradient(to bottom, transparent 0, #000 1.6rem, #000 calc(100% - var(--nav-h, 150px) - 3rem), transparent calc(100% - var(--nav-h, 150px) + 0.5rem));
  }
  /* same top and height as the OG Records logo, so all three share one centre line */
  .socials { top: 2.2rem; height: 26px; bottom: auto; left: 1.4rem; right: 1.4rem; justify-content: space-between; align-items: center; }
  .social { display: block; }
  .hero.revealed .socials { pointer-events: none; }
  .hero.revealed .social { pointer-events: auto; }
  .social svg { height: 20px; }
  .social:first-child svg { height: 17px; }
  /* phone: flyer and text side by side, full-width button underneath */
  .ticket {
    grid-template-columns: 72px 1fr;
    grid-template-areas: "art date" "art info" "cta cta";
    align-items: start;
    gap: 0.25rem 0.9rem;
    padding: 0.75rem;
  }
  .t-art img, .t-art-blank { width: 72px; height: 72px; }
  .t-info { overflow-wrap: anywhere; }
  .t-cta { margin-top: 0.6rem; text-align: center; transform: none; padding: 0.65em 1em; }
  .t-date { flex-direction: row; gap: 0.4rem; align-items: baseline; }
  .t-dm { font-size: 0.95rem; }
  .t-title { font-size: 0.95rem; }
  .release-grid { grid-template-columns: repeat(2, 1fr); gap: 1rem; }
  .merch-grid { grid-template-columns: repeat(2, 1fr); gap: 1rem; }
  #star-canvas,
  #star-video,
  .balloon-grain {
    /* square, as big as fits: 118% of the screen width, or the stage height if
       that is less. Set by height so balloon and grain layer match exactly */
    width: auto;
    height: min(118vw, 100%);
    max-height: none;
    aspect-ratio: 1;
    object-fit: contain;
    transform: translateY(var(--pre-shift, 0px)) scale(1.27);
    transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
  }
  .hero.revealed #star-canvas,
  .hero.revealed #star-video,
  .hero.revealed .balloon-grain { transform: none; }
  /* stacked: bandcamp over the top tip, GO to site over the bottom tip */
  .sticker-hero { left: 50%; right: auto; --x: -50%; }
  /* placed against the viewport, not the stage, since the stage is padded for the logo */
  .sticker-left { top: calc(var(--app-h, 100svh) * 0.44); --tilt: -4deg; }
  .sticker-right { top: calc(var(--app-h, 100svh) * 0.63); --tilt: 3deg; }
  .sticker-left { --w: min(210px, 60vw); }
  .sticker-right { --w: min(195px, 56vw); }

  .main-nav {
    flex-wrap: wrap;
    justify-content: center;
    gap: 2vw 3vw;
    /* a little air above the browser bar / home indicator */
    padding: 2vw 5vw max(6vw, calc(env(safe-area-inset-bottom) + 2vw));
  }
  /* two rows like the mockup: bandcamp + tickets, then streams, music, merch */
  .nav-bandcamp { --w: 37vw; }
  .nav-tickets  { --w: 29vw; }
  .nav-streams  { --w: 26vw; }
  .nav-music    { --w: 26vw; }
  .nav-merch    { --w: 23vw; }
}

/* centred column under the centred panel titles */
.stream-player,
.video-grid,
.merch-grid { margin-left: auto; margin-right: auto; }
.panel-inner > .btn-pill { display: block; width: fit-content; margin-left: auto; margin-right: auto; }

/* ---------- Phones on their side and other short screens ---------- */

@media (max-height: 500px) and (min-width: 721px) {
  .logo-og img { height: 22px; }
  .logo-ftn { height: 26px; }
  .hero-logos { top: 0.9rem; }
  .panels { --panel-top: 3rem; }
  .sticker-left  { --w: 36vh; }
  .sticker-right { --w: 33vh; }
  .main-nav { padding: 0.4rem 1.5rem 0.7rem; gap: 1.2rem; }
  .nav-bandcamp { --w: 25vh; }
  .nav-tickets  { --w: 20vh; }
  .nav-streams  { --w: 18vh; }
  .nav-music    { --w: 18vh; }
  .nav-merch    { --w: 16vh; }
  .socials { bottom: 0.9rem; }
  .social svg { height: 20px; }
  .social:first-child svg { height: 17px; }
  .release-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  .merch-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); max-width: 640px; }
  .stream-player { max-width: 60vh; max-width: 105vh; }
}

/* small phones (iPhone SE and similar): keep the two hero stickers apart */
@media (max-width: 720px) and (max-height: 620px) {
  .sticker-left { top: calc(var(--app-h, 100svh) * 0.42); }
  .sticker-right { top: calc(var(--app-h, 100svh) * 0.65); }
}

/* narrow phones (iPhone SE, small Androids): a little more room around the logo */
@media (max-width: 360px) {
  .logo-og img { height: 23px; }
  .socials { height: 23px; }
  .social:first-child svg { height: 14px; }
  .social svg { height: 18px; }
}

/* ---------- Buttons never wrap ----------
   Every button keeps its label on one line. When the screen is too narrow,
   js/site.js (fitButtons) shrinks the font just enough to fit, down to 70%.
   CSS keeps them inside the screen in the meantime. */
.btn-pill,
.btn-buy,
.t-cta,
.merch-buy {
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: clip;
}

/* the stream player never grows taller than the room above the nav, so the
   YouTube button stays in view on laptops */
.stream-player { max-width: min(900px, max(280px, calc((var(--app-h, 100svh) - var(--nav-h, 150px) - 11rem) * 16 / 9))); }

/* very narrow screens: merch in one column so its buttons keep full size */
@media (max-width: 300px) {
  .merch-grid { grid-template-columns: 1fr; }
}

/* page restored (reload or reopened tab): no opening animations, everything
   lands in its final place at once (js/site.js settleInstantly) */
html.instant *,
html.instant *::before,
html.instant *::after {
  transition: none !important;
  animation-duration: 0s !important;
  animation-delay: 0s !important;
  animation-play-state: running !important;
}
/* after a restore the intro animations stay off (they would otherwise start
   over once html.instant is removed); GO to site switches them back on */
html.settled .sticker-hero,
html.settled .hero.revealed .sticker-nav:not(.wiggle) { animation: none; }
html.settled .hero.revealed .sticker-hero { opacity: 0; pointer-events: none; }

/* SoundCloud full sets, under the YouTube videos: square artwork tiles in the
   same rounded, image-first style as the video thumbnail */
.sets { max-width: 900px; margin: 2.4rem auto 0; }
.sets-grid { justify-content: center; }
.sets-label {
  text-align: center;
  font-family: var(--serif);
  font-size: 1.05rem;
  opacity: 0.7;
  margin-bottom: 0.8rem;
}
.sets-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 1rem;
}
.set-cell {
  border: 0; padding: 0; background: none; color: inherit; font: inherit;
  text-align: left; cursor: pointer;
  display: flex; flex-direction: column; align-self: start; min-width: 0;
}
.set-art {
  position: relative;
  display: block;
  aspect-ratio: 1;
  border-radius: 8px;
  overflow: hidden;
  background: #111;
}
.set-art img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.25s ease; }
.set-art::after {
  content: "▶";
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 1.8rem; color: var(--white);
  background: rgba(0, 0, 0, 0.2);
  transition: background 0.2s;
}
.set-time {
  position: absolute; right: 0.45rem; bottom: 0.45rem; z-index: 1;
  font-size: 0.75rem; font-weight: 600;
  padding: 0.15em 0.5em; border-radius: 6px;
  background: rgba(0, 0, 0, 0.7); color: var(--white);
}
.set-title {
  margin-top: 0.5rem;
  font-size: 0.88rem; line-height: 1.35; opacity: 0.85;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
@media (hover: hover) {
  .set-cell:hover .set-art img { transform: scale(1.04); }
  .set-cell:hover .set-art::after { background: rgba(0, 0, 0, 0.4); }
}
.sets > .btn-pill { display: block; width: fit-content; margin: 1.6rem auto 0; }
@media (max-width: 720px) {
  .sets-grid { grid-template-columns: repeat(2, 1fr); }
}
