/*
 * Schriften liegen seit v1.21.0 lokal im Projekt (public/assets/fonts) statt
 * bei Google. Beim Einbinden über fonts.googleapis.com wird bei jedem Aufruf
 * die IP-Adresse des Besuchers an Google in die USA übertragen — genau das hat
 * das LG München (Urteil vom 20.01.2022, Az. 3 O 17493/20) als Verstoß gegen
 * die DSGVO gewertet. Lokal eingebunden entfällt der Datenabfluss komplett,
 * die Datenschutzerklärung bleibt kurz und die Seite lädt schneller.
 *
 * Beide Familien stehen unter der SIL Open Font License 1.1, die Lizenztexte
 * liegen bei den Dateien.
 */

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/fonts/space-grotesk-latin-500-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/space-grotesk-latin-700-normal.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/ibm-plex-mono-latin-600-normal.woff2") format("woff2");
}

:root {
  --bg: #12141a;
  --bg-2: #1b1e27; /* Oberfläche für erhöhte Panels (z. B. Schubladen-Modal-Karte) — sichtbar heller als --bg, damit die Karte sich vom Seitenhintergrund abhebt statt lose auf dem Backdrop zu schweben. */
  --bg-texture: none;
  --paper: #ece4d3;
  --paper-shadow: #d8cdb4;
  --ink: #241f18;
  --ink-soft: #55503f;
  --side-a: #e8a33d;
  --side-a-ink: #2a1c05;
  --side-b: #4fa88c;
  --side-b-ink: #08251d;
  /* Nur fürs Schubladen-Grid (schublade.js) — mehr Farbvarianz beim Durchblättern
     statt der strikten Zweifarb-Abwechslung. Bewusst NICHT bei Side A/B auf
     der eigentlichen Kassette/den Playlist-Covers verwendet — dort bleibt die
     feste Amber/Teal-Marke (siehe Projektwissen Abschnitt 0). Gedämpfte Töne,
     passend zur restlichen Palette, kein Regenbogen. */
  --tile-c: #c1614a;
  --tile-c-ink: #2c0f08;
  --tile-d: #7c8fd4;
  --tile-d-ink: #10142e;
  --tile-e: #8fae52;
  --tile-e-ink: #1a2308;
  --muted: #8891a3;
  /* Text direkt auf dem Seitenhintergrund (Body, Eyebrow, Legal-Nav-Hover) —
     getrennt von --paper, weil --paper zusätzlich die physische Etikett-/
     Papierfarbe ist (Legal-Sheet-Hintergrund, Kassetten-Etikett), die sich
     NICHT mit dem Theme ändert (genau wie das schwarze Gehäuseplastik der
     Kassette selbst — ein echtes Papier-Etikett wird bei Tageslicht nicht
     heller). --page-fg ist der Teil, der bei Hell/Dunkel wirklich wechselt. */
  --page-fg: #ece4d3;
  --display: "Space Grotesk", var(--sans, sans-serif);
  --mono: "IBM Plex Mono", "SF Mono", Consolas, monospace;
}

/* ============================================================================
   Hell-Modus — "Gebürstetes Chrom" (Tape-Deck-Gehäuse bei Tageslicht).
   Aktiviert über [data-theme="light"] auf <html> (siehe _theme_init.php:
   automatisch 7-19 Uhr, oder manuell über den Footer-Umschalter/theme-
   toggle.js). Bewusst nicht die erwartbare "warmes Creme + Terracotta"- oder
   "reines Weiß"-Standardkombination — kühles Metall-Grau mit gedämpftem
   Bronze/Petrol als Akzentfarben, plus ein feines diagonales Chrom-Linien-
   Muster im Hintergrund. --paper/--ink (das physische Etikett) bleiben
   unverändert, nur Seitenhintergrund/-text und die beiden Akzentfarben wechseln.
============================================================================ */
html[data-theme="light"] {
  --bg: #d8d9db;
  --bg-2: #ececed;
  --bg-texture:
    repeating-linear-gradient(100deg, rgba(255,255,255,0.35) 0px, rgba(255,255,255,0.35) 1px, transparent 1px, transparent 5px);
  --side-a: #b3762a;
  --side-a-ink: #241a08;
  --side-b: #35707a;
  --side-b-ink: #08221f;
  --tile-c: #9c4a37;
  --tile-c-ink: #200a05;
  --tile-d: #52619e;
  --tile-d-ink: #0c0f22;
  --tile-e: #647a35;
  --tile-e-ink: #121a05;
  --muted: #74777c;
  --page-fg: #1a1b1d;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
}

html { transition: background-color 0.2s ease; }

body {
  margin: 0;
  background:
    var(--bg-texture),
    radial-gradient(circle at 15% 8%, rgba(232, 163, 61, 0.08), transparent 40%),
    radial-gradient(circle at 85% 92%, rgba(79, 168, 140, 0.08), transparent 40%),
    var(--bg);
  color: var(--page-fg);
  font-family: var(--mono);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 2rem 1.25rem;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.tape-deck {
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
  text-align: center;
}

/* Schublade ist lang/scrollbar, keine einzelne kleine Karte wie die Startseite —
   die body-Flex-Zentrierung (align-items: center) würde den Seitenanfang
   sonst über den sichtbaren Bereich hinaus nach oben schieben, sobald der
   Inhalt größer als der Viewport ist (man landet dann mitten im Content,
   ohne oberen Abstand zu sehen). */
body.schublade-page {
  display: block;
  padding-top: 2rem;
}

.brand-mark {
  display: flex;
  justify-content: center;
  gap: 2.5rem;
  margin-bottom: 0.6rem;
  position: relative;
}

/* Band zwischen den beiden Wickeln — dasselbe Motiv wie auf dem Playlist-Cover.
   Liegt hinter den Wickeln, deshalb bekommen die unten z-index. */
.brand-mark::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* Nur den Abstand zwischen den Wickeln überbrücken (gap: 2.5rem) plus ein
     paar Pixel, die unter den Wickeln verschwinden. Bewusst nicht auf
     Mitte-zu-Mitte gerechnet: dann würde jede Änderung der Wickelgröße das
     Band seitlich überstehen lassen. */
  width: 2.8rem;
  height: 2px;
  background: var(--muted);
  opacity: 0.5;
}

.reel {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 3px solid var(--muted);
  position: relative;
  z-index: 1;
  background: var(--bg, transparent);
  animation: spin 6s linear infinite;
}

/* Nabe in der Mitte */
.reel::before {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background: var(--muted);
  z-index: 1;
}

/* Speichen: ein Kreuz aus zwei schmalen Balken. Ohne sie ist der Wickel
   punktsymmetrisch — die Drehung lief zwar, war aber unsichtbar. Bewusst aus
   zwei linear-gradient statt conic-gradient: gleiche Optik, funktioniert aber
   auch in älteren Engines. */
.reel::after {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: 50%;
  background:
    linear-gradient(to right, transparent 42%, var(--muted) 42%, var(--muted) 58%, transparent 58%),
    linear-gradient(to bottom, transparent 42%, var(--muted) 42%, var(--muted) 58%, transparent 58%);
}

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

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 2rem;
}

/* Kurzer Projekt-Beschreibungstext über der Kassette (Startseite) bzw. unter
   der Schublade-Überschrift — geteiltes Partial _intro.php, siehe dort. Als Box
   abgesetzt (var(--bg-2), dieselbe erhöhte Oberfläche wie z. B. das Schubladen-
   Modal), damit der Text sich vom Seitenhintergrund abhebt statt mit Footer/
   Fließtext zu verschwimmen (Nutzer-Screenshot 04.08.2026). var(--bg-2)/
   var(--muted) sind bereits im Hell-Modus separat definiert
   ([data-theme="light"], siehe :root weiter oben) — hier keine eigenen
   Theme-Überschreibungen nötig. Text bewusst linksbündig innerhalb der Box
   (auch auf der zentrierten Startseite) — mehrzeilige Fließtext-Box liest
   sich linksbündig deutlich besser als zentriert. */
.intro-text {
  background: var(--bg-2);
  color: var(--muted);
  font-size: 0.85rem;
  line-height: 1.5;
  text-align: left;
  max-width: 34rem;
  margin: 0 auto 1.6rem;
  padding: 1rem 1.2rem;
  border-radius: 10px;
}

/* Auf der Startseite (.tape-deck, 420px breit, zentriert) begrenzt max-width
   die Textbreite für bessere Lesbarkeit — greift dort praktisch nie, da der
   Container selbst schon schmaler ist. Auf /schublade (.tape-deck.schublade,
   720px breit, linksbündig) machte genau diese Kappung die Box schmaler als
   Suchfeld und Grid daneben (Nutzer-Screenshot 04.08.2026) — hier aufgehoben,
   Box füllt die volle Containerbreite wie ihre Geschwister-Elemente. */
.tape-deck.schublade .intro-text {
  max-width: none;
  margin: 0 0 1.6rem;
}

/* Generisch für alle Seiten (Startseite, Schublade, Rechtsseiten) — ohne diese
   Regel erbt ein <a> in .eyebrow die Browser-Standardfarbe für Links
   (i. d. R. lila/blau, unterstrichen), nicht den gedämpften Seitenstil. */
.eyebrow a {
  color: inherit;
  text-decoration: none;
}
.eyebrow a:hover,
.eyebrow a:focus-visible {
  color: var(--side-b);
}

.cassette-card {
  background: var(--paper);
  color: var(--ink);
  border-radius: 10px;
  padding: 2.2rem 1.8rem 2rem;
  box-shadow: 0 1px 0 var(--paper-shadow) inset, 0 20px 60px -20px rgba(0, 0, 0, 0.6);
  position: relative;
}

.cassette-card::before {
  content: "";
  position: absolute;
  top: 14px;
  left: 14px;
  right: 14px;
  bottom: 14px;
  border: 1px dashed rgba(36, 31, 24, 0.18);
  border-radius: 6px;
  pointer-events: none;
}

.cover {
  width: 88px;
  height: 88px;
  object-fit: cover;
  border-radius: 6px;
  margin-bottom: 1rem;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
}

.vol {
  font-family: var(--display);
  font-weight: 700;
  font-size: 2.6rem;
  margin: 0;
  line-height: 1;
  letter-spacing: -0.01em;
}

.genre {
  font-family: var(--mono);
  font-weight: 600;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0.5rem 0 0.15rem;
}

.date {
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin: 0 0 1.6rem;
}

.tape-deck .sides { margin-top: 1.2rem; }

.sides {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  max-width: 420px;
  margin: 1.2rem auto 0;
}

.side-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.8rem 1.1rem;
  border-radius: 7px;
  text-decoration: none;
  font-family: var(--mono);
  font-weight: 600;
  transition: transform 0.15s ease;
}

.side-btn:hover { transform: translateY(-1px); }

.side-a { background: var(--side-a); color: var(--side-a-ink); }
.side-b { background: var(--side-b); color: var(--side-b-ink); }

.side-label {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.75;
}

.side-action {
  font-size: 0.9rem;
}

.muted {
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* Wie .muted, aber für Text direkt auf dem Seiten-/Modal-Hintergrund statt auf
   dem Papier-Etikett — var(--muted) statt var(--ink-soft), sonst auf dem
   dunklen Hintergrund/Modal-Backdrop praktisch unlesbar (dunkles Braun auf
   Fast-Schwarz). Siehe schublade.php (#shelfEmpty) und schublade.js (Lade-/Fehlertext
   im Modal, bevor die echte Kassettenkarte da ist). */
.muted-page {
  color: var(--muted);
  font-size: 0.85rem;
}

.empty h1 {
  font-family: var(--display);
  font-size: 1.4rem;
  margin: 0 0 0.6rem;
}

.footline {
  margin-top: 1.8rem;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--muted);
}

/* Deutlich auffälliger als die reinen Pflicht-Links unten (.legal-nav) —
   genau das war die Kritik an der ursprünglichen Version, wo "Schublade" dort
   klein zwischen Impressum/Datenschutz unterging. */
.schublade-link {
  display: inline-block;
  margin: 1.8rem 0 1.6rem;
  padding: 0.6rem 1.4rem;
  border: 1.5px solid var(--side-b);
  border-radius: 999px;
  color: var(--side-b);
  text-decoration: none;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.schublade-link:hover,
.schublade-link:focus-visible {
  background: var(--side-b);
  color: var(--side-b-ink);
}

/* Auf /schublade selbst ist der Content-Block linksbündig (.tape-deck.schublade,
   nötig fürs Grid/die Suche) — der "Zurück"-Pill-Button soll trotzdem zentriert
   sitzen wie sein Pendant "In der Schublade stöbern" auf der Startseite. */
.tape-deck.schublade > a.schublade-link {
  display: block;
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
}

/* ---------------------------------------------------------------------------
   Kassette (Wartungsseite). Als SVG im Maßstab des Originals gezeichnet
   (100,5 × 63,5 mm ≈ 402 × 254), damit sie auch als kleine Grafik auf dem
   Handy als Kassette lesbar bleibt. Der Text liegt als HTML darüber statt als
   SVG-Text: so bricht er bei schmalen Displays um und bleibt vorlesbar.
--------------------------------------------------------------------------- */

.cassette-figure {
  position: relative;
  max-width: 420px;
  margin: 0 auto;
  filter: drop-shadow(0 22px 36px rgba(0, 0, 0, 0.6));
}

.cassette-figure svg {
  display: block;
  width: 100%;
  height: auto;
}

/*
 * Schreibfeld des Etiketts: unter dem orangen Kopfbalken, oberhalb der zwei
 * Schreiblinien. Die Prozentwerte beziehen sich auf die Bildfläche und decken
 * sich mit den Koordinaten im SVG — linke Kante bündig mit „MISCHKASSETTE.DE" und den
 * Schreiblinien (dort x = 42 von 402 ≙ 10,4 %).
 */
.cassette-inscription {
  position: absolute;
  left: 10.4%;
  top: 19.5%;
  width: 78%;
  height: 22%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  color: var(--ink);
  text-align: left;
}

.cassette-inscription .genre {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.15rem, 6.2vw, 1.7rem);
  letter-spacing: 0.02em;
  line-height: 1.05;
  margin: 0;
  text-transform: uppercase;
}

.cassette-inscription h1 {
  font-family: var(--display);
  font-size: clamp(0.92rem, 4.7vw, 1.22rem);
  line-height: 1.12;
  margin: 0 0 0.18em;
}

.cassette-inscription p {
  font-size: clamp(0.66rem, 3.1vw, 0.82rem);
  line-height: 1.2;
  color: var(--ink-soft);
  margin: 0;
}

.reel-spin {
  animation: spin 6s linear infinite;
}

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

/* ---------------------------------------------------------------------------
   Rechtsseiten und Fußzeilen-Navigation
--------------------------------------------------------------------------- */

.legal-nav {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.35rem 1.1rem;
  margin-top: 0.6rem;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
}

.legal-nav a {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.legal-nav a:hover,
.legal-nav a:focus-visible {
  color: var(--page-fg);
  border-bottom-color: var(--side-a);
}

/* Die Rechtsseiten sind Fließtext und dürfen breiter werden als die Kassette. */
.tape-deck.legal {
  max-width: 640px;
  text-align: left;
}

.tape-deck.legal .eyebrow { text-align: center; }

.legal-sheet {
  background: var(--paper);
  color: var(--ink);
  border-radius: 10px;
  padding: 1.6rem 1.4rem 1.8rem;
  box-shadow: 0 20px 60px -20px rgba(0, 0, 0, 0.6);
}

.legal-sheet h1 {
  font-family: var(--display);
  font-size: 1.35rem;
  margin: 0 0 1.2rem;
}

.legal-sheet h2 {
  font-family: var(--display);
  font-size: 0.95rem;
  margin: 1.6rem 0 0.5rem;
}

.legal-sheet h2:first-of-type { margin-top: 0; }

.legal-sheet p {
  font-size: 0.85rem;
  line-height: 1.65;
  color: var(--ink-soft);
  margin: 0 0 0.7rem;
}

.legal-sheet .legal-line {
  margin-bottom: 0.15rem;
  color: var(--ink);
}

.legal-sheet a { color: var(--ink); text-decoration: underline; }

/* ---------------------------------------------------------------------------
   Rechtsseiten-Modal (nur Startseite, siehe legal-modal.js). Direkter Aufruf
   der URLs bleibt davon unberührt funktionsfähig — Pflicht nach § 5 DDG.
--------------------------------------------------------------------------- */

.legal-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 9, 7, 0.72);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  z-index: 100;
}

.legal-modal-backdrop[hidden] { display: none; }

.legal-modal {
  position: relative;
  width: 100%;
  max-width: 640px;
  max-height: min(80vh, 720px);
  overflow-y: auto;
  border-radius: 10px;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.7);
}

.legal-modal .legal-sheet {
  box-shadow: none;
  min-height: 100%;
}

.legal-modal-close {
  position: sticky;
  top: 0.6rem;
  float: right;
  margin-right: 0.6rem;
  width: 2rem;
  height: 2rem;
  border: none;
  border-radius: 50%;
  background: rgba(36, 31, 24, 0.1);
  color: var(--ink);
  font-size: 1.3rem;
  line-height: 1.9rem;
  text-align: center;
  cursor: pointer;
}

.legal-modal-close:hover,
.legal-modal-close:focus-visible {
  background: rgba(36, 31, 24, 0.2);
  outline: none;
}

.legal-modal-loading {
  padding: 2rem 0;
  text-align: center;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: no-preference) {
  .legal-modal-backdrop { animation: legal-modal-fade 0.15s ease-out; }
}

@keyframes legal-modal-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Genre auf dem Etikett der Startseite: einzige Angabe im Schreibfeld und
   deshalb bewusst groß. Vol.-Nummer steht im Kopfbalken, Datum entfällt. */
.cassette-inscription .genre {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.15rem, 6.2vw, 1.7rem);
  line-height: 1.05;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin: 0;
}

/* ---------------------------------------------------------------------------
   Schublade (/schublade) — Grid aller bisherigen Kassetten als Mini-Icons, plus Modal
   mit der vollen Illustration (_cassette.php, dieselbe Partial wie die
   Startseite). Siehe app/Frontend/SchubladeController.php.
--------------------------------------------------------------------------- */

.tape-deck.schublade {
  max-width: 720px;
  text-align: left;
}

/* Fußzeile bleibt immer zentriert, unabhängig vom text-align des umgebenden
   .tape-deck (auf /schublade links, sonst zentriert) — sonst reißt .tape-deck.schublade
   die Fußzeile mit nach links (siehe Chat-Verlauf: Screenshot in breiterer Ansicht). */
.tape-deck.schublade .site-footer {
  text-align: center;
}

.schublade-heading {
  font-family: var(--display);
  font-size: 1.6rem;
  margin: 0.4rem 0 0.3rem;
  color: var(--page-fg);
}

.schublade-sub {
  color: var(--muted);
  font-size: 0.85rem;
  margin: 0 0 2rem;
}

.schublade-search { margin: 0 0 1.6rem; position: relative; }
.schublade-search input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  box-sizing: border-box;
  background: transparent;
  border: 1px solid var(--muted);
  color: var(--page-fg);
  font-family: var(--mono);
  font-size: 0.9rem;
  padding: 0.65rem 2.4rem 0.65rem 0.9rem;
  border-radius: 999px;
}
.schublade-search input::-webkit-search-decoration,
.schublade-search input::-webkit-search-cancel-button,
.schublade-search input::-webkit-search-results-button,
.schublade-search input::-webkit-search-results-decoration {
  -webkit-appearance: none;
  display: none;
}
.schublade-search input:focus {
  outline: 2px solid var(--side-a);
  border-color: var(--side-a);
}
.schublade-search input::placeholder { color: var(--muted); }
.schublade-search-clear {
  position: absolute;
  right: 0.5rem;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 1rem;
  line-height: 1;
  padding: 0.4rem;
  cursor: pointer;
}
.schublade-search-clear:hover { color: var(--side-a); }

.month-heading {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 2rem 0 0.9rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid rgba(128, 128, 128, 0.25);
}
.month-heading:first-of-type { margin-top: 0; }

.shelf {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 0.7rem 0.6rem;
}

.mini-cassette {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--mono);
}

.mini-shell {
  width: 100%;
  aspect-ratio: 8 / 5;
  background: linear-gradient(180deg, #37332d 0%, #242220 42%, #17150f 100%);
  border: 1px solid #544d42;
  border-radius: 6px;
  position: relative;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  overflow: hidden;
}

.mini-cassette:hover .mini-shell,
.mini-cassette:focus-visible .mini-shell {
  transform: translateY(-3px);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.4);
}
.mini-cassette:focus-visible .mini-shell {
  outline: 2px solid var(--side-a);
  outline-offset: 2px;
}
.mini-cassette.is-current .mini-shell {
  box-shadow: 0 0 0 1.5px var(--side-a);
}

.mini-stripe {
  position: absolute;
  top: 12%;
  left: 6%;
  right: 6%;
  height: 34%;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4%;
}
.mini-stripe span {
  font-size: 0.56rem;
  font-weight: 600;
  line-height: 1.05;
  text-align: center;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  /* Kondensierte Etikett-Typografie — Anspielung auf Thermodrucker-
     Kassettenbeschriftung statt neutraler UI-Schrift (Design-Vorschlag
     04.08.2026, Preview abgestimmt). font-stretch condensed hat auf den
     meisten Systemfonts keine echte Wirkung, deshalb zusätzlich per
     transform simuliert — funktioniert unabhängig von Font-Verfügbarkeit. */
  font-stretch: condensed;
  letter-spacing: 0.01em;
  transform: scaleX(0.92);
}

.mini-reels {
  position: absolute;
  bottom: 14%;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 22%;
}
.mini-reel {
  width: 20%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #0d0b09;
  border: 1px solid #5b5347;
  position: relative;
  animation: spin 6s linear infinite;
}
.mini-reel-dot {
  position: absolute;
  top: 10%;
  left: 50%;
  width: 24%;
  aspect-ratio: 1;
  border-radius: 50%;
  transform: translateX(-50%);
}
@media (prefers-reduced-motion: reduce) {
  .mini-reel, .reel-spin { animation: none; }
}

.load-more-reel {
  vertical-align: -2px;
  margin-right: 0.4rem;
  color: var(--muted);
}
/* Schneller als die 6s-Ambient-Drehung auf der Kassetten-Illustration
   (.reel-spin generisch) — als Lade-Indikator soll die Bewegung sofort als
   "etwas passiert" lesbar sein, nicht als dezentes Hintergrund-Detail. */
.load-more-reel .reel-spin {
  animation-duration: 2.2s;
}

.load-more {
  display: block;
  margin: 2.2rem auto 0;
  background: transparent;
  border: 1px solid var(--muted);
  color: var(--page-fg);
  font-family: var(--mono);
  font-size: 0.85rem;
  padding: 0.65rem 1.4rem;
  border-radius: 999px;
  cursor: pointer;
}
.load-more:hover { border-color: var(--side-b); color: var(--side-b); }
.load-more:disabled { opacity: 0.6; cursor: default; }

/* Nur auf der langen Schubladen-Seite relevant (siehe schublade.js) — erscheint erst
   nach etwas Scrolltiefe, sonst würde er die kurze Startseite/Rechtsseiten
   unnötig zumüllen. */
.back-to-top {
  position: fixed;
  right: 1.1rem;
  bottom: 1.1rem;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: var(--bg-2);
  border: 1px solid rgba(128, 128, 128, 0.35);
  color: var(--page-fg);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease, border-color 0.15s ease, color 0.15s ease;
  z-index: 15;
}
.back-to-top.visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
.back-to-top:hover,
.back-to-top:focus-visible {
  border-color: var(--side-b);
  color: var(--side-b);
}

/* ---- Modal (Schubladen-Detailkarte) ---- */
.detail-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 11, 15, 0.78);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 2.2rem 1.2rem;
  overflow-y: auto;
  z-index: 20;
}
.detail-backdrop.open { display: flex; }

.detail-modal {
  position: relative;
  width: 100%;
  max-width: 400px;
  background: var(--bg-2);
  border-radius: 18px;
  padding: 3.4rem 1.6rem 1.8rem;
  box-shadow: 0 30px 70px -18px rgba(0, 0, 0, 0.65);
}

.detail-modal .cassette-figure { margin-top: 0; }
.detail-modal .sides { margin-top: 1.6rem; }

.detail-modal-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: rgba(128, 128, 128, 0.16);
  color: var(--page-fg);
  border: none;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.detail-modal-close:hover,
.detail-modal-close:focus-visible {
  background: rgba(128, 128, 128, 0.32);
}

/* ---- Theme-Umschalter (Footer, alle öffentlichen Seiten) ---- */
.theme-toggle {
  display: block;
  margin: 1rem auto 0;
  background: transparent;
  border: 1px solid rgba(128, 128, 128, 0.35);
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
  cursor: pointer;
}
.theme-toggle:hover { color: var(--side-b); border-color: var(--side-b); }
