/* ============================================================
   V3 — KELLERDECK · Das Label als Player
   Dichtes, dunkles Streaming-Interface im Markenlook.
   Persistente Player-Leiste, Cyan-Waveform, scanbare
   Tracklist. Ansichten wechseln, die Wiedergabe laeuft weiter.
   ============================================================ */

:root{
  --tex-hero:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%201200%20800%27%3E%3Cfilter%20id%3D%27c%27%20x%3D%270%27%20y%3D%270%27%20width%3D%27100%25%27%20height%3D%27100%25%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.009%200.038%27%20numOctaves%3D%275%27%20seed%3D%277%27%2F%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%271200%27%20height%3D%27800%27%20fill%3D%27%230e0e0e%27%2F%3E%3Crect%20width%3D%271200%27%20height%3D%27800%27%20filter%3D%27url%28%23c%29%27%20opacity%3D%270.62%27%2F%3E%3Cg%20fill%3D%27%23e8e6e1%27%20opacity%3D%270.05%27%3E%3Crect%20y%3D%27196%27%20width%3D%271200%27%20height%3D%279%27%2F%3E%3Crect%20y%3D%27523%27%20width%3D%271200%27%20height%3D%274%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
  --tex-cover:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20800%20800%27%3E%3Cfilter%20id%3D%27g%27%20x%3D%270%27%20y%3D%270%27%20width%3D%27100%25%27%20height%3D%27100%25%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.014%200.055%27%20numOctaves%3D%275%27%20seed%3D%2711%27%2F%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27800%27%20height%3D%27800%27%20fill%3D%27%23101010%27%2F%3E%3Crect%20width%3D%27800%27%20height%3D%27800%27%20filter%3D%27url%28%23g%29%27%20opacity%3D%270.66%27%2F%3E%3Cg%20fill%3D%27%23e8e6e1%27%20opacity%3D%270.07%27%3E%3Crect%20y%3D%27112%27%20width%3D%27800%27%20height%3D%277%27%2F%3E%3Crect%20y%3D%27318%27%20width%3D%27800%27%20height%3D%273%27%2F%3E%3Crect%20y%3D%27487%27%20width%3D%27800%27%20height%3D%2712%27%2F%3E%3Crect%20y%3D%27655%27%20width%3D%27800%27%20height%3D%274%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
  --black:#0a0a0a;
  --black-2:#131313;
  --black-3:#1c1c1d;
  --white:#eeece6;
  --grey:#a5a39c;
  --grey-dim:#8a8881;      /* 4.8:1 auf --black-3, 6.6:1 auf --black. War #85837d
                              und lag auf --black-3 bei 4.49:1 — knapp unter AA. */
  --cyan:#17f2ff;
  --line:#2a2a2a;            /* Trennlinien und Flaechenkanten, kein Bedienelement */
  --rand:#6b6963;            /* Rand von Bedienelementen: 3.6:1 auf --black,
                                3.4:1 auf --black-2 — WCAG 1.4.11 verlangt 3:1 */
  --warn:#ff5a4d;            /* Fehlerzustaende, 6.4:1 auf --black */
  --warn-text:#ffb3ac;       /* Fehlertext, 11.6:1 auf --black */

  --font-display:'Anton','Arial Narrow',sans-serif;
  --font-body:'Barlow Condensed','Arial Narrow',sans-serif;
  --font-mono:'Space Mono','Courier New',monospace;

  --gutter:clamp(16px,4vw,56px);
  --bar-h:84px;               /* Hoehe der Player-Leiste, Desktop */

  /* Abstandsskala, Vierer-Basis. Die mittleren Stufen fehlen einer reinen
     Achterskala, und genau die braucht diese Seite zwischen Zeile und Block. */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:20px;
  --s-5:32px; --s-6:52px; --s-7:84px;

  /* Rhythmus: drei benannte Intervalle statt eines wiederholten Wertes.
     Vorher hatte jede Sektion denselben Innenabstand — dadurch wog alles
     gleich viel und die Seite hatte keine Gliederung, nur Wiederholung.
       eng    = innerhalb einer Gruppe, Teile gehoeren zusammen
       mittel = zwischen Gruppen derselben Aussage
       weit   = zwischen zwei Gedanken, hier darf der Blick anhalten */
  --takt-eng:clamp(20px,3vh,34px);
  --takt-mittel:clamp(34px,5vh,56px);
  --takt-weit:clamp(56px,8.5vh,108px);
}

*,*::before,*::after{box-sizing:border-box}

html{
  scroll-behavior:smooth;
  scroll-padding-top:72px;
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  background:var(--black);
  color:var(--white);
  font-family:var(--font-body);
  font-size:clamp(16px,1.05vw,18px);
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  /* Platz fuer die fixe Player-Leiste, damit sie nie Inhalt verdeckt */
  padding-bottom:calc(var(--bar-h) + 12px + env(safe-area-inset-bottom, 0px));

  /* Kurze Seiten endeten mitten im Bild: unter dem Fussbereich stand
     schwarzer Leerraum bis zur Player-Leiste — gemessen 194 Pixel auf
     /interpreten bei 1440x900 und 315 Pixel im Impressum. Der Fussbereich
     ist der Abschluss der Seite und gehoert an deren Unterkante, auch
     wenn der Inhalt den Schirm nicht fuellt. */
  min-height:100vh;
  display:flex;
  flex-direction:column;
}
/* Neuere Browser rechnen die ein- und ausfahrende Adressleiste des Telefons
   mit; bei 100vh springt die Hoehe dort. */
@supports (min-height:100dvh){
  body{min-height:100dvh}
}
body > main{flex:1 0 auto}

/* Verwaltung, Rechtstexte und die 404-Seite tragen keine Player-Leiste. Der
   reservierte Platz stand dort trotzdem: 88 Pixel Leere unter dem Fussbereich,
   auf dem Telefon fast eine Bildschirmzeile. */
body.ohne-player{padding-bottom:env(safe-area-inset-bottom, 0px)}

img{max-width:100%;display:block}
::selection{background:var(--cyan);color:var(--black)}
:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}

/* Was der Browser selbst zeichnet, gehoert trotzdem zum Geraet. Auf einem
   fast schwarzen Grund ist die helle Standard-Bildlaufleiste ein heller
   Streifen aus einer fremden Oberflaeche — und die Songliste hat auf breiten
   Schirmen eine waagerechte, die staendig zu sehen ist. */
html{scrollbar-color:var(--rand) var(--black-2);scrollbar-width:thin}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:var(--black-2)}
::-webkit-scrollbar-thumb{background:var(--rand);border:2px solid var(--black-2)}
::-webkit-scrollbar-thumb:hover{background:var(--grey-dim)}
::-webkit-scrollbar-corner{background:var(--black-2)}

/* Der Schreibcursor im Akzent des Labels: das einzige Cyan, das der Besucher
   selbst bewegt. */
.field input,.field textarea,.field select,.afeld input{caret-color:var(--cyan)}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

.wrap{
  max-width:1400px;margin-inline:auto;
  /* Im Querformat schneiden Kerbe und Rundung in den Rand. max() nimmt
     jeweils den groesseren von Gestaltungsrand und Geraeterand. */
  padding-inline:
    max(var(--gutter), env(safe-area-inset-left, 0px))
    max(var(--gutter), env(safe-area-inset-right, 0px));
}

/* Feines Korn — leiser als in den Schwestervarianten,
   das Interface soll ruhig bleiben. */
body::after{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:5;
  opacity:.22;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/></filter><rect width='160' height='160' filter='url(%23n)' opacity='.5'/></svg>");
}

.skip{
  position:absolute;left:var(--gutter);top:-100px;z-index:90;
  background:var(--cyan);color:var(--black);
  font-family:var(--font-mono);font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;padding:10px 16px;text-decoration:none;
}
.skip:focus{top:12px}

/* ---------- Kopfleiste mit Ansichtswechsel ---------- */

.top{
  position:sticky;top:0;z-index:40;
  background:rgba(10,10,10,.94);
  backdrop-filter:blur(6px);
  border-bottom:1px solid var(--line);
}
.top__inner{
  display:flex;align-items:center;justify-content:space-between;
  gap:16px;height:60px;
}
.top__mark{
  display:flex;align-items:baseline;gap:8px;
  font-family:var(--font-display);
  font-size:clamp(15px,1.5vw,19px);letter-spacing:.05em;
  text-transform:uppercase;color:var(--white);
  text-decoration:none;white-space:nowrap;
  /* Die Zeile ist 20 Pixel hoch — als einziger Weg zurueck auf die Startseite
     ist das auf dem Telefon zu wenig. Der Rand waechst, die Schrift nicht;
     in der 60 Pixel hohen Kopfleiste bleibt das ohne Folge fuers Bild. */
  padding-block:13px;
}
.top__mark span{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;
  color:var(--cyan);border:1px solid var(--cyan);padding:2px 5px;
}

/* Segmentierter Umschalter, kein Link — die Wiedergabe soll
   den Ansichtswechsel ueberleben. */
.views{display:flex;border:1px solid var(--rand)}
.views__btn{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;
  background:transparent;border:0;color:var(--grey);
  display:inline-flex;align-items:center;min-height:44px;padding:0 16px;
  cursor:pointer;text-decoration:none;
  transition:background .12s linear,color .12s linear;
}
.views__btn + .views__btn{border-left:1px solid var(--line)}
.views__btn:hover{color:var(--white)}
.views__btn[aria-selected="true"]{background:var(--cyan);color:var(--black)}

/* Auf dem Telefon braucht die Kopfleiste mehr Platz als vorhanden ist:
   Wortmarke, "DECK"-Plakette und beide Reiter stehen alle auf nowrap und
   ergeben zusammen 409 px Mindestbreite. Im Browser bei 360 und 390 px
   gemessen: die ganze Seite liess sich seitlich schieben, und der Reiter
   "Interpreten" lag zur Haelfte ausserhalb des Sichtfelds — der zweite von
   zwei Ansichten war damit nur ueber eine Seitwaertsgeste erreichbar.
   Die Plakette ist Schmuck und geht zuerst. */
@media (max-width:560px){
  .top__inner{gap:10px}
  .top__mark{font-size:13px;letter-spacing:.04em}
  .top__mark span{display:none}
  .views__btn{padding:0 10px;letter-spacing:.08em}
}

/* ---------- Ansichten ---------- */

.view[hidden]{display:none}

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

.hero{
  position:relative;overflow:hidden;
  border-bottom:1px solid var(--line);
  padding-block:clamp(40px,7vh,86px) clamp(28px,4.5vh,54px);
}
.hero::before{
  content:"";position:absolute;inset:0;
  background:var(--tex-hero) center/cover no-repeat;
  opacity:.42;filter:grayscale(.4) contrast(1.2);
  mask-image:linear-gradient(to bottom,#000,transparent);
  -webkit-mask-image:linear-gradient(to bottom,#000,transparent);
  pointer-events:none;
}
.hero__inner{position:relative;z-index:1}
.hero__meta{
  display:flex;flex-wrap:wrap;gap:6px 22px;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--grey-dim);
  margin-bottom:clamp(16px,3vh,28px);
}
.hero__meta b{color:var(--cyan);font-weight:400}
.hero__title{
  margin:0;font-family:var(--font-display);font-weight:400;
  text-transform:uppercase;line-height:.84;letter-spacing:-.018em;
  font-size:clamp(50px,12vw,180px);
}
.hero__title span{display:block}
.hero__title .l2{color:var(--grey)}
.hero__claim{
  margin:clamp(20px,3.5vh,36px) 0 0;
  max-width:44ch;
  font-size:clamp(17px,1.5vw,22px);
  line-height:1.45;color:var(--grey);
}

/* ---------- Sektionen ---------- */

.section{
  border-bottom:1px solid var(--line);
  padding-block:clamp(40px,7vh,84px);
}
.section__head{
  display:flex;flex-wrap:wrap;align-items:baseline;
  justify-content:space-between;gap:10px 24px;
  padding-bottom:20px;margin-bottom:clamp(22px,4vh,40px);
  border-bottom:1px solid var(--line);
}
.section__title{
  margin:0;font-family:var(--font-display);font-weight:400;
  text-transform:uppercase;line-height:.92;letter-spacing:-.005em;
  font-size:clamp(28px,4.4vw,58px);
}
.section__hint{
  margin:0;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--grey-dim);
}

/* ---------- Rollen der Sektionen ----------
   Die Startseite hat drei Aufgaben, und sie sind nicht gleich viel wert:
   zuerst hoerbar machen, dann erklaeren, dann ansprechbar sein. Vorher trugen
   alle drei dieselbe Klasse und damit dasselbe Gewicht — die Musik stand als
   vierter Block hinter rund 450 Woertern, obwohl der Hero „direkt, ohne
   Umweg" verspricht. Die Reihenfolge im Markup ist jetzt Hero, Musik, Text,
   Anfrage; hier bekommt jede Rolle den Abstand, der ihr zusteht. */

/* Fuehrend: haengt am Hero, beide lesen als ein Moment. Deshalb oben eng,
   unten weit — der Bruch kommt nach der Musik, nicht vor ihr. Zwischen Hero
   und Titel lagen vorher drei Linien kurz hintereinander; die mittlere faellt. */
.section--fuehrend{padding-block:var(--takt-mittel) var(--takt-weit)}
.section--fuehrend .section__head{
  border-bottom:0;padding-bottom:0;margin-bottom:var(--takt-eng);
}
.section--fuehrend .section__title{font-size:clamp(32px,5.2vw,68px)}

/* Lesen und Handeln: davor darf der Blick anhalten. */
.section--lesen,.section--handeln{padding-block:var(--takt-weit)}

/* Der Fliesstext misst 66ch, das Formular 620px — eine 1400px breite
   Ueberschriftenlinie zeigte darueber ins Leere. Kopf und Inhalt teilen
   sich jetzt dieselbe Spalte. */
.wrap--lesen{max-width:74ch}

/* ---------- Lesetext: ruhig und offen ---------- */

.prose{max-width:66ch}
.prose p{margin:0 0 1.05em;font-size:clamp(17px,1.2vw,19px);line-height:1.62}
.prose p:first-child{
  font-size:clamp(20px,1.9vw,27px);line-height:1.38;margin-bottom:.85em;
  color:var(--white);
}
.prose p:last-child{margin-bottom:0}

.disclaimer{
  margin:clamp(24px,4vh,40px) 0;
  padding:clamp(18px,2.6vw,28px);
  background:var(--black-2);
  border:1px solid var(--line);
  border-left:2px solid var(--cyan);
  max-width:66ch;
}
.disclaimer__label{
  display:block;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--cyan);
  margin-bottom:12px;
}
.disclaimer p{
  margin:0 0 .9em;font-family:var(--font-mono);
  font-size:14px;line-height:1.75;color:var(--grey);
}
.disclaimer p:last-child{margin-bottom:0}

.statement{
  margin-top:clamp(32px,5vh,60px);padding-top:clamp(22px,4vh,40px);
  border-top:1px solid var(--line);
}
.statement blockquote{
  margin:0;font-family:var(--font-display);font-weight:400;
  line-height:1.12;
  font-size:clamp(22px,3.4vw,48px);max-width:24ch;
}
.statement blockquote em{font-style:normal;color:var(--cyan)}

/* ---------- Cover-Platzhalter ---------- */

.cover{
  position:relative;aspect-ratio:1/1;flex:none;
  background:var(--black-2);border:1px solid var(--line);overflow:hidden;
}
.cover::before{
  content:"";position:absolute;inset:0;
  background-image:var(--tex-cover);
  background-size:280% auto;
  filter:grayscale(.7) contrast(1.4) brightness(.85);
  opacity:.8;
}
.cover__mark{
  position:absolute;inset:0;display:flex;align-items:flex-end;
  padding:8%;font-family:var(--font-display);
  font-size:clamp(20px,3vw,44px);line-height:.8;
  text-transform:uppercase;color:var(--white);
  mix-blend-mode:difference;letter-spacing:-.02em;
}
.cover--a::before{background-position:14% 22%}
.cover--b::before{background-position:66% 42%}
.cover--c::before{background-position:34% 76%}
.cover--d::before{background-position:86% 16%}
.cover--e::before{background-position:8% 58%}
.cover--f::before{background-position:50% 10%}
.cover--g::before{background-position:74% 86%}
/* Der cyanfarbene Querbalken auf den Kacheln ist auf Wunsch des Betreibers
   ersatzlos entfernt (2026-09-08). Er stammte aus dem Entwurf V3 und sass je
   Kachelvariante auf einer anderen Hoehe (40 bis 70 Prozent); bei echten
   Bildern lag er ueber dem Artwork, auf leeren Kacheln quer ueber der
   Betonflaeche. Weil er absolut positioniert war, aendert sein Wegfall am
   Layout der Karten und Listenzeilen nichts — die Kachel behaelt Groesse,
   Rahmen und Seitenverhaeltnis.
   Der Akzent lebt weiter, wo er Bedeutung traegt: laufender Track, Zaehlwert,
   aktive Karte, Waveform. */

/* Die Beton-Textur bleibt der leeren Kachel vorbehalten. Hinter einem echten
   Bild ist sie unsichtbar und kostet nur eine Malschicht. */
.cover.has-bild::before{display:none}

/* ---------- Vorstellung: drei Karten ---------- */

/* auto-fill statt drei festen Spalten: bei zwei Tracks im Deck zogen sich
   zwei Karten ueber 1400px auseinander und die Kachel stand allein in einer
   Wueste aus leerem Kasten. Jetzt behalten die Karten ihr Mass, und die
   Reihe fuellt sich erst, wenn der Katalog dafuer da ist. */
.top3{
  display:grid;gap:clamp(14px,2vw,22px);
  grid-template-columns:repeat(auto-fill,minmax(min(320px,100%),1fr));
}
.top3__card{
  display:flex;gap:14px;align-items:center;
  background:var(--black-2);border:1px solid var(--line);
  padding:14px;text-align:left;
  transition:border-color .12s linear,background .12s linear;
}
@media (hover:hover){.top3__card:hover{background:var(--black-3)}}
.top3__card.is-active{border-color:var(--cyan)}
.top3__cover{width:76px}
.top3__body{min-width:0;flex:1}
.top3__rank{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;
  color:var(--grey-dim);display:block;margin-bottom:4px;
}
.top3__card.is-active .top3__rank{color:var(--cyan)}
.top3__title{
  margin:0 0 4px;font-family:var(--font-display);font-weight:400;
  text-transform:uppercase;line-height:1.3;
  font-size:clamp(19px,1.9vw,26px);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.top3__artist{
  margin:0 0 6px;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.top3__clicks{
  font-family:var(--font-mono);font-size:12px;
  font-variant-numeric:tabular-nums;color:var(--cyan);
}

/* ---------- Play-Schalter ---------- */

.play{
  --sz:44px;width:var(--sz);height:var(--sz);flex:none;
  display:grid;place-items:center;padding:0;
  background:transparent;border:1px solid var(--rand);
  color:var(--white);cursor:pointer;
  transition:background .12s linear,border-color .12s linear,color .12s linear;
}
.play:hover,.play:focus-visible{border-color:var(--cyan);color:var(--cyan)}
.play[aria-pressed="true"]{background:var(--cyan);border-color:var(--cyan);color:var(--black)}
.play__glyph{
  width:0;height:0;
  border-left:10px solid currentColor;
  border-top:6.5px solid transparent;
  border-bottom:6.5px solid transparent;
  margin-left:3px;
}
.play[aria-pressed="true"] .play__glyph{
  width:10px;height:12px;margin-left:0;border:0;
  background:linear-gradient(to right,currentColor 0 34%,transparent 34% 66%,currentColor 66% 100%);
}

/* ---------- Tracklist ---------- */

.tracks-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.tracks{
  width:100%;min-width:620px;border-collapse:collapse;
  font-variant-numeric:tabular-nums;
}
.tracks caption{
  text-align:left;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--grey-dim);
  padding-bottom:12px;
  /* Ohne Begrenzung lief dieser Satz auf dem Rechner ueber die volle
     Tabellenbreite: bei 1440 Pixeln rund 150 Zeichen in einer Zeile, also
     das Doppelte dessen, was das Auge am Zeilenende noch zurueckfindet.
     Auf dem Telefon aendert die Grenze nichts — dort ist die Spalte
     ohnehin schmaler, und der Block bleibt wie verlangt randbuendig. */
  max-width:72ch;
}
.tracks th{
  text-align:left;font-family:var(--font-mono);font-weight:400;
  font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--grey-dim);padding:0 12px 10px 0;
  border-bottom:1px solid var(--line);white-space:nowrap;
}
.tracks th.num{text-align:right;padding-right:0}
/* Sortierrichtung sichtbar markiert */
.tracks th.is-sorted{color:var(--cyan)}
.tracks th.is-sorted::after{content:" ↓"}
.tracks td{
  padding:0 12px 0 0;border-bottom:1px solid var(--line);
  vertical-align:middle;height:62px;
}
.tracks tbody tr{transition:background .1s linear}
.tracks--reflow tbody tr:has(.play:not([disabled])){cursor:pointer}
@media (hover:hover){.tracks tbody tr:hover{background:var(--black-2)}}

/* Auf dem Telefon gibt es kein Hover — und damit fehlte dort jeder Hinweis
   darauf, dass die ganze Zeile ausloest und nicht nur der Knopf am Rand. Den
   Platz des Zeigers nimmt hier der Druck ein: solange der Finger liegt, faerbt
   sich die Zeile und die Rangziffer tauscht gegen das Abspielzeichen. Die
   Rueckmeldung kommt also im selben Moment, in dem sie gebraucht wird.
   Ergaenzt in app.js um einen leeren touchstart-Horcher — ohne den schickt
   iOS an eine Tabellenzeile gar kein :active. */
@media (hover:none){
  .tracks tbody tr:has(.play:not([disabled])):active{background:var(--black-2)}
  .tracks tbody tr:has(.play:not([disabled])):not(.is-current):active .track__nr{opacity:0}
  .tracks tbody tr:has(.play:not([disabled])):not(.is-current):active .track__rank::after{opacity:1}
  .top3__card:active{background:var(--black-3)}
}
.tracks tbody tr.is-current{background:var(--black-3)}
.tracks tbody tr.is-current .track__title{color:var(--cyan)}

.track__rank{
  width:52px;font-family:var(--font-mono);font-size:12px;color:var(--grey-dim);
  position:relative;
}
.tracks tbody tr.is-current .track__rank{color:var(--cyan)}

/* Die Rangnummer ist der Ausloeser.
   Beim Zeigen oder Fokussieren tauscht die Ziffer gegen das Abspielzeichen —
   gleiche Box, gleiche Breite, nichts springt. Dass die ganze Zeile ausloest,
   hat bisher nur der Mauszeiger behauptet und auf dem Handy niemand erfahren.
   Nicht auf der laufenden Zeile: dort saehe ein Abspielzeichen aus, als waere
   nichts an. */
.track__nr{transition:opacity .12s linear}
.track__rank::after{
  content:"";position:absolute;top:50%;left:0;
  width:0;height:0;margin-top:-6px;
  border-left:9px solid var(--cyan);
  border-top:6px solid transparent;
  border-bottom:6px solid transparent;
  opacity:0;transition:opacity .12s linear;
  pointer-events:none;
}
.tracks tbody tr:has(.play:not([disabled])):not(.is-current):focus-within .track__nr{opacity:0}
.tracks tbody tr:has(.play:not([disabled])):not(.is-current):focus-within .track__rank::after{opacity:1}
@media (hover:hover){
  .tracks tbody tr:has(.play:not([disabled])):not(.is-current):hover .track__nr{opacity:0}
  .tracks tbody tr:has(.play:not([disabled])):not(.is-current):hover .track__rank::after{opacity:1}
}
.track{display:flex;align-items:center;gap:14px;min-width:0}
.track__cover{width:44px;height:44px}
.track__cover .cover__mark{font-size:16px;padding:6%}
.track__title{
  font-family:var(--font-display);font-size:clamp(17px,1.5vw,22px);
  line-height:1.3;text-transform:uppercase;white-space:nowrap;
}
.track__artist,.track__len{
  font-family:var(--font-mono);font-size:12px;color:var(--grey);white-space:nowrap;
}
.track__clicks{
  font-family:var(--font-mono);font-size:12.5px;color:var(--cyan);
  white-space:nowrap;text-align:right;
}
.track__act{width:56px;text-align:right}
.track__act .play{margin-left:auto}
/* Laufender Track: kleiner Pegel-Indikator statt Icon */
.track__eq{
  display:inline-flex;align-items:flex-end;gap:2px;height:12px;
  margin-right:8px;vertical-align:-1px;
}
.track__eq i{
  width:2px;background:var(--cyan);height:4px;
  animation:eq .9s ease-in-out infinite;
}
.track__eq i:nth-child(2){animation-delay:.15s}
.track__eq i:nth-child(3){animation-delay:.3s}
@keyframes eq{
  0%,100%{height:3px}
  50%{height:12px}
}
.is-paused .track__eq i{animation-play-state:paused}


/* ---------- Interpreten ---------- */

.artists{display:grid;grid-template-columns:1fr;gap:clamp(16px,2.4vw,28px)}
@media (min-width:720px){.artists{grid-template-columns:1fr 1fr}}
.artists__item{
  background:var(--black-2);border:1px solid var(--line);padding:16px;
  display:flex;gap:16px;align-items:center;
}
.artists__portrait{width:clamp(90px,16vw,130px);aspect-ratio:4/5}
.artists__portrait .cover__mark{
  align-items:center;justify-content:center;font-size:clamp(34px,5vw,58px);
}
.artists__name{
  margin:0 0 6px;font-family:var(--font-display);font-weight:400;
  text-transform:uppercase;line-height:.95;font-size:clamp(24px,3vw,40px);
}
.artists__meta{
  margin:0 0 10px;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--grey);
}

.note{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.04em;
  color:var(--grey-dim);margin-top:var(--s-4);line-height:1.7;
}
/* Ohne diese Regel setzte der Browser sein Standardblau: 2,11:1 unbesucht,
   1,80:1 besucht — und die einzige zweite Farbe auf einer Seite, die sich auf
   genau einen Akzent festgelegt hat. */
.note a{color:var(--cyan);text-decoration-thickness:1px;text-underline-offset:3px}

/* ---------- Anfrage ---------- */

.form{max-width:620px}
.field{margin-bottom:clamp(16px,2.6vh,24px)}
.field label{
  display:block;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--grey-dim);
  margin-bottom:7px;
}
.field input,.field select,.field textarea{
  width:100%;background:var(--black-2);border:1px solid var(--rand);
  border-radius:0;color:var(--white);font-family:var(--font-body);
  font-size:clamp(16px,1.3vw,19px);padding:11px 13px;
  transition:border-color .12s linear;
}
.field select{
  font-family:var(--font-mono);
  /* Nicht kleiner: iOS Safari zoomt beim Fokussieren jedes Feld unter 16px
     und reisst damit das Formularlayout auseinander. */
  font-size:16px;
  appearance:none;-webkit-appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--grey) 50%),
                   linear-gradient(135deg,var(--grey) 50%,transparent 50%);
  background-position:calc(100% - 17px) 20px,calc(100% - 12px) 20px;
  background-size:5px 5px;background-repeat:no-repeat;padding-right:34px;
}
.field select option{background:var(--black-2);color:var(--white)}
.field textarea{resize:vertical;min-height:120px;line-height:1.5}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--cyan);
}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--cyan);outline-offset:2px;
}
.field input::placeholder,.field textarea::placeholder{color:var(--grey-dim)}

/* Bleibender Hinweis am Feld. Ein Platzhalter kann das nicht leisten: er ist
   ein Beispiel, keine Anforderung, und verschwindet beim ersten Zeichen —
   also genau dann, wenn die Anforderung gebraucht wird. Steht ueber dem Feld,
   weil eine Anforderung vor dem Ausfuellen kommt, nicht danach. */
.field__hint{
  margin:0 0 8px;font-family:var(--font-body);font-size:15px;line-height:1.45;
  color:var(--grey);max-width:60ch;overflow-wrap:break-word;
}

/* Die Auswahl steht offen statt in einer Liste: alle Moeglichkeiten sind
   gleichzeitig sichtbar, die Wahl kostet einen Griff statt zwei, und auf dem
   Telefon oeffnet sich kein Systemrad. Das <fieldset> braucht den Reset, sonst
   setzt der Browser Rahmen und Innenabstand dazu. */
.feld--wahl{border:0;padding:0;margin:0 0 clamp(16px,2.6vh,24px);min-width:0}
.feld--wahl legend{
  padding:0;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--grey-dim);
  margin-bottom:9px;
}
.wahl{display:flex;flex-wrap:wrap;gap:8px}
.wahl__opt{position:relative;display:inline-flex;cursor:pointer}
/* Der Knopf bleibt im Dokument — er traegt Rolle, Name und Zustand fuer die
   Hilfstechnik. Sichtbar ist nur die Flaeche daneben. Bewusst ueber den
   Geschwister-Wahlschalter gestylt und nicht ueber :has(), damit auch aeltere
   Browser den gewaehlten Zustand zeigen. */
.wahl__opt input{position:absolute;opacity:0;width:1px;height:1px;margin:0}
.wahl__opt span{
  display:inline-flex;align-items:center;min-height:44px;padding:0 14px;
  border:1px solid var(--rand);background:var(--black-2);
  font-family:var(--font-mono);font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--grey);
  transition:border-color .12s linear,color .12s linear,background .12s linear;
}
.wahl__opt input:checked + span{
  background:var(--cyan);border-color:var(--cyan);color:var(--black);
}
.wahl__opt input:focus-visible + span{outline:2px solid var(--cyan);outline-offset:2px}
@media (hover:hover){
  .wahl__opt:hover input:not(:checked) + span{color:var(--white);border-color:var(--grey-dim)}
}

/* Freiwillige Felder sagen das selbst. Sonst raet man, und im Zweifel laesst
   man das Feld aus — gerade das mit dem Link zur Musik. */
.field__opt{
  font-size:10px;letter-spacing:.12em;color:var(--grey-dim);
  border:1px solid var(--line);padding:1px 5px;margin-left:6px;
}

/* Was nach dem Absenden passiert. Steht ueber dem Knopf, weil die Antwort auf
   "was passiert dann?" vor dem Druck gebraucht wird und nicht danach. */
.danach{
  margin:0 0 clamp(16px,2.4vh,22px);padding:13px 15px;
  background:var(--black-2);border-left:2px solid var(--rand);
  font-family:var(--font-body);font-size:15px;line-height:1.5;
  color:var(--grey);max-width:62ch;
}
.danach b{color:var(--white);font-weight:400}

.consent{display:flex;gap:11px;align-items:flex-start;margin-bottom:clamp(20px,3vh,28px)}
.consent input{
  appearance:none;-webkit-appearance:none;width:24px;height:24px;flex:none;
  margin-top:1px;border:1px solid var(--rand);background:transparent;
  cursor:pointer;border-radius:0;
}
.consent input:checked{background:var(--cyan);border-color:var(--cyan)}
.consent label{
  font-family:var(--font-mono);font-size:12px;line-height:1.65;
  color:var(--grey);cursor:pointer;
}
.submit{
  font-family:var(--font-display);font-size:clamp(17px,1.6vw,22px);
  letter-spacing:.04em;text-transform:uppercase;
  background:var(--white);color:var(--black);border:0;
  padding:14px 36px;cursor:pointer;transition:background .1s linear;
}
.submit:hover,.submit:focus-visible{background:var(--cyan)}
/* Steht ueber dem Formular, damit die Rueckmeldung nach dem Absenden
   im Blick ist statt zweitausend Pixel darunter. */
.formstate{
  margin:0 0 26px;padding:16px 20px;
  border:1px solid var(--cyan);background:var(--black-2);
  font-family:var(--font-mono);font-size:12.5px;line-height:1.7;color:var(--white);
}
.formstate b{color:var(--cyan);font-weight:400}
.formstate:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
.formstate.is-fehler{border-color:var(--warn)}
.formstate.is-fehler b{color:var(--warn)}

/* ---------- Fusszeile ---------- */

/* Die Fusszeile nahm auf dem Telefon 308 Pixel ein — 42 Prozent des
   Bildschirms — und am Rechner 205. Gekuerzt wurde ueber die Abstaende,
   nicht ueber die Schrift: unter 11 Pixel geht Funktionstext hier nicht. */
.foot{padding-block:clamp(20px,3vh,34px)}
.foot__grid{
  display:flex;flex-wrap:wrap;gap:8px 28px;
  align-items:center;justify-content:space-between;
}
.foot__links{display:flex;flex-wrap:wrap;gap:4px 22px;align-items:center}
.foot__link{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey);
  background:none;border:0;
  display:inline-flex;align-items:center;min-height:44px;
  /* Die Linie lag als Schatten am unteren Rand des Kastens — bei 44 Pixeln
     Trefferflaeche also gut einen Zentimeter unter dem Wort, zu dem sie
     gehoert. Als Unterstreichung haengt sie am Text, unabhaengig davon, wie
     hoch der Kasten fuer den Finger sein muss. */
  text-decoration:underline;
  text-decoration-color:var(--rand);
  text-underline-offset:4px;
  padding:0;cursor:pointer;
}
.foot__link:hover,.foot__link:focus-visible{color:var(--cyan);text-decoration-color:var(--cyan)}

/* Die 44 Pixel sind eine Regel fuer den Finger. Wo mit Maus oder Stift gezeigt
   wird, treffen 30 Pixel genauso sicher — WCAG 2.5.8 verlangt 24 — und die
   Fusszeile verliert damit drei aufgeblasene Zeilen. Auf Tastgeraeten bleibt
   es bei 44. Nebenbei rueckt die Unterstreichung des Links wieder an den
   Text heran, statt am Boden eines zu hohen Kastens zu liegen. */
@media (hover:hover) and (pointer:fine){
  .foot__link,.foot__plattform a{min-height:30px}
}

/* ============================================================
   Player-Leiste — das Herzstueck. Fix am unteren Rand,
   ueberlebt jeden Ansichtswechsel.
   ============================================================ */

.player{
  position:fixed;left:0;right:0;bottom:0;z-index:45;
  /* Unter der Leiste liegt auf neueren Telefonen der Home-Indikator. Ohne
     diesen Zuschlag sitzt die Wiedergabesteuerung genau darunter. */
  height:calc(var(--bar-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom:env(safe-area-inset-bottom, 0px);
  background:rgba(13,13,13,.97);
  backdrop-filter:blur(8px);
  border-top:1px solid var(--line);
}
.player__inner{
  height:100%;
  display:grid;
  grid-template-columns:1fr;
  align-items:center;
  gap:14px;
}
@media (min-width:900px){
  /* Dritte Spalte breiter: dort steht jetzt neben Lautstaerke auch der
     Weiter-Schalter. Die Waveform gibt die Breite ab, sie skaliert ohnehin. */
  /* Die linke Spalte war auf 240px gedeckelt und damit auf dem grossen
     Schirm SCHMALER als auf dem kleinen, wo sie sich am Inhalt orientiert
     (298px bei 768). Der Interpretenname brauchte 242px, bekam 176 und
     wurde gekuerzt, obwohl daneben Platz frei stand. Der Deckel steigt
     deshalb; die Waveform in der Mitte gibt die Breite ab, sie skaliert. */
  .player__inner{grid-template-columns:minmax(190px,340px) 1fr minmax(180px,244px)}
}

/* linke Spalte: Was laeuft */
.player__now{display:flex;align-items:center;gap:12px;min-width:0}
.player__cover{
  width:52px;height:52px;
  /* Die Initiale in der Kachel mischt mit `mix-blend-mode:difference`. Ohne
     eigenen Stapelkontext mischt sie nicht nur mit der Kachel, sondern mit
     allem dahinter — hier also mit der fixierten Player-Leiste selbst. Das
     zwingt die ganze Leiste in eine gemischte Schicht, und auf Android blieb
     dann die Flaeche eines Kindes unvollstaendig gefuellt: gemeldet am
     Weiter-Schalter, dessen Cyan nur einen Teil des Knopfes bedeckte.
     `isolation` sperrt die Mischung in die Kachel, wo sie hingehoert.
     Bewusst nur hier und nicht an `.cover` allgemein: seitenweit gesetzt
     wechselt der Browser die Kantenglaettung des gesamten Fliesstextes von
     Graustufen auf Subpixel, und das ist eine Aenderung am Schriftbild,
     die dieser Fehler nicht verlangt. */
  isolation:isolate;
}
.player__cover .cover__mark{font-size:18px;padding:6%}
.player__txt{min-width:0}
/* Anton setzt die Umlautpunkte weit ueber die Versalhoehe: gemessen liegt der
   Scheitel von Ä bei 1,053 em ueber der Grundlinie, waehrend A bei 0,859 em
   endet. Bei line-height:1 reicht die Zeilenbox nur bis 0,924 em — die Punkte
   liegen ausserhalb und werden von overflow:hidden abgeschnitten, aus
   "GEWÄHLT" wurde "GEWAHLT". Noetig sind rechnerisch 1,26; 1,3 laesst etwas
   Luft. Die Zeilen bleiben trotzdem in ihren Kaesten: in der Leiste stehen
   84 px zur Verfuegung, in der Songliste gibt das 44-px-Cover die Hoehe vor. */
.player__title{
  margin:0;font-family:var(--font-display);font-weight:400;
  text-transform:uppercase;line-height:1.3;font-size:clamp(16px,1.5vw,20px);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.player__artist{
  margin:3px 0 0;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grey);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.player.is-empty .player__title{color:var(--grey-dim)}

/* Mitte: Transport + Waveform */
.player__mid{display:flex;align-items:center;gap:12px;min-width:0}
.player__wave{
  flex:1;min-width:0;
  display:flex;align-items:center;gap:10px;
}
.player__time{
  font-family:var(--font-mono);font-size:11px;
  font-variant-numeric:tabular-nums;color:var(--grey);
  white-space:nowrap;
}
/* Der leere Player erklaert sich statt leer zu bleiben. Der Hinweis ersetzt
   die Waveform, solange keine da ist, und verschwindet mit dem ersten Track. */
.player__leer{
  display:none;margin:0;min-width:0;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.08em;
  color:var(--grey-dim);line-height:1.4;
}
.player.is-empty .player__wave{display:none}
@media (min-width:560px){.player.is-empty .player__leer{display:block}}

/* Laden und Fehlschlag treten an die Stelle des Sprungbalkens — solange nichts
   spielbar ist, zeigt der Balken ohnehin nichts Wahres an. */
.player__status{
  display:none;margin:0;min-width:0;
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.06em;
  line-height:1.4;color:var(--grey);
  overflow-wrap:anywhere;
}
.player.is-laedt .player__wave,
.player.is-hinweis .player__wave,
.player.is-fehler .player__wave{display:none}
.player.is-laedt .player__status,
.player.is-hinweis .player__status,
.player.is-fehler .player__status{display:block}
.player.is-fehler .player__status{color:var(--warn-text)}
/* Der Ladepunkt pulst nur, wenn Bewegung erwuenscht ist. */
.player.is-laedt .player__status::before{
  content:"";display:inline-block;width:6px;height:6px;margin-right:8px;
  background:var(--cyan);vertical-align:1px;
  animation:laden 1.1s ease-in-out infinite;
}
@keyframes laden{0%,100%{opacity:.25}50%{opacity:1}}

/* Der Balken ist ein Button: Klicken springt an die Position */
.wavebtn{
  flex:1;min-width:0;height:46px;
  background:transparent;border:0;padding:0;cursor:pointer;
  touch-action:none;
  display:block;
}
.wavebtn canvas{display:block;width:100%;height:46px}
.wavebtn:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}

/* rechte Spalte: Lautstaerke */
.player__vol{display:flex;align-items:center;gap:10px;justify-content:flex-end}

/* Der Weiter-Schalter. Spricht dieselbe Sprache wie der Ansichtswechsel im
   Kopf — Mono, Rahmen, gefuellt wenn aktiv —, damit die Seite nur ein
   Schaltermuster hat und nicht zwei. Volle 44 Pixel Trefferflaeche wie jedes
   andere Bedienelement hier; die Leiste ist 84 hoch, der Platz ist da. */
.weiter{
  flex:none;font-family:var(--font-mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;
  background:transparent;border:1px solid var(--rand);color:var(--grey);
  display:inline-flex;align-items:center;min-height:44px;padding:0 11px;
  cursor:pointer;
  transition:background .12s linear,color .12s linear,border-color .12s linear;
}
.weiter:hover{color:var(--white);border-color:var(--white)}
.weiter[aria-pressed="true"]{background:var(--cyan);border-color:var(--cyan);color:var(--black)}
.weiter[aria-pressed="true"]:hover{border-color:var(--cyan)}
.player__vol span{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--grey-dim);white-space:nowrap;
}
.player__vol input{
  -webkit-appearance:none;appearance:none;
  /* Die Bahn bleibt 2 Pixel duenn, die Trefferflaeche wird 24 — das Bild
     traegt der Track, nicht die Box. WCAG 2.5.8 verlangt 24x24. */
  width:clamp(70px,10vw,120px);height:24px;background:transparent;
  cursor:pointer;
}
.player__vol input::-webkit-slider-runnable-track{height:2px;background:var(--line)}
.player__vol input::-moz-range-track{height:2px;background:var(--line)}
.player__vol input::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;
  width:12px;height:12px;background:var(--cyan);border:0;border-radius:0;
  margin-top:-5px;                 /* mittig auf der 2px-Bahn */
}
.player__vol input::-moz-range-thumb{
  width:12px;height:12px;background:var(--cyan);border:0;border-radius:0;
}
.player__vol input:focus-visible{outline:2px solid var(--cyan);outline-offset:4px}

/* Mobil: kompakte Leiste. Die Lautstaerke entfaellt — das regelt das Geraet —,
   der Weiter-Schalter aber nicht: unterwegs ist er am wichtigsten, und dort
   fehlte er bisher ganz. Die dritte Spalte traegt deshalb nur noch ihn. */
/* Drei Schichten liegen dauerhaft ueber jedem Bildlauf: das Korn als
   bildschirmfuellende Flaeche mit mix-blend-mode und zweimal backdrop-filter
   an Kopf- und Player-Leiste. Auf dem Rechner ist das folgenlos, auf einem
   schwachen Telefon kostet jede davon Bildrate — und zwar staendig, nicht nur
   einmal. Auf kleinen Geraeten weichen sie deshalb undurchsichtigen Flaechen;
   sichtbar ist der Unterschied dort ohnehin kaum. */
@media (max-width:899px){
  body::after{display:none}
  /* Die Farbe bleibt exakt dieselbe, nur die Alpha-Stufe faellt weg:
     rgba(10,10,10,.985) ist #0a0a0a, rgba(13,13,13,.99) ist #0d0d0d.
     Der Unterschied ist unsichtbar, die Wirkung nicht. Eine fixierte
     Ebene mit *fast* undurchsichtigem Grund muss der Compositor bei
     jedem Bildlauf gegen die Seite darunter verrechnen; auf Android
     malt er dabei sichtbar in Kacheln, und ein Kind der Leiste kann
     dann teilweise ungefuellt stehenbleiben — gemeldet am
     Weiter-Schalter, dessen Cyan nur einen Teil der Flaeche fuellte.
     Undurchsichtig faellt das Verrechnen ganz weg. */
  .top{backdrop-filter:none;background:#0a0a0a}
  .player{backdrop-filter:none;background:#0d0d0d}
}

@media (max-width:899px){
  :root{--bar-h:76px}
  .player__vol span,.player__vol input{display:none}
  /* Die mittlere Spalte trug `auto 1fr auto` und durfte damit auf 0 fallen:
     `.player__mid` hat `min-width:0`, also ist die automatische Mindestbreite
     der fr-Spalte null, und die linke Spalte nahm sich ihre volle
     Inhaltsbreite (gemessen 269 von 328 Pixeln bei 390 px Bildbreite). Der
     44 Pixel breite Abspielknopf quoll daraufhin aus der leeren Spalte und
     lag UEBER dem Weiter-Schalter — er ueberlappte ihn um 34 Pixel. Das sah
     aus wie ein Knopf, dessen Cyan nur halb gefuellt ist, und war in
     Wahrheit ein zweiter Knopf davor. Zugleich war der Abspielknopf auf dem
     Telefon damit praktisch unbenutzbar.
     Jetzt bekommt die Mitte einen Boden in Hoehe des Knopfes, und die
     Textspalte gibt nach — kuerzen kann sie ohnehin, Titel und Interpret
     tragen seit jeher Auslassungspunkte. */
  .player__inner{grid-template-columns:minmax(0,auto) minmax(44px,1fr) auto;gap:10px}
  .weiter{font-size:9px;letter-spacing:.1em;padding:0 9px}
  .player__cover{width:44px;height:44px}
  .player__wave{gap:8px}
  .wavebtn,.wavebtn canvas{height:34px}
  .player__time--total{display:none}
}

/* Sehr schmal: auch die laufende Zeit weicht. Sie steht ohnehin im
   Sprungbalken, und der Platz gehoert dem Balken selbst. */
@media (max-width:419px){
  .player__time{display:none}
  .player__now{gap:9px}
}

/* Querformat auf dem Telefon: rund 390 Pixel Hoehe insgesamt. Eine 76 Pixel
   hohe Leiste plus 60 Pixel Kopf frisst davon ein Drittel, bevor eine Zeile
   Inhalt zu sehen ist. Das Cover ist hier das Erste, was gehen kann. */
@media (max-height:480px) and (orientation:landscape){
  :root{--bar-h:58px}
  .player__cover{display:none}
  .wavebtn,.wavebtn canvas{height:26px}
  .top{position:static}
}

/* ---------- Overlays ---------- */

.overlay[hidden]{display:none}
.overlay{
  position:fixed;inset:0;z-index:80;
  background:rgba(6,6,6,.94);
  display:grid;place-items:start center;overflow-y:auto;
  padding:clamp(16px,5vh,60px) var(--gutter);
}
.overlay__panel{
  width:min(700px,100%);background:var(--black);
  border:1px solid var(--line);padding:clamp(22px,4vw,42px);
}
.overlay__head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:20px;
  padding-bottom:18px;margin-bottom:20px;border-bottom:1px solid var(--line);
}
.overlay__title{
  margin:0;font-family:var(--font-display);font-weight:400;
  text-transform:uppercase;font-size:clamp(24px,3.4vw,40px);line-height:.95;
}
.overlay__close{
  flex:none;font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--grey);background:transparent;
  border:1px solid var(--rand);
  display:inline-flex;align-items:center;min-height:44px;padding:0 16px;cursor:pointer;
}
.overlay__close:hover,.overlay__close:focus-visible{color:var(--cyan);border-color:var(--cyan)}
.overlay__body{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;color:var(--grey)}
.overlay__body strong{color:var(--white);font-weight:400}
.overlay__body a{color:var(--cyan)}

/* ---------- Rechtstexte ----------
   Deutlich laenger als alles andere auf der Seite, deshalb eigener Satz:
   Fliesstext statt Mono, Abschnitte als Mono-Marken mit Cyan-Nummer. */

.legal{font-family:var(--font-body);font-size:15.5px;line-height:1.62;color:var(--grey)}
.legal h3{
  margin:26px 0 8px;
  font-family:var(--font-mono);font-weight:700;
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--white);
}
.legal h3:first-child{margin-top:0}
.legal h3 b{color:var(--cyan);font-weight:700;margin-right:.7em}
.legal p{margin:0 0 10px}
.legal ul{margin:0 0 12px;padding-left:17px}
.legal li{margin-bottom:2px}
.legal address{font-style:normal;color:var(--white);margin:0 0 12px}
.legal .stand{
  margin-top:26px;padding-top:14px;border-top:1px solid var(--line);
  font-family:var(--font-mono);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grey);
}


/* ---------- Bewegung nur, wenn erwuenscht ----------
   Die Waveform friert ein, der Fortschritt bleibt korrekt. */

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  /* Ausnahme: der Pegel ist keine Zierde. Er ist die einzige Stelle, an der
     die Songliste zeigt, welcher Track gerade laeuft. Ohne Bewegung bleibt er
     als gestaffelte Balkengruppe stehen und sagt dasselbe; pausiert faellt er
     flach zusammen. */
  .track__eq i{height:12px}
  .track__eq i:nth-child(2){height:7px}
  .track__eq i:nth-child(3){height:10px}
  .is-paused .track__eq i{height:3px}
}

/* ============================================================
   Ergänzungen für die echte Seite
   Alles darüber stammt unverändert aus der freigegebenen
   Richtung V3. Hier kommt nur dazu, was der Entwurf noch
   nicht brauchte: echte Bilder, Leerzustände, Verwaltung.
   ============================================================ */

/* ---------- Echte Cover und Porträts ---------- */

.cover__bild{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  /* Bilder kommen vom Label in unterschiedlicher Qualität —
     die Entsättigung hält sie im Look der Seite zusammen. */
  filter:grayscale(.35) contrast(1.12);
}
.cover.has-bild .cover__mark{display:none}

/* ---------- Leerzustände ---------- */

.leer{
  margin:0;padding:22px 24px;
  border:1px dashed var(--line);border-left:2px solid var(--cyan);
  font-family:var(--font-body);font-size:17px;line-height:1.5;color:var(--grey);
  max-width:62ch;
}
.leer a{color:var(--cyan)}

/* ---------- Plattform-Links (nur extern, nie eingebettet) ---------- */

.plattform{
  display:flex;gap:14px;margin:8px 0 0;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
}
.plattform a{
  color:var(--grey);
  /* Die Unterkante lag als border am Kasten — der darf hier aber auf 44 Pixel
     wachsen, und die Linie waere mitgewandert. Als Unterstreichung haengt sie
     am Text und bleibt, wo sie hingehoert. */
  text-decoration:underline;
  text-decoration-color:var(--line);
  text-underline-offset:4px;
  display:inline-flex;align-items:center;min-height:44px;
}
.plattform a:hover,.plattform a:focus-visible{color:var(--cyan);text-decoration-color:var(--cyan)}

.inline-link{
  background:none;border:0;padding:0;
  font:inherit;color:var(--cyan);text-decoration:underline;cursor:pointer;
}

/* ---------- Schmale Spalte für Formularseiten ---------- */

.wrap--schmal{max-width:640px}

/* ============================================================
   Verwaltung
   Ein Werkzeug, keine Lesestrecke: Zustand muss auf einen Blick
   erkennbar sein, deshalb Statuswörter statt bloßer Farbe.
   ============================================================ */

.akopf{display:flex;flex-wrap:wrap;gap:12px;align-items:center}

.abtn{
  display:inline-flex;align-items:center;min-height:44px;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--white);background:transparent;
  border:1px solid var(--rand);padding:0 16px;
  text-decoration:none;cursor:pointer;
}
.abtn:hover,.abtn:focus-visible{border-color:var(--cyan);color:var(--cyan)}
.abtn--stark{border-color:var(--cyan);color:var(--cyan)}
.abtn--stark:hover,.abtn--stark:focus-visible{background:var(--cyan);color:var(--black)}
.abtn--warn:hover,.abtn--warn:focus-visible{border-color:var(--warn);color:var(--warn)}

.ainline{display:inline}

.aform{max-width:none}
.afeld{display:flex;flex-direction:column;gap:7px;margin-bottom:22px}
.afeld label{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--grey);
}
.afeld input[type=text],
.afeld input[type=url],
.afeld input[type=password],
.afeld input[type=number]{
  font-family:var(--font-body);font-size:18px;color:var(--white);
  background:var(--black-2);border:1px solid var(--line);
  padding:11px 13px;width:100%;
}
.afeld input:focus-visible{outline:2px solid var(--cyan);outline-offset:1px}
.afeld input[type=file]{
  font-family:var(--font-mono);font-size:12px;color:var(--grey);
  border:1px dashed var(--line);padding:14px;width:100%;
}
.afeld input[type=file]::file-selector-button{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--white);background:transparent;border:1px solid var(--line);
  padding:8px 12px;margin-right:12px;cursor:pointer;
}
.afeld__hint{
  margin:0;font-family:var(--font-body);font-size:15px;line-height:1.45;color:var(--grey);
  max-width:60ch;
}

.ameldung{
  margin:0 0 22px;padding:14px 16px;
  font-family:var(--font-mono);font-size:12.5px;line-height:1.6;
  border:1px solid var(--line);
}
.ameldung.is-ok{border-left:2px solid var(--cyan);color:var(--white)}
.ameldung.is-fehler{border-left:2px solid var(--warn);color:var(--warn-text)}

.aliste{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line)}
.aliste__item{
  display:flex;flex-wrap:wrap;gap:16px;align-items:center;justify-content:space-between;
  background:var(--black);padding:16px 18px;
}
.aliste__item--block{display:block}
.aliste__act{display:flex;gap:8px;flex-wrap:wrap}

/* Dateizustand: das Wort trägt die Information, die Farbe verstärkt sie nur. */
.adatei{display:flex;gap:10px;flex-wrap:wrap;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase}
.adatei .ja,.anfrage__kopf .ja{color:var(--cyan)}
.adatei .nein,.anfrage__kopf .nein{color:var(--grey-dim)}

.anfrage__kopf{
  display:flex;flex-wrap:wrap;gap:14px;align-items:baseline;margin:0 0 8px;
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.06em;color:var(--grey);
}
.anfrage__kopf strong{color:var(--white);font-weight:400;letter-spacing:.1em;text-transform:uppercase}
.anfrage__kopf a{color:var(--cyan)}
.anfrage__zeit{color:var(--grey-dim)}
/* Art der Anfrage und Link stehen seit dem 2026-09-07 in eigenen Spalten und
   damit auch als eigene Zeilen — vorher klebte die Art als Klammer vorn im
   Nachrichtentext, und den Link musste man dort suchen. */
.anfrage__art{
  margin:0 0 6px;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--cyan);
}
.anfrage__link{margin:0 0 8px;font-family:var(--font-mono);font-size:13px;overflow-wrap:anywhere}
.anfrage__link a{color:var(--white)}
.anfrage__link a:hover{color:var(--cyan)}
.anfrage__text{
  margin:0;font-family:var(--font-body);font-size:17px;line-height:1.55;color:var(--white);
  white-space:pre-wrap;max-width:70ch;
}

/* Kanäle des Labels im Fussbereich. Nur Verweise nach aussen. */
.foot__plattform{
  display:flex;flex-wrap:wrap;gap:16px;
  margin-bottom:12px;padding-bottom:10px;
  border-bottom:1px solid var(--line);
  font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
}
.foot__plattform a{
  color:var(--grey);text-decoration:none;
  /* Die Kanalzeile kam erst nach der Runde, in der alle Klickflaechen auf
     44 Pixel gezogen wurden — sie stand seitdem bei 17. Gleiches Mittel wie
     bei .foot__link: der Kasten waechst, die Schrift bleibt. */
  display:inline-flex;align-items:center;min-height:44px;
}
.foot__plattform a:hover,.foot__plattform a:focus-visible{color:var(--cyan)}

/* Die Stand-Angabe steht auch am Kopf des Rechtstextes — dort ohne
   Trennlinie, die trennt ja nichts ab. */
.legal .stand--oben{margin:0 0 24px;padding-top:0;border-top:0}

/* ============================================================
   Songliste auf schmalen Geräten
   Die Tabelle hat 620px Mindestbreite; darunter lag der
   Abspielknopf als sechste Spalte außerhalb des Bildschirms.
   Abspielen verlangte dort eine Zwei-Achsen-Geste: horizontal
   wischen innerhalb einer vertikal scrollenden Seite. Unter
   720px wird daraus deshalb eine Liste aus zwei Zeilen je Track,
   bei der Rang, Titel und Knopf gleichzeitig sichtbar sind.
   ============================================================ */

/* ============================================================
   Songliste auf schmalen Geraeten — nur die oeffentliche
   Der Umbruch galt bisher jeder Tabelle mit der Klasse .tracks,
   also auch der in der Verwaltung. Deren Spalten sind andere
   (Titel, Interpret, Klicks, Laenge, Dateien, Aktionen), ihre
   Zellen landeten damit in Rasterbereichen, die fuer sie nie
   gedacht waren. Deshalb haengt der Umbruch jetzt an einem
   eigenen Modifikator.
   ============================================================ */
@media (max-width:719px){
  .tracks-scroll:has(.tracks--reflow){overflow-x:visible}

  .tracks--reflow{min-width:0;display:block}
  /* Eine caption in einer Tabelle, die display:block traegt, bekommt keine
     Tabellenbreite mehr und schrumpft auf ihren Inhalt: der Hinweis stand
     als schmale, zerrissene Spalte von rund 110 Pixeln da, ein Wort je
     Zeile. Als Block nimmt er wieder die volle Breite. */
  .tracks--reflow caption{display:block;width:auto}
  .tracks--reflow thead{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
  }
  .tracks--reflow tbody{display:block}

  .tracks--reflow tbody tr{
    display:grid;
    grid-template-columns:2.4rem 1fr auto 44px;
    grid-template-areas:
      "rang titel  titel  spiel"
      "rang artist klicks spiel";
    align-items:center;
    column-gap:12px;row-gap:2px;
    padding:12px 0;
    border-bottom:1px solid var(--line);
  }

  .tracks--reflow td{
    display:block;height:auto;padding:0;border:0;
    min-width:0;overflow:hidden;text-overflow:ellipsis;
  }

  .tracks--reflow .track__rank{grid-area:rang;align-self:center}
  .tracks--reflow td:nth-child(2){grid-area:titel}
  .tracks--reflow .track__artist{grid-area:artist}
  .tracks--reflow .track__clicks{grid-area:klicks;text-align:right}
  .tracks--reflow .track__act{grid-area:spiel;width:auto;align-self:center}

  /* Die Länge steht im Player, sobald der Track läuft — auf dem
     schmalen Raum ist sie die entbehrlichste der fünf Angaben. */
  .tracks--reflow .track__len{display:none}

  .tracks--reflow .track__cover{width:38px;height:38px}
  .tracks--reflow .track__title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .tracks--reflow .track__clicks::after{content:"× gehört";font-size:.85em;color:var(--grey-dim)}
}

/* ---------- Die ganze Zeile ist die Klickfläche ----------
   Vorher versprach der Hover-Zustand, dass Zeile und Karte
   klickbar sind, auslösen konnte aber nur der Knopf. */

.tracks tbody tr:has(.play:not([disabled])),
.top3__card:has(.play:not([disabled])){cursor:pointer}

/* ---------- Kurzfassung des Inhaltshinweises ----------
   Steht ueber der Songliste, damit ihn auch sieht, wer ueber einen geteilten
   Link direkt in der Ansicht "Inhalte" landet. */

.disclaimer--kurz{margin-top:0;margin-bottom:clamp(18px,3vh,28px)}
.disclaimer--kurz p:last-child{margin-bottom:0}

/* ---------- Zeichenzaehler am Nachrichtenfeld ---------- */

.zeichen{
  display:block;margin-top:6px;text-align:right;
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.04em;
  color:var(--grey-dim);
}
.zeichen.is-knapp{color:var(--cyan)}

/* ============================================================
   Belastbarkeit gegen echte Eingaben
   Titel und Namen duerfen 120 Zeichen haben, Kurztexte 160,
   Nachrichten 5000 — und nichts davon muss Leerzeichen
   enthalten. An diesen Stellen fehlte die Bremse.
   ============================================================ */

/* Ein Flex-Kind schrumpft ohne min-width:0 nicht unter seinen Inhalt. Ein
   langer Interpretenname in Anton hat die Karte deshalb aufgesprengt. */
.artists__item > *{min-width:0}
.artists__name,.artists__meta{overflow-wrap:anywhere}

/* Eine 5000 Zeichen lange Nachricht ohne ein einziges Leerzeichen ist
   moeglich — pre-wrap allein bricht sie nicht um. */
.anfrage__text{overflow-wrap:anywhere}
.anfrage__kopf a,.anfrage__kopf strong{overflow-wrap:anywhere}

/* Auf breiten Schirmen hatte der Titel weder Umbruch noch Kuerzung: ein
   120-Zeichen-Titel zog die Tabelle in die waagerechte Bildlaufleiste und
   schob Klicks, Laenge und Abspielknopf aus dem Bild. Unter 720px kuerzt
   die Listenansicht bereits. */
@media (min-width:720px){
  .track__title{max-width:42ch;overflow:hidden;text-overflow:ellipsis;min-width:0}
}

/* Gilt auch fuer die Verwaltung, wo dieselben Klassen in der Tabelle stehen. */
.aliste__item > *{min-width:0}
.leer,.note,.afeld__hint{overflow-wrap:break-word}


/* ============================================================
   Die Tracktabelle der Verwaltung auf dem Telefon
   Sie behielt die 620 Pixel Mindestbreite und lag damit in einem
   waagerecht scrollenden Behaelter: bei 360 Pixel Bildbreite
   begannen "Bearbeiten" und "Entfernen" erst bei 568 Pixel, also
   gut 200 Pixel ausserhalb des Bildes. Wer unterwegs einen Track
   aendern wollte, musste die Tabelle blind seitwaerts schieben —
   dieselbe Zwei-Achsen-Geste, die fuer die oeffentliche Liste
   schon behoben ist. Hier wird jeder Track zu einem Block:
   Titel, Interpret, Zahlen, Dateizustand, dann die Schalter.
   ============================================================ */
@media (max-width:719px){
  .tracks-scroll:has(.tracks--admin){overflow-x:visible}

  .tracks--admin{min-width:0;display:block}
  /* Der Kopf verschwindet aus dem Bild, bleibt aber im Baum: die
     Spaltennamen tragen die Bedeutung fuer Hilfstechnik weiter. */
  .tracks--admin thead{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
  }
  .tracks--admin tbody{display:block}

  .tracks--admin tbody tr{
    display:grid;
    grid-template-columns:auto auto 1fr;
    grid-template-areas:
      "titel  titel  titel"
      "artist artist artist"
      "hoert  laenge ."
      "datei  datei  datei"
      "akt    akt    akt";
    column-gap:16px;row-gap:4px;
    padding:16px 0;
    border-bottom:1px solid var(--line);
  }

  .tracks--admin td{display:block;height:auto;padding:0;border:0;min-width:0}

  /* Ein 120 Zeichen langer Titel darf hier umbrechen statt zu kuerzen —
     in der Verwaltung muss der ganze Titel lesbar sein. */
  .tracks--admin .track__title{
    grid-area:titel;white-space:normal;overflow-wrap:anywhere;
    font-size:19px;
  }
  .tracks--admin .track__artist{grid-area:artist;white-space:normal;overflow-wrap:anywhere}
  .tracks--admin .track__clicks{grid-area:hoert;text-align:left}
  .tracks--admin td:nth-child(4){grid-area:laenge}

  /* Ohne Kopfzeile sagen nackte Zahlen nichts. Die Beschriftung
     kommt deshalb an die Zahl selbst. */
  .tracks--admin .track__clicks::after{content:"× gehört";color:var(--grey-dim)}
  .tracks--admin td:nth-child(4)::before{content:"Länge ";color:var(--grey-dim)}

  .tracks--admin .adatei{grid-area:datei;margin-top:6px}
  .tracks--admin .track__act{
    grid-area:akt;width:auto;text-align:left;
    display:flex;flex-wrap:wrap;gap:8px;margin-top:10px;
  }
}

/* Dateifelder der Verwaltung auf dem Telefon
   iOS Safari zoomt beim Fokussieren jedes Formularfeld unter 16 Pixel —
   dieselbe Falle, die bei den Auswahllisten schon geschlossen ist. Und der
   Knopf im Feld war mit 8 Pixel Innenabstand rund 30 Pixel hoch. */
@media (max-width:719px){
  .afeld input[type=file]{font-size:16px}
  .afeld input[type=file]::file-selector-button{min-height:44px;padding:0 14px}
}
