/* ============================================================
   NEVER SAY DIE — Website Stylesheet
   Design: gig-poster identity — full-bleed sections, oversized
   Oswald type, a paper-toned ticker stripe, grain texture, and a
   few tactile touches (tilting member cards, ticket-stub shows,
   scroll reveals). Three tones only: ink / paper / accent-red.

   Structure: css tokens → base → chrome (nav/marquee/grain) → hero
   → shared section/disclosure/button components → each section →
   responsive. The multitrack player keeps its original class names
   throughout (.player__panel, .player__control, .player__track,
   .player__caption, .player__volume…) — js/player.js is unchanged.
   ============================================================ */

:root{
  --ink:      #08080a;   /* page ground               */
  --ink-2:    #131316;   /* raised panels on ink       */
  --ink-3:    #1c1c20;   /* borders / hairlines on ink */
  --paper:    #f2ece0;   /* the one light surface      */
  --paper-2:  #e7ddc9;   /* borders/shade on paper     */
  --text:     #e9e4da;   /* body copy on ink           */
  --muted:    #948b7e;   /* secondary text on ink      */
  --accent:   #e31c2e;   /* blood red                  */
  --accent-2: #9c0f1c;   /* darker red, for gradients  */
  --line:     rgba(255,255,255,.12);
  --display:  'Oswald', 'Haettenschweiler', 'Franklin Gothic Heavy', Impact, sans-serif;
  --body:     'Inter', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --edge:     clamp(20px, 5vw, 64px);
  --radius:   2px;
}

*{ box-sizing:border-box; margin:0; padding:0; }

html{ background:var(--ink); scroll-behavior:smooth; }
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
}

body{
  font-family:var(--body);
  background:var(--ink);
  color:var(--text);
  overflow-x:hidden;
  /* overflow-x:hidden stops scrolling to reveal actual off-screen
     content, but not a touch browser's own rubber-band/bounce drag past
     the page edge — these two are what actually suppress that, and
     unlike overflow-x on <html>, neither of them can cause the
     double-scrollbar bug (they don't turn body into a scroll container) */
  overscroll-behavior-x:none;
  /* pan-y (not "pan-x pan-y" or the auto default) is what actually
     suppresses the horizontal rubber-band above — but touch-action's
     allowed-gesture list is exhaustive, not additive, so pan-y alone
     silently disabled pinch-to-zoom site-wide too. pinch-zoom has to be
     listed explicitly to get it back. Needed on this site specifically
     because the multitrack player's small per-member tap targets are
     hard to hit precisely on a phone without being able to zoom in. */
  touch-action:pan-y pinch-zoom;
}

a{ color:inherit; text-decoration:none; }
img{ max-width:100%; display:block; }

.wrap{
  max-width:1200px;
  margin:0 auto;
  padding-left:var(--edge);
  padding-right:var(--edge);
}

/* keeps the sticky nav from covering a section's heading when a nav
   link scrolls to it */
#ueber-uns, #hoeren, #band, #shows, #kontakt{ scroll-margin-top:4.6rem; }

.eyebrow{
  font-family:var(--display);
  font-weight:500;
  font-size:.78rem;
  letter-spacing:.24em;
  text-transform:uppercase;
  color:var(--accent);
  display:flex;
  align-items:center;
  gap:.7rem;
}
.eyebrow::after{
  content:"";
  flex:1;
  height:1px;
  background:var(--line);
}

.section{ padding:5rem 0; }
.section__head{ margin-bottom:2.2rem; }
.section__subhead{
  font-family:var(--display);
  font-weight:500;
  font-size:.75rem;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--muted);
  margin:0 0 1rem;
}

/* ---- grain texture (whole page, decorative, non-interactive) --- */

.grain{
  position:fixed;
  inset:0;
  z-index:80;
  pointer-events:none;
  opacity:.05;
  mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- reveal-on-scroll (progressive enhancement, see js/site.js) --- */

.reveal.pre-reveal{
  opacity:0;
  transform:translateY(28px);
}
@media (prefers-reduced-motion:no-preference){
  .reveal{
    transition:opacity .7s ease, transform .7s ease;
  }
}

/* ---- cta cards (shared) ------------------------------------------ */
/* the streaming link, styled as a "primary" card — Icon badge + title/
   subtitle + a trailing arrow that slides right on hover. .cta-card is
   the shared base; .cta-row is unused now that Instagram/Facebook have
   their own cards removed (still in the footer icon row) but stays
   since other cta-card consumers may want it later. */

.cta-card{
  position:relative;
  display:flex;
  align-items:center;
  gap:1.1rem;
  padding:1.2rem 1.4rem;
  background:var(--ink-2);
  border:1px solid var(--ink-3);
  overflow:hidden;
  transition:border-color .2s ease, transform .2s ease, background-color .2s ease;
}
.cta-card:hover{
  border-color:var(--accent);
  background:#181819;
  transform:translateY(-2px);
}

.cta-card__icon{
  flex:none;
  width:2.9rem;
  height:2.9rem;
  border-radius:50%;
  display:flex;
  align-items:center;
  justify-content:center;
  background:var(--ink-3);
  color:var(--accent);
  transition:background-color .2s ease, color .2s ease;
}
.cta-card__icon svg{ width:1.35rem; height:1.35rem; }
.cta-card:hover .cta-card__icon{ background:var(--accent); color:var(--ink); }

.cta-card__text{ min-width:0; flex:1; }
.cta-card__title{
  font-family:var(--display);
  font-weight:600;
  font-size:1.05rem;
  letter-spacing:.02em;
  color:var(--paper);
}
.cta-card__sub{
  font-size:.82rem;
  color:var(--muted);
  margin-top:.15rem;
}

.cta-card__arrow{
  flex:none;
  width:1.3rem;
  height:1.3rem;
  color:var(--muted);
  transition:transform .2s ease, color .2s ease;
}
.cta-card:hover .cta-card__arrow{ transform:translateX(4px); color:var(--accent); }

/* the streaming link gets top billing: full-bleed red gradient, its own
   larger type scale, and a paper-colored icon badge so it reads against
   the red instead of blending into it. Sized a touch smaller than the
   original — it's the only card in .listen-cta now, not the biggest of
   a set, so it no longer needs to carry that much visual weight. */
.cta-card--primary{
  background:linear-gradient(120deg, var(--accent) 0%, var(--accent-2) 100%);
  border-color:transparent;
  padding:1.15rem 1.4rem;
  box-shadow:0 10px 30px -10px rgba(227,28,46,.55);
}
.cta-card--primary:hover{
  border-color:transparent;
  background:linear-gradient(120deg, var(--accent) 0%, var(--accent-2) 100%);
  box-shadow:0 14px 34px -8px rgba(227,28,46,.7);
}
.cta-card--primary .cta-card__icon{ width:2.4rem; height:2.4rem; background:var(--paper); color:var(--accent); }
.cta-card--primary .cta-card__icon svg{ width:1.15rem; height:1.15rem; }
.cta-card:hover.cta-card--primary .cta-card__icon{ background:var(--paper); color:var(--accent); }
.cta-card--primary .cta-card__title{ font-size:1.1rem; color:var(--paper); }
.cta-card--primary .cta-card__sub{ font-size:.78rem; color:rgba(242,236,224,.85); }
.cta-card--primary .cta-card__arrow{ color:var(--paper); }
.cta-card:hover.cta-card--primary .cta-card__arrow{ color:var(--paper); }

.cta-row{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(13rem, 1fr));
  gap:.9rem;
}

/* ---- disclosure (shared collapsed-by-default panel) -------------- */

.disclosure{
  background:var(--ink-2);
  border:1px solid var(--ink-3);
  border-left:3px solid var(--accent);
}
.disclosure__summary{
  list-style:none;
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:1rem;
  padding:1.1rem 1.5rem;
  font-family:var(--display);
  font-weight:500;
  font-size:.88rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--paper);
}
.disclosure__summary::-webkit-details-marker{ display:none; }
.disclosure__summary:hover{ color:var(--accent); }
.disclosure__chev{
  width:1.1rem; height:1.1rem;
  color:var(--accent);
  flex:none;
  transition:transform .2s ease;
}
.disclosure[open] .disclosure__chev{ transform:rotate(180deg); }
.disclosure__content{
  padding:0 1.5rem 1.8rem;
  display:flex;
  flex-direction:column;
  gap:1.8rem;
}

/* ================================================================
   NAV
   ================================================================ */

.nav{
  position:sticky;
  top:0;
  z-index:90;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:1rem;
  padding:1.1rem var(--edge);
  background:transparent;
  border-bottom:1px solid transparent;
  transition:background-color .25s ease, border-color .25s ease;
}
/* .nav:has(...) is a pure-CSS backstop for the same "solid while the
   mobile menu is open" state js/site.js also sets via .nav--solid —
   so the bar can't be left see-through behind its own opaque drawer
   even if the JS toggle doesn't fire for some reason.
   No backdrop-filter here (deliberately) — background is fully opaque
   now so blur has nothing to do visually, and backdrop-filter has a
   real side effect: it makes .nav a containing block for its own
   position:fixed descendants (the mobile drawer, #navLinks), which
   broke the drawer's top/bottom inset sizing down to ~64px tall
   instead of the full viewport height the moment this class landed. */
.nav--solid,
.nav:has(.nav__links.is-open){
  background:var(--ink);
  border-bottom-color:var(--ink-3);
}
.nav__brand{
  font-family:var(--display);
  font-weight:700;
  font-size:1rem;
  letter-spacing:.08em;
  color:var(--paper);
}
.nav__links{
  display:flex;
  gap:1.8rem;
  font-family:var(--display);
  font-weight:500;
  font-size:.8rem;
  letter-spacing:.08em;
  text-transform:uppercase;
}
/* plain white/paper by default — was --muted (a warm gray), which
   didn't have enough contrast against the hero photo while the nav
   still sits transparent over it, before scrolling triggers .nav--solid */
.nav__links a{ color:var(--paper); transition:color .15s ease; padding:.3rem 0; }
.nav__links a:hover{ color:var(--accent); }
.nav__links a.is-active{ color:var(--accent); }

.nav__toggle{
  display:none;
  flex-direction:column;
  justify-content:center;
  gap:5px;
  width:2.2rem;
  height:2.2rem;
  background:none;
  border:none;
  cursor:pointer;
}
.nav__toggle span{
  display:block;
  height:2px;
  background:var(--paper);
  transition:transform .2s ease, opacity .2s ease;
}
.nav__toggle[aria-expanded="true"] span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2){ opacity:0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }

/* ================================================================
   HERO
   ================================================================ */

.hero{
  position:relative;
  aspect-ratio:2660 / 1300;
  overflow:hidden;
  /* sit the sticky nav on top of the photo. A % margin is computed from
     the hero's own width — and since its height is itself a fixed ratio
     of that width (aspect-ratio above), this stays a constant fraction
     of the hero's height at every viewport size. A fixed rem value here
     would instead eat a growing share of the image as the hero (and its
     aspect-ratio-locked height) shrinks on narrow screens — up to ~40%
     of it on a phone — which is what was cropping the heads out. */
  margin-top:-3%;
}
.hero__img{
  position:absolute; inset:0;
  background-image:url('../material/Bandfoto_header.jpg');
  background-size:cover;
  background-position:center top;
  filter:grayscale(1) contrast(1.12) brightness(.85);
}
.hero__veil{
  position:absolute; inset:0;
  background:
    linear-gradient(to bottom,
      rgba(8,8,10,.55) 0%,
      rgba(8,8,10,.08) 22%,
      rgba(8,8,10,.4) 58%,
      rgba(8,8,10,.95) 88%,
      var(--ink) 100%),
    linear-gradient(to right, var(--ink) 0%, rgba(8,8,10,0) 16%),
    linear-gradient(to left,  var(--ink) 0%, rgba(8,8,10,0) 16%);
    /* was: , linear-gradient(100deg, rgba(227,28,46,.22), transparent 55%);
       — a diagonal red wash across the photo. Testing pure grayscale/black
       here instead; bring it back by re-adding that layer if red wins. */
}

.hero__stage{
  position:absolute;
  inset:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:1.4rem;
  padding:3% var(--edge) 0; /* matches .hero's margin-top exactly, so the logo is centered within the part of the photo actually visible below the nav, at every width */
  text-align:center;
}
.hero__logo{
  /* pure vw scaling so it keeps growing in step with the image itself at
     every desktop width — the rem side is only a sanity ceiling for
     ultra-wide monitors, not a cap that kicks in at normal sizes */
  width:min(55rem, 38vw);
  margin-top:2rem;
  filter:drop-shadow(0 12px 40px rgba(0,0,0,.65));
}

.hero__scroll{
  position:absolute;
  left:50%;
  bottom:1.6rem;
  transform:translateX(-50%);
  color:var(--accent);
  opacity:.9;
}
.hero__scroll svg{ width:1.8rem; height:1.8rem; display:block; }
@media (prefers-reduced-motion:no-preference){
  .hero__scroll{ animation:scrollcue 1.6s ease infinite; }
}
@keyframes scrollcue{
  0%{ transform:translate(-50%, 0); opacity:.5; }
  50%{ transform:translate(-50%, .5rem); opacity:1; }
  100%{ transform:translate(-50%, 0); opacity:.5; }
}

/* ================================================================
   MARQUEE
   ================================================================ */

.marquee{
  position:relative;
  background:var(--paper);
     color:var(--ink);
  overflow:hidden;
  white-space:nowrap;
  border-bottom:1px solid var(--paper-2);
  /* pull the strip up over the bottom of the hero photo, which the
     .hero__veil gradient has already darkened almost to --ink by that
     point — same %-of-width trick as .hero's own margin-top so the
     overlap stays a constant fraction of the (aspect-ratio-locked)
     hero height at every viewport width, instead of eating a growing
     share of a short mobile hero. */
  margin-top:-7%;
}
.marquee__track{
  display:inline-flex;
  align-items:center;
  padding:.7rem 0;
}
@media (prefers-reduced-motion:no-preference){
  .marquee__track{ animation:marquee 26s linear infinite; }
}
@keyframes marquee{
  from{ transform:translateX(0); }
  to{ transform:translateX(-50%); }
}
.marquee__item{
  font-family:var(--display);
  font-weight:600;
  font-size:1rem;
  letter-spacing:.1em;
  text-transform:uppercase;
  padding:0 1.4rem;
}
.marquee__sep{ color:var(--accent); }

/* ================================================================
   BIO
   ================================================================ */

/* flex, not grid: a grid row's height is shared by every column in that
   row, so a photo placed via grid-template-areas under .bio-grid__head
   still gets pushed down by however tall .bio-grid__body's row turns
   out to be. Flex items size independently — .bio-grid__left (head +
   photo, stacked) and .bio-grid__body just sit side by side, each as
   tall as its own content, so the photo stays snug under the heading
   regardless of how long the bio text runs. */
.bio-grid{
  display:flex;
  gap:3rem;
  /* stretch, not flex-start: lets .bio-grid__left grow to match
     .bio-grid__body's height (the taller column, given how much bio
     text there is), so the flex:1 photo below has real extra space to
     grow into and its bottom edge lands level with the text's. */
  align-items:stretch;
}
.bio-grid__left{
  display:flex;
  flex-direction:column;
  gap:2.2rem;
  flex:1.1;
  min-width:0;
}
.bio-grid__body{ flex:1; min-width:0; }
.bio-grid__quote{
  font-family:var(--display);
  font-weight:600;
  font-size:clamp(2.1rem, 5vw, 3.4rem);
  line-height:1.05;
  letter-spacing:.01em;
  text-transform:uppercase;
  color:var(--paper);
  text-wrap:balance;
  margin-top:1rem;
}
.bio-grid__quote em{
  font-style:normal;
  color:var(--accent);
}
.bio-grid__body p{
  font-size:1.05rem;
  line-height:1.7;
  color:var(--text);
  margin-bottom:1.1rem;
  max-width:56ch;
  text-align:justify;
  hyphens:auto;
}
.bio-grid__body p:last-child{ margin-bottom:0; }
.bio-grid__body strong{ color:var(--paper); font-weight:600; }

/* fills the empty space left under the heading once the bio text runs
   longer than it — see the .bio-grid comment above for why this is
   flex, not grid. Mobile reordering (below the bio text there, instead
   of under the heading) is handled in the responsive section. */
.bio-grid__photo{
  flex:1;
  min-height:0;
  overflow:hidden;
}
.bio-grid__photo img{
  display:block;
  width:100%;
  /* height:100% of the flex-grown box, cropped to fit via object-fit —
     on mobile .bio-grid__photo's height is auto (content-sized, no
     free space for flex:1 to claim), so this percentage resolves back
     to auto there and the image just falls back to its natural ratio. */
  height:100%;
  object-fit:cover;
  border:1px solid var(--ink-3);
}

/* ================================================================
   LISTEN — multitrack mixer + streaming CTA
   (player__* classes are consumed directly by js/player.js — keep
   their names stable even while restyling)
   ================================================================ */

/* the marquee ticker right above already carries its own vertical
   padding, so this section (now the first one after it) needs a touch
   less top padding than the .section default to avoid a too-large gap */
.listen-section{ padding-top:4.6rem; }

.mixer{
  background:linear-gradient(155deg, var(--ink-2) 0%, #17070a 130%);
  border:1px solid var(--ink-3);
  border-left:3px solid var(--accent);
  padding:1.6rem clamp(1.4rem, 3vw, 2.6rem) 1.8rem;
  margin-bottom:1.6rem;
}

.player__status{
  font-size:.85rem;
  color:var(--muted);
  margin-bottom:1.1rem;
}
.player__status b{ color:var(--paper); font-weight:600; }

.player__row{
  display:flex;
  flex-wrap:wrap;
  align-items:flex-start;
  gap:1.8rem;
}

.player__control{
  flex:none;
  width:5rem;
  height:5rem;
  border:2px solid var(--accent);
  border-radius:50%;
  color:var(--accent);
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  transition:color .2s ease, border-color .2s ease, transform .15s ease, background-color .2s ease;
  background:none;
}
.player__control svg{ width:1.7rem; height:1.7rem; }
.player__control:hover,
.player__control.is-active{
  color:var(--ink);
  background:var(--accent);
  border-color:var(--accent);
}
.player__control.is-loading{ animation:player-pulse 1.1s ease infinite; }
@keyframes player-pulse{
  0%,100%{ transform:scale(1); }
  50%{ transform:scale(1.08); }
}

.player__tracks{
  flex:1 1 auto;
  display:flex;
  flex-wrap:wrap;
  align-items:flex-start;
  gap:1.5rem;
}

.player__track{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:space-between;
  gap:.35rem;
  height:6.2rem;
  width:4.8rem;
  cursor:pointer;
  background:none;
  border:none;
  color:var(--muted);
  font-family:var(--body);
}
.player__track img{
  width:4.8rem;
  height:4.8rem;
  border-radius:50%;
  object-fit:cover;
  filter:grayscale(1);
  border:2px solid transparent;
  transition:filter .2s ease, border-color .2s ease, transform .15s ease;
}
.player__caption{
  font-family:var(--display);
  font-weight:500;
  font-size:.72rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  transition:color .2s ease;
}
.player__track:hover img{ transform:translateY(-2px); }
.player__track.is-active img{
  filter:grayscale(0);
  border-color:var(--accent);
}
.player__track.is-active .player__caption{ color:var(--paper); }

.player__volume{
  flex:none;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  justify-content:space-between;
  gap:.35rem;
  height:6.2rem;
  min-width:9rem;
}
.player__volume-row{
  display:flex;
  align-items:center;
  gap:.6rem;
  height:4.8rem;
  width:100%;
}
.player__volume svg{ width:1.1rem; height:1.1rem; color:var(--muted); flex:none; }
.player__volume input[type="range"]{
  flex:1;
  /* flex items default to min-width:auto, and a range input's own
     intrinsic min-width (its native browser-drawn track/thumb) is wider
     than that on narrow phones — without this it refuses to shrink and
     spills out past .player__volume-row's edge instead of scaling down */
  min-width:0;
  -webkit-appearance:none;
  appearance:none;
  height:2px;
  /* was --ink-3 — nearly invisible against the mixer's own dark
     background, leaving the slider's travel range unclear */
  background:var(--muted);
  outline:none;
}
.player__volume input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance:none;
  width:.85rem; height:.85rem;
  border-radius:50%;
  background:var(--accent);
  cursor:pointer;
}
.player__volume input[type="range"]::-moz-range-thumb{
  width:.85rem; height:.85rem;
  border:none;
  border-radius:50%;
  background:var(--accent);
  cursor:pointer;
}

/* just the one streaming-link card now (Instagram/Facebook cards were
   removed — those platforms still have icons in the footer) — spans
   the same width as .mixer above it, since both sit in the same .wrap */
.listen-cta{
  display:flex;
  flex-direction:column;
  gap:.9rem;
}

/* the player stays comfortable down to ~480px, but the default wrap
   layout only has room above ~860px — force the compact single-row
   layout across that whole gap, same fix as before, ported to the
   new sizes */
@media (max-width:860px){
  .mixer{ padding:1.3rem 1.2rem 1.5rem; }
  .player__row{ flex-wrap:nowrap; align-items:center; gap:.5rem; }
  .player__control{ width:2.4rem; height:2.4rem; }
  .player__control svg{ width:.95rem; height:.95rem; }
  /* 5 tracks now instead of 4 — a bit tighter than before to keep them
     (plus the volume slider) fitting a single row on narrow phones */
  .player__tracks{ flex-wrap:nowrap; gap:.32rem; }
  .player__track{ width:2.05rem; height:2.9rem; gap:.12rem; }
  .player__track img{ width:2.05rem; height:2.05rem; }
  .player__caption{ font-size:.44rem; letter-spacing:0; }
  .player__volume{ height:2.9rem; min-width:0; flex:1 1 auto; gap:.15rem; }
  .player__volume-row{ height:2.4rem; }
  .player__volume svg{ display:none; }
}

/* ================================================================
   BAND
   ================================================================ */


.members__grid{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(8.5rem, 1fr));
  gap:1.6rem;
  margin-bottom:1.6rem;
}
.member{
  /* it's a <button> now (was a <div>) so it's clickable/keyboard-focusable
     for the steckbrief modal — reset the UA button chrome back to plain */
  display:block;
  width:100%;
  background:none;
  border:none;
  font:inherit;
  color:inherit;
  cursor:pointer;
  text-align:center;
  perspective:900px; /* must sit on .member__photo's direct parent for the tilt effect in js/site.js to render with real depth */
}
.member__photo{
  display:block;
  width:100%;
  aspect-ratio:1;
  object-fit:cover;
  border-radius:50%;
  filter:grayscale(1) contrast(1.08);
  border:2px solid transparent;
  transition:filter .25s ease, border-color .25s ease, transform .18s ease;
  will-change:transform;
}
.member:hover .member__photo{
  filter:grayscale(0);
  border-color:var(--accent);
}
/* TEMPORARY: applied by js/members.js while the steckbrief modal is
   disabled — cards keep their colorful hover (it's a nice effect on its
   own), they just stop looking clickable since there's nothing to open.
   Remove once MEMBER_MODAL_ENABLED goes back to true. */
.members__grid--static .member{ cursor:default; }
.member__name{
  font-family:var(--display);
  font-weight:600;
  font-size:1.05rem;
  letter-spacing:.03em;
  color:var(--paper);
  margin-top:.9rem;
}
.member__role{
  font-size:.8rem;
  color:var(--muted);
  margin-top:.2rem;
}
.member__since{
  display:inline-block;
  font-family:var(--display);
  font-weight:500;
  font-size:.62rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--accent);
  margin-top:.4rem;
}

.members__former ul{ list-style:none; }
.members__former li{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:1rem;
  font-size:.88rem;
  color:var(--muted);
  padding:.5rem 0;
  border-top:1px solid var(--ink-3);
}
.members__former li:first-child{ border-top:none; }
.members__former b{ color:var(--text); font-weight:500; }
.members__former .years{
  flex:none;
  font-variant-numeric:tabular-nums;
  font-size:.8rem;
}

/* ---- member steckbrief modal --------------------------------------- */

.member-modal{
  position:fixed;
  inset:0;
  z-index:95;
  display:none;
  align-items:center;
  justify-content:center;
  padding:1.5rem;
}
.member-modal.is-open{ display:flex; }
.member-modal__backdrop{
  position:absolute;
  inset:0;
  background:rgba(8,8,10,.82);
}
.member-modal__card{
  position:relative;
  z-index:1;
  width:100%;
  max-width:26rem;
  max-height:88vh;
  overflow-y:auto;
  background:var(--ink-2);
  border:1px solid var(--ink-3);
  border-top:3px solid var(--accent);
}
.member-modal__close{
  position:absolute;
  top:.7rem;
  right:.7rem;
  z-index:2;
  width:2.2rem;
  height:2.2rem;
  border-radius:50%;
  display:flex;
  align-items:center;
  justify-content:center;
  background:var(--ink-3);
  color:var(--paper);
  border:none;
  cursor:pointer;
  transition:background-color .15s ease, color .15s ease;
}
.member-modal__close svg{ width:1.1rem; height:1.1rem; }
.member-modal__close:hover{ background:var(--accent); color:var(--ink); }
.member-modal__photo{
  display:block;
  width:100%;
  aspect-ratio:4/3;
  object-fit:cover;
  filter:grayscale(1) contrast(1.08);
}
.member-modal__body{ padding:1.6rem 1.8rem 1.8rem; }
.member-modal__name{
  font-family:var(--display);
  font-weight:700;
  font-size:1.6rem;
  color:var(--paper);
}
.member-modal__role{
  font-family:var(--display);
  font-weight:500;
  font-size:.8rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--accent);
  margin-top:.35rem;
}
.member-modal__facts{
  margin-top:1.5rem;
  display:flex;
  flex-direction:column;
  gap:1rem;
}
.member-modal__fact dt{
  font-family:var(--display);
  font-weight:500;
  font-size:.66rem;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--muted);
}
.member-modal__fact dd{
  font-size:.95rem;
  line-height:1.4;
  color:var(--text);
  margin-top:.2rem;
}
.member-modal__fact dd a{
  color:var(--accent);
  text-decoration:underline;
  text-decoration-color:currentColor;
  text-underline-offset:.15em;
}
.member-modal__fact dd a:hover{ color:var(--paper); }

/* ================================================================
   SHOWS
   ================================================================ */


.tickets{
  display:flex;
  flex-direction:column;
  gap:.9rem;
  margin-bottom:1.6rem;
}
.ticket{
  position:relative;
  display:flex;
  align-items:center;
  gap:1.4rem;
  background:var(--ink-2);
  border:1px solid var(--ink-3);
  padding:1.2rem 1.5rem;
  overflow:hidden;
}
.ticket__date{
  flex:none;
  display:flex;
  flex-direction:column;
  align-items:center;
  line-height:1;
  width:4.2rem;
}
.ticket__day{
  font-family:var(--display);
  font-weight:700;
  font-size:2.1rem;
  color:var(--paper);
}
.ticket__month{
  font-family:var(--display);
  font-weight:500;
  font-size:.75rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--accent);
  margin-top:.3rem;
}
.ticket__stub{
  flex:none;
  align-self:stretch;
  width:0;
  border-left:2px dashed var(--ink-3);
}
.ticket__info{ flex:1; min-width:0; position:relative; }
.ticket__info:has(.ticket__venue a){ cursor:pointer; }
.ticket__lineup{
  font-size:1rem;
  color:var(--text);
  line-height:1.4;
}
.ticket__lineup a{
  position:relative;
  z-index:1;
  color:var(--paper);
  text-decoration:underline;
  text-decoration-color:var(--line);
  text-underline-offset:.15em;
}
.ticket__lineup a:hover{ color:var(--accent); text-decoration-color:var(--accent); }
.ticket__lineup b{ color:var(--paper); font-weight:600; }
.ticket__venue{
  font-size:.82rem;
  color:var(--muted);
  margin-top:.2rem;
}
.ticket__venue a{
  color:var(--muted);
  text-decoration:underline;
  text-decoration-color:var(--line);
  text-underline-offset:.15em;
}
.ticket__venue a:hover{ color:var(--accent); text-decoration-color:var(--accent); }
/* extend the venue link's hit area to the whole info cell, so clicking
   anywhere next to the date (not just the underlined venue text) opens
   the map link — the lineup link stays independently clickable via its
   own z-index above this overlay */
.ticket__venue a::after{ content:""; position:absolute; inset:0; }
/* optional — only rendered when a show specifies show.doors */
.ticket__doors{ font-size:.78rem; color:var(--muted); opacity:.8; margin-top:.15rem; }
/* only rendered by js/shows.js when the cell is actually a link — a
   visual hint that the whole card opens something on click */
.ticket__arrow{
  flex:none;
  width:1.1rem;
  height:1.1rem;
  color:var(--muted);
  transition:transform .15s ease, color .15s ease;
}
.ticket__info:hover ~ .ticket__arrow{ color:var(--accent); transform:translateX(3px); }

.shows__year + .shows__year{ margin-top:1.4rem; }
.shows__year h4{
  font-family:var(--display);
  font-weight:500;
  font-size:.78rem;
  letter-spacing:.08em;
  color:var(--accent);
  margin-bottom:.5rem;
}
.shows__list{ list-style:none; }
/* a real 3-column table (date | info | arrow), not flex — so every row
   lines up in identical columns regardless of content length, at every
   viewport size down to small phones (see the narrower column widths
   in the responsive section instead of the old stack-to-column
   fallback this replaced). The arrow slot is always rendered by
   js/shows.js even when a show has no venueUrl, empty rather than
   omitted, so its column keeps its width on every row. */
.show{
  display:grid;
  grid-template-columns:4.4rem 1fr 1.1rem;
  align-items:center;
  /* roomy by default — tightened back down for narrow screens in the
     responsive section, where the date column needs what little width
     it has just for the date itself, not extra breathing room */
  gap:1.6rem;
  padding:.55rem 0;
  border-top:1px solid var(--ink-3);
}
.shows__list li.show:first-child{ border-top:none; }
.show__date{
  font-variant-numeric:tabular-nums;
  font-size:.76rem;
  white-space:nowrap;
  color:var(--muted);
  padding-top:.1rem;
}
.show__info{ min-width:0; position:relative; }
.show__info:has(.show__venue a){ cursor:pointer; }
.show__lineup{ font-size:.92rem; color:var(--text); line-height:1.4; }
.show__lineup a{
  position:relative;
  z-index:1;
  color:var(--paper);
  text-decoration:underline;
  text-decoration-color:var(--line);
  text-underline-offset:.15em;
}
.show__lineup a:hover{ color:var(--accent); text-decoration-color:var(--accent); }
.show__lineup b{ color:var(--paper); font-weight:600; }
.show__venue{ font-size:.8rem; color:var(--muted); margin-top:.15rem; }
.show__venue a{
  color:var(--muted);
  text-decoration:underline;
  text-decoration-color:var(--line);
  text-underline-offset:.15em;
}
.show__venue a:hover{ color:var(--accent); text-decoration-color:var(--accent); }
/* same whole-cell-clickable treatment as .ticket__venue above */
.show__venue a::after{ content:""; position:absolute; inset:0; }
/* optional — only rendered when a show specifies show.doors */
.show__doors{ font-size:.76rem; color:var(--muted); opacity:.8; margin-top:.1rem; }
.show__arrow-slot{ display:flex; align-items:center; justify-content:center; }
.show__arrow{
  width:.95rem;
  height:.95rem;
  color:var(--muted);
  transition:transform .15s ease, color .15s ease;
}
.show__info:hover ~ .show__arrow-slot .show__arrow{ color:var(--accent); transform:translateX(3px); }

.shows__empty{ font-size:.85rem; color:var(--muted); }

/* ================================================================
   FILMSTRIP
   ================================================================ */

.strip-section{ padding:0 0 5rem; }
.filmstrip{
  display:flex;
  gap:.6rem;
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  padding:0 var(--edge);
  scrollbar-width:thin;
  scrollbar-color:var(--accent) var(--ink-2);
}
.filmstrip img{
  flex:none;
  scroll-snap-align:start;
  width:min(78vw, 340px);
  height:min(70vh, 440px);
  object-fit:cover;
  filter:grayscale(1) contrast(1.1) brightness(.95);
  transition:filter .3s ease;
}
.filmstrip img:hover{ filter:grayscale(0) contrast(1.05) brightness(1); }

/* ================================================================
   FOOTER
   ================================================================ */

/* same red gradient as .cta-card--primary (the streaming-link card) —
   paper-toned text/icons throughout so they read against the red
   instead of blending into it, same reasoning as that card. */
.footer{
  background:linear-gradient(120deg, var(--accent) 0%, var(--accent-2) 100%);
  color:var(--paper);
  padding:3.4rem 0 2.4rem;
}
.footer .eyebrow{ color:var(--paper); }
.footer .eyebrow::after{ background:rgba(242,236,224,.4); }
.footer__grid{
  display:flex;
  flex-wrap:wrap;
  justify-content:space-between;
  align-items:flex-end;
  gap:2rem;
}
.footer__mail{
  display:block;
  font-family:var(--display);
  font-weight:700;
  font-size:clamp(1.6rem, 4vw, 2.4rem);
  letter-spacing:.01em;
  margin-top:.6rem;
  color:var(--paper);
}
.footer__mail:hover{ color:var(--ink); }
.footer__meta{ font-size:.85rem; color:rgba(242,236,224,.8); margin-top:.6rem; }
/* two icon rows — Social (Instagram/Facebook) and Musik (streaming
   platforms) — each with its own small caps label above it */
.footer__platform-groups{ display:flex; flex-wrap:wrap; gap:1.6rem 2.2rem; }
.footer__platform-group{ display:flex; flex-direction:column; gap:.6rem; align-items:flex-start; }
.footer__platform-label{
  font-family:var(--display);
  font-weight:500;
  font-size:.72rem;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:rgba(242,236,224,.8);
}
.footer__platforms{ display:flex; gap:.7rem; }
.footer__platforms a{
  width:2.9rem;
  height:2.9rem;
  border-radius:50%;
  display:flex;
  align-items:center;
  justify-content:center;
  background:var(--paper);
  color:var(--accent);
  transition:background-color .15s ease, color .15s ease, transform .15s ease;
}
.footer__platforms a svg{ width:1.3rem; height:1.3rem; }
.footer__platforms a:hover{ background:var(--ink); color:var(--paper); transform:translateY(-2px); }

/* ================================================================
   RESPONSIVE
   ================================================================ */

@media (max-width:900px){
  .nav__links{
    position:fixed;
    inset:4.4rem 0 0 0;
    background:var(--ink);
    flex-direction:column;
    align-items:flex-start;
    padding:2rem var(--edge);
    gap:1.4rem;
    font-size:1.1rem;
    transform:translateX(100%);
    visibility:hidden;
    pointer-events:none;
    transition:transform .25s ease, visibility .25s;
  }
  .nav__links.is-open{
    transform:translateX(0);
    visibility:visible;
    pointer-events:auto;
  }
  .nav__toggle{ display:flex; }

  .bio-grid{ flex-direction:column; gap:1.6rem; }
  /* unwrap .bio-grid__left so head and photo become direct flex items
     of .bio-grid, sitting as siblings of .bio-grid__body — only then
     can `order` interleave them: heading first, then the full bio
     text, then the photo last (see the request this answers). */
  .bio-grid__left{ display:contents; }
  .bio-grid__head{ order:1; }
  .bio-grid__body{ order:2; }
  .bio-grid__photo{ order:3; }
}

@media (max-width:700px){
  .section{ padding:3.4rem 0; }

  .show{ gap:.6rem; }

  /* .hero__stage keeps the same centered treatment as full resolution
     here — now that the logo itself is this much smaller, it comfortably
     fits the shrunken (aspect-ratio-locked) mobile hero. */
  .hero__logo{ width:min(14rem, 52vw); }

  /* the shrunken hero leaves no room for this without it sitting behind
     the logo, and on mobile most of the page is visible on first paint
     anyway — the "scroll for more" cue isn't needed to begin with */
  .hero__scroll{ display:none; }

  /* keep the ticker — it's a nice bit of motion — but as a slim strip
     instead of a full-size text band eating a chunk of the screen */
  /* .marquee{
      background:var(--ink-2);
      color:var(--text);
      border-bottom:1px solid var(--ink-3);
  } */
  .marquee__track{ padding:.3rem 0; }
  .marquee__item{ font-size:.62rem; letter-spacing:.06em; padding:0 .8rem; }
}
