/* Component layer — every rule below reads from css/tokens/, never from a raw value. */

/* ---------- bands: the full-bleed horizontal stripes the page is made of ---------- */
.band{padding:var(--band-pad-y) var(--band-pad-x)}
.band--sky{text-align:center}
.band--sky h2{color:var(--text-on-sky)}
/* The sky band is the plain sky colour and nothing else — no scrim, no gradient.
   One was tried, to lift the white type off the blue, and it failed for a reason
   worth keeping: the band is only ~195px tall and the sky continues well past it,
   so the darkening stopped where the band stopped and left a hard horizontal edge
   across the photograph. Any tint bounded by this band does the same.
   The white type here is at 2.59:1 and the glyphs at 2.53:1. If that has to be
   fixed, fix it on the type and the glyph files — not on the picture. */
/* The follow band and the player band read as one unit over the photograph,
   so they close the gap between them rather than each carrying full rhythm. */
.band--sky{padding-bottom:var(--space-5)}
.band--player{padding-top:var(--space-5)}
.band--page{background:var(--surface-page)}
.band--dark{background:var(--surface-dark)}
.band--dark h2{color:var(--text-on-dark)}
.band--mark{
  height:var(--band-mark-h);
  padding:0 var(--band-pad-x);
  display:flex;
  align-items:center;
  justify-content:center;
}
/* The mark grows with the viewport but the band did not, so it crowded the
   edges on desktop while a phone had room to spare. 648px is where --size-mark
   stops growing: 34vw reaches its 220px maximum there, so the band opens at the
   same moment rather than leaving a stretch where a full-size mark sits in a
   short band. Breakpoints are literal — a media query cannot read a custom
   property, so this one has to be kept in step with --size-mark by hand. */
@media (min-width:648px){
  .band--mark{height:var(--band-mark-h-lg)}
}

/* The card carries its own vertical breathing room — above the heading and below
   whatever ends it — so the player and the press block stay in step. Horizontal
   padding stays at 0 so rows and their rules run the full width. */
.panel{
  background:var(--surface-panel-90);
  max-width:var(--block-max);
  margin:0 auto;
  padding:var(--space-7) 0;
}

/* ---------- shared primitives ---------- */
.caps{
  font-size:var(--type-caps);
  font-weight:var(--weight-bold);
  letter-spacing:var(--track-caps);
  text-transform:uppercase;
}
.num{font-variant-numeric:tabular-nums}

/* Carried by the accessibility tree, not by the eye. Used for the h1: the wordmark
   is the band's name on screen, but a page needs one in its outline too. */
.visually-hidden{
  position:absolute;
  width:var(--size-hairline);
  height:var(--size-hairline);
  margin:calc(var(--size-hairline) * -1);
  padding:0;
  border:0;
  overflow:hidden;
  clip-path:inset(50%);
  white-space:nowrap;
}

.follow{display:flex;justify-content:center;gap:var(--space-4);margin-top:var(--space-5)}
.follow a{padding:var(--space-2);opacity:var(--opacity-full);transition:opacity var(--dur-base) var(--ease-brand)}
.follow a:hover{opacity:var(--opacity-hover)}
.follow--sm{gap:var(--space-3);margin-top:var(--space-6)}
.glyph{display:block;width:var(--size-icon);height:var(--size-icon)}
.glyph-sm{width:var(--size-icon-sm);height:var(--size-icon-sm)}

/* ---------- player ---------- */
.player__title{padding:0 var(--space-5)}
.player__head{display:flex;align-items:stretch;gap:var(--space-5);padding:var(--space-5)}
.player__art{position:relative;flex:0 0 auto}
.player__cover{width:var(--size-cover);aspect-ratio:1;object-fit:cover;display:block}
.player__flag{
  position:absolute;
  left:0;
  bottom:0;
  background:var(--surface-dark);
  color:var(--text-on-dark);
  padding:var(--space-1) var(--space-2);
}
.player__meta{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:space-between}
.player__label{color:var(--text-muted)}
.player__now{
  font-family:var(--font-hand);
  font-size:var(--type-hand-md);
  line-height:var(--leading-hand);
  margin-top:var(--space-2);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.player__controls{display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-4)}
.player__progress{padding:0 var(--space-5) var(--space-4)}
/* The rail itself is a hairline; the padding around it is the hit area, so the
   seek target is a finger wide rather than three pixels. */
.player__seek{padding:var(--space-2) 0;cursor:pointer}
.player__rail{height:var(--size-progress);background:var(--line-hairline)}
.player__bar{width:0;height:100%;background:var(--surface-dark);transition:width var(--dur-tick) var(--ease-linear)}
.player__times{
  display:flex;
  justify-content:space-between;
  margin-top:var(--space-2);
  font-size:var(--type-caps);
  color:var(--text-muted);
}
.player__tracks{border-top:var(--border-soft)}

.ctl{
  width:var(--size-control);
  height:var(--size-control);
  display:grid;
  place-items:center;
  border:var(--border-none);
  border-radius:var(--radius-none);
  background:none;
  color:var(--text-body);
  font-size:var(--type-caption);
  padding:0;
  cursor:pointer;
  transition:opacity var(--dur-base) var(--ease-brand);
}
.ctl:hover{opacity:var(--opacity-hover)}
.ctl--main{
  width:var(--size-control-lg);
  height:var(--size-control-lg);
  border-color:var(--line-ink);
  background:var(--surface-dark);
  color:var(--text-on-dark);
  font-size:var(--type-body-sm);
}
.ctl--main:hover{opacity:var(--opacity-full);background:var(--text-muted)}

.trk{
  width:100%;
  display:flex;
  align-items:center;
  gap:var(--space-3);
  padding:var(--space-3) var(--space-5);
  background:none;
  border:none;
  border-bottom:var(--border-soft);
  font-family:var(--font-sans);
  font-size:var(--type-body-sm);
  color:var(--text-body);
  cursor:pointer;
  text-align:left;
  transition:background-color var(--dur-fast) var(--ease-brand);
}
.trk:last-child{border-bottom:none}
.trk[aria-current=true]{background:var(--state-current-ink)}
.trk .n{width:var(--size-trk-num);font-size:var(--type-caps);color:var(--text-muted)}
.trk .t{flex:1}
.trk[aria-current=true] .t{font-weight:var(--weight-bold)}
.trk .d{font-size:var(--type-meta);color:var(--text-muted)}
/* A song with no file yet: listed, legible, plainly not clickable. */
.trk--soon{cursor:default;color:var(--text-muted)}
.trk--soon:hover{background:none}
.ctl:disabled{opacity:var(--opacity-disabled);cursor:default}
.ctl:disabled:hover{opacity:var(--opacity-disabled)}

/* ---------- live dates ---------- */
.gigs{
  max-width:var(--block-max);
  margin:var(--space-6) auto 0;
  border:var(--border-on-dark);
  color:var(--text-on-dark);
}
.gigs__head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--space-4);
  padding:var(--space-3) var(--space-5);
  border-bottom:var(--border-on-dark);
}
.gigs__head a{color:var(--text-on-dark);text-decoration:underline;text-underline-offset:3px}
.gigs__all{
  display:block;
  padding:var(--space-3) var(--space-5);
  text-align:center;
  color:var(--text-on-dark);
  text-decoration:none;
  border-top:var(--border-on-dark-soft);
  transition:background-color var(--dur-base) var(--ease-brand);
}
.gigs__all:hover{background:var(--state-hover-on-dark);color:var(--text-on-dark)}
/* Status lines: loading, nothing booked, API unreachable. */
.gigs__note{
  margin:0;
  padding:var(--space-5);
  text-align:center;
  font-size:var(--type-body-sm);
  line-height:var(--leading-body);
  color:var(--text-on-dark-muted);
}
.gigs__note a{color:var(--text-on-dark);text-decoration:underline;text-underline-offset:3px}

/* Past dates, collapsed by default. */
.gigs__past{border-top:var(--border-on-dark-soft)}
.gigs__toggle{
  width:100%;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--space-4);
  padding:var(--space-3) var(--space-5);
  background:none;
  border:none;
  border-radius:var(--radius-none);
  font-family:var(--font-sans);
  font-size:var(--type-caps);
  font-weight:var(--weight-bold);
  letter-spacing:var(--track-caps);
  text-transform:uppercase;
  color:var(--text-on-dark-muted);
  cursor:pointer;
  transition:color var(--dur-base) var(--ease-brand);
}
.gigs__toggle:hover{color:var(--text-on-dark)}
.gigs__chevron{transition:transform var(--dur-base) var(--ease-brand)}
.gigs__toggle[aria-expanded=true] .gigs__chevron{transform:rotate(180deg)}
.gigs__past .gig{border-top:var(--border-on-dark-soft);border-bottom:none}
/* A played show is a record, not an offer — it reads back a step. */
.gig--past{color:var(--text-on-dark-muted)}
.gig--past:hover{color:var(--text-on-dark)}
.gig__note{flex:0 0 auto;white-space:nowrap;color:var(--text-on-dark-faint)}
.gig{
  display:flex;
  align-items:center;
  gap:var(--space-5);
  padding:var(--space-4) var(--space-5);
  border-bottom:var(--border-on-dark-soft);
  color:var(--text-on-dark);
  text-decoration:none;
  transition:background-color var(--dur-base) var(--ease-brand);
}
.gig:hover{background:var(--state-hover-on-dark);color:var(--text-on-dark)}
/* The rows below carry their own top rule, so the list must not double it up. */
.gigs__list .gig:last-child{border-bottom:none}
.gig .day{flex:0 0 var(--size-gig-day);text-align:center;line-height:var(--leading-none)}
.gig .day b{display:block;font-size:var(--type-numeral);font-variant-numeric:tabular-nums}
.gig .day span{
  display:block;
  font-size:var(--type-caps-sm);
  font-weight:var(--weight-bold);
  letter-spacing:var(--track-caps);
  margin-top:var(--space-1);
  color:var(--text-on-dark-muted);
}
.gig .v{flex:1;min-width:0}
.gig .v b{display:block;font-size:var(--type-body-sm)}
.gig .v span{display:block;font-size:var(--type-caption);color:var(--text-on-dark-muted);margin-top:var(--space-1)}
.pill{
  flex:0 0 auto;
  padding:var(--space-2) var(--space-4);
  white-space:nowrap;
  border:var(--border-on-dark);
  transition:background-color var(--dur-base) var(--ease-brand),color var(--dur-base) var(--ease-brand);
}
.gig:hover .pill{background:var(--text-on-dark);color:var(--text-body)}
.pill--off{border-color:var(--line-on-dark-soft);color:var(--text-on-dark-faint)}
.gig:hover .pill--off{background:transparent;color:var(--text-on-dark-faint)}
/* On a phone the venue column has to win the space, or names like "MuK Studios"
   break across two lines. Breakpoints are literal — a media query cannot read a
   custom property. */
@media (max-width:480px){
  .gig{gap:var(--space-3);padding:var(--space-4)}
  .gig .pill{padding:var(--space-2) var(--space-3)}
}

/* ---------- prose ---------- */
.prose{
  max-width:var(--content-max);
  margin:var(--space-7) auto 0;
  font-size:var(--type-body);
  line-height:var(--leading-body);
  text-wrap:pretty;
}
.prose p{margin:0}
.prose p + p{margin-top:var(--space-4)}

/* ---------- rotating mark ----------
   Painted as a mask in --text-on-dark, the same way .wordmark is. It used to be
   filter:brightness(0) invert(1), which produces pure #ffffff — so the two brand
   marks on the page were two different whites, and the filter route bypassed the
   colour system entirely. heartakreis.svg carries no fill of its own, so it works
   as a stencil unchanged.
   A mask clips the element, so this has to be an empty element rather than an
   <img>: an <img> would still paint its own black paths over the masked fill.
   Hence the <span> in the markup, exactly as .wordmark does it. */
.mark{
  display:block;
  width:var(--size-mark);
  aspect-ratio:1;
  animation:kpspin var(--dur-rotate) var(--ease-linear) infinite;
  background:var(--text-on-dark);
  -webkit-mask:url(../assets/heartakreis.svg) no-repeat center/contain;
  mask:url(../assets/heartakreis.svg) no-repeat center/contain;
}

/* ---------- downloads ---------- */
.downloads__title{padding:0 var(--space-5) var(--space-4)}
.downloads__contact{padding:var(--space-4) var(--space-5) 0;font-size:var(--type-caption);color:var(--text-muted)}
.dl{
  display:flex;
  align-items:center;
  gap:var(--space-4);
  padding:var(--space-4) var(--space-5);
  text-decoration:none;
  color:var(--text-body);
  border-bottom:var(--border-soft);
  transition:background-color var(--dur-base) var(--ease-brand);
}
.dl:hover{background:var(--state-hover-ink);color:var(--text-body)}
.dl .l{flex:1;min-width:0}
.dl .l b{display:block;font-size:var(--type-body-sm)}
.dl .l span{display:block;font-size:var(--type-caption);color:var(--text-muted);margin-top:var(--space-1)}
.dl .b{
  flex:0 0 auto;
  /* Every action in the list is the width of the widest label, so a short one
     like "ZIP" does not shrink out of the column. */
  min-width:var(--size-action-min);
  text-align:center;
  padding:var(--space-2) var(--space-4);
  white-space:nowrap;
  border:var(--border-hairline);
  transition:background-color var(--dur-base) var(--ease-brand),color var(--dur-base) var(--ease-brand);
}
.dl:hover .b{background:var(--surface-dark);color:var(--text-on-dark)}

/* ---------- newsletter ----------
   PARKED, not dead. The markup sits commented out in index.html; these rules are the
   other half of it and stay so that un-commenting is the whole job. Do not tidy them
   away as orphans — see the PARKED note in index.html. */
.news{max-width:var(--block-max);margin:0 auto;text-align:center}
.news__lead{
  font-size:var(--type-body-sm);
  line-height:var(--leading-body);
  color:var(--text-muted);
  margin:var(--space-3) 0 var(--space-5);
}
.news__form{display:grid;gap:var(--space-4);text-align:left}
.news__row{display:flex;gap:var(--space-3);align-items:flex-end}
.news__row label{flex:1}
.news__label{display:block;margin-bottom:var(--space-2)}
.news__consent{
  display:flex;
  align-items:flex-start;
  gap:var(--space-3);
  font-size:var(--type-body-sm);
  line-height:var(--leading-body);
  cursor:pointer;
}
.news__consent input{
  margin-top:var(--space-1);
  width:var(--size-control-sm);
  height:var(--size-control-sm);
  accent-color:var(--control-accent);
}
.news__ok{font-size:var(--type-body);margin:0}
.field{
  width:100%;
  padding:var(--space-3) var(--space-4);
  background:transparent;
  color:var(--text-body);
  border:var(--border-hairline);
  border-radius:var(--radius-none);
  font-family:var(--font-sans);
  font-size:var(--type-body);
  outline-color:var(--focus-ring);
  outline-offset:2px;
}
.submit{
  padding:var(--space-4) var(--space-5);
  border:var(--border-none);
  border-radius:var(--radius-none);
  background:var(--surface-dark);
  color:var(--text-on-dark);
  font-family:var(--font-sans);
  font-size:var(--type-body-sm);
  font-weight:var(--weight-bold);
  letter-spacing:var(--track-caps);
  text-transform:uppercase;
  cursor:pointer;
  transition:opacity var(--dur-base) var(--ease-brand);
}
.submit:hover{opacity:var(--opacity-hover)}

/* ---------- footer ---------- */
.site-footer{
  background:var(--surface-footer);
  color:var(--text-on-dark);
  padding:var(--band-pad-y) var(--band-pad-x) var(--space-7);
  text-align:center;
}
/* The logo SVG carries no fill of its own, so it is painted as a mask. */
.wordmark{
  display:block;
  width:var(--size-wordmark);
  max-width:var(--wordmark-max);
  aspect-ratio:var(--ratio-wordmark);
  margin:0 auto;
  background:var(--text-on-dark);
  -webkit-mask:url(../assets/logo-offwhite.svg) no-repeat center/contain;
  mask:url(../assets/logo-offwhite.svg) no-repeat center/contain;
}
.site-footer .wordmark{width:var(--size-wordmark-sm)}
.footer-nav{display:flex;justify-content:center;flex-wrap:wrap;gap:var(--space-5);margin-top:var(--space-6)}
.footer-nav a{color:var(--text-on-dark-muted);text-decoration:none}

/* The page sits above the photograph — see the #backdrop note in base.css.
   The footer is listed separately because it is a sibling of main, not inside it. */
main,
.site-footer{position:relative;z-index:1}

/* ---------- legal pages ----------
   Impressum und Datenschutz: langer Fließtext, kein Foto, kein Gate. Eine Spalte
   auf Lesemaß, sonst nichts. */
.legal{
  max-width:var(--content-max);
  margin:0 auto;
  padding:var(--band-pad-y) var(--band-pad-x);
}
.legal__back{
  display:inline-block;
  margin-bottom:var(--space-6);
  font-size:var(--type-body-sm);
}
.legal h1{
  font-family:var(--font-hand);
  font-size:var(--type-hand-section);
  line-height:var(--leading-hand);
  letter-spacing:var(--track-hand);
  text-align:left;
  margin:0 0 var(--space-7);
}
/* Ein nummerierter Abschnitt. Bekommt oben eine Haarlinie, damit die vier
   Hauptteile der Erklärung ohne Zählen auseinanderzuhalten sind. */
.legal h2{
  font-family:var(--font-hand);
  font-size:var(--type-hand-block);
  line-height:var(--leading-hand);
  letter-spacing:var(--track-hand);
  text-align:left;
  margin:var(--space-8) 0 var(--space-5);
  padding-top:var(--space-6);
  border-top:var(--border-soft);
}
.legal h2:first-of-type{margin-top:0;padding-top:0;border-top:none}
.legal h3{
  font-family:var(--font-sans);
  font-size:var(--type-body-lg);
  font-weight:var(--weight-bold);
  line-height:var(--leading-tight);
  letter-spacing:var(--track-body);
  text-align:left;
  margin:var(--space-6) 0 var(--space-3);
}
.legal h4{
  font-size:var(--type-body);
  font-weight:var(--weight-bold);
  line-height:var(--leading-tight);
  margin:var(--space-5) 0 var(--space-2);
}
.legal p{
  font-size:var(--type-body-sm);
  line-height:var(--leading-body);
  margin:0 0 var(--space-4);
  text-wrap:pretty;
}
.legal ul{
  margin:0 0 var(--space-4);
  padding-left:var(--space-5);
}
.legal li{
  font-size:var(--type-body-sm);
  line-height:var(--leading-body);
  margin-bottom:var(--space-3);
}
.legal__address{font-style:normal}
/* Der Art.-21-Widerspruch steht im Gesetzestext in Versalien und bleibt so.
   Kleiner gesetzt und eingerahmt, damit er den Rest der Seite nicht anschreit. */
.legal__shout{
  font-size:var(--type-caption);
  line-height:var(--leading-body);
  padding:var(--space-4);
  border:var(--border-soft);
  margin-bottom:var(--space-3);
}

/* ---------- safe areas ----------
   With viewport-fit=cover the page reaches under the status bar, the home indicator
   and, in landscape, the notch. The bands stay full-bleed — the photograph should run
   right to the edge — but their contents are held clear of the hardware.
   env() resolves to 0 wherever there is no inset, so this changes nothing elsewhere. */
.band,
.site-footer{
  padding-left:calc(var(--band-pad-x) + env(safe-area-inset-left,0px));
  padding-right:calc(var(--band-pad-x) + env(safe-area-inset-right,0px));
}
.band--sky{padding-top:calc(var(--band-pad-y) + env(safe-area-inset-top,0px))}
.site-footer{padding-bottom:calc(var(--space-7) + env(safe-area-inset-bottom,0px))}
